source: trunk/src/shell32/pidl.cpp@ 1469

Last change on this file since 1469 was 1469, checked in by phaller, 26 years ago

Fix: debug info

File size: 39.3 KB
Line 
1/* $Id: pidl.cpp,v 1.3 1999-10-27 09:03:31 phaller Exp $ */
2
3/*
4 * Win32 SHELL32 for OS/2
5 *
6 * Copyright 1999 Patrick Haller (haller@zebra.fh-weingarten.de)
7 * Project Odin Software License can be found in LICENSE.TXT
8 *
9 * pidl Handling
10 *
11 * Copyright 1998 Juergen Schmied
12 *
13 * NOTES
14 * a pidl == NULL means desktop and is legal
15 *
16 */
17
18/*****************************************************************************
19 * Includes *
20 *****************************************************************************/
21
22#include <odin.h>
23#include <odinwrap.h>
24#include <os2sel.h>
25
26#include <ctype.h>
27#include <stdlib.h>
28#include <string.h>
29#include <assert.h>
30
31#define ICOM_CINTERFACE 1
32#define CINTERFACE 1
33
34#include "debugtools.h"
35#include "shell.h"
36#include "shlguid.h"
37#include "winerror.h"
38#include "winnls.h"
39#include "winversion.h"
40#include "shell32_main.h"
41
42#include "pidl.h"
43#include "wine/undocshell.h"
44
45#include <heapstring.h>
46#include <misc.h>
47
48
49ODINDEBUGCHANNEL(SHELL32-PIDL)
50
51void pdump (LPCITEMIDLIST pidl)
52{ DWORD type;
53 char * szData;
54 char * szShortName;
55 char szName[MAX_PATH];
56 BOOL bIsShellDebug;
57
58 LPITEMIDLIST pidltemp = pidl;
59 if (!TRACE_ON(pidl))
60 return;
61
62 /* silence the sub-functions */
63 bIsShellDebug = TRACE_ON(shell);
64 __SET_DEBUGGING(__DBCL_TRACE, dbch_shell, FALSE);
65 __SET_DEBUGGING(__DBCL_TRACE, dbch_pidl, FALSE);
66
67 if (! pidltemp)
68 {
69 MESSAGE ("-------- pidl=NULL (Desktop)\n");
70 }
71 else
72 {
73 MESSAGE ("-------- pidl=%p\n", pidl);
74 if (pidltemp->mkid.cb)
75 {
76 do
77 {
78 type = _ILGetDataPointer(pidltemp)->type;
79 szData = _ILGetTextPointer(type, _ILGetDataPointer(pidltemp));
80 szShortName = _ILGetSTextPointer(type, _ILGetDataPointer(pidltemp));
81 _ILSimpleGetText(pidltemp, szName, MAX_PATH);
82
83 MESSAGE ("-- pidl=%p size=%u type=%lx name=%s (%s,%s)\n",
84 pidltemp, pidltemp->mkid.cb,type,szName,debugstr_a(szData), debugstr_a(szShortName));
85
86 pidltemp = ILGetNext(pidltemp);
87
88 } while (pidltemp->mkid.cb);
89 }
90 else
91 {
92 MESSAGE ("empty pidl (Desktop)\n");
93 }
94 }
95
96 __SET_DEBUGGING(__DBCL_TRACE, dbch_shell, bIsShellDebug);
97 __SET_DEBUGGING(__DBCL_TRACE, dbch_pidl, TRUE);
98
99}
100#define BYTES_PRINTED 32
101BOOL pcheck (LPCITEMIDLIST pidl)
102{ DWORD type, ret=TRUE;
103 BOOL bIsPidlDebug;
104
105 LPITEMIDLIST pidltemp = pidl;
106
107 bIsPidlDebug = TRACE_ON(shell);
108 __SET_DEBUGGING(__DBCL_TRACE, dbch_pidl, FALSE);
109
110 if (pidltemp && pidltemp->mkid.cb)
111 { do
112 { type = _ILGetDataPointer(pidltemp)->type;
113 switch (type)
114 { case PT_DESKTOP:
115 case PT_MYCOMP:
116 case PT_SPECIAL:
117 case PT_DRIVE:
118 case PT_DRIVE1:
119 case PT_DRIVE2:
120 case PT_DRIVE3:
121 case PT_FOLDER:
122 case PT_VALUE:
123 case PT_FOLDER1:
124 case PT_WORKGRP:
125 case PT_COMP:
126 case PT_NETWORK:
127 case PT_SHARE:
128 case PT_IESPECIAL:
129 break;
130 default:
131 {
132 char szTemp[BYTES_PRINTED*4 + 1];
133 int i;
134 unsigned char c;
135
136 memset(szTemp, ' ', BYTES_PRINTED*4 + 1);
137 for ( i = 0; (i<pidltemp->mkid.cb) && (i<BYTES_PRINTED); i++)
138 {
139 c = ((unsigned char *)pidltemp)[i];
140
141 szTemp[i*3+0] = ((c>>4)>9)? (c>>4)+55 : (c>>4)+48;
142 szTemp[i*3+1] = ((0x0F&c)>9)? (0x0F&c)+55 : (0x0F&c)+48;
143 szTemp[i*3+2] = ' ';
144 szTemp[i+BYTES_PRINTED*3] = (c>=0x20 && c <=0x80) ? c : '.';
145 }
146 szTemp[BYTES_PRINTED*4] = 0x00;
147 ERR_(pidl)("unknown IDLIST type size=%u type=%lx\n%s\n",pidltemp->mkid.cb,type, szTemp);
148 ret = FALSE;
149 }
150 }
151 pidltemp = ILGetNext(pidltemp);
152 } while (pidltemp->mkid.cb);
153 }
154 __SET_DEBUGGING(__DBCL_TRACE, dbch_pidl, bIsPidlDebug);
155 return ret;
156}
157
158/*************************************************************************
159 * ILGetDisplayName [SHELL32.15]
160 */
161
162ODINFUNCTION2(BOOL,ILGetDisplayName,LPCITEMIDLIST, pidl,
163 LPSTR, path)
164{
165 TRACE_(shell)("pidl=%p %p semi-stub\n",pidl,path);
166 return SHGetPathFromIDListA(pidl, path);
167}
168
169
170/*************************************************************************
171 * ILFindLastID [SHELL32.16]
172 *
173 * NOTES
174 * observed: pidl=Desktop return=pidl
175 */
176
177ODINFUNCTION1(LPITEMIDLIST,ILFindLastID,LPITEMIDLIST, pidl)
178{ LPITEMIDLIST pidlLast = pidl;
179
180 while (pidl->mkid.cb)
181 {
182 pidlLast = pidl;
183 pidl = ILGetNext(pidl);
184 }
185 return pidlLast;
186}
187/*************************************************************************
188 * ILRemoveLastID [SHELL32.17]
189 *
190 * NOTES
191 * when pidl=Desktop return=FALSE
192 */
193
194ODINFUNCTION1(BOOL,ILRemoveLastID,LPCITEMIDLIST, pidl)
195{
196 if (!pidl || !pidl->mkid.cb)
197 return 0;
198 ILFindLastID(pidl)->mkid.cb = 0;
199 return 1;
200}
201
202/*************************************************************************
203 * ILClone [SHELL32.18]
204 *
205 * NOTES
206 * dupicate an idlist
207 */
208
209ODINFUNCTION1(LPITEMIDLIST,ILClone,LPCITEMIDLIST,pidl)
210{ DWORD len;
211 LPITEMIDLIST newpidl;
212
213 if (!pidl)
214 return NULL;
215
216 len = ILGetSize(pidl);
217 newpidl = (LPITEMIDLIST)SHAlloc(len);
218 if (newpidl)
219 memcpy(newpidl,pidl,len);
220
221 TRACE_(pidl)("pidl=%p newpidl=%p\n",pidl, newpidl);
222 pdump(pidl);
223
224 return newpidl;
225}
226
227
228/*************************************************************************
229 * ILCloneFirst [SHELL32.19]
230 *
231 * NOTES
232 * duplicates the first idlist of a complex pidl
233 */
234
235ODINFUNCTION1(LPITEMIDLIST,ILCloneFirst,LPCITEMIDLIST,pidl)
236{ DWORD len;
237 LPITEMIDLIST pidlNew = NULL;
238
239 pdump(pidl);
240
241 if (pidl)
242 {
243 len = pidl->mkid.cb;
244 pidlNew = (LPITEMIDLIST) SHAlloc (len+2);
245 if (pidlNew)
246 {
247 memcpy(pidlNew,pidl,len+2); /* 2 -> mind a desktop pidl */
248
249 if (len)
250 ILGetNext(pidlNew)->mkid.cb = 0x00;
251 }
252 }
253 TRACE_(pidl)("-- newpidl=%p\n",pidlNew);
254
255 return pidlNew;
256}
257/*************************************************************************
258 * ILLoadFromStream
259 *
260 * NOTES
261 * the first two bytes are the len, the pidl is following then
262 */
263
264ODINFUNCTION2(HRESULT,ILLoadFromStream,IStream*, pStream,
265 LPITEMIDLIST*, ppPidl)
266{ WORD wLen = 0;
267 DWORD dwBytesRead;
268 HRESULT ret = E_FAIL;
269
270 if (*ppPidl)
271 { SHFree(*ppPidl);
272 *ppPidl = NULL;
273 }
274
275 IStream_AddRef (pStream);
276
277 if (SUCCEEDED(IStream_Read(pStream, (LPVOID)&wLen, 2, &dwBytesRead)))
278 { *ppPidl = (ITEMIDLIST*)SHAlloc (wLen);
279 if (SUCCEEDED(IStream_Read(pStream, *ppPidl , wLen, &dwBytesRead)))
280 { ret = S_OK;
281 }
282 else
283 { SHFree(*ppPidl);
284 *ppPidl = NULL;
285 }
286 }
287
288 /* we are not jet fully compatible */
289 if (!pcheck(*ppPidl))
290 { SHFree(*ppPidl);
291 *ppPidl = NULL;
292 }
293
294
295 IStream_Release (pStream);
296
297 return ret;
298}
299/*************************************************************************
300 * SHILCreateFromPath [SHELL32.28]
301 *
302 * NOTES
303 * wraper for IShellFolder::ParseDisplayName()
304 */
305
306ODINFUNCTION3(HRESULT,SHILCreateFromPathA,LPCSTR, path,
307 LPITEMIDLIST*, ppidl,
308 DWORD*, attributes)
309{ LPSHELLFOLDER sf;
310 WCHAR lpszDisplayName[MAX_PATH];
311 DWORD pchEaten;
312 HRESULT ret = E_FAIL;
313
314 LocalToWideChar(lpszDisplayName, (LPSTR)path, MAX_PATH);
315
316 if (SUCCEEDED (SHGetDesktopFolder(&sf)))
317 {
318 ret = IShellFolder_ParseDisplayName(sf,0, NULL,lpszDisplayName,&pchEaten,ppidl,attributes);
319 IShellFolder_Release(sf);
320 }
321 return ret;
322}
323
324ODINFUNCTION3(HRESULT,SHILCreateFromPathW,LPCWSTR, path,
325 LPITEMIDLIST*, ppidl,
326 DWORD*, attributes)
327{ LPSHELLFOLDER sf;
328 DWORD pchEaten;
329 HRESULT ret = E_FAIL;
330
331 if (SUCCEEDED (SHGetDesktopFolder(&sf)))
332 {
333 ret = IShellFolder_ParseDisplayName(sf,0, NULL, (LPOLESTR)path, &pchEaten, ppidl, attributes);
334 IShellFolder_Release(sf);
335 }
336 return ret;
337}
338
339ODINFUNCTION3(HRESULT,SHILCreateFromPathAW,LPCVOID, path,
340 LPITEMIDLIST*, ppidl,
341 DWORD*, attributes)
342{
343 if ( VERSION_OsIsUnicode())
344 return SHILCreateFromPathW ((LPCWSTR)path, ppidl, attributes);
345 return SHILCreateFromPathA ((LPCSTR)path, ppidl, attributes);
346}
347
348/*************************************************************************
349 * SHCloneSpecialIDList [SHELL32.89]
350 *
351 * PARAMETERS
352 * hwndOwner [in]
353 * nFolder [in] CSIDL_xxxxx ??
354 *
355 * RETURNS
356 * pidl ??
357 * NOTES
358 * exported by ordinal
359 */
360
361ODINFUNCTION3(LPITEMIDLIST,SHCloneSpecialIDList,HWND, hwndOwner,
362 DWORD, nFolder,
363 DWORD, x3)
364{ LPITEMIDLIST ppidl;
365 WARN_(shell)("(hwnd=0x%x,csidl=0x%lx,0x%lx):semi-stub.\n",
366 hwndOwner,nFolder,x3);
367
368 SHGetSpecialFolderLocation(hwndOwner, nFolder, &ppidl);
369
370 return ppidl;
371}
372
373/*************************************************************************
374 * ILGlobalClone [SHELL32.97]
375 *
376 */
377
378ODINFUNCTION1(LPITEMIDLIST,ILGlobalClone,LPCITEMIDLIST, pidl)
379{ DWORD len;
380 LPITEMIDLIST newpidl;
381
382 if (!pidl)
383 return NULL;
384
385 len = ILGetSize(pidl);
386 newpidl = (LPITEMIDLIST)pCOMCTL32_Alloc(len);
387 if (newpidl)
388 memcpy(newpidl,pidl,len);
389
390 TRACE_(pidl)("pidl=%p newpidl=%p\n",pidl, newpidl);
391 pdump(pidl);
392
393 return newpidl;
394}
395
396/*************************************************************************
397 * ILIsEqual [SHELL32.21]
398 *
399 */
400
401ODINFUNCTION2(BOOL,ILIsEqual,LPCITEMIDLIST, pidl1,
402 LPCITEMIDLIST, pidl2)
403{
404 char szData1[MAX_PATH];
405 char szData2[MAX_PATH];
406
407 LPITEMIDLIST pidltemp1 = pidl1;
408 LPITEMIDLIST pidltemp2 = pidl2;
409
410 /* explorer reads from registry directly (StreamMRU),
411 so we can only check here */
412 if ((!pcheck (pidl1)) || (!pcheck (pidl2))) return FALSE;
413
414 pdump (pidl1);
415 pdump (pidl2);
416
417 if ( (!pidl1) || (!pidl2) ) return FALSE;
418
419 while (pidltemp1->mkid.cb && pidltemp2->mkid.cb)
420 {
421 _ILSimpleGetText(pidltemp1, szData1, MAX_PATH);
422 _ILSimpleGetText(pidltemp2, szData2, MAX_PATH);
423
424 if (strcmp ( szData1, szData2 )!=0 )
425 return FALSE;
426
427 pidltemp1 = ILGetNext(pidltemp1);
428 pidltemp2 = ILGetNext(pidltemp2);
429 }
430
431 if (!pidltemp1->mkid.cb && !pidltemp2->mkid.cb)
432 {
433 return TRUE;
434 }
435
436 return FALSE;
437}
438/*************************************************************************
439 * ILIsParent [SHELL32.23]
440 *
441 * parent=a/b child=a/b/c -> true, c is in folder a/b
442 * child=a/b/c/d -> false if bImmediate is true, d is not in folder a/b
443 * child=a/b/c/d -> true if bImmediate is false, d is in a subfolder of a/b
444 */
445
446ODINFUNCTION3(BOOL,ILIsParent,LPCITEMIDLIST, pidlParent,
447 LPCITEMIDLIST, pidlChild,
448 BOOL, bImmediate)
449{
450 char szData1[MAX_PATH];
451 char szData2[MAX_PATH];
452
453 LPITEMIDLIST pParent = pidlParent;
454 LPITEMIDLIST pChild = pidlChild;
455
456 while (pParent->mkid.cb && pChild->mkid.cb)
457 {
458 _ILSimpleGetText(pParent, szData1, MAX_PATH);
459 _ILSimpleGetText(pChild, szData2, MAX_PATH);
460
461 if (strcmp ( szData1, szData2 )!=0 )
462 return FALSE;
463
464 pParent = ILGetNext(pParent);
465 pChild = ILGetNext(pChild);
466 }
467
468 if ( pParent->mkid.cb || ! pChild->mkid.cb) /* child shorter or has equal length to parent */
469 return FALSE;
470
471 if ( ILGetNext(pChild)->mkid.cb && bImmediate) /* not immediate descent */
472 return FALSE;
473
474 return TRUE;
475}
476
477/*************************************************************************
478 * ILFindChild [SHELL32.24]
479 *
480 * NOTES
481 * Compares elements from pidl1 and pidl2.
482 *
483 * pidl1 is desktop pidl2
484 * pidl1 shorter pidl2 pointer to first different element of pidl2
485 * if there was at least one equal element
486 * pidl2 shorter pidl1 0
487 * pidl2 equal pidl1 pointer to last 0x00-element of pidl2
488 */
489
490ODINFUNCTION2(LPITEMIDLIST,ILFindChild,LPCITEMIDLIST, pidl1,
491 LPCITEMIDLIST, pidl2)
492{
493 char szData1[MAX_PATH];
494 char szData2[MAX_PATH];
495
496 LPITEMIDLIST pidltemp1 = pidl1;
497 LPITEMIDLIST pidltemp2 = pidl2;
498 LPITEMIDLIST ret=NULL;
499
500 /* explorer reads from registry directly (StreamMRU),
501 so we can only check here */
502 if ((!pcheck (pidl1)) || (!pcheck (pidl2)))
503 return FALSE;
504
505 pdump (pidl1);
506 pdump (pidl2);
507
508 if ( _ILIsDesktop(pidl1) )
509 {
510 ret = pidl2;
511 }
512 else
513 {
514 while (pidltemp1->mkid.cb && pidltemp2->mkid.cb)
515 {
516 _ILSimpleGetText(pidltemp1, szData1, MAX_PATH);
517 _ILSimpleGetText(pidltemp2, szData2, MAX_PATH);
518
519 if (strcmp(szData1,szData2))
520 break;
521
522 pidltemp1 = ILGetNext(pidltemp1);
523 pidltemp2 = ILGetNext(pidltemp2);
524 ret = pidltemp2;
525 }
526
527 if (pidltemp1->mkid.cb)
528 {
529 ret = NULL; /* elements of pidl1 left*/
530 }
531 }
532 TRACE_(shell)("--- %p\n", ret);
533 return ret; /* pidl 1 is shorter */
534}
535
536/*************************************************************************
537 * ILCombine [SHELL32.25]
538 *
539 * NOTES
540 * Concatenates two complex idlists.
541 * The pidl is the first one, pidlsub the next one
542 * Does not destroy the passed in idlists!
543 */
544
545ODINFUNCTION2(LPITEMIDLIST, ILCombine, LPCITEMIDLIST, pidl1,
546 LPCITEMIDLIST, pidl2)
547{
548 DWORD len1,len2;
549 LPITEMIDLIST pidlNew;
550
551 if(!pidl1 && !pidl2) return NULL;
552
553 pdump (pidl1);
554 pdump (pidl2);
555
556 if(!pidl1)
557 {
558 pidlNew = ILClone(pidl2);
559 return pidlNew;
560 }
561
562 if(!pidl2)
563 {
564 pidlNew = ILClone(pidl1);
565 return pidlNew;
566 }
567
568 len1 = ILGetSize(pidl1)-2;
569 len2 = ILGetSize(pidl2);
570 pidlNew = (ITEMIDLIST*)SHAlloc(len1+len2);
571
572 if (pidlNew)
573 {
574 memcpy(pidlNew,pidl1,len1);
575 memcpy(((BYTE *)pidlNew)+len1,pidl2,len2);
576 }
577
578 /* TRACE(pidl,"--new pidl=%p\n",pidlNew);*/
579 return pidlNew;
580}
581/*************************************************************************
582 * SHGetRealIDL [SHELL32.98]
583 *
584 * NOTES
585 */
586
587ODINFUNCTION3(LPITEMIDLIST, SHGetRealIDL, LPSHELLFOLDER, lpsf,
588 LPITEMIDLIST, pidl,
589 DWORD, z)
590{
591 FIXME_(pidl)("sf=%p pidl=%p 0x%04lx\n",lpsf,pidl,z);
592
593 pdump (pidl);
594 return 0;
595}
596
597/*************************************************************************
598 * SHLogILFromFSIL [SHELL32.95]
599 *
600 * NOTES
601 * pild = CSIDL_DESKTOP ret = 0
602 * pild = CSIDL_DRIVES ret = 0
603 */
604
605ODINFUNCTION1(LPITEMIDLIST,SHLogILFromFSIL,LPITEMIDLIST,pidl)
606{
607 FIXME_(pidl)("(pidl=%p)\n",pidl);
608
609 pdump(pidl);
610
611 return 0;
612}
613
614/*************************************************************************
615 * ILGetSize [SHELL32.152]
616 * gets the byte size of an idlist including zero terminator (pidl)
617 *
618 * PARAMETERS
619 * pidl ITEMIDLIST
620 *
621 * RETURNS
622 * size of pidl
623 *
624 * NOTES
625 * exported by ordinal
626 */
627
628ODINFUNCTION1(DWORD,ILGetSize,LPITEMIDLIST,pidl)
629{
630 LPSHITEMID si = &(pidl->mkid);
631 DWORD len=0;
632
633 if (pidl)
634 { while (si->cb)
635 { len += si->cb;
636 si = (LPSHITEMID)(((LPBYTE)si)+si->cb);
637 }
638 len += 2;
639 }
640 TRACE_(pidl)("pidl=%p size=%lu\n",pidl, len);
641 return len;
642}
643
644/*************************************************************************
645 * ILGetNext [SHELL32.153]
646 * gets the next simple pidl of a complex pidl
647 *
648 * observed return values:
649 * null -> null
650 * desktop -> null
651 * simple pidl -> pointer to 0x0000 element
652 *
653 */
654
655ODINFUNCTION1(LPITEMIDLIST,ILGetNext,LPITEMIDLIST,pidl)
656{
657 WORD len;
658
659 if(pidl)
660 {
661 len = pidl->mkid.cb;
662 if (len)
663 {
664 pidl = (LPITEMIDLIST) (((LPBYTE)pidl)+len);
665 return pidl;
666 }
667 }
668 return NULL;
669}
670/*************************************************************************
671 * ILAppend [SHELL32.154]
672 *
673 * NOTES
674 * Adds the single item to the idlist indicated by pidl.
675 * if bEnd is 0, adds the item to the front of the list,
676 * otherwise adds the item to the end. (???)
677 * Destroys the passed in idlist! (???)
678 */
679
680ODINFUNCTION3(LPITEMIDLIST,ILAppend,LPITEMIDLIST, pidl,
681 LPCITEMIDLIST, item,
682 BOOL, bEnd)
683{
684 LPITEMIDLIST idlRet;
685
686 WARN_(pidl)("(pidl=%p,pidl=%p,%08u)semi-stub\n",pidl,item,bEnd);
687
688 pdump (pidl);
689 pdump (item);
690
691 if (_ILIsDesktop(pidl))
692 {
693 idlRet = ILClone(item);
694 if (pidl)
695 SHFree (pidl);
696 return idlRet;
697 }
698
699 if (bEnd)
700 {
701 idlRet=ILCombine(pidl,item);
702 }
703 else
704 {
705 idlRet=ILCombine(item,pidl);
706 }
707
708 SHFree(pidl);
709 return idlRet;
710}
711/*************************************************************************
712 * ILFree [SHELL32.155]
713 *
714 * NOTES
715 * free_check_ptr - frees memory (if not NULL)
716 * allocated by SHMalloc allocator
717 * exported by ordinal
718 */
719
720ODINFUNCTION1(DWORD,ILFree,LPITEMIDLIST, pidl)
721{ TRACE_(pidl)("(pidl=0x%08lx)\n",(DWORD)pidl);
722
723 if (!pidl)
724 return FALSE;
725
726 return SHFree(pidl);
727}
728/*************************************************************************
729 * ILGlobalFree [SHELL32.156]
730 *
731 */
732
733ODINFUNCTION1(DWORD,ILGlobalFree,LPITEMIDLIST, pidl)
734{
735 TRACE_(pidl)("%p\n",pidl);
736
737 if (!pidl)
738 return FALSE;
739
740 return pCOMCTL32_Free (pidl);
741}
742/*************************************************************************
743 * ILCreateFromPath [SHELL32.157]
744 *
745 */
746
747ODINFUNCTION1(LPITEMIDLIST,ILCreateFromPathA,LPCSTR,path)
748{
749 LPITEMIDLIST pidlnew;
750 DWORD attributes = 0;
751
752 TRACE_(shell)("%s\n",path);
753
754 if (SUCCEEDED (SHILCreateFromPathA (path, &pidlnew, &attributes)))
755 return pidlnew;
756 return FALSE;
757}
758
759ODINFUNCTION1(LPITEMIDLIST,ILCreateFromPathW,LPCWSTR,path)
760{
761 LPITEMIDLIST pidlnew;
762 DWORD attributes = 0;
763
764 TRACE_(shell)("%s\n",debugstr_w(path));
765
766 if (SUCCEEDED (SHILCreateFromPathW (path, &pidlnew, &attributes)))
767 return pidlnew;
768 return FALSE;
769}
770
771ODINFUNCTION1(LPITEMIDLIST,ILCreateFromPathAW,LPCVOID,path)
772{
773 if ( VERSION_OsIsUnicode())
774 return ILCreateFromPathW ((LPCWSTR)path);
775 return ILCreateFromPathA ((LPCSTR)path);
776}
777/*************************************************************************
778 * SHSimpleIDListFromPath [SHELL32.162]
779 */
780
781ODINFUNCTION1(LPITEMIDLIST,SHSimpleIDListFromPathA,LPSTR, lpszPath)
782{
783 LPITEMIDLIST pidl=NULL;
784 HANDLE hFile;
785 WIN32_FIND_DATAA stffile;
786
787 if (!lpszPath) return NULL;
788
789 hFile = FindFirstFileA(lpszPath, &stffile);
790
791 if ( hFile != INVALID_HANDLE_VALUE )
792 {
793 if (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
794 {
795 pidl = _ILCreateFolder (&stffile);
796 }
797 else
798 {
799 pidl = _ILCreateValue (&stffile);
800 }
801 FindClose (hFile);
802 }
803 return pidl;
804}
805
806ODINFUNCTION1(LPITEMIDLIST,SHSimpleIDListFromPathW,LPWSTR, lpszPath)
807{
808 char lpszTemp[MAX_PATH];
809
810 WideCharToLocal(lpszTemp, lpszPath, MAX_PATH);
811
812 return SHSimpleIDListFromPathA (lpszTemp);
813}
814
815ODINFUNCTION1(LPITEMIDLIST,SHSimpleIDListFromPathAW,LPVOID, lpszPath)
816{
817 if ( VERSION_OsIsUnicode())
818 return SHSimpleIDListFromPathW ((LPWSTR)lpszPath);
819 return SHSimpleIDListFromPathA ((LPSTR)lpszPath);
820}
821
822/*************************************************************************
823 * SHGetSpecialFolderLocation [SHELL32.223]
824 *
825 * gets the folder locations from the registry and creates a pidl
826 * creates missing reg keys and directorys
827 *
828 * PARAMS
829 * hwndOwner [I]
830 * nFolder [I] CSIDL_xxxxx
831 * ppidl [O] PIDL of a special folder
832 *
833 */
834ODINFUNCTION3(HRESULT,SHGetSpecialFolderLocation,HWND, hwndOwner,
835 INT, nFolder,
836 LPITEMIDLIST*, ppidl)
837{
838 CHAR szPath[256];
839 HRESULT hr = E_INVALIDARG;
840
841 *ppidl = NULL;
842
843 if (ppidl)
844 {
845 switch (nFolder)
846 {
847 case CSIDL_DESKTOP:
848 *ppidl = _ILCreateDesktop();
849 hr = NOERROR;
850 break;
851
852 case CSIDL_DRIVES:
853 *ppidl = _ILCreateMyComputer();
854 hr = NOERROR;
855 break;
856
857 default:
858 if (SHGetSpecialFolderPathA(hwndOwner, szPath, nFolder, TRUE))
859 {
860 DWORD attributes=0;
861 TRACE_(shell)("Value=%s\n",szPath);
862 hr = SHILCreateFromPathA(szPath, ppidl, &attributes);
863 }
864 }
865 }
866
867 TRACE_(shell)("-- (new pidl %p)\n",*ppidl);
868 return hr;
869}
870
871/*************************************************************************
872 * SHGetDataFromIDListA [SHELL32.247]
873 *
874 */
875
876ODINFUNCTION5(HRESULT,SHGetDataFromIDListA,LPSHELLFOLDER, psf,
877 LPCITEMIDLIST, pidl,
878 int, nFormat,
879 LPVOID, dest,
880 int, len)
881{
882 TRACE_(shell)("sf=%p pidl=%p 0x%04x %p 0x%04x stub\n",psf,pidl,nFormat,dest,len);
883
884 if (! psf || !dest ) return E_INVALIDARG;
885
886 switch (nFormat)
887 {
888 case SHGDFIL_FINDDATA:
889 {
890 WIN32_FIND_DATAA * pfd = (WIN32_FIND_DATAA*)dest;
891 CHAR pszPath[MAX_PATH];
892 HANDLE handle;
893
894 if ( len < sizeof (WIN32_FIND_DATAA)) {
895 ERR_(shell)("%d does not find sizeof(finddata)\n",len);
896 return E_INVALIDARG;
897 }
898
899 SHGetPathFromIDListA(pidl, pszPath);
900
901 if ((handle = FindFirstFileA ( pszPath, pfd)))
902 FindClose (handle);
903 }
904 return NOERROR;
905
906 case SHGDFIL_NETRESOURCE:
907 case SHGDFIL_DESCRIPTIONID:
908 FIXME_(shell)("SHGDFIL %i stub\n", nFormat);
909 break;
910
911 default:
912 ERR_(shell)("Unknown SHGDFIL %i, please report\n", nFormat);
913 }
914
915 return E_INVALIDARG;
916}
917/*************************************************************************
918 * SHGetDataFromIDListW [SHELL32.247]
919 *
920 */
921
922ODINFUNCTION5(HRESULT,SHGetDataFromIDListW,LPSHELLFOLDER, psf,
923 LPCITEMIDLIST, pidl,
924 int, nFormat,
925 LPVOID, dest,
926 int, len)
927{
928 if (! psf || !dest ) return E_INVALIDARG;
929
930 switch (nFormat)
931 {
932 case SHGDFIL_FINDDATA:
933 {
934 WIN32_FIND_DATAW * pfd = (WIN32_FIND_DATAW*)dest;
935 WCHAR pszPath[MAX_PATH];
936 HANDLE handle;
937
938 if ( len < sizeof (WIN32_FIND_DATAW)) {
939 ERR_(shell)("%d does not find sizeof(finddata)\n",len);
940 return E_INVALIDARG;
941 }
942 SHGetPathFromIDListW(pidl, pszPath);
943 if ((handle = FindFirstFileW ( pszPath, pfd)))
944 FindClose (handle);
945 }
946 return NOERROR;
947 default: /* fallthrough */
948 break;
949 }
950 FIXME_(shell)("(sf=%p pidl=%p nFormat=0x%04x %p 0x%04x), unhandled.\n",psf,pidl,nFormat,dest,len);
951 return SHGetDataFromIDListA( psf, pidl, nFormat, dest, len);
952}
953
954/*************************************************************************
955 * SHGetPathFromIDListA [SHELL32.261][NT 4.0: SHELL32.220]
956 *
957 * PARAMETERS
958 * pidl, [IN] pidl
959 * pszPath [OUT] path
960 *
961 * RETURNS
962 * path from a passed PIDL.
963 *
964 * NOTES
965 * NULL returns FALSE
966 * desktop pidl gives path to desktopdirectory back
967 * special pidls returning FALSE
968 *
969 * FIXME
970 * fnGetDisplayNameOf can return different types of OLEString
971 */
972
973ODINFUNCTION2(BOOL,SHGetPathFromIDListA,LPCITEMIDLIST, pidl,
974 LPSTR, pszPath)
975{ STRRET str;
976 LPSHELLFOLDER shellfolder;
977
978 if (!pidl) return FALSE;
979
980 pdump(pidl);
981
982 if(_ILIsDesktop(pidl))
983 {
984 SHGetSpecialFolderPathA(0, pszPath, CSIDL_DESKTOPDIRECTORY, FALSE);
985 }
986 else
987 {
988 if (SHGetDesktopFolder(&shellfolder)==S_OK)
989 {
990 IShellFolder_GetDisplayNameOf(shellfolder,pidl,SHGDN_FORPARSING,&str);
991 StrRetToStrNA (pszPath, MAX_PATH, &str, pidl);
992 IShellFolder_Release(shellfolder);
993 }
994 }
995 TRACE_(shell)("-- (%s)\n",pszPath);
996
997 return TRUE;
998}
999/*************************************************************************
1000 * SHGetPathFromIDListW [SHELL32.262]
1001 */
1002
1003ODINFUNCTION2(BOOL,SHGetPathFromIDListW,LPCITEMIDLIST, pidl,
1004 LPWSTR, pszPath)
1005{ char sTemp[MAX_PATH];
1006
1007 SHGetPathFromIDListA (pidl, sTemp);
1008 lstrcpyAtoW(pszPath, sTemp);
1009
1010 TRACE_(shell)("-- (%s)\n",debugstr_w(pszPath));
1011
1012 return TRUE;
1013}
1014
1015/*************************************************************************
1016 * SHBindToParent [shell version 5.0]
1017 */
1018
1019ODINFUNCTION4(HRESULT,SHBindToParent,LPCITEMIDLIST, pidl,
1020 REFIID, riid,
1021 LPVOID*, ppv,
1022 LPCITEMIDLIST*,ppidlLast)
1023{
1024 IShellFolder * psf;
1025 LPITEMIDLIST pidlChild, pidlParent;
1026 HRESULT hr=E_FAIL;
1027
1028 pdump(pidl);
1029
1030 *ppv = NULL;
1031 if (ppidlLast) *ppidlLast = NULL;
1032
1033 if (_ILIsPidlSimple(pidl))
1034 {
1035 /* we are on desktop level */
1036 if (ppidlLast)
1037 *ppidlLast = ILClone(pidl);
1038 hr = SHGetDesktopFolder((IShellFolder**)ppv);
1039 }
1040 else
1041 {
1042 pidlChild = ILClone(ILFindLastID(pidl));
1043 pidlParent = ILClone(pidl);
1044 ILRemoveLastID(pidlParent);
1045
1046 hr = SHGetDesktopFolder(&psf);
1047
1048 if (SUCCEEDED(hr))
1049 hr = IShellFolder_BindToObject(psf, pidlParent, NULL, riid, ppv);
1050
1051 if (SUCCEEDED(hr) && ppidlLast)
1052 *ppidlLast = pidlChild;
1053 else
1054 ILFree (pidlChild);
1055
1056 SHFree (pidlParent);
1057 }
1058
1059
1060 TRACE_(shell)("-- psf=%p pidl=%p ret=0x%08lx\n", *ppv, (ppidlLast)?*ppidlLast:NULL, hr);
1061 return hr;
1062}
1063
1064/*************************************************************************
1065 * SHGetPathFromIDListAW [SHELL32.221][NT 4.0: SHELL32.219]
1066 */
1067
1068ODINFUNCTION2(BOOL,SHGetPathFromIDListAW,LPCITEMIDLIST, pidl,
1069 LPVOID, pszPath)
1070{
1071 if (VERSION_OsIsUnicode())
1072 return SHGetPathFromIDListW(pidl,(LPWSTR)pszPath);
1073 return SHGetPathFromIDListA(pidl,(LPSTR)pszPath);
1074}
1075
1076/**************************************************************************
1077 *
1078 * internal functions
1079 *
1080 * ### 1. section creating pidls ###
1081 *
1082 *************************************************************************
1083 * _ILCreateDesktop()
1084 * _ILCreateIExplore()
1085 * _ILCreateMyComputer()
1086 * _ILCreateDrive()
1087 * _ILCreateFolder()
1088 * _ILCreateValue()
1089 */
1090
1091ODINFUNCTION0(LPITEMIDLIST,_ILCreateDesktop)
1092{
1093 return _ILCreate(PT_DESKTOP, NULL, 0);
1094}
1095
1096ODINFUNCTION0(LPITEMIDLIST,_ILCreateMyComputer)
1097{
1098 return _ILCreate(PT_MYCOMP, &IID_MyComputer, sizeof(GUID));
1099}
1100
1101ODINFUNCTION0(LPITEMIDLIST,_ILCreateIExplore)
1102{
1103 return _ILCreate(PT_MYCOMP, &IID_IExplore, sizeof(GUID));
1104}
1105
1106ODINFUNCTION1(LPITEMIDLIST,_ILCreateDrive,LPCSTR,lpszNew)
1107{ char sTemp[4];
1108 lstrcpynA (sTemp,lpszNew,4);
1109 sTemp[2]='\\';
1110 sTemp[3]=0x00;
1111 TRACE_(pidl)("(%s)\n",sTemp);
1112 return _ILCreate(PT_DRIVE,(LPVOID)&sTemp[0],4);
1113}
1114
1115ODINFUNCTION1(LPITEMIDLIST,_ILCreateFolder,WIN32_FIND_DATAA*, stffile )
1116{
1117 char buff[MAX_PATH + 14 +1]; /* see WIN32_FIND_DATA */
1118 char * pbuff = buff;
1119 ULONG len, len1;
1120 LPITEMIDLIST pidl;
1121
1122 TRACE_(pidl)("(%s, %s)\n",stffile->cAlternateFileName, stffile->cFileName);
1123
1124 /* prepare buffer with both names */
1125 len = strlen (stffile->cFileName) + 1;
1126 memcpy (pbuff, stffile->cFileName, len);
1127 pbuff += len;
1128
1129 if (stffile->cAlternateFileName)
1130 {
1131 len1 = strlen (stffile->cAlternateFileName)+1;
1132 memcpy (pbuff, stffile->cAlternateFileName, len1);
1133 }
1134 else
1135 {
1136 len1 = 1;
1137 *pbuff = 0x00;
1138 }
1139
1140 pidl = _ILCreate(PT_FOLDER, (LPVOID)buff, len + len1);
1141
1142 /* set attributes */
1143 if (pidl)
1144 {
1145 LPPIDLDATA pData;
1146 pData = _ILGetDataPointer(pidl);
1147 FileTimeToDosDateTime(&(stffile->ftLastWriteTime),&pData->u.folder.uFileDate,&pData->u.folder.uFileTime);
1148 pData->u.folder.dwFileSize = stffile->nFileSizeLow;
1149 pData->u.folder.uFileAttribs=stffile->dwFileAttributes;
1150 }
1151
1152 return pidl;
1153}
1154
1155ODINFUNCTION1(LPITEMIDLIST,_ILCreateValue,WIN32_FIND_DATAA*, stffile)
1156{
1157 char buff[MAX_PATH + 14 +1]; /* see WIN32_FIND_DATA */
1158 char * pbuff = buff;
1159 ULONG len, len1;
1160 LPITEMIDLIST pidl;
1161
1162 TRACE_(pidl)("(%s, %s)\n",stffile->cAlternateFileName, stffile->cFileName);
1163
1164 /* prepare buffer with both names */
1165 len = strlen (stffile->cFileName) + 1;
1166 memcpy (pbuff, stffile->cFileName, len);
1167 pbuff += len;
1168
1169 if (stffile->cAlternateFileName)
1170 {
1171 len1 = strlen (stffile->cAlternateFileName)+1;
1172 memcpy (pbuff, stffile->cAlternateFileName, len1);
1173 }
1174 else
1175 {
1176 len1 = 1;
1177 *pbuff = 0x00;
1178 }
1179
1180 pidl = _ILCreate(PT_VALUE, (LPVOID)buff, len + len1);
1181
1182 /* set attributes */
1183 if (pidl)
1184 {
1185 LPPIDLDATA pData;
1186 pData = _ILGetDataPointer(pidl);
1187 FileTimeToDosDateTime(&(stffile->ftLastWriteTime),&pData->u.folder.uFileDate,&pData->u.folder.uFileTime);
1188 pData->u.folder.dwFileSize = stffile->nFileSizeLow;
1189 pData->u.folder.uFileAttribs=stffile->dwFileAttributes;
1190 }
1191
1192 return pidl;
1193}
1194
1195ODINFUNCTION1(LPITEMIDLIST,_ILCreateSpecial,LPCSTR,szGUID)
1196{
1197 IID iid;
1198 CLSIDFromStringA(szGUID,&iid);
1199 return _ILCreate(PT_MYCOMP, &iid, sizeof(IID));
1200}
1201
1202/**************************************************************************
1203 * _ILCreate()
1204 * Creates a new PIDL
1205 * type = PT_DESKTOP | PT_DRIVE | PT_FOLDER | PT_VALUE
1206 * pIn = data
1207 * uInSize = size of data (raw)
1208 */
1209
1210ODINFUNCTION3(LPITEMIDLIST,_ILCreate,PIDLTYPE,type,
1211 LPCVOID, pIn,
1212 UINT16, uInSize)
1213{ LPITEMIDLIST pidlOut = NULL, pidlTemp = NULL;
1214 LPPIDLDATA pData;
1215 UINT16 uSize = 0;
1216 LPSTR pszDest;
1217
1218 switch (type)
1219 { case PT_DESKTOP:
1220 uSize = 0;
1221 pidlOut = (ITEMIDLIST*)SHAlloc(uSize + 2);
1222 pidlOut->mkid.cb = uSize;
1223 TRACE_(pidl)("- create Desktop\n");
1224 break;
1225
1226 case PT_MYCOMP:
1227 uSize = 2 + 2 + sizeof(GUID);
1228 pidlOut = (ITEMIDLIST*)SHAlloc(uSize + 2);
1229 ZeroMemory(pidlOut, uSize + 2);
1230 pidlOut->mkid.cb = uSize;
1231 pData =_ILGetDataPointer(pidlOut);
1232 pData->type = type;
1233 memcpy(&(pData->u.mycomp.guid), pIn, uInSize);
1234 TRACE_(pidl)("- create GUID-pidl\n");
1235 break;
1236
1237 case PT_DRIVE:
1238 uSize = 2 + 23;
1239 pidlOut = (ITEMIDLIST*)SHAlloc(uSize + 2);
1240 ZeroMemory(pidlOut, uSize + 2);
1241 pidlOut->mkid.cb = uSize;
1242 pData =_ILGetDataPointer(pidlOut);
1243 pData->type = type;
1244 pszDest = _ILGetTextPointer(type, pData);
1245 memcpy(pszDest, pIn, uInSize);
1246 TRACE_(pidl)("- create Drive: %s\n",debugstr_a(pszDest));
1247 break;
1248
1249 case PT_FOLDER:
1250 case PT_VALUE:
1251 uSize = 2 + 12 + uInSize;
1252 pidlOut = (ITEMIDLIST*)SHAlloc(uSize + 2);
1253 ZeroMemory(pidlOut, uSize + 2);
1254 pidlOut->mkid.cb = uSize;
1255 pData =_ILGetDataPointer(pidlOut);
1256 pData->type = type;
1257 pszDest = _ILGetTextPointer(type, pData);
1258 memcpy(pszDest, pIn, uInSize);
1259 TRACE_(pidl)("- create Value: %s\n",debugstr_a(pszDest));
1260 break;
1261 }
1262
1263 pidlTemp = ILGetNext(pidlOut);
1264 if (pidlTemp)
1265 pidlTemp->mkid.cb = 0x00;
1266
1267 TRACE_(pidl)("-- (pidl=%p, size=%u)\n", pidlOut, uSize);
1268 return pidlOut;
1269}
1270
1271/**************************************************************************
1272 * _ILGetDrive()
1273 *
1274 * Gets the text for the drive eg. 'c:\'
1275 *
1276 * RETURNS
1277 * strlen (lpszText)
1278 */
1279
1280ODINFUNCTION3(DWORD,_ILGetDrive,LPCITEMIDLIST, pidl,
1281 LPSTR, pOut,
1282 UINT16, uSize)
1283{
1284 if(_ILIsMyComputer(pidl))
1285 pidl = ILGetNext(pidl);
1286
1287 if (pidl && _ILIsDrive(pidl))
1288 return _ILSimpleGetText(pidl, pOut, uSize);
1289
1290 return 0;
1291}
1292
1293/**************************************************************************
1294 *
1295 * ### 2. section testing pidls ###
1296 *
1297 **************************************************************************
1298 * _ILIsDesktop()
1299 * _ILIsMyComputer()
1300 * _ILIsSpecialFolder()
1301 * _ILIsDrive()
1302 * _ILIsFolder()
1303 * _ILIsValue()
1304 * _ILIsPidlSimple()
1305 */
1306
1307ODINFUNCTION1(BOOL,_ILIsDesktop,LPCITEMIDLIST, pidl)
1308{
1309 return ( !pidl || (pidl && pidl->mkid.cb == 0x00) );
1310}
1311
1312ODINFUNCTION1(BOOL,_ILIsMyComputer,LPCITEMIDLIST, pidl)
1313{
1314 REFIID iid = _ILGetGUIDPointer(pidl);
1315
1316 TRACE_(pidl)("(%p)\n",pidl);
1317
1318 if (iid)
1319 return IsEqualIID(iid, &IID_MyComputer);
1320 return FALSE;
1321}
1322
1323ODINFUNCTION1(BOOL,_ILIsSpecialFolder,LPCITEMIDLIST, pidl)
1324{
1325 LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
1326 TRACE_(pidl)("(%p)\n",pidl);
1327 return (pidl && ( (lpPData && (PT_MYCOMP== lpPData->type || PT_SPECIAL== lpPData->type)) ||
1328 (pidl && pidl->mkid.cb == 0x00)
1329 ));
1330}
1331
1332ODINFUNCTION1(BOOL,_ILIsDrive,LPCITEMIDLIST, pidl)
1333{ LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
1334 TRACE_(pidl)("(%p)\n",pidl);
1335 return (pidl && lpPData && (PT_DRIVE == lpPData->type ||
1336 PT_DRIVE1 == lpPData->type ||
1337 PT_DRIVE2 == lpPData->type ||
1338 PT_DRIVE3 == lpPData->type));
1339}
1340
1341ODINFUNCTION1(BOOL,_ILIsFolder,LPCITEMIDLIST, pidl)
1342{ LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
1343 TRACE_(pidl)("(%p)\n",pidl);
1344 return (pidl && lpPData && (PT_FOLDER == lpPData->type || PT_FOLDER1 == lpPData->type));
1345}
1346
1347ODINFUNCTION1(BOOL,_ILIsValue,LPCITEMIDLIST, pidl)
1348{ LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
1349 TRACE_(pidl)("(%p)\n",pidl);
1350 return (pidl && lpPData && PT_VALUE == lpPData->type);
1351}
1352
1353/**************************************************************************
1354 * _ILIsPidlSimple
1355 */
1356ODINFUNCTION1(BOOL,_ILIsPidlSimple,LPCITEMIDLIST, pidl)
1357{
1358 BOOL ret = TRUE;
1359
1360 if(! _ILIsDesktop(pidl)) /* pidl=NULL or mkid.cb=0 */
1361 {
1362 WORD len = pidl->mkid.cb;
1363 LPCITEMIDLIST pidlnext = (LPCITEMIDLIST) (((LPBYTE)pidl) + len );
1364 if (pidlnext->mkid.cb)
1365 ret = FALSE;
1366 }
1367
1368 TRACE_(pidl)("%s\n", ret ? "Yes" : "No");
1369 return ret;
1370}
1371
1372/**************************************************************************
1373 *
1374 * ### 3. section getting values from pidls ###
1375 */
1376
1377 /**************************************************************************
1378 * _ILSimpleGetText
1379 *
1380 * gets the text for the first item in the pidl (eg. simple pidl)
1381 *
1382 * returns the lenght of the string
1383 */
1384
1385ODINFUNCTION3(DWORD, _ILSimpleGetText, LPCITEMIDLIST, pidl,
1386 LPSTR, szOut,
1387 UINT, uOutSize)
1388{
1389 LPPIDLDATA pData;
1390 DWORD dwReturn=0;
1391 LPSTR szSrc;
1392 GUID const * riid;
1393 char szTemp[MAX_PATH];
1394
1395 if (!pidl) return 0;
1396
1397 if (szOut)
1398 *szOut = 0;
1399
1400 pData = _ILGetDataPointer(pidl);
1401
1402 if (!pData)
1403 {
1404 /* desktop */
1405 if (HCR_GetClassName(&CLSID_ShellDesktop, szTemp, MAX_PATH))
1406 {
1407 if (szOut)
1408 lstrcpynA(szOut, szTemp, uOutSize);
1409
1410 dwReturn = strlen (szTemp);
1411 }
1412 }
1413 else if (( szSrc = _ILGetTextPointer(pData->type, pData) ))
1414 {
1415 /* filesystem */
1416 if (szOut)
1417 lstrcpynA(szOut, szSrc, MAX_PATH);
1418
1419 dwReturn = strlen(szSrc);
1420 }
1421 else if (( riid = _ILGetGUIDPointer(pidl) ))
1422 {
1423 /* special folder */
1424 if ( HCR_GetClassName(riid, szTemp, MAX_PATH) )
1425 {
1426 if (szOut)
1427 lstrcpynA(szOut, szTemp, uOutSize);
1428
1429 dwReturn = strlen (szTemp);
1430 }
1431 }
1432 else
1433 {
1434 ERR_(pidl)("-- no text\n");
1435 }
1436
1437 TRACE_(pidl)("-- (%p=%s 0x%08lx)\n",szOut,(char*)szOut,dwReturn);
1438 return dwReturn;
1439}
1440
1441/**************************************************************************
1442 *
1443 * ### 4. getting pointers to parts of pidls ###
1444 *
1445 **************************************************************************
1446 * _ILGetDataPointer()
1447 */
1448
1449ODINFUNCTION1(LPPIDLDATA,_ILGetDataPointer,LPITEMIDLIST, pidl)
1450{
1451 if(pidl && pidl->mkid.cb != 0x00)
1452 return (LPPIDLDATA) &(pidl->mkid.abID);
1453 return NULL;
1454}
1455
1456/**************************************************************************
1457 * _ILGetTextPointer()
1458 * gets a pointer to the long filename string stored in the pidl
1459 */
1460
1461ODINFUNCTION2(LPSTR,_ILGetTextPointer,PIDLTYPE, type,
1462 LPPIDLDATA, pidldata)
1463{/* TRACE(pidl,"(type=%x data=%p)\n", type, pidldata);*/
1464
1465 if(!pidldata)
1466 { return NULL;
1467 }
1468
1469 switch (type)
1470 {
1471 case PT_MYCOMP:
1472 case PT_SPECIAL:
1473 return NULL;
1474
1475 case PT_DRIVE:
1476 case PT_DRIVE1:
1477 case PT_DRIVE2:
1478 case PT_DRIVE3:
1479 return (LPSTR)&(pidldata->u.drive.szDriveName);
1480
1481 case PT_FOLDER:
1482 case PT_FOLDER1:
1483 case PT_VALUE:
1484 case PT_IESPECIAL:
1485 return (LPSTR)&(pidldata->u.file.szNames);
1486
1487 case PT_WORKGRP:
1488 case PT_COMP:
1489 case PT_NETWORK:
1490 case PT_SHARE:
1491 return (LPSTR)&(pidldata->u.network.szNames);
1492 }
1493 return NULL;
1494}
1495
1496/**************************************************************************
1497 * _ILGetSTextPointer()
1498 * gets a pointer to the short filename string stored in the pidl
1499 */
1500
1501ODINFUNCTION2(LPSTR,_ILGetSTextPointer,PIDLTYPE, type,
1502 LPPIDLDATA, pidldata)
1503{/* TRACE(pidl,"(type=%x data=%p)\n", type, pidldata);*/
1504
1505 if(!pidldata)
1506 return NULL;
1507
1508 switch (type)
1509 {
1510 case PT_FOLDER:
1511 case PT_VALUE:
1512 case PT_IESPECIAL:
1513 return (LPSTR)(pidldata->u.file.szNames + strlen (pidldata->u.file.szNames) + 1);
1514
1515 case PT_WORKGRP:
1516 return (LPSTR)(pidldata->u.network.szNames + strlen (pidldata->u.network.szNames) + 1);
1517 }
1518 return NULL;
1519}
1520
1521/**************************************************************************
1522 * _ILGetGUIDPointer()
1523 *
1524 * returns reference to guid stored in some pidls
1525 */
1526
1527ODINFUNCTION1(REFIID,_ILGetGUIDPointer,LPCITEMIDLIST, pidl)
1528{
1529 LPPIDLDATA pdata =_ILGetDataPointer(pidl);
1530
1531 if (pdata)
1532 {
1533 switch (pdata->type)
1534 {
1535 case PT_SPECIAL:
1536 case PT_MYCOMP:
1537 return (REFIID) &(pdata->u.mycomp.guid);
1538 }
1539 }
1540 return NULL;
1541}
1542
1543ODINFUNCTION3(BOOL, _ILGetFileDate, LPCITEMIDLIST, pidl,
1544 LPSTR, pOut,
1545 UINT, uOutSize)
1546{ LPPIDLDATA pdata =_ILGetDataPointer(pidl);
1547 FILETIME ft;
1548 SYSTEMTIME time;
1549
1550 switch (pdata->type)
1551 { case PT_FOLDER:
1552 DosDateTimeToFileTime(pdata->u.folder.uFileDate, pdata->u.folder.uFileTime, &ft);
1553 break;
1554 case PT_VALUE:
1555 DosDateTimeToFileTime(pdata->u.file.uFileDate, pdata->u.file.uFileTime, &ft);
1556 break;
1557 default:
1558 return FALSE;
1559 }
1560 FileTimeToSystemTime (&ft, &time);
1561 return GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&time, NULL, pOut, uOutSize);
1562}
1563
1564
1565ODINFUNCTION3(BOOL,_ILGetFileSize,LPCITEMIDLIST, pidl,
1566 LPSTR, pOut,
1567 UINT, uOutSize)
1568{ LPPIDLDATA pdata =_ILGetDataPointer(pidl);
1569
1570 switch (pdata->type)
1571 { case PT_VALUE:
1572 break;
1573 default:
1574 return FALSE;
1575 }
1576 StrFormatByteSizeA(pdata->u.file.dwFileSize, pOut, uOutSize);
1577 return TRUE;
1578}
1579
1580
1581ODINFUNCTION3(BOOL,_ILGetExtension,LPCITEMIDLIST, pidl,
1582 LPSTR, pOut,
1583 UINT, uOutSize)
1584{
1585 char szTemp[MAX_PATH];
1586 const char * pPoint;
1587 LPITEMIDLIST pidlTemp=pidl;
1588
1589 if (!pidl) return FALSE;
1590
1591 pidlTemp = ILFindLastID(pidl);
1592
1593 if (!_ILIsValue(pidlTemp)) return FALSE;
1594 if (!_ILSimpleGetText(pidlTemp, szTemp, MAX_PATH)) return FALSE;
1595
1596 pPoint = PathFindExtensionA(szTemp);
1597
1598 if (! *pPoint) return FALSE;
1599
1600 pPoint++;
1601 lstrcpynA(pOut, pPoint, uOutSize);
1602 TRACE_(pidl)("%s\n",pOut);
1603
1604 return TRUE;
1605}
1606
Note: See TracBrowser for help on using the repository browser.