ReactOS  0.4.13-dev-259-g5ca9c9c
recyclebin_v5_enumerator.c
Go to the documentation of this file.
1 /*
2  * PROJECT: Recycle bin management
3  * LICENSE: GPL v2 - See COPYING in the top level directory
4  * FILE: lib/recyclebin/recyclebin_v5_enumerator.c
5  * PURPOSE: Enumerates contents of a MS Windows 2000/XP/2003 recyclebin
6  * PROGRAMMERS: Copyright 2006-2007 Hervé Poussineau (hpoussin@reactos.org)
7  */
8 
9 #include "recyclebin_private.h"
10 
12 {
16  IRecycleBinFile recycleBinFileImpl;
18 };
19 
22  IN IRecycleBinFile *This,
23  IN REFIID riid,
24  OUT void **ppvObject)
25 {
27 
28  TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObject);
29 
30  if (!ppvObject)
31  return E_POINTER;
32 
34  *ppvObject = &s->recycleBinFileImpl;
36  *ppvObject = &s->recycleBinFileImpl;
37  else
38  {
39  *ppvObject = NULL;
40  return E_NOINTERFACE;
41  }
42 
43  IUnknown_AddRef(This);
44  return S_OK;
45 }
46 
49  IN IRecycleBinFile *This)
50 {
52  ULONG refCount = InterlockedIncrement((PLONG)&s->ref);
53  TRACE("(%p)\n", This);
54  return refCount;
55 }
56 
57 static VOID
59  struct RecycleBin5File *s)
60 {
61  TRACE("(%p)\n", s);
62 
63  IRecycleBin5_Release(s->recycleBin);
65 }
66 
69  IN IRecycleBinFile *This)
70 {
72  ULONG refCount;
73 
74  TRACE("(%p)\n", This);
75 
76  refCount = InterlockedDecrement((PLONG)&s->ref);
77 
78  if (refCount == 0)
80 
81  return refCount;
82 }
83 
86  IN IRecycleBinFile *This,
87  OUT FILETIME *pLastModificationTime)
88 {
90  HRESULT hr;
92  HANDLE hFile;
93 
94  TRACE("(%p, %p)\n", This, pLastModificationTime);
95 
96  dwAttributes = GetFileAttributesW(s->FullName);
101  else
105 
106  if (GetFileTime(hFile, NULL, NULL, pLastModificationTime))
107  hr = S_OK;
108  else
111  return hr;
112 }
113 
116  IN IRecycleBinFile *This,
117  OUT FILETIME *pDeletionTime)
118 {
120  TRACE("(%p, %p)\n", This, pDeletionTime);
121  *pDeletionTime = s->deletedFile.DeletionTime;
122  return S_OK;
123 }
124 
127  IN IRecycleBinFile *This,
128  OUT ULARGE_INTEGER *pFileSize)
129 {
131  HRESULT hr;
133  HANDLE hFile;
134 
135  TRACE("(%p, %p)\n", This, pFileSize);
136 
137  dwAttributes = GetFileAttributesW(s->FullName);
141  {
142  pFileSize->QuadPart = 0;
143  return S_OK;
144  }
145 
149  pFileSize->u.LowPart = GetFileSize(hFile, &pFileSize->u.HighPart);
150  if (pFileSize->u.LowPart != INVALID_FILE_SIZE)
151  hr = S_OK;
152  else
155  return hr;
156 }
157 
160  IN IRecycleBinFile *This,
161  OUT ULARGE_INTEGER *pPhysicalFileSize)
162 {
164  TRACE("(%p, %p)\n", This, pPhysicalFileSize);
165  pPhysicalFileSize->u.HighPart = 0;
166  pPhysicalFileSize->u.LowPart = s->deletedFile.dwPhysicalFileSize;
167  return S_OK;
168 }
169 
172  IN IRecycleBinFile *This,
173  OUT DWORD *pAttributes)
174 {
177 
178  TRACE("(%p, %p)\n", This, pAttributes);
179 
180  dwAttributes = GetFileAttributesW(s->FullName);
183 
184  *pAttributes = dwAttributes;
185  return S_OK;
186 }
187 
190  IN IRecycleBinFile *This,
194 {
196  DWORD dwRequired;
197 
198  TRACE("(%p, %u, %p, %p)\n", This, BufferSize, Buffer, RequiredSize);
199 
200  dwRequired = (DWORD)(wcslen(s->deletedFile.FileNameW) + 1) * sizeof(WCHAR);
201  if (RequiredSize)
202  *RequiredSize = dwRequired;
203 
204  if (BufferSize == 0 && !Buffer)
205  return S_OK;
206 
207  if (BufferSize < dwRequired)
208  return E_OUTOFMEMORY;
209  CopyMemory(Buffer, s->deletedFile.FileNameW, dwRequired);
210  return S_OK;
211 }
212 
215  IN IRecycleBinFile *This)
216 {
218  TRACE("(%p)\n", This);
219  return IRecycleBin5_Delete(s->recycleBin, s->FullName, &s->deletedFile);
220 }
221 
224  IN IRecycleBinFile *This)
225 {
227  TRACE("(%p)\n", This);
228  return IRecycleBin5_Restore(s->recycleBin, s->FullName, &s->deletedFile);
229 }
230 
231 CONST_VTBL struct IRecycleBinFileVtbl RecycleBin5FileVtbl =
232 {
244 };
245 
246 static HRESULT
248  IN IRecycleBin5 *prb,
249  IN LPCWSTR Folder,
250  IN PDELETED_FILE_RECORD pDeletedFile,
251  OUT IRecycleBinFile **ppFile)
252 {
253  struct RecycleBin5File *s = NULL;
255  SIZE_T Needed;
256 
257  if (!ppFile)
258  return E_POINTER;
259 
260  Extension = wcsrchr(pDeletedFile->FileNameW, '.');
261  if (Extension < wcsrchr(pDeletedFile->FileNameW, '\\'))
262  Extension = NULL;
263  Needed = wcslen(Folder) + 13;
264  if (Extension)
265  Needed += wcslen(Extension);
266  Needed *= sizeof(WCHAR);
267 
268  s = CoTaskMemAlloc(sizeof(struct RecycleBin5File) + Needed);
269  if (!s)
270  return E_OUTOFMEMORY;
271  ZeroMemory(s, sizeof(struct RecycleBin5File) + Needed);
272  s->recycleBinFileImpl.lpVtbl = &RecycleBin5FileVtbl;
273  s->ref = 1;
274  s->deletedFile = *pDeletedFile;
275  s->recycleBin = prb;
276  IRecycleBin5_AddRef(s->recycleBin);
277  *ppFile = &s->recycleBinFileImpl;
278  wsprintfW(s->FullName, L"%s\\D%c%lu%s", Folder, pDeletedFile->dwDriveNumber + 'a', pDeletedFile->dwRecordUniqueId, Extension);
279  if (GetFileAttributesW(s->FullName) == INVALID_FILE_ATTRIBUTES)
280  {
282  return E_FAIL;
283  }
284 
285  return S_OK;
286 }
287 
289 {
295  IRecycleBinEnumList recycleBinEnumImpl;
297 };
298 
301  IN IRecycleBinEnumList *This,
302  IN REFIID riid,
303  OUT void **ppvObject)
304 {
306 
307  TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObject);
308 
309  if (!ppvObject)
310  return E_POINTER;
311 
313  *ppvObject = &s->recycleBinEnumImpl;
315  *ppvObject = &s->recycleBinEnumImpl;
316  else
317  {
318  *ppvObject = NULL;
319  return E_NOINTERFACE;
320  }
321 
322  IUnknown_AddRef(This);
323  return S_OK;
324 }
325 
328  IN IRecycleBinEnumList *This)
329 {
331  ULONG refCount = InterlockedIncrement((PLONG)&s->ref);
332  TRACE("(%p)\n", This);
333  return refCount;
334 }
335 
336 static VOID
338  struct RecycleBin5Enum *s)
339 {
340  TRACE("(%p)\n", s);
341 
342  IRecycleBin5_OnClosing(s->recycleBin, &s->recycleBinEnumImpl);
343  UnmapViewOfFile(s->pInfo);
344  IRecycleBin5_Release(s->recycleBin);
345  CoTaskMemFree(s);
346 }
347 
350  IN IRecycleBinEnumList *This)
351 {
353  ULONG refCount;
354 
355  TRACE("(%p)\n", This);
356 
357  refCount = InterlockedDecrement((PLONG)&s->ref);
358 
359  if (refCount == 0)
361 
362  return refCount;
363 }
364 
367  IRecycleBinEnumList *This,
368  IN DWORD celt,
369  IN OUT IRecycleBinFile **rgelt,
370  OUT DWORD *pceltFetched)
371 {
374  INFO2_HEADER *pHeader = s->pInfo;
375  DELETED_FILE_RECORD *pDeletedFile;
376  DWORD fetched = 0, i;
377  DWORD dwEntries;
378  HRESULT hr;
379 
380  TRACE("(%p, %u, %p, %p)\n", This, celt, rgelt, pceltFetched);
381 
382  if (!rgelt)
383  return E_POINTER;
384  if (!pceltFetched && celt > 1)
385  return E_INVALIDARG;
386 
387  FileSize.u.LowPart = GetFileSize(s->hInfo, &FileSize.u.HighPart);
388  if (FileSize.u.LowPart == 0)
390  dwEntries = (DWORD)((FileSize.QuadPart - sizeof(INFO2_HEADER)) / sizeof(DELETED_FILE_RECORD));
391 
392  i = s->dwCurrent;
393  pDeletedFile = (DELETED_FILE_RECORD *)(pHeader + 1) + i;
394  for (; i < dwEntries && fetched < celt; i++)
395  {
396  hr = RecycleBin5File_Constructor(s->recycleBin, s->szPrefix, pDeletedFile, &rgelt[fetched]);
397  if (SUCCEEDED(hr))
398  fetched++;
399  pDeletedFile++;
400  }
401 
402  s->dwCurrent = i;
403  if (pceltFetched)
404  *pceltFetched = fetched;
405  if (fetched == celt)
406  return S_OK;
407  else
408  return S_FALSE;
409 }
410 
413  IN IRecycleBinEnumList *This,
414  IN DWORD celt)
415 {
417  TRACE("(%p, %u)\n", This, celt);
418  s->dwCurrent += celt;
419  return S_OK;
420 }
421 
424  IN IRecycleBinEnumList *This)
425 {
427  TRACE("(%p)\n", This);
428  s->dwCurrent = 0;
429  return S_OK;
430 }
431 
432 CONST_VTBL struct IRecycleBinEnumListVtbl RecycleBin5EnumVtbl =
433 {
440 };
441 
442 HRESULT
444  IN IRecycleBin5 *prb,
445  IN HANDLE hInfo,
446  IN HANDLE hInfoMapped,
447  IN LPCWSTR szPrefix,
448  OUT IUnknown **ppUnknown)
449 {
450  struct RecycleBin5Enum *s = NULL;
451  SIZE_T Needed;
452 
453  if (!ppUnknown)
454  return E_POINTER;
455 
456  Needed = (wcslen(szPrefix) + 1) * sizeof(WCHAR);
457 
458  s = CoTaskMemAlloc(sizeof(struct RecycleBin5Enum) + Needed);
459  if (!s)
460  return E_OUTOFMEMORY;
461  ZeroMemory(s, sizeof(struct RecycleBin5Enum) + Needed);
462  s->recycleBinEnumImpl.lpVtbl = &RecycleBin5EnumVtbl;
463  s->ref = 1;
464  s->recycleBin = prb;
465  wcscpy(s->szPrefix, szPrefix);
466  s->hInfo = hInfo;
467  s->pInfo = MapViewOfFile(hInfoMapped, FILE_MAP_READ, 0, 0, 0);
468  if (!s->pInfo)
469  {
470  CoTaskMemFree(s);
472  }
473  if (s->pInfo->dwVersion != 5 || s->pInfo->dwRecordSize != sizeof(DELETED_FILE_RECORD))
474  {
475  UnmapViewOfFile(s->pInfo);
476  CoTaskMemFree(s);
477  return E_FAIL;
478  }
479  IRecycleBin5_AddRef(s->recycleBin);
480  *ppUnknown = (IUnknown *)&s->recycleBinEnumImpl;
481 
482  return S_OK;
483 }
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
static ULONG STDMETHODCALLTYPE RecycleBin5File_RecycleBinFile_Release(IN IRecycleBinFile *This)
#define IN
Definition: typedefs.h:38
#define REFIID
Definition: guiddef.h:113
CONST_VTBL struct IRecycleBinEnumListVtbl RecycleBin5EnumVtbl
#define CloseHandle
Definition: compat.h:398
#define E_NOINTERFACE
Definition: winerror.h:2364
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:422
#define MapViewOfFile
Definition: compat.h:402
HRESULT hr
Definition: shlfolder.c:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
REFIID riid
Definition: precomp.h:44
EXTERN_C const IID IID_IRecycleBinEnumList
Definition: recyclebin.h:248
static ULONG STDMETHODCALLTYPE RecycleBin5Enum_RecycleBinEnumList_AddRef(IN IRecycleBinEnumList *This)
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1635
static ULONG STDMETHODCALLTYPE RecycleBin5File_RecycleBinFile_AddRef(IN IRecycleBinFile *This)
EXTERN_C const IID IID_IRecycleBinFile
Definition: recyclebin.h:245
#define INVALID_FILE_SIZE
Definition: winbase.h:529
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define E_FAIL
Definition: ddrawi.h:102
#define DWORD
Definition: nt_native.h:44
DWORD dwAttributes
Definition: vdmdbg.h:34
IRecycleBinEnumList recycleBinEnumImpl
#define FILE_SHARE_READ
Definition: compat.h:125
struct _DELETED_FILE_RECORD DELETED_FILE_RECORD
static HRESULT STDMETHODCALLTYPE RecycleBin5Enum_RecycleBinEnumList_Reset(IN IRecycleBinEnumList *This)
WCHAR FullName[ANY_SIZE]
static HRESULT STDMETHODCALLTYPE RecycleBin5File_RecycleBinFile_GetPhysicalFileSize(IN IRecycleBinFile *This, OUT ULARGE_INTEGER *pPhysicalFileSize)
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define CONST_VTBL
Definition: objbase.h:222
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:802
static HRESULT STDMETHODCALLTYPE RecycleBin5Enum_RecycleBinEnumList_Next(IRecycleBinEnumList *This, IN DWORD celt, IN OUT IRecycleBinFile **rgelt, OUT DWORD *pceltFetched)
#define S_FALSE
Definition: winerror.h:2357
static HRESULT STDMETHODCALLTYPE RecycleBin5File_RecycleBinFile_Restore(IN IRecycleBinFile *This)
#define E_INVALIDARG
Definition: ddrawi.h:101
smooth NULL
Definition: ftsmooth.c:416
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcsrchr(_In_z_ const wchar_t *_Str, _In_ wchar_t _Ch)
Definition: bufpool.h:45
#define FILE_MAP_READ
Definition: compat.h:427
#define debugstr_guid
Definition: kernel32.h:35
#define OPEN_EXISTING
Definition: compat.h:426
_Inout_ PRTL_BUFFER _In_ SIZE_T RequiredSize
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
static HRESULT STDMETHODCALLTYPE RecycleBin5File_RecycleBinFile_GetLastModificationTime(IN IRecycleBinFile *This, OUT FILETIME *pLastModificationTime)
#define TRACE(s)
Definition: solgame.cpp:4
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
static HRESULT STDMETHODCALLTYPE RecycleBin5File_RecycleBinFile_GetFileName(IN IRecycleBinFile *This, IN SIZE_T BufferSize, IN OUT LPWSTR Buffer, OUT SIZE_T *RequiredSize)
const GUID IID_IUnknown
#define CopyMemory
Definition: winbase.h:1633
static HRESULT RecycleBin5File_Constructor(IN IRecycleBin5 *prb, IN LPCWSTR Folder, IN PDELETED_FILE_RECORD pDeletedFile, OUT IRecycleBinFile **ppFile)
#define STDMETHODCALLTYPE
Definition: bdasup.h:9
#define BufferSize
Definition: classpnp.h:419
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:481
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
IRecycleBinFile recycleBinFileImpl
HRESULT RecycleBin5Enum_Constructor(IN IRecycleBin5 *prb, IN HANDLE hInfo, IN HANDLE hInfoMapped, IN LPCWSTR szPrefix, OUT IUnknown **ppUnknown)
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
static const WCHAR L[]
Definition: oid.c:1250
#define InterlockedDecrement
Definition: armddk.h:52
interface IRecycleBin5 IRecycleBin5
Definition: recyclebin_v5.h:27
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
static HRESULT STDMETHODCALLTYPE RecycleBin5File_RecycleBinFile_QueryInterface(IN IRecycleBinFile *This, IN REFIID riid, OUT void **ppvObject)
GLdouble s
Definition: gl.h:2039
REFIID LPVOID * ppvObject
Definition: precomp.h:44
#define GENERIC_READ
Definition: compat.h:124
_In_ HANDLE hFile
Definition: mswsock.h:90
static VOID RecycleBin5File_Destructor(struct RecycleBin5File *s)
static HRESULT STDMETHODCALLTYPE RecycleBin5File_RecycleBinFile_GetAttributes(IN IRecycleBinFile *This, OUT DWORD *pAttributes)
ULONG_PTR SIZE_T
Definition: typedefs.h:78
static HRESULT STDMETHODCALLTYPE RecycleBin5File_RecycleBinFile_GetFileSize(IN IRecycleBinFile *This, OUT ULARGE_INTEGER *pFileSize)
#define S_OK
Definition: intsafe.h:59
#define InterlockedIncrement
Definition: armddk.h:53
static VOID RecycleBin5Enum_Destructor(struct RecycleBin5Enum *s)
static HRESULT STDMETHODCALLTYPE RecycleBin5File_RecycleBinFile_Delete(IN IRecycleBinFile *This)
static HRESULT STDMETHODCALLTYPE RecycleBin5File_RecycleBinFile_GetDeletionTime(IN IRecycleBinFile *This, OUT FILETIME *pDeletionTime)
static HRESULT STDMETHODCALLTYPE RecycleBin5Enum_RecycleBinEnumList_Skip(IN IRecycleBinEnumList *This, IN DWORD celt)
#define ANY_SIZE
Definition: recyclebin.h:20
#define CreateFileW
Definition: compat.h:400
static ULONG STDMETHODCALLTYPE RecycleBin5Enum_RecycleBinEnumList_Release(IN IRecycleBinEnumList *This)
struct _LARGE_INTEGER::@2192 u
#define FILE_FLAG_BACKUP_SEMANTICS
Definition: disk.h:41
#define OUT
Definition: typedefs.h:39
CONST_VTBL struct IRecycleBinFileVtbl RecycleBin5FileVtbl
unsigned int ULONG
Definition: retypes.h:1
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define E_POINTER
Definition: winerror.h:2365
#define UnmapViewOfFile
Definition: compat.h:403
signed int * PLONG
Definition: retypes.h:5
DELETED_FILE_RECORD deletedFile
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:406
BOOL WINAPI GetFileTime(IN HANDLE hFile, OUT LPFILETIME lpCreationTime OPTIONAL, OUT LPFILETIME lpLastAccessTime OPTIONAL, OUT LPFILETIME lpLastWriteTime OPTIONAL)
Definition: fileinfo.c:1046
_Inout_opt_ PUNICODE_STRING Extension
Definition: fltkernel.h:1092
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:90
#define SUCCEEDED(hr)
Definition: intsafe.h:57
LONGLONG QuadPart
Definition: typedefs.h:112
static HRESULT STDMETHODCALLTYPE RecycleBin5Enum_RecycleBinEnumList_QueryInterface(IN IRecycleBinEnumList *This, IN REFIID riid, OUT void **ppvObject)