+VOID
+NTAPI
+ExpCheckPoolHeader(IN PPOOL_HEADER Entry)
+{
+ PPOOL_HEADER PreviousEntry, NextEntry;
+
+ /* Is there a block before this one? */
+ if (Entry->PreviousSize)
+ {
+ /* Get it */
+ PreviousEntry = POOL_PREV_BLOCK(Entry);
+
+ /* The two blocks must be on the same page! */
+ if (PAGE_ALIGN(Entry) != PAGE_ALIGN(PreviousEntry))
+ {
+ /* Something is awry */
+ KeBugCheckEx(BAD_POOL_HEADER,
+ 6,
+ (ULONG_PTR)PreviousEntry,
+ __LINE__,
+ (ULONG_PTR)Entry);
+ }
+
+ /* This block should also indicate that it's as large as we think it is */
+ if (PreviousEntry->BlockSize != Entry->PreviousSize)
+ {
+ /* Otherwise, someone corrupted one of the sizes */
+ KeBugCheckEx(BAD_POOL_HEADER,
+ 5,
+ (ULONG_PTR)PreviousEntry,
+ __LINE__,
+ (ULONG_PTR)Entry);
+ }
+ }
+ else if (PAGE_ALIGN(Entry) != Entry)
+ {
+ /* If there's no block before us, we are the first block, so we should be on a page boundary */
+ KeBugCheckEx(BAD_POOL_HEADER,
+ 7,
+ 0,
+ __LINE__,
+ (ULONG_PTR)Entry);
+ }
+
+ /* This block must have a size */
+ if (!Entry->BlockSize)
+ {
+ /* Someone must've corrupted this field */
+ KeBugCheckEx(BAD_POOL_HEADER,
+ 8,
+ 0,
+ __LINE__,
+ (ULONG_PTR)Entry);
+ }
+
+ /* Okay, now get the next block */
+ NextEntry = POOL_NEXT_BLOCK(Entry);
+
+ /* If this is the last block, then we'll be page-aligned, otherwise, check this block */
+ if (PAGE_ALIGN(NextEntry) != NextEntry)
+ {
+ /* The two blocks must be on the same page! */
+ if (PAGE_ALIGN(Entry) != PAGE_ALIGN(NextEntry))
+ {
+ /* Something is messed up */
+ KeBugCheckEx(BAD_POOL_HEADER,
+ 9,
+ (ULONG_PTR)NextEntry,
+ __LINE__,
+ (ULONG_PTR)Entry);
+ }
+
+ /* And this block should think we are as large as we truly are */
+ if (NextEntry->PreviousSize != Entry->BlockSize)
+ {
+ /* Otherwise, someone corrupted the field */
+ KeBugCheckEx(BAD_POOL_HEADER,
+ 5,
+ (ULONG_PTR)NextEntry,
+ __LINE__,
+ (ULONG_PTR)Entry);
+ }
+ }
+}
+
+VOID
+NTAPI
+ExpCheckPoolBlocks(IN PVOID Block)
+{
+ BOOLEAN FoundBlock;
+ SIZE_T Size = 0;
+ PPOOL_HEADER Entry;
+
+ /* Get the first entry for this page, make sure it really is the first */
+ Entry = PAGE_ALIGN(Block);
+ ASSERT(Entry->PreviousSize == 0);
+
+ /* Now scan each entry */
+ while (TRUE)
+ {
+ /* When we actually found our block, remember this */
+ if (Entry == Block) FoundBlock = TRUE;
+
+ /* Now validate this block header */
+ ExpCheckPoolHeader(Entry);
+
+ /* And go to the next one, keeping track of our size */
+ Size += Entry->BlockSize;
+ Entry = POOL_NEXT_BLOCK(Entry);
+
+ /* If we hit the last block, stop */
+ if (Size >= (PAGE_SIZE / POOL_BLOCK_SIZE)) break;
+
+ /* If we hit the end of the page, stop */
+ if (PAGE_ALIGN(Entry) == Entry) break;
+ }
+
+ /* We must've found our block, and we must have hit the end of the page */
+ if ((PAGE_ALIGN(Entry) != Entry) || !(FoundBlock))
+ {
+ /* Otherwise, the blocks are messed up */
+ KeBugCheckEx(BAD_POOL_HEADER, 10, (ULONG_PTR)Block, __LINE__, (ULONG_PTR)Entry);
+ }
+}
+