2 * Virtual Desktop Folder
4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998, 1999, 2002 Juergen Schmied
6 * Copyright 2009 Andrew Hill
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
28 CDesktopFolder should create two file system folders internally, one representing the
29 user's desktop folder, and the other representing the common desktop folder. It should
30 also create a CRegFolder to represent the virtual items that exist only in the registry.
31 The CRegFolder is aggregated by the CDesktopFolder, and queries for the CLSID_IShellFolder,
32 CLSID_IShellFolder2, or CLSID_IShellIconOverlay interfaces prefer the CRegFolder
34 The CDesktopFolderEnum class should create two enumerators, one for each of the file
35 system folders, and enumerate the contents of each folder. Since the CRegFolder
36 implementation of IShellFolder::EnumObjects enumerates the virtual items, the
37 CDesktopFolderEnum is only responsible for returning the physical items.
38 CDesktopFolderEnum is incorrect where it filters My Computer from the enumeration
39 if the new start menu is used. The CDesktopViewCallback is responsible for filtering
40 it from the view by handling the IncludeObject query to return S_FALSE. The enumerator
41 always shows My Computer.
44 /* Undocumented functions from shdocvw */
45 extern "C" HRESULT WINAPI
IEParseDisplayNameWithBCW(DWORD codepage
, LPCWSTR lpszDisplayName
, LPBC pbc
, LPITEMIDLIST
*ppidl
);
47 /***********************************************************************
48 * Desktopfolder implementation
53 class CDesktopFolderEnum
:
54 public CEnumIDListBase
57 // CComPtr fDesktopEnumerator;
58 // CComPtr fCommonDesktopEnumerator;
61 ~CDesktopFolderEnum();
62 HRESULT WINAPI
Initialize(CDesktopFolder
*desktopFolder
, HWND hwndOwner
, DWORD dwFlags
);
64 BEGIN_COM_MAP(CDesktopFolderEnum
)
65 COM_INTERFACE_ENTRY_IID(IID_IEnumIDList
, IEnumIDList
)
69 int SHELL_ConfirmMsgBox(HWND hWnd
, LPWSTR lpszText
, LPWSTR lpszCaption
, HICON hIcon
, BOOL bYesToAll
);
71 static const shvheader DesktopSFHeader
[] = {
72 {IDS_SHV_COLUMN1
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 15},
73 {IDS_SHV_COLUMN2
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10},
74 {IDS_SHV_COLUMN3
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 10},
75 {IDS_SHV_COLUMN4
, SHCOLSTATE_TYPE_DATE
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 12},
76 {IDS_SHV_COLUMN5
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 5}
79 #define DESKTOPSHELLVIEWCOLUMNS 5
81 CDesktopFolderEnum::CDesktopFolderEnum()
85 CDesktopFolderEnum::~CDesktopFolderEnum()
89 static const WCHAR ClassicStartMenuW
[] = L
"SOFTWARE\\Microsoft\\Windows\\"
90 L
"CurrentVersion\\Explorer\\HideDesktopIcons\\ClassicStartMenu";
93 IsNamespaceExtensionHidden(const WCHAR
*iid
)
95 DWORD Result
, dwResult
;
96 dwResult
= sizeof(DWORD
);
98 if (RegGetValueW(HKEY_CURRENT_USER
, /* FIXME use NewStartPanel when activated */
104 &dwResult
) != ERROR_SUCCESS
)
113 SetNamespaceExtensionVisibleStatus(const WCHAR
* iid
, DWORD dwStatus
)
117 if (RegOpenKeyExW(HKEY_CURRENT_USER
, ClassicStartMenuW
, 0, KEY_WRITE
, &hKey
) == ERROR_SUCCESS
)
119 RegSetValueExW(hKey
, iid
, 0, REG_DWORD
, (LPBYTE
)&dwStatus
, sizeof(DWORD
));
124 /**************************************************************************
125 * CreateDesktopEnumList()
128 HRESULT WINAPI
CDesktopFolderEnum::Initialize(CDesktopFolder
*desktopFolder
, HWND hwndOwner
, DWORD dwFlags
)
131 WCHAR szPath
[MAX_PATH
];
133 static const WCHAR MyDocumentsClassString
[] = L
"{450D8FBA-AD25-11D0-98A8-0800361B1103}";
134 static const WCHAR Desktop_NameSpaceW
[] = L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Desktop\\Namespace";
136 TRACE("(%p)->(flags=0x%08x)\n", this, dwFlags
);
138 /* enumerate the root folders */
139 if (dwFlags
& SHCONTF_FOLDERS
)
145 /* create the pidl for This item */
146 if (IsNamespaceExtensionHidden(MyDocumentsClassString
) < 1)
148 ret
= AddToEnumList(_ILCreateMyDocuments());
150 ret
= AddToEnumList(_ILCreateMyComputer());
152 for (i
= 0; i
< 2; i
++)
155 dwResult
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, Desktop_NameSpaceW
, 0, KEY_READ
, &hkey
);
157 dwResult
= RegOpenKeyExW(HKEY_CURRENT_USER
, Desktop_NameSpaceW
, 0, KEY_READ
, &hkey
);
159 if (dwResult
== ERROR_SUCCESS
)
170 size
= sizeof (iid
) / sizeof (iid
[0]);
171 r
= RegEnumKeyExW(hkey
, i
, iid
, &size
, 0, NULL
, NULL
, NULL
);
172 if (ERROR_SUCCESS
== r
)
174 if (IsNamespaceExtensionHidden(iid
) < 1)
176 pidl
= _ILCreateGuidFromStrW(iid
);
179 if (!HasItemWithCLSID(pidl
))
181 ret
= AddToEnumList(pidl
);
190 else if (ERROR_NO_MORE_ITEMS
== r
)
199 for (i
= 0; i
< 2; i
++)
202 dwResult
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, ClassicStartMenuW
, 0, KEY_READ
, &hkey
);
204 dwResult
= RegOpenKeyExW(HKEY_CURRENT_USER
, ClassicStartMenuW
, 0, KEY_READ
, &hkey
);
206 if (dwResult
== ERROR_SUCCESS
)
208 DWORD j
= 0, dwVal
, Val
, dwType
, dwIID
;
215 dwIID
= sizeof(iid
) / sizeof(WCHAR
);
217 r
= RegEnumValueW(hkey
, j
++, iid
, &dwIID
, NULL
, &dwType
, (LPBYTE
)&Val
, &dwVal
);
218 if (r
== ERROR_SUCCESS
)
220 if (Val
== 0 && dwType
== REG_DWORD
)
222 LPITEMIDLIST pidl
= _ILCreateGuidFromStrW(iid
);
225 if (!HasItemWithCLSID(pidl
))
236 else if (ERROR_NO_MORE_ITEMS
== r
)
247 /* enumerate the elements in %windir%\desktop */
248 ret
= ret
&& SHGetSpecialFolderPathW(0, szPath
, CSIDL_DESKTOPDIRECTORY
, FALSE
);
249 ret
= ret
&& CreateFolderEnumList(szPath
, dwFlags
);
251 ret
= ret
&& SHGetSpecialFolderPathW(0, szPath
, CSIDL_COMMON_DESKTOPDIRECTORY
, FALSE
);
252 ret
= ret
&& CreateFolderEnumList(szPath
, dwFlags
);
254 return ret
? S_OK
: E_FAIL
;
257 void CDesktopFolder::SF_RegisterClipFmt()
259 TRACE ("(%p)\n", this);
262 cfShellIDList
= RegisterClipboardFormatW(CFSTR_SHELLIDLIST
);
265 CDesktopFolder::CDesktopFolder()
270 SF_RegisterClipFmt();
274 CDesktopFolder::~CDesktopFolder()
278 HRESULT WINAPI
CDesktopFolder::FinalConstruct()
280 WCHAR szMyPath
[MAX_PATH
];
282 if (!SHGetSpecialFolderPathW( 0, szMyPath
, CSIDL_DESKTOPDIRECTORY
, TRUE
))
285 pidlRoot
= _ILCreateDesktop(); /* my qualified pidl */
286 sPathTarget
= (LPWSTR
)SHAlloc((wcslen(szMyPath
) + 1) * sizeof(WCHAR
));
287 wcscpy(sPathTarget
, szMyPath
);
291 /**************************************************************************
292 * CDesktopFolder::ParseDisplayName
295 * "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
298 HRESULT WINAPI
CDesktopFolder::ParseDisplayName(
301 LPOLESTR lpszDisplayName
,
303 PIDLIST_RELATIVE
*ppidl
,
304 DWORD
*pdwAttributes
)
306 WCHAR szElement
[MAX_PATH
];
307 LPCWSTR szNext
= NULL
;
308 LPITEMIDLIST pidlTemp
= NULL
;
313 TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
314 this, hwndOwner
, pbc
, lpszDisplayName
, debugstr_w(lpszDisplayName
),
315 pchEaten
, ppidl
, pdwAttributes
);
320 if (!lpszDisplayName
)
329 *pchEaten
= 0; /* strange but like the original */
331 urldata
.cbSize
= sizeof(urldata
);
333 if (lpszDisplayName
[0] == ':' && lpszDisplayName
[1] == ':')
335 szNext
= GetNextElementW (lpszDisplayName
, szElement
, MAX_PATH
);
336 TRACE ("-- element: %s\n", debugstr_w (szElement
));
337 CLSIDFromString (szElement
+ 2, &clsid
);
338 pidlTemp
= _ILCreateGuid (PT_GUID
, clsid
);
340 else if (PathGetDriveNumberW (lpszDisplayName
) >= 0)
342 /* it's a filesystem path with a drive. Let MyComputer/UnixDosFolder parse it */
343 pidlTemp
= _ILCreateMyComputer ();
344 szNext
= lpszDisplayName
;
346 else if (PathIsUNCW(lpszDisplayName
))
348 pidlTemp
= _ILCreateNetwork();
349 szNext
= lpszDisplayName
;
351 else if( (pidlTemp
= SHELL32_CreatePidlFromBindCtx(pbc
, lpszDisplayName
)) )
356 else if (SUCCEEDED(ParseURLW(lpszDisplayName
, &urldata
)))
358 if (urldata
.nScheme
== URL_SCHEME_SHELL
) /* handle shell: urls */
360 TRACE ("-- shell url: %s\n", debugstr_w(urldata
.pszSuffix
));
361 SHCLSIDFromStringW (urldata
.pszSuffix
+ 2, &clsid
);
362 pidlTemp
= _ILCreateGuid (PT_GUID
, clsid
);
365 return IEParseDisplayNameWithBCW(CP_ACP
, lpszDisplayName
, pbc
, ppidl
);
369 /* it's a filesystem path on the desktop. Let a FSFolder parse it */
371 if (*lpszDisplayName
)
373 WCHAR szPath
[MAX_PATH
];
376 /* build a complete path to create a simple pidl */
377 lstrcpynW(szPath
, sPathTarget
, MAX_PATH
);
378 pathPtr
= PathAddBackslashW(szPath
);
381 lstrcpynW(pathPtr
, lpszDisplayName
, MAX_PATH
- (pathPtr
- szPath
));
382 hr
= _ILCreateFromPathW(szPath
, &pidlTemp
);
386 /* should never reach here, but for completeness */
387 hr
= HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
);
391 pidlTemp
= _ILCreateMyComputer();
396 if (SUCCEEDED(hr
) && pidlTemp
)
398 if (szNext
&& *szNext
)
400 hr
= SHELL32_ParseNextElement(this, hwndOwner
, pbc
,
401 &pidlTemp
, (LPOLESTR
) szNext
, pchEaten
, pdwAttributes
);
405 if (pdwAttributes
&& *pdwAttributes
)
406 hr
= SHELL32_GetItemAttributes((IShellFolder
*)this,
407 pidlTemp
, pdwAttributes
);
416 TRACE ("(%p)->(-- ret=0x%08x)\n", this, hr
);
421 /**************************************************************************
422 * CDesktopFolder::EnumObjects
424 HRESULT WINAPI
CDesktopFolder::EnumObjects(HWND hwndOwner
, DWORD dwFlags
, LPENUMIDLIST
*ppEnumIDList
)
426 return ShellObjectCreatorInit
<CDesktopFolderEnum
>(this, hwndOwner
, dwFlags
, IID_IEnumIDList
, ppEnumIDList
);
429 /**************************************************************************
430 * CDesktopFolder::BindToObject
432 HRESULT WINAPI
CDesktopFolder::BindToObject(
433 PCUIDLIST_RELATIVE pidl
,
438 TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n",
439 this, pidl
, pbcReserved
, shdebugstr_guid (&riid
), ppvOut
);
441 return SHELL32_BindToChild( pidlRoot
, sPathTarget
, pidl
, riid
, ppvOut
);
444 /**************************************************************************
445 * CDesktopFolder::BindToStorage
447 HRESULT WINAPI
CDesktopFolder::BindToStorage(
448 PCUIDLIST_RELATIVE pidl
,
453 FIXME ("(%p)->(pidl=%p,%p,%s,%p) stub\n",
454 this, pidl
, pbcReserved
, shdebugstr_guid (&riid
), ppvOut
);
460 /**************************************************************************
461 * CDesktopFolder::CompareIDs
463 HRESULT WINAPI
CDesktopFolder::CompareIDs(LPARAM lParam
, PCUIDLIST_RELATIVE pidl1
, PCUIDLIST_RELATIVE pidl2
)
467 TRACE ("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", this, lParam
, pidl1
, pidl2
);
468 nReturn
= SHELL32_CompareIDs ((IShellFolder
*)this, lParam
, pidl1
, pidl2
);
469 TRACE ("-- %i\n", nReturn
);
473 /**************************************************************************
474 * CDesktopFolder::CreateViewObject
476 HRESULT WINAPI
CDesktopFolder::CreateViewObject(
481 CComPtr
<IShellView
> pShellView
;
482 HRESULT hr
= E_INVALIDARG
;
484 TRACE ("(%p)->(hwnd=%p,%s,%p)\n",
485 this, hwndOwner
, shdebugstr_guid (&riid
), ppvOut
);
492 if (IsEqualIID (riid
, IID_IDropTarget
))
494 hr
= this->QueryInterface (IID_IDropTarget
, ppvOut
);
496 else if (IsEqualIID (riid
, IID_IContextMenu
))
498 WARN ("IContextMenu not implemented\n");
501 else if (IsEqualIID (riid
, IID_IShellView
))
503 hr
= IShellView_Constructor((IShellFolder
*)this, &pShellView
);
505 hr
= pShellView
->QueryInterface(riid
, ppvOut
);
507 TRACE ("-- (%p)->(interface=%p)\n", this, ppvOut
);
511 /**************************************************************************
512 * CDesktopFolder::GetAttributesOf
514 HRESULT WINAPI
CDesktopFolder::GetAttributesOf(
516 PCUITEMID_CHILD_ARRAY apidl
,
520 static const DWORD dwDesktopAttributes
=
521 SFGAO_HASSUBFOLDER
| SFGAO_FILESYSTEM
| SFGAO_FOLDER
| SFGAO_FILESYSANCESTOR
|
522 SFGAO_STORAGEANCESTOR
| SFGAO_HASPROPSHEET
| SFGAO_STORAGE
| SFGAO_CANLINK
;
523 static const DWORD dwMyComputerAttributes
=
524 SFGAO_CANRENAME
| SFGAO_CANDELETE
| SFGAO_HASPROPSHEET
| SFGAO_DROPTARGET
|
525 SFGAO_FILESYSANCESTOR
| SFGAO_FOLDER
| SFGAO_HASSUBFOLDER
| SFGAO_CANLINK
;
526 static DWORD dwMyNetPlacesAttributes
=
527 SFGAO_CANRENAME
| SFGAO_CANDELETE
| SFGAO_HASPROPSHEET
| SFGAO_DROPTARGET
|
528 SFGAO_FILESYSANCESTOR
| SFGAO_FOLDER
| SFGAO_HASSUBFOLDER
| SFGAO_CANLINK
;
530 TRACE("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
531 this, cidl
, apidl
, rgfInOut
, rgfInOut
? *rgfInOut
: 0);
540 *rgfInOut
&= dwDesktopAttributes
;
543 /* TODO: always add SFGAO_CANLINK */
544 for (UINT i
= 0; i
< cidl
; ++i
)
547 if (_ILIsDesktop(*apidl
))
548 *rgfInOut
&= dwDesktopAttributes
;
549 else if (_ILIsMyComputer(apidl
[i
]))
550 *rgfInOut
&= dwMyComputerAttributes
;
551 else if (_ILIsNetHood(apidl
[i
]))
552 *rgfInOut
&= dwMyNetPlacesAttributes
;
553 else if (_ILIsSpecialFolder(apidl
[i
]))
554 SHELL32_GetItemAttributes(this, apidl
[i
], rgfInOut
);
555 else if(_ILIsFolder(apidl
[i
]) || _ILIsValue(apidl
[i
]))
556 SHELL32_GetItemAttributes(this, apidl
[i
], rgfInOut
);
558 ERR("Got an unknown pidl type!!!\n");
561 /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
562 *rgfInOut
&= ~SFGAO_VALIDATE
;
564 TRACE("-- result=0x%08x\n", *rgfInOut
);
569 /**************************************************************************
570 * CDesktopFolder::GetUIObjectOf
573 * HWND hwndOwner, //[in ] Parent window for any output
574 * UINT cidl, //[in ] array size
575 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
576 * REFIID riid, //[in ] Requested Interface
577 * UINT* prgfInOut, //[ ] reserved
578 * LPVOID* ppvObject) //[out] Resulting Interface
581 HRESULT WINAPI
CDesktopFolder::GetUIObjectOf(
584 PCUITEMID_CHILD_ARRAY apidl
,
590 IUnknown
*pObj
= NULL
;
591 HRESULT hr
= E_INVALIDARG
;
593 TRACE ("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n",
594 this, hwndOwner
, cidl
, apidl
, shdebugstr_guid (&riid
), prgfInOut
, ppvOut
);
601 if (IsEqualIID (riid
, IID_IContextMenu
))
603 hr
= CDefFolderMenu_Create2(pidlRoot
, hwndOwner
, cidl
, apidl
, (IShellFolder
*)this, NULL
, 0, NULL
, (IContextMenu
**)&pObj
);
605 else if (IsEqualIID (riid
, IID_IDataObject
) && (cidl
>= 1))
607 hr
= IDataObject_Constructor( hwndOwner
, pidlRoot
, apidl
, cidl
, (IDataObject
**)&pObj
);
609 else if (IsEqualIID (riid
, IID_IExtractIconA
) && (cidl
== 1))
611 pidl
= ILCombine (pidlRoot
, apidl
[0]);
612 pObj
= IExtractIconA_Constructor (pidl
);
616 else if (IsEqualIID (riid
, IID_IExtractIconW
) && (cidl
== 1))
618 pidl
= ILCombine (pidlRoot
, apidl
[0]);
619 pObj
= IExtractIconW_Constructor (pidl
);
623 else if (IsEqualIID (riid
, IID_IDropTarget
))
625 /* only interested in attempting to bind to shell folders, not files, semicolon intentionate */
626 if (cidl
!= 1 || FAILED(hr
= this->_GetDropTarget(apidl
[0], (LPVOID
*) &pObj
)))
628 IDropTarget
* pDt
= NULL
;
629 hr
= this->QueryInterface(IID_PPV_ARG(IDropTarget
, &pDt
));
633 else if ((IsEqualIID(riid
, IID_IShellLinkW
) ||
634 IsEqualIID(riid
, IID_IShellLinkA
)) && (cidl
== 1))
636 pidl
= ILCombine (pidlRoot
, apidl
[0]);
637 hr
= IShellLink_ConstructFromFile(NULL
, riid
, pidl
, (LPVOID
*)&pObj
);
643 if (SUCCEEDED(hr
) && !pObj
)
647 TRACE ("(%p)->hr=0x%08x\n", this, hr
);
651 /**************************************************************************
652 * CDesktopFolder::GetDisplayNameOf
655 * special case: pidl = null gives desktop-name back
657 HRESULT WINAPI
CDesktopFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl
, DWORD dwFlags
, LPSTRRET strRet
)
662 TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl
, dwFlags
, strRet
);
668 pszPath
= (LPWSTR
)CoTaskMemAlloc((MAX_PATH
+ 1) * sizeof(WCHAR
));
670 return E_OUTOFMEMORY
;
672 if (_ILIsDesktop (pidl
))
674 if ((GET_SHGDN_RELATION (dwFlags
) == SHGDN_NORMAL
) &&
675 (GET_SHGDN_FOR (dwFlags
) & SHGDN_FORPARSING
))
676 wcscpy(pszPath
, sPathTarget
);
678 HCR_GetClassNameW(CLSID_ShellDesktop
, pszPath
, MAX_PATH
);
680 else if (_ILIsPidlSimple (pidl
))
684 if ((clsid
= _ILGetGUIDPointer (pidl
)))
686 if (GET_SHGDN_FOR (dwFlags
) == SHGDN_FORPARSING
)
688 int bWantsForParsing
;
691 * We can only get a filesystem path from a shellfolder if the
692 * value WantsFORPARSING in CLSID\\{...}\\shellfolder exists.
694 * Exception: The MyComputer folder doesn't have this key,
695 * but any other filesystem backed folder it needs it.
697 if (IsEqualIID (*clsid
, CLSID_MyComputer
))
699 bWantsForParsing
= TRUE
;
703 /* get the "WantsFORPARSING" flag from the registry */
704 static const WCHAR clsidW
[] =
705 { 'C', 'L', 'S', 'I', 'D', '\\', 0 };
706 static const WCHAR shellfolderW
[] =
707 { '\\', 's', 'h', 'e', 'l', 'l', 'f', 'o', 'l', 'd', 'e', 'r', 0 };
708 static const WCHAR wantsForParsingW
[] =
709 { 'W', 'a', 'n', 't', 's', 'F', 'o', 'r', 'P', 'a', 'r', 's', 'i', 'n',
712 WCHAR szRegPath
[100];
715 wcscpy (szRegPath
, clsidW
);
716 SHELL32_GUIDToStringW (*clsid
, &szRegPath
[6]);
717 wcscat (szRegPath
, shellfolderW
);
718 r
= SHGetValueW(HKEY_CLASSES_ROOT
, szRegPath
,
719 wantsForParsingW
, NULL
, NULL
, NULL
);
720 if (r
== ERROR_SUCCESS
)
721 bWantsForParsing
= TRUE
;
723 bWantsForParsing
= FALSE
;
726 if ((GET_SHGDN_RELATION (dwFlags
) == SHGDN_NORMAL
) &&
730 * we need the filesystem path to the destination folder.
731 * Only the folder itself can know it
733 hr
= SHELL32_GetDisplayNameOfChild (this, pidl
, dwFlags
,
739 /* parsing name like ::{...} */
742 SHELL32_GUIDToStringW (*clsid
, &pszPath
[2]);
747 /* user friendly name */
748 HCR_GetClassNameW (*clsid
, pszPath
, MAX_PATH
);
755 /* file system folder or file rooted at the desktop */
756 if ((GET_SHGDN_FOR(dwFlags
) == SHGDN_FORPARSING
) &&
757 (GET_SHGDN_RELATION(dwFlags
) != SHGDN_INFOLDER
))
759 lstrcpynW(pszPath
, sPathTarget
, MAX_PATH
- 1);
760 PathAddBackslashW(pszPath
);
761 cLen
= wcslen(pszPath
);
764 _ILSimpleGetTextW(pidl
, pszPath
+ cLen
, MAX_PATH
- cLen
);
765 if (!_ILIsFolder(pidl
))
766 SHELL_FS_ProcessDisplayFilename(pszPath
, dwFlags
);
768 if (GetFileAttributes(pszPath
) == INVALID_FILE_ATTRIBUTES
)
770 /* file system folder or file rooted at the AllUsers desktop */
771 if ((GET_SHGDN_FOR(dwFlags
) == SHGDN_FORPARSING
) &&
772 (GET_SHGDN_RELATION(dwFlags
) != SHGDN_INFOLDER
))
774 SHGetSpecialFolderPathW(0, pszPath
, CSIDL_COMMON_DESKTOPDIRECTORY
, FALSE
);
775 PathAddBackslashW(pszPath
);
776 cLen
= wcslen(pszPath
);
779 _ILSimpleGetTextW(pidl
, pszPath
+ cLen
, MAX_PATH
- cLen
);
780 if (!_ILIsFolder(pidl
))
781 SHELL_FS_ProcessDisplayFilename(pszPath
, dwFlags
);
787 /* a complex pidl, let the subfolder do the work */
788 hr
= SHELL32_GetDisplayNameOfChild (this, pidl
, dwFlags
,
794 /* Win9x always returns ANSI strings, NT always returns Unicode strings */
795 if (GetVersion() & 0x80000000)
797 strRet
->uType
= STRRET_CSTR
;
798 if (!WideCharToMultiByte(CP_ACP
, 0, pszPath
, -1, strRet
->cStr
, MAX_PATH
,
800 strRet
->cStr
[0] = '\0';
801 CoTaskMemFree(pszPath
);
805 strRet
->uType
= STRRET_WSTR
;
806 strRet
->pOleStr
= pszPath
;
810 CoTaskMemFree(pszPath
);
812 TRACE ("-- (%p)->(%s,0x%08x)\n", this,
813 strRet
->uType
== STRRET_CSTR
? strRet
->cStr
:
814 debugstr_w(strRet
->pOleStr
), hr
);
818 /**************************************************************************
819 * CDesktopFolder::SetNameOf
820 * Changes the name of a file object or subfolder, possibly changing its item
821 * identifier in the process.
824 * HWND hwndOwner, //[in ] Owner window for output
825 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
826 * LPCOLESTR lpszName, //[in ] the items new display name
827 * DWORD dwFlags, //[in ] SHGNO formatting flags
828 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
830 HRESULT WINAPI
CDesktopFolder::SetNameOf(
832 PCUITEMID_CHILD pidl
, /* simple pidl */
835 PITEMID_CHILD
*pPidlOut
)
837 CComPtr
<IShellFolder2
> psf
;
839 WCHAR szSrc
[MAX_PATH
+ 1], szDest
[MAX_PATH
+ 1];
841 BOOL bIsFolder
= _ILIsFolder (ILFindLastID (pidl
));
843 TRACE ("(%p)->(%p,pidl=%p,%s,%u,%p)\n", this, hwndOwner
, pidl
,
844 debugstr_w (lpName
), dwFlags
, pPidlOut
);
846 if (_ILGetGUIDPointer(pidl
))
848 if (SUCCEEDED(BindToObject(pidl
, NULL
, IID_PPV_ARG(IShellFolder2
, &psf
))))
850 hr
= psf
->SetNameOf(hwndOwner
, pidl
, lpName
, dwFlags
, pPidlOut
);
855 /* build source path */
856 lstrcpynW(szSrc
, sPathTarget
, MAX_PATH
);
857 ptr
= PathAddBackslashW (szSrc
);
859 _ILSimpleGetTextW (pidl
, ptr
, MAX_PATH
+ 1 - (ptr
- szSrc
));
861 /* build destination path */
862 if (dwFlags
== SHGDN_NORMAL
|| dwFlags
& SHGDN_INFOLDER
) {
863 lstrcpynW(szDest
, sPathTarget
, MAX_PATH
);
864 ptr
= PathAddBackslashW (szDest
);
866 lstrcpynW(ptr
, lpName
, MAX_PATH
+ 1 - (ptr
- szDest
));
868 lstrcpynW(szDest
, lpName
, MAX_PATH
);
870 if(!(dwFlags
& SHGDN_FORPARSING
) && SHELL_FS_HideExtension(szSrc
)) {
871 WCHAR
*ext
= PathFindExtensionW(szSrc
);
873 INT len
= wcslen(szDest
);
874 lstrcpynW(szDest
+ len
, ext
, MAX_PATH
- len
);
878 if (!memcmp(szSrc
, szDest
, (wcslen(szDest
) + 1) * sizeof(WCHAR
)))
880 /* src and destination is the same */
883 hr
= _ILCreateFromPathW(szDest
, pPidlOut
);
888 TRACE ("src=%s dest=%s\n", debugstr_w(szSrc
), debugstr_w(szDest
));
889 if (MoveFileW (szSrc
, szDest
))
894 hr
= _ILCreateFromPathW(szDest
, pPidlOut
);
896 SHChangeNotify (bIsFolder
? SHCNE_RENAMEFOLDER
: SHCNE_RENAMEITEM
,
897 SHCNF_PATHW
, szSrc
, szDest
);
904 HRESULT WINAPI
CDesktopFolder::GetDefaultSearchGUID(GUID
*pguid
)
906 FIXME ("(%p)\n", this);
910 HRESULT WINAPI
CDesktopFolder::EnumSearches(IEnumExtraSearch
**ppenum
)
912 FIXME ("(%p)\n", this);
916 HRESULT WINAPI
CDesktopFolder::GetDefaultColumn(DWORD dwRes
, ULONG
*pSort
, ULONG
*pDisplay
)
918 TRACE ("(%p)\n", this);
928 HRESULT WINAPI
CDesktopFolder::GetDefaultColumnState(UINT iColumn
, DWORD
*pcsFlags
)
930 TRACE ("(%p)\n", this);
932 if (!pcsFlags
|| iColumn
>= DESKTOPSHELLVIEWCOLUMNS
)
935 *pcsFlags
= DesktopSFHeader
[iColumn
].pcsFlags
;
940 HRESULT WINAPI
CDesktopFolder::GetDetailsEx(
941 PCUITEMID_CHILD pidl
,
942 const SHCOLUMNID
*pscid
,
945 FIXME ("(%p)\n", this);
950 HRESULT WINAPI
CDesktopFolder::GetDetailsOf(
951 PCUITEMID_CHILD pidl
,
957 TRACE ("(%p)->(%p %i %p)\n", this, pidl
, iColumn
, psd
);
959 if (!psd
|| iColumn
>= DESKTOPSHELLVIEWCOLUMNS
)
964 psd
->fmt
= DesktopSFHeader
[iColumn
].fmt
;
965 psd
->cxChar
= DesktopSFHeader
[iColumn
].cxChar
;
966 psd
->str
.uType
= STRRET_CSTR
;
967 LoadStringA (shell32_hInstance
, DesktopSFHeader
[iColumn
].colnameid
,
968 psd
->str
.cStr
, MAX_PATH
);
972 /* the data from the pidl */
973 psd
->str
.uType
= STRRET_CSTR
;
977 hr
= GetDisplayNameOf(pidl
,
978 SHGDN_NORMAL
| SHGDN_INFOLDER
, &psd
->str
);
981 _ILGetFileSize (pidl
, psd
->str
.cStr
, MAX_PATH
);
984 _ILGetFileType (pidl
, psd
->str
.cStr
, MAX_PATH
);
987 _ILGetFileDate (pidl
, psd
->str
.cStr
, MAX_PATH
);
989 case 4: /* attributes */
990 _ILGetFileAttributes (pidl
, psd
->str
.cStr
, MAX_PATH
);
997 HRESULT WINAPI
CDesktopFolder::MapColumnToSCID(UINT column
, SHCOLUMNID
*pscid
)
999 FIXME ("(%p)\n", this);
1003 HRESULT WINAPI
CDesktopFolder::GetClassID(CLSID
*lpClassId
)
1005 TRACE ("(%p)\n", this);
1010 *lpClassId
= CLSID_ShellDesktop
;
1015 HRESULT WINAPI
CDesktopFolder::Initialize(LPCITEMIDLIST pidl
)
1017 TRACE ("(%p)->(%p)\n", this, pidl
);
1022 HRESULT WINAPI
CDesktopFolder::GetCurFolder(LPITEMIDLIST
* pidl
)
1024 TRACE ("(%p)->(%p)\n", this, pidl
);
1026 if (!pidl
) return E_POINTER
;
1027 *pidl
= ILClone (pidlRoot
);
1031 HRESULT WINAPI
CDesktopFolder::GetUniqueName(LPWSTR pwszName
, UINT uLen
)
1033 CComPtr
<IEnumIDList
> penum
;
1035 WCHAR wszText
[MAX_PATH
];
1036 WCHAR wszNewFolder
[25];
1037 const WCHAR wszFormat
[] = {'%', 's', ' ', '%', 'd', 0 };
1039 LoadStringW(shell32_hInstance
, IDS_NEWFOLDER
, wszNewFolder
, sizeof(wszNewFolder
) / sizeof(WCHAR
));
1041 TRACE ("(%p)(%p %u)\n", this, pwszName
, uLen
);
1043 if (uLen
< sizeof(wszNewFolder
) / sizeof(WCHAR
) + 3)
1046 lstrcpynW (pwszName
, wszNewFolder
, uLen
);
1049 SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
| SHCONTF_INCLUDEHIDDEN
, &penum
);
1057 while (S_OK
== penum
->Next(1, &pidl
, &dwFetched
) &&
1059 _ILSimpleGetTextW (pidl
, wszText
, MAX_PATH
);
1060 if (0 == lstrcmpiW (wszText
, pwszName
)) {
1061 _snwprintf (pwszName
, uLen
, wszFormat
, wszNewFolder
, i
++);
1074 HRESULT WINAPI
CDesktopFolder::AddFolder(HWND hwnd
, LPCWSTR pwszName
, LPITEMIDLIST
*ppidlOut
)
1076 WCHAR wszNewDir
[MAX_PATH
];
1078 HRESULT hres
= E_FAIL
;
1080 TRACE ("(%p)(%s %p)\n", this, debugstr_w(pwszName
), ppidlOut
);
1084 lstrcpynW(wszNewDir
, sPathTarget
, MAX_PATH
);
1085 PathAppendW(wszNewDir
, pwszName
);
1086 bRes
= CreateDirectoryW (wszNewDir
, NULL
);
1089 SHChangeNotify (SHCNE_MKDIR
, SHCNF_PATHW
, wszNewDir
, NULL
);
1092 hres
= _ILCreateFromPathW(wszNewDir
, ppidlOut
);
1098 HRESULT WINAPI
CDesktopFolder::DeleteItems(UINT cidl
, LPCITEMIDLIST
*apidl
)
1102 WCHAR wszPath
[MAX_PATH
];
1103 WCHAR wszCaption
[50];
1104 WCHAR
*wszPathsList
;
1106 WCHAR
*wszCurrentPath
;
1107 UINT bRestoreWithDeskCpl
= FALSE
;
1110 TRACE ("(%p)(%u %p)\n", this, cidl
, apidl
);
1111 if (cidl
== 0) return S_OK
;
1113 for(i
= 0; i
< cidl
; i
++)
1115 if (_ILIsMyComputer(apidl
[i
]))
1116 bRestoreWithDeskCpl
++;
1117 else if (_ILIsNetHood(apidl
[i
]))
1118 bRestoreWithDeskCpl
++;
1119 else if (_ILIsMyDocuments(apidl
[i
]))
1120 bRestoreWithDeskCpl
++;
1123 if (bRestoreWithDeskCpl
)
1125 /* FIXME use FormatMessage
1126 * use a similar message resource as in windows
1128 LoadStringW(shell32_hInstance
, IDS_DELETEMULTIPLE_TEXT
, wszPath
, sizeof(wszPath
) / sizeof(WCHAR
));
1129 wszPath
[(sizeof(wszPath
)/sizeof(WCHAR
))-1] = 0;
1131 LoadStringW(shell32_hInstance
, IDS_DELETEITEM_CAPTION
, wszCaption
, sizeof(wszCaption
) / sizeof(WCHAR
));
1132 wszCaption
[(sizeof(wszCaption
)/sizeof(WCHAR
))-1] = 0;
1134 res
= SHELL_ConfirmMsgBox(GetActiveWindow(), wszPath
, wszCaption
, NULL
, cidl
> 1);
1135 if (res
== IDC_YESTOALL
|| res
== IDYES
)
1137 for(i
= 0; i
< cidl
; i
++)
1139 if (_ILIsMyComputer(apidl
[i
]))
1140 SetNamespaceExtensionVisibleStatus(L
"{20D04FE0-3AEA-1069-A2D8-08002B30309D}", 0x1);
1141 else if (_ILIsNetHood(apidl
[i
]))
1142 SetNamespaceExtensionVisibleStatus(L
"{208D2C60-3AEA-1069-A2D7-08002B30309D}", 0x1);
1143 else if (_ILIsMyDocuments(apidl
[i
]))
1144 SetNamespaceExtensionVisibleStatus(L
"{450D8FBA-AD25-11D0-98A8-0800361B1103}", 0x1);
1149 lstrcpynW(wszPath
, sPathTarget
, MAX_PATH
);
1153 PathAddBackslashW(wszPath
);
1154 wszPathsList
= BuildPathsList(wszPath
, cidl
, apidl
);
1156 ZeroMemory(&op
, sizeof(op
));
1157 op
.hwnd
= GetActiveWindow();
1158 op
.wFunc
= FO_DELETE
;
1159 op
.pFrom
= wszPathsList
;
1160 op
.fFlags
= FOF_ALLOWUNDO
;
1161 if (SHFileOperationW(&op
))
1163 WARN("SHFileOperation failed\n");
1169 /* we currently need to manually send the notifies */
1170 wszCurrentPath
= wszPathsList
;
1171 for (i
= 0; i
< cidl
; i
++)
1175 if (_ILIsFolder(apidl
[i
]))
1176 wEventId
= SHCNE_RMDIR
;
1177 else if (_ILIsValue(apidl
[i
]))
1178 wEventId
= SHCNE_DELETE
;
1182 /* check if file exists */
1183 if (GetFileAttributesW(wszCurrentPath
) == INVALID_FILE_ATTRIBUTES
)
1185 LPITEMIDLIST pidl
= ILCombine(pidlRoot
, apidl
[i
]);
1186 SHChangeNotify(wEventId
, SHCNF_IDLIST
, pidl
, NULL
);
1190 wszCurrentPath
+= wcslen(wszCurrentPath
) + 1;
1192 HeapFree(GetProcessHeap(), 0, wszPathsList
);
1196 HRESULT WINAPI
CDesktopFolder::CopyItems(IShellFolder
*pSFFrom
, UINT cidl
, LPCITEMIDLIST
*apidl
, BOOL bCopy
)
1198 CComPtr
<IPersistFolder2
> ppf2
;
1199 WCHAR szSrcPath
[MAX_PATH
];
1200 WCHAR szTargetPath
[MAX_PATH
];
1203 LPWSTR pszSrc
, pszTarget
, pszSrcList
, pszTargetList
, pszFileName
;
1207 TRACE ("(%p)->(%p,%u,%p)\n", this, pSFFrom
, cidl
, apidl
);
1209 pSFFrom
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2
));
1212 if (FAILED(ppf2
->GetCurFolder(&pidl
)))
1215 if (FAILED(pSFFrom
->GetDisplayNameOf(pidl
, SHGDN_FORPARSING
, &strRet
)))
1221 if (FAILED(StrRetToBufW(&strRet
, pidl
, szSrcPath
, MAX_PATH
)))
1228 pszSrc
= PathAddBackslashW (szSrcPath
);
1230 wcscpy(szTargetPath
, sPathTarget
);
1231 pszTarget
= PathAddBackslashW (szTargetPath
);
1233 pszSrcList
= BuildPathsList(szSrcPath
, cidl
, apidl
);
1234 pszTargetList
= BuildPathsList(szTargetPath
, cidl
, apidl
);
1236 if (!pszSrcList
|| !pszTargetList
)
1239 HeapFree(GetProcessHeap(), 0, pszSrcList
);
1242 HeapFree(GetProcessHeap(), 0, pszTargetList
);
1245 return E_OUTOFMEMORY
;
1247 ZeroMemory(&op
, sizeof(op
));
1250 /* remove trailing backslash */
1253 op
.pFrom
= szSrcPath
;
1257 op
.pFrom
= pszSrcList
;
1260 if (!pszTargetList
[0])
1262 /* remove trailing backslash */
1263 if (pszTarget
- szTargetPath
> 3)
1266 pszTarget
[0] = L
'\0';
1270 pszTarget
[1] = L
'\0';
1273 op
.pTo
= szTargetPath
;
1278 op
.pTo
= pszTargetList
;
1279 op
.fFlags
= FOF_MULTIDESTFILES
;
1281 op
.hwnd
= GetActiveWindow();
1282 op
.wFunc
= bCopy
? FO_COPY
: FO_MOVE
;
1283 op
.fFlags
|= FOF_ALLOWUNDO
| FOF_NOCONFIRMMKDIR
;
1285 res
= SHFileOperationW(&op
);
1287 if (res
== DE_SAMEFILE
)
1289 length
= wcslen(szTargetPath
);
1292 pszFileName
= wcsrchr(pszSrcList
, '\\');
1295 if (LoadStringW(shell32_hInstance
, IDS_COPY_OF
, pszTarget
, MAX_PATH
- length
))
1297 wcscat(szTargetPath
, L
" ");
1300 wcscat(szTargetPath
, pszFileName
);
1301 op
.pTo
= szTargetPath
;
1303 res
= SHFileOperationW(&op
);
1307 HeapFree(GetProcessHeap(), 0, pszSrcList
);
1308 HeapFree(GetProcessHeap(), 0, pszTargetList
);
1318 /****************************************************************************
1319 * IDropTarget implementation
1321 * This should allow two somewhat separate things, copying files to the users directory,
1322 * as well as allowing icons to be moved anywhere and updating the registry to save.
1324 * The first thing I think is best done using fs.cpp to prevent WET code. So we'll simulate
1325 * a drop to the user's home directory. The second will look at the pointer location and
1326 * set sensible places for the icons to live.
1329 BOOL
CDesktopFolder::QueryDrop(DWORD dwKeyState
, LPDWORD pdwEffect
)
1331 /* TODO Windows does different drop effects if dragging across drives.
1332 i.e., it will copy instead of move if the directories are on different disks. */
1334 DWORD dwEffect
= DROPEFFECT_MOVE
;
1336 *pdwEffect
= DROPEFFECT_NONE
;
1338 if (fAcceptFmt
) { /* Does our interpretation of the keystate ... */
1339 *pdwEffect
= KeyStateToDropEffect (dwKeyState
);
1341 if (*pdwEffect
== DROPEFFECT_NONE
)
1342 *pdwEffect
= dwEffect
;
1344 /* ... matches the desired effect ? */
1345 if (dwEffect
& *pdwEffect
) {
1352 HRESULT WINAPI
CDesktopFolder::DragEnter(IDataObject
*pDataObject
,
1353 DWORD dwKeyState
, POINTL pt
, DWORD
*pdwEffect
)
1355 TRACE("(%p)->(DataObject=%p)\n", this, pDataObject
);
1360 InitFormatEtc (fmt
, cfShellIDList
, TYMED_HGLOBAL
);
1361 InitFormatEtc (fmt2
, CF_HDROP
, TYMED_HGLOBAL
);
1363 if (SUCCEEDED(pDataObject
->QueryGetData(&fmt
)))
1365 else if (SUCCEEDED(pDataObject
->QueryGetData(&fmt2
)))
1368 QueryDrop(dwKeyState
, pdwEffect
);
1372 HRESULT WINAPI
CDesktopFolder::DragOver(DWORD dwKeyState
, POINTL pt
,
1375 TRACE("(%p)\n", this);
1378 return E_INVALIDARG
;
1380 QueryDrop(dwKeyState
, pdwEffect
);
1385 HRESULT WINAPI
CDesktopFolder::DragLeave()
1387 TRACE("(%p)\n", this);
1392 HRESULT WINAPI
CDesktopFolder::Drop(IDataObject
*pDataObject
,
1393 DWORD dwKeyState
, POINTL pt
, DWORD
*pdwEffect
)
1395 TRACE("(%p) object dropped desktop\n", this);
1398 bool passthroughtofs
= FALSE
;
1399 FORMATETC formatetc
;
1400 InitFormatEtc(formatetc
, RegisterClipboardFormatW(CFSTR_SHELLIDLIST
), TYMED_HGLOBAL
);
1402 HRESULT hr
= pDataObject
->GetData(&formatetc
, &medium
);
1405 /* lock the handle */
1406 LPIDA lpcida
= (LPIDA
)GlobalLock(medium
.hGlobal
);
1409 ReleaseStgMedium(&medium
);
1413 /* convert the clipboard data into pidl (pointer to id list) */
1415 LPITEMIDLIST
*apidl
= _ILCopyCidaToaPidl(&pidl
, lpcida
);
1418 ReleaseStgMedium(&medium
);
1421 passthroughtofs
= !_ILIsDesktop(pidl
) || (dwKeyState
& MK_CONTROL
);
1423 _ILFreeaPidl(apidl
, lpcida
->cidl
);
1424 ReleaseStgMedium(&medium
);
1428 InitFormatEtc (formatetc
, CF_HDROP
, TYMED_HGLOBAL
);
1429 if (SUCCEEDED(pDataObject
->QueryGetData(&formatetc
)))
1431 passthroughtofs
= TRUE
;
1434 /* We only want to really move files around if they don't already
1435 come from the desktop, or we're linking or copying */
1436 if (passthroughtofs
)
1438 LPITEMIDLIST pidl
= NULL
;
1440 WCHAR szPath
[MAX_PATH
];
1443 /* build a complete path to create a simple pidl */
1444 lstrcpynW(szPath
, sPathTarget
, MAX_PATH
);
1445 /*pathPtr = */PathAddBackslashW(szPath
);
1446 //hr = _ILCreateFromPathW(szPath, &pidl);
1447 hr
= this->ParseDisplayName(NULL
, NULL
, szPath
, NULL
, &pidl
, NULL
);
1451 CComPtr
<IDropTarget
> pDT
;
1452 hr
= this->BindToObject(pidl
, NULL
, IID_PPV_ARG(IDropTarget
, &pDT
));
1453 CoTaskMemFree(pidl
);
1455 SHSimulateDrop(pDT
, pDataObject
, dwKeyState
, NULL
, pdwEffect
);
1457 ERR("Error Binding");
1460 ERR("Error creating from %s\n", debugstr_w(szPath
));
1463 /* Todo, rewrite the registry such that the icons are well placed.
1464 Blocked by no bags implementation. */
1468 HRESULT WINAPI
CDesktopFolder::_GetDropTarget(LPCITEMIDLIST pidl
, LPVOID
*ppvOut
) {
1471 TRACE("CFSFolder::_GetDropTarget entered\n");
1473 if (_ILGetGUIDPointer (pidl
) || _ILIsFolder (pidl
))
1474 return this->BindToObject(pidl
, NULL
, IID_IDropTarget
, ppvOut
);
1476 LPITEMIDLIST pidlNext
= NULL
;
1479 hr
= this->GetDisplayNameOf(pidl
, SHGDN_FORPARSING
, &strFile
);
1482 WCHAR wszPath
[MAX_PATH
];
1483 hr
= StrRetToBufW(&strFile
, pidl
, wszPath
, _countof(wszPath
));
1487 PathRemoveFileSpecW (wszPath
);
1488 hr
= this->ParseDisplayName(NULL
, NULL
, wszPath
, NULL
, &pidlNext
, NULL
);
1492 CComPtr
<IShellFolder
> psf
;
1493 hr
= this->BindToObject(pidlNext
, NULL
, IID_PPV_ARG(IShellFolder
, &psf
));
1494 CoTaskMemFree(pidlNext
);
1497 hr
= psf
->GetUIObjectOf(NULL
, 1, &pidl
, IID_IDropTarget
, NULL
, ppvOut
);
1499 ERR("FS GetUIObjectOf failed: %x\n", hr
);
1502 ERR("BindToObject failed: %x\n", hr
);
1505 ERR("ParseDisplayName failed: %x\n", hr
);
1508 ERR("StrRetToBufW failed: %x\n", hr
);
1511 ERR("GetDisplayNameOf failed: %x\n", hr
);
1516 /*************************************************************************
1517 * SHGetDesktopFolder [SHELL32.@]
1519 HRESULT WINAPI
SHGetDesktopFolder(IShellFolder
**psf
)
1521 HRESULT hres
= S_OK
;
1524 if(!psf
) return E_INVALIDARG
;
1526 hres
= CDesktopFolder::_CreatorClass::CreateInstance(NULL
, IID_PPV_ARG(IShellFolder
, psf
));
1528 TRACE("-- %p->(%p)\n",psf
, *psf
);