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