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)
10 #include "recyclebin_private.h"
13 WINE_DEFAULT_DEBUG_CHANNEL(recyclebin
);
15 struct RecycleBinGenericEnum
18 IRecycleBinEnumList recycleBinEnumImpl
;
19 IRecycleBinEnumList
*current
;
20 DWORD dwLogicalDrives
;
24 static HRESULT STDMETHODCALLTYPE
25 RecycleBinGenericEnum_RecycleBinEnumList_QueryInterface(
26 IN IRecycleBinEnumList
*This
,
30 struct RecycleBinGenericEnum
*s
= CONTAINING_RECORD(This
, struct RecycleBinGenericEnum
, recycleBinEnumImpl
);
32 TRACE("(%p, %s, %p)\n", This
, debugstr_guid(riid
), ppvObject
);
37 if (IsEqualIID(riid
, &IID_IUnknown
))
38 *ppvObject
= &s
->recycleBinEnumImpl
;
39 else if (IsEqualIID(riid
, &IID_IRecycleBinEnumList
))
40 *ppvObject
= &s
->recycleBinEnumImpl
;
47 IUnknown_AddRef(This
);
51 static ULONG STDMETHODCALLTYPE
52 RecycleBinGenericEnum_RecycleBinEnumList_AddRef(
53 IN IRecycleBinEnumList
*This
)
55 struct RecycleBinGenericEnum
*s
= CONTAINING_RECORD(This
, struct RecycleBinGenericEnum
, recycleBinEnumImpl
);
56 ULONG refCount
= InterlockedIncrement((PLONG
)&s
->ref
);
57 TRACE("(%p)\n", This
);
62 RecycleBinGenericEnum_Destructor(
63 struct RecycleBinGenericEnum
*s
)
68 IRecycleBinEnumList_Release(s
->current
);
72 static ULONG STDMETHODCALLTYPE
73 RecycleBinGenericEnum_RecycleBinEnumList_Release(
74 IN IRecycleBinEnumList
*This
)
76 struct RecycleBinGenericEnum
*s
= CONTAINING_RECORD(This
, struct RecycleBinGenericEnum
, recycleBinEnumImpl
);
79 TRACE("(%p)\n", This
);
81 refCount
= InterlockedDecrement((PLONG
)&s
->ref
);
84 RecycleBinGenericEnum_Destructor(s
);
89 static HRESULT STDMETHODCALLTYPE
90 RecycleBinGenericEnum_RecycleBinEnumList_Next(
91 IN IRecycleBinEnumList
*This
,
93 IN OUT IRecycleBinFile
**rgelt
,
94 OUT DWORD
*pceltFetched
)
96 struct RecycleBinGenericEnum
*s
= CONTAINING_RECORD(This
, struct RecycleBinGenericEnum
, recycleBinEnumImpl
);
99 DWORD fetched
= 0, newFetched
;
102 TRACE("(%p, %u, %p, %p)\n", This
, celt
, rgelt
, pceltFetched
);
106 if (!pceltFetched
&& celt
> 1)
111 /* Get enumerator implementation */
112 if (!s
->current
&& s
->dwLogicalDrives
)
114 for (i
= 0; i
< 26; i
++)
115 if (s
->dwLogicalDrives
& (1 << i
))
117 WCHAR szVolumeName
[4];
118 szVolumeName
[0] = (WCHAR
)('A' + i
);
119 szVolumeName
[1] = ':';
120 szVolumeName
[2] = '\\';
121 szVolumeName
[3] = UNICODE_NULL
;
122 if (GetDriveTypeW(szVolumeName
) != DRIVE_FIXED
)
124 s
->dwLogicalDrives
&= ~(1 << i
);
127 hr
= GetDefaultRecycleBin(szVolumeName
, &prb
);
130 hr
= IRecycleBin_EnumObjects(prb
, &s
->current
);
131 IRecycleBin_Release(prb
);
134 s
->dwLogicalDrives
&= ~(1 << i
);
140 /* Nothing more to enumerate */
142 *pceltFetched
= fetched
;
146 /* Skip some elements */
149 IRecycleBinFile
*rbf
;
150 hr
= IRecycleBinEnumList_Next(s
->current
, 1, &rbf
, NULL
);
152 hr
= IRecycleBinFile_Release(rbf
);
153 else if (hr
== S_FALSE
)
155 else if (!SUCCEEDED(hr
))
162 hr
= IRecycleBinEnumList_Next(s
->current
, celt
- fetched
, &rgelt
[fetched
], &newFetched
);
164 fetched
+= newFetched
;
165 if (hr
== S_FALSE
|| newFetched
== 0)
167 hr
= IRecycleBinEnumList_Release(s
->current
);
170 else if (!SUCCEEDED(hr
))
175 *pceltFetched
= fetched
;
183 static HRESULT STDMETHODCALLTYPE
184 RecycleBinGenericEnum_RecycleBinEnumList_Skip(
185 IN IRecycleBinEnumList
*This
,
188 struct RecycleBinGenericEnum
*s
= CONTAINING_RECORD(This
, struct RecycleBinGenericEnum
, recycleBinEnumImpl
);
189 TRACE("(%p, %u)\n", This
, celt
);
194 static HRESULT STDMETHODCALLTYPE
195 RecycleBinGenericEnum_RecycleBinEnumList_Reset(
196 IN IRecycleBinEnumList
*This
)
198 struct RecycleBinGenericEnum
*s
= CONTAINING_RECORD(This
, struct RecycleBinGenericEnum
, recycleBinEnumImpl
);
200 TRACE("(%p)\n", This
);
204 IRecycleBinEnumList_Release(s
->current
);
208 s
->dwLogicalDrives
= GetLogicalDrives();
212 CONST_VTBL
struct IRecycleBinEnumListVtbl RecycleBinGenericEnumVtbl
=
214 RecycleBinGenericEnum_RecycleBinEnumList_QueryInterface
,
215 RecycleBinGenericEnum_RecycleBinEnumList_AddRef
,
216 RecycleBinGenericEnum_RecycleBinEnumList_Release
,
217 RecycleBinGenericEnum_RecycleBinEnumList_Next
,
218 RecycleBinGenericEnum_RecycleBinEnumList_Skip
,
219 RecycleBinGenericEnum_RecycleBinEnumList_Reset
,
223 RecycleBinGenericEnum_Constructor(
224 OUT IRecycleBinEnumList
**pprbel
)
226 struct RecycleBinGenericEnum
*s
;
228 s
= CoTaskMemAlloc(sizeof(struct RecycleBinGenericEnum
));
230 return E_OUTOFMEMORY
;
231 ZeroMemory(s
, sizeof(struct RecycleBinGenericEnum
));
233 s
->recycleBinEnumImpl
.lpVtbl
= &RecycleBinGenericEnumVtbl
;
235 *pprbel
= &s
->recycleBinEnumImpl
;
236 return IRecycleBinEnumList_Reset(*pprbel
);