Commit 0a17edf3 authored by Ove Kaaven's avatar Ove Kaaven Committed by Alexandre Julliard

Implemented I_RpcFreeBuffer, I_RpcGetBuffer, I_RpcReceive, I_RpcSend,

I_RpcSendReceive; administrivia.
parent d78b458e
...@@ -11,6 +11,7 @@ SYMBOLFILE = $(MODULE).tmp.o ...@@ -11,6 +11,7 @@ SYMBOLFILE = $(MODULE).tmp.o
C_SRCS = \ C_SRCS = \
rpc_binding.c \ rpc_binding.c \
rpc_message.c \
rpcrt4_main.c rpcrt4_main.c
SUBDIRS = tests SUBDIRS = tests
......
/*
* RPC definitions
*
* Copyright 2001-2002 Ove Kven, 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 */
/*
* RPC messages
*
* Copyright 2001-2002 Ove Kven, 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 <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;
}
...@@ -435,10 +435,10 @@ init RPCRT4_LibMain ...@@ -435,10 +435,10 @@ init RPCRT4_LibMain
@ stub I_RpcConnectionSetSockBuffSize @ stub I_RpcConnectionSetSockBuffSize
@ stub I_RpcDeleteMutex @ stub I_RpcDeleteMutex
@ stub I_RpcFree @ stub I_RpcFree
@ stub I_RpcFreeBuffer @ stdcall I_RpcFreeBuffer(ptr) I_RpcFreeBuffer
@ stub I_RpcFreePipeBuffer @ stub I_RpcFreePipeBuffer
@ stub I_RpcGetAssociationContext @ stub I_RpcGetAssociationContext
@ stub I_RpcGetBuffer @ stdcall I_RpcGetBuffer(ptr) I_RpcGetBuffer
@ stub I_RpcGetBufferWithObject @ stub I_RpcGetBufferWithObject
@ stub I_RpcGetCurrentCallHandle @ stub I_RpcGetCurrentCallHandle
@ stub I_RpcGetExtendedError @ stub I_RpcGetExtendedError
...@@ -458,10 +458,10 @@ init RPCRT4_LibMain ...@@ -458,10 +458,10 @@ init RPCRT4_LibMain
@ stub I_RpcParseSecurity @ stub I_RpcParseSecurity
@ stub I_RpcPauseExecution @ stub I_RpcPauseExecution
@ stub I_RpcReallocPipeBuffer @ stub I_RpcReallocPipeBuffer
@ stub I_RpcReceive @ stdcall I_RpcReceive(ptr) I_RpcReceive
@ stub I_RpcRequestMutex @ stub I_RpcRequestMutex
@ stub I_RpcSend @ stdcall I_RpcSend(ptr) I_RpcSend
@ stub I_RpcSendReceive @ stdcall I_RpcSendReceive(ptr) I_RpcSendReceive
@ stub I_RpcServerAllocateIpPort @ stub I_RpcServerAllocateIpPort
@ stub I_RpcServerInqAddressChangeFn @ stub I_RpcServerInqAddressChangeFn
@ stub I_RpcServerInqTransportType @ stub I_RpcServerInqTransportType
......
...@@ -128,49 +128,45 @@ RPC_STATUS WINAPI RpcStringFreeW(LPWSTR* String) ...@@ -128,49 +128,45 @@ RPC_STATUS WINAPI RpcStringFreeW(LPWSTR* String)
} }
/************************************************************************* /*************************************************************************
* UuidEqual [RPCRT4.@] * UuidCompare [RPCRT4.@]
*
* (an educated-guess implementation)
* *
* PARAMS * PARAMS
* UUID *Uuid1 [I] Uuid to compare * UUID *Uuid1 [I] Uuid to compare
* UUID *Uuid2 [I] Uuid to compare * UUID *Uuid2 [I] Uuid to compare
* RPC_STATUS *Status [O] returns RPC_S_OK * RPC_STATUS *Status [O] returns RPC_S_OK
* *
* RETURNS * 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)); TRACE("(%s,%s)\n", debugstr_guid(Uuid1), debugstr_guid(Uuid2));
*Status = RPC_S_OK; *Status = RPC_S_OK;
if (!Uuid1) Uuid1 = &uuid_nil; if (!Uuid1) Uuid1 = &uuid_nil;
if (!Uuid2) Uuid2 = &uuid_nil; if (!Uuid2) Uuid2 = &uuid_nil;
if (Uuid1 == Uuid2) return TRUE; if (Uuid1 == Uuid2) return 0;
return !memcmp(Uuid1, Uuid2, sizeof(UUID)); return memcmp(Uuid1, Uuid2, sizeof(UUID));
} }
/************************************************************************* /*************************************************************************
* UuidCompare [RPCRT4.@] * UuidEqual [RPCRT4.@]
*
* (an educated-guess implementation)
* *
* PARAMS * PARAMS
* UUID *Uuid1 [I] Uuid to compare * UUID *Uuid1 [I] Uuid to compare
* UUID *Uuid2 [I] Uuid to compare * UUID *Uuid2 [I] Uuid to compare
* RPC_STATUS *Status [O] returns RPC_S_OK * RPC_STATUS *Status [O] returns RPC_S_OK
* *
* RETURNS * RETURNS
* -1 if Uuid1 is less than Uuid2 * TRUE/FALSE
* 0 if Uuid1 and Uuid2 are equal
* 1 if Uuid1 is greater than Uuid2
*/ */
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)); TRACE("(%s,%s)\n", debugstr_guid(Uuid1), debugstr_guid(Uuid2));
*Status = RPC_S_OK; return !UuidCompare(Uuid1, Uuid2, Status);
if (!Uuid1) Uuid1 = &uuid_nil;
if (!Uuid2) Uuid2 = &uuid_nil;
if (Uuid1 == Uuid2) return 0;
return memcmp(Uuid1, Uuid2, sizeof(UUID));
} }
/************************************************************************* /*************************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment