static BOOL
IntDeleteRecursive(
- IN LPCWSTR FullName)
+ IN LPCWSTR FullName)
{
- DWORD RemovableAttributes = FILE_ATTRIBUTE_READONLY;
- WIN32_FIND_DATAW FindData;
- HANDLE hSearch = INVALID_HANDLE_VALUE;
- LPWSTR FullPath = NULL, pFilePart;
- DWORD FileAttributes;
- SIZE_T dwLength;
- BOOL ret = FALSE;
-
- FileAttributes = GetFileAttributesW(FullName);
- if (FileAttributes == INVALID_FILE_ATTRIBUTES)
- {
- if (GetLastError() == ERROR_FILE_NOT_FOUND)
- ret = TRUE;
- goto cleanup;
- }
- if (FileAttributes & RemovableAttributes)
- {
- if (!SetFileAttributesW(FullName, FileAttributes & ~RemovableAttributes))
- goto cleanup;
- }
- if (FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- {
- /* Prepare file specification */
- dwLength = wcslen(FullName);
- FullPath = HeapAlloc(GetProcessHeap(), 0, (dwLength + 1 + MAX_PATH + 1) * sizeof(WCHAR));
- if (!FullPath)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- goto cleanup;
- }
- wcscpy(FullPath, FullName);
- if (FullPath[dwLength - 1] != '\\')
- {
- FullPath[dwLength] = '\\';
- dwLength++;
- }
- pFilePart = &FullPath[dwLength];
- wcscpy(pFilePart, L"*");
-
- /* Enumerate contents, and delete it */
- hSearch = FindFirstFileW(FullPath, &FindData);
- if (hSearch == INVALID_HANDLE_VALUE)
- goto cleanup;
- do
- {
- if (!(FindData.cFileName[0] == '.' &&
- (FindData.cFileName[1] == '\0' || (FindData.cFileName[1] == '.' && FindData.cFileName[2] == '\0'))))
- {
- wcscpy(pFilePart, FindData.cFileName);
- if (!IntDeleteRecursive(FullPath))
- {
- FindClose(hSearch);
- goto cleanup;
- }
- }
- }
- while (FindNextFileW(hSearch, &FindData));
- FindClose(hSearch);
- if (GetLastError() != ERROR_NO_MORE_FILES)
- goto cleanup;
-
- /* Remove (now empty) directory */
- if (!RemoveDirectoryW(FullName))
- goto cleanup;
- }
- else
- {
- if (!DeleteFileW(FullName))
- goto cleanup;
- }
- ret = TRUE;
+ DWORD RemovableAttributes = FILE_ATTRIBUTE_READONLY;
+ WIN32_FIND_DATAW FindData;
+ HANDLE hSearch = INVALID_HANDLE_VALUE;
+ LPWSTR FullPath = NULL, pFilePart;
+ DWORD FileAttributes;
+ SIZE_T dwLength;
+ BOOL ret = FALSE;
+
+ FileAttributes = GetFileAttributesW(FullName);
+ if (FileAttributes == INVALID_FILE_ATTRIBUTES)
+ {
+ if (GetLastError() == ERROR_FILE_NOT_FOUND)
+ ret = TRUE;
+ goto cleanup;
+ }
+ if (FileAttributes & RemovableAttributes)
+ {
+ if (!SetFileAttributesW(FullName, FileAttributes & ~RemovableAttributes))
+ goto cleanup;
+ }
+ if (FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ /* Prepare file specification */
+ dwLength = wcslen(FullName);
+ FullPath = HeapAlloc(GetProcessHeap(), 0, (dwLength + 1 + MAX_PATH + 1) * sizeof(WCHAR));
+ if (!FullPath)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto cleanup;
+ }
+ wcscpy(FullPath, FullName);
+ if (FullPath[dwLength - 1] != '\\')
+ {
+ FullPath[dwLength] = '\\';
+ dwLength++;
+ }
+ pFilePart = &FullPath[dwLength];
+ wcscpy(pFilePart, L"*");
+
+ /* Enumerate contents, and delete it */
+ hSearch = FindFirstFileW(FullPath, &FindData);
+ if (hSearch == INVALID_HANDLE_VALUE)
+ goto cleanup;
+ do
+ {
+ if (!(FindData.cFileName[0] == '.' &&
+ (FindData.cFileName[1] == '\0' || (FindData.cFileName[1] == '.' && FindData.cFileName[2] == '\0'))))
+ {
+ wcscpy(pFilePart, FindData.cFileName);
+ if (!IntDeleteRecursive(FullPath))
+ {
+ FindClose(hSearch);
+ goto cleanup;
+ }
+ }
+ }
+ while (FindNextFileW(hSearch, &FindData));
+ FindClose(hSearch);
+ if (GetLastError() != ERROR_NO_MORE_FILES)
+ goto cleanup;
+
+ /* Remove (now empty) directory */
+ if (!RemoveDirectoryW(FullName))
+ goto cleanup;
+ }
+ else
+ {
+ if (!DeleteFileW(FullName))
+ goto cleanup;
+ }
+ ret = TRUE;
cleanup:
- HeapFree(GetProcessHeap(), 0, FullPath);
- return ret;
+ HeapFree(GetProcessHeap(), 0, FullPath);
+ return ret;
}
struct RecycleBin5
{
- ULONG ref;
- IRecycleBin5 recycleBinImpl;
- HANDLE hInfo;
- HANDLE hInfoMapped;
+ ULONG ref;
+ IRecycleBin5 recycleBinImpl;
+ HANDLE hInfo;
+ HANDLE hInfoMapped;
- DWORD EnumeratorCount;
+ DWORD EnumeratorCount;
- LPWSTR VolumePath;
- WCHAR Folder[ANY_SIZE]; /* [drive]:\[RECYCLE_BIN_DIRECTORY]\{SID} */
+ LPWSTR VolumePath;
+ WCHAR Folder[ANY_SIZE]; /* [drive]:\[RECYCLE_BIN_DIRECTORY]\{SID} */
};
static HRESULT STDMETHODCALLTYPE
RecycleBin5_RecycleBin5_QueryInterface(
- IRecycleBin5 *This,
- REFIID riid,
- void **ppvObject)
+ IRecycleBin5 *This,
+ REFIID riid,
+ void **ppvObject)
{
- struct RecycleBin5 *s = CONTAINING_RECORD(This, struct RecycleBin5, recycleBinImpl);
-
- TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObject);
-
- if (!ppvObject)
- return E_POINTER;
-
- if (IsEqualIID(riid, &IID_IUnknown))
- *ppvObject = &s->recycleBinImpl;
- else if (IsEqualIID(riid, &IID_IRecycleBin))
- *ppvObject = &s->recycleBinImpl;
- else if (IsEqualIID(riid, &IID_IRecycleBin5))
- *ppvObject = &s->recycleBinImpl;
- else
- {
- *ppvObject = NULL;
- return E_NOINTERFACE;
- }
-
- IUnknown_AddRef(This);
- return S_OK;
+ struct RecycleBin5 *s = CONTAINING_RECORD(This, struct RecycleBin5, recycleBinImpl);
+
+ TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObject);
+
+ if (!ppvObject)
+ return E_POINTER;
+
+ if (IsEqualIID(riid, &IID_IUnknown))
+ *ppvObject = &s->recycleBinImpl;
+ else if (IsEqualIID(riid, &IID_IRecycleBin))
+ *ppvObject = &s->recycleBinImpl;
+ else if (IsEqualIID(riid, &IID_IRecycleBin5))
+ *ppvObject = &s->recycleBinImpl;
+ else
+ {
+ *ppvObject = NULL;
+ return E_NOINTERFACE;
+ }
+
+ IUnknown_AddRef(This);
+ return S_OK;
}
static ULONG STDMETHODCALLTYPE
RecycleBin5_RecycleBin5_AddRef(
- IRecycleBin5 *This)
+ IRecycleBin5 *This)
{
- struct RecycleBin5 *s = CONTAINING_RECORD(This, struct RecycleBin5, recycleBinImpl);
- ULONG refCount = InterlockedIncrement((PLONG)&s->ref);
- TRACE("(%p)\n", This);
- return refCount;
+ struct RecycleBin5 *s = CONTAINING_RECORD(This, struct RecycleBin5, recycleBinImpl);
+ ULONG refCount = InterlockedIncrement((PLONG)&s->ref);
+ TRACE("(%p)\n", This);
+ return refCount;
}
static VOID
RecycleBin5_Destructor(
- struct RecycleBin5 *s)
+ struct RecycleBin5 *s)
{
- TRACE("(%p)\n", s);
+ TRACE("(%p)\n", s);
- if (s->hInfo && s->hInfo != INVALID_HANDLE_VALUE)
- CloseHandle(s->hInfo);
- if (s->hInfoMapped)
- CloseHandle(s->hInfoMapped);
- CoTaskMemFree(s);
+ if (s->hInfo && s->hInfo != INVALID_HANDLE_VALUE)
+ CloseHandle(s->hInfo);
+ if (s->hInfoMapped)
+ CloseHandle(s->hInfoMapped);
+ CoTaskMemFree(s);
}
static ULONG STDMETHODCALLTYPE
RecycleBin5_RecycleBin5_Release(
- IRecycleBin5 *This)
+ IRecycleBin5 *This)
{
- struct RecycleBin5 *s = CONTAINING_RECORD(This, struct RecycleBin5, recycleBinImpl);
- ULONG refCount;
+ struct RecycleBin5 *s = CONTAINING_RECORD(This, struct RecycleBin5, recycleBinImpl);
+ ULONG refCount;
- TRACE("(%p)\n", This);
+ TRACE("(%p)\n", This);
- refCount = InterlockedDecrement((PLONG)&s->ref);
+ refCount = InterlockedDecrement((PLONG)&s->ref);
- if (refCount == 0)
- RecycleBin5_Destructor(s);
+ if (refCount == 0)
+ RecycleBin5_Destructor(s);
- return refCount;
+ return refCount;
}
static HRESULT STDMETHODCALLTYPE
RecycleBin5_RecycleBin5_DeleteFile(
- IN IRecycleBin5 *This,
- IN LPCWSTR szFileName)
+ IN IRecycleBin5 *This,
+ IN LPCWSTR szFileName)
{
- struct RecycleBin5 *s = CONTAINING_RECORD(This, struct RecycleBin5, recycleBinImpl);
- LPWSTR szFullName = NULL;
- DWORD dwBufferLength = 0;
- LPWSTR lpFilePart;
- LPCWSTR Extension;
- WCHAR DeletedFileName[MAX_PATH];
- DWORD len;
- HANDLE hFile = INVALID_HANDLE_VALUE;
- PINFO2_HEADER pHeader = NULL;
- PDELETED_FILE_RECORD pDeletedFile;
- ULARGE_INTEGER FileSize;
- DWORD dwAttributes, dwEntries;
- SYSTEMTIME SystemTime;
- DWORD ClusterSize, BytesPerSector, SectorsPerCluster;
- HRESULT hr;
-
- TRACE("(%p, %s)\n", This, debugstr_w(szFileName));
-
- if (s->EnumeratorCount != 0)
- return HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION);
-
- /* Get full file name */
- while (TRUE)
- {
- len = GetFullPathNameW(szFileName, dwBufferLength, szFullName, &lpFilePart);
- if (len == 0)
- {
- if (szFullName)
- CoTaskMemFree(szFullName);
- return HRESULT_FROM_WIN32(GetLastError());
- }
- else if (len < dwBufferLength)
- break;
- if (szFullName)
- CoTaskMemFree(szFullName);
- dwBufferLength = len;
- szFullName = CoTaskMemAlloc(dwBufferLength * sizeof(WCHAR));
- if (!szFullName)
- return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
- }
-
- /* Check if file exists */
- dwAttributes = GetFileAttributesW(szFullName);
- if (dwAttributes == INVALID_FILE_ATTRIBUTES)
- {
- CoTaskMemFree(szFullName);
- return HRESULT_FROM_WIN32(GetLastError());
- }
-
- if (dwBufferLength < 2 || szFullName[1] != ':')
- {
- /* Not a local file */
- CoTaskMemFree(szFullName);
- return HRESULT_FROM_WIN32(ERROR_INVALID_NAME);
- }
-
- hFile = CreateFileW(szFullName, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
- if (hFile == INVALID_HANDLE_VALUE)
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto cleanup;
- }
-
- /* Increase INFO2 file size */
- CloseHandle(s->hInfoMapped);
- SetFilePointer(s->hInfo, sizeof(DELETED_FILE_RECORD), NULL, FILE_END);
- SetEndOfFile(s->hInfo);
- s->hInfoMapped = CreateFileMappingW(s->hInfo, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 0, NULL);
- if (!s->hInfoMapped)
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto cleanup;
- }
-
- /* Open INFO2 file */
- pHeader = MapViewOfFile(s->hInfoMapped, FILE_MAP_WRITE, 0, 0, 0);
- if (!pHeader)
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto cleanup;
- }
-
- /* Get number of entries */
- FileSize.u.LowPart = GetFileSize(s->hInfo, &FileSize.u.HighPart);
- if (FileSize.u.LowPart < sizeof(INFO2_HEADER))
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto cleanup;
- }
- dwEntries = (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD)) - 1;
- pDeletedFile = ((PDELETED_FILE_RECORD)(pHeader + 1)) + dwEntries;
-
- /* Get file size */
+ struct RecycleBin5 *s = CONTAINING_RECORD(This, struct RecycleBin5, recycleBinImpl);
+ LPWSTR szFullName = NULL;
+ DWORD dwBufferLength = 0;
+ LPWSTR lpFilePart;
+ LPCWSTR Extension;
+ WCHAR DeletedFileName[MAX_PATH];
+ DWORD len;
+ HANDLE hFile = INVALID_HANDLE_VALUE;
+ PINFO2_HEADER pHeader = NULL;
+ PDELETED_FILE_RECORD pDeletedFile;
+ ULARGE_INTEGER FileSize;
+ DWORD dwAttributes, dwEntries;
+ SYSTEMTIME SystemTime;
+ DWORD ClusterSize, BytesPerSector, SectorsPerCluster;
+ HRESULT hr;
+
+ TRACE("(%p, %s)\n", This, debugstr_w(szFileName));
+
+ if (s->EnumeratorCount != 0)
+ return HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION);
+
+ /* Get full file name */
+ while (TRUE)
+ {
+ len = GetFullPathNameW(szFileName, dwBufferLength, szFullName, &lpFilePart);
+ if (len == 0)
+ {
+ if (szFullName)
+ CoTaskMemFree(szFullName);
+ return HRESULT_FROM_WIN32(GetLastError());
+ }
+ else if (len < dwBufferLength)
+ break;
+ if (szFullName)
+ CoTaskMemFree(szFullName);
+ dwBufferLength = len;
+ szFullName = CoTaskMemAlloc(dwBufferLength * sizeof(WCHAR));
+ if (!szFullName)
+ return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
+ }
+
+ /* Check if file exists */
+ dwAttributes = GetFileAttributesW(szFullName);
+ if (dwAttributes == INVALID_FILE_ATTRIBUTES)
+ {
+ CoTaskMemFree(szFullName);
+ return HRESULT_FROM_WIN32(GetLastError());
+ }
+
+ if (dwBufferLength < 2 || szFullName[1] != ':')
+ {
+ /* Not a local file */
+ CoTaskMemFree(szFullName);
+ return HRESULT_FROM_WIN32(ERROR_INVALID_NAME);
+ }
+
+ hFile = CreateFileW(szFullName, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto cleanup;
+ }
+
+ /* Increase INFO2 file size */
+ CloseHandle(s->hInfoMapped);
+ SetFilePointer(s->hInfo, sizeof(DELETED_FILE_RECORD), NULL, FILE_END);
+ SetEndOfFile(s->hInfo);
+ s->hInfoMapped = CreateFileMappingW(s->hInfo, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 0, NULL);
+ if (!s->hInfoMapped)
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto cleanup;
+ }
+
+ /* Open INFO2 file */
+ pHeader = MapViewOfFile(s->hInfoMapped, FILE_MAP_WRITE, 0, 0, 0);
+ if (!pHeader)
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto cleanup;
+ }
+
+ /* Get number of entries */
+ FileSize.u.LowPart = GetFileSize(s->hInfo, &FileSize.u.HighPart);
+ if (FileSize.u.LowPart < sizeof(INFO2_HEADER))
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto cleanup;
+ }
+ dwEntries = (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD)) - 1;
+ pDeletedFile = ((PDELETED_FILE_RECORD)(pHeader + 1)) + dwEntries;
+
+ /* Get file size */
#if 0
- if (!GetFileSizeEx(hFile, (PLARGE_INTEGER)&FileSize))
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto cleanup;
- }
+ if (!GetFileSizeEx(hFile, (PLARGE_INTEGER)&FileSize))
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto cleanup;
+ }
#else
- FileSize.u.LowPart = GetFileSize(hFile, &FileSize.u.HighPart);
- if (FileSize.u.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR)
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto cleanup;
- }
+ FileSize.u.LowPart = GetFileSize(hFile, &FileSize.u.HighPart);
+ if (FileSize.u.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR)
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto cleanup;
+ }
#endif
- /* Check if file size is > 4Gb */
- if (FileSize.u.HighPart != 0)
- {
- /* Yes, this recyclebin can't support this file */
- hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
- goto cleanup;
- }
- pHeader->dwTotalLogicalSize += FileSize.u.LowPart;
-
- /* Generate new name */
- Extension = wcsrchr(szFullName, '.');
- ZeroMemory(pDeletedFile, sizeof(DELETED_FILE_RECORD));
- if (dwEntries == 0)
- pDeletedFile->dwRecordUniqueId = 0;
- else
- {
- PDELETED_FILE_RECORD pLastDeleted = ((PDELETED_FILE_RECORD)(pHeader + 1)) + dwEntries - 1;
- pDeletedFile->dwRecordUniqueId = pLastDeleted->dwRecordUniqueId + 1;
- }
- pDeletedFile->dwDriveNumber = tolower(szFullName[0]) - 'a';
- _snwprintf(DeletedFileName, MAX_PATH, L"%s\\D%c%lu%s", s->Folder, pDeletedFile->dwDriveNumber + 'a', pDeletedFile->dwRecordUniqueId, Extension);
-
- /* Get cluster size */
- if (!GetDiskFreeSpaceW(s->VolumePath, &SectorsPerCluster, &BytesPerSector, NULL, NULL))
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto cleanup;
- }
- ClusterSize = BytesPerSector * SectorsPerCluster;
-
- /* Get current time */
- GetSystemTime(&SystemTime);
- if (!SystemTimeToFileTime(&SystemTime, &pDeletedFile->DeletionTime))
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto cleanup;
- }
- pDeletedFile->dwPhysicalFileSize = ROUND_UP(FileSize.u.LowPart, ClusterSize);
-
- /* Set name */
- wcscpy(pDeletedFile->FileNameW, szFullName);
- if (WideCharToMultiByte(CP_ACP, 0, pDeletedFile->FileNameW, -1, pDeletedFile->FileNameA, MAX_PATH, NULL, NULL) == 0)
- {
- hr = HRESULT_FROM_WIN32(ERROR_INVALID_NAME);
- SetLastError(ERROR_INVALID_NAME);
- goto cleanup;
- }
-
- /* Move file */
- if (MoveFileW(szFullName, DeletedFileName))
- hr = S_OK;
- else
- hr = HRESULT_FROM_WIN32(GetLastError());
+ /* Check if file size is > 4Gb */
+ if (FileSize.u.HighPart != 0)
+ {
+ /* Yes, this recyclebin can't support this file */
+ hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
+ goto cleanup;
+ }
+ pHeader->dwTotalLogicalSize += FileSize.u.LowPart;
+
+ /* Generate new name */
+ Extension = wcsrchr(szFullName, '.');
+ ZeroMemory(pDeletedFile, sizeof(DELETED_FILE_RECORD));
+ if (dwEntries == 0)
+ pDeletedFile->dwRecordUniqueId = 0;
+ else
+ {
+ PDELETED_FILE_RECORD pLastDeleted = ((PDELETED_FILE_RECORD)(pHeader + 1)) + dwEntries - 1;
+ pDeletedFile->dwRecordUniqueId = pLastDeleted->dwRecordUniqueId + 1;
+ }
+ pDeletedFile->dwDriveNumber = tolower(szFullName[0]) - 'a';
+ _snwprintf(DeletedFileName, MAX_PATH, L"%s\\D%c%lu%s", s->Folder, pDeletedFile->dwDriveNumber + 'a', pDeletedFile->dwRecordUniqueId, Extension);
+
+ /* Get cluster size */
+ if (!GetDiskFreeSpaceW(s->VolumePath, &SectorsPerCluster, &BytesPerSector, NULL, NULL))
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto cleanup;
+ }
+ ClusterSize = BytesPerSector * SectorsPerCluster;
+
+ /* Get current time */
+ GetSystemTime(&SystemTime);
+ if (!SystemTimeToFileTime(&SystemTime, &pDeletedFile->DeletionTime))
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto cleanup;
+ }
+ pDeletedFile->dwPhysicalFileSize = ROUND_UP(FileSize.u.LowPart, ClusterSize);
+
+ /* Set name */
+ wcscpy(pDeletedFile->FileNameW, szFullName);
+ if (WideCharToMultiByte(CP_ACP, 0, pDeletedFile->FileNameW, -1, pDeletedFile->FileNameA, MAX_PATH, NULL, NULL) == 0)
+ {
+ hr = HRESULT_FROM_WIN32(ERROR_INVALID_NAME);
+ SetLastError(ERROR_INVALID_NAME);
+ goto cleanup;
+ }
+
+ /* Move file */
+ if (MoveFileW(szFullName, DeletedFileName))
+ hr = S_OK;
+ else
+ hr = HRESULT_FROM_WIN32(GetLastError());
cleanup:
- if (pHeader)
- UnmapViewOfFile(pHeader);
- if (hFile != INVALID_HANDLE_VALUE)
- CloseHandle(hFile);
- CoTaskMemFree(szFullName);
- return hr;
+ if (pHeader)
+ UnmapViewOfFile(pHeader);
+ if (hFile != INVALID_HANDLE_VALUE)
+ CloseHandle(hFile);
+ CoTaskMemFree(szFullName);
+ return hr;
}
static HRESULT STDMETHODCALLTYPE
RecycleBin5_RecycleBin5_EmptyRecycleBin(
- IN IRecycleBin5 *This)
+ IN IRecycleBin5 *This)
{
- IRecycleBinEnumList *prbel;
- IRecycleBinFile *prbf;
- HRESULT hr;
-
- TRACE("(%p)\n", This);
-
- while (TRUE)
- {
- hr = IRecycleBin5_EnumObjects(This, &prbel);
- if (!SUCCEEDED(hr))
- return hr;
- hr = IRecycleBinEnumList_Next(prbel, 1, &prbf, NULL);
- IRecycleBinEnumList_Release(prbel);
- if (hr == S_FALSE)
- return S_OK;
- hr = IRecycleBinFile_Delete(prbf);
- IRecycleBinFile_Release(prbf);
- if (!SUCCEEDED(hr))
- return hr;
- }
+ IRecycleBinEnumList *prbel;
+ IRecycleBinFile *prbf;
+ HRESULT hr;
+
+ TRACE("(%p)\n", This);
+
+ while (TRUE)
+ {
+ hr = IRecycleBin5_EnumObjects(This, &prbel);
+ if (!SUCCEEDED(hr))
+ return hr;
+ hr = IRecycleBinEnumList_Next(prbel, 1, &prbf, NULL);
+ IRecycleBinEnumList_Release(prbel);
+ if (hr == S_FALSE)
+ return S_OK;
+ hr = IRecycleBinFile_Delete(prbf);
+ IRecycleBinFile_Release(prbf);
+ if (!SUCCEEDED(hr))
+ return hr;
+ }
}
static HRESULT STDMETHODCALLTYPE
RecycleBin5_RecycleBin5_EnumObjects(
- IN IRecycleBin5 *This,
- OUT IRecycleBinEnumList **ppEnumList)
+ IN IRecycleBin5 *This,
+ OUT IRecycleBinEnumList **ppEnumList)
{
- struct RecycleBin5 *s = CONTAINING_RECORD(This, struct RecycleBin5, recycleBinImpl);
- IRecycleBinEnumList *prbel;
- HRESULT hr;
- IUnknown *pUnk;
-
- TRACE("(%p, %p)\n", This, ppEnumList);
-
- hr = RecycleBin5Enum_Constructor(This, s->hInfo, s->hInfoMapped, s->Folder, &pUnk);
- if (!SUCCEEDED(hr))
- return hr;
-
- hr = IUnknown_QueryInterface(pUnk, &IID_IRecycleBinEnumList, (void **)&prbel);
- if (SUCCEEDED(hr))
- {
- s->EnumeratorCount++;
- *ppEnumList = prbel;
- }
- IUnknown_Release(pUnk);
- return hr;
+ struct RecycleBin5 *s = CONTAINING_RECORD(This, struct RecycleBin5, recycleBinImpl);
+ IRecycleBinEnumList *prbel;
+ HRESULT hr;
+ IUnknown *pUnk;
+
+ TRACE("(%p, %p)\n", This, ppEnumList);
+
+ hr = RecycleBin5Enum_Constructor(This, s->hInfo, s->hInfoMapped, s->Folder, &pUnk);
+ if (!SUCCEEDED(hr))
+ return hr;
+
+ hr = IUnknown_QueryInterface(pUnk, &IID_IRecycleBinEnumList, (void **)&prbel);
+ if (SUCCEEDED(hr))
+ {
+ s->EnumeratorCount++;
+ *ppEnumList = prbel;
+ }
+ IUnknown_Release(pUnk);
+ return hr;
}
static HRESULT STDMETHODCALLTYPE
RecycleBin5_RecycleBin5_Delete(
- IN IRecycleBin5 *This,
- IN LPCWSTR pDeletedFileName,
- IN DELETED_FILE_RECORD *pDeletedFile)
+ IN IRecycleBin5 *This,
+ IN LPCWSTR pDeletedFileName,
+ IN DELETED_FILE_RECORD *pDeletedFile)
{
- struct RecycleBin5 *s = CONTAINING_RECORD(This, struct RecycleBin5, recycleBinImpl);
- ULARGE_INTEGER FileSize;
- PINFO2_HEADER pHeader;
- DELETED_FILE_RECORD *pRecord, *pLast;
- DWORD dwEntries, i;
-
- TRACE("(%p, %s, %p)\n", This, debugstr_w(pDeletedFileName), pDeletedFile);
-
- if (s->EnumeratorCount != 0)
- return HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION);
-
- pHeader = MapViewOfFile(s->hInfoMapped, FILE_MAP_WRITE, 0, 0, 0);
- if (!pHeader)
- return HRESULT_FROM_WIN32(GetLastError());
-
- FileSize.u.LowPart = GetFileSize(s->hInfo, &FileSize.u.HighPart);
- if (FileSize.u.LowPart == 0)
- {
- UnmapViewOfFile(pHeader);
- return HRESULT_FROM_WIN32(GetLastError());
- }
- dwEntries = (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD));
-
- pRecord = (DELETED_FILE_RECORD *)(pHeader + 1);
- for (i = 0; i < dwEntries; i++)
- {
- if (pRecord->dwRecordUniqueId == pDeletedFile->dwRecordUniqueId)
- {
- /* Delete file */
- if (!IntDeleteRecursive(pDeletedFileName))
- {
- UnmapViewOfFile(pHeader);
- return HRESULT_FROM_WIN32(GetLastError());
- }
-
- /* Clear last entry in the file */
- MoveMemory(pRecord, pRecord + 1, (dwEntries - i - 1) * sizeof(DELETED_FILE_RECORD));
- pLast = pRecord + (dwEntries - i - 1);
- ZeroMemory(pLast, sizeof(DELETED_FILE_RECORD));
- UnmapViewOfFile(pHeader);
-
- /* Resize file */
- CloseHandle(s->hInfoMapped);
- SetFilePointer(s->hInfo, -(LONG)sizeof(DELETED_FILE_RECORD), NULL, FILE_END);
- SetEndOfFile(s->hInfo);
- s->hInfoMapped = CreateFileMappingW(s->hInfo, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 0, NULL);
- if (!s->hInfoMapped)
- return HRESULT_FROM_WIN32(GetLastError());
- return S_OK;
- }
- pRecord++;
- }
- UnmapViewOfFile(pHeader);
- return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
+ struct RecycleBin5 *s = CONTAINING_RECORD(This, struct RecycleBin5, recycleBinImpl);
+ ULARGE_INTEGER FileSize;
+ PINFO2_HEADER pHeader;
+ DELETED_FILE_RECORD *pRecord, *pLast;
+ DWORD dwEntries, i;
+
+ TRACE("(%p, %s, %p)\n", This, debugstr_w(pDeletedFileName), pDeletedFile);
+
+ if (s->EnumeratorCount != 0)
+ return HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION);
+
+ pHeader = MapViewOfFile(s->hInfoMapped, FILE_MAP_WRITE, 0, 0, 0);
+ if (!pHeader)
+ return HRESULT_FROM_WIN32(GetLastError());
+
+ FileSize.u.LowPart = GetFileSize(s->hInfo, &FileSize.u.HighPart);
+ if (FileSize.u.LowPart == 0)
+ {
+ UnmapViewOfFile(pHeader);
+ return HRESULT_FROM_WIN32(GetLastError());
+ }
+ dwEntries = (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD));
+
+ pRecord = (DELETED_FILE_RECORD *)(pHeader + 1);
+ for (i = 0; i < dwEntries; i++)
+ {
+ if (pRecord->dwRecordUniqueId == pDeletedFile->dwRecordUniqueId)
+ {
+ /* Delete file */
+ if (!IntDeleteRecursive(pDeletedFileName))
+ {
+ UnmapViewOfFile(pHeader);
+ return HRESULT_FROM_WIN32(GetLastError());
+ }
+
+ /* Clear last entry in the file */
+ MoveMemory(pRecord, pRecord + 1, (dwEntries - i - 1) * sizeof(DELETED_FILE_RECORD));
+ pLast = pRecord + (dwEntries - i - 1);
+ ZeroMemory(pLast, sizeof(DELETED_FILE_RECORD));
+ UnmapViewOfFile(pHeader);
+
+ /* Resize file */
+ CloseHandle(s->hInfoMapped);
+ SetFilePointer(s->hInfo, -(LONG)sizeof(DELETED_FILE_RECORD), NULL, FILE_END);
+ SetEndOfFile(s->hInfo);
+ s->hInfoMapped = CreateFileMappingW(s->hInfo, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 0, NULL);
+ if (!s->hInfoMapped)
+ return HRESULT_FROM_WIN32(GetLastError());
+ return S_OK;
+ }
+ pRecord++;
+ }
+ UnmapViewOfFile(pHeader);
+ return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
static HRESULT STDMETHODCALLTYPE
RecycleBin5_RecycleBin5_Restore(
- IN IRecycleBin5 *This,
- IN LPCWSTR pDeletedFileName,
- IN DELETED_FILE_RECORD *pDeletedFile)
+ IN IRecycleBin5 *This,
+ IN LPCWSTR pDeletedFileName,
+ IN DELETED_FILE_RECORD *pDeletedFile)
{
- struct RecycleBin5 *s = CONTAINING_RECORD(This, struct RecycleBin5, recycleBinImpl);
- ULARGE_INTEGER FileSize;
- PINFO2_HEADER pHeader;
- DELETED_FILE_RECORD *pRecord, *pLast;
- DWORD dwEntries, i;
- SHFILEOPSTRUCTW op;
-
- TRACE("(%p, %s, %p)\n", This, debugstr_w(pDeletedFileName), pDeletedFile);
-
- if (s->EnumeratorCount != 0)
- return HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION);
-
- pHeader = MapViewOfFile(s->hInfoMapped, FILE_MAP_WRITE, 0, 0, 0);
- if (!pHeader)
- return HRESULT_FROM_WIN32(GetLastError());
-
- FileSize.u.LowPart = GetFileSize(s->hInfo, &FileSize.u.HighPart);
- if (FileSize.u.LowPart == 0)
- {
- UnmapViewOfFile(pHeader);
- return HRESULT_FROM_WIN32(GetLastError());
- }
- dwEntries = (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD));
-
- pRecord = (DELETED_FILE_RECORD *)(pHeader + 1);
- for (i = 0; i < dwEntries; i++)
- {
- if (pRecord->dwRecordUniqueId == pDeletedFile->dwRecordUniqueId)
- {
- /* Restore file */
- ZeroMemory(&op, sizeof(op));
- op.wFunc = FO_COPY;
- op.pFrom = pDeletedFileName;
- op.pTo = pDeletedFile->FileNameW;
-
- if (!SHFileOperationW(&op))
- {
- UnmapViewOfFile(pHeader);
- return HRESULT_FROM_WIN32(GetLastError());
- }
-
- /* Clear last entry in the file */
- MoveMemory(pRecord, pRecord + 1, (dwEntries - i - 1) * sizeof(DELETED_FILE_RECORD));
- pLast = pRecord + (dwEntries - i - 1);
- ZeroMemory(pLast, sizeof(DELETED_FILE_RECORD));
- UnmapViewOfFile(pHeader);
-
- /* Resize file */
- CloseHandle(s->hInfoMapped);
- SetFilePointer(s->hInfo, -(LONG)sizeof(DELETED_FILE_RECORD), NULL, FILE_END);
- SetEndOfFile(s->hInfo);
- s->hInfoMapped = CreateFileMappingW(s->hInfo, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 0, NULL);
- if (!s->hInfoMapped)
- return HRESULT_FROM_WIN32(GetLastError());
- return S_OK;
- }
- pRecord++;
- }
-
- UnmapViewOfFile(pHeader);
- return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
+ struct RecycleBin5 *s = CONTAINING_RECORD(This, struct RecycleBin5, recycleBinImpl);
+ ULARGE_INTEGER FileSize;
+ PINFO2_HEADER pHeader;
+ DELETED_FILE_RECORD *pRecord, *pLast;
+ DWORD dwEntries, i;
+ SHFILEOPSTRUCTW op;
+
+ TRACE("(%p, %s, %p)\n", This, debugstr_w(pDeletedFileName), pDeletedFile);
+
+ if (s->EnumeratorCount != 0)
+ return HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION);
+
+ pHeader = MapViewOfFile(s->hInfoMapped, FILE_MAP_WRITE, 0, 0, 0);
+ if (!pHeader)
+ return HRESULT_FROM_WIN32(GetLastError());
+
+ FileSize.u.LowPart = GetFileSize(s->hInfo, &FileSize.u.HighPart);
+ if (FileSize.u.LowPart == 0)
+ {
+ UnmapViewOfFile(pHeader);
+ return HRESULT_FROM_WIN32(GetLastError());
+ }
+ dwEntries = (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD));
+
+ pRecord = (DELETED_FILE_RECORD *)(pHeader + 1);
+ for (i = 0; i < dwEntries; i++)
+ {
+ if (pRecord->dwRecordUniqueId == pDeletedFile->dwRecordUniqueId)
+ {
+ /* Restore file */
+ ZeroMemory(&op, sizeof(op));
+ op.wFunc = FO_COPY;
+ op.pFrom = pDeletedFileName;
+ op.pTo = pDeletedFile->FileNameW;
+
+ if (!SHFileOperationW(&op))
+ {
+ UnmapViewOfFile(pHeader);
+ return HRESULT_FROM_WIN32(GetLastError());
+ }
+
+ /* Clear last entry in the file */
+ MoveMemory(pRecord, pRecord + 1, (dwEntries - i - 1) * sizeof(DELETED_FILE_RECORD));
+ pLast = pRecord + (dwEntries - i - 1);
+ ZeroMemory(pLast, sizeof(DELETED_FILE_RECORD));
+ UnmapViewOfFile(pHeader);
+
+ /* Resize file */
+ CloseHandle(s->hInfoMapped);
+ SetFilePointer(s->hInfo, -(LONG)sizeof(DELETED_FILE_RECORD), NULL, FILE_END);
+ SetEndOfFile(s->hInfo);
+ s->hInfoMapped = CreateFileMappingW(s->hInfo, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 0, NULL);
+ if (!s->hInfoMapped)
+ return HRESULT_FROM_WIN32(GetLastError());
+ return S_OK;
+ }
+ pRecord++;
+ }
+
+ UnmapViewOfFile(pHeader);
+ return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
static HRESULT STDMETHODCALLTYPE
RecycleBin5_RecycleBin5_OnClosing(
- IN IRecycleBin5 *This,
- IN IRecycleBinEnumList *prbel)
+ IN IRecycleBin5 *This,
+ IN IRecycleBinEnumList *prbel)
{
- struct RecycleBin5 *s = CONTAINING_RECORD(This, struct RecycleBin5, recycleBinImpl);
- TRACE("(%p, %p)\n", This, prbel);
- s->EnumeratorCount--;
- return S_OK;
+ struct RecycleBin5 *s = CONTAINING_RECORD(This, struct RecycleBin5, recycleBinImpl);
+ TRACE("(%p, %p)\n", This, prbel);
+ s->EnumeratorCount--;
+ return S_OK;
}
CONST_VTBL struct IRecycleBin5Vtbl RecycleBin5Vtbl =
{
- RecycleBin5_RecycleBin5_QueryInterface,
- RecycleBin5_RecycleBin5_AddRef,
- RecycleBin5_RecycleBin5_Release,
- RecycleBin5_RecycleBin5_DeleteFile,
- RecycleBin5_RecycleBin5_EmptyRecycleBin,
- RecycleBin5_RecycleBin5_EnumObjects,
- RecycleBin5_RecycleBin5_Delete,
- RecycleBin5_RecycleBin5_Restore,
- RecycleBin5_RecycleBin5_OnClosing,
+ RecycleBin5_RecycleBin5_QueryInterface,
+ RecycleBin5_RecycleBin5_AddRef,
+ RecycleBin5_RecycleBin5_Release,
+ RecycleBin5_RecycleBin5_DeleteFile,
+ RecycleBin5_RecycleBin5_EmptyRecycleBin,
+ RecycleBin5_RecycleBin5_EnumObjects,
+ RecycleBin5_RecycleBin5_Delete,
+ RecycleBin5_RecycleBin5_Restore,
+ RecycleBin5_RecycleBin5_OnClosing,
};
static HRESULT
RecycleBin5_Create(
- IN LPCWSTR Folder,
- IN PSID OwnerSid OPTIONAL)
+ IN LPCWSTR Folder,
+ IN PSID OwnerSid OPTIONAL)
{
- LPWSTR BufferName = NULL;
- LPWSTR Separator; /* Pointer into BufferName buffer */
- LPWSTR FileName; /* Pointer into BufferName buffer */
- LPCSTR DesktopIniContents = "[.ShellClassInfo]\r\nCLSID={645FF040-5081-101B-9F08-00AA002F954E}\r\n";
- INFO2_HEADER Info2Contents[] = { { 5, 0, 0, 0x320, 0 } };
- DWORD BytesToWrite, BytesWritten, Needed;
- HANDLE hFile = INVALID_HANDLE_VALUE;
- HRESULT hr;
-
- Needed = (wcslen(Folder) + 1 + max(wcslen(RECYCLE_BIN_FILE_NAME), wcslen(L"desktop.ini")) + 1) * sizeof(WCHAR);
- BufferName = HeapAlloc(GetProcessHeap(), 0, Needed);
- if (!BufferName)
- {
- hr = ERROR_NOT_ENOUGH_MEMORY;
- goto cleanup;
- }
-
- wcscpy(BufferName, Folder);
- Separator = wcsstr(&BufferName[3], L"\\");
- if (Separator)
- *Separator = UNICODE_NULL;
- if (!CreateDirectoryW(BufferName, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto cleanup;
- }
- SetFileAttributesW(BufferName, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
- if (Separator)
- {
- *Separator = L'\\';
- if (!CreateDirectoryW(BufferName, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto cleanup;
- }
- }
-
- if (OwnerSid)
- {
- //DWORD rc;
-
- /* Add ACL to allow only user/SYSTEM to open it */
- /* FIXME: rc = SetNamedSecurityInfo(
- BufferName,
- SE_FILE_OBJECT,
- ???,
- OwnerSid,
- NULL,
- ???,
- ???);
- if (rc != ERROR_SUCCESS)
- {
- hr = HRESULT_FROM_WIN32(rc);
- goto cleanup;
- }
- */
- }
-
- wcscat(BufferName, L"\\");
- FileName = &BufferName[wcslen(BufferName)];
-
- /* Create desktop.ini */
- wcscpy(FileName, L"desktop.ini");
- hFile = CreateFileW(BufferName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN, NULL);
- if (hFile == INVALID_HANDLE_VALUE)
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto cleanup;
- }
- BytesToWrite = strlen(DesktopIniContents);
- if (!WriteFile(hFile, DesktopIniContents, (DWORD)BytesToWrite, &BytesWritten, NULL))
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto cleanup;
- }
- if (BytesWritten != BytesToWrite)
- {
- hr = E_FAIL;
- goto cleanup;
- }
- CloseHandle(hFile);
- hFile = INVALID_HANDLE_VALUE;
-
- /* Create empty INFO2 file */
- wcscpy(FileName, RECYCLE_BIN_FILE_NAME);
- hFile = CreateFileW(BufferName, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN, NULL);
- if (hFile == INVALID_HANDLE_VALUE)
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto cleanup;
- }
- BytesToWrite = sizeof(Info2Contents);
- if (!WriteFile(hFile, Info2Contents, (DWORD)BytesToWrite, &BytesWritten, NULL))
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto cleanup;
- }
- if (BytesWritten == BytesToWrite)
- hr = S_OK;
- else
- hr = E_FAIL;
+ LPWSTR BufferName = NULL;
+ LPWSTR Separator; /* Pointer into BufferName buffer */
+ LPWSTR FileName; /* Pointer into BufferName buffer */
+ LPCSTR DesktopIniContents = "[.ShellClassInfo]\r\nCLSID={645FF040-5081-101B-9F08-00AA002F954E}\r\n";
+ INFO2_HEADER Info2Contents[] = { { 5, 0, 0, 0x320, 0 } };
+ DWORD BytesToWrite, BytesWritten, Needed;
+ HANDLE hFile = INVALID_HANDLE_VALUE;
+ HRESULT hr;
+
+ Needed = (wcslen(Folder) + 1 + max(wcslen(RECYCLE_BIN_FILE_NAME), wcslen(L"desktop.ini")) + 1) * sizeof(WCHAR);
+ BufferName = HeapAlloc(GetProcessHeap(), 0, Needed);
+ if (!BufferName)
+ {
+ hr = ERROR_NOT_ENOUGH_MEMORY;
+ goto cleanup;
+ }
+
+ wcscpy(BufferName, Folder);
+ Separator = wcsstr(&BufferName[3], L"\\");
+ if (Separator)
+ *Separator = UNICODE_NULL;
+ if (!CreateDirectoryW(BufferName, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto cleanup;
+ }
+ SetFileAttributesW(BufferName, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
+ if (Separator)
+ {
+ *Separator = L'\\';
+ if (!CreateDirectoryW(BufferName, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto cleanup;
+ }
+ }
+
+ if (OwnerSid)
+ {
+ //DWORD rc;
+
+ /* Add ACL to allow only user/SYSTEM to open it */
+ /* FIXME: rc = SetNamedSecurityInfo(
+ BufferName,
+ SE_FILE_OBJECT,
+ ???,
+ OwnerSid,
+ NULL,
+ ???,
+ ???);
+ if (rc != ERROR_SUCCESS)
+ {
+ hr = HRESULT_FROM_WIN32(rc);
+ goto cleanup;
+ }
+ */
+ }
+
+ wcscat(BufferName, L"\\");
+ FileName = &BufferName[wcslen(BufferName)];
+
+ /* Create desktop.ini */
+ wcscpy(FileName, L"desktop.ini");
+ hFile = CreateFileW(BufferName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN, NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto cleanup;
+ }
+ BytesToWrite = strlen(DesktopIniContents);
+ if (!WriteFile(hFile, DesktopIniContents, (DWORD)BytesToWrite, &BytesWritten, NULL))
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto cleanup;
+ }
+ if (BytesWritten != BytesToWrite)
+ {
+ hr = E_FAIL;
+ goto cleanup;
+ }
+ CloseHandle(hFile);
+ hFile = INVALID_HANDLE_VALUE;
+
+ /* Create empty INFO2 file */
+ wcscpy(FileName, RECYCLE_BIN_FILE_NAME);
+ hFile = CreateFileW(BufferName, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN, NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto cleanup;
+ }
+ BytesToWrite = sizeof(Info2Contents);
+ if (!WriteFile(hFile, Info2Contents, (DWORD)BytesToWrite, &BytesWritten, NULL))
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto cleanup;
+ }
+ if (BytesWritten == BytesToWrite)
+ hr = S_OK;
+ else
+ hr = E_FAIL;
cleanup:
- HeapFree(GetProcessHeap(), 0, BufferName);
- if (hFile != INVALID_HANDLE_VALUE)
- CloseHandle(hFile);
- return hr;
+ HeapFree(GetProcessHeap(), 0, BufferName);
+ if (hFile != INVALID_HANDLE_VALUE)
+ CloseHandle(hFile);
+ return hr;
}
HRESULT RecycleBin5_Constructor(IN LPCWSTR VolumePath, OUT IUnknown **ppUnknown)
{
- struct RecycleBin5 *s = NULL;
- DWORD FileSystemFlags;
- LPCWSTR RecycleBinDirectory;
- HANDLE tokenHandle = INVALID_HANDLE_VALUE;
- PTOKEN_USER TokenUserInfo = NULL;
- LPWSTR StringSid = NULL, p;
- DWORD Needed, DirectoryLength;
- INT len;
- HRESULT hr;
-
- if (!ppUnknown)
- return E_POINTER;
-
- /* Get information about file system */
- if (!GetVolumeInformationW(
- VolumePath,
- NULL,
- 0,
- NULL,
- NULL,
- &FileSystemFlags,
- NULL,
- 0))
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto cleanup;
- }
- if (!(FileSystemFlags & FILE_PERSISTENT_ACLS))
- RecycleBinDirectory = RECYCLE_BIN_DIRECTORY_WITHOUT_ACL;
- else
- {
- RecycleBinDirectory = RECYCLE_BIN_DIRECTORY_WITH_ACL;
-
- /* Get user SID */
- if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &tokenHandle))
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto cleanup;
- }
- if (GetTokenInformation(tokenHandle, TokenUser, NULL, 0, &Needed))
- {
- hr = E_FAIL;
- goto cleanup;
- }
- if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto cleanup;
- }
- TokenUserInfo = HeapAlloc(GetProcessHeap(), 0, Needed);
- if (!TokenUserInfo)
- {
- hr = E_OUTOFMEMORY;
- goto cleanup;
- }
- if (!GetTokenInformation(tokenHandle, TokenUser, TokenUserInfo, (DWORD)Needed, &Needed))
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto cleanup;
- }
- if (!ConvertSidToStringSidW(TokenUserInfo->User.Sid, &StringSid))
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto cleanup;
- }
- }
-
- DirectoryLength = wcslen(VolumePath) + wcslen(RecycleBinDirectory) + 1;
- if (StringSid)
- DirectoryLength += wcslen(StringSid) + 1;
- DirectoryLength += 1 + wcslen(RECYCLE_BIN_FILE_NAME);
- DirectoryLength += wcslen(VolumePath) + 1;
- Needed = (DirectoryLength + 1) * sizeof(WCHAR);
-
- s = CoTaskMemAlloc(sizeof(struct RecycleBin5) + Needed);
- if (!s)
- {
- hr = E_OUTOFMEMORY;
- goto cleanup;
- }
- ZeroMemory(s, sizeof(struct RecycleBin5));
- s->recycleBinImpl.lpVtbl = &RecycleBin5Vtbl;
- s->ref = 1;
- if (StringSid)
- len = swprintf(s->Folder, L"%s%s\\%s", VolumePath, RecycleBinDirectory, StringSid);
- else
- len = swprintf(s->Folder, L"%s%s", VolumePath, RecycleBinDirectory);
- p = &s->Folder[len];
- wcscpy(p, L"\\" RECYCLE_BIN_FILE_NAME);
- s->hInfo = CreateFileW(s->Folder, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
- if (s->hInfo == INVALID_HANDLE_VALUE && (GetLastError() == ERROR_PATH_NOT_FOUND || GetLastError() == ERROR_FILE_NOT_FOUND))
- {
- *p = UNICODE_NULL;
- hr = RecycleBin5_Create(s->Folder, TokenUserInfo ? TokenUserInfo->User.Sid : NULL);
- *p = L'\\';
- if (!SUCCEEDED(hr))
- goto cleanup;
- s->hInfo = CreateFileW(s->Folder, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
- }
- if (s->hInfo == INVALID_HANDLE_VALUE)
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto cleanup;
- }
- s->hInfoMapped = CreateFileMappingW(s->hInfo, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 0, NULL);
- if (!s->hInfoMapped)
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto cleanup;
- }
- *p = UNICODE_NULL;
- s->VolumePath = p + 1;
- wcscpy(s->VolumePath, VolumePath);
-
- *ppUnknown = (IUnknown *)&s->recycleBinImpl;
-
- hr = S_OK;
+ struct RecycleBin5 *s = NULL;
+ DWORD FileSystemFlags;
+ LPCWSTR RecycleBinDirectory;
+ HANDLE tokenHandle = INVALID_HANDLE_VALUE;
+ PTOKEN_USER TokenUserInfo = NULL;
+ LPWSTR StringSid = NULL, p;
+ DWORD Needed, DirectoryLength;
+ INT len;
+ HRESULT hr;
+
+ if (!ppUnknown)
+ return E_POINTER;
+
+ /* Get information about file system */
+ if (!GetVolumeInformationW(
+ VolumePath,
+ NULL,
+ 0,
+ NULL,
+ NULL,
+ &FileSystemFlags,
+ NULL,
+ 0))
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto cleanup;
+ }
+ if (!(FileSystemFlags & FILE_PERSISTENT_ACLS))
+ RecycleBinDirectory = RECYCLE_BIN_DIRECTORY_WITHOUT_ACL;
+ else
+ {
+ RecycleBinDirectory = RECYCLE_BIN_DIRECTORY_WITH_ACL;
+
+ /* Get user SID */
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &tokenHandle))
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto cleanup;
+ }
+ if (GetTokenInformation(tokenHandle, TokenUser, NULL, 0, &Needed))
+ {
+ hr = E_FAIL;
+ goto cleanup;
+ }
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto cleanup;
+ }
+ TokenUserInfo = HeapAlloc(GetProcessHeap(), 0, Needed);
+ if (!TokenUserInfo)
+ {
+ hr = E_OUTOFMEMORY;
+ goto cleanup;
+ }
+ if (!GetTokenInformation(tokenHandle, TokenUser, TokenUserInfo, (DWORD)Needed, &Needed))
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto cleanup;
+ }
+ if (!ConvertSidToStringSidW(TokenUserInfo->User.Sid, &StringSid))
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto cleanup;
+ }
+ }
+
+ DirectoryLength = wcslen(VolumePath) + wcslen(RecycleBinDirectory) + 1;
+ if (StringSid)
+ DirectoryLength += wcslen(StringSid) + 1;
+ DirectoryLength += 1 + wcslen(RECYCLE_BIN_FILE_NAME);
+ DirectoryLength += wcslen(VolumePath) + 1;
+ Needed = (DirectoryLength + 1) * sizeof(WCHAR);
+
+ s = CoTaskMemAlloc(sizeof(struct RecycleBin5) + Needed);
+ if (!s)
+ {
+ hr = E_OUTOFMEMORY;
+ goto cleanup;
+ }
+ ZeroMemory(s, sizeof(struct RecycleBin5));
+ s->recycleBinImpl.lpVtbl = &RecycleBin5Vtbl;
+ s->ref = 1;
+ if (StringSid)
+ len = swprintf(s->Folder, L"%s%s\\%s", VolumePath, RecycleBinDirectory, StringSid);
+ else
+ len = swprintf(s->Folder, L"%s%s", VolumePath, RecycleBinDirectory);
+ p = &s->Folder[len];
+ wcscpy(p, L"\\" RECYCLE_BIN_FILE_NAME);
+ s->hInfo = CreateFileW(s->Folder, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
+ if (s->hInfo == INVALID_HANDLE_VALUE && (GetLastError() == ERROR_PATH_NOT_FOUND || GetLastError() == ERROR_FILE_NOT_FOUND))
+ {
+ *p = UNICODE_NULL;
+ hr = RecycleBin5_Create(s->Folder, TokenUserInfo ? TokenUserInfo->User.Sid : NULL);
+ *p = L'\\';
+ if (!SUCCEEDED(hr))
+ goto cleanup;
+ s->hInfo = CreateFileW(s->Folder, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
+ }
+ if (s->hInfo == INVALID_HANDLE_VALUE)
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto cleanup;
+ }
+ s->hInfoMapped = CreateFileMappingW(s->hInfo, NULL, PAGE_READWRITE | SEC_COMMIT, 0, 0, NULL);
+ if (!s->hInfoMapped)
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ goto cleanup;
+ }
+ *p = UNICODE_NULL;
+ s->VolumePath = p + 1;
+ wcscpy(s->VolumePath, VolumePath);
+
+ *ppUnknown = (IUnknown *)&s->recycleBinImpl;
+
+ hr = S_OK;
cleanup:
- if (tokenHandle != INVALID_HANDLE_VALUE)
- CloseHandle(tokenHandle);
- HeapFree(GetProcessHeap(), 0, TokenUserInfo);
- if (StringSid)
- LocalFree(StringSid);
- if (!SUCCEEDED(hr))
- {
- if (s)
- RecycleBin5_Destructor(s);
- }
- return hr;
+ if (tokenHandle != INVALID_HANDLE_VALUE)
+ CloseHandle(tokenHandle);
+ HeapFree(GetProcessHeap(), 0, TokenUserInfo);
+ if (StringSid)
+ LocalFree(StringSid);
+ if (!SUCCEEDED(hr))
+ {
+ if (s)
+ RecycleBin5_Destructor(s);
+ }
+ return hr;
}