sync rpcrt4_new to Wine 0.9.44

svn path=/trunk/; revision=28871
This commit is contained in:
Ged Murphy 2007-09-05 10:21:30 +00:00
parent 0e970f97eb
commit 05e11ee73f
7 changed files with 203 additions and 69 deletions

View file

@ -21,7 +21,6 @@
* TODO:
* - Non-conformant strings
* - String structs
* - Encapsulated unions
* - Byte count pointers
* - transmit_as/represent as
* - Multi-dimensional arrays
@ -351,6 +350,8 @@ static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
{
ALIGN_POINTER(pStubMsg->Buffer, 4);
if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
RpcRaiseException(RPC_X_BAD_STUB_DATA);
pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
pStubMsg->Buffer += 4;
TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
@ -370,6 +371,8 @@ static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_S
}
ALIGN_POINTER(pStubMsg->Buffer, 4);
if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
RpcRaiseException(RPC_X_BAD_STUB_DATA);
pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
pStubMsg->Buffer += 4;
TRACE("offset is %d\n", pStubMsg->Offset);
@ -571,6 +574,24 @@ static inline ULONG safe_multiply(ULONG a, ULONG b)
return ret;
}
static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
{
if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
(pStubMsg->Buffer + size > pStubMsg->BufferEnd))
RpcRaiseException(RPC_X_BAD_STUB_DATA);
pStubMsg->Buffer += size;
}
/* copies data from the buffer, checking that there is enough data in the buffer
* to do so */
static inline void safe_buffer_copy(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
{
if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
(pStubMsg->Buffer + size > pStubMsg->BufferEnd))
RpcRaiseException(RPC_X_BAD_STUB_DATA);
memcpy(p, pStubMsg->Buffer, size);
pStubMsg->Buffer += size;
}
/*
* NdrConformantString:
@ -735,6 +756,17 @@ unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
RpcRaiseException(RPC_S_INVALID_BOUND);
return NULL;
}
/* verify the buffer is safe to access */
if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
(pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
{
ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
pStubMsg->BufferEnd, pStubMsg->Buffer);
RpcRaiseException(RPC_X_BAD_STUB_DATA);
return NULL;
}
for (i = bufsize - esize; i < bufsize; i++)
if (pStubMsg->Buffer[i] != 0)
{
@ -747,9 +779,7 @@ unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
if (fMustAlloc || !*ppMemory)
*ppMemory = NdrAllocate(pStubMsg, memsize);
memcpy(*ppMemory, pStubMsg->Buffer, bufsize);
pStubMsg->Buffer += bufsize;
safe_buffer_copy(pStubMsg, *ppMemory, bufsize);
if (*pFormat == RPC_FC_C_CSTRING) {
TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
@ -1539,7 +1569,7 @@ unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
{
ALIGN_POINTER(pStubMsg->Buffer, 4);
Buffer = pStubMsg->Buffer;
pStubMsg->Buffer += 4;
safe_buffer_increment(pStubMsg, 4);
}
else
Buffer = pStubMsg->Buffer;
@ -1718,7 +1748,7 @@ void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
}
static unsigned long EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg,
PFORMAT_STRING pFormat)
{
switch (*pFormat) {
@ -1894,31 +1924,27 @@ static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
case RPC_FC_CHAR:
case RPC_FC_SMALL:
case RPC_FC_USMALL:
memcpy(pMemory, pStubMsg->Buffer, 1);
safe_buffer_copy(pStubMsg, pMemory, 1);
TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
pStubMsg->Buffer += 1;
pMemory += 1;
break;
case RPC_FC_WCHAR:
case RPC_FC_SHORT:
case RPC_FC_USHORT:
memcpy(pMemory, pStubMsg->Buffer, 2);
safe_buffer_copy(pStubMsg, pMemory, 2);
TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
pStubMsg->Buffer += 2;
pMemory += 2;
break;
case RPC_FC_LONG:
case RPC_FC_ULONG:
case RPC_FC_ENUM32:
memcpy(pMemory, pStubMsg->Buffer, 4);
safe_buffer_copy(pStubMsg, pMemory, 4);
TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
pStubMsg->Buffer += 4;
pMemory += 4;
break;
case RPC_FC_HYPER:
memcpy(pMemory, pStubMsg->Buffer, 8);
safe_buffer_copy(pStubMsg, pMemory, 8);
TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
pStubMsg->Buffer += 8;
pMemory += 8;
break;
case RPC_FC_POINTER:
@ -2547,10 +2573,8 @@ unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
ALIGN_POINTER(pStubMsg->Buffer, alignment);
memcpy(*ppMemory, pStubMsg->Buffer, size);
pStubMsg->BufferMark = pStubMsg->Buffer;
pStubMsg->Buffer += size;
safe_buffer_copy(pStubMsg, *ppMemory, size);
EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
@ -2697,8 +2721,7 @@ unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pS
if (!*ppMemory || fMustAlloc)
*ppMemory = NdrAllocate(pStubMsg, memsize);
memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
pStubMsg->Buffer += bufsize;
safe_buffer_copy(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize);
EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
@ -3086,7 +3109,7 @@ void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
}
static ULONG UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
static ULONG UserMarshalFlags(const MIDL_STUB_MESSAGE *pStubMsg)
{
return MAKELONG(pStubMsg->dwDestContext,
pStubMsg->RpcMsg->DataRepresentation);
@ -3436,8 +3459,7 @@ unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMs
/* now copy the data */
pStubMsg->BufferMark = pStubMsg->Buffer;
memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size + bufsize);
pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
safe_buffer_copy(pStubMsg, *ppMemory, pCStructFormat->memory_size + bufsize);
if (pCStructFormat->type == RPC_FC_CPSTRUCT)
EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
@ -3659,8 +3681,7 @@ unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE
/* copy the constant data */
pStubMsg->BufferMark = pStubMsg->Buffer;
memcpy(*ppMemory, pStubMsg->Buffer, pCVStructFormat->memory_size);
pStubMsg->Buffer += pCVStructFormat->memory_size;
safe_buffer_copy(pStubMsg, *ppMemory, pCVStructFormat->memory_size);
pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
@ -3688,9 +3709,7 @@ unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE
}
/* copy the array data */
memcpy(*ppMemory + pCVStructFormat->memory_size, pStubMsg->Buffer,
bufsize);
pStubMsg->Buffer += bufsize;
safe_buffer_copy(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize);
if (cvarray_type == RPC_FC_C_CSTRING)
TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
@ -3999,9 +4018,8 @@ unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
if (fMustAlloc || !*ppMemory)
*ppMemory = NdrAllocate(pStubMsg, total_size);
memcpy(*ppMemory, pStubMsg->Buffer, total_size);
pStubMsg->BufferMark = pStubMsg->Buffer;
pStubMsg->Buffer += total_size;
safe_buffer_copy(pStubMsg, *ppMemory, total_size);
pFormat = EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
@ -4234,8 +4252,7 @@ unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
if (!*ppMemory || fMustAlloc)
*ppMemory = NdrAllocate(pStubMsg, size);
memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize);
pStubMsg->Buffer += bufsize;
safe_buffer_copy(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize);
EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
@ -4402,7 +4419,7 @@ void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
}
static ULONG get_discriminant(unsigned char fc, unsigned char *pMemory)
static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
{
switch (fc)
{
@ -4410,16 +4427,16 @@ static ULONG get_discriminant(unsigned char fc, unsigned char *pMemory)
case RPC_FC_CHAR:
case RPC_FC_SMALL:
case RPC_FC_USMALL:
return *(UCHAR *)pMemory;
return *(const UCHAR *)pMemory;
case RPC_FC_WCHAR:
case RPC_FC_SHORT:
case RPC_FC_USHORT:
case RPC_FC_ENUM16:
return *(USHORT *)pMemory;
return *(const USHORT *)pMemory;
case RPC_FC_LONG:
case RPC_FC_ULONG:
case RPC_FC_ENUM32:
return *(ULONG *)pMemory;
return *(const ULONG *)pMemory;
default:
FIXME("Unhandled base type: 0x%02x\n", fc);
return 0;
@ -4539,7 +4556,7 @@ static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
if((type & 0xff00) == 0x8000)
{
unsigned char basetype = LOBYTE(type);
return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, fMustAlloc);
return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
}
else
{
@ -4567,6 +4584,9 @@ static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
else
pStubMsg->Buffer += 4; /* for pointer ID */
if (saved_buffer + 4 > pStubMsg->BufferEnd)
RpcRaiseException(RPC_X_BAD_STUB_DATA);
PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, desc, fMustAlloc);
if (pointer_buffer_mark_set)
{
@ -4900,22 +4920,31 @@ static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
case RPC_FC_CHAR:
case RPC_FC_SMALL:
case RPC_FC_USMALL:
discriminant = *(UCHAR *)pStubMsg->Buffer;
pStubMsg->Buffer += sizeof(UCHAR);
{
UCHAR d;
safe_buffer_copy(pStubMsg, &d, sizeof(d));
discriminant = d;
break;
}
case RPC_FC_WCHAR:
case RPC_FC_SHORT:
case RPC_FC_USHORT:
{
USHORT d;
ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
discriminant = *(USHORT *)pStubMsg->Buffer;
pStubMsg->Buffer += sizeof(USHORT);
safe_buffer_copy(pStubMsg, &d, sizeof(d));
discriminant = d;
break;
}
case RPC_FC_LONG:
case RPC_FC_ULONG:
{
ULONG d;
ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
discriminant = *(ULONG *)pStubMsg->Buffer;
pStubMsg->Buffer += sizeof(ULONG);
safe_buffer_copy(pStubMsg, &d, sizeof(d));
discriminant = d;
break;
}
default:
FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
}
@ -5354,7 +5383,7 @@ static unsigned char *WINAPI NdrBaseTypeMarshall(
break;
case RPC_FC_ENUM16:
/* only 16-bits on the wire, so do a sanity check */
if (*(UINT *)pMemory > USHRT_MAX)
if (*(UINT *)pMemory > SHRT_MAX)
RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
*(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
@ -5655,6 +5684,9 @@ void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
ALIGN_POINTER(pStubMsg->Buffer, 4);
if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
RpcRaiseException(RPC_X_BAD_STUB_DATA);
NDRCContextUnmarshall(pContextHandle,
BindHandle,
pStubMsg->Buffer,
@ -5741,7 +5773,7 @@ static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
return che;
}
static struct context_handle_entry *context_entry_from_guid(LPGUID uuid)
static struct context_handle_entry *context_entry_from_guid(LPCGUID uuid)
{
struct context_handle_entry *che;
LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry)
@ -5791,7 +5823,7 @@ void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff)
static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
RPC_BINDING_HANDLE hBinding,
ndr_context_handle *chi)
const ndr_context_handle *chi)
{
struct context_handle_entry *che = NULL;

View file

@ -274,8 +274,8 @@ RPC_STATUS RPCRT4_DestroyBinding(RpcBinding* Binding)
}
RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection,
PRPC_SYNTAX_IDENTIFIER TransferSyntax,
PRPC_SYNTAX_IDENTIFIER InterfaceId)
const RPC_SYNTAX_IDENTIFIER *TransferSyntax,
const RPC_SYNTAX_IDENTIFIER *InterfaceId)
{
TRACE("(Binding == ^%p)\n", Binding);

View file

@ -161,13 +161,14 @@ RPC_STATUS RPCRT4_SetBindingObject(RpcBinding* Binding, const UUID* ObjectUuid);
RPC_STATUS RPCRT4_MakeBinding(RpcBinding** Binding, RpcConnection* Connection);
RPC_STATUS RPCRT4_ExportBinding(RpcBinding** Binding, RpcBinding* OldBinding);
RPC_STATUS RPCRT4_DestroyBinding(RpcBinding* Binding);
RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection, PRPC_SYNTAX_IDENTIFIER TransferSyntax, PRPC_SYNTAX_IDENTIFIER InterfaceId);
RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection,
const RPC_SYNTAX_IDENTIFIER *TransferSyntax, const RPC_SYNTAX_IDENTIFIER *InterfaceId);
RPC_STATUS RPCRT4_CloseBinding(RpcBinding* Binding, RpcConnection* Connection);
BOOL RPCRT4_RPCSSOnDemandCall(PRPCSS_NP_MESSAGE msg, char *vardata_payload, PRPCSS_NP_REPLY reply);
HANDLE RPCRT4_GetMasterMutex(void);
HANDLE RPCRT4_RpcssNPConnect(void);
static inline const char *rpcrt4_conn_get_name(RpcConnection *Connection)
static inline const char *rpcrt4_conn_get_name(const RpcConnection *Connection)
{
return Connection->ops->name;
}

View file

@ -177,9 +177,25 @@ typedef struct
#define PKT_CO_CANCEL 18
#define PKT_ORPHANED 19
#define RESULT_ACCEPT 0
#define RESULT_ACCEPT 0
#define RESULT_USER_REJECTION 1
#define RESULT_PROVIDER_REJECTION 2
#define NO_REASON 0
#define REASON_NONE 0
#define REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED 1
#define REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED 2
#define REASON_LOCAL_LIMIT_EXCEEDED 3
#define REJECT_REASON_NOT_SPECIFIED 0
#define REJECT_TEMPORARY_CONGESTION 1
#define REJECT_LOCAL_LIMIT_EXCEEDED 2
#define REJECT_CALLED_PADDR_UNKNOWN 3 /* not used */
#define REJECT_PROTOCOL_VERSION_NOT_SUPPORTED 4
#define REJECT_DEFAULT_CONTEXT_NOT_SUPPORTED 5 /* not used */
#define REJECT_USER_DATA_NOT_READABLE 6 /* not used */
#define REJECT_NO_PSAP_AVAILABLE 7 /* not used */
#define REJECT_UNKNOWN_AUTHN_SERVICE 8
#define REJECT_INVALID_CHECKSUM 9
#define NCADG_IP_UDP 0x08
#define NCACN_IP_TCP 0x07

View file

@ -230,6 +230,7 @@ RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation,
RPCRT4_BuildCommonHeader(header, PKT_BIND_NACK, DataRepresentation);
header->common.frag_len = sizeof(header->bind_nack);
header->bind_nack.reject_reason = REJECT_REASON_NOT_SPECIFIED;
header->bind_nack.protocols_count = 1;
header->bind_nack.protocols[0].rpc_ver = RpcVersion;
header->bind_nack.protocols[0].rpc_ver_minor = RpcVersionMinor;
@ -301,6 +302,12 @@ NCA_STATUS RPC2NCA_STATUS(RPC_STATUS status)
case RPC_S_INVALID_BOUND: return NCA_S_FAULT_INVALID_BOUND;
case RPC_S_PROCNUM_OUT_OF_RANGE: return NCA_S_OP_RNG_ERROR;
case RPC_X_SS_HANDLES_MISMATCH: return NCA_S_FAULT_CONTEXT_MISMATCH;
case RPC_S_CALL_CANCELLED: return NCA_S_FAULT_CANCEL;
case RPC_S_COMM_FAILURE: return NCA_S_COMM_FAILURE;
case RPC_X_WRONG_PIPE_ORDER: return NCA_S_FAULT_PIPE_ORDER;
case RPC_X_PIPE_CLOSED: return NCA_S_FAULT_PIPE_CLOSED;
case RPC_X_PIPE_DISCIPLINE_ERROR: return NCA_S_FAULT_PIPE_DISCIPLINE;
case RPC_X_PIPE_EMPTY: return NCA_S_FAULT_PIPE_EMPTY;
case STATUS_FLOAT_DIVIDE_BY_ZERO: return NCA_S_FAULT_FP_DIV_ZERO;
case STATUS_FLOAT_INVALID_OPERATION: return NCA_S_FAULT_FP_ERROR;
case STATUS_FLOAT_OVERFLOW: return NCA_S_FAULT_FP_OVERFLOW;
@ -433,7 +440,7 @@ static RPC_STATUS RPCRT4_SecurePacket(RpcConnection *Connection,
*/
static RPC_STATUS RPCRT4_SendAuth(RpcConnection *Connection, RpcPktHdr *Header,
void *Buffer, unsigned int BufferLength,
void *Auth, unsigned int AuthLength)
const void *Auth, unsigned int AuthLength)
{
PUCHAR buffer_pos;
DWORD hdr_size;
@ -1013,6 +1020,7 @@ static inline BOOL is_hard_error(RPC_STATUS status)
case RPC_S_PROTOCOL_ERROR:
case RPC_S_CALL_FAILED:
case RPC_S_CALL_FAILED_DNE:
case RPC_S_SEC_PKG_ERROR:
return TRUE;
default:
return FALSE;

View file

@ -119,7 +119,7 @@ static inline UUID *LookupObjType(UUID *ObjUuid)
}
static RpcServerInterface* RPCRT4_find_interface(UUID* object,
RPC_SYNTAX_IDENTIFIER* if_id,
const RPC_SYNTAX_IDENTIFIER* if_id,
BOOL check_object)
{
UUID* MgrType = NULL;
@ -198,7 +198,7 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA
RPC_MAX_PACKET_SIZE,
RPC_MAX_PACKET_SIZE,
conn->Endpoint,
RESULT_ACCEPT, NO_REASON,
RESULT_ACCEPT, REASON_NONE,
&sif->If->TransferSyntax);
/* save the interface for later use */

View file

@ -1211,7 +1211,7 @@ static int rpcrt4_protseq_sock_wait_for_new_connection(RpcServerProtseq *protseq
if (!poll_info)
return -1;
ret = poll(poll_info, count, -1);
if (ret < 0)
{
@ -1484,7 +1484,9 @@ ULONG RpcAssoc_Release(RpcAssoc *assoc)
return refs;
}
static RPC_STATUS RpcAssoc_BindConnection(RpcAssoc *assoc, RpcConnection *conn,
#define ROUND_UP(value, alignment) (((value) + ((alignment) - 1)) & ~((alignment)-1))
static RPC_STATUS RpcAssoc_BindConnection(const RpcAssoc *assoc, RpcConnection *conn,
const RPC_SYNTAX_IDENTIFIER *InterfaceId,
const RPC_SYNTAX_IDENTIFIER *TransferSyntax)
{
@ -1512,23 +1514,98 @@ static RPC_STATUS RpcAssoc_BindConnection(RpcAssoc *assoc, RpcConnection *conn,
return status;
}
if (response_hdr->common.ptype != PKT_BIND_ACK)
switch (response_hdr->common.ptype)
{
ERR("failed to bind for interface %s, %d.%d\n",
debugstr_guid(&InterfaceId->SyntaxGUID),
InterfaceId->SyntaxVersion.MajorVersion,
InterfaceId->SyntaxVersion.MinorVersion);
RPCRT4_FreeHeader(response_hdr);
return RPC_S_PROTOCOL_ERROR;
case PKT_BIND_ACK:
{
RpcAddressString *server_address = msg.Buffer;
if ((msg.BufferLength >= FIELD_OFFSET(RpcAddressString, string[0])) ||
(msg.BufferLength >= ROUND_UP(FIELD_OFFSET(RpcAddressString, string[server_address->length]), 4)))
{
unsigned short remaining = msg.BufferLength -
ROUND_UP(FIELD_OFFSET(RpcAddressString, string[server_address->length]), 4);
RpcResults *results = (RpcResults*)((ULONG_PTR)server_address +
ROUND_UP(FIELD_OFFSET(RpcAddressString, string[server_address->length]), 4));
if ((results->num_results == 1) && (remaining >= sizeof(*results)))
{
switch (results->results[0].result)
{
case RESULT_ACCEPT:
conn->assoc_group_id = response_hdr->bind_ack.assoc_gid;
conn->MaxTransmissionSize = response_hdr->bind_ack.max_tsize;
conn->ActiveInterface = *InterfaceId;
break;
case RESULT_PROVIDER_REJECTION:
switch (results->results[0].reason)
{
case REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED:
ERR("syntax %s, %d.%d not supported\n",
debugstr_guid(&InterfaceId->SyntaxGUID),
InterfaceId->SyntaxVersion.MajorVersion,
InterfaceId->SyntaxVersion.MinorVersion);
status = RPC_S_UNKNOWN_IF;
break;
case REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED:
ERR("transfer syntax not supported\n");
status = RPC_S_SERVER_UNAVAILABLE;
break;
case REASON_NONE:
default:
status = RPC_S_CALL_FAILED_DNE;
}
break;
case RESULT_USER_REJECTION:
default:
ERR("rejection result %d\n", results->results[0].result);
status = RPC_S_CALL_FAILED_DNE;
}
}
else
{
ERR("incorrect results size\n");
status = RPC_S_CALL_FAILED_DNE;
}
}
else
{
ERR("bind ack packet too small (%d)\n", msg.BufferLength);
status = RPC_S_PROTOCOL_ERROR;
}
break;
}
case PKT_BIND_NACK:
switch (response_hdr->bind_nack.reject_reason)
{
case REJECT_LOCAL_LIMIT_EXCEEDED:
case REJECT_TEMPORARY_CONGESTION:
ERR("server too busy\n");
status = RPC_S_SERVER_TOO_BUSY;
break;
case REJECT_PROTOCOL_VERSION_NOT_SUPPORTED:
ERR("protocol version not supported\n");
status = RPC_S_PROTOCOL_ERROR;
break;
case REJECT_UNKNOWN_AUTHN_SERVICE:
ERR("unknown authentication service\n");
status = RPC_S_UNKNOWN_AUTHN_SERVICE;
break;
case REJECT_INVALID_CHECKSUM:
ERR("invalid checksum\n");
status = ERROR_ACCESS_DENIED;
break;
default:
ERR("rejected bind for reason %d\n", response_hdr->bind_nack.reject_reason);
status = RPC_S_CALL_FAILED_DNE;
}
break;
default:
ERR("wrong packet type received %d\n", response_hdr->common.ptype);
status = RPC_S_PROTOCOL_ERROR;
break;
}
/* FIXME: do more checks? */
conn->assoc_group_id = response_hdr->bind_ack.assoc_gid;
conn->MaxTransmissionSize = response_hdr->bind_ack.max_tsize;
conn->ActiveInterface = *InterfaceId;
RPCRT4_FreeHeader(response_hdr);
return RPC_S_OK;
return status;
}
static RpcConnection *RpcAssoc_GetIdleConnection(RpcAssoc *assoc,