mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 22:46:43 +00:00
Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.
This commit is contained in:
parent
b94e2d8ca0
commit
c2c66aff7d
24198 changed files with 0 additions and 37285 deletions
628
sdk/tools/xml2sdb/xml2sdb.cpp
Normal file
628
sdk/tools/xml2sdb/xml2sdb.cpp
Normal file
|
@ -0,0 +1,628 @@
|
|||
/*
|
||||
* PROJECT: xml2sdb
|
||||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||
* PURPOSE: Conversion functions from xml -> db
|
||||
* COPYRIGHT: Copyright 2016,2017 Mark Jansen (mark.jansen@reactos.org)
|
||||
*/
|
||||
|
||||
#include "xml2sdb.h"
|
||||
#include "sdbpapi.h"
|
||||
#include "tinyxml2.h"
|
||||
#include <time.h>
|
||||
#include <algorithm>
|
||||
|
||||
using tinyxml2::XMLText;
|
||||
|
||||
static const GUID GUID_NULL = { 0 };
|
||||
static const char szCompilerVersion[] = "1.6.0.0";
|
||||
|
||||
#if !defined(C_ASSERT)
|
||||
#define C_ASSERT(expr) extern char (*c_assert(void)) [(expr) ? 1 : -1]
|
||||
#endif
|
||||
|
||||
|
||||
C_ASSERT(sizeof(GUID) == 16);
|
||||
C_ASSERT(sizeof(ULONG) == 4);
|
||||
C_ASSERT(sizeof(LARGE_INTEGER) == 8);
|
||||
C_ASSERT(sizeof(WCHAR) == 2);
|
||||
C_ASSERT(sizeof(wchar_t) == 2);
|
||||
C_ASSERT(sizeof(TAG) == 2);
|
||||
C_ASSERT(sizeof(TAGID) == 4);
|
||||
|
||||
|
||||
extern "C"
|
||||
VOID NTAPI RtlSecondsSince1970ToTime(IN ULONG SecondsSince1970,
|
||||
OUT PLARGE_INTEGER Time);
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Helper functions
|
||||
*/
|
||||
|
||||
|
||||
// Convert utf8 to utf16:
|
||||
// http://stackoverflow.com/a/7154226/4928207
|
||||
|
||||
bool IsEmptyGuid(const GUID& g)
|
||||
{
|
||||
return !memcmp(&g, &GUID_NULL, sizeof(GUID));
|
||||
}
|
||||
|
||||
void RandomGuid(GUID& g)
|
||||
{
|
||||
BYTE* p = (BYTE*)&g;
|
||||
for (size_t n = 0; n < sizeof(GUID); ++n)
|
||||
p[n] = (BYTE)(rand() % 0xff);
|
||||
}
|
||||
|
||||
// Given a node, return the node value (safe)
|
||||
std::string ToString(XMLHandle node)
|
||||
{
|
||||
XMLText* txtNode = node.FirstChild().ToText();
|
||||
const char* txt = txtNode ? txtNode->Value() : NULL;
|
||||
if (txt)
|
||||
return std::string(txt);
|
||||
return std::string();
|
||||
}
|
||||
|
||||
// Given a node, return the node name (safe)
|
||||
std::string ToNodeName(XMLHandle node)
|
||||
{
|
||||
tinyxml2::XMLNode* raw = node.ToNode();
|
||||
const char* txt = raw ? raw->Value() : NULL;
|
||||
if (txt)
|
||||
return std::string(txt);
|
||||
return std::string();
|
||||
}
|
||||
|
||||
// Read either an attribute, or a child node
|
||||
std::string ReadStringNode(XMLHandle dbNode, const char* nodeName)
|
||||
{
|
||||
tinyxml2::XMLElement* elem = dbNode.ToElement();
|
||||
if (elem)
|
||||
{
|
||||
const char* rawVal = elem->Attribute(nodeName);
|
||||
if (rawVal)
|
||||
return std::string(rawVal);
|
||||
}
|
||||
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
|
||||
static bool StringToGuid(const std::string& str, GUID& guid)
|
||||
{
|
||||
const char *lpszGUID = str.c_str();
|
||||
BYTE* lpOut = (BYTE*)&guid;
|
||||
int i = 0;
|
||||
bool expectBrace = true;
|
||||
while (i <= 37)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
if (*lpszGUID != '{')
|
||||
{
|
||||
i++;
|
||||
expectBrace = false;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case 9:
|
||||
case 14:
|
||||
case 19:
|
||||
case 24:
|
||||
if (*lpszGUID != '-')
|
||||
return false;
|
||||
break;
|
||||
|
||||
case 37:
|
||||
return expectBrace == (*lpszGUID == '}');
|
||||
|
||||
default:
|
||||
{
|
||||
CHAR ch = *lpszGUID, ch2 = lpszGUID[1];
|
||||
unsigned char byte;
|
||||
bool converted = true;
|
||||
|
||||
byte = char2byte(ch, &converted) << 4 | char2byte(ch2, &converted);
|
||||
if (!converted)
|
||||
return false;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
/* For Big Endian machines, we store the data such that the
|
||||
* dword/word members can be read as DWORDS and WORDS correctly. */
|
||||
/* Dword */
|
||||
case 1:
|
||||
lpOut[3] = byte;
|
||||
break;
|
||||
case 3:
|
||||
lpOut[2] = byte;
|
||||
break;
|
||||
case 5:
|
||||
lpOut[1] = byte;
|
||||
break;
|
||||
case 7:
|
||||
lpOut[0] = byte;
|
||||
lpOut += 4;
|
||||
break;
|
||||
/* Word */
|
||||
case 10:
|
||||
case 15:
|
||||
lpOut[1] = byte;
|
||||
break;
|
||||
case 12:
|
||||
case 17:
|
||||
lpOut[0] = byte;
|
||||
lpOut += 2;
|
||||
break;
|
||||
#endif
|
||||
/* Byte */
|
||||
default:
|
||||
lpOut[0] = byte;
|
||||
lpOut++;
|
||||
break;
|
||||
}
|
||||
|
||||
lpszGUID++; /* Skip 2nd character of byte */
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
lpszGUID++;
|
||||
i++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ReadGuidNode(XMLHandle dbNode, const char* nodeName, GUID& guid)
|
||||
{
|
||||
std::string value = ReadStringNode(dbNode, nodeName);
|
||||
if (!StringToGuid(value, guid))
|
||||
{
|
||||
memset(&guid, 0, sizeof(GUID));
|
||||
return false;
|
||||
}
|
||||
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
|
||||
*/
|
||||
|
||||
bool InExclude::fromXml(XMLHandle dbNode)
|
||||
{
|
||||
Module = ReadStringNode(dbNode, "MODULE");
|
||||
// Special module names: '$' and '*'
|
||||
if (!Module.empty())
|
||||
{
|
||||
Include = ToNodeName(dbNode) == "INCLUDE";
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InExclude::toSdb(PDB pdb, Database& db)
|
||||
{
|
||||
TAGID tagid = db.BeginWriteListTag(pdb, TAG_INEXCLUD);
|
||||
db.WriteString(pdb, TAG_MODULE, Module, true);
|
||||
if (Include)
|
||||
SdbWriteNULLTag(pdb, TAG_INCLUDE);
|
||||
return !!db.EndWriteListTag(pdb, tagid);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
void ReadGeneric(XMLHandle dbNode, std::list<T>& result, const char* nodeName)
|
||||
{
|
||||
XMLHandle node = dbNode.FirstChildElement(nodeName);
|
||||
while (node.ToNode())
|
||||
{
|
||||
T object;
|
||||
if (object.fromXml(node))
|
||||
result.push_back(object);
|
||||
|
||||
node = node.NextSiblingElement(nodeName);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool WriteGeneric(PDB pdb, std::list<T>& data, Database& db)
|
||||
{
|
||||
for (typename std::list<T>::iterator it = data.begin(); it != data.end(); ++it)
|
||||
{
|
||||
if (!it->toSdb(pdb, db))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* ShimRef
|
||||
*/
|
||||
|
||||
bool ShimRef::fromXml(XMLHandle dbNode)
|
||||
{
|
||||
Name = ReadStringNode(dbNode, "NAME");
|
||||
CommandLine = ReadStringNode(dbNode, "COMMAND_LINE");
|
||||
ReadGeneric(dbNode, InExcludes, "INCLUDE");
|
||||
ReadGeneric(dbNode, InExcludes, "EXCLUDE");
|
||||
return !Name.empty();
|
||||
}
|
||||
|
||||
bool ShimRef::toSdb(PDB pdb, Database& db)
|
||||
{
|
||||
TAGID tagid = db.BeginWriteListTag(pdb, TAG_SHIM_REF);
|
||||
db.WriteString(pdb, TAG_NAME, Name, true);
|
||||
db.WriteString(pdb, TAG_COMMAND_LINE, CommandLine);
|
||||
|
||||
if (!ShimTagid)
|
||||
ShimTagid = db.FindShimTagid(Name);
|
||||
SdbWriteDWORDTag(pdb, TAG_SHIM_TAGID, ShimTagid);
|
||||
return !!db.EndWriteListTag(pdb, tagid);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Shim
|
||||
*/
|
||||
|
||||
bool Shim::fromXml(XMLHandle dbNode)
|
||||
{
|
||||
Name = ReadStringNode(dbNode, "NAME");
|
||||
DllFile = ReadStringNode(dbNode, "DLLFILE");
|
||||
ReadGuidNode(dbNode, "FIX_ID", FixID);
|
||||
// GENERAL ?
|
||||
// DESCRIPTION_RC_ID
|
||||
ReadGeneric(dbNode, InExcludes, "INCLUDE");
|
||||
ReadGeneric(dbNode, InExcludes, "EXCLUDE");
|
||||
return !Name.empty() && !DllFile.empty();
|
||||
}
|
||||
|
||||
bool Shim::toSdb(PDB pdb, Database& db)
|
||||
{
|
||||
Tagid = db.BeginWriteListTag(pdb, TAG_SHIM);
|
||||
db.InsertShimTagid(Name, Tagid);
|
||||
db.WriteString(pdb, TAG_NAME, Name);
|
||||
db.WriteString(pdb, TAG_DLLFILE, DllFile);
|
||||
if (IsEmptyGuid(FixID))
|
||||
RandomGuid(FixID);
|
||||
db.WriteBinary(pdb, TAG_FIX_ID, FixID);
|
||||
if (!WriteGeneric(pdb, InExcludes, db))
|
||||
return false;
|
||||
return !!db.EndWriteListTag(pdb, Tagid);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Layer
|
||||
*/
|
||||
|
||||
bool Layer::fromXml(XMLHandle dbNode)
|
||||
{
|
||||
Name = ReadStringNode(dbNode, "NAME");
|
||||
ReadGeneric(dbNode, ShimRefs, "SHIM_REF");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Layer::toSdb(PDB pdb, Database& db)
|
||||
{
|
||||
Tagid = db.BeginWriteListTag(pdb, TAG_LAYER);
|
||||
db.WriteString(pdb, TAG_NAME, Name, true);
|
||||
if (!WriteGeneric(pdb, ShimRefs, db))
|
||||
return false;
|
||||
return !!db.EndWriteListTag(pdb, Tagid);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* MatchingFile
|
||||
*/
|
||||
|
||||
bool MatchingFile::fromXml(XMLHandle dbNode)
|
||||
{
|
||||
Name = ReadStringNode(dbNode, "NAME");
|
||||
Size = ReadDWordNode(dbNode, "SIZE");
|
||||
Checksum = ReadDWordNode(dbNode, "CHECKSUM");
|
||||
CompanyName = ReadStringNode(dbNode, "COMPANY_NAME");
|
||||
InternalName = ReadStringNode(dbNode, "INTERNAL_NAME");
|
||||
ProductName = ReadStringNode(dbNode, "PRODUCT_NAME");
|
||||
ProductVersion = ReadStringNode(dbNode, "PRODUCT_VERSION");
|
||||
FileVersion = ReadStringNode(dbNode, "FILE_VERSION");
|
||||
BinFileVersion = ReadStringNode(dbNode, "BIN_FILE_VERSION");
|
||||
LinkDate = ReadStringNode(dbNode, "LINK_DATE");
|
||||
VerLanguage = ReadStringNode(dbNode, "VER_LANGUAGE");
|
||||
FileDescription = ReadStringNode(dbNode, "FILE_DESCRIPTION");
|
||||
OriginalFilename = ReadStringNode(dbNode, "ORIGINAL_FILENAME");
|
||||
UptoBinFileVersion = ReadStringNode(dbNode, "UPTO_BIN_FILE_VERSION");
|
||||
LinkerVersion = ReadStringNode(dbNode, "LINKER_VERSION");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MatchingFile::toSdb(PDB pdb, Database& db)
|
||||
{
|
||||
TAGID tagid = db.BeginWriteListTag(pdb, TAG_MATCHING_FILE);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Exe
|
||||
*/
|
||||
|
||||
bool Exe::fromXml(XMLHandle dbNode)
|
||||
{
|
||||
Name = ReadStringNode(dbNode, "NAME");
|
||||
ReadGuidNode(dbNode, "EXE_ID", ExeID);
|
||||
AppName = ReadStringNode(dbNode, "APP_NAME");
|
||||
Vendor = ReadStringNode(dbNode, "VENDOR");
|
||||
|
||||
ReadGeneric(dbNode, MatchingFiles, "MATCHING_FILE");
|
||||
|
||||
ReadGeneric(dbNode, ShimRefs, "SHIM_REF");
|
||||
|
||||
return !Name.empty();
|
||||
}
|
||||
|
||||
bool Exe::toSdb(PDB pdb, Database& db)
|
||||
{
|
||||
Tagid = db.BeginWriteListTag(pdb, TAG_EXE);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Database
|
||||
*/
|
||||
|
||||
void Database::WriteBinary(PDB pdb, TAG tag, const GUID& guid, bool always)
|
||||
{
|
||||
if (always || !IsEmptyGuid(guid))
|
||||
SdbWriteBinaryTag(pdb, tag, (BYTE*)&guid, sizeof(GUID));
|
||||
}
|
||||
|
||||
void Database::WriteBinary(PDB pdb, TAG tag, const std::vector<BYTE>& data, bool always)
|
||||
{
|
||||
if (always || !data.empty())
|
||||
SdbWriteBinaryTag(pdb, tag, data.data(), data.size());
|
||||
}
|
||||
|
||||
void Database::WriteString(PDB pdb, TAG tag, const sdbstring& str, bool always)
|
||||
{
|
||||
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 pdb, TAG tag)
|
||||
{
|
||||
return SdbBeginWriteListTag(pdb, tag);
|
||||
}
|
||||
|
||||
BOOL Database::EndWriteListTag(PDB pdb, TAGID tagid)
|
||||
{
|
||||
return SdbEndWriteListTag(pdb, tagid);
|
||||
}
|
||||
|
||||
bool Database::fromXml(XMLHandle dbNode)
|
||||
{
|
||||
Name = ReadStringNode(dbNode, "NAME");
|
||||
ReadGuidNode(dbNode, "DATABASE_ID", ID);
|
||||
|
||||
XMLHandle libChild = dbNode.FirstChildElement("LIBRARY").FirstChild();
|
||||
while (libChild.ToNode())
|
||||
{
|
||||
std::string NodeName = ToNodeName(libChild);
|
||||
if (NodeName == "SHIM")
|
||||
{
|
||||
Shim shim;
|
||||
if (shim.fromXml(libChild))
|
||||
Library.Shims.push_back(shim);
|
||||
}
|
||||
else if (NodeName == "FLAG")
|
||||
{
|
||||
SHIM_ERR("Unhanled FLAG type\n");
|
||||
}
|
||||
else if (NodeName == "INCLUDE" || NodeName == "EXCLUDE")
|
||||
{
|
||||
InExclude inex;
|
||||
if (inex.fromXml(libChild))
|
||||
Library.InExcludes.push_back(inex);
|
||||
}
|
||||
libChild = libChild.NextSibling();
|
||||
}
|
||||
|
||||
ReadGeneric(dbNode, Layers, "LAYER");
|
||||
ReadGeneric(dbNode, Exes, "EXE");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Database::fromXml(const char* fileName)
|
||||
{
|
||||
tinyxml2::XMLDocument doc;
|
||||
tinyxml2::XMLError err = doc.LoadFile(fileName);
|
||||
XMLHandle dbHandle = tinyxml2::XMLHandle(&doc).FirstChildElement("SDB").FirstChildElement("DATABASE");
|
||||
return fromXml(dbHandle);
|
||||
}
|
||||
|
||||
bool Database::toSdb(LPCWSTR path)
|
||||
{
|
||||
PDB pdb = SdbCreateDatabase(path, DOS_PATH);
|
||||
TAGID tidDatabase = BeginWriteListTag(pdb, TAG_DATABASE);
|
||||
LARGE_INTEGER li = { 0 };
|
||||
RtlSecondsSince1970ToTime(time(0), &li);
|
||||
SdbWriteQWORDTag(pdb, TAG_TIME, li.QuadPart);
|
||||
WriteString(pdb, TAG_COMPILER_VERSION, szCompilerVersion);
|
||||
SdbWriteDWORDTag(pdb, TAG_OS_PLATFORM, 1);
|
||||
WriteString(pdb, TAG_NAME, Name, true);
|
||||
if (IsEmptyGuid(ID))
|
||||
{
|
||||
SHIM_WARN("DB has empty ID!\n");
|
||||
RandomGuid(ID);
|
||||
}
|
||||
WriteBinary(pdb, TAG_DATABASE_ID, ID);
|
||||
TAGID tidLibrary = BeginWriteListTag(pdb, TAG_LIBRARY);
|
||||
if (!WriteGeneric(pdb, Library.InExcludes, *this))
|
||||
return false;
|
||||
if (!WriteGeneric(pdb, Library.Shims, *this))
|
||||
return false;
|
||||
EndWriteListTag(pdb, tidLibrary);
|
||||
if (!WriteGeneric(pdb, Layers, *this))
|
||||
return false;
|
||||
if (!WriteGeneric(pdb, Exes, *this))
|
||||
return false;
|
||||
EndWriteListTag(pdb, tidDatabase);
|
||||
|
||||
SdbCloseDatabaseWrite(pdb);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void InsertTagid(const sdbstring& name, TAGID tagid, std::map<sdbstring, TAGID>& lookup, const char* type)
|
||||
{
|
||||
sdbstring nameLower = name;
|
||||
std::transform(nameLower.begin(), nameLower.end(), nameLower.begin(), ::tolower);
|
||||
if (lookup.find(nameLower) != lookup.end())
|
||||
{
|
||||
std::string nameA(name.begin(), name.end());
|
||||
SHIM_WARN("%s '%s' redefined\n", type, nameA.c_str());
|
||||
return;
|
||||
}
|
||||
lookup[nameLower] = tagid;
|
||||
}
|
||||
|
||||
static TAGID FindTagid(const sdbstring& name, const std::map<sdbstring, TAGID>& lookup)
|
||||
{
|
||||
sdbstring nameLower = name;
|
||||
std::transform(nameLower.begin(), nameLower.end(), nameLower.begin(), ::tolower);
|
||||
std::map<sdbstring, TAGID>::const_iterator it = lookup.find(nameLower);
|
||||
if (it == lookup.end())
|
||||
return 0;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void Database::InsertShimTagid(const sdbstring& name, TAGID tagid)
|
||||
{
|
||||
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)
|
||||
{
|
||||
Database db;
|
||||
if (db.fromXml(xml))
|
||||
{
|
||||
return db.toSdb((LPCWSTR)sdb);
|
||||
}
|
||||
return false;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue