mirror of
https://github.com/reactos/reactos.git
synced 2025-05-19 09:10:56 +00:00
[SDK][XML2SDB] Simplify helper functions, output Exe matches + file attributes
svn path=/trunk/; revision=75202
This commit is contained in:
parent
5c59bd330a
commit
2ef285e193
4 changed files with 216 additions and 88 deletions
|
@ -5,6 +5,7 @@ list(APPEND SOURCE
|
||||||
main.cpp
|
main.cpp
|
||||||
tinyxml2.cpp
|
tinyxml2.cpp
|
||||||
xml2sdb.cpp
|
xml2sdb.cpp
|
||||||
|
xml2sdb.h
|
||||||
${REACTOS_SOURCE_DIR}/dll/appcompat/apphelp/sdbwrite.c
|
${REACTOS_SOURCE_DIR}/dll/appcompat/apphelp/sdbwrite.c
|
||||||
${REACTOS_SOURCE_DIR}/dll/appcompat/apphelp/sdbstringtable.c)
|
${REACTOS_SOURCE_DIR}/dll/appcompat/apphelp/sdbstringtable.c)
|
||||||
|
|
||||||
|
|
|
@ -186,14 +186,19 @@ static bool run_one(std::string& input, std::string& output)
|
||||||
|
|
||||||
static std::string get_strarg(int argc, char* argv[], int& i)
|
static std::string get_strarg(int argc, char* argv[], int& i)
|
||||||
{
|
{
|
||||||
if (argv[i][2] == 0)
|
if (argv[i][2] != 0)
|
||||||
{
|
return std::string(argv[i] + 2);
|
||||||
++i;
|
|
||||||
if (i >= argc || !argv[i])
|
++i;
|
||||||
return std::string();
|
if (i >= argc || !argv[i])
|
||||||
return argv[i];
|
return std::string();
|
||||||
}
|
return argv[i];
|
||||||
return std::string(argv[i] + 2);
|
}
|
||||||
|
|
||||||
|
static void update_loglevel(int argc, char* argv[], int& i)
|
||||||
|
{
|
||||||
|
std::string value = get_strarg(argc, argv, i);
|
||||||
|
g_ShimDebugLevel = strtoul(value.c_str(), NULL, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -i R:\src\apphelp\reactos\media\sdb\sysmain.xml -oR:\build\apphelp\devenv_msvc\media\sdb\ros2.sdb
|
// -i R:\src\apphelp\reactos\media\sdb\sysmain.xml -oR:\build\apphelp\devenv_msvc\media\sdb\ros2.sdb
|
||||||
|
@ -204,25 +209,28 @@ int main(int argc, char * argv[])
|
||||||
|
|
||||||
for (int i = 1; i < argc; ++i)
|
for (int i = 1; i < argc; ++i)
|
||||||
{
|
{
|
||||||
if (argv[i][0] == '/' || argv[i][0] == '-')
|
if (argv[i][0] != '/' && argv[i][0] != '-')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch(argv[i][1])
|
||||||
{
|
{
|
||||||
switch(argv[i][1])
|
case 'i':
|
||||||
{
|
input = get_strarg(argc, argv, i);
|
||||||
case 'i':
|
break;
|
||||||
input = get_strarg(argc, argv, i);
|
case 'o':
|
||||||
break;
|
output = get_strarg(argc, argv, i);
|
||||||
case 'o':
|
break;
|
||||||
output = get_strarg(argc, argv, i);
|
case 'l':
|
||||||
break;
|
update_loglevel(argc, argv, i);
|
||||||
}
|
break;
|
||||||
if (!input.empty() && !output.empty())
|
}
|
||||||
{
|
if (input.empty() || output.empty())
|
||||||
if (!run_one(input, output))
|
continue;
|
||||||
{
|
|
||||||
printf("Failed converting '%s' to '%s'\n", input.c_str(), output.c_str());
|
if (!run_one(input, output))
|
||||||
return 1;
|
{
|
||||||
}
|
printf("Failed converting '%s' to '%s'\n", input.c_str(), output.c_str());
|
||||||
}
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS xml to sdb converter
|
* PROJECT: ReactOS xml to sdb converter
|
||||||
* FILE: sdk/tools/xml2sdb/xml2sdb.cpp
|
* FILE: sdk/tools/xml2sdb/xml2sdb.cpp
|
||||||
* PURPOSE: Main conversion functions from xml -> db
|
* PURPOSE: Conversion functions from xml -> db
|
||||||
* PROGRAMMERS: Mark Jansen
|
* PROGRAMMERS: Mark Jansen
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -16,6 +16,7 @@
|
||||||
using tinyxml2::XMLText;
|
using tinyxml2::XMLText;
|
||||||
|
|
||||||
static const GUID GUID_NULL = { 0 };
|
static const GUID GUID_NULL = { 0 };
|
||||||
|
static const char szCompilerVersion[] = "1.5.0.0";
|
||||||
|
|
||||||
#if !defined(C_ASSERT)
|
#if !defined(C_ASSERT)
|
||||||
#define C_ASSERT(expr) extern char (*c_assert(void)) [(expr) ? 1 : -1]
|
#define C_ASSERT(expr) extern char (*c_assert(void)) [(expr) ? 1 : -1]
|
||||||
|
@ -44,7 +45,7 @@ VOID NTAPI RtlSecondsSince1970ToTime(IN ULONG SecondsSince1970,
|
||||||
// Convert utf8 to utf16:
|
// Convert utf8 to utf16:
|
||||||
// http://stackoverflow.com/a/7154226/4928207
|
// http://stackoverflow.com/a/7154226/4928207
|
||||||
|
|
||||||
bool IsEmptyGuid(GUID& g)
|
bool IsEmptyGuid(const GUID& g)
|
||||||
{
|
{
|
||||||
return !memcmp(&g, &GUID_NULL, sizeof(GUID));
|
return !memcmp(&g, &GUID_NULL, sizeof(GUID));
|
||||||
}
|
}
|
||||||
|
@ -89,6 +90,32 @@ std::string ReadStringNode(XMLHandle dbNode, const char* nodeName)
|
||||||
return ToString(dbNode.FirstChildElement(nodeName));
|
return ToString(dbNode.FirstChildElement(nodeName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD ReadDWordNode(XMLHandle dbNode, const char* nodeName)
|
||||||
|
{
|
||||||
|
std::string value = ReadStringNode(dbNode, nodeName);
|
||||||
|
int base = 10;
|
||||||
|
if (value.size() > 2 && value[0] == '0' && value[1] == 'x')
|
||||||
|
{
|
||||||
|
base = 16;
|
||||||
|
value = value.substr(2);
|
||||||
|
}
|
||||||
|
return static_cast<DWORD>(strtoul(value.c_str(), NULL, base));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char char2byte(char hexChar, bool* success = NULL)
|
||||||
|
{
|
||||||
|
if (hexChar >= '0' && hexChar <= '9')
|
||||||
|
return hexChar - '0';
|
||||||
|
if (hexChar >= 'A' && hexChar <= 'F')
|
||||||
|
return hexChar - 'A' + 10;
|
||||||
|
if (hexChar >= 'a' && hexChar <= 'f')
|
||||||
|
return hexChar - 'a' + 10;
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
*success = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// adapted from wine's ntdll\rtlstr.c rev 1.45
|
// adapted from wine's ntdll\rtlstr.c rev 1.45
|
||||||
static bool StringToGuid(const std::string& str, GUID& guid)
|
static bool StringToGuid(const std::string& str, GUID& guid)
|
||||||
{
|
{
|
||||||
|
@ -124,28 +151,12 @@ static bool StringToGuid(const std::string& str, GUID& guid)
|
||||||
{
|
{
|
||||||
CHAR ch = *lpszGUID, ch2 = lpszGUID[1];
|
CHAR ch = *lpszGUID, ch2 = lpszGUID[1];
|
||||||
unsigned char byte;
|
unsigned char byte;
|
||||||
|
bool converted = true;
|
||||||
|
|
||||||
/* Read two hex digits as a byte value */
|
byte = char2byte(ch, &converted) << 4 | char2byte(ch2, &converted);
|
||||||
if (ch >= '0' && ch <= '9')
|
if (!converted)
|
||||||
ch = ch - '0';
|
|
||||||
else if (ch >= 'a' && ch <= 'f')
|
|
||||||
ch = ch - 'a' + 10;
|
|
||||||
else if (ch >= 'A' && ch <= 'F')
|
|
||||||
ch = ch - 'A' + 10;
|
|
||||||
else
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (ch2 >= '0' && ch2 <= '9')
|
|
||||||
ch2 = ch2 - '0';
|
|
||||||
else if (ch2 >= 'a' && ch2 <= 'f')
|
|
||||||
ch2 = ch2 - 'a' + 10;
|
|
||||||
else if (ch2 >= 'A' && ch2 <= 'F')
|
|
||||||
ch2 = ch2 - 'A' + 10;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
|
|
||||||
byte = ch << 4 | ch2;
|
|
||||||
|
|
||||||
switch (i)
|
switch (i)
|
||||||
{
|
{
|
||||||
#ifndef WORDS_BIGENDIAN
|
#ifndef WORDS_BIGENDIAN
|
||||||
|
@ -194,7 +205,7 @@ static bool StringToGuid(const std::string& str, GUID& guid)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReadBinaryNode(XMLHandle dbNode, const char* nodeName, GUID& guid)
|
bool ReadGuidNode(XMLHandle dbNode, const char* nodeName, GUID& guid)
|
||||||
{
|
{
|
||||||
std::string value = ReadStringNode(dbNode, nodeName);
|
std::string value = ReadStringNode(dbNode, nodeName);
|
||||||
if (!StringToGuid(value, guid))
|
if (!StringToGuid(value, guid))
|
||||||
|
@ -205,6 +216,23 @@ bool ReadBinaryNode(XMLHandle dbNode, const char* nodeName, GUID& guid)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ReadBinaryNode(XMLHandle dbNode, const char* nodeName, std::vector<BYTE>& data)
|
||||||
|
{
|
||||||
|
std::string value = ReadStringNode(dbNode, nodeName);
|
||||||
|
value.erase(std::remove_if(value.begin(), value.end(), ::isspace), value.end());
|
||||||
|
|
||||||
|
size_t length = value.size() / 2;
|
||||||
|
if (length * 2 != value.size())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
data.resize(length);
|
||||||
|
for (size_t n = 0; n < length; ++n)
|
||||||
|
{
|
||||||
|
data[n] = (BYTE)(char2byte(value[n * 2]) << 4 | char2byte(value[(n * 2) + 1]));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* InExclude
|
* InExclude
|
||||||
|
@ -234,7 +262,7 @@ bool InExclude::fromXml(XMLHandle dbNode)
|
||||||
bool InExclude::toSdb(PDB pdb, Database& db)
|
bool InExclude::toSdb(PDB pdb, Database& db)
|
||||||
{
|
{
|
||||||
TAGID tagid = db.BeginWriteListTag(pdb, TAG_INEXCLUD);
|
TAGID tagid = db.BeginWriteListTag(pdb, TAG_INEXCLUD);
|
||||||
db.WriteString(pdb, TAG_MODULE, Module);
|
db.WriteString(pdb, TAG_MODULE, Module, true);
|
||||||
if (Include)
|
if (Include)
|
||||||
SdbWriteNULLTag(pdb, TAG_INCLUDE);
|
SdbWriteNULLTag(pdb, TAG_INCLUDE);
|
||||||
return !!db.EndWriteListTag(pdb, tagid);
|
return !!db.EndWriteListTag(pdb, tagid);
|
||||||
|
@ -282,9 +310,8 @@ bool ShimRef::fromXml(XMLHandle dbNode)
|
||||||
bool ShimRef::toSdb(PDB pdb, Database& db)
|
bool ShimRef::toSdb(PDB pdb, Database& db)
|
||||||
{
|
{
|
||||||
TAGID tagid = db.BeginWriteListTag(pdb, TAG_SHIM_REF);
|
TAGID tagid = db.BeginWriteListTag(pdb, TAG_SHIM_REF);
|
||||||
db.WriteString(pdb, TAG_NAME, Name);
|
db.WriteString(pdb, TAG_NAME, Name, true);
|
||||||
if (!CommandLine.empty())
|
db.WriteString(pdb, TAG_COMMAND_LINE, CommandLine);
|
||||||
db.WriteString(pdb, TAG_COMMAND_LINE, CommandLine);
|
|
||||||
|
|
||||||
if (!ShimTagid)
|
if (!ShimTagid)
|
||||||
ShimTagid = db.FindShimTagid(Name);
|
ShimTagid = db.FindShimTagid(Name);
|
||||||
|
@ -301,7 +328,7 @@ bool Shim::fromXml(XMLHandle dbNode)
|
||||||
{
|
{
|
||||||
Name = ReadStringNode(dbNode, "NAME");
|
Name = ReadStringNode(dbNode, "NAME");
|
||||||
DllFile = ReadStringNode(dbNode, "DLLFILE");
|
DllFile = ReadStringNode(dbNode, "DLLFILE");
|
||||||
ReadBinaryNode(dbNode, "FIX_ID", FixID);
|
ReadGuidNode(dbNode, "FIX_ID", FixID);
|
||||||
// GENERAL ?
|
// GENERAL ?
|
||||||
// DESCRIPTION_RC_ID
|
// DESCRIPTION_RC_ID
|
||||||
ReadGeneric(dbNode, InExcludes, "INEXCLUDE");
|
ReadGeneric(dbNode, InExcludes, "INEXCLUDE");
|
||||||
|
@ -337,7 +364,7 @@ bool Layer::fromXml(XMLHandle dbNode)
|
||||||
bool Layer::toSdb(PDB pdb, Database& db)
|
bool Layer::toSdb(PDB pdb, Database& db)
|
||||||
{
|
{
|
||||||
Tagid = db.BeginWriteListTag(pdb, TAG_LAYER);
|
Tagid = db.BeginWriteListTag(pdb, TAG_LAYER);
|
||||||
db.WriteString(pdb, TAG_NAME, Name);
|
db.WriteString(pdb, TAG_NAME, Name, true);
|
||||||
if (!WriteGeneric(pdb, ShimRefs, db))
|
if (!WriteGeneric(pdb, ShimRefs, db))
|
||||||
return false;
|
return false;
|
||||||
return !!db.EndWriteListTag(pdb, Tagid);
|
return !!db.EndWriteListTag(pdb, Tagid);
|
||||||
|
@ -351,9 +378,13 @@ bool Layer::toSdb(PDB pdb, Database& db)
|
||||||
bool MatchingFile::fromXml(XMLHandle dbNode)
|
bool MatchingFile::fromXml(XMLHandle dbNode)
|
||||||
{
|
{
|
||||||
Name = ReadStringNode(dbNode, "NAME");
|
Name = ReadStringNode(dbNode, "NAME");
|
||||||
|
Size = ReadDWordNode(dbNode, "SIZE");
|
||||||
|
Checksum = ReadDWordNode(dbNode, "CHECKSUM");
|
||||||
CompanyName = ReadStringNode(dbNode, "COMPANY_NAME");
|
CompanyName = ReadStringNode(dbNode, "COMPANY_NAME");
|
||||||
|
InternalName = ReadStringNode(dbNode, "INTERNAL_NAME");
|
||||||
ProductName = ReadStringNode(dbNode, "PRODUCT_NAME");
|
ProductName = ReadStringNode(dbNode, "PRODUCT_NAME");
|
||||||
ProductVersion = ReadStringNode(dbNode, "PRODUCT_VERSION");
|
ProductVersion = ReadStringNode(dbNode, "PRODUCT_VERSION");
|
||||||
|
FileVersion = ReadStringNode(dbNode, "FILE_VERSION");
|
||||||
BinFileVersion = ReadStringNode(dbNode, "BIN_FILE_VERSION");
|
BinFileVersion = ReadStringNode(dbNode, "BIN_FILE_VERSION");
|
||||||
LinkDate = ReadStringNode(dbNode, "LINK_DATE");
|
LinkDate = ReadStringNode(dbNode, "LINK_DATE");
|
||||||
VerLanguage = ReadStringNode(dbNode, "VER_LANGUAGE");
|
VerLanguage = ReadStringNode(dbNode, "VER_LANGUAGE");
|
||||||
|
@ -367,7 +398,28 @@ bool MatchingFile::fromXml(XMLHandle dbNode)
|
||||||
bool MatchingFile::toSdb(PDB pdb, Database& db)
|
bool MatchingFile::toSdb(PDB pdb, Database& db)
|
||||||
{
|
{
|
||||||
TAGID tagid = db.BeginWriteListTag(pdb, TAG_MATCHING_FILE);
|
TAGID tagid = db.BeginWriteListTag(pdb, TAG_MATCHING_FILE);
|
||||||
SHIM_ERR("Unimplemented\n");
|
|
||||||
|
db.WriteString(pdb, TAG_NAME, Name, true);
|
||||||
|
db.WriteDWord(pdb, TAG_SIZE, Size);
|
||||||
|
db.WriteDWord(pdb, TAG_CHECKSUM, Checksum);
|
||||||
|
db.WriteString(pdb, TAG_COMPANY_NAME, CompanyName);
|
||||||
|
db.WriteString(pdb, TAG_INTERNAL_NAME, InternalName);
|
||||||
|
db.WriteString(pdb, TAG_PRODUCT_NAME, ProductName);
|
||||||
|
db.WriteString(pdb, TAG_PRODUCT_VERSION, ProductVersion);
|
||||||
|
db.WriteString(pdb, TAG_FILE_VERSION, FileVersion);
|
||||||
|
if (!BinFileVersion.empty())
|
||||||
|
SHIM_ERR("TAG_BIN_FILE_VERSION Unimplemented\n"); //db.WriteQWord(pdb, TAG_BIN_FILE_VERSION, BinFileVersion);
|
||||||
|
if (!LinkDate.empty())
|
||||||
|
SHIM_ERR("TAG_LINK_DATE Unimplemented\n"); //db.WriteDWord(pdb, TAG_LINK_DATE, LinkDate);
|
||||||
|
if (!VerLanguage.empty())
|
||||||
|
SHIM_ERR("TAG_VER_LANGUAGE Unimplemented\n"); //db.WriteDWord(pdb, TAG_VER_LANGUAGE, VerLanguage);
|
||||||
|
db.WriteString(pdb, TAG_FILE_DESCRIPTION, FileDescription);
|
||||||
|
db.WriteString(pdb, TAG_ORIGINAL_FILENAME, OriginalFilename);
|
||||||
|
if (!UptoBinFileVersion.empty())
|
||||||
|
SHIM_ERR("TAG_UPTO_BIN_FILE_VERSION Unimplemented\n"); //db.WriteQWord(pdb, TAG_UPTO_BIN_FILE_VERSION, UptoBinFileVersion);
|
||||||
|
if (!LinkerVersion.empty())
|
||||||
|
SHIM_ERR("TAG_LINKER_VERSION Unimplemented\n"); //db.WriteDWord(pdb, TAG_LINKER_VERSION, LinkerVersion);
|
||||||
|
|
||||||
|
|
||||||
return !!db.EndWriteListTag(pdb, tagid);
|
return !!db.EndWriteListTag(pdb, tagid);
|
||||||
}
|
}
|
||||||
|
@ -380,9 +432,12 @@ bool MatchingFile::toSdb(PDB pdb, Database& db)
|
||||||
bool Exe::fromXml(XMLHandle dbNode)
|
bool Exe::fromXml(XMLHandle dbNode)
|
||||||
{
|
{
|
||||||
Name = ReadStringNode(dbNode, "NAME");
|
Name = ReadStringNode(dbNode, "NAME");
|
||||||
|
ReadGuidNode(dbNode, "EXE_ID", ExeID);
|
||||||
AppName = ReadStringNode(dbNode, "APP_NAME");
|
AppName = ReadStringNode(dbNode, "APP_NAME");
|
||||||
Vendor = ReadStringNode(dbNode, "VENDOR");
|
Vendor = ReadStringNode(dbNode, "VENDOR");
|
||||||
|
|
||||||
|
ReadGeneric(dbNode, MatchingFiles, "MATCHING_FILE");
|
||||||
|
|
||||||
ReadGeneric(dbNode, ShimRefs, "SHIM_REF");
|
ReadGeneric(dbNode, ShimRefs, "SHIM_REF");
|
||||||
|
|
||||||
return !Name.empty();
|
return !Name.empty();
|
||||||
|
@ -391,7 +446,20 @@ bool Exe::fromXml(XMLHandle dbNode)
|
||||||
bool Exe::toSdb(PDB pdb, Database& db)
|
bool Exe::toSdb(PDB pdb, Database& db)
|
||||||
{
|
{
|
||||||
Tagid = db.BeginWriteListTag(pdb, TAG_EXE);
|
Tagid = db.BeginWriteListTag(pdb, TAG_EXE);
|
||||||
SHIM_ERR("Unimplemented\n");
|
|
||||||
|
db.WriteString(pdb, TAG_NAME, Name, true);
|
||||||
|
if (IsEmptyGuid(ExeID))
|
||||||
|
RandomGuid(ExeID);
|
||||||
|
db.WriteBinary(pdb, TAG_EXE_ID, ExeID);
|
||||||
|
|
||||||
|
|
||||||
|
db.WriteString(pdb, TAG_APP_NAME, AppName);
|
||||||
|
db.WriteString(pdb, TAG_VENDOR, Vendor);
|
||||||
|
|
||||||
|
if (!WriteGeneric(pdb, MatchingFiles, db))
|
||||||
|
return false;
|
||||||
|
if (!WriteGeneric(pdb, ShimRefs, db))
|
||||||
|
return false;
|
||||||
|
|
||||||
return !!db.EndWriteListTag(pdb, Tagid);
|
return !!db.EndWriteListTag(pdb, Tagid);
|
||||||
}
|
}
|
||||||
|
@ -401,19 +469,33 @@ bool Exe::toSdb(PDB pdb, Database& db)
|
||||||
* Database
|
* Database
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Database::WriteBinary(PDB pdb, TAG tag, const GUID& guid)
|
void Database::WriteBinary(PDB pdb, TAG tag, const GUID& guid, bool always)
|
||||||
{
|
{
|
||||||
SdbWriteBinaryTag(pdb, tag, (BYTE*)&guid, sizeof(GUID));
|
if (always || !IsEmptyGuid(guid))
|
||||||
|
SdbWriteBinaryTag(pdb, tag, (BYTE*)&guid, sizeof(GUID));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::WriteString(PDB pdb, TAG tag, const sdbstring& str)
|
void Database::WriteBinary(PDB pdb, TAG tag, const std::vector<BYTE>& data, bool always)
|
||||||
{
|
{
|
||||||
SdbWriteStringTag(pdb, tag, (LPCWSTR)str.c_str());
|
if (always || !data.empty())
|
||||||
|
SdbWriteBinaryTag(pdb, tag, data.data(), data.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::WriteString(PDB pdb, TAG tag, const std::string& str)
|
void Database::WriteString(PDB pdb, TAG tag, const sdbstring& str, bool always)
|
||||||
{
|
{
|
||||||
WriteString(pdb, tag, sdbstring(str.begin(), str.end()));
|
if (always || !str.empty())
|
||||||
|
SdbWriteStringTag(pdb, tag, (LPCWSTR)str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Database::WriteString(PDB pdb, TAG tag, const std::string& str, bool always)
|
||||||
|
{
|
||||||
|
WriteString(pdb, tag, sdbstring(str.begin(), str.end()), always);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Database::WriteDWord(PDB pdb, TAG tag, DWORD value, bool always)
|
||||||
|
{
|
||||||
|
if (always || value)
|
||||||
|
SdbWriteDWORDTag(pdb, tag, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
TAGID Database::BeginWriteListTag(PDB db, TAG tag)
|
TAGID Database::BeginWriteListTag(PDB db, TAG tag)
|
||||||
|
@ -429,7 +511,7 @@ BOOL Database::EndWriteListTag(PDB db, TAGID tagid)
|
||||||
bool Database::fromXml(XMLHandle dbNode)
|
bool Database::fromXml(XMLHandle dbNode)
|
||||||
{
|
{
|
||||||
Name = ReadStringNode(dbNode, "NAME");
|
Name = ReadStringNode(dbNode, "NAME");
|
||||||
ReadBinaryNode(dbNode, "DATABASE_ID", ID);
|
ReadGuidNode(dbNode, "DATABASE_ID", ID);
|
||||||
|
|
||||||
XMLHandle libChild = dbNode.FirstChildElement("LIBRARY").FirstChild();
|
XMLHandle libChild = dbNode.FirstChildElement("LIBRARY").FirstChild();
|
||||||
while (libChild.ToNode())
|
while (libChild.ToNode())
|
||||||
|
@ -439,7 +521,7 @@ bool Database::fromXml(XMLHandle dbNode)
|
||||||
{
|
{
|
||||||
Shim shim;
|
Shim shim;
|
||||||
if (shim.fromXml(libChild))
|
if (shim.fromXml(libChild))
|
||||||
Library.push_back(shim);
|
Library.Shims.push_back(shim);
|
||||||
}
|
}
|
||||||
else if (NodeName == "FLAG")
|
else if (NodeName == "FLAG")
|
||||||
{
|
{
|
||||||
|
@ -468,12 +550,17 @@ bool Database::toSdb(LPCWSTR path)
|
||||||
LARGE_INTEGER li = { 0 };
|
LARGE_INTEGER li = { 0 };
|
||||||
RtlSecondsSince1970ToTime(time(0), &li);
|
RtlSecondsSince1970ToTime(time(0), &li);
|
||||||
SdbWriteQWORDTag(pdb, TAG_TIME, li.QuadPart);
|
SdbWriteQWORDTag(pdb, TAG_TIME, li.QuadPart);
|
||||||
WriteString(pdb, TAG_COMPILER_VERSION, "1.0.0.0");
|
WriteString(pdb, TAG_COMPILER_VERSION, szCompilerVersion);
|
||||||
SdbWriteDWORDTag(pdb, TAG_OS_PLATFORM, 1);
|
SdbWriteDWORDTag(pdb, TAG_OS_PLATFORM, 1);
|
||||||
WriteString(pdb, TAG_NAME, Name);
|
WriteString(pdb, TAG_NAME, Name, true);
|
||||||
|
if (IsEmptyGuid(ID))
|
||||||
|
{
|
||||||
|
SHIM_WARN("DB has empty ID!\n");
|
||||||
|
RandomGuid(ID);
|
||||||
|
}
|
||||||
WriteBinary(pdb, TAG_DATABASE_ID, ID);
|
WriteBinary(pdb, TAG_DATABASE_ID, ID);
|
||||||
TAGID tidLibrary = BeginWriteListTag(pdb, TAG_LIBRARY);
|
TAGID tidLibrary = BeginWriteListTag(pdb, TAG_LIBRARY);
|
||||||
if (!WriteGeneric(pdb, Library, *this))
|
if (!WriteGeneric(pdb, Library.Shims, *this))
|
||||||
return false;
|
return false;
|
||||||
EndWriteListTag(pdb, tidLibrary);
|
EndWriteListTag(pdb, tidLibrary);
|
||||||
if (!WriteGeneric(pdb, Layers, *this))
|
if (!WriteGeneric(pdb, Layers, *this))
|
||||||
|
@ -486,40 +573,50 @@ bool Database::toSdb(LPCWSTR path)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void InsertTagid(const sdbstring& name, TAGID tagid, std::map<sdbstring, TAGID>& lookup, const char* type)
|
||||||
void Database::InsertShimTagid(const sdbstring& name, TAGID tagid)
|
|
||||||
{
|
{
|
||||||
sdbstring nameLower = name;
|
sdbstring nameLower = name;
|
||||||
std::transform(nameLower.begin(), nameLower.end(), nameLower.begin(), ::tolower);
|
std::transform(nameLower.begin(), nameLower.end(), nameLower.begin(), ::tolower);
|
||||||
if (KnownShims.find(nameLower) != KnownShims.end())
|
if (lookup.find(nameLower) != lookup.end())
|
||||||
{
|
{
|
||||||
std::string nameA(name.begin(), name.end());
|
std::string nameA(name.begin(), name.end());
|
||||||
SHIM_WARN("Shim '%s' redefined\n", nameA.c_str());
|
SHIM_WARN("%s '%s' redefined\n", type, nameA.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
KnownShims[nameLower] = tagid;
|
lookup[nameLower] = tagid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::InsertShimTagid(const std::string& name, TAGID tagid)
|
static TAGID FindTagid(const sdbstring& name, const std::map<sdbstring, TAGID>& lookup)
|
||||||
{
|
|
||||||
InsertShimTagid(sdbstring(name.begin(), name.end()), tagid);
|
|
||||||
}
|
|
||||||
|
|
||||||
TAGID Database::FindShimTagid(const sdbstring& name)
|
|
||||||
{
|
{
|
||||||
sdbstring nameLower = name;
|
sdbstring nameLower = name;
|
||||||
std::transform(nameLower.begin(), nameLower.end(), nameLower.begin(), ::tolower);
|
std::transform(nameLower.begin(), nameLower.end(), nameLower.begin(), ::tolower);
|
||||||
std::map<sdbstring, TAGID>::iterator it = KnownShims.find(nameLower);
|
std::map<sdbstring, TAGID>::const_iterator it = lookup.find(nameLower);
|
||||||
if (it == KnownShims.end())
|
if (it == lookup.end())
|
||||||
return 0;
|
return 0;
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
TAGID Database::FindShimTagid(const std::string& name)
|
void Database::InsertShimTagid(const sdbstring& name, TAGID tagid)
|
||||||
{
|
{
|
||||||
return FindShimTagid(sdbstring(name.begin(), name.end()));
|
InsertTagid(name, tagid, KnownShims, "Shim");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TAGID Database::FindShimTagid(const sdbstring& name)
|
||||||
|
{
|
||||||
|
return FindTagid(name, KnownShims);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Database::InsertPatchTagid(const sdbstring& name, TAGID tagid)
|
||||||
|
{
|
||||||
|
InsertTagid(name, tagid, KnownPatches, "Patch");
|
||||||
|
}
|
||||||
|
|
||||||
|
TAGID Database::FindPatchTagid(const sdbstring& name)
|
||||||
|
{
|
||||||
|
return FindTagid(name, KnownPatches);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool xml_2_db(const char* xml, const WCHAR* sdb)
|
bool xml_2_db(const char* xml, const WCHAR* sdb)
|
||||||
{
|
{
|
||||||
|
|
|
@ -71,13 +71,19 @@ struct Layer
|
||||||
|
|
||||||
struct MatchingFile
|
struct MatchingFile
|
||||||
{
|
{
|
||||||
|
MatchingFile() : Size(0), Checksum(0) {;}
|
||||||
|
|
||||||
bool fromXml(XMLHandle dbNode);
|
bool fromXml(XMLHandle dbNode);
|
||||||
bool toSdb(PDB pdb, Database& db);
|
bool toSdb(PDB pdb, Database& db);
|
||||||
|
|
||||||
std::string Name;
|
std::string Name;
|
||||||
|
DWORD Size;
|
||||||
|
DWORD Checksum;
|
||||||
std::string CompanyName;
|
std::string CompanyName;
|
||||||
|
std::string InternalName;
|
||||||
std::string ProductName;
|
std::string ProductName;
|
||||||
std::string ProductVersion;
|
std::string ProductVersion;
|
||||||
|
std::string FileVersion;
|
||||||
std::string BinFileVersion;
|
std::string BinFileVersion;
|
||||||
std::string LinkDate;
|
std::string LinkDate;
|
||||||
std::string VerLanguage;
|
std::string VerLanguage;
|
||||||
|
@ -95,12 +101,19 @@ struct Exe
|
||||||
bool toSdb(PDB pdb, Database& db);
|
bool toSdb(PDB pdb, Database& db);
|
||||||
|
|
||||||
std::string Name;
|
std::string Name;
|
||||||
|
GUID ExeID;
|
||||||
std::string AppName;
|
std::string AppName;
|
||||||
std::string Vendor;
|
std::string Vendor;
|
||||||
TAGID Tagid;
|
TAGID Tagid;
|
||||||
|
std::list<MatchingFile> MatchingFiles;
|
||||||
std::list<ShimRef> ShimRefs;
|
std::list<ShimRef> ShimRefs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Library
|
||||||
|
{
|
||||||
|
std::list<Shim> Shims;
|
||||||
|
};
|
||||||
|
|
||||||
struct Database
|
struct Database
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -108,25 +121,34 @@ struct Database
|
||||||
bool fromXml(XMLHandle dbNode);
|
bool fromXml(XMLHandle dbNode);
|
||||||
bool toSdb(LPCWSTR path);
|
bool toSdb(LPCWSTR path);
|
||||||
|
|
||||||
void WriteString(PDB pdb, TAG tag, const sdbstring& str);
|
void WriteString(PDB pdb, TAG tag, const sdbstring& str, bool always = false);
|
||||||
void WriteString(PDB pdb, TAG tag, const std::string& str);
|
void WriteString(PDB pdb, TAG tag, const std::string& str, bool always = false);
|
||||||
void WriteBinary(PDB pdb, TAG tag, const GUID& guid);
|
void WriteBinary(PDB pdb, TAG tag, const GUID& guid, bool always = false);
|
||||||
|
void WriteBinary(PDB pdb, TAG tag, const std::vector<BYTE>& data, bool always = false);
|
||||||
|
void WriteDWord(PDB pdb, TAG tag, DWORD value, bool always = false);
|
||||||
TAGID BeginWriteListTag(PDB db, TAG tag);
|
TAGID BeginWriteListTag(PDB db, TAG tag);
|
||||||
BOOL EndWriteListTag(PDB db, TAGID tagid);
|
BOOL EndWriteListTag(PDB db, TAGID tagid);
|
||||||
|
|
||||||
void InsertShimTagid(const sdbstring& name, TAGID tagid);
|
void InsertShimTagid(const sdbstring& name, TAGID tagid);
|
||||||
void InsertShimTagid(const std::string& name, TAGID tagid);
|
inline void InsertShimTagid(const std::string& name, TAGID tagid)
|
||||||
|
{
|
||||||
|
InsertShimTagid(sdbstring(name.begin(), name.end()), tagid);
|
||||||
|
}
|
||||||
TAGID FindShimTagid(const sdbstring& name);
|
TAGID FindShimTagid(const sdbstring& name);
|
||||||
TAGID FindShimTagid(const std::string& name);
|
inline TAGID FindShimTagid(const std::string& name)
|
||||||
|
{
|
||||||
|
return FindShimTagid(sdbstring(name.begin(), name.end()));
|
||||||
|
}
|
||||||
|
|
||||||
std::string Name;
|
std::string Name;
|
||||||
GUID ID;
|
GUID ID;
|
||||||
|
|
||||||
std::list<Shim> Library;
|
struct Library Library;
|
||||||
std::list<Layer> Layers;
|
std::list<Layer> Layers;
|
||||||
std::list<Exe> Exes;
|
std::list<Exe> Exes;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<sdbstring, TAGID> KnownShims;
|
std::map<sdbstring, TAGID> KnownShims;
|
||||||
|
std::map<sdbstring, TAGID> KnownPatches;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue