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)
10 #include "recyclebin_private.h"
13 WINE_DEFAULT_DEBUG_CHANNEL(recyclebin
);
16 CloseRecycleBinHandle(
17 IN HANDLE hDeletedFile
)
19 IRecycleBinFile
*rbf
= (IRecycleBinFile
*)hDeletedFile
;
22 TRACE("(%p)\n", hDeletedFile
);
24 hr
= IRecycleBinFile_Release(rbf
);
27 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
28 SetLastError(HRESULT_CODE(hr
));
30 SetLastError(ERROR_GEN_FAILURE
);
35 DeleteFileToRecycleBinA(
39 LPWSTR FileNameW
= NULL
;
42 TRACE("(%s)\n", debugstr_a(FileName
));
44 /* Check parameters */
47 SetLastError(ERROR_INVALID_PARAMETER
);
51 len
= MultiByteToWideChar(CP_ACP
, 0, FileName
, -1, NULL
, 0);
54 FileNameW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
57 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
60 if (MultiByteToWideChar(CP_ACP
, 0, FileName
, -1, FileNameW
, len
) == 0)
63 ret
= DeleteFileToRecycleBinW(FileNameW
);
66 HeapFree(GetProcessHeap(), 0, FileNameW
);
71 DeleteFileToRecycleBinW(
77 TRACE("(%s)\n", debugstr_w(FileName
));
79 hr
= GetDefaultRecycleBin(NULL
, &prb
);
83 hr
= IRecycleBin_DeleteFile(prb
, FileName
);
84 IRecycleBin_Release(prb
);
89 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
90 SetLastError(HRESULT_CODE(hr
));
92 SetLastError(ERROR_GEN_FAILURE
);
97 DeleteFileHandleToRecycleBin(
98 IN HANDLE hDeletedFile
)
100 IRecycleBinFile
*rbf
= (IRecycleBinFile
*)hDeletedFile
;
103 TRACE("(%p)\n", hDeletedFile
);
105 hr
= IRecycleBinFile_Delete(rbf
);
109 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
110 SetLastError(HRESULT_CODE(hr
));
112 SetLastError(ERROR_GEN_FAILURE
);
118 IN LPCSTR pszRoot OPTIONAL
)
121 LPWSTR szRootW
= NULL
;
124 TRACE("(%s)\n", debugstr_a(pszRoot
));
128 len
= MultiByteToWideChar(CP_ACP
, 0, pszRoot
, -1, NULL
, 0);
131 szRootW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
134 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
137 if (MultiByteToWideChar(CP_ACP
, 0, pszRoot
, -1, szRootW
, len
) == 0)
141 ret
= EmptyRecycleBinW(szRootW
);
144 HeapFree(GetProcessHeap(), 0, szRootW
);
150 IN LPCWSTR pszRoot OPTIONAL
)
155 TRACE("(%s)\n", debugstr_w(pszRoot
));
157 hr
= GetDefaultRecycleBin(pszRoot
, &prb
);
161 hr
= IRecycleBin_EmptyRecycleBin(prb
);
162 IRecycleBin_Release(prb
);
167 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
168 SetLastError(HRESULT_CODE(hr
));
170 SetLastError(ERROR_GEN_FAILURE
);
175 EnumerateRecycleBinA(
176 IN LPCSTR pszRoot OPTIONAL
,
177 IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback
,
178 IN PVOID Context OPTIONAL
)
181 LPWSTR szRootW
= NULL
;
184 TRACE("(%s, %p, %p)\n", debugstr_a(pszRoot
), pFnCallback
, Context
);
188 len
= MultiByteToWideChar(CP_ACP
, 0, pszRoot
, -1, NULL
, 0);
191 szRootW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
194 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
197 if (MultiByteToWideChar(CP_ACP
, 0, pszRoot
, -1, szRootW
, len
) == 0)
201 ret
= EnumerateRecycleBinW(szRootW
, pFnCallback
, Context
);
204 HeapFree(GetProcessHeap(), 0, szRootW
);
209 EnumerateRecycleBinW(
210 IN LPCWSTR pszRoot OPTIONAL
,
211 IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback
,
212 IN PVOID Context OPTIONAL
)
214 IRecycleBin
*prb
= NULL
;
215 IRecycleBinEnumList
*prbel
= NULL
;
216 IRecycleBinFile
*prbf
;
219 TRACE("(%s, %p, %p)\n", debugstr_w(pszRoot
), pFnCallback
, Context
);
221 hr
= GetDefaultRecycleBin(NULL
, &prb
);
225 hr
= IRecycleBin_EnumObjects(prb
, &prbel
);
230 hr
= IRecycleBinEnumList_Next(prbel
, 1, &prbf
, NULL
);
236 else if (!SUCCEEDED(hr
))
238 if (!pFnCallback(Context
, (HANDLE
)prbf
))
240 hr
= HRESULT_FROM_WIN32(GetLastError());
247 IRecycleBin_Release(prb
);
249 IRecycleBinEnumList_Release(prbel
);
252 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
253 SetLastError(HRESULT_CODE(hr
));
255 SetLastError(ERROR_GEN_FAILURE
);
260 GetDeletedFileDetailsA(
261 IN HANDLE hDeletedFile
,
263 IN OUT PDELETED_FILE_DETAILS_A FileDetails OPTIONAL
,
264 OUT LPDWORD RequiredSize OPTIONAL
)
266 PDELETED_FILE_DETAILS_W FileDetailsW
= NULL
;
267 DWORD BufferSizeW
= 0;
270 TRACE("(%p, %lu, %p, %p)\n", hDeletedFile
, BufferSize
, FileDetails
, RequiredSize
);
272 if (BufferSize
>= FIELD_OFFSET(DELETED_FILE_DETAILS_A
, FileName
))
274 BufferSizeW
= FIELD_OFFSET(DELETED_FILE_DETAILS_W
, FileName
)
275 + (BufferSize
- FIELD_OFFSET(DELETED_FILE_DETAILS_A
, FileName
)) * sizeof(WCHAR
);
277 if (FileDetails
&& BufferSizeW
)
279 FileDetailsW
= HeapAlloc(GetProcessHeap(), 0, BufferSizeW
);
282 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
287 ret
= GetDeletedFileDetailsW(hDeletedFile
, BufferSizeW
, FileDetailsW
, RequiredSize
);
293 CopyMemory(FileDetails
, FileDetailsW
, FIELD_OFFSET(DELETED_FILE_DETAILS_A
, FileName
));
294 if (0 == WideCharToMultiByte(CP_ACP
, 0, FileDetailsW
->FileName
, -1, FileDetails
->FileName
, BufferSize
- FIELD_OFFSET(DELETED_FILE_DETAILS_A
, FileName
), NULL
, NULL
))
300 HeapFree(GetProcessHeap(), 0, FileDetailsW
);
305 GetDeletedFileDetailsW(
306 IN HANDLE hDeletedFile
,
308 IN OUT PDELETED_FILE_DETAILS_W FileDetails OPTIONAL
,
309 OUT LPDWORD RequiredSize OPTIONAL
)
311 IRecycleBinFile
*rbf
= (IRecycleBinFile
*)hDeletedFile
;
313 SIZE_T NameSize
, Needed
;
315 TRACE("(%p, %lu, %p, %p)\n", hDeletedFile
, BufferSize
, FileDetails
, RequiredSize
);
317 hr
= IRecycleBinFile_GetFileName(rbf
, 0, NULL
, &NameSize
);
320 Needed
= FIELD_OFFSET(DELETED_FILE_DETAILS_W
, FileName
) + NameSize
;
322 *RequiredSize
= (DWORD
)Needed
;
323 if (Needed
> BufferSize
)
325 hr
= HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
);
328 hr
= IRecycleBinFile_GetFileName(rbf
, NameSize
, FileDetails
->FileName
, NULL
);
331 hr
= IRecycleBinFile_GetLastModificationTime(rbf
, &FileDetails
->LastModification
);
334 hr
= IRecycleBinFile_GetDeletionTime(rbf
, &FileDetails
->DeletionTime
);
337 hr
= IRecycleBinFile_GetFileSize(rbf
, &FileDetails
->FileSize
);
340 hr
= IRecycleBinFile_GetPhysicalFileSize(rbf
, &FileDetails
->PhysicalFileSize
);
343 hr
= IRecycleBinFile_GetAttributes(rbf
, &FileDetails
->Attributes
);
350 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
351 SetLastError(HRESULT_CODE(hr
));
353 SetLastError(ERROR_GEN_FAILURE
);
358 GetRecycleBinDetails(
359 IN LPCWSTR pszVolume OPTIONAL
,
360 OUT ULARGE_INTEGER
*pulTotalItems
,
361 OUT ULARGE_INTEGER
*pulTotalSize
)
363 pulTotalItems
->QuadPart
= 0;
364 pulTotalSize
->QuadPart
= 0;
365 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
371 IN HANDLE hDeletedFile
)
373 IRecycleBinFile
*rbf
= (IRecycleBinFile
*)hDeletedFile
;
376 TRACE("(%p)\n", hDeletedFile
);
378 hr
= IRecycleBinFile_Restore(rbf
);
381 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
382 SetLastError(HRESULT_CODE(hr
));
384 SetLastError(ERROR_GEN_FAILURE
);
389 GetDefaultRecycleBin(
390 IN LPCWSTR pszVolume OPTIONAL
,
391 OUT IRecycleBin
**pprb
)
396 TRACE("(%s, %p)\n", debugstr_w(pszVolume
), pprb
);
402 hr
= RecycleBinGeneric_Constructor(&pUnk
);
405 /* FIXME: do a better validation! */
406 if (wcslen(pszVolume
) != 3 || pszVolume
[1] != ':' || pszVolume
[2] != '\\')
407 return HRESULT_FROM_WIN32(ERROR_INVALID_NAME
);
409 /* For now, only support this type of recycle bins... */
410 hr
= RecycleBin5_Constructor(pszVolume
, &pUnk
);
414 hr
= IUnknown_QueryInterface(pUnk
, &IID_IRecycleBin
, (void **)pprb
);
415 IUnknown_Release(pUnk
);