Rob Shearman : rpcrt4: Store allocated memory in a singly-linked list to keep track of what we should and shouldn 't free in NdrFree.

Alexandre Julliard julliard at winehq.org
Wed Dec 12 09:29:23 CST 2007


Module: wine
Branch: master
Commit: 9c8c74f388631be71c3d1c6ad52cdcbc702272b7
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=9c8c74f388631be71c3d1c6ad52cdcbc702272b7

Author: Rob Shearman <rob at codeweavers.com>
Date:   Wed Dec 12 14:48:41 2007 +0000

rpcrt4: Store allocated memory in a singly-linked list to keep track of what we should and shouldn't free in NdrFree.

---

 dlls/rpcrt4/ndr_marshall.c       |   65 ++++++++++++++++++++++++++++++++++++--
 dlls/rpcrt4/tests/ndr_marshall.c |    2 -
 2 files changed, 62 insertions(+), 5 deletions(-)

diff --git a/dlls/rpcrt4/ndr_marshall.c b/dlls/rpcrt4/ndr_marshall.c
index 66833df..0fd2456 100644
--- a/dlls/rpcrt4/ndr_marshall.c
+++ b/dlls/rpcrt4/ndr_marshall.c
@@ -331,15 +331,74 @@ const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
   NdrRangeFree
 };
 
+typedef struct _NDR_MEMORY_LIST
+{
+    ULONG magic;
+    ULONG size;
+    ULONG reserved;
+    struct _NDR_MEMORY_LIST *next;
+} NDR_MEMORY_LIST;
+
+#define MEML_MAGIC  ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
+
 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
 {
-  /* hmm, this is probably supposed to do more? */
-  return pStubMsg->pfnAllocate(len);
+    size_t aligned_len;
+    size_t adjusted_len;
+    void *p;
+    NDR_MEMORY_LIST *mem_list;
+
+    aligned_len = ALIGNED_LENGTH(len, 8);
+    adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
+    /* check for overflow */
+    if (adjusted_len < len)
+    {
+        ERR("overflow of adjusted_len %d, len %d\n", adjusted_len, len);
+        RpcRaiseException(RPC_X_BAD_STUB_DATA);
+    }
+
+    p = pStubMsg->pfnAllocate(adjusted_len);
+    if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
+
+    mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
+    mem_list->magic = MEML_MAGIC;
+    mem_list->size = aligned_len;
+    mem_list->reserved = 0;
+    mem_list->next = pStubMsg->pMemoryList;
+    pStubMsg->pMemoryList = mem_list;
+
+    TRACE("-- %p\n", p);
+    return p;
 }
 
 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
 {
-  pStubMsg->pfnFree(Pointer);
+    NDR_MEMORY_LIST *mem_list, *prev_mem_list;
+
+    TRACE("(%p, %p)\n", pStubMsg, Pointer);
+
+    for (prev_mem_list = NULL, mem_list = pStubMsg->pMemoryList;
+       mem_list;
+       prev_mem_list = mem_list, mem_list = mem_list->next)
+    {
+      const unsigned char *base_pointer = (unsigned char *)mem_list - mem_list->size;
+      if (base_pointer == Pointer)
+      {
+          if (mem_list->magic != MEML_MAGIC)
+          {
+              ERR("memory linked list corrupted, magic changed to 0x%08x\n", mem_list->magic);
+              break;
+          }
+
+          /* fixup next pointers */
+          if (prev_mem_list)
+              prev_mem_list->next = mem_list->next;
+          else
+              pStubMsg->pMemoryList = mem_list->next;
+          pStubMsg->pfnFree(Pointer);
+          break;
+      }
+    }
 }
 
 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
diff --git a/dlls/rpcrt4/tests/ndr_marshall.c b/dlls/rpcrt4/tests/ndr_marshall.c
index 5389fcc..42929d9 100644
--- a/dlls/rpcrt4/tests/ndr_marshall.c
+++ b/dlls/rpcrt4/tests/ndr_marshall.c
@@ -975,9 +975,7 @@ static void test_ndr_allocate(void)
     p1 = NdrAllocate(&StubMsg, 10);
     p2 = NdrAllocate(&StubMsg, 24);
     ok(my_alloc_called == 2, "alloc called %d\n", my_alloc_called);
-todo_wine {
     ok(StubMsg.pMemoryList != NULL, "StubMsg.pMemoryList NULL\n");
- }
     if(StubMsg.pMemoryList)
     {
         mem_list_v2 = StubMsg.pMemoryList;




More information about the wine-cvs mailing list