Rob Shearman : rpcrt4:
The allocation hint in request and response packets is just that - a
hint.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Oct 27 05:49:21 CDT 2006
Module: wine
Branch: master
Commit: 709b536f0c35e6d3d6eb12eb1cc3c53af0686307
URL: http://source.winehq.org/git/wine.git/?a=commit;h=709b536f0c35e6d3d6eb12eb1cc3c53af0686307
Author: Rob Shearman <rob at codeweavers.com>
Date: Thu Oct 26 23:16:25 2006 +0100
rpcrt4: The allocation hint in request and response packets is just that - a hint.
It is not an error if the stub data exceeds this size, so reallocate the
buffer with the newly calculated size and continue.
---
dlls/rpcrt4/rpc_message.c | 35 +++++++++++++++++++++++++++--------
1 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/dlls/rpcrt4/rpc_message.c b/dlls/rpcrt4/rpc_message.c
index 6d434c0..80fbcc0 100644
--- a/dlls/rpcrt4/rpc_message.c
+++ b/dlls/rpcrt4/rpc_message.c
@@ -50,6 +50,8 @@ #define AUTH_ALIGNMENT 16
#define ROUND_UP_AMOUNT(value, alignment) \
(((alignment) - (((value) % (alignment)))) % (alignment))
+static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg);
+
static DWORD RPCRT4_GetHeaderSize(RpcPktHdr *Header)
{
static const DWORD header_sizes[] = {
@@ -476,7 +478,6 @@ RPC_STATUS RPCRT4_Receive(RpcConnection
unsigned long data_length;
unsigned long buffer_length;
unsigned long auth_length;
- unsigned char *buffer_ptr;
unsigned char *auth_data = NULL;
RpcPktCommonHdr common_hdr;
@@ -545,7 +546,6 @@ RPC_STATUS RPCRT4_Receive(RpcConnection
}
}
buffer_length = 0;
- buffer_ptr = pMsg->Buffer;
while (TRUE)
{
unsigned int header_auth_len = RPC_AUTH_VERIFIER_LEN(&(*Header)->common);
@@ -567,16 +567,24 @@ RPC_STATUS RPCRT4_Receive(RpcConnection
goto fail;
}
- data_length = (*Header)->common.frag_len - hdr_length - header_auth_len;
- if (((*Header)->common.flags & RPC_FLG_FIRST) != first_flag ||
- data_length + buffer_length > pMsg->BufferLength) {
- TRACE("invalid packet flags or buffer length\n");
+ if (((*Header)->common.flags & RPC_FLG_FIRST) != first_flag) {
+ TRACE("invalid packet flags\n");
status = RPC_S_PROTOCOL_ERROR;
goto fail;
}
+ data_length = (*Header)->common.frag_len - hdr_length - header_auth_len;
+ if (data_length + buffer_length > pMsg->BufferLength) {
+ TRACE("allocation hint exceeded, new buffer length = %ld\n",
+ data_length + buffer_length);
+ pMsg->BufferLength = data_length + buffer_length;
+ status = I_RpcReAllocateBuffer(pMsg);
+ if (status != RPC_S_OK) goto fail;
+ }
+
if (data_length == 0) dwRead = 0; else
- dwRead = rpcrt4_conn_read(Connection, buffer_ptr, data_length);
+ dwRead = rpcrt4_conn_read(Connection,
+ (unsigned char *)pMsg->Buffer + buffer_length, data_length);
if (dwRead != data_length) {
WARN("bad data length, %ld/%ld\n", dwRead, data_length);
status = RPC_S_PROTOCOL_ERROR;
@@ -610,7 +618,6 @@ RPC_STATUS RPCRT4_Receive(RpcConnection
goto fail;
}
- buffer_ptr += data_length;
first_flag = 0;
} else {
break;
@@ -655,6 +662,18 @@ RPC_STATUS WINAPI I_RpcGetBuffer(PRPC_ME
}
/***********************************************************************
+ * I_RpcReAllocateBuffer (internal)
+ */
+static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg)
+{
+ TRACE("(%p): BufferLength=%d\n", pMsg, pMsg->BufferLength);
+ pMsg->Buffer = HeapReAlloc(GetProcessHeap(), 0, pMsg->Buffer, pMsg->BufferLength);
+
+ TRACE("Buffer=%p\n", pMsg->Buffer);
+ return pMsg->Buffer ? RPC_S_OK : RPC_S_OUT_OF_RESOURCES;
+}
+
+/***********************************************************************
* I_RpcFreeBuffer [RPCRT4.@]
*/
RPC_STATUS WINAPI I_RpcFreeBuffer(PRPC_MESSAGE pMsg)
More information about the wine-cvs
mailing list