Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261/* * PROJECT: xml2sdb * LICENSE: MIT (https://spdx.org/licenses/MIT) * PURPOSE: Implement platform agnostic read / write / allocation functions, parse commandline * COPYRIGHT: Copyright 2016-2025 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#endifVOID NTAPI RtlSecondsSince1970ToTime(IN ULONG SecondsSince1970, OUT PLARGE_INTEGER Time){ Time->QuadPart = ((LONGLONG)SecondsSince1970 * TICKSPERSEC) + TICKSTO1970;}
}
static bool convert(const std::string& input, const std::string& output, PlatformType platform){ sdbstring outputW(output.begin(), output.end()); Database db; if (!db.fromXml(input.c_str(), platform)) { printf("Failed to read XML file '%s'\n", input.c_str()); return false; } if (!db.toSdb(outputW.c_str())) { printf("Failed to write SDB file '%s'\n", output.c_str()); return false; } 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);}
static PlatformTypeparse_platform(const std::string &input){ return (PlatformType)str_to_enum(input, platform_to_flag);}
int main(int argc, char * argv[]){ std::string input, output; PlatformType platform = PLATFORM_ANY; 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; case 'p': platform = parse_platform(get_strarg(argc, argv, i)); break; } } if (input.empty() || output.empty()) { printf("Usage: %s -i <input.xml> -o <output.sdb> [-l <loglevel>] [-v <version>]\n", argv[0]); printf(" -i <input.xml> : Input XML file to convert\n"); printf(" -o <output.sdb> : Output SDB file to create\n"); printf(" -l <loglevel> : Set log level (1=ERR, 2=WARN, 3=INFO)\n"); printf(" -p <platform> : Set the runtime platform (X86, AMD64, ANY)\n"); return 1; }
if (!convert(input, output, platform)) { printf("Failed converting '%s' to '%s'\n", input.c_str(), output.c_str()); return 1; } return 0;}