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

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

* empty log message *

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