[RECYCLEBIN] tabs to spaces (no code changes)

svn path=/trunk/; revision=68961
This commit is contained in:
Christoph von Wittich 2015-09-03 17:40:13 +00:00
parent d4e8254f9e
commit acbf8ce925
7 changed files with 1525 additions and 1525 deletions

View file

@ -10,404 +10,404 @@
BOOL WINAPI BOOL WINAPI
CloseRecycleBinHandle( CloseRecycleBinHandle(
IN HANDLE hDeletedFile) IN HANDLE hDeletedFile)
{ {
IRecycleBinFile *rbf = (IRecycleBinFile *)hDeletedFile; IRecycleBinFile *rbf = (IRecycleBinFile *)hDeletedFile;
HRESULT hr; HRESULT hr;
TRACE("(%p)\n", hDeletedFile); TRACE("(%p)\n", hDeletedFile);
hr = IRecycleBinFile_Release(rbf); hr = IRecycleBinFile_Release(rbf);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
return TRUE; return TRUE;
if (HRESULT_FACILITY(hr) == FACILITY_WIN32) if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
SetLastError(HRESULT_CODE(hr)); SetLastError(HRESULT_CODE(hr));
else else
SetLastError(ERROR_GEN_FAILURE); SetLastError(ERROR_GEN_FAILURE);
return FALSE; return FALSE;
} }
BOOL WINAPI BOOL WINAPI
DeleteFileToRecycleBinA( DeleteFileToRecycleBinA(
IN LPCSTR FileName) IN LPCSTR FileName)
{ {
int len; int len;
LPWSTR FileNameW = NULL; LPWSTR FileNameW = NULL;
BOOL ret = FALSE; BOOL ret = FALSE;
TRACE("(%s)\n", debugstr_a(FileName)); TRACE("(%s)\n", debugstr_a(FileName));
/* Check parameters */ /* Check parameters */
if (FileName == NULL) if (FileName == NULL)
{ {
SetLastError(ERROR_INVALID_PARAMETER); SetLastError(ERROR_INVALID_PARAMETER);
goto cleanup; goto cleanup;
} }
len = MultiByteToWideChar(CP_ACP, 0, FileName, -1, NULL, 0); len = MultiByteToWideChar(CP_ACP, 0, FileName, -1, NULL, 0);
if (len == 0) if (len == 0)
goto cleanup; goto cleanup;
FileNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); FileNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if (!FileNameW) if (!FileNameW)
{ {
SetLastError(ERROR_NOT_ENOUGH_MEMORY); SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto cleanup; goto cleanup;
} }
if (MultiByteToWideChar(CP_ACP, 0, FileName, -1, FileNameW, len) == 0) if (MultiByteToWideChar(CP_ACP, 0, FileName, -1, FileNameW, len) == 0)
goto cleanup; goto cleanup;
ret = DeleteFileToRecycleBinW(FileNameW); ret = DeleteFileToRecycleBinW(FileNameW);
cleanup: cleanup:
HeapFree(GetProcessHeap(), 0, FileNameW); HeapFree(GetProcessHeap(), 0, FileNameW);
return ret; return ret;
} }
BOOL WINAPI BOOL WINAPI
DeleteFileToRecycleBinW( DeleteFileToRecycleBinW(
IN LPCWSTR FileName) IN LPCWSTR FileName)
{ {
IRecycleBin *prb; IRecycleBin *prb;
HRESULT hr; HRESULT hr;
TRACE("(%s)\n", debugstr_w(FileName)); TRACE("(%s)\n", debugstr_w(FileName));
hr = GetDefaultRecycleBin(NULL, &prb); hr = GetDefaultRecycleBin(NULL, &prb);
if (!SUCCEEDED(hr)) if (!SUCCEEDED(hr))
goto cleanup; goto cleanup;
hr = IRecycleBin_DeleteFile(prb, FileName); hr = IRecycleBin_DeleteFile(prb, FileName);
IRecycleBin_Release(prb); IRecycleBin_Release(prb);
cleanup: cleanup:
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
return TRUE; return TRUE;
if (HRESULT_FACILITY(hr) == FACILITY_WIN32) if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
SetLastError(HRESULT_CODE(hr)); SetLastError(HRESULT_CODE(hr));
else else
SetLastError(ERROR_GEN_FAILURE); SetLastError(ERROR_GEN_FAILURE);
return FALSE; return FALSE;
} }
BOOL WINAPI BOOL WINAPI
DeleteFileHandleToRecycleBin( DeleteFileHandleToRecycleBin(
IN HANDLE hDeletedFile) IN HANDLE hDeletedFile)
{ {
IRecycleBinFile *rbf = (IRecycleBinFile *)hDeletedFile; IRecycleBinFile *rbf = (IRecycleBinFile *)hDeletedFile;
HRESULT hr; HRESULT hr;
TRACE("(%p)\n", hDeletedFile); TRACE("(%p)\n", hDeletedFile);
hr = IRecycleBinFile_Delete(rbf); hr = IRecycleBinFile_Delete(rbf);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
return TRUE; return TRUE;
if (HRESULT_FACILITY(hr) == FACILITY_WIN32) if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
SetLastError(HRESULT_CODE(hr)); SetLastError(HRESULT_CODE(hr));
else else
SetLastError(ERROR_GEN_FAILURE); SetLastError(ERROR_GEN_FAILURE);
return FALSE; return FALSE;
} }
BOOL WINAPI BOOL WINAPI
EmptyRecycleBinA( EmptyRecycleBinA(
IN LPCSTR pszRoot OPTIONAL) IN LPCSTR pszRoot OPTIONAL)
{ {
int len; int len;
LPWSTR szRootW = NULL; LPWSTR szRootW = NULL;
BOOL ret = FALSE; BOOL ret = FALSE;
TRACE("(%s)\n", debugstr_a(pszRoot)); TRACE("(%s)\n", debugstr_a(pszRoot));
if (pszRoot) if (pszRoot)
{ {
len = MultiByteToWideChar(CP_ACP, 0, pszRoot, -1, NULL, 0); len = MultiByteToWideChar(CP_ACP, 0, pszRoot, -1, NULL, 0);
if (len == 0) if (len == 0)
goto cleanup; goto cleanup;
szRootW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); szRootW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if (!szRootW) if (!szRootW)
{ {
SetLastError(ERROR_NOT_ENOUGH_MEMORY); SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto cleanup; goto cleanup;
} }
if (MultiByteToWideChar(CP_ACP, 0, pszRoot, -1, szRootW, len) == 0) if (MultiByteToWideChar(CP_ACP, 0, pszRoot, -1, szRootW, len) == 0)
goto cleanup; goto cleanup;
} }
ret = EmptyRecycleBinW(szRootW); ret = EmptyRecycleBinW(szRootW);
cleanup: cleanup:
HeapFree(GetProcessHeap(), 0, szRootW); HeapFree(GetProcessHeap(), 0, szRootW);
return ret; return ret;
} }
BOOL WINAPI BOOL WINAPI
EmptyRecycleBinW( EmptyRecycleBinW(
IN LPCWSTR pszRoot OPTIONAL) IN LPCWSTR pszRoot OPTIONAL)
{ {
IRecycleBin *prb; IRecycleBin *prb;
HRESULT hr; HRESULT hr;
TRACE("(%s)\n", debugstr_w(pszRoot)); TRACE("(%s)\n", debugstr_w(pszRoot));
hr = GetDefaultRecycleBin(pszRoot, &prb); hr = GetDefaultRecycleBin(pszRoot, &prb);
if (!SUCCEEDED(hr)) if (!SUCCEEDED(hr))
goto cleanup; goto cleanup;
hr = IRecycleBin_EmptyRecycleBin(prb); hr = IRecycleBin_EmptyRecycleBin(prb);
IRecycleBin_Release(prb); IRecycleBin_Release(prb);
cleanup: cleanup:
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
return TRUE; return TRUE;
if (HRESULT_FACILITY(hr) == FACILITY_WIN32) if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
SetLastError(HRESULT_CODE(hr)); SetLastError(HRESULT_CODE(hr));
else else
SetLastError(ERROR_GEN_FAILURE); SetLastError(ERROR_GEN_FAILURE);
return FALSE; return FALSE;
} }
BOOL WINAPI BOOL WINAPI
EnumerateRecycleBinA( EnumerateRecycleBinA(
IN LPCSTR pszRoot OPTIONAL, IN LPCSTR pszRoot OPTIONAL,
IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback, IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback,
IN PVOID Context OPTIONAL) IN PVOID Context OPTIONAL)
{ {
int len; int len;
LPWSTR szRootW = NULL; LPWSTR szRootW = NULL;
BOOL ret = FALSE; BOOL ret = FALSE;
TRACE("(%s, %p, %p)\n", debugstr_a(pszRoot), pFnCallback, Context); TRACE("(%s, %p, %p)\n", debugstr_a(pszRoot), pFnCallback, Context);
if (pszRoot) if (pszRoot)
{ {
len = MultiByteToWideChar(CP_ACP, 0, pszRoot, -1, NULL, 0); len = MultiByteToWideChar(CP_ACP, 0, pszRoot, -1, NULL, 0);
if (len == 0) if (len == 0)
goto cleanup; goto cleanup;
szRootW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); szRootW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if (!szRootW) if (!szRootW)
{ {
SetLastError(ERROR_NOT_ENOUGH_MEMORY); SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto cleanup; goto cleanup;
} }
if (MultiByteToWideChar(CP_ACP, 0, pszRoot, -1, szRootW, len) == 0) if (MultiByteToWideChar(CP_ACP, 0, pszRoot, -1, szRootW, len) == 0)
goto cleanup; goto cleanup;
} }
ret = EnumerateRecycleBinW(szRootW, pFnCallback, Context); ret = EnumerateRecycleBinW(szRootW, pFnCallback, Context);
cleanup: cleanup:
HeapFree(GetProcessHeap(), 0, szRootW); HeapFree(GetProcessHeap(), 0, szRootW);
return ret; return ret;
} }
BOOL WINAPI BOOL WINAPI
EnumerateRecycleBinW( EnumerateRecycleBinW(
IN LPCWSTR pszRoot OPTIONAL, IN LPCWSTR pszRoot OPTIONAL,
IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback, IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback,
IN PVOID Context OPTIONAL) IN PVOID Context OPTIONAL)
{ {
IRecycleBin *prb = NULL; IRecycleBin *prb = NULL;
IRecycleBinEnumList *prbel = NULL; IRecycleBinEnumList *prbel = NULL;
IRecycleBinFile *prbf; IRecycleBinFile *prbf;
HRESULT hr; HRESULT hr;
TRACE("(%s, %p, %p)\n", debugstr_w(pszRoot), pFnCallback, Context); TRACE("(%s, %p, %p)\n", debugstr_w(pszRoot), pFnCallback, Context);
hr = GetDefaultRecycleBin(NULL, &prb); hr = GetDefaultRecycleBin(NULL, &prb);
if (!SUCCEEDED(hr)) if (!SUCCEEDED(hr))
goto cleanup; goto cleanup;
hr = IRecycleBin_EnumObjects(prb, &prbel); hr = IRecycleBin_EnumObjects(prb, &prbel);
if (!SUCCEEDED(hr)) if (!SUCCEEDED(hr))
goto cleanup; goto cleanup;
while (TRUE) while (TRUE)
{ {
hr = IRecycleBinEnumList_Next(prbel, 1, &prbf, NULL); hr = IRecycleBinEnumList_Next(prbel, 1, &prbf, NULL);
if (hr == S_FALSE) if (hr == S_FALSE)
{ {
hr = S_OK; hr = S_OK;
goto cleanup; goto cleanup;
} }
else if (!SUCCEEDED(hr)) else if (!SUCCEEDED(hr))
goto cleanup; goto cleanup;
if (!pFnCallback(Context, (HANDLE)prbf)) if (!pFnCallback(Context, (HANDLE)prbf))
{ {
hr = HRESULT_FROM_WIN32(GetLastError()); hr = HRESULT_FROM_WIN32(GetLastError());
goto cleanup; goto cleanup;
} }
} }
cleanup: cleanup:
if (prb) if (prb)
IRecycleBin_Release(prb); IRecycleBin_Release(prb);
if (prbel) if (prbel)
IRecycleBinEnumList_Release(prbel); IRecycleBinEnumList_Release(prbel);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
return TRUE; return TRUE;
if (HRESULT_FACILITY(hr) == FACILITY_WIN32) if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
SetLastError(HRESULT_CODE(hr)); SetLastError(HRESULT_CODE(hr));
else else
SetLastError(ERROR_GEN_FAILURE); SetLastError(ERROR_GEN_FAILURE);
return FALSE; return FALSE;
} }
BOOL WINAPI BOOL WINAPI
GetDeletedFileDetailsA( GetDeletedFileDetailsA(
IN HANDLE hDeletedFile, IN HANDLE hDeletedFile,
IN DWORD BufferSize, IN DWORD BufferSize,
IN OUT PDELETED_FILE_DETAILS_A FileDetails OPTIONAL, IN OUT PDELETED_FILE_DETAILS_A FileDetails OPTIONAL,
OUT LPDWORD RequiredSize OPTIONAL) OUT LPDWORD RequiredSize OPTIONAL)
{ {
PDELETED_FILE_DETAILS_W FileDetailsW = NULL; PDELETED_FILE_DETAILS_W FileDetailsW = NULL;
DWORD BufferSizeW = 0; DWORD BufferSizeW = 0;
BOOL ret = FALSE; BOOL ret = FALSE;
TRACE("(%p, %lu, %p, %p)\n", hDeletedFile, BufferSize, FileDetails, RequiredSize); TRACE("(%p, %lu, %p, %p)\n", hDeletedFile, BufferSize, FileDetails, RequiredSize);
if (BufferSize >= FIELD_OFFSET(DELETED_FILE_DETAILS_A, FileName)) if (BufferSize >= FIELD_OFFSET(DELETED_FILE_DETAILS_A, FileName))
{ {
BufferSizeW = FIELD_OFFSET(DELETED_FILE_DETAILS_W, FileName) BufferSizeW = FIELD_OFFSET(DELETED_FILE_DETAILS_W, FileName)
+ (BufferSize - FIELD_OFFSET(DELETED_FILE_DETAILS_A, FileName)) * sizeof(WCHAR); + (BufferSize - FIELD_OFFSET(DELETED_FILE_DETAILS_A, FileName)) * sizeof(WCHAR);
} }
if (FileDetails && BufferSizeW) if (FileDetails && BufferSizeW)
{ {
FileDetailsW = HeapAlloc(GetProcessHeap(), 0, BufferSizeW); FileDetailsW = HeapAlloc(GetProcessHeap(), 0, BufferSizeW);
if (!FileDetailsW) if (!FileDetailsW)
{ {
SetLastError(ERROR_NOT_ENOUGH_MEMORY); SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto cleanup; goto cleanup;
} }
} }
ret = GetDeletedFileDetailsW(hDeletedFile, BufferSizeW, FileDetailsW, RequiredSize); ret = GetDeletedFileDetailsW(hDeletedFile, BufferSizeW, FileDetailsW, RequiredSize);
if (!ret) if (!ret)
goto cleanup; goto cleanup;
if (FileDetails) if (FileDetails)
{ {
CopyMemory(FileDetails, FileDetailsW, FIELD_OFFSET(DELETED_FILE_DETAILS_A, FileName)); CopyMemory(FileDetails, FileDetailsW, FIELD_OFFSET(DELETED_FILE_DETAILS_A, FileName));
if (0 == WideCharToMultiByte(CP_ACP, 0, FileDetailsW->FileName, -1, FileDetails->FileName, BufferSize - FIELD_OFFSET(DELETED_FILE_DETAILS_A, FileName), NULL, NULL)) if (0 == WideCharToMultiByte(CP_ACP, 0, FileDetailsW->FileName, -1, FileDetails->FileName, BufferSize - FIELD_OFFSET(DELETED_FILE_DETAILS_A, FileName), NULL, NULL))
goto cleanup; goto cleanup;
} }
ret = TRUE; ret = TRUE;
cleanup: cleanup:
HeapFree(GetProcessHeap(), 0, FileDetailsW); HeapFree(GetProcessHeap(), 0, FileDetailsW);
return ret; return ret;
} }
BOOL WINAPI BOOL WINAPI
GetDeletedFileDetailsW( GetDeletedFileDetailsW(
IN HANDLE hDeletedFile, IN HANDLE hDeletedFile,
IN DWORD BufferSize, IN DWORD BufferSize,
IN OUT PDELETED_FILE_DETAILS_W FileDetails OPTIONAL, IN OUT PDELETED_FILE_DETAILS_W FileDetails OPTIONAL,
OUT LPDWORD RequiredSize OPTIONAL) OUT LPDWORD RequiredSize OPTIONAL)
{ {
IRecycleBinFile *rbf = (IRecycleBinFile *)hDeletedFile; IRecycleBinFile *rbf = (IRecycleBinFile *)hDeletedFile;
HRESULT hr; HRESULT hr;
SIZE_T NameSize, Needed; SIZE_T NameSize, Needed;
TRACE("(%p, %lu, %p, %p)\n", hDeletedFile, BufferSize, FileDetails, RequiredSize); TRACE("(%p, %lu, %p, %p)\n", hDeletedFile, BufferSize, FileDetails, RequiredSize);
hr = IRecycleBinFile_GetFileName(rbf, 0, NULL, &NameSize); hr = IRecycleBinFile_GetFileName(rbf, 0, NULL, &NameSize);
if (!SUCCEEDED(hr)) if (!SUCCEEDED(hr))
goto cleanup; goto cleanup;
Needed = FIELD_OFFSET(DELETED_FILE_DETAILS_W, FileName) + NameSize; Needed = FIELD_OFFSET(DELETED_FILE_DETAILS_W, FileName) + NameSize;
if (RequiredSize) if (RequiredSize)
*RequiredSize = (DWORD)Needed; *RequiredSize = (DWORD)Needed;
if (Needed > BufferSize) if (Needed > BufferSize)
{ {
hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
goto cleanup; goto cleanup;
} }
hr = IRecycleBinFile_GetFileName(rbf, NameSize, FileDetails->FileName, NULL); hr = IRecycleBinFile_GetFileName(rbf, NameSize, FileDetails->FileName, NULL);
if (!SUCCEEDED(hr)) if (!SUCCEEDED(hr))
goto cleanup; goto cleanup;
hr = IRecycleBinFile_GetLastModificationTime(rbf, &FileDetails->LastModification); hr = IRecycleBinFile_GetLastModificationTime(rbf, &FileDetails->LastModification);
if (!SUCCEEDED(hr)) if (!SUCCEEDED(hr))
goto cleanup; goto cleanup;
hr = IRecycleBinFile_GetDeletionTime(rbf, &FileDetails->DeletionTime); hr = IRecycleBinFile_GetDeletionTime(rbf, &FileDetails->DeletionTime);
if (!SUCCEEDED(hr)) if (!SUCCEEDED(hr))
goto cleanup; goto cleanup;
hr = IRecycleBinFile_GetFileSize(rbf, &FileDetails->FileSize); hr = IRecycleBinFile_GetFileSize(rbf, &FileDetails->FileSize);
if (!SUCCEEDED(hr)) if (!SUCCEEDED(hr))
goto cleanup; goto cleanup;
hr = IRecycleBinFile_GetPhysicalFileSize(rbf, &FileDetails->PhysicalFileSize); hr = IRecycleBinFile_GetPhysicalFileSize(rbf, &FileDetails->PhysicalFileSize);
if (!SUCCEEDED(hr)) if (!SUCCEEDED(hr))
goto cleanup; goto cleanup;
hr = IRecycleBinFile_GetAttributes(rbf, &FileDetails->Attributes); hr = IRecycleBinFile_GetAttributes(rbf, &FileDetails->Attributes);
if (!SUCCEEDED(hr)) if (!SUCCEEDED(hr))
goto cleanup; goto cleanup;
cleanup: cleanup:
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
return TRUE; return TRUE;
if (HRESULT_FACILITY(hr) == FACILITY_WIN32) if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
SetLastError(HRESULT_CODE(hr)); SetLastError(HRESULT_CODE(hr));
else else
SetLastError(ERROR_GEN_FAILURE); SetLastError(ERROR_GEN_FAILURE);
return FALSE; return FALSE;
} }
BOOL WINAPI BOOL WINAPI
GetRecycleBinDetails( GetRecycleBinDetails(
IN LPCWSTR pszVolume OPTIONAL, IN LPCWSTR pszVolume OPTIONAL,
OUT ULARGE_INTEGER *pulTotalItems, OUT ULARGE_INTEGER *pulTotalItems,
OUT ULARGE_INTEGER *pulTotalSize) OUT ULARGE_INTEGER *pulTotalSize)
{ {
pulTotalItems->QuadPart = 0; pulTotalItems->QuadPart = 0;
pulTotalSize->QuadPart = 0; pulTotalSize->QuadPart = 0;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE; return FALSE;
} }
BOOL WINAPI BOOL WINAPI
RestoreFile( RestoreFile(
IN HANDLE hDeletedFile) IN HANDLE hDeletedFile)
{ {
IRecycleBinFile *rbf = (IRecycleBinFile *)hDeletedFile; IRecycleBinFile *rbf = (IRecycleBinFile *)hDeletedFile;
HRESULT hr; HRESULT hr;
TRACE("(%p)\n", hDeletedFile); TRACE("(%p)\n", hDeletedFile);
hr = IRecycleBinFile_Restore(rbf); hr = IRecycleBinFile_Restore(rbf);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
return TRUE; return TRUE;
if (HRESULT_FACILITY(hr) == FACILITY_WIN32) if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
SetLastError(HRESULT_CODE(hr)); SetLastError(HRESULT_CODE(hr));
else else
SetLastError(ERROR_GEN_FAILURE); SetLastError(ERROR_GEN_FAILURE);
return FALSE; return FALSE;
} }
HRESULT WINAPI HRESULT WINAPI
GetDefaultRecycleBin( GetDefaultRecycleBin(
IN LPCWSTR pszVolume OPTIONAL, IN LPCWSTR pszVolume OPTIONAL,
OUT IRecycleBin **pprb) OUT IRecycleBin **pprb)
{ {
IUnknown *pUnk; IUnknown *pUnk;
HRESULT hr; HRESULT hr;
TRACE("(%s, %p)\n", debugstr_w(pszVolume), pprb); TRACE("(%s, %p)\n", debugstr_w(pszVolume), pprb);
if (!pprb) if (!pprb)
return E_POINTER; return E_POINTER;
if (!pszVolume) if (!pszVolume)
hr = RecycleBinGeneric_Constructor(&pUnk); hr = RecycleBinGeneric_Constructor(&pUnk);
else else
{ {
/* FIXME: do a better validation! */ /* FIXME: do a better validation! */
if (wcslen(pszVolume) != 3 || pszVolume[1] != ':' || pszVolume[2] != '\\') if (wcslen(pszVolume) != 3 || pszVolume[1] != ':' || pszVolume[2] != '\\')
return HRESULT_FROM_WIN32(ERROR_INVALID_NAME); return HRESULT_FROM_WIN32(ERROR_INVALID_NAME);
/* For now, only support this type of recycle bins... */ /* For now, only support this type of recycle bins... */
hr = RecycleBin5_Constructor(pszVolume, &pUnk); hr = RecycleBin5_Constructor(pszVolume, &pUnk);
} }
if (!SUCCEEDED(hr)) if (!SUCCEEDED(hr))
return hr; return hr;
hr = IUnknown_QueryInterface(pUnk, &IID_IRecycleBin, (void **)pprb); hr = IUnknown_QueryInterface(pUnk, &IID_IRecycleBin, (void **)pprb);
IUnknown_Release(pUnk); IUnknown_Release(pUnk);
return hr; return hr;
} }

View file

@ -23,21 +23,21 @@ extern "C" {
typedef struct _DELETED_FILE_DETAILS_A typedef struct _DELETED_FILE_DETAILS_A
{ {
FILETIME LastModification; FILETIME LastModification;
FILETIME DeletionTime; FILETIME DeletionTime;
ULARGE_INTEGER FileSize; ULARGE_INTEGER FileSize;
ULARGE_INTEGER PhysicalFileSize; ULARGE_INTEGER PhysicalFileSize;
DWORD Attributes; DWORD Attributes;
CHAR FileName[ANY_SIZE]; CHAR FileName[ANY_SIZE];
} DELETED_FILE_DETAILS_A, *PDELETED_FILE_DETAILS_A; } DELETED_FILE_DETAILS_A, *PDELETED_FILE_DETAILS_A;
typedef struct _DELETED_FILE_DETAILS_W typedef struct _DELETED_FILE_DETAILS_W
{ {
FILETIME LastModification; FILETIME LastModification;
FILETIME DeletionTime; FILETIME DeletionTime;
ULARGE_INTEGER FileSize; ULARGE_INTEGER FileSize;
ULARGE_INTEGER PhysicalFileSize; ULARGE_INTEGER PhysicalFileSize;
DWORD Attributes; DWORD Attributes;
WCHAR FileName[ANY_SIZE]; WCHAR FileName[ANY_SIZE];
} DELETED_FILE_DETAILS_W, *PDELETED_FILE_DETAILS_W; } DELETED_FILE_DETAILS_W, *PDELETED_FILE_DETAILS_W;
#ifdef UNICODE #ifdef UNICODE
#define DELETED_FILE_DETAILS DELETED_FILE_DETAILS_W #define DELETED_FILE_DETAILS DELETED_FILE_DETAILS_W
@ -64,7 +64,7 @@ typedef BOOL (WINAPI *PENUMERATE_RECYCLEBIN_CALLBACK)(IN PVOID Context, IN HANDL
*/ */
BOOL WINAPI BOOL WINAPI
CloseRecycleBinHandle( CloseRecycleBinHandle(
IN HANDLE hDeletedFile); IN HANDLE hDeletedFile);
/* Moves a file to the recycle bin. /* Moves a file to the recycle bin.
* FileName: the name of the file to move the recycle bin * FileName: the name of the file to move the recycle bin
@ -72,10 +72,10 @@ CloseRecycleBinHandle(
*/ */
BOOL WINAPI BOOL WINAPI
DeleteFileToRecycleBinA( DeleteFileToRecycleBinA(
IN LPCSTR FileName); IN LPCSTR FileName);
BOOL WINAPI BOOL WINAPI
DeleteFileToRecycleBinW( DeleteFileToRecycleBinW(
IN LPCWSTR FileName); IN LPCWSTR FileName);
#ifdef UNICODE #ifdef UNICODE
#define DeleteFileToRecycleBin DeleteFileToRecycleBinW #define DeleteFileToRecycleBin DeleteFileToRecycleBinW
#else #else
@ -89,7 +89,7 @@ DeleteFileToRecycleBinW(
*/ */
BOOL WINAPI BOOL WINAPI
DeleteFileHandleToRecycleBin( DeleteFileHandleToRecycleBin(
IN HANDLE hDeletedFile); IN HANDLE hDeletedFile);
/* Removes all elements contained in a recycle bin /* Removes all elements contained in a recycle bin
* pszRoot: the name of the drive containing the recycle bin * pszRoot: the name of the drive containing the recycle bin
@ -98,10 +98,10 @@ DeleteFileHandleToRecycleBin(
*/ */
BOOL WINAPI BOOL WINAPI
EmptyRecycleBinA( EmptyRecycleBinA(
IN LPCSTR pszRoot OPTIONAL); IN LPCSTR pszRoot OPTIONAL);
BOOL WINAPI BOOL WINAPI
EmptyRecycleBinW( EmptyRecycleBinW(
IN LPCWSTR pszRoot OPTIONAL); IN LPCWSTR pszRoot OPTIONAL);
#ifdef UNICODE #ifdef UNICODE
#define EmptyRecycleBin EmptyRecycleBinW #define EmptyRecycleBin EmptyRecycleBinW
#else #else
@ -117,14 +117,14 @@ EmptyRecycleBinW(
*/ */
BOOL WINAPI BOOL WINAPI
EnumerateRecycleBinA( EnumerateRecycleBinA(
IN LPCSTR pszRoot OPTIONAL, IN LPCSTR pszRoot OPTIONAL,
IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback, IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback,
IN PVOID Context OPTIONAL); IN PVOID Context OPTIONAL);
BOOL WINAPI BOOL WINAPI
EnumerateRecycleBinW( EnumerateRecycleBinW(
IN LPCWSTR pszRoot OPTIONAL, IN LPCWSTR pszRoot OPTIONAL,
IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback, IN PENUMERATE_RECYCLEBIN_CALLBACK pFnCallback,
IN PVOID Context OPTIONAL); IN PVOID Context OPTIONAL);
#ifdef UNICODE #ifdef UNICODE
#define EnumerateRecycleBin EnumerateRecycleBinW #define EnumerateRecycleBin EnumerateRecycleBinW
#else #else
@ -141,16 +141,16 @@ EnumerateRecycleBinW(
*/ */
BOOL WINAPI BOOL WINAPI
GetDeletedFileDetailsA( GetDeletedFileDetailsA(
IN HANDLE hDeletedFile, IN HANDLE hDeletedFile,
IN DWORD BufferSize, IN DWORD BufferSize,
IN OUT PDELETED_FILE_DETAILS_A FileDetails OPTIONAL, IN OUT PDELETED_FILE_DETAILS_A FileDetails OPTIONAL,
OUT LPDWORD RequiredSize OPTIONAL); OUT LPDWORD RequiredSize OPTIONAL);
BOOL WINAPI BOOL WINAPI
GetDeletedFileDetailsW( GetDeletedFileDetailsW(
IN HANDLE hDeletedFile, IN HANDLE hDeletedFile,
IN DWORD BufferSize, IN DWORD BufferSize,
IN OUT PDELETED_FILE_DETAILS_W FileDetails OPTIONAL, IN OUT PDELETED_FILE_DETAILS_W FileDetails OPTIONAL,
OUT LPDWORD RequiredSize OPTIONAL); OUT LPDWORD RequiredSize OPTIONAL);
#ifdef UNICODE #ifdef UNICODE
#define GetDeletedFileDetails GetDeletedFileDetailsW #define GetDeletedFileDetails GetDeletedFileDetailsW
#else #else
@ -164,9 +164,9 @@ GetDeletedFileDetailsW(
*/ */
BOOL WINAPI BOOL WINAPI
GetRecycleBinDetails( GetRecycleBinDetails(
IN LPCWSTR pszVolume OPTIONAL, IN LPCWSTR pszVolume OPTIONAL,
OUT ULARGE_INTEGER *pulTotalItems, OUT ULARGE_INTEGER *pulTotalItems,
OUT ULARGE_INTEGER *pulTotalSize); OUT ULARGE_INTEGER *pulTotalSize);
/* Restores a deleted file /* Restores a deleted file
* hDeletedFile: handle of the deleted file to restore * hDeletedFile: handle of the deleted file to restore
@ -175,7 +175,7 @@ GetRecycleBinDetails(
*/ */
BOOL WINAPI BOOL WINAPI
RestoreFile( RestoreFile(
IN HANDLE hDeletedFile); IN HANDLE hDeletedFile);
/* COM interface */ /* COM interface */
@ -184,24 +184,24 @@ RestoreFile(
DECLARE_INTERFACE_(IRecycleBinFile, IUnknown) DECLARE_INTERFACE_(IRecycleBinFile, IUnknown)
{ {
BEGIN_INTERFACE BEGIN_INTERFACE
/* IUnknown methods */ /* IUnknown methods */
STDMETHOD(QueryInterface)(THIS_ REFIID riid, void **ppvObject) PURE; STDMETHOD(QueryInterface)(THIS_ REFIID riid, void **ppvObject) PURE;
STDMETHOD_(ULONG, AddRef)(THIS) PURE; STDMETHOD_(ULONG, AddRef)(THIS) PURE;
STDMETHOD_(ULONG, Release)(THIS) PURE; STDMETHOD_(ULONG, Release)(THIS) PURE;
/* IRecycleBinFile methods */ /* IRecycleBinFile methods */
STDMETHOD(GetLastModificationTime)(THIS_ FILETIME *pLastModificationTime) PURE; STDMETHOD(GetLastModificationTime)(THIS_ FILETIME *pLastModificationTime) PURE;
STDMETHOD(GetDeletionTime)(THIS_ FILETIME *pDeletionTime) PURE; STDMETHOD(GetDeletionTime)(THIS_ FILETIME *pDeletionTime) PURE;
STDMETHOD(GetFileSize)(THIS_ ULARGE_INTEGER *pFileSize) PURE; STDMETHOD(GetFileSize)(THIS_ ULARGE_INTEGER *pFileSize) PURE;
STDMETHOD(GetPhysicalFileSize)(THIS_ ULARGE_INTEGER *pPhysicalFileSize) PURE; STDMETHOD(GetPhysicalFileSize)(THIS_ ULARGE_INTEGER *pPhysicalFileSize) PURE;
STDMETHOD(GetAttributes)(THIS_ DWORD *pAttributes) PURE; STDMETHOD(GetAttributes)(THIS_ DWORD *pAttributes) PURE;
STDMETHOD(GetFileName)(THIS_ SIZE_T BufferSize, LPWSTR Buffer, SIZE_T *RequiredSize) PURE; STDMETHOD(GetFileName)(THIS_ SIZE_T BufferSize, LPWSTR Buffer, SIZE_T *RequiredSize) PURE;
STDMETHOD(Delete)(THIS) PURE; STDMETHOD(Delete)(THIS) PURE;
STDMETHOD(Restore)(THIS) PURE; STDMETHOD(Restore)(THIS) PURE;
END_INTERFACE END_INTERFACE
}; };
#undef INTERFACE #undef INTERFACE
@ -209,19 +209,19 @@ DECLARE_INTERFACE_(IRecycleBinFile, IUnknown)
DECLARE_INTERFACE_(IRecycleBinEnumList, IUnknown) DECLARE_INTERFACE_(IRecycleBinEnumList, IUnknown)
{ {
BEGIN_INTERFACE BEGIN_INTERFACE
/* IUnknown methods */ /* IUnknown methods */
STDMETHOD(QueryInterface)(THIS_ REFIID riid, void **ppvObject) PURE; STDMETHOD(QueryInterface)(THIS_ REFIID riid, void **ppvObject) PURE;
STDMETHOD_(ULONG, AddRef)(THIS) PURE; STDMETHOD_(ULONG, AddRef)(THIS) PURE;
STDMETHOD_(ULONG, Release)(THIS) PURE; STDMETHOD_(ULONG, Release)(THIS) PURE;
/* IRecycleBinEnumList methods */ /* IRecycleBinEnumList methods */
STDMETHOD(Next)(THIS_ DWORD celt, IRecycleBinFile **rgelt, DWORD *pceltFetched); STDMETHOD(Next)(THIS_ DWORD celt, IRecycleBinFile **rgelt, DWORD *pceltFetched);
STDMETHOD(Skip)(THIS_ DWORD celt) PURE; STDMETHOD(Skip)(THIS_ DWORD celt) PURE;
STDMETHOD(Reset)(THIS) PURE; STDMETHOD(Reset)(THIS) PURE;
END_INTERFACE END_INTERFACE
}; };
#undef INTERFACE #undef INTERFACE
@ -229,19 +229,19 @@ DECLARE_INTERFACE_(IRecycleBinEnumList, IUnknown)
DECLARE_INTERFACE_(IRecycleBin, IUnknown) DECLARE_INTERFACE_(IRecycleBin, IUnknown)
{ {
BEGIN_INTERFACE BEGIN_INTERFACE
/* IUnknown methods */ /* IUnknown methods */
STDMETHOD(QueryInterface)(THIS_ REFIID riid, void **ppvObject) PURE; STDMETHOD(QueryInterface)(THIS_ REFIID riid, void **ppvObject) PURE;
STDMETHOD_(ULONG, AddRef)(THIS) PURE; STDMETHOD_(ULONG, AddRef)(THIS) PURE;
STDMETHOD_(ULONG, Release)(THIS) PURE; STDMETHOD_(ULONG, Release)(THIS) PURE;
/* IRecycleBin methods */ /* IRecycleBin methods */
STDMETHOD(DeleteFile)(THIS_ LPCWSTR szFileName); STDMETHOD(DeleteFile)(THIS_ LPCWSTR szFileName);
STDMETHOD(EmptyRecycleBin)(THIS); STDMETHOD(EmptyRecycleBin)(THIS);
STDMETHOD(EnumObjects)(THIS_ IRecycleBinEnumList **ppEnumList); STDMETHOD(EnumObjects)(THIS_ IRecycleBinEnumList **ppEnumList);
END_INTERFACE END_INTERFACE
}; };
EXTERN_C const IID IID_IRecycleBinFile; EXTERN_C const IID IID_IRecycleBinFile;
@ -250,59 +250,59 @@ EXTERN_C const IID IID_IRecycleBin;
#if (!defined(__cplusplus) || defined(CINTERFACE)) && defined(COBJMACROS) #if (!defined(__cplusplus) || defined(CINTERFACE)) && defined(COBJMACROS)
#define IRecycleBinFile_QueryInterface(This, riid, ppvObject) \ #define IRecycleBinFile_QueryInterface(This, riid, ppvObject) \
(This)->lpVtbl->QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)
#define IRecycleBinFile_AddRef(This) \ #define IRecycleBinFile_AddRef(This) \
(This)->lpVtbl->AddRef(This) (This)->lpVtbl->AddRef(This)
#define IRecycleBinFile_Release(This) \ #define IRecycleBinFile_Release(This) \
(This)->lpVtbl->Release(This) (This)->lpVtbl->Release(This)
#define IRecycleBinFile_GetLastModificationTime(This, pLastModificationTime) \ #define IRecycleBinFile_GetLastModificationTime(This, pLastModificationTime) \
(This)->lpVtbl->GetLastModificationTime(This, pLastModificationTime) (This)->lpVtbl->GetLastModificationTime(This, pLastModificationTime)
#define IRecycleBinFile_GetDeletionTime(This, pDeletionTime) \ #define IRecycleBinFile_GetDeletionTime(This, pDeletionTime) \
(This)->lpVtbl->GetDeletionTime(This, pDeletionTime) (This)->lpVtbl->GetDeletionTime(This, pDeletionTime)
#define IRecycleBinFile_GetFileSize(This, pFileSize) \ #define IRecycleBinFile_GetFileSize(This, pFileSize) \
(This)->lpVtbl->GetFileSize(This, pFileSize) (This)->lpVtbl->GetFileSize(This, pFileSize)
#define IRecycleBinFile_GetPhysicalFileSize(This, pPhysicalFileSize) \ #define IRecycleBinFile_GetPhysicalFileSize(This, pPhysicalFileSize) \
(This)->lpVtbl->GetPhysicalFileSize(This, pPhysicalFileSize) (This)->lpVtbl->GetPhysicalFileSize(This, pPhysicalFileSize)
#define IRecycleBinFile_GetAttributes(This, pAttributes) \ #define IRecycleBinFile_GetAttributes(This, pAttributes) \
(This)->lpVtbl->GetAttributes(This, pAttributes) (This)->lpVtbl->GetAttributes(This, pAttributes)
#define IRecycleBinFile_GetFileName(This, BufferSize, Buffer, RequiredSize) \ #define IRecycleBinFile_GetFileName(This, BufferSize, Buffer, RequiredSize) \
(This)->lpVtbl->GetFileName(This, BufferSize, Buffer, RequiredSize) (This)->lpVtbl->GetFileName(This, BufferSize, Buffer, RequiredSize)
#define IRecycleBinFile_Delete(This) \ #define IRecycleBinFile_Delete(This) \
(This)->lpVtbl->Delete(This) (This)->lpVtbl->Delete(This)
#define IRecycleBinFile_Restore(This) \ #define IRecycleBinFile_Restore(This) \
(This)->lpVtbl->Restore(This) (This)->lpVtbl->Restore(This)
#define IRecycleBinEnumList_QueryInterface(This, riid, ppvObject) \ #define IRecycleBinEnumList_QueryInterface(This, riid, ppvObject) \
(This)->lpVtbl->QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)
#define IRecycleBinEnumList_AddRef(This) \ #define IRecycleBinEnumList_AddRef(This) \
(This)->lpVtbl->AddRef(This) (This)->lpVtbl->AddRef(This)
#define IRecycleBinEnumList_Release(This) \ #define IRecycleBinEnumList_Release(This) \
(This)->lpVtbl->Release(This) (This)->lpVtbl->Release(This)
#define IRecycleBinEnumList_Next(This, celt, rgelt, pceltFetched) \ #define IRecycleBinEnumList_Next(This, celt, rgelt, pceltFetched) \
(This)->lpVtbl->Next(This, celt, rgelt, pceltFetched) (This)->lpVtbl->Next(This, celt, rgelt, pceltFetched)
#define IRecycleBinEnumList_Skip(This, celt) \ #define IRecycleBinEnumList_Skip(This, celt) \
(This)->lpVtbl->Skip(This, celt) (This)->lpVtbl->Skip(This, celt)
#define IRecycleBinEnumList_Reset(This) \ #define IRecycleBinEnumList_Reset(This) \
(This)->lpVtbl->Reset(This) (This)->lpVtbl->Reset(This)
#define IRecycleBin_QueryInterface(This, riid, ppvObject) \ #define IRecycleBin_QueryInterface(This, riid, ppvObject) \
(This)->lpVtbl->QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)
#define IRecycleBin_AddRef(This) \ #define IRecycleBin_AddRef(This) \
(This)->lpVtbl->AddRef(This) (This)->lpVtbl->AddRef(This)
#define IRecycleBin_Release(This) \ #define IRecycleBin_Release(This) \
(This)->lpVtbl->Release(This) (This)->lpVtbl->Release(This)
#define IRecycleBin_DeleteFile(This, szFileName) \ #define IRecycleBin_DeleteFile(This, szFileName) \
(This)->lpVtbl->DeleteFile(This, szFileName) (This)->lpVtbl->DeleteFile(This, szFileName)
#define IRecycleBin_EmptyRecycleBin(This) \ #define IRecycleBin_EmptyRecycleBin(This) \
(This)->lpVtbl->EmptyRecycleBin(This) (This)->lpVtbl->EmptyRecycleBin(This)
#define IRecycleBin_EnumObjects(This, ppEnumList) \ #define IRecycleBin_EnumObjects(This, ppEnumList) \
(This)->lpVtbl->EnumObjects(This, ppEnumList) (This)->lpVtbl->EnumObjects(This, ppEnumList)
#endif #endif
HRESULT WINAPI HRESULT WINAPI
GetDefaultRecycleBin( GetDefaultRecycleBin(
IN LPCWSTR pszVolume OPTIONAL, IN LPCWSTR pszVolume OPTIONAL,
OUT IRecycleBin **pprb); OUT IRecycleBin **pprb);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -10,205 +10,205 @@
struct RecycleBinGeneric struct RecycleBinGeneric
{ {
ULONG ref; ULONG ref;
IRecycleBin recycleBinImpl; IRecycleBin recycleBinImpl;
}; };
static HRESULT STDMETHODCALLTYPE static HRESULT STDMETHODCALLTYPE
RecycleBinGeneric_RecycleBin_QueryInterface( RecycleBinGeneric_RecycleBin_QueryInterface(
IRecycleBin *This, IRecycleBin *This,
REFIID riid, REFIID riid,
void **ppvObject) void **ppvObject)
{ {
struct RecycleBinGeneric *s = CONTAINING_RECORD(This, struct RecycleBinGeneric, recycleBinImpl); struct RecycleBinGeneric *s = CONTAINING_RECORD(This, struct RecycleBinGeneric, recycleBinImpl);
TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObject); TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObject);
if (!ppvObject) if (!ppvObject)
return E_POINTER; return E_POINTER;
if (IsEqualIID(riid, &IID_IUnknown)) if (IsEqualIID(riid, &IID_IUnknown))
*ppvObject = &s->recycleBinImpl; *ppvObject = &s->recycleBinImpl;
else if (IsEqualIID(riid, &IID_IRecycleBin)) else if (IsEqualIID(riid, &IID_IRecycleBin))
*ppvObject = &s->recycleBinImpl; *ppvObject = &s->recycleBinImpl;
else else
{ {
*ppvObject = NULL; *ppvObject = NULL;
return E_NOINTERFACE; return E_NOINTERFACE;
} }
IUnknown_AddRef(This); IUnknown_AddRef(This);
return S_OK; return S_OK;
} }
static ULONG STDMETHODCALLTYPE static ULONG STDMETHODCALLTYPE
RecycleBinGeneric_RecycleBin_AddRef( RecycleBinGeneric_RecycleBin_AddRef(
IRecycleBin *This) IRecycleBin *This)
{ {
struct RecycleBinGeneric *s = CONTAINING_RECORD(This, struct RecycleBinGeneric, recycleBinImpl); struct RecycleBinGeneric *s = CONTAINING_RECORD(This, struct RecycleBinGeneric, recycleBinImpl);
ULONG refCount = InterlockedIncrement((PLONG)&s->ref); ULONG refCount = InterlockedIncrement((PLONG)&s->ref);
TRACE("(%p)\n", This); TRACE("(%p)\n", This);
return refCount; return refCount;
} }
static VOID static VOID
RecycleBinGeneric_Destructor( RecycleBinGeneric_Destructor(
struct RecycleBinGeneric *s) struct RecycleBinGeneric *s)
{ {
TRACE("(%p)\n", s); TRACE("(%p)\n", s);
CoTaskMemFree(s); CoTaskMemFree(s);
} }
static ULONG STDMETHODCALLTYPE static ULONG STDMETHODCALLTYPE
RecycleBinGeneric_RecycleBin_Release( RecycleBinGeneric_RecycleBin_Release(
IRecycleBin *This) IRecycleBin *This)
{ {
struct RecycleBinGeneric *s = CONTAINING_RECORD(This, struct RecycleBinGeneric, recycleBinImpl); struct RecycleBinGeneric *s = CONTAINING_RECORD(This, struct RecycleBinGeneric, recycleBinImpl);
ULONG refCount; ULONG refCount;
TRACE("(%p)\n", This); TRACE("(%p)\n", This);
refCount = InterlockedDecrement((PLONG)&s->ref); refCount = InterlockedDecrement((PLONG)&s->ref);
if (refCount == 0) if (refCount == 0)
RecycleBinGeneric_Destructor(s); RecycleBinGeneric_Destructor(s);
return refCount; return refCount;
} }
static HRESULT STDMETHODCALLTYPE static HRESULT STDMETHODCALLTYPE
RecycleBinGeneric_RecycleBin_DeleteFile( RecycleBinGeneric_RecycleBin_DeleteFile(
IN IRecycleBin *This, IN IRecycleBin *This,
IN LPCWSTR szFileName) IN LPCWSTR szFileName)
{ {
IRecycleBin *prb; IRecycleBin *prb;
LPWSTR szFullName = NULL; LPWSTR szFullName = NULL;
DWORD dwBufferLength = 0; DWORD dwBufferLength = 0;
DWORD len; DWORD len;
WCHAR szVolume[MAX_PATH]; WCHAR szVolume[MAX_PATH];
HRESULT hr; HRESULT hr;
TRACE("(%p, %s)\n", This, debugstr_w(szFileName)); TRACE("(%p, %s)\n", This, debugstr_w(szFileName));
/* Get full file name */ /* Get full file name */
while (TRUE) while (TRUE)
{ {
len = GetFullPathNameW(szFileName, dwBufferLength, szFullName, NULL); len = GetFullPathNameW(szFileName, dwBufferLength, szFullName, NULL);
if (len == 0) if (len == 0)
{ {
if (szFullName) if (szFullName)
CoTaskMemFree(szFullName); CoTaskMemFree(szFullName);
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
else if (len < dwBufferLength) else if (len < dwBufferLength)
break; break;
if (szFullName) if (szFullName)
CoTaskMemFree(szFullName); CoTaskMemFree(szFullName);
dwBufferLength = len; dwBufferLength = len;
szFullName = CoTaskMemAlloc(dwBufferLength * sizeof(WCHAR)); szFullName = CoTaskMemAlloc(dwBufferLength * sizeof(WCHAR));
if (!szFullName) if (!szFullName)
return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
} }
/* Get associated volume path */ /* Get associated volume path */
#ifndef __REACTOS__ #ifndef __REACTOS__
if (!GetVolumePathNameW(szFullName, szVolume, MAX_PATH)) if (!GetVolumePathNameW(szFullName, szVolume, MAX_PATH))
{ {
CoTaskMemFree(szFullName); CoTaskMemFree(szFullName);
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
#else #else
swprintf(szVolume, L"%c:\\", szFullName[0]); swprintf(szVolume, L"%c:\\", szFullName[0]);
#endif #endif
/* Skip namespace (if any) */ /* Skip namespace (if any) */
if (szVolume[0] == '\\' if (szVolume[0] == '\\'
&& szVolume[1] == '\\' && szVolume[1] == '\\'
&& (szVolume[2] == '.' || szVolume[2] == '?') && (szVolume[2] == '.' || szVolume[2] == '?')
&& szVolume[3] == '\\') && szVolume[3] == '\\')
{ {
MoveMemory(szVolume, &szVolume[4], (MAX_PATH - 4) * sizeof(WCHAR)); MoveMemory(szVolume, &szVolume[4], (MAX_PATH - 4) * sizeof(WCHAR));
} }
hr = GetDefaultRecycleBin(szVolume, &prb); hr = GetDefaultRecycleBin(szVolume, &prb);
if (!SUCCEEDED(hr)) if (!SUCCEEDED(hr))
{ {
CoTaskMemFree(szFullName); CoTaskMemFree(szFullName);
return hr; return hr;
} }
hr = IRecycleBin_DeleteFile(prb, szFullName); hr = IRecycleBin_DeleteFile(prb, szFullName);
CoTaskMemFree(szFullName); CoTaskMemFree(szFullName);
IRecycleBin_Release(prb); IRecycleBin_Release(prb);
return hr; return hr;
} }
static HRESULT STDMETHODCALLTYPE static HRESULT STDMETHODCALLTYPE
RecycleBinGeneric_RecycleBin_EmptyRecycleBin( RecycleBinGeneric_RecycleBin_EmptyRecycleBin(
IN IRecycleBin *This) IN IRecycleBin *This)
{ {
WCHAR szVolumeName[MAX_PATH]; WCHAR szVolumeName[MAX_PATH];
DWORD dwLogicalDrives, i; DWORD dwLogicalDrives, i;
IRecycleBin *prb; IRecycleBin *prb;
HRESULT hr; HRESULT hr;
TRACE("(%p)\n", This); TRACE("(%p)\n", This);
dwLogicalDrives = GetLogicalDrives(); dwLogicalDrives = GetLogicalDrives();
if (dwLogicalDrives == 0) if (dwLogicalDrives == 0)
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
for (i = 0; i < 26; i++) for (i = 0; i < 26; i++)
{ {
if (!(dwLogicalDrives & (1 << i))) if (!(dwLogicalDrives & (1 << i)))
continue; continue;
swprintf(szVolumeName, L"%c:\\", 'A' + i); swprintf(szVolumeName, L"%c:\\", 'A' + i);
if (GetDriveTypeW(szVolumeName) != DRIVE_FIXED) if (GetDriveTypeW(szVolumeName) != DRIVE_FIXED)
continue; continue;
hr = GetDefaultRecycleBin(szVolumeName, &prb); hr = GetDefaultRecycleBin(szVolumeName, &prb);
if (!SUCCEEDED(hr)) if (!SUCCEEDED(hr))
return hr; return hr;
hr = IRecycleBin_EmptyRecycleBin(prb); hr = IRecycleBin_EmptyRecycleBin(prb);
IRecycleBin_Release(prb); IRecycleBin_Release(prb);
} }
return S_OK; return S_OK;
} }
static HRESULT STDMETHODCALLTYPE static HRESULT STDMETHODCALLTYPE
RecycleBinGeneric_RecycleBin_EnumObjects( RecycleBinGeneric_RecycleBin_EnumObjects(
IN IRecycleBin *This, IN IRecycleBin *This,
OUT IRecycleBinEnumList **ppEnumList) OUT IRecycleBinEnumList **ppEnumList)
{ {
TRACE("(%p, %p)\n", This, ppEnumList); TRACE("(%p, %p)\n", This, ppEnumList);
return RecycleBinGenericEnum_Constructor(ppEnumList); return RecycleBinGenericEnum_Constructor(ppEnumList);
} }
CONST_VTBL struct IRecycleBinVtbl RecycleBinGenericVtbl = CONST_VTBL struct IRecycleBinVtbl RecycleBinGenericVtbl =
{ {
RecycleBinGeneric_RecycleBin_QueryInterface, RecycleBinGeneric_RecycleBin_QueryInterface,
RecycleBinGeneric_RecycleBin_AddRef, RecycleBinGeneric_RecycleBin_AddRef,
RecycleBinGeneric_RecycleBin_Release, RecycleBinGeneric_RecycleBin_Release,
RecycleBinGeneric_RecycleBin_DeleteFile, RecycleBinGeneric_RecycleBin_DeleteFile,
RecycleBinGeneric_RecycleBin_EmptyRecycleBin, RecycleBinGeneric_RecycleBin_EmptyRecycleBin,
RecycleBinGeneric_RecycleBin_EnumObjects, RecycleBinGeneric_RecycleBin_EnumObjects,
}; };
HRESULT RecycleBinGeneric_Constructor(OUT IUnknown **ppUnknown) HRESULT RecycleBinGeneric_Constructor(OUT IUnknown **ppUnknown)
{ {
/* This RecycleBin implementation was introduced to be able to manage all /* This RecycleBin implementation was introduced to be able to manage all
* drives at once, and instanciate the 'real' implementations when needed */ * drives at once, and instanciate the 'real' implementations when needed */
struct RecycleBinGeneric *s; struct RecycleBinGeneric *s;
s = CoTaskMemAlloc(sizeof(struct RecycleBinGeneric)); s = CoTaskMemAlloc(sizeof(struct RecycleBinGeneric));
if (!s) if (!s)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
s->ref = 1; s->ref = 1;
s->recycleBinImpl.lpVtbl = &RecycleBinGenericVtbl; s->recycleBinImpl.lpVtbl = &RecycleBinGenericVtbl;
*ppUnknown = (IUnknown *)&s->recycleBinImpl; *ppUnknown = (IUnknown *)&s->recycleBinImpl;
return S_OK; return S_OK;
} }

View file

@ -25,11 +25,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(recyclebin);
typedef struct _INFO2_HEADER typedef struct _INFO2_HEADER
{ {
DWORD dwVersion; DWORD dwVersion;
DWORD dwNumberOfEntries; /* unused */ DWORD dwNumberOfEntries; /* unused */
DWORD dwHighestRecordUniqueId; /* unused */ DWORD dwHighestRecordUniqueId; /* unused */
DWORD dwRecordSize; DWORD dwRecordSize;
DWORD dwTotalLogicalSize; DWORD dwTotalLogicalSize;
} INFO2_HEADER, *PINFO2_HEADER; } INFO2_HEADER, *PINFO2_HEADER;
#include <poppack.h> #include <poppack.h>

File diff suppressed because it is too large Load diff

View file

@ -12,12 +12,12 @@ extern "C" {
/* MS Windows 2000/XP/2003 */ /* MS Windows 2000/XP/2003 */
typedef struct _DELETED_FILE_RECORD typedef struct _DELETED_FILE_RECORD
{ {
CHAR FileNameA[MAX_PATH]; CHAR FileNameA[MAX_PATH];
DWORD dwRecordUniqueId; DWORD dwRecordUniqueId;
DWORD dwDriveNumber; DWORD dwDriveNumber;
FILETIME DeletionTime; FILETIME DeletionTime;
DWORD dwPhysicalFileSize; DWORD dwPhysicalFileSize;
WCHAR FileNameW[MAX_PATH]; WCHAR FileNameW[MAX_PATH];
} DELETED_FILE_RECORD, *PDELETED_FILE_RECORD; } DELETED_FILE_RECORD, *PDELETED_FILE_RECORD;
#include <poppack.h> #include <poppack.h>
@ -29,78 +29,78 @@ EXTERN_C const IID IID_IRecycleBin5;
typedef struct IRecycleBin5Vtbl typedef struct IRecycleBin5Vtbl
{ {
/* IRecycleBin interface */ /* IRecycleBin interface */
HRESULT (STDMETHODCALLTYPE *QueryInterface)( HRESULT (STDMETHODCALLTYPE *QueryInterface)(
IN IRecycleBin5 *This, IN IRecycleBin5 *This,
IN REFIID riid, IN REFIID riid,
OUT void **ppvObject); OUT void **ppvObject);
ULONG (STDMETHODCALLTYPE *AddRef)( ULONG (STDMETHODCALLTYPE *AddRef)(
IN IRecycleBin5 *This); IN IRecycleBin5 *This);
ULONG (STDMETHODCALLTYPE *Release)( ULONG (STDMETHODCALLTYPE *Release)(
IN IRecycleBin5 *This); IN IRecycleBin5 *This);
HRESULT (STDMETHODCALLTYPE *DeleteFile)( HRESULT (STDMETHODCALLTYPE *DeleteFile)(
IN IRecycleBin5 *This, IN IRecycleBin5 *This,
IN LPCWSTR szFileName); IN LPCWSTR szFileName);
HRESULT (STDMETHODCALLTYPE *EmptyRecycleBin)( HRESULT (STDMETHODCALLTYPE *EmptyRecycleBin)(
IN IRecycleBin5 *This); IN IRecycleBin5 *This);
HRESULT (STDMETHODCALLTYPE *EnumObjects)( HRESULT (STDMETHODCALLTYPE *EnumObjects)(
IN IRecycleBin5 *This, IN IRecycleBin5 *This,
OUT IRecycleBinEnumList **ppEnumList); OUT IRecycleBinEnumList **ppEnumList);
/* IRecycleBin5 interface */ /* IRecycleBin5 interface */
HRESULT (STDMETHODCALLTYPE *Delete)( HRESULT (STDMETHODCALLTYPE *Delete)(
IN IRecycleBin5 *This, IN IRecycleBin5 *This,
IN LPCWSTR pDeletedFileName, IN LPCWSTR pDeletedFileName,
IN DELETED_FILE_RECORD *pDeletedFile); IN DELETED_FILE_RECORD *pDeletedFile);
HRESULT (STDMETHODCALLTYPE *Restore)( HRESULT (STDMETHODCALLTYPE *Restore)(
IN IRecycleBin5 *This, IN IRecycleBin5 *This,
IN LPCWSTR pDeletedFileName, IN LPCWSTR pDeletedFileName,
IN DELETED_FILE_RECORD *pDeletedFile); IN DELETED_FILE_RECORD *pDeletedFile);
HRESULT (STDMETHODCALLTYPE *OnClosing)( HRESULT (STDMETHODCALLTYPE *OnClosing)(
IN IRecycleBin5 *This, IN IRecycleBin5 *This,
IN IRecycleBinEnumList *prbel); IN IRecycleBinEnumList *prbel);
} IRecycleBin5Vtbl; } IRecycleBin5Vtbl;
interface IRecycleBin5 interface IRecycleBin5
{ {
CONST_VTBL struct IRecycleBin5Vtbl *lpVtbl; CONST_VTBL struct IRecycleBin5Vtbl *lpVtbl;
}; };
#ifdef COBJMACROS #ifdef COBJMACROS
#define IRecycleBin5_QueryInterface(This, riid, ppvObject) \ #define IRecycleBin5_QueryInterface(This, riid, ppvObject) \
(This)->lpVtbl->QueryInterface(This, riid, ppvObject) (This)->lpVtbl->QueryInterface(This, riid, ppvObject)
#define IRecycleBin5_AddRef(This) \ #define IRecycleBin5_AddRef(This) \
(This)->lpVtbl->AddRef(This) (This)->lpVtbl->AddRef(This)
#define IRecycleBin5_Release(This) \ #define IRecycleBin5_Release(This) \
(This)->lpVtbl->Release(This) (This)->lpVtbl->Release(This)
#define IRecycleBin5_DeleteFile(This, szFileName) \ #define IRecycleBin5_DeleteFile(This, szFileName) \
(This)->lpVtbl->DeleteFile(This, szFileName) (This)->lpVtbl->DeleteFile(This, szFileName)
#define IRecycleBin5_EmptyRecycleBin(This) \ #define IRecycleBin5_EmptyRecycleBin(This) \
(This)->lpVtbl->EmptyRecycleBin(This) (This)->lpVtbl->EmptyRecycleBin(This)
#define IRecycleBin5_EnumObjects(This, ppEnumList) \ #define IRecycleBin5_EnumObjects(This, ppEnumList) \
(This)->lpVtbl->EnumObjects(This, ppEnumList) (This)->lpVtbl->EnumObjects(This, ppEnumList)
#define IRecycleBin5_Delete(This, pDeletedFileName, pDeletedFile) \ #define IRecycleBin5_Delete(This, pDeletedFileName, pDeletedFile) \
(This)->lpVtbl->Delete(This, pDeletedFileName, pDeletedFile) (This)->lpVtbl->Delete(This, pDeletedFileName, pDeletedFile)
#define IRecycleBin5_Restore(This, pDeletedFileName, pDeletedFile) \ #define IRecycleBin5_Restore(This, pDeletedFileName, pDeletedFile) \
(This)->lpVtbl->Restore(This, pDeletedFileName, pDeletedFile) (This)->lpVtbl->Restore(This, pDeletedFileName, pDeletedFile)
#define IRecycleBin5_OnClosing(This, prb5el) \ #define IRecycleBin5_OnClosing(This, prb5el) \
(This)->lpVtbl->OnClosing(This, prb5el) (This)->lpVtbl->OnClosing(This, prb5el)
#endif #endif
HRESULT HRESULT
RecycleBin5Enum_Constructor( RecycleBin5Enum_Constructor(
IN IRecycleBin5 *prb, IN IRecycleBin5 *prb,
IN HANDLE hInfo, IN HANDLE hInfo,
IN HANDLE hInfoMapped, IN HANDLE hInfoMapped,
IN LPCWSTR szPrefix, IN LPCWSTR szPrefix,
OUT IUnknown **ppUnknown); OUT IUnknown **ppUnknown);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -10,474 +10,474 @@
struct RecycleBin5File struct RecycleBin5File
{ {
ULONG ref; ULONG ref;
IRecycleBin5 *recycleBin; IRecycleBin5 *recycleBin;
DELETED_FILE_RECORD deletedFile; DELETED_FILE_RECORD deletedFile;
IRecycleBinFile recycleBinFileImpl; IRecycleBinFile recycleBinFileImpl;
WCHAR FullName[ANY_SIZE]; WCHAR FullName[ANY_SIZE];
}; };
static HRESULT STDMETHODCALLTYPE static HRESULT STDMETHODCALLTYPE
RecycleBin5File_RecycleBinFile_QueryInterface( RecycleBin5File_RecycleBinFile_QueryInterface(
IN IRecycleBinFile *This, IN IRecycleBinFile *This,
IN REFIID riid, IN REFIID riid,
OUT void **ppvObject) OUT void **ppvObject)
{ {
struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl); struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl);
TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObject); TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObject);
if (!ppvObject) if (!ppvObject)
return E_POINTER; return E_POINTER;
if (IsEqualIID(riid, &IID_IUnknown)) if (IsEqualIID(riid, &IID_IUnknown))
*ppvObject = &s->recycleBinFileImpl; *ppvObject = &s->recycleBinFileImpl;
else if (IsEqualIID(riid, &IID_IRecycleBinFile)) else if (IsEqualIID(riid, &IID_IRecycleBinFile))
*ppvObject = &s->recycleBinFileImpl; *ppvObject = &s->recycleBinFileImpl;
else else
{ {
*ppvObject = NULL; *ppvObject = NULL;
return E_NOINTERFACE; return E_NOINTERFACE;
} }
IUnknown_AddRef(This); IUnknown_AddRef(This);
return S_OK; return S_OK;
} }
static ULONG STDMETHODCALLTYPE static ULONG STDMETHODCALLTYPE
RecycleBin5File_RecycleBinFile_AddRef( RecycleBin5File_RecycleBinFile_AddRef(
IN IRecycleBinFile *This) IN IRecycleBinFile *This)
{ {
struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl); struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl);
ULONG refCount = InterlockedIncrement((PLONG)&s->ref); ULONG refCount = InterlockedIncrement((PLONG)&s->ref);
TRACE("(%p)\n", This); TRACE("(%p)\n", This);
return refCount; return refCount;
} }
static VOID static VOID
RecycleBin5File_Destructor( RecycleBin5File_Destructor(
struct RecycleBin5File *s) struct RecycleBin5File *s)
{ {
TRACE("(%p)\n", s); TRACE("(%p)\n", s);
IRecycleBin5_Release(s->recycleBin); IRecycleBin5_Release(s->recycleBin);
CoTaskMemFree(s); CoTaskMemFree(s);
} }
static ULONG STDMETHODCALLTYPE static ULONG STDMETHODCALLTYPE
RecycleBin5File_RecycleBinFile_Release( RecycleBin5File_RecycleBinFile_Release(
IN IRecycleBinFile *This) IN IRecycleBinFile *This)
{ {
struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl); struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl);
ULONG refCount; ULONG refCount;
TRACE("(%p)\n", This); TRACE("(%p)\n", This);
refCount = InterlockedDecrement((PLONG)&s->ref); refCount = InterlockedDecrement((PLONG)&s->ref);
if (refCount == 0) if (refCount == 0)
RecycleBin5File_Destructor(s); RecycleBin5File_Destructor(s);
return refCount; return refCount;
} }
static HRESULT STDMETHODCALLTYPE static HRESULT STDMETHODCALLTYPE
RecycleBin5File_RecycleBinFile_GetLastModificationTime( RecycleBin5File_RecycleBinFile_GetLastModificationTime(
IN IRecycleBinFile *This, IN IRecycleBinFile *This,
OUT FILETIME *pLastModificationTime) OUT FILETIME *pLastModificationTime)
{ {
struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl); struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl);
HRESULT hr; HRESULT hr;
DWORD dwAttributes; DWORD dwAttributes;
HANDLE hFile; HANDLE hFile;
TRACE("(%p, %p)\n", This, pLastModificationTime); TRACE("(%p, %p)\n", This, pLastModificationTime);
dwAttributes = GetFileAttributesW(s->FullName); dwAttributes = GetFileAttributesW(s->FullName);
if (dwAttributes == INVALID_FILE_ATTRIBUTES) if (dwAttributes == INVALID_FILE_ATTRIBUTES)
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
if (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) if (dwAttributes & FILE_ATTRIBUTE_DIRECTORY)
hFile = CreateFileW(s->FullName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); hFile = CreateFileW(s->FullName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
else else
hFile = CreateFileW(s->FullName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); hFile = CreateFileW(s->FullName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) if (hFile == INVALID_HANDLE_VALUE)
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
if (GetFileTime(hFile, NULL, NULL, pLastModificationTime)) if (GetFileTime(hFile, NULL, NULL, pLastModificationTime))
hr = S_OK; hr = S_OK;
else else
hr = HRESULT_FROM_WIN32(GetLastError()); hr = HRESULT_FROM_WIN32(GetLastError());
CloseHandle(hFile); CloseHandle(hFile);
return hr; return hr;
} }
static HRESULT STDMETHODCALLTYPE static HRESULT STDMETHODCALLTYPE
RecycleBin5File_RecycleBinFile_GetDeletionTime( RecycleBin5File_RecycleBinFile_GetDeletionTime(
IN IRecycleBinFile *This, IN IRecycleBinFile *This,
OUT FILETIME *pDeletionTime) OUT FILETIME *pDeletionTime)
{ {
struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl); struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl);
TRACE("(%p, %p)\n", This, pDeletionTime); TRACE("(%p, %p)\n", This, pDeletionTime);
*pDeletionTime = s->deletedFile.DeletionTime; *pDeletionTime = s->deletedFile.DeletionTime;
return S_OK; return S_OK;
} }
static HRESULT STDMETHODCALLTYPE static HRESULT STDMETHODCALLTYPE
RecycleBin5File_RecycleBinFile_GetFileSize( RecycleBin5File_RecycleBinFile_GetFileSize(
IN IRecycleBinFile *This, IN IRecycleBinFile *This,
OUT ULARGE_INTEGER *pFileSize) OUT ULARGE_INTEGER *pFileSize)
{ {
struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl); struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl);
HRESULT hr; HRESULT hr;
DWORD dwAttributes; DWORD dwAttributes;
HANDLE hFile; HANDLE hFile;
TRACE("(%p, %p)\n", This, pFileSize); TRACE("(%p, %p)\n", This, pFileSize);
dwAttributes = GetFileAttributesW(s->FullName); dwAttributes = GetFileAttributesW(s->FullName);
if (dwAttributes == INVALID_FILE_ATTRIBUTES) if (dwAttributes == INVALID_FILE_ATTRIBUTES)
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
if (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) if (dwAttributes & FILE_ATTRIBUTE_DIRECTORY)
{ {
pFileSize->QuadPart = 0; pFileSize->QuadPart = 0;
return S_OK; return S_OK;
} }
hFile = CreateFileW(s->FullName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); hFile = CreateFileW(s->FullName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) if (hFile == INVALID_HANDLE_VALUE)
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
pFileSize->u.LowPart = GetFileSize(hFile, &pFileSize->u.HighPart); pFileSize->u.LowPart = GetFileSize(hFile, &pFileSize->u.HighPart);
if (pFileSize->u.LowPart != INVALID_FILE_SIZE) if (pFileSize->u.LowPart != INVALID_FILE_SIZE)
hr = S_OK; hr = S_OK;
else else
hr = HRESULT_FROM_WIN32(GetLastError()); hr = HRESULT_FROM_WIN32(GetLastError());
CloseHandle(hFile); CloseHandle(hFile);
return hr; return hr;
} }
static HRESULT STDMETHODCALLTYPE static HRESULT STDMETHODCALLTYPE
RecycleBin5File_RecycleBinFile_GetPhysicalFileSize( RecycleBin5File_RecycleBinFile_GetPhysicalFileSize(
IN IRecycleBinFile *This, IN IRecycleBinFile *This,
OUT ULARGE_INTEGER *pPhysicalFileSize) OUT ULARGE_INTEGER *pPhysicalFileSize)
{ {
struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl); struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl);
TRACE("(%p, %p)\n", This, pPhysicalFileSize); TRACE("(%p, %p)\n", This, pPhysicalFileSize);
pPhysicalFileSize->u.HighPart = 0; pPhysicalFileSize->u.HighPart = 0;
pPhysicalFileSize->u.LowPart = s->deletedFile.dwPhysicalFileSize; pPhysicalFileSize->u.LowPart = s->deletedFile.dwPhysicalFileSize;
return S_OK; return S_OK;
} }
static HRESULT STDMETHODCALLTYPE static HRESULT STDMETHODCALLTYPE
RecycleBin5File_RecycleBinFile_GetAttributes( RecycleBin5File_RecycleBinFile_GetAttributes(
IN IRecycleBinFile *This, IN IRecycleBinFile *This,
OUT DWORD *pAttributes) OUT DWORD *pAttributes)
{ {
struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl); struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl);
DWORD dwAttributes; DWORD dwAttributes;
TRACE("(%p, %p)\n", This, pAttributes); TRACE("(%p, %p)\n", This, pAttributes);
dwAttributes = GetFileAttributesW(s->FullName); dwAttributes = GetFileAttributesW(s->FullName);
if (dwAttributes == INVALID_FILE_ATTRIBUTES) if (dwAttributes == INVALID_FILE_ATTRIBUTES)
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
*pAttributes = dwAttributes; *pAttributes = dwAttributes;
return S_OK; return S_OK;
} }
static HRESULT STDMETHODCALLTYPE static HRESULT STDMETHODCALLTYPE
RecycleBin5File_RecycleBinFile_GetFileName( RecycleBin5File_RecycleBinFile_GetFileName(
IN IRecycleBinFile *This, IN IRecycleBinFile *This,
IN SIZE_T BufferSize, IN SIZE_T BufferSize,
IN OUT LPWSTR Buffer, IN OUT LPWSTR Buffer,
OUT SIZE_T *RequiredSize) OUT SIZE_T *RequiredSize)
{ {
struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl); struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl);
DWORD dwRequired; DWORD dwRequired;
TRACE("(%p, %u, %p, %p)\n", This, BufferSize, Buffer, RequiredSize); TRACE("(%p, %u, %p, %p)\n", This, BufferSize, Buffer, RequiredSize);
dwRequired = (DWORD)(wcslen(s->deletedFile.FileNameW) + 1) * sizeof(WCHAR); dwRequired = (DWORD)(wcslen(s->deletedFile.FileNameW) + 1) * sizeof(WCHAR);
if (RequiredSize) if (RequiredSize)
*RequiredSize = dwRequired; *RequiredSize = dwRequired;
if (BufferSize == 0 && !Buffer) if (BufferSize == 0 && !Buffer)
return S_OK; return S_OK;
if (BufferSize < dwRequired) if (BufferSize < dwRequired)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
CopyMemory(Buffer, s->deletedFile.FileNameW, dwRequired); CopyMemory(Buffer, s->deletedFile.FileNameW, dwRequired);
return S_OK; return S_OK;
} }
static HRESULT STDMETHODCALLTYPE static HRESULT STDMETHODCALLTYPE
RecycleBin5File_RecycleBinFile_Delete( RecycleBin5File_RecycleBinFile_Delete(
IN IRecycleBinFile *This) IN IRecycleBinFile *This)
{ {
struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl); struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl);
TRACE("(%p)\n", This); TRACE("(%p)\n", This);
return IRecycleBin5_Delete(s->recycleBin, s->FullName, &s->deletedFile); return IRecycleBin5_Delete(s->recycleBin, s->FullName, &s->deletedFile);
} }
static HRESULT STDMETHODCALLTYPE static HRESULT STDMETHODCALLTYPE
RecycleBin5File_RecycleBinFile_Restore( RecycleBin5File_RecycleBinFile_Restore(
IN IRecycleBinFile *This) IN IRecycleBinFile *This)
{ {
struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl); struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl);
TRACE("(%p)\n", This); TRACE("(%p)\n", This);
return IRecycleBin5_Restore(s->recycleBin, s->FullName, &s->deletedFile); return IRecycleBin5_Restore(s->recycleBin, s->FullName, &s->deletedFile);
} }
CONST_VTBL struct IRecycleBinFileVtbl RecycleBin5FileVtbl = CONST_VTBL struct IRecycleBinFileVtbl RecycleBin5FileVtbl =
{ {
RecycleBin5File_RecycleBinFile_QueryInterface, RecycleBin5File_RecycleBinFile_QueryInterface,
RecycleBin5File_RecycleBinFile_AddRef, RecycleBin5File_RecycleBinFile_AddRef,
RecycleBin5File_RecycleBinFile_Release, RecycleBin5File_RecycleBinFile_Release,
RecycleBin5File_RecycleBinFile_GetLastModificationTime, RecycleBin5File_RecycleBinFile_GetLastModificationTime,
RecycleBin5File_RecycleBinFile_GetDeletionTime, RecycleBin5File_RecycleBinFile_GetDeletionTime,
RecycleBin5File_RecycleBinFile_GetFileSize, RecycleBin5File_RecycleBinFile_GetFileSize,
RecycleBin5File_RecycleBinFile_GetPhysicalFileSize, RecycleBin5File_RecycleBinFile_GetPhysicalFileSize,
RecycleBin5File_RecycleBinFile_GetAttributes, RecycleBin5File_RecycleBinFile_GetAttributes,
RecycleBin5File_RecycleBinFile_GetFileName, RecycleBin5File_RecycleBinFile_GetFileName,
RecycleBin5File_RecycleBinFile_Delete, RecycleBin5File_RecycleBinFile_Delete,
RecycleBin5File_RecycleBinFile_Restore, RecycleBin5File_RecycleBinFile_Restore,
}; };
static HRESULT static HRESULT
RecycleBin5File_Constructor( RecycleBin5File_Constructor(
IN IRecycleBin5 *prb, IN IRecycleBin5 *prb,
IN LPCWSTR Folder, IN LPCWSTR Folder,
IN PDELETED_FILE_RECORD pDeletedFile, IN PDELETED_FILE_RECORD pDeletedFile,
OUT IRecycleBinFile **ppFile) OUT IRecycleBinFile **ppFile)
{ {
struct RecycleBin5File *s = NULL; struct RecycleBin5File *s = NULL;
LPCWSTR Extension; LPCWSTR Extension;
SIZE_T Needed; SIZE_T Needed;
if (!ppFile) if (!ppFile)
return E_POINTER; return E_POINTER;
Extension = wcsrchr(pDeletedFile->FileNameW, '.'); Extension = wcsrchr(pDeletedFile->FileNameW, '.');
if (Extension < wcsrchr(pDeletedFile->FileNameW, '\\')) if (Extension < wcsrchr(pDeletedFile->FileNameW, '\\'))
Extension = NULL; Extension = NULL;
Needed = wcslen(Folder) + 13; Needed = wcslen(Folder) + 13;
if (Extension) if (Extension)
Needed += wcslen(Extension); Needed += wcslen(Extension);
Needed *= sizeof(WCHAR); Needed *= sizeof(WCHAR);
s = CoTaskMemAlloc(sizeof(struct RecycleBin5File) + Needed); s = CoTaskMemAlloc(sizeof(struct RecycleBin5File) + Needed);
if (!s) if (!s)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
ZeroMemory(s, sizeof(struct RecycleBin5File) + Needed); ZeroMemory(s, sizeof(struct RecycleBin5File) + Needed);
s->recycleBinFileImpl.lpVtbl = &RecycleBin5FileVtbl; s->recycleBinFileImpl.lpVtbl = &RecycleBin5FileVtbl;
s->ref = 1; s->ref = 1;
s->deletedFile = *pDeletedFile; s->deletedFile = *pDeletedFile;
s->recycleBin = prb; s->recycleBin = prb;
IRecycleBin5_AddRef(s->recycleBin); IRecycleBin5_AddRef(s->recycleBin);
*ppFile = &s->recycleBinFileImpl; *ppFile = &s->recycleBinFileImpl;
wsprintfW(s->FullName, L"%s\\D%c%lu%s", Folder, pDeletedFile->dwDriveNumber + 'a', pDeletedFile->dwRecordUniqueId, Extension); wsprintfW(s->FullName, L"%s\\D%c%lu%s", Folder, pDeletedFile->dwDriveNumber + 'a', pDeletedFile->dwRecordUniqueId, Extension);
if (GetFileAttributesW(s->FullName) == INVALID_FILE_ATTRIBUTES) if (GetFileAttributesW(s->FullName) == INVALID_FILE_ATTRIBUTES)
{ {
RecycleBin5File_Destructor(s); RecycleBin5File_Destructor(s);
return E_FAIL; return E_FAIL;
} }
return S_OK; return S_OK;
} }
struct RecycleBin5Enum struct RecycleBin5Enum
{ {
ULONG ref; ULONG ref;
IRecycleBin5 *recycleBin; IRecycleBin5 *recycleBin;
HANDLE hInfo; HANDLE hInfo;
INFO2_HEADER *pInfo; INFO2_HEADER *pInfo;
DWORD dwCurrent; DWORD dwCurrent;
IRecycleBinEnumList recycleBinEnumImpl; IRecycleBinEnumList recycleBinEnumImpl;
WCHAR szPrefix[ANY_SIZE]; WCHAR szPrefix[ANY_SIZE];
}; };
static HRESULT STDMETHODCALLTYPE static HRESULT STDMETHODCALLTYPE
RecycleBin5Enum_RecycleBinEnumList_QueryInterface( RecycleBin5Enum_RecycleBinEnumList_QueryInterface(
IN IRecycleBinEnumList *This, IN IRecycleBinEnumList *This,
IN REFIID riid, IN REFIID riid,
OUT void **ppvObject) OUT void **ppvObject)
{ {
struct RecycleBin5Enum *s = CONTAINING_RECORD(This, struct RecycleBin5Enum, recycleBinEnumImpl); struct RecycleBin5Enum *s = CONTAINING_RECORD(This, struct RecycleBin5Enum, recycleBinEnumImpl);
TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObject); TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObject);
if (!ppvObject) if (!ppvObject)
return E_POINTER; return E_POINTER;
if (IsEqualIID(riid, &IID_IUnknown)) if (IsEqualIID(riid, &IID_IUnknown))
*ppvObject = &s->recycleBinEnumImpl; *ppvObject = &s->recycleBinEnumImpl;
else if (IsEqualIID(riid, &IID_IRecycleBinEnumList)) else if (IsEqualIID(riid, &IID_IRecycleBinEnumList))
*ppvObject = &s->recycleBinEnumImpl; *ppvObject = &s->recycleBinEnumImpl;
else else
{ {
*ppvObject = NULL; *ppvObject = NULL;
return E_NOINTERFACE; return E_NOINTERFACE;
} }
IUnknown_AddRef(This); IUnknown_AddRef(This);
return S_OK; return S_OK;
} }
static ULONG STDMETHODCALLTYPE static ULONG STDMETHODCALLTYPE
RecycleBin5Enum_RecycleBinEnumList_AddRef( RecycleBin5Enum_RecycleBinEnumList_AddRef(
IN IRecycleBinEnumList *This) IN IRecycleBinEnumList *This)
{ {
struct RecycleBin5Enum *s = CONTAINING_RECORD(This, struct RecycleBin5Enum, recycleBinEnumImpl); struct RecycleBin5Enum *s = CONTAINING_RECORD(This, struct RecycleBin5Enum, recycleBinEnumImpl);
ULONG refCount = InterlockedIncrement((PLONG)&s->ref); ULONG refCount = InterlockedIncrement((PLONG)&s->ref);
TRACE("(%p)\n", This); TRACE("(%p)\n", This);
return refCount; return refCount;
} }
static VOID static VOID
RecycleBin5Enum_Destructor( RecycleBin5Enum_Destructor(
struct RecycleBin5Enum *s) struct RecycleBin5Enum *s)
{ {
TRACE("(%p)\n", s); TRACE("(%p)\n", s);
IRecycleBin5_OnClosing(s->recycleBin, &s->recycleBinEnumImpl); IRecycleBin5_OnClosing(s->recycleBin, &s->recycleBinEnumImpl);
UnmapViewOfFile(s->pInfo); UnmapViewOfFile(s->pInfo);
IRecycleBin5_Release(s->recycleBin); IRecycleBin5_Release(s->recycleBin);
CoTaskMemFree(s); CoTaskMemFree(s);
} }
static ULONG STDMETHODCALLTYPE static ULONG STDMETHODCALLTYPE
RecycleBin5Enum_RecycleBinEnumList_Release( RecycleBin5Enum_RecycleBinEnumList_Release(
IN IRecycleBinEnumList *This) IN IRecycleBinEnumList *This)
{ {
struct RecycleBin5Enum *s = CONTAINING_RECORD(This, struct RecycleBin5Enum, recycleBinEnumImpl); struct RecycleBin5Enum *s = CONTAINING_RECORD(This, struct RecycleBin5Enum, recycleBinEnumImpl);
ULONG refCount; ULONG refCount;
TRACE("(%p)\n", This); TRACE("(%p)\n", This);
refCount = InterlockedDecrement((PLONG)&s->ref); refCount = InterlockedDecrement((PLONG)&s->ref);
if (refCount == 0) if (refCount == 0)
RecycleBin5Enum_Destructor(s); RecycleBin5Enum_Destructor(s);
return refCount; return refCount;
} }
static HRESULT STDMETHODCALLTYPE static HRESULT STDMETHODCALLTYPE
RecycleBin5Enum_RecycleBinEnumList_Next( RecycleBin5Enum_RecycleBinEnumList_Next(
IRecycleBinEnumList *This, IRecycleBinEnumList *This,
IN DWORD celt, IN DWORD celt,
IN OUT IRecycleBinFile **rgelt, IN OUT IRecycleBinFile **rgelt,
OUT DWORD *pceltFetched) OUT DWORD *pceltFetched)
{ {
struct RecycleBin5Enum *s = CONTAINING_RECORD(This, struct RecycleBin5Enum, recycleBinEnumImpl); struct RecycleBin5Enum *s = CONTAINING_RECORD(This, struct RecycleBin5Enum, recycleBinEnumImpl);
ULARGE_INTEGER FileSize; ULARGE_INTEGER FileSize;
INFO2_HEADER *pHeader = s->pInfo; INFO2_HEADER *pHeader = s->pInfo;
DELETED_FILE_RECORD *pDeletedFile; DELETED_FILE_RECORD *pDeletedFile;
DWORD fetched = 0, i; DWORD fetched = 0, i;
DWORD dwEntries; DWORD dwEntries;
HRESULT hr; HRESULT hr;
TRACE("(%p, %u, %p, %p)\n", This, celt, rgelt, pceltFetched); TRACE("(%p, %u, %p, %p)\n", This, celt, rgelt, pceltFetched);
if (!rgelt) if (!rgelt)
return E_POINTER; return E_POINTER;
if (!pceltFetched && celt > 1) if (!pceltFetched && celt > 1)
return E_INVALIDARG; return E_INVALIDARG;
FileSize.u.LowPart = GetFileSize(s->hInfo, &FileSize.u.HighPart); FileSize.u.LowPart = GetFileSize(s->hInfo, &FileSize.u.HighPart);
if (FileSize.u.LowPart == 0) if (FileSize.u.LowPart == 0)
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
dwEntries = (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD)); dwEntries = (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD));
i = s->dwCurrent; i = s->dwCurrent;
pDeletedFile = (DELETED_FILE_RECORD *)(pHeader + 1) + i; pDeletedFile = (DELETED_FILE_RECORD *)(pHeader + 1) + i;
for (; i < dwEntries && fetched < celt; i++) for (; i < dwEntries && fetched < celt; i++)
{ {
hr = RecycleBin5File_Constructor(s->recycleBin, s->szPrefix, pDeletedFile, &rgelt[fetched]); hr = RecycleBin5File_Constructor(s->recycleBin, s->szPrefix, pDeletedFile, &rgelt[fetched]);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
fetched++; fetched++;
pDeletedFile++; pDeletedFile++;
} }
s->dwCurrent = i; s->dwCurrent = i;
if (pceltFetched) if (pceltFetched)
*pceltFetched = fetched; *pceltFetched = fetched;
if (fetched == celt) if (fetched == celt)
return S_OK; return S_OK;
else else
return S_FALSE; return S_FALSE;
} }
static HRESULT STDMETHODCALLTYPE static HRESULT STDMETHODCALLTYPE
RecycleBin5Enum_RecycleBinEnumList_Skip( RecycleBin5Enum_RecycleBinEnumList_Skip(
IN IRecycleBinEnumList *This, IN IRecycleBinEnumList *This,
IN DWORD celt) IN DWORD celt)
{ {
struct RecycleBin5Enum *s = CONTAINING_RECORD(This, struct RecycleBin5Enum, recycleBinEnumImpl); struct RecycleBin5Enum *s = CONTAINING_RECORD(This, struct RecycleBin5Enum, recycleBinEnumImpl);
TRACE("(%p, %u)\n", This, celt); TRACE("(%p, %u)\n", This, celt);
s->dwCurrent += celt; s->dwCurrent += celt;
return S_OK; return S_OK;
} }
static HRESULT STDMETHODCALLTYPE static HRESULT STDMETHODCALLTYPE
RecycleBin5Enum_RecycleBinEnumList_Reset( RecycleBin5Enum_RecycleBinEnumList_Reset(
IN IRecycleBinEnumList *This) IN IRecycleBinEnumList *This)
{ {
struct RecycleBin5Enum *s = CONTAINING_RECORD(This, struct RecycleBin5Enum, recycleBinEnumImpl); struct RecycleBin5Enum *s = CONTAINING_RECORD(This, struct RecycleBin5Enum, recycleBinEnumImpl);
TRACE("(%p)\n", This); TRACE("(%p)\n", This);
s->dwCurrent = 0; s->dwCurrent = 0;
return S_OK; return S_OK;
} }
CONST_VTBL struct IRecycleBinEnumListVtbl RecycleBin5EnumVtbl = CONST_VTBL struct IRecycleBinEnumListVtbl RecycleBin5EnumVtbl =
{ {
RecycleBin5Enum_RecycleBinEnumList_QueryInterface, RecycleBin5Enum_RecycleBinEnumList_QueryInterface,
RecycleBin5Enum_RecycleBinEnumList_AddRef, RecycleBin5Enum_RecycleBinEnumList_AddRef,
RecycleBin5Enum_RecycleBinEnumList_Release, RecycleBin5Enum_RecycleBinEnumList_Release,
RecycleBin5Enum_RecycleBinEnumList_Next, RecycleBin5Enum_RecycleBinEnumList_Next,
RecycleBin5Enum_RecycleBinEnumList_Skip, RecycleBin5Enum_RecycleBinEnumList_Skip,
RecycleBin5Enum_RecycleBinEnumList_Reset, RecycleBin5Enum_RecycleBinEnumList_Reset,
}; };
HRESULT HRESULT
RecycleBin5Enum_Constructor( RecycleBin5Enum_Constructor(
IN IRecycleBin5 *prb, IN IRecycleBin5 *prb,
IN HANDLE hInfo, IN HANDLE hInfo,
IN HANDLE hInfoMapped, IN HANDLE hInfoMapped,
IN LPCWSTR szPrefix, IN LPCWSTR szPrefix,
OUT IUnknown **ppUnknown) OUT IUnknown **ppUnknown)
{ {
struct RecycleBin5Enum *s = NULL; struct RecycleBin5Enum *s = NULL;
SIZE_T Needed; SIZE_T Needed;
if (!ppUnknown) if (!ppUnknown)
return E_POINTER; return E_POINTER;
Needed = (wcslen(szPrefix) + 1) * sizeof(WCHAR); Needed = (wcslen(szPrefix) + 1) * sizeof(WCHAR);
s = CoTaskMemAlloc(sizeof(struct RecycleBin5Enum) + Needed); s = CoTaskMemAlloc(sizeof(struct RecycleBin5Enum) + Needed);
if (!s) if (!s)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
ZeroMemory(s, sizeof(struct RecycleBin5Enum) + Needed); ZeroMemory(s, sizeof(struct RecycleBin5Enum) + Needed);
s->recycleBinEnumImpl.lpVtbl = &RecycleBin5EnumVtbl; s->recycleBinEnumImpl.lpVtbl = &RecycleBin5EnumVtbl;
s->ref = 1; s->ref = 1;
s->recycleBin = prb; s->recycleBin = prb;
wcscpy(s->szPrefix, szPrefix); wcscpy(s->szPrefix, szPrefix);
s->hInfo = hInfo; s->hInfo = hInfo;
s->pInfo = MapViewOfFile(hInfoMapped, FILE_MAP_READ, 0, 0, 0); s->pInfo = MapViewOfFile(hInfoMapped, FILE_MAP_READ, 0, 0, 0);
if (!s->pInfo) if (!s->pInfo)
{ {
CoTaskMemFree(s); CoTaskMemFree(s);
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
if (s->pInfo->dwVersion != 5 || s->pInfo->dwRecordSize != sizeof(DELETED_FILE_RECORD)) if (s->pInfo->dwVersion != 5 || s->pInfo->dwRecordSize != sizeof(DELETED_FILE_RECORD))
{ {
UnmapViewOfFile(s->pInfo); UnmapViewOfFile(s->pInfo);
CoTaskMemFree(s); CoTaskMemFree(s);
return E_FAIL; return E_FAIL;
} }
IRecycleBin5_AddRef(s->recycleBin); IRecycleBin5_AddRef(s->recycleBin);
*ppUnknown = (IUnknown *)&s->recycleBinEnumImpl; *ppUnknown = (IUnknown *)&s->recycleBinEnumImpl;
return S_OK; return S_OK;
} }