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