2 * Copyright 2011 André Hentschel
3 * Copyright 2013 Mislav Bla\9eevic
4 * Copyright 2015,2016 Mark Jansen
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #if !defined(SDBWRITE_HOSTTOOL)
23 #define WIN32_NO_STATUS
27 #include "wine/unicode.h"
40 BOOL WINAPI
SdbWriteStringRefTag(PDB db
, TAG tag
, TAGID tagid
);
41 TAGID WINAPI
SdbBeginWriteListTag(PDB db
, TAG tag
);
42 BOOL WINAPI
SdbEndWriteListTag(PDB db
, TAGID tagid
);
45 static void WINAPI
SdbpWrite(PDB db
, const void* data
, DWORD size
)
47 if (db
->write_iter
+ size
> db
->size
)
49 /* Round to powers of two to prevent too many reallocations */
50 while (db
->size
< db
->write_iter
+ size
) db
->size
<<= 1;
51 db
->data
= SdbReAlloc(db
->data
, db
->size
);
54 memcpy(db
->data
+ db
->write_iter
, data
, size
);
55 db
->write_iter
+= size
;
58 static BOOL WINAPI
SdbpGetOrAddStringRef(PDB db
, LPCWSTR string
, TAGID
* tagid
)
61 - Insert or find in stringtable
68 static void WINAPI
SdbpWriteStringtable(PDB db
)
70 TAGID table
= SdbBeginWriteListTag(db
, TAG_STRINGTABLE
);
71 /* TODO: Write out all strings*/
72 SdbEndWriteListTag(db
, table
);
76 * Creates new shim database file
78 * If a file already exists on specified path, that file shall be overwritten.
80 * @note Use SdbCloseDatabasWrite to close the database opened with this function.
82 * @param [in] path Path to the new shim database.
83 * @param [in] type Type of path. Either DOS_PATH or NT_PATH.
85 * @return Success: Handle to the newly created shim database, NULL otherwise.
87 PDB WINAPI
SdbCreateDatabase(LPCWSTR path
, PATH_TYPE type
)
89 static const DWORD version_major
= 2, version_minor
= 1;
90 static const char* magic
= "sdbf";
93 db
= SdbpCreate(path
, type
, TRUE
);
97 db
->size
= sizeof(DWORD
) + sizeof(DWORD
) + strlen(magic
);
98 db
->data
= SdbAlloc(db
->size
);
100 SdbpWrite(db
, &version_major
, sizeof(DWORD
));
101 SdbpWrite(db
, &version_minor
, sizeof(DWORD
));
102 SdbpWrite(db
, magic
, strlen(magic
));
108 * Closes specified database and writes data to file.
110 * @param [in] db Handle to the shim database.
112 void WINAPI
SdbCloseDatabaseWrite(PDB db
)
114 SdbpWriteStringtable(db
);
116 SdbCloseDatabase(db
);
120 * Writes a tag-only (NULL) entry to the specified shim database.
122 * @param [in] db Handle to the shim database.
123 * @param [in] tag A tag for the entry.
125 * @return TRUE if it succeeds, FALSE if it fails.
127 BOOL WINAPI
SdbWriteNULLTag(PDB db
, TAG tag
)
129 if (!SdbpCheckTagType(tag
, TAG_TYPE_NULL
))
132 SdbpWrite(db
, &tag
, sizeof(TAG
));
137 * Writes a WORD entry to the specified shim database.
139 * @param [in] db Handle to the shim database.
140 * @param [in] tag A tag for the entry.
141 * @param [in] data WORD entry which will be written to the database.
143 * @return TRUE if it succeeds, FALSE if it fails.
145 BOOL WINAPI
SdbWriteWORDTag(PDB db
, TAG tag
, WORD data
)
147 if (!SdbpCheckTagType(tag
, TAG_TYPE_WORD
))
150 SdbpWrite(db
, &tag
, sizeof(TAG
));
151 SdbpWrite(db
, &data
, sizeof(data
));
156 * Writes a DWORD entry to the specified shim database.
158 * @param [in] db Handle to the shim database.
159 * @param [in] tag A tag for the entry.
160 * @param [in] data DWORD entry which will be written to the database.
162 * @return TRUE if it succeeds, FALSE if it fails.
164 BOOL WINAPI
SdbWriteDWORDTag(PDB db
, TAG tag
, DWORD data
)
166 if (!SdbpCheckTagType(tag
, TAG_TYPE_DWORD
))
169 SdbpWrite(db
, &tag
, sizeof(TAG
));
170 SdbpWrite(db
, &data
, sizeof(data
));
175 * Writes a DWORD entry to the specified shim database.
177 * @param [in] db Handle to the shim database.
178 * @param [in] tag A tag for the entry.
179 * @param [in] data QWORD entry which will be written to the database.
181 * @return TRUE if it succeeds, FALSE if it fails.
183 BOOL WINAPI
SdbWriteQWORDTag(PDB db
, TAG tag
, QWORD data
)
185 if (!SdbpCheckTagType(tag
, TAG_TYPE_QWORD
))
188 SdbpWrite(db
, &tag
, sizeof(TAG
));
189 SdbpWrite(db
, &data
, sizeof(data
));
194 * Writes a wide string entry to the specified shim database.
196 * @param [in] db Handle to the shim database.
197 * @param [in] tag A tag for the entry.
198 * @param [in] string Wide string entry which will be written to the database.
200 * @return TRUE if it succeeds, FALSE if it fails.
202 BOOL WINAPI
SdbWriteStringTag(PDB db
, TAG tag
, LPCWSTR string
)
206 if (SdbpCheckTagType(tag
, TAG_TYPE_STRINGREF
))
209 if (!SdbpGetOrAddStringRef(db
, string
, &tagid
))
212 return SdbWriteStringRefTag(db
, tag
, tagid
);
215 if (!SdbpCheckTagType(tag
, TAG_TYPE_STRING
))
218 size
= SdbpStrsize(string
);
219 SdbpWrite(db
, &tag
, sizeof(TAG
));
220 SdbpWrite(db
, &size
, sizeof(size
));
221 SdbpWrite(db
, string
, size
);
226 * Writes a stringref tag to specified database
227 * @note Reference (tagid) is not checked for validity.
229 * @param [in] db Handle to the shim database.
230 * @param [in] tag TAG which will be written.
231 * @param [in] tagid TAGID of the string tag refers to.
233 * @return TRUE if it succeeds, FALSE if it fails.
235 BOOL WINAPI
SdbWriteStringRefTag(PDB db
, TAG tag
, TAGID tagid
)
237 if (!SdbpCheckTagType(tag
, TAG_TYPE_STRINGREF
))
240 SdbpWrite(db
, &tag
, sizeof(TAG
));
241 SdbpWrite(db
, &tagid
, sizeof(tagid
));
246 * Writes data the specified shim database.
248 * @param [in] db Handle to the shim database.
249 * @param [in] tag A tag for the entry.
250 * @param [in] data Pointer to data.
251 * @param [in] size Number of bytes to write.
253 * @return TRUE if it succeeds, FALSE if it fails.
255 BOOL WINAPI
SdbWriteBinaryTag(PDB db
, TAG tag
, BYTE
* data
, DWORD size
)
257 if (!SdbpCheckTagType(tag
, TAG_TYPE_BINARY
))
260 SdbpWrite(db
, &tag
, sizeof(TAG
));
261 SdbpWrite(db
, &size
, sizeof(size
));
262 SdbpWrite(db
, data
, size
);
266 #if !defined(SDBWRITE_HOSTTOOL)
268 * Writes data from a file to the specified shim database.
270 * @param [in] db Handle to the shim database.
271 * @param [in] tag A tag for the entry.
272 * @param [in] path Path of the input file.
274 * @return TRUE if it succeeds, FALSE if it fails.
276 BOOL WINAPI
SdbWriteBinaryTagFromFile(PDB db
, TAG tag
, LPCWSTR path
)
280 if (!SdbpCheckTagType(tag
, TAG_TYPE_BINARY
))
283 if (!SdbpOpenMemMappedFile(path
, &mapped
))
286 SdbWriteBinaryTag(db
, tag
, mapped
.view
, mapped
.size
);
287 SdbpCloseMemMappedFile(&mapped
);
293 * Writes a list tag to specified database All subsequent SdbWrite* functions shall write to
294 * newly created list untill TAGID of that list is passed to SdbEndWriteListTag.
296 * @param [in] db Handle to the shim database.
297 * @param [in] tag TAG for the list
299 * RETURNS Success: TAGID of the newly created list, or TAGID_NULL on failure.
303 TAGID WINAPI
SdbBeginWriteListTag(PDB db
, TAG tag
)
308 if (!SdbpCheckTagType(tag
, TAG_TYPE_LIST
))
311 list_id
= db
->write_iter
;
312 SdbpWrite(db
, &tag
, sizeof(TAG
));
313 SdbpWrite(db
, &dum
, sizeof(dum
)); /* reserve some memory for storing list size */
318 * Marks end of the specified list.
320 * @param [in] db Handle to the shim database.
321 * @param [in] tagid TAGID of the list.
323 * @return TRUE if it succeeds, FALSE if it fails.
325 BOOL WINAPI
SdbEndWriteListTag(PDB db
, TAGID tagid
)
327 if (!SdbpCheckTagIDType(db
, tagid
, TAG_TYPE_LIST
))
330 /* Write size of list to list tag header */
331 *(DWORD
*)&db
->data
[tagid
+ sizeof(TAG
)] = db
->write_iter
- tagid
- sizeof(TAG
) - sizeof(TAGID
);