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

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

Fix: broken shell build

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