xref: /reactos/sdk/tools/xml2sdb/main.cpp (revision 36873c49)
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