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>
24c2c66affSColin Finck 
25c2c66affSColin Finck WINE_DEFAULT_DEBUG_CHANNEL(shell);
26c2c66affSColin Finck 
27c2c66affSColin Finck /*
28c2c66affSColin Finck CDesktopFolder should create two file system folders internally, one representing the
29c2c66affSColin Finck user's desktop folder, and the other representing the common desktop folder. It should
30c2c66affSColin Finck also create a CRegFolder to represent the virtual items that exist only in the registry.
31c2c66affSColin Finck The CRegFolder is aggregated by the CDesktopFolder, and queries for the CLSID_IShellFolder,
32c2c66affSColin Finck CLSID_IShellFolder2, or CLSID_IShellIconOverlay interfaces prefer the CRegFolder
33c2c66affSColin Finck implementation.
34c2c66affSColin Finck The CDesktopFolderEnum class should create two enumerators, one for each of the file
35c2c66affSColin Finck system folders, and enumerate the contents of each folder. Since the CRegFolder
36c2c66affSColin Finck implementation of IShellFolder::EnumObjects enumerates the virtual items, the
37c2c66affSColin Finck CDesktopFolderEnum is only responsible for returning the physical items.
38c2c66affSColin Finck CDesktopFolderEnum is incorrect where it filters My Computer from the enumeration
39c2c66affSColin Finck if the new start menu is used. The CDesktopViewCallback is responsible for filtering
40c2c66affSColin Finck it from the view by handling the IncludeObject query to return S_FALSE. The enumerator
41c2c66affSColin Finck always shows My Computer.
42c2c66affSColin Finck */
43c2c66affSColin Finck 
44c2c66affSColin Finck /* Undocumented functions from shdocvw */
45c2c66affSColin Finck extern "C" HRESULT WINAPI IEParseDisplayNameWithBCW(DWORD codepage, LPCWSTR lpszDisplayName, LPBC pbc, LPITEMIDLIST *ppidl);
46c2c66affSColin Finck 
47c2c66affSColin Finck static const WCHAR ClassicStartMenuW[] = L"SOFTWARE\\Microsoft\\Windows\\"
48c2c66affSColin Finck     L"CurrentVersion\\Explorer\\HideDesktopIcons\\ClassicStartMenu";
49c2c66affSColin Finck 
50c2c66affSColin Finck static INT
51c2c66affSColin Finck IsNamespaceExtensionHidden(const WCHAR *iid)
52c2c66affSColin Finck {
53c2c66affSColin Finck     DWORD Result, dwResult;
54c2c66affSColin Finck     dwResult = sizeof(DWORD);
55c2c66affSColin Finck 
56c2c66affSColin Finck     if (RegGetValueW(HKEY_CURRENT_USER, /* FIXME use NewStartPanel when activated */
57c2c66affSColin Finck                      ClassicStartMenuW,
58c2c66affSColin Finck                      iid,
59c2c66affSColin Finck                      RRF_RT_DWORD,
60c2c66affSColin Finck                      NULL,
61c2c66affSColin Finck                      &Result,
62c2c66affSColin Finck                      &dwResult) != ERROR_SUCCESS)
63c2c66affSColin Finck     {
64c2c66affSColin Finck         return -1;
65c2c66affSColin Finck     }
66c2c66affSColin Finck 
67c2c66affSColin Finck     return Result;
68c2c66affSColin Finck }
69c2c66affSColin Finck 
70c2c66affSColin Finck static INT IsNamespaceExtensionHidden(LPCITEMIDLIST pidl)
71c2c66affSColin Finck {
72c2c66affSColin Finck     GUID const *clsid = _ILGetGUIDPointer (pidl);
73c2c66affSColin Finck     if (!clsid)
74c2c66affSColin Finck         return -1;
75c2c66affSColin Finck 
76c2c66affSColin Finck     WCHAR pwszGuid[CHARS_IN_GUID];
77c2c66affSColin Finck     SHELL32_GUIDToStringW(*clsid, pwszGuid);
78c2c66affSColin Finck     return IsNamespaceExtensionHidden(pwszGuid);
79c2c66affSColin Finck }
80c2c66affSColin Finck 
81c2c66affSColin Finck class CDesktopFolderEnum :
82c2c66affSColin Finck     public CEnumIDListBase
83c2c66affSColin Finck {
84c2c66affSColin Finck     private:
85c2c66affSColin Finck //    CComPtr                                fDesktopEnumerator;
86c2c66affSColin Finck //    CComPtr                                fCommonDesktopEnumerator;
87c2c66affSColin Finck     public:
88c2c66affSColin Finck 
89c2c66affSColin Finck         void AddItemsFromClassicStartMenuKey(HKEY hKeyRoot)
90c2c66affSColin Finck         {
91c2c66affSColin Finck             DWORD dwResult;
92c2c66affSColin Finck             HKEY hkey;
93c2c66affSColin Finck             DWORD j = 0, dwVal, Val, dwType, dwIID;
94c2c66affSColin Finck             LONG r;
95c2c66affSColin Finck             WCHAR iid[50];
96c2c66affSColin Finck             LPITEMIDLIST pidl;
97c2c66affSColin Finck 
98c2c66affSColin Finck             dwResult = RegOpenKeyExW(hKeyRoot, ClassicStartMenuW, 0, KEY_READ, &hkey);
99c2c66affSColin Finck             if (dwResult != ERROR_SUCCESS)
100c2c66affSColin Finck                 return;
101c2c66affSColin Finck 
102c2c66affSColin Finck             while(1)
103c2c66affSColin Finck             {
104c2c66affSColin Finck                 dwVal = sizeof(Val);
105c2c66affSColin Finck                 dwIID = sizeof(iid) / sizeof(WCHAR);
106c2c66affSColin Finck 
107c2c66affSColin Finck                 r = RegEnumValueW(hkey, j++, iid, &dwIID, NULL, &dwType, (LPBYTE)&Val, &dwVal);
108c2c66affSColin Finck                 if (r != ERROR_SUCCESS)
109c2c66affSColin Finck                     break;
110c2c66affSColin Finck 
111c2c66affSColin Finck                 if (Val == 0 && dwType == REG_DWORD)
112c2c66affSColin Finck                 {
113c2c66affSColin Finck                     pidl = _ILCreateGuidFromStrW(iid);
114c2c66affSColin Finck                     if (pidl != NULL)
115c2c66affSColin Finck                     {
116c2c66affSColin Finck                         if (!HasItemWithCLSID(pidl))
117c2c66affSColin Finck                             AddToEnumList(pidl);
118c2c66affSColin Finck                         else
119c2c66affSColin Finck                             SHFree(pidl);
120c2c66affSColin Finck                     }
121c2c66affSColin Finck                 }
122c2c66affSColin Finck             }
123c2c66affSColin Finck             RegCloseKey(hkey);
124c2c66affSColin Finck         }
125c2c66affSColin Finck 
126c2c66affSColin Finck         HRESULT WINAPI Initialize(DWORD dwFlags,IEnumIDList * pRegEnumerator, IEnumIDList *pDesktopEnumerator, IEnumIDList *pCommonDesktopEnumerator)
127c2c66affSColin Finck         {
128c2c66affSColin Finck             BOOL ret = TRUE;
129c2c66affSColin Finck             LPITEMIDLIST pidl;
130c2c66affSColin Finck 
131c2c66affSColin Finck             static const WCHAR MyDocumentsClassString[] = L"{450D8FBA-AD25-11D0-98A8-0800361B1103}";
132c2c66affSColin Finck 
133c2c66affSColin Finck             TRACE("(%p)->(flags=0x%08x)\n", this, dwFlags);
134c2c66affSColin Finck 
135c2c66affSColin Finck             /* enumerate the root folders */
136c2c66affSColin Finck             if (dwFlags & SHCONTF_FOLDERS)
137c2c66affSColin Finck             {
138c2c66affSColin Finck                 AddToEnumList(_ILCreateMyComputer());
139c2c66affSColin Finck                 if (IsNamespaceExtensionHidden(MyDocumentsClassString) < 1)
140c2c66affSColin Finck                     AddToEnumList(_ILCreateMyDocuments());
141c2c66affSColin Finck 
142c2c66affSColin Finck                 DWORD dwFetched;
143c2c66affSColin Finck                 while((S_OK == pRegEnumerator->Next(1, &pidl, &dwFetched)) && dwFetched)
144c2c66affSColin Finck                 {
145c2c66affSColin Finck                     if (IsNamespaceExtensionHidden(pidl) < 1)
146c2c66affSColin Finck                     {
147c2c66affSColin Finck                         if (!HasItemWithCLSID(pidl))
148c2c66affSColin Finck                             AddToEnumList(pidl);
149c2c66affSColin Finck                         else
150c2c66affSColin Finck                             SHFree(pidl);
151c2c66affSColin Finck                     }
152c2c66affSColin Finck                 }
153c2c66affSColin Finck                 AddItemsFromClassicStartMenuKey(HKEY_LOCAL_MACHINE);
154c2c66affSColin Finck                 AddItemsFromClassicStartMenuKey(HKEY_CURRENT_USER);
155c2c66affSColin Finck             }
156c2c66affSColin Finck 
157c2c66affSColin Finck             /* Enumerate the items in the two fs folders */
158c2c66affSColin Finck             AppendItemsFromEnumerator(pDesktopEnumerator);
159c2c66affSColin Finck             AppendItemsFromEnumerator(pCommonDesktopEnumerator);
160c2c66affSColin Finck 
161c2c66affSColin Finck             return ret ? S_OK : E_FAIL;
162c2c66affSColin Finck         }
163c2c66affSColin Finck 
164c2c66affSColin Finck 
165c2c66affSColin Finck         BEGIN_COM_MAP(CDesktopFolderEnum)
166c2c66affSColin Finck         COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
167c2c66affSColin Finck         END_COM_MAP()
168c2c66affSColin Finck };
169c2c66affSColin Finck 
170c2c66affSColin Finck int SHELL_ConfirmMsgBox(HWND hWnd, LPWSTR lpszText, LPWSTR lpszCaption, HICON hIcon, BOOL bYesToAll);
171c2c66affSColin Finck 
172c2c66affSColin Finck static const shvheader DesktopSFHeader[] = {
173c2c66affSColin Finck     {IDS_SHV_COLUMN_NAME, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 15},
174c2c66affSColin Finck     {IDS_SHV_COLUMN_COMMENTS, SHCOLSTATE_TYPE_STR, LVCFMT_LEFT, 10},
175c2c66affSColin Finck     {IDS_SHV_COLUMN_TYPE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10},
176c2c66affSColin Finck     {IDS_SHV_COLUMN_SIZE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
177c2c66affSColin Finck     {IDS_SHV_COLUMN_MODIFIED, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 12},
178c2c66affSColin Finck     {IDS_SHV_COLUMN_ATTRIBUTES, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10}
179c2c66affSColin Finck };
180c2c66affSColin Finck 
181c2c66affSColin Finck #define DESKTOPSHELLVIEWCOLUMNS 6
182c2c66affSColin Finck 
183c2c66affSColin Finck static const DWORD dwDesktopAttributes =
184c2c66affSColin Finck     SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR |
185730d81b9SGiannis Adamopoulos     SFGAO_STORAGEANCESTOR | SFGAO_HASPROPSHEET | SFGAO_STORAGE;
186c2c66affSColin Finck static const DWORD dwMyComputerAttributes =
187c2c66affSColin Finck     SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
188c2c66affSColin Finck     SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK;
189c2c66affSColin Finck static DWORD dwMyNetPlacesAttributes =
190c2c66affSColin Finck     SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
191c2c66affSColin Finck     SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK;
192c2c66affSColin Finck 
193c2c66affSColin Finck CDesktopFolder::CDesktopFolder() :
194c2c66affSColin Finck     sPathTarget(NULL),
195c2c66affSColin Finck     pidlRoot(NULL)
196c2c66affSColin Finck {
197c2c66affSColin Finck }
198c2c66affSColin Finck 
199c2c66affSColin Finck CDesktopFolder::~CDesktopFolder()
200c2c66affSColin Finck {
201c2c66affSColin Finck }
202c2c66affSColin Finck 
203c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::FinalConstruct()
204c2c66affSColin Finck {
205c2c66affSColin Finck     WCHAR szMyPath[MAX_PATH];
206c2c66affSColin Finck     HRESULT hr;
207c2c66affSColin Finck 
208c2c66affSColin Finck     /* Create the root pidl */
209c2c66affSColin Finck     pidlRoot = _ILCreateDesktop();
210c2c66affSColin Finck     if (!pidlRoot)
211c2c66affSColin Finck         return E_OUTOFMEMORY;
212c2c66affSColin Finck 
213c2c66affSColin Finck     /* Create the inner fs folder */
214c2c66affSColin Finck     hr = SHELL32_CoCreateInitSF(pidlRoot,
215c2c66affSColin Finck                                 &CLSID_ShellFSFolder,
216c2c66affSColin Finck                                 CSIDL_DESKTOPDIRECTORY,
217c2c66affSColin Finck                                 IID_PPV_ARG(IShellFolder2, &m_DesktopFSFolder));
218c2c66affSColin Finck     if (FAILED_UNEXPECTEDLY(hr))
219c2c66affSColin Finck         return hr;
220c2c66affSColin Finck 
221c2c66affSColin Finck     /* Create the inner shared fs folder. Dont fail on failure. */
222c2c66affSColin Finck     hr = SHELL32_CoCreateInitSF(pidlRoot,
223c2c66affSColin Finck                                 &CLSID_ShellFSFolder,
224c2c66affSColin Finck                                 CSIDL_COMMON_DESKTOPDIRECTORY,
225c2c66affSColin Finck                                 IID_PPV_ARG(IShellFolder2, &m_SharedDesktopFSFolder));
226c2c66affSColin Finck     if (FAILED_UNEXPECTEDLY(hr))
227c2c66affSColin Finck         return hr;
228c2c66affSColin Finck 
229c2c66affSColin Finck     /* Create the inner reg folder */
230c2c66affSColin Finck     hr = CRegFolder_CreateInstance(&CLSID_ShellDesktop,
231c2c66affSColin Finck                                    pidlRoot,
232c2c66affSColin Finck                                    L"",
233c2c66affSColin Finck                                    L"Desktop",
234c2c66affSColin Finck                                    IID_PPV_ARG(IShellFolder2, &m_regFolder));
235c2c66affSColin Finck     if (FAILED_UNEXPECTEDLY(hr))
236c2c66affSColin Finck         return hr;
237c2c66affSColin Finck 
238c2c66affSColin Finck     /* Cache the path to the user desktop directory */
239c2c66affSColin Finck     if (!SHGetSpecialFolderPathW( 0, szMyPath, CSIDL_DESKTOPDIRECTORY, TRUE ))
240c2c66affSColin Finck         return E_UNEXPECTED;
241c2c66affSColin Finck 
242c2c66affSColin Finck     sPathTarget = (LPWSTR)SHAlloc((wcslen(szMyPath) + 1) * sizeof(WCHAR));
243c2c66affSColin Finck     if (!sPathTarget)
244c2c66affSColin Finck         return E_OUTOFMEMORY;
245c2c66affSColin Finck 
246c2c66affSColin Finck     wcscpy(sPathTarget, szMyPath);
247c2c66affSColin Finck     return S_OK;
248c2c66affSColin Finck }
249c2c66affSColin Finck 
250c2c66affSColin Finck HRESULT CDesktopFolder::_GetSFFromPidl(LPCITEMIDLIST pidl, IShellFolder2** psf)
251c2c66affSColin Finck {
252c2c66affSColin Finck     WCHAR szFileName[MAX_PATH];
253c2c66affSColin Finck 
254c2c66affSColin Finck     if (_ILIsSpecialFolder(pidl))
255c2c66affSColin Finck         return m_regFolder->QueryInterface(IID_PPV_ARG(IShellFolder2, psf));
256c2c66affSColin Finck 
257c2c66affSColin Finck     lstrcpynW(szFileName, sPathTarget, MAX_PATH - 1);
258c2c66affSColin Finck     PathAddBackslashW(szFileName);
259c2c66affSColin Finck     int cLen = wcslen(szFileName);
260c2c66affSColin Finck 
261c2c66affSColin Finck     if (!_ILSimpleGetTextW(pidl, szFileName + cLen, MAX_PATH - cLen))
262c2c66affSColin Finck         return E_FAIL;
263c2c66affSColin Finck 
264c2c66affSColin Finck     if (GetFileAttributes(szFileName) == INVALID_FILE_ATTRIBUTES)
265c2c66affSColin Finck         return m_SharedDesktopFSFolder->QueryInterface(IID_PPV_ARG(IShellFolder2, psf));
266c2c66affSColin Finck     else
267c2c66affSColin Finck         return m_DesktopFSFolder->QueryInterface(IID_PPV_ARG(IShellFolder2, psf));
268c2c66affSColin Finck }
269c2c66affSColin Finck 
270c2c66affSColin Finck /**************************************************************************
271c2c66affSColin Finck  *    CDesktopFolder::ParseDisplayName
272c2c66affSColin Finck  *
273c2c66affSColin Finck  * NOTES
274c2c66affSColin Finck  *    "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
275c2c66affSColin Finck  *    to MyComputer
276c2c66affSColin Finck  */
277c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::ParseDisplayName(
278c2c66affSColin Finck     HWND hwndOwner,
279c2c66affSColin Finck     LPBC pbc,
280c2c66affSColin Finck     LPOLESTR lpszDisplayName,
281c2c66affSColin Finck     DWORD *pchEaten,
282c2c66affSColin Finck     PIDLIST_RELATIVE *ppidl,
283c2c66affSColin Finck     DWORD *pdwAttributes)
284c2c66affSColin Finck {
285c2c66affSColin Finck     LPCWSTR szNext = NULL;
286c2c66affSColin Finck     LPITEMIDLIST pidlTemp = NULL;
287c2c66affSColin Finck     PARSEDURLW urldata;
288c2c66affSColin Finck     HRESULT hr = S_OK;
289c2c66affSColin Finck 
290c2c66affSColin Finck     TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
291c2c66affSColin Finck            this, hwndOwner, pbc, lpszDisplayName, debugstr_w(lpszDisplayName),
292c2c66affSColin Finck            pchEaten, ppidl, pdwAttributes);
293c2c66affSColin Finck 
294c2c66affSColin Finck     if (!ppidl)
295c2c66affSColin Finck         return E_INVALIDARG;
296c2c66affSColin Finck 
297c2c66affSColin Finck     *ppidl = NULL;
298c2c66affSColin Finck 
299c2c66affSColin Finck     if (!lpszDisplayName)
300c2c66affSColin Finck         return E_INVALIDARG;
301c2c66affSColin Finck 
302c2c66affSColin Finck     if (pchEaten)
303c2c66affSColin Finck         *pchEaten = 0;        /* strange but like the original */
304c2c66affSColin Finck 
305c2c66affSColin Finck     urldata.cbSize = sizeof(urldata);
306c2c66affSColin Finck 
307c2c66affSColin Finck     if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':')
308c2c66affSColin Finck     {
309c2c66affSColin Finck         return m_regFolder->ParseDisplayName(hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
310c2c66affSColin Finck     }
311c2c66affSColin Finck     else if (PathGetDriveNumberW (lpszDisplayName) >= 0)
312c2c66affSColin Finck     {
313c2c66affSColin Finck         /* it's a filesystem path with a drive. Let MyComputer/UnixDosFolder parse it */
314c2c66affSColin Finck         pidlTemp = _ILCreateMyComputer ();
315c2c66affSColin Finck         szNext = lpszDisplayName;
316c2c66affSColin Finck     }
317c2c66affSColin Finck     else if (PathIsUNCW(lpszDisplayName))
318c2c66affSColin Finck     {
319c2c66affSColin Finck         pidlTemp = _ILCreateNetwork();
320c2c66affSColin Finck         szNext = lpszDisplayName;
321c2c66affSColin Finck     }
322c2c66affSColin Finck     else if( (pidlTemp = SHELL32_CreatePidlFromBindCtx(pbc, lpszDisplayName)) )
323c2c66affSColin Finck     {
324c2c66affSColin Finck         *ppidl = pidlTemp;
325c2c66affSColin Finck         return S_OK;
326c2c66affSColin Finck     }
327c2c66affSColin Finck     else if (SUCCEEDED(ParseURLW(lpszDisplayName, &urldata)))
328c2c66affSColin Finck     {
329c2c66affSColin Finck         if (urldata.nScheme == URL_SCHEME_SHELL) /* handle shell: urls */
330c2c66affSColin Finck         {
331c2c66affSColin Finck             TRACE ("-- shell url: %s\n", debugstr_w(urldata.pszSuffix));
332c2c66affSColin Finck             pidlTemp = _ILCreateGuidFromStrW(urldata.pszSuffix + 2);
333c2c66affSColin Finck         }
334c2c66affSColin Finck         else
335c2c66affSColin Finck             return IEParseDisplayNameWithBCW(CP_ACP, lpszDisplayName, pbc, ppidl);
336c2c66affSColin Finck     }
337c2c66affSColin Finck     else
338c2c66affSColin Finck     {
339c2c66affSColin Finck         if (*lpszDisplayName)
340c2c66affSColin Finck         {
341c2c66affSColin Finck             /* it's a filesystem path on the desktop. Let a FSFolder parse it */
342c2c66affSColin Finck             hr = m_DesktopFSFolder->ParseDisplayName(hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
343c2c66affSColin Finck             if (SUCCEEDED(hr))
344c2c66affSColin Finck                 return hr;
345c2c66affSColin Finck 
346c2c66affSColin Finck             return m_SharedDesktopFSFolder->ParseDisplayName(hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
347c2c66affSColin Finck         }
348c2c66affSColin Finck         else
349c2c66affSColin Finck             pidlTemp = _ILCreateMyComputer();
350c2c66affSColin Finck 
351c2c66affSColin Finck         szNext = NULL;
352c2c66affSColin Finck     }
353c2c66affSColin Finck 
354c2c66affSColin Finck     if (SUCCEEDED(hr) && pidlTemp)
355c2c66affSColin Finck     {
356c2c66affSColin Finck         if (szNext && *szNext)
357c2c66affSColin Finck         {
358c2c66affSColin Finck             hr = SHELL32_ParseNextElement(this, hwndOwner, pbc,
359c2c66affSColin Finck                                           &pidlTemp, (LPOLESTR) szNext, pchEaten, pdwAttributes);
360c2c66affSColin Finck         }
361c2c66affSColin Finck         else
362c2c66affSColin Finck         {
363c2c66affSColin Finck             if (pdwAttributes && *pdwAttributes)
364c2c66affSColin Finck             {
365c2c66affSColin Finck                 GetAttributesOf(1, &pidlTemp, pdwAttributes);
366c2c66affSColin Finck             }
367c2c66affSColin Finck         }
368c2c66affSColin Finck     }
369c2c66affSColin Finck 
370c2c66affSColin Finck     if (SUCCEEDED(hr))
371c2c66affSColin Finck         *ppidl = pidlTemp;
372c2c66affSColin Finck     else
373c2c66affSColin Finck         *ppidl = NULL;
374c2c66affSColin Finck 
375c2c66affSColin Finck     TRACE ("(%p)->(-- ret=0x%08x)\n", this, hr);
376c2c66affSColin Finck 
377c2c66affSColin Finck     return hr;
378c2c66affSColin Finck }
379c2c66affSColin Finck 
380c2c66affSColin Finck /**************************************************************************
381c2c66affSColin Finck  *        CDesktopFolder::EnumObjects
382c2c66affSColin Finck  */
383c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
384c2c66affSColin Finck {
385c2c66affSColin Finck     CComPtr<IEnumIDList> pRegEnumerator;
386c2c66affSColin Finck     CComPtr<IEnumIDList> pDesktopEnumerator;
387c2c66affSColin Finck     CComPtr<IEnumIDList> pCommonDesktopEnumerator;
388c2c66affSColin Finck     HRESULT hr;
389c2c66affSColin Finck 
390c2c66affSColin Finck     hr = m_regFolder->EnumObjects(hwndOwner, dwFlags, &pRegEnumerator);
391c2c66affSColin Finck     if (FAILED(hr))
392c2c66affSColin Finck         ERR("EnumObjects for reg folder failed\n");
393c2c66affSColin Finck 
394c2c66affSColin Finck     hr = m_DesktopFSFolder->EnumObjects(hwndOwner, dwFlags, &pDesktopEnumerator);
395c2c66affSColin Finck     if (FAILED(hr))
396c2c66affSColin Finck         ERR("EnumObjects for desktop fs folder failed\n");
397c2c66affSColin Finck 
398c2c66affSColin Finck     hr = m_SharedDesktopFSFolder->EnumObjects(hwndOwner, dwFlags, &pCommonDesktopEnumerator);
399c2c66affSColin Finck     if (FAILED(hr))
400c2c66affSColin Finck         ERR("EnumObjects for shared desktop fs folder failed\n");
401c2c66affSColin Finck 
402c2c66affSColin Finck     return ShellObjectCreatorInit<CDesktopFolderEnum>(dwFlags,pRegEnumerator, pDesktopEnumerator, pCommonDesktopEnumerator, IID_PPV_ARG(IEnumIDList, ppEnumIDList));
403c2c66affSColin Finck }
404c2c66affSColin Finck 
405c2c66affSColin Finck /**************************************************************************
406c2c66affSColin Finck  *        CDesktopFolder::BindToObject
407c2c66affSColin Finck  */
408c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::BindToObject(
409c2c66affSColin Finck     PCUIDLIST_RELATIVE pidl,
410c2c66affSColin Finck     LPBC pbcReserved,
411c2c66affSColin Finck     REFIID riid,
412c2c66affSColin Finck     LPVOID *ppvOut)
413c2c66affSColin Finck {
414c2c66affSColin Finck     if (!pidl)
415c2c66affSColin Finck         return E_INVALIDARG;
416c2c66affSColin Finck 
417c2c66affSColin Finck     CComPtr<IShellFolder2> psf;
418c2c66affSColin Finck     HRESULT hr = _GetSFFromPidl(pidl, &psf);
419c2c66affSColin Finck     if (FAILED_UNEXPECTEDLY(hr))
420c2c66affSColin Finck         return hr;
421c2c66affSColin Finck 
422c2c66affSColin Finck     return psf->BindToObject(pidl, pbcReserved, riid, ppvOut);
423c2c66affSColin Finck }
424c2c66affSColin Finck 
425c2c66affSColin Finck /**************************************************************************
426c2c66affSColin Finck  *    CDesktopFolder::BindToStorage
427c2c66affSColin Finck  */
428c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::BindToStorage(
429c2c66affSColin Finck     PCUIDLIST_RELATIVE pidl,
430c2c66affSColin Finck     LPBC pbcReserved,
431c2c66affSColin Finck     REFIID riid,
432c2c66affSColin Finck     LPVOID *ppvOut)
433c2c66affSColin Finck {
434c2c66affSColin Finck     FIXME ("(%p)->(pidl=%p,%p,%s,%p) stub\n",
435c2c66affSColin Finck            this, pidl, pbcReserved, shdebugstr_guid (&riid), ppvOut);
436c2c66affSColin Finck 
437c2c66affSColin Finck     *ppvOut = NULL;
438c2c66affSColin Finck     return E_NOTIMPL;
439c2c66affSColin Finck }
440c2c66affSColin Finck 
441c2c66affSColin Finck /**************************************************************************
442c2c66affSColin Finck  *     CDesktopFolder::CompareIDs
443c2c66affSColin Finck  */
444c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
445c2c66affSColin Finck {
446c2c66affSColin Finck     bool bIsDesktopFolder1, bIsDesktopFolder2;
447c2c66affSColin Finck 
448c2c66affSColin Finck     if (!pidl1 || !pidl2)
449c2c66affSColin Finck     {
450c2c66affSColin Finck         ERR("Got null pidl pointer (%Ix %p %p)!\n", lParam, pidl1, pidl2);
451c2c66affSColin Finck         return E_INVALIDARG;
452c2c66affSColin Finck     }
453c2c66affSColin Finck 
454c2c66affSColin Finck     bIsDesktopFolder1 = _ILIsDesktop(pidl1);
455c2c66affSColin Finck     bIsDesktopFolder2 = _ILIsDesktop(pidl2);
456c2c66affSColin Finck     if (bIsDesktopFolder1 || bIsDesktopFolder2)
457c2c66affSColin Finck         return MAKE_COMPARE_HRESULT(bIsDesktopFolder1 - bIsDesktopFolder2);
458c2c66affSColin Finck 
459c2c66affSColin Finck     if (_ILIsSpecialFolder(pidl1) || _ILIsSpecialFolder(pidl2))
460c2c66affSColin Finck         return m_regFolder->CompareIDs(lParam, pidl1, pidl2);
461c2c66affSColin Finck 
462c2c66affSColin Finck     return m_DesktopFSFolder->CompareIDs(lParam, pidl1, pidl2);
463c2c66affSColin Finck }
464c2c66affSColin Finck 
465c2c66affSColin Finck /**************************************************************************
466c2c66affSColin Finck  *    CDesktopFolder::CreateViewObject
467c2c66affSColin Finck  */
468c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::CreateViewObject(
469c2c66affSColin Finck     HWND hwndOwner,
470c2c66affSColin Finck     REFIID riid,
471c2c66affSColin Finck     LPVOID *ppvOut)
472c2c66affSColin Finck {
473c2c66affSColin Finck     HRESULT hr = E_INVALIDARG;
474c2c66affSColin Finck 
475c2c66affSColin Finck     TRACE ("(%p)->(hwnd=%p,%s,%p)\n",
476c2c66affSColin Finck            this, hwndOwner, shdebugstr_guid (&riid), ppvOut);
477c2c66affSColin Finck 
478c2c66affSColin Finck     if (!ppvOut)
479c2c66affSColin Finck         return hr;
480c2c66affSColin Finck 
481c2c66affSColin Finck     *ppvOut = NULL;
482c2c66affSColin Finck 
483c2c66affSColin Finck     if (IsEqualIID (riid, IID_IDropTarget))
484c2c66affSColin Finck     {
485c2c66affSColin Finck         hr = m_DesktopFSFolder->CreateViewObject(hwndOwner, riid, ppvOut);
486c2c66affSColin Finck     }
487c2c66affSColin Finck     else if (IsEqualIID (riid, IID_IContextMenu))
488c2c66affSColin Finck     {
489c2c66affSColin Finck             HKEY hKeys[16];
490c2c66affSColin Finck             UINT cKeys = 0;
491c2c66affSColin Finck             AddClassKeyToArray(L"Directory\\Background", hKeys, &cKeys);
492c2c66affSColin Finck 
493c2c66affSColin Finck             DEFCONTEXTMENU dcm;
494c2c66affSColin Finck             dcm.hwnd = hwndOwner;
495c2c66affSColin Finck             dcm.pcmcb = this;
496c2c66affSColin Finck             dcm.pidlFolder = pidlRoot;
497c2c66affSColin Finck             dcm.psf = this;
498c2c66affSColin Finck             dcm.cidl = 0;
499c2c66affSColin Finck             dcm.apidl = NULL;
500c2c66affSColin Finck             dcm.cKeys = cKeys;
501c2c66affSColin Finck             dcm.aKeys = hKeys;
502c2c66affSColin Finck             dcm.punkAssociationInfo = NULL;
503c2c66affSColin Finck             hr = SHCreateDefaultContextMenu (&dcm, riid, ppvOut);
504c2c66affSColin Finck     }
505c2c66affSColin Finck     else if (IsEqualIID (riid, IID_IShellView))
506c2c66affSColin Finck     {
507c2c66affSColin Finck         SFV_CREATE sfvparams = {sizeof(SFV_CREATE), this};
508c2c66affSColin Finck         hr = SHCreateShellFolderView(&sfvparams, (IShellView**)ppvOut);
509c2c66affSColin Finck     }
510c2c66affSColin Finck     TRACE ("-- (%p)->(interface=%p)\n", this, ppvOut);
511c2c66affSColin Finck     return hr;
512c2c66affSColin Finck }
513c2c66affSColin Finck 
514c2c66affSColin Finck /**************************************************************************
515c2c66affSColin Finck  *  CDesktopFolder::GetAttributesOf
516c2c66affSColin Finck  */
517c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetAttributesOf(
518c2c66affSColin Finck     UINT cidl,
519c2c66affSColin Finck     PCUITEMID_CHILD_ARRAY apidl,
520c2c66affSColin Finck     DWORD *rgfInOut)
521c2c66affSColin Finck {
522c2c66affSColin Finck     HRESULT hr = S_OK;
523c2c66affSColin Finck 
524c2c66affSColin Finck     TRACE("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
525c2c66affSColin Finck           this, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
526c2c66affSColin Finck 
527c2c66affSColin Finck     if (cidl && !apidl)
528c2c66affSColin Finck         return E_INVALIDARG;
529c2c66affSColin Finck 
530c2c66affSColin Finck     if (*rgfInOut == 0)
531c2c66affSColin Finck         *rgfInOut = ~0;
532c2c66affSColin Finck 
533c2c66affSColin Finck     if(cidl == 0)
534c2c66affSColin Finck         *rgfInOut &= dwDesktopAttributes;
535c2c66affSColin Finck     else
536c2c66affSColin Finck     {
537c2c66affSColin Finck         /* TODO: always add SFGAO_CANLINK */
538c2c66affSColin Finck         for (UINT i = 0; i < cidl; ++i)
539c2c66affSColin Finck         {
540c2c66affSColin Finck             pdump(*apidl);
541c2c66affSColin Finck             if (_ILIsDesktop(*apidl))
542c2c66affSColin Finck                 *rgfInOut &= dwDesktopAttributes;
543c2c66affSColin Finck             else if (_ILIsMyComputer(apidl[i]))
544c2c66affSColin Finck                 *rgfInOut &= dwMyComputerAttributes;
545c2c66affSColin Finck             else if (_ILIsNetHood(apidl[i]))
546c2c66affSColin Finck                 *rgfInOut &= dwMyNetPlacesAttributes;
547c2c66affSColin Finck             else if (_ILIsFolder(apidl[i]) || _ILIsValue(apidl[i]) || _ILIsSpecialFolder(apidl[i]))
548c2c66affSColin Finck             {
549c2c66affSColin Finck                 CComPtr<IShellFolder2> psf;
550c2c66affSColin Finck                 HRESULT hr = _GetSFFromPidl(apidl[i], &psf);
551c2c66affSColin Finck                 if (FAILED_UNEXPECTEDLY(hr))
552c2c66affSColin Finck                     continue;
553c2c66affSColin Finck 
554c2c66affSColin Finck                 psf->GetAttributesOf(1, &apidl[i], rgfInOut);
555c2c66affSColin Finck             }
556c2c66affSColin Finck             else
557c2c66affSColin Finck                 ERR("Got an unknown pidl type!!!\n");
558c2c66affSColin Finck         }
559c2c66affSColin Finck     }
560c2c66affSColin Finck     /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
561c2c66affSColin Finck     *rgfInOut &= ~SFGAO_VALIDATE;
562c2c66affSColin Finck 
563c2c66affSColin Finck     TRACE("-- result=0x%08x\n", *rgfInOut);
564c2c66affSColin Finck 
565c2c66affSColin Finck     return hr;
566c2c66affSColin Finck }
567c2c66affSColin Finck 
568c2c66affSColin Finck /**************************************************************************
569c2c66affSColin Finck  *    CDesktopFolder::GetUIObjectOf
570c2c66affSColin Finck  *
571c2c66affSColin Finck  * PARAMETERS
572c2c66affSColin Finck  *  HWND           hwndOwner, //[in ] Parent window for any output
573c2c66affSColin Finck  *  UINT           cidl,      //[in ] array size
574c2c66affSColin Finck  *  LPCITEMIDLIST* apidl,     //[in ] simple pidl array
575c2c66affSColin Finck  *  REFIID         riid,      //[in ] Requested Interface
576c2c66affSColin Finck  *  UINT*          prgfInOut, //[   ] reserved
577c2c66affSColin Finck  *  LPVOID*        ppvObject) //[out] Resulting Interface
578c2c66affSColin Finck  *
579c2c66affSColin Finck  */
580c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetUIObjectOf(
581c2c66affSColin Finck     HWND hwndOwner,
582c2c66affSColin Finck     UINT cidl,
583c2c66affSColin Finck     PCUITEMID_CHILD_ARRAY apidl,
584c2c66affSColin Finck     REFIID riid,
585c2c66affSColin Finck     UINT *prgfInOut,
586c2c66affSColin Finck     LPVOID *ppvOut)
587c2c66affSColin Finck {
588c2c66affSColin Finck     LPVOID pObj = NULL;
589c2c66affSColin Finck     HRESULT hr = E_INVALIDARG;
590c2c66affSColin Finck 
591c2c66affSColin Finck     TRACE ("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n",
592c2c66affSColin Finck            this, hwndOwner, cidl, apidl, shdebugstr_guid (&riid), prgfInOut, ppvOut);
593c2c66affSColin Finck 
594c2c66affSColin Finck     if (!ppvOut)
595c2c66affSColin Finck         return hr;
596c2c66affSColin Finck 
597c2c66affSColin Finck     *ppvOut = NULL;
598c2c66affSColin Finck 
599c2c66affSColin Finck     if (cidl == 1 && !_ILIsSpecialFolder(apidl[0]))
600c2c66affSColin Finck     {
601c2c66affSColin Finck         CComPtr<IShellFolder2> psf;
602c2c66affSColin Finck         HRESULT hr = _GetSFFromPidl(apidl[0], &psf);
603c2c66affSColin Finck         if (FAILED_UNEXPECTEDLY(hr))
604c2c66affSColin Finck             return hr;
605c2c66affSColin Finck 
606c2c66affSColin Finck         return psf->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, ppvOut);
607c2c66affSColin Finck     }
608c2c66affSColin Finck 
609c2c66affSColin Finck     if (IsEqualIID (riid, IID_IContextMenu))
610c2c66affSColin Finck     {
611*0d077c30SIoannis Adamopoulos         if (cidl > 0 && _ILIsSpecialFolder(apidl[0]))
612c2c66affSColin Finck         {
613c2c66affSColin Finck             hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
614c2c66affSColin Finck         }
615c2c66affSColin Finck         else
616c2c66affSColin Finck         {
617c2c66affSColin Finck             /* Do not use the context menu of the CFSFolder here. */
618c2c66affSColin 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 */
619c2c66affSColin Finck             /* Otherwise operations like that involve items from both user and shared desktop will not work */
620c2c66affSColin Finck             HKEY hKeys[16];
621c2c66affSColin Finck             UINT cKeys = 0;
622*0d077c30SIoannis Adamopoulos             if (cidl > 0)
623*0d077c30SIoannis Adamopoulos             {
624c2c66affSColin Finck                 AddFSClassKeysToArray(apidl[0], hKeys, &cKeys);
625*0d077c30SIoannis Adamopoulos             }
626c2c66affSColin Finck 
627c2c66affSColin Finck             DEFCONTEXTMENU dcm;
628c2c66affSColin Finck             dcm.hwnd = hwndOwner;
629c2c66affSColin Finck             dcm.pcmcb = this;
630c2c66affSColin Finck             dcm.pidlFolder = pidlRoot;
631c2c66affSColin Finck             dcm.psf = this;
632c2c66affSColin Finck             dcm.cidl = cidl;
633c2c66affSColin Finck             dcm.apidl = apidl;
634c2c66affSColin Finck             dcm.cKeys = cKeys;
635c2c66affSColin Finck             dcm.aKeys = hKeys;
636c2c66affSColin Finck             dcm.punkAssociationInfo = NULL;
637c2c66affSColin Finck             hr = SHCreateDefaultContextMenu (&dcm, riid, &pObj);
638c2c66affSColin Finck         }
639c2c66affSColin Finck     }
640c2c66affSColin Finck     else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1))
641c2c66affSColin Finck     {
642c3132711SMark Jansen         hr = IDataObject_Constructor( hwndOwner, pidlRoot, apidl, cidl, TRUE, (IDataObject **)&pObj);
643c2c66affSColin Finck     }
644c2c66affSColin Finck     else if ((IsEqualIID (riid, IID_IExtractIconA) || IsEqualIID (riid, IID_IExtractIconW)) && (cidl == 1))
645c2c66affSColin Finck     {
646c2c66affSColin Finck         hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
647c2c66affSColin Finck     }
648c2c66affSColin Finck     else if (IsEqualIID (riid, IID_IDropTarget) && (cidl == 1))
649c2c66affSColin Finck     {
650c2c66affSColin Finck         CComPtr<IShellFolder> psfChild;
651c2c66affSColin Finck         hr = this->BindToObject(apidl[0], NULL, IID_PPV_ARG(IShellFolder, &psfChild));
652c2c66affSColin Finck         if (FAILED_UNEXPECTEDLY(hr))
653c2c66affSColin Finck             return hr;
654c2c66affSColin Finck 
655c2c66affSColin Finck         return psfChild->CreateViewObject(NULL, riid, ppvOut);
656c2c66affSColin Finck     }
657c2c66affSColin Finck     else
658c2c66affSColin Finck         hr = E_NOINTERFACE;
659c2c66affSColin Finck 
660c2c66affSColin Finck     if (SUCCEEDED(hr) && !pObj)
661c2c66affSColin Finck         hr = E_OUTOFMEMORY;
662c2c66affSColin Finck 
663c2c66affSColin Finck     *ppvOut = pObj;
664c2c66affSColin Finck     TRACE ("(%p)->hr=0x%08x\n", this, hr);
665c2c66affSColin Finck     return hr;
666c2c66affSColin Finck }
667c2c66affSColin Finck 
668c2c66affSColin Finck /**************************************************************************
669c2c66affSColin Finck  *    CDesktopFolder::GetDisplayNameOf
670c2c66affSColin Finck  *
671c2c66affSColin Finck  * NOTES
672c2c66affSColin Finck  *    special case: pidl = null gives desktop-name back
673c2c66affSColin Finck  */
674c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet)
675c2c66affSColin Finck {
676c2c66affSColin Finck     TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet);
677c2c66affSColin Finck     pdump (pidl);
678c2c66affSColin Finck 
679c2c66affSColin Finck     if (!strRet)
680c2c66affSColin Finck         return E_INVALIDARG;
681c2c66affSColin Finck 
682c2c66affSColin Finck     if (!_ILIsPidlSimple (pidl))
683c2c66affSColin Finck     {
684c2c66affSColin Finck         return SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, strRet);
685c2c66affSColin Finck     }
686c2c66affSColin Finck     else if (_ILIsDesktop(pidl))
687c2c66affSColin Finck     {
688c2c66affSColin Finck         if ((GET_SHGDN_RELATION(dwFlags) == SHGDN_NORMAL) && (GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING))
689c2c66affSColin Finck             return SHSetStrRet(strRet, sPathTarget);
690c2c66affSColin Finck         else
691c2c66affSColin Finck             return m_regFolder->GetDisplayNameOf(pidl, dwFlags, strRet);
692c2c66affSColin Finck     }
693c2c66affSColin Finck 
694c2c66affSColin Finck     /* file system folder or file rooted at the desktop */
695c2c66affSColin Finck     CComPtr<IShellFolder2> psf;
696c2c66affSColin Finck     HRESULT hr = _GetSFFromPidl(pidl, &psf);
697c2c66affSColin Finck     if (FAILED_UNEXPECTEDLY(hr))
698c2c66affSColin Finck         return hr;
699c2c66affSColin Finck 
700c2c66affSColin Finck     return psf->GetDisplayNameOf(pidl, dwFlags, strRet);
701c2c66affSColin Finck }
702c2c66affSColin Finck 
703c2c66affSColin Finck /**************************************************************************
704c2c66affSColin Finck  *  CDesktopFolder::SetNameOf
705c2c66affSColin Finck  *  Changes the name of a file object or subfolder, possibly changing its item
706c2c66affSColin Finck  *  identifier in the process.
707c2c66affSColin Finck  *
708c2c66affSColin Finck  * PARAMETERS
709c2c66affSColin Finck  *  HWND          hwndOwner,  //[in ] Owner window for output
710c2c66affSColin Finck  *  LPCITEMIDLIST pidl,       //[in ] simple pidl of item to change
711c2c66affSColin Finck  *  LPCOLESTR     lpszName,   //[in ] the items new display name
712c2c66affSColin Finck  *  DWORD         dwFlags,    //[in ] SHGNO formatting flags
713c2c66affSColin Finck  *  LPITEMIDLIST* ppidlOut)   //[out] simple pidl returned
714c2c66affSColin Finck  */
715c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::SetNameOf(
716c2c66affSColin Finck     HWND hwndOwner,
717c2c66affSColin Finck     PCUITEMID_CHILD pidl,    /* simple pidl */
718c2c66affSColin Finck     LPCOLESTR lpName,
719c2c66affSColin Finck     DWORD dwFlags,
720c2c66affSColin Finck     PITEMID_CHILD *pPidlOut)
721c2c66affSColin Finck {
722c2c66affSColin Finck     CComPtr<IShellFolder2> psf;
723c2c66affSColin Finck     HRESULT hr = _GetSFFromPidl(pidl, &psf);
724c2c66affSColin Finck     if (FAILED_UNEXPECTEDLY(hr))
725c2c66affSColin Finck         return hr;
726c2c66affSColin Finck 
727c2c66affSColin Finck     return psf->SetNameOf(hwndOwner, pidl, lpName, dwFlags, pPidlOut);
728c2c66affSColin Finck }
729c2c66affSColin Finck 
730c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetDefaultSearchGUID(GUID *pguid)
731c2c66affSColin Finck {
732c2c66affSColin Finck     FIXME ("(%p)\n", this);
733c2c66affSColin Finck     return E_NOTIMPL;
734c2c66affSColin Finck }
735c2c66affSColin Finck 
736c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::EnumSearches(IEnumExtraSearch **ppenum)
737c2c66affSColin Finck {
738c2c66affSColin Finck     FIXME ("(%p)\n", this);
739c2c66affSColin Finck     return E_NOTIMPL;
740c2c66affSColin Finck }
741c2c66affSColin Finck 
742c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetDefaultColumn(DWORD dwRes, ULONG *pSort, ULONG *pDisplay)
743c2c66affSColin Finck {
744c2c66affSColin Finck     TRACE ("(%p)\n", this);
745c2c66affSColin Finck 
746c2c66affSColin Finck     if (pSort)
747c2c66affSColin Finck         *pSort = 0;
748c2c66affSColin Finck     if (pDisplay)
749c2c66affSColin Finck         *pDisplay = 0;
750c2c66affSColin Finck 
751c2c66affSColin Finck     return S_OK;
752c2c66affSColin Finck }
753c2c66affSColin Finck 
754c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags)
755c2c66affSColin Finck {
756c2c66affSColin Finck     TRACE ("(%p)\n", this);
757c2c66affSColin Finck 
758c2c66affSColin Finck     if (!pcsFlags || iColumn >= DESKTOPSHELLVIEWCOLUMNS)
759c2c66affSColin Finck         return E_INVALIDARG;
760c2c66affSColin Finck 
761c2c66affSColin Finck     *pcsFlags = DesktopSFHeader[iColumn].pcsFlags;
762c2c66affSColin Finck 
763c2c66affSColin Finck     return S_OK;
764c2c66affSColin Finck }
765c2c66affSColin Finck 
766c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetDetailsEx(
767c2c66affSColin Finck     PCUITEMID_CHILD pidl,
768c2c66affSColin Finck     const SHCOLUMNID *pscid,
769c2c66affSColin Finck     VARIANT *pv)
770c2c66affSColin Finck {
771c2c66affSColin Finck     FIXME ("(%p)\n", this);
772c2c66affSColin Finck 
773c2c66affSColin Finck     return E_NOTIMPL;
774c2c66affSColin Finck }
775c2c66affSColin Finck 
776c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetDetailsOf(
777c2c66affSColin Finck     PCUITEMID_CHILD pidl,
778c2c66affSColin Finck     UINT iColumn,
779c2c66affSColin Finck     SHELLDETAILS *psd)
780c2c66affSColin Finck {
781c2c66affSColin Finck     if (!psd || iColumn >= DESKTOPSHELLVIEWCOLUMNS)
782c2c66affSColin Finck         return E_INVALIDARG;
783c2c66affSColin Finck 
784c2c66affSColin Finck     if (!pidl)
785c2c66affSColin Finck     {
786c2c66affSColin Finck         psd->fmt = DesktopSFHeader[iColumn].fmt;
787c2c66affSColin Finck         psd->cxChar = DesktopSFHeader[iColumn].cxChar;
788c2c66affSColin Finck         return SHSetStrRet(&psd->str, DesktopSFHeader[iColumn].colnameid);
789c2c66affSColin Finck     }
790c2c66affSColin Finck 
791c2c66affSColin Finck     CComPtr<IShellFolder2> psf;
792c2c66affSColin Finck     HRESULT hr = _GetSFFromPidl(pidl, &psf);
793c2c66affSColin Finck     if (FAILED_UNEXPECTEDLY(hr))
794c2c66affSColin Finck         return hr;
795c2c66affSColin Finck 
796c2c66affSColin Finck     hr =  psf->GetDetailsOf(pidl, iColumn, psd);
797c2c66affSColin Finck     if (FAILED_UNEXPECTEDLY(hr))
798c2c66affSColin Finck         return hr;
799c2c66affSColin Finck 
800c2c66affSColin Finck     return hr;
801c2c66affSColin Finck }
802c2c66affSColin Finck 
803c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::MapColumnToSCID(UINT column, SHCOLUMNID *pscid)
804c2c66affSColin Finck {
805c2c66affSColin Finck     FIXME ("(%p)\n", this);
806c2c66affSColin Finck     return E_NOTIMPL;
807c2c66affSColin Finck }
808c2c66affSColin Finck 
809c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetClassID(CLSID *lpClassId)
810c2c66affSColin Finck {
811c2c66affSColin Finck     TRACE ("(%p)\n", this);
812c2c66affSColin Finck 
813c2c66affSColin Finck     if (!lpClassId)
814c2c66affSColin Finck         return E_POINTER;
815c2c66affSColin Finck 
816c2c66affSColin Finck     *lpClassId = CLSID_ShellDesktop;
817c2c66affSColin Finck 
818c2c66affSColin Finck     return S_OK;
819c2c66affSColin Finck }
820c2c66affSColin Finck 
8216b0d2c2aSThomas Faber HRESULT WINAPI CDesktopFolder::Initialize(PCIDLIST_ABSOLUTE pidl)
822c2c66affSColin Finck {
823c2c66affSColin Finck     TRACE ("(%p)->(%p)\n", this, pidl);
824c2c66affSColin Finck 
8257e48c20bSGiannis Adamopoulos     if (!pidl)
8267e48c20bSGiannis Adamopoulos         return S_OK;
8277e48c20bSGiannis Adamopoulos 
828c2c66affSColin Finck     return E_INVALIDARG;
829c2c66affSColin Finck }
830c2c66affSColin Finck 
831b90c24d6SThomas Faber HRESULT WINAPI CDesktopFolder::GetCurFolder(PIDLIST_ABSOLUTE * pidl)
832c2c66affSColin Finck {
833c2c66affSColin Finck     TRACE ("(%p)->(%p)\n", this, pidl);
834c2c66affSColin Finck 
835c2c66affSColin Finck     if (!pidl)
836c2c66affSColin Finck         return E_INVALIDARG; /* xp doesn't have this check and crashes on NULL */
837c2c66affSColin Finck     *pidl = ILClone (pidlRoot);
838c2c66affSColin Finck     return S_OK;
839c2c66affSColin Finck }
840c2c66affSColin Finck 
841c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam)
842c2c66affSColin Finck {
843c2c66affSColin Finck     if (uMsg != DFM_MERGECONTEXTMENU && uMsg != DFM_INVOKECOMMAND)
844c2c66affSColin Finck         return S_OK;
845c2c66affSColin Finck 
846c2c66affSColin Finck     /* no data object means no selection */
847c2c66affSColin Finck     if (!pdtobj)
848c2c66affSColin Finck     {
849c2c66affSColin Finck         if (uMsg == DFM_INVOKECOMMAND && wParam == 0)
850c2c66affSColin Finck         {
851944aba1fSKatayama Hirofumi MZ             if (32 >= (UINT_PTR)ShellExecuteW(hwndOwner, L"open", L"rundll32.exe",
852944aba1fSKatayama Hirofumi MZ                                               L"shell32.dll,Control_RunDLL desk.cpl", NULL, SW_SHOWNORMAL))
853944aba1fSKatayama Hirofumi MZ             {
854c2c66affSColin Finck                 return E_FAIL;
855944aba1fSKatayama Hirofumi MZ             }
856c2c66affSColin Finck             return S_OK;
857c2c66affSColin Finck         }
858c2c66affSColin Finck         else if (uMsg == DFM_MERGECONTEXTMENU)
859c2c66affSColin Finck         {
860c2c66affSColin Finck             QCMINFO *pqcminfo = (QCMINFO *)lParam;
861c2c66affSColin Finck             HMENU hpopup = CreatePopupMenu();
862c2c66affSColin Finck             _InsertMenuItemW(hpopup, 0, TRUE, 0, MFT_STRING, MAKEINTRESOURCEW(IDS_PROPERTIES), MFS_ENABLED);
863c2c66affSColin Finck             Shell_MergeMenus(pqcminfo->hmenu, hpopup, pqcminfo->indexMenu++, pqcminfo->idCmdFirst, pqcminfo->idCmdLast, MM_ADDSEPARATOR);
864c2c66affSColin Finck             DestroyMenu(hpopup);
865c2c66affSColin Finck         }
866c2c66affSColin Finck 
867c2c66affSColin Finck         return S_OK;
868c2c66affSColin Finck     }
869c2c66affSColin Finck 
8709192d39fSManuel Bachmann     if (uMsg != DFM_INVOKECOMMAND || wParam != DFM_CMD_PROPERTIES)
8719192d39fSManuel Bachmann         return S_OK;
8729192d39fSManuel Bachmann 
87355469633SKatayama Hirofumi MZ     return Shell_DefaultContextMenuCallBack(this, pdtobj);
874c2c66affSColin Finck }
875c2c66affSColin Finck 
876c2c66affSColin Finck /*************************************************************************
877c2c66affSColin Finck  * SHGetDesktopFolder            [SHELL32.@]
878c2c66affSColin Finck  */
879c2c66affSColin Finck HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
880c2c66affSColin Finck {
881c2c66affSColin Finck     HRESULT    hres = S_OK;
882c2c66affSColin Finck     TRACE("\n");
883c2c66affSColin Finck 
884c2c66affSColin Finck     if(!psf) return E_INVALIDARG;
885c2c66affSColin Finck     *psf = NULL;
886c2c66affSColin Finck     hres = CDesktopFolder::_CreatorClass::CreateInstance(NULL, IID_PPV_ARG(IShellFolder, psf));
887c2c66affSColin Finck 
888c2c66affSColin Finck     TRACE("-- %p->(%p)\n",psf, *psf);
889c2c66affSColin Finck     return hres;
890c2c66affSColin Finck }