[SHELL32]
[reactos.git] / dll / win32 / shell32 / folders / cpanel.cpp
index cf0c9cf..f415461 100644 (file)
@@ -312,7 +312,7 @@ HRESULT WINAPI CControlPanelFolder::ParseDisplayName(
     LPBC pbc,
     LPOLESTR lpszDisplayName,
     DWORD *pchEaten,
-    LPITEMIDLIST *ppidl,
+    PIDLIST_RELATIVE *ppidl,
     DWORD *pdwAttributes)
 {
     WCHAR szElement[MAX_PATH];
@@ -371,44 +371,16 @@ HRESULT WINAPI CControlPanelFolder::ParseDisplayName(
 /**************************************************************************
 *        CControlPanelFolder::EnumObjects
 */
-HRESULT WINAPI CControlPanelFolder::EnumObjects(
-    HWND hwndOwner,
-    DWORD dwFlags,
-    LPENUMIDLIST *ppEnumIDList)
+HRESULT WINAPI CControlPanelFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
 {
-    CComObject<CControlPanelEnum>            *theEnumerator;
-    CComPtr<IEnumIDList>                    result;
-    HRESULT                                    hResult;
-
-    TRACE ("(%p)->(HWND=%p flags=0x%08x pplist=%p)\n", this, hwndOwner, dwFlags, ppEnumIDList);
-
-    if (ppEnumIDList == NULL)
-        return E_POINTER;
-    *ppEnumIDList = NULL;
-    ATLTRY (theEnumerator = new CComObject<CControlPanelEnum>);
-    if (theEnumerator == NULL)
-        return E_OUTOFMEMORY;
-    hResult = theEnumerator->QueryInterface(IID_PPV_ARG(IEnumIDList, &result));
-    if (FAILED (hResult))
-    {
-        delete theEnumerator;
-        return hResult;
-    }
-    hResult = theEnumerator->Initialize (dwFlags);
-    if (FAILED (hResult))
-        return hResult;
-    *ppEnumIDList = result.Detach ();
-
-    TRACE ("-- (%p)->(new ID List: %p)\n", this, *ppEnumIDList);
-
-    return S_OK;
+    return ShellObjectCreatorInit<CControlPanelEnum>(dwFlags, IID_IEnumIDList, ppEnumIDList);
 }
 
 /**************************************************************************
 *        CControlPanelFolder::BindToObject
 */
 HRESULT WINAPI CControlPanelFolder::BindToObject(
-    LPCITEMIDLIST pidl,
+    PCUIDLIST_RELATIVE pidl,
     LPBC pbcReserved,
     REFIID riid,
     LPVOID *ppvOut)
@@ -422,7 +394,7 @@ HRESULT WINAPI CControlPanelFolder::BindToObject(
 *    CControlPanelFolder::BindToStorage
 */
 HRESULT WINAPI CControlPanelFolder::BindToStorage(
-    LPCITEMIDLIST pidl,
+    PCUIDLIST_RELATIVE pidl,
     LPBC pbcReserved,
     REFIID riid,
     LPVOID *ppvOut)
@@ -437,7 +409,7 @@ HRESULT WINAPI CControlPanelFolder::BindToStorage(
 *     CControlPanelFolder::CompareIDs
 */
 
-HRESULT WINAPI CControlPanelFolder::CompareIDs(LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
+HRESULT WINAPI CControlPanelFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
 {
     int nReturn;
 
@@ -480,7 +452,7 @@ HRESULT WINAPI CControlPanelFolder::CreateViewObject(HWND hwndOwner, REFIID riid
 /**************************************************************************
 *  CControlPanelFolder::GetAttributesOf
 */
-HRESULT WINAPI CControlPanelFolder::GetAttributesOf(UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut)
+HRESULT WINAPI CControlPanelFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD * rgfInOut)
 {
     HRESULT hr = S_OK;
 
@@ -522,7 +494,7 @@ HRESULT WINAPI CControlPanelFolder::GetAttributesOf(UINT cidl, LPCITEMIDLIST * a
 *
 */
 HRESULT WINAPI CControlPanelFolder::GetUIObjectOf(HWND hwndOwner,
-        UINT cidl, LPCITEMIDLIST * apidl, REFIID riid, UINT * prgfInOut, LPVOID * ppvOut)
+        UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT * prgfInOut, LPVOID * ppvOut)
 {
     LPITEMIDLIST pidl;
     IUnknown *pObj = NULL;
@@ -547,12 +519,12 @@ HRESULT WINAPI CControlPanelFolder::GetUIObjectOf(HWND hwndOwner,
             hr = IDataObject_Constructor(hwndOwner, pidlRoot, apidl, cidl, (IDataObject **)&pObj);
         } else if (IsEqualIID(riid, IID_IExtractIconA) && (cidl == 1)) {
             pidl = ILCombine(pidlRoot, apidl[0]);
-            pObj = (LPUNKNOWN) IExtractIconA_Constructor(pidl);
+            pObj = IExtractIconA_Constructor(pidl);
             SHFree(pidl);
             hr = S_OK;
         } else if (IsEqualIID(riid, IID_IExtractIconW) && (cidl == 1)) {
             pidl = ILCombine(pidlRoot, apidl[0]);
-            pObj = (LPUNKNOWN) IExtractIconW_Constructor(pidl);
+            pObj = IExtractIconW_Constructor(pidl);
             SHFree(pidl);
             hr = S_OK;
         } else if ((IsEqualIID(riid, IID_IShellLinkW) || IsEqualIID(riid, IID_IShellLinkA))
@@ -576,7 +548,7 @@ HRESULT WINAPI CControlPanelFolder::GetUIObjectOf(HWND hwndOwner,
 /**************************************************************************
 *    CControlPanelFolder::GetDisplayNameOf
 */
-HRESULT WINAPI CControlPanelFolder::GetDisplayNameOf(LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet)
+HRESULT WINAPI CControlPanelFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet)
 {
     CHAR szName[MAX_PATH];
     WCHAR wszName[MAX_PATH+1]; /* +1 for potential backslash */
@@ -656,8 +628,8 @@ HRESULT WINAPI CControlPanelFolder::GetDisplayNameOf(LPCITEMIDLIST pidl, DWORD d
 *  DWORD         dwFlags,    //[in ] SHGNO formatting flags
 *  LPITEMIDLIST* ppidlOut)   //[out] simple pidl returned
 */
-HRESULT WINAPI CControlPanelFolder::SetNameOf(HWND hwndOwner, LPCITEMIDLIST pidl,    /*simple pidl */
-        LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST * pPidlOut)
+HRESULT WINAPI CControlPanelFolder::SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl,    /*simple pidl */
+        LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut)
 {
     FIXME("(%p)->(%p,pidl=%p,%s,%u,%p)\n", this, hwndOwner, pidl, debugstr_w(lpName), dwFlags, pPidlOut);
     return E_FAIL;
@@ -693,13 +665,13 @@ HRESULT WINAPI CControlPanelFolder::GetDefaultColumnState(UINT iColumn, DWORD *p
     return S_OK;
 }
 
-HRESULT WINAPI CControlPanelFolder::GetDetailsEx(LPCITEMIDLIST pidl, const SHCOLUMNID *pscid, VARIANT *pv)
+HRESULT WINAPI CControlPanelFolder::GetDetailsEx(PCUITEMID_CHILD pidl, const SHCOLUMNID *pscid, VARIANT *pv)
 {
     FIXME("(%p)\n", this);
     return E_NOTIMPL;
 }
 
-HRESULT WINAPI CControlPanelFolder::GetDetailsOf(LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS *psd)
+HRESULT WINAPI CControlPanelFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *psd)
 {
     HRESULT hr;
 
@@ -791,126 +763,6 @@ HRESULT CPanel_GetIconLocationW(LPCITEMIDLIST pidl, LPWSTR szIconFile, UINT cchM
     return S_OK;
 }
 
-
-/**************************************************************************
-* IShellExecuteHookW Implementation
-*/
-
-static HRESULT
-ExecuteAppletFromCLSID(LPOLESTR pOleStr)
-{
-    WCHAR wszBuf[128], wszCmd[MAX_PATH];
-    DWORD cbCmd = sizeof(wszCmd);
-
-    StringCbPrintfW(wszBuf, sizeof(wszBuf), L"CLSID\\%s\\shell\\open\\command", pOleStr);
-
-    if (RegGetValueW(HKEY_CLASSES_ROOT, wszBuf, NULL, RRF_RT_REG_SZ, NULL, (PVOID)wszCmd, &cbCmd) != ERROR_SUCCESS)
-    {
-        ERR("RegGetValueW(%ls) failed with %u\n", wszBuf, GetLastError());
-        return E_FAIL;
-    }
-
-    if (!ExpandEnvironmentStringsW(wszCmd, wszBuf, _countof(wszBuf)))
-        return E_FAIL;
-
-    PROCESS_INFORMATION pi;
-    STARTUPINFOW si;
-    ZeroMemory(&si, sizeof(si));
-    si.cb = sizeof(si);
-    if (!CreateProcessW(NULL, wszBuf, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
-        return E_FAIL;
-
-    CloseHandle(pi.hProcess);
-    CloseHandle(pi.hThread);
-    return S_OK;
-}
-
-EXTERN_C void WINAPI Control_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow);
-
-HRESULT WINAPI CControlPanelFolder::ExecuteFromIdList(LPCITEMIDLIST pidl)
-{
-    PIDLCPanelStruct *pCPanel = _ILGetCPanelPointer(ILFindLastID(pidl));
-
-    if (!pCPanel)
-    {
-        /* Is it GUID to control panel applet? */
-        IID *piid = _ILGetGUIDPointer(ILFindLastID(pidl));
-        if (!piid)
-            return E_INVALIDARG;
-
-        /* Start it */
-        LPOLESTR pOleStr;
-        if (StringFromCLSID(*piid, &pOleStr) == S_OK)
-        {
-            HRESULT hr = ExecuteAppletFromCLSID(pOleStr);
-            CoTaskMemFree(pOleStr);
-            return hr;
-        }
-
-        ERR("Cannot open cpanel applet\n");
-        return E_INVALIDARG;
-    }
-
-    /* Build control panel applet cmd
-       Note: we pass the applet name to Control_RunDLL to distinguish between multiple applets in one .cpl file */
-    WCHAR wszCmd[2*MAX_PATH];
-    WCHAR wszAppletName[MAX_PATH];
-
-    if(!MultiByteToWideChar(CP_ACP, 0, pCPanel->szName + pCPanel->offsDispName, -1, wszAppletName, MAX_PATH))
-        return E_FAIL;
-
-    StringCbPrintfW(wszCmd, sizeof(wszCmd), L"rundll32 shell32.dll,Control_RunDLL \"%hs\",\"%ls\"", pCPanel->szName, wszAppletName);
-
-    /* Start the applet */
-    TRACE("Run cpl %ls\n", wszCmd);
-    STARTUPINFO si;
-    PROCESS_INFORMATION pi;
-    ZeroMemory(&si, sizeof(si));
-    si.cb = sizeof(si);
-    if (!CreateProcessW(NULL, wszCmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
-        return E_FAIL;
-
-    CloseHandle(pi.hProcess);
-    CloseHandle(pi.hThread);
-    return S_OK;
-}
-
-HRESULT WINAPI CControlPanelFolder::Execute(LPSHELLEXECUTEINFOW psei)
-{
-    TRACE("(%p)->execute(%p)\n", this, psei);
-
-    if (!psei)
-        return E_INVALIDARG;
-
-    if (!(psei->fMask & SEE_MASK_IDLIST))
-    {
-        FIXME("no idlist given!\n");
-        return E_FAIL;
-    }
-
-    return ExecuteFromIdList((LPCITEMIDLIST)psei->lpIDList);
-}
-
-/**************************************************************************
-* IShellExecuteHookA Implementation
-*/
-
-HRESULT WINAPI CControlPanelFolder::Execute(LPSHELLEXECUTEINFOA psei)
-{
-    TRACE("(%p)->execute(%p)\n", this, psei);
-
-    if (!psei)
-        return E_INVALIDARG;
-
-    if (!(psei->fMask & SEE_MASK_IDLIST))
-    {
-        FIXME("no idlist given!\n");
-        return E_FAIL;
-    }
-
-    return ExecuteFromIdList((LPCITEMIDLIST)psei->lpIDList);
-}
-
 /**************************************************************************
 * IContextMenu2 Implementation
 */
@@ -957,30 +809,38 @@ HRESULT WINAPI CControlPanelFolder::QueryContextMenu(
 */
 HRESULT WINAPI CControlPanelFolder::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
 {
-    SHELLEXECUTEINFOW sei;
     WCHAR szPath[MAX_PATH];
     char szTarget[MAX_PATH];
     STRRET strret;
     WCHAR* pszPath;
     INT Length, cLength;
-    PIDLCPanelStruct *pcpanel;
     CComPtr<IPersistFile>                ppf;
     CComPtr<IShellLinkA>                isl;
     HRESULT hResult;
 
+    PIDLCPanelStruct *pcpanel = _ILGetCPanelPointer(apidl[0]);
+
     TRACE("(%p)->(invcom=%p verb=%p wnd=%p)\n", this, lpcmi, lpcmi->lpVerb, lpcmi->hwnd);
 
     if (lpcmi->lpVerb == MAKEINTRESOURCEA(IDS_OPEN)) //FIXME
     {
-        ZeroMemory(&sei, sizeof(sei));
-        sei.cbSize = sizeof(sei);
-        sei.fMask = SEE_MASK_INVOKEIDLIST;
-        sei.lpIDList = ILCombine(pidlRoot, apidl[0]);
-        sei.hwnd = lpcmi->hwnd;
-        sei.nShow = SW_SHOWNORMAL;
-        sei.lpVerb = L"open";
-ERR("here\n");
-        return Execute(&sei);
+        LPITEMIDLIST lpIDList = ILCombine(pidlRoot, apidl[0]);
+
+        if (!pcpanel)
+        {
+            /* UGLY HACK! */
+            LPSHELLBROWSER lpSB = (LPSHELLBROWSER)SendMessageW(lpcmi->hwnd, CWM_GETISHELLBROWSER, 0, 0);
+            HRESULT hr;
+
+            if (lpSB == NULL)
+                return E_FAIL;
+
+            hr = lpSB->BrowseObject(lpIDList, 0);
+            return hr;
+        }
+
+        /* Note: we pass the applet name to Control_RunDLL to distinguish between multiple applets in one .cpl file */
+        ShellExecuteA(NULL, "cplopen", pcpanel->szName, pcpanel->szName + pcpanel->offsDispName, NULL, 0);
     }
     else if (lpcmi->lpVerb == MAKEINTRESOURCEA(IDS_CREATELINK)) //FIXME
     {