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"
41 static void WINAPI
SdbpWrite(PDB db
, const void* data
, DWORD size
)
43 if (db
->write_iter
+ size
> db
->size
)
45 /* Round to powers of two to prevent too many reallocations */
46 while (db
->size
< db
->write_iter
+ size
) db
->size
<<= 1;
47 db
->data
= SdbReAlloc(db
->data
, db
->size
);
50 memcpy(db
->data
+ db
->write_iter
, data
, size
);
51 db
->write_iter
+= size
;
55 * Creates new shim database file
57 * If a file already exists on specified path, that file shall be overwritten.
59 * @note Use SdbCloseDatabasWrite to close the database opened with this function.
61 * @param [in] path Path to the new shim database.
62 * @param [in] type Type of path. Either DOS_PATH or NT_PATH.
64 * @return Success: Handle to the newly created shim database, NULL otherwise.
66 PDB WINAPI
SdbCreateDatabase(LPCWSTR path
, PATH_TYPE type
)
68 static const DWORD version_major
= 2, version_minor
= 1;
69 static const char* magic
= "sdbf";
72 db
= SdbpCreate(path
, type
, TRUE
);
76 db
->size
= sizeof(DWORD
) + sizeof(DWORD
) + strlen(magic
);
77 db
->data
= SdbAlloc(db
->size
);
79 SdbpWrite(db
, &version_major
, sizeof(DWORD
));
80 SdbpWrite(db
, &version_minor
, sizeof(DWORD
));
81 SdbpWrite(db
, magic
, strlen(magic
));
87 * Closes specified database and writes data to file.
89 * @param [in] db Handle to the shim database.
91 void WINAPI
SdbCloseDatabaseWrite(PDB db
)
98 * Writes a tag-only (NULL) entry to the specified shim database.
100 * @param [in] db Handle to the shim database.
101 * @param [in] tag A tag for the entry.
103 * @return TRUE if it succeeds, FALSE if it fails.
105 BOOL WINAPI
SdbWriteNULLTag(PDB db
, TAG tag
)
107 if (!SdbpCheckTagType(tag
, TAG_TYPE_NULL
))
110 SdbpWrite(db
, &tag
, sizeof(TAG
));
115 * Writes a WORD entry to the specified shim database.
117 * @param [in] db Handle to the shim database.
118 * @param [in] tag A tag for the entry.
119 * @param [in] data WORD entry which will be written to the database.
121 * @return TRUE if it succeeds, FALSE if it fails.
123 BOOL WINAPI
SdbWriteWORDTag(PDB db
, TAG tag
, WORD data
)
125 if (!SdbpCheckTagType(tag
, TAG_TYPE_WORD
))
128 SdbpWrite(db
, &tag
, sizeof(TAG
));
129 SdbpWrite(db
, &data
, sizeof(data
));
134 * Writes a DWORD entry to the specified shim database.
136 * @param [in] db Handle to the shim database.
137 * @param [in] tag A tag for the entry.
138 * @param [in] data DWORD entry which will be written to the database.
140 * @return TRUE if it succeeds, FALSE if it fails.
142 BOOL WINAPI
SdbWriteDWORDTag(PDB db
, TAG tag
, DWORD data
)
144 if (!SdbpCheckTagType(tag
, TAG_TYPE_DWORD
))
147 SdbpWrite(db
, &tag
, sizeof(TAG
));
148 SdbpWrite(db
, &data
, sizeof(data
));
153 * Writes a DWORD entry to the specified shim database.
155 * @param [in] db Handle to the shim database.
156 * @param [in] tag A tag for the entry.
157 * @param [in] data QWORD entry which will be written to the database.
159 * @return TRUE if it succeeds, FALSE if it fails.
161 BOOL WINAPI
SdbWriteQWORDTag(PDB db
, TAG tag
, QWORD data
)
163 if (!SdbpCheckTagType(tag
, TAG_TYPE_QWORD
))
166 SdbpWrite(db
, &tag
, sizeof(TAG
));
167 SdbpWrite(db
, &data
, sizeof(data
));
172 * Writes a wide string entry to the specified shim database.
174 * @param [in] db Handle to the shim database.
175 * @param [in] tag A tag for the entry.
176 * @param [in] string Wide string entry which will be written to the database.
178 * @return TRUE if it succeeds, FALSE if it fails.
180 BOOL WINAPI
SdbWriteStringTag(PDB db
, TAG tag
, LPCWSTR string
)
184 if (!SdbpCheckTagType(tag
, TAG_TYPE_STRING
))
187 size
= SdbpStrlen(string
);
188 SdbpWrite(db
, &tag
, sizeof(TAG
));
189 SdbpWrite(db
, &size
, sizeof(size
));
190 SdbpWrite(db
, string
, size
);
195 * Writes a stringref tag to specified database
196 * @note Reference (tagid) is not checked for validity.
198 * @param [in] db Handle to the shim database.
199 * @param [in] tag TAG which will be written.
200 * @param [in] tagid TAGID of the string tag refers to.
202 * @return TRUE if it succeeds, FALSE if it fails.
204 BOOL WINAPI
SdbWriteStringRefTag(PDB db
, TAG tag
, TAGID tagid
)
206 if (!SdbpCheckTagType(tag
, TAG_TYPE_STRINGREF
))
209 SdbpWrite(db
, &tag
, sizeof(TAG
));
210 SdbpWrite(db
, &tagid
, sizeof(tagid
));
215 * Writes data the specified shim database.
217 * @param [in] db Handle to the shim database.
218 * @param [in] tag A tag for the entry.
219 * @param [in] data Pointer to data.
220 * @param [in] size Number of bytes to write.
222 * @return TRUE if it succeeds, FALSE if it fails.
224 BOOL WINAPI
SdbWriteBinaryTag(PDB db
, TAG tag
, BYTE
* data
, DWORD size
)
226 if (!SdbpCheckTagType(tag
, TAG_TYPE_BINARY
))
229 SdbpWrite(db
, &tag
, sizeof(TAG
));
230 SdbpWrite(db
, &size
, sizeof(size
));
231 SdbpWrite(db
, data
, size
);
235 #if !defined(SDBWRITE_HOSTTOOL)
237 * Writes data from a file to the specified shim database.
239 * @param [in] db Handle to the shim database.
240 * @param [in] tag A tag for the entry.
241 * @param [in] path Path of the input file.
243 * @return TRUE if it succeeds, FALSE if it fails.
245 BOOL WINAPI
SdbWriteBinaryTagFromFile(PDB db
, TAG tag
, LPCWSTR path
)
249 if (!SdbpCheckTagType(tag
, TAG_TYPE_BINARY
))
252 if (!SdbpOpenMemMappedFile(path
, &mapped
))
255 SdbWriteBinaryTag(db
, tag
, mapped
.view
, mapped
.size
);
256 SdbpCloseMemMappedFile(&mapped
);
262 * Writes a list tag to specified database All subsequent SdbWrite* functions shall write to
263 * newly created list untill TAGID of that list is passed to SdbEndWriteListTag.
265 * @param [in] db Handle to the shim database.
266 * @param [in] tag TAG for the list
268 * RETURNS Success: TAGID of the newly created list, or TAGID_NULL on failure.
272 TAGID WINAPI
SdbBeginWriteListTag(PDB db
, TAG tag
)
277 if (!SdbpCheckTagType(tag
, TAG_TYPE_LIST
))
280 list_id
= db
->write_iter
;
281 SdbpWrite(db
, &tag
, sizeof(TAG
));
282 SdbpWrite(db
, &dum
, sizeof(dum
)); /* reserve some memory for storing list size */
287 * Marks end of the specified list.
289 * @param [in] db Handle to the shim database.
290 * @param [in] tagid TAGID of the list.
292 * @return TRUE if it succeeds, FALSE if it fails.
294 BOOL WINAPI
SdbEndWriteListTag(PDB db
, TAGID tagid
)
296 if (!SdbpCheckTagIDType(db
, tagid
, TAG_TYPE_LIST
))
299 /* Write size of list to list tag header */
300 *(DWORD
*)&db
->data
[tagid
+ sizeof(TAG
)] = db
->write_iter
- tagid
- sizeof(TAG
);