source: trunk/src/shell32/shlfolder.c@ 6989

Last change on this file since 6989 was 6776, checked in by sandervl, 24 years ago

shell folder bugfix (wine)

File size: 71.6 KB
Line 
1/*
2 * Shell Folder stuff
3 *
4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998, 1999 Juergen Schmied
6 *
7 * IShellFolder2 and related interfaces
8 *
9 */
10#ifdef __WIN32OS2__
11#define WINE_LARGE_INTEGER
12#define snprintf(a,b,c,d) sprintf(a,c,d)
13#endif
14#include <stdlib.h>
15#include <string.h>
16#include <stdio.h>
17
18#include "debugtools.h"
19#include "winerror.h"
20#include "winbase.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#include "shlwapi.h"
33#include "shellfolder.h"
34
35DEFAULT_DEBUG_CHANNEL(shell);
36
37
38/***************************************************************************
39 * debughelper: print out the return adress
40 * helps especially to track down unbalanced AddRef/Release
41 */
42#define MEM_DEBUG 0
43
44#if MEM_DEBUG
45#define _CALL_TRACE TRACE("called from: 0x%08x\n", *( ((UINT*)&iface)-1 ));
46#else
47#define _CALL_TRACE
48#endif
49
50typedef struct
51{
52 int colnameid;
53 int pcsFlags;
54 int fmt;
55 int cxChar;
56
57} shvheader;
58
59/***************************************************************************
60 * GetNextElement (internal function)
61 *
62 * gets a part of a string till the first backslash
63 *
64 * PARAMETERS
65 * pszNext [IN] string to get the element from
66 * pszOut [IN] pointer to buffer whitch receives string
67 * dwOut [IN] length of pszOut
68 *
69 * RETURNS
70 * LPSTR pointer to first, not yet parsed char
71 */
72
73static LPCWSTR GetNextElementW(LPCWSTR pszNext,LPWSTR pszOut,DWORD dwOut)
74{ LPCWSTR pszTail = pszNext;
75 DWORD dwCopy;
76 TRACE("(%s %p 0x%08lx)\n",debugstr_w(pszNext),pszOut,dwOut);
77
78 *pszOut=0x0000;
79
80 if(!pszNext || !*pszNext)
81 return NULL;
82
83 while(*pszTail && (*pszTail != (WCHAR)'\\'))
84 pszTail++;
85
86 dwCopy = (WCHAR*)pszTail - (WCHAR*)pszNext + 1;
87 lstrcpynW(pszOut, pszNext, (dwOut<dwCopy)? dwOut : dwCopy);
88
89 if(*pszTail)
90 pszTail++;
91 else
92 pszTail = NULL;
93
94 TRACE("--(%s %s 0x%08lx %p)\n",debugstr_w(pszNext),debugstr_w(pszOut),dwOut,pszTail);
95 return pszTail;
96}
97
98static HRESULT SHELL32_ParseNextElement(
99 HWND hwndOwner,
100 IShellFolder2 * psf,
101 LPITEMIDLIST * pidlInOut,
102 LPOLESTR szNext,
103 DWORD *pEaten,
104 DWORD *pdwAttributes)
105{
106 HRESULT hr = E_OUTOFMEMORY;
107 LPITEMIDLIST pidlOut, pidlTemp = NULL;
108 IShellFolder *psfChild;
109
110 TRACE("(%p, %p, %s)\n",psf, pidlInOut ? *pidlInOut : NULL, debugstr_w(szNext));
111
112
113 /* get the shellfolder for the child pidl and let it analyse further */
114 hr = IShellFolder_BindToObject(psf, *pidlInOut, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
115
116 if (psfChild)
117 {
118 hr = IShellFolder_ParseDisplayName(psfChild, hwndOwner, NULL, szNext, pEaten, &pidlOut, pdwAttributes);
119 IShellFolder_Release(psfChild);
120
121 pidlTemp = ILCombine(*pidlInOut, pidlOut);
122
123 if (pidlOut)
124 ILFree(pidlOut);
125 }
126
127 ILFree(*pidlInOut);
128 *pidlInOut = pidlTemp;
129
130 TRACE("-- pidl=%p ret=0x%08lx\n", pidlInOut? *pidlInOut: NULL, hr);
131 return hr;
132}
133
134/***********************************************************************
135 * SHELL32_CoCreateInitSF
136 *
137 * creates a initialized shell folder
138 */
139static HRESULT SHELL32_CoCreateInitSF (
140 LPITEMIDLIST pidlRoot,
141 LPITEMIDLIST pidlChild,
142 REFCLSID clsid,
143 REFIID iid,
144 LPVOID * ppvOut)
145{
146 HRESULT hr;
147 LPITEMIDLIST absPidl;
148 IShellFolder2 *pShellFolder;
149 IPersistFolder *pPersistFolder;
150
151 TRACE("%p %p\n", pidlRoot, pidlChild);
152
153 *ppvOut = NULL;
154
155 /* we have to ask first for IPersistFolder, some special folders are expecting this */
156 hr = SHCoCreateInstance(NULL, clsid, NULL, &IID_IPersistFolder, (LPVOID*)&pPersistFolder);
157 if (SUCCEEDED(hr))
158 {
159 hr = IPersistFolder_QueryInterface(pPersistFolder, iid, (LPVOID*)&pShellFolder);
160 if (SUCCEEDED(hr))
161 {
162 absPidl = ILCombine (pidlRoot, pidlChild);
163 hr = IPersistFolder_Initialize(pPersistFolder, absPidl);
164 IPersistFolder_Release(pPersistFolder);
165 SHFree(absPidl);
166 *ppvOut = pShellFolder;
167 }
168 }
169
170 TRACE("-- ret=0x%08lx\n", hr);
171 return hr;
172}
173
174static HRESULT SHELL32_GetDisplayNameOfChild(
175 IShellFolder2 * psf,
176 LPCITEMIDLIST pidl,
177 DWORD dwFlags,
178 LPSTR szOut,
179 DWORD dwOutLen)
180{
181 LPITEMIDLIST pidlFirst, pidlNext;
182 IShellFolder2 * psfChild;
183 HRESULT hr = E_OUTOFMEMORY;
184 STRRET strTemp;
185
186 TRACE("(%p)->(pidl=%p 0x%08lx %p 0x%08lx)\n",psf,pidl,dwFlags,szOut, dwOutLen);
187 pdump(pidl);
188
189 if ((pidlFirst = ILCloneFirst(pidl)))
190 {
191 hr = IShellFolder_BindToObject(psf, pidlFirst, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
192 if (SUCCEEDED(hr))
193 {
194 pidlNext = ILGetNext(pidl);
195
196 hr = IShellFolder_GetDisplayNameOf(psfChild, pidlNext, dwFlags | SHGDN_INFOLDER, &strTemp);
197 if (SUCCEEDED(hr))
198 {
199 hr = StrRetToStrNA(szOut, dwOutLen, &strTemp, pidlNext);
200 }
201
202 IShellFolder_Release(psfChild);
203 }
204 ILFree(pidlFirst);
205 }
206
207 TRACE("-- ret=0x%08lx %s\n", hr, szOut);
208
209 return hr;
210}
211
212/***********************************************************************
213 * SHELL32_GetItemAttributes
214 *
215 * NOTES
216 * observerd values:
217 * folder: 0xE0000177 FILESYSTEM | HASSUBFOLDER | FOLDER
218 * file: 0x40000177 FILESYSTEM
219 * drive: 0xf0000144 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR
220 * mycomputer: 0xb0000154 HASSUBFOLDER | FOLDER | FILESYSANCESTOR
221 * (seems to be default for shell extensions if no registry entry exists)
222 *
223 * This functions does not set flags!! It only resets flags when nessesary.
224 */
225static HRESULT SHELL32_GetItemAttributes(
226 IShellFolder * psf,
227 LPITEMIDLIST pidl,
228 LPDWORD pdwAttributes)
229{
230 GUID const * clsid;
231 DWORD dwAttributes;
232
233 TRACE("0x%08lx\n", *pdwAttributes);
234
235 if (*pdwAttributes & (0xcff3fe88))
236 WARN("attribute 0x%08lx not implemented\n", *pdwAttributes);
237 *pdwAttributes &= ~SFGAO_LINK; /* FIXME: for native filedialogs */
238
239 if (_ILIsDrive(pidl))
240 {
241 *pdwAttributes &= 0xf0000144;
242 }
243 else if ((clsid=_ILGetGUIDPointer(pidl)))
244 {
245 if (HCR_GetFolderAttributes(clsid, &dwAttributes))
246 {
247 *pdwAttributes &= dwAttributes;
248 }
249 else
250 {
251 *pdwAttributes &= 0xb0000154;
252 }
253 }
254 else if (_ILGetDataPointer(pidl))
255 {
256 dwAttributes = _ILGetFileAttributes(pidl, NULL, 0);
257 *pdwAttributes &= ~SFGAO_FILESYSANCESTOR;
258
259 if(( SFGAO_FOLDER & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
260 *pdwAttributes &= ~(SFGAO_FOLDER|SFGAO_HASSUBFOLDER);
261
262 if(( SFGAO_HIDDEN & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_HIDDEN))
263 *pdwAttributes &= ~SFGAO_HIDDEN;
264
265 if(( SFGAO_READONLY & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_READONLY))
266 *pdwAttributes &= ~SFGAO_READONLY;
267 }
268 else
269 {
270 *pdwAttributes &= 0xb0000154;
271 }
272 TRACE("-- 0x%08lx\n", *pdwAttributes);
273 return S_OK;
274}
275
276/***********************************************************************
277* IShellFolder implementation
278*/
279
280typedef struct
281{
282 ICOM_VFIELD(IUnknown);
283 DWORD ref;
284 ICOM_VTABLE(IShellFolder2)* lpvtblShellFolder;
285 ICOM_VTABLE(IPersistFolder2)* lpvtblPersistFolder2;
286 ICOM_VTABLE(IDropTarget)* lpvtblDropTarget;
287 ICOM_VTABLE(ISFHelper)* lpvtblSFHelper;
288
289 IUnknown *pUnkOuter; /* used for aggregation */
290
291 CLSID* pclsid;
292
293 LPSTR sMyPath;
294 LPITEMIDLIST absPidl; /* complete pidl */
295
296 UINT cfShellIDList; /* clipboardformat for IDropTarget */
297 BOOL fAcceptFmt; /* flag for pending Drop */
298} IGenericSFImpl;
299
300static struct ICOM_VTABLE(IUnknown) unkvt;
301static struct ICOM_VTABLE(IShellFolder2) sfvt;
302static struct ICOM_VTABLE(IPersistFolder2) psfvt;
303static struct ICOM_VTABLE(IDropTarget) dtvt;
304static struct ICOM_VTABLE(ISFHelper) shvt;
305
306static IShellFolder * ISF_MyComputer_Constructor(void);
307
308#define _IShellFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblShellFolder)))
309#define _ICOM_THIS_From_IShellFolder2(class, name) class* This = (class*)(((char*)name)-_IShellFolder2_Offset);
310
311#define _IPersistFolder_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder2)))
312#define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder_Offset);
313
314#define _IDropTarget_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblDropTarget)))
315#define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
316
317#define _ISFHelper_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblSFHelper)))
318#define _ICOM_THIS_From_ISFHelper(class, name) class* This = (class*)(((char*)name)-_ISFHelper_Offset);
319/*
320 converts This to a interface pointer
321*/
322#define _IUnknown_(This) (IUnknown*)&(This->lpVtbl)
323#define _IShellFolder_(This) (IShellFolder*)&(This->lpvtblShellFolder)
324#define _IShellFolder2_(This) (IShellFolder2*)&(This->lpvtblShellFolder)
325#define _IPersist_(This) (IPersist*)&(This->lpvtblPersistFolder2)
326#define _IPersistFolder_(This) (IPersistFolder*)&(This->lpvtblPersistFolder2)
327#define _IPersistFolder2_(This) (IPersistFolder2*)&(This->lpvtblPersistFolder2)
328#define _IDropTarget_(This) (IDropTarget*)&(This->lpvtblDropTarget)
329#define _ISFHelper_(This) (ISFHelper*)&(This->lpvtblSFHelper)
330/**************************************************************************
331* registers clipboardformat once
332*/
333static void SF_RegisterClipFmt (IGenericSFImpl * This)
334{
335 TRACE("(%p)\n", This);
336
337 if (!This->cfShellIDList)
338 {
339 This->cfShellIDList = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
340 }
341}
342
343/**************************************************************************
344* we need a separate IUnknown to handle aggregation
345* (inner IUnknown)
346*/
347static HRESULT WINAPI IUnknown_fnQueryInterface(
348 IUnknown * iface,
349 REFIID riid,
350 LPVOID *ppvObj)
351{
352 ICOM_THIS(IGenericSFImpl, iface);
353
354 _CALL_TRACE
355 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
356
357 *ppvObj = NULL;
358
359 if(IsEqualIID(riid, &IID_IUnknown)) *ppvObj = _IUnknown_(This);
360 else if(IsEqualIID(riid, &IID_IShellFolder)) *ppvObj = _IShellFolder_(This);
361 else if(IsEqualIID(riid, &IID_IShellFolder2)) *ppvObj = _IShellFolder_(This);
362 else if(IsEqualIID(riid, &IID_IPersist)) *ppvObj = _IPersist_(This);
363 else if(IsEqualIID(riid, &IID_IPersistFolder)) *ppvObj = _IPersistFolder_(This);
364 else if(IsEqualIID(riid, &IID_IPersistFolder2)) *ppvObj = _IPersistFolder2_(This);
365 else if(IsEqualIID(riid, &IID_ISFHelper)) *ppvObj = _ISFHelper_(This);
366 else if(IsEqualIID(riid, &IID_IDropTarget))
367 {
368 *ppvObj = _IDropTarget_(This);
369 SF_RegisterClipFmt(This);
370 }
371
372 if(*ppvObj)
373 {
374 IUnknown_AddRef((IUnknown*)(*ppvObj));
375 TRACE("-- Interface = %p\n", *ppvObj);
376 return S_OK;
377 }
378 TRACE("-- Interface: E_NOINTERFACE\n");
379 return E_NOINTERFACE;
380}
381
382static ULONG WINAPI IUnknown_fnAddRef(IUnknown * iface)
383{
384 ICOM_THIS(IGenericSFImpl, iface);
385
386 _CALL_TRACE
387 TRACE("(%p)->(count=%lu)\n",This,This->ref);
388
389 shell32_ObjCount++;
390 return ++(This->ref);
391}
392
393static ULONG WINAPI IUnknown_fnRelease(IUnknown * iface)
394{
395 ICOM_THIS(IGenericSFImpl, iface);
396
397 _CALL_TRACE
398 TRACE("(%p)->(count=%lu)\n",This,This->ref);
399
400 shell32_ObjCount--;
401 if (!--(This->ref))
402 {
403 TRACE("-- destroying IShellFolder(%p)\n",This);
404
405 if (pdesktopfolder == _IShellFolder_(This))
406 {
407 pdesktopfolder=NULL;
408 TRACE("-- destroyed IShellFolder(%p) was Desktopfolder\n",This);
409 }
410 if(This->absPidl) SHFree(This->absPidl);
411 if(This->sMyPath) SHFree(This->sMyPath);
412 HeapFree(GetProcessHeap(),0,This);
413 return 0;
414 }
415 return This->ref;
416}
417
418static ICOM_VTABLE(IUnknown) unkvt =
419{
420 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
421 IUnknown_fnQueryInterface,
422 IUnknown_fnAddRef,
423 IUnknown_fnRelease,
424};
425
426static shvheader GenericSFHeader [] =
427{
428 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
429 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
430 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
431 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
432 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
433};
434#define GENERICSHELLVIEWCOLUMNS 5
435
436/**************************************************************************
437* IShellFolder_Constructor
438*
439* NOTES
440* creating undocumented ShellFS_Folder as part of an aggregation
441* {F3364BA0-65B9-11CE-A9BA-00AA004AE837}
442*
443* FIXME
444* when pUnkOuter = 0 then rrid = IID_IShellFolder is returned
445*/
446HRESULT IFSFolder_Constructor(
447 IUnknown * pUnkOuter,
448 REFIID riid,
449 LPVOID * ppv)
450{
451 IGenericSFImpl * sf;
452 HRESULT hr = S_OK;
453
454 TRACE("unkOut=%p riid=%s\n",pUnkOuter, debugstr_guid(riid));
455
456 if(pUnkOuter && ! IsEqualIID(riid, &IID_IUnknown))
457 {
458 hr = CLASS_E_NOAGGREGATION; /* forbidden by definition */
459 }
460 else
461 {
462 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
463 if (sf)
464 {
465 sf->ref=1;
466 ICOM_VTBL(sf)=&unkvt;
467 sf->lpvtblShellFolder=&sfvt;
468 sf->lpvtblPersistFolder2=&psfvt;
469 sf->lpvtblDropTarget=&dtvt;
470 sf->lpvtblSFHelper=&shvt;
471
472 sf->pclsid = (CLSID*)&CLSID_SFFile;
473 sf->pUnkOuter = pUnkOuter ? pUnkOuter : _IUnknown_(sf);
474 *ppv = _IUnknown_(sf);
475 hr = S_OK;
476 shell32_ObjCount++;
477 }
478 else
479 {
480 hr = E_OUTOFMEMORY;
481 }
482 }
483 return hr;
484}
485/**************************************************************************
486* IShellFolder_Constructor
487*
488* NOTES
489* THIS points to the parent folder
490*/
491
492IShellFolder * IShellFolder_Constructor(
493 IShellFolder2 * iface,
494 LPITEMIDLIST pidl)
495{
496 IGenericSFImpl * sf;
497 DWORD dwSize=0;
498
499 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
500
501 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
502 sf->ref=1;
503
504 ICOM_VTBL(sf)=&unkvt;
505 sf->lpvtblShellFolder=&sfvt;
506 sf->lpvtblPersistFolder2=&psfvt;
507 sf->lpvtblDropTarget=&dtvt;
508 sf->lpvtblSFHelper=&shvt;
509
510 sf->pclsid = (CLSID*)&CLSID_SFFile;
511 sf->pUnkOuter = _IUnknown_(sf);
512
513 TRACE("(%p)->(parent=%p, pidl=%p)\n",sf,This, pidl);
514 pdump(pidl);
515
516 if(pidl && iface) /* do we have a pidl? */
517 {
518 int len;
519
520 sf->absPidl = ILCombine(This->absPidl, pidl); /* build a absolute pidl */
521
522 if (!_ILIsSpecialFolder(pidl)) /* only file system paths */
523 {
524 if(This->sMyPath) /* get the size of the parents path */
525 {
526 dwSize += strlen(This->sMyPath) ;
527 TRACE("-- (%p)->(parent's path=%s)\n",sf, debugstr_a(This->sMyPath));
528 }
529
530 dwSize += _ILSimpleGetText(pidl,NULL,0); /* add the size of our name*/
531 sf->sMyPath = SHAlloc(dwSize + 2); /* '\0' and backslash */
532
533 if(!sf->sMyPath) return NULL;
534 *(sf->sMyPath)=0x00;
535
536 if(This->sMyPath) /* if the parent has a path, get it*/
537 {
538 strcpy(sf->sMyPath, This->sMyPath);
539 PathAddBackslashA (sf->sMyPath);
540 }
541
542 len = strlen(sf->sMyPath);
543 _ILSimpleGetText(pidl, sf->sMyPath + len, dwSize+2 - len);
544 }
545
546 TRACE("-- (%p)->(my pidl=%p, my path=%s)\n",sf, sf->absPidl,debugstr_a(sf->sMyPath));
547
548 pdump (sf->absPidl);
549 }
550
551 shell32_ObjCount++;
552 return _IShellFolder_(sf);
553}
554
555/**************************************************************************
556 * IShellFolder_fnQueryInterface
557 *
558 * PARAMETERS
559 * REFIID riid [in ] Requested InterfaceID
560 * LPVOID* ppvObject [out] Interface* to hold the result
561 */
562static HRESULT WINAPI IShellFolder_fnQueryInterface(
563 IShellFolder2 * iface,
564 REFIID riid,
565 LPVOID *ppvObj)
566{
567 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
568
569 _CALL_TRACE
570 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
571
572 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
573}
574
575/**************************************************************************
576* IShellFolder_AddRef
577*/
578
579static ULONG WINAPI IShellFolder_fnAddRef(IShellFolder2 * iface)
580{
581 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
582
583 _CALL_TRACE
584 TRACE("(%p)->(count=%lu)\n",This,This->ref);
585
586 return IUnknown_AddRef(This->pUnkOuter);
587}
588
589/**************************************************************************
590 * IShellFolder_fnRelease
591 */
592static ULONG WINAPI IShellFolder_fnRelease(IShellFolder2 * iface)
593{
594 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
595
596 _CALL_TRACE
597 TRACE("(%p)->(count=%lu)\n",This,This->ref);
598
599 return IUnknown_Release(This->pUnkOuter);
600}
601
602/**************************************************************************
603* IShellFolder_fnParseDisplayName
604* PARAMETERS
605* HWND hwndOwner, //[in ] Parent window for any message's
606* LPBC pbc, //[in ] reserved
607* LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname.
608* ULONG* pchEaten, //[out] (unicode) characters processed
609* LPITEMIDLIST* ppidl, //[out] complex pidl to item
610* ULONG* pdwAttributes //[out] items attributes
611*
612* NOTES
613* every folder tries to parse only its own (the leftmost) pidl and creates a
614* subfolder to evaluate the remaining parts
615* now we can parse into namespaces implemented by shell extensions
616*
617* behaviour on win98: lpszDisplayName=NULL -> chrash
618* lpszDisplayName="" -> returns mycoputer-pidl
619*
620* FIXME:
621* pdwAttributes: not set
622* pchEaten: not set like in windows
623*/
624static HRESULT WINAPI IShellFolder_fnParseDisplayName(
625 IShellFolder2 * iface,
626 HWND hwndOwner,
627 LPBC pbcReserved,
628 LPOLESTR lpszDisplayName,
629 DWORD *pchEaten,
630 LPITEMIDLIST *ppidl,
631 DWORD *pdwAttributes)
632{
633 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
634
635 HRESULT hr = E_OUTOFMEMORY;
636 LPCWSTR szNext=NULL;
637 WCHAR szElement[MAX_PATH];
638 CHAR szTempA[MAX_PATH], szPath[MAX_PATH];
639 LPITEMIDLIST pidlTemp=NULL;
640
641 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
642 This,hwndOwner,pbcReserved,lpszDisplayName,
643 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
644
645 if (!lpszDisplayName || !ppidl) return E_INVALIDARG;
646
647 if (pchEaten) *pchEaten = 0; /* strange but like the original */
648
649 if (*lpszDisplayName)
650 {
651 /* get the next element */
652 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
653
654 /* build the full pathname to the element */
655 WideCharToMultiByte( CP_ACP, 0, szElement, -1, szTempA, MAX_PATH, NULL, NULL );
656 strcpy(szPath, This->sMyPath);
657 PathAddBackslashA(szPath);
658 strcat(szPath, szTempA);
659
660 /* get the pidl */
661 pidlTemp = SHSimpleIDListFromPathA(szPath);
662
663 if (pidlTemp)
664 {
665 /* try to analyse the next element */
666 if (szNext && *szNext)
667 {
668 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
669 }
670 else
671 {
672 if (pdwAttributes && *pdwAttributes)
673 {
674 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
675/* WIN32_FIND_DATAA fd;
676 SHGetDataFromIDListA(_IShellFolder_(This), pidlTemp, SHGDFIL_FINDDATA, &fd, sizeof(fd));
677 if (!(FILE_ATTRIBUTE_DIRECTORY & fd.dwFileAttributes))
678 *pdwAttributes &= ~SFGAO_FOLDER;
679 if (FILE_ATTRIBUTE_READONLY & fd.dwFileAttributes)
680 *pdwAttributes &= ~(SFGAO_CANDELETE|SFGAO_CANMOVE|SFGAO_CANRENAME );
681*/
682 }
683 hr = S_OK;
684 }
685 }
686 }
687
688 if (!hr)
689 *ppidl = pidlTemp;
690 else
691 *ppidl = NULL;
692
693 TRACE("(%p)->(-- pidl=%p ret=0x%08lx)\n", This, ppidl? *ppidl:0, hr);
694
695 return hr;
696}
697
698/**************************************************************************
699* IShellFolder_fnEnumObjects
700* PARAMETERS
701* HWND hwndOwner, //[in ] Parent Window
702* DWORD grfFlags, //[in ] SHCONTF enumeration mask
703* LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface
704*/
705static HRESULT WINAPI IShellFolder_fnEnumObjects(
706 IShellFolder2 * iface,
707 HWND hwndOwner,
708 DWORD dwFlags,
709 LPENUMIDLIST* ppEnumIDList)
710{
711 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
712
713 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
714
715 *ppEnumIDList = NULL;
716 *ppEnumIDList = IEnumIDList_Constructor (This->sMyPath, dwFlags, EIDL_FILE);
717
718 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
719
720 if(!*ppEnumIDList) return E_OUTOFMEMORY;
721
722 return S_OK;
723}
724
725/**************************************************************************
726* IShellFolder_fnBindToObject
727* PARAMETERS
728* LPCITEMIDLIST pidl, //[in ] relative pidl to open
729* LPBC pbc, //[in ] reserved
730* REFIID riid, //[in ] Initial Interface
731* LPVOID* ppvObject //[out] Interface*
732*/
733static HRESULT WINAPI IShellFolder_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
734 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
735{
736 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
737 GUID const * iid;
738 IShellFolder *pShellFolder, *pSubFolder;
739 IPersistFolder *pPersistFolder;
740 LPITEMIDLIST absPidl;
741
742 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
743
744 if(!pidl || !ppvOut) return E_INVALIDARG;
745
746 *ppvOut = NULL;
747
748 if ((iid=_ILGetGUIDPointer(pidl)))
749 {
750 /* we have to create a alien folder */
751 if ( SUCCEEDED(SHCoCreateInstance(NULL, iid, NULL, riid, (LPVOID*)&pShellFolder))
752 && SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&pPersistFolder)))
753 {
754 absPidl = ILCombine (This->absPidl, pidl);
755 IPersistFolder_Initialize(pPersistFolder, absPidl);
756 IPersistFolder_Release(pPersistFolder);
757 SHFree(absPidl);
758 }
759 else
760 {
761 return E_FAIL;
762 }
763 }
764 else if(_ILIsFolder(pidl))
765 {
766 LPITEMIDLIST pidltemp = ILCloneFirst(pidl);
767 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
768 ILFree(pidltemp);
769 }
770 else
771 {
772 ERR("can't bind to a file\n");
773 return E_FAIL;
774 }
775
776 if (_ILIsPidlSimple(pidl))
777 {
778 *ppvOut = pShellFolder;
779 }
780 else
781 {
782 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
783 IShellFolder_Release(pShellFolder);
784 *ppvOut = pSubFolder;
785 }
786
787 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
788
789 return S_OK;
790}
791
792/**************************************************************************
793* IShellFolder_fnBindToStorage
794* PARAMETERS
795* LPCITEMIDLIST pidl, //[in ] complex pidl to store
796* LPBC pbc, //[in ] reserved
797* REFIID riid, //[in ] Initial storage interface
798* LPVOID* ppvObject //[out] Interface* returned
799*/
800static HRESULT WINAPI IShellFolder_fnBindToStorage(
801 IShellFolder2 * iface,
802 LPCITEMIDLIST pidl,
803 LPBC pbcReserved,
804 REFIID riid,
805 LPVOID *ppvOut)
806{
807 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
808
809 FIXME("(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",
810 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
811
812 *ppvOut = NULL;
813 return E_NOTIMPL;
814}
815
816/**************************************************************************
817* IShellFolder_fnCompareIDs
818*
819* PARMETERS
820* LPARAM lParam, //[in ] Column?
821* LPCITEMIDLIST pidl1, //[in ] simple pidl
822* LPCITEMIDLIST pidl2) //[in ] simple pidl
823*
824* NOTES
825* Special case - If one of the items is a Path and the other is a File,
826* always make the Path come before the File.
827*
828* NOTES
829* use SCODE_CODE() on the return value to get the result
830*/
831
832static HRESULT WINAPI IShellFolder_fnCompareIDs(
833 IShellFolder2 * iface,
834 LPARAM lParam,
835 LPCITEMIDLIST pidl1,
836 LPCITEMIDLIST pidl2)
837{
838 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
839
840 CHAR szTemp1[MAX_PATH];
841 CHAR szTemp2[MAX_PATH];
842 int nReturn;
843 IShellFolder * psf;
844 HRESULT hr = E_OUTOFMEMORY;
845 LPCITEMIDLIST pidlTemp;
846 PIDLTYPE pt1, pt2;
847
848 TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",This,lParam,pidl1,pidl2);
849 pdump (pidl1);
850 pdump (pidl2);
851
852 if (!pidl1 && !pidl2)
853 {
854 hr = ResultFromShort(0);
855 }
856 else if (!pidl1)
857 {
858 hr = ResultFromShort(-1);
859 }
860 else if (!pidl2)
861 {
862 hr = ResultFromShort(1);
863 }
864 else
865 {
866 LPPIDLDATA pd1, pd2;
867 pd1 = _ILGetDataPointer(pidl1);
868 pd2 = _ILGetDataPointer(pidl2);
869
870 /* compate the types. sort order is the PT_* constant */
871 pt1 = ( pd1 ? pd1->type: PT_DESKTOP);
872 pt2 = ( pd2 ? pd2->type: PT_DESKTOP);
873
874 if (pt1 != pt2)
875 {
876 hr = ResultFromShort(pt1-pt2);
877 }
878 else /* same type of pidl */
879 {
880 _ILSimpleGetText(pidl1, szTemp1, MAX_PATH);
881 _ILSimpleGetText(pidl2, szTemp2, MAX_PATH);
882 nReturn = strcasecmp(szTemp1, szTemp2);
883
884 if (nReturn == 0) /* first pidl different ? */
885 {
886 pidl1 = ILGetNext(pidl1);
887
888 if (pidl1 && pidl1->mkid.cb) /* go deeper? */
889 {
890 pidlTemp = ILCloneFirst(pidl1);
891 pidl2 = ILGetNext(pidl2);
892
893 hr = IShellFolder_BindToObject(iface, pidlTemp, NULL, &IID_IShellFolder, (LPVOID*)&psf);
894 if (SUCCEEDED(hr))
895 {
896 nReturn = IShellFolder_CompareIDs(psf, 0, pidl1, pidl2);
897 IShellFolder_Release(psf);
898 hr = ResultFromShort(nReturn);
899 }
900 ILFree(pidlTemp);
901 }
902 else
903 {
904 pidl2 = ILGetNext(pidl2);
905 if (pidl2 && pidl2->mkid.cb) /* go deeper on #2 ? */
906 hr = ResultFromShort(-1); /* two different */
907 else
908 hr = ResultFromShort(nReturn); /* two equal simple pidls */
909 }
910 }
911 else
912 {
913 hr = ResultFromShort(nReturn); /* two different simple pidls */
914 }
915 }
916 }
917
918 TRACE("-- res=0x%08lx\n", hr);
919 return hr;
920}
921
922/**************************************************************************
923* IShellFolder_fnCreateViewObject
924*/
925static HRESULT WINAPI IShellFolder_fnCreateViewObject(
926 IShellFolder2 * iface,
927 HWND hwndOwner,
928 REFIID riid,
929 LPVOID *ppvOut)
930{
931 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
932
933 LPSHELLVIEW pShellView;
934 HRESULT hr = E_INVALIDARG;
935
936 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
937
938 if(ppvOut)
939 {
940 *ppvOut = NULL;
941
942 if(IsEqualIID(riid, &IID_IDropTarget))
943 {
944 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, ppvOut);
945 }
946 else if(IsEqualIID(riid, &IID_IContextMenu))
947 {
948 FIXME("IContextMenu not implemented\n");
949 hr = E_NOTIMPL;
950 }
951 else if(IsEqualIID(riid, &IID_IShellView))
952 {
953 pShellView = IShellView_Constructor((IShellFolder*)iface);
954 if(pShellView)
955 {
956 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
957 IShellView_Release(pShellView);
958 }
959 }
960 }
961 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
962 return hr;
963}
964
965/**************************************************************************
966* IShellFolder_fnGetAttributesOf
967*
968* PARAMETERS
969* UINT cidl, //[in ] num elements in pidl array
970* LPCITEMIDLIST* apidl, //[in ] simple pidl array
971* ULONG* rgfInOut) //[out] result array
972*
973*/
974static HRESULT WINAPI IShellFolder_fnGetAttributesOf(
975 IShellFolder2 * iface,
976 UINT cidl,
977 LPCITEMIDLIST *apidl,
978 DWORD *rgfInOut)
979{
980 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
981
982 HRESULT hr = S_OK;
983
984 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
985
986 if ( (!cidl) || (!apidl) || (!rgfInOut))
987 return E_INVALIDARG;
988
989 while (cidl > 0 && *apidl)
990 {
991 pdump (*apidl);
992 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
993 apidl++;
994 cidl--;
995 }
996
997 TRACE("-- result=0x%08lx\n",*rgfInOut);
998
999 return hr;
1000}
1001/**************************************************************************
1002* IShellFolder_fnGetUIObjectOf
1003*
1004* PARAMETERS
1005* HWND hwndOwner, //[in ] Parent window for any output
1006* UINT cidl, //[in ] array size
1007* LPCITEMIDLIST* apidl, //[in ] simple pidl array
1008* REFIID riid, //[in ] Requested Interface
1009* UINT* prgfInOut, //[ ] reserved
1010* LPVOID* ppvObject) //[out] Resulting Interface
1011*
1012* NOTES
1013* This function gets asked to return "view objects" for one or more (multiple select)
1014* items:
1015* The viewobject typically is an COM object with one of the following interfaces:
1016* IExtractIcon,IDataObject,IContextMenu
1017* In order to support icon positions in the default Listview your DataObject
1018* must implement the SetData method (in addition to GetData :) - the shell passes
1019* a barely documented "Icon positions" structure to SetData when the drag starts,
1020* and GetData's it if the drop is in another explorer window that needs the positions.
1021*/
1022static HRESULT WINAPI IShellFolder_fnGetUIObjectOf(
1023 IShellFolder2 * iface,
1024 HWND hwndOwner,
1025 UINT cidl,
1026 LPCITEMIDLIST * apidl,
1027 REFIID riid,
1028 UINT * prgfInOut,
1029 LPVOID * ppvOut)
1030{
1031 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1032
1033 LPITEMIDLIST pidl;
1034 IUnknown* pObj = NULL;
1035 HRESULT hr = E_INVALIDARG;
1036
1037 TRACE("(%p)->(0x%04x,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
1038 This,hwndOwner,cidl,apidl,debugstr_guid(riid),prgfInOut,ppvOut);
1039
1040 if (ppvOut)
1041 {
1042 *ppvOut = NULL;
1043
1044 if(IsEqualIID(riid, &IID_IContextMenu) && (cidl >= 1))
1045 {
1046 pObj = (LPUNKNOWN)ISvItemCm_Constructor((IShellFolder*)iface, This->absPidl, apidl, cidl);
1047 hr = S_OK;
1048 }
1049 else if (IsEqualIID(riid, &IID_IDataObject) &&(cidl >= 1))
1050 {
1051 pObj = (LPUNKNOWN)IDataObject_Constructor (hwndOwner, This->absPidl, apidl, cidl);
1052 hr = S_OK;
1053 }
1054 else if (IsEqualIID(riid, &IID_IExtractIconA) && (cidl == 1))
1055 {
1056 pidl = ILCombine(This->absPidl,apidl[0]);
1057 pObj = (LPUNKNOWN)IExtractIconA_Constructor( pidl );
1058 SHFree(pidl);
1059 hr = S_OK;
1060 }
1061 else if (IsEqualIID(riid, &IID_IDropTarget) && (cidl >= 1))
1062 {
1063 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, (LPVOID*)&pObj);
1064 }
1065 else
1066 {
1067 hr = E_NOINTERFACE;
1068 }
1069
1070 if(!pObj)
1071 hr = E_OUTOFMEMORY;
1072
1073 *ppvOut = pObj;
1074 }
1075 TRACE("(%p)->hr=0x%08lx\n",This, hr);
1076 return hr;
1077}
1078
1079/**************************************************************************
1080* IShellFolder_fnGetDisplayNameOf
1081* Retrieves the display name for the specified file object or subfolder
1082*
1083* PARAMETERS
1084* LPCITEMIDLIST pidl, //[in ] complex pidl to item
1085* DWORD dwFlags, //[in ] SHGNO formatting flags
1086* LPSTRRET lpName) //[out] Returned display name
1087*
1088* FIXME
1089* if the name is in the pidl the ret value should be a STRRET_OFFSET
1090*/
1091#define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
1092#define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
1093
1094static HRESULT WINAPI IShellFolder_fnGetDisplayNameOf(
1095 IShellFolder2 * iface,
1096 LPCITEMIDLIST pidl,
1097 DWORD dwFlags,
1098 LPSTRRET strRet)
1099{
1100 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1101
1102 CHAR szPath[MAX_PATH]= "";
1103 int len = 0;
1104 BOOL bSimplePidl;
1105
1106 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1107 pdump(pidl);
1108
1109 if(!pidl || !strRet) return E_INVALIDARG;
1110
1111 bSimplePidl = _ILIsPidlSimple(pidl);
1112
1113 /* take names of special folders only if its only this folder */
1114 if (_ILIsSpecialFolder(pidl))
1115 {
1116 if ( bSimplePidl)
1117 {
1118 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
1119 }
1120 }
1121 else
1122 {
1123 if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) && This->sMyPath)
1124 {
1125 strcpy (szPath, This->sMyPath); /* get path to root*/
1126 PathAddBackslashA(szPath);
1127 len = strlen(szPath);
1128 }
1129 _ILSimpleGetText(pidl, szPath + len, MAX_PATH - len); /* append my own path */
1130 }
1131
1132 if ( (dwFlags & SHGDN_FORPARSING) && !bSimplePidl) /* go deeper if needed */
1133 {
1134 PathAddBackslashA(szPath);
1135 len = strlen(szPath);
1136
1137 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath + len, MAX_PATH - len)))
1138 return E_OUTOFMEMORY;
1139 }
1140 strRet->uType = STRRET_CSTRA;
1141 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1142
1143 TRACE("-- (%p)->(%s)\n", This, szPath);
1144 return S_OK;
1145}
1146
1147/**************************************************************************
1148* IShellFolder_fnSetNameOf
1149* Changes the name of a file object or subfolder, possibly changing its item
1150* identifier in the process.
1151*
1152* PARAMETERS
1153* HWND hwndOwner, //[in ] Owner window for output
1154* LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
1155* LPCOLESTR lpszName, //[in ] the items new display name
1156* DWORD dwFlags, //[in ] SHGNO formatting flags
1157* LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
1158*/
1159static HRESULT WINAPI IShellFolder_fnSetNameOf(
1160 IShellFolder2 * iface,
1161 HWND hwndOwner,
1162 LPCITEMIDLIST pidl, /*simple pidl*/
1163 LPCOLESTR lpName,
1164 DWORD dwFlags,
1165 LPITEMIDLIST *pPidlOut)
1166{
1167 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1168 char szSrc[MAX_PATH], szDest[MAX_PATH];
1169 int len;
1170 BOOL bIsFolder = _ILIsFolder(ILFindLastID(pidl));
1171
1172 TRACE("(%p)->(%u,pidl=%p,%s,%lu,%p)\n",
1173 This,hwndOwner,pidl,debugstr_w(lpName),dwFlags,pPidlOut);
1174
1175 /* build source path */
1176 if (dwFlags & SHGDN_INFOLDER)
1177 {
1178 strcpy(szSrc, This->sMyPath);
1179 PathAddBackslashA(szSrc);
1180 len = strlen (szSrc);
1181 _ILSimpleGetText(pidl, szSrc+len, MAX_PATH-len);
1182 }
1183 else
1184 {
1185 SHGetPathFromIDListA(pidl, szSrc);
1186 }
1187
1188 /* build destination path */
1189 strcpy(szDest, This->sMyPath);
1190 PathAddBackslashA(szDest);
1191 len = strlen (szDest);
1192 WideCharToMultiByte( CP_ACP, 0, lpName, -1, szDest+len, MAX_PATH-len, NULL, NULL );
1193 szDest[MAX_PATH-1] = 0;
1194 TRACE("src=%s dest=%s\n", szSrc, szDest);
1195 if ( MoveFileA(szSrc, szDest) )
1196 {
1197 if (pPidlOut) *pPidlOut = SHSimpleIDListFromPathA(szDest);
1198 SHChangeNotifyA( bIsFolder?SHCNE_RENAMEFOLDER:SHCNE_RENAMEITEM, SHCNF_PATHA, szSrc, szDest);
1199 return S_OK;
1200 }
1201 return E_FAIL;
1202}
1203
1204static HRESULT WINAPI IShellFolder_fnGetDefaultSearchGUID(
1205 IShellFolder2 * iface,
1206 GUID *pguid)
1207{
1208 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1209 FIXME("(%p)\n",This);
1210 return E_NOTIMPL;
1211}
1212static HRESULT WINAPI IShellFolder_fnEnumSearches(
1213 IShellFolder2 * iface,
1214 IEnumExtraSearch **ppenum)
1215{
1216 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1217 FIXME("(%p)\n",This);
1218 return E_NOTIMPL;
1219}
1220static HRESULT WINAPI IShellFolder_fnGetDefaultColumn(
1221 IShellFolder2 * iface,
1222 DWORD dwRes,
1223 ULONG *pSort,
1224 ULONG *pDisplay)
1225{
1226 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1227
1228 TRACE("(%p)\n",This);
1229
1230 if (pSort) *pSort = 0;
1231 if (pDisplay) *pDisplay = 0;
1232
1233 return S_OK;
1234}
1235static HRESULT WINAPI IShellFolder_fnGetDefaultColumnState(
1236 IShellFolder2 * iface,
1237 UINT iColumn,
1238 DWORD *pcsFlags)
1239{
1240 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1241
1242 TRACE("(%p)\n",This);
1243
1244 if (!pcsFlags || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1245
1246 *pcsFlags = GenericSFHeader[iColumn].pcsFlags;
1247
1248 return S_OK;
1249}
1250static HRESULT WINAPI IShellFolder_fnGetDetailsEx(
1251 IShellFolder2 * iface,
1252 LPCITEMIDLIST pidl,
1253 const SHCOLUMNID *pscid,
1254 VARIANT *pv)
1255{
1256 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1257 FIXME("(%p)\n",This);
1258
1259 return E_NOTIMPL;
1260}
1261static HRESULT WINAPI IShellFolder_fnGetDetailsOf(
1262 IShellFolder2 * iface,
1263 LPCITEMIDLIST pidl,
1264 UINT iColumn,
1265 SHELLDETAILS *psd)
1266{
1267 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1268 HRESULT hr = E_FAIL;
1269
1270 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
1271
1272 if (!psd || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1273
1274 if (!pidl)
1275 {
1276 /* the header titles */
1277 psd->fmt = GenericSFHeader[iColumn].fmt;
1278 psd->cxChar = GenericSFHeader[iColumn].cxChar;
1279 psd->str.uType = STRRET_CSTRA;
1280 LoadStringA(shell32_hInstance, GenericSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
1281 return S_OK;
1282 }
1283 else
1284 {
1285 /* the data from the pidl */
1286 switch(iColumn)
1287 {
1288 case 0: /* name */
1289 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
1290 break;
1291 case 1: /* size */
1292 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
1293 break;
1294 case 2: /* type */
1295 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
1296 break;
1297 case 3: /* date */
1298 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
1299 break;
1300 case 4: /* attributes */
1301 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
1302 break;
1303 }
1304 hr = S_OK;
1305 psd->str.uType = STRRET_CSTRA;
1306 }
1307
1308 return hr;
1309}
1310static HRESULT WINAPI IShellFolder_fnMapNameToSCID(
1311 IShellFolder2 * iface,
1312 LPCWSTR pwszName,
1313 SHCOLUMNID *pscid)
1314{
1315 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1316 FIXME("(%p)\n",This);
1317 return E_NOTIMPL;
1318}
1319
1320static ICOM_VTABLE(IShellFolder2) sfvt =
1321{
1322 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1323 IShellFolder_fnQueryInterface,
1324 IShellFolder_fnAddRef,
1325 IShellFolder_fnRelease,
1326 IShellFolder_fnParseDisplayName,
1327 IShellFolder_fnEnumObjects,
1328 IShellFolder_fnBindToObject,
1329 IShellFolder_fnBindToStorage,
1330 IShellFolder_fnCompareIDs,
1331 IShellFolder_fnCreateViewObject,
1332 IShellFolder_fnGetAttributesOf,
1333 IShellFolder_fnGetUIObjectOf,
1334 IShellFolder_fnGetDisplayNameOf,
1335 IShellFolder_fnSetNameOf,
1336
1337 /* ShellFolder2 */
1338 IShellFolder_fnGetDefaultSearchGUID,
1339 IShellFolder_fnEnumSearches,
1340 IShellFolder_fnGetDefaultColumn,
1341 IShellFolder_fnGetDefaultColumnState,
1342 IShellFolder_fnGetDetailsEx,
1343 IShellFolder_fnGetDetailsOf,
1344 IShellFolder_fnMapNameToSCID
1345};
1346
1347/****************************************************************************
1348 * ISFHelper for IShellFolder implementation
1349 */
1350
1351static HRESULT WINAPI ISFHelper_fnQueryInterface(
1352 ISFHelper *iface,
1353 REFIID riid,
1354 LPVOID *ppvObj)
1355{
1356 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1357
1358 TRACE("(%p)\n", This);
1359
1360 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
1361}
1362
1363static ULONG WINAPI ISFHelper_fnAddRef(
1364 ISFHelper *iface)
1365{
1366 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1367
1368 TRACE("(%p)\n", This);
1369
1370 return IUnknown_AddRef(This->pUnkOuter);
1371}
1372
1373static ULONG WINAPI ISFHelper_fnRelease(
1374 ISFHelper *iface)
1375{
1376 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1377
1378 TRACE("(%p)\n", This);
1379
1380 return IUnknown_Release(This->pUnkOuter);
1381}
1382
1383
1384/****************************************************************************
1385 * ISFHelper_fnAddFolder
1386 *
1387 * creates a unique folder name
1388 */
1389
1390static HRESULT WINAPI ISFHelper_fnGetUniqueName(
1391 ISFHelper *iface,
1392 LPSTR lpName,
1393 UINT uLen)
1394{
1395 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1396 IEnumIDList * penum;
1397 HRESULT hr;
1398 char szText[MAX_PATH];
1399 char * szNewFolder = "New Folder";
1400
1401 TRACE("(%p)(%s %u)\n", This, lpName, uLen);
1402
1403 if (uLen < strlen(szNewFolder) + 4) return E_POINTER;
1404
1405 strcpy(lpName, szNewFolder);
1406
1407 hr = IShellFolder_fnEnumObjects(_IShellFolder2_(This), 0, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penum);
1408 if (penum)
1409 {
1410 LPITEMIDLIST pidl;
1411 DWORD dwFetched;
1412 int i=1;
1413
1414next: IEnumIDList_Reset(penum);
1415 while(S_OK == IEnumIDList_Next(penum, 1, &pidl, &dwFetched) && dwFetched)
1416 {
1417 _ILSimpleGetText(pidl, szText, MAX_PATH);
1418 if (0 == strcasecmp(szText, lpName))
1419 {
1420 sprintf(lpName, "%s %d", szNewFolder, i++);
1421 if (i > 99)
1422 {
1423 hr = E_FAIL;
1424 break;
1425 }
1426 goto next;
1427 }
1428 }
1429
1430 IEnumIDList_Release(penum);
1431 }
1432 return hr;
1433}
1434
1435/****************************************************************************
1436 * ISFHelper_fnAddFolder
1437 *
1438 * adds a new folder.
1439 */
1440
1441static HRESULT WINAPI ISFHelper_fnAddFolder(
1442 ISFHelper *iface,
1443 HWND hwnd,
1444 LPCSTR lpName,
1445 LPITEMIDLIST* ppidlOut)
1446{
1447 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1448 char lpstrNewDir[MAX_PATH];
1449 DWORD bRes;
1450 HRESULT hres = E_FAIL;
1451
1452 TRACE("(%p)(%s %p)\n", This, lpName, ppidlOut);
1453
1454 strcpy(lpstrNewDir, This->sMyPath);
1455 PathAddBackslashA(lpstrNewDir);
1456 strcat(lpstrNewDir, lpName);
1457
1458 bRes = CreateDirectoryA(lpstrNewDir, NULL);
1459
1460 if (bRes)
1461 {
1462 LPITEMIDLIST pidl, pidlitem;
1463
1464 pidlitem = SHSimpleIDListFromPathA(lpstrNewDir);
1465
1466 pidl = ILCombine(This->absPidl, pidlitem);
1467 SHChangeNotifyA(SHCNE_MKDIR, SHCNF_IDLIST, pidl, NULL);
1468 SHFree(pidl);
1469
1470 if (ppidlOut) *ppidlOut = pidlitem;
1471 hres = S_OK;
1472 }
1473 else
1474 {
1475 char lpstrText[128+MAX_PATH];
1476 char lpstrTempText[128];
1477 char lpstrCaption[256];
1478
1479 /* Cannot Create folder because of permissions */
1480 LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_DENIED, lpstrTempText, sizeof(lpstrTempText));
1481 LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_CAPTION, lpstrCaption, sizeof(lpstrCaption));
1482 sprintf(lpstrText,lpstrTempText, lpstrNewDir);
1483 MessageBoxA(hwnd,lpstrText, lpstrCaption, MB_OK | MB_ICONEXCLAMATION);
1484 }
1485
1486 return hres;
1487}
1488
1489/****************************************************************************
1490 * ISFHelper_fnDeleteItems
1491 *
1492 * deletes items in folder
1493 */
1494static HRESULT WINAPI ISFHelper_fnDeleteItems(
1495 ISFHelper *iface,
1496 UINT cidl,
1497 LPCITEMIDLIST* apidl)
1498{
1499 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1500 int i;
1501 char szPath[MAX_PATH];
1502 BOOL bConfirm = TRUE;
1503
1504 TRACE("(%p)(%u %p)\n", This, cidl, apidl);
1505
1506 /* deleting multiple items so give a slightly different warning */
1507 if(cidl != 1)
1508 {
1509 char tmp[8];
1510 snprintf(tmp, sizeof(tmp), "%d", cidl);
1511 if(!SHELL_WarnItemDelete(ASK_DELETE_MULTIPLE_ITEM, tmp))
1512 return E_FAIL;
1513 bConfirm = FALSE;
1514 }
1515
1516 for(i=0; i< cidl; i++)
1517 {
1518 strcpy(szPath, This->sMyPath);
1519 PathAddBackslashA(szPath);
1520 _ILSimpleGetText(apidl[i], szPath+strlen(szPath), MAX_PATH);
1521
1522 if (_ILIsFolder(apidl[i]))
1523 {
1524 LPITEMIDLIST pidl;
1525 TRACE("delete %s\n", szPath);
1526 if (! SHELL_DeleteDirectoryA(szPath, bConfirm))
1527 {
1528 TRACE("delete %s failed, bConfirm=%d", szPath, bConfirm);
1529 return E_FAIL;
1530 }
1531 pidl = ILCombine(This->absPidl, apidl[i]);
1532 SHChangeNotifyA(SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);
1533 SHFree(pidl);
1534 }
1535 else if (_ILIsValue(apidl[i]))
1536 {
1537 LPITEMIDLIST pidl;
1538
1539 TRACE("delete %s\n", szPath);
1540 if (! SHELL_DeleteFileA(szPath, bConfirm))
1541 {
1542 TRACE("delete %s failed, bConfirm=%d", szPath, bConfirm);
1543 return E_FAIL;
1544 }
1545 pidl = ILCombine(This->absPidl, apidl[i]);
1546 SHChangeNotifyA(SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);
1547 SHFree(pidl);
1548 }
1549
1550 }
1551 return S_OK;
1552}
1553
1554/****************************************************************************
1555 * ISFHelper_fnCopyItems
1556 *
1557 * copys items to this folder
1558 */
1559static HRESULT WINAPI ISFHelper_fnCopyItems(
1560 ISFHelper *iface,
1561 IShellFolder* pSFFrom,
1562 UINT cidl,
1563 LPCITEMIDLIST *apidl)
1564{
1565 int i;
1566 IPersistFolder2 * ppf2=NULL;
1567 char szSrcPath[MAX_PATH], szDstPath[MAX_PATH];
1568 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1569
1570 TRACE("(%p)->(%p,%u,%p)\n", This, pSFFrom, cidl, apidl);
1571
1572 IShellFolder_QueryInterface(pSFFrom, &IID_IPersistFolder2, (LPVOID*)&ppf2);
1573 if (ppf2)
1574 {
1575 LPITEMIDLIST pidl;
1576 if (SUCCEEDED(IPersistFolder2_GetCurFolder(ppf2, &pidl)))
1577 {
1578 for (i=0; i<cidl; i++)
1579 {
1580 SHGetPathFromIDListA(pidl, szSrcPath);
1581 PathAddBackslashA(szSrcPath);
1582 _ILSimpleGetText(apidl[i], szSrcPath+strlen(szSrcPath), MAX_PATH);
1583
1584 strcpy(szDstPath, This->sMyPath);
1585 PathAddBackslashA(szDstPath);
1586 _ILSimpleGetText(apidl[i], szDstPath+strlen(szDstPath), MAX_PATH);
1587 MESSAGE("would copy %s to %s\n", szSrcPath, szDstPath);
1588 }
1589 SHFree(pidl);
1590 }
1591 IPersistFolder2_Release(ppf2);
1592 }
1593 return S_OK;
1594}
1595
1596static ICOM_VTABLE(ISFHelper) shvt =
1597{
1598 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1599 ISFHelper_fnQueryInterface,
1600 ISFHelper_fnAddRef,
1601 ISFHelper_fnRelease,
1602 ISFHelper_fnGetUniqueName,
1603 ISFHelper_fnAddFolder,
1604 ISFHelper_fnDeleteItems,
1605 ISFHelper_fnCopyItems,
1606};
1607
1608/***********************************************************************
1609* [Desktopfolder] IShellFolder implementation
1610*/
1611static struct ICOM_VTABLE(IShellFolder2) sfdvt;
1612
1613static shvheader DesktopSFHeader [] =
1614{
1615 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
1616 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1617 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1618 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
1619 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
1620};
1621#define DESKTOPSHELLVIEWCOLUMNS 5
1622
1623/**************************************************************************
1624* ISF_Desktop_Constructor
1625*
1626*/
1627IShellFolder * ISF_Desktop_Constructor()
1628{
1629 IGenericSFImpl * sf;
1630
1631 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
1632 sf->ref=1;
1633 ICOM_VTBL(sf)=&unkvt;
1634 sf->lpvtblShellFolder=&sfdvt;
1635 sf->absPidl=_ILCreateDesktop(); /* my qualified pidl */
1636 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
1637
1638 TRACE("(%p)\n",sf);
1639
1640 shell32_ObjCount++;
1641 return _IShellFolder_(sf);
1642}
1643
1644/**************************************************************************
1645 * ISF_Desktop_fnQueryInterface
1646 *
1647 * NOTES supports not IPersist/IPersistFolder
1648 */
1649static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
1650 IShellFolder2 * iface,
1651 REFIID riid,
1652 LPVOID *ppvObj)
1653{
1654 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1655
1656 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1657
1658 *ppvObj = NULL;
1659
1660 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
1661 {
1662 *ppvObj = _IUnknown_(This);
1663 }
1664 else if(IsEqualIID(riid, &IID_IShellFolder)) /*IShellFolder*/
1665 {
1666 *ppvObj = _IShellFolder_(This);
1667 }
1668 else if(IsEqualIID(riid, &IID_IShellFolder2)) /*IShellFolder2*/
1669 {
1670 *ppvObj = _IShellFolder_(This);
1671 }
1672
1673 if(*ppvObj)
1674 {
1675 IUnknown_AddRef((IUnknown*)(*ppvObj));
1676 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1677 return S_OK;
1678 }
1679 TRACE("-- Interface: E_NOINTERFACE\n");
1680 return E_NOINTERFACE;
1681}
1682
1683/**************************************************************************
1684* ISF_Desktop_fnParseDisplayName
1685*
1686* NOTES
1687* "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
1688* to MyComputer
1689*/
1690static HRESULT WINAPI ISF_Desktop_fnParseDisplayName(
1691 IShellFolder2 * iface,
1692 HWND hwndOwner,
1693 LPBC pbcReserved,
1694 LPOLESTR lpszDisplayName,
1695 DWORD *pchEaten,
1696 LPITEMIDLIST *ppidl,
1697 DWORD *pdwAttributes)
1698{
1699 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1700
1701 LPCWSTR szNext=NULL;
1702 LPITEMIDLIST pidlTemp=NULL;
1703 HRESULT hr=E_OUTOFMEMORY;
1704
1705 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1706 This,hwndOwner,pbcReserved,lpszDisplayName,
1707 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
1708
1709 *ppidl = 0;
1710 if (pchEaten) *pchEaten = 0; /* strange but like the original */
1711
1712 /* fixme no real parsing implemented */
1713 pidlTemp = _ILCreateMyComputer();
1714 szNext = lpszDisplayName;
1715
1716 if (szNext && *szNext)
1717 {
1718 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
1719 }
1720 else
1721 {
1722 hr = S_OK;
1723
1724 if (pdwAttributes && *pdwAttributes)
1725 {
1726 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
1727 }
1728 }
1729
1730 *ppidl = pidlTemp;
1731
1732 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
1733
1734 return hr;
1735}
1736
1737/**************************************************************************
1738* ISF_Desktop_fnEnumObjects
1739*/
1740static HRESULT WINAPI ISF_Desktop_fnEnumObjects(
1741 IShellFolder2 * iface,
1742 HWND hwndOwner,
1743 DWORD dwFlags,
1744 LPENUMIDLIST* ppEnumIDList)
1745{
1746 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1747
1748 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
1749
1750 *ppEnumIDList = NULL;
1751 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_DESK);
1752
1753 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
1754
1755 if(!*ppEnumIDList) return E_OUTOFMEMORY;
1756
1757 return S_OK;
1758}
1759
1760/**************************************************************************
1761* ISF_Desktop_fnBindToObject
1762*/
1763static HRESULT WINAPI ISF_Desktop_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
1764 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
1765{
1766 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1767 GUID const * clsid;
1768 IShellFolder *pShellFolder, *pSubFolder;
1769
1770 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
1771 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
1772
1773 *ppvOut = NULL;
1774
1775 if ((clsid=_ILGetGUIDPointer(pidl)))
1776 {
1777 if ( IsEqualIID(clsid, &CLSID_MyComputer))
1778 {
1779 pShellFolder = ISF_MyComputer_Constructor();
1780 }
1781 else
1782 {
1783 /* shell extension */
1784 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
1785 {
1786 return E_INVALIDARG;
1787 }
1788 }
1789 }
1790 else
1791 {
1792 /* file system folder on the desktop */
1793 LPITEMIDLIST deskpidl, firstpidl, completepidl;
1794 IPersistFolder * ppf;
1795
1796 /* combine pidls */
1797 SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, &deskpidl);
1798 firstpidl = ILCloneFirst(pidl);
1799 completepidl = ILCombine(deskpidl, firstpidl);
1800
1801 pShellFolder = IShellFolder_Constructor(NULL, NULL);
1802 if (SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&ppf)))
1803 {
1804 IPersistFolder_Initialize(ppf, completepidl);
1805 IPersistFolder_Release(ppf);
1806 }
1807 ILFree(completepidl);
1808 ILFree(deskpidl);
1809 ILFree(firstpidl);
1810 }
1811
1812 if (_ILIsPidlSimple(pidl)) /* no sub folders */
1813 {
1814 *ppvOut = pShellFolder;
1815 }
1816 else /* go deeper */
1817 {
1818 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, riid, (LPVOID)&pSubFolder);
1819 IShellFolder_Release(pShellFolder);
1820 *ppvOut = pSubFolder;
1821 }
1822
1823 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
1824
1825 return S_OK;
1826}
1827
1828/**************************************************************************
1829* ISF_Desktop_fnCreateViewObject
1830*/
1831static HRESULT WINAPI ISF_Desktop_fnCreateViewObject( IShellFolder2 * iface,
1832 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
1833{
1834 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1835
1836 LPSHELLVIEW pShellView;
1837 HRESULT hr = E_INVALIDARG;
1838
1839 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
1840
1841 if(ppvOut)
1842 {
1843 *ppvOut = NULL;
1844
1845 if(IsEqualIID(riid, &IID_IDropTarget))
1846 {
1847 WARN("IDropTarget not implemented\n");
1848 hr = E_NOTIMPL;
1849 }
1850 else if(IsEqualIID(riid, &IID_IContextMenu))
1851 {
1852 WARN("IContextMenu not implemented\n");
1853 hr = E_NOTIMPL;
1854 }
1855 else if(IsEqualIID(riid, &IID_IShellView))
1856 {
1857 pShellView = IShellView_Constructor((IShellFolder*)iface);
1858 if(pShellView)
1859 {
1860 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
1861 IShellView_Release(pShellView);
1862 }
1863 }
1864 }
1865 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
1866 return hr;
1867}
1868
1869/**************************************************************************
1870* ISF_Desktop_fnGetAttributesOf
1871*/
1872static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf(
1873 IShellFolder2 * iface,
1874 UINT cidl,
1875 LPCITEMIDLIST *apidl,
1876 DWORD *rgfInOut)
1877{
1878 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1879
1880 HRESULT hr = S_OK;
1881
1882 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl, *rgfInOut);
1883
1884 if ( (!cidl) || (!apidl) || (!rgfInOut))
1885 return E_INVALIDARG;
1886
1887 while (cidl > 0 && *apidl)
1888 {
1889 pdump (*apidl);
1890 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
1891 apidl++;
1892 cidl--;
1893 }
1894
1895 TRACE("-- result=0x%08lx\n",*rgfInOut);
1896
1897 return hr;
1898}
1899
1900/**************************************************************************
1901* ISF_Desktop_fnGetDisplayNameOf
1902*
1903* NOTES
1904* special case: pidl = null gives desktop-name back
1905*/
1906static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf(
1907 IShellFolder2 * iface,
1908 LPCITEMIDLIST pidl,
1909 DWORD dwFlags,
1910 LPSTRRET strRet)
1911{
1912 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1913
1914 CHAR szPath[MAX_PATH]= "";
1915
1916 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1917 pdump(pidl);
1918
1919 if(!strRet) return E_INVALIDARG;
1920
1921 if(!pidl)
1922 {
1923 HCR_GetClassName(&CLSID_ShellDesktop, szPath, MAX_PATH);
1924 }
1925 else if ( _ILIsPidlSimple(pidl) )
1926 {
1927 _ILSimpleGetText(pidl, szPath, MAX_PATH);
1928 }
1929 else
1930 {
1931 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath, MAX_PATH)))
1932 return E_OUTOFMEMORY;
1933 }
1934 strRet->uType = STRRET_CSTRA;
1935 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1936
1937
1938 TRACE("-- (%p)->(%s)\n", This, szPath);
1939 return S_OK;
1940}
1941
1942static HRESULT WINAPI ISF_Desktop_fnGetDefaultSearchGUID(
1943 IShellFolder2 * iface,
1944 GUID *pguid)
1945{
1946 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1947 FIXME("(%p)\n",This);
1948 return E_NOTIMPL;
1949}
1950static HRESULT WINAPI ISF_Desktop_fnEnumSearches(
1951 IShellFolder2 * iface,
1952 IEnumExtraSearch **ppenum)
1953{
1954 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1955 FIXME("(%p)\n",This);
1956 return E_NOTIMPL;
1957}
1958static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumn(
1959 IShellFolder2 * iface,
1960 DWORD dwRes,
1961 ULONG *pSort,
1962 ULONG *pDisplay)
1963{
1964 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1965
1966 TRACE("(%p)\n",This);
1967
1968 if (pSort) *pSort = 0;
1969 if (pDisplay) *pDisplay = 0;
1970
1971 return S_OK;
1972}
1973static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumnState(
1974 IShellFolder2 * iface,
1975 UINT iColumn,
1976 DWORD *pcsFlags)
1977{
1978 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1979
1980 TRACE("(%p)\n",This);
1981
1982 if (!pcsFlags || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1983
1984 *pcsFlags = DesktopSFHeader[iColumn].pcsFlags;
1985
1986 return S_OK;
1987}
1988static HRESULT WINAPI ISF_Desktop_fnGetDetailsEx(
1989 IShellFolder2 * iface,
1990 LPCITEMIDLIST pidl,
1991 const SHCOLUMNID *pscid,
1992 VARIANT *pv)
1993{
1994 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1995 FIXME("(%p)\n",This);
1996
1997 return E_NOTIMPL;
1998}
1999static HRESULT WINAPI ISF_Desktop_fnGetDetailsOf(
2000 IShellFolder2 * iface,
2001 LPCITEMIDLIST pidl,
2002 UINT iColumn,
2003 SHELLDETAILS *psd)
2004{
2005 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2006 HRESULT hr = E_FAIL;;
2007
2008 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
2009
2010 if (!psd || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2011
2012 if (!pidl)
2013 {
2014 psd->fmt = DesktopSFHeader[iColumn].fmt;
2015 psd->cxChar = DesktopSFHeader[iColumn].cxChar;
2016 psd->str.uType = STRRET_CSTRA;
2017 LoadStringA(shell32_hInstance, DesktopSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
2018 return S_OK;
2019 }
2020 else
2021 {
2022 /* the data from the pidl */
2023 switch(iColumn)
2024 {
2025 case 0: /* name */
2026 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2027 break;
2028 case 1: /* size */
2029 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
2030 break;
2031 case 2: /* type */
2032 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2033 break;
2034 case 3: /* date */
2035 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
2036 break;
2037 case 4: /* attributes */
2038 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
2039 break;
2040 }
2041 hr = S_OK;
2042 psd->str.uType = STRRET_CSTRA;
2043 }
2044
2045 return hr;
2046}
2047static HRESULT WINAPI ISF_Desktop_fnMapNameToSCID(
2048 IShellFolder2 * iface,
2049 LPCWSTR pwszName,
2050 SHCOLUMNID *pscid)
2051{
2052 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2053 FIXME("(%p)\n",This);
2054 return E_NOTIMPL;
2055}
2056
2057static ICOM_VTABLE(IShellFolder2) sfdvt =
2058{
2059 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2060 ISF_Desktop_fnQueryInterface,
2061 IShellFolder_fnAddRef,
2062 IShellFolder_fnRelease,
2063 ISF_Desktop_fnParseDisplayName,
2064 ISF_Desktop_fnEnumObjects,
2065 ISF_Desktop_fnBindToObject,
2066 IShellFolder_fnBindToStorage,
2067 IShellFolder_fnCompareIDs,
2068 ISF_Desktop_fnCreateViewObject,
2069 ISF_Desktop_fnGetAttributesOf,
2070 IShellFolder_fnGetUIObjectOf,
2071 ISF_Desktop_fnGetDisplayNameOf,
2072 IShellFolder_fnSetNameOf,
2073
2074 /* ShellFolder2 */
2075 ISF_Desktop_fnGetDefaultSearchGUID,
2076 ISF_Desktop_fnEnumSearches,
2077 ISF_Desktop_fnGetDefaultColumn,
2078 ISF_Desktop_fnGetDefaultColumnState,
2079 ISF_Desktop_fnGetDetailsEx,
2080 ISF_Desktop_fnGetDetailsOf,
2081 ISF_Desktop_fnMapNameToSCID
2082};
2083
2084
2085/***********************************************************************
2086* IShellFolder [MyComputer] implementation
2087*/
2088
2089static struct ICOM_VTABLE(IShellFolder2) sfmcvt;
2090
2091static shvheader MyComputerSFHeader [] =
2092{
2093 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
2094 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2095 { IDS_SHV_COLUMN6, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2096 { IDS_SHV_COLUMN7, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2097};
2098#define MYCOMPUTERSHELLVIEWCOLUMNS 4
2099
2100/**************************************************************************
2101* ISF_MyComputer_Constructor
2102*/
2103static IShellFolder * ISF_MyComputer_Constructor(void)
2104{
2105 IGenericSFImpl * sf;
2106
2107 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
2108 sf->ref=1;
2109
2110 ICOM_VTBL(sf)=&unkvt;
2111 sf->lpvtblShellFolder=&sfmcvt;
2112 sf->lpvtblPersistFolder2 = &psfvt;
2113 sf->pclsid = (CLSID*)&CLSID_SFMyComp;
2114 sf->absPidl=_ILCreateMyComputer(); /* my qualified pidl */
2115 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
2116
2117 TRACE("(%p)\n",sf);
2118
2119 shell32_ObjCount++;
2120 return _IShellFolder_(sf);
2121}
2122
2123/**************************************************************************
2124* ISF_MyComputer_fnParseDisplayName
2125*/
2126static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName(
2127 IShellFolder2 * iface,
2128 HWND hwndOwner,
2129 LPBC pbcReserved,
2130 LPOLESTR lpszDisplayName,
2131 DWORD *pchEaten,
2132 LPITEMIDLIST *ppidl,
2133 DWORD *pdwAttributes)
2134{
2135 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2136
2137 HRESULT hr = E_OUTOFMEMORY;
2138 LPCWSTR szNext=NULL;
2139 WCHAR szElement[MAX_PATH];
2140 CHAR szTempA[MAX_PATH];
2141 LPITEMIDLIST pidlTemp;
2142
2143 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
2144 This,hwndOwner,pbcReserved,lpszDisplayName,
2145 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
2146
2147 *ppidl = 0;
2148 if (pchEaten) *pchEaten = 0; /* strange but like the original */
2149
2150 /* do we have an absolute path name ? */
2151 if (PathGetDriveNumberW(lpszDisplayName) >= 0 &&
2152 lpszDisplayName[2] == (WCHAR)'\\')
2153 {
2154 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
2155 WideCharToMultiByte( CP_ACP, 0, szElement, -1, szTempA, MAX_PATH, NULL, NULL );
2156 pidlTemp = _ILCreateDrive(szTempA);
2157
2158 if (szNext && *szNext)
2159 {
2160 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
2161 }
2162 else
2163 {
2164 if (pdwAttributes && *pdwAttributes)
2165 {
2166 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
2167 }
2168 hr = S_OK;
2169 }
2170 *ppidl = pidlTemp;
2171 }
2172
2173 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
2174
2175 return hr;
2176}
2177
2178/**************************************************************************
2179* ISF_MyComputer_fnEnumObjects
2180*/
2181static HRESULT WINAPI ISF_MyComputer_fnEnumObjects(
2182 IShellFolder2 * iface,
2183 HWND hwndOwner,
2184 DWORD dwFlags,
2185 LPENUMIDLIST* ppEnumIDList)
2186{
2187 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2188
2189 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
2190
2191 *ppEnumIDList = NULL;
2192 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_MYCOMP);
2193
2194 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
2195
2196 if(!*ppEnumIDList) return E_OUTOFMEMORY;
2197
2198 return S_OK;
2199}
2200
2201/**************************************************************************
2202* ISF_MyComputer_fnBindToObject
2203*/
2204static HRESULT WINAPI ISF_MyComputer_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
2205 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
2206{
2207 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2208 GUID const * clsid;
2209 IShellFolder *pShellFolder, *pSubFolder;
2210 LPITEMIDLIST pidltemp;
2211
2212 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
2213 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
2214
2215 if(!pidl || !ppvOut) return E_INVALIDARG;
2216
2217 *ppvOut = NULL;
2218
2219 if ((clsid=_ILGetGUIDPointer(pidl)) && !IsEqualIID(clsid, &CLSID_MyComputer))
2220 {
2221 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
2222 {
2223 return E_FAIL;
2224 }
2225 }
2226 else
2227 {
2228 if (!_ILIsDrive(pidl)) return E_INVALIDARG;
2229
2230 pidltemp = ILCloneFirst(pidl);
2231 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
2232 ILFree(pidltemp);
2233 }
2234
2235 if (_ILIsPidlSimple(pidl)) /* no sub folders */
2236 {
2237 *ppvOut = pShellFolder;
2238 }
2239 else /* go deeper */
2240 {
2241 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
2242 IShellFolder_Release(pShellFolder);
2243 *ppvOut = pSubFolder;
2244 }
2245
2246 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
2247
2248 return S_OK;
2249}
2250
2251/**************************************************************************
2252* ISF_MyComputer_fnCreateViewObject
2253*/
2254static HRESULT WINAPI ISF_MyComputer_fnCreateViewObject( IShellFolder2 * iface,
2255 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
2256{
2257 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2258
2259 LPSHELLVIEW pShellView;
2260 HRESULT hr = E_INVALIDARG;
2261
2262 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
2263
2264 if(ppvOut)
2265 {
2266 *ppvOut = NULL;
2267
2268 if(IsEqualIID(riid, &IID_IDropTarget))
2269 {
2270 WARN("IDropTarget not implemented\n");
2271 hr = E_NOTIMPL;
2272 }
2273 else if(IsEqualIID(riid, &IID_IContextMenu))
2274 {
2275 WARN("IContextMenu not implemented\n");
2276 hr = E_NOTIMPL;
2277 }
2278 else if(IsEqualIID(riid, &IID_IShellView))
2279 {
2280 pShellView = IShellView_Constructor((IShellFolder*)iface);
2281 if(pShellView)
2282 {
2283 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
2284 IShellView_Release(pShellView);
2285 }
2286 }
2287 }
2288 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
2289 return hr;
2290}
2291
2292/**************************************************************************
2293* ISF_MyComputer_fnGetAttributesOf
2294*/
2295static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf(
2296 IShellFolder2 * iface,
2297 UINT cidl,
2298 LPCITEMIDLIST *apidl,
2299 DWORD *rgfInOut)
2300{
2301 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2302
2303 HRESULT hr = S_OK;
2304
2305 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
2306
2307 if ( (!cidl) || (!apidl) || (!rgfInOut))
2308 return E_INVALIDARG;
2309
2310 while (cidl > 0 && *apidl)
2311 {
2312 pdump (*apidl);
2313 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
2314 apidl++;
2315 cidl--;
2316 }
2317
2318 TRACE("-- result=0x%08lx\n",*rgfInOut);
2319 return hr;
2320}
2321
2322/**************************************************************************
2323* ISF_MyComputer_fnGetDisplayNameOf
2324*
2325* NOTES
2326* The desktopfolder creates only complete paths (SHGDN_FORPARSING).
2327* SHGDN_INFOLDER makes no sense.
2328*/
2329static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf(
2330 IShellFolder2 * iface,
2331 LPCITEMIDLIST pidl,
2332 DWORD dwFlags,
2333 LPSTRRET strRet)
2334{
2335 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2336
2337 char szPath[MAX_PATH], szDrive[18];
2338 int len = 0;
2339 BOOL bSimplePidl;
2340
2341 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
2342 pdump(pidl);
2343
2344 if(!strRet) return E_INVALIDARG;
2345
2346 szPath[0]=0x00; szDrive[0]=0x00;
2347
2348
2349 bSimplePidl = _ILIsPidlSimple(pidl);
2350
2351 if (_ILIsSpecialFolder(pidl))
2352 {
2353 /* take names of special folders only if its only this folder */
2354 if ( bSimplePidl )
2355 {
2356 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2357 }
2358 }
2359 else
2360 {
2361 if (!_ILIsDrive(pidl))
2362 {
2363 ERR("Wrong pidl type\n");
2364 return E_INVALIDARG;
2365 }
2366
2367 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2368
2369 /* long view "lw_name (C:)" */
2370 if ( bSimplePidl && !(dwFlags & SHGDN_FORPARSING))
2371 {
2372 DWORD dwVolumeSerialNumber,dwMaximumComponetLength,dwFileSystemFlags;
2373
2374#ifdef __WIN32OS2__
2375//CB: floppy drives have a fixed name
2376 if ((szPath[0] == 'A') || (szPath[0] == 'a') || (szPath[0] == 'B') || (szPath[0] == 'b'))
2377 {
2378 //floppy
2379 strncpy(szDrive,szPath,2);
2380 //3.5 floppy
2381 LoadStringA(shell32_hInstance,IDS_35FLOPPY,szPath,sizeof(szPath)-10);
2382 //CB: todo: 5.25 floppy check
2383 strcat(szPath," (");
2384 strncat(szPath,szDrive,2);
2385 strcat(szPath,")");
2386 } else
2387 {
2388 GetVolumeInformationA(szPath,szDrive,12,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0);
2389 strcat (szDrive," (");
2390 strncat (szDrive, szPath, 2);
2391 strcat (szDrive,")");
2392 strcpy (szPath, szDrive);
2393 }
2394#else
2395 GetVolumeInformationA(szPath,szDrive,12,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0);
2396 strcat (szDrive," (");
2397 strncat (szDrive, szPath, 2);
2398 strcat (szDrive,")");
2399 strcpy (szPath, szDrive);
2400#endif
2401 }
2402 }
2403
2404 if (!bSimplePidl) /* go deeper if needed */
2405 {
2406 PathAddBackslashA(szPath);
2407 len = strlen(szPath);
2408
2409 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags | SHGDN_FORPARSING, szPath + len, MAX_PATH - len)))
2410 return E_OUTOFMEMORY;
2411 }
2412 strRet->uType = STRRET_CSTRA;
2413 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
2414
2415
2416 TRACE("-- (%p)->(%s)\n", This, szPath);
2417 return S_OK;
2418}
2419
2420static HRESULT WINAPI ISF_MyComputer_fnGetDefaultSearchGUID(
2421 IShellFolder2 * iface,
2422 GUID *pguid)
2423{
2424 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2425 FIXME("(%p)\n",This);
2426 return E_NOTIMPL;
2427}
2428static HRESULT WINAPI ISF_MyComputer_fnEnumSearches(
2429 IShellFolder2 * iface,
2430 IEnumExtraSearch **ppenum)
2431{
2432 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2433 FIXME("(%p)\n",This);
2434 return E_NOTIMPL;
2435}
2436static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumn(
2437 IShellFolder2 * iface,
2438 DWORD dwRes,
2439 ULONG *pSort,
2440 ULONG *pDisplay)
2441{
2442 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2443
2444 TRACE("(%p)\n",This);
2445
2446 if (pSort) *pSort = 0;
2447 if (pDisplay) *pDisplay = 0;
2448
2449 return S_OK;
2450}
2451static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumnState(
2452 IShellFolder2 * iface,
2453 UINT iColumn,
2454 DWORD *pcsFlags)
2455{
2456 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2457
2458 TRACE("(%p)\n",This);
2459
2460 if (!pcsFlags || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2461
2462 *pcsFlags = MyComputerSFHeader[iColumn].pcsFlags;
2463
2464 return S_OK;
2465}
2466static HRESULT WINAPI ISF_MyComputer_fnGetDetailsEx(
2467 IShellFolder2 * iface,
2468 LPCITEMIDLIST pidl,
2469 const SHCOLUMNID *pscid,
2470 VARIANT *pv)
2471{
2472 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2473 FIXME("(%p)\n",This);
2474
2475 return E_NOTIMPL;
2476}
2477
2478/* fixme: drive size >4GB is rolling over */
2479static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf(
2480 IShellFolder2 * iface,
2481 LPCITEMIDLIST pidl,
2482 UINT iColumn,
2483 SHELLDETAILS *psd)
2484{
2485 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2486 HRESULT hr;
2487
2488 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
2489
2490 if (!psd || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2491
2492 if (!pidl)
2493 {
2494 psd->fmt = MyComputerSFHeader[iColumn].fmt;
2495 psd->cxChar = MyComputerSFHeader[iColumn].cxChar;
2496 psd->str.uType = STRRET_CSTRA;
2497 LoadStringA(shell32_hInstance, MyComputerSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
2498 return S_OK;
2499 }
2500 else
2501 {
2502 char szPath[MAX_PATH];
2503 ULARGE_INTEGER ulBytes;
2504
2505 psd->str.u.cStr[0] = 0x00;
2506 psd->str.uType = STRRET_CSTRA;
2507 switch(iColumn)
2508 {
2509 case 0: /* name */
2510 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2511 break;
2512 case 1: /* type */
2513 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2514 break;
2515 case 2: /* total size */
2516 if (_ILIsDrive(pidl))
2517 {
2518 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2519 GetDiskFreeSpaceExA(szPath, NULL, &ulBytes, NULL);
2520 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2521 }
2522 break;
2523 case 3: /* free size */
2524 if (_ILIsDrive(pidl))
2525 {
2526 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2527 GetDiskFreeSpaceExA(szPath, &ulBytes, NULL, NULL);
2528 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2529 }
2530 break;
2531 }
2532 hr = S_OK;
2533 }
2534
2535 return hr;
2536}
2537static HRESULT WINAPI ISF_MyComputer_fnMapNameToSCID(
2538 IShellFolder2 * iface,
2539 LPCWSTR pwszName,
2540 SHCOLUMNID *pscid)
2541{
2542 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2543 FIXME("(%p)\n",This);
2544 return E_NOTIMPL;
2545}
2546
2547static ICOM_VTABLE(IShellFolder2) sfmcvt =
2548{
2549 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2550 IShellFolder_fnQueryInterface,
2551 IShellFolder_fnAddRef,
2552 IShellFolder_fnRelease,
2553 ISF_MyComputer_fnParseDisplayName,
2554 ISF_MyComputer_fnEnumObjects,
2555 ISF_MyComputer_fnBindToObject,
2556 IShellFolder_fnBindToStorage,
2557 IShellFolder_fnCompareIDs,
2558 ISF_MyComputer_fnCreateViewObject,
2559 ISF_MyComputer_fnGetAttributesOf,
2560 IShellFolder_fnGetUIObjectOf,
2561 ISF_MyComputer_fnGetDisplayNameOf,
2562 IShellFolder_fnSetNameOf,
2563
2564 /* ShellFolder2 */
2565 ISF_MyComputer_fnGetDefaultSearchGUID,
2566 ISF_MyComputer_fnEnumSearches,
2567 ISF_MyComputer_fnGetDefaultColumn,
2568 ISF_MyComputer_fnGetDefaultColumnState,
2569 ISF_MyComputer_fnGetDetailsEx,
2570 ISF_MyComputer_fnGetDetailsOf,
2571 ISF_MyComputer_fnMapNameToSCID
2572};
2573
2574
2575/************************************************************************
2576 * ISFPersistFolder_QueryInterface (IUnknown)
2577 *
2578 */
2579static HRESULT WINAPI ISFPersistFolder2_QueryInterface(
2580 IPersistFolder2 * iface,
2581 REFIID iid,
2582 LPVOID* ppvObj)
2583{
2584 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2585
2586 TRACE("(%p)\n", This);
2587
2588 return IUnknown_QueryInterface(This->pUnkOuter, iid, ppvObj);
2589}
2590
2591/************************************************************************
2592 * ISFPersistFolder_AddRef (IUnknown)
2593 *
2594 */
2595static ULONG WINAPI ISFPersistFolder2_AddRef(
2596 IPersistFolder2 * iface)
2597{
2598 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2599
2600 TRACE("(%p)\n", This);
2601
2602 return IUnknown_AddRef(This->pUnkOuter);
2603}
2604
2605/************************************************************************
2606 * ISFPersistFolder_Release (IUnknown)
2607 *
2608 */
2609static ULONG WINAPI ISFPersistFolder2_Release(
2610 IPersistFolder2 * iface)
2611{
2612 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2613
2614 TRACE("(%p)\n", This);
2615
2616 return IUnknown_Release(This->pUnkOuter);
2617}
2618
2619/************************************************************************
2620 * ISFPersistFolder_GetClassID (IPersist)
2621 */
2622static HRESULT WINAPI ISFPersistFolder2_GetClassID(
2623 IPersistFolder2 * iface,
2624 CLSID * lpClassId)
2625{
2626 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2627
2628 TRACE("(%p)\n", This);
2629
2630 if (!lpClassId) return E_POINTER;
2631 *lpClassId = *This->pclsid;
2632
2633 return S_OK;
2634}
2635
2636/************************************************************************
2637 * ISFPersistFolder_Initialize (IPersistFolder)
2638 *
2639 * NOTES
2640 * sMyPath is not set. Don't know how to handle in a non rooted environment.
2641 */
2642static HRESULT WINAPI ISFPersistFolder2_Initialize(
2643 IPersistFolder2 * iface,
2644 LPCITEMIDLIST pidl)
2645{
2646 char sTemp[MAX_PATH];
2647 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2648
2649 TRACE("(%p)->(%p)\n", This, pidl);
2650
2651 /* free the old stuff */
2652 if(This->absPidl)
2653 {
2654 SHFree(This->absPidl);
2655 This->absPidl = NULL;
2656 }
2657 if(This->sMyPath)
2658 {
2659 SHFree(This->sMyPath);
2660 This->sMyPath = NULL;
2661 }
2662
2663 /* set my pidl */
2664 This->absPidl = ILClone(pidl);
2665
2666 /* set my path */
2667 if (SHGetPathFromIDListA(pidl, sTemp))
2668 {
2669 This->sMyPath = SHAlloc(strlen(sTemp)+1);
2670 strcpy(This->sMyPath, sTemp);
2671 }
2672
2673 TRACE("--(%p)->(%s)\n", This, This->sMyPath);
2674
2675 return S_OK;
2676}
2677
2678/**************************************************************************
2679* IPersistFolder2_fnGetCurFolder
2680*/
2681static HRESULT WINAPI ISFPersistFolder2_fnGetCurFolder(
2682 IPersistFolder2 * iface,
2683 LPITEMIDLIST * pidl)
2684{
2685 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2686
2687 TRACE("(%p)->(%p)\n",This, pidl);
2688
2689 if (!pidl) return E_POINTER;
2690
2691 *pidl = ILClone(This->absPidl);
2692
2693 return S_OK;
2694}
2695
2696static ICOM_VTABLE(IPersistFolder2) psfvt =
2697{
2698 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2699 ISFPersistFolder2_QueryInterface,
2700 ISFPersistFolder2_AddRef,
2701 ISFPersistFolder2_Release,
2702 ISFPersistFolder2_GetClassID,
2703 ISFPersistFolder2_Initialize,
2704 ISFPersistFolder2_fnGetCurFolder
2705};
2706
2707/****************************************************************************
2708 * ISFDropTarget implementation
2709 */
2710static BOOL ISFDropTarget_QueryDrop(
2711 IDropTarget *iface,
2712 DWORD dwKeyState,
2713 LPDWORD pdwEffect)
2714{
2715 DWORD dwEffect = *pdwEffect;
2716
2717 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2718
2719 *pdwEffect = DROPEFFECT_NONE;
2720
2721 if (This->fAcceptFmt)
2722 { /* Does our interpretation of the keystate ... */
2723 *pdwEffect = KeyStateToDropEffect(dwKeyState);
2724
2725 /* ... matches the desired effect ? */
2726 if (dwEffect & *pdwEffect)
2727 {
2728 return TRUE;
2729 }
2730 }
2731 return FALSE;
2732}
2733
2734static HRESULT WINAPI ISFDropTarget_QueryInterface(
2735 IDropTarget *iface,
2736 REFIID riid,
2737 LPVOID *ppvObj)
2738{
2739 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2740
2741 TRACE("(%p)\n", This);
2742
2743 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
2744}
2745
2746static ULONG WINAPI ISFDropTarget_AddRef( IDropTarget *iface)
2747{
2748 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2749
2750 TRACE("(%p)\n", This);
2751
2752 return IUnknown_AddRef(This->pUnkOuter);
2753}
2754
2755static ULONG WINAPI ISFDropTarget_Release( IDropTarget *iface)
2756{
2757 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2758
2759 TRACE("(%p)\n", This);
2760
2761 return IUnknown_Release(This->pUnkOuter);
2762}
2763
2764static HRESULT WINAPI ISFDropTarget_DragEnter(
2765 IDropTarget *iface,
2766 IDataObject *pDataObject,
2767 DWORD dwKeyState,
2768 POINTL pt,
2769 DWORD *pdwEffect)
2770{
2771 FORMATETC fmt;
2772
2773 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2774
2775 TRACE("(%p)->(DataObject=%p)\n",This,pDataObject);
2776
2777 InitFormatEtc(fmt, This->cfShellIDList, TYMED_HGLOBAL);
2778
2779 This->fAcceptFmt = (S_OK == IDataObject_QueryGetData(pDataObject, &fmt)) ? TRUE : FALSE;
2780
2781 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2782
2783 return S_OK;
2784}
2785
2786static HRESULT WINAPI ISFDropTarget_DragOver(
2787 IDropTarget *iface,
2788 DWORD dwKeyState,
2789 POINTL pt,
2790 DWORD *pdwEffect)
2791{
2792 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2793
2794 TRACE("(%p)\n",This);
2795
2796 if(!pdwEffect) return E_INVALIDARG;
2797
2798 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2799
2800 return S_OK;
2801}
2802
2803static HRESULT WINAPI ISFDropTarget_DragLeave(
2804 IDropTarget *iface)
2805{
2806 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2807
2808 TRACE("(%p)\n",This);
2809
2810 This->fAcceptFmt = FALSE;
2811
2812 return S_OK;
2813}
2814
2815static HRESULT WINAPI ISFDropTarget_Drop(
2816 IDropTarget *iface,
2817 IDataObject* pDataObject,
2818 DWORD dwKeyState,
2819 POINTL pt,
2820 DWORD *pdwEffect)
2821{
2822 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2823
2824 FIXME("(%p) object dropped\n",This);
2825
2826 return E_NOTIMPL;
2827}
2828
2829static struct ICOM_VTABLE(IDropTarget) dtvt =
2830{
2831 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2832 ISFDropTarget_QueryInterface,
2833 ISFDropTarget_AddRef,
2834 ISFDropTarget_Release,
2835 ISFDropTarget_DragEnter,
2836 ISFDropTarget_DragOver,
2837 ISFDropTarget_DragLeave,
2838 ISFDropTarget_Drop
2839};
Note: See TracBrowser for help on using the repository browser.