Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencpsf.c
Go to the documentation of this file.
00001 /* 00002 * COM proxy/stub factory (CStdPSFactory) implementation 00003 * 00004 * Copyright 2001 Ove Kåven, TransGaming Technologies 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 #include "config.h" 00022 #include "wine/port.h" 00023 00024 #include <stdarg.h> 00025 #include <stdio.h> 00026 #include <string.h> 00027 00028 #define COBJMACROS 00029 00030 #include "windef.h" 00031 #include "winbase.h" 00032 #include "winerror.h" 00033 #include "winreg.h" 00034 00035 #include "objbase.h" 00036 00037 #include "rpcproxy.h" 00038 00039 #include "wine/unicode.h" 00040 #include "wine/debug.h" 00041 00042 #include "cpsf.h" 00043 00044 WINE_DEFAULT_DEBUG_CHANNEL(ole); 00045 00046 static void format_clsid( WCHAR *buffer, const CLSID *clsid ) 00047 { 00048 static const WCHAR clsid_formatW[] = {'{','%','0','8','X','-','%','0','4','X','-','%','0','4','X','-', 00049 '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X', 00050 '%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','}',0}; 00051 00052 sprintfW( buffer, clsid_formatW, clsid->Data1, clsid->Data2, clsid->Data3, 00053 clsid->Data4[0], clsid->Data4[1], clsid->Data4[2], clsid->Data4[3], 00054 clsid->Data4[4], clsid->Data4[5], clsid->Data4[6], clsid->Data4[7] ); 00055 00056 } 00057 00058 static BOOL FindProxyInfo(const ProxyFileInfo **pProxyFileList, REFIID riid, const ProxyFileInfo **pProxyInfo, int *pIndex) 00059 { 00060 while (*pProxyFileList) { 00061 if ((*pProxyFileList)->pIIDLookupRtn(riid, pIndex)) { 00062 *pProxyInfo = *pProxyFileList; 00063 TRACE("found: ProxyInfo %p Index %d\n", *pProxyInfo, *pIndex); 00064 return TRUE; 00065 } 00066 pProxyFileList++; 00067 } 00068 TRACE("not found\n"); 00069 return FALSE; 00070 } 00071 00072 static HRESULT WINAPI CStdPSFactory_QueryInterface(LPPSFACTORYBUFFER iface, 00073 REFIID riid, 00074 LPVOID *obj) 00075 { 00076 CStdPSFactoryBuffer *This = (CStdPSFactoryBuffer *)iface; 00077 TRACE("(%p)->QueryInterface(%s,%p)\n",iface,debugstr_guid(riid),obj); 00078 if (IsEqualGUID(&IID_IUnknown,riid) || 00079 IsEqualGUID(&IID_IPSFactoryBuffer,riid)) { 00080 *obj = This; 00081 InterlockedIncrement( &This->RefCount ); 00082 return S_OK; 00083 } 00084 return E_NOINTERFACE; 00085 } 00086 00087 static ULONG WINAPI CStdPSFactory_AddRef(LPPSFACTORYBUFFER iface) 00088 { 00089 CStdPSFactoryBuffer *This = (CStdPSFactoryBuffer *)iface; 00090 TRACE("(%p)->AddRef()\n",iface); 00091 return InterlockedIncrement( &This->RefCount ); 00092 } 00093 00094 static ULONG WINAPI CStdPSFactory_Release(LPPSFACTORYBUFFER iface) 00095 { 00096 CStdPSFactoryBuffer *This = (CStdPSFactoryBuffer *)iface; 00097 TRACE("(%p)->Release()\n",iface); 00098 return InterlockedDecrement( &This->RefCount ); 00099 } 00100 00101 static HRESULT WINAPI CStdPSFactory_CreateProxy(LPPSFACTORYBUFFER iface, 00102 LPUNKNOWN pUnkOuter, 00103 REFIID riid, 00104 LPRPCPROXYBUFFER *ppProxy, 00105 LPVOID *ppv) 00106 { 00107 CStdPSFactoryBuffer *This = (CStdPSFactoryBuffer *)iface; 00108 const ProxyFileInfo *ProxyInfo; 00109 int Index; 00110 TRACE("(%p)->CreateProxy(%p,%s,%p,%p)\n",iface,pUnkOuter, 00111 debugstr_guid(riid),ppProxy,ppv); 00112 if (!FindProxyInfo(This->pProxyFileList,riid,&ProxyInfo,&Index)) 00113 return E_NOINTERFACE; 00114 return StdProxy_Construct(riid, pUnkOuter, ProxyInfo, Index, iface, ppProxy, ppv); 00115 } 00116 00117 static HRESULT WINAPI CStdPSFactory_CreateStub(LPPSFACTORYBUFFER iface, 00118 REFIID riid, 00119 LPUNKNOWN pUnkServer, 00120 LPRPCSTUBBUFFER *ppStub) 00121 { 00122 CStdPSFactoryBuffer *This = (CStdPSFactoryBuffer *)iface; 00123 const ProxyFileInfo *ProxyInfo; 00124 int Index; 00125 TRACE("(%p)->CreateStub(%s,%p,%p)\n",iface,debugstr_guid(riid), 00126 pUnkServer,ppStub); 00127 if (!FindProxyInfo(This->pProxyFileList,riid,&ProxyInfo,&Index)) 00128 return E_NOINTERFACE; 00129 00130 if(ProxyInfo->pDelegatedIIDs && ProxyInfo->pDelegatedIIDs[Index]) 00131 return CStdStubBuffer_Delegating_Construct(riid, pUnkServer, ProxyInfo->pNamesArray[Index], 00132 ProxyInfo->pStubVtblList[Index], ProxyInfo->pDelegatedIIDs[Index], 00133 iface, ppStub); 00134 00135 return CStdStubBuffer_Construct(riid, pUnkServer, ProxyInfo->pNamesArray[Index], 00136 ProxyInfo->pStubVtblList[Index], iface, ppStub); 00137 } 00138 00139 static const IPSFactoryBufferVtbl CStdPSFactory_Vtbl = 00140 { 00141 CStdPSFactory_QueryInterface, 00142 CStdPSFactory_AddRef, 00143 CStdPSFactory_Release, 00144 CStdPSFactory_CreateProxy, 00145 CStdPSFactory_CreateStub 00146 }; 00147 00148 00149 static void init_psfactory( CStdPSFactoryBuffer *psfac, const ProxyFileInfo **file_list ) 00150 { 00151 DWORD i, j, k; 00152 00153 psfac->lpVtbl = &CStdPSFactory_Vtbl; 00154 psfac->RefCount = 0; 00155 psfac->pProxyFileList = file_list; 00156 for (i = 0; file_list[i]; i++) 00157 { 00158 const PCInterfaceProxyVtblList *proxies = file_list[i]->pProxyVtblList; 00159 const PCInterfaceStubVtblList *stubs = file_list[i]->pStubVtblList; 00160 00161 for (j = 0; j < file_list[i]->TableSize; j++) 00162 { 00163 /* FIXME: i think that different vtables should be copied for 00164 * async interfaces */ 00165 void * const *pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Vtbl; 00166 void **pRpcStubVtbl = (void **)&stubs[j]->Vtbl; 00167 00168 if (file_list[i]->pDelegatedIIDs && file_list[i]->pDelegatedIIDs[j]) 00169 { 00170 void **vtbl = proxies[j]->Vtbl; 00171 if (file_list[i]->TableVersion > 1) vtbl++; 00172 fill_delegated_proxy_table( (IUnknownVtbl *)vtbl, stubs[j]->header.DispatchTableCount ); 00173 pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Delegating_Vtbl; 00174 } 00175 00176 for (k = 0; k < sizeof(IRpcStubBufferVtbl)/sizeof(void *); k++) 00177 if (!pRpcStubVtbl[k]) pRpcStubVtbl[k] = pSrcRpcStubVtbl[k]; 00178 } 00179 } 00180 } 00181 00182 00183 /*********************************************************************** 00184 * NdrDllGetClassObject [RPCRT4.@] 00185 */ 00186 HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv, 00187 const ProxyFileInfo **pProxyFileList, 00188 const CLSID *pclsid, 00189 CStdPSFactoryBuffer *pPSFactoryBuffer) 00190 { 00191 TRACE("(%s, %s, %p, %p, %s, %p)\n", debugstr_guid(rclsid), 00192 debugstr_guid(iid), ppv, pProxyFileList, debugstr_guid(pclsid), 00193 pPSFactoryBuffer); 00194 00195 *ppv = NULL; 00196 if (!pPSFactoryBuffer->lpVtbl) init_psfactory( pPSFactoryBuffer, pProxyFileList ); 00197 00198 if (pclsid && IsEqualGUID(rclsid, pclsid)) 00199 return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv); 00200 else { 00201 const ProxyFileInfo *info; 00202 int index; 00203 /* otherwise, the dll may be using the iid as the clsid, so 00204 * search for it in the proxy file list */ 00205 if (FindProxyInfo(pProxyFileList, rclsid, &info, &index)) 00206 return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv); 00207 00208 WARN("class %s not available\n", debugstr_guid(rclsid)); 00209 return CLASS_E_CLASSNOTAVAILABLE; 00210 } 00211 } 00212 00213 /*********************************************************************** 00214 * NdrDllCanUnloadNow [RPCRT4.@] 00215 */ 00216 HRESULT WINAPI NdrDllCanUnloadNow(CStdPSFactoryBuffer *pPSFactoryBuffer) 00217 { 00218 return pPSFactoryBuffer->RefCount != 0 ? S_FALSE : S_OK; 00219 } 00220 00221 00222 /*********************************************************************** 00223 * NdrDllRegisterProxy [RPCRT4.@] 00224 */ 00225 HRESULT WINAPI NdrDllRegisterProxy(HMODULE hDll, 00226 const ProxyFileInfo **pProxyFileList, 00227 const CLSID *pclsid) 00228 { 00229 static const WCHAR bothW[] = {'B','o','t','h',0}; 00230 static const WCHAR clsidW[] = {'C','L','S','I','D','\\',0}; 00231 static const WCHAR clsid32W[] = {'P','r','o','x','y','S','t','u','b','C','l','s','i','d','3','2',0}; 00232 static const WCHAR interfaceW[] = {'I','n','t','e','r','f','a','c','e','\\',0}; 00233 static const WCHAR psfactoryW[] = {'P','S','F','a','c','t','o','r','y','B','u','f','f','e','r',0}; 00234 static const WCHAR numformatW[] = {'%','u',0}; 00235 static const WCHAR nummethodsW[] = {'N','u','m','M','e','t','h','o','d','s',0}; 00236 static const WCHAR inprocserverW[] = {'I','n','P','r','o','c','S','e','r','v','e','r','3','2',0}; 00237 static const WCHAR threadingmodelW[] = {'T','h','r','e','a','d','i','n','g','M','o','d','e','l',0}; 00238 WCHAR clsid[39], keyname[50], module[MAX_PATH]; 00239 HKEY key, subkey; 00240 DWORD len; 00241 00242 TRACE("(%p,%p,%s)\n", hDll, pProxyFileList, debugstr_guid(pclsid)); 00243 00244 if (!hDll) return E_HANDLE; 00245 if (!*pProxyFileList) return E_NOINTERFACE; 00246 00247 if (pclsid) 00248 format_clsid( clsid, pclsid ); 00249 else if ((*pProxyFileList)->TableSize > 0) 00250 format_clsid( clsid,(*pProxyFileList)->pStubVtblList[0]->header.piid); 00251 else 00252 return E_NOINTERFACE; 00253 00254 /* register interfaces to point to clsid */ 00255 while (*pProxyFileList) { 00256 unsigned u; 00257 for (u=0; u<(*pProxyFileList)->TableSize; u++) { 00258 CInterfaceStubVtbl *proxy = (*pProxyFileList)->pStubVtblList[u]; 00259 PCInterfaceName name = (*pProxyFileList)->pNamesArray[u]; 00260 00261 TRACE("registering %s %s => %s\n", 00262 debugstr_a(name), debugstr_guid(proxy->header.piid), debugstr_w(clsid)); 00263 00264 strcpyW( keyname, interfaceW ); 00265 format_clsid( keyname + strlenW(keyname), proxy->header.piid ); 00266 if (RegCreateKeyW(HKEY_CLASSES_ROOT, keyname, &key) == ERROR_SUCCESS) { 00267 WCHAR num[10]; 00268 if (name) 00269 RegSetValueExA(key, NULL, 0, REG_SZ, (const BYTE *)name, strlen(name)+1); 00270 RegSetValueW( key, clsid32W, REG_SZ, clsid, 0 ); 00271 sprintfW(num, numformatW, proxy->header.DispatchTableCount); 00272 RegSetValueW( key, nummethodsW, REG_SZ, num, 0 ); 00273 RegCloseKey(key); 00274 } 00275 } 00276 pProxyFileList++; 00277 } 00278 00279 /* register clsid to point to module */ 00280 strcpyW( keyname, clsidW ); 00281 strcatW( keyname, clsid ); 00282 len = GetModuleFileNameW(hDll, module, sizeof(module)/sizeof(WCHAR)); 00283 if (len && len < sizeof(module)) { 00284 TRACE("registering CLSID %s => %s\n", debugstr_w(clsid), debugstr_w(module)); 00285 if (RegCreateKeyW(HKEY_CLASSES_ROOT, keyname, &key) == ERROR_SUCCESS) { 00286 RegSetValueExW(key, NULL, 0, REG_SZ, (const BYTE *)psfactoryW, sizeof(psfactoryW)); 00287 if (RegCreateKeyW(key, inprocserverW, &subkey) == ERROR_SUCCESS) { 00288 RegSetValueExW(subkey, NULL, 0, REG_SZ, (LPBYTE)module, (strlenW(module)+1)*sizeof(WCHAR)); 00289 RegSetValueExW(subkey, threadingmodelW, 0, REG_SZ, (const BYTE *)bothW, sizeof(bothW)); 00290 RegCloseKey(subkey); 00291 } 00292 RegCloseKey(key); 00293 } 00294 } 00295 00296 return S_OK; 00297 } 00298 00299 /*********************************************************************** 00300 * NdrDllUnregisterProxy [RPCRT4.@] 00301 */ 00302 HRESULT WINAPI NdrDllUnregisterProxy(HMODULE hDll, 00303 const ProxyFileInfo **pProxyFileList, 00304 const CLSID *pclsid) 00305 { 00306 static const WCHAR clsidW[] = {'C','L','S','I','D','\\',0}; 00307 static const WCHAR interfaceW[] = {'I','n','t','e','r','f','a','c','e','\\',0}; 00308 WCHAR keyname[50]; 00309 WCHAR clsid[39]; 00310 00311 TRACE("(%p,%p,%s)\n", hDll, pProxyFileList, debugstr_guid(pclsid)); 00312 if (pclsid) 00313 format_clsid( clsid, pclsid ); 00314 else if ((*pProxyFileList)->TableSize > 0) 00315 format_clsid( clsid,(*pProxyFileList)->pStubVtblList[0]->header.piid); 00316 else 00317 return E_NOINTERFACE; 00318 00319 /* unregister interfaces */ 00320 while (*pProxyFileList) { 00321 unsigned u; 00322 for (u=0; u<(*pProxyFileList)->TableSize; u++) { 00323 CInterfaceStubVtbl *proxy = (*pProxyFileList)->pStubVtblList[u]; 00324 PCInterfaceName name = (*pProxyFileList)->pNamesArray[u]; 00325 00326 TRACE("unregistering %s %s\n", debugstr_a(name), debugstr_guid(proxy->header.piid)); 00327 00328 strcpyW( keyname, interfaceW ); 00329 format_clsid( keyname + strlenW(keyname), proxy->header.piid ); 00330 RegDeleteTreeW(HKEY_CLASSES_ROOT, keyname); 00331 } 00332 pProxyFileList++; 00333 } 00334 00335 /* unregister clsid */ 00336 strcpyW( keyname, clsidW ); 00337 strcatW( keyname, clsid ); 00338 RegDeleteTreeW(HKEY_CLASSES_ROOT, keyname); 00339 00340 return S_OK; 00341 } Generated on Sun May 27 2012 04:26:01 for ReactOS by
1.7.6.1
|