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

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

Fix: updated to current wine 19990913

File size: 35.4 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, (LPSTR)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 ERR_(shell)("%d does not find sizeof(finddata)\n",len);
855 return E_INVALIDARG;
856 }
857
858 SHGetPathFromIDListA(pidl, pszPath);
859
860 if ((handle = FindFirstFileA ( pszPath, pfd)))
861 FindClose (handle);
862 }
863 return NOERROR;
864
865 case SHGDFIL_NETRESOURCE:
866 case SHGDFIL_DESCRIPTIONID:
867 FIXME_(shell)("SHGDFIL %i stub\n", nFormat);
868 break;
869
870 default:
871 ERR_(shell)("Unknown SHGDFIL %i, please report\n", nFormat);
872 }
873
874 return E_INVALIDARG;
875}
876/*************************************************************************
877 * SHGetDataFromIDListW [SHELL32.247]
878 *
879 */
880HRESULT WINAPI SHGetDataFromIDListW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, int nFormat, LPVOID dest, int len)
881{
882 if (! psf || !dest ) return E_INVALIDARG;
883
884 switch (nFormat)
885 {
886 case SHGDFIL_FINDDATA:
887 {
888 WIN32_FIND_DATAW * pfd = (WIN32_FIND_DATAW*)dest;
889 WCHAR pszPath[MAX_PATH];
890 HANDLE handle;
891
892 if ( len < sizeof (WIN32_FIND_DATAW)) {
893 ERR_(shell)("%d does not find sizeof(finddata)\n",len);
894 return E_INVALIDARG;
895 }
896 SHGetPathFromIDListW(pidl, pszPath);
897 if ((handle = FindFirstFileW ( pszPath, pfd)))
898 FindClose (handle);
899 }
900 return NOERROR;
901 default: /* fallthrough */
902 break;
903 }
904 FIXME_(shell)("(sf=%p pidl=%p nFormat=0x%04x %p 0x%04x), unhandled.\n",psf,pidl,nFormat,dest,len);
905 return SHGetDataFromIDListA( psf, pidl, nFormat, dest, len);
906}
907
908/*************************************************************************
909 * SHGetPathFromIDListA [SHELL32.261][NT 4.0: SHELL32.220]
910 *
911 * PARAMETERS
912 * pidl, [IN] pidl
913 * pszPath [OUT] path
914 *
915 * RETURNS
916 * path from a passed PIDL.
917 *
918 * NOTES
919 * NULL returns FALSE
920 * desktop pidl gives path to desktopdirectory back
921 * special pidls returning FALSE
922 *
923 * FIXME
924 * fnGetDisplayNameOf can return different types of OLEString
925 */
926BOOL WINAPI SHGetPathFromIDListA (LPCITEMIDLIST pidl,LPSTR pszPath)
927{ STRRET str;
928 LPSHELLFOLDER shellfolder;
929
930 TRACE_(shell)("(pidl=%p,%p)\n",pidl,pszPath);
931
932 if (!pidl) return FALSE;
933
934 pdump(pidl);
935
936 if(_ILIsDesktop(pidl))
937 {
938 SHGetSpecialFolderPathA(0, pszPath, CSIDL_DESKTOPDIRECTORY, FALSE);
939 }
940 else
941 {
942 if (SHGetDesktopFolder(&shellfolder)==S_OK)
943 {
944 IShellFolder_GetDisplayNameOf(shellfolder,pidl,SHGDN_FORPARSING,&str);
945 StrRetToStrNA (pszPath, MAX_PATH, &str, pidl);
946 IShellFolder_Release(shellfolder);
947 }
948 }
949 TRACE_(shell)("-- (%s)\n",pszPath);
950
951 return TRUE;
952}
953/*************************************************************************
954 * SHGetPathFromIDListW [SHELL32.262]
955 */
956BOOL WINAPI SHGetPathFromIDListW (LPCITEMIDLIST pidl,LPWSTR pszPath)
957{ char sTemp[MAX_PATH];
958
959 TRACE_(shell)("(pidl=%p)\n", pidl);
960
961 SHGetPathFromIDListA (pidl, sTemp);
962 lstrcpyAtoW(pszPath, sTemp);
963
964 TRACE_(shell)("-- (%s)\n",debugstr_w(pszPath));
965
966 return TRUE;
967}
968
969/*************************************************************************
970 * SHBindToParent [shell version 5.0]
971 */
972HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
973{
974 IShellFolder * psf;
975 LPITEMIDLIST pidlChild, pidlParent;
976 HRESULT hr=E_FAIL;
977
978 TRACE_(shell)("pidl=%p\n", pidl);
979 pdump(pidl);
980
981 *ppv = NULL;
982 if (ppidlLast) *ppidlLast = NULL;
983
984 if (_ILIsPidlSimple(pidl))
985 {
986 /* we are on desktop level */
987 if (ppidlLast)
988 *ppidlLast = ILClone(pidl);
989 hr = SHGetDesktopFolder((IShellFolder**)ppv);
990 }
991 else
992 {
993 pidlChild = ILClone(ILFindLastID(pidl));
994 pidlParent = ILClone(pidl);
995 ILRemoveLastID(pidlParent);
996
997 hr = SHGetDesktopFolder(&psf);
998
999 if (SUCCEEDED(hr))
1000 hr = IShellFolder_BindToObject(psf, pidlParent, NULL, riid, ppv);
1001
1002 if (SUCCEEDED(hr) && ppidlLast)
1003 *ppidlLast = pidlChild;
1004 else
1005 ILFree (pidlChild);
1006
1007 SHFree (pidlParent);
1008 }
1009
1010
1011 TRACE_(shell)("-- psf=%p pidl=%p ret=0x%08lx\n", *ppv, (ppidlLast)?*ppidlLast:NULL, hr);
1012 return hr;
1013}
1014
1015/*************************************************************************
1016 * SHGetPathFromIDListAW [SHELL32.221][NT 4.0: SHELL32.219]
1017 */
1018BOOL WINAPI SHGetPathFromIDListAW(LPCITEMIDLIST pidl,LPVOID pszPath)
1019{
1020 TRACE_(shell)("(pidl=%p,%p)\n",pidl,pszPath);
1021
1022 if (VERSION_OsIsUnicode())
1023 return SHGetPathFromIDListW(pidl,(LPWSTR)pszPath);
1024 return SHGetPathFromIDListA(pidl,(LPSTR)pszPath);
1025}
1026
1027/**************************************************************************
1028 *
1029 * internal functions
1030 *
1031 * ### 1. section creating pidls ###
1032 *
1033 *************************************************************************
1034 * _ILCreateDesktop()
1035 * _ILCreateIExplore()
1036 * _ILCreateMyComputer()
1037 * _ILCreateDrive()
1038 * _ILCreateFolder()
1039 * _ILCreateValue()
1040 */
1041LPITEMIDLIST WINAPI _ILCreateDesktop()
1042{ TRACE_(pidl)("()\n");
1043 return _ILCreate(PT_DESKTOP, NULL, 0);
1044}
1045
1046LPITEMIDLIST WINAPI _ILCreateMyComputer()
1047{ TRACE_(pidl)("()\n");
1048 return _ILCreate(PT_MYCOMP, &IID_MyComputer, sizeof(GUID));
1049}
1050
1051LPITEMIDLIST WINAPI _ILCreateIExplore()
1052{ TRACE_(pidl)("()\n");
1053 return _ILCreate(PT_MYCOMP, &IID_IExplore, sizeof(GUID));
1054}
1055
1056LPITEMIDLIST WINAPI _ILCreateDrive( LPCSTR lpszNew)
1057{ char sTemp[4];
1058 lstrcpynA (sTemp,lpszNew,4);
1059 sTemp[2]='\\';
1060 sTemp[3]=0x00;
1061 TRACE_(pidl)("(%s)\n",sTemp);
1062 return _ILCreate(PT_DRIVE,(LPVOID)&sTemp[0],4);
1063}
1064
1065LPITEMIDLIST WINAPI _ILCreateFolder( WIN32_FIND_DATAA * stffile )
1066{
1067 char buff[MAX_PATH + 14 +1]; /* see WIN32_FIND_DATA */
1068 char * pbuff = buff;
1069 ULONG len, len1;
1070 LPITEMIDLIST pidl;
1071
1072 TRACE_(pidl)("(%s, %s)\n",stffile->cAlternateFileName, stffile->cFileName);
1073
1074 /* prepare buffer with both names */
1075 len = strlen (stffile->cFileName) + 1;
1076 memcpy (pbuff, stffile->cFileName, len);
1077 pbuff += len;
1078
1079 if (stffile->cAlternateFileName)
1080 {
1081 len1 = strlen (stffile->cAlternateFileName)+1;
1082 memcpy (pbuff, stffile->cAlternateFileName, len1);
1083 }
1084 else
1085 {
1086 len1 = 1;
1087 *pbuff = 0x00;
1088 }
1089
1090 pidl = _ILCreate(PT_FOLDER, (LPVOID)buff, len + len1);
1091
1092 /* set attributes */
1093 if (pidl)
1094 {
1095 LPPIDLDATA pData;
1096 pData = _ILGetDataPointer(pidl);
1097 FileTimeToDosDateTime(&(stffile->ftLastWriteTime),&pData->u.folder.uFileDate,&pData->u.folder.uFileTime);
1098 pData->u.folder.dwFileSize = stffile->nFileSizeLow;
1099 pData->u.folder.uFileAttribs=stffile->dwFileAttributes;
1100 }
1101
1102 return pidl;
1103}
1104
1105LPITEMIDLIST WINAPI _ILCreateValue(WIN32_FIND_DATAA * stffile)
1106{
1107 char buff[MAX_PATH + 14 +1]; /* see WIN32_FIND_DATA */
1108 char * pbuff = buff;
1109 ULONG len, len1;
1110 LPITEMIDLIST pidl;
1111
1112 TRACE_(pidl)("(%s, %s)\n",stffile->cAlternateFileName, stffile->cFileName);
1113
1114 /* prepare buffer with both names */
1115 len = strlen (stffile->cFileName) + 1;
1116 memcpy (pbuff, stffile->cFileName, len);
1117 pbuff += len;
1118
1119 if (stffile->cAlternateFileName)
1120 {
1121 len1 = strlen (stffile->cAlternateFileName)+1;
1122 memcpy (pbuff, stffile->cAlternateFileName, len1);
1123 }
1124 else
1125 {
1126 len1 = 1;
1127 *pbuff = 0x00;
1128 }
1129
1130 pidl = _ILCreate(PT_VALUE, (LPVOID)buff, len + len1);
1131
1132 /* set attributes */
1133 if (pidl)
1134 {
1135 LPPIDLDATA pData;
1136 pData = _ILGetDataPointer(pidl);
1137 FileTimeToDosDateTime(&(stffile->ftLastWriteTime),&pData->u.folder.uFileDate,&pData->u.folder.uFileTime);
1138 pData->u.folder.dwFileSize = stffile->nFileSizeLow;
1139 pData->u.folder.uFileAttribs=stffile->dwFileAttributes;
1140 }
1141
1142 return pidl;
1143}
1144
1145LPITEMIDLIST WINAPI _ILCreateSpecial(LPCSTR szGUID)
1146{
1147 IID iid;
1148 CLSIDFromStringA(szGUID,&iid);
1149 return _ILCreate(PT_MYCOMP, &iid, sizeof(IID));
1150}
1151
1152/**************************************************************************
1153 * _ILCreate()
1154 * Creates a new PIDL
1155 * type = PT_DESKTOP | PT_DRIVE | PT_FOLDER | PT_VALUE
1156 * pIn = data
1157 * uInSize = size of data (raw)
1158 */
1159
1160LPITEMIDLIST WINAPI _ILCreate(PIDLTYPE type, LPCVOID pIn, UINT16 uInSize)
1161{ LPITEMIDLIST pidlOut = NULL, pidlTemp = NULL;
1162 LPPIDLDATA pData;
1163 UINT16 uSize = 0;
1164 LPSTR pszDest;
1165
1166 TRACE_(pidl)("(0x%02x %p %i)\n",type,pIn,uInSize);
1167
1168 switch (type)
1169 { case PT_DESKTOP:
1170 uSize = 0;
1171 pidlOut = (ITEMIDLIST*)SHAlloc(uSize + 2);
1172 pidlOut->mkid.cb = uSize;
1173 TRACE_(pidl)("- create Desktop\n");
1174 break;
1175
1176 case PT_MYCOMP:
1177 uSize = 2 + 2 + sizeof(GUID);
1178 pidlOut = (ITEMIDLIST*)SHAlloc(uSize + 2);
1179 ZeroMemory(pidlOut, uSize + 2);
1180 pidlOut->mkid.cb = uSize;
1181 pData =_ILGetDataPointer(pidlOut);
1182 pData->type = type;
1183 memcpy(&(pData->u.mycomp.guid), pIn, uInSize);
1184 TRACE_(pidl)("- create GUID-pidl\n");
1185 break;
1186
1187 case PT_DRIVE:
1188 uSize = 2 + 23;
1189 pidlOut = (ITEMIDLIST*)SHAlloc(uSize + 2);
1190 ZeroMemory(pidlOut, uSize + 2);
1191 pidlOut->mkid.cb = uSize;
1192 pData =_ILGetDataPointer(pidlOut);
1193 pData->type = type;
1194 pszDest = _ILGetTextPointer(type, pData);
1195 memcpy(pszDest, pIn, uInSize);
1196 TRACE_(pidl)("- create Drive: %s\n",debugstr_a(pszDest));
1197 break;
1198
1199 case PT_FOLDER:
1200 case PT_VALUE:
1201 uSize = 2 + 12 + uInSize;
1202 pidlOut = (ITEMIDLIST*)SHAlloc(uSize + 2);
1203 ZeroMemory(pidlOut, uSize + 2);
1204 pidlOut->mkid.cb = uSize;
1205 pData =_ILGetDataPointer(pidlOut);
1206 pData->type = type;
1207 pszDest = _ILGetTextPointer(type, pData);
1208 memcpy(pszDest, pIn, uInSize);
1209 TRACE_(pidl)("- create Value: %s\n",debugstr_a(pszDest));
1210 break;
1211 }
1212
1213 pidlTemp = ILGetNext(pidlOut);
1214 if (pidlTemp)
1215 pidlTemp->mkid.cb = 0x00;
1216
1217 TRACE_(pidl)("-- (pidl=%p, size=%u)\n", pidlOut, uSize);
1218 return pidlOut;
1219}
1220
1221/**************************************************************************
1222 * _ILGetDrive()
1223 *
1224 * Gets the text for the drive eg. 'c:\'
1225 *
1226 * RETURNS
1227 * strlen (lpszText)
1228 */
1229DWORD WINAPI _ILGetDrive(LPCITEMIDLIST pidl,LPSTR pOut, UINT16 uSize)
1230{ TRACE_(pidl)("(%p,%p,%u)\n",pidl,pOut,uSize);
1231
1232 if(_ILIsMyComputer(pidl))
1233 pidl = ILGetNext(pidl);
1234
1235 if (pidl && _ILIsDrive(pidl))
1236 return _ILSimpleGetText(pidl, pOut, uSize);
1237
1238 return 0;
1239}
1240
1241/**************************************************************************
1242 *
1243 * ### 2. section testing pidls ###
1244 *
1245 **************************************************************************
1246 * _ILIsDesktop()
1247 * _ILIsMyComputer()
1248 * _ILIsSpecialFolder()
1249 * _ILIsDrive()
1250 * _ILIsFolder()
1251 * _ILIsValue()
1252 * _ILIsPidlSimple()
1253 */
1254BOOL WINAPI _ILIsDesktop(LPCITEMIDLIST pidl)
1255{ TRACE_(pidl)("(%p)\n",pidl);
1256 return ( !pidl || (pidl && pidl->mkid.cb == 0x00) );
1257}
1258
1259BOOL WINAPI _ILIsMyComputer(LPCITEMIDLIST pidl)
1260{
1261 REFIID iid = _ILGetGUIDPointer(pidl);
1262
1263 TRACE_(pidl)("(%p)\n",pidl);
1264
1265 if (iid)
1266 return IsEqualIID(iid, &IID_MyComputer);
1267 return FALSE;
1268}
1269
1270BOOL WINAPI _ILIsSpecialFolder (LPCITEMIDLIST pidl)
1271{
1272 LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
1273 TRACE_(pidl)("(%p)\n",pidl);
1274 return (pidl && ( (lpPData && (PT_MYCOMP== lpPData->type || PT_SPECIAL== lpPData->type)) ||
1275 (pidl && pidl->mkid.cb == 0x00)
1276 ));
1277}
1278
1279BOOL WINAPI _ILIsDrive(LPCITEMIDLIST pidl)
1280{ LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
1281 TRACE_(pidl)("(%p)\n",pidl);
1282 return (pidl && lpPData && (PT_DRIVE == lpPData->type ||
1283 PT_DRIVE1 == lpPData->type ||
1284 PT_DRIVE2 == lpPData->type ||
1285 PT_DRIVE3 == lpPData->type));
1286}
1287
1288BOOL WINAPI _ILIsFolder(LPCITEMIDLIST pidl)
1289{ LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
1290 TRACE_(pidl)("(%p)\n",pidl);
1291 return (pidl && lpPData && (PT_FOLDER == lpPData->type || PT_FOLDER1 == lpPData->type));
1292}
1293
1294BOOL WINAPI _ILIsValue(LPCITEMIDLIST pidl)
1295{ LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
1296 TRACE_(pidl)("(%p)\n",pidl);
1297 return (pidl && lpPData && PT_VALUE == lpPData->type);
1298}
1299
1300/**************************************************************************
1301 * _ILIsPidlSimple
1302 */
1303BOOL WINAPI _ILIsPidlSimple ( LPCITEMIDLIST pidl)
1304{
1305 BOOL ret = TRUE;
1306
1307 if(! _ILIsDesktop(pidl)) /* pidl=NULL or mkid.cb=0 */
1308 {
1309 WORD len = pidl->mkid.cb;
1310 LPCITEMIDLIST pidlnext = (LPCITEMIDLIST) (((LPBYTE)pidl) + len );
1311 if (pidlnext->mkid.cb)
1312 ret = FALSE;
1313 }
1314
1315 TRACE_(pidl)("%s\n", ret ? "Yes" : "No");
1316 return ret;
1317}
1318
1319/**************************************************************************
1320 *
1321 * ### 3. section getting values from pidls ###
1322 */
1323
1324 /**************************************************************************
1325 * _ILSimpleGetText
1326 *
1327 * gets the text for the first item in the pidl (eg. simple pidl)
1328 *
1329 * returns the lenght of the string
1330 */
1331DWORD WINAPI _ILSimpleGetText (LPCITEMIDLIST pidl, LPSTR szOut, UINT uOutSize)
1332{
1333 LPPIDLDATA pData;
1334 DWORD dwReturn=0;
1335 LPSTR szSrc;
1336 GUID const * riid;
1337 char szTemp[MAX_PATH];
1338
1339 TRACE_(pidl)("(%p %p %x)\n",pidl,szOut,uOutSize);
1340
1341 if (!pidl) return 0;
1342
1343 if (szOut)
1344 *szOut = 0;
1345
1346 pData = _ILGetDataPointer(pidl);
1347
1348 if (!pData)
1349 {
1350 /* desktop */
1351 if (HCR_GetClassName(&CLSID_ShellDesktop, szTemp, MAX_PATH))
1352 {
1353 if (szOut)
1354 lstrcpynA(szOut, szTemp, uOutSize);
1355
1356 dwReturn = strlen (szTemp);
1357 }
1358 }
1359 else if (( szSrc = _ILGetTextPointer(pData->type, pData) ))
1360 {
1361 /* filesystem */
1362 if (szOut)
1363 lstrcpynA(szOut, szSrc, MAX_PATH);
1364
1365 dwReturn = strlen(szSrc);
1366 }
1367 else if (( riid = _ILGetGUIDPointer(pidl) ))
1368 {
1369 /* special folder */
1370 if ( HCR_GetClassName(riid, szTemp, MAX_PATH) )
1371 {
1372 if (szOut)
1373 lstrcpynA(szOut, szTemp, uOutSize);
1374
1375 dwReturn = strlen (szTemp);
1376 }
1377 }
1378 else
1379 {
1380 ERR_(pidl)("-- no text\n");
1381 }
1382
1383 TRACE_(pidl)("-- (%p=%s 0x%08lx)\n",szOut,(char*)szOut,dwReturn);
1384 return dwReturn;
1385}
1386
1387/**************************************************************************
1388 *
1389 * ### 4. getting pointers to parts of pidls ###
1390 *
1391 **************************************************************************
1392 * _ILGetDataPointer()
1393 */
1394LPPIDLDATA WINAPI _ILGetDataPointer(LPITEMIDLIST pidl)
1395{
1396 if(pidl && pidl->mkid.cb != 0x00)
1397 return (LPPIDLDATA) &(pidl->mkid.abID);
1398 return NULL;
1399}
1400
1401/**************************************************************************
1402 * _ILGetTextPointer()
1403 * gets a pointer to the long filename string stored in the pidl
1404 */
1405LPSTR WINAPI _ILGetTextPointer(PIDLTYPE type, LPPIDLDATA pidldata)
1406{/* TRACE(pidl,"(type=%x data=%p)\n", type, pidldata);*/
1407
1408 if(!pidldata)
1409 { return NULL;
1410 }
1411
1412 switch (type)
1413 {
1414 case PT_MYCOMP:
1415 case PT_SPECIAL:
1416 return NULL;
1417
1418 case PT_DRIVE:
1419 case PT_DRIVE1:
1420 case PT_DRIVE2:
1421 case PT_DRIVE3:
1422 return (LPSTR)&(pidldata->u.drive.szDriveName);
1423
1424 case PT_FOLDER:
1425 case PT_FOLDER1:
1426 case PT_VALUE:
1427 case PT_IESPECIAL:
1428 return (LPSTR)&(pidldata->u.file.szNames);
1429
1430 case PT_WORKGRP:
1431 case PT_COMP:
1432 case PT_NETWORK:
1433 case PT_SHARE:
1434 return (LPSTR)&(pidldata->u.network.szNames);
1435 }
1436 return NULL;
1437}
1438
1439/**************************************************************************
1440 * _ILGetSTextPointer()
1441 * gets a pointer to the short filename string stored in the pidl
1442 */
1443LPSTR WINAPI _ILGetSTextPointer(PIDLTYPE type, LPPIDLDATA pidldata)
1444{/* TRACE(pidl,"(type=%x data=%p)\n", type, pidldata);*/
1445
1446 if(!pidldata)
1447 return NULL;
1448
1449 switch (type)
1450 {
1451 case PT_FOLDER:
1452 case PT_VALUE:
1453 case PT_IESPECIAL:
1454 return (LPSTR)(pidldata->u.file.szNames + strlen (pidldata->u.file.szNames) + 1);
1455
1456 case PT_WORKGRP:
1457 return (LPSTR)(pidldata->u.network.szNames + strlen (pidldata->u.network.szNames) + 1);
1458 }
1459 return NULL;
1460}
1461
1462/**************************************************************************
1463 * _ILGetGUIDPointer()
1464 *
1465 * returns reference to guid stored in some pidls
1466 */
1467REFIID WINAPI _ILGetGUIDPointer(LPCITEMIDLIST pidl)
1468{
1469 LPPIDLDATA pdata =_ILGetDataPointer(pidl);
1470
1471 if (pdata)
1472 {
1473 switch (pdata->type)
1474 {
1475 case PT_SPECIAL:
1476 case PT_MYCOMP:
1477 return (REFIID) &(pdata->u.mycomp.guid);
1478 }
1479 }
1480 return NULL;
1481}
1482
1483BOOL WINAPI _ILGetFileDate (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
1484{ LPPIDLDATA pdata =_ILGetDataPointer(pidl);
1485 FILETIME ft;
1486 SYSTEMTIME time;
1487
1488 switch (pdata->type)
1489 { case PT_FOLDER:
1490 DosDateTimeToFileTime(pdata->u.folder.uFileDate, pdata->u.folder.uFileTime, &ft);
1491 break;
1492 case PT_VALUE:
1493 DosDateTimeToFileTime(pdata->u.file.uFileDate, pdata->u.file.uFileTime, &ft);
1494 break;
1495 default:
1496 return FALSE;
1497 }
1498 FileTimeToSystemTime (&ft, &time);
1499 return GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&time, NULL, pOut, uOutSize);
1500}
1501
1502BOOL WINAPI _ILGetFileSize (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
1503{ LPPIDLDATA pdata =_ILGetDataPointer(pidl);
1504
1505 switch (pdata->type)
1506 { case PT_VALUE:
1507 break;
1508 default:
1509 return FALSE;
1510 }
1511 StrFormatByteSizeA(pdata->u.file.dwFileSize, pOut, uOutSize);
1512 return TRUE;
1513}
1514
1515BOOL WINAPI _ILGetExtension (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
1516{
1517 char szTemp[MAX_PATH];
1518 const char * pPoint;
1519 LPITEMIDLIST pidlTemp=pidl;
1520
1521 TRACE_(pidl)("pidl=%p\n",pidl);
1522
1523 if (!pidl) return FALSE;
1524
1525 pidlTemp = ILFindLastID(pidl);
1526
1527 if (!_ILIsValue(pidlTemp)) return FALSE;
1528 if (!_ILSimpleGetText(pidlTemp, szTemp, MAX_PATH)) return FALSE;
1529
1530 pPoint = PathFindExtensionA(szTemp);
1531
1532 if (! *pPoint) return FALSE;
1533
1534 pPoint++;
1535 lstrcpynA(pOut, pPoint, uOutSize);
1536 TRACE_(pidl)("%s\n",pOut);
1537
1538 return TRUE;
1539}
1540
Note: See TracBrowser for help on using the repository browser.