4 * Copyright 1998 Juergen Schmied <juergen.schmied@metronet.de>
10 #include "wine/obj_base.h"
11 #include "wine/obj_enumidlist.h"
16 #include "shell32_main.h"
18 typedef struct tagENUMLIST
20 struct tagENUMLIST
*pNext
;
23 } ENUMLIST
, *LPENUMLIST
;
27 ICOM_VTABLE(IEnumIDList
)* lpvtbl
;
35 static struct ICOM_VTABLE(IEnumIDList
) eidlvt
;
37 /**************************************************************************
38 * IEnumIDList_fnConstructor
41 IEnumIDList
* IEnumIDList_Constructor(
44 { IEnumIDListImpl
* lpeidl
;
46 lpeidl
= (IEnumIDListImpl
*)HeapAlloc(GetProcessHeap(),0,sizeof(IEnumIDListImpl
));
51 lpeidl
->lpvtbl
= &eidlvt
;
54 lpeidl
->mpCurrent
=NULL
;
56 TRACE(shell
,"(%p)->(%s flags=0x%08lx)\n",lpeidl
,debugstr_a(lpszPath
),dwFlags
);
58 if(!IEnumIDList_CreateEnumList((IEnumIDList
*)lpeidl
, lpszPath
, dwFlags
))
60 { HeapFree(GetProcessHeap(),0,lpeidl
);
65 TRACE(shell
,"-- (%p)->()\n",lpeidl
);
67 return (IEnumIDList
*)lpeidl
;
70 /**************************************************************************
71 * EnumIDList_QueryInterface
73 static HRESULT WINAPI
IEnumIDList_fnQueryInterface(
78 ICOM_THIS(IEnumIDListImpl
,iface
);
81 WINE_StringFromCLSID((LPCLSID
)riid
,xriid
);
82 TRACE(shell
,"(%p)->(\n\tIID:\t%s,%p)\n",This
,xriid
,ppvObj
);
86 if(IsEqualIID(riid
, &IID_IUnknown
)) /*IUnknown*/
89 else if(IsEqualIID(riid
, &IID_IEnumIDList
)) /*IEnumIDList*/
90 { *ppvObj
= (IEnumIDList
*)This
;
94 { IEnumIDList_AddRef((IEnumIDList
*)*ppvObj
);
95 TRACE(shell
,"-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
99 TRACE(shell
,"-- Interface: E_NOINTERFACE\n");
100 return E_NOINTERFACE
;
103 /******************************************************************************
104 * IEnumIDList_fnAddRef
106 static ULONG WINAPI
IEnumIDList_fnAddRef(
109 ICOM_THIS(IEnumIDListImpl
,iface
);
111 TRACE(shell
,"(%p)->(%lu)\n",This
,This
->ref
);
114 return ++(This
->ref
);
116 /******************************************************************************
117 * IEnumIDList_fnRelease
119 static ULONG WINAPI
IEnumIDList_fnRelease(
122 ICOM_THIS(IEnumIDListImpl
,iface
);
124 TRACE(shell
,"(%p)->(%lu)\n",This
,This
->ref
);
129 { TRACE(shell
," destroying IEnumIDList(%p)\n",This
);
130 IEnumIDList_DeleteList((IEnumIDList
*)This
);
131 HeapFree(GetProcessHeap(),0,This
);
137 /**************************************************************************
141 static HRESULT WINAPI
IEnumIDList_fnNext(
144 LPITEMIDLIST
* rgelt
,
147 ICOM_THIS(IEnumIDListImpl
,iface
);
153 TRACE(shell
,"(%p)->(%ld,%p, %p)\n",This
,celt
,rgelt
,pceltFetched
);
155 /* It is valid to leave pceltFetched NULL when celt is 1. Some of explorer's
156 * subsystems actually use it (and so may a third party browser)
163 if(celt
> 1 && !pceltFetched
)
164 { return E_INVALIDARG
;
167 for(i
= 0; i
< celt
; i
++)
168 { if(!(This
->mpCurrent
))
172 temp
= ILClone(This
->mpCurrent
->pidl
);
174 This
->mpCurrent
= This
->mpCurrent
->pNext
;
183 /**************************************************************************
186 static HRESULT WINAPI
IEnumIDList_fnSkip(
187 IEnumIDList
* iface
,ULONG celt
)
189 ICOM_THIS(IEnumIDListImpl
,iface
);
194 TRACE(shell
,"(%p)->(%lu)\n",This
,celt
);
196 for(dwIndex
= 0; dwIndex
< celt
; dwIndex
++)
197 { if(!This
->mpCurrent
)
201 This
->mpCurrent
= This
->mpCurrent
->pNext
;
205 /**************************************************************************
206 * IEnumIDList_fnReset
208 static HRESULT WINAPI
IEnumIDList_fnReset(
211 ICOM_THIS(IEnumIDListImpl
,iface
);
213 TRACE(shell
,"(%p)\n",This
);
214 This
->mpCurrent
= This
->mpFirst
;
217 /**************************************************************************
218 * IEnumIDList_fnClone
220 static HRESULT WINAPI
IEnumIDList_fnClone(
221 IEnumIDList
* iface
,LPENUMIDLIST
* ppenum
)
223 ICOM_THIS(IEnumIDListImpl
,iface
);
225 TRACE(shell
,"(%p)->() to (%p)->() E_NOTIMPL\n",This
,ppenum
);
228 /**************************************************************************
229 * EnumIDList_CreateEnumList()
230 * fixme: devices not handled
231 * fixme: add wildcards to path
233 static BOOL WINAPI
IEnumIDList_fnCreateEnumList(
238 ICOM_THIS(IEnumIDListImpl
,iface
);
240 LPITEMIDLIST pidl
=NULL
;
241 LPPIDLDATA pData
=NULL
;
242 WIN32_FIND_DATAA stffile
;
246 CHAR szPath
[MAX_PATH
];
248 TRACE(shell
,"(%p)->(path=%s flags=0x%08lx) \n",This
,debugstr_a(lpszPath
),dwFlags
);
250 if (lpszPath
&& lpszPath
[0]!='\0')
251 { strcpy(szPath
, lpszPath
);
252 PathAddBackslashA(szPath
);
253 strcat(szPath
,"*.*");
256 /*enumerate the folders*/
257 if(dwFlags
& SHCONTF_FOLDERS
)
258 { /* special case - we can't enumerate the Desktop level Objects (MyComputer,Nethood...
259 so we need to fake an enumeration of those.*/
261 { TRACE (shell
,"-- (%p)-> enumerate SHCONTF_FOLDERS (special) items\n",This
);
262 /*create the pidl for This item */
263 pidl
= _ILCreateMyComputer();
265 { if(!IEnumIDList_AddToEnumList((IEnumIDList
*)This
, pidl
))
269 else if (lpszPath
[0]=='\0') /* enumerate the drives*/
270 { TRACE (shell
,"-- (%p)-> enumerate SHCONTF_FOLDERS (drives)\n",This
);
271 dwDrivemap
= GetLogicalDrives();
272 strcpy (szDriveName
,"A:\\");
273 while (szDriveName
[0]<='Z')
274 { if(dwDrivemap
& 0x00000001L
)
275 { pidl
= _ILCreateDrive(szDriveName
);
277 { if(!IEnumIDList_AddToEnumList((IEnumIDList
*)This
, pidl
))
282 dwDrivemap
= dwDrivemap
>> 1;
286 { TRACE (shell
,"-- (%p)-> enumerate SHCONTF_FOLDERS of %s\n",This
,debugstr_a(szPath
));
287 hFile
= FindFirstFileA(szPath
,&stffile
);
288 if ( hFile
!= INVALID_HANDLE_VALUE
)
290 { if ( (stffile
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) && strcmp (stffile
.cFileName
, ".") && strcmp (stffile
.cFileName
, ".."))
291 { pidl
= _ILCreateFolder( stffile
.cAlternateFileName
, stffile
.cFileName
);
293 { pData
= _ILGetDataPointer(pidl
);
294 FileTimeToDosDateTime(&stffile
.ftLastWriteTime
,&pData
->u
.folder
.uFileDate
,&pData
->u
.folder
.uFileTime
);
295 pData
->u
.folder
.dwFileSize
= stffile
.nFileSizeLow
;
296 pData
->u
.folder
.uFileAttribs
=stffile
.dwFileAttributes
;
297 if(!IEnumIDList_AddToEnumList((IEnumIDList
*)This
, pidl
))
305 } while( FindNextFileA(hFile
,&stffile
));
310 /*enumerate the non-folder items (values) */
311 if(dwFlags
& SHCONTF_NONFOLDERS
)
313 { TRACE (shell
,"-- (%p)-> enumerate SHCONTF_NONFOLDERS of %s\n",This
,debugstr_a(szPath
));
314 hFile
= FindFirstFileA(szPath
,&stffile
);
315 if ( hFile
!= INVALID_HANDLE_VALUE
)
317 { if (! (stffile
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) )
318 { pidl
= _ILCreateValue( stffile
.cAlternateFileName
, stffile
.cFileName
);
320 { pData
= _ILGetDataPointer(pidl
);
321 FileTimeToDosDateTime(&stffile
.ftLastWriteTime
,&pData
->u
.file
.uFileDate
,&pData
->u
.file
.uFileTime
);
322 pData
->u
.file
.dwFileSize
= stffile
.nFileSizeLow
;
323 pData
->u
.file
.uFileAttribs
=stffile
.dwFileAttributes
;
324 if(!IEnumIDList_AddToEnumList((IEnumIDList
*)This
, pidl
))
332 } while( FindNextFileA(hFile
,&stffile
));
340 /**************************************************************************
341 * EnumIDList_AddToEnumList()
343 static BOOL WINAPI
IEnumIDList_fnAddToEnumList(
347 ICOM_THIS(IEnumIDListImpl
,iface
);
351 TRACE(shell
,"(%p)->(pidl=%p)\n",This
,pidl
);
352 pNew
= (LPENUMLIST
)SHAlloc(sizeof(ENUMLIST
));
354 { /*set the next pointer */
358 /*is This the first item in the list? */
360 { This
->mpFirst
= pNew
;
361 This
->mpCurrent
= pNew
;
365 { /*add the new item to the end of the list */
366 This
->mpLast
->pNext
= pNew
;
369 /*update the last item pointer */
371 TRACE(shell
,"-- (%p)->(first=%p, last=%p)\n",This
,This
->mpFirst
,This
->mpLast
);
376 /**************************************************************************
377 * EnumIDList_DeleteList()
379 static BOOL WINAPI
IEnumIDList_fnDeleteList(
382 ICOM_THIS(IEnumIDListImpl
,iface
);
386 TRACE(shell
,"(%p)->()\n",This
);
389 { pDelete
= This
->mpFirst
;
390 This
->mpFirst
= pDelete
->pNext
;
391 SHFree(pDelete
->pidl
);
394 This
->mpFirst
= This
->mpLast
= This
->mpCurrent
= NULL
;
398 /**************************************************************************
399 * IEnumIDList_fnVTable
401 static ICOM_VTABLE (IEnumIDList
) eidlvt
=
402 { IEnumIDList_fnQueryInterface
,
403 IEnumIDList_fnAddRef
,
404 IEnumIDList_fnRelease
,
409 IEnumIDList_fnCreateEnumList
,
410 IEnumIDList_fnAddToEnumList
,
411 IEnumIDList_fnDeleteList