#!/usr/bin/env python

from struct import unpack

POOL_SIZE_MASK = 0x01FF
POOL_TYPE_MASK = 0xFE00

# info based on _POOL_HEADER info from XPSP2
# Some details differ on Win2K SP4--don't trust this entirely.

class PoolHeader:
    types = {
        "FreedPool": 0,
        "NonPagedPool": 1,
        "PagedPool": 2,
        "NonPagedPoolMustSucceed": 3,
        "DontUseThisType": 4,
        "NonPagedPoolCacheAligned": 5,
        "PagedPoolCacheAligned": 6,
        "NonPagedPoolCacheAlignedMustS": 7,
        "MaxPoolType": 8,
        "NonPagedPoolSession": 33,
        "PagedPoolSession": 34,
        "NonPagedPoolMustSucceedSession": 35,
        "DontUseThisTypeSession": 36,
        "NonPagedPoolCacheAlignedSession": 37,
        "PagedPoolCacheAlignedSession": 38,
        "NonPagedPoolCacheAlignedMustSSession": 39
    }
    names = {
        0: "FreedPool",
        1: "NonPagedPool",
        2: "PagedPool",
        3: "NonPagedPoolMustSucceed",
        4: "DontUseThisType",
        5: "NonPagedPoolCacheAligned",
        6: "PagedPoolCacheAligned",
        7: "NonPagedPoolCacheAlignedMustS",
        8: "MaxPoolType",
        33: "NonPagedPool",
        34: "PagedPoolSession",
        35: "NonPagedPoolMustSucceedSession",
        36: "DontUseThisTypeSession",
        37: "NonPagedPoolCacheAlignedSession",
        38: "PagedPoolCacheAlignedSession",
        39: "NonPagedPoolCacheAlignedMustSSession",
    }

    def __init__(self, str):
        (prev, cur, tag) = unpack("<HH4s", str)
        self.tag = tag
        self.prev_size = (prev & POOL_SIZE_MASK) * 8 # Should be 32 on Win2k
        self.cur_size = (cur & POOL_SIZE_MASK) * 8 # Should be 32 on Win2k
        self.index = (prev & POOL_TYPE_MASK) >> 9
        self.type = (cur & POOL_TYPE_MASK) >> 9
    def getType(self):
        return self.type
    def getTypeStr(self):
        try: return self.names[self.type]
        except KeyError: return "UnknownType"
