ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

cpsf.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.