#include "ntndk.h"
#include "strsafe.h"
#include "apphelp.h"
+#include "sdbstringtable.h"
#include "wine/unicode.h"
return mem;
}
-LPVOID SdbpReAlloc(LPVOID mem, SIZE_T size
+LPVOID SdbpReAlloc(LPVOID mem, SIZE_T size, SIZE_T oldSize
#if SDBAPI_DEBUG_ALLOC
, int line, const char* file
#endif
HeapFree(SdbpHeap(), 0, mem);
}
-PDB WINAPI SdbpCreate(void)
+PDB WINAPI SdbpCreate(LPCWSTR path, PATH_TYPE type, BOOL write)
{
- PDB db = (PDB)SdbAlloc(sizeof(DB));
+ NTSTATUS Status;
+ IO_STATUS_BLOCK io;
+ OBJECT_ATTRIBUTES attr;
+ UNICODE_STRING str;
+ PDB db;
+
+ if (type == DOS_PATH)
+ {
+ if (!RtlDosPathNameToNtPathName_U(path, &str, NULL, NULL))
+ return NULL;
+ }
+ else
+ RtlInitUnicodeString(&str, path);
+
/* SdbAlloc zeroes the memory. */
+ db = (PDB)SdbAlloc(sizeof(DB));
+ if (!db)
+ {
+ SHIM_ERR("Failed to allocate memory for shim database\n");
+ return NULL;
+ }
+
+ InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, NULL, NULL);
+
+ Status = NtCreateFile(&db->file, (write ? FILE_GENERIC_WRITE : FILE_GENERIC_READ )| SYNCHRONIZE,
+ &attr, &io, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
+ write ? FILE_SUPERSEDE : FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
+
+ if (type == DOS_PATH)
+ RtlFreeUnicodeString(&str);
+
+ if (!NT_SUCCESS(Status))
+ {
+ SdbCloseDatabase(db);
+ SHIM_ERR("Failed to create shim database file: %lx\n", Status);
+ return NULL;
+ }
+
return db;
}
+
+void WINAPI SdbpFlush(PDB db)
+{
+ IO_STATUS_BLOCK io;
+ NTSTATUS Status = NtWriteFile(db->file, NULL, NULL, NULL, &io,
+ db->data, db->write_iter, NULL, NULL);
+ if( !NT_SUCCESS(Status))
+ SHIM_WARN("failed with 0x%lx\n", Status);
+}
+
DWORD SdbpStrlen(PCWSTR string)
{
- return (lstrlenW(string) + 1) * sizeof(WCHAR);
+ return lstrlenW(string);
+}
+
+DWORD SdbpStrsize(PCWSTR string)
+{
+ return (SdbpStrlen(string) + 1) * sizeof(WCHAR);
}
PWSTR SdbpStrDup(LPCWSTR string)
{
- PWSTR ret = SdbpAlloc(SdbpStrlen(string));
+ PWSTR ret = SdbpAlloc(SdbpStrsize(string));
lstrcpyW(ret, string);
return ret;
}
PDB SdbpOpenDatabase(LPCWSTR path, PATH_TYPE type, PDWORD major, PDWORD minor)
{
- UNICODE_STRING str;
- OBJECT_ATTRIBUTES attr;
IO_STATUS_BLOCK io;
PDB db;
NTSTATUS Status;
BYTE header[12];
- if (type == DOS_PATH)
- {
- if (!RtlDosPathNameToNtPathName_U(path, &str, NULL, NULL))
- return NULL;
- }
- else
- RtlInitUnicodeString(&str, path);
-
- db = SdbpCreate();
+ db = SdbpCreate(path, type, FALSE);
if (!db)
- {
- SHIM_ERR("Failed to allocate memory for shim database\n");
return NULL;
- }
-
- InitializeObjectAttributes(&attr, &str, OBJ_CASE_INSENSITIVE, NULL, NULL);
-
- Status = NtCreateFile(&db->file, FILE_GENERIC_READ | SYNCHRONIZE,
- &attr, &io, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
- FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
-
- if (type == DOS_PATH)
- RtlFreeUnicodeString(&str);
-
- if (!NT_SUCCESS(Status))
- {
- SdbCloseDatabase(db);
- SHIM_ERR("Failed to open shim database file: 0x%lx\n", Status);
- return NULL;
- }
db->size = GetFileSize(db->file, NULL);
db->data = SdbAlloc(db->size);
if (db->file)
NtClose(db->file);
+ if (db->string_buffer)
+ SdbCloseDatabase(db->string_buffer);
+ if (db->string_lookup)
+ SdbpTableDestroy(&db->string_lookup);
SdbFree(db->data);
SdbFree(db);
}
BOOL WINAPI SdbGetAppPatchDir(HSDB db, LPWSTR path, DWORD size)
{
static WCHAR* default_dir = NULL;
+ static CONST WCHAR szAppPatch[] = {'\\','A','p','p','P','a','t','c','h',0};
+
+ /* In case function fails, path holds empty string */
+ if (size > 0)
+ *path = 0;
- if(!default_dir)
+ if (!default_dir)
{
WCHAR* tmp = NULL;
- UINT len = GetSystemWindowsDirectoryW(NULL, 0) + lstrlenW((CONST WCHAR[]){'\\','A','p','p','P','a','t','c','h',0});
+ UINT len = GetSystemWindowsDirectoryW(NULL, 0) + lstrlenW(szAppPatch);
tmp = SdbAlloc((len + 1)* sizeof(WCHAR));
- if(tmp)
+ if (tmp)
{
UINT r = GetSystemWindowsDirectoryW(tmp, len+1);
if (r && r < len)
{
- if (SUCCEEDED(StringCchCatW(tmp, len+1, (CONST WCHAR[]){'\\','A','p','p','P','a','t','c','h',0})))
+ if (SUCCEEDED(StringCchCatW(tmp, len+1, szAppPatch)))
{
- if(InterlockedCompareExchangePointer((void**)&default_dir, tmp, NULL) == NULL)
+ if (InterlockedCompareExchangePointer((void**)&default_dir, tmp, NULL) == NULL)
tmp = NULL;
}
}
if (tmp)
SdbFree(tmp);
}
+ if (!default_dir)
+ {
+ SHIM_ERR("Unable to obtain default AppPatch directory\n");
+ return FALSE;
+ }
}
- /* In case function fails, path holds empty string */
- if (size > 0)
- *path = 0;
-
if (!db)
{
return SUCCEEDED(StringCchCopyW(path, size, default_dir));
return TRUE;
}
+
+/**
+ * Converts the specified string to an index key.
+ *
+ * @param [in] str The string which will be converted.
+ *
+ * @return The resulting index key
+ *
+ * @todo: Fix this for unicode strings.
+ */
+LONGLONG WINAPI SdbMakeIndexKeyFromString(LPCWSTR str)
+{
+ LONGLONG result = 0;
+ int shift = 56;
+
+ while (*str && shift >= 0)
+ {
+ WCHAR c = toupper(*(str++));
+
+ if (c & 0xff)
+ {
+ result |= (((LONGLONG)(c & 0xff)) << shift);
+ shift -= 8;
+ }
+
+ if (shift < 0)
+ break;
+
+ c >>= 8;
+
+ if (c & 0xff)
+ {
+ result |= (((LONGLONG)(c & 0xff)) << shift);
+ shift -= 8;
+ }
+ }
+
+ return result;
+}
+
+
/**
* Converts specified tag into a string.
*