Sure, here it is. Disclaimer: This once worked for me. I have no idea if it even still applies or compiles. It did in July, it's now September... good luck. I have a few test apps I used to make sure this stuff was actually working, however the one I used required IE to be installed :) Sending to the list as well, as it might as well be in the hands of the public. I wish I had time to work on this, OLE/DCOM is quite interesting, but my "things to hack" list is crazy at the moment. thanks -mike On Wed, 2003-12-10 at 20:53, Brian Vincent wrote: > You mentioned you mailed Mike McCormack a big DCOM patch > from your work over the summer. Could you forward it to > me? I've got a friend I might try to con into Wine development > and a patch merge might be a good way to do it. > > -brian
? total.patch ? typelib.patch ? world-of-dcom.patch ? dlls/kernel/comm.spec.c ? dlls/kernel/system.spec.c ? dlls/ntdll/ntdll.dll.glue.c ? dlls/ntdll/relay16.s ? dlls/ole32/compobj.diff ? dlls/ole32/compobj_private.diff ? dlls/ole32/dcom_p.c ? dlls/ole32/proxy.c ? dlls/ole32/unknwn_p.c ? dlls/user/display.spec.c ? dlls/user/keyboard.spec.c ? dlls/user/mouse.spec.c ? tools/winewrap Index: dlls/ole32/Makefile.in =================================================================== RCS file: /home/wine/wine/dlls/ole32/Makefile.in,v retrieving revision 1.33 diff -u -r1.33 Makefile.in --- dlls/ole32/Makefile.in 11 Oct 2003 01:09:18 -0000 1.33 +++ dlls/ole32/Makefile.in 18 Oct 2003 12:04:22 -0000 @@ -16,6 +16,7 @@ clipboard.c \ compobj.c \ compositemoniker.c \ + dcom_p.c \ datacache.c \ defaulthandler.c \ errorinfo.c \ @@ -25,7 +26,6 @@ hglobalstream.c \ ifs.c \ itemmoniker.c \ - marshal.c \ memlockbytes.c \ moniker.c \ ole2.c \ @@ -33,12 +33,12 @@ ole2impl.c \ ole32_main.c \ oleobj.c \ - oleproxy.c \ + proxy.c \ regsvr.c \ - rpc.c \ stg_bigblockfile.c \ stg_stream.c \ - storage32.c + storage32.c \ + unknwn_p.c C_SRCS16 = \ memlockbytes16.c \ Index: dlls/ole32/compobj.c =================================================================== RCS file: /home/wine/wine/dlls/ole32/compobj.c,v retrieving revision 1.84 diff -u -r1.84 compobj.c --- dlls/ole32/compobj.c 6 Oct 2003 21:03:32 -0000 1.84 +++ dlls/ole32/compobj.c 18 Oct 2003 12:04:22 -0000 @@ -24,8 +24,8 @@ #include "config.h" -#include <stdlib.h> #include <stdarg.h> +#include <stdlib.h> #include <stdio.h> #include <string.h> #include <assert.h> @@ -39,6 +39,7 @@ #include "ole2.h" #include "ole2ver.h" #include "rpc.h" +#include "wingdi.h" #include "winerror.h" #include "winreg.h" #include "wownt32.h" @@ -58,7 +59,6 @@ */ HINSTANCE COMPOBJ_hInstance32 = 0; -static HRESULT COM_GetRegisteredClassObject(REFCLSID rclsid, DWORD dwClsContext, LPUNKNOWN* ppUnk); static void COM_RevokeAllClasses(); static void COM_ExternalLockFreeList(); @@ -93,11 +93,10 @@ typedef struct tagRegisteredClass { CLSID classIdentifier; - LPUNKNOWN classObject; DWORD runContext; DWORD connectFlags; DWORD dwCookie; - HANDLE hThread; /* only for localserver */ + LPSTREAM pMarshal; struct tagRegisteredClass* nextClass; } RegisteredClass; @@ -140,7 +139,6 @@ static CRITICAL_SECTION csOpenDllList = { &dll_cs_debug, -1, 0, 0, 0, 0 }; static const char aptWinClass[] = "WINE_OLE32_APT_CLASS"; -static LRESULT CALLBACK COM_AptWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); static void COMPOBJ_DLLList_Add(HANDLE hLibrary); static void COMPOBJ_DllList_FreeUnused(int Timeout); @@ -242,10 +240,6 @@ return win; } -static LRESULT CALLBACK COM_AptWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - return DefWindowProcA(hWnd, msg, wParam, lParam); -} /***************************************************************************** * This section contains OpenDllList implemantation @@ -324,7 +318,7 @@ /****************************************************************************** * CoBuildVersion [COMPOBJ.1] - * CoBuildVersion [OLE32.@] + * CoBuildVersion [OLE32.4] * * RETURNS * Current build version, hiword is majornumber, loword is minornumber @@ -336,7 +330,7 @@ } /****************************************************************************** - * CoInitialize [OLE32.@] + * CoInitialize [OLE32.26] * * Initializes the COM libraries. * @@ -354,7 +348,7 @@ } /****************************************************************************** - * CoInitializeEx [OLE32.@] + * CoInitializeEx [OLE32.163] * * Initializes the COM libraries. The behavior used to set the win32 IMalloc * used for memory management is obsolete. @@ -412,7 +406,7 @@ } /*********************************************************************** - * CoUninitialize [OLE32.@] + * CoUninitialize [OLE32.47] * * This method will release the COM libraries. * @@ -472,7 +466,7 @@ /****************************************************************************** * CoDisconnectObject [COMPOBJ.15] - * CoDisconnectObject [OLE32.@] + * CoDisconnectObject [OLE32.8] */ HRESULT WINAPI CoDisconnectObject( LPUNKNOWN lpUnk, DWORD reserved ) { @@ -481,7 +475,7 @@ } /****************************************************************************** - * CoCreateGuid[OLE32.@] + * CoCreateGuid[OLE32.6] * */ HRESULT WINAPI CoCreateGuid( @@ -491,8 +485,8 @@ } /****************************************************************************** - * CLSIDFromString [OLE32.@] - * IIDFromString [OLE32.@] + * CLSIDFromString [OLE32.3] + * IIDFromString [OLE32.74] * Converts a unique identifier from its string representation into * the GUID struct. * @@ -626,8 +620,8 @@ /****************************************************************************** - * StringFromCLSID [OLE32.@] - * StringFromIID [OLE32.@] + * StringFromCLSID [OLE32.151] + * StringFromIID [OLE32.153] * Converts a GUID into the respective string representation. * The target string is allocated using the OLE IMalloc. * RETURNS @@ -655,7 +649,7 @@ /****************************************************************************** * StringFromGUID2 [COMPOBJ.76] - * StringFromGUID2 [OLE32.@] + * StringFromGUID2 [OLE32.152] * * Converts a global unique identifier into a string of an API- * specified fixed format. (The usual {.....} stuff.) @@ -675,7 +669,7 @@ } /****************************************************************************** - * ProgIDFromCLSID [OLE32.@] + * ProgIDFromCLSID [OLE32.133] * Converts a class id into the respective Program ID. (By using a registry lookup) * RETURNS S_OK on success * riid associated with the progid @@ -758,7 +752,7 @@ } /****************************************************************************** - * CLSIDFromProgID [OLE32.@] + * CLSIDFromProgID [OLE32.2] * Converts a program id into the respective GUID. (By using a registry lookup) * RETURNS * riid associated with the progid @@ -794,7 +788,7 @@ /***************************************************************************** - * CoGetPSClsid [OLE32.@] + * CoGetPSClsid [OLE32.22] * * This function returns the CLSID of the DLL that implements the proxy and stub * for the specified interface. @@ -860,7 +854,7 @@ /*********************************************************************** - * WriteClassStm (OLE32.@) + * WriteClassStm (OLE32.159) * * This function write a CLSID on stream */ @@ -875,7 +869,7 @@ } /*********************************************************************** - * ReadClassStm (OLE32.@) + * ReadClassStm (OLE32.135) * * This function read a CLSID from a stream */ @@ -909,15 +903,17 @@ * * Params: * rclsid Class ID of the class to find. - * dwClsContext Class context to match. - * ppv [out] returns a pointer to the class object. Complying + * ppUnk [out] returns a pointer to the class object. Complying * to normal COM usage, this method will increase the * reference count on this object. + * pObjRef [out] DCOM standard object reference + * pMIF [out] DCOM marshalled interface pointer */ -static HRESULT COM_GetRegisteredClassObject( - REFCLSID rclsid, - DWORD dwClsContext, - LPUNKNOWN* ppUnk) +HRESULT COM_GetRegisteredClassObject( + REFCLSID rclsid, + LPUNKNOWN* ppUnk, + STDOBJREF* pObjRef, + MInterfacePointer** ppMIF) { HRESULT hr = S_FALSE; RegisteredClass* curClass; @@ -925,11 +921,6 @@ EnterCriticalSection( &csRegisteredClassList ); /* - * Sanity check - */ - assert(ppUnk!=0); - - /* * Iterate through the whole list and try to match the class ID. */ curClass = firstRegisteredClass; @@ -942,18 +933,28 @@ if (IsEqualGUID(&(curClass->classIdentifier), rclsid)) { /* - * Since we don't do out-of process or DCOM just right away, let's ignore the - * class context. - */ - - /* - * We have a match, return the pointer to the class object. + * We have a match, unmarshal the class object reference. */ - *ppUnk = curClass->classObject; + if (ppUnk || pObjRef || ppMIF) + { + LARGE_INTEGER pos; - IUnknown_AddRef(curClass->classObject); + pos.s.LowPart = 0; + pos.s.HighPart = 0; + IStream_Seek(curClass->pMarshal, pos, 0, NULL); + } + if (ppUnk) { + hr = CoUnmarshalInterface(curClass->pMarshal, &IID_IUnknown, (void**)ppUnk); + } + else if (pObjRef) { + hr = COM_GetStdObjRef(curClass->pMarshal, pObjRef, NULL); + } + else if (ppMIF) { + FIXME("create MInterfacePointer\n"); + hr = E_FAIL; + } + else hr = S_OK; - hr = S_OK; goto end; } @@ -971,85 +972,8 @@ return hr; } -static DWORD WINAPI -_LocalServerThread(LPVOID param) { - HANDLE hPipe; - char pipefn[200]; - RegisteredClass *newClass = (RegisteredClass*)param; - HRESULT hres; - IStream *pStm; - STATSTG ststg; - unsigned char *buffer; - int buflen; - IClassFactory *classfac; - LARGE_INTEGER seekto; - ULARGE_INTEGER newpos; - ULONG res; - - TRACE("Starting threader for %s.\n",debugstr_guid(&newClass->classIdentifier)); - strcpy(pipefn,PIPEPREF); - WINE_StringFromCLSID(&newClass->classIdentifier,pipefn+strlen(PIPEPREF)); - - hres = IUnknown_QueryInterface(newClass->classObject,&IID_IClassFactory,(LPVOID*)&classfac); - if (hres) return hres; - - hres = CreateStreamOnHGlobal(0,TRUE,&pStm); - if (hres) { - FIXME("Failed to create stream on hglobal.\n"); - return hres; - } - hres = CoMarshalInterface(pStm,&IID_IClassFactory,(LPVOID)classfac,0,NULL,0); - if (hres) { - FIXME("CoMarshalInterface failed, %lx!\n",hres); - return hres; - } - hres = IStream_Stat(pStm,&ststg,0); - if (hres) return hres; - - buflen = ststg.cbSize.s.LowPart; - buffer = HeapAlloc(GetProcessHeap(),0,buflen); - seekto.s.LowPart = 0; - seekto.s.HighPart = 0; - hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos); - if (hres) { - FIXME("IStream_Seek failed, %lx\n",hres); - return hres; - } - hres = IStream_Read(pStm,buffer,buflen,&res); - if (hres) { - FIXME("Stream Read failed, %lx\n",hres); - return hres; - } - IStream_Release(pStm); - - while (1) { - hPipe = CreateNamedPipeA( - pipefn, - PIPE_ACCESS_DUPLEX, - PIPE_TYPE_BYTE|PIPE_WAIT, - PIPE_UNLIMITED_INSTANCES, - 4096, - 4096, - NMPWAIT_USE_DEFAULT_WAIT, - NULL - ); - if (hPipe == INVALID_HANDLE_VALUE) { - FIXME("pipe creation failed for %s, le is %lx\n",pipefn,GetLastError()); - return 1; - } - if (!ConnectNamedPipe(hPipe,NULL)) { - ERR("Failure during ConnectNamedPipe %lx, ABORT!\n",GetLastError()); - CloseHandle(hPipe); - continue; - } - WriteFile(hPipe,buffer,buflen,&res,NULL); - CloseHandle(hPipe); - } - return 0; -} - /****************************************************************************** - * CoRegisterClassObject [OLE32.@] + * CoRegisterClassObject [OLE32.36] * * This method will register the class object for a given class ID. * @@ -1064,11 +988,15 @@ ) { RegisteredClass* newClass; - LPUNKNOWN foundObject; + DWORD dwCtx; HRESULT hr; + char buf[80]; + + WINE_StringFromCLSID(rclsid,buf); TRACE("(%s,%p,0x%08lx,0x%08lx,%p)\n", - debugstr_guid(rclsid),pUnk,dwClsContext,flags,lpdwRegister); + buf,pUnk,dwClsContext,flags,lpdwRegister); + TRACE("vtbl=%p\n", pUnk->lpVtbl); if ( (lpdwRegister==0) || (pUnk==0) ) return E_INVALIDARG; @@ -1079,18 +1007,24 @@ * First, check if the class is already registered. * If it is, this should cause an error. */ - hr = COM_GetRegisteredClassObject(rclsid, dwClsContext, &foundObject); - if (hr == S_OK) { - IUnknown_Release(foundObject); + hr = COM_GetRegisteredClassObject(rclsid, NULL, NULL, NULL); + + if (hr == S_OK) return CO_E_OBJISREG; - } - newClass = HeapAlloc(GetProcessHeap(), 0, sizeof(RegisteredClass)); + /* + * If it is not registered, we must create a new entry for this class and + * append it to the registered class list. + * We use the address of the chain node as the cookie since we are sure it's + * unique. + */ + newClass = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RegisteredClass)); if ( newClass == NULL ) return E_OUTOFMEMORY; - EnterCriticalSection( &csRegisteredClassList ); - + /* + * Initialize the node. + */ newClass->classIdentifier = *rclsid; newClass->runContext = dwClsContext; newClass->connectFlags = flags; @@ -1099,31 +1033,51 @@ * unique. */ newClass->dwCookie = (DWORD)newClass; - newClass->nextClass = firstRegisteredClass; /* - * Since we're making a copy of the object pointer, we have to increase its - * reference count. + * Marshal a reference to the class object. + */ + hr = CreateStreamOnHGlobal(0, TRUE, &newClass->pMarshal); + if (FAILED(hr)) { + HeapFree(GetProcessHeap(), 0, newClass); + return hr; + } + + if (dwClsContext & CLSCTX_REMOTE_SERVER) dwCtx = MSHCTX_DIFFERENTMACHINE; + else if (dwClsContext & CLSCTX_LOCAL_SERVER) dwCtx = MSHCTX_LOCAL; + else dwCtx = MSHCTX_INPROC; + + hr = CoMarshalInterface(newClass->pMarshal, &IID_IUnknown, pUnk, dwCtx, NULL, MSHLFLAGS_TABLESTRONG); + if (FAILED(hr)) { + IStream_Release(newClass->pMarshal); + HeapFree(GetProcessHeap(), 0, newClass); + return hr; + } + + /* + * Insert the class into the chain. */ - newClass->classObject = pUnk; - IUnknown_AddRef(newClass->classObject); + EnterCriticalSection( &csRegisteredClassList ); + newClass->nextClass = firstRegisteredClass; firstRegisteredClass = newClass; LeaveCriticalSection( &csRegisteredClassList ); - *lpdwRegister = newClass->dwCookie; + /* + * Register the exported object. + */ + COM_RpcExportClass(&newClass->classIdentifier, dwCtx); - if (dwClsContext & CLSCTX_LOCAL_SERVER) { - DWORD tid; + /* + * Assign the out parameter (cookie) + */ + *lpdwRegister = newClass->dwCookie; - STUBMGR_Start(); - newClass->hThread=CreateThread(NULL,0,_LocalServerThread,newClass,0,&tid); - } return S_OK; } /*********************************************************************** - * CoRevokeClassObject [OLE32.@] + * CoRevokeClassObject [OLE32.40] * * This method will remove a class object from the class registry * @@ -1153,15 +1107,23 @@ */ if (curClass->dwCookie == dwRegister) { + LARGE_INTEGER pos; + /* * Remove the class from the chain. */ *prevClassLink = curClass->nextClass; /* - * Release the reference to the class object. + * Release the marshalled reference. */ - IUnknown_Release(curClass->classObject); + pos.s.LowPart = 0; + pos.s.HighPart = 0; + IStream_Seek(curClass->pMarshal, pos, 0, NULL); + + CoReleaseMarshalData(curClass->pMarshal); + + IStream_Release(curClass->pMarshal); /* * Free the memory used by the chain node. @@ -1184,9 +1146,12 @@ /* * If we get to here, we haven't found our class. */ - return hr; + return E_INVALIDARG; } +typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv); + + /*********************************************************************** * compobj_RegReadPath [internal] * @@ -1215,7 +1180,7 @@ /*********************************************************************** * CoGetClassObject [COMPOBJ.7] - * CoGetClassObject [OLE32.@] + * CoGetClassObject [OLE32.16] * * FIXME. If request allows of several options and there is a failure * with one (other than not being registered) do we try the @@ -1230,7 +1195,6 @@ HRESULT hres = E_UNEXPECTED; char xclsid[80]; HINSTANCE hLibrary; - typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv); DllGetClassObjectFunc DllGetClassObject; WINE_StringFromCLSID((LPCLSID)rclsid,xclsid); @@ -1246,7 +1210,7 @@ * First, try and see if we can't match the class ID with one of the * registered classes. */ - if (S_OK == COM_GetRegisteredClassObject(rclsid, dwClsContext, ®ClassObject)) + if (S_OK == COM_GetRegisteredClassObject(rclsid, ®ClassObject, NULL, NULL)) { /* * Get the required interface from the retrieved pointer. @@ -1272,7 +1236,7 @@ if ( compobj_RegReadPath(keyname, NULL, dllpath, sizeof(dllpath)) != ERROR_SUCCESS) { /* failure: CLSID is not found in registry */ - WARN("class %s not registred\n", xclsid); + WARN("class %s not registered\n", xclsid); hres = REGDB_E_CLASSNOTREG; } else { if ((hLibrary = LoadLibraryExA(dllpath, 0, LOAD_WITH_ALTERED_SEARCH_PATH)) == 0) { @@ -1293,9 +1257,55 @@ } /* Next try out of process */ - if (CLSCTX_LOCAL_SERVER & dwClsContext) - { - return create_marshalled_proxy(rclsid,iid,ppv); + if (CLSCTX_LOCAL_SERVER & dwClsContext) { + char keyname[MAX_PATH]; + char exepath[MAX_PATH+1]; + STARTUPINFOA si; + PROCESS_INFORMATION pi; + int wait; + + hres = COM_RpcImportClass(ppv, rclsid, iid, NULL); + if (hres != EPT_S_NOT_REGISTERED) + return hres; + + /* we need to load the server + * (FIXME: this is a job for IRemoteActivation, + * but I haven't implemented that stuff) */ + /* FIXME: protect this with a named mutex, + * so the local server won't be launched twice */ + sprintf(keyname,"CLSID\\%s\\LocalServer32",xclsid); + if (compobj_RegReadPath(keyname, NULL, exepath, sizeof(exepath)) != ERROR_SUCCESS) { + /* failure: CLSID is not found in registry */ + WARN("class %s not registred\n", xclsid); + return REGDB_E_CLASSNOTREG; + } + TRACE("found LocalServer32 app %s\n", exepath); + + /* create process (FIXME: creation flags?) */ + memset(&si, 0, sizeof(si)); + si.cb = sizeof(si); + /* FIXME: I think we're supposed to add an argument, + * see MS's COM samples */ + TRACE("About to create LocalServer32 app\n"); + if (!CreateProcessA(exepath, NULL, NULL, NULL, FALSE, 0, + NULL, NULL, &si, &pi)) { + FIXME("couldn't load LocalServer32 app %s\n", exepath); + return CO_E_APPNOTFOUND; + } + + /* wait for the local server to load + * (don't remember how long MS gives it, was it 2 minutes?) */ + wait = 0; + do { + Sleep(1000); + wait++; + hres = COM_RpcImportClass(ppv, rclsid, iid, NULL); + } while (hres == EPT_S_NOT_REGISTERED && wait < 120); + if (hres == EPT_S_NOT_REGISTERED) { + /* wait failed */ + return CO_E_APPDIDNTREG; + } + return hres; } /* Finally try remote */ @@ -1308,7 +1318,7 @@ return hres; } /*********************************************************************** - * CoResumeClassObjects (OLE32.@) + * CoResumeClassObjects (OLE32.173) * * Resumes classobjects registered with REGCLS suspended */ @@ -1319,7 +1329,7 @@ } /*********************************************************************** - * GetClassFile (OLE32.@) + * GetClassFile (OLE32.67) * * This function supplies the CLSID associated with the given filename. */ @@ -1413,7 +1423,7 @@ } /*********************************************************************** * CoCreateInstance [COMPOBJ.13] - * CoCreateInstance [OLE32.@] + * CoCreateInstance [OLE32.7] */ HRESULT WINAPI CoCreateInstance( REFCLSID rclsid, @@ -1422,8 +1432,8 @@ REFIID iid, LPVOID *ppv) { - HRESULT hres; - LPCLASSFACTORY lpclf = 0; + HRESULT hres; + LPCLASSFACTORY lpclf = 0; /* * Sanity check @@ -1468,17 +1478,17 @@ /* * Create the object and don't forget to release the factory */ - hres = IClassFactory_CreateInstance(lpclf, pUnkOuter, iid, ppv); - IClassFactory_Release(lpclf); - if(FAILED(hres)) - FIXME("no instance created for interface %s of class %s, hres is 0x%08lx\n", - debugstr_guid(iid), debugstr_guid(rclsid),hres); + hres = IClassFactory_CreateInstance(lpclf, pUnkOuter, iid, ppv); + IClassFactory_Release(lpclf); + if(FAILED(hres)) + FIXME("no instance created for interface %s of class %s, hres is 0x%08lx\n", + debugstr_guid(iid), debugstr_guid(rclsid),hres); - return hres; + return hres; } /*********************************************************************** - * CoCreateInstanceEx [OLE32.@] + * CoCreateInstanceEx [OLE32.165] */ HRESULT WINAPI CoCreateInstanceEx( REFCLSID rclsid, @@ -1551,7 +1561,7 @@ } /*********************************************************************** - * CoLoadLibrary (OLE32.@) + * CoLoadLibrary (OLE32.30) */ HINSTANCE WINAPI CoLoadLibrary(LPOLESTR lpszLibName, BOOL bAutoFree) { @@ -1561,7 +1571,7 @@ } /*********************************************************************** - * CoFreeLibrary [OLE32.@] + * CoFreeLibrary [OLE32.13] * * NOTES: don't belive the docu */ @@ -1572,7 +1582,7 @@ /*********************************************************************** - * CoFreeAllLibraries [OLE32.@] + * CoFreeAllLibraries [OLE32.12] * * NOTES: don't belive the docu */ @@ -1584,7 +1594,7 @@ /*********************************************************************** * CoFreeUnusedLibraries [COMPOBJ.17] - * CoFreeUnusedLibraries [OLE32.@] + * CoFreeUnusedLibraries [OLE32.14] * * FIXME: Calls to CoFreeUnusedLibraries from any thread always route * through the main apartment's thread to call DllCanUnloadNow @@ -1596,7 +1606,7 @@ /*********************************************************************** * CoFileTimeNow [COMPOBJ.82] - * CoFileTimeNow [OLE32.@] + * CoFileTimeNow [OLE32.10] * * RETURNS * the current system time in lpFileTime @@ -1608,7 +1618,7 @@ } /*********************************************************************** - * CoLoadLibrary (OLE32.@) + * CoLoadLibrary (OLE32.30) */ static void COM_RevokeAllClasses() { @@ -1826,7 +1836,7 @@ } /****************************************************************************** - * CoLockObjectExternal [OLE32.@] + * CoLockObjectExternal [OLE32.31] */ HRESULT WINAPI CoLockObjectExternal( LPUNKNOWN pUnk, /* [in] object to be locked */ @@ -1852,7 +1862,7 @@ } /*********************************************************************** - * CoInitializeWOW (OLE32.@) + * CoInitializeWOW (OLE32.27) */ HRESULT WINAPI CoInitializeWOW(DWORD x,DWORD y) { FIXME("(0x%08lx,0x%08lx),stub!\n",x,y); @@ -1864,7 +1874,7 @@ static HMODULE hOleAut32 = 0; /* global */ /*********************************************************************** - * CoGetState [OLE32.@] + * CoGetState [OLE32.24] * * NOTES: might be incomplete */ @@ -1884,7 +1894,7 @@ } /*********************************************************************** - * CoSetState [OLE32.@] + * CoSetState [OLE32.42] * * NOTES: FIXME: protect this with a crst */ @@ -1910,7 +1920,7 @@ /****************************************************************************** - * OleGetAutoConvert [OLE32.@] + * OleGetAutoConvert [OLE32.104] */ HRESULT WINAPI OleGetAutoConvert(REFCLSID clsidOld, LPCLSID pClsidNew) { @@ -1942,7 +1952,7 @@ } /****************************************************************************** - * OleSetAutoConvert [OLE32.@] + * OleSetAutoConvert [OLE32.126] */ HRESULT WINAPI OleSetAutoConvert(REFCLSID clsidOld, REFCLSID clsidNew) { @@ -1970,7 +1980,7 @@ } /****************************************************************************** - * OleDoAutoConvert [OLE32.@] + * OleDoAutoConvert [OLE32.100] */ HRESULT WINAPI OleDoAutoConvert(IStorage *pStg, LPCLSID pClsidNew) { @@ -1979,7 +1989,7 @@ } /****************************************************************************** - * CoTreatAsClass [OLE32.@] + * CoTreatAsClass [OLE32.46] */ HRESULT WINAPI CoTreatAsClass(REFCLSID clsidOld, REFCLSID clsidNew) { @@ -2007,7 +2017,7 @@ } /****************************************************************************** - * CoGetTreatAsClass [OLE32.@] + * CoGetTreatAsClass [OLE32.25] * * Reads the TreatAs value from a class. */ @@ -2042,7 +2052,7 @@ } /*********************************************************************** - * IsEqualGUID [OLE32.@] + * IsEqualGUID [OLE32.76] * * Compares two Unique Identifiers. * @@ -2059,7 +2069,7 @@ } /*********************************************************************** - * CoInitializeSecurity [OLE32.@] + * CoInitializeSecurity [OLE32.164] */ HRESULT WINAPI CoInitializeSecurity(PSECURITY_DESCRIPTOR pSecDesc, LONG cAuthSvc, SOLE_AUTHENTICATION_SERVICE* asAuthSvc, Index: dlls/ole32/compobj_private.h =================================================================== RCS file: /home/wine/wine/dlls/ole32/compobj_private.h,v retrieving revision 1.12 diff -u -r1.12 compobj_private.h --- dlls/ole32/compobj_private.h 5 Sep 2003 23:08:33 -0000 1.12 +++ dlls/ole32/compobj_private.h 18 Oct 2003 12:04:22 -0000 @@ -34,6 +34,7 @@ #include "dcom.h" #include "winreg.h" #include "winternl.h" +#include "thread.h" /* exported interface */ typedef struct tagXIF { @@ -216,7 +217,17 @@ return apt; } +/* proxy.c */ +void COM_RpcInit(void); +void COM_RpcExportClass(REFCLSID rclsid, DWORD dwCtx); +HRESULT COM_RpcImportClass(LPVOID *ppv, REFCLSID rclsid, REFIID riid, LPSTR server); + +HRESULT COM_GetStdObjRef(IStream *pStm, STDOBJREF *pObjRef, LPIID piid); + +LRESULT CALLBACK COM_AptWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + /* compobj.c */ HWND COM_GetApartmentWin(OXID oxid); +HRESULT COM_GetRegisteredClassObject(REFCLSID rclsid, LPUNKNOWN* ppUnk, STDOBJREF* pObjRef, MInterfacePointer** ppMIF); #endif /* __WINE_OLE_COMPOBJ_H */ --- /dev/null 2003-01-30 10:24:37.000000000 +0000 +++ dlls/ole32/dcom_p.c 2003-10-01 17:13:22.000000000 +0100 @@ -0,0 +1,1891 @@ +/* this ALWAYS GENERATED file contains the proxy stub code */ + + +/* File created by MIDL compiler version 5.01.0164 */ +/* at Fri May 23 15:10:07 2003 + */ +/* Compiler settings for dcom.idl: + Os (OptLev=s), W1, Zp8, env=Win32, ms_ext, c_ext + error checks: allocation ref bounds_check enum stub_data +*/ +//@@MIDL_FILE_HEADING( ) + + +/* verify that the <rpcproxy.h> version is high enough to compile this file*/ +#ifndef __REDQ_RPCPROXY_H_VERSION__ +#define __REQUIRED_RPCPROXY_H_VERSION__ 440 +#endif + +#include "windef.h" +#include "objbase.h" +#include "objidl.h" +#include "rpc.h" +#include "rpcproxy.h" +#ifndef __RPCPROXY_H_VERSION__ +#error this stub requires an updated version of <rpcproxy.h> +#endif // __RPCPROXY_H_VERSION__ + + +#include "dcom.h" + +#define TYPE_FORMAT_STRING_SIZE 531 +#define PROC_FORMAT_STRING_SIZE 225 + +typedef struct _MIDL_TYPE_FORMAT_STRING + { + short Pad; + unsigned char Format[ TYPE_FORMAT_STRING_SIZE ]; + } MIDL_TYPE_FORMAT_STRING; + +typedef struct _MIDL_PROC_FORMAT_STRING + { + short Pad; + unsigned char Format[ PROC_FORMAT_STRING_SIZE ]; + } MIDL_PROC_FORMAT_STRING; + + +extern const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString; +extern const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString; + + +/* Standard interface: ObjectRpcBaseTypes, ver. 0.0, + GUID={0x99fcfe60,0x5260,0x101b,{0xbb,0xcb,0x00,0xaa,0x00,0x21,0x34,0x7a}} */ + + +/* Object interface: IUnknown, ver. 0.0, + GUID={0x00000000,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +/* Object interface: IRemUnknown, ver. 0.0, + GUID={0x00000131,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +extern const MIDL_STUB_DESC Object_StubDesc; + + +#pragma code_seg(".orpc") + +HRESULT STDMETHODCALLTYPE IRemUnknown_RemQueryInterface_Proxy( + IRemUnknown __RPC_FAR * This, + /* [in] */ REFIPID ripid, + /* [in] */ unsigned long cRefs, + /* [in] */ unsigned short cIids, + /* [size_is][in] */ IID __RPC_FAR *iids, + /* [size_is][size_is][out] */ REMQIRESULT __RPC_FAR *__RPC_FAR *ppQIResults) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(ppQIResults) + { + *ppQIResults = 0; + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 3); + + + + if(!ripid) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!iids) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!ppQIResults) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U + 11U + 4U + 7U; + NdrSimpleStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ripid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[54] ); + + _StubMsg.MaxCount = cIids; + + NdrConformantArrayBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)iids, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[360] ); + + NdrProxyGetBuffer(This, &_StubMsg); + NdrSimpleStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ripid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[54] ); + + *(( unsigned long __RPC_FAR * )_StubMsg.Buffer)++ = cRefs; + + *(( unsigned short __RPC_FAR * )_StubMsg.Buffer)++ = cIids; + + _StubMsg.MaxCount = cIids; + + NdrConformantArrayMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)iids, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[360] ); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[166] ); + + NdrPointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ppQIResults, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[374], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *(( HRESULT __RPC_FAR * )_StubMsg.Buffer)++; + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _StubMsg.MaxCount = cIids; + + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[374], + ( void __RPC_FAR * )ppQIResults); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB IRemUnknown_RemQueryInterface_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + REMQIRESULT __RPC_FAR *_M21; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + unsigned short cIids; + unsigned long cRefs; + IID __RPC_FAR *iids; + REMQIRESULT __RPC_FAR *__RPC_FAR *ppQIResults; + REFIPID ripid; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + ( REFIPID )ripid = 0; + ( IID __RPC_FAR * )iids = 0; + ( REMQIRESULT __RPC_FAR *__RPC_FAR * )ppQIResults = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[166] ); + + NdrSimpleStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ripid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[54], + (unsigned char)0 ); + + cRefs = *(( unsigned long __RPC_FAR * )_StubMsg.Buffer)++; + + cIids = *(( unsigned short __RPC_FAR * )_StubMsg.Buffer)++; + + NdrConformantArrayUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&iids, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[360], + (unsigned char)0 ); + + ppQIResults = &_M21; + _M21 = 0; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((IRemUnknown*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> RemQueryInterface( + (IRemUnknown *) ((CStdStubBuffer *)This)->pvServerObject, + ripid, + cRefs, + cIids, + iids, + ppQIResults); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 8U + 8U; + _StubMsg.MaxCount = cIids; + + NdrPointerBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ppQIResults, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[374] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + _StubMsg.MaxCount = cIids; + + NdrPointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ppQIResults, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[374] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *(( HRESULT __RPC_FAR * )_StubMsg.Buffer)++ = _RetVal; + + } + RpcFinally + { + _StubMsg.MaxCount = cIids; + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)ppQIResults, + &__MIDL_TypeFormatString.Format[374] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE IRemUnknown_RemAddRef_Proxy( + IRemUnknown __RPC_FAR * This, + /* [in] */ unsigned short cInterfaceRefs, + /* [size_is][in] */ REMINTERFACEREF __RPC_FAR *InterfaceRefs, + /* [size_is][out] */ HRESULT __RPC_FAR *pResults) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 4); + + + + if(!InterfaceRefs) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pResults) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 2U + 4U; + _StubMsg.MaxCount = cInterfaceRefs; + + NdrConformantArrayBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)InterfaceRefs, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[436] ); + + NdrProxyGetBuffer(This, &_StubMsg); + *(( unsigned short __RPC_FAR * )_StubMsg.Buffer)++ = cInterfaceRefs; + + _StubMsg.MaxCount = cInterfaceRefs; + + NdrConformantArrayMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)InterfaceRefs, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[436] ); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[184] ); + + NdrConformantArrayUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pResults, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[454], + (unsigned char)0 ); + + _RetVal = *(( HRESULT __RPC_FAR * )_StubMsg.Buffer)++; + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _StubMsg.MaxCount = cInterfaceRefs; + + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[450], + ( void __RPC_FAR * )pResults); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB IRemUnknown_RemAddRef_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + REMINTERFACEREF __RPC_FAR *InterfaceRefs; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + unsigned short cInterfaceRefs; + HRESULT __RPC_FAR *pResults; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + ( REMINTERFACEREF __RPC_FAR * )InterfaceRefs = 0; + ( HRESULT __RPC_FAR * )pResults = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[184] ); + + cInterfaceRefs = *(( unsigned short __RPC_FAR * )_StubMsg.Buffer)++; + + NdrConformantArrayUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&InterfaceRefs, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[436], + (unsigned char)0 ); + + pResults = NdrAllocate(&_StubMsg,cInterfaceRefs * 4); + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((IRemUnknown*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> RemAddRef( + (IRemUnknown *) ((CStdStubBuffer *)This)->pvServerObject, + cInterfaceRefs, + InterfaceRefs, + pResults); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U + 7U; + _StubMsg.MaxCount = cInterfaceRefs; + + NdrConformantArrayBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pResults, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[454] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + _StubMsg.MaxCount = cInterfaceRefs; + + NdrConformantArrayMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pResults, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[454] ); + + *(( HRESULT __RPC_FAR * )_StubMsg.Buffer)++ = _RetVal; + + } + RpcFinally + { + if ( pResults ) + _StubMsg.pfnFree( pResults ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE IRemUnknown_RemRelease_Proxy( + IRemUnknown __RPC_FAR * This, + /* [in] */ unsigned short cInterfaceRefs, + /* [size_is][in] */ REMINTERFACEREF __RPC_FAR *InterfaceRefs) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 5); + + + + if(!InterfaceRefs) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 2U + 4U; + _StubMsg.MaxCount = cInterfaceRefs; + + NdrConformantArrayBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)InterfaceRefs, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[436] ); + + NdrProxyGetBuffer(This, &_StubMsg); + *(( unsigned short __RPC_FAR * )_StubMsg.Buffer)++ = cInterfaceRefs; + + _StubMsg.MaxCount = cInterfaceRefs; + + NdrConformantArrayMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)InterfaceRefs, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[436] ); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[196] ); + + _RetVal = *(( HRESULT __RPC_FAR * )_StubMsg.Buffer)++; + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB IRemUnknown_RemRelease_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + REMINTERFACEREF __RPC_FAR *InterfaceRefs; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + unsigned short cInterfaceRefs; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + ( REMINTERFACEREF __RPC_FAR * )InterfaceRefs = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[196] ); + + cInterfaceRefs = *(( unsigned short __RPC_FAR * )_StubMsg.Buffer)++; + + NdrConformantArrayUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&InterfaceRefs, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[436], + (unsigned char)0 ); + + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((IRemUnknown*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> RemRelease( + (IRemUnknown *) ((CStdStubBuffer *)This)->pvServerObject, + cInterfaceRefs, + InterfaceRefs); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U; + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *(( HRESULT __RPC_FAR * )_StubMsg.Buffer)++ = _RetVal; + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + +const CINTERFACE_PROXY_VTABLE(6) _IRemUnknownProxyVtbl = +{ + &IID_IRemUnknown, + IUnknown_QueryInterface_Proxy, + IUnknown_AddRef_Proxy, + IUnknown_Release_Proxy , + IRemUnknown_RemQueryInterface_Proxy , + IRemUnknown_RemAddRef_Proxy , + IRemUnknown_RemRelease_Proxy +}; + + +static const PRPC_STUB_FUNCTION IRemUnknown_table[] = +{ + IRemUnknown_RemQueryInterface_Stub, + IRemUnknown_RemAddRef_Stub, + IRemUnknown_RemRelease_Stub +}; + +const CInterfaceStubVtbl _IRemUnknownStubVtbl = +{ + &IID_IRemUnknown, + 0, + 6, + &IRemUnknown_table[-3], + CStdStubBuffer_METHODS +}; + + +/* Object interface: IRemUnknown2, ver. 0.0, + GUID={0x00000142,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +extern const MIDL_STUB_DESC Object_StubDesc; + + +#pragma code_seg(".orpc") + +HRESULT STDMETHODCALLTYPE IRemUnknown2_RemQueryInterface2_Proxy( + IRemUnknown2 __RPC_FAR * This, + /* [in] */ REFIPID ripid, + /* [in] */ unsigned short cIids, + /* [size_is][in] */ IID __RPC_FAR *iids, + /* [size_is][out] */ HRESULT __RPC_FAR *phr, + /* [size_is][out] */ MInterfacePointer __RPC_FAR *__RPC_FAR *ppMIF) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(ppMIF) + { + *ppMIF = 0; + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 6); + + + + if(!ripid) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!iids) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!phr) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!ppMIF) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U + 5U + 7U; + NdrSimpleStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ripid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[54] ); + + _StubMsg.MaxCount = cIids; + + NdrConformantArrayBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)iids, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[468] ); + + NdrProxyGetBuffer(This, &_StubMsg); + NdrSimpleStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ripid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[54] ); + + *(( unsigned short __RPC_FAR * )_StubMsg.Buffer)++ = cIids; + + _StubMsg.MaxCount = cIids; + + NdrConformantArrayMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)iids, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[468] ); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[204] ); + + NdrConformantArrayUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&phr, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[486], + (unsigned char)0 ); + + NdrConformantArrayUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ppMIF, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[500], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *(( HRESULT __RPC_FAR * )_StubMsg.Buffer)++; + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _StubMsg.MaxCount = cIids; + + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[482], + ( void __RPC_FAR * )phr); + _StubMsg.MaxCount = cIids; + + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[496], + ( void __RPC_FAR * )ppMIF); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB IRemUnknown2_RemQueryInterface2_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + unsigned short cIids; + IID __RPC_FAR *iids; + HRESULT __RPC_FAR *phr; + MInterfacePointer __RPC_FAR *__RPC_FAR *ppMIF; + REFIPID ripid; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + ( REFIPID )ripid = 0; + ( IID __RPC_FAR * )iids = 0; + ( HRESULT __RPC_FAR * )phr = 0; + ( MInterfacePointer __RPC_FAR *__RPC_FAR * )ppMIF = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[204] ); + + NdrSimpleStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ripid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[54], + (unsigned char)0 ); + + cIids = *(( unsigned short __RPC_FAR * )_StubMsg.Buffer)++; + + NdrConformantArrayUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&iids, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[468], + (unsigned char)0 ); + + phr = NdrAllocate(&_StubMsg,cIids * 4); + ppMIF = NdrAllocate(&_StubMsg,cIids * 4); + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((IRemUnknown2*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> RemQueryInterface2( + (IRemUnknown2 *) ((CStdStubBuffer *)This)->pvServerObject, + ripid, + cIids, + iids, + phr, + ppMIF); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U + 7U + 7U; + _StubMsg.MaxCount = cIids; + + NdrConformantArrayBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)phr, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[486] ); + + _StubMsg.MaxCount = cIids; + + NdrConformantArrayBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ppMIF, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[500] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + _StubMsg.MaxCount = cIids; + + NdrConformantArrayMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)phr, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[486] ); + + _StubMsg.MaxCount = cIids; + + NdrConformantArrayMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ppMIF, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[500] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *(( HRESULT __RPC_FAR * )_StubMsg.Buffer)++ = _RetVal; + + } + RpcFinally + { + if ( phr ) + _StubMsg.pfnFree( phr ); + + _StubMsg.MaxCount = cIids; + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)ppMIF, + &__MIDL_TypeFormatString.Format[496] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + +extern const EXPR_EVAL ExprEvalRoutines[]; + +static const MIDL_STUB_DESC Object_StubDesc = + { + 0, + NdrOleAllocate, + NdrOleFree, + 0, + 0, + 0, + ExprEvalRoutines, + 0, + __MIDL_TypeFormatString.Format, + 1, /* -error bounds_check flag */ + 0x10001, /* Ndr library version */ + 0, + 0x50100a4, /* MIDL Version 5.1.164 */ + 0, + 0, + 0, /* notify & notify_flag routine table */ + 1, /* Flags */ + 0, /* Reserved3 */ + 0, /* Reserved4 */ + 0 /* Reserved5 */ + }; + +const CINTERFACE_PROXY_VTABLE(7) _IRemUnknown2ProxyVtbl = +{ + &IID_IRemUnknown2, + IUnknown_QueryInterface_Proxy, + IUnknown_AddRef_Proxy, + IUnknown_Release_Proxy , + IRemUnknown_RemQueryInterface_Proxy , + IRemUnknown_RemAddRef_Proxy , + IRemUnknown_RemRelease_Proxy , + IRemUnknown2_RemQueryInterface2_Proxy +}; + + +static const PRPC_STUB_FUNCTION IRemUnknown2_table[] = +{ + IRemUnknown_RemQueryInterface_Stub, + IRemUnknown_RemAddRef_Stub, + IRemUnknown_RemRelease_Stub, + IRemUnknown2_RemQueryInterface2_Stub +}; + +const CInterfaceStubVtbl _IRemUnknown2StubVtbl = +{ + &IID_IRemUnknown2, + 0, + 7, + &IRemUnknown2_table[-3], + CStdStubBuffer_METHODS +}; + + +/* Standard interface: __MIDL_itf_dcom_0008, ver. 0.0, + GUID={0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} */ + + +/* Standard interface: IOXIDResolver, ver. 0.0, + GUID={0x99fcfec4,0x5260,0x101b,{0xbb,0xcb,0x00,0xaa,0x00,0x21,0x34,0x7a}} */ + + +/* Standard interface: IRemoteActivation, ver. 0.0, + GUID={0x4d9f4ab8,0x7d1c,0x11cf,{0x86,0x1e,0x00,0x20,0xaf,0x6e,0x7c,0x57}} */ + + +/* Standard interface: __MIDL_itf_dcom_0010, ver. 0.0, + GUID={0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} */ + +#pragma data_seg(".rdata") + +static void __RPC_USER IRemoteActivation_ORPC_EXTENTExprEval_0000( PMIDL_STUB_MESSAGE pStubMsg ) +{ + ORPC_EXTENT __RPC_FAR *pS = ( ORPC_EXTENT __RPC_FAR * )(pStubMsg->StackTop - 20); + + pStubMsg->Offset = 0; + pStubMsg->MaxCount = ( unsigned long ) ( pS->size + 7 & ~7 ); +} + +static void __RPC_USER IRemoteActivation_ORPC_EXTENT_ARRAYExprEval_0001( PMIDL_STUB_MESSAGE pStubMsg ) +{ + ORPC_EXTENT_ARRAY __RPC_FAR *pS = ( ORPC_EXTENT_ARRAY __RPC_FAR * )pStubMsg->StackTop; + + pStubMsg->Offset = 0; + pStubMsg->MaxCount = ( unsigned long ) ( pS->size + 1 & ~1 ); +} + +static const EXPR_EVAL ExprEvalRoutines[] = + { + IRemoteActivation_ORPC_EXTENTExprEval_0000 + ,IRemoteActivation_ORPC_EXTENT_ARRAYExprEval_0001 + }; + + +#if !defined(__RPC_WIN32__) +#error Invalid build platform for this stub. +#endif + +static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString = + { + 0, + { + 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0xf, /* FC_IGNORE */ +/* 2 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 4 */ NdrFcShort( 0x2 ), /* Type Offset=2 */ +/* 6 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x6, /* FC_SHORT */ +/* 8 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 10 */ NdrFcShort( 0x6 ), /* Type Offset=6 */ +/* 12 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 14 */ NdrFcShort( 0x10 ), /* Type Offset=16 */ +/* 16 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 18 */ NdrFcShort( 0x2c ), /* Type Offset=44 */ +/* 20 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 22 */ NdrFcShort( 0x42 ), /* Type Offset=66 */ +/* 24 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x10, /* FC_ERROR_STATUS_T */ +/* 26 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0xf, /* FC_IGNORE */ +/* 28 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 30 */ NdrFcShort( 0x2 ), /* Type Offset=2 */ +/* 32 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x10, /* FC_ERROR_STATUS_T */ +/* 34 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0xf, /* FC_IGNORE */ +/* 36 */ + 0x50, /* FC_IN_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 38 */ NdrFcShort( 0x2 ), /* Type Offset=2 */ +/* 40 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x6, /* FC_SHORT */ +/* 42 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x6, /* FC_SHORT */ +/* 44 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x6, /* FC_SHORT */ +/* 46 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 48 */ NdrFcShort( 0x46 ), /* Type Offset=70 */ +/* 50 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 52 */ NdrFcShort( 0x54 ), /* Type Offset=84 */ +/* 54 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 56 */ NdrFcShort( 0x62 ), /* Type Offset=98 */ +/* 58 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x10, /* FC_ERROR_STATUS_T */ +/* 60 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0xf, /* FC_IGNORE */ +/* 62 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x10, /* FC_ERROR_STATUS_T */ +/* 64 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0xf, /* FC_IGNORE */ +/* 66 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 68 */ NdrFcShort( 0x2 ), /* Type Offset=2 */ +/* 70 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x6, /* FC_SHORT */ +/* 72 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 74 */ NdrFcShort( 0x6 ), /* Type Offset=6 */ +/* 76 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 78 */ NdrFcShort( 0x10 ), /* Type Offset=16 */ +/* 80 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 82 */ NdrFcShort( 0x2c ), /* Type Offset=44 */ +/* 84 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 86 */ NdrFcShort( 0x42 ), /* Type Offset=66 */ +/* 88 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 90 */ NdrFcShort( 0x66 ), /* Type Offset=102 */ +/* 92 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x10, /* FC_ERROR_STATUS_T */ +/* 94 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0xf, /* FC_IGNORE */ +/* 96 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 98 */ NdrFcShort( 0x72 ), /* Type Offset=114 */ +/* 100 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 102 */ NdrFcShort( 0xde ), /* Type Offset=222 */ +/* 104 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 106 */ NdrFcShort( 0xf6 ), /* Type Offset=246 */ +/* 108 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 110 */ NdrFcShort( 0xfa ), /* Type Offset=250 */ +/* 112 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 114 */ NdrFcShort( 0xfe ), /* Type Offset=254 */ +/* 116 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 118 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 120 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 122 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 124 */ NdrFcShort( 0x114 ), /* Type Offset=276 */ +/* 126 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x6, /* FC_SHORT */ +/* 128 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 130 */ NdrFcShort( 0x126 ), /* Type Offset=294 */ +/* 132 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 134 */ NdrFcShort( 0x130 ), /* Type Offset=304 */ +/* 136 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 138 */ NdrFcShort( 0x10 ), /* Type Offset=16 */ +/* 140 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 142 */ NdrFcShort( 0x2c ), /* Type Offset=44 */ +/* 144 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 146 */ NdrFcShort( 0x42 ), /* Type Offset=66 */ +/* 148 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 150 */ NdrFcShort( 0x66 ), /* Type Offset=102 */ +/* 152 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 154 */ NdrFcShort( 0x42 ), /* Type Offset=66 */ +/* 156 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 158 */ NdrFcShort( 0x134 ), /* Type Offset=308 */ +/* 160 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 162 */ NdrFcShort( 0x156 ), /* Type Offset=342 */ +/* 164 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 166 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 168 */ NdrFcShort( 0xf6 ), /* Type Offset=246 */ +/* 170 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 172 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x6, /* FC_SHORT */ +/* 174 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 176 */ NdrFcShort( 0x164 ), /* Type Offset=356 */ +/* 178 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 180 */ NdrFcShort( 0x176 ), /* Type Offset=374 */ +/* 182 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 184 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x6, /* FC_SHORT */ +/* 186 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 188 */ NdrFcShort( 0x1a4 ), /* Type Offset=420 */ +/* 190 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 192 */ NdrFcShort( 0x1c2 ), /* Type Offset=450 */ +/* 194 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 196 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x6, /* FC_SHORT */ +/* 198 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 200 */ NdrFcShort( 0x1a4 ), /* Type Offset=420 */ +/* 202 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 204 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 206 */ NdrFcShort( 0xf6 ), /* Type Offset=246 */ +/* 208 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x6, /* FC_SHORT */ +/* 210 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 212 */ NdrFcShort( 0x1d0 ), /* Type Offset=464 */ +/* 214 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 216 */ NdrFcShort( 0x1e2 ), /* Type Offset=482 */ +/* 218 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 220 */ NdrFcShort( 0x1f0 ), /* Type Offset=496 */ +/* 222 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ + + 0x0 + } + }; + +static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString = + { + 0, + { + NdrFcShort( 0x0 ), /* 0 */ +/* 2 */ + 0x11, 0x8, /* FC_RP [simple_pointer] */ +/* 4 */ 0xb, /* FC_HYPER */ + 0x5c, /* FC_PAD */ +/* 6 */ + 0x1b, /* FC_CARRAY */ + 0x1, /* 1 */ +/* 8 */ NdrFcShort( 0x2 ), /* 2 */ +/* 10 */ 0x27, /* Corr desc: parameter, FC_USHORT */ + 0x0, /* */ +#ifndef _ALPHA_ +/* 12 */ NdrFcShort( 0x8 ), /* x86, MIPS, PPC Stack size/offset = 8 */ +#else + NdrFcShort( 0x10 ), /* Alpha Stack size/offset = 16 */ +#endif +/* 14 */ 0x6, /* FC_SHORT */ + 0x5b, /* FC_END */ +/* 16 */ + 0x11, 0x14, /* FC_RP [alloced_on_stack] */ +/* 18 */ NdrFcShort( 0x2 ), /* Offset= 2 (20) */ +/* 20 */ + 0x12, 0x0, /* FC_UP */ +/* 22 */ NdrFcShort( 0xc ), /* Offset= 12 (34) */ +/* 24 */ + 0x1b, /* FC_CARRAY */ + 0x1, /* 1 */ +/* 26 */ NdrFcShort( 0x2 ), /* 2 */ +/* 28 */ 0x7, /* Corr desc: FC_USHORT */ + 0x0, /* */ +/* 30 */ NdrFcShort( 0xfffc ), /* -4 */ +/* 32 */ 0x6, /* FC_SHORT */ + 0x5b, /* FC_END */ +/* 34 */ + 0x17, /* FC_CSTRUCT */ + 0x1, /* 1 */ +/* 36 */ NdrFcShort( 0x4 ), /* 4 */ +/* 38 */ NdrFcShort( 0xfffffff2 ), /* Offset= -14 (24) */ +/* 40 */ 0x6, /* FC_SHORT */ + 0x6, /* FC_SHORT */ +/* 42 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 44 */ + 0x11, 0x4, /* FC_RP [alloced_on_stack] */ +/* 46 */ NdrFcShort( 0x8 ), /* Offset= 8 (54) */ +/* 48 */ + 0x1d, /* FC_SMFARRAY */ + 0x0, /* 0 */ +/* 50 */ NdrFcShort( 0x8 ), /* 8 */ +/* 52 */ 0x2, /* FC_CHAR */ + 0x5b, /* FC_END */ +/* 54 */ + 0x15, /* FC_STRUCT */ + 0x3, /* 3 */ +/* 56 */ NdrFcShort( 0x10 ), /* 16 */ +/* 58 */ 0x8, /* FC_LONG */ + 0x6, /* FC_SHORT */ +/* 60 */ 0x6, /* FC_SHORT */ + 0x4c, /* FC_EMBEDDED_COMPLEX */ +/* 62 */ 0x0, /* 0 */ + NdrFcShort( 0xfffffff1 ), /* Offset= -15 (48) */ + 0x5b, /* FC_END */ +/* 66 */ + 0x11, 0xc, /* FC_RP [alloced_on_stack] [simple_pointer] */ +/* 68 */ 0x8, /* FC_LONG */ + 0x5c, /* FC_PAD */ +/* 70 */ + 0x12, /* FC_UP */ + 0x0, /* 0 */ +/* 72 */ NdrFcShort( 0x2 ), /* Offset= 2 (74) */ +/* 74 */ + 0x1b, /* FC_CARRAY */ + 0x7, /* 7 */ +/* 76 */ NdrFcShort( 0x8 ), /* 8 */ +/* 78 */ 0x27, /* Corr desc: parameter, FC_USHORT */ + 0x0, /* */ +#ifndef _ALPHA_ +/* 80 */ NdrFcShort( 0xc ), /* x86, MIPS, PPC Stack size/offset = 12 */ +#else + NdrFcShort( 0x18 ), /* Alpha Stack size/offset = 24 */ +#endif +/* 82 */ 0xb, /* FC_HYPER */ + 0x5b, /* FC_END */ +/* 84 */ + 0x12, /* FC_UP */ + 0x0, /* 0 */ +/* 86 */ NdrFcShort( 0x2 ), /* Offset= 2 (88) */ +/* 88 */ + 0x1b, /* FC_CARRAY */ + 0x7, /* 7 */ +/* 90 */ NdrFcShort( 0x8 ), /* 8 */ +/* 92 */ 0x27, /* Corr desc: parameter, FC_USHORT */ + 0x0, /* */ +#ifndef _ALPHA_ +/* 94 */ NdrFcShort( 0x10 ), /* x86, MIPS, PPC Stack size/offset = 16 */ +#else + NdrFcShort( 0x20 ), /* Alpha Stack size/offset = 32 */ +#endif +/* 96 */ 0xb, /* FC_HYPER */ + 0x5b, /* FC_END */ +/* 98 */ + 0x11, 0xc, /* FC_RP [alloced_on_stack] [simple_pointer] */ +/* 100 */ 0x6, /* FC_SHORT */ + 0x5c, /* FC_PAD */ +/* 102 */ + 0x11, 0x4, /* FC_RP [alloced_on_stack] */ +/* 104 */ NdrFcShort( 0x2 ), /* Offset= 2 (106) */ +/* 106 */ + 0x15, /* FC_STRUCT */ + 0x1, /* 1 */ +/* 108 */ NdrFcShort( 0x4 ), /* 4 */ +/* 110 */ 0x6, /* FC_SHORT */ + 0x6, /* FC_SHORT */ +/* 112 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 114 */ + 0x11, 0x0, /* FC_RP */ +/* 116 */ NdrFcShort( 0x4c ), /* Offset= 76 (192) */ +/* 118 */ + 0x1b, /* FC_CARRAY */ + 0x0, /* 0 */ +/* 120 */ NdrFcShort( 0x1 ), /* 1 */ +/* 122 */ 0x0, /* Corr desc: */ + 0x59, /* FC_CALLBACK */ +/* 124 */ NdrFcShort( 0x0 ), /* 0 */ +/* 126 */ 0x1, /* FC_BYTE */ + 0x5b, /* FC_END */ +/* 128 */ + 0x17, /* FC_CSTRUCT */ + 0x3, /* 3 */ +/* 130 */ NdrFcShort( 0x14 ), /* 20 */ +/* 132 */ NdrFcShort( 0xfffffff2 ), /* Offset= -14 (118) */ +/* 134 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 136 */ NdrFcShort( 0xffffffae ), /* Offset= -82 (54) */ +/* 138 */ 0x8, /* FC_LONG */ + 0x5b, /* FC_END */ +/* 140 */ + 0x1b, /* FC_CARRAY */ + 0x3, /* 3 */ +/* 142 */ NdrFcShort( 0x4 ), /* 4 */ +/* 144 */ 0x10, /* Corr desc: field pointer, */ + 0x59, /* FC_CALLBACK */ +/* 146 */ NdrFcShort( 0x1 ), /* 1 */ +/* 148 */ + 0x4b, /* FC_PP */ + 0x5c, /* FC_PAD */ +/* 150 */ + 0x48, /* FC_VARIABLE_REPEAT */ + 0x49, /* FC_FIXED_OFFSET */ +/* 152 */ NdrFcShort( 0x4 ), /* 4 */ +/* 154 */ NdrFcShort( 0x0 ), /* 0 */ +/* 156 */ NdrFcShort( 0x1 ), /* 1 */ +/* 158 */ NdrFcShort( 0x0 ), /* 0 */ +/* 160 */ NdrFcShort( 0x0 ), /* 0 */ +/* 162 */ 0x12, 0x0, /* FC_UP */ +/* 164 */ NdrFcShort( 0xffffffdc ), /* Offset= -36 (128) */ +/* 166 */ + 0x5b, /* FC_END */ + + 0x8, /* FC_LONG */ +/* 168 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 170 */ + 0x16, /* FC_PSTRUCT */ + 0x3, /* 3 */ +/* 172 */ NdrFcShort( 0xc ), /* 12 */ +/* 174 */ + 0x4b, /* FC_PP */ + 0x5c, /* FC_PAD */ +/* 176 */ + 0x46, /* FC_NO_REPEAT */ + 0x5c, /* FC_PAD */ +/* 178 */ NdrFcShort( 0x8 ), /* 8 */ +/* 180 */ NdrFcShort( 0x8 ), /* 8 */ +/* 182 */ 0x12, 0x0, /* FC_UP */ +/* 184 */ NdrFcShort( 0xffffffd4 ), /* Offset= -44 (140) */ +/* 186 */ + 0x5b, /* FC_END */ + + 0x8, /* FC_LONG */ +/* 188 */ 0x8, /* FC_LONG */ + 0x8, /* FC_LONG */ +/* 190 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 192 */ + 0x16, /* FC_PSTRUCT */ + 0x3, /* 3 */ +/* 194 */ NdrFcShort( 0x20 ), /* 32 */ +/* 196 */ + 0x4b, /* FC_PP */ + 0x5c, /* FC_PAD */ +/* 198 */ + 0x46, /* FC_NO_REPEAT */ + 0x5c, /* FC_PAD */ +/* 200 */ NdrFcShort( 0x1c ), /* 28 */ +/* 202 */ NdrFcShort( 0x1c ), /* 28 */ +/* 204 */ 0x12, 0x0, /* FC_UP */ +/* 206 */ NdrFcShort( 0xffffffdc ), /* Offset= -36 (170) */ +/* 208 */ + 0x5b, /* FC_END */ + + 0x4c, /* FC_EMBEDDED_COMPLEX */ +/* 210 */ 0x0, /* 0 */ + NdrFcShort( 0xffffff97 ), /* Offset= -105 (106) */ + 0x8, /* FC_LONG */ +/* 214 */ 0x8, /* FC_LONG */ + 0x4c, /* FC_EMBEDDED_COMPLEX */ +/* 216 */ 0x0, /* 0 */ + NdrFcShort( 0xffffff5d ), /* Offset= -163 (54) */ + 0x8, /* FC_LONG */ +/* 220 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 222 */ + 0x11, 0x4, /* FC_RP [alloced_on_stack] */ +/* 224 */ NdrFcShort( 0x2 ), /* Offset= 2 (226) */ +/* 226 */ + 0x16, /* FC_PSTRUCT */ + 0x3, /* 3 */ +/* 228 */ NdrFcShort( 0x8 ), /* 8 */ +/* 230 */ + 0x4b, /* FC_PP */ + 0x5c, /* FC_PAD */ +/* 232 */ + 0x46, /* FC_NO_REPEAT */ + 0x5c, /* FC_PAD */ +/* 234 */ NdrFcShort( 0x4 ), /* 4 */ +/* 236 */ NdrFcShort( 0x4 ), /* 4 */ +/* 238 */ 0x12, 0x0, /* FC_UP */ +/* 240 */ NdrFcShort( 0xffffffba ), /* Offset= -70 (170) */ +/* 242 */ + 0x5b, /* FC_END */ + + 0x8, /* FC_LONG */ +/* 244 */ 0x8, /* FC_LONG */ + 0x5b, /* FC_END */ +/* 246 */ + 0x11, 0x0, /* FC_RP */ +/* 248 */ NdrFcShort( 0xffffff3e ), /* Offset= -194 (54) */ +/* 250 */ + 0x12, 0x8, /* FC_UP [simple_pointer] */ +/* 252 */ + 0x25, /* FC_C_WSTRING */ + 0x5c, /* FC_PAD */ +/* 254 */ + 0x12, 0x0, /* FC_UP */ +/* 256 */ NdrFcShort( 0xc ), /* Offset= 12 (268) */ +/* 258 */ + 0x1b, /* FC_CARRAY */ + 0x0, /* 0 */ +/* 260 */ NdrFcShort( 0x1 ), /* 1 */ +/* 262 */ 0x9, /* Corr desc: FC_ULONG */ + 0x0, /* */ +/* 264 */ NdrFcShort( 0xfffc ), /* -4 */ +/* 266 */ 0x2, /* FC_CHAR */ + 0x5b, /* FC_END */ +/* 268 */ + 0x17, /* FC_CSTRUCT */ + 0x3, /* 3 */ +/* 270 */ NdrFcShort( 0x4 ), /* 4 */ +/* 272 */ NdrFcShort( 0xfffffff2 ), /* Offset= -14 (258) */ +/* 274 */ 0x8, /* FC_LONG */ + 0x5b, /* FC_END */ +/* 276 */ + 0x12, 0x0, /* FC_UP */ +/* 278 */ NdrFcShort( 0x2 ), /* Offset= 2 (280) */ +/* 280 */ + 0x1b, /* FC_CARRAY */ + 0x3, /* 3 */ +/* 282 */ NdrFcShort( 0x10 ), /* 16 */ +/* 284 */ 0x29, /* Corr desc: parameter, FC_ULONG */ + 0x0, /* */ +#ifndef _ALPHA_ +/* 286 */ NdrFcShort( 0x20 ), /* x86, MIPS, PPC Stack size/offset = 32 */ +#else + NdrFcShort( 0x40 ), /* Alpha Stack size/offset = 64 */ +#endif +/* 288 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 290 */ NdrFcShort( 0xffffff14 ), /* Offset= -236 (54) */ +/* 292 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 294 */ + 0x1b, /* FC_CARRAY */ + 0x1, /* 1 */ +/* 296 */ NdrFcShort( 0x2 ), /* 2 */ +/* 298 */ 0x27, /* Corr desc: parameter, FC_USHORT */ + 0x0, /* */ +#ifndef _ALPHA_ +/* 300 */ NdrFcShort( 0x28 ), /* x86, MIPS, PPC Stack size/offset = 40 */ +#else + NdrFcShort( 0x50 ), /* Alpha Stack size/offset = 80 */ +#endif +/* 302 */ 0x6, /* FC_SHORT */ + 0x5b, /* FC_END */ +/* 304 */ + 0x11, 0xc, /* FC_RP [alloced_on_stack] [simple_pointer] */ +/* 306 */ 0xb, /* FC_HYPER */ + 0x5c, /* FC_PAD */ +/* 308 */ + 0x11, 0x0, /* FC_RP */ +/* 310 */ NdrFcShort( 0x2 ), /* Offset= 2 (312) */ +/* 312 */ + 0x1b, /* FC_CARRAY */ + 0x3, /* 3 */ +/* 314 */ NdrFcShort( 0x4 ), /* 4 */ +/* 316 */ 0x29, /* Corr desc: parameter, FC_ULONG */ + 0x0, /* */ +#ifndef _ALPHA_ +/* 318 */ NdrFcShort( 0x20 ), /* x86, MIPS, PPC Stack size/offset = 32 */ +#else + NdrFcShort( 0x40 ), /* Alpha Stack size/offset = 64 */ +#endif +/* 320 */ + 0x4b, /* FC_PP */ + 0x5c, /* FC_PAD */ +/* 322 */ + 0x48, /* FC_VARIABLE_REPEAT */ + 0x49, /* FC_FIXED_OFFSET */ +/* 324 */ NdrFcShort( 0x4 ), /* 4 */ +/* 326 */ NdrFcShort( 0x0 ), /* 0 */ +/* 328 */ NdrFcShort( 0x1 ), /* 1 */ +/* 330 */ NdrFcShort( 0x0 ), /* 0 */ +/* 332 */ NdrFcShort( 0x0 ), /* 0 */ +/* 334 */ 0x12, 0x0, /* FC_UP */ +/* 336 */ NdrFcShort( 0xffffffbc ), /* Offset= -68 (268) */ +/* 338 */ + 0x5b, /* FC_END */ + + 0x8, /* FC_LONG */ +/* 340 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 342 */ + 0x11, 0x0, /* FC_RP */ +/* 344 */ NdrFcShort( 0x2 ), /* Offset= 2 (346) */ +/* 346 */ + 0x1b, /* FC_CARRAY */ + 0x3, /* 3 */ +/* 348 */ NdrFcShort( 0x4 ), /* 4 */ +/* 350 */ 0x29, /* Corr desc: parameter, FC_ULONG */ + 0x0, /* */ +#ifndef _ALPHA_ +/* 352 */ NdrFcShort( 0x20 ), /* x86, MIPS, PPC Stack size/offset = 32 */ +#else + NdrFcShort( 0x40 ), /* Alpha Stack size/offset = 64 */ +#endif +/* 354 */ 0x8, /* FC_LONG */ + 0x5b, /* FC_END */ +/* 356 */ + 0x11, 0x0, /* FC_RP */ +/* 358 */ NdrFcShort( 0x2 ), /* Offset= 2 (360) */ +/* 360 */ + 0x1b, /* FC_CARRAY */ + 0x3, /* 3 */ +/* 362 */ NdrFcShort( 0x10 ), /* 16 */ +/* 364 */ 0x27, /* Corr desc: parameter, FC_USHORT */ + 0x0, /* */ +#ifndef _ALPHA_ +/* 366 */ NdrFcShort( 0xc ), /* x86, MIPS, PPC Stack size/offset = 12 */ +#else + NdrFcShort( 0x18 ), /* Alpha Stack size/offset = 24 */ +#endif +/* 368 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 370 */ NdrFcShort( 0xfffffec4 ), /* Offset= -316 (54) */ +/* 372 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 374 */ + 0x11, 0x14, /* FC_RP [alloced_on_stack] */ +/* 376 */ NdrFcShort( 0x2 ), /* Offset= 2 (378) */ +/* 378 */ + 0x13, 0x0, /* FC_OP */ +/* 380 */ NdrFcShort( 0x1a ), /* Offset= 26 (406) */ +/* 382 */ + 0x15, /* FC_STRUCT */ + 0x7, /* 7 */ +/* 384 */ NdrFcShort( 0x28 ), /* 40 */ +/* 386 */ 0x8, /* FC_LONG */ + 0x8, /* FC_LONG */ +/* 388 */ 0x39, /* FC_ALIGNM8 */ + 0xb, /* FC_HYPER */ +/* 390 */ 0xb, /* FC_HYPER */ + 0x4c, /* FC_EMBEDDED_COMPLEX */ +/* 392 */ 0x0, /* 0 */ + NdrFcShort( 0xfffffead ), /* Offset= -339 (54) */ + 0x5b, /* FC_END */ +/* 396 */ + 0x15, /* FC_STRUCT */ + 0x7, /* 7 */ +/* 398 */ NdrFcShort( 0x30 ), /* 48 */ +/* 400 */ 0x8, /* FC_LONG */ + 0x4c, /* FC_EMBEDDED_COMPLEX */ +/* 402 */ 0x4, /* 4 */ + NdrFcShort( 0xffffffeb ), /* Offset= -21 (382) */ + 0x5b, /* FC_END */ +/* 406 */ + 0x1b, /* FC_CARRAY */ + 0x7, /* 7 */ +/* 408 */ NdrFcShort( 0x30 ), /* 48 */ +/* 410 */ 0x27, /* Corr desc: parameter, FC_USHORT */ + 0x0, /* */ +#ifndef _ALPHA_ +/* 412 */ NdrFcShort( 0xc ), /* x86, MIPS, PPC Stack size/offset = 12 */ +#else + NdrFcShort( 0x18 ), /* Alpha Stack size/offset = 24 */ +#endif +/* 414 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 416 */ NdrFcShort( 0xffffffec ), /* Offset= -20 (396) */ +/* 418 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 420 */ + 0x11, 0x0, /* FC_RP */ +/* 422 */ NdrFcShort( 0xe ), /* Offset= 14 (436) */ +/* 424 */ + 0x15, /* FC_STRUCT */ + 0x3, /* 3 */ +/* 426 */ NdrFcShort( 0x18 ), /* 24 */ +/* 428 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 430 */ NdrFcShort( 0xfffffe88 ), /* Offset= -376 (54) */ +/* 432 */ 0x8, /* FC_LONG */ + 0x8, /* FC_LONG */ +/* 434 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 436 */ + 0x1b, /* FC_CARRAY */ + 0x3, /* 3 */ +/* 438 */ NdrFcShort( 0x18 ), /* 24 */ +/* 440 */ 0x27, /* Corr desc: parameter, FC_USHORT */ + 0x0, /* */ +#ifndef _ALPHA_ +/* 442 */ NdrFcShort( 0x4 ), /* x86, MIPS, PPC Stack size/offset = 4 */ +#else + NdrFcShort( 0x8 ), /* Alpha Stack size/offset = 8 */ +#endif +/* 444 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 446 */ NdrFcShort( 0xffffffea ), /* Offset= -22 (424) */ +/* 448 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 450 */ + 0x11, 0x0, /* FC_RP */ +/* 452 */ NdrFcShort( 0x2 ), /* Offset= 2 (454) */ +/* 454 */ + 0x1b, /* FC_CARRAY */ + 0x3, /* 3 */ +/* 456 */ NdrFcShort( 0x4 ), /* 4 */ +/* 458 */ 0x27, /* Corr desc: parameter, FC_USHORT */ + 0x0, /* */ +#ifndef _ALPHA_ +/* 460 */ NdrFcShort( 0x4 ), /* x86, MIPS, PPC Stack size/offset = 4 */ +#else + NdrFcShort( 0x8 ), /* Alpha Stack size/offset = 8 */ +#endif +/* 462 */ 0x8, /* FC_LONG */ + 0x5b, /* FC_END */ +/* 464 */ + 0x11, 0x0, /* FC_RP */ +/* 466 */ NdrFcShort( 0x2 ), /* Offset= 2 (468) */ +/* 468 */ + 0x1b, /* FC_CARRAY */ + 0x3, /* 3 */ +/* 470 */ NdrFcShort( 0x10 ), /* 16 */ +/* 472 */ 0x27, /* Corr desc: parameter, FC_USHORT */ + 0x0, /* */ +#ifndef _ALPHA_ +/* 474 */ NdrFcShort( 0x8 ), /* x86, MIPS, PPC Stack size/offset = 8 */ +#else + NdrFcShort( 0x10 ), /* Alpha Stack size/offset = 16 */ +#endif +/* 476 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 478 */ NdrFcShort( 0xfffffe58 ), /* Offset= -424 (54) */ +/* 480 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 482 */ + 0x11, 0x0, /* FC_RP */ +/* 484 */ NdrFcShort( 0x2 ), /* Offset= 2 (486) */ +/* 486 */ + 0x1b, /* FC_CARRAY */ + 0x3, /* 3 */ +/* 488 */ NdrFcShort( 0x4 ), /* 4 */ +/* 490 */ 0x27, /* Corr desc: parameter, FC_USHORT */ + 0x0, /* */ +#ifndef _ALPHA_ +/* 492 */ NdrFcShort( 0x8 ), /* x86, MIPS, PPC Stack size/offset = 8 */ +#else + NdrFcShort( 0x10 ), /* Alpha Stack size/offset = 16 */ +#endif +/* 494 */ 0x8, /* FC_LONG */ + 0x5b, /* FC_END */ +/* 496 */ + 0x11, 0x0, /* FC_RP */ +/* 498 */ NdrFcShort( 0x2 ), /* Offset= 2 (500) */ +/* 500 */ + 0x1b, /* FC_CARRAY */ + 0x3, /* 3 */ +/* 502 */ NdrFcShort( 0x4 ), /* 4 */ +/* 504 */ 0x27, /* Corr desc: parameter, FC_USHORT */ + 0x0, /* */ +#ifndef _ALPHA_ +/* 506 */ NdrFcShort( 0x8 ), /* x86, MIPS, PPC Stack size/offset = 8 */ +#else + NdrFcShort( 0x10 ), /* Alpha Stack size/offset = 16 */ +#endif +/* 508 */ + 0x4b, /* FC_PP */ + 0x5c, /* FC_PAD */ +/* 510 */ + 0x48, /* FC_VARIABLE_REPEAT */ + 0x49, /* FC_FIXED_OFFSET */ +/* 512 */ NdrFcShort( 0x4 ), /* 4 */ +/* 514 */ NdrFcShort( 0x0 ), /* 0 */ +/* 516 */ NdrFcShort( 0x1 ), /* 1 */ +/* 518 */ NdrFcShort( 0x0 ), /* 0 */ +/* 520 */ NdrFcShort( 0x0 ), /* 0 */ +/* 522 */ 0x13, 0x0, /* FC_OP */ +/* 524 */ NdrFcShort( 0xffffff00 ), /* Offset= -256 (268) */ +/* 526 */ + 0x5b, /* FC_END */ + + 0x8, /* FC_LONG */ +/* 528 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ + + 0x0 + } + }; + +const CInterfaceProxyVtbl * _dcom_ProxyVtblList[] = +{ + ( CInterfaceProxyVtbl *) &_IRemUnknownProxyVtbl, + ( CInterfaceProxyVtbl *) &_IRemUnknown2ProxyVtbl, + 0 +}; + +const CInterfaceStubVtbl * _dcom_StubVtblList[] = +{ + ( CInterfaceStubVtbl *) &_IRemUnknownStubVtbl, + ( CInterfaceStubVtbl *) &_IRemUnknown2StubVtbl, + 0 +}; + +PCInterfaceName const _dcom_InterfaceNamesList[] = +{ + "IRemUnknown", + "IRemUnknown2", + 0 +}; + + +#define _dcom_CHECK_IID(n) IID_GENERIC_CHECK_IID( _dcom, pIID, n) + +int __stdcall _dcom_IID_Lookup( const IID * pIID, int * pIndex ) +{ + IID_BS_LOOKUP_SETUP + + IID_BS_LOOKUP_INITIAL_TEST( _dcom, 2, 1 ) + IID_BS_LOOKUP_RETURN_RESULT( _dcom, 2, *pIndex ) + +} + +const ExtendedProxyFileInfo dcom_ProxyFileInfo = +{ + (PCInterfaceProxyVtblList *) & _dcom_ProxyVtblList, + (PCInterfaceStubVtblList *) & _dcom_StubVtblList, + (const PCInterfaceName * ) & _dcom_InterfaceNamesList, + 0, // no delegation + & _dcom_IID_Lookup, + 2, + 1, + 0, /* table of [async_uuid] interfaces */ + 0, /* Filler1 */ + 0, /* Filler2 */ + 0 /* Filler3 */ +}; --- /dev/null 2003-01-30 10:24:37.000000000 +0000 +++ dlls/ole32/proxy.c 2003-10-01 16:28:24.000000000 +0100 @@ -0,0 +1,2326 @@ +/* + * Proxy/Stub implementation + * + * Copyright 2001 Ove KÃ¥ven, TransGaming Technologies + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <string.h> +#include <stdarg.h> + +#define NONAMELESSUNION +#define NONAMELESSSTRUCT + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winerror.h" +#include "ole2.h" +#include "rpcproxy.h" +#include "wine/unicode.h" + +#include "objbase.h" +#include "compobj_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +static void __RPC_STUB COM_RpcDispatch(PRPC_MESSAGE Message); +static LPRPCCHANNELBUFFER RpcChannel_Create(RPC_BINDING_HANDLE bind, DWORD model, DWORD tid); +void COM_FindXIf2(APARTMENT *apt, XOBJECT *obj, XIF **xif, REFIID riid); +void COM_FindXObj(APARTMENT *apt, OID oid, IPID ipid, XOBJECT **xobj, XIF **xif); +void COM_ExtAddRef(APARTMENT *apt, XOBJECT *xobj, XIF *xif, DWORD refs); +void COM_ExtRelease(APARTMENT *apt, XOBJECT *xobj, XIF *xif, DWORD refs); +void COM_CreateIObj(APARTMENT *apt, OXID oxid, OID oid, IPID ipid, IOBJECT **iobj, RPC_BINDING_HANDLE bind); +static HRESULT COM_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv); + +/* the standard marshaller returns a special GUID */ +static const CLSID CLSID_StdMarshal = { + 0x1B, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46} +}; + +/* CLSID for ole32's builtin marshalers + * (referenced by winedefault.reg) */ +static const CLSID CLSID_PSFactoryBuffer = { + 0x320, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46} +}; + +const IID IID_IRemUnknown = { + 0x131, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46} +}; + +const IID IID_IRemUnknown2 = { + 0x142, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46} +}; + +static LONG initRPC; + +static RPC_DISPATCH_FUNCTION rpc_dispatch_table[1] = { COM_RpcDispatch }; +static RPC_DISPATCH_TABLE rpc_dispatch = { 1, rpc_dispatch_table }; + +typedef struct tagREGIF { + struct tagREGIF *next; + RPC_SERVER_INTERFACE If; +} REGIF; + +static REGIF *RegIf; +static CRITICAL_SECTION csRegIf; +static CRITICAL_SECTION_DEBUG csRegIf_debug = +{ + 0, 0, &csRegIf, + { &csRegIf_debug.ProcessLocksList, &csRegIf_debug.ProcessLocksList }, + 0, 0, { 0, (DWORD)(__FILE__ ": dcom registered server interfaces") } +}; +static CRITICAL_SECTION csRegIf = { &csRegIf_debug, -1, 0, 0, 0, 0 }; + +static LPRPCCHANNELBUFFER rpc_server_chan; +static RPC_IF_HANDLE rpc_IRemUnknown; + +/* since I don't know how MS generates IPIDs, I'll just + * combine the lower 32 bits of the OXID with the OID + * and an interface counter */ +typedef struct tagIIPID { + OID oid; + DWORD ifc; + DWORD oxid; +} IIPID; + +static RPC_IF_HANDLE COM_RpcRegIf(REFIID riid) +{ + REGIF *cif; + BOOL reg = FALSE; + + TRACE("(%s)\n", debugstr_guid(riid)); + EnterCriticalSection(&csRegIf); + TRACE("Entered\n"); + for (cif = RegIf; + cif && !IsEqualGUID(&cif->If.InterfaceId.SyntaxGUID, riid); + cif = cif->next); + if (!cif) { + TRACE("Creating new interface\n"); + cif = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(REGIF)); + cif->If.Length = sizeof(RPC_SERVER_INTERFACE); + cif->If.InterfaceId.SyntaxGUID = *riid; + cif->If.DispatchTable = &rpc_dispatch; + cif->next = RegIf; + RegIf = cif; + reg = TRUE; + } + LeaveCriticalSection(&csRegIf); + if (reg) { + TRACE("Calling RpcServerRegisterIfEx\n"); + RpcServerRegisterIfEx((RPC_IF_HANDLE)&cif->If, + NULL, NULL, + RPC_IF_OLE | RPC_IF_AUTOLISTEN, + RPC_C_LISTEN_MAX_CALLS_DEFAULT, + NULL); + } + return (RPC_IF_HANDLE)&cif->If; +} + +void COM_RpcInit(void) +{ + if (!InterlockedExchange(&initRPC, 1)) { + LPSTR eps; + + UuidToStringA((UUID*)&MTA.oxid, &eps); + RpcServerUseProtseqEpA("ncalrpc", + RPC_C_PROTSEQ_MAX_REQS_DEFAULT, + eps, NULL); + RpcStringFreeA(&eps); + rpc_server_chan = RpcChannel_Create(0, COINIT_MULTITHREADED, 0); + rpc_IRemUnknown = COM_RpcRegIf(&IID_IRemUnknown); + } +} + +void COM_RpcExportClass(REFCLSID rclsid, DWORD dwCtx) +{ + RPC_BINDING_VECTOR *bind; + UUID_VECTOR objs; + + if (dwCtx == MSHCTX_INPROC) return; + + COM_RpcInit(); + /* I don't think using the RPC endpoint mapper is really the right place to + * register class objects, but it'll do for now */ + objs.Count = 1; + objs.Uuid[0] = (UUID*)rclsid; + RpcServerInqBindings(&bind); + /* FIXME: IRemUnknown is not the right interface for this, we should + * rather implement IRemoteActivation, but I don't wanna right now */ + RpcEpRegisterA(rpc_IRemUnknown, bind, &objs, NULL); + RpcBindingVectorFree(&bind); +} + +HRESULT COM_RpcImportClass(LPVOID *ppv, REFCLSID rclsid, REFIID riid, LPSTR server) +{ + APARTMENT *apt = COM_CurrentApt(); + LPSTR uuid = NULL, sbind = NULL; + RPC_BINDING_HANDLE bind = NULL; + RPC_STATUS status; + + COM_RpcInit(); /* temporary */ + + *ppv = NULL; + UuidToStringA((UUID*)rclsid, &uuid); + /* we only do local connections for now */ + RpcStringBindingComposeA(uuid, "ncalrpc", NULL, NULL, NULL, &sbind); + status = RpcBindingFromStringBindingA(sbind, &bind); + RpcStringFreeA(&sbind); + if (status != RPC_S_OK) return status; + /* use the endpoint mapper entry we made in COM_RpcExportClass */ + status = RpcEpResolveBinding(bind, rpc_IRemUnknown); + if (status == RPC_S_OK) { + /* we have a fully bound handle, get the class object */ + /* as a hack, we use IRemUnknown with the clsid as the ipid, + * since we haven't implemented IRemoteActivation yet */ + IOBJECT *obj; + + COM_CreateIObj(apt, 0, 0, *rclsid, &obj, bind); + if (obj) { + status = IRemUnknown_QueryInterface((LPREMUNKNOWN)obj, riid, ppv); + IRemUnknown_Release((LPREMUNKNOWN)obj); + } + else status = CO_E_OBJNOTCONNECTED; + } + else RpcBindingFree(&bind); + return status; +} + +static void __RPC_STUB COM_RpcDispatch(PRPC_MESSAGE pMsg) +{ + APARTMENT *apt = COM_CurrentApt(); + PRPC_SERVER_INTERFACE sif; + IID iid; + STDOBJREF oref; + HRESULT hr; + XOBJECT *xobj; + XIF *xif; + LPRPCSTUBBUFFER stub; + + TRACE("(%p)\n", pMsg); + sif = pMsg->RpcInterfaceInformation; + iid = sif->InterfaceId.SyntaxGUID; + RpcBindingInqObject(pMsg->Handle, &oref.ipid); + TRACE(" iid %s\n", debugstr_guid(&iid)); + TRACE(" method %d\n", pMsg->ProcNum); + + if (!apt) apt = &MTA; + + /* to support the hack we use in COM_RpcImportClass, + * first check whether the IPID is an exported clas + */ + hr = COM_GetRegisteredClassObject(&oref.ipid, NULL, + &oref, NULL); + /* if found: hr = S_OK, oref.ipid replaced + * if not found: hr = S_FALSE, oref.ipid unchanged + */ + if (FAILED(hr)) { + /* we need to implement IRemoteActivation */ + FIXME("can't handle custom-marshaled class object\n"); + return; + } + + /* get OID */ + oref.oid = ((IIPID*)&oref.ipid)->oid; + /* recreate OXID (see compobj.c for OXID generation) */ + oref.oxid = ((IIPID*)&oref.ipid)->oxid | MTA.oxid; + + TRACE(" oxid %llx\n", oref.oxid); + TRACE(" oid %llx\n", oref.oid); + TRACE(" ipid %s\n", debugstr_guid(&oref.ipid)); + + if (oref.oxid != apt->oxid) { + HWND win; + + if (oref.oxid == MTA.oxid) { + FIXME("mysterious RPC STA found - aiee\n"); + return; + } + win = COM_GetApartmentWin(oref.oxid); + if (win) { + TRACE("dispatching to STA (hwnd=%08x)\n", win); + SendMessageA(win, WM_USER, 0, (LPARAM)pMsg); + } else { + ERR("failed to dispatch to STA\n"); + } + return; + } + + COM_FindXObj(apt, oref.oid, oref.ipid, &xobj, NULL); + if (!xobj) { + ERR("requested object not found\n"); + return; + } + + TRACE(" object=%p\n", xobj->obj); + + /* handle IRemUnknown specially, since we haven't properly + * implemented the apartment objects (and IOXIDResolver) yet */ + if (IsEqualGUID(&iid, &IID_IRemUnknown)) { + stub = (LPRPCSTUBBUFFER)xobj; + } + else { + /* our proxies use the same RPC binding for all the interfaces, + * so we get the same IPID for them all, so we'll use the IID + * instead of the IPID to find the actual interface stub */ + COM_FindXIf2(apt, xobj, &xif, &iid); + if (!xif) { + ERR("requested interface not found\n"); + return; + } + TRACE(" interface=%p\n", xif->iface); + stub = xif->stub; + } + + TRACE(" stub=%p\n", stub); + if (!stub) { + ERR("stub not found\n"); + return; + } + + /* FIXME: handle ORPCTHIS and ORPCTHAT */ + + IRpcStubBuffer_Invoke(stub, (RPCOLEMESSAGE*)pMsg, rpc_server_chan); +} + +LRESULT CALLBACK COM_AptWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_USER: + TRACE("received RPC message\n"); + COM_RpcDispatch((PRPC_MESSAGE)lParam); + break; + default: + return DefWindowProcA(hWnd, msg, wParam, lParam); + } + return 0; +} + +/* COM_GetPSFactory [internal]: + * Given an interface ID riid, this function returns an IPSFactoryBuffer + * interface which can be used to create marshalling proxies or stubs for + * the given interface. */ +static HRESULT COM_GetPSFactory(REFIID riid, LPPSFACTORYBUFFER *pPS) +{ + HRESULT hr; + CLSID clsid; + hr = CoGetPSClsid(riid, &clsid); + if (FAILED(hr)) return hr; + hr = CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, + &IID_IPSFactoryBuffer, (LPVOID *)pPS); + return hr; +} + +/******************** CHANNEL OBJECT ********************/ + +#define MAX_THREADS 128 + +typedef struct { + ICOM_VTABLE(IRpcChannelBuffer) *lpVtbl; + DWORD ref, tid; + RPC_BINDING_HANDLE bind; + HANDLE done; +} RpcChannelImpl; + +typedef struct _RpcRequest { + struct _RpcRequest *next; + PRPC_MESSAGE msg; + RPC_STATUS ret; + HANDLE done; +} RpcRequest; + +static HANDLE worker_sem; +static DWORD worker_count, worker_free; +static CRITICAL_SECTION creq_cs; +static CRITICAL_SECTION_DEBUG creq_cs_debug = +{ + 0, 0, &creq_cs_debug, + { &creq_cs_debug.ProcessLocksList, &creq_cs_debug.ProcessLocksList }, + 0, 0, { 0, (DWORD)(__FILE__ ": dcom rpc request queue") } +}; +static CRITICAL_SECTION creq_cs = { &creq_cs_debug, -1, 0, 0, 0, 0 }; + +static RpcRequest *creq_head; +static RpcRequest *creq_tail; + +static void RpcChannel_push_request(RpcRequest *req) +{ + req->next = NULL; + req->ret = RPC_S_CALL_IN_PROGRESS; /* ? */ + EnterCriticalSection(&creq_cs); + if (creq_tail) { + creq_tail->next = req; + creq_tail = req; + } else { + creq_head = req; + creq_tail = req; + } + LeaveCriticalSection(&creq_cs); +} + +static RpcRequest* RpcChannel_pop_request(void) +{ + RpcRequest* req; + EnterCriticalSection(&creq_cs); + req = creq_head; + if (req) { + creq_head = req->next; + if (!creq_head) creq_tail = NULL; + } + LeaveCriticalSection(&creq_cs); + if (req) req->next = NULL; + return req; +} + +static DWORD CALLBACK RpcChannel_worker_thread(LPVOID the_arg) +{ + DWORD obj; + RpcRequest* req; + + for (;;) { + /* idle timeout after 5s */ + obj = WaitForSingleObject(worker_sem, 5000); + if (obj == WAIT_TIMEOUT) { + /* if another idle thread exist, self-destruct */ + if (worker_free > 1) break; + continue; + } + req = RpcChannel_pop_request(); + if (!req) continue; + InterlockedDecrement(&worker_free); + for (;;) { + req->ret = I_RpcSendReceive(req->msg); + SetEvent(req->done); + /* try to grab another request here without waiting + * on the semaphore, in case it hits max */ + req = RpcChannel_pop_request(); + if (!req) break; + /* decrement semaphore */ + WaitForSingleObject(worker_sem, 0); + } + InterlockedIncrement(&worker_free); + } + InterlockedDecrement(&worker_free); + InterlockedDecrement(&worker_count); + return 0; +} + +static void RpcChannel_create_worker_if_needed(void) +{ + if (!worker_sem) { + HANDLE sem; + sem = CreateSemaphoreA(NULL, 0, MAX_THREADS, NULL); + if (InterlockedCompareExchange((PLONG)&worker_sem, (LONG)sem, 0)) + CloseHandle(sem); /* somebody beat us to it */ + } + if (!worker_free && worker_count < MAX_THREADS) { + HANDLE thread; + InterlockedIncrement(&worker_count); + InterlockedIncrement(&worker_free); + thread = CreateThread(NULL, 0, RpcChannel_worker_thread, NULL, 0, NULL); + if (thread) CloseHandle(thread); + else { + InterlockedDecrement(&worker_free); + InterlockedDecrement(&worker_count); + } + } +} + +static HRESULT WINAPI RpcChannel_QueryInterface(LPRPCCHANNELBUFFER iface, + REFIID riid, + LPVOID *obj) +{ + ICOM_THIS(RpcChannelImpl,iface); + TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(riid),obj); + if (IsEqualGUID(&IID_IUnknown,riid) || + IsEqualGUID(&IID_IRpcChannelBuffer,riid)) { + *obj = This; + This->ref++; + return S_OK; + } + return E_NOINTERFACE; +} + +static ULONG WINAPI RpcChannel_AddRef(LPRPCCHANNELBUFFER iface) +{ + ICOM_THIS(RpcChannelImpl,iface); + TRACE("(%p)->AddRef()\n",This); + return ++(This->ref); +} + +static ULONG WINAPI RpcChannel_Release(LPRPCCHANNELBUFFER iface) +{ + ICOM_THIS(RpcChannelImpl,iface); + TRACE("(%p)->Release()\n",This); + if (!--(This->ref)) { + if (This->done) CloseHandle(This->done); + RpcBindingFree(&This->bind); + HeapFree(GetProcessHeap(),0,This); + return 0; + } + return This->ref; +} + +static inline HRESULT RPC2HR(RPC_STATUS status) +{ + switch (status) { + case RPC_S_OK: + return S_OK; + default: + return E_FAIL; + } +} + +static HRESULT WINAPI RpcChannel_GetBuffer(LPRPCCHANNELBUFFER iface, + PRPCOLEMESSAGE pMessage, + REFIID riid) +{ + ICOM_THIS(RpcChannelImpl,iface); + PRPC_MESSAGE pmsg = (PRPC_MESSAGE)pMessage; + PRPC_CLIENT_INTERFACE cif; + RPC_STATUS status; + + TRACE("(%p)->GetBuffer(%p,%p)\n",This,pMessage,riid); + + if (This->bind) { + cif = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RPC_CLIENT_INTERFACE)); + cif->Length = sizeof(RPC_CLIENT_INTERFACE); + cif->InterfaceId.SyntaxGUID = *riid; + pmsg->RpcInterfaceInformation = cif; + pmsg->Handle = This->bind; + } + + status = I_RpcGetBuffer(pmsg); + return RPC2HR(status); +} + +static HRESULT WINAPI RpcChannel_SendReceive(LPRPCCHANNELBUFFER iface, + PRPCOLEMESSAGE pMessage, + ULONG *pStatus) +{ + ICOM_THIS(RpcChannelImpl,iface); + PRPC_MESSAGE pmsg = (PRPC_MESSAGE)pMessage; + RPC_STATUS status; + + TRACE("(%p)->SendReceive(%p,%p)\n",This,pMessage,pStatus); + if (This->done) { + RpcRequest req; + DWORD w; + MSG msg; + + req.msg = pmsg; + req.done = This->done; + RpcChannel_create_worker_if_needed(); + RpcChannel_push_request(&req); + ReleaseSemaphore(worker_sem, 1, NULL); + do { + while (PeekMessageW(&msg, 0, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessageW(&msg); + TRACE("message %04x dispatched\n", msg.message); + } + w = MsgWaitForMultipleObjectsEx(1, &This->done, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE); + TRACE("MsgWaitForMultipleObjects returns %ld\n", w); + if (w == WAIT_OBJECT_0) break; + } while (TRUE); + status = req.ret; + } else { + status = I_RpcSendReceive(pmsg); + } + return RPC2HR(status); +} + +static HRESULT WINAPI RpcChannel_FreeBuffer(LPRPCCHANNELBUFFER iface, + PRPCOLEMESSAGE pMessage) +{ + ICOM_THIS(RpcChannelImpl,iface); + PRPC_MESSAGE pmsg = (PRPC_MESSAGE)pMessage; + RPC_STATUS status; + + TRACE("(%p)->FreeBuffer(%p)\n",This,pMessage); + status = I_RpcFreeBuffer(pmsg); + if (This->bind) { + HeapFree(GetProcessHeap(), 0, pmsg->RpcInterfaceInformation); + pmsg->RpcInterfaceInformation = NULL; + } + return RPC2HR(status); +} + +static HRESULT WINAPI RpcChannel_GetDestCtx(LPRPCCHANNELBUFFER iface, + DWORD *pdwDestContext, + LPVOID *ppvDestContext) +{ + ICOM_THIS(RpcChannelImpl,iface); + FIXME("(%p)->GetDestCtx(%p,%p)\n",This,pdwDestContext,ppvDestContext); + return E_FAIL; +} + +static HRESULT WINAPI RpcChannel_IsConnected(LPRPCCHANNELBUFFER iface) +{ + ICOM_THIS(RpcChannelImpl,iface); + FIXME("(%p)->IsConnected()\n",This); + return S_OK; +} + +static ICOM_VTABLE(IRpcChannelBuffer) RpcChannel_VTable = { + RpcChannel_QueryInterface, + RpcChannel_AddRef, + RpcChannel_Release, + RpcChannel_GetBuffer, + RpcChannel_SendReceive, + RpcChannel_FreeBuffer, + RpcChannel_GetDestCtx, + RpcChannel_IsConnected +}; + +static LPRPCCHANNELBUFFER RpcChannel_Create(RPC_BINDING_HANDLE bind, DWORD model, DWORD tid) +{ + RpcChannelImpl *chan; + + chan = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(RpcChannelImpl)); + if (!chan) return NULL; + chan->lpVtbl = &RpcChannel_VTable; + chan->ref = 1; + chan->tid = tid; + chan->bind = bind; + if (bind && (model & COINIT_APARTMENTTHREADED)) { + chan->done = CreateEventA(NULL, FALSE, FALSE, NULL); + } + return (LPRPCCHANNELBUFFER)chan; +} + + +/* COM tracks interfaces with three kinds of IDs: + * OXID = Object Exporter ID, one for each apartment (unique within network) + * OID = Object ID, one for each object (unique within apartment) + * IPID = Interface Pointer ID, one for each interface (unique within apartment) + * + * Hence, each "stub manager" would correspond to an OID, and each + * of the interface stubs would correspond to an IPID. + */ + +/******************** STUB MANAGER ********************/ +/* (FIXME: it is incorrect for the stub manager to implement + * IRemUnknown, it's rather a job for the OXID object, + * but this will do for now) */ + +void COM_FindXIf(APARTMENT *apt, IPID ipid, XOBJECT *obj, XIF **xif) +{ + XIF *iface; + EnterCriticalSection(&apt->cs); + if (xif) { + for (iface = obj->ifaces; iface && !IsEqualGUID(&iface->ipid, &ipid); iface = iface->next); + *xif = iface; + } + LeaveCriticalSection(&apt->cs); +} + +void COM_FindXIf2(APARTMENT *apt, XOBJECT *obj, XIF **xif, REFIID riid) +{ + XIF *iface; + EnterCriticalSection(&apt->cs); + if (xif) { + for (iface = obj->ifaces; iface && !IsEqualGUID(&iface->iid, riid); iface = iface->next); + *xif = iface; + } + LeaveCriticalSection(&apt->cs); +} + +void COM_CreateXIf(APARTMENT *apt, XOBJECT *obj, XIF **xif, REFIID riid, LPVOID pv) +{ + XIF *iface; + + EnterCriticalSection(&apt->cs); + for (iface = obj->ifaces; iface && !IsEqualGUID(&iface->iid, riid); iface = iface->next); + if (!iface) { + LPPSFACTORYBUFFER pPSF; + iface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(XIF)); + iface->iface = pv; + iface->iid = *riid; + /* generate IPID */ + ((IIPID*)&iface->ipid)->oxid = apt->oxid; + ((IIPID*)&iface->ipid)->oid = obj->oid; + ((IIPID*)&iface->ipid)->ifc = obj->ifc++; + if (!IsEqualGUID(riid, &IID_IUnknown)) { + /* register RPC interface */ + COM_RpcRegIf(riid); + iface->hres = COM_GetPSFactory(riid, &pPSF); + /* attempt to create an interface stub */ + if (SUCCEEDED(iface->hres)) { + iface->hres = IPSFactoryBuffer_CreateStub(pPSF, riid, pv, + &iface->stub); + IPSFactoryBuffer_Release(pPSF); + TRACE(" oid %llx ipid %s iface=%p stub=%p\n", + obj->oid, debugstr_guid(&iface->ipid), iface->iface, + iface->stub); + } + } + iface->next = obj->ifaces; + obj->ifaces = iface; + } +#if 0 /* I don't think we AddRef-ed it? */ + else IUnknown_Release((LPUNKNOWN)pv); +#endif + if (xif) *xif = iface; + LeaveCriticalSection(&apt->cs); +} + +static HRESULT WINAPI StubMan_QueryInterface(LPRPCSTUBBUFFER iface, + REFIID riid, + LPVOID *obj) +{ + ICOM_THIS(XOBJECT,iface); + TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(riid),obj); + if (IsEqualGUID(&IID_IUnknown,riid) || + IsEqualGUID(&IID_IRpcStubBuffer,riid)) { + *obj = This; + return S_OK; + } + return E_NOINTERFACE; +} + +static ULONG WINAPI StubMan_AddRef(LPRPCSTUBBUFFER iface) +{ + ICOM_THIS(XOBJECT,iface); + TRACE("(%p)->AddRef()\n",This); + return 2; +} + +static ULONG WINAPI StubMan_Release(LPRPCSTUBBUFFER iface) +{ + ICOM_THIS(XOBJECT,iface); + TRACE("(%p)->Release()\n",This); + return 1; +} + +static HRESULT WINAPI StubMan_Connect(LPRPCSTUBBUFFER iface, + LPUNKNOWN lpUnkServer) +{ + ICOM_THIS(XOBJECT,iface); + TRACE("(%p)->Connect(%p)\n",This,lpUnkServer); + return S_OK; +} + +static void WINAPI StubMan_Disconnect(LPRPCSTUBBUFFER iface) +{ + ICOM_THIS(XOBJECT,iface); + TRACE("(%p)->Disconnect()\n",This); +} + +static HRESULT WINAPI StubMan_Invoke(LPRPCSTUBBUFFER iface, + PRPCOLEMESSAGE pMsg, + LPRPCCHANNELBUFFER pChannel) +{ + ICOM_THIS(XOBJECT,iface); + APARTMENT *apt = COM_CurrentApt(); + /* DWORD dwPhase = 0; */ + ULONG iMethod = pMsg->iMethod; + XIF *xiface; + LPVOID ipv; + LPBYTE buf = pMsg->Buffer; + DWORD count; + ULONG cRefs; + USHORT cIids; + IID iid, *piid; + + TRACE("(%p)->Invoke(%p,%p) method %ld\n",This,pMsg,pChannel,iMethod); + switch (iMethod) { + case 3: /* RemQueryInterface */ + /* FIXME: use rpcrt4's NDR marshaller library + * (NdrSimpleTypeUnmarshall etc) */ +#if 0 + COM_FindXIf(apt, *(IPID*)buf, This, &xiface); + if (!xiface) { + ERR("RemQueryInterface on invalid interface %s\n", debugstr_guid((IPID*)buf)); + break; + } + ipv = xiface->iface; +#else + xiface = NULL; + ipv = This->obj; +#endif + buf += sizeof(IPID); + memcpy(&cRefs, buf, sizeof(ULONG)); + buf += sizeof(ULONG); + memcpy(&cIids, buf, sizeof(USHORT)); + buf += sizeof(USHORT); + TRACE("RemQueryInterface(%p,%ld,%d,...)\n", ipv, cRefs, cIids); + if (cIids == 1) { + piid = &iid; + } + else { + FIXME("handle more than one IID\n"); + break; + } + memcpy(piid, buf, cIids*sizeof(IID)); + /* compose reply */ + pMsg->cbBuffer = cIids*sizeof(REMQIRESULT); + I_RpcGetBuffer((PRPC_MESSAGE)pMsg); + buf = pMsg->Buffer; + for (count=0; count<cIids; count++) { + REMQIRESULT *qi = (REMQIRESULT*)buf; + XIF *xif; + LPVOID pv = NULL; + + qi->hResult = E_FAIL; + TRACE(" querying IID %s\n", debugstr_guid(&piid[count])); + COM_FindXIf2(apt, This, &xif, &piid[count]); + if (!xif) { + qi->hResult = IUnknown_QueryInterface((LPUNKNOWN)ipv, + &piid[count], + &pv); + if (qi->hResult == S_OK) + COM_CreateXIf(apt, This, &xif, &piid[count], pv); + } + if (xif) { + qi->hResult = xif->hres; + if (qi->hResult == S_OK) { + qi->std.flags = 0; + qi->std.cPublicRefs = cRefs; + qi->std.oxid = apt->oxid; + qi->std.oid = This->oid; + qi->std.ipid = xif->ipid; + COM_ExtAddRef(apt, This, xif, cRefs); + TRACE(" returning IPID %s for iface %p\n", + debugstr_guid(&qi->std.ipid), xif->iface); + } + } + buf += sizeof(REMQIRESULT); + } + break; + case 4: /* RemAddRef */ + memcpy(&cIids, buf, sizeof(USHORT)); + buf += sizeof(USHORT); + TRACE("RemAddRef(%d,...)\n", cIids); + for (count=0; count<cIids; count++) { + REMINTERFACEREF *ir = (REMINTERFACEREF*)buf; + TRACE(" on IPID %s\n", debugstr_guid(&ir->ipid)); + COM_FindXIf(apt, ir->ipid, This, &xiface); + if (!xiface) + ERR("RemAddRef on invalid interface %s\n", debugstr_guid(&ir->ipid)); + else + COM_ExtAddRef(apt, This, xiface, ir->cPublicRefs); + buf += sizeof(REMINTERFACEREF); + } + pMsg->cbBuffer = cIids * sizeof(HRESULT); + I_RpcGetBuffer((PRPC_MESSAGE)pMsg); + buf = pMsg->Buffer; + /* S_OK on all addrefs */ + memset(buf, 0, cIids * sizeof(HRESULT)); + break; + case 5: /* RemRelease */ + memcpy(&cIids, buf, sizeof(USHORT)); + buf += sizeof(USHORT); + TRACE("RemRelease(%d,...)\n", cIids); + for (count=0; count<cIids; count++) { + REMINTERFACEREF *ir = (REMINTERFACEREF*)buf; + TRACE(" on IPID %s\n", debugstr_guid(&ir->ipid)); + COM_FindXIf(apt, ir->ipid, This, &xiface); + if (!xiface) + ERR("RemRelease on invalid interface %s\n", debugstr_guid(&ir->ipid)); + else + COM_ExtRelease(apt, This, xiface, ir->cPublicRefs); + buf += sizeof(REMINTERFACEREF); + } + pMsg->cbBuffer = 0; + I_RpcGetBuffer((PRPC_MESSAGE)pMsg); + buf = pMsg->Buffer; + break; + } + return S_OK; +} + +static LPRPCSTUBBUFFER WINAPI StubMan_IsIIDSupported(LPRPCSTUBBUFFER iface, + REFIID riid) +{ + ICOM_THIS(XOBJECT,iface); + TRACE("(%p)->IsIIDSupported(%s)\n",This,debugstr_guid(riid)); + return IsEqualGUID(&IID_IRemUnknown, riid) ? iface : NULL; +} + +static ULONG WINAPI StubMan_CountRefs(LPRPCSTUBBUFFER iface) +{ + ICOM_THIS(XOBJECT,iface); + TRACE("(%p)->CountRefs()\n",This); + return This->refs; +} + +static HRESULT WINAPI StubMan_DebugServerQueryInterface(LPRPCSTUBBUFFER iface, + LPVOID *ppv) +{ + ICOM_THIS(XOBJECT,iface); + TRACE("(%p)->DebugServerQueryInterface(%p)\n",This,ppv); + return S_OK; +} + +static void WINAPI StubMan_DebugServerRelease(LPRPCSTUBBUFFER iface, + LPVOID pv) +{ + ICOM_THIS(XOBJECT,iface); + TRACE("(%p)->DebugServerRelease(%p)\n",This,pv); +} + +static ICOM_VTABLE(IRpcStubBuffer) StubMan_VTable = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + StubMan_QueryInterface, + StubMan_AddRef, + StubMan_Release, + StubMan_Connect, + StubMan_Disconnect, + StubMan_Invoke, + StubMan_IsIIDSupported, + StubMan_CountRefs, + StubMan_DebugServerQueryInterface, + StubMan_DebugServerRelease +}; + +void COM_FindXObj(APARTMENT *apt, OID oid, IPID ipid, XOBJECT **xobj, XIF **xif) +{ + XOBJECT *obj; + EnterCriticalSection(&apt->cs); + for (obj = apt->objs; obj && obj->oid != oid; obj = obj->next); + if (xobj) *xobj = obj; + if (obj) { + if (xif) COM_FindXIf(apt, ipid, obj, xif); + } + else if (xif) *xif = NULL; + LeaveCriticalSection(&apt->cs); +} + +void COM_CreateXObj(APARTMENT *apt, XOBJECT **xobj, XIF **xif, REFIID riid, LPVOID pv) +{ + LPUNKNOWN pUnk = NULL; + XOBJECT *obj; + + IUnknown_QueryInterface((LPUNKNOWN)pv, &IID_IUnknown, (LPVOID*)&pUnk); + EnterCriticalSection(&apt->cs); + for (obj = apt->objs; obj && obj->obj != pUnk; obj = obj->next); + if (!obj) { + obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(XOBJECT)); + obj->lpVtbl = &StubMan_VTable; + obj->parent = apt; + IUnknown_AddRef(pUnk); + obj->obj = pUnk; + /* generate OID */ + obj->oid = apt->oidc++; + obj->next = apt->objs; + apt->objs = obj; + TRACE(" oid=%llx\n", obj->oid); + /* add the IUnknown interface first */ +#if 0 + IUnknown_AddRef(pUnk); +#endif + COM_CreateXIf(apt, obj, NULL, &IID_IUnknown, pUnk); + } + if (xobj) *xobj = obj; + if (obj) COM_CreateXIf(apt, obj, xif, riid, pv); + else { +#if 0 /* I don't think we AddRef-ed it? */ + IUnknown_Release((LPUNKNOWN)pv); +#endif + if (xif) *xif = NULL; + } + LeaveCriticalSection(&apt->cs); + IUnknown_Release(pUnk); +} + +void COM_ExtAddRef(APARTMENT *apt, XOBJECT *xobj, XIF *xif, DWORD refs) +{ + EnterCriticalSection(&apt->cs); + xif->refs += refs; + xobj->refs += refs; + LeaveCriticalSection(&apt->cs); +} + +void COM_ExtRelease(APARTMENT *apt, XOBJECT *xobj, XIF *xif, DWORD refs) +{ + EnterCriticalSection(&apt->cs); + xif->refs -= refs; + xobj->refs -= refs; + if (!xobj->refs) { + XOBJECT *cobj, *pobj; + XIF *cif, *pif; + + TRACE("destroying stub manager %p\n", xobj); + TRACE(" oid=%llx\n", xobj->oid); + + /* unlink exported object */ + for (pobj = NULL, cobj = apt->objs; + cobj && cobj != xobj; + pobj = cobj, cobj = cobj->next); + if (cobj) { + if (pobj) pobj->next = cobj->next; + else apt->objs = cobj->next; + cobj->next = NULL; + } + LeaveCriticalSection(&apt->cs); + + /* destroy interface stubs */ + cif = xobj->ifaces; + while (cif) { + pif = cif; + cif = cif->next; + + TRACE(" ipid %s iface=%p stub=%p\n", + debugstr_guid(&pif->ipid), pif->iface, pif->stub); + + /* maybe call something like RpcUnreg? */ + if (pif->stub) + IRpcStubBuffer_Release(pif->stub); +#if 0 /* I don't think we AddRef-ed it */ + IUnknown_Release((LPUNKNOWN)pif->iface); +#endif + HeapFree(GetProcessHeap(), 0, pif); + } + /* destroy stub manager */ + IUnknown_Release(xobj->obj); + HeapFree(GetProcessHeap(), 0, xobj); + return; + } + LeaveCriticalSection(&apt->cs); +} + +/******************** PROXY MANAGER ********************/ +/* (FIXME: it is incorrect for the proxy manager to implement + * IRemUnknown, it's rather a job for the OXID object, + * but this will do for now) */ +/* FIXME: the proxy manager should implement IMarshal, + * so that proxies to proxies can't occur */ + +void COM_CreateIIf(APARTMENT *apt, IPID ipid, IOBJECT *obj, IIF **iif, REFIID riid) +{ + IIF *iface; + EnterCriticalSection(&apt->cs); + for (iface = obj->ifaces; iface && !IsEqualGUID(&iface->ipid, &ipid); iface = iface->next); + if (!iface) { + LPPSFACTORYBUFFER pPSF; + iface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IIF)); + iface->iid = *riid; + iface->ipid = ipid; + if (!IsEqualGUID(riid, &IID_IUnknown)) { + /* attempt to aggregate an interface proxy + * into the imported object identity */ + iface->hres = COM_GetPSFactory(riid, &pPSF); + if (SUCCEEDED(iface->hres)) { + iface->hres = IPSFactoryBuffer_CreateProxy(pPSF, (LPUNKNOWN)obj, riid, + &iface->proxy, &iface->iface); + IPSFactoryBuffer_Release(pPSF); + /* if successful, connect the interface proxy */ + if (SUCCEEDED(iface->hres) && obj->chan) + IRpcProxyBuffer_Connect(iface->proxy, obj->chan); + } + } + else iface->iface = obj; + iface->next = obj->ifaces; + obj->ifaces = iface; + } + if (iif) *iif = iface; + LeaveCriticalSection(&apt->cs); +} + +static HRESULT WINAPI ProxyMan_QueryInterface(LPREMUNKNOWN iface, + REFIID riid, + LPVOID *obj) +{ + ICOM_THIS(IOBJECT,iface); + TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(riid),obj); + if (IsEqualGUID(&IID_IUnknown,riid)) { + *obj = This; + EnterCriticalSection(&This->parent->cs); + This->refs++; + LeaveCriticalSection(&This->parent->cs); + return S_OK; + } + else { + IIF *iif; + REMQIRESULT *qres = NULL; + HRESULT hr; + + EnterCriticalSection(&This->parent->cs); + iif = This->ifaces; + while (iif) { + if (IsEqualGUID(&iif->iid,riid)) { + *obj = iif->iface; + IUnknown_AddRef((LPUNKNOWN)*obj); + LeaveCriticalSection(&This->parent->cs); + return S_OK; + } + iif = iif->next; + } + LeaveCriticalSection(&This->parent->cs); + + /* not found locally, ask server for interface */ + hr = IRemUnknown_RemQueryInterface(iface, &This->ipid, 5, + 1, (IID*)riid, &qres); + if (SUCCEEDED(hr)) hr = qres->hResult; + if (SUCCEEDED(hr)) { + EnterCriticalSection(&This->parent->cs); + COM_CreateIIf(This->parent, qres->std.ipid, This, &iif, riid); + if (iif) { + iif->refs += qres->std.cPublicRefs; + hr = iif->hres; + + /* unmarshal complete */ + if (SUCCEEDED(hr)) { + *obj = iif->iface; + IUnknown_AddRef((LPUNKNOWN)*obj); + } + } + LeaveCriticalSection(&This->parent->cs); + } + if (qres) CoTaskMemFree(qres); + return hr; + } + return E_NOINTERFACE; +} + +static ULONG WINAPI ProxyMan_AddRef(LPREMUNKNOWN iface) +{ + ICOM_THIS(IOBJECT,iface); + ULONG refs; + + TRACE("(%p)->AddRef()\n",This); + EnterCriticalSection(&This->parent->cs); + refs = ++(This->refs); + LeaveCriticalSection(&This->parent->cs); + return refs; +} + +static ULONG WINAPI ProxyMan_Release(LPREMUNKNOWN iface) +{ + ICOM_THIS(IOBJECT,iface); + ULONG refs; + + TRACE("(%p)->Release()\n",This); + EnterCriticalSection(&This->parent->cs); + refs = --(This->refs); + if (!refs) { + IOBJECT *cobj, *pobj; + IIF *cif, *pif; + DWORD icnt, icur; + REMINTERFACEREF *iref; + + /* unlink imported object */ + for (pobj = NULL, cobj = This->parent->proxies; + cobj && cobj != This; + pobj = cobj, cobj = cobj->next); + if (cobj) { + if (pobj) pobj->next = cobj->next; + else This->parent->proxies = cobj->next; + cobj->next = NULL; + } + LeaveCriticalSection(&This->parent->cs); + + /* count interface proxies */ + for (icnt = 0, cif = This->ifaces; cif; cif = cif->next, icnt++); + if (icnt) { + iref = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(REMINTERFACEREF)*icnt); + + /* destroy interface proxies */ + icur = 0; + cif = This->ifaces; + while (cif) { + iref[icur].ipid = cif->ipid; + iref[icur].cPublicRefs = cif->refs; + iref[icur].cPrivateRefs = 0; + + pif = cif; + cif = cif->next; + icur++; + + if (pif->proxy) IRpcProxyBuffer_Release(pif->proxy); + HeapFree(GetProcessHeap(), 0, pif); + } + + if (icur != icnt) { + ERR("icur != icnt, bad stuff\n"); + } + + IRemUnknown_RemRelease(iface, icur, iref); + HeapFree(GetProcessHeap(), 0, iref); + } + HeapFree(GetProcessHeap(), 0, This); + return 0; + } + LeaveCriticalSection(&This->parent->cs); + return refs; +} + +static HRESULT WINAPI ProxyMan_RemQueryInterface(LPREMUNKNOWN iface, + REFIPID ripid, + ULONG cRefs, + USHORT cIids, + IID* iids, + REMQIRESULT** ppQIResults) +{ + ICOM_THIS(IOBJECT,iface); + RPCOLEMESSAGE msg; + HRESULT hr = S_OK; + ULONG status; + + TRACE("(%p)->(%s,%ld,%d,%p,%p)\n",This, + debugstr_guid(ripid),cRefs,cIids,iids,ppQIResults); + + *ppQIResults = NULL; + memset(&msg, 0, sizeof(msg)); + msg.iMethod = 3; + msg.cbBuffer = sizeof(IPID) + sizeof(ULONG) + + sizeof(USHORT) + cIids*sizeof(IID); + hr = IRpcChannelBuffer_GetBuffer(This->chan, &msg, &IID_IRemUnknown); + if (SUCCEEDED(hr)) { + LPBYTE buf = msg.Buffer; + /* FIXME: use rpcrt4's NDR marshaller library + * (NdrSimpleTypeMarshall etc) */ + memcpy(buf, ripid, sizeof(IPID)); + buf += sizeof(IPID); + memcpy(buf, &cRefs, sizeof(ULONG)); + buf += sizeof(ULONG); + memcpy(buf, &cIids, sizeof(USHORT)); + buf += sizeof(USHORT); + memcpy(buf, iids, cIids*sizeof(IID)); + + hr = IRpcChannelBuffer_SendReceive(This->chan, &msg, &status); + + if (SUCCEEDED(hr)) { + buf = msg.Buffer; + *ppQIResults = CoTaskMemAlloc(cIids*sizeof(REMQIRESULT)); + memcpy(*ppQIResults, buf, cIids*sizeof(REMQIRESULT)); + } + + IRpcChannelBuffer_FreeBuffer(This->chan, &msg); + } + + return hr; +} + +static HRESULT WINAPI ProxyMan_RemAddRef(LPREMUNKNOWN iface, + USHORT cInterfaceRefs, + REMINTERFACEREF* InterfaceRefs, + HRESULT* pResults) +{ + ICOM_THIS(IOBJECT,iface); + RPCOLEMESSAGE msg; + HRESULT hr = S_OK; + ULONG status; + + TRACE("(%p)->(%d,%p,%p)\n",This, + cInterfaceRefs,InterfaceRefs,pResults); + + memset(&msg, 0, sizeof(msg)); + msg.iMethod = 4; + msg.cbBuffer = sizeof(USHORT) + cInterfaceRefs*sizeof(REMINTERFACEREF); + hr = IRpcChannelBuffer_GetBuffer(This->chan, &msg, &IID_IRemUnknown); + if (SUCCEEDED(hr)) { + LPBYTE buf = msg.Buffer; + /* FIXME: use rpcrt4's NDR marshaller library + * (NdrSimpleTypeMarshall etc) */ + memcpy(buf, &cInterfaceRefs, sizeof(USHORT)); + buf += sizeof(USHORT); + memcpy(buf, InterfaceRefs, cInterfaceRefs*sizeof(REMINTERFACEREF)); + + hr = IRpcChannelBuffer_SendReceive(This->chan, &msg, &status); + + if (SUCCEEDED(hr)) { + buf = msg.Buffer; + memcpy(pResults, buf, cInterfaceRefs*sizeof(HRESULT)); + } + + IRpcChannelBuffer_FreeBuffer(This->chan, &msg); + } + + return hr; +} + +static HRESULT WINAPI ProxyMan_RemRelease(LPREMUNKNOWN iface, + USHORT cInterfaceRefs, + REMINTERFACEREF* InterfaceRefs) +{ + ICOM_THIS(IOBJECT,iface); + RPCOLEMESSAGE msg; + HRESULT hr = S_OK; + ULONG status; + + TRACE("(%p)->(%d,%p)\n",This, + cInterfaceRefs,InterfaceRefs); + + memset(&msg, 0, sizeof(msg)); + msg.iMethod = 5; + msg.cbBuffer = sizeof(USHORT) + cInterfaceRefs*sizeof(REMINTERFACEREF); + hr = IRpcChannelBuffer_GetBuffer(This->chan, &msg, &IID_IRemUnknown); + if (SUCCEEDED(hr)) { + LPBYTE buf = msg.Buffer; + /* FIXME: use rpcrt4's NDR marshaller library + * (NdrSimpleTypeMarshall etc) */ + memcpy(buf, &cInterfaceRefs, sizeof(USHORT)); + buf += sizeof(USHORT); + memcpy(buf, InterfaceRefs, cInterfaceRefs*sizeof(REMINTERFACEREF)); + + hr = IRpcChannelBuffer_SendReceive(This->chan, &msg, &status); + + IRpcChannelBuffer_FreeBuffer(This->chan, &msg); + } + + return hr; +} + +static ICOM_VTABLE(IRemUnknown) ProxyMan_VTable = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + ProxyMan_QueryInterface, + ProxyMan_AddRef, + ProxyMan_Release, + ProxyMan_RemQueryInterface, + ProxyMan_RemAddRef, + ProxyMan_RemRelease +}; + +void COM_FindIObj(APARTMENT *apt, OXID oxid, OID oid, IPID ipid, IOBJECT **iobj, IIF **iif) +{ + IOBJECT *obj; + IIF *iface; + EnterCriticalSection(&apt->cs); + for (obj = apt->proxies; obj && (obj->oxid != oxid || obj->oid != oid); obj = obj->next); + if (iobj) *iobj = obj; + if (obj) { + if (iif) { + for (iface = obj->ifaces; iface && !IsEqualGUID(&iface->ipid, &ipid); iface = iface->next); + *iif = iface; + } + } + else if (iif) *iif = NULL; + LeaveCriticalSection(&apt->cs); +} + +void COM_CreateIObj(APARTMENT *apt, OXID oxid, OID oid, IPID ipid, IOBJECT **iobj, RPC_BINDING_HANDLE bind) +{ + IOBJECT *obj; + RpcBindingSetObject(bind, &ipid); + EnterCriticalSection(&apt->cs); + for (obj = apt->proxies; obj && (obj->oxid != oxid || obj->oid != oid); obj = obj->next); + if (!obj) { + obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IOBJECT)); + obj->lpVtbl = &ProxyMan_VTable; + obj->parent = apt; + obj->oxid = oxid; + obj->oid = oid; + obj->ipid = ipid; + if (bind) + if ((obj->chan = RpcChannel_Create(bind, apt->model, apt->tid)) != NULL) bind = 0; + obj->refs = 1; + obj->next = apt->proxies; + apt->proxies = obj; + } + if (iobj) *iobj = obj; + LeaveCriticalSection(&apt->cs); + if (bind) RpcBindingFree(&bind); +} + +/******************** STANDARD MARSHALER ********************/ + +typedef struct StdMarshalImpl { + ICOM_VTABLE(IMarshal) *lpVtbl; + DWORD ref; +} StdMarshalImpl; + +static HRESULT WINAPI StdMarshal_QueryInterface(LPMARSHAL iface, + REFIID riid, + LPVOID *obj) +{ + ICOM_THIS(StdMarshalImpl,iface); + TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(riid),obj); + if (IsEqualGUID(&IID_IUnknown,riid) || + IsEqualGUID(&IID_IMarshal,riid)) { + *obj = This; + This->ref++; + return S_OK; + } + return E_NOINTERFACE; +} + +static ULONG WINAPI StdMarshal_AddRef(LPMARSHAL iface) +{ + ICOM_THIS(StdMarshalImpl,iface); + TRACE("(%p)->AddRef()\n",This); + return ++(This->ref); +} + +static ULONG WINAPI StdMarshal_Release(LPMARSHAL iface) +{ + ICOM_THIS(StdMarshalImpl,iface); + TRACE("(%p)->Release()\n",This); + if (!--(This->ref)) { + HeapFree(GetProcessHeap(),0,This); + return 0; + } + return This->ref; +} + +static DWORD GetDualStringArray(LPWSTR *binds, DWORD *sec_ofs) +{ + RPC_BINDING_VECTOR *bind = NULL; + DWORD count, len = 0; + STRINGBINDING **sbind = NULL; + unsigned u; + + if (binds) *binds = NULL; + if (sec_ofs) *sec_ofs = 0; + RpcServerInqBindings(&bind); + count = bind->Count; + if (binds) sbind = HeapAlloc(GetProcessHeap(), 0, count*sizeof(STRINGBINDING*)); + for (u=0; u<count; u++) { + LPWSTR sb, protseq, nsb; + RPC_BINDING_HANDLE bindh = bind->BindingH[u]; + DWORD clen; + + /* get string binding */ + RpcBindingToStringBindingW(bindh, &sb); + /* skip the object, if any */ + protseq = strchrW(sb, '@'); + if (protseq) protseq++; else protseq = sb; + /* grab the protseq */ + nsb = strchrW(protseq, ':'); + if (nsb) { *nsb++ = 0; } + TRACE("protseq: %s\n", debugstr_w(protseq)); + TRACE("net-addr: %s\n", debugstr_w(nsb)); + /* the rest becomes the marshaled string binding */ + /* (the null terminator is included in sizeof(STRINGBINDING)) */ + clen = sizeof(STRINGBINDING) + strlenW(nsb)*sizeof(WCHAR); + len += clen; + if (sbind) { + STRINGBINDING *cbind = HeapAlloc(GetProcessHeap(), 0, clen); + sbind[u] = cbind; + /* FIXME: lookup the protseq tower id... */ + cbind->wTowerId = 0; + strcpyW(cbind->aNetworkAddr, nsb); + RpcStringFreeW(&sb); + } + } + len += sizeof(WCHAR); + if (sec_ofs) *sec_ofs = len; + /* FIXME: security bindings */ + RpcBindingVectorFree(&bind); + if (sbind) { + LPBYTE ptr; + *binds = HeapAlloc(GetProcessHeap(), 0, len); + ptr = (LPBYTE)*binds; + for (u=0; u<count; u++) { + STRINGBINDING *cbind = sbind[u]; + DWORD clen = sizeof(STRINGBINDING) + strlenW(cbind->aNetworkAddr)*sizeof(WCHAR); + memcpy(ptr, cbind, clen); + ptr += clen; + HeapFree(GetProcessHeap(), 0, cbind); + } + *(WCHAR*)ptr = 0; + ptr += sizeof(WCHAR); + TRACE("len=%ld (%d)\n", len, ptr-(LPBYTE)*binds); + HeapFree(GetProcessHeap(), 0, sbind); + } + else { + TRACE("len=%ld\n", len); + } + return len; +} + +static RPC_BINDING_HANDLE ParseDualStringArray(LPWSTR binds, DWORD len, DWORD sec_ofs) +{ + RPC_BINDING_HANDLE bind = 0; + RPC_STATUS status; + LPBYTE ptr; + LPWSTR sb; + STRINGBINDING *cbind; + DWORD pos, lim, clen, plen, slen; + static const WCHAR def_protseq[] = {'n','c','a','l','r','p','c',0}; + + TRACE("(%p,%ld,%ld)\n", binds, len, sec_ofs); + + if (!len) return 0; + if (sec_ofs >= len) sec_ofs = 0; + + ptr = (LPBYTE)binds; + pos = 0; + lim = (sec_ofs ? sec_ofs : len) - 1; + while ((!bind) && (pos < lim)) { + cbind = (STRINGBINDING *)(ptr+pos); + + pos += sizeof(STRINGBINDING) + strlenW(cbind->aNetworkAddr)*sizeof(WCHAR); + if (pos > lim) { + ERR("malformed dual string array (%ld > %ld)\n", pos, lim); + return 0; + } + TRACE("protseq: %s\n", debugstr_w(def_protseq)); + TRACE("net-addr: %s\n", debugstr_w(cbind->aNetworkAddr)); + + /* FIXME: lookup the protseq tower id... */ + plen = strlenW(def_protseq); + clen = strlenW(cbind->aNetworkAddr) + 1; + slen = plen + 1 + clen; + sb = HeapAlloc(GetProcessHeap(), 0, slen*sizeof(WCHAR)); + strcpyW(sb, def_protseq); + sb[plen] = ':'; + strcpyW(sb + plen + 1, cbind->aNetworkAddr); + + /* try to get a RPC binding */ + status = RpcBindingFromStringBindingW(sb, &bind); + + HeapFree(GetProcessHeap(), 0, sb); + } + + if (!bind) return 0; + + /* make sure string binding array is null-terminated */ + if (*(WCHAR*)(ptr + pos)) { + ERR("malformed dual string array (not terminated)\n"); + RpcBindingFree(&bind); + return 0; + } + ptr += sizeof(WCHAR); + + /* FIXME: security bindings */ + + return bind; +} + +static HRESULT WINAPI StdMarshal_GetUnmarshalClass(LPMARSHAL iface, + REFIID riid, + LPVOID pv, + DWORD dwDestContext, + LPVOID pvDestContext, + DWORD mshlFlags, + CLSID *pCid) +{ + ICOM_THIS(StdMarshalImpl,iface); + TRACE("(%p)->GetUnmarshalClass(%s,%p,%lx,%p,%lx,%p)\n",This, + debugstr_guid(riid),pv,dwDestContext,pvDestContext,mshlFlags,pCid); + /* return CLSID of the standard marshaller */ + memcpy(pCid, &CLSID_StdMarshal,sizeof(*pCid)); + return S_OK; +} + +static HRESULT WINAPI StdMarshal_GetMarshalSizeMax(LPMARSHAL iface, + REFIID riid, + LPVOID pv, + DWORD dwDestContext, + LPVOID pvDestContext, + DWORD mshlFlags, + DWORD *pSize) +{ + ICOM_THIS(StdMarshalImpl,iface); + APARTMENT *apt = COM_CurrentApt(); + DWORD size; + + TRACE("(%p)->GetMarshalSizeMax(%s,%p,%lx,%p,%lx,%p)\n",This, + debugstr_guid(riid),pv,dwDestContext,pvDestContext,mshlFlags,pSize); + if (!apt) return CO_E_NOTINITIALIZED; + + COM_RpcInit(); + + size = sizeof(struct OR_STANDARD); + size += GetDualStringArray(NULL, NULL); + *pSize = size; + return S_OK; +} + +static HRESULT WINAPI StdMarshal_MarshalInterface(LPMARSHAL iface, + LPSTREAM pStm, + REFIID riid, + LPVOID pv, + DWORD dwDestContext, + LPVOID pvDestContext, + DWORD mshlFlags) +{ + ICOM_THIS(StdMarshalImpl,iface); + APARTMENT *apt = COM_CurrentApt(); + struct OR_STANDARD obj; + LPWSTR dsastr; + DWORD dsalen, secofs; + HRESULT hr; + XOBJECT *xobj; + XIF *xif; + + TRACE("(%p)->MarshalInterface(%p,%s,%p,%lx,%p,%lx)\n",This,pStm, + debugstr_guid(riid),pv,dwDestContext,pvDestContext,mshlFlags); + if (!apt) return CO_E_NOTINITIALIZED; + + COM_RpcInit(); + + memset(&obj, 0, sizeof(obj)); + if (mshlFlags & MSHLFLAGS_TABLEWEAK) { + /* marshaled data is 0 external refs */ + obj.std.cPublicRefs = 0; + FIXME("table-weak marshal\n"); + } + else if (mshlFlags & MSHLFLAGS_TABLESTRONG) { + /* marshaled data is 1 external ref */ + obj.std.cPublicRefs = 0; + FIXME("table-strong marshal\n"); + } + else { + /* 5 external refs transferred in marshaled data */ + obj.std.cPublicRefs = 5; + } + if (mshlFlags & MSHLFLAGS_NOPING) + obj.std.flags |= SORF_NOPING; + + EnterCriticalSection(&apt->cs); + COM_CreateXObj(apt, &xobj, &xif, riid, pv); + if (xif) { + obj.std.oxid = apt->oxid; + obj.std.oid = xobj->oid; + obj.std.ipid = xif->ipid; + COM_ExtAddRef(apt, xobj, xif, obj.std.cPublicRefs); + hr = xif->hres; + if (FAILED(hr)) + COM_ExtRelease(apt, xobj, xif, obj.std.cPublicRefs); + } + else hr = E_OUTOFMEMORY; + LeaveCriticalSection(&apt->cs); + + if (FAILED(hr)) return hr; + + dsalen = GetDualStringArray(&dsastr, &secofs); + obj.saResAddr.wNumEntries = dsalen / sizeof(WCHAR); + obj.saResAddr.wSecurityOffset = secofs / sizeof(WCHAR); + + hr = IStream_Write(pStm, &obj, sizeof(obj), NULL); + if (SUCCEEDED(hr)) { + hr = IStream_Write(pStm, dsastr, dsalen, NULL); + } + + HeapFree(GetProcessHeap(), 0, dsastr); + + return hr; +} + +static HRESULT WINAPI StdMarshal_UnmarshalInterface(LPMARSHAL iface, + LPSTREAM pStm, + REFIID riid, + LPVOID *ppv) +{ + ICOM_THIS(StdMarshalImpl,iface); + APARTMENT *apt = COM_CurrentApt(); + struct OR_STANDARD obj; + LPWSTR dsastr = NULL; + DWORD dsalen = 0, secofs = 0; + HRESULT hr; + IOBJECT *iobj; + IIF *iif; + + TRACE("(%p)->UnmarshalInterface(%p,%s,%p)\n",This,pStm, + debugstr_guid(riid),ppv); + *ppv = NULL; + if (!apt) return CO_E_NOTINITIALIZED; + + hr = IStream_Read(pStm, &obj, sizeof(obj), NULL); + if (FAILED(hr)) return hr; + if (obj.saResAddr.wNumEntries) { + dsalen = obj.saResAddr.wNumEntries*sizeof(WCHAR); + secofs = obj.saResAddr.wSecurityOffset*sizeof(WCHAR); + dsastr = HeapAlloc(GetProcessHeap(), 0, dsalen); + hr = IStream_Read(pStm, dsastr, dsalen, NULL); + if (FAILED(hr)) goto finito; + } + + if (obj.std.oxid == apt->oxid) { + XOBJECT *xobj; + XIF *xif; + TRACE("dude! some crazy fool demarshalled us into the source apartment! we got no work to do :)\n"); + /* dude, we're still in the same apartment... + * we don't need no stinkin' proxy */ + EnterCriticalSection(&apt->cs); + COM_FindXObj(apt, obj.std.oid, obj.std.ipid, &xobj, &xif); + if (xif) { + IUnknown_AddRef((LPUNKNOWN)xif->iface); + *ppv = xif->iface; + COM_ExtRelease(apt, xobj, xif, obj.std.cPublicRefs); + hr = S_OK; + } + else hr = CO_E_OBJNOTCONNECTED; + LeaveCriticalSection(&apt->cs); + goto finito; + } + + hr = E_FAIL; + + /* see if object has already been imported */ + EnterCriticalSection(&apt->cs); + COM_FindIObj(apt, obj.std.oxid, obj.std.oid, obj.std.ipid, &iobj, &iif); + + if (!iobj) { + /* object not already imported, connect to it */ + RPC_BINDING_HANDLE bind = ParseDualStringArray(dsastr, dsalen, secofs); + if (bind) /* register new connection */ + COM_CreateIObj(apt, obj.std.oxid, obj.std.oid, obj.std.ipid, &iobj, bind); + else + hr = CO_E_OBJNOTCONNECTED; + } + else iobj->refs++; + if (iobj && !iif) { + /* object imported, register new interface */ + COM_CreateIIf(apt, obj.std.ipid, iobj, &iif, riid); + } + + if (iif) { + iif->refs += obj.std.cPublicRefs; + hr = iif->hres; + + /* unmarshal complete */ + *ppv = iif->iface; + } + + LeaveCriticalSection(&apt->cs); + +finito: + if (dsastr) HeapFree(GetProcessHeap(), 0, dsastr); + return hr; +} + +static HRESULT WINAPI StdMarshal_ReleaseMarshalData(LPMARSHAL iface, + LPSTREAM pStm) +{ + ICOM_THIS(StdMarshalImpl,iface); + APARTMENT *apt = COM_CurrentApt(); + struct OR_STANDARD obj; + HRESULT hr; + + TRACE("(%p)->ReleaseMarshalData(%p)\n",This,pStm); + if (!apt) return CO_E_NOTINITIALIZED; + + hr = IStream_Read(pStm, &obj, sizeof(obj), NULL); + if (FAILED(hr)) return hr; + /* FIXME: read string bindings */ + /* FIXME: read security bindings */ + + if (obj.std.oxid == apt->oxid) { + XOBJECT *xobj; + XIF *xif; + EnterCriticalSection(&apt->cs); + COM_FindXObj(apt, obj.std.oid, obj.std.ipid, &xobj, &xif); + if (xif) { + COM_ExtRelease(apt, xobj, xif, obj.std.cPublicRefs); + hr = S_OK; + } + else hr = CO_E_OBJNOTCONNECTED; + LeaveCriticalSection(&apt->cs); + return hr; + } + + FIXME("interapartment marshal release\n"); + return RPC_E_WRONG_THREAD; +} + +static HRESULT WINAPI StdMarshal_DisconnectObject(LPMARSHAL iface, + DWORD dwReserved) +{ + ICOM_THIS(StdMarshalImpl,iface); + TRACE("(%p)->DisconnectObject(%ld)\n",This,dwReserved); + /* FIXME */ + return S_OK; +} + +static ICOM_VTABLE(IMarshal) StdMarshalImpl_VTable = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + StdMarshal_QueryInterface, + StdMarshal_AddRef, + StdMarshal_Release, + StdMarshal_GetUnmarshalClass, + StdMarshal_GetMarshalSizeMax, + StdMarshal_MarshalInterface, + StdMarshal_UnmarshalInterface, + StdMarshal_ReleaseMarshalData, + StdMarshal_DisconnectObject +}; + +static HRESULT COM_GetMarshal(REFIID riid, + IUnknown *pUnk, + DWORD dwDestContext, + void *pvDestContext, + DWORD mshlFlags, + LPMARSHAL *pMarshal) +{ + HRESULT hr; + hr = IUnknown_QueryInterface(pUnk, &IID_IMarshal, (LPVOID*)pMarshal); + if (hr == E_NOINTERFACE) { + TRACE("no custom marshaler found, using standard marshaler\n"); + hr = CoGetStandardMarshal(riid, pUnk, dwDestContext, pvDestContext, + mshlFlags, pMarshal); + } + return hr; +} + +static HRESULT COM_GetUnmarshal(IStream *pStm, + LPMARSHAL *pMarshal, + LPIID piid) +{ + HRESULT hr; + OBJREF obj; + struct OR_CUSTOM cobj; + ULONG count; + + + TRACE("pStm=%p, ppMarshal=%p, piid=%p\n", pStm, pMarshal, piid); + if (!pStm) return E_FAIL; + + /* get administrative data */ + hr = IStream_Read(pStm, &obj, sizeof(obj), &count); + TRACE("stream read\n"); + if (FAILED(hr)) return hr; + if (count != sizeof(obj)) return E_FAIL; + + TRACE("memcpy\n"); + if (piid) memcpy(piid, &obj.iid, sizeof(obj.iid)); + + /* get unmarshal class instance */ + if (obj.flags & OBJREF_CUSTOM) { + TRACE("reading stream\n"); + hr = IStream_Read(pStm, &cobj, sizeof(cobj), &count); + if (FAILED(hr)) return hr; + if (count != sizeof(cobj)) return E_FAIL; + TRACE("Creating unmarshal class instance\n"); + hr = CoCreateInstance(&cobj.clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IMarshal, (LPVOID*)pMarshal); + } + else { + TRACE("Retrieving standard marshaller\n"); + hr = CoGetStandardMarshal(NULL, NULL, 0, NULL, 0, pMarshal); + } + + return hr; +} + +HRESULT COM_GetStdObjRef(IStream *pStm, + STDOBJREF *pObjRef, + LPIID piid) +{ + HRESULT hr; + OBJREF obj; + LARGE_INTEGER move, opos; + ULONG count; + + /* save initial position */ + move.s.LowPart = 0; + move.s.HighPart = 0; + hr = IStream_Seek(pStm, move, STREAM_SEEK_CUR, (ULARGE_INTEGER*)&opos); + if (FAILED(hr)) return hr; + + /* get administrative data */ + hr = IStream_Read(pStm, &obj, sizeof(obj), &count); + if (FAILED(hr)) return hr; + if (count != sizeof(obj)) return E_FAIL; + + if (piid) memcpy(piid, &obj.iid, sizeof(obj.iid)); + + /* read objref */ + if (obj.flags & OBJREF_CUSTOM) { + hr = E_INVALIDARG; + } + else { + hr = IStream_Read(pStm, pObjRef, sizeof(STDOBJREF), &count); + } + + /* return to initial position */ + IStream_Seek(pStm, opos, STREAM_SEEK_SET, NULL); + + return hr; +} + +/******************** API FUNCTIONS ********************/ + +/*********************************************************************** + * CoGetStandardMarshal [OLE32.23] + * + * When the COM library in the client process receives a marshalled + * interface pointer, it looks for a CLSID to be used in creating a proxy + * for the purposes of unmarshalling the packet. If the packet does not + * contain a CLSID for the proxy, COM calls CoGetStandardMarshal, passing a + * NULL pUnk value. + * This function creates a standard proxy in the client process and returns + * a pointer to that proxy's implementation of IMarshal. + * COM uses this pointer to call CoUnmarshalInterface to retrieve the pointer + * to the requested interface. + */ +HRESULT WINAPI CoGetStandardMarshal(REFIID riid, + IUnknown *pUnk, + DWORD dwDestContext, + LPVOID pvDestContext, + DWORD mshlFlags, + LPMARSHAL *ppMarshal) +{ + StdMarshalImpl *pMarshal; + pMarshal = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(StdMarshalImpl)); + if (!pMarshal) return E_OUTOFMEMORY; + pMarshal->lpVtbl = &StdMarshalImpl_VTable; + pMarshal->ref = 1; + *ppMarshal = (LPMARSHAL)pMarshal; + return S_OK; +} + +HRESULT WINAPI CoGetMarshalSizeMax(ULONG *pulSize, + REFIID riid, + IUnknown *pUnk, + DWORD dwDestContext, + void *pvDestContext, + DWORD mshlFlags) +{ + HRESULT hr = S_OK; + CLSID clsid; + ULONG size = 0; + LPMARSHAL pMarshal; + + *pulSize = 0; + TRACE("riid=%s, pUnk=%p, mshlFlags=0x%x\n", debugstr_guid(riid), pUnk, mshlFlags); + + /* get an IMarshal interface */ + hr = COM_GetMarshal(riid, pUnk, dwDestContext, pvDestContext, mshlFlags, &pMarshal); + if (FAILED(hr)) return hr; + + /* get unmarshal class */ + hr = IMarshal_GetUnmarshalClass(pMarshal, riid, pUnk, dwDestContext, pvDestContext, + mshlFlags, &clsid); + if (FAILED(hr)) goto fail; + + /* get marshal size */ + hr = IMarshal_GetMarshalSizeMax(pMarshal, riid, pUnk, dwDestContext, pvDestContext, + mshlFlags, &size); + if (FAILED(hr)) goto fail; + + if (!IsEqualGUID(&clsid, &CLSID_StdMarshal)) size += sizeof(struct OR_CUSTOM); + *pulSize = sizeof(OBJREF) + size; + +fail: + IMarshal_Release(pMarshal); + + return hr; +} + +HRESULT WINAPI CoMarshalInterface(IStream *pStm, + REFIID riid, + IUnknown *pUnk, + DWORD dwDestContext, + void *pvDestContext, + DWORD mshlFlags) +{ + HRESULT hr; + CLSID clsid; + LPMARSHAL pMarshal; + OBJREF obj; + struct OR_CUSTOM cobj; + ULONG count; + + /* get an IMarshal interface */ + hr = COM_GetMarshal(riid, pUnk, dwDestContext, pvDestContext, mshlFlags, &pMarshal); + if (FAILED(hr)) return hr; + + /* get unmarshal class */ + hr = IMarshal_GetUnmarshalClass(pMarshal, riid, pUnk, dwDestContext, pvDestContext, + mshlFlags, &clsid); + if (FAILED(hr)) goto fail; + + /* write marshal header */ + obj.signature = OBJREF_SIGNATURE; + if (!IsEqualGUID(&clsid, &CLSID_StdMarshal)) + obj.flags = OBJREF_CUSTOM; + else + obj.flags = OBJREF_STANDARD; + memcpy(&obj.iid, riid, sizeof(obj.iid)); + + hr = IStream_Write(pStm, &obj, sizeof(obj), &count); + if (FAILED(hr)) goto fail; + if (count != sizeof(obj)) { + hr = E_FAIL; + goto fail; + } + + if (obj.flags == OBJREF_CUSTOM) { + memcpy(&cobj.clsid, &clsid, sizeof(cobj.clsid)); + cobj.cbExtension = 0; + cobj.size = 0; + + hr = IStream_Write(pStm, &cobj, sizeof(cobj), &count); + if (FAILED(hr)) goto fail; + if (count != sizeof(cobj)) { + hr = E_FAIL; + goto fail; + } + } + + /* perform the marshaling */ + hr = IMarshal_MarshalInterface(pMarshal, pStm, riid, pUnk, dwDestContext, pvDestContext, + mshlFlags); + + + if (obj.flags == OBJREF_CUSTOM) { + FIXME("update custom-marshal size\n"); + } + +fail: + IMarshal_Release(pMarshal); + + return hr; +} + +HRESULT WINAPI CoUnmarshalInterface(IStream *pStm, + REFIID riid, + void **ppv) +{ + HRESULT hr; + LPMARSHAL pMarshal; + IID iid; + void *pv; + TRACE("pStm=%p, riid=%s, ppv=%p\n", pStm, debugstr_guid(riid), ppv); + + hr = COM_GetUnmarshal(pStm, &pMarshal, &iid); + if (FAILED(hr)) return hr; + + TRACE("Calling IMarshal::UnmarshalInterface on %p\n", pMarshal); + hr = IMarshal_UnmarshalInterface(pMarshal, pStm, &iid, &pv); + IMarshal_Release(pMarshal); + if (FAILED(hr)) return hr; + + if (IsEqualGUID(riid, &IID_NULL) || + IsEqualGUID(riid, &iid)) { + *ppv = pv; + } else { + TRACE("releasing\n"); + hr = IUnknown_QueryInterface((LPUNKNOWN)pv, riid, ppv); + IUnknown_Release((LPUNKNOWN)pv); + } + return hr; +} + +HRESULT WINAPI CoReleaseMarshalData(IStream *pStm) +{ + HRESULT hr; + LPMARSHAL pMarshal; + + hr = COM_GetUnmarshal(pStm, &pMarshal, NULL); + if (FAILED(hr)) return hr; + + hr = IMarshal_ReleaseMarshalData(pMarshal, pStm); + + IMarshal_Release(pMarshal); + + return hr; +} + +/* #define FAKE_INTERTHREAD */ + +HRESULT WINAPI CoMarshalInterThreadInterfaceInStream(REFIID riid, + LPUNKNOWN pUnk, + LPSTREAM *ppStm) +{ + HRESULT hr = CreateStreamOnHGlobal(0, TRUE, ppStm); + TRACE("(%s, %p, %p)\n",debugstr_guid(riid), pUnk, ppStm); + if (SUCCEEDED(hr)) { + LARGE_INTEGER pos; + hr = CoMarshalInterface(*ppStm, riid, pUnk, MSHCTX_INPROC, 0, MSHLFLAGS_NORMAL); + pos.s.LowPart = 0; + pos.s.HighPart = 0; + IStream_Seek(*ppStm, pos, 0, NULL); + TRACE("Marshalled OK\n"); + } + return hr; +} + + +HRESULT WINAPI CoGetInterfaceAndReleaseStream(LPSTREAM pStm, + REFIID riid, + LPVOID *ppv) +{ + TRACE("pStm=%p, riid=%s, ppv=%p\n", pStm, debugstr_guid(riid), ppv); + if (!pStm) return E_INVALIDARG; + HRESULT hr = CoUnmarshalInterface(pStm, riid, ppv); + IStream_Release(pStm); + return hr; +} + +/******************** BUILT-IN P/S MARSHALERS ********************/ + +HRESULT CALLBACK IClassFactory_CreateInstance_Proxy( + IClassFactory* This, + IUnknown* pUnkOuter, + REFIID riid, + void** ppvObject) +{ + HRESULT hr; + IUnknown* proxy = NULL; + TRACE("(%p,%p,%s,%p)\n", This, pUnkOuter, debugstr_guid(riid), ppvObject); + hr = IClassFactory_RemoteCreateInstance_Proxy(This, riid, &proxy); + *ppvObject = proxy; + if (pUnkOuter) { + /* I'm not sure yet how to handle this, I think we're supposed + * to let the proxy manager aggregate into pUnkOuter */ + FIXME("remote aggregation not supported yet\n"); + } + return hr; +} + +HRESULT __RPC_STUB IClassFactory_CreateInstance_Stub( + IClassFactory* This, + REFIID riid, + IUnknown** ppvObject) +{ + HRESULT hr; + TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppvObject); + *ppvObject = NULL; + hr = IClassFactory_CreateInstance(This, NULL, riid, ppvObject); + return hr; +} + +HRESULT CALLBACK IClassFactory_LockServer_Proxy( + IClassFactory* This, + BOOL fLock) +{ + TRACE("(%p,%d)\n", This, fLock); + return IClassFactory_RemoteLockServer_Proxy(This, fLock); +} + +HRESULT __RPC_STUB IClassFactory_LockServer_Stub( + IClassFactory* This, + BOOL fLock) +{ + TRACE("(%p,%d)\n", This, fLock); + return IClassFactory_LockServer(This, fLock); +} + +#if 0 +/* we need to create an IDL compiler for Wine that can generate + * most of these automatically */ + +const MIDL_STUB_DESC Object_StubDesc = { + 0, + NdrOleAllocate, + NdrOleFree, + {0}, 0, 0, 0, 0, + 0 /* __MIDL_TypeFormatString.Format */ +}; + +#define INTERFACES 2 + +HRESULT WINAPI IClassFactory_CreateInstance_Proxy(LPCLASSFACTORY This, + LPUNKNOWN pUnkOuter, + REFIID riid, + LPVOID *ppv) +{ + HRESULT ret = E_FAIL; + RPC_MESSAGE Msg; + MIDL_STUB_MESSAGE StubMsg; + LPUNKNOWN pvObj = NULL; + BOOL not_null; + + TRACE("(%p,%p,%s,%p)\n", This, pUnkOuter, debugstr_guid(riid), ppv); + *ppv = NULL; + + NdrProxyInitialize(This, &Msg, &StubMsg, &Object_StubDesc, 3); + + StubMsg.BufferLength = sizeof(IID); + NdrProxyGetBuffer(This, &StubMsg); + + /* FIXME: use NdrSimpleStructMarshall instead of memcpy */ + memcpy(StubMsg.Buffer, riid, sizeof(IID)); + StubMsg.Buffer += sizeof(IID); + + NdrProxySendReceive(This, &StubMsg); + + /* FIXME: NdrPointerUnmarshall */ + memcpy(¬_null, StubMsg.Buffer, sizeof(BOOL)); + StubMsg.Buffer += sizeof(BOOL); + if (not_null) + NdrInterfacePointerUnmarshall(&StubMsg, + (unsigned char**)&pvObj, + NULL, + 0); + memcpy(&ret, StubMsg.Buffer, sizeof(HRESULT)); + StubMsg.Buffer += sizeof(HRESULT); + + NdrProxyFreeBuffer(This, &StubMsg); + + if (pvObj) + ret = IUnknown_QueryInterface(pvObj, riid, ppv); + + return ret; +} + +HRESULT WINAPI IClassFactory_LockServer_Proxy(LPCLASSFACTORY This, + BOOL fLock) +{ + FIXME("(%p,%d):stub\n", This, fLock); + return S_OK; +} + +const CINTERFACE_PROXY_VTABLE(5) IClassFactoryProxyVtbl = { + {&IID_IClassFactory}, + {IUnknown_QueryInterface_Proxy, + IUnknown_AddRef_Proxy, + IUnknown_Release_Proxy, + IClassFactory_CreateInstance_Proxy, + IClassFactory_LockServer_Proxy} +}; + +/* FIXME: this marshalling is not done exactly like MS's, + * so it needs to be fixed for real DCOM, but for real DCOM + * we should probably implement a real IDL compiler anyway */ + +void __RPC_STUB IClassFactory_RemoteCreateInstance_Stub(LPRPCSTUBBUFFER This, + LPRPCCHANNELBUFFER pChannel, + PRPC_MESSAGE pMsg, + DWORD *pdwPhase) +{ + LPCLASSFACTORY pServer = (LPCLASSFACTORY)((CStdStubBuffer*)This)->pvServerObject; + HRESULT ret = E_FAIL; + MIDL_STUB_MESSAGE StubMsg; + IID iid; + LPVOID pvObj = NULL; + BOOL not_null; + + TRACE("(%p,%p,%p,%p)\n", This, pChannel, pMsg, pdwPhase); + + NdrStubInitialize(pMsg, &StubMsg, &Object_StubDesc, pChannel); + /* FIXME: use NdrSimpleStructUnmarshall instead of memcpy */ + memcpy(&iid, StubMsg.Buffer, sizeof(IID)); + StubMsg.Buffer += sizeof(IID); + + *pdwPhase = STUB_CALL_SERVER; + TRACE("->(%p,NULL,%s,%p)\n", pServer, debugstr_guid(&iid), &pvObj); + TRACE("vtbl=%p\n", pServer->lpVtbl); + ret = IClassFactory_CreateInstance(pServer, NULL, &iid, &pvObj); + TRACE("<-(%p) %08lx\n", pvObj, ret); + not_null = (pvObj != NULL); + *pdwPhase = STUB_MARSHAL; + + StubMsg.BufferLength = sizeof(BOOL); + if (not_null) { + /* seems MaxCount is used to store the riid for interface marshaling */ + StubMsg.MaxCount = (ULONG_PTR)&iid; + NdrInterfacePointerBufferSize(&StubMsg, + (unsigned char*)pvObj, + NULL); + } + StubMsg.BufferLength += sizeof(HRESULT); + NdrStubGetBuffer(This, pChannel, &StubMsg); + /* FIXME: NdrPointerMarshall */ + memcpy(StubMsg.Buffer, ¬_null, sizeof(BOOL)); + StubMsg.Buffer += sizeof(BOOL); + if (not_null) { + StubMsg.MaxCount = (ULONG_PTR)&iid; + NdrInterfacePointerMarshall(&StubMsg, + (unsigned char*)pvObj, + NULL); + } + memcpy(StubMsg.Buffer, &ret, sizeof(HRESULT)); + StubMsg.Buffer += sizeof(HRESULT); +} + +void __RPC_STUB IClassFactory_RemoteLockServer_Stub(LPRPCSTUBBUFFER This, + LPRPCCHANNELBUFFER pChannel, + PRPC_MESSAGE pMsg, + DWORD *pdwPhase) +{ + FIXME("(%p,%p,%p,%p):stub\n", This, pChannel, pMsg, pdwPhase); +} + +const PRPC_STUB_FUNCTION IClassFactory_table[] = { + IClassFactory_RemoteCreateInstance_Stub, + IClassFactory_RemoteLockServer_Stub +}; + +const CInterfaceStubVtbl IClassFactoryStubVtbl = { + {&IID_IClassFactory, + 0, + 5, + &IClassFactory_table[-3]}, + {CStdStubBuffer_METHODS} +}; + +const CInterfaceProxyVtbl* _compobj_ProxyVtblList[INTERFACES+1] = { + 0, + (CInterfaceProxyVtbl*)&IClassFactoryProxyVtbl, + 0 +}; + +const CInterfaceStubVtbl* _compobj_StubVtblList[INTERFACES+1] = { + 0, + (CInterfaceStubVtbl*)&IClassFactoryStubVtbl, + 0 +}; + +const PCInterfaceName _compobj_InterfaceNamesList[INTERFACES+1] = { + "IRemUnknown", + "IClassFactory", + 0 +}; + +int __stdcall _compobj_IID_Lookup(const IID *pIID, int *pIndex) +{ + unsigned u; + /* the purpose of this routine is probably to "unroll" + * this kind of for loop, but without an IDL compiler, + * maintainability is more important */ + for (u=1; u<INTERFACES; u++) { + if (!IID_GENERIC_CHECK_IID(_compobj, pIID, u)) { + *pIndex = u; + return 1; + } + } + return 0; +} + +const ExtendedProxyFileInfo compobj_ProxyFileInfo = { + (PCInterfaceProxyVtblList*)&_compobj_ProxyVtblList, + (PCInterfaceStubVtblList*)&_compobj_StubVtblList, + (const PCInterfaceName*)&_compobj_InterfaceNamesList, + 0, /* pDelegatedIIDs */ + &_compobj_IID_Lookup, + INTERFACES, /* TableSize */ + 1 /* TableVersion */ +}; +#endif + +extern const ExtendedProxyFileInfo dcom_ProxyFileInfo; +extern const ExtendedProxyFileInfo unknwn_ProxyFileInfo; + +const ProxyFileInfo* OLE32_ProxyFileList[] = { + &unknwn_ProxyFileInfo, + &dcom_ProxyFileInfo, + NULL +}; + +static CStdPSFactoryBuffer PSFactoryBuffer; + +CSTDSTUBBUFFERRELEASE(&PSFactoryBuffer) + +static HRESULT COM_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) +{ + return NdrDllGetClassObject(rclsid, riid, ppv, OLE32_ProxyFileList, + &CLSID_PSFactoryBuffer, &PSFactoryBuffer); +} + + +/*********************************************************************** + * DllGetClassObject [OLE32.63] + */ +HRESULT WINAPI OLE32_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) +{ + if (IsEqualGUID(rclsid, &CLSID_PSFactoryBuffer)) + return COM_DllGetClassObject(rclsid, riid, ppv); + if (IsEqualIID(rclsid,&CLSID_StdGlobalInterfaceTable) && (IsEqualIID(riid,&IID_IClassFactory) || IsEqualIID(riid,&IID_IUnknown))) + return StdGlobalInterfaceTable_GetFactory(ppv); + + FIXME("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(riid)); + return CLASS_E_CLASSNOTAVAILABLE; +} --- /dev/null 2003-01-30 10:24:37.000000000 +0000 +++ dlls/ole32/unknwn_p.c 2003-10-01 17:08:50.000000000 +0100 @@ -0,0 +1,509 @@ +/* this ALWAYS GENERATED file contains the proxy stub code */ + + +/* File created by MIDL compiler version 5.01.0164 */ +/* at Fri May 23 15:29:11 2003 + */ +/* Compiler settings for unknwn.idl: + Os (OptLev=s), W1, Zp8, env=Win32, ms_ext, c_ext + error checks: allocation ref bounds_check enum stub_data +*/ +//@@MIDL_FILE_HEADING( ) + + +/* verify that the <rpcproxy.h> version is high enough to compile this file*/ +#ifndef __REDQ_RPCPROXY_H_VERSION__ +#define __REQUIRED_RPCPROXY_H_VERSION__ 440 +#endif + +#include "windef.h" +#include "objbase.h" +#include "objidl.h" + +#undef __WINE__ +#include "rpc.h" +#include "rpcproxy.h" +#ifndef __RPCPROXY_H_VERSION__ +#error this stub requires an updated version of <rpcproxy.h> +#endif // __RPCPROXY_H_VERSION__ + + +#include "unknwn.h" + +#define TYPE_FORMAT_STRING_SIZE 35 +#define PROC_FORMAT_STRING_SIZE 15 + +typedef struct _MIDL_TYPE_FORMAT_STRING + { + short Pad; + unsigned char Format[ TYPE_FORMAT_STRING_SIZE ]; + } MIDL_TYPE_FORMAT_STRING; + +typedef struct _MIDL_PROC_FORMAT_STRING + { + short Pad; + unsigned char Format[ PROC_FORMAT_STRING_SIZE ]; + } MIDL_PROC_FORMAT_STRING; + + +extern const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString; +extern const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString; + + +/* Standard interface: __MIDL_itf_unknwn_0000, ver. 0.0, + GUID={0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} */ + + +/* Object interface: IUnknown, ver. 0.0, + GUID={0x00000000,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +/* Object interface: IClassFactory, ver. 0.0, + GUID={0x00000001,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +extern const MIDL_STUB_DESC Object_StubDesc; + + +#pragma code_seg(".orpc") + +/* [call_as] */ HRESULT STDMETHODCALLTYPE IClassFactory_RemoteCreateInstance_Proxy( + IClassFactory __RPC_FAR * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppvObject) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(ppvObject) + { + MIDL_memset( + ppvObject, + 0, + sizeof( IUnknown __RPC_FAR *__RPC_FAR * )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 3); + + + + if(!riid) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!ppvObject) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrSimpleStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)riid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[12] ); + + NdrProxyGetBuffer(This, &_StubMsg); + NdrSimpleStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)riid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[12] ); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[0] ); + + NdrPointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ppvObject, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[24], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *(( HRESULT __RPC_FAR * )_StubMsg.Buffer)++; + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _StubMsg.MaxCount = (unsigned long) ( riid ); + + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[24], + ( void __RPC_FAR * )ppvObject); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB IClassFactory_RemoteCreateInstance_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + IUnknown __RPC_FAR *__RPC_FAR *_M0; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + IUnknown __RPC_FAR *__RPC_FAR *ppvObject; + REFIID riid; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + ( REFIID )riid = 0; + ( IUnknown __RPC_FAR *__RPC_FAR * )ppvObject = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[0] ); + + NdrSimpleStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&riid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[12], + (unsigned char)0 ); + + ppvObject = &_M0; + _M0 = 0; + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = IClassFactory_CreateInstance_Stub( + (IClassFactory *) ((CStdStubBuffer *)This)->pvServerObject, + riid, + ppvObject); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 0U + 4U; + _StubMsg.MaxCount = (unsigned long) ( riid ); + + NdrPointerBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ppvObject, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[24] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + _StubMsg.MaxCount = (unsigned long) ( riid ); + + NdrPointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ppvObject, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[24] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *(( HRESULT __RPC_FAR * )_StubMsg.Buffer)++ = _RetVal; + + } + RpcFinally + { + _StubMsg.MaxCount = (unsigned long) ( riid ); + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)ppvObject, + &__MIDL_TypeFormatString.Format[24] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +/* [call_as] */ HRESULT __stdcall IClassFactory_RemoteLockServer_Proxy( + IClassFactory __RPC_FAR * This, + /* [in] */ BOOL fLock) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 4); + + + + RpcTryFinally + { + + _StubMsg.BufferLength = 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *(( BOOL __RPC_FAR * )_StubMsg.Buffer)++ = fLock; + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[10] ); + + _RetVal = *(( HRESULT __RPC_FAR * )_StubMsg.Buffer)++; + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB IClassFactory_RemoteLockServer_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + BOOL fLock; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[10] ); + + fLock = *(( BOOL __RPC_FAR * )_StubMsg.Buffer)++; + + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = IClassFactory_LockServer_Stub((IClassFactory *) ((CStdStubBuffer *)This)->pvServerObject,fLock); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U; + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *(( HRESULT __RPC_FAR * )_StubMsg.Buffer)++ = _RetVal; + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +static const MIDL_STUB_DESC Object_StubDesc = + { + 0, + NdrOleAllocate, + NdrOleFree, + 0, + 0, + 0, + 0, + 0, + __MIDL_TypeFormatString.Format, + 1, /* -error bounds_check flag */ + 0x10001, /* Ndr library version */ + 0, + 0x50100a4, /* MIDL Version 5.1.164 */ + 0, + 0, + 0, /* notify & notify_flag routine table */ + 1, /* Flags */ + 0, /* Reserved3 */ + 0, /* Reserved4 */ + 0 /* Reserved5 */ + }; + +const CINTERFACE_PROXY_VTABLE(5) _IClassFactoryProxyVtbl = +{ + &IID_IClassFactory, + IUnknown_QueryInterface_Proxy, + IUnknown_AddRef_Proxy, + IUnknown_Release_Proxy , + IClassFactory_CreateInstance_Proxy , + IClassFactory_LockServer_Proxy +}; + + +static const PRPC_STUB_FUNCTION IClassFactory_table[] = +{ + IClassFactory_RemoteCreateInstance_Stub, + IClassFactory_RemoteLockServer_Stub +}; + +const CInterfaceStubVtbl _IClassFactoryStubVtbl = +{ + &IID_IClassFactory, + 0, + 5, + &IClassFactory_table[-3], + CStdStubBuffer_METHODS +}; + +#pragma data_seg(".rdata") + +#if !defined(__RPC_WIN32__) +#error Invalid build platform for this stub. +#endif + +static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString = + { + 0, + { + + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 2 */ NdrFcShort( 0x2 ), /* Type Offset=2 */ +/* 4 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 6 */ NdrFcShort( 0x18 ), /* Type Offset=24 */ +/* 8 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 10 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 12 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ + + 0x0 + } + }; + +static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString = + { + 0, + { + NdrFcShort( 0x0 ), /* 0 */ +/* 2 */ + 0x11, 0x0, /* FC_RP */ +/* 4 */ NdrFcShort( 0x8 ), /* Offset= 8 (12) */ +/* 6 */ + 0x1d, /* FC_SMFARRAY */ + 0x0, /* 0 */ +/* 8 */ NdrFcShort( 0x8 ), /* 8 */ +/* 10 */ 0x2, /* FC_CHAR */ + 0x5b, /* FC_END */ +/* 12 */ + 0x15, /* FC_STRUCT */ + 0x3, /* 3 */ +/* 14 */ NdrFcShort( 0x10 ), /* 16 */ +/* 16 */ 0x8, /* FC_LONG */ + 0x6, /* FC_SHORT */ +/* 18 */ 0x6, /* FC_SHORT */ + 0x4c, /* FC_EMBEDDED_COMPLEX */ +/* 20 */ 0x0, /* 0 */ + NdrFcShort( 0xfffffff1 ), /* Offset= -15 (6) */ + 0x5b, /* FC_END */ +/* 24 */ + 0x11, 0x14, /* FC_RP [alloced_on_stack] */ +/* 26 */ NdrFcShort( 0x2 ), /* Offset= 2 (28) */ +/* 28 */ + 0x2f, /* FC_IP */ + 0x5c, /* FC_PAD */ +/* 30 */ 0x28, /* Corr desc: parameter, FC_LONG */ + 0x0, /* */ +#ifndef _ALPHA_ +/* 32 */ NdrFcShort( 0x4 ), /* x86, MIPS, PPC Stack size/offset = 4 */ +#else + NdrFcShort( 0x8 ), /* Alpha Stack size/offset = 8 */ +#endif + + 0x0 + } + }; + +const CInterfaceProxyVtbl * _unknwn_ProxyVtblList[] = +{ + ( CInterfaceProxyVtbl *) &_IClassFactoryProxyVtbl, + 0 +}; + +const CInterfaceStubVtbl * _unknwn_StubVtblList[] = +{ + ( CInterfaceStubVtbl *) &_IClassFactoryStubVtbl, + 0 +}; + +PCInterfaceName const _unknwn_InterfaceNamesList[] = +{ + "IClassFactory", + 0 +}; + + +#define _unknwn_CHECK_IID(n) IID_GENERIC_CHECK_IID( _unknwn, pIID, n) + +int __stdcall _unknwn_IID_Lookup( const IID * pIID, int * pIndex ) +{ + + if(!_unknwn_CHECK_IID(0)) + { + *pIndex = 0; + return 1; + } + + return 0; +} + +const ExtendedProxyFileInfo unknwn_ProxyFileInfo = +{ + (PCInterfaceProxyVtblList *) & _unknwn_ProxyVtblList, + (PCInterfaceStubVtblList *) & _unknwn_StubVtblList, + (const PCInterfaceName * ) & _unknwn_InterfaceNamesList, + 0, // no delegation + & _unknwn_IID_Lookup, + 1, + 1, + 0, /* table of [async_uuid] interfaces */ + 0, /* Filler1 */ + 0, /* Filler2 */ + 0 /* Filler3 */ +};