mirror of
https://github.com/reactos/reactos.git
synced 2024-08-18 17:37:02 +00:00
238 lines
5 KiB
C++
238 lines
5 KiB
C++
/*
|
|
* PROJECT: xml2sdb
|
|
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
|
* PURPOSE: Implement platform agnostic read / write / allocation functions, parse commandline
|
|
* COPYRIGHT: Copyright 2016,2017 Mark Jansen (mark.jansen@reactos.org)
|
|
*/
|
|
|
|
#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 pdb;
|
|
FILE* f;
|
|
std::string pathA(path, path + SdbpStrlen(path));
|
|
|
|
f = fopen(pathA.c_str(), write ? "wb" : "rb");
|
|
if (!f)
|
|
return NULL;
|
|
|
|
pdb = (PDB)SdbAlloc(sizeof(DB));
|
|
pdb->file = f;
|
|
pdb->for_write = write;
|
|
|
|
return pdb;
|
|
}
|
|
|
|
void WINAPI SdbpFlush(PDB pdb)
|
|
{
|
|
ASSERT(pdb->for_write);
|
|
|
|
fwrite(pdb->data, pdb->write_iter, 1, (FILE*)pdb->file);
|
|
}
|
|
|
|
void WINAPI SdbCloseDatabase(PDB pdb)
|
|
{
|
|
if (!pdb)
|
|
return;
|
|
|
|
if (pdb->file)
|
|
fclose((FILE*)pdb->file);
|
|
if (pdb->string_buffer)
|
|
SdbCloseDatabase(pdb->string_buffer);
|
|
if (pdb->string_lookup)
|
|
SdbpTableDestroy(&pdb->string_lookup);
|
|
SdbFree(pdb->data);
|
|
SdbFree(pdb);
|
|
}
|
|
|
|
BOOL WINAPI SdbpCheckTagType(TAG tag, WORD type)
|
|
{
|
|
if ((tag & TAG_TYPE_MASK) != type)
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL WINAPI SdbpReadData(PDB pdb, PVOID dest, DWORD offset, DWORD num)
|
|
{
|
|
DWORD size = offset + num;
|
|
|
|
/* Either overflow or no data to read */
|
|
if (size <= offset)
|
|
return FALSE;
|
|
|
|
/* Overflow */
|
|
if (pdb->size < size)
|
|
return FALSE;
|
|
|
|
memcpy(dest, pdb->data + offset, num);
|
|
return TRUE;
|
|
}
|
|
|
|
TAG WINAPI SdbGetTagFromTagID(PDB pdb, TAGID tagid)
|
|
{
|
|
TAG data;
|
|
if (!SdbpReadData(pdb, &data, tagid, sizeof(data)))
|
|
return TAG_NULL;
|
|
return data;
|
|
}
|
|
|
|
BOOL WINAPI SdbpCheckTagIDType(PDB pdb, TAGID tagid, WORD type)
|
|
{
|
|
TAG tag = SdbGetTagFromTagID(pdb, 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 ((ULONG)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)
|
|
return std::string(argv[i] + 2);
|
|
|
|
++i;
|
|
if (i >= argc || !argv[i])
|
|
return std::string();
|
|
return argv[i];
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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] != '-')
|
|
continue;
|
|
|
|
switch(argv[i][1])
|
|
{
|
|
case 'i':
|
|
input = get_strarg(argc, argv, i);
|
|
break;
|
|
case 'o':
|
|
output = get_strarg(argc, argv, i);
|
|
break;
|
|
case 'l':
|
|
update_loglevel(argc, argv, i);
|
|
break;
|
|
}
|
|
if (input.empty() || output.empty())
|
|
continue;
|
|
|
|
if (!run_one(input, output))
|
|
{
|
|
printf("Failed converting '%s' to '%s'\n", input.c_str(), output.c_str());
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|