1 #pragma once
2 
3 #ifdef __cplusplus
4 extern "C" {
5 #endif
6 
7 #include <stdarg.h>
8 
9 #define WIN32_NO_STATUS
10 #define _INC_WINDOWS
11 #define COM_NO_WINDOWS_H
12 
13 #include <windef.h>
14 #include <winbase.h>
15 #include <winnls.h>
16 #include <winver.h>
17 #include <shellapi.h>
18 #include <objbase.h>
19 
20 #define RECYCLEBINMAXDRIVECOUNT 26
21 
22 /* Structures used by the API Interface */
23 
24 typedef UINT RECYCLEBINFILESIZETYPE;
25 
26 typedef struct _RECYCLEBINFILEIDENTITY
27 {
28     FILETIME DeletionTime;
29     LPCWSTR RecycledFullPath; /* "C:\Recycled\Dc1.ext" etc. */
30 } RECYCLEBINFILEIDENTITY, *PRECYCLEBINFILEIDENTITY;
31 
32 typedef struct _RECYCLEBINSTRING
33 {
34     LPCWSTR String;
35     LPWSTR Alloc;
36 } RECYCLEBINSTRING, *PRECYCLEBINSTRING;
37 
38 typedef struct _DELETED_FILE_INFO
39 {
40     FILETIME LastModification;
41     FILETIME DeletionTime;
42     RECYCLEBINFILESIZETYPE FileSize;
43     DWORD Attributes;
44     RECYCLEBINSTRING OriginalFullPath;
45     RECYCLEBINSTRING RecycledFullPath;
46 } DELETED_FILE_INFO, *PDELETED_FILE_INFO;
47 
48 /* Distinct handle type for deleted file/folder */
49 DECLARE_HANDLE(HDELFILE);
50 #define IRecycleBinFileFromHDELFILE(hDF) ( (IRecycleBinFile*)(hDF) )
51 
52 /* API Interface */
53 
54 static inline void
FreeRecycleBinString(PRECYCLEBINSTRING pRBS)55 FreeRecycleBinString(PRECYCLEBINSTRING pRBS)
56 {
57     SHFree(pRBS->Alloc);
58     pRBS->String = pRBS->Alloc = NULL;
59 }
60 
61 static inline void
InitializeRecycleBinStringRef(PRECYCLEBINSTRING pRBS,LPCWSTR String)62 InitializeRecycleBinStringRef(PRECYCLEBINSTRING pRBS, LPCWSTR String)
63 {
64     pRBS->String = String;
65     pRBS->Alloc = NULL;
66 }
67 
68 EXTERN_C HRESULT
69 GetRecycleBinPathFromDriveNumber(UINT Drive, LPWSTR Path);
70 
71 /* Function called for each deleted file in the recycle bin
72  * Context: value given by the caller of the EnumerateRecycleBin function
73  * hDeletedFile: a handle to the deleted file
74  * Returning FALSE stops the enumeration.
75  * Remarks: the handle must be closed with the CloseRecycleBinHandle function
76  */
77 typedef BOOL (CALLBACK *PENUMERATE_RECYCLEBIN_CALLBACK)(IN PVOID Context, IN HDELFILE hDeletedFile);
78 
79 /* Closes a file deleted handle.
80  * hDeletedFile: the handle to close
81  * Returns TRUE if operation succeeded, FALSE otherwise.
82  * Remark: The handle is obtained in the PENUMERATE_RECYCLEBIN_CALLBACK callback
83  */
84 BOOL WINAPI
85 CloseRecycleBinHandle(
86     IN HDELFILE hDeletedFile);
87 
88 /* Moves a file to the recycle bin.
89  * FileName: the name of the file to move the recycle bin
90  * Returns TRUE if operation succeeded, FALSE otherwise.
91  */
92 BOOL WINAPI
93 DeleteFileToRecycleBinA(
94     IN LPCSTR FileName);
95 BOOL WINAPI
96 DeleteFileToRecycleBinW(
97     IN LPCWSTR FileName);
98 #ifdef UNICODE
99 #define DeleteFileToRecycleBin DeleteFileToRecycleBinW
100 #else
101 #define DeleteFileToRecycleBin DeleteFileToRecycleBinA
102 #endif
103 
104 /* Deletes a file in the recycle bin.
105  * hDeletedFile: handle of the deleted file to delete
106  * Returns TRUE if operation succeeded, FALSE otherwise.
107  * Remark: The handle is obtained in the PENUMERATE_RECYCLEBIN_CALLBACK callback
108  */
109 BOOL WINAPI
110 DeleteFileInRecycleBin(
111     IN HDELFILE hDeletedFile);
112 
113 /* Removes all elements contained in a recycle bin
114  * pszRoot: the name of the drive containing the recycle bin
115  * Returns TRUE if operation succeeded, FALSE otherwise.
116  * Remarks: 'pszRoot' can be NULL to mean 'all recycle bins'.
117  */
118 BOOL WINAPI
119 EmptyRecycleBinA(
120     IN LPCSTR pszRoot OPTIONAL);
121 BOOL WINAPI
122 EmptyRecycleBinW(
123     IN LPCWSTR pszRoot OPTIONAL);
124 #ifdef UNICODE
125 #define EmptyRecycleBin EmptyRecycleBinW
126 #else
127 #define EmptyRecycleBin EmptyRecycleBinA
128 #endif
129 
130 /* Enumerate contents of a recycle bin.
131  * pszRoot: the name of the drive containing the recycle bin
132  * pFnCallback: callback function to be called for each deleted item found
133  * Context: some value which will be given back in the callback function
134  * Returns TRUE if operation succeeded, FALSE otherwise.
135  * Remarks: 'pszRoot' can be NULL to mean 'all recycle bins'.
136  */
137 BOOL WINAPI
138 EnumerateRecycleBinA(
139     IN LPCSTR pszRoot OPTIONAL,
140     IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback,
141     IN PVOID Context OPTIONAL);
142 BOOL WINAPI
143 EnumerateRecycleBinW(
144     IN LPCWSTR pszRoot OPTIONAL,
145     IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback,
146     IN PVOID Context OPTIONAL);
147 #ifdef UNICODE
148 #define EnumerateRecycleBin EnumerateRecycleBinW
149 #else
150 #define EnumerateRecycleBin EnumerateRecycleBinA
151 #endif
152 
153 EXTERN_C HDELFILE
154 GetRecycleBinFileHandle(
155     IN LPCWSTR pszRoot OPTIONAL,
156     IN const RECYCLEBINFILEIDENTITY *pFI);
157 
158 /* Restores a deleted file
159  * hDeletedFile: handle of the deleted file to restore
160  * Returns TRUE if operation succeeded, FALSE otherwise.
161  * Remarks: if the function succeeds, the handle is not valid anymore.
162  */
163 BOOL WINAPI
164 RestoreFileFromRecycleBin(
165     IN HDELFILE hDeletedFile);
166 
167 /* COM interface */
168 
169 #define INTERFACE IRecycleBinFile
DECLARE_INTERFACE_(IRecycleBinFile,IUnknown)170 DECLARE_INTERFACE_(IRecycleBinFile, IUnknown)
171 {
172     BEGIN_INTERFACE
173 
174     /* IUnknown methods */
175     STDMETHOD(QueryInterface)(THIS_ REFIID riid, void **ppvObject) PURE;
176     STDMETHOD_(ULONG, AddRef)(THIS) PURE;
177     STDMETHOD_(ULONG, Release)(THIS) PURE;
178 
179     /* IRecycleBinFile methods */
180     STDMETHOD(IsEqualIdentity)(THIS_ const RECYCLEBINFILEIDENTITY *pFI) PURE;
181     STDMETHOD(GetInfo)(THIS_ PDELETED_FILE_INFO pInfo) PURE;
182     STDMETHOD(GetLastModificationTime)(THIS_ FILETIME *pLastModificationTime) PURE;
183     STDMETHOD(GetDeletionTime)(THIS_ FILETIME *pDeletionTime) PURE;
184     STDMETHOD(GetFileSize)(THIS_ ULARGE_INTEGER *pFileSize) PURE;
185     STDMETHOD(GetPhysicalFileSize)(THIS_ ULARGE_INTEGER *pPhysicalFileSize) PURE;
186     STDMETHOD(GetAttributes)(THIS_ DWORD *pAttributes) PURE;
187     STDMETHOD(GetFileName)(THIS_ SIZE_T BufferSize, LPWSTR Buffer, SIZE_T *RequiredSize) PURE;
188     STDMETHOD(Delete)(THIS) PURE;
189     STDMETHOD(Restore)(THIS) PURE;
190 
191     END_INTERFACE
192 };
193 #undef INTERFACE
194 
195 #define INTERFACE IRecycleBinEnumList
DECLARE_INTERFACE_(IRecycleBinEnumList,IUnknown)196 DECLARE_INTERFACE_(IRecycleBinEnumList, IUnknown)
197 {
198     BEGIN_INTERFACE
199 
200     /* IUnknown methods */
201     STDMETHOD(QueryInterface)(THIS_ REFIID riid, void **ppvObject) PURE;
202     STDMETHOD_(ULONG, AddRef)(THIS) PURE;
203     STDMETHOD_(ULONG, Release)(THIS) PURE;
204 
205     /* IRecycleBinEnumList methods */
206     STDMETHOD(Next)(THIS_ DWORD celt, IRecycleBinFile **rgelt, DWORD *pceltFetched) PURE;
207     STDMETHOD(Skip)(THIS_ DWORD celt) PURE;
208     STDMETHOD(Reset)(THIS) PURE;
209 
210     END_INTERFACE
211 };
212 #undef INTERFACE
213 
214 #define INTERFACE IRecycleBin
DECLARE_INTERFACE_(IRecycleBin,IUnknown)215 DECLARE_INTERFACE_(IRecycleBin, IUnknown)
216 {
217     BEGIN_INTERFACE
218 
219     /* IUnknown methods */
220     STDMETHOD(QueryInterface)(THIS_ REFIID riid, void **ppvObject) PURE;
221     STDMETHOD_(ULONG, AddRef)(THIS) PURE;
222     STDMETHOD_(ULONG, Release)(THIS) PURE;
223 
224     /* IRecycleBin methods */
225     STDMETHOD(DeleteFile)(THIS_ LPCWSTR szFileName) PURE;
226     STDMETHOD(EmptyRecycleBin)(THIS) PURE;
227     STDMETHOD(EnumObjects)(THIS_ IRecycleBinEnumList **ppEnumList) PURE;
228     STDMETHOD(GetDirectory)(THIS_ LPWSTR szPath) PURE;
229 
230     END_INTERFACE
231 };
232 #undef INTERFACE
233 
234 EXTERN_C const IID IID_IRecycleBinFile;
235 EXTERN_C const IID IID_IRecycleBinEnumList;
236 EXTERN_C const IID IID_IRecycleBin;
237 
238 #if (!defined(__cplusplus) || defined(CINTERFACE)) && defined(COBJMACROS)
239 #define IRecycleBinFile_QueryInterface(This, riid, ppvObject) \
240     (This)->lpVtbl->QueryInterface(This, riid, ppvObject)
241 #define IRecycleBinFile_AddRef(This) \
242     (This)->lpVtbl->AddRef(This)
243 #define IRecycleBinFile_Release(This) \
244     (This)->lpVtbl->Release(This)
245 #define IRecycleBinFile_IsEqualIdentity(This, pFI) \
246     (This)->lpVtbl->IsEqualIdentity(This, pFI)
247 #define IRecycleBinFile_GetInfo(This, pInfo) \
248     (This)->lpVtbl->GetInfo(This, pInfo)
249 #define IRecycleBinFile_GetLastModificationTime(This, pLastModificationTime) \
250     (This)->lpVtbl->GetLastModificationTime(This, pLastModificationTime)
251 #define IRecycleBinFile_GetDeletionTime(This, pDeletionTime) \
252     (This)->lpVtbl->GetDeletionTime(This, pDeletionTime)
253 #define IRecycleBinFile_GetFileSize(This, pFileSize) \
254     (This)->lpVtbl->GetFileSize(This, pFileSize)
255 #define IRecycleBinFile_GetPhysicalFileSize(This, pPhysicalFileSize) \
256     (This)->lpVtbl->GetPhysicalFileSize(This, pPhysicalFileSize)
257 #define IRecycleBinFile_GetAttributes(This, pAttributes) \
258     (This)->lpVtbl->GetAttributes(This, pAttributes)
259 #define IRecycleBinFile_GetFileName(This, BufferSize, Buffer, RequiredSize) \
260     (This)->lpVtbl->GetFileName(This, BufferSize, Buffer, RequiredSize)
261 #define IRecycleBinFile_Delete(This) \
262     (This)->lpVtbl->Delete(This)
263 #define IRecycleBinFile_Restore(This) \
264     (This)->lpVtbl->Restore(This)
265 
266 #define IRecycleBinEnumList_QueryInterface(This, riid, ppvObject) \
267     (This)->lpVtbl->QueryInterface(This, riid, ppvObject)
268 #define IRecycleBinEnumList_AddRef(This) \
269     (This)->lpVtbl->AddRef(This)
270 #define IRecycleBinEnumList_Release(This) \
271     (This)->lpVtbl->Release(This)
272 #define IRecycleBinEnumList_Next(This, celt, rgelt, pceltFetched) \
273     (This)->lpVtbl->Next(This, celt, rgelt, pceltFetched)
274 #define IRecycleBinEnumList_Skip(This, celt) \
275     (This)->lpVtbl->Skip(This, celt)
276 #define IRecycleBinEnumList_Reset(This) \
277     (This)->lpVtbl->Reset(This)
278 
279 #define IRecycleBin_QueryInterface(This, riid, ppvObject) \
280     (This)->lpVtbl->QueryInterface(This, riid, ppvObject)
281 #define IRecycleBin_AddRef(This) \
282     (This)->lpVtbl->AddRef(This)
283 #define IRecycleBin_Release(This) \
284     (This)->lpVtbl->Release(This)
285 #define IRecycleBin_DeleteFile(This, szFileName) \
286     (This)->lpVtbl->DeleteFile(This, szFileName)
287 #define IRecycleBin_EmptyRecycleBin(This) \
288     (This)->lpVtbl->EmptyRecycleBin(This)
289 #define IRecycleBin_EnumObjects(This, ppEnumList) \
290     (This)->lpVtbl->EnumObjects(This, ppEnumList)
291 #define IRecycleBin_GetDirectory(This, szPath) \
292     (This)->lpVtbl->GetDirectory(This, szPath)
293 #endif
294 
295 EXTERN_C HRESULT
296 GetDefaultRecycleBin(
297     IN LPCWSTR pszVolume OPTIONAL,
298     OUT IRecycleBin **pprb);
299 
300 /* Recycle Bin shell folder internal API */
301 void CRecycleBin_NotifyRecycled(LPCWSTR OrigPath, const WIN32_FIND_DATAW *pFind,
302                                 const RECYCLEBINFILEIDENTITY *pFI);
303 
304 
305 #ifdef __cplusplus
306 }
307 #endif
308