Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376/* * 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 <windef.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 %lu\n", FileName, GetLastError()); return FALSE; } Success = WriteFile(Handle, Data, Size, &dwWritten, NULL); ok(Success == TRUE, "WriteFile failed with %lu\n", GetLastError()); ok(dwWritten == Size, "WriteFile wrote %lu bytes instead of %lu\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 %lu bytes instead of 0l%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);
extern "C"BOOL IsUserAdmin(VOID){ 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%lx)\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%lx)\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%lx)\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%lx)\n", Status); if (!Status) winetest_ok(ValueBuffer == Type, "Expected DatabaseType to be 0x%lx, was 0x%lx\n", Type, ValueBuffer);
Status = key.QueryQWORDValue(L"DatabaseInstallTimeStamp", LargeUIntBuffer.QuadPart); winetest_ok(!Status, "Unable to read DatabaseInstallTimeStamp (0x%lx)\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: %lu)\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);}