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

cpanel.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 doxygen 1.7.6.1

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