Added the DFCS_{HOT,TRANSPARENT} definitions.
[wine/gsoc_dplay.git] / dlls / shell32 / shlfolder.c
blob9bfb06b35fd52a216fe8de43b0313e954074014c
1 /*
2 * Shell Folder stuff
4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998, 1999 Juergen Schmied
6 *
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 <stdlib.h>
25 #include <string.h>
26 #include <stdio.h>
28 #include "winerror.h"
29 #include "winbase.h"
30 #include "winreg.h"
32 #include "oleidl.h"
33 #include "shlguid.h"
35 #include "pidl.h"
36 #include "wine/obj_base.h"
37 #include "wine/obj_dragdrop.h"
38 #include "wine/obj_shellfolder.h"
39 #include "undocshell.h"
40 #include "shell32_main.h"
41 #include "shresdef.h"
42 #include "shlwapi.h"
43 #include "shellfolder.h"
44 #include "wine/debug.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(shell);
49 /***************************************************************************
50 * debughelper: print out the return adress
51 * helps especially to track down unbalanced AddRef/Release
53 #define MEM_DEBUG 0
55 #if MEM_DEBUG
56 #define _CALL_TRACE TRACE("called from: 0x%08x\n", *( ((UINT*)&iface)-1 ));
57 #else
58 #define _CALL_TRACE
59 #endif
61 typedef struct
63 int colnameid;
64 int pcsFlags;
65 int fmt;
66 int cxChar;
68 } shvheader;
70 /***************************************************************************
71 * GetNextElement (internal function)
73 * gets a part of a string till the first backslash
75 * PARAMETERS
76 * pszNext [IN] string to get the element from
77 * pszOut [IN] pointer to buffer whitch receives string
78 * dwOut [IN] length of pszOut
80 * RETURNS
81 * LPSTR pointer to first, not yet parsed char
84 static LPCWSTR GetNextElementW(LPCWSTR pszNext,LPWSTR pszOut,DWORD dwOut)
85 { LPCWSTR pszTail = pszNext;
86 DWORD dwCopy;
87 TRACE("(%s %p 0x%08lx)\n",debugstr_w(pszNext),pszOut,dwOut);
89 *pszOut=0x0000;
91 if(!pszNext || !*pszNext)
92 return NULL;
94 while(*pszTail && (*pszTail != (WCHAR)'\\'))
95 pszTail++;
97 dwCopy = (WCHAR*)pszTail - (WCHAR*)pszNext + 1;
98 lstrcpynW(pszOut, pszNext, (dwOut<dwCopy)? dwOut : dwCopy);
100 if(*pszTail)
101 pszTail++;
102 else
103 pszTail = NULL;
105 TRACE("--(%s %s 0x%08lx %p)\n",debugstr_w(pszNext),debugstr_w(pszOut),dwOut,pszTail);
106 return pszTail;
109 static HRESULT SHELL32_ParseNextElement(
110 HWND hwndOwner,
111 IShellFolder2 * psf,
112 LPITEMIDLIST * pidlInOut,
113 LPOLESTR szNext,
114 DWORD *pEaten,
115 DWORD *pdwAttributes)
117 HRESULT hr = E_OUTOFMEMORY;
118 LPITEMIDLIST pidlOut, pidlTemp = NULL;
119 IShellFolder *psfChild;
121 TRACE("(%p, %p, %s)\n",psf, pidlInOut ? *pidlInOut : NULL, debugstr_w(szNext));
124 /* get the shellfolder for the child pidl and let it analyse further */
125 hr = IShellFolder_BindToObject(psf, *pidlInOut, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
127 if (psfChild)
129 hr = IShellFolder_ParseDisplayName(psfChild, hwndOwner, NULL, szNext, pEaten, &pidlOut, pdwAttributes);
130 IShellFolder_Release(psfChild);
132 pidlTemp = ILCombine(*pidlInOut, pidlOut);
134 if (pidlOut)
135 ILFree(pidlOut);
138 ILFree(*pidlInOut);
139 *pidlInOut = pidlTemp;
141 TRACE("-- pidl=%p ret=0x%08lx\n", pidlInOut? *pidlInOut: NULL, hr);
142 return hr;
145 /***********************************************************************
146 * SHELL32_CoCreateInitSF
148 * creates a initialized shell folder
150 static HRESULT SHELL32_CoCreateInitSF (
151 LPITEMIDLIST pidlRoot,
152 LPITEMIDLIST pidlChild,
153 REFCLSID clsid,
154 REFIID iid,
155 LPVOID * ppvOut)
157 HRESULT hr;
158 LPITEMIDLIST absPidl;
159 IShellFolder2 *pShellFolder;
160 IPersistFolder *pPersistFolder;
162 TRACE("%p %p\n", pidlRoot, pidlChild);
164 *ppvOut = NULL;
166 /* we have to ask first for IPersistFolder, some special folders are expecting this */
167 hr = SHCoCreateInstance(NULL, clsid, NULL, &IID_IPersistFolder, (LPVOID*)&pPersistFolder);
168 if (SUCCEEDED(hr))
170 hr = IPersistFolder_QueryInterface(pPersistFolder, iid, (LPVOID*)&pShellFolder);
171 if (SUCCEEDED(hr))
173 absPidl = ILCombine (pidlRoot, pidlChild);
174 hr = IPersistFolder_Initialize(pPersistFolder, absPidl);
175 IPersistFolder_Release(pPersistFolder);
176 SHFree(absPidl);
177 *ppvOut = pShellFolder;
181 TRACE("-- ret=0x%08lx\n", hr);
182 return hr;
185 static HRESULT SHELL32_GetDisplayNameOfChild(
186 IShellFolder2 * psf,
187 LPCITEMIDLIST pidl,
188 DWORD dwFlags,
189 LPSTR szOut,
190 DWORD dwOutLen)
192 LPITEMIDLIST pidlFirst, pidlNext;
193 IShellFolder2 * psfChild;
194 HRESULT hr = E_OUTOFMEMORY;
195 STRRET strTemp;
197 TRACE("(%p)->(pidl=%p 0x%08lx %p 0x%08lx)\n",psf,pidl,dwFlags,szOut, dwOutLen);
198 pdump(pidl);
200 if ((pidlFirst = ILCloneFirst(pidl)))
202 hr = IShellFolder_BindToObject(psf, pidlFirst, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
203 if (SUCCEEDED(hr))
205 pidlNext = ILGetNext(pidl);
207 hr = IShellFolder_GetDisplayNameOf(psfChild, pidlNext, dwFlags | SHGDN_INFOLDER, &strTemp);
208 if (SUCCEEDED(hr))
210 hr = StrRetToStrNA(szOut, dwOutLen, &strTemp, pidlNext);
213 IShellFolder_Release(psfChild);
215 ILFree(pidlFirst);
218 TRACE("-- ret=0x%08lx %s\n", hr, szOut);
220 return hr;
223 /***********************************************************************
224 * SHELL32_GetItemAttributes
226 * NOTES
227 * observerd values:
228 * folder: 0xE0000177 FILESYSTEM | HASSUBFOLDER | FOLDER
229 * file: 0x40000177 FILESYSTEM
230 * drive: 0xf0000144 FILESYSTEM | HASSUBFOLDER | FOLDER | FILESYSANCESTOR
231 * mycomputer: 0xb0000154 HASSUBFOLDER | FOLDER | FILESYSANCESTOR
232 * (seems to be default for shell extensions if no registry entry exists)
234 * This functions does not set flags!! It only resets flags when nessesary.
236 static HRESULT SHELL32_GetItemAttributes(
237 IShellFolder * psf,
238 LPITEMIDLIST pidl,
239 LPDWORD pdwAttributes)
241 GUID const * clsid;
242 DWORD dwAttributes;
244 TRACE("0x%08lx\n", *pdwAttributes);
246 if (*pdwAttributes & (0xcff3fe88))
247 WARN("attribute 0x%08lx not implemented\n", *pdwAttributes);
248 *pdwAttributes &= ~SFGAO_LINK; /* FIXME: for native filedialogs */
250 if (_ILIsDrive(pidl))
252 *pdwAttributes &= 0xf0000144;
254 else if ((clsid=_ILGetGUIDPointer(pidl)))
256 if (HCR_GetFolderAttributes(clsid, &dwAttributes))
258 *pdwAttributes &= dwAttributes;
260 else
262 *pdwAttributes &= 0xb0000154;
265 else if (_ILGetDataPointer(pidl))
267 dwAttributes = _ILGetFileAttributes(pidl, NULL, 0);
268 *pdwAttributes &= ~SFGAO_FILESYSANCESTOR;
270 if(( SFGAO_FOLDER & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
271 *pdwAttributes &= ~(SFGAO_FOLDER|SFGAO_HASSUBFOLDER);
273 if(( SFGAO_HIDDEN & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_HIDDEN))
274 *pdwAttributes &= ~SFGAO_HIDDEN;
276 if(( SFGAO_READONLY & *pdwAttributes) && !(dwAttributes & FILE_ATTRIBUTE_READONLY))
277 *pdwAttributes &= ~SFGAO_READONLY;
279 else
281 *pdwAttributes &= 0xb0000154;
283 TRACE("-- 0x%08lx\n", *pdwAttributes);
284 return S_OK;
287 /***********************************************************************
288 * IShellFolder implementation
291 typedef struct
293 ICOM_VFIELD(IUnknown);
294 DWORD ref;
295 ICOM_VTABLE(IShellFolder2)* lpvtblShellFolder;
296 ICOM_VTABLE(IPersistFolder2)* lpvtblPersistFolder2;
297 ICOM_VTABLE(IDropTarget)* lpvtblDropTarget;
298 ICOM_VTABLE(ISFHelper)* lpvtblSFHelper;
300 IUnknown *pUnkOuter; /* used for aggregation */
302 CLSID* pclsid;
304 LPSTR sMyPath;
305 LPITEMIDLIST absPidl; /* complete pidl */
307 UINT cfShellIDList; /* clipboardformat for IDropTarget */
308 BOOL fAcceptFmt; /* flag for pending Drop */
309 } IGenericSFImpl;
311 static struct ICOM_VTABLE(IUnknown) unkvt;
312 static struct ICOM_VTABLE(IShellFolder2) sfvt;
313 static struct ICOM_VTABLE(IPersistFolder2) psfvt;
314 static struct ICOM_VTABLE(IDropTarget) dtvt;
315 static struct ICOM_VTABLE(ISFHelper) shvt;
317 static IShellFolder * ISF_MyComputer_Constructor(void);
319 #define _IShellFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblShellFolder)))
320 #define _ICOM_THIS_From_IShellFolder2(class, name) class* This = (class*)(((char*)name)-_IShellFolder2_Offset);
322 #define _IPersistFolder_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblPersistFolder2)))
323 #define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder_Offset);
325 #define _IDropTarget_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblDropTarget)))
326 #define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
328 #define _ISFHelper_Offset ((int)(&(((IGenericSFImpl*)0)->lpvtblSFHelper)))
329 #define _ICOM_THIS_From_ISFHelper(class, name) class* This = (class*)(((char*)name)-_ISFHelper_Offset);
331 converts This to a interface pointer
333 #define _IUnknown_(This) (IUnknown*)&(This->lpVtbl)
334 #define _IShellFolder_(This) (IShellFolder*)&(This->lpvtblShellFolder)
335 #define _IShellFolder2_(This) (IShellFolder2*)&(This->lpvtblShellFolder)
336 #define _IPersist_(This) (IPersist*)&(This->lpvtblPersistFolder2)
337 #define _IPersistFolder_(This) (IPersistFolder*)&(This->lpvtblPersistFolder2)
338 #define _IPersistFolder2_(This) (IPersistFolder2*)&(This->lpvtblPersistFolder2)
339 #define _IDropTarget_(This) (IDropTarget*)&(This->lpvtblDropTarget)
340 #define _ISFHelper_(This) (ISFHelper*)&(This->lpvtblSFHelper)
341 /**************************************************************************
342 * registers clipboardformat once
344 static void SF_RegisterClipFmt (IGenericSFImpl * This)
346 TRACE("(%p)\n", This);
348 if (!This->cfShellIDList)
350 This->cfShellIDList = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
354 /**************************************************************************
355 * we need a separate IUnknown to handle aggregation
356 * (inner IUnknown)
358 static HRESULT WINAPI IUnknown_fnQueryInterface(
359 IUnknown * iface,
360 REFIID riid,
361 LPVOID *ppvObj)
363 ICOM_THIS(IGenericSFImpl, iface);
365 _CALL_TRACE
366 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
368 *ppvObj = NULL;
370 if(IsEqualIID(riid, &IID_IUnknown)) *ppvObj = _IUnknown_(This);
371 else if(IsEqualIID(riid, &IID_IShellFolder)) *ppvObj = _IShellFolder_(This);
372 else if(IsEqualIID(riid, &IID_IShellFolder2)) *ppvObj = _IShellFolder_(This);
373 else if(IsEqualIID(riid, &IID_IPersist)) *ppvObj = _IPersist_(This);
374 else if(IsEqualIID(riid, &IID_IPersistFolder)) *ppvObj = _IPersistFolder_(This);
375 else if(IsEqualIID(riid, &IID_IPersistFolder2)) *ppvObj = _IPersistFolder2_(This);
376 else if(IsEqualIID(riid, &IID_ISFHelper)) *ppvObj = _ISFHelper_(This);
377 else if(IsEqualIID(riid, &IID_IDropTarget))
379 *ppvObj = _IDropTarget_(This);
380 SF_RegisterClipFmt(This);
383 if(*ppvObj)
385 IUnknown_AddRef((IUnknown*)(*ppvObj));
386 TRACE("-- Interface = %p\n", *ppvObj);
387 return S_OK;
389 TRACE("-- Interface: E_NOINTERFACE\n");
390 return E_NOINTERFACE;
393 static ULONG WINAPI IUnknown_fnAddRef(IUnknown * iface)
395 ICOM_THIS(IGenericSFImpl, iface);
397 _CALL_TRACE
398 TRACE("(%p)->(count=%lu)\n",This,This->ref);
400 shell32_ObjCount++;
401 return ++(This->ref);
404 static ULONG WINAPI IUnknown_fnRelease(IUnknown * iface)
406 ICOM_THIS(IGenericSFImpl, iface);
408 _CALL_TRACE
409 TRACE("(%p)->(count=%lu)\n",This,This->ref);
411 shell32_ObjCount--;
412 if (!--(This->ref))
414 TRACE("-- destroying IShellFolder(%p)\n",This);
416 if (pdesktopfolder == _IShellFolder_(This))
418 pdesktopfolder=NULL;
419 TRACE("-- destroyed IShellFolder(%p) was Desktopfolder\n",This);
421 if(This->absPidl) SHFree(This->absPidl);
422 if(This->sMyPath) SHFree(This->sMyPath);
423 HeapFree(GetProcessHeap(),0,This);
424 return 0;
426 return This->ref;
429 static ICOM_VTABLE(IUnknown) unkvt =
431 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
432 IUnknown_fnQueryInterface,
433 IUnknown_fnAddRef,
434 IUnknown_fnRelease,
437 static shvheader GenericSFHeader [] =
439 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
440 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
441 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
442 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
443 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
445 #define GENERICSHELLVIEWCOLUMNS 5
447 /**************************************************************************
448 * IShellFolder_Constructor
450 * NOTES
451 * creating undocumented ShellFS_Folder as part of an aggregation
452 * {F3364BA0-65B9-11CE-A9BA-00AA004AE837}
454 * FIXME
455 * when pUnkOuter = 0 then rrid = IID_IShellFolder is returned
457 HRESULT IFSFolder_Constructor(
458 IUnknown * pUnkOuter,
459 REFIID riid,
460 LPVOID * ppv)
462 IGenericSFImpl * sf;
463 HRESULT hr = S_OK;
465 TRACE("unkOut=%p riid=%s\n",pUnkOuter, debugstr_guid(riid));
467 if(pUnkOuter && ! IsEqualIID(riid, &IID_IUnknown))
469 hr = CLASS_E_NOAGGREGATION; /* forbidden by definition */
471 else
473 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
474 if (sf)
476 sf->ref=1;
477 ICOM_VTBL(sf)=&unkvt;
478 sf->lpvtblShellFolder=&sfvt;
479 sf->lpvtblPersistFolder2=&psfvt;
480 sf->lpvtblDropTarget=&dtvt;
481 sf->lpvtblSFHelper=&shvt;
483 sf->pclsid = (CLSID*)&CLSID_SFFile;
484 sf->pUnkOuter = pUnkOuter ? pUnkOuter : _IUnknown_(sf);
485 *ppv = _IUnknown_(sf);
486 hr = S_OK;
487 shell32_ObjCount++;
489 else
491 hr = E_OUTOFMEMORY;
494 return hr;
496 /**************************************************************************
497 * IShellFolder_Constructor
499 * NOTES
500 * THIS points to the parent folder
503 IShellFolder * IShellFolder_Constructor(
504 IShellFolder2 * iface,
505 LPITEMIDLIST pidl)
507 IGenericSFImpl * sf;
508 DWORD dwSize=0;
510 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
512 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
513 sf->ref=1;
515 ICOM_VTBL(sf)=&unkvt;
516 sf->lpvtblShellFolder=&sfvt;
517 sf->lpvtblPersistFolder2=&psfvt;
518 sf->lpvtblDropTarget=&dtvt;
519 sf->lpvtblSFHelper=&shvt;
521 sf->pclsid = (CLSID*)&CLSID_SFFile;
522 sf->pUnkOuter = _IUnknown_(sf);
524 TRACE("(%p)->(parent=%p, pidl=%p)\n",sf,This, pidl);
525 pdump(pidl);
527 if(pidl && iface) /* do we have a pidl? */
529 int len;
531 sf->absPidl = ILCombine(This->absPidl, pidl); /* build a absolute pidl */
533 if (!_ILIsSpecialFolder(pidl)) /* only file system paths */
535 if(This->sMyPath) /* get the size of the parents path */
537 dwSize += strlen(This->sMyPath) ;
538 TRACE("-- (%p)->(parent's path=%s)\n",sf, debugstr_a(This->sMyPath));
541 dwSize += _ILSimpleGetText(pidl,NULL,0); /* add the size of our name*/
542 sf->sMyPath = SHAlloc(dwSize + 2); /* '\0' and backslash */
544 if(!sf->sMyPath) return NULL;
545 *(sf->sMyPath)=0x00;
547 if(This->sMyPath) /* if the parent has a path, get it*/
549 strcpy(sf->sMyPath, This->sMyPath);
550 PathAddBackslashA (sf->sMyPath);
553 len = strlen(sf->sMyPath);
554 _ILSimpleGetText(pidl, sf->sMyPath + len, dwSize+2 - len);
557 TRACE("-- (%p)->(my pidl=%p, my path=%s)\n",sf, sf->absPidl,debugstr_a(sf->sMyPath));
559 pdump (sf->absPidl);
562 shell32_ObjCount++;
563 return _IShellFolder_(sf);
566 /**************************************************************************
567 * IShellFolder_fnQueryInterface
569 * PARAMETERS
570 * REFIID riid [in ] Requested InterfaceID
571 * LPVOID* ppvObject [out] Interface* to hold the result
573 static HRESULT WINAPI IShellFolder_fnQueryInterface(
574 IShellFolder2 * iface,
575 REFIID riid,
576 LPVOID *ppvObj)
578 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
580 _CALL_TRACE
581 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
583 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
586 /**************************************************************************
587 * IShellFolder_AddRef
590 static ULONG WINAPI IShellFolder_fnAddRef(IShellFolder2 * iface)
592 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
594 _CALL_TRACE
595 TRACE("(%p)->(count=%lu)\n",This,This->ref);
597 return IUnknown_AddRef(This->pUnkOuter);
600 /**************************************************************************
601 * IShellFolder_fnRelease
603 static ULONG WINAPI IShellFolder_fnRelease(IShellFolder2 * iface)
605 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
607 _CALL_TRACE
608 TRACE("(%p)->(count=%lu)\n",This,This->ref);
610 return IUnknown_Release(This->pUnkOuter);
613 /**************************************************************************
614 * IShellFolder_fnParseDisplayName
615 * PARAMETERS
616 * HWND hwndOwner, //[in ] Parent window for any message's
617 * LPBC pbc, //[in ] reserved
618 * LPOLESTR lpszDisplayName,//[in ] "Unicode" displayname.
619 * ULONG* pchEaten, //[out] (unicode) characters processed
620 * LPITEMIDLIST* ppidl, //[out] complex pidl to item
621 * ULONG* pdwAttributes //[out] items attributes
623 * NOTES
624 * every folder tries to parse only its own (the leftmost) pidl and creates a
625 * subfolder to evaluate the remaining parts
626 * now we can parse into namespaces implemented by shell extensions
628 * behaviour on win98: lpszDisplayName=NULL -> chrash
629 * lpszDisplayName="" -> returns mycoputer-pidl
631 * FIXME:
632 * pdwAttributes: not set
633 * pchEaten: not set like in windows
635 static HRESULT WINAPI IShellFolder_fnParseDisplayName(
636 IShellFolder2 * iface,
637 HWND hwndOwner,
638 LPBC pbcReserved,
639 LPOLESTR lpszDisplayName,
640 DWORD *pchEaten,
641 LPITEMIDLIST *ppidl,
642 DWORD *pdwAttributes)
644 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
646 HRESULT hr = E_OUTOFMEMORY;
647 LPCWSTR szNext=NULL;
648 WCHAR szElement[MAX_PATH];
649 CHAR szTempA[MAX_PATH], szPath[MAX_PATH];
650 LPITEMIDLIST pidlTemp=NULL;
652 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
653 This,hwndOwner,pbcReserved,lpszDisplayName,
654 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
656 if (!lpszDisplayName || !ppidl) return E_INVALIDARG;
658 if (pchEaten) *pchEaten = 0; /* strange but like the original */
660 if (*lpszDisplayName)
662 /* get the next element */
663 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
665 /* build the full pathname to the element */
666 WideCharToMultiByte( CP_ACP, 0, szElement, -1, szTempA, MAX_PATH, NULL, NULL );
667 strcpy(szPath, This->sMyPath);
668 PathAddBackslashA(szPath);
669 strcat(szPath, szTempA);
671 /* get the pidl */
672 pidlTemp = SHSimpleIDListFromPathA(szPath);
674 if (pidlTemp)
676 /* try to analyse the next element */
677 if (szNext && *szNext)
679 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
681 else
683 if (pdwAttributes && *pdwAttributes)
685 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
686 /* WIN32_FIND_DATAA fd;
687 SHGetDataFromIDListA(_IShellFolder_(This), pidlTemp, SHGDFIL_FINDDATA, &fd, sizeof(fd));
688 if (!(FILE_ATTRIBUTE_DIRECTORY & fd.dwFileAttributes))
689 *pdwAttributes &= ~SFGAO_FOLDER;
690 if (FILE_ATTRIBUTE_READONLY & fd.dwFileAttributes)
691 *pdwAttributes &= ~(SFGAO_CANDELETE|SFGAO_CANMOVE|SFGAO_CANRENAME );
694 hr = S_OK;
699 if (!hr)
700 *ppidl = pidlTemp;
701 else
702 *ppidl = NULL;
704 TRACE("(%p)->(-- pidl=%p ret=0x%08lx)\n", This, ppidl? *ppidl:0, hr);
706 return hr;
709 /**************************************************************************
710 * IShellFolder_fnEnumObjects
711 * PARAMETERS
712 * HWND hwndOwner, //[in ] Parent Window
713 * DWORD grfFlags, //[in ] SHCONTF enumeration mask
714 * LPENUMIDLIST* ppenumIDList //[out] IEnumIDList interface
716 static HRESULT WINAPI IShellFolder_fnEnumObjects(
717 IShellFolder2 * iface,
718 HWND hwndOwner,
719 DWORD dwFlags,
720 LPENUMIDLIST* ppEnumIDList)
722 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
724 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
726 *ppEnumIDList = NULL;
727 *ppEnumIDList = IEnumIDList_Constructor (This->sMyPath, dwFlags, EIDL_FILE);
729 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
731 if(!*ppEnumIDList) return E_OUTOFMEMORY;
733 return S_OK;
736 /**************************************************************************
737 * IShellFolder_fnBindToObject
738 * PARAMETERS
739 * LPCITEMIDLIST pidl, //[in ] relative pidl to open
740 * LPBC pbc, //[in ] reserved
741 * REFIID riid, //[in ] Initial Interface
742 * LPVOID* ppvObject //[out] Interface*
744 static HRESULT WINAPI IShellFolder_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
745 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
747 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
748 GUID const * iid;
749 IShellFolder *pShellFolder, *pSubFolder;
750 IPersistFolder *pPersistFolder;
751 LPITEMIDLIST absPidl;
752 HRESULT hr;
754 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
756 if(!pidl || !ppvOut) return E_INVALIDARG;
758 *ppvOut = NULL;
760 if ((iid=_ILGetGUIDPointer(pidl)))
762 /* we have to create a alien folder */
763 if ( SUCCEEDED(SHCoCreateInstance(NULL, iid, NULL, riid, (LPVOID*)&pShellFolder))
764 && SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&pPersistFolder)))
766 absPidl = ILCombine (This->absPidl, pidl);
767 IPersistFolder_Initialize(pPersistFolder, absPidl);
768 IPersistFolder_Release(pPersistFolder);
769 SHFree(absPidl);
771 else
773 return E_FAIL;
776 else
778 LPITEMIDLIST pidltemp = ILCloneFirst(pidl);
779 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
780 ILFree(pidltemp);
783 if (_ILIsPidlSimple(pidl))
785 if(IsEqualIID(riid, &IID_IShellFolder))
787 *ppvOut = pShellFolder;
788 hr = S_OK;
790 else
792 hr = IShellFolder_QueryInterface(pShellFolder, riid, ppvOut);
793 IShellFolder_Release(pShellFolder);
796 else
798 hr = IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL,
799 riid, (LPVOID)&pSubFolder);
800 IShellFolder_Release(pShellFolder);
801 *ppvOut = pSubFolder;
804 TRACE("-- (%p) returning (%p) %08lx\n",This, *ppvOut, hr);
806 return hr;
809 /**************************************************************************
810 * IShellFolder_fnBindToStorage
811 * PARAMETERS
812 * LPCITEMIDLIST pidl, //[in ] complex pidl to store
813 * LPBC pbc, //[in ] reserved
814 * REFIID riid, //[in ] Initial storage interface
815 * LPVOID* ppvObject //[out] Interface* returned
817 static HRESULT WINAPI IShellFolder_fnBindToStorage(
818 IShellFolder2 * iface,
819 LPCITEMIDLIST pidl,
820 LPBC pbcReserved,
821 REFIID riid,
822 LPVOID *ppvOut)
824 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
826 FIXME("(%p)->(pidl=%p,%p,\n\tIID:%s,%p) stub\n",
827 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
829 *ppvOut = NULL;
830 return E_NOTIMPL;
833 /**************************************************************************
834 * IShellFolder_fnCompareIDs
836 * PARMETERS
837 * LPARAM lParam, //[in ] Column?
838 * LPCITEMIDLIST pidl1, //[in ] simple pidl
839 * LPCITEMIDLIST pidl2) //[in ] simple pidl
841 * NOTES
842 * Special case - If one of the items is a Path and the other is a File,
843 * always make the Path come before the File.
845 * NOTES
846 * use SCODE_CODE() on the return value to get the result
849 static HRESULT WINAPI IShellFolder_fnCompareIDs(
850 IShellFolder2 * iface,
851 LPARAM lParam,
852 LPCITEMIDLIST pidl1,
853 LPCITEMIDLIST pidl2)
855 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
857 CHAR szTemp1[MAX_PATH];
858 CHAR szTemp2[MAX_PATH];
859 int nReturn;
860 IShellFolder * psf;
861 HRESULT hr = E_OUTOFMEMORY;
862 LPCITEMIDLIST pidlTemp;
863 PIDLTYPE pt1, pt2;
865 TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n",This,lParam,pidl1,pidl2);
866 pdump (pidl1);
867 pdump (pidl2);
869 if (!pidl1 && !pidl2)
871 hr = ResultFromShort(0);
873 else if (!pidl1)
875 hr = ResultFromShort(-1);
877 else if (!pidl2)
879 hr = ResultFromShort(1);
881 else
883 LPPIDLDATA pd1, pd2;
884 pd1 = _ILGetDataPointer(pidl1);
885 pd2 = _ILGetDataPointer(pidl2);
887 /* compate the types. sort order is the PT_* constant */
888 pt1 = ( pd1 ? pd1->type: PT_DESKTOP);
889 pt2 = ( pd2 ? pd2->type: PT_DESKTOP);
891 if (pt1 != pt2)
893 hr = ResultFromShort(pt1-pt2);
895 else /* same type of pidl */
897 _ILSimpleGetText(pidl1, szTemp1, MAX_PATH);
898 _ILSimpleGetText(pidl2, szTemp2, MAX_PATH);
899 nReturn = strcasecmp(szTemp1, szTemp2);
901 if (nReturn == 0) /* first pidl different ? */
903 pidl1 = ILGetNext(pidl1);
905 if (pidl1 && pidl1->mkid.cb) /* go deeper? */
907 pidlTemp = ILCloneFirst(pidl1);
908 pidl2 = ILGetNext(pidl2);
910 hr = IShellFolder_BindToObject(iface, pidlTemp, NULL, &IID_IShellFolder, (LPVOID*)&psf);
911 if (SUCCEEDED(hr))
913 nReturn = IShellFolder_CompareIDs(psf, 0, pidl1, pidl2);
914 IShellFolder_Release(psf);
915 hr = ResultFromShort(nReturn);
917 ILFree(pidlTemp);
919 else /* no deeper on #1 */
921 pidl2 = ILGetNext(pidl2);
922 if (pidl2 && pidl2->mkid.cb) /* go deeper on #2 ? */
923 hr = ResultFromShort(-1); /* two different */
924 else
925 hr = ResultFromShort(nReturn); /* two equal simple pidls */
928 else
930 hr = ResultFromShort(nReturn); /* two different simple pidls */
935 TRACE("-- res=0x%08lx\n", hr);
936 return hr;
939 /**************************************************************************
940 * IShellFolder_fnCreateViewObject
942 static HRESULT WINAPI IShellFolder_fnCreateViewObject(
943 IShellFolder2 * iface,
944 HWND hwndOwner,
945 REFIID riid,
946 LPVOID *ppvOut)
948 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
950 LPSHELLVIEW pShellView;
951 HRESULT hr = E_INVALIDARG;
953 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
955 if(ppvOut)
957 *ppvOut = NULL;
959 if(IsEqualIID(riid, &IID_IDropTarget))
961 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, ppvOut);
963 else if(IsEqualIID(riid, &IID_IContextMenu))
965 FIXME("IContextMenu not implemented\n");
966 hr = E_NOTIMPL;
968 else if(IsEqualIID(riid, &IID_IShellView))
970 pShellView = IShellView_Constructor((IShellFolder*)iface);
971 if(pShellView)
973 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
974 IShellView_Release(pShellView);
978 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
979 return hr;
982 /**************************************************************************
983 * IShellFolder_fnGetAttributesOf
985 * PARAMETERS
986 * UINT cidl, //[in ] num elements in pidl array
987 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
988 * ULONG* rgfInOut) //[out] result array
991 static HRESULT WINAPI IShellFolder_fnGetAttributesOf(
992 IShellFolder2 * iface,
993 UINT cidl,
994 LPCITEMIDLIST *apidl,
995 DWORD *rgfInOut)
997 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
999 HRESULT hr = S_OK;
1001 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
1003 if ( (!cidl) || (!apidl) || (!rgfInOut))
1004 return E_INVALIDARG;
1006 while (cidl > 0 && *apidl)
1008 pdump (*apidl);
1009 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
1010 apidl++;
1011 cidl--;
1014 TRACE("-- result=0x%08lx\n",*rgfInOut);
1016 return hr;
1018 /**************************************************************************
1019 * IShellFolder_fnGetUIObjectOf
1021 * PARAMETERS
1022 * HWND hwndOwner, //[in ] Parent window for any output
1023 * UINT cidl, //[in ] array size
1024 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
1025 * REFIID riid, //[in ] Requested Interface
1026 * UINT* prgfInOut, //[ ] reserved
1027 * LPVOID* ppvObject) //[out] Resulting Interface
1029 * NOTES
1030 * This function gets asked to return "view objects" for one or more (multiple select)
1031 * items:
1032 * The viewobject typically is an COM object with one of the following interfaces:
1033 * IExtractIcon,IDataObject,IContextMenu
1034 * In order to support icon positions in the default Listview your DataObject
1035 * must implement the SetData method (in addition to GetData :) - the shell passes
1036 * a barely documented "Icon positions" structure to SetData when the drag starts,
1037 * and GetData's it if the drop is in another explorer window that needs the positions.
1039 static HRESULT WINAPI IShellFolder_fnGetUIObjectOf(
1040 IShellFolder2 * iface,
1041 HWND hwndOwner,
1042 UINT cidl,
1043 LPCITEMIDLIST * apidl,
1044 REFIID riid,
1045 UINT * prgfInOut,
1046 LPVOID * ppvOut)
1048 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1050 LPITEMIDLIST pidl;
1051 IUnknown* pObj = NULL;
1052 HRESULT hr = E_INVALIDARG;
1054 TRACE("(%p)->(0x%04x,%u,apidl=%p,\n\tIID:%s,%p,%p)\n",
1055 This,hwndOwner,cidl,apidl,debugstr_guid(riid),prgfInOut,ppvOut);
1057 if (ppvOut)
1059 *ppvOut = NULL;
1061 if(IsEqualIID(riid, &IID_IContextMenu) && (cidl >= 1))
1063 pObj = (LPUNKNOWN)ISvItemCm_Constructor((IShellFolder*)iface, This->absPidl, apidl, cidl);
1064 hr = S_OK;
1066 else if (IsEqualIID(riid, &IID_IDataObject) &&(cidl >= 1))
1068 pObj = (LPUNKNOWN)IDataObject_Constructor (hwndOwner, This->absPidl, apidl, cidl);
1069 hr = S_OK;
1071 else if (IsEqualIID(riid, &IID_IExtractIconA) && (cidl == 1))
1073 pidl = ILCombine(This->absPidl,apidl[0]);
1074 pObj = (LPUNKNOWN)IExtractIconA_Constructor( pidl );
1075 SHFree(pidl);
1076 hr = S_OK;
1078 else if (IsEqualIID(riid, &IID_IDropTarget) && (cidl >= 1))
1080 hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget, (LPVOID*)&pObj);
1082 else
1084 hr = E_NOINTERFACE;
1087 if(!pObj)
1088 hr = E_OUTOFMEMORY;
1090 *ppvOut = pObj;
1092 TRACE("(%p)->hr=0x%08lx\n",This, hr);
1093 return hr;
1096 /**************************************************************************
1097 * IShellFolder_fnGetDisplayNameOf
1098 * Retrieves the display name for the specified file object or subfolder
1100 * PARAMETERS
1101 * LPCITEMIDLIST pidl, //[in ] complex pidl to item
1102 * DWORD dwFlags, //[in ] SHGNO formatting flags
1103 * LPSTRRET lpName) //[out] Returned display name
1105 * FIXME
1106 * if the name is in the pidl the ret value should be a STRRET_OFFSET
1108 #define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
1109 #define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
1111 static HRESULT WINAPI IShellFolder_fnGetDisplayNameOf(
1112 IShellFolder2 * iface,
1113 LPCITEMIDLIST pidl,
1114 DWORD dwFlags,
1115 LPSTRRET strRet)
1117 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1119 CHAR szPath[MAX_PATH]= "";
1120 int len = 0;
1121 BOOL bSimplePidl;
1123 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1124 pdump(pidl);
1126 if(!pidl || !strRet) return E_INVALIDARG;
1128 bSimplePidl = _ILIsPidlSimple(pidl);
1130 /* take names of special folders only if its only this folder */
1131 if (_ILIsSpecialFolder(pidl))
1133 if ( bSimplePidl)
1135 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
1138 else
1140 if (!(dwFlags & SHGDN_INFOLDER) && (dwFlags & SHGDN_FORPARSING) && This->sMyPath)
1142 strcpy (szPath, This->sMyPath); /* get path to root*/
1143 PathAddBackslashA(szPath);
1144 len = strlen(szPath);
1146 _ILSimpleGetText(pidl, szPath + len, MAX_PATH - len); /* append my own path */
1149 if ( (dwFlags & SHGDN_FORPARSING) && !bSimplePidl) /* go deeper if needed */
1151 PathAddBackslashA(szPath);
1152 len = strlen(szPath);
1154 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath + len, MAX_PATH - len)))
1155 return E_OUTOFMEMORY;
1157 strRet->uType = STRRET_CSTRA;
1158 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1160 TRACE("-- (%p)->(%s)\n", This, szPath);
1161 return S_OK;
1164 /**************************************************************************
1165 * IShellFolder_fnSetNameOf
1166 * Changes the name of a file object or subfolder, possibly changing its item
1167 * identifier in the process.
1169 * PARAMETERS
1170 * HWND hwndOwner, //[in ] Owner window for output
1171 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
1172 * LPCOLESTR lpszName, //[in ] the items new display name
1173 * DWORD dwFlags, //[in ] SHGNO formatting flags
1174 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
1176 static HRESULT WINAPI IShellFolder_fnSetNameOf(
1177 IShellFolder2 * iface,
1178 HWND hwndOwner,
1179 LPCITEMIDLIST pidl, /*simple pidl*/
1180 LPCOLESTR lpName,
1181 DWORD dwFlags,
1182 LPITEMIDLIST *pPidlOut)
1184 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1185 char szSrc[MAX_PATH], szDest[MAX_PATH];
1186 int len;
1187 BOOL bIsFolder = _ILIsFolder(ILFindLastID(pidl));
1189 TRACE("(%p)->(%u,pidl=%p,%s,%lu,%p)\n",
1190 This,hwndOwner,pidl,debugstr_w(lpName),dwFlags,pPidlOut);
1192 /* build source path */
1193 if (dwFlags & SHGDN_INFOLDER)
1195 strcpy(szSrc, This->sMyPath);
1196 PathAddBackslashA(szSrc);
1197 len = strlen (szSrc);
1198 _ILSimpleGetText(pidl, szSrc+len, MAX_PATH-len);
1200 else
1202 SHGetPathFromIDListA(pidl, szSrc);
1205 /* build destination path */
1206 strcpy(szDest, This->sMyPath);
1207 PathAddBackslashA(szDest);
1208 len = strlen (szDest);
1209 WideCharToMultiByte( CP_ACP, 0, lpName, -1, szDest+len, MAX_PATH-len, NULL, NULL );
1210 szDest[MAX_PATH-1] = 0;
1211 TRACE("src=%s dest=%s\n", szSrc, szDest);
1212 if ( MoveFileA(szSrc, szDest) )
1214 if (pPidlOut) *pPidlOut = SHSimpleIDListFromPathA(szDest);
1215 SHChangeNotifyA( bIsFolder?SHCNE_RENAMEFOLDER:SHCNE_RENAMEITEM, SHCNF_PATHA, szSrc, szDest);
1216 return S_OK;
1218 return E_FAIL;
1221 static HRESULT WINAPI IShellFolder_fnGetDefaultSearchGUID(
1222 IShellFolder2 * iface,
1223 GUID *pguid)
1225 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1226 FIXME("(%p)\n",This);
1227 return E_NOTIMPL;
1229 static HRESULT WINAPI IShellFolder_fnEnumSearches(
1230 IShellFolder2 * iface,
1231 IEnumExtraSearch **ppenum)
1233 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1234 FIXME("(%p)\n",This);
1235 return E_NOTIMPL;
1237 static HRESULT WINAPI IShellFolder_fnGetDefaultColumn(
1238 IShellFolder2 * iface,
1239 DWORD dwRes,
1240 ULONG *pSort,
1241 ULONG *pDisplay)
1243 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1245 TRACE("(%p)\n",This);
1247 if (pSort) *pSort = 0;
1248 if (pDisplay) *pDisplay = 0;
1250 return S_OK;
1252 static HRESULT WINAPI IShellFolder_fnGetDefaultColumnState(
1253 IShellFolder2 * iface,
1254 UINT iColumn,
1255 DWORD *pcsFlags)
1257 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1259 TRACE("(%p)\n",This);
1261 if (!pcsFlags || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1263 *pcsFlags = GenericSFHeader[iColumn].pcsFlags;
1265 return S_OK;
1267 static HRESULT WINAPI IShellFolder_fnGetDetailsEx(
1268 IShellFolder2 * iface,
1269 LPCITEMIDLIST pidl,
1270 const SHCOLUMNID *pscid,
1271 VARIANT *pv)
1273 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1274 FIXME("(%p)\n",This);
1276 return E_NOTIMPL;
1278 static HRESULT WINAPI IShellFolder_fnGetDetailsOf(
1279 IShellFolder2 * iface,
1280 LPCITEMIDLIST pidl,
1281 UINT iColumn,
1282 SHELLDETAILS *psd)
1284 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1285 HRESULT hr = E_FAIL;
1287 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
1289 if (!psd || iColumn >= GENERICSHELLVIEWCOLUMNS ) return E_INVALIDARG;
1291 if (!pidl)
1293 /* the header titles */
1294 psd->fmt = GenericSFHeader[iColumn].fmt;
1295 psd->cxChar = GenericSFHeader[iColumn].cxChar;
1296 psd->str.uType = STRRET_CSTRA;
1297 LoadStringA(shell32_hInstance, GenericSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
1298 return S_OK;
1300 else
1302 /* the data from the pidl */
1303 switch(iColumn)
1305 case 0: /* name */
1306 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
1307 break;
1308 case 1: /* size */
1309 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
1310 break;
1311 case 2: /* type */
1312 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
1313 break;
1314 case 3: /* date */
1315 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
1316 break;
1317 case 4: /* attributes */
1318 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
1319 break;
1321 hr = S_OK;
1322 psd->str.uType = STRRET_CSTRA;
1325 return hr;
1327 static HRESULT WINAPI IShellFolder_fnMapNameToSCID(
1328 IShellFolder2 * iface,
1329 LPCWSTR pwszName,
1330 SHCOLUMNID *pscid)
1332 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1333 FIXME("(%p)\n",This);
1334 return E_NOTIMPL;
1337 static ICOM_VTABLE(IShellFolder2) sfvt =
1339 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1340 IShellFolder_fnQueryInterface,
1341 IShellFolder_fnAddRef,
1342 IShellFolder_fnRelease,
1343 IShellFolder_fnParseDisplayName,
1344 IShellFolder_fnEnumObjects,
1345 IShellFolder_fnBindToObject,
1346 IShellFolder_fnBindToStorage,
1347 IShellFolder_fnCompareIDs,
1348 IShellFolder_fnCreateViewObject,
1349 IShellFolder_fnGetAttributesOf,
1350 IShellFolder_fnGetUIObjectOf,
1351 IShellFolder_fnGetDisplayNameOf,
1352 IShellFolder_fnSetNameOf,
1354 /* ShellFolder2 */
1355 IShellFolder_fnGetDefaultSearchGUID,
1356 IShellFolder_fnEnumSearches,
1357 IShellFolder_fnGetDefaultColumn,
1358 IShellFolder_fnGetDefaultColumnState,
1359 IShellFolder_fnGetDetailsEx,
1360 IShellFolder_fnGetDetailsOf,
1361 IShellFolder_fnMapNameToSCID
1364 /****************************************************************************
1365 * ISFHelper for IShellFolder implementation
1368 static HRESULT WINAPI ISFHelper_fnQueryInterface(
1369 ISFHelper *iface,
1370 REFIID riid,
1371 LPVOID *ppvObj)
1373 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1375 TRACE("(%p)\n", This);
1377 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
1380 static ULONG WINAPI ISFHelper_fnAddRef(
1381 ISFHelper *iface)
1383 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1385 TRACE("(%p)\n", This);
1387 return IUnknown_AddRef(This->pUnkOuter);
1390 static ULONG WINAPI ISFHelper_fnRelease(
1391 ISFHelper *iface)
1393 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1395 TRACE("(%p)\n", This);
1397 return IUnknown_Release(This->pUnkOuter);
1401 /****************************************************************************
1402 * ISFHelper_fnAddFolder
1404 * creates a unique folder name
1407 static HRESULT WINAPI ISFHelper_fnGetUniqueName(
1408 ISFHelper *iface,
1409 LPSTR lpName,
1410 UINT uLen)
1412 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1413 IEnumIDList * penum;
1414 HRESULT hr;
1415 char szText[MAX_PATH];
1416 char * szNewFolder = "New Folder";
1418 TRACE("(%p)(%s %u)\n", This, lpName, uLen);
1420 if (uLen < strlen(szNewFolder) + 4) return E_POINTER;
1422 strcpy(lpName, szNewFolder);
1424 hr = IShellFolder_fnEnumObjects(_IShellFolder2_(This), 0, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penum);
1425 if (penum)
1427 LPITEMIDLIST pidl;
1428 DWORD dwFetched;
1429 int i=1;
1431 next: IEnumIDList_Reset(penum);
1432 while(S_OK == IEnumIDList_Next(penum, 1, &pidl, &dwFetched) && dwFetched)
1434 _ILSimpleGetText(pidl, szText, MAX_PATH);
1435 if (0 == strcasecmp(szText, lpName))
1437 sprintf(lpName, "%s %d", szNewFolder, i++);
1438 if (i > 99)
1440 hr = E_FAIL;
1441 break;
1443 goto next;
1447 IEnumIDList_Release(penum);
1449 return hr;
1452 /****************************************************************************
1453 * ISFHelper_fnAddFolder
1455 * adds a new folder.
1458 static HRESULT WINAPI ISFHelper_fnAddFolder(
1459 ISFHelper *iface,
1460 HWND hwnd,
1461 LPCSTR lpName,
1462 LPITEMIDLIST* ppidlOut)
1464 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1465 char lpstrNewDir[MAX_PATH];
1466 DWORD bRes;
1467 HRESULT hres = E_FAIL;
1469 TRACE("(%p)(%s %p)\n", This, lpName, ppidlOut);
1471 strcpy(lpstrNewDir, This->sMyPath);
1472 PathAddBackslashA(lpstrNewDir);
1473 strcat(lpstrNewDir, lpName);
1475 bRes = CreateDirectoryA(lpstrNewDir, NULL);
1477 if (bRes)
1479 LPITEMIDLIST pidl, pidlitem;
1481 pidlitem = SHSimpleIDListFromPathA(lpstrNewDir);
1483 pidl = ILCombine(This->absPidl, pidlitem);
1484 SHChangeNotifyA(SHCNE_MKDIR, SHCNF_IDLIST, pidl, NULL);
1485 SHFree(pidl);
1487 if (ppidlOut) *ppidlOut = pidlitem;
1488 hres = S_OK;
1490 else
1492 char lpstrText[128+MAX_PATH];
1493 char lpstrTempText[128];
1494 char lpstrCaption[256];
1496 /* Cannot Create folder because of permissions */
1497 LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_DENIED, lpstrTempText, sizeof(lpstrTempText));
1498 LoadStringA(shell32_hInstance, IDS_CREATEFOLDER_CAPTION, lpstrCaption, sizeof(lpstrCaption));
1499 sprintf(lpstrText,lpstrTempText, lpstrNewDir);
1500 MessageBoxA(hwnd,lpstrText, lpstrCaption, MB_OK | MB_ICONEXCLAMATION);
1503 return hres;
1506 /****************************************************************************
1507 * ISFHelper_fnDeleteItems
1509 * deletes items in folder
1511 static HRESULT WINAPI ISFHelper_fnDeleteItems(
1512 ISFHelper *iface,
1513 UINT cidl,
1514 LPCITEMIDLIST* apidl)
1516 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface)
1517 int i;
1518 char szPath[MAX_PATH];
1519 BOOL bConfirm = TRUE;
1521 TRACE("(%p)(%u %p)\n", This, cidl, apidl);
1523 /* deleting multiple items so give a slightly different warning */
1524 if(cidl != 1)
1526 char tmp[8];
1527 snprintf(tmp, sizeof(tmp), "%d", cidl);
1528 if(!SHELL_WarnItemDelete(ASK_DELETE_MULTIPLE_ITEM, tmp))
1529 return E_FAIL;
1530 bConfirm = FALSE;
1533 for(i=0; i< cidl; i++)
1535 strcpy(szPath, This->sMyPath);
1536 PathAddBackslashA(szPath);
1537 _ILSimpleGetText(apidl[i], szPath+strlen(szPath), MAX_PATH);
1539 if (_ILIsFolder(apidl[i]))
1541 LPITEMIDLIST pidl;
1542 TRACE("delete %s\n", szPath);
1543 if (! SHELL_DeleteDirectoryA(szPath, bConfirm))
1545 TRACE("delete %s failed, bConfirm=%d\n", szPath, bConfirm);
1546 return E_FAIL;
1548 pidl = ILCombine(This->absPidl, apidl[i]);
1549 SHChangeNotifyA(SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);
1550 SHFree(pidl);
1552 else if (_ILIsValue(apidl[i]))
1554 LPITEMIDLIST pidl;
1556 TRACE("delete %s\n", szPath);
1557 if (! SHELL_DeleteFileA(szPath, bConfirm))
1559 TRACE("delete %s failed, bConfirm=%d\n", szPath, bConfirm);
1560 return E_FAIL;
1562 pidl = ILCombine(This->absPidl, apidl[i]);
1563 SHChangeNotifyA(SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);
1564 SHFree(pidl);
1568 return S_OK;
1571 /****************************************************************************
1572 * ISFHelper_fnCopyItems
1574 * copies items to this folder
1576 static HRESULT WINAPI ISFHelper_fnCopyItems(
1577 ISFHelper *iface,
1578 IShellFolder* pSFFrom,
1579 UINT cidl,
1580 LPCITEMIDLIST *apidl)
1582 int i;
1583 IPersistFolder2 * ppf2=NULL;
1584 char szSrcPath[MAX_PATH], szDstPath[MAX_PATH];
1585 _ICOM_THIS_From_ISFHelper(IGenericSFImpl,iface);
1587 TRACE("(%p)->(%p,%u,%p)\n", This, pSFFrom, cidl, apidl);
1589 IShellFolder_QueryInterface(pSFFrom, &IID_IPersistFolder2, (LPVOID*)&ppf2);
1590 if (ppf2)
1592 LPITEMIDLIST pidl;
1593 if (SUCCEEDED(IPersistFolder2_GetCurFolder(ppf2, &pidl)))
1595 for (i=0; i<cidl; i++)
1597 SHGetPathFromIDListA(pidl, szSrcPath);
1598 PathAddBackslashA(szSrcPath);
1599 _ILSimpleGetText(apidl[i], szSrcPath+strlen(szSrcPath), MAX_PATH);
1601 strcpy(szDstPath, This->sMyPath);
1602 PathAddBackslashA(szDstPath);
1603 _ILSimpleGetText(apidl[i], szDstPath+strlen(szDstPath), MAX_PATH);
1604 MESSAGE("would copy %s to %s\n", szSrcPath, szDstPath);
1606 SHFree(pidl);
1608 IPersistFolder2_Release(ppf2);
1610 return S_OK;
1613 static ICOM_VTABLE(ISFHelper) shvt =
1615 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1616 ISFHelper_fnQueryInterface,
1617 ISFHelper_fnAddRef,
1618 ISFHelper_fnRelease,
1619 ISFHelper_fnGetUniqueName,
1620 ISFHelper_fnAddFolder,
1621 ISFHelper_fnDeleteItems,
1622 ISFHelper_fnCopyItems,
1625 /***********************************************************************
1626 * [Desktopfolder] IShellFolder implementation
1628 static struct ICOM_VTABLE(IShellFolder2) sfdvt;
1630 static shvheader DesktopSFHeader [] =
1632 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
1633 { IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1634 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
1635 { IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12 },
1636 { IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5 }
1638 #define DESKTOPSHELLVIEWCOLUMNS 5
1640 /**************************************************************************
1641 * ISF_Desktop_Constructor
1644 IShellFolder * ISF_Desktop_Constructor()
1646 IGenericSFImpl * sf;
1648 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
1649 sf->ref=1;
1650 ICOM_VTBL(sf)=&unkvt;
1651 sf->lpvtblShellFolder=&sfdvt;
1652 sf->absPidl=_ILCreateDesktop(); /* my qualified pidl */
1653 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
1655 TRACE("(%p)\n",sf);
1657 shell32_ObjCount++;
1658 return _IShellFolder_(sf);
1661 /**************************************************************************
1662 * ISF_Desktop_fnQueryInterface
1664 * NOTES supports not IPersist/IPersistFolder
1666 static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
1667 IShellFolder2 * iface,
1668 REFIID riid,
1669 LPVOID *ppvObj)
1671 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1673 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1675 *ppvObj = NULL;
1677 if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
1679 *ppvObj = _IUnknown_(This);
1681 else if(IsEqualIID(riid, &IID_IShellFolder)) /*IShellFolder*/
1683 *ppvObj = _IShellFolder_(This);
1685 else if(IsEqualIID(riid, &IID_IShellFolder2)) /*IShellFolder2*/
1687 *ppvObj = _IShellFolder_(This);
1690 if(*ppvObj)
1692 IUnknown_AddRef((IUnknown*)(*ppvObj));
1693 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1694 return S_OK;
1696 TRACE("-- Interface: E_NOINTERFACE\n");
1697 return E_NOINTERFACE;
1700 /**************************************************************************
1701 * ISF_Desktop_fnParseDisplayName
1703 * NOTES
1704 * "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
1705 * to MyComputer
1707 static HRESULT WINAPI ISF_Desktop_fnParseDisplayName(
1708 IShellFolder2 * iface,
1709 HWND hwndOwner,
1710 LPBC pbcReserved,
1711 LPOLESTR lpszDisplayName,
1712 DWORD *pchEaten,
1713 LPITEMIDLIST *ppidl,
1714 DWORD *pdwAttributes)
1716 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1718 LPCWSTR szNext=NULL;
1719 LPITEMIDLIST pidlTemp=NULL;
1720 HRESULT hr=E_OUTOFMEMORY;
1722 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
1723 This,hwndOwner,pbcReserved,lpszDisplayName,
1724 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
1726 *ppidl = 0;
1727 if (pchEaten) *pchEaten = 0; /* strange but like the original */
1729 /* FIXME no real parsing implemented */
1730 pidlTemp = _ILCreateMyComputer();
1731 szNext = lpszDisplayName;
1733 if (szNext && *szNext)
1735 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
1737 else
1739 hr = S_OK;
1741 if (pdwAttributes && *pdwAttributes)
1743 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
1747 *ppidl = pidlTemp;
1749 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
1751 return hr;
1754 /**************************************************************************
1755 * ISF_Desktop_fnEnumObjects
1757 static HRESULT WINAPI ISF_Desktop_fnEnumObjects(
1758 IShellFolder2 * iface,
1759 HWND hwndOwner,
1760 DWORD dwFlags,
1761 LPENUMIDLIST* ppEnumIDList)
1763 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1765 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
1767 *ppEnumIDList = NULL;
1768 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_DESK);
1770 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
1772 if(!*ppEnumIDList) return E_OUTOFMEMORY;
1774 return S_OK;
1777 /**************************************************************************
1778 * ISF_Desktop_fnBindToObject
1780 static HRESULT WINAPI ISF_Desktop_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
1781 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
1783 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1784 GUID const * clsid;
1785 IShellFolder *pShellFolder, *pSubFolder;
1786 HRESULT hr;
1788 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
1789 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
1791 *ppvOut = NULL;
1793 if ((clsid=_ILGetGUIDPointer(pidl)))
1795 if ( IsEqualIID(clsid, &CLSID_MyComputer))
1797 pShellFolder = ISF_MyComputer_Constructor();
1799 else
1801 /* shell extension */
1802 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
1804 return E_INVALIDARG;
1808 else
1810 /* file system folder on the desktop */
1811 LPITEMIDLIST deskpidl, firstpidl, completepidl;
1812 IPersistFolder * ppf;
1814 /* combine pidls */
1815 SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, &deskpidl);
1816 firstpidl = ILCloneFirst(pidl);
1817 completepidl = ILCombine(deskpidl, firstpidl);
1819 pShellFolder = IShellFolder_Constructor(NULL, NULL);
1820 if (SUCCEEDED(IShellFolder_QueryInterface(pShellFolder, &IID_IPersistFolder, (LPVOID*)&ppf)))
1822 IPersistFolder_Initialize(ppf, completepidl);
1823 IPersistFolder_Release(ppf);
1825 ILFree(completepidl);
1826 ILFree(deskpidl);
1827 ILFree(firstpidl);
1830 if (_ILIsPidlSimple(pidl)) /* no sub folders */
1832 *ppvOut = pShellFolder;
1833 hr = S_OK;
1835 else /* go deeper */
1837 hr = IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL, riid, (LPVOID)&pSubFolder);
1838 IShellFolder_Release(pShellFolder);
1839 *ppvOut = pSubFolder;
1842 TRACE("-- (%p) returning (%p) %08lx\n",This, *ppvOut, hr);
1844 return hr;
1847 /**************************************************************************
1848 * ISF_Desktop_fnCreateViewObject
1850 static HRESULT WINAPI ISF_Desktop_fnCreateViewObject( IShellFolder2 * iface,
1851 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
1853 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1855 LPSHELLVIEW pShellView;
1856 HRESULT hr = E_INVALIDARG;
1858 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
1860 if(ppvOut)
1862 *ppvOut = NULL;
1864 if(IsEqualIID(riid, &IID_IDropTarget))
1866 WARN("IDropTarget not implemented\n");
1867 hr = E_NOTIMPL;
1869 else if(IsEqualIID(riid, &IID_IContextMenu))
1871 WARN("IContextMenu not implemented\n");
1872 hr = E_NOTIMPL;
1874 else if(IsEqualIID(riid, &IID_IShellView))
1876 pShellView = IShellView_Constructor((IShellFolder*)iface);
1877 if(pShellView)
1879 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
1880 IShellView_Release(pShellView);
1884 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
1885 return hr;
1888 /**************************************************************************
1889 * ISF_Desktop_fnGetAttributesOf
1891 static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf(
1892 IShellFolder2 * iface,
1893 UINT cidl,
1894 LPCITEMIDLIST *apidl,
1895 DWORD *rgfInOut)
1897 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1899 HRESULT hr = S_OK;
1901 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl, *rgfInOut);
1903 if ( (!cidl) || (!apidl) || (!rgfInOut))
1904 return E_INVALIDARG;
1906 while (cidl > 0 && *apidl)
1908 pdump (*apidl);
1909 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
1910 apidl++;
1911 cidl--;
1914 TRACE("-- result=0x%08lx\n",*rgfInOut);
1916 return hr;
1919 /**************************************************************************
1920 * ISF_Desktop_fnGetDisplayNameOf
1922 * NOTES
1923 * special case: pidl = null gives desktop-name back
1925 static HRESULT WINAPI ISF_Desktop_fnGetDisplayNameOf(
1926 IShellFolder2 * iface,
1927 LPCITEMIDLIST pidl,
1928 DWORD dwFlags,
1929 LPSTRRET strRet)
1931 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1933 CHAR szPath[MAX_PATH]= "";
1935 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
1936 pdump(pidl);
1938 if(!strRet) return E_INVALIDARG;
1940 if(!pidl)
1942 HCR_GetClassName(&CLSID_ShellDesktop, szPath, MAX_PATH);
1944 else if ( _ILIsPidlSimple(pidl) )
1946 _ILSimpleGetText(pidl, szPath, MAX_PATH);
1948 else
1950 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, szPath, MAX_PATH)))
1951 return E_OUTOFMEMORY;
1953 strRet->uType = STRRET_CSTRA;
1954 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
1957 TRACE("-- (%p)->(%s)\n", This, szPath);
1958 return S_OK;
1961 static HRESULT WINAPI ISF_Desktop_fnGetDefaultSearchGUID(
1962 IShellFolder2 * iface,
1963 GUID *pguid)
1965 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1966 FIXME("(%p)\n",This);
1967 return E_NOTIMPL;
1969 static HRESULT WINAPI ISF_Desktop_fnEnumSearches(
1970 IShellFolder2 * iface,
1971 IEnumExtraSearch **ppenum)
1973 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1974 FIXME("(%p)\n",This);
1975 return E_NOTIMPL;
1977 static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumn(
1978 IShellFolder2 * iface,
1979 DWORD dwRes,
1980 ULONG *pSort,
1981 ULONG *pDisplay)
1983 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1985 TRACE("(%p)\n",This);
1987 if (pSort) *pSort = 0;
1988 if (pDisplay) *pDisplay = 0;
1990 return S_OK;
1992 static HRESULT WINAPI ISF_Desktop_fnGetDefaultColumnState(
1993 IShellFolder2 * iface,
1994 UINT iColumn,
1995 DWORD *pcsFlags)
1997 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
1999 TRACE("(%p)\n",This);
2001 if (!pcsFlags || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2003 *pcsFlags = DesktopSFHeader[iColumn].pcsFlags;
2005 return S_OK;
2007 static HRESULT WINAPI ISF_Desktop_fnGetDetailsEx(
2008 IShellFolder2 * iface,
2009 LPCITEMIDLIST pidl,
2010 const SHCOLUMNID *pscid,
2011 VARIANT *pv)
2013 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2014 FIXME("(%p)\n",This);
2016 return E_NOTIMPL;
2018 static HRESULT WINAPI ISF_Desktop_fnGetDetailsOf(
2019 IShellFolder2 * iface,
2020 LPCITEMIDLIST pidl,
2021 UINT iColumn,
2022 SHELLDETAILS *psd)
2024 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2025 HRESULT hr = E_FAIL;;
2027 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
2029 if (!psd || iColumn >= DESKTOPSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2031 if (!pidl)
2033 psd->fmt = DesktopSFHeader[iColumn].fmt;
2034 psd->cxChar = DesktopSFHeader[iColumn].cxChar;
2035 psd->str.uType = STRRET_CSTRA;
2036 LoadStringA(shell32_hInstance, DesktopSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
2037 return S_OK;
2039 else
2041 /* the data from the pidl */
2042 switch(iColumn)
2044 case 0: /* name */
2045 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2046 break;
2047 case 1: /* size */
2048 _ILGetFileSize (pidl, psd->str.u.cStr, MAX_PATH);
2049 break;
2050 case 2: /* type */
2051 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2052 break;
2053 case 3: /* date */
2054 _ILGetFileDate(pidl, psd->str.u.cStr, MAX_PATH);
2055 break;
2056 case 4: /* attributes */
2057 _ILGetFileAttributes(pidl, psd->str.u.cStr, MAX_PATH);
2058 break;
2060 hr = S_OK;
2061 psd->str.uType = STRRET_CSTRA;
2064 return hr;
2066 static HRESULT WINAPI ISF_Desktop_fnMapNameToSCID(
2067 IShellFolder2 * iface,
2068 LPCWSTR pwszName,
2069 SHCOLUMNID *pscid)
2071 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2072 FIXME("(%p)\n",This);
2073 return E_NOTIMPL;
2076 static ICOM_VTABLE(IShellFolder2) sfdvt =
2078 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2079 ISF_Desktop_fnQueryInterface,
2080 IShellFolder_fnAddRef,
2081 IShellFolder_fnRelease,
2082 ISF_Desktop_fnParseDisplayName,
2083 ISF_Desktop_fnEnumObjects,
2084 ISF_Desktop_fnBindToObject,
2085 IShellFolder_fnBindToStorage,
2086 IShellFolder_fnCompareIDs,
2087 ISF_Desktop_fnCreateViewObject,
2088 ISF_Desktop_fnGetAttributesOf,
2089 IShellFolder_fnGetUIObjectOf,
2090 ISF_Desktop_fnGetDisplayNameOf,
2091 IShellFolder_fnSetNameOf,
2093 /* ShellFolder2 */
2094 ISF_Desktop_fnGetDefaultSearchGUID,
2095 ISF_Desktop_fnEnumSearches,
2096 ISF_Desktop_fnGetDefaultColumn,
2097 ISF_Desktop_fnGetDefaultColumnState,
2098 ISF_Desktop_fnGetDetailsEx,
2099 ISF_Desktop_fnGetDetailsOf,
2100 ISF_Desktop_fnMapNameToSCID
2104 /***********************************************************************
2105 * IShellFolder [MyComputer] implementation
2108 static struct ICOM_VTABLE(IShellFolder2) sfmcvt;
2110 static shvheader MyComputerSFHeader [] =
2112 { IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15 },
2113 { IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2114 { IDS_SHV_COLUMN6, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2115 { IDS_SHV_COLUMN7, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10 },
2117 #define MYCOMPUTERSHELLVIEWCOLUMNS 4
2119 /**************************************************************************
2120 * ISF_MyComputer_Constructor
2122 static IShellFolder * ISF_MyComputer_Constructor(void)
2124 IGenericSFImpl * sf;
2126 sf=(IGenericSFImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IGenericSFImpl));
2127 sf->ref=1;
2129 ICOM_VTBL(sf)=&unkvt;
2130 sf->lpvtblShellFolder=&sfmcvt;
2131 sf->lpvtblPersistFolder2 = &psfvt;
2132 sf->pclsid = (CLSID*)&CLSID_SFMyComp;
2133 sf->absPidl=_ILCreateMyComputer(); /* my qualified pidl */
2134 sf->pUnkOuter = (IUnknown *) &sf->lpVtbl;
2136 TRACE("(%p)\n",sf);
2138 shell32_ObjCount++;
2139 return _IShellFolder_(sf);
2142 /**************************************************************************
2143 * ISF_MyComputer_fnParseDisplayName
2145 static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName(
2146 IShellFolder2 * iface,
2147 HWND hwndOwner,
2148 LPBC pbcReserved,
2149 LPOLESTR lpszDisplayName,
2150 DWORD *pchEaten,
2151 LPITEMIDLIST *ppidl,
2152 DWORD *pdwAttributes)
2154 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2156 HRESULT hr = E_OUTOFMEMORY;
2157 LPCWSTR szNext=NULL;
2158 WCHAR szElement[MAX_PATH];
2159 CHAR szTempA[MAX_PATH];
2160 LPITEMIDLIST pidlTemp;
2162 TRACE("(%p)->(HWND=0x%08x,%p,%p=%s,%p,pidl=%p,%p)\n",
2163 This,hwndOwner,pbcReserved,lpszDisplayName,
2164 debugstr_w(lpszDisplayName),pchEaten,ppidl,pdwAttributes);
2166 *ppidl = 0;
2167 if (pchEaten) *pchEaten = 0; /* strange but like the original */
2169 /* do we have an absolute path name ? */
2170 if (PathGetDriveNumberW(lpszDisplayName) >= 0 &&
2171 lpszDisplayName[2] == (WCHAR)'\\')
2173 szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH);
2174 WideCharToMultiByte( CP_ACP, 0, szElement, -1, szTempA, MAX_PATH, NULL, NULL );
2175 pidlTemp = _ILCreateDrive(szTempA);
2177 if (szNext && *szNext)
2179 hr = SHELL32_ParseNextElement(hwndOwner, iface, &pidlTemp, (LPOLESTR)szNext, pchEaten, pdwAttributes);
2181 else
2183 if (pdwAttributes && *pdwAttributes)
2185 SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes);
2187 hr = S_OK;
2189 *ppidl = pidlTemp;
2192 TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr);
2194 return hr;
2197 /**************************************************************************
2198 * ISF_MyComputer_fnEnumObjects
2200 static HRESULT WINAPI ISF_MyComputer_fnEnumObjects(
2201 IShellFolder2 * iface,
2202 HWND hwndOwner,
2203 DWORD dwFlags,
2204 LPENUMIDLIST* ppEnumIDList)
2206 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2208 TRACE("(%p)->(HWND=0x%08x flags=0x%08lx pplist=%p)\n",This,hwndOwner,dwFlags,ppEnumIDList);
2210 *ppEnumIDList = NULL;
2211 *ppEnumIDList = IEnumIDList_Constructor (NULL, dwFlags, EIDL_MYCOMP);
2213 TRACE("-- (%p)->(new ID List: %p)\n",This,*ppEnumIDList);
2215 if(!*ppEnumIDList) return E_OUTOFMEMORY;
2217 return S_OK;
2220 /**************************************************************************
2221 * ISF_MyComputer_fnBindToObject
2223 static HRESULT WINAPI ISF_MyComputer_fnBindToObject( IShellFolder2 * iface, LPCITEMIDLIST pidl,
2224 LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
2226 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2227 GUID const * clsid;
2228 IShellFolder *pShellFolder, *pSubFolder;
2229 LPITEMIDLIST pidltemp;
2230 HRESULT hr;
2232 TRACE("(%p)->(pidl=%p,%p,\n\tIID:\t%s,%p)\n",
2233 This,pidl,pbcReserved,debugstr_guid(riid),ppvOut);
2235 if(!pidl || !ppvOut) return E_INVALIDARG;
2237 *ppvOut = NULL;
2239 if ((clsid=_ILGetGUIDPointer(pidl)) && !IsEqualIID(clsid, &CLSID_MyComputer))
2241 if (!SUCCEEDED(SHELL32_CoCreateInitSF (This->absPidl, pidl, clsid, riid, (LPVOID*)&pShellFolder)))
2243 return E_FAIL;
2246 else
2248 if (!_ILIsDrive(pidl)) return E_INVALIDARG;
2250 pidltemp = ILCloneFirst(pidl);
2251 pShellFolder = IShellFolder_Constructor(iface, pidltemp);
2252 ILFree(pidltemp);
2255 if (_ILIsPidlSimple(pidl)) /* no sub folders */
2257 *ppvOut = pShellFolder;
2258 hr = S_OK;
2260 else /* go deeper */
2262 hr = IShellFolder_BindToObject(pShellFolder, ILGetNext(pidl), NULL,
2263 riid, (LPVOID)&pSubFolder);
2264 IShellFolder_Release(pShellFolder);
2265 *ppvOut = pSubFolder;
2268 TRACE("-- (%p) returning (%p) %08lx\n",This, *ppvOut, hr);
2270 return hr;
2273 /**************************************************************************
2274 * ISF_MyComputer_fnCreateViewObject
2276 static HRESULT WINAPI ISF_MyComputer_fnCreateViewObject( IShellFolder2 * iface,
2277 HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
2279 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2281 LPSHELLVIEW pShellView;
2282 HRESULT hr = E_INVALIDARG;
2284 TRACE("(%p)->(hwnd=0x%x,\n\tIID:\t%s,%p)\n",This,hwndOwner,debugstr_guid(riid),ppvOut);
2286 if(ppvOut)
2288 *ppvOut = NULL;
2290 if(IsEqualIID(riid, &IID_IDropTarget))
2292 WARN("IDropTarget not implemented\n");
2293 hr = E_NOTIMPL;
2295 else if(IsEqualIID(riid, &IID_IContextMenu))
2297 WARN("IContextMenu not implemented\n");
2298 hr = E_NOTIMPL;
2300 else if(IsEqualIID(riid, &IID_IShellView))
2302 pShellView = IShellView_Constructor((IShellFolder*)iface);
2303 if(pShellView)
2305 hr = IShellView_QueryInterface(pShellView, riid, ppvOut);
2306 IShellView_Release(pShellView);
2310 TRACE("-- (%p)->(interface=%p)\n",This, ppvOut);
2311 return hr;
2314 /**************************************************************************
2315 * ISF_MyComputer_fnGetAttributesOf
2317 static HRESULT WINAPI ISF_MyComputer_fnGetAttributesOf(
2318 IShellFolder2 * iface,
2319 UINT cidl,
2320 LPCITEMIDLIST *apidl,
2321 DWORD *rgfInOut)
2323 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2325 HRESULT hr = S_OK;
2327 TRACE("(%p)->(cidl=%d apidl=%p mask=0x%08lx)\n",This,cidl,apidl,*rgfInOut);
2329 if ( (!cidl) || (!apidl) || (!rgfInOut))
2330 return E_INVALIDARG;
2332 while (cidl > 0 && *apidl)
2334 pdump (*apidl);
2335 SHELL32_GetItemAttributes(_IShellFolder_(This), *apidl, rgfInOut);
2336 apidl++;
2337 cidl--;
2340 TRACE("-- result=0x%08lx\n",*rgfInOut);
2341 return hr;
2344 /**************************************************************************
2345 * ISF_MyComputer_fnGetDisplayNameOf
2347 * NOTES
2348 * The desktopfolder creates only complete paths (SHGDN_FORPARSING).
2349 * SHGDN_INFOLDER makes no sense.
2351 static HRESULT WINAPI ISF_MyComputer_fnGetDisplayNameOf(
2352 IShellFolder2 * iface,
2353 LPCITEMIDLIST pidl,
2354 DWORD dwFlags,
2355 LPSTRRET strRet)
2357 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2359 char szPath[MAX_PATH], szDrive[18];
2360 int len = 0;
2361 BOOL bSimplePidl;
2363 TRACE("(%p)->(pidl=%p,0x%08lx,%p)\n",This,pidl,dwFlags,strRet);
2364 pdump(pidl);
2366 if(!strRet) return E_INVALIDARG;
2368 szPath[0]=0x00; szDrive[0]=0x00;
2371 bSimplePidl = _ILIsPidlSimple(pidl);
2373 if (_ILIsSpecialFolder(pidl))
2375 /* take names of special folders only if its only this folder */
2376 if ( bSimplePidl )
2378 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2381 else
2383 if (!_ILIsDrive(pidl))
2385 ERR("Wrong pidl type\n");
2386 return E_INVALIDARG;
2389 _ILSimpleGetText(pidl, szPath, MAX_PATH); /* append my own path */
2391 /* long view "lw_name (C:)" */
2392 if ( bSimplePidl && !(dwFlags & SHGDN_FORPARSING))
2394 DWORD dwVolumeSerialNumber,dwMaximumComponetLength,dwFileSystemFlags;
2396 GetVolumeInformationA(szPath,szDrive,12,&dwVolumeSerialNumber,&dwMaximumComponetLength,&dwFileSystemFlags,NULL,0);
2397 strcat (szDrive," (");
2398 strncat (szDrive, szPath, 2);
2399 strcat (szDrive,")");
2400 strcpy (szPath, szDrive);
2404 if (!bSimplePidl) /* go deeper if needed */
2406 PathAddBackslashA(szPath);
2407 len = strlen(szPath);
2409 if (!SUCCEEDED(SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags | SHGDN_FORPARSING, szPath + len, MAX_PATH - len)))
2410 return E_OUTOFMEMORY;
2412 strRet->uType = STRRET_CSTRA;
2413 lstrcpynA(strRet->u.cStr, szPath, MAX_PATH);
2416 TRACE("-- (%p)->(%s)\n", This, szPath);
2417 return S_OK;
2420 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultSearchGUID(
2421 IShellFolder2 * iface,
2422 GUID *pguid)
2424 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2425 FIXME("(%p)\n",This);
2426 return E_NOTIMPL;
2428 static HRESULT WINAPI ISF_MyComputer_fnEnumSearches(
2429 IShellFolder2 * iface,
2430 IEnumExtraSearch **ppenum)
2432 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2433 FIXME("(%p)\n",This);
2434 return E_NOTIMPL;
2436 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumn(
2437 IShellFolder2 * iface,
2438 DWORD dwRes,
2439 ULONG *pSort,
2440 ULONG *pDisplay)
2442 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2444 TRACE("(%p)\n",This);
2446 if (pSort) *pSort = 0;
2447 if (pDisplay) *pDisplay = 0;
2449 return S_OK;
2451 static HRESULT WINAPI ISF_MyComputer_fnGetDefaultColumnState(
2452 IShellFolder2 * iface,
2453 UINT iColumn,
2454 DWORD *pcsFlags)
2456 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2458 TRACE("(%p)\n",This);
2460 if (!pcsFlags || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2462 *pcsFlags = MyComputerSFHeader[iColumn].pcsFlags;
2464 return S_OK;
2466 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsEx(
2467 IShellFolder2 * iface,
2468 LPCITEMIDLIST pidl,
2469 const SHCOLUMNID *pscid,
2470 VARIANT *pv)
2472 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2473 FIXME("(%p)\n",This);
2475 return E_NOTIMPL;
2478 /* FIXME: drive size >4GB is rolling over */
2479 static HRESULT WINAPI ISF_MyComputer_fnGetDetailsOf(
2480 IShellFolder2 * iface,
2481 LPCITEMIDLIST pidl,
2482 UINT iColumn,
2483 SHELLDETAILS *psd)
2485 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2486 HRESULT hr;
2488 TRACE("(%p)->(%p %i %p)\n",This, pidl, iColumn, psd);
2490 if (!psd || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS ) return E_INVALIDARG;
2492 if (!pidl)
2494 psd->fmt = MyComputerSFHeader[iColumn].fmt;
2495 psd->cxChar = MyComputerSFHeader[iColumn].cxChar;
2496 psd->str.uType = STRRET_CSTRA;
2497 LoadStringA(shell32_hInstance, MyComputerSFHeader[iColumn].colnameid, psd->str.u.cStr, MAX_PATH);
2498 return S_OK;
2500 else
2502 char szPath[MAX_PATH];
2503 ULARGE_INTEGER ulBytes;
2505 psd->str.u.cStr[0] = 0x00;
2506 psd->str.uType = STRRET_CSTRA;
2507 switch(iColumn)
2509 case 0: /* name */
2510 hr = IShellFolder_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
2511 break;
2512 case 1: /* type */
2513 _ILGetFileType(pidl, psd->str.u.cStr, MAX_PATH);
2514 break;
2515 case 2: /* total size */
2516 if (_ILIsDrive(pidl))
2518 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2519 GetDiskFreeSpaceExA(szPath, NULL, &ulBytes, NULL);
2520 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2522 break;
2523 case 3: /* free size */
2524 if (_ILIsDrive(pidl))
2526 _ILSimpleGetText(pidl, szPath, MAX_PATH);
2527 GetDiskFreeSpaceExA(szPath, &ulBytes, NULL, NULL);
2528 StrFormatByteSizeA(ulBytes.s.LowPart, psd->str.u.cStr, MAX_PATH);
2530 break;
2532 hr = S_OK;
2535 return hr;
2537 static HRESULT WINAPI ISF_MyComputer_fnMapNameToSCID(
2538 IShellFolder2 * iface,
2539 LPCWSTR pwszName,
2540 SHCOLUMNID *pscid)
2542 _ICOM_THIS_From_IShellFolder2(IGenericSFImpl, iface)
2543 FIXME("(%p)\n",This);
2544 return E_NOTIMPL;
2547 static ICOM_VTABLE(IShellFolder2) sfmcvt =
2549 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2550 IShellFolder_fnQueryInterface,
2551 IShellFolder_fnAddRef,
2552 IShellFolder_fnRelease,
2553 ISF_MyComputer_fnParseDisplayName,
2554 ISF_MyComputer_fnEnumObjects,
2555 ISF_MyComputer_fnBindToObject,
2556 IShellFolder_fnBindToStorage,
2557 IShellFolder_fnCompareIDs,
2558 ISF_MyComputer_fnCreateViewObject,
2559 ISF_MyComputer_fnGetAttributesOf,
2560 IShellFolder_fnGetUIObjectOf,
2561 ISF_MyComputer_fnGetDisplayNameOf,
2562 IShellFolder_fnSetNameOf,
2564 /* ShellFolder2 */
2565 ISF_MyComputer_fnGetDefaultSearchGUID,
2566 ISF_MyComputer_fnEnumSearches,
2567 ISF_MyComputer_fnGetDefaultColumn,
2568 ISF_MyComputer_fnGetDefaultColumnState,
2569 ISF_MyComputer_fnGetDetailsEx,
2570 ISF_MyComputer_fnGetDetailsOf,
2571 ISF_MyComputer_fnMapNameToSCID
2575 /************************************************************************
2576 * ISFPersistFolder_QueryInterface (IUnknown)
2579 static HRESULT WINAPI ISFPersistFolder2_QueryInterface(
2580 IPersistFolder2 * iface,
2581 REFIID iid,
2582 LPVOID* ppvObj)
2584 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2586 TRACE("(%p)\n", This);
2588 return IUnknown_QueryInterface(This->pUnkOuter, iid, ppvObj);
2591 /************************************************************************
2592 * ISFPersistFolder_AddRef (IUnknown)
2595 static ULONG WINAPI ISFPersistFolder2_AddRef(
2596 IPersistFolder2 * iface)
2598 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2600 TRACE("(%p)\n", This);
2602 return IUnknown_AddRef(This->pUnkOuter);
2605 /************************************************************************
2606 * ISFPersistFolder_Release (IUnknown)
2609 static ULONG WINAPI ISFPersistFolder2_Release(
2610 IPersistFolder2 * iface)
2612 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2614 TRACE("(%p)\n", This);
2616 return IUnknown_Release(This->pUnkOuter);
2619 /************************************************************************
2620 * ISFPersistFolder_GetClassID (IPersist)
2622 static HRESULT WINAPI ISFPersistFolder2_GetClassID(
2623 IPersistFolder2 * iface,
2624 CLSID * lpClassId)
2626 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2628 TRACE("(%p)\n", This);
2630 if (!lpClassId) return E_POINTER;
2631 *lpClassId = *This->pclsid;
2633 return S_OK;
2636 /************************************************************************
2637 * ISFPersistFolder_Initialize (IPersistFolder)
2639 * NOTES
2640 * sMyPath is not set. Don't know how to handle in a non rooted environment.
2642 static HRESULT WINAPI ISFPersistFolder2_Initialize(
2643 IPersistFolder2 * iface,
2644 LPCITEMIDLIST pidl)
2646 char sTemp[MAX_PATH];
2647 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2649 TRACE("(%p)->(%p)\n", This, pidl);
2651 /* free the old stuff */
2652 if(This->absPidl)
2654 SHFree(This->absPidl);
2655 This->absPidl = NULL;
2657 if(This->sMyPath)
2659 SHFree(This->sMyPath);
2660 This->sMyPath = NULL;
2663 /* set my pidl */
2664 This->absPidl = ILClone(pidl);
2666 /* set my path */
2667 if (SHGetPathFromIDListA(pidl, sTemp))
2669 This->sMyPath = SHAlloc(strlen(sTemp)+1);
2670 strcpy(This->sMyPath, sTemp);
2673 TRACE("--(%p)->(%s)\n", This, This->sMyPath);
2675 return S_OK;
2678 /**************************************************************************
2679 * IPersistFolder2_fnGetCurFolder
2681 static HRESULT WINAPI ISFPersistFolder2_fnGetCurFolder(
2682 IPersistFolder2 * iface,
2683 LPITEMIDLIST * pidl)
2685 _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface);
2687 TRACE("(%p)->(%p)\n",This, pidl);
2689 if (!pidl) return E_POINTER;
2691 *pidl = ILClone(This->absPidl);
2693 return S_OK;
2696 static ICOM_VTABLE(IPersistFolder2) psfvt =
2698 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2699 ISFPersistFolder2_QueryInterface,
2700 ISFPersistFolder2_AddRef,
2701 ISFPersistFolder2_Release,
2702 ISFPersistFolder2_GetClassID,
2703 ISFPersistFolder2_Initialize,
2704 ISFPersistFolder2_fnGetCurFolder
2707 /****************************************************************************
2708 * ISFDropTarget implementation
2710 static BOOL ISFDropTarget_QueryDrop(
2711 IDropTarget *iface,
2712 DWORD dwKeyState,
2713 LPDWORD pdwEffect)
2715 DWORD dwEffect = *pdwEffect;
2717 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2719 *pdwEffect = DROPEFFECT_NONE;
2721 if (This->fAcceptFmt)
2722 { /* Does our interpretation of the keystate ... */
2723 *pdwEffect = KeyStateToDropEffect(dwKeyState);
2725 /* ... matches the desired effect ? */
2726 if (dwEffect & *pdwEffect)
2728 return TRUE;
2731 return FALSE;
2734 static HRESULT WINAPI ISFDropTarget_QueryInterface(
2735 IDropTarget *iface,
2736 REFIID riid,
2737 LPVOID *ppvObj)
2739 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2741 TRACE("(%p)\n", This);
2743 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObj);
2746 static ULONG WINAPI ISFDropTarget_AddRef( IDropTarget *iface)
2748 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2750 TRACE("(%p)\n", This);
2752 return IUnknown_AddRef(This->pUnkOuter);
2755 static ULONG WINAPI ISFDropTarget_Release( IDropTarget *iface)
2757 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2759 TRACE("(%p)\n", This);
2761 return IUnknown_Release(This->pUnkOuter);
2764 static HRESULT WINAPI ISFDropTarget_DragEnter(
2765 IDropTarget *iface,
2766 IDataObject *pDataObject,
2767 DWORD dwKeyState,
2768 POINTL pt,
2769 DWORD *pdwEffect)
2771 FORMATETC fmt;
2773 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2775 TRACE("(%p)->(DataObject=%p)\n",This,pDataObject);
2777 InitFormatEtc(fmt, This->cfShellIDList, TYMED_HGLOBAL);
2779 This->fAcceptFmt = (S_OK == IDataObject_QueryGetData(pDataObject, &fmt)) ? TRUE : FALSE;
2781 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2783 return S_OK;
2786 static HRESULT WINAPI ISFDropTarget_DragOver(
2787 IDropTarget *iface,
2788 DWORD dwKeyState,
2789 POINTL pt,
2790 DWORD *pdwEffect)
2792 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2794 TRACE("(%p)\n",This);
2796 if(!pdwEffect) return E_INVALIDARG;
2798 ISFDropTarget_QueryDrop(iface, dwKeyState, pdwEffect);
2800 return S_OK;
2803 static HRESULT WINAPI ISFDropTarget_DragLeave(
2804 IDropTarget *iface)
2806 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2808 TRACE("(%p)\n",This);
2810 This->fAcceptFmt = FALSE;
2812 return S_OK;
2815 static HRESULT WINAPI ISFDropTarget_Drop(
2816 IDropTarget *iface,
2817 IDataObject* pDataObject,
2818 DWORD dwKeyState,
2819 POINTL pt,
2820 DWORD *pdwEffect)
2822 _ICOM_THIS_From_IDropTarget(IGenericSFImpl,iface);
2824 FIXME("(%p) object dropped\n",This);
2826 return E_NOTIMPL;
2829 static struct ICOM_VTABLE(IDropTarget) dtvt =
2831 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2832 ISFDropTarget_QueryInterface,
2833 ISFDropTarget_AddRef,
2834 ISFDropTarget_Release,
2835 ISFDropTarget_DragEnter,
2836 ISFDropTarget_DragOver,
2837 ISFDropTarget_DragLeave,
2838 ISFDropTarget_Drop