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

mycomp.cpp
Go to the documentation of this file.
00001 /*
00002  *    Virtual Workplace 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 CDrivesFolder should create a CRegFolder to represent the virtual items that exist only in
00029 the registry. The CRegFolder is aggregated by the CDrivesFolder.
00030 The CDrivesFolderEnum class should enumerate only drives on the system. Since the CRegFolder
00031 implementation of IShellFolder::EnumObjects enumerates the virtual items, the
00032 CDrivesFolderEnum is only responsible for returning the physical items.
00033 
00034 2. At least on my XP system, the drive pidls returned are of type PT_DRIVE1, not PT_DRIVE
00035 3. The parsing name returned for my computer is incorrect. It should be "My Computer"
00036 */
00037 
00038 /***********************************************************************
00039 *   IShellFolder implementation
00040 */
00041 
00042 class CDrivesFolderEnum :
00043     public IEnumIDListImpl
00044 {
00045     public:
00046         CDrivesFolderEnum();
00047         ~CDrivesFolderEnum();
00048         HRESULT WINAPI Initialize(HWND hwndOwner, DWORD dwFlags);
00049         BOOL CreateMyCompEnumList(DWORD dwFlags);
00050 
00051         BEGIN_COM_MAP(CDrivesFolderEnum)
00052         COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
00053         END_COM_MAP()
00054 };
00055 
00056 /***********************************************************************
00057 *   IShellFolder [MyComputer] implementation
00058 */
00059 
00060 static const shvheader MyComputerSFHeader[] = {
00061     {IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
00062     {IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
00063     {IDS_SHV_COLUMN6, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
00064     {IDS_SHV_COLUMN7, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
00065 };
00066 
00067 #define MYCOMPUTERSHELLVIEWCOLUMNS 4
00068 
00069 CDrivesFolderEnum::CDrivesFolderEnum()
00070 {
00071 }
00072 
00073 CDrivesFolderEnum::~CDrivesFolderEnum()
00074 {
00075 }
00076 
00077 HRESULT WINAPI CDrivesFolderEnum::Initialize(HWND hwndOwner, DWORD dwFlags)
00078 {
00079     if (CreateMyCompEnumList(dwFlags) == FALSE)
00080         return E_FAIL;
00081 
00082     return S_OK;
00083 }
00084 
00085 /**************************************************************************
00086  *  CDrivesFolderEnum::CreateMyCompEnumList()
00087  */
00088 
00089 BOOL CDrivesFolderEnum::CreateMyCompEnumList(DWORD dwFlags)
00090 {
00091     BOOL bRet = TRUE;
00092     static const WCHAR MyComputer_NameSpaceW[] = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\Namespace";
00093 
00094     TRACE("(%p)->(flags=0x%08x)\n", this, dwFlags);
00095 
00096     /* enumerate the folders */
00097     if (dwFlags & SHCONTF_FOLDERS)
00098     {
00099         WCHAR wszDriveName[] = {'A', ':', '\\', '\0'};
00100         DWORD dwDrivemap = GetLogicalDrives();
00101         HKEY hKey;
00102         UINT i;
00103 
00104         while (bRet && wszDriveName[0] <= 'Z')
00105         {
00106             if(dwDrivemap & 0x00000001L)
00107                 bRet = AddToEnumList(_ILCreateDrive(wszDriveName));
00108             wszDriveName[0]++;
00109             dwDrivemap = dwDrivemap >> 1;
00110         }
00111 
00112         TRACE("-- (%p)-> enumerate (mycomputer shell extensions)\n", this);
00113         for (i = 0; i < 2; i++)
00114         {
00115             if (bRet && ERROR_SUCCESS == RegOpenKeyExW(i == 0 ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
00116                     MyComputer_NameSpaceW, 0, KEY_READ, &hKey))
00117             {
00118                 WCHAR wszBuf[50];
00119                 DWORD dwSize, j = 0;
00120                 LONG ErrorCode;
00121                 LPITEMIDLIST pidl;
00122 
00123                 while (bRet)
00124                 {
00125                     dwSize = sizeof(wszBuf) / sizeof(wszBuf[0]);
00126                     ErrorCode = RegEnumKeyExW(hKey, j, wszBuf, &dwSize, 0, NULL, NULL, NULL);
00127                     if (ERROR_SUCCESS == ErrorCode)
00128                     {
00129                         if (wszBuf[0] != L'{')
00130                         {
00131                             dwSize = sizeof(wszBuf);
00132                             RegGetValueW(hKey, wszBuf, NULL, RRF_RT_REG_SZ, NULL, wszBuf, &dwSize);
00133                         }
00134 
00135                         /* FIXME: shell extensions - the type should be PT_SHELLEXT (tested) */
00136                         pidl = _ILCreateGuidFromStrW(wszBuf);
00137                         if (pidl != NULL)
00138                             bRet = AddToEnumList(pidl);
00139                         else
00140                             ERR("Invalid MyComputer namespace extesion: %s\n", wszBuf);
00141                         j++;
00142                     }
00143                     else if (ERROR_NO_MORE_ITEMS == ErrorCode)
00144                         break;
00145                     else
00146                         bRet = FALSE;
00147                 }
00148                 RegCloseKey(hKey);
00149             }
00150         }
00151     }
00152     return bRet;
00153 }
00154 
00155 CDrivesFolder::CDrivesFolder()
00156 {
00157     pidlRoot = NULL;
00158     sName = NULL;
00159 }
00160 
00161 CDrivesFolder::~CDrivesFolder()
00162 {
00163     TRACE ("-- destroying IShellFolder(%p)\n", this);
00164     SHFree(pidlRoot);
00165 }
00166 
00167 HRESULT WINAPI CDrivesFolder::FinalConstruct()
00168 {
00169     DWORD dwSize;
00170     WCHAR szName[MAX_PATH];
00171     WCHAR wszMyCompKey[256];
00172     INT i;
00173 
00174     pidlRoot = _ILCreateMyComputer();    /* my qualified pidl */
00175     if (pidlRoot == NULL)
00176         return E_OUTOFMEMORY;
00177 
00178     i = swprintf(wszMyCompKey, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CLSID\\");
00179     StringFromGUID2(CLSID_MyComputer, wszMyCompKey + i, sizeof(wszMyCompKey) / sizeof(wszMyCompKey[0]) - i);
00180     dwSize = sizeof(szName);
00181     if (RegGetValueW(HKEY_CURRENT_USER, wszMyCompKey,
00182                      NULL, RRF_RT_REG_SZ, NULL, szName, &dwSize) == ERROR_SUCCESS)
00183     {
00184         sName = (LPWSTR)SHAlloc((wcslen(szName) + 1) * sizeof(WCHAR));
00185         if (sName)
00186             wcscpy(sName, szName);
00187         TRACE("sName %s\n", debugstr_w(sName));
00188     }
00189     return S_OK;
00190 }
00191 
00192 /**************************************************************************
00193 *    CDrivesFolder::ParseDisplayName
00194 */
00195 HRESULT WINAPI CDrivesFolder::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName,
00196         DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes)
00197 {
00198     HRESULT hr = E_INVALIDARG;
00199     LPCWSTR szNext = NULL;
00200     WCHAR szElement[MAX_PATH];
00201     LPITEMIDLIST pidlTemp = NULL;
00202     CLSID clsid;
00203 
00204     TRACE("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n", this,
00205           hwndOwner, pbc, lpszDisplayName, debugstr_w (lpszDisplayName),
00206           pchEaten, ppidl, pdwAttributes);
00207 
00208     *ppidl = 0;
00209     if (pchEaten)
00210         *pchEaten = 0;        /* strange but like the original */
00211 
00212     /* handle CLSID paths */
00213     if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':')
00214     {
00215         szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
00216         TRACE ("-- element: %s\n", debugstr_w (szElement));
00217         CLSIDFromString (szElement + 2, &clsid);
00218         pidlTemp = _ILCreateGuid (PT_GUID, clsid);
00219     }
00220     /* do we have an absolute path name ? */
00221     else if (PathGetDriveNumberW (lpszDisplayName) >= 0 &&
00222              lpszDisplayName[2] == (WCHAR) '\\')
00223     {
00224         szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
00225         /* make drive letter uppercase to enable PIDL comparison */
00226         szElement[0] = toupper(szElement[0]);
00227         pidlTemp = _ILCreateDrive (szElement);
00228     }
00229 
00230     if (szNext && *szNext)
00231     {
00232         hr = SHELL32_ParseNextElement (this, hwndOwner, pbc, &pidlTemp,
00233                                        (LPOLESTR) szNext, pchEaten, pdwAttributes);
00234     }
00235     else
00236     {
00237         if (pdwAttributes && *pdwAttributes)
00238             SHELL32_GetItemAttributes (this,
00239                                        pidlTemp, pdwAttributes);
00240         hr = S_OK;
00241     }
00242 
00243     *ppidl = pidlTemp;
00244 
00245     TRACE ("(%p)->(-- ret=0x%08x)\n", this, hr);
00246 
00247     return hr;
00248 }
00249 
00250 /**************************************************************************
00251 *        CDrivesFolder::EnumObjects
00252 */
00253 HRESULT WINAPI CDrivesFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
00254 {
00255     CComObject<CDrivesFolderEnum> *theEnumerator;
00256     CComPtr<IEnumIDList>          result;
00257     HRESULT                       hResult;
00258 
00259     TRACE ("(%p)->(HWND=%p flags=0x%08x pplist=%p)\n", this, hwndOwner, dwFlags, ppEnumIDList);
00260 
00261     if (ppEnumIDList == NULL)
00262         return E_POINTER;
00263 
00264     *ppEnumIDList = NULL;
00265     ATLTRY(theEnumerator = new CComObject<CDrivesFolderEnum>);
00266 
00267     if (theEnumerator == NULL)
00268         return E_OUTOFMEMORY;
00269 
00270     hResult = theEnumerator->QueryInterface(IID_IEnumIDList, (void **)&result);
00271     if (FAILED(hResult))
00272     {
00273         delete theEnumerator;
00274         return hResult;
00275     }
00276 
00277     hResult = theEnumerator->Initialize(hwndOwner, dwFlags);
00278     if (FAILED(hResult))
00279         return hResult;
00280     *ppEnumIDList = result.Detach();
00281 
00282     TRACE("-- (%p)->(new ID List: %p)\n", this, *ppEnumIDList);
00283 
00284     return S_OK;
00285 }
00286 
00287 /**************************************************************************
00288 *        CDrivesFolder::BindToObject
00289 */
00290 HRESULT WINAPI CDrivesFolder::BindToObject(LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
00291 {
00292     TRACE("(%p)->(pidl=%p,%p,%s,%p)\n", this,
00293           pidl, pbcReserved, shdebugstr_guid(&riid), ppvOut);
00294 
00295     return SHELL32_BindToChild(pidlRoot, NULL, pidl, riid, ppvOut);
00296 }
00297 
00298 /**************************************************************************
00299 *    CDrivesFolder::BindToStorage
00300 */
00301 HRESULT WINAPI CDrivesFolder::BindToStorage(LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
00302 {
00303     FIXME("(%p)->(pidl=%p,%p,%s,%p) stub\n", this,
00304           pidl, pbcReserved, shdebugstr_guid (&riid), ppvOut);
00305 
00306     *ppvOut = NULL;
00307     return E_NOTIMPL;
00308 }
00309 
00310 /**************************************************************************
00311 *     CDrivesFolder::CompareIDs
00312 */
00313 
00314 HRESULT WINAPI CDrivesFolder::CompareIDs(LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
00315 {
00316     int nReturn;
00317 
00318     TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", this, lParam, pidl1, pidl2);
00319     nReturn = SHELL32_CompareIDs (this, lParam, pidl1, pidl2);
00320     TRACE("-- %i\n", nReturn);
00321     return nReturn;
00322 }
00323 
00324 /**************************************************************************
00325 *    CDrivesFolder::CreateViewObject
00326 */
00327 HRESULT WINAPI CDrivesFolder::CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID * ppvOut)
00328 {
00329     LPSHELLVIEW pShellView;
00330     HRESULT hr = E_INVALIDARG;
00331 
00332     TRACE("(%p)->(hwnd=%p,%s,%p)\n", this,
00333           hwndOwner, shdebugstr_guid (&riid), ppvOut);
00334 
00335     if (!ppvOut)
00336         return hr;
00337 
00338     *ppvOut = NULL;
00339 
00340     if (IsEqualIID(riid, IID_IDropTarget))
00341     {
00342         WARN("IDropTarget not implemented\n");
00343         hr = E_NOTIMPL;
00344     }
00345     else if (IsEqualIID(riid, IID_IContextMenu))
00346     {
00347         WARN("IContextMenu not implemented\n");
00348         hr = E_NOTIMPL;
00349     }
00350     else if (IsEqualIID(riid, IID_IShellView))
00351     {
00352         hr = IShellView_Constructor ((IShellFolder *)this, &pShellView);
00353         if (pShellView)
00354         {
00355             hr = pShellView->QueryInterface(riid, ppvOut);
00356             pShellView->Release();
00357         }
00358     }
00359     TRACE ("-- (%p)->(interface=%p)\n", this, ppvOut);
00360     return hr;
00361 }
00362 
00363 /**************************************************************************
00364 *  CDrivesFolder::GetAttributesOf
00365 */
00366 HRESULT WINAPI CDrivesFolder::GetAttributesOf(UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut)
00367 {
00368     static const DWORD dwComputerAttributes =
00369         SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
00370         SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK;
00371     static const DWORD dwControlPanelAttributes =
00372         SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_CANLINK;
00373     static const DWORD dwDriveAttributes =
00374         SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR |
00375         SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANRENAME | SFGAO_CANLINK;
00376 
00377     TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
00378            this, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
00379 
00380     if (cidl && !apidl)
00381         return E_INVALIDARG;
00382 
00383     if (*rgfInOut == 0)
00384         *rgfInOut = ~0;
00385 
00386     /* FIXME: always add SFGAO_CANLINK */
00387     if(cidl == 0)
00388         *rgfInOut &= dwComputerAttributes;
00389     else
00390     {
00391         for (UINT i = 0; i < cidl; ++i)
00392         {
00393             if (_ILIsDrive(apidl[i]))
00394                 *rgfInOut &= dwDriveAttributes;
00395             else if (_ILIsControlPanel(apidl[i]))
00396                 *rgfInOut &= dwControlPanelAttributes;
00397             else
00398             {
00399                 pdump(apidl[i]);
00400                 SHELL32_GetItemAttributes(this, apidl[i], rgfInOut);
00401             }
00402         }
00403     }
00404 
00405     /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
00406     *rgfInOut &= ~SFGAO_VALIDATE;
00407 
00408     TRACE ("-- result=0x%08x\n", *rgfInOut);
00409     return S_OK;
00410 }
00411 
00412 /**************************************************************************
00413 *    CDrivesFolder::GetUIObjectOf
00414 *
00415 * PARAMETERS
00416 *  hwndOwner [in]  Parent window for any output
00417 *  cidl      [in]  array size
00418 *  apidl     [in]  simple pidl array
00419 *  riid      [in]  Requested Interface
00420 *  prgfInOut [   ] reserved
00421 *  ppvObject [out] Resulting Interface
00422 *
00423 */
00424 HRESULT WINAPI CDrivesFolder::GetUIObjectOf(HWND hwndOwner,
00425     UINT cidl, LPCITEMIDLIST *apidl,
00426     REFIID riid, UINT *prgfInOut, LPVOID *ppvOut)
00427 {
00428     LPITEMIDLIST pidl;
00429     IUnknown *pObj = NULL;
00430     HRESULT hr = E_INVALIDARG;
00431 
00432     TRACE("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n", this,
00433           hwndOwner, cidl, apidl, shdebugstr_guid (&riid), prgfInOut, ppvOut);
00434 
00435     if (!ppvOut)
00436         return hr;
00437 
00438     *ppvOut = NULL;
00439 
00440     if (IsEqualIID (riid, IID_IContextMenu) && (cidl >= 1))
00441     {
00442         hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl, (IShellFolder*)this, NULL, 0, NULL, (IContextMenu**)&pObj);
00443     }
00444     else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1))
00445     {
00446         hr = IDataObject_Constructor (hwndOwner,
00447                                       pidlRoot, apidl, cidl, (IDataObject **)&pObj);
00448     }
00449     else if (IsEqualIID (riid, IID_IExtractIconA) && (cidl == 1))
00450     {
00451         pidl = ILCombine (pidlRoot, apidl[0]);
00452         pObj = (LPUNKNOWN) IExtractIconA_Constructor (pidl);
00453         SHFree (pidl);
00454         hr = S_OK;
00455     }
00456     else if (IsEqualIID (riid, IID_IExtractIconW) && (cidl == 1))
00457     {
00458         pidl = ILCombine (pidlRoot, apidl[0]);
00459         pObj = (LPUNKNOWN) IExtractIconW_Constructor (pidl);
00460         SHFree (pidl);
00461         hr = S_OK;
00462     }
00463     else if (IsEqualIID (riid, IID_IDropTarget) && (cidl >= 1))
00464     {
00465         hr = this->QueryInterface(IID_IDropTarget,
00466                                   (LPVOID *) &pObj);
00467     }
00468     else if ((IsEqualIID(riid, IID_IShellLinkW) ||
00469               IsEqualIID(riid, IID_IShellLinkA)) && (cidl == 1))
00470     {
00471         pidl = ILCombine (pidlRoot, apidl[0]);
00472         hr = IShellLink_ConstructFromFile(NULL, riid, pidl, (LPVOID*) &pObj);
00473         SHFree (pidl);
00474     }
00475     else
00476         hr = E_NOINTERFACE;
00477 
00478     if (SUCCEEDED(hr) && !pObj)
00479         hr = E_OUTOFMEMORY;
00480 
00481     *ppvOut = pObj;
00482     TRACE ("(%p)->hr=0x%08x\n", this, hr);
00483     return hr;
00484 }
00485 
00486 /**************************************************************************
00487 *    CDrivesFolder::GetDisplayNameOf
00488 */
00489 HRESULT WINAPI CDrivesFolder::GetDisplayNameOf(LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet)
00490 {
00491     LPWSTR pszPath;
00492     HRESULT hr = S_OK;
00493 
00494     TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet);
00495     pdump (pidl);
00496 
00497     if (!strRet)
00498         return E_INVALIDARG;
00499 
00500     pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR));
00501     if (!pszPath)
00502         return E_OUTOFMEMORY;
00503 
00504     pszPath[0] = 0;
00505 
00506     if (!pidl->mkid.cb)
00507     {
00508         /* parsing name like ::{...} */
00509         pszPath[0] = ':';
00510         pszPath[1] = ':';
00511         SHELL32_GUIDToStringW(CLSID_MyComputer, &pszPath[2]);
00512     }
00513     else if (_ILIsPidlSimple(pidl))
00514     {
00515         /* take names of special folders only if its only this folder */
00516         if (_ILIsSpecialFolder(pidl))
00517         {
00518             GUID const *clsid;
00519 
00520             clsid = _ILGetGUIDPointer (pidl);
00521             if (clsid)
00522             {
00523                 if (GET_SHGDN_FOR (dwFlags) & SHGDN_FORPARSING)
00524                 {
00525                     static const WCHAR clsidW[] = L"CLSID\\";
00526                     static const WCHAR shellfolderW[] = L"\\shellfolder";
00527                     static const WCHAR wantsForParsingW[] = L"WantsForParsing";
00528                     BOOL bWantsForParsing = FALSE;
00529                     WCHAR szRegPath[100];
00530                     LONG r;
00531 
00532                     /*
00533                      * We can only get a filesystem path from a shellfolder
00534                      * if the value WantsFORPARSING exists in
00535                      *      CLSID\\{...}\\shellfolder
00536                      * exception: the MyComputer folder has this keys not
00537                      *            but like any filesystem backed
00538                      *            folder it needs these behaviour
00539                      *
00540                      * Get the "WantsFORPARSING" flag from the registry
00541                      */
00542 
00543                     wcscpy(szRegPath, clsidW);
00544                     SHELL32_GUIDToStringW(*clsid, &szRegPath[6]);
00545                     wcscat(szRegPath, shellfolderW);
00546                     r = SHGetValueW(HKEY_CLASSES_ROOT, szRegPath,
00547                                     wantsForParsingW, NULL, NULL, NULL);
00548                     if (r == ERROR_SUCCESS)
00549                         bWantsForParsing = TRUE;
00550 
00551                     if ((GET_SHGDN_RELATION (dwFlags) == SHGDN_NORMAL) &&
00552                             bWantsForParsing)
00553                     {
00554                         /*
00555                          * We need the filesystem path to the destination folder
00556                          * Only the folder itself can know it
00557                          */
00558                         hr = SHELL32_GetDisplayNameOfChild (this, pidl,
00559                                                             dwFlags, pszPath, MAX_PATH);
00560                     }
00561                     else
00562                     {
00563                         LPWSTR p = pszPath;
00564 
00565                         /* parsing name like ::{...} */
00566                         p[0] = ':';
00567                         p[1] = ':';
00568                         p += 2;
00569                         p += SHELL32_GUIDToStringW(CLSID_MyComputer, p);
00570 
00571                         /* \:: */
00572                         p[0] = '\\';
00573                         p[1] = ':';
00574                         p[2] = ':';
00575                         p += 3;
00576                         SHELL32_GUIDToStringW(*clsid, p);
00577                     }
00578                 }
00579                 else
00580                 {
00581                     /* user friendly name */
00582 
00583                     if (_ILIsMyComputer(pidl) && sName)
00584                         wcscpy(pszPath, sName);
00585                     else
00586                         HCR_GetClassNameW (*clsid, pszPath, MAX_PATH);
00587 
00588                     TRACE("pszPath %s\n", debugstr_w(pszPath));
00589                 }
00590             }
00591             else
00592             {
00593                 /* append my own path */
00594                 _ILSimpleGetTextW(pidl, pszPath, MAX_PATH);
00595             }
00596         }
00597         else if (_ILIsDrive(pidl))
00598         {
00599 
00600             _ILSimpleGetTextW(pidl, pszPath, MAX_PATH);    /* append my own path */
00601             /* long view "lw_name (C:)" */
00602             if (!(dwFlags & SHGDN_FORPARSING))
00603             {
00604                 WCHAR wszDrive[18] = {0};
00605                 DWORD dwVolumeSerialNumber, dwMaximumComponentLength, dwFileSystemFlags;
00606                 static const WCHAR wszOpenBracket[] = {' ', '(', 0};
00607                 static const WCHAR wszCloseBracket[] = {')', 0};
00608 
00609                 lstrcpynW(wszDrive, pszPath, 4);
00610                 pszPath[0] = L'\0';
00611                 GetVolumeInformationW(wszDrive, pszPath,
00612                                       MAX_PATH - 7,
00613                                       &dwVolumeSerialNumber,
00614                                       &dwMaximumComponentLength, &dwFileSystemFlags, NULL, 0);
00615                 pszPath[MAX_PATH-1] = L'\0';
00616                 if (!wcslen(pszPath))
00617                 {
00618                     UINT DriveType, ResourceId;
00619                     DriveType = GetDriveTypeW(wszDrive);
00620                     switch(DriveType)
00621                     {
00622                         case DRIVE_FIXED:
00623                             ResourceId = IDS_DRIVE_FIXED;
00624                             break;
00625                         case DRIVE_REMOTE:
00626                             ResourceId = IDS_DRIVE_NETWORK;
00627                             break;
00628                         case DRIVE_CDROM:
00629                             ResourceId = IDS_DRIVE_CDROM;
00630                             break;
00631                         default:
00632                             ResourceId = 0;
00633                     }
00634                     if (ResourceId)
00635                     {
00636                         dwFileSystemFlags = LoadStringW(shell32_hInstance, ResourceId, pszPath, MAX_PATH);
00637                         if (dwFileSystemFlags > MAX_PATH - 7)
00638                             pszPath[MAX_PATH-7] = L'\0';
00639                     }
00640                 }
00641                 wcscat (pszPath, wszOpenBracket);
00642                 wszDrive[2] = L'\0';
00643                 wcscat (pszPath, wszDrive);
00644                 wcscat (pszPath, wszCloseBracket);
00645             }
00646         }
00647         else
00648         {
00649             /* Neither a shell namespace extension nor a drive letter. */
00650             ERR("Wrong pidl type\n");
00651             CoTaskMemFree(pszPath);
00652             return E_INVALIDARG;
00653         }
00654     }
00655     else
00656     {
00657         /* Complex pidl. Let the child folder do the work */
00658         hr = SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, pszPath, MAX_PATH);
00659     }
00660 
00661     if (SUCCEEDED(hr))
00662     {
00663         strRet->uType = STRRET_WSTR;
00664         strRet->pOleStr = pszPath;
00665     }
00666     else
00667         CoTaskMemFree(pszPath);
00668 
00669     TRACE("-- (%p)->(%s)\n", this, strRet->uType == STRRET_CSTR ? strRet->cStr : debugstr_w(strRet->pOleStr));
00670     return hr;
00671 }
00672 
00673 /**************************************************************************
00674 *  CDrivesFolder::SetNameOf
00675 *  Changes the name of a file object or subfolder, possibly changing its item
00676 *  identifier in the process.
00677 *
00678 * PARAMETERS
00679 *  hwndOwner  [in]   Owner window for output
00680 *  pidl       [in]   simple pidl of item to change
00681 *  lpszName   [in]   the items new display name
00682 *  dwFlags    [in]   SHGNO formatting flags
00683 *  ppidlOut   [out]  simple pidl returned
00684 */
00685 HRESULT WINAPI CDrivesFolder::SetNameOf(HWND hwndOwner, LPCITEMIDLIST pidl,
00686                                         LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST *pPidlOut)
00687 {
00688     LPWSTR sName;
00689     HKEY hKey;
00690     UINT length;
00691     WCHAR szName[30];
00692 
00693     TRACE("(%p)->(%p,pidl=%p,%s,%u,%p)\n", this,
00694           hwndOwner, pidl, debugstr_w (lpName), dwFlags, pPidlOut);
00695 
00696     if (_ILIsDrive(pidl))
00697     {
00698         if (_ILSimpleGetTextW(pidl, szName, _countof(szName)))
00699             SetVolumeLabelW(szName, lpName);
00700         if (pPidlOut)
00701             *pPidlOut = _ILCreateDrive(szName);
00702         return S_OK;
00703     }
00704 
00705 
00706     if (pPidlOut != NULL)
00707         *pPidlOut = _ILCreateMyComputer();
00708 
00709     length = (wcslen(lpName) + 1) * sizeof(WCHAR);
00710     sName = (LPWSTR)SHAlloc(length);
00711 
00712     if (!sName)
00713         return E_OUTOFMEMORY;
00714 
00715     if (RegOpenKeyExW(HKEY_CURRENT_USER,
00716                       L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CLSID\\{20D04FE0-3AEA-1069-A2D8-08002B30309D}",
00717                       0,
00718                       KEY_WRITE,
00719                       &hKey) != ERROR_SUCCESS)
00720     {
00721         WARN("Error: failed to open registry key\n");
00722     }
00723     else
00724     {
00725         RegSetValueExW(hKey, NULL, 0, REG_SZ, (const LPBYTE)lpName, length);
00726         RegCloseKey(hKey);
00727     }
00728 
00729     wcscpy(sName, lpName);
00730     SHFree(sName);
00731     sName = sName;
00732     TRACE("result %s\n", debugstr_w(sName));
00733     return S_OK;
00734 }
00735 
00736 HRESULT WINAPI CDrivesFolder::GetDefaultSearchGUID(GUID * pguid)
00737 {
00738     FIXME ("(%p)\n", this);
00739     return E_NOTIMPL;
00740 }
00741 
00742 HRESULT WINAPI CDrivesFolder::EnumSearches(IEnumExtraSearch ** ppenum)
00743 {
00744     FIXME ("(%p)\n", this);
00745     return E_NOTIMPL;
00746 }
00747 
00748 HRESULT WINAPI CDrivesFolder::GetDefaultColumn (DWORD dwRes, ULONG *pSort, ULONG *pDisplay)
00749 {
00750     TRACE ("(%p)\n", this);
00751 
00752     if (pSort)
00753         *pSort = 0;
00754     if (pDisplay)
00755         *pDisplay = 0;
00756     return S_OK;
00757 }
00758 
00759 HRESULT WINAPI CDrivesFolder::GetDefaultColumnState(UINT iColumn, DWORD * pcsFlags)
00760 {
00761     TRACE ("(%p)\n", this);
00762 
00763     if (!pcsFlags || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS)
00764         return E_INVALIDARG;
00765     *pcsFlags = MyComputerSFHeader[iColumn].pcsFlags;
00766     return S_OK;
00767 }
00768 
00769 HRESULT WINAPI CDrivesFolder::GetDetailsEx(LPCITEMIDLIST pidl, const SHCOLUMNID * pscid, VARIANT * pv)
00770 {
00771     FIXME ("(%p)\n", this);
00772     return E_NOTIMPL;
00773 }
00774 
00775 /* FIXME: drive size >4GB is rolling over */
00776 HRESULT WINAPI CDrivesFolder::GetDetailsOf(LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS *psd)
00777 {
00778     HRESULT hr;
00779 
00780     TRACE ("(%p)->(%p %i %p)\n", this, pidl, iColumn, psd);
00781 
00782     if (!psd || iColumn >= MYCOMPUTERSHELLVIEWCOLUMNS)
00783         return E_INVALIDARG;
00784 
00785     if (!pidl)
00786     {
00787         psd->fmt = MyComputerSFHeader[iColumn].fmt;
00788         psd->cxChar = MyComputerSFHeader[iColumn].cxChar;
00789         psd->str.uType = STRRET_CSTR;
00790         LoadStringA(shell32_hInstance, MyComputerSFHeader[iColumn].colnameid,
00791                     psd->str.cStr, MAX_PATH);
00792         return S_OK;
00793     }
00794     else
00795     {
00796         char szPath[MAX_PATH];
00797         ULARGE_INTEGER ulBytes;
00798 
00799         psd->str.cStr[0] = 0x00;
00800         psd->str.uType = STRRET_CSTR;
00801         switch (iColumn)
00802         {
00803             case 0:        /* name */
00804                 hr = GetDisplayNameOf(pidl,
00805                                       SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
00806                 break;
00807             case 1:        /* type */
00808                 _ILGetFileType(pidl, psd->str.cStr, MAX_PATH);
00809                 break;
00810             case 2:        /* total size */
00811                 if (_ILIsDrive(pidl))
00812                 {
00813                     _ILSimpleGetText (pidl, szPath, MAX_PATH);
00814                     GetDiskFreeSpaceExA (szPath, NULL, &ulBytes, NULL);
00815                     StrFormatByteSizeA (ulBytes.LowPart, psd->str.cStr, MAX_PATH);
00816                 }
00817                 break;
00818             case 3:        /* free size */
00819                 if (_ILIsDrive(pidl))
00820                 {
00821                     _ILSimpleGetText (pidl, szPath, MAX_PATH);
00822                     GetDiskFreeSpaceExA (szPath, &ulBytes, NULL, NULL);
00823                     StrFormatByteSizeA (ulBytes.LowPart, psd->str.cStr, MAX_PATH);
00824                 }
00825                 break;
00826         }
00827         hr = S_OK;
00828     }
00829 
00830     return hr;
00831 }
00832 
00833 HRESULT WINAPI CDrivesFolder::MapColumnToSCID(UINT column, SHCOLUMNID * pscid)
00834 {
00835     FIXME("(%p)\n", this);
00836     return E_NOTIMPL;
00837 }
00838 
00839 /************************************************************************
00840  *    CDrivesFolder::GetClassID
00841  */
00842 HRESULT WINAPI CDrivesFolder::GetClassID(CLSID *lpClassId)
00843 {
00844     TRACE ("(%p)\n", this);
00845 
00846     if (!lpClassId)
00847         return E_POINTER;
00848 
00849     *lpClassId = CLSID_MyComputer;
00850     return S_OK;
00851 }
00852 
00853 /************************************************************************
00854  *    CDrivesFolder::Initialize
00855  *
00856  * NOTES: it makes no sense to change the pidl
00857  */
00858 HRESULT WINAPI CDrivesFolder::Initialize(LPCITEMIDLIST pidl)
00859 {
00860     TRACE ("(%p)->(%p)\n", this, pidl);
00861 
00862     if (pidlRoot)
00863         SHFree((LPVOID)pidlRoot);
00864 
00865     pidlRoot = ILClone(pidl);
00866     return S_OK;
00867 }
00868 
00869 /**************************************************************************
00870  *    CDrivesFolder::GetCurFolder
00871  */
00872 HRESULT WINAPI CDrivesFolder::GetCurFolder(LPITEMIDLIST *pidl)
00873 {
00874     TRACE("(%p)->(%p)\n", this, pidl);
00875 
00876     if (!pidl)
00877         return E_POINTER;
00878 
00879     *pidl = ILClone(pidlRoot);
00880     return S_OK;
00881 }

Generated on Sat May 26 2012 04:24:58 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.