[APPHELP][APPHELP_APITEST] Update db apitests to succeed from 2k3 to 10, paving the way for the next set of tests.

- Support 2k3 and Vista+ versions of the SDBQUERYRESULT structure.
- Add tests for SdbFindFirstNamedTag, SdbTagIDToTagRef, SdbGetLayerTagRef
- Implement SdbFindFirstNamedTag, SdbTagIDToTagRef, SdbGetLayerTagRef
- Add a version resource to apphelp, so that we can use it to identify which tests to use.

svn path=/trunk/; revision=73083
This commit is contained in:
Mark Jansen 2016-10-30 19:39:43 +00:00
parent 705f7ce49e
commit 22ba0b5aa5
10 changed files with 538 additions and 196 deletions

View file

@ -1,4 +1,9 @@
include_directories(${SHIMLIB_DIR})
remove_definitions(-D_WIN32_WINNT=0x502 -DWINVER=0x502)
add_definitions(-D_WIN32_WINNT=0x600 -DWINVER=0x600)
spec2def(apphelp.dll apphelp.spec ADD_IMPORTLIB) spec2def(apphelp.dll apphelp.spec ADD_IMPORTLIB)
list(APPEND SOURCE list(APPEND SOURCE
@ -16,6 +21,7 @@ list(APPEND SOURCE
add_library(apphelp SHARED add_library(apphelp SHARED
${SOURCE} ${SOURCE}
apphelp.rc
${CMAKE_CURRENT_BINARY_DIR}/apphelp.def) ${CMAKE_CURRENT_BINARY_DIR}/apphelp.def)
set_module_type(apphelp win32dll) set_module_type(apphelp win32dll)

View file

@ -79,10 +79,9 @@ typedef struct tagSDBQUERYRESULT {
GUID rgGuidDB[SDB_MAX_SDBS]; GUID rgGuidDB[SDB_MAX_SDBS];
} SDBQUERYRESULT, *PSDBQUERYRESULT; } SDBQUERYRESULT, *PSDBQUERYRESULT;
/* apphelp.c */
#include "sdbpapi.h" #include "sdbpapi.h"
/* sdbapi.c */
PWSTR SdbpStrDup(LPCWSTR string); PWSTR SdbpStrDup(LPCWSTR string);
HSDB WINAPI SdbInitDatabase(DWORD, LPCWSTR); HSDB WINAPI SdbInitDatabase(DWORD, LPCWSTR);
void WINAPI SdbReleaseDatabase(HSDB); void WINAPI SdbReleaseDatabase(HSDB);
@ -92,6 +91,7 @@ void WINAPI SdbCloseDatabase(PDB);
BOOL WINAPI SdbIsNullGUID(CONST GUID *Guid); BOOL WINAPI SdbIsNullGUID(CONST GUID *Guid);
BOOL WINAPI SdbGetAppPatchDir(HSDB db, LPWSTR path, DWORD size); BOOL WINAPI SdbGetAppPatchDir(HSDB db, LPWSTR path, DWORD size);
LPWSTR WINAPI SdbGetStringTagPtr(PDB db, TAGID tagid); LPWSTR WINAPI SdbGetStringTagPtr(PDB db, TAGID tagid);
TAGID WINAPI SdbFindFirstNamedTag(PDB db, TAGID root, TAGID find, TAGID nametag, LPCWSTR find_name);
/* sdbread.c */ /* sdbread.c */
BOOL WINAPI SdbpReadData(PDB db, PVOID dest, DWORD offset, DWORD num); BOOL WINAPI SdbpReadData(PDB db, PVOID dest, DWORD offset, DWORD num);
@ -108,6 +108,9 @@ BOOL WINAPI AllowPermLayer(PCWSTR path);
BOOL WINAPI SdbGetPermLayerKeys(PCWSTR wszPath, PWSTR pwszLayers, PDWORD pdwBytes, DWORD dwFlags); BOOL WINAPI SdbGetPermLayerKeys(PCWSTR wszPath, PWSTR pwszLayers, PDWORD pdwBytes, DWORD dwFlags);
BOOL WINAPI SetPermLayerState(PCWSTR wszPath, PCWSTR wszLayer, DWORD dwFlags, BOOL bMachine, BOOL bEnable); BOOL WINAPI SetPermLayerState(PCWSTR wszPath, PCWSTR wszLayer, DWORD dwFlags, BOOL bMachine, BOOL bEnable);
/* hsdb.c */
BOOL WINAPI SdbTagIDToTagRef(HSDB hsdb, PDB pdb, TAGID tiWhich, TAGREF* ptrWhich);
#define ATTRIBUTE_AVAILABLE 0x1 #define ATTRIBUTE_AVAILABLE 0x1
#define ATTRIBUTE_FAILED 0x2 #define ATTRIBUTE_FAILED 0x2

View file

@ -0,0 +1,11 @@
#include <windef.h>
#define REACTOS_FILEVERSION 6,0,6000,0
#define REACTOS_STR_FILE_VERSION "6.0.6000.0"
#define REACTOS_PRODUCTVERSION 6,0,6000,0
#define REACTOS_STR_PRODUCT_VERSION "6.0"
#define REACTOS_STR_FILE_DESCRIPTION "Application compatibility module"
#define REACTOS_STR_INTERNAL_NAME "apphelp"
#define REACTOS_STR_ORIGINAL_FILENAME "apphelp.dll"
#include <reactos/version.rc>

View file

@ -38,7 +38,7 @@
@ stub SdbFindFirstDWORDIndexedTag @ stub SdbFindFirstDWORDIndexedTag
@ stub SdbFindFirstMsiPackage @ stub SdbFindFirstMsiPackage
@ stub SdbFindFirstMsiPackage_Str @ stub SdbFindFirstMsiPackage_Str
@ stub SdbFindFirstNamedTag @ stdcall SdbFindFirstNamedTag(ptr long long long wstr)
@ stub SdbFindFirstStringIndexedTag @ stub SdbFindFirstStringIndexedTag
@ stdcall SdbFindFirstTag(ptr long long) @ stdcall SdbFindFirstTag(ptr long long)
@ stub SdbFindFirstTagRef @ stub SdbFindFirstTagRef
@ -69,7 +69,7 @@
@ stub SdbGetIndex @ stub SdbGetIndex
@ stub SdbGetItemFromItemRef @ stub SdbGetItemFromItemRef
@ stub SdbGetLayerName @ stub SdbGetLayerName
@ stub SdbGetLayerTagRef @ stdcall SdbGetLayerTagRef(ptr wstr)
@ stub SdbGetLocalPDB @ stub SdbGetLocalPDB
@ stdcall SdbGetMatchingExe(ptr wstr wstr wstr long ptr) @ stdcall SdbGetMatchingExe(ptr wstr wstr wstr long ptr)
@ stub SdbGetMsiPackageInformation @ stub SdbGetMsiPackageInformation
@ -143,7 +143,7 @@
@ stub SdbStringDuplicate @ stub SdbStringDuplicate
@ stub SdbStringReplace @ stub SdbStringReplace
@ stub SdbStringReplaceArray @ stub SdbStringReplaceArray
@ stub SdbTagIDToTagRef @ stdcall SdbTagIDToTagRef(ptr ptr long ptr)
@ stdcall SdbTagRefToTagID(ptr long ptr ptr) @ stdcall SdbTagRefToTagID(ptr long ptr ptr)
@ stdcall SdbTagToString(long) @ stdcall SdbTagToString(long)
@ stub SdbUnregisterDatabase @ stub SdbUnregisterDatabase

View file

@ -23,7 +23,6 @@
#include "ntndk.h" #include "ntndk.h"
#include "strsafe.h" #include "strsafe.h"
#include "apphelp.h" #include "apphelp.h"
//#include "sdbstringtable.h"
#include "wine/unicode.h" #include "wine/unicode.h"
@ -256,26 +255,58 @@ BOOL WINAPI SdbGetAppPatchDir(HSDB db, LPWSTR path, DWORD size)
* Translates the given trWhich to a specific database / tagid * Translates the given trWhich to a specific database / tagid
* *
* @param [in] hsdb Handle to the database. * @param [in] hsdb Handle to the database.
* @param [in] trWhich Path to executable for which we query database. * @param [in] trWhich Tagref to find
* @param [out,opt] ppdb The Shim database that trWhich belongs to. * @param [out,opt] ppdb The Shim database that trWhich belongs to.
* @param [out,opt] ptiWhich The tagid that trWhich corresponds to. * @param [out,opt] ptiWhich The tagid that trWhich corresponds to.
* *
* @return TRUE if it succeeds, FALSE if it fails. * @return TRUE if it succeeds, FALSE if it fails.
*/ */
BOOL WINAPI SdbTagRefToTagID(HSDB hSDB, TAGREF trWhich, PDB* ppdb, TAGID* ptiWhich) BOOL WINAPI SdbTagRefToTagID(HSDB hsdb, TAGREF trWhich, PDB* ppdb, TAGID* ptiWhich)
{ {
if (trWhich & 0xf0000000) if (trWhich & 0xf0000000)
{ {
SHIM_ERR("Multiple shim databases not yet implemented!\n"); SHIM_ERR("Multiple shim databases not yet implemented!\n");
if (ppdb)
*ppdb = NULL;
if (ptiWhich)
*ptiWhich = TAG_NULL;
return FALSE; return FALSE;
} }
/* There seems to be no range checking on trWhich.. */ /* There seems to be no range checking on trWhich.. */
if (ppdb) if (ppdb)
*ppdb = hSDB->db; *ppdb = hsdb->db;
if (ptiWhich) if (ptiWhich)
*ptiWhich = trWhich & 0x0fffffff; *ptiWhich = trWhich & 0x0fffffff;
return TRUE; return TRUE;
} }
/**
* Translates the given trWhich to a specific database / tagid
*
* @param [in] hsdb Handle to the database.
* @param [in] pdb The Shim database that tiWhich belongs to.
* @param [in] tiWhich Path to executable for which we query database.
* @param [out,opt] ptrWhich The tagid that tiWhich corresponds to.
*
* @return TRUE if it succeeds, FALSE if it fails.
*/
BOOL WINAPI SdbTagIDToTagRef(HSDB hsdb, PDB pdb, TAGID tiWhich, TAGREF* ptrWhich)
{
if (pdb != hsdb->db)
{
SHIM_ERR("Multiple shim databases not yet implemented!\n");
if (ptrWhich)
*ptrWhich = TAGREF_NULL;
return FALSE;
}
if (ptrWhich)
*ptrWhich = tiWhich & 0x0fffffff;
return TRUE;
}

View file

@ -425,7 +425,7 @@ PDB WINAPI SdbOpenDatabase(LPCWSTR path, PATH_TYPE type)
if (!db) if (!db)
return NULL; return NULL;
if (major != 2) if (major != 2 && major != 3)
{ {
SdbCloseDatabase(db); SdbCloseDatabase(db);
SHIM_ERR("Invalid shim database version\n"); SHIM_ERR("Invalid shim database version\n");
@ -563,6 +563,67 @@ BOOL WINAPI SdbGetDatabaseVersion(LPCWSTR database, PDWORD VersionHi, PDWORD Ver
} }
/**
* Find the first named child tag.
*
* @param [in] database The database.
* @param [in] root The tag to start at
* @param [in] find The tag type to find
* @param [in] nametag The child of 'find' that contains the name
* @param [in] find_name The name to find
*
* @return The found tag, or TAGID_NULL on failure
*/
TAGID WINAPI SdbFindFirstNamedTag(PDB db, TAGID root, TAGID find, TAGID nametag, LPCWSTR find_name)
{
TAGID iter;
iter = SdbFindFirstTag(db, root, find);
while (iter != TAGID_NULL)
{
TAGID tmp = SdbFindFirstTag(db, iter, nametag);
if (tmp != TAGID_NULL)
{
LPCWSTR name = SdbGetStringTagPtr(db, tmp);
if (name && !lstrcmpiW(name, find_name))
return iter;
}
iter = SdbFindNextTag(db, root, iter);
}
return TAGID_NULL;
}
/**
* Find a named layer in a multi-db.
*
* @param [in] hsdb The multi-database.
* @param [in] layerName The named tag to find.
*
* @return The layer, or TAGREF_NULL on failure
*/
TAGREF WINAPI SdbGetLayerTagRef(HSDB hsdb, LPCWSTR layerName)
{
PDB db = hsdb->db;
TAGID database = SdbFindFirstTag(db, TAGID_ROOT, TAG_DATABASE);
if (database != TAGID_NULL)
{
TAGID layer = SdbFindFirstNamedTag(db, database, TAG_LAYER, TAG_NAME, layerName);
if (layer != TAGID_NULL)
{
TAGREF tr;
if (SdbTagIDToTagRef(hsdb, db, layer, &tr))
{
return tr;
}
}
}
return TAGREF_NULL;
}
/** /**
* Converts the specified string to an index key. * Converts the specified string to an index key.
* *

View file

@ -4,11 +4,11 @@ add_definitions(-D__ROS_LONG64__ -DWINETEST_USE_DBGSTR_LONGLONG)
list(APPEND SOURCE list(APPEND SOURCE
apphelp.c apphelp.c
data.c data.c
db.c db.cpp
layerapi.c layerapi.c
testlist.c) testlist.c)
add_executable(apphelp_apitest ${SOURCE}) add_executable(apphelp_apitest ${SOURCE})
set_module_type(apphelp_apitest win32cui) set_module_type(apphelp_apitest win32cui)
add_importlibs(apphelp_apitest advapi32 shlwapi msvcrt kernel32 ntdll) add_importlibs(apphelp_apitest advapi32 userenv version shlwapi msvcrt kernel32 ntdll)
add_cd_file(TARGET apphelp_apitest DESTINATION reactos/bin FOR all) add_cd_file(TARGET apphelp_apitest DESTINATION reactos/bin FOR all)

View file

@ -1,14 +1,19 @@
#ifndef APPHELP_APITEST_H #ifndef APPHELP_APITEST_H
#define APPHELP_APITEST_H #define APPHELP_APITEST_H
#ifdef __cplusplus
extern "C" {
#endif
/* data.c */ /* data.c */
void test_create_db_imp(const char* name); void test_create_db_imp(const char* name, int win10);
DWORD test_get_db_size(); DWORD test_get_db_size();
void test_create_exe_imp(const char* name, int skip_rsrc_exports); 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_file_imp(const char* name, const char* contents, size_t len);
void test_create_ne_imp(const char* name, int skip_names); void test_create_ne_imp(const char* name, int skip_names);
DWORD get_host_winver(void); DWORD get_host_winver(void);
DWORD get_module_version(HMODULE mod);
void silence_debug_output(void); // Silence output if the environment variable is not set. 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_db (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : test_create_db_imp
@ -27,5 +32,8 @@ static DWORD g_WinVersion;
#define WINVER_WIN8 0x0602 #define WINVER_WIN8 0x0602
#define WINVER_WIN10 0x0a00 #define WINVER_WIN10 0x0a00
#ifdef __cplusplus
} // extern "C"
#endif
#endif // APPHELP_APITEST_H #endif // APPHELP_APITEST_H

View file

@ -569,6 +569,9 @@ void test_create_file_imp(const char* name, const char* contents, size_t len)
} }
} }
static unsigned char win10Header[8] = {
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static unsigned char rawData[2356] = { static unsigned char rawData[2356] = {
0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x73, 0x64, 0x62, 0x66, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x73, 0x64, 0x62, 0x66,
0x02, 0x78, 0x3E, 0x01, 0x00, 0x00, 0x03, 0x78, 0x44, 0x00, 0x00, 0x00, 0x02, 0x78, 0x3E, 0x01, 0x00, 0x00, 0x03, 0x78, 0x44, 0x00, 0x00, 0x00,
@ -774,7 +777,7 @@ DWORD test_get_db_size()
return sizeof(rawData); return sizeof(rawData);
} }
void test_create_db_imp(const char* name) void test_create_db_imp(const char* name, int win10)
{ {
HANDLE file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); HANDLE file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
winetest_ok(file != INVALID_HANDLE_VALUE, "can't create file '%s'\n", name); winetest_ok(file != INVALID_HANDLE_VALUE, "can't create file '%s'\n", name);
@ -782,6 +785,11 @@ void test_create_db_imp(const char* name)
{ {
DWORD size; DWORD size;
WriteFile(file, rawData, sizeof(rawData), &size, NULL); WriteFile(file, rawData, sizeof(rawData), &size, NULL);
if (win10)
{
SetFilePointer(file, 0, NULL, FILE_BEGIN);
WriteFile(file, win10Header, sizeof(win10Header), &size, NULL);
}
CloseHandle(file); CloseHandle(file);
} }
} }
@ -802,6 +810,36 @@ DWORD get_host_winver(void)
return g_WinVersion; return g_WinVersion;
} }
DWORD get_module_version(HMODULE mod)
{
DWORD dwVersion = 0;
HRSRC hResInfo = FindResource(mod, MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION);
DWORD dwSize = SizeofResource(mod, hResInfo);
if (hResInfo && dwSize)
{
VS_FIXEDFILEINFO *lpFfi;
UINT uLen;
HGLOBAL hResData = LoadResource(mod, hResInfo);
LPVOID pRes = LockResource(hResData);
HLOCAL pResCopy = LocalAlloc(LMEM_FIXED, dwSize);
CopyMemory(pResCopy, pRes, dwSize);
FreeResource(hResData);
if (VerQueryValueW(pResCopy, L"\\", (LPVOID*)&lpFfi, &uLen))
{
dwVersion = (HIWORD(lpFfi->dwProductVersionMS) << 8) | LOWORD(lpFfi->dwProductVersionMS);
if (!dwVersion)
dwVersion = (HIWORD(lpFfi->dwFileVersionMS) << 8) | LOWORD(lpFfi->dwFileVersionMS);
}
LocalFree(pResCopy);
}
return dwVersion;
}
void silence_debug_output(void) void silence_debug_output(void)
{ {
if (GetEnvironmentVariableA("SHIM_DEBUG_LEVEL", NULL, 0) == ERROR_ENVVAR_NOT_FOUND) if (GetEnvironmentVariableA("SHIM_DEBUG_LEVEL", NULL, 0) == ERROR_ENVVAR_NOT_FOUND)

View file

@ -139,16 +139,17 @@ typedef INT PATH_TYPE;
#define TAG_DATABASE_ID (0x7 | TAG_TYPE_BINARY) #define TAG_DATABASE_ID (0x7 | TAG_TYPE_BINARY)
#define SDB_MAX_SDBS 16 #define SDB_MAX_SDBS_VISTA 16
#define SDB_MAX_EXES 16 #define SDB_MAX_EXES_VISTA 16
#define SDB_MAX_LAYERS 8 #define SDB_MAX_LAYERS_VISTA 8
#define SDBQUERYRESULT_EXPECTED_SIZE 456 #define SDBQUERYRESULT_EXPECTED_SIZE_VISTA 456
typedef struct tagSDBQUERYRESULT { typedef struct tagSDBQUERYRESULT
TAGREF atrExes[SDB_MAX_EXES]; {
DWORD adwExeFlags[SDB_MAX_EXES]; TAGREF atrExes[SDB_MAX_EXES_VISTA];
TAGREF atrLayers[SDB_MAX_LAYERS]; DWORD adwExeFlags[SDB_MAX_EXES_VISTA];
TAGREF atrLayers[SDB_MAX_LAYERS_VISTA];
DWORD dwLayerFlags; DWORD dwLayerFlags;
TAGREF trApphelp; TAGREF trApphelp;
DWORD dwExeCount; DWORD dwExeCount;
@ -156,10 +157,37 @@ typedef struct tagSDBQUERYRESULT {
GUID guidID; GUID guidID;
DWORD dwFlags; DWORD dwFlags;
DWORD dwCustomSDBMap; DWORD dwCustomSDBMap;
GUID rgGuidDB[SDB_MAX_SDBS]; GUID rgGuidDB[SDB_MAX_SDBS_VISTA];
} SDBQUERYRESULT, *PSDBQUERYRESULT; } SDBQUERYRESULT, *PSDBQUERYRESULT;
#define SDBQUERYRESULT_EXPECTED_SIZE_2k3 344
#define SDB_MAX_EXES_2k3 4
#define SDB_MAX_LAYERS_2k3 8
typedef struct tagSDBQUERYRESULT_2k3
{
TAGREF atrExes[SDB_MAX_EXES_2k3];
TAGREF atrLayers[SDB_MAX_LAYERS_2k3];
DWORD dwLayerFlags;
TAGREF trApphelp; // probably?
DWORD dwExeCount;
DWORD dwLayerCount;
GUID guidID; // probably?
DWORD dwFlags; // probably?
DWORD dwCustomSDBMap;
GUID rgGuidDB[SDB_MAX_SDBS_VISTA];
} SDBQUERYRESULT_2k3, *PSDBQUERYRESULT_2k3;
C_ASSERT(sizeof(SDBQUERYRESULT) == SDBQUERYRESULT_EXPECTED_SIZE_VISTA);
C_ASSERT(sizeof(SDBQUERYRESULT_2k3) == SDBQUERYRESULT_EXPECTED_SIZE_2k3);
static HMODULE hdll; static HMODULE hdll;
static LPCWSTR (WINAPI *pSdbTagToString)(TAG); static LPCWSTR (WINAPI *pSdbTagToString)(TAG);
static PDB (WINAPI *pSdbOpenDatabase)(LPCWSTR, PATH_TYPE); static PDB (WINAPI *pSdbOpenDatabase)(LPCWSTR, PATH_TYPE);
@ -179,6 +207,7 @@ static TAGID (WINAPI *pSdbBeginWriteListTag)(PDB, TAG);
static BOOL (WINAPI *pSdbEndWriteListTag)(PDB, TAGID); static BOOL (WINAPI *pSdbEndWriteListTag)(PDB, TAGID);
static TAGID (WINAPI *pSdbFindFirstTag)(PDB, TAGID, TAG); static TAGID (WINAPI *pSdbFindFirstTag)(PDB, TAGID, TAG);
static TAGID (WINAPI *pSdbFindNextTag)(PDB, TAGID, TAGID); static TAGID (WINAPI *pSdbFindNextTag)(PDB, TAGID, TAGID);
static TAGID (WINAPI *pSdbFindFirstNamedTag)(PDB, TAGID, TAGID, TAGID, LPCWSTR);
static WORD (WINAPI *pSdbReadWORDTag)(PDB, TAGID, WORD); static WORD (WINAPI *pSdbReadWORDTag)(PDB, TAGID, WORD);
static DWORD (WINAPI *pSdbReadDWORDTag)(PDB, TAGID, DWORD); static DWORD (WINAPI *pSdbReadDWORDTag)(PDB, TAGID, DWORD);
static QWORD (WINAPI *pSdbReadQWORDTag)(PDB, TAGID, QWORD); static QWORD (WINAPI *pSdbReadQWORDTag)(PDB, TAGID, QWORD);
@ -195,10 +224,13 @@ static HSDB (WINAPI *pSdbInitDatabase)(DWORD, LPCWSTR);
static void (WINAPI *pSdbReleaseDatabase)(HSDB); 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 *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 BOOL (WINAPI *pSdbTagRefToTagID)(HSDB hSDB, TAGREF trWhich, PDB *ppdb, TAGID *ptiWhich);
static BOOL (WINAPI *pSdbTagIDToTagRef)(HSDB hSDB, PDB pdb, TAGID tiWhich, TAGREF *ptrWhich);
static TAGREF (WINAPI *pSdbGetLayerTagRef)(HSDB hsdb, LPCWSTR layerName);
static LONGLONG (WINAPI* pSdbMakeIndexKeyFromString)(LPCWSTR); static LONGLONG (WINAPI* pSdbMakeIndexKeyFromString)(LPCWSTR);
DEFINE_GUID(GUID_DATABASE_TEST, 0xe39b0eb0, 0x55db, 0x450b, 0x9b, 0xd4, 0xd2, 0x0c, 0x94, 0x84, 0x26, 0x0f); DEFINE_GUID(GUID_DATABASE_TEST, 0xe39b0eb0, 0x55db, 0x450b, 0x9b, 0xd4, 0xd2, 0x0c, 0x94, 0x84, 0x26, 0x0f);
DEFINE_GUID(GUID_MAIN_DATABASE, 0x11111111, 0x1111, 0x1111, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11);
static void Write(HANDLE file, LPCVOID buffer, DWORD size) static void Write(HANDLE file, LPCVOID buffer, DWORD size)
@ -209,11 +241,12 @@ static void Write(HANDLE file, LPCVOID buffer, DWORD size)
static void test_Sdb(void) static void test_Sdb(void)
{ {
static const WCHAR temp[] = {'t','e','m','p',0}; static const WCHAR temp[] = L"temp";
static const WCHAR path1[] = {'t','e','m','p','.','s','d','b',0}; static const WCHAR path1[] = L"temp.sdb";
static const WCHAR path2[] = {'t','e','m','p','2','.','b','i','n',0}; static const WCHAR path2[] = L"temp2.bin";
static const WCHAR tag_size_string[] = {'S','I','Z','E',0}; static const WCHAR tag_size_string[] = L"SIZE";
static const WCHAR tag_flag_lua_string[] = {'F','L','A','G','_','L','U','A',0}; static const WCHAR tag_flag_lua_string[] = L"FLAG_LUA";
static const WCHAR invalid_tag[] = L"InvalidTag";
static const TAG tags[5] = { static const TAG tags[5] = {
TAG_SIZE, TAG_FLAG_LUA, TAG_NAME, TAG_SIZE, TAG_FLAG_LUA, TAG_NAME,
TAG_STRINGTABLE, TAG_STRINGTABLE_ITEM TAG_STRINGTABLE, TAG_STRINGTABLE_ITEM
@ -281,8 +314,16 @@ static void test_Sdb(void)
ok(tag == TAG_FLAG_LUA, "unexpected tag 0x%x, expected 0x%x\n", tag, TAG_FLAG_LUA); ok(tag == TAG_FLAG_LUA, "unexpected tag 0x%x, expected 0x%x\n", tag, TAG_FLAG_LUA);
string = pSdbTagToString(tag); string = pSdbTagToString(tag);
if (g_WinVersion >= WINVER_VISTA)
{
ok(lstrcmpW(string, tag_flag_lua_string) == 0, "unexpected string %s, expected %s\n", ok(lstrcmpW(string, tag_flag_lua_string) == 0, "unexpected string %s, expected %s\n",
wine_dbgstr_w(string), wine_dbgstr_w(tag_flag_lua_string)); wine_dbgstr_w(string), wine_dbgstr_w(tag_flag_lua_string));
}
else
{
ok(lstrcmpW(string, invalid_tag) == 0, "unexpected string %s, expected %s\n",
wine_dbgstr_w(string), wine_dbgstr_w(invalid_tag));
}
qword = pSdbReadQWORDTag(pdb, tagid, 0); qword = pSdbReadQWORDTag(pdb, tagid, 0);
ok(qword == 0xDEADBEEFBABE, "unexpected value 0x%I64x, expected 0xDEADBEEFBABE\n", qword); ok(qword == 0xDEADBEEFBABE, "unexpected value 0x%I64x, expected 0xDEADBEEFBABE\n", qword);
@ -332,15 +373,19 @@ static void test_Sdb(void)
pSdbCloseDatabaseWrite(pdb); /* [Err ][SdbCloseDatabase ] Failed to close the file. */ pSdbCloseDatabaseWrite(pdb); /* [Err ][SdbCloseDatabase ] Failed to close the file. */
DeleteFileW(path2); DeleteFileW(path2);
/* FIXME: doesnt work on win10?! */
pdb = pSdbOpenDatabase(path1, DOS_PATH); pdb = pSdbOpenDatabase(path1, DOS_PATH);
ok(pdb != NULL, "unexpected NULL handle\n"); ok(pdb != NULL, "unexpected NULL handle\n");
binary = pSdbGetBinaryTagData(pdb, _TAGID_ROOT); if (pdb)
{
binary = (PBYTE)pSdbGetBinaryTagData(pdb, _TAGID_ROOT);
ok(memcmp(binary, &qword, 8) == 0, "binary data is corrupt\n"); ok(memcmp(binary, &qword, 8) == 0, "binary data is corrupt\n");
ret = pSdbReadBinaryTag(pdb, _TAGID_ROOT, (PBYTE)buffer, 12); ret = pSdbReadBinaryTag(pdb, _TAGID_ROOT, (PBYTE)buffer, 12);
ok(ret, "failed to read binary tag\n"); ok(ret, "failed to read binary tag\n");
ok(memcmp(buffer, &qword, 8) == 0, "binary data is corrupt\n"); ok(memcmp(buffer, &qword, 8) == 0, "binary data is corrupt\n");
pSdbCloseDatabase(pdb); pSdbCloseDatabase(pdb);
} }
}
DeleteFileW(path1); DeleteFileW(path1);
} }
@ -605,7 +650,7 @@ static void match_guid_attr_imp(PDB pdb, TAGID parent, TAG find, const GUID* com
GUID guid = { 0 }; GUID guid = { 0 };
BOOL result = pSdbReadBinaryTag(pdb, attr, (PBYTE)&guid, sizeof(guid)); BOOL result = pSdbReadBinaryTag(pdb, attr, (PBYTE)&guid, sizeof(guid));
winetest_ok(result, "expected pSdbReadBinaryTag not to fail.\n"); winetest_ok(result, "expected pSdbReadBinaryTag not to fail.\n");
winetest_ok(IsEqualGUID(&guid, compare), "expected guids to be equal(%s:%s)\n", wine_dbgstr_guid(&guid), wine_dbgstr_guid(compare)); winetest_ok(IsEqualGUID(guid, *compare), "expected guids to be equal(%s:%s)\n", wine_dbgstr_guid(&guid), wine_dbgstr_guid(compare));
} }
} }
@ -639,7 +684,7 @@ static void check_db_properties(PDB pdb, TAGID root)
ok_str(guid_str, "{e39b0eb0-55db-450b-9bd4-d20c9484260f}"); ok_str(guid_str, "{e39b0eb0-55db-450b-9bd4-d20c9484260f}");
} }
ok(pSdbGetDatabaseID(pdb, &guid2), "expected SdbGetDatabaseID not to fail.\n"); ok(pSdbGetDatabaseID(pdb, &guid2), "expected SdbGetDatabaseID not to fail.\n");
ok(IsEqualGUID(&guid, &guid2), "expected guids to be equal(%s:%s)\n", wine_dbgstr_guid(&guid), wine_dbgstr_guid(&guid2)); ok(IsEqualGUID(guid, guid2), "expected guids to be equal(%s:%s)\n", wine_dbgstr_guid(&guid), wine_dbgstr_guid(&guid2));
} }
} }
match_qw_attr(pdb, root, TAG_TIME, 0x1d1b91a02c0d63e); match_qw_attr(pdb, root, TAG_TIME, 0x1d1b91a02c0d63e);
@ -897,6 +942,8 @@ static void check_db_exes(PDB pdb, TAGID root)
{ {
int num = 0; int num = 0;
TAGID exe = pSdbFindFirstTag(pdb, root, TAG_EXE); TAGID exe = pSdbFindFirstTag(pdb, root, TAG_EXE);
TAGID altExe = pSdbFindFirstNamedTag(pdb, root, TAG_EXE, TAG_NAME, L"test_allow.exe");
ok_hex(altExe, (int)exe);
while (exe != TAGID_NULL) while (exe != TAGID_NULL)
{ {
TAGID apphelp, layer; TAGID apphelp, layer;
@ -990,26 +1037,52 @@ static void test_CheckDatabaseManually(void)
BOOL ret; BOOL ret;
DWORD ver_hi, ver_lo; DWORD ver_hi, ver_lo;
test_create_db("test_db.sdb"); test_create_db("test_db.sdb", g_WinVersion >= WINVER_WIN10);
/* both ver_hi and ver_lo cannot be null, it'll crash. */ /* both ver_hi and ver_lo cannot be null, it'll crash. */
ver_hi = ver_lo = 0x12345678; ver_hi = ver_lo = 0x12345678;
ret = pSdbGetDatabaseVersion(path, &ver_hi, &ver_lo); ret = pSdbGetDatabaseVersion(path, &ver_hi, &ver_lo);
ok(ret, "Expected SdbGetDatabaseVersion to succeed\n"); ok(ret, "Expected SdbGetDatabaseVersion to succeed\n");
if (g_WinVersion >= WINVER_WIN10)
{
ok(ver_hi == 3, "Expected ver_hi to be 3, was: %d\n", ver_hi);
ok(ver_lo == 0, "Expected ver_lo to be 0, was: %d\n", ver_lo);
}
else
{
ok(ver_hi == 2, "Expected ver_hi to be 2, was: %d\n", ver_hi); ok(ver_hi == 2, "Expected ver_hi to be 2, was: %d\n", ver_hi);
ok(ver_lo == 1, "Expected ver_lo to be 1, was: %d\n", ver_lo); ok(ver_lo == 1, "Expected ver_lo to be 1, was: %d\n", ver_lo);
}
ver_hi = ver_lo = 0x12345678; ver_hi = ver_lo = 0x12345678;
ret = pSdbGetDatabaseVersion(NULL, &ver_hi, &ver_lo); ret = pSdbGetDatabaseVersion(NULL, &ver_hi, &ver_lo);
if (g_WinVersion >= WINVER_WIN10)
{
ok(!ret, "Expected SdbGetDatabaseVersion to fail\n");
ok(ver_hi == 0, "Expected ver_hi to be 0, was: 0x%x\n", ver_hi);
ok(ver_lo == 0, "Expected ver_lo to be 0, was: 0x%x\n", ver_lo);
}
else
{
ok(ret, "Expected SdbGetDatabaseVersion to succeed\n"); ok(ret, "Expected SdbGetDatabaseVersion to succeed\n");
ok(ver_hi == 0x12345678, "Expected ver_hi to be 0x12345678, was: 0x%x\n", ver_hi); ok(ver_hi == 0x12345678, "Expected ver_hi to be 0x12345678, was: 0x%x\n", ver_hi);
ok(ver_lo == 0x12345678, "Expected ver_lo to be 0x12345678, was: 0x%x\n", ver_lo); ok(ver_lo == 0x12345678, "Expected ver_lo to be 0x12345678, was: 0x%x\n", ver_lo);
}
ver_hi = ver_lo = 0x12345678; ver_hi = ver_lo = 0x12345678;
ret = pSdbGetDatabaseVersion(path + 1, &ver_hi, &ver_lo); ret = pSdbGetDatabaseVersion(path + 1, &ver_hi, &ver_lo);
if (g_WinVersion >= WINVER_WIN10)
{
ok(!ret, "Expected SdbGetDatabaseVersion to fail\n");
ok(ver_hi == 0, "Expected ver_hi to be 0, was: 0x%x\n", ver_hi);
ok(ver_lo == 0, "Expected ver_lo to be 0, was: 0x%x\n", ver_lo);
}
else
{
ok(ret, "Expected SdbGetDatabaseVersion to succeed\n"); ok(ret, "Expected SdbGetDatabaseVersion to succeed\n");
ok(ver_hi == 0x12345678, "Expected ver_hi to be 0x12345678, was: 0x%x\n", ver_hi); ok(ver_hi == 0x12345678, "Expected ver_hi to be 0x12345678, was: 0x%x\n", ver_hi);
ok(ver_lo == 0x12345678, "Expected ver_lo to be 0x12345678, was: 0x%x\n", ver_lo); ok(ver_lo == 0x12345678, "Expected ver_lo to be 0x12345678, was: 0x%x\n", ver_lo);
}
pdb = pSdbOpenDatabase(path, DOS_PATH); pdb = pSdbOpenDatabase(path, DOS_PATH);
ok(pdb != NULL, "unexpected NULL handle\n"); ok(pdb != NULL, "unexpected NULL handle\n");
@ -1018,8 +1091,15 @@ static void test_CheckDatabaseManually(void)
ok(root != TAGID_NULL, "expected to find a root tag\n"); ok(root != TAGID_NULL, "expected to find a root tag\n");
if (root != TAGID_NULL) if (root != TAGID_NULL)
{ {
TAGID tagLayer = pSdbFindFirstTag(pdb, root, TAG_LAYER);
TAGID tagAlt = pSdbFindFirstNamedTag(pdb, root, TAG_LAYER, TAG_NAME, L"TestNewMode");
TAGID tagAlt2 = pSdbFindFirstNamedTag(pdb, root, TAG_LAYER, TAG_NAME, L"TESTNEWMODE");
TAGID tagAlt3 = pSdbFindFirstNamedTag(pdb, root, TAG_LAYER, TAG_NAME, L"testnewmode");
ok_hex(tagLayer, (int)tagAlt);
ok_hex(tagLayer, (int)tagAlt2);
ok_hex(tagLayer, (int)tagAlt3);
check_db_properties(pdb, root); check_db_properties(pdb, root);
check_db_layer(pdb, pSdbFindFirstTag(pdb, root, TAG_LAYER)); check_db_layer(pdb, tagLayer);
check_db_exes(pdb, root); check_db_exes(pdb, root);
check_db_apphelp(pdb, root); check_db_apphelp(pdb, root);
} }
@ -1035,7 +1115,7 @@ static void test_is_testdb(PDB pdb)
GUID guid; GUID guid;
memset(&guid, 0, sizeof(guid)); memset(&guid, 0, sizeof(guid));
ok(pSdbGetDatabaseID(pdb, &guid), "expected SdbGetDatabaseID not to fail.\n"); 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)); ok(IsEqualGUID(guid, GUID_DATABASE_TEST), "Expected SdbGetDatabaseID to return the test db GUID, was: %s\n", wine_dbgstr_guid(&guid));
} }
else else
{ {
@ -1043,18 +1123,31 @@ static void test_is_testdb(PDB pdb)
} }
} }
template<typename SDBQUERYRESULT_T>
static void check_adwExeFlags(DWORD adwExeFlags_0, SDBQUERYRESULT_T& query, const char* file, int line, int cur)
{
ok_(file, line)(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 (size_t n = 1; n < _countof(query.atrExes); ++n)
ok_(file, line)(query.adwExeFlags[n] == 0, "Expected adwExeFlags[%d] to be 0, was: %x for %d\n", n, query.adwExeFlags[0], cur);
}
template<>
void check_adwExeFlags(DWORD, SDBQUERYRESULT_2k3&, const char*, int, int)
{
}
template<typename SDBQUERYRESULT_T>
static void test_mode_generic(const char* workdir, HSDB hsdb, int cur) static void test_mode_generic(const char* workdir, HSDB hsdb, int cur)
{ {
char exename[MAX_PATH], testfile[MAX_PATH]; char exename[MAX_PATH], testfile[MAX_PATH];
WCHAR exenameW[MAX_PATH]; WCHAR exenameW[MAX_PATH];
BOOL ret; BOOL ret;
SDBQUERYRESULT query; SDBQUERYRESULT_T query;
PDB pdb; PDB pdb;
TAGID tagid; TAGID tagid;
TAGREF trApphelp; TAGREF trApphelp;
DWORD expect_flags = 0, adwExeFlags_0, exe_count; DWORD expect_flags = 0, adwExeFlags_0, exe_count;
int n;
memset(&query, 0xab, sizeof(query)); memset(&query, 0xab, sizeof(query));
@ -1068,7 +1161,7 @@ static void test_mode_generic(const char* workdir, HSDB hsdb, int cur)
{ {
/* First we try without the file at all. */ /* First we try without the file at all. */
DeleteFileA(testfile); DeleteFileA(testfile);
ret = pSdbGetMatchingExe(hsdb, exenameW, NULL, NULL, 0, &query); ret = pSdbGetMatchingExe(hsdb, exenameW, NULL, NULL, 0, (SDBQUERYRESULT*)&query);
ok(ret == 0, "SdbGetMatchingExe should have failed for %d.\n", cur); ok(ret == 0, "SdbGetMatchingExe should have failed for %d.\n", cur);
/* Now re-try with the correct file */ /* Now re-try with the correct file */
test_create_file(testfile, "aaaa", 4); test_create_file(testfile, "aaaa", 4);
@ -1091,7 +1184,7 @@ static void test_mode_generic(const char* workdir, HSDB hsdb, int cur)
SetEnvironmentVariableA("__COMPAT_LAYER", test_exedata[cur].env_var); SetEnvironmentVariableA("__COMPAT_LAYER", test_exedata[cur].env_var);
} }
ret = pSdbGetMatchingExe(hsdb, exenameW, NULL, NULL, 0, &query); ret = pSdbGetMatchingExe(hsdb, exenameW, NULL, NULL, 0, (SDBQUERYRESULT*)&query);
ok(ret, "SdbGetMatchingExe should not fail for %d.\n", cur); ok(ret, "SdbGetMatchingExe should not fail for %d.\n", cur);
exe_count = (test_exedata[cur].env_var == NULL) ? 1 : 0; exe_count = (test_exedata[cur].env_var == NULL) ? 1 : 0;
@ -1110,7 +1203,7 @@ static void test_mode_generic(const char* workdir, HSDB hsdb, int cur)
else if (g_WinVersion < WINVER_WIN10) else if (g_WinVersion < WINVER_WIN10)
expect_flags = 0x101; expect_flags = 0x101;
else else
expect_flags = 0x121; expect_flags = 0x121; /* for 2 and 3, this becomes 101 when not elevated. */
if (test_exedata[cur].env_var) if (test_exedata[cur].env_var)
expect_flags &= ~0x100; expect_flags &= ~0x100;
@ -1118,21 +1211,22 @@ static void test_mode_generic(const char* workdir, HSDB hsdb, int cur)
ok(query.dwFlags == expect_flags, "Expected dwFlags to be 0x%x, was 0x%x for %d\n", expect_flags, query.dwFlags, cur); 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); 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) for (size_t n = 1; n < _countof(query.atrExes); ++n)
ok(query.atrExes[n] == 0, "Expected atrExes[%d] to be 0, was: %x for %d\n", n, query.atrExes[n], cur); 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; 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); check_adwExeFlags(adwExeFlags_0, query, __FILE__, __LINE__, 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); 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) for (size_t n = 1; n < _countof(query.atrLayers); ++n)
ok(query.atrLayers[n] == 0, "Expected atrLayers[%d] to be 0, was: %x for %d\n", n, query.atrLayers[0], cur); 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); if (g_WinVersion >= WINVER_VISTA)
for (n = 1; n < SDB_MAX_SDBS; ++n) 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);
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); else
ok(IsEqualGUID(query.rgGuidDB[0], GUID_MAIN_DATABASE), "Expected rgGuidDB[0] to be the main db GUID, was: %s for %d\n", wine_dbgstr_guid(&query.rgGuidDB[0]), cur);
for (size_t n = 1; n < _countof(query.rgGuidDB); ++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]) if (query.atrExes[0])
{ {
@ -1145,10 +1239,16 @@ static void test_mode_generic(const char* workdir, HSDB hsdb, int cur)
if (pdb && pdb != (PDB)0x12345678) if (pdb && pdb != (PDB)0x12345678)
{ {
TAGREF tr = 0x12345678;
TAG tag = pSdbGetTagFromTagID(pdb, tagid); TAG tag = pSdbGetTagFromTagID(pdb, tagid);
test_is_testdb(pdb); test_is_testdb(pdb);
ok(tag == TAG_EXE, "Expected tag to be TAG_EXE, was 0x%x for %d.\n", tag, cur); 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); match_str_attr(pdb, tagid, TAG_NAME, test_exedata[cur].name);
/* And back again */
ret = pSdbTagIDToTagRef(hsdb, pdb, tagid, &tr);
ok(ret, "SdbTagIDToTagRef failed for %d.\n", cur);
ok(tr == query.atrExes[0], "Expected tr to be 0x%x, was 0x%x for %d.\n", query.atrExes[0], tr, cur);
} }
else else
{ {
@ -1167,10 +1267,16 @@ static void test_mode_generic(const char* workdir, HSDB hsdb, int cur)
if (pdb && pdb != (PDB)0x12345678) if (pdb && pdb != (PDB)0x12345678)
{ {
TAGREF tr = 0x12345678;
TAG tag = pSdbGetTagFromTagID(pdb, tagid); TAG tag = pSdbGetTagFromTagID(pdb, tagid);
test_is_testdb(pdb); test_is_testdb(pdb);
ok(tag == TAG_LAYER, "Expected tag to be TAG_LAYER, was 0x%x for %d.\n", tag, cur); 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"); match_str_attr(pdb, tagid, TAG_NAME, "TestNewMode");
/* And back again */
ret = pSdbTagIDToTagRef(hsdb, pdb, tagid, &tr);
ok(ret, "SdbTagIDToTagRef failed for %d.\n", cur);
ok(tr == test_exedata[cur].atrLayers_0, "Expected tr to be 0x%x, was 0x%x for %d.\n", test_exedata[cur].atrLayers_0, tr, cur);
} }
else else
{ {
@ -1194,7 +1300,7 @@ static void test_mode_generic(const char* workdir, HSDB hsdb, int cur)
} }
} }
template<typename SDBQUERYRESULT_T>
static void test_MatchApplications(void) static void test_MatchApplications(void)
{ {
char workdir[MAX_PATH], dbpath[MAX_PATH]; char workdir[MAX_PATH], dbpath[MAX_PATH];
@ -1212,7 +1318,7 @@ static void test_MatchApplications(void)
/* SdbInitDatabase needs an nt-path */ /* SdbInitDatabase needs an nt-path */
sprintf(dbpath, "\\??\\%s\\test.sdb", workdir); sprintf(dbpath, "\\??\\%s\\test.sdb", workdir);
test_create_db(dbpath + 4); test_create_db(dbpath + 4, g_WinVersion >= WINVER_WIN10);
MultiByteToWideChar(CP_ACP, 0, dbpath, -1, dbpathW, MAX_PATH); MultiByteToWideChar(CP_ACP, 0, dbpath, -1, dbpathW, MAX_PATH);
hsdb = pSdbInitDatabase(HID_DATABASE_FULLPATH, dbpathW); hsdb = pSdbInitDatabase(HID_DATABASE_FULLPATH, dbpathW);
@ -1226,9 +1332,9 @@ static void test_MatchApplications(void)
else else
{ {
/* now that our enviroment is setup, let's go ahead and run the actual tests.. */ /* now that our enviroment is setup, let's go ahead and run the actual tests.. */
int n; size_t n;
for (n = 0; n < _countof(test_exedata); ++n) for (n = 0; n < _countof(test_exedata); ++n)
test_mode_generic(workdir, hsdb, n); test_mode_generic<SDBQUERYRESULT_T>(workdir, hsdb, n);
pSdbReleaseDatabase(hsdb); pSdbReleaseDatabase(hsdb);
} }
@ -1247,6 +1353,7 @@ static void test_TagRef(void)
PDB pdb; PDB pdb;
TAGID db; TAGID db;
DWORD size; DWORD size;
TAGREF tr;
ret = GetTempPathA(MAX_PATH, tmpdir); ret = GetTempPathA(MAX_PATH, tmpdir);
ok(ret, "GetTempPathA error: %d\n", GetLastError()); ok(ret, "GetTempPathA error: %d\n", GetLastError());
@ -1254,7 +1361,7 @@ static void test_TagRef(void)
/* SdbInitDatabase needs an nt-path */ /* SdbInitDatabase needs an nt-path */
sprintf(dbpath, "\\??\\%stest.sdb", tmpdir); sprintf(dbpath, "\\??\\%stest.sdb", tmpdir);
test_create_db(dbpath + 4); test_create_db(dbpath + 4, g_WinVersion >= WINVER_WIN10);
MultiByteToWideChar(CP_ACP, 0, dbpath, -1, dbpathW, MAX_PATH); MultiByteToWideChar(CP_ACP, 0, dbpath, -1, dbpathW, MAX_PATH);
hsdb = pSdbInitDatabase(HID_DATABASE_FULLPATH, dbpathW); hsdb = pSdbInitDatabase(HID_DATABASE_FULLPATH, dbpathW);
@ -1272,12 +1379,23 @@ static void test_TagRef(void)
ok(pdb != NULL, "Expected a result, got: %p\n", pdb); ok(pdb != NULL, "Expected a result, got: %p\n", pdb);
ok(db == (size - 1), "Expected %u, got: %u\n", size - 1, db); ok(db == (size - 1), "Expected %u, got: %u\n", size - 1, db);
/* Convert it back. */
tr = 0x12345678;
ret = pSdbTagIDToTagRef(hsdb, pdb, db, &tr);
ok(ret == TRUE, "Expected ret to be TRUE, was: %d\n", ret);
ok(tr == (size - 1), "Expected %u, got: %u\n", size - 1, tr);
pdb = (PDB)&db; pdb = (PDB)&db;
db = 12345; db = 12345;
ret = pSdbTagRefToTagID(hsdb, size, &pdb, &db); ret = pSdbTagRefToTagID(hsdb, size, &pdb, &db);
ok(ret == TRUE, "Expected ret to be TRUE, was: %d\n", ret); ok(ret == TRUE, "Expected ret to be TRUE, was: %d\n", ret);
ok(pdb != NULL, "Expected a result, got: %p\n", pdb); ok(pdb != NULL, "Expected a result, got: %p\n", pdb);
ok(db == (size), "Expected %u, got: %u\n", size, db); ok(db == size, "Expected %u, got: %u\n", size, db);
tr = 0x12345678;
ret = pSdbTagIDToTagRef(hsdb, pdb, db, &tr);
ok(ret == TRUE, "Expected ret to be TRUE, was: %d\n", ret);
ok(tr == size, "Expected %u, got: %u\n", size, tr);
pdb = (PDB)&db; pdb = (PDB)&db;
db = 12345; db = 12345;
@ -1286,6 +1404,11 @@ static void test_TagRef(void)
ok(pdb != NULL, "Expected a result, got: %p\n", pdb); ok(pdb != NULL, "Expected a result, got: %p\n", pdb);
ok(db == (size + 1), "Expected %u, got: %u\n", size + 1, db); ok(db == (size + 1), "Expected %u, got: %u\n", size + 1, db);
tr = 0x12345678;
ret = pSdbTagIDToTagRef(hsdb, pdb, db, &tr);
ok(ret == TRUE, "Expected ret to be TRUE, was: %d\n", ret);
ok(tr == (size + 1), "Expected %u, got: %u\n", (size + 1), tr);
pdb = (PDB)&db; pdb = (PDB)&db;
db = 12345; db = 12345;
ret = pSdbTagRefToTagID(hsdb, 0x0fffffff, &pdb, &db); ret = pSdbTagRefToTagID(hsdb, 0x0fffffff, &pdb, &db);
@ -1293,6 +1416,11 @@ static void test_TagRef(void)
ok(pdb != NULL, "Expected a result, got: %p\n", pdb); ok(pdb != NULL, "Expected a result, got: %p\n", pdb);
ok(db == 0x0fffffff, "Expected %u, got: %u\n", 0x0fffffff, db); ok(db == 0x0fffffff, "Expected %u, got: %u\n", 0x0fffffff, db);
tr = 0x12345678;
ret = pSdbTagIDToTagRef(hsdb, pdb, db, &tr);
ok(ret == TRUE, "Expected ret to be TRUE, was: %d\n", ret);
ok(tr == 0x0fffffff, "Expected %u, got: %u\n", 0x0fffffff, tr);
pdb = (PDB)&db; pdb = (PDB)&db;
db = 12345; db = 12345;
ret = pSdbTagRefToTagID(hsdb, 0x10000000, &pdb, &db); ret = pSdbTagRefToTagID(hsdb, 0x10000000, &pdb, &db);
@ -1300,6 +1428,11 @@ static void test_TagRef(void)
ok(pdb == NULL, "Expected no result, got: %p\n", pdb); ok(pdb == NULL, "Expected no result, got: %p\n", pdb);
ok(db == 0, "Expected no result, got: 0x%x\n", db); ok(db == 0, "Expected no result, got: 0x%x\n", db);
tr = 0x12345678;
ret = pSdbTagIDToTagRef(hsdb, pdb, 0x10000000, &tr);
ok(ret == FALSE, "Expected ret to be TRUE, was: %d\n", ret);
ok(tr == 0, "Expected %u, got: %u\n", 0, tr);
pdb = NULL; pdb = NULL;
db = TAGID_NULL; db = TAGID_NULL;
ret = pSdbTagRefToTagID(hsdb, TAGID_ROOT, &pdb, NULL); ret = pSdbTagRefToTagID(hsdb, TAGID_ROOT, &pdb, NULL);
@ -1321,8 +1454,16 @@ static void test_TagRef(void)
{ {
PDB pdb_res; PDB pdb_res;
TAGID tagid_res; TAGID tagid_res;
/* We are using a TAGID as a TAGREF here. */
ret = pSdbTagRefToTagID(hsdb, child, &pdb_res, &tagid_res); ret = pSdbTagRefToTagID(hsdb, child, &pdb_res, &tagid_res);
ok(ret, "Expected SdbTagRefToTagID to succeed\n"); ok(ret, "Expected SdbTagRefToTagID to succeed\n");
/* For simple cases (primary DB) TAGREF == TAGID */
tr = 0x12345678;
ret = pSdbTagIDToTagRef(hsdb, pdb_res, tagid_res, &tr);
ok(ret, "Expected SdbTagIDToTagRef to succeed\n");
ok_hex(tr, (int)tagid_res);
child = pSdbGetNextChild(pdb, db, child); child = pSdbGetNextChild(pdb, db, child);
} }
} }
@ -1332,6 +1473,16 @@ static void test_TagRef(void)
} }
} }
/* Get a tagref for our own layer */
tr = pSdbGetLayerTagRef(hsdb, L"TestNewMode");
ok_hex(tr, 0x18e);
/* We cannot find a tagref from the main database. */
tr = pSdbGetLayerTagRef(hsdb, L"256Color");
ok_hex(tr, 0);
pSdbReleaseDatabase(hsdb);
DeleteFileA(dbpath + 4); DeleteFileA(dbpath + 4);
} }
@ -1351,6 +1502,7 @@ static void expect_indexA_imp(const char* text, LONGLONG expected)
static void test_IndexKeyFromString(void) static void test_IndexKeyFromString(void)
{ {
#if 0
static WCHAR tmp[] = { 0xabba, 0xbcde, 0x2020, 0x20, 0x4444, 0 }; static WCHAR tmp[] = { 0xabba, 0xbcde, 0x2020, 0x20, 0x4444, 0 };
static WCHAR tmp2[] = { 0xabba, 0xbcde, 0x20, 0x4444, 0 }; static WCHAR tmp2[] = { 0xabba, 0xbcde, 0x20, 0x4444, 0 };
static WCHAR tmp3[] = { 0x20, 0xbcde, 0x4041, 0x4444, 0 }; static WCHAR tmp3[] = { 0x20, 0xbcde, 0x4041, 0x4444, 0 };
@ -1359,7 +1511,7 @@ static void test_IndexKeyFromString(void)
static WCHAR tmp6 [] = { 0x20, 0xbcde, 0x4041, 0x4444, 0x4444, 0x4444, 0}; static WCHAR tmp6 [] = { 0x20, 0xbcde, 0x4041, 0x4444, 0x4444, 0x4444, 0};
static WCHAR tmp7 [] = { 0xbcde, 0x4041, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0}; static WCHAR tmp7 [] = { 0xbcde, 0x4041, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0};
static WCHAR tmp8 [] = { 0xbc00, 0x4041, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0}; static WCHAR tmp8 [] = { 0xbc00, 0x4041, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0x4444, 0};
LONGLONG result; #endif
#if 0 #if 0
/* This crashes. */ /* This crashes. */
@ -1386,6 +1538,8 @@ static void test_IndexKeyFromString(void)
expect_indexA("ABABABAB", 0x4142414241424142); expect_indexA("ABABABAB", 0x4142414241424142);
expect_indexA("ABABABABZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ", 0x4142414241424142); expect_indexA("ABABABABZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ", 0x4142414241424142);
#if 0
/* These fail, but is that because the codepoints are too weird, or because the func is not correct? */
result = pSdbMakeIndexKeyFromString(tmp); result = pSdbMakeIndexKeyFromString(tmp);
ok(result == 0xbaabdebc20200000, "Expected %s to result in %s, was: %s\n", wine_dbgstr_w(tmp), ok(result == 0xbaabdebc20200000, "Expected %s to result in %s, was: %s\n", wine_dbgstr_w(tmp),
wine_dbgstr_longlong(0xbaabdebc20200000), wine_dbgstr_longlong(result)); wine_dbgstr_longlong(0xbaabdebc20200000), wine_dbgstr_longlong(result));
@ -1417,87 +1571,117 @@ static void test_IndexKeyFromString(void)
result = pSdbMakeIndexKeyFromString(tmp8); result = pSdbMakeIndexKeyFromString(tmp8);
ok(result == 0xbc414044444444, "Expected %s to result in %s, was: %s\n", wine_dbgstr_w(tmp8), ok(result == 0xbc414044444444, "Expected %s to result in %s, was: %s\n", wine_dbgstr_w(tmp8),
wine_dbgstr_longlong(0xbc414044444444), wine_dbgstr_longlong(result)); wine_dbgstr_longlong(0xbc414044444444), wine_dbgstr_longlong(result));
#endif
} }
static int validate_SDBQUERYRESULT_size() static int validate_SDBQUERYRESULT_size()
{ {
unsigned char buffer[SDBQUERYRESULT_EXPECTED_SIZE * 2]; unsigned char buffer[SDBQUERYRESULT_EXPECTED_SIZE_VISTA * 2];
WCHAR path[MAX_PATH]; WCHAR path[MAX_PATH];
HSDB hsdb; size_t n;
memset(buffer, 0xab, sizeof(buffer)); memset(buffer, 0xab, sizeof(buffer));
hsdb = pSdbInitDatabase(SDB_DATABASE_MAIN_SHIM, NULL);
if (hsdb)
{
GetModuleFileNameW(NULL, path, MAX_PATH); GetModuleFileNameW(NULL, path, MAX_PATH);
pSdbGetMatchingExe(hsdb, path, NULL, NULL, 0, (SDBQUERYRESULT*)buffer); pSdbGetMatchingExe(NULL, path, NULL, NULL, 0, (SDBQUERYRESULT*)buffer);
pSdbReleaseDatabase(hsdb); if (buffer[0] == 0xab)
if (buffer[0] == buffer[1] && buffer[1] == 0xab)
{ {
trace("SdbGetMatchingExe didnt do anything, cannot determine SDBQUERYRESULT size\n"); trace("SdbGetMatchingExe didnt do anything, cannot determine SDBQUERYRESULT size\n");
return 1; return 0;
}
return buffer[SDBQUERYRESULT_EXPECTED_SIZE] == 0xab && buffer[SDBQUERYRESULT_EXPECTED_SIZE-1] != 0xab;
} }
if (buffer[SDBQUERYRESULT_EXPECTED_SIZE_2k3] == 0xab && buffer[SDBQUERYRESULT_EXPECTED_SIZE_2k3-1] != 0xab)
{
return 1; return 1;
} }
if (buffer[SDBQUERYRESULT_EXPECTED_SIZE_VISTA] == 0xab && buffer[SDBQUERYRESULT_EXPECTED_SIZE_VISTA-1] != 0xab)
{
return 2;
}
for (n = 0; n < _countof(buffer); ++n)
{
if (buffer[n] != 0xab)
{
trace("Unknown size: %i\n", n);
break;
}
}
return 0;
}
START_TEST(db) 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("SHIM_DEBUG_LEVEL", "4");
//SetEnvironmentVariable("SHIMENG_DEBUG_LEVEL", "4"); //SetEnvironmentVariable("SHIMENG_DEBUG_LEVEL", "4");
//SetEnvironmentVariable("DEBUGCHANNEL", "+apphelp"); //SetEnvironmentVariable("DEBUGCHANNEL", "+apphelp");
silence_debug_output();
hdll = LoadLibraryA("apphelp.dll"); hdll = LoadLibraryA("apphelp.dll");
pSdbTagToString = (void *) GetProcAddress(hdll, "SdbTagToString");
pSdbOpenDatabase = (void *) GetProcAddress(hdll, "SdbOpenDatabase"); /* We detect the apphelp version that is loaded, instead of the os we are running on.
pSdbCreateDatabase = (void *) GetProcAddress(hdll, "SdbCreateDatabase"); This allows for easier testing multiple versions of the dll */
pSdbGetDatabaseVersion = (void *) GetProcAddress(hdll, "SdbGetDatabaseVersion"); g_WinVersion = get_module_version(hdll);
pSdbCloseDatabase = (void *) GetProcAddress(hdll, "SdbCloseDatabase"); trace("Apphelp version: 0x%x\n", g_WinVersion);
pSdbCloseDatabaseWrite = (void *) GetProcAddress(hdll, "SdbCloseDatabaseWrite");
pSdbGetTagFromTagID = (void *) GetProcAddress(hdll, "SdbGetTagFromTagID"); *(void**)&pSdbTagToString = (void *)GetProcAddress(hdll, "SdbTagToString");
pSdbWriteNULLTag = (void *) GetProcAddress(hdll, "SdbWriteNULLTag"); *(void**)&pSdbOpenDatabase = (void *)GetProcAddress(hdll, "SdbOpenDatabase");
pSdbWriteWORDTag = (void *) GetProcAddress(hdll, "SdbWriteWORDTag"); *(void**)&pSdbCreateDatabase = (void *)GetProcAddress(hdll, "SdbCreateDatabase");
pSdbWriteDWORDTag = (void *) GetProcAddress(hdll, "SdbWriteDWORDTag"); *(void**)&pSdbGetDatabaseVersion = (void *)GetProcAddress(hdll, "SdbGetDatabaseVersion");
pSdbWriteQWORDTag = (void *) GetProcAddress(hdll, "SdbWriteQWORDTag"); *(void**)&pSdbCloseDatabase = (void *)GetProcAddress(hdll, "SdbCloseDatabase");
pSdbWriteBinaryTagFromFile = (void *) GetProcAddress(hdll, "SdbWriteBinaryTagFromFile"); *(void**)&pSdbCloseDatabaseWrite = (void *)GetProcAddress(hdll, "SdbCloseDatabaseWrite");
pSdbWriteStringTag = (void *) GetProcAddress(hdll, "SdbWriteStringTag"); *(void**)&pSdbGetTagFromTagID = (void *)GetProcAddress(hdll, "SdbGetTagFromTagID");
pSdbWriteStringRefTag = (void *) GetProcAddress(hdll, "SdbWriteStringRefTag"); *(void**)&pSdbWriteNULLTag = (void *)GetProcAddress(hdll, "SdbWriteNULLTag");
pSdbBeginWriteListTag = (void *)GetProcAddress(hdll, "SdbBeginWriteListTag"); *(void**)&pSdbWriteWORDTag = (void *)GetProcAddress(hdll, "SdbWriteWORDTag");
pSdbEndWriteListTag = (void *) GetProcAddress(hdll, "SdbEndWriteListTag"); *(void**)&pSdbWriteDWORDTag = (void *)GetProcAddress(hdll, "SdbWriteDWORDTag");
pSdbFindFirstTag = (void *) GetProcAddress(hdll, "SdbFindFirstTag"); *(void**)&pSdbWriteQWORDTag = (void *)GetProcAddress(hdll, "SdbWriteQWORDTag");
pSdbFindNextTag = (void *) GetProcAddress(hdll, "SdbFindNextTag"); *(void**)&pSdbWriteBinaryTagFromFile = (void *)GetProcAddress(hdll, "SdbWriteBinaryTagFromFile");
pSdbReadWORDTag = (void *) GetProcAddress(hdll, "SdbReadWORDTag"); *(void**)&pSdbWriteStringTag = (void *)GetProcAddress(hdll, "SdbWriteStringTag");
pSdbReadDWORDTag = (void *) GetProcAddress(hdll, "SdbReadDWORDTag"); *(void**)&pSdbWriteStringRefTag = (void *)GetProcAddress(hdll, "SdbWriteStringRefTag");
pSdbReadQWORDTag = (void *) GetProcAddress(hdll, "SdbReadQWORDTag"); *(void**)&pSdbBeginWriteListTag = (void *)GetProcAddress(hdll, "SdbBeginWriteListTag");
pSdbReadBinaryTag = (void *) GetProcAddress(hdll, "SdbReadBinaryTag"); *(void**)&pSdbEndWriteListTag = (void *)GetProcAddress(hdll, "SdbEndWriteListTag");
pSdbReadStringTag = (void *) GetProcAddress(hdll, "SdbReadStringTag"); *(void**)&pSdbFindFirstTag = (void *)GetProcAddress(hdll, "SdbFindFirstTag");
pSdbGetTagDataSize = (void *) GetProcAddress(hdll, "SdbGetTagDataSize"); *(void**)&pSdbFindNextTag = (void *)GetProcAddress(hdll, "SdbFindNextTag");
pSdbGetBinaryTagData = (void *) GetProcAddress(hdll, "SdbGetBinaryTagData"); *(void**)&pSdbFindFirstNamedTag = (void *)GetProcAddress(hdll, "SdbFindFirstNamedTag");
pSdbGetStringTagPtr = (void *) GetProcAddress(hdll, "SdbGetStringTagPtr"); *(void**)&pSdbReadWORDTag = (void *)GetProcAddress(hdll, "SdbReadWORDTag");
pSdbGetFirstChild = (void *) GetProcAddress(hdll, "SdbGetFirstChild"); *(void**)&pSdbReadDWORDTag = (void *)GetProcAddress(hdll, "SdbReadDWORDTag");
pSdbGetNextChild = (void *) GetProcAddress(hdll, "SdbGetNextChild"); *(void**)&pSdbReadQWORDTag = (void *)GetProcAddress(hdll, "SdbReadQWORDTag");
pSdbGetDatabaseID = (void *) GetProcAddress(hdll, "SdbGetDatabaseID"); *(void**)&pSdbReadBinaryTag = (void *)GetProcAddress(hdll, "SdbReadBinaryTag");
pSdbGUIDToString = (void *) GetProcAddress(hdll, "SdbGUIDToString"); *(void**)&pSdbReadStringTag = (void *)GetProcAddress(hdll, "SdbReadStringTag");
pSdbInitDatabase = (void *) GetProcAddress(hdll, "SdbInitDatabase"); *(void**)&pSdbGetTagDataSize = (void *)GetProcAddress(hdll, "SdbGetTagDataSize");
pSdbReleaseDatabase = (void *) GetProcAddress(hdll, "SdbReleaseDatabase"); *(void**)&pSdbGetBinaryTagData = (void *)GetProcAddress(hdll, "SdbGetBinaryTagData");
pSdbGetMatchingExe = (void *) GetProcAddress(hdll, "SdbGetMatchingExe"); *(void**)&pSdbGetStringTagPtr = (void *)GetProcAddress(hdll, "SdbGetStringTagPtr");
pSdbTagRefToTagID = (void *) GetProcAddress(hdll, "SdbTagRefToTagID"); *(void**)&pSdbGetFirstChild = (void *)GetProcAddress(hdll, "SdbGetFirstChild");
pSdbMakeIndexKeyFromString = (void *) GetProcAddress(hdll, "SdbMakeIndexKeyFromString"); *(void**)&pSdbGetNextChild = (void *)GetProcAddress(hdll, "SdbGetNextChild");
*(void**)&pSdbGetDatabaseID = (void *)GetProcAddress(hdll, "SdbGetDatabaseID");
*(void**)&pSdbGUIDToString = (void *)GetProcAddress(hdll, "SdbGUIDToString");
*(void**)&pSdbInitDatabase = (void *)GetProcAddress(hdll, "SdbInitDatabase");
*(void**)&pSdbReleaseDatabase = (void *)GetProcAddress(hdll, "SdbReleaseDatabase");
*(void**)&pSdbGetMatchingExe = (void *)GetProcAddress(hdll, "SdbGetMatchingExe");
*(void**)&pSdbTagRefToTagID = (void *)GetProcAddress(hdll, "SdbTagRefToTagID");
*(void**)&pSdbTagIDToTagRef = (void *)GetProcAddress(hdll, "SdbTagIDToTagRef");
*(void**)&pSdbMakeIndexKeyFromString = (void *)GetProcAddress(hdll, "SdbMakeIndexKeyFromString");
*(void**)&pSdbGetLayerTagRef = (void *)GetProcAddress(hdll, "SdbGetLayerTagRef");
test_Sdb(); test_Sdb();
test_write_ex(); test_write_ex();
test_stringtable(); test_stringtable();
test_CheckDatabaseManually(); test_CheckDatabaseManually();
if (validate_SDBQUERYRESULT_size()) switch (validate_SDBQUERYRESULT_size())
test_MatchApplications(); {
else case 1:
test_MatchApplications<SDBQUERYRESULT_2k3>();
break;
case 2:
test_MatchApplications<SDBQUERYRESULT>();
break;
default:
skip("Skipping tests with SDBQUERYRESULT due to a wrong size reported\n"); skip("Skipping tests with SDBQUERYRESULT due to a wrong size reported\n");
break;
}
test_TagRef(); test_TagRef();
skip("test_SecondaryDB()\n"); skip("test_SecondaryDB()\n");
test_IndexKeyFromString(); test_IndexKeyFromString();