Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenrecyclebin_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
1.7.6.1
|