4 * Copyright 1998 Juergen Schmied <juergen.schmied@metronet.de>
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "wine/debug.h"
28 #include "undocshell.h"
35 #include "enumidlist.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(shell);
39 typedef struct tagENUMLIST
41 struct tagENUMLIST *pNext;
44 } ENUMLIST, *LPENUMLIST;
48 IEnumIDListVtbl *lpVtbl;
56 static struct IEnumIDListVtbl eidlvt;
58 /**************************************************************************
65 IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
69 TRACE("(%p)->(pidl=%p)\n",This,pidl);
74 pNew = (LPENUMLIST)SHAlloc(sizeof(ENUMLIST));
77 /*set the next pointer */
81 /*is This the first item in the list? */
85 This->mpCurrent = pNew;
90 /*add the new item to the end of the list */
91 This->mpLast->pNext = pNew;
94 /*update the last item pointer */
96 TRACE("-- (%p)->(first=%p, last=%p)\n",This,This->mpFirst,This->mpLast);
102 /**************************************************************************
103 * CreateFolderEnumList()
105 BOOL CreateFolderEnumList(
110 LPITEMIDLIST pidl=NULL;
111 WIN32_FIND_DATAA stffile;
113 CHAR szPath[MAX_PATH];
114 BOOL succeeded = TRUE;
116 TRACE("(%p)->(path=%s flags=0x%08lx) \n",list,debugstr_a(lpszPath),dwFlags);
118 if(!lpszPath || !lpszPath[0]) return FALSE;
120 strcpy(szPath, lpszPath);
121 PathAddBackslashA(szPath);
122 strcat(szPath,"*.*");
124 hFile = FindFirstFileA(szPath,&stffile);
125 if ( hFile != INVALID_HANDLE_VALUE )
127 BOOL findFinished = FALSE;
131 if ( !(stffile.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
132 || (dwFlags & SHCONTF_INCLUDEHIDDEN) )
134 if ( (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
135 dwFlags & SHCONTF_FOLDERS &&
136 strcmp (stffile.cFileName, ".") && strcmp (stffile.cFileName, ".."))
138 pidl = _ILCreateFromFindDataA(&stffile);
139 succeeded = succeeded && AddToEnumList(list, pidl);
141 else if (!(stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
142 && dwFlags & SHCONTF_NONFOLDERS)
144 pidl = _ILCreateFromFindDataA(&stffile);
145 succeeded = succeeded && AddToEnumList(list, pidl);
150 if (!FindNextFileA(hFile, &stffile))
152 if (GetLastError() == ERROR_NO_MORE_FILES)
158 } while (succeeded && !findFinished);
164 /**************************************************************************
167 static BOOL DeleteList(
170 IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
174 TRACE("(%p)->()\n",This);
177 { pDelete = This->mpFirst;
178 This->mpFirst = pDelete->pNext;
179 SHFree(pDelete->pidl);
182 This->mpFirst = This->mpLast = This->mpCurrent = NULL;
186 /**************************************************************************
187 * IEnumIDList_Folder_Constructor
191 IEnumIDList * IEnumIDList_Constructor(void)
193 IEnumIDListImpl *lpeidl = (IEnumIDListImpl*)HeapAlloc(GetProcessHeap(),
194 HEAP_ZERO_MEMORY, sizeof(IEnumIDListImpl));
199 lpeidl->lpVtbl = &eidlvt;
201 TRACE("-- (%p)->()\n",lpeidl);
203 return (IEnumIDList*)lpeidl;
206 /**************************************************************************
207 * EnumIDList_QueryInterface
209 static HRESULT WINAPI IEnumIDList_fnQueryInterface(
214 IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
216 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
220 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
223 else if(IsEqualIID(riid, &IID_IEnumIDList)) /*IEnumIDList*/
224 { *ppvObj = (IEnumIDList*)This;
228 { IEnumIDList_AddRef((IEnumIDList*)*ppvObj);
229 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
233 TRACE("-- Interface: E_NOINTERFACE\n");
234 return E_NOINTERFACE;
237 /******************************************************************************
238 * IEnumIDList_fnAddRef
240 static ULONG WINAPI IEnumIDList_fnAddRef(
243 IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
244 TRACE("(%p)->(%lu)\n",This,This->ref);
245 return ++(This->ref);
247 /******************************************************************************
248 * IEnumIDList_fnRelease
250 static ULONG WINAPI IEnumIDList_fnRelease(
253 IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
255 TRACE("(%p)->(%lu)\n",This,This->ref);
257 if (!--(This->ref)) {
258 TRACE(" destroying IEnumIDList(%p)\n",This);
259 DeleteList((IEnumIDList*)This);
260 HeapFree(GetProcessHeap(),0,This);
266 /**************************************************************************
270 static HRESULT WINAPI IEnumIDList_fnNext(
273 LPITEMIDLIST * rgelt,
276 IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
282 TRACE("(%p)->(%ld,%p, %p)\n",This,celt,rgelt,pceltFetched);
284 /* It is valid to leave pceltFetched NULL when celt is 1. Some of explorer's
285 * subsystems actually use it (and so may a third party browser)
292 if(celt > 1 && !pceltFetched)
293 { return E_INVALIDARG;
296 if(celt > 0 && !This->mpCurrent)
300 for(i = 0; i < celt; i++)
301 { if(!(This->mpCurrent))
304 temp = ILClone(This->mpCurrent->pidl);
306 This->mpCurrent = This->mpCurrent->pNext;
315 /**************************************************************************
318 static HRESULT WINAPI IEnumIDList_fnSkip(
319 IEnumIDList * iface,ULONG celt)
321 IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
326 TRACE("(%p)->(%lu)\n",This,celt);
328 for(dwIndex = 0; dwIndex < celt; dwIndex++)
329 { if(!This->mpCurrent)
333 This->mpCurrent = This->mpCurrent->pNext;
337 /**************************************************************************
338 * IEnumIDList_fnReset
340 static HRESULT WINAPI IEnumIDList_fnReset(
343 IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
345 TRACE("(%p)\n",This);
346 This->mpCurrent = This->mpFirst;
349 /**************************************************************************
350 * IEnumIDList_fnClone
352 static HRESULT WINAPI IEnumIDList_fnClone(
353 IEnumIDList * iface,LPENUMIDLIST * ppenum)
355 IEnumIDListImpl *This = (IEnumIDListImpl *)iface;
357 TRACE("(%p)->() to (%p)->() E_NOTIMPL\n",This,ppenum);
361 /**************************************************************************
362 * IEnumIDList_fnVTable
364 static IEnumIDListVtbl eidlvt =
366 IEnumIDList_fnQueryInterface,
367 IEnumIDList_fnAddRef,
368 IEnumIDList_fnRelease,