From 66840f7d11890a3073e0da2903828405cbe1de14 Mon Sep 17 00:00:00 2001 From: Ove Kaaven Date: Thu, 10 Oct 2002 23:36:52 +0000 Subject: [PATCH] Added NdrDllCanUnloadNow, NdrDllGetClassObject, NdrDllRegisterProxy, NdrDllUnregisterProxy, CStdPSFactory methods. --- dlls/Makefile.in | 2 +- dlls/rpcrt4/Makefile.in | 3 +- dlls/rpcrt4/cpsf.c | 253 ++++++++++++++++++++++++++++++++++++++ dlls/rpcrt4/rpcrt4.spec | 10 +- dlls/rpcrt4/rpcrt4_main.c | 36 ------ 5 files changed, 261 insertions(+), 43 deletions(-) create mode 100644 dlls/rpcrt4/cpsf.c diff --git a/dlls/Makefile.in b/dlls/Makefile.in index 1d675566f2d..c32e2bd8996 100644 --- a/dlls/Makefile.in +++ b/dlls/Makefile.in @@ -821,7 +821,7 @@ qcap: kernel32.dll$(DLLEXT) quartz: kernel32.dll$(DLLEXT) rasapi32: kernel32.dll$(DLLEXT) richedit: user32.dll$(DLLEXT) kernel32.dll$(DLLEXT) -rpcrt4: kernel32.dll$(DLLEXT) +rpcrt4: advapi32.dll$(DLLEXT) kernel32.dll$(DLLEXT) serialui: user32.dll$(DLLEXT) advapi32.dll$(DLLEXT) kernel32.dll$(DLLEXT) setupapi: user32.dll$(DLLEXT) advapi32.dll$(DLLEXT) kernel32.dll$(DLLEXT) ntdll.dll$(DLLEXT) shdocvw: ole32.dll$(DLLEXT) kernel32.dll$(DLLEXT) diff --git a/dlls/rpcrt4/Makefile.in b/dlls/rpcrt4/Makefile.in index 6ea1808b634..8dc57978024 100644 --- a/dlls/rpcrt4/Makefile.in +++ b/dlls/rpcrt4/Makefile.in @@ -4,7 +4,7 @@ TOPOBJDIR = ../.. SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = rpcrt4.dll -IMPORTS = kernel32 +IMPORTS = advapi32 kernel32 EXTRALIBS = $(LIBUUID) LDDLLFLAGS = @LDDLLFLAGS@ @@ -12,6 +12,7 @@ SYMBOLFILE = $(MODULE).tmp.o C_SRCS = \ cproxy.c \ + cpsf.c \ cstub.c \ ndr_midl.c \ ndr_stubless.c \ diff --git a/dlls/rpcrt4/cpsf.c b/dlls/rpcrt4/cpsf.c new file mode 100644 index 00000000000..321a93bdcd9 --- /dev/null +++ b/dlls/rpcrt4/cpsf.c @@ -0,0 +1,253 @@ +/* + * COM proxy/stub factory (CStdPSFactory) implementation + * + * Copyright 2001 Ove Kåven, TransGaming Technologies + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winreg.h" + +#include "wine/obj_base.h" +#include "wine/obj_channel.h" + +#include "rpcproxy.h" + +#include "wine/debug.h" + +#include "cpsf.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +static BOOL FindProxyInfo(const ProxyFileInfo **pProxyFileList, REFIID riid, const ProxyFileInfo **pProxyInfo, int *pIndex) +{ + while (*pProxyFileList) { + if ((*pProxyFileList)->pIIDLookupRtn(riid, pIndex)) { + *pProxyInfo = *pProxyFileList; + TRACE("found: ProxyInfo %p Index %d\n", *pProxyInfo, *pIndex); + return TRUE; + } + pProxyFileList++; + } + TRACE("not found\n"); + return FALSE; +} + +static HRESULT WINAPI CStdPSFactory_QueryInterface(LPPSFACTORYBUFFER iface, + REFIID riid, + LPVOID *obj) +{ + ICOM_THIS(CStdPSFactoryBuffer,iface); + TRACE("(%p)->QueryInterface(%s,%p)\n",iface,debugstr_guid(riid),obj); + if (IsEqualGUID(&IID_IUnknown,riid) || + IsEqualGUID(&IID_IPSFactoryBuffer,riid)) { + *obj = This; + This->RefCount++; + return S_OK; + } + return E_NOINTERFACE; +} + +static ULONG WINAPI CStdPSFactory_AddRef(LPPSFACTORYBUFFER iface) +{ + ICOM_THIS(CStdPSFactoryBuffer,iface); + TRACE("(%p)->AddRef()\n",iface); + return ++(This->RefCount); +} + +static ULONG WINAPI CStdPSFactory_Release(LPPSFACTORYBUFFER iface) +{ + ICOM_THIS(CStdPSFactoryBuffer,iface); + TRACE("(%p)->Release()\n",iface); + return --(This->RefCount); +} + +static HRESULT WINAPI CStdPSFactory_CreateProxy(LPPSFACTORYBUFFER iface, + LPUNKNOWN pUnkOuter, + REFIID riid, + LPRPCPROXYBUFFER *ppProxy, + LPVOID *ppv) +{ + ICOM_THIS(CStdPSFactoryBuffer,iface); + const ProxyFileInfo *ProxyInfo; + int Index; + TRACE("(%p)->CreateProxy(%p,%s,%p,%p)\n",iface,pUnkOuter, + debugstr_guid(riid),ppProxy,ppv); + if (!FindProxyInfo(This->pProxyFileList,riid,&ProxyInfo,&Index)) + return E_NOINTERFACE; + return StdProxy_Construct(riid, pUnkOuter, ProxyInfo->pProxyVtblList[Index], + ProxyInfo->pStubVtblList[Index], iface, ppProxy, ppv); +} + +static HRESULT WINAPI CStdPSFactory_CreateStub(LPPSFACTORYBUFFER iface, + REFIID riid, + LPUNKNOWN pUnkServer, + LPRPCSTUBBUFFER *ppStub) +{ + ICOM_THIS(CStdPSFactoryBuffer,iface); + const ProxyFileInfo *ProxyInfo; + int Index; + TRACE("(%p)->CreateStub(%s,%p,%p)\n",iface,debugstr_guid(riid), + pUnkServer,ppStub); + if (!FindProxyInfo(This->pProxyFileList,riid,&ProxyInfo,&Index)) + return E_NOINTERFACE; + return CStdStubBuffer_Construct(riid, pUnkServer, ProxyInfo->pStubVtblList[Index], iface, ppStub); +} + +static ICOM_VTABLE(IPSFactoryBuffer) CStdPSFactory_Vtbl = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + CStdPSFactory_QueryInterface, + CStdPSFactory_AddRef, + CStdPSFactory_Release, + CStdPSFactory_CreateProxy, + CStdPSFactory_CreateStub +}; + +/*********************************************************************** + * NdrDllGetClassObject [RPCRT4.@] + */ +HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv, + const ProxyFileInfo **pProxyFileList, + const CLSID *pclsid, + CStdPSFactoryBuffer *pPSFactoryBuffer) +{ + *ppv = NULL; + if (!pPSFactoryBuffer->lpVtbl) { + pPSFactoryBuffer->lpVtbl = &CStdPSFactory_Vtbl; + pPSFactoryBuffer->RefCount = 0; + pPSFactoryBuffer->pProxyFileList = pProxyFileList; + } + if (IsEqualGUID(rclsid, pclsid)) + return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv); + return CLASS_E_CLASSNOTAVAILABLE; +} + +/*********************************************************************** + * NdrDllCanUnloadNow [RPCRT4.@] + */ +HRESULT WINAPI NdrDllCanUnloadNow(CStdPSFactoryBuffer *pPSFactoryBuffer) +{ + return !(pPSFactoryBuffer->RefCount); +} + +/*********************************************************************** + * NdrDllRegisterProxy [RPCRT4.@] + */ +HRESULT WINAPI NdrDllRegisterProxy(HMODULE hDll, + const ProxyFileInfo **pProxyFileList, + const CLSID *pclsid) +{ + LPSTR clsid; + char keyname[120], module[120]; + HKEY key, subkey; + + TRACE("(%x,%p,%s)\n", hDll, pProxyFileList, debugstr_guid(pclsid)); + UuidToStringA((UUID*)pclsid, &clsid); + + /* register interfaces to point to clsid */ + while (*pProxyFileList) { + unsigned u; + for (u=0; u<(*pProxyFileList)->TableSize; u++) { + CInterfaceProxyVtbl *proxy = (*pProxyFileList)->pProxyVtblList[u]; + PCInterfaceName name = (*pProxyFileList)->pNamesArray[u]; + LPSTR iid; + + TRACE("registering %s %s => %s\n", name, debugstr_guid(proxy->header.piid), clsid); + + UuidToStringA((UUID*)proxy->header.piid, &iid); + snprintf(keyname, sizeof(keyname), "Interface\\%s", iid); + RpcStringFreeA(&iid); + if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyname, 0, NULL, 0, + KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) { + if (name) + RegSetValueExA(key, NULL, 0, REG_SZ, name, strlen(name)); + if (RegCreateKeyExA(key, "ProxyStubClsid32", 0, NULL, 0, + KEY_WRITE, NULL, &subkey, NULL) == ERROR_SUCCESS) { + RegSetValueExA(subkey, NULL, 0, REG_SZ, clsid, strlen(clsid)); + RegCloseKey(subkey); + } + RegCloseKey(key); + } + } + pProxyFileList++; + } + + /* register clsid to point to module */ + snprintf(keyname, sizeof(keyname), "CLSID\\%s", clsid); + GetModuleFileNameA(hDll, module, sizeof(module)); + TRACE("registering %s => %s\n", clsid, module); + if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyname, 0, NULL, 0, + KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) { + if (RegCreateKeyExA(key, "InProcServer32", 0, NULL, 0, + KEY_WRITE, NULL, &subkey, NULL) == ERROR_SUCCESS) { + RegSetValueExA(subkey, NULL, 0, REG_SZ, module, strlen(module)); + RegCloseKey(subkey); + } + RegCloseKey(key); + } + + /* done */ + RpcStringFreeA(&clsid); + return S_OK; +} + +/*********************************************************************** + * NdrDllUnregisterProxy [RPCRT4.@] + */ +HRESULT WINAPI NdrDllUnregisterProxy(HMODULE hDll, + const ProxyFileInfo **pProxyFileList, + const CLSID *pclsid) +{ + LPSTR clsid; + char keyname[120], module[120]; + + TRACE("(%x,%p,%s)\n", hDll, pProxyFileList, debugstr_guid(pclsid)); + UuidToStringA((UUID*)pclsid, &clsid); + + /* unregister interfaces */ + while (*pProxyFileList) { + unsigned u; + for (u=0; u<(*pProxyFileList)->TableSize; u++) { + CInterfaceProxyVtbl *proxy = (*pProxyFileList)->pProxyVtblList[u]; + PCInterfaceName name = (*pProxyFileList)->pNamesArray[u]; + LPSTR iid; + + TRACE("unregistering %s %s <= %s\n", name, debugstr_guid(proxy->header.piid), clsid); + + UuidToStringA((UUID*)proxy->header.piid, &iid); + snprintf(keyname, sizeof(keyname), "Interface\\%s", iid); + RpcStringFreeA(&iid); + RegDeleteKeyA(HKEY_CLASSES_ROOT, keyname); + } + pProxyFileList++; + } + + /* unregister clsid */ + snprintf(keyname, sizeof(keyname), "CLSID\\%s", clsid); + GetModuleFileNameA(hDll, module, sizeof(module)); + TRACE("unregistering %s <= %s\n", clsid, module); + RegDeleteKeyA(HKEY_CLASSES_ROOT, keyname); + + /* done */ + RpcStringFreeA(&clsid); + return S_OK; +} diff --git a/dlls/rpcrt4/rpcrt4.spec b/dlls/rpcrt4/rpcrt4.spec index dad0d511817..ca749ce6305 100644 --- a/dlls/rpcrt4/rpcrt4.spec +++ b/dlls/rpcrt4/rpcrt4.spec @@ -17,11 +17,6 @@ init RPCRT4_LibMain @ stub MqGetContext # win9x @ stub MqRegisterQueue # win9x -@ stdcall NdrDllCanUnloadNow(ptr) NdrDllCanUnloadNow -@ stdcall NdrDllGetClassObject(ptr ptr ptr ptr ptr ptr) NdrDllGetClassObject -@ stdcall NdrDllRegisterProxy(long ptr ptr) NdrDllRegisterProxy -@ stub NdrDllUnregisterProxy - @ stub RpcAbortAsyncCall @ stub RpcAsyncAbortCall @ stub RpcAsyncCancelCall @@ -199,6 +194,11 @@ init RPCRT4_LibMain @ stdcall IUnknown_AddRef_Proxy(ptr) IUnknown_AddRef_Proxy @ stdcall IUnknown_Release_Proxy(ptr) IUnknown_Release_Proxy +@ stdcall NdrDllCanUnloadNow(ptr) NdrDllCanUnloadNow +@ stdcall NdrDllGetClassObject(ptr ptr ptr ptr ptr ptr) NdrDllGetClassObject +@ stdcall NdrDllRegisterProxy(long ptr ptr) NdrDllRegisterProxy +@ stdcall NdrDllUnregisterProxy(long ptr ptr) NdrDllUnregisterProxy + @ stub NdrAllocate @ stub NdrAsyncClientCall @ stub NdrAsyncServerCall diff --git a/dlls/rpcrt4/rpcrt4_main.c b/dlls/rpcrt4/rpcrt4_main.c index 89b15d44757..9977bebc988 100644 --- a/dlls/rpcrt4/rpcrt4_main.c +++ b/dlls/rpcrt4/rpcrt4_main.c @@ -590,19 +590,6 @@ RPC_STATUS WINAPI UuidFromStringW(LPWSTR s, UUID *uuid) return RPC_S_OK; } -/*********************************************************************** - * NdrDllRegisterProxy (RPCRT4.@) - */ -HRESULT WINAPI NdrDllRegisterProxy( - HMODULE hDll, /* [in] */ - const ProxyFileInfo **pProxyFileList, /* [in] */ - const CLSID *pclsid /* [in] */ -) -{ - FIXME("(%x,%p,%s), stub!\n",hDll,pProxyFileList,debugstr_guid(pclsid)); - return S_OK; -} - /*********************************************************************** * RpcServerUseProtseqEpA (RPCRT4.@) */ @@ -731,29 +718,6 @@ RPC_STATUS WINAPI RpcServerListen( UINT MinimumCallThreads, UINT MaxCalls, UINT return RPC_S_NO_PROTSEQS_REGISTERED; /* Since we don't allow registration this seems reasonable */ } -/*********************************************************************** - * NdrDllCanUnloadNow (RPCRT4.@) - */ -HRESULT WINAPI NdrDllCanUnloadNow(CStdPSFactoryBuffer *pPSFactoryBuffer) -{ - FIXME("%p\n",pPSFactoryBuffer); - return FALSE; -} - -/*********************************************************************** - * NdrDllGetClassObject (RPCRT4.@) - */ -HRESULT WINAPI NdrDllGetClassObject( - REFCLSID rclsid, REFIID riid , LPVOID *ppv, - const ProxyFileInfo ** pProxyFileList, - const CLSID * pclsid, - CStdPSFactoryBuffer * pPSFactoryBuffer) -{ - if(ppv) - *ppv = NULL; - return RPC_S_UNKNOWN_IF; -} - /*********************************************************************** * DllRegisterServer (RPCRT4.@) */