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
);
98 IN LPCSTR pszRoot OPTIONAL
)
101 LPWSTR szRootW
= NULL
;
104 TRACE("(%s)\n", debugstr_a(pszRoot
));
108 len
= MultiByteToWideChar(CP_ACP
, 0, pszRoot
, -1, NULL
, 0);
111 szRootW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
114 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
117 if (MultiByteToWideChar(CP_ACP
, 0, pszRoot
, -1, szRootW
, len
) == 0)
121 ret
= EmptyRecycleBinW(szRootW
);
124 HeapFree(GetProcessHeap(), 0, szRootW
);
130 IN LPCWSTR pszRoot OPTIONAL
)
135 TRACE("(%s)\n", debugstr_w(pszRoot
));
137 hr
= GetDefaultRecycleBin(pszRoot
, &prb
);
141 hr
= IRecycleBin_EmptyRecycleBin(prb
);
142 IRecycleBin_Release(prb
);
147 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
148 SetLastError(HRESULT_CODE(hr
));
150 SetLastError(ERROR_GEN_FAILURE
);
155 EnumerateRecycleBinA(
156 IN LPCSTR pszRoot OPTIONAL
,
157 IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback
,
158 IN PVOID Context OPTIONAL
)
161 LPWSTR szRootW
= NULL
;
164 TRACE("(%s, %p, %p)\n", debugstr_a(pszRoot
), pFnCallback
, Context
);
168 len
= MultiByteToWideChar(CP_ACP
, 0, pszRoot
, -1, NULL
, 0);
171 szRootW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
174 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
177 if (MultiByteToWideChar(CP_ACP
, 0, pszRoot
, -1, szRootW
, len
) == 0)
181 ret
= EnumerateRecycleBinW(szRootW
, pFnCallback
, Context
);
184 HeapFree(GetProcessHeap(), 0, szRootW
);
189 EnumerateRecycleBinW(
190 IN LPCWSTR pszRoot OPTIONAL
,
191 IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback
,
192 IN PVOID Context OPTIONAL
)
194 IRecycleBin
*prb
= NULL
;
195 IRecycleBinEnumList
*prbel
= NULL
;
196 IRecycleBinFile
*prbf
;
199 TRACE("(%s, %p, %p)\n", debugstr_w(pszRoot
), pFnCallback
, Context
);
201 hr
= GetDefaultRecycleBin(NULL
, &prb
);
205 hr
= IRecycleBin_EnumObjects(prb
, &prbel
);
210 hr
= IRecycleBinEnumList_Next(prbel
, 1, &prbf
, NULL
);
216 else if (!SUCCEEDED(hr
))
218 if (!pFnCallback(Context
, (HANDLE
)prbf
))
220 hr
= HRESULT_FROM_WIN32(GetLastError());
227 IRecycleBin_Release(prb
);
229 IRecycleBinEnumList_Release(prbel
);
232 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
233 SetLastError(HRESULT_CODE(hr
));
235 SetLastError(ERROR_GEN_FAILURE
);
240 GetDeletedFileDetailsA(
241 IN HANDLE hDeletedFile
,
243 IN OUT PDELETED_FILE_DETAILS_A FileDetails OPTIONAL
,
244 OUT LPDWORD RequiredSize OPTIONAL
)
246 PDELETED_FILE_DETAILS_W FileDetailsW
= NULL
;
247 DWORD BufferSizeW
= 0;
250 TRACE("(%p, %lu, %p, %p)\n", hDeletedFile
, BufferSize
, FileDetails
, RequiredSize
);
252 if (BufferSize
>= FIELD_OFFSET(DELETED_FILE_DETAILS_A
, FileName
))
254 BufferSizeW
= FIELD_OFFSET(DELETED_FILE_DETAILS_W
, FileName
)
255 + (BufferSize
- FIELD_OFFSET(DELETED_FILE_DETAILS_A
, FileName
)) * sizeof(WCHAR
);
257 if (FileDetails
&& BufferSizeW
)
259 FileDetailsW
= HeapAlloc(GetProcessHeap(), 0, BufferSizeW
);
262 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
267 ret
= GetDeletedFileDetailsW(hDeletedFile
, BufferSizeW
, FileDetailsW
, RequiredSize
);
273 CopyMemory(FileDetails
, FileDetailsW
, FIELD_OFFSET(DELETED_FILE_DETAILS_A
, FileName
));
274 if (0 == WideCharToMultiByte(CP_ACP
, 0, FileDetailsW
->FileName
, -1, FileDetails
->FileName
, BufferSize
- FIELD_OFFSET(DELETED_FILE_DETAILS_A
, FileName
), NULL
, NULL
))
280 HeapFree(GetProcessHeap(), 0, FileDetailsW
);
285 GetDeletedFileDetailsW(
286 IN HANDLE hDeletedFile
,
288 IN OUT PDELETED_FILE_DETAILS_W FileDetails OPTIONAL
,
289 OUT LPDWORD RequiredSize OPTIONAL
)
291 IRecycleBinFile
*rbf
= (IRecycleBinFile
*)hDeletedFile
;
293 SIZE_T NameSize
, Needed
;
295 TRACE("(%p, %lu, %p, %p)\n", hDeletedFile
, BufferSize
, FileDetails
, RequiredSize
);
297 hr
= IRecycleBinFile_GetFileName(rbf
, 0, NULL
, &NameSize
);
300 Needed
= FIELD_OFFSET(DELETED_FILE_DETAILS_W
, FileName
) + NameSize
;
302 *RequiredSize
= (DWORD
)Needed
;
303 if (Needed
> BufferSize
)
305 hr
= HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
);
308 hr
= IRecycleBinFile_GetFileName(rbf
, NameSize
, FileDetails
->FileName
, NULL
);
311 hr
= IRecycleBinFile_GetLastModificationTime(rbf
, &FileDetails
->LastModification
);
314 hr
= IRecycleBinFile_GetDeletionTime(rbf
, &FileDetails
->DeletionTime
);
317 hr
= IRecycleBinFile_GetFileSize(rbf
, &FileDetails
->FileSize
);
320 hr
= IRecycleBinFile_GetPhysicalFileSize(rbf
, &FileDetails
->PhysicalFileSize
);
323 hr
= IRecycleBinFile_GetAttributes(rbf
, &FileDetails
->Attributes
);
330 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
331 SetLastError(HRESULT_CODE(hr
));
333 SetLastError(ERROR_GEN_FAILURE
);
339 IN HANDLE hDeletedFile
)
341 IRecycleBinFile
*rbf
= (IRecycleBinFile
*)hDeletedFile
;
344 TRACE("(%p)\n", hDeletedFile
);
346 hr
= IRecycleBinFile_Restore(rbf
);
349 if (HRESULT_FACILITY(hr
) == FACILITY_WIN32
)
350 SetLastError(HRESULT_CODE(hr
));
352 SetLastError(ERROR_GEN_FAILURE
);
357 GetDefaultRecycleBin(
358 IN LPCWSTR pszVolume OPTIONAL
,
359 OUT IRecycleBin
**pprb
)
364 TRACE("(%s, %p)\n", debugstr_w(pszVolume
), pprb
);
370 hr
= RecycleBinGeneric_Constructor(&pUnk
);
373 /* FIXME: do a better validation! */
374 if (wcslen(pszVolume
) != 3 || pszVolume
[1] != ':' || pszVolume
[2] != '\\')
375 return HRESULT_FROM_WIN32(ERROR_INVALID_NAME
);
377 /* For now, only support this type of recycle bins... */
378 hr
= RecycleBin5_Constructor(pszVolume
, &pUnk
);
382 hr
= IUnknown_QueryInterface(pUnk
, &IID_IRecycleBin
, (void **)pprb
);
383 IUnknown_Release(pUnk
);