Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmycomp.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
1.7.6.1
|