~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/shell32/enumidlist.c

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  *      IEnumIDList
  3  *
  4  *      Copyright 1998  Juergen Schmied <juergen.schmied@metronet.de>
  5  *
  6  * This library is free software; you can redistribute it and/or
  7  * modify it under the terms of the GNU Lesser General Public
  8  * License as published by the Free Software Foundation; either
  9  * version 2.1 of the License, or (at your option) any later version.
 10  *
 11  * This library is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14  * Lesser General Public License for more details.
 15  *
 16  * You should have received a copy of the GNU Lesser General Public
 17  * License along with this library; if not, write to the Free Software
 18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 19  */
 20 
 21 #include <stdarg.h>
 22 #include <stdlib.h>
 23 #include <string.h>
 24 
 25 #define COBJMACROS
 26 
 27 #include "wine/debug.h"
 28 #include "wine/unicode.h"
 29 #include "windef.h"
 30 #include "winbase.h"
 31 #include "winreg.h"
 32 #include "shlwapi.h"
 33 
 34 #include "pidl.h"
 35 #include "enumidlist.h"
 36 
 37 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 38 
 39 typedef struct tagENUMLIST
 40 {
 41         struct tagENUMLIST      *pNext;
 42         LPITEMIDLIST            pidl;
 43 
 44 } ENUMLIST, *LPENUMLIST;
 45 
 46 typedef struct
 47 {
 48         const IEnumIDListVtbl          *lpVtbl;
 49         LONG                            ref;
 50         LPENUMLIST                      mpFirst;
 51         LPENUMLIST                      mpLast;
 52         LPENUMLIST                      mpCurrent;
 53 
 54 } IEnumIDListImpl;
 55 
 56 static const IEnumIDListVtbl eidlvt;
 57 
 58 /**************************************************************************
 59  *  AddToEnumList()
 60  */
 61 BOOL AddToEnumList(
 62         IEnumIDList * iface,
 63         LPITEMIDLIST pidl)
 64 {
 65         IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
 66 
 67         LPENUMLIST  pNew;
 68 
 69         TRACE("(%p)->(pidl=%p)\n",This,pidl);
 70 
 71     if (!iface || !pidl)
 72         return FALSE;
 73 
 74         pNew = SHAlloc(sizeof(ENUMLIST));
 75         if(pNew)
 76         {
 77           /*set the next pointer */
 78           pNew->pNext = NULL;
 79           pNew->pidl = pidl;
 80 
 81           /*is This the first item in the list? */
 82           if(!This->mpFirst)
 83           {
 84             This->mpFirst = pNew;
 85             This->mpCurrent = pNew;
 86           }
 87 
 88           if(This->mpLast)
 89           {
 90             /*add the new item to the end of the list */
 91             This->mpLast->pNext = pNew;
 92           }
 93 
 94           /*update the last item pointer */
 95           This->mpLast = pNew;
 96           TRACE("-- (%p)->(first=%p, last=%p)\n",This,This->mpFirst,This->mpLast);
 97           return TRUE;
 98         }
 99         return FALSE;
100 }
101 
102 /**************************************************************************
103  *  CreateFolderEnumList()
104  */
105 BOOL CreateFolderEnumList(
106         IEnumIDList *list,
107         LPCWSTR lpszPath,
108         DWORD dwFlags)
109 {
110     LPITEMIDLIST pidl=NULL;
111     WIN32_FIND_DATAW stffile;
112     HANDLE hFile;
113     WCHAR  szPath[MAX_PATH];
114     BOOL succeeded = TRUE;
115     static const WCHAR stars[] = { '*','.','*',0 };
116     static const WCHAR dot[] = { '.',0 };
117     static const WCHAR dotdot[] = { '.','.',0 };
118 
119     TRACE("(%p)->(path=%s flags=0x%08x)\n", list, debugstr_w(lpszPath), dwFlags);
120 
121     if(!lpszPath || !lpszPath[0]) return FALSE;
122 
123     strcpyW(szPath, lpszPath);
124     PathAddBackslashW(szPath);
125     strcatW(szPath,stars);
126 
127     hFile = FindFirstFileW(szPath,&stffile);
128     if ( hFile != INVALID_HANDLE_VALUE )
129     {
130         BOOL findFinished = FALSE;
131 
132         do
133         {
134             if ( !(stffile.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) 
135              || (dwFlags & SHCONTF_INCLUDEHIDDEN) )
136             {
137                 if ( (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
138                  dwFlags & SHCONTF_FOLDERS &&
139                  strcmpW(stffile.cFileName, dot) && strcmpW(stffile.cFileName, dotdot))
140                 {
141                     pidl = _ILCreateFromFindDataW(&stffile);
142                     succeeded = succeeded && AddToEnumList(list, pidl);
143                 }
144                 else if (!(stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
145                  && dwFlags & SHCONTF_NONFOLDERS)
146                 {
147                     pidl = _ILCreateFromFindDataW(&stffile);
148                     succeeded = succeeded && AddToEnumList(list, pidl);
149                 }
150             }
151             if (succeeded)
152             {
153                 if (!FindNextFileW(hFile, &stffile))
154                 {
155                     if (GetLastError() == ERROR_NO_MORE_FILES)
156                         findFinished = TRUE;
157                     else
158                         succeeded = FALSE;
159                 }
160             }
161         } while (succeeded && !findFinished);
162         FindClose(hFile);
163     }
164     return succeeded;
165 }
166 
167 /**************************************************************************
168 *   DeleteList()
169 */
170 static BOOL DeleteList(
171         IEnumIDList * iface)
172 {
173         IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
174 
175         LPENUMLIST  pDelete;
176 
177         TRACE("(%p)->()\n",This);
178 
179         while(This->mpFirst)
180         { pDelete = This->mpFirst;
181           This->mpFirst = pDelete->pNext;
182           SHFree(pDelete->pidl);
183           SHFree(pDelete);
184         }
185         This->mpFirst = This->mpLast = This->mpCurrent = NULL;
186         return TRUE;
187 }
188 
189 /**************************************************************************
190  *  IEnumIDList_Folder_Constructor
191  *
192  */
193 
194 IEnumIDList * IEnumIDList_Constructor(void)
195 {
196     IEnumIDListImpl *lpeidl = HeapAlloc(GetProcessHeap(),
197      HEAP_ZERO_MEMORY, sizeof(IEnumIDListImpl));
198 
199     if (lpeidl)
200     {
201         lpeidl->ref = 1;
202         lpeidl->lpVtbl = &eidlvt;
203     }
204     TRACE("-- (%p)->()\n",lpeidl);
205 
206     return (IEnumIDList*)lpeidl;
207 }
208 
209 /**************************************************************************
210  *  EnumIDList_QueryInterface
211  */
212 static HRESULT WINAPI IEnumIDList_fnQueryInterface(
213         IEnumIDList * iface,
214         REFIID riid,
215         LPVOID *ppvObj)
216 {
217         IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
218 
219         TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
220 
221         *ppvObj = NULL;
222 
223         if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
224         { *ppvObj = This;
225         }
226         else if(IsEqualIID(riid, &IID_IEnumIDList))  /*IEnumIDList*/
227         {    *ppvObj = This;
228         }
229 
230         if(*ppvObj)
231         { IEnumIDList_AddRef((IEnumIDList*)*ppvObj);
232           TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
233           return S_OK;
234         }
235 
236         TRACE("-- Interface: E_NOINTERFACE\n");
237         return E_NOINTERFACE;
238 }
239 
240 /******************************************************************************
241  * IEnumIDList_fnAddRef
242  */
243 static ULONG WINAPI IEnumIDList_fnAddRef(
244         IEnumIDList * iface)
245 {
246         IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
247         ULONG refCount = InterlockedIncrement(&This->ref);
248 
249         TRACE("(%p)->(%u)\n", This, refCount - 1);
250 
251         return refCount;
252 }
253 /******************************************************************************
254  * IEnumIDList_fnRelease
255  */
256 static ULONG WINAPI IEnumIDList_fnRelease(
257         IEnumIDList * iface)
258 {
259         IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
260         ULONG refCount = InterlockedDecrement(&This->ref);
261 
262         TRACE("(%p)->(%u)\n", This, refCount + 1);
263 
264         if (!refCount) {
265           TRACE(" destroying IEnumIDList(%p)\n",This);
266           DeleteList((IEnumIDList*)This);
267           HeapFree(GetProcessHeap(),0,This);
268         }
269         return refCount;
270 }
271 
272 /**************************************************************************
273  *  IEnumIDList_fnNext
274  */
275 
276 static HRESULT WINAPI IEnumIDList_fnNext(
277         IEnumIDList * iface,
278         ULONG celt,
279         LPITEMIDLIST * rgelt,
280         ULONG *pceltFetched)
281 {
282         IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
283 
284         ULONG    i;
285         HRESULT  hr = S_OK;
286         LPITEMIDLIST  temp;
287 
288         TRACE("(%p)->(%d,%p, %p)\n",This,celt,rgelt,pceltFetched);
289 
290 /* It is valid to leave pceltFetched NULL when celt is 1. Some of explorer's
291  * subsystems actually use it (and so may a third party browser)
292  */
293         if(pceltFetched)
294           *pceltFetched = 0;
295 
296         *rgelt=0;
297 
298         if(celt > 1 && !pceltFetched)
299         { return E_INVALIDARG;
300         }
301 
302         if(celt > 0 && !This->mpCurrent)
303         { return S_FALSE;
304         }
305 
306         for(i = 0; i < celt; i++)
307         { if(!(This->mpCurrent))
308             break;
309 
310           temp = ILClone(This->mpCurrent->pidl);
311           rgelt[i] = temp;
312           This->mpCurrent = This->mpCurrent->pNext;
313         }
314         if(pceltFetched)
315         {  *pceltFetched = i;
316         }
317 
318         return hr;
319 }
320 
321 /**************************************************************************
322 *  IEnumIDList_fnSkip
323 */
324 static HRESULT WINAPI IEnumIDList_fnSkip(
325         IEnumIDList * iface,ULONG celt)
326 {
327         IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
328 
329         DWORD    dwIndex;
330         HRESULT  hr = S_OK;
331 
332         TRACE("(%p)->(%u)\n",This,celt);
333 
334         for(dwIndex = 0; dwIndex < celt; dwIndex++)
335         { if(!This->mpCurrent)
336           { hr = S_FALSE;
337             break;
338           }
339           This->mpCurrent = This->mpCurrent->pNext;
340         }
341         return hr;
342 }
343 /**************************************************************************
344 *  IEnumIDList_fnReset
345 */
346 static HRESULT WINAPI IEnumIDList_fnReset(
347         IEnumIDList * iface)
348 {
349         IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
350 
351         TRACE("(%p)\n",This);
352         This->mpCurrent = This->mpFirst;
353         return S_OK;
354 }
355 /**************************************************************************
356 *  IEnumIDList_fnClone
357 */
358 static HRESULT WINAPI IEnumIDList_fnClone(
359         IEnumIDList * iface,LPENUMIDLIST * ppenum)
360 {
361         IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
362 
363         TRACE("(%p)->() to (%p)->() E_NOTIMPL\n",This,ppenum);
364         return E_NOTIMPL;
365 }
366 
367 /**************************************************************************
368  *  IEnumIDList_fnVTable
369  */
370 static const IEnumIDListVtbl eidlvt =
371 {
372         IEnumIDList_fnQueryInterface,
373         IEnumIDList_fnAddRef,
374         IEnumIDList_fnRelease,
375         IEnumIDList_fnNext,
376         IEnumIDList_fnSkip,
377         IEnumIDList_fnReset,
378         IEnumIDList_fnClone,
379 };
380 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.