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