source: trunk/src/shell32/new/pidl.cpp@ 793

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

.

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