source: trunk/src/shell32/shlfolder.c

Last change on this file was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

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