merged rpcrt-dll part from transgaming (Ove) --- juergen.schmied@debitel.net
Index: wine/dlls/rpcrt4/Makefile.in =================================================================== RCS file: /home/wine/wine/dlls/rpcrt4/Makefile.in,v retrieving revision 1.8 diff -d -u -r1.8 Makefile.in --- wine/dlls/rpcrt4/Makefile.in 17 May 2002 03:37:14 -0000 1.8 +++ wine/dlls/rpcrt4/Makefile.in 16 Jun 2002 10:53:10 -0000 @@ -4,14 +4,29 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = rpcrt4.dll -IMPORTS = kernel32 +IMPORTS = kernel32 ntdll advapi32 +EXTRALIBS = $(LIBUUID) LDDLLFLAGS = @LDDLLFLAGS@ SYMBOLFILE = $(MODULE).tmp.o C_SRCS = \ + cproxy.c \ + cpsf.c \ + cstub.c \ + ndr_midl.c \ + ndr_ole.c \ + ndr_stubless.c \ + rpc_binding.c \ + rpc_epmap.c \ + rpc_message.c \ + rpc_server.c \ rpcrt4_main.c @MAKE_DLL_RULES@ ### Dependencies: + + + + Index: wine/dlls/rpcrt4/rpcrt4.spec =================================================================== RCS file: /home/wine/wine/dlls/rpcrt4/rpcrt4.spec,v retrieving revision 1.17 diff -d -u -r1.17 rpcrt4.spec --- wine/dlls/rpcrt4/rpcrt4.spec 13 Jun 2002 21:50:12 -0000 1.17 +++ wine/dlls/rpcrt4/rpcrt4.spec 16 Jun 2002 10:53:11 -0000 @@ -18,11 +18,6 @@ @ stub MqGetContext # win9x @ stub MqRegisterQueue # win9x -@ stdcall NdrDllCanUnloadNow(ptr) NdrDllCanUnloadNow -@ stdcall NdrDllGetClassObject(ptr ptr ptr ptr ptr ptr) NdrDllGetClassObject -@ stdcall NdrDllRegisterProxy(long ptr ptr) NdrDllRegisterProxy -@ stub NdrDllUnregisterProxy - @ stub RpcAbortAsyncCall @ stub RpcAsyncAbortCall @ stub RpcAsyncCancelCall @@ -42,7 +37,7 @@ @ stub RpcBindingInqAuthInfoW @ stub RpcBindingInqAuthInfoExA @ stub RpcBindingInqAuthInfoExW -@ stub RpcBindingInqObject +@ stdcall RpcBindingInqObject(ptr ptr) RpcBindingInqObject @ stub RpcBindingInqOption @ stub RpcBindingReset @ stub RpcBindingServerFromClient @@ -50,23 +45,23 @@ @ stub RpcBindingSetAuthInfoW @ stub RpcBindingSetAuthInfoExA @ stub RpcBindingSetAuthInfoExW -@ stub RpcBindingSetObject +@ stdcall RpcBindingSetObject(ptr ptr) RpcBindingSetObject @ stub RpcBindingSetOption -@ stub RpcBindingToStringBindingA -@ stub RpcBindingToStringBindingW -@ stub RpcBindingVectorFree +@ stdcall RpcBindingToStringBindingA(ptr ptr) RpcBindingToStringBindingA +@ stdcall RpcBindingToStringBindingW(ptr ptr) RpcBindingToStringBindingW +@ stdcall RpcBindingVectorFree(ptr) RpcBindingVectorFree @ stub RpcCancelAsyncCall @ stub RpcCancelThread @ stub RpcCancelThreadEx @ stub RpcCertGeneratePrincipalNameA @ stub RpcCertGeneratePrincipalNameW @ stub RpcCompleteAsyncCall -@ stub RpcEpRegisterA +@ stdcall RpcEpRegisterA(ptr ptr ptr str) RpcEpRegisterA @ stub RpcEpRegisterW @ stub RpcEpRegisterNoReplaceA @ stub RpcEpRegisterNoReplaceW -@ stub RpcEpResolveBinding -@ stub RpcEpUnregister +@ stdcall RpcEpResolveBinding(ptr ptr) RpcEpResolveBinding +@ stdcall RpcEpUnregister(ptr ptr ptr) RpcEpUnregister @ stub RpcGetAsyncCallStatus @ stub RpcIfIdVectorFree @ stub RpcIfInqId @@ -111,7 +106,7 @@ @ stub RpcRegisterAsyncInfo @ stub RpcRevertToSelf @ stub RpcRevertToSelfEx -@ stub RpcServerInqBindings +@ stdcall RpcServerInqBindings(ptr) RpcServerInqBindings @ stub RpcServerInqDefaultPrincNameA @ stub RpcServerInqDefaultPrincNameW @ stub RpcServerInqIf @@ -163,49 +158,54 @@ @ stub RpcSsSwapClientAllocFree @ stdcall RpcStringBindingComposeA(str str str str str ptr) RpcStringBindingComposeA @ stdcall RpcStringBindingComposeW(wstr wstr wstr wstr wstr ptr) RpcStringBindingComposeW -@ stub RpcStringBindingParseA -@ stub RpcStringBindingParseW +@ stdcall RpcStringBindingParseA(str ptr ptr ptr ptr ptr) RpcStringBindingParseA +@ stdcall RpcStringBindingParseW(wstr ptr ptr ptr ptr ptr) RpcStringBindingParseW @ stdcall RpcStringFreeA(ptr) RpcStringFreeA -@ stub RpcStringFreeW +@ stdcall RpcStringFreeW(ptr) RpcStringFreeW @ stub RpcTestCancel @ stub TowerConstruct @ stub TowerExplode @ stub UuidCompare -@ stdcall UuidCreate(ptr) UuidCreate -@ stdcall UuidCreateSequential(ptr) UuidCreateSequential # win 2000 -@ stub UuidCreateNil -@ stub UuidEqual -@ stdcall UuidFromStringA(ptr ptr) UuidFromStringA -@ stdcall UuidFromStringW(ptr ptr) UuidFromStringW -@ stdcall UuidHash(ptr ptr) UuidHash -@ stub UuidIsNil -@ stdcall UuidToStringA(ptr ptr) UuidToStringA -@ stub UuidToStringW +@ stdcall UuidCreate(ptr) UuidCreate +@ stdcall UuidCreateNil(ptr) UuidCreateNil +@ stdcall UuidCreateSequential(ptr) UuidCreateSequential +@ stdcall UuidEqual(ptr ptr ptr) UuidEqual +@ stdcall UuidFromStringA(str ptr) UuidFromStringA +@ stdcall UuidFromStringW(wstr ptr) UuidFromStringW +@ stdcall UuidHash(ptr ptr) UuidHash +@ stdcall UuidIsNil(ptr ptr) UuidIsNil +@ stdcall UuidToStringA(ptr ptr) UuidToStringA +@ stdcall UuidToStringW(ptr ptr) UuidToStringW -@ stub CStdStubBuffer_QueryInterface -@ stub CStdStubBuffer_AddRef -@ stub CStdStubBuffer_Connect -@ stub CStdStubBuffer_Disconnect -@ stub CStdStubBuffer_Invoke -@ stub CStdStubBuffer_IsIIDSupported -@ stub CStdStubBuffer_CountRefs -@ stub CStdStubBuffer_DebugServerQueryInterface -@ stub CStdStubBuffer_DebugServerRelease +@ stdcall CStdStubBuffer_QueryInterface(ptr ptr) CStdStubBuffer_QueryInterface +@ stdcall CStdStubBuffer_AddRef(ptr) CStdStubBuffer_AddRef +@ stdcall CStdStubBuffer_Connect(ptr ptr) CStdStubBuffer_Connect +@ stdcall CStdStubBuffer_Disconnect(ptr) CStdStubBuffer_Disconnect +@ stdcall CStdStubBuffer_Invoke(ptr ptr ptr) CStdStubBuffer_Invoke +@ stdcall CStdStubBuffer_IsIIDSupported(ptr ptr) CStdStubBuffer_IsIIDSupported +@ stdcall CStdStubBuffer_CountRefs(ptr) CStdStubBuffer_CountRefs +@ stdcall CStdStubBuffer_DebugServerQueryInterface(ptr ptr) CStdStubBuffer_DebugServerQueryInterface +@ stdcall CStdStubBuffer_DebugServerRelease(ptr ptr) CStdStubBuffer_DebugServerRelease +@ stdcall NdrCStdStubBuffer_Release(ptr ptr) NdrCStdStubBuffer_Release @ stub NdrCStdStubBuffer2_Release -@ stub NdrCStdStubBuffer_Release -@ stub IUnknown_QueryInterface_Proxy -@ stub IUnknown_AddRef_Proxy -@ stub IUnknown_Release_Proxy +@ stdcall IUnknown_QueryInterface_Proxy(ptr ptr ptr) IUnknown_QueryInterface_Proxy +@ stdcall IUnknown_AddRef_Proxy(ptr) IUnknown_AddRef_Proxy +@ stdcall IUnknown_Release_Proxy(ptr) IUnknown_Release_Proxy + +@ stdcall NdrDllCanUnloadNow(ptr) NdrDllCanUnloadNow +@ stdcall NdrDllGetClassObject(ptr ptr ptr ptr ptr ptr) NdrDllGetClassObject +@ stdcall NdrDllRegisterProxy(long ptr ptr) NdrDllRegisterProxy +@ stdcall NdrDllUnregisterProxy(long ptr ptr) NdrDllUnregisterProxy @ stub NdrAllocate @ stub NdrAsyncClientCall @ stub NdrAsyncServerCall @ stub NdrClearOutParameters @ stub NdrClientCall -@ stub NdrClientCall2 +@ varargs NdrClientCall2(ptr ptr) NdrClientCall2 @ stub NdrClientInitialize @ stub NdrClientInitializeNew @ stub NdrContextHandleInitialize @@ -246,18 +246,18 @@ @ stub NdrMesTypeFree2 @ stub NdrNsGetBuffer @ stub NdrNsSendReceive -@ stub NdrOleAllocate -@ stub NdrOleFree +@ stdcall NdrOleAllocate(long) NdrOleAllocate +@ stdcall NdrOleFree(ptr) NdrOleFree @ stub NdrPipePull @ stub NdrPipePush @ stub NdrPipeSendReceive @ stub NdrPipesDone @ stub NdrPipesInitialize @ stub NdrProxyErrorHandler -@ stub NdrProxyFreeBuffer -@ stub NdrProxyGetBuffer -@ stub NdrProxyInitialize -@ stub NdrProxySendReceive +@ stdcall NdrProxyFreeBuffer(ptr ptr) NdrProxyFreeBuffer +@ stdcall NdrProxyGetBuffer(ptr ptr) NdrProxyGetBuffer +@ stdcall NdrProxyInitialize(ptr ptr ptr ptr long) NdrProxyInitialize +@ stdcall NdrProxySendReceive(ptr ptr) NdrProxySendReceive @ stub NdrRangeUnmarshall @ stub NdrRpcSmClientAllocate @ stub NdrRpcSmClientFree @@ -272,7 +272,9 @@ @ stub NdrStubCall @ stub NdrStubCall2 @ stub NdrStubForwardingFunction -@ stub NdrStubGetBuffer +@ stdcall NdrStubGetBuffer(ptr ptr ptr) NdrStubGetBuffer +@ stdcall NdrStubInitialize(ptr ptr ptr ptr) NdrStubInitialize +@ stub NdrStubInitializeMarshall @ stub NdrpSetRpcSsDefaults @ stub NdrByteCountPointerBufferSize @@ -325,11 +327,11 @@ @ stub NdrHardStructMarshall @ stub NdrHardStructMemorySize @ stub NdrHardStructUnmarshall -@ stub NdrInterfacePointerBufferSize -@ stub NdrInterfacePointerFree -@ stub NdrInterfacePointerMarshall -@ stub NdrInterfacePointerMemorySize -@ stub NdrInterfacePointerUnmarshall +@ stdcall NdrInterfacePointerBufferSize(ptr ptr ptr) NdrInterfacePointerBufferSize +@ stdcall NdrInterfacePointerFree(ptr ptr ptr) NdrInterfacePointerFree +@ stdcall NdrInterfacePointerMarshall(ptr ptr ptr) NdrInterfacePointerMarshall +@ stdcall NdrInterfacePointerMemorySize(ptr ptr) NdrInterfacePointerMemorySize +@ stdcall NdrInterfacePointerUnmarshall(ptr ptr ptr long) NdrInterfacePointerUnmarshall @ stub NdrNonConformantStringBufferSize @ stub NdrNonConformantStringMarshall @ stub NdrNonConformantStringMemorySize @@ -359,8 +361,6 @@ @ stub NdrSimpleStructUnmarshall @ stub NdrSimpleTypeMarshall @ stub NdrSimpleTypeUnmarshall -@ stub NdrStubInitialize -@ stub NdrStubInitializeMarshall @ stub NdrUserMarshalBufferSize @ stub NdrUserMarshalFree @ stub NdrUserMarshalMarshall @@ -428,17 +428,18 @@ @ stub I_RpcBindingInqWireIdForSnego @ stub I_RpcBindingIsClientLocal @ stub I_RpcBindingToStaticStringBindingW -@ stub I_RpcBindingSetAsync # win9x +@ stdcall I_RpcBindingSetAsync(ptr ptr long) I_RpcBindingSetAsync # win9x +# NT version of I_RpcBindingSetAsync has 2 arguments, not 3 @ stub I_RpcClearMutex @ stub I_RpcConnectionInqSockBuffSize @ stub I_RpcConnectionInqSockBuffSize2 @ stub I_RpcConnectionSetSockBuffSize @ stub I_RpcDeleteMutex @ stub I_RpcFree -@ stub I_RpcFreeBuffer +@ stdcall I_RpcFreeBuffer(ptr) I_RpcFreeBuffer @ stub I_RpcFreePipeBuffer @ stub I_RpcGetAssociationContext -@ stub I_RpcGetBuffer +@ stdcall I_RpcGetBuffer(ptr) I_RpcGetBuffer @ stub I_RpcGetBufferWithObject @ stub I_RpcGetCurrentCallHandle @ stub I_RpcGetExtendedError @@ -458,17 +459,17 @@ @ stub I_RpcParseSecurity @ stub I_RpcPauseExecution @ stub I_RpcReallocPipeBuffer -@ stub I_RpcReceive +@ stdcall I_RpcReceive(ptr) I_RpcReceive @ stub I_RpcRequestMutex -@ stub I_RpcSend -@ stub I_RpcSendReceive +@ stdcall I_RpcSend(ptr) I_RpcSend +@ stdcall I_RpcSendReceive(ptr) I_RpcSendReceive @ stub I_RpcServerAllocateIpPort @ stub I_RpcServerInqAddressChangeFn @ stub I_RpcServerInqTransportType @ stub I_RpcServerRegisterForwardFunction @ stub I_RpcServerSetAddressChangeFn -@ stub I_RpcServerStartListening # win9x -@ stub I_RpcServerStopListening # win9x +@ stdcall I_RpcServerStartListening(ptr) I_RpcServerStartListening # win9x +@ stdcall I_RpcServerStopListening() I_RpcServerStopListening # win9x @ stub I_RpcServerUnregisterEndpointA # win9x @ stub I_RpcServerUnregisterEndpointW # win9x @ stub I_RpcServerUseProtseq2A @@ -505,7 +506,7 @@ @ stub I_RpcTransServerReallocBuffer # win9x @ stub I_RpcTransServerReceiveDirectReady # win9x @ stub I_RpcTransServerUnprotectThread # win9x -@ stub I_RpcWindowProc # win9x +@ stdcall I_RpcWindowProc(ptr long long long) I_RpcWindowProc # win9x @ stub I_RpcltDebugSetPDUFilter @ stub I_UuidCreate @@ -515,3 +516,5 @@ @ stub StartServiceIfNecessary # win9x @ stub GlobalMutexClearExternal @ stub GlobalMutexRequestExternal + + Index: wine/dlls/rpcrt4/rpcrt4_main.c =================================================================== RCS file: /home/wine/wine/dlls/rpcrt4/rpcrt4_main.c,v retrieving revision 1.25 diff -d -u -r1.25 rpcrt4_main.c --- wine/dlls/rpcrt4/rpcrt4_main.c 13 Jun 2002 21:50:12 -0000 1.25 +++ wine/dlls/rpcrt4/rpcrt4_main.c 16 Jun 2002 10:53:12 -0000 @@ -28,9 +28,9 @@ #include <unistd.h> #include "windef.h" -#include "wine/windef16.h" #include "winerror.h" #include "winbase.h" +#include "wine/unicode.h" #include "rpc.h" #include "ole2.h" @@ -58,8 +58,12 @@ #include "wine/debug.h" +#include "rpc_binding.h" + WINE_DEFAULT_DEBUG_CHANNEL(ole); +static UUID uuid_nil; + /*********************************************************************** * RPCRT4_LibMain * @@ -87,6 +91,41 @@ return TRUE; } + +/************************************************************************* + * RpcStringFreeA [RPCRT4.@] + * + * Frees a character string allocated by the RPC run-time library. + * + * RETURNS + * + * S_OK if successful. + */ +RPC_STATUS WINAPI RpcStringFreeA(LPSTR* String) +{ + HeapFree( GetProcessHeap(), 0, *String); + + return RPC_S_OK; +} + + +/************************************************************************* + * RpcStringFreeW [RPCRT4.@] + * + * Frees a character string allocated by the RPC run-time library. + * + * RETURNS + * + * S_OK if successful. + */ +RPC_STATUS WINAPI RpcStringFreeW(LPWSTR* String) +{ + HeapFree( GetProcessHeap(), 0, *String); + + return RPC_S_OK; +} + + /************************************************************************* * UuidCreate [RPCRT4.@] * @@ -105,11 +144,11 @@ static unsigned char a[6]; static int adjustment = 0; static struct timeval last = {0, 0}; - static UINT16 clock_seq; + static WORD clock_seq; struct timeval tv; unsigned long long clock_reg; - UINT clock_high, clock_low; - UINT16 temp_clock_seq, temp_clock_mid, temp_clock_hi_and_version; + DWORD clock_high, clock_low; + WORD temp_clock_seq, temp_clock_mid, temp_clock_hi_and_version; #ifdef HAVE_NET_IF_H int sd; struct ifreq ifr, *ifrp; @@ -248,7 +287,7 @@ clock_high = clock_reg >> 32; clock_low = clock_reg; temp_clock_seq = clock_seq | 0x8000; - temp_clock_mid = (UINT16)clock_high; + temp_clock_mid = (WORD)clock_high; temp_clock_hi_and_version = (clock_high >> 16) | 0x1000; /* pack the information into the GUID structure */ @@ -285,6 +324,14 @@ return RPC_S_OK; } +/************************************************************************* + * UuidCreateNil [RPCRT4.@] + */ +RPC_STATUS WINAPI UuidCreateNil(UUID *Uuid) +{ + *Uuid = uuid_nil; + return RPC_S_OK; +} /************************************************************************* * UuidCreateSequential [RPCRT4.@] @@ -292,45 +339,87 @@ * Creates a 128bit UUID by calling UuidCreate. * New API in Win 2000 */ - RPC_STATUS WINAPI UuidCreateSequential(UUID *Uuid) { return UuidCreate (Uuid); } - /************************************************************************* - * RpcStringFreeA [RPCRT4.@] - * - * Frees a character string allocated by the RPC run-time library. - * - * RETURNS - * - * S_OK if successful. + * UuidEqual [RPCRT4.@] */ -RPC_STATUS WINAPI RpcStringFreeA(unsigned char** String) +int WINAPI UuidEqual(UUID *uuid1, UUID *uuid2, RPC_STATUS *Status) { - HeapFree( GetProcessHeap(), 0, *String); - - return RPC_S_OK; + TRACE("(%s,%s)\n", debugstr_guid(uuid1), debugstr_guid(uuid2)); + *Status = RPC_S_OK; + if (!uuid1) uuid1 = &uuid_nil; + if (!uuid2) uuid2 = &uuid_nil; + if (uuid1 == uuid2) return TRUE; + return !memcmp(uuid1, uuid2, sizeof(UUID)); } +/************************************************************************* + * UuidIsNil [RPCRT4.@] + */ +int WINAPI UuidIsNil(UUID *uuid, RPC_STATUS *Status) +{ + TRACE("(%s)\n", debugstr_guid(uuid)); + *Status = RPC_S_OK; + if (!uuid) return TRUE; + return !memcmp(uuid, &uuid_nil, sizeof(UUID)); +} /************************************************************************* * UuidHash [RPCRT4.@] * * Generates a hash value for a given UUID - * + * Code based on FreeDCE implementation */ unsigned short WINAPI UuidHash(UUID *uuid, RPC_STATUS *Status) { - FIXME("stub:\n"); + BYTE *data = (BYTE*)uuid; + short c0 = 0, c1 = 0, x, y; + int i; + + TRACE("(%s)\n", debugstr_guid(uuid)); + + for (i=0; i<sizeof(UUID); i++) { + c0 += data[i]; + c1 += c0; + } + + x = -c1 % 255; + if (x < 0) x += 255; + + y = (c1 - c0) % 255; + if (y < 0) y += 255; + *Status = RPC_S_OK; - return 0xabcd; + return y*256 + x; } /************************************************************************* * UuidToStringA [RPCRT4.@] + */ +RPC_STATUS WINAPI UuidToStringA(UUID *Uuid, LPSTR* StringUuid) +{ + char buf[37]; + + sprintf(buf, "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + Uuid->Data1, Uuid->Data2, Uuid->Data3, + Uuid->Data4[0], Uuid->Data4[1], Uuid->Data4[2], + Uuid->Data4[3], Uuid->Data4[4], Uuid->Data4[5], + Uuid->Data4[6], Uuid->Data4[7] ); + + *StringUuid = RPCRT4_strdupAA(buf, -1); + + if(!(*StringUuid)) + return RPC_S_OUT_OF_MEMORY; + + return RPC_S_OK; +} + +/************************************************************************* + * UuidToStringW [RPCRT4.@] * * Converts a UUID to a string. * @@ -342,256 +431,151 @@ * S_OK if successful. * S_OUT_OF_MEMORY if unsucessful. */ -RPC_STATUS WINAPI UuidToStringA(UUID *Uuid, unsigned char** StringUuid) +RPC_STATUS WINAPI UuidToStringW(UUID *Uuid, LPWSTR* StringUuid) { - *StringUuid = HeapAlloc( GetProcessHeap(), 0, sizeof(char) * 37); + char buf[37]; + + sprintf(buf, "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + Uuid->Data1, Uuid->Data2, Uuid->Data3, + Uuid->Data4[0], Uuid->Data4[1], Uuid->Data4[2], + Uuid->Data4[3], Uuid->Data4[4], Uuid->Data4[5], + Uuid->Data4[6], Uuid->Data4[7] ); + + *StringUuid = RPCRT4_strdupWA(buf, -1); if(!(*StringUuid)) return RPC_S_OUT_OF_MEMORY; - sprintf(*StringUuid, "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", - Uuid->Data1, Uuid->Data2, Uuid->Data3, - Uuid->Data4[0], Uuid->Data4[1], Uuid->Data4[2], - Uuid->Data4[3], Uuid->Data4[4], Uuid->Data4[5], - Uuid->Data4[6], Uuid->Data4[7] ); - return RPC_S_OK; } -/*********************************************************************** - * UuidFromStringA (RPCRT4.@) - */ -RPC_STATUS WINAPI UuidFromStringA(unsigned char *str, UUID *uuid) -{ - FIXME("%s %p\n",debugstr_a(str),uuid); - return RPC_S_INVALID_STRING_UUID; -} - -/*********************************************************************** - * UuidFromStringW (RPCRT4.@) - */ -RPC_STATUS WINAPI UuidFromStringW(unsigned short *str, UUID *uuid) -{ - FIXME("%s %p\n",debugstr_w(str),uuid); - return RPC_S_INVALID_STRING_UUID; -} - -/*********************************************************************** - * NdrDllRegisterProxy (RPCRT4.@) - */ -HRESULT WINAPI NdrDllRegisterProxy( - HMODULE hDll, /* [in] */ - const ProxyFileInfo **pProxyFileList, /* [in] */ - const CLSID *pclsid /* [in] */ -) +static inline int hex_d(WCHAR v) { - FIXME("(%x,%p,%s), stub!\n",hDll,pProxyFileList,debugstr_guid(pclsid)); - return S_OK; + switch (v) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + return v - '0'; + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + return v - 'a' + 10; + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + return v - 'A' + 10; + default: + return -1; + } } -/*********************************************************************** - * RpcServerUseProtseqEpA (RPCRT4.@) - */ - -RPC_STATUS WINAPI RpcServerUseProtseqEpA( LPSTR Protseq, UINT MaxCalls, LPSTR Endpoint, LPVOID SecurityDescriptor ) +static inline unsigned char hex1A(LPSTR s) { - RPC_POLICY policy; - - TRACE( "(%s,%u,%s,%p)\n", Protseq, MaxCalls, Endpoint, SecurityDescriptor ); - - /* This should provide the default behaviour */ - policy.Length = sizeof( policy ); - policy.EndpointFlags = 0; - policy.NICFlags = 0; - - return RpcServerUseProtseqEpExA( Protseq, MaxCalls, Endpoint, SecurityDescriptor, &policy ); + unsigned char v1 = hex_d(s[0]), v2 = hex_d(s[1]); + return (v1 << 4) | v2; } -/*********************************************************************** - * RpcServerUseProtseqEpW (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcServerUseProtseqEpW( LPWSTR Protseq, UINT MaxCalls, LPWSTR Endpoint, LPVOID SecurityDescriptor ) +static inline unsigned char hex1W(LPWSTR s) { - RPC_POLICY policy; - - TRACE( "(%s,%u,%s,%p)\n", debugstr_w( Protseq ), MaxCalls, debugstr_w( Endpoint ), SecurityDescriptor ); - - /* This should provide the default behaviour */ - policy.Length = sizeof( policy ); - policy.EndpointFlags = 0; - policy.NICFlags = 0; - - return RpcServerUseProtseqEpExW( Protseq, MaxCalls, Endpoint, SecurityDescriptor, &policy ); + unsigned char v1 = hex_d(s[0]), v2 = hex_d(s[1]); + return (v1 << 4) | v2; } -/*********************************************************************** - * RpcServerUseProtseqEpExA (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcServerUseProtseqEpExA( LPSTR Protseq, UINT MaxCalls, LPSTR Endpoint, LPVOID SecurityDescriptor, - PRPC_POLICY lpPolicy ) +static inline unsigned short hex2A(LPSTR s) { - FIXME( "(%s,%u,%s,%p,{%u,%lu,%lu}): stub\n", Protseq, MaxCalls, Endpoint, SecurityDescriptor, - lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags ); - - return RPC_S_PROTSEQ_NOT_SUPPORTED; /* We don't support anything at this point */ + unsigned char v1 = hex1A(s+0), v2 = hex1A(s+2); + return (unsigned short)(v1 << 8) | v2; } -/*********************************************************************** - * RpcServerUseProtseqEpExW (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcServerUseProtseqEpExW( LPWSTR Protseq, UINT MaxCalls, LPWSTR Endpoint, LPVOID SecurityDescriptor, - PRPC_POLICY lpPolicy ) +static inline unsigned short hex2W(LPWSTR s) { - FIXME( "(%s,%u,%s,%p,{%u,%lu,%lu}): stub\n", debugstr_w( Protseq ), MaxCalls, debugstr_w( Endpoint ), - SecurityDescriptor, - lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags ); - - return RPC_S_PROTSEQ_NOT_SUPPORTED; /* We don't support anything at this point */ + unsigned char v1 = hex1W(s+0), v2 = hex1W(s+2); + return (unsigned short)(v1 << 8) | v2; } -/*********************************************************************** - * RpcServerRegisterIf (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcServerRegisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv ) +static inline unsigned long hex4A(LPSTR s) { - /* FIXME: Dump UUID using UuidToStringA */ - TRACE( "(%p,%p,%p)\n", IfSpec, MgrTypeUuid, MgrEpv ); - - return RpcServerRegisterIf2( IfSpec, MgrTypeUuid, MgrEpv, 0, RPC_C_LISTEN_MAX_CALLS_DEFAULT, (UINT)-1, NULL ); + unsigned short v1 = hex2A(s+0), v2 = hex2A(s+4); + return (unsigned long)(v1 << 16) | v2; } -/*********************************************************************** - * RpcServerRegisterIfEx (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcServerRegisterIfEx( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv, - UINT Flags, UINT MaxCalls, RPC_IF_CALLBACK_FN* IfCallbackFn ) +static inline unsigned long hex4W(LPWSTR s) { - /* FIXME: Dump UUID using UuidToStringA */ - TRACE( "(%p,%p,%p,%u,%u,%p)\n", IfSpec, MgrTypeUuid, MgrEpv, Flags, MaxCalls, IfCallbackFn ); - - return RpcServerRegisterIf2( IfSpec, MgrTypeUuid, MgrEpv, Flags, MaxCalls, (UINT)-1, IfCallbackFn ); + unsigned short v1 = hex2W(s+0), v2 = hex2W(s+4); + return (unsigned long)(v1 << 16) | v2; } -/*********************************************************************** - * RpcServerRegisterIf2 (RPCRT4.@) +/************************************************************************* + * UuidFromStringA [RPCRT4.@] + * + * Converts a string to a UUID. */ -RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv, - UINT Flags, UINT MaxCalls, UINT MaxRpcSize, RPC_IF_CALLBACK_FN* IfCallbackFn ) +RPC_STATUS WINAPI UuidFromStringA(LPSTR StringUuid, UUID *Uuid) { - /* FIXME: Dump UUID using UuidToStringA */ - FIXME( "(%p,%p,%p,%u,%u,%u,%p): stub\n", IfSpec, MgrTypeUuid, MgrEpv, Flags, MaxCalls, MaxRpcSize, IfCallbackFn ); - - return RPC_S_UNKNOWN_IF; /* I guess this return code is as good as any failure */ -} + unsigned i; + if(!StringUuid) + return UuidCreateNil(Uuid); -/*********************************************************************** - * RpcServerRegisterAuthInfoA (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcServerRegisterAuthInfoA( LPSTR ServerPrincName, ULONG AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn, - LPVOID Arg ) -{ - FIXME( "(%s,%lu,%p,%p): stub\n", ServerPrincName, AuthnSvc, GetKeyFn, Arg ); + if (strlen(StringUuid) != 36) + return RPC_S_INVALID_STRING_UUID; - return RPC_S_UNKNOWN_AUTHN_SERVICE; /* We don't know any authentication services */ -} + if (StringUuid[8]!='-' || StringUuid[13]!='-' || StringUuid[18]!='-' || StringUuid[23]!='-') + return RPC_S_INVALID_STRING_UUID; -/*********************************************************************** - * RpcServerRegisterAuthInfoW (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcServerRegisterAuthInfoW( LPWSTR ServerPrincName, ULONG AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn, - LPVOID Arg ) -{ - FIXME( "(%s,%lu,%p,%p): stub\n", debugstr_w( ServerPrincName ), AuthnSvc, GetKeyFn, Arg ); + for (i=0; i<36; i++) { + if (i==8 || i == 13 || i == 18 || i == 23) continue; + if (hex_d(StringUuid[i]) == -1) + return RPC_S_INVALID_STRING_UUID; + } - return RPC_S_UNKNOWN_AUTHN_SERVICE; /* We don't know any authentication services */ + Uuid->Data1 = hex4A(StringUuid); + Uuid->Data2 = hex2A(StringUuid+9); + Uuid->Data3 = hex2A(StringUuid+14); + Uuid->Data4[0] = hex1A(StringUuid+19); + Uuid->Data4[1] = hex1A(StringUuid+21); + Uuid->Data4[2] = hex1A(StringUuid+24); + Uuid->Data4[3] = hex1A(StringUuid+26); + Uuid->Data4[4] = hex1A(StringUuid+28); + Uuid->Data4[5] = hex1A(StringUuid+30); + Uuid->Data4[6] = hex1A(StringUuid+32); + Uuid->Data4[7] = hex1A(StringUuid+34); + return RPC_S_OK; } -/*********************************************************************** - * RpcServerListen (RPCRT4.@) +/************************************************************************* + * UuidFromStringW [RPCRT4.@] + * + * Converts a string to a UUID. */ -RPC_STATUS WINAPI RpcServerListen( UINT MinimumCallThreads, UINT MaxCalls, UINT DontWait ) +RPC_STATUS WINAPI UuidFromStringW(LPWSTR StringUuid, UUID *Uuid) { - FIXME( "(%u,%u,%u): stub\n", MinimumCallThreads, MaxCalls, DontWait ); + unsigned i; - return RPC_S_NO_PROTSEQS_REGISTERED; /* Since we don't allow registration this seems reasonable */ -} + if(!StringUuid) + return UuidCreateNil(Uuid); -/*********************************************************************** - * RpcStringBindingComposeA (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcStringBindingComposeA( LPSTR ObjUuid, LPSTR Protseq, LPSTR NetworkAddr, LPSTR Endpoint, - LPSTR Options, LPSTR* StringBinding ) -{ - FIXME( "(%s,%s,%s,%s,%s,%p): stub\n", ObjUuid, Protseq, NetworkAddr, Endpoint, Options, StringBinding ); - *StringBinding = NULL; + if (strlenW(StringUuid) != 36) + return RPC_S_INVALID_STRING_UUID; - return RPC_S_INVALID_STRING_UUID; /* Failure */ -} + if (StringUuid[8]!='-' || StringUuid[13]!='-' || StringUuid[18]!='-' || StringUuid[23]!='-') + return RPC_S_INVALID_STRING_UUID; -/*********************************************************************** - * RpcStringBindingComposeW (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcStringBindingComposeW( LPWSTR ObjUuid, LPWSTR Protseq, LPWSTR NetworkAddr, LPWSTR Endpoint, - LPWSTR Options, LPWSTR* StringBinding ) -{ - FIXME( "(%s,%s,%s,%s,%s,%p): stub\n", debugstr_w( ObjUuid ), debugstr_w( Protseq ), debugstr_w( NetworkAddr ), - debugstr_w( Endpoint ), debugstr_w( Options ), StringBinding ); - *StringBinding = NULL; + for (i=0; i<36; i++) { + if (i==8 || i == 13 || i == 18 || i == 23) continue; + if (hex_d(StringUuid[i]) == -1) + return RPC_S_INVALID_STRING_UUID; + } - return RPC_S_INVALID_STRING_UUID; /* Failure */ -} + Uuid->Data1 = hex4W(StringUuid); + Uuid->Data2 = hex2W(StringUuid+9); + Uuid->Data3 = hex2W(StringUuid+14); + Uuid->Data4[0] = hex1W(StringUuid+19); + Uuid->Data4[1] = hex1W(StringUuid+21); + Uuid->Data4[2] = hex1W(StringUuid+24); + Uuid->Data4[3] = hex1W(StringUuid+26); + Uuid->Data4[4] = hex1W(StringUuid+28); + Uuid->Data4[5] = hex1W(StringUuid+30); + Uuid->Data4[6] = hex1W(StringUuid+32); + Uuid->Data4[7] = hex1W(StringUuid+34); -/*********************************************************************** - * RpcBindingFree (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcBindingFree(RPC_BINDING_HANDLE* Binding) -{ - FIXME("(%p): stub\n", Binding); return RPC_S_OK; } -/*********************************************************************** - * RpcBindingFromStringBindingA (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcBindingFromStringBindingA( LPSTR StringBinding, RPC_BINDING_HANDLE* Binding ) -{ - FIXME( "(%s,%p): stub\n", StringBinding, Binding ); - - return RPC_S_INVALID_STRING_BINDING; /* As good as any failure code */ -} - -/*********************************************************************** - * RpcBindingFromStringBindingW (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcBindingFromStringBindingW( LPWSTR StringBinding, RPC_BINDING_HANDLE* Binding ) -{ - FIXME( "(%s,%p): stub\n", debugstr_w( StringBinding ), Binding ); - - return RPC_S_INVALID_STRING_BINDING; /* As good as any failure code */ -} - -/*********************************************************************** - * NdrDllCanUnloadNow (RPCRT4.@) - */ -HRESULT WINAPI NdrDllCanUnloadNow(CStdPSFactoryBuffer *pPSFactoryBuffer) -{ - FIXME("%p\n",pPSFactoryBuffer); - return FALSE; -} - -/*********************************************************************** - * NdrDllGetClassObject (RPCRT4.@) - */ -HRESULT WINAPI NdrDllGetClassObject( - REFCLSID rclsid, REFIID riid , LPVOID *ppv, - const ProxyFileInfo ** pProxyFileList, - const CLSID * pclsid, - CStdPSFactoryBuffer * pPSFactoryBuffer) -{ - if(ppv) - *ppv = NULL; - return RPC_S_UNKNOWN_IF; -} /*********************************************************************** * DllRegisterServer (RPCRT4.@) @@ -602,3 +586,4 @@ FIXME( "(): stub\n" ); return S_OK; } + Index: wine/include/rpc.h =================================================================== RCS file: /home/wine/wine/include/rpc.h,v retrieving revision 1.8 diff -d -u -r1.8 rpc.h --- wine/include/rpc.h 10 Mar 2002 00:02:34 -0000 1.8 +++ wine/include/rpc.h 16 Jun 2002 10:53:43 -0000 @@ -25,6 +25,8 @@ #ifndef __WINE_RPC_H #define __WINE_RPC_H +#define __RPC_WIN32__ + #define __RPC_FAR #define __RPC_API WINAPI #define __RPC_USER WINAPI Index: wine/include/rpcdce.h =================================================================== RCS file: /home/wine/wine/include/rpcdce.h,v retrieving revision 1.8 diff -d -u -r1.8 rpcdce.h --- wine/include/rpcdce.h 31 May 2002 23:06:48 -0000 1.8 +++ wine/include/rpcdce.h 16 Jun 2002 10:53:43 -0000 @@ -29,8 +29,6 @@ typedef void* RPC_AUTHZ_HANDLE; typedef void* RPC_IF_HANDLE; typedef I_RPC_HANDLE RPC_BINDING_HANDLE; -typedef RPC_BINDING_HANDLE handle_t; -#define rpc_binding_handle_t RPC_BINDING_HANDLE #define RPC_MGR_EPV void typedef struct _RPC_BINDING_VECTOR @@ -38,14 +36,19 @@ unsigned long Count; RPC_BINDING_HANDLE BindingH[1]; } RPC_BINDING_VECTOR; -#define rpc_binding_vector_t RPC_BINDING_VECTOR typedef struct _UUID_VECTOR { unsigned long Count; UUID *Uuid[1]; } UUID_VECTOR; + +#ifndef __WINE__ +typedef RPC_BINDING_HANDLE handle_t; +#define rpc_binding_handle_t RPC_BINDING_HANDLE +#define rpc_binding_vector_t RPC_BINDING_VECTOR #define uuid_vector_t UUID_VECTOR +#endif typedef struct _RPC_IF_ID { @@ -90,6 +93,11 @@ ULONG NICFlags; } RPC_POLICY, *PRPC_POLICY; +/* RpcServerRegisterIfEx Flags */ +#define RPC_IF_AUTOLISTEN 0x1 +#define RPC_IF_OLE 0x2 +#define RPC_IF_ALLOW_UNKNOWN_AUTHORITY 0x4 +#define RPC_IF_ALLOW_SECURE_ONLY 0x8 RPCRTAPI RPC_STATUS RPC_ENTRY RpcBindingCopy( RPC_BINDING_HANDLE SourceBinding, RPC_BINDING_HANDLE* DestinationBinding ); @@ -98,6 +106,13 @@ RpcBindingFree( RPC_BINDING_HANDLE* Binding ); RPCRTAPI RPC_STATUS RPC_ENTRY + RpcBindingInqObject( RPC_BINDING_HANDLE Binding, UUID* ObjectUuid ); +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcBindingReset( RPC_BINDING_HANDLE Binding ); +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcBindingSetObject( RPC_BINDING_HANDLE Binding, UUID* ObjectUuid ); + +RPCRTAPI RPC_STATUS RPC_ENTRY RpcBindingFromStringBindingA( LPSTR StringBinding, RPC_BINDING_HANDLE* Binding ); RPCRTAPI RPC_STATUS RPC_ENTRY RpcBindingFromStringBindingW( LPWSTR StringBinding, RPC_BINDING_HANDLE* Binding ); @@ -113,6 +128,45 @@ RpcBindingVectorFree( RPC_BINDING_VECTOR** BindingVector ); RPCRTAPI RPC_STATUS RPC_ENTRY + RpcStringBindingComposeA( LPSTR ObjUuid, LPSTR Protseq, LPSTR NetworkAddr, + LPSTR Endpoint, LPSTR Options, LPSTR* StringBinding ); +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcStringBindingComposeW( LPWSTR ObjUuid, LPWSTR Protseq, LPWSTR NetworkAddr, + LPWSTR Endpoint, LPWSTR Options, LPWSTR* StringBinding ); +#define RpcStringBindingCompose WINELIB_NAME_AW(RpcStringBindingCompose) + +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcStringBindingParseA( LPSTR StringBinding, LPSTR* ObjUuid, LPSTR* Protseq, + LPSTR* NetworkAddr, LPSTR* Endpoint, LPSTR* NetworkOptions ); +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcStringBindingParseW( LPWSTR StringBinding, LPWSTR* ObjUuid, LPWSTR* Protseq, + LPWSTR* NetworkAddr, LPWSTR* Endpoint, LPWSTR* NetworkOptions ); +#define RpcStringBindingParse WINELIB_NAME_AW(RpcStringBindingParse) + +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcEpResolveBinding( RPC_BINDING_HANDLE Binding, RPC_IF_HANDLE IfSpec ); + +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR* BindingVector, + UUID_VECTOR* UuidVector, LPSTR Annotation ); +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcEpRegisterW( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR* BindingVector, + UUID_VECTOR* UuidVector, LPWSTR Annotation ); +#define RpcEpRegister WINELIB_NAME_AW(RpcEpRegister) + +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcEpRegisterNoReplaceA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR* BindingVector, + UUID_VECTOR* UuidVector, LPSTR Annotation ); +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcEpRegisterNoReplaceW( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR* BindingVector, + UUID_VECTOR* UuidVector, LPWSTR Annotation ); +#define RpcEpRegisterNoReplace WINELIB_NAME_AW(RpcEpRegisterNoReplace) + +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR* BindingVector, + UUID_VECTOR* UuidVector ); + +RPCRTAPI RPC_STATUS RPC_ENTRY RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector ); RPCRTAPI RPC_STATUS RPC_ENTRY @@ -163,22 +217,37 @@ #define RpcStringBindingCompose WINELIB_NAME_AW(RpcStringBindingCompose) RPCRTAPI RPC_STATUS RPC_ENTRY - RpcStringFreeA(unsigned char** String); + RpcStringFreeA(LPSTR* String); RPCRTAPI RPC_STATUS RPC_ENTRY - RpcStringFreeW(unsigned short** String); + RpcStringFreeW(LPWSTR* String); #define RpcStringFree WINELIB_NAME_AW(RpcStringFree) RPCRTAPI RPC_STATUS RPC_ENTRY - UuidCreate( UUID* Uuid ); + UuidToStringA( UUID* Uuid, LPSTR* StringUuid ); +RPCRTAPI RPC_STATUS RPC_ENTRY + UuidToStringW( UUID* Uuid, LPWSTR* StringUuid ); +#define UuidToString WINELIB_NAME_AW(UuidToString) RPCRTAPI RPC_STATUS RPC_ENTRY - UuidToStringA( UUID* Uuid, unsigned char** StringUuid ); + UuidFromStringA( LPSTR StringUuid, UUID* Uuid ); RPCRTAPI RPC_STATUS RPC_ENTRY - UuidToStringW( UUID* Uuid, unsigned short** StringUuid ); -#define UuidToString WINELIB_NAME_AW(UuidToString) + UuidFromStringW( LPWSTR StringUuid, UUID* Uuid ); +#define UuidFromString WINELIB_NAME_AW(UuidFromString) +RPCRTAPI RPC_STATUS RPC_ENTRY + UuidCreate( UUID* Uuid ); +RPCRTAPI RPC_STATUS RPC_ENTRY + UuidCreateSequential( UUID* Uuid ); +RPCRTAPI RPC_STATUS RPC_ENTRY + UuidCreateNil( UUID* Uuid ); +RPCRTAPI signed int RPC_ENTRY + UuidCompare( UUID* Uuid1, UUID* Uuid2, RPC_STATUS* Status_ ); +RPCRTAPI int RPC_ENTRY + UuidEqual( UUID* Uuid1, UUID* Uuid2, RPC_STATUS* Status_ ); RPCRTAPI unsigned short RPC_ENTRY UuidHash(UUID* Uuid, RPC_STATUS* Status_ ); +RPCRTAPI int RPC_ENTRY + UuidIsNil( UUID* Uuid, RPC_STATUS* Status_ ); #include "rpcdcep.h" Index: wine/include/rpcdcep.h =================================================================== RCS file: /home/wine/wine/include/rpcdcep.h,v retrieving revision 1.2 diff -d -u -r1.2 rpcdcep.h --- wine/include/rpcdcep.h 10 Mar 2002 00:02:34 -0000 1.2 +++ wine/include/rpcdcep.h 16 Jun 2002 10:53:43 -0000 @@ -19,7 +19,6 @@ #ifndef __WINE_RPCDCEP_H #define __WINE_RPCDCEP_H - typedef struct _RPC_VERSION { unsigned short MajorVersion; unsigned short MinorVersion; @@ -45,4 +44,117 @@ unsigned long RpcFlags; } RPC_MESSAGE, *PRPC_MESSAGE; -#endif /*__WINE_RPCDCE_H */ +typedef void __RPC_STUB (*RPC_DISPATCH_FUNCTION)(PRPC_MESSAGE Message); + +typedef struct +{ + unsigned int DispatchTableCount; + RPC_DISPATCH_FUNCTION* DispatchTable; + LONG_PTR Reserved; +} RPC_DISPATCH_TABLE, *PRPC_DISPATCH_TABLE; + +typedef struct _RPC_PROTSEQ_ENDPOINT +{ + unsigned char* RpcProtocolSequence; + unsigned char* Endpoint; +} RPC_PROTSEQ_ENDPOINT, *PRPC_PROTSEQ_ENDPOINT; + +#define NT351_INTERFACE_SIZE 0x40 +#define RPC_INTERFACE_HAS_PIPES 0x0001 + +typedef struct _RPC_SERVER_INTERFACE +{ + unsigned int Length; + RPC_SYNTAX_IDENTIFIER InterfaceId; + RPC_SYNTAX_IDENTIFIER TransferSyntax; + PRPC_DISPATCH_TABLE DispatchTable; + unsigned int RpcProtseqEndpointCount; + PRPC_PROTSEQ_ENDPOINT RpcProtseqEndpoint; + RPC_MGR_EPV* DefaultManagerEpv; + void const* InterpreterInfo; + unsigned int Flags; +} RPC_SERVER_INTERFACE, *PRPC_SERVER_INTERFACE; + +typedef struct _RPC_CLIENT_INTERFACE +{ + unsigned int Length; + RPC_SYNTAX_IDENTIFIER InterfaceId; + RPC_SYNTAX_IDENTIFIER TransferSyntax; + PRPC_DISPATCH_TABLE DispatchTable; + unsigned int RpcProtseqEndpointCount; + PRPC_PROTSEQ_ENDPOINT RpcProtseqEndpoint; + ULONG_PTR Reserved; + void const* InterpreterInfo; + unsigned int Flags; +} RPC_CLIENT_INTERFACE, *PRPC_CLIENT_INTERFACE; + +#define TRANSPORT_TYPE_CN 0x01 +#define TRANSPORT_TYPE_DG 0x02 +#define TRANSPORT_TYPE_LPC 0x04 +#define TRANSPORT_TYPE_WMSG 0x08 + +#ifdef WINNT +typedef RPC_STATUS (*RPC_BLOCKING_FN)(void* hWnd, void* Context, HANDLE hSyncEvent); +#else +typedef RPC_STATUS (*RPC_BLOCKING_FN)(void* hWnd, void* Context, void* hSyncEvent); +#endif + +RPCRTAPI RPC_STATUS RPC_ENTRY + I_RpcGetBuffer( RPC_MESSAGE* Message ); +RPCRTAPI RPC_STATUS RPC_ENTRY + I_RpcGetBufferWithObject( RPC_MESSAGE* Message, UUID* ObjectUuid ); +RPCRTAPI RPC_STATUS RPC_ENTRY + I_RpcSendReceive( RPC_MESSAGE* Message ); +RPCRTAPI RPC_STATUS RPC_ENTRY + I_RpcFreeBuffer( RPC_MESSAGE* Message ); +RPCRTAPI RPC_STATUS RPC_ENTRY + I_RpcSend( RPC_MESSAGE* Message ); +RPCRTAPI RPC_STATUS RPC_ENTRY + I_RpcReceive( RPC_MESSAGE* Message ); + +RPCRTAPI void* RPC_ENTRY + I_RpcAllocate( unsigned int Size ); +RPCRTAPI void RPC_ENTRY + I_RpcFree( void* Object ); + +RPCRTAPI RPC_BINDING_HANDLE RPC_ENTRY + I_RpcGetCurrentCallHandle( void ); + +RPCRTAPI RPC_STATUS RPC_ENTRY + I_RpcServerStartListening( void* hWnd ); +RPCRTAPI RPC_STATUS RPC_ENTRY + I_RpcServerStopListening( void ); +/* WINNT */ +RPCRTAPI RPC_STATUS RPC_ENTRY + I_GetThreadWindowHandle( HWND* hWnd ); +RPCRTAPI RPC_STATUS RPC_ENTRY + I_RpcAsyncSendReceive( RPC_MESSAGE* Message, void* Context, HWND hWnd ); + +#ifdef WINNT +RPCRTAPI RPC_STATUS RPC_ENTRY + I_RpcBindingSetAsync( RPC_BINDING_HANDLE Binding, RPC_BLOCKING_FN BlockingFn ); +#else +RPCRTAPI RPC_STATUS RPC_ENTRY + I_RpcBindingSetAsync( RPC_BINDING_HANDLE Binding, RPC_BLOCKING_FN BlockingFn, unsigned long ServerTid ); +#endif + +/* WIN9x */ +RPCRTAPI RPC_STATUS RPC_ENTRY + I_RpcSetThreadParams( int fClientFree, void* Context, void* hWndClient ); + +#ifdef WINNT +RPCRTAPI LONG RPC_ENTRY + I_RpcWindowProc( HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam ); +#else +RPCRTAPI unsigned int RPC_ENTRY + I_RpcWindowProc( void* hWnd, unsigned int Message, unsigned int wParam, unsigned long lParam ); +#endif + +/* WINNT */ +RPCRTAPI RPC_STATUS RPC_ENTRY + I_RpcSetWMsgEndpoint( WCHAR* Endpoint ); + +RPCRTAPI RPC_STATUS RPC_ENTRY + I_RpcBindingInqTransportType( RPC_BINDING_HANDLE Binding, unsigned int* Type ); + +#endif /*__WINE_RPCDCEP_H */ Index: wine/include/rpcndr.h =================================================================== RCS file: /home/wine/wine/include/rpcndr.h,v retrieving revision 1.5 diff -d -u -r1.5 rpcndr.h --- wine/include/rpcndr.h 10 Mar 2002 00:02:34 -0000 1.5 +++ wine/include/rpcndr.h 16 Jun 2002 10:53:44 -0000 @@ -22,7 +22,10 @@ #ifndef __RPCNDR_H_VERSION__ /* FIXME: I'm not sure what version though */ #define __RPCNDR_H_VERSION__ -#endif // __RPCNDR_H_VERSION__ +#endif + +#define TARGET_IS_NT40_OR_LATER 1 +#define TARGET_IS_NT351_OR_WIN95_OR_LATER 1 typedef unsigned char byte; typedef __int64 hyper; @@ -31,6 +34,9 @@ typedef unsigned char _wine_boolean; /* typedef _wine_boolean boolean; */ +#define __RPC_CALLEE WINAPI +#define RPC_VAR_ENTRY WINAPIV + typedef struct { void *pad[2]; @@ -96,7 +102,7 @@ unsigned char *StackTop; unsigned char *pPresentedType; unsigned char *pTransmitType; - handle_t SavedHandle; + RPC_BINDING_HANDLE SavedHandle; const struct _MIDL_STUB_DESC *StubDesc; struct _FULL_PTR_XLAT_TABLES *FullPtrXlatTables; unsigned long FullPtrRefId; @@ -146,8 +152,8 @@ void * (__RPC_API *pfnAllocate)(size_t); void (__RPC_API *pfnFree)(void *); union { - handle_t *pAutoHandle; - handle_t *pPrimitiveHandle; + RPC_BINDING_HANDLE *pAutoHandle; + RPC_BINDING_HANDLE *pPrimitiveHandle; PGENERIC_BINDING_INFO pGenericBindingInfo; } IMPLICIT_HANDLE_INFO; const NDR_RUNDOWN *apfnNdrRundownRoutines; @@ -195,6 +201,22 @@ const unsigned short *LocalFmtStringOffset; } MIDL_SERVER_INFO, *PMIDL_SERVER_INFO; +typedef struct _MIDL_STUBLESS_PROXY_INFO +{ + PMIDL_STUB_DESC pStubDesc; + PFORMAT_STRING ProcFormatString; + const unsigned short *FormatStringOffset; + PFORMAT_STRING LocalFormatTypes; + PFORMAT_STRING LocalProcStrings; + const unsigned short *LocalFmtStringOffset; +} MIDL_STUBLESS_PROXY_INFO, *PMIDL_STUBLESS_PROXY_INFO; + +typedef union _CLIENT_CALL_RETURN +{ + void *Pointer; + LONG_PTR Simple; +} CLIENT_CALL_RETURN; + typedef enum { STUB_UNMARSHAL, STUB_CALL_SERVER, @@ -253,6 +275,21 @@ NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, long NumberParams ); RPCRTAPI void RPC_ENTRY NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat ); + +CLIENT_CALL_RETURN RPC_VAR_ENTRY + NdrClientCall2( PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRING pFormat, ... ); +CLIENT_CALL_RETURN RPC_VAR_ENTRY + NdrClientCall( PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRING pFormat, ... ); + +RPCRTAPI void RPC_ENTRY + NdrServerCall2( PRPC_MESSAGE pRpcMsg ); +RPCRTAPI void RPC_ENTRY + NdrServerCall( PRPC_MESSAGE pRpcMsg ); + +RPCRTAPI long RPC_ENTRY + NdrStubCall2( struct IRpcStubBuffer* pThis, struct IRpcChannelBuffer* pChannel, PRPC_MESSAGE pRpcMsg, LPDWORD pdwStubPhase ); +RPCRTAPI long RPC_ENTRY + NdrStubCall( struct IRpcStubBuffer* pThis, struct IRpcChannelBuffer* pChannel, PRPC_MESSAGE pRpcMsg, LPDWORD pdwStubPhase ); RPCRTAPI void* RPC_ENTRY NdrOleAllocate( size_t Size ); Index: wine/include/rpcproxy.h =================================================================== RCS file: /home/wine/wine/include/rpcproxy.h,v retrieving revision 1.2 diff -d -u -r1.2 rpcproxy.h --- wine/include/rpcproxy.h 10 Mar 2002 00:02:34 -0000 1.2 +++ wine/include/rpcproxy.h 16 Jun 2002 10:53:44 -0000 @@ -19,8 +19,14 @@ #ifndef __WINE_RPCPROXY_H #define __WINE_RPCPROXY_H +#ifndef __RPCPROXY_H_VERSION__ +/* FIXME: I'm not sure what version though */ +#define __RPCPROXY_H_VERSION__ +#endif + #include "basetsd.h" #include "guiddef.h" +#include "winnt.h" typedef struct tagCInterfaceStubVtbl *PCInterfaceStubVtblList; typedef struct tagCInterfaceProxyVtbl *PCInterfaceProxyVtblList; @@ -47,6 +53,8 @@ #include "rpc.h" #include "rpcndr.h" +#include "wine/obj_base.h" +#include "wine/obj_channel.h" typedef struct tagCInterfaceProxyHeader { @@ -147,6 +155,32 @@ CStdStubBuffer_DebugServerQueryInterface, \ CStdStubBuffer_DebugServerRelease +RPCRTAPI void RPC_ENTRY + NdrProxyInitialize( void *This, PRPC_MESSAGE pRpcMsg, PMIDL_STUB_MESSAGE pStubMsg, + PMIDL_STUB_DESC pStubDescriptor, unsigned int ProcNum ); +RPCRTAPI void RPC_ENTRY + NdrProxyGetBuffer( void *This, PMIDL_STUB_MESSAGE pStubMsg ); +RPCRTAPI void RPC_ENTRY + NdrProxySendReceive( void *This, PMIDL_STUB_MESSAGE pStubMsg ); +RPCRTAPI void RPC_ENTRY + NdrProxyFreeBuffer( void *This, PMIDL_STUB_MESSAGE pStubMsg ); +RPCRTAPI HRESULT RPC_ENTRY + NdrProxyErrorHandler( DWORD dwExceptionCode ); + +RPCRTAPI void RPC_ENTRY + NdrStubInitialize( PRPC_MESSAGE pRpcMsg, PMIDL_STUB_MESSAGE pStubMsg, + PMIDL_STUB_DESC pStubDescriptor, IRpcChannelBuffer *pRpcChannelBuffer ); +RPCRTAPI void RPC_ENTRY + NdrStubInitializePartial( PRPC_MESSAGE pRpcMsg, PMIDL_STUB_MESSAGE pStubMsg, + PMIDL_STUB_DESC pStubDescriptor, IRpcChannelBuffer *pRpcChannelBuffer, + unsigned long RequestedBufferSize ); +void __RPC_STUB NdrStubForwardingFunction( IRpcStubBuffer *This, IRpcChannelBuffer *pChannel, + PRPC_MESSAGE pMsg, DWORD *pdwStubPhase ); +RPCRTAPI void RPC_ENTRY + NdrStubGetBuffer( IRpcStubBuffer *This, IRpcChannelBuffer *pRpcChannelBuffer, PMIDL_STUB_MESSAGE pStubMsg ); +RPCRTAPI HRESULT RPC_ENTRY + NdrStubErrorHandler( DWORD dwExceptionCode ); + RPCRTAPI HRESULT RPC_ENTRY NdrDllGetClassObject( REFCLSID rclsid, REFIID riid, void **ppv, const ProxyFileInfo **pProxyFileList, const CLSID *pclsid, CStdPSFactoryBuffer *pPSFactoryBuffer ); @@ -161,6 +195,8 @@ #define CSTDSTUBBUFFERRELEASE(pFactory) \ ULONG WINAPI CStdStubBuffer_Release(IRpcStubBuffer *This) \ { return NdrCStdStubBuffer_Release(This, (IPSFactoryBuffer *)pFactory); } + +#define IID_GENERIC_CHECK_IID(name,pIID,index) memcmp(pIID, name##_ProxyVtblList[index]->header.piid, sizeof(IID)) #if defined(__WINE__) && defined(__WINE_WINE_OBJ_OLEAUT_H) /* see http://msdn.microsoft.com/library/en-us/dnmsj99/html/com0199.asp?frame=true */ --- /dev/null Mon Mar 4 08:42:02 2002 +++ wine/dlls/rpcrt4/cproxy.c Thu Jun 13 17:15:25 2002 @@ -0,0 +1,276 @@ +/* + * COM proxy implementation + * + * Copyright 2001 Ove K�en, TransGaming Technologies + */ + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" + +#include "wine/obj_base.h" +#include "wine/obj_channel.h" + +#include "rpcproxy.h" + +#include "cpsf.h" +#include "ndr_misc.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +struct StublessThunk; + +/* I don't know what MS's std proxy structure looks like, + so this probably doesn't match, but that shouldn't matter */ +typedef struct { + ICOM_VTABLE(IRpcProxyBuffer) *lpVtbl; + LPVOID *PVtbl; + DWORD RefCount; + const MIDL_STUBLESS_PROXY_INFO *stubless; + const IID* piid; + LPUNKNOWN pUnkOuter; + LPPSFACTORYBUFFER pPSFactory; + LPRPCCHANNELBUFFER pChannel; + struct StublessThunk *thunks; +} StdProxyImpl; + +static ICOM_VTABLE(IRpcProxyBuffer) StdProxy_Vtbl; + +/* How the Windows stubless proxy thunks work is explained at + * http://msdn.microsoft.com/library/en-us/dnmsj99/html/com0199.asp, + * but I'll use a slightly different method, to make life easier */ + +#if defined(__i386__) + +struct StublessThunk { + BYTE push WINE_PACKED; + DWORD index WINE_PACKED; + BYTE call WINE_PACKED; + LONG handler WINE_PACKED; + BYTE ret WINE_PACKED; + WORD bytes WINE_PACKED; + BYTE pad[3]; +}; + +/* adjust the stack size since we don't use Windows's method */ +#define STACK_ADJUST sizeof(DWORD) + +#define FILL_STUBLESS(x,idx,stk) \ + x->push = 0x68; /* pushl [immediate] */ \ + x->index = (idx); \ + x->call = 0xe8; /* call [near] */ \ + x->handler = (char*)ObjectStubless - (char*)&x->ret; \ + x->ret = 0xc2; /* ret [immediate] */ \ + x->bytes = stk; \ + x->pad[0] = 0x8d; /* leal (%esi),%esi */ \ + x->pad[1] = 0x76; \ + x->pad[2] = 0x00; + +#else +/* can't do that on this arch */ +struct ObjectStubless {}; +#define FILL_STUBLESS(x,idx) \ + ERR("stubless proxies are not supported on this architecture\n"); +#endif + +static HRESULT WINAPI ObjectStubless(DWORD index) +{ + char *args = (char*)(&index + 2); + LPVOID iface = *(LPVOID*)args; + ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface); + PFORMAT_STRING fs = This->stubless->ProcFormatString + This->stubless->FormatStringOffset[index]; + unsigned bytes = *(WORD*)(fs+8) - STACK_ADJUST; + TRACE("(%p)->(%ld)([%d bytes]) ret=%08lx\n", iface, index, bytes, *(DWORD*)(args+bytes)); + return RPCRT4_NdrClientCall2(This->stubless->pStubDesc, fs, args); +} + +HRESULT WINAPI StdProxy_Construct(REFIID riid, + LPUNKNOWN pUnkOuter, + CInterfaceProxyVtbl *vtbl, + CInterfaceStubVtbl *svtbl, + LPPSFACTORYBUFFER pPSFactory, + LPRPCPROXYBUFFER *ppProxy, + LPVOID *ppvObj) +{ + StdProxyImpl *This; + const MIDL_STUBLESS_PROXY_INFO *stubless = NULL; + TRACE("(%p,%p,%p,%p,%p)\n", pUnkOuter, vtbl, pPSFactory, ppProxy, ppvObj); + /* I can't find any other way to detect stubless proxies than this hack */ + if (!IsEqualGUID(vtbl->header.piid, riid)) { + stubless = *((const void **)vtbl)++; + TRACE("stubless=%p\n", stubless); + } + TRACE("iid=%s\n", debugstr_guid(vtbl->header.piid)); + TRACE("vtbl=%p\n", vtbl->Vtbl); + if (!IsEqualGUID(vtbl->header.piid, riid)) { + ERR("IID mismatch during proxy creation\n"); + return RPC_E_UNEXPECTED; + } + This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(StdProxyImpl)); + if (!This) return E_OUTOFMEMORY; + if (stubless) { + unsigned i, count = svtbl->header.DispatchTableCount; + /* Maybe the original vtbl is just modified directly to point at + * ObjectStublessClientXXX thunks in real Windows, but I don't like it + */ + TRACE("stubless thunks: count=%d\n", count); + This->thunks = HeapAlloc(GetProcessHeap(),0,sizeof(struct StublessThunk)*count); + This->PVtbl = HeapAlloc(GetProcessHeap(),0,sizeof(LPVOID)*count); + for (i=0; i<count; i++) { + struct StublessThunk *thunk = &This->thunks[i]; + if (vtbl->Vtbl[i] == (LPVOID)-1) { + PFORMAT_STRING fs = stubless->ProcFormatString + stubless->FormatStringOffset[i]; + unsigned bytes = *(WORD*)(fs+8) - STACK_ADJUST; + TRACE("method %d: stacksize=%d\n", i, bytes); + FILL_STUBLESS(thunk, i, bytes) + This->PVtbl[i] = thunk; + } + else { + memset(thunk, 0, sizeof(struct StublessThunk)); + This->PVtbl[i] = vtbl->Vtbl[i]; + } + } + } + else This->PVtbl = vtbl->Vtbl; + This->lpVtbl = &StdProxy_Vtbl; + This->RefCount = 1; + This->stubless = stubless; + This->piid = vtbl->header.piid; + This->pUnkOuter = pUnkOuter; + This->pPSFactory = pPSFactory; + This->pChannel = NULL; + *ppProxy = (LPRPCPROXYBUFFER)&This->lpVtbl; + *ppvObj = &This->PVtbl; + IPSFactoryBuffer_AddRef(pPSFactory); + return S_OK; +} + +static void WINAPI StdProxy_Destruct(LPRPCPROXYBUFFER iface) +{ + ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface); + IPSFactoryBuffer_Release(This->pPSFactory); + if (This->thunks) { + HeapFree(GetProcessHeap(),0,This->PVtbl); + HeapFree(GetProcessHeap(),0,This->thunks); + } + HeapFree(GetProcessHeap(),0,This); +} + +static HRESULT WINAPI StdProxy_QueryInterface(LPRPCPROXYBUFFER iface, + REFIID riid, + LPVOID *obj) +{ + ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface); + TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(riid),obj); + if (IsEqualGUID(&IID_IUnknown,riid) || + IsEqualGUID(This->piid,riid)) { + *obj = &This->PVtbl; + This->RefCount++; + return S_OK; + } + if (IsEqualGUID(&IID_IRpcProxyBuffer,riid)) { + *obj = &This->lpVtbl; + This->RefCount++; + return S_OK; + } + return E_NOINTERFACE; +} + +static ULONG WINAPI StdProxy_AddRef(LPRPCPROXYBUFFER iface) +{ + ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface); + TRACE("(%p)->AddRef()\n",This); + return ++(This->RefCount); +} + +static ULONG WINAPI StdProxy_Release(LPRPCPROXYBUFFER iface) +{ + ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface); + TRACE("(%p)->Release()\n",This); + if (!--(This->RefCount)) { + StdProxy_Destruct((LPRPCPROXYBUFFER)&This->lpVtbl); + return 0; + } + return This->RefCount; +} + +static HRESULT WINAPI StdProxy_Connect(LPRPCPROXYBUFFER iface, + LPRPCCHANNELBUFFER pChannel) +{ + ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface); + TRACE("(%p)->Connect(%p)\n",This,pChannel); + This->pChannel = pChannel; + return S_OK; +} + +static VOID WINAPI StdProxy_Disconnect(LPRPCPROXYBUFFER iface) +{ + ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface); + TRACE("(%p)->Disconnect()\n",This); + This->pChannel = NULL; +} + +static ICOM_VTABLE(IRpcProxyBuffer) StdProxy_Vtbl = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + StdProxy_QueryInterface, + StdProxy_AddRef, + StdProxy_Release, + StdProxy_Connect, + StdProxy_Disconnect +}; + +HRESULT WINAPI StdProxy_GetChannel(LPVOID iface, + LPRPCCHANNELBUFFER *ppChannel) +{ + ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface); + TRACE("(%p)->GetChannel(%p)\n",This,ppChannel); + *ppChannel = This->pChannel; + return S_OK; +} + +HRESULT WINAPI StdProxy_GetIID(LPVOID iface, + const IID **ppiid) +{ + ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface); + TRACE("(%p)->GetIID(%p)\n",This,ppiid); + *ppiid = This->piid; + return S_OK; +} + +HRESULT WINAPI IUnknown_QueryInterface_Proxy(LPUNKNOWN iface, + REFIID riid, + LPVOID *ppvObj) +{ + ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface); + TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(riid),ppvObj); + return IUnknown_QueryInterface(This->pUnkOuter,riid,ppvObj); +} + +ULONG WINAPI IUnknown_AddRef_Proxy(LPUNKNOWN iface) +{ + ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface); + TRACE("(%p)->AddRef()\n",This); +#if 0 /* interface refcounting */ + return ++(This->RefCount); +#else /* object refcounting */ + return IUnknown_AddRef(This->pUnkOuter); +#endif +} + +ULONG WINAPI IUnknown_Release_Proxy(LPUNKNOWN iface) +{ + ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface); + TRACE("(%p)->Release()\n",This); +#if 0 /* interface refcounting */ + if (!--(This->RefCount)) { + StdProxy_Destruct((LPRPCPROXYBUFFER)&This->lpVtbl); + return 0; + } + return This->RefCount; +#else /* object refcounting */ + return IUnknown_Release(This->pUnkOuter); +#endif +} + --- /dev/null Mon Mar 4 08:42:02 2002 +++ wine/dlls/rpcrt4/cpsf.c Thu Jun 13 17:15:56 2002 @@ -0,0 +1,245 @@ +/* + * COM proxy/stub factory (CStdPSFactory) implementation + * + * Copyright 2001 Ove K�en, TransGaming Technologies + */ + +#include <stdio.h> +#include <string.h> + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winreg.h" + +#include "wine/obj_base.h" +#include "wine/obj_channel.h" + +#include "rpcproxy.h" + +#include "wine/debug.h" + +#include "cpsf.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +static BOOL FindProxyInfo(const ProxyFileInfo **pProxyFileList, REFIID riid, const ProxyFileInfo **pProxyInfo, int *pIndex) +{ + while (*pProxyFileList) { + if ((*pProxyFileList)->pIIDLookupRtn(riid, pIndex)) { + *pProxyInfo = *pProxyFileList; + TRACE("found: ProxyInfo %p Index %d\n", *pProxyInfo, *pIndex); + return TRUE; + } + pProxyFileList++; + } + TRACE("not found\n"); + return FALSE; +} + +static HRESULT WINAPI CStdPSFactory_QueryInterface(LPPSFACTORYBUFFER iface, + REFIID riid, + LPVOID *obj) +{ + ICOM_THIS(CStdPSFactoryBuffer,iface); + TRACE("(%p)->QueryInterface(%s,%p)\n",iface,debugstr_guid(riid),obj); + if (IsEqualGUID(&IID_IUnknown,riid) || + IsEqualGUID(&IID_IPSFactoryBuffer,riid)) { + *obj = This; + This->RefCount++; + return S_OK; + } + return E_NOINTERFACE; +} + +static ULONG WINAPI CStdPSFactory_AddRef(LPPSFACTORYBUFFER iface) +{ + ICOM_THIS(CStdPSFactoryBuffer,iface); + TRACE("(%p)->AddRef()\n",iface); + return ++(This->RefCount); +} + +static ULONG WINAPI CStdPSFactory_Release(LPPSFACTORYBUFFER iface) +{ + ICOM_THIS(CStdPSFactoryBuffer,iface); + TRACE("(%p)->Release()\n",iface); + return --(This->RefCount); +} + +static HRESULT WINAPI CStdPSFactory_CreateProxy(LPPSFACTORYBUFFER iface, + LPUNKNOWN pUnkOuter, + REFIID riid, + LPRPCPROXYBUFFER *ppProxy, + LPVOID *ppv) +{ + ICOM_THIS(CStdPSFactoryBuffer,iface); + const ProxyFileInfo *ProxyInfo; + int Index; + TRACE("(%p)->CreateProxy(%p,%s,%p,%p)\n",iface,pUnkOuter, + debugstr_guid(riid),ppProxy,ppv); + if (!FindProxyInfo(This->pProxyFileList,riid,&ProxyInfo,&Index)) + return E_NOINTERFACE; + return StdProxy_Construct(riid, pUnkOuter, ProxyInfo->pProxyVtblList[Index], + ProxyInfo->pStubVtblList[Index], iface, ppProxy, ppv); +} + +static HRESULT WINAPI CStdPSFactory_CreateStub(LPPSFACTORYBUFFER iface, + REFIID riid, + LPUNKNOWN pUnkServer, + LPRPCSTUBBUFFER *ppStub) +{ + ICOM_THIS(CStdPSFactoryBuffer,iface); + const ProxyFileInfo *ProxyInfo; + int Index; + TRACE("(%p)->CreateStub(%s,%p,%p)\n",iface,debugstr_guid(riid), + pUnkServer,ppStub); + if (!FindProxyInfo(This->pProxyFileList,riid,&ProxyInfo,&Index)) + return E_NOINTERFACE; + return CStdStubBuffer_Construct(riid, pUnkServer, ProxyInfo->pStubVtblList[Index], iface, ppStub); +} + +static ICOM_VTABLE(IPSFactoryBuffer) CStdPSFactory_Vtbl = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + CStdPSFactory_QueryInterface, + CStdPSFactory_AddRef, + CStdPSFactory_Release, + CStdPSFactory_CreateProxy, + CStdPSFactory_CreateStub +}; + +/*********************************************************************** + * NdrDllGetClassObject [RPCRT4.@] + */ +HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv, + const ProxyFileInfo **pProxyFileList, + const CLSID *pclsid, + CStdPSFactoryBuffer *pPSFactoryBuffer) +{ + *ppv = NULL; + if (!pPSFactoryBuffer->lpVtbl) { + pPSFactoryBuffer->lpVtbl = &CStdPSFactory_Vtbl; + pPSFactoryBuffer->RefCount = 0; + pPSFactoryBuffer->pProxyFileList = pProxyFileList; + } + if (IsEqualGUID(rclsid, pclsid)) + return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv); + return CLASS_E_CLASSNOTAVAILABLE; +} + +/*********************************************************************** + * NdrDllCanUnloadNow [RPCRT4.@] + */ +HRESULT WINAPI NdrDllCanUnloadNow(CStdPSFactoryBuffer *pPSFactoryBuffer) +{ + return !(pPSFactoryBuffer->RefCount); +} + +/*********************************************************************** + * NdrDllRegisterProxy [RPCRT4.@] + */ +HRESULT WINAPI NdrDllRegisterProxy(HMODULE hDll, + const ProxyFileInfo **pProxyFileList, + const CLSID *pclsid) +{ +/* #define INSTALLSHIELD_HACK */ +#ifndef INSTALLSHIELD_HACK + LPSTR clsid; + char keyname[120], module[120]; + HKEY key, subkey; + + TRACE("(%x,%p,%s)\n", hDll, pProxyFileList, debugstr_guid(pclsid)); + UuidToStringA((UUID*)pclsid, &clsid); + + /* register interfaces to point to clsid */ + while (*pProxyFileList) { + unsigned u; + for (u=0; u<(*pProxyFileList)->TableSize; u++) { + CInterfaceProxyVtbl *proxy = (*pProxyFileList)->pProxyVtblList[u]; + PCInterfaceName name = (*pProxyFileList)->pNamesArray[u]; + LPSTR iid; + + TRACE("registering %s %s => %s\n", name, debugstr_guid(proxy->header.piid), clsid); + + UuidToStringA((UUID*)proxy->header.piid, &iid); + snprintf(keyname, sizeof(keyname), "Interface\\%s", iid); + RpcStringFreeA(&iid); + if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyname, 0, NULL, 0, + KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) { + if (name) + RegSetValueExA(key, NULL, 0, REG_SZ, name, strlen(name)); + if (RegCreateKeyExA(key, "ProxyStubClsid32", 0, NULL, 0, + KEY_WRITE, NULL, &subkey, NULL) == ERROR_SUCCESS) { + RegSetValueExA(subkey, NULL, 0, REG_SZ, clsid, strlen(clsid)); + RegCloseKey(subkey); + } + RegCloseKey(key); + } + } + pProxyFileList++; + } + + /* register clsid to point to module */ + snprintf(keyname, sizeof(keyname), "CLSID\\%s", clsid); + GetModuleFileNameA(hDll, module, sizeof(module)); + TRACE("registering %s => %s\n", clsid, module); + if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyname, 0, NULL, 0, + KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) { + if (RegCreateKeyExA(key, "InProcServer32", 0, NULL, 0, + KEY_WRITE, NULL, &subkey, NULL) == ERROR_SUCCESS) { + RegSetValueExA(subkey, NULL, 0, REG_SZ, module, strlen(module)); + RegCloseKey(subkey); + } + RegCloseKey(key); + } + + /* done */ + RpcStringFreeA(&clsid); +#endif + return S_OK; +} + +/*********************************************************************** + * NdrDllUnregisterProxy [RPCRT4.@] + */ +HRESULT WINAPI NdrDllUnregisterProxy(HMODULE hDll, + const ProxyFileInfo **pProxyFileList, + const CLSID *pclsid) +{ +#ifndef INSTALLSHIELD_HACK + LPSTR clsid; + char keyname[120], module[120]; + + TRACE("(%x,%p,%s)\n", hDll, pProxyFileList, debugstr_guid(pclsid)); + UuidToStringA((UUID*)pclsid, &clsid); + + /* unregister interfaces */ + while (*pProxyFileList) { + unsigned u; + for (u=0; u<(*pProxyFileList)->TableSize; u++) { + CInterfaceProxyVtbl *proxy = (*pProxyFileList)->pProxyVtblList[u]; + PCInterfaceName name = (*pProxyFileList)->pNamesArray[u]; + LPSTR iid; + + TRACE("unregistering %s %s <= %s\n", name, debugstr_guid(proxy->header.piid), clsid); + + UuidToStringA((UUID*)proxy->header.piid, &iid); + snprintf(keyname, sizeof(keyname), "Interface\\%s", iid); + RpcStringFreeA(&iid); + RegDeleteKeyA(HKEY_CLASSES_ROOT, keyname); + } + pProxyFileList++; + } + + /* unregister clsid */ + snprintf(keyname, sizeof(keyname), "CLSID\\%s", clsid); + GetModuleFileNameA(hDll, module, sizeof(module)); + TRACE("unregistering %s <= %s\n", clsid, module); + RegDeleteKeyA(HKEY_CLASSES_ROOT, keyname); + + /* done */ + RpcStringFreeA(&clsid); +#endif + return S_OK; +} + --- /dev/null Mon Mar 4 08:42:02 2002 +++ wine/dlls/rpcrt4/cstub.c Thu Jun 13 17:16:27 2002 @@ -0,0 +1,141 @@ +/* + * COM stub (CStdStubBuffer) implementation + * + * Copyright 2001 Ove K�en, TransGaming Technologies + */ + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" + +#include "wine/obj_base.h" +#include "wine/obj_channel.h" + +#include "rpcproxy.h" + +#include "wine/debug.h" + +#include "cpsf.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +#define STUB_HEADER(This) (((CInterfaceStubHeader*)((This)->lpVtbl))[-1]) + +HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid, + LPUNKNOWN pUnkServer, + CInterfaceStubVtbl *vtbl, + LPPSFACTORYBUFFER pPSFactory, + LPRPCSTUBBUFFER *ppStub) +{ + CStdStubBuffer *This; + TRACE("(%p,%p,%p,%p)\n", pUnkServer, vtbl, pPSFactory, ppStub); + TRACE("iid=%s\n", debugstr_guid(vtbl->header.piid)); + TRACE("vtbl=%p\n", &vtbl->Vtbl); + if (!IsEqualGUID(vtbl->header.piid, riid)) { + ERR("IID mismatch during stub creation\n"); + return RPC_E_UNEXPECTED; + } + This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CStdStubBuffer)); + if (!This) return E_OUTOFMEMORY; + This->lpVtbl = &vtbl->Vtbl; + This->RefCount = 1; + This->pvServerObject = pUnkServer; + This->pPSFactory = pPSFactory; + *ppStub = (LPRPCSTUBBUFFER)This; + IPSFactoryBuffer_AddRef(pPSFactory); + return S_OK; +} + +HRESULT WINAPI CStdStubBuffer_QueryInterface(LPRPCSTUBBUFFER iface, + REFIID riid, + LPVOID *obj) +{ + ICOM_THIS(CStdStubBuffer,iface); + TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(riid),obj); + if (IsEqualGUID(&IID_IUnknown,riid) || + IsEqualGUID(&IID_IRpcStubBuffer,riid)) { + *obj = This; + This->RefCount++; + return S_OK; + } + return E_NOINTERFACE; +} + +ULONG WINAPI CStdStubBuffer_AddRef(LPRPCSTUBBUFFER iface) +{ + ICOM_THIS(CStdStubBuffer,iface); + TRACE("(%p)->AddRef()\n",This); + return ++(This->RefCount); +} + +ULONG WINAPI NdrCStdStubBuffer_Release(LPRPCSTUBBUFFER iface, + LPPSFACTORYBUFFER pPSF) +{ + ICOM_THIS(CStdStubBuffer,iface); + TRACE("(%p)->Release()\n",This); + if (!--(This->RefCount)) { + IUnknown_Release(This->pvServerObject); + IPSFactoryBuffer_Release(This->pPSFactory); + HeapFree(GetProcessHeap(),0,This); + return 0; + } + return This->RefCount; +} + +HRESULT WINAPI CStdStubBuffer_Connect(LPRPCSTUBBUFFER iface, + LPUNKNOWN lpUnkServer) +{ + ICOM_THIS(CStdStubBuffer,iface); + TRACE("(%p)->Connect(%p)\n",This,lpUnkServer); + This->pvServerObject = lpUnkServer; + return S_OK; +} + +void WINAPI CStdStubBuffer_Disconnect(LPRPCSTUBBUFFER iface) +{ + ICOM_THIS(CStdStubBuffer,iface); + TRACE("(%p)->Disconnect()\n",This); + This->pvServerObject = NULL; +} + +HRESULT WINAPI CStdStubBuffer_Invoke(LPRPCSTUBBUFFER iface, + PRPCOLEMESSAGE pMsg, + LPRPCCHANNELBUFFER pChannel) +{ + ICOM_THIS(CStdStubBuffer,iface); + DWORD dwPhase = STUB_UNMARSHAL; + TRACE("(%p)->Invoke(%p,%p)\n",This,pMsg,pChannel); + STUB_HEADER(This).pDispatchTable[pMsg->iMethod](iface, pChannel, (PRPC_MESSAGE)pMsg, &dwPhase); + return S_OK; +} + +LPRPCSTUBBUFFER WINAPI CStdStubBuffer_IsIIDSupported(LPRPCSTUBBUFFER iface, + REFIID riid) +{ + ICOM_THIS(CStdStubBuffer,iface); + TRACE("(%p)->IsIIDSupported(%s)\n",This,debugstr_guid(riid)); + return IsEqualGUID(STUB_HEADER(This).piid, riid) ? iface : NULL; +} + +ULONG WINAPI CStdStubBuffer_CountRefs(LPRPCSTUBBUFFER iface) +{ + ICOM_THIS(CStdStubBuffer,iface); + TRACE("(%p)->CountRefs()\n",This); + return This->RefCount; +} + +HRESULT WINAPI CStdStubBuffer_DebugServerQueryInterface(LPRPCSTUBBUFFER iface, + LPVOID *ppv) +{ + ICOM_THIS(CStdStubBuffer,iface); + TRACE("(%p)->DebugServerQueryInterface(%p)\n",This,ppv); + return S_OK; +} + +void WINAPI CStdStubBuffer_DebugServerRelease(LPRPCSTUBBUFFER iface, + LPVOID pv) +{ + ICOM_THIS(CStdStubBuffer,iface); + TRACE("(%p)->DebugServerRelease(%p)\n",This,pv); +} + --- /dev/null Mon Mar 4 08:42:02 2002 +++ wine/dlls/rpcrt4/ndr_midl.c Thu Jun 13 17:16:55 2002 @@ -0,0 +1,157 @@ +/* + * MIDL proxy/stub stuff + * + * Copyright 2002 Ove K�en, TransGaming Technologies + * + * TODO: + * - figure out whether we *really* got this right + * - check for errors and throw exceptions + */ + +#include <stdio.h> +#include <string.h> + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winreg.h" + +#include "wine/obj_base.h" +#include "wine/obj_channel.h" + +#include "rpcproxy.h" + +#include "wine/debug.h" + +#include "cpsf.h" +#include "ndr_misc.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +/*********************************************************************** + * NdrProxyInitialize [RPCRT4.@] + */ +void WINAPI NdrProxyInitialize(void *This, + PRPC_MESSAGE pRpcMsg, + PMIDL_STUB_MESSAGE pStubMsg, + PMIDL_STUB_DESC pStubDescriptor, + unsigned int ProcNum) +{ + HRESULT hr; + + TRACE("(%p,%p,%p,%p,%d)\n", This, pRpcMsg, pStubMsg, pStubDescriptor, ProcNum); + memset(pRpcMsg, 0, sizeof(RPC_MESSAGE)); + memset(pStubMsg, 0, sizeof(MIDL_STUB_MESSAGE)); + pRpcMsg->ProcNum = ProcNum; + pRpcMsg->RpcInterfaceInformation = pStubDescriptor->RpcInterfaceInformation; + pStubMsg->RpcMsg = pRpcMsg; + pStubMsg->IsClient = 1; + pStubMsg->ReuseBuffer = 1; + pStubMsg->pfnAllocate = pStubDescriptor->pfnAllocate; + pStubMsg->pfnFree = pStubDescriptor->pfnFree; + pStubMsg->StubDesc = pStubDescriptor; + if (This) StdProxy_GetChannel(This, &pStubMsg->pRpcChannelBuffer); + if (pStubMsg->pRpcChannelBuffer) { + hr = IRpcChannelBuffer_GetDestCtx(pStubMsg->pRpcChannelBuffer, + &pStubMsg->dwDestContext, + &pStubMsg->pvDestContext); + } + TRACE("channel=%p\n", pStubMsg->pRpcChannelBuffer); +} + +/*********************************************************************** + * NdrProxyGetBuffer [RPCRT4.@] + */ +void WINAPI NdrProxyGetBuffer(void *This, + PMIDL_STUB_MESSAGE pStubMsg) +{ + HRESULT hr; + const IID *riid = NULL; + + TRACE("(%p,%p)\n", This, pStubMsg); + pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength; + pStubMsg->dwStubPhase = PROXY_GETBUFFER; + hr = StdProxy_GetIID(This, &riid); + hr = IRpcChannelBuffer_GetBuffer(pStubMsg->pRpcChannelBuffer, + (RPCOLEMESSAGE*)pStubMsg->RpcMsg, + riid); + pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer; + pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength; + pStubMsg->Buffer = pStubMsg->BufferStart; + pStubMsg->dwStubPhase = PROXY_MARSHAL; +} + +/*********************************************************************** + * NdrProxySendReceive [RPCRT4.@] + */ +void WINAPI NdrProxySendReceive(void *This, + PMIDL_STUB_MESSAGE pStubMsg) +{ + ULONG Status = 0; + HRESULT hr; + + TRACE("(%p,%p)\n", This, pStubMsg); + pStubMsg->dwStubPhase = PROXY_SENDRECEIVE; + hr = IRpcChannelBuffer_SendReceive(pStubMsg->pRpcChannelBuffer, + (RPCOLEMESSAGE*)pStubMsg->RpcMsg, + &Status); + pStubMsg->dwStubPhase = PROXY_UNMARSHAL; + pStubMsg->BufferLength = pStubMsg->RpcMsg->BufferLength; + pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer; + pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength; + pStubMsg->Buffer = pStubMsg->BufferStart; +} + +/*********************************************************************** + * NdrProxyFreeBuffer [RPCRT4.@] + */ +void WINAPI NdrProxyFreeBuffer(void *This, + PMIDL_STUB_MESSAGE pStubMsg) +{ + HRESULT hr; + + TRACE("(%p,%p)\n", This, pStubMsg); + hr = IRpcChannelBuffer_FreeBuffer(pStubMsg->pRpcChannelBuffer, + (RPCOLEMESSAGE*)pStubMsg->RpcMsg); +} + +/*********************************************************************** + * NdrStubInitialize [RPCRT4.@] + */ +void WINAPI NdrStubInitialize(PRPC_MESSAGE pRpcMsg, + PMIDL_STUB_MESSAGE pStubMsg, + PMIDL_STUB_DESC pStubDescriptor, + LPRPCCHANNELBUFFER pRpcChannelBuffer) +{ + TRACE("(%p,%p,%p,%p)\n", pRpcMsg, pStubMsg, pStubDescriptor, pRpcChannelBuffer); + memset(pStubMsg, 0, sizeof(MIDL_STUB_MESSAGE)); + pStubMsg->RpcMsg = pRpcMsg; + pStubMsg->IsClient = 0; + pStubMsg->ReuseBuffer = 1; + pStubMsg->pfnAllocate = pStubDescriptor->pfnAllocate; + pStubMsg->pfnFree = pStubDescriptor->pfnFree; + pStubMsg->StubDesc = pStubDescriptor; + pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer; + pStubMsg->BufferLength = pStubMsg->RpcMsg->BufferLength; + pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer; + pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength; + pStubMsg->Buffer = pStubMsg->BufferStart; +} + +/*********************************************************************** + * NdrStubGetBuffer [RPCRT4.@] + */ +void WINAPI NdrStubGetBuffer(LPRPCSTUBBUFFER This, + LPRPCCHANNELBUFFER pRpcChannelBuffer, + PMIDL_STUB_MESSAGE pStubMsg) +{ + TRACE("(%p,%p)\n", This, pStubMsg); + pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer; + pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength; + I_RpcGetBuffer(pStubMsg->RpcMsg); /* ? */ + pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer; + pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength; + pStubMsg->Buffer = pStubMsg->BufferStart; +} + + --- /dev/null Mon Mar 4 08:42:02 2002 +++ wine/dlls/rpcrt4/ndr_ole.c Thu Jun 13 17:17:39 2002 @@ -0,0 +1,319 @@ +/* + * OLE32 callouts, COM interface marshalling + * + * Copyright 2001 Ove K�en, TransGaming Technologies + * + * TODO: + * - figure out whether we *really* got this right + * - check for errors and throw exceptions + * - what's the marshalling functions supposed to return? + */ + +#include <stdio.h> +#include <string.h> + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winreg.h" + +#include "wine/obj_base.h" +#include "wine/obj_storage.h" +#include "wine/obj_marshal.h" +#include "wine/obj_channel.h" + +#include "rpcndr.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +static HMODULE hOLE; + +static HRESULT WINAPI (*COM_GetMarshalSizeMax)(ULONG *,REFIID,LPUNKNOWN,DWORD,LPVOID,DWORD); +static HRESULT WINAPI (*COM_MarshalInterface)(LPSTREAM,REFIID,LPUNKNOWN,DWORD,LPVOID,DWORD); +static HRESULT WINAPI (*COM_UnmarshalInterface)(LPSTREAM,REFIID,LPVOID*); +static HRESULT WINAPI (*COM_ReleaseMarshalData)(LPSTREAM); +static HRESULT WINAPI (*COM_GetClassObject)(REFCLSID,DWORD,COSERVERINFO *,REFIID,LPVOID *); +static HRESULT WINAPI (*COM_GetPSClsid)(REFIID,CLSID *); +static LPVOID WINAPI (*COM_MemAlloc)(ULONG); +static void WINAPI (*COM_MemFree)(LPVOID); + +static HMODULE LoadCOM(void) +{ + if (hOLE) return hOLE; + hOLE = LoadLibraryA("OLE32.DLL"); + if (!hOLE) return 0; + COM_GetMarshalSizeMax = (LPVOID)GetProcAddress(hOLE, "CoGetMarshalSizeMax"); + COM_MarshalInterface = (LPVOID)GetProcAddress(hOLE, "CoMarshalInterface"); + COM_UnmarshalInterface = (LPVOID)GetProcAddress(hOLE, "CoUnmarshalInterface"); + COM_ReleaseMarshalData = (LPVOID)GetProcAddress(hOLE, "CoReleaseMarshalData"); + COM_GetClassObject = (LPVOID)GetProcAddress(hOLE, "CoGetClassObject"); + COM_GetPSClsid = (LPVOID)GetProcAddress(hOLE, "CoGetPSClsid"); + COM_MemAlloc = (LPVOID)GetProcAddress(hOLE, "CoTaskMemAlloc"); + COM_MemFree = (LPVOID)GetProcAddress(hOLE, "CoTaskMemFree"); + return hOLE; +} + +/* CoMarshalInterface/CoUnmarshalInterface works on streams, + * so implement a simple stream on top of the RPC buffer + * (which also implements the MInterfacePointer structure) */ +typedef struct RpcStreamImpl +{ + ICOM_VFIELD(IStream); + DWORD RefCount; + PMIDL_STUB_MESSAGE pMsg; + LPDWORD size; + char *data; + DWORD pos; +} RpcStreamImpl; + +static HRESULT WINAPI RpcStream_QueryInterface(LPSTREAM iface, + REFIID riid, + LPVOID *obj) +{ + ICOM_THIS(RpcStreamImpl, iface); + if (IsEqualGUID(&IID_IUnknown, riid) || + IsEqualGUID(&IID_ISequentialStream, riid) || + IsEqualGUID(&IID_IStream, riid)) { + *obj = This; + This->RefCount++; + return S_OK; + } + return E_NOINTERFACE; +} + +static ULONG WINAPI RpcStream_AddRef(LPSTREAM iface) +{ + ICOM_THIS(RpcStreamImpl, iface); + return ++(This->RefCount); +} + +static ULONG WINAPI RpcStream_Release(LPSTREAM iface) +{ + ICOM_THIS(RpcStreamImpl, iface); + if (!--(This->RefCount)) { + TRACE("size=%ld\n", *This->size); + This->pMsg->Buffer = This->data + *This->size; + HeapFree(GetProcessHeap(),0,This); + return 0; + } + return This->RefCount; +} + +static HRESULT WINAPI RpcStream_Read(LPSTREAM iface, + void *pv, + ULONG cb, + ULONG *pcbRead) +{ + ICOM_THIS(RpcStreamImpl, iface); + if (This->pos + cb > *This->size) cb = *This->size - This->pos; + if (cb) { + memcpy(pv, This->data + This->pos, cb); + This->pos += cb; + } + if (pcbRead) *pcbRead = cb; + return S_OK; +} + +static HRESULT WINAPI RpcStream_Write(LPSTREAM iface, + const void *pv, + ULONG cb, + ULONG *pcbWritten) +{ + ICOM_THIS(RpcStreamImpl, iface); + memcpy(This->data + This->pos, pv, cb); + This->pos += cb; + if (This->pos > *This->size) *This->size = This->pos; + if (pcbWritten) *pcbWritten = cb; + return S_OK; +} + +static HRESULT WINAPI RpcStream_Seek(LPSTREAM iface, + LARGE_INTEGER move, + DWORD origin, + ULARGE_INTEGER *newPos) +{ + ICOM_THIS(RpcStreamImpl, iface); + switch (origin) { + case STREAM_SEEK_SET: + This->pos = move.s.LowPart; + break; + case STREAM_SEEK_CUR: + This->pos = This->pos + move.s.LowPart; + break; + case STREAM_SEEK_END: + This->pos = *This->size + move.s.LowPart; + break; + default: + return STG_E_INVALIDFUNCTION; + } + if (newPos) { + newPos->s.LowPart = This->pos; + newPos->s.HighPart = 0; + } + return S_OK; +} + +static HRESULT WINAPI RpcStream_SetSize(LPSTREAM iface, + ULARGE_INTEGER newSize) +{ + ICOM_THIS(RpcStreamImpl, iface); + *This->size = newSize.s.LowPart; + return S_OK; +} + +static ICOM_VTABLE(IStream) RpcStream_Vtbl = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + RpcStream_QueryInterface, + RpcStream_AddRef, + RpcStream_Release, + RpcStream_Read, + RpcStream_Write, + RpcStream_Seek, + RpcStream_SetSize, + NULL, /* CopyTo */ + NULL, /* Commit */ + NULL, /* Revert */ + NULL, /* LockRegion */ + NULL, /* UnlockRegion */ + NULL, /* Stat */ + NULL /* Clone */ +}; + +static LPSTREAM RpcStream_Create(PMIDL_STUB_MESSAGE pStubMsg, BOOL init) +{ + RpcStreamImpl *This; + This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(RpcStreamImpl)); + if (!This) return NULL; + This->lpVtbl = &RpcStream_Vtbl; + This->RefCount = 1; + This->pMsg = pStubMsg; + This->size = (LPDWORD)pStubMsg->Buffer; + This->data = (char*)(This->size + 1); + This->pos = 0; + if (init) *This->size = 0; + TRACE("init size=%ld\n", *This->size); + return (LPSTREAM)This; +} + +/*********************************************************************** + * NdrInterfacePointerMarshall [RPCRT4.@] + */ +unsigned char * WINAPI NdrInterfacePointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, + unsigned char *pMemory, + PFORMAT_STRING pFormat) +{ + const IID *riid = (const IID *)pStubMsg->MaxCount; + LPSTREAM stream; + HRESULT hr; + + TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); + if (!riid) riid = &IID_IUnknown; + pStubMsg->MaxCount = 0; + if (!LoadCOM()) return NULL; + stream = RpcStream_Create(pStubMsg, TRUE); + hr = COM_MarshalInterface(stream, riid, (LPUNKNOWN)pMemory, + pStubMsg->dwDestContext, pStubMsg->pvDestContext, + MSHLFLAGS_NORMAL); + IStream_Release(stream); + return NULL; +} + +/*********************************************************************** + * NdrInterfacePointerUnmarshall [RPCRT4.@] + */ +unsigned char * WINAPI NdrInterfacePointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, + unsigned char **ppMemory, + PFORMAT_STRING pFormat, + unsigned char fMustAlloc) +{ + LPSTREAM stream; + HRESULT hr; + + TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); + if (!LoadCOM()) return NULL; + *(LPVOID*)ppMemory = NULL; + stream = RpcStream_Create(pStubMsg, FALSE); + hr = COM_UnmarshalInterface(stream, &IID_NULL, (LPVOID*)ppMemory); + IStream_Release(stream); + return NULL; +} + +/*********************************************************************** + * NdrInterfacePointerBufferSize [RPCRT4.@] + */ +void WINAPI NdrInterfacePointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, + unsigned char *pMemory, + PFORMAT_STRING pFormat) +{ + const IID *riid = (const IID *)pStubMsg->MaxCount; + ULONG size = 0; + HRESULT hr; + + TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); + if (!riid) riid = &IID_IUnknown; + if (!LoadCOM()) return; + hr = COM_GetMarshalSizeMax(&size, riid, (LPUNKNOWN)pMemory, + pStubMsg->dwDestContext, pStubMsg->pvDestContext, + MSHLFLAGS_NORMAL); + TRACE("size=%ld\n", size); + pStubMsg->BufferLength += sizeof(DWORD) + size; +} + +/*********************************************************************** + * NdrInterfacePointerMemorySize [RPCRT4.@] + */ +unsigned long WINAPI NdrInterfacePointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, + PFORMAT_STRING pFormat) +{ + FIXME("(%p,%p): stub\n", pStubMsg, pFormat); + return 0; +} + +/*********************************************************************** + * NdrInterfacePointerFree [RPCRT4.@] + */ +void WINAPI NdrInterfacePointerFree(PMIDL_STUB_MESSAGE pStubMsg, + unsigned char *pMemory, + PFORMAT_STRING pFormat) +{ + LPUNKNOWN pUnk = (LPUNKNOWN)pMemory; + TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); + if (pUnk) IUnknown_Release(pUnk); +} + +/*********************************************************************** + * NdrOleAllocate [RPCRT4.@] + */ +void * WINAPI NdrOleAllocate(size_t Size) +{ + if (!LoadCOM()) return NULL; + return COM_MemAlloc(Size); +} + +/*********************************************************************** + * NdrOleFree [RPCRT4.@] + */ +void WINAPI NdrOleFree(void *NodeToFree) +{ + if (!LoadCOM()) return; + COM_MemFree(NodeToFree); +} + +/* internal */ +HRESULT RPCRT4_GetPSFactory(REFIID riid, LPPSFACTORYBUFFER *pPS) +{ + HRESULT hr; + CLSID clsid; + + if (!LoadCOM()) return RPC_E_UNEXPECTED; + hr = COM_GetPSClsid(riid, &clsid); + if (FAILED(hr)) return hr; + hr = COM_GetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, + &IID_IPSFactoryBuffer, (LPVOID *)pPS); + return hr; +} + + --- /dev/null Mon Mar 4 08:42:02 2002 +++ wine/dlls/rpcrt4/ndr_stubless.c Thu Jun 13 17:18:32 2002 @@ -0,0 +1,46 @@ +/* + * NDR client stuff + * + * Copyright 2001 Ove K�en, TransGaming Technologies + * + * TODO: + * - figure out whether we *really* got this right + * - check for errors and throw exceptions + */ + +#include <stdio.h> +#include <string.h> + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winreg.h" + +#include "rpc.h" +#include "rpcndr.h" + +#include "wine/debug.h" + +#include "ndr_misc.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +LONG_PTR RPCRT4_NdrClientCall2(PMIDL_STUB_DESC pStubDesc, + PFORMAT_STRING pFormat, + LPVOID args) +{ + FIXME("(%p,%p,...)\n", pStubDesc, pFormat); + return 0; +} + +/*********************************************************************** + * NdrClientCall2 [RPCRT4.@] + */ +CLIENT_CALL_RETURN WINAPIV NdrClientCall2(PMIDL_STUB_DESC pStubDesc, + PFORMAT_STRING pFormat, + ...) +{ + TRACE("(%p,%p,...)\n", pStubDesc, pFormat); + return (CLIENT_CALL_RETURN)RPCRT4_NdrClientCall2(pStubDesc, pFormat, &pFormat + 1); +} + --- /dev/null Mon Mar 4 08:42:02 2002 +++ wine/dlls/rpcrt4/rpc_binding.c Thu Jun 13 17:19:45 2002 @@ -0,0 +1,743 @@ +/* + * RPC binding API + * + * Copyright 2001 Ove K�en, TransGaming Technologies + * + * TODO: + * - a whole lot + */ + +#include <stdio.h> +#include <string.h> + +#include "windef.h" +#include "winbase.h" +#include "winnls.h" +#include "winerror.h" +#include "winreg.h" +#include "wine/unicode.h" + +#include "rpc.h" + +#include "wine/debug.h" + +#include "rpc_binding.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +LPSTR RPCRT4_strdupAA(LPSTR src, INT slen) +{ + DWORD len; + LPSTR s; + if (!src) return NULL; + if (slen == -1) slen = strlen(src); + len = slen; + s = HeapAlloc(GetProcessHeap(), 0, len+1); + memcpy(s, src, len); + s[len] = 0; + return s; +} + +LPSTR RPCRT4_strdupAW(LPWSTR src, INT slen) +{ + DWORD len; + LPSTR s; + if (!src) return NULL; + if (slen == -1) slen = strlenW(src); + len = WideCharToMultiByte(CP_ACP, 0, src, slen, NULL, 0, NULL, NULL); + s = HeapAlloc(GetProcessHeap(), 0, len+1); + WideCharToMultiByte(CP_ACP, 0, src, slen, s, len, NULL, NULL); + s[len] = 0; + return s; +} + +LPWSTR RPCRT4_strdupWA(LPSTR src, INT slen) +{ + DWORD len; + LPWSTR s; + if (!src) return NULL; + if (slen == -1) slen = strlen(src); + len = MultiByteToWideChar(CP_ACP, 0, src, slen, NULL, 0); + s = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, src, slen, s, len); + s[len] = 0; + return s; +} + +LPWSTR RPCRT4_strdupWW(LPWSTR src, INT slen) +{ + DWORD len; + LPWSTR s; + if (!src) return NULL; + if (slen == -1) slen = strlenW(src); + len = slen; + s = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR)); + memcpy(s, src, len*sizeof(WCHAR)); + s[len] = 0; + return s; +} + +void RPCRT4_strfree(LPSTR src) +{ + if (src) HeapFree(GetProcessHeap(), 0, src); +} + +RPC_STATUS RPCRT4_CreateBindingA(RpcBinding** Binding, BOOL server, LPSTR Protseq) +{ + RpcBinding* NewBinding; + + NewBinding = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcBinding)); + NewBinding->refs = 1; + NewBinding->server = server; + NewBinding->Protseq = RPCRT4_strdupA(Protseq); + + TRACE("binding: %p\n", NewBinding); + *Binding = NewBinding; + + return RPC_S_OK; +} + +RPC_STATUS RPCRT4_CreateBindingW(RpcBinding** Binding, BOOL server, LPWSTR Protseq) +{ + RpcBinding* NewBinding; + + NewBinding = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcBinding)); + NewBinding->refs = 1; + NewBinding->server = server; + NewBinding->Protseq = RPCRT4_strdupW(Protseq); + + TRACE("binding: %p\n", NewBinding); + *Binding = NewBinding; + + return RPC_S_OK; +} + +RPC_STATUS RPCRT4_CompleteBindingA(RpcBinding* Binding, LPSTR NetworkAddr, LPSTR Endpoint, LPSTR NetworkOptions) +{ + RPCRT4_strfree(Binding->NetworkAddr); + Binding->NetworkAddr = RPCRT4_strdupA(NetworkAddr); + RPCRT4_strfree(Binding->Endpoint); + Binding->Endpoint = RPCRT4_strdupA(Endpoint); + + return RPC_S_OK; +} + +RPC_STATUS RPCRT4_CompleteBindingW(RpcBinding* Binding, LPWSTR NetworkAddr, LPWSTR Endpoint, LPWSTR NetworkOptions) +{ + RPCRT4_strfree(Binding->NetworkAddr); + Binding->NetworkAddr = RPCRT4_strdupW(NetworkAddr); + RPCRT4_strfree(Binding->Endpoint); + Binding->Endpoint = RPCRT4_strdupW(Endpoint); + + return RPC_S_OK; +} + +RPC_STATUS RPCRT4_ResolveBinding(RpcBinding* Binding, LPSTR Endpoint) +{ + RPCRT4_strfree(Binding->Endpoint); + Binding->Endpoint = RPCRT4_strdup(Endpoint); + + return RPC_S_OK; +} + +RPC_STATUS RPCRT4_SetBindingObject(RpcBinding* Binding, UUID* ObjectUuid) +{ + if (ObjectUuid) memcpy(&Binding->ObjectUuid, ObjectUuid, sizeof(UUID)); + else UuidCreateNil(&Binding->ObjectUuid); + return RPC_S_OK; +} + +RPC_STATUS RPCRT4_SpawnBinding(RpcBinding** Binding, RpcBinding* OldBinding) +{ + RpcBinding* NewBinding; + + NewBinding = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcBinding)); + NewBinding->refs = 1; + NewBinding->server = OldBinding->server; + NewBinding->Protseq = RPCRT4_strdup(OldBinding->Protseq); + NewBinding->NetworkAddr = RPCRT4_strdup(OldBinding->NetworkAddr); + NewBinding->Endpoint = RPCRT4_strdup(OldBinding->Endpoint); + /* because of the way named pipes work, we'll transfer the connected pipe + * to the child, then reopen the server binding to continue listening */ + NewBinding->conn = OldBinding->conn; + NewBinding->ovl = OldBinding->ovl; + OldBinding->conn = 0; + memset(&OldBinding->ovl, 0, sizeof(OldBinding->ovl)); + *Binding = NewBinding; + RPCRT4_OpenBinding(OldBinding); + + return RPC_S_OK; +} + +RPC_STATUS RPCRT4_ExportBinding(RpcBinding** Binding, RpcBinding* OldBinding) +{ + InterlockedIncrement(&OldBinding->refs); + *Binding = OldBinding; + return RPC_S_OK; +} + +RPC_STATUS RPCRT4_DestroyBinding(RpcBinding* Binding) +{ + if (InterlockedDecrement(&Binding->refs)) + return RPC_S_OK; + + TRACE("binding: %p\n", Binding); + RPCRT4_CloseBinding(Binding); + RPCRT4_strfree(Binding->Endpoint); + RPCRT4_strfree(Binding->NetworkAddr); + RPCRT4_strfree(Binding->Protseq); + HeapFree(GetProcessHeap(), 0, Binding); + return RPC_S_OK; +} + +RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding) +{ + if (!Binding->conn) { + if (Binding->server) { /* server */ + /* protseq=ncalrpc: supposed to use NT LPC ports, + * but we'll implement it with named pipes for now */ + if (strcmp(Binding->Protseq, "ncalrpc") == 0) { + static LPSTR prefix = "\\\\.\\pipe\\lrpc\\"; + LPSTR pname; + pname = HeapAlloc(GetProcessHeap(), 0, strlen(prefix) + strlen(Binding->Endpoint) + 1); + strcat(strcpy(pname, prefix), Binding->Endpoint); + TRACE("listening on %s\n", pname); + Binding->conn = CreateNamedPipeA(pname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, + 0, PIPE_UNLIMITED_INSTANCES, 0, 0, 5000, NULL); + HeapFree(GetProcessHeap(), 0, pname); + memset(&Binding->ovl, 0, sizeof(Binding->ovl)); + Binding->ovl.hEvent = CreateEventA(NULL, TRUE, FALSE, NULL); + if (!ConnectNamedPipe(Binding->conn, &Binding->ovl)) { + DWORD err = GetLastError(); + if (err == ERROR_PIPE_CONNECTED) { + SetEvent(Binding->ovl.hEvent); + return RPC_S_OK; + } + return err; + } + } + /* protseq=ncacn_np: named pipes */ + else if (strcmp(Binding->Protseq, "ncacn_np") == 0) { + static LPSTR prefix = "\\\\."; + LPSTR pname; + pname = HeapAlloc(GetProcessHeap(), 0, strlen(prefix) + strlen(Binding->Endpoint) + 1); + strcat(strcpy(pname, prefix), Binding->Endpoint); + TRACE("listening on %s\n", pname); + Binding->conn = CreateNamedPipeA(pname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, + 0, PIPE_UNLIMITED_INSTANCES, 0, 0, 5000, NULL); + HeapFree(GetProcessHeap(), 0, pname); + memset(&Binding->ovl, 0, sizeof(Binding->ovl)); + Binding->ovl.hEvent = CreateEventA(NULL, TRUE, FALSE, NULL); + if (!ConnectNamedPipe(Binding->conn, &Binding->ovl)) { + DWORD err = GetLastError(); + if (err == ERROR_PIPE_CONNECTED) { + SetEvent(Binding->ovl.hEvent); + return RPC_S_OK; + } + return err; + } + } + else { + ERR("protseq %s not supported\n", Binding->Protseq); + return RPC_S_PROTSEQ_NOT_SUPPORTED; + } + } + else { /* client */ + /* protseq=ncalrpc: supposed to use NT LPC ports, + * but we'll implement it with named pipes for now */ + if (strcmp(Binding->Protseq, "ncalrpc") == 0) { + static LPSTR prefix = "\\\\.\\pipe\\lrpc\\"; + LPSTR pname; + HANDLE conn; + DWORD err; + + pname = HeapAlloc(GetProcessHeap(), 0, strlen(prefix) + strlen(Binding->Endpoint) + 1); + strcat(strcpy(pname, prefix), Binding->Endpoint); + TRACE("connecting to %s\n", pname); + while (TRUE) { + if (WaitNamedPipeA(pname, NMPWAIT_WAIT_FOREVER)) { + conn = CreateFileA(pname, GENERIC_READ|GENERIC_WRITE, 0, NULL, + OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); + if (conn != INVALID_HANDLE_VALUE) break; + err = GetLastError(); + if (err == ERROR_PIPE_BUSY) continue; + TRACE("connection failed, error=%lx\n", err); + HeapFree(GetProcessHeap(), 0, pname); + return err; + } + else { + err = GetLastError(); + TRACE("connection failed, error=%lx\n", err); + HeapFree(GetProcessHeap(), 0, pname); + return err; + } + } + + /* success */ + HeapFree(GetProcessHeap(), 0, pname); + memset(&Binding->ovl, 0, sizeof(Binding->ovl)); + Binding->ovl.hEvent = CreateEventA(NULL, TRUE, FALSE, NULL); + Binding->conn = conn; + } + /* protseq=ncacn_np: named pipes */ + else if (strcmp(Binding->Protseq, "ncacn_np") == 0) { + static LPSTR prefix = "\\\\."; + LPSTR pname; + HANDLE conn; + DWORD err; + + pname = HeapAlloc(GetProcessHeap(), 0, strlen(prefix) + strlen(Binding->Endpoint) + 1); + strcat(strcpy(pname, prefix), Binding->Endpoint); + TRACE("connecting to %s\n", pname); + conn = CreateFileA(pname, GENERIC_READ|GENERIC_WRITE, 0, NULL, + OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); + if (conn == INVALID_HANDLE_VALUE) { + err = GetLastError(); + /* we don't need to handle ERROR_PIPE_BUSY here, + * the doc says that it is returned to the app */ + TRACE("connection failed, error=%lx\n", err); + HeapFree(GetProcessHeap(), 0, pname); + return err; + } + + /* success */ + HeapFree(GetProcessHeap(), 0, pname); + memset(&Binding->ovl, 0, sizeof(Binding->ovl)); + Binding->ovl.hEvent = CreateEventA(NULL, TRUE, FALSE, NULL); + Binding->conn = conn; + } + else { + ERR("protseq %s not supported\n", Binding->Protseq); + return RPC_S_PROTSEQ_NOT_SUPPORTED; + } + } + } + return RPC_S_OK; +} + +RPC_STATUS RPCRT4_CloseBinding(RpcBinding* Binding) +{ + if (Binding->conn) { + CancelIo(Binding->conn); + CloseHandle(Binding->conn); + Binding->conn = 0; + } + if (Binding->ovl.hEvent) { + CloseHandle(Binding->ovl.hEvent); + Binding->ovl.hEvent = 0; + } + return RPC_S_OK; +} + +/* utility functions for string composing and parsing */ +static unsigned RPCRT4_strcopyA(LPSTR data, LPCSTR src) +{ + unsigned len = strlen(src); + memcpy(data, src, len*sizeof(CHAR)); + return len; +} + +static unsigned RPCRT4_strcopyW(LPWSTR data, LPCWSTR src) +{ + unsigned len = strlenW(src); + memcpy(data, src, len*sizeof(WCHAR)); + return len; +} + +static LPSTR RPCRT4_strconcatA(LPSTR dst, LPCSTR src) +{ + DWORD len = strlen(dst), slen = strlen(src); + LPSTR ndst = HeapReAlloc(GetProcessHeap(), 0, dst, (len+slen+2)*sizeof(CHAR)); + if (!ndst) HeapFree(GetProcessHeap(), 0, dst); + ndst[len] = ','; + memcpy(ndst+len+1, src, slen*sizeof(CHAR)); + ndst[len+slen+1] = 0; + return ndst; +} + +static LPWSTR RPCRT4_strconcatW(LPWSTR dst, LPCWSTR src) +{ + DWORD len = strlenW(dst), slen = strlenW(src); + LPWSTR ndst = HeapReAlloc(GetProcessHeap(), 0, dst, (len+slen+2)*sizeof(WCHAR)); + if (!ndst) HeapFree(GetProcessHeap(), 0, dst); + ndst[len] = ','; + memcpy(ndst+len+1, src, slen*sizeof(WCHAR)); + ndst[len+slen+1] = 0; + return ndst; +} + +#define RPC_STRING_BINDING_COMPOSE(char_t,strlen_t,strcopy_t) \ + if (ObjUuid && *ObjUuid) len += strlen_t(ObjUuid) + 1; \ + if (Protseq && *Protseq) len += strlen_t(Protseq) + 1; \ + if (NetworkAddr && *NetworkAddr) len += strlen_t(NetworkAddr); \ + if (Endpoint && *Endpoint) len += strlen_t(Endpoint) + 2; \ + if (Options && *Options) len += strlen_t(Options) + 2; \ + \ + data = HeapAlloc(GetProcessHeap(), 0, len*sizeof(char_t)); \ + *StringBinding = data; \ + \ + if (ObjUuid && *ObjUuid) { \ + data += strcopy_t(data, ObjUuid); \ + *data++ = '@'; \ + } \ + if (Protseq && *Protseq) { \ + data += strcopy_t(data, Protseq); \ + *data++ = ':'; \ + } \ + if (NetworkAddr && *NetworkAddr) { \ + data += strcopy_t(data, NetworkAddr); \ + } \ + if ((Endpoint && *Endpoint) || \ + (Options && *Options)) { \ + *data++ = '['; \ + if (Endpoint && *Endpoint) { \ + data += strcopy_t(data, Endpoint); \ + if (Options && *Options) *data++ = ','; \ + } \ + if (Options && *Options) { \ + data += strcopy_t(data, Options); \ + } \ + *data++ = ']'; \ + } \ + *data = 0; + +/*********************************************************************** + * RpcStringBindingComposeA (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcStringBindingComposeA( LPSTR ObjUuid, LPSTR Protseq, + LPSTR NetworkAddr, LPSTR Endpoint, + LPSTR Options, LPSTR* StringBinding ) +{ + DWORD len = 1; + LPSTR data; + + TRACE( "(%s,%s,%s,%s,%s,%p)\n", + debugstr_a( ObjUuid ), debugstr_a( Protseq ), + debugstr_a( NetworkAddr ), debugstr_a( Endpoint ), + debugstr_a( Options ), StringBinding ); + + RPC_STRING_BINDING_COMPOSE(CHAR,strlen,RPCRT4_strcopyA) + + return RPC_S_OK; +} + +/*********************************************************************** + * RpcStringBindingComposeW (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcStringBindingComposeW( LPWSTR ObjUuid, LPWSTR Protseq, + LPWSTR NetworkAddr, LPWSTR Endpoint, + LPWSTR Options, LPWSTR* StringBinding ) +{ + DWORD len = 1; + LPWSTR data; + + TRACE("(%s,%s,%s,%s,%s,%p)\n", + debugstr_w( ObjUuid ), debugstr_w( Protseq ), + debugstr_w( NetworkAddr ), debugstr_w( Endpoint ), + debugstr_w( Options ), StringBinding); + + RPC_STRING_BINDING_COMPOSE(WCHAR,strlenW,RPCRT4_strcopyW) + + return RPC_S_OK; +} + +#define RPC_STRING_BINDING_PARSE(char_t,strlen_t,strchr_t,strncmp_t,strdup_t,strconc_t) \ + if (ObjUuid) *ObjUuid = NULL; \ + if (Protseq) *Protseq = NULL; \ + if (NetworkAddr) *NetworkAddr = NULL; \ + if (Endpoint) *Endpoint = NULL; \ + if (Options) *Options = NULL; \ + \ + data = StringBinding; \ + \ + next = strchr_t(data, '@'); \ + if (next) { \ + if (ObjUuid) *ObjUuid = strdup_t(data, next - data); \ + data = next+1; \ + } \ + \ + next = strchr_t(data, ':'); \ + if (next) { \ + if (Protseq) *Protseq = strdup_t(data, next - data); \ + data = next+1; \ + } \ + \ + next = strchr_t(data, '['); \ + if (next) { \ + char_t *close, *opt; \ + \ + if (NetworkAddr) *NetworkAddr = strdup_t(data, next - data); \ + data = next+1; \ + close = strchr_t(data, ']'); \ + if (!close) goto fail; \ + \ + /* tokenize options */ \ + while (data < close) { \ + next = strchr_t(data, ','); \ + if (!next || next > close) next = close; \ + /* FIXME: this is kind of inefficient */ \ + opt = strdup_t(data, next - data); \ + data = next+1; \ + \ + /* parse option */ \ + next = strchr_t(opt, '='); \ + if (!next) { \ + /* not an option, must be an endpoint */ \ + if (*Endpoint) goto fail; \ + *Endpoint = opt; \ + } \ + else { \ + if (strncmp_t(opt, ep_opt, strlen_t(ep_opt)) == 0) { \ + /* endpoint option */ \ + if (*Endpoint) goto fail; \ + *Endpoint = strdup_t(next+1, strlen_t(next+1)); \ + HeapFree(GetProcessHeap(), 0, opt); \ + } \ + else { \ + /* network option */ \ + if (*Options) { \ + /* FIXME: this is kind of inefficient */ \ + *Options = strconc_t(*Options, opt); \ + HeapFree(GetProcessHeap(), 0, opt); \ + } \ + else *Options = opt; \ + } \ + } \ + } \ + \ + data = close+1; \ + if (*data) goto fail; \ + } \ + else if (NetworkAddr) *NetworkAddr = strdup_t(data, strlen_t(data)); \ + +/*********************************************************************** + * RpcStringBindingParseA (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcStringBindingParseA( LPSTR StringBinding, LPSTR *ObjUuid, + LPSTR *Protseq, LPSTR *NetworkAddr, + LPSTR *Endpoint, LPSTR *Options) +{ + CHAR *data, *next; + static CHAR ep_opt[] = {'e','n','d','p','o','i','n','t','=',0}; + + TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_a(StringBinding), + ObjUuid, Protseq, NetworkAddr, Endpoint, Options); + + RPC_STRING_BINDING_PARSE(CHAR,strlen,strchr,strncmp,RPCRT4_strdupAA,RPCRT4_strconcatA) + + return RPC_S_OK; +fail: + if (ObjUuid) RpcStringFreeA(ObjUuid); + if (Protseq) RpcStringFreeA(Protseq); + if (NetworkAddr) RpcStringFreeA(NetworkAddr); + if (Endpoint) RpcStringFreeA(Endpoint); + if (Options) RpcStringFreeA(Options); + return RPC_S_INVALID_STRING_BINDING; +} + +/*********************************************************************** + * RpcStringBindingParseW (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcStringBindingParseW( LPWSTR StringBinding, LPWSTR *ObjUuid, + LPWSTR *Protseq, LPWSTR *NetworkAddr, + LPWSTR *Endpoint, LPWSTR *Options) +{ + WCHAR *data, *next; + static WCHAR ep_opt[] = {'e','n','d','p','o','i','n','t','=',0}; + + TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_w(StringBinding), + ObjUuid, Protseq, NetworkAddr, Endpoint, Options); + + RPC_STRING_BINDING_PARSE(WCHAR,strlenW,strchrW,strncmpW,RPCRT4_strdupWW,RPCRT4_strconcatW) + + return RPC_S_OK; +fail: + if (ObjUuid) RpcStringFreeW(ObjUuid); + if (Protseq) RpcStringFreeW(Protseq); + if (NetworkAddr) RpcStringFreeW(NetworkAddr); + if (Endpoint) RpcStringFreeW(Endpoint); + if (Options) RpcStringFreeW(Options); + return RPC_S_INVALID_STRING_BINDING; +} + +/*********************************************************************** + * RpcBindingFree (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcBindingFree( RPC_BINDING_HANDLE* Binding ) +{ + RPC_STATUS status; + TRACE("(%p) = %p\n", Binding, *Binding); + status = RPCRT4_DestroyBinding(*Binding); + if (status == RPC_S_OK) *Binding = 0; + return status; +} + +/*********************************************************************** + * RpcBindingVectorFree (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcBindingVectorFree( RPC_BINDING_VECTOR** BindingVector ) +{ + RPC_STATUS status; + unsigned long c; + + TRACE("(%p)\n", BindingVector); + for (c=0; c<(*BindingVector)->Count; c++) { + status = RpcBindingFree(&(*BindingVector)->BindingH[c]); + } + HeapFree(GetProcessHeap(), 0, *BindingVector); + *BindingVector = NULL; + return RPC_S_OK; +} + +/*********************************************************************** + * RpcBindingInqObject (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcBindingInqObject( RPC_BINDING_HANDLE Binding, UUID* ObjectUuid ) +{ + RpcBinding* bind = (RpcBinding*)Binding; + + TRACE("(%p,%p) = %s\n", Binding, ObjectUuid, debugstr_guid(&bind->ObjectUuid)); + memcpy(ObjectUuid, &bind->ObjectUuid, sizeof(UUID)); + return RPC_S_OK; +} + +/*********************************************************************** + * RpcBindingSetObject (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcBindingSetObject( RPC_BINDING_HANDLE Binding, UUID* ObjectUuid ) +{ + RpcBinding* bind = (RpcBinding*)Binding; + + TRACE("(%p,%s)\n", Binding, debugstr_guid(ObjectUuid)); + if (bind->server) return RPC_S_WRONG_KIND_OF_BINDING; + return RPCRT4_SetBindingObject(Binding, ObjectUuid); +} + +/*********************************************************************** + * RpcBindingFromStringBindingA (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcBindingFromStringBindingA( LPSTR StringBinding, RPC_BINDING_HANDLE* Binding ) +{ + RPC_STATUS ret; + RpcBinding* bind = NULL; + LPSTR ObjectUuid, Protseq, NetworkAddr, Endpoint, Options; + UUID Uuid; + + TRACE("(%s,%p)\n", debugstr_a(StringBinding), Binding); + + ret = RpcStringBindingParseA(StringBinding, &ObjectUuid, &Protseq, + &NetworkAddr, &Endpoint, &Options); + if (ret != RPC_S_OK) return ret; + + ret = UuidFromStringA(ObjectUuid, &Uuid); + + if (ret == RPC_S_OK) + ret = RPCRT4_CreateBindingA(&bind, FALSE, Protseq); + if (ret == RPC_S_OK) + ret = RPCRT4_SetBindingObject(bind, &Uuid); + if (ret == RPC_S_OK) + ret = RPCRT4_CompleteBindingA(bind, NetworkAddr, Endpoint, Options); + + RpcStringFreeA(&Options); + RpcStringFreeA(&Endpoint); + RpcStringFreeA(&NetworkAddr); + RpcStringFreeA(&Protseq); + RpcStringFreeA(&ObjectUuid); + + if (ret == RPC_S_OK) *Binding = (RPC_BINDING_HANDLE)bind; + else RPCRT4_DestroyBinding(bind); + + return ret; +} + +/*********************************************************************** + * RpcBindingFromStringBindingW (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcBindingFromStringBindingW( LPWSTR StringBinding, RPC_BINDING_HANDLE* Binding ) +{ + RPC_STATUS ret; + RpcBinding* bind = NULL; + LPWSTR ObjectUuid, Protseq, NetworkAddr, Endpoint, Options; + UUID Uuid; + + TRACE("(%s,%p)\n", debugstr_w(StringBinding), Binding); + + ret = RpcStringBindingParseW(StringBinding, &ObjectUuid, &Protseq, + &NetworkAddr, &Endpoint, &Options); + if (ret != RPC_S_OK) return ret; + + ret = UuidFromStringW(ObjectUuid, &Uuid); + + if (ret == RPC_S_OK) + ret = RPCRT4_CreateBindingW(&bind, FALSE, Protseq); + if (ret == RPC_S_OK) + ret = RPCRT4_SetBindingObject(bind, &Uuid); + if (ret == RPC_S_OK) + ret = RPCRT4_CompleteBindingW(bind, NetworkAddr, Endpoint, Options); + + RpcStringFreeW(&Options); + RpcStringFreeW(&Endpoint); + RpcStringFreeW(&NetworkAddr); + RpcStringFreeW(&Protseq); + RpcStringFreeW(&ObjectUuid); + + if (ret == RPC_S_OK) *Binding = (RPC_BINDING_HANDLE)bind; + else RPCRT4_DestroyBinding(bind); + + return ret; +} + +/*********************************************************************** + * RpcBindingToStringBindingA (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcBindingToStringBindingA( RPC_BINDING_HANDLE Binding, LPSTR* StringBinding ) +{ + RPC_STATUS ret; + RpcBinding* bind = (RpcBinding*)Binding; + LPSTR ObjectUuid; + + TRACE("(%p,%p)\n", Binding, StringBinding); + + ret = UuidToStringA(&bind->ObjectUuid, &ObjectUuid); + if (ret != RPC_S_OK) return ret; + + ret = RpcStringBindingComposeA(ObjectUuid, bind->Protseq, bind->NetworkAddr, + bind->Endpoint, NULL, StringBinding); + + RpcStringFreeA(&ObjectUuid); + + return ret; +} + +/*********************************************************************** + * RpcBindingToStringBindingW (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcBindingToStringBindingW( RPC_BINDING_HANDLE Binding, LPWSTR* StringBinding ) +{ + RPC_STATUS ret; + LPSTR str = NULL; + TRACE("(%p,%p)\n", Binding, StringBinding); + ret = RpcBindingToStringBindingA(Binding, &str); + *StringBinding = RPCRT4_strdupWA(str, -1); + RpcStringFreeA(&str); + return ret; +} + +/*********************************************************************** + * I_RpcBindingSetAsync (RPCRT4.@) + * NOTES + * Exists in win9x and winNT, but with different number of arguments + * (9x version has 3 arguments, NT has 2). + */ +RPC_STATUS WINAPI I_RpcBindingSetAsync( RPC_BINDING_HANDLE Binding, RPC_BLOCKING_FN BlockingFn, unsigned long ServerTid ) +{ + RpcBinding* bind = (RpcBinding*)Binding; + + TRACE( "(%p,%p,%ld): stub\n", Binding, BlockingFn, ServerTid ); + + bind->BlockingFn = BlockingFn; + bind->ServerTid = ServerTid; + + return RPC_S_OK; +} + --- /dev/null Mon Mar 4 08:42:02 2002 +++ wine/dlls/rpcrt4/rpc_epmap.c Thu Jun 13 17:20:10 2002 @@ -0,0 +1,172 @@ +/* + * RPC endpoint mapper + * + * Copyright 2001 Ove K�en, TransGaming Technologies + * + * TODO: + * - actually do things right + */ + +#include <stdio.h> +#include <string.h> + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winreg.h" + +#include "wine/server.h" +#include "rpc.h" + +#include "wine/debug.h" + +#include "rpc_binding.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +/* The "real" RPC portmapper endpoints that I know of are: + * + * ncadg_ip_udp: 135 + * ncacn_ip_tcp: 135 + * ncacn_np: \\pipe\epmapper (?) + * ncalrpc: epmapper + * + * If the user's machine ran a DCE RPC daemon, it would + * probably be possible to connect to it, but there are many + * reasons not to, like: + * - the user probably does *not* run one, and probably + * shouldn't be forced to run one just for local COM + * - very few Unix systems use DCE RPC... if they run a RPC + * daemon at all, it's usually Sun RPC + * - DCE RPC registrations are persistent and saved on disk, + * while MS-RPC registrations are documented as non-persistent + * and stored only in RAM, and auto-destroyed when the process + * dies (something DCE RPC can't do) + * + * Of course, if the user *did* want to run a DCE RPC daemon anyway, + * there would be interoperability advantages, like the possibility + * of running a fully functional DCOM server using Wine... + * + * But for now, I'll just use the wineserver... + */ + +/*********************************************************************** + * RpcEpRegisterA (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR* BindingVector, + UUID_VECTOR* UuidVector, LPSTR Annotation ) +{ + NTSTATUS ret; + PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec; + unsigned long c; + + TRACE("(%p,%p,%p,%s)\n", IfSpec, BindingVector, UuidVector, debugstr_a(Annotation)); + TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID)); + for (c=0; c<BindingVector->Count; c++) { + RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[c]); + TRACE(" protseq[%ld]=%s\n", c, bind->Protseq); + TRACE(" endpoint[%ld]=%s\n", c, bind->Endpoint); + } + if (UuidVector) { + for (c=0; c<UuidVector->Count; c++) + TRACE(" obj[%ld]=%s\n", c, debugstr_guid(UuidVector->Uuid[c])); + } + + SERVER_START_REQ( register_rpc_endpoints ) + { + wine_server_add_data( req, &If->InterfaceId, sizeof(RPC_SYNTAX_IDENTIFIER) ); + if (UuidVector) { + req->objects = UuidVector->Count; + for (c=0; c<req->objects; c++) + wine_server_add_data( req, UuidVector->Uuid[c], sizeof(UUID) ); + } + else req->objects = 0; + req->bindings = BindingVector->Count; + for (c=0; c<req->bindings; c++) { + RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[c]); + wine_server_add_data( req, bind->Protseq, strlen(bind->Protseq)+1 ); + wine_server_add_data( req, bind->Endpoint, strlen(bind->Endpoint)+1 ); + } + req->no_replace = 0; + /* FIXME: annotation */ + ret = wine_server_call( req ); + } + SERVER_END_REQ; + + return RtlNtStatusToDosError(ret); +} + +/*********************************************************************** + * RpcEpUnregister (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR* BindingVector, + UUID_VECTOR* UuidVector ) +{ + NTSTATUS ret; + PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec; + unsigned long c; + + TRACE("(%p,%p,%p)\n", IfSpec, BindingVector, UuidVector); + TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID)); + for (c=0; c<BindingVector->Count; c++) { + RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[c]); + TRACE(" protseq[%ld]=%s\n", c, bind->Protseq); + TRACE(" endpoint[%ld]=%s\n", c, bind->Endpoint); + } + if (UuidVector) { + for (c=0; c<UuidVector->Count; c++) + TRACE(" obj[%ld]=%s\n", c, debugstr_guid(UuidVector->Uuid[c])); + } + + SERVER_START_REQ( unregister_rpc_endpoints ) + { + wine_server_add_data( req, &If->InterfaceId, sizeof(RPC_SYNTAX_IDENTIFIER) ); + if (UuidVector) { + req->objects = UuidVector->Count; + for (c=0; c<req->objects; c++) + wine_server_add_data( req, UuidVector->Uuid[c], sizeof(UUID) ); + } + else req->objects = 0; + req->bindings = BindingVector->Count; + for (c=0; c<req->bindings; c++) { + RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[c]); + wine_server_add_data( req, bind->Protseq, strlen(bind->Protseq)+1 ); + wine_server_add_data( req, bind->Endpoint, strlen(bind->Endpoint)+1 ); + } + ret = wine_server_call( req ); + } + SERVER_END_REQ; + + return RtlNtStatusToDosError(ret); +} + +/*********************************************************************** + * RpcEpResolveBinding (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcEpResolveBinding( RPC_BINDING_HANDLE Binding, RPC_IF_HANDLE IfSpec ) +{ + NTSTATUS ret; + PRPC_CLIENT_INTERFACE If = (PRPC_CLIENT_INTERFACE)IfSpec; + RpcBinding* bind = (RpcBinding*)Binding; + char Endpoint[64]; + + TRACE("(%p,%p)\n", Binding, IfSpec); + TRACE(" protseq=%s\n", bind->Protseq); + TRACE(" obj=%s\n", debugstr_guid(&bind->ObjectUuid)); + TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID)); + + SERVER_START_REQ( resolve_rpc_endpoint ) + { + wine_server_add_data( req, &If->InterfaceId, sizeof(RPC_SYNTAX_IDENTIFIER) ); + wine_server_add_data( req, &bind->ObjectUuid, sizeof(UUID) ); + wine_server_add_data( req, bind->Protseq, strlen(bind->Protseq)+1 ); + wine_server_set_reply( req, Endpoint, sizeof(Endpoint) ); + ret = wine_server_call( req ); + } + SERVER_END_REQ; + + if (ret) return RtlNtStatusToDosError(ret); + + return RPCRT4_ResolveBinding(Binding, Endpoint); +} + --- /dev/null Mon Mar 4 08:42:02 2002 +++ wine/dlls/rpcrt4/rpc_message.c Thu Jun 13 17:26:16 2002 @@ -0,0 +1,166 @@ +/* + * RPC messages + * + * Copyright 2001-2002 Ove K�en, TransGaming Technologies + * + * TODO: + * - figure out whether we *really* got this right + * - check for errors and throw exceptions + */ + +#include <stdio.h> +#include <string.h> + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winreg.h" + +#include "rpc.h" +#include "rpcdcep.h" + +#include "wine/debug.h" + +#include "rpc_binding.h" +#include "rpc_defs.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +/*********************************************************************** + * I_RpcGetBuffer [RPCRT4.@] + */ +RPC_STATUS WINAPI I_RpcGetBuffer(PRPC_MESSAGE pMsg) +{ + void* buf; + + TRACE("(%p)\n", pMsg); + buf = HeapReAlloc(GetProcessHeap(), 0, pMsg->Buffer, pMsg->BufferLength); + if (buf) pMsg->Buffer = buf; + /* FIXME: which errors to return? */ + return buf ? S_OK : E_OUTOFMEMORY; +} + +/*********************************************************************** + * I_RpcFreeBuffer [RPCRT4.@] + */ +RPC_STATUS WINAPI I_RpcFreeBuffer(PRPC_MESSAGE pMsg) +{ + TRACE("(%p)\n", pMsg); + HeapFree(GetProcessHeap(), 0, pMsg->Buffer); + pMsg->Buffer = NULL; + return S_OK; +} + +/*********************************************************************** + * I_RpcSend [RPCRT4.@] + */ +RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg) +{ + RpcBinding* bind = (RpcBinding*)pMsg->Handle; + RPC_CLIENT_INTERFACE* cif; + RPC_STATUS status; + RpcPktHdr hdr; + + TRACE("(%p)\n", pMsg); + if (!bind) return RPC_S_INVALID_BINDING; + + /* I'll only implement this for client handles for now */ + if (bind->server) return RPC_S_WRONG_KIND_OF_BINDING; + + cif = pMsg->RpcInterfaceInformation; + if (!cif) return RPC_S_INTERFACE_NOT_FOUND; /* ? */ + + status = RPCRT4_OpenBinding(bind); + if (status != RPC_S_OK) return status; + + /* initialize packet header */ + memset(&hdr, 0, sizeof(hdr)); + hdr.rpc_ver = 4; + hdr.ptype = PKT_REQUEST; + hdr.object = bind->ObjectUuid; + hdr.if_id = cif->InterfaceId.SyntaxGUID; + hdr.if_vers = MAKELONG(cif->InterfaceId.SyntaxVersion.MinorVersion, + cif->InterfaceId.SyntaxVersion.MajorVersion); + hdr.opnum = pMsg->ProcNum; + hdr.len = pMsg->BufferLength; + + /* transmit packet */ + if (!WriteFile(bind->conn, &hdr, sizeof(hdr), NULL, NULL)) + return GetLastError(); + if (!WriteFile(bind->conn, pMsg->Buffer, pMsg->BufferLength, NULL, NULL)) + return GetLastError(); + + /* success */ + return RPC_S_OK; +} + +/*********************************************************************** + * I_RpcReceive [RPCRT4.@] + */ +RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg) +{ + RpcBinding* bind = (RpcBinding*)pMsg->Handle; + RPC_STATUS status; + RpcPktHdr hdr; + DWORD dwRead; + + TRACE("(%p)\n", pMsg); + if (!bind) return RPC_S_INVALID_BINDING; + + /* I'll only implement this for client handles for now */ + if (bind->server) return RPC_S_WRONG_KIND_OF_BINDING; + + status = RPCRT4_OpenBinding(bind); + if (status != RPC_S_OK) return status; + + /* read packet header */ +#ifdef OVERLAPPED_WORKS + if (!ReadFile(bind->conn, &hdr, sizeof(hdr), &dwRead, &bind->ovl)) { + DWORD err = GetLastError(); + if (err != ERROR_IO_PENDING) { + return err; + } + if (!GetOverlappedResult(bind->conn, &bind->ovl, &dwRead, TRUE)) return GetLastError(); + } +#else + if (!ReadFile(bind->conn, &hdr, sizeof(hdr), &dwRead, NULL)) + return GetLastError(); +#endif + if (dwRead != sizeof(hdr)) return RPC_S_PROTOCOL_ERROR; + + /* read packet body */ + pMsg->BufferLength = hdr.len; + status = I_RpcGetBuffer(pMsg); + if (status != RPC_S_OK) return status; +#ifdef OVERLAPPED_WORKS + if (!ReadFile(bind->conn, pMsg->Buffer, hdr.len, &dwRead, &bind->ovl)) { + DWORD err = GetLastError(); + if (err != ERROR_IO_PENDING) { + return err; + } + if (!GetOverlappedResult(bind->conn, &bind->ovl, &dwRead, TRUE)) return GetLastError(); + } +#else + if (!ReadFile(bind->conn, pMsg->Buffer, hdr.len, &dwRead, NULL)) + return GetLastError(); +#endif + if (dwRead != hdr.len) return RPC_S_PROTOCOL_ERROR; + + /* success */ + return RPC_S_OK; +} + +/*********************************************************************** + * I_RpcSendReceive [RPCRT4.@] + */ +RPC_STATUS WINAPI I_RpcSendReceive(PRPC_MESSAGE pMsg) +{ + RPC_STATUS status; + + TRACE("(%p)\n", pMsg); + status = I_RpcSend(pMsg); + if (status == RPC_S_OK) + status = I_RpcReceive(pMsg); + return status; +} + --- /dev/null Mon Mar 4 08:42:02 2002 +++ wine/dlls/rpcrt4/rpc_server.c Thu Jun 13 17:26:43 2002 @@ -0,0 +1,563 @@ +/* + * RPC server API + * + * Copyright 2001 Ove K�en, TransGaming Technologies + * + * TODO: + * - a whole lot + */ + +#include <stdio.h> +#include <string.h> + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winreg.h" + +#include "rpc.h" + +#include "wine/debug.h" + +#include "rpc_server.h" +#include "rpc_defs.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +static RpcServerProtseq* protseqs; +static RpcServerInterface* ifs; + +static CRITICAL_SECTION server_cs = CRITICAL_SECTION_INIT("RpcServer"); +static BOOL std_listen; +static LONG listen_count = -1; +static HANDLE mgr_event, server_thread; + +static RpcServerInterface* RPCRT4_find_interface(UUID* object, UUID* if_id) +{ + UUID* MgrType = NULL; + RpcServerInterface* cif = NULL; + RPC_STATUS status; + + /* FIXME: object -> MgrType */ + EnterCriticalSection(&server_cs); + cif = ifs; + while (cif) { + if (UuidEqual(if_id, &cif->If->InterfaceId.SyntaxGUID, &status) && + UuidEqual(MgrType, &cif->MgrTypeUuid, &status) && + (std_listen || (cif->Flags & RPC_IF_AUTOLISTEN))) break; + cif = cif->Next; + } + LeaveCriticalSection(&server_cs); + return cif; +} + +static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg) +{ + RpcBinding* bind = (RpcBinding*)the_arg; + RpcPktHdr hdr; + DWORD dwRead; + RPC_MESSAGE msg; + RpcServerInterface* sif; + RPC_DISPATCH_FUNCTION func; + + memset(&msg, 0, sizeof(msg)); + msg.Handle = (RPC_BINDING_HANDLE)bind; + + for (;;) { + /* read packet header */ +#ifdef OVERLAPPED_WORKS + if (!ReadFile(bind->conn, &hdr, sizeof(hdr), &dwRead, &bind->ovl)) { + DWORD err = GetLastError(); + if (err != ERROR_IO_PENDING) { + TRACE("connection lost, error=%08lx\n", err); + break; + } + if (!GetOverlappedResult(bind->conn, &bind->ovl, &dwRead, TRUE)) break; + } +#else + if (!ReadFile(bind->conn, &hdr, sizeof(hdr), &dwRead, NULL)) { + TRACE("connection lost, error=%08lx\n", GetLastError()); + break; + } +#endif + if (dwRead != sizeof(hdr)) { + TRACE("protocol error\n"); + break; + } + + /* read packet body */ + msg.BufferLength = hdr.len; + msg.Buffer = HeapAlloc(GetProcessHeap(), 0, msg.BufferLength); +#ifdef OVERLAPPED_WORKS + if (!ReadFile(bind->conn, msg.Buffer, msg.BufferLength, &dwRead, &bind->ovl)) { + DWORD err = GetLastError(); + if (err != ERROR_IO_PENDING) { + TRACE("connection lost, error=%08lx\n", err); + break; + } + if (!GetOverlappedResult(bind->conn, &bind->ovl, &dwRead, TRUE)) break; + } +#else + if (!ReadFile(bind->conn, msg.Buffer, msg.BufferLength, &dwRead, NULL)) { + TRACE("connection lost, error=%08lx\n", GetLastError()); + break; + } +#endif + if (dwRead != hdr.len) { + TRACE("protocol error\n"); + break; + } + + sif = RPCRT4_find_interface(&hdr.object, &hdr.if_id); + if (sif) { + msg.RpcInterfaceInformation = sif->If; + /* associate object with binding (this is a bit of a hack... + * a new binding should probably be created for each object) */ + RPCRT4_SetBindingObject(bind, &hdr.object); + /* process packet*/ + switch (hdr.ptype) { + case PKT_REQUEST: + /* find dispatch function */ + msg.ProcNum = hdr.opnum; + if (sif->Flags & RPC_IF_OLE) { + /* native ole32 always gives us a dispatch table with a single entry + * (I assume that's a wrapper for IRpcStubBuffer::Invoke) */ + func = *sif->If->DispatchTable->DispatchTable; + } else { + if (msg.ProcNum >= sif->If->DispatchTable->DispatchTableCount) { + ERR("invalid procnum\n"); + func = NULL; + } + func = sif->If->DispatchTable->DispatchTable[msg.ProcNum]; + } + + /* dispatch */ + if (func) func(&msg); + + /* prepare response packet */ + hdr.ptype = PKT_RESPONSE; + break; + default: + ERR("unknown packet type\n"); + goto no_reply; + } + + /* write reply packet */ + hdr.len = msg.BufferLength; + WriteFile(bind->conn, &hdr, sizeof(hdr), NULL, NULL); + WriteFile(bind->conn, msg.Buffer, msg.BufferLength, NULL, NULL); + + no_reply: + /* un-associate object */ + RPCRT4_SetBindingObject(bind, NULL); + msg.RpcInterfaceInformation = NULL; + } + else { + ERR("got RPC packet to unregistered interface %s\n", debugstr_guid(&hdr.if_id)); + } + + /* clean up */ + HeapFree(GetProcessHeap(), 0, msg.Buffer); + msg.Buffer = NULL; + } + if (msg.Buffer) HeapFree(GetProcessHeap(), 0, msg.Buffer); + RPCRT4_DestroyBinding(bind); + return 0; +} + +static void RPCRT4_new_client(RpcBinding* bind) +{ + bind->thread = CreateThread(NULL, 0, RPCRT4_io_thread, bind, 0, NULL); +} + +static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg) +{ + HANDLE m_event = mgr_event, b_handle; + HANDLE *objs = NULL; + DWORD count, res; + RpcServerProtseq* cps; + RpcBinding* bind; + RpcBinding* cbind; + + for (;;) { + EnterCriticalSection(&server_cs); + /* open and count bindings */ + count = 1; + cps = protseqs; + while (cps) { + bind = cps->bind; + while (bind) { + RPCRT4_OpenBinding(bind); + if (bind->ovl.hEvent) count++; + bind = bind->Next; + } + cps = cps->Next; + } + /* make array of bindings */ + objs = HeapReAlloc(GetProcessHeap(), 0, objs, count*sizeof(HANDLE)); + objs[0] = m_event; + count = 1; + cps = protseqs; + while (cps) { + bind = cps->bind; + while (bind) { + if (bind->ovl.hEvent) objs[count++] = bind->ovl.hEvent; + bind = bind->Next; + } + cps = cps->Next; + } + LeaveCriticalSection(&server_cs); + + /* start waiting */ + res = WaitForMultipleObjects(count, objs, FALSE, INFINITE); + if (res == WAIT_OBJECT_0) { + if (listen_count == -1) break; + } + else if (res == WAIT_FAILED) { + ERR("wait failed\n"); + } + else { + b_handle = objs[res - WAIT_OBJECT_0]; + /* find which binding got a RPC */ + EnterCriticalSection(&server_cs); + bind = NULL; + cps = protseqs; + while (cps) { + bind = cps->bind; + while (bind) { + if (bind->ovl.hEvent == b_handle) break; + bind = bind->Next; + } + if (bind) break; + cps = cps->Next; + } + cbind = NULL; + if (bind) RPCRT4_SpawnBinding(&cbind, bind); + LeaveCriticalSection(&server_cs); + if (!bind) { + ERR("failed to locate binding for handle %d\n", b_handle); + } + if (cbind) RPCRT4_new_client(cbind); + } + } + HeapFree(GetProcessHeap(), 0, objs); + EnterCriticalSection(&server_cs); + /* close bindings */ + cps = protseqs; + while (cps) { + bind = cps->bind; + while (bind) { + RPCRT4_CloseBinding(bind); + bind = bind->Next; + } + cps = cps->Next; + } + LeaveCriticalSection(&server_cs); + return 0; +} + +static void RPCRT4_start_listen(void) +{ + if (!InterlockedIncrement(&listen_count)) { + mgr_event = CreateEventA(NULL, FALSE, FALSE, NULL); + server_thread = CreateThread(NULL, 0, RPCRT4_server_thread, NULL, 0, NULL); + } + else SetEvent(mgr_event); +} + +static void RPCRT4_stop_listen(void) +{ + HANDLE m_event = mgr_event; + if (InterlockedDecrement(&listen_count) < 0) + SetEvent(m_event); +} + +static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps) +{ + RPCRT4_CreateBindingA(&ps->bind, TRUE, ps->Protseq); + RPCRT4_CompleteBindingA(ps->bind, NULL, ps->Endpoint, NULL); + + EnterCriticalSection(&server_cs); + ps->Next = protseqs; + protseqs = ps; + LeaveCriticalSection(&server_cs); + + if (listen_count >= 0) SetEvent(mgr_event); + + return RPC_S_OK; +} + +/*********************************************************************** + * RpcServerInqBindings (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector ) +{ + RPC_STATUS status; + DWORD count; + RpcServerProtseq* ps; + RpcBinding* bind; + + EnterCriticalSection(&server_cs); + /* count bindings */ + count = 0; + ps = protseqs; + while (ps) { + bind = ps->bind; + while (bind) { + count++; + bind = bind->Next; + } + ps = ps->Next; + } + if (count) { + /* export bindings */ + *BindingVector = HeapAlloc(GetProcessHeap(), 0, + sizeof(RPC_BINDING_VECTOR) + + sizeof(RPC_BINDING_HANDLE)*(count-1)); + (*BindingVector)->Count = count; + count = 0; + ps = protseqs; + while (ps) { + bind = ps->bind; + while (bind) { + RPCRT4_ExportBinding((RpcBinding**)&(*BindingVector)->BindingH[count], + bind); + count++; + bind = bind->Next; + } + ps = ps->Next; + } + status = RPC_S_OK; + } else { + *BindingVector = NULL; + status = RPC_S_NO_BINDINGS; + } + LeaveCriticalSection(&server_cs); + return status; +} + +/*********************************************************************** + * RpcServerUseProtseqEpA (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcServerUseProtseqEpA( LPSTR Protseq, UINT MaxCalls, LPSTR Endpoint, LPVOID SecurityDescriptor ) +{ + RPC_POLICY policy; + + TRACE( "(%s,%u,%s,%p)\n", Protseq, MaxCalls, Endpoint, SecurityDescriptor ); + + /* This should provide the default behaviour */ + policy.Length = sizeof( policy ); + policy.EndpointFlags = 0; + policy.NICFlags = 0; + + return RpcServerUseProtseqEpExA( Protseq, MaxCalls, Endpoint, SecurityDescriptor, &policy ); +} + +/*********************************************************************** + * RpcServerUseProtseqEpW (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcServerUseProtseqEpW( LPWSTR Protseq, UINT MaxCalls, LPWSTR Endpoint, LPVOID SecurityDescriptor ) +{ + RPC_POLICY policy; + + TRACE( "(%s,%u,%s,%p)\n", debugstr_w( Protseq ), MaxCalls, debugstr_w( Endpoint ), SecurityDescriptor ); + + /* This should provide the default behaviour */ + policy.Length = sizeof( policy ); + policy.EndpointFlags = 0; + policy.NICFlags = 0; + + return RpcServerUseProtseqEpExW( Protseq, MaxCalls, Endpoint, SecurityDescriptor, &policy ); +} + +/*********************************************************************** + * RpcServerUseProtseqEpExA (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcServerUseProtseqEpExA( LPSTR Protseq, UINT MaxCalls, LPSTR Endpoint, LPVOID SecurityDescriptor, + PRPC_POLICY lpPolicy ) +{ + RpcServerProtseq* ps; + + TRACE("(%s,%u,%s,%p,{%u,%lu,%lu}): stub\n", debugstr_a( Protseq ), MaxCalls, + debugstr_a( Endpoint ), SecurityDescriptor, + lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags ); + + ps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcServerProtseq)); + ps->MaxCalls = MaxCalls; + ps->Protseq = RPCRT4_strdupA(Protseq); + ps->Endpoint = RPCRT4_strdupA(Endpoint); + + return RPCRT4_use_protseq(ps); +} + +/*********************************************************************** + * RpcServerUseProtseqEpExW (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcServerUseProtseqEpExW( LPWSTR Protseq, UINT MaxCalls, LPWSTR Endpoint, LPVOID SecurityDescriptor, + PRPC_POLICY lpPolicy ) +{ + RpcServerProtseq* ps; + + TRACE("(%s,%u,%s,%p,{%u,%lu,%lu}): stub\n", debugstr_w( Protseq ), MaxCalls, + debugstr_w( Endpoint ), SecurityDescriptor, + lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags ); + + ps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcServerProtseq)); + ps->MaxCalls = MaxCalls; + ps->Protseq = RPCRT4_strdupW(Protseq); + ps->Endpoint = RPCRT4_strdupW(Endpoint); + + return RPCRT4_use_protseq(ps); +} + +/*********************************************************************** + * RpcServerRegisterIf (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcServerRegisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv ) +{ + TRACE("(%p,%s,%p)\n", IfSpec, debugstr_guid(MgrTypeUuid), MgrEpv); + return RpcServerRegisterIf2( IfSpec, MgrTypeUuid, MgrEpv, 0, RPC_C_LISTEN_MAX_CALLS_DEFAULT, (UINT)-1, NULL ); +} + +/*********************************************************************** + * RpcServerRegisterIfEx (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcServerRegisterIfEx( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv, + UINT Flags, UINT MaxCalls, RPC_IF_CALLBACK_FN* IfCallbackFn ) +{ + TRACE("(%p,%s,%p,%u,%u,%p)\n", IfSpec, debugstr_guid(MgrTypeUuid), MgrEpv, Flags, MaxCalls, IfCallbackFn); + return RpcServerRegisterIf2( IfSpec, MgrTypeUuid, MgrEpv, Flags, MaxCalls, (UINT)-1, IfCallbackFn ); +} + +/*********************************************************************** + * RpcServerRegisterIf2 (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv, + UINT Flags, UINT MaxCalls, UINT MaxRpcSize, RPC_IF_CALLBACK_FN* IfCallbackFn ) +{ + PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec; + RpcServerInterface* sif; + int i; + + TRACE("(%p,%s,%p,%u,%u,%u,%p)\n", IfSpec, debugstr_guid(MgrTypeUuid), MgrEpv, Flags, MaxCalls, + MaxRpcSize, IfCallbackFn); + TRACE(" interface id: %s %d.%d\n", debugstr_guid(&If->InterfaceId.SyntaxGUID), + If->InterfaceId.SyntaxVersion.MajorVersion, + If->InterfaceId.SyntaxVersion.MinorVersion); + TRACE(" transfer syntax: %s %d.%d\n", debugstr_guid(&If->InterfaceId.SyntaxGUID), + If->InterfaceId.SyntaxVersion.MajorVersion, + If->InterfaceId.SyntaxVersion.MinorVersion); + TRACE(" dispatch table: %p\n", If->DispatchTable); + if (If->DispatchTable) { + TRACE(" dispatch table count: %d\n", If->DispatchTable->DispatchTableCount); + for (i=0; i<If->DispatchTable->DispatchTableCount; i++) { + TRACE(" entry %d: %p\n", i, If->DispatchTable->DispatchTable[i]); + } + TRACE(" reserved: %d\n", If->DispatchTable->Reserved); + } + TRACE(" protseq endpoint count: %d\n", If->RpcProtseqEndpointCount); + TRACE(" default manager epv: %p\n", If->DefaultManagerEpv); + TRACE(" interpreter info: %p\n", If->InterpreterInfo); + TRACE(" flags: %08x\n", If->Flags); + + sif = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcServerInterface)); + sif->If = If; + if (MgrTypeUuid) + memcpy(&sif->MgrTypeUuid, MgrTypeUuid, sizeof(UUID)); + else + memset(&sif->MgrTypeUuid, 0, sizeof(UUID)); + sif->MgrEpv = MgrEpv; + sif->Flags = Flags; + sif->MaxCalls = MaxCalls; + sif->MaxRpcSize = MaxRpcSize; + sif->IfCallbackFn = IfCallbackFn; + + EnterCriticalSection(&server_cs); + sif->Next = ifs; + ifs = sif; + LeaveCriticalSection(&server_cs); + + if (sif->Flags & RPC_IF_AUTOLISTEN) { + /* well, start listening, I think... */ + RPCRT4_start_listen(); + } + + return RPC_S_OK; +} + +/*********************************************************************** + * RpcServerRegisterAuthInfoA (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcServerRegisterAuthInfoA( LPSTR ServerPrincName, ULONG AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn, + LPVOID Arg ) +{ + FIXME( "(%s,%lu,%p,%p): stub\n", ServerPrincName, AuthnSvc, GetKeyFn, Arg ); + + return RPC_S_UNKNOWN_AUTHN_SERVICE; /* We don't know any authentication services */ +} + +/*********************************************************************** + * RpcServerRegisterAuthInfoW (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcServerRegisterAuthInfoW( LPWSTR ServerPrincName, ULONG AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn, + LPVOID Arg ) +{ + FIXME( "(%s,%lu,%p,%p): stub\n", debugstr_w( ServerPrincName ), AuthnSvc, GetKeyFn, Arg ); + + return RPC_S_UNKNOWN_AUTHN_SERVICE; /* We don't know any authentication services */ +} + +/*********************************************************************** + * RpcServerListen (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcServerListen( UINT MinimumCallThreads, UINT MaxCalls, UINT DontWait ) +{ + TRACE("(%u,%u,%u)\n", MinimumCallThreads, MaxCalls, DontWait); + + if (std_listen) + return RPC_S_ALREADY_LISTENING; + + if (!protseqs) + return RPC_S_NO_PROTSEQS_REGISTERED; + + std_listen = TRUE; + RPCRT4_start_listen(); + + if (DontWait) return RPC_S_OK; + + /* RpcMgmtWaitServerListen(); */ + FIXME("can't wait yet\n"); + return RPC_S_OK; +} + +/*********************************************************************** + * I_RpcServerStartListening (RPCRT4.@) + */ +RPC_STATUS WINAPI I_RpcServerStartListening( void* hWnd ) +{ + FIXME( "(%p): stub\n", hWnd ); + + return RPC_S_OK; +} + +/*********************************************************************** + * I_RpcServerStopListening (RPCRT4.@) + */ +RPC_STATUS WINAPI I_RpcServerStopListening( void ) +{ + FIXME( "(): stub\n" ); + + return RPC_S_OK; +} + +/*********************************************************************** + * I_RpcWindowProc (RPCRT4.@) + */ +UINT WINAPI I_RpcWindowProc( void* hWnd, UINT Message, UINT wParam, ULONG lParam ) +{ + FIXME( "(%p,%08x,%08x,%08lx): stub\n", hWnd, Message, wParam, lParam ); + + return 0; +} + +