ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

desktop.cpp
Go to the documentation of this file.
00001 /*
00002  *    Virtual Desktop Folder
00003  *
00004  *    Copyright 1997                Marcus Meissner
00005  *    Copyright 1998, 1999, 2002    Juergen Schmied
00006  *    Copyright 2009                Andrew Hill
00007  *
00008  * This library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00021  */
00022 
00023 #include <precomp.h>
00024 
00025 WINE_DEFAULT_DEBUG_CHANNEL(shell);
00026 
00027 /*
00028 CDesktopFolder should create two file system folders internally, one representing the
00029 user's desktop folder, and the other representing the common desktop folder. It should
00030 also create a CRegFolder to represent the virtual items that exist only in the registry.
00031 The CRegFolder is aggregated by the CDesktopFolder, and queries for the CLSID_IShellFolder,
00032 CLSID_IShellFolder2, or CLSID_IShellIconOverlay interfaces prefer the CRegFolder
00033 implementation.
00034 The CDesktopFolderEnum class should create two enumerators, one for each of the file
00035 system folders, and enumerate the contents of each folder. Since the CRegFolder
00036 implementation of IShellFolder::EnumObjects enumerates the virtual items, the
00037 CDesktopFolderEnum is only responsible for returning the physical items.
00038 CDesktopFolderEnum is incorrect where it filters My Computer from the enumeration
00039 if the new start menu is used. The CDesktopViewCallback is responsible for filtering
00040 it from the view by handling the IncludeObject query to return S_FALSE. The enumerator
00041 always shows My Computer.
00042 */
00043 
00044 /* Undocumented functions from shdocvw */
00045 extern "C" HRESULT WINAPI IEParseDisplayNameWithBCW(DWORD codepage, LPCWSTR lpszDisplayName, LPBC pbc, LPITEMIDLIST *ppidl);
00046 
00047 /***********************************************************************
00048 *     Desktopfolder implementation
00049 */
00050 
00051 class CDesktopFolder;
00052 
00053 class CDesktopFolderEnum :
00054     public IEnumIDListImpl
00055 {
00056     private:
00057 //    CComPtr                                fDesktopEnumerator;
00058 //    CComPtr                                fCommonDesktopEnumerator;
00059     public:
00060         CDesktopFolderEnum();
00061         ~CDesktopFolderEnum();
00062         HRESULT WINAPI Initialize(CDesktopFolder *desktopFolder, HWND hwndOwner, DWORD dwFlags);
00063 
00064         BEGIN_COM_MAP(CDesktopFolderEnum)
00065         COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
00066         END_COM_MAP()
00067 };
00068 
00069 int SHELL_ConfirmMsgBox(HWND hWnd, LPWSTR lpszText, LPWSTR lpszCaption, HICON hIcon, BOOL bYesToAll);
00070 
00071 static const shvheader DesktopSFHeader[] = {
00072     {IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
00073     {IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
00074     {IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
00075     {IDS_SHV_COLUMN4, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12},
00076     {IDS_SHV_COLUMN5, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5}
00077 };
00078 
00079 #define DESKTOPSHELLVIEWCOLUMNS 5
00080 
00081 CDesktopFolderEnum::CDesktopFolderEnum()
00082 {
00083 }
00084 
00085 CDesktopFolderEnum::~CDesktopFolderEnum()
00086 {
00087 }
00088 
00089 static const WCHAR ClassicStartMenuW[] = L"SOFTWARE\\Microsoft\\Windows\\"
00090     L"CurrentVersion\\Explorer\\HideDesktopIcons\\ClassicStartMenu";
00091 
00092 static INT
00093 IsNamespaceExtensionHidden(const WCHAR *iid)
00094 {
00095     DWORD Result, dwResult;
00096     dwResult = sizeof(DWORD);
00097 
00098     if (RegGetValueW(HKEY_CURRENT_USER, /* FIXME use NewStartPanel when activated */
00099                      ClassicStartMenuW,
00100                      iid,
00101                      RRF_RT_DWORD,
00102                      NULL,
00103                      &Result,
00104                      &dwResult) != ERROR_SUCCESS)
00105     {
00106         return -1;
00107     }
00108 
00109     return Result;
00110 }
00111 
00112 static VOID
00113 SetNamespaceExtensionVisibleStatus(const WCHAR * iid, DWORD dwStatus)
00114 {
00115     HKEY hKey;
00116 
00117     if (RegOpenKeyExW(HKEY_CURRENT_USER, ClassicStartMenuW, 0, KEY_WRITE, &hKey) == ERROR_SUCCESS)
00118     {
00119         RegSetValueExW(hKey, iid, 0, REG_DWORD, (LPBYTE)&dwStatus, sizeof(DWORD));
00120         RegCloseKey(hKey);
00121     }
00122 }
00123 
00124 /**************************************************************************
00125  *  CreateDesktopEnumList()
00126  */
00127 
00128 HRESULT WINAPI CDesktopFolderEnum::Initialize(CDesktopFolder *desktopFolder, HWND hwndOwner, DWORD dwFlags)
00129 {
00130     BOOL ret = TRUE;
00131     WCHAR szPath[MAX_PATH];
00132 
00133     static const WCHAR MyDocumentsClassString[] = L"{450D8FBA-AD25-11D0-98A8-0800361B1103}";
00134     static const WCHAR Desktop_NameSpaceW[] = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Desktop\\Namespace";
00135 
00136     TRACE("(%p)->(flags=0x%08x)\n", this, dwFlags);
00137 
00138     /* enumerate the root folders */
00139     if (dwFlags & SHCONTF_FOLDERS)
00140     {
00141         HKEY hkey;
00142         UINT i;
00143         DWORD dwResult;
00144 
00145         /* create the pidl for This item */
00146         if (IsNamespaceExtensionHidden(MyDocumentsClassString) < 1)
00147         {
00148             ret = AddToEnumList(_ILCreateMyDocuments());
00149         }
00150         ret = AddToEnumList(_ILCreateMyComputer());
00151 
00152         for (i = 0; i < 2; i++)
00153         {
00154             if (i == 0)
00155                 dwResult = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Desktop_NameSpaceW, 0, KEY_READ, &hkey);
00156             else
00157                 dwResult = RegOpenKeyExW(HKEY_CURRENT_USER, Desktop_NameSpaceW, 0, KEY_READ, &hkey);
00158 
00159             if (dwResult == ERROR_SUCCESS)
00160             {
00161                 WCHAR iid[50];
00162                 LPITEMIDLIST pidl;
00163                 int i = 0;
00164 
00165                 while (ret)
00166                 {
00167                     DWORD size;
00168                     LONG r;
00169 
00170                     size = sizeof (iid) / sizeof (iid[0]);
00171                     r = RegEnumKeyExW(hkey, i, iid, &size, 0, NULL, NULL, NULL);
00172                     if (ERROR_SUCCESS == r)
00173                     {
00174                         if (IsNamespaceExtensionHidden(iid) < 1)
00175                         {
00176                             pidl = _ILCreateGuidFromStrW(iid);
00177                             if (pidl != NULL)
00178                             {
00179                                 if (!HasItemWithCLSID(pidl))
00180                                 {
00181                                     ret = AddToEnumList(pidl);
00182                                 }
00183                                 else
00184                                 {
00185                                     SHFree(pidl);
00186                                 }
00187                             }
00188                         }
00189                     }
00190                     else if (ERROR_NO_MORE_ITEMS == r)
00191                         break;
00192                     else
00193                         ret = FALSE;
00194                     i++;
00195                 }
00196                 RegCloseKey(hkey);
00197             }
00198         }
00199         for (i = 0; i < 2; i++)
00200         {
00201             if (i == 0)
00202                 dwResult = RegOpenKeyExW(HKEY_LOCAL_MACHINE, ClassicStartMenuW, 0, KEY_READ, &hkey);
00203             else
00204                 dwResult = RegOpenKeyExW(HKEY_CURRENT_USER, ClassicStartMenuW, 0, KEY_READ, &hkey);
00205 
00206             if (dwResult == ERROR_SUCCESS)
00207             {
00208                 DWORD j = 0, dwVal, Val, dwType, dwIID;
00209                 LONG r;
00210                 WCHAR iid[50];
00211 
00212                 while(ret)
00213                 {
00214                     dwVal = sizeof(Val);
00215                     dwIID = sizeof(iid) / sizeof(WCHAR);
00216 
00217                     r = RegEnumValueW(hkey, j++, iid, &dwIID, NULL, &dwType, (LPBYTE)&Val, &dwVal);
00218                     if (r == ERROR_SUCCESS)
00219                     {
00220                         if (Val == 0 && dwType == REG_DWORD)
00221                         {
00222                             LPITEMIDLIST pidl = _ILCreateGuidFromStrW(iid);
00223                             if (pidl != NULL)
00224                             {
00225                                 if (!HasItemWithCLSID(pidl))
00226                                 {
00227                                     AddToEnumList(pidl);
00228                                 }
00229                                 else
00230                                 {
00231                                     SHFree(pidl);
00232                                 }
00233                             }
00234                         }
00235                     }
00236                     else if (ERROR_NO_MORE_ITEMS == r)
00237                         break;
00238                     else
00239                         ret = FALSE;
00240                 }
00241                 RegCloseKey(hkey);
00242             }
00243 
00244         }
00245     }
00246 
00247     /* enumerate the elements in %windir%\desktop */
00248     ret = ret && SHGetSpecialFolderPathW(0, szPath, CSIDL_DESKTOPDIRECTORY, FALSE);
00249     ret = ret && CreateFolderEnumList(szPath, dwFlags);
00250 
00251     ret = ret && SHGetSpecialFolderPathW(0, szPath, CSIDL_COMMON_DESKTOPDIRECTORY, FALSE);
00252     ret = ret && CreateFolderEnumList(szPath, dwFlags);
00253 
00254     return ret ? S_OK : E_FAIL;
00255 }
00256 
00257 CDesktopFolder::CDesktopFolder()
00258 {
00259     pidlRoot = NULL;
00260     sPathTarget = NULL;
00261 }
00262 
00263 CDesktopFolder::~CDesktopFolder()
00264 {
00265 }
00266 
00267 HRESULT WINAPI CDesktopFolder::FinalConstruct()
00268 {
00269     WCHAR                                szMyPath[MAX_PATH];
00270 
00271     if (!SHGetSpecialFolderPathW( 0, szMyPath, CSIDL_DESKTOPDIRECTORY, TRUE ))
00272         return E_UNEXPECTED;
00273 
00274     pidlRoot = _ILCreateDesktop();    /* my qualified pidl */
00275     sPathTarget = (LPWSTR)SHAlloc((wcslen(szMyPath) + 1) * sizeof(WCHAR));
00276     wcscpy(sPathTarget, szMyPath);
00277     return S_OK;
00278 }
00279 
00280 /**************************************************************************
00281  *    CDesktopFolder::ParseDisplayName
00282  *
00283  * NOTES
00284  *    "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" and "" binds
00285  *    to MyComputer
00286  */
00287 HRESULT WINAPI CDesktopFolder::ParseDisplayName(
00288     HWND hwndOwner,
00289     LPBC pbc,
00290     LPOLESTR lpszDisplayName,
00291     DWORD *pchEaten,
00292     LPITEMIDLIST *ppidl,
00293     DWORD *pdwAttributes)
00294 {
00295     WCHAR szElement[MAX_PATH];
00296     LPCWSTR szNext = NULL;
00297     LPITEMIDLIST pidlTemp = NULL;
00298     PARSEDURLW urldata;
00299     HRESULT hr = S_OK;
00300     CLSID clsid;
00301 
00302     TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
00303            this, hwndOwner, pbc, lpszDisplayName, debugstr_w(lpszDisplayName),
00304            pchEaten, ppidl, pdwAttributes);
00305 
00306     if (!ppidl)
00307         return E_INVALIDARG;
00308 
00309     if (!lpszDisplayName)
00310     {
00311         *ppidl = NULL;
00312         return E_INVALIDARG;
00313     }
00314 
00315     *ppidl = NULL;
00316 
00317     if (pchEaten)
00318         *pchEaten = 0;        /* strange but like the original */
00319 
00320     urldata.cbSize = sizeof(urldata);
00321 
00322     if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':')
00323     {
00324         szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
00325         TRACE ("-- element: %s\n", debugstr_w (szElement));
00326         CLSIDFromString (szElement + 2, &clsid);
00327         pidlTemp = _ILCreateGuid (PT_GUID, clsid);
00328     }
00329     else if (PathGetDriveNumberW (lpszDisplayName) >= 0)
00330     {
00331         /* it's a filesystem path with a drive. Let MyComputer/UnixDosFolder parse it */
00332         pidlTemp = _ILCreateMyComputer ();
00333         szNext = lpszDisplayName;
00334     }
00335     else if (PathIsUNCW(lpszDisplayName))
00336     {
00337         pidlTemp = _ILCreateNetwork();
00338         szNext = lpszDisplayName;
00339     }
00340     else if( (pidlTemp = SHELL32_CreatePidlFromBindCtx(pbc, lpszDisplayName)) )
00341     {
00342         *ppidl = pidlTemp;
00343         return S_OK;
00344     }
00345     else if (SUCCEEDED(ParseURLW(lpszDisplayName, &urldata)))
00346     {
00347         if (urldata.nScheme == URL_SCHEME_SHELL) /* handle shell: urls */
00348         {
00349             TRACE ("-- shell url: %s\n", debugstr_w(urldata.pszSuffix));
00350             SHCLSIDFromStringW (urldata.pszSuffix + 2, &clsid);
00351             pidlTemp = _ILCreateGuid (PT_GUID, clsid);
00352         }
00353         else
00354             return IEParseDisplayNameWithBCW(CP_ACP, lpszDisplayName, pbc, ppidl);
00355     }
00356     else
00357     {
00358         /* it's a filesystem path on the desktop. Let a FSFolder parse it */
00359 
00360         if (*lpszDisplayName)
00361         {
00362             WCHAR szPath[MAX_PATH];
00363             LPWSTR pathPtr;
00364 
00365             /* build a complete path to create a simple pidl */
00366             lstrcpynW(szPath, sPathTarget, MAX_PATH);
00367             pathPtr = PathAddBackslashW(szPath);
00368             if (pathPtr)
00369             {
00370                 lstrcpynW(pathPtr, lpszDisplayName, MAX_PATH - (pathPtr - szPath));
00371                 hr = _ILCreateFromPathW(szPath, &pidlTemp);
00372             }
00373             else
00374             {
00375                 /* should never reach here, but for completeness */
00376                 hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
00377             }
00378         }
00379         else
00380             pidlTemp = _ILCreateMyComputer();
00381 
00382         szNext = NULL;
00383     }
00384 
00385     if (SUCCEEDED(hr) && pidlTemp)
00386     {
00387         if (szNext && *szNext)
00388         {
00389             hr = SHELL32_ParseNextElement(this, hwndOwner, pbc,
00390                                           &pidlTemp, (LPOLESTR) szNext, pchEaten, pdwAttributes);
00391         }
00392         else
00393         {
00394             if (pdwAttributes && *pdwAttributes)
00395                 hr = SHELL32_GetItemAttributes((IShellFolder *)this,
00396                                                pidlTemp, pdwAttributes);
00397         }
00398     }
00399 
00400     if (SUCCEEDED(hr))
00401         *ppidl = pidlTemp;
00402     else
00403         *ppidl = NULL;
00404 
00405     TRACE ("(%p)->(-- ret=0x%08x)\n", this, hr);
00406 
00407     return hr;
00408 }
00409 
00410 /**************************************************************************
00411  *        CDesktopFolder::EnumObjects
00412  */
00413 HRESULT WINAPI CDesktopFolder::EnumObjects(
00414     HWND hwndOwner,
00415     DWORD dwFlags,
00416     LPENUMIDLIST *ppEnumIDList)
00417 {
00418     CComObject<CDesktopFolderEnum>            *theEnumerator;
00419     CComPtr<IEnumIDList>                    result;
00420     HRESULT                                    hResult;
00421 
00422     TRACE ("(%p)->(HWND=%p flags=0x%08x pplist=%p)\n", this, hwndOwner, dwFlags, ppEnumIDList);
00423 
00424     if (ppEnumIDList == NULL)
00425         return E_POINTER;
00426     *ppEnumIDList = NULL;
00427 
00428     ATLTRY (theEnumerator = new CComObject<CDesktopFolderEnum>);
00429 
00430     if (theEnumerator == NULL)
00431         return E_OUTOFMEMORY;
00432 
00433     hResult = theEnumerator->QueryInterface (IID_IEnumIDList, (void **)&result);
00434     if (FAILED (hResult))
00435     {
00436         delete theEnumerator;
00437         return hResult;
00438     }
00439 
00440     hResult = theEnumerator->Initialize (this, hwndOwner, dwFlags);
00441     if (FAILED (hResult))
00442         return hResult;
00443     *ppEnumIDList = result.Detach ();
00444 
00445     TRACE ("-- (%p)->(new ID List: %p)\n", this, *ppEnumIDList);
00446 
00447     return S_OK;
00448 }
00449 
00450 /**************************************************************************
00451  *        CDesktopFolder::BindToObject
00452  */
00453 HRESULT WINAPI CDesktopFolder::BindToObject(
00454     LPCITEMIDLIST pidl,
00455     LPBC pbcReserved,
00456     REFIID riid,
00457     LPVOID *ppvOut)
00458 {
00459     TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n",
00460            this, pidl, pbcReserved, shdebugstr_guid (&riid), ppvOut);
00461 
00462     return SHELL32_BindToChild( pidlRoot, sPathTarget, pidl, riid, ppvOut );
00463 }
00464 
00465 /**************************************************************************
00466  *    CDesktopFolder::BindToStorage
00467  */
00468 HRESULT WINAPI CDesktopFolder::BindToStorage(
00469     LPCITEMIDLIST pidl,
00470     LPBC pbcReserved,
00471     REFIID riid,
00472     LPVOID *ppvOut)
00473 {
00474     FIXME ("(%p)->(pidl=%p,%p,%s,%p) stub\n",
00475            this, pidl, pbcReserved, shdebugstr_guid (&riid), ppvOut);
00476 
00477     *ppvOut = NULL;
00478     return E_NOTIMPL;
00479 }
00480 
00481 /**************************************************************************
00482  *     CDesktopFolder::CompareIDs
00483  */
00484 HRESULT WINAPI CDesktopFolder::CompareIDs(LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
00485 {
00486     int nReturn;
00487 
00488     TRACE ("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", this, lParam, pidl1, pidl2);
00489     nReturn = SHELL32_CompareIDs ((IShellFolder *)this, lParam, pidl1, pidl2);
00490     TRACE ("-- %i\n", nReturn);
00491     return nReturn;
00492 }
00493 
00494 /**************************************************************************
00495  *    CDesktopFolder::CreateViewObject
00496  */
00497 HRESULT WINAPI CDesktopFolder::CreateViewObject(
00498     HWND hwndOwner,
00499     REFIID riid,
00500     LPVOID *ppvOut)
00501 {
00502     CComPtr<IShellView> pShellView;
00503     HRESULT hr = E_INVALIDARG;
00504 
00505     TRACE ("(%p)->(hwnd=%p,%s,%p)\n",
00506            this, hwndOwner, shdebugstr_guid (&riid), ppvOut);
00507 
00508     if (!ppvOut)
00509         return hr;
00510 
00511     *ppvOut = NULL;
00512 
00513     if (IsEqualIID (riid, IID_IDropTarget))
00514     {
00515         WARN ("IDropTarget not implemented\n");
00516         hr = E_NOTIMPL;
00517     }
00518     else if (IsEqualIID (riid, IID_IContextMenu))
00519     {
00520         WARN ("IContextMenu not implemented\n");
00521         hr = E_NOTIMPL;
00522     }
00523     else if (IsEqualIID (riid, IID_IShellView))
00524     {
00525         hr = IShellView_Constructor((IShellFolder *)this, &pShellView);
00526         if (pShellView)
00527             hr = pShellView->QueryInterface(riid, ppvOut);
00528     }
00529     TRACE ("-- (%p)->(interface=%p)\n", this, ppvOut);
00530     return hr;
00531 }
00532 
00533 /**************************************************************************
00534  *  CDesktopFolder::GetAttributesOf
00535  */
00536 HRESULT WINAPI CDesktopFolder::GetAttributesOf(
00537     UINT cidl,
00538     LPCITEMIDLIST *apidl,
00539     DWORD *rgfInOut)
00540 {
00541     HRESULT hr = S_OK;
00542     static const DWORD dwDesktopAttributes =
00543         SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR |
00544         SFGAO_STORAGEANCESTOR | SFGAO_HASPROPSHEET | SFGAO_STORAGE | SFGAO_CANLINK;
00545     static const DWORD dwMyComputerAttributes =
00546         SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
00547         SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK;
00548     static DWORD dwMyNetPlacesAttributes =
00549         SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
00550         SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK;
00551 
00552     TRACE("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
00553           this, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
00554 
00555     if (cidl && !apidl)
00556         return E_INVALIDARG;
00557 
00558     if (*rgfInOut == 0)
00559         *rgfInOut = ~0;
00560 
00561     if(cidl == 0)
00562         *rgfInOut &= dwDesktopAttributes;
00563     else
00564     {
00565         /* TODO: always add SFGAO_CANLINK */
00566         for (UINT i = 0; i < cidl; ++i)
00567         {
00568             pdump(*apidl);
00569             if (_ILIsDesktop(*apidl))
00570                 *rgfInOut &= dwDesktopAttributes;
00571             else if (_ILIsMyComputer(apidl[i]))
00572                 *rgfInOut &= dwMyComputerAttributes;
00573             else if (_ILIsNetHood(apidl[i]))
00574                 *rgfInOut &= dwMyNetPlacesAttributes;
00575             else
00576                 SHELL32_GetItemAttributes((IShellFolder *)this, apidl[i], rgfInOut);
00577         }
00578     }
00579     /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
00580     *rgfInOut &= ~SFGAO_VALIDATE;
00581 
00582     TRACE("-- result=0x%08x\n", *rgfInOut);
00583 
00584     return hr;
00585 }
00586 
00587 /**************************************************************************
00588  *    CDesktopFolder::GetUIObjectOf
00589  *
00590  * PARAMETERS
00591  *  HWND           hwndOwner, //[in ] Parent window for any output
00592  *  UINT           cidl,      //[in ] array size
00593  *  LPCITEMIDLIST* apidl,     //[in ] simple pidl array
00594  *  REFIID         riid,      //[in ] Requested Interface
00595  *  UINT*          prgfInOut, //[   ] reserved
00596  *  LPVOID*        ppvObject) //[out] Resulting Interface
00597  *
00598  */
00599 HRESULT WINAPI CDesktopFolder::GetUIObjectOf(
00600     HWND hwndOwner,
00601     UINT cidl,
00602     LPCITEMIDLIST *apidl,
00603     REFIID riid,
00604     UINT *prgfInOut,
00605     LPVOID *ppvOut)
00606 {
00607     LPITEMIDLIST pidl;
00608     IUnknown *pObj = NULL;
00609     HRESULT hr = E_INVALIDARG;
00610 
00611     TRACE ("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n",
00612            this, hwndOwner, cidl, apidl, shdebugstr_guid (&riid), prgfInOut, ppvOut);
00613 
00614     if (!ppvOut)
00615         return hr;
00616 
00617     *ppvOut = NULL;
00618 
00619     if (IsEqualIID (riid, IID_IContextMenu))
00620     {
00621         hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, (IShellFolder *)this, NULL, 0, NULL, (IContextMenu **)&pObj);
00622     }
00623     else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1))
00624     {
00625         hr = IDataObject_Constructor( hwndOwner, pidlRoot, apidl, cidl, (IDataObject **)&pObj);
00626     }
00627     else if (IsEqualIID (riid, IID_IExtractIconA) && (cidl == 1))
00628     {
00629         pidl = ILCombine (pidlRoot, apidl[0]);
00630         pObj = (LPUNKNOWN) IExtractIconA_Constructor (pidl);
00631         SHFree (pidl);
00632         hr = S_OK;
00633     }
00634     else if (IsEqualIID (riid, IID_IExtractIconW) && (cidl == 1))
00635     {
00636         pidl = ILCombine (pidlRoot, apidl[0]);
00637         pObj = (LPUNKNOWN) IExtractIconW_Constructor (pidl);
00638         SHFree (pidl);
00639         hr = S_OK;
00640     }
00641     else if (IsEqualIID (riid, IID_IDropTarget) && (cidl >= 1))
00642     {
00643         hr = this->QueryInterface (IID_IDropTarget, (LPVOID *)&pObj);
00644     }
00645     else if ((IsEqualIID(riid, IID_IShellLinkW) ||
00646               IsEqualIID(riid, IID_IShellLinkA)) && (cidl == 1))
00647     {
00648         pidl = ILCombine (pidlRoot, apidl[0]);
00649         hr = IShellLink_ConstructFromFile(NULL, riid, pidl, (LPVOID*)&pObj);
00650         SHFree (pidl);
00651     }
00652     else
00653         hr = E_NOINTERFACE;
00654 
00655     if (SUCCEEDED(hr) && !pObj)
00656         hr = E_OUTOFMEMORY;
00657 
00658     *ppvOut = pObj;
00659     TRACE ("(%p)->hr=0x%08x\n", this, hr);
00660     return hr;
00661 }
00662 
00663 /**************************************************************************
00664  *    CDesktopFolder::GetDisplayNameOf
00665  *
00666  * NOTES
00667  *    special case: pidl = null gives desktop-name back
00668  */
00669 HRESULT WINAPI CDesktopFolder::GetDisplayNameOf(LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet)
00670 {
00671     HRESULT hr = S_OK;
00672     LPWSTR pszPath;
00673 
00674     TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet);
00675     pdump (pidl);
00676 
00677     if (!strRet)
00678         return E_INVALIDARG;
00679 
00680     pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR));
00681     if (!pszPath)
00682         return E_OUTOFMEMORY;
00683 
00684     if (_ILIsDesktop (pidl))
00685     {
00686         if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) &&
00687                 (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING))
00688             wcscpy(pszPath, sPathTarget);
00689         else
00690             HCR_GetClassNameW(CLSID_ShellDesktop, pszPath, MAX_PATH);
00691     }
00692     else if (_ILIsPidlSimple (pidl))
00693     {
00694         GUID const *clsid;
00695 
00696         if ((clsid = _ILGetGUIDPointer (pidl)))
00697         {
00698             if (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING)
00699             {
00700                 int bWantsForParsing;
00701 
00702                 /*
00703                  * We can only get a filesystem path from a shellfolder if the
00704                  *  value WantsFORPARSING in CLSID\\{...}\\shellfolder exists.
00705                  *
00706                  * Exception: The MyComputer folder doesn't have this key,
00707                  *   but any other filesystem backed folder it needs it.
00708                  */
00709                 if (IsEqualIID (*clsid, CLSID_MyComputer))
00710                 {
00711                     bWantsForParsing = TRUE;
00712                 }
00713                 else
00714                 {
00715                     /* get the "WantsFORPARSING" flag from the registry */
00716                     static const WCHAR clsidW[] =
00717                     { 'C', 'L', 'S', 'I', 'D', '\\', 0 };
00718                     static const WCHAR shellfolderW[] =
00719                     { '\\', 's', 'h', 'e', 'l', 'l', 'f', 'o', 'l', 'd', 'e', 'r', 0 };
00720                     static const WCHAR wantsForParsingW[] =
00721                     {   'W', 'a', 'n', 't', 's', 'F', 'o', 'r', 'P', 'a', 'r', 's', 'i', 'n',
00722                         'g', 0
00723                     };
00724                     WCHAR szRegPath[100];
00725                     LONG r;
00726 
00727                     wcscpy (szRegPath, clsidW);
00728                     SHELL32_GUIDToStringW (*clsid, &szRegPath[6]);
00729                     wcscat (szRegPath, shellfolderW);
00730                     r = SHGetValueW(HKEY_CLASSES_ROOT, szRegPath,
00731                                     wantsForParsingW, NULL, NULL, NULL);
00732                     if (r == ERROR_SUCCESS)
00733                         bWantsForParsing = TRUE;
00734                     else
00735                         bWantsForParsing = FALSE;
00736                 }
00737 
00738                 if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) &&
00739                         bWantsForParsing)
00740                 {
00741                     /*
00742                      * we need the filesystem path to the destination folder.
00743                      * Only the folder itself can know it
00744                      */
00745                     hr = SHELL32_GetDisplayNameOfChild (this, pidl, dwFlags,
00746                                                         pszPath,
00747                                                         MAX_PATH);
00748                 }
00749                 else
00750                 {
00751                     /* parsing name like ::{...} */
00752                     pszPath[0] = ':';
00753                     pszPath[1] = ':';
00754                     SHELL32_GUIDToStringW (*clsid, &pszPath[2]);
00755                 }
00756             }
00757             else
00758             {
00759                 /* user friendly name */
00760                 HCR_GetClassNameW (*clsid, pszPath, MAX_PATH);
00761             }
00762         }
00763         else
00764         {
00765             int cLen = 0;
00766 
00767             /* file system folder or file rooted at the desktop */
00768             if ((GET_SHGDN_FOR(dwFlags) == SHGDN_FORPARSING) &&
00769                     (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER))
00770             {
00771                 lstrcpynW(pszPath, sPathTarget, MAX_PATH - 1);
00772                 PathAddBackslashW(pszPath);
00773                 cLen = wcslen(pszPath);
00774             }
00775 
00776             _ILSimpleGetTextW(pidl, pszPath + cLen, MAX_PATH - cLen);
00777             if (!_ILIsFolder(pidl))
00778                 SHELL_FS_ProcessDisplayFilename(pszPath, dwFlags);
00779 
00780             if (GetFileAttributes(pszPath) == INVALID_FILE_ATTRIBUTES)
00781             {
00782                 /* file system folder or file rooted at the AllUsers desktop */
00783                 if ((GET_SHGDN_FOR(dwFlags) == SHGDN_FORPARSING) &&
00784                         (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER))
00785                 {
00786                     SHGetSpecialFolderPathW(0, pszPath, CSIDL_COMMON_DESKTOPDIRECTORY, FALSE);
00787                     PathAddBackslashW(pszPath);
00788                     cLen = wcslen(pszPath);
00789                 }
00790 
00791                 _ILSimpleGetTextW(pidl, pszPath + cLen, MAX_PATH - cLen);
00792                 if (!_ILIsFolder(pidl))
00793                     SHELL_FS_ProcessDisplayFilename(pszPath, dwFlags);
00794             }
00795         }
00796     }
00797     else
00798     {
00799         /* a complex pidl, let the subfolder do the work */
00800         hr = SHELL32_GetDisplayNameOfChild (this, pidl, dwFlags,
00801                                             pszPath, MAX_PATH);
00802     }
00803 
00804     if (SUCCEEDED(hr))
00805     {
00806         /* Win9x always returns ANSI strings, NT always returns Unicode strings */
00807         if (GetVersion() & 0x80000000)
00808         {
00809             strRet->uType = STRRET_CSTR;
00810             if (!WideCharToMultiByte(CP_ACP, 0, pszPath, -1, strRet->cStr, MAX_PATH,
00811                                      NULL, NULL))
00812                 strRet->cStr[0] = '\0';
00813             CoTaskMemFree(pszPath);
00814         }
00815         else
00816         {
00817             strRet->uType = STRRET_WSTR;
00818             strRet->pOleStr = pszPath;
00819         }
00820     }
00821     else
00822         CoTaskMemFree(pszPath);
00823 
00824     TRACE ("-- (%p)->(%s,0x%08x)\n", this,
00825            strRet->uType == STRRET_CSTR ? strRet->cStr :
00826            debugstr_w(strRet->pOleStr), hr);
00827     return hr;
00828 }
00829 
00830 /**************************************************************************
00831  *  CDesktopFolder::SetNameOf
00832  *  Changes the name of a file object or subfolder, possibly changing its item
00833  *  identifier in the process.
00834  *
00835  * PARAMETERS
00836  *  HWND          hwndOwner,  //[in ] Owner window for output
00837  *  LPCITEMIDLIST pidl,       //[in ] simple pidl of item to change
00838  *  LPCOLESTR     lpszName,   //[in ] the items new display name
00839  *  DWORD         dwFlags,    //[in ] SHGNO formatting flags
00840  *  LPITEMIDLIST* ppidlOut)   //[out] simple pidl returned
00841  */
00842 HRESULT WINAPI CDesktopFolder::SetNameOf(
00843     HWND hwndOwner,
00844     LPCITEMIDLIST pidl,    /* simple pidl */
00845     LPCOLESTR lpName,
00846     DWORD dwFlags,
00847     LPITEMIDLIST *pPidlOut)
00848 {
00849     CComPtr<IShellFolder2>                psf;
00850     HRESULT hr;
00851     WCHAR szSrc[MAX_PATH + 1], szDest[MAX_PATH + 1];
00852     LPWSTR ptr;
00853     BOOL bIsFolder = _ILIsFolder (ILFindLastID (pidl));
00854 
00855     TRACE ("(%p)->(%p,pidl=%p,%s,%u,%p)\n", this, hwndOwner, pidl,
00856            debugstr_w (lpName), dwFlags, pPidlOut);
00857 
00858     if (_ILGetGUIDPointer(pidl))
00859     {
00860         if (SUCCEEDED(BindToObject(pidl, NULL, IID_IShellFolder2, (LPVOID *)&psf)))
00861         {
00862             hr = psf->SetNameOf(hwndOwner, pidl, lpName, dwFlags, pPidlOut);
00863             return hr;
00864         }
00865     }
00866 
00867     /* build source path */
00868     lstrcpynW(szSrc, sPathTarget, MAX_PATH);
00869     ptr = PathAddBackslashW (szSrc);
00870     if (ptr)
00871         _ILSimpleGetTextW (pidl, ptr, MAX_PATH + 1 - (ptr - szSrc));
00872 
00873     /* build destination path */
00874     if (dwFlags == SHGDN_NORMAL || dwFlags & SHGDN_INFOLDER) {
00875         lstrcpynW(szDest, sPathTarget, MAX_PATH);
00876         ptr = PathAddBackslashW (szDest);
00877         if (ptr)
00878             lstrcpynW(ptr, lpName, MAX_PATH + 1 - (ptr - szDest));
00879     } else
00880         lstrcpynW(szDest, lpName, MAX_PATH);
00881 
00882     if(!(dwFlags & SHGDN_FORPARSING) && SHELL_FS_HideExtension(szSrc)) {
00883         WCHAR *ext = PathFindExtensionW(szSrc);
00884         if(*ext != '\0') {
00885             INT len = wcslen(szDest);
00886             lstrcpynW(szDest + len, ext, MAX_PATH - len);
00887         }
00888     }
00889 
00890     if (!memcmp(szSrc, szDest, (wcslen(szDest) + 1) * sizeof(WCHAR)))
00891     {
00892         /* src and destination is the same */
00893         hr = S_OK;
00894         if (pPidlOut)
00895             hr = _ILCreateFromPathW(szDest, pPidlOut);
00896 
00897         return hr;
00898     }
00899 
00900     TRACE ("src=%s dest=%s\n", debugstr_w(szSrc), debugstr_w(szDest));
00901     if (MoveFileW (szSrc, szDest))
00902     {
00903         hr = S_OK;
00904 
00905         if (pPidlOut)
00906             hr = _ILCreateFromPathW(szDest, pPidlOut);
00907 
00908         SHChangeNotify (bIsFolder ? SHCNE_RENAMEFOLDER : SHCNE_RENAMEITEM,
00909                         SHCNF_PATHW, szSrc, szDest);
00910 
00911         return hr;
00912     }
00913     return E_FAIL;
00914 }
00915 
00916 HRESULT WINAPI CDesktopFolder::GetDefaultSearchGUID(GUID *pguid)
00917 {
00918     FIXME ("(%p)\n", this);
00919     return E_NOTIMPL;
00920 }
00921 
00922 HRESULT WINAPI CDesktopFolder::EnumSearches(IEnumExtraSearch **ppenum)
00923 {
00924     FIXME ("(%p)\n", this);
00925     return E_NOTIMPL;
00926 }
00927 
00928 HRESULT WINAPI CDesktopFolder::GetDefaultColumn(DWORD dwRes, ULONG *pSort, ULONG *pDisplay)
00929 {
00930     TRACE ("(%p)\n", this);
00931 
00932     if (pSort)
00933         *pSort = 0;
00934     if (pDisplay)
00935         *pDisplay = 0;
00936 
00937     return S_OK;
00938 }
00939 
00940 HRESULT WINAPI CDesktopFolder::GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags)
00941 {
00942     TRACE ("(%p)\n", this);
00943 
00944     if (!pcsFlags || iColumn >= DESKTOPSHELLVIEWCOLUMNS)
00945         return E_INVALIDARG;
00946 
00947     *pcsFlags = DesktopSFHeader[iColumn].pcsFlags;
00948 
00949     return S_OK;
00950 }
00951 
00952 HRESULT WINAPI CDesktopFolder::GetDetailsEx(
00953     LPCITEMIDLIST pidl,
00954     const SHCOLUMNID *pscid,
00955     VARIANT *pv)
00956 {
00957     FIXME ("(%p)\n", this);
00958 
00959     return E_NOTIMPL;
00960 }
00961 
00962 HRESULT WINAPI CDesktopFolder::GetDetailsOf(
00963     LPCITEMIDLIST pidl,
00964     UINT iColumn,
00965     SHELLDETAILS *psd)
00966 {
00967     HRESULT hr = S_OK;
00968 
00969     TRACE ("(%p)->(%p %i %p)\n", this, pidl, iColumn, psd);
00970 
00971     if (!psd || iColumn >= DESKTOPSHELLVIEWCOLUMNS)
00972         return E_INVALIDARG;
00973 
00974     if (!pidl)
00975     {
00976         psd->fmt = DesktopSFHeader[iColumn].fmt;
00977         psd->cxChar = DesktopSFHeader[iColumn].cxChar;
00978         psd->str.uType = STRRET_CSTR;
00979         LoadStringA (shell32_hInstance, DesktopSFHeader[iColumn].colnameid,
00980                      psd->str.cStr, MAX_PATH);
00981         return S_OK;
00982     }
00983 
00984     /* the data from the pidl */
00985     psd->str.uType = STRRET_CSTR;
00986     switch (iColumn)
00987     {
00988         case 0:        /* name */
00989             hr = GetDisplayNameOf(pidl,
00990                                   SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
00991             break;
00992         case 1:        /* size */
00993             _ILGetFileSize (pidl, psd->str.cStr, MAX_PATH);
00994             break;
00995         case 2:        /* type */
00996             _ILGetFileType (pidl, psd->str.cStr, MAX_PATH);
00997             break;
00998         case 3:        /* date */
00999             _ILGetFileDate (pidl, psd->str.cStr, MAX_PATH);
01000             break;
01001         case 4:        /* attributes */
01002             _ILGetFileAttributes (pidl, psd->str.cStr, MAX_PATH);
01003             break;
01004     }
01005 
01006     return hr;
01007 }
01008 
01009 HRESULT WINAPI CDesktopFolder::MapColumnToSCID(UINT column, SHCOLUMNID *pscid)
01010 {
01011     FIXME ("(%p)\n", this);
01012     return E_NOTIMPL;
01013 }
01014 
01015 HRESULT WINAPI CDesktopFolder::GetClassID(CLSID *lpClassId)
01016 {
01017     TRACE ("(%p)\n", this);
01018 
01019     if (!lpClassId)
01020         return E_POINTER;
01021 
01022     *lpClassId = CLSID_ShellDesktop;
01023 
01024     return S_OK;
01025 }
01026 
01027 HRESULT WINAPI CDesktopFolder::Initialize(LPCITEMIDLIST pidl)
01028 {
01029     TRACE ("(%p)->(%p)\n", this, pidl);
01030 
01031     return E_NOTIMPL;
01032 }
01033 
01034 HRESULT WINAPI CDesktopFolder::GetCurFolder(LPITEMIDLIST * pidl)
01035 {
01036     TRACE ("(%p)->(%p)\n", this, pidl);
01037 
01038     if (!pidl) return E_POINTER;
01039     *pidl = ILClone (pidlRoot);
01040     return S_OK;
01041 }
01042 
01043 HRESULT WINAPI CDesktopFolder::GetUniqueName(LPWSTR pwszName, UINT uLen)
01044 {
01045     CComPtr<IEnumIDList>                penum;
01046     HRESULT hr;
01047     WCHAR wszText[MAX_PATH];
01048     WCHAR wszNewFolder[25];
01049     const WCHAR wszFormat[] = {'%', 's', ' ', '%', 'd', 0 };
01050 
01051     LoadStringW(shell32_hInstance, IDS_NEWFOLDER, wszNewFolder,  sizeof(wszNewFolder) / sizeof(WCHAR));
01052 
01053     TRACE ("(%p)(%p %u)\n", this, pwszName, uLen);
01054 
01055     if (uLen < sizeof(wszNewFolder) / sizeof(WCHAR) + 3)
01056         return E_POINTER;
01057 
01058     lstrcpynW (pwszName, wszNewFolder, uLen);
01059 
01060     hr = EnumObjects(0,
01061                      SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penum);
01062     if (penum) {
01063         LPITEMIDLIST pidl;
01064         DWORD dwFetched;
01065         int i = 1;
01066 
01067 next:
01068         penum->Reset ();
01069         while (S_OK == penum->Next(1, &pidl, &dwFetched) &&
01070                 dwFetched) {
01071             _ILSimpleGetTextW (pidl, wszText, MAX_PATH);
01072             if (0 == lstrcmpiW (wszText, pwszName)) {
01073                 _snwprintf (pwszName, uLen, wszFormat, wszNewFolder, i++);
01074                 if (i > 99) {
01075                     hr = E_FAIL;
01076                     break;
01077                 }
01078                 goto next;
01079             }
01080         }
01081 
01082     }
01083     return hr;
01084 }
01085 
01086 HRESULT WINAPI CDesktopFolder::AddFolder(HWND hwnd, LPCWSTR pwszName, LPITEMIDLIST *ppidlOut)
01087 {
01088     WCHAR wszNewDir[MAX_PATH];
01089     DWORD bRes;
01090     HRESULT hres = E_FAIL;
01091 
01092     TRACE ("(%p)(%s %p)\n", this, debugstr_w(pwszName), ppidlOut);
01093 
01094     wszNewDir[0] = 0;
01095     if (sPathTarget)
01096         lstrcpynW(wszNewDir, sPathTarget, MAX_PATH);
01097     PathAppendW(wszNewDir, pwszName);
01098     bRes = CreateDirectoryW (wszNewDir, NULL);
01099     if (bRes)
01100     {
01101         SHChangeNotify (SHCNE_MKDIR, SHCNF_PATHW, wszNewDir, NULL);
01102         hres = S_OK;
01103         if (ppidlOut)
01104             hres = _ILCreateFromPathW(wszNewDir, ppidlOut);
01105     }
01106 
01107     return hres;
01108 }
01109 
01110 HRESULT WINAPI CDesktopFolder::DeleteItems(UINT cidl, LPCITEMIDLIST *apidl)
01111 {
01112     UINT i;
01113     SHFILEOPSTRUCTW op;
01114     WCHAR wszPath[MAX_PATH];
01115     WCHAR wszCaption[50];
01116     WCHAR *wszPathsList;
01117     HRESULT ret;
01118     WCHAR *wszCurrentPath;
01119     UINT bRestoreWithDeskCpl = FALSE;
01120     int res;
01121 
01122     TRACE ("(%p)(%u %p)\n", this, cidl, apidl);
01123     if (cidl == 0) return S_OK;
01124 
01125     for(i = 0; i < cidl; i++)
01126     {
01127         if (_ILIsMyComputer(apidl[i]))
01128             bRestoreWithDeskCpl++;
01129         else if (_ILIsNetHood(apidl[i]))
01130             bRestoreWithDeskCpl++;
01131         else if (_ILIsMyDocuments(apidl[i]))
01132             bRestoreWithDeskCpl++;
01133     }
01134 
01135     if (bRestoreWithDeskCpl)
01136     {
01137         /* FIXME use FormatMessage
01138          * use a similar message resource as in windows
01139          */
01140         LoadStringW(shell32_hInstance, IDS_DELETEMULTIPLE_TEXT, wszPath, sizeof(wszPath) / sizeof(WCHAR));
01141         wszPath[(sizeof(wszPath)/sizeof(WCHAR))-1] = 0;
01142 
01143         LoadStringW(shell32_hInstance, IDS_DELETEITEM_CAPTION, wszCaption, sizeof(wszCaption) / sizeof(WCHAR));
01144         wszCaption[(sizeof(wszCaption)/sizeof(WCHAR))-1] = 0;
01145 
01146         res = SHELL_ConfirmMsgBox(GetActiveWindow(), wszPath, wszCaption, NULL, cidl > 1);
01147         if (res == IDC_YESTOALL || res == IDYES)
01148         {
01149             for(i = 0; i < cidl; i++)
01150             {
01151                 if (_ILIsMyComputer(apidl[i]))
01152                     SetNamespaceExtensionVisibleStatus(L"{20D04FE0-3AEA-1069-A2D8-08002B30309D}", 0x1);
01153                 else if (_ILIsNetHood(apidl[i]))
01154                     SetNamespaceExtensionVisibleStatus(L"{208D2C60-3AEA-1069-A2D7-08002B30309D}", 0x1);
01155                 else if (_ILIsMyDocuments(apidl[i]))
01156                     SetNamespaceExtensionVisibleStatus(L"{450D8FBA-AD25-11D0-98A8-0800361B1103}", 0x1);
01157             }
01158         }
01159     }
01160     if (sPathTarget)
01161         lstrcpynW(wszPath, sPathTarget, MAX_PATH);
01162     else
01163         wszPath[0] = '\0';
01164 
01165     PathAddBackslashW(wszPath);
01166     wszPathsList = BuildPathsList(wszPath, cidl, apidl);
01167 
01168     ZeroMemory(&op, sizeof(op));
01169     op.hwnd = GetActiveWindow();
01170     op.wFunc = FO_DELETE;
01171     op.pFrom = wszPathsList;
01172     op.fFlags = FOF_ALLOWUNDO;
01173     if (SHFileOperationW(&op))
01174     {
01175         WARN("SHFileOperation failed\n");
01176         ret = E_FAIL;
01177     }
01178     else
01179         ret = S_OK;
01180 
01181     /* we currently need to manually send the notifies */
01182     wszCurrentPath = wszPathsList;
01183     for (i = 0; i < cidl; i++)
01184     {
01185         LONG wEventId;
01186 
01187         if (_ILIsFolder(apidl[i]))
01188             wEventId = SHCNE_RMDIR;
01189         else if (_ILIsValue(apidl[i]))
01190             wEventId = SHCNE_DELETE;
01191         else
01192             continue;
01193 
01194         /* check if file exists */
01195         if (GetFileAttributesW(wszCurrentPath) == INVALID_FILE_ATTRIBUTES)
01196         {
01197             LPITEMIDLIST pidl = ILCombine(pidlRoot, apidl[i]);
01198             SHChangeNotify(wEventId, SHCNF_IDLIST, pidl, NULL);
01199             SHFree(pidl);
01200         }
01201 
01202         wszCurrentPath += wcslen(wszCurrentPath) + 1;
01203     }
01204     HeapFree(GetProcessHeap(), 0, wszPathsList);
01205     return ret;
01206 }
01207 
01208 HRESULT WINAPI CDesktopFolder::CopyItems(IShellFolder *pSFFrom, UINT cidl, LPCITEMIDLIST *apidl)
01209 {
01210     CComPtr<IPersistFolder2> ppf2;
01211     WCHAR szSrcPath[MAX_PATH];
01212     WCHAR szTargetPath[MAX_PATH];
01213     SHFILEOPSTRUCTW op;
01214     LPITEMIDLIST pidl;
01215     LPWSTR pszSrc, pszTarget, pszSrcList, pszTargetList, pszFileName;
01216     int res, length;
01217     STRRET strRet;
01218 
01219     TRACE ("(%p)->(%p,%u,%p)\n", this, pSFFrom, cidl, apidl);
01220 
01221     pSFFrom->QueryInterface(IID_IPersistFolder2, (LPVOID *)&ppf2);
01222     if (ppf2)
01223     {
01224         if (FAILED(ppf2->GetCurFolder(&pidl)))
01225             return E_FAIL;
01226 
01227         if (FAILED(pSFFrom->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strRet)))
01228         {
01229             SHFree (pidl);
01230             return E_FAIL;
01231         }
01232 
01233         if (FAILED(StrRetToBufW(&strRet, pidl, szSrcPath, MAX_PATH)))
01234         {
01235             SHFree (pidl);
01236             return E_FAIL;
01237         }
01238         SHFree (pidl);
01239 
01240         pszSrc = PathAddBackslashW (szSrcPath);
01241 
01242         wcscpy(szTargetPath, sPathTarget);
01243         pszTarget = PathAddBackslashW (szTargetPath);
01244 
01245         pszSrcList = BuildPathsList(szSrcPath, cidl, apidl);
01246         pszTargetList = BuildPathsList(szTargetPath, cidl, apidl);
01247 
01248         if (!pszSrcList || !pszTargetList)
01249         {
01250             if (pszSrcList)
01251                 HeapFree(GetProcessHeap(), 0, pszSrcList);
01252 
01253             if (pszTargetList)
01254                 HeapFree(GetProcessHeap(), 0, pszTargetList);
01255 
01256             SHFree (pidl);
01257             return E_OUTOFMEMORY;
01258         }
01259         ZeroMemory(&op, sizeof(op));
01260         if (!pszSrcList[0])
01261         {
01262             /* remove trailing backslash */
01263             pszSrc--;
01264             pszSrc[0] = L'\0';
01265             op.pFrom = szSrcPath;
01266         }
01267         else
01268         {
01269             op.pFrom = pszSrcList;
01270         }
01271 
01272         if (!pszTargetList[0])
01273         {
01274             /* remove trailing backslash */
01275             if (pszTarget - szTargetPath > 3)
01276             {
01277                 pszTarget--;
01278                 pszTarget[0] = L'\0';
01279             }
01280             else
01281             {
01282                 pszTarget[1] = L'\0';
01283             }
01284 
01285             op.pTo = szTargetPath;
01286         }
01287         else
01288         {
01289             op.pTo = pszTargetList;
01290         }
01291         op.hwnd = GetActiveWindow();
01292         op.wFunc = FO_COPY;
01293         op.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMMKDIR;
01294 
01295         res = SHFileOperationW(&op);
01296 
01297         if (res == DE_SAMEFILE)
01298         {
01299             length = wcslen(szTargetPath);
01300 
01301 
01302             pszFileName = wcsrchr(pszSrcList, '\\');
01303             pszFileName++;
01304 
01305             if (LoadStringW(shell32_hInstance, IDS_COPY_OF, pszTarget, MAX_PATH - length))
01306             {
01307                 wcscat(szTargetPath, L" ");
01308             }
01309 
01310             wcscat(szTargetPath, pszFileName);
01311             op.pTo = szTargetPath;
01312 
01313             res = SHFileOperationW(&op);
01314         }
01315 
01316 
01317         HeapFree(GetProcessHeap(), 0, pszSrcList);
01318         HeapFree(GetProcessHeap(), 0, pszTargetList);
01319 
01320         if (res)
01321             return E_FAIL;
01322         else
01323             return S_OK;
01324     }
01325     return E_FAIL;
01326 }

Generated on Sat May 26 2012 04:17:27 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.