1c2c66affSColin Finck /*
2c2c66affSColin Finck * Virtual Desktop Folder
3c2c66affSColin Finck *
4c2c66affSColin Finck * Copyright 1997 Marcus Meissner
5c2c66affSColin Finck * Copyright 1998, 1999, 2002 Juergen Schmied
6c2c66affSColin Finck * Copyright 2009 Andrew Hill
7c2c66affSColin Finck *
8c2c66affSColin Finck * This library is free software; you can redistribute it and/or
9c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
10c2c66affSColin Finck * License as published by the Free Software Foundation; either
11c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
12c2c66affSColin Finck *
13c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
14c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
15c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16c2c66affSColin Finck * Lesser General Public License for more details.
17c2c66affSColin Finck *
18c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
19c2c66affSColin Finck * License along with this library; if not, write to the Free Software
20c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21c2c66affSColin Finck */
22c2c66affSColin Finck
23c2c66affSColin Finck #include <precomp.h>
243693d554SDoug Lyons #include "CFSFolder.h" // Only for CFSFolder::*FSColumn* helpers!
25c2c66affSColin Finck
26c2c66affSColin Finck WINE_DEFAULT_DEBUG_CHANNEL(shell);
27c2c66affSColin Finck
286ae11ba0SWhindmar Saksit extern BOOL SHELL32_IsShellFolderNamespaceItemHidden(LPCWSTR SubKey, REFCLSID Clsid);
296ae11ba0SWhindmar Saksit
306ae11ba0SWhindmar Saksit static const REQUIREDREGITEM g_RequiredItems[] =
316ae11ba0SWhindmar Saksit {
326ae11ba0SWhindmar Saksit { CLSID_MyComputer, "sysdm.cpl", 0x50 },
336ae11ba0SWhindmar Saksit { CLSID_NetworkPlaces, "ncpa.cpl", 0x58 },
346ae11ba0SWhindmar Saksit { CLSID_Internet, "inetcpl.cpl", 0x68 },
356ae11ba0SWhindmar Saksit };
366ae11ba0SWhindmar Saksit static const REGFOLDERINFO g_RegFolderInfo =
376ae11ba0SWhindmar Saksit {
386ae11ba0SWhindmar Saksit PT_DESKTOP_REGITEM,
396ae11ba0SWhindmar Saksit _countof(g_RequiredItems), g_RequiredItems,
406ae11ba0SWhindmar Saksit CLSID_ShellDesktop,
416ae11ba0SWhindmar Saksit L"",
426ae11ba0SWhindmar Saksit L"Desktop",
436ae11ba0SWhindmar Saksit };
446ae11ba0SWhindmar Saksit
IsSelf(UINT cidl,PCUITEMID_CHILD_ARRAY apidl)4563935f85SWhindmar Saksit static BOOL IsSelf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl)
4663935f85SWhindmar Saksit {
4763935f85SWhindmar Saksit return cidl == 0 || (cidl == 1 && apidl && _ILIsEmpty(apidl[0]));
4863935f85SWhindmar Saksit }
4963935f85SWhindmar Saksit
IsRegItem(PCUITEMID_CHILD pidl)506ae11ba0SWhindmar Saksit static const CLSID* IsRegItem(PCUITEMID_CHILD pidl)
516ae11ba0SWhindmar Saksit {
526ae11ba0SWhindmar Saksit if (pidl && pidl->mkid.cb == 2 + 2 + sizeof(CLSID) && pidl->mkid.abID[0] == PT_GUID)
536ae11ba0SWhindmar Saksit return (const CLSID*)(&pidl->mkid.abID[2]);
546ae11ba0SWhindmar Saksit return NULL;
556ae11ba0SWhindmar Saksit }
566ae11ba0SWhindmar Saksit
57d05dcf6aSKatayama Hirofumi MZ STDMETHODIMP
ShellUrlParseDisplayName(HWND hwndOwner,LPBC pbc,LPOLESTR lpszDisplayName,DWORD * pchEaten,PIDLIST_RELATIVE * ppidl,DWORD * pdwAttributes)58ff282894SKatayama Hirofumi MZ CDesktopFolder::ShellUrlParseDisplayName(
59ff282894SKatayama Hirofumi MZ HWND hwndOwner,
60ff282894SKatayama Hirofumi MZ LPBC pbc,
61ff282894SKatayama Hirofumi MZ LPOLESTR lpszDisplayName,
62ff282894SKatayama Hirofumi MZ DWORD *pchEaten,
63ff282894SKatayama Hirofumi MZ PIDLIST_RELATIVE *ppidl,
64ff282894SKatayama Hirofumi MZ DWORD *pdwAttributes)
65d05dcf6aSKatayama Hirofumi MZ {
66d05dcf6aSKatayama Hirofumi MZ LPWSTR pch;
67d05dcf6aSKatayama Hirofumi MZ INT cch, csidl;
68d05dcf6aSKatayama Hirofumi MZ HRESULT hr = HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND);
69d05dcf6aSKatayama Hirofumi MZ PARSEDURLW ParsedURL = { sizeof(ParsedURL) };
70d05dcf6aSKatayama Hirofumi MZ
71d05dcf6aSKatayama Hirofumi MZ ::ParseURLW(lpszDisplayName, &ParsedURL);
72d05dcf6aSKatayama Hirofumi MZ
73d05dcf6aSKatayama Hirofumi MZ DWORD attrs = (pdwAttributes ? *pdwAttributes : 0) | SFGAO_STREAM;
74ff282894SKatayama Hirofumi MZ if (ParsedURL.pszSuffix[0] == L':' && ParsedURL.pszSuffix[1] == L':') // It begins from "::"
75d05dcf6aSKatayama Hirofumi MZ {
76d05dcf6aSKatayama Hirofumi MZ CComPtr<IShellFolder> psfDesktop;
77d05dcf6aSKatayama Hirofumi MZ hr = SHGetDesktopFolder(&psfDesktop);
78d05dcf6aSKatayama Hirofumi MZ if (SUCCEEDED(hr))
79d05dcf6aSKatayama Hirofumi MZ {
80d05dcf6aSKatayama Hirofumi MZ CComPtr<IBindCtx> pBindCtx;
81d05dcf6aSKatayama Hirofumi MZ hr = ::CreateBindCtx(0, &pBindCtx);
82d05dcf6aSKatayama Hirofumi MZ if (SUCCEEDED(hr))
83d05dcf6aSKatayama Hirofumi MZ {
84d05dcf6aSKatayama Hirofumi MZ BIND_OPTS BindOps = { sizeof(BindOps) };
85d05dcf6aSKatayama Hirofumi MZ BindOps.grfMode = STGM_CREATE;
86d05dcf6aSKatayama Hirofumi MZ pBindCtx->SetBindOptions(&BindOps);
87d05dcf6aSKatayama Hirofumi MZ hr = psfDesktop->ParseDisplayName(hwndOwner, pBindCtx,
88d05dcf6aSKatayama Hirofumi MZ (LPWSTR)ParsedURL.pszSuffix,
89d05dcf6aSKatayama Hirofumi MZ pchEaten, ppidl, &attrs);
90d05dcf6aSKatayama Hirofumi MZ }
91d05dcf6aSKatayama Hirofumi MZ }
92d05dcf6aSKatayama Hirofumi MZ }
93d05dcf6aSKatayama Hirofumi MZ else
94d05dcf6aSKatayama Hirofumi MZ {
95d05dcf6aSKatayama Hirofumi MZ csidl = Shell_ParseSpecialFolder(ParsedURL.pszSuffix, &pch, &cch);
96d05dcf6aSKatayama Hirofumi MZ if (csidl == -1)
97d05dcf6aSKatayama Hirofumi MZ {
98d05dcf6aSKatayama Hirofumi MZ ERR("\n");
99d05dcf6aSKatayama Hirofumi MZ return hr;
100d05dcf6aSKatayama Hirofumi MZ }
101d05dcf6aSKatayama Hirofumi MZ
102d05dcf6aSKatayama Hirofumi MZ CComHeapPtr<ITEMIDLIST> pidlLocation;
103d05dcf6aSKatayama Hirofumi MZ hr = SHGetFolderLocation(hwndOwner, (csidl | CSIDL_FLAG_CREATE), NULL, 0, &pidlLocation);
104d05dcf6aSKatayama Hirofumi MZ if (FAILED_UNEXPECTEDLY(hr))
105d05dcf6aSKatayama Hirofumi MZ return hr;
106d05dcf6aSKatayama Hirofumi MZ
107d05dcf6aSKatayama Hirofumi MZ if (pch && *pch)
108d05dcf6aSKatayama Hirofumi MZ {
109d05dcf6aSKatayama Hirofumi MZ CComPtr<IShellFolder> psfFolder;
110d05dcf6aSKatayama Hirofumi MZ hr = SHBindToObject(NULL, pidlLocation, IID_PPV_ARG(IShellFolder, &psfFolder));
111d05dcf6aSKatayama Hirofumi MZ if (SUCCEEDED(hr))
112d05dcf6aSKatayama Hirofumi MZ {
113d05dcf6aSKatayama Hirofumi MZ CComHeapPtr<ITEMIDLIST> pidlNew;
114d05dcf6aSKatayama Hirofumi MZ hr = psfFolder->ParseDisplayName(hwndOwner, pbc, pch, pchEaten, &pidlNew, &attrs);
115d05dcf6aSKatayama Hirofumi MZ if (SUCCEEDED(hr))
116d05dcf6aSKatayama Hirofumi MZ {
117d05dcf6aSKatayama Hirofumi MZ hr = SHILCombine(pidlLocation, pidlNew, ppidl);
118d05dcf6aSKatayama Hirofumi MZ if (pchEaten)
119d05dcf6aSKatayama Hirofumi MZ *pchEaten += cch;
120d05dcf6aSKatayama Hirofumi MZ }
121d05dcf6aSKatayama Hirofumi MZ }
122d05dcf6aSKatayama Hirofumi MZ }
123d05dcf6aSKatayama Hirofumi MZ else
124d05dcf6aSKatayama Hirofumi MZ {
125d05dcf6aSKatayama Hirofumi MZ if (attrs)
126d05dcf6aSKatayama Hirofumi MZ hr = SHGetNameAndFlagsW(pidlLocation, 0, NULL, 0, &attrs);
127d05dcf6aSKatayama Hirofumi MZ
128d05dcf6aSKatayama Hirofumi MZ if (SUCCEEDED(hr))
129d05dcf6aSKatayama Hirofumi MZ {
130d05dcf6aSKatayama Hirofumi MZ if (pchEaten)
131d05dcf6aSKatayama Hirofumi MZ *pchEaten = cch;
132d05dcf6aSKatayama Hirofumi MZ *ppidl = pidlLocation.Detach();
133d05dcf6aSKatayama Hirofumi MZ }
134d05dcf6aSKatayama Hirofumi MZ }
135d05dcf6aSKatayama Hirofumi MZ }
136d05dcf6aSKatayama Hirofumi MZ
137d05dcf6aSKatayama Hirofumi MZ // FIXME: SHWindowsPolicy
138d05dcf6aSKatayama Hirofumi MZ if (SUCCEEDED(hr) && (attrs & SFGAO_STREAM) &&
139d05dcf6aSKatayama Hirofumi MZ !BindCtx_ContainsObject(pbc, STR_PARSE_SHELL_PROTOCOL_TO_FILE_OBJECTS))
140d05dcf6aSKatayama Hirofumi MZ {
141d05dcf6aSKatayama Hirofumi MZ ILFree(*ppidl);
142d05dcf6aSKatayama Hirofumi MZ *ppidl = NULL;
143d05dcf6aSKatayama Hirofumi MZ hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
144d05dcf6aSKatayama Hirofumi MZ }
145d05dcf6aSKatayama Hirofumi MZ
146d05dcf6aSKatayama Hirofumi MZ if (pdwAttributes)
147d05dcf6aSKatayama Hirofumi MZ *pdwAttributes = attrs;
148d05dcf6aSKatayama Hirofumi MZ
149d05dcf6aSKatayama Hirofumi MZ // FIXME: SHWindowsPolicy
150d05dcf6aSKatayama Hirofumi MZ if (FAILED(hr) && !Shell_FailForceReturn(hr))
151d05dcf6aSKatayama Hirofumi MZ hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
152d05dcf6aSKatayama Hirofumi MZ
153d05dcf6aSKatayama Hirofumi MZ return hr;
154d05dcf6aSKatayama Hirofumi MZ }
155d05dcf6aSKatayama Hirofumi MZ
156d05dcf6aSKatayama Hirofumi MZ STDMETHODIMP
HttpUrlParseDisplayName(HWND hwndOwner,LPBC pbc,LPOLESTR lpszDisplayName,DWORD * pchEaten,PIDLIST_RELATIVE * ppidl,DWORD * pdwAttributes)157ff282894SKatayama Hirofumi MZ CDesktopFolder::HttpUrlParseDisplayName(
158d05dcf6aSKatayama Hirofumi MZ HWND hwndOwner,
159ff282894SKatayama Hirofumi MZ LPBC pbc,
160ff282894SKatayama Hirofumi MZ LPOLESTR lpszDisplayName,
161d05dcf6aSKatayama Hirofumi MZ DWORD *pchEaten,
162ff282894SKatayama Hirofumi MZ PIDLIST_RELATIVE *ppidl,
163d05dcf6aSKatayama Hirofumi MZ DWORD *pdwAttributes)
164d05dcf6aSKatayama Hirofumi MZ {
165ff282894SKatayama Hirofumi MZ FIXME("\n");
166ff282894SKatayama Hirofumi MZ return E_NOTIMPL; // FIXME
167d05dcf6aSKatayama Hirofumi MZ }
168d05dcf6aSKatayama Hirofumi MZ
169c2c66affSColin Finck /*
170c2c66affSColin Finck CDesktopFolder should create two file system folders internally, one representing the
171c2c66affSColin Finck user's desktop folder, and the other representing the common desktop folder. It should
172c2c66affSColin Finck also create a CRegFolder to represent the virtual items that exist only in the registry.
173c2c66affSColin Finck The CRegFolder is aggregated by the CDesktopFolder, and queries for the CLSID_IShellFolder,
174c2c66affSColin Finck CLSID_IShellFolder2, or CLSID_IShellIconOverlay interfaces prefer the CRegFolder
175c2c66affSColin Finck implementation.
176c2c66affSColin Finck The CDesktopFolderEnum class should create two enumerators, one for each of the file
177c2c66affSColin Finck system folders, and enumerate the contents of each folder. Since the CRegFolder
178c2c66affSColin Finck implementation of IShellFolder::EnumObjects enumerates the virtual items, the
179c2c66affSColin Finck CDesktopFolderEnum is only responsible for returning the physical items.
1806ae11ba0SWhindmar Saksit CDesktopFolderViewCB is responsible for filtering hidden regitems.
1816ae11ba0SWhindmar Saksit The enumerator always shows My Computer.
182c2c66affSColin Finck */
183c2c66affSColin Finck
184c2c66affSColin Finck /* Undocumented functions from shdocvw */
185c2c66affSColin Finck extern "C" HRESULT WINAPI IEParseDisplayNameWithBCW(DWORD codepage, LPCWSTR lpszDisplayName, LPBC pbc, LPITEMIDLIST *ppidl);
186c2c66affSColin Finck
187c2c66affSColin Finck class CDesktopFolderEnum :
188c2c66affSColin Finck public CEnumIDListBase
189c2c66affSColin Finck {
190c2c66affSColin Finck private:
191c2c66affSColin Finck // CComPtr fDesktopEnumerator;
192c2c66affSColin Finck // CComPtr fCommonDesktopEnumerator;
193c2c66affSColin Finck public:
194c2c66affSColin Finck
Initialize(IShellFolder * pRegFolder,SHCONTF dwFlags,IEnumIDList * pRegEnumerator,IEnumIDList * pDesktopEnumerator,IEnumIDList * pCommonDesktopEnumerator)1956ae11ba0SWhindmar Saksit HRESULT WINAPI Initialize(IShellFolder *pRegFolder, SHCONTF dwFlags, IEnumIDList *pRegEnumerator,
1966ae11ba0SWhindmar Saksit IEnumIDList *pDesktopEnumerator, IEnumIDList *pCommonDesktopEnumerator)
197c2c66affSColin Finck {
198c2c66affSColin Finck TRACE("(%p)->(flags=0x%08x)\n", this, dwFlags);
199c2c66affSColin Finck
2006ae11ba0SWhindmar Saksit AppendItemsFromEnumerator(pRegEnumerator);
201c2c66affSColin Finck
202c2c66affSColin Finck /* Enumerate the items in the two fs folders */
203c2c66affSColin Finck AppendItemsFromEnumerator(pDesktopEnumerator);
204c2c66affSColin Finck AppendItemsFromEnumerator(pCommonDesktopEnumerator);
205c2c66affSColin Finck
2066ae11ba0SWhindmar Saksit return S_OK;
207c2c66affSColin Finck }
208c2c66affSColin Finck
209c2c66affSColin Finck BEGIN_COM_MAP(CDesktopFolderEnum)
210c2c66affSColin Finck COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
211c2c66affSColin Finck END_COM_MAP()
212c2c66affSColin Finck };
213c2c66affSColin Finck
214c2c66affSColin Finck int SHELL_ConfirmMsgBox(HWND hWnd, LPWSTR lpszText, LPWSTR lpszCaption, HICON hIcon, BOOL bYesToAll);
215c2c66affSColin Finck
216c2c66affSColin Finck static const DWORD dwDesktopAttributes =
217c2c66affSColin Finck SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR |
218730d81b9SGiannis Adamopoulos SFGAO_STORAGEANCESTOR | SFGAO_HASPROPSHEET | SFGAO_STORAGE;
219c2c66affSColin Finck static const DWORD dwMyComputerAttributes =
220c2c66affSColin Finck SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
221c2c66affSColin Finck SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK;
222c2c66affSColin Finck static DWORD dwMyNetPlacesAttributes =
223c2c66affSColin Finck SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
224c2c66affSColin Finck SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK;
225c2c66affSColin Finck
CDesktopFolder()226c2c66affSColin Finck CDesktopFolder::CDesktopFolder() :
227c2c66affSColin Finck sPathTarget(NULL),
228c2c66affSColin Finck pidlRoot(NULL)
229c2c66affSColin Finck {
230c2c66affSColin Finck }
231c2c66affSColin Finck
~CDesktopFolder()232c2c66affSColin Finck CDesktopFolder::~CDesktopFolder()
233c2c66affSColin Finck {
234c2c66affSColin Finck }
235c2c66affSColin Finck
FinalConstruct()236c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::FinalConstruct()
237c2c66affSColin Finck {
238c2c66affSColin Finck WCHAR szMyPath[MAX_PATH];
239c2c66affSColin Finck HRESULT hr;
240c2c66affSColin Finck
241c2c66affSColin Finck /* Create the root pidl */
242c2c66affSColin Finck pidlRoot = _ILCreateDesktop();
243c2c66affSColin Finck if (!pidlRoot)
244c2c66affSColin Finck return E_OUTOFMEMORY;
245c2c66affSColin Finck
246c2c66affSColin Finck /* Create the inner fs folder */
247c2c66affSColin Finck hr = SHELL32_CoCreateInitSF(pidlRoot,
248c2c66affSColin Finck &CLSID_ShellFSFolder,
249c2c66affSColin Finck CSIDL_DESKTOPDIRECTORY,
250c2c66affSColin Finck IID_PPV_ARG(IShellFolder2, &m_DesktopFSFolder));
251c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
252c2c66affSColin Finck return hr;
253c2c66affSColin Finck
254c2c66affSColin Finck /* Create the inner shared fs folder. Dont fail on failure. */
255c2c66affSColin Finck hr = SHELL32_CoCreateInitSF(pidlRoot,
256c2c66affSColin Finck &CLSID_ShellFSFolder,
257c2c66affSColin Finck CSIDL_COMMON_DESKTOPDIRECTORY,
258c2c66affSColin Finck IID_PPV_ARG(IShellFolder2, &m_SharedDesktopFSFolder));
259c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
260c2c66affSColin Finck return hr;
261c2c66affSColin Finck
262c2c66affSColin Finck /* Create the inner reg folder */
2636ae11ba0SWhindmar Saksit REGFOLDERINITDATA RegInit = { static_cast<IShellFolder*>(this), &g_RegFolderInfo };
2646ae11ba0SWhindmar Saksit hr = CRegFolder_CreateInstance(&RegInit,
265c2c66affSColin Finck pidlRoot,
266c2c66affSColin Finck IID_PPV_ARG(IShellFolder2, &m_regFolder));
267c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
268c2c66affSColin Finck return hr;
269c2c66affSColin Finck
270c2c66affSColin Finck /* Cache the path to the user desktop directory */
271c2c66affSColin Finck if (!SHGetSpecialFolderPathW( 0, szMyPath, CSIDL_DESKTOPDIRECTORY, TRUE ))
272c2c66affSColin Finck return E_UNEXPECTED;
273c2c66affSColin Finck
274c2c66affSColin Finck sPathTarget = (LPWSTR)SHAlloc((wcslen(szMyPath) + 1) * sizeof(WCHAR));
275c2c66affSColin Finck if (!sPathTarget)
276c2c66affSColin Finck return E_OUTOFMEMORY;
277c2c66affSColin Finck
278c2c66affSColin Finck wcscpy(sPathTarget, szMyPath);
279c2c66affSColin Finck return S_OK;
280c2c66affSColin Finck }
281c2c66affSColin Finck
_GetSFFromPidl(LPCITEMIDLIST pidl,IShellFolder2 ** psf)282c2c66affSColin Finck HRESULT CDesktopFolder::_GetSFFromPidl(LPCITEMIDLIST pidl, IShellFolder2** psf)
283c2c66affSColin Finck {
284c2c66affSColin Finck WCHAR szFileName[MAX_PATH];
285c2c66affSColin Finck
286c2c66affSColin Finck if (_ILIsSpecialFolder(pidl))
287c2c66affSColin Finck return m_regFolder->QueryInterface(IID_PPV_ARG(IShellFolder2, psf));
288c2c66affSColin Finck
289c2c66affSColin Finck lstrcpynW(szFileName, sPathTarget, MAX_PATH - 1);
290c2c66affSColin Finck PathAddBackslashW(szFileName);
291c2c66affSColin Finck int cLen = wcslen(szFileName);
292c2c66affSColin Finck
293c2c66affSColin Finck if (!_ILSimpleGetTextW(pidl, szFileName + cLen, MAX_PATH - cLen))
294c2c66affSColin Finck return E_FAIL;
295c2c66affSColin Finck
296c2c66affSColin Finck if (GetFileAttributes(szFileName) == INVALID_FILE_ATTRIBUTES)
297c2c66affSColin Finck return m_SharedDesktopFSFolder->QueryInterface(IID_PPV_ARG(IShellFolder2, psf));
298c2c66affSColin Finck else
299c2c66affSColin Finck return m_DesktopFSFolder->QueryInterface(IID_PPV_ARG(IShellFolder2, psf));
300c2c66affSColin Finck }
301c2c66affSColin Finck
_ParseDisplayNameByParent(HWND hwndOwner,LPBC pbc,LPOLESTR lpszDisplayName,DWORD * pchEaten,PIDLIST_RELATIVE * ppidl,DWORD * pdwAttributes)302ff282894SKatayama Hirofumi MZ HRESULT CDesktopFolder::_ParseDisplayNameByParent(
303ff282894SKatayama Hirofumi MZ HWND hwndOwner,
304ff282894SKatayama Hirofumi MZ LPBC pbc,
305ff282894SKatayama Hirofumi MZ LPOLESTR lpszDisplayName,
306ff282894SKatayama Hirofumi MZ DWORD *pchEaten,
307ff282894SKatayama Hirofumi MZ PIDLIST_RELATIVE *ppidl,
308ff282894SKatayama Hirofumi MZ DWORD *pdwAttributes)
309ff282894SKatayama Hirofumi MZ {
310ff282894SKatayama Hirofumi MZ if (pchEaten)
311ff282894SKatayama Hirofumi MZ *pchEaten = 0;
312ff282894SKatayama Hirofumi MZ
313ff282894SKatayama Hirofumi MZ CComHeapPtr<ITEMIDLIST> pidlParent;
314ff282894SKatayama Hirofumi MZ BOOL bPath = FALSE;
315ff282894SKatayama Hirofumi MZ WCHAR wch = *lpszDisplayName;
316ff282894SKatayama Hirofumi MZ if (((L'A' <= wch && wch <= L'Z') || (L'a' <= wch && wch <= L'z')) &&
317ff282894SKatayama Hirofumi MZ (lpszDisplayName[1] == L':'))
318ff282894SKatayama Hirofumi MZ {
319ff282894SKatayama Hirofumi MZ // "C:..."
320ff282894SKatayama Hirofumi MZ bPath = TRUE;
321ff282894SKatayama Hirofumi MZ pidlParent.Attach(_ILCreateMyComputer());
322ff282894SKatayama Hirofumi MZ }
323ff282894SKatayama Hirofumi MZ else if (PathIsUNCW(lpszDisplayName)) // "\\\\..."
324ff282894SKatayama Hirofumi MZ {
325ff282894SKatayama Hirofumi MZ bPath = TRUE;
326ff282894SKatayama Hirofumi MZ pidlParent.Attach(_ILCreateNetwork());
327ff282894SKatayama Hirofumi MZ }
328ff282894SKatayama Hirofumi MZ
329ff282894SKatayama Hirofumi MZ if (bPath)
330ff282894SKatayama Hirofumi MZ {
331ff282894SKatayama Hirofumi MZ if (!pidlParent)
332ff282894SKatayama Hirofumi MZ return E_OUTOFMEMORY;
333ff282894SKatayama Hirofumi MZ
334ff282894SKatayama Hirofumi MZ CComPtr<IShellFolder> pParentFolder;
335ff282894SKatayama Hirofumi MZ SHBindToObject(NULL, pidlParent, IID_PPV_ARG(IShellFolder, &pParentFolder));
336ff282894SKatayama Hirofumi MZ
337ff282894SKatayama Hirofumi MZ CComHeapPtr<ITEMIDLIST> pidlChild;
338ff282894SKatayama Hirofumi MZ HRESULT hr = pParentFolder->ParseDisplayName(hwndOwner, pbc, lpszDisplayName,
339ff282894SKatayama Hirofumi MZ pchEaten, &pidlChild, pdwAttributes);
340ff282894SKatayama Hirofumi MZ if (FAILED(hr))
341ff282894SKatayama Hirofumi MZ return hr;
342ff282894SKatayama Hirofumi MZ
343ff282894SKatayama Hirofumi MZ *ppidl = ILCombine(pidlParent, pidlChild);
344ff282894SKatayama Hirofumi MZ return (*ppidl ? S_OK : E_OUTOFMEMORY);
345ff282894SKatayama Hirofumi MZ }
346ff282894SKatayama Hirofumi MZ
347ff282894SKatayama Hirofumi MZ if (!UrlIsW(lpszDisplayName, URLIS_URL) || SHSkipJunctionBinding(pbc, NULL))
348ff282894SKatayama Hirofumi MZ return E_INVALIDARG;
349ff282894SKatayama Hirofumi MZ
350ff282894SKatayama Hirofumi MZ // Now lpszDisplayName is a URL
351ff282894SKatayama Hirofumi MZ PARSEDURLW ParsedURL = { sizeof(ParsedURL) };
352ff282894SKatayama Hirofumi MZ ::ParseURLW(lpszDisplayName, &ParsedURL);
353ff282894SKatayama Hirofumi MZ
354ff282894SKatayama Hirofumi MZ switch (ParsedURL.nScheme)
355ff282894SKatayama Hirofumi MZ {
356ff282894SKatayama Hirofumi MZ case URL_SCHEME_FILE: // "file:..."
357ff282894SKatayama Hirofumi MZ {
358ff282894SKatayama Hirofumi MZ // Convert "file://..." to a normal path
359ff282894SKatayama Hirofumi MZ WCHAR szPath[MAX_PATH];
360ff282894SKatayama Hirofumi MZ DWORD cchPath = _countof(szPath);
361ff282894SKatayama Hirofumi MZ HRESULT hr = PathCreateFromUrlW(lpszDisplayName, szPath, &cchPath, 0);
362ff282894SKatayama Hirofumi MZ if (FAILED_UNEXPECTEDLY(hr))
363ff282894SKatayama Hirofumi MZ return hr;
364ff282894SKatayama Hirofumi MZ
365ff282894SKatayama Hirofumi MZ CComPtr<IShellFolder> psfDesktop;
366ff282894SKatayama Hirofumi MZ hr = SHGetDesktopFolder(&psfDesktop);
367ff282894SKatayama Hirofumi MZ if (FAILED_UNEXPECTEDLY(hr))
368ff282894SKatayama Hirofumi MZ return hr;
369ff282894SKatayama Hirofumi MZ
370ff282894SKatayama Hirofumi MZ // Parse by desktop folder
371ff282894SKatayama Hirofumi MZ return psfDesktop->ParseDisplayName(hwndOwner, pbc, szPath, pchEaten, ppidl,
372ff282894SKatayama Hirofumi MZ pdwAttributes);
373ff282894SKatayama Hirofumi MZ }
374ff282894SKatayama Hirofumi MZ case URL_SCHEME_HTTP: // "http:..."
375ff282894SKatayama Hirofumi MZ case URL_SCHEME_HTTPS: // "https:..."
376ff282894SKatayama Hirofumi MZ {
377ff282894SKatayama Hirofumi MZ if (!BindCtx_ContainsObject(pbc, STR_PARSE_PREFER_FOLDER_BROWSING))
378ff282894SKatayama Hirofumi MZ return E_INVALIDARG;
379ff282894SKatayama Hirofumi MZ
380ff282894SKatayama Hirofumi MZ return HttpUrlParseDisplayName(hwndOwner,
381ff282894SKatayama Hirofumi MZ pbc,
382ff282894SKatayama Hirofumi MZ lpszDisplayName,
383ff282894SKatayama Hirofumi MZ pchEaten,
384ff282894SKatayama Hirofumi MZ ppidl,
385ff282894SKatayama Hirofumi MZ pdwAttributes);
386ff282894SKatayama Hirofumi MZ }
387ff282894SKatayama Hirofumi MZ case URL_SCHEME_SHELL: // "shell:..."
388ff282894SKatayama Hirofumi MZ {
389ff282894SKatayama Hirofumi MZ return ShellUrlParseDisplayName(hwndOwner,
390ff282894SKatayama Hirofumi MZ pbc,
391ff282894SKatayama Hirofumi MZ lpszDisplayName,
392ff282894SKatayama Hirofumi MZ pchEaten,
393ff282894SKatayama Hirofumi MZ ppidl,
394ff282894SKatayama Hirofumi MZ pdwAttributes);
395ff282894SKatayama Hirofumi MZ }
396ff282894SKatayama Hirofumi MZ case URL_SCHEME_MSSHELLROOTED:
397ff282894SKatayama Hirofumi MZ case URL_SCHEME_MSSHELLIDLIST:
398ff282894SKatayama Hirofumi MZ {
399ff282894SKatayama Hirofumi MZ WARN("We don't support 'ms-shell-rooted:' and 'ms-shell-idlist:' schemes\n");
400ff282894SKatayama Hirofumi MZ break;
401ff282894SKatayama Hirofumi MZ }
402ff282894SKatayama Hirofumi MZ default:
403ff282894SKatayama Hirofumi MZ {
404ff282894SKatayama Hirofumi MZ TRACE("Scheme: %u\n", ParsedURL.nScheme);
405ff282894SKatayama Hirofumi MZ break;
406ff282894SKatayama Hirofumi MZ }
407ff282894SKatayama Hirofumi MZ }
408ff282894SKatayama Hirofumi MZ
409ff282894SKatayama Hirofumi MZ return E_INVALIDARG;
410ff282894SKatayama Hirofumi MZ }
411ff282894SKatayama Hirofumi MZ
412c2c66affSColin Finck /**************************************************************************
413c2c66affSColin Finck * CDesktopFolder::ParseDisplayName
414c2c66affSColin Finck *
415c2c66affSColin Finck * NOTES
416c2c66affSColin Finck * "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
417c2c66affSColin Finck * to MyComputer
418c2c66affSColin Finck */
ParseDisplayName(HWND hwndOwner,LPBC pbc,LPOLESTR lpszDisplayName,DWORD * pchEaten,PIDLIST_RELATIVE * ppidl,DWORD * pdwAttributes)419c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::ParseDisplayName(
420c2c66affSColin Finck HWND hwndOwner,
421c2c66affSColin Finck LPBC pbc,
422c2c66affSColin Finck LPOLESTR lpszDisplayName,
423c2c66affSColin Finck DWORD *pchEaten,
424c2c66affSColin Finck PIDLIST_RELATIVE *ppidl,
425c2c66affSColin Finck DWORD *pdwAttributes)
426c2c66affSColin Finck {
427c2c66affSColin Finck TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
428c2c66affSColin Finck this, hwndOwner, pbc, lpszDisplayName, debugstr_w(lpszDisplayName),
429c2c66affSColin Finck pchEaten, ppidl, pdwAttributes);
430c2c66affSColin Finck
431c2c66affSColin Finck if (!ppidl)
432c2c66affSColin Finck return E_INVALIDARG;
433c2c66affSColin Finck
434c2c66affSColin Finck *ppidl = NULL;
435c2c66affSColin Finck
436c2c66affSColin Finck if (!lpszDisplayName)
437c2c66affSColin Finck return E_INVALIDARG;
438c2c66affSColin Finck
439d05dcf6aSKatayama Hirofumi MZ if (!*lpszDisplayName)
440d05dcf6aSKatayama Hirofumi MZ {
441d05dcf6aSKatayama Hirofumi MZ *ppidl = _ILCreateMyComputer();
442d05dcf6aSKatayama Hirofumi MZ return (*ppidl ? S_OK : E_OUTOFMEMORY);
443d05dcf6aSKatayama Hirofumi MZ }
444c2c66affSColin Finck
445c2c66affSColin Finck if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':')
446c2c66affSColin Finck {
447d05dcf6aSKatayama Hirofumi MZ return m_regFolder->ParseDisplayName(hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl,
448d05dcf6aSKatayama Hirofumi MZ pdwAttributes);
449c2c66affSColin Finck }
450d05dcf6aSKatayama Hirofumi MZ
451ff282894SKatayama Hirofumi MZ HRESULT hr = _ParseDisplayNameByParent(hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl,
452d05dcf6aSKatayama Hirofumi MZ pdwAttributes);
453c2c66affSColin Finck if (SUCCEEDED(hr))
454d05dcf6aSKatayama Hirofumi MZ {
455d05dcf6aSKatayama Hirofumi MZ if (BindCtx_ContainsObject(pbc, STR_PARSE_TRANSLATE_ALIASES))
456d05dcf6aSKatayama Hirofumi MZ {
457ff282894SKatayama Hirofumi MZ CComHeapPtr<ITEMIDLIST> pidlAlias;
458d05dcf6aSKatayama Hirofumi MZ if (SUCCEEDED(Shell_TranslateIDListAlias(*ppidl, NULL, &pidlAlias, 0xFFFF)))
459d05dcf6aSKatayama Hirofumi MZ {
460d05dcf6aSKatayama Hirofumi MZ ILFree(*ppidl);
461ff282894SKatayama Hirofumi MZ *ppidl = pidlAlias.Detach();
462d05dcf6aSKatayama Hirofumi MZ }
463d05dcf6aSKatayama Hirofumi MZ }
464ff282894SKatayama Hirofumi MZ
465ff282894SKatayama Hirofumi MZ TRACE ("(%p)->(-- ret=0x%08x)\n", this, hr);
466d05dcf6aSKatayama Hirofumi MZ return hr;
467d05dcf6aSKatayama Hirofumi MZ }
468d05dcf6aSKatayama Hirofumi MZ
469d05dcf6aSKatayama Hirofumi MZ if (Shell_FailForceReturn(hr))
470c2c66affSColin Finck return hr;
471c2c66affSColin Finck
472d05dcf6aSKatayama Hirofumi MZ if (BindCtx_ContainsObject(pbc, STR_DONT_PARSE_RELATIVE))
473d05dcf6aSKatayama Hirofumi MZ return E_INVALIDARG;
474c2c66affSColin Finck
475d05dcf6aSKatayama Hirofumi MZ if (SHIsFileSysBindCtx(pbc, NULL) == S_OK)
476d05dcf6aSKatayama Hirofumi MZ return hr;
477d05dcf6aSKatayama Hirofumi MZ
478d05dcf6aSKatayama Hirofumi MZ BIND_OPTS BindOps = { sizeof(BindOps) };
479d05dcf6aSKatayama Hirofumi MZ BOOL bCreate = FALSE;
480d05dcf6aSKatayama Hirofumi MZ if (pbc && SUCCEEDED(pbc->GetBindOptions(&BindOps)) && (BindOps.grfMode & STGM_CREATE))
481d05dcf6aSKatayama Hirofumi MZ {
482d05dcf6aSKatayama Hirofumi MZ BindOps.grfMode &= ~STGM_CREATE;
483d05dcf6aSKatayama Hirofumi MZ bCreate = TRUE;
484d05dcf6aSKatayama Hirofumi MZ pbc->SetBindOptions(&BindOps);
485c2c66affSColin Finck }
486c2c66affSColin Finck
487d05dcf6aSKatayama Hirofumi MZ if (m_DesktopFSFolder)
488c2c66affSColin Finck {
489d05dcf6aSKatayama Hirofumi MZ hr = m_DesktopFSFolder->ParseDisplayName(hwndOwner,
490d05dcf6aSKatayama Hirofumi MZ pbc,
491d05dcf6aSKatayama Hirofumi MZ lpszDisplayName,
492d05dcf6aSKatayama Hirofumi MZ pchEaten,
493d05dcf6aSKatayama Hirofumi MZ ppidl,
494d05dcf6aSKatayama Hirofumi MZ pdwAttributes);
495c2c66affSColin Finck }
496c2c66affSColin Finck
497d05dcf6aSKatayama Hirofumi MZ if (FAILED(hr) && m_SharedDesktopFSFolder)
498d05dcf6aSKatayama Hirofumi MZ {
499d05dcf6aSKatayama Hirofumi MZ hr = m_SharedDesktopFSFolder->ParseDisplayName(hwndOwner,
500d05dcf6aSKatayama Hirofumi MZ pbc,
501d05dcf6aSKatayama Hirofumi MZ lpszDisplayName,
502d05dcf6aSKatayama Hirofumi MZ pchEaten,
503d05dcf6aSKatayama Hirofumi MZ ppidl,
504d05dcf6aSKatayama Hirofumi MZ pdwAttributes);
505d05dcf6aSKatayama Hirofumi MZ }
506d05dcf6aSKatayama Hirofumi MZ
507d05dcf6aSKatayama Hirofumi MZ if (FAILED(hr) && bCreate && m_DesktopFSFolder)
508d05dcf6aSKatayama Hirofumi MZ {
509d05dcf6aSKatayama Hirofumi MZ BindOps.grfMode |= STGM_CREATE;
510d05dcf6aSKatayama Hirofumi MZ pbc->SetBindOptions(&BindOps);
511d05dcf6aSKatayama Hirofumi MZ hr = m_DesktopFSFolder->ParseDisplayName(hwndOwner,
512d05dcf6aSKatayama Hirofumi MZ pbc,
513d05dcf6aSKatayama Hirofumi MZ lpszDisplayName,
514d05dcf6aSKatayama Hirofumi MZ pchEaten,
515d05dcf6aSKatayama Hirofumi MZ ppidl,
516d05dcf6aSKatayama Hirofumi MZ pdwAttributes);
517d05dcf6aSKatayama Hirofumi MZ }
518c2c66affSColin Finck
519c2c66affSColin Finck TRACE ("(%p)->(-- ret=0x%08x)\n", this, hr);
520c2c66affSColin Finck
521c2c66affSColin Finck return hr;
522c2c66affSColin Finck }
523c2c66affSColin Finck
524c2c66affSColin Finck /**************************************************************************
525c2c66affSColin Finck * CDesktopFolder::EnumObjects
526c2c66affSColin Finck */
EnumObjects(HWND hwndOwner,DWORD dwFlags,LPENUMIDLIST * ppEnumIDList)527c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
528c2c66affSColin Finck {
529c2c66affSColin Finck CComPtr<IEnumIDList> pRegEnumerator;
530c2c66affSColin Finck CComPtr<IEnumIDList> pDesktopEnumerator;
531c2c66affSColin Finck CComPtr<IEnumIDList> pCommonDesktopEnumerator;
532c2c66affSColin Finck HRESULT hr;
533c2c66affSColin Finck
534c2c66affSColin Finck hr = m_regFolder->EnumObjects(hwndOwner, dwFlags, &pRegEnumerator);
535c2c66affSColin Finck if (FAILED(hr))
536c2c66affSColin Finck ERR("EnumObjects for reg folder failed\n");
537c2c66affSColin Finck
538c2c66affSColin Finck hr = m_DesktopFSFolder->EnumObjects(hwndOwner, dwFlags, &pDesktopEnumerator);
539c2c66affSColin Finck if (FAILED(hr))
540c2c66affSColin Finck ERR("EnumObjects for desktop fs folder failed\n");
541c2c66affSColin Finck
542c2c66affSColin Finck hr = m_SharedDesktopFSFolder->EnumObjects(hwndOwner, dwFlags, &pCommonDesktopEnumerator);
543c2c66affSColin Finck if (FAILED(hr))
544c2c66affSColin Finck ERR("EnumObjects for shared desktop fs folder failed\n");
545c2c66affSColin Finck
5466ae11ba0SWhindmar Saksit return ShellObjectCreatorInit<CDesktopFolderEnum>(m_regFolder, dwFlags, pRegEnumerator, pDesktopEnumerator,
5476ae11ba0SWhindmar Saksit pCommonDesktopEnumerator, IID_PPV_ARG(IEnumIDList, ppEnumIDList));
548c2c66affSColin Finck }
549c2c66affSColin Finck
550c2c66affSColin Finck /**************************************************************************
551c2c66affSColin Finck * CDesktopFolder::BindToObject
552c2c66affSColin Finck */
BindToObject(PCUIDLIST_RELATIVE pidl,LPBC pbcReserved,REFIID riid,LPVOID * ppvOut)553c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::BindToObject(
554c2c66affSColin Finck PCUIDLIST_RELATIVE pidl,
555c2c66affSColin Finck LPBC pbcReserved,
556c2c66affSColin Finck REFIID riid,
557c2c66affSColin Finck LPVOID *ppvOut)
558c2c66affSColin Finck {
559c2c66affSColin Finck if (!pidl)
560c2c66affSColin Finck return E_INVALIDARG;
561c2c66affSColin Finck
562c2c66affSColin Finck CComPtr<IShellFolder2> psf;
563c2c66affSColin Finck HRESULT hr = _GetSFFromPidl(pidl, &psf);
564c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
565c2c66affSColin Finck return hr;
566c2c66affSColin Finck
567c2c66affSColin Finck return psf->BindToObject(pidl, pbcReserved, riid, ppvOut);
568c2c66affSColin Finck }
569c2c66affSColin Finck
570c2c66affSColin Finck /**************************************************************************
571c2c66affSColin Finck * CDesktopFolder::BindToStorage
572c2c66affSColin Finck */
BindToStorage(PCUIDLIST_RELATIVE pidl,LPBC pbcReserved,REFIID riid,LPVOID * ppvOut)573c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::BindToStorage(
574c2c66affSColin Finck PCUIDLIST_RELATIVE pidl,
575c2c66affSColin Finck LPBC pbcReserved,
576c2c66affSColin Finck REFIID riid,
577c2c66affSColin Finck LPVOID *ppvOut)
578c2c66affSColin Finck {
579c2c66affSColin Finck FIXME ("(%p)->(pidl=%p,%p,%s,%p) stub\n",
580c2c66affSColin Finck this, pidl, pbcReserved, shdebugstr_guid (&riid), ppvOut);
581c2c66affSColin Finck
582c2c66affSColin Finck *ppvOut = NULL;
583c2c66affSColin Finck return E_NOTIMPL;
584c2c66affSColin Finck }
585c2c66affSColin Finck
586c2c66affSColin Finck /**************************************************************************
587c2c66affSColin Finck * CDesktopFolder::CompareIDs
588c2c66affSColin Finck */
CompareIDs(LPARAM lParam,PCUIDLIST_RELATIVE pidl1,PCUIDLIST_RELATIVE pidl2)589c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
590c2c66affSColin Finck {
591c2c66affSColin Finck bool bIsDesktopFolder1, bIsDesktopFolder2;
592c2c66affSColin Finck
593c2c66affSColin Finck if (!pidl1 || !pidl2)
594c2c66affSColin Finck {
595c2c66affSColin Finck ERR("Got null pidl pointer (%Ix %p %p)!\n", lParam, pidl1, pidl2);
596c2c66affSColin Finck return E_INVALIDARG;
597c2c66affSColin Finck }
598c2c66affSColin Finck
599c2c66affSColin Finck bIsDesktopFolder1 = _ILIsDesktop(pidl1);
600c2c66affSColin Finck bIsDesktopFolder2 = _ILIsDesktop(pidl2);
601c2c66affSColin Finck if (bIsDesktopFolder1 || bIsDesktopFolder2)
602c2c66affSColin Finck return MAKE_COMPARE_HRESULT(bIsDesktopFolder1 - bIsDesktopFolder2);
603c2c66affSColin Finck
604c2c66affSColin Finck if (_ILIsSpecialFolder(pidl1) || _ILIsSpecialFolder(pidl2))
605c2c66affSColin Finck return m_regFolder->CompareIDs(lParam, pidl1, pidl2);
606c2c66affSColin Finck
607c2c66affSColin Finck return m_DesktopFSFolder->CompareIDs(lParam, pidl1, pidl2);
608c2c66affSColin Finck }
609c2c66affSColin Finck
610c2c66affSColin Finck /**************************************************************************
611c2c66affSColin Finck * CDesktopFolder::CreateViewObject
612c2c66affSColin Finck */
CreateViewObject(HWND hwndOwner,REFIID riid,LPVOID * ppvOut)613c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::CreateViewObject(
614c2c66affSColin Finck HWND hwndOwner,
615c2c66affSColin Finck REFIID riid,
616c2c66affSColin Finck LPVOID *ppvOut)
617c2c66affSColin Finck {
618c2c66affSColin Finck HRESULT hr = E_INVALIDARG;
619c2c66affSColin Finck
620c2c66affSColin Finck TRACE ("(%p)->(hwnd=%p,%s,%p)\n",
621c2c66affSColin Finck this, hwndOwner, shdebugstr_guid (&riid), ppvOut);
622c2c66affSColin Finck
623c2c66affSColin Finck if (!ppvOut)
624c2c66affSColin Finck return hr;
625c2c66affSColin Finck
626c2c66affSColin Finck *ppvOut = NULL;
627c2c66affSColin Finck
628c2c66affSColin Finck if (IsEqualIID (riid, IID_IDropTarget))
629c2c66affSColin Finck {
630c2c66affSColin Finck hr = m_DesktopFSFolder->CreateViewObject(hwndOwner, riid, ppvOut);
631c2c66affSColin Finck }
632c2c66affSColin Finck else if (IsEqualIID (riid, IID_IContextMenu))
633c2c66affSColin Finck {
634c2c66affSColin Finck HKEY hKeys[16];
635c2c66affSColin Finck UINT cKeys = 0;
636c2c66affSColin Finck AddClassKeyToArray(L"Directory\\Background", hKeys, &cKeys);
637c2c66affSColin Finck
638c2c66affSColin Finck DEFCONTEXTMENU dcm;
639c2c66affSColin Finck dcm.hwnd = hwndOwner;
640c2c66affSColin Finck dcm.pcmcb = this;
641c2c66affSColin Finck dcm.pidlFolder = pidlRoot;
642c2c66affSColin Finck dcm.psf = this;
643c2c66affSColin Finck dcm.cidl = 0;
644c2c66affSColin Finck dcm.apidl = NULL;
645c2c66affSColin Finck dcm.cKeys = cKeys;
646c2c66affSColin Finck dcm.aKeys = hKeys;
647c2c66affSColin Finck dcm.punkAssociationInfo = NULL;
648c2c66affSColin Finck hr = SHCreateDefaultContextMenu (&dcm, riid, ppvOut);
649c2c66affSColin Finck }
650c2c66affSColin Finck else if (IsEqualIID (riid, IID_IShellView))
651c2c66affSColin Finck {
6526ae11ba0SWhindmar Saksit CComPtr<CDesktopFolderViewCB> sfviewcb;
6536ae11ba0SWhindmar Saksit if (SUCCEEDED(hr = ShellObjectCreator(sfviewcb)))
6546ae11ba0SWhindmar Saksit {
6556ae11ba0SWhindmar Saksit SFV_CREATE create = { sizeof(create), this, NULL, sfviewcb };
6566ae11ba0SWhindmar Saksit hr = SHCreateShellFolderView(&create, (IShellView**)ppvOut);
6576ae11ba0SWhindmar Saksit if (SUCCEEDED(hr))
6586ae11ba0SWhindmar Saksit sfviewcb->Initialize((IShellView*)*ppvOut);
6596ae11ba0SWhindmar Saksit }
660c2c66affSColin Finck }
661c2c66affSColin Finck TRACE ("-- (%p)->(interface=%p)\n", this, ppvOut);
662c2c66affSColin Finck return hr;
663c2c66affSColin Finck }
664c2c66affSColin Finck
665c2c66affSColin Finck /**************************************************************************
666c2c66affSColin Finck * CDesktopFolder::GetAttributesOf
667c2c66affSColin Finck */
GetAttributesOf(UINT cidl,PCUITEMID_CHILD_ARRAY apidl,DWORD * rgfInOut)668c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetAttributesOf(
669c2c66affSColin Finck UINT cidl,
670c2c66affSColin Finck PCUITEMID_CHILD_ARRAY apidl,
671c2c66affSColin Finck DWORD *rgfInOut)
672c2c66affSColin Finck {
673c2c66affSColin Finck HRESULT hr = S_OK;
674c2c66affSColin Finck
675c2c66affSColin Finck TRACE("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
676c2c66affSColin Finck this, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
677c2c66affSColin Finck
678c2c66affSColin Finck if (cidl && !apidl)
679c2c66affSColin Finck return E_INVALIDARG;
680c2c66affSColin Finck
681c2c66affSColin Finck if (*rgfInOut == 0)
682c2c66affSColin Finck *rgfInOut = ~0;
683c2c66affSColin Finck
684c2c66affSColin Finck if(cidl == 0)
685c2c66affSColin Finck *rgfInOut &= dwDesktopAttributes;
686c2c66affSColin Finck else
687c2c66affSColin Finck {
688c2c66affSColin Finck /* TODO: always add SFGAO_CANLINK */
689c2c66affSColin Finck for (UINT i = 0; i < cidl; ++i)
690c2c66affSColin Finck {
691c2c66affSColin Finck pdump(*apidl);
692c2c66affSColin Finck if (_ILIsDesktop(*apidl))
693c2c66affSColin Finck *rgfInOut &= dwDesktopAttributes;
694c2c66affSColin Finck else if (_ILIsMyComputer(apidl[i]))
695c2c66affSColin Finck *rgfInOut &= dwMyComputerAttributes;
696c2c66affSColin Finck else if (_ILIsNetHood(apidl[i]))
697c2c66affSColin Finck *rgfInOut &= dwMyNetPlacesAttributes;
698c2c66affSColin Finck else if (_ILIsFolder(apidl[i]) || _ILIsValue(apidl[i]) || _ILIsSpecialFolder(apidl[i]))
699c2c66affSColin Finck {
700c2c66affSColin Finck CComPtr<IShellFolder2> psf;
701c2c66affSColin Finck HRESULT hr = _GetSFFromPidl(apidl[i], &psf);
702c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
703c2c66affSColin Finck continue;
704c2c66affSColin Finck
705c2c66affSColin Finck psf->GetAttributesOf(1, &apidl[i], rgfInOut);
706c2c66affSColin Finck }
707c2c66affSColin Finck else
708c2c66affSColin Finck ERR("Got an unknown pidl type!!!\n");
709c2c66affSColin Finck }
710c2c66affSColin Finck }
711c2c66affSColin Finck /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
712c2c66affSColin Finck *rgfInOut &= ~SFGAO_VALIDATE;
713c2c66affSColin Finck
714c2c66affSColin Finck TRACE("-- result=0x%08x\n", *rgfInOut);
715c2c66affSColin Finck
716c2c66affSColin Finck return hr;
717c2c66affSColin Finck }
718c2c66affSColin Finck
719c2c66affSColin Finck /**************************************************************************
720c2c66affSColin Finck * CDesktopFolder::GetUIObjectOf
721c2c66affSColin Finck *
722c2c66affSColin Finck * PARAMETERS
723c2c66affSColin Finck * HWND hwndOwner, //[in ] Parent window for any output
724c2c66affSColin Finck * UINT cidl, //[in ] array size
725c2c66affSColin Finck * LPCITEMIDLIST* apidl, //[in ] simple pidl array
726c2c66affSColin Finck * REFIID riid, //[in ] Requested Interface
727c2c66affSColin Finck * UINT* prgfInOut, //[ ] reserved
728c2c66affSColin Finck * LPVOID* ppvObject) //[out] Resulting Interface
729c2c66affSColin Finck *
730c2c66affSColin Finck */
GetUIObjectOf(HWND hwndOwner,UINT cidl,PCUITEMID_CHILD_ARRAY apidl,REFIID riid,UINT * prgfInOut,LPVOID * ppvOut)731c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetUIObjectOf(
732c2c66affSColin Finck HWND hwndOwner,
733c2c66affSColin Finck UINT cidl,
734c2c66affSColin Finck PCUITEMID_CHILD_ARRAY apidl,
735c2c66affSColin Finck REFIID riid,
736c2c66affSColin Finck UINT *prgfInOut,
737c2c66affSColin Finck LPVOID *ppvOut)
738c2c66affSColin Finck {
739c2c66affSColin Finck LPVOID pObj = NULL;
740c2c66affSColin Finck HRESULT hr = E_INVALIDARG;
741c2c66affSColin Finck
742c2c66affSColin Finck TRACE ("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n",
743c2c66affSColin Finck this, hwndOwner, cidl, apidl, shdebugstr_guid (&riid), prgfInOut, ppvOut);
744c2c66affSColin Finck
745c2c66affSColin Finck if (!ppvOut)
746c2c66affSColin Finck return hr;
747c2c66affSColin Finck *ppvOut = NULL;
748c2c66affSColin Finck
74963935f85SWhindmar Saksit BOOL self = IsSelf(cidl, apidl);
75063935f85SWhindmar Saksit if (cidl == 1 && !_ILIsSpecialFolder(apidl[0]) && !self)
751c2c66affSColin Finck {
752c2c66affSColin Finck CComPtr<IShellFolder2> psf;
753c2c66affSColin Finck HRESULT hr = _GetSFFromPidl(apidl[0], &psf);
754c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
755c2c66affSColin Finck return hr;
756c2c66affSColin Finck
757c2c66affSColin Finck return psf->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, ppvOut);
758c2c66affSColin Finck }
759c2c66affSColin Finck
760c2c66affSColin Finck if (IsEqualIID (riid, IID_IContextMenu))
761c2c66affSColin Finck {
76263935f85SWhindmar Saksit // FIXME: m_regFolder vs AddFSClassKeysToArray is incorrect when the selection includes both regitems and FS items
76363935f85SWhindmar Saksit if (!self && cidl > 0 && _ILIsSpecialFolder(apidl[0]))
764c2c66affSColin Finck {
765c2c66affSColin Finck hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
766c2c66affSColin Finck }
767c2c66affSColin Finck else
768c2c66affSColin Finck {
769c2c66affSColin Finck /* Do not use the context menu of the CFSFolder here. */
770c2c66affSColin Finck /* We need to pass a pointer of the CDesktopFolder so as the data object that the context menu gets is rooted to the desktop */
771c2c66affSColin Finck /* Otherwise operations like that involve items from both user and shared desktop will not work */
772c2c66affSColin Finck HKEY hKeys[16];
773c2c66affSColin Finck UINT cKeys = 0;
77463935f85SWhindmar Saksit if (self)
77563935f85SWhindmar Saksit {
77663935f85SWhindmar Saksit AddClsidKeyToArray(CLSID_ShellDesktop, hKeys, &cKeys);
77763935f85SWhindmar Saksit AddClassKeyToArray(L"Folder", hKeys, &cKeys);
77863935f85SWhindmar Saksit }
77963935f85SWhindmar Saksit else if (cidl > 0)
7800d077c30SIoannis Adamopoulos {
781a83e40f6SWhindmar Saksit AddFSClassKeysToArray(cidl, apidl, hKeys, &cKeys);
7820d077c30SIoannis Adamopoulos }
783c2c66affSColin Finck
784c2c66affSColin Finck DEFCONTEXTMENU dcm;
785c2c66affSColin Finck dcm.hwnd = hwndOwner;
786c2c66affSColin Finck dcm.pcmcb = this;
787c2c66affSColin Finck dcm.pidlFolder = pidlRoot;
788c2c66affSColin Finck dcm.psf = this;
789c2c66affSColin Finck dcm.cidl = cidl;
790c2c66affSColin Finck dcm.apidl = apidl;
791c2c66affSColin Finck dcm.cKeys = cKeys;
792c2c66affSColin Finck dcm.aKeys = hKeys;
793c2c66affSColin Finck dcm.punkAssociationInfo = NULL;
794c2c66affSColin Finck hr = SHCreateDefaultContextMenu (&dcm, riid, &pObj);
795c2c66affSColin Finck }
796c2c66affSColin Finck }
797c2c66affSColin Finck else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1))
798c2c66affSColin Finck {
799c3132711SMark Jansen hr = IDataObject_Constructor( hwndOwner, pidlRoot, apidl, cidl, TRUE, (IDataObject **)&pObj);
800c2c66affSColin Finck }
801c2c66affSColin Finck else if ((IsEqualIID (riid, IID_IExtractIconA) || IsEqualIID (riid, IID_IExtractIconW)) && (cidl == 1))
802c2c66affSColin Finck {
803c2c66affSColin Finck hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
804c2c66affSColin Finck }
805c2c66affSColin Finck else if (IsEqualIID (riid, IID_IDropTarget) && (cidl == 1))
806c2c66affSColin Finck {
807c2c66affSColin Finck CComPtr<IShellFolder> psfChild;
808c2c66affSColin Finck hr = this->BindToObject(apidl[0], NULL, IID_PPV_ARG(IShellFolder, &psfChild));
809c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
810c2c66affSColin Finck return hr;
811c2c66affSColin Finck
812c2c66affSColin Finck return psfChild->CreateViewObject(NULL, riid, ppvOut);
813c2c66affSColin Finck }
814c2c66affSColin Finck else
815c2c66affSColin Finck hr = E_NOINTERFACE;
816c2c66affSColin Finck
817c2c66affSColin Finck if (SUCCEEDED(hr) && !pObj)
818c2c66affSColin Finck hr = E_OUTOFMEMORY;
819c2c66affSColin Finck
820c2c66affSColin Finck *ppvOut = pObj;
821c2c66affSColin Finck TRACE ("(%p)->hr=0x%08x\n", this, hr);
822c2c66affSColin Finck return hr;
823c2c66affSColin Finck }
824c2c66affSColin Finck
825c2c66affSColin Finck /**************************************************************************
826c2c66affSColin Finck * CDesktopFolder::GetDisplayNameOf
827c2c66affSColin Finck *
828c2c66affSColin Finck * NOTES
829c2c66affSColin Finck * special case: pidl = null gives desktop-name back
830c2c66affSColin Finck */
GetDisplayNameOf(PCUITEMID_CHILD pidl,DWORD dwFlags,LPSTRRET strRet)831c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet)
832c2c66affSColin Finck {
833c2c66affSColin Finck TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet);
834c2c66affSColin Finck pdump (pidl);
835c2c66affSColin Finck
836c2c66affSColin Finck if (!strRet)
837c2c66affSColin Finck return E_INVALIDARG;
838c2c66affSColin Finck
839c2c66affSColin Finck if (!_ILIsPidlSimple (pidl))
840c2c66affSColin Finck {
841c2c66affSColin Finck return SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, strRet);
842c2c66affSColin Finck }
843c2c66affSColin Finck else if (_ILIsDesktop(pidl))
844c2c66affSColin Finck {
8454da2e783SWhindmar Saksit if (IS_SHGDN_DESKTOPABSOLUTEPARSING(dwFlags))
846c2c66affSColin Finck return SHSetStrRet(strRet, sPathTarget);
847c2c66affSColin Finck else
848c2c66affSColin Finck return m_regFolder->GetDisplayNameOf(pidl, dwFlags, strRet);
849c2c66affSColin Finck }
850c2c66affSColin Finck
851c2c66affSColin Finck /* file system folder or file rooted at the desktop */
852c2c66affSColin Finck CComPtr<IShellFolder2> psf;
853c2c66affSColin Finck HRESULT hr = _GetSFFromPidl(pidl, &psf);
854c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
855c2c66affSColin Finck return hr;
856c2c66affSColin Finck
857c2c66affSColin Finck return psf->GetDisplayNameOf(pidl, dwFlags, strRet);
858c2c66affSColin Finck }
859c2c66affSColin Finck
860c2c66affSColin Finck /**************************************************************************
861c2c66affSColin Finck * CDesktopFolder::SetNameOf
862c2c66affSColin Finck * Changes the name of a file object or subfolder, possibly changing its item
863c2c66affSColin Finck * identifier in the process.
864c2c66affSColin Finck *
865c2c66affSColin Finck * PARAMETERS
866c2c66affSColin Finck * HWND hwndOwner, //[in ] Owner window for output
867c2c66affSColin Finck * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
868c2c66affSColin Finck * LPCOLESTR lpszName, //[in ] the items new display name
869c2c66affSColin Finck * DWORD dwFlags, //[in ] SHGNO formatting flags
870c2c66affSColin Finck * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
871c2c66affSColin Finck */
SetNameOf(HWND hwndOwner,PCUITEMID_CHILD pidl,LPCOLESTR lpName,DWORD dwFlags,PITEMID_CHILD * pPidlOut)872c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::SetNameOf(
873c2c66affSColin Finck HWND hwndOwner,
874c2c66affSColin Finck PCUITEMID_CHILD pidl, /* simple pidl */
875c2c66affSColin Finck LPCOLESTR lpName,
876c2c66affSColin Finck DWORD dwFlags,
877c2c66affSColin Finck PITEMID_CHILD *pPidlOut)
878c2c66affSColin Finck {
879c2c66affSColin Finck CComPtr<IShellFolder2> psf;
880c2c66affSColin Finck HRESULT hr = _GetSFFromPidl(pidl, &psf);
881c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
882c2c66affSColin Finck return hr;
883c2c66affSColin Finck
884c2c66affSColin Finck return psf->SetNameOf(hwndOwner, pidl, lpName, dwFlags, pPidlOut);
885c2c66affSColin Finck }
886c2c66affSColin Finck
GetDefaultSearchGUID(GUID * pguid)887c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetDefaultSearchGUID(GUID *pguid)
888c2c66affSColin Finck {
889c2c66affSColin Finck FIXME ("(%p)\n", this);
890c2c66affSColin Finck return E_NOTIMPL;
891c2c66affSColin Finck }
892c2c66affSColin Finck
EnumSearches(IEnumExtraSearch ** ppenum)893c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::EnumSearches(IEnumExtraSearch **ppenum)
894c2c66affSColin Finck {
895c2c66affSColin Finck FIXME ("(%p)\n", this);
896c2c66affSColin Finck return E_NOTIMPL;
897c2c66affSColin Finck }
898c2c66affSColin Finck
GetDefaultColumn(DWORD dwRes,ULONG * pSort,ULONG * pDisplay)899c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetDefaultColumn(DWORD dwRes, ULONG *pSort, ULONG *pDisplay)
900c2c66affSColin Finck {
901c2c66affSColin Finck TRACE ("(%p)\n", this);
902c2c66affSColin Finck
903c2c66affSColin Finck if (pSort)
904c2c66affSColin Finck *pSort = 0;
905c2c66affSColin Finck if (pDisplay)
906c2c66affSColin Finck *pDisplay = 0;
907c2c66affSColin Finck
908c2c66affSColin Finck return S_OK;
909c2c66affSColin Finck }
910c2c66affSColin Finck
GetDefaultColumnState(UINT iColumn,SHCOLSTATEF * pcsFlags)9113693d554SDoug Lyons HRESULT WINAPI CDesktopFolder::GetDefaultColumnState(UINT iColumn, SHCOLSTATEF *pcsFlags)
912c2c66affSColin Finck {
9133693d554SDoug Lyons HRESULT hr;
914c2c66affSColin Finck TRACE ("(%p)\n", this);
915c2c66affSColin Finck
9163693d554SDoug Lyons if (!pcsFlags)
917c2c66affSColin Finck return E_INVALIDARG;
918c2c66affSColin Finck
9193693d554SDoug Lyons hr = CFSFolder::GetDefaultFSColumnState(iColumn, *pcsFlags);
9203693d554SDoug Lyons /*
9213693d554SDoug Lyons // CDesktopFolder may override the flags if desired (future)
9223693d554SDoug Lyons switch(iColumn)
9233693d554SDoug Lyons {
9243693d554SDoug Lyons case SHFSF_COL_FATTS:
9253693d554SDoug Lyons *pcsFlags &= ~SHCOLSTATE_ONBYDEFAULT;
9263693d554SDoug Lyons break;
9273693d554SDoug Lyons }
9283693d554SDoug Lyons */
9293693d554SDoug Lyons return hr;
930c2c66affSColin Finck }
931c2c66affSColin Finck
GetDetailsEx(PCUITEMID_CHILD pidl,const SHCOLUMNID * pscid,VARIANT * pv)932c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetDetailsEx(
933c2c66affSColin Finck PCUITEMID_CHILD pidl,
934c2c66affSColin Finck const SHCOLUMNID *pscid,
935c2c66affSColin Finck VARIANT *pv)
936c2c66affSColin Finck {
937c2c66affSColin Finck FIXME ("(%p)\n", this);
938c2c66affSColin Finck
939c2c66affSColin Finck return E_NOTIMPL;
940c2c66affSColin Finck }
941c2c66affSColin Finck
9423693d554SDoug Lyons /*************************************************************************
9433693d554SDoug Lyons * Column info functions.
9443693d554SDoug Lyons * CFSFolder.h provides defaults for us.
9453693d554SDoug Lyons */
GetColumnDetails(UINT iColumn,SHELLDETAILS & sd)9463693d554SDoug Lyons HRESULT CDesktopFolder::GetColumnDetails(UINT iColumn, SHELLDETAILS &sd)
9473693d554SDoug Lyons {
9483693d554SDoug Lyons /* CDesktopFolder may override the flags and/or name if desired */
9493693d554SDoug Lyons return CFSFolder::GetFSColumnDetails(iColumn, sd);
9503693d554SDoug Lyons }
9513693d554SDoug Lyons
GetDetailsOf(PCUITEMID_CHILD pidl,UINT iColumn,SHELLDETAILS * psd)952c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetDetailsOf(
953c2c66affSColin Finck PCUITEMID_CHILD pidl,
954c2c66affSColin Finck UINT iColumn,
955c2c66affSColin Finck SHELLDETAILS *psd)
956c2c66affSColin Finck {
9573693d554SDoug Lyons if (!psd)
958c2c66affSColin Finck return E_INVALIDARG;
959c2c66affSColin Finck
960c2c66affSColin Finck if (!pidl)
961c2c66affSColin Finck {
9623693d554SDoug Lyons return GetColumnDetails(iColumn, *psd);
963c2c66affSColin Finck }
964c2c66affSColin Finck
965c2c66affSColin Finck CComPtr<IShellFolder2> psf;
966c2c66affSColin Finck HRESULT hr = _GetSFFromPidl(pidl, &psf);
967c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
968c2c66affSColin Finck return hr;
969c2c66affSColin Finck
970c2c66affSColin Finck hr = psf->GetDetailsOf(pidl, iColumn, psd);
971c2c66affSColin Finck if (FAILED_UNEXPECTEDLY(hr))
972c2c66affSColin Finck return hr;
973c2c66affSColin Finck
974c2c66affSColin Finck return hr;
975c2c66affSColin Finck }
976c2c66affSColin Finck
MapColumnToSCID(UINT column,SHCOLUMNID * pscid)977c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::MapColumnToSCID(UINT column, SHCOLUMNID *pscid)
978c2c66affSColin Finck {
979c2c66affSColin Finck FIXME ("(%p)\n", this);
980c2c66affSColin Finck return E_NOTIMPL;
981c2c66affSColin Finck }
982c2c66affSColin Finck
GetClassID(CLSID * lpClassId)983c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetClassID(CLSID *lpClassId)
984c2c66affSColin Finck {
985c2c66affSColin Finck TRACE ("(%p)\n", this);
986c2c66affSColin Finck
987c2c66affSColin Finck if (!lpClassId)
988c2c66affSColin Finck return E_POINTER;
989c2c66affSColin Finck
990c2c66affSColin Finck *lpClassId = CLSID_ShellDesktop;
991c2c66affSColin Finck
992c2c66affSColin Finck return S_OK;
993c2c66affSColin Finck }
994c2c66affSColin Finck
Initialize(PCIDLIST_ABSOLUTE pidl)9956b0d2c2aSThomas Faber HRESULT WINAPI CDesktopFolder::Initialize(PCIDLIST_ABSOLUTE pidl)
996c2c66affSColin Finck {
997c2c66affSColin Finck TRACE ("(%p)->(%p)\n", this, pidl);
998c2c66affSColin Finck
9997e48c20bSGiannis Adamopoulos if (!pidl)
10007e48c20bSGiannis Adamopoulos return S_OK;
10017e48c20bSGiannis Adamopoulos
1002c2c66affSColin Finck return E_INVALIDARG;
1003c2c66affSColin Finck }
1004c2c66affSColin Finck
GetCurFolder(PIDLIST_ABSOLUTE * pidl)1005b90c24d6SThomas Faber HRESULT WINAPI CDesktopFolder::GetCurFolder(PIDLIST_ABSOLUTE * pidl)
1006c2c66affSColin Finck {
1007c2c66affSColin Finck TRACE ("(%p)->(%p)\n", this, pidl);
1008c2c66affSColin Finck
1009c2c66affSColin Finck if (!pidl)
1010c2c66affSColin Finck return E_INVALIDARG; /* xp doesn't have this check and crashes on NULL */
1011c2c66affSColin Finck *pidl = ILClone (pidlRoot);
1012c2c66affSColin Finck return S_OK;
1013c2c66affSColin Finck }
1014c2c66affSColin Finck
CallBack(IShellFolder * psf,HWND hwndOwner,IDataObject * pdtobj,UINT uMsg,WPARAM wParam,LPARAM lParam)1015c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam)
1016c2c66affSColin Finck {
1017daf80680SWhindmar Saksit enum { IDC_PROPERTIES };
101863935f85SWhindmar Saksit if (uMsg == DFM_INVOKECOMMAND && wParam == (pdtobj ? DFM_CMD_PROPERTIES : IDC_PROPERTIES))
1019c2c66affSColin Finck {
1020daf80680SWhindmar Saksit return SHELL_ExecuteControlPanelCPL(hwndOwner, L"desk.cpl") ? S_OK : E_FAIL;
1021c2c66affSColin Finck }
102263935f85SWhindmar Saksit else if (uMsg == DFM_MERGECONTEXTMENU && !pdtobj) // Add Properties item when called for directory background
1023c2c66affSColin Finck {
1024c2c66affSColin Finck QCMINFO *pqcminfo = (QCMINFO *)lParam;
1025c2c66affSColin Finck HMENU hpopup = CreatePopupMenu();
1026daf80680SWhindmar Saksit _InsertMenuItemW(hpopup, 0, TRUE, IDC_PROPERTIES, MFT_STRING, MAKEINTRESOURCEW(IDS_PROPERTIES), MFS_ENABLED);
1027daf80680SWhindmar Saksit pqcminfo->idCmdFirst = Shell_MergeMenus(pqcminfo->hmenu, hpopup, pqcminfo->indexMenu, pqcminfo->idCmdFirst, pqcminfo->idCmdLast, MM_ADDSEPARATOR);
1028c2c66affSColin Finck DestroyMenu(hpopup);
1029c2c66affSColin Finck return S_OK;
1030c2c66affSColin Finck }
1031daf80680SWhindmar Saksit return SHELL32_DefaultContextMenuCallBack(psf, pdtobj, uMsg);
1032c2c66affSColin Finck }
1033c2c66affSColin Finck
1034c2c66affSColin Finck /*************************************************************************
10356ae11ba0SWhindmar Saksit * CDesktopFolderViewCB
10366ae11ba0SWhindmar Saksit */
10376ae11ba0SWhindmar Saksit
IsProgmanHostedBrowser(IShellView * psv)10386ae11ba0SWhindmar Saksit bool CDesktopFolderViewCB::IsProgmanHostedBrowser(IShellView *psv)
10396ae11ba0SWhindmar Saksit {
10406ae11ba0SWhindmar Saksit FOLDERSETTINGS settings;
10416ae11ba0SWhindmar Saksit return SUCCEEDED(psv->GetCurrentInfo(&settings)) && (settings.fFlags & FWF_DESKTOP);
10426ae11ba0SWhindmar Saksit }
10436ae11ba0SWhindmar Saksit
IsProgmanHostedBrowser()10446ae11ba0SWhindmar Saksit bool CDesktopFolderViewCB::IsProgmanHostedBrowser()
10456ae11ba0SWhindmar Saksit {
10466ae11ba0SWhindmar Saksit enum { Uninitialized = 0, NotHosted, IsHosted };
10476ae11ba0SWhindmar Saksit C_ASSERT(Uninitialized == 0);
10486ae11ba0SWhindmar Saksit if (m_IsProgmanHosted == Uninitialized)
10496ae11ba0SWhindmar Saksit m_IsProgmanHosted = m_pShellView && IsProgmanHostedBrowser(m_pShellView) ? IsHosted : NotHosted;
10506ae11ba0SWhindmar Saksit return m_IsProgmanHosted == IsHosted;
10516ae11ba0SWhindmar Saksit }
10526ae11ba0SWhindmar Saksit
ShouldShow(IShellFolder * psf,PCIDLIST_ABSOLUTE pidlFolder,PCUITEMID_CHILD pidlItem)10536ae11ba0SWhindmar Saksit HRESULT WINAPI CDesktopFolderViewCB::ShouldShow(IShellFolder *psf, PCIDLIST_ABSOLUTE pidlFolder, PCUITEMID_CHILD pidlItem)
10546ae11ba0SWhindmar Saksit {
10556ae11ba0SWhindmar Saksit const CLSID* pClsid;
10566ae11ba0SWhindmar Saksit if (IsProgmanHostedBrowser() && (pClsid = IsRegItem(pidlItem)) != NULL)
10576ae11ba0SWhindmar Saksit {
10586ae11ba0SWhindmar Saksit const BOOL NewStart = SHELL_GetSetting(SSF_STARTPANELON, fStartPanelOn);
10596ae11ba0SWhindmar Saksit LPCWSTR SubKey = NewStart ? L"HideDesktopIcons\\NewStartPanel" : L"HideDesktopIcons\\ClassicStartMenu";
10606ae11ba0SWhindmar Saksit return SHELL32_IsShellFolderNamespaceItemHidden(SubKey, *pClsid) ? S_FALSE : S_OK;
10616ae11ba0SWhindmar Saksit }
10626ae11ba0SWhindmar Saksit return S_OK;
10636ae11ba0SWhindmar Saksit }
10646ae11ba0SWhindmar Saksit
MessageSFVCB(UINT uMsg,WPARAM wParam,LPARAM lParam)10656ae11ba0SWhindmar Saksit HRESULT WINAPI CDesktopFolderViewCB::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam)
10666ae11ba0SWhindmar Saksit {
10676ae11ba0SWhindmar Saksit switch (uMsg)
10686ae11ba0SWhindmar Saksit {
10696ae11ba0SWhindmar Saksit case SFVM_VIEWRELEASE:
10706ae11ba0SWhindmar Saksit m_pShellView = NULL;
10716ae11ba0SWhindmar Saksit return S_OK;
1072*a17b6e93SWhindmar Saksit case SFVM_GETCOMMANDDIR:
1073*a17b6e93SWhindmar Saksit {
1074*a17b6e93SWhindmar Saksit WCHAR buf[MAX_PATH];
1075*a17b6e93SWhindmar Saksit if (SHGetSpecialFolderPathW(NULL, buf, CSIDL_DESKTOPDIRECTORY, TRUE))
1076*a17b6e93SWhindmar Saksit return StringCchCopyW((PWSTR)lParam, wParam, buf);
1077*a17b6e93SWhindmar Saksit break;
1078*a17b6e93SWhindmar Saksit }
10796ae11ba0SWhindmar Saksit }
10806ae11ba0SWhindmar Saksit return E_NOTIMPL;
10816ae11ba0SWhindmar Saksit }
10826ae11ba0SWhindmar Saksit
10836ae11ba0SWhindmar Saksit /*************************************************************************
1084c2c66affSColin Finck * SHGetDesktopFolder [SHELL32.@]
1085c2c66affSColin Finck */
SHGetDesktopFolder(IShellFolder ** psf)1086c2c66affSColin Finck HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
1087c2c66affSColin Finck {
1088c2c66affSColin Finck HRESULT hres = S_OK;
1089c2c66affSColin Finck TRACE("\n");
1090c2c66affSColin Finck
1091c2c66affSColin Finck if(!psf) return E_INVALIDARG;
1092c2c66affSColin Finck *psf = NULL;
1093c2c66affSColin Finck hres = CDesktopFolder::_CreatorClass::CreateInstance(NULL, IID_PPV_ARG(IShellFolder, psf));
1094c2c66affSColin Finck
1095c2c66affSColin Finck TRACE("-- %p->(%p)\n",psf, *psf);
1096c2c66affSColin Finck return hres;
1097c2c66affSColin Finck }
1098