2 * PROJECT: Recycle bin management
3 * LICENSE: GPL v2 - See COPYING in the top level directory
4 * FILE: lib/recyclebin/recyclebin.c
5 * PURPOSE: Public interface
6 * PROGRAMMERS: Copyright 2006-2007 Hervé Poussineau (hpoussin@reactos.org)
9 #include "recyclebin_private.h"
12 CloseRecycleBinHandle(
13 IN HANDLE hDeletedFile
)
15 IRecycleBinFile
*rbf
= (IRecycleBinFile
*)hDeletedFile
;
18 TRACE("(%p)\n", hDeletedFile
);
20 hr
= IRecycleBinFile_Release(rbf
);
23 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
24 SetLastError(HRESULT_CODE(hr
));
26 SetLastError(ERROR_GEN_FAILURE
);
31 DeleteFileToRecycleBinA(
35 LPWSTR FileNameW
= NULL
;
38 TRACE("(%s)\n", debugstr_a(FileName
));
40 /* Check parameters */
43 SetLastError(ERROR_INVALID_PARAMETER
);
47 len
= MultiByteToWideChar(CP_ACP
, 0, FileName
, -1, NULL
, 0);
50 FileNameW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
53 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
56 if (MultiByteToWideChar(CP_ACP
, 0, FileName
, -1, FileNameW
, len
) == 0)
59 ret
= DeleteFileToRecycleBinW(FileNameW
);
62 HeapFree(GetProcessHeap(), 0, FileNameW
);
67 DeleteFileToRecycleBinW(
73 TRACE("(%s)\n", debugstr_w(FileName
));
75 hr
= GetDefaultRecycleBin(NULL
, &prb
);
79 hr
= IRecycleBin_DeleteFile(prb
, FileName
);
80 IRecycleBin_Release(prb
);
85 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
86 SetLastError(HRESULT_CODE(hr
));
88 SetLastError(ERROR_GEN_FAILURE
);
93 DeleteFileHandleToRecycleBin(
94 IN HANDLE hDeletedFile
)
96 IRecycleBinFile
*rbf
= (IRecycleBinFile
*)hDeletedFile
;
99 TRACE("(%p)\n", hDeletedFile
);
101 hr
= IRecycleBinFile_Delete(rbf
);
105 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
106 SetLastError(HRESULT_CODE(hr
));
108 SetLastError(ERROR_GEN_FAILURE
);
114 IN LPCSTR pszRoot OPTIONAL
)
117 LPWSTR szRootW
= NULL
;
120 TRACE("(%s)\n", debugstr_a(pszRoot
));
124 len
= MultiByteToWideChar(CP_ACP
, 0, pszRoot
, -1, NULL
, 0);
127 szRootW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
130 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
133 if (MultiByteToWideChar(CP_ACP
, 0, pszRoot
, -1, szRootW
, len
) == 0)
137 ret
= EmptyRecycleBinW(szRootW
);
140 HeapFree(GetProcessHeap(), 0, szRootW
);
146 IN LPCWSTR pszRoot OPTIONAL
)
151 TRACE("(%s)\n", debugstr_w(pszRoot
));
153 hr
= GetDefaultRecycleBin(pszRoot
, &prb
);
157 hr
= IRecycleBin_EmptyRecycleBin(prb
);
158 IRecycleBin_Release(prb
);
163 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
164 SetLastError(HRESULT_CODE(hr
));
166 SetLastError(ERROR_GEN_FAILURE
);
171 EnumerateRecycleBinA(
172 IN LPCSTR pszRoot OPTIONAL
,
173 IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback
,
174 IN PVOID Context OPTIONAL
)
177 LPWSTR szRootW
= NULL
;
180 TRACE("(%s, %p, %p)\n", debugstr_a(pszRoot
), pFnCallback
, Context
);
184 len
= MultiByteToWideChar(CP_ACP
, 0, pszRoot
, -1, NULL
, 0);
187 szRootW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
190 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
193 if (MultiByteToWideChar(CP_ACP
, 0, pszRoot
, -1, szRootW
, len
) == 0)
197 ret
= EnumerateRecycleBinW(szRootW
, pFnCallback
, Context
);
200 HeapFree(GetProcessHeap(), 0, szRootW
);
205 EnumerateRecycleBinW(
206 IN LPCWSTR pszRoot OPTIONAL
,
207 IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback
,
208 IN PVOID Context OPTIONAL
)
210 IRecycleBin
*prb
= NULL
;
211 IRecycleBinEnumList
*prbel
= NULL
;
212 IRecycleBinFile
*prbf
;
215 TRACE("(%s, %p, %p)\n", debugstr_w(pszRoot
), pFnCallback
, Context
);
217 hr
= GetDefaultRecycleBin(NULL
, &prb
);
221 hr
= IRecycleBin_EnumObjects(prb
, &prbel
);
226 hr
= IRecycleBinEnumList_Next(prbel
, 1, &prbf
, NULL
);
232 else if (!SUCCEEDED(hr
))
234 if (!pFnCallback(Context
, (HANDLE
)prbf
))
236 hr
= HRESULT_FROM_WIN32(GetLastError());
243 IRecycleBin_Release(prb
);
245 IRecycleBinEnumList_Release(prbel
);
248 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
249 SetLastError(HRESULT_CODE(hr
));
251 SetLastError(ERROR_GEN_FAILURE
);
256 GetDeletedFileDetailsA(
257 IN HANDLE hDeletedFile
,
259 IN OUT PDELETED_FILE_DETAILS_A FileDetails OPTIONAL
,
260 OUT LPDWORD RequiredSize OPTIONAL
)
262 PDELETED_FILE_DETAILS_W FileDetailsW
= NULL
;
263 DWORD BufferSizeW
= 0;
266 TRACE("(%p, %lu, %p, %p)\n", hDeletedFile
, BufferSize
, FileDetails
, RequiredSize
);
268 if (BufferSize
>= FIELD_OFFSET(DELETED_FILE_DETAILS_A
, FileName
))
270 BufferSizeW
= FIELD_OFFSET(DELETED_FILE_DETAILS_W
, FileName
)
271 + (BufferSize
- FIELD_OFFSET(DELETED_FILE_DETAILS_A
, FileName
)) * sizeof(WCHAR
);
273 if (FileDetails
&& BufferSizeW
)
275 FileDetailsW
= HeapAlloc(GetProcessHeap(), 0, BufferSizeW
);
278 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
283 ret
= GetDeletedFileDetailsW(hDeletedFile
, BufferSizeW
, FileDetailsW
, RequiredSize
);
289 CopyMemory(FileDetails
, FileDetailsW
, FIELD_OFFSET(DELETED_FILE_DETAILS_A
, FileName
));
290 if (0 == WideCharToMultiByte(CP_ACP
, 0, FileDetailsW
->FileName
, -1, FileDetails
->FileName
, BufferSize
- FIELD_OFFSET(DELETED_FILE_DETAILS_A
, FileName
), NULL
, NULL
))
296 HeapFree(GetProcessHeap(), 0, FileDetailsW
);
301 GetDeletedFileDetailsW(
302 IN HANDLE hDeletedFile
,
304 IN OUT PDELETED_FILE_DETAILS_W FileDetails OPTIONAL
,
305 OUT LPDWORD RequiredSize OPTIONAL
)
307 IRecycleBinFile
*rbf
= (IRecycleBinFile
*)hDeletedFile
;
309 SIZE_T NameSize
, Needed
;
311 TRACE("(%p, %lu, %p, %p)\n", hDeletedFile
, BufferSize
, FileDetails
, RequiredSize
);
313 hr
= IRecycleBinFile_GetFileName(rbf
, 0, NULL
, &NameSize
);
316 Needed
= FIELD_OFFSET(DELETED_FILE_DETAILS_W
, FileName
) + NameSize
;
318 *RequiredSize
= (DWORD
)Needed
;
319 if (Needed
> BufferSize
)
321 hr
= HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
);
324 hr
= IRecycleBinFile_GetFileName(rbf
, NameSize
, FileDetails
->FileName
, NULL
);
327 hr
= IRecycleBinFile_GetLastModificationTime(rbf
, &FileDetails
->LastModification
);
330 hr
= IRecycleBinFile_GetDeletionTime(rbf
, &FileDetails
->DeletionTime
);
333 hr
= IRecycleBinFile_GetFileSize(rbf
, &FileDetails
->FileSize
);
336 hr
= IRecycleBinFile_GetPhysicalFileSize(rbf
, &FileDetails
->PhysicalFileSize
);
339 hr
= IRecycleBinFile_GetAttributes(rbf
, &FileDetails
->Attributes
);
346 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
347 SetLastError(HRESULT_CODE(hr
));
349 SetLastError(ERROR_GEN_FAILURE
);
354 GetRecycleBinDetails(
355 IN LPCWSTR pszVolume OPTIONAL
,
356 OUT ULARGE_INTEGER
*pulTotalItems
,
357 OUT ULARGE_INTEGER
*pulTotalSize
)
359 pulTotalItems
->QuadPart
= 0;
360 pulTotalSize
->QuadPart
= 0;
361 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
367 IN HANDLE hDeletedFile
)
369 IRecycleBinFile
*rbf
= (IRecycleBinFile
*)hDeletedFile
;
372 TRACE("(%p)\n", hDeletedFile
);
374 hr
= IRecycleBinFile_Restore(rbf
);
377 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
378 SetLastError(HRESULT_CODE(hr
));
380 SetLastError(ERROR_GEN_FAILURE
);
385 GetDefaultRecycleBin(
386 IN LPCWSTR pszVolume OPTIONAL
,
387 OUT IRecycleBin
**pprb
)
392 TRACE("(%s, %p)\n", debugstr_w(pszVolume
), pprb
);
398 hr
= RecycleBinGeneric_Constructor(&pUnk
);
401 /* FIXME: do a better validation! */
402 if (wcslen(pszVolume
) != 3 || pszVolume
[1] != ':' || pszVolume
[2] != '\\')
403 return HRESULT_FROM_WIN32(ERROR_INVALID_NAME
);
405 /* For now, only support this type of recycle bins... */
406 hr
= RecycleBin5_Constructor(pszVolume
, &pUnk
);
410 hr
= IUnknown_QueryInterface(pUnk
, &IID_IRecycleBin
, (void **)pprb
);
411 IUnknown_Release(pUnk
);