2 * COM proxy/stub factory (CStdPSFactory) implementation
4 * Copyright 2001 Ove Kåven, TransGaming Technologies
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
39 static BOOL
FindProxyInfo(const ProxyFileInfo
**pProxyFileList
, REFIID riid
, const ProxyFileInfo
**pProxyInfo
, int *pIndex
)
41 while (*pProxyFileList
) {
42 if ((*pProxyFileList
)->pIIDLookupRtn(riid
, pIndex
)) {
43 *pProxyInfo
= *pProxyFileList
;
44 TRACE("found: ProxyInfo %p Index %d\n", *pProxyInfo
, *pIndex
);
53 static HRESULT WINAPI
CStdPSFactory_QueryInterface(LPPSFACTORYBUFFER iface
,
57 ICOM_THIS(CStdPSFactoryBuffer
,iface
);
58 TRACE("(%p)->QueryInterface(%s,%p)\n",iface
,debugstr_guid(riid
),obj
);
59 if (IsEqualGUID(&IID_IUnknown
,riid
) ||
60 IsEqualGUID(&IID_IPSFactoryBuffer
,riid
)) {
68 static ULONG WINAPI
CStdPSFactory_AddRef(LPPSFACTORYBUFFER iface
)
70 ICOM_THIS(CStdPSFactoryBuffer
,iface
);
71 TRACE("(%p)->AddRef()\n",iface
);
72 return ++(This
->RefCount
);
75 static ULONG WINAPI
CStdPSFactory_Release(LPPSFACTORYBUFFER iface
)
77 ICOM_THIS(CStdPSFactoryBuffer
,iface
);
78 TRACE("(%p)->Release()\n",iface
);
79 return --(This
->RefCount
);
82 static HRESULT WINAPI
CStdPSFactory_CreateProxy(LPPSFACTORYBUFFER iface
,
85 LPRPCPROXYBUFFER
*ppProxy
,
88 ICOM_THIS(CStdPSFactoryBuffer
,iface
);
89 const ProxyFileInfo
*ProxyInfo
;
91 TRACE("(%p)->CreateProxy(%p,%s,%p,%p)\n",iface
,pUnkOuter
,
92 debugstr_guid(riid
),ppProxy
,ppv
);
93 if (!FindProxyInfo(This
->pProxyFileList
,riid
,&ProxyInfo
,&Index
))
95 return StdProxy_Construct(riid
, pUnkOuter
, ProxyInfo
->pProxyVtblList
[Index
],
96 ProxyInfo
->pStubVtblList
[Index
], iface
, ppProxy
, ppv
);
99 static HRESULT WINAPI
CStdPSFactory_CreateStub(LPPSFACTORYBUFFER iface
,
101 LPUNKNOWN pUnkServer
,
102 LPRPCSTUBBUFFER
*ppStub
)
104 ICOM_THIS(CStdPSFactoryBuffer
,iface
);
105 const ProxyFileInfo
*ProxyInfo
;
107 TRACE("(%p)->CreateStub(%s,%p,%p)\n",iface
,debugstr_guid(riid
),
109 if (!FindProxyInfo(This
->pProxyFileList
,riid
,&ProxyInfo
,&Index
))
110 return E_NOINTERFACE
;
111 return CStdStubBuffer_Construct(riid
, pUnkServer
, ProxyInfo
->pStubVtblList
[Index
], iface
, ppStub
);
114 static ICOM_VTABLE(IPSFactoryBuffer
) CStdPSFactory_Vtbl
=
116 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
117 CStdPSFactory_QueryInterface
,
118 CStdPSFactory_AddRef
,
119 CStdPSFactory_Release
,
120 CStdPSFactory_CreateProxy
,
121 CStdPSFactory_CreateStub
124 /***********************************************************************
125 * NdrDllGetClassObject [RPCRT4.@]
127 HRESULT WINAPI
NdrDllGetClassObject(REFCLSID rclsid
, REFIID iid
, LPVOID
*ppv
,
128 const ProxyFileInfo
**pProxyFileList
,
130 CStdPSFactoryBuffer
*pPSFactoryBuffer
)
133 if (!pPSFactoryBuffer
->lpVtbl
) {
134 pPSFactoryBuffer
->lpVtbl
= &CStdPSFactory_Vtbl
;
135 pPSFactoryBuffer
->RefCount
= 0;
136 pPSFactoryBuffer
->pProxyFileList
= pProxyFileList
;
138 if (IsEqualGUID(rclsid
, pclsid
))
139 return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER
)pPSFactoryBuffer
, iid
, ppv
);
140 return CLASS_E_CLASSNOTAVAILABLE
;
143 /***********************************************************************
144 * NdrDllCanUnloadNow [RPCRT4.@]
146 HRESULT WINAPI
NdrDllCanUnloadNow(CStdPSFactoryBuffer
*pPSFactoryBuffer
)
148 return !(pPSFactoryBuffer
->RefCount
);
151 /***********************************************************************
152 * NdrDllRegisterProxy [RPCRT4.@]
154 HRESULT WINAPI
NdrDllRegisterProxy(HMODULE hDll
,
155 const ProxyFileInfo
**pProxyFileList
,
159 char keyname
[120], module
[120];
162 TRACE("(%p,%p,%s)\n", hDll
, pProxyFileList
, debugstr_guid(pclsid
));
163 UuidToStringA((UUID
*)pclsid
, (unsigned char**)&clsid
);
165 /* register interfaces to point to clsid */
166 while (*pProxyFileList
) {
168 for (u
=0; u
<(*pProxyFileList
)->TableSize
; u
++) {
169 CInterfaceStubVtbl
*proxy
= (*pProxyFileList
)->pStubVtblList
[u
];
170 PCInterfaceName name
= (*pProxyFileList
)->pNamesArray
[u
];
173 TRACE("registering %s %s => %s\n", name
, debugstr_guid(proxy
->header
.piid
), clsid
);
175 UuidToStringA((UUID
*)proxy
->header
.piid
, (unsigned char**)&iid
);
176 snprintf(keyname
, sizeof(keyname
), "Interface\\%s", iid
);
177 RpcStringFreeA((unsigned char**)&iid
);
178 if (RegCreateKeyExA(HKEY_CLASSES_ROOT
, keyname
, 0, NULL
, 0,
179 KEY_WRITE
, NULL
, &key
, NULL
) == ERROR_SUCCESS
) {
181 RegSetValueExA(key
, NULL
, 0, REG_SZ
, name
, strlen(name
));
182 if (RegCreateKeyExA(key
, "ProxyStubClsid32", 0, NULL
, 0,
183 KEY_WRITE
, NULL
, &subkey
, NULL
) == ERROR_SUCCESS
) {
184 RegSetValueExA(subkey
, NULL
, 0, REG_SZ
, clsid
, strlen(clsid
));
193 /* register clsid to point to module */
194 snprintf(keyname
, sizeof(keyname
), "CLSID\\%s", clsid
);
195 GetModuleFileNameA(hDll
, module
, sizeof(module
));
196 TRACE("registering CLSID %s => %s\n", clsid
, module
);
197 if (RegCreateKeyExA(HKEY_CLASSES_ROOT
, keyname
, 0, NULL
, 0,
198 KEY_WRITE
, NULL
, &key
, NULL
) == ERROR_SUCCESS
) {
199 if (RegCreateKeyExA(key
, "InProcServer32", 0, NULL
, 0,
200 KEY_WRITE
, NULL
, &subkey
, NULL
) == ERROR_SUCCESS
) {
201 RegSetValueExA(subkey
, NULL
, 0, REG_SZ
, module
, strlen(module
));
208 RpcStringFreeA((unsigned char**)&clsid
);
212 /***********************************************************************
213 * NdrDllUnregisterProxy [RPCRT4.@]
215 HRESULT WINAPI
NdrDllUnregisterProxy(HMODULE hDll
,
216 const ProxyFileInfo
**pProxyFileList
,
220 char keyname
[120], module
[120];
222 TRACE("(%p,%p,%s)\n", hDll
, pProxyFileList
, debugstr_guid(pclsid
));
223 UuidToStringA((UUID
*)pclsid
, (unsigned char**)&clsid
);
225 /* unregister interfaces */
226 while (*pProxyFileList
) {
228 for (u
=0; u
<(*pProxyFileList
)->TableSize
; u
++) {
229 CInterfaceStubVtbl
*proxy
= (*pProxyFileList
)->pStubVtblList
[u
];
230 PCInterfaceName name
= (*pProxyFileList
)->pNamesArray
[u
];
233 TRACE("unregistering %s %s <= %s\n", name
, debugstr_guid(proxy
->header
.piid
), clsid
);
235 UuidToStringA((UUID
*)proxy
->header
.piid
, (unsigned char**)&iid
);
236 snprintf(keyname
, sizeof(keyname
), "Interface\\%s", iid
);
237 RpcStringFreeA((unsigned char**)&iid
);
238 RegDeleteKeyA(HKEY_CLASSES_ROOT
, keyname
);
243 /* unregister clsid */
244 snprintf(keyname
, sizeof(keyname
), "CLSID\\%s", clsid
);
245 GetModuleFileNameA(hDll
, module
, sizeof(module
));
246 TRACE("unregistering CLSID %s <= %s\n", clsid
, module
);
247 RegDeleteKeyA(HKEY_CLASSES_ROOT
, keyname
);
250 RpcStringFreeA((unsigned char**)&clsid
);