I can't find any doc from Microsoft on these, they are kind of mysterious to me... but here they are. From Jürgen Schmied's RPC patches. Minor changes may exist between this and the original patch but it's intended to be basically the same stuff. LICENSE: X11 CHANGELOG: * dlls/rpcrt4: rpcrt4.spec, rpcrt4_main.c, rpc_message.c (new), rpc_defs.h (new), Makefile.in: Ove Kaaven <ovek@transgaming.com> - implement I_RpcFreeBuffer, I_RpcGetBuffer, I_RpcReceive, I_RpcSend, I_RpcSendReceive; administrivia. -- gmt "If ye love wealth better than liberty, the tranquility of servitude better than the animating contest of freedom, go home from us in peace. We ask not your counsels or your arms. Crouch down and lick the hands, which feed you. May your chains set lightly upon you, and may posterity forget that ye were our countrymen." -Samuel Adams
Index: dlls/rpcrt4/Makefile.in =================================================================== RCS file: /home/wine/wine/dlls/rpcrt4/Makefile.in,v retrieving revision 1.10 diff -u -r1.10 Makefile.in --- dlls/rpcrt4/Makefile.in 7 Oct 2002 21:54:07 -0000 1.10 +++ dlls/rpcrt4/Makefile.in 8 Oct 2002 22:05:31 -0000 @@ -11,6 +11,7 @@ C_SRCS = \ rpc_binding.c \ + rpc_message.c \ rpcrt4_main.c SUBDIRS = tests Index: dlls/rpcrt4/rpcrt4.spec =================================================================== RCS file: /home/wine/wine/dlls/rpcrt4/rpcrt4.spec,v retrieving revision 1.21 diff -u -r1.21 rpcrt4.spec --- dlls/rpcrt4/rpcrt4.spec 7 Oct 2002 21:52:55 -0000 1.21 +++ dlls/rpcrt4/rpcrt4.spec 8 Oct 2002 22:05:32 -0000 @@ -435,10 +435,10 @@ @ 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,10 +458,10 @@ @ 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 Index: dlls/rpcrt4/rpcrt4_main.c =================================================================== RCS file: /home/wine/wine/dlls/rpcrt4/rpcrt4_main.c,v retrieving revision 1.31 diff -u -r1.31 rpcrt4_main.c --- dlls/rpcrt4/rpcrt4_main.c 7 Oct 2002 21:52:55 -0000 1.31 +++ dlls/rpcrt4/rpcrt4_main.c 8 Oct 2002 22:05:32 -0000 @@ -128,49 +128,45 @@ } /************************************************************************* - * UuidEqual [RPCRT4.@] + * UuidCompare [RPCRT4.@] + * + * (an educated-guess implementation) * * PARAMS * UUID *Uuid1 [I] Uuid to compare * UUID *Uuid2 [I] Uuid to compare * RPC_STATUS *Status [O] returns RPC_S_OK - * + * * RETURNS - * TRUE/FALSE + * -1 if Uuid1 is less than Uuid2 + * 0 if Uuid1 and Uuid2 are equal + * 1 if Uuid1 is greater than Uuid2 */ -int WINAPI UuidEqual(UUID *Uuid1, UUID *Uuid2, RPC_STATUS *Status) +int WINAPI UuidCompare(UUID *Uuid1, UUID *Uuid2, RPC_STATUS *Status) { 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)); + if (Uuid1 == Uuid2) return 0; + return memcmp(Uuid1, Uuid2, sizeof(UUID)); } /************************************************************************* - * UuidCompare [RPCRT4.@] - * - * (an educated-guess implementation) + * UuidEqual [RPCRT4.@] * * PARAMS * UUID *Uuid1 [I] Uuid to compare * UUID *Uuid2 [I] Uuid to compare * RPC_STATUS *Status [O] returns RPC_S_OK - * + * * RETURNS - * -1 if Uuid1 is less than Uuid2 - * 0 if Uuid1 and Uuid2 are equal - * 1 if Uuid1 is greater than Uuid2 + * TRUE/FALSE */ -int WINAPI UuidCompare(UUID *Uuid1, UUID *Uuid2, RPC_STATUS *Status) +int WINAPI UuidEqual(UUID *Uuid1, UUID *Uuid2, RPC_STATUS *Status) { 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 0; - return memcmp(Uuid1, Uuid2, sizeof(UUID)); + return !UuidCompare(Uuid1, Uuid2, Status); } /************************************************************************* --- /dev/null 1969-12-31 18:00:00.000000000 -0600 +++ dlls/rpcrt4/rpc_defs.h 2002-10-08 16:50:17.000000000 -0500 @@ -0,0 +1,61 @@ +#ifndef __WINE_RPC_DEFS_H +#define __WINE_RPC_DEFS_H + +/* info from http://www.microsoft.com/msj/0398/dcomtextfigs.htm */ + +typedef struct +{ + unsigned char rpc_ver; + unsigned char ptype; + unsigned char flags1; + unsigned char flags2; + unsigned char drep[3]; + unsigned char serial_hi; + GUID object; + GUID if_id; + GUID act_id; + unsigned long server_boot; + unsigned long if_vers; + unsigned long seqnum; + unsigned short opnum; + unsigned short ihint; + unsigned short ahint; + unsigned short len; + unsigned short fragnum; + unsigned char auth_proto; + unsigned char serial_lo; +} RpcPktHdr; + +#define PKT_REQUEST 0 +#define PKT_PING 1 +#define PKT_RESPONSE 2 +#define PKT_FAULT 3 +#define PKT_WORKING 4 +#define PKT_NOCALL 5 +#define PKT_REJECT 6 +#define PKT_ACK 7 +#define PKT_CL_CANCEL 8 +#define PKT_FACK 9 +#define PKT_CANCEL_ACK 10 +#define PKT_BIND 11 +#define PKT_BIND_ACK 12 +#define PKT_BIND_NAK 13 +#define PKT_ALTER_CONTEXT 14 +#define PKT_ALTER_CONTEXT_RESP 15 +#define PKT_SHUTDOWN 17 +#define PKT_CO_CANCEL 18 +#define PKT_ORPHANED 19 + +#define NCADG_IP_UDP 0x08 +#define NCACN_IP_TCP 0x07 +#define NCADG_IPX 0x0E +#define NCACN_SPX 0x0C +#define NCACN_NB_NB 0x12 +#define NCACN_NB_IPX 0x0D +#define NCACN_DNET_NSP 0x04 +#define NCACN_HTTP 0x1F + +/* FreeDCE: TWR_C_FLR_PROT_ID_IP */ +#define TWR_IP 0x09 + +#endif --- /dev/null 1969-12-31 18:00:00.000000000 -0600 +++ dlls/rpcrt4/rpc_message.c 2002-10-08 16:32:21.000000000 -0500 @@ -0,0 +1,167 @@ +/* + * RPC messages + * + * Copyright 2001-2002 Ove Kåven, TransGaming Technologies + * + * TODO: + * - figure out whether we *really* got this right + * - check for errors and throw exceptions + * - decide if OVERLAPPED_WORKS + */ + +#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; +} +