source: trunk/src/shell32/pidl.c

Last change on this file was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

File size: 46.2 KB
RevLine 
[8614]1/* $Id: pidl.c,v 1.16 2002-06-09 12:41:21 sandervl Exp $ */
[4121]2/*
[6709]3 * pidl Handling
[4121]4 *
[6709]5 * Copyright 1998 Juergen Schmied
[4121]6 *
7 * NOTES
8 * a pidl == NULL means desktop and is legal
9 *
10 */
11
[6999]12
13/****************************************************************************
14 * includes
15 ****************************************************************************/
16
17#include <odin.h>
18#include <os2sel.h>
19#include <odinwrap.h>
20
21ODINDEBUGCHANNEL(SHELL32-PIDL)
22
23
[4121]24#include <ctype.h>
25#include <stdlib.h>
26#include <string.h>
27#include "winbase.h"
[8048]28#include "winreg.h"
[4121]29#include "shlguid.h"
30#include "winerror.h"
31#include "winnls.h"
[8614]32#include "undocshell.h"
[4121]33#include "shell32_main.h"
34#include "shellapi.h"
[5618]35#include "shlwapi.h"
[4121]36
37#include "pidl.h"
[8048]38#include "debugtools.h"
[4121]39
40DEFAULT_DEBUG_CHANNEL(pidl);
[6999]41
42#ifndef __WIN32OS2__
[4121]43DECLARE_DEBUG_CHANNEL(shell);
[6999]44#endif
[4121]45
[7012]46
[7359]47#define ODIN_ILGETNEXT(pidl) \
48 (pidl ? ( pidl->mkid.cb ? (LPITEMIDLIST) (((LPBYTE)pidl)+pidl->mkid.cb) : NULL) : NULL)
[7012]49
[5618]50#if defined( __WIN32OS2__) && defined(DEBUG)
[4121]51void pdump (LPCITEMIDLIST pidl)
52{
[6709]53 BOOL bIsShellDebug;
[21639]54
[6709]55 LPITEMIDLIST pidltemp = pidl;
56 if (!TRACE_ON(pidl))
57 return;
[4121]58
[6709]59 /* silence the sub-functions */
60 bIsShellDebug = TRACE_ON(shell);
61 __SET_DEBUGGING(__DBCL_TRACE, __wine_dbch_shell, FALSE);
62 __SET_DEBUGGING(__DBCL_TRACE, __wine_dbch_pidl, FALSE);
[4121]63
[6709]64 if (! pidltemp)
65 {
[6999]66 MESSAGE ("PIDL: -------- pidl=NULL (Desktop)\n");
[6709]67 }
68 else
69 {
[6999]70 MESSAGE ("PIDL: -------- pidl=%p\n", pidl);
[6709]71 if (pidltemp->mkid.cb)
[21639]72 {
[6709]73 do
74 {
75 DWORD dwAttrib = 0;
76 LPPIDLDATA pData = _ILGetDataPointer(pidltemp);
77 DWORD type = pData->type;
78 LPSTR szLongName = _ILGetTextPointer(pidltemp);
79 LPSTR szShortName = _ILGetSTextPointer(pidltemp);
80 char szName[MAX_PATH];
[4121]81
[6709]82 _ILSimpleGetText(pidltemp, szName, MAX_PATH);
83 if( PT_FOLDER == type)
84 dwAttrib = pData->u.folder.uFileAttribs;
85 else if( PT_VALUE == type)
86 dwAttrib = pData->u.file.uFileAttribs;
[4121]87
[6999]88 MESSAGE ("PIDL: -- pidl=%p size=%u type=%lx attr=0x%08lx name=%s (%s,%s)\n",
[6709]89 pidltemp, pidltemp->mkid.cb,type,dwAttrib,szName,debugstr_a(szLongName), debugstr_a(szShortName));
[4121]90
[7359]91 pidltemp = ODIN_ILGETNEXT(pidltemp);
[4121]92
[6709]93 } while (pidltemp->mkid.cb);
94 }
95 else
96 {
[6999]97 MESSAGE ("PIDL: empty pidl (Desktop)\n");
[6709]98 }
99 pcheck(pidl);
100 }
[4121]101
[6709]102 __SET_DEBUGGING(__DBCL_TRACE, __wine_dbch_shell, bIsShellDebug);
103 __SET_DEBUGGING(__DBCL_TRACE, __wine_dbch_pidl, TRUE);
[4121]104
105}
[5618]106#endif
[4121]107#define BYTES_PRINTED 32
108BOOL pcheck (LPCITEMIDLIST pidl)
109{ DWORD type, ret=TRUE;
[6709]110 BOOL bIsPidlDebug;
[4121]111
112 LPITEMIDLIST pidltemp = pidl;
113
[6709]114 bIsPidlDebug = TRACE_ON(shell);
115 __SET_DEBUGGING(__DBCL_TRACE, __wine_dbch_pidl, FALSE);
[4121]116
117 if (pidltemp && pidltemp->mkid.cb)
118 { do
119 { type = _ILGetDataPointer(pidltemp)->type;
120 switch (type)
[6709]121 { case PT_DESKTOP:
122 case PT_MYCOMP:
123 case PT_SPECIAL:
124 case PT_DRIVE:
125 case PT_DRIVE1:
126 case PT_DRIVE2:
127 case PT_DRIVE3:
128 case PT_FOLDER:
129 case PT_VALUE:
130 case PT_FOLDER1:
131 case PT_WORKGRP:
132 case PT_COMP:
133 case PT_NETWORK:
134 case PT_IESPECIAL1:
135 case PT_IESPECIAL2:
136 case PT_SHARE:
137 break;
138 default:
139 {
140 char szTemp[BYTES_PRINTED*4 + 1];
141 int i;
142 unsigned char c;
[4121]143
[6709]144 memset(szTemp, ' ', BYTES_PRINTED*4 + 1);
145 for ( i = 0; (i<pidltemp->mkid.cb) && (i<BYTES_PRINTED); i++)
146 {
147 c = ((unsigned char *)pidltemp)[i];
[4121]148
[6709]149 szTemp[i*3+0] = ((c>>4)>9)? (c>>4)+55 : (c>>4)+48;
150 szTemp[i*3+1] = ((0x0F&c)>9)? (0x0F&c)+55 : (0x0F&c)+48;
151 szTemp[i*3+2] = ' ';
152 szTemp[i+BYTES_PRINTED*3] = (c>=0x20 && c <=0x80) ? c : '.';
153 }
154 szTemp[BYTES_PRINTED*4] = 0x00;
155 ERR("unknown IDLIST type size=%u type=%lx\n%s\n",pidltemp->mkid.cb,type, szTemp);
156 ret = FALSE;
157 }
158 }
[7359]159 pidltemp = ODIN_ILGETNEXT(pidltemp);
[6709]160 } while (pidltemp->mkid.cb);
161 }
162 __SET_DEBUGGING(__DBCL_TRACE, __wine_dbch_pidl, bIsPidlDebug);
163 return ret;
[4121]164}
165
166/*************************************************************************
[6709]167 * ILGetDisplayName [SHELL32.15]
[4121]168 */
[6999]169
[7904]170BOOL WIN32API ILGetDisplayName(LPCITEMIDLIST pidl, LPSTR path)
[4121]171{
[6709]172 TRACE_(shell)("pidl=%p %p semi-stub\n",pidl,path);
173 return SHGetPathFromIDListA(pidl, path);
[4121]174}
175/*************************************************************************
176 * ILFindLastID [SHELL32.16]
177 *
178 * NOTES
179 * observed: pidl=Desktop return=pidl
180 */
[7904]181LPITEMIDLIST WIN32API ILFindLastID(LPITEMIDLIST pidl)
[6709]182{ LPITEMIDLIST pidlLast = pidl;
[4121]183
[6709]184 TRACE("(pidl=%p)\n",pidl);
[4121]185
[6709]186 while (pidl->mkid.cb)
187 {
188 pidlLast = pidl;
[7359]189 pidl = ODIN_ILGETNEXT(pidl);
[6709]190 }
[21639]191 return pidlLast;
[4121]192}
193/*************************************************************************
194 * ILRemoveLastID [SHELL32.17]
195 *
196 * NOTES
197 * when pidl=Desktop return=FALSE
198 */
[7904]199BOOL WIN32API ILRemoveLastID(LPCITEMIDLIST pidl)
[4121]200{
[6709]201 TRACE_(shell)("pidl=%p\n",pidl);
[4121]202
[6709]203 if (!pidl || !pidl->mkid.cb)
204 return 0;
205 ILFindLastID(pidl)->mkid.cb = 0;
206 return 1;
[4121]207}
208
209/*************************************************************************
210 * ILClone [SHELL32.18]
211 *
212 * NOTES
213 * dupicate an idlist
214 */
[7904]215LPITEMIDLIST WIN32API ILClone(LPCITEMIDLIST pidl)
[4121]216{ DWORD len;
217 LPITEMIDLIST newpidl;
218
219 if (!pidl)
220 return NULL;
[21639]221
[7359]222 len = ILGetSize(pidl);
223 newpidl = (LPITEMIDLIST)SHAlloc(len);
[4121]224 if (newpidl)
225 memcpy(newpidl,pidl,len);
226
227 TRACE("pidl=%p newpidl=%p\n",pidl, newpidl);
228 pdump(pidl);
229
230 return newpidl;
231}
232/*************************************************************************
233 * ILCloneFirst [SHELL32.19]
234 *
235 * NOTES
236 * duplicates the first idlist of a complex pidl
237 */
[7904]238LPITEMIDLIST WIN32API ILCloneFirst(LPCITEMIDLIST pidl)
[6709]239{ DWORD len;
240 LPITEMIDLIST pidlNew = NULL;
[21639]241
[6709]242 TRACE("pidl=%p \n",pidl);
243 pdump(pidl);
[21639]244
[6709]245 if (pidl)
246 {
[21639]247 len = pidl->mkid.cb;
[7359]248 pidlNew = (LPITEMIDLIST) SHAlloc (len+2);
[6709]249 if (pidlNew)
250 {
251 memcpy(pidlNew,pidl,len+2); /* 2 -> mind a desktop pidl */
[4121]252
[6709]253 if (len)
[7359]254 ODIN_ILGETNEXT(pidlNew)->mkid.cb = 0x00;
[6709]255 }
256 }
257 TRACE("-- newpidl=%p\n",pidlNew);
[4121]258
[6709]259 return pidlNew;
[4121]260}
[5618]261
[4121]262/*************************************************************************
263 * ILLoadFromStream
264 *
265 * NOTES
266 * the first two bytes are the len, the pidl is following then
267 */
[7904]268HRESULT WIN32API ILLoadFromStream(IStream *pStream, LPITEMIDLIST *ppPidl)
[6709]269{ WORD wLen = 0;
270 DWORD dwBytesRead;
271 HRESULT ret = E_FAIL;
[4121]272
[21639]273
[6709]274 TRACE_(shell)("%p %p\n", pStream , ppPidl);
[4121]275
[6709]276 if (*ppPidl)
[7359]277 { SHFree(*ppPidl);
[6709]278 *ppPidl = NULL;
279 }
[21639]280
[6709]281 IStream_AddRef (pStream);
[4121]282
[6709]283 if (SUCCEEDED(IStream_Read(pStream, (LPVOID)&wLen, 2, &dwBytesRead)))
[7359]284 { *ppPidl = SHAlloc (wLen);
[6709]285 if (SUCCEEDED(IStream_Read(pStream, *ppPidl , wLen, &dwBytesRead)))
286 { ret = S_OK;
287 }
288 else
[7359]289 { SHFree(*ppPidl);
[6709]290 *ppPidl = NULL;
291 }
292 }
[21639]293
[6709]294 /* we are not yet fully compatible */
295 if (!pcheck(*ppPidl))
[7359]296 { SHFree(*ppPidl);
[6709]297 *ppPidl = NULL;
298 }
[4121]299
[21639]300
[6709]301 IStream_Release (pStream);
[4121]302
[6709]303 return ret;
[4121]304}
[5618]305
[4121]306/*************************************************************************
[5618]307 * ILSaveToStream
308 *
309 * NOTES
310 * the first two bytes are the len, the pidl is following then
311 */
[7904]312HRESULT WIN32API ILSaveToStream(IStream * pStream, LPCITEMIDLIST pPidl)
[5618]313{
[6709]314 LPITEMIDLIST pidl;
315 WORD wLen = 0;
316 HRESULT ret = E_FAIL;
[21639]317
[6709]318 TRACE_(shell)("%p %p\n", pStream, pPidl);
[5618]319
[6709]320 IStream_AddRef (pStream);
[5618]321
[6709]322 pidl = pPidl;
[5618]323 while (pidl->mkid.cb)
324 {
325 wLen += sizeof(WORD) + pidl->mkid.cb;
[7359]326 pidl = ODIN_ILGETNEXT(pidl);
[5618]327 }
328
[6709]329 if (SUCCEEDED(IStream_Write(pStream, (LPVOID)&wLen, 2, NULL)))
330 {
331 if (SUCCEEDED(IStream_Write(pStream, pPidl, wLen, NULL)))
332 { ret = S_OK;
333 }
334 }
[5618]335
[21639]336
[6709]337 IStream_Release (pStream);
[5618]338
[6709]339 return ret;
[5618]340}
341
342/*************************************************************************
[6709]343 * SHILCreateFromPath [SHELL32.28]
[4121]344 *
345 * NOTES
346 * wraper for IShellFolder::ParseDisplayName()
347 */
[21639]348HRESULT WIN32API SHILCreateFromPathA(LPCSTR path, LPITEMIDLIST *ppidl,
[7904]349 DWORD *attributes)
[6709]350{ LPSHELLFOLDER sf;
351 WCHAR lpszDisplayName[MAX_PATH];
352 DWORD pchEaten;
353 HRESULT ret = E_FAIL;
[21639]354
[6709]355 TRACE_(shell)("%s %p 0x%08lx\n",path,ppidl,attributes?*attributes:0);
[4121]356
[5618]357 if (!MultiByteToWideChar( CP_ACP, 0, path, -1, lpszDisplayName, MAX_PATH ))
358 lpszDisplayName[MAX_PATH-1] = 0;
[4121]359
[6709]360 if (SUCCEEDED (SHGetDesktopFolder(&sf)))
361 {
362 ret = IShellFolder_ParseDisplayName(sf,0, NULL,lpszDisplayName,&pchEaten,ppidl,attributes);
363 IShellFolder_Release(sf);
364 }
365 return ret;
[4121]366}
[6999]367
368
[21639]369HRESULT WIN32API SHILCreateFromPathW(LPCWSTR path,
370 LPITEMIDLIST * ppidl,
[7904]371 DWORD * attributes)
[6709]372{ LPSHELLFOLDER sf;
373 DWORD pchEaten;
374 HRESULT ret = E_FAIL;
[21639]375
[6709]376 TRACE_(shell)("%s %p 0x%08lx\n",debugstr_w(path),ppidl,attributes?*attributes:0);
[4121]377
[6709]378 if (SUCCEEDED (SHGetDesktopFolder(&sf)))
379 {
380 ret = IShellFolder_ParseDisplayName(sf,0, NULL, (LPWSTR) path, &pchEaten, ppidl, attributes);
381 IShellFolder_Release(sf);
382 }
383 return ret;
[4121]384}
385HRESULT WINAPI SHILCreateFromPathAW (LPCVOID path, LPITEMIDLIST * ppidl, DWORD * attributes)
386{
[6709]387 if ( SHELL_OsIsUnicode())
388 return SHILCreateFromPathW (path, ppidl, attributes);
389 return SHILCreateFromPathA (path, ppidl, attributes);
[4121]390}
391
392/*************************************************************************
393 * SHCloneSpecialIDList [SHELL32.89]
[21639]394 *
[4121]395 * PARAMETERS
[21639]396 * hwndOwner [in]
[6709]397 * nFolder [in] CSIDL_xxxxx ??
[4121]398 *
399 * RETURNS
400 * pidl ??
401 * NOTES
402 * exported by ordinal
403 */
[7904]404LPITEMIDLIST WIN32API SHCloneSpecialIDList(HWND hwndOwner,
405 DWORD nFolder,
406 DWORD x3)
[6709]407{ LPITEMIDLIST ppidl;
408 WARN_(shell)("(hwnd=0x%x,csidl=0x%lx,0x%lx):semi-stub.\n",
409 hwndOwner,nFolder,x3);
[4121]410
[6709]411 SHGetSpecialFolderLocation(hwndOwner, nFolder, &ppidl);
[4121]412
[6709]413 return ppidl;
[4121]414}
415
416/*************************************************************************
417 * ILGlobalClone [SHELL32.97]
418 *
419 */
[7904]420LPITEMIDLIST WIN32API ILGlobalClone(
421 LPCITEMIDLIST pidl)
[6709]422{ DWORD len;
423 LPITEMIDLIST newpidl;
[4121]424
[6709]425 if (!pidl)
426 return NULL;
[21639]427
[7359]428 len = ILGetSize(pidl);
[6709]429 newpidl = (LPITEMIDLIST)pCOMCTL32_Alloc(len);
430 if (newpidl)
431 memcpy(newpidl,pidl,len);
[4121]432
[6709]433 TRACE("pidl=%p newpidl=%p\n",pidl, newpidl);
434 pdump(pidl);
[4121]435
[6709]436 return newpidl;
[4121]437}
438
439/*************************************************************************
440 * ILIsEqual [SHELL32.21]
441 *
442 */
[7904]443BOOL WIN32API ILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
[4121]444{
[7098]445// char szData1[MAX_PATH];
446// char szData2[MAX_PATH];
[4121]447
[7098]448// LPITEMIDLIST pidltemp1 = pidl1;
449// LPITEMIDLIST pidltemp2 = pidl2;
[4121]450
[6709]451 TRACE("pidl1=%p pidl2=%p\n",pidl1, pidl2);
[4121]452
[6709]453 /* explorer reads from registry directly (StreamMRU),
454 so we can only check here */
[7098]455// if ((!pcheck (pidl1)) || (!pcheck (pidl2))) return FALSE;
[4121]456
[7098]457// pdump (pidl1);
458// pdump (pidl2);
[4121]459
[6709]460 if ( (!pidl1) || (!pidl2) ) return FALSE;
[21639]461
[7098]462 while (pidl1->mkid.cb && pidl2->mkid.cb)
463 {
[7156]464 // compare lengths first
465 if (pidl1->mkid.cb != pidl2->mkid.cb)
466 return FALSE;
[21639]467
[7031]468// _ILSimpleGetText(pidltemp1, szData1, MAX_PATH);
469// _ILSimpleGetText(pidltemp2, szData2, MAX_PATH);
470//
471// if (strcasecmp ( szData1, szData2 )!=0 )
[7098]472 if (_ILSimpleCompareText(pidl1, pidl2) != 0)
[6709]473 return FALSE;
[4121]474
[7359]475 pidl1 = ODIN_ILGETNEXT(pidl1);
476 pidl2 = ODIN_ILGETNEXT(pidl2);
[6709]477 }
[21639]478
[7098]479 if (!pidl1->mkid.cb && !pidl2->mkid.cb)
480 {
481 return TRUE;
482 }
[4121]483
[6709]484 return FALSE;
[4121]485}
486/*************************************************************************
487 * ILIsParent [SHELL32.23]
488 *
[6709]489 * parent=a/b child=a/b/c -> true, c is in folder a/b
490 * child=a/b/c/d -> false if bImmediate is true, d is not in folder a/b
491 * child=a/b/c/d -> true if bImmediate is false, d is in a subfolder of a/b
[4121]492 */
[7904]493BOOL WIN32API ILIsParent(LPCITEMIDLIST pidlParent, LPCITEMIDLIST pidlChild,
494 BOOL bImmediate)
[4121]495{
[6709]496 char szData1[MAX_PATH];
497 char szData2[MAX_PATH];
[4121]498
[6709]499 LPITEMIDLIST pParent = pidlParent;
500 LPITEMIDLIST pChild = pidlChild;
[21639]501
[6709]502 TRACE("%p %p %x\n", pidlParent, pidlChild, bImmediate);
[4121]503
[6709]504 while (pParent->mkid.cb && pChild->mkid.cb)
505 {
[7031]506// _ILSimpleGetText(pParent, szData1, MAX_PATH);
507// _ILSimpleGetText(pChild, szData2, MAX_PATH);
508//
509// if (strcasecmp ( szData1, szData2 )!=0 )
510 if ( _ILSimpleCompareText(pParent, pChild) != 0)
511 return FALSE;
[4121]512
[7359]513 pParent = ODIN_ILGETNEXT(pParent);
514 pChild = ODIN_ILGETNEXT(pChild);
[21639]515 }
516
[6709]517 if ( pParent->mkid.cb || ! pChild->mkid.cb) /* child shorter or has equal length to parent */
518 return FALSE;
[21639]519
[7359]520 if ( ODIN_ILGETNEXT(pChild)->mkid.cb && bImmediate) /* not immediate descent */
[6709]521 return FALSE;
[21639]522
[6709]523 return TRUE;
[4121]524}
525
526/*************************************************************************
527 * ILFindChild [SHELL32.24]
528 *
529 * NOTES
530 * Compares elements from pidl1 and pidl2.
531 *
[6709]532 * pidl1 is desktop pidl2
533 * pidl1 shorter pidl2 pointer to first different element of pidl2
534 * if there was at least one equal element
535 * pidl2 shorter pidl1 0
536 * pidl2 equal pidl1 pointer to last 0x00-element of pidl2
[4121]537 */
[21916]538LPITEMIDLIST WIN32API ILFindChild(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
[4121]539{
[6709]540 char szData1[MAX_PATH];
541 char szData2[MAX_PATH];
[4121]542
[6709]543 LPITEMIDLIST pidltemp1 = pidl1;
544 LPITEMIDLIST pidltemp2 = pidl2;
545 LPITEMIDLIST ret=NULL;
[4121]546
[6709]547 TRACE("pidl1=%p pidl2=%p\n",pidl1, pidl2);
[4121]548
[6709]549 /* explorer reads from registry directly (StreamMRU),
550 so we can only check here */
551 if ((!pcheck (pidl1)) || (!pcheck (pidl2)))
552 return FALSE;
[4121]553
[6709]554 pdump (pidl1);
555 pdump (pidl2);
[4121]556
[6709]557 if ( _ILIsDesktop(pidl1) )
558 {
559 ret = pidl2;
560 }
561 else
562 {
563 while (pidltemp1->mkid.cb && pidltemp2->mkid.cb)
564 {
[7031]565// _ILSimpleGetText(pidltemp1, szData1, MAX_PATH);
566// _ILSimpleGetText(pidltemp2, szData2, MAX_PATH);
567//
568// if (strcasecmp(szData1,szData2))
569 if ( _ILSimpleCompareText( pidltemp1, pidltemp2 ) )
[6709]570 break;
[4121]571
[7359]572 pidltemp1 = ODIN_ILGETNEXT(pidltemp1);
573 pidltemp2 = ODIN_ILGETNEXT(pidltemp2);
[21639]574 ret = pidltemp2;
[6709]575 }
[4121]576
[6709]577 if (pidltemp1->mkid.cb)
578 {
579 ret = NULL; /* elements of pidl1 left*/
580 }
581 }
582 TRACE_(shell)("--- %p\n", ret);
583 return ret; /* pidl 1 is shorter */
[4121]584}
585
586/*************************************************************************
587 * ILCombine [SHELL32.25]
588 *
589 * NOTES
590 * Concatenates two complex idlists.
591 * The pidl is the first one, pidlsub the next one
592 * Does not destroy the passed in idlists!
593 */
[7904]594LPITEMIDLIST WIN32API ILCombine(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
[4121]595{
[6709]596 DWORD len1,len2;
597 LPITEMIDLIST pidlNew;
[4121]598
[21639]599
[6709]600 if(!pidl1 && !pidl2) return NULL;
[4121]601
[6709]602 pdump (pidl1);
603 pdump (pidl2);
[4121]604
[6709]605 if(!pidl1)
606 {
[7359]607 pidlNew = ILClone(pidl2);
[6709]608 return pidlNew;
609 }
[4121]610
[6709]611 if(!pidl2)
612 {
[7359]613 pidlNew = ILClone(pidl1);
[6709]614 return pidlNew;
615 }
[4121]616
[7359]617 len1 = ILGetSize(pidl1)-2;
618 len2 = ILGetSize(pidl2);
619 pidlNew = SHAlloc(len1+len2);
[4121]620
[6709]621 if (pidlNew)
622 {
623 memcpy(pidlNew,pidl1,len1);
624 memcpy(((BYTE *)pidlNew)+len1,pidl2,len2);
625 }
[4121]626
[6709]627 /* TRACE(pidl,"--new pidl=%p\n",pidlNew);*/
628 return pidlNew;
[4121]629}
630/*************************************************************************
631 * SHGetRealIDL [SHELL32.98]
632 *
633 * NOTES
634 */
[7904]635LPITEMIDLIST WIN32API SHGetRealIDL(LPSHELLFOLDER lpsf, LPITEMIDLIST pidl,
636 DWORD z)
[4121]637{
[6999]638 dprintf(("not yet implemented"));
[21639]639
[6709]640 FIXME("sf=%p pidl=%p 0x%04lx\n",lpsf,pidl,z);
[4121]641
[6709]642 pdump (pidl);
643 return 0;
[4121]644}
645
646/*************************************************************************
647 * SHLogILFromFSIL [SHELL32.95]
648 *
649 * NOTES
[6709]650 * pild = CSIDL_DESKTOP ret = 0
651 * pild = CSIDL_DRIVES ret = 0
[4121]652 */
[7904]653LPITEMIDLIST WIN32API SHLogILFromFSIL(LPITEMIDLIST pidl)
[4121]654{
[6999]655 dprintf(("not yet implemented"));
[21639]656
[6709]657 FIXME("(pidl=%p)\n",pidl);
[4121]658
[6709]659 pdump(pidl);
[4121]660
[6709]661 return 0;
[4121]662}
663
664/*************************************************************************
665 * ILGetSize [SHELL32.152]
666 * gets the byte size of an idlist including zero terminator (pidl)
667 *
668 * PARAMETERS
669 * pidl ITEMIDLIST
670 *
671 * RETURNS
672 * size of pidl
673 *
674 * NOTES
675 * exported by ordinal
676 */
[7904]677DWORD WIN32API ILGetSize(LPITEMIDLIST pidl)
[4121]678{
[6999]679 LPSHITEMID si = &(pidl->mkid);
680 DWORD len=0;
[21639]681
[6999]682 // @@@PH this cannot be correct: pidl==NULL would crash!
683 if (pidl)
[21639]684 {
[6999]685 while (si->cb)
[21639]686 {
[6999]687 len += si->cb;
688 si = (LPSHITEMID)(((LPBYTE)si)+si->cb);
689 }
690 len += 2;
691 }
692 TRACE("pidl=%p size=%lu\n",pidl, len);
693 return len;
[4121]694}
695
696/*************************************************************************
[7359]697 * ODIN_ILGETNEXT [SHELL32.153]
[4121]698 * gets the next simple pidl of a complex pidl
699 *
700 * observed return values:
701 * null -> null
702 * desktop -> null
703 * simple pidl -> pointer to 0x0000 element
704 *
705 */
[7904]706LPITEMIDLIST WIN32API ILGetNext(LPITEMIDLIST pidl)
[4121]707{
[7359]708#ifdef __WIN32OS2__
709 return ODIN_ILGETNEXT(pidl);
710#else
[7012]711 WORD len;
[4121]712
[7012]713 if(pidl)
714 {
715 len = pidl->mkid.cb;
716 if (len)
717 return (LPITEMIDLIST) (((LPBYTE)pidl)+len);
718 }
719 return NULL;
[7359]720#endif
[4121]721}
722/*************************************************************************
723 * ILAppend [SHELL32.154]
724 *
725 * NOTES
726 * Adds the single item to the idlist indicated by pidl.
727 * if bEnd is 0, adds the item to the front of the list,
728 * otherwise adds the item to the end. (???)
729 * Destroys the passed in idlist! (???)
730 */
[7904]731LPITEMIDLIST WIN32API ILAppend(
732 LPITEMIDLIST pidl,
733 LPCITEMIDLIST item,
734 BOOL bEnd)
[4121]735{
[6709]736 LPITEMIDLIST idlRet;
[4121]737
[6709]738 WARN("(pidl=%p,pidl=%p,%08u)semi-stub\n",pidl,item,bEnd);
[4121]739
[6709]740 pdump (pidl);
741 pdump (item);
[21639]742
[6709]743 if (_ILIsDesktop(pidl))
744 {
[7359]745 idlRet = ILClone(item);
[6709]746 if (pidl)
[7359]747 SHFree (pidl);
[6709]748 return idlRet;
749 }
[4121]750
[6709]751 if (bEnd)
752 {
753 idlRet=ILCombine(pidl,item);
754 }
755 else
756 {
757 idlRet=ILCombine(item,pidl);
758 }
[4121]759
[7359]760 SHFree(pidl);
[6709]761 return idlRet;
[4121]762}
763/*************************************************************************
764 * ILFree [SHELL32.155]
765 *
766 * NOTES
767 * free_check_ptr - frees memory (if not NULL)
768 * allocated by SHMalloc allocator
769 * exported by ordinal
770 */
[21916]771DWORD WIN32API ILFree(LPITEMIDLIST pidl)
[4121]772{
[21639]773 if(!pidl)
[7012]774 return FALSE;
[7359]775 SHFree(pidl);
[7012]776 return TRUE;
[4121]777}
778/*************************************************************************
779 * ILGlobalFree [SHELL32.156]
780 *
781 */
[7904]782void WIN32API ILGlobalFree(LPCITEMIDLIST pidl)
[4121]783{
[6709]784 TRACE("%p\n",pidl);
[4121]785
[6709]786 if(!pidl) return;
787 pCOMCTL32_Free(pidl);
[4121]788}
789/*************************************************************************
790 * ILCreateFromPath [SHELL32.157]
791 *
792 */
[7904]793LPITEMIDLIST WIN32API ILCreateFromPathA(LPCSTR path)
[4121]794{
[6709]795 LPITEMIDLIST pidlnew;
796 DWORD attributes = 0;
[4121]797
[6709]798 TRACE_(shell)("%s\n",path);
[4121]799
[6709]800 if (SUCCEEDED (SHILCreateFromPathA (path, &pidlnew, &attributes)))
801 return pidlnew;
802 return FALSE;
[4121]803}
[6999]804
805
[7904]806LPITEMIDLIST WIN32API ILCreateFromPathW(LPCWSTR path)
[4121]807{
[6709]808 LPITEMIDLIST pidlnew;
809 DWORD attributes = 0;
[4121]810
[6709]811 TRACE_(shell)("%s\n",debugstr_w(path));
[4121]812
[6709]813 if (SUCCEEDED (SHILCreateFromPathW (path, &pidlnew, &attributes)))
814 return pidlnew;
815 return FALSE;
[4121]816}
[21639]817LPITEMIDLIST WINAPI ILCreateFromPathAW (LPCVOID path)
[4121]818{
[6709]819 if ( SHELL_OsIsUnicode())
820 return ILCreateFromPathW (path);
821 return ILCreateFromPathA (path);
[4121]822}
823/*************************************************************************
824 * SHSimpleIDListFromPath [SHELL32.162]
825 */
[7904]826LPITEMIDLIST WIN32API SHSimpleIDListFromPathA(LPCSTR lpszPath)
[4121]827{
[6709]828 LPITEMIDLIST pidl=NULL;
829 HANDLE hFile;
830 WIN32_FIND_DATAA stffile;
[4121]831
[6709]832 TRACE("path=%s\n", lpszPath);
[4121]833
[6709]834 if (!lpszPath) return NULL;
[4121]835
[6709]836 hFile = FindFirstFileA(lpszPath, &stffile);
[4121]837
[6709]838 if ( hFile != INVALID_HANDLE_VALUE )
839 {
840 if (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
841 {
842 pidl = _ILCreateFolder (&stffile);
843 }
844 else
845 {
846 pidl = _ILCreateValue (&stffile);
847 }
848 FindClose (hFile);
849 }
850 return pidl;
[4121]851}
[6999]852
853
[7904]854LPITEMIDLIST WIN32API SHSimpleIDListFromPathW(LPCWSTR lpszPath)
[4121]855{
[6709]856 char lpszTemp[MAX_PATH];
857 TRACE("path=%s\n",debugstr_w(lpszPath));
[4121]858
[5618]859 if (!WideCharToMultiByte( CP_ACP, 0, lpszPath, -1, lpszTemp, sizeof(lpszTemp), NULL, NULL ))
860 lpszTemp[sizeof(lpszTemp)-1] = 0;
[4121]861
[6709]862 return SHSimpleIDListFromPathA (lpszTemp);
[4121]863}
864
865LPITEMIDLIST WINAPI SHSimpleIDListFromPathAW (LPCVOID lpszPath)
866{
[6709]867 if ( SHELL_OsIsUnicode())
868 return SHSimpleIDListFromPathW (lpszPath);
869 return SHSimpleIDListFromPathA (lpszPath);
[4121]870}
871
872/*************************************************************************
[6709]873 * SHGetSpecialFolderLocation [SHELL32.223]
[4121]874 *
875 * gets the folder locations from the registry and creates a pidl
876 * creates missing reg keys and directorys
[21639]877 *
[4121]878 * PARAMS
879 * hwndOwner [I]
880 * nFolder [I] CSIDL_xxxxx
881 * ppidl [O] PIDL of a special folder
882 *
883 */
[7904]884HRESULT WIN32API SHGetSpecialFolderLocation(HWND hwndOwner,
885 INT nFolder,
886 LPITEMIDLIST * ppidl)
[4121]887{
[6709]888 CHAR szPath[MAX_PATH];
889 HRESULT hr = E_INVALIDARG;
[4121]890
[6709]891 TRACE_(shell)("(%04x,0x%x,%p)\n", hwndOwner,nFolder,ppidl);
[4121]892
[6709]893 if (ppidl)
894 {
895 *ppidl = NULL;
896 switch (nFolder)
897 {
898 case CSIDL_DESKTOP:
899 *ppidl = _ILCreateDesktop();
900 break;
[4121]901
[6709]902 case CSIDL_DRIVES:
903 *ppidl = _ILCreateMyComputer();
904 break;
[4121]905
[6709]906 case CSIDL_NETWORK:
907 *ppidl = _ILCreateNetwork ();
908 break;
[4121]909
[6709]910 case CSIDL_CONTROLS:
911 *ppidl = _ILCreateControl ();
912 break;
[4121]913
[6709]914 case CSIDL_PRINTERS:
915 *ppidl = _ILCreatePrinter ();
916 break;
[4121]917
[6709]918 case CSIDL_BITBUCKET:
919 *ppidl = _ILCreateBitBucket ();
920 break;
[4121]921
[6709]922 default:
923 if (SHGetSpecialFolderPathA(hwndOwner, szPath, nFolder, TRUE))
924 {
925 DWORD attributes=0;
926 TRACE_(shell)("Value=%s\n",szPath);
927 hr = SHILCreateFromPathA(szPath, ppidl, &attributes);
928 }
929 }
930 if(*ppidl) hr = NOERROR;
931 }
[4121]932
[6709]933 TRACE_(shell)("-- (new pidl %p)\n",*ppidl);
934 return hr;
[4121]935}
936
937/*************************************************************************
938 * SHGetFolderLocation [SHELL32]
939 *
940 * NOTES
941 * the pidl can be a simple one. since we cant get the path out of the pidl
942 * we have to take all data from the pidl
943 */
[7904]944HRESULT WIN32API SHGetFolderLocation(HWND hwnd, int csidl,
945 HANDLE hToken,
946 DWORD dwFlags,
947 LPITEMIDLIST * ppidl)
[4121]948{
[6709]949 FIXME("0x%04x 0x%08x 0x%08x 0x%08lx %p\n",
950 hwnd, csidl, hToken, dwFlags, ppidl);
951 return SHGetSpecialFolderLocation(hwnd, csidl, ppidl);
[4121]952}
953
954/*************************************************************************
955 * SHGetDataFromIDListA [SHELL32.247]
956 *
957 * NOTES
958 * the pidl can be a simple one. since we cant get the path out of the pidl
959 * we have to take all data from the pidl
960 */
[7904]961HRESULT WIN32API SHGetDataFromIDListA(LPSHELLFOLDER psf,
962 LPCITEMIDLIST pidl,
963 int nFormat,
964 LPVOID dest,
965 int len)
[4121]966{
[6709]967 TRACE_(shell)("sf=%p pidl=%p 0x%04x %p 0x%04x stub\n",psf,pidl,nFormat,dest,len);
[21639]968
[6709]969 pdump(pidl);
970 if (!psf || !dest ) return E_INVALIDARG;
[4121]971
[6709]972 switch (nFormat)
973 {
974 case SHGDFIL_FINDDATA:
975 {
976 WIN32_FIND_DATAA * pfd = dest;
[4121]977
[6709]978 if ( len < sizeof (WIN32_FIND_DATAA)) return E_INVALIDARG;
[4121]979
[6709]980 ZeroMemory(pfd, sizeof (WIN32_FIND_DATAA));
981 _ILGetFileDateTime( pidl, &(pfd->ftLastWriteTime));
982 pfd->dwFileAttributes = _ILGetFileAttributes(pidl, NULL, 0);
983 pfd->nFileSizeLow = _ILGetFileSize ( pidl, NULL, 0);
984 lstrcpynA(pfd->cFileName,_ILGetTextPointer(pidl), MAX_PATH);
985 lstrcpynA(pfd->cAlternateFileName,_ILGetSTextPointer(pidl), 14);
986 }
987 return NOERROR;
[4121]988
[6709]989 case SHGDFIL_NETRESOURCE:
990 case SHGDFIL_DESCRIPTIONID:
991 FIXME_(shell)("SHGDFIL %i stub\n", nFormat);
992 break;
[4121]993
[6709]994 default:
995 ERR_(shell)("Unknown SHGDFIL %i, please report\n", nFormat);
996 }
[4121]997
[6709]998 return E_INVALIDARG;
[4121]999}
1000/*************************************************************************
1001 * SHGetDataFromIDListW [SHELL32.247]
1002 *
1003 */
[7904]1004HRESULT WIN32API SHGetDataFromIDListW(
1005 LPSHELLFOLDER psf,
1006 LPCITEMIDLIST pidl,
1007 int nFormat,
1008 LPVOID dest,
1009 int len)
[4121]1010{
[6709]1011 TRACE_(shell)("sf=%p pidl=%p 0x%04x %p 0x%04x stub\n",psf,pidl,nFormat,dest,len);
[4121]1012
[6709]1013 pdump(pidl);
[4121]1014
[6709]1015 if (! psf || !dest ) return E_INVALIDARG;
[4121]1016
[6709]1017 switch (nFormat)
1018 {
1019 case SHGDFIL_FINDDATA:
1020 {
1021 WIN32_FIND_DATAW * pfd = dest;
[4121]1022
[6709]1023 if ( len < sizeof (WIN32_FIND_DATAW)) return E_INVALIDARG;
[4121]1024
[6709]1025 ZeroMemory(pfd, sizeof (WIN32_FIND_DATAA));
1026 _ILGetFileDateTime( pidl, &(pfd->ftLastWriteTime));
1027 pfd->dwFileAttributes = _ILGetFileAttributes(pidl, NULL, 0);
1028 pfd->nFileSizeLow = _ILGetFileSize ( pidl, NULL, 0);
[5618]1029 if (!MultiByteToWideChar( CP_ACP, 0, _ILGetTextPointer(pidl), -1,
1030 pfd->cFileName, MAX_PATH ))
1031 pfd->cFileName[MAX_PATH-1] = 0;
1032 if (!MultiByteToWideChar( CP_ACP, 0, _ILGetSTextPointer(pidl), -1,
1033 pfd->cAlternateFileName, 14 ))
1034 pfd->cFileName[13] = 0;
[6709]1035 }
1036 return NOERROR;
1037 case SHGDFIL_NETRESOURCE:
1038 case SHGDFIL_DESCRIPTIONID:
1039 FIXME_(shell)("SHGDFIL %i stub\n", nFormat);
1040 break;
[4121]1041
[6709]1042 default:
1043 ERR_(shell)("Unknown SHGDFIL %i, please report\n", nFormat);
1044 }
[4121]1045
[6709]1046 return E_INVALIDARG;
[4121]1047}
1048
1049/*************************************************************************
[6709]1050 * SHGetPathFromIDListA [SHELL32.261][NT 4.0: SHELL32.220]
[4121]1051 *
1052 * PARAMETERS
[21639]1053 * pidl, [IN] pidl
[4121]1054 * pszPath [OUT] path
1055 *
[21639]1056 * RETURNS
[4121]1057 * path from a passed PIDL.
1058 *
1059 * NOTES
[6709]1060 * NULL returns FALSE
1061 * desktop pidl gives path to desktopdirectory back
1062 * special pidls returning FALSE
[4121]1063 *
1064 * FIXME
1065 * fnGetDisplayNameOf can return different types of OLEString
1066 */
[7904]1067BOOL WIN32API SHGetPathFromIDListA(
1068 LPCITEMIDLIST pidl,
1069 LPSTR pszPath)
[6709]1070{ STRRET str;
1071 LPSHELLFOLDER shellfolder;
[4121]1072
[6709]1073 TRACE_(shell)("(pidl=%p,%p)\n",pidl,pszPath);
[4121]1074
[6709]1075 if (!pidl) return FALSE;
[4121]1076
[6709]1077 pdump(pidl);
[4121]1078
[6709]1079 if(_ILIsDesktop(pidl))
1080 {
[21639]1081 SHGetSpecialFolderPathA(0, pszPath, CSIDL_DESKTOPDIRECTORY, FALSE);
[6709]1082 }
1083 else if (_ILIsSpecialFolder(ILFindLastID(pidl)))
1084 {
1085 /* we are somewhere in a special folder */
1086 return FALSE;
1087 }
1088 else
1089 {
1090 if (SHGetDesktopFolder(&shellfolder)==S_OK)
1091 {
1092 IShellFolder_GetDisplayNameOf(shellfolder,pidl,SHGDN_FORPARSING,&str);
1093 StrRetToStrNA (pszPath, MAX_PATH, &str, pidl);
1094 IShellFolder_Release(shellfolder);
1095 }
1096 }
1097 TRACE_(shell)("-- (%s)\n",pszPath);
[4121]1098
[6709]1099 return TRUE;
[4121]1100}
1101/*************************************************************************
[6709]1102 * SHGetPathFromIDListW [SHELL32.262]
[4121]1103 */
[7904]1104BOOL WIN32API SHGetPathFromIDListW(
1105 LPCITEMIDLIST pidl,
1106 LPWSTR pszPath)
[6709]1107{ char sTemp[MAX_PATH];
[4121]1108
[6709]1109 TRACE_(shell)("(pidl=%p)\n", pidl);
[4121]1110
[6709]1111 SHGetPathFromIDListA (pidl, sTemp);
[5618]1112 MultiByteToWideChar( CP_ACP, 0, sTemp, -1, pszPath, MAX_PATH );
[4121]1113
[6709]1114 TRACE_(shell)("-- (%s)\n",debugstr_w(pszPath));
[4121]1115
[6709]1116 return TRUE;
[4121]1117}
1118
1119/*************************************************************************
[6709]1120 * SHBindToParent [shell version 5.0]
[4121]1121 */
[7904]1122HRESULT WIN32API SHBindToParent(
1123 LPCITEMIDLIST pidl,
1124 REFIID riid,
1125 LPVOID * ppv,
1126 LPCITEMIDLIST *ppidlLast)
[4121]1127{
[6709]1128 IShellFolder * psf;
1129 LPITEMIDLIST pidlChild, pidlParent;
1130 HRESULT hr=E_FAIL;
[21639]1131
[6709]1132 TRACE_(shell)("pidl=%p\n", pidl);
1133 pdump(pidl);
[21639]1134
[6709]1135 *ppv = NULL;
1136 if (ppidlLast) *ppidlLast = NULL;
[4121]1137
[6709]1138 if (_ILIsPidlSimple(pidl))
1139 {
1140 /* we are on desktop level */
[21639]1141 if (ppidlLast)
[7359]1142 *ppidlLast = ILClone(pidl);
[6709]1143 hr = SHGetDesktopFolder((IShellFolder**)ppv);
1144 }
1145 else
1146 {
[7359]1147 pidlChild = ILClone(ILFindLastID(pidl));
1148 pidlParent = ILClone(pidl);
[6709]1149 ILRemoveLastID(pidlParent);
[4121]1150
[6709]1151 hr = SHGetDesktopFolder(&psf);
[4121]1152
[6709]1153 if (SUCCEEDED(hr))
1154 hr = IShellFolder_BindToObject(psf, pidlParent, NULL, riid, ppv);
[4121]1155
[6709]1156 if (SUCCEEDED(hr) && ppidlLast)
1157 *ppidlLast = pidlChild;
1158 else
1159 ILFree (pidlChild);
[4121]1160
[7359]1161 SHFree (pidlParent);
[6709]1162 if (psf) IShellFolder_Release(psf);
1163 }
[4121]1164
1165
[6709]1166 TRACE_(shell)("-- psf=%p pidl=%p ret=0x%08lx\n", *ppv, (ppidlLast)?*ppidlLast:NULL, hr);
1167 return hr;
[4121]1168}
1169
1170/*************************************************************************
[6709]1171 * SHGetPathFromIDListAW [SHELL32.221][NT 4.0: SHELL32.219]
[4121]1172 */
[7904]1173BOOL WIN32API SHGetPathFromIDListAW(LPCITEMIDLIST pidl,
1174 LPVOID pszPath)
[4121]1175{
[6709]1176 TRACE_(shell)("(pidl=%p,%p)\n",pidl,pszPath);
[4121]1177
[6709]1178 if (SHELL_OsIsUnicode())
1179 return SHGetPathFromIDListW(pidl,pszPath);
1180 return SHGetPathFromIDListA(pidl,pszPath);
[4121]1181}
1182
1183/**************************************************************************
1184 *
[6709]1185 * internal functions
[4121]1186 *
[6709]1187 * ### 1. section creating pidls ###
[4121]1188 *
1189 *************************************************************************
1190 * _ILCreateDesktop()
1191 * _ILCreateIExplore()
1192 * _ILCreateMyComputer()
1193 * _ILCreateDrive()
[21639]1194 * _ILCreateFolder()
[4121]1195 * _ILCreateValue()
1196 */
1197LPITEMIDLIST _ILCreateDesktop()
[6709]1198{ TRACE("()\n");
1199 return _ILCreate(PT_DESKTOP, NULL, 0);
[4121]1200}
1201
1202LPITEMIDLIST _ILCreateMyComputer()
[6709]1203{ TRACE("()\n");
1204 return _ILCreate(PT_MYCOMP, &CLSID_MyComputer, sizeof(GUID));
[4121]1205}
1206
1207LPITEMIDLIST _ILCreateIExplore()
[6709]1208{ TRACE("()\n");
1209 return _ILCreate(PT_MYCOMP, &CLSID_Internet, sizeof(GUID));
[4121]1210}
1211
1212LPITEMIDLIST _ILCreateControl()
[6709]1213{ TRACE("()\n");
1214 return _ILCreate(PT_SPECIAL, &CLSID_ControlPanel, sizeof(GUID));
[4121]1215}
1216
1217LPITEMIDLIST _ILCreatePrinter()
[6709]1218{ TRACE("()\n");
1219 return _ILCreate(PT_SPECIAL, &CLSID_Printers, sizeof(GUID));
[4121]1220}
1221
1222LPITEMIDLIST _ILCreateNetwork()
[6709]1223{ TRACE("()\n");
1224 return _ILCreate(PT_MYCOMP, &CLSID_NetworkPlaces, sizeof(GUID));
[4121]1225}
1226
1227LPITEMIDLIST _ILCreateBitBucket()
[6709]1228{ TRACE("()\n");
1229 return _ILCreate(PT_MYCOMP, &CLSID_RecycleBin, sizeof(GUID));
[4121]1230}
1231
1232LPITEMIDLIST _ILCreateDrive( LPCSTR lpszNew)
[6709]1233{ char sTemp[4];
1234 lstrcpynA (sTemp,lpszNew,4);
1235 sTemp[2]='\\';
1236 sTemp[3]=0x00;
1237 TRACE("(%s)\n",sTemp);
1238 return _ILCreate(PT_DRIVE,(LPVOID)&sTemp[0],4);
[4121]1239}
1240
1241LPITEMIDLIST _ILCreateFolder( WIN32_FIND_DATAA * stffile )
1242{
[6709]1243 char buff[MAX_PATH + 14 +1]; /* see WIN32_FIND_DATA */
1244 char * pbuff = buff;
1245 ULONG len, len1;
1246 LPITEMIDLIST pidl;
[21639]1247
[6709]1248 TRACE("(%s, %s)\n",stffile->cAlternateFileName, stffile->cFileName);
[4121]1249
[6709]1250 /* prepare buffer with both names */
1251 len = strlen (stffile->cFileName) + 1;
1252 memcpy (pbuff, stffile->cFileName, len);
1253 pbuff += len;
[4121]1254
[6709]1255 if (stffile->cAlternateFileName)
1256 {
1257 len1 = strlen (stffile->cAlternateFileName)+1;
1258 memcpy (pbuff, stffile->cAlternateFileName, len1);
1259 }
1260 else
1261 {
1262 len1 = 1;
1263 *pbuff = 0x00;
1264 }
[4121]1265
[6709]1266 pidl = _ILCreate(PT_FOLDER, (LPVOID)buff, len + len1);
[21639]1267
[6709]1268 /* set attributes */
1269 if (pidl)
1270 {
1271 LPPIDLDATA pData;
1272 pData = _ILGetDataPointer(pidl);
1273 FileTimeToDosDateTime(&(stffile->ftLastWriteTime),&pData->u.folder.uFileDate,&pData->u.folder.uFileTime);
1274 pData->u.folder.dwFileSize = stffile->nFileSizeLow;
1275 pData->u.folder.uFileAttribs=stffile->dwFileAttributes;
1276 }
[4121]1277
[6709]1278 return pidl;
[4121]1279}
1280
1281LPITEMIDLIST _ILCreateValue(WIN32_FIND_DATAA * stffile)
1282{
[6709]1283 char buff[MAX_PATH + 14 +1]; /* see WIN32_FIND_DATA */
1284 char * pbuff = buff;
1285 ULONG len, len1;
1286 LPITEMIDLIST pidl;
[21639]1287
[6709]1288 TRACE("(%s, %s)\n",stffile->cAlternateFileName, stffile->cFileName);
[4121]1289
[6709]1290 /* prepare buffer with both names */
1291 len = strlen (stffile->cFileName) + 1;
1292 memcpy (pbuff, stffile->cFileName, len);
1293 pbuff += len;
[4121]1294
[6709]1295 if (stffile->cAlternateFileName)
1296 {
1297 len1 = strlen (stffile->cAlternateFileName)+1;
1298 memcpy (pbuff, stffile->cAlternateFileName, len1);
1299 }
1300 else
1301 {
1302 len1 = 1;
1303 *pbuff = 0x00;
1304 }
[4121]1305
[6709]1306 pidl = _ILCreate(PT_VALUE, (LPVOID)buff, len + len1);
[21639]1307
[6709]1308 /* set attributes */
1309 if (pidl)
1310 {
1311 LPPIDLDATA pData;
1312 pData = _ILGetDataPointer(pidl);
1313 FileTimeToDosDateTime(&(stffile->ftLastWriteTime),&pData->u.folder.uFileDate,&pData->u.folder.uFileTime);
1314 pData->u.folder.dwFileSize = stffile->nFileSizeLow;
1315 pData->u.folder.uFileAttribs=stffile->dwFileAttributes;
1316 }
[4121]1317
[6709]1318 return pidl;
[4121]1319}
1320
1321LPITEMIDLIST _ILCreateSpecial(LPCSTR szGUID)
1322{
1323 IID iid;
1324 WCHAR buffer[40];
1325
1326 if (!MultiByteToWideChar( CP_ACP, 0, szGUID, -1, buffer, sizeof(buffer)/sizeof(WCHAR) ))
1327 return NULL;
1328 CLSIDFromString( buffer, &iid );
1329 return _ILCreate(PT_MYCOMP, &iid, sizeof(IID));
1330}
1331
1332/**************************************************************************
1333 * _ILCreate()
1334 * Creates a new PIDL
1335 * type = PT_DESKTOP | PT_DRIVE | PT_FOLDER | PT_VALUE
1336 * pIn = data
1337 * uInSize = size of data (raw)
1338 */
1339
[5618]1340LPITEMIDLIST _ILCreate(PIDLTYPE type, LPCVOID pIn, UINT uInSize)
[4121]1341{
[6709]1342 LPITEMIDLIST pidlOut = NULL, pidlTemp = NULL;
1343 LPPIDLDATA pData;
1344 UINT uSize = 0;
1345 LPSTR pszDest;
[21639]1346
[6709]1347 TRACE("(0x%02x %p %i)\n",type,pIn,uInSize);
[4121]1348
[6709]1349 switch (type)
1350 {
1351 case PT_DESKTOP:
1352 uSize = 0;
1353 break;
1354 case PT_SPECIAL:
1355 case PT_MYCOMP:
1356 uSize = 2 + 2 + sizeof(GUID);
1357 break;
1358 case PT_DRIVE:
1359 uSize = 2 + 23;
1360 break;
1361 case PT_FOLDER:
[21639]1362 case PT_VALUE:
[6709]1363 uSize = 2 + 12 + uInSize;
1364 break;
1365 default:
[21639]1366 FIXME("can't create type: 0x%08x\n",type);
[6709]1367 return NULL;
1368 }
[4121]1369
[7359]1370 if(!(pidlOut = SHAlloc(uSize + 2))) return NULL;
[6709]1371 ZeroMemory(pidlOut, uSize + 2);
1372 pidlOut->mkid.cb = uSize;
[4121]1373
[6709]1374 switch (type)
1375 {
1376 case PT_DESKTOP:
1377 TRACE("- create Desktop\n");
1378 break;
[4121]1379
[6709]1380 case PT_SPECIAL:
1381 case PT_MYCOMP:
1382 pData =_ILGetDataPointer(pidlOut);
1383 pData->type = type;
1384 memcpy(&(pData->u.mycomp.guid), pIn, uInSize);
1385 TRACE("- create GUID-pidl\n");
1386 break;
[4121]1387
[6709]1388 case PT_DRIVE:
1389 pData =_ILGetDataPointer(pidlOut);
1390 pData->type = type;
1391 pszDest = _ILGetTextPointer(pidlOut);
1392 memcpy(pszDest, pIn, uInSize);
1393 TRACE("- create Drive: %s\n",debugstr_a(pszDest));
1394 break;
[4121]1395
[6709]1396 case PT_FOLDER:
[21639]1397 case PT_VALUE:
[6709]1398 pData =_ILGetDataPointer(pidlOut);
1399 pData->type = type;
1400 pszDest = _ILGetTextPointer(pidlOut);
1401 memcpy(pszDest, pIn, uInSize);
1402 TRACE("- create Value: %s\n",debugstr_a(pszDest));
1403 break;
1404 }
[21639]1405
[7359]1406 pidlTemp = ODIN_ILGETNEXT(pidlOut);
[6709]1407 if (pidlTemp)
1408 pidlTemp->mkid.cb = 0x00;
[4121]1409
[6709]1410 TRACE("-- (pidl=%p, size=%u)\n", pidlOut, uSize);
1411 return pidlOut;
[4121]1412}
1413
1414/**************************************************************************
1415 * _ILGetDrive()
1416 *
1417 * Gets the text for the drive eg. 'c:\'
1418 *
1419 * RETURNS
1420 * strlen (lpszText)
1421 */
[5618]1422DWORD _ILGetDrive(LPCITEMIDLIST pidl,LPSTR pOut, UINT uSize)
[6709]1423{ TRACE("(%p,%p,%u)\n",pidl,pOut,uSize);
[4121]1424
[6709]1425 if(_ILIsMyComputer(pidl))
[7359]1426 pidl = ODIN_ILGETNEXT(pidl);
[4121]1427
[6709]1428 if (pidl && _ILIsDrive(pidl))
1429 return _ILSimpleGetText(pidl, pOut, uSize);
[4121]1430
[6709]1431 return 0;
[4121]1432}
1433
1434/**************************************************************************
1435 *
[6709]1436 * ### 2. section testing pidls ###
[4121]1437 *
1438 **************************************************************************
1439 * _ILIsDesktop()
1440 * _ILIsMyComputer()
1441 * _ILIsSpecialFolder()
1442 * _ILIsDrive()
1443 * _ILIsFolder()
1444 * _ILIsValue()
1445 * _ILIsPidlSimple()
1446 */
1447BOOL _ILIsDesktop(LPCITEMIDLIST pidl)
[6709]1448{ TRACE("(%p)\n",pidl);
1449 return ( !pidl || (pidl && pidl->mkid.cb == 0x00) );
[4121]1450}
1451
1452BOOL _ILIsMyComputer(LPCITEMIDLIST pidl)
1453{
[6709]1454 REFIID iid = _ILGetGUIDPointer(pidl);
[4121]1455
[6709]1456 TRACE("(%p)\n",pidl);
[4121]1457
[6709]1458 if (iid)
1459 return IsEqualIID(iid, &CLSID_MyComputer);
1460 return FALSE;
[4121]1461}
1462
1463BOOL _ILIsSpecialFolder (LPCITEMIDLIST pidl)
1464{
[6709]1465 LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
1466 TRACE("(%p)\n",pidl);
[21639]1467 return (pidl && ( (lpPData && (PT_MYCOMP== lpPData->type || PT_SPECIAL== lpPData->type)) ||
[6709]1468 (pidl && pidl->mkid.cb == 0x00)
1469 ));
[4121]1470}
1471
1472BOOL _ILIsDrive(LPCITEMIDLIST pidl)
[6709]1473{ LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
1474 TRACE("(%p)\n",pidl);
1475 return (pidl && lpPData && (PT_DRIVE == lpPData->type ||
1476 PT_DRIVE1 == lpPData->type ||
1477 PT_DRIVE2 == lpPData->type ||
1478 PT_DRIVE3 == lpPData->type));
[4121]1479}
1480
1481BOOL _ILIsFolder(LPCITEMIDLIST pidl)
[6709]1482{ LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
1483 TRACE("(%p)\n",pidl);
1484 return (pidl && lpPData && (PT_FOLDER == lpPData->type || PT_FOLDER1 == lpPData->type));
[4121]1485}
1486
1487BOOL _ILIsValue(LPCITEMIDLIST pidl)
[6709]1488{ LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
1489 TRACE("(%p)\n",pidl);
1490 return (pidl && lpPData && PT_VALUE == lpPData->type);
[4121]1491}
1492
1493/**************************************************************************
[6709]1494 * _ILIsPidlSimple
[4121]1495 */
1496BOOL _ILIsPidlSimple ( LPCITEMIDLIST pidl)
1497{
[6709]1498 BOOL ret = TRUE;
[4121]1499
[6709]1500 if(! _ILIsDesktop(pidl)) /* pidl=NULL or mkid.cb=0 */
1501 {
1502 WORD len = pidl->mkid.cb;
1503 LPCITEMIDLIST pidlnext = (LPCITEMIDLIST) (((LPBYTE)pidl) + len );
1504 if (pidlnext->mkid.cb)
1505 ret = FALSE;
1506 }
[4121]1507
[6709]1508 TRACE("%s\n", ret ? "Yes" : "No");
1509 return ret;
[4121]1510}
1511
1512/**************************************************************************
1513 *
[6709]1514 * ### 3. section getting values from pidls ###
[4121]1515 */
1516
1517 /**************************************************************************
1518 * _ILSimpleGetText
1519 *
1520 * gets the text for the first item in the pidl (eg. simple pidl)
1521 *
[5618]1522 * returns the length of the string
[4121]1523 */
1524DWORD _ILSimpleGetText (LPCITEMIDLIST pidl, LPSTR szOut, UINT uOutSize)
1525{
[21639]1526 DWORD dwReturn=0;
[6709]1527 LPSTR szSrc;
1528 GUID const * riid;
1529 char szTemp[MAX_PATH];
[21639]1530
[6709]1531 TRACE("(%p %p %x)\n",pidl,szOut,uOutSize);
[21639]1532
[6709]1533 if (!pidl) return 0;
[4121]1534
[6709]1535 if (szOut)
1536 *szOut = 0;
[4121]1537
[21639]1538 if (_ILIsDesktop(pidl))
[6709]1539 {
1540 /* desktop */
1541 if (HCR_GetClassName(&CLSID_ShellDesktop, szTemp, MAX_PATH))
1542 {
1543 if (szOut)
1544 lstrcpynA(szOut, szTemp, uOutSize);
[4121]1545
[6709]1546 dwReturn = strlen (szTemp);
1547 }
1548 }
1549 else if (( szSrc = _ILGetTextPointer(pidl) ))
1550 {
1551 /* filesystem */
1552 if (szOut)
1553 lstrcpynA(szOut, szSrc, uOutSize);
[4121]1554
[6709]1555 dwReturn = strlen(szSrc);
1556 }
1557 else if (( riid = _ILGetGUIDPointer(pidl) ))
1558 {
1559 /* special folder */
1560 if ( HCR_GetClassName(riid, szTemp, MAX_PATH) )
1561 {
1562 if (szOut)
1563 lstrcpynA(szOut, szTemp, uOutSize);
[4121]1564
[6709]1565 dwReturn = strlen (szTemp);
1566 }
1567 }
1568 else
1569 {
1570 ERR("-- no text\n");
1571 }
[4121]1572
[6709]1573 TRACE("-- (%p=%s 0x%08lx)\n",szOut,(char*)szOut,dwReturn);
1574 return dwReturn;
[4121]1575}
1576
[7031]1577
1578 /**************************************************************************
1579 * _ILSimpleCompareText
1580 *
1581 * gets the text for the first item in the pidl (eg. simple pidl)
1582 * and compares it with the text for the second pidl
1583 *
1584 * returns the length of the string
1585 */
1586int _ILSimpleCompareText (LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
1587{
1588 LPSTR lpText1;
1589 LPSTR lpText2;
[21639]1590
[7031]1591 char szTemp1[MAX_PATH];
1592 char szTemp2[MAX_PATH];
1593 GUID const * riid;
1594
[21639]1595
[7031]1596 if (!pidl1 && !pidl2)
1597 return 0;
[21639]1598
[7031]1599 if (!pidl1 && pidl2)
1600 return -1;
[21639]1601
[7031]1602 if (pidl1 && !pidl2)
1603 return 1;
[21639]1604
1605
[7031]1606 // -------------
1607 // examine pidl1
1608 // -------------
1609 if (_ILIsDesktop(pidl1))
1610 {
1611 HCR_GetClassName(&CLSID_ShellDesktop, szTemp1, MAX_PATH);
1612 lpText1 = szTemp1;
1613 }
1614 else
1615 if ( lpText1 = _ILGetTextPointer(pidl1) )
1616 {
1617 // OK, nice to have a valid pointer :)
1618 }
1619 else
1620 if ( riid = _ILGetGUIDPointer(pidl1) )
1621 {
1622 /* special folder */
1623 HCR_GetClassName(riid, szTemp1, MAX_PATH);
1624 lpText1 = szTemp1;
1625 }
1626 else
1627 lpText1 = "undetermined";
[21639]1628
[7031]1629 // -------------
1630 // examine pidl2
1631 // -------------
1632 if (_ILIsDesktop(pidl2))
1633 {
1634 HCR_GetClassName(&CLSID_ShellDesktop, szTemp2, MAX_PATH);
1635 lpText2 = szTemp2;
1636 }
1637 else
1638 if ( lpText2 = _ILGetTextPointer(pidl2) )
1639 {
1640 // OK, nice to have a valid pointer :)
1641 }
1642 else
1643 if ( riid = _ILGetGUIDPointer(pidl2) )
1644 {
1645 /* special folder */
1646 HCR_GetClassName(riid, szTemp2, MAX_PATH);
1647 lpText2 = szTemp2;
1648 }
1649 else
1650 lpText2 = "undetermined";
[21639]1651
1652
[7031]1653 // now finally compare the texts
1654 return strcasecmp(lpText1, lpText2);
1655}
1656
1657
[4121]1658/**************************************************************************
1659 *
[6709]1660 * ### 4. getting pointers to parts of pidls ###
[4121]1661 *
1662 **************************************************************************
1663 * _ILGetDataPointer()
1664 */
1665LPPIDLDATA _ILGetDataPointer(LPITEMIDLIST pidl)
1666{
[6709]1667 if(pidl && pidl->mkid.cb != 0x00)
1668 return (LPPIDLDATA) &(pidl->mkid.abID);
1669 return NULL;
[4121]1670}
1671
1672/**************************************************************************
1673 * _ILGetTextPointer()
1674 * gets a pointer to the long filename string stored in the pidl
1675 */
1676LPSTR _ILGetTextPointer(LPCITEMIDLIST pidl)
[6709]1677{/* TRACE(pidl,"(pidl%p)\n", pidl);*/
[4121]1678
[6709]1679 LPPIDLDATA pdata =_ILGetDataPointer(pidl);
[4121]1680
[6709]1681 if (pdata)
1682 {
1683 switch (pdata->type)
1684 {
1685 case PT_MYCOMP:
1686 case PT_SPECIAL:
1687 return NULL;
[4121]1688
[6709]1689 case PT_DRIVE:
1690 case PT_DRIVE1:
1691 case PT_DRIVE2:
1692 case PT_DRIVE3:
1693 return (LPSTR)&(pdata->u.drive.szDriveName);
[4121]1694
[6709]1695 case PT_FOLDER:
1696 case PT_FOLDER1:
1697 case PT_VALUE:
1698 case PT_IESPECIAL1:
1699 case PT_IESPECIAL2:
1700 return (LPSTR)&(pdata->u.file.szNames);
[4121]1701
[6709]1702 case PT_WORKGRP:
1703 case PT_COMP:
1704 case PT_NETWORK:
1705 case PT_SHARE:
1706 return (LPSTR)&(pdata->u.network.szNames);
1707 }
1708 }
1709 return NULL;
[4121]1710}
1711
1712/**************************************************************************
1713 * _ILGetSTextPointer()
1714 * gets a pointer to the short filename string stored in the pidl
1715 */
1716LPSTR _ILGetSTextPointer(LPCITEMIDLIST pidl)
[6709]1717{/* TRACE(pidl,"(pidl%p)\n", pidl);*/
[4121]1718
[6709]1719 LPPIDLDATA pdata =_ILGetDataPointer(pidl);
[4121]1720
[6709]1721 if (pdata)
1722 {
1723 switch (pdata->type)
1724 {
1725 case PT_FOLDER:
1726 case PT_VALUE:
1727 case PT_IESPECIAL1:
1728 case PT_IESPECIAL2:
1729 return (LPSTR)(pdata->u.file.szNames + strlen (pdata->u.file.szNames) + 1);
[4121]1730
[6709]1731 case PT_WORKGRP:
1732 return (LPSTR)(pdata->u.network.szNames + strlen (pdata->u.network.szNames) + 1);
1733 }
1734 }
1735 return NULL;
[4121]1736}
1737
1738/**************************************************************************
1739 * _ILGetGUIDPointer()
1740 *
1741 * returns reference to guid stored in some pidls
1742 */
1743REFIID _ILGetGUIDPointer(LPCITEMIDLIST pidl)
1744{
[6709]1745 LPPIDLDATA pdata =_ILGetDataPointer(pidl);
[4121]1746
[6709]1747 if (pdata)
1748 {
1749 switch (pdata->type)
1750 {
1751 case PT_SPECIAL:
1752 case PT_MYCOMP:
1753 return (REFIID) &(pdata->u.mycomp.guid);
1754 }
1755 }
1756 return NULL;
[4121]1757}
1758
1759/*************************************************************************
1760 * _ILGetFileDateTime
1761 *
1762 * Given the ItemIdList, get the FileTime
1763 *
1764 * PARAMS
1765 * pidl [I] The ItemIDList
1766 * pFt [I] the resulted FILETIME of the file
1767 *
1768 * RETURNS
1769 * True if Successful
1770 *
1771 * NOTES
[21639]1772 *
[4121]1773 */
1774BOOL _ILGetFileDateTime(LPCITEMIDLIST pidl, FILETIME *pFt)
1775{
1776 LPPIDLDATA pdata =_ILGetDataPointer(pidl);
1777
1778 if(! pdata) return FALSE;
1779
1780 switch (pdata->type)
[21639]1781 {
[4121]1782 case PT_FOLDER:
1783 DosDateTimeToFileTime(pdata->u.folder.uFileDate, pdata->u.folder.uFileTime, pFt);
[21639]1784 break;
[4121]1785 case PT_VALUE:
1786 DosDateTimeToFileTime(pdata->u.file.uFileDate, pdata->u.file.uFileTime, pFt);
1787 break;
1788 default:
1789 return FALSE;
1790 }
1791 return TRUE;
1792}
1793
1794BOOL _ILGetFileDate (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
[21639]1795{
[6709]1796 FILETIME ft,lft;
1797 SYSTEMTIME time;
[4121]1798
[6709]1799 if (! _ILGetFileDateTime( pidl, &ft )) return FALSE;
[21639]1800
[6709]1801 FileTimeToLocalFileTime(&ft, &lft);
1802 FileTimeToSystemTime (&lft, &time);
1803 return GetDateFormatA(LOCALE_USER_DEFAULT,DATE_SHORTDATE,&time, NULL, pOut, uOutSize);
[4121]1804}
1805
1806/*************************************************************************
1807 * _ILGetFileSize
1808 *
1809 * Given the ItemIdList, get the FileSize
1810 *
1811 * PARAMS
1812 * pidl [I] The ItemIDList
[6709]1813 * pOut [I] The buffer to save the result
[4121]1814 * uOutsize [I] The size of the buffer
1815 *
1816 * RETURNS
1817 * The FileSize
1818 *
1819 * NOTES
[6709]1820 * pOut can be null when no string is needed
[21639]1821 *
[4121]1822 */
1823DWORD _ILGetFileSize (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
1824{
[6709]1825 LPPIDLDATA pdata =_ILGetDataPointer(pidl);
1826 DWORD dwSize;
[21639]1827
[6709]1828 if(! pdata) return 0;
[4121]1829
[6709]1830 switch (pdata->type)
1831 {
1832 case PT_VALUE:
1833 dwSize = pdata->u.file.dwFileSize;
1834 if (pOut) StrFormatByteSizeA(dwSize, pOut, uOutSize);
1835 return dwSize;
1836 }
1837 if (pOut) *pOut = 0x00;
1838 return 0;
[4121]1839}
1840
1841BOOL _ILGetExtension (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
1842{
[6709]1843 char szTemp[MAX_PATH];
1844 const char * pPoint;
1845 LPITEMIDLIST pidlTemp=pidl;
[21639]1846
[6709]1847 TRACE("pidl=%p\n",pidl);
[4121]1848
[6709]1849 if (!pidl) return FALSE;
[21639]1850
[6709]1851 pidlTemp = ILFindLastID(pidl);
[21639]1852
[6709]1853 if (!_ILIsValue(pidlTemp)) return FALSE;
1854 if (!_ILSimpleGetText(pidlTemp, szTemp, MAX_PATH)) return FALSE;
[4121]1855
[6709]1856 pPoint = PathFindExtensionA(szTemp);
[4121]1857
[6709]1858 if (! *pPoint) return FALSE;
[4121]1859
[6709]1860 pPoint++;
1861 lstrcpynA(pOut, pPoint, uOutSize);
1862 TRACE("%s\n",pOut);
[4121]1863
[6709]1864 return TRUE;
[4121]1865}
1866
1867/*************************************************************************
1868 * _ILGetFileType
1869 *
1870 * Given the ItemIdList, get the file type description
1871 *
1872 * PARAMS
1873 * pidl [I] The ItemIDList (simple)
1874 * pOut [I] The buffer to save the result
1875 * uOutsize [I] The size of the buffer
1876 *
1877 * RETURNS
[6709]1878 * nothing
[4121]1879 *
1880 * NOTES
[21639]1881 * This function copies as much as possible into the buffer.
[4121]1882 */
1883void _ILGetFileType(LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
1884{
[6709]1885 if(_ILIsValue(pidl))
1886 {
[21639]1887 char sTemp[64];
1888 if(uOutSize > 0)
1889 {
1890 pOut[0] = 0;
1891 }
1892 if (_ILGetExtension (pidl, sTemp, 64))
1893 {
1894 if (!( HCR_MapTypeToValue(sTemp, sTemp, 64, TRUE)
1895 && HCR_MapTypeToValue(sTemp, pOut, uOutSize, FALSE )))
1896 {
1897 lstrcpynA (pOut, sTemp, uOutSize - 6);
1898 strupr (pOut);
1899 strcat (pOut, " File");
1900 }
1901 }
[6709]1902 }
1903 else
1904 {
[21639]1905 LPPIDLDATA pdata =_ILGetDataPointer(pidl);
1906
1907 if (pdata)
1908 {
1909 switch (pdata->type)
1910 {
1911 case PT_DRIVE:
1912 case PT_DRIVE1:
1913 case PT_DRIVE2:
1914 case PT_DRIVE3:
1915 {
1916 UINT type =
1917 GetDriveTypeA((LPSTR)&(pdata->u.drive.szDriveName));
1918 switch (type)
1919 {
1920 case DRIVE_REMOVABLE:
1921 lstrcpynA(pOut, "Removable Disk", uOutSize); return;
1922 case DRIVE_FIXED:
1923 lstrcpynA(pOut, "Local Disk", uOutSize); return;
1924 case DRIVE_REMOTE:
1925 lstrcpynA(pOut, "Network Drive", uOutSize); return;
1926 case DRIVE_CDROM:
1927 lstrcpynA(pOut, "CD Disk", uOutSize); return;
1928 default:
1929 break;
1930 }
1931 }
1932 default:
1933 break;
1934 }
1935 }
1936
1937 lstrcpynA(pOut, "File Folder", uOutSize);
[6709]1938 }
[4121]1939}
1940
1941/*************************************************************************
1942 * _ILGetFileAttributes
1943 *
1944 * Given the ItemIdList, get the Attrib string format
1945 *
1946 * PARAMS
1947 * pidl [I] The ItemIDList
1948 * pOut [I] The buffer to save the result
1949 * uOutsize [I] The size of the Buffer
1950 *
1951 * RETURNS
1952 * Attributes
1953 *
1954 * FIXME
1955 * return value 0 in case of error is a valid return value
[21639]1956 *
[4121]1957 */
1958DWORD _ILGetFileAttributes(LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize)
1959{
[6709]1960 LPPIDLDATA pData =_ILGetDataPointer(pidl);
1961 WORD wAttrib = 0;
1962 int i;
[4121]1963
[6709]1964 if(! pData) return 0;
[4121]1965
[6709]1966 switch(pData->type)
1967 {
1968 case PT_FOLDER:
1969 wAttrib = pData->u.folder.uFileAttribs;
1970 break;
1971 case PT_VALUE:
1972 wAttrib = pData->u.file.uFileAttribs;
1973 break;
1974 }
[21639]1975
[6709]1976 if(uOutSize >= 6)
1977 {
1978 i=0;
1979 if(wAttrib & FILE_ATTRIBUTE_READONLY)
1980 {
1981 pOut[i++] = 'R';
1982 }
1983 if(wAttrib & FILE_ATTRIBUTE_HIDDEN)
1984 {
1985 pOut[i++] = 'H';
1986 }
1987 if(wAttrib & FILE_ATTRIBUTE_SYSTEM)
1988 {
1989 pOut[i++] = 'S';
1990 }
1991 if(wAttrib & FILE_ATTRIBUTE_ARCHIVE)
1992 {
1993 pOut[i++] = 'A';
1994 }
1995 if(wAttrib & FILE_ATTRIBUTE_COMPRESSED)
1996 {
1997 pOut[i++] = 'C';
1998 }
1999 pOut[i] = 0x00;
2000 }
2001 return wAttrib;
[4121]2002}
2003
2004/*************************************************************************
2005* ILFreeaPidl
2006*
2007* free a aPidl struct
2008*/
2009void _ILFreeaPidl(LPITEMIDLIST * apidl, UINT cidl)
2010{
[6709]2011 int i;
[4121]2012
[6709]2013 if(apidl)
2014 {
[7359]2015 for(i = 0; i < cidl; i++) SHFree(apidl[i]);
2016 SHFree(apidl);
[6709]2017 }
[4121]2018}
2019
2020/*************************************************************************
2021* ILCopyaPidl
2022*
2023* copys a aPidl struct
2024*/
2025LPITEMIDLIST * _ILCopyaPidl(LPITEMIDLIST * apidlsrc, UINT cidl)
2026{
[6709]2027 int i;
[7359]2028 LPITEMIDLIST * apidldest = (LPITEMIDLIST*)SHAlloc(cidl * sizeof(LPITEMIDLIST));
[6709]2029 if(!apidlsrc) return NULL;
[4121]2030
[6709]2031 for(i = 0; i < cidl; i++)
[7359]2032 apidldest[i] = ILClone(apidlsrc[i]);
[4121]2033
[6709]2034 return apidldest;
[4121]2035}
2036
2037/*************************************************************************
2038* _ILCopyCidaToaPidl
2039*
2040* creates aPidl from CIDA
2041*/
2042LPITEMIDLIST * _ILCopyCidaToaPidl(LPITEMIDLIST* pidl, LPCIDA cida)
2043{
[6709]2044 int i;
[7359]2045 LPITEMIDLIST * dst = (LPITEMIDLIST*)SHAlloc(cida->cidl * sizeof(LPITEMIDLIST));
[4121]2046
[6709]2047 if(!dst) return NULL;
[4121]2048
[6709]2049 if (pidl)
[7359]2050 *pidl = ILClone((LPITEMIDLIST)(&((LPBYTE)cida)[cida->aoffset[0]]));
[4121]2051
[6709]2052 for(i = 0; i < cida->cidl; i++)
[7359]2053 dst[i] = ILClone((LPITEMIDLIST)(&((LPBYTE)cida)[cida->aoffset[i + 1]]));
[4121]2054
[6709]2055 return dst;
[4121]2056}
Note: See TracBrowser for help on using the repository browser.