Release 980927
[wine.git] / dlls / shell32 / pidl.c
blob67ccd94237ac45053bf1a7fd3f525fa3dfe902b4
1 /*
2 * pidl Handling
4 * Copyright 1998 Juergen Schmied
6 * NOTES
7 * a pidl == NULL means desktop and is legal
9 */
11 #include <ctype.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include "ole.h"
15 #include "ole2.h"
16 #include "debug.h"
17 #include "compobj.h"
18 #include "interfaces.h"
19 #include "shlobj.h"
20 #include "shell.h"
21 #include "winerror.h"
22 #include "winnls.h"
23 #include "winproc.h"
24 #include "commctrl.h"
25 #include "shell32_main.h"
27 #include "pidl.h"
29 void pdump (LPCITEMIDLIST pidl)
30 { DWORD type;
31 CHAR * szData;
32 LPITEMIDLIST pidltemp = pidl;
33 if (! pidltemp)
34 { TRACE(pidl,"-------- pidl = NULL (Root)\n");
35 return;
37 TRACE(pidl,"-------- pidl=%p \n", pidl);
38 if (pidltemp->mkid.cb)
39 { do
40 { type = _ILGetDataPointer(pidltemp)->type;
41 szData = _ILGetTextPointer(type, _ILGetDataPointer(pidltemp));
43 TRACE(pidl,"---- pidl=%p size=%u type=%lx %s\n",pidltemp, pidltemp->mkid.cb,type,debugstr_a(szData));
45 pidltemp = ILGetNext(pidltemp);
46 } while (pidltemp->mkid.cb);
47 return;
49 else
50 TRACE(pidl,"empty pidl (Desktop)\n");
52 /*************************************************************************
53 * ILGetDisplayName [SHELL32.15]
55 BOOL32 WINAPI ILGetDisplayName(LPCITEMIDLIST iil,LPSTR path)
56 { FIXME(pidl,"(%p,%p),stub, return e:!\n",iil,path);
57 strcpy(path,"e:\\");
58 return TRUE;
60 /*************************************************************************
61 * ILFindLastID [SHELL32.16]
63 LPITEMIDLIST WINAPI ILFindLastID(LPITEMIDLIST pidl)
64 { LPITEMIDLIST pidlLast = NULL;
66 TRACE(pidl,"(pidl=%p)\n",pidl);
68 if(pidl)
69 { while(pidl->mkid.cb)
70 { pidlLast = (LPITEMIDLIST)pidl;
71 pidl = ILGetNext(pidl);
74 return pidlLast;
76 /*************************************************************************
77 * ILRemoveLastID [SHELL32.17]
78 * NOTES
79 * Removes the last item
81 BOOL32 WINAPI ILRemoveLastID(LPCITEMIDLIST pidl)
82 { TRACE(shell,"pidl=%p\n",pidl);
83 if (!pidl || !pidl->mkid.cb)
84 return 0;
85 ILFindLastID(pidl)->mkid.cb = 0;
86 return 1;
89 /*************************************************************************
90 * ILClone [SHELL32.18]
92 * NOTES
93 * dupicate an idlist
95 LPITEMIDLIST WINAPI ILClone (LPCITEMIDLIST pidl)
96 { DWORD len;
97 LPITEMIDLIST newpidl;
99 TRACE(pidl,"%p\n",pidl);
101 pdump(pidl);
103 if (!pidl)
104 return NULL;
106 len = ILGetSize(pidl);
107 newpidl = (LPITEMIDLIST)SHAlloc(len);
108 if (newpidl)
109 memcpy(newpidl,pidl,len);
110 return newpidl;
112 /*************************************************************************
113 * ILCloneFirst [SHELL32.19]
115 * NOTES
116 * duplicates the first idlist of a complex pidl
118 LPITEMIDLIST WINAPI ILCloneFirst(LPCITEMIDLIST pidl)
119 { DWORD len;
120 LPITEMIDLIST newpidl=NULL;
121 TRACE(pidl,"pidl=%p\n",pidl);
123 if (pidl)
124 { len = pidl->mkid.cb;
125 newpidl = (LPITEMIDLIST) SHAlloc (len+2);
126 if (newpidl)
127 { memcpy(newpidl,pidl,len);
128 ILGetNext(newpidl)->mkid.cb = 0x00;
132 return newpidl;
134 /*************************************************************************
135 * ILIsEqual [SHELL32.21]
138 BOOL32 WINAPI ILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
139 { FIXME(pidl,"pidl1=%p pidl2=%p stub\n",pidl1, pidl2);
140 pdump (pidl1);
141 pdump (pidl2);
142 return FALSE;
144 /*************************************************************************
145 * ILFindChild [SHELL32.24]
148 DWORD WINAPI ILFindChild(LPCITEMIDLIST pidl1,LPCITEMIDLIST pidl2)
149 { FIXME(pidl,"%p %p stub\n",pidl1,pidl2);
150 pdump (pidl1);
151 pdump (pidl2);
152 return 0;
155 /*************************************************************************
156 * ILCombine [SHELL32.25]
158 * NOTES
159 * Concatenates two complex idlists.
160 * The pidl is the first one, pidlsub the next one
161 * Does not destroy the passed in idlists!
163 LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1,LPCITEMIDLIST pidl2)
164 { DWORD len1,len2;
165 LPITEMIDLIST pidlNew;
167 TRACE(pidl,"pidl=%p pidl=%p\n",pidl1,pidl2);
169 if(!pidl1 && !pidl2)
170 { return NULL;
173 pdump (pidl1);
174 pdump (pidl2);
176 if(!pidl1)
177 { pidlNew = ILClone(pidl2);
178 return pidlNew;
181 if(!pidl2)
182 { pidlNew = ILClone(pidl1);
183 return pidlNew;
186 len1 = ILGetSize(pidl1)-2;
187 len2 = ILGetSize(pidl2);
188 pidlNew = SHAlloc(len1+len2);
190 if (pidlNew)
191 { memcpy(pidlNew,pidl1,len1);
192 memcpy(((BYTE *)pidlNew)+len1,pidl2,len2);
195 /* TRACE(pidl,"--new pidl=%p\n",pidlNew);*/
196 return pidlNew;
198 /*************************************************************************
199 * SHLogILFromFSIL [SHELL32.95]
201 * NOTES
202 * might be the prepending of MyComputer to a filesystem pidl (?)
204 LPITEMIDLIST WINAPI SHLogILFromFSIL(LPITEMIDLIST pidl)
205 { FIXME(pidl,"(pidl=%p)\n",pidl);
206 pdump(pidl);
207 return ILClone(pidl);
210 /*************************************************************************
211 * ILGetSize [SHELL32.152]
212 * gets the byte size of an idlist including zero terminator (pidl)
214 * PARAMETERS
215 * pidl ITEMIDLIST
217 * RETURNS
218 * size of pidl
220 * NOTES
221 * exported by ordinal
223 DWORD WINAPI ILGetSize(LPITEMIDLIST pidl)
224 { LPSHITEMID si = &(pidl->mkid);
225 DWORD len=0;
227 /*TRACE(pidl,"pidl=%p\n",pidl);*/
229 if (pidl)
230 { while (si->cb)
231 { len += si->cb;
232 si = (LPSHITEMID)(((LPBYTE)si)+si->cb);
234 len += 2;
236 /*TRACE(pidl,"-- size=%lu\n",len);*/
237 return len;
239 /*************************************************************************
240 * ILGetNext [SHELL32.153]
241 * gets the next simple pidl of a complex pidl
243 * PARAMETERS
244 * pidl ITEMIDLIST
246 * RETURNS
247 * pointer to next element
250 LPITEMIDLIST WINAPI ILGetNext(LPITEMIDLIST pidl)
251 { LPITEMIDLIST nextpidl;
253 /* TRACE(pidl,"(pidl=%p)\n",pidl);*/
254 if(pidl)
255 { nextpidl = (LPITEMIDLIST)(LPBYTE)(((LPBYTE)pidl) + pidl->mkid.cb);
256 return nextpidl;
258 else
259 { return (NULL);
262 /*************************************************************************
263 * ILAppend [SHELL32.154]
265 * NOTES
266 * Adds the single item to the idlist indicated by pidl.
267 * if bEnd is 0, adds the item to the front of the list,
268 * otherwise adds the item to the end.
269 * Destroys the passed in idlist!
271 LPITEMIDLIST WINAPI ILAppend(LPITEMIDLIST pidl,LPCITEMIDLIST item,BOOL32 bEnd)
272 { FIXME(pidl,"(pidl=%p,pidl=%p,%08u)stub\n",pidl,item,bEnd);
273 return NULL;
275 /*************************************************************************
276 * ILFree [SHELL32.155]
278 * NOTES
279 * free_check_ptr - frees memory (if not NULL)
280 * allocated by SHMalloc allocator
281 * exported by ordinal
283 DWORD WINAPI ILFree(LPVOID pidl)
284 { TRACE(pidl,"(pidl=0x%08lx)\n",(DWORD)pidl);
285 if (!pidl)
286 return 0;
287 return SHFree(pidl);
289 /*************************************************************************
290 * ILCreateFromPath [SHELL32.157]
293 LPITEMIDLIST WINAPI ILCreateFromPath(LPSTR path)
294 { LPSHELLFOLDER shellfolder;
295 LPITEMIDLIST pidlnew;
296 CHAR pszTemp[MAX_PATH*2];
297 LPWSTR lpszDisplayName = (LPWSTR)&pszTemp[0];
298 DWORD pchEaten;
300 TRACE(pidl,"(path=%s)\n",path);
302 LocalToWideChar32(lpszDisplayName, path, MAX_PATH);
304 if (SHGetDesktopFolder(&shellfolder)==S_OK)
305 { shellfolder->lpvtbl->fnParseDisplayName(shellfolder,0, NULL,lpszDisplayName,&pchEaten,&pidlnew,NULL);
306 shellfolder->lpvtbl->fnRelease(shellfolder);
308 return pidlnew;
311 /**************************************************************************
312 * internal functions
315 /**************************************************************************
316 * _ILCreateDesktop()
317 * _ILCreateMyComputer()
318 * _ILCreateDrive()
319 * _ILCreateFolder()
320 * _ILCreateValue()
322 LPITEMIDLIST WINAPI _ILCreateDesktop()
323 { TRACE(pidl,"()\n");
324 return _ILCreate(PT_DESKTOP, NULL, 0);
326 LPITEMIDLIST WINAPI _ILCreateMyComputer()
327 { TRACE(pidl,"()\n");
328 return _ILCreate(PT_MYCOMP, (void *)"My Computer", strlen ("My Computer")+1);
330 LPITEMIDLIST WINAPI _ILCreateDrive( LPCSTR lpszNew)
331 { char sTemp[4];
332 strncpy (sTemp,lpszNew,4);
333 sTemp[2]='\\';
334 sTemp[3]=0x00;
335 TRACE(pidl,"(%s)\n",sTemp);
336 return _ILCreate(PT_DRIVE,(LPVOID)&sTemp[0],4);
338 LPITEMIDLIST WINAPI _ILCreateFolder( LPCSTR lpszNew)
339 { TRACE(pidl,"(%s)\n",lpszNew);
340 return _ILCreate(PT_FOLDER, (LPVOID)lpszNew, strlen(lpszNew)+1);
342 LPITEMIDLIST WINAPI _ILCreateValue(LPCSTR lpszNew)
343 { TRACE(pidl,"(%s)\n",lpszNew);
344 return _ILCreate(PT_VALUE, (LPVOID)lpszNew, strlen(lpszNew)+1);
347 /**************************************************************************
348 * _ILGetDrive()
350 * FIXME: quick hack
352 BOOL32 WINAPI _ILGetDrive(LPCITEMIDLIST pidl,LPSTR pOut, UINT16 uSize)
353 { LPITEMIDLIST pidlTemp=NULL;
355 TRACE(pidl,"(%p,%p,%u)\n",pidl,pOut,uSize);
356 if(_ILIsMyComputer(pidl))
357 { pidlTemp = ILGetNext(pidl);
359 else if (pidlTemp && _ILIsDrive(pidlTemp))
360 { return (BOOL32)_ILGetData(PT_DRIVE, pidlTemp, (LPVOID)pOut, uSize);
362 return FALSE;
364 /**************************************************************************
365 * _ILGetItemText()
366 * Gets the text for only this item
368 DWORD WINAPI _ILGetItemText(LPCITEMIDLIST pidl, LPSTR lpszText, UINT16 uSize)
369 { TRACE(pidl,"(pidl=%p %p %x)\n",pidl,lpszText,uSize);
370 if (_ILIsMyComputer(pidl))
371 { return _ILGetData(PT_MYCOMP, pidl, (LPVOID)lpszText, uSize);
373 if (_ILIsDrive(pidl))
374 { return _ILGetData(PT_DRIVE, pidl, (LPVOID)lpszText, uSize);
376 if (_ILIsFolder (pidl))
377 { return _ILGetData(PT_FOLDER, pidl, (LPVOID)lpszText, uSize);
379 return _ILGetData(PT_VALUE, pidl, (LPVOID)lpszText, uSize);
381 /**************************************************************************
382 * _ILIsDesktop()
383 * _ILIsDrive()
384 * _ILIsFolder()
385 * _ILIsValue()
387 BOOL32 WINAPI _ILIsDesktop(LPCITEMIDLIST pidl)
388 { TRACE(pidl,"(%p)\n",pidl);
390 if (! pidl)
391 return TRUE;
393 return ( pidl->mkid.cb == 0x00 );
396 BOOL32 WINAPI _ILIsMyComputer(LPCITEMIDLIST pidl)
397 { LPPIDLDATA pData;
398 TRACE(pidl,"(%p)\n",pidl);
400 if (! pidl)
401 return FALSE;
403 pData = _ILGetDataPointer(pidl);
404 return (PT_MYCOMP == pData->type);
407 BOOL32 WINAPI _ILIsDrive(LPCITEMIDLIST pidl)
408 { LPPIDLDATA pData;
409 TRACE(pidl,"(%p)\n",pidl);
411 if (! pidl)
412 return FALSE;
414 pData = _ILGetDataPointer(pidl);
415 return (PT_DRIVE == pData->type);
418 BOOL32 WINAPI _ILIsFolder(LPCITEMIDLIST pidl)
419 { LPPIDLDATA pData;
420 TRACE(pidl,"(%p)\n",pidl);
422 if (! pidl)
423 return FALSE;
425 pData = _ILGetDataPointer(pidl);
426 return (PT_FOLDER == pData->type);
429 BOOL32 WINAPI _ILIsValue(LPCITEMIDLIST pidl)
430 { LPPIDLDATA pData;
431 TRACE(pidl,"(%p)\n",pidl);
433 if (! pidl)
434 return FALSE;
436 pData = _ILGetDataPointer(pidl);
437 return (PT_VALUE == pData->type);
439 /**************************************************************************
440 * _ILHasFolders()
441 * fixme: quick hack
443 BOOL32 WINAPI _ILHasFolders( LPSTR pszPath, LPCITEMIDLIST pidl)
444 { BOOL32 bResult= FALSE;
445 WIN32_FIND_DATA32A stffile;
446 HANDLE32 hFile;
448 TRACE(pidl,"%p %p\n", pszPath, pidl);
450 hFile = FindFirstFile32A(pszPath,&stffile);
452 { if (! (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
453 { bResult= TRUE;
455 } while( FindNextFile32A(hFile,&stffile));
456 FindClose32 (hFile);
458 return bResult;
461 /**************************************************************************
462 * _ILGetFolderText()
463 * Creates a Path string from a PIDL, filtering out the special Folders
465 DWORD WINAPI _ILGetFolderText(LPCITEMIDLIST pidl,LPSTR lpszPath, DWORD dwSize)
466 { LPITEMIDLIST pidlTemp;
467 DWORD dwCopied = 0;
468 LPSTR pText;
470 TRACE(pidl,"(%p)\n",pidl);
472 if(!pidl)
473 { return 0;
476 if(_ILIsMyComputer(pidl))
477 { pidlTemp = ILGetNext(pidl);
478 TRACE(pidl,"-- skip My Computer\n");
480 else
481 { pidlTemp = (LPITEMIDLIST)pidl;
484 //if this is NULL, return the required size of the buffer
485 if(!lpszPath)
486 { while(pidlTemp->mkid.cb)
487 { LPPIDLDATA pData = _ILGetDataPointer(pidlTemp);
488 pText = _ILGetTextPointer(pData->type,pData);
490 /*add the length of this item plus one for the backslash
491 fixme: is one to much, drive has its own backslash*/
492 dwCopied += strlen(pText) + 1;
493 pidlTemp = ILGetNext(pidlTemp);
496 //add one for the NULL terminator
497 TRACE(pidl,"-- (size=%lu)\n",dwCopied);
498 return dwCopied + 1;
501 *lpszPath = 0;
503 while(pidlTemp->mkid.cb && (dwCopied < dwSize))
504 { LPPIDLDATA pData = _ILGetDataPointer(pidlTemp);
506 //if this item is a value, then skip it and finish
507 if(PT_VALUE == pData->type)
508 { break;
510 pText = _ILGetTextPointer(pData->type,pData);
511 strcat(lpszPath, pText);
512 PathAddBackslash(lpszPath);
513 dwCopied += strlen(pText) + 1;
514 pidlTemp = ILGetNext(pidlTemp);
516 TRACE(pidl,"-- (size=%lu,%s)\n",dwCopied,lpszPath);
519 //remove the last backslash if necessary
520 if(dwCopied)
521 { if(*(lpszPath + strlen(lpszPath) - 1) == '\\')
522 { *(lpszPath + strlen(lpszPath) - 1) = 0;
523 dwCopied--;
526 TRACE(pidl,"-- (path=%s)\n",lpszPath);
527 return dwCopied;
531 /**************************************************************************
532 * _ILGetValueText()
533 * Gets the text for the last item in the list
535 DWORD WINAPI _ILGetValueText(
536 LPCITEMIDLIST pidl, LPSTR lpszValue, DWORD dwSize)
537 { LPITEMIDLIST pidlTemp=pidl;
538 CHAR szText[MAX_PATH];
540 TRACE(pidl,"(pidl=%p %p 0x%08lx)\n",pidl,lpszValue,dwSize);
542 if(!pidl)
543 { return 0;
546 while(pidlTemp->mkid.cb && !_ILIsValue(pidlTemp))
547 { pidlTemp = ILGetNext(pidlTemp);
550 if(!pidlTemp->mkid.cb)
551 { return 0;
554 _ILGetItemText( pidlTemp, szText, sizeof(szText));
556 if(!lpszValue)
557 { return strlen(szText) + 1;
559 strcpy(lpszValue, szText);
560 TRACE(pidl,"-- (pidl=%p %p=%s 0x%08lx)\n",pidl,lpszValue,lpszValue,dwSize);
561 return strlen(lpszValue);
563 /**************************************************************************
564 * _ILGetDataText()
565 * NOTES
566 * used from ShellView
568 DWORD WINAPI _ILGetDataText( LPCITEMIDLIST pidlPath, LPCITEMIDLIST pidlValue, LPSTR lpszOut, DWORD dwOutSize)
569 { LPSTR lpszFolder,
570 lpszValueName;
571 DWORD dwNameSize;
573 FIXME(pidl,"(pidl=%p pidl=%p) stub\n",pidlPath,pidlValue);
575 if(!lpszOut || !pidlPath || !pidlValue)
576 { return FALSE;
579 /* fixme: get the driveletter*/
581 //assemble the Folder string
582 dwNameSize = _ILGetFolderText(pidlPath, NULL, 0);
583 lpszFolder = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize);
584 if(!lpszFolder)
585 { return FALSE;
587 _ILGetFolderText(pidlPath, lpszFolder, dwNameSize);
589 //assemble the value name
590 dwNameSize = _ILGetValueText(pidlValue, NULL, 0);
591 lpszValueName = (LPSTR)HeapAlloc(GetProcessHeap(),0,dwNameSize);
592 if(!lpszValueName)
593 { HeapFree(GetProcessHeap(),0,lpszFolder);
594 return FALSE;
596 _ILGetValueText(pidlValue, lpszValueName, dwNameSize);
598 /* fixme: we've got the path now do something with it*/
600 HeapFree(GetProcessHeap(),0,lpszFolder);
601 HeapFree(GetProcessHeap(),0,lpszValueName);
603 TRACE(pidl,"-- (%p=%s 0x%08lx)\n",lpszOut,lpszOut,dwOutSize);
605 return TRUE;
608 /**************************************************************************
609 * _ILGetPidlPath()
610 * Create a string that includes the Drive name, the folder text and
611 * the value text.
613 DWORD WINAPI _ILGetPidlPath( LPCITEMIDLIST pidl, LPSTR lpszOut, DWORD dwOutSize)
614 { LPSTR lpszTemp;
615 WORD len;
617 TRACE(pidl,"(%p,%lu)\n",lpszOut,dwOutSize);
619 if(!lpszOut)
620 { return 0;
623 *lpszOut = 0;
624 lpszTemp = lpszOut;
626 dwOutSize -= _ILGetFolderText(pidl, lpszTemp, dwOutSize);
628 //add a backslash if necessary
629 len = strlen(lpszTemp);
630 if (len && lpszTemp[len-1]!='\\')
631 { lpszTemp[len+0]='\\';
632 lpszTemp[len+1]='\0';
633 dwOutSize--;
636 lpszTemp = lpszOut + strlen(lpszOut);
638 //add the value string
639 _ILGetValueText(pidl, lpszTemp, dwOutSize);
641 //remove the last backslash if necessary
642 if(*(lpszOut + strlen(lpszOut) - 1) == '\\')
643 { *(lpszOut + strlen(lpszOut) - 1) = 0;
646 TRACE(pidl,"-- (%p=%s,%lu)\n",lpszOut,lpszOut,dwOutSize);
648 return strlen(lpszOut);
652 /**************************************************************************
653 * _ILCreate()
654 * Creates a new PIDL
655 * type = PT_DESKTOP | PT_DRIVE | PT_FOLDER | PT_VALUE
656 * pIn = data
657 * uInSize = size of data
660 LPITEMIDLIST WINAPI _ILCreate(PIDLTYPE type, LPVOID pIn, UINT16 uInSize)
661 { LPITEMIDLIST pidlOut=NULL;
662 UINT16 uSize;
663 LPITEMIDLIST pidlTemp=NULL;
664 LPPIDLDATA pData;
665 LPSTR pszDest;
667 TRACE(pidl,"(%x %p %x)\n",type,pIn,uInSize);
669 if ( type == PT_DESKTOP)
670 { pidlOut = SHAlloc(2);
671 pidlOut->mkid.cb=0x0000;
672 return pidlOut;
675 if (! pIn)
676 { return NULL;
679 /* the sizes of: cb(2), pidldata-1, szText+1, next cb(2) */
680 switch (type)
681 { case PT_DRIVE:
682 uSize = 4 + 10;
683 break;
684 default:
685 uSize = 4 + (sizeof(PIDLDATA)) + uInSize;
687 pidlOut = SHAlloc(uSize);
688 pidlTemp = pidlOut;
689 if(pidlOut)
690 { pidlTemp->mkid.cb = uSize - 2;
691 pData =_ILGetDataPointer(pidlTemp);
692 pszDest = _ILGetTextPointer(type, pData);
693 pData->type = type;
694 switch(type)
695 { case PT_MYCOMP:
696 memcpy(pszDest, pIn, uInSize);
697 TRACE(pidl,"- create My Computer: %s\n",debugstr_a(pszDest));
698 break;
699 case PT_DRIVE:
700 memcpy(pszDest, pIn, uInSize);
701 TRACE(pidl,"- create Drive: %s\n",debugstr_a(pszDest));
702 break;
703 case PT_FOLDER:
704 case PT_VALUE:
705 memcpy(pszDest, pIn, uInSize);
706 TRACE(pidl,"- create Value: %s\n",debugstr_a(pszDest));
707 break;
708 default:
709 FIXME(pidl,"-- wrong argument\n");
710 break;
713 pidlTemp = ILGetNext(pidlTemp);
714 pidlTemp->mkid.cb = 0x00;
716 TRACE(pidl,"-- (pidl=%p, size=%u)\n",pidlOut,uSize-2);
717 return pidlOut;
719 /**************************************************************************
720 * _ILGetData(PIDLTYPE, LPCITEMIDLIST, LPVOID, UINT16)
722 DWORD WINAPI _ILGetData(PIDLTYPE type, LPCITEMIDLIST pidl, LPVOID pOut, UINT16 uOutSize)
723 { LPPIDLDATA pData;
724 DWORD dwReturn=0;
725 LPSTR pszSrc;
727 TRACE(pidl,"(%x %p %p %x)\n",type,pidl,pOut,uOutSize);
729 if(!pidl)
730 { return 0;
733 *(LPSTR)pOut = 0;
735 pData = _ILGetDataPointer(pidl);
736 if ( pData->type != type)
737 { ERR(pidl,"-- wrong type\n");
738 return 0;
740 pszSrc = _ILGetTextPointer(pData->type, pData);
742 switch(type)
743 { case PT_MYCOMP:
744 if(uOutSize < 1)
745 return 0;
746 strncpy((LPSTR)pOut, "My Computer", uOutSize);
747 dwReturn = strlen((LPSTR)pOut);
748 break;
750 case PT_DRIVE:
751 if(uOutSize < 1)
752 return 0;
753 strncpy((LPSTR)pOut, pszSrc, uOutSize);
754 dwReturn = strlen((LPSTR)pOut);
755 break;
757 case PT_FOLDER:
758 case PT_VALUE:
759 strncpy((LPSTR)pOut, pszSrc, uOutSize);
760 dwReturn = strlen((LPSTR)pOut);
761 break;
762 default:
763 ERR(pidl,"-- unknown type\n");
764 break;
766 TRACE(pidl,"-- (%p=%s 0x%08lx)\n",pOut,(char*)pOut,dwReturn);
767 return dwReturn;
771 /**************************************************************************
772 * _ILGetDataPointer()
774 LPPIDLDATA WINAPI _ILGetDataPointer(LPITEMIDLIST pidl)
775 { if(!pidl)
776 { return NULL;
778 /* TRACE(pidl,"(%p)\n", pidl);*/
779 return (LPPIDLDATA)(&pidl->mkid.abID);
781 /**************************************************************************
782 * _ILGetTextPointer()
783 * gets a pointer to the string stored in the pidl
785 LPSTR WINAPI _ILGetTextPointer(PIDLTYPE type, LPPIDLDATA pidldata)
786 {/* TRACE(pidl,"(type=%x data=%p)\n", type, pidldata);*/
788 if(!pidldata)
789 { return NULL;
791 switch (type)
792 { case PT_DRIVE:
793 return (LPSTR)&(pidldata->u.drive.szDriveName);
794 case PT_MYCOMP:
795 case PT_FOLDER:
796 case PT_VALUE:
797 return (LPSTR)&(pidldata->u.file.szText);
799 return NULL;