mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 18:13:03 +00:00
* Create a branch for USB experiments.
svn path=/branches/usb-experiments/; revision=72629
This commit is contained in:
parent
28d8ba0d3e
commit
0ee830d7a4
23049 changed files with 0 additions and 1313991 deletions
19
sdk/tools/xml2sdb/CMakeLists.txt
Normal file
19
sdk/tools/xml2sdb/CMakeLists.txt
Normal file
|
@ -0,0 +1,19 @@
|
|||
|
||||
add_definitions(-DSDBWRITE_HOSTTOOL=1)
|
||||
|
||||
if(MSVC)
|
||||
set_property(SOURCE main.cpp tinyxml2.cpp xml2sdb.cpp APPEND_STRING PROPERTY COMPILE_FLAGS " /EHsc")
|
||||
else()
|
||||
add_compile_flags("-fshort-wchar -Wno-multichar")
|
||||
endif()
|
||||
|
||||
|
||||
list(APPEND SOURCE
|
||||
main.cpp
|
||||
tinyxml2.cpp
|
||||
xml2sdb.cpp
|
||||
${REACTOS_SOURCE_DIR}/dll/appcompat/apphelp/sdbwrite.c
|
||||
${REACTOS_SOURCE_DIR}/dll/appcompat/apphelp/sdbstringtable.c)
|
||||
|
||||
include_directories(${REACTOS_SOURCE_DIR}/dll/appcompat/apphelp)
|
||||
add_host_tool(xml2sdb ${SOURCE})
|
229
sdk/tools/xml2sdb/main.cpp
Normal file
229
sdk/tools/xml2sdb/main.cpp
Normal file
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS xml to sdb converter
|
||||
* FILE: sdk/tools/xml2sdb/main.cpp
|
||||
* PURPOSE: Implement platform agnostic read / write / allocation functions, parse commandline
|
||||
* PROGRAMMERS: Mark Jansen
|
||||
*
|
||||
*/
|
||||
|
||||
#include "xml2sdb.h"
|
||||
#include "sdbpapi.h"
|
||||
#include "sdbstringtable.h"
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
ULONG g_ShimDebugLevel = SHIM_WARN;
|
||||
|
||||
LPVOID WINAPI SdbpAlloc(SIZE_T size)
|
||||
{
|
||||
return ::calloc(1, size);
|
||||
}
|
||||
|
||||
LPVOID WINAPI SdbpReAlloc(LPVOID mem, SIZE_T size, SIZE_T oldSize)
|
||||
{
|
||||
LPVOID newMem = ::realloc(mem, size);
|
||||
if (newMem && size > oldSize)
|
||||
{
|
||||
memset((BYTE*)newMem + oldSize, 0, size - oldSize);
|
||||
}
|
||||
return newMem;
|
||||
}
|
||||
|
||||
void WINAPI SdbpFree(LPVOID mem)
|
||||
{
|
||||
return ::free(mem);
|
||||
}
|
||||
|
||||
DWORD SdbpStrlen(PCWSTR string)
|
||||
{
|
||||
size_t len = 0;
|
||||
while (string[len])
|
||||
len++;
|
||||
return len;
|
||||
}
|
||||
|
||||
DWORD WINAPI SdbpStrsize(PCWSTR string)
|
||||
{
|
||||
return (SdbpStrlen(string) + 1) * sizeof(WCHAR);
|
||||
}
|
||||
|
||||
PDB WINAPI SdbpCreate(LPCWSTR path, PATH_TYPE type, BOOL write)
|
||||
{
|
||||
PDB db;
|
||||
FILE* f;
|
||||
std::string pathA(path, path + SdbpStrlen(path));
|
||||
|
||||
f = fopen(pathA.c_str(), write ? "wb" : "rb");
|
||||
if (!f)
|
||||
return NULL;
|
||||
|
||||
db = (PDB)SdbAlloc(sizeof(DB));
|
||||
db->file = f;
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
void WINAPI SdbpFlush(PDB db)
|
||||
{
|
||||
fwrite(db->data, db->write_iter, 1, (FILE*)db->file);
|
||||
}
|
||||
|
||||
void WINAPI SdbCloseDatabase(PDB db)
|
||||
{
|
||||
if (!db)
|
||||
return;
|
||||
|
||||
if (db->file)
|
||||
fclose((FILE*)db->file);
|
||||
if (db->string_buffer)
|
||||
SdbCloseDatabase(db->string_buffer);
|
||||
if (db->string_lookup)
|
||||
SdbpTableDestroy(&db->string_lookup);
|
||||
SdbFree(db->data);
|
||||
SdbFree(db);
|
||||
}
|
||||
|
||||
BOOL WINAPI SdbpCheckTagType(TAG tag, WORD type)
|
||||
{
|
||||
if ((tag & TAG_TYPE_MASK) != type)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WINAPI SdbpReadData(PDB db, PVOID dest, DWORD offset, DWORD num)
|
||||
{
|
||||
DWORD size = offset + num;
|
||||
|
||||
/* Either overflow or no data to read */
|
||||
if (size <= offset)
|
||||
return FALSE;
|
||||
|
||||
/* Overflow */
|
||||
if (db->size < size)
|
||||
return FALSE;
|
||||
|
||||
memcpy(dest, db->data + offset, num);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
TAG WINAPI SdbGetTagFromTagID(PDB db, TAGID tagid)
|
||||
{
|
||||
TAG data;
|
||||
if (!SdbpReadData(db, &data, tagid, sizeof(data)))
|
||||
return TAG_NULL;
|
||||
return data;
|
||||
}
|
||||
|
||||
BOOL WINAPI SdbpCheckTagIDType(PDB db, TAGID tagid, WORD type)
|
||||
{
|
||||
TAG tag = SdbGetTagFromTagID(db, tagid);
|
||||
if (tag == TAG_NULL)
|
||||
return FALSE;
|
||||
return SdbpCheckTagType(tag, type);
|
||||
}
|
||||
|
||||
BOOL WINAPIV ShimDbgPrint(SHIM_LOG_LEVEL Level, PCSTR FunctionName, PCSTR Format, ...)
|
||||
{
|
||||
va_list ArgList;
|
||||
const char* LevelStr;
|
||||
|
||||
if (Level > g_ShimDebugLevel)
|
||||
return FALSE;
|
||||
|
||||
switch (Level)
|
||||
{
|
||||
case SHIM_ERR:
|
||||
LevelStr = "Err ";
|
||||
break;
|
||||
case SHIM_WARN:
|
||||
LevelStr = "Warn";
|
||||
break;
|
||||
case SHIM_INFO:
|
||||
LevelStr = "Info";
|
||||
break;
|
||||
default:
|
||||
LevelStr = "User";
|
||||
break;
|
||||
}
|
||||
printf("[%s][%-20s] ", LevelStr, FunctionName);
|
||||
va_start(ArgList, Format);
|
||||
vprintf(Format, ArgList);
|
||||
va_end(ArgList);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
#define TICKSPERSEC 10000000
|
||||
#if defined(__GNUC__)
|
||||
#define TICKSTO1970 0x019db1ded53e8000LL
|
||||
#else
|
||||
#define TICKSTO1970 0x019db1ded53e8000i64
|
||||
#endif
|
||||
VOID NTAPI RtlSecondsSince1970ToTime(IN ULONG SecondsSince1970,
|
||||
OUT PLARGE_INTEGER Time)
|
||||
{
|
||||
Time->QuadPart = ((LONGLONG)SecondsSince1970 * TICKSPERSEC) + TICKSTO1970;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool xml_2_db(const char* xml, const WCHAR* sdb);
|
||||
|
||||
static bool run_one(std::string& input, std::string& output)
|
||||
{
|
||||
sdbstring outputW(output.begin(), output.end());
|
||||
if (!xml_2_db(input.c_str(), outputW.c_str()))
|
||||
return false;
|
||||
input = output = "";
|
||||
return true;
|
||||
}
|
||||
|
||||
static std::string get_strarg(int argc, char* argv[], int& i)
|
||||
{
|
||||
if (argv[i][2] == 0)
|
||||
{
|
||||
++i;
|
||||
if (i >= argc || !argv[i])
|
||||
return std::string();
|
||||
return argv[i];
|
||||
}
|
||||
return std::string(argv[i] + 2);
|
||||
}
|
||||
|
||||
// -i R:\src\apphelp\reactos\media\sdb\sysmain.xml -oR:\build\apphelp\devenv_msvc\media\sdb\ros2.sdb
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
std::string input, output;
|
||||
srand(time(0));
|
||||
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
if (argv[i][0] == '/' || argv[i][0] == '-')
|
||||
{
|
||||
switch(argv[i][1])
|
||||
{
|
||||
case 'i':
|
||||
input = get_strarg(argc, argv, i);
|
||||
break;
|
||||
case 'o':
|
||||
output = get_strarg(argc, argv, i);
|
||||
break;
|
||||
}
|
||||
if (!input.empty() && !output.empty())
|
||||
{
|
||||
if (!run_one(input, output))
|
||||
{
|
||||
printf("Failed converting '%s' to '%s'\n", input.c_str(), output.c_str());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
2467
sdk/tools/xml2sdb/tinyxml2.cpp
Normal file
2467
sdk/tools/xml2sdb/tinyxml2.cpp
Normal file
File diff suppressed because it is too large
Load diff
2102
sdk/tools/xml2sdb/tinyxml2.h
Normal file
2102
sdk/tools/xml2sdb/tinyxml2.h
Normal file
File diff suppressed because it is too large
Load diff
532
sdk/tools/xml2sdb/xml2sdb.cpp
Normal file
532
sdk/tools/xml2sdb/xml2sdb.cpp
Normal file
|
@ -0,0 +1,532 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS xml to sdb converter
|
||||
* FILE: sdk/tools/xml2sdb/xml2sdb.cpp
|
||||
* PURPOSE: Main conversion functions from xml -> db
|
||||
* PROGRAMMERS: Mark Jansen
|
||||
*
|
||||
*/
|
||||
|
||||
#include "xml2sdb.h"
|
||||
#include "sdbpapi.h"
|
||||
#include "tinyxml2.h"
|
||||
#include <time.h>
|
||||
#include <algorithm>
|
||||
|
||||
using tinyxml2::XMLText;
|
||||
|
||||
static const GUID GUID_NULL = { 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(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));
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
/* Read two hex digits as a byte value */
|
||||
if (ch >= '0' && ch <= '9')
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
#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 ReadBinaryNode(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;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* InExclude
|
||||
*/
|
||||
|
||||
bool InExclude::fromXml(XMLHandle dbNode)
|
||||
{
|
||||
Module = ReadStringNode(dbNode, "MODULE");
|
||||
if (!Module.empty())
|
||||
{
|
||||
Include = dbNode.FirstChildElement("INCLUDE").ToNode() != NULL;
|
||||
if (!Include)
|
||||
{
|
||||
tinyxml2::XMLElement* elem = dbNode.ToElement();
|
||||
if (elem)
|
||||
{
|
||||
Include |= (elem->Attribute("INCLUDE") != NULL);
|
||||
}
|
||||
}
|
||||
// $ = ??
|
||||
// *
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InExclude::toSdb(PDB pdb, Database& db)
|
||||
{
|
||||
TAGID tagid = db.BeginWriteListTag(pdb, TAG_INEXCLUD);
|
||||
db.WriteString(pdb, TAG_MODULE, Module);
|
||||
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, "INEXCLUDE");
|
||||
return !Name.empty();
|
||||
}
|
||||
|
||||
bool ShimRef::toSdb(PDB pdb, Database& db)
|
||||
{
|
||||
TAGID tagid = db.BeginWriteListTag(pdb, TAG_SHIM_REF);
|
||||
db.WriteString(pdb, TAG_NAME, Name);
|
||||
if (!CommandLine.empty())
|
||||
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");
|
||||
ReadBinaryNode(dbNode, "FIX_ID", FixID);
|
||||
// GENERAL ?
|
||||
// DESCRIPTION_RC_ID
|
||||
ReadGeneric(dbNode, InExcludes, "INEXCLUDE");
|
||||
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);
|
||||
if (!WriteGeneric(pdb, ShimRefs, db))
|
||||
return false;
|
||||
return !!db.EndWriteListTag(pdb, Tagid);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* MatchingFile
|
||||
*/
|
||||
|
||||
bool MatchingFile::fromXml(XMLHandle dbNode)
|
||||
{
|
||||
Name = ReadStringNode(dbNode, "NAME");
|
||||
CompanyName = ReadStringNode(dbNode, "COMPANY_NAME");
|
||||
ProductName = ReadStringNode(dbNode, "PRODUCT_NAME");
|
||||
ProductVersion = ReadStringNode(dbNode, "PRODUCT_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);
|
||||
SHIM_ERR("Unimplemented\n");
|
||||
|
||||
return !!db.EndWriteListTag(pdb, tagid);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Exe
|
||||
*/
|
||||
|
||||
bool Exe::fromXml(XMLHandle dbNode)
|
||||
{
|
||||
Name = ReadStringNode(dbNode, "NAME");
|
||||
AppName = ReadStringNode(dbNode, "APP_NAME");
|
||||
Vendor = ReadStringNode(dbNode, "VENDOR");
|
||||
|
||||
ReadGeneric(dbNode, ShimRefs, "SHIM_REF");
|
||||
|
||||
return !Name.empty();
|
||||
}
|
||||
|
||||
bool Exe::toSdb(PDB pdb, Database& db)
|
||||
{
|
||||
Tagid = db.BeginWriteListTag(pdb, TAG_EXE);
|
||||
SHIM_ERR("Unimplemented\n");
|
||||
|
||||
return !!db.EndWriteListTag(pdb, Tagid);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Database
|
||||
*/
|
||||
|
||||
void Database::WriteBinary(PDB pdb, TAG tag, const GUID& guid)
|
||||
{
|
||||
SdbWriteBinaryTag(pdb, tag, (BYTE*)&guid, sizeof(GUID));
|
||||
}
|
||||
|
||||
void Database::WriteString(PDB pdb, TAG tag, const sdbstring& str)
|
||||
{
|
||||
SdbWriteStringTag(pdb, tag, (LPCWSTR)str.c_str());
|
||||
}
|
||||
|
||||
void Database::WriteString(PDB pdb, TAG tag, const std::string& str)
|
||||
{
|
||||
WriteString(pdb, tag, sdbstring(str.begin(), str.end()));
|
||||
}
|
||||
|
||||
TAGID Database::BeginWriteListTag(PDB db, TAG tag)
|
||||
{
|
||||
return SdbBeginWriteListTag(db, tag);
|
||||
}
|
||||
|
||||
BOOL Database::EndWriteListTag(PDB db, TAGID tagid)
|
||||
{
|
||||
return SdbEndWriteListTag(db, tagid);
|
||||
}
|
||||
|
||||
bool Database::fromXml(XMLHandle dbNode)
|
||||
{
|
||||
Name = ReadStringNode(dbNode, "NAME");
|
||||
ReadBinaryNode(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.push_back(shim);
|
||||
}
|
||||
else if (NodeName == "FLAG")
|
||||
{
|
||||
SHIM_ERR("Unhanled FLAG type\n");
|
||||
}
|
||||
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, "1.0.0.0");
|
||||
SdbWriteDWORDTag(pdb, TAG_OS_PLATFORM, 1);
|
||||
WriteString(pdb, TAG_NAME, Name);
|
||||
WriteBinary(pdb, TAG_DATABASE_ID, ID);
|
||||
TAGID tidLibrary = BeginWriteListTag(pdb, TAG_LIBRARY);
|
||||
if (!WriteGeneric(pdb, Library, *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;
|
||||
}
|
||||
|
||||
|
||||
void Database::InsertShimTagid(const sdbstring& name, TAGID tagid)
|
||||
{
|
||||
sdbstring nameLower = name;
|
||||
std::transform(nameLower.begin(), nameLower.end(), nameLower.begin(), ::tolower);
|
||||
if (KnownShims.find(nameLower) != KnownShims.end())
|
||||
{
|
||||
std::string nameA(name.begin(), name.end());
|
||||
SHIM_WARN("Shim '%s' redefined\n", nameA.c_str());
|
||||
return;
|
||||
}
|
||||
KnownShims[nameLower] = tagid;
|
||||
}
|
||||
|
||||
void Database::InsertShimTagid(const std::string& name, TAGID tagid)
|
||||
{
|
||||
InsertShimTagid(sdbstring(name.begin(), name.end()), tagid);
|
||||
}
|
||||
|
||||
TAGID Database::FindShimTagid(const sdbstring& name)
|
||||
{
|
||||
sdbstring nameLower = name;
|
||||
std::transform(nameLower.begin(), nameLower.end(), nameLower.begin(), ::tolower);
|
||||
std::map<sdbstring, TAGID>::iterator it = KnownShims.find(nameLower);
|
||||
if (it == KnownShims.end())
|
||||
return 0;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
TAGID Database::FindShimTagid(const std::string& name)
|
||||
{
|
||||
return FindShimTagid(sdbstring(name.begin(), name.end()));
|
||||
}
|
||||
|
||||
|
||||
bool xml_2_db(const char* xml, const WCHAR* sdb)
|
||||
{
|
||||
Database db;
|
||||
if (db.fromXml(xml))
|
||||
{
|
||||
return db.toSdb((LPCWSTR)sdb);
|
||||
}
|
||||
return false;
|
||||
}
|
132
sdk/tools/xml2sdb/xml2sdb.h
Normal file
132
sdk/tools/xml2sdb/xml2sdb.h
Normal file
|
@ -0,0 +1,132 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
#include <typedefs.h>
|
||||
#include <guiddef.h>
|
||||
#include "sdbtypes.h"
|
||||
#include "sdbwrite.h"
|
||||
#include "sdbtagid.h"
|
||||
|
||||
namespace tinyxml2
|
||||
{
|
||||
class XMLHandle;
|
||||
}
|
||||
using tinyxml2::XMLHandle;
|
||||
|
||||
typedef std::basic_string<WCHAR> sdbstring;
|
||||
|
||||
struct Database;
|
||||
|
||||
struct InExclude
|
||||
{
|
||||
InExclude() : Include(false) { ; }
|
||||
bool fromXml(XMLHandle dbNode);
|
||||
bool toSdb(PDB pdb, Database& db);
|
||||
|
||||
std::string Module;
|
||||
bool Include;
|
||||
};
|
||||
|
||||
struct ShimRef
|
||||
{
|
||||
ShimRef() : ShimTagid(0) { ; }
|
||||
|
||||
bool fromXml(XMLHandle dbNode);
|
||||
bool toSdb(PDB pdb, Database& db);
|
||||
|
||||
std::string Name;
|
||||
std::string CommandLine;
|
||||
TAGID ShimTagid;
|
||||
std::list<InExclude> InExcludes;
|
||||
};
|
||||
|
||||
struct Shim
|
||||
{
|
||||
Shim() : Tagid(0) { ; }
|
||||
|
||||
bool fromXml(XMLHandle dbNode);
|
||||
bool toSdb(PDB pdb, Database& db);
|
||||
|
||||
std::string Name;
|
||||
std::string DllFile;
|
||||
GUID FixID;
|
||||
TAGID Tagid;
|
||||
std::list<InExclude> InExcludes;
|
||||
};
|
||||
|
||||
struct Layer
|
||||
{
|
||||
Layer() : Tagid(0) { ; }
|
||||
|
||||
bool fromXml(XMLHandle dbNode);
|
||||
bool toSdb(PDB pdb, Database& db);
|
||||
|
||||
std::string Name;
|
||||
TAGID Tagid;
|
||||
std::list<ShimRef> ShimRefs;
|
||||
};
|
||||
|
||||
struct MatchingFile
|
||||
{
|
||||
bool fromXml(XMLHandle dbNode);
|
||||
bool toSdb(PDB pdb, Database& db);
|
||||
|
||||
std::string Name;
|
||||
std::string CompanyName;
|
||||
std::string ProductName;
|
||||
std::string ProductVersion;
|
||||
std::string BinFileVersion;
|
||||
std::string LinkDate;
|
||||
std::string VerLanguage;
|
||||
std::string FileDescription;
|
||||
std::string OriginalFilename;
|
||||
std::string UptoBinFileVersion;
|
||||
std::string LinkerVersion;
|
||||
};
|
||||
|
||||
struct Exe
|
||||
{
|
||||
Exe() : Tagid(0) { ; }
|
||||
|
||||
bool fromXml(XMLHandle dbNode);
|
||||
bool toSdb(PDB pdb, Database& db);
|
||||
|
||||
std::string Name;
|
||||
std::string AppName;
|
||||
std::string Vendor;
|
||||
TAGID Tagid;
|
||||
std::list<ShimRef> ShimRefs;
|
||||
};
|
||||
|
||||
struct Database
|
||||
{
|
||||
|
||||
bool fromXml(const char* fileName);
|
||||
bool fromXml(XMLHandle dbNode);
|
||||
bool toSdb(LPCWSTR path);
|
||||
|
||||
void WriteString(PDB pdb, TAG tag, const sdbstring& str);
|
||||
void WriteString(PDB pdb, TAG tag, const std::string& str);
|
||||
void WriteBinary(PDB pdb, TAG tag, const GUID& guid);
|
||||
TAGID BeginWriteListTag(PDB db, TAG tag);
|
||||
BOOL EndWriteListTag(PDB db, TAGID tagid);
|
||||
|
||||
void InsertShimTagid(const sdbstring& name, TAGID tagid);
|
||||
void InsertShimTagid(const std::string& name, TAGID tagid);
|
||||
TAGID FindShimTagid(const sdbstring& name);
|
||||
TAGID FindShimTagid(const std::string& name);
|
||||
|
||||
std::string Name;
|
||||
GUID ID;
|
||||
|
||||
std::list<Shim> Library;
|
||||
std::list<Layer> Layers;
|
||||
std::list<Exe> Exes;
|
||||
|
||||
private:
|
||||
std::map<sdbstring, TAGID> KnownShims;
|
||||
};
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue