Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencpanel.cpp
Go to the documentation of this file.
00001 /* 00002 * Control panel folder 00003 * 00004 * Copyright 2003 Martin Fuchs 00005 * Copyright 2009 Andrew Hill 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00020 */ 00021 00022 /* 00023 TODO: 00024 1. The selected items list should not be stored in CControlPanelFolder, it should 00025 be a result returned by an internal method. 00026 */ 00027 00028 #include <precomp.h> 00029 00030 WINE_DEFAULT_DEBUG_CHANNEL(shell); 00031 00032 /*********************************************************************** 00033 * control panel implementation in shell namespace 00034 */ 00035 00036 class CControlPanelEnum : 00037 public IEnumIDListImpl 00038 { 00039 public: 00040 CControlPanelEnum(); 00041 ~CControlPanelEnum(); 00042 HRESULT WINAPI Initialize(DWORD dwFlags); 00043 BOOL RegisterCPanelApp(LPCSTR path); 00044 int RegisterRegistryCPanelApps(HKEY hkey_root, LPCSTR szRepPath); 00045 int RegisterCPanelFolders(HKEY hkey_root, LPCSTR szRepPath); 00046 BOOL CreateCPanelEnumList(DWORD dwFlags); 00047 00048 BEGIN_COM_MAP(CControlPanelEnum) 00049 COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList) 00050 END_COM_MAP() 00051 }; 00052 00053 /*********************************************************************** 00054 * IShellFolder [ControlPanel] implementation 00055 */ 00056 00057 static const shvheader ControlPanelSFHeader[] = { 00058 {IDS_SHV_COLUMN8, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},/*FIXME*/ 00059 {IDS_SHV_COLUMN9, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 200},/*FIXME*/ 00060 }; 00061 00062 #define CONROLPANELSHELLVIEWCOLUMNS 2 00063 00064 CControlPanelEnum::CControlPanelEnum() 00065 { 00066 } 00067 00068 CControlPanelEnum::~CControlPanelEnum() 00069 { 00070 } 00071 00072 HRESULT WINAPI CControlPanelEnum::Initialize(DWORD dwFlags) 00073 { 00074 if (CreateCPanelEnumList(dwFlags) == FALSE) 00075 return E_FAIL; 00076 return S_OK; 00077 } 00078 00079 static LPITEMIDLIST _ILCreateCPanelApplet(LPCSTR pszName, LPCSTR pszDisplayName, LPCSTR pszComment, int iIconIdx) 00080 { 00081 PIDLCPanelStruct *pCP; 00082 LPITEMIDLIST pidl; 00083 LPPIDLDATA pData; 00084 int cchName, cchDisplayName, cchComment, cbData; 00085 00086 /* Calculate lengths of given strings */ 00087 cchName = strlen(pszName); 00088 cchDisplayName = strlen(pszDisplayName); 00089 cchComment = strlen(pszComment); 00090 00091 /* Allocate PIDL */ 00092 cbData = sizeof(pidl->mkid.cb) + sizeof(pData->type) + sizeof(pData->u.cpanel) - sizeof(pData->u.cpanel.szName) 00093 + cchName + cchDisplayName + cchComment + 3; 00094 pidl = (LPITEMIDLIST)SHAlloc(cbData + sizeof(WORD)); 00095 if (!pidl) 00096 return NULL; 00097 00098 /* Copy data to allocated memory */ 00099 pidl->mkid.cb = cbData; 00100 pData = (PIDLDATA *)pidl->mkid.abID; 00101 pData->type = PT_CPLAPPLET; 00102 00103 pCP = &pData->u.cpanel; 00104 pCP->dummy = 0; 00105 pCP->iconIdx = iIconIdx; 00106 strcpy(pCP->szName, pszName); 00107 pCP->offsDispName = cchName + 1; 00108 strcpy(pCP->szName + pCP->offsDispName, pszDisplayName); 00109 pCP->offsComment = pCP->offsDispName + cchDisplayName + 1; 00110 strcpy(pCP->szName + pCP->offsComment, pszComment); 00111 00112 /* Add PIDL NULL terminator */ 00113 *(WORD*)(pCP->szName + pCP->offsComment + cchComment + 1) = 0; 00114 00115 pcheck(pidl); 00116 00117 return pidl; 00118 } 00119 00120 /************************************************************************** 00121 * _ILGetCPanelPointer() 00122 * gets a pointer to the control panel struct stored in the pidl 00123 */ 00124 static PIDLCPanelStruct *_ILGetCPanelPointer(LPCITEMIDLIST pidl) 00125 { 00126 LPPIDLDATA pdata = _ILGetDataPointer(pidl); 00127 00128 if (pdata && pdata->type == PT_CPLAPPLET) 00129 return (PIDLCPanelStruct *) & (pdata->u.cpanel); 00130 00131 return NULL; 00132 } 00133 00134 BOOL CControlPanelEnum::RegisterCPanelApp(LPCSTR path) 00135 { 00136 LPITEMIDLIST pidl; 00137 CPlApplet* applet; 00138 CPanel panel; 00139 CPLINFO info; 00140 unsigned i; 00141 int iconIdx; 00142 00143 char displayName[MAX_PATH]; 00144 char comment[MAX_PATH]; 00145 00146 WCHAR wpath[MAX_PATH]; 00147 00148 MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, MAX_PATH); 00149 00150 panel.first = NULL; 00151 applet = Control_LoadApplet(0, wpath, &panel); 00152 00153 if (applet) 00154 { 00155 for (i = 0; i < applet->count; ++i) 00156 { 00157 WideCharToMultiByte(CP_ACP, 0, applet->info[i].szName, -1, displayName, MAX_PATH, 0, 0); 00158 WideCharToMultiByte(CP_ACP, 0, applet->info[i].szInfo, -1, comment, MAX_PATH, 0, 0); 00159 00160 applet->proc(0, CPL_INQUIRE, i, (LPARAM)&info); 00161 00162 if (info.idIcon > 0) 00163 iconIdx = -info.idIcon; /* negative icon index instead of icon number */ 00164 else 00165 iconIdx = 0; 00166 00167 pidl = _ILCreateCPanelApplet(path, displayName, comment, iconIdx); 00168 00169 if (pidl) 00170 AddToEnumList(pidl); 00171 } 00172 Control_UnloadApplet(applet); 00173 } 00174 return TRUE; 00175 } 00176 00177 int CControlPanelEnum::RegisterRegistryCPanelApps(HKEY hkey_root, LPCSTR szRepPath) 00178 { 00179 char name[MAX_PATH]; 00180 char value[MAX_PATH]; 00181 HKEY hkey; 00182 00183 int cnt = 0; 00184 00185 if (RegOpenKeyA(hkey_root, szRepPath, &hkey) == ERROR_SUCCESS) 00186 { 00187 int idx = 0; 00188 00189 for(; ; idx++) 00190 { 00191 DWORD nameLen = MAX_PATH; 00192 DWORD valueLen = MAX_PATH; 00193 00194 if (RegEnumValueA(hkey, idx, name, &nameLen, NULL, NULL, (LPBYTE)&value, &valueLen) != ERROR_SUCCESS) 00195 break; 00196 00197 if (RegisterCPanelApp(value)) 00198 ++cnt; 00199 } 00200 RegCloseKey(hkey); 00201 } 00202 00203 return cnt; 00204 } 00205 00206 int CControlPanelEnum::RegisterCPanelFolders(HKEY hkey_root, LPCSTR szRepPath) 00207 { 00208 char name[MAX_PATH]; 00209 HKEY hkey; 00210 00211 int cnt = 0; 00212 00213 if (RegOpenKeyA(hkey_root, szRepPath, &hkey) == ERROR_SUCCESS) 00214 { 00215 int idx = 0; 00216 for (; ; idx++) 00217 { 00218 if (RegEnumKeyA(hkey, idx, name, MAX_PATH) != ERROR_SUCCESS) 00219 break; 00220 00221 if (*name == '{') 00222 { 00223 LPITEMIDLIST pidl = _ILCreateGuidFromStrA(name); 00224 00225 if (pidl && AddToEnumList(pidl)) 00226 ++cnt; 00227 } 00228 } 00229 00230 RegCloseKey(hkey); 00231 } 00232 00233 return cnt; 00234 } 00235 00236 /************************************************************************** 00237 * CControlPanelEnum::CreateCPanelEnumList() 00238 */ 00239 BOOL CControlPanelEnum::CreateCPanelEnumList(DWORD dwFlags) 00240 { 00241 CHAR szPath[MAX_PATH]; 00242 WIN32_FIND_DATAA wfd; 00243 HANDLE hFile; 00244 00245 TRACE("(%p)->(flags=0x%08x)\n", this, dwFlags); 00246 00247 /* enumerate control panel folders */ 00248 if (dwFlags & SHCONTF_FOLDERS) 00249 RegisterCPanelFolders(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ControlPanel\\NameSpace"); 00250 00251 /* enumerate the control panel applets */ 00252 if (dwFlags & SHCONTF_NONFOLDERS) 00253 { 00254 LPSTR p; 00255 00256 GetSystemDirectoryA(szPath, MAX_PATH); 00257 p = PathAddBackslashA(szPath); 00258 strcpy(p, "*.cpl"); 00259 00260 TRACE("-- (%p)-> enumerate SHCONTF_NONFOLDERS of %s\n", this, debugstr_a(szPath)); 00261 hFile = FindFirstFileA(szPath, &wfd); 00262 00263 if (hFile != INVALID_HANDLE_VALUE) 00264 { 00265 do 00266 { 00267 if (!(dwFlags & SHCONTF_INCLUDEHIDDEN) && (wfd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)) 00268 continue; 00269 00270 if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { 00271 strcpy(p, wfd.cFileName); 00272 if (strcmp(wfd.cFileName, "ncpa.cpl")) 00273 RegisterCPanelApp(szPath); 00274 } 00275 } while(FindNextFileA(hFile, &wfd)); 00276 FindClose(hFile); 00277 } 00278 00279 RegisterRegistryCPanelApps(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cpls"); 00280 RegisterRegistryCPanelApps(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cpls"); 00281 } 00282 return TRUE; 00283 } 00284 00285 CControlPanelFolder::CControlPanelFolder() 00286 { 00287 pidlRoot = NULL; /* absolute pidl */ 00288 dwAttributes = 0; /* attributes returned by GetAttributesOf FIXME: use it */ 00289 apidl = NULL; 00290 cidl = 0; 00291 } 00292 00293 CControlPanelFolder::~CControlPanelFolder() 00294 { 00295 TRACE("-- destroying IShellFolder(%p)\n", this); 00296 SHFree(pidlRoot); 00297 } 00298 00299 HRESULT WINAPI CControlPanelFolder::FinalConstruct() 00300 { 00301 pidlRoot = _ILCreateControlPanel(); /* my qualified pidl */ 00302 if (pidlRoot == NULL) 00303 return E_OUTOFMEMORY; 00304 return S_OK; 00305 } 00306 00307 /************************************************************************** 00308 * CControlPanelFolder::ParseDisplayName 00309 */ 00310 HRESULT WINAPI CControlPanelFolder::ParseDisplayName( 00311 HWND hwndOwner, 00312 LPBC pbc, 00313 LPOLESTR lpszDisplayName, 00314 DWORD *pchEaten, 00315 LPITEMIDLIST *ppidl, 00316 DWORD *pdwAttributes) 00317 { 00318 WCHAR szElement[MAX_PATH]; 00319 LPCWSTR szNext = NULL; 00320 LPITEMIDLIST pidlTemp = NULL; 00321 HRESULT hr = S_OK; 00322 CLSID clsid; 00323 00324 TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n", 00325 this, hwndOwner, pbc, lpszDisplayName, debugstr_w(lpszDisplayName), 00326 pchEaten, ppidl, pdwAttributes); 00327 00328 if (!lpszDisplayName || !ppidl) 00329 return E_INVALIDARG; 00330 00331 *ppidl = 0; 00332 00333 if (pchEaten) 00334 *pchEaten = 0; /* strange but like the original */ 00335 00336 if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':') 00337 { 00338 szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH); 00339 TRACE ("-- element: %s\n", debugstr_w (szElement)); 00340 CLSIDFromString (szElement + 2, &clsid); 00341 pidlTemp = _ILCreateGuid (PT_GUID, clsid); 00342 } 00343 else if( (pidlTemp = SHELL32_CreatePidlFromBindCtx(pbc, lpszDisplayName)) ) 00344 { 00345 *ppidl = pidlTemp; 00346 return S_OK; 00347 } 00348 00349 if (SUCCEEDED(hr) && pidlTemp) 00350 { 00351 if (szNext && *szNext) 00352 { 00353 hr = SHELL32_ParseNextElement(this, hwndOwner, pbc, 00354 &pidlTemp, (LPOLESTR) szNext, pchEaten, pdwAttributes); 00355 } 00356 else 00357 { 00358 if (pdwAttributes && *pdwAttributes) 00359 hr = SHELL32_GetItemAttributes(this, 00360 pidlTemp, pdwAttributes); 00361 } 00362 } 00363 00364 *ppidl = pidlTemp; 00365 00366 TRACE ("(%p)->(-- ret=0x%08x)\n", this, hr); 00367 00368 return hr; 00369 } 00370 00371 /************************************************************************** 00372 * CControlPanelFolder::EnumObjects 00373 */ 00374 HRESULT WINAPI CControlPanelFolder::EnumObjects( 00375 HWND hwndOwner, 00376 DWORD dwFlags, 00377 LPENUMIDLIST *ppEnumIDList) 00378 { 00379 CComObject<CControlPanelEnum> *theEnumerator; 00380 CComPtr<IEnumIDList> result; 00381 HRESULT hResult; 00382 00383 TRACE ("(%p)->(HWND=%p flags=0x%08x pplist=%p)\n", this, hwndOwner, dwFlags, ppEnumIDList); 00384 00385 if (ppEnumIDList == NULL) 00386 return E_POINTER; 00387 *ppEnumIDList = NULL; 00388 ATLTRY (theEnumerator = new CComObject<CControlPanelEnum>); 00389 if (theEnumerator == NULL) 00390 return E_OUTOFMEMORY; 00391 hResult = theEnumerator->QueryInterface (IID_IEnumIDList, (void **)&result); 00392 if (FAILED (hResult)) 00393 { 00394 delete theEnumerator; 00395 return hResult; 00396 } 00397 hResult = theEnumerator->Initialize (dwFlags); 00398 if (FAILED (hResult)) 00399 return hResult; 00400 *ppEnumIDList = result.Detach (); 00401 00402 TRACE ("-- (%p)->(new ID List: %p)\n", this, *ppEnumIDList); 00403 00404 return S_OK; 00405 } 00406 00407 /************************************************************************** 00408 * CControlPanelFolder::BindToObject 00409 */ 00410 HRESULT WINAPI CControlPanelFolder::BindToObject( 00411 LPCITEMIDLIST pidl, 00412 LPBC pbcReserved, 00413 REFIID riid, 00414 LPVOID *ppvOut) 00415 { 00416 TRACE("(%p)->(pidl=%p,%p,%s,%p)\n", this, pidl, pbcReserved, shdebugstr_guid(&riid), ppvOut); 00417 00418 return SHELL32_BindToChild(pidlRoot, NULL, pidl, riid, ppvOut); 00419 } 00420 00421 /************************************************************************** 00422 * CControlPanelFolder::BindToStorage 00423 */ 00424 HRESULT WINAPI CControlPanelFolder::BindToStorage( 00425 LPCITEMIDLIST pidl, 00426 LPBC pbcReserved, 00427 REFIID riid, 00428 LPVOID *ppvOut) 00429 { 00430 FIXME("(%p)->(pidl=%p,%p,%s,%p) stub\n", this, pidl, pbcReserved, shdebugstr_guid(&riid), ppvOut); 00431 00432 *ppvOut = NULL; 00433 return E_NOTIMPL; 00434 } 00435 00436 /************************************************************************** 00437 * CControlPanelFolder::CompareIDs 00438 */ 00439 00440 HRESULT WINAPI CControlPanelFolder::CompareIDs(LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) 00441 { 00442 int nReturn; 00443 00444 TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", this, lParam, pidl1, pidl2); 00445 nReturn = SHELL32_CompareIDs(this, lParam, pidl1, pidl2); 00446 TRACE("-- %i\n", nReturn); 00447 return nReturn; 00448 } 00449 00450 /************************************************************************** 00451 * CControlPanelFolder::CreateViewObject 00452 */ 00453 HRESULT WINAPI CControlPanelFolder::CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID * ppvOut) 00454 { 00455 CComPtr<IShellView> pShellView; 00456 HRESULT hr = E_INVALIDARG; 00457 00458 TRACE("(%p)->(hwnd=%p,%s,%p)\n", this, hwndOwner, shdebugstr_guid(&riid), ppvOut); 00459 00460 if (ppvOut) { 00461 *ppvOut = NULL; 00462 00463 if (IsEqualIID(riid, IID_IDropTarget)) { 00464 WARN("IDropTarget not implemented\n"); 00465 hr = E_NOTIMPL; 00466 } else if (IsEqualIID(riid, IID_IContextMenu)) { 00467 WARN("IContextMenu not implemented\n"); 00468 hr = E_NOTIMPL; 00469 } else if (IsEqualIID(riid, IID_IShellView)) { 00470 hr = IShellView_Constructor((IShellFolder *)this, &pShellView); 00471 if (pShellView) { 00472 hr = pShellView->QueryInterface(riid, ppvOut); 00473 } 00474 } 00475 } 00476 TRACE("--(%p)->(interface=%p)\n", this, ppvOut); 00477 return hr; 00478 } 00479 00480 /************************************************************************** 00481 * CControlPanelFolder::GetAttributesOf 00482 */ 00483 HRESULT WINAPI CControlPanelFolder::GetAttributesOf(UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut) 00484 { 00485 HRESULT hr = S_OK; 00486 00487 TRACE("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n", 00488 this, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0); 00489 00490 if (!rgfInOut) 00491 return E_INVALIDARG; 00492 if (cidl && !apidl) 00493 return E_INVALIDARG; 00494 00495 if (*rgfInOut == 0) 00496 *rgfInOut = ~0; 00497 00498 while(cidl > 0 && *apidl) 00499 { 00500 pdump(*apidl); 00501 SHELL32_GetItemAttributes(this, *apidl, rgfInOut); 00502 apidl++; 00503 cidl--; 00504 } 00505 /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */ 00506 *rgfInOut &= ~SFGAO_VALIDATE; 00507 00508 TRACE("-- result=0x%08x\n", *rgfInOut); 00509 return hr; 00510 } 00511 00512 /************************************************************************** 00513 * CControlPanelFolder::GetUIObjectOf 00514 * 00515 * PARAMETERS 00516 * HWND hwndOwner, //[in ] Parent window for any output 00517 * UINT cidl, //[in ] array size 00518 * LPCITEMIDLIST* apidl, //[in ] simple pidl array 00519 * REFIID riid, //[in ] Requested Interface 00520 * UINT* prgfInOut, //[ ] reserved 00521 * LPVOID* ppvObject) //[out] Resulting Interface 00522 * 00523 */ 00524 HRESULT WINAPI CControlPanelFolder::GetUIObjectOf(HWND hwndOwner, 00525 UINT cidl, LPCITEMIDLIST * apidl, REFIID riid, UINT * prgfInOut, LPVOID * ppvOut) 00526 { 00527 LPITEMIDLIST pidl; 00528 IUnknown *pObj = NULL; 00529 HRESULT hr = E_INVALIDARG; 00530 00531 TRACE("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n", 00532 this, hwndOwner, cidl, apidl, shdebugstr_guid(&riid), prgfInOut, ppvOut); 00533 00534 if (ppvOut) { 00535 *ppvOut = NULL; 00536 00537 if (IsEqualIID(riid, IID_IContextMenu) && (cidl >= 1)) { 00538 // TODO 00539 // create a seperate item struct 00540 // 00541 pObj = (IContextMenu *)this; 00542 this->apidl = apidl; 00543 cidl = cidl; 00544 pObj->AddRef(); 00545 hr = S_OK; 00546 } else if (IsEqualIID(riid, IID_IDataObject) && (cidl >= 1)) { 00547 hr = IDataObject_Constructor(hwndOwner, pidlRoot, apidl, cidl, (IDataObject **)&pObj); 00548 } else if (IsEqualIID(riid, IID_IExtractIconA) && (cidl == 1)) { 00549 pidl = ILCombine(pidlRoot, apidl[0]); 00550 pObj = (LPUNKNOWN) IExtractIconA_Constructor(pidl); 00551 SHFree(pidl); 00552 hr = S_OK; 00553 } else if (IsEqualIID(riid, IID_IExtractIconW) && (cidl == 1)) { 00554 pidl = ILCombine(pidlRoot, apidl[0]); 00555 pObj = (LPUNKNOWN) IExtractIconW_Constructor(pidl); 00556 SHFree(pidl); 00557 hr = S_OK; 00558 } else if ((IsEqualIID(riid, IID_IShellLinkW) || IsEqualIID(riid, IID_IShellLinkA)) 00559 && (cidl == 1)) { 00560 pidl = ILCombine(pidlRoot, apidl[0]); 00561 hr = IShellLink_ConstructFromFile(NULL, riid, pidl, (LPVOID*)&pObj); 00562 SHFree(pidl); 00563 } else { 00564 hr = E_NOINTERFACE; 00565 } 00566 00567 if (SUCCEEDED(hr) && !pObj) 00568 hr = E_OUTOFMEMORY; 00569 00570 *ppvOut = pObj; 00571 } 00572 TRACE("(%p)->hr=0x%08x\n", this, hr); 00573 return hr; 00574 } 00575 00576 /************************************************************************** 00577 * CControlPanelFolder::GetDisplayNameOf 00578 */ 00579 HRESULT WINAPI CControlPanelFolder::GetDisplayNameOf(LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet) 00580 { 00581 CHAR szName[MAX_PATH]; 00582 WCHAR wszName[MAX_PATH+1]; /* +1 for potential backslash */ 00583 PIDLCPanelStruct *pCPanel; 00584 HRESULT hr; 00585 00586 *szName = '\0'; 00587 00588 TRACE("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet); 00589 pdump(pidl); 00590 00591 if (!pidl) 00592 return S_FALSE; 00593 00594 pCPanel = _ILGetCPanelPointer(pidl); 00595 00596 if (pCPanel) 00597 { 00598 /* copy display name from pidl - it was retrived from applet before; 00599 SHGDN_FORPARSING does not need special handling */ 00600 lstrcpyA(szName, pCPanel->szName + pCPanel->offsDispName); 00601 } 00602 /* take names of special folders only if it's only this folder */ 00603 else if (_ILIsSpecialFolder(pidl)) 00604 { 00605 BOOL bSimplePidl = _ILIsPidlSimple(pidl); 00606 SFGAOF Attr = SFGAO_FILESYSTEM; 00607 00608 SHELL32_GetItemAttributes(this, pidl, &Attr); 00609 if (Attr & SFGAO_FILESYSTEM) 00610 { 00611 hr = SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, wszName, sizeof(wszName)); 00612 if (FAILED(hr)) 00613 return hr; 00614 } 00615 else if (bSimplePidl) 00616 { 00617 _ILSimpleGetTextW(pidl, wszName, MAX_PATH); /* append my own path */ 00618 } 00619 else 00620 { 00621 FIXME("special pidl\n"); 00622 if (dwFlags & SHGDN_FORPARSING) 00623 { 00624 /* go deeper if needed */ 00625 int cchName; 00626 00627 PathAddBackslashW(wszName); 00628 cchName = wcslen(wszName); 00629 00630 hr = SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, wszName + cchName, MAX_PATH + 1 - cchName); 00631 if (FAILED(hr)) 00632 return hr; 00633 } 00634 } 00635 00636 if (!WideCharToMultiByte(CP_ACP, 0, wszName, -1, szName, MAX_PATH, NULL, NULL)) 00637 szName[0] = '\0'; 00638 } 00639 00640 strRet->uType = STRRET_CSTR; 00641 lstrcpynA(strRet->cStr, szName, MAX_PATH); 00642 00643 TRACE("--(%p)->(%s)\n", this, szName); 00644 return S_OK; 00645 } 00646 00647 /************************************************************************** 00648 * CControlPanelFolder::SetNameOf 00649 * Changes the name of a file object or subfolder, possibly changing its item 00650 * identifier in the process. 00651 * 00652 * PARAMETERS 00653 * HWND hwndOwner, //[in ] Owner window for output 00654 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change 00655 * LPCOLESTR lpszName, //[in ] the items new display name 00656 * DWORD dwFlags, //[in ] SHGNO formatting flags 00657 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned 00658 */ 00659 HRESULT WINAPI CControlPanelFolder::SetNameOf(HWND hwndOwner, LPCITEMIDLIST pidl, /*simple pidl */ 00660 LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST * pPidlOut) 00661 { 00662 FIXME("(%p)->(%p,pidl=%p,%s,%u,%p)\n", this, hwndOwner, pidl, debugstr_w(lpName), dwFlags, pPidlOut); 00663 return E_FAIL; 00664 } 00665 00666 HRESULT WINAPI CControlPanelFolder::GetDefaultSearchGUID(GUID *pguid) 00667 { 00668 FIXME("(%p)\n", this); 00669 return E_NOTIMPL; 00670 } 00671 00672 HRESULT WINAPI CControlPanelFolder::EnumSearches(IEnumExtraSearch **ppenum) 00673 { 00674 FIXME("(%p)\n", this); 00675 return E_NOTIMPL; 00676 } 00677 00678 HRESULT WINAPI CControlPanelFolder::GetDefaultColumn(DWORD dwRes, ULONG *pSort, ULONG *pDisplay) 00679 { 00680 TRACE("(%p)\n", this); 00681 00682 if (pSort) *pSort = 0; 00683 if (pDisplay) *pDisplay = 0; 00684 return S_OK; 00685 } 00686 00687 HRESULT WINAPI CControlPanelFolder::GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags) 00688 { 00689 TRACE("(%p)\n", this); 00690 00691 if (!pcsFlags || iColumn >= CONROLPANELSHELLVIEWCOLUMNS) return E_INVALIDARG; 00692 *pcsFlags = ControlPanelSFHeader[iColumn].pcsFlags; 00693 return S_OK; 00694 } 00695 00696 HRESULT WINAPI CControlPanelFolder::GetDetailsEx(LPCITEMIDLIST pidl, const SHCOLUMNID *pscid, VARIANT *pv) 00697 { 00698 FIXME("(%p)\n", this); 00699 return E_NOTIMPL; 00700 } 00701 00702 HRESULT WINAPI CControlPanelFolder::GetDetailsOf(LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS *psd) 00703 { 00704 HRESULT hr; 00705 00706 TRACE("(%p)->(%p %i %p)\n", this, pidl, iColumn, psd); 00707 00708 if (!psd || iColumn >= CONROLPANELSHELLVIEWCOLUMNS) 00709 return E_INVALIDARG; 00710 00711 if (!pidl) { 00712 psd->fmt = ControlPanelSFHeader[iColumn].fmt; 00713 psd->cxChar = ControlPanelSFHeader[iColumn].cxChar; 00714 psd->str.uType = STRRET_CSTR; 00715 LoadStringA(shell32_hInstance, ControlPanelSFHeader[iColumn].colnameid, psd->str.cStr, MAX_PATH); 00716 return S_OK; 00717 } else { 00718 psd->str.cStr[0] = 0x00; 00719 psd->str.uType = STRRET_CSTR; 00720 switch(iColumn) { 00721 case 0: /* name */ 00722 hr = GetDisplayNameOf(pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str); 00723 break; 00724 case 1: /* comment */ 00725 _ILGetFileType(pidl, psd->str.cStr, MAX_PATH); 00726 break; 00727 } 00728 hr = S_OK; 00729 } 00730 00731 return hr; 00732 } 00733 00734 HRESULT WINAPI CControlPanelFolder::MapColumnToSCID(UINT column, SHCOLUMNID *pscid) 00735 { 00736 FIXME("(%p)\n", this); 00737 return E_NOTIMPL; 00738 } 00739 00740 /************************************************************************ 00741 * CControlPanelFolder::GetClassID 00742 */ 00743 HRESULT WINAPI CControlPanelFolder::GetClassID(CLSID *lpClassId) 00744 { 00745 TRACE("(%p)\n", this); 00746 00747 if (!lpClassId) 00748 return E_POINTER; 00749 *lpClassId = CLSID_ControlPanel; 00750 00751 return S_OK; 00752 } 00753 00754 /************************************************************************ 00755 * CControlPanelFolder::Initialize 00756 * 00757 * NOTES: it makes no sense to change the pidl 00758 */ 00759 HRESULT WINAPI CControlPanelFolder::Initialize(LPCITEMIDLIST pidl) 00760 { 00761 if (pidlRoot) 00762 SHFree((LPVOID)pidlRoot); 00763 00764 pidlRoot = ILClone(pidl); 00765 return S_OK; 00766 } 00767 00768 /************************************************************************** 00769 * CControlPanelFolder::GetCurFolder 00770 */ 00771 HRESULT WINAPI CControlPanelFolder::GetCurFolder(LPITEMIDLIST * pidl) 00772 { 00773 TRACE("(%p)->(%p)\n", this, pidl); 00774 00775 if (!pidl) 00776 return E_POINTER; 00777 *pidl = ILClone(pidlRoot); 00778 return S_OK; 00779 } 00780 00781 HRESULT CPanel_GetIconLocationW(LPCITEMIDLIST pidl, LPWSTR szIconFile, UINT cchMax, int* piIndex) 00782 { 00783 PIDLCPanelStruct* pcpanel = _ILGetCPanelPointer(pidl); 00784 00785 if (!pcpanel) 00786 return E_INVALIDARG; 00787 00788 MultiByteToWideChar(CP_ACP, 0, pcpanel->szName, -1, szIconFile, cchMax); 00789 *piIndex = (int)pcpanel->iconIdx != -1 ? pcpanel->iconIdx : 0; 00790 00791 return S_OK; 00792 } 00793 00794 00795 /************************************************************************** 00796 * IShellExecuteHookW Implementation 00797 */ 00798 00799 static HRESULT 00800 ExecuteAppletFromCLSID(LPOLESTR pOleStr) 00801 { 00802 WCHAR wszBuf[128], wszCmd[MAX_PATH]; 00803 DWORD cbCmd = sizeof(wszCmd); 00804 00805 StringCbPrintfW(wszBuf, sizeof(wszBuf), L"CLSID\\%s\\shell\\open\\command", pOleStr); 00806 00807 if (RegGetValueW(HKEY_CLASSES_ROOT, wszBuf, NULL, RRF_RT_REG_SZ, NULL, (PVOID)wszCmd, &cbCmd) != ERROR_SUCCESS) 00808 { 00809 ERR("RegGetValueW(%ls) failed with %u\n", wszBuf, GetLastError()); 00810 return E_FAIL; 00811 } 00812 00813 if (!ExpandEnvironmentStringsW(wszCmd, wszBuf, _countof(wszBuf))) 00814 return E_FAIL; 00815 00816 PROCESS_INFORMATION pi; 00817 STARTUPINFOW si; 00818 ZeroMemory(&si, sizeof(si)); 00819 si.cb = sizeof(si); 00820 if (!CreateProcessW(NULL, wszBuf, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) 00821 return E_FAIL; 00822 00823 CloseHandle(pi.hProcess); 00824 CloseHandle(pi.hThread); 00825 return S_OK; 00826 } 00827 00828 EXTERN_C void WINAPI Control_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow); 00829 00830 HRESULT WINAPI CControlPanelFolder::ExecuteFromIdList(LPCITEMIDLIST pidl) 00831 { 00832 PIDLCPanelStruct *pCPanel = _ILGetCPanelPointer(ILFindLastID(pidl)); 00833 00834 if (!pCPanel) 00835 { 00836 /* Is it GUID to control panel applet? */ 00837 IID *piid = _ILGetGUIDPointer(ILFindLastID(pidl)); 00838 if (!piid) 00839 return E_INVALIDARG; 00840 00841 /* Start it */ 00842 LPOLESTR pOleStr; 00843 if (StringFromCLSID(*piid, &pOleStr) == S_OK) 00844 { 00845 HRESULT hr = ExecuteAppletFromCLSID(pOleStr); 00846 CoTaskMemFree(pOleStr); 00847 return hr; 00848 } 00849 00850 ERR("Cannot open cpanel applet\n"); 00851 return E_INVALIDARG; 00852 } 00853 00854 /* Build control panel applet cmd 00855 Note: we passes applet name to Control_RunDLL to distinguish between applets in one .cpl file */ 00856 WCHAR wszCmd[2*MAX_PATH]; 00857 StringCbPrintfW(wszCmd, sizeof(wszCmd), L"rundll32 shell32.dll,Control_RunDLL \"%hs\",\"%hs\"", pCPanel->szName, pCPanel->szName + pCPanel->offsDispName); 00858 00859 /* Start the applet */ 00860 TRACE("Run cpl %ls\n", wszCmd); 00861 STARTUPINFO si; 00862 PROCESS_INFORMATION pi; 00863 ZeroMemory(&si, sizeof(si)); 00864 si.cb = sizeof(si); 00865 if (!CreateProcessW(NULL, wszCmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) 00866 return E_FAIL; 00867 00868 CloseHandle(pi.hProcess); 00869 CloseHandle(pi.hThread); 00870 return S_OK; 00871 } 00872 00873 HRESULT WINAPI CControlPanelFolder::Execute(LPSHELLEXECUTEINFOW psei) 00874 { 00875 TRACE("(%p)->execute(%p)\n", this, psei); 00876 00877 if (!psei) 00878 return E_INVALIDARG; 00879 00880 if (!(psei->fMask & SEE_MASK_IDLIST)) 00881 { 00882 FIXME("no idlist given!\n"); 00883 return E_FAIL; 00884 } 00885 00886 return ExecuteFromIdList((LPCITEMIDLIST)psei->lpIDList); 00887 } 00888 00889 /************************************************************************** 00890 * IShellExecuteHookA Implementation 00891 */ 00892 00893 HRESULT WINAPI CControlPanelFolder::Execute(LPSHELLEXECUTEINFOA psei) 00894 { 00895 TRACE("(%p)->execute(%p)\n", this, psei); 00896 00897 if (!psei) 00898 return E_INVALIDARG; 00899 00900 if (!(psei->fMask & SEE_MASK_IDLIST)) 00901 { 00902 FIXME("no idlist given!\n"); 00903 return E_FAIL; 00904 } 00905 00906 return ExecuteFromIdList((LPCITEMIDLIST)psei->lpIDList); 00907 } 00908 00909 /************************************************************************** 00910 * IContextMenu2 Implementation 00911 */ 00912 00913 /************************************************************************** 00914 * ICPanel_IContextMenu_QueryContextMenu() 00915 */ 00916 HRESULT WINAPI CControlPanelFolder::QueryContextMenu( 00917 HMENU hMenu, 00918 UINT indexMenu, 00919 UINT idCmdFirst, 00920 UINT idCmdLast, 00921 UINT uFlags) 00922 { 00923 WCHAR szBuffer[30] = {0}; 00924 ULONG Count = 1; 00925 00926 TRACE("(%p)->(hmenu=%p indexmenu=%x cmdfirst=%x cmdlast=%x flags=%x )\n", 00927 this, hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags); 00928 00929 if (LoadStringW(shell32_hInstance, IDS_OPEN, szBuffer, sizeof(szBuffer) / sizeof(WCHAR))) 00930 { 00931 szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0'; 00932 _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_OPEN, MFT_STRING, szBuffer, MFS_DEFAULT); //FIXME identifier 00933 Count++; 00934 } 00935 00936 if (LoadStringW(shell32_hInstance, IDS_CREATELINK, szBuffer, sizeof(szBuffer) / sizeof(WCHAR))) 00937 { 00938 if (Count) 00939 { 00940 _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + Count, MFT_SEPARATOR, NULL, MFS_ENABLED); 00941 } 00942 szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0'; 00943 00944 _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_CREATELINK, MFT_STRING, szBuffer, MFS_ENABLED); //FIXME identifier 00945 Count++; 00946 } 00947 return MAKE_HRESULT(SEVERITY_SUCCESS, 0, Count); 00948 } 00949 00950 /************************************************************************** 00951 * ICPanel_IContextMenu_InvokeCommand() 00952 */ 00953 HRESULT WINAPI CControlPanelFolder::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) 00954 { 00955 SHELLEXECUTEINFOW sei; 00956 WCHAR szPath[MAX_PATH]; 00957 char szTarget[MAX_PATH]; 00958 STRRET strret; 00959 WCHAR* pszPath; 00960 INT Length, cLength; 00961 PIDLCPanelStruct *pcpanel; 00962 CComPtr<IPersistFile> ppf; 00963 CComPtr<IShellLinkA> isl; 00964 HRESULT hResult; 00965 00966 TRACE("(%p)->(invcom=%p verb=%p wnd=%p)\n", this, lpcmi, lpcmi->lpVerb, lpcmi->hwnd); 00967 00968 if (lpcmi->lpVerb == MAKEINTRESOURCEA(IDS_OPEN)) //FIXME 00969 { 00970 ZeroMemory(&sei, sizeof(sei)); 00971 sei.cbSize = sizeof(sei); 00972 sei.fMask = SEE_MASK_INVOKEIDLIST; 00973 sei.lpIDList = ILCombine(pidlRoot, apidl[0]); 00974 sei.hwnd = lpcmi->hwnd; 00975 sei.nShow = SW_SHOWNORMAL; 00976 sei.lpVerb = L"open"; 00977 ERR("here\n"); 00978 return Execute(&sei); 00979 } 00980 else if (lpcmi->lpVerb == MAKEINTRESOURCEA(IDS_CREATELINK)) //FIXME 00981 { 00982 if (!SHGetSpecialFolderPathW(NULL, szPath, CSIDL_DESKTOPDIRECTORY, FALSE)) 00983 return E_FAIL; 00984 00985 pszPath = PathAddBackslashW(szPath); 00986 if (!pszPath) 00987 return E_FAIL; 00988 00989 if (GetDisplayNameOf(apidl[0], SHGDN_FORPARSING, &strret) != S_OK) 00990 return E_FAIL; 00991 00992 Length = MAX_PATH - (pszPath - szPath); 00993 cLength = strlen(strret.cStr); 00994 if (Length < cLength + 5) 00995 { 00996 FIXME("\n"); 00997 return E_FAIL; 00998 } 00999 01000 if (MultiByteToWideChar(CP_ACP, 0, strret.cStr, cLength + 1, pszPath, Length)) 01001 { 01002 pszPath += cLength; 01003 Length -= cLength; 01004 } 01005 01006 if (Length > 10) 01007 { 01008 wcscpy(pszPath, L" - "); 01009 cLength = LoadStringW(shell32_hInstance, IDS_LNK_FILE, &pszPath[3], Length - 4) + 3; 01010 if (cLength + 5 > Length) 01011 cLength = Length - 5; 01012 Length -= cLength; 01013 pszPath += cLength; 01014 } 01015 wcscpy(pszPath, L".lnk"); 01016 01017 pcpanel = _ILGetCPanelPointer(ILFindLastID(apidl[0])); 01018 if (pcpanel) 01019 { 01020 strncpy(szTarget, pcpanel->szName, MAX_PATH); 01021 } 01022 else 01023 { 01024 FIXME("Couldn't retrieve pointer to cpl structure\n"); 01025 return E_FAIL; 01026 } 01027 hResult = CShellLink::_CreatorClass::CreateInstance(NULL, IID_IShellLinkA, (void **)&isl); 01028 if (SUCCEEDED(hResult)) 01029 { 01030 isl->SetPath(szTarget); 01031 if (SUCCEEDED(isl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf))) 01032 ppf->Save(szPath, TRUE); 01033 } 01034 return NOERROR; 01035 } 01036 return S_OK; 01037 } 01038 01039 /************************************************************************** 01040 * ICPanel_IContextMenu_GetCommandString() 01041 * 01042 */ 01043 HRESULT WINAPI CControlPanelFolder::GetCommandString( 01044 UINT_PTR idCommand, 01045 UINT uFlags, 01046 UINT* lpReserved, 01047 LPSTR lpszName, 01048 UINT uMaxNameLen) 01049 { 01050 TRACE("(%p)->(idcom=%lx flags=%x %p name=%p len=%x)\n", this, idCommand, uFlags, lpReserved, lpszName, uMaxNameLen); 01051 01052 FIXME("unknown command string\n"); 01053 return E_FAIL; 01054 } 01055 01056 /************************************************************************** 01057 * ICPanel_IContextMenu_HandleMenuMsg() 01058 */ 01059 HRESULT WINAPI CControlPanelFolder::HandleMenuMsg( 01060 UINT uMsg, 01061 WPARAM wParam, 01062 LPARAM lParam) 01063 { 01064 TRACE("ICPanel_IContextMenu_HandleMenuMsg (%p)->(msg=%x wp=%lx lp=%lx)\n", this, uMsg, wParam, lParam); 01065 01066 return E_NOTIMPL; 01067 } Generated on Wed May 23 2012 04:24:12 for ReactOS by
1.7.6.1
|