/** * Searches shim database for a next tag which matches prev_child within parent's domain. * * @param [in] pdb Handle to the shim database. * @param [in] parent TAGID of parent. * @param [in] prev_child TAGID of previous match. * * @return Success: TAGID of next match, Failure: TAGID_NULL. */ TAGID WINAPI SdbFindNextTag(PDB pdb, TAGID parent, TAGID prev_child) { TAG tag; TAGID iter; tag = SdbGetTagFromTagID(pdb, prev_child); iter = SdbGetNextChild(pdb, parent, prev_child); while (iter != TAGID_NULL) { if (SdbGetTagFromTagID(pdb, iter) == tag) return iter; iter = SdbGetNextChild(pdb, parent, iter); } return TAGID_NULL; }
BOOL WINAPI SdbpCheckTagIDType(PDB db, TAGID tagid, WORD type) { TAG tag = SdbGetTagFromTagID(db, tagid); if (tag == TAG_NULL) return FALSE; return SdbpCheckTagType(tag, type); }
/** * Searches shim database for a tag within specified domain. * * @param [in] pdb Handle to the shim database. * @param [in] parent TAGID of parent. * @param [in] tag TAG to be located. * * @return Success: TAGID of first matching tag, Failure: TAGID_NULL. */ TAGID WINAPI SdbFindFirstTag(PDB pdb, TAGID parent, TAG tag) { TAGID iter; iter = SdbGetFirstChild(pdb, parent); while (iter != TAGID_NULL) { if (SdbGetTagFromTagID(pdb, iter) == tag) return iter; iter = SdbGetNextChild(pdb, parent, iter); } return TAGID_NULL; }
static DWORD WINAPI SdbpGetTagSize(PDB pdb, TAGID tagid) { WORD type; DWORD size; type = SdbGetTagFromTagID(pdb, tagid) & TAG_TYPE_MASK; if (type == TAG_NULL) return 0; size = SdbGetTagDataSize(pdb, tagid); if (type <= TAG_TYPE_STRINGREF) return size += sizeof(TAG); else size += (sizeof(TAG) + sizeof(DWORD)); return size; }
/** * Searches shim database for a child of specified parent tag. * * @param [in] pdb Handle to the shim database. * @param [in] parent TAGID of parent. * * @return Success: TAGID of child tag, Failure: TAGID_NULL. */ TAGID WINAPI SdbGetFirstChild(PDB pdb, TAGID parent) { /* if we are at beginning of database */ if (parent == TAGID_ROOT) { /* header only database: no tags */ if (pdb->size <= _TAGID_ROOT) return TAGID_NULL; /* return *real* root tagid */ else return _TAGID_ROOT; } /* only list tag can have children */ if ((SdbGetTagFromTagID(pdb, parent) & TAG_TYPE_MASK) != TAG_TYPE_LIST) return TAGID_NULL; /* first child is sizeof(TAG) + sizeof(DWORD) bytes after beginning of list */ return parent + sizeof(TAG) + sizeof(DWORD); }
LPWSTR WINAPI SdbpGetString(PDB pdb, TAGID tagid, PDWORD size) { TAG tag; TAGID offset; tag = SdbGetTagFromTagID(pdb, tagid); if (tag == TAG_NULL) return NULL; if ((tag & TAG_TYPE_MASK) == TAG_TYPE_STRINGREF) { /* No stringtable; all references are invalid */ if (pdb->stringtable == TAGID_NULL) return NULL; /* TAG_TYPE_STRINGREF contains offset of string relative to stringtable */ if (!SdbpReadData(pdb, &tagid, tagid + sizeof(TAG), sizeof(TAGID))) return NULL; offset = pdb->stringtable + tagid + sizeof(TAG) + sizeof(TAGID); } else if ((tag & TAG_TYPE_MASK) == TAG_TYPE_STRING) { offset = tagid + sizeof(TAG) + sizeof(TAGID); } else { SHIM_ERR("Tag 0x%u at tagid %u is neither a string or reference to string\n", tag, tagid); return NULL; } /* Optionally read string size */ if (size && !SdbpReadData(pdb, size, offset - sizeof(TAGID), sizeof(*size))) return FALSE; return (LPWSTR)(&pdb->data[offset]); }
/** * Retrieves size of data at specified tagid. * * @param [in] pdb Handle to the shim database. * @param [in] tagid Tagid of tag whose size is queried. * * @return Success: Size of data at specified tagid, Failure: 0. */ DWORD WINAPI SdbGetTagDataSize(PDB pdb, TAGID tagid) { /* sizes of data types with fixed size */ static const SIZE_T sizes[6] = { 0, /* NULL */ 1, /* BYTE */ 2, /* WORD */ 4, /* DWORD */ 8, /* QWORD */ 4 /* STRINGREF */ }; WORD type; DWORD size; type = SdbGetTagFromTagID(pdb, tagid) & TAG_TYPE_MASK; if (type == TAG_NULL) return 0; if (type <= TAG_TYPE_STRINGREF) return sizes[(type >> 12) - 1]; /* tag with dynamic size (e.g. list): must read size */ if (!SdbpReadData(pdb, &size, tagid + sizeof(TAG), sizeof(size))) return 0; return size; }