Fix typo in OUTLINETEXTMETRIC definition.
[wine.git] / dlls / shell32 / shlfolder.c
blob31fc1c7acd8bdca55bd049a856634b0ea35d3b46
1 /*
2 * Shell Folder stuff
4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998, 1999 Juergen Schmied
6 *
7 * IShellFolder2 and related interfaces
9 */
11 #include <stdlib.h>
12 #include <string.h>
13 #include <stdio.h>
15 #include "debugtools.h"
16 #include "winerror.h"
17 #include "winbase.h"
19 #include "oleidl.h"
20 #include "shlguid.h"
22 #include "pidl.h"
23 #include "wine/obj_base.h"
24 #include "wine/obj_dragdrop.h"
25 #include "wine/obj_shellfolder.h"
26 #include "wine/undocshell.h"
27 #include "shell32_main.h"
28 #include "shresdef.h"
29 #include "shlwapi.h"
30 #include "shellfolder.h"
32 DEFAULT_DEBUG_CHANNEL(shell);
35 /***************************************************************************
36 * debughelper: print out the return adress
37 * helps especially to track down unbalanced AddRef/Release
39 #define MEM_DEBUG 0
41 #if MEM_DEBUG
42 #define _CALL_TRACE TRACE("called from: 0x%08x\n", *( ((UINT*)&iface)-1 ));
43 #else
44 #define _CALL_TRACE
45 #endif
47 typedef struct
49 int colnameid;
50 int pcsFlags;
51 int fmt;
52 int cxChar;
54 } shvheader;
56 /***************************************************************************
57 * GetNextElement (internal function)
59 * gets a part of a string till the first backslash
61 * PARAMETERS
62 * pszNext [IN] string to get the element from
63 * pszOut [IN] pointer to buffer whitch receives string
64 * dwOut [IN] length of pszOut
66 * RETURNS
67 * LPSTR pointer to first, not yet parsed char
70 static LPCWSTR GetNextElementW(LPCWSTR pszNext,LPWSTR pszOut,DWORD dwOut)
71 { LPCWSTR pszTail = pszNext;
72 DWORD dwCopy;
73 TRACE("(%s %p 0x%08lx)\n",debugstr_w(pszNext),pszOut,dwOut);
75 *pszOut=0x0000;
77 if(!pszNext || !*pszNext)
78 return NULL;
80 while(*pszTail && (*pszTail != (WCHAR)'\\'))
81 pszTail++;
83 dwCopy = (WCHAR*)pszTail - (WCHAR*)pszNext + 1;
84 lstrcpynW(pszOut, pszNext, (dwOut<dwCopy)? dwOut : dwCopy);
86 if(*pszTail)
87 pszTail++;
88 else
89 pszTail = NULL;
91 TRACE("--(%s %s 0x%08lx %p)\n",debugstr_w(pszNext),debugstr_w(pszOut),dwOut,pszTail);
92 return pszTail;
95 static HRESULT SHELL32_ParseNextElement(
96 HWND hwndOwner,
97 IShellFolder2 * psf,
98 LPITEMIDLIST * pidlInOut,
99 LPOLESTR szNext,
100 DWORD *pEaten,
101 DWORD *pdwAttributes)
103 HRESULT hr = E_OUTOFMEMORY;
104 LPITEMIDLIST pidlOut, pidlTemp = NULL;
105 IShellFolder *psfChild;
107 TRACE("(%p, %p, %s)\n",psf, pidlInOut ? *pidlInOut : NULL, debugstr_w(szNext));
110 /* get the shellfolder for the child pidl and let it analyse further */
111 hr = IShellFolder_BindToObject(psf, *pidlInOut, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
113 if (psfChild)
115 hr = IShellFolder_ParseDisplayName(psfChild, hwndOwner, NULL, szNext, pEaten, &pidlOut, pdwAttributes);
116 IShellFolder_Release(psfChild);
118 pidlTemp = ILCombine(*pidlInOut, pidlOut);
120 if (pidlOut)
121 ILFree(pidlOut);
124 ILFree(*pidlInOut);
125 *pidlInOut = pidlTemp;
127 TRACE("-- pidl=%p ret=0x%08lx\n", pidlInOut? *pidlInOut: NULL, hr);
128 return hr;
131 /***********************************************************************
132 * SHELL32_CoCreateInitSF
134 * creates a initialized shell folder
136 static HRESULT SHELL32_CoCreateInitSF (
137 LPITEMIDLIST pidlRoot,
138 LPITEMIDLIST pidlChild,
139 REFCLSID clsid,
140 REFIID iid,
141 LPVOID * ppvOut)
143 HRESULT hr;
144 LPITEMIDLIST absPidl;
145 IShellFolder2 *pShellFolder;
146 IPersistFolder *pPersistFolder;
148 TRACE("%p %p\n", pidlRoot, pidlChild);
150 *ppvOut = NULL;
152 /* we have to ask first for IPersistFolder, some special folders are expecting this */
153 hr = SHCoCreateInstance(NULL, clsid, NULL, &IID_IPersistFolder, (LPVOID*)&pPersistFolder);
154 if (SUCCEEDED(hr))
156 hr = IPersistFolder_QueryInterface(pPersistFolder, iid, (LPVOID*)&pShellFolder);
157 if (SUCCEEDED(hr))
159 absPidl = ILCombine (pidlRoot, pidlChild);
160 hr = IPersistFolder_Initialize(pPersistFolder, absPidl);
161 IPersistFolder_Release(pPersistFolder);
162 SHFree(absPidl);
163 *ppvOut = pShellFolder;
167 TRACE("-- ret=0x%08lx\n", hr);
168 return hr;
171 static HRESULT SHELL32_GetDisplayNameOfChild(
172 IShellFolder2 * psf,
173 LPCITEMIDLIST pidl,
174 DWORD dwFlags,
175 LPSTR szOut,
176 DWORD dwOutLen)
178 LPITEMIDLIST pidlFirst, pidlNext;
179 IShellFolder2 * psfChild;
180 HRESULT hr = E_OUTOFMEMORY;
181 STRRET strTemp;
183 TRACE("(%p)->(pidl=%p 0x%08lx %p 0x%08lx)\n",psf,pidl,dwFlags,szOut, dwOutLen);
184 pdump(pidl);
186 if ((pidlFirst = ILCloneFirst(pidl)))
188 hr = IShellFolder_BindToObject(psf, pidlFirst, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
189 if (SUCCEEDED(hr))
191 pidlNext = ILGetNext(pidl);
193 hr = IShellFolder_GetDisplayNameOf(psfChild, pidlNext, dwFlags | SHGDN_INFOLDER, &strTemp);
194 if (SUCCEEDED(hr))
196 hr = StrRetToStrNA(szOut, dwOutLen, &strTemp, pidlNext);
199 IShellFolder_Release(psfChild);
201 ILFree(pidlFirst);
204 TRACE("-- ret=0x%08lx %s\n", hr, szOut);
206 return hr;
209 /***********************************************************************
210 * SHELL32_GetItemAttributes
212 * NOTES
213 * observerd values:
214 * folder: 0xE0000177 FILESYSTEM | HASSUBFOLDER | FOLDER
215 * file: 0x40000177 FILESYSTEM
216 * drive: 0xf0000144 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR
217 * mycomputer: 0xb0000154 HASSUBFOLDER | FOLDER | FILESYSANCESTOR
218 * (seems to be default for shell extensions if no registry entry exists)
220 * This functions does not set flags!! It only resets flags when nessesary.
222 static HRESULT SHELL32_GetItemAttributes(
223 IShellFolder * psf,
224 LPITEMIDLIST pidl,
225 LPDWORD pdwAttributes)
227 GUID const * clsid;
228 DWORD dwAttributes;
230 TRACE("0x%08lx\n", *pdwAttributes);
232 if (*pdwAttributes & (0xcff3fe88))
233 WARN("attribute 0x%08lx not implemented\n", *pdwAttributes);
234 *pdwAttributes &= ~SFGAO_LINK; /* FIXME: for native filedialogs */
236 if (_ILIsDrive(pidl))
238 *pdwAttributes &= 0xf0000144;
240 else if ((clsid=_ILGetGUIDPointer(pidl)))
242 if (HCR_GetFolderAttributes(clsid, &dwAttributes))
244 *pdwAttributes &= dwAttributes;
246 else
248 *pdwAttributes &= 0xb0000154;
251 else if (_ILGetDataPointer(pidl))
253 dwAttributes = _ILGetFileAttributes(pidl, NULL, 0);
254 *pdwAttributes &= ~SFGAO_FILESYSANCESTOR;
256 if(( SFGAO_FOLDER & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
257 *pdwAttributes &= ~(SFGAO_FOLDER|SFGAO_HASSUBFOLDER);
259 if(( SFGAO_HIDDEN & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_HIDDEN))
260 *pdwAttributes &= ~SFGAO_HIDDEN;
262 if(( SFGAO_READONLY & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_READONLY))
263 *pdwAttributes &= ~SFGAO_READONLY;
265 else
267 *pdwAttributes &= 0xb0000154;
269 TRACE("-- 0x%08lx\n", *pdwAttributes);
270 return S_OK;
273 /***********************************************************************
274 * IShellFolder implementation
277 typedef struct
279 ICOM_VFIELD(IUnknown);
280 DWORD ref;
281 ICOM_VTABLE(IShellFolder2)* lpvtblShellFolder;
282 ICOM_VTABLE(IPersistFolder2)* lpvtblPersistFolder2;
283 ICOM_VTABLE(IDropTarget)* lpvtblDropTarget;
284 ICOM_VTABLE(ISFHelper)* lpvtblSFHelper;
286 IUnknown *pUnkOuter; /* used for aggregation */
288 CLSID* pclsid;
290 LPSTR sMyPath;
291 LPITEMIDLIST absPidl; /* complete pidl */
293 UINT cfShellIDList; /* clipboardformat for IDropTarget */
294 BOOL fAcceptFmt; /* flag for pending Drop */
295 } IGenericSFImpl;
297 static struct ICOM_VTABLE(IUnknown) unkvt;
298 static struct ICOM_VTABLE(IShellFolder2) sfvt;
299 static struct ICOM_VTABLE(IPersistFolder2) psfvt;
300 static struct ICOM_VTABLE(IDropTarget) dtvt;
301 static struct ICOM_VTABLE(ISFHelper) shvt;
303 static IShellFolder * ISF_MyComputer_Constructor(void);
305 #define _IShellFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblShellFolder)))
306 #define _ICOM_THIS_From_IShellFolder2(class, name) class* This = (class*)(((char*)name)-_IShellFolder2_Offset);
308 #define _IPersistFolder_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder2)))
309 #define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder_Offset);
311 #define _IDropTarget_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblDropTarget)))
312 #define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
314 #define _ISFHelper_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblSFHelper)))
315 #define _ICOM_THIS_From_ISFHelper(class, name) class* This = (class*)(((char*)name)-_ISFHelper_Offset);
317 converts This to a interface pointer
319 #define _IUnknown_(This) (IUnknown*)&(This->lpVtbl)
320 #define _IShellFolder_(This) (IShellFolder*)&(This->lpvtblShellFolder)
321 #define _IShellFolder2_(This) (IShellFolder2*)&(This->lpvtblShellFolder)
322 #define _IPersist_(This) (IPersist*)&(This->lpvtblPersistFolder2)
323 #define _IPersistFolder_(This) (IPersistFolder*)&(This->lpvtblPersistFolder2)
324 #define _IPersistFolder2_(This) (IPersistFolder2*)&(This->lpvtblPersistFolder2)
325 #define _IDropTarget_(This) (IDropTarget*)&(This->lpvtblDropTarget)
326 #define _ISFHelper_(This) (ISFHelper*)&(This->lpvtblSFHelper)
327 /**************************************************************************
328 * registers clipboardformat once
330 static void SF_RegisterClipFmt (IGenericSFImpl * This)
332 TRACE("(%p)\n", This);
334 if (!This->cfShellIDList)
336 This->cfShellIDList = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
340 /**************************************************************************
341 * we need a separate IUnknown to handle aggregation
342 * (inner IUnknown)
344 static HRESULT WINAPI IUnknown_fnQueryInterface(
345 IUnknown * iface,
346 REFIID riid,
347 LPVOID *ppvObj)
349 ICOM_THIS(IGenericSFImpl, iface);
351 _CALL_TRACE
352 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
354 *ppvObj = NULL;
356 if(IsEqualIID(riid, &IID_IUnknown)) *ppvObj = _IUnknown_(This);
357 else if(IsEqualIID(riid, &IID_IShellFolder)) *ppvObj = _IShellFolder_(This);
358 else if(IsEqualIID(riid, &IID_IShellFolder2)) *ppvObj = _IShellFolder_(This);
359 else if(IsEqualIID(riid, &IID_IPersist)) *ppvObj = _IPersist_(This);
360 else if(IsEqualIID(riid, &IID_IPersistFolder)) *ppvObj = _IPersistFolder_(This);
361 else if(IsEqualIID(riid, &IID_IPersistFolder2)) *ppvObj = _IPersistFolder2_(This);
362 else if(IsEqualIID(riid, &IID_ISFHelper)) *ppvObj = _ISFHelper_(This);
363 else if(IsEqualIID(riid, &IID_IDropTarget))
365 *ppvObj = _IDropTarget_(This);
366 SF_RegisterClipFmt(This);
369 if(*ppvObj)
371 IUnknown_AddRef((IUnknown*)(*ppvObj));
372 TRACE("-- Interface = %p\n", *ppvObj);
373 return S_OK;
375 TRACE("-- Interface: E_NOINTERFACE\n");
376 return E_NOINTERFACE;
379 static ULONG WINAPI IUnknown_fnAddRef(IUnknown * iface)
381 ICOM_THIS(IGenericSFImpl, iface);
383 _CALL_TRACE
384 TRACE("(%p)->(count=%lu)\n",This,This->ref);
386 shell32_ObjCount++;
387 return ++(This->ref);
390 static ULONG WINAPI IUnknown_fnRelease(IUnknown * iface)
392 ICOM_THIS(IGenericSFImpl, iface);
394 _CALL_TRACE
395 TRACE("(%p)->(count=%lu)\n",This,This->ref);
397 shell32_ObjCount--;
398 if (!--(This->ref))
400 TRACE("-- destroying IShellFolder(%p)\n",This);
402 if (pdesktopfolder == _IShellFolder_(This))
404 pdesktopfolder=NULL;
405 TRACE("-- destroyed IShellFolder(%p) was Desktopfolder\n",This);
407 if(This->absPidl) SHFree(This->absPidl);
408 if(This->sMyPath) SHFree(This->sMyPath);
409 HeapFree(GetProcessHeap(),0,This);
410 return 0;
412 return This->ref;
415 static ICOM_VTABLE(IUnknown) unkvt =
417 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
418 IUnknown_fnQueryInterface,
419 IUnknown_fnAddRef,
420 IUnknown_fnRelease,
423 static shvheader GenericSFHeader [] =
425 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
426 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
427 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
428 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
429 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
431 #define GENERICSHELLVIEWCOLUMNS 5
433 /**************************************************************************
434 * IShellFolder_Constructor
436 * NOTES
437 * creating undocumented ShellFS_Folder as part of an aggregation
438 * {F3364BA0-65B9-11CE-A9BA-00AA004AE837}
440 * FIXME
441 * when pUnkOuter = 0 then rrid = IID_IShellFolder is returned
443 HRESULT IFSFolder_Constructor(
444 IUnknown * pUnkOuter,
445 REFIID riid,
446 LPVOID * ppv)
448 IGenericSFImpl * sf;
449 HRESULT hr = S_OK;
451 TRACE("unkOut=%p riid=%s\n",pUnkOuter, debugstr_guid(riid));
453 if(pUnkOuter && ! IsEqualIID(riid, &IID_IUnknown))
455 hr = CLASS_E_NOAGGREGATION; /* forbidden by definition */
457 else
459 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
460 if (sf)
462 sf->ref=1;
463 ICOM_VTBL(sf)=&unkvt;
464 sf->lpvtblShellFolder=&sfvt;
465 sf->lpvtblPersistFolder2=&psfvt;
466 sf->lpvtblDropTarget=&dtvt;
467 sf->lpvtblSFHelper=&shvt;
469 sf->pclsid = (CLSID*)&CLSID_SFFile;
470 sf->pUnkOuter = pUnkOuter ? pUnkOuter : _IUnknown_(sf);
471 *ppv = _IUnknown_(sf);
472 hr = S_OK;
473 shell32_ObjCount++;
475 else
477 hr = E_OUTOFMEMORY;
480 return hr;
482 /**************************************************************************
483 * IShellFolder_Constructor
485 * NOTES
486 * THIS points to the parent folder
489 IShellFolder * IShellFolder_Constructor(
490 IShellFolder2 * iface,
491 LPITEMIDLIST pidl)
493 IGenericSFImpl * sf;
494 DWORD dwSize=0;
496 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
498 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
499 sf->ref=1;
501 ICOM_VTBL(sf)=&unkvt;
502 sf->lpvtblShellFolder=&sfvt;
503 sf->lpvtblPersistFolder2=&psfvt;
504 sf->lpvtblDropTarget=&dtvt;
505 sf->lpvtblSFHelper=&shvt;
507 sf->pclsid = (CLSID*)&CLSID_SFFile;
508 sf->pUnkOuter = _IUnknown_(sf);
510 TRACE("(%p)->(parent=%p, pidl=%p)\n",sf,This, pidl);
511 pdump(pidl);
513 if(pidl && iface) /* do we have a pidl? */
515 int len;
517 sf->absPidl = ILCombine(This->absPidl, pidl); /* build a absolute pidl */
519 if (!_ILIsSpecialFolder(pidl)) /* only file system paths */
521 if(This->sMyPath) /* get the size of the parents path */
523 dwSize += strlen(This->sMyPath) ;
524 TRACE("-- (%p)->(parent's path=%s)\n",sf, debugstr_a(This->sMyPath));
527 dwSize += _ILSimpleGetText(pidl,NULL,0); /* add the size of our name*/
528 sf->sMyPath = SHAlloc(dwSize + 2); /* '\0' and backslash */
530 if(!sf->sMyPath) return NULL;
531 *(sf->sMyPath)=0x00;
533 if(This->sMyPath) /* if the parent has a path, get it*/
535 strcpy(sf->sMyPath, This->sMyPath);
536 PathAddBackslashA (sf->sMyPath);
539 len = strlen(sf->sMyPath);
540 _ILSimpleGetText(pidl, sf->sMyPath + len, dwSize+2 - len);
543 TRACE("-- (%p)->(my pidl=%p, my path=%s)\n",sf, sf->absPidl,debugstr_a(sf->sMyPath));
545 pdump (sf->absPidl);
548 shell32_ObjCount++;
549 return _IShellFolder_(sf);
552 /**************************************************************************
553 * IShellFolder_fnQueryInterface
555 * PARAMETERS
556 * REFIID riid [in ] Requested InterfaceID
557 * LPVOID* ppvObject [out] Interface* to hold the result
559 static HRESULT WINAPI IShellFolder_fnQueryInterface(
560 IShellFolder2 * iface,
561 REFIID riid,
562 LPVOID *ppvObj)
564 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
566 _CALL_TRACE
567 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
569 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
572 /**************************************************************************
573 * IShellFolder_AddRef
576 static ULONG WINAPI IShellFolder_fnAddRef(IShellFolder2 * iface)
578 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
580 _CALL_TRACE
581 TRACE("(%p)->(count=%lu)\n",This,This->ref);
583 return IUnknown_AddRef(This->pUnkOuter);
586 /**************************************************************************
587 * IShellFolder_fnRelease
589 static ULONG WINAPI IShellFolder_fnRelease(IShellFolder2 * iface)
591 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
593 _CALL_TRACE
594 TRACE("(%p)->(count=%lu)\n",This,This->ref);
596 return IUnknown_Release(This->pUnkOuter);
599 /**************************************************************************
600 * IShellFolder_fnParseDisplayName
601 * PARAMETERS
602 * HWND hwndOwner, //[in ] Parent window for any message's
603 * LPBC pbc, //[in ] reserved
604 * LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname.
605 * ULONG* pchEaten, //[out] (unicode) characters processed
606 * LPITEMIDLIST* ppidl, //[out] complex pidl to item
607 * ULONG* pdwAttributes //[out] items attributes
609 * NOTES
610 * every folder tries to parse only its own (the leftmost) pidl and creates a
611 * subfolder to evaluate the remaining parts
612 * now we can parse into namespaces implemented by shell extensions
614 * behaviour on win98: lpszDisplayName=NULL -> chrash
615 * lpszDisplayName="" -> returns mycoputer-pidl
617 * FIXME:
618 * pdwAttributes: not set
619 * pchEaten: not set like in windows
621 static HRESULT WINAPI IShellFolder_fnParseDisplayName(
622 IShellFolder2 * iface,
623 HWND hwndOwner,
624 LPBC pbcReserved,
625 LPOLESTR lpszDisplayName,
626 DWORD *pchEaten,
627 LPITEMIDLIST *ppidl,
628 DWORD *pdwAttributes)
630 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
632 HRESULT hr = E_OUTOFMEMORY;
633 LPCWSTR szNext=NULL;
634 WCHAR szElement[MAX_PATH];
635 CHAR szTempA[MAX_PATH], szPath[MAX_PATH];
636 LPITEMIDLIST pidlTemp=NULL;
638 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
639 This,hwndOwner,pbcReserved,lpszDisplayName,
640 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
642 if (!lpszDisplayName || !ppidl) return E_INVALIDARG;
644 if (pchEaten) *pchEaten = 0; /* strange but like the original */
646 if (*lpszDisplayName)
648 /* get the next element */
649 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
651 /* build the full pathname to the element */
652 WideCharToMultiByte( CP_ACP, 0, szElement, -1, szTempA, MAX_PATH, NULL, NULL );
653 strcpy(szPath, This->sMyPath);
654 PathAddBackslashA(szPath);
655 strcat(szPath, szTempA);
657 /* get the pidl */
658 pidlTemp = SHSimpleIDListFromPathA(szPath);
660 if (pidlTemp)
662 /* try to analyse the next element */
663 if (szNext && *szNext)
665 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
667 else
669 if (pdwAttributes && *pdwAttributes)
671 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
672 /* WIN32_FIND_DATAA fd;
673 SHGetDataFromIDListA(_IShellFolder_(This), pidlTemp, SHGDFIL_FINDDATA, &fd, sizeof(fd));
674 if (!(FILE_ATTRIBUTE_DIRECTORY & fd.dwFileAttributes))
675 *pdwAttributes &= ~SFGAO_FOLDER;
676 if (FILE_ATTRIBUTE_READONLY & fd.dwFileAttributes)
677 *pdwAttributes &= ~(SFGAO_CANDELETE|SFGAO_CANMOVE|SFGAO_CANRENAME );
680 hr = S_OK;
685 if (!hr)
686 *ppidl = pidlTemp;
687 else
688 *ppidl = NULL;
690 TRACE("(%p)->(-- pidl=%p ret=0x%08lx)\n", This, ppidl? *ppidl:0, hr);
692 return hr;
695 /**************************************************************************
696 * IShellFolder_fnEnumObjects
697 * PARAMETERS
698 * HWND hwndOwner, //[in ] Parent Window
699 * DWORD grfFlags, //[in ] SHCONTF enumeration mask
700 * LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface
702 static HRESULT WINAPI IShellFolder_fnEnumObjects(
703 IShellFolder2 * iface,
704 HWND hwndOwner,
705 DWORD dwFlags,
706 LPENUMIDLIST* ppEnumIDList)
708 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
710 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
712 *ppEnumIDList = NULL;
713 *ppEnumIDList = IEnumIDList_Constructor (This->sMyPath, dwFlags, EIDL_FILE);
715 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
717 if(!*ppEnumIDList) return E_OUTOFMEMORY;
719 return S_OK;
722 /**************************************************************************
723 * IShellFolder_fnBindToObject
724 * PARAMETERS
725 * LPCITEMIDLIST pidl, //[in ] relative pidl to open
726 * LPBC pbc, //[in ] reserved
727 * REFIID riid, //[in ] Initial Interface
728 * LPVOID* ppvObject //[out] Interface*
730 static HRESULT WINAPI IShellFolder_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
731 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
733 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
734 GUID const * iid;
735 IShellFolder *pShellFolder, *pSubFolder;
736 IPersistFolder *pPersistFolder;
737 LPITEMIDLIST absPidl;
739 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
741 if(!pidl || !ppvOut) return E_INVALIDARG;
743 *ppvOut = NULL;
745 if ((iid=_ILGetGUIDPointer(pidl)))
747 /* we have to create a alien folder */
748 if ( SUCCEEDED(SHCoCreateInstance(NULL, iid, NULL, riid, (LPVOID*)&pShellFolder))
749 && SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&pPersistFolder)))
751 absPidl = ILCombine (This->absPidl, pidl);
752 IPersistFolder_Initialize(pPersistFolder, absPidl);
753 IPersistFolder_Release(pPersistFolder);
754 SHFree(absPidl);
756 else
758 return E_FAIL;
761 else if(_ILIsFolder(pidl))
763 LPITEMIDLIST pidltemp = ILCloneFirst(pidl);
764 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
765 ILFree(pidltemp);
767 else
769 ERR("can't bind to a file\n");
770 return E_FAIL;
773 if (_ILIsPidlSimple(pidl))
775 *ppvOut = pShellFolder;
777 else
779 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
780 IShellFolder_Release(pShellFolder);
781 *ppvOut = pSubFolder;
784 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
786 return S_OK;
789 /**************************************************************************
790 * IShellFolder_fnBindToStorage
791 * PARAMETERS
792 * LPCITEMIDLIST pidl, //[in ] complex pidl to store
793 * LPBC pbc, //[in ] reserved
794 * REFIID riid, //[in ] Initial storage interface
795 * LPVOID* ppvObject //[out] Interface* returned
797 static HRESULT WINAPI IShellFolder_fnBindToStorage(
798 IShellFolder2 * iface,
799 LPCITEMIDLIST pidl,
800 LPBC pbcReserved,
801 REFIID riid,
802 LPVOID *ppvOut)
804 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
806 FIXME("(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",
807 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
809 *ppvOut = NULL;
810 return E_NOTIMPL;
813 /**************************************************************************
814 * IShellFolder_fnCompareIDs
816 * PARMETERS
817 * LPARAM lParam, //[in ] Column?
818 * LPCITEMIDLIST pidl1, //[in ] simple pidl
819 * LPCITEMIDLIST pidl2) //[in ] simple pidl
821 * NOTES
822 * Special case - If one of the items is a Path and the other is a File,
823 * always make the Path come before the File.
825 * NOTES
826 * use SCODE_CODE() on the return value to get the result
829 static HRESULT WINAPI IShellFolder_fnCompareIDs(
830 IShellFolder2 * iface,
831 LPARAM lParam,
832 LPCITEMIDLIST pidl1,
833 LPCITEMIDLIST pidl2)
835 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
837 CHAR szTemp1[MAX_PATH];
838 CHAR szTemp2[MAX_PATH];
839 int nReturn;
840 IShellFolder * psf;
841 HRESULT hr = E_OUTOFMEMORY;
842 LPCITEMIDLIST pidlTemp;
843 PIDLTYPE pt1, pt2;
845 TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",This,lParam,pidl1,pidl2);
846 pdump (pidl1);
847 pdump (pidl2);
849 if (!pidl1 && !pidl2)
851 hr = ResultFromShort(0);
853 else if (!pidl1)
855 hr = ResultFromShort(-1);
857 else if (!pidl2)
859 hr = ResultFromShort(1);
861 else
863 LPPIDLDATA pd1, pd2;
864 pd1 = _ILGetDataPointer(pidl1);
865 pd2 = _ILGetDataPointer(pidl2);
867 /* compate the types. sort order is the PT_* constant */
868 pt1 = ( pd1 ? pd1->type: PT_DESKTOP);
869 pt2 = ( pd2 ? pd2->type: PT_DESKTOP);
871 if (pt1 != pt2)
873 hr = ResultFromShort(pt1-pt2);
875 else /* same type of pidl */
877 _ILSimpleGetText(pidl1, szTemp1, MAX_PATH);
878 _ILSimpleGetText(pidl2, szTemp2, MAX_PATH);
879 nReturn = strcasecmp(szTemp1, szTemp2);
881 if (nReturn == 0) /* first pidl different ? */
883 pidl1 = ILGetNext(pidl1);
885 if (pidl1 && pidl1->mkid.cb) /* go deeper? */
887 pidlTemp = ILCloneFirst(pidl1);
888 pidl2 = ILGetNext(pidl2);
890 hr = IShellFolder_BindToObject(iface, pidlTemp, NULL, &IID_IShellFolder, (LPVOID*)&psf);
891 if (SUCCEEDED(hr))
893 nReturn = IShellFolder_CompareIDs(psf, 0, pidl1, pidl2);
894 IShellFolder_Release(psf);
895 hr = ResultFromShort(nReturn);
897 ILFree(pidlTemp);
899 else
901 hr = ResultFromShort(nReturn); /* two equal simple pidls */
904 else
906 hr = ResultFromShort(nReturn); /* two different simple pidls */
911 TRACE("-- res=0x%08lx\n", hr);
912 return hr;
915 /**************************************************************************
916 * IShellFolder_fnCreateViewObject
918 static HRESULT WINAPI IShellFolder_fnCreateViewObject(
919 IShellFolder2 * iface,
920 HWND hwndOwner,
921 REFIID riid,
922 LPVOID *ppvOut)
924 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
926 LPSHELLVIEW pShellView;
927 HRESULT hr = E_INVALIDARG;
929 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
931 if(ppvOut)
933 *ppvOut = NULL;
935 if(IsEqualIID(riid, &IID_IDropTarget))
937 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, ppvOut);
939 else if(IsEqualIID(riid, &IID_IContextMenu))
941 FIXME("IContextMenu not implemented\n");
942 hr = E_NOTIMPL;
944 else if(IsEqualIID(riid, &IID_IShellView))
946 pShellView = IShellView_Constructor((IShellFolder*)iface);
947 if(pShellView)
949 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
950 IShellView_Release(pShellView);
954 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
955 return hr;
958 /**************************************************************************
959 * IShellFolder_fnGetAttributesOf
961 * PARAMETERS
962 * UINT cidl, //[in ] num elements in pidl array
963 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
964 * ULONG* rgfInOut) //[out] result array
967 static HRESULT WINAPI IShellFolder_fnGetAttributesOf(
968 IShellFolder2 * iface,
969 UINT cidl,
970 LPCITEMIDLIST *apidl,
971 DWORD *rgfInOut)
973 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
975 HRESULT hr = S_OK;
977 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
979 if ( (!cidl) || (!apidl) || (!rgfInOut))
980 return E_INVALIDARG;
982 while (cidl > 0 && *apidl)
984 pdump (*apidl);
985 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
986 apidl++;
987 cidl--;
990 TRACE("-- result=0x%08lx\n",*rgfInOut);
992 return hr;
994 /**************************************************************************
995 * IShellFolder_fnGetUIObjectOf
997 * PARAMETERS
998 * HWND hwndOwner, //[in ] Parent window for any output
999 * UINT cidl, //[in ] array size
1000 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
1001 * REFIID riid, //[in ] Requested Interface
1002 * UINT* prgfInOut, //[ ] reserved
1003 * LPVOID* ppvObject) //[out] Resulting Interface
1005 * NOTES
1006 * This function gets asked to return "view objects" for one or more (multiple select)
1007 * items:
1008 * The viewobject typically is an COM object with one of the following interfaces:
1009 * IExtractIcon,IDataObject,IContextMenu
1010 * In order to support icon positions in the default Listview your DataObject
1011 * must implement the SetData method (in addition to GetData :) - the shell passes
1012 * a barely documented "Icon positions" structure to SetData when the drag starts,
1013 * and GetData's it if the drop is in another explorer window that needs the positions.
1015 static HRESULT WINAPI IShellFolder_fnGetUIObjectOf(
1016 IShellFolder2 * iface,
1017 HWND hwndOwner,
1018 UINT cidl,
1019 LPCITEMIDLIST * apidl,
1020 REFIID riid,
1021 UINT * prgfInOut,
1022 LPVOID * ppvOut)
1024 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1026 LPITEMIDLIST pidl;
1027 IUnknown* pObj = NULL;
1028 HRESULT hr = E_INVALIDARG;
1030 TRACE("(%p)->(0x%04x,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
1031 This,hwndOwner,cidl,apidl,debugstr_guid(riid),prgfInOut,ppvOut);
1033 if (ppvOut)
1035 *ppvOut = NULL;
1037 if(IsEqualIID(riid, &IID_IContextMenu) && (cidl >= 1))
1039 pObj = (LPUNKNOWN)ISvItemCm_Constructor((IShellFolder*)iface, This->absPidl, apidl, cidl);
1040 hr = S_OK;
1042 else if (IsEqualIID(riid, &IID_IDataObject) &&(cidl >= 1))
1044 pObj = (LPUNKNOWN)IDataObject_Constructor (hwndOwner, This->absPidl, apidl, cidl);
1045 hr = S_OK;
1047 else if (IsEqualIID(riid, &IID_IExtractIconA) && (cidl == 1))
1049 pidl = ILCombine(This->absPidl,apidl[0]);
1050 pObj = (LPUNKNOWN)IExtractIconA_Constructor( pidl );
1051 SHFree(pidl);
1052 hr = S_OK;
1054 else if (IsEqualIID(riid, &IID_IDropTarget) && (cidl >= 1))
1056 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, (LPVOID*)&pObj);
1058 else
1060 hr = E_NOINTERFACE;
1063 if(!pObj)
1064 hr = E_OUTOFMEMORY;
1066 *ppvOut = pObj;
1068 TRACE("(%p)->hr=0x%08lx\n",This, hr);
1069 return hr;
1072 /**************************************************************************
1073 * IShellFolder_fnGetDisplayNameOf
1074 * Retrieves the display name for the specified file object or subfolder
1076 * PARAMETERS
1077 * LPCITEMIDLIST pidl, //[in ] complex pidl to item
1078 * DWORD dwFlags, //[in ] SHGNO formatting flags
1079 * LPSTRRET lpName) //[out] Returned display name
1081 * FIXME
1082 * if the name is in the pidl the ret value should be a STRRET_OFFSET
1084 #define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
1085 #define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
1087 static HRESULT WINAPI IShellFolder_fnGetDisplayNameOf(
1088 IShellFolder2 * iface,
1089 LPCITEMIDLIST pidl,
1090 DWORD dwFlags,
1091 LPSTRRET strRet)
1093 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1095 CHAR szPath[MAX_PATH]= "";
1096 int len = 0;
1097 BOOL bSimplePidl;
1099 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1100 pdump(pidl);
1102 if(!pidl || !strRet) return E_INVALIDARG;
1104 bSimplePidl = _ILIsPidlSimple(pidl);
1106 /* take names of special folders only if its only this folder */
1107 if (_ILIsSpecialFolder(pidl))
1109 if ( bSimplePidl)
1111 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
1114 else
1116 if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) && This->sMyPath)
1118 strcpy (szPath, This->sMyPath); /* get path to root*/
1119 PathAddBackslashA(szPath);
1120 len = strlen(szPath);
1122 _ILSimpleGetText(pidl, szPath + len, MAX_PATH - len); /* append my own path */
1125 if ( (dwFlags & SHGDN_FORPARSING) && !bSimplePidl) /* go deeper if needed */
1127 PathAddBackslashA(szPath);
1128 len = strlen(szPath);
1130 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath + len, MAX_PATH - len)))
1131 return E_OUTOFMEMORY;
1133 strRet->uType = STRRET_CSTRA;
1134 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1136 TRACE("-- (%p)->(%s)\n", This, szPath);
1137 return S_OK;
1140 /**************************************************************************
1141 * IShellFolder_fnSetNameOf
1142 * Changes the name of a file object or subfolder, possibly changing its item
1143 * identifier in the process.
1145 * PARAMETERS
1146 * HWND hwndOwner, //[in ] Owner window for output
1147 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
1148 * LPCOLESTR lpszName, //[in ] the items new display name
1149 * DWORD dwFlags, //[in ] SHGNO formatting flags
1150 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
1152 static HRESULT WINAPI IShellFolder_fnSetNameOf(
1153 IShellFolder2 * iface,
1154 HWND hwndOwner,
1155 LPCITEMIDLIST pidl, /*simple pidl*/
1156 LPCOLESTR lpName,
1157 DWORD dwFlags,
1158 LPITEMIDLIST *pPidlOut)
1160 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1161 char szSrc[MAX_PATH], szDest[MAX_PATH];
1162 int len;
1163 BOOL bIsFolder = _ILIsFolder(ILFindLastID(pidl));
1165 TRACE("(%p)->(%u,pidl=%p,%s,%lu,%p)\n",
1166 This,hwndOwner,pidl,debugstr_w(lpName),dwFlags,pPidlOut);
1168 /* build source path */
1169 if (dwFlags & SHGDN_INFOLDER)
1171 strcpy(szSrc, This->sMyPath);
1172 PathAddBackslashA(szSrc);
1173 len = strlen (szSrc);
1174 _ILSimpleGetText(pidl, szSrc+len, MAX_PATH-len);
1176 else
1178 SHGetPathFromIDListA(pidl, szSrc);
1181 /* build destination path */
1182 strcpy(szDest, This->sMyPath);
1183 PathAddBackslashA(szDest);
1184 len = strlen (szDest);
1185 WideCharToMultiByte( CP_ACP, 0, lpName, -1, szDest+len, MAX_PATH-len, NULL, NULL );
1186 szDest[MAX_PATH-1] = 0;
1187 TRACE("src=%s dest=%s\n", szSrc, szDest);
1188 if ( MoveFileA(szSrc, szDest) )
1190 if (pPidlOut) *pPidlOut = SHSimpleIDListFromPathA(szDest);
1191 SHChangeNotifyA( bIsFolder?SHCNE_RENAMEFOLDER:SHCNE_RENAMEITEM, SHCNF_PATHA, szSrc, szDest);
1192 return S_OK;
1194 return E_FAIL;
1197 static HRESULT WINAPI IShellFolder_fnGetDefaultSearchGUID(
1198 IShellFolder2 * iface,
1199 GUID *pguid)
1201 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1202 FIXME("(%p)\n",This);
1203 return E_NOTIMPL;
1205 static HRESULT WINAPI IShellFolder_fnEnumSearches(
1206 IShellFolder2 * iface,
1207 IEnumExtraSearch **ppenum)
1209 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1210 FIXME("(%p)\n",This);
1211 return E_NOTIMPL;
1213 static HRESULT WINAPI IShellFolder_fnGetDefaultColumn(
1214 IShellFolder2 * iface,
1215 DWORD dwRes,
1216 ULONG *pSort,
1217 ULONG *pDisplay)
1219 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1221 TRACE("(%p)\n",This);
1223 if (pSort) *pSort = 0;
1224 if (pDisplay) *pDisplay = 0;
1226 return S_OK;
1228 static HRESULT WINAPI IShellFolder_fnGetDefaultColumnState(
1229 IShellFolder2 * iface,
1230 UINT iColumn,
1231 DWORD *pcsFlags)
1233 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1235 TRACE("(%p)\n",This);
1237 if (!pcsFlags || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1239 *pcsFlags = GenericSFHeader[iColumn].pcsFlags;
1241 return S_OK;
1243 static HRESULT WINAPI IShellFolder_fnGetDetailsEx(
1244 IShellFolder2 * iface,
1245 LPCITEMIDLIST pidl,
1246 const SHCOLUMNID *pscid,
1247 VARIANT *pv)
1249 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1250 FIXME("(%p)\n",This);
1252 return E_NOTIMPL;
1254 static HRESULT WINAPI IShellFolder_fnGetDetailsOf(
1255 IShellFolder2 * iface,
1256 LPCITEMIDLIST pidl,
1257 UINT iColumn,
1258 SHELLDETAILS *psd)
1260 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1261 HRESULT hr = E_FAIL;
1263 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
1265 if (!psd || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1267 if (!pidl)
1269 /* the header titles */
1270 psd->fmt = GenericSFHeader[iColumn].fmt;
1271 psd->cxChar = GenericSFHeader[iColumn].cxChar;
1272 psd->str.uType = STRRET_CSTRA;
1273 LoadStringA(shell32_hInstance, GenericSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
1274 return S_OK;
1276 else
1278 /* the data from the pidl */
1279 switch(iColumn)
1281 case 0: /* name */
1282 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
1283 break;
1284 case 1: /* size */
1285 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
1286 break;
1287 case 2: /* type */
1288 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
1289 break;
1290 case 3: /* date */
1291 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
1292 break;
1293 case 4: /* attributes */
1294 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
1295 break;
1297 hr = S_OK;
1298 psd->str.uType = STRRET_CSTRA;
1301 return hr;
1303 static HRESULT WINAPI IShellFolder_fnMapNameToSCID(
1304 IShellFolder2 * iface,
1305 LPCWSTR pwszName,
1306 SHCOLUMNID *pscid)
1308 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1309 FIXME("(%p)\n",This);
1310 return E_NOTIMPL;
1313 static ICOM_VTABLE(IShellFolder2) sfvt =
1315 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1316 IShellFolder_fnQueryInterface,
1317 IShellFolder_fnAddRef,
1318 IShellFolder_fnRelease,
1319 IShellFolder_fnParseDisplayName,
1320 IShellFolder_fnEnumObjects,
1321 IShellFolder_fnBindToObject,
1322 IShellFolder_fnBindToStorage,
1323 IShellFolder_fnCompareIDs,
1324 IShellFolder_fnCreateViewObject,
1325 IShellFolder_fnGetAttributesOf,
1326 IShellFolder_fnGetUIObjectOf,
1327 IShellFolder_fnGetDisplayNameOf,
1328 IShellFolder_fnSetNameOf,
1330 /* ShellFolder2 */
1331 IShellFolder_fnGetDefaultSearchGUID,
1332 IShellFolder_fnEnumSearches,
1333 IShellFolder_fnGetDefaultColumn,
1334 IShellFolder_fnGetDefaultColumnState,
1335 IShellFolder_fnGetDetailsEx,
1336 IShellFolder_fnGetDetailsOf,
1337 IShellFolder_fnMapNameToSCID
1340 /****************************************************************************
1341 * ISFHelper for IShellFolder implementation
1344 static HRESULT WINAPI ISFHelper_fnQueryInterface(
1345 ISFHelper *iface,
1346 REFIID riid,
1347 LPVOID *ppvObj)
1349 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1351 TRACE("(%p)\n", This);
1353 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
1356 static ULONG WINAPI ISFHelper_fnAddRef(
1357 ISFHelper *iface)
1359 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1361 TRACE("(%p)\n", This);
1363 return IUnknown_AddRef(This->pUnkOuter);
1366 static ULONG WINAPI ISFHelper_fnRelease(
1367 ISFHelper *iface)
1369 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1371 TRACE("(%p)\n", This);
1373 return IUnknown_Release(This->pUnkOuter);
1377 /****************************************************************************
1378 * ISFHelper_fnAddFolder
1380 * creates a unique folder name
1383 static HRESULT WINAPI ISFHelper_fnGetUniqueName(
1384 ISFHelper *iface,
1385 LPSTR lpName,
1386 UINT uLen)
1388 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1389 IEnumIDList * penum;
1390 HRESULT hr;
1391 char szText[MAX_PATH];
1392 char * szNewFolder = "New Folder";
1394 TRACE("(%p)(%s %u)\n", This, lpName, uLen);
1396 if (uLen < strlen(szNewFolder) + 4) return E_POINTER;
1398 strcpy(lpName, szNewFolder);
1400 hr = IShellFolder_fnEnumObjects(_IShellFolder2_(This), 0, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penum);
1401 if (penum)
1403 LPITEMIDLIST pidl;
1404 DWORD dwFetched;
1405 int i=1;
1407 next: IEnumIDList_Reset(penum);
1408 while(S_OK == IEnumIDList_Next(penum, 1, &pidl, &dwFetched) && dwFetched)
1410 _ILSimpleGetText(pidl, szText, MAX_PATH);
1411 if (0 == strcasecmp(szText, lpName))
1413 sprintf(lpName, "%s %d", szNewFolder, i++);
1414 if (i > 99)
1416 hr = E_FAIL;
1417 break;
1419 goto next;
1423 IEnumIDList_Release(penum);
1425 return hr;
1428 /****************************************************************************
1429 * ISFHelper_fnAddFolder
1431 * adds a new folder.
1434 static HRESULT WINAPI ISFHelper_fnAddFolder(
1435 ISFHelper *iface,
1436 HWND hwnd,
1437 LPCSTR lpName,
1438 LPITEMIDLIST* ppidlOut)
1440 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1441 char lpstrNewDir[MAX_PATH];
1442 DWORD bRes;
1443 HRESULT hres = E_FAIL;
1445 TRACE("(%p)(%s %p)\n", This, lpName, ppidlOut);
1447 strcpy(lpstrNewDir, This->sMyPath);
1448 PathAddBackslashA(lpstrNewDir);
1449 strcat(lpstrNewDir, lpName);
1451 bRes = CreateDirectoryA(lpstrNewDir, NULL);
1453 if (bRes)
1455 LPITEMIDLIST pidl, pidlitem;
1457 pidlitem = SHSimpleIDListFromPathA(lpstrNewDir);
1459 pidl = ILCombine(This->absPidl, pidlitem);
1460 SHChangeNotifyA(SHCNE_MKDIR, SHCNF_IDLIST, pidl, NULL);
1461 SHFree(pidl);
1463 if (ppidlOut) *ppidlOut = pidlitem;
1464 hres = S_OK;
1466 else
1468 char lpstrText[128+MAX_PATH];
1469 char lpstrTempText[128];
1470 char lpstrCaption[256];
1472 /* Cannot Create folder because of permissions */
1473 LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_DENIED, lpstrTempText, sizeof(lpstrTempText));
1474 LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_CAPTION, lpstrCaption, sizeof(lpstrCaption));
1475 sprintf(lpstrText,lpstrTempText, lpstrNewDir);
1476 MessageBoxA(hwnd,lpstrText, lpstrCaption, MB_OK | MB_ICONEXCLAMATION);
1479 return hres;
1482 /****************************************************************************
1483 * ISFHelper_fnDeleteItems
1485 * deletes items in folder
1487 static HRESULT WINAPI ISFHelper_fnDeleteItems(
1488 ISFHelper *iface,
1489 UINT cidl,
1490 LPCITEMIDLIST* apidl)
1492 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1493 int i;
1494 char szPath[MAX_PATH];
1495 BOOL bConfirm = TRUE;
1497 TRACE("(%p)(%u %p)\n", This, cidl, apidl);
1499 /* deleting multiple items so give a slightly different warning */
1500 if(cidl != 1)
1502 char tmp[8];
1503 snprintf(tmp, sizeof(tmp), "%d", cidl);
1504 if(!SHELL_WarnItemDelete(ASK_DELETE_MULTIPLE_ITEM, tmp))
1505 return E_FAIL;
1506 bConfirm = FALSE;
1509 for(i=0; i< cidl; i++)
1511 strcpy(szPath, This->sMyPath);
1512 PathAddBackslashA(szPath);
1513 _ILSimpleGetText(apidl[i], szPath+strlen(szPath), MAX_PATH);
1515 if (_ILIsFolder(apidl[i]))
1517 LPITEMIDLIST pidl;
1518 TRACE("delete %s\n", szPath);
1519 if (! SHELL_DeleteDirectoryA(szPath, bConfirm))
1521 TRACE("delete %s failed, bConfirm=%d", szPath, bConfirm);
1522 return E_FAIL;
1524 pidl = ILCombine(This->absPidl, apidl[i]);
1525 SHChangeNotifyA(SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);
1526 SHFree(pidl);
1528 else if (_ILIsValue(apidl[i]))
1530 LPITEMIDLIST pidl;
1532 TRACE("delete %s\n", szPath);
1533 if (! SHELL_DeleteFileA(szPath, bConfirm))
1535 TRACE("delete %s failed, bConfirm=%d", szPath, bConfirm);
1536 return E_FAIL;
1538 pidl = ILCombine(This->absPidl, apidl[i]);
1539 SHChangeNotifyA(SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);
1540 SHFree(pidl);
1544 return S_OK;
1547 /****************************************************************************
1548 * ISFHelper_fnCopyItems
1550 * copys items to this folder
1552 static HRESULT WINAPI ISFHelper_fnCopyItems(
1553 ISFHelper *iface,
1554 IShellFolder* pSFFrom,
1555 UINT cidl,
1556 LPCITEMIDLIST *apidl)
1558 int i;
1559 IPersistFolder2 * ppf2=NULL;
1560 char szSrcPath[MAX_PATH], szDstPath[MAX_PATH];
1561 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1563 TRACE("(%p)->(%p,%u,%p)\n", This, pSFFrom, cidl, apidl);
1565 IShellFolder_QueryInterface(pSFFrom, &IID_IPersistFolder2, (LPVOID*)&ppf2);
1566 if (ppf2)
1568 LPITEMIDLIST pidl;
1569 if (SUCCEEDED(IPersistFolder2_GetCurFolder(ppf2, &pidl)))
1571 for (i=0; i<cidl; i++)
1573 SHGetPathFromIDListA(pidl, szSrcPath);
1574 PathAddBackslashA(szSrcPath);
1575 _ILSimpleGetText(apidl[i], szSrcPath+strlen(szSrcPath), MAX_PATH);
1577 strcpy(szDstPath, This->sMyPath);
1578 PathAddBackslashA(szDstPath);
1579 _ILSimpleGetText(apidl[i], szDstPath+strlen(szDstPath), MAX_PATH);
1580 MESSAGE("would copy %s to %s\n", szSrcPath, szDstPath);
1582 SHFree(pidl);
1584 IPersistFolder2_Release(ppf2);
1586 return S_OK;
1589 static ICOM_VTABLE(ISFHelper) shvt =
1591 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1592 ISFHelper_fnQueryInterface,
1593 ISFHelper_fnAddRef,
1594 ISFHelper_fnRelease,
1595 ISFHelper_fnGetUniqueName,
1596 ISFHelper_fnAddFolder,
1597 ISFHelper_fnDeleteItems,
1598 ISFHelper_fnCopyItems,
1601 /***********************************************************************
1602 * [Desktopfolder] IShellFolder implementation
1604 static struct ICOM_VTABLE(IShellFolder2) sfdvt;
1606 static shvheader DesktopSFHeader [] =
1608 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
1609 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1610 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1611 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
1612 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
1614 #define DESKTOPSHELLVIEWCOLUMNS 5
1616 /**************************************************************************
1617 * ISF_Desktop_Constructor
1620 IShellFolder * ISF_Desktop_Constructor()
1622 IGenericSFImpl * sf;
1624 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
1625 sf->ref=1;
1626 ICOM_VTBL(sf)=&unkvt;
1627 sf->lpvtblShellFolder=&sfdvt;
1628 sf->absPidl=_ILCreateDesktop(); /* my qualified pidl */
1629 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
1631 TRACE("(%p)\n",sf);
1633 shell32_ObjCount++;
1634 return _IShellFolder_(sf);
1637 /**************************************************************************
1638 * ISF_Desktop_fnQueryInterface
1640 * NOTES supports not IPersist/IPersistFolder
1642 static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
1643 IShellFolder2 * iface,
1644 REFIID riid,
1645 LPVOID *ppvObj)
1647 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1649 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1651 *ppvObj = NULL;
1653 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
1655 *ppvObj = _IUnknown_(This);
1657 else if(IsEqualIID(riid, &IID_IShellFolder)) /*IShellFolder*/
1659 *ppvObj = _IShellFolder_(This);
1661 else if(IsEqualIID(riid, &IID_IShellFolder2)) /*IShellFolder2*/
1663 *ppvObj = _IShellFolder_(This);
1666 if(*ppvObj)
1668 IUnknown_AddRef((IUnknown*)(*ppvObj));
1669 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1670 return S_OK;
1672 TRACE("-- Interface: E_NOINTERFACE\n");
1673 return E_NOINTERFACE;
1676 /**************************************************************************
1677 * ISF_Desktop_fnParseDisplayName
1679 * NOTES
1680 * "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
1681 * to MyComputer
1683 static HRESULT WINAPI ISF_Desktop_fnParseDisplayName(
1684 IShellFolder2 * iface,
1685 HWND hwndOwner,
1686 LPBC pbcReserved,
1687 LPOLESTR lpszDisplayName,
1688 DWORD *pchEaten,
1689 LPITEMIDLIST *ppidl,
1690 DWORD *pdwAttributes)
1692 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1694 LPCWSTR szNext=NULL;
1695 LPITEMIDLIST pidlTemp=NULL;
1696 HRESULT hr=E_OUTOFMEMORY;
1698 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1699 This,hwndOwner,pbcReserved,lpszDisplayName,
1700 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
1702 *ppidl = 0;
1703 if (pchEaten) *pchEaten = 0; /* strange but like the original */
1705 /* fixme no real parsing implemented */
1706 pidlTemp = _ILCreateMyComputer();
1707 szNext = lpszDisplayName;
1709 if (szNext && *szNext)
1711 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
1713 else
1715 hr = S_OK;
1717 if (pdwAttributes && *pdwAttributes)
1719 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
1723 *ppidl = pidlTemp;
1725 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
1727 return hr;
1730 /**************************************************************************
1731 * ISF_Desktop_fnEnumObjects
1733 static HRESULT WINAPI ISF_Desktop_fnEnumObjects(
1734 IShellFolder2 * iface,
1735 HWND hwndOwner,
1736 DWORD dwFlags,
1737 LPENUMIDLIST* ppEnumIDList)
1739 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1741 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
1743 *ppEnumIDList = NULL;
1744 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_DESK);
1746 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
1748 if(!*ppEnumIDList) return E_OUTOFMEMORY;
1750 return S_OK;
1753 /**************************************************************************
1754 * ISF_Desktop_fnBindToObject
1756 static HRESULT WINAPI ISF_Desktop_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
1757 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
1759 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1760 GUID const * clsid;
1761 IShellFolder *pShellFolder, *pSubFolder;
1763 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
1764 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
1766 *ppvOut = NULL;
1768 if ((clsid=_ILGetGUIDPointer(pidl)))
1770 if ( IsEqualIID(clsid, &CLSID_MyComputer))
1772 pShellFolder = ISF_MyComputer_Constructor();
1774 else
1776 /* shell extension */
1777 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
1779 return E_INVALIDARG;
1783 else
1785 /* file system folder on the desktop */
1786 LPITEMIDLIST deskpidl, firstpidl, completepidl;
1787 IPersistFolder * ppf;
1789 /* combine pidls */
1790 SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, &deskpidl);
1791 firstpidl = ILCloneFirst(pidl);
1792 completepidl = ILCombine(deskpidl, firstpidl);
1794 pShellFolder = IShellFolder_Constructor(NULL, NULL);
1795 if (SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&ppf)))
1797 IPersistFolder_Initialize(ppf, completepidl);
1798 IPersistFolder_Release(ppf);
1800 ILFree(completepidl);
1801 ILFree(deskpidl);
1802 ILFree(firstpidl);
1805 if (_ILIsPidlSimple(pidl)) /* no sub folders */
1807 *ppvOut = pShellFolder;
1809 else /* go deeper */
1811 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, riid, (LPVOID)&pSubFolder);
1812 IShellFolder_Release(pShellFolder);
1813 *ppvOut = pSubFolder;
1816 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
1818 return S_OK;
1821 /**************************************************************************
1822 * ISF_Desktop_fnCreateViewObject
1824 static HRESULT WINAPI ISF_Desktop_fnCreateViewObject( IShellFolder2 * iface,
1825 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
1827 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1829 LPSHELLVIEW pShellView;
1830 HRESULT hr = E_INVALIDARG;
1832 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
1834 if(ppvOut)
1836 *ppvOut = NULL;
1838 if(IsEqualIID(riid, &IID_IDropTarget))
1840 WARN("IDropTarget not implemented\n");
1841 hr = E_NOTIMPL;
1843 else if(IsEqualIID(riid, &IID_IContextMenu))
1845 WARN("IContextMenu not implemented\n");
1846 hr = E_NOTIMPL;
1848 else if(IsEqualIID(riid, &IID_IShellView))
1850 pShellView = IShellView_Constructor((IShellFolder*)iface);
1851 if(pShellView)
1853 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
1854 IShellView_Release(pShellView);
1858 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
1859 return hr;
1862 /**************************************************************************
1863 * ISF_Desktop_fnGetAttributesOf
1865 static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf(
1866 IShellFolder2 * iface,
1867 UINT cidl,
1868 LPCITEMIDLIST *apidl,
1869 DWORD *rgfInOut)
1871 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1873 HRESULT hr = S_OK;
1875 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl, *rgfInOut);
1877 if ( (!cidl) || (!apidl) || (!rgfInOut))
1878 return E_INVALIDARG;
1880 while (cidl > 0 && *apidl)
1882 pdump (*apidl);
1883 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
1884 apidl++;
1885 cidl--;
1888 TRACE("-- result=0x%08lx\n",*rgfInOut);
1890 return hr;
1893 /**************************************************************************
1894 * ISF_Desktop_fnGetDisplayNameOf
1896 * NOTES
1897 * special case: pidl = null gives desktop-name back
1899 static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf(
1900 IShellFolder2 * iface,
1901 LPCITEMIDLIST pidl,
1902 DWORD dwFlags,
1903 LPSTRRET strRet)
1905 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1907 CHAR szPath[MAX_PATH]= "";
1909 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1910 pdump(pidl);
1912 if(!strRet) return E_INVALIDARG;
1914 if(!pidl)
1916 HCR_GetClassName(&CLSID_ShellDesktop, szPath, MAX_PATH);
1918 else if ( _ILIsPidlSimple(pidl) )
1920 _ILSimpleGetText(pidl, szPath, MAX_PATH);
1922 else
1924 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath, MAX_PATH)))
1925 return E_OUTOFMEMORY;
1927 strRet->uType = STRRET_CSTRA;
1928 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1931 TRACE("-- (%p)->(%s)\n", This, szPath);
1932 return S_OK;
1935 static HRESULT WINAPI ISF_Desktop_fnGetDefaultSearchGUID(
1936 IShellFolder2 * iface,
1937 GUID *pguid)
1939 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1940 FIXME("(%p)\n",This);
1941 return E_NOTIMPL;
1943 static HRESULT WINAPI ISF_Desktop_fnEnumSearches(
1944 IShellFolder2 * iface,
1945 IEnumExtraSearch **ppenum)
1947 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1948 FIXME("(%p)\n",This);
1949 return E_NOTIMPL;
1951 static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumn(
1952 IShellFolder2 * iface,
1953 DWORD dwRes,
1954 ULONG *pSort,
1955 ULONG *pDisplay)
1957 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1959 TRACE("(%p)\n",This);
1961 if (pSort) *pSort = 0;
1962 if (pDisplay) *pDisplay = 0;
1964 return S_OK;
1966 static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumnState(
1967 IShellFolder2 * iface,
1968 UINT iColumn,
1969 DWORD *pcsFlags)
1971 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1973 TRACE("(%p)\n",This);
1975 if (!pcsFlags || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1977 *pcsFlags = DesktopSFHeader[iColumn].pcsFlags;
1979 return S_OK;
1981 static HRESULT WINAPI ISF_Desktop_fnGetDetailsEx(
1982 IShellFolder2 * iface,
1983 LPCITEMIDLIST pidl,
1984 const SHCOLUMNID *pscid,
1985 VARIANT *pv)
1987 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1988 FIXME("(%p)\n",This);
1990 return E_NOTIMPL;
1992 static HRESULT WINAPI ISF_Desktop_fnGetDetailsOf(
1993 IShellFolder2 * iface,
1994 LPCITEMIDLIST pidl,
1995 UINT iColumn,
1996 SHELLDETAILS *psd)
1998 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1999 HRESULT hr = E_FAIL;;
2001 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
2003 if (!psd || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2005 if (!pidl)
2007 psd->fmt = DesktopSFHeader[iColumn].fmt;
2008 psd->cxChar = DesktopSFHeader[iColumn].cxChar;
2009 psd->str.uType = STRRET_CSTRA;
2010 LoadStringA(shell32_hInstance, DesktopSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
2011 return S_OK;
2013 else
2015 /* the data from the pidl */
2016 switch(iColumn)
2018 case 0: /* name */
2019 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2020 break;
2021 case 1: /* size */
2022 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
2023 break;
2024 case 2: /* type */
2025 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2026 break;
2027 case 3: /* date */
2028 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
2029 break;
2030 case 4: /* attributes */
2031 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
2032 break;
2034 hr = S_OK;
2035 psd->str.uType = STRRET_CSTRA;
2038 return hr;
2040 static HRESULT WINAPI ISF_Desktop_fnMapNameToSCID(
2041 IShellFolder2 * iface,
2042 LPCWSTR pwszName,
2043 SHCOLUMNID *pscid)
2045 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2046 FIXME("(%p)\n",This);
2047 return E_NOTIMPL;
2050 static ICOM_VTABLE(IShellFolder2) sfdvt =
2052 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2053 ISF_Desktop_fnQueryInterface,
2054 IShellFolder_fnAddRef,
2055 IShellFolder_fnRelease,
2056 ISF_Desktop_fnParseDisplayName,
2057 ISF_Desktop_fnEnumObjects,
2058 ISF_Desktop_fnBindToObject,
2059 IShellFolder_fnBindToStorage,
2060 IShellFolder_fnCompareIDs,
2061 ISF_Desktop_fnCreateViewObject,
2062 ISF_Desktop_fnGetAttributesOf,
2063 IShellFolder_fnGetUIObjectOf,
2064 ISF_Desktop_fnGetDisplayNameOf,
2065 IShellFolder_fnSetNameOf,
2067 /* ShellFolder2 */
2068 ISF_Desktop_fnGetDefaultSearchGUID,
2069 ISF_Desktop_fnEnumSearches,
2070 ISF_Desktop_fnGetDefaultColumn,
2071 ISF_Desktop_fnGetDefaultColumnState,
2072 ISF_Desktop_fnGetDetailsEx,
2073 ISF_Desktop_fnGetDetailsOf,
2074 ISF_Desktop_fnMapNameToSCID
2078 /***********************************************************************
2079 * IShellFolder [MyComputer] implementation
2082 static struct ICOM_VTABLE(IShellFolder2) sfmcvt;
2084 static shvheader MyComputerSFHeader [] =
2086 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
2087 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2088 { IDS_SHV_COLUMN6, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2089 { IDS_SHV_COLUMN7, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2091 #define MYCOMPUTERSHELLVIEWCOLUMNS 4
2093 /**************************************************************************
2094 * ISF_MyComputer_Constructor
2096 static IShellFolder * ISF_MyComputer_Constructor(void)
2098 IGenericSFImpl * sf;
2100 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
2101 sf->ref=1;
2103 ICOM_VTBL(sf)=&unkvt;
2104 sf->lpvtblShellFolder=&sfmcvt;
2105 sf->lpvtblPersistFolder2 = &psfvt;
2106 sf->pclsid = (CLSID*)&CLSID_SFMyComp;
2107 sf->absPidl=_ILCreateMyComputer(); /* my qualified pidl */
2108 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
2110 TRACE("(%p)\n",sf);
2112 shell32_ObjCount++;
2113 return _IShellFolder_(sf);
2116 /**************************************************************************
2117 * ISF_MyComputer_fnParseDisplayName
2119 static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName(
2120 IShellFolder2 * iface,
2121 HWND hwndOwner,
2122 LPBC pbcReserved,
2123 LPOLESTR lpszDisplayName,
2124 DWORD *pchEaten,
2125 LPITEMIDLIST *ppidl,
2126 DWORD *pdwAttributes)
2128 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2130 HRESULT hr = E_OUTOFMEMORY;
2131 LPCWSTR szNext=NULL;
2132 WCHAR szElement[MAX_PATH];
2133 CHAR szTempA[MAX_PATH];
2134 LPITEMIDLIST pidlTemp;
2136 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
2137 This,hwndOwner,pbcReserved,lpszDisplayName,
2138 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
2140 *ppidl = 0;
2141 if (pchEaten) *pchEaten = 0; /* strange but like the original */
2143 /* do we have an absolute path name ? */
2144 if (PathGetDriveNumberW(lpszDisplayName) >= 0 &&
2145 lpszDisplayName[2] == (WCHAR)'\\')
2147 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
2148 WideCharToMultiByte( CP_ACP, 0, szElement, -1, szTempA, MAX_PATH, NULL, NULL );
2149 pidlTemp = _ILCreateDrive(szTempA);
2151 if (szNext && *szNext)
2153 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
2155 else
2157 if (pdwAttributes && *pdwAttributes)
2159 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
2161 hr = S_OK;
2163 *ppidl = pidlTemp;
2166 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
2168 return hr;
2171 /**************************************************************************
2172 * ISF_MyComputer_fnEnumObjects
2174 static HRESULT WINAPI ISF_MyComputer_fnEnumObjects(
2175 IShellFolder2 * iface,
2176 HWND hwndOwner,
2177 DWORD dwFlags,
2178 LPENUMIDLIST* ppEnumIDList)
2180 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2182 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
2184 *ppEnumIDList = NULL;
2185 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_MYCOMP);
2187 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
2189 if(!*ppEnumIDList) return E_OUTOFMEMORY;
2191 return S_OK;
2194 /**************************************************************************
2195 * ISF_MyComputer_fnBindToObject
2197 static HRESULT WINAPI ISF_MyComputer_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
2198 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
2200 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2201 GUID const * clsid;
2202 IShellFolder *pShellFolder, *pSubFolder;
2203 LPITEMIDLIST pidltemp;
2205 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
2206 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
2208 if(!pidl || !ppvOut) return E_INVALIDARG;
2210 *ppvOut = NULL;
2212 if ((clsid=_ILGetGUIDPointer(pidl)) && !IsEqualIID(clsid, &CLSID_MyComputer))
2214 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
2216 return E_FAIL;
2219 else
2221 if (!_ILIsDrive(pidl)) return E_INVALIDARG;
2223 pidltemp = ILCloneFirst(pidl);
2224 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
2225 ILFree(pidltemp);
2228 if (_ILIsPidlSimple(pidl)) /* no sub folders */
2230 *ppvOut = pShellFolder;
2232 else /* go deeper */
2234 IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, &IID_IShellFolder, (LPVOID)&pSubFolder);
2235 IShellFolder_Release(pShellFolder);
2236 *ppvOut = pSubFolder;
2239 TRACE("-- (%p) returning (%p)\n",This, *ppvOut);
2241 return S_OK;
2244 /**************************************************************************
2245 * ISF_MyComputer_fnCreateViewObject
2247 static HRESULT WINAPI ISF_MyComputer_fnCreateViewObject( IShellFolder2 * iface,
2248 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
2250 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2252 LPSHELLVIEW pShellView;
2253 HRESULT hr = E_INVALIDARG;
2255 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
2257 if(ppvOut)
2259 *ppvOut = NULL;
2261 if(IsEqualIID(riid, &IID_IDropTarget))
2263 WARN("IDropTarget not implemented\n");
2264 hr = E_NOTIMPL;
2266 else if(IsEqualIID(riid, &IID_IContextMenu))
2268 WARN("IContextMenu not implemented\n");
2269 hr = E_NOTIMPL;
2271 else if(IsEqualIID(riid, &IID_IShellView))
2273 pShellView = IShellView_Constructor((IShellFolder*)iface);
2274 if(pShellView)
2276 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
2277 IShellView_Release(pShellView);
2281 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
2282 return hr;
2285 /**************************************************************************
2286 * ISF_MyComputer_fnGetAttributesOf
2288 static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf(
2289 IShellFolder2 * iface,
2290 UINT cidl,
2291 LPCITEMIDLIST *apidl,
2292 DWORD *rgfInOut)
2294 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2296 HRESULT hr = S_OK;
2298 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
2300 if ( (!cidl) || (!apidl) || (!rgfInOut))
2301 return E_INVALIDARG;
2303 while (cidl > 0 && *apidl)
2305 pdump (*apidl);
2306 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
2307 apidl++;
2308 cidl--;
2311 TRACE("-- result=0x%08lx\n",*rgfInOut);
2312 return hr;
2315 /**************************************************************************
2316 * ISF_MyComputer_fnGetDisplayNameOf
2318 * NOTES
2319 * The desktopfolder creates only complete paths (SHGDN_FORPARSING).
2320 * SHGDN_INFOLDER makes no sense.
2322 static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf(
2323 IShellFolder2 * iface,
2324 LPCITEMIDLIST pidl,
2325 DWORD dwFlags,
2326 LPSTRRET strRet)
2328 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2330 char szPath[MAX_PATH], szDrive[18];
2331 int len = 0;
2332 BOOL bSimplePidl;
2334 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
2335 pdump(pidl);
2337 if(!strRet) return E_INVALIDARG;
2339 szPath[0]=0x00; szDrive[0]=0x00;
2342 bSimplePidl = _ILIsPidlSimple(pidl);
2344 if (_ILIsSpecialFolder(pidl))
2346 /* take names of special folders only if its only this folder */
2347 if ( bSimplePidl )
2349 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2352 else
2354 if (!_ILIsDrive(pidl))
2356 ERR("Wrong pidl type\n");
2357 return E_INVALIDARG;
2360 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2362 /* long view "lw_name (C:)" */
2363 if ( bSimplePidl && !(dwFlags & SHGDN_FORPARSING))
2365 DWORD dwVolumeSerialNumber,dwMaximumComponetLength,dwFileSystemFlags;
2367 GetVolumeInformationA(szPath,szDrive,12,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0);
2368 strcat (szDrive," (");
2369 strncat (szDrive, szPath, 2);
2370 strcat (szDrive,")");
2371 strcpy (szPath, szDrive);
2375 if (!bSimplePidl) /* go deeper if needed */
2377 PathAddBackslashA(szPath);
2378 len = strlen(szPath);
2380 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags | SHGDN_FORPARSING, szPath + len, MAX_PATH - len)))
2381 return E_OUTOFMEMORY;
2383 strRet->uType = STRRET_CSTRA;
2384 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
2387 TRACE("-- (%p)->(%s)\n", This, szPath);
2388 return S_OK;
2391 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultSearchGUID(
2392 IShellFolder2 * iface,
2393 GUID *pguid)
2395 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2396 FIXME("(%p)\n",This);
2397 return E_NOTIMPL;
2399 static HRESULT WINAPI ISF_MyComputer_fnEnumSearches(
2400 IShellFolder2 * iface,
2401 IEnumExtraSearch **ppenum)
2403 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2404 FIXME("(%p)\n",This);
2405 return E_NOTIMPL;
2407 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumn(
2408 IShellFolder2 * iface,
2409 DWORD dwRes,
2410 ULONG *pSort,
2411 ULONG *pDisplay)
2413 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2415 TRACE("(%p)\n",This);
2417 if (pSort) *pSort = 0;
2418 if (pDisplay) *pDisplay = 0;
2420 return S_OK;
2422 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumnState(
2423 IShellFolder2 * iface,
2424 UINT iColumn,
2425 DWORD *pcsFlags)
2427 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2429 TRACE("(%p)\n",This);
2431 if (!pcsFlags || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2433 *pcsFlags = MyComputerSFHeader[iColumn].pcsFlags;
2435 return S_OK;
2437 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsEx(
2438 IShellFolder2 * iface,
2439 LPCITEMIDLIST pidl,
2440 const SHCOLUMNID *pscid,
2441 VARIANT *pv)
2443 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2444 FIXME("(%p)\n",This);
2446 return E_NOTIMPL;
2449 /* fixme: drive size >4GB is rolling over */
2450 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf(
2451 IShellFolder2 * iface,
2452 LPCITEMIDLIST pidl,
2453 UINT iColumn,
2454 SHELLDETAILS *psd)
2456 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2457 HRESULT hr;
2459 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
2461 if (!psd || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2463 if (!pidl)
2465 psd->fmt = MyComputerSFHeader[iColumn].fmt;
2466 psd->cxChar = MyComputerSFHeader[iColumn].cxChar;
2467 psd->str.uType = STRRET_CSTRA;
2468 LoadStringA(shell32_hInstance, MyComputerSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
2469 return S_OK;
2471 else
2473 char szPath[MAX_PATH];
2474 ULARGE_INTEGER ulBytes;
2476 psd->str.u.cStr[0] = 0x00;
2477 psd->str.uType = STRRET_CSTRA;
2478 switch(iColumn)
2480 case 0: /* name */
2481 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2482 break;
2483 case 1: /* type */
2484 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2485 break;
2486 case 2: /* total size */
2487 if (_ILIsDrive(pidl))
2489 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2490 GetDiskFreeSpaceExA(szPath, NULL, &ulBytes, NULL);
2491 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2493 break;
2494 case 3: /* free size */
2495 if (_ILIsDrive(pidl))
2497 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2498 GetDiskFreeSpaceExA(szPath, &ulBytes, NULL, NULL);
2499 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2501 break;
2503 hr = S_OK;
2506 return hr;
2508 static HRESULT WINAPI ISF_MyComputer_fnMapNameToSCID(
2509 IShellFolder2 * iface,
2510 LPCWSTR pwszName,
2511 SHCOLUMNID *pscid)
2513 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2514 FIXME("(%p)\n",This);
2515 return E_NOTIMPL;
2518 static ICOM_VTABLE(IShellFolder2) sfmcvt =
2520 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2521 IShellFolder_fnQueryInterface,
2522 IShellFolder_fnAddRef,
2523 IShellFolder_fnRelease,
2524 ISF_MyComputer_fnParseDisplayName,
2525 ISF_MyComputer_fnEnumObjects,
2526 ISF_MyComputer_fnBindToObject,
2527 IShellFolder_fnBindToStorage,
2528 IShellFolder_fnCompareIDs,
2529 ISF_MyComputer_fnCreateViewObject,
2530 ISF_MyComputer_fnGetAttributesOf,
2531 IShellFolder_fnGetUIObjectOf,
2532 ISF_MyComputer_fnGetDisplayNameOf,
2533 IShellFolder_fnSetNameOf,
2535 /* ShellFolder2 */
2536 ISF_MyComputer_fnGetDefaultSearchGUID,
2537 ISF_MyComputer_fnEnumSearches,
2538 ISF_MyComputer_fnGetDefaultColumn,
2539 ISF_MyComputer_fnGetDefaultColumnState,
2540 ISF_MyComputer_fnGetDetailsEx,
2541 ISF_MyComputer_fnGetDetailsOf,
2542 ISF_MyComputer_fnMapNameToSCID
2546 /************************************************************************
2547 * ISFPersistFolder_QueryInterface (IUnknown)
2550 static HRESULT WINAPI ISFPersistFolder2_QueryInterface(
2551 IPersistFolder2 * iface,
2552 REFIID iid,
2553 LPVOID* ppvObj)
2555 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2557 TRACE("(%p)\n", This);
2559 return IUnknown_QueryInterface(This->pUnkOuter, iid, ppvObj);
2562 /************************************************************************
2563 * ISFPersistFolder_AddRef (IUnknown)
2566 static ULONG WINAPI ISFPersistFolder2_AddRef(
2567 IPersistFolder2 * iface)
2569 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2571 TRACE("(%p)\n", This);
2573 return IUnknown_AddRef(This->pUnkOuter);
2576 /************************************************************************
2577 * ISFPersistFolder_Release (IUnknown)
2580 static ULONG WINAPI ISFPersistFolder2_Release(
2581 IPersistFolder2 * iface)
2583 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2585 TRACE("(%p)\n", This);
2587 return IUnknown_Release(This->pUnkOuter);
2590 /************************************************************************
2591 * ISFPersistFolder_GetClassID (IPersist)
2593 static HRESULT WINAPI ISFPersistFolder2_GetClassID(
2594 IPersistFolder2 * iface,
2595 CLSID * lpClassId)
2597 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2599 TRACE("(%p)\n", This);
2601 if (!lpClassId) return E_POINTER;
2602 *lpClassId = *This->pclsid;
2604 return S_OK;
2607 /************************************************************************
2608 * ISFPersistFolder_Initialize (IPersistFolder)
2610 * NOTES
2611 * sMyPath is not set. Don't know how to handle in a non rooted environment.
2613 static HRESULT WINAPI ISFPersistFolder2_Initialize(
2614 IPersistFolder2 * iface,
2615 LPCITEMIDLIST pidl)
2617 char sTemp[MAX_PATH];
2618 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2620 TRACE("(%p)->(%p)\n", This, pidl);
2622 /* free the old stuff */
2623 if(This->absPidl)
2625 SHFree(This->absPidl);
2626 This->absPidl = NULL;
2628 if(This->sMyPath)
2630 SHFree(This->sMyPath);
2631 This->sMyPath = NULL;
2634 /* set my pidl */
2635 This->absPidl = ILClone(pidl);
2637 /* set my path */
2638 if (SHGetPathFromIDListA(pidl, sTemp))
2640 This->sMyPath = SHAlloc(strlen(sTemp)+1);
2641 strcpy(This->sMyPath, sTemp);
2644 TRACE("--(%p)->(%s)\n", This, This->sMyPath);
2646 return S_OK;
2649 /**************************************************************************
2650 * IPersistFolder2_fnGetCurFolder
2652 static HRESULT WINAPI ISFPersistFolder2_fnGetCurFolder(
2653 IPersistFolder2 * iface,
2654 LPITEMIDLIST * pidl)
2656 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2658 TRACE("(%p)->(%p)\n",This, pidl);
2660 if (!pidl) return E_POINTER;
2662 *pidl = ILClone(This->absPidl);
2664 return S_OK;
2667 static ICOM_VTABLE(IPersistFolder2) psfvt =
2669 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2670 ISFPersistFolder2_QueryInterface,
2671 ISFPersistFolder2_AddRef,
2672 ISFPersistFolder2_Release,
2673 ISFPersistFolder2_GetClassID,
2674 ISFPersistFolder2_Initialize,
2675 ISFPersistFolder2_fnGetCurFolder
2678 /****************************************************************************
2679 * ISFDropTarget implementation
2681 static BOOL ISFDropTarget_QueryDrop(
2682 IDropTarget *iface,
2683 DWORD dwKeyState,
2684 LPDWORD pdwEffect)
2686 DWORD dwEffect = *pdwEffect;
2688 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2690 *pdwEffect = DROPEFFECT_NONE;
2692 if (This->fAcceptFmt)
2693 { /* Does our interpretation of the keystate ... */
2694 *pdwEffect = KeyStateToDropEffect(dwKeyState);
2696 /* ... matches the desired effect ? */
2697 if (dwEffect & *pdwEffect)
2699 return TRUE;
2702 return FALSE;
2705 static HRESULT WINAPI ISFDropTarget_QueryInterface(
2706 IDropTarget *iface,
2707 REFIID riid,
2708 LPVOID *ppvObj)
2710 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2712 TRACE("(%p)\n", This);
2714 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
2717 static ULONG WINAPI ISFDropTarget_AddRef( IDropTarget *iface)
2719 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2721 TRACE("(%p)\n", This);
2723 return IUnknown_AddRef(This->pUnkOuter);
2726 static ULONG WINAPI ISFDropTarget_Release( IDropTarget *iface)
2728 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2730 TRACE("(%p)\n", This);
2732 return IUnknown_Release(This->pUnkOuter);
2735 static HRESULT WINAPI ISFDropTarget_DragEnter(
2736 IDropTarget *iface,
2737 IDataObject *pDataObject,
2738 DWORD dwKeyState,
2739 POINTL pt,
2740 DWORD *pdwEffect)
2742 FORMATETC fmt;
2744 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2746 TRACE("(%p)->(DataObject=%p)\n",This,pDataObject);
2748 InitFormatEtc(fmt, This->cfShellIDList, TYMED_HGLOBAL);
2750 This->fAcceptFmt = (S_OK == IDataObject_QueryGetData(pDataObject, &fmt)) ? TRUE : FALSE;
2752 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2754 return S_OK;
2757 static HRESULT WINAPI ISFDropTarget_DragOver(
2758 IDropTarget *iface,
2759 DWORD dwKeyState,
2760 POINTL pt,
2761 DWORD *pdwEffect)
2763 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2765 TRACE("(%p)\n",This);
2767 if(!pdwEffect) return E_INVALIDARG;
2769 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2771 return S_OK;
2774 static HRESULT WINAPI ISFDropTarget_DragLeave(
2775 IDropTarget *iface)
2777 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2779 TRACE("(%p)\n",This);
2781 This->fAcceptFmt = FALSE;
2783 return S_OK;
2786 static HRESULT WINAPI ISFDropTarget_Drop(
2787 IDropTarget *iface,
2788 IDataObject* pDataObject,
2789 DWORD dwKeyState,
2790 POINTL pt,
2791 DWORD *pdwEffect)
2793 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2795 FIXME("(%p) object dropped\n",This);
2797 return E_NOTIMPL;
2800 static struct ICOM_VTABLE(IDropTarget) dtvt =
2802 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2803 ISFDropTarget_QueryInterface,
2804 ISFDropTarget_AddRef,
2805 ISFDropTarget_Release,
2806 ISFDropTarget_DragEnter,
2807 ISFDropTarget_DragOver,
2808 ISFDropTarget_DragLeave,
2809 ISFDropTarget_Drop