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

Last change on this file since 6502 was 5618, checked in by sandervl, 24 years ago

resync with latest wine

File size: 71.4 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 hr = ResultFromShort(nReturn); /* two equal simple pidls */
905 }
906 }
907 else
908 {
909 hr = ResultFromShort(nReturn); /* two different simple pidls */
910 }
911 }
912 }
913
914 TRACE("-- res=0x%08lx\n", hr);
915 return hr;
916}
917
918/**************************************************************************
919* IShellFolder_fnCreateViewObject
920*/
921static HRESULT WINAPI IShellFolder_fnCreateViewObject(
922 IShellFolder2 * iface,
923 HWND hwndOwner,
924 REFIID riid,
925 LPVOID *ppvOut)
926{
927 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
928
929 LPSHELLVIEW pShellView;
930 HRESULT hr = E_INVALIDARG;
931
932 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
933
934 if(ppvOut)
935 {
936 *ppvOut = NULL;
937
938 if(IsEqualIID(riid, &IID_IDropTarget))
939 {
940 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, ppvOut);
941 }
942 else if(IsEqualIID(riid, &IID_IContextMenu))
943 {
944 FIXME("IContextMenu not implemented\n");
945 hr = E_NOTIMPL;
946 }
947 else if(IsEqualIID(riid, &IID_IShellView))
948 {
949 pShellView = IShellView_Constructor((IShellFolder*)iface);
950 if(pShellView)
951 {
952 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
953 IShellView_Release(pShellView);
954 }
955 }
956 }
957 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
958 return hr;
959}
960
961/**************************************************************************
962* IShellFolder_fnGetAttributesOf
963*
964* PARAMETERS
965* UINT cidl, //[in ] num elements in pidl array
966* LPCITEMIDLIST* apidl, //[in ] simple pidl array
967* ULONG* rgfInOut) //[out] result array
968*
969*/
970static HRESULT WINAPI IShellFolder_fnGetAttributesOf(
971 IShellFolder2 * iface,
972 UINT cidl,
973 LPCITEMIDLIST *apidl,
974 DWORD *rgfInOut)
975{
976 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
977
978 HRESULT hr = S_OK;
979
980 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
981
982 if ( (!cidl) || (!apidl) || (!rgfInOut))
983 return E_INVALIDARG;
984
985 while (cidl > 0 && *apidl)
986 {
987 pdump (*apidl);
988 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
989 apidl++;
990 cidl--;
991 }
992
993 TRACE("-- result=0x%08lx\n",*rgfInOut);
994
995 return hr;
996}
997/**************************************************************************
998* IShellFolder_fnGetUIObjectOf
999*
1000* PARAMETERS
1001* HWND hwndOwner, //[in ] Parent window for any output
1002* UINT cidl, //[in ] array size
1003* LPCITEMIDLIST* apidl, //[in ] simple pidl array
1004* REFIID riid, //[in ] Requested Interface
1005* UINT* prgfInOut, //[ ] reserved
1006* LPVOID* ppvObject) //[out] Resulting Interface
1007*
1008* NOTES
1009* This function gets asked to return "view objects" for one or more (multiple select)
1010* items:
1011* The viewobject typically is an COM object with one of the following interfaces:
1012* IExtractIcon,IDataObject,IContextMenu
1013* In order to support icon positions in the default Listview your DataObject
1014* must implement the SetData method (in addition to GetData :) - the shell passes
1015* a barely documented "Icon positions" structure to SetData when the drag starts,
1016* and GetData's it if the drop is in another explorer window that needs the positions.
1017*/
1018static HRESULT WINAPI IShellFolder_fnGetUIObjectOf(
1019 IShellFolder2 * iface,
1020 HWND hwndOwner,
1021 UINT cidl,
1022 LPCITEMIDLIST * apidl,
1023 REFIID riid,
1024 UINT * prgfInOut,
1025 LPVOID * ppvOut)
1026{
1027 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1028
1029 LPITEMIDLIST pidl;
1030 IUnknown* pObj = NULL;
1031 HRESULT hr = E_INVALIDARG;
1032
1033 TRACE("(%p)->(0x%04x,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
1034 This,hwndOwner,cidl,apidl,debugstr_guid(riid),prgfInOut,ppvOut);
1035
1036 if (ppvOut)
1037 {
1038 *ppvOut = NULL;
1039
1040 if(IsEqualIID(riid, &IID_IContextMenu) && (cidl >= 1))
1041 {
1042 pObj = (LPUNKNOWN)ISvItemCm_Constructor((IShellFolder*)iface, This->absPidl, apidl, cidl);
1043 hr = S_OK;
1044 }
1045 else if (IsEqualIID(riid, &IID_IDataObject) &&(cidl >= 1))
1046 {
1047 pObj = (LPUNKNOWN)IDataObject_Constructor (hwndOwner, This->absPidl, apidl, cidl);
1048 hr = S_OK;
1049 }
1050 else if (IsEqualIID(riid, &IID_IExtractIconA) && (cidl == 1))
1051 {
1052 pidl = ILCombine(This->absPidl,apidl[0]);
1053 pObj = (LPUNKNOWN)IExtractIconA_Constructor( pidl );
1054 SHFree(pidl);
1055 hr = S_OK;
1056 }
1057 else if (IsEqualIID(riid, &IID_IDropTarget) && (cidl >= 1))
1058 {
1059 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, (LPVOID*)&pObj);
1060 }
1061 else
1062 {
1063 hr = E_NOINTERFACE;
1064 }
1065
1066 if(!pObj)
1067 hr = E_OUTOFMEMORY;
1068
1069 *ppvOut = pObj;
1070 }
1071 TRACE("(%p)->hr=0x%08lx\n",This, hr);
1072 return hr;
1073}
1074
1075/**************************************************************************
1076* IShellFolder_fnGetDisplayNameOf
1077* Retrieves the display name for the specified file object or subfolder
1078*
1079* PARAMETERS
1080* LPCITEMIDLIST pidl, //[in ] complex pidl to item
1081* DWORD dwFlags, //[in ] SHGNO formatting flags
1082* LPSTRRET lpName) //[out] Returned display name
1083*
1084* FIXME
1085* if the name is in the pidl the ret value should be a STRRET_OFFSET
1086*/
1087#define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
1088#define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
1089
1090static HRESULT WINAPI IShellFolder_fnGetDisplayNameOf(
1091 IShellFolder2 * iface,
1092 LPCITEMIDLIST pidl,
1093 DWORD dwFlags,
1094 LPSTRRET strRet)
1095{
1096 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1097
1098 CHAR szPath[MAX_PATH]= "";
1099 int len = 0;
1100 BOOL bSimplePidl;
1101
1102 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1103 pdump(pidl);
1104
1105 if(!pidl || !strRet) return E_INVALIDARG;
1106
1107 bSimplePidl = _ILIsPidlSimple(pidl);
1108
1109 /* take names of special folders only if its only this folder */
1110 if (_ILIsSpecialFolder(pidl))
1111 {
1112 if ( bSimplePidl)
1113 {
1114 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
1115 }
1116 }
1117 else
1118 {
1119 if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) && This->sMyPath)
1120 {
1121 strcpy (szPath, This->sMyPath); /* get path to root*/
1122 PathAddBackslashA(szPath);
1123 len = strlen(szPath);
1124 }
1125 _ILSimpleGetText(pidl, szPath + len, MAX_PATH - len); /* append my own path */
1126 }
1127
1128 if ( (dwFlags & SHGDN_FORPARSING) && !bSimplePidl) /* go deeper if needed */
1129 {
1130 PathAddBackslashA(szPath);
1131 len = strlen(szPath);
1132
1133 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath + len, MAX_PATH - len)))
1134 return E_OUTOFMEMORY;
1135 }
1136 strRet->uType = STRRET_CSTRA;
1137 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1138
1139 TRACE("-- (%p)->(%s)\n", This, szPath);
1140 return S_OK;
1141}
1142
1143/**************************************************************************
1144* IShellFolder_fnSetNameOf
1145* Changes the name of a file object or subfolder, possibly changing its item
1146* identifier in the process.
1147*
1148* PARAMETERS
1149* HWND hwndOwner, //[in ] Owner window for output
1150* LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
1151* LPCOLESTR lpszName, //[in ] the items new display name
1152* DWORD dwFlags, //[in ] SHGNO formatting flags
1153* LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
1154*/
1155static HRESULT WINAPI IShellFolder_fnSetNameOf(
1156 IShellFolder2 * iface,
1157 HWND hwndOwner,
1158 LPCITEMIDLIST pidl, /*simple pidl*/
1159 LPCOLESTR lpName,
1160 DWORD dwFlags,
1161 LPITEMIDLIST *pPidlOut)
1162{
1163 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1164 char szSrc[MAX_PATH], szDest[MAX_PATH];
1165 int len;
1166 BOOL bIsFolder = _ILIsFolder(ILFindLastID(pidl));
1167
1168 TRACE("(%p)->(%u,pidl=%p,%s,%lu,%p)\n",
1169 This,hwndOwner,pidl,debugstr_w(lpName),dwFlags,pPidlOut);
1170
1171 /* build source path */
1172 if (dwFlags & SHGDN_INFOLDER)
1173 {
1174 strcpy(szSrc, This->sMyPath);
1175 PathAddBackslashA(szSrc);
1176 len = strlen (szSrc);
1177 _ILSimpleGetText(pidl, szSrc+len, MAX_PATH-len);
1178 }
1179 else
1180 {
1181 SHGetPathFromIDListA(pidl, szSrc);
1182 }
1183
1184 /* build destination path */
1185 strcpy(szDest, This->sMyPath);
1186 PathAddBackslashA(szDest);
1187 len = strlen (szDest);
1188 WideCharToMultiByte( CP_ACP, 0, lpName, -1, szDest+len, MAX_PATH-len, NULL, NULL );
1189 szDest[MAX_PATH-1] = 0;
1190 TRACE("src=%s dest=%s\n", szSrc, szDest);
1191 if ( MoveFileA(szSrc, szDest) )
1192 {
1193 if (pPidlOut) *pPidlOut = SHSimpleIDListFromPathA(szDest);
1194 SHChangeNotifyA( bIsFolder?SHCNE_RENAMEFOLDER:SHCNE_RENAMEITEM, SHCNF_PATHA, szSrc, szDest);
1195 return S_OK;
1196 }
1197 return E_FAIL;
1198}
1199
1200static HRESULT WINAPI IShellFolder_fnGetDefaultSearchGUID(
1201 IShellFolder2 * iface,
1202 GUID *pguid)
1203{
1204 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1205 FIXME("(%p)\n",This);
1206 return E_NOTIMPL;
1207}
1208static HRESULT WINAPI IShellFolder_fnEnumSearches(
1209 IShellFolder2 * iface,
1210 IEnumExtraSearch **ppenum)
1211{
1212 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1213 FIXME("(%p)\n",This);
1214 return E_NOTIMPL;
1215}
1216static HRESULT WINAPI IShellFolder_fnGetDefaultColumn(
1217 IShellFolder2 * iface,
1218 DWORD dwRes,
1219 ULONG *pSort,
1220 ULONG *pDisplay)
1221{
1222 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1223
1224 TRACE("(%p)\n",This);
1225
1226 if (pSort) *pSort = 0;
1227 if (pDisplay) *pDisplay = 0;
1228
1229 return S_OK;
1230}
1231static HRESULT WINAPI IShellFolder_fnGetDefaultColumnState(
1232 IShellFolder2 * iface,
1233 UINT iColumn,
1234 DWORD *pcsFlags)
1235{
1236 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1237
1238 TRACE("(%p)\n",This);
1239
1240 if (!pcsFlags || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1241
1242 *pcsFlags = GenericSFHeader[iColumn].pcsFlags;
1243
1244 return S_OK;
1245}
1246static HRESULT WINAPI IShellFolder_fnGetDetailsEx(
1247 IShellFolder2 * iface,
1248 LPCITEMIDLIST pidl,
1249 const SHCOLUMNID *pscid,
1250 VARIANT *pv)
1251{
1252 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1253 FIXME("(%p)\n",This);
1254
1255 return E_NOTIMPL;
1256}
1257static HRESULT WINAPI IShellFolder_fnGetDetailsOf(
1258 IShellFolder2 * iface,
1259 LPCITEMIDLIST pidl,
1260 UINT iColumn,
1261 SHELLDETAILS *psd)
1262{
1263 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1264 HRESULT hr = E_FAIL;
1265
1266 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
1267
1268 if (!psd || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1269
1270 if (!pidl)
1271 {
1272 /* the header titles */
1273 psd->fmt = GenericSFHeader[iColumn].fmt;
1274 psd->cxChar = GenericSFHeader[iColumn].cxChar;
1275 psd->str.uType = STRRET_CSTRA;
1276 LoadStringA(shell32_hInstance, GenericSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
1277 return S_OK;
1278 }
1279 else
1280 {
1281 /* the data from the pidl */
1282 switch(iColumn)
1283 {
1284 case 0: /* name */
1285 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
1286 break;
1287 case 1: /* size */
1288 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
1289 break;
1290 case 2: /* type */
1291 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
1292 break;
1293 case 3: /* date */
1294 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
1295 break;
1296 case 4: /* attributes */
1297 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
1298 break;
1299 }
1300 hr = S_OK;
1301 psd->str.uType = STRRET_CSTRA;
1302 }
1303
1304 return hr;
1305}
1306static HRESULT WINAPI IShellFolder_fnMapNameToSCID(
1307 IShellFolder2 * iface,
1308 LPCWSTR pwszName,
1309 SHCOLUMNID *pscid)
1310{
1311 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1312 FIXME("(%p)\n",This);
1313 return E_NOTIMPL;
1314}
1315
1316static ICOM_VTABLE(IShellFolder2) sfvt =
1317{
1318 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1319 IShellFolder_fnQueryInterface,
1320 IShellFolder_fnAddRef,
1321 IShellFolder_fnRelease,
1322 IShellFolder_fnParseDisplayName,
1323 IShellFolder_fnEnumObjects,
1324 IShellFolder_fnBindToObject,
1325 IShellFolder_fnBindToStorage,
1326 IShellFolder_fnCompareIDs,
1327 IShellFolder_fnCreateViewObject,
1328 IShellFolder_fnGetAttributesOf,
1329 IShellFolder_fnGetUIObjectOf,
1330 IShellFolder_fnGetDisplayNameOf,
1331 IShellFolder_fnSetNameOf,
1332
1333 /* ShellFolder2 */
1334 IShellFolder_fnGetDefaultSearchGUID,
1335 IShellFolder_fnEnumSearches,
1336 IShellFolder_fnGetDefaultColumn,
1337 IShellFolder_fnGetDefaultColumnState,
1338 IShellFolder_fnGetDetailsEx,
1339 IShellFolder_fnGetDetailsOf,
1340 IShellFolder_fnMapNameToSCID
1341};
1342
1343/****************************************************************************
1344 * ISFHelper for IShellFolder implementation
1345 */
1346
1347static HRESULT WINAPI ISFHelper_fnQueryInterface(
1348 ISFHelper *iface,
1349 REFIID riid,
1350 LPVOID *ppvObj)
1351{
1352 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1353
1354 TRACE("(%p)\n", This);
1355
1356 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
1357}
1358
1359static ULONG WINAPI ISFHelper_fnAddRef(
1360 ISFHelper *iface)
1361{
1362 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1363
1364 TRACE("(%p)\n", This);
1365
1366 return IUnknown_AddRef(This->pUnkOuter);
1367}
1368
1369static ULONG WINAPI ISFHelper_fnRelease(
1370 ISFHelper *iface)
1371{
1372 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1373
1374 TRACE("(%p)\n", This);
1375
1376 return IUnknown_Release(This->pUnkOuter);
1377}
1378
1379
1380/****************************************************************************
1381 * ISFHelper_fnAddFolder
1382 *
1383 * creates a unique folder name
1384 */
1385
1386static HRESULT WINAPI ISFHelper_fnGetUniqueName(
1387 ISFHelper *iface,
1388 LPSTR lpName,
1389 UINT uLen)
1390{
1391 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1392 IEnumIDList * penum;
1393 HRESULT hr;
1394 char szText[MAX_PATH];
1395 char * szNewFolder = "New Folder";
1396
1397 TRACE("(%p)(%s %u)\n", This, lpName, uLen);
1398
1399 if (uLen < strlen(szNewFolder) + 4) return E_POINTER;
1400
1401 strcpy(lpName, szNewFolder);
1402
1403 hr = IShellFolder_fnEnumObjects(_IShellFolder2_(This), 0, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penum);
1404 if (penum)
1405 {
1406 LPITEMIDLIST pidl;
1407 DWORD dwFetched;
1408 int i=1;
1409
1410next: IEnumIDList_Reset(penum);
1411 while(S_OK == IEnumIDList_Next(penum, 1, &pidl, &dwFetched) && dwFetched)
1412 {
1413 _ILSimpleGetText(pidl, szText, MAX_PATH);
1414 if (0 == strcasecmp(szText, lpName))
1415 {
1416 sprintf(lpName, "%s %d", szNewFolder, i++);
1417 if (i > 99)
1418 {
1419 hr = E_FAIL;
1420 break;
1421 }
1422 goto next;
1423 }
1424 }
1425
1426 IEnumIDList_Release(penum);
1427 }
1428 return hr;
1429}
1430
1431/****************************************************************************
1432 * ISFHelper_fnAddFolder
1433 *
1434 * adds a new folder.
1435 */
1436
1437static HRESULT WINAPI ISFHelper_fnAddFolder(
1438 ISFHelper *iface,
1439 HWND hwnd,
1440 LPCSTR lpName,
1441 LPITEMIDLIST* ppidlOut)
1442{
1443 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1444 char lpstrNewDir[MAX_PATH];
1445 DWORD bRes;
1446 HRESULT hres = E_FAIL;
1447
1448 TRACE("(%p)(%s %p)\n", This, lpName, ppidlOut);
1449
1450 strcpy(lpstrNewDir, This->sMyPath);
1451 PathAddBackslashA(lpstrNewDir);
1452 strcat(lpstrNewDir, lpName);
1453
1454 bRes = CreateDirectoryA(lpstrNewDir, NULL);
1455
1456 if (bRes)
1457 {
1458 LPITEMIDLIST pidl, pidlitem;
1459
1460 pidlitem = SHSimpleIDListFromPathA(lpstrNewDir);
1461
1462 pidl = ILCombine(This->absPidl, pidlitem);
1463 SHChangeNotifyA(SHCNE_MKDIR, SHCNF_IDLIST, pidl, NULL);
1464 SHFree(pidl);
1465
1466 if (ppidlOut) *ppidlOut = pidlitem;
1467 hres = S_OK;
1468 }
1469 else
1470 {
1471 char lpstrText[128+MAX_PATH];
1472 char lpstrTempText[128];
1473 char lpstrCaption[256];
1474
1475 /* Cannot Create folder because of permissions */
1476 LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_DENIED, lpstrTempText, sizeof(lpstrTempText));
1477 LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_CAPTION, lpstrCaption, sizeof(lpstrCaption));
1478 sprintf(lpstrText,lpstrTempText, lpstrNewDir);
1479 MessageBoxA(hwnd,lpstrText, lpstrCaption, MB_OK | MB_ICONEXCLAMATION);
1480 }
1481
1482 return hres;
1483}
1484
1485/****************************************************************************
1486 * ISFHelper_fnDeleteItems
1487 *
1488 * deletes items in folder
1489 */
1490static HRESULT WINAPI ISFHelper_fnDeleteItems(
1491 ISFHelper *iface,
1492 UINT cidl,
1493 LPCITEMIDLIST* apidl)
1494{
1495 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1496 int i;
1497 char szPath[MAX_PATH];
1498 BOOL bConfirm = TRUE;
1499
1500 TRACE("(%p)(%u %p)\n", This, cidl, apidl);
1501
1502 /* deleting multiple items so give a slightly different warning */
1503 if(cidl != 1)
1504 {
1505 char tmp[8];
1506 snprintf(tmp, sizeof(tmp), "%d", cidl);
1507 if(!SHELL_WarnItemDelete(ASK_DELETE_MULTIPLE_ITEM, tmp))
1508 return E_FAIL;
1509 bConfirm = FALSE;
1510 }
1511
1512 for(i=0; i< cidl; i++)
1513 {
1514 strcpy(szPath, This->sMyPath);
1515 PathAddBackslashA(szPath);
1516 _ILSimpleGetText(apidl[i], szPath+strlen(szPath), MAX_PATH);
1517
1518 if (_ILIsFolder(apidl[i]))
1519 {
1520 LPITEMIDLIST pidl;
1521 TRACE("delete %s\n", szPath);
1522 if (! SHELL_DeleteDirectoryA(szPath, bConfirm))
1523 {
1524 TRACE("delete %s failed, bConfirm=%d", szPath, bConfirm);
1525 return E_FAIL;
1526 }
1527 pidl = ILCombine(This->absPidl, apidl[i]);
1528 SHChangeNotifyA(SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);
1529 SHFree(pidl);
1530 }
1531 else if (_ILIsValue(apidl[i]))
1532 {
1533 LPITEMIDLIST pidl;
1534
1535 TRACE("delete %s\n", szPath);
1536 if (! SHELL_DeleteFileA(szPath, bConfirm))
1537 {
1538 TRACE("delete %s failed, bConfirm=%d", szPath, bConfirm);
1539 return E_FAIL;
1540 }
1541 pidl = ILCombine(This->absPidl, apidl[i]);
1542 SHChangeNotifyA(SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);
1543 SHFree(pidl);
1544 }
1545
1546 }
1547 return S_OK;
1548}
1549
1550/****************************************************************************
1551 * ISFHelper_fnCopyItems
1552 *
1553 * copys items to this folder
1554 */
1555static HRESULT WINAPI ISFHelper_fnCopyItems(
1556 ISFHelper *iface,
1557 IShellFolder* pSFFrom,
1558 UINT cidl,
1559 LPCITEMIDLIST *apidl)
1560{
1561 int i;
1562 IPersistFolder2 * ppf2=NULL;
1563 char szSrcPath[MAX_PATH], szDstPath[MAX_PATH];
1564 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1565
1566 TRACE("(%p)->(%p,%u,%p)\n", This, pSFFrom, cidl, apidl);
1567
1568 IShellFolder_QueryInterface(pSFFrom, &IID_IPersistFolder2, (LPVOID*)&ppf2);
1569 if (ppf2)
1570 {
1571 LPITEMIDLIST pidl;
1572 if (SUCCEEDED(IPersistFolder2_GetCurFolder(ppf2, &pidl)))
1573 {
1574 for (i=0; i<cidl; i++)
1575 {
1576 SHGetPathFromIDListA(pidl, szSrcPath);
1577 PathAddBackslashA(szSrcPath);
1578 _ILSimpleGetText(apidl[i], szSrcPath+strlen(szSrcPath), MAX_PATH);
1579
1580 strcpy(szDstPath, This->sMyPath);
1581 PathAddBackslashA(szDstPath);
1582 _ILSimpleGetText(apidl[i], szDstPath+strlen(szDstPath), MAX_PATH);
1583 MESSAGE("would copy %s to %s\n", szSrcPath, szDstPath);
1584 }
1585 SHFree(pidl);
1586 }
1587 IPersistFolder2_Release(ppf2);
1588 }
1589 return S_OK;
1590}
1591
1592static ICOM_VTABLE(ISFHelper) shvt =
1593{
1594 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1595 ISFHelper_fnQueryInterface,
1596 ISFHelper_fnAddRef,
1597 ISFHelper_fnRelease,
1598 ISFHelper_fnGetUniqueName,
1599 ISFHelper_fnAddFolder,
1600 ISFHelper_fnDeleteItems,
1601 ISFHelper_fnCopyItems,
1602};
1603
1604/***********************************************************************
1605* [Desktopfolder] IShellFolder implementation
1606*/
1607static struct ICOM_VTABLE(IShellFolder2) sfdvt;
1608
1609static shvheader DesktopSFHeader [] =
1610{
1611 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
1612 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1613 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1614 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
1615 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
1616};
1617#define DESKTOPSHELLVIEWCOLUMNS 5
1618
1619/**************************************************************************
1620* ISF_Desktop_Constructor
1621*
1622*/
1623IShellFolder * ISF_Desktop_Constructor()
1624{
1625 IGenericSFImpl * sf;
1626
1627 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
1628 sf->ref=1;
1629 ICOM_VTBL(sf)=&unkvt;
1630 sf->lpvtblShellFolder=&sfdvt;
1631 sf->absPidl=_ILCreateDesktop(); /* my qualified pidl */
1632 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
1633
1634 TRACE("(%p)\n",sf);
1635
1636 shell32_ObjCount++;
1637 return _IShellFolder_(sf);
1638}
1639
1640/**************************************************************************
1641 * ISF_Desktop_fnQueryInterface
1642 *
1643 * NOTES supports not IPersist/IPersistFolder
1644 */
1645static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
1646 IShellFolder2 * iface,
1647 REFIID riid,
1648 LPVOID *ppvObj)
1649{
1650 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1651
1652 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1653
1654 *ppvObj = NULL;
1655
1656 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
1657 {
1658 *ppvObj = _IUnknown_(This);
1659 }
1660 else if(IsEqualIID(riid, &IID_IShellFolder)) /*IShellFolder*/
1661 {
1662 *ppvObj = _IShellFolder_(This);
1663 }
1664 else if(IsEqualIID(riid, &IID_IShellFolder2)) /*IShellFolder2*/
1665 {
1666 *ppvObj = _IShellFolder_(This);
1667 }
1668
1669 if(*ppvObj)
1670 {
1671 IUnknown_AddRef((IUnknown*)(*ppvObj));
1672 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1673 return S_OK;
1674 }
1675 TRACE("-- Interface: E_NOINTERFACE\n");
1676 return E_NOINTERFACE;
1677}
1678
1679/**************************************************************************
1680* ISF_Desktop_fnParseDisplayName
1681*
1682* NOTES
1683* "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
1684* to MyComputer
1685*/
1686static HRESULT WINAPI ISF_Desktop_fnParseDisplayName(
1687 IShellFolder2 * iface,
1688 HWND hwndOwner,
1689 LPBC pbcReserved,
1690 LPOLESTR lpszDisplayName,
1691 DWORD *pchEaten,
1692 LPITEMIDLIST *ppidl,
1693 DWORD *pdwAttributes)
1694{
1695 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1696
1697 LPCWSTR szNext=NULL;
1698 LPITEMIDLIST pidlTemp=NULL;
1699 HRESULT hr=E_OUTOFMEMORY;
1700
1701 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1702 This,hwndOwner,pbcReserved,lpszDisplayName,
1703 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
1704
1705 *ppidl = 0;
1706 if (pchEaten) *pchEaten = 0; /* strange but like the original */
1707
1708 /* fixme no real parsing implemented */
1709 pidlTemp = _ILCreateMyComputer();
1710 szNext = lpszDisplayName;
1711
1712 if (szNext && *szNext)
1713 {
1714 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
1715 }
1716 else
1717 {
1718 hr = S_OK;
1719
1720 if (pdwAttributes && *pdwAttributes)
1721 {
1722 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
1723 }
1724 }
1725
1726 *ppidl = pidlTemp;
1727
1728 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
1729
1730 return hr;
1731}
1732
1733/**************************************************************************
1734* ISF_Desktop_fnEnumObjects
1735*/
1736static HRESULT WINAPI ISF_Desktop_fnEnumObjects(
1737 IShellFolder2 * iface,
1738 HWND hwndOwner,
1739 DWORD dwFlags,
1740 LPENUMIDLIST* ppEnumIDList)
1741{
1742 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1743
1744 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
1745
1746 *ppEnumIDList = NULL;
1747 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_DESK);
1748
1749 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
1750
1751 if(!*ppEnumIDList) return E_OUTOFMEMORY;
1752
1753 return S_OK;
1754}
1755
1756/**************************************************************************
1757* ISF_Desktop_fnBindToObject
1758*/
1759static HRESULT WINAPI ISF_Desktop_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
1760 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
1761{
1762 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1763 GUID const * clsid;
1764 IShellFolder *pShellFolder, *pSubFolder;
1765
1766 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
1767 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
1768
1769 *ppvOut = NULL;
1770
1771 if ((clsid=_ILGetGUIDPointer(pidl)))
1772 {
1773 if ( IsEqualIID(clsid, &CLSID_MyComputer))
1774 {
1775 pShellFolder = ISF_MyComputer_Constructor();
1776 }
1777 else
1778 {
1779 /* shell extension */
1780 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
1781 {
1782 return E_INVALIDARG;
1783 }
1784 }
1785 }
1786 else
1787 {
1788 /* file system folder on the desktop */
1789 LPITEMIDLIST deskpidl, firstpidl, completepidl;
1790 IPersistFolder * ppf;
1791
1792 /* combine pidls */
1793 SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, &deskpidl);
1794 firstpidl = ILCloneFirst(pidl);
1795 completepidl = ILCombine(deskpidl, firstpidl);
1796
1797 pShellFolder = IShellFolder_Constructor(NULL, NULL);
1798 if (SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&ppf)))
1799 {
1800 IPersistFolder_Initialize(ppf, completepidl);
1801 IPersistFolder_Release(ppf);
1802 }
1803 ILFree(completepidl);
1804 ILFree(deskpidl);
1805 ILFree(firstpidl);
1806 }
1807
1808 if (_ILIsPidlSimple(pidl)) /* no sub folders */
1809 {
1810 *ppvOut = pShellFolder;
1811 }
1812 else /* go deeper */
1813 {
1814 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, riid, (LPVOID)&pSubFolder);
1815 IShellFolder_Release(pShellFolder);
1816 *ppvOut = pSubFolder;
1817 }
1818
1819 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
1820
1821 return S_OK;
1822}
1823
1824/**************************************************************************
1825* ISF_Desktop_fnCreateViewObject
1826*/
1827static HRESULT WINAPI ISF_Desktop_fnCreateViewObject( IShellFolder2 * iface,
1828 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
1829{
1830 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1831
1832 LPSHELLVIEW pShellView;
1833 HRESULT hr = E_INVALIDARG;
1834
1835 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
1836
1837 if(ppvOut)
1838 {
1839 *ppvOut = NULL;
1840
1841 if(IsEqualIID(riid, &IID_IDropTarget))
1842 {
1843 WARN("IDropTarget not implemented\n");
1844 hr = E_NOTIMPL;
1845 }
1846 else if(IsEqualIID(riid, &IID_IContextMenu))
1847 {
1848 WARN("IContextMenu not implemented\n");
1849 hr = E_NOTIMPL;
1850 }
1851 else if(IsEqualIID(riid, &IID_IShellView))
1852 {
1853 pShellView = IShellView_Constructor((IShellFolder*)iface);
1854 if(pShellView)
1855 {
1856 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
1857 IShellView_Release(pShellView);
1858 }
1859 }
1860 }
1861 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
1862 return hr;
1863}
1864
1865/**************************************************************************
1866* ISF_Desktop_fnGetAttributesOf
1867*/
1868static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf(
1869 IShellFolder2 * iface,
1870 UINT cidl,
1871 LPCITEMIDLIST *apidl,
1872 DWORD *rgfInOut)
1873{
1874 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1875
1876 HRESULT hr = S_OK;
1877
1878 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl, *rgfInOut);
1879
1880 if ( (!cidl) || (!apidl) || (!rgfInOut))
1881 return E_INVALIDARG;
1882
1883 while (cidl > 0 && *apidl)
1884 {
1885 pdump (*apidl);
1886 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
1887 apidl++;
1888 cidl--;
1889 }
1890
1891 TRACE("-- result=0x%08lx\n",*rgfInOut);
1892
1893 return hr;
1894}
1895
1896/**************************************************************************
1897* ISF_Desktop_fnGetDisplayNameOf
1898*
1899* NOTES
1900* special case: pidl = null gives desktop-name back
1901*/
1902static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf(
1903 IShellFolder2 * iface,
1904 LPCITEMIDLIST pidl,
1905 DWORD dwFlags,
1906 LPSTRRET strRet)
1907{
1908 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1909
1910 CHAR szPath[MAX_PATH]= "";
1911
1912 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1913 pdump(pidl);
1914
1915 if(!strRet) return E_INVALIDARG;
1916
1917 if(!pidl)
1918 {
1919 HCR_GetClassName(&CLSID_ShellDesktop, szPath, MAX_PATH);
1920 }
1921 else if ( _ILIsPidlSimple(pidl) )
1922 {
1923 _ILSimpleGetText(pidl, szPath, MAX_PATH);
1924 }
1925 else
1926 {
1927 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath, MAX_PATH)))
1928 return E_OUTOFMEMORY;
1929 }
1930 strRet->uType = STRRET_CSTRA;
1931 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1932
1933
1934 TRACE("-- (%p)->(%s)\n", This, szPath);
1935 return S_OK;
1936}
1937
1938static HRESULT WINAPI ISF_Desktop_fnGetDefaultSearchGUID(
1939 IShellFolder2 * iface,
1940 GUID *pguid)
1941{
1942 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1943 FIXME("(%p)\n",This);
1944 return E_NOTIMPL;
1945}
1946static HRESULT WINAPI ISF_Desktop_fnEnumSearches(
1947 IShellFolder2 * iface,
1948 IEnumExtraSearch **ppenum)
1949{
1950 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1951 FIXME("(%p)\n",This);
1952 return E_NOTIMPL;
1953}
1954static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumn(
1955 IShellFolder2 * iface,
1956 DWORD dwRes,
1957 ULONG *pSort,
1958 ULONG *pDisplay)
1959{
1960 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1961
1962 TRACE("(%p)\n",This);
1963
1964 if (pSort) *pSort = 0;
1965 if (pDisplay) *pDisplay = 0;
1966
1967 return S_OK;
1968}
1969static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumnState(
1970 IShellFolder2 * iface,
1971 UINT iColumn,
1972 DWORD *pcsFlags)
1973{
1974 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1975
1976 TRACE("(%p)\n",This);
1977
1978 if (!pcsFlags || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1979
1980 *pcsFlags = DesktopSFHeader[iColumn].pcsFlags;
1981
1982 return S_OK;
1983}
1984static HRESULT WINAPI ISF_Desktop_fnGetDetailsEx(
1985 IShellFolder2 * iface,
1986 LPCITEMIDLIST pidl,
1987 const SHCOLUMNID *pscid,
1988 VARIANT *pv)
1989{
1990 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1991 FIXME("(%p)\n",This);
1992
1993 return E_NOTIMPL;
1994}
1995static HRESULT WINAPI ISF_Desktop_fnGetDetailsOf(
1996 IShellFolder2 * iface,
1997 LPCITEMIDLIST pidl,
1998 UINT iColumn,
1999 SHELLDETAILS *psd)
2000{
2001 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2002 HRESULT hr = E_FAIL;;
2003
2004 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
2005
2006 if (!psd || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2007
2008 if (!pidl)
2009 {
2010 psd->fmt = DesktopSFHeader[iColumn].fmt;
2011 psd->cxChar = DesktopSFHeader[iColumn].cxChar;
2012 psd->str.uType = STRRET_CSTRA;
2013 LoadStringA(shell32_hInstance, DesktopSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
2014 return S_OK;
2015 }
2016 else
2017 {
2018 /* the data from the pidl */
2019 switch(iColumn)
2020 {
2021 case 0: /* name */
2022 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2023 break;
2024 case 1: /* size */
2025 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
2026 break;
2027 case 2: /* type */
2028 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2029 break;
2030 case 3: /* date */
2031 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
2032 break;
2033 case 4: /* attributes */
2034 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
2035 break;
2036 }
2037 hr = S_OK;
2038 psd->str.uType = STRRET_CSTRA;
2039 }
2040
2041 return hr;
2042}
2043static HRESULT WINAPI ISF_Desktop_fnMapNameToSCID(
2044 IShellFolder2 * iface,
2045 LPCWSTR pwszName,
2046 SHCOLUMNID *pscid)
2047{
2048 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2049 FIXME("(%p)\n",This);
2050 return E_NOTIMPL;
2051}
2052
2053static ICOM_VTABLE(IShellFolder2) sfdvt =
2054{
2055 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2056 ISF_Desktop_fnQueryInterface,
2057 IShellFolder_fnAddRef,
2058 IShellFolder_fnRelease,
2059 ISF_Desktop_fnParseDisplayName,
2060 ISF_Desktop_fnEnumObjects,
2061 ISF_Desktop_fnBindToObject,
2062 IShellFolder_fnBindToStorage,
2063 IShellFolder_fnCompareIDs,
2064 ISF_Desktop_fnCreateViewObject,
2065 ISF_Desktop_fnGetAttributesOf,
2066 IShellFolder_fnGetUIObjectOf,
2067 ISF_Desktop_fnGetDisplayNameOf,
2068 IShellFolder_fnSetNameOf,
2069
2070 /* ShellFolder2 */
2071 ISF_Desktop_fnGetDefaultSearchGUID,
2072 ISF_Desktop_fnEnumSearches,
2073 ISF_Desktop_fnGetDefaultColumn,
2074 ISF_Desktop_fnGetDefaultColumnState,
2075 ISF_Desktop_fnGetDetailsEx,
2076 ISF_Desktop_fnGetDetailsOf,
2077 ISF_Desktop_fnMapNameToSCID
2078};
2079
2080
2081/***********************************************************************
2082* IShellFolder [MyComputer] implementation
2083*/
2084
2085static struct ICOM_VTABLE(IShellFolder2) sfmcvt;
2086
2087static shvheader MyComputerSFHeader [] =
2088{
2089 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
2090 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2091 { IDS_SHV_COLUMN6, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2092 { IDS_SHV_COLUMN7, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2093};
2094#define MYCOMPUTERSHELLVIEWCOLUMNS 4
2095
2096/**************************************************************************
2097* ISF_MyComputer_Constructor
2098*/
2099static IShellFolder * ISF_MyComputer_Constructor(void)
2100{
2101 IGenericSFImpl * sf;
2102
2103 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
2104 sf->ref=1;
2105
2106 ICOM_VTBL(sf)=&unkvt;
2107 sf->lpvtblShellFolder=&sfmcvt;
2108 sf->lpvtblPersistFolder2 = &psfvt;
2109 sf->pclsid = (CLSID*)&CLSID_SFMyComp;
2110 sf->absPidl=_ILCreateMyComputer(); /* my qualified pidl */
2111 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
2112
2113 TRACE("(%p)\n",sf);
2114
2115 shell32_ObjCount++;
2116 return _IShellFolder_(sf);
2117}
2118
2119/**************************************************************************
2120* ISF_MyComputer_fnParseDisplayName
2121*/
2122static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName(
2123 IShellFolder2 * iface,
2124 HWND hwndOwner,
2125 LPBC pbcReserved,
2126 LPOLESTR lpszDisplayName,
2127 DWORD *pchEaten,
2128 LPITEMIDLIST *ppidl,
2129 DWORD *pdwAttributes)
2130{
2131 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2132
2133 HRESULT hr = E_OUTOFMEMORY;
2134 LPCWSTR szNext=NULL;
2135 WCHAR szElement[MAX_PATH];
2136 CHAR szTempA[MAX_PATH];
2137 LPITEMIDLIST pidlTemp;
2138
2139 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
2140 This,hwndOwner,pbcReserved,lpszDisplayName,
2141 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
2142
2143 *ppidl = 0;
2144 if (pchEaten) *pchEaten = 0; /* strange but like the original */
2145
2146 /* do we have an absolute path name ? */
2147 if (PathGetDriveNumberW(lpszDisplayName) >= 0 &&
2148 lpszDisplayName[2] == (WCHAR)'\\')
2149 {
2150 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
2151 WideCharToMultiByte( CP_ACP, 0, szElement, -1, szTempA, MAX_PATH, NULL, NULL );
2152 pidlTemp = _ILCreateDrive(szTempA);
2153
2154 if (szNext && *szNext)
2155 {
2156 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
2157 }
2158 else
2159 {
2160 if (pdwAttributes && *pdwAttributes)
2161 {
2162 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
2163 }
2164 hr = S_OK;
2165 }
2166 *ppidl = pidlTemp;
2167 }
2168
2169 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
2170
2171 return hr;
2172}
2173
2174/**************************************************************************
2175* ISF_MyComputer_fnEnumObjects
2176*/
2177static HRESULT WINAPI ISF_MyComputer_fnEnumObjects(
2178 IShellFolder2 * iface,
2179 HWND hwndOwner,
2180 DWORD dwFlags,
2181 LPENUMIDLIST* ppEnumIDList)
2182{
2183 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2184
2185 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
2186
2187 *ppEnumIDList = NULL;
2188 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_MYCOMP);
2189
2190 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
2191
2192 if(!*ppEnumIDList) return E_OUTOFMEMORY;
2193
2194 return S_OK;
2195}
2196
2197/**************************************************************************
2198* ISF_MyComputer_fnBindToObject
2199*/
2200static HRESULT WINAPI ISF_MyComputer_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
2201 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
2202{
2203 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2204 GUID const * clsid;
2205 IShellFolder *pShellFolder, *pSubFolder;
2206 LPITEMIDLIST pidltemp;
2207
2208 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
2209 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
2210
2211 if(!pidl || !ppvOut) return E_INVALIDARG;
2212
2213 *ppvOut = NULL;
2214
2215 if ((clsid=_ILGetGUIDPointer(pidl)) && !IsEqualIID(clsid, &CLSID_MyComputer))
2216 {
2217 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
2218 {
2219 return E_FAIL;
2220 }
2221 }
2222 else
2223 {
2224 if (!_ILIsDrive(pidl)) return E_INVALIDARG;
2225
2226 pidltemp = ILCloneFirst(pidl);
2227 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
2228 ILFree(pidltemp);
2229 }
2230
2231 if (_ILIsPidlSimple(pidl)) /* no sub folders */
2232 {
2233 *ppvOut = pShellFolder;
2234 }
2235 else /* go deeper */
2236 {
2237 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
2238 IShellFolder_Release(pShellFolder);
2239 *ppvOut = pSubFolder;
2240 }
2241
2242 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
2243
2244 return S_OK;
2245}
2246
2247/**************************************************************************
2248* ISF_MyComputer_fnCreateViewObject
2249*/
2250static HRESULT WINAPI ISF_MyComputer_fnCreateViewObject( IShellFolder2 * iface,
2251 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
2252{
2253 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2254
2255 LPSHELLVIEW pShellView;
2256 HRESULT hr = E_INVALIDARG;
2257
2258 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
2259
2260 if(ppvOut)
2261 {
2262 *ppvOut = NULL;
2263
2264 if(IsEqualIID(riid, &IID_IDropTarget))
2265 {
2266 WARN("IDropTarget not implemented\n");
2267 hr = E_NOTIMPL;
2268 }
2269 else if(IsEqualIID(riid, &IID_IContextMenu))
2270 {
2271 WARN("IContextMenu not implemented\n");
2272 hr = E_NOTIMPL;
2273 }
2274 else if(IsEqualIID(riid, &IID_IShellView))
2275 {
2276 pShellView = IShellView_Constructor((IShellFolder*)iface);
2277 if(pShellView)
2278 {
2279 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
2280 IShellView_Release(pShellView);
2281 }
2282 }
2283 }
2284 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
2285 return hr;
2286}
2287
2288/**************************************************************************
2289* ISF_MyComputer_fnGetAttributesOf
2290*/
2291static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf(
2292 IShellFolder2 * iface,
2293 UINT cidl,
2294 LPCITEMIDLIST *apidl,
2295 DWORD *rgfInOut)
2296{
2297 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2298
2299 HRESULT hr = S_OK;
2300
2301 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
2302
2303 if ( (!cidl) || (!apidl) || (!rgfInOut))
2304 return E_INVALIDARG;
2305
2306 while (cidl > 0 && *apidl)
2307 {
2308 pdump (*apidl);
2309 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
2310 apidl++;
2311 cidl--;
2312 }
2313
2314 TRACE("-- result=0x%08lx\n",*rgfInOut);
2315 return hr;
2316}
2317
2318/**************************************************************************
2319* ISF_MyComputer_fnGetDisplayNameOf
2320*
2321* NOTES
2322* The desktopfolder creates only complete paths (SHGDN_FORPARSING).
2323* SHGDN_INFOLDER makes no sense.
2324*/
2325static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf(
2326 IShellFolder2 * iface,
2327 LPCITEMIDLIST pidl,
2328 DWORD dwFlags,
2329 LPSTRRET strRet)
2330{
2331 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2332
2333 char szPath[MAX_PATH], szDrive[18];
2334 int len = 0;
2335 BOOL bSimplePidl;
2336
2337 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
2338 pdump(pidl);
2339
2340 if(!strRet) return E_INVALIDARG;
2341
2342 szPath[0]=0x00; szDrive[0]=0x00;
2343
2344
2345 bSimplePidl = _ILIsPidlSimple(pidl);
2346
2347 if (_ILIsSpecialFolder(pidl))
2348 {
2349 /* take names of special folders only if its only this folder */
2350 if ( bSimplePidl )
2351 {
2352 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2353 }
2354 }
2355 else
2356 {
2357 if (!_ILIsDrive(pidl))
2358 {
2359 ERR("Wrong pidl type\n");
2360 return E_INVALIDARG;
2361 }
2362
2363 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2364
2365 /* long view "lw_name (C:)" */
2366 if ( bSimplePidl && !(dwFlags & SHGDN_FORPARSING))
2367 {
2368 DWORD dwVolumeSerialNumber,dwMaximumComponetLength,dwFileSystemFlags;
2369
2370#ifdef __WIN32OS2__
2371//CB: floppy drives have a fixed name
2372 if ((szPath[0] == 'A') || (szPath[0] == 'a') || (szPath[0] == 'B') || (szPath[0] == 'b'))
2373 {
2374 //floppy
2375 strncpy(szDrive,szPath,2);
2376 //3.5 floppy
2377 LoadStringA(shell32_hInstance,IDS_35FLOPPY,szPath,sizeof(szPath)-10);
2378 //CB: todo: 5.25 floppy check
2379 strcat(szPath," (");
2380 strncat(szPath,szDrive,2);
2381 strcat(szPath,")");
2382 } else
2383 {
2384 GetVolumeInformationA(szPath,szDrive,12,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0);
2385 strcat (szDrive," (");
2386 strncat (szDrive, szPath, 2);
2387 strcat (szDrive,")");
2388 strcpy (szPath, szDrive);
2389 }
2390#else
2391 GetVolumeInformationA(szPath,szDrive,12,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0);
2392 strcat (szDrive," (");
2393 strncat (szDrive, szPath, 2);
2394 strcat (szDrive,")");
2395 strcpy (szPath, szDrive);
2396#endif
2397 }
2398 }
2399
2400 if (!bSimplePidl) /* go deeper if needed */
2401 {
2402 PathAddBackslashA(szPath);
2403 len = strlen(szPath);
2404
2405 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags | SHGDN_FORPARSING, szPath + len, MAX_PATH - len)))
2406 return E_OUTOFMEMORY;
2407 }
2408 strRet->uType = STRRET_CSTRA;
2409 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
2410
2411
2412 TRACE("-- (%p)->(%s)\n", This, szPath);
2413 return S_OK;
2414}
2415
2416static HRESULT WINAPI ISF_MyComputer_fnGetDefaultSearchGUID(
2417 IShellFolder2 * iface,
2418 GUID *pguid)
2419{
2420 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2421 FIXME("(%p)\n",This);
2422 return E_NOTIMPL;
2423}
2424static HRESULT WINAPI ISF_MyComputer_fnEnumSearches(
2425 IShellFolder2 * iface,
2426 IEnumExtraSearch **ppenum)
2427{
2428 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2429 FIXME("(%p)\n",This);
2430 return E_NOTIMPL;
2431}
2432static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumn(
2433 IShellFolder2 * iface,
2434 DWORD dwRes,
2435 ULONG *pSort,
2436 ULONG *pDisplay)
2437{
2438 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2439
2440 TRACE("(%p)\n",This);
2441
2442 if (pSort) *pSort = 0;
2443 if (pDisplay) *pDisplay = 0;
2444
2445 return S_OK;
2446}
2447static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumnState(
2448 IShellFolder2 * iface,
2449 UINT iColumn,
2450 DWORD *pcsFlags)
2451{
2452 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2453
2454 TRACE("(%p)\n",This);
2455
2456 if (!pcsFlags || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2457
2458 *pcsFlags = MyComputerSFHeader[iColumn].pcsFlags;
2459
2460 return S_OK;
2461}
2462static HRESULT WINAPI ISF_MyComputer_fnGetDetailsEx(
2463 IShellFolder2 * iface,
2464 LPCITEMIDLIST pidl,
2465 const SHCOLUMNID *pscid,
2466 VARIANT *pv)
2467{
2468 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2469 FIXME("(%p)\n",This);
2470
2471 return E_NOTIMPL;
2472}
2473
2474/* fixme: drive size >4GB is rolling over */
2475static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf(
2476 IShellFolder2 * iface,
2477 LPCITEMIDLIST pidl,
2478 UINT iColumn,
2479 SHELLDETAILS *psd)
2480{
2481 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2482 HRESULT hr;
2483
2484 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
2485
2486 if (!psd || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2487
2488 if (!pidl)
2489 {
2490 psd->fmt = MyComputerSFHeader[iColumn].fmt;
2491 psd->cxChar = MyComputerSFHeader[iColumn].cxChar;
2492 psd->str.uType = STRRET_CSTRA;
2493 LoadStringA(shell32_hInstance, MyComputerSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
2494 return S_OK;
2495 }
2496 else
2497 {
2498 char szPath[MAX_PATH];
2499 ULARGE_INTEGER ulBytes;
2500
2501 psd->str.u.cStr[0] = 0x00;
2502 psd->str.uType = STRRET_CSTRA;
2503 switch(iColumn)
2504 {
2505 case 0: /* name */
2506 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2507 break;
2508 case 1: /* type */
2509 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2510 break;
2511 case 2: /* total size */
2512 if (_ILIsDrive(pidl))
2513 {
2514 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2515 GetDiskFreeSpaceExA(szPath, NULL, &ulBytes, NULL);
2516 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2517 }
2518 break;
2519 case 3: /* free size */
2520 if (_ILIsDrive(pidl))
2521 {
2522 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2523 GetDiskFreeSpaceExA(szPath, &ulBytes, NULL, NULL);
2524 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2525 }
2526 break;
2527 }
2528 hr = S_OK;
2529 }
2530
2531 return hr;
2532}
2533static HRESULT WINAPI ISF_MyComputer_fnMapNameToSCID(
2534 IShellFolder2 * iface,
2535 LPCWSTR pwszName,
2536 SHCOLUMNID *pscid)
2537{
2538 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2539 FIXME("(%p)\n",This);
2540 return E_NOTIMPL;
2541}
2542
2543static ICOM_VTABLE(IShellFolder2) sfmcvt =
2544{
2545 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2546 IShellFolder_fnQueryInterface,
2547 IShellFolder_fnAddRef,
2548 IShellFolder_fnRelease,
2549 ISF_MyComputer_fnParseDisplayName,
2550 ISF_MyComputer_fnEnumObjects,
2551 ISF_MyComputer_fnBindToObject,
2552 IShellFolder_fnBindToStorage,
2553 IShellFolder_fnCompareIDs,
2554 ISF_MyComputer_fnCreateViewObject,
2555 ISF_MyComputer_fnGetAttributesOf,
2556 IShellFolder_fnGetUIObjectOf,
2557 ISF_MyComputer_fnGetDisplayNameOf,
2558 IShellFolder_fnSetNameOf,
2559
2560 /* ShellFolder2 */
2561 ISF_MyComputer_fnGetDefaultSearchGUID,
2562 ISF_MyComputer_fnEnumSearches,
2563 ISF_MyComputer_fnGetDefaultColumn,
2564 ISF_MyComputer_fnGetDefaultColumnState,
2565 ISF_MyComputer_fnGetDetailsEx,
2566 ISF_MyComputer_fnGetDetailsOf,
2567 ISF_MyComputer_fnMapNameToSCID
2568};
2569
2570
2571/************************************************************************
2572 * ISFPersistFolder_QueryInterface (IUnknown)
2573 *
2574 */
2575static HRESULT WINAPI ISFPersistFolder2_QueryInterface(
2576 IPersistFolder2 * iface,
2577 REFIID iid,
2578 LPVOID* ppvObj)
2579{
2580 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2581
2582 TRACE("(%p)\n", This);
2583
2584 return IUnknown_QueryInterface(This->pUnkOuter, iid, ppvObj);
2585}
2586
2587/************************************************************************
2588 * ISFPersistFolder_AddRef (IUnknown)
2589 *
2590 */
2591static ULONG WINAPI ISFPersistFolder2_AddRef(
2592 IPersistFolder2 * iface)
2593{
2594 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2595
2596 TRACE("(%p)\n", This);
2597
2598 return IUnknown_AddRef(This->pUnkOuter);
2599}
2600
2601/************************************************************************
2602 * ISFPersistFolder_Release (IUnknown)
2603 *
2604 */
2605static ULONG WINAPI ISFPersistFolder2_Release(
2606 IPersistFolder2 * iface)
2607{
2608 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2609
2610 TRACE("(%p)\n", This);
2611
2612 return IUnknown_Release(This->pUnkOuter);
2613}
2614
2615/************************************************************************
2616 * ISFPersistFolder_GetClassID (IPersist)
2617 */
2618static HRESULT WINAPI ISFPersistFolder2_GetClassID(
2619 IPersistFolder2 * iface,
2620 CLSID * lpClassId)
2621{
2622 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2623
2624 TRACE("(%p)\n", This);
2625
2626 if (!lpClassId) return E_POINTER;
2627 *lpClassId = *This->pclsid;
2628
2629 return S_OK;
2630}
2631
2632/************************************************************************
2633 * ISFPersistFolder_Initialize (IPersistFolder)
2634 *
2635 * NOTES
2636 * sMyPath is not set. Don't know how to handle in a non rooted environment.
2637 */
2638static HRESULT WINAPI ISFPersistFolder2_Initialize(
2639 IPersistFolder2 * iface,
2640 LPCITEMIDLIST pidl)
2641{
2642 char sTemp[MAX_PATH];
2643 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2644
2645 TRACE("(%p)->(%p)\n", This, pidl);
2646
2647 /* free the old stuff */
2648 if(This->absPidl)
2649 {
2650 SHFree(This->absPidl);
2651 This->absPidl = NULL;
2652 }
2653 if(This->sMyPath)
2654 {
2655 SHFree(This->sMyPath);
2656 This->sMyPath = NULL;
2657 }
2658
2659 /* set my pidl */
2660 This->absPidl = ILClone(pidl);
2661
2662 /* set my path */
2663 if (SHGetPathFromIDListA(pidl, sTemp))
2664 {
2665 This->sMyPath = SHAlloc(strlen(sTemp)+1);
2666 strcpy(This->sMyPath, sTemp);
2667 }
2668
2669 TRACE("--(%p)->(%s)\n", This, This->sMyPath);
2670
2671 return S_OK;
2672}
2673
2674/**************************************************************************
2675* IPersistFolder2_fnGetCurFolder
2676*/
2677static HRESULT WINAPI ISFPersistFolder2_fnGetCurFolder(
2678 IPersistFolder2 * iface,
2679 LPITEMIDLIST * pidl)
2680{
2681 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2682
2683 TRACE("(%p)->(%p)\n",This, pidl);
2684
2685 if (!pidl) return E_POINTER;
2686
2687 *pidl = ILClone(This->absPidl);
2688
2689 return S_OK;
2690}
2691
2692static ICOM_VTABLE(IPersistFolder2) psfvt =
2693{
2694 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2695 ISFPersistFolder2_QueryInterface,
2696 ISFPersistFolder2_AddRef,
2697 ISFPersistFolder2_Release,
2698 ISFPersistFolder2_GetClassID,
2699 ISFPersistFolder2_Initialize,
2700 ISFPersistFolder2_fnGetCurFolder
2701};
2702
2703/****************************************************************************
2704 * ISFDropTarget implementation
2705 */
2706static BOOL ISFDropTarget_QueryDrop(
2707 IDropTarget *iface,
2708 DWORD dwKeyState,
2709 LPDWORD pdwEffect)
2710{
2711 DWORD dwEffect = *pdwEffect;
2712
2713 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2714
2715 *pdwEffect = DROPEFFECT_NONE;
2716
2717 if (This->fAcceptFmt)
2718 { /* Does our interpretation of the keystate ... */
2719 *pdwEffect = KeyStateToDropEffect(dwKeyState);
2720
2721 /* ... matches the desired effect ? */
2722 if (dwEffect & *pdwEffect)
2723 {
2724 return TRUE;
2725 }
2726 }
2727 return FALSE;
2728}
2729
2730static HRESULT WINAPI ISFDropTarget_QueryInterface(
2731 IDropTarget *iface,
2732 REFIID riid,
2733 LPVOID *ppvObj)
2734{
2735 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2736
2737 TRACE("(%p)\n", This);
2738
2739 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
2740}
2741
2742static ULONG WINAPI ISFDropTarget_AddRef( IDropTarget *iface)
2743{
2744 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2745
2746 TRACE("(%p)\n", This);
2747
2748 return IUnknown_AddRef(This->pUnkOuter);
2749}
2750
2751static ULONG WINAPI ISFDropTarget_Release( IDropTarget *iface)
2752{
2753 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2754
2755 TRACE("(%p)\n", This);
2756
2757 return IUnknown_Release(This->pUnkOuter);
2758}
2759
2760static HRESULT WINAPI ISFDropTarget_DragEnter(
2761 IDropTarget *iface,
2762 IDataObject *pDataObject,
2763 DWORD dwKeyState,
2764 POINTL pt,
2765 DWORD *pdwEffect)
2766{
2767 FORMATETC fmt;
2768
2769 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2770
2771 TRACE("(%p)->(DataObject=%p)\n",This,pDataObject);
2772
2773 InitFormatEtc(fmt, This->cfShellIDList, TYMED_HGLOBAL);
2774
2775 This->fAcceptFmt = (S_OK == IDataObject_QueryGetData(pDataObject, &fmt)) ? TRUE : FALSE;
2776
2777 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2778
2779 return S_OK;
2780}
2781
2782static HRESULT WINAPI ISFDropTarget_DragOver(
2783 IDropTarget *iface,
2784 DWORD dwKeyState,
2785 POINTL pt,
2786 DWORD *pdwEffect)
2787{
2788 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2789
2790 TRACE("(%p)\n",This);
2791
2792 if(!pdwEffect) return E_INVALIDARG;
2793
2794 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2795
2796 return S_OK;
2797}
2798
2799static HRESULT WINAPI ISFDropTarget_DragLeave(
2800 IDropTarget *iface)
2801{
2802 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2803
2804 TRACE("(%p)\n",This);
2805
2806 This->fAcceptFmt = FALSE;
2807
2808 return S_OK;
2809}
2810
2811static HRESULT WINAPI ISFDropTarget_Drop(
2812 IDropTarget *iface,
2813 IDataObject* pDataObject,
2814 DWORD dwKeyState,
2815 POINTL pt,
2816 DWORD *pdwEffect)
2817{
2818 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2819
2820 FIXME("(%p) object dropped\n",This);
2821
2822 return E_NOTIMPL;
2823}
2824
2825static struct ICOM_VTABLE(IDropTarget) dtvt =
2826{
2827 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2828 ISFDropTarget_QueryInterface,
2829 ISFDropTarget_AddRef,
2830 ISFDropTarget_Release,
2831 ISFDropTarget_DragEnter,
2832 ISFDropTarget_DragOver,
2833 ISFDropTarget_DragLeave,
2834 ISFDropTarget_Drop
2835};
Note: See TracBrowser for help on using the repository browser.