ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

recyclebin_v5_enumerator.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:     Recycle bin management
00003  * LICENSE:     GPL v2 - See COPYING in the top level directory
00004  * FILE:        lib/recyclebin/recyclebin_v5_enumerator.c
00005  * PURPOSE:     Enumerates contents of a MS Windows 2000/XP/2003 recyclebin
00006  * PROGRAMMERS: Copyright 2006-2007 Hervé Poussineau (hpoussin@reactos.org)
00007  */
00008 
00009 #define COBJMACROS
00010 #include "recyclebin_v5.h"
00011 
00012 WINE_DEFAULT_DEBUG_CHANNEL(recyclebin);
00013 
00014 struct RecycleBin5File
00015 {
00016     ULONG ref;
00017     IRecycleBin5 *recycleBin;
00018     DELETED_FILE_RECORD deletedFile;
00019     IRecycleBinFile recycleBinFileImpl;
00020     WCHAR FullName[ANY_SIZE];
00021 };
00022 
00023 static HRESULT STDMETHODCALLTYPE
00024 RecycleBin5File_RecycleBinFile_QueryInterface(
00025     IN IRecycleBinFile *This,
00026     IN REFIID riid,
00027     OUT void **ppvObject)
00028 {
00029     struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl);
00030 
00031     TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObject);
00032 
00033     if (!ppvObject)
00034         return E_POINTER;
00035 
00036     if (IsEqualIID(riid, &IID_IUnknown))
00037         *ppvObject = &s->recycleBinFileImpl;
00038     else if (IsEqualIID(riid, &IID_IRecycleBinFile))
00039         *ppvObject = &s->recycleBinFileImpl;
00040     else
00041     {
00042         *ppvObject = NULL;
00043         return E_NOINTERFACE;
00044     }
00045 
00046     IUnknown_AddRef(This);
00047     return S_OK;
00048 }
00049 
00050 static ULONG STDMETHODCALLTYPE
00051 RecycleBin5File_RecycleBinFile_AddRef(
00052     IN IRecycleBinFile *This)
00053 {
00054     struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl);
00055     ULONG refCount = InterlockedIncrement((PLONG)&s->ref);
00056     TRACE("(%p)\n", This);
00057     return refCount;
00058 }
00059 
00060 static VOID
00061 RecycleBin5File_Destructor(
00062     struct RecycleBin5File *s)
00063 {
00064     TRACE("(%p)\n", s);
00065 
00066     IRecycleBin5_Release(s->recycleBin);
00067     CoTaskMemFree(s);
00068 }
00069 
00070 static ULONG STDMETHODCALLTYPE
00071 RecycleBin5File_RecycleBinFile_Release(
00072     IN IRecycleBinFile *This)
00073 {
00074     struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl);
00075     ULONG refCount;
00076 
00077     TRACE("(%p)\n", This);
00078 
00079     refCount = InterlockedDecrement((PLONG)&s->ref);
00080 
00081     if (refCount == 0)
00082         RecycleBin5File_Destructor(s);
00083 
00084     return refCount;
00085 }
00086 
00087 static HRESULT STDMETHODCALLTYPE
00088 RecycleBin5File_RecycleBinFile_GetLastModificationTime(
00089     IN IRecycleBinFile *This,
00090     OUT FILETIME *pLastModificationTime)
00091 {
00092     struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl);
00093     HRESULT hr;
00094     DWORD dwAttributes;
00095     HANDLE hFile;
00096 
00097     TRACE("(%p, %p)\n", This, pLastModificationTime);
00098 
00099     dwAttributes = GetFileAttributesW(s->FullName);
00100     if (dwAttributes == INVALID_FILE_ATTRIBUTES)
00101         return HRESULT_FROM_WIN32(GetLastError());
00102     if (dwAttributes & FILE_ATTRIBUTE_DIRECTORY)
00103         hFile = CreateFileW(s->FullName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
00104     else
00105         hFile = CreateFileW(s->FullName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
00106     if (hFile == INVALID_HANDLE_VALUE)
00107         return HRESULT_FROM_WIN32(GetLastError());
00108 
00109     if (GetFileTime(hFile, NULL, NULL, pLastModificationTime))
00110         hr = S_OK;
00111     else
00112         hr = HRESULT_FROM_WIN32(GetLastError());
00113     CloseHandle(hFile);
00114     return hr;
00115 }
00116 
00117 static HRESULT STDMETHODCALLTYPE
00118 RecycleBin5File_RecycleBinFile_GetDeletionTime(
00119     IN IRecycleBinFile *This,
00120     OUT FILETIME *pDeletionTime)
00121 {
00122     struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl);
00123     TRACE("(%p, %p)\n", This, pDeletionTime);
00124     *pDeletionTime = s->deletedFile.DeletionTime;
00125     return S_OK;
00126 }
00127 
00128 static HRESULT STDMETHODCALLTYPE
00129 RecycleBin5File_RecycleBinFile_GetFileSize(
00130     IN IRecycleBinFile *This,
00131     OUT ULARGE_INTEGER *pFileSize)
00132 {
00133     struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl);
00134     HRESULT hr;
00135     DWORD dwAttributes;
00136     HANDLE hFile;
00137 
00138     TRACE("(%p, %p)\n", This, pFileSize);
00139 
00140     dwAttributes = GetFileAttributesW(s->FullName);
00141     if (dwAttributes == INVALID_FILE_ATTRIBUTES)
00142         return HRESULT_FROM_WIN32(GetLastError());
00143     if (dwAttributes & FILE_ATTRIBUTE_DIRECTORY)
00144     {
00145         pFileSize->QuadPart = 0;
00146         return S_OK;
00147     }
00148 
00149     hFile = CreateFileW(s->FullName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
00150     if (hFile == INVALID_HANDLE_VALUE)
00151         return HRESULT_FROM_WIN32(GetLastError());
00152     pFileSize->u.LowPart = GetFileSize(hFile, &pFileSize->u.HighPart);
00153     if (pFileSize->u.LowPart != INVALID_FILE_SIZE)
00154         hr = S_OK;
00155     else
00156         hr = HRESULT_FROM_WIN32(GetLastError());
00157     CloseHandle(hFile);
00158     return hr;
00159 }
00160 
00161 static HRESULT STDMETHODCALLTYPE
00162 RecycleBin5File_RecycleBinFile_GetPhysicalFileSize(
00163     IN IRecycleBinFile *This,
00164     OUT ULARGE_INTEGER *pPhysicalFileSize)
00165 {
00166     struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl);
00167     TRACE("(%p, %p)\n", This, pPhysicalFileSize);
00168     pPhysicalFileSize->u.HighPart = 0;
00169     pPhysicalFileSize->u.LowPart = s->deletedFile.dwPhysicalFileSize;
00170     return S_OK;
00171 }
00172 
00173 static HRESULT STDMETHODCALLTYPE
00174 RecycleBin5File_RecycleBinFile_GetAttributes(
00175     IN IRecycleBinFile *This,
00176     OUT DWORD *pAttributes)
00177 {
00178     struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl);
00179     DWORD dwAttributes;
00180 
00181     TRACE("(%p, %p)\n", This, pAttributes);
00182 
00183     dwAttributes = GetFileAttributesW(s->FullName);
00184     if (dwAttributes == INVALID_FILE_ATTRIBUTES)
00185         return HRESULT_FROM_WIN32(GetLastError());
00186 
00187     *pAttributes = dwAttributes;
00188     return S_OK;
00189 }
00190 
00191 static HRESULT STDMETHODCALLTYPE
00192 RecycleBin5File_RecycleBinFile_GetFileName(
00193     IN IRecycleBinFile *This,
00194     IN SIZE_T BufferSize,
00195     IN OUT LPWSTR Buffer,
00196     OUT SIZE_T *RequiredSize)
00197 {
00198     struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl);
00199     DWORD dwRequired;
00200 
00201     TRACE("(%p, %u, %p, %p)\n", This, BufferSize, Buffer, RequiredSize);
00202 
00203     dwRequired = (DWORD)(wcslen(s->deletedFile.FileNameW) + 1) * sizeof(WCHAR);
00204     if (RequiredSize)
00205         *RequiredSize = dwRequired;
00206 
00207     if (BufferSize == 0 && !Buffer)
00208         return S_OK;
00209 
00210     if (BufferSize < dwRequired)
00211         return E_OUTOFMEMORY;
00212     CopyMemory(Buffer, s->deletedFile.FileNameW, dwRequired);
00213     return S_OK;
00214 }
00215 
00216 static HRESULT STDMETHODCALLTYPE
00217 RecycleBin5File_RecycleBinFile_Delete(
00218     IN IRecycleBinFile *This)
00219 {
00220     struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl);
00221     TRACE("(%p)\n", This);
00222     return IRecycleBin5_Delete(s->recycleBin, s->FullName, &s->deletedFile);
00223 }
00224 
00225 static HRESULT STDMETHODCALLTYPE
00226 RecycleBin5File_RecycleBinFile_Restore(
00227     IN IRecycleBinFile *This)
00228 {
00229     struct RecycleBin5File *s = CONTAINING_RECORD(This, struct RecycleBin5File, recycleBinFileImpl);
00230     TRACE("(%p)\n", This);
00231     return IRecycleBin5_Restore(s->recycleBin, s->FullName, &s->deletedFile);
00232 }
00233 
00234 CONST_VTBL struct IRecycleBinFileVtbl RecycleBin5FileVtbl =
00235 {
00236     RecycleBin5File_RecycleBinFile_QueryInterface,
00237     RecycleBin5File_RecycleBinFile_AddRef,
00238     RecycleBin5File_RecycleBinFile_Release,
00239     RecycleBin5File_RecycleBinFile_GetLastModificationTime,
00240     RecycleBin5File_RecycleBinFile_GetDeletionTime,
00241     RecycleBin5File_RecycleBinFile_GetFileSize,
00242     RecycleBin5File_RecycleBinFile_GetPhysicalFileSize,
00243     RecycleBin5File_RecycleBinFile_GetAttributes,
00244     RecycleBin5File_RecycleBinFile_GetFileName,
00245     RecycleBin5File_RecycleBinFile_Delete,
00246     RecycleBin5File_RecycleBinFile_Restore,
00247 };
00248 
00249 static HRESULT
00250 RecycleBin5File_Constructor(
00251     IN IRecycleBin5 *prb,
00252     IN LPCWSTR Folder,
00253     IN PDELETED_FILE_RECORD pDeletedFile,
00254     OUT IRecycleBinFile **ppFile)
00255 {
00256     struct RecycleBin5File *s = NULL;
00257     LPCWSTR Extension;
00258     SIZE_T Needed;
00259 
00260     if (!ppFile)
00261         return E_POINTER;
00262 
00263     Extension = wcsrchr(pDeletedFile->FileNameW, '.');
00264     if (Extension < wcsrchr(pDeletedFile->FileNameW, '\\'))
00265         Extension = NULL;
00266     Needed = wcslen(Folder) + 13;
00267     if (Extension)
00268         Needed += wcslen(Extension);
00269     Needed *= sizeof(WCHAR);
00270 
00271     s = CoTaskMemAlloc(sizeof(struct RecycleBin5File) + Needed);
00272     if (!s)
00273         return E_OUTOFMEMORY;
00274     ZeroMemory(s, sizeof(struct RecycleBin5File) + Needed);
00275     s->recycleBinFileImpl.lpVtbl = &RecycleBin5FileVtbl;
00276     s->ref = 1;
00277     s->deletedFile = *pDeletedFile;
00278     s->recycleBin = prb;
00279     IRecycleBin5_AddRef(s->recycleBin);
00280     *ppFile = &s->recycleBinFileImpl;
00281     wsprintfW(s->FullName, L"%s\\D%c%lu%s", Folder, pDeletedFile->dwDriveNumber + 'a', pDeletedFile->dwRecordUniqueId, Extension);
00282     if (GetFileAttributesW(s->FullName) == INVALID_FILE_ATTRIBUTES)
00283     {
00284         RecycleBin5File_Destructor(s);
00285         return E_FAIL;
00286     }
00287 
00288     return S_OK;
00289 }
00290 
00291 struct RecycleBin5Enum
00292 {
00293     ULONG ref;
00294     IRecycleBin5 *recycleBin;
00295     HANDLE hInfo;
00296     INFO2_HEADER *pInfo;
00297     DWORD dwCurrent;
00298     IRecycleBinEnumList recycleBinEnumImpl;
00299     WCHAR szPrefix[ANY_SIZE];
00300 };
00301 
00302 static HRESULT STDMETHODCALLTYPE
00303 RecycleBin5Enum_RecycleBinEnumList_QueryInterface(
00304     IN IRecycleBinEnumList *This,
00305     IN REFIID riid,
00306     OUT void **ppvObject)
00307 {
00308     struct RecycleBin5Enum *s = CONTAINING_RECORD(This, struct RecycleBin5Enum, recycleBinEnumImpl);
00309 
00310     TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObject);
00311 
00312     if (!ppvObject)
00313         return E_POINTER;
00314 
00315     if (IsEqualIID(riid, &IID_IUnknown))
00316         *ppvObject = &s->recycleBinEnumImpl;
00317     else if (IsEqualIID(riid, &IID_IRecycleBinEnumList))
00318         *ppvObject = &s->recycleBinEnumImpl;
00319     else
00320     {
00321         *ppvObject = NULL;
00322         return E_NOINTERFACE;
00323     }
00324 
00325     IUnknown_AddRef(This);
00326     return S_OK;
00327 }
00328 
00329 static ULONG STDMETHODCALLTYPE
00330 RecycleBin5Enum_RecycleBinEnumList_AddRef(
00331     IN IRecycleBinEnumList *This)
00332 {
00333     struct RecycleBin5Enum *s = CONTAINING_RECORD(This, struct RecycleBin5Enum, recycleBinEnumImpl);
00334     ULONG refCount = InterlockedIncrement((PLONG)&s->ref);
00335     TRACE("(%p)\n", This);
00336     return refCount;
00337 }
00338 
00339 static VOID
00340 RecycleBin5Enum_Destructor(
00341     struct RecycleBin5Enum *s)
00342 {
00343     TRACE("(%p)\n", s);
00344 
00345     IRecycleBin5_OnClosing(s->recycleBin, &s->recycleBinEnumImpl);
00346     UnmapViewOfFile(s->pInfo);
00347     IRecycleBin5_Release(s->recycleBin);
00348     CoTaskMemFree(s);
00349 }
00350 
00351 static ULONG STDMETHODCALLTYPE
00352 RecycleBin5Enum_RecycleBinEnumList_Release(
00353     IN IRecycleBinEnumList *This)
00354 {
00355     struct RecycleBin5Enum *s = CONTAINING_RECORD(This, struct RecycleBin5Enum, recycleBinEnumImpl);
00356     ULONG refCount;
00357 
00358     TRACE("(%p)\n", This);
00359 
00360     refCount = InterlockedDecrement((PLONG)&s->ref);
00361 
00362     if (refCount == 0)
00363         RecycleBin5Enum_Destructor(s);
00364 
00365     return refCount;
00366 }
00367 
00368 static HRESULT STDMETHODCALLTYPE
00369 RecycleBin5Enum_RecycleBinEnumList_Next(
00370     IRecycleBinEnumList *This,
00371     IN DWORD celt,
00372     IN OUT IRecycleBinFile **rgelt,
00373     OUT DWORD *pceltFetched)
00374 {
00375     struct RecycleBin5Enum *s = CONTAINING_RECORD(This, struct RecycleBin5Enum, recycleBinEnumImpl);
00376     ULARGE_INTEGER FileSize;
00377     INFO2_HEADER *pHeader = s->pInfo;
00378     DELETED_FILE_RECORD *pDeletedFile;
00379     DWORD fetched = 0, i;
00380     DWORD dwEntries;
00381     HRESULT hr;
00382 
00383     TRACE("(%p, %u, %p, %p)\n", This, celt, rgelt, pceltFetched);
00384 
00385     if (!rgelt)
00386         return E_POINTER;
00387     if (!pceltFetched && celt > 1)
00388         return E_INVALIDARG;
00389 
00390     FileSize.u.LowPart = GetFileSize(s->hInfo, &FileSize.u.HighPart);
00391     if (FileSize.u.LowPart == 0)
00392         return HRESULT_FROM_WIN32(GetLastError());
00393     dwEntries = (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD));
00394 
00395     i = s->dwCurrent;
00396     pDeletedFile = (DELETED_FILE_RECORD *)(pHeader + 1) + i;
00397     for (; i < dwEntries && fetched < celt; i++)
00398     {
00399         hr = RecycleBin5File_Constructor(s->recycleBin, s->szPrefix, pDeletedFile, &rgelt[fetched]);
00400         if (SUCCEEDED(hr))
00401             fetched++;
00402         pDeletedFile++;
00403     }
00404 
00405     s->dwCurrent = i;
00406     if (pceltFetched)
00407         *pceltFetched = fetched;
00408     if (fetched == celt)
00409         return S_OK;
00410     else
00411         return S_FALSE;
00412 }
00413 
00414 static HRESULT STDMETHODCALLTYPE
00415 RecycleBin5Enum_RecycleBinEnumList_Skip(
00416     IN IRecycleBinEnumList *This,
00417     IN DWORD celt)
00418 {
00419     struct RecycleBin5Enum *s = CONTAINING_RECORD(This, struct RecycleBin5Enum, recycleBinEnumImpl);
00420     TRACE("(%p, %u)\n", This, celt);
00421     s->dwCurrent += celt;
00422     return S_OK;
00423 }
00424 
00425 static HRESULT STDMETHODCALLTYPE
00426 RecycleBin5Enum_RecycleBinEnumList_Reset(
00427     IN IRecycleBinEnumList *This)
00428 {
00429     struct RecycleBin5Enum *s = CONTAINING_RECORD(This, struct RecycleBin5Enum, recycleBinEnumImpl);
00430     TRACE("(%p)\n", This);
00431     s->dwCurrent = 0;
00432     return S_OK;
00433 }
00434 
00435 CONST_VTBL struct IRecycleBinEnumListVtbl RecycleBin5EnumVtbl =
00436 {
00437     RecycleBin5Enum_RecycleBinEnumList_QueryInterface,
00438     RecycleBin5Enum_RecycleBinEnumList_AddRef,
00439     RecycleBin5Enum_RecycleBinEnumList_Release,
00440     RecycleBin5Enum_RecycleBinEnumList_Next,
00441     RecycleBin5Enum_RecycleBinEnumList_Skip,
00442     RecycleBin5Enum_RecycleBinEnumList_Reset,
00443 };
00444 
00445 HRESULT
00446 RecycleBin5Enum_Constructor(
00447     IN IRecycleBin5 *prb,
00448     IN HANDLE hInfo,
00449     IN HANDLE hInfoMapped,
00450     IN LPCWSTR szPrefix,
00451     OUT IUnknown **ppUnknown)
00452 {
00453     struct RecycleBin5Enum *s = NULL;
00454     SIZE_T Needed;
00455 
00456     if (!ppUnknown)
00457         return E_POINTER;
00458 
00459     Needed = (wcslen(szPrefix) + 1) * sizeof(WCHAR);
00460 
00461     s = CoTaskMemAlloc(sizeof(struct RecycleBin5Enum) + Needed);
00462     if (!s)
00463         return E_OUTOFMEMORY;
00464     ZeroMemory(s, sizeof(struct RecycleBin5Enum) + Needed);
00465     s->recycleBinEnumImpl.lpVtbl = &RecycleBin5EnumVtbl;
00466     s->ref = 1;
00467     s->recycleBin = prb;
00468     wcscpy(s->szPrefix, szPrefix);
00469     s->hInfo = hInfo;
00470     s->pInfo = MapViewOfFile(hInfoMapped, FILE_MAP_READ, 0, 0, 0);
00471     if (!s->pInfo)
00472     {
00473         CoTaskMemFree(s);
00474         return HRESULT_FROM_WIN32(GetLastError());
00475     }
00476     if (s->pInfo->dwVersion != 5 || s->pInfo->dwRecordSize != sizeof(DELETED_FILE_RECORD))
00477     {
00478         UnmapViewOfFile(s->pInfo);
00479         CoTaskMemFree(s);
00480         return E_FAIL;
00481     }
00482     IRecycleBin5_AddRef(s->recycleBin);
00483     *ppUnknown = (IUnknown *)&s->recycleBinEnumImpl;
00484 
00485     return S_OK;
00486 }

Generated on Mon May 28 2012 04:36:10 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.