diff --git a/dlls/rpcrt4/Makefile.in b/dlls/rpcrt4/Makefile.in index 6e068f3b9a8..6243cdd7bf7 100644 --- a/dlls/rpcrt4/Makefile.in +++ b/dlls/rpcrt4/Makefile.in @@ -11,6 +11,7 @@ SYMBOLFILE = $(MODULE).tmp.o C_SRCS = \ rpc_binding.c \ + rpc_message.c \ rpcrt4_main.c SUBDIRS = tests diff --git a/dlls/rpcrt4/rpc_defs.h b/dlls/rpcrt4/rpc_defs.h new file mode 100644 index 00000000000..3cb688f3bc9 --- /dev/null +++ b/dlls/rpcrt4/rpc_defs.h @@ -0,0 +1,81 @@ +/* + * RPC definitions + * + * Copyright 2001-2002 Ove Kåven, TransGaming Technologies + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#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 /* __WINE_RPC_DEFS_H */ diff --git a/dlls/rpcrt4/rpc_message.c b/dlls/rpcrt4/rpc_message.c new file mode 100644 index 00000000000..b10c451c1e1 --- /dev/null +++ b/dlls/rpcrt4/rpc_message.c @@ -0,0 +1,180 @@ +/* + * RPC messages + * + * Copyright 2001-2002 Ove Kåven, TransGaming Technologies + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * TODO: + * - figure out whether we *really* got this right + * - check for errors and throw exceptions + * - decide if OVERLAPPED_WORKS + */ + +#include +#include + +#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; +} diff --git a/dlls/rpcrt4/rpcrt4.spec b/dlls/rpcrt4/rpcrt4.spec index 5f3b6a6ebff..7d94040070d 100644 --- a/dlls/rpcrt4/rpcrt4.spec +++ b/dlls/rpcrt4/rpcrt4.spec @@ -435,10 +435,10 @@ init RPCRT4_LibMain @ 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 @@ init RPCRT4_LibMain @ 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 diff --git a/dlls/rpcrt4/rpcrt4_main.c b/dlls/rpcrt4/rpcrt4_main.c index 3a745d0fa6e..89b15d44757 100644 --- a/dlls/rpcrt4/rpcrt4_main.c +++ b/dlls/rpcrt4/rpcrt4_main.c @@ -127,27 +127,6 @@ RPC_STATUS WINAPI RpcStringFreeW(LPWSTR* String) return RPC_S_OK; } -/************************************************************************* - * UuidEqual [RPCRT4.@] - * - * PARAMS - * UUID *Uuid1 [I] Uuid to compare - * UUID *Uuid2 [I] Uuid to compare - * RPC_STATUS *Status [O] returns RPC_S_OK - * - * RETURNS - * TRUE/FALSE - */ -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 TRUE; - return !memcmp(Uuid1, Uuid2, sizeof(UUID)); -} - /************************************************************************* * UuidCompare [RPCRT4.@] * @@ -173,6 +152,23 @@ int WINAPI UuidCompare(UUID *Uuid1, UUID *Uuid2, RPC_STATUS *Status) return memcmp(Uuid1, Uuid2, sizeof(UUID)); } +/************************************************************************* + * UuidEqual [RPCRT4.@] + * + * PARAMS + * UUID *Uuid1 [I] Uuid to compare + * UUID *Uuid2 [I] Uuid to compare + * RPC_STATUS *Status [O] returns RPC_S_OK + * + * RETURNS + * TRUE/FALSE + */ +int WINAPI UuidEqual(UUID *Uuid1, UUID *Uuid2, RPC_STATUS *Status) +{ + TRACE("(%s,%s)\n", debugstr_guid(Uuid1), debugstr_guid(Uuid2)); + return !UuidCompare(Uuid1, Uuid2, Status); +} + /************************************************************************* * UuidIsNil [RPCRT4.@] *