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

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

* empty log message *

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