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 pidl
,LPSTR path
)
57 { FIXME(shell
,"pidl=%p %p semi-stub\n",pidl
,path
);
58 return SHGetPathFromIDList32A(pidl
, path
);
60 /*************************************************************************
61 * ILFindLastID [SHELL32.16]
63 LPITEMIDLIST WINAPI
ILFindLastID(LPITEMIDLIST pidl
)
64 { LPITEMIDLIST pidlLast
= NULL
;
66 TRACE(pidl
,"(pidl=%p)\n",pidl
);
69 { while(pidl
->mkid
.cb
)
70 { pidlLast
= (LPITEMIDLIST
)pidl
;
71 pidl
= ILGetNext(pidl
);
76 /*************************************************************************
77 * ILRemoveLastID [SHELL32.17]
79 * Removes the last item
81 BOOL32 WINAPI
ILRemoveLastID(LPCITEMIDLIST pidl
)
82 { TRACE(shell
,"pidl=%p\n",pidl
);
83 if (!pidl
|| !pidl
->mkid
.cb
)
85 ILFindLastID(pidl
)->mkid
.cb
= 0;
89 /*************************************************************************
90 * ILClone [SHELL32.18]
95 LPITEMIDLIST WINAPI
ILClone (LPCITEMIDLIST pidl
)
102 len
= ILGetSize(pidl
);
103 newpidl
= (LPITEMIDLIST
)SHAlloc(len
);
105 memcpy(newpidl
,pidl
,len
);
107 TRACE(pidl
,"pidl=%p newpidl=%p\n",pidl
, newpidl
);
112 /*************************************************************************
113 * ILCloneFirst [SHELL32.19]
116 * duplicates the first idlist of a complex pidl
118 LPITEMIDLIST WINAPI
ILCloneFirst(LPCITEMIDLIST pidl
)
120 LPITEMIDLIST newpidl
=NULL
;
122 TRACE(pidl
,"pidl=%p \n",pidl
);
126 { len
= pidl
->mkid
.cb
;
127 newpidl
= (LPITEMIDLIST
) SHAlloc (len
+2);
129 { memcpy(newpidl
,pidl
,len
);
130 ILGetNext(newpidl
)->mkid
.cb
= 0x00;
133 TRACE(pidl
,"-- newpidl=%p\n",newpidl
);
137 /*************************************************************************
138 * ILGlobalClone [SHELL32.97]
141 LPITEMIDLIST WINAPI
ILGlobalClone(LPCITEMIDLIST pidl
)
143 LPITEMIDLIST newpidl
;
148 len
= ILGetSize(pidl
);
149 newpidl
= (LPITEMIDLIST
)pCOMCTL32_Alloc(len
);
151 memcpy(newpidl
,pidl
,len
);
153 TRACE(pidl
,"pidl=%p newpidl=%p\n",pidl
, newpidl
);
159 /*************************************************************************
160 * ILIsEqual [SHELL32.21]
163 BOOL32 WINAPI
ILIsEqual(LPCITEMIDLIST pidl1
, LPCITEMIDLIST pidl2
)
164 { LPPIDLDATA ppidldata
;
168 LPITEMIDLIST pidltemp1
= pidl1
;
169 LPITEMIDLIST pidltemp2
= pidl2
;
171 TRACE(pidl
,"pidl1=%p pidl2=%p\n",pidl1
, pidl2
);
176 if ( (!pidl1
) || (!pidl2
) )
180 if (pidltemp1
->mkid
.cb
&& pidltemp2
->mkid
.cb
)
182 { ppidldata
= _ILGetDataPointer(pidltemp1
);
183 szData1
= _ILGetTextPointer(ppidldata
->type
, ppidldata
);
185 ppidldata
= _ILGetDataPointer(pidltemp2
);
186 szData2
= _ILGetTextPointer(ppidldata
->type
, ppidldata
);
188 if (strcmp ( szData1
, szData2
)!=0 )
191 pidltemp1
= ILGetNext(pidltemp1
);
192 pidltemp2
= ILGetNext(pidltemp2
);
194 } while (pidltemp1
->mkid
.cb
&& pidltemp2
->mkid
.cb
);
196 if (!pidltemp1
->mkid
.cb
&& !pidltemp2
->mkid
.cb
)
197 { TRACE(shell
, "--- equal\n");
203 /*************************************************************************
204 * ILIsParent [SHELL32.23]
207 DWORD WINAPI
ILIsParent( DWORD x
, DWORD y
, DWORD z
)
208 { FIXME(pidl
,"0x%08lx 0x%08lx 0x%08lx stub\n",x
,y
,z
);
212 /*************************************************************************
213 * ILFindChild [SHELL32.24]
216 * Compares elements from pidl1 and pidl2.
217 * When at least the first element is equal, it gives a pointer
218 * to the first different element of pidl 2 back.
219 * Returns 0 if pidl 2 is shorter.
221 LPITEMIDLIST WINAPI
ILFindChild(LPCITEMIDLIST pidl1
,LPCITEMIDLIST pidl2
)
222 { LPPIDLDATA ppidldata
;
226 LPITEMIDLIST pidltemp1
= pidl1
;
227 LPITEMIDLIST pidltemp2
= pidl2
;
228 LPITEMIDLIST ret
=NULL
;
230 TRACE(pidl
,"pidl1=%p pidl2=%p\n",pidl1
, pidl2
);
235 if ( !pidl1
|| !pidl1
->mkid
.cb
) /* pidl 1 is desktop (root) */
236 { TRACE(shell
, "--- %p\n", pidl2
);
240 if (pidltemp1
->mkid
.cb
&& pidltemp2
->mkid
.cb
)
242 { ppidldata
= _ILGetDataPointer(pidltemp1
);
243 szData1
= _ILGetTextPointer(ppidldata
->type
, ppidldata
);
245 ppidldata
= _ILGetDataPointer(pidltemp2
);
246 szData2
= _ILGetTextPointer(ppidldata
->type
, ppidldata
);
248 pidltemp2
= ILGetNext(pidltemp2
); /* points behind the pidl2 */
250 if (strcmp(szData1
,szData2
) == 0)
251 { ret
= pidltemp2
; /* found equal element */
254 { if (ret
) /* different element after equal -> break */
259 pidltemp1
= ILGetNext(pidltemp1
);
260 } while (pidltemp1
->mkid
.cb
&& pidltemp2
->mkid
.cb
);
263 if (!pidltemp2
->mkid
.cb
)
264 { return NULL
; /* complete equal or pidl 2 is shorter */
267 TRACE(shell
, "--- %p\n", ret
);
268 return ret
; /* pidl 1 is shorter */
271 /*************************************************************************
272 * ILCombine [SHELL32.25]
275 * Concatenates two complex idlists.
276 * The pidl is the first one, pidlsub the next one
277 * Does not destroy the passed in idlists!
279 LPITEMIDLIST WINAPI
ILCombine(LPCITEMIDLIST pidl1
,LPCITEMIDLIST pidl2
)
281 LPITEMIDLIST pidlNew
;
283 TRACE(pidl
,"pidl=%p pidl=%p\n",pidl1
,pidl2
);
293 { pidlNew
= ILClone(pidl2
);
298 { pidlNew
= ILClone(pidl1
);
302 len1
= ILGetSize(pidl1
)-2;
303 len2
= ILGetSize(pidl2
);
304 pidlNew
= SHAlloc(len1
+len2
);
307 { memcpy(pidlNew
,pidl1
,len1
);
308 memcpy(((BYTE
*)pidlNew
)+len1
,pidl2
,len2
);
311 /* TRACE(pidl,"--new pidl=%p\n",pidlNew);*/
314 /*************************************************************************
315 * SHGetRealIDL [SHELL32.98]
319 LPITEMIDLIST WINAPI
SHGetRealIDL(DWORD x
, DWORD y
, DWORD z
)
320 { FIXME(pidl
,"0x%04lx 0x%04lx 0x%04lx\n",x
,y
,z
);
324 /*************************************************************************
325 * SHLogILFromFSIL [SHELL32.95]
329 LPITEMIDLIST WINAPI
SHLogILFromFSIL(LPITEMIDLIST pidl
)
330 { FIXME(pidl
,"(pidl=%p)\n",pidl
);
335 /*************************************************************************
336 * ILGetSize [SHELL32.152]
337 * gets the byte size of an idlist including zero terminator (pidl)
346 * exported by ordinal
348 DWORD WINAPI
ILGetSize(LPITEMIDLIST pidl
)
349 { LPSHITEMID si
= &(pidl
->mkid
);
355 si
= (LPSHITEMID
)(((LPBYTE
)si
)+si
->cb
);
359 TRACE(pidl
,"pidl=%p size=%lu\n",pidl
, len
);
362 /*************************************************************************
363 * ILGetNext [SHELL32.153]
364 * gets the next simple pidl of a complex pidl
370 * pointer to next element
373 LPITEMIDLIST WINAPI
ILGetNext(LPITEMIDLIST pidl
)
374 { LPITEMIDLIST nextpidl
;
376 /* TRACE(pidl,"(pidl=%p)\n",pidl);*/
378 { nextpidl
= (LPITEMIDLIST
)(LPBYTE
)(((LPBYTE
)pidl
) + pidl
->mkid
.cb
);
385 /*************************************************************************
386 * ILAppend [SHELL32.154]
389 * Adds the single item to the idlist indicated by pidl.
390 * if bEnd is 0, adds the item to the front of the list,
391 * otherwise adds the item to the end. (???)
392 * Destroys the passed in idlist! (???)
394 LPITEMIDLIST WINAPI
ILAppend(LPITEMIDLIST pidl
,LPCITEMIDLIST item
,BOOL32 bEnd
)
395 { LPITEMIDLIST idlRet
;
396 WARN(pidl
,"(pidl=%p,pidl=%p,%08u)semi-stub\n",pidl
,item
,bEnd
);
400 if (_ILIsDesktop(pidl
))
401 { idlRet
= ILClone(item
);
407 { idlRet
=ILCombine(pidl
,item
);
410 { idlRet
=ILCombine(item
,pidl
);
415 /*************************************************************************
416 * ILFree [SHELL32.155]
419 * free_check_ptr - frees memory (if not NULL)
420 * allocated by SHMalloc allocator
421 * exported by ordinal
423 DWORD WINAPI
ILFree(LPITEMIDLIST pidl
)
424 { TRACE(pidl
,"(pidl=0x%08lx)\n",(DWORD
)pidl
);
431 /*************************************************************************
432 * ILGlobalFree [SHELL32.156]
435 DWORD WINAPI
ILGlobalFree( LPITEMIDLIST pidl
)
436 { TRACE(pidl
,"%p\n",pidl
);
441 return pCOMCTL32_Free (pidl
);
443 /*************************************************************************
444 * ILCreateFromPath [SHELL32.157]
447 LPITEMIDLIST WINAPI
ILCreateFromPath(LPVOID path
)
448 { LPSHELLFOLDER shellfolder
;
449 LPITEMIDLIST pidlnew
;
450 WCHAR lpszDisplayName
[MAX_PATH
];
453 if ( !VERSION_OsIsUnicode())
454 { TRACE(pidl
,"(path=%s)\n",(LPSTR
)path
);
455 LocalToWideChar32(lpszDisplayName
, path
, MAX_PATH
);
458 { TRACE(pidl
,"(path=L%s)\n",debugstr_w(path
));
459 lstrcpy32W(lpszDisplayName
, path
);
462 if (SHGetDesktopFolder(&shellfolder
)==S_OK
)
463 { shellfolder
->lpvtbl
->fnParseDisplayName(shellfolder
,0, NULL
,lpszDisplayName
,&pchEaten
,&pidlnew
,NULL
);
464 shellfolder
->lpvtbl
->fnRelease(shellfolder
);
468 /*************************************************************************
469 * SHSimpleIDListFromPath [SHELL32.162]
472 LPITEMIDLIST WINAPI
SHSimpleIDListFromPath32AW (LPVOID lpszPath
)
473 { LPCSTR lpszElement
;
474 char lpszTemp
[MAX_PATH
];
479 if ( VERSION_OsIsUnicode())
480 { TRACE(pidl
,"(path=L%s)\n",debugstr_w((LPWSTR
)lpszPath
));
481 WideCharToLocal32(lpszTemp
, lpszPath
, MAX_PATH
);
484 { TRACE(pidl
,"(path=%s)\n",(LPSTR
)lpszPath
);
485 strcpy(lpszTemp
, lpszPath
);
488 lpszElement
= PathFindFilename32A(lpszTemp
);
489 if( GetFileAttributes32A(lpszTemp
) & FILE_ATTRIBUTE_DIRECTORY
)
490 { return _ILCreateFolder(lpszElement
);
492 return _ILCreateValue(lpszElement
);
495 /**************************************************************************
499 /**************************************************************************
501 * _ILCreateMyComputer()
506 LPITEMIDLIST WINAPI
_ILCreateDesktop()
507 { TRACE(pidl
,"()\n");
508 return _ILCreate(PT_DESKTOP
, NULL
, 0);
510 LPITEMIDLIST WINAPI
_ILCreateMyComputer()
511 { TRACE(pidl
,"()\n");
512 return _ILCreate(PT_MYCOMP
, (void *)"My Computer", strlen ("My Computer")+1);
514 LPITEMIDLIST WINAPI
_ILCreateDrive( LPCSTR lpszNew
)
516 strncpy (sTemp
,lpszNew
,4);
519 TRACE(pidl
,"(%s)\n",sTemp
);
520 return _ILCreate(PT_DRIVE
,(LPVOID
)&sTemp
[0],4);
522 LPITEMIDLIST WINAPI
_ILCreateFolder( LPCSTR lpszNew
)
523 { TRACE(pidl
,"(%s)\n",lpszNew
);
524 return _ILCreate(PT_FOLDER
, (LPVOID
)lpszNew
, strlen(lpszNew
)+1);
526 LPITEMIDLIST WINAPI
_ILCreateValue(LPCSTR lpszNew
)
527 { TRACE(pidl
,"(%s)\n",lpszNew
);
528 return _ILCreate(PT_VALUE
, (LPVOID
)lpszNew
, strlen(lpszNew
)+1);
531 /**************************************************************************
536 BOOL32 WINAPI
_ILGetDrive(LPCITEMIDLIST pidl
,LPSTR pOut
, UINT16 uSize
)
537 { LPITEMIDLIST pidlTemp
=NULL
;
539 TRACE(pidl
,"(%p,%p,%u)\n",pidl
,pOut
,uSize
);
540 if(_ILIsMyComputer(pidl
))
541 { pidlTemp
= ILGetNext(pidl
);
543 else if (pidlTemp
&& _ILIsDrive(pidlTemp
))
544 { return (BOOL32
)_ILGetData(PT_DRIVE
, pidlTemp
, (LPVOID
)pOut
, uSize
);
548 /**************************************************************************
550 * Gets the text for only this item
552 DWORD WINAPI
_ILGetItemText(LPCITEMIDLIST pidl
, LPSTR lpszText
, UINT16 uSize
)
553 { TRACE(pidl
,"(pidl=%p %p %x)\n",pidl
,lpszText
,uSize
);
554 if (_ILIsMyComputer(pidl
))
555 { return _ILGetData(PT_MYCOMP
, pidl
, (LPVOID
)lpszText
, uSize
);
557 if (_ILIsDrive(pidl
))
558 { return _ILGetData(PT_DRIVE
, pidl
, (LPVOID
)lpszText
, uSize
);
560 if (_ILIsFolder (pidl
))
561 { return _ILGetData(PT_FOLDER
, pidl
, (LPVOID
)lpszText
, uSize
);
563 return _ILGetData(PT_VALUE
, pidl
, (LPVOID
)lpszText
, uSize
);
565 /**************************************************************************
571 BOOL32 WINAPI
_ILIsDesktop(LPCITEMIDLIST pidl
)
572 { TRACE(pidl
,"(%p)\n",pidl
);
577 return ( pidl
->mkid
.cb
== 0x00 );
580 BOOL32 WINAPI
_ILIsMyComputer(LPCITEMIDLIST pidl
)
582 TRACE(pidl
,"(%p)\n",pidl
);
587 pData
= _ILGetDataPointer(pidl
);
588 return (PT_MYCOMP
== pData
->type
);
591 BOOL32 WINAPI
_ILIsDrive(LPCITEMIDLIST pidl
)
593 TRACE(pidl
,"(%p)\n",pidl
);
598 pData
= _ILGetDataPointer(pidl
);
599 return (PT_DRIVE
== pData
->type
);
602 BOOL32 WINAPI
_ILIsFolder(LPCITEMIDLIST pidl
)
604 TRACE(pidl
,"(%p)\n",pidl
);
609 pData
= _ILGetDataPointer(pidl
);
610 return (PT_FOLDER
== pData
->type
);
613 BOOL32 WINAPI
_ILIsValue(LPCITEMIDLIST pidl
)
615 TRACE(pidl
,"(%p)\n",pidl
);
620 pData
= _ILGetDataPointer(pidl
);
621 return (PT_VALUE
== pData
->type
);
623 /**************************************************************************
627 BOOL32 WINAPI
_ILHasFolders( LPSTR pszPath
, LPCITEMIDLIST pidl
)
628 { BOOL32 bResult
= FALSE
;
629 WIN32_FIND_DATA32A stffile
;
632 TRACE(pidl
,"%p %p\n", pszPath
, pidl
);
634 hFile
= FindFirstFile32A(pszPath
,&stffile
);
636 { if (! (stffile
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) )
639 } while( FindNextFile32A(hFile
,&stffile
));
645 /**************************************************************************
647 * Creates a Path string from a PIDL, filtering out the special Folders
649 DWORD WINAPI
_ILGetFolderText(LPCITEMIDLIST pidl
,LPSTR lpszPath
, DWORD dwSize
)
650 { LPITEMIDLIST pidlTemp
;
654 TRACE(pidl
,"(%p path=%p)\n",pidl
, lpszPath
);
660 if(_ILIsMyComputer(pidl
))
661 { pidlTemp
= ILGetNext(pidl
);
662 TRACE(pidl
,"-- skip My Computer\n");
665 { pidlTemp
= (LPITEMIDLIST
)pidl
;
668 /*if this is NULL, return the required size of the buffer */
670 { while(pidlTemp
->mkid
.cb
)
671 { LPPIDLDATA pData
= _ILGetDataPointer(pidlTemp
);
672 pText
= _ILGetTextPointer(pData
->type
,pData
);
674 /*add the length of this item plus one for the backslash
675 fixme: is one to much, drive has its own backslash*/
676 dwCopied
+= strlen(pText
) + 1;
677 pidlTemp
= ILGetNext(pidlTemp
);
680 /*add one for the NULL terminator */
681 TRACE(pidl
,"-- (size=%lu)\n",dwCopied
);
687 while(pidlTemp
->mkid
.cb
&& (dwCopied
< dwSize
))
688 { LPPIDLDATA pData
= _ILGetDataPointer(pidlTemp
);
690 /*if this item is a value, then skip it and finish */
691 if(PT_VALUE
== pData
->type
)
694 pText
= _ILGetTextPointer(pData
->type
,pData
);
695 strcat(lpszPath
, pText
);
696 PathAddBackslash32A(lpszPath
);
697 dwCopied
+= strlen(pText
) + 1;
698 pidlTemp
= ILGetNext(pidlTemp
);
700 TRACE(pidl
,"-- (size=%lu,%s)\n",dwCopied
,lpszPath
);
703 /*remove the last backslash if necessary */
705 { if(*(lpszPath
+ strlen(lpszPath
) - 1) == '\\')
706 { *(lpszPath
+ strlen(lpszPath
) - 1) = 0;
710 TRACE(pidl
,"-- (path=%s)\n",lpszPath
);
715 /**************************************************************************
717 * Gets the text for the last item in the list
719 DWORD WINAPI
_ILGetValueText(
720 LPCITEMIDLIST pidl
, LPSTR lpszValue
, DWORD dwSize
)
721 { LPITEMIDLIST pidlTemp
=pidl
;
722 CHAR szText
[MAX_PATH
];
724 TRACE(pidl
,"(pidl=%p %p 0x%08lx)\n",pidl
,lpszValue
,dwSize
);
730 while(pidlTemp
->mkid
.cb
&& !_ILIsValue(pidlTemp
))
731 { pidlTemp
= ILGetNext(pidlTemp
);
734 if(!pidlTemp
->mkid
.cb
)
738 _ILGetItemText( pidlTemp
, szText
, sizeof(szText
));
741 { return strlen(szText
) + 1;
743 strcpy(lpszValue
, szText
);
744 TRACE(pidl
,"-- (pidl=%p %p=%s 0x%08lx)\n",pidl
,lpszValue
,lpszValue
,dwSize
);
745 return strlen(lpszValue
);
747 /**************************************************************************
750 * used from ShellView
752 DWORD WINAPI
_ILGetDataText( LPCITEMIDLIST pidlPath
, LPCITEMIDLIST pidlValue
, LPSTR lpszOut
, DWORD dwOutSize
)
757 FIXME(pidl
,"(pidl=%p pidl=%p) stub\n",pidlPath
,pidlValue
);
759 if(!lpszOut
|| !pidlPath
|| !pidlValue
)
763 /* fixme: get the driveletter*/
765 /*assemble the Folder string */
766 dwNameSize
= _ILGetFolderText(pidlPath
, NULL
, 0);
767 lpszFolder
= (LPSTR
)HeapAlloc(GetProcessHeap(),0,dwNameSize
);
771 _ILGetFolderText(pidlPath
, lpszFolder
, dwNameSize
);
773 /*assemble the value name */
774 dwNameSize
= _ILGetValueText(pidlValue
, NULL
, 0);
775 lpszValueName
= (LPSTR
)HeapAlloc(GetProcessHeap(),0,dwNameSize
);
777 { HeapFree(GetProcessHeap(),0,lpszFolder
);
780 _ILGetValueText(pidlValue
, lpszValueName
, dwNameSize
);
782 /* fixme: we've got the path now do something with it*/
784 HeapFree(GetProcessHeap(),0,lpszFolder
);
785 HeapFree(GetProcessHeap(),0,lpszValueName
);
787 TRACE(pidl
,"-- (%p=%s 0x%08lx)\n",lpszOut
,lpszOut
,dwOutSize
);
792 /**************************************************************************
794 * Create a string that includes the Drive name, the folder text and
797 DWORD WINAPI
_ILGetPidlPath( LPCITEMIDLIST pidl
, LPSTR lpszOut
, DWORD dwOutSize
)
801 TRACE(pidl
,"(%p,%lu)\n",lpszOut
,dwOutSize
);
810 dwOutSize
-= _ILGetFolderText(pidl
, lpszTemp
, dwOutSize
);
812 /*add a backslash if necessary */
813 len
= strlen(lpszTemp
);
814 if (len
&& lpszTemp
[len
-1]!='\\')
815 { lpszTemp
[len
+0]='\\';
816 lpszTemp
[len
+1]='\0';
820 lpszTemp
= lpszOut
+ strlen(lpszOut
);
822 /*add the value string */
823 _ILGetValueText(pidl
, lpszTemp
, dwOutSize
);
825 /*remove the last backslash if necessary */
826 if(*(lpszOut
+ strlen(lpszOut
) - 1) == '\\')
827 { *(lpszOut
+ strlen(lpszOut
) - 1) = 0;
830 TRACE(pidl
,"-- (%p=%s,%lu)\n",lpszOut
,lpszOut
,dwOutSize
);
832 return strlen(lpszOut
);
836 /**************************************************************************
839 * type = PT_DESKTOP | PT_DRIVE | PT_FOLDER | PT_VALUE
841 * uInSize = size of data
844 LPITEMIDLIST WINAPI
_ILCreate(PIDLTYPE type
, LPVOID pIn
, UINT16 uInSize
)
845 { LPITEMIDLIST pidlOut
=NULL
;
847 LPITEMIDLIST pidlTemp
=NULL
;
851 TRACE(pidl
,"(%x %p %x)\n",type
,pIn
,uInSize
);
853 if ( type
== PT_DESKTOP
)
854 { pidlOut
= SHAlloc(2);
855 pidlOut
->mkid
.cb
=0x0000;
863 /* the sizes of: cb(2), pidldata-1, szText+1, next cb(2) */
869 uSize
= 4 + (sizeof(PIDLDATA
)) + uInSize
;
871 pidlOut
= SHAlloc(uSize
);
874 { pidlTemp
->mkid
.cb
= uSize
- 2;
875 pData
=_ILGetDataPointer(pidlTemp
);
876 pszDest
= _ILGetTextPointer(type
, pData
);
880 memcpy(pszDest
, pIn
, uInSize
);
881 TRACE(pidl
,"- create My Computer: %s\n",debugstr_a(pszDest
));
884 memcpy(pszDest
, pIn
, uInSize
);
885 TRACE(pidl
,"- create Drive: %s\n",debugstr_a(pszDest
));
889 memcpy(pszDest
, pIn
, uInSize
);
890 TRACE(pidl
,"- create Value: %s\n",debugstr_a(pszDest
));
893 FIXME(pidl
,"-- wrong argument\n");
897 pidlTemp
= ILGetNext(pidlTemp
);
898 pidlTemp
->mkid
.cb
= 0x00;
900 TRACE(pidl
,"-- (pidl=%p, size=%u)\n",pidlOut
,uSize
-2);
903 /**************************************************************************
904 * _ILGetData(PIDLTYPE, LPCITEMIDLIST, LPVOID, UINT16)
906 DWORD WINAPI
_ILGetData(PIDLTYPE type
, LPCITEMIDLIST pidl
, LPVOID pOut
, UINT32 uOutSize
)
911 TRACE(pidl
,"(%x %p %p %x)\n",type
,pidl
,pOut
,uOutSize
);
919 pData
= _ILGetDataPointer(pidl
);
920 if ( pData
->type
!= type
)
921 { ERR(pidl
,"-- wrong type\n");
924 pszSrc
= _ILGetTextPointer(pData
->type
, pData
);
930 strncpy((LPSTR
)pOut
, "My Computer", uOutSize
);
931 dwReturn
= strlen((LPSTR
)pOut
);
937 strncpy((LPSTR
)pOut
, pszSrc
, uOutSize
);
938 dwReturn
= strlen((LPSTR
)pOut
);
943 strncpy((LPSTR
)pOut
, pszSrc
, uOutSize
);
944 dwReturn
= strlen((LPSTR
)pOut
);
947 ERR(pidl
,"-- unknown type\n");
950 TRACE(pidl
,"-- (%p=%s 0x%08lx)\n",pOut
,(char*)pOut
,dwReturn
);
955 /**************************************************************************
956 * _ILGetDataPointer()
958 LPPIDLDATA WINAPI
_ILGetDataPointer(LPITEMIDLIST pidl
)
962 /* TRACE(pidl,"(%p)\n", pidl);*/
963 return (LPPIDLDATA
)(&pidl
->mkid
.abID
);
965 /**************************************************************************
966 * _ILGetTextPointer()
967 * gets a pointer to the string stored in the pidl
969 LPSTR WINAPI
_ILGetTextPointer(PIDLTYPE type
, LPPIDLDATA pidldata
)
970 {/* TRACE(pidl,"(type=%x data=%p)\n", type, pidldata);*/
977 return (LPSTR
)&(pidldata
->u
.drive
.szDriveName
);
981 return (LPSTR
)&(pidldata
->u
.file
.szText
);
985 BOOL32 WINAPI
_ILGetFileDate (LPCITEMIDLIST pidl
, LPSTR pOut
, UINT32 uOutSize
)
986 { LPPIDLDATA pdata
=_ILGetDataPointer(pidl
);
995 DosDateTimeToFileTime(pdata
->u
.folder
.uFileDate
, pdata
->u
.folder
.uFileTime
, &ft
);
998 DosDateTimeToFileTime(pdata
->u
.file
.uFileDate
, pdata
->u
.file
.uFileTime
, &ft
);
1003 FileTimeToSystemTime (&ft
, &time
);
1004 return GetDateFormat32A(LOCALE_USER_DEFAULT
,DATE_SHORTDATE
,&time
, NULL
, pOut
, uOutSize
);
1006 BOOL32 WINAPI
_ILGetFileSize (LPCITEMIDLIST pidl
, LPSTR pOut
, UINT32 uOutSize
)
1007 { LPPIDLDATA pdata
=_ILGetDataPointer(pidl
);
1008 char stemp
[20]; /* for filesize */
1010 switch (pdata
->type
)
1020 StrFormatByteSize32A(pdata
->u
.file
.dwFileSize
, stemp
, 20);
1021 strncpy( pOut
, stemp
, 20);
1025 BOOL32 WINAPI
_ILGetExtension (LPCITEMIDLIST pidl
, LPSTR pOut
, UINT32 uOutSize
)
1026 { char pTemp
[MAX_PATH
];
1029 TRACE(pidl
,"pidl=%p\n",pidl
);
1031 if ( ! _ILGetValueText(pidl
, pTemp
, MAX_PATH
))
1035 for (i
=0; pTemp
[i
]!='.' && pTemp
[i
];i
++);
1040 strncpy(pOut
, &pTemp
[i
], uOutSize
);
1041 TRACE(pidl
,"%s\n",pOut
);
1046 /**************************************************************************
1047 * IDLList "Item ID List List"
1050 static UINT32 WINAPI
IDLList_GetState(LPIDLLIST
this);
1051 static LPITEMIDLIST WINAPI
IDLList_GetElement(LPIDLLIST
this, UINT32 nIndex
);
1052 static UINT32 WINAPI
IDLList_GetCount(LPIDLLIST
this);
1053 static BOOL32 WINAPI
IDLList_StoreItem(LPIDLLIST
this, LPITEMIDLIST pidl
);
1054 static BOOL32 WINAPI
IDLList_AddItems(LPIDLLIST
this, LPITEMIDLIST
*apidl
, UINT32 cidl
);
1055 static BOOL32 WINAPI
IDLList_InitList(LPIDLLIST
this);
1056 static void WINAPI
IDLList_CleanList(LPIDLLIST
this);
1058 static IDLList_VTable idllvt
=
1068 LPIDLLIST
IDLList_Constructor (UINT32 uStep
)
1070 if (!(lpidll
= (LPIDLLIST
)HeapAlloc(GetProcessHeap(),0,sizeof(IDLList
))))
1073 lpidll
->lpvtbl
=&idllvt
;
1074 lpidll
->uStep
=uStep
;
1077 TRACE (shell
,"(%p)\n",lpidll
);
1080 void IDLList_Destructor(LPIDLLIST
this)
1081 { TRACE (shell
,"(%p)\n",this);
1082 IDLList_CleanList(this);
1085 static UINT32 WINAPI
IDLList_GetState(LPIDLLIST
this)
1086 { TRACE (shell
,"(%p)->(uStep=%u dpa=%p)\n",this, this->uStep
, this->dpa
);
1088 if (this->uStep
== 0)
1091 return(State_OutOfMem
);
1093 return(State_UnInit
);
1095 static LPITEMIDLIST WINAPI
IDLList_GetElement(LPIDLLIST
this, UINT32 nIndex
)
1096 { TRACE (shell
,"(%p)->(index=%u)\n",this, nIndex
);
1097 return((LPITEMIDLIST
)pDPA_GetPtr(this->dpa
, nIndex
));
1099 static UINT32 WINAPI
IDLList_GetCount(LPIDLLIST
this)
1100 { TRACE (shell
,"(%p)\n",this);
1101 return(IDLList_GetState(this)==State_Init
? DPA_GetPtrCount(this->dpa
) : 0);
1103 static BOOL32 WINAPI
IDLList_StoreItem(LPIDLLIST
this, LPITEMIDLIST pidl
)
1104 { TRACE (shell
,"(%p)->(pidl=%p)\n",this, pidl
);
1106 { if (IDLList_InitList(this) && pDPA_InsertPtr(this->dpa
, 0x7fff, (LPSTR
)pidl
)>=0)
1110 IDLList_CleanList(this);
1113 static BOOL32 WINAPI
IDLList_AddItems(LPIDLLIST
this, LPITEMIDLIST
*apidl
, UINT32 cidl
)
1115 TRACE (shell
,"(%p)->(apidl=%p cidl=%u)\n",this, apidl
, cidl
);
1117 for (i
=0; i
<cidl
; ++i
)
1118 { if (!IDLList_StoreItem(this, ILClone((LPCITEMIDLIST
)apidl
[i
])))
1123 static BOOL32 WINAPI
IDLList_InitList(LPIDLLIST
this)
1124 { TRACE (shell
,"(%p)\n",this);
1125 switch (IDLList_GetState(this))
1129 case State_OutOfMem
:
1134 this->dpa
= pDPA_Create(this->uStep
);
1136 return(IDLList_InitList(this));
1139 static void WINAPI
IDLList_CleanList(LPIDLLIST
this)
1141 TRACE (shell
,"(%p)\n",this);
1143 if (this->uStep
!= 0)
1153 for (i
=DPA_GetPtrCount(this->dpa
)-1; i
>=0; --i
)
1154 { ILFree(IDLList_GetElement(this,i
));
1157 pDPA_Destroy(this->dpa
);