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_generic_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_generic_enumerator.c
00005  * PURPOSE:     Enumerates contents of all recycle bins
00006  * PROGRAMMERS: Copyright 2007 Hervé Poussineau (hpoussin@reactos.org)
00007  */
00008 
00009 #define COBJMACROS
00010 #include "recyclebin_private.h"
00011 #include <stdio.h>
00012 
00013 WINE_DEFAULT_DEBUG_CHANNEL(recyclebin);
00014 
00015 struct RecycleBinGenericEnum
00016 {
00017     ULONG ref;
00018     IRecycleBinEnumList recycleBinEnumImpl;
00019     IRecycleBinEnumList *current;
00020     DWORD dwLogicalDrives;
00021     SIZE_T skip;
00022 };
00023 
00024 static HRESULT STDMETHODCALLTYPE
00025 RecycleBinGenericEnum_RecycleBinEnumList_QueryInterface(
00026     IN IRecycleBinEnumList *This,
00027     IN REFIID riid,
00028     OUT void **ppvObject)
00029 {
00030     struct RecycleBinGenericEnum *s = CONTAINING_RECORD(This, struct RecycleBinGenericEnum, recycleBinEnumImpl);
00031 
00032     TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppvObject);
00033 
00034     if (!ppvObject)
00035         return E_POINTER;
00036 
00037     if (IsEqualIID(riid, &IID_IUnknown))
00038         *ppvObject = &s->recycleBinEnumImpl;
00039     else if (IsEqualIID(riid, &IID_IRecycleBinEnumList))
00040         *ppvObject = &s->recycleBinEnumImpl;
00041     else
00042     {
00043         *ppvObject = NULL;
00044         return E_NOINTERFACE;
00045     }
00046 
00047     IUnknown_AddRef(This);
00048     return S_OK;
00049 }
00050 
00051 static ULONG STDMETHODCALLTYPE
00052 RecycleBinGenericEnum_RecycleBinEnumList_AddRef(
00053     IN IRecycleBinEnumList *This)
00054 {
00055     struct RecycleBinGenericEnum *s = CONTAINING_RECORD(This, struct RecycleBinGenericEnum, recycleBinEnumImpl);
00056     ULONG refCount = InterlockedIncrement((PLONG)&s->ref);
00057     TRACE("(%p)\n", This);
00058     return refCount;
00059 }
00060 
00061 static VOID
00062 RecycleBinGenericEnum_Destructor(
00063     struct RecycleBinGenericEnum *s)
00064 {
00065     TRACE("(%p)\n", s);
00066 
00067     if (s->current)
00068         IRecycleBinEnumList_Release(s->current);
00069     CoTaskMemFree(s);
00070 }
00071 
00072 static ULONG STDMETHODCALLTYPE
00073 RecycleBinGenericEnum_RecycleBinEnumList_Release(
00074     IN IRecycleBinEnumList *This)
00075 {
00076     struct RecycleBinGenericEnum *s = CONTAINING_RECORD(This, struct RecycleBinGenericEnum, recycleBinEnumImpl);
00077     ULONG refCount;
00078 
00079     TRACE("(%p)\n", This);
00080 
00081     refCount = InterlockedDecrement((PLONG)&s->ref);
00082 
00083     if (refCount == 0)
00084         RecycleBinGenericEnum_Destructor(s);
00085 
00086     return refCount;
00087 }
00088 
00089 static HRESULT STDMETHODCALLTYPE
00090 RecycleBinGenericEnum_RecycleBinEnumList_Next(
00091     IN IRecycleBinEnumList *This,
00092     IN DWORD celt,
00093     IN OUT IRecycleBinFile **rgelt,
00094     OUT DWORD *pceltFetched)
00095 {
00096     struct RecycleBinGenericEnum *s = CONTAINING_RECORD(This, struct RecycleBinGenericEnum, recycleBinEnumImpl);
00097     IRecycleBin *prb;
00098     DWORD i;
00099     DWORD fetched = 0, newFetched;
00100     HRESULT hr;
00101 
00102     TRACE("(%p, %u, %p, %p)\n", This, celt, rgelt, pceltFetched);
00103 
00104     if (!rgelt)
00105         return E_POINTER;
00106     if (!pceltFetched && celt > 1)
00107         return E_INVALIDARG;
00108 
00109     while (TRUE)
00110     {
00111         /* Get enumerator implementation */
00112         if (!s->current && s->dwLogicalDrives)
00113         {
00114             for (i = 0; i < 26; i++)
00115                 if (s->dwLogicalDrives & (1 << i))
00116                 {
00117                     WCHAR szVolumeName[4];
00118                     szVolumeName[0] = (WCHAR)('A' + i);
00119                     szVolumeName[1] = ':';
00120                     szVolumeName[2] = '\\';
00121                     szVolumeName[3] = UNICODE_NULL;
00122                     if (GetDriveTypeW(szVolumeName) != DRIVE_FIXED)
00123                     {
00124                         s->dwLogicalDrives &= ~(1 << i);
00125                         continue;
00126                     }
00127                     hr = GetDefaultRecycleBin(szVolumeName, &prb);
00128                     if (!SUCCEEDED(hr))
00129                         return hr;
00130                     hr = IRecycleBin_EnumObjects(prb, &s->current);
00131                     IRecycleBin_Release(prb);
00132                     if (!SUCCEEDED(hr))
00133                         return hr;
00134                     s->dwLogicalDrives &= ~(1 << i);
00135                     break;
00136                 }
00137         }
00138         if (!s->current)
00139         {
00140             /* Nothing more to enumerate */
00141             if (pceltFetched)
00142                 *pceltFetched = fetched;
00143             return S_FALSE;
00144         }
00145 
00146         /* Skip some elements */
00147         while (s->skip > 0)
00148         {
00149             IRecycleBinFile *rbf;
00150             hr = IRecycleBinEnumList_Next(s->current, 1, &rbf, NULL);
00151             if (hr == S_OK)
00152                 hr = IRecycleBinFile_Release(rbf);
00153             else if (hr == S_FALSE)
00154                 break;
00155             else if (!SUCCEEDED(hr))
00156                 return hr;
00157         }
00158         if (s->skip > 0)
00159             continue;
00160 
00161         /* Fill area */
00162         hr = IRecycleBinEnumList_Next(s->current, celt - fetched, &rgelt[fetched], &newFetched);
00163         if (SUCCEEDED(hr))
00164             fetched += newFetched;
00165         if (hr == S_FALSE || newFetched == 0)
00166         {
00167             hr = IRecycleBinEnumList_Release(s->current);
00168             s->current = NULL;
00169         }
00170         else if (!SUCCEEDED(hr))
00171             return hr;
00172         if (fetched == celt)
00173         {
00174             if (pceltFetched)
00175                 *pceltFetched = fetched;
00176             return S_OK;
00177         }
00178     }
00179 
00180     /* Never go here */
00181 }
00182 
00183 static HRESULT STDMETHODCALLTYPE
00184 RecycleBinGenericEnum_RecycleBinEnumList_Skip(
00185     IN IRecycleBinEnumList *This,
00186     IN DWORD celt)
00187 {
00188     struct RecycleBinGenericEnum *s = CONTAINING_RECORD(This, struct RecycleBinGenericEnum, recycleBinEnumImpl);
00189     TRACE("(%p, %u)\n", This, celt);
00190     s->skip += celt;
00191     return S_OK;
00192 }
00193 
00194 static HRESULT STDMETHODCALLTYPE
00195 RecycleBinGenericEnum_RecycleBinEnumList_Reset(
00196     IN IRecycleBinEnumList *This)
00197 {
00198     struct RecycleBinGenericEnum *s = CONTAINING_RECORD(This, struct RecycleBinGenericEnum, recycleBinEnumImpl);
00199 
00200     TRACE("(%p)\n", This);
00201 
00202     if (s->current)
00203     {
00204         IRecycleBinEnumList_Release(s->current);
00205         s->current = NULL;
00206         s->skip = 0;
00207     }
00208     s->dwLogicalDrives = GetLogicalDrives();
00209     return S_OK;
00210 }
00211 
00212 CONST_VTBL struct IRecycleBinEnumListVtbl RecycleBinGenericEnumVtbl =
00213 {
00214     RecycleBinGenericEnum_RecycleBinEnumList_QueryInterface,
00215     RecycleBinGenericEnum_RecycleBinEnumList_AddRef,
00216     RecycleBinGenericEnum_RecycleBinEnumList_Release,
00217     RecycleBinGenericEnum_RecycleBinEnumList_Next,
00218     RecycleBinGenericEnum_RecycleBinEnumList_Skip,
00219     RecycleBinGenericEnum_RecycleBinEnumList_Reset,
00220 };
00221 
00222 HRESULT
00223 RecycleBinGenericEnum_Constructor(
00224     OUT IRecycleBinEnumList **pprbel)
00225 {
00226     struct RecycleBinGenericEnum *s;
00227 
00228     s = CoTaskMemAlloc(sizeof(struct RecycleBinGenericEnum));
00229     if (!s)
00230         return E_OUTOFMEMORY;
00231     ZeroMemory(s, sizeof(struct RecycleBinGenericEnum));
00232     s->ref = 1;
00233     s->recycleBinEnumImpl.lpVtbl = &RecycleBinGenericEnumVtbl;
00234 
00235     *pprbel = &s->recycleBinEnumImpl;
00236     return IRecycleBinEnumList_Reset(*pprbel);
00237 }

Generated on Sat May 26 2012 04:35:16 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.