2 * PROJECT: Recycle bin management
3 * LICENSE: GPL v2 - See COPYING in the top level directory
4 * FILE: lib/recyclebin/recyclebin_generic_enumerator.c
5 * PURPOSE: Enumerates contents of all recycle bins
6 * PROGRAMMERS: Copyright 2007 Hervé Poussineau (hpoussin@reactos.org)
9 #include "recyclebin_private.h"
11 struct RecycleBinGenericEnum
14 IRecycleBinEnumList recycleBinEnumImpl
;
15 IRecycleBinEnumList
*current
;
16 DWORD dwLogicalDrives
;
20 static HRESULT STDMETHODCALLTYPE
21 RecycleBinGenericEnum_RecycleBinEnumList_QueryInterface(
22 IN IRecycleBinEnumList
*This
,
26 struct RecycleBinGenericEnum
*s
= CONTAINING_RECORD(This
, struct RecycleBinGenericEnum
, recycleBinEnumImpl
);
28 TRACE("(%p, %s, %p)\n", This
, debugstr_guid(riid
), ppvObject
);
33 if (IsEqualIID(riid
, &IID_IUnknown
))
34 *ppvObject
= &s
->recycleBinEnumImpl
;
35 else if (IsEqualIID(riid
, &IID_IRecycleBinEnumList
))
36 *ppvObject
= &s
->recycleBinEnumImpl
;
43 IUnknown_AddRef(This
);
47 static ULONG STDMETHODCALLTYPE
48 RecycleBinGenericEnum_RecycleBinEnumList_AddRef(
49 IN IRecycleBinEnumList
*This
)
51 struct RecycleBinGenericEnum
*s
= CONTAINING_RECORD(This
, struct RecycleBinGenericEnum
, recycleBinEnumImpl
);
52 ULONG refCount
= InterlockedIncrement((PLONG
)&s
->ref
);
53 TRACE("(%p)\n", This
);
58 RecycleBinGenericEnum_Destructor(
59 struct RecycleBinGenericEnum
*s
)
64 IRecycleBinEnumList_Release(s
->current
);
68 static ULONG STDMETHODCALLTYPE
69 RecycleBinGenericEnum_RecycleBinEnumList_Release(
70 IN IRecycleBinEnumList
*This
)
72 struct RecycleBinGenericEnum
*s
= CONTAINING_RECORD(This
, struct RecycleBinGenericEnum
, recycleBinEnumImpl
);
75 TRACE("(%p)\n", This
);
77 refCount
= InterlockedDecrement((PLONG
)&s
->ref
);
80 RecycleBinGenericEnum_Destructor(s
);
85 static HRESULT STDMETHODCALLTYPE
86 RecycleBinGenericEnum_RecycleBinEnumList_Next(
87 IN IRecycleBinEnumList
*This
,
89 IN OUT IRecycleBinFile
**rgelt
,
90 OUT DWORD
*pceltFetched
)
92 struct RecycleBinGenericEnum
*s
= CONTAINING_RECORD(This
, struct RecycleBinGenericEnum
, recycleBinEnumImpl
);
95 DWORD fetched
= 0, newFetched
;
98 TRACE("(%p, %u, %p, %p)\n", This
, celt
, rgelt
, pceltFetched
);
102 if (!pceltFetched
&& celt
> 1)
107 /* Get enumerator implementation */
108 if (!s
->current
&& s
->dwLogicalDrives
)
110 for (i
= 0; i
< 26; i
++)
111 if (s
->dwLogicalDrives
& (1 << i
))
113 WCHAR szVolumeName
[4];
114 szVolumeName
[0] = (WCHAR
)('A' + i
);
115 szVolumeName
[1] = ':';
116 szVolumeName
[2] = '\\';
117 szVolumeName
[3] = UNICODE_NULL
;
118 if (GetDriveTypeW(szVolumeName
) != DRIVE_FIXED
)
120 s
->dwLogicalDrives
&= ~(1 << i
);
123 hr
= GetDefaultRecycleBin(szVolumeName
, &prb
);
126 hr
= IRecycleBin_EnumObjects(prb
, &s
->current
);
127 IRecycleBin_Release(prb
);
130 s
->dwLogicalDrives
&= ~(1 << i
);
136 /* Nothing more to enumerate */
138 *pceltFetched
= fetched
;
142 /* Skip some elements */
145 IRecycleBinFile
*rbf
;
146 hr
= IRecycleBinEnumList_Next(s
->current
, 1, &rbf
, NULL
);
148 hr
= IRecycleBinFile_Release(rbf
);
149 else if (hr
== S_FALSE
)
151 else if (!SUCCEEDED(hr
))
158 hr
= IRecycleBinEnumList_Next(s
->current
, celt
- fetched
, &rgelt
[fetched
], &newFetched
);
160 fetched
+= newFetched
;
161 if (hr
== S_FALSE
|| newFetched
== 0)
163 hr
= IRecycleBinEnumList_Release(s
->current
);
166 else if (!SUCCEEDED(hr
))
171 *pceltFetched
= fetched
;
179 static HRESULT STDMETHODCALLTYPE
180 RecycleBinGenericEnum_RecycleBinEnumList_Skip(
181 IN IRecycleBinEnumList
*This
,
184 struct RecycleBinGenericEnum
*s
= CONTAINING_RECORD(This
, struct RecycleBinGenericEnum
, recycleBinEnumImpl
);
185 TRACE("(%p, %u)\n", This
, celt
);
190 static HRESULT STDMETHODCALLTYPE
191 RecycleBinGenericEnum_RecycleBinEnumList_Reset(
192 IN IRecycleBinEnumList
*This
)
194 struct RecycleBinGenericEnum
*s
= CONTAINING_RECORD(This
, struct RecycleBinGenericEnum
, recycleBinEnumImpl
);
196 TRACE("(%p)\n", This
);
200 IRecycleBinEnumList_Release(s
->current
);
204 s
->dwLogicalDrives
= GetLogicalDrives();
208 CONST_VTBL
struct IRecycleBinEnumListVtbl RecycleBinGenericEnumVtbl
=
210 RecycleBinGenericEnum_RecycleBinEnumList_QueryInterface
,
211 RecycleBinGenericEnum_RecycleBinEnumList_AddRef
,
212 RecycleBinGenericEnum_RecycleBinEnumList_Release
,
213 RecycleBinGenericEnum_RecycleBinEnumList_Next
,
214 RecycleBinGenericEnum_RecycleBinEnumList_Skip
,
215 RecycleBinGenericEnum_RecycleBinEnumList_Reset
,
219 RecycleBinGenericEnum_Constructor(
220 OUT IRecycleBinEnumList
**pprbel
)
222 struct RecycleBinGenericEnum
*s
;
224 s
= CoTaskMemAlloc(sizeof(struct RecycleBinGenericEnum
));
226 return E_OUTOFMEMORY
;
227 ZeroMemory(s
, sizeof(struct RecycleBinGenericEnum
));
229 s
->recycleBinEnumImpl
.lpVtbl
= &RecycleBinGenericEnumVtbl
;
231 *pprbel
= &s
->recycleBinEnumImpl
;
232 return IRecycleBinEnumList_Reset(*pprbel
);