2 * PROJECT: Recycle bin management
3 * LICENSE: GPL v2 - See COPYING in the top level directory
4 * FILE: lib/recyclebin/recyclebin_generic.c
5 * PURPOSE: Deals with a system-wide recycle bin
6 * PROGRAMMERS: Copyright 2007 Hervé Poussineau (hpoussin@reactos.org)
10 #include "recyclebin_private.h"
13 WINE_DEFAULT_DEBUG_CHANNEL(recyclebin
);
15 struct RecycleBinGeneric
18 IRecycleBin recycleBinImpl
;
21 static HRESULT STDMETHODCALLTYPE
22 RecycleBinGeneric_RecycleBin_QueryInterface(
27 struct RecycleBinGeneric
*s
= CONTAINING_RECORD(This
, struct RecycleBinGeneric
, recycleBinImpl
);
29 TRACE("(%p, %s, %p)\n", This
, debugstr_guid(riid
), ppvObject
);
34 if (IsEqualIID(riid
, &IID_IUnknown
))
35 *ppvObject
= &s
->recycleBinImpl
;
36 else if (IsEqualIID(riid
, &IID_IRecycleBin
))
37 *ppvObject
= &s
->recycleBinImpl
;
44 IUnknown_AddRef(This
);
48 static ULONG STDMETHODCALLTYPE
49 RecycleBinGeneric_RecycleBin_AddRef(
52 struct RecycleBinGeneric
*s
= CONTAINING_RECORD(This
, struct RecycleBinGeneric
, recycleBinImpl
);
53 ULONG refCount
= InterlockedIncrement((PLONG
)&s
->ref
);
54 TRACE("(%p)\n", This
);
59 RecycleBinGeneric_Destructor(
60 struct RecycleBinGeneric
*s
)
67 static ULONG STDMETHODCALLTYPE
68 RecycleBinGeneric_RecycleBin_Release(
71 struct RecycleBinGeneric
*s
= CONTAINING_RECORD(This
, struct RecycleBinGeneric
, recycleBinImpl
);
74 TRACE("(%p)\n", This
);
76 refCount
= InterlockedDecrement((PLONG
)&s
->ref
);
79 RecycleBinGeneric_Destructor(s
);
84 static HRESULT STDMETHODCALLTYPE
85 RecycleBinGeneric_RecycleBin_DeleteFile(
87 IN LPCWSTR szFileName
)
90 LPWSTR szFullName
= NULL
;
91 DWORD dwBufferLength
= 0;
93 WCHAR szVolume
[MAX_PATH
];
96 TRACE("(%p, %s)\n", This
, debugstr_w(szFileName
));
98 /* Get full file name */
101 len
= GetFullPathNameW(szFileName
, dwBufferLength
, szFullName
, NULL
);
105 CoTaskMemFree(szFullName
);
106 return HRESULT_FROM_WIN32(GetLastError());
108 else if (len
< dwBufferLength
)
111 CoTaskMemFree(szFullName
);
112 dwBufferLength
= len
;
113 szFullName
= CoTaskMemAlloc(dwBufferLength
* sizeof(WCHAR
));
115 return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY
);
118 /* Get associated volume path */
120 if (!GetVolumePathNameW(szFullName
, szVolume
, MAX_PATH
))
122 CoTaskMemFree(szFullName
);
123 return HRESULT_FROM_WIN32(GetLastError());
126 swprintf(szVolume
, L
"%c:\\", szFullName
[0]);
129 /* Skip namespace (if any) */
130 if (szVolume
[0] == '\\'
131 && szVolume
[1] == '\\'
132 && (szVolume
[2] == '.' || szVolume
[2] == '?')
133 && szVolume
[3] == '\\')
135 MoveMemory(szVolume
, &szVolume
[4], (MAX_PATH
- 4) * sizeof(WCHAR
));
138 hr
= GetDefaultRecycleBin(szVolume
, &prb
);
141 CoTaskMemFree(szFullName
);
145 hr
= IRecycleBin_DeleteFile(prb
, szFullName
);
146 CoTaskMemFree(szFullName
);
147 IRecycleBin_Release(prb
);
151 static HRESULT STDMETHODCALLTYPE
152 RecycleBinGeneric_RecycleBin_EmptyRecycleBin(
153 IN IRecycleBin
*This
)
155 WCHAR szVolumeName
[MAX_PATH
];
156 DWORD dwLogicalDrives
, i
;
160 TRACE("(%p)\n", This
);
162 dwLogicalDrives
= GetLogicalDrives();
163 if (dwLogicalDrives
== 0)
164 return HRESULT_FROM_WIN32(GetLastError());
166 for (i
= 0; i
< 26; i
++)
168 if (!(dwLogicalDrives
& (1 << i
)))
170 swprintf(szVolumeName
, L
"%c:\\", 'A' + i
);
171 if (GetDriveTypeW(szVolumeName
) != DRIVE_FIXED
)
174 hr
= GetDefaultRecycleBin(szVolumeName
, &prb
);
178 hr
= IRecycleBin_EmptyRecycleBin(prb
);
179 IRecycleBin_Release(prb
);
185 static HRESULT STDMETHODCALLTYPE
186 RecycleBinGeneric_RecycleBin_EnumObjects(
187 IN IRecycleBin
*This
,
188 OUT IRecycleBinEnumList
**ppEnumList
)
190 TRACE("(%p, %p)\n", This
, ppEnumList
);
191 return RecycleBinGenericEnum_Constructor(ppEnumList
);
194 CONST_VTBL
struct IRecycleBinVtbl RecycleBinGenericVtbl
=
196 RecycleBinGeneric_RecycleBin_QueryInterface
,
197 RecycleBinGeneric_RecycleBin_AddRef
,
198 RecycleBinGeneric_RecycleBin_Release
,
199 RecycleBinGeneric_RecycleBin_DeleteFile
,
200 RecycleBinGeneric_RecycleBin_EmptyRecycleBin
,
201 RecycleBinGeneric_RecycleBin_EnumObjects
,
204 HRESULT
RecycleBinGeneric_Constructor(OUT IUnknown
**ppUnknown
)
206 /* This RecycleBin implementation was introduced to be able to manage all
207 * drives at once, and instanciate the 'real' implementations when needed */
208 struct RecycleBinGeneric
*s
;
210 s
= CoTaskMemAlloc(sizeof(struct RecycleBinGeneric
));
212 return E_OUTOFMEMORY
;
214 s
->recycleBinImpl
.lpVtbl
= &RecycleBinGenericVtbl
;
216 *ppUnknown
= (IUnknown
*)&s
->recycleBinImpl
;