[APPHELP] Various cleanup tasks

- Move debug heap functionality to a separate file
- Clean includes
- Remove msvcrt dependency
- Clean up string usage
- Remove some higher level functions in favor of their ntdll counterparts (wip).

svn path=/trunk/; revision=75432
This commit is contained in:
Mark Jansen 2017-07-28 19:00:27 +00:00
parent 9f2558d971
commit 63568c9f24
8 changed files with 222 additions and 153 deletions

View file

@ -9,6 +9,7 @@ spec2def(apphelp.dll apphelp.spec ADD_IMPORTLIB)
list(APPEND SOURCE
apphelp.c
dbgheap.c
hsdb.c
layer.c
sdbapi.c
@ -26,8 +27,7 @@ add_library(apphelp SHARED
apphelp.rc
${CMAKE_CURRENT_BINARY_DIR}/apphelp.def)
set_module_type(apphelp win32dll)
target_link_libraries(apphelp wine)
set_module_type(apphelp win32dll UNICODE ENTRYPOINT DllMain 12)
add_delay_importlibs(apphelp version)
add_importlibs(apphelp msvcrt kernel32 ntdll)
add_importlibs(apphelp kernel32 ntdll)
add_cd_file(TARGET apphelp DESTINATION reactos/system32 FOR all)

View file

@ -0,0 +1,177 @@
/*
* Copyright 2017 Mark Jansen (mark.jansen@reactos.org)
*
* 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
*/
#define WIN32_NO_STATUS
#include "ntndk.h"
#if SDBAPI_DEBUG_ALLOC
#define TRACE_ALL_FREE_CALLS 1
typedef struct SHIM_ALLOC_ENTRY
{
PVOID Address;
SIZE_T Size;
int Line;
const char* File;
PVOID Next;
PVOID Prev;
} SHIM_ALLOC_ENTRY, *PSHIM_ALLOC_ENTRY;
static RTL_CRITICAL_SECTION g_SdbpAllocationLock;
static RTL_AVL_TABLE g_SdbpAllocationTable;
static HANDLE g_PrivAllocationHeap;
static RTL_GENERIC_COMPARE_RESULTS
NTAPI ShimAllocCompareRoutine(_In_ PRTL_AVL_TABLE Table, _In_ PVOID FirstStruct, _In_ PVOID SecondStruct)
{
PVOID First = ((PSHIM_ALLOC_ENTRY)FirstStruct)->Address;
PVOID Second = ((PSHIM_ALLOC_ENTRY)SecondStruct)->Address;
if (First < Second)
return GenericLessThan;
else if (First == Second)
return GenericEqual;
return GenericGreaterThan;
}
static PVOID NTAPI ShimAllocAllocateRoutine(_In_ PRTL_AVL_TABLE Table, _In_ CLONG ByteSize)
{
return RtlAllocateHeap(g_PrivAllocationHeap, HEAP_ZERO_MEMORY, ByteSize);
}
static VOID NTAPI ShimAllocFreeRoutine(_In_ PRTL_AVL_TABLE Table, _In_ PVOID Buffer)
{
RtlFreeHeap(g_PrivAllocationHeap, 0, Buffer);
}
void SdbpInsertAllocation(PVOID address, SIZE_T size, int line, const char* file)
{
SHIM_ALLOC_ENTRY Entry = {0};
Entry.Address = address;
Entry.Size = size;
Entry.Line = line;
Entry.File = file;
RtlEnterCriticalSection(&g_SdbpAllocationLock);
RtlInsertElementGenericTableAvl(&g_SdbpAllocationTable, &Entry, sizeof(Entry), NULL);
RtlLeaveCriticalSection(&g_SdbpAllocationLock);
}
void SdbpUpdateAllocation(PVOID address, PVOID newaddress, SIZE_T size, int line, const char* file)
{
SHIM_ALLOC_ENTRY Lookup = {0};
PSHIM_ALLOC_ENTRY Entry;
Lookup.Address = address;
RtlEnterCriticalSection(&g_SdbpAllocationLock);
Entry = RtlLookupElementGenericTableAvl(&g_SdbpAllocationTable, &Lookup);
if (address == newaddress)
{
Entry->Size = size;
}
else
{
Lookup.Address = newaddress;
Lookup.Size = size;
Lookup.Line = line;
Lookup.File = file;
Lookup.Prev = address;
RtlInsertElementGenericTableAvl(&g_SdbpAllocationTable, &Lookup, sizeof(Lookup), NULL);
Entry->Next = newaddress;
}
RtlLeaveCriticalSection(&g_SdbpAllocationLock);
}
static void SdbpPrintSingleAllocation(PSHIM_ALLOC_ENTRY Entry)
{
DbgPrint(" > %s(%d): %s%sAlloc( %d ) ==> %p\r\n", Entry->File, Entry->Line,
Entry->Next ? "Invalidated " : "", Entry->Prev ? "Re" : "", Entry->Size, Entry->Address);
}
void SdbpRemoveAllocation(PVOID address, int line, const char* file)
{
SHIM_ALLOC_ENTRY Lookup = {0};
PSHIM_ALLOC_ENTRY Entry;
#if TRACE_ALL_FREE_CALLS
DbgPrint("\r\n===============\r\n%s(%d): SdbpFree called, tracing alloc:\r\n", file, line);
#endif
Lookup.Address = address;
RtlEnterCriticalSection(&g_SdbpAllocationLock);
while (Lookup.Address)
{
Entry = RtlLookupElementGenericTableAvl(&g_SdbpAllocationTable, &Lookup);
if (Entry)
{
Lookup = *Entry;
RtlDeleteElementGenericTableAvl(&g_SdbpAllocationTable, Entry);
#if TRACE_ALL_FREE_CALLS
SdbpPrintSingleAllocation(&Lookup);
#endif
Lookup.Address = Lookup.Prev;
}
else
{
Lookup.Address = NULL;
}
}
RtlLeaveCriticalSection(&g_SdbpAllocationLock);
#if TRACE_ALL_FREE_CALLS
DbgPrint("===============\r\n");
#endif
}
void SdbpDebugHeapInit(HANDLE privateHeapPtr)
{
g_PrivAllocationHeap = privateHeapPtr;
RtlInitializeCriticalSection(&g_SdbpAllocationLock);
RtlInitializeGenericTableAvl(&g_SdbpAllocationTable, ShimAllocCompareRoutine,
ShimAllocAllocateRoutine, ShimAllocFreeRoutine, NULL);
}
void SdbpDebugHeapDeinit(void)
{
if (g_SdbpAllocationTable.NumberGenericTableElements != 0)
{
PSHIM_ALLOC_ENTRY Entry;
DbgPrint("\r\n===============\r\n===============\r\nSdbpHeapDeinit: Dumping leaks\r\n");
RtlEnterCriticalSection(&g_SdbpAllocationLock);
Entry = RtlEnumerateGenericTableAvl(&g_SdbpAllocationTable, TRUE);
while (Entry)
{
SdbpPrintSingleAllocation(Entry);
Entry = RtlEnumerateGenericTableAvl(&g_SdbpAllocationTable, FALSE);
}
RtlLeaveCriticalSection(&g_SdbpAllocationLock);
DbgPrint("===============\r\n===============\r\n");
}
/*__debugbreak();*/
/*RtlDeleteCriticalSection(&g_SdbpAllocationLock);*/
}
#endif

View file

@ -1,7 +1,7 @@
/*
* Copyright 2011 André Hentschel
* Copyright 2013 Mislav Blažević
* Copyright 2015-2017 Mark Jansen
* Copyright 2015-2017 Mark Jansen (mark.jansen@reactos.org)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -24,7 +24,6 @@
#include "strsafe.h"
#include "apphelp.h"
#include "wine/unicode.h"
#define MAX_LAYER_LENGTH 256
#define GPLK_USER 1
@ -385,8 +384,8 @@ HSDB WINAPI SdbInitDatabase(DWORD flags, LPCWSTR path)
SdbReleaseDatabase(hsdb);
return NULL;
}
SdbGetAppPatchDir(NULL, buffer, 128);
memcpy(buffer + lstrlenW(buffer), name, SdbpStrsize(name));
SdbGetAppPatchDir(NULL, buffer, _countof(buffer));
StringCchCatW(buffer, _countof(buffer), name);
flags = HID_DOS_PATHS;
}
@ -481,7 +480,7 @@ BOOL WINAPI SdbGetMatchingExe(HSDB hsdb, LPCWSTR path, LPCWSTR module_name,
/* Extract file name */
file_name = strrchrW(DosApplicationName.String.Buffer, '\\');
file_name = wcsrchr(DosApplicationName.String.Buffer, '\\');
if (!file_name)
{
SHIM_ERR("Failed to find Exe name in %wZ.", &DosApplicationName.String);
@ -578,7 +577,7 @@ BOOL WINAPI SdbGetAppPatchDir(HSDB db, LPWSTR path, DWORD size)
if (!default_dir)
{
WCHAR* tmp;
UINT len = GetSystemWindowsDirectoryW(NULL, 0) + lstrlenW(szAppPatch);
UINT len = GetSystemWindowsDirectoryW(NULL, 0) + SdbpStrlen(szAppPatch);
tmp = SdbAlloc((len + 1)* sizeof(WCHAR));
if (tmp)
{

View file

@ -1,5 +1,5 @@
/*
* Copyright 2015 Mark Jansen
* Copyright 2015-2017 Mark Jansen (mark.jansen@reactos.org)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -159,7 +159,7 @@ BOOL SdbpBuildSignMediaId(PSDB_TMP_STR LongPath)
FindClose(FindHandle);
SdbpResizeTempStr(LongPath, (LongPath->Str.Length >> 1) + 20);
StringCbPrintfW(LongPath->Str.Buffer, LongPath->Str.MaximumLength, SIGN_MEDIA_FMT, SignMedia, Scratch.Str.Buffer + 3);
LongPath->Str.Length = (USHORT)wcslen(LongPath->Str.Buffer) * sizeof(WCHAR);
LongPath->Str.Length = (USHORT)SdbpStrlen(LongPath->Str.Buffer) * sizeof(WCHAR);
SdbpFreeTempStr(&Scratch);
return TRUE;
}
@ -217,7 +217,7 @@ NTSTATUS SdbpOpenKey(PUNICODE_STRING FullPath, BOOL bMachine, ACCESS_MASK Access
return Status;
}
}
FullPath->MaximumLength = (USHORT)(BasePath.Length + (wcslen(LayersKey) + 1) * sizeof(WCHAR));
FullPath->MaximumLength = (USHORT)(BasePath.Length + SdbpStrsize(LayersKey));
FullPath->Buffer = SdbAlloc(FullPath->MaximumLength);
FullPath->Length = 0;
RtlAppendUnicodeStringToString(FullPath, &BasePath);
@ -447,7 +447,7 @@ BOOL WINAPI SdbSetPermLayerKeys(PCWSTR wszPath, PCWSTR wszLayers, BOOL bMachine)
Status = SdbpOpenKey(&FullKey, bMachine, KEY_SET_VALUE, &KeyHandle);
if (NT_SUCCESS(Status))
{
Status = NtSetValueKey(KeyHandle, &LongPath.Str, 0, REG_SZ, (PVOID)wszLayers, (wcslen(wszLayers)+1) * sizeof(WCHAR));
Status = NtSetValueKey(KeyHandle, &LongPath.Str, 0, REG_SZ, (PVOID)wszLayers, SdbpStrsize(wszLayers));
if (!NT_SUCCESS(Status))
{
SHIM_INFO("Failed to write a value to Key \"%wZ\" Status 0x%lx\n", &FullKey, Status);

View file

@ -18,15 +18,11 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define WIN32_NO_STATUS
#include "windows.h"
#include "ntndk.h"
#include "strsafe.h"
#include "apphelp.h"
#include "sdbstringtable.h"
#include "wine/unicode.h"
static const GUID GUID_DATABASE_MSI = {0xd8ff6d16,0x6a3a,0x468a, {0x8b,0x44,0x01,0x71,0x4d,0xdc,0x49,0xea}};
static const GUID GUID_DATABASE_SHIM = {0x11111111,0x1111,0x1111, {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}};
@ -36,139 +32,30 @@ static HANDLE SdbpHeap(void);
#if SDBAPI_DEBUG_ALLOC
typedef struct SHIM_ALLOC_ENTRY
{
PVOID Address;
SIZE_T Size;
int Line;
const char* File;
PVOID Next;
PVOID Prev;
} SHIM_ALLOC_ENTRY, *PSHIM_ALLOC_ENTRY;
/* FIXME: This is not threadsafe */
static RTL_AVL_TABLE g_SdbpAllocationTable;
static RTL_GENERIC_COMPARE_RESULTS
NTAPI ShimAllocCompareRoutine(_In_ PRTL_AVL_TABLE Table, _In_ PVOID FirstStruct, _In_ PVOID SecondStruct)
{
PVOID First = ((PSHIM_ALLOC_ENTRY)FirstStruct)->Address;
PVOID Second = ((PSHIM_ALLOC_ENTRY)SecondStruct)->Address;
if (First < Second)
return GenericLessThan;
else if (First == Second)
return GenericEqual;
return GenericGreaterThan;
}
static PVOID NTAPI ShimAllocAllocateRoutine(_In_ PRTL_AVL_TABLE Table, _In_ CLONG ByteSize)
{
return HeapAlloc(SdbpHeap(), HEAP_ZERO_MEMORY, ByteSize);
}
static VOID NTAPI ShimAllocFreeRoutine(_In_ PRTL_AVL_TABLE Table, _In_ PVOID Buffer)
{
HeapFree(SdbpHeap(), 0, Buffer);
}
static void SdbpInsertAllocation(PVOID address, SIZE_T size, int line, const char* file)
{
SHIM_ALLOC_ENTRY Entry = {0};
Entry.Address = address;
Entry.Size = size;
Entry.Line = line;
Entry.File = file;
RtlInsertElementGenericTableAvl(&g_SdbpAllocationTable, &Entry, sizeof(Entry), NULL);
}
static void SdbpUpdateAllocation(PVOID address, PVOID newaddress, SIZE_T size, int line, const char* file)
{
SHIM_ALLOC_ENTRY Lookup = {0};
PSHIM_ALLOC_ENTRY Entry;
Lookup.Address = address;
Entry = RtlLookupElementGenericTableAvl(&g_SdbpAllocationTable, &Lookup);
if (address == newaddress)
{
Entry->Size = size;
}
else
{
Lookup.Address = newaddress;
Lookup.Size = size;
Lookup.Line = line;
Lookup.File = file;
Lookup.Prev = address;
RtlInsertElementGenericTableAvl(&g_SdbpAllocationTable, &Lookup, sizeof(Lookup), NULL);
Entry->Next = newaddress;
}
}
static void SdbpRemoveAllocation(PVOID address, int line, const char* file)
{
SHIM_ALLOC_ENTRY Lookup = {0};
PSHIM_ALLOC_ENTRY Entry;
DbgPrint("\r\n===============\r\n%s(%d): SdbpFree called, tracing alloc:\r\n", file, line);
Lookup.Address = address;
while (Lookup.Address)
{
Entry = RtlLookupElementGenericTableAvl(&g_SdbpAllocationTable, &Lookup);
if (Entry)
{
Lookup = *Entry;
RtlDeleteElementGenericTableAvl(&g_SdbpAllocationTable, Entry);
DbgPrint(" > %s(%d): %s%sAlloc( %d ) ==> %p\r\n", Lookup.File, Lookup.Line,
Lookup.Next ? "Invalidated " : "", Lookup.Prev ? "Re" : "", Lookup.Size, Lookup.Address);
Lookup.Address = Lookup.Prev;
}
else
{
Lookup.Address = NULL;
}
}
DbgPrint("===============\r\n");
}
/* dbgheap.c */
void SdbpInsertAllocation(PVOID address, SIZE_T size, int line, const char* file);
void SdbpUpdateAllocation(PVOID address, PVOID newaddress, SIZE_T size, int line, const char* file);
void SdbpRemoveAllocation(PVOID address, int line, const char* file);
void SdbpDebugHeapInit(HANDLE privateHeapPtr);
void SdbpDebugHeapDeinit(void);
#endif
static HANDLE g_Heap;
void SdbpHeapInit(void)
{
g_Heap = RtlCreateHeap(HEAP_GROWABLE, NULL, 0, 0x10000, NULL, NULL);
#if SDBAPI_DEBUG_ALLOC
RtlInitializeGenericTableAvl(&g_SdbpAllocationTable, ShimAllocCompareRoutine,
ShimAllocAllocateRoutine, ShimAllocFreeRoutine, NULL);
SdbpDebugHeapInit(g_Heap);
#endif
g_Heap = HeapCreate(0, 0x10000, 0);
}
void SdbpHeapDeinit(void)
{
#if SDBAPI_DEBUG_ALLOC
if (g_SdbpAllocationTable.NumberGenericTableElements != 0)
{
PSHIM_ALLOC_ENTRY Entry;
DbgPrint("\r\n===============\r\n===============\r\nSdbpHeapDeinit: Dumping leaks\r\n");
Entry = RtlEnumerateGenericTableAvl(&g_SdbpAllocationTable, TRUE);
while (Entry)
{
DbgPrint(" > %s(%d): %s%sAlloc( %d ) ==> %p\r\n", Entry->File, Entry->Line,
Entry->Next ? "Invalidated " : "", Entry->Prev ? "Re" : "", Entry->Size, Entry->Address);
Entry = RtlEnumerateGenericTableAvl(&g_SdbpAllocationTable, FALSE);
}
DbgPrint("===============\r\n===============\r\n");
}
/*__debugbreak();*/
SdbpDebugHeapDeinit();
#endif
HeapDestroy(g_Heap);
RtlDestroyHeap(g_Heap);
}
static HANDLE SdbpHeap(void)
@ -182,7 +69,7 @@ LPVOID SdbpAlloc(SIZE_T size
#endif
)
{
LPVOID mem = HeapAlloc(SdbpHeap(), HEAP_ZERO_MEMORY, size);
LPVOID mem = RtlAllocateHeap(SdbpHeap(), HEAP_ZERO_MEMORY, size);
#if SDBAPI_DEBUG_ALLOC
SdbpInsertAllocation(mem, size, line, file);
#endif
@ -195,7 +82,7 @@ LPVOID SdbpReAlloc(LPVOID mem, SIZE_T size, SIZE_T oldSize
#endif
)
{
LPVOID newmem = HeapReAlloc(SdbpHeap(), HEAP_ZERO_MEMORY, mem, size);
LPVOID newmem = RtlReAllocateHeap(SdbpHeap(), HEAP_ZERO_MEMORY, mem, size);
#if SDBAPI_DEBUG_ALLOC
SdbpUpdateAllocation(mem, newmem, size, line, file);
#endif
@ -211,7 +98,7 @@ void SdbpFree(LPVOID mem
#if SDBAPI_DEBUG_ALLOC
SdbpRemoveAllocation(mem, line, file);
#endif
HeapFree(SdbpHeap(), 0, mem);
RtlFreeHeap(SdbpHeap(), 0, mem);
}
PDB WINAPI SdbpCreate(LPCWSTR path, PATH_TYPE type, BOOL write)
@ -228,7 +115,9 @@ PDB WINAPI SdbpCreate(LPCWSTR path, PATH_TYPE type, BOOL write)
return NULL;
}
else
{
RtlInitUnicodeString(&str, path);
}
/* SdbAlloc zeroes the memory. */
db = (PDB)SdbAlloc(sizeof(DB));
@ -268,7 +157,7 @@ void WINAPI SdbpFlush(PDB db)
DWORD SdbpStrlen(PCWSTR string)
{
return lstrlenW(string);
return wcslen(string);
}
DWORD SdbpStrsize(PCWSTR string)
@ -279,7 +168,7 @@ DWORD SdbpStrsize(PCWSTR string)
PWSTR SdbpStrDup(LPCWSTR string)
{
PWSTR ret = SdbAlloc(SdbpStrsize(string));
lstrcpyW(ret, string);
wcscpy(ret, string);
return ret;
}
@ -379,6 +268,7 @@ BOOL WINAPI SdbpCheckTagIDType(PDB db, TAGID tagid, WORD type)
PDB SdbpOpenDatabase(LPCWSTR path, PATH_TYPE type, PDWORD major, PDWORD minor)
{
IO_STATUS_BLOCK io;
FILE_STANDARD_INFORMATION fsi;
PDB db;
NTSTATUS Status;
BYTE header[12];
@ -387,7 +277,15 @@ PDB SdbpOpenDatabase(LPCWSTR path, PATH_TYPE type, PDWORD major, PDWORD minor)
if (!db)
return NULL;
db->size = GetFileSize(db->file, NULL);
Status = NtQueryInformationFile(db->file, &io, &fsi, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation);
if (!NT_SUCCESS(Status))
{
SdbCloseDatabase(db);
SHIM_ERR("Failed to get shim database size: 0x%lx\n", Status);
return NULL;
}
db->size = fsi.EndOfFile.u.LowPart;
db->data = SdbAlloc(db->size);
Status = NtReadFile(db->file, NULL, NULL, NULL, &io, db->data, db->size, NULL, NULL);
@ -597,7 +495,7 @@ TAGID WINAPI SdbFindFirstNamedTag(PDB db, TAGID root, TAGID find, TAGID nametag,
if (tmp != TAGID_NULL)
{
LPCWSTR name = SdbGetStringTagPtr(db, tmp);
if (name && !lstrcmpiW(name, find_name))
if (name && !wcsicmp(name, find_name))
return iter;
}
iter = SdbFindNextTag(db, root, iter);

View file

@ -20,13 +20,11 @@
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "apphelp.h"
#include "imagehlp.h"
#include "strsafe.h"
#include "winver.h"
#include "rtlfuncs.h"
#include "wine/unicode.h"
#define NUM_ATTRIBUTES 28
enum APPHELP_MODULETYPE
@ -79,7 +77,7 @@ static WCHAR* WINAPI SdbpGetStringAttr(LPWSTR translation, LPCWSTR attr, PVOID f
if (!file_info)
return NULL;
snprintfW(value, 128, translation, attr);
StringCchPrintfW(value, ARRAYSIZE(value), translation, attr);
if (VerQueryValueW(file_info, value, &buffer, &size) && size != 0)
return (WCHAR*)buffer;
@ -309,7 +307,7 @@ BOOL WINAPI SdbGetFileAttributes(LPCWSTR path, PATTRINFO *attr_info_ret, LPDWORD
file_info = SdbAlloc(info_size);
GetFileVersionInfoW(path, 0, info_size, file_info);
VerQueryValueW(file_info, str_tinfo, (LPVOID)&lang_page, &page_size);
snprintfW(translation, 128, str_trans, lang_page->language, lang_page->code_page);
StringCchPrintfW(translation, ARRAYSIZE(translation), str_trans, lang_page->language, lang_page->code_page);
}
/* Handles 2, 3, 12, 13, 14, 15, 21, 22 */

View file

@ -1,7 +1,7 @@
/*
* Copyright 2011 André Hentschel
* Copyright 2013 Mislav Blaževic
* Copyright 2015,2016 Mark Jansen
* Copyright 2015-2017 Mark Jansen (mark.jansen@reactos.org)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -19,11 +19,8 @@
*/
#include "windef.h"
#include "winbase.h"
#include "apphelp.h"
#include "wine/unicode.h"
DWORD WINAPI SdbGetTagDataSize(PDB db, TAGID tagid);

View file

@ -20,7 +20,7 @@
#if !defined(SDBWRITE_HOSTTOOL)
#define WIN32_NO_STATUS
#include "windows.h"
#include "windef.h"
#include "ntndk.h"
#else
#include <typedefs.h>