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

Last change on this file since 3646 was 3646, checked in by sandervl, 25 years ago

fix for open file dialog

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