Keep track of per-column information inside the listview.
[wine] / dlls / rpcrt4 / cpsf.c
1 /*
2  * COM proxy/stub factory (CStdPSFactory) implementation
3  *
4  * Copyright 2001 Ove Kåven, TransGaming Technologies
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include <stdio.h>
22 #include <string.h>
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winerror.h"
27 #include "winreg.h"
28
29 #include "wine/obj_base.h"
30 #include "wine/obj_channel.h"
31
32 #include "rpcproxy.h"
33
34 #include "wine/debug.h"
35
36 #include "cpsf.h"
37
38 WINE_DEFAULT_DEBUG_CHANNEL(ole);
39
40 static BOOL FindProxyInfo(const ProxyFileInfo **pProxyFileList, REFIID riid, const ProxyFileInfo **pProxyInfo, int *pIndex)
41 {
42   while (*pProxyFileList) {
43     if ((*pProxyFileList)->pIIDLookupRtn(riid, pIndex)) {
44       *pProxyInfo = *pProxyFileList;
45       TRACE("found: ProxyInfo %p Index %d\n", *pProxyInfo, *pIndex);
46       return TRUE;
47     }
48     pProxyFileList++;
49   }
50   TRACE("not found\n");
51   return FALSE;
52 }
53
54 static HRESULT WINAPI CStdPSFactory_QueryInterface(LPPSFACTORYBUFFER iface,
55                                                   REFIID riid,
56                                                   LPVOID *obj)
57 {
58   ICOM_THIS(CStdPSFactoryBuffer,iface);
59   TRACE("(%p)->QueryInterface(%s,%p)\n",iface,debugstr_guid(riid),obj);
60   if (IsEqualGUID(&IID_IUnknown,riid) ||
61       IsEqualGUID(&IID_IPSFactoryBuffer,riid)) {
62     *obj = This;
63     This->RefCount++;
64     return S_OK;
65   }
66   return E_NOINTERFACE;
67 }
68
69 static ULONG WINAPI CStdPSFactory_AddRef(LPPSFACTORYBUFFER iface)
70 {
71   ICOM_THIS(CStdPSFactoryBuffer,iface);
72   TRACE("(%p)->AddRef()\n",iface);
73   return ++(This->RefCount);
74 }
75
76 static ULONG WINAPI CStdPSFactory_Release(LPPSFACTORYBUFFER iface)
77 {
78   ICOM_THIS(CStdPSFactoryBuffer,iface);
79   TRACE("(%p)->Release()\n",iface);
80   return --(This->RefCount);
81 }
82
83 static HRESULT WINAPI CStdPSFactory_CreateProxy(LPPSFACTORYBUFFER iface,
84                                                LPUNKNOWN pUnkOuter,
85                                                REFIID riid,
86                                                LPRPCPROXYBUFFER *ppProxy,
87                                                LPVOID *ppv)
88 {
89   ICOM_THIS(CStdPSFactoryBuffer,iface);
90   const ProxyFileInfo *ProxyInfo;
91   int Index;
92   TRACE("(%p)->CreateProxy(%p,%s,%p,%p)\n",iface,pUnkOuter,
93        debugstr_guid(riid),ppProxy,ppv);
94   if (!FindProxyInfo(This->pProxyFileList,riid,&ProxyInfo,&Index))
95     return E_NOINTERFACE;
96   return StdProxy_Construct(riid, pUnkOuter, ProxyInfo->pProxyVtblList[Index],
97                            ProxyInfo->pStubVtblList[Index], iface, ppProxy, ppv);
98 }
99
100 static HRESULT WINAPI CStdPSFactory_CreateStub(LPPSFACTORYBUFFER iface,
101                                               REFIID riid,
102                                               LPUNKNOWN pUnkServer,
103                                               LPRPCSTUBBUFFER *ppStub)
104 {
105   ICOM_THIS(CStdPSFactoryBuffer,iface);
106   const ProxyFileInfo *ProxyInfo;
107   int Index;
108   TRACE("(%p)->CreateStub(%s,%p,%p)\n",iface,debugstr_guid(riid),
109        pUnkServer,ppStub);
110   if (!FindProxyInfo(This->pProxyFileList,riid,&ProxyInfo,&Index))
111     return E_NOINTERFACE;
112   return CStdStubBuffer_Construct(riid, pUnkServer, ProxyInfo->pStubVtblList[Index], iface, ppStub);
113 }
114
115 static ICOM_VTABLE(IPSFactoryBuffer) CStdPSFactory_Vtbl =
116 {
117   ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
118   CStdPSFactory_QueryInterface,
119   CStdPSFactory_AddRef,
120   CStdPSFactory_Release,
121   CStdPSFactory_CreateProxy,
122   CStdPSFactory_CreateStub
123 };
124
125 /***********************************************************************
126  *           NdrDllGetClassObject [RPCRT4.@]
127  */
128 HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv,
129                                    const ProxyFileInfo **pProxyFileList,
130                                    const CLSID *pclsid,
131                                    CStdPSFactoryBuffer *pPSFactoryBuffer)
132 {
133   *ppv = NULL;
134   if (!pPSFactoryBuffer->lpVtbl) {
135     pPSFactoryBuffer->lpVtbl = &CStdPSFactory_Vtbl;
136     pPSFactoryBuffer->RefCount = 0;
137     pPSFactoryBuffer->pProxyFileList = pProxyFileList;
138   }
139   if (IsEqualGUID(rclsid, pclsid))
140     return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv);
141   return CLASS_E_CLASSNOTAVAILABLE;
142 }
143
144 /***********************************************************************
145  *           NdrDllCanUnloadNow [RPCRT4.@]
146  */
147 HRESULT WINAPI NdrDllCanUnloadNow(CStdPSFactoryBuffer *pPSFactoryBuffer)
148 {
149   return !(pPSFactoryBuffer->RefCount);
150 }
151
152 /***********************************************************************
153  *           NdrDllRegisterProxy [RPCRT4.@]
154  */
155 HRESULT WINAPI NdrDllRegisterProxy(HMODULE hDll,
156                                   const ProxyFileInfo **pProxyFileList,
157                                   const CLSID *pclsid)
158 {
159   LPSTR clsid;
160   char keyname[120], module[120];
161   HKEY key, subkey;
162
163   TRACE("(%p,%p,%s)\n", hDll, pProxyFileList, debugstr_guid(pclsid));
164   UuidToStringA((UUID*)pclsid, &clsid);
165
166   /* register interfaces to point to clsid */
167   while (*pProxyFileList) {
168     unsigned u;
169     for (u=0; u<(*pProxyFileList)->TableSize; u++) {
170       CInterfaceProxyVtbl *proxy = (*pProxyFileList)->pProxyVtblList[u];
171       PCInterfaceName name = (*pProxyFileList)->pNamesArray[u];
172       LPSTR iid;
173
174       TRACE("registering %s %s => %s\n", name, debugstr_guid(proxy->header.piid), clsid);
175
176       UuidToStringA((UUID*)proxy->header.piid, &iid);
177       snprintf(keyname, sizeof(keyname), "Interface\\%s", iid);
178       RpcStringFreeA(&iid);
179       if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyname, 0, NULL, 0,
180                           KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) {
181         if (name)
182           RegSetValueExA(key, NULL, 0, REG_SZ, name, strlen(name));
183         if (RegCreateKeyExA(key, "ProxyStubClsid32", 0, NULL, 0,
184                             KEY_WRITE, NULL, &subkey, NULL) == ERROR_SUCCESS) {
185           RegSetValueExA(subkey, NULL, 0, REG_SZ, clsid, strlen(clsid));
186           RegCloseKey(subkey);
187         }
188         RegCloseKey(key);
189       }
190     }
191     pProxyFileList++;
192   }
193
194   /* register clsid to point to module */
195   snprintf(keyname, sizeof(keyname), "CLSID\\%s", clsid);
196   GetModuleFileNameA(hDll, module, sizeof(module));
197   TRACE("registering %s => %s\n", clsid, module);
198   if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyname, 0, NULL, 0,
199                       KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) {
200      if (RegCreateKeyExA(key, "InProcServer32", 0, NULL, 0,
201                          KEY_WRITE, NULL, &subkey, NULL) == ERROR_SUCCESS) {
202        RegSetValueExA(subkey, NULL, 0, REG_SZ, module, strlen(module));
203        RegCloseKey(subkey);
204      }
205      RegCloseKey(key);
206   }
207
208   /* done */
209   RpcStringFreeA(&clsid);
210   return S_OK;
211 }
212
213 /***********************************************************************
214  *           NdrDllUnregisterProxy [RPCRT4.@]
215  */
216 HRESULT WINAPI NdrDllUnregisterProxy(HMODULE hDll,
217                                     const ProxyFileInfo **pProxyFileList,
218                                     const CLSID *pclsid)
219 {
220   LPSTR clsid;
221   char keyname[120], module[120];
222
223   TRACE("(%p,%p,%s)\n", hDll, pProxyFileList, debugstr_guid(pclsid));
224   UuidToStringA((UUID*)pclsid, &clsid);
225
226   /* unregister interfaces */
227   while (*pProxyFileList) {
228     unsigned u;
229     for (u=0; u<(*pProxyFileList)->TableSize; u++) {
230       CInterfaceProxyVtbl *proxy = (*pProxyFileList)->pProxyVtblList[u];
231       PCInterfaceName name = (*pProxyFileList)->pNamesArray[u];
232       LPSTR iid;
233
234       TRACE("unregistering %s %s <= %s\n", name, debugstr_guid(proxy->header.piid), clsid);
235
236       UuidToStringA((UUID*)proxy->header.piid, &iid);
237       snprintf(keyname, sizeof(keyname), "Interface\\%s", iid);
238       RpcStringFreeA(&iid);
239       RegDeleteKeyA(HKEY_CLASSES_ROOT, keyname);
240     }
241     pProxyFileList++;
242   }
243
244   /* unregister clsid */
245   snprintf(keyname, sizeof(keyname), "CLSID\\%s", clsid);
246   GetModuleFileNameA(hDll, module, sizeof(module));
247   TRACE("unregistering %s <= %s\n", clsid, module);
248   RegDeleteKeyA(HKEY_CLASSES_ROOT, keyname);
249
250   /* done */
251   RpcStringFreeA(&clsid);
252   return S_OK;
253 }