ReactOS  0.4.14-dev-604-gcfdd483
sdbread.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Application compatibility module
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: Shim database query functions
5  * COPYRIGHT: Copyright 2011 André Hentschel
6  * Copyright 2013 Mislav Blaževic
7  * Copyright 2015-2018 Mark Jansen (mark.jansen@reactos.org)
8  */
9 
10 #include "windef.h"
11 #include "apphelp.h"
12 
13 
15 {
16  DWORD size = offset + num;
17 
18  /* Either overflow or no data to read */
19  if (size <= offset)
20  return FALSE;
21 
22  /* Overflow */
23  if (pdb->size < size)
24  return FALSE;
25 
26  memcpy(dest, pdb->data + offset, num);
27  return TRUE;
28 }
29 
31 {
32  WORD type;
33  DWORD size;
34 
36  if (type == TAG_NULL)
37  return 0;
38 
39  size = SdbGetTagDataSize(pdb, tagid);
40  if (type <= TAG_TYPE_STRINGREF)
41  return size += sizeof(TAG);
42  else size += (sizeof(TAG) + sizeof(DWORD));
43 
44  return size;
45 }
46 
48 {
49  TAG tag;
50  TAGID offset;
51 
52  tag = SdbGetTagFromTagID(pdb, tagid);
53  if (tag == TAG_NULL)
54  return NULL;
55 
57  {
58  /* No stringtable; all references are invalid */
59  if (pdb->stringtable == TAGID_NULL)
60  return NULL;
61 
62  /* TAG_TYPE_STRINGREF contains offset of string relative to stringtable */
63  if (!SdbpReadData(pdb, &tagid, tagid + sizeof(TAG), sizeof(TAGID)))
64  return NULL;
65 
66  offset = pdb->stringtable + tagid + sizeof(TAG) + sizeof(TAGID);
67  }
68  else if ((tag & TAG_TYPE_MASK) == TAG_TYPE_STRING)
69  {
70  offset = tagid + sizeof(TAG) + sizeof(TAGID);
71  }
72  else
73  {
74  SHIM_ERR("Tag 0x%u at tagid %u is neither a string or reference to string\n", tag, tagid);
75  return NULL;
76  }
77 
78  /* Optionally read string size */
79  if (size && !SdbpReadData(pdb, size, offset - sizeof(TAGID), sizeof(*size)))
80  return FALSE;
81 
82  return (LPWSTR)(&pdb->data[offset]);
83 }
84 
94 {
95  TAG data;
96  if (!SdbpReadData(pdb, &data, tagid, sizeof(data)))
97  return TAG_NULL;
98  return data;
99 }
100 
110 {
111  /* sizes of data types with fixed size */
112  static const SIZE_T sizes[6] = {
113  0, /* NULL */ 1, /* BYTE */
114  2, /* WORD */ 4, /* DWORD */
115  8, /* QWORD */ 4 /* STRINGREF */
116  };
117  WORD type;
118  DWORD size;
119 
121  if (type == TAG_NULL)
122  return 0;
123 
124  if (type <= TAG_TYPE_STRINGREF)
125  return sizes[(type >> 12) - 1];
126 
127  /* tag with dynamic size (e.g. list): must read size */
128  if (!SdbpReadData(pdb, &size, tagid + sizeof(TAG), sizeof(size)))
129  return 0;
130 
131  return size;
132 }
133 
143 {
144  /* if we are at beginning of database */
145  if (parent == TAGID_ROOT)
146  {
147  /* header only database: no tags */
148  if (pdb->size <= _TAGID_ROOT)
149  return TAGID_NULL;
150  /* return *real* root tagid */
151  else return _TAGID_ROOT;
152  }
153 
154  /* only list tag can have children */
156  return TAGID_NULL;
157 
158  /* first child is sizeof(TAG) + sizeof(DWORD) bytes after beginning of list */
159  return parent + sizeof(TAG) + sizeof(DWORD);
160 }
161 
172 {
173  TAGID next_child;
174  DWORD prev_child_size, parent_size;
175 
176  prev_child_size = SdbpGetTagSize(pdb, prev_child);
177  if (prev_child_size == 0)
178  return TAGID_NULL;
179 
180  /* Bound check */
181  next_child = prev_child + prev_child_size;
182  if (next_child >= pdb->size)
183  return TAGID_NULL;
184 
185  if (parent == TAGID_ROOT)
186  return next_child;
187 
188  parent_size = SdbpGetTagSize(pdb, parent);
189  if (parent_size == 0)
190  return TAGID_NULL;
191 
192  /* Specified parent has no more children */
193  if (next_child >= parent + parent_size)
194  return TAGID_NULL;
195 
196  return next_child;
197 }
198 
209 {
210  TAGID iter;
211 
212  iter = SdbGetFirstChild(pdb, parent);
213  while (iter != TAGID_NULL)
214  {
215  if (SdbGetTagFromTagID(pdb, iter) == tag)
216  return iter;
217  iter = SdbGetNextChild(pdb, parent, iter);
218  }
219  return TAGID_NULL;
220 }
221 
232 {
233  TAG tag;
234  TAGID iter;
235 
236  tag = SdbGetTagFromTagID(pdb, prev_child);
237  iter = SdbGetNextChild(pdb, parent, prev_child);
238 
239  while (iter != TAGID_NULL)
240  {
241  if (SdbGetTagFromTagID(pdb, iter) == tag)
242  return iter;
243  iter = SdbGetNextChild(pdb, parent, iter);
244  }
245  return TAGID_NULL;
246 }
247 
264 {
265  LPWSTR string;
266  DWORD string_size;
267 
268  string = SdbpGetString(pdb, tagid, &string_size);
269  if (!string)
270  return FALSE;
271 
272  /* Check if buffer is too small */
273  if (size * sizeof(WCHAR) < string_size)
274  return FALSE;
275 
276  memcpy(buffer, string, string_size);
277  return TRUE;
278 }
279 
290 {
291  if (SdbpCheckTagIDType(pdb, tagid, TAG_TYPE_WORD))
292  SdbpReadData(pdb, &ret, tagid + 2, sizeof(WORD));
293  return ret;
294 }
295 
306 {
308  SdbpReadData(pdb, &ret, tagid + 2, sizeof(DWORD));
309  return ret;
310 }
311 
322 {
324  SdbpReadData(pdb, &ret, tagid + sizeof(TAG), sizeof(QWORD));
325  return ret;
326 }
327 
339 {
340  DWORD data_size = 0;
341 
343  {
344  SdbpReadData(pdb, &data_size, tagid + sizeof(TAG), sizeof(data_size));
345  if (size >= data_size)
346  return SdbpReadData(pdb, buffer, tagid + sizeof(TAG) + sizeof(data_size), data_size);
347  }
348 
349  return FALSE;
350 }
351 
361 {
362  if (!SdbpCheckTagIDType(pdb, tagid, TAG_TYPE_BINARY))
363  return NULL;
364  return &pdb->data[tagid + sizeof(TAG) + sizeof(DWORD)];
365 }
366 
376 {
377  return SdbpGetString(pdb, tagid, NULL);
378 }
379 
389 {
390  if(SdbIsNullGUID(&pdb->database_id))
391  {
393  if(root != TAGID_NULL)
394  {
396  if(id != TAGID_NULL)
397  {
398  if(!SdbReadBinaryTag(pdb, id, (PBYTE)&pdb->database_id, sizeof(pdb->database_id)))
399  {
400  memset(&pdb->database_id, 0, sizeof(pdb->database_id));
401  }
402  }
403  else
404  {
405  /* Should we silence this if we are opening a system db? */
406  SHIM_ERR("Failed to get the database id\n");
407  }
408  }
409  else
410  {
411  /* Should we silence this if we are opening a system db? */
412  SHIM_ERR("Failed to get root tag\n");
413  }
414  }
415  if(!SdbIsNullGUID(&pdb->database_id))
416  {
417  memcpy(Guid, &pdb->database_id, sizeof(pdb->database_id));
418  return TRUE;
419  }
420  return FALSE;
421 }
422 
#define TAG_TYPE_STRING
Definition: apphelp.c:41
#define TRUE
Definition: types.h:120
static PDB pdb
Definition: db.cpp:170
TAG WINAPI SdbGetTagFromTagID(PDB pdb, TAGID tagid)
Definition: sdbread.c:93
#define TAG_TYPE_DWORD
Definition: shimdbg.c:107
#define TAG_DATABASE
Definition: db.cpp:83
GLintptr offset
Definition: glext.h:5920
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
Definition: ecma_167.h:138
GLuint buffer
Definition: glext.h:5915
WORD WINAPI SdbReadWORDTag(PDB pdb, TAGID tagid, WORD ret)
Definition: sdbread.c:289
#define TAG_NULL
Definition: apphelp.c:43
#define TAG_TYPE_MASK
Definition: shimdbg.c:106
LPWSTR WINAPI SdbpGetString(PDB pdb, TAGID tagid, PDWORD size)
Definition: sdbread.c:47
DWORD WINAPI SdbGetTagDataSize(PDB pdb, TAGID tagid)
Definition: sdbread.c:109
BOOL WINAPI SdbReadStringTag(PDB pdb, TAGID tagid, LPWSTR buffer, DWORD size)
Definition: sdbread.c:263
TAGID WINAPI SdbGetNextChild(PDB pdb, TAGID parent, TAGID prev_child)
Definition: sdbread.c:171
DWORD WINAPI SdbReadDWORDTag(PDB pdb, TAGID tagid, DWORD ret)
Definition: sdbread.c:305
static DWORD WINAPI SdbpGetTagSize(PDB pdb, TAGID tagid)
Definition: sdbread.c:30
unsigned int BOOL
Definition: ntddk_ex.h:94
#define _TAGID_ROOT
Definition: db.cpp:38
TAGID WINAPI SdbFindFirstTag(PDB pdb, TAGID parent, TAG tag)
Definition: sdbread.c:208
static GUID * Guid
Definition: apphelp.c:93
smooth NULL
Definition: ftsmooth.c:416
QWORD WINAPI SdbReadQWORDTag(PDB pdb, TAGID tagid, QWORD ret)
Definition: sdbread.c:321
GLsizeiptr size
Definition: glext.h:5919
PVOID WINAPI SdbGetBinaryTagData(PDB pdb, TAGID tagid)
Definition: sdbread.c:360
r parent
Definition: btrfs.c:2869
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define TAG_TYPE_WORD
Definition: apphelp.c:36
BOOL WINAPI SdbIsNullGUID(CONST GUID *Guid)
Definition: sdbapi.c:431
UINT64 QWORD
Definition: shimdbg.c:104
#define WINAPI
Definition: msvc.h:6
LPWSTR WINAPI SdbGetStringTagPtr(PDB pdb, TAGID tagid)
Definition: sdbread.c:375
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint num
Definition: glext.h:9618
TAGID WINAPI SdbFindNextTag(PDB pdb, TAGID parent, TAGID prev_child)
Definition: sdbread.c:231
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define TAG_TYPE_QWORD
Definition: shimdbg.c:108
static const struct @527 sizes[]
int ret
#define TAG_TYPE_LIST
Definition: apphelp.c:40
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
char string[160]
Definition: util.h:11
#define TAGID_NULL
Definition: db.cpp:36
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define TAG_TYPE_STRINGREF
Definition: shimdbg.c:109
TAGID WINAPI SdbGetFirstChild(PDB pdb, TAGID parent)
Definition: sdbread.c:142
#define TAG_TYPE_BINARY
Definition: apphelp.c:42
#define TAGID_ROOT
Definition: db.cpp:37
Definition: fs_rec.h:142
DWORD * PDWORD
Definition: pedump.c:68
BOOL WINAPI SdbpCheckTagIDType(PDB pdb, TAGID tagid, WORD type)
Definition: sdbapi.c:261
#define TAG_DATABASE_ID
Definition: db.cpp:120
static char * dest
Definition: rtl.c:135
#define TAG(x)
Definition: ObTypes.c:150
DWORD TAGID
WCHAR * LPWSTR
Definition: xmlstorage.h:184
BOOL WINAPI SdbGetDatabaseID(PDB pdb, GUID *Guid)
Definition: sdbread.c:388
#define memset(x, y, z)
Definition: compat.h:39
BYTE * PBYTE
Definition: pedump.c:66
BOOL WINAPI SdbReadBinaryTag(PDB pdb, TAGID tagid, PBYTE buffer, DWORD size)
Definition: sdbread.c:338
BOOL WINAPI SdbpReadData(PDB pdb, PVOID dest, DWORD offset, DWORD num)
Definition: sdbread.c:14
char * tag
Definition: main.c:59