PagedPool improvements: differenciate between hiredzone and loredzone, added double...
authorRoyce Mitchell III <royce3@ev1.net>
Sat, 11 Dec 2004 00:13:37 +0000 (00:13 +0000)
committerRoyce Mitchell III <royce3@ev1.net>
Sat, 11 Dec 2004 00:13:37 +0000 (00:13 +0000)
svn path=/trunk/; revision=12006

reactos/include/ddk/exfuncs.h
reactos/lib/rtl/heap.c
reactos/ntoskrnl/mm/pool.c
reactos/ntoskrnl/mm/ppool.c
reactos/ntoskrnl/ntoskrnl.def

index 962fe2e..4408434 100644 (file)
@@ -678,6 +678,16 @@ ExReleaseRundownProtectionEx (
     IN PEX_RUNDOWN_REF RunRef,
     IN ULONG Count
     );
+/* ReactOS Specific: begin */
+VOID STDCALL
+ExRosDumpPagedPoolByTag (
+    IN ULONG Tag
+    );
+ULONG STDCALL
+ExRosQueryPoolTag (
+    IN PVOID Block
+    );
+/* ReactOS Specific: end */
 VOID
 FASTCALL
 ExRundownCompleted (
index a9d7d4b..144f28c 100644 (file)
@@ -937,7 +937,30 @@ int HEAP_IsInsideHeap(
 }
 
 
-
+void DumpStackFrames ( PULONG Frame, ULONG FrameCount )
+{
+       ULONG i=0;
+
+       DbgPrint("Frames: ");
+       if ( !Frame )
+       {
+#if defined __GNUC__
+               __asm__("mov %%ebp, %%ebx" : "=b" (Frame) : );
+#elif defined(_MSC_VER)
+               __asm mov [Frame], ebp
+#endif
+               Frame = (PULONG)Frame[0]; // step out of DumpStackFrames
+       }
+       while ( Frame != 0 && (ULONG)Frame != 0xDEADBEEF && (ULONG)Frame != 0xcdcdcdcd && (ULONG)Frame != 0xcccccccc && i++ < FrameCount )
+       {
+               DbgPrint("<%X>", (PVOID)Frame[1]);
+               if (Frame[1] == 0xdeadbeef)
+                   break;
+               Frame = (PULONG)Frame[0];
+               DbgPrint(" ");
+       }
+       DbgPrint("\n");
+}
 
 /***********************************************************************
  *           HEAP_IsRealArena  [Internal]
@@ -985,11 +1008,13 @@ static BOOLEAN HEAP_IsRealArena(
          {
             DPRINT("Heap %p: block %p is not inside heap\n",
                    heap, block );
+                       DumpStackFrames(NULL,10);
          }
          else if (WARN_ON(heap))
          {
             DPRINT1("Heap %p: block %p is not inside heap\n",
                     heap, block );
+                       DumpStackFrames(NULL,10);
          }
          ret = FALSE;
       }
index 701fc3a..7542643 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pool.c,v 1.35 2004/10/01 20:51:29 arty Exp $
+/* $Id: pool.c,v 1.36 2004/12/11 00:13:37 royce Exp $
  * 
  * COPYRIGHT:    See COPYING in the top level directory
  * PROJECT:      ReactOS kernel
@@ -24,6 +24,9 @@ extern MM_STATS MmStats;
 
 #define TAG_NONE (ULONG)(('N'<<0) + ('o'<<8) + ('n'<<16) + ('e'<<24))
 
+ULONG STDCALL
+ExRosQueryPagedPoolTag ( PVOID Block );
+
 /* FUNCTIONS ***************************************************************/
 
 STATIC PVOID STDCALL
@@ -336,4 +339,20 @@ MiRaisePoolQuota(
     }
 }
 
+ULONG STDCALL
+ExRosQueryPoolTag ( PVOID Block )
+{
+   ASSERT_IRQL(DISPATCH_LEVEL);
+
+   if (Block >= MmPagedPoolBase && (char*)Block < ((char*)MmPagedPoolBase + MmPagedPoolSize))
+   {
+      return ExRosQueryPagedPoolTag(Block);
+   }
+   else
+   {
+      UNIMPLEMENTED;
+      return 0;
+   }
+}
+
 /* EOF */
index 581ce5f..edaf1da 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: ppool.c,v 1.33 2004/11/20 21:16:38 navaraf Exp $
+/* $Id: ppool.c,v 1.34 2004/12/11 00:13:37 royce Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
 
 #undef assert
 #define assert(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d\n", __FILE__,__LINE__); KeBugCheck(0); }
-#define ASSERT_SIZE(n) assert ( (n) <= MmPagedPoolSize && (n) >= 0 )
-#define ASSERT_PTR(p) assert ( ((size_t)(p)) >= ((size_t)MmPagedPoolBase) && ((size_t)(p)) < ((size_t)((size_t)MmPagedPoolBase+MmPagedPoolSize)) )
+#define ASSERT_SIZE(n) assert ( (n) <= MmPagedPoolSize && (n) > 0 )
+#define IS_PPOOL_PTR(p) ((size_t)(p)) >= ((size_t)MmPagedPoolBase) && ((size_t)(p)) < ((size_t)((size_t)MmPagedPoolBase+MmPagedPoolSize))
+#define ASSERT_PTR(p) assert ( IS_PPOOL_PTR(p) )
 
 // to disable buffer over/under-run detection, set the following macro to 0
+#if !defined(DBG) && !defined(KDBG)
+#define MM_PPOOL_REDZONE_BYTES 0
+#else
 #define MM_PPOOL_REDZONE_BYTES 4
-#define MM_PPOOL_REDZONE_VALUE 0xCD
+#define MM_PPOOL_REDZONE_LOVALUE 0x87
+#define MM_PPOOL_REDZONE_HIVALUE 0xA5
+#define MM_PPOOL_FREEMAGIC (ULONG)(('F'<<0) + ('r'<<8) + ('E'<<16) + ('e'<<24))
+#define MM_PPOOL_USEDMAGIC (ULONG)(('u'<<0) + ('S'<<8) + ('e'<<16) + ('D'<<24))
+#define MM_PPOOL_LASTOWNER_ENTRIES 3
+#endif
 
 typedef struct _MM_PPOOL_FREE_BLOCK_HEADER
 {
+#if MM_PPOOL_REDZONE_BYTES
+   ULONG FreeMagic;
+#endif//MM_PPOOL_REDZONE_BYTES
    ULONG Size;
    struct _MM_PPOOL_FREE_BLOCK_HEADER* NextFree;
+#if MM_PPOOL_REDZONE_BYTES
+   ULONG LastOwnerStack[MM_PPOOL_LASTOWNER_ENTRIES];
+#endif//MM_PPOOL_REDZONE_BYTES
 }
 MM_PPOOL_FREE_BLOCK_HEADER, *PMM_PPOOL_FREE_BLOCK_HEADER;
 
 typedef struct _MM_PPOOL_USED_BLOCK_HEADER
 {
+#if MM_PPOOL_REDZONE_BYTES
+   ULONG UsedMagic;
+#endif//MM_PPOOL_REDZONE_BYTES
    ULONG Size;
 #if MM_PPOOL_REDZONE_BYTES
-
    ULONG UserSize; // how many bytes the user actually asked for...
-   struct _MM_PPOOL_USED_BLOCK_HEADER* NextUsed;
 #endif//MM_PPOOL_REDZONE_BYTES
+   struct _MM_PPOOL_USED_BLOCK_HEADER* NextUsed;
+   ULONG Tag;
 }
 MM_PPOOL_USED_BLOCK_HEADER, *PMM_PPOOL_USED_BLOCK_HEADER;
 
@@ -52,9 +70,7 @@ ULONG MmPagedPoolSize;
 ULONG MmTotalPagedPoolQuota = 0;
 static FAST_MUTEX MmPagedPoolLock;
 static PMM_PPOOL_FREE_BLOCK_HEADER MmPagedPoolFirstFreeBlock;
-#if MM_PPOOL_REDZONE_BYTES
 static PMM_PPOOL_USED_BLOCK_HEADER MmPagedPoolFirstUsedBlock;
-#endif//MM_PPOOL_REDZONE_BYTES
 
 /* FUNCTIONS *****************************************************************/
 
@@ -86,6 +102,12 @@ MmInitializePagedPool(VOID)
    MmPagedPoolFirstFreeBlock->NextFree = NULL;
 
 #if MM_PPOOL_REDZONE_BYTES
+   MmPagedPoolFirstFreeBlock->FreeMagic = MM_PPOOL_FREEMAGIC;
+   {
+      int i;
+      for ( i = 0; i < MM_PPOOL_LASTOWNER_ENTRIES; i++ )
+         MmPagedPoolFirstFreeBlock->LastOwnerStack[i] = 0;
+   }
 
    MmPagedPoolFirstUsedBlock = NULL;
 #endif//MM_PPOOL_REDZONE_BYTES
@@ -102,6 +124,9 @@ static void VerifyPagedPool ( int line )
    while ( p )
    {
       DPRINT ( "  0x%x: %lu bytes (next 0x%x)\n", p, p->Size, p->NextFree );
+#if MM_PPOOL_REDZONE_BYTES
+      ASSERT ( p->FreeMagic == MM_PPOOL_FREEMAGIC );
+#endif//MM_PPOOL_REDZONE_BYTES
       ASSERT_PTR(p);
       ASSERT_SIZE(p->Size);
       count++;
@@ -114,34 +139,84 @@ static void VerifyPagedPool ( int line )
 #define VerifyPagedPool()
 #endif
 
+BOOLEAN STDCALL
+KeRosPrintAddress(PVOID address);
+
+#if !MM_PPOOL_REDZONE_BYTES
+#define MmpRedZoneCheck(pUsed,Addr,file,line)
+#else//MM_PPOOL_REDZONE_BYTES
+static VOID FASTCALL
+MmpRedZoneCheck ( PMM_PPOOL_USED_BLOCK_HEADER pUsed, PUCHAR Addr, const char* file, int line )
+{
+   int i;
+   PUCHAR AddrEnd = Addr + pUsed->UserSize;
+   BOOL bLow = TRUE;
+   BOOL bHigh = TRUE;
+
+   ASSERT_PTR(Addr);
+   if ( pUsed->UsedMagic == MM_PPOOL_FREEMAGIC )
+   {
+      PMM_PPOOL_FREE_BLOCK_HEADER pFree = (PMM_PPOOL_FREE_BLOCK_HEADER)pUsed;
+      DPRINT1 ( "Double-free detected for Block 0x%x (kthread=0x%x)!\n", Addr, KeGetCurrentThread() );
+      DbgPrint ( "First Free Stack Frames:" );
+      for ( i = 0; i < MM_PPOOL_LASTOWNER_ENTRIES; i++ )
+         {
+                 if ( pFree->LastOwnerStack[i] != 0xDEADBEEF )
+                 {
+                       DbgPrint(" ");
+                       if (!KeRosPrintAddress ((PVOID)pFree->LastOwnerStack[i]) )
+                       {
+                               DbgPrint("<%X>", pFree->LastOwnerStack[i] );
+                       }
+                 }
+         }
+      DbgPrint ( "\n" );
+      KEBUGCHECK(BAD_POOL_HEADER);
+   }
+   if ( pUsed->UsedMagic != MM_PPOOL_USEDMAGIC )
+   {
+      DPRINT1 ( "Bad magic in Block 0x%x!\n", Addr );
+      KEBUGCHECK(BAD_POOL_HEADER);
+   }
+   ASSERT_SIZE(pUsed->Size);
+   ASSERT_SIZE(pUsed->UserSize);
+   ASSERT_PTR(AddrEnd);
+   Addr -= MM_PPOOL_REDZONE_BYTES; // this is to simplify indexing below...
+   for ( i = 0; i < MM_PPOOL_REDZONE_BYTES && bLow && bHigh; i++ )
+   {
+      bLow = bLow && ( Addr[i] == MM_PPOOL_REDZONE_LOVALUE );
+      bHigh = bHigh && ( AddrEnd[i] == MM_PPOOL_REDZONE_HIVALUE );
+   }
+   if ( !bLow || !bHigh )
+   {
+      const char* violation = "High and Low-side";
+      if ( bHigh ) // high is okay, so it was just low failed
+         violation = "Low-side";
+      else if ( bLow ) // low side is okay, so it was just high failed
+         violation = "High-side";
+      DbgPrint("%s(%i): %s redzone violation detected for paged pool address 0x%x\n",
+               file, line, violation, Addr );
+      DbgPrint ( "UsedMagic 0x%x, LoZone ", pUsed->UsedMagic );
+      for ( i = 0; i < MM_PPOOL_REDZONE_BYTES; i++ )
+         DbgPrint ( "%02x", Addr[i] );
+      DbgPrint ( ", HiZone " );
+      for ( i = 0; i < MM_PPOOL_REDZONE_BYTES; i++ )
+         DbgPrint ( "%02x", AddrEnd[i] );
+      DbgPrint ( "\n" );
+      KEBUGCHECK(BAD_POOL_HEADER);
+   }
+}
+#endif//MM_PPOOL_REDZONE_BYTES
+
 VOID STDCALL
 MmDbgPagedPoolRedZoneCheck ( const char* file, int line )
 {
 #if MM_PPOOL_REDZONE_BYTES
    PMM_PPOOL_USED_BLOCK_HEADER pUsed = MmPagedPoolFirstUsedBlock;
-   int i;
-   BOOL bLow = TRUE;
-   BOOL bHigh = TRUE;
 
    while ( pUsed )
    {
-      PUCHAR Addr = (PUCHAR)block_to_address(pUsed);
-      for ( i = 0; i < MM_PPOOL_REDZONE_BYTES; i++ )
-      {
-         bLow = bLow && ( *(Addr-i-1) == MM_PPOOL_REDZONE_VALUE );
-         bHigh = bHigh && ( *(Addr+pUsed->UserSize+i) == MM_PPOOL_REDZONE_VALUE );
-      }
-      if ( !bLow || !bHigh )
-      {
-         const char* violation = "High and Low-side";
-         if ( bHigh ) // high is okay, so it was just low failed
-            violation = "Low-side";
-         else if ( bLow ) // low side is okay, so it was just high failed
-            violation = "High-side";
-         DbgPrint("%s(%i): %s redzone violation detected for paged pool address 0x%x\n",
-                  file, line, violation, Addr );
-         KEBUGCHECK(0);
-      }
+      MmpRedZoneCheck ( pUsed, block_to_address(pUsed), __FILE__, __LINE__ );
       pUsed = pUsed->NextUsed;
    }
 #endif//MM_PPOOL_REDZONE_BYTES
@@ -270,6 +345,9 @@ ExAllocatePagedPoolWithTag (IN POOL_TYPE PoolType,
                (PMM_PPOOL_FREE_BLOCK_HEADER)address_to_block(BestAlignedAddr);
             assert ( BestAlignedAddr > Addr );
             NewFreeBlock->Size = (char*)Addr + BestBlock->Size - (char*)BestAlignedAddr;
+#if MM_PPOOL_REDZONE_BYTES
+            NewFreeBlock->FreeMagic = MM_PPOOL_FREEMAGIC;
+#endif//MM_PPOOL_REDZONE_BYTES
             ASSERT_SIZE(NewFreeBlock->Size);
             BestBlock->Size = (size_t)NewFreeBlock - (size_t)Addr;
             ASSERT_SIZE(BestBlock->Size);
@@ -344,6 +422,9 @@ ExAllocatePagedPoolWithTag (IN POOL_TYPE PoolType,
       NextBlock = (PMM_PPOOL_FREE_BLOCK_HEADER)((char*)BestBlock + BlockSize);
       //DPRINT(".");
       NextBlock->Size = NewSize;
+#if MM_PPOOL_REDZONE_BYTES
+      NextBlock->FreeMagic = MM_PPOOL_FREEMAGIC;
+#endif//MM_PPOOL_REDZONE_BYTES
       ASSERT_SIZE ( NextBlock->Size );
       //DPRINT(".");
       NextBlock->NextFree = BestBlock->NextFree;
@@ -372,6 +453,9 @@ ExAllocatePagedPoolWithTag (IN POOL_TYPE PoolType,
       NewBlock = (PMM_PPOOL_USED_BLOCK_HEADER)BestBlock;
       //DPRINT(".");
       NewBlock->Size = BlockSize;
+#if MM_PPOOL_REDZONE_BYTES
+      NewBlock->UsedMagic = MM_PPOOL_USEDMAGIC;
+#endif//MM_PPOOL_REDZONE_BYTES
       ASSERT_SIZE ( NewBlock->Size );
       //DPRINT(".\n");
    }
@@ -397,14 +481,17 @@ ExAllocatePagedPoolWithTag (IN POOL_TYPE PoolType,
        */
       NewBlock = (PMM_PPOOL_USED_BLOCK_HEADER)BestBlock;
       NewBlock->Size = NewSize;
+#if MM_PPOOL_REDZONE_BYTES
+      NewBlock->UsedMagic = MM_PPOOL_USEDMAGIC;
+#endif//MM_PPOOL_REDZONE_BYTES
       ASSERT_SIZE ( NewBlock->Size );
    }
 
-#if MM_PPOOL_REDZONE_BYTES
    // now add the block to the used block list
    NewBlock->NextUsed = MmPagedPoolFirstUsedBlock;
    MmPagedPoolFirstUsedBlock = NewBlock;
-#endif//MM_PPOOL_REDZONE_BYTES
+
+   NewBlock->Tag = Tag;
 
    VerifyPagedPool();
 
@@ -421,17 +508,9 @@ ExAllocatePagedPoolWithTag (IN POOL_TYPE PoolType,
       PUCHAR Addr = (PUCHAR)BlockAddress;
       //DbgPrint ( "writing buffer-overrun detection bytes" );
       memset ( Addr - MM_PPOOL_REDZONE_BYTES,
-               MM_PPOOL_REDZONE_VALUE, MM_PPOOL_REDZONE_BYTES );
-      memset ( Addr + NewBlock->UserSize, MM_PPOOL_REDZONE_VALUE,
+               MM_PPOOL_REDZONE_LOVALUE, MM_PPOOL_REDZONE_BYTES );
+      memset ( Addr + NewBlock->UserSize, MM_PPOOL_REDZONE_HIVALUE,
                MM_PPOOL_REDZONE_BYTES );
-      /*for ( i = 0; i < MM_PPOOL_REDZONE_BYTES; i++ )
-      {
-        //DbgPrint(".");
-        *(Addr-i-1) = 0xCD;
-        //DbgPrint("o");
-        *(Addr+NewBlock->UserSize+i) = 0xCD;
-      }*/
-      //DbgPrint ( "done!\n" );
    }
 
 #endif//MM_PPOOL_REDZONE_BYTES
@@ -452,33 +531,14 @@ ExFreePagedPool(IN PVOID Block)
 
    ASSERT_IRQL(APC_LEVEL);
 
-#if MM_PPOOL_REDZONE_BYTES
-   // write out buffer-overrun detection bytes
-   {
-      int i;
-      PUCHAR Addr = (PUCHAR)Block;
-      //DbgPrint ( "checking buffer-overrun detection bytes..." );
-      for ( i = 0; i < MM_PPOOL_REDZONE_BYTES; i++ )
-      {
-         if (*(Addr-i-1) != MM_PPOOL_REDZONE_VALUE)
-         {
-            DPRINT1("Attempt to free memory %#08x. Redzone underrun!\n", Block);
-         }
-         if (*(Addr+UsedBlock->UserSize+i) != MM_PPOOL_REDZONE_VALUE)
-         {
-            DPRINT1("Attempt to free memory %#08x. Redzone overrun!\n", Block);
-         }
+   MmpRedZoneCheck ( UsedBlock, Block, __FILE__, __LINE__ );
 
-         assert ( *(Addr-i-1) == MM_PPOOL_REDZONE_VALUE );
-         assert ( *(Addr+UsedBlock->UserSize+i) == MM_PPOOL_REDZONE_VALUE );
-      }
-      //DbgPrint ( "done!\n" );
-   }
-#endif//MM_PPOOL_REDZONE_BYTES
+#if MM_PPOOL_REDZONE_BYTES
+   memset ( Block, 0xCD, UsedBlock->UserSize );
+#endif
 
    ExAcquireFastMutex(&MmPagedPoolLock);
 
-#if MM_PPOOL_REDZONE_BYTES
    // remove from used list...
    {
       PMM_PPOOL_USED_BLOCK_HEADER pPrev = MmPagedPoolFirstUsedBlock;
@@ -497,12 +557,38 @@ ExFreePagedPool(IN PVOID Block)
          pPrev->NextUsed = UsedBlock->NextUsed;
       }
    }
-#endif//MM_PPOOL_REDZONE_BYTES
 
    /*
     * Begin setting up the newly freed block's header.
     */
    FreeBlock->Size = UsedSize;
+#if MM_PPOOL_REDZONE_BYTES
+   FreeBlock->FreeMagic = MM_PPOOL_FREEMAGIC;
+   {
+      PULONG Frame;
+      int i;
+#if defined __GNUC__
+      __asm__("mov %%ebp, %%ebx" : "=b" (Frame) : );
+#elif defined(_MSC_VER)
+      __asm mov [Frame], ebp
+#endif
+      //DbgPrint ( "Stack Frames for Free Block 0x%x:", Block );
+      Frame = (PULONG)Frame[0]; // step out of ExFreePagedPool
+      for ( i = 0; i < MM_PPOOL_LASTOWNER_ENTRIES; i++ )
+      {
+         if ( Frame == 0 || (ULONG)Frame == 0xDEADBEEF )
+            FreeBlock->LastOwnerStack[i] = 0xDEADBEEF;
+         else
+         {
+            //DbgPrint ( " 0x%x", Frame[1] );
+            FreeBlock->LastOwnerStack[i] = Frame[1];
+            Frame = (PULONG)Frame[0];
+         }
+      }
+      //DbgPrint ( "\n" );
+      //KeRosDumpStackFrames ( NULL, 4 );
+   }
+#endif//MM_PPOOL_REDZONE_BYTES
    ASSERT_SIZE ( FreeBlock->Size );
 
    /*
@@ -533,6 +619,7 @@ ExFreePagedPool(IN PVOID Block)
    /*
     * If the next block is immediately adjacent to the newly freed one then
     * merge them.
+    * PLEASE DO NOT WIPE OUT 'MAGIC' OR 'LASTOWNER' DATA FOR MERGED FREE BLOCKS
     */
    if (NextBlock != NULL &&
          ((char*)FreeBlock + FreeBlock->Size) == (char*)NextBlock)
@@ -550,6 +637,7 @@ ExFreePagedPool(IN PVOID Block)
    /*
     * If the previous block is adjacent to the newly freed one then
     * merge them.
+    * PLEASE DO NOT WIPE OUT 'MAGIC' OR 'LASTOWNER' DATA FOR MERGED FREE BLOCKS
     */
    if (PreviousBlock != NULL &&
          ((char*)PreviousBlock + PreviousBlock->Size) == (char*)FreeBlock)
@@ -564,4 +652,40 @@ ExFreePagedPool(IN PVOID Block)
    ExReleaseFastMutex(&MmPagedPoolLock);
 }
 
+VOID STDCALL
+ExRosDumpPagedPoolByTag ( ULONG Tag )
+{
+       PMM_PPOOL_USED_BLOCK_HEADER UsedBlock = MmPagedPoolFirstUsedBlock;
+       int count = 0;
+       char tag[5];
+
+       // TODO FIXME - should we validate params or ASSERT_IRQL?
+       *(ULONG*)&tag[0] = Tag;
+       tag[4] = 0;
+       DbgPrint ( "PagedPool Dump by tag '%s'\n", tag );
+       DbgPrint ( "  -BLOCK-- --SIZE--\n" );
+       while ( IS_PPOOL_PTR(UsedBlock) )
+       {
+               if ( UsedBlock->Tag == Tag )
+               {
+                       DbgPrint ( "  %08X %08X\n", UsedBlock, UsedBlock->Size );
+                       ++count;
+               }
+               UsedBlock = UsedBlock->NextUsed;
+       }
+       if ( UsedBlock && !IS_PPOOL_PTR(UsedBlock) )
+       {
+               DPRINT1 ( "!!NextUsed took me to lala land: 0x%08X\n", UsedBlock );
+       }
+       DbgPrint ( "Entries found for tag '%s': %i\n", tag, count );
+}
+
+ULONG STDCALL
+ExRosQueryPagedPoolTag ( PVOID Block )
+{
+       PMM_PPOOL_USED_BLOCK_HEADER UsedBlock = address_to_block(Block);
+       // TODO FIXME - should we validate params or ASSERT_IRQL?
+       return UsedBlock->Tag;
+}
+
 /* EOF */
index 8548d96..e3d6408 100644 (file)
@@ -1,4 +1,4 @@
-; $Id: ntoskrnl.def,v 1.202 2004/11/27 13:04:06 navaraf Exp $
+; $Id: ntoskrnl.def,v 1.203 2004/12/11 00:13:37 royce Exp $
 ;
 ; reactos/ntoskrnl/ntoskrnl.def
 ;
@@ -139,6 +139,8 @@ ExReleaseResourceForThreadLite@8
 @ExReleaseResourceLite@4
 @ExReleaseRundownProtection@4
 @ExReleaseRundownProtectionEx@8
+ExRosDumpPagedPoolByTag@4
+ExRosQueryPoolTag@4
 @ExRundownCompleted@4
 ExSetResourceOwnerPointer@8
 ExSetTimerResolution@8