ReactOS 0.4.15-dev-6679-g945ee4b
register.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: apphelp_apitest
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Tests for shim database registration
5 * COPYRIGHT: Copyright 2017-2019 Mark Jansen (mark.jansen@reactos.org)
6 */
7
8#include <ntstatus.h>
9#define WIN32_NO_STATUS
10#include <windef.h>
11#include <ntndk.h>
12#include <atlbase.h>
13#include <strsafe.h>
14#include "wine/test.h"
15
16static const unsigned char rawDB[] =
17{
18 /* Header: Major, Minor, 'sdbf' */
19 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x73, 0x64, 0x62, 0x66,
20
21 /* TAG_DATABASE, Length */
22 0x01, 0x70, 0x22, 0x00, 0x00, 0x00,
23 /* TAG_NAME, Value */
24 0x01, 0x60, 0x06, 0x00, 0x00, 0x00,
25
26 /* TAG_DATABASE_ID, Length, Value*/
27 0x07, 0x90, 0x10, 0x00, 0x00, 0x00,
28 /* offset 30 */
29 0xEB, 0x75, 0xDD, 0x79, 0x98, 0xC0, 0x57, 0x47, 0x99, 0x65, 0x9E, 0x83, 0xC4, 0xCA, 0x9D, 0xA4,
30
31 /* TAG_LIBRARY, Length */
32 0x02, 0x70, 0x00, 0x00, 0x00, 0x00,
33
34 /* TAG_STRINGTABLE, Length */
35 0x01, 0x78, 0x0E, 0x00, 0x00, 0x00,
36 /* TAG_STRINGTABLE_ITEM, Length, Value */
37 0x01, 0x88, 0x08, 0x00, 0x00, 0x00,
38 0x49, 0x00, 0x43, 0x00, 0x53, 0x00, 0x00, 0x00
39};
40
41static BOOL WriteSdbFile(const WCHAR* FileName, const unsigned char* Data, DWORD Size, const GUID* CustomID)
42{
44 DWORD dwWritten;
46
48 {
49 skip("Failed to create temp file %ls, error %u\n", FileName, GetLastError());
50 return FALSE;
51 }
52 Success = WriteFile(Handle, Data, Size, &dwWritten, NULL);
53 ok(Success == TRUE, "WriteFile failed with %u\n", GetLastError());
54 ok(dwWritten == Size, "WriteFile wrote %u bytes instead of %u\n", dwWritten, Size);
55 if (CustomID)
56 {
57 DWORD dwGuidSize;
59 Success = WriteFile(Handle, CustomID, sizeof(*CustomID), &dwGuidSize, NULL);
60 ok(dwGuidSize == sizeof(GUID), "WriteFile wrote %u bytes instead of %u\n", dwGuidSize, sizeof(GUID));
61 }
63 return Success && (dwWritten == Size);
64}
65
66
67
68static const GUID GUID_DATABASE_SHIM = { 0x11111111, 0x1111, 0x1111, { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 } };
69static const GUID GUID_DATABASE_MSI = { 0xd8ff6d16, 0x6a3a, 0x468a, { 0x8b, 0x44, 0x01, 0x71, 0x4d, 0xdc, 0x49, 0xea } };
70static const GUID GUID_DATABASE_DRIVERS = { 0xf9ab2228, 0x3312, 0x4a73, { 0xb6, 0xf9, 0x93, 0x6d, 0x70, 0xe1, 0x12, 0xef } };
71static const GUID TEST_DB_GUID = { 0x79dd75eb, 0xc098, 0x4757, { 0x99, 0x65, 0x9e, 0x83, 0xc4, 0xca, 0x9d, 0xa4 } };
72
73#define SDB_DATABASE_MAIN 0x80000000
74
77BOOL (WINAPI *pSdbUnregisterDatabase)(REFGUID pguidDB);
78
79
81{
84 PSID AdministratorsGroup;
85
89 0, 0, 0, 0, 0, 0,
90 &AdministratorsGroup);
91 if (Result)
92 {
93 if (!CheckTokenMembership( NULL, AdministratorsGroup, &Result))
94 Result = FALSE;
95 FreeSid(AdministratorsGroup);
96 }
97
98 return Result;
99}
100
101static DWORD g_QueryFlag = 0xffffffff;
102static DWORD QueryFlag(void)
103{
104 if (g_QueryFlag == 0xffffffff)
105 {
106 ULONG_PTR wow64_ptr = 0;
108 g_QueryFlag = (NT_SUCCESS(status) && wow64_ptr != 0) ? KEY_WOW64_64KEY : 0;
109 }
110 return g_QueryFlag;
111}
112
114{
115 FILETIME TimeBuffer;
116
117 GetSystemTimeAsFileTime(&TimeBuffer);
118 Result.HighPart = TimeBuffer.dwHighDateTime;
119 Result.LowPart = TimeBuffer.dwLowDateTime;
120}
121
123{
125 WCHAR StringBuffer[200];
126 DWORD ValueBuffer;
127 ULARGE_INTEGER LargeUIntBuffer;
128
129 CRegKey key;
130 LSTATUS Status = key.Open(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\InstalledSDB", KEY_READ | QueryFlag());
131 winetest_ok(!Status, "Unable to open InstalledSDB key\n");
132 if (Status)
133 return;
134
136 {
137 ok(0, "Unable to format guid\n");
138 return;
139 }
140
141 Status = key.Open(key.m_hKey, GuidString.Buffer, KEY_READ);
142 winetest_ok(!Status, "Unable to open %s key (0x%x)\n", wine_dbgstr_w(GuidString.Buffer), Status);
144 if (Status)
145 return;
146
147 ULONG nChars = _countof(StringBuffer);
148 Status = key.QueryStringValue(L"DatabaseDescription", StringBuffer, &nChars);
149 winetest_ok(!Status, "Unable to read DatabaseDescription (0x%x)\n", Status);
150 if (!Status)
151 winetest_ok(!wcscmp(DisplayName, StringBuffer), "Expected DatabaseDescription to be %s, was %s\n", wine_dbgstr_w(DisplayName), wine_dbgstr_w(StringBuffer));
152
153 nChars = _countof(StringBuffer);
154 Status = key.QueryStringValue(L"DatabasePath", StringBuffer, &nChars);
155 winetest_ok(!Status, "Unable to read DatabasePath (0x%x)\n", Status);
156 if (!Status)
157 winetest_ok(!wcscmp(Path, StringBuffer), "Expected DatabasePath to be %s, was %s\n", wine_dbgstr_w(Path), wine_dbgstr_w(StringBuffer));
158
159 Status = key.QueryDWORDValue(L"DatabaseType", ValueBuffer);
160 winetest_ok(!Status, "Unable to read DatabaseType (0x%x)\n", Status);
161 if (!Status)
162 winetest_ok(ValueBuffer == Type, "Expected DatabaseType to be 0x%x, was 0x%x\n", Type, ValueBuffer);
163
164 Status = key.QueryQWORDValue(L"DatabaseInstallTimeStamp", LargeUIntBuffer.QuadPart);
165 winetest_ok(!Status, "Unable to read DatabaseInstallTimeStamp (0x%x)\n", Status);
166 if (!Status)
167 {
168 if (TimeStamp)
169 {
170 winetest_ok(LargeUIntBuffer.QuadPart == *TimeStamp, "Expected DatabaseInstallTimeStamp to be %s, was %s\n",
172 }
173 else
174 {
175 ULARGE_INTEGER CurrentTime;
176 FileTimeNow(CurrentTime);
177 ULONG DiffMS = (ULONG)((CurrentTime.QuadPart - LargeUIntBuffer.QuadPart) / 10000);
178 winetest_ok(DiffMS < 5000 , "Expected DatabaseInstallTimeStamp to be less than 5 seconds before now (was: %u)\n", DiffMS);
179 }
180 }
181}
182
183
184#define ok_keys (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : ok_keys_
185
186
187START_TEST(register)
188{
189 WCHAR TempPath[MAX_PATH * 2];
192
193 SetEnvironmentVariableA("SHIM_DEBUG_LEVEL", "4");
194 SetEnvironmentVariableA("SHIMENG_DEBUG_LEVEL", "4");
195 SetEnvironmentVariableA("DEBUGCHANNEL", "+apphelp");
196
197 //silence_debug_output();
198 hdll = LoadLibraryA("apphelp.dll");
199
200 *(void**)&pSdbRegisterDatabase = (void*)GetProcAddress(hdll, "SdbRegisterDatabase");
201 *(void**)&pSdbRegisterDatabaseEx = (void*)GetProcAddress(hdll, "SdbRegisterDatabaseEx");
202 *(void**)&pSdbUnregisterDatabase = (void*)GetProcAddress(hdll, "SdbUnregisterDatabase");
203
204 if (!pSdbRegisterDatabase || !pSdbRegisterDatabaseEx || !pSdbUnregisterDatabase)
205 {
206 skip("Not all functions present: %p, %p, %p\n", pSdbRegisterDatabase, pSdbRegisterDatabaseEx, pSdbUnregisterDatabase);
207 return;
208 }
209
210 /* [Err ][SdbUnregisterDatabase] Failed to open key "\Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\InstalledSDB\{11111111-1111-1111-1111-111111111111}" Status 0xc0000034 */
211 ok_int(pSdbUnregisterDatabase(GUID_DATABASE_SHIM), FALSE);
212 ok_int(pSdbUnregisterDatabase(GUID_DATABASE_MSI), FALSE);
213 ok_int(pSdbUnregisterDatabase(GUID_DATABASE_DRIVERS), FALSE);
214
215
216 if (!IsUserAdmin())
217 {
218 skip("Not running as admin, unable to install databases!\n");
219 return;
220 }
221
222 GetTempPathW(_countof(TempPath), TempPath);
223 StringCchCatW(TempPath, _countof(TempPath), L"\\shim_db.sdb");
224 if (!WriteSdbFile(TempPath, rawDB, sizeof(rawDB), NULL))
225 {
226 skip("Cannot write %s\n", wine_dbgstr_w(TempPath));
227 return;
228 }
229
230 /* No Type */
231 Success = pSdbRegisterDatabase(TempPath, 0);
233 if (Success)
234 {
235 ok_keys(TEST_DB_GUID, L"ICS", TempPath, 0, NULL);
236 Success = pSdbUnregisterDatabase(TEST_DB_GUID);
238 }
239
240 /* Unknown type */
241 Success = pSdbRegisterDatabase(TempPath, 1);
243 if (Success)
244 {
245 ok_keys(TEST_DB_GUID, L"ICS", TempPath, 1, NULL);
246 Success = pSdbUnregisterDatabase(TEST_DB_GUID);
248 }
249
250 /* System type */
251 Success = pSdbRegisterDatabase(TempPath, SDB_DATABASE_MAIN);
253 if (Success)
254 {
255 ok_keys(TEST_DB_GUID, L"ICS", TempPath, SDB_DATABASE_MAIN, NULL);
256 Success = pSdbUnregisterDatabase(TEST_DB_GUID);
258 }
259
260 /* No type, null time */
261 Success = pSdbRegisterDatabaseEx(TempPath, 0, NULL);
263 if (Success)
264 {
265 ok_keys(TEST_DB_GUID, L"ICS", TempPath, 0, NULL);
266 Success = pSdbUnregisterDatabase(TEST_DB_GUID);
268 }
269
270 /* Unknown type, null time */
271 Success = pSdbRegisterDatabaseEx(TempPath, 1, NULL);
273 if (Success)
274 {
275 ok_keys(TEST_DB_GUID, L"ICS", TempPath, 1, NULL);
276 Success = pSdbUnregisterDatabase(TEST_DB_GUID);
278 }
279
280
281 /* System type, null time */
282 Success = pSdbRegisterDatabaseEx(TempPath, SDB_DATABASE_MAIN, NULL);
284 if (Success)
285 {
286 ok_keys(TEST_DB_GUID, L"ICS", TempPath, SDB_DATABASE_MAIN, NULL);
287 Success = pSdbUnregisterDatabase(TEST_DB_GUID);
289 }
290
293 Time.QuadPart ^= 0xffffffffffffffffll;
294 /* No type, random time */
295 Success = pSdbRegisterDatabaseEx(TempPath, 0, &Time.QuadPart);
297 if (Success)
298 {
299 ok_keys(TEST_DB_GUID, L"ICS", TempPath, 0, &Time.QuadPart);
300 Success = pSdbUnregisterDatabase(TEST_DB_GUID);
302 }
303
304 /* Unknown type, random time */
305 Success = pSdbRegisterDatabaseEx(TempPath, 1, &Time.QuadPart);
307 if (Success)
308 {
309 ok_keys(TEST_DB_GUID, L"ICS", TempPath, 1, &Time.QuadPart);
310 Success = pSdbUnregisterDatabase(TEST_DB_GUID);
312 }
313
314 /* System type, random time */
315 Success = pSdbRegisterDatabaseEx(TempPath, SDB_DATABASE_MAIN, &Time.QuadPart);
317 if (Success)
318 {
320 Success = pSdbUnregisterDatabase(TEST_DB_GUID);
322 }
323
324 /* System reserved ID's */
325 if (!WriteSdbFile(TempPath, rawDB, sizeof(rawDB), &GUID_DATABASE_SHIM))
326 {
327 skip("Cannot write %s\n", wine_dbgstr_w(TempPath));
328 DeleteFileW(TempPath);
329 return;
330 }
331
332 Success = pSdbRegisterDatabase(TempPath, 0);
334 if (Success)
335 {
336 ok_keys(GUID_DATABASE_SHIM, L"ICS", TempPath, 0, NULL);
337 Success = pSdbUnregisterDatabase(GUID_DATABASE_SHIM);
339 }
340
341 if (!WriteSdbFile(TempPath, rawDB, sizeof(rawDB), &GUID_DATABASE_MSI))
342 {
343 skip("Cannot write %s\n", wine_dbgstr_w(TempPath));
344 DeleteFileW(TempPath);
345 return;
346 }
347
348 Success = pSdbRegisterDatabase(TempPath, 0);
350 if (Success)
351 {
352 ok_keys(GUID_DATABASE_MSI, L"ICS", TempPath, 0, NULL);
353 Success = pSdbUnregisterDatabase(GUID_DATABASE_MSI);
355 }
356
357 if (!WriteSdbFile(TempPath, rawDB, sizeof(rawDB), &GUID_DATABASE_DRIVERS))
358 {
359 skip("Cannot write %s\n", wine_dbgstr_w(TempPath));
360 DeleteFileW(TempPath);
361 return;
362 }
363
364 Success = pSdbRegisterDatabase(TempPath, 0);
366 if (Success)
367 {
368 ok_keys(GUID_DATABASE_DRIVERS, L"ICS", TempPath, 0, NULL);
369 Success = pSdbUnregisterDatabase(GUID_DATABASE_DRIVERS);
371 }
372
373 DeleteFileW(TempPath);
374}
PRTL_UNICODE_STRING_BUFFER Path
Type
Definition: Type.h:7
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define ok_int(expression, result)
Definition: atltest.h:134
LONG NTSTATUS
Definition: precomp.h:26
static SID_IDENTIFIER_AUTHORITY NtAuthority
Definition: security.c:40
static LSTATUS(WINAPI *pRegDeleteTreeW)(HKEY
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOL WINAPI CheckTokenMembership(IN HANDLE ExistingTokenHandle, IN PSID SidToCheck, OUT PBOOL IsMember)
Definition: token.c:21
BOOL WINAPI AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, BYTE nSubAuthorityCount, DWORD nSubAuthority0, DWORD nSubAuthority1, DWORD nSubAuthority2, DWORD nSubAuthority3, DWORD nSubAuthority4, DWORD nSubAuthority5, DWORD nSubAuthority6, DWORD nSubAuthority7, PSID *pSid)
Definition: security.c:676
PVOID WINAPI FreeSid(PSID pSid)
Definition: security.c:700
#define CloseHandle
Definition: compat.h:739
#define FILE_BEGIN
Definition: compat.h:761
#define SetFilePointer
Definition: compat.h:743
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
#define MAX_PATH
Definition: compat.h:34
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableA(IN LPCSTR lpName, IN LPCSTR lpValue)
Definition: environ.c:218
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2080
VOID WINAPI GetSystemTimeAsFileTime(OUT PFILETIME lpFileTime)
Definition: time.c:128
@ Success
Definition: eventcreate.c:712
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
@ ProcessWow64Information
Definition: winternl.h:396
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define wine_dbgstr_w
Definition: kernel32.h:34
WCHAR StringBuffer[156]
Definition: ldrinit.c:41
#define CREATE_ALWAYS
Definition: disk.h:72
static PWSTR GuidString
Definition: apphelp.c:93
LPCWSTR pszDatabasePath
Definition: env.c:38
static PLARGE_INTEGER Time
Definition: time.c:105
#define BOOL
Definition: nt_native.h:43
#define KEY_READ
Definition: nt_native.h:1023
#define NtCurrentProcess()
Definition: nt_native.h:1657
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define GENERIC_WRITE
Definition: nt_native.h:90
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:383
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:59
#define L(x)
Definition: ntvdm.h:50
static DWORD QueryFlag(void)
Definition: register.cpp:102
#define ok_keys
Definition: register.cpp:184
DWORD dwDatabaseType
Definition: register.cpp:75
DWORD const PULONGLONG pTimeStamp
Definition: register.cpp:76
static void FileTimeNow(ULARGE_INTEGER &Result)
Definition: register.cpp:113
static const GUID TEST_DB_GUID
Definition: register.cpp:71
BOOL IsUserAdmin()
Definition: register.cpp:80
static const GUID GUID_DATABASE_DRIVERS
Definition: register.cpp:70
#define SDB_DATABASE_MAIN
Definition: register.cpp:73
static void ok_keys_(REFGUID Guid, LPCWSTR DisplayName, LPCWSTR Path, DWORD Type, PULONGLONG TimeStamp)
Definition: register.cpp:122
static const GUID GUID_DATABASE_MSI
Definition: register.cpp:69
static const unsigned char rawDB[]
Definition: register.cpp:16
static DWORD g_QueryFlag
Definition: register.cpp:101
static BOOL WriteSdbFile(const WCHAR *FileName, const unsigned char *Data, DWORD Size, const GUID *CustomID)
Definition: register.cpp:41
static const GUID GUID_DATABASE_SHIM
Definition: register.cpp:68
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
void __winetest_cdecl winetest_ok(int condition, const char *msg,...)
static PVOID hdll
Definition: shimdbg.c:126
#define _countof(array)
Definition: sndvol32.h:68
STRSAFEAPI StringCchCatW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:325
DWORD dwHighDateTime
Definition: mapidefs.h:66
DWORD dwLowDateTime
Definition: mapidefs.h:65
Definition: scsiwmi.h:51
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
Definition: copy.c:22
Definition: ps.c:97
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
LONGLONG QuadPart
Definition: typedefs.h:114
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFOBJECT _In_ CONST GUID * Guid
Definition: wdfobject.h:762
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define WINAPI
Definition: msvc.h:6
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46
#define SECURITY_BUILTIN_DOMAIN_RID
Definition: setypes.h:581
#define SECURITY_NT_AUTHORITY
Definition: setypes.h:554
#define DOMAIN_ALIAS_RID_ADMINS
Definition: setypes.h:652
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185