Merged the two serializer and unserializer functions into one, cleaned
[wine.git] / dlls / shell32 / shlfolder.c
bloba7086b9590d2a887168a70b8f297019efb3df7d8
1 /*
2 * Shell Folder stuff
4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998, 1999 Juergen Schmied
7 * IShellFolder2 and related interfaces
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "config.h"
25 #include "wine/port.h"
27 #include <stdlib.h>
28 #include <string.h>
29 #include <stdio.h>
31 #include "winerror.h"
32 #include "winbase.h"
33 #include "winreg.h"
35 #include "oleidl.h"
36 #include "shlguid.h"
38 #include "pidl.h"
39 #include "wine/obj_base.h"
40 #include "wine/obj_dragdrop.h"
41 #include "wine/obj_shellfolder.h"
42 #include "undocshell.h"
43 #include "shell32_main.h"
44 #include "shresdef.h"
45 #include "shlwapi.h"
46 #include "shellfolder.h"
47 #include "wine/debug.h"
49 WINE_DEFAULT_DEBUG_CHANNEL(shell);
52 /***************************************************************************
53 * debughelper: print out the return adress
54 * helps especially to track down unbalanced AddRef/Release
56 #define MEM_DEBUG 0
58 #if MEM_DEBUG
59 #define _CALL_TRACE TRACE("called from: 0x%08x\n", *( ((UINT*)&iface)-1 ));
60 #else
61 #define _CALL_TRACE
62 #endif
64 typedef struct
66 int colnameid;
67 int pcsFlags;
68 int fmt;
69 int cxChar;
71 } shvheader;
73 /***************************************************************************
74 * GetNextElement (internal function)
76 * gets a part of a string till the first backslash
78 * PARAMETERS
79 * pszNext [IN] string to get the element from
80 * pszOut [IN] pointer to buffer whitch receives string
81 * dwOut [IN] length of pszOut
83 * RETURNS
84 * LPSTR pointer to first, not yet parsed char
87 static LPCWSTR GetNextElementW(LPCWSTR pszNext,LPWSTR pszOut,DWORD dwOut)
88 { LPCWSTR pszTail = pszNext;
89 DWORD dwCopy;
90 TRACE("(%s %p 0x%08lx)\n",debugstr_w(pszNext),pszOut,dwOut);
92 *pszOut=0x0000;
94 if(!pszNext || !*pszNext)
95 return NULL;
97 while(*pszTail && (*pszTail != (WCHAR)'\\'))
98 pszTail++;
100 dwCopy = (WCHAR*)pszTail - (WCHAR*)pszNext + 1;
101 lstrcpynW(pszOut, pszNext, (dwOut<dwCopy)? dwOut : dwCopy);
103 if(*pszTail)
104 pszTail++;
105 else
106 pszTail = NULL;
108 TRACE("--(%s %s 0x%08lx %p)\n",debugstr_w(pszNext),debugstr_w(pszOut),dwOut,pszTail);
109 return pszTail;
112 static HRESULT SHELL32_ParseNextElement(
113 HWND hwndOwner,
114 IShellFolder2 * psf,
115 LPITEMIDLIST * pidlInOut,
116 LPOLESTR szNext,
117 DWORD *pEaten,
118 DWORD *pdwAttributes)
120 HRESULT hr = E_OUTOFMEMORY;
121 LPITEMIDLIST pidlOut, pidlTemp = NULL;
122 IShellFolder *psfChild;
124 TRACE("(%p, %p, %s)\n",psf, pidlInOut ? *pidlInOut : NULL, debugstr_w(szNext));
127 /* get the shellfolder for the child pidl and let it analyse further */
128 hr = IShellFolder_BindToObject(psf, *pidlInOut, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
130 if (psfChild)
132 hr = IShellFolder_ParseDisplayName(psfChild, hwndOwner, NULL, szNext, pEaten, &pidlOut, pdwAttributes);
133 IShellFolder_Release(psfChild);
135 pidlTemp = ILCombine(*pidlInOut, pidlOut);
137 if (pidlOut)
138 ILFree(pidlOut);
141 ILFree(*pidlInOut);
142 *pidlInOut = pidlTemp;
144 TRACE("-- pidl=%p ret=0x%08lx\n", pidlInOut? *pidlInOut: NULL, hr);
145 return hr;
148 /***********************************************************************
149 * SHELL32_CoCreateInitSF
151 * creates a initialized shell folder
153 static HRESULT SHELL32_CoCreateInitSF (
154 LPITEMIDLIST pidlRoot,
155 LPITEMIDLIST pidlChild,
156 REFCLSID clsid,
157 REFIID iid,
158 LPVOID * ppvOut)
160 HRESULT hr;
161 LPITEMIDLIST absPidl;
162 IShellFolder2 *pShellFolder;
163 IPersistFolder *pPersistFolder;
165 TRACE("%p %p\n", pidlRoot, pidlChild);
167 *ppvOut = NULL;
169 /* we have to ask first for IPersistFolder, some special folders are expecting this */
170 hr = SHCoCreateInstance(NULL, clsid, NULL, &IID_IPersistFolder, (LPVOID*)&pPersistFolder);
171 if (SUCCEEDED(hr))
173 hr = IPersistFolder_QueryInterface(pPersistFolder, iid, (LPVOID*)&pShellFolder);
174 if (SUCCEEDED(hr))
176 absPidl = ILCombine (pidlRoot, pidlChild);
177 hr = IPersistFolder_Initialize(pPersistFolder, absPidl);
178 IPersistFolder_Release(pPersistFolder);
179 SHFree(absPidl);
180 *ppvOut = pShellFolder;
184 TRACE("-- ret=0x%08lx\n", hr);
185 return hr;
188 static HRESULT SHELL32_GetDisplayNameOfChild(
189 IShellFolder2 * psf,
190 LPCITEMIDLIST pidl,
191 DWORD dwFlags,
192 LPSTR szOut,
193 DWORD dwOutLen)
195 LPITEMIDLIST pidlFirst, pidlNext;
196 IShellFolder2 * psfChild;
197 HRESULT hr = E_OUTOFMEMORY;
198 STRRET strTemp;
200 TRACE("(%p)->(pidl=%p 0x%08lx %p 0x%08lx)\n",psf,pidl,dwFlags,szOut, dwOutLen);
201 pdump(pidl);
203 if ((pidlFirst = ILCloneFirst(pidl)))
205 hr = IShellFolder_BindToObject(psf, pidlFirst, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
206 if (SUCCEEDED(hr))
208 pidlNext = ILGetNext(pidl);
210 hr = IShellFolder_GetDisplayNameOf(psfChild, pidlNext, dwFlags | SHGDN_INFOLDER, &strTemp);
211 if (SUCCEEDED(hr))
213 hr = StrRetToStrNA(szOut, dwOutLen, &strTemp, pidlNext);
216 IShellFolder_Release(psfChild);
218 ILFree(pidlFirst);
221 TRACE("-- ret=0x%08lx %s\n", hr, szOut);
223 return hr;
226 /***********************************************************************
227 * SHELL32_GetItemAttributes
229 * NOTES
230 * observerd values:
231 * folder: 0xE0000177 FILESYSTEM | HASSUBFOLDER | FOLDER
232 * file: 0x40000177 FILESYSTEM
233 * drive: 0xf0000144 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR
234 * mycomputer: 0xb0000154 HASSUBFOLDER | FOLDER | FILESYSANCESTOR
235 * (seems to be default for shell extensions if no registry entry exists)
237 * This functions does not set flags!! It only resets flags when nessesary.
239 static HRESULT SHELL32_GetItemAttributes(
240 IShellFolder * psf,
241 LPITEMIDLIST pidl,
242 LPDWORD pdwAttributes)
244 GUID const * clsid;
245 DWORD dwAttributes;
247 TRACE("0x%08lx\n", *pdwAttributes);
249 if (*pdwAttributes & (0xcff3fe88))
250 WARN("attribute 0x%08lx not implemented\n", *pdwAttributes);
251 *pdwAttributes &= ~SFGAO_LINK; /* FIXME: for native filedialogs */
253 if (_ILIsDrive(pidl))
255 *pdwAttributes &= 0xf0000144;
257 else if ((clsid=_ILGetGUIDPointer(pidl)))
259 if (HCR_GetFolderAttributes(clsid, &dwAttributes))
261 *pdwAttributes &= dwAttributes;
263 else
265 *pdwAttributes &= 0xb0000154;
268 else if (_ILGetDataPointer(pidl))
270 dwAttributes = _ILGetFileAttributes(pidl, NULL, 0);
271 *pdwAttributes &= ~SFGAO_FILESYSANCESTOR;
273 if(( SFGAO_FOLDER & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
274 *pdwAttributes &= ~(SFGAO_FOLDER|SFGAO_HASSUBFOLDER);
276 if(( SFGAO_HIDDEN & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_HIDDEN))
277 *pdwAttributes &= ~SFGAO_HIDDEN;
279 if(( SFGAO_READONLY & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_READONLY))
280 *pdwAttributes &= ~SFGAO_READONLY;
282 else
284 *pdwAttributes &= 0xb0000154;
286 TRACE("-- 0x%08lx\n", *pdwAttributes);
287 return S_OK;
290 /***********************************************************************
291 * IShellFolder implementation
294 typedef struct
296 ICOM_VFIELD(IUnknown);
297 DWORD ref;
298 ICOM_VTABLE(IShellFolder2)* lpvtblShellFolder;
299 ICOM_VTABLE(IPersistFolder2)* lpvtblPersistFolder2;
300 ICOM_VTABLE(IDropTarget)* lpvtblDropTarget;
301 ICOM_VTABLE(ISFHelper)* lpvtblSFHelper;
303 IUnknown *pUnkOuter; /* used for aggregation */
305 CLSID* pclsid;
307 LPSTR sMyPath;
308 LPITEMIDLIST absPidl; /* complete pidl */
310 UINT cfShellIDList; /* clipboardformat for IDropTarget */
311 BOOL fAcceptFmt; /* flag for pending Drop */
312 } IGenericSFImpl;
314 static struct ICOM_VTABLE(IUnknown) unkvt;
315 static struct ICOM_VTABLE(IShellFolder2) sfvt;
316 static struct ICOM_VTABLE(IPersistFolder2) psfvt;
317 static struct ICOM_VTABLE(IDropTarget) dtvt;
318 static struct ICOM_VTABLE(ISFHelper) shvt;
320 static IShellFolder * ISF_MyComputer_Constructor(void);
322 #define _IShellFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblShellFolder)))
323 #define _ICOM_THIS_From_IShellFolder2(class, name) class* This = (class*)(((char*)name)-_IShellFolder2_Offset);
325 #define _IPersistFolder_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder2)))
326 #define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder_Offset);
328 #define _IDropTarget_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblDropTarget)))
329 #define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
331 #define _ISFHelper_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblSFHelper)))
332 #define _ICOM_THIS_From_ISFHelper(class, name) class* This = (class*)(((char*)name)-_ISFHelper_Offset);
334 converts This to a interface pointer
336 #define _IUnknown_(This) (IUnknown*)&(This->lpVtbl)
337 #define _IShellFolder_(This) (IShellFolder*)&(This->lpvtblShellFolder)
338 #define _IShellFolder2_(This) (IShellFolder2*)&(This->lpvtblShellFolder)
339 #define _IPersist_(This) (IPersist*)&(This->lpvtblPersistFolder2)
340 #define _IPersistFolder_(This) (IPersistFolder*)&(This->lpvtblPersistFolder2)
341 #define _IPersistFolder2_(This) (IPersistFolder2*)&(This->lpvtblPersistFolder2)
342 #define _IDropTarget_(This) (IDropTarget*)&(This->lpvtblDropTarget)
343 #define _ISFHelper_(This) (ISFHelper*)&(This->lpvtblSFHelper)
344 /**************************************************************************
345 * registers clipboardformat once
347 static void SF_RegisterClipFmt (IGenericSFImpl * This)
349 TRACE("(%p)\n", This);
351 if (!This->cfShellIDList)
353 This->cfShellIDList = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
357 /**************************************************************************
358 * we need a separate IUnknown to handle aggregation
359 * (inner IUnknown)
361 static HRESULT WINAPI IUnknown_fnQueryInterface(
362 IUnknown * iface,
363 REFIID riid,
364 LPVOID *ppvObj)
366 ICOM_THIS(IGenericSFImpl, iface);
368 _CALL_TRACE
369 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
371 *ppvObj = NULL;
373 if(IsEqualIID(riid, &IID_IUnknown)) *ppvObj = _IUnknown_(This);
374 else if(IsEqualIID(riid, &IID_IShellFolder)) *ppvObj = _IShellFolder_(This);
375 else if(IsEqualIID(riid, &IID_IShellFolder2)) *ppvObj = _IShellFolder_(This);
376 else if(IsEqualIID(riid, &IID_IPersist)) *ppvObj = _IPersist_(This);
377 else if(IsEqualIID(riid, &IID_IPersistFolder)) *ppvObj = _IPersistFolder_(This);
378 else if(IsEqualIID(riid, &IID_IPersistFolder2)) *ppvObj = _IPersistFolder2_(This);
379 else if(IsEqualIID(riid, &IID_ISFHelper)) *ppvObj = _ISFHelper_(This);
380 else if(IsEqualIID(riid, &IID_IDropTarget))
382 *ppvObj = _IDropTarget_(This);
383 SF_RegisterClipFmt(This);
386 if(*ppvObj)
388 IUnknown_AddRef((IUnknown*)(*ppvObj));
389 TRACE("-- Interface = %p\n", *ppvObj);
390 return S_OK;
392 TRACE("-- Interface: E_NOINTERFACE\n");
393 return E_NOINTERFACE;
396 static ULONG WINAPI IUnknown_fnAddRef(IUnknown * iface)
398 ICOM_THIS(IGenericSFImpl, iface);
400 _CALL_TRACE
401 TRACE("(%p)->(count=%lu)\n",This,This->ref);
403 shell32_ObjCount++;
404 return ++(This->ref);
407 static ULONG WINAPI IUnknown_fnRelease(IUnknown * iface)
409 ICOM_THIS(IGenericSFImpl, iface);
411 _CALL_TRACE
412 TRACE("(%p)->(count=%lu)\n",This,This->ref);
414 shell32_ObjCount--;
415 if (!--(This->ref))
417 TRACE("-- destroying IShellFolder(%p)\n",This);
419 if (pdesktopfolder == _IShellFolder_(This))
421 pdesktopfolder=NULL;
422 TRACE("-- destroyed IShellFolder(%p) was Desktopfolder\n",This);
424 if(This->absPidl) SHFree(This->absPidl);
425 if(This->sMyPath) SHFree(This->sMyPath);
426 HeapFree(GetProcessHeap(),0,This);
427 return 0;
429 return This->ref;
432 static ICOM_VTABLE(IUnknown) unkvt =
434 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
435 IUnknown_fnQueryInterface,
436 IUnknown_fnAddRef,
437 IUnknown_fnRelease,
440 static shvheader GenericSFHeader [] =
442 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
443 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
444 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
445 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
446 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
448 #define GENERICSHELLVIEWCOLUMNS 5
450 /**************************************************************************
451 * IShellFolder_Constructor
453 * NOTES
454 * creating undocumented ShellFS_Folder as part of an aggregation
455 * {F3364BA0-65B9-11CE-A9BA-00AA004AE837}
457 * FIXME
458 * when pUnkOuter = 0 then rrid = IID_IShellFolder is returned
460 HRESULT IFSFolder_Constructor(
461 IUnknown * pUnkOuter,
462 REFIID riid,
463 LPVOID * ppv)
465 IGenericSFImpl * sf;
466 HRESULT hr = S_OK;
468 TRACE("unkOut=%p riid=%s\n",pUnkOuter, debugstr_guid(riid));
470 if(pUnkOuter && ! IsEqualIID(riid, &IID_IUnknown))
472 hr = CLASS_E_NOAGGREGATION; /* forbidden by definition */
474 else
476 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
477 if (sf)
479 sf->ref=1;
480 ICOM_VTBL(sf)=&unkvt;
481 sf->lpvtblShellFolder=&sfvt;
482 sf->lpvtblPersistFolder2=&psfvt;
483 sf->lpvtblDropTarget=&dtvt;
484 sf->lpvtblSFHelper=&shvt;
486 sf->pclsid = (CLSID*)&CLSID_SFFile;
487 sf->pUnkOuter = pUnkOuter ? pUnkOuter : _IUnknown_(sf);
488 *ppv = _IUnknown_(sf);
489 hr = S_OK;
490 shell32_ObjCount++;
492 else
494 hr = E_OUTOFMEMORY;
497 return hr;
499 /**************************************************************************
500 * IShellFolder_Constructor
502 * NOTES
503 * THIS points to the parent folder
506 IShellFolder * IShellFolder_Constructor(
507 IShellFolder2 * iface,
508 LPITEMIDLIST pidl)
510 IGenericSFImpl * sf;
511 DWORD dwSize=0;
513 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
515 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
516 sf->ref=1;
518 ICOM_VTBL(sf)=&unkvt;
519 sf->lpvtblShellFolder=&sfvt;
520 sf->lpvtblPersistFolder2=&psfvt;
521 sf->lpvtblDropTarget=&dtvt;
522 sf->lpvtblSFHelper=&shvt;
524 sf->pclsid = (CLSID*)&CLSID_SFFile;
525 sf->pUnkOuter = _IUnknown_(sf);
527 TRACE("(%p)->(parent=%p, pidl=%p)\n",sf,This, pidl);
528 pdump(pidl);
530 if(pidl && iface) /* do we have a pidl? */
532 int len;
534 sf->absPidl = ILCombine(This->absPidl, pidl); /* build a absolute pidl */
536 if (!_ILIsSpecialFolder(pidl)) /* only file system paths */
538 if(This->sMyPath) /* get the size of the parents path */
540 dwSize += strlen(This->sMyPath) ;
541 TRACE("-- (%p)->(parent's path=%s)\n",sf, debugstr_a(This->sMyPath));
544 dwSize += _ILSimpleGetText(pidl,NULL,0); /* add the size of our name*/
545 sf->sMyPath = SHAlloc(dwSize + 2); /* '\0' and backslash */
547 if(!sf->sMyPath) return NULL;
548 *(sf->sMyPath)=0x00;
550 if(This->sMyPath) /* if the parent has a path, get it*/
552 strcpy(sf->sMyPath, This->sMyPath);
553 PathAddBackslashA (sf->sMyPath);
556 len = strlen(sf->sMyPath);
557 _ILSimpleGetText(pidl, sf->sMyPath + len, dwSize+2 - len);
560 TRACE("-- (%p)->(my pidl=%p, my path=%s)\n",sf, sf->absPidl,debugstr_a(sf->sMyPath));
562 pdump (sf->absPidl);
565 shell32_ObjCount++;
566 return _IShellFolder_(sf);
569 /**************************************************************************
570 * IShellFolder_fnQueryInterface
572 * PARAMETERS
573 * REFIID riid [in ] Requested InterfaceID
574 * LPVOID* ppvObject [out] Interface* to hold the result
576 static HRESULT WINAPI IShellFolder_fnQueryInterface(
577 IShellFolder2 * iface,
578 REFIID riid,
579 LPVOID *ppvObj)
581 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
583 _CALL_TRACE
584 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
586 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
589 /**************************************************************************
590 * IShellFolder_AddRef
593 static ULONG WINAPI IShellFolder_fnAddRef(IShellFolder2 * iface)
595 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
597 _CALL_TRACE
598 TRACE("(%p)->(count=%lu)\n",This,This->ref);
600 return IUnknown_AddRef(This->pUnkOuter);
603 /**************************************************************************
604 * IShellFolder_fnRelease
606 static ULONG WINAPI IShellFolder_fnRelease(IShellFolder2 * iface)
608 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
610 _CALL_TRACE
611 TRACE("(%p)->(count=%lu)\n",This,This->ref);
613 return IUnknown_Release(This->pUnkOuter);
616 /**************************************************************************
617 * IShellFolder_fnParseDisplayName
618 * PARAMETERS
619 * HWND hwndOwner, //[in ] Parent window for any message's
620 * LPBC pbc, //[in ] reserved
621 * LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname.
622 * ULONG* pchEaten, //[out] (unicode) characters processed
623 * LPITEMIDLIST* ppidl, //[out] complex pidl to item
624 * ULONG* pdwAttributes //[out] items attributes
626 * NOTES
627 * every folder tries to parse only its own (the leftmost) pidl and creates a
628 * subfolder to evaluate the remaining parts
629 * now we can parse into namespaces implemented by shell extensions
631 * behaviour on win98: lpszDisplayName=NULL -> chrash
632 * lpszDisplayName="" -> returns mycoputer-pidl
634 * FIXME:
635 * pdwAttributes: not set
636 * pchEaten: not set like in windows
638 static HRESULT WINAPI IShellFolder_fnParseDisplayName(
639 IShellFolder2 * iface,
640 HWND hwndOwner,
641 LPBC pbcReserved,
642 LPOLESTR lpszDisplayName,
643 DWORD *pchEaten,
644 LPITEMIDLIST *ppidl,
645 DWORD *pdwAttributes)
647 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
649 HRESULT hr = E_OUTOFMEMORY;
650 LPCWSTR szNext=NULL;
651 WCHAR szElement[MAX_PATH];
652 CHAR szTempA[MAX_PATH], szPath[MAX_PATH];
653 LPITEMIDLIST pidlTemp=NULL;
655 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
656 This,hwndOwner,pbcReserved,lpszDisplayName,
657 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
659 if (!lpszDisplayName || !ppidl) return E_INVALIDARG;
661 if (pchEaten) *pchEaten = 0; /* strange but like the original */
663 if (*lpszDisplayName)
665 /* get the next element */
666 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
668 /* build the full pathname to the element */
669 WideCharToMultiByte( CP_ACP, 0, szElement, -1, szTempA, MAX_PATH, NULL, NULL );
670 strcpy(szPath, This->sMyPath);
671 PathAddBackslashA(szPath);
672 strcat(szPath, szTempA);
674 /* get the pidl */
675 pidlTemp = SHSimpleIDListFromPathA(szPath);
677 if (pidlTemp)
679 /* try to analyse the next element */
680 if (szNext && *szNext)
682 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
684 else
686 if (pdwAttributes && *pdwAttributes)
688 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
689 /* WIN32_FIND_DATAA fd;
690 SHGetDataFromIDListA(_IShellFolder_(This), pidlTemp, SHGDFIL_FINDDATA, &fd, sizeof(fd));
691 if (!(FILE_ATTRIBUTE_DIRECTORY & fd.dwFileAttributes))
692 *pdwAttributes &= ~SFGAO_FOLDER;
693 if (FILE_ATTRIBUTE_READONLY & fd.dwFileAttributes)
694 *pdwAttributes &= ~(SFGAO_CANDELETE|SFGAO_CANMOVE|SFGAO_CANRENAME );
697 hr = S_OK;
702 if (!hr)
703 *ppidl = pidlTemp;
704 else
705 *ppidl = NULL;
707 TRACE("(%p)->(-- pidl=%p ret=0x%08lx)\n", This, ppidl? *ppidl:0, hr);
709 return hr;
712 /**************************************************************************
713 * IShellFolder_fnEnumObjects
714 * PARAMETERS
715 * HWND hwndOwner, //[in ] Parent Window
716 * DWORD grfFlags, //[in ] SHCONTF enumeration mask
717 * LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface
719 static HRESULT WINAPI IShellFolder_fnEnumObjects(
720 IShellFolder2 * iface,
721 HWND hwndOwner,
722 DWORD dwFlags,
723 LPENUMIDLIST* ppEnumIDList)
725 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
727 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
729 *ppEnumIDList = NULL;
730 *ppEnumIDList = IEnumIDList_Constructor (This->sMyPath, dwFlags, EIDL_FILE);
732 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
734 if(!*ppEnumIDList) return E_OUTOFMEMORY;
736 return S_OK;
739 /**************************************************************************
740 * IShellFolder_fnBindToObject
741 * PARAMETERS
742 * LPCITEMIDLIST pidl, //[in ] relative pidl to open
743 * LPBC pbc, //[in ] reserved
744 * REFIID riid, //[in ] Initial Interface
745 * LPVOID* ppvObject //[out] Interface*
747 static HRESULT WINAPI IShellFolder_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
748 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
750 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
751 GUID const * iid;
752 IShellFolder *pShellFolder, *pSubFolder;
753 IPersistFolder *pPersistFolder;
754 LPITEMIDLIST absPidl;
755 HRESULT hr;
757 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
759 if(!pidl || !ppvOut) return E_INVALIDARG;
761 *ppvOut = NULL;
763 if ((iid=_ILGetGUIDPointer(pidl)))
765 /* we have to create a alien folder */
766 if ( SUCCEEDED(SHCoCreateInstance(NULL, iid, NULL, riid, (LPVOID*)&pShellFolder))
767 && SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&pPersistFolder)))
769 absPidl = ILCombine (This->absPidl, pidl);
770 IPersistFolder_Initialize(pPersistFolder, absPidl);
771 IPersistFolder_Release(pPersistFolder);
772 SHFree(absPidl);
774 else
776 return E_FAIL;
779 else
781 LPITEMIDLIST pidltemp = ILCloneFirst(pidl);
782 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
783 ILFree(pidltemp);
786 if (_ILIsPidlSimple(pidl))
788 if(IsEqualIID(riid, &IID_IShellFolder))
790 *ppvOut = pShellFolder;
791 hr = S_OK;
793 else
795 hr = IShellFolder_QueryInterface(pShellFolder, riid, ppvOut);
796 IShellFolder_Release(pShellFolder);
799 else
801 hr = IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL,
802 riid, (LPVOID)&pSubFolder);
803 IShellFolder_Release(pShellFolder);
804 *ppvOut = pSubFolder;
807 TRACE("-- (%p) returning (%p) %08lx\n",This, *ppvOut, hr);
809 return hr;
812 /**************************************************************************
813 * IShellFolder_fnBindToStorage
814 * PARAMETERS
815 * LPCITEMIDLIST pidl, //[in ] complex pidl to store
816 * LPBC pbc, //[in ] reserved
817 * REFIID riid, //[in ] Initial storage interface
818 * LPVOID* ppvObject //[out] Interface* returned
820 static HRESULT WINAPI IShellFolder_fnBindToStorage(
821 IShellFolder2 * iface,
822 LPCITEMIDLIST pidl,
823 LPBC pbcReserved,
824 REFIID riid,
825 LPVOID *ppvOut)
827 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
829 FIXME("(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",
830 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
832 *ppvOut = NULL;
833 return E_NOTIMPL;
836 /**************************************************************************
837 * IShellFolder_fnCompareIDs
839 * PARMETERS
840 * LPARAM lParam, //[in ] Column?
841 * LPCITEMIDLIST pidl1, //[in ] simple pidl
842 * LPCITEMIDLIST pidl2) //[in ] simple pidl
844 * NOTES
845 * Special case - If one of the items is a Path and the other is a File,
846 * always make the Path come before the File.
848 * NOTES
849 * use SCODE_CODE() on the return value to get the result
852 static HRESULT WINAPI IShellFolder_fnCompareIDs(
853 IShellFolder2 * iface,
854 LPARAM lParam,
855 LPCITEMIDLIST pidl1,
856 LPCITEMIDLIST pidl2)
858 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
860 CHAR szTemp1[MAX_PATH];
861 CHAR szTemp2[MAX_PATH];
862 int nReturn;
863 IShellFolder * psf;
864 HRESULT hr = E_OUTOFMEMORY;
865 LPCITEMIDLIST pidlTemp;
866 PIDLTYPE pt1, pt2;
868 if (TRACE_ON(shell)) {
869 TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",This,lParam,pidl1,pidl2);
870 pdump (pidl1);
871 pdump (pidl2);
874 if (!pidl1 && !pidl2)
876 hr = ResultFromShort(0);
878 else if (!pidl1)
880 hr = ResultFromShort(-1);
882 else if (!pidl2)
884 hr = ResultFromShort(1);
886 else
888 LPPIDLDATA pd1, pd2;
889 pd1 = _ILGetDataPointer(pidl1);
890 pd2 = _ILGetDataPointer(pidl2);
892 /* compate the types. sort order is the PT_* constant */
893 pt1 = ( pd1 ? pd1->type: PT_DESKTOP);
894 pt2 = ( pd2 ? pd2->type: PT_DESKTOP);
896 if (pt1 != pt2)
898 hr = ResultFromShort(pt1-pt2);
900 else /* same type of pidl */
902 _ILSimpleGetText(pidl1, szTemp1, MAX_PATH);
903 _ILSimpleGetText(pidl2, szTemp2, MAX_PATH);
904 nReturn = strcasecmp(szTemp1, szTemp2);
906 if (nReturn == 0) /* first pidl different ? */
908 pidl1 = ILGetNext(pidl1);
910 if (pidl1 && pidl1->mkid.cb) /* go deeper? */
912 pidlTemp = ILCloneFirst(pidl1);
913 pidl2 = ILGetNext(pidl2);
915 hr = IShellFolder_BindToObject(iface, pidlTemp, NULL, &IID_IShellFolder, (LPVOID*)&psf);
916 if (SUCCEEDED(hr))
918 nReturn = IShellFolder_CompareIDs(psf, 0, pidl1, pidl2);
919 IShellFolder_Release(psf);
920 hr = ResultFromShort(nReturn);
922 ILFree(pidlTemp);
924 else /* no deeper on #1 */
926 pidl2 = ILGetNext(pidl2);
927 if (pidl2 && pidl2->mkid.cb) /* go deeper on #2 ? */
928 hr = ResultFromShort(-1); /* two different */
929 else
930 hr = ResultFromShort(nReturn); /* two equal simple pidls */
933 else
935 hr = ResultFromShort(nReturn); /* two different simple pidls */
940 TRACE("-- res=0x%08lx\n", hr);
941 return hr;
944 /**************************************************************************
945 * IShellFolder_fnCreateViewObject
947 static HRESULT WINAPI IShellFolder_fnCreateViewObject(
948 IShellFolder2 * iface,
949 HWND hwndOwner,
950 REFIID riid,
951 LPVOID *ppvOut)
953 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
955 LPSHELLVIEW pShellView;
956 HRESULT hr = E_INVALIDARG;
958 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
960 if(ppvOut)
962 *ppvOut = NULL;
964 if(IsEqualIID(riid, &IID_IDropTarget))
966 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, ppvOut);
968 else if(IsEqualIID(riid, &IID_IContextMenu))
970 FIXME("IContextMenu not implemented\n");
971 hr = E_NOTIMPL;
973 else if(IsEqualIID(riid, &IID_IShellView))
975 pShellView = IShellView_Constructor((IShellFolder*)iface);
976 if(pShellView)
978 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
979 IShellView_Release(pShellView);
983 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
984 return hr;
987 /**************************************************************************
988 * IShellFolder_fnGetAttributesOf
990 * PARAMETERS
991 * UINT cidl, //[in ] num elements in pidl array
992 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
993 * ULONG* rgfInOut) //[out] result array
996 static HRESULT WINAPI IShellFolder_fnGetAttributesOf(
997 IShellFolder2 * iface,
998 UINT cidl,
999 LPCITEMIDLIST *apidl,
1000 DWORD *rgfInOut)
1002 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1004 HRESULT hr = S_OK;
1006 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
1008 if ( (!cidl) || (!apidl) || (!rgfInOut))
1009 return E_INVALIDARG;
1011 while (cidl > 0 && *apidl)
1013 pdump (*apidl);
1014 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
1015 apidl++;
1016 cidl--;
1019 TRACE("-- result=0x%08lx\n",*rgfInOut);
1021 return hr;
1023 /**************************************************************************
1024 * IShellFolder_fnGetUIObjectOf
1026 * PARAMETERS
1027 * HWND hwndOwner, //[in ] Parent window for any output
1028 * UINT cidl, //[in ] array size
1029 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
1030 * REFIID riid, //[in ] Requested Interface
1031 * UINT* prgfInOut, //[ ] reserved
1032 * LPVOID* ppvObject) //[out] Resulting Interface
1034 * NOTES
1035 * This function gets asked to return "view objects" for one or more (multiple select)
1036 * items:
1037 * The viewobject typically is an COM object with one of the following interfaces:
1038 * IExtractIcon,IDataObject,IContextMenu
1039 * In order to support icon positions in the default Listview your DataObject
1040 * must implement the SetData method (in addition to GetData :) - the shell passes
1041 * a barely documented "Icon positions" structure to SetData when the drag starts,
1042 * and GetData's it if the drop is in another explorer window that needs the positions.
1044 static HRESULT WINAPI IShellFolder_fnGetUIObjectOf(
1045 IShellFolder2 * iface,
1046 HWND hwndOwner,
1047 UINT cidl,
1048 LPCITEMIDLIST * apidl,
1049 REFIID riid,
1050 UINT * prgfInOut,
1051 LPVOID * ppvOut)
1053 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1055 LPITEMIDLIST pidl;
1056 IUnknown* pObj = NULL;
1057 HRESULT hr = E_INVALIDARG;
1059 TRACE("(%p)->(0x%04x,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
1060 This,hwndOwner,cidl,apidl,debugstr_guid(riid),prgfInOut,ppvOut);
1062 if (ppvOut)
1064 *ppvOut = NULL;
1066 if(IsEqualIID(riid, &IID_IContextMenu) && (cidl >= 1))
1068 pObj = (LPUNKNOWN)ISvItemCm_Constructor((IShellFolder*)iface, This->absPidl, apidl, cidl);
1069 hr = S_OK;
1071 else if (IsEqualIID(riid, &IID_IDataObject) &&(cidl >= 1))
1073 pObj = (LPUNKNOWN)IDataObject_Constructor (hwndOwner, This->absPidl, apidl, cidl);
1074 hr = S_OK;
1076 else if (IsEqualIID(riid, &IID_IExtractIconA) && (cidl == 1))
1078 pidl = ILCombine(This->absPidl,apidl[0]);
1079 pObj = (LPUNKNOWN)IExtractIconA_Constructor( pidl );
1080 SHFree(pidl);
1081 hr = S_OK;
1083 else if (IsEqualIID(riid, &IID_IDropTarget) && (cidl >= 1))
1085 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, (LPVOID*)&pObj);
1087 else
1089 hr = E_NOINTERFACE;
1092 if(!pObj)
1093 hr = E_OUTOFMEMORY;
1095 *ppvOut = pObj;
1097 TRACE("(%p)->hr=0x%08lx\n",This, hr);
1098 return hr;
1101 /**************************************************************************
1102 * IShellFolder_fnGetDisplayNameOf
1103 * Retrieves the display name for the specified file object or subfolder
1105 * PARAMETERS
1106 * LPCITEMIDLIST pidl, //[in ] complex pidl to item
1107 * DWORD dwFlags, //[in ] SHGNO formatting flags
1108 * LPSTRRET lpName) //[out] Returned display name
1110 * FIXME
1111 * if the name is in the pidl the ret value should be a STRRET_OFFSET
1113 #define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
1114 #define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
1116 static HRESULT WINAPI IShellFolder_fnGetDisplayNameOf(
1117 IShellFolder2 * iface,
1118 LPCITEMIDLIST pidl,
1119 DWORD dwFlags,
1120 LPSTRRET strRet)
1122 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1124 CHAR szPath[MAX_PATH]= "";
1125 int len = 0;
1126 BOOL bSimplePidl;
1128 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1129 pdump(pidl);
1131 if(!pidl || !strRet) return E_INVALIDARG;
1133 bSimplePidl = _ILIsPidlSimple(pidl);
1135 /* take names of special folders only if its only this folder */
1136 if (_ILIsSpecialFolder(pidl))
1138 if ( bSimplePidl)
1140 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
1143 else
1145 if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) && This->sMyPath)
1147 strcpy (szPath, This->sMyPath); /* get path to root*/
1148 PathAddBackslashA(szPath);
1149 len = strlen(szPath);
1151 _ILSimpleGetText(pidl, szPath + len, MAX_PATH - len); /* append my own path */
1153 /* MSDN also mentions SHGDN_FOREDITING, which isn't defined in wine */
1154 if(!_ILIsFolder(pidl) && !(dwFlags & SHGDN_FORPARSING) &&
1155 ((dwFlags & SHGDN_INFOLDER) || (dwFlags == SHGDN_NORMAL)))
1157 HKEY hKey;
1158 DWORD dwData;
1159 DWORD dwDataSize = sizeof(DWORD);
1160 BOOL doHide = 0; /* The default value is FALSE (win98 at least) */
1162 /* XXX should it do this only for known file types? -- that would make it even slower! */
1163 /* XXX That's what the prompt says!! */
1164 if(!RegCreateKeyExA(HKEY_CURRENT_USER,
1165 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
1166 0, 0, 0, KEY_ALL_ACCESS, 0, &hKey, 0))
1168 if(!RegQueryValueExA(hKey, "HideFileExt", 0, 0, (LPBYTE)&dwData, &dwDataSize))
1169 doHide = dwData;
1170 RegCloseKey(hKey);
1172 if(doHide && szPath[0]!='.') PathRemoveExtensionA(szPath);
1176 if ( (dwFlags & SHGDN_FORPARSING) && !bSimplePidl) /* go deeper if needed */
1178 PathAddBackslashA(szPath);
1179 len = strlen(szPath);
1181 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath + len, MAX_PATH - len)))
1182 return E_OUTOFMEMORY;
1184 strRet->uType = STRRET_CSTRA;
1185 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1187 TRACE("-- (%p)->(%s)\n", This, szPath);
1188 return S_OK;
1191 /**************************************************************************
1192 * IShellFolder_fnSetNameOf
1193 * Changes the name of a file object or subfolder, possibly changing its item
1194 * identifier in the process.
1196 * PARAMETERS
1197 * HWND hwndOwner, //[in ] Owner window for output
1198 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
1199 * LPCOLESTR lpszName, //[in ] the items new display name
1200 * DWORD dwFlags, //[in ] SHGNO formatting flags
1201 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
1203 static HRESULT WINAPI IShellFolder_fnSetNameOf(
1204 IShellFolder2 * iface,
1205 HWND hwndOwner,
1206 LPCITEMIDLIST pidl, /*simple pidl*/
1207 LPCOLESTR lpName,
1208 DWORD dwFlags,
1209 LPITEMIDLIST *pPidlOut)
1211 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1212 char szSrc[MAX_PATH], szDest[MAX_PATH];
1213 int len;
1214 BOOL bIsFolder = _ILIsFolder(ILFindLastID(pidl));
1216 TRACE("(%p)->(%u,pidl=%p,%s,%lu,%p)\n",
1217 This,hwndOwner,pidl,debugstr_w(lpName),dwFlags,pPidlOut);
1219 /* build source path */
1220 if (dwFlags & SHGDN_INFOLDER)
1222 strcpy(szSrc, This->sMyPath);
1223 PathAddBackslashA(szSrc);
1224 len = strlen (szSrc);
1225 _ILSimpleGetText(pidl, szSrc+len, MAX_PATH-len);
1227 else
1229 SHGetPathFromIDListA(pidl, szSrc);
1232 /* build destination path */
1233 strcpy(szDest, This->sMyPath);
1234 PathAddBackslashA(szDest);
1235 len = strlen (szDest);
1236 WideCharToMultiByte( CP_ACP, 0, lpName, -1, szDest+len, MAX_PATH-len, NULL, NULL );
1237 szDest[MAX_PATH-1] = 0;
1238 TRACE("src=%s dest=%s\n", szSrc, szDest);
1239 if ( MoveFileA(szSrc, szDest) )
1241 if (pPidlOut) *pPidlOut = SHSimpleIDListFromPathA(szDest);
1242 SHChangeNotifyA( bIsFolder?SHCNE_RENAMEFOLDER:SHCNE_RENAMEITEM, SHCNF_PATHA, szSrc, szDest);
1243 return S_OK;
1245 return E_FAIL;
1248 static HRESULT WINAPI IShellFolder_fnGetDefaultSearchGUID(
1249 IShellFolder2 * iface,
1250 GUID *pguid)
1252 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1253 FIXME("(%p)\n",This);
1254 return E_NOTIMPL;
1256 static HRESULT WINAPI IShellFolder_fnEnumSearches(
1257 IShellFolder2 * iface,
1258 IEnumExtraSearch **ppenum)
1260 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1261 FIXME("(%p)\n",This);
1262 return E_NOTIMPL;
1264 static HRESULT WINAPI IShellFolder_fnGetDefaultColumn(
1265 IShellFolder2 * iface,
1266 DWORD dwRes,
1267 ULONG *pSort,
1268 ULONG *pDisplay)
1270 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1272 TRACE("(%p)\n",This);
1274 if (pSort) *pSort = 0;
1275 if (pDisplay) *pDisplay = 0;
1277 return S_OK;
1279 static HRESULT WINAPI IShellFolder_fnGetDefaultColumnState(
1280 IShellFolder2 * iface,
1281 UINT iColumn,
1282 DWORD *pcsFlags)
1284 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1286 TRACE("(%p)\n",This);
1288 if (!pcsFlags || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1290 *pcsFlags = GenericSFHeader[iColumn].pcsFlags;
1292 return S_OK;
1294 static HRESULT WINAPI IShellFolder_fnGetDetailsEx(
1295 IShellFolder2 * iface,
1296 LPCITEMIDLIST pidl,
1297 const SHCOLUMNID *pscid,
1298 VARIANT *pv)
1300 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1301 FIXME("(%p)\n",This);
1303 return E_NOTIMPL;
1305 static HRESULT WINAPI IShellFolder_fnGetDetailsOf(
1306 IShellFolder2 * iface,
1307 LPCITEMIDLIST pidl,
1308 UINT iColumn,
1309 SHELLDETAILS *psd)
1311 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1312 HRESULT hr = E_FAIL;
1314 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
1316 if (!psd || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1318 if (!pidl)
1320 /* the header titles */
1321 psd->fmt = GenericSFHeader[iColumn].fmt;
1322 psd->cxChar = GenericSFHeader[iColumn].cxChar;
1323 psd->str.uType = STRRET_CSTRA;
1324 LoadStringA(shell32_hInstance, GenericSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
1325 return S_OK;
1327 else
1329 /* the data from the pidl */
1330 switch(iColumn)
1332 case 0: /* name */
1333 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
1334 break;
1335 case 1: /* size */
1336 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
1337 break;
1338 case 2: /* type */
1339 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
1340 break;
1341 case 3: /* date */
1342 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
1343 break;
1344 case 4: /* attributes */
1345 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
1346 break;
1348 hr = S_OK;
1349 psd->str.uType = STRRET_CSTRA;
1352 return hr;
1354 static HRESULT WINAPI IShellFolder_fnMapNameToSCID(
1355 IShellFolder2 * iface,
1356 LPCWSTR pwszName,
1357 SHCOLUMNID *pscid)
1359 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1360 FIXME("(%p)\n",This);
1361 return E_NOTIMPL;
1364 static ICOM_VTABLE(IShellFolder2) sfvt =
1366 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1367 IShellFolder_fnQueryInterface,
1368 IShellFolder_fnAddRef,
1369 IShellFolder_fnRelease,
1370 IShellFolder_fnParseDisplayName,
1371 IShellFolder_fnEnumObjects,
1372 IShellFolder_fnBindToObject,
1373 IShellFolder_fnBindToStorage,
1374 IShellFolder_fnCompareIDs,
1375 IShellFolder_fnCreateViewObject,
1376 IShellFolder_fnGetAttributesOf,
1377 IShellFolder_fnGetUIObjectOf,
1378 IShellFolder_fnGetDisplayNameOf,
1379 IShellFolder_fnSetNameOf,
1381 /* ShellFolder2 */
1382 IShellFolder_fnGetDefaultSearchGUID,
1383 IShellFolder_fnEnumSearches,
1384 IShellFolder_fnGetDefaultColumn,
1385 IShellFolder_fnGetDefaultColumnState,
1386 IShellFolder_fnGetDetailsEx,
1387 IShellFolder_fnGetDetailsOf,
1388 IShellFolder_fnMapNameToSCID
1391 /****************************************************************************
1392 * ISFHelper for IShellFolder implementation
1395 static HRESULT WINAPI ISFHelper_fnQueryInterface(
1396 ISFHelper *iface,
1397 REFIID riid,
1398 LPVOID *ppvObj)
1400 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1402 TRACE("(%p)\n", This);
1404 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
1407 static ULONG WINAPI ISFHelper_fnAddRef(
1408 ISFHelper *iface)
1410 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1412 TRACE("(%p)\n", This);
1414 return IUnknown_AddRef(This->pUnkOuter);
1417 static ULONG WINAPI ISFHelper_fnRelease(
1418 ISFHelper *iface)
1420 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1422 TRACE("(%p)\n", This);
1424 return IUnknown_Release(This->pUnkOuter);
1428 /****************************************************************************
1429 * ISFHelper_fnAddFolder
1431 * creates a unique folder name
1434 static HRESULT WINAPI ISFHelper_fnGetUniqueName(
1435 ISFHelper *iface,
1436 LPSTR lpName,
1437 UINT uLen)
1439 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1440 IEnumIDList * penum;
1441 HRESULT hr;
1442 char szText[MAX_PATH];
1443 char * szNewFolder = "New Folder";
1445 TRACE("(%p)(%s %u)\n", This, lpName, uLen);
1447 if (uLen < strlen(szNewFolder) + 4) return E_POINTER;
1449 strcpy(lpName, szNewFolder);
1451 hr = IShellFolder_fnEnumObjects(_IShellFolder2_(This), 0, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penum);
1452 if (penum)
1454 LPITEMIDLIST pidl;
1455 DWORD dwFetched;
1456 int i=1;
1458 next: IEnumIDList_Reset(penum);
1459 while(S_OK == IEnumIDList_Next(penum, 1, &pidl, &dwFetched) && dwFetched)
1461 _ILSimpleGetText(pidl, szText, MAX_PATH);
1462 if (0 == strcasecmp(szText, lpName))
1464 sprintf(lpName, "%s %d", szNewFolder, i++);
1465 if (i > 99)
1467 hr = E_FAIL;
1468 break;
1470 goto next;
1474 IEnumIDList_Release(penum);
1476 return hr;
1479 /****************************************************************************
1480 * ISFHelper_fnAddFolder
1482 * adds a new folder.
1485 static HRESULT WINAPI ISFHelper_fnAddFolder(
1486 ISFHelper *iface,
1487 HWND hwnd,
1488 LPCSTR lpName,
1489 LPITEMIDLIST* ppidlOut)
1491 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1492 char lpstrNewDir[MAX_PATH];
1493 DWORD bRes;
1494 HRESULT hres = E_FAIL;
1496 TRACE("(%p)(%s %p)\n", This, lpName, ppidlOut);
1498 strcpy(lpstrNewDir, This->sMyPath);
1499 PathAddBackslashA(lpstrNewDir);
1500 strcat(lpstrNewDir, lpName);
1502 bRes = CreateDirectoryA(lpstrNewDir, NULL);
1504 if (bRes)
1506 LPITEMIDLIST pidl, pidlitem;
1508 pidlitem = SHSimpleIDListFromPathA(lpstrNewDir);
1510 pidl = ILCombine(This->absPidl, pidlitem);
1511 SHChangeNotifyA(SHCNE_MKDIR, SHCNF_IDLIST, pidl, NULL);
1512 SHFree(pidl);
1514 if (ppidlOut) *ppidlOut = pidlitem;
1515 hres = S_OK;
1517 else
1519 char lpstrText[128+MAX_PATH];
1520 char lpstrTempText[128];
1521 char lpstrCaption[256];
1523 /* Cannot Create folder because of permissions */
1524 LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_DENIED, lpstrTempText, sizeof(lpstrTempText));
1525 LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_CAPTION, lpstrCaption, sizeof(lpstrCaption));
1526 sprintf(lpstrText,lpstrTempText, lpstrNewDir);
1527 MessageBoxA(hwnd,lpstrText, lpstrCaption, MB_OK | MB_ICONEXCLAMATION);
1530 return hres;
1533 /****************************************************************************
1534 * ISFHelper_fnDeleteItems
1536 * deletes items in folder
1538 static HRESULT WINAPI ISFHelper_fnDeleteItems(
1539 ISFHelper *iface,
1540 UINT cidl,
1541 LPCITEMIDLIST* apidl)
1543 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1544 int i;
1545 char szPath[MAX_PATH];
1546 BOOL bConfirm = TRUE;
1548 TRACE("(%p)(%u %p)\n", This, cidl, apidl);
1550 /* deleting multiple items so give a slightly different warning */
1551 if(cidl != 1)
1553 char tmp[8];
1554 snprintf(tmp, sizeof(tmp), "%d", cidl);
1555 if(!SHELL_WarnItemDelete(ASK_DELETE_MULTIPLE_ITEM, tmp))
1556 return E_FAIL;
1557 bConfirm = FALSE;
1560 for(i=0; i< cidl; i++)
1562 strcpy(szPath, This->sMyPath);
1563 PathAddBackslashA(szPath);
1564 _ILSimpleGetText(apidl[i], szPath+strlen(szPath), MAX_PATH);
1566 if (_ILIsFolder(apidl[i]))
1568 LPITEMIDLIST pidl;
1569 TRACE("delete %s\n", szPath);
1570 if (! SHELL_DeleteDirectoryA(szPath, bConfirm))
1572 TRACE("delete %s failed, bConfirm=%d\n", szPath, bConfirm);
1573 return E_FAIL;
1575 pidl = ILCombine(This->absPidl, apidl[i]);
1576 SHChangeNotifyA(SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);
1577 SHFree(pidl);
1579 else if (_ILIsValue(apidl[i]))
1581 LPITEMIDLIST pidl;
1583 TRACE("delete %s\n", szPath);
1584 if (! SHELL_DeleteFileA(szPath, bConfirm))
1586 TRACE("delete %s failed, bConfirm=%d\n", szPath, bConfirm);
1587 return E_FAIL;
1589 pidl = ILCombine(This->absPidl, apidl[i]);
1590 SHChangeNotifyA(SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);
1591 SHFree(pidl);
1595 return S_OK;
1598 /****************************************************************************
1599 * ISFHelper_fnCopyItems
1601 * copies items to this folder
1603 static HRESULT WINAPI ISFHelper_fnCopyItems(
1604 ISFHelper *iface,
1605 IShellFolder* pSFFrom,
1606 UINT cidl,
1607 LPCITEMIDLIST *apidl)
1609 int i;
1610 IPersistFolder2 * ppf2=NULL;
1611 char szSrcPath[MAX_PATH], szDstPath[MAX_PATH];
1612 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1614 TRACE("(%p)->(%p,%u,%p)\n", This, pSFFrom, cidl, apidl);
1616 IShellFolder_QueryInterface(pSFFrom, &IID_IPersistFolder2, (LPVOID*)&ppf2);
1617 if (ppf2)
1619 LPITEMIDLIST pidl;
1620 if (SUCCEEDED(IPersistFolder2_GetCurFolder(ppf2, &pidl)))
1622 for (i=0; i<cidl; i++)
1624 SHGetPathFromIDListA(pidl, szSrcPath);
1625 PathAddBackslashA(szSrcPath);
1626 _ILSimpleGetText(apidl[i], szSrcPath+strlen(szSrcPath), MAX_PATH);
1628 strcpy(szDstPath, This->sMyPath);
1629 PathAddBackslashA(szDstPath);
1630 _ILSimpleGetText(apidl[i], szDstPath+strlen(szDstPath), MAX_PATH);
1631 MESSAGE("would copy %s to %s\n", szSrcPath, szDstPath);
1633 SHFree(pidl);
1635 IPersistFolder2_Release(ppf2);
1637 return S_OK;
1640 static ICOM_VTABLE(ISFHelper) shvt =
1642 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1643 ISFHelper_fnQueryInterface,
1644 ISFHelper_fnAddRef,
1645 ISFHelper_fnRelease,
1646 ISFHelper_fnGetUniqueName,
1647 ISFHelper_fnAddFolder,
1648 ISFHelper_fnDeleteItems,
1649 ISFHelper_fnCopyItems,
1652 /***********************************************************************
1653 * [Desktopfolder] IShellFolder implementation
1655 static struct ICOM_VTABLE(IShellFolder2) sfdvt;
1657 static shvheader DesktopSFHeader [] =
1659 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
1660 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1661 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1662 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
1663 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
1665 #define DESKTOPSHELLVIEWCOLUMNS 5
1667 /**************************************************************************
1668 * ISF_Desktop_Constructor
1671 IShellFolder * ISF_Desktop_Constructor()
1673 IGenericSFImpl * sf;
1675 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
1676 sf->ref=1;
1677 ICOM_VTBL(sf)=&unkvt;
1678 sf->lpvtblShellFolder=&sfdvt;
1679 sf->absPidl=_ILCreateDesktop(); /* my qualified pidl */
1680 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
1682 TRACE("(%p)\n",sf);
1684 shell32_ObjCount++;
1685 return _IShellFolder_(sf);
1688 /**************************************************************************
1689 * ISF_Desktop_fnQueryInterface
1691 * NOTES supports not IPersist/IPersistFolder
1693 static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
1694 IShellFolder2 * iface,
1695 REFIID riid,
1696 LPVOID *ppvObj)
1698 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1700 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1702 *ppvObj = NULL;
1704 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
1706 *ppvObj = _IUnknown_(This);
1708 else if(IsEqualIID(riid, &IID_IShellFolder)) /*IShellFolder*/
1710 *ppvObj = _IShellFolder_(This);
1712 else if(IsEqualIID(riid, &IID_IShellFolder2)) /*IShellFolder2*/
1714 *ppvObj = _IShellFolder_(This);
1717 if(*ppvObj)
1719 IUnknown_AddRef((IUnknown*)(*ppvObj));
1720 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1721 return S_OK;
1723 TRACE("-- Interface: E_NOINTERFACE\n");
1724 return E_NOINTERFACE;
1727 /**************************************************************************
1728 * ISF_Desktop_fnParseDisplayName
1730 * NOTES
1731 * "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
1732 * to MyComputer
1734 static HRESULT WINAPI ISF_Desktop_fnParseDisplayName(
1735 IShellFolder2 * iface,
1736 HWND hwndOwner,
1737 LPBC pbcReserved,
1738 LPOLESTR lpszDisplayName,
1739 DWORD *pchEaten,
1740 LPITEMIDLIST *ppidl,
1741 DWORD *pdwAttributes)
1743 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1745 LPCWSTR szNext=NULL;
1746 LPITEMIDLIST pidlTemp=NULL;
1747 HRESULT hr=E_OUTOFMEMORY;
1749 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1750 This,hwndOwner,pbcReserved,lpszDisplayName,
1751 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
1753 *ppidl = 0;
1754 if (pchEaten) *pchEaten = 0; /* strange but like the original */
1756 /* FIXME no real parsing implemented */
1757 pidlTemp = _ILCreateMyComputer();
1758 szNext = lpszDisplayName;
1760 if (szNext && *szNext)
1762 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
1764 else
1766 hr = S_OK;
1768 if (pdwAttributes && *pdwAttributes)
1770 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
1774 *ppidl = pidlTemp;
1776 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
1778 return hr;
1781 /**************************************************************************
1782 * ISF_Desktop_fnEnumObjects
1784 static HRESULT WINAPI ISF_Desktop_fnEnumObjects(
1785 IShellFolder2 * iface,
1786 HWND hwndOwner,
1787 DWORD dwFlags,
1788 LPENUMIDLIST* ppEnumIDList)
1790 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1792 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
1794 *ppEnumIDList = NULL;
1795 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_DESK);
1797 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
1799 if(!*ppEnumIDList) return E_OUTOFMEMORY;
1801 return S_OK;
1804 /**************************************************************************
1805 * ISF_Desktop_fnBindToObject
1807 static HRESULT WINAPI ISF_Desktop_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
1808 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
1810 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1811 GUID const * clsid;
1812 IShellFolder *pShellFolder, *pSubFolder;
1813 HRESULT hr;
1815 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
1816 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
1818 *ppvOut = NULL;
1820 if ((clsid=_ILGetGUIDPointer(pidl)))
1822 if ( IsEqualIID(clsid, &CLSID_MyComputer))
1824 pShellFolder = ISF_MyComputer_Constructor();
1826 else
1828 /* shell extension */
1829 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
1831 return E_INVALIDARG;
1835 else
1837 /* file system folder on the desktop */
1838 LPITEMIDLIST deskpidl, firstpidl, completepidl;
1839 IPersistFolder * ppf;
1841 /* combine pidls */
1842 SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, &deskpidl);
1843 firstpidl = ILCloneFirst(pidl);
1844 completepidl = ILCombine(deskpidl, firstpidl);
1846 pShellFolder = IShellFolder_Constructor(NULL, NULL);
1847 if (SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&ppf)))
1849 IPersistFolder_Initialize(ppf, completepidl);
1850 IPersistFolder_Release(ppf);
1852 ILFree(completepidl);
1853 ILFree(deskpidl);
1854 ILFree(firstpidl);
1857 if (_ILIsPidlSimple(pidl)) /* no sub folders */
1859 *ppvOut = pShellFolder;
1860 hr = S_OK;
1862 else /* go deeper */
1864 hr = IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, riid, (LPVOID)&pSubFolder);
1865 IShellFolder_Release(pShellFolder);
1866 *ppvOut = pSubFolder;
1869 TRACE("-- (%p) returning (%p) %08lx\n",This, *ppvOut, hr);
1871 return hr;
1874 /**************************************************************************
1875 * ISF_Desktop_fnCreateViewObject
1877 static HRESULT WINAPI ISF_Desktop_fnCreateViewObject( IShellFolder2 * iface,
1878 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
1880 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1882 LPSHELLVIEW pShellView;
1883 HRESULT hr = E_INVALIDARG;
1885 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
1887 if(ppvOut)
1889 *ppvOut = NULL;
1891 if(IsEqualIID(riid, &IID_IDropTarget))
1893 WARN("IDropTarget not implemented\n");
1894 hr = E_NOTIMPL;
1896 else if(IsEqualIID(riid, &IID_IContextMenu))
1898 WARN("IContextMenu not implemented\n");
1899 hr = E_NOTIMPL;
1901 else if(IsEqualIID(riid, &IID_IShellView))
1903 pShellView = IShellView_Constructor((IShellFolder*)iface);
1904 if(pShellView)
1906 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
1907 IShellView_Release(pShellView);
1911 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
1912 return hr;
1915 /**************************************************************************
1916 * ISF_Desktop_fnGetAttributesOf
1918 static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf(
1919 IShellFolder2 * iface,
1920 UINT cidl,
1921 LPCITEMIDLIST *apidl,
1922 DWORD *rgfInOut)
1924 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1926 HRESULT hr = S_OK;
1928 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl, *rgfInOut);
1930 if ( (!cidl) || (!apidl) || (!rgfInOut))
1931 return E_INVALIDARG;
1933 while (cidl > 0 && *apidl)
1935 pdump (*apidl);
1936 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
1937 apidl++;
1938 cidl--;
1941 TRACE("-- result=0x%08lx\n",*rgfInOut);
1943 return hr;
1946 /**************************************************************************
1947 * ISF_Desktop_fnGetDisplayNameOf
1949 * NOTES
1950 * special case: pidl = null gives desktop-name back
1952 static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf(
1953 IShellFolder2 * iface,
1954 LPCITEMIDLIST pidl,
1955 DWORD dwFlags,
1956 LPSTRRET strRet)
1958 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1960 CHAR szPath[MAX_PATH]= "";
1962 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1963 pdump(pidl);
1965 if(!strRet) return E_INVALIDARG;
1967 if(!pidl)
1969 HCR_GetClassName(&CLSID_ShellDesktop, szPath, MAX_PATH);
1971 else if ( _ILIsPidlSimple(pidl) )
1973 _ILSimpleGetText(pidl, szPath, MAX_PATH);
1975 else
1977 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath, MAX_PATH)))
1978 return E_OUTOFMEMORY;
1980 strRet->uType = STRRET_CSTRA;
1981 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1984 TRACE("-- (%p)->(%s)\n", This, szPath);
1985 return S_OK;
1988 static HRESULT WINAPI ISF_Desktop_fnGetDefaultSearchGUID(
1989 IShellFolder2 * iface,
1990 GUID *pguid)
1992 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1993 FIXME("(%p)\n",This);
1994 return E_NOTIMPL;
1996 static HRESULT WINAPI ISF_Desktop_fnEnumSearches(
1997 IShellFolder2 * iface,
1998 IEnumExtraSearch **ppenum)
2000 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2001 FIXME("(%p)\n",This);
2002 return E_NOTIMPL;
2004 static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumn(
2005 IShellFolder2 * iface,
2006 DWORD dwRes,
2007 ULONG *pSort,
2008 ULONG *pDisplay)
2010 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2012 TRACE("(%p)\n",This);
2014 if (pSort) *pSort = 0;
2015 if (pDisplay) *pDisplay = 0;
2017 return S_OK;
2019 static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumnState(
2020 IShellFolder2 * iface,
2021 UINT iColumn,
2022 DWORD *pcsFlags)
2024 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2026 TRACE("(%p)\n",This);
2028 if (!pcsFlags || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2030 *pcsFlags = DesktopSFHeader[iColumn].pcsFlags;
2032 return S_OK;
2034 static HRESULT WINAPI ISF_Desktop_fnGetDetailsEx(
2035 IShellFolder2 * iface,
2036 LPCITEMIDLIST pidl,
2037 const SHCOLUMNID *pscid,
2038 VARIANT *pv)
2040 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2041 FIXME("(%p)\n",This);
2043 return E_NOTIMPL;
2045 static HRESULT WINAPI ISF_Desktop_fnGetDetailsOf(
2046 IShellFolder2 * iface,
2047 LPCITEMIDLIST pidl,
2048 UINT iColumn,
2049 SHELLDETAILS *psd)
2051 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2052 HRESULT hr = E_FAIL;
2054 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
2056 if (!psd || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2058 if (!pidl)
2060 psd->fmt = DesktopSFHeader[iColumn].fmt;
2061 psd->cxChar = DesktopSFHeader[iColumn].cxChar;
2062 psd->str.uType = STRRET_CSTRA;
2063 LoadStringA(shell32_hInstance, DesktopSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
2064 return S_OK;
2066 else
2068 /* the data from the pidl */
2069 switch(iColumn)
2071 case 0: /* name */
2072 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2073 break;
2074 case 1: /* size */
2075 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
2076 break;
2077 case 2: /* type */
2078 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2079 break;
2080 case 3: /* date */
2081 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
2082 break;
2083 case 4: /* attributes */
2084 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
2085 break;
2087 hr = S_OK;
2088 psd->str.uType = STRRET_CSTRA;
2091 return hr;
2093 static HRESULT WINAPI ISF_Desktop_fnMapNameToSCID(
2094 IShellFolder2 * iface,
2095 LPCWSTR pwszName,
2096 SHCOLUMNID *pscid)
2098 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2099 FIXME("(%p)\n",This);
2100 return E_NOTIMPL;
2103 static ICOM_VTABLE(IShellFolder2) sfdvt =
2105 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2106 ISF_Desktop_fnQueryInterface,
2107 IShellFolder_fnAddRef,
2108 IShellFolder_fnRelease,
2109 ISF_Desktop_fnParseDisplayName,
2110 ISF_Desktop_fnEnumObjects,
2111 ISF_Desktop_fnBindToObject,
2112 IShellFolder_fnBindToStorage,
2113 IShellFolder_fnCompareIDs,
2114 ISF_Desktop_fnCreateViewObject,
2115 ISF_Desktop_fnGetAttributesOf,
2116 IShellFolder_fnGetUIObjectOf,
2117 ISF_Desktop_fnGetDisplayNameOf,
2118 IShellFolder_fnSetNameOf,
2120 /* ShellFolder2 */
2121 ISF_Desktop_fnGetDefaultSearchGUID,
2122 ISF_Desktop_fnEnumSearches,
2123 ISF_Desktop_fnGetDefaultColumn,
2124 ISF_Desktop_fnGetDefaultColumnState,
2125 ISF_Desktop_fnGetDetailsEx,
2126 ISF_Desktop_fnGetDetailsOf,
2127 ISF_Desktop_fnMapNameToSCID
2131 /***********************************************************************
2132 * IShellFolder [MyComputer] implementation
2135 static struct ICOM_VTABLE(IShellFolder2) sfmcvt;
2137 static shvheader MyComputerSFHeader [] =
2139 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
2140 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2141 { IDS_SHV_COLUMN6, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2142 { IDS_SHV_COLUMN7, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2144 #define MYCOMPUTERSHELLVIEWCOLUMNS 4
2146 /**************************************************************************
2147 * ISF_MyComputer_Constructor
2149 static IShellFolder * ISF_MyComputer_Constructor(void)
2151 IGenericSFImpl * sf;
2153 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
2154 sf->ref=1;
2156 ICOM_VTBL(sf)=&unkvt;
2157 sf->lpvtblShellFolder=&sfmcvt;
2158 sf->lpvtblPersistFolder2 = &psfvt;
2159 sf->pclsid = (CLSID*)&CLSID_SFMyComp;
2160 sf->absPidl=_ILCreateMyComputer(); /* my qualified pidl */
2161 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
2163 TRACE("(%p)\n",sf);
2165 shell32_ObjCount++;
2166 return _IShellFolder_(sf);
2169 /**************************************************************************
2170 * ISF_MyComputer_fnParseDisplayName
2172 static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName(
2173 IShellFolder2 * iface,
2174 HWND hwndOwner,
2175 LPBC pbcReserved,
2176 LPOLESTR lpszDisplayName,
2177 DWORD *pchEaten,
2178 LPITEMIDLIST *ppidl,
2179 DWORD *pdwAttributes)
2181 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2183 HRESULT hr = E_OUTOFMEMORY;
2184 LPCWSTR szNext=NULL;
2185 WCHAR szElement[MAX_PATH];
2186 CHAR szTempA[MAX_PATH];
2187 LPITEMIDLIST pidlTemp;
2189 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
2190 This,hwndOwner,pbcReserved,lpszDisplayName,
2191 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
2193 *ppidl = 0;
2194 if (pchEaten) *pchEaten = 0; /* strange but like the original */
2196 /* do we have an absolute path name ? */
2197 if (PathGetDriveNumberW(lpszDisplayName) >= 0 &&
2198 lpszDisplayName[2] == (WCHAR)'\\')
2200 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
2201 WideCharToMultiByte( CP_ACP, 0, szElement, -1, szTempA, MAX_PATH, NULL, NULL );
2202 pidlTemp = _ILCreateDrive(szTempA);
2204 if (szNext && *szNext)
2206 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
2208 else
2210 if (pdwAttributes && *pdwAttributes)
2212 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
2214 hr = S_OK;
2216 *ppidl = pidlTemp;
2219 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
2221 return hr;
2224 /**************************************************************************
2225 * ISF_MyComputer_fnEnumObjects
2227 static HRESULT WINAPI ISF_MyComputer_fnEnumObjects(
2228 IShellFolder2 * iface,
2229 HWND hwndOwner,
2230 DWORD dwFlags,
2231 LPENUMIDLIST* ppEnumIDList)
2233 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2235 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
2237 *ppEnumIDList = NULL;
2238 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_MYCOMP);
2240 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
2242 if(!*ppEnumIDList) return E_OUTOFMEMORY;
2244 return S_OK;
2247 /**************************************************************************
2248 * ISF_MyComputer_fnBindToObject
2250 static HRESULT WINAPI ISF_MyComputer_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
2251 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
2253 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2254 GUID const * clsid;
2255 IShellFolder *pShellFolder, *pSubFolder;
2256 LPITEMIDLIST pidltemp;
2257 HRESULT hr;
2259 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
2260 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
2262 if(!pidl || !ppvOut) return E_INVALIDARG;
2264 *ppvOut = NULL;
2266 if ((clsid=_ILGetGUIDPointer(pidl)) && !IsEqualIID(clsid, &CLSID_MyComputer))
2268 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
2270 return E_FAIL;
2273 else
2275 if (!_ILIsDrive(pidl)) return E_INVALIDARG;
2277 pidltemp = ILCloneFirst(pidl);
2278 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
2279 ILFree(pidltemp);
2282 if (_ILIsPidlSimple(pidl)) /* no sub folders */
2284 *ppvOut = pShellFolder;
2285 hr = S_OK;
2287 else /* go deeper */
2289 hr = IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL,
2290 riid, (LPVOID)&pSubFolder);
2291 IShellFolder_Release(pShellFolder);
2292 *ppvOut = pSubFolder;
2295 TRACE("-- (%p) returning (%p) %08lx\n",This, *ppvOut, hr);
2297 return hr;
2300 /**************************************************************************
2301 * ISF_MyComputer_fnCreateViewObject
2303 static HRESULT WINAPI ISF_MyComputer_fnCreateViewObject( IShellFolder2 * iface,
2304 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
2306 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2308 LPSHELLVIEW pShellView;
2309 HRESULT hr = E_INVALIDARG;
2311 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
2313 if(ppvOut)
2315 *ppvOut = NULL;
2317 if(IsEqualIID(riid, &IID_IDropTarget))
2319 WARN("IDropTarget not implemented\n");
2320 hr = E_NOTIMPL;
2322 else if(IsEqualIID(riid, &IID_IContextMenu))
2324 WARN("IContextMenu not implemented\n");
2325 hr = E_NOTIMPL;
2327 else if(IsEqualIID(riid, &IID_IShellView))
2329 pShellView = IShellView_Constructor((IShellFolder*)iface);
2330 if(pShellView)
2332 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
2333 IShellView_Release(pShellView);
2337 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
2338 return hr;
2341 /**************************************************************************
2342 * ISF_MyComputer_fnGetAttributesOf
2344 static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf(
2345 IShellFolder2 * iface,
2346 UINT cidl,
2347 LPCITEMIDLIST *apidl,
2348 DWORD *rgfInOut)
2350 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2352 HRESULT hr = S_OK;
2354 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
2356 if ( (!cidl) || (!apidl) || (!rgfInOut))
2357 return E_INVALIDARG;
2359 while (cidl > 0 && *apidl)
2361 pdump (*apidl);
2362 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
2363 apidl++;
2364 cidl--;
2367 TRACE("-- result=0x%08lx\n",*rgfInOut);
2368 return hr;
2371 /**************************************************************************
2372 * ISF_MyComputer_fnGetDisplayNameOf
2374 * NOTES
2375 * The desktopfolder creates only complete paths (SHGDN_FORPARSING).
2376 * SHGDN_INFOLDER makes no sense.
2378 static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf(
2379 IShellFolder2 * iface,
2380 LPCITEMIDLIST pidl,
2381 DWORD dwFlags,
2382 LPSTRRET strRet)
2384 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2386 char szPath[MAX_PATH], szDrive[18];
2387 int len = 0;
2388 BOOL bSimplePidl;
2390 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
2391 pdump(pidl);
2393 if(!strRet) return E_INVALIDARG;
2395 szPath[0]=0x00; szDrive[0]=0x00;
2398 bSimplePidl = _ILIsPidlSimple(pidl);
2400 if (_ILIsSpecialFolder(pidl))
2402 /* take names of special folders only if its only this folder */
2403 if ( bSimplePidl )
2405 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2408 else
2410 if (!_ILIsDrive(pidl))
2412 ERR("Wrong pidl type\n");
2413 return E_INVALIDARG;
2416 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2418 /* long view "lw_name (C:)" */
2419 if ( bSimplePidl && !(dwFlags & SHGDN_FORPARSING))
2421 DWORD dwVolumeSerialNumber,dwMaximumComponetLength,dwFileSystemFlags;
2423 GetVolumeInformationA(szPath,szDrive,sizeof(szDrive)-6,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0);
2424 strcat (szDrive," (");
2425 strncat (szDrive, szPath, 2);
2426 strcat (szDrive,")");
2427 strcpy (szPath, szDrive);
2431 if (!bSimplePidl) /* go deeper if needed */
2433 PathAddBackslashA(szPath);
2434 len = strlen(szPath);
2436 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags | SHGDN_FORPARSING, szPath + len, MAX_PATH - len)))
2437 return E_OUTOFMEMORY;
2439 strRet->uType = STRRET_CSTRA;
2440 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
2443 TRACE("-- (%p)->(%s)\n", This, szPath);
2444 return S_OK;
2447 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultSearchGUID(
2448 IShellFolder2 * iface,
2449 GUID *pguid)
2451 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2452 FIXME("(%p)\n",This);
2453 return E_NOTIMPL;
2455 static HRESULT WINAPI ISF_MyComputer_fnEnumSearches(
2456 IShellFolder2 * iface,
2457 IEnumExtraSearch **ppenum)
2459 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2460 FIXME("(%p)\n",This);
2461 return E_NOTIMPL;
2463 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumn(
2464 IShellFolder2 * iface,
2465 DWORD dwRes,
2466 ULONG *pSort,
2467 ULONG *pDisplay)
2469 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2471 TRACE("(%p)\n",This);
2473 if (pSort) *pSort = 0;
2474 if (pDisplay) *pDisplay = 0;
2476 return S_OK;
2478 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumnState(
2479 IShellFolder2 * iface,
2480 UINT iColumn,
2481 DWORD *pcsFlags)
2483 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2485 TRACE("(%p)\n",This);
2487 if (!pcsFlags || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2489 *pcsFlags = MyComputerSFHeader[iColumn].pcsFlags;
2491 return S_OK;
2493 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsEx(
2494 IShellFolder2 * iface,
2495 LPCITEMIDLIST pidl,
2496 const SHCOLUMNID *pscid,
2497 VARIANT *pv)
2499 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2500 FIXME("(%p)\n",This);
2502 return E_NOTIMPL;
2505 /* FIXME: drive size >4GB is rolling over */
2506 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf(
2507 IShellFolder2 * iface,
2508 LPCITEMIDLIST pidl,
2509 UINT iColumn,
2510 SHELLDETAILS *psd)
2512 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2513 HRESULT hr;
2515 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
2517 if (!psd || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2519 if (!pidl)
2521 psd->fmt = MyComputerSFHeader[iColumn].fmt;
2522 psd->cxChar = MyComputerSFHeader[iColumn].cxChar;
2523 psd->str.uType = STRRET_CSTRA;
2524 LoadStringA(shell32_hInstance, MyComputerSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
2525 return S_OK;
2527 else
2529 char szPath[MAX_PATH];
2530 ULARGE_INTEGER ulBytes;
2532 psd->str.u.cStr[0] = 0x00;
2533 psd->str.uType = STRRET_CSTRA;
2534 switch(iColumn)
2536 case 0: /* name */
2537 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2538 break;
2539 case 1: /* type */
2540 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2541 break;
2542 case 2: /* total size */
2543 if (_ILIsDrive(pidl))
2545 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2546 GetDiskFreeSpaceExA(szPath, NULL, &ulBytes, NULL);
2547 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2549 break;
2550 case 3: /* free size */
2551 if (_ILIsDrive(pidl))
2553 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2554 GetDiskFreeSpaceExA(szPath, &ulBytes, NULL, NULL);
2555 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2557 break;
2559 hr = S_OK;
2562 return hr;
2564 static HRESULT WINAPI ISF_MyComputer_fnMapNameToSCID(
2565 IShellFolder2 * iface,
2566 LPCWSTR pwszName,
2567 SHCOLUMNID *pscid)
2569 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2570 FIXME("(%p)\n",This);
2571 return E_NOTIMPL;
2574 static ICOM_VTABLE(IShellFolder2) sfmcvt =
2576 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2577 IShellFolder_fnQueryInterface,
2578 IShellFolder_fnAddRef,
2579 IShellFolder_fnRelease,
2580 ISF_MyComputer_fnParseDisplayName,
2581 ISF_MyComputer_fnEnumObjects,
2582 ISF_MyComputer_fnBindToObject,
2583 IShellFolder_fnBindToStorage,
2584 IShellFolder_fnCompareIDs,
2585 ISF_MyComputer_fnCreateViewObject,
2586 ISF_MyComputer_fnGetAttributesOf,
2587 IShellFolder_fnGetUIObjectOf,
2588 ISF_MyComputer_fnGetDisplayNameOf,
2589 IShellFolder_fnSetNameOf,
2591 /* ShellFolder2 */
2592 ISF_MyComputer_fnGetDefaultSearchGUID,
2593 ISF_MyComputer_fnEnumSearches,
2594 ISF_MyComputer_fnGetDefaultColumn,
2595 ISF_MyComputer_fnGetDefaultColumnState,
2596 ISF_MyComputer_fnGetDetailsEx,
2597 ISF_MyComputer_fnGetDetailsOf,
2598 ISF_MyComputer_fnMapNameToSCID
2602 /************************************************************************
2603 * ISFPersistFolder_QueryInterface (IUnknown)
2606 static HRESULT WINAPI ISFPersistFolder2_QueryInterface(
2607 IPersistFolder2 * iface,
2608 REFIID iid,
2609 LPVOID* ppvObj)
2611 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2613 TRACE("(%p)\n", This);
2615 return IUnknown_QueryInterface(This->pUnkOuter, iid, ppvObj);
2618 /************************************************************************
2619 * ISFPersistFolder_AddRef (IUnknown)
2622 static ULONG WINAPI ISFPersistFolder2_AddRef(
2623 IPersistFolder2 * iface)
2625 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2627 TRACE("(%p)\n", This);
2629 return IUnknown_AddRef(This->pUnkOuter);
2632 /************************************************************************
2633 * ISFPersistFolder_Release (IUnknown)
2636 static ULONG WINAPI ISFPersistFolder2_Release(
2637 IPersistFolder2 * iface)
2639 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2641 TRACE("(%p)\n", This);
2643 return IUnknown_Release(This->pUnkOuter);
2646 /************************************************************************
2647 * ISFPersistFolder_GetClassID (IPersist)
2649 static HRESULT WINAPI ISFPersistFolder2_GetClassID(
2650 IPersistFolder2 * iface,
2651 CLSID * lpClassId)
2653 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2655 TRACE("(%p)\n", This);
2657 if (!lpClassId) return E_POINTER;
2658 *lpClassId = *This->pclsid;
2660 return S_OK;
2663 /************************************************************************
2664 * ISFPersistFolder_Initialize (IPersistFolder)
2666 * NOTES
2667 * sMyPath is not set. Don't know how to handle in a non rooted environment.
2669 static HRESULT WINAPI ISFPersistFolder2_Initialize(
2670 IPersistFolder2 * iface,
2671 LPCITEMIDLIST pidl)
2673 char sTemp[MAX_PATH];
2674 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2676 TRACE("(%p)->(%p)\n", This, pidl);
2678 /* free the old stuff */
2679 if(This->absPidl)
2681 SHFree(This->absPidl);
2682 This->absPidl = NULL;
2684 if(This->sMyPath)
2686 SHFree(This->sMyPath);
2687 This->sMyPath = NULL;
2690 /* set my pidl */
2691 This->absPidl = ILClone(pidl);
2693 /* set my path */
2694 if (SHGetPathFromIDListA(pidl, sTemp))
2696 This->sMyPath = SHAlloc(strlen(sTemp)+1);
2697 strcpy(This->sMyPath, sTemp);
2700 TRACE("--(%p)->(%s)\n", This, This->sMyPath);
2702 return S_OK;
2705 /**************************************************************************
2706 * IPersistFolder2_fnGetCurFolder
2708 static HRESULT WINAPI ISFPersistFolder2_fnGetCurFolder(
2709 IPersistFolder2 * iface,
2710 LPITEMIDLIST * pidl)
2712 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2714 TRACE("(%p)->(%p)\n",This, pidl);
2716 if (!pidl) return E_POINTER;
2718 *pidl = ILClone(This->absPidl);
2720 return S_OK;
2723 static ICOM_VTABLE(IPersistFolder2) psfvt =
2725 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2726 ISFPersistFolder2_QueryInterface,
2727 ISFPersistFolder2_AddRef,
2728 ISFPersistFolder2_Release,
2729 ISFPersistFolder2_GetClassID,
2730 ISFPersistFolder2_Initialize,
2731 ISFPersistFolder2_fnGetCurFolder
2734 /****************************************************************************
2735 * ISFDropTarget implementation
2737 static BOOL ISFDropTarget_QueryDrop(
2738 IDropTarget *iface,
2739 DWORD dwKeyState,
2740 LPDWORD pdwEffect)
2742 DWORD dwEffect = *pdwEffect;
2744 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2746 *pdwEffect = DROPEFFECT_NONE;
2748 if (This->fAcceptFmt)
2749 { /* Does our interpretation of the keystate ... */
2750 *pdwEffect = KeyStateToDropEffect(dwKeyState);
2752 /* ... matches the desired effect ? */
2753 if (dwEffect & *pdwEffect)
2755 return TRUE;
2758 return FALSE;
2761 static HRESULT WINAPI ISFDropTarget_QueryInterface(
2762 IDropTarget *iface,
2763 REFIID riid,
2764 LPVOID *ppvObj)
2766 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2768 TRACE("(%p)\n", This);
2770 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
2773 static ULONG WINAPI ISFDropTarget_AddRef( IDropTarget *iface)
2775 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2777 TRACE("(%p)\n", This);
2779 return IUnknown_AddRef(This->pUnkOuter);
2782 static ULONG WINAPI ISFDropTarget_Release( IDropTarget *iface)
2784 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2786 TRACE("(%p)\n", This);
2788 return IUnknown_Release(This->pUnkOuter);
2791 static HRESULT WINAPI ISFDropTarget_DragEnter(
2792 IDropTarget *iface,
2793 IDataObject *pDataObject,
2794 DWORD dwKeyState,
2795 POINTL pt,
2796 DWORD *pdwEffect)
2798 FORMATETC fmt;
2800 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2802 TRACE("(%p)->(DataObject=%p)\n",This,pDataObject);
2804 InitFormatEtc(fmt, This->cfShellIDList, TYMED_HGLOBAL);
2806 This->fAcceptFmt = (S_OK == IDataObject_QueryGetData(pDataObject, &fmt)) ? TRUE : FALSE;
2808 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2810 return S_OK;
2813 static HRESULT WINAPI ISFDropTarget_DragOver(
2814 IDropTarget *iface,
2815 DWORD dwKeyState,
2816 POINTL pt,
2817 DWORD *pdwEffect)
2819 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2821 TRACE("(%p)\n",This);
2823 if(!pdwEffect) return E_INVALIDARG;
2825 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2827 return S_OK;
2830 static HRESULT WINAPI ISFDropTarget_DragLeave(
2831 IDropTarget *iface)
2833 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2835 TRACE("(%p)\n",This);
2837 This->fAcceptFmt = FALSE;
2839 return S_OK;
2842 static HRESULT WINAPI ISFDropTarget_Drop(
2843 IDropTarget *iface,
2844 IDataObject* pDataObject,
2845 DWORD dwKeyState,
2846 POINTL pt,
2847 DWORD *pdwEffect)
2849 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2851 FIXME("(%p) object dropped\n",This);
2853 return E_NOTIMPL;
2856 static struct ICOM_VTABLE(IDropTarget) dtvt =
2858 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2859 ISFDropTarget_QueryInterface,
2860 ISFDropTarget_AddRef,
2861 ISFDropTarget_Release,
2862 ISFDropTarget_DragEnter,
2863 ISFDropTarget_DragOver,
2864 ISFDropTarget_DragLeave,
2865 ISFDropTarget_Drop