mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 12:23:31 +00:00
[APPHELP][APPHELP_APITEST] Partially implement SdbGetMatchingExe, SdbInitDatabase and SdbTagRefToTagID. CORE-10367
- SdbGetMatchingExe, SdbInitDatabase partial implementation by Mislav Blažević - Tests by me, they pass on vista - win10. (Win2k3 has another struct layout) - Move shared test functions to a common header - SdbTagRefToTagID misses functionality related to multiple databases, but that is not supported anywhere yet. svn path=/trunk/; revision=72549
This commit is contained in:
@@ -3,6 +3,7 @@ spec2def(apphelp.dll apphelp.spec ADD_IMPORTLIB)
|
||||
|
||||
list(APPEND SOURCE
|
||||
apphelp.c
|
||||
hsdb.c
|
||||
layer.c
|
||||
sdbapi.c
|
||||
sdbfileattr.c
|
||||
|
||||
@@ -40,7 +40,7 @@ void ApphelppInitDebugLevel(void)
|
||||
{
|
||||
UNICODE_STRING DebugKey, DebugValue;
|
||||
NTSTATUS Status;
|
||||
ULONG NewLevel = 0;
|
||||
ULONG NewLevel = SHIM_ERR;
|
||||
WCHAR Buffer[40];
|
||||
|
||||
RtlInitUnicodeString(&DebugKey, L"SHIM_DEBUG_LEVEL");
|
||||
|
||||
@@ -50,22 +50,58 @@ typedef struct tagATTRINFO {
|
||||
};
|
||||
} ATTRINFO, *PATTRINFO;
|
||||
|
||||
#define SDB_MAX_SDBS 16
|
||||
#define SDB_MAX_EXES 16
|
||||
#define SDB_MAX_LAYERS 8
|
||||
|
||||
/* Flags for adwExeFlags */
|
||||
#define SHIMREG_DISABLE_SHIM (0x00000001)
|
||||
#define SHIMREG_DISABLE_APPHELP (0x00000002)
|
||||
#define SHIMREG_APPHELP_NOUI (0x00000004)
|
||||
#define SHIMREG_APPHELP_CANCEL (0x10000000)
|
||||
#define SHIMREG_DISABLE_SXS (0x00000010)
|
||||
#define SHIMREG_DISABLE_LAYER (0x00000020)
|
||||
#define SHIMREG_DISABLE_DRIVER (0x00000040)
|
||||
|
||||
#define SDBGMEF_IGNORE_ENVIRONMENT (0x1)
|
||||
|
||||
typedef struct tagSDBQUERYRESULT {
|
||||
TAGREF atrExes[SDB_MAX_EXES];
|
||||
DWORD adwExeFlags[SDB_MAX_EXES];
|
||||
TAGREF atrLayers[SDB_MAX_LAYERS];
|
||||
DWORD dwLayerFlags;
|
||||
TAGREF trApphelp;
|
||||
DWORD dwExeCount;
|
||||
DWORD dwLayerCount;
|
||||
GUID guidID;
|
||||
DWORD dwFlags;
|
||||
DWORD dwCustomSDBMap;
|
||||
GUID rgGuidDB[SDB_MAX_SDBS];
|
||||
} SDBQUERYRESULT, *PSDBQUERYRESULT;
|
||||
|
||||
/* apphelp.c */
|
||||
|
||||
#include "sdbpapi.h"
|
||||
|
||||
PWSTR SdbpStrDup(LPCWSTR string);
|
||||
HSDB WINAPI SdbInitDatabase(DWORD, LPCWSTR);
|
||||
void WINAPI SdbReleaseDatabase(HSDB);
|
||||
|
||||
PDB WINAPI SdbOpenDatabase(LPCWSTR path, PATH_TYPE type);
|
||||
void WINAPI SdbCloseDatabase(PDB);
|
||||
BOOL WINAPI SdbIsNullGUID(CONST GUID *Guid);
|
||||
BOOL WINAPI SdbGetAppPatchDir(HSDB db, LPWSTR path, DWORD size);
|
||||
LPWSTR WINAPI SdbGetStringTagPtr(PDB db, TAGID tagid);
|
||||
|
||||
/* sdbread.c */
|
||||
BOOL WINAPI SdbpReadData(PDB db, PVOID dest, DWORD offset, DWORD num);
|
||||
TAG WINAPI SdbGetTagFromTagID(PDB db, TAGID tagid);
|
||||
TAGID WINAPI SdbFindFirstTag(PDB db, TAGID parent, TAG tag);
|
||||
TAGID WINAPI SdbFindNextTag(PDB db, TAGID parent, TAGID prev_child);
|
||||
BOOL WINAPI SdbGetDatabaseID(PDB db, GUID* Guid);
|
||||
|
||||
/* sdbfileattr.c*/
|
||||
BOOL WINAPI SdbFreeFileAttributes(PATTRINFO attr_info);
|
||||
|
||||
/* layer.c */
|
||||
BOOL WINAPI AllowPermLayer(PCWSTR path);
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
@ stub SdbGetLayerName
|
||||
@ stub SdbGetLayerTagRef
|
||||
@ stub SdbGetLocalPDB
|
||||
@ stub SdbGetMatchingExe
|
||||
@ stdcall SdbGetMatchingExe(ptr wstr wstr wstr long ptr)
|
||||
@ stub SdbGetMsiPackageInformation
|
||||
@ stub SdbGetNamedLayer
|
||||
@ stdcall SdbGetNextChild(ptr long long)
|
||||
@@ -87,7 +87,7 @@
|
||||
@ stub SdbGrabMatchingInfoEx
|
||||
@ stdcall SdbGUIDFromString(wstr ptr)
|
||||
@ stdcall SdbGUIDToString(ptr wstr long)
|
||||
@ stub SdbInitDatabase
|
||||
@ stdcall SdbInitDatabase(long wstr)
|
||||
@ stub SdbInitDatabaseEx
|
||||
@ stdcall SdbIsNullGUID(ptr)
|
||||
@ stub SdbIsStandardDatabase
|
||||
@@ -129,7 +129,7 @@
|
||||
@ stdcall SdbReadWORDTag(ptr long long)
|
||||
@ stub SdbReadWORDTagRef
|
||||
@ stub SdbRegisterDatabase
|
||||
@ stub SdbReleaseDatabase
|
||||
@ stdcall SdbReleaseDatabase(ptr)
|
||||
@ stub SdbReleaseMatchingExe
|
||||
@ stub SdbResolveDatabase
|
||||
@ stub SdbSetApphelpDebugParameters
|
||||
@@ -144,7 +144,7 @@
|
||||
@ stub SdbStringReplace
|
||||
@ stub SdbStringReplaceArray
|
||||
@ stub SdbTagIDToTagRef
|
||||
@ stub SdbTagRefToTagID
|
||||
@ stdcall SdbTagRefToTagID(ptr long ptr ptr)
|
||||
@ stdcall SdbTagToString(long)
|
||||
@ stub SdbUnregisterDatabase
|
||||
@ stdcall SdbWriteBinaryTag(ptr long ptr long)
|
||||
|
||||
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* 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
|
||||
* 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 "windows.h"
|
||||
#include "ntndk.h"
|
||||
#include "strsafe.h"
|
||||
#include "apphelp.h"
|
||||
//#include "sdbstringtable.h"
|
||||
|
||||
#include "wine/unicode.h"
|
||||
|
||||
|
||||
static BOOL WINAPI SdbpFileExists(LPCWSTR path)
|
||||
{
|
||||
DWORD attr = GetFileAttributesW(path);
|
||||
return (attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Opens specified shim database file Handle returned by this function may only be used by
|
||||
* functions which take HSDB param thus differing it from SdbOpenDatabase.
|
||||
*
|
||||
* @param [in] flags Specifies type of path or predefined database.
|
||||
* @param [in] path Path to the shim database file.
|
||||
*
|
||||
* @return Success: Handle to the opened shim database, NULL otherwise.
|
||||
*/
|
||||
HSDB WINAPI SdbInitDatabase(DWORD flags, LPCWSTR path)
|
||||
{
|
||||
static const WCHAR shim[] = {'\\','s','y','s','m','a','i','n','.','s','d','b',0};
|
||||
static const WCHAR msi[] = {'\\','m','s','i','m','a','i','n','.','s','d','b',0};
|
||||
static const WCHAR drivers[] = {'\\','d','r','v','m','a','i','n','.','s','d','b',0};
|
||||
LPCWSTR name;
|
||||
WCHAR buffer[128];
|
||||
HSDB sdb;
|
||||
|
||||
sdb = SdbAlloc(sizeof(SDB));
|
||||
if (!sdb)
|
||||
return NULL;
|
||||
sdb->auto_loaded = 0;
|
||||
|
||||
/* Check for predefined databases */
|
||||
if ((flags & HID_DATABASE_TYPE_MASK) && path == NULL)
|
||||
{
|
||||
switch (flags & HID_DATABASE_TYPE_MASK)
|
||||
{
|
||||
case SDB_DATABASE_MAIN_SHIM: name = shim; break;
|
||||
case SDB_DATABASE_MAIN_MSI: name = msi; break;
|
||||
case SDB_DATABASE_MAIN_DRIVERS: name = drivers; break;
|
||||
default: return NULL;
|
||||
}
|
||||
SdbGetAppPatchDir(NULL, buffer, 128);
|
||||
memcpy(buffer + lstrlenW(buffer), name, SdbpStrlen(name));
|
||||
}
|
||||
|
||||
sdb->db = SdbOpenDatabase(path ? path : buffer, (flags & 0xF) - 1);
|
||||
|
||||
/* If database could not be loaded, a handle doesn't make sense either */
|
||||
if (!sdb->db)
|
||||
{
|
||||
SdbReleaseDatabase(sdb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sdb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes shim database opened by SdbInitDatabase.
|
||||
*
|
||||
* @param [in] hsdb Handle to the shim database.
|
||||
*/
|
||||
void WINAPI SdbReleaseDatabase(HSDB hsdb)
|
||||
{
|
||||
SdbCloseDatabase(hsdb->db);
|
||||
SdbFree(hsdb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries database for a specified exe If hsdb is NULL default database shall be loaded and
|
||||
* searched.
|
||||
*
|
||||
* @param [in] hsdb Handle to the shim database.
|
||||
* @param [in] path Path to executable for which we query database.
|
||||
* @param [in] module_name Unused.
|
||||
* @param [in] env Unused.
|
||||
* @param [in] flags 0 or SDBGMEF_IGNORE_ENVIRONMENT.
|
||||
* @param [out] result Pointer to structure in which query result shall be stored.
|
||||
*
|
||||
* @return TRUE if it succeeds, FALSE if it fails.
|
||||
*/
|
||||
BOOL WINAPI SdbGetMatchingExe(HSDB hsdb, LPCWSTR path, LPCWSTR module_name,
|
||||
LPCWSTR env, DWORD flags, PSDBQUERYRESULT result)
|
||||
{
|
||||
static const WCHAR fmt[] = {'%','s','%','s',0};
|
||||
BOOL ok, ret;
|
||||
TAGID database, iter, attr;
|
||||
PATTRINFO attribs = NULL;
|
||||
/*DWORD attr_count;*/
|
||||
LPWSTR file_name;
|
||||
WCHAR dir_path[128];
|
||||
WCHAR buffer[256];
|
||||
PDB db;
|
||||
|
||||
/* Load default database if one is not specified */
|
||||
if (!hsdb)
|
||||
{
|
||||
/* To reproduce windows behaviour HID_DOS_PATHS needs
|
||||
* to be specified when loading default database */
|
||||
hsdb = SdbInitDatabase(HID_DOS_PATHS | SDB_DATABASE_MAIN_SHIM, NULL);
|
||||
if(hsdb)
|
||||
hsdb->auto_loaded = TRUE;
|
||||
}
|
||||
|
||||
/* No database could be loaded */
|
||||
if (!hsdb)
|
||||
return FALSE;
|
||||
|
||||
db = hsdb->db;
|
||||
|
||||
/* Extract file name */
|
||||
file_name = strrchrW(path, '\\') + 1;
|
||||
|
||||
/* Extract directory path */
|
||||
memcpy(dir_path, path, (size_t)(file_name - path) * sizeof(WCHAR));
|
||||
|
||||
/* Get information about executable required to match it with database entry */
|
||||
/*if (!SdbGetFileAttributes(path, &attribs, &attr_count))
|
||||
return FALSE;*/
|
||||
|
||||
/* DATABASE is list TAG which contains all executables */
|
||||
database = SdbFindFirstTag(db, TAGID_ROOT, TAG_DATABASE);
|
||||
if (database == TAGID_NULL)
|
||||
return FALSE;
|
||||
|
||||
/* EXE is list TAG which contains data required to match executable */
|
||||
iter = SdbFindFirstTag(db, database, TAG_EXE);
|
||||
|
||||
/* Search for entry in database */
|
||||
while (iter != TAGID_NULL)
|
||||
{
|
||||
/* Check if exe name matches */
|
||||
attr = SdbFindFirstTag(db, iter, TAG_NAME);
|
||||
if (lstrcmpiW(SdbGetStringTagPtr(db, attr), file_name) == 0)
|
||||
{
|
||||
/* Assume that entry is found (in case there are no "matching files") */
|
||||
ok = TRUE;
|
||||
|
||||
/* Check if all "matching files" exist */
|
||||
/* TODO: check size/checksum as well */
|
||||
for (attr = SdbFindFirstTag(db, attr, TAG_MATCHING_FILE);
|
||||
attr != TAGID_NULL; attr = SdbFindNextTag(db, iter, attr))
|
||||
{
|
||||
snprintfW(buffer, 256, fmt, dir_path, SdbGetStringTagPtr(db, attr));
|
||||
if (!SdbpFileExists(buffer))
|
||||
ok = FALSE;
|
||||
}
|
||||
|
||||
/* Found it! */
|
||||
if (ok)
|
||||
{
|
||||
/* TODO: fill result data */
|
||||
/* TODO: there may be multiple matches */
|
||||
ret = TRUE;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
/* Continue iterating */
|
||||
iter = SdbFindNextTag(db, database, iter);
|
||||
}
|
||||
|
||||
/* Exe not found */
|
||||
ret = FALSE;
|
||||
|
||||
cleanup:
|
||||
SdbFreeFileAttributes(attribs);
|
||||
if (hsdb->auto_loaded) SdbReleaseDatabase(hsdb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves AppPatch directory.
|
||||
*
|
||||
* @param [in] db Handle to the shim database.
|
||||
* @param [out] path Pointer to memory in which path shall be written.
|
||||
* @param [in] size Size of the buffer in characters.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
WCHAR* tmp = NULL;
|
||||
UINT len = GetSystemWindowsDirectoryW(NULL, 0) + lstrlenW(szAppPatch);
|
||||
tmp = SdbAlloc((len + 1)* sizeof(WCHAR));
|
||||
if (tmp)
|
||||
{
|
||||
UINT r = GetSystemWindowsDirectoryW(tmp, len+1);
|
||||
if (r && r < len)
|
||||
{
|
||||
if (SUCCEEDED(StringCchCatW(tmp, len+1, szAppPatch)))
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (!db)
|
||||
{
|
||||
return SUCCEEDED(StringCchCopyW(path, size, default_dir));
|
||||
}
|
||||
else
|
||||
{
|
||||
SHIM_ERR("Unimplemented for db != NULL\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Translates the given trWhich to a specific database / tagid
|
||||
*
|
||||
* @param [in] hsdb Handle to the database.
|
||||
* @param [in] trWhich Path to executable for which we query database.
|
||||
* @param [out,opt] ppdb The Shim database that trWhich belongs to.
|
||||
* @param [out,opt] ptiWhich The tagid that trWhich corresponds to.
|
||||
*
|
||||
* @return TRUE if it succeeds, FALSE if it fails.
|
||||
*/
|
||||
BOOL WINAPI SdbTagRefToTagID(HSDB hSDB, TAGREF trWhich, PDB* ppdb, TAGID* ptiWhich)
|
||||
{
|
||||
if (trWhich & 0xf0000000)
|
||||
{
|
||||
SHIM_ERR("Multiple shim databases not yet implemented!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* There seems to be no range checking on trWhich.. */
|
||||
if (ppdb)
|
||||
*ppdb = hSDB->db;
|
||||
if (ptiWhich)
|
||||
*ptiWhich = trWhich & 0x0fffffff;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -460,59 +460,6 @@ void WINAPI SdbCloseDatabase(PDB db)
|
||||
SdbFree(db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves AppPatch directory.
|
||||
*
|
||||
* @param [in] db Handle to the shim database.
|
||||
* @param [out] path Pointer to memory in which path shall be written.
|
||||
* @param [in] size Size of the buffer in characters.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
WCHAR* tmp = NULL;
|
||||
UINT len = GetSystemWindowsDirectoryW(NULL, 0) + lstrlenW(szAppPatch);
|
||||
tmp = SdbAlloc((len + 1)* sizeof(WCHAR));
|
||||
if (tmp)
|
||||
{
|
||||
UINT r = GetSystemWindowsDirectoryW(tmp, len+1);
|
||||
if (r && r < len)
|
||||
{
|
||||
if (SUCCEEDED(StringCchCatW(tmp, len+1, szAppPatch)))
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (!db)
|
||||
{
|
||||
return SUCCEEDED(StringCchCopyW(path, size, default_dir));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* fixme */
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a string to retrieve a GUID.
|
||||
*
|
||||
|
||||
@@ -36,26 +36,7 @@
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
/* data.c */
|
||||
void test_create_exe_imp(const char* name, int skip_rsrc_exports);
|
||||
void test_create_file_imp(const char* name, const char* contents, size_t len);
|
||||
void test_create_ne_imp(const char* name, int skip_names);
|
||||
DWORD get_host_winver(void);
|
||||
|
||||
#define test_create_exe (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : test_create_exe_imp
|
||||
#define test_create_file (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : test_create_file_imp
|
||||
#define test_create_ne (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : test_create_ne_imp
|
||||
|
||||
|
||||
static DWORD g_WinVersion;
|
||||
|
||||
#define WINVER_ANY 0
|
||||
#define WINVER_WINXP 0x0501
|
||||
#define WINVER_2003 0x0502
|
||||
#define WINVER_VISTA 0x0600
|
||||
#define WINVER_WIN7 0x0601
|
||||
#define WINVER_WIN8 0x0602
|
||||
#define WINVER_WIN10 0x1000
|
||||
#include "apphelp_apitest.h"
|
||||
|
||||
|
||||
typedef WORD TAG;
|
||||
@@ -848,6 +829,8 @@ START_TEST(apphelp)
|
||||
{
|
||||
g_WinVersion = get_host_winver();
|
||||
trace("Detected version: 0x%x\n", g_WinVersion);
|
||||
silence_debug_output();
|
||||
|
||||
//SetEnvironmentVariable("SHIM_DEBUG_LEVEL", "4");
|
||||
//SetEnvironmentVariable("DEBUGCHANNEL", "+apphelp");
|
||||
hdll = LoadLibraryA("apphelp.dll");
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef APPHELP_APITEST_H
|
||||
#define APPHELP_APITEST_H
|
||||
|
||||
|
||||
/* data.c */
|
||||
void test_create_db_imp(const char* name);
|
||||
DWORD test_get_db_size();
|
||||
void test_create_exe_imp(const char* name, int skip_rsrc_exports);
|
||||
void test_create_file_imp(const char* name, const char* contents, size_t len);
|
||||
void test_create_ne_imp(const char* name, int skip_names);
|
||||
DWORD get_host_winver(void);
|
||||
void silence_debug_output(void); // Silence output if the environment variable is not set.
|
||||
|
||||
#define test_create_db (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : test_create_db_imp
|
||||
#define test_create_exe (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : test_create_exe_imp
|
||||
#define test_create_file (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : test_create_file_imp
|
||||
#define test_create_ne (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : test_create_ne_imp
|
||||
|
||||
|
||||
static DWORD g_WinVersion;
|
||||
|
||||
#define WINVER_ANY 0
|
||||
#define WINVER_WINXP 0x0501
|
||||
#define WINVER_2003 0x0502
|
||||
#define WINVER_VISTA 0x0600
|
||||
#define WINVER_WIN7 0x0601
|
||||
#define WINVER_WIN8 0x0602
|
||||
#define WINVER_WIN10 0x0a00
|
||||
|
||||
|
||||
#endif // APPHELP_APITEST_H
|
||||
@@ -771,11 +771,16 @@ static unsigned char rawData[2356] = {
|
||||
0x21, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
DWORD test_get_db_size()
|
||||
{
|
||||
return sizeof(rawData);
|
||||
}
|
||||
|
||||
void test_create_db_imp(const char* name)
|
||||
{
|
||||
HANDLE file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
ok(file != INVALID_HANDLE_VALUE, "can't create file\n");
|
||||
if(file != INVALID_HANDLE_VALUE)
|
||||
winetest_ok(file != INVALID_HANDLE_VALUE, "can't create file '%s'\n", name);
|
||||
if (file != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DWORD size;
|
||||
WriteFile(file, rawData, sizeof(rawData), &size, NULL);
|
||||
@@ -799,3 +804,11 @@ DWORD get_host_winver(void)
|
||||
return g_WinVersion;
|
||||
}
|
||||
|
||||
void silence_debug_output(void)
|
||||
{
|
||||
if (GetEnvironmentVariableA("SHIM_DEBUG_LEVEL", NULL, 0) == ERROR_ENVVAR_NOT_FOUND)
|
||||
SetEnvironmentVariableA("SHIM_DEBUG_LEVEL", "0");
|
||||
if (GetEnvironmentVariableA("SHIMENG_DEBUG_LEVEL", NULL, 0) == ERROR_ENVVAR_NOT_FOUND)
|
||||
SetEnvironmentVariableA("SHIMENG_DEBUG_LEVEL", "0");
|
||||
}
|
||||
|
||||
|
||||
@@ -36,18 +36,23 @@
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
/* data.c */
|
||||
void test_create_db_imp(const char* name);
|
||||
#include "apphelp_apitest.h"
|
||||
|
||||
|
||||
#define test_create_db (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : test_create_db_imp
|
||||
|
||||
typedef WORD TAG;
|
||||
typedef DWORD TAGID;
|
||||
typedef DWORD TAGREF;
|
||||
typedef UINT64 QWORD;
|
||||
typedef VOID* PDB;
|
||||
typedef VOID* HSDB;
|
||||
typedef INT PATH_TYPE;
|
||||
|
||||
#define DOS_PATH 0
|
||||
#define HID_DATABASE_FULLPATH 2
|
||||
|
||||
#define SDB_DATABASE_MAIN_SHIM 0x80030000
|
||||
|
||||
|
||||
#define TAGID_NULL 0x0
|
||||
#define TAGID_ROOT 0x0
|
||||
@@ -134,6 +139,26 @@ typedef INT PATH_TYPE;
|
||||
#define TAG_DATABASE_ID (0x7 | TAG_TYPE_BINARY)
|
||||
|
||||
|
||||
#define SDB_MAX_SDBS 16
|
||||
#define SDB_MAX_EXES 16
|
||||
#define SDB_MAX_LAYERS 8
|
||||
|
||||
#define SDBQUERYRESULT_EXPECTED_SIZE 456
|
||||
|
||||
typedef struct tagSDBQUERYRESULT {
|
||||
TAGREF atrExes[SDB_MAX_EXES];
|
||||
DWORD adwExeFlags[SDB_MAX_EXES];
|
||||
TAGREF atrLayers[SDB_MAX_LAYERS];
|
||||
DWORD dwLayerFlags;
|
||||
TAGREF trApphelp;
|
||||
DWORD dwExeCount;
|
||||
DWORD dwLayerCount;
|
||||
GUID guidID;
|
||||
DWORD dwFlags;
|
||||
DWORD dwCustomSDBMap;
|
||||
GUID rgGuidDB[SDB_MAX_SDBS];
|
||||
} SDBQUERYRESULT, *PSDBQUERYRESULT;
|
||||
|
||||
|
||||
static HMODULE hdll;
|
||||
static LPCWSTR (WINAPI *pSdbTagToString)(TAG);
|
||||
@@ -166,6 +191,10 @@ static TAGID (WINAPI *pSdbGetFirstChild)(PDB, TAGID);
|
||||
static TAGID (WINAPI *pSdbGetNextChild)(PDB, TAGID, TAGID);
|
||||
static BOOL (WINAPI *pSdbGetDatabaseID)(PDB, GUID*);
|
||||
static BOOL (WINAPI *pSdbGUIDToString)(CONST GUID *, PCWSTR, SIZE_T);
|
||||
static HSDB (WINAPI *pSdbInitDatabase)(DWORD, LPCWSTR);
|
||||
static void (WINAPI *pSdbReleaseDatabase)(HSDB);
|
||||
static BOOL(WINAPI *pSdbGetMatchingExe)(HSDB hsdb, LPCWSTR path, LPCWSTR module_name, LPCWSTR env, DWORD flags, PSDBQUERYRESULT result);
|
||||
static BOOL (WINAPI *pSdbTagRefToTagID)(HSDB hSDB, TAGREF trWhich, PDB *ppdb, TAGID *ptiWhich);
|
||||
static LONGLONG(WINAPI* pSdbMakeIndexKeyFromString)(LPCWSTR);
|
||||
|
||||
|
||||
@@ -717,6 +746,9 @@ static void check_matching_file(PDB pdb, TAGID exe, TAGID matching_file, int num
|
||||
}
|
||||
}
|
||||
|
||||
// "C:\WINDOWS\system32\pcaui.exe" /g {bf39e0e6-c61c-4a22-8802-3ea8ad00b655} /x {4e50c93f-b863-4dfa-bae2-d80ef4ce5c89} /a "apphelp_name_allow" /v "apphelp_vendor_allow" /s "Allow it!" /b 1 /f 0 /k 0 /e "C:\Users\Mark\AppData\Local\Temp\apphelp_test\test_allow.exe" /u "http://reactos.org/allow" /c
|
||||
// "C:\WINDOWS\system32\pcaui.exe" /g {fa150915-1244-4169-a4ba-fc098c442840} /x {156720e1-ef98-4d04-965a-d85de05e6d9f} /a "apphelp_name_disallow" /v "apphelp_vendor_disallow" /s "Not allowed!" /b 2 /f 0 /k 0 /e "C:\Users\Mark\AppData\Local\Temp\apphelp_test\test_disallow.exe" /u "http://reactos.org/disallow" /c
|
||||
|
||||
static void check_matching_apphelp(PDB pdb, TAGID apphelp, int num)
|
||||
{
|
||||
if(num == 0)
|
||||
@@ -789,8 +821,11 @@ static struct
|
||||
const char* extra_file;
|
||||
DWORD dwLayerCount;
|
||||
TAGREF atrExes_0;
|
||||
DWORD adwExeFlags_0;
|
||||
TAGREF atrLayers_0;
|
||||
} test_exedata[4] = {
|
||||
TAGREF trApphelp;
|
||||
const char* env_var;
|
||||
} test_exedata[5] = {
|
||||
{
|
||||
"test_allow.exe",
|
||||
"apphelp_name_allow",
|
||||
@@ -799,7 +834,10 @@ static struct
|
||||
NULL,
|
||||
0,
|
||||
0x1c6,
|
||||
0x1000,
|
||||
0,
|
||||
0x1c6,
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
"test_disallow.exe",
|
||||
@@ -809,7 +847,10 @@ static struct
|
||||
NULL,
|
||||
0,
|
||||
0x256,
|
||||
0x3000,
|
||||
0,
|
||||
0x256,
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
"test_new.exe",
|
||||
@@ -819,7 +860,10 @@ static struct
|
||||
"test_checkfile.txt",
|
||||
1,
|
||||
0x2ec,
|
||||
0,
|
||||
0x18e,
|
||||
0,
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
"test_w2k3.exe",
|
||||
@@ -830,6 +874,22 @@ static struct
|
||||
0,
|
||||
0x37c,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
"test_unknown_file.exe",
|
||||
"apphelp_name_allow",
|
||||
"apphelp_vendor_allow",
|
||||
{0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
|
||||
NULL,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0x18e,
|
||||
0,
|
||||
"TestNewMode",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -968,6 +1028,314 @@ static void test_CheckDatabaseManually(void)
|
||||
DeleteFileA("test_db.sdb");
|
||||
}
|
||||
|
||||
static void test_is_testdb(PDB pdb)
|
||||
{
|
||||
if(pdb)
|
||||
{
|
||||
GUID guid;
|
||||
memset(&guid, 0, sizeof(guid));
|
||||
ok(pSdbGetDatabaseID(pdb, &guid),"expected SdbGetDatabaseID not to fail.\n");
|
||||
ok(IsEqualGUID(&guid, &GUID_DATABASE_TEST), "Expected SdbGetDatabaseID to return the test db GUID, was: %s\n", wine_dbgstr_guid(&guid));
|
||||
}
|
||||
else
|
||||
{
|
||||
skip("Not checking DB GUID, received a null pdb\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void test_mode_generic(const char* workdir, HSDB hsdb, int cur)
|
||||
{
|
||||
char exename[MAX_PATH], testfile[MAX_PATH];
|
||||
WCHAR exenameW[MAX_PATH];
|
||||
BOOL ret;
|
||||
SDBQUERYRESULT query;
|
||||
PDB pdb;
|
||||
TAGID tagid;
|
||||
TAGREF trApphelp;
|
||||
DWORD expect_flags = 0, adwExeFlags_0, exe_count;
|
||||
int n;
|
||||
|
||||
memset(&query, 0xab, sizeof(query));
|
||||
|
||||
sprintf(exename, "%s\\%s", workdir, test_exedata[cur].name);
|
||||
if (test_exedata[cur].extra_file)
|
||||
sprintf(testfile, "%s\\%s", workdir, test_exedata[cur].extra_file);
|
||||
test_create_exe(exename, 0);
|
||||
MultiByteToWideChar(CP_ACP, 0, exename, -1, exenameW, MAX_PATH);
|
||||
|
||||
if (test_exedata[cur].extra_file)
|
||||
{
|
||||
/* First we try without the file at all. */
|
||||
DeleteFileA(testfile);
|
||||
ret = pSdbGetMatchingExe(hsdb, exenameW, NULL, NULL, 0, &query);
|
||||
ok(ret == 0, "SdbGetMatchingExe should have failed for %d.\n", cur);
|
||||
/* Now re-try with the correct file */
|
||||
test_create_file(testfile, "aaaa", 4);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Results seem to be cached based on filename, until we can invalidate this, do not test the same filename twice!
|
||||
DeleteFileA(exename);
|
||||
// skip exports
|
||||
test_create_exe(exename, 1);
|
||||
ret = pSdbGetMatchingExe(hsdb, exenameW, NULL, NULL, 0, &query);
|
||||
ok(ret == 0, "SdbGetMatchingExe should have failed for %d.\n", cur);
|
||||
|
||||
DeleteFileA(exename);
|
||||
test_create_exe(exename, 0);
|
||||
#endif
|
||||
|
||||
if (test_exedata[cur].env_var)
|
||||
{
|
||||
SetEnvironmentVariableA("__COMPAT_LAYER", test_exedata[cur].env_var);
|
||||
}
|
||||
|
||||
ret = pSdbGetMatchingExe(hsdb, exenameW, NULL, NULL, 0, &query);
|
||||
ok(ret, "SdbGetMatchingExe should not fail for %d.\n", cur);
|
||||
|
||||
exe_count = (test_exedata[cur].env_var == NULL) ? 1 : 0;
|
||||
|
||||
ok(query.dwExeCount == exe_count, "Expected dwExeCount to be %d, was %d for %d\n", exe_count, query.dwExeCount, cur);
|
||||
ok(query.dwLayerCount == test_exedata[cur].dwLayerCount, "Expected dwLayerCount to be %d, was %d for %d\n", test_exedata[cur].dwLayerCount, query.dwLayerCount, cur);
|
||||
ok(query.dwCustomSDBMap == 1, "Expected dwCustomSDBMap to be 1, was %d for %d\n", query.dwCustomSDBMap, cur);
|
||||
ok(query.dwLayerFlags == 0, "Expected dwLayerFlags to be 0, was 0x%x for %d\n", query.dwLayerFlags, cur);
|
||||
trApphelp = (g_WinVersion < WINVER_WIN10) ? 0 : test_exedata[cur].trApphelp;
|
||||
ok(query.trApphelp == trApphelp, "Expected trApphelp to be 0x%x, was 0x%x for %d\n", trApphelp, query.trApphelp, cur);
|
||||
|
||||
if (g_WinVersion < WINVER_WIN7)
|
||||
expect_flags = 0;
|
||||
else if (g_WinVersion < WINVER_WIN8)
|
||||
expect_flags = 1;
|
||||
else if (g_WinVersion < WINVER_WIN10)
|
||||
expect_flags = 0x101;
|
||||
else
|
||||
expect_flags = 0x121;
|
||||
|
||||
if (test_exedata[cur].env_var)
|
||||
expect_flags &= ~0x100;
|
||||
|
||||
ok(query.dwFlags == expect_flags, "Expected dwFlags to be 0x%x, was 0x%x for %d\n", expect_flags, query.dwFlags, cur);
|
||||
|
||||
ok(query.atrExes[0] == test_exedata[cur].atrExes_0, "Expected atrExes[0] to be 0x%x, was: 0x%x for %d\n", test_exedata[cur].atrExes_0, query.atrExes[0], cur);
|
||||
for (n = 1; n < SDB_MAX_EXES; ++n)
|
||||
ok(query.atrExes[n] == 0, "Expected atrExes[%d] to be 0, was: %x for %d\n", n, query.atrExes[n], cur);
|
||||
|
||||
adwExeFlags_0 = (g_WinVersion < WINVER_WIN10) ? 0 : test_exedata[cur].adwExeFlags_0;
|
||||
ok(query.adwExeFlags[0] == adwExeFlags_0, "Expected adwExeFlags[0] to be 0x%x, was: 0x%x for %d\n", adwExeFlags_0, query.adwExeFlags[0], cur);
|
||||
for (n = 1; n < SDB_MAX_EXES; ++n)
|
||||
ok(query.adwExeFlags[n] == 0, "Expected adwExeFlags[%d] to be 0, was: %x for %d\n", n, query.adwExeFlags[0], cur);
|
||||
|
||||
ok(query.atrLayers[0] == test_exedata[cur].atrLayers_0, "Expected atrLayers[0] to be 0x%x, was: %x for %d\n", test_exedata[cur].atrLayers_0, query.atrLayers[0], cur);
|
||||
for (n = 1; n < SDB_MAX_LAYERS; ++n)
|
||||
ok(query.atrLayers[n] == 0, "Expected atrLayers[%d] to be 0, was: %x for %d\n", n, query.atrLayers[0], cur);
|
||||
|
||||
ok(IsEqualGUID(&query.rgGuidDB[0], &GUID_DATABASE_TEST), "Expected rgGuidDB[0] to be the test db GUID, was: %s for %d\n", wine_dbgstr_guid(&query.rgGuidDB[0]), cur);
|
||||
for (n = 1; n < SDB_MAX_SDBS; ++n)
|
||||
ok(IsEqualGUID(&query.rgGuidDB[n], &GUID_NULL), "Expected rgGuidDB[%d] to be GUID_NULL, was: %s for %d\n", n, wine_dbgstr_guid(&query.rgGuidDB[n]), cur);
|
||||
|
||||
if (query.atrExes[0])
|
||||
{
|
||||
pdb = (PDB)0x12345678;
|
||||
tagid = 0x76543210;
|
||||
ret = pSdbTagRefToTagID(hsdb, query.atrExes[0], &pdb, &tagid);
|
||||
ok(ret, "SdbTagRefToTagID failed for %d.\n", cur);
|
||||
ok(pdb != NULL && pdb != (PDB)0x12345678, "SdbTagRefToTagID failed to return a pdb for %d.\n", cur);
|
||||
ok(tagid != 0 && tagid != 0x76543210, "SdbTagRefToTagID failed to return a tagid for %d.\n", cur);
|
||||
|
||||
if (pdb && pdb != (PDB)0x12345678)
|
||||
{
|
||||
TAG tag = pSdbGetTagFromTagID(pdb, tagid);
|
||||
test_is_testdb(pdb);
|
||||
ok(tag == TAG_EXE, "Expected tag to be TAG_EXE, was 0x%x for %d.\n", tag, cur);
|
||||
match_str_attr(pdb, tagid, TAG_NAME, test_exedata[cur].name);
|
||||
}
|
||||
else
|
||||
{
|
||||
skip("Skipping a bunch of tests because of an invalid pointer\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (test_exedata[cur].atrLayers_0)
|
||||
{
|
||||
pdb = (PDB)0x12345678;
|
||||
tagid = 0x76543210;
|
||||
ret = pSdbTagRefToTagID(hsdb, query.atrLayers[0], &pdb, &tagid);
|
||||
ok(ret, "SdbTagRefToTagID failed for %d.\n", cur);
|
||||
ok(pdb != NULL && pdb != (PDB)0x12345678, "SdbTagRefToTagID failed to return a pdb for %d.\n", cur);
|
||||
ok(tagid != 0 && tagid != 0x76543210, "SdbTagRefToTagID failed to return a tagid for %d.\n", cur);
|
||||
|
||||
if (pdb && pdb != (PDB)0x12345678)
|
||||
{
|
||||
TAG tag = pSdbGetTagFromTagID(pdb, tagid);
|
||||
test_is_testdb(pdb);
|
||||
ok(tag == TAG_LAYER, "Expected tag to be TAG_LAYER, was 0x%x for %d.\n", tag, cur);
|
||||
match_str_attr(pdb, tagid, TAG_NAME, "TestNewMode");
|
||||
}
|
||||
else
|
||||
{
|
||||
skip("Skipping a bunch of tests because of an invalid pointer\n");
|
||||
}
|
||||
}
|
||||
|
||||
pdb = (PDB)0x12345678;
|
||||
tagid = 0x76543210;
|
||||
ret = pSdbTagRefToTagID(hsdb, 0, &pdb, &tagid);
|
||||
ok(pdb != NULL && pdb != (PDB)0x12345678, "Expected pdb to be set to a valid pdb, was: %p\n", pdb);
|
||||
ok(tagid == 0, "Expected tagid to be set to 0, was: 0x%x\n", tagid);
|
||||
|
||||
if (test_exedata[cur].extra_file)
|
||||
DeleteFileA(testfile);
|
||||
DeleteFileA(exename);
|
||||
|
||||
if (test_exedata[cur].env_var)
|
||||
{
|
||||
SetEnvironmentVariableA("__COMPAT_LAYER", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void test_MatchApplications(void)
|
||||
{
|
||||
char workdir[MAX_PATH], dbpath[MAX_PATH];
|
||||
WCHAR dbpathW[MAX_PATH];
|
||||
BOOL ret;
|
||||
HSDB hsdb;
|
||||
|
||||
ret = GetTempPathA(MAX_PATH, workdir);
|
||||
ok(ret, "GetTempPathA error: %d\n", GetLastError());
|
||||
lstrcatA(workdir, "apphelp_test");
|
||||
|
||||
ret = CreateDirectoryA(workdir, NULL);
|
||||
ok(ret, "CreateDirectoryA error: %d\n", GetLastError());
|
||||
|
||||
/* SdbInitDatabase needs an nt-path */
|
||||
sprintf(dbpath, "\\??\\%s\\test.sdb", workdir);
|
||||
|
||||
test_create_db(dbpath + 4);
|
||||
|
||||
MultiByteToWideChar(CP_ACP, 0, dbpath, -1, dbpathW, MAX_PATH);
|
||||
hsdb = pSdbInitDatabase(HID_DATABASE_FULLPATH, dbpathW);
|
||||
|
||||
ok(hsdb != NULL, "Expected a valid database handle\n");
|
||||
|
||||
if (!hsdb)
|
||||
{
|
||||
skip("SdbInitDatabase not implemented?\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* now that our enviroment is setup, let's go ahead and run the actual tests.. */
|
||||
int n;
|
||||
for (n = 0; n < _countof(test_exedata); ++n)
|
||||
test_mode_generic(workdir, hsdb, n);
|
||||
pSdbReleaseDatabase(hsdb);
|
||||
}
|
||||
|
||||
DeleteFileA(dbpath + 4);
|
||||
|
||||
ret = RemoveDirectoryA(workdir);
|
||||
ok(ret, "RemoveDirectoryA error: %d\n", GetLastError());
|
||||
}
|
||||
|
||||
static void test_TagRef(void)
|
||||
{
|
||||
char tmpdir[MAX_PATH], dbpath[MAX_PATH];
|
||||
WCHAR dbpathW[MAX_PATH];
|
||||
BOOL ret;
|
||||
HSDB hsdb;
|
||||
PDB pdb;
|
||||
TAGID db;
|
||||
DWORD size;
|
||||
|
||||
ret = GetTempPathA(MAX_PATH, tmpdir);
|
||||
ok(ret, "GetTempPathA error: %d\n", GetLastError());
|
||||
|
||||
/* SdbInitDatabase needs an nt-path */
|
||||
sprintf(dbpath, "\\??\\%stest.sdb", tmpdir);
|
||||
|
||||
test_create_db(dbpath + 4);
|
||||
|
||||
MultiByteToWideChar(CP_ACP, 0, dbpath, -1, dbpathW, MAX_PATH);
|
||||
hsdb = pSdbInitDatabase(HID_DATABASE_FULLPATH, dbpathW);
|
||||
|
||||
/* HSDB is the only arg that can't be null */
|
||||
ret = pSdbTagRefToTagID(hsdb, 0, NULL, NULL);
|
||||
ok(ret == TRUE, "Expected ret to be TRUE, was: %d\n", ret);
|
||||
|
||||
size = test_get_db_size();
|
||||
|
||||
pdb = (PDB)&db;
|
||||
db = 12345;
|
||||
ret = pSdbTagRefToTagID(hsdb, size - 1, &pdb, &db);
|
||||
ok(ret == TRUE, "Expected ret to be TRUE, was: %d\n", ret);
|
||||
ok(pdb != NULL, "Expected a result, got: %p\n", pdb);
|
||||
ok(db == (size - 1), "Expected %u, got: %u\n", size - 1, db);
|
||||
|
||||
pdb = (PDB)&db;
|
||||
db = 12345;
|
||||
ret = pSdbTagRefToTagID(hsdb, size, &pdb, &db);
|
||||
ok(ret == TRUE, "Expected ret to be TRUE, was: %d\n", ret);
|
||||
ok(pdb != NULL, "Expected a result, got: %p\n", pdb);
|
||||
ok(db == (size), "Expected %u, got: %u\n", size, db);
|
||||
|
||||
pdb = (PDB)&db;
|
||||
db = 12345;
|
||||
ret = pSdbTagRefToTagID(hsdb, size + 1, &pdb, &db);
|
||||
ok(ret == TRUE, "Expected ret to be TRUE, was: %d\n", ret);
|
||||
ok(pdb != NULL, "Expected a result, got: %p\n", pdb);
|
||||
ok(db == (size + 1), "Expected %u, got: %u\n", size + 1, db);
|
||||
|
||||
pdb = (PDB)&db;
|
||||
db = 12345;
|
||||
ret = pSdbTagRefToTagID(hsdb, 0x0fffffff, &pdb, &db);
|
||||
ok(ret == TRUE, "Expected ret to be TRUE, was: %d\n", ret);
|
||||
ok(pdb != NULL, "Expected a result, got: %p\n", pdb);
|
||||
ok(db == 0x0fffffff, "Expected %u, got: %u\n", 0x0fffffff, db);
|
||||
|
||||
pdb = (PDB)&db;
|
||||
db = 12345;
|
||||
ret = pSdbTagRefToTagID(hsdb, 0x10000000, &pdb, &db);
|
||||
ok(ret == FALSE, "Expected ret to be FALSE, was: %d\n", ret);
|
||||
ok(pdb == NULL, "Expected no result, got: %p\n", pdb);
|
||||
ok(db == 0, "Expected no result, got: 0x%x\n", db);
|
||||
|
||||
pdb = NULL;
|
||||
db = TAGID_NULL;
|
||||
ret = pSdbTagRefToTagID(hsdb, TAGID_ROOT, &pdb, NULL);
|
||||
ok(ret != FALSE, "Expected ret to be TRUE, was: %d\n", ret);
|
||||
ok(pdb != NULL, "Expected pdb to be valid\n");
|
||||
|
||||
if(pdb == NULL)
|
||||
{
|
||||
skip("Cannot run tests without pdb\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
db = pSdbFindFirstTag(pdb, TAGID_ROOT, TAG_DATABASE);
|
||||
if(db != TAGID_NULL)
|
||||
{
|
||||
TAGID child;
|
||||
child = pSdbGetFirstChild(pdb, db);
|
||||
while(child != TAGID_NULL)
|
||||
{
|
||||
PDB pdb_res;
|
||||
TAGID tagid_res;
|
||||
ret = pSdbTagRefToTagID(hsdb, child, &pdb_res, &tagid_res);
|
||||
ok(ret, "Expected SdbTagRefToTagID to succeed\n");
|
||||
child = pSdbGetNextChild(pdb, db, child);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
skip("Cannot run tests without valid db tag\n");
|
||||
}
|
||||
}
|
||||
|
||||
DeleteFileA(dbpath + 4);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void expect_indexA_imp(const char* text, LONGLONG expected)
|
||||
{
|
||||
@@ -1051,10 +1419,39 @@ static void test_IndexKeyFromString(void)
|
||||
wine_dbgstr_longlong(0xbc414044444444), wine_dbgstr_longlong(result));
|
||||
}
|
||||
|
||||
static int validate_SDBQUERYRESULT_size()
|
||||
{
|
||||
unsigned char buffer[SDBQUERYRESULT_EXPECTED_SIZE * 2];
|
||||
WCHAR path[MAX_PATH];
|
||||
HSDB hsdb;
|
||||
|
||||
memset(buffer, 0xab, sizeof(buffer));
|
||||
hsdb = pSdbInitDatabase(SDB_DATABASE_MAIN_SHIM, NULL);
|
||||
if (hsdb)
|
||||
{
|
||||
GetModuleFileNameW(NULL, path, MAX_PATH);
|
||||
pSdbGetMatchingExe(hsdb, path, NULL, NULL, 0, (SDBQUERYRESULT*)buffer);
|
||||
pSdbReleaseDatabase(hsdb);
|
||||
if (buffer[0] == buffer[1] && buffer[1] == 0xab)
|
||||
{
|
||||
trace("SdbGetMatchingExe didnt do anything, cannot determine SDBQUERYRESULT size\n");
|
||||
return 1;
|
||||
}
|
||||
return buffer[SDBQUERYRESULT_EXPECTED_SIZE] == 0xab && buffer[SDBQUERYRESULT_EXPECTED_SIZE-1] != 0xab;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
START_TEST(db)
|
||||
{
|
||||
g_WinVersion = get_host_winver();
|
||||
trace("Detected version: 0x%x\n", g_WinVersion);
|
||||
silence_debug_output();
|
||||
|
||||
//SetEnvironmentVariable("SHIM_DEBUG_LEVEL", "4");
|
||||
//SetEnvironmentVariable("SHIMENG_DEBUG_LEVEL", "4");
|
||||
//SetEnvironmentVariable("DEBUGCHANNEL", "+apphelp");
|
||||
hdll = LoadLibraryA("apphelp.dll");
|
||||
pSdbTagToString = (void *) GetProcAddress(hdll, "SdbTagToString");
|
||||
@@ -1087,11 +1484,21 @@ START_TEST(db)
|
||||
pSdbGetNextChild = (void *) GetProcAddress(hdll, "SdbGetNextChild");
|
||||
pSdbGetDatabaseID = (void *) GetProcAddress(hdll, "SdbGetDatabaseID");
|
||||
pSdbGUIDToString = (void *) GetProcAddress(hdll, "SdbGUIDToString");
|
||||
pSdbMakeIndexKeyFromString = (void*) GetProcAddress(hdll, "SdbMakeIndexKeyFromString");
|
||||
pSdbInitDatabase = (void *) GetProcAddress(hdll, "SdbInitDatabase");
|
||||
pSdbReleaseDatabase = (void *) GetProcAddress(hdll, "SdbReleaseDatabase");
|
||||
pSdbGetMatchingExe = (void *) GetProcAddress(hdll, "SdbGetMatchingExe");
|
||||
pSdbTagRefToTagID = (void *) GetProcAddress(hdll, "SdbTagRefToTagID");
|
||||
pSdbMakeIndexKeyFromString = (void *) GetProcAddress(hdll, "SdbMakeIndexKeyFromString");
|
||||
|
||||
test_Sdb();
|
||||
test_write_ex();
|
||||
test_stringtable();
|
||||
test_CheckDatabaseManually();
|
||||
if (validate_SDBQUERYRESULT_size())
|
||||
test_MatchApplications();
|
||||
else
|
||||
skip("Skipping tests with SDBQUERYRESULT due to a wrong size reported\n");
|
||||
test_TagRef();
|
||||
skip("test_SecondaryDB()\n");
|
||||
test_IndexKeyFromString();
|
||||
}
|
||||
|
||||
@@ -31,8 +31,7 @@
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
/* data.c */
|
||||
DWORD get_host_winver(void);
|
||||
#include "apphelp_apitest.h"
|
||||
|
||||
#define GPLK_USER 1
|
||||
#define GPLK_MACHINE 2
|
||||
@@ -47,12 +46,6 @@ static BOOL(WINAPI *pSdbGetPermLayerKeys)(PCWSTR wszPath, PWSTR pwszLayers, PDWO
|
||||
static BOOL(WINAPI *pSetPermLayerState)(PCWSTR wszPath, PCWSTR wszLayer, DWORD dwFlags, BOOL bMachine, BOOL bEnable);
|
||||
|
||||
|
||||
static DWORD g_WinVersion;
|
||||
#define WINVER_VISTA 0x0600
|
||||
#define WINVER_WIN8 0x0602
|
||||
#define WINVER_WIN10 0x1000
|
||||
|
||||
|
||||
/* Helper function to disable Wow64 redirection on an os that reports it being enabled. */
|
||||
static DWORD g_QueryFlag = 0xffffffff;
|
||||
static DWORD QueryFlag(void)
|
||||
@@ -877,6 +870,7 @@ static void test_Sign_Media(void)
|
||||
|
||||
START_TEST(layerapi)
|
||||
{
|
||||
silence_debug_output();
|
||||
/*SetEnvironmentVariable("SHIM_DEBUG_LEVEL", "4");*/
|
||||
hdll = LoadLibraryA("apphelp.dll");
|
||||
pAllowPermLayer = (void *)GetProcAddress(hdll, "AllowPermLayer");
|
||||
|
||||
Reference in New Issue
Block a user