From 35e2c06791ce2c1b36f1d0d893a1f9b5f61379da Mon Sep 17 00:00:00 2001 From: Martin Fuchs Date: Tue, 6 Jan 2004 21:33:12 +0000 Subject: [PATCH] implemented IShellExecuteHook for control panel svn path=/trunk/; revision=7492 --- reactos/lib/shell32/control.c | 20 +- reactos/lib/shell32/pidl.c | 12 +- reactos/lib/shell32/shfldr_desktop.c | 3 +- reactos/lib/shell32/shfldr_mycomp.c | 4 +- reactos/lib/shell32/shlcpanel.c | 434 ++++++++++++++++++--------- reactos/lib/shell32/shlexec.c | 20 +- reactos/lib/shell32/shlfolder.c | 4 +- reactos/lib/shell32/shlfsbind.c | 1 - reactos/lib/shell32/shv_item_cmenu.c | 2 +- 9 files changed, 341 insertions(+), 159 deletions(-) diff --git a/reactos/lib/shell32/control.c b/reactos/lib/shell32/control.c index 6eeb62fda08..d040273071b 100644 --- a/reactos/lib/shell32/control.c +++ b/reactos/lib/shell32/control.c @@ -465,7 +465,25 @@ HRESULT WINAPI Control_FillCache_RunDLLW(HWND hWnd, HANDLE hModule, DWORD w, DWO void WINAPI RunDLL_CallEntry16( DWORD proc, HWND hwnd, HINSTANCE inst, LPCSTR cmdline, INT cmdshow ) { - FIXME("RunDLL_CallEntry16 not implemented\n"); +#if !defined(__CYGWIN__) && !defined (__MINGW32__) && !defined(_MSC_VER) + WORD args[5]; + SEGPTR cmdline_seg; + + TRACE( "proc %lx hwnd %p inst %p cmdline %s cmdshow %d\n", + proc, hwnd, inst, debugstr_a(cmdline), cmdshow ); + + cmdline_seg = MapLS( cmdline ); + args[4] = HWND_16(hwnd); + args[3] = MapHModuleLS(inst); + args[2] = SELECTOROF(cmdline_seg); + args[1] = OFFSETOF(cmdline_seg); + args[0] = cmdshow; + WOWCallback16Ex( proc, WCB16_PASCAL, sizeof(args), args, NULL ); + UnMapLS( cmdline_seg ); +#else + FIXME( "proc %lx hwnd %p inst %p cmdline %s cmdshow %d\n", + proc, hwnd, inst, debugstr_a(cmdline), cmdshow ); +#endif } /************************************************************************* diff --git a/reactos/lib/shell32/pidl.c b/reactos/lib/shell32/pidl.c index 8fdfc169283..fb6f1b0c86b 100644 --- a/reactos/lib/shell32/pidl.c +++ b/reactos/lib/shell32/pidl.c @@ -1520,12 +1520,12 @@ HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCI if (SUCCEEDED(hr)) { - hr = IShellFolder_QueryInterface(desktop, riid, ppv); + hr = IShellFolder_QueryInterface(desktop, riid, ppv); - if (SUCCEEDED(hr) && ppidlLast) - *ppidlLast = ILClone(pidl); + if (SUCCEEDED(hr) && ppidlLast) + *ppidlLast = ILClone(pidl); - IShellFolder_Release(desktop); + IShellFolder_Release(desktop); } } else @@ -1545,7 +1545,9 @@ HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCI ILFree (pidlChild); SHFree (pidlParent); - if (psf) IShellFolder_Release(psf); + + if (psf) + IShellFolder_Release(psf); } TRACE_(shell)("-- psf=%p pidl=%p ret=0x%08lx\n", *ppv, (ppidlLast)?*ppidlLast:NULL, hr); diff --git a/reactos/lib/shell32/shfldr_desktop.c b/reactos/lib/shell32/shfldr_desktop.c index c9eac04fa07..14aec33b88d 100644 --- a/reactos/lib/shell32/shfldr_desktop.c +++ b/reactos/lib/shell32/shfldr_desktop.c @@ -676,4 +676,5 @@ static ICOM_VTABLE (IShellFolder2) vt_MCFldr_ShellFolder2 = ISF_Desktop_fnGetDefaultColumnState, ISF_Desktop_fnGetDetailsEx, ISF_Desktop_fnGetDetailsOf, - ISF_Desktop_fnMapColumnToSCID}; + ISF_Desktop_fnMapColumnToSCID +}; diff --git a/reactos/lib/shell32/shfldr_mycomp.c b/reactos/lib/shell32/shfldr_mycomp.c index 6b8085ade67..c3fb8726a4e 100644 --- a/reactos/lib/shell32/shfldr_mycomp.c +++ b/reactos/lib/shell32/shfldr_mycomp.c @@ -656,7 +656,7 @@ static HRESULT WINAPI ISF_MyComputer_fnMapColumnToSCID (IShellFolder2 * iface, U static ICOM_VTABLE (IShellFolder2) vt_ShellFolder2 = { - ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE ISF_MyComputer_fnQueryInterface, ISF_MyComputer_fnAddRef, ISF_MyComputer_fnRelease, @@ -671,7 +671,7 @@ static ICOM_VTABLE (IShellFolder2) vt_ShellFolder2 = ISF_MyComputer_fnGetDisplayNameOf, ISF_MyComputer_fnSetNameOf, /* ShellFolder2 */ - ISF_MyComputer_fnGetDefaultSearchGUID, + ISF_MyComputer_fnGetDefaultSearchGUID, ISF_MyComputer_fnEnumSearches, ISF_MyComputer_fnGetDefaultColumn, ISF_MyComputer_fnGetDefaultColumnState, diff --git a/reactos/lib/shell32/shlcpanel.c b/reactos/lib/shell32/shlcpanel.c index 8b60aeb706e..a4458bafa41 100644 --- a/reactos/lib/shell32/shlcpanel.c +++ b/reactos/lib/shell32/shlcpanel.c @@ -58,29 +58,45 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell); typedef struct { ICOM_VFIELD(IShellFolder2); DWORD ref; - ICOM_VTABLE(IPersistFolder2) * lpVtblPersistFolder2; + + ICOM_VTABLE(IPersistFolder2)* lpVtblPersistFolder2; + ICOM_VTABLE(IShellExecuteHookW)* lpVtblShellExecuteHookW; + ICOM_VTABLE(IShellExecuteHookA)* lpVtblShellExecuteHookA; + + IUnknown *pUnkOuter; /* used for aggregation */ /* both paths are parsible from the desktop */ LPITEMIDLIST pidlRoot; /* absolute pidl */ int dwAttributes; /* attributes returned by GetAttributesOf FIXME: use it */ -} IGenericSFImpl; +} ICPanelImpl; -static struct ICOM_VTABLE(IShellFolder2) vt_ShellFolder2; -static struct ICOM_VTABLE(IPersistFolder2) vt_PersistFolder2; +static ICOM_VTABLE(IShellFolder2) vt_ShellFolder2; +static ICOM_VTABLE(IPersistFolder2) vt_PersistFolder2; +static ICOM_VTABLE(IShellExecuteHookW) vt_ShellExecuteHookW; +static ICOM_VTABLE(IShellExecuteHookA) vt_ShellExecuteHookA; + +#define _IPersistFolder2_Offset ((int)(&(((ICPanelImpl*)0)->lpVtblPersistFolder2))) +#define _ICOM_THIS_From_IPersistFolder2(class, name) class* This =(class*)(((char*)name)-_IPersistFolder2_Offset); + +#define IShellExecuteHookW_Offset ((int)(&(((ICPanelImpl*)0)->lpVtblShellExecuteHookW))) +#define _ICOM_THIS_From_IShellExecuteHookW(class, name) class* This =(class*)(((char*)name)-IShellExecuteHookW_Offset); + +#define IShellExecuteHookA_Offset ((int)(&(((ICPanelImpl*)0)->lpVtblShellExecuteHookA))) +#define _ICOM_THIS_From_IShellExecuteHookA(class, name) class* This =(class*)(((char*)name)-IShellExecuteHookA_Offset); -#define _IPersistFolder2_Offset ((int)(&(((IGenericSFImpl*)0)->lpVtblPersistFolder2))) -#define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder2_Offset); /* converts This to a interface pointer */ -#define _IUnknown_(This) (IUnknown*)&(This->lpVtbl) -#define _IShellFolder_(This) (IShellFolder*)&(This->lpVtbl) -#define _IShellFolder2_(This) (IShellFolder2*)&(This->lpVtbl) +#define _IUnknown_(This) (IUnknown*)&(This->lpVtbl) +#define _IShellFolder_(This) (IShellFolder*)&(This->lpVtbl) +#define _IShellFolder2_(This) (IShellFolder2*)&(This->lpVtbl) -#define _IPersist_(This) (IPersist*)&(This->lpVtblPersistFolder2) -#define _IPersistFolder_(This) (IPersistFolder*)&(This->lpVtblPersistFolder2) -#define _IPersistFolder2_(This) (IPersistFolder2*)&(This->lpVtblPersistFolder2) +#define _IPersist_(This) (IPersist*)&(This->lpVtblPersistFolder2) +#define _IPersistFolder_(This) (IPersistFolder*)&(This->lpVtblPersistFolder2) +#define _IPersistFolder2_(This) (IPersistFolder2*)&(This->lpVtblPersistFolder2) +#define _IShellExecuteHookW_(This) (IShellExecuteHookW*)&(This->lpVtblShellExecuteHookW) +#define _IShellExecuteHookA_(This) (IShellExecuteHookA*)&(This->lpVtblShellExecuteHookA) /*********************************************************************** * IShellFolder [ControlPanel] implementation @@ -96,25 +112,28 @@ static shvheader ControlPanelSFHeader[] = { /************************************************************************** * IControlPanel_Constructor */ -HRESULT WINAPI IControlPanel_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv) +HRESULT WINAPI IControlPanel_Constructor(IUnknown* pUnkOuter, REFIID riid, LPVOID * ppv) { - IGenericSFImpl *sf; + ICPanelImpl *sf; TRACE("unkOut=%p %s\n", pUnkOuter, shdebugstr_guid(riid)); if (!ppv) return E_POINTER; - if (pUnkOuter) + if (pUnkOuter && !IsEqualIID (riid, &IID_IUnknown)) return CLASS_E_NOAGGREGATION; - sf = (IGenericSFImpl *) LocalAlloc(GMEM_ZEROINIT, sizeof(IGenericSFImpl)); + sf = (ICPanelImpl *) LocalAlloc(GMEM_ZEROINIT, sizeof(ICPanelImpl)); if (!sf) return E_OUTOFMEMORY; sf->ref = 0; sf->lpVtbl = &vt_ShellFolder2; sf->lpVtblPersistFolder2 = &vt_PersistFolder2; + sf->lpVtblShellExecuteHookW = &vt_ShellExecuteHookW; + sf->lpVtblShellExecuteHookA = &vt_ShellExecuteHookA; sf->pidlRoot = _ILCreateControl(); /* my qualified pidl */ + sf->pUnkOuter = pUnkOuter ? pUnkOuter : _IUnknown_ (sf); if (!SUCCEEDED(IUnknown_QueryInterface(_IUnknown_(sf), riid, ppv))) { IUnknown_Release(_IUnknown_(sf)); @@ -130,25 +149,28 @@ HRESULT WINAPI IControlPanel_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVO * * NOTES supports not IPersist/IPersistFolder */ -static HRESULT WINAPI ISF_ControlPanel_fnQueryInterface(IShellFolder2 * iface, REFIID riid, LPVOID * ppvObj) +static HRESULT WINAPI ISF_ControlPanel_fnQueryInterface(IShellFolder2 * iface, REFIID riid, LPVOID * ppvObject) { - ICOM_THIS(IGenericSFImpl, iface); + ICOM_THIS(ICPanelImpl, iface); - TRACE("(%p)->(%s,%p)\n", This, shdebugstr_guid(riid), ppvObj); + TRACE("(%p)->(%s,%p)\n", This, shdebugstr_guid(riid), ppvObject); - *ppvObj = NULL; + *ppvObject = NULL; if (IsEqualIID(riid, &IID_IUnknown) || - IsEqualIID(riid, &IID_IShellFolder) || IsEqualIID(riid, &IID_IShellFolder2)) { - *ppvObj = This; - } else if (IsEqualIID(riid, &IID_IPersist) || - IsEqualIID(riid, &IID_IPersistFolder) || IsEqualIID(riid, &IID_IPersistFolder2)) { - *ppvObj = _IPersistFolder2_(This); - } + IsEqualIID(riid, &IID_IShellFolder) || IsEqualIID(riid, &IID_IShellFolder2)) + *ppvObject = This; + else if (IsEqualIID(riid, &IID_IPersist) || + IsEqualIID(riid, &IID_IPersistFolder) || IsEqualIID(riid, &IID_IPersistFolder2)) + *ppvObject = _IPersistFolder2_(This); + else if (IsEqualIID(riid, &IID_IShellExecuteHookW)) + *ppvObject = _IShellExecuteHookW_(This); + else if (IsEqualIID(riid, &IID_IShellExecuteHookA)) + *ppvObject = _IShellExecuteHookA_(This); - if (*ppvObj) { - IUnknown_AddRef((IUnknown *)(*ppvObj)); - TRACE("-- Interface:(%p)->(%p)\n", ppvObj, *ppvObj); + if (*ppvObject) { + IUnknown_AddRef((IUnknown *)(*ppvObject)); + TRACE("-- Interface:(%p)->(%p)\n", ppvObject, *ppvObject); return S_OK; } TRACE("-- Interface: E_NOINTERFACE\n"); @@ -157,7 +179,7 @@ static HRESULT WINAPI ISF_ControlPanel_fnQueryInterface(IShellFolder2 * iface, R static ULONG WINAPI ISF_ControlPanel_fnAddRef(IShellFolder2 * iface) { - ICOM_THIS(IGenericSFImpl, iface); + ICOM_THIS(ICPanelImpl, iface); TRACE("(%p)->(count=%lu)\n", This, This->ref); @@ -166,7 +188,7 @@ static ULONG WINAPI ISF_ControlPanel_fnAddRef(IShellFolder2 * iface) static ULONG WINAPI ISF_ControlPanel_fnRelease(IShellFolder2 * iface) { - ICOM_THIS(IGenericSFImpl, iface); + ICOM_THIS(ICPanelImpl, iface); TRACE("(%p)->(count=%lu)\n", This, This->ref); @@ -190,47 +212,17 @@ ISF_ControlPanel_fnParseDisplayName(IShellFolder2 * iface, LPOLESTR lpszDisplayName, DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes) { - ICOM_THIS(IGenericSFImpl, iface); + ICOM_THIS(ICPanelImpl, iface); - HRESULT hr = E_OUTOFMEMORY; - LPCWSTR szNext = NULL; - WCHAR szElement[MAX_PATH]; - CHAR szTempA[MAX_PATH]; - LPITEMIDLIST pidlTemp = NULL; - CLSID clsid; + HRESULT hr = E_INVALIDARG; - TRACE("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n", + FIXME("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n", This, hwndOwner, pbc, lpszDisplayName, debugstr_w(lpszDisplayName), pchEaten, ppidl, pdwAttributes); *ppidl = 0; if (pchEaten) *pchEaten = 0; - /* handle CLSID paths */ - if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':') { - szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH); - TRACE("-- element: %s\n", debugstr_w(szElement)); - SHCLSIDFromStringW(szElement + 2, &clsid); - pidlTemp = _ILCreate(PT_MYCOMP, &clsid, sizeof(clsid)); - } - /* do we have an absolute path name ? */ - else if (PathGetDriveNumberW(lpszDisplayName)>=0 && lpszDisplayName[2]==(WCHAR) '\\') { - szNext = GetNextElementW(lpszDisplayName, szElement, MAX_PATH); - WideCharToMultiByte(CP_ACP, 0, szElement, -1, szTempA, MAX_PATH, NULL, NULL); - pidlTemp = _ILCreateDrive(szTempA); - } - - if (szNext && *szNext) { - hr = SHELL32_ParseNextElement(iface, hwndOwner, pbc, &pidlTemp,(LPOLESTR) szNext, pchEaten, pdwAttributes); - } else { - if (pdwAttributes && *pdwAttributes) { - SHELL32_GetItemAttributes(_IShellFolder_(This), pidlTemp, pdwAttributes); - } - hr = S_OK; - } - - *ppidl = pidlTemp; - TRACE("(%p)->(-- ret=0x%08lx)\n", This, hr); return hr; @@ -242,7 +234,7 @@ ISF_ControlPanel_fnParseDisplayName(IShellFolder2 * iface, static HRESULT WINAPI ISF_ControlPanel_fnEnumObjects(IShellFolder2 * iface, HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST * ppEnumIDList) { - ICOM_THIS(IGenericSFImpl, iface); + ICOM_THIS(ICPanelImpl, iface); TRACE("(%p)->(HWND=%p flags=0x%08lx pplist=%p)\n", This, hwndOwner, dwFlags, ppEnumIDList); @@ -260,7 +252,7 @@ static HRESULT WINAPI ISF_ControlPanel_fnBindToObject(IShellFolder2 * iface, LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut) { - ICOM_THIS(IGenericSFImpl, iface); + ICOM_THIS(ICPanelImpl, iface); TRACE("(%p)->(pidl=%p,%p,%s,%p)\n", This, pidl, pbcReserved, shdebugstr_guid(riid), ppvOut); @@ -274,7 +266,7 @@ static HRESULT WINAPI ISF_ControlPanel_fnBindToStorage(IShellFolder2 * iface, LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut) { - ICOM_THIS(IGenericSFImpl, iface); + ICOM_THIS(ICPanelImpl, iface); FIXME("(%p)->(pidl=%p,%p,%s,%p) stub\n", This, pidl, pbcReserved, shdebugstr_guid(riid), ppvOut); @@ -289,7 +281,7 @@ ISF_ControlPanel_fnBindToStorage(IShellFolder2 * iface, static HRESULT WINAPI ISF_ControlPanel_fnCompareIDs(IShellFolder2 * iface, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) { - ICOM_THIS(IGenericSFImpl, iface); + ICOM_THIS(ICPanelImpl, iface); int nReturn; @@ -305,7 +297,7 @@ ISF_ControlPanel_fnCompareIDs(IShellFolder2 * iface, LPARAM lParam, LPCITEMIDLIS static HRESULT WINAPI ISF_ControlPanel_fnCreateViewObject(IShellFolder2 * iface, HWND hwndOwner, REFIID riid, LPVOID * ppvOut) { - ICOM_THIS(IGenericSFImpl, iface); + ICOM_THIS(ICPanelImpl, iface); LPSHELLVIEW pShellView; HRESULT hr = E_INVALIDARG; @@ -339,7 +331,7 @@ ISF_ControlPanel_fnCreateViewObject(IShellFolder2 * iface, HWND hwndOwner, REFII static HRESULT WINAPI ISF_ControlPanel_fnGetAttributesOf(IShellFolder2 * iface, UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut) { - ICOM_THIS(IGenericSFImpl, iface); + ICOM_THIS(ICPanelImpl, iface); HRESULT hr = S_OK; @@ -376,7 +368,7 @@ ISF_ControlPanel_fnGetUIObjectOf(IShellFolder2 * iface, HWND hwndOwner, UINT cidl, LPCITEMIDLIST * apidl, REFIID riid, UINT * prgfInOut, LPVOID * ppvOut) { - ICOM_THIS(IGenericSFImpl, iface); + ICOM_THIS(ICPanelImpl, iface); LPITEMIDLIST pidl; IUnknown *pObj = NULL; @@ -389,23 +381,21 @@ ISF_ControlPanel_fnGetUIObjectOf(IShellFolder2 * iface, *ppvOut = NULL; if (IsEqualIID(riid, &IID_IContextMenu) &&(cidl >= 1)) { - pObj = (LPUNKNOWN) ISvItemCm_Constructor((IShellFolder *) iface, This->pidlRoot, apidl, cidl); + pObj =(LPUNKNOWN) ISvItemCm_Constructor((IShellFolder *) iface, This->pidlRoot, apidl, cidl); hr = S_OK; } else if (IsEqualIID(riid, &IID_IDataObject) &&(cidl >= 1)) { - pObj = (LPUNKNOWN) IDataObject_Constructor(hwndOwner, This->pidlRoot, apidl, cidl); + pObj =(LPUNKNOWN) IDataObject_Constructor(hwndOwner, This->pidlRoot, apidl, cidl); hr = S_OK; } else if (IsEqualIID(riid, &IID_IExtractIconA) &&(cidl == 1)) { pidl = ILCombine(This->pidlRoot, apidl[0]); - pObj = (LPUNKNOWN) IExtractIconA_Constructor(pidl); + pObj =(LPUNKNOWN) IExtractIconA_Constructor(pidl); SHFree(pidl); hr = S_OK; } else if (IsEqualIID(riid, &IID_IExtractIconW) &&(cidl == 1)) { pidl = ILCombine(This->pidlRoot, apidl[0]); - pObj = (LPUNKNOWN) IExtractIconW_Constructor(pidl); + pObj =(LPUNKNOWN) IExtractIconW_Constructor(pidl); SHFree(pidl); hr = S_OK; - } else if (IsEqualIID(riid, &IID_IDropTarget) &&(cidl >= 1)) { - hr = IShellFolder_QueryInterface(iface, &IID_IDropTarget,(LPVOID *) & pObj); } else if ((IsEqualIID(riid,&IID_IShellLinkW) || IsEqualIID(riid,&IID_IShellLinkA)) &&(cidl >= 1)) { pidl = ILCombine(This->pidlRoot, apidl[0]); @@ -429,7 +419,7 @@ ISF_ControlPanel_fnGetUIObjectOf(IShellFolder2 * iface, */ static HRESULT WINAPI ISF_ControlPanel_fnGetDisplayNameOf(IShellFolder2 * iface, LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet) { - ICOM_THIS(IGenericSFImpl, iface); + ICOM_THIS(ICPanelImpl, iface); CHAR szPath[MAX_PATH*2]; PIDLCPanelStruct* pcpanel; @@ -445,15 +435,7 @@ static HRESULT WINAPI ISF_ControlPanel_fnGetDisplayNameOf(IShellFolder2 * iface, pcpanel = _ILGetCPanelPointer(pidl); if (pcpanel) { - if (dwFlags & SHGDN_FORPARSING) { - lstrcpyA(szPath, "\""); - lstrcpyA(szPath+1, pcpanel->szName); - - /* pass applet name to Control_RunDLL to distinguish between applets in one .cpl file */ - lstrcatA(szPath, "\" "); - lstrcatA(szPath, pcpanel->szName+pcpanel->offsDispName); - } else - lstrcpyA(szPath, pcpanel->szName+pcpanel->offsDispName); + lstrcpyA(szPath, pcpanel->szName+pcpanel->offsDispName); if (!(dwFlags & SHGDN_FORPARSING)) FIXME("retrieve display name from control panel app\n"); @@ -468,14 +450,14 @@ static HRESULT WINAPI ISF_ControlPanel_fnGetDisplayNameOf(IShellFolder2 * iface, FIXME("special pidl\n"); } - if ((dwFlags & SHGDN_FORPARSING) && !bSimplePidl) { /* go deeper if needed */ + if ((dwFlags & SHGDN_FORPARSING) && !bSimplePidl) { /* go deeper if needed */ int len = 0; PathAddBackslashA(szPath); /*FIXME*/ len = lstrlenA(szPath); if (!SUCCEEDED - (SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags | SHGDN_INFOLDER, szPath + len, MAX_PATH - len))) + (SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags | SHGDN_INFOLDER, szPath + len, MAX_PATH - len))) return E_OUTOFMEMORY; } } @@ -502,26 +484,26 @@ static HRESULT WINAPI ISF_ControlPanel_fnGetDisplayNameOf(IShellFolder2 * iface, static HRESULT WINAPI ISF_ControlPanel_fnSetNameOf(IShellFolder2 * iface, HWND hwndOwner, LPCITEMIDLIST pidl, /*simple pidl */ LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST * pPidlOut) { - ICOM_THIS(IGenericSFImpl, iface); + ICOM_THIS(ICPanelImpl, iface); FIXME("(%p)->(%p,pidl=%p,%s,%lu,%p)\n", This, hwndOwner, pidl, debugstr_w(lpName), dwFlags, pPidlOut); return E_FAIL; } static HRESULT WINAPI ISF_ControlPanel_fnGetDefaultSearchGUID(IShellFolder2 * iface, GUID * pguid) { - ICOM_THIS(IGenericSFImpl, iface); + ICOM_THIS(ICPanelImpl, iface); FIXME("(%p)\n", This); return E_NOTIMPL; } static HRESULT WINAPI ISF_ControlPanel_fnEnumSearches(IShellFolder2 * iface, IEnumExtraSearch ** ppenum) { - ICOM_THIS(IGenericSFImpl, iface); + ICOM_THIS(ICPanelImpl, iface); FIXME("(%p)\n", This); return E_NOTIMPL; } static HRESULT WINAPI ISF_ControlPanel_fnGetDefaultColumn(IShellFolder2 * iface, DWORD dwRes, ULONG * pSort, ULONG * pDisplay) { - ICOM_THIS(IGenericSFImpl, iface); + ICOM_THIS(ICPanelImpl, iface); TRACE("(%p)\n", This); @@ -531,7 +513,7 @@ static HRESULT WINAPI ISF_ControlPanel_fnGetDefaultColumn(IShellFolder2 * iface, } static HRESULT WINAPI ISF_ControlPanel_fnGetDefaultColumnState(IShellFolder2 * iface, UINT iColumn, DWORD * pcsFlags) { - ICOM_THIS(IGenericSFImpl, iface); + ICOM_THIS(ICPanelImpl, iface); TRACE("(%p)\n", This); @@ -541,14 +523,14 @@ static HRESULT WINAPI ISF_ControlPanel_fnGetDefaultColumnState(IShellFolder2 * i } static HRESULT WINAPI ISF_ControlPanel_fnGetDetailsEx(IShellFolder2 * iface, LPCITEMIDLIST pidl, const SHCOLUMNID * pscid, VARIANT * pv) { - ICOM_THIS(IGenericSFImpl, iface); + ICOM_THIS(ICPanelImpl, iface); FIXME("(%p)\n", This); return E_NOTIMPL; } static HRESULT WINAPI ISF_ControlPanel_fnGetDetailsOf(IShellFolder2 * iface, LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS * psd) { - ICOM_THIS(IGenericSFImpl, iface); + ICOM_THIS(ICPanelImpl, iface); HRESULT hr; TRACE("(%p)->(%p %i %p)\n", This, pidl, iColumn, psd); @@ -580,55 +562,57 @@ static HRESULT WINAPI ISF_ControlPanel_fnGetDetailsOf(IShellFolder2 * iface, LPC } static HRESULT WINAPI ISF_ControlPanel_fnMapColumnToSCID(IShellFolder2 * iface, UINT column, SHCOLUMNID * pscid) { - ICOM_THIS(IGenericSFImpl, iface); + ICOM_THIS(ICPanelImpl, iface); FIXME("(%p)\n", This); return E_NOTIMPL; } static ICOM_VTABLE(IShellFolder2) vt_ShellFolder2 = { - ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE - ISF_ControlPanel_fnQueryInterface, - ISF_ControlPanel_fnAddRef, - ISF_ControlPanel_fnRelease, - ISF_ControlPanel_fnParseDisplayName, - ISF_ControlPanel_fnEnumObjects, - ISF_ControlPanel_fnBindToObject, - ISF_ControlPanel_fnBindToStorage, - ISF_ControlPanel_fnCompareIDs, - ISF_ControlPanel_fnCreateViewObject, - ISF_ControlPanel_fnGetAttributesOf, - ISF_ControlPanel_fnGetUIObjectOf, - ISF_ControlPanel_fnGetDisplayNameOf, - ISF_ControlPanel_fnSetNameOf, - /* ShellFolder2 */ - ISF_ControlPanel_fnGetDefaultSearchGUID, - ISF_ControlPanel_fnEnumSearches, - ISF_ControlPanel_fnGetDefaultColumn, - ISF_ControlPanel_fnGetDefaultColumnState, - ISF_ControlPanel_fnGetDetailsEx, - ISF_ControlPanel_fnGetDetailsOf, - ISF_ControlPanel_fnMapColumnToSCID + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + + ISF_ControlPanel_fnQueryInterface, + ISF_ControlPanel_fnAddRef, + ISF_ControlPanel_fnRelease, + ISF_ControlPanel_fnParseDisplayName, + ISF_ControlPanel_fnEnumObjects, + ISF_ControlPanel_fnBindToObject, + ISF_ControlPanel_fnBindToStorage, + ISF_ControlPanel_fnCompareIDs, + ISF_ControlPanel_fnCreateViewObject, + ISF_ControlPanel_fnGetAttributesOf, + ISF_ControlPanel_fnGetUIObjectOf, + ISF_ControlPanel_fnGetDisplayNameOf, + ISF_ControlPanel_fnSetNameOf, + + /* ShellFolder2 */ + ISF_ControlPanel_fnGetDefaultSearchGUID, + ISF_ControlPanel_fnEnumSearches, + ISF_ControlPanel_fnGetDefaultColumn, + ISF_ControlPanel_fnGetDefaultColumnState, + ISF_ControlPanel_fnGetDetailsEx, + ISF_ControlPanel_fnGetDetailsOf, + ISF_ControlPanel_fnMapColumnToSCID }; /************************************************************************ - * IMCFldr_PersistFolder2_QueryInterface + * ICPanel_PersistFolder2_QueryInterface */ -static HRESULT WINAPI IMCFldr_PersistFolder2_QueryInterface(IPersistFolder2 * iface, REFIID iid, LPVOID * ppvObj) +static HRESULT WINAPI ICPanel_PersistFolder2_QueryInterface(IPersistFolder2 * iface, REFIID iid, LPVOID * ppvObject) { - _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface); + _ICOM_THIS_From_IPersistFolder2(ICPanelImpl, iface); TRACE("(%p)\n", This); - return IUnknown_QueryInterface(_IUnknown_(This), iid, ppvObj); + return IUnknown_QueryInterface(_IUnknown_(This), iid, ppvObject); } /************************************************************************ - * IMCFldr_PersistFolder2_AddRef + * ICPanel_PersistFolder2_AddRef */ -static ULONG WINAPI IMCFldr_PersistFolder2_AddRef(IPersistFolder2 * iface) +static ULONG WINAPI ICPanel_PersistFolder2_AddRef(IPersistFolder2 * iface) { - _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface); + _ICOM_THIS_From_IPersistFolder2(ICPanelImpl, iface); TRACE("(%p)->(count=%lu)\n", This, This->ref); @@ -638,9 +622,9 @@ static ULONG WINAPI IMCFldr_PersistFolder2_AddRef(IPersistFolder2 * iface) /************************************************************************ * ISFPersistFolder_Release */ -static ULONG WINAPI IMCFldr_PersistFolder2_Release(IPersistFolder2 * iface) +static ULONG WINAPI ICPanel_PersistFolder2_Release(IPersistFolder2 * iface) { - _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface); + _ICOM_THIS_From_IPersistFolder2(ICPanelImpl, iface); TRACE("(%p)->(count=%lu)\n", This, This->ref); @@ -648,11 +632,11 @@ static ULONG WINAPI IMCFldr_PersistFolder2_Release(IPersistFolder2 * iface) } /************************************************************************ - * IMCFldr_PersistFolder2_GetClassID + * ICPanel_PersistFolder2_GetClassID */ -static HRESULT WINAPI IMCFldr_PersistFolder2_GetClassID(IPersistFolder2 * iface, CLSID * lpClassId) +static HRESULT WINAPI ICPanel_PersistFolder2_GetClassID(IPersistFolder2 * iface, CLSID * lpClassId) { - _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface); + _ICOM_THIS_From_IPersistFolder2(ICPanelImpl, iface); TRACE("(%p)\n", This); @@ -664,13 +648,13 @@ static HRESULT WINAPI IMCFldr_PersistFolder2_GetClassID(IPersistFolder2 * iface, } /************************************************************************ - * IMCFldr_PersistFolder2_Initialize + * ICPanel_PersistFolder2_Initialize * * NOTES: it makes no sense to change the pidl */ -static HRESULT WINAPI IMCFldr_PersistFolder2_Initialize(IPersistFolder2 * iface, LPCITEMIDLIST pidl) +static HRESULT WINAPI ICPanel_PersistFolder2_Initialize(IPersistFolder2 * iface, LPCITEMIDLIST pidl) { - _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface); + _ICOM_THIS_From_IPersistFolder2(ICPanelImpl, iface); TRACE("(%p)->(%p)\n", This, pidl); return E_NOTIMPL; } @@ -678,9 +662,9 @@ static HRESULT WINAPI IMCFldr_PersistFolder2_Initialize(IPersistFolder2 * iface, /************************************************************************** * IPersistFolder2_fnGetCurFolder */ -static HRESULT WINAPI IMCFldr_PersistFolder2_GetCurFolder(IPersistFolder2 * iface, LPITEMIDLIST * pidl) +static HRESULT WINAPI ICPanel_PersistFolder2_GetCurFolder(IPersistFolder2 * iface, LPITEMIDLIST * pidl) { - _ICOM_THIS_From_IPersistFolder2(IGenericSFImpl, iface); + _ICOM_THIS_From_IPersistFolder2(ICPanelImpl, iface); TRACE("(%p)->(%p)\n", This, pidl); @@ -692,13 +676,14 @@ static HRESULT WINAPI IMCFldr_PersistFolder2_GetCurFolder(IPersistFolder2 * ifac static ICOM_VTABLE(IPersistFolder2) vt_PersistFolder2 = { -ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE - IMCFldr_PersistFolder2_QueryInterface, - IMCFldr_PersistFolder2_AddRef, - IMCFldr_PersistFolder2_Release, - IMCFldr_PersistFolder2_GetClassID, - IMCFldr_PersistFolder2_Initialize, - IMCFldr_PersistFolder2_GetCurFolder + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + + ICPanel_PersistFolder2_QueryInterface, + ICPanel_PersistFolder2_AddRef, + ICPanel_PersistFolder2_Release, + ICPanel_PersistFolder2_GetClassID, + ICPanel_PersistFolder2_Initialize, + ICPanel_PersistFolder2_GetCurFolder }; HRESULT WINAPI CPanel_GetIconLocationA(LPITEMIDLIST pidl, LPSTR szIconFile, UINT cchMax, int* piIndex) @@ -726,3 +711,166 @@ HRESULT WINAPI CPanel_GetIconLocationW(LPITEMIDLIST pidl, LPWSTR szIconFile, UIN return S_OK; } + + +/************************************************************************** +* IShellExecuteHookW Implementation +*/ + +static HRESULT WINAPI IShellExecuteHookW_fnQueryInterface(IShellExecuteHookW* iface, REFIID riid, void** ppvObject) +{ + _ICOM_THIS_From_IShellExecuteHookW(ICPanelImpl, iface); + + TRACE("(%p)->(count=%lu)\n", This, This->ref); + + return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObject); +} + +static ULONG STDMETHODCALLTYPE IShellExecuteHookW_fnAddRef(IShellExecuteHookW* iface) +{ + _ICOM_THIS_From_IShellExecuteHookW(ICPanelImpl, iface); + + TRACE("(%p)->(count=%lu)\n", This, This->ref); + + return IUnknown_AddRef(This->pUnkOuter); +} + +static ULONG STDMETHODCALLTYPE IShellExecuteHookW_fnRelease(IShellExecuteHookW* iface) +{ + _ICOM_THIS_From_IShellExecuteHookW(ICPanelImpl, iface); + + TRACE("(%p)\n", This); + + return IUnknown_Release(This->pUnkOuter); +} + +static HRESULT WINAPI IShellExecuteHookW_fnExecute(IShellExecuteHookW* iface, LPSHELLEXECUTEINFOW psei) +{ + ICOM_THIS(ICPanelImpl, iface); + + SHELLEXECUTEINFOW sei_tmp; + PIDLCPanelStruct* pcpanel; + WCHAR path[MAX_PATH]; + BOOL ret; + int l; + + TRACE("(%p)->execute(%x)\n", This, psei); + + if (!psei) + return E_INVALIDARG; + + pcpanel = _ILGetCPanelPointer(ILFindLastID(psei->lpIDList)); + + if (!pcpanel) + return E_INVALIDARG; + + path[0] = '\"'; + l = 1 + MultiByteToWideChar(CP_ACP, 0, pcpanel->szName, -1, path+1, MAX_PATH); + + /* pass applet name to Control_RunDLL to distinguish between applets in one .cpl file */ + lstrcpyW(path+1, L"\" "); + l += 2; + + MultiByteToWideChar(CP_ACP, 0, pcpanel->szName+pcpanel->offsDispName, -1, path+l, MAX_PATH); + + memcpy(&sei_tmp, psei, sizeof(sei_tmp)); + sei_tmp.lpFile = path; + sei_tmp.fMask &= ~SEE_MASK_INVOKEIDLIST; + + ret = ShellExecuteExW(&sei_tmp); + if (ret) + return S_OK; + else + return S_FALSE; +} + +static ICOM_VTABLE(IShellExecuteHookW) vt_ShellExecuteHookW = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + + IShellExecuteHookW_fnQueryInterface, + IShellExecuteHookW_fnAddRef, + IShellExecuteHookW_fnRelease, + + IShellExecuteHookW_fnExecute +}; + + +/************************************************************************** +* IShellExecuteHookA Implementation +*/ + +static HRESULT WINAPI IShellExecuteHookA_fnQueryInterface(IShellExecuteHookA* iface, REFIID riid, void** ppvObject) +{ + _ICOM_THIS_From_IShellExecuteHookA(ICPanelImpl, iface); + + TRACE("(%p)->(count=%lu)\n", This, This->ref); + + return IUnknown_QueryInterface(This->pUnkOuter, riid, ppvObject); +} + +static ULONG STDMETHODCALLTYPE IShellExecuteHookA_fnAddRef(IShellExecuteHookA* iface) +{ + _ICOM_THIS_From_IShellExecuteHookA(ICPanelImpl, iface); + + TRACE("(%p)->(count=%lu)\n", This, This->ref); + + return IUnknown_AddRef(This->pUnkOuter); +} + +static ULONG STDMETHODCALLTYPE IShellExecuteHookA_fnRelease(IShellExecuteHookA* iface) +{ + _ICOM_THIS_From_IShellExecuteHookA(ICPanelImpl, iface); + + TRACE("(%p)\n", This); + + return IUnknown_Release(This->pUnkOuter); +} + +static HRESULT WINAPI IShellExecuteHookA_fnExecute(IShellExecuteHookA* iface, LPSHELLEXECUTEINFOA psei) +{ + ICOM_THIS(ICPanelImpl, iface); + + SHELLEXECUTEINFOA sei_tmp; + PIDLCPanelStruct* pcpanel; + char path[MAX_PATH]; + BOOL ret; + + TRACE("(%p)->execute(%x)\n", This, psei); + + if (!psei) + return E_INVALIDARG; + + pcpanel = _ILGetCPanelPointer(ILFindLastID(psei->lpIDList)); + + if (!pcpanel) + return E_INVALIDARG; + + path[0] = '\"'; + lstrcpyA(path+1, pcpanel->szName); + + /* pass applet name to Control_RunDLL to distinguish between applets in one .cpl file */ + lstrcatA(path, "\" "); + lstrcatA(path, pcpanel->szName+pcpanel->offsDispName); + + memcpy(&sei_tmp, psei, sizeof(sei_tmp)); + sei_tmp.lpFile = path; + sei_tmp.fMask &= ~SEE_MASK_INVOKEIDLIST; + + ret = ShellExecuteExA(&sei_tmp); + if (ret) + return S_OK; + else + return S_FALSE; +} + +static ICOM_VTABLE(IShellExecuteHookA) vt_ShellExecuteHookA = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + + IShellExecuteHookA_fnQueryInterface, + IShellExecuteHookA_fnAddRef, + IShellExecuteHookA_fnRelease, + + IShellExecuteHookA_fnExecute +}; diff --git a/reactos/lib/shell32/shlexec.c b/reactos/lib/shell32/shlexec.c index e6104c4bb20..c0e832051ce 100644 --- a/reactos/lib/shell32/shlexec.c +++ b/reactos/lib/shell32/shlexec.c @@ -427,7 +427,7 @@ static UINT _FindExecutableByOperation(LPCSTR lpPath, LPCSTR lpFile, LPCSTR lpOp * on the operation) */ UINT SHELL_FindExecutable(LPCSTR lpPath, LPCSTR lpFile, LPCSTR lpOperation, - LPSTR lpResult, LPSTR key, void **env, LPITEMIDLIST pidl, LPCSTR args) + LPSTR lpResult, LPSTR key, void **env, LPITEMIDLIST pidl, LPCSTR args) { char *extension = NULL; /* pointer to file extension */ char tmpext[5]; /* local copy to mung as we please */ @@ -851,6 +851,19 @@ BOOL WINAPI ShellExecuteExA32 (LPSHELLEXECUTEINFOA sei, SHELL_ExecuteA1632 execf /* process the IDList */ if (sei->fMask & SEE_MASK_INVOKEIDLIST) /* 0x0c: includes SEE_MASK_IDLIST */ { + IShellExecuteHookA* pSEH; + + HRESULT hr = SHBindToParent(pidl, &IID_IShellExecuteHookA, (LPVOID*)&pSEH, NULL); + + if (SUCCEEDED(hr)) { + hr = IShellExecuteHookA_Execute(pSEH, sei); + + IShellExecuteHookA_Release(pSEH); + + if (hr == S_OK) + return TRUE; + } + if (!SHGetPathFromIDListA(pidl, szApplicationName)) return FALSE; @@ -859,7 +872,7 @@ BOOL WINAPI ShellExecuteExA32 (LPSHELLEXECUTEINFOA sei, SHELL_ExecuteA1632 execf if (sei->fMask & (SEE_MASK_CLASSNAME | SEE_MASK_CLASSKEY)) { - /* launch a document by fileclass like 'WordPad.Document.1' */ + /* launch a document by fileclass like 'WordPad.Document.1' */ /* the Commandline contains 'c:\Path\wordpad.exe "%1"' */ /* FIXME: szCommandline should not be of a fixed size. Plus MAX_PATH is way too short! */ if (sei->fMask & SEE_MASK_CLASSKEY) @@ -970,7 +983,8 @@ BOOL WINAPI ShellExecuteExA32 (LPSHELLEXECUTEINFOA sei, SHELL_ExecuteA1632 execf } else { - /*FIXME This search loop should be moved into CreateProcess() ? */ + /* We have to use this search loop here, that in CreateProcess() + is not sufficent because it does not handle shell links. */ LPSTR space, s; char buffer[MAX_PATH], xlpFile[MAX_PATH]; diff --git a/reactos/lib/shell32/shlfolder.c b/reactos/lib/shell32/shlfolder.c index 91ba87df0f2..15f392df471 100644 --- a/reactos/lib/shell32/shlfolder.c +++ b/reactos/lib/shell32/shlfolder.c @@ -388,9 +388,9 @@ HRESULT SHELL32_GetItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWO *pdwAttributes &= ~SFGAO_READONLY; if (SFGAO_LINK & *pdwAttributes) { - char ext[_MAX_EXT]; + char ext[MAX_PATH]; - if (!_ILGetExtension(pidl, ext, _MAX_EXT) || stricmp(ext, "lnk")) + if (!_ILGetExtension(pidl, ext, MAX_PATH) || stricmp(ext, "lnk")) *pdwAttributes &= ~SFGAO_READONLY; } } else { diff --git a/reactos/lib/shell32/shlfsbind.c b/reactos/lib/shell32/shlfsbind.c index 04b25401c85..3619beb0b41 100644 --- a/reactos/lib/shell32/shlfsbind.c +++ b/reactos/lib/shell32/shlfsbind.c @@ -26,7 +26,6 @@ #include "windef.h" #include "winbase.h" -#include "wingdi.h" #include "winreg.h" #include "winuser.h" #include "shlobj.h" diff --git a/reactos/lib/shell32/shv_item_cmenu.c b/reactos/lib/shell32/shv_item_cmenu.c index 77f0ad6e412..c5beee9be7a 100644 --- a/reactos/lib/shell32/shv_item_cmenu.c +++ b/reactos/lib/shell32/shv_item_cmenu.c @@ -295,7 +295,7 @@ static void DoOpenExplore( sei.cbSize = sizeof(sei); sei.fMask = SEE_MASK_IDLIST | SEE_MASK_CLASSNAME; sei.lpIDList = pidlFQ; - sei.lpClass = "folder"; + sei.lpClass = "Folder"; sei.hwnd = hwnd; sei.nShow = SW_SHOWNORMAL; sei.lpVerb = verb;