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 
27*d05dcf6aSKatayama Hirofumi MZ STDMETHODIMP
28*d05dcf6aSKatayama Hirofumi MZ CShellUrlStub::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten,
29*d05dcf6aSKatayama Hirofumi MZ                                 PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes)
30*d05dcf6aSKatayama Hirofumi MZ {
31*d05dcf6aSKatayama Hirofumi MZ     LPWSTR pch;
32*d05dcf6aSKatayama Hirofumi MZ     INT cch, csidl;
33*d05dcf6aSKatayama Hirofumi MZ     HRESULT hr = HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND);
34*d05dcf6aSKatayama Hirofumi MZ     PARSEDURLW ParsedURL = { sizeof(ParsedURL) };
35*d05dcf6aSKatayama Hirofumi MZ 
36*d05dcf6aSKatayama Hirofumi MZ     ::ParseURLW(lpszDisplayName, &ParsedURL);
37*d05dcf6aSKatayama Hirofumi MZ 
38*d05dcf6aSKatayama Hirofumi MZ     DWORD attrs = (pdwAttributes ? *pdwAttributes : 0) | SFGAO_STREAM;
39*d05dcf6aSKatayama Hirofumi MZ     if (ParsedURL.pszSuffix[0] == L':' && ParsedURL.pszSuffix[1] == L':')
40*d05dcf6aSKatayama Hirofumi MZ     {
41*d05dcf6aSKatayama Hirofumi MZ         CComPtr<IShellFolder> psfDesktop;
42*d05dcf6aSKatayama Hirofumi MZ         hr = SHGetDesktopFolder(&psfDesktop);
43*d05dcf6aSKatayama Hirofumi MZ         if (SUCCEEDED(hr))
44*d05dcf6aSKatayama Hirofumi MZ         {
45*d05dcf6aSKatayama Hirofumi MZ             CComPtr<IBindCtx> pBindCtx;
46*d05dcf6aSKatayama Hirofumi MZ             hr = ::CreateBindCtx(0, &pBindCtx);
47*d05dcf6aSKatayama Hirofumi MZ             if (SUCCEEDED(hr))
48*d05dcf6aSKatayama Hirofumi MZ             {
49*d05dcf6aSKatayama Hirofumi MZ                 BIND_OPTS BindOps = { sizeof(BindOps) };
50*d05dcf6aSKatayama Hirofumi MZ                 BindOps.grfMode = STGM_CREATE;
51*d05dcf6aSKatayama Hirofumi MZ                 pBindCtx->SetBindOptions(&BindOps);
52*d05dcf6aSKatayama Hirofumi MZ                 hr = psfDesktop->ParseDisplayName(hwndOwner, pBindCtx,
53*d05dcf6aSKatayama Hirofumi MZ                                                   (LPWSTR)ParsedURL.pszSuffix,
54*d05dcf6aSKatayama Hirofumi MZ                                                   pchEaten, ppidl, &attrs);
55*d05dcf6aSKatayama Hirofumi MZ             }
56*d05dcf6aSKatayama Hirofumi MZ         }
57*d05dcf6aSKatayama Hirofumi MZ     }
58*d05dcf6aSKatayama Hirofumi MZ     else
59*d05dcf6aSKatayama Hirofumi MZ     {
60*d05dcf6aSKatayama Hirofumi MZ         csidl = Shell_ParseSpecialFolder(ParsedURL.pszSuffix, &pch, &cch);
61*d05dcf6aSKatayama Hirofumi MZ         if (csidl == -1)
62*d05dcf6aSKatayama Hirofumi MZ         {
63*d05dcf6aSKatayama Hirofumi MZ             ERR("\n");
64*d05dcf6aSKatayama Hirofumi MZ             return hr;
65*d05dcf6aSKatayama Hirofumi MZ         }
66*d05dcf6aSKatayama Hirofumi MZ 
67*d05dcf6aSKatayama Hirofumi MZ         CComHeapPtr<ITEMIDLIST> pidlLocation;
68*d05dcf6aSKatayama Hirofumi MZ         hr = SHGetFolderLocation(hwndOwner, (csidl | CSIDL_FLAG_CREATE), NULL, 0, &pidlLocation);
69*d05dcf6aSKatayama Hirofumi MZ         if (FAILED_UNEXPECTEDLY(hr))
70*d05dcf6aSKatayama Hirofumi MZ             return hr;
71*d05dcf6aSKatayama Hirofumi MZ 
72*d05dcf6aSKatayama Hirofumi MZ         if (pch && *pch)
73*d05dcf6aSKatayama Hirofumi MZ         {
74*d05dcf6aSKatayama Hirofumi MZ             CComPtr<IShellFolder> psfFolder;
75*d05dcf6aSKatayama Hirofumi MZ             hr = SHBindToObject(NULL, pidlLocation, IID_PPV_ARG(IShellFolder, &psfFolder));
76*d05dcf6aSKatayama Hirofumi MZ             if (SUCCEEDED(hr))
77*d05dcf6aSKatayama Hirofumi MZ             {
78*d05dcf6aSKatayama Hirofumi MZ                 CComHeapPtr<ITEMIDLIST> pidlNew;
79*d05dcf6aSKatayama Hirofumi MZ                 hr = psfFolder->ParseDisplayName(hwndOwner, pbc, pch, pchEaten, &pidlNew, &attrs);
80*d05dcf6aSKatayama Hirofumi MZ                 if (SUCCEEDED(hr))
81*d05dcf6aSKatayama Hirofumi MZ                 {
82*d05dcf6aSKatayama Hirofumi MZ                     hr = SHILCombine(pidlLocation, pidlNew, ppidl);
83*d05dcf6aSKatayama Hirofumi MZ                     if (pchEaten)
84*d05dcf6aSKatayama Hirofumi MZ                         *pchEaten += cch;
85*d05dcf6aSKatayama Hirofumi MZ                 }
86*d05dcf6aSKatayama Hirofumi MZ             }
87*d05dcf6aSKatayama Hirofumi MZ         }
88*d05dcf6aSKatayama Hirofumi MZ         else
89*d05dcf6aSKatayama Hirofumi MZ         {
90*d05dcf6aSKatayama Hirofumi MZ             if (attrs)
91*d05dcf6aSKatayama Hirofumi MZ                 hr = SHGetNameAndFlagsW(pidlLocation, 0, NULL, 0, &attrs);
92*d05dcf6aSKatayama Hirofumi MZ 
93*d05dcf6aSKatayama Hirofumi MZ             if (SUCCEEDED(hr))
94*d05dcf6aSKatayama Hirofumi MZ             {
95*d05dcf6aSKatayama Hirofumi MZ                 if (pchEaten)
96*d05dcf6aSKatayama Hirofumi MZ                     *pchEaten = cch;
97*d05dcf6aSKatayama Hirofumi MZ                 *ppidl = pidlLocation.Detach();
98*d05dcf6aSKatayama Hirofumi MZ             }
99*d05dcf6aSKatayama Hirofumi MZ         }
100*d05dcf6aSKatayama Hirofumi MZ     }
101*d05dcf6aSKatayama Hirofumi MZ 
102*d05dcf6aSKatayama Hirofumi MZ     // FIXME: SHWindowsPolicy
103*d05dcf6aSKatayama Hirofumi MZ     if (SUCCEEDED(hr) && (attrs & SFGAO_STREAM) &&
104*d05dcf6aSKatayama Hirofumi MZ         !BindCtx_ContainsObject(pbc, STR_PARSE_SHELL_PROTOCOL_TO_FILE_OBJECTS))
105*d05dcf6aSKatayama Hirofumi MZ     {
106*d05dcf6aSKatayama Hirofumi MZ         ILFree(*ppidl);
107*d05dcf6aSKatayama Hirofumi MZ         *ppidl = NULL;
108*d05dcf6aSKatayama Hirofumi MZ         hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
109*d05dcf6aSKatayama Hirofumi MZ     }
110*d05dcf6aSKatayama Hirofumi MZ 
111*d05dcf6aSKatayama Hirofumi MZ     if (pdwAttributes)
112*d05dcf6aSKatayama Hirofumi MZ         *pdwAttributes = attrs;
113*d05dcf6aSKatayama Hirofumi MZ 
114*d05dcf6aSKatayama Hirofumi MZ     // FIXME: SHWindowsPolicy
115*d05dcf6aSKatayama Hirofumi MZ     if (FAILED(hr) && !Shell_FailForceReturn(hr))
116*d05dcf6aSKatayama Hirofumi MZ         hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
117*d05dcf6aSKatayama Hirofumi MZ 
118*d05dcf6aSKatayama Hirofumi MZ     return hr;
119*d05dcf6aSKatayama Hirofumi MZ }
120*d05dcf6aSKatayama Hirofumi MZ 
121*d05dcf6aSKatayama Hirofumi MZ STDMETHODIMP
122*d05dcf6aSKatayama Hirofumi MZ CFileUrlStub::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten,
123*d05dcf6aSKatayama Hirofumi MZ                                PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes)
124*d05dcf6aSKatayama Hirofumi MZ {
125*d05dcf6aSKatayama Hirofumi MZ     WCHAR szPath[MAX_PATH];
126*d05dcf6aSKatayama Hirofumi MZ     DWORD cchPath = _countof(szPath);
127*d05dcf6aSKatayama Hirofumi MZ     HRESULT hr = PathCreateFromUrlW(lpszDisplayName, szPath, &cchPath, 0);
128*d05dcf6aSKatayama Hirofumi MZ     if (FAILED_UNEXPECTEDLY(hr))
129*d05dcf6aSKatayama Hirofumi MZ         return hr;
130*d05dcf6aSKatayama Hirofumi MZ 
131*d05dcf6aSKatayama Hirofumi MZ     CComPtr<IShellFolder> psfDesktop;
132*d05dcf6aSKatayama Hirofumi MZ     hr = SHGetDesktopFolder(&psfDesktop);
133*d05dcf6aSKatayama Hirofumi MZ     if (FAILED_UNEXPECTEDLY(hr))
134*d05dcf6aSKatayama Hirofumi MZ         return hr;
135*d05dcf6aSKatayama Hirofumi MZ 
136*d05dcf6aSKatayama Hirofumi MZ     return psfDesktop->ParseDisplayName(hwndOwner, pbc, szPath, pchEaten, ppidl, pdwAttributes);
137*d05dcf6aSKatayama Hirofumi MZ }
138*d05dcf6aSKatayama Hirofumi MZ 
139*d05dcf6aSKatayama Hirofumi MZ STDMETHODIMP
140*d05dcf6aSKatayama Hirofumi MZ CIDListUrlStub::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten,
141*d05dcf6aSKatayama Hirofumi MZ                                  PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes)
142*d05dcf6aSKatayama Hirofumi MZ {
143*d05dcf6aSKatayama Hirofumi MZ     return E_NOTIMPL; // FIXME
144*d05dcf6aSKatayama Hirofumi MZ }
145*d05dcf6aSKatayama Hirofumi MZ 
146*d05dcf6aSKatayama Hirofumi MZ STDMETHODIMP
147*d05dcf6aSKatayama Hirofumi MZ CHttpUrlStub::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten,
148*d05dcf6aSKatayama Hirofumi MZ                                PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes)
149*d05dcf6aSKatayama Hirofumi MZ {
150*d05dcf6aSKatayama Hirofumi MZ     return E_NOTIMPL; // FIXME
151*d05dcf6aSKatayama Hirofumi MZ }
152*d05dcf6aSKatayama Hirofumi MZ 
153*d05dcf6aSKatayama Hirofumi MZ BOOL CDesktopFolder::_TryUrlJunctions(
154*d05dcf6aSKatayama Hirofumi MZ     LPCWSTR pcszURL,
155*d05dcf6aSKatayama Hirofumi MZ     IBindCtx *pBindCtx,
156*d05dcf6aSKatayama Hirofumi MZ     IShellFolder **ppShellFolder,
157*d05dcf6aSKatayama Hirofumi MZ     LPITEMIDLIST *ppidl)
158*d05dcf6aSKatayama Hirofumi MZ {
159*d05dcf6aSKatayama Hirofumi MZ     PARSEDURLW ParsedURL = { sizeof(ParsedURL) };
160*d05dcf6aSKatayama Hirofumi MZ     ::ParseURLW(pcszURL, &ParsedURL);
161*d05dcf6aSKatayama Hirofumi MZ 
162*d05dcf6aSKatayama Hirofumi MZ     *ppShellFolder = NULL;
163*d05dcf6aSKatayama Hirofumi MZ     switch (ParsedURL.nScheme)
164*d05dcf6aSKatayama Hirofumi MZ     {
165*d05dcf6aSKatayama Hirofumi MZ         case URL_SCHEME_FILE:
166*d05dcf6aSKatayama Hirofumi MZ             *ppShellFolder = &m_FileUrlStub;
167*d05dcf6aSKatayama Hirofumi MZ             break;
168*d05dcf6aSKatayama Hirofumi MZ 
169*d05dcf6aSKatayama Hirofumi MZ         case URL_SCHEME_HTTP:
170*d05dcf6aSKatayama Hirofumi MZ         case URL_SCHEME_HTTPS:
171*d05dcf6aSKatayama Hirofumi MZ             if (!BindCtx_ContainsObject(pBindCtx, STR_PARSE_PREFER_FOLDER_BROWSING))
172*d05dcf6aSKatayama Hirofumi MZ                 break;
173*d05dcf6aSKatayama Hirofumi MZ             *ppShellFolder = &m_HttpUrlStub;
174*d05dcf6aSKatayama Hirofumi MZ             break;
175*d05dcf6aSKatayama Hirofumi MZ 
176*d05dcf6aSKatayama Hirofumi MZ         case URL_SCHEME_SHELL:
177*d05dcf6aSKatayama Hirofumi MZ             *ppShellFolder = &m_ShellUrlStub;
178*d05dcf6aSKatayama Hirofumi MZ             break;
179*d05dcf6aSKatayama Hirofumi MZ 
180*d05dcf6aSKatayama Hirofumi MZ         case URL_SCHEME_MSSHELLROOTED:
181*d05dcf6aSKatayama Hirofumi MZ             *ppShellFolder = NULL; // FIXME
182*d05dcf6aSKatayama Hirofumi MZ             break;
183*d05dcf6aSKatayama Hirofumi MZ 
184*d05dcf6aSKatayama Hirofumi MZ         case URL_SCHEME_MSSHELLIDLIST:
185*d05dcf6aSKatayama Hirofumi MZ             *ppShellFolder = &m_IDListUrlStub;
186*d05dcf6aSKatayama Hirofumi MZ             break;
187*d05dcf6aSKatayama Hirofumi MZ 
188*d05dcf6aSKatayama Hirofumi MZ         default:
189*d05dcf6aSKatayama Hirofumi MZ             break;
190*d05dcf6aSKatayama Hirofumi MZ     }
191*d05dcf6aSKatayama Hirofumi MZ 
192*d05dcf6aSKatayama Hirofumi MZ     return !!*ppShellFolder;
193*d05dcf6aSKatayama Hirofumi MZ }
194*d05dcf6aSKatayama Hirofumi MZ 
195*d05dcf6aSKatayama Hirofumi MZ BOOL CDesktopFolder::_GetParentForParsing(
196*d05dcf6aSKatayama Hirofumi MZ     LPCWSTR pszPath,
197*d05dcf6aSKatayama Hirofumi MZ     IBindCtx *pbc,
198*d05dcf6aSKatayama Hirofumi MZ     IShellFolder **ppParentFolder,
199*d05dcf6aSKatayama Hirofumi MZ     LPITEMIDLIST *ppidlParent)
200*d05dcf6aSKatayama Hirofumi MZ {
201*d05dcf6aSKatayama Hirofumi MZ     WCHAR wch = *pszPath;
202*d05dcf6aSKatayama Hirofumi MZ     if (((L'A' <= wch && wch <= L'Z') || (L'a' <= wch && wch <= L'z')) && (pszPath[1] == ':'))
203*d05dcf6aSKatayama Hirofumi MZ         *ppidlParent = _ILCreateMyComputer();
204*d05dcf6aSKatayama Hirofumi MZ     else if (PathIsUNCW(pszPath))
205*d05dcf6aSKatayama Hirofumi MZ         *ppidlParent = _ILCreateNetwork();
206*d05dcf6aSKatayama Hirofumi MZ     else if (UrlIsW(pszPath, URLIS_URL) && !SHSkipJunctionBinding(pbc, NULL))
207*d05dcf6aSKatayama Hirofumi MZ         _TryUrlJunctions(pszPath, pbc, ppParentFolder, ppidlParent);
208*d05dcf6aSKatayama Hirofumi MZ 
209*d05dcf6aSKatayama Hirofumi MZ     if (!*ppParentFolder && *ppidlParent)
210*d05dcf6aSKatayama Hirofumi MZ         SHBindToObject(NULL, *ppidlParent, IID_PPV_ARG(IShellFolder, ppParentFolder));
211*d05dcf6aSKatayama Hirofumi MZ 
212*d05dcf6aSKatayama Hirofumi MZ     return *ppParentFolder != NULL;
213*d05dcf6aSKatayama Hirofumi MZ }
214*d05dcf6aSKatayama Hirofumi MZ 
215*d05dcf6aSKatayama Hirofumi MZ HRESULT CDesktopFolder::_ChildParseDisplayName(
216*d05dcf6aSKatayama Hirofumi MZ     IShellFolder *pParentFolder,
217*d05dcf6aSKatayama Hirofumi MZ     LPCITEMIDLIST pidlParent,
218*d05dcf6aSKatayama Hirofumi MZ     HWND hwndOwner,
219*d05dcf6aSKatayama Hirofumi MZ     IBindCtx *pBindCtx,
220*d05dcf6aSKatayama Hirofumi MZ     LPWSTR lpszDisplayName,
221*d05dcf6aSKatayama Hirofumi MZ     DWORD *pchEaten,
222*d05dcf6aSKatayama Hirofumi MZ     LPITEMIDLIST *ppidl,
223*d05dcf6aSKatayama Hirofumi MZ     DWORD *pdwAttributes)
224*d05dcf6aSKatayama Hirofumi MZ {
225*d05dcf6aSKatayama Hirofumi MZ     LPITEMIDLIST pidlChild;
226*d05dcf6aSKatayama Hirofumi MZ     HRESULT hr = pParentFolder->ParseDisplayName(hwndOwner, pBindCtx, lpszDisplayName,
227*d05dcf6aSKatayama Hirofumi MZ                                                  pchEaten, &pidlChild, pdwAttributes);
228*d05dcf6aSKatayama Hirofumi MZ     if (FAILED(hr))
229*d05dcf6aSKatayama Hirofumi MZ         return hr;
230*d05dcf6aSKatayama Hirofumi MZ 
231*d05dcf6aSKatayama Hirofumi MZ     if (pidlParent)
232*d05dcf6aSKatayama Hirofumi MZ     {
233*d05dcf6aSKatayama Hirofumi MZ         *ppidl = ILCombine(pidlParent, pidlChild);
234*d05dcf6aSKatayama Hirofumi MZ         ILFree(pidlChild);
235*d05dcf6aSKatayama Hirofumi MZ     }
236*d05dcf6aSKatayama Hirofumi MZ     else
237*d05dcf6aSKatayama Hirofumi MZ     {
238*d05dcf6aSKatayama Hirofumi MZ         *ppidl = pidlChild;
239*d05dcf6aSKatayama Hirofumi MZ     }
240*d05dcf6aSKatayama Hirofumi MZ 
241*d05dcf6aSKatayama Hirofumi MZ     return (*ppidl ? S_OK : E_OUTOFMEMORY);
242*d05dcf6aSKatayama Hirofumi MZ }
243*d05dcf6aSKatayama Hirofumi MZ 
244c2c66affSColin Finck /*
245c2c66affSColin Finck CDesktopFolder should create two file system folders internally, one representing the
246c2c66affSColin Finck user's desktop folder, and the other representing the common desktop folder. It should
247c2c66affSColin Finck also create a CRegFolder to represent the virtual items that exist only in the registry.
248c2c66affSColin Finck The CRegFolder is aggregated by the CDesktopFolder, and queries for the CLSID_IShellFolder,
249c2c66affSColin Finck CLSID_IShellFolder2, or CLSID_IShellIconOverlay interfaces prefer the CRegFolder
250c2c66affSColin Finck implementation.
251c2c66affSColin Finck The CDesktopFolderEnum class should create two enumerators, one for each of the file
252c2c66affSColin Finck system folders, and enumerate the contents of each folder. Since the CRegFolder
253c2c66affSColin Finck implementation of IShellFolder::EnumObjects enumerates the virtual items, the
254c2c66affSColin Finck CDesktopFolderEnum is only responsible for returning the physical items.
255c2c66affSColin Finck CDesktopFolderEnum is incorrect where it filters My Computer from the enumeration
256c2c66affSColin Finck if the new start menu is used. The CDesktopViewCallback is responsible for filtering
257c2c66affSColin Finck it from the view by handling the IncludeObject query to return S_FALSE. The enumerator
258c2c66affSColin Finck always shows My Computer.
259c2c66affSColin Finck */
260c2c66affSColin Finck 
261c2c66affSColin Finck /* Undocumented functions from shdocvw */
262c2c66affSColin Finck extern "C" HRESULT WINAPI IEParseDisplayNameWithBCW(DWORD codepage, LPCWSTR lpszDisplayName, LPBC pbc, LPITEMIDLIST *ppidl);
263c2c66affSColin Finck 
264c2c66affSColin Finck static const WCHAR ClassicStartMenuW[] = L"SOFTWARE\\Microsoft\\Windows\\"
265c2c66affSColin Finck     L"CurrentVersion\\Explorer\\HideDesktopIcons\\ClassicStartMenu";
266c2c66affSColin Finck 
267c2c66affSColin Finck static INT
268c2c66affSColin Finck IsNamespaceExtensionHidden(const WCHAR *iid)
269c2c66affSColin Finck {
270c2c66affSColin Finck     DWORD Result, dwResult;
271c2c66affSColin Finck     dwResult = sizeof(DWORD);
272c2c66affSColin Finck 
273c2c66affSColin Finck     if (RegGetValueW(HKEY_CURRENT_USER, /* FIXME use NewStartPanel when activated */
274c2c66affSColin Finck                      ClassicStartMenuW,
275c2c66affSColin Finck                      iid,
276c2c66affSColin Finck                      RRF_RT_DWORD,
277c2c66affSColin Finck                      NULL,
278c2c66affSColin Finck                      &Result,
279c2c66affSColin Finck                      &dwResult) != ERROR_SUCCESS)
280c2c66affSColin Finck     {
281c2c66affSColin Finck         return -1;
282c2c66affSColin Finck     }
283c2c66affSColin Finck 
284c2c66affSColin Finck     return Result;
285c2c66affSColin Finck }
286c2c66affSColin Finck 
287c2c66affSColin Finck static INT IsNamespaceExtensionHidden(LPCITEMIDLIST pidl)
288c2c66affSColin Finck {
289c2c66affSColin Finck     GUID const *clsid = _ILGetGUIDPointer (pidl);
290c2c66affSColin Finck     if (!clsid)
291c2c66affSColin Finck         return -1;
292c2c66affSColin Finck 
293c2c66affSColin Finck     WCHAR pwszGuid[CHARS_IN_GUID];
294c2c66affSColin Finck     SHELL32_GUIDToStringW(*clsid, pwszGuid);
295c2c66affSColin Finck     return IsNamespaceExtensionHidden(pwszGuid);
296c2c66affSColin Finck }
297c2c66affSColin Finck 
298c2c66affSColin Finck class CDesktopFolderEnum :
299c2c66affSColin Finck     public CEnumIDListBase
300c2c66affSColin Finck {
301c2c66affSColin Finck     private:
302c2c66affSColin Finck //    CComPtr                                fDesktopEnumerator;
303c2c66affSColin Finck //    CComPtr                                fCommonDesktopEnumerator;
304c2c66affSColin Finck     public:
305c2c66affSColin Finck 
306c2c66affSColin Finck         void AddItemsFromClassicStartMenuKey(HKEY hKeyRoot)
307c2c66affSColin Finck         {
308c2c66affSColin Finck             DWORD dwResult;
309c2c66affSColin Finck             HKEY hkey;
310c2c66affSColin Finck             DWORD j = 0, dwVal, Val, dwType, dwIID;
311c2c66affSColin Finck             LONG r;
312c2c66affSColin Finck             WCHAR iid[50];
313c2c66affSColin Finck             LPITEMIDLIST pidl;
314c2c66affSColin Finck 
315c2c66affSColin Finck             dwResult = RegOpenKeyExW(hKeyRoot, ClassicStartMenuW, 0, KEY_READ, &hkey);
316c2c66affSColin Finck             if (dwResult != ERROR_SUCCESS)
317c2c66affSColin Finck                 return;
318c2c66affSColin Finck 
319c2c66affSColin Finck             while(1)
320c2c66affSColin Finck             {
321c2c66affSColin Finck                 dwVal = sizeof(Val);
322c2c66affSColin Finck                 dwIID = sizeof(iid) / sizeof(WCHAR);
323c2c66affSColin Finck 
324c2c66affSColin Finck                 r = RegEnumValueW(hkey, j++, iid, &dwIID, NULL, &dwType, (LPBYTE)&Val, &dwVal);
325c2c66affSColin Finck                 if (r != ERROR_SUCCESS)
326c2c66affSColin Finck                     break;
327c2c66affSColin Finck 
328c2c66affSColin Finck                 if (Val == 0 && dwType == REG_DWORD)
329c2c66affSColin Finck                 {
330c2c66affSColin Finck                     pidl = _ILCreateGuidFromStrW(iid);
331c2c66affSColin Finck                     if (pidl != NULL)
332c2c66affSColin Finck                     {
333c2c66affSColin Finck                         if (!HasItemWithCLSID(pidl))
334c2c66affSColin Finck                             AddToEnumList(pidl);
335c2c66affSColin Finck                         else
336c2c66affSColin Finck                             SHFree(pidl);
337c2c66affSColin Finck                     }
338c2c66affSColin Finck                 }
339c2c66affSColin Finck             }
340c2c66affSColin Finck             RegCloseKey(hkey);
341c2c66affSColin Finck         }
342c2c66affSColin Finck 
343c2c66affSColin Finck         HRESULT WINAPI Initialize(DWORD dwFlags,IEnumIDList * pRegEnumerator, IEnumIDList *pDesktopEnumerator, IEnumIDList *pCommonDesktopEnumerator)
344c2c66affSColin Finck         {
345c2c66affSColin Finck             BOOL ret = TRUE;
346c2c66affSColin Finck             LPITEMIDLIST pidl;
347c2c66affSColin Finck 
348c2c66affSColin Finck             static const WCHAR MyDocumentsClassString[] = L"{450D8FBA-AD25-11D0-98A8-0800361B1103}";
34952bc5f7cSKatayama Hirofumi MZ             static const WCHAR InternetClassString[] = L"{871C5380-42A0-1069-A2EA-08002B30309D}";
350c2c66affSColin Finck 
351c2c66affSColin Finck             TRACE("(%p)->(flags=0x%08x)\n", this, dwFlags);
352c2c66affSColin Finck 
353c2c66affSColin Finck             /* enumerate the root folders */
354c2c66affSColin Finck             if (dwFlags & SHCONTF_FOLDERS)
355c2c66affSColin Finck             {
356c2c66affSColin Finck                 AddToEnumList(_ILCreateMyComputer());
357c2c66affSColin Finck                 if (IsNamespaceExtensionHidden(MyDocumentsClassString) < 1)
358c2c66affSColin Finck                     AddToEnumList(_ILCreateMyDocuments());
35952bc5f7cSKatayama Hirofumi MZ                 if (IsNamespaceExtensionHidden(InternetClassString) < 1)
36052bc5f7cSKatayama Hirofumi MZ                     AddToEnumList(_ILCreateIExplore());
361c2c66affSColin Finck 
362c2c66affSColin Finck                 DWORD dwFetched;
363c2c66affSColin Finck                 while((S_OK == pRegEnumerator->Next(1, &pidl, &dwFetched)) && dwFetched)
364c2c66affSColin Finck                 {
365c2c66affSColin Finck                     if (IsNamespaceExtensionHidden(pidl) < 1)
366c2c66affSColin Finck                     {
367c2c66affSColin Finck                         if (!HasItemWithCLSID(pidl))
368c2c66affSColin Finck                             AddToEnumList(pidl);
369c2c66affSColin Finck                         else
370c2c66affSColin Finck                             SHFree(pidl);
371c2c66affSColin Finck                     }
372c2c66affSColin Finck                 }
373c2c66affSColin Finck                 AddItemsFromClassicStartMenuKey(HKEY_LOCAL_MACHINE);
374c2c66affSColin Finck                 AddItemsFromClassicStartMenuKey(HKEY_CURRENT_USER);
375c2c66affSColin Finck             }
376c2c66affSColin Finck 
377c2c66affSColin Finck             /* Enumerate the items in the two fs folders */
378c2c66affSColin Finck             AppendItemsFromEnumerator(pDesktopEnumerator);
379c2c66affSColin Finck             AppendItemsFromEnumerator(pCommonDesktopEnumerator);
380c2c66affSColin Finck 
381c2c66affSColin Finck             return ret ? S_OK : E_FAIL;
382c2c66affSColin Finck         }
383c2c66affSColin Finck 
384c2c66affSColin Finck 
385c2c66affSColin Finck         BEGIN_COM_MAP(CDesktopFolderEnum)
386c2c66affSColin Finck         COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
387c2c66affSColin Finck         END_COM_MAP()
388c2c66affSColin Finck };
389c2c66affSColin Finck 
390c2c66affSColin Finck int SHELL_ConfirmMsgBox(HWND hWnd, LPWSTR lpszText, LPWSTR lpszCaption, HICON hIcon, BOOL bYesToAll);
391c2c66affSColin Finck 
392c2c66affSColin Finck static const shvheader DesktopSFHeader[] = {
393c2c66affSColin Finck     {IDS_SHV_COLUMN_NAME, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 15},
394c2c66affSColin Finck     {IDS_SHV_COLUMN_COMMENTS, SHCOLSTATE_TYPE_STR, LVCFMT_LEFT, 10},
395c2c66affSColin Finck     {IDS_SHV_COLUMN_TYPE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10},
396c2c66affSColin Finck     {IDS_SHV_COLUMN_SIZE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
397c2c66affSColin Finck     {IDS_SHV_COLUMN_MODIFIED, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 12},
398c2c66affSColin Finck     {IDS_SHV_COLUMN_ATTRIBUTES, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10}
399c2c66affSColin Finck };
400c2c66affSColin Finck 
401c2c66affSColin Finck #define DESKTOPSHELLVIEWCOLUMNS 6
402c2c66affSColin Finck 
403c2c66affSColin Finck static const DWORD dwDesktopAttributes =
404c2c66affSColin Finck     SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR |
405730d81b9SGiannis Adamopoulos     SFGAO_STORAGEANCESTOR | SFGAO_HASPROPSHEET | SFGAO_STORAGE;
406c2c66affSColin Finck static const DWORD dwMyComputerAttributes =
407c2c66affSColin Finck     SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
408c2c66affSColin Finck     SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK;
409c2c66affSColin Finck static DWORD dwMyNetPlacesAttributes =
410c2c66affSColin Finck     SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
411c2c66affSColin Finck     SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK;
412c2c66affSColin Finck 
413c2c66affSColin Finck CDesktopFolder::CDesktopFolder() :
414c2c66affSColin Finck     sPathTarget(NULL),
415c2c66affSColin Finck     pidlRoot(NULL)
416c2c66affSColin Finck {
417c2c66affSColin Finck }
418c2c66affSColin Finck 
419c2c66affSColin Finck CDesktopFolder::~CDesktopFolder()
420c2c66affSColin Finck {
421c2c66affSColin Finck }
422c2c66affSColin Finck 
423c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::FinalConstruct()
424c2c66affSColin Finck {
425c2c66affSColin Finck     WCHAR szMyPath[MAX_PATH];
426c2c66affSColin Finck     HRESULT hr;
427c2c66affSColin Finck 
428c2c66affSColin Finck     /* Create the root pidl */
429c2c66affSColin Finck     pidlRoot = _ILCreateDesktop();
430c2c66affSColin Finck     if (!pidlRoot)
431c2c66affSColin Finck         return E_OUTOFMEMORY;
432c2c66affSColin Finck 
433c2c66affSColin Finck     /* Create the inner fs folder */
434c2c66affSColin Finck     hr = SHELL32_CoCreateInitSF(pidlRoot,
435c2c66affSColin Finck                                 &CLSID_ShellFSFolder,
436c2c66affSColin Finck                                 CSIDL_DESKTOPDIRECTORY,
437c2c66affSColin Finck                                 IID_PPV_ARG(IShellFolder2, &m_DesktopFSFolder));
438c2c66affSColin Finck     if (FAILED_UNEXPECTEDLY(hr))
439c2c66affSColin Finck         return hr;
440c2c66affSColin Finck 
441c2c66affSColin Finck     /* Create the inner shared fs folder. Dont fail on failure. */
442c2c66affSColin Finck     hr = SHELL32_CoCreateInitSF(pidlRoot,
443c2c66affSColin Finck                                 &CLSID_ShellFSFolder,
444c2c66affSColin Finck                                 CSIDL_COMMON_DESKTOPDIRECTORY,
445c2c66affSColin Finck                                 IID_PPV_ARG(IShellFolder2, &m_SharedDesktopFSFolder));
446c2c66affSColin Finck     if (FAILED_UNEXPECTEDLY(hr))
447c2c66affSColin Finck         return hr;
448c2c66affSColin Finck 
449c2c66affSColin Finck     /* Create the inner reg folder */
450c2c66affSColin Finck     hr = CRegFolder_CreateInstance(&CLSID_ShellDesktop,
451c2c66affSColin Finck                                    pidlRoot,
452c2c66affSColin Finck                                    L"",
453c2c66affSColin Finck                                    L"Desktop",
454c2c66affSColin Finck                                    IID_PPV_ARG(IShellFolder2, &m_regFolder));
455c2c66affSColin Finck     if (FAILED_UNEXPECTEDLY(hr))
456c2c66affSColin Finck         return hr;
457c2c66affSColin Finck 
458c2c66affSColin Finck     /* Cache the path to the user desktop directory */
459c2c66affSColin Finck     if (!SHGetSpecialFolderPathW( 0, szMyPath, CSIDL_DESKTOPDIRECTORY, TRUE ))
460c2c66affSColin Finck         return E_UNEXPECTED;
461c2c66affSColin Finck 
462c2c66affSColin Finck     sPathTarget = (LPWSTR)SHAlloc((wcslen(szMyPath) + 1) * sizeof(WCHAR));
463c2c66affSColin Finck     if (!sPathTarget)
464c2c66affSColin Finck         return E_OUTOFMEMORY;
465c2c66affSColin Finck 
466c2c66affSColin Finck     wcscpy(sPathTarget, szMyPath);
467c2c66affSColin Finck     return S_OK;
468c2c66affSColin Finck }
469c2c66affSColin Finck 
470c2c66affSColin Finck HRESULT CDesktopFolder::_GetSFFromPidl(LPCITEMIDLIST pidl, IShellFolder2** psf)
471c2c66affSColin Finck {
472c2c66affSColin Finck     WCHAR szFileName[MAX_PATH];
473c2c66affSColin Finck 
474c2c66affSColin Finck     if (_ILIsSpecialFolder(pidl))
475c2c66affSColin Finck         return m_regFolder->QueryInterface(IID_PPV_ARG(IShellFolder2, psf));
476c2c66affSColin Finck 
477c2c66affSColin Finck     lstrcpynW(szFileName, sPathTarget, MAX_PATH - 1);
478c2c66affSColin Finck     PathAddBackslashW(szFileName);
479c2c66affSColin Finck     int cLen = wcslen(szFileName);
480c2c66affSColin Finck 
481c2c66affSColin Finck     if (!_ILSimpleGetTextW(pidl, szFileName + cLen, MAX_PATH - cLen))
482c2c66affSColin Finck         return E_FAIL;
483c2c66affSColin Finck 
484c2c66affSColin Finck     if (GetFileAttributes(szFileName) == INVALID_FILE_ATTRIBUTES)
485c2c66affSColin Finck         return m_SharedDesktopFSFolder->QueryInterface(IID_PPV_ARG(IShellFolder2, psf));
486c2c66affSColin Finck     else
487c2c66affSColin Finck         return m_DesktopFSFolder->QueryInterface(IID_PPV_ARG(IShellFolder2, psf));
488c2c66affSColin Finck }
489c2c66affSColin Finck 
490c2c66affSColin Finck /**************************************************************************
491c2c66affSColin Finck  *    CDesktopFolder::ParseDisplayName
492c2c66affSColin Finck  *
493c2c66affSColin Finck  * NOTES
494c2c66affSColin Finck  *    "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
495c2c66affSColin Finck  *    to MyComputer
496c2c66affSColin Finck  */
497c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::ParseDisplayName(
498c2c66affSColin Finck     HWND hwndOwner,
499c2c66affSColin Finck     LPBC pbc,
500c2c66affSColin Finck     LPOLESTR lpszDisplayName,
501c2c66affSColin Finck     DWORD *pchEaten,
502c2c66affSColin Finck     PIDLIST_RELATIVE *ppidl,
503c2c66affSColin Finck     DWORD *pdwAttributes)
504c2c66affSColin Finck {
505c2c66affSColin Finck     TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
506c2c66affSColin Finck            this, hwndOwner, pbc, lpszDisplayName, debugstr_w(lpszDisplayName),
507c2c66affSColin Finck            pchEaten, ppidl, pdwAttributes);
508c2c66affSColin Finck 
509c2c66affSColin Finck     if (!ppidl)
510c2c66affSColin Finck         return E_INVALIDARG;
511c2c66affSColin Finck 
512c2c66affSColin Finck     *ppidl = NULL;
513c2c66affSColin Finck 
514c2c66affSColin Finck     if (!lpszDisplayName)
515c2c66affSColin Finck         return E_INVALIDARG;
516c2c66affSColin Finck 
517*d05dcf6aSKatayama Hirofumi MZ     if (!*lpszDisplayName)
518*d05dcf6aSKatayama Hirofumi MZ     {
519*d05dcf6aSKatayama Hirofumi MZ         *ppidl = _ILCreateMyComputer();
520*d05dcf6aSKatayama Hirofumi MZ         return (*ppidl ? S_OK : E_OUTOFMEMORY);
521*d05dcf6aSKatayama Hirofumi MZ     }
522c2c66affSColin Finck 
523c2c66affSColin Finck     if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':')
524c2c66affSColin Finck     {
525*d05dcf6aSKatayama Hirofumi MZ         return m_regFolder->ParseDisplayName(hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl,
526*d05dcf6aSKatayama Hirofumi MZ                                              pdwAttributes);
527c2c66affSColin Finck     }
528*d05dcf6aSKatayama Hirofumi MZ 
529*d05dcf6aSKatayama Hirofumi MZ     HRESULT hr = E_INVALIDARG;
530*d05dcf6aSKatayama Hirofumi MZ     CComHeapPtr<ITEMIDLIST> pidlParent;
531*d05dcf6aSKatayama Hirofumi MZ     CComPtr<IShellFolder> pParentFolder;
532*d05dcf6aSKatayama Hirofumi MZ     if (_GetParentForParsing(lpszDisplayName, pbc, &pParentFolder, &pidlParent))
533c2c66affSColin Finck     {
534*d05dcf6aSKatayama Hirofumi MZ         if (pchEaten)
535*d05dcf6aSKatayama Hirofumi MZ             *pchEaten = 0;
536*d05dcf6aSKatayama Hirofumi MZ 
537*d05dcf6aSKatayama Hirofumi MZ         hr = _ChildParseDisplayName(pParentFolder,
538*d05dcf6aSKatayama Hirofumi MZ                                     pidlParent,
539*d05dcf6aSKatayama Hirofumi MZ                                     hwndOwner,
540*d05dcf6aSKatayama Hirofumi MZ                                     pbc,
541*d05dcf6aSKatayama Hirofumi MZ                                     lpszDisplayName,
542*d05dcf6aSKatayama Hirofumi MZ                                     pchEaten,
543*d05dcf6aSKatayama Hirofumi MZ                                     ppidl,
544*d05dcf6aSKatayama Hirofumi MZ                                     pdwAttributes);
545c2c66affSColin Finck         if (SUCCEEDED(hr))
546*d05dcf6aSKatayama Hirofumi MZ         {
547*d05dcf6aSKatayama Hirofumi MZ             if (BindCtx_ContainsObject(pbc, STR_PARSE_TRANSLATE_ALIASES))
548*d05dcf6aSKatayama Hirofumi MZ             {
549*d05dcf6aSKatayama Hirofumi MZ                 LPITEMIDLIST pidlAlias;
550*d05dcf6aSKatayama Hirofumi MZ                 if (SUCCEEDED(Shell_TranslateIDListAlias(*ppidl, NULL, &pidlAlias, 0xFFFF)))
551*d05dcf6aSKatayama Hirofumi MZ                 {
552*d05dcf6aSKatayama Hirofumi MZ                     ILFree(*ppidl);
553*d05dcf6aSKatayama Hirofumi MZ                     *ppidl = pidlAlias;
554*d05dcf6aSKatayama Hirofumi MZ                 }
555*d05dcf6aSKatayama Hirofumi MZ             }
556*d05dcf6aSKatayama Hirofumi MZ             return hr;
557*d05dcf6aSKatayama Hirofumi MZ         }
558*d05dcf6aSKatayama Hirofumi MZ     }
559*d05dcf6aSKatayama Hirofumi MZ 
560*d05dcf6aSKatayama Hirofumi MZ     if (Shell_FailForceReturn(hr))
561c2c66affSColin Finck         return hr;
562c2c66affSColin Finck 
563*d05dcf6aSKatayama Hirofumi MZ     if (BindCtx_ContainsObject(pbc, STR_DONT_PARSE_RELATIVE))
564*d05dcf6aSKatayama Hirofumi MZ         return E_INVALIDARG;
565c2c66affSColin Finck 
566*d05dcf6aSKatayama Hirofumi MZ     if (SHIsFileSysBindCtx(pbc, NULL) == S_OK)
567*d05dcf6aSKatayama Hirofumi MZ         return hr;
568*d05dcf6aSKatayama Hirofumi MZ 
569*d05dcf6aSKatayama Hirofumi MZ     BIND_OPTS BindOps = { sizeof(BindOps) };
570*d05dcf6aSKatayama Hirofumi MZ     BOOL bCreate = FALSE;
571*d05dcf6aSKatayama Hirofumi MZ     if (pbc && SUCCEEDED(pbc->GetBindOptions(&BindOps)) && (BindOps.grfMode & STGM_CREATE))
572*d05dcf6aSKatayama Hirofumi MZ     {
573*d05dcf6aSKatayama Hirofumi MZ         BindOps.grfMode &= ~STGM_CREATE;
574*d05dcf6aSKatayama Hirofumi MZ         bCreate = TRUE;
575*d05dcf6aSKatayama Hirofumi MZ         pbc->SetBindOptions(&BindOps);
576c2c66affSColin Finck     }
577c2c66affSColin Finck 
578*d05dcf6aSKatayama Hirofumi MZ     if (m_DesktopFSFolder)
579c2c66affSColin Finck     {
580*d05dcf6aSKatayama Hirofumi MZ         hr = m_DesktopFSFolder->ParseDisplayName(hwndOwner,
581*d05dcf6aSKatayama Hirofumi MZ                                                  pbc,
582*d05dcf6aSKatayama Hirofumi MZ                                                  lpszDisplayName,
583*d05dcf6aSKatayama Hirofumi MZ                                                  pchEaten,
584*d05dcf6aSKatayama Hirofumi MZ                                                  ppidl,
585*d05dcf6aSKatayama Hirofumi MZ                                                  pdwAttributes);
586c2c66affSColin Finck     }
587c2c66affSColin Finck 
588*d05dcf6aSKatayama Hirofumi MZ     if (FAILED(hr) && m_SharedDesktopFSFolder)
589*d05dcf6aSKatayama Hirofumi MZ     {
590*d05dcf6aSKatayama Hirofumi MZ         hr = m_SharedDesktopFSFolder->ParseDisplayName(hwndOwner,
591*d05dcf6aSKatayama Hirofumi MZ                                                        pbc,
592*d05dcf6aSKatayama Hirofumi MZ                                                        lpszDisplayName,
593*d05dcf6aSKatayama Hirofumi MZ                                                        pchEaten,
594*d05dcf6aSKatayama Hirofumi MZ                                                        ppidl,
595*d05dcf6aSKatayama Hirofumi MZ                                                        pdwAttributes);
596*d05dcf6aSKatayama Hirofumi MZ     }
597*d05dcf6aSKatayama Hirofumi MZ 
598*d05dcf6aSKatayama Hirofumi MZ     if (FAILED(hr) && bCreate && m_DesktopFSFolder)
599*d05dcf6aSKatayama Hirofumi MZ     {
600*d05dcf6aSKatayama Hirofumi MZ         BindOps.grfMode |= STGM_CREATE;
601*d05dcf6aSKatayama Hirofumi MZ         pbc->SetBindOptions(&BindOps);
602*d05dcf6aSKatayama Hirofumi MZ         hr = m_DesktopFSFolder->ParseDisplayName(hwndOwner,
603*d05dcf6aSKatayama Hirofumi MZ                                                  pbc,
604*d05dcf6aSKatayama Hirofumi MZ                                                  lpszDisplayName,
605*d05dcf6aSKatayama Hirofumi MZ                                                  pchEaten,
606*d05dcf6aSKatayama Hirofumi MZ                                                  ppidl,
607*d05dcf6aSKatayama Hirofumi MZ                                                  pdwAttributes);
608*d05dcf6aSKatayama Hirofumi MZ     }
609c2c66affSColin Finck 
610c2c66affSColin Finck     TRACE ("(%p)->(-- ret=0x%08x)\n", this, hr);
611c2c66affSColin Finck 
612c2c66affSColin Finck     return hr;
613c2c66affSColin Finck }
614c2c66affSColin Finck 
615c2c66affSColin Finck /**************************************************************************
616c2c66affSColin Finck  *        CDesktopFolder::EnumObjects
617c2c66affSColin Finck  */
618c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
619c2c66affSColin Finck {
620c2c66affSColin Finck     CComPtr<IEnumIDList> pRegEnumerator;
621c2c66affSColin Finck     CComPtr<IEnumIDList> pDesktopEnumerator;
622c2c66affSColin Finck     CComPtr<IEnumIDList> pCommonDesktopEnumerator;
623c2c66affSColin Finck     HRESULT hr;
624c2c66affSColin Finck 
625c2c66affSColin Finck     hr = m_regFolder->EnumObjects(hwndOwner, dwFlags, &pRegEnumerator);
626c2c66affSColin Finck     if (FAILED(hr))
627c2c66affSColin Finck         ERR("EnumObjects for reg folder failed\n");
628c2c66affSColin Finck 
629c2c66affSColin Finck     hr = m_DesktopFSFolder->EnumObjects(hwndOwner, dwFlags, &pDesktopEnumerator);
630c2c66affSColin Finck     if (FAILED(hr))
631c2c66affSColin Finck         ERR("EnumObjects for desktop fs folder failed\n");
632c2c66affSColin Finck 
633c2c66affSColin Finck     hr = m_SharedDesktopFSFolder->EnumObjects(hwndOwner, dwFlags, &pCommonDesktopEnumerator);
634c2c66affSColin Finck     if (FAILED(hr))
635c2c66affSColin Finck         ERR("EnumObjects for shared desktop fs folder failed\n");
636c2c66affSColin Finck 
637c2c66affSColin Finck     return ShellObjectCreatorInit<CDesktopFolderEnum>(dwFlags,pRegEnumerator, pDesktopEnumerator, pCommonDesktopEnumerator, IID_PPV_ARG(IEnumIDList, ppEnumIDList));
638c2c66affSColin Finck }
639c2c66affSColin Finck 
640c2c66affSColin Finck /**************************************************************************
641c2c66affSColin Finck  *        CDesktopFolder::BindToObject
642c2c66affSColin Finck  */
643c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::BindToObject(
644c2c66affSColin Finck     PCUIDLIST_RELATIVE pidl,
645c2c66affSColin Finck     LPBC pbcReserved,
646c2c66affSColin Finck     REFIID riid,
647c2c66affSColin Finck     LPVOID *ppvOut)
648c2c66affSColin Finck {
649c2c66affSColin Finck     if (!pidl)
650c2c66affSColin Finck         return E_INVALIDARG;
651c2c66affSColin Finck 
652c2c66affSColin Finck     CComPtr<IShellFolder2> psf;
653c2c66affSColin Finck     HRESULT hr = _GetSFFromPidl(pidl, &psf);
654c2c66affSColin Finck     if (FAILED_UNEXPECTEDLY(hr))
655c2c66affSColin Finck         return hr;
656c2c66affSColin Finck 
657c2c66affSColin Finck     return psf->BindToObject(pidl, pbcReserved, riid, ppvOut);
658c2c66affSColin Finck }
659c2c66affSColin Finck 
660c2c66affSColin Finck /**************************************************************************
661c2c66affSColin Finck  *    CDesktopFolder::BindToStorage
662c2c66affSColin Finck  */
663c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::BindToStorage(
664c2c66affSColin Finck     PCUIDLIST_RELATIVE pidl,
665c2c66affSColin Finck     LPBC pbcReserved,
666c2c66affSColin Finck     REFIID riid,
667c2c66affSColin Finck     LPVOID *ppvOut)
668c2c66affSColin Finck {
669c2c66affSColin Finck     FIXME ("(%p)->(pidl=%p,%p,%s,%p) stub\n",
670c2c66affSColin Finck            this, pidl, pbcReserved, shdebugstr_guid (&riid), ppvOut);
671c2c66affSColin Finck 
672c2c66affSColin Finck     *ppvOut = NULL;
673c2c66affSColin Finck     return E_NOTIMPL;
674c2c66affSColin Finck }
675c2c66affSColin Finck 
676c2c66affSColin Finck /**************************************************************************
677c2c66affSColin Finck  *     CDesktopFolder::CompareIDs
678c2c66affSColin Finck  */
679c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
680c2c66affSColin Finck {
681c2c66affSColin Finck     bool bIsDesktopFolder1, bIsDesktopFolder2;
682c2c66affSColin Finck 
683c2c66affSColin Finck     if (!pidl1 || !pidl2)
684c2c66affSColin Finck     {
685c2c66affSColin Finck         ERR("Got null pidl pointer (%Ix %p %p)!\n", lParam, pidl1, pidl2);
686c2c66affSColin Finck         return E_INVALIDARG;
687c2c66affSColin Finck     }
688c2c66affSColin Finck 
689c2c66affSColin Finck     bIsDesktopFolder1 = _ILIsDesktop(pidl1);
690c2c66affSColin Finck     bIsDesktopFolder2 = _ILIsDesktop(pidl2);
691c2c66affSColin Finck     if (bIsDesktopFolder1 || bIsDesktopFolder2)
692c2c66affSColin Finck         return MAKE_COMPARE_HRESULT(bIsDesktopFolder1 - bIsDesktopFolder2);
693c2c66affSColin Finck 
694c2c66affSColin Finck     if (_ILIsSpecialFolder(pidl1) || _ILIsSpecialFolder(pidl2))
695c2c66affSColin Finck         return m_regFolder->CompareIDs(lParam, pidl1, pidl2);
696c2c66affSColin Finck 
697c2c66affSColin Finck     return m_DesktopFSFolder->CompareIDs(lParam, pidl1, pidl2);
698c2c66affSColin Finck }
699c2c66affSColin Finck 
700c2c66affSColin Finck /**************************************************************************
701c2c66affSColin Finck  *    CDesktopFolder::CreateViewObject
702c2c66affSColin Finck  */
703c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::CreateViewObject(
704c2c66affSColin Finck     HWND hwndOwner,
705c2c66affSColin Finck     REFIID riid,
706c2c66affSColin Finck     LPVOID *ppvOut)
707c2c66affSColin Finck {
708c2c66affSColin Finck     HRESULT hr = E_INVALIDARG;
709c2c66affSColin Finck 
710c2c66affSColin Finck     TRACE ("(%p)->(hwnd=%p,%s,%p)\n",
711c2c66affSColin Finck            this, hwndOwner, shdebugstr_guid (&riid), ppvOut);
712c2c66affSColin Finck 
713c2c66affSColin Finck     if (!ppvOut)
714c2c66affSColin Finck         return hr;
715c2c66affSColin Finck 
716c2c66affSColin Finck     *ppvOut = NULL;
717c2c66affSColin Finck 
718c2c66affSColin Finck     if (IsEqualIID (riid, IID_IDropTarget))
719c2c66affSColin Finck     {
720c2c66affSColin Finck         hr = m_DesktopFSFolder->CreateViewObject(hwndOwner, riid, ppvOut);
721c2c66affSColin Finck     }
722c2c66affSColin Finck     else if (IsEqualIID (riid, IID_IContextMenu))
723c2c66affSColin Finck     {
724c2c66affSColin Finck             HKEY hKeys[16];
725c2c66affSColin Finck             UINT cKeys = 0;
726c2c66affSColin Finck             AddClassKeyToArray(L"Directory\\Background", hKeys, &cKeys);
727c2c66affSColin Finck 
728c2c66affSColin Finck             DEFCONTEXTMENU dcm;
729c2c66affSColin Finck             dcm.hwnd = hwndOwner;
730c2c66affSColin Finck             dcm.pcmcb = this;
731c2c66affSColin Finck             dcm.pidlFolder = pidlRoot;
732c2c66affSColin Finck             dcm.psf = this;
733c2c66affSColin Finck             dcm.cidl = 0;
734c2c66affSColin Finck             dcm.apidl = NULL;
735c2c66affSColin Finck             dcm.cKeys = cKeys;
736c2c66affSColin Finck             dcm.aKeys = hKeys;
737c2c66affSColin Finck             dcm.punkAssociationInfo = NULL;
738c2c66affSColin Finck             hr = SHCreateDefaultContextMenu (&dcm, riid, ppvOut);
739c2c66affSColin Finck     }
740c2c66affSColin Finck     else if (IsEqualIID (riid, IID_IShellView))
741c2c66affSColin Finck     {
742c2c66affSColin Finck         SFV_CREATE sfvparams = {sizeof(SFV_CREATE), this};
743c2c66affSColin Finck         hr = SHCreateShellFolderView(&sfvparams, (IShellView**)ppvOut);
744c2c66affSColin Finck     }
745c2c66affSColin Finck     TRACE ("-- (%p)->(interface=%p)\n", this, ppvOut);
746c2c66affSColin Finck     return hr;
747c2c66affSColin Finck }
748c2c66affSColin Finck 
749c2c66affSColin Finck /**************************************************************************
750c2c66affSColin Finck  *  CDesktopFolder::GetAttributesOf
751c2c66affSColin Finck  */
752c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetAttributesOf(
753c2c66affSColin Finck     UINT cidl,
754c2c66affSColin Finck     PCUITEMID_CHILD_ARRAY apidl,
755c2c66affSColin Finck     DWORD *rgfInOut)
756c2c66affSColin Finck {
757c2c66affSColin Finck     HRESULT hr = S_OK;
758c2c66affSColin Finck 
759c2c66affSColin Finck     TRACE("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
760c2c66affSColin Finck           this, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
761c2c66affSColin Finck 
762c2c66affSColin Finck     if (cidl && !apidl)
763c2c66affSColin Finck         return E_INVALIDARG;
764c2c66affSColin Finck 
765c2c66affSColin Finck     if (*rgfInOut == 0)
766c2c66affSColin Finck         *rgfInOut = ~0;
767c2c66affSColin Finck 
768c2c66affSColin Finck     if(cidl == 0)
769c2c66affSColin Finck         *rgfInOut &= dwDesktopAttributes;
770c2c66affSColin Finck     else
771c2c66affSColin Finck     {
772c2c66affSColin Finck         /* TODO: always add SFGAO_CANLINK */
773c2c66affSColin Finck         for (UINT i = 0; i < cidl; ++i)
774c2c66affSColin Finck         {
775c2c66affSColin Finck             pdump(*apidl);
776c2c66affSColin Finck             if (_ILIsDesktop(*apidl))
777c2c66affSColin Finck                 *rgfInOut &= dwDesktopAttributes;
778c2c66affSColin Finck             else if (_ILIsMyComputer(apidl[i]))
779c2c66affSColin Finck                 *rgfInOut &= dwMyComputerAttributes;
780c2c66affSColin Finck             else if (_ILIsNetHood(apidl[i]))
781c2c66affSColin Finck                 *rgfInOut &= dwMyNetPlacesAttributes;
782c2c66affSColin Finck             else if (_ILIsFolder(apidl[i]) || _ILIsValue(apidl[i]) || _ILIsSpecialFolder(apidl[i]))
783c2c66affSColin Finck             {
784c2c66affSColin Finck                 CComPtr<IShellFolder2> psf;
785c2c66affSColin Finck                 HRESULT hr = _GetSFFromPidl(apidl[i], &psf);
786c2c66affSColin Finck                 if (FAILED_UNEXPECTEDLY(hr))
787c2c66affSColin Finck                     continue;
788c2c66affSColin Finck 
789c2c66affSColin Finck                 psf->GetAttributesOf(1, &apidl[i], rgfInOut);
790c2c66affSColin Finck             }
791c2c66affSColin Finck             else
792c2c66affSColin Finck                 ERR("Got an unknown pidl type!!!\n");
793c2c66affSColin Finck         }
794c2c66affSColin Finck     }
795c2c66affSColin Finck     /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
796c2c66affSColin Finck     *rgfInOut &= ~SFGAO_VALIDATE;
797c2c66affSColin Finck 
798c2c66affSColin Finck     TRACE("-- result=0x%08x\n", *rgfInOut);
799c2c66affSColin Finck 
800c2c66affSColin Finck     return hr;
801c2c66affSColin Finck }
802c2c66affSColin Finck 
803c2c66affSColin Finck /**************************************************************************
804c2c66affSColin Finck  *    CDesktopFolder::GetUIObjectOf
805c2c66affSColin Finck  *
806c2c66affSColin Finck  * PARAMETERS
807c2c66affSColin Finck  *  HWND           hwndOwner, //[in ] Parent window for any output
808c2c66affSColin Finck  *  UINT           cidl,      //[in ] array size
809c2c66affSColin Finck  *  LPCITEMIDLIST* apidl,     //[in ] simple pidl array
810c2c66affSColin Finck  *  REFIID         riid,      //[in ] Requested Interface
811c2c66affSColin Finck  *  UINT*          prgfInOut, //[   ] reserved
812c2c66affSColin Finck  *  LPVOID*        ppvObject) //[out] Resulting Interface
813c2c66affSColin Finck  *
814c2c66affSColin Finck  */
815c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetUIObjectOf(
816c2c66affSColin Finck     HWND hwndOwner,
817c2c66affSColin Finck     UINT cidl,
818c2c66affSColin Finck     PCUITEMID_CHILD_ARRAY apidl,
819c2c66affSColin Finck     REFIID riid,
820c2c66affSColin Finck     UINT *prgfInOut,
821c2c66affSColin Finck     LPVOID *ppvOut)
822c2c66affSColin Finck {
823c2c66affSColin Finck     LPVOID pObj = NULL;
824c2c66affSColin Finck     HRESULT hr = E_INVALIDARG;
825c2c66affSColin Finck 
826c2c66affSColin Finck     TRACE ("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n",
827c2c66affSColin Finck            this, hwndOwner, cidl, apidl, shdebugstr_guid (&riid), prgfInOut, ppvOut);
828c2c66affSColin Finck 
829c2c66affSColin Finck     if (!ppvOut)
830c2c66affSColin Finck         return hr;
831c2c66affSColin Finck 
832c2c66affSColin Finck     *ppvOut = NULL;
833c2c66affSColin Finck 
834c2c66affSColin Finck     if (cidl == 1 && !_ILIsSpecialFolder(apidl[0]))
835c2c66affSColin Finck     {
836c2c66affSColin Finck         CComPtr<IShellFolder2> psf;
837c2c66affSColin Finck         HRESULT hr = _GetSFFromPidl(apidl[0], &psf);
838c2c66affSColin Finck         if (FAILED_UNEXPECTEDLY(hr))
839c2c66affSColin Finck             return hr;
840c2c66affSColin Finck 
841c2c66affSColin Finck         return psf->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, ppvOut);
842c2c66affSColin Finck     }
843c2c66affSColin Finck 
844c2c66affSColin Finck     if (IsEqualIID (riid, IID_IContextMenu))
845c2c66affSColin Finck     {
8460d077c30SIoannis Adamopoulos         if (cidl > 0 && _ILIsSpecialFolder(apidl[0]))
847c2c66affSColin Finck         {
848c2c66affSColin Finck             hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
849c2c66affSColin Finck         }
850c2c66affSColin Finck         else
851c2c66affSColin Finck         {
852c2c66affSColin Finck             /* Do not use the context menu of the CFSFolder here. */
853c2c66affSColin 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 */
854c2c66affSColin Finck             /* Otherwise operations like that involve items from both user and shared desktop will not work */
855c2c66affSColin Finck             HKEY hKeys[16];
856c2c66affSColin Finck             UINT cKeys = 0;
8570d077c30SIoannis Adamopoulos             if (cidl > 0)
8580d077c30SIoannis Adamopoulos             {
859a83e40f6SWhindmar Saksit                 AddFSClassKeysToArray(cidl, apidl, hKeys, &cKeys);
8600d077c30SIoannis Adamopoulos             }
861c2c66affSColin Finck 
862c2c66affSColin Finck             DEFCONTEXTMENU dcm;
863c2c66affSColin Finck             dcm.hwnd = hwndOwner;
864c2c66affSColin Finck             dcm.pcmcb = this;
865c2c66affSColin Finck             dcm.pidlFolder = pidlRoot;
866c2c66affSColin Finck             dcm.psf = this;
867c2c66affSColin Finck             dcm.cidl = cidl;
868c2c66affSColin Finck             dcm.apidl = apidl;
869c2c66affSColin Finck             dcm.cKeys = cKeys;
870c2c66affSColin Finck             dcm.aKeys = hKeys;
871c2c66affSColin Finck             dcm.punkAssociationInfo = NULL;
872c2c66affSColin Finck             hr = SHCreateDefaultContextMenu (&dcm, riid, &pObj);
873c2c66affSColin Finck         }
874c2c66affSColin Finck     }
875c2c66affSColin Finck     else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1))
876c2c66affSColin Finck     {
877c3132711SMark Jansen         hr = IDataObject_Constructor( hwndOwner, pidlRoot, apidl, cidl, TRUE, (IDataObject **)&pObj);
878c2c66affSColin Finck     }
879c2c66affSColin Finck     else if ((IsEqualIID (riid, IID_IExtractIconA) || IsEqualIID (riid, IID_IExtractIconW)) && (cidl == 1))
880c2c66affSColin Finck     {
881c2c66affSColin Finck         hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
882c2c66affSColin Finck     }
883c2c66affSColin Finck     else if (IsEqualIID (riid, IID_IDropTarget) && (cidl == 1))
884c2c66affSColin Finck     {
885c2c66affSColin Finck         CComPtr<IShellFolder> psfChild;
886c2c66affSColin Finck         hr = this->BindToObject(apidl[0], NULL, IID_PPV_ARG(IShellFolder, &psfChild));
887c2c66affSColin Finck         if (FAILED_UNEXPECTEDLY(hr))
888c2c66affSColin Finck             return hr;
889c2c66affSColin Finck 
890c2c66affSColin Finck         return psfChild->CreateViewObject(NULL, riid, ppvOut);
891c2c66affSColin Finck     }
892c2c66affSColin Finck     else
893c2c66affSColin Finck         hr = E_NOINTERFACE;
894c2c66affSColin Finck 
895c2c66affSColin Finck     if (SUCCEEDED(hr) && !pObj)
896c2c66affSColin Finck         hr = E_OUTOFMEMORY;
897c2c66affSColin Finck 
898c2c66affSColin Finck     *ppvOut = pObj;
899c2c66affSColin Finck     TRACE ("(%p)->hr=0x%08x\n", this, hr);
900c2c66affSColin Finck     return hr;
901c2c66affSColin Finck }
902c2c66affSColin Finck 
903c2c66affSColin Finck /**************************************************************************
904c2c66affSColin Finck  *    CDesktopFolder::GetDisplayNameOf
905c2c66affSColin Finck  *
906c2c66affSColin Finck  * NOTES
907c2c66affSColin Finck  *    special case: pidl = null gives desktop-name back
908c2c66affSColin Finck  */
909c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet)
910c2c66affSColin Finck {
911c2c66affSColin Finck     TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet);
912c2c66affSColin Finck     pdump (pidl);
913c2c66affSColin Finck 
914c2c66affSColin Finck     if (!strRet)
915c2c66affSColin Finck         return E_INVALIDARG;
916c2c66affSColin Finck 
917c2c66affSColin Finck     if (!_ILIsPidlSimple (pidl))
918c2c66affSColin Finck     {
919c2c66affSColin Finck         return SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, strRet);
920c2c66affSColin Finck     }
921c2c66affSColin Finck     else if (_ILIsDesktop(pidl))
922c2c66affSColin Finck     {
923c2c66affSColin Finck         if ((GET_SHGDN_RELATION(dwFlags) == SHGDN_NORMAL) && (GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING))
924c2c66affSColin Finck             return SHSetStrRet(strRet, sPathTarget);
925c2c66affSColin Finck         else
926c2c66affSColin Finck             return m_regFolder->GetDisplayNameOf(pidl, dwFlags, strRet);
927c2c66affSColin Finck     }
928c2c66affSColin Finck 
929c2c66affSColin Finck     /* file system folder or file rooted at the desktop */
930c2c66affSColin Finck     CComPtr<IShellFolder2> psf;
931c2c66affSColin Finck     HRESULT hr = _GetSFFromPidl(pidl, &psf);
932c2c66affSColin Finck     if (FAILED_UNEXPECTEDLY(hr))
933c2c66affSColin Finck         return hr;
934c2c66affSColin Finck 
935c2c66affSColin Finck     return psf->GetDisplayNameOf(pidl, dwFlags, strRet);
936c2c66affSColin Finck }
937c2c66affSColin Finck 
938c2c66affSColin Finck /**************************************************************************
939c2c66affSColin Finck  *  CDesktopFolder::SetNameOf
940c2c66affSColin Finck  *  Changes the name of a file object or subfolder, possibly changing its item
941c2c66affSColin Finck  *  identifier in the process.
942c2c66affSColin Finck  *
943c2c66affSColin Finck  * PARAMETERS
944c2c66affSColin Finck  *  HWND          hwndOwner,  //[in ] Owner window for output
945c2c66affSColin Finck  *  LPCITEMIDLIST pidl,       //[in ] simple pidl of item to change
946c2c66affSColin Finck  *  LPCOLESTR     lpszName,   //[in ] the items new display name
947c2c66affSColin Finck  *  DWORD         dwFlags,    //[in ] SHGNO formatting flags
948c2c66affSColin Finck  *  LPITEMIDLIST* ppidlOut)   //[out] simple pidl returned
949c2c66affSColin Finck  */
950c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::SetNameOf(
951c2c66affSColin Finck     HWND hwndOwner,
952c2c66affSColin Finck     PCUITEMID_CHILD pidl,    /* simple pidl */
953c2c66affSColin Finck     LPCOLESTR lpName,
954c2c66affSColin Finck     DWORD dwFlags,
955c2c66affSColin Finck     PITEMID_CHILD *pPidlOut)
956c2c66affSColin Finck {
957c2c66affSColin Finck     CComPtr<IShellFolder2> psf;
958c2c66affSColin Finck     HRESULT hr = _GetSFFromPidl(pidl, &psf);
959c2c66affSColin Finck     if (FAILED_UNEXPECTEDLY(hr))
960c2c66affSColin Finck         return hr;
961c2c66affSColin Finck 
962c2c66affSColin Finck     return psf->SetNameOf(hwndOwner, pidl, lpName, dwFlags, pPidlOut);
963c2c66affSColin Finck }
964c2c66affSColin Finck 
965c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetDefaultSearchGUID(GUID *pguid)
966c2c66affSColin Finck {
967c2c66affSColin Finck     FIXME ("(%p)\n", this);
968c2c66affSColin Finck     return E_NOTIMPL;
969c2c66affSColin Finck }
970c2c66affSColin Finck 
971c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::EnumSearches(IEnumExtraSearch **ppenum)
972c2c66affSColin Finck {
973c2c66affSColin Finck     FIXME ("(%p)\n", this);
974c2c66affSColin Finck     return E_NOTIMPL;
975c2c66affSColin Finck }
976c2c66affSColin Finck 
977c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetDefaultColumn(DWORD dwRes, ULONG *pSort, ULONG *pDisplay)
978c2c66affSColin Finck {
979c2c66affSColin Finck     TRACE ("(%p)\n", this);
980c2c66affSColin Finck 
981c2c66affSColin Finck     if (pSort)
982c2c66affSColin Finck         *pSort = 0;
983c2c66affSColin Finck     if (pDisplay)
984c2c66affSColin Finck         *pDisplay = 0;
985c2c66affSColin Finck 
986c2c66affSColin Finck     return S_OK;
987c2c66affSColin Finck }
988c2c66affSColin Finck 
989c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags)
990c2c66affSColin Finck {
991c2c66affSColin Finck     TRACE ("(%p)\n", this);
992c2c66affSColin Finck 
993c2c66affSColin Finck     if (!pcsFlags || iColumn >= DESKTOPSHELLVIEWCOLUMNS)
994c2c66affSColin Finck         return E_INVALIDARG;
995c2c66affSColin Finck 
996c2c66affSColin Finck     *pcsFlags = DesktopSFHeader[iColumn].pcsFlags;
997c2c66affSColin Finck 
998c2c66affSColin Finck     return S_OK;
999c2c66affSColin Finck }
1000c2c66affSColin Finck 
1001c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetDetailsEx(
1002c2c66affSColin Finck     PCUITEMID_CHILD pidl,
1003c2c66affSColin Finck     const SHCOLUMNID *pscid,
1004c2c66affSColin Finck     VARIANT *pv)
1005c2c66affSColin Finck {
1006c2c66affSColin Finck     FIXME ("(%p)\n", this);
1007c2c66affSColin Finck 
1008c2c66affSColin Finck     return E_NOTIMPL;
1009c2c66affSColin Finck }
1010c2c66affSColin Finck 
1011c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetDetailsOf(
1012c2c66affSColin Finck     PCUITEMID_CHILD pidl,
1013c2c66affSColin Finck     UINT iColumn,
1014c2c66affSColin Finck     SHELLDETAILS *psd)
1015c2c66affSColin Finck {
1016c2c66affSColin Finck     if (!psd || iColumn >= DESKTOPSHELLVIEWCOLUMNS)
1017c2c66affSColin Finck         return E_INVALIDARG;
1018c2c66affSColin Finck 
1019c2c66affSColin Finck     if (!pidl)
1020c2c66affSColin Finck     {
1021c2c66affSColin Finck         psd->fmt = DesktopSFHeader[iColumn].fmt;
1022c2c66affSColin Finck         psd->cxChar = DesktopSFHeader[iColumn].cxChar;
1023c2c66affSColin Finck         return SHSetStrRet(&psd->str, DesktopSFHeader[iColumn].colnameid);
1024c2c66affSColin Finck     }
1025c2c66affSColin Finck 
1026c2c66affSColin Finck     CComPtr<IShellFolder2> psf;
1027c2c66affSColin Finck     HRESULT hr = _GetSFFromPidl(pidl, &psf);
1028c2c66affSColin Finck     if (FAILED_UNEXPECTEDLY(hr))
1029c2c66affSColin Finck         return hr;
1030c2c66affSColin Finck 
1031c2c66affSColin Finck     hr =  psf->GetDetailsOf(pidl, iColumn, psd);
1032c2c66affSColin Finck     if (FAILED_UNEXPECTEDLY(hr))
1033c2c66affSColin Finck         return hr;
1034c2c66affSColin Finck 
1035c2c66affSColin Finck     return hr;
1036c2c66affSColin Finck }
1037c2c66affSColin Finck 
1038c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::MapColumnToSCID(UINT column, SHCOLUMNID *pscid)
1039c2c66affSColin Finck {
1040c2c66affSColin Finck     FIXME ("(%p)\n", this);
1041c2c66affSColin Finck     return E_NOTIMPL;
1042c2c66affSColin Finck }
1043c2c66affSColin Finck 
1044c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::GetClassID(CLSID *lpClassId)
1045c2c66affSColin Finck {
1046c2c66affSColin Finck     TRACE ("(%p)\n", this);
1047c2c66affSColin Finck 
1048c2c66affSColin Finck     if (!lpClassId)
1049c2c66affSColin Finck         return E_POINTER;
1050c2c66affSColin Finck 
1051c2c66affSColin Finck     *lpClassId = CLSID_ShellDesktop;
1052c2c66affSColin Finck 
1053c2c66affSColin Finck     return S_OK;
1054c2c66affSColin Finck }
1055c2c66affSColin Finck 
10566b0d2c2aSThomas Faber HRESULT WINAPI CDesktopFolder::Initialize(PCIDLIST_ABSOLUTE pidl)
1057c2c66affSColin Finck {
1058c2c66affSColin Finck     TRACE ("(%p)->(%p)\n", this, pidl);
1059c2c66affSColin Finck 
10607e48c20bSGiannis Adamopoulos     if (!pidl)
10617e48c20bSGiannis Adamopoulos         return S_OK;
10627e48c20bSGiannis Adamopoulos 
1063c2c66affSColin Finck     return E_INVALIDARG;
1064c2c66affSColin Finck }
1065c2c66affSColin Finck 
1066b90c24d6SThomas Faber HRESULT WINAPI CDesktopFolder::GetCurFolder(PIDLIST_ABSOLUTE * pidl)
1067c2c66affSColin Finck {
1068c2c66affSColin Finck     TRACE ("(%p)->(%p)\n", this, pidl);
1069c2c66affSColin Finck 
1070c2c66affSColin Finck     if (!pidl)
1071c2c66affSColin Finck         return E_INVALIDARG; /* xp doesn't have this check and crashes on NULL */
1072c2c66affSColin Finck     *pidl = ILClone (pidlRoot);
1073c2c66affSColin Finck     return S_OK;
1074c2c66affSColin Finck }
1075c2c66affSColin Finck 
1076c2c66affSColin Finck HRESULT WINAPI CDesktopFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam)
1077c2c66affSColin Finck {
1078c2c66affSColin Finck     if (uMsg != DFM_MERGECONTEXTMENU && uMsg != DFM_INVOKECOMMAND)
1079c2c66affSColin Finck         return S_OK;
1080c2c66affSColin Finck 
1081c2c66affSColin Finck     /* no data object means no selection */
1082c2c66affSColin Finck     if (!pdtobj)
1083c2c66affSColin Finck     {
1084c2c66affSColin Finck         if (uMsg == DFM_INVOKECOMMAND && wParam == 0)
1085c2c66affSColin Finck         {
1086944aba1fSKatayama Hirofumi MZ             if (32 >= (UINT_PTR)ShellExecuteW(hwndOwner, L"open", L"rundll32.exe",
1087944aba1fSKatayama Hirofumi MZ                                               L"shell32.dll,Control_RunDLL desk.cpl", NULL, SW_SHOWNORMAL))
1088944aba1fSKatayama Hirofumi MZ             {
1089c2c66affSColin Finck                 return E_FAIL;
1090944aba1fSKatayama Hirofumi MZ             }
1091c2c66affSColin Finck             return S_OK;
1092c2c66affSColin Finck         }
1093c2c66affSColin Finck         else if (uMsg == DFM_MERGECONTEXTMENU)
1094c2c66affSColin Finck         {
1095c2c66affSColin Finck             QCMINFO *pqcminfo = (QCMINFO *)lParam;
1096c2c66affSColin Finck             HMENU hpopup = CreatePopupMenu();
1097c2c66affSColin Finck             _InsertMenuItemW(hpopup, 0, TRUE, 0, MFT_STRING, MAKEINTRESOURCEW(IDS_PROPERTIES), MFS_ENABLED);
10985bd86b84SMark Jansen             Shell_MergeMenus(pqcminfo->hmenu, hpopup, pqcminfo->indexMenu, pqcminfo->idCmdFirst++, pqcminfo->idCmdLast, MM_ADDSEPARATOR);
1099c2c66affSColin Finck             DestroyMenu(hpopup);
1100c2c66affSColin Finck         }
1101c2c66affSColin Finck 
1102c2c66affSColin Finck         return S_OK;
1103c2c66affSColin Finck     }
1104c2c66affSColin Finck 
11059192d39fSManuel Bachmann     if (uMsg != DFM_INVOKECOMMAND || wParam != DFM_CMD_PROPERTIES)
11069192d39fSManuel Bachmann         return S_OK;
11079192d39fSManuel Bachmann 
110855469633SKatayama Hirofumi MZ     return Shell_DefaultContextMenuCallBack(this, pdtobj);
1109c2c66affSColin Finck }
1110c2c66affSColin Finck 
1111c2c66affSColin Finck /*************************************************************************
1112c2c66affSColin Finck  * SHGetDesktopFolder            [SHELL32.@]
1113c2c66affSColin Finck  */
1114c2c66affSColin Finck HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
1115c2c66affSColin Finck {
1116c2c66affSColin Finck     HRESULT    hres = S_OK;
1117c2c66affSColin Finck     TRACE("\n");
1118c2c66affSColin Finck 
1119c2c66affSColin Finck     if(!psf) return E_INVALIDARG;
1120c2c66affSColin Finck     *psf = NULL;
1121c2c66affSColin Finck     hres = CDesktopFolder::_CreatorClass::CreateInstance(NULL, IID_PPV_ARG(IShellFolder, psf));
1122c2c66affSColin Finck 
1123c2c66affSColin Finck     TRACE("-- %p->(%p)\n",psf, *psf);
1124c2c66affSColin Finck     return hres;
1125c2c66affSColin Finck }
1126