142 lines
5.9 KiB
Plaintext
142 lines
5.9 KiB
Plaintext
|
//
|
||
|
// BASIC DATABASE STRUCTURE
|
||
|
//
|
||
|
// The database file format was specifically designed to allow for a simple, extensible representation
|
||
|
// of a hierarchical file like an XML file, and be forwards and backwards compatible. A future reader
|
||
|
// should be able to read any current files, and future files should be readable by this code.
|
||
|
//
|
||
|
//
|
||
|
// CORE BINARY FORMAT
|
||
|
//
|
||
|
// The file begins with a header of three DWORDs (defined in struct DB_HEADER):
|
||
|
//
|
||
|
// MajorVersion
|
||
|
// MinorVersion
|
||
|
// MagicNumber
|
||
|
//
|
||
|
// The Major version should only be changed if the new format would break old readers, i.e. NEVER.
|
||
|
// The Minor version can be changed for informational purposes if there is a significant change
|
||
|
// to the layout of the data.
|
||
|
// The Magic number is there to ensure we don't try to read some random file with the same extension.
|
||
|
//
|
||
|
// Following the header are tags, packed end-to-end with no padding. All tags are of the form:
|
||
|
//
|
||
|
// TAG[SIZE][DATA...]
|
||
|
//
|
||
|
// Where SIZE and DATA are optional, depending on the type of TAG.
|
||
|
//
|
||
|
// TAG is 2 bytes long, SIZE is 4 bytes long, and DATA is anywhere from 0 to 2^32 bytes long.
|
||
|
//
|
||
|
// The top 4 bits of a TAG are reserved for internal database BASIC TYPE info.
|
||
|
// This tells the database what kind of data is stored after the TAG, and if the tag has an
|
||
|
// implied size. For example a TAG of basic type TAG_TYPE_BYTE has an implied size of 1 byte,
|
||
|
// and does not require a SIZE. But a tag of basic type TAG_TYPE_STRING does not have an implied
|
||
|
// size, and will therefore have a SIZE after the tag.
|
||
|
//
|
||
|
// The BASIC TYPES are:
|
||
|
// TAG_TYPE_NULL (no SIZE, 0 bytes of DATA)
|
||
|
// TAG_TYPE_BYTE (no SIZE, 1 byte of DATA)
|
||
|
// TAG_TYPE_WORD (no SIZE, 2 bytes of DATA)
|
||
|
// TAG_TYPE_DWORD (no SIZE, 4 bytes of DATA)
|
||
|
// TAG_TYPE_QWORD (no SIZE, 8 bytes of DATA)
|
||
|
// TAG_TYPE_STRINGREF (no SIZE, 4 bytes of DATA)
|
||
|
// TAG_TYPE_LIST (SIZE, variable DATA)
|
||
|
// TAG_TYPE_STRING (SIZE, variable DATA)
|
||
|
// TAG_TYPE_BINARY (SIZE, variable DATA)
|
||
|
//
|
||
|
// Each of these types can be used for many different TAGs, by OR-ing the TAG_TYPE_x with a constant.
|
||
|
// See SHIMTAGS.H and SHIMDB.H for examples.
|
||
|
//
|
||
|
// TAG_TYPE_STRINGREF is used for strings that should be placed in a stringtable by the database code.
|
||
|
// This allows for efficient packing of duplicate strings. Tags of type STRING will be directly added
|
||
|
// to the DB with no indirection.
|
||
|
//
|
||
|
// TAG_TYPE_LIST is defined to contain only more tags. Its SIZE is the combined size of all of its child
|
||
|
// TAGs, including the TAG, DATA, and SIZE of each of them. This allows easy skipping over an entire
|
||
|
// branch of the heirarchy.
|
||
|
//
|
||
|
// If new BASIC TYPES are defined later, they MUST have a SIZE associated with them, as the code assumes
|
||
|
// that any type it doesn't recognize must have a SIZE. The first 5 types are really just a size optimization,
|
||
|
// and new types should not try to have implied sizes.
|
||
|
//
|
||
|
//
|
||
|
// THE SHIMDB LAYOUT
|
||
|
//
|
||
|
// Our layout for the application compatibility database mirrors closely the layout found in the DB.XML
|
||
|
// file, found in the NT tree in WINDOWS\APPCOMPAT\DB, used to store information about apps that need
|
||
|
// some kind of application compatibility fix applied to them. This comment block may get out of
|
||
|
// date as new data is added to the database, so for the most current layout, consult
|
||
|
// that file. One can also run the DUMPSDB.EXE utility (found in \WINDOWS\APPCOMPAT\DUMPSDB)
|
||
|
// on an existing SDB to see the exact layout being used.
|
||
|
//
|
||
|
// The root contains only two tags: DATABASE (list) and STRINGTABLE (list).
|
||
|
// The STRINGTABLE is used internally by the DB; all the useful data is under DATABASE.
|
||
|
//
|
||
|
// DATABASE contains a single LIBRARY (list) tag, 0 or more LAYER (list) tags, and 0 or more EXE (list) tags.
|
||
|
//
|
||
|
// LIBRARY contains 0 or more INEXCLUDE (list) tags, 0 or more DLL (list) tags, and 0 or more PATCH (list) tags
|
||
|
//
|
||
|
// an INEXCLUDE record contains potentially MODULE (string), API (string), INCLUDE (null, its existence
|
||
|
// or nonexistence is treated like a boolean), and OFFSET (dword).
|
||
|
//
|
||
|
// a DLL record contains potentially NAME (string), SHORTNAME (string),
|
||
|
// DESCRIPTION (string), DLL_BITS (binary),
|
||
|
// and 0 or more INEXCLUDE (list) tags.
|
||
|
//
|
||
|
// a PATCH record contains potentially NAME (string),
|
||
|
// DESCRIPTION (string), and PATCH_BITS (binary),
|
||
|
//
|
||
|
// a LAYER record contains exactly the same things that can be in an EXE record except MATCHING_FILE tags
|
||
|
// and PATCH_REF tags.
|
||
|
//
|
||
|
// an EXE record contains potentially a NAME (string), KERNEL_FLAGS (qword), 0 or more
|
||
|
// MATCHING_FILE (list) tags, 0 or more DLL_REF (list) tags, and 0 or more PATCH_REF (list) tags.
|
||
|
//
|
||
|
// a MATCHING_FILE record contains potentially a NAME (string), SIZE (dword), TIME (qword), and CHECKSUM (dword)
|
||
|
//
|
||
|
// a DLL_REF record contains potentially a NAME (string), DLL_TAGID (dword), and 0 or more INEXCLUDE (list)
|
||
|
// tags.
|
||
|
//
|
||
|
// a PATCH_REF record contains potentially a NAME (string) and PATCH_TAGID (dword)
|
||
|
//
|
||
|
// Here's a map of where each tag is generally found, where "+" means there can be 0 or more, and [] means
|
||
|
// the tag is optional:
|
||
|
//
|
||
|
// DATABASE
|
||
|
// LIBRARY
|
||
|
// [INEXCLUDE+]
|
||
|
// [INCLUDE]
|
||
|
// MODULE
|
||
|
// [API]
|
||
|
// [OFFSET]
|
||
|
// [DLL+]
|
||
|
// NAME
|
||
|
// [SHORTNAME]
|
||
|
// [DESCRIPTION]
|
||
|
// [INEXCLUDE+]
|
||
|
// [DLL_BITS]
|
||
|
// [PATCH+]
|
||
|
// NAME
|
||
|
// [DESCRIPTION]
|
||
|
// [PATCH_BITS]
|
||
|
// [EXE+]
|
||
|
// NAME
|
||
|
// [APP_NAME]
|
||
|
// [VENDOR_NAME]
|
||
|
// [KERNEL_FLAGS]
|
||
|
// [MATCHING_FILE+]
|
||
|
// NAME
|
||
|
// [SIZE]
|
||
|
// [TIME]
|
||
|
// [CHECKSUM]
|
||
|
// [DLL_REF+]
|
||
|
// NAME
|
||
|
// [DLL_TAGID]
|
||
|
// [INEXCLUDE+]
|
||
|
// [PATCH_REF+]
|
||
|
// NAME
|
||
|
// [PATCH_TAGID]
|
||
|
// [STRINGTABLE]
|
||
|
// STRINGTABLE_ITEM+
|
||
|
//
|