mirror of
https://github.com/reactos/reactos.git
synced 2025-05-23 19:14:48 +00:00
[APPHELP_APITEST] Add a test for shim database registration
CORE-11301
This commit is contained in:
parent
12e78a9039
commit
a9bd3da299
3 changed files with 381 additions and 2 deletions
|
@ -1,7 +1,9 @@
|
||||||
project(appcompat)
|
project(appcompat)
|
||||||
add_definitions(-D__ROS_LONG64__ -DWINETEST_USE_DBGSTR_LONGLONG)
|
add_definitions(-D__ROS_LONG64__ -DWINETEST_USE_DBGSTR_LONGLONG -DUNICODE -D_UNICODE)
|
||||||
|
set_cpp(WITH_RUNTIME)
|
||||||
|
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
include_directories(${REACTOS_SOURCE_DIR}/sdk/lib/atl
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
list(APPEND SOURCE
|
list(APPEND SOURCE
|
||||||
apphelp.c
|
apphelp.c
|
||||||
|
@ -9,6 +11,7 @@ list(APPEND SOURCE
|
||||||
db.cpp
|
db.cpp
|
||||||
env.c
|
env.c
|
||||||
layerapi.c
|
layerapi.c
|
||||||
|
register.cpp
|
||||||
testlist.c
|
testlist.c
|
||||||
testdata.rc
|
testdata.rc
|
||||||
testdb.xml)
|
testdb.xml)
|
||||||
|
|
374
modules/rostests/apitests/apphelp/register.cpp
Normal file
374
modules/rostests/apitests/apphelp/register.cpp
Normal file
|
@ -0,0 +1,374 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: apphelp_apitest
|
||||||
|
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||||
|
* PURPOSE: Tests for shim database registration
|
||||||
|
* COPYRIGHT: Copyright 2017-2019 Mark Jansen (mark.jansen@reactos.org)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ntstatus.h>
|
||||||
|
#define WIN32_NO_STATUS
|
||||||
|
#include <windows.h>
|
||||||
|
#include <ntndk.h>
|
||||||
|
#include <atlbase.h>
|
||||||
|
#include <strsafe.h>
|
||||||
|
#include "wine/test.h"
|
||||||
|
|
||||||
|
static const unsigned char rawDB[] =
|
||||||
|
{
|
||||||
|
/* Header: Major, Minor, 'sdbf' */
|
||||||
|
0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x73, 0x64, 0x62, 0x66,
|
||||||
|
|
||||||
|
/* TAG_DATABASE, Length */
|
||||||
|
0x01, 0x70, 0x22, 0x00, 0x00, 0x00,
|
||||||
|
/* TAG_NAME, Value */
|
||||||
|
0x01, 0x60, 0x06, 0x00, 0x00, 0x00,
|
||||||
|
|
||||||
|
/* TAG_DATABASE_ID, Length, Value*/
|
||||||
|
0x07, 0x90, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
/* offset 30 */
|
||||||
|
0xEB, 0x75, 0xDD, 0x79, 0x98, 0xC0, 0x57, 0x47, 0x99, 0x65, 0x9E, 0x83, 0xC4, 0xCA, 0x9D, 0xA4,
|
||||||
|
|
||||||
|
/* TAG_LIBRARY, Length */
|
||||||
|
0x02, 0x70, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
|
||||||
|
/* TAG_STRINGTABLE, Length */
|
||||||
|
0x01, 0x78, 0x0E, 0x00, 0x00, 0x00,
|
||||||
|
/* TAG_STRINGTABLE_ITEM, Length, Value */
|
||||||
|
0x01, 0x88, 0x08, 0x00, 0x00, 0x00,
|
||||||
|
0x49, 0x00, 0x43, 0x00, 0x53, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
static BOOL WriteSdbFile(const WCHAR* FileName, const unsigned char* Data, DWORD Size, const GUID* CustomID)
|
||||||
|
{
|
||||||
|
BOOL Success;
|
||||||
|
DWORD dwWritten;
|
||||||
|
HANDLE Handle = CreateFileW(FileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
|
||||||
|
if (Handle == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
skip("Failed to create temp file %ls, error %u\n", FileName, GetLastError());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
Success = WriteFile(Handle, Data, Size, &dwWritten, NULL);
|
||||||
|
ok(Success == TRUE, "WriteFile failed with %u\n", GetLastError());
|
||||||
|
ok(dwWritten == Size, "WriteFile wrote %u bytes instead of %u\n", dwWritten, Size);
|
||||||
|
if (CustomID)
|
||||||
|
{
|
||||||
|
DWORD dwGuidSize;
|
||||||
|
SetFilePointer(Handle, 30, NULL, FILE_BEGIN);
|
||||||
|
Success = WriteFile(Handle, CustomID, sizeof(*CustomID), &dwGuidSize, NULL);
|
||||||
|
ok(dwGuidSize == sizeof(GUID), "WriteFile wrote %u bytes instead of %u\n", dwGuidSize, sizeof(GUID));
|
||||||
|
}
|
||||||
|
CloseHandle(Handle);
|
||||||
|
return Success && (dwWritten == Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static const GUID GUID_DATABASE_SHIM = { 0x11111111, 0x1111, 0x1111, { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 } };
|
||||||
|
static const GUID GUID_DATABASE_MSI = { 0xd8ff6d16, 0x6a3a, 0x468a, { 0x8b, 0x44, 0x01, 0x71, 0x4d, 0xdc, 0x49, 0xea } };
|
||||||
|
static const GUID GUID_DATABASE_DRIVERS = { 0xf9ab2228, 0x3312, 0x4a73, { 0xb6, 0xf9, 0x93, 0x6d, 0x70, 0xe1, 0x12, 0xef } };
|
||||||
|
static const GUID TEST_DB_GUID = { 0x79dd75eb, 0xc098, 0x4757, { 0x99, 0x65, 0x9e, 0x83, 0xc4, 0xca, 0x9d, 0xa4 } };
|
||||||
|
|
||||||
|
#define SDB_DATABASE_MAIN 0x80000000
|
||||||
|
|
||||||
|
BOOL (WINAPI *pSdbRegisterDatabase)(LPCWSTR pszDatabasePath, DWORD dwDatabaseType);
|
||||||
|
BOOL (WINAPI *pSdbRegisterDatabaseEx)(LPCWSTR pszDatabasePath, DWORD dwDatabaseType, const PULONGLONG pTimeStamp);
|
||||||
|
BOOL (WINAPI *pSdbUnregisterDatabase)(REFGUID pguidDB);
|
||||||
|
|
||||||
|
|
||||||
|
BOOL IsUserAdmin()
|
||||||
|
{
|
||||||
|
BOOL Result;
|
||||||
|
SID_IDENTIFIER_AUTHORITY NtAuthority = { SECURITY_NT_AUTHORITY };
|
||||||
|
PSID AdministratorsGroup;
|
||||||
|
|
||||||
|
Result = AllocateAndInitializeSid(&NtAuthority, 2,
|
||||||
|
SECURITY_BUILTIN_DOMAIN_RID,
|
||||||
|
DOMAIN_ALIAS_RID_ADMINS,
|
||||||
|
0, 0, 0, 0, 0, 0,
|
||||||
|
&AdministratorsGroup);
|
||||||
|
if (Result)
|
||||||
|
{
|
||||||
|
if (!CheckTokenMembership( NULL, AdministratorsGroup, &Result))
|
||||||
|
Result = FALSE;
|
||||||
|
FreeSid(AdministratorsGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD g_QueryFlag = 0xffffffff;
|
||||||
|
static DWORD QueryFlag(void)
|
||||||
|
{
|
||||||
|
if (g_QueryFlag == 0xffffffff)
|
||||||
|
{
|
||||||
|
ULONG_PTR wow64_ptr = 0;
|
||||||
|
NTSTATUS status = NtQueryInformationProcess(NtCurrentProcess(), ProcessWow64Information, &wow64_ptr, sizeof(wow64_ptr), NULL);
|
||||||
|
g_QueryFlag = (NT_SUCCESS(status) && wow64_ptr != 0) ? KEY_WOW64_64KEY : 0;
|
||||||
|
}
|
||||||
|
return g_QueryFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FileTimeNow(ULARGE_INTEGER& Result)
|
||||||
|
{
|
||||||
|
FILETIME TimeBuffer;
|
||||||
|
|
||||||
|
GetSystemTimeAsFileTime(&TimeBuffer);
|
||||||
|
Result.HighPart = TimeBuffer.dwHighDateTime;
|
||||||
|
Result.LowPart = TimeBuffer.dwLowDateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ok_keys_(REFGUID Guid, LPCWSTR DisplayName, LPCWSTR Path, DWORD Type, PULONGLONG TimeStamp)
|
||||||
|
{
|
||||||
|
UNICODE_STRING GuidString;
|
||||||
|
WCHAR StringBuffer[200];
|
||||||
|
DWORD ValueBuffer;
|
||||||
|
ULARGE_INTEGER LargeUIntBuffer;
|
||||||
|
|
||||||
|
CRegKey key;
|
||||||
|
LSTATUS Status = key.Open(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\InstalledSDB", KEY_READ | QueryFlag());
|
||||||
|
winetest_ok(!Status, "Unable to open InstalledSDB key\n");
|
||||||
|
if (Status)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!SUCCEEDED(RtlStringFromGUID(Guid, &GuidString)))
|
||||||
|
{
|
||||||
|
ok(0, "Unable to format guid\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = key.Open(key.m_hKey, GuidString.Buffer, KEY_READ);
|
||||||
|
winetest_ok(!Status, "Unable to open %s key (0x%x)\n", wine_dbgstr_w(GuidString.Buffer), Status);
|
||||||
|
RtlFreeUnicodeString(&GuidString);
|
||||||
|
if (Status)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ULONG nChars = _countof(StringBuffer);
|
||||||
|
Status = key.QueryStringValue(L"DatabaseDescription", StringBuffer, &nChars);
|
||||||
|
winetest_ok(!Status, "Unable to read DatabaseDescription (0x%x)\n", Status);
|
||||||
|
if (!Status)
|
||||||
|
winetest_ok(!wcscmp(DisplayName, StringBuffer), "Expected DatabaseDescription to be %s, was %s\n", wine_dbgstr_w(DisplayName), wine_dbgstr_w(StringBuffer));
|
||||||
|
|
||||||
|
nChars = _countof(StringBuffer);
|
||||||
|
Status = key.QueryStringValue(L"DatabasePath", StringBuffer, &nChars);
|
||||||
|
winetest_ok(!Status, "Unable to read DatabasePath (0x%x)\n", Status);
|
||||||
|
if (!Status)
|
||||||
|
winetest_ok(!wcscmp(Path, StringBuffer), "Expected DatabasePath to be %s, was %s\n", wine_dbgstr_w(Path), wine_dbgstr_w(StringBuffer));
|
||||||
|
|
||||||
|
Status = key.QueryDWORDValue(L"DatabaseType", ValueBuffer);
|
||||||
|
winetest_ok(!Status, "Unable to read DatabaseType (0x%x)\n", Status);
|
||||||
|
if (!Status)
|
||||||
|
winetest_ok(ValueBuffer == Type, "Expected DatabaseType to be 0x%x, was 0x%x\n", Type, ValueBuffer);
|
||||||
|
|
||||||
|
Status = key.QueryQWORDValue(L"DatabaseInstallTimeStamp", LargeUIntBuffer.QuadPart);
|
||||||
|
winetest_ok(!Status, "Unable to read DatabaseInstallTimeStamp (0x%x)\n", Status);
|
||||||
|
if (!Status)
|
||||||
|
{
|
||||||
|
if (TimeStamp)
|
||||||
|
{
|
||||||
|
winetest_ok(LargeUIntBuffer.QuadPart == *TimeStamp, "Expected DatabaseInstallTimeStamp to be %s, was %s\n",
|
||||||
|
wine_dbgstr_longlong(*TimeStamp), wine_dbgstr_longlong(LargeUIntBuffer.QuadPart));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ULARGE_INTEGER CurrentTime;
|
||||||
|
FileTimeNow(CurrentTime);
|
||||||
|
ULONG DiffMS = (ULONG)((CurrentTime.QuadPart - LargeUIntBuffer.QuadPart) / 10000);
|
||||||
|
winetest_ok(DiffMS < 5000 , "Expected DatabaseInstallTimeStamp to be less than 5 seconds before now (was: %u)\n", DiffMS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define ok_keys (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : ok_keys_
|
||||||
|
|
||||||
|
|
||||||
|
START_TEST(register)
|
||||||
|
{
|
||||||
|
WCHAR TempPath[MAX_PATH * 2];
|
||||||
|
BOOL Success;
|
||||||
|
HMODULE hdll;
|
||||||
|
|
||||||
|
SetEnvironmentVariableA("SHIM_DEBUG_LEVEL", "4");
|
||||||
|
SetEnvironmentVariableA("SHIMENG_DEBUG_LEVEL", "4");
|
||||||
|
SetEnvironmentVariableA("DEBUGCHANNEL", "+apphelp");
|
||||||
|
|
||||||
|
//silence_debug_output();
|
||||||
|
hdll = LoadLibraryA("apphelp.dll");
|
||||||
|
|
||||||
|
*(void**)&pSdbRegisterDatabase = (void*)GetProcAddress(hdll, "SdbRegisterDatabase");
|
||||||
|
*(void**)&pSdbRegisterDatabaseEx = (void*)GetProcAddress(hdll, "SdbRegisterDatabaseEx");
|
||||||
|
*(void**)&pSdbUnregisterDatabase = (void*)GetProcAddress(hdll, "SdbUnregisterDatabase");
|
||||||
|
|
||||||
|
if (!pSdbRegisterDatabase || !pSdbRegisterDatabaseEx || !pSdbUnregisterDatabase)
|
||||||
|
{
|
||||||
|
skip("Not all functions present: %p, %p, %p\n", pSdbRegisterDatabase, pSdbRegisterDatabaseEx, pSdbUnregisterDatabase);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [Err ][SdbUnregisterDatabase] Failed to open key "\Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\InstalledSDB\{11111111-1111-1111-1111-111111111111}" Status 0xc0000034 */
|
||||||
|
ok_int(pSdbUnregisterDatabase(GUID_DATABASE_SHIM), FALSE);
|
||||||
|
ok_int(pSdbUnregisterDatabase(GUID_DATABASE_MSI), FALSE);
|
||||||
|
ok_int(pSdbUnregisterDatabase(GUID_DATABASE_DRIVERS), FALSE);
|
||||||
|
|
||||||
|
|
||||||
|
if (!IsUserAdmin())
|
||||||
|
{
|
||||||
|
skip("Not running as admin, unable to install databases!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetTempPathW(_countof(TempPath), TempPath);
|
||||||
|
StringCchCatW(TempPath, _countof(TempPath), L"\\shim_db.sdb");
|
||||||
|
if (!WriteSdbFile(TempPath, rawDB, sizeof(rawDB), NULL))
|
||||||
|
{
|
||||||
|
skip("Cannot write %s\n", wine_dbgstr_w(TempPath));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No Type */
|
||||||
|
Success = pSdbRegisterDatabase(TempPath, 0);
|
||||||
|
ok_int(Success, TRUE);
|
||||||
|
if (Success)
|
||||||
|
{
|
||||||
|
ok_keys(TEST_DB_GUID, L"ICS", TempPath, 0, NULL);
|
||||||
|
Success = pSdbUnregisterDatabase(TEST_DB_GUID);
|
||||||
|
ok_int(Success, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unknown type */
|
||||||
|
Success = pSdbRegisterDatabase(TempPath, 1);
|
||||||
|
ok_int(Success, TRUE);
|
||||||
|
if (Success)
|
||||||
|
{
|
||||||
|
ok_keys(TEST_DB_GUID, L"ICS", TempPath, 1, NULL);
|
||||||
|
Success = pSdbUnregisterDatabase(TEST_DB_GUID);
|
||||||
|
ok_int(Success, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* System type */
|
||||||
|
Success = pSdbRegisterDatabase(TempPath, SDB_DATABASE_MAIN);
|
||||||
|
ok_int(Success, TRUE);
|
||||||
|
if (Success)
|
||||||
|
{
|
||||||
|
ok_keys(TEST_DB_GUID, L"ICS", TempPath, SDB_DATABASE_MAIN, NULL);
|
||||||
|
Success = pSdbUnregisterDatabase(TEST_DB_GUID);
|
||||||
|
ok_int(Success, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No type, null time */
|
||||||
|
Success = pSdbRegisterDatabaseEx(TempPath, 0, NULL);
|
||||||
|
ok_int(Success, TRUE);
|
||||||
|
if (Success)
|
||||||
|
{
|
||||||
|
ok_keys(TEST_DB_GUID, L"ICS", TempPath, 0, NULL);
|
||||||
|
Success = pSdbUnregisterDatabase(TEST_DB_GUID);
|
||||||
|
ok_int(Success, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unknown type, null time */
|
||||||
|
Success = pSdbRegisterDatabaseEx(TempPath, 1, NULL);
|
||||||
|
ok_int(Success, TRUE);
|
||||||
|
if (Success)
|
||||||
|
{
|
||||||
|
ok_keys(TEST_DB_GUID, L"ICS", TempPath, 1, NULL);
|
||||||
|
Success = pSdbUnregisterDatabase(TEST_DB_GUID);
|
||||||
|
ok_int(Success, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* System type, null time */
|
||||||
|
Success = pSdbRegisterDatabaseEx(TempPath, SDB_DATABASE_MAIN, NULL);
|
||||||
|
ok_int(Success, TRUE);
|
||||||
|
if (Success)
|
||||||
|
{
|
||||||
|
ok_keys(TEST_DB_GUID, L"ICS", TempPath, SDB_DATABASE_MAIN, NULL);
|
||||||
|
Success = pSdbUnregisterDatabase(TEST_DB_GUID);
|
||||||
|
ok_int(Success, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
ULARGE_INTEGER Time;
|
||||||
|
FileTimeNow(Time);
|
||||||
|
Time.QuadPart ^= 0xffffffffffffffffll;
|
||||||
|
/* No type, random time */
|
||||||
|
Success = pSdbRegisterDatabaseEx(TempPath, 0, &Time.QuadPart);
|
||||||
|
ok_int(Success, TRUE);
|
||||||
|
if (Success)
|
||||||
|
{
|
||||||
|
ok_keys(TEST_DB_GUID, L"ICS", TempPath, 0, &Time.QuadPart);
|
||||||
|
Success = pSdbUnregisterDatabase(TEST_DB_GUID);
|
||||||
|
ok_int(Success, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unknown type, random time */
|
||||||
|
Success = pSdbRegisterDatabaseEx(TempPath, 1, &Time.QuadPart);
|
||||||
|
ok_int(Success, TRUE);
|
||||||
|
if (Success)
|
||||||
|
{
|
||||||
|
ok_keys(TEST_DB_GUID, L"ICS", TempPath, 1, &Time.QuadPart);
|
||||||
|
Success = pSdbUnregisterDatabase(TEST_DB_GUID);
|
||||||
|
ok_int(Success, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* System type, random time */
|
||||||
|
Success = pSdbRegisterDatabaseEx(TempPath, SDB_DATABASE_MAIN, &Time.QuadPart);
|
||||||
|
ok_int(Success, TRUE);
|
||||||
|
if (Success)
|
||||||
|
{
|
||||||
|
ok_keys(TEST_DB_GUID, L"ICS", TempPath, SDB_DATABASE_MAIN, &Time.QuadPart);
|
||||||
|
Success = pSdbUnregisterDatabase(TEST_DB_GUID);
|
||||||
|
ok_int(Success, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* System reserved ID's */
|
||||||
|
if (!WriteSdbFile(TempPath, rawDB, sizeof(rawDB), &GUID_DATABASE_SHIM))
|
||||||
|
{
|
||||||
|
skip("Cannot write %s\n", wine_dbgstr_w(TempPath));
|
||||||
|
DeleteFileW(TempPath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Success = pSdbRegisterDatabase(TempPath, 0);
|
||||||
|
ok_int(Success, TRUE);
|
||||||
|
if (Success)
|
||||||
|
{
|
||||||
|
ok_keys(GUID_DATABASE_SHIM, L"ICS", TempPath, 0, NULL);
|
||||||
|
Success = pSdbUnregisterDatabase(GUID_DATABASE_SHIM);
|
||||||
|
ok_int(Success, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!WriteSdbFile(TempPath, rawDB, sizeof(rawDB), &GUID_DATABASE_MSI))
|
||||||
|
{
|
||||||
|
skip("Cannot write %s\n", wine_dbgstr_w(TempPath));
|
||||||
|
DeleteFileW(TempPath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Success = pSdbRegisterDatabase(TempPath, 0);
|
||||||
|
ok_int(Success, TRUE);
|
||||||
|
if (Success)
|
||||||
|
{
|
||||||
|
ok_keys(GUID_DATABASE_MSI, L"ICS", TempPath, 0, NULL);
|
||||||
|
Success = pSdbUnregisterDatabase(GUID_DATABASE_MSI);
|
||||||
|
ok_int(Success, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!WriteSdbFile(TempPath, rawDB, sizeof(rawDB), &GUID_DATABASE_DRIVERS))
|
||||||
|
{
|
||||||
|
skip("Cannot write %s\n", wine_dbgstr_w(TempPath));
|
||||||
|
DeleteFileW(TempPath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Success = pSdbRegisterDatabase(TempPath, 0);
|
||||||
|
ok_int(Success, TRUE);
|
||||||
|
if (Success)
|
||||||
|
{
|
||||||
|
ok_keys(GUID_DATABASE_DRIVERS, L"ICS", TempPath, 0, NULL);
|
||||||
|
Success = pSdbUnregisterDatabase(GUID_DATABASE_DRIVERS);
|
||||||
|
ok_int(Success, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteFileW(TempPath);
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ extern void func_apphelp(void);
|
||||||
extern void func_db(void);
|
extern void func_db(void);
|
||||||
extern void func_env(void);
|
extern void func_env(void);
|
||||||
extern void func_layerapi(void);
|
extern void func_layerapi(void);
|
||||||
|
extern void func_register(void);
|
||||||
|
|
||||||
const struct test winetest_testlist[] =
|
const struct test winetest_testlist[] =
|
||||||
{
|
{
|
||||||
|
@ -14,5 +15,6 @@ const struct test winetest_testlist[] =
|
||||||
{ "db", func_db },
|
{ "db", func_db },
|
||||||
{ "env", func_env },
|
{ "env", func_env },
|
||||||
{ "layerapi", func_layerapi },
|
{ "layerapi", func_layerapi },
|
||||||
|
{ "register", func_register },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue