From 7ccdc95f086bfb148ad73a4a195effae366fecb1 Mon Sep 17 00:00:00 2001 From: Dmitry Chapyshev Date: Sat, 23 May 2009 10:23:33 +0000 Subject: [PATCH] shell32: - Add IShellItem implementation from Wine - Implement SHCreateShellItem setupapi: - Stubimplement SetupUninstallOEMInfA/W - Stubimplement Get_Device_Interface_List_Size_ExA/W svn path=/trunk/; revision=41061 --- reactos/dll/win32/setupapi/misc.c | 45 +++ reactos/dll/win32/setupapi/setupapi.spec | 8 +- reactos/dll/win32/setupapi/stubs.c | 20 + reactos/dll/win32/shell32/pidl.c | 7 - reactos/dll/win32/shell32/shell32.rbuild | 6 + reactos/dll/win32/shell32/shell32_main.h | 1 + reactos/dll/win32/shell32/shellitem.c | 382 +++++++++++++++++++ reactos/dll/win32/shell32/shellole.c | 1 + reactos/dll/win32/shell32/shobjidl_local.idl | 2 + 9 files changed, 461 insertions(+), 11 deletions(-) create mode 100644 reactos/dll/win32/shell32/shellitem.c create mode 100644 reactos/dll/win32/shell32/shobjidl_local.idl diff --git a/reactos/dll/win32/setupapi/misc.c b/reactos/dll/win32/setupapi/misc.c index aa3f1314000..00ccb341acc 100644 --- a/reactos/dll/win32/setupapi/misc.c +++ b/reactos/dll/win32/setupapi/misc.c @@ -1162,6 +1162,51 @@ GetVersionInfoFromImage(LPWSTR lpFileName, return TRUE; } +/*********************************************************************** + * SetupUninstallOEMInfW (SETUPAPI.@) + */ +BOOL WINAPI SetupUninstallOEMInfW( PCWSTR inf_file, DWORD flags, PVOID reserved ) +{ + static const WCHAR infW[] = {'\\','i','n','f','\\',0}; + WCHAR target[MAX_PATH]; + + TRACE("%s, 0x%08x, %p\n", debugstr_w(inf_file), flags, reserved); + + if (!inf_file) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if (!GetWindowsDirectoryW( target, sizeof(target)/sizeof(WCHAR) )) return FALSE; + + strcatW( target, infW ); + strcatW( target, inf_file ); + + if (flags & SUOI_FORCEDELETE) + return DeleteFileW(target); + + FIXME("not deleting %s\n", debugstr_w(target)); + + return TRUE; +} + +/*********************************************************************** + * SetupUninstallOEMInfA (SETUPAPI.@) + */ +BOOL WINAPI SetupUninstallOEMInfA( PCSTR inf_file, DWORD flags, PVOID reserved ) +{ + BOOL ret; + WCHAR *inf_fileW = NULL; + + TRACE("%s, 0x%08x, %p\n", debugstr_a(inf_file), flags, reserved); + + if (inf_file && !(inf_fileW = strdupAtoW( inf_file ))) return FALSE; + ret = SetupUninstallOEMInfW( inf_fileW, flags, reserved ); + HeapFree( GetProcessHeap(), 0, inf_fileW ); + return ret; +} + /*********************************************************************** * InstallCatalog (SETUPAPI.@) */ diff --git a/reactos/dll/win32/setupapi/setupapi.spec b/reactos/dll/win32/setupapi/setupapi.spec index e61aa873b41..c98d49b8102 100644 --- a/reactos/dll/win32/setupapi/setupapi.spec +++ b/reactos/dll/win32/setupapi/setupapi.spec @@ -100,8 +100,8 @@ @ stub CM_Get_Device_Interface_List_ExW @ stub CM_Get_Device_Interface_List_SizeA @ stub CM_Get_Device_Interface_List_SizeW -@ stub CM_Get_Device_Interface_List_Size_ExA -@ stub CM_Get_Device_Interface_List_Size_ExW +@ stdcall CM_Get_Device_Interface_List_Size_ExA(ptr ptr str long ptr) +@ stdcall CM_Get_Device_Interface_List_Size_ExW(ptr ptr wstr long ptr) @ stdcall CM_Get_First_Log_Conf(ptr long long) @ stdcall CM_Get_First_Log_Conf_Ex(ptr long long long) @ stdcall CM_Get_Global_State(ptr long) @@ -528,8 +528,8 @@ @ stdcall SetupTermDefaultQueueCallback(ptr) @ stdcall SetupTerminateFileLog(long) @ stub SetupUninstallNewlyCopiedInfs -@ stub SetupUninstallOEMInfA -@ stub SetupUninstallOEMInfW +@ stdcall SetupUninstallOEMInfA(str long ptr) +@ stdcall SetupUninstallOEMInfW(wstr long ptr) @ stub SetupVerifyInfFileA @ stub SetupVerifyInfFileW @ stdcall UnicodeToMultiByte(wstr long) diff --git a/reactos/dll/win32/setupapi/stubs.c b/reactos/dll/win32/setupapi/stubs.c index 0d13e76003e..f7d0711c4cc 100644 --- a/reactos/dll/win32/setupapi/stubs.c +++ b/reactos/dll/win32/setupapi/stubs.c @@ -213,3 +213,23 @@ CMP_UnregisterNotification(IN HDEVNOTIFY handle) FIXME ("Stub %p\n", handle); return CR_SUCCESS; } + +/*********************************************************************** + * CM_Get_Device_Interface_List_Size_ExA (SETUPAPI.@) + */ +CONFIGRET WINAPI CM_Get_Device_Interface_List_Size_ExA(PULONG len, LPGUID class, DEVINSTID_A id, + ULONG flags, HMACHINE machine) +{ + FIXME("%p %p %s 0x%08x %p: stub\n", len, class, debugstr_a(id), flags, machine); + return CR_FAILURE; +} + +/*********************************************************************** + * CM_Get_Device_Interface_List_Size_ExW (SETUPAPI.@) + */ +CONFIGRET WINAPI CM_Get_Device_Interface_List_Size_ExW(PULONG len, LPGUID class, DEVINSTID_W id, + ULONG flags, HMACHINE machine) +{ + FIXME("%p %p %s 0x%08x %p: stub\n", len, class, debugstr_w(id), flags, machine); + return CR_FAILURE; +} diff --git a/reactos/dll/win32/shell32/pidl.c b/reactos/dll/win32/shell32/pidl.c index e923b941de5..3da70ca3961 100644 --- a/reactos/dll/win32/shell32/pidl.c +++ b/reactos/dll/win32/shell32/pidl.c @@ -2392,10 +2392,3 @@ LPITEMIDLIST* _ILCopyCidaToaPidl(LPITEMIDLIST* pidl, const CIDA * cida) return dst; } - -HRESULT WINAPI SHCreateShellItem(LPCITEMIDLIST pidlParent, - IShellFolder *psfParent, LPCITEMIDLIST pidl, void **ppsi) -{ - FIXME("STUB: %p %p %p %p\n",pidlParent, psfParent, pidl, ppsi); - return E_NOINTERFACE; -} diff --git a/reactos/dll/win32/shell32/shell32.rbuild b/reactos/dll/win32/shell32/shell32.rbuild index 0c3c558bb59..2f91a1d63a3 100644 --- a/reactos/dll/win32/shell32/shell32.rbuild +++ b/reactos/dll/win32/shell32/shell32.rbuild @@ -1,3 +1,4 @@ + @@ -44,6 +45,7 @@ pidl.c regsvr.c shell32_main.c + shellitem.c shelllink.c shellole.c shellord.c @@ -78,3 +80,7 @@ folder_options.c shell32.rc + + shobjidl_local.idl + + diff --git a/reactos/dll/win32/shell32/shell32_main.h b/reactos/dll/win32/shell32/shell32_main.h index 9e43b9a45bf..3a262237a8a 100644 --- a/reactos/dll/win32/shell32/shell32_main.h +++ b/reactos/dll/win32/shell32/shell32_main.h @@ -91,6 +91,7 @@ IContextMenu2 * ISvBgCm_Constructor(LPSHELLFOLDER pSFParent, BOOL bDesktop); LPSHELLVIEW IShellView_Constructor(LPSHELLFOLDER); HRESULT WINAPI IFSFolder_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv); +HRESULT WINAPI IShellItem_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv); HRESULT WINAPI IShellLink_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv); HRESULT WINAPI IShellLink_ConstructFromFile(IUnknown * pUnkOuter, REFIID riid, LPCITEMIDLIST pidl, LPVOID * ppv); HRESULT WINAPI ISF_Desktop_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv); diff --git a/reactos/dll/win32/shell32/shellitem.c b/reactos/dll/win32/shell32/shellitem.c new file mode 100644 index 00000000000..613455011a7 --- /dev/null +++ b/reactos/dll/win32/shell32/shellitem.c @@ -0,0 +1,382 @@ +/* + * IShellItem implementation + * + * Copyright 2008 Vincent Povirk for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "precomp.h" + +WINE_DEFAULT_DEBUG_CHANNEL(shell); + +typedef struct _ShellItem { + const IShellItemVtbl *lpIShellItemVtbl; + LONG ref; + LPITEMIDLIST pidl; + const IPersistIDListVtbl *lpIPersistIDListVtbl; +} ShellItem; + +HRESULT WINAPI SHCreateShellItem(LPCITEMIDLIST pidlParent, + IShellFolder *psfParent, LPCITEMIDLIST pidl, IShellItem **ppsi); + + +static inline ShellItem *impl_from_IPersistIDList( IPersistIDList *iface ) +{ + return (ShellItem*)((char*)iface - FIELD_OFFSET(ShellItem, lpIPersistIDListVtbl)); +} + + +static HRESULT WINAPI ShellItem_QueryInterface(IShellItem *iface, REFIID riid, + void **ppv) +{ + ShellItem *This = (ShellItem*)iface; + + TRACE("(%p,%p,%p)\n", iface, riid, ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, riid) || IsEqualIID(&IID_IShellItem, riid)) + { + *ppv = This; + } + else if (IsEqualIID(&IID_IPersist, riid) || IsEqualIID(&IID_IPersistIDList, riid)) + { + *ppv = &(This->lpIPersistIDListVtbl); + } + else { + FIXME("not implemented for %s\n", shdebugstr_guid(riid)); + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI ShellItem_AddRef(IShellItem *iface) +{ + ShellItem *This = (ShellItem*)iface; + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p), new refcount=%i\n", iface, ref); + + return ref; +} + +static ULONG WINAPI ShellItem_Release(IShellItem *iface) +{ + ShellItem *This = (ShellItem*)iface; + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p), new refcount=%i\n", iface, ref); + + if (ref == 0) + { + ILFree(This->pidl); + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +static HRESULT ShellItem_get_parent_pidl(ShellItem *This, LPITEMIDLIST *parent_pidl) +{ + *parent_pidl = ILClone(This->pidl); + if (*parent_pidl) + { + if (ILRemoveLastID(*parent_pidl)) + return S_OK; + else + { + ILFree(*parent_pidl); + *parent_pidl = NULL; + return E_INVALIDARG; + } + } + else + { + *parent_pidl = NULL; + return E_OUTOFMEMORY; + } +} + +static HRESULT ShellItem_get_parent_shellfolder(ShellItem *This, IShellFolder **ppsf) +{ + LPITEMIDLIST parent_pidl; + IShellFolder *desktop; + HRESULT ret; + + ret = ShellItem_get_parent_pidl(This, &parent_pidl); + if (SUCCEEDED(ret)) + { + ret = SHGetDesktopFolder(&desktop); + if (SUCCEEDED(ret)) + { + ret = IShellFolder_BindToObject(desktop, parent_pidl, NULL, &IID_IShellFolder, (void**)ppsf); + IShellFolder_Release(desktop); + } + ILFree(parent_pidl); + } + + return ret; +} + +static HRESULT WINAPI ShellItem_BindToHandler(IShellItem *iface, IBindCtx *pbc, + REFGUID rbhid, REFIID riid, void **ppvOut) +{ + FIXME("(%p,%p,%s,%p,%p)\n", iface, pbc, shdebugstr_guid(rbhid), riid, ppvOut); + + *ppvOut = NULL; + + return E_NOTIMPL; +} + +static HRESULT WINAPI ShellItem_GetParent(IShellItem *iface, IShellItem **ppsi) +{ + ShellItem *This = (ShellItem*)iface; + LPITEMIDLIST parent_pidl; + HRESULT ret; + + TRACE("(%p,%p)\n", iface, ppsi); + + ret = ShellItem_get_parent_pidl(This, &parent_pidl); + if (SUCCEEDED(ret)) + { + ret = SHCreateShellItem(NULL, NULL, parent_pidl, ppsi); + ILFree(parent_pidl); + } + + return ret; +} + +static HRESULT WINAPI ShellItem_GetDisplayName(IShellItem *iface, SIGDN sigdnName, + LPWSTR *ppszName) +{ + FIXME("(%p,%x,%p)\n", iface, sigdnName, ppszName); + + *ppszName = NULL; + + return E_NOTIMPL; +} + +static HRESULT WINAPI ShellItem_GetAttributes(IShellItem *iface, SFGAOF sfgaoMask, + SFGAOF *psfgaoAttribs) +{ + ShellItem *This = (ShellItem*)iface; + IShellFolder *parent_folder; + LPITEMIDLIST child_pidl; + HRESULT ret; + + TRACE("(%p,%x,%p)\n", iface, sfgaoMask, psfgaoAttribs); + + ret = ShellItem_get_parent_shellfolder(This, &parent_folder); + if (SUCCEEDED(ret)) + { + child_pidl = ILFindLastID(This->pidl); + *psfgaoAttribs = sfgaoMask; + ret = IShellFolder_GetAttributesOf(parent_folder, 1, (LPCITEMIDLIST*)&child_pidl, psfgaoAttribs); + IShellFolder_Release(parent_folder); + } + + return ret; +} + +static HRESULT WINAPI ShellItem_Compare(IShellItem *iface, IShellItem *oth, + SICHINTF hint, int *piOrder) +{ + FIXME("(%p,%p,%x,%p)\n", iface, oth, hint, piOrder); + + return E_NOTIMPL; +} + +static const IShellItemVtbl ShellItem_Vtbl = { + ShellItem_QueryInterface, + ShellItem_AddRef, + ShellItem_Release, + ShellItem_BindToHandler, + ShellItem_GetParent, + ShellItem_GetDisplayName, + ShellItem_GetAttributes, + ShellItem_Compare +}; + + +static HRESULT ShellItem_GetClassID(ShellItem* This, CLSID *pClassID) +{ + TRACE("(%p,%p)\n", This, pClassID); + + *pClassID = CLSID_ShellItem; + return S_OK; +} + + +static HRESULT WINAPI ShellItem_IPersistIDList_QueryInterface(IPersistIDList *iface, + REFIID riid, void **ppv) +{ + ShellItem *This = impl_from_IPersistIDList(iface); + return ShellItem_QueryInterface((IShellItem*)This, riid, ppv); +} + +static ULONG WINAPI ShellItem_IPersistIDList_AddRef(IPersistIDList *iface) +{ + ShellItem *This = impl_from_IPersistIDList(iface); + return ShellItem_AddRef((IShellItem*)This); +} + +static ULONG WINAPI ShellItem_IPersistIDList_Release(IPersistIDList *iface) +{ + ShellItem *This = impl_from_IPersistIDList(iface); + return ShellItem_Release((IShellItem*)This); +} + +static HRESULT WINAPI ShellItem_IPersistIDList_GetClassID(IPersistIDList* iface, + CLSID *pClassID) +{ + ShellItem *This = impl_from_IPersistIDList(iface); + + return ShellItem_GetClassID(This, pClassID); +} + +static HRESULT WINAPI ShellItem_IPersistIDList_SetIDList(IPersistIDList* iface, + LPCITEMIDLIST pidl) +{ + ShellItem *This = impl_from_IPersistIDList(iface); + LPITEMIDLIST new_pidl; + + TRACE("(%p,%p)\n", This, pidl); + + new_pidl = ILClone(pidl); + + if (new_pidl) + { + ILFree(This->pidl); + This->pidl = new_pidl; + return S_OK; + } + else + return E_OUTOFMEMORY; +} + +static HRESULT WINAPI ShellItem_IPersistIDList_GetIDList(IPersistIDList* iface, + LPITEMIDLIST *ppidl) +{ + ShellItem *This = impl_from_IPersistIDList(iface); + + TRACE("(%p,%p)\n", This, ppidl); + + *ppidl = ILClone(This->pidl); + if (*ppidl) + return S_OK; + else + return E_OUTOFMEMORY; +} + +static const IPersistIDListVtbl ShellItem_IPersistIDList_Vtbl = { + ShellItem_IPersistIDList_QueryInterface, + ShellItem_IPersistIDList_AddRef, + ShellItem_IPersistIDList_Release, + ShellItem_IPersistIDList_GetClassID, + ShellItem_IPersistIDList_SetIDList, + ShellItem_IPersistIDList_GetIDList +}; + + +HRESULT WINAPI IShellItem_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv) +{ + ShellItem *This; + HRESULT ret; + + TRACE("(%p,%s)\n",pUnkOuter, debugstr_guid(riid)); + + *ppv = NULL; + + if (pUnkOuter) return CLASS_E_NOAGGREGATION; + + This = HeapAlloc(GetProcessHeap(), 0, sizeof(ShellItem)); + This->lpIShellItemVtbl = &ShellItem_Vtbl; + This->ref = 1; + This->pidl = NULL; + This->lpIPersistIDListVtbl = &ShellItem_IPersistIDList_Vtbl; + + ret = ShellItem_QueryInterface((IShellItem*)This, riid, ppv); + ShellItem_Release((IShellItem*)This); + + return ret; +} + +HRESULT WINAPI SHCreateShellItem(LPCITEMIDLIST pidlParent, + IShellFolder *psfParent, LPCITEMIDLIST pidl, IShellItem **ppsi) +{ + ShellItem *This; + LPITEMIDLIST new_pidl; + HRESULT ret; + + TRACE("(%p,%p,%p,%p)\n", pidlParent, psfParent, pidl, ppsi); + + if (!pidl) + { + return E_INVALIDARG; + } + else if (pidlParent || psfParent) + { + LPITEMIDLIST temp_parent=NULL; + if (!pidlParent) + { + IPersistFolder2* ppf2Parent; + + if (!SUCCEEDED(IPersistFolder2_QueryInterface(psfParent, &IID_IPersistFolder2, (void**)&ppf2Parent))) + { + FIXME("couldn't get IPersistFolder2 interface of parent\n"); + return E_NOINTERFACE; + } + + if (!SUCCEEDED(IPersistFolder2_GetCurFolder(ppf2Parent, &temp_parent))) + { + FIXME("couldn't get parent PIDL\n"); + IPersistFolder2_Release(ppf2Parent); + return E_NOINTERFACE; + } + + pidlParent = temp_parent; + IPersistFolder2_Release(ppf2Parent); + } + + new_pidl = ILCombine(pidlParent, pidl); + ILFree(temp_parent); + + if (!new_pidl) + return E_OUTOFMEMORY; + } + else + { + new_pidl = ILClone(pidl); + if (!new_pidl) + return E_OUTOFMEMORY; + } + + ret = IShellItem_Constructor(NULL, &IID_IShellItem, (void**)&This); + if (This) + { + *ppsi = (IShellItem*)This; + This->pidl = new_pidl; + } + else + { + *ppsi = NULL; + ILFree(new_pidl); + } + return ret; +} diff --git a/reactos/dll/win32/shell32/shellole.c b/reactos/dll/win32/shell32/shellole.c index 06894a4be70..892d15b3500 100644 --- a/reactos/dll/win32/shell32/shellole.c +++ b/reactos/dll/win32/shell32/shellole.c @@ -42,6 +42,7 @@ static const struct { {&CLSID_ShellFSFolder, &IFSFolder_Constructor}, {&CLSID_MyComputer, &ISF_MyComputer_Constructor}, {&CLSID_ShellDesktop, &ISF_Desktop_Constructor}, + {&CLSID_ShellItem, &IShellItem_Constructor}, {&CLSID_ShellLink, &IShellLink_Constructor}, {&CLSID_DragDropHelper, &IDropTargetHelper_Constructor}, {&CLSID_ControlPanel, &IControlPanel_Constructor}, diff --git a/reactos/dll/win32/shell32/shobjidl_local.idl b/reactos/dll/win32/shell32/shobjidl_local.idl new file mode 100644 index 00000000000..1f90784d861 --- /dev/null +++ b/reactos/dll/win32/shell32/shobjidl_local.idl @@ -0,0 +1,2 @@ + +#include "shobjidl.idl"