Implemented Rtl*ByteSwap() functions, based on a patch by Jon
[wine/multimedia.git] / dlls / rpcrt4 / cpsf.c
blob8ea44e419ccd7751207e2e6af9b4fe2c530bf495
1 /*
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
21 #include <stdio.h>
22 #include <string.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winerror.h"
27 #include "winreg.h"
29 #include "objbase.h"
31 #include "rpcproxy.h"
33 #include "wine/debug.h"
35 #include "cpsf.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);
45 return TRUE;
47 pProxyFileList++;
49 TRACE("not found\n");
50 return FALSE;
53 static HRESULT WINAPI CStdPSFactory_QueryInterface(LPPSFACTORYBUFFER iface,
54 REFIID riid,
55 LPVOID *obj)
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)) {
61 *obj = This;
62 This->RefCount++;
63 return S_OK;
65 return E_NOINTERFACE;
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,
83 LPUNKNOWN pUnkOuter,
84 REFIID riid,
85 LPRPCPROXYBUFFER *ppProxy,
86 LPVOID *ppv)
88 ICOM_THIS(CStdPSFactoryBuffer,iface);
89 const ProxyFileInfo *ProxyInfo;
90 int Index;
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))
94 return E_NOINTERFACE;
95 return StdProxy_Construct(riid, pUnkOuter, ProxyInfo->pProxyVtblList[Index],
96 ProxyInfo->pStubVtblList[Index], iface, ppProxy, ppv);
99 static HRESULT WINAPI CStdPSFactory_CreateStub(LPPSFACTORYBUFFER iface,
100 REFIID riid,
101 LPUNKNOWN pUnkServer,
102 LPRPCSTUBBUFFER *ppStub)
104 ICOM_THIS(CStdPSFactoryBuffer,iface);
105 const ProxyFileInfo *ProxyInfo;
106 int Index;
107 TRACE("(%p)->CreateStub(%s,%p,%p)\n",iface,debugstr_guid(riid),
108 pUnkServer,ppStub);
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,
129 const CLSID *pclsid,
130 CStdPSFactoryBuffer *pPSFactoryBuffer)
132 *ppv = NULL;
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,
156 const CLSID *pclsid)
158 LPSTR clsid;
159 char keyname[120], module[120];
160 HKEY key, subkey;
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) {
167 unsigned u;
168 for (u=0; u<(*pProxyFileList)->TableSize; u++) {
169 CInterfaceStubVtbl *proxy = (*pProxyFileList)->pStubVtblList[u];
170 PCInterfaceName name = (*pProxyFileList)->pNamesArray[u];
171 LPSTR iid;
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) {
180 if (name)
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));
185 RegCloseKey(subkey);
187 RegCloseKey(key);
190 pProxyFileList++;
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));
202 RegCloseKey(subkey);
204 RegCloseKey(key);
207 /* done */
208 RpcStringFreeA((unsigned char**)&clsid);
209 return S_OK;
212 /***********************************************************************
213 * NdrDllUnregisterProxy [RPCRT4.@]
215 HRESULT WINAPI NdrDllUnregisterProxy(HMODULE hDll,
216 const ProxyFileInfo **pProxyFileList,
217 const CLSID *pclsid)
219 LPSTR clsid;
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) {
227 unsigned u;
228 for (u=0; u<(*pProxyFileList)->TableSize; u++) {
229 CInterfaceStubVtbl *proxy = (*pProxyFileList)->pStubVtblList[u];
230 PCInterfaceName name = (*pProxyFileList)->pNamesArray[u];
231 LPSTR iid;
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);
240 pProxyFileList++;
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);
249 /* done */
250 RpcStringFreeA((unsigned char**)&clsid);
251 return S_OK;