Skip to content

Instantly share code, notes, and snippets.

@krofna
Created July 30, 2013 16:55
Show Gist options
  • Save krofna/6114761 to your computer and use it in GitHub Desktop.
Save krofna/6114761 to your computer and use it in GitHub Desktop.
/**************************************************************************
* SdbTagToString [APPHELP.@]
*
* Converts specified tag into a string
*
* PARAMS
* tag [I] The tag which will be converted to a string
*
* RETURNS
* Success: Pointer to the string matching specified tag
* Failure: L"InvalidTag" string
*/
LPCWSTR WINAPI SdbTagToString(TAG tag)
{
/* lookup table for tags in range 0x1 -> 0xFF | TYPE */
static LPCWSTR table[9][0x31] = {
/* TAG_TYPE_NULL */
{
L"INCLUDE", L"GENERAL", L"MATCH_LOGIC_NOT", L"APPLY_ALL_SHIMS",
L"USE_SERVICE_PACK_FILES", L"MITIGATION_OS", L"BLOCK_UPGRADE",
L"INCLUDEEXCLUDEDLL", L"RAC_EVENT_OFF", L"TELEMETRY_OFF",
L"SHIM_ENGINE_OFF", L"LAYER_PROPAGATION_OFF", L"REINSTALL_UPGRADE"
},
/* TAG_TYPE_BYTE does not have tags, so align table */
{
INVALID_TAG_STRING
},
/* TAG_TYPE_WORD */
{
L"MATCH_MODE"
},
/* TAG_TYPE_DWORD */
{
L"SIZE", L"OFFSET", L"CHECKSUM", L"SHIM_TAGID", L"PATCH_TAGID",
L"MODULE_TYPE", L"VERDATEHI", L"VERDATELO", L"VERFILEOS",
L"VERFILETYPE", L"PE_CHECKSUM", L"PREVOSMAJORVER", L"PREVOSMINORVER",
L"PREVOSPLATFORMID", L"PREVOSBUILDNO", L"PROBLEMSEVERITY", L"LANGID",
L"VER_LANGUAGE", INVALID_TAG_STRING, L"ENGINE", L"HTMLHELPID", L"INDEX_FLAGS",
L"FLAGS", L"DATA_VALUETYPE", L"DATA_DWORD", L"LAYER_TAGID",
L"MSI_TRANSFORM_TAGID", L"LINKER_VERSION", L"LINK_DATE",
L"UPTO_LINK_DATE", L"OS_SERVICE_PACK", L"FLAG_TAGID", L"RUNTIME_PLATFORM",
L"OS_SKU", L"OS_PLATFORM", L"APP_NAME_RC_ID", L"VENDOR_NAME_RC_ID",
L"SUMMARY_MSG_RC_ID", L"VISTA_SKU", L"DESCRIPTION_RC_ID", L"PARAMETER1_RC_ID",
INVALID_TAG_STRING, INVALID_TAG_STRING, INVALID_TAG_STRING, INVALID_TAG_STRING,
INVALID_TAG_STRING, INVALID_TAG_STRING, L"CONTEXT_TAGID", L"EXE_WRAPPER",
},
/* TAG_TYPE_QWORD */
{
L"TIME", L"BIN_FILE_VERSION", L"BIN_PRODUCT_VERSION", L"MODTIME",
L"FLAG_MASK_KERNEL", L"UPTO_BIN_PRODUCT_VERSION", L"DATA_QWORD",
L"FLAG_MASK_USER", L"FLAGS_NTVDM1", L"FLAGS_NTVDM2", L"FLAGS_NTVDM3",
L"FLAG_MASK_SHELL", L"UPTO_BIN_FILE_VERSION", L"FLAG_MASK_FUSION",
L"FLAG_PROCESSPARAM", L"FLAG_LUA", L"FLAG_INSTALL"
},
/* TAG_TYPE_STRINGREF */
{
L"NAME", L"DESCRIPTION", L"MODULE", L"API", L"VENDOR", L"APP_NAME",
INVALID_TAG_STRING, L"COMMAND_LINE", L"COMPANY_NAME", L"DLLFILE",
L"WILDCARD_NAME", INVALID_TAG_STRING, INVALID_TAG_STRING,
INVALID_TAG_STRING, INVALID_TAG_STRING, L"PRODUCT_NAME", L"PRODUCT_VERSION",
L"FILE_DESCRIPTION", L"FILE_VERSION", L"ORIGINAL_FILENAME", L"INTERNAL_NAME",
L"LEGAL_COPYRIGHT", L"16BIT_DESCRIPTION", L"APPHELP_DETAILS", L"LINK_URL",
L"LINK_TEXT", L"APPHELP_TITLE", L"APPHELP_CONTACT", L"SXS_MANIFEST",
L"DATA_STRING", L"MSI_TRANSFORM_FILE", L"16BIT_MODULE_NAME",
L"LAYER_DISPLAYNAME", L"COMPILER_VERSION", L"ACTION_TYPE", L"EXPORT_NAME"
},
/* TAG_TYPE_LIST */
{
L"DATABASE", L"LIBRARY", L"INEXCLUDE", L"SHIM", L"PATCH",
L"APP", L"EXE", L"MATCHING_FILE", L"SHIM_REF", L"PATCH_REF", L"LAYER",
L"FILE", L"APPHELP", L"LINK", L"DATA", L"MSI_TRANSFORM", L"MSI_TRANSFORM_REF",
L"MSI_PACKAGE", L"FLAG", L"MSI_CUSTOM_ACTION", L"FLAG_REF", L"ACTION",
L"LOOKUP", L"CONTEXT", L"CONTEXT_REF"
},
/* TAG_TYPE_STRING does not have tags at 0x1 -> 0xFF, so align table */
{
INVALID_TAG_STRING
},
/* TAG_TYPE_BINARY */
{
INVALID_TAG_STRING, L"PATCH_BITS", L"FILE_BITS", L"EXE_ID", L"DATA_BITS",
L"MSI_PACKAGE_ID", L"DATABASE_ID", L"CONTEXT_PLATFORM_ID",
L"CONTEXT_BRANCH_ID", INVALID_TAG_STRING, INVALID_TAG_STRING,
INVALID_TAG_STRING, INVALID_TAG_STRING, INVALID_TAG_STRING,
INVALID_TAG_STRING, L"FIX_ID", L"APP_ID"
}
};
/* sizes of tables in above 2D array */
static WORD limits[9] = {
/* switch off TYPE_* byte of last tag for each type */
TAG_REINSTALL_UPGRADE & 0xFF,
1,
TAG_MATCH_MODE & 0xFF,
TAG_EXE_WRAPPER & 0xFF,
TAG_FLAG_INSTALL & 0xFF,
TAG_EXPORT_NAME & 0xFF,
TAG_CONTEXT_REF & 0xFF,
1,
TAG_APP_ID & 0xFF
};
/* lookup table for tags in range 0x800 + (0x1 -> 0xFF) | TYPE */
static LPCWSTR table2[9][3] = {
/* TAG_TYPE_NULL */ { INVALID_TAG_STRING },
/* TAG_TYPE_BYTE */ { INVALID_TAG_STRING },
/* TAG_TYPE_WORD */ { L"TAG", L"INDEX_TAG", L"INDEX_KEY" },
/* TAG_TYPE_DWORD */ { L"TAGID" },
/* TAG_TYPE_QWORD */ { INVALID_TAG_STRING },
/* TAG_TYPE_STRINGREF */ { INVALID_TAG_STRING },
/* TAG_TYPE_LIST */ { L"STRINGTABLE", L"INDEXES", L"INDEX" },
/* TAG_TYPE_STRING */ { L"STRINGTABLE_ITEM" },
/* TAG_TYPE_BINARY */ { L"INDEX_BITS" }
};
/* sizes of tables in above 2D array, hardcoded for simplicity */
static WORD limits2[9] = { 0, 0, 3, 1, 0, 0, 3, 1, 1 };
BOOL switch_table; /* should we use table2 and limits2? */
WORD index;
/* special case: tag without type */
if (tag == 0)
return L"NULL";
/* tags with only type byte or no type byte are invalid */
if ((tag & ~TAG_TYPE_MASK) == 0 || (tag & TAG_TYPE_MASK) == 0)
return INVALID_TAG_STRING;
/* some valid tags are in range 0x800 + (0x1 -> 0xF) | TYPE */
if ((tag & 0xF00) == 0x800)
switch_table = TRUE;
else if ((tag & 0xF00) == 0)
switch_table = FALSE;
else return INVALID_TAG_STRING;
/* index of string in table */
index = tag & 0xFF;
/* bound check, tag >> 12 extracts the type byte */
if (index < 1 || (tag >> 12) > 9 || index > (switch_table ?
limits2[(tag >> 12) - 1] :
limits[(tag >> 12) - 1]))
return INVALID_TAG_STRING;
/* note that table is sorted by [type][low word] */
return switch_table ? table2[(tag >> 12) - 1][(tag & 0xFF) - 1] :
table[(tag >> 12) - 1][(tag & 0xFF) - 1];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment