1 /* 2 * PROJECT: xml2sdb 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: Implement platform agnostic read / write / allocation functions, parse commandline 5 * COPYRIGHT: Copyright 2016,2017 Mark Jansen (mark.jansen@reactos.org) 6 */ 7 8 #include "xml2sdb.h" 9 #include "sdbpapi.h" 10 #include "sdbstringtable.h" 11 #include <time.h> 12 #include <stdio.h> 13 #include <stdarg.h> 14 15 extern "C" 16 { 17 ULONG g_ShimDebugLevel = SHIM_WARN; 18 19 LPVOID WINAPI SdbpAlloc(SIZE_T size) 20 { 21 return ::calloc(1, size); 22 } 23 24 LPVOID WINAPI SdbpReAlloc(LPVOID mem, SIZE_T size, SIZE_T oldSize) 25 { 26 LPVOID newMem = ::realloc(mem, size); 27 if (newMem && size > oldSize) 28 { 29 memset((BYTE*)newMem + oldSize, 0, size - oldSize); 30 } 31 return newMem; 32 } 33 34 void WINAPI SdbpFree(LPVOID mem) 35 { 36 return ::free(mem); 37 } 38 39 DWORD SdbpStrlen(PCWSTR string) 40 { 41 size_t len = 0; 42 while (string[len]) 43 len++; 44 return len; 45 } 46 47 DWORD WINAPI SdbpStrsize(PCWSTR string) 48 { 49 return (SdbpStrlen(string) + 1) * sizeof(WCHAR); 50 } 51 52 PDB WINAPI SdbpCreate(LPCWSTR path, PATH_TYPE type, BOOL write) 53 { 54 PDB pdb; 55 FILE* f; 56 std::string pathA(path, path + SdbpStrlen(path)); 57 58 f = fopen(pathA.c_str(), write ? "wb" : "rb"); 59 if (!f) 60 return NULL; 61 62 pdb = (PDB)SdbAlloc(sizeof(DB)); 63 pdb->file = f; 64 pdb->for_write = write; 65 66 return pdb; 67 } 68 69 void WINAPI SdbpFlush(PDB pdb) 70 { 71 ASSERT(pdb->for_write); 72 73 fwrite(pdb->data, pdb->write_iter, 1, (FILE*)pdb->file); 74 } 75 76 void WINAPI SdbCloseDatabase(PDB pdb) 77 { 78 if (!pdb) 79 return; 80 81 if (pdb->file) 82 fclose((FILE*)pdb->file); 83 if (pdb->string_buffer) 84 SdbCloseDatabase(pdb->string_buffer); 85 if (pdb->string_lookup) 86 SdbpTableDestroy(&pdb->string_lookup); 87 SdbFree(pdb->data); 88 SdbFree(pdb); 89 } 90 91 BOOL WINAPI SdbpCheckTagType(TAG tag, WORD type) 92 { 93 if ((tag & TAG_TYPE_MASK) != type) 94 return FALSE; 95 return TRUE; 96 } 97 98 BOOL WINAPI SdbpReadData(PDB pdb, PVOID dest, DWORD offset, DWORD num) 99 { 100 DWORD size = offset + num; 101 102 /* Either overflow or no data to read */ 103 if (size <= offset) 104 return FALSE; 105 106 /* Overflow */ 107 if (pdb->size < size) 108 return FALSE; 109 110 memcpy(dest, pdb->data + offset, num); 111 return TRUE; 112 } 113 114 TAG WINAPI SdbGetTagFromTagID(PDB pdb, TAGID tagid) 115 { 116 TAG data; 117 if (!SdbpReadData(pdb, &data, tagid, sizeof(data))) 118 return TAG_NULL; 119 return data; 120 } 121 122 BOOL WINAPI SdbpCheckTagIDType(PDB pdb, TAGID tagid, WORD type) 123 { 124 TAG tag = SdbGetTagFromTagID(pdb, tagid); 125 if (tag == TAG_NULL) 126 return FALSE; 127 return SdbpCheckTagType(tag, type); 128 } 129 130 BOOL WINAPIV ShimDbgPrint(SHIM_LOG_LEVEL Level, PCSTR FunctionName, PCSTR Format, ...) 131 { 132 va_list ArgList; 133 const char* LevelStr; 134 135 if ((ULONG)Level > g_ShimDebugLevel) 136 return FALSE; 137 138 switch (Level) 139 { 140 case SHIM_ERR: 141 LevelStr = "Err "; 142 break; 143 case SHIM_WARN: 144 LevelStr = "Warn"; 145 break; 146 case SHIM_INFO: 147 LevelStr = "Info"; 148 break; 149 default: 150 LevelStr = "User"; 151 break; 152 } 153 printf("[%s][%-20s] ", LevelStr, FunctionName); 154 va_start(ArgList, Format); 155 vprintf(Format, ArgList); 156 va_end(ArgList); 157 return TRUE; 158 } 159 160 161 #define TICKSPERSEC 10000000 162 #if defined(__GNUC__) 163 #define TICKSTO1970 0x019db1ded53e8000LL 164 #else 165 #define TICKSTO1970 0x019db1ded53e8000i64 166 #endif 167 VOID NTAPI RtlSecondsSince1970ToTime(IN ULONG SecondsSince1970, 168 OUT PLARGE_INTEGER Time) 169 { 170 Time->QuadPart = ((LONGLONG)SecondsSince1970 * TICKSPERSEC) + TICKSTO1970; 171 } 172 173 174 } 175 176 177 bool xml_2_db(const char* xml, const WCHAR* sdb); 178 179 static bool run_one(std::string& input, std::string& output) 180 { 181 sdbstring outputW(output.begin(), output.end()); 182 if (!xml_2_db(input.c_str(), outputW.c_str())) 183 return false; 184 input = output = ""; 185 return true; 186 } 187 188 static std::string get_strarg(int argc, char* argv[], int& i) 189 { 190 if (argv[i][2] != 0) 191 return std::string(argv[i] + 2); 192 193 ++i; 194 if (i >= argc || !argv[i]) 195 return std::string(); 196 return argv[i]; 197 } 198 199 static void update_loglevel(int argc, char* argv[], int& i) 200 { 201 std::string value = get_strarg(argc, argv, i); 202 g_ShimDebugLevel = strtoul(value.c_str(), NULL, 10); 203 } 204 205 int main(int argc, char * argv[]) 206 { 207 std::string input, output; 208 srand(time(0)); 209 210 for (int i = 1; i < argc; ++i) 211 { 212 if (argv[i][0] != '/' && argv[i][0] != '-') 213 continue; 214 215 switch(argv[i][1]) 216 { 217 case 'i': 218 input = get_strarg(argc, argv, i); 219 break; 220 case 'o': 221 output = get_strarg(argc, argv, i); 222 break; 223 case 'l': 224 update_loglevel(argc, argv, i); 225 break; 226 } 227 if (input.empty() || output.empty()) 228 continue; 229 230 if (!run_one(input, output)) 231 { 232 printf("Failed converting '%s' to '%s'\n", input.c_str(), output.c_str()); 233 return 1; 234 } 235 } 236 return 0; 237 } 238