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.

227 lines
7.7 KiB

  1. #include "windows.h"
  2. #define PHDRF_CONTAINER_RELATIVE (0x00000001)
  3. typedef struct _PIC_OBJECT_HEADER
  4. {
  5. ULONG ulFlags;
  6. ULONG ulSize;
  7. ULONG ulType;
  8. } PIC_OBJECT_HEADER, *PPIC_OBJECT_HEADER;
  9. typedef struct _PIC_CONTAINER
  10. {
  11. PIC_OBJECT_HEADER Header; // Header blob
  12. ULONG ulTotalPicSize; // How many bytes long is this PIC region?
  13. ULONG ulIndexTableOffset; // Index table offset from PIC header
  14. } PIC_CONTAINER, *PPIC_CONTAINER;
  15. #define PSTF_ITEMS_SORTED_BY_STRING (0x00010000)
  16. #define PSTF_ITEMS_SORTED_BY_IDENT (0x00020000)
  17. #define PSTF_ITEM_IDENT_IS_HASH (0x00040000)
  18. typedef struct _PIC_STRING_TABLE
  19. {
  20. PIC_OBJECT_HEADER Header;
  21. ULONG ulStringCount; // Object header
  22. ULONG ulTableItemsOffset; // Offset to the table of string items
  23. ULONG ulContainerBlobOffset; // Offset to the blob of string data
  24. } PIC_STRING_TABLE, *PPIC_STRING_TABLE;
  25. typedef struct _PIC_STRING_TABLE_ENTRY
  26. {
  27. ULONG ulStringIdent;
  28. ULONG ulStringLength;
  29. ULONG ulOffsetIntoBlob;
  30. } PIC_STRING_TABLE_ENTRY, *PPIC_STRING_TABLE_ENTRY;
  31. #define PBLBF_DATA_FOLLOWS (0x00010000) // Data follows this object directly
  32. typedef struct _PIC_DATA_BLOB
  33. {
  34. PIC_OBJECT_HEADER Header;
  35. ULONG ulSize;
  36. ULONG ulOffsetToObject;
  37. } PIC_DATA_BLOB, *PPIC_DATA_BLOB;
  38. //
  39. // An object table acts as an index into a blob of PIC items. Think of it like a
  40. // top-level directory that you can index into with some pretty trivial functions.
  41. // You can store things by name, identifier, etc. Type information is also available
  42. //
  43. typedef struct _PIC_OBJECT_TABLE
  44. {
  45. PIC_OBJECT_HEADER Header; // Header blob
  46. ULONG ulEntryCount; // How many objects?
  47. ULONG ulTableOffset; // Offset in the container to the entry table
  48. ULONG ulStringTableOffset; // Offset to the stringtable that matches this in container
  49. } PIC_OBJECT_TABLE, *PPIC_OBJECT_TABLE;
  50. #define PIC_OBJTYPE_STRING ((ULONG)'rtsP') // Object is a string
  51. #define PIC_OBJTYPE_TABLE ((ULONG)'lbtP') // Object is a string table
  52. #define PIC_OBJTYPE_DIRECTORY ((ULONG)'ridP') // Object is a directory blob
  53. #define PIC_OBJTYPE_BLOB ((ULONG)'blbP') // Object is an anonymous blob of data
  54. #define POBJTIF_HAS_STRING (0x00010000) // The object table entry string offset is valid
  55. #define POBJTIF_KEY_VALID (0x00020000) // The object key value is valid
  56. #define POBJTIF_STRING_IS_INDEX (0x00040000) // The string value is an index into the table
  57. #define PBOJTIF_STRING_IS_IDENT (0x00080000) // The string value is an identifier
  58. typedef struct _PIC_OBJECT_TABLE_ENTRY
  59. {
  60. ULONG ulObjectKey; // integral key of this object
  61. ULONG ulObjectType; // Object type (PIC_OBJ_*)
  62. ULONG ulStringIdent; // Identifier in the matching stringtable for this objecttable, if
  63. ULONG ulObjectOffset; // Offset to the object from the table's indicated base addy
  64. } PIC_OBJECT_TABLE_ENTRY, *PPIC_OBJECT_TABLE_ENTRY;
  65. #define PSTRF_UNICODE (0x00010000)
  66. #define PSTRF_MBCS (0x00020000)
  67. typedef struct _PIC_STRING
  68. {
  69. PIC_OBJECT_HEADER Header; // Header blob
  70. ULONG ulLength; // Length, in bytes, of the string
  71. ULONG ulContentOffset; // Relative to either the containing object or the table base.
  72. // Zero indicates that the data is immediately following.
  73. } PIC_STRING, *PPIC_STRING;
  74. //
  75. // C++ analogues to the above structures for easier access
  76. //
  77. class CPicIndexTable;
  78. class CPicHeaderObject;
  79. class CPicReference;
  80. class CPicObject
  81. {
  82. protected:
  83. PVOID m_pvObjectBase;
  84. PPIC_OBJECT_HEADER m_pObjectHeader;
  85. CPicHeaderObject *m_pParentContainer;
  86. ULONG m_ulObjectOffset;
  87. PVOID GetObjectPointer() { return m_pvObjectBase; }
  88. public:
  89. CPicObject(CPicHeaderObject* pOwningObject, ULONG ulOffsetFromParentBase);
  90. CPicObject(CPicReference pr);
  91. ULONG GetType() const { return m_pObjectHeader->ulType; }
  92. ULONG GetSize() const { return m_pObjectHeader->ulSize; }
  93. ULONG GetFlags() const { return m_pObjectHeader->ulFlags; }
  94. CPicHeaderObject *GetContainer() const { return m_pParentContainer; }
  95. CPicReference GetSelfReference();
  96. friend CPicReference;
  97. };
  98. //
  99. // This is the object that represents the root of a PI object tree.
  100. // You may construct it based on just a PVOID, in which case it assumes
  101. // that there's at least sizeof(PIC_CONTAINER) there to gather details
  102. // from to load the rest of the tree into memory. Things are created on-
  103. // demand, to optimize for things like memory-mapped files.
  104. //
  105. // PI headers may contain an 'index table' like a card catalog to find
  106. // objects in the structure.
  107. //
  108. class CPicHeaderObject : public CPicObject
  109. {
  110. PPIC_CONTAINER m_pPicContainerBase; // m_pvBaseOfPic, just cast for easy access
  111. CPicIndexTable *m_pIndexTable; // Index table, if present
  112. public:
  113. CPicHeaderObject(PVOID pvBaseOfCollection);
  114. CPicHeaderObject(CPicReference objectReference);
  115. const CPicIndexTable* GetIndexTable();
  116. friend CPicReference;
  117. };
  118. //
  119. // Index table of objects in this PI blob, referrable by name or key.
  120. //
  121. class CPicIndexTable : public CPicObject
  122. {
  123. PPIC_OBJECT_TABLE m_pObject; // Pointer to the actual object table
  124. PPIC_OBJECT_TABLE_ENTRY m_pObjectList; // Pointer to the list of object table entries
  125. public:
  126. CPicIndexTable(CPicReference object); // Construct this index table based on the object
  127. bool FindObject(ULONG ulObjectIdent, CPicReference *reference) const;
  128. bool FindObject(PCWSTR pcwszString, CPicReference *reference) const;
  129. bool FindObjects(ULONG ulObjectType, ULONG *pulObjectKeys, SIZE_T *cObjectKeys) const;
  130. ULONG GetObjectCount() const;
  131. };
  132. //
  133. // This reference object can be carted around and be passed from object to
  134. // object. The CPicObject class works well off these, and every other CPic*
  135. // class has constructors for a reference object. Basically, this works like
  136. // a pointer ... there's an object base, and an offset into the object.
  137. //
  138. class CPicReference
  139. {
  140. ULONG m_ulObjectOffsetFromParent;
  141. CPicHeaderObject *m_pParentObject;
  142. public:
  143. CPicReference(CPicHeaderObject *pParent, ULONG ulOffset);
  144. const PVOID GetRawPointer() const;
  145. ULONG GetOffset() const;
  146. CPicObject GetObject() const { return CPicObject(m_pParentObject, m_ulObjectOffsetFromParent); }
  147. void Clear();
  148. };
  149. //
  150. // String table
  151. //
  152. class CPicStringTable : public CPicObject
  153. {
  154. PPIC_STRING_TABLE m_pObject;
  155. public:
  156. CPicStringTable(CPicReference object);
  157. bool GetString(ULONG ulFlags, ULONG ulIdent, WCHAR* pwsStringData, ULONG *ulCbString);
  158. };
  159. CPicIndexTable::CPicIndexTable(CPicReference object) : CPicObject(object)
  160. {
  161. if (this->GetType() != PIC_OBJTYPE_DIRECTORY)
  162. DebugBreak();
  163. // This is just "self"
  164. m_pObject = (PPIC_OBJECT_TABLE)this->GetObjectPointer();
  165. // This is the list of objects
  166. m_pObjectList = (PPIC_OBJECT_TABLE_ENTRY)CPicReference(this->GetContainer(), m_pObject->ulTableOffset).GetRawPointer();
  167. }
  168. //
  169. // Search for an object by its identifier
  170. //
  171. bool
  172. CPicIndexTable::FindObject(ULONG ulObjectIdent, CPicReference *reference) const
  173. {
  174. if (reference)
  175. reference->Clear();
  176. ULONG ul;
  177. PPIC_OBJECT_TABLE_ENTRY pHere = this->m_pObjectList;
  178. for (ul = 0; ul < m_pObject->ulEntryCount; ul++, pHere++)
  179. {
  180. if (pHere->ulObjectKey == ulObjectIdent)
  181. {
  182. if (reference)
  183. *reference = CPicReference(this->GetContainer(), pHere->ulObjectOffset);
  184. return true;
  185. }
  186. }
  187. return false;
  188. }