Author: mjansen
Date: Sat Jun 11 21:12:43 2016
New Revision: 71614
URL:
http://svn.reactos.org/svn/reactos?rev=71614&view=rev
Log:
[APPHELP] Implement automatic stringtable generation when writing an Sdb database.
CORE-10367
Added:
trunk/reactos/dll/appcompat/apphelp/sdbstringtable.c (with props)
trunk/reactos/dll/appcompat/apphelp/sdbstringtable.h (with props)
trunk/reactos/dll/appcompat/hacking.txt (with props)
Modified:
trunk/reactos/dll/appcompat/apphelp/CMakeLists.txt
trunk/reactos/dll/appcompat/apphelp/apphelp.h
trunk/reactos/dll/appcompat/apphelp/sdbapi.c
trunk/reactos/dll/appcompat/apphelp/sdbpapi.h
trunk/reactos/dll/appcompat/apphelp/sdbtypes.h
trunk/reactos/dll/appcompat/apphelp/sdbwrite.c
Modified: trunk/reactos/dll/appcompat/apphelp/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/apphelp/CMak…
==============================================================================
--- trunk/reactos/dll/appcompat/apphelp/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/dll/appcompat/apphelp/CMakeLists.txt [iso-8859-1] Sat Jun 11 21:12:43
2016
@@ -5,9 +5,10 @@
apphelp.c
layer.c
sdbapi.c
+ sdbfileattr.c
sdbread.c
+ sdbstringtable.c
sdbwrite.c
- sdbfileattr.c
apphelp.spec
apphelp.h
${CMAKE_CURRENT_BINARY_DIR}/apphelp_stubs.c)
Modified: trunk/reactos/dll/appcompat/apphelp/apphelp.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/apphelp/apph…
==============================================================================
--- trunk/reactos/dll/appcompat/apphelp/apphelp.h [iso-8859-1] (original)
+++ trunk/reactos/dll/appcompat/apphelp/apphelp.h [iso-8859-1] Sat Jun 11 21:12:43 2016
@@ -50,26 +50,11 @@
};
} ATTRINFO, *PATTRINFO;
-typedef enum _SHIM_LOG_LEVEL {
- SHIM_ERR = 1,
- SHIM_WARN = 2,
- SHIM_INFO = 3,
-}SHIM_LOG_LEVEL;
-
/* apphelp.c */
-BOOL WINAPIV ShimDbgPrint(SHIM_LOG_LEVEL Level, PCSTR FunctionName, PCSTR Format, ...);
-extern ULONG g_ShimDebugLevel;
-
-#define SHIM_ERR(fmt, ...) do { if (g_ShimDebugLevel) ShimDbgPrint(SHIM_ERR,
__FUNCTION__, fmt, ##__VA_ARGS__ ); } while (0)
-#define SHIM_WARN(fmt, ...) do { if (g_ShimDebugLevel) ShimDbgPrint(SHIM_WARN,
__FUNCTION__, fmt, ##__VA_ARGS__ ); } while (0)
-#define SHIM_INFO(fmt, ...) do { if (g_ShimDebugLevel) ShimDbgPrint(SHIM_INFO,
__FUNCTION__, fmt, ##__VA_ARGS__ ); } while (0)
-
#include "sdbpapi.h"
PWSTR SdbpStrDup(LPCWSTR string);
-BOOL WINAPI SdbpCheckTagType(TAG tag, WORD type);
-BOOL WINAPI SdbpCheckTagIDType(PDB db, TAGID tagid, WORD type);
PDB WINAPI SdbOpenDatabase(LPCWSTR path, PATH_TYPE type);
void WINAPI SdbCloseDatabase(PDB);
Modified: trunk/reactos/dll/appcompat/apphelp/sdbapi.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/apphelp/sdba…
==============================================================================
--- trunk/reactos/dll/appcompat/apphelp/sdbapi.c [iso-8859-1] (original)
+++ trunk/reactos/dll/appcompat/apphelp/sdbapi.c [iso-8859-1] Sat Jun 11 21:12:43 2016
@@ -23,6 +23,7 @@
#include "ntndk.h"
#include "strsafe.h"
#include "apphelp.h"
+#include "sdbstringtable.h"
#include "wine/unicode.h"
@@ -228,9 +229,6 @@
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);
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);
@@ -454,6 +452,10 @@
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);
}
Modified: trunk/reactos/dll/appcompat/apphelp/sdbpapi.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/apphelp/sdbp…
==============================================================================
--- trunk/reactos/dll/appcompat/apphelp/sdbpapi.h [iso-8859-1] (original)
+++ trunk/reactos/dll/appcompat/apphelp/sdbpapi.h [iso-8859-1] Sat Jun 11 21:12:43 2016
@@ -68,6 +68,22 @@
DWORD SdbpStrlen(PCWSTR string);
DWORD SdbpStrsize(PCWSTR string);
+BOOL WINAPI SdbpCheckTagType(TAG tag, WORD type);
+BOOL WINAPI SdbpCheckTagIDType(PDB db, TAGID tagid, WORD type);
+
+
+typedef enum _SHIM_LOG_LEVEL {
+ SHIM_ERR = 1,
+ SHIM_WARN = 2,
+ SHIM_INFO = 3,
+} SHIM_LOG_LEVEL;
+
+BOOL WINAPIV ShimDbgPrint(SHIM_LOG_LEVEL Level, PCSTR FunctionName, PCSTR Format, ...);
+extern ULONG g_ShimDebugLevel;
+
+#define SHIM_ERR(fmt, ...) do { if (g_ShimDebugLevel) ShimDbgPrint(SHIM_ERR,
__FUNCTION__, fmt, ##__VA_ARGS__ ); } while (0)
+#define SHIM_WARN(fmt, ...) do { if (g_ShimDebugLevel) ShimDbgPrint(SHIM_WARN,
__FUNCTION__, fmt, ##__VA_ARGS__ ); } while (0)
+#define SHIM_INFO(fmt, ...) do { if (g_ShimDebugLevel) ShimDbgPrint(SHIM_INFO,
__FUNCTION__, fmt, ##__VA_ARGS__ ); } while (0)
#ifdef __cplusplus
} // extern "C"
Added: trunk/reactos/dll/appcompat/apphelp/sdbstringtable.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/apphelp/sdbs…
==============================================================================
--- trunk/reactos/dll/appcompat/apphelp/sdbstringtable.c (added)
+++ trunk/reactos/dll/appcompat/apphelp/sdbstringtable.c [iso-8859-1] Sat Jun 11 21:12:43
2016
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2016 Mark Jansen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#if !defined(SDBWRITE_HOSTTOOL)
+#define WIN32_NO_STATUS
+#include "windows.h"
+#include "sdbtypes.h"
+#include "sdbpapi.h"
+#else /* !defined(SDBWRITE_HOSTTOOL) */
+#include <typedefs.h>
+#include "sdbtypes.h"
+#include "sdbpapi.h"
+#endif /* !defined(SDBWRITE_HOSTTOOL) */
+
+#include "sdbstringtable.h"
+
+#define DEFAULT_TABLE_SIZE 0x100
+
+typedef struct SdbHashEntry
+{
+ struct SdbHashEntry* Next;
+ TAGID Tagid;
+ WCHAR Name[1];
+} SdbHashEntry;
+
+struct SdbStringHashTable
+{
+ DWORD Size;
+ struct SdbHashEntry** Entries;
+};
+
+
+static struct SdbStringHashTable* HashCreate(void)
+{
+ struct SdbStringHashTable* tab = SdbAlloc(sizeof(*tab));
+ if (!tab)
+ {
+ SHIM_ERR("Failed to allocate 8 bytes.\r\n");
+ return tab;
+ }
+ tab->Size = DEFAULT_TABLE_SIZE;
+ tab->Entries = SdbAlloc(tab->Size * sizeof(*tab->Entries));
+ return tab;
+}
+
+
+void SdbpTableDestroy(struct SdbStringHashTable** pTable)
+{
+ struct SdbStringHashTable* table = *pTable;
+ struct SdbHashEntry* entry, *next;
+ DWORD n, depth = 0, once = 1;
+
+ *pTable = NULL;
+ for (n = 0; n < table->Size; ++n)
+ {
+ depth = 0;
+ entry = next = table->Entries[n];
+ while (entry)
+ {
+ next = entry->Next;
+ SdbFree(entry);
+ entry = next;
+ depth++;
+ }
+ if (once && depth > 3)
+ {
+ // warn
+ once = 0;
+ }
+ }
+ SdbFree(table->Entries);
+ SdbFree(table);
+}
+
+/* Based on RtlHashUnicodeString */
+static DWORD StringHash(const WCHAR* str)
+{
+ DWORD hash = 0;
+ for (; *str; str++)
+ {
+ hash = ((65599 * hash) + (ULONG)(*str));
+ }
+ return hash;
+}
+
+static struct SdbHashEntry** TableFindPtr(struct SdbStringHashTable* table, const WCHAR*
str)
+{
+ DWORD hash = StringHash(str);
+ struct SdbHashEntry** entry = &table->Entries[hash % table->Size];
+ while (*entry)
+ {
+ if (!wcscmp((*entry)->Name, str))
+ return entry;
+ entry = &(*entry)->Next;
+ }
+ return entry;
+}
+
+static BOOL HashAddString(struct SdbStringHashTable* table, struct SdbHashEntry**
position, const WCHAR* str, TAGID tagid)
+{
+ struct SdbHashEntry* entry;
+ SIZE_T size;
+
+ if (!position)
+ position = TableFindPtr(table, str);
+
+ size = offsetof(struct SdbHashEntry, Name[SdbpStrlen(str) + 2]);
+ entry = (*position) = SdbAlloc(size);
+ if (!entry)
+ {
+ SHIM_ERR("Failed to allocate %u bytes.", size);
+ return FALSE;
+ }
+ entry->Tagid = tagid;
+ wcscpy(entry->Name, str);
+ return TRUE;
+}
+
+
+BOOL SdbpAddStringToTable(struct SdbStringHashTable** table, const WCHAR* str, TAGID*
tagid)
+{
+ struct SdbHashEntry** entry;
+
+ if (!*table)
+ {
+ *table = HashCreate();
+ if (!*table)
+ {
+ SHIM_ERR("Error creating hash table\n");
+ return FALSE;
+ }
+ }
+
+ entry = TableFindPtr(*table, str);
+ if (*entry)
+ {
+ *tagid = (*entry)->Tagid;
+ return FALSE;
+ }
+ return HashAddString(*table, entry, str, *tagid);
+}
+
Propchange: trunk/reactos/dll/appcompat/apphelp/sdbstringtable.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/dll/appcompat/apphelp/sdbstringtable.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/apphelp/sdbs…
==============================================================================
--- trunk/reactos/dll/appcompat/apphelp/sdbstringtable.h (added)
+++ trunk/reactos/dll/appcompat/apphelp/sdbstringtable.h [iso-8859-1] Sat Jun 11 21:12:43
2016
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2016 Mark Jansen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef SDBSTRINGTABLE_H
+#define SDBSTRINGTABLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * Destroy the hashtable and release all resources.
+ *
+ * @param [in] table Pointer to table pointer, will be cleared after use
+ *
+ */
+void SdbpTableDestroy(struct SdbStringHashTable* * table);
+
+/**
+ * Find an entry in the stringtable, or allocate it when an entry could not be found.
+ * - When the string specified does not yet exist, a new entry will be added to the
table,
+ * and the pTagid specified will be associated with this string.
+ * - When the string specified does already exist,
+ * the TAGID associated with this string will be returned in pTagid.
+ *
+ *
+ * @param [in] table Pointer to table pointer, will be allocated when needed.
+ * @param [in] str The string to search for
+ * @param [in,out] pTagid
+ * the data written (in bytes)
+ *
+ * @return TRUE if the string was added to the table, FALSE if it already existed
+ */
+BOOL SdbpAddStringToTable(struct SdbStringHashTable* * table, const WCHAR* str, TAGID*
pTagid);
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // SDBSTRINGTABLE_H
Propchange: trunk/reactos/dll/appcompat/apphelp/sdbstringtable.h
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/dll/appcompat/apphelp/sdbtypes.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/apphelp/sdbt…
==============================================================================
--- trunk/reactos/dll/appcompat/apphelp/sdbtypes.h [iso-8859-1] (original)
+++ trunk/reactos/dll/appcompat/apphelp/sdbtypes.h [iso-8859-1] Sat Jun 11 21:12:43 2016
@@ -39,6 +39,8 @@
TAGID stringtable;
DWORD write_iter;
GUID database_id;
+ struct SdbStringHashTable* string_lookup;
+ struct _DB* string_buffer;
} DB, *PDB;
typedef enum _PATH_TYPE {
Modified: trunk/reactos/dll/appcompat/apphelp/sdbwrite.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/apphelp/sdbw…
==============================================================================
--- trunk/reactos/dll/appcompat/apphelp/sdbwrite.c [iso-8859-1] (original)
+++ trunk/reactos/dll/appcompat/apphelp/sdbwrite.c [iso-8859-1] Sat Jun 11 21:12:43 2016
@@ -1,6 +1,6 @@
/*
- * Copyright 2011 André Hentschel
- * Copyright 2013 Mislav Blaevic
+ * Copyright 2011 André Hentschel
+ * Copyright 2013 Mislav BlaževiÄ
* Copyright 2015,2016 Mark Jansen
*
* This library is free software; you can redistribute it and/or
@@ -19,27 +19,28 @@
*/
#if !defined(SDBWRITE_HOSTTOOL)
-
#define WIN32_NO_STATUS
#include "windows.h"
#include "ntndk.h"
-#include "apphelp.h"
-#include "wine/unicode.h"
-
#else
-
#include <typedefs.h>
#include <guiddef.h>
+#endif
#include "sdbtypes.h"
#include "sdbpapi.h"
#include "sdbtagid.h"
-
-#endif
-
+#include "sdbstringtable.h"
+
+
+/* Local functions */
BOOL WINAPI SdbWriteStringRefTag(PDB db, TAG tag, TAGID tagid);
+BOOL WINAPI SdbWriteStringTag(PDB db, TAG tag, LPCWSTR string);
TAGID WINAPI SdbBeginWriteListTag(PDB db, TAG tag);
BOOL WINAPI SdbEndWriteListTag(PDB db, TAGID tagid);
+
+/* sdbapi.c */
+void WINAPI SdbCloseDatabase(PDB);
static void WINAPI SdbpWrite(PDB db, const void* data, DWORD size)
@@ -57,19 +58,35 @@
static BOOL WINAPI SdbpGetOrAddStringRef(PDB db, LPCWSTR string, TAGID* tagid)
{
- /* TODO:
- - Insert or find in stringtable
- - return TAGID
- */
-
- return FALSE;
-}
-
-static void WINAPI SdbpWriteStringtable(PDB db)
-{
- TAGID table = SdbBeginWriteListTag(db, TAG_STRINGTABLE);
- /* TODO: Write out all strings*/
- SdbEndWriteListTag(db, table);
+ PDB buf = db->string_buffer;
+ if (db->string_buffer == NULL)
+ {
+ db->string_buffer = buf = SdbpAlloc(sizeof(DB));
+ if (buf == NULL)
+ return FALSE;
+ buf->size = 128;
+ buf->data = SdbAlloc(buf->size);
+ if (buf->data == NULL)
+ return FALSE;
+ }
+
+ *tagid = buf->write_iter + sizeof(TAG) + sizeof(DWORD);
+ if (SdbpAddStringToTable(&db->string_lookup, string, tagid))
+ return SdbWriteStringTag(buf, TAG_STRINGTABLE_ITEM, string);
+
+ return db->string_lookup != NULL;
+}
+
+static BOOL WINAPI SdbpWriteStringtable(PDB db)
+{
+ TAGID table;
+ PDB buf = db->string_buffer;
+ if (buf == NULL || db->string_lookup == NULL)
+ return FALSE;
+
+ table = SdbBeginWriteListTag(db, TAG_STRINGTABLE);
+ SdbpWrite(db, buf->data, buf->write_iter);
+ return SdbEndWriteListTag(db, table);
}
/**
Added: trunk/reactos/dll/appcompat/hacking.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/appcompat/hacking.txt?…
==============================================================================
--- trunk/reactos/dll/appcompat/hacking.txt (added)
+++ trunk/reactos/dll/appcompat/hacking.txt [iso-8859-1] Sat Jun 11 21:12:43 2016
@@ -0,0 +1,23 @@
+
+Set the environment variable 'SHIM_DEBUG_LEVEL' to '4' before loading
apphelp.dll for debug info related to loading / matching modules.
+The environment variable 'SHIMENG_DEBUG_LEVEL' is related to the hooking code.
+
+
+When there is not enough debug output, force memory allocations to fail:
+
+pSdbCreateDatabase
+ [Err ][SdbpCreateFile ] Failed to convert DOS path "TEST1.SDB"
+ [Err ][SdbCreateDatabase ] Failed to create the database.
+ [Err ][SdbpWriteBufferedData] Failed to allocate 65548 bytes.
+
+pSdbWriteStringTag
+ [Err ][SdbpAddStringToTable] Error Gettting temp path 0x8
+ [Err ][SdbpCreateFile ] Failed to convert DOS path
"C:\Users\MAE67~1.JAN\AppData\Local\Temp\SDBAB16.tmp"
+ [Err ][SdbpAddStringToTable] Error copying string table temp filename
+ [Err ][HashCreate ] Failed to allocate 8 bytes.
+ [Err ][SdbpAddStringToTable] Error creating hash table
+ [Err ][HashAddString ] Failed to allocate 22 bytes.
+
+pSdbCloseDatabaseWrite
+ [Err ][SdbCloseDatabase ] Failed to close the file.
+ [Err ][SdbpDeleteFile ] Failed to convert DOS path
"C:\Users\MAE67~1.JAN\AppData\Local\Temp\SDBAB2D.tmp"
Propchange: trunk/reactos/dll/appcompat/hacking.txt
------------------------------------------------------------------------------
svn:eol-style = native