4 * Copyright 1998 Juergen Schmied
7 * a pidl == NULL means desktop and is legal
18 #include "interfaces.h"
25 #include "winversion.h"
26 #include "shell32_main.h"
30 void pdump (LPCITEMIDLIST pidl
)
33 LPITEMIDLIST pidltemp
= pidl
;
35 { TRACE(pidl
,"-------- pidl = NULL (Root)\n");
38 TRACE(pidl
,"-------- pidl=%p \n", pidl
);
39 if (pidltemp
->mkid
.cb
)
41 { type
= _ILGetDataPointer(pidltemp
)->type
;
42 szData
= _ILGetTextPointer(type
, _ILGetDataPointer(pidltemp
));
44 TRACE(pidl
,"---- pidl=%p size=%u type=%lx %s\n",pidltemp
, pidltemp
->mkid
.cb
,type
,debugstr_a(szData
));
46 pidltemp
= ILGetNext(pidltemp
);
47 } while (pidltemp
->mkid
.cb
);
51 TRACE(pidl
,"empty pidl (Desktop)\n");
53 /*************************************************************************
54 * ILGetDisplayName [SHELL32.15]
56 BOOL32 WINAPI
ILGetDisplayName(LPCITEMIDLIST iil
,LPSTR path
)
57 { FIXME(pidl
,"(%p,%p),stub, return e:!\n",iil
,path
);
61 /*************************************************************************
62 * ILFindLastID [SHELL32.16]
64 LPITEMIDLIST WINAPI
ILFindLastID(LPITEMIDLIST pidl
)
65 { LPITEMIDLIST pidlLast
= NULL
;
67 TRACE(pidl
,"(pidl=%p)\n",pidl
);
70 { while(pidl
->mkid
.cb
)
71 { pidlLast
= (LPITEMIDLIST
)pidl
;
72 pidl
= ILGetNext(pidl
);
77 /*************************************************************************
78 * ILRemoveLastID [SHELL32.17]
80 * Removes the last item
82 BOOL32 WINAPI
ILRemoveLastID(LPCITEMIDLIST pidl
)
83 { TRACE(shell
,"pidl=%p\n",pidl
);
84 if (!pidl
|| !pidl
->mkid
.cb
)
86 ILFindLastID(pidl
)->mkid
.cb
= 0;
90 /*************************************************************************
91 * ILClone [SHELL32.18]
96 LPITEMIDLIST WINAPI
ILClone (LPCITEMIDLIST pidl
)
103 len
= ILGetSize(pidl
);
104 newpidl
= (LPITEMIDLIST
)SHAlloc(len
);
106 memcpy(newpidl
,pidl
,len
);
108 TRACE(pidl
,"pidl=%p newpidl=%p\n",pidl
, newpidl
);
113 /*************************************************************************
114 * ILCloneFirst [SHELL32.19]
117 * duplicates the first idlist of a complex pidl
119 LPITEMIDLIST WINAPI
ILCloneFirst(LPCITEMIDLIST pidl
)
121 LPITEMIDLIST newpidl
=NULL
;
123 TRACE(pidl
,"pidl=%p \n",pidl
);
127 { len
= pidl
->mkid
.cb
;
128 newpidl
= (LPITEMIDLIST
) SHAlloc (len
+2);
130 { memcpy(newpidl
,pidl
,len
);
131 ILGetNext(newpidl
)->mkid
.cb
= 0x00;
134 TRACE(pidl
,"-- newpidl=%p\n",newpidl
);
138 /*************************************************************************
139 * ILIsEqual [SHELL32.21]
142 BOOL32 WINAPI
ILIsEqual(LPCITEMIDLIST pidl1
, LPCITEMIDLIST pidl2
)
143 { LPPIDLDATA ppidldata
;
147 LPITEMIDLIST pidltemp1
= pidl1
;
148 LPITEMIDLIST pidltemp2
= pidl2
;
150 TRACE(pidl
,"pidl1=%p pidl2=%p\n",pidl1
, pidl2
);
155 if ( (!pidl1
) || (!pidl2
) )
159 if (pidltemp1
->mkid
.cb
&& pidltemp2
->mkid
.cb
)
161 { ppidldata
= _ILGetDataPointer(pidltemp1
);
162 szData1
= _ILGetTextPointer(ppidldata
->type
, ppidldata
);
164 ppidldata
= _ILGetDataPointer(pidltemp2
);
165 szData2
= _ILGetTextPointer(ppidldata
->type
, ppidldata
);
167 if (strcmp ( szData1
, szData2
)!=0 )
170 pidltemp1
= ILGetNext(pidltemp1
);
171 pidltemp2
= ILGetNext(pidltemp2
);
173 } while (pidltemp1
->mkid
.cb
&& pidltemp2
->mkid
.cb
);
175 if (!pidltemp1
->mkid
.cb
&& !pidltemp2
->mkid
.cb
)
176 { TRACE(shell
, "--- equal\n");
182 /*************************************************************************
183 * ILIsParent [SHELL32.23]
186 DWORD WINAPI
ILIsParent( DWORD x
, DWORD y
, DWORD z
)
187 { FIXME(pidl
,"0x%08lx 0x%08lx 0x%08lx stub\n",x
,y
,z
);
191 /*************************************************************************
192 * ILFindChild [SHELL32.24]
195 * Compares elements from pidl1 and pidl2.
196 * When at least the first element is equal, it gives a pointer
197 * to the first different element of pidl 2 back.
198 * Returns 0 if pidl 2 is shorter.
200 LPITEMIDLIST WINAPI
ILFindChild(LPCITEMIDLIST pidl1
,LPCITEMIDLIST pidl2
)
201 { LPPIDLDATA ppidldata
;
205 LPITEMIDLIST pidltemp1
= pidl1
;
206 LPITEMIDLIST pidltemp2
= pidl2
;
207 LPITEMIDLIST ret
=NULL
;
209 TRACE(pidl
,"pidl1=%p pidl2=%p\n",pidl1
, pidl2
);
214 if ( !pidl1
|| !pidl1
->mkid
.cb
) /* pidl 1 is desktop (root) */
215 { TRACE(shell
, "--- %p\n", pidl2
);
219 if (pidltemp1
->mkid
.cb
&& pidltemp2
->mkid
.cb
)
221 { ppidldata
= _ILGetDataPointer(pidltemp1
);
222 szData1
= _ILGetTextPointer(ppidldata
->type
, ppidldata
);
224 ppidldata
= _ILGetDataPointer(pidltemp2
);
225 szData2
= _ILGetTextPointer(ppidldata
->type
, ppidldata
);
227 pidltemp2
= ILGetNext(pidltemp2
); /* points behind the pidl2 */
229 if (strcmp(szData1
,szData2
) == 0)
230 { ret
= pidltemp2
; /* found equal element */
233 { if (ret
) /* different element after equal -> break */
238 pidltemp1
= ILGetNext(pidltemp1
);
239 } while (pidltemp1
->mkid
.cb
&& pidltemp2
->mkid
.cb
);
242 if (!pidltemp2
->mkid
.cb
)
243 { return NULL
; /* complete equal or pidl 2 is shorter */
246 TRACE(shell
, "--- %p\n", ret
);
247 return ret
; /* pidl 1 is shorter */
250 /*************************************************************************
251 * ILCombine [SHELL32.25]
254 * Concatenates two complex idlists.
255 * The pidl is the first one, pidlsub the next one
256 * Does not destroy the passed in idlists!
258 LPITEMIDLIST WINAPI
ILCombine(LPCITEMIDLIST pidl1
,LPCITEMIDLIST pidl2
)
260 LPITEMIDLIST pidlNew
;
262 TRACE(pidl
,"pidl=%p pidl=%p\n",pidl1
,pidl2
);
272 { pidlNew
= ILClone(pidl2
);
277 { pidlNew
= ILClone(pidl1
);
281 len1
= ILGetSize(pidl1
)-2;
282 len2
= ILGetSize(pidl2
);
283 pidlNew
= SHAlloc(len1
+len2
);
286 { memcpy(pidlNew
,pidl1
,len1
);
287 memcpy(((BYTE
*)pidlNew
)+len1
,pidl2
,len2
);
290 /* TRACE(pidl,"--new pidl=%p\n",pidlNew);*/
293 /*************************************************************************
294 * SHGetRealIDL [SHELL32.98]
298 LPITEMIDLIST WINAPI
SHGetRealIDL(DWORD x
, DWORD y
, DWORD z
)
299 { FIXME(pidl
,"0x%04lx 0x%04lx 0x%04lx\n",x
,y
,z
);
303 /*************************************************************************
304 * SHLogILFromFSIL [SHELL32.95]
308 LPITEMIDLIST WINAPI
SHLogILFromFSIL(LPITEMIDLIST pidl
)
309 { FIXME(pidl
,"(pidl=%p)\n",pidl
);
314 /*************************************************************************
315 * ILGetSize [SHELL32.152]
316 * gets the byte size of an idlist including zero terminator (pidl)
325 * exported by ordinal
327 DWORD WINAPI
ILGetSize(LPITEMIDLIST pidl
)
328 { LPSHITEMID si
= &(pidl
->mkid
);
334 si
= (LPSHITEMID
)(((LPBYTE
)si
)+si
->cb
);
338 TRACE(pidl
,"pidl=%p size=%lu\n",pidl
, len
);
341 /*************************************************************************
342 * ILGetNext [SHELL32.153]
343 * gets the next simple pidl of a complex pidl
349 * pointer to next element
352 LPITEMIDLIST WINAPI
ILGetNext(LPITEMIDLIST pidl
)
353 { LPITEMIDLIST nextpidl
;
355 /* TRACE(pidl,"(pidl=%p)\n",pidl);*/
357 { nextpidl
= (LPITEMIDLIST
)(LPBYTE
)(((LPBYTE
)pidl
) + pidl
->mkid
.cb
);
364 /*************************************************************************
365 * ILAppend [SHELL32.154]
368 * Adds the single item to the idlist indicated by pidl.
369 * if bEnd is 0, adds the item to the front of the list,
370 * otherwise adds the item to the end. (???)
371 * Destroys the passed in idlist! (???)
373 LPITEMIDLIST WINAPI
ILAppend(LPITEMIDLIST pidl
,LPCITEMIDLIST item
,BOOL32 bEnd
)
374 { LPITEMIDLIST idlRet
;
375 WARN(pidl
,"(pidl=%p,pidl=%p,%08u)semi-stub\n",pidl
,item
,bEnd
);
379 if (_ILIsDesktop(pidl
))
380 { idlRet
= ILClone(item
);
385 idlRet
=ILCombine(pidl
,item
);
389 /*************************************************************************
390 * ILFree [SHELL32.155]
393 * free_check_ptr - frees memory (if not NULL)
394 * allocated by SHMalloc allocator
395 * exported by ordinal
397 DWORD WINAPI
ILFree(LPVOID pidl
)
398 { TRACE(pidl
,"(pidl=0x%08lx)\n",(DWORD
)pidl
);
403 /*************************************************************************
404 * ILCreateFromPath [SHELL32.157]
407 LPITEMIDLIST WINAPI
ILCreateFromPath(LPVOID path
)
408 { LPSHELLFOLDER shellfolder
;
409 LPITEMIDLIST pidlnew
;
410 WCHAR lpszDisplayName
[MAX_PATH
];
413 if ( !VERSION_OsIsUnicode())
414 { TRACE(pidl
,"(path=%s)\n",(LPSTR
)path
);
415 LocalToWideChar32(lpszDisplayName
, path
, MAX_PATH
);
418 { TRACE(pidl
,"(path=L%s)\n",debugstr_w(path
));
419 lstrcpy32W(lpszDisplayName
, path
);
422 if (SHGetDesktopFolder(&shellfolder
)==S_OK
)
423 { shellfolder
->lpvtbl
->fnParseDisplayName(shellfolder
,0, NULL
,lpszDisplayName
,&pchEaten
,&pidlnew
,NULL
);
424 shellfolder
->lpvtbl
->fnRelease(shellfolder
);
428 /*************************************************************************
429 * SHSimpleIDListFromPath [SHELL32.162]
432 LPITEMIDLIST WINAPI
SHSimpleIDListFromPath32AW (LPVOID lpszPath
)
433 { LPCSTR lpszElement
;
434 char lpszTemp
[MAX_PATH
];
439 if ( VERSION_OsIsUnicode())
440 { TRACE(pidl
,"(path=L%s)\n",debugstr_w((LPWSTR
)lpszPath
));
441 WideCharToLocal32(lpszTemp
, lpszPath
, MAX_PATH
);
444 { TRACE(pidl
,"(path=%s)\n",(LPSTR
)lpszPath
);
445 strcpy(lpszTemp
, lpszPath
);
448 lpszElement
= PathFindFilename32A(lpszTemp
);
449 if( GetFileAttributes32A(lpszTemp
) & FILE_ATTRIBUTE_DIRECTORY
)
450 { return _ILCreateFolder(lpszElement
);
452 return _ILCreateValue(lpszElement
);
455 /**************************************************************************
459 /**************************************************************************
461 * _ILCreateMyComputer()
466 LPITEMIDLIST WINAPI
_ILCreateDesktop()
467 { TRACE(pidl
,"()\n");
468 return _ILCreate(PT_DESKTOP
, NULL
, 0);
470 LPITEMIDLIST WINAPI
_ILCreateMyComputer()
471 { TRACE(pidl
,"()\n");
472 return _ILCreate(PT_MYCOMP
, (void *)"My Computer", strlen ("My Computer")+1);
474 LPITEMIDLIST WINAPI
_ILCreateDrive( LPCSTR lpszNew
)
476 strncpy (sTemp
,lpszNew
,4);
479 TRACE(pidl
,"(%s)\n",sTemp
);
480 return _ILCreate(PT_DRIVE
,(LPVOID
)&sTemp
[0],4);
482 LPITEMIDLIST WINAPI
_ILCreateFolder( LPCSTR lpszNew
)
483 { TRACE(pidl
,"(%s)\n",lpszNew
);
484 return _ILCreate(PT_FOLDER
, (LPVOID
)lpszNew
, strlen(lpszNew
)+1);
486 LPITEMIDLIST WINAPI
_ILCreateValue(LPCSTR lpszNew
)
487 { TRACE(pidl
,"(%s)\n",lpszNew
);
488 return _ILCreate(PT_VALUE
, (LPVOID
)lpszNew
, strlen(lpszNew
)+1);
491 /**************************************************************************
496 BOOL32 WINAPI
_ILGetDrive(LPCITEMIDLIST pidl
,LPSTR pOut
, UINT16 uSize
)
497 { LPITEMIDLIST pidlTemp
=NULL
;
499 TRACE(pidl
,"(%p,%p,%u)\n",pidl
,pOut
,uSize
);
500 if(_ILIsMyComputer(pidl
))
501 { pidlTemp
= ILGetNext(pidl
);
503 else if (pidlTemp
&& _ILIsDrive(pidlTemp
))
504 { return (BOOL32
)_ILGetData(PT_DRIVE
, pidlTemp
, (LPVOID
)pOut
, uSize
);
508 /**************************************************************************
510 * Gets the text for only this item
512 DWORD WINAPI
_ILGetItemText(LPCITEMIDLIST pidl
, LPSTR lpszText
, UINT16 uSize
)
513 { TRACE(pidl
,"(pidl=%p %p %x)\n",pidl
,lpszText
,uSize
);
514 if (_ILIsMyComputer(pidl
))
515 { return _ILGetData(PT_MYCOMP
, pidl
, (LPVOID
)lpszText
, uSize
);
517 if (_ILIsDrive(pidl
))
518 { return _ILGetData(PT_DRIVE
, pidl
, (LPVOID
)lpszText
, uSize
);
520 if (_ILIsFolder (pidl
))
521 { return _ILGetData(PT_FOLDER
, pidl
, (LPVOID
)lpszText
, uSize
);
523 return _ILGetData(PT_VALUE
, pidl
, (LPVOID
)lpszText
, uSize
);
525 /**************************************************************************
531 BOOL32 WINAPI
_ILIsDesktop(LPCITEMIDLIST pidl
)
532 { TRACE(pidl
,"(%p)\n",pidl
);
537 return ( pidl
->mkid
.cb
== 0x00 );
540 BOOL32 WINAPI
_ILIsMyComputer(LPCITEMIDLIST pidl
)
542 TRACE(pidl
,"(%p)\n",pidl
);
547 pData
= _ILGetDataPointer(pidl
);
548 return (PT_MYCOMP
== pData
->type
);
551 BOOL32 WINAPI
_ILIsDrive(LPCITEMIDLIST pidl
)
553 TRACE(pidl
,"(%p)\n",pidl
);
558 pData
= _ILGetDataPointer(pidl
);
559 return (PT_DRIVE
== pData
->type
);
562 BOOL32 WINAPI
_ILIsFolder(LPCITEMIDLIST pidl
)
564 TRACE(pidl
,"(%p)\n",pidl
);
569 pData
= _ILGetDataPointer(pidl
);
570 return (PT_FOLDER
== pData
->type
);
573 BOOL32 WINAPI
_ILIsValue(LPCITEMIDLIST pidl
)
575 TRACE(pidl
,"(%p)\n",pidl
);
580 pData
= _ILGetDataPointer(pidl
);
581 return (PT_VALUE
== pData
->type
);
583 /**************************************************************************
587 BOOL32 WINAPI
_ILHasFolders( LPSTR pszPath
, LPCITEMIDLIST pidl
)
588 { BOOL32 bResult
= FALSE
;
589 WIN32_FIND_DATA32A stffile
;
592 TRACE(pidl
,"%p %p\n", pszPath
, pidl
);
594 hFile
= FindFirstFile32A(pszPath
,&stffile
);
596 { if (! (stffile
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) )
599 } while( FindNextFile32A(hFile
,&stffile
));
605 /**************************************************************************
607 * Creates a Path string from a PIDL, filtering out the special Folders
609 DWORD WINAPI
_ILGetFolderText(LPCITEMIDLIST pidl
,LPSTR lpszPath
, DWORD dwSize
)
610 { LPITEMIDLIST pidlTemp
;
614 TRACE(pidl
,"(%p path=%p)\n",pidl
, lpszPath
);
620 if(_ILIsMyComputer(pidl
))
621 { pidlTemp
= ILGetNext(pidl
);
622 TRACE(pidl
,"-- skip My Computer\n");
625 { pidlTemp
= (LPITEMIDLIST
)pidl
;
628 //if this is NULL, return the required size of the buffer
630 { while(pidlTemp
->mkid
.cb
)
631 { LPPIDLDATA pData
= _ILGetDataPointer(pidlTemp
);
632 pText
= _ILGetTextPointer(pData
->type
,pData
);
634 /*add the length of this item plus one for the backslash
635 fixme: is one to much, drive has its own backslash*/
636 dwCopied
+= strlen(pText
) + 1;
637 pidlTemp
= ILGetNext(pidlTemp
);
640 //add one for the NULL terminator
641 TRACE(pidl
,"-- (size=%lu)\n",dwCopied
);
647 while(pidlTemp
->mkid
.cb
&& (dwCopied
< dwSize
))
648 { LPPIDLDATA pData
= _ILGetDataPointer(pidlTemp
);
650 //if this item is a value, then skip it and finish
651 if(PT_VALUE
== pData
->type
)
654 pText
= _ILGetTextPointer(pData
->type
,pData
);
655 strcat(lpszPath
, pText
);
656 PathAddBackslash32A(lpszPath
);
657 dwCopied
+= strlen(pText
) + 1;
658 pidlTemp
= ILGetNext(pidlTemp
);
660 TRACE(pidl
,"-- (size=%lu,%s)\n",dwCopied
,lpszPath
);
663 //remove the last backslash if necessary
665 { if(*(lpszPath
+ strlen(lpszPath
) - 1) == '\\')
666 { *(lpszPath
+ strlen(lpszPath
) - 1) = 0;
670 TRACE(pidl
,"-- (path=%s)\n",lpszPath
);
675 /**************************************************************************
677 * Gets the text for the last item in the list
679 DWORD WINAPI
_ILGetValueText(
680 LPCITEMIDLIST pidl
, LPSTR lpszValue
, DWORD dwSize
)
681 { LPITEMIDLIST pidlTemp
=pidl
;
682 CHAR szText
[MAX_PATH
];
684 TRACE(pidl
,"(pidl=%p %p 0x%08lx)\n",pidl
,lpszValue
,dwSize
);
690 while(pidlTemp
->mkid
.cb
&& !_ILIsValue(pidlTemp
))
691 { pidlTemp
= ILGetNext(pidlTemp
);
694 if(!pidlTemp
->mkid
.cb
)
698 _ILGetItemText( pidlTemp
, szText
, sizeof(szText
));
701 { return strlen(szText
) + 1;
703 strcpy(lpszValue
, szText
);
704 TRACE(pidl
,"-- (pidl=%p %p=%s 0x%08lx)\n",pidl
,lpszValue
,lpszValue
,dwSize
);
705 return strlen(lpszValue
);
707 /**************************************************************************
710 * used from ShellView
712 DWORD WINAPI
_ILGetDataText( LPCITEMIDLIST pidlPath
, LPCITEMIDLIST pidlValue
, LPSTR lpszOut
, DWORD dwOutSize
)
717 FIXME(pidl
,"(pidl=%p pidl=%p) stub\n",pidlPath
,pidlValue
);
719 if(!lpszOut
|| !pidlPath
|| !pidlValue
)
723 /* fixme: get the driveletter*/
725 //assemble the Folder string
726 dwNameSize
= _ILGetFolderText(pidlPath
, NULL
, 0);
727 lpszFolder
= (LPSTR
)HeapAlloc(GetProcessHeap(),0,dwNameSize
);
731 _ILGetFolderText(pidlPath
, lpszFolder
, dwNameSize
);
733 //assemble the value name
734 dwNameSize
= _ILGetValueText(pidlValue
, NULL
, 0);
735 lpszValueName
= (LPSTR
)HeapAlloc(GetProcessHeap(),0,dwNameSize
);
737 { HeapFree(GetProcessHeap(),0,lpszFolder
);
740 _ILGetValueText(pidlValue
, lpszValueName
, dwNameSize
);
742 /* fixme: we've got the path now do something with it*/
744 HeapFree(GetProcessHeap(),0,lpszFolder
);
745 HeapFree(GetProcessHeap(),0,lpszValueName
);
747 TRACE(pidl
,"-- (%p=%s 0x%08lx)\n",lpszOut
,lpszOut
,dwOutSize
);
752 /**************************************************************************
754 * Create a string that includes the Drive name, the folder text and
757 DWORD WINAPI
_ILGetPidlPath( LPCITEMIDLIST pidl
, LPSTR lpszOut
, DWORD dwOutSize
)
761 TRACE(pidl
,"(%p,%lu)\n",lpszOut
,dwOutSize
);
770 dwOutSize
-= _ILGetFolderText(pidl
, lpszTemp
, dwOutSize
);
772 //add a backslash if necessary
773 len
= strlen(lpszTemp
);
774 if (len
&& lpszTemp
[len
-1]!='\\')
775 { lpszTemp
[len
+0]='\\';
776 lpszTemp
[len
+1]='\0';
780 lpszTemp
= lpszOut
+ strlen(lpszOut
);
782 //add the value string
783 _ILGetValueText(pidl
, lpszTemp
, dwOutSize
);
785 //remove the last backslash if necessary
786 if(*(lpszOut
+ strlen(lpszOut
) - 1) == '\\')
787 { *(lpszOut
+ strlen(lpszOut
) - 1) = 0;
790 TRACE(pidl
,"-- (%p=%s,%lu)\n",lpszOut
,lpszOut
,dwOutSize
);
792 return strlen(lpszOut
);
796 /**************************************************************************
799 * type = PT_DESKTOP | PT_DRIVE | PT_FOLDER | PT_VALUE
801 * uInSize = size of data
804 LPITEMIDLIST WINAPI
_ILCreate(PIDLTYPE type
, LPVOID pIn
, UINT16 uInSize
)
805 { LPITEMIDLIST pidlOut
=NULL
;
807 LPITEMIDLIST pidlTemp
=NULL
;
811 TRACE(pidl
,"(%x %p %x)\n",type
,pIn
,uInSize
);
813 if ( type
== PT_DESKTOP
)
814 { pidlOut
= SHAlloc(2);
815 pidlOut
->mkid
.cb
=0x0000;
823 /* the sizes of: cb(2), pidldata-1, szText+1, next cb(2) */
829 uSize
= 4 + (sizeof(PIDLDATA
)) + uInSize
;
831 pidlOut
= SHAlloc(uSize
);
834 { pidlTemp
->mkid
.cb
= uSize
- 2;
835 pData
=_ILGetDataPointer(pidlTemp
);
836 pszDest
= _ILGetTextPointer(type
, pData
);
840 memcpy(pszDest
, pIn
, uInSize
);
841 TRACE(pidl
,"- create My Computer: %s\n",debugstr_a(pszDest
));
844 memcpy(pszDest
, pIn
, uInSize
);
845 TRACE(pidl
,"- create Drive: %s\n",debugstr_a(pszDest
));
849 memcpy(pszDest
, pIn
, uInSize
);
850 TRACE(pidl
,"- create Value: %s\n",debugstr_a(pszDest
));
853 FIXME(pidl
,"-- wrong argument\n");
857 pidlTemp
= ILGetNext(pidlTemp
);
858 pidlTemp
->mkid
.cb
= 0x00;
860 TRACE(pidl
,"-- (pidl=%p, size=%u)\n",pidlOut
,uSize
-2);
863 /**************************************************************************
864 * _ILGetData(PIDLTYPE, LPCITEMIDLIST, LPVOID, UINT16)
866 DWORD WINAPI
_ILGetData(PIDLTYPE type
, LPCITEMIDLIST pidl
, LPVOID pOut
, UINT32 uOutSize
)
871 TRACE(pidl
,"(%x %p %p %x)\n",type
,pidl
,pOut
,uOutSize
);
879 pData
= _ILGetDataPointer(pidl
);
880 if ( pData
->type
!= type
)
881 { ERR(pidl
,"-- wrong type\n");
884 pszSrc
= _ILGetTextPointer(pData
->type
, pData
);
890 strncpy((LPSTR
)pOut
, "My Computer", uOutSize
);
891 dwReturn
= strlen((LPSTR
)pOut
);
897 strncpy((LPSTR
)pOut
, pszSrc
, uOutSize
);
898 dwReturn
= strlen((LPSTR
)pOut
);
903 strncpy((LPSTR
)pOut
, pszSrc
, uOutSize
);
904 dwReturn
= strlen((LPSTR
)pOut
);
907 ERR(pidl
,"-- unknown type\n");
910 TRACE(pidl
,"-- (%p=%s 0x%08lx)\n",pOut
,(char*)pOut
,dwReturn
);
915 /**************************************************************************
916 * _ILGetDataPointer()
918 LPPIDLDATA WINAPI
_ILGetDataPointer(LPITEMIDLIST pidl
)
922 /* TRACE(pidl,"(%p)\n", pidl);*/
923 return (LPPIDLDATA
)(&pidl
->mkid
.abID
);
925 /**************************************************************************
926 * _ILGetTextPointer()
927 * gets a pointer to the string stored in the pidl
929 LPSTR WINAPI
_ILGetTextPointer(PIDLTYPE type
, LPPIDLDATA pidldata
)
930 {/* TRACE(pidl,"(type=%x data=%p)\n", type, pidldata);*/
937 return (LPSTR
)&(pidldata
->u
.drive
.szDriveName
);
941 return (LPSTR
)&(pidldata
->u
.file
.szText
);
945 BOOL32 WINAPI
_ILGetFileDate (LPCITEMIDLIST pidl
, LPSTR pOut
, UINT32 uOutSize
)
946 { LPPIDLDATA pdata
=_ILGetDataPointer(pidl
);
955 DosDateTimeToFileTime(pdata
->u
.folder
.uFileDate
, pdata
->u
.folder
.uFileTime
, &ft
);
958 DosDateTimeToFileTime(pdata
->u
.file
.uFileDate
, pdata
->u
.file
.uFileTime
, &ft
);
963 FileTimeToSystemTime (&ft
, &time
);
964 return GetDateFormat32A(LOCALE_USER_DEFAULT
,DATE_SHORTDATE
,&time
, NULL
, pOut
, uOutSize
);
966 BOOL32 WINAPI
_ILGetFileSize (LPCITEMIDLIST pidl
, LPSTR pOut
, UINT32 uOutSize
)
967 { LPPIDLDATA pdata
=_ILGetDataPointer(pidl
);
968 char stemp
[20]; /* for filesize */
980 sprintf(stemp
,"%lu", pdata
->u
.file
.dwFileSize
);
981 return GetNumberFormat32A(LOCALE_USER_DEFAULT
, 0, stemp
, NULL
, pOut
, uOutSize
);
983 /**************************************************************************
984 * IDLList "Item ID List List"
987 static UINT32 WINAPI
IDLList_GetState(LPIDLLIST
this);
988 static LPITEMIDLIST WINAPI
IDLList_GetElement(LPIDLLIST
this, UINT32 nIndex
);
989 static UINT32 WINAPI
IDLList_GetCount(LPIDLLIST
this);
990 static BOOL32 WINAPI
IDLList_StoreItem(LPIDLLIST
this, LPITEMIDLIST pidl
);
991 static BOOL32 WINAPI
IDLList_AddItems(LPIDLLIST
this, LPITEMIDLIST
*apidl
, UINT32 cidl
);
992 static BOOL32 WINAPI
IDLList_InitList(LPIDLLIST
this);
993 static void WINAPI
IDLList_CleanList(LPIDLLIST
this);
995 static IDLList_VTable idllvt
=
1005 LPIDLLIST
IDLList_Constructor (UINT32 uStep
)
1007 if (!(lpidll
= (LPIDLLIST
)HeapAlloc(GetProcessHeap(),0,sizeof(IDLList
))))
1010 lpidll
->lpvtbl
=&idllvt
;
1011 lpidll
->uStep
=uStep
;
1014 TRACE (shell
,"(%p)\n",lpidll
);
1017 void IDLList_Destructor(LPIDLLIST
this)
1018 { TRACE (shell
,"(%p)\n",this);
1019 IDLList_CleanList(this);
1022 static UINT32 WINAPI
IDLList_GetState(LPIDLLIST
this)
1023 { TRACE (shell
,"(%p)->(uStep=%u dpa=%p)\n",this, this->uStep
, this->dpa
);
1025 if (this->uStep
== 0)
1028 return(State_OutOfMem
);
1030 return(State_UnInit
);
1032 static LPITEMIDLIST WINAPI
IDLList_GetElement(LPIDLLIST
this, UINT32 nIndex
)
1033 { TRACE (shell
,"(%p)->(index=%u)\n",this, nIndex
);
1034 return((LPITEMIDLIST
)pDPA_GetPtr(this->dpa
, nIndex
));
1036 static UINT32 WINAPI
IDLList_GetCount(LPIDLLIST
this)
1037 { TRACE (shell
,"(%p)\n",this);
1038 return(IDLList_GetState(this)==State_Init
? DPA_GetPtrCount(this->dpa
) : 0);
1040 static BOOL32 WINAPI
IDLList_StoreItem(LPIDLLIST
this, LPITEMIDLIST pidl
)
1041 { TRACE (shell
,"(%p)->(pidl=%p)\n",this, pidl
);
1043 { if (IDLList_InitList(this) && pDPA_InsertPtr(this->dpa
, 0x7fff, (LPSTR
)pidl
)>=0)
1047 IDLList_CleanList(this);
1050 static BOOL32 WINAPI
IDLList_AddItems(LPIDLLIST
this, LPITEMIDLIST
*apidl
, UINT32 cidl
)
1052 TRACE (shell
,"(%p)->(apidl=%p cidl=%u)\n",this, apidl
, cidl
);
1054 for (i
=0; i
<cidl
; ++i
)
1055 { if (!IDLList_StoreItem(this, ILClone((LPCITEMIDLIST
)apidl
[i
])))
1060 static BOOL32 WINAPI
IDLList_InitList(LPIDLLIST
this)
1061 { TRACE (shell
,"(%p)\n",this);
1062 switch (IDLList_GetState(this))
1066 case State_OutOfMem
:
1071 this->dpa
= pDPA_Create(this->uStep
);
1073 return(IDLList_InitList(this));
1076 static void WINAPI
IDLList_CleanList(LPIDLLIST
this)
1078 TRACE (shell
,"(%p)\n",this);
1080 if (this->uStep
!= 0)
1090 for (i
=DPA_GetPtrCount(this->dpa
)-1; i
>=0; --i
)
1091 { ILFree(IDLList_GetElement(this,i
));
1094 pDPA_Destroy(this->dpa
);