4 * Copyright 1998 Juergen Schmied
7 * a pidl == NULL means desktop and is legal
22 #include "winversion.h"
23 #include "shell32_main.h"
27 DECLARE_DEBUG_CHANNEL(pidl)
28 DECLARE_DEBUG_CHANNEL(shell)
30 void pdump (LPCITEMIDLIST pidl)
34 LPITEMIDLIST pidltemp = pidl;
36 { TRACE(pidl,"-------- pidl = NULL (Root)\n");
39 TRACE(pidl,"-------- pidl=%p \n", pidl);
40 if (pidltemp->mkid.cb)
42 { type = _ILGetDataPointer(pidltemp)->type;
43 szData = _ILGetTextPointer(type, _ILGetDataPointer(pidltemp));
44 szShortName = _ILGetSTextPointer(type, _ILGetDataPointer(pidltemp));
46 TRACE(pidl,"---- pidl=%p size=%u type=%lx %s, (%s)\n",
47 pidltemp, pidltemp->mkid.cb,type,debugstr_a(szData), debugstr_a(szShortName));
49 pidltemp = ILGetNext(pidltemp);
50 } while (pidltemp->mkid.cb);
54 TRACE(pidl,"empty pidl (Desktop)\n");
57 BOOL pcheck (LPCITEMIDLIST pidl)
58 { DWORD type, ret=TRUE;
60 LPITEMIDLIST pidltemp = pidl;
62 if (pidltemp && pidltemp->mkid.cb)
64 { type = _ILGetDataPointer(pidltemp)->type;
75 char szTemp[100]; /* 3*32 + 3 + 1 */
77 for ( i = 0; i < pidltemp->mkid.cb; i++)
79 sprintf (&(szTemp[i*3]),"%02x ", ((LPBYTE)pidltemp)[i]);
82 sprintf (&(szTemp[i*3+3]),"...");
86 ERR (pidl,"unknown IDLIST type size=%u type=%lx\n%s\n",pidltemp->mkid.cb,type, szTemp);
90 pidltemp = ILGetNext(pidltemp);
91 } while (pidltemp->mkid.cb);
96 /*************************************************************************
97 * ILGetDisplayName [SHELL32.15]
99 BOOL WINAPI ILGetDisplayName(LPCITEMIDLIST pidl,LPSTR path)
100 { FIXME(shell,"pidl=%p %p semi-stub\n",pidl,path);
101 return SHGetPathFromIDListA(pidl, path);
103 /*************************************************************************
104 * ILFindLastID [SHELL32.16]
106 LPITEMIDLIST WINAPI ILFindLastID(LPITEMIDLIST pidl)
107 { LPITEMIDLIST pidlLast = NULL;
109 TRACE(pidl,"(pidl=%p)\n",pidl);
112 { while(pidl->mkid.cb)
113 { pidlLast = (LPITEMIDLIST)pidl;
114 pidl = ILGetNext(pidl);
119 /*************************************************************************
120 * ILRemoveLastID [SHELL32.17]
122 * Removes the last item
124 BOOL WINAPI ILRemoveLastID(LPCITEMIDLIST pidl)
125 { TRACE(shell,"pidl=%p\n",pidl);
126 if (!pidl || !pidl->mkid.cb)
128 ILFindLastID(pidl)->mkid.cb = 0;
132 /*************************************************************************
133 * ILClone [SHELL32.18]
138 LPITEMIDLIST WINAPI ILClone (LPCITEMIDLIST pidl)
140 LPITEMIDLIST newpidl;
145 len = ILGetSize(pidl);
146 newpidl = (LPITEMIDLIST)SHAlloc(len);
148 memcpy(newpidl,pidl,len);
150 TRACE(pidl,"pidl=%p newpidl=%p\n",pidl, newpidl);
155 /*************************************************************************
156 * ILCloneFirst [SHELL32.19]
159 * duplicates the first idlist of a complex pidl
161 LPITEMIDLIST WINAPI ILCloneFirst(LPCITEMIDLIST pidl)
163 LPITEMIDLIST newpidl=NULL;
165 TRACE(pidl,"pidl=%p \n",pidl);
169 { len = pidl->mkid.cb;
170 newpidl = (LPITEMIDLIST) SHAlloc (len+2);
172 { memcpy(newpidl,pidl,len);
173 ILGetNext(newpidl)->mkid.cb = 0x00;
176 TRACE(pidl,"-- newpidl=%p\n",newpidl);
180 /*************************************************************************
184 * the first two bytes are the len, the pidl is following then
186 HRESULT WINAPI ILLoadFromStream (IStream * pStream, LPITEMIDLIST * ppPidl)
189 HRESULT ret = E_FAIL;
192 TRACE(shell,"%p %p\n", pStream , ppPidl);
199 IStream_AddRef (pStream);
201 if (SUCCEEDED(IStream_Read(pStream, (LPVOID)&wLen, 2, &dwBytesRead)))
202 { *ppPidl = SHAlloc (wLen);
203 if (SUCCEEDED(IStream_Read(pStream, *ppPidl , wLen, &dwBytesRead)))
212 /* we are not jet fully compatible */
213 if (!pcheck(*ppPidl))
219 IStream_Release (pStream);
223 /*************************************************************************
224 * SHILCreateFromPath [SHELL32.28]
227 * wraper for IShellFolder::ParseDisplayName()
229 HRESULT WINAPI SHILCreateFromPathA (LPSTR path, LPITEMIDLIST * ppidl, DWORD attributes)
231 WCHAR lpszDisplayName[MAX_PATH];
233 HRESULT ret = E_FAIL;
235 TRACE(shell, "%s %p 0x%08lx\n",path,ppidl,attributes);
237 LocalToWideChar(lpszDisplayName, path, MAX_PATH);
239 if (SUCCEEDED (SHGetDesktopFolder(&sf)))
240 { ret = sf->lpvtbl->fnParseDisplayName(sf,0, NULL,lpszDisplayName,&pchEaten,ppidl,&attributes);
241 sf->lpvtbl->fnRelease(sf);
245 HRESULT WINAPI SHILCreateFromPathW (LPWSTR path, LPITEMIDLIST * ppidl, DWORD attributes)
248 HRESULT ret = E_FAIL;
250 TRACE(shell, "%s %p 0x%08lx\n",debugstr_w(path),ppidl,attributes);
252 if (SUCCEEDED (SHGetDesktopFolder(&sf)))
253 { ret = sf->lpvtbl->fnParseDisplayName(sf,0, NULL, path, &pchEaten, ppidl, &attributes);
254 sf->lpvtbl->fnRelease(sf);
258 HRESULT WINAPI SHILCreateFromPathAW (LPVOID path, LPITEMIDLIST * ppidl, DWORD attributes)
260 if ( VERSION_OsIsUnicode())
261 return SHILCreateFromPathW (path, ppidl, attributes);
262 return SHILCreateFromPathA (path, ppidl, attributes);
265 /*************************************************************************
266 * SHCloneSpecialIDList [SHELL32.89]
270 * nFolder [in] CSIDL_xxxxx ??
275 * exported by ordinal
277 LPITEMIDLIST WINAPI SHCloneSpecialIDList(HWND hwndOwner,DWORD nFolder,DWORD x3)
278 { LPITEMIDLIST ppidl;
279 WARN(shell,"(hwnd=0x%x,csidl=0x%lx,0x%lx):semi-stub.\n",
280 hwndOwner,nFolder,x3);
282 SHGetSpecialFolderLocation(hwndOwner, nFolder, &ppidl);
287 /*************************************************************************
288 * ILGlobalClone [SHELL32.97]
291 LPITEMIDLIST WINAPI ILGlobalClone(LPCITEMIDLIST pidl)
293 LPITEMIDLIST newpidl;
298 len = ILGetSize(pidl);
299 newpidl = (LPITEMIDLIST)pCOMCTL32_Alloc(len);
301 memcpy(newpidl,pidl,len);
303 TRACE(pidl,"pidl=%p newpidl=%p\n",pidl, newpidl);
309 /*************************************************************************
310 * ILIsEqual [SHELL32.21]
313 BOOL WINAPI ILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
314 { LPPIDLDATA ppidldata;
318 LPITEMIDLIST pidltemp1 = pidl1;
319 LPITEMIDLIST pidltemp2 = pidl2;
321 TRACE(pidl,"pidl1=%p pidl2=%p\n",pidl1, pidl2);
323 /* explorer reads from registry directly (StreamMRU),
324 so we can only check here */
325 if ((!pcheck (pidl1)) || (!pcheck (pidl2)))
331 if ( (!pidl1) || (!pidl2) )
335 if (pidltemp1->mkid.cb && pidltemp2->mkid.cb)
337 { ppidldata = _ILGetDataPointer(pidltemp1);
338 szData1 = _ILGetTextPointer(ppidldata->type, ppidldata);
340 ppidldata = _ILGetDataPointer(pidltemp2);
341 szData2 = _ILGetTextPointer(ppidldata->type, ppidldata);
343 if (strcmp ( szData1, szData2 )!=0 )
346 pidltemp1 = ILGetNext(pidltemp1);
347 pidltemp2 = ILGetNext(pidltemp2);
349 } while (pidltemp1->mkid.cb && pidltemp2->mkid.cb);
351 if (!pidltemp1->mkid.cb && !pidltemp2->mkid.cb)
352 { TRACE(shell, "--- equal\n");
358 /*************************************************************************
359 * ILIsParent [SHELL32.23]
362 DWORD WINAPI ILIsParent( DWORD x, DWORD y, DWORD z)
363 { FIXME(pidl,"0x%08lx 0x%08lx 0x%08lx stub\n",x,y,z);
367 /*************************************************************************
368 * ILFindChild [SHELL32.24]
371 * Compares elements from pidl1 and pidl2.
372 * When at least the first element is equal, it gives a pointer
373 * to the first different element of pidl 2 back.
374 * Returns 0 if pidl 2 is shorter.
376 LPITEMIDLIST WINAPI ILFindChild(LPCITEMIDLIST pidl1,LPCITEMIDLIST pidl2)
377 { LPPIDLDATA ppidldata;
381 LPITEMIDLIST pidltemp1 = pidl1;
382 LPITEMIDLIST pidltemp2 = pidl2;
383 LPITEMIDLIST ret=NULL;
385 TRACE(pidl,"pidl1=%p pidl2=%p\n",pidl1, pidl2);
390 if ( !pidl1 || !pidl1->mkid.cb) /* pidl 1 is desktop (root) */
391 { TRACE(shell, "--- %p\n", pidl2);
395 if (pidltemp1->mkid.cb && pidltemp2->mkid.cb)
397 { ppidldata = _ILGetDataPointer(pidltemp1);
398 szData1 = _ILGetTextPointer(ppidldata->type, ppidldata);
400 ppidldata = _ILGetDataPointer(pidltemp2);
401 szData2 = _ILGetTextPointer(ppidldata->type, ppidldata);
403 pidltemp2 = ILGetNext(pidltemp2); /* points behind the pidl2 */
405 if (strcmp(szData1,szData2) == 0)
406 { ret = pidltemp2; /* found equal element */
409 { if (ret) /* different element after equal -> break */
414 pidltemp1 = ILGetNext(pidltemp1);
415 } while (pidltemp1->mkid.cb && pidltemp2->mkid.cb);
418 if (!pidltemp2->mkid.cb)
419 { return NULL; /* complete equal or pidl 2 is shorter */
422 TRACE(shell, "--- %p\n", ret);
423 return ret; /* pidl 1 is shorter */
426 /*************************************************************************
427 * ILCombine [SHELL32.25]
430 * Concatenates two complex idlists.
431 * The pidl is the first one, pidlsub the next one
432 * Does not destroy the passed in idlists!
434 LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1,LPCITEMIDLIST pidl2)
436 LPITEMIDLIST pidlNew;
438 TRACE(pidl,"pidl=%p pidl=%p\n",pidl1,pidl2);
448 { pidlNew = ILClone(pidl2);
453 { pidlNew = ILClone(pidl1);
457 len1 = ILGetSize(pidl1)-2;
458 len2 = ILGetSize(pidl2);
459 pidlNew = SHAlloc(len1+len2);
462 { memcpy(pidlNew,pidl1,len1);
463 memcpy(((BYTE *)pidlNew)+len1,pidl2,len2);
466 /* TRACE(pidl,"--new pidl=%p\n",pidlNew);*/
469 /*************************************************************************
470 * SHGetRealIDL [SHELL32.98]
474 LPITEMIDLIST WINAPI SHGetRealIDL(LPSHELLFOLDER lpsf, LPITEMIDLIST pidl, DWORD z)
475 { FIXME(pidl,"sf=%p pidl=%p 0x%04lx\n",lpsf,pidl,z);
480 /*************************************************************************
481 * SHLogILFromFSIL [SHELL32.95]
485 LPITEMIDLIST WINAPI SHLogILFromFSIL(LPITEMIDLIST pidl)
486 { FIXME(pidl,"(pidl=%p)\n",pidl);
491 /*************************************************************************
492 * ILGetSize [SHELL32.152]
493 * gets the byte size of an idlist including zero terminator (pidl)
502 * exported by ordinal
504 DWORD WINAPI ILGetSize(LPITEMIDLIST pidl)
505 { LPSHITEMID si = &(pidl->mkid);
511 si = (LPSHITEMID)(((LPBYTE)si)+si->cb);
515 TRACE(pidl,"pidl=%p size=%lu\n",pidl, len);
518 /*************************************************************************
519 * ILGetNext [SHELL32.153]
520 * gets the next simple pidl of a complex pidl
526 * pointer to next element
529 LPITEMIDLIST WINAPI ILGetNext(LPITEMIDLIST pidl)
530 { LPITEMIDLIST nextpidl;
532 /* TRACE(pidl,"(pidl=%p)\n",pidl);*/
534 { nextpidl = (LPITEMIDLIST)(LPBYTE)(((LPBYTE)pidl) + pidl->mkid.cb);
541 /*************************************************************************
542 * ILAppend [SHELL32.154]
545 * Adds the single item to the idlist indicated by pidl.
546 * if bEnd is 0, adds the item to the front of the list,
547 * otherwise adds the item to the end. (???)
548 * Destroys the passed in idlist! (???)
550 LPITEMIDLIST WINAPI ILAppend(LPITEMIDLIST pidl,LPCITEMIDLIST item,BOOL bEnd)
551 { LPITEMIDLIST idlRet;
552 WARN(pidl,"(pidl=%p,pidl=%p,%08u)semi-stub\n",pidl,item,bEnd);
556 if (_ILIsDesktop(pidl))
557 { idlRet = ILClone(item);
563 { idlRet=ILCombine(pidl,item);
566 { idlRet=ILCombine(item,pidl);
571 /*************************************************************************
572 * ILFree [SHELL32.155]
575 * free_check_ptr - frees memory (if not NULL)
576 * allocated by SHMalloc allocator
577 * exported by ordinal
579 DWORD WINAPI ILFree(LPITEMIDLIST pidl)
580 { TRACE(pidl,"(pidl=0x%08lx)\n",(DWORD)pidl);
587 /*************************************************************************
588 * ILGlobalFree [SHELL32.156]
591 DWORD WINAPI ILGlobalFree( LPITEMIDLIST pidl)
592 { TRACE(pidl,"%p\n",pidl);
597 return pCOMCTL32_Free (pidl);
599 /*************************************************************************
600 * ILCreateFromPath [SHELL32.157]
603 LPITEMIDLIST WINAPI ILCreateFromPathA (LPSTR path)
604 { LPITEMIDLIST pidlnew;
606 TRACE(shell,"%s\n",path);
607 if (SUCCEEDED (SHILCreateFromPathA (path, &pidlnew, 0)))
611 LPITEMIDLIST WINAPI ILCreateFromPathW (LPWSTR path)
612 { LPITEMIDLIST pidlnew;
614 TRACE(shell,"%s\n",debugstr_w(path));
616 if (SUCCEEDED (SHILCreateFromPathW (path, &pidlnew, 0)))
620 LPITEMIDLIST WINAPI ILCreateFromPathAW (LPVOID path)
622 if ( VERSION_OsIsUnicode())
623 return ILCreateFromPathW (path);
624 return ILCreateFromPathA (path);
626 /*************************************************************************
627 * SHSimpleIDListFromPath [SHELL32.162]
630 LPITEMIDLIST WINAPI SHSimpleIDListFromPathAW (LPVOID lpszPath)
631 { LPCSTR lpszElement;
632 char lpszTemp[MAX_PATH];
637 if ( VERSION_OsIsUnicode())
638 { TRACE(pidl,"(path=L%s)\n",debugstr_w((LPWSTR)lpszPath));
639 WideCharToLocal(lpszTemp, lpszPath, MAX_PATH);
642 { TRACE(pidl,"(path=%s)\n",(LPSTR)lpszPath);
643 strcpy(lpszTemp, lpszPath);
646 lpszElement = PathFindFilenameA(lpszTemp);
647 if( GetFileAttributesA(lpszTemp) & FILE_ATTRIBUTE_DIRECTORY )
648 { return _ILCreateFolder(NULL, lpszElement); /*FIXME: fill shortname */
650 return _ILCreateValue(NULL, lpszElement); /*FIXME: fill shortname */
652 /*************************************************************************
653 * SHGetDataFromIDListA [SHELL32.247]
656 HRESULT WINAPI SHGetDataFromIDListA(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, int nFormat, LPVOID dest, int len)
657 { TRACE(shell,"sf=%p pidl=%p 0x%04x %p 0x%04x stub\n",psf,pidl,nFormat,dest,len);
663 { case SHGDFIL_FINDDATA:
664 { WIN32_FIND_DATAA * pfd = dest;
666 CHAR pszPath[MAX_PATH];
669 if ( len < sizeof (WIN32_FIND_DATAA))
672 psf->lpvtbl->fnAddRef(psf);
673 psf->lpvtbl->fnGetDisplayNameOf( psf, pidl, SHGDN_FORPARSING, &lpName);
674 psf->lpvtbl->fnRelease(psf);
676 strcpy(pszPath,lpName.u.cStr);
677 if ((handle = FindFirstFileA ( pszPath, pfd)))
681 case SHGDFIL_NETRESOURCE:
682 case SHGDFIL_DESCRIPTIONID:
683 FIXME(shell, "SHGDFIL %i stub\n", nFormat);
686 ERR(shell,"Unknown SHGDFIL %i, please report\n", nFormat);
690 /*************************************************************************
691 * SHGetDataFromIDListW [SHELL32.247]
694 HRESULT WINAPI SHGetDataFromIDListW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, int nFormat, LPVOID dest, int len)
695 { FIXME(shell,"sf=%p pidl=%p 0x%04x %p 0x%04x stub\n",psf,pidl,nFormat,dest,len);
696 return SHGetDataFromIDListA( psf, pidl, nFormat, dest, len);
699 /**************************************************************************
703 /**************************************************************************
705 * _ILCreateMyComputer()
710 LPITEMIDLIST WINAPI _ILCreateDesktop()
711 { TRACE(pidl,"()\n");
712 return _ILCreate(PT_DESKTOP, NULL, 0);
714 LPITEMIDLIST WINAPI _ILCreateMyComputer()
715 { TRACE(pidl,"()\n");
716 return _ILCreate(PT_MYCOMP, (void *)"My Computer", strlen ("My Computer")+1);
718 LPITEMIDLIST WINAPI _ILCreateDrive( LPCSTR lpszNew)
720 strncpy (sTemp,lpszNew,4);
723 TRACE(pidl,"(%s)\n",sTemp);
724 return _ILCreate(PT_DRIVE,(LPVOID)&sTemp[0],4);
726 LPITEMIDLIST WINAPI _ILCreateFolder( LPCSTR lpszShortName, LPCSTR lpszName)
727 { char buff[MAX_PATH];
731 TRACE(pidl,"(%s, %s)\n",lpszShortName, lpszName);
733 len = strlen (lpszName)+1;
734 memcpy (pbuff, lpszName, len);
738 { len1 = strlen (lpszShortName)+1;
739 memcpy (pbuff, lpszShortName, len1);
745 return _ILCreate(PT_FOLDER, (LPVOID)buff, len + len1);
747 LPITEMIDLIST WINAPI _ILCreateValue(LPCSTR lpszShortName, LPCSTR lpszName)
748 { char buff[MAX_PATH];
752 TRACE(pidl,"(%s, %s)\n", lpszShortName, lpszName);
754 len = strlen (lpszName)+1;
755 memcpy (pbuff, lpszName, len);
759 { len1 = strlen (lpszShortName)+1;
760 memcpy (pbuff, lpszShortName, len1);
766 return _ILCreate(PT_VALUE, (LPVOID)buff, len + len1);
769 /**************************************************************************
772 * Gets the text for the drive eg. 'c:\'
777 DWORD WINAPI _ILGetDrive(LPCITEMIDLIST pidl,LPSTR pOut, UINT16 uSize)
778 { TRACE(pidl,"(%p,%p,%u)\n",pidl,pOut,uSize);
780 if(_ILIsMyComputer(pidl))
781 pidl = ILGetNext(pidl);
783 if (pidl && _ILIsDrive(pidl))
784 return _ILGetData(PT_DRIVE, pidl, (LPVOID)pOut, uSize)-1;
788 /**************************************************************************
790 * Gets the text for only the first item
795 DWORD WINAPI _ILGetItemText(LPCITEMIDLIST pidl, LPSTR lpszText, UINT16 uSize)
798 TRACE(pidl,"(pidl=%p %p %d)\n",pidl,lpszText,uSize);
799 if (_ILIsMyComputer(pidl))
800 { ret = _ILGetData(PT_MYCOMP, pidl, (LPVOID)lpszText, uSize)-1;
802 else if (_ILIsDrive(pidl))
803 { ret = _ILGetData(PT_DRIVE, pidl, (LPVOID)lpszText, uSize)-1;
805 else if (_ILIsFolder (pidl))
806 { ret = _ILGetData(PT_FOLDER, pidl, (LPVOID)lpszText, uSize)-1;
808 else if (_ILIsValue (pidl))
809 { ret = _ILGetData(PT_VALUE, pidl, (LPVOID)lpszText, uSize)-1;
811 TRACE(pidl,"(-- %s)\n",debugstr_a(lpszText));
814 /**************************************************************************
820 BOOL WINAPI _ILIsDesktop(LPCITEMIDLIST pidl)
821 { TRACE(pidl,"(%p)\n",pidl);
822 return ( !pidl || (pidl && pidl->mkid.cb == 0x00) );
825 BOOL WINAPI _ILIsMyComputer(LPCITEMIDLIST pidl)
826 { LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
827 TRACE(pidl,"(%p)\n",pidl);
828 return (pidl && lpPData && PT_MYCOMP == lpPData->type);
831 BOOL WINAPI _ILIsDrive(LPCITEMIDLIST pidl)
832 { LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
833 TRACE(pidl,"(%p)\n",pidl);
834 return (pidl && lpPData && PT_DRIVE == lpPData->type);
837 BOOL WINAPI _ILIsFolder(LPCITEMIDLIST pidl)
838 { LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
839 TRACE(pidl,"(%p)\n",pidl);
840 return (pidl && lpPData && PT_FOLDER == lpPData->type);
843 BOOL WINAPI _ILIsValue(LPCITEMIDLIST pidl)
844 { LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
845 TRACE(pidl,"(%p)\n",pidl);
846 return (pidl && lpPData && PT_VALUE == lpPData->type);
849 /**************************************************************************
851 * Creates a Path string from a PIDL, filtering out the special Folders and values
852 * There is no trailing backslash
853 * When lpszPath is NULL the needed size is returned
858 DWORD WINAPI _ILGetFolderText(LPCITEMIDLIST pidl,LPSTR lpszPath, DWORD dwSize)
859 { LPITEMIDLIST pidlTemp;
864 TRACE(pidl,"(%p path=%p)\n",pidl, lpszPath);
869 if(_ILIsMyComputer(pidl))
870 { pidlTemp = ILGetNext(pidl);
871 TRACE(pidl,"-- skip My Computer\n");
874 { pidlTemp = (LPITEMIDLIST)pidl;
880 pData = _ILGetDataPointer(pidlTemp);
882 while(pidlTemp->mkid.cb && !(PT_VALUE == pData->type))
884 if (!(pText = _ILGetTextPointer(pData->type,pData)))
885 return 0; /* foreign pidl */
887 dwCopied += strlen(pText);
889 pidlTemp = ILGetNext(pidlTemp);
890 pData = _ILGetDataPointer(pidlTemp);
893 { strcat(lpszPath, pText);
895 if (pidlTemp->mkid.cb /* last element ? */
896 && (pText[2] != '\\') /* drive has own '\' */
897 && (PT_VALUE != pData->type)) /* next element is value */
898 { lpszPath[dwCopied] = '\\';
899 lpszPath[dwCopied+1] = '\0';
903 else /* only length */
904 { if (pidlTemp->mkid.cb
905 && (pText[2] != '\\')
906 && (PT_VALUE != pData->type))
907 dwCopied++; /* backslash between elements */
911 TRACE(pidl,"-- (size=%lu path=%s)\n",dwCopied, debugstr_a(lpszPath));
916 /**************************************************************************
918 * Gets the text for the last item in the list
920 DWORD WINAPI _ILGetValueText(LPCITEMIDLIST pidl, LPSTR lpszValue, DWORD dwSize)
921 { LPITEMIDLIST pidlTemp=pidl;
922 CHAR szText[MAX_PATH];
924 TRACE(pidl,"(pidl=%p %p 0x%08lx)\n",pidl,lpszValue,dwSize);
930 while(pidlTemp->mkid.cb && !_ILIsValue(pidlTemp))
931 { pidlTemp = ILGetNext(pidlTemp);
934 if(!pidlTemp->mkid.cb)
938 _ILGetItemText( pidlTemp, szText, sizeof(szText));
941 { return strlen(szText);
944 strcpy(lpszValue, szText);
946 TRACE(pidl,"-- (pidl=%p %p=%s 0x%08lx)\n",pidl,lpszValue,lpszValue,dwSize);
947 return strlen(lpszValue);
950 /**************************************************************************
952 * Create a string that includes the Drive name, the folder text and
958 DWORD WINAPI _ILGetPidlPath( LPCITEMIDLIST pidl, LPSTR lpszOut, DWORD dwOutSize)
960 LPSTR lpszTemp = lpszOut;
962 TRACE(pidl,"(%p,%lu)\n",lpszOut,dwOutSize);
970 len = _ILGetFolderText(pidl, lpszOut, dwOutSize);
973 strcpy (lpszOut,"\\");
974 len++; lpszOut++; dwOutSize -= len;
976 len += _ILGetValueText(pidl, lpszOut, dwOutSize );
978 /*remove the last backslash if necessary */
979 if( lpszTemp[len-1]=='\\')
980 { lpszTemp[len-1] = 0;
984 TRACE(pidl,"-- (%p=%s,%u)\n",lpszTemp,lpszTemp,len);
989 /**************************************************************************
992 * type = PT_DESKTOP | PT_DRIVE | PT_FOLDER | PT_VALUE
994 * uInSize = size of data (raw)
997 LPITEMIDLIST WINAPI _ILCreate(PIDLTYPE type, LPVOID pIn, UINT16 uInSize)
998 { LPITEMIDLIST pidlOut=NULL;
1000 LPITEMIDLIST pidlTemp=NULL;
1004 TRACE(pidl,"(0x%02x %p %i)\n",type,pIn,uInSize);
1006 if ( type == PT_DESKTOP)
1007 { pidlOut = SHAlloc(2);
1008 pidlOut->mkid.cb=0x0000;
1016 /* the sizes of: cb(2), pidldata-1(26), szText+1, next cb(2) */
1022 uSize = 4 + (sizeof(PIDLDATA)) + uInSize;
1024 pidlOut = SHAlloc(uSize);
1027 { pidlTemp->mkid.cb = uSize - 2;
1028 pData =_ILGetDataPointer(pidlTemp);
1029 pszDest = _ILGetTextPointer(type, pData);
1033 memcpy(pszDest, pIn, uInSize);
1034 TRACE(pidl,"- create My Computer: %s\n",debugstr_a(pszDest));
1037 memcpy(pszDest, pIn, uInSize);
1038 TRACE(pidl,"- create Drive: %s\n",debugstr_a(pszDest));
1042 memcpy(pszDest, pIn, uInSize);
1043 TRACE(pidl,"- create Value: %s\n",debugstr_a(pszDest));
1046 FIXME(pidl,"-- wrong argument\n");
1050 pidlTemp = ILGetNext(pidlTemp);
1051 pidlTemp->mkid.cb = 0x00;
1053 TRACE(pidl,"-- (pidl=%p, size=%u)\n",pidlOut,uSize-2);
1056 /**************************************************************************
1057 * _ILGetData(PIDLTYPE, LPCITEMIDLIST, LPVOID, UINT16)
1060 * length of data (raw)
1062 DWORD WINAPI _ILGetData(PIDLTYPE type, LPCITEMIDLIST pidl, LPVOID pOut, UINT uOutSize)
1067 TRACE(pidl,"(%x %p %p %x)\n",type,pidl,pOut,uOutSize);
1075 pData = _ILGetDataPointer(pidl);
1076 if ( pData->type != type)
1077 { ERR(pidl,"-- wrong type\n");
1080 pszSrc = _ILGetTextPointer(pData->type, pData);
1086 strncpy((LPSTR)pOut, "My Computer", uOutSize);
1087 dwReturn = strlen((LPSTR)pOut)+1;
1093 strncpy((LPSTR)pOut, pszSrc, uOutSize);
1094 dwReturn = strlen((LPSTR)pOut)+1;
1099 strncpy((LPSTR)pOut, pszSrc, uOutSize);
1100 dwReturn = strlen((LPSTR)pOut)+1;
1103 ERR(pidl,"-- unknown type\n");
1106 TRACE(pidl,"-- (%p=%s 0x%08lx)\n",pOut,(char*)pOut,dwReturn);
1111 /**************************************************************************
1112 * _ILGetDataPointer()
1114 LPPIDLDATA WINAPI _ILGetDataPointer(LPITEMIDLIST pidl)
1115 { if(pidl && pidl->mkid.cb != 0x00)
1116 return (LPPIDLDATA)(&pidl->mkid.abID);
1119 /**************************************************************************
1120 * _ILGetTextPointer()
1121 * gets a pointer to the long filename string stored in the pidl
1123 LPSTR WINAPI _ILGetTextPointer(PIDLTYPE type, LPPIDLDATA pidldata)
1124 {/* TRACE(pidl,"(type=%x data=%p)\n", type, pidldata);*/
1131 return (LPSTR)&(pidldata->u.drive.szDriveName);
1135 return (LPSTR)&(pidldata->u.file.szNames);
1139 /**************************************************************************
1140 * _ILGetSTextPointer()
1141 * gets a pointer to the long filename string stored in the pidl
1143 LPSTR WINAPI _ILGetSTextPointer(PIDLTYPE type, LPPIDLDATA pidldata)
1144 {/* TRACE(pidl,"(type=%x data=%p)\n", type, pidldata);*/
1155 return (LPSTR)(pidldata->u.file.szNames + strlen (pidldata->u.file.szNames) + 1);
1159 BOOL WINAPI _ILGetFileDate (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
1160 { LPPIDLDATA pdata =_ILGetDataPointer(pidl);
1164 switch (pdata->type)
1169 DosDateTimeToFileTime(pdata->u.folder.uFileDate, pdata->u.folder.uFileTime, &ft);
1172 DosDateTimeToFileTime(pdata->u.file.uFileDate, pdata->u.file.uFileTime, &ft);
1177 FileTimeToSystemTime (&ft, &time);
1178 return GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&time, NULL, pOut, uOutSize);
1180 BOOL WINAPI _ILGetFileSize (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
1181 { LPPIDLDATA pdata =_ILGetDataPointer(pidl);
1182 char stemp[20]; /* for filesize */
1184 switch (pdata->type)
1194 StrFormatByteSizeA(pdata->u.file.dwFileSize, stemp, 20);
1195 strncpy( pOut, stemp, 20);
1199 BOOL WINAPI _ILGetExtension (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
1200 { char pTemp[MAX_PATH];
1203 TRACE(pidl,"pidl=%p\n",pidl);
1205 if ( ! _ILGetValueText(pidl, pTemp, MAX_PATH))
1209 for (i=0; pTemp[i]!='.' && pTemp[i];i++);
1214 strncpy(pOut, &pTemp[i], uOutSize);
1215 TRACE(pidl,"%s\n",pOut);