[ros-diffs] [hpoussin] 30811: Better compatibility with MS Windows recycle bin Add traces

hpoussin at svn.reactos.org hpoussin at svn.reactos.org
Tue Nov 27 09:22:17 CET 2007


Author: hpoussin
Date: Tue Nov 27 11:22:16 2007
New Revision: 30811

URL: http://svn.reactos.org/svn/reactos?rev=30811&view=rev
Log:
Better compatibility with MS Windows recycle bin
Add traces

Modified:
    trunk/reactos/lib/recyclebin/readme.txt
    trunk/reactos/lib/recyclebin/recyclebin.c
    trunk/reactos/lib/recyclebin/recyclebin_generic.c
    trunk/reactos/lib/recyclebin/recyclebin_generic_enumerator.c
    trunk/reactos/lib/recyclebin/recyclebin_private.h
    trunk/reactos/lib/recyclebin/recyclebin_v5.c
    trunk/reactos/lib/recyclebin/recyclebin_v5.h
    trunk/reactos/lib/recyclebin/recyclebin_v5_enumerator.c

Modified: trunk/reactos/lib/recyclebin/readme.txt
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/recyclebin/readme.txt?rev=30811&r1=30810&r2=30811&view=diff
==============================================================================
--- trunk/reactos/lib/recyclebin/readme.txt (original)
+++ trunk/reactos/lib/recyclebin/readme.txt Tue Nov 27 11:22:16 2007
@@ -4,7 +4,6 @@
 TODO
 - Empty a recycle bin containing directories (v5)
 - Set security on recycle bin folder
-- Delete files > 4Gb
 - Make the library thread-safe
 
 3 levels

Modified: trunk/reactos/lib/recyclebin/recyclebin.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/recyclebin/recyclebin.c?rev=30811&r1=30810&r2=30811&view=diff
==============================================================================
--- trunk/reactos/lib/recyclebin/recyclebin.c (original)
+++ trunk/reactos/lib/recyclebin/recyclebin.c Tue Nov 27 11:22:16 2007
@@ -10,12 +10,16 @@
 #include "recyclebin_private.h"
 #include <stdio.h>
 
+WINE_DEFAULT_DEBUG_CHANNEL(recyclebin);
+
 BOOL WINAPI
 CloseRecycleBinHandle(
 	IN HANDLE hDeletedFile)
 {
 	IRecycleBinFile *rbf = (IRecycleBinFile *)hDeletedFile;
 	HRESULT hr;
+
+	TRACE("(%p)\n", hDeletedFile);
 
 	hr = IRecycleBinFile_Release(rbf);
 	if (SUCCEEDED(hr))
@@ -35,6 +39,8 @@
 	LPWSTR FileNameW = NULL;
 	BOOL ret = FALSE;
 
+	TRACE("(%s)\n", debugstr_a(FileName));
+
 	/* Check parameters */
 	if (FileName == NULL)
 	{
@@ -67,6 +73,8 @@
 {
 	IRecycleBin *prb;
 	HRESULT hr;
+
+	TRACE("(%s)\n", debugstr_w(FileName));
 
 	hr = GetDefaultRecycleBin(NULL, &prb);
 	if (!SUCCEEDED(hr))
@@ -93,6 +101,8 @@
 	LPWSTR szRootW = NULL;
 	BOOL ret = FALSE;
 
+	TRACE("(%s)\n", debugstr_a(pszRoot));
+
 	if (pszRoot)
 	{
 		len = MultiByteToWideChar(CP_ACP, 0, pszRoot, -1, NULL, 0);
@@ -121,6 +131,8 @@
 {
 	IRecycleBin *prb;
 	HRESULT hr;
+
+	TRACE("(%s)\n", debugstr_w(pszRoot));
 
 	hr = GetDefaultRecycleBin(pszRoot, &prb);
 	if (!SUCCEEDED(hr))
@@ -149,6 +161,8 @@
 	LPWSTR szRootW = NULL;
 	BOOL ret = FALSE;
 
+	TRACE("(%s, %p, %p)\n", debugstr_a(pszRoot), pFnCallback, Context);
+
 	if (pszRoot)
 	{
 		len = MultiByteToWideChar(CP_ACP, 0, pszRoot, -1, NULL, 0);
@@ -181,6 +195,8 @@
 	IRecycleBinEnumList *prbel = NULL;
 	IRecycleBinFile *prbf;
 	HRESULT hr;
+
+	TRACE("(%s, %p, %p)\n", debugstr_w(pszRoot), pFnCallback, Context);
 
 	hr = GetDefaultRecycleBin(NULL, &prb);
 	if (!SUCCEEDED(hr))
@@ -231,6 +247,8 @@
 	DWORD BufferSizeW = 0;
 	BOOL ret = FALSE;
 
+	TRACE("(%p, %lu, %p, %p)\n", hDeletedFile, BufferSize, FileDetails, RequiredSize);
+
 	if (BufferSize >= FIELD_OFFSET(DELETED_FILE_DETAILS_A, FileName))
 	{
 		BufferSizeW = FIELD_OFFSET(DELETED_FILE_DETAILS_W, FileName)
@@ -274,6 +292,8 @@
 	HRESULT hr;
 	SIZE_T NameSize, Needed;
 
+	TRACE("(%p, %lu, %p, %p)\n", hDeletedFile, BufferSize, FileDetails, RequiredSize);
+
 	hr = IRecycleBinFile_GetFileName(rbf, 0, NULL, &NameSize);
 	if (!SUCCEEDED(hr))
 		goto cleanup;
@@ -321,6 +341,8 @@
 	IRecycleBinFile *rbf = (IRecycleBinFile *)hDeletedFile;
 	HRESULT hr;
 
+	TRACE("(%p)\n", hDeletedFile);
+
 	hr = IRecycleBinFile_Restore(rbf);
 	if (SUCCEEDED(hr))
 		return TRUE;
@@ -339,6 +361,8 @@
 	IUnknown *pUnk;
 	HRESULT hr;
 
+	TRACE("(%s, %p)\n", debugstr_w(pszVolume), pprb);
+
 	if (!pprb)
 		return E_POINTER;
 

Modified: trunk/reactos/lib/recyclebin/recyclebin_generic.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/recyclebin/recyclebin_generic.c?rev=30811&r1=30810&r2=30811&view=diff
==============================================================================
--- trunk/reactos/lib/recyclebin/recyclebin_generic.c (original)
+++ trunk/reactos/lib/recyclebin/recyclebin_generic.c Tue Nov 27 11:22:16 2007
@@ -19,7 +19,7 @@
 };
 
 static HRESULT STDMETHODCALLTYPE
-RecycleBinGenericVtbl_RecycleBin_QueryInterface( 
+RecycleBinGeneric_RecycleBin_QueryInterface(
 	IRecycleBin *This,
 	REFIID riid,
 	void **ppvObject)
@@ -46,7 +46,7 @@
 }
 
 static ULONG STDMETHODCALLTYPE
-RecycleBinGenericVtbl_RecycleBin_AddRef(
+RecycleBinGeneric_RecycleBin_AddRef(
 	IRecycleBin *This)
 {
 	struct RecycleBinGeneric *s = CONTAINING_RECORD(This, struct RecycleBinGeneric, recycleBinImpl);
@@ -55,8 +55,17 @@
 	return refCount;
 }
 
+static VOID
+RecycleBinGeneric_Destructor(
+	struct RecycleBinGeneric *s)
+{
+	TRACE("(%p)\n", s);
+
+	CoTaskMemFree(s);
+}
+
 static ULONG STDMETHODCALLTYPE
-RecycleBinGenericVtbl_RecycleBin_Release(
+RecycleBinGeneric_RecycleBin_Release(
 	IRecycleBin *This)
 {
 	struct RecycleBinGeneric *s = CONTAINING_RECORD(This, struct RecycleBinGeneric, recycleBinImpl);
@@ -67,13 +76,13 @@
 	refCount = InterlockedDecrement((PLONG)&s->ref);
 
 	if (refCount == 0)
-		CoTaskMemFree(s);
+		RecycleBinGeneric_Destructor(s);
 
 	return refCount;
 }
 
 static HRESULT STDMETHODCALLTYPE
-RecycleBinGenericVtbl_RecycleBin_DeleteFile(
+RecycleBinGeneric_RecycleBin_DeleteFile(
 	IN IRecycleBin *This,
 	IN LPCWSTR szFileName)
 {
@@ -140,7 +149,7 @@
 }
 
 static HRESULT STDMETHODCALLTYPE
-RecycleBinGenericVtbl_RecycleBin_EmptyRecycleBin(
+RecycleBinGeneric_RecycleBin_EmptyRecycleBin(
 	IN IRecycleBin *This)
 {
 	WCHAR szVolumeName[MAX_PATH];
@@ -161,7 +170,7 @@
 		swprintf(szVolumeName, L"%c:\\", 'A' + i);
 		if (GetDriveTypeW(szVolumeName) != DRIVE_FIXED)
 			continue;
-		
+
 		hr = GetDefaultRecycleBin(szVolumeName, &prb);
 		if (!SUCCEEDED(hr))
 			return hr;
@@ -174,22 +183,22 @@
 }
 
 static HRESULT STDMETHODCALLTYPE
-RecycleBinGenericVtbl_RecycleBin_EnumObjects(
+RecycleBinGeneric_RecycleBin_EnumObjects(
 	IN IRecycleBin *This,
 	OUT IRecycleBinEnumList **ppEnumList)
 {
 	TRACE("(%p, %p)\n", This, ppEnumList);
-	return RecycleBinGeneric_Enumerator_Constructor(ppEnumList);
+	return RecycleBinGenericEnum_Constructor(ppEnumList);
 }
 
 CONST_VTBL struct IRecycleBinVtbl RecycleBinGenericVtbl =
 {
-	RecycleBinGenericVtbl_RecycleBin_QueryInterface,
-	RecycleBinGenericVtbl_RecycleBin_AddRef,
-	RecycleBinGenericVtbl_RecycleBin_Release,
-	RecycleBinGenericVtbl_RecycleBin_DeleteFile,
-	RecycleBinGenericVtbl_RecycleBin_EmptyRecycleBin,
-	RecycleBinGenericVtbl_RecycleBin_EnumObjects,
+	RecycleBinGeneric_RecycleBin_QueryInterface,
+	RecycleBinGeneric_RecycleBin_AddRef,
+	RecycleBinGeneric_RecycleBin_Release,
+	RecycleBinGeneric_RecycleBin_DeleteFile,
+	RecycleBinGeneric_RecycleBin_EmptyRecycleBin,
+	RecycleBinGeneric_RecycleBin_EnumObjects,
 };
 
 HRESULT RecycleBinGeneric_Constructor(OUT IUnknown **ppUnknown)

Modified: trunk/reactos/lib/recyclebin/recyclebin_generic_enumerator.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/recyclebin/recyclebin_generic_enumerator.c?rev=30811&r1=30810&r2=30811&view=diff
==============================================================================
--- trunk/reactos/lib/recyclebin/recyclebin_generic_enumerator.c (original)
+++ trunk/reactos/lib/recyclebin/recyclebin_generic_enumerator.c Tue Nov 27 11:22:16 2007
@@ -58,6 +58,17 @@
 	return refCount;
 }
 
+static VOID
+RecycleBinGenericEnum_Destructor(
+	struct RecycleBinGenericEnum *s)
+{
+	TRACE("(%p)\n", s);
+
+	if (s->current)
+		IRecycleBinEnumList_Release(s->current);
+	CoTaskMemFree(s);
+}
+
 static ULONG STDMETHODCALLTYPE
 RecycleBinGenericEnum_RecycleBinEnumList_Release(
 	IN IRecycleBinEnumList *This)
@@ -70,11 +81,7 @@
 	refCount = InterlockedDecrement((PLONG)&s->ref);
 
 	if (refCount == 0)
-	{
-		if (s->current)
-			IRecycleBinEnumList_Release(s->current);
-		CoTaskMemFree(s);
-	}
+		RecycleBinGenericEnum_Destructor(s);
 
 	return refCount;
 }
@@ -213,7 +220,7 @@
 };
 
 HRESULT
-RecycleBinGeneric_Enumerator_Constructor(
+RecycleBinGenericEnum_Constructor(
 	OUT IRecycleBinEnumList **pprbel)
 {
 	struct RecycleBinGenericEnum *s;

Modified: trunk/reactos/lib/recyclebin/recyclebin_private.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/recyclebin/recyclebin_private.h?rev=30811&r1=30810&r2=30811&view=diff
==============================================================================
--- trunk/reactos/lib/recyclebin/recyclebin_private.h (original)
+++ trunk/reactos/lib/recyclebin/recyclebin_private.h Tue Nov 27 11:22:16 2007
@@ -3,21 +3,12 @@
 #include <wine/debug.h>
 
 /* Defines */
-#define RECYCLEBIN_MAGIC  0x6e694252
-#define DELETEDFILE_MAGIC 0x6e694253
 
 #define RECYCLE_BIN_DIRECTORY_WITH_ACL    L"RECYCLER"
 #define RECYCLE_BIN_DIRECTORY_WITHOUT_ACL L"RECYCLED"
 #define RECYCLE_BIN_FILE_NAME             L"INFO2"
 
 #define ROUND_UP(N, S) ((( (N) + (S)  - 1) / (S) ) * (S) )
-
-/* List manipulation */
-#define InitializeListHead(le)  (void)((le)->Flink = (le)->Blink = (le))
-#define InsertTailList(le,e)    do { PLIST_ENTRY b = (le)->Blink; (e)->Flink = (le); (e)->Blink = b; b->Flink = (e); (le)->Blink = (e); } while (0)
-#define RemoveEntryList(Entry)  { PLIST_ENTRY _EX_Blink, _EX_Flink; _EX_Flink = (Entry)->Flink; _EX_Blink = (Entry)->Blink; _EX_Blink->Flink = _EX_Flink; _EX_Flink->Blink = _EX_Blink; }
-
-/* Typedefs */
 
 /* Structures on disk */
 
@@ -26,8 +17,8 @@
 typedef struct _INFO2_HEADER
 {
 	DWORD dwVersion;
-	DWORD dwNumberOfEntries;
-	DWORD dwHighestRecordUniqueId;
+	DWORD dwNumberOfEntries; /* unused */
+	DWORD dwHighestRecordUniqueId; /* unused */
 	DWORD dwRecordSize;
 	DWORD dwTotalLogicalSize;
 } INFO2_HEADER, *PINFO2_HEADER;
@@ -42,7 +33,7 @@
 
 /* recyclebin_generic_enumerator.c */
 
-HRESULT RecycleBinGeneric_Enumerator_Constructor(OUT IRecycleBinEnumList **pprbel);
+HRESULT RecycleBinGenericEnum_Constructor(OUT IRecycleBinEnumList **pprbel);
 
 /* recyclebin_v5.c */
 

Modified: trunk/reactos/lib/recyclebin/recyclebin_v5.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/recyclebin/recyclebin_v5.c?rev=30811&r1=30810&r2=30811&view=diff
==============================================================================
--- trunk/reactos/lib/recyclebin/recyclebin_v5.c (original)
+++ trunk/reactos/lib/recyclebin/recyclebin_v5.c Tue Nov 27 11:22:16 2007
@@ -67,7 +67,7 @@
 };
 
 static HRESULT STDMETHODCALLTYPE
-RecycleBin5_RecycleBin5_QueryInterface( 
+RecycleBin5_RecycleBin5_QueryInterface(
 	IRecycleBin5 *This,
 	REFIID riid,
 	void **ppvObject)
@@ -105,6 +105,19 @@
 	return refCount;
 }
 
+static VOID
+RecycleBin5_Destructor(
+	struct RecycleBin5 *s)
+{
+	TRACE("(%p)\n", 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)
@@ -117,11 +130,7 @@
 	refCount = InterlockedDecrement((PLONG)&s->ref);
 
 	if (refCount == 0)
-	{
-		CloseHandle(s->hInfo);
-		CloseHandle(s->hInfoMapped);
-		CoTaskMemFree(s);
-	}
+		RecycleBin5_Destructor(s);
 
 	return refCount;
 }
@@ -141,8 +150,8 @@
 	HANDLE hFile = INVALID_HANDLE_VALUE;
 	PINFO2_HEADER pHeader = NULL;
 	PDELETED_FILE_RECORD pDeletedFile;
-	ULARGE_INTEGER fileSize;
-	DWORD dwAttributes;
+	ULARGE_INTEGER FileSize;
+	DWORD dwAttributes, dwEntries;
 	SYSTEMTIME SystemTime;
 	DWORD ClusterSize, BytesPerSector, SectorsPerCluster;
 	HRESULT hr;
@@ -209,37 +218,51 @@
 		hr = HRESULT_FROM_WIN32(GetLastError());
 		goto cleanup;
 	}
-	pDeletedFile = ((PDELETED_FILE_RECORD)(pHeader + 1)) + pHeader->dwNumberOfEntries;
+
+	/* Get number of entries */
+	FileSize.u.LowPart = GetFileSize(s->hInfo, &FileSize.u.HighPart);
+	if (FileSize.u.LowPart < sizeof(INFO2_HEADER))
+	{
+		UnmapViewOfFile(pHeader);
+		return HRESULT_FROM_WIN32(GetLastError());
+	}
+	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))
+	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)
+	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)
-	{
-		/* FIXME: how to delete files >= 4Gb? */
-		hr = E_NOTIMPL;
-		goto cleanup;
-	}
-	pHeader->dwTotalLogicalSize += fileSize.u.LowPart;
+	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 */
-	pHeader->dwHighestRecordUniqueId++;
 	Extension = wcsrchr(szFullName, '.');
 	ZeroMemory(pDeletedFile, sizeof(DELETED_FILE_RECORD));
-	pDeletedFile->dwRecordUniqueId = pHeader->dwHighestRecordUniqueId;
+	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);
 
@@ -258,7 +281,7 @@
 		hr = HRESULT_FROM_WIN32(GetLastError());
 		goto cleanup;
 	}
-	pDeletedFile->dwPhysicalFileSize = ROUND_UP(fileSize.u.LowPart, ClusterSize);
+	pDeletedFile->dwPhysicalFileSize = ROUND_UP(FileSize.u.LowPart, ClusterSize);
 
 	/* Set name */
 	wcscpy(pDeletedFile->FileNameW, szFullName);
@@ -268,7 +291,6 @@
 		SetLastError(ERROR_INVALID_NAME);
 		goto cleanup;
 	}
-	pHeader->dwNumberOfEntries++;
 
 	/* Move file */
 	if (MoveFileW(szFullName, DeletedFileName))
@@ -323,7 +345,7 @@
 
 	TRACE("(%p, %p)\n", This, ppEnumList);
 
-	hr = RecycleBin5_Enumerator_Constructor(This, s->hInfo, s->hInfoMapped, s->Folder, &pUnk);
+	hr = RecycleBin5Enum_Constructor(This, s->hInfo, s->hInfoMapped, s->Folder, &pUnk);
 	if (!SUCCEEDED(hr))
 		return hr;
 
@@ -353,7 +375,7 @@
 
 	if (s->EnumeratorCount != 0)
 		return E_FAIL;
-	
+
 	pHeader = MapViewOfFile(s->hInfoMapped, FILE_MAP_WRITE, 0, 0, 0);
 	if (!pHeader)
 		return HRESULT_FROM_WIN32(GetLastError());
@@ -729,13 +751,7 @@
 	if (!SUCCEEDED(hr))
 	{
 		if (s)
-		{
-			if (s->hInfo && s->hInfo != INVALID_HANDLE_VALUE)
-				CloseHandle(s->hInfo);
-			if (s->hInfoMapped)
-				CloseHandle(s->hInfoMapped);
-			CoTaskMemFree(s);
-		}
+			RecycleBin5_Destructor(s);
 	}
 	return hr;
 }

Modified: trunk/reactos/lib/recyclebin/recyclebin_v5.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/recyclebin/recyclebin_v5.h?rev=30811&r1=30810&r2=30811&view=diff
==============================================================================
--- trunk/reactos/lib/recyclebin/recyclebin_v5.h (original)
+++ trunk/reactos/lib/recyclebin/recyclebin_v5.h Tue Nov 27 11:22:16 2007
@@ -97,7 +97,7 @@
 #endif
 
 HRESULT
-RecycleBin5_Enumerator_Constructor(
+RecycleBin5Enum_Constructor(
 	IN IRecycleBin5 *prb,
 	IN HANDLE hInfo,
 	IN HANDLE hInfoMapped,

Modified: trunk/reactos/lib/recyclebin/recyclebin_v5_enumerator.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/recyclebin/recyclebin_v5_enumerator.c?rev=30811&r1=30810&r2=30811&view=diff
==============================================================================
--- trunk/reactos/lib/recyclebin/recyclebin_v5_enumerator.c (original)
+++ trunk/reactos/lib/recyclebin/recyclebin_v5_enumerator.c Tue Nov 27 11:22:16 2007
@@ -57,6 +57,16 @@
 	return refCount;
 }
 
+static VOID
+RecycleBin5File_Destructor(
+	struct RecycleBin5File *s)
+{
+	TRACE("(%p)\n", s);
+
+	IRecycleBin5_Release(s->recycleBin);
+	CoTaskMemFree(s);
+}
+
 static ULONG STDMETHODCALLTYPE
 RecycleBin5File_RecycleBinFile_Release(
 	IN IRecycleBinFile *This)
@@ -69,10 +79,7 @@
 	refCount = InterlockedDecrement((PLONG)&s->ref);
 
 	if (refCount == 0)
-	{
-		IRecycleBin5_Release(s->recycleBin);
-		CoTaskMemFree(s);
-	}
+		RecycleBin5File_Destructor(s);
 
 	return refCount;
 }
@@ -240,7 +247,7 @@
 };
 
 static HRESULT
-RecycleBin5_File_Constructor(
+RecycleBin5File_Constructor(
 	IN IRecycleBin5 *prb,
 	IN LPCWSTR Folder,
 	IN PDELETED_FILE_RECORD pDeletedFile,
@@ -272,6 +279,11 @@
 	IRecycleBin5_AddRef(s->recycleBin);
 	*ppFile = &s->recycleBinFileImpl;
 	wsprintfW(s->FullName, L"%s\\D%c%lu%s", Folder, pDeletedFile->dwDriveNumber + 'a', pDeletedFile->dwRecordUniqueId, Extension);
+	if (GetFileAttributesW(s->FullName) == INVALID_FILE_ATTRIBUTES)
+	{
+		RecycleBin5File_Destructor(s);
+		return E_FAIL;
+	}
 
 	return S_OK;
 }
@@ -324,6 +336,18 @@
 	return refCount;
 }
 
+static VOID
+RecycleBin5Enum_Destructor(
+	struct RecycleBin5Enum *s)
+{
+	TRACE("(%p)\n", s);
+
+	IRecycleBin5_OnClosing(s->recycleBin, &s->recycleBinEnumImpl);
+	UnmapViewOfFile(s->pInfo);
+	IRecycleBin5_Release(s->recycleBin);
+	CoTaskMemFree(s);
+}
+
 static ULONG STDMETHODCALLTYPE
 RecycleBin5Enum_RecycleBinEnumList_Release(
 	IN IRecycleBinEnumList *This)
@@ -336,12 +360,7 @@
 	refCount = InterlockedDecrement((PLONG)&s->ref);
 
 	if (refCount == 0)
-	{
-		IRecycleBin5_OnClosing(s->recycleBin, This);
-		UnmapViewOfFile(s->pInfo);
-		IRecycleBin5_Release(s->recycleBin);
-		CoTaskMemFree(s);
-	}
+		RecycleBin5Enum_Destructor(s);
 
 	return refCount;
 }
@@ -377,15 +396,10 @@
 	pDeletedFile = (DELETED_FILE_RECORD *)(pHeader + 1) + i;
 	for (; i < dwEntries && fetched < celt; i++)
 	{
-		hr = RecycleBin5_File_Constructor(s->recycleBin, s->szPrefix, pDeletedFile, &rgelt[fetched]);
-		if (!SUCCEEDED(hr))
-		{
-			for (i = 0; i < fetched; i++)
-				IRecycleBinFile_Release(rgelt[i]);
-			return hr;
-		}
+		hr = RecycleBin5File_Constructor(s->recycleBin, s->szPrefix, pDeletedFile, &rgelt[fetched]);
+		if (SUCCEEDED(hr))
+			fetched++;
 		pDeletedFile++;
-		fetched++;
 	}
 
 	s->dwCurrent = i;
@@ -429,7 +443,7 @@
 };
 
 HRESULT
-RecycleBin5_Enumerator_Constructor(
+RecycleBin5Enum_Constructor(
 	IN IRecycleBin5 *prb,
 	IN HANDLE hInfo,
 	IN HANDLE hInfoMapped,




More information about the Ros-diffs mailing list