source: trunk/src/shell32/shlfolder.cpp@ 3217

Last change on this file since 3217 was 3217, checked in by cbratschi, 25 years ago

bug fixes

File size: 60.8 KB
Line 
1/* $Id: shlfolder.cpp,v 1.8 2000-03-24 17:17:27 cbratschi Exp $ */
2/*
3 * Shell Folder stuff
4 *
5 * Copyright 1997 Marcus Meissner
6 * Copyright 1998, 1999 Juergen Schmied
7 *
8 * IShellFolder2 and related interfaces
9 *
10 */
11
12#include <stdlib.h>
13#include <string.h>
14#include <odin.h>
15
16#define ICOM_CINTERFACE 1
17#define CINTERFACE 1
18
19#include "debugtools.h"
20#include "winerror.h"
21
22#include "oleidl.h"
23#include "shlguid.h"
24
25#include "pidl.h"
26#include "wine/obj_base.h"
27#include "wine/obj_dragdrop.h"
28#include "wine/obj_shellfolder.h"
29#include "wine/undocshell.h"
30#include "shell32_main.h"
31#include "shresdef.h"
32
33#include <heapstring.h>
34#include <misc.h>
35
36DEFAULT_DEBUG_CHANNEL(shell)
37
38#define MEM_DEBUG 1
39
40typedef struct
41{
42 int colnameid;
43 int pcsFlags;
44 int fmt;
45 int cxChar;
46
47} shvheader;
48
49/***************************************************************************
50 * GetNextElement (internal function)
51 *
52 * gets a part of a string till the first backslash
53 *
54 * PARAMETERS
55 * pszNext [IN] string to get the element from
56 * pszOut [IN] pointer to buffer whitch receives string
57 * dwOut [IN] length of pszOut
58 *
59 * RETURNS
60 * LPSTR pointer to first, not yet parsed char
61 */
62
63static LPCWSTR GetNextElementW(LPCWSTR pszNext,LPWSTR pszOut,DWORD dwOut)
64{ LPCWSTR pszTail = pszNext;
65 DWORD dwCopy;
66 TRACE("(%s %p 0x%08lx)\n",debugstr_w(pszNext),pszOut,dwOut);
67
68 *pszOut=0x0000;
69
70 if(!pszNext || !*pszNext)
71 return NULL;
72
73 while(*pszTail && (*pszTail != (WCHAR)'\\'))
74 pszTail++;
75
76 dwCopy = (WCHAR*)pszTail - (WCHAR*)pszNext + 1;
77 lstrcpynW(pszOut, pszNext, (dwOut<dwCopy)? dwOut : dwCopy);
78
79 if(*pszTail)
80 pszTail++;
81 else
82 pszTail = NULL;
83
84 TRACE("--(%s %s 0x%08lx %p)\n",debugstr_w(pszNext),debugstr_w(pszOut),dwOut,pszTail);
85 return pszTail;
86}
87
88static HRESULT SHELL32_ParseNextElement(
89 HWND hwndOwner,
90 IShellFolder2 * psf,
91 LPITEMIDLIST * pidlInOut,
92 LPOLESTR szNext,
93 DWORD *pEaten,
94 DWORD *pdwAttributes)
95{
96 HRESULT hr = E_OUTOFMEMORY;
97 LPITEMIDLIST pidlOut, pidlTemp = NULL;
98 IShellFolder *psfChild;
99
100 TRACE("(%p %p %s)\n",psf, pidlInOut? *pidlInOut: NULL, debugstr_w(szNext));
101
102
103 /* get the shellfolder for the child pidl and let it analyse further */
104 hr = IShellFolder_BindToObject(psf, *pidlInOut, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
105
106 if (psfChild)
107 {
108 hr = IShellFolder_ParseDisplayName(psfChild, hwndOwner, NULL, szNext, pEaten, &pidlOut, pdwAttributes);
109 IShellFolder_Release(psfChild);
110
111 pidlTemp = ILCombine(*pidlInOut, pidlOut);
112
113 if (pidlOut)
114 ILFree(pidlOut);
115 }
116
117 ILFree(*pidlInOut);
118 *pidlInOut = pidlTemp;
119
120 TRACE("-- pidl=%p ret=0x%08lx\n", pidlInOut? *pidlInOut: NULL, hr);
121 return hr;
122}
123
124/***********************************************************************
125 * SHELL32_CoCreateInitSF
126 *
127 * creates a initialized shell folder
128 */
129static HRESULT SHELL32_CoCreateInitSF (
130 LPITEMIDLIST pidlRoot,
131 LPITEMIDLIST pidlChild,
132 REFCLSID clsid,
133 REFIID iid,
134 LPVOID * ppvOut)
135{
136 HRESULT hr;
137 LPITEMIDLIST absPidl;
138 IShellFolder2 *pShellFolder;
139 IPersistFolder *pPersistFolder;
140
141 TRACE("%p %p\n", pidlRoot, pidlChild);
142
143 *ppvOut = NULL;
144
145 /* we have to ask first for IPersistFolder, some special folders are expecting this */
146 hr = SHCoCreateInstance(NULL, clsid, NULL, &IID_IPersistFolder, (LPVOID*)&pPersistFolder);
147 if (SUCCEEDED(hr))
148 {
149 hr = IPersistFolder_QueryInterface(pPersistFolder, iid, (LPVOID*)&pShellFolder);
150 if (SUCCEEDED(hr))
151 {
152 absPidl = ILCombine (pidlRoot, pidlChild);
153 hr = IPersistFolder_Initialize(pPersistFolder, absPidl);
154 IPersistFolder_Release(pPersistFolder);
155 SHFree(absPidl);
156 *ppvOut = pShellFolder;
157 }
158 }
159
160 TRACE("-- ret=0x%08lx\n", hr);
161 return hr;
162}
163
164static HRESULT SHELL32_GetDisplayNameOfChild(
165 IShellFolder2 * psf,
166 LPCITEMIDLIST pidl,
167 DWORD dwFlags,
168 LPSTR szOut,
169 DWORD dwOutLen)
170{
171 LPITEMIDLIST pidlFirst, pidlNext;
172 IShellFolder2 * psfChild;
173 HRESULT hr = E_OUTOFMEMORY;
174 STRRET strTemp;
175
176 TRACE("(%p)->(pidl=%p 0x%08lx %p 0x%08lx)\n",psf,pidl,dwFlags,szOut, dwOutLen);
177 pdump(pidl);
178
179 pidlFirst = ILCloneFirst(pidl);
180 if (pidlFirst)
181 {
182 hr = IShellFolder_BindToObject(psf, pidlFirst, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
183 if (SUCCEEDED(hr))
184 {
185 pidlNext = ILGetNext(pidl);
186
187 hr = IShellFolder_GetDisplayNameOf(psfChild, pidlNext, dwFlags | SHGDN_INFOLDER, &strTemp);
188 if (SUCCEEDED(hr))
189 {
190 hr = StrRetToStrNA(szOut, dwOutLen, &strTemp, pidlNext);
191 }
192
193 IShellFolder_Release(psfChild);
194 }
195 ILFree(pidlFirst);
196 }
197
198 TRACE("-- ret=0x%08lx %s\n", hr, szOut);
199
200 return hr;
201}
202
203/***********************************************************************
204* IShellFolder implementation
205*/
206
207typedef struct
208{
209 ICOM_VTABLE(IShellFolder2)* lpvtbl;
210 DWORD ref;
211
212 ICOM_VTABLE(IPersistFolder)* lpvtblPersistFolder;
213 ICOM_VTABLE(IDropTarget)* lpvtblDropTarget;
214
215 CLSID* pclsid;
216
217 LPSTR sMyPath;
218 LPITEMIDLIST absPidl; /* complete pidl */
219
220 UINT cfShellIDList; /* clipboardformat for IDropTarget */
221 BOOL fAcceptFmt; /* flag for pending Drop */
222} IGenericSFImpl;
223
224extern struct ICOM_VTABLE(IShellFolder2) sfvt;
225extern struct ICOM_VTABLE(IPersistFolder) psfvt;
226extern struct ICOM_VTABLE(IDropTarget) dt2vt;
227
228static IShellFolder * ISF_MyComputer_Constructor(void);
229
230#define _IPersistFolder_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder)))
231#define _ICOM_THIS_From_IPersistFolder(class, name) class* This = (class*)(((char*)name)-_IPersistFolder_Offset);
232
233#define _IDropTarget_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblDropTarget)))
234#define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
235
236static shvheader GenericSFHeader [] =
237{
238 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
239 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
240 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
241 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
242 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
243};
244#define GENERICSHELLVIEWCOLUMNS 5
245
246/**************************************************************************
247* registers clipboardformat once
248*/
249static void SF_RegisterClipFmt (IShellFolder2 * iface)
250{
251 ICOM_THIS(IGenericSFImpl, iface);
252
253 TRACE("(%p)\n", This);
254
255 if (!This->cfShellIDList)
256 {
257 This->cfShellIDList = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
258 }
259}
260
261/**************************************************************************
262* IShellFolder_Constructor
263*
264*/
265
266static IShellFolder * IShellFolder_Constructor(
267 IShellFolder * psf,
268 LPITEMIDLIST pidl)
269{
270 IGenericSFImpl * sf;
271 IGenericSFImpl * sfParent = (IGenericSFImpl*) psf;
272 DWORD dwSize=0;
273
274 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
275 sf->ref=1;
276
277 sf->lpvtbl=&sfvt;
278 sf->lpvtblPersistFolder=&psfvt;
279 sf->lpvtblDropTarget=&dt2vt;
280 sf->pclsid = (CLSID*)&CLSID_SFFile;
281 sf->cfShellIDList=0;
282 sf->fAcceptFmt=FALSE;
283
284 TRACE("(%p)->(parent=%p, pidl=%p)\n",sf,sfParent, pidl);
285 pdump(pidl);
286
287 if(pidl) /* do we have a pidl? */
288 {
289 int len;
290
291 sf->absPidl = ILCombine(sfParent->absPidl, pidl); /* build a absolute pidl */
292
293 if (!_ILIsSpecialFolder(pidl)) /* only file system paths */
294 {
295 if(sfParent->sMyPath) /* get the size of the parents path */
296 {
297 dwSize += strlen(sfParent->sMyPath) ;
298 TRACE("-- (%p)->(parent's path=%s)\n",sf, debugstr_a(sfParent->sMyPath));
299 }
300
301 dwSize += _ILSimpleGetText(pidl,NULL,0); /* add the size of our name*/
302 sf->sMyPath = (char*)SHAlloc(dwSize + 2); /* '\0' and backslash */
303
304 if(!sf->sMyPath) return NULL;
305 *(sf->sMyPath)=0x00;
306
307 if(sfParent->sMyPath) /* if the parent has a path, get it*/
308 {
309 strcpy(sf->sMyPath, sfParent->sMyPath);
310 PathAddBackslashA (sf->sMyPath);
311 }
312
313 len = strlen(sf->sMyPath);
314 _ILSimpleGetText(pidl, sf->sMyPath + len, dwSize - len + 1);
315 }
316
317 TRACE("-- (%p)->(my pidl=%p, my path=%s)\n",sf, sf->absPidl,debugstr_a(sf->sMyPath));
318
319 pdump (sf->absPidl);
320 }
321
322 shell32_ObjCount++;
323 return (IShellFolder *)sf;
324}
325/**************************************************************************
326 * IShellFolder_fnQueryInterface
327 *
328 * PARAMETERS
329 * REFIID riid [in ] Requested InterfaceID
330 * LPVOID* ppvObject [out] Interface* to hold the result
331 */
332static HRESULT WINAPI IShellFolder_fnQueryInterface(
333 IShellFolder2 * iface,
334 REFIID riid,
335 LPVOID *ppvObj)
336{
337 ICOM_THIS(IGenericSFImpl, iface);
338
339 char xriid[50];
340 WINE_StringFromCLSID((LPCLSID)riid,xriid);
341 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,xriid,ppvObj);
342
343 *ppvObj = NULL;
344
345 if(IsEqualIID(riid, &IID_IUnknown))
346 { *ppvObj = This;
347 }
348 else if(IsEqualIID(riid, &IID_IShellFolder))
349 {
350 *ppvObj = (IShellFolder*)This;
351 }
352 else if(IsEqualIID(riid, &IID_IShellFolder2))
353 {
354 *ppvObj = (IShellFolder2*)This;
355 }
356 else if(IsEqualIID(riid, &IID_IPersist))
357 {
358 *ppvObj = (IPersistFolder*)&(This->lpvtblPersistFolder);
359 }
360 else if(IsEqualIID(riid, &IID_IPersistFolder))
361 {
362 *ppvObj = (IPersistFolder*)&(This->lpvtblPersistFolder);
363 }
364 else if(IsEqualIID(riid, &IID_IDropTarget))
365 {
366 *ppvObj = (IDropTarget*)&(This->lpvtblDropTarget);
367 SF_RegisterClipFmt((IShellFolder2*)This);
368 }
369
370 if(*ppvObj)
371 {
372 IUnknown_AddRef((IUnknown*)(*ppvObj));
373 TRACE("-- Interface = %p\n", *ppvObj);
374 return S_OK;
375 }
376 TRACE("-- Interface: E_NOINTERFACE\n");
377 return E_NOINTERFACE;
378}
379
380/**************************************************************************
381* IShellFolder_AddRef
382*/
383
384static ULONG WINAPI IShellFolder_fnAddRef(IShellFolder2 * iface)
385{
386 ICOM_THIS(IGenericSFImpl, iface);
387
388#ifdef MEM_DEBUG
389 TRACE("called from: 0x%08x\n", *( ((UINT*)&iface)-1 ));
390#endif
391 TRACE("(%p)->(count=%lu)\n",This,This->ref);
392
393 shell32_ObjCount++;
394 return ++(This->ref);
395}
396
397/**************************************************************************
398 * IShellFolder_fnRelease
399 */
400static ULONG WINAPI IShellFolder_fnRelease(IShellFolder2 * iface)
401{
402 ICOM_THIS(IGenericSFImpl, iface);
403
404#ifdef MEM_DEBUG
405 TRACE("called from: 0x%08x\n", *( ((UINT*)&iface)-1 ));
406#endif
407 TRACE("(%p)->(count=%lu)\n",This,This->ref);
408
409 shell32_ObjCount--;
410 if (!--(This->ref))
411 { TRACE("-- destroying IShellFolder(%p)\n",This);
412
413 if (pdesktopfolder == (IShellFolder*)iface)
414 { pdesktopfolder=NULL;
415 TRACE("-- destroyed IShellFolder(%p) was Desktopfolder\n",This);
416 }
417 if(This->absPidl)
418 { SHFree(This->absPidl);
419 }
420 if(This->sMyPath)
421 { SHFree(This->sMyPath);
422 }
423
424 HeapFree(GetProcessHeap(),0,This);
425
426 return 0;
427 }
428 return This->ref;
429}
430/**************************************************************************
431* IShellFolder_fnParseDisplayName
432* PARAMETERS
433* HWND hwndOwner, //[in ] Parent window for any message's
434* LPBC pbc, //[in ] reserved
435* LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname.
436* ULONG* pchEaten, //[out] (unicode) characters processed
437* LPITEMIDLIST* ppidl, //[out] complex pidl to item
438* ULONG* pdwAttributes //[out] items attributes
439*
440* NOTES
441* every folder trys to parse only it's own (the leftmost) pidl and creates a
442* subfolder to evaluate the remaining parts
443* now we can parse into namespaces implemented by shell extensions
444*
445* behaviour on win98: lpszDisplayName=NULL -> chrash
446* lpszDisplayName="" -> returns mycoputer-pidl
447*
448* FIXME:
449* pdwAttributes: not set
450* pchEaten: not set like in windows
451*/
452static HRESULT WINAPI IShellFolder_fnParseDisplayName(
453 IShellFolder2 * iface,
454 HWND hwndOwner,
455 LPBC pbcReserved,
456 LPOLESTR lpszDisplayName,
457 DWORD *pchEaten,
458 LPITEMIDLIST *ppidl,
459 DWORD *pdwAttributes)
460{
461 ICOM_THIS(IGenericSFImpl, iface);
462
463 HRESULT hr = E_OUTOFMEMORY;
464 LPCWSTR szNext=NULL;
465 WCHAR szElement[MAX_PATH];
466 CHAR szTempA[MAX_PATH], szPath[MAX_PATH];
467 LPITEMIDLIST pidlTemp=NULL;
468
469 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
470 This,hwndOwner,pbcReserved,lpszDisplayName,
471 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
472
473 if (!lpszDisplayName || !ppidl) return E_INVALIDARG;
474
475 if (pchEaten) *pchEaten = 0; /* strange but like the original */
476
477 if (*lpszDisplayName)
478 {
479 /* get the next element */
480 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
481
482 /* build the full pathname to the element */
483 WideCharToLocal(szTempA, szElement, lstrlenW(szElement) + 1);
484 strcpy(szPath, This->sMyPath);
485 PathAddBackslashA(szPath);
486 strcat(szPath, szTempA);
487
488 /* get the pidl */
489 pidlTemp = SHSimpleIDListFromPathA(szPath);
490
491 if (pidlTemp)
492 {
493 /* try to analyse the next element */
494 if (szNext && *szNext)
495 {
496 hr = SHELL32_ParseNextElement(hwndOwner, (IShellFolder2*)This, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
497 }
498 else
499 {
500 hr = S_OK;
501 }
502 }
503 }
504
505 *ppidl = pidlTemp;
506
507 TRACE("(%p)->(-- pidl=%p ret=0x%08lx)\n", This, ppidl? *ppidl:0, hr);
508
509 return hr;
510}
511
512/**************************************************************************
513* IShellFolder_fnEnumObjects
514* PARAMETERS
515* HWND hwndOwner, //[in ] Parent Window
516* DWORD grfFlags, //[in ] SHCONTF enumeration mask
517* LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface
518*/
519static HRESULT WINAPI IShellFolder_fnEnumObjects(
520 IShellFolder2 * iface,
521 HWND hwndOwner,
522 DWORD dwFlags,
523 LPENUMIDLIST* ppEnumIDList)
524{
525 ICOM_THIS(IGenericSFImpl, iface);
526
527 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
528
529 *ppEnumIDList = NULL;
530 *ppEnumIDList = IEnumIDList_Constructor (This->sMyPath, dwFlags, EIDL_FILE);
531
532 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
533
534 if(!*ppEnumIDList) return E_OUTOFMEMORY;
535
536 return S_OK;
537}
538
539/**************************************************************************
540* IShellFolder_fnBindToObject
541* PARAMETERS
542* LPCITEMIDLIST pidl, //[in ] relative pidl to open
543* LPBC pbc, //[in ] reserved
544* REFIID riid, //[in ] Initial Interface
545* LPVOID* ppvObject //[out] Interface*
546*/
547static HRESULT WINAPI IShellFolder_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
548 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
549{
550 ICOM_THIS(IGenericSFImpl, iface);
551 GUID const * iid;
552 char xriid[50];
553 IShellFolder *pShellFolder, *pSubFolder;
554 IPersistFolder *pPersistFolder;
555 LPITEMIDLIST absPidl;
556
557 WINE_StringFromCLSID(riid,xriid);
558
559 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This,pidl,pbcReserved,xriid,ppvOut);
560
561 if(!pidl || !ppvOut) return E_INVALIDARG;
562
563 *ppvOut = NULL;
564
565 iid = _ILGetGUIDPointer(pidl);
566 if (iid)
567 {
568 /* we have to create a alien folder */
569 if ( SUCCEEDED(SHCoCreateInstance(NULL, iid, NULL, riid, (LPVOID*)&pShellFolder))
570 && SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&pPersistFolder)))
571 {
572 absPidl = ILCombine (This->absPidl, pidl);
573 IPersistFolder_Initialize(pPersistFolder, absPidl);
574 IPersistFolder_Release(pPersistFolder);
575 SHFree(absPidl);
576 }
577 else
578 {
579 return E_FAIL;
580 }
581 }
582 else
583 {
584 LPITEMIDLIST pidltemp = ILCloneFirst(pidl);
585 pShellFolder = IShellFolder_Constructor((IShellFolder*)This, pidltemp);
586 ILFree(pidltemp);
587 }
588
589 if (_ILIsPidlSimple(pidl))
590 {
591 *ppvOut = pShellFolder;
592 }
593 else
594 {
595 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID*)&pSubFolder);
596 IShellFolder_Release(pShellFolder);
597 *ppvOut = pSubFolder;
598 }
599
600 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
601
602 return S_OK;
603}
604
605/**************************************************************************
606* IShellFolder_fnBindToStorage
607* PARAMETERS
608* LPCITEMIDLIST pidl, //[in ] complex pidl to store
609* LPBC pbc, //[in ] reserved
610* REFIID riid, //[in ] Initial storage interface
611* LPVOID* ppvObject //[out] Interface* returned
612*/
613static HRESULT WINAPI IShellFolder_fnBindToStorage(
614 IShellFolder2 * iface,
615 LPCITEMIDLIST pidl,
616 LPBC pbcReserved,
617 REFIID riid,
618 LPVOID *ppvOut)
619{
620 ICOM_THIS(IGenericSFImpl, iface);
621
622 char xriid[50];
623 WINE_StringFromCLSID(riid,xriid);
624
625 FIXME("(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",This,pidl,pbcReserved,xriid,ppvOut);
626
627 *ppvOut = NULL;
628 return E_NOTIMPL;
629}
630
631/**************************************************************************
632* IShellFolder_fnCompareIDs
633*
634* PARMETERS
635* LPARAM lParam, //[in ] Column?
636* LPCITEMIDLIST pidl1, //[in ] simple pidl
637* LPCITEMIDLIST pidl2) //[in ] simple pidl
638*
639* NOTES
640* Special case - If one of the items is a Path and the other is a File,
641* always make the Path come before the File.
642*
643* NOTES
644* use SCODE_CODE() on the return value to get the result
645*/
646
647static HRESULT WINAPI IShellFolder_fnCompareIDs(
648 IShellFolder2 * iface,
649 LPARAM lParam,
650 LPCITEMIDLIST pidl1,
651 LPCITEMIDLIST pidl2)
652{
653 ICOM_THIS(IGenericSFImpl, iface);
654
655 CHAR szTemp1[MAX_PATH];
656 CHAR szTemp2[MAX_PATH];
657 int nReturn;
658 IShellFolder * psf;
659 HRESULT hr = E_OUTOFMEMORY;
660 LPCITEMIDLIST pidlTemp;
661 PIDLTYPE pt1, pt2;
662
663 TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",This,lParam,pidl1,pidl2);
664 pdump (pidl1);
665 pdump (pidl2);
666
667 if (!pidl1 && !pidl2)
668 {
669 hr = ResultFromShort(0);
670 }
671 else if (!pidl1)
672 {
673 hr = ResultFromShort(-1);
674 }
675 else if (!pidl2)
676 {
677 hr = ResultFromShort(1);
678 }
679 else
680 {
681 LPPIDLDATA pd1, pd2;
682 pd1 = _ILGetDataPointer(pidl1);
683 pd2 = _ILGetDataPointer(pidl2);
684
685 /* compate the types. sort order is the PT_* constant */
686 pt1 = ( pd1 ? pd1->type: PT_DESKTOP);
687 pt2 = ( pd2 ? pd2->type: PT_DESKTOP);
688
689 if (pt1 != pt2)
690 {
691 hr = ResultFromShort(pt1-pt2);
692 }
693 else /* same type of pidl */
694 {
695 _ILSimpleGetText(pidl1, szTemp1, MAX_PATH);
696 _ILSimpleGetText(pidl2, szTemp2, MAX_PATH);
697 nReturn = strcmp(szTemp1, szTemp2);
698
699 if (nReturn == 0) /* first pidl different ? */
700 {
701 pidl1 = ILGetNext(pidl1);
702
703 if (pidl1 && pidl1->mkid.cb) /* go deeper? */
704 {
705 pidlTemp = ILCloneFirst(pidl1);
706 pidl2 = ILGetNext(pidl2);
707
708 hr = IShellFolder_BindToObject((IShellFolder*)This, pidlTemp, NULL, &IID_IShellFolder, (LPVOID*)&psf);
709 if (SUCCEEDED(hr))
710 {
711 nReturn = IShellFolder_CompareIDs(psf, 0, pidl1, pidl2);
712 IShellFolder_Release(psf);
713 hr = ResultFromShort(nReturn);
714 }
715 ILFree(pidlTemp);
716 }
717 else
718 {
719 hr = ResultFromShort(nReturn); /* two equal simple pidls */
720 }
721 }
722 else
723 {
724 hr = ResultFromShort(nReturn); /* two different simple pidls */
725 }
726 }
727 }
728
729 TRACE("-- res=0x%08lx\n", hr);
730 return hr;
731}
732
733/**************************************************************************
734* IShellFolder_fnCreateViewObject
735*/
736static HRESULT WINAPI IShellFolder_fnCreateViewObject( IShellFolder2 * iface,
737 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
738{
739 ICOM_THIS(IGenericSFImpl, iface);
740
741 LPSHELLVIEW pShellView;
742 char xriid[50];
743 HRESULT hr = E_INVALIDARG;
744
745 WINE_StringFromCLSID(riid,xriid);
746 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,xriid,ppvOut);
747
748 if(ppvOut)
749 {
750 *ppvOut = NULL;
751
752 if(IsEqualIID(riid, &IID_IDropTarget))
753 {
754 hr = IShellFolder_QueryInterface((IShellFolder*)This, &IID_IDropTarget, ppvOut);
755 }
756 else if(IsEqualIID(riid, &IID_IContextMenu))
757 {
758 FIXME("IContextMenu not implemented\n");
759 hr = E_NOTIMPL;
760 }
761 else if(IsEqualIID(riid, &IID_IShellView))
762 {
763 pShellView = IShellView_Constructor((IShellFolder *) This);
764 if(pShellView)
765 {
766 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
767 IShellView_Release(pShellView);
768 }
769 }
770 }
771 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
772 return hr;
773}
774
775/**************************************************************************
776* IShellFolder_fnGetAttributesOf
777*
778* PARAMETERS
779* UINT cidl, //[in ] num elements in pidl array
780* LPCITEMIDLIST* apidl, //[in ] simple pidl array
781* ULONG* rgfInOut) //[out] result array
782*
783*/
784static HRESULT WINAPI IShellFolder_fnGetAttributesOf(IShellFolder2 * iface,UINT cidl,LPCITEMIDLIST *apidl,DWORD *rgfInOut)
785{
786 ICOM_THIS(IGenericSFImpl, iface);
787
788 HRESULT hr = S_OK;
789
790 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
791
792 if ( (!cidl) || (!apidl) || (!rgfInOut))
793 return E_INVALIDARG;
794
795 while (cidl > 0 && *apidl)
796 {
797 pdump (*apidl);
798 if (_ILIsFolder( *apidl))
799 {
800 *rgfInOut &= 0xe0000177;
801 goto next;
802 }
803 else if (_ILIsValue( *apidl))
804 {
805 *rgfInOut &= 0x40000177;
806 goto next;
807 }
808 hr = E_INVALIDARG;
809
810next: apidl++;
811 cidl--;
812 }
813
814 TRACE("-- result=0x%08lx\n",*rgfInOut);
815
816 return hr;
817}
818/**************************************************************************
819* IShellFolder_fnGetUIObjectOf
820*
821* PARAMETERS
822* HWND hwndOwner, //[in ] Parent window for any output
823* UINT cidl, //[in ] array size
824* LPCITEMIDLIST* apidl, //[in ] simple pidl array
825* REFIID riid, //[in ] Requested Interface
826* UINT* prgfInOut, //[ ] reserved
827* LPVOID* ppvObject) //[out] Resulting Interface
828*
829* NOTES
830* This function gets asked to return "view objects" for one or more (multiple select)
831* items:
832* The viewobject typically is an COM object with one of the following interfaces:
833* IExtractIcon,IDataObject,IContextMenu
834* In order to support icon positions in the default Listview your DataObject
835* must implement the SetData method (in addition to GetData :) - the shell passes
836* a barely documented "Icon positions" structure to SetData when the drag starts,
837* and GetData's it if the drop is in another explorer window that needs the positions.
838*/
839static HRESULT WINAPI IShellFolder_fnGetUIObjectOf(
840 IShellFolder2 * iface,
841 HWND hwndOwner,
842 UINT cidl,
843 LPCITEMIDLIST * apidl,
844 REFIID riid,
845 UINT * prgfInOut,
846 LPVOID * ppvOut)
847{
848 ICOM_THIS(IGenericSFImpl, iface);
849
850 char xclsid[50];
851 LPITEMIDLIST pidl;
852 IUnknown* pObj = NULL;
853 HRESULT hr = E_INVALIDARG;
854
855 WINE_StringFromCLSID(riid,xclsid);
856
857 TRACE("(%p)->(%u,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
858 This,hwndOwner,cidl,apidl,xclsid,prgfInOut,ppvOut);
859
860 if (ppvOut)
861 {
862 *ppvOut = NULL;
863
864 if(IsEqualIID(riid, &IID_IContextMenu) && (cidl >= 1))
865 {
866 pObj = (LPUNKNOWN)IContextMenu_Constructor((IShellFolder *)This, This->absPidl, apidl, cidl);
867 hr = S_OK;
868 }
869 else if (IsEqualIID(riid, &IID_IDataObject) &&(cidl >= 1))
870 {
871 pObj = (LPUNKNOWN)IDataObject_Constructor (hwndOwner, This->absPidl, apidl, cidl);
872 hr = S_OK;
873 }
874 else if (IsEqualIID(riid, &IID_IExtractIconA) && (cidl == 1))
875 {
876 pidl = ILCombine(This->absPidl,apidl[0]);
877 pObj = (LPUNKNOWN)IExtractIconA_Constructor( pidl );
878 SHFree(pidl);
879 hr = S_OK;
880 }
881 else if (IsEqualIID(riid, &IID_IDropTarget) && (cidl >= 1))
882 {
883 hr = IShellFolder_QueryInterface((IShellFolder*)This, &IID_IDropTarget, (LPVOID*)&pObj);
884 }
885 else
886 {
887 hr = E_NOINTERFACE;
888 }
889
890 if(!pObj)
891 hr = E_OUTOFMEMORY;
892
893 *ppvOut = pObj;
894 }
895 TRACE("(%p)->hr=0x%08lx\n",This, hr);
896 return hr;
897}
898
899/**************************************************************************
900* IShellFolder_fnGetDisplayNameOf
901* Retrieves the display name for the specified file object or subfolder
902*
903* PARAMETERS
904* LPCITEMIDLIST pidl, //[in ] complex pidl to item
905* DWORD dwFlags, //[in ] SHGNO formatting flags
906* LPSTRRET lpName) //[out] Returned display name
907*
908* FIXME
909* if the name is in the pidl the ret value should be a STRRET_OFFSET
910*/
911#define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
912#define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
913
914static HRESULT WINAPI IShellFolder_fnGetDisplayNameOf(
915 IShellFolder2 * iface,
916 LPCITEMIDLIST pidl,
917 DWORD dwFlags,
918 LPSTRRET strRet)
919{
920 ICOM_THIS(IGenericSFImpl, iface);
921
922 CHAR szPath[MAX_PATH]= "";
923 int len = 0;
924 BOOL bSimplePidl;
925
926 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
927 pdump(pidl);
928
929 if(!pidl || !strRet) return E_INVALIDARG;
930
931 bSimplePidl = _ILIsPidlSimple(pidl);
932
933 /* take names of special folders only if its only this folder */
934 if (_ILIsSpecialFolder(pidl))
935 {
936 if ( bSimplePidl)
937 {
938 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
939 }
940 }
941 else
942 {
943 if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) && This->sMyPath)
944 {
945 strcpy (szPath, This->sMyPath); /* get path to root*/
946 PathAddBackslashA(szPath);
947 len = strlen(szPath);
948 }
949 _ILSimpleGetText(pidl, szPath + len, MAX_PATH - len); /* append my own path */
950 }
951
952 if ( (dwFlags & SHGDN_FORPARSING) && !bSimplePidl) /* go deeper if needed */
953 {
954 PathAddBackslashA(szPath);
955 len = strlen(szPath);
956
957 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild((IShellFolder2*)This, pidl, dwFlags, szPath + len, MAX_PATH - len)))
958 return E_OUTOFMEMORY;
959 }
960 strRet->uType = STRRET_CSTRA;
961 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
962
963 TRACE("-- (%p)->(%s)\n", This, szPath);
964 return S_OK;
965}
966
967/**************************************************************************
968* IShellFolder_fnSetNameOf
969* Changes the name of a file object or subfolder, possibly changing its item
970* identifier in the process.
971*
972* PARAMETERS
973* HWND hwndOwner, //[in ] Owner window for output
974* LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
975* LPCOLESTR lpszName, //[in ] the items new display name
976* DWORD dwFlags, //[in ] SHGNO formatting flags
977* LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
978*/
979static HRESULT WINAPI IShellFolder_fnSetNameOf(
980 IShellFolder2 * iface,
981 HWND hwndOwner,
982 LPCITEMIDLIST pidl, /*simple pidl*/
983 LPCOLESTR lpName,
984 DWORD dw,
985 LPITEMIDLIST *pPidlOut)
986{
987 ICOM_THIS(IGenericSFImpl, iface);
988
989 FIXME("(%p)->(%u,pidl=%p,%s,%lu,%p),stub!\n",
990 This,hwndOwner,pidl,debugstr_w(lpName),dw,pPidlOut);
991
992 return E_NOTIMPL;
993}
994
995/**************************************************************************
996* IShellFolder_fnGetFolderPath
997*/
998static HRESULT WINAPI IShellFolder_fnGetFolderPath(IShellFolder2 * iface, LPSTR lpszOut, DWORD dwOutSize)
999{
1000 ICOM_THIS(IGenericSFImpl, iface);
1001
1002 TRACE("(%p)->(%p %lu)\n",This, lpszOut, dwOutSize);
1003
1004 if (!lpszOut) return FALSE;
1005
1006 *lpszOut=0;
1007
1008 if (! This->sMyPath) return FALSE;
1009
1010 lstrcpynA(lpszOut, This->sMyPath, dwOutSize);
1011
1012 TRACE("-- (%p)->(return=%s)\n",This, lpszOut);
1013 return TRUE;
1014}
1015
1016static HRESULT WINAPI IShellFolder_fnGetDefaultSearchGUID(
1017 IShellFolder2 * iface,
1018 GUID *pguid)
1019{
1020 ICOM_THIS(IGenericSFImpl, iface);
1021 TRACE("(%p)\n",This);
1022 return E_NOTIMPL;
1023}
1024static HRESULT WINAPI IShellFolder_fnEnumSearches(
1025 IShellFolder2 * iface,
1026 IEnumExtraSearch **ppenum)
1027{
1028 ICOM_THIS(IGenericSFImpl, iface);
1029 TRACE("(%p)\n",This);
1030 return E_NOTIMPL;
1031}
1032static HRESULT WINAPI IShellFolder_fnGetDefaultColumn(
1033 IShellFolder2 * iface,
1034 DWORD dwRes,
1035 ULONG *pSort,
1036 ULONG *pDisplay)
1037{
1038 ICOM_THIS(IGenericSFImpl, iface);
1039
1040 TRACE("(%p)\n",This);
1041
1042 if (pSort) *pSort = 0;
1043 if (pDisplay) *pDisplay = 0;
1044
1045 return S_OK;
1046}
1047static HRESULT WINAPI IShellFolder_fnGetDefaultColumnState(
1048 IShellFolder2 * iface,
1049 UINT iColumn,
1050 DWORD *pcsFlags)
1051{
1052 ICOM_THIS(IGenericSFImpl, iface);
1053
1054 TRACE("(%p)\n",This);
1055
1056 if (!pcsFlags || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1057
1058 *pcsFlags = GenericSFHeader[iColumn].pcsFlags;
1059
1060 return S_OK;
1061}
1062static HRESULT WINAPI IShellFolder_fnGetDetailsEx(
1063 IShellFolder2 * iface,
1064 LPCITEMIDLIST pidl,
1065 const SHCOLUMNID *pscid,
1066 VARIANT *pv)
1067{
1068 ICOM_THIS(IGenericSFImpl, iface);
1069 TRACE("(%p)\n",This);
1070 return E_NOTIMPL;
1071}
1072static HRESULT WINAPI IShellFolder_fnGetDetailsOf(
1073 IShellFolder2 * iface,
1074 LPCITEMIDLIST pidl,
1075 UINT iColumn,
1076 SHELLDETAILS *psd)
1077{
1078 ICOM_THIS(IGenericSFImpl, iface);
1079 HRESULT hr = E_FAIL;
1080
1081 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
1082
1083 if (!psd || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1084
1085 if (!pidl)
1086 {
1087 /* the header titles */
1088 psd->fmt = GenericSFHeader[iColumn].fmt;
1089 psd->cxChar = GenericSFHeader[iColumn].cxChar;
1090 psd->str.uType = STRRET_CSTRA;
1091 LoadStringA(shell32_hInstance, GenericSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
1092 return S_OK;
1093 }
1094 else
1095 {
1096 /* the data from the pidl */
1097 switch(iColumn)
1098 {
1099 case 0: /* name */
1100 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
1101 break;
1102 case 1: /* size */
1103 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
1104 break;
1105 case 2: /* type */
1106 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
1107 break;
1108 case 3: /* date */
1109 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
1110 break;
1111 case 4: /* attributes */
1112 _ILGetAttributeStr(pidl, psd->str.u.cStr, MAX_PATH);
1113 break;
1114 }
1115 hr = S_OK;
1116 psd->str.uType = STRRET_CSTRA;
1117 }
1118
1119 return hr;
1120}
1121static HRESULT WINAPI IShellFolder_fnMapNameToSCID(
1122 IShellFolder2 * iface,
1123 LPCWSTR pwszName,
1124 SHCOLUMNID *pscid)
1125{
1126 ICOM_THIS(IGenericSFImpl, iface);
1127 TRACE("(%p)\n",This);
1128 return E_NOTIMPL;
1129}
1130
1131
1132
1133ICOM_VTABLE(IShellFolder2) sfvt =
1134{
1135 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1136 IShellFolder_fnQueryInterface,
1137 IShellFolder_fnAddRef,
1138 IShellFolder_fnRelease,
1139 IShellFolder_fnParseDisplayName,
1140 IShellFolder_fnEnumObjects,
1141 IShellFolder_fnBindToObject,
1142 IShellFolder_fnBindToStorage,
1143 IShellFolder_fnCompareIDs,
1144 IShellFolder_fnCreateViewObject,
1145 IShellFolder_fnGetAttributesOf,
1146 IShellFolder_fnGetUIObjectOf,
1147 IShellFolder_fnGetDisplayNameOf,
1148 IShellFolder_fnSetNameOf,
1149
1150 /* ShellFolder2 */
1151 IShellFolder_fnGetDefaultSearchGUID,
1152 IShellFolder_fnEnumSearches,
1153 IShellFolder_fnGetDefaultColumn,
1154 IShellFolder_fnGetDefaultColumnState,
1155 IShellFolder_fnGetDetailsEx,
1156 IShellFolder_fnGetDetailsOf,
1157 IShellFolder_fnMapNameToSCID
1158};
1159
1160/***********************************************************************
1161* [Desktopfolder] IShellFolder implementation
1162*/
1163extern struct ICOM_VTABLE(IShellFolder2) sfdvt;
1164
1165static shvheader DesktopSFHeader [] =
1166{
1167 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
1168 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1169 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1170 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
1171 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
1172};
1173#define DESKTOPSHELLVIEWCOLUMNS 5
1174
1175/**************************************************************************
1176* ISF_Desktop_Constructor
1177*
1178*/
1179IShellFolder * ISF_Desktop_Constructor()
1180{
1181 IGenericSFImpl * sf;
1182
1183 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
1184 sf->ref=1;
1185 sf->lpvtbl=&sfdvt;
1186 sf->absPidl=_ILCreateDesktop(); /* my qualified pidl */
1187
1188 TRACE("(%p)\n",sf);
1189
1190 shell32_ObjCount++;
1191 return (IShellFolder *)sf;
1192}
1193
1194/**************************************************************************
1195 * ISF_Desktop_fnQueryInterface
1196 *
1197 * NOTES supports not IPersist/IPersistFolder
1198 */
1199static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
1200 IShellFolder2 * iface,
1201 REFIID riid,
1202 LPVOID *ppvObj)
1203{
1204 ICOM_THIS(IGenericSFImpl, iface);
1205
1206 char xriid[50];
1207 WINE_StringFromCLSID((LPCLSID)riid,xriid);
1208 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,xriid,ppvObj);
1209
1210 *ppvObj = NULL;
1211
1212 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
1213 { *ppvObj = This;
1214 }
1215 else if(IsEqualIID(riid, &IID_IShellFolder)) /*IShellFolder*/
1216 { *ppvObj = (IShellFolder*)This;
1217 }
1218 else if(IsEqualIID(riid, &IID_IShellFolder2)) /*IShellFolder2*/
1219 { *ppvObj = (IShellFolder2*)This;
1220 }
1221
1222 if(*ppvObj)
1223 {
1224 IUnknown_AddRef((IUnknown*)(*ppvObj));
1225 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1226 return S_OK;
1227 }
1228 TRACE("-- Interface: E_NOINTERFACE\n");
1229 return E_NOINTERFACE;
1230}
1231
1232/**************************************************************************
1233* ISF_Desktop_fnParseDisplayName
1234*
1235* NOTES
1236* "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
1237* to MyComputer
1238*/
1239static HRESULT WINAPI ISF_Desktop_fnParseDisplayName(
1240 IShellFolder2 * iface,
1241 HWND hwndOwner,
1242 LPBC pbcReserved,
1243 LPOLESTR lpszDisplayName,
1244 DWORD *pchEaten,
1245 LPITEMIDLIST *ppidl,
1246 DWORD *pdwAttributes)
1247{
1248 ICOM_THIS(IGenericSFImpl, iface);
1249
1250 LPCWSTR szNext=NULL;
1251 LPITEMIDLIST pidlTemp=NULL;
1252 HRESULT hr=E_OUTOFMEMORY;
1253
1254 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1255 This,hwndOwner,pbcReserved,lpszDisplayName,
1256 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
1257
1258 *ppidl = 0;
1259 if (pchEaten) *pchEaten = 0; /* strange but like the original */
1260
1261 /* fixme no real parsing implemented */
1262 pidlTemp = _ILCreateMyComputer();
1263 szNext = lpszDisplayName;
1264
1265 if (szNext && *szNext)
1266 {
1267 hr = SHELL32_ParseNextElement(hwndOwner, (IShellFolder2*)This, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
1268 }
1269 else
1270 {
1271 hr = S_OK;
1272 }
1273
1274 *ppidl = pidlTemp;
1275
1276 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
1277
1278 return hr;
1279}
1280
1281/**************************************************************************
1282* ISF_Desktop_fnEnumObjects
1283*/
1284static HRESULT WINAPI ISF_Desktop_fnEnumObjects(
1285 IShellFolder2 * iface,
1286 HWND hwndOwner,
1287 DWORD dwFlags,
1288 LPENUMIDLIST* ppEnumIDList)
1289{
1290 ICOM_THIS(IGenericSFImpl, iface);
1291
1292 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
1293
1294 *ppEnumIDList = NULL;
1295 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_DESK);
1296
1297 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
1298
1299 if(!*ppEnumIDList) return E_OUTOFMEMORY;
1300
1301 return S_OK;
1302}
1303
1304/**************************************************************************
1305* ISF_Desktop_fnBindToObject
1306*/
1307static HRESULT WINAPI ISF_Desktop_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
1308 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
1309{
1310 ICOM_THIS(IGenericSFImpl, iface);
1311 GUID const * clsid;
1312 char xriid[50];
1313 IShellFolder *pShellFolder, *pSubFolder;
1314
1315 WINE_StringFromCLSID(riid,xriid);
1316
1317 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This,pidl,pbcReserved,xriid,ppvOut);
1318
1319 *ppvOut = NULL;
1320
1321 clsid = _ILGetGUIDPointer(pidl);
1322 if (clsid)
1323 {
1324 if ( IsEqualIID(clsid, &IID_MyComputer))
1325 {
1326 pShellFolder = ISF_MyComputer_Constructor();
1327 }
1328 else
1329 {
1330 /* shell extension */
1331 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
1332 {
1333 return E_INVALIDARG;
1334 }
1335 }
1336 }
1337 else
1338 {
1339 /* file system folder on the desktop */
1340 LPITEMIDLIST pidltemp = ILCloneFirst(pidl);
1341 pShellFolder = IShellFolder_Constructor((IShellFolder*)This, pidltemp);
1342 ILFree(pidltemp);
1343 }
1344
1345 if (_ILIsPidlSimple(pidl)) /* no sub folders */
1346 {
1347 *ppvOut = pShellFolder;
1348 }
1349 else /* go deeper */
1350 {
1351 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, riid, (LPVOID*)&pSubFolder);
1352 IShellFolder_Release(pShellFolder);
1353 *ppvOut = pSubFolder;
1354 }
1355
1356 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
1357
1358 return S_OK;
1359}
1360
1361/**************************************************************************
1362* ISF_Desktop_fnCreateViewObject
1363*/
1364static HRESULT WINAPI ISF_Desktop_fnCreateViewObject( IShellFolder2 * iface,
1365 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
1366{
1367 ICOM_THIS(IGenericSFImpl, iface);
1368
1369 LPSHELLVIEW pShellView;
1370 char xriid[50];
1371 HRESULT hr = E_INVALIDARG;
1372
1373 WINE_StringFromCLSID(riid,xriid);
1374 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,xriid,ppvOut);
1375
1376 if(ppvOut)
1377 {
1378 *ppvOut = NULL;
1379
1380 if(IsEqualIID(riid, &IID_IDropTarget))
1381 {
1382 FIXME("IDropTarget not implemented\n");
1383 hr = E_NOTIMPL;
1384 }
1385 else if(IsEqualIID(riid, &IID_IContextMenu))
1386 {
1387 FIXME("IContextMenu not implemented\n");
1388 hr = E_NOTIMPL;
1389 }
1390 else if(IsEqualIID(riid, &IID_IShellView))
1391 {
1392 pShellView = IShellView_Constructor((IShellFolder *) This);
1393 if(pShellView)
1394 {
1395 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
1396 IShellView_Release(pShellView);
1397 }
1398 }
1399 }
1400 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
1401 return hr;
1402}
1403
1404/**************************************************************************
1405* ISF_Desktop_fnGetAttributesOf
1406*/
1407static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf(IShellFolder2 * iface,UINT cidl,LPCITEMIDLIST *apidl,DWORD *rgfInOut)
1408{
1409 ICOM_THIS(IGenericSFImpl, iface);
1410
1411 GUID const * clsid;
1412 DWORD attributes;
1413 HRESULT hr = S_OK;
1414
1415 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl, *rgfInOut);
1416
1417 if ( (!cidl) || (!apidl) || (!rgfInOut))
1418 return E_INVALIDARG;
1419
1420 while (cidl > 0 && *apidl)
1421 {
1422 pdump (*apidl);
1423
1424 clsid = _ILGetGUIDPointer(*apidl);
1425 if (clsid)
1426 {
1427 if (IsEqualIID(clsid, &IID_MyComputer))
1428 {
1429 *rgfInOut &= 0xb0000154;
1430 goto next;
1431 }
1432 else if (HCR_GetFolderAttributes(clsid, &attributes))
1433 {
1434 *rgfInOut &= attributes;
1435 goto next;
1436 }
1437 else
1438 { /* some shell-extension */
1439 *rgfInOut &= 0xb0000154;
1440 }
1441 }
1442 else if (_ILIsFolder( *apidl))
1443 {
1444 *rgfInOut &= 0xe0000177;
1445 goto next;
1446 }
1447 else if (_ILIsValue( *apidl))
1448 {
1449 *rgfInOut &= 0x40000177;
1450 goto next;
1451 }
1452 hr = E_INVALIDARG;
1453
1454next: apidl++;
1455 cidl--;
1456 }
1457
1458 TRACE("-- result=0x%08lx\n",*rgfInOut);
1459
1460 return hr;
1461}
1462
1463/**************************************************************************
1464* ISF_Desktop_fnGetDisplayNameOf
1465*
1466* NOTES
1467* special case: pidl = null gives desktop-name back
1468*/
1469static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf(
1470 IShellFolder2 * iface,
1471 LPCITEMIDLIST pidl,
1472 DWORD dwFlags,
1473 LPSTRRET strRet)
1474{
1475 ICOM_THIS(IGenericSFImpl, iface);
1476
1477 CHAR szPath[MAX_PATH]= "";
1478
1479 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1480 pdump(pidl);
1481
1482 if(!strRet) return E_INVALIDARG;
1483
1484 if(!pidl)
1485 {
1486 HCR_GetClassName(&CLSID_ShellDesktop, szPath, MAX_PATH);
1487 }
1488 else if ( _ILIsPidlSimple(pidl) )
1489 {
1490 _ILSimpleGetText(pidl, szPath, MAX_PATH);
1491 }
1492 else
1493 {
1494 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild((IShellFolder2*)This, pidl, dwFlags, szPath, MAX_PATH)))
1495 return E_OUTOFMEMORY;
1496 }
1497 strRet->uType = STRRET_CSTRA;
1498 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1499
1500
1501 TRACE("-- (%p)->(%s)\n", This, szPath);
1502 return S_OK;
1503}
1504
1505static HRESULT WINAPI ISF_Desktop_fnGetDefaultSearchGUID(
1506 IShellFolder2 * iface,
1507 GUID *pguid)
1508{
1509 ICOM_THIS(IGenericSFImpl, iface);
1510 FIXME("(%p)\n",This);
1511 return E_NOTIMPL;
1512}
1513static HRESULT WINAPI ISF_Desktop_fnEnumSearches(
1514 IShellFolder2 * iface,
1515 IEnumExtraSearch **ppenum)
1516{
1517 ICOM_THIS(IGenericSFImpl, iface);
1518 FIXME("(%p)\n",This);
1519 return E_NOTIMPL;
1520}
1521static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumn(
1522 IShellFolder2 * iface,
1523 DWORD dwRes,
1524 ULONG *pSort,
1525 ULONG *pDisplay)
1526{
1527 ICOM_THIS(IGenericSFImpl, iface);
1528
1529 TRACE("(%p)\n",This);
1530
1531 if (pSort) *pSort = 0;
1532 if (pDisplay) *pDisplay = 0;
1533
1534 return S_OK;
1535}
1536static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumnState(
1537 IShellFolder2 * iface,
1538 UINT iColumn,
1539 DWORD *pcsFlags)
1540{
1541 ICOM_THIS(IGenericSFImpl, iface);
1542
1543 TRACE("(%p)\n",This);
1544
1545 if (!pcsFlags || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1546
1547 *pcsFlags = DesktopSFHeader[iColumn].pcsFlags;
1548
1549 return S_OK;
1550}
1551static HRESULT WINAPI ISF_Desktop_fnGetDetailsEx(
1552 IShellFolder2 * iface,
1553 LPCITEMIDLIST pidl,
1554 const SHCOLUMNID *pscid,
1555 VARIANT *pv)
1556{
1557 ICOM_THIS(IGenericSFImpl, iface);
1558 FIXME("(%p)\n",This);
1559
1560 return E_NOTIMPL;
1561}
1562static HRESULT WINAPI ISF_Desktop_fnGetDetailsOf(
1563 IShellFolder2 * iface,
1564 LPCITEMIDLIST pidl,
1565 UINT iColumn,
1566 SHELLDETAILS *psd)
1567{
1568 ICOM_THIS(IGenericSFImpl, iface);
1569 HRESULT hr = E_FAIL;;
1570
1571 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
1572
1573 if (!psd || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1574
1575 if (!pidl)
1576 {
1577 psd->fmt = DesktopSFHeader[iColumn].fmt;
1578 psd->cxChar = DesktopSFHeader[iColumn].cxChar;
1579 psd->str.uType = STRRET_CSTRA;
1580 LoadStringA(shell32_hInstance, DesktopSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
1581 return S_OK;
1582 }
1583 else
1584 {
1585 /* the data from the pidl */
1586 switch(iColumn)
1587 {
1588 case 0: /* name */
1589 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
1590 break;
1591 case 1: /* size */
1592 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
1593 break;
1594 case 2: /* type */
1595 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
1596 break;
1597 case 3: /* date */
1598 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
1599 break;
1600 case 4: /* attributes */
1601 _ILGetAttributeStr(pidl, psd->str.u.cStr, MAX_PATH);
1602 break;
1603 }
1604 hr = S_OK;
1605 psd->str.uType = STRRET_CSTRA;
1606 }
1607
1608 return hr;
1609}
1610static HRESULT WINAPI ISF_Desktop_fnMapNameToSCID(
1611 IShellFolder2 * iface,
1612 LPCWSTR pwszName,
1613 SHCOLUMNID *pscid)
1614{
1615 ICOM_THIS(IGenericSFImpl, iface);
1616 FIXME("(%p)\n",This);
1617 return E_NOTIMPL;
1618}
1619
1620ICOM_VTABLE(IShellFolder2) sfdvt =
1621{
1622 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1623 ISF_Desktop_fnQueryInterface,
1624 IShellFolder_fnAddRef,
1625 IShellFolder_fnRelease,
1626 ISF_Desktop_fnParseDisplayName,
1627 ISF_Desktop_fnEnumObjects,
1628 ISF_Desktop_fnBindToObject,
1629 IShellFolder_fnBindToStorage,
1630 IShellFolder_fnCompareIDs,
1631 ISF_Desktop_fnCreateViewObject,
1632 ISF_Desktop_fnGetAttributesOf,
1633 IShellFolder_fnGetUIObjectOf,
1634 ISF_Desktop_fnGetDisplayNameOf,
1635 IShellFolder_fnSetNameOf,
1636
1637 /* ShellFolder2 */
1638 ISF_Desktop_fnGetDefaultSearchGUID,
1639 ISF_Desktop_fnEnumSearches,
1640 ISF_Desktop_fnGetDefaultColumn,
1641 ISF_Desktop_fnGetDefaultColumnState,
1642 ISF_Desktop_fnGetDetailsEx,
1643 ISF_Desktop_fnGetDetailsOf,
1644 ISF_Desktop_fnMapNameToSCID
1645};
1646
1647
1648/***********************************************************************
1649* IShellFolder [MyComputer] implementation
1650*/
1651
1652extern struct ICOM_VTABLE(IShellFolder2) sfmcvt;
1653
1654static shvheader MyComputerSFHeader [] =
1655{
1656 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
1657 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1658 { IDS_SHV_COLUMN3DV, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1659 { IDS_SHV_COLUMN4DV, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1660};
1661#define MYCOMPUTERSHELLVIEWCOLUMNS 4
1662
1663/**************************************************************************
1664* ISF_MyComputer_Constructor
1665*/
1666static IShellFolder * ISF_MyComputer_Constructor(void)
1667{
1668 IGenericSFImpl * sf;
1669
1670 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
1671 sf->ref=1;
1672
1673 sf->lpvtbl = &sfmcvt;
1674 sf->lpvtblPersistFolder = &psfvt;
1675 sf->pclsid = (CLSID*)&CLSID_SFMyComp;
1676 sf->absPidl=_ILCreateMyComputer(); /* my qualified pidl */
1677
1678 TRACE("(%p)\n",sf);
1679
1680 shell32_ObjCount++;
1681 return (IShellFolder *)sf;
1682}
1683
1684/**************************************************************************
1685* ISF_MyComputer_fnParseDisplayName
1686*/
1687static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName(
1688 IShellFolder2 * iface,
1689 HWND hwndOwner,
1690 LPBC pbcReserved,
1691 LPOLESTR lpszDisplayName,
1692 DWORD *pchEaten,
1693 LPITEMIDLIST *ppidl,
1694 DWORD *pdwAttributes)
1695{
1696 ICOM_THIS(IGenericSFImpl, iface);
1697
1698 HRESULT hr = E_OUTOFMEMORY;
1699 LPCWSTR szNext=NULL;
1700 WCHAR szElement[MAX_PATH];
1701 CHAR szTempA[MAX_PATH];
1702 LPITEMIDLIST pidlTemp;
1703
1704 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1705 This,hwndOwner,pbcReserved,lpszDisplayName,
1706 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
1707
1708 *ppidl = 0;
1709 if (pchEaten) *pchEaten = 0; /* strange but like the original */
1710
1711 if (PathIsRootW(lpszDisplayName))
1712 {
1713 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
1714 WideCharToLocal(szTempA, szElement, lstrlenW(szElement) + 1);
1715 pidlTemp = _ILCreateDrive(szTempA);
1716
1717 if (szNext && *szNext)
1718 {
1719 hr = SHELL32_ParseNextElement(hwndOwner, (IShellFolder2*)This, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
1720 }
1721 else
1722 {
1723 hr = S_OK;
1724 }
1725 *ppidl = pidlTemp;
1726 }
1727
1728 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
1729
1730 return hr;
1731}
1732
1733/**************************************************************************
1734* ISF_MyComputer_fnEnumObjects
1735*/
1736static HRESULT WINAPI ISF_MyComputer_fnEnumObjects(
1737 IShellFolder2 * iface,
1738 HWND hwndOwner,
1739 DWORD dwFlags,
1740 LPENUMIDLIST* ppEnumIDList)
1741{
1742 ICOM_THIS(IGenericSFImpl, iface);
1743
1744 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
1745
1746 *ppEnumIDList = NULL;
1747 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_MYCOMP);
1748
1749 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
1750
1751 if(!*ppEnumIDList) return E_OUTOFMEMORY;
1752
1753 return S_OK;
1754}
1755
1756/**************************************************************************
1757* ISF_MyComputer_fnBindToObject
1758*/
1759static HRESULT WINAPI ISF_MyComputer_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
1760 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
1761{
1762 ICOM_THIS(IGenericSFImpl, iface);
1763 GUID const * clsid;
1764 char xriid[50];
1765 IShellFolder *pShellFolder, *pSubFolder;
1766 LPITEMIDLIST pidltemp;
1767
1768 WINE_StringFromCLSID(riid,xriid);
1769
1770 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This,pidl,pbcReserved,xriid,ppvOut);
1771
1772 if(!pidl || !ppvOut) return E_INVALIDARG;
1773
1774 *ppvOut = NULL;
1775
1776 if ((clsid=_ILGetGUIDPointer(pidl)) && !IsEqualIID(clsid, &IID_MyComputer))
1777 {
1778 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
1779 {
1780 return E_FAIL;
1781 }
1782 }
1783 else
1784 {
1785 if (!_ILIsDrive(pidl)) return E_INVALIDARG;
1786
1787 pidltemp = ILCloneFirst(pidl);
1788 pShellFolder = IShellFolder_Constructor((IShellFolder*)This, pidltemp);
1789 ILFree(pidltemp);
1790 }
1791
1792 if (_ILIsPidlSimple(pidl)) /* no sub folders */
1793 {
1794 *ppvOut = pShellFolder;
1795 }
1796 else /* go deeper */
1797 {
1798 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID*)&pSubFolder);
1799 IShellFolder_Release(pShellFolder);
1800 *ppvOut = pSubFolder;
1801 }
1802
1803 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
1804
1805 return S_OK;
1806}
1807
1808/**************************************************************************
1809* ISF_MyComputer_fnCreateViewObject
1810*/
1811static HRESULT WINAPI ISF_MyComputer_fnCreateViewObject( IShellFolder2 * iface,
1812 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
1813{
1814 ICOM_THIS(IGenericSFImpl, iface);
1815
1816 LPSHELLVIEW pShellView;
1817 char xriid[50];
1818 HRESULT hr = E_INVALIDARG;
1819
1820 WINE_StringFromCLSID(riid,xriid);
1821 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,xriid,ppvOut);
1822
1823 if(ppvOut)
1824 {
1825 *ppvOut = NULL;
1826
1827 if(IsEqualIID(riid, &IID_IDropTarget))
1828 {
1829 FIXME("IDropTarget not implemented\n");
1830 hr = E_NOTIMPL;
1831 }
1832 else if(IsEqualIID(riid, &IID_IContextMenu))
1833 {
1834 FIXME("IContextMenu not implemented\n");
1835 hr = E_NOTIMPL;
1836 }
1837 else if(IsEqualIID(riid, &IID_IShellView))
1838 {
1839 pShellView = IShellView_Constructor((IShellFolder *) This);
1840 if(pShellView)
1841 {
1842 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
1843 IShellView_Release(pShellView);
1844 }
1845 }
1846 }
1847 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
1848 return hr;
1849}
1850
1851/**************************************************************************
1852* ISF_MyComputer_fnGetAttributesOf
1853*/
1854static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf(IShellFolder2 * iface,UINT cidl,LPCITEMIDLIST *apidl,DWORD *rgfInOut)
1855{
1856 ICOM_THIS(IGenericSFImpl, iface);
1857
1858 GUID const * clsid;
1859 DWORD attributes;
1860 HRESULT hr = S_OK;
1861
1862 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
1863
1864 if ( (!cidl) || (!apidl) || (!rgfInOut))
1865 return E_INVALIDARG;
1866
1867 *rgfInOut = 0xffffffff;
1868
1869 while (cidl > 0 && *apidl)
1870 {
1871 pdump (*apidl);
1872
1873 if (_ILIsDrive(*apidl))
1874 {
1875 *rgfInOut &= 0xf0000144;
1876 goto next;
1877 } else
1878 {
1879 clsid = _ILGetGUIDPointer(*apidl);
1880 if (clsid)
1881 {
1882 if (HCR_GetFolderAttributes(clsid, &attributes))
1883 {
1884 *rgfInOut &= attributes;
1885 goto next;
1886 }
1887 }
1888 }
1889 hr = E_INVALIDARG;
1890
1891next: apidl++;
1892 cidl--;
1893 }
1894
1895 TRACE("-- result=0x%08lx\n",*rgfInOut);
1896 return hr;
1897}
1898
1899/**************************************************************************
1900* ISF_MyComputer_fnGetDisplayNameOf
1901*
1902* NOTES
1903* The desktopfolder creates only complete paths (SHGDN_FORPARSING).
1904* SHGDN_INFOLDER makes no sense.
1905*/
1906static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf(
1907 IShellFolder2 * iface,
1908 LPCITEMIDLIST pidl,
1909 DWORD dwFlags,
1910 LPSTRRET strRet)
1911{
1912 ICOM_THIS(IGenericSFImpl, iface);
1913
1914 char szPath[MAX_PATH], szDrive[18];
1915 int len = 0;
1916 BOOL bSimplePidl;
1917
1918 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1919 pdump(pidl);
1920
1921 if(!strRet) return E_INVALIDARG;
1922
1923 szPath[0]=0x00; szDrive[0]=0x00;
1924
1925
1926 bSimplePidl = _ILIsPidlSimple(pidl);
1927
1928 if (_ILIsSpecialFolder(pidl))
1929 {
1930 /* take names of special folders only if its only this folder */
1931 if ( bSimplePidl )
1932 {
1933 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
1934 }
1935 }
1936 else
1937 {
1938 if (!_ILIsDrive(pidl))
1939 {
1940 ERR("Wrong pidl type\n");
1941 return E_INVALIDARG;
1942 }
1943
1944 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
1945
1946 /* long view "lw_name (C:)" */
1947 if ( bSimplePidl && !(dwFlags & SHGDN_FORPARSING))
1948 {
1949 DWORD dwVolumeSerialNumber,dwMaximumComponetLength,dwFileSystemFlags;
1950
1951 GetVolumeInformationA(szPath,szDrive,12,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0);
1952 strcat (szDrive," (");
1953 strncat (szDrive, szPath, 2);
1954 strcat (szDrive,")");
1955 strcpy (szPath, szDrive);
1956 }
1957 }
1958
1959 if (!bSimplePidl) /* go deeper if needed */
1960 {
1961 PathAddBackslashA(szPath);
1962 len = strlen(szPath);
1963
1964 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild((IShellFolder2*)This, pidl, dwFlags | SHGDN_FORPARSING, szPath + len, MAX_PATH - len)))
1965 return E_OUTOFMEMORY;
1966 }
1967 strRet->uType = STRRET_CSTRA;
1968 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1969
1970
1971 TRACE("-- (%p)->(%s)\n", This, szPath);
1972 return S_OK;
1973}
1974
1975static HRESULT WINAPI ISF_MyComputer_fnGetDefaultSearchGUID(
1976 IShellFolder2 * iface,
1977 GUID *pguid)
1978{
1979 ICOM_THIS(IGenericSFImpl, iface);
1980 FIXME("(%p)\n",This);
1981 return E_NOTIMPL;
1982}
1983static HRESULT WINAPI ISF_MyComputer_fnEnumSearches(
1984 IShellFolder2 * iface,
1985 IEnumExtraSearch **ppenum)
1986{
1987 ICOM_THIS(IGenericSFImpl, iface);
1988 FIXME("(%p)\n",This);
1989 return E_NOTIMPL;
1990}
1991static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumn(
1992 IShellFolder2 * iface,
1993 DWORD dwRes,
1994 ULONG *pSort,
1995 ULONG *pDisplay)
1996{
1997 ICOM_THIS(IGenericSFImpl, iface);
1998
1999 TRACE("(%p)\n",This);
2000
2001 if (pSort) *pSort = 0;
2002 if (pDisplay) *pDisplay = 0;
2003
2004 return S_OK;
2005}
2006static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumnState(
2007 IShellFolder2 * iface,
2008 UINT iColumn,
2009 DWORD *pcsFlags)
2010{
2011 ICOM_THIS(IGenericSFImpl, iface);
2012
2013 TRACE("(%p)\n",This);
2014
2015 if (!pcsFlags || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2016
2017 *pcsFlags = MyComputerSFHeader[iColumn].pcsFlags;
2018
2019 return S_OK;
2020}
2021static HRESULT WINAPI ISF_MyComputer_fnGetDetailsEx(
2022 IShellFolder2 * iface,
2023 LPCITEMIDLIST pidl,
2024 const SHCOLUMNID *pscid,
2025 VARIANT *pv)
2026{
2027 ICOM_THIS(IGenericSFImpl, iface);
2028 FIXME("(%p)\n",This);
2029
2030 return E_NOTIMPL;
2031}
2032
2033/* fixme: drive size >4GB is rolling over */
2034static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf(
2035 IShellFolder2 * iface,
2036 LPCITEMIDLIST pidl,
2037 UINT iColumn,
2038 SHELLDETAILS *psd)
2039{
2040 ICOM_THIS(IGenericSFImpl, iface);
2041 HRESULT hr;
2042
2043 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
2044
2045 if (!psd || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2046
2047 if (!pidl)
2048 {
2049 psd->fmt = MyComputerSFHeader[iColumn].fmt;
2050 psd->cxChar = MyComputerSFHeader[iColumn].cxChar;
2051 psd->str.uType = STRRET_CSTRA;
2052 LoadStringA(shell32_hInstance, MyComputerSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
2053 return S_OK;
2054 }
2055 else
2056 {
2057 char szPath[MAX_PATH];
2058 ULARGE_INTEGER ulBytes;
2059
2060 psd->str.u.cStr[0] = 0x00;
2061 psd->str.uType = STRRET_CSTRA;
2062 switch(iColumn)
2063 {
2064 case 0: /* name */
2065 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2066 break;
2067 case 1: /* type */
2068 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2069 break;
2070 case 2: /* total size */
2071 if (_ILIsDrive(pidl))
2072 {
2073 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2074 GetDiskFreeSpaceExA(szPath, NULL, &ulBytes, NULL);
2075 StrFormatByteSizeA(ulBytes.LowPart, psd->str.u.cStr, MAX_PATH);
2076 }
2077 break;
2078 case 3: /* free size */
2079 if (_ILIsDrive(pidl))
2080 {
2081 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2082 GetDiskFreeSpaceExA(szPath, &ulBytes, NULL, NULL);
2083 StrFormatByteSizeA(ulBytes.LowPart, psd->str.u.cStr, MAX_PATH);
2084 }
2085 break;
2086 }
2087 hr = S_OK;
2088 }
2089
2090 return hr;
2091}
2092static HRESULT WINAPI ISF_MyComputer_fnMapNameToSCID(
2093 IShellFolder2 * iface,
2094 LPCWSTR pwszName,
2095 SHCOLUMNID *pscid)
2096{
2097 ICOM_THIS(IGenericSFImpl, iface);
2098 FIXME("(%p)\n",This);
2099 return E_NOTIMPL;
2100}
2101
2102ICOM_VTABLE(IShellFolder2) sfmcvt =
2103{
2104 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2105 IShellFolder_fnQueryInterface,
2106 IShellFolder_fnAddRef,
2107 IShellFolder_fnRelease,
2108 ISF_MyComputer_fnParseDisplayName,
2109 ISF_MyComputer_fnEnumObjects,
2110 ISF_MyComputer_fnBindToObject,
2111 IShellFolder_fnBindToStorage,
2112 IShellFolder_fnCompareIDs,
2113 ISF_MyComputer_fnCreateViewObject,
2114 ISF_MyComputer_fnGetAttributesOf,
2115 IShellFolder_fnGetUIObjectOf,
2116 ISF_MyComputer_fnGetDisplayNameOf,
2117 IShellFolder_fnSetNameOf,
2118
2119 /* ShellFolder2 */
2120 ISF_MyComputer_fnGetDefaultSearchGUID,
2121 ISF_MyComputer_fnEnumSearches,
2122 ISF_MyComputer_fnGetDefaultColumn,
2123 ISF_MyComputer_fnGetDefaultColumnState,
2124 ISF_MyComputer_fnGetDetailsEx,
2125 ISF_MyComputer_fnGetDetailsOf,
2126 ISF_MyComputer_fnMapNameToSCID
2127};
2128
2129
2130/************************************************************************
2131 * ISFPersistFolder_QueryInterface (IUnknown)
2132 *
2133 */
2134static HRESULT WINAPI ISFPersistFolder_QueryInterface(
2135 IPersistFolder * iface,
2136 REFIID iid,
2137 LPVOID* ppvObj)
2138{
2139 _ICOM_THIS_From_IPersistFolder(IGenericSFImpl, iface);
2140
2141 TRACE("(%p)\n", This);
2142
2143 return IShellFolder_QueryInterface((IShellFolder*)This, iid, ppvObj);
2144}
2145
2146/************************************************************************
2147 * ISFPersistFolder_AddRef (IUnknown)
2148 *
2149 */
2150static ULONG WINAPI ISFPersistFolder_AddRef(
2151 IPersistFolder * iface)
2152{
2153 _ICOM_THIS_From_IPersistFolder(IShellFolder, iface);
2154
2155 TRACE("(%p)\n", This);
2156
2157 return IShellFolder_AddRef((IShellFolder*)This);
2158}
2159
2160/************************************************************************
2161 * ISFPersistFolder_Release (IUnknown)
2162 *
2163 */
2164static ULONG WINAPI ISFPersistFolder_Release(
2165 IPersistFolder * iface)
2166{
2167 _ICOM_THIS_From_IPersistFolder(IGenericSFImpl, iface);
2168
2169 TRACE("(%p)\n", This);
2170
2171 return IShellFolder_Release((IShellFolder*)This);
2172}
2173
2174/************************************************************************
2175 * ISFPersistFolder_GetClassID (IPersist)
2176 */
2177static HRESULT WINAPI ISFPersistFolder_GetClassID(
2178 IPersistFolder * iface,
2179 CLSID * lpClassId)
2180{
2181 _ICOM_THIS_From_IPersistFolder(IGenericSFImpl, iface);
2182
2183 TRACE("(%p)\n", This);
2184
2185 if (!lpClassId) return E_POINTER;
2186 *lpClassId = *This->pclsid;
2187
2188 return S_OK;
2189}
2190
2191/************************************************************************
2192 * ISFPersistFolder_Initialize (IPersistFolder)
2193 *
2194 * NOTES
2195 * sMyPath is not set. Don't know how to handle in a non rooted environment.
2196 */
2197static HRESULT WINAPI ISFPersistFolder_Initialize(
2198 IPersistFolder * iface,
2199 LPCITEMIDLIST pidl)
2200{
2201 _ICOM_THIS_From_IPersistFolder(IGenericSFImpl, iface);
2202
2203 TRACE("(%p)\n", This);
2204
2205 if(This->absPidl)
2206 {
2207 SHFree(This->absPidl);
2208 This->absPidl = NULL;
2209 }
2210 This->absPidl = ILClone(pidl);
2211 return S_OK;
2212}
2213
2214ICOM_VTABLE(IPersistFolder) psfvt =
2215{
2216 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2217 ISFPersistFolder_QueryInterface,
2218 ISFPersistFolder_AddRef,
2219 ISFPersistFolder_Release,
2220 ISFPersistFolder_GetClassID,
2221 ISFPersistFolder_Initialize
2222};
2223
2224/****************************************************************************
2225 * ISFDropTarget implementation
2226 */
2227static BOOL ISFDropTarget_QueryDrop(
2228 IDropTarget *iface,
2229 DWORD dwKeyState,
2230 LPDWORD pdwEffect)
2231{
2232 DWORD dwEffect = *pdwEffect;
2233
2234 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2235
2236 *pdwEffect = DROPEFFECT_NONE;
2237
2238 if (This->fAcceptFmt)
2239 { /* Does our interpretation of the keystate ... */
2240 *pdwEffect = KeyStateToDropEffect(dwKeyState);
2241
2242 /* ... matches the desired effect ? */
2243 if (dwEffect & *pdwEffect)
2244 {
2245 return TRUE;
2246 }
2247 }
2248 return FALSE;
2249}
2250
2251static HRESULT WINAPI ISFDropTarget_QueryInterface(
2252 IDropTarget *iface,
2253 REFIID riid,
2254 LPVOID *ppvObj)
2255{
2256 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2257
2258 TRACE("(%p)\n", This);
2259
2260 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2261}
2262
2263static ULONG WINAPI ISFDropTarget_AddRef( IDropTarget *iface)
2264{
2265 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2266
2267 TRACE("(%p)\n", This);
2268
2269 return IShellFolder_AddRef((IShellFolder*)This);
2270}
2271
2272static ULONG WINAPI ISFDropTarget_Release( IDropTarget *iface)
2273{
2274 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2275
2276 TRACE("(%p)\n", This);
2277
2278 return IShellFolder_Release((IShellFolder*)This);
2279}
2280
2281static HRESULT WINAPI ISFDropTarget_DragEnter(
2282 IDropTarget *iface,
2283 IDataObject *pDataObject,
2284 DWORD dwKeyState,
2285 POINTL pt,
2286 DWORD *pdwEffect)
2287{
2288 FORMATETC fmt;
2289
2290 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2291
2292 TRACE("(%p)->(DataObject=%p)\n",This,pDataObject);
2293
2294 InitFormatEtc(fmt, This->cfShellIDList, TYMED_HGLOBAL);
2295
2296 This->fAcceptFmt = (S_OK == IDataObject_QueryGetData(pDataObject, &fmt)) ? TRUE : FALSE;
2297
2298 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2299
2300 return S_OK;
2301}
2302
2303static HRESULT WINAPI ISFDropTarget_DragOver(
2304 IDropTarget *iface,
2305 DWORD dwKeyState,
2306 POINTL pt,
2307 DWORD *pdwEffect)
2308{
2309 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2310
2311 TRACE("(%p)\n",This);
2312
2313 if(!pdwEffect) return E_INVALIDARG;
2314
2315 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2316
2317 return S_OK;
2318}
2319
2320static HRESULT WINAPI ISFDropTarget_DragLeave(
2321 IDropTarget *iface)
2322{
2323 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2324
2325 TRACE("(%p)\n",This);
2326
2327 This->fAcceptFmt = FALSE;
2328
2329 return S_OK;
2330}
2331
2332static HRESULT WINAPI ISFDropTarget_Drop(
2333 IDropTarget *iface,
2334 IDataObject* pDataObject,
2335 DWORD dwKeyState,
2336 POINTL pt,
2337 DWORD *pdwEffect)
2338{
2339 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2340
2341 FIXME("(%p) object dropped\n",This);
2342
2343 return E_NOTIMPL;
2344}
2345
2346struct ICOM_VTABLE(IDropTarget) dt2vt =
2347{
2348 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2349 ISFDropTarget_QueryInterface,
2350 ISFDropTarget_AddRef,
2351 ISFDropTarget_Release,
2352 ISFDropTarget_DragEnter,
2353 ISFDropTarget_DragOver,
2354 ISFDropTarget_DragLeave,
2355 ISFDropTarget_Drop
2356};
2357
Note: See TracBrowser for help on using the repository browser.