Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

228 lines
7.7 KiB

#include "windows.h"
#define PHDRF_CONTAINER_RELATIVE (0x00000001)
typedef struct _PIC_OBJECT_HEADER
{
ULONG ulFlags;
ULONG ulSize;
ULONG ulType;
} PIC_OBJECT_HEADER, *PPIC_OBJECT_HEADER;
typedef struct _PIC_CONTAINER
{
PIC_OBJECT_HEADER Header; // Header blob
ULONG ulTotalPicSize; // How many bytes long is this PIC region?
ULONG ulIndexTableOffset; // Index table offset from PIC header
} PIC_CONTAINER, *PPIC_CONTAINER;
#define PSTF_ITEMS_SORTED_BY_STRING (0x00010000)
#define PSTF_ITEMS_SORTED_BY_IDENT (0x00020000)
#define PSTF_ITEM_IDENT_IS_HASH (0x00040000)
typedef struct _PIC_STRING_TABLE
{
PIC_OBJECT_HEADER Header;
ULONG ulStringCount; // Object header
ULONG ulTableItemsOffset; // Offset to the table of string items
ULONG ulContainerBlobOffset; // Offset to the blob of string data
} PIC_STRING_TABLE, *PPIC_STRING_TABLE;
typedef struct _PIC_STRING_TABLE_ENTRY
{
ULONG ulStringIdent;
ULONG ulStringLength;
ULONG ulOffsetIntoBlob;
} PIC_STRING_TABLE_ENTRY, *PPIC_STRING_TABLE_ENTRY;
#define PBLBF_DATA_FOLLOWS (0x00010000) // Data follows this object directly
typedef struct _PIC_DATA_BLOB
{
PIC_OBJECT_HEADER Header;
ULONG ulSize;
ULONG ulOffsetToObject;
} PIC_DATA_BLOB, *PPIC_DATA_BLOB;
//
// An object table acts as an index into a blob of PIC items. Think of it like a
// top-level directory that you can index into with some pretty trivial functions.
// You can store things by name, identifier, etc. Type information is also available
//
typedef struct _PIC_OBJECT_TABLE
{
PIC_OBJECT_HEADER Header; // Header blob
ULONG ulEntryCount; // How many objects?
ULONG ulTableOffset; // Offset in the container to the entry table
ULONG ulStringTableOffset; // Offset to the stringtable that matches this in container
} PIC_OBJECT_TABLE, *PPIC_OBJECT_TABLE;
#define PIC_OBJTYPE_STRING ((ULONG)'rtsP') // Object is a string
#define PIC_OBJTYPE_TABLE ((ULONG)'lbtP') // Object is a string table
#define PIC_OBJTYPE_DIRECTORY ((ULONG)'ridP') // Object is a directory blob
#define PIC_OBJTYPE_BLOB ((ULONG)'blbP') // Object is an anonymous blob of data
#define POBJTIF_HAS_STRING (0x00010000) // The object table entry string offset is valid
#define POBJTIF_KEY_VALID (0x00020000) // The object key value is valid
#define POBJTIF_STRING_IS_INDEX (0x00040000) // The string value is an index into the table
#define PBOJTIF_STRING_IS_IDENT (0x00080000) // The string value is an identifier
typedef struct _PIC_OBJECT_TABLE_ENTRY
{
ULONG ulObjectKey; // integral key of this object
ULONG ulObjectType; // Object type (PIC_OBJ_*)
ULONG ulStringIdent; // Identifier in the matching stringtable for this objecttable, if
ULONG ulObjectOffset; // Offset to the object from the table's indicated base addy
} PIC_OBJECT_TABLE_ENTRY, *PPIC_OBJECT_TABLE_ENTRY;
#define PSTRF_UNICODE (0x00010000)
#define PSTRF_MBCS (0x00020000)
typedef struct _PIC_STRING
{
PIC_OBJECT_HEADER Header; // Header blob
ULONG ulLength; // Length, in bytes, of the string
ULONG ulContentOffset; // Relative to either the containing object or the table base.
// Zero indicates that the data is immediately following.
} PIC_STRING, *PPIC_STRING;
//
// C++ analogues to the above structures for easier access
//
class CPicIndexTable;
class CPicHeaderObject;
class CPicReference;
class CPicObject
{
protected:
PVOID m_pvObjectBase;
PPIC_OBJECT_HEADER m_pObjectHeader;
CPicHeaderObject *m_pParentContainer;
ULONG m_ulObjectOffset;
PVOID GetObjectPointer() { return m_pvObjectBase; }
public:
CPicObject(CPicHeaderObject* pOwningObject, ULONG ulOffsetFromParentBase);
CPicObject(CPicReference pr);
ULONG GetType() const { return m_pObjectHeader->ulType; }
ULONG GetSize() const { return m_pObjectHeader->ulSize; }
ULONG GetFlags() const { return m_pObjectHeader->ulFlags; }
CPicHeaderObject *GetContainer() const { return m_pParentContainer; }
CPicReference GetSelfReference();
friend CPicReference;
};
//
// This is the object that represents the root of a PI object tree.
// You may construct it based on just a PVOID, in which case it assumes
// that there's at least sizeof(PIC_CONTAINER) there to gather details
// from to load the rest of the tree into memory. Things are created on-
// demand, to optimize for things like memory-mapped files.
//
// PI headers may contain an 'index table' like a card catalog to find
// objects in the structure.
//
class CPicHeaderObject : public CPicObject
{
PPIC_CONTAINER m_pPicContainerBase; // m_pvBaseOfPic, just cast for easy access
CPicIndexTable *m_pIndexTable; // Index table, if present
public:
CPicHeaderObject(PVOID pvBaseOfCollection);
CPicHeaderObject(CPicReference objectReference);
const CPicIndexTable* GetIndexTable();
friend CPicReference;
};
//
// Index table of objects in this PI blob, referrable by name or key.
//
class CPicIndexTable : public CPicObject
{
PPIC_OBJECT_TABLE m_pObject; // Pointer to the actual object table
PPIC_OBJECT_TABLE_ENTRY m_pObjectList; // Pointer to the list of object table entries
public:
CPicIndexTable(CPicReference object); // Construct this index table based on the object
bool FindObject(ULONG ulObjectIdent, CPicReference *reference) const;
bool FindObject(PCWSTR pcwszString, CPicReference *reference) const;
bool FindObjects(ULONG ulObjectType, ULONG *pulObjectKeys, SIZE_T *cObjectKeys) const;
ULONG GetObjectCount() const;
};
//
// This reference object can be carted around and be passed from object to
// object. The CPicObject class works well off these, and every other CPic*
// class has constructors for a reference object. Basically, this works like
// a pointer ... there's an object base, and an offset into the object.
//
class CPicReference
{
ULONG m_ulObjectOffsetFromParent;
CPicHeaderObject *m_pParentObject;
public:
CPicReference(CPicHeaderObject *pParent, ULONG ulOffset);
const PVOID GetRawPointer() const;
ULONG GetOffset() const;
CPicObject GetObject() const { return CPicObject(m_pParentObject, m_ulObjectOffsetFromParent); }
void Clear();
};
//
// String table
//
class CPicStringTable : public CPicObject
{
PPIC_STRING_TABLE m_pObject;
public:
CPicStringTable(CPicReference object);
bool GetString(ULONG ulFlags, ULONG ulIdent, WCHAR* pwsStringData, ULONG *ulCbString);
};
CPicIndexTable::CPicIndexTable(CPicReference object) : CPicObject(object)
{
if (this->GetType() != PIC_OBJTYPE_DIRECTORY)
DebugBreak();
// This is just "self"
m_pObject = (PPIC_OBJECT_TABLE)this->GetObjectPointer();
// This is the list of objects
m_pObjectList = (PPIC_OBJECT_TABLE_ENTRY)CPicReference(this->GetContainer(), m_pObject->ulTableOffset).GetRawPointer();
}
//
// Search for an object by its identifier
//
bool
CPicIndexTable::FindObject(ULONG ulObjectIdent, CPicReference *reference) const
{
if (reference)
reference->Clear();
ULONG ul;
PPIC_OBJECT_TABLE_ENTRY pHere = this->m_pObjectList;
for (ul = 0; ul < m_pObject->ulEntryCount; ul++, pHere++)
{
if (pHere->ulObjectKey == ulObjectIdent)
{
if (reference)
*reference = CPicReference(this->GetContainer(), pHere->ulObjectOffset);
return true;
}
}
return false;
}