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