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: * TODO:
* - Non-conformant strings * - Non-conformant strings
* - String structs * - String structs
* - Encapsulated unions
* - Byte count pointers * - Byte count pointers
* - transmit_as/represent as * - transmit_as/represent as
* - Multi-dimensional arrays * - 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) static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
{ {
ALIGN_POINTER(pStubMsg->Buffer, 4); 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->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
pStubMsg->Buffer += 4; pStubMsg->Buffer += 4;
TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount); 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); 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->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
pStubMsg->Buffer += 4; pStubMsg->Buffer += 4;
TRACE("offset is %d\n", pStubMsg->Offset); TRACE("offset is %d\n", pStubMsg->Offset);
@ -571,6 +574,24 @@ static inline ULONG safe_multiply(ULONG a, ULONG b)
return ret; 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: * NdrConformantString:
@ -735,6 +756,17 @@ unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
RpcRaiseException(RPC_S_INVALID_BOUND); RpcRaiseException(RPC_S_INVALID_BOUND);
return NULL; 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++) for (i = bufsize - esize; i < bufsize; i++)
if (pStubMsg->Buffer[i] != 0) if (pStubMsg->Buffer[i] != 0)
{ {
@ -747,9 +779,7 @@ unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
if (fMustAlloc || !*ppMemory) if (fMustAlloc || !*ppMemory)
*ppMemory = NdrAllocate(pStubMsg, memsize); *ppMemory = NdrAllocate(pStubMsg, memsize);
memcpy(*ppMemory, pStubMsg->Buffer, bufsize); safe_buffer_copy(pStubMsg, *ppMemory, bufsize);
pStubMsg->Buffer += bufsize;
if (*pFormat == RPC_FC_C_CSTRING) { if (*pFormat == RPC_FC_C_CSTRING) {
TRACE("string=%s\n", debugstr_a((char*)*ppMemory)); 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); ALIGN_POINTER(pStubMsg->Buffer, 4);
Buffer = pStubMsg->Buffer; Buffer = pStubMsg->Buffer;
pStubMsg->Buffer += 4; safe_buffer_increment(pStubMsg, 4);
} }
else else
Buffer = pStubMsg->Buffer; 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) PFORMAT_STRING pFormat)
{ {
switch (*pFormat) { switch (*pFormat) {
@ -1894,31 +1924,27 @@ static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
case RPC_FC_CHAR: case RPC_FC_CHAR:
case RPC_FC_SMALL: case RPC_FC_SMALL:
case RPC_FC_USMALL: case RPC_FC_USMALL:
memcpy(pMemory, pStubMsg->Buffer, 1); safe_buffer_copy(pStubMsg, pMemory, 1);
TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory); TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
pStubMsg->Buffer += 1;
pMemory += 1; pMemory += 1;
break; break;
case RPC_FC_WCHAR: case RPC_FC_WCHAR:
case RPC_FC_SHORT: case RPC_FC_SHORT:
case RPC_FC_USHORT: case RPC_FC_USHORT:
memcpy(pMemory, pStubMsg->Buffer, 2); safe_buffer_copy(pStubMsg, pMemory, 2);
TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory); TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
pStubMsg->Buffer += 2;
pMemory += 2; pMemory += 2;
break; break;
case RPC_FC_LONG: case RPC_FC_LONG:
case RPC_FC_ULONG: case RPC_FC_ULONG:
case RPC_FC_ENUM32: case RPC_FC_ENUM32:
memcpy(pMemory, pStubMsg->Buffer, 4); safe_buffer_copy(pStubMsg, pMemory, 4);
TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory); TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
pStubMsg->Buffer += 4;
pMemory += 4; pMemory += 4;
break; break;
case RPC_FC_HYPER: 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); TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
pStubMsg->Buffer += 8;
pMemory += 8; pMemory += 8;
break; break;
case RPC_FC_POINTER: case RPC_FC_POINTER:
@ -2547,10 +2573,8 @@ unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
ALIGN_POINTER(pStubMsg->Buffer, alignment); ALIGN_POINTER(pStubMsg->Buffer, alignment);
memcpy(*ppMemory, pStubMsg->Buffer, size);
pStubMsg->BufferMark = pStubMsg->Buffer; pStubMsg->BufferMark = pStubMsg->Buffer;
pStubMsg->Buffer += size; safe_buffer_copy(pStubMsg, *ppMemory, size);
EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc); EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
@ -2697,8 +2721,7 @@ unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pS
if (!*ppMemory || fMustAlloc) if (!*ppMemory || fMustAlloc)
*ppMemory = NdrAllocate(pStubMsg, memsize); *ppMemory = NdrAllocate(pStubMsg, memsize);
memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize); safe_buffer_copy(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize);
pStubMsg->Buffer += bufsize;
EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc); EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
@ -3086,7 +3109,7 @@ void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL); 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, return MAKELONG(pStubMsg->dwDestContext,
pStubMsg->RpcMsg->DataRepresentation); pStubMsg->RpcMsg->DataRepresentation);
@ -3436,8 +3459,7 @@ unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMs
/* now copy the data */ /* now copy the data */
pStubMsg->BufferMark = pStubMsg->Buffer; pStubMsg->BufferMark = pStubMsg->Buffer;
memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size + bufsize); safe_buffer_copy(pStubMsg, *ppMemory, pCStructFormat->memory_size + bufsize);
pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
if (pCStructFormat->type == RPC_FC_CPSTRUCT) if (pCStructFormat->type == RPC_FC_CPSTRUCT)
EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc); EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
@ -3659,8 +3681,7 @@ unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE
/* copy the constant data */ /* copy the constant data */
pStubMsg->BufferMark = pStubMsg->Buffer; pStubMsg->BufferMark = pStubMsg->Buffer;
memcpy(*ppMemory, pStubMsg->Buffer, pCVStructFormat->memory_size); safe_buffer_copy(pStubMsg, *ppMemory, pCVStructFormat->memory_size);
pStubMsg->Buffer += pCVStructFormat->memory_size;
pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount); pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
@ -3688,9 +3709,7 @@ unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE
} }
/* copy the array data */ /* copy the array data */
memcpy(*ppMemory + pCVStructFormat->memory_size, pStubMsg->Buffer, safe_buffer_copy(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize);
bufsize);
pStubMsg->Buffer += bufsize;
if (cvarray_type == RPC_FC_C_CSTRING) if (cvarray_type == RPC_FC_C_CSTRING)
TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size))); 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) if (fMustAlloc || !*ppMemory)
*ppMemory = NdrAllocate(pStubMsg, total_size); *ppMemory = NdrAllocate(pStubMsg, total_size);
memcpy(*ppMemory, pStubMsg->Buffer, total_size);
pStubMsg->BufferMark = pStubMsg->Buffer; pStubMsg->BufferMark = pStubMsg->Buffer;
pStubMsg->Buffer += total_size; safe_buffer_copy(pStubMsg, *ppMemory, total_size);
pFormat = EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc); pFormat = EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
@ -4234,8 +4252,7 @@ unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
if (!*ppMemory || fMustAlloc) if (!*ppMemory || fMustAlloc)
*ppMemory = NdrAllocate(pStubMsg, size); *ppMemory = NdrAllocate(pStubMsg, size);
memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, bufsize); safe_buffer_copy(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize);
pStubMsg->Buffer += bufsize;
EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc); EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
@ -4402,7 +4419,7 @@ void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
EmbeddedPointerFree(pStubMsg, pMemory, pFormat); 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) switch (fc)
{ {
@ -4410,16 +4427,16 @@ static ULONG get_discriminant(unsigned char fc, unsigned char *pMemory)
case RPC_FC_CHAR: case RPC_FC_CHAR:
case RPC_FC_SMALL: case RPC_FC_SMALL:
case RPC_FC_USMALL: case RPC_FC_USMALL:
return *(UCHAR *)pMemory; return *(const UCHAR *)pMemory;
case RPC_FC_WCHAR: case RPC_FC_WCHAR:
case RPC_FC_SHORT: case RPC_FC_SHORT:
case RPC_FC_USHORT: case RPC_FC_USHORT:
case RPC_FC_ENUM16: case RPC_FC_ENUM16:
return *(USHORT *)pMemory; return *(const USHORT *)pMemory;
case RPC_FC_LONG: case RPC_FC_LONG:
case RPC_FC_ULONG: case RPC_FC_ULONG:
case RPC_FC_ENUM32: case RPC_FC_ENUM32:
return *(ULONG *)pMemory; return *(const ULONG *)pMemory;
default: default:
FIXME("Unhandled base type: 0x%02x\n", fc); FIXME("Unhandled base type: 0x%02x\n", fc);
return 0; return 0;
@ -4539,7 +4556,7 @@ static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
if((type & 0xff00) == 0x8000) if((type & 0xff00) == 0x8000)
{ {
unsigned char basetype = LOBYTE(type); unsigned char basetype = LOBYTE(type);
return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, fMustAlloc); return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
} }
else else
{ {
@ -4567,6 +4584,9 @@ static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
else else
pStubMsg->Buffer += 4; /* for pointer ID */ 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); PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, desc, fMustAlloc);
if (pointer_buffer_mark_set) if (pointer_buffer_mark_set)
{ {
@ -4900,22 +4920,31 @@ static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
case RPC_FC_CHAR: case RPC_FC_CHAR:
case RPC_FC_SMALL: case RPC_FC_SMALL:
case RPC_FC_USMALL: case RPC_FC_USMALL:
discriminant = *(UCHAR *)pStubMsg->Buffer; {
pStubMsg->Buffer += sizeof(UCHAR); UCHAR d;
safe_buffer_copy(pStubMsg, &d, sizeof(d));
discriminant = d;
break; break;
}
case RPC_FC_WCHAR: case RPC_FC_WCHAR:
case RPC_FC_SHORT: case RPC_FC_SHORT:
case RPC_FC_USHORT: case RPC_FC_USHORT:
{
USHORT d;
ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT)); ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
discriminant = *(USHORT *)pStubMsg->Buffer; safe_buffer_copy(pStubMsg, &d, sizeof(d));
pStubMsg->Buffer += sizeof(USHORT); discriminant = d;
break; break;
}
case RPC_FC_LONG: case RPC_FC_LONG:
case RPC_FC_ULONG: case RPC_FC_ULONG:
{
ULONG d;
ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG)); ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
discriminant = *(ULONG *)pStubMsg->Buffer; safe_buffer_copy(pStubMsg, &d, sizeof(d));
pStubMsg->Buffer += sizeof(ULONG); discriminant = d;
break; break;
}
default: default:
FIXME("Unhandled base type: 0x%02x\n", **ppFormat); FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
} }
@ -5354,7 +5383,7 @@ static unsigned char *WINAPI NdrBaseTypeMarshall(
break; break;
case RPC_FC_ENUM16: case RPC_FC_ENUM16:
/* only 16-bits on the wire, so do a sanity check */ /* 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); RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT)); ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
*(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory; *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
@ -5655,6 +5684,9 @@ void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
ALIGN_POINTER(pStubMsg->Buffer, 4); ALIGN_POINTER(pStubMsg->Buffer, 4);
if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
RpcRaiseException(RPC_X_BAD_STUB_DATA);
NDRCContextUnmarshall(pContextHandle, NDRCContextUnmarshall(pContextHandle,
BindHandle, BindHandle,
pStubMsg->Buffer, pStubMsg->Buffer,
@ -5741,7 +5773,7 @@ static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext)
return che; 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; struct context_handle_entry *che;
LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry) 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, static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext,
RPC_BINDING_HANDLE hBinding, RPC_BINDING_HANDLE hBinding,
ndr_context_handle *chi) const ndr_context_handle *chi)
{ {
struct context_handle_entry *che = NULL; 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, RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection,
PRPC_SYNTAX_IDENTIFIER TransferSyntax, const RPC_SYNTAX_IDENTIFIER *TransferSyntax,
PRPC_SYNTAX_IDENTIFIER InterfaceId) const RPC_SYNTAX_IDENTIFIER *InterfaceId)
{ {
TRACE("(Binding == ^%p)\n", Binding); 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_MakeBinding(RpcBinding** Binding, RpcConnection* Connection);
RPC_STATUS RPCRT4_ExportBinding(RpcBinding** Binding, RpcBinding* OldBinding); RPC_STATUS RPCRT4_ExportBinding(RpcBinding** Binding, RpcBinding* OldBinding);
RPC_STATUS RPCRT4_DestroyBinding(RpcBinding* Binding); 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); RPC_STATUS RPCRT4_CloseBinding(RpcBinding* Binding, RpcConnection* Connection);
BOOL RPCRT4_RPCSSOnDemandCall(PRPCSS_NP_MESSAGE msg, char *vardata_payload, PRPCSS_NP_REPLY reply); BOOL RPCRT4_RPCSSOnDemandCall(PRPCSS_NP_MESSAGE msg, char *vardata_payload, PRPCSS_NP_REPLY reply);
HANDLE RPCRT4_GetMasterMutex(void); HANDLE RPCRT4_GetMasterMutex(void);
HANDLE RPCRT4_RpcssNPConnect(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; return Connection->ops->name;
} }

View file

@ -177,9 +177,25 @@ typedef struct
#define PKT_CO_CANCEL 18 #define PKT_CO_CANCEL 18
#define PKT_ORPHANED 19 #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 NCADG_IP_UDP 0x08
#define NCACN_IP_TCP 0x07 #define NCACN_IP_TCP 0x07

View file

@ -230,6 +230,7 @@ RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation,
RPCRT4_BuildCommonHeader(header, PKT_BIND_NACK, DataRepresentation); RPCRT4_BuildCommonHeader(header, PKT_BIND_NACK, DataRepresentation);
header->common.frag_len = sizeof(header->bind_nack); 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_count = 1;
header->bind_nack.protocols[0].rpc_ver = RpcVersion; header->bind_nack.protocols[0].rpc_ver = RpcVersion;
header->bind_nack.protocols[0].rpc_ver_minor = RpcVersionMinor; 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_INVALID_BOUND: return NCA_S_FAULT_INVALID_BOUND;
case RPC_S_PROCNUM_OUT_OF_RANGE: return NCA_S_OP_RNG_ERROR; 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_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_DIVIDE_BY_ZERO: return NCA_S_FAULT_FP_DIV_ZERO;
case STATUS_FLOAT_INVALID_OPERATION: return NCA_S_FAULT_FP_ERROR; case STATUS_FLOAT_INVALID_OPERATION: return NCA_S_FAULT_FP_ERROR;
case STATUS_FLOAT_OVERFLOW: return NCA_S_FAULT_FP_OVERFLOW; 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, static RPC_STATUS RPCRT4_SendAuth(RpcConnection *Connection, RpcPktHdr *Header,
void *Buffer, unsigned int BufferLength, void *Buffer, unsigned int BufferLength,
void *Auth, unsigned int AuthLength) const void *Auth, unsigned int AuthLength)
{ {
PUCHAR buffer_pos; PUCHAR buffer_pos;
DWORD hdr_size; DWORD hdr_size;
@ -1013,6 +1020,7 @@ static inline BOOL is_hard_error(RPC_STATUS status)
case RPC_S_PROTOCOL_ERROR: case RPC_S_PROTOCOL_ERROR:
case RPC_S_CALL_FAILED: case RPC_S_CALL_FAILED:
case RPC_S_CALL_FAILED_DNE: case RPC_S_CALL_FAILED_DNE:
case RPC_S_SEC_PKG_ERROR:
return TRUE; return TRUE;
default: default:
return FALSE; return FALSE;

View file

@ -119,7 +119,7 @@ static inline UUID *LookupObjType(UUID *ObjUuid)
} }
static RpcServerInterface* RPCRT4_find_interface(UUID* object, static RpcServerInterface* RPCRT4_find_interface(UUID* object,
RPC_SYNTAX_IDENTIFIER* if_id, const RPC_SYNTAX_IDENTIFIER* if_id,
BOOL check_object) BOOL check_object)
{ {
UUID* MgrType = NULL; 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,
RPC_MAX_PACKET_SIZE, RPC_MAX_PACKET_SIZE,
conn->Endpoint, conn->Endpoint,
RESULT_ACCEPT, NO_REASON, RESULT_ACCEPT, REASON_NONE,
&sif->If->TransferSyntax); &sif->If->TransferSyntax);
/* save the interface for later use */ /* save the interface for later use */

View file

@ -1484,7 +1484,9 @@ ULONG RpcAssoc_Release(RpcAssoc *assoc)
return refs; 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 *InterfaceId,
const RPC_SYNTAX_IDENTIFIER *TransferSyntax) const RPC_SYNTAX_IDENTIFIER *TransferSyntax)
{ {
@ -1512,23 +1514,98 @@ static RPC_STATUS RpcAssoc_BindConnection(RpcAssoc *assoc, RpcConnection *conn,
return status; 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", case PKT_BIND_ACK:
debugstr_guid(&InterfaceId->SyntaxGUID), {
InterfaceId->SyntaxVersion.MajorVersion, RpcAddressString *server_address = msg.Buffer;
InterfaceId->SyntaxVersion.MinorVersion); if ((msg.BufferLength >= FIELD_OFFSET(RpcAddressString, string[0])) ||
RPCRT4_FreeHeader(response_hdr); (msg.BufferLength >= ROUND_UP(FIELD_OFFSET(RpcAddressString, string[server_address->length]), 4)))
return RPC_S_PROTOCOL_ERROR; {
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); RPCRT4_FreeHeader(response_hdr);
return RPC_S_OK; return status;
} }
static RpcConnection *RpcAssoc_GetIdleConnection(RpcAssoc *assoc, static RpcConnection *RpcAssoc_GetIdleConnection(RpcAssoc *assoc,