ReactOS 0.4.15-dev-5664-g3bf4ef6
env.c
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 showing shim artifacts in the environment
5 * COPYRIGHT: Copyright 2016,2017 Mark Jansen (mark.jansen@reactos.org)
6 */
7
8#include <ntstatus.h>
9#define WIN32_NO_STATUS
10#include <windows.h>
11#include <shlwapi.h>
12#include <winnt.h>
13#include <userenv.h>
14#ifdef __REACTOS__
15#include <ntndk.h>
16#else
17#include <winternl.h>
18#endif
19#include <winerror.h>
20#include <stdio.h>
21
22#include "wine/test.h"
23
24#include <pseh/pseh2.h>
25
26#include "apphelp_apitest.h"
27
28typedef void* HSDB;
29typedef void* PDB;
30typedef DWORD TAGREF;
31typedef WORD TAG;
32
33
34
36
39void (WINAPI *pSdbReleaseDatabase)(HSDB hsdb);
40BOOL (WINAPI *pSdbTagRefToTagID)(HSDB hsdb, TAGREF trWhich, PDB* ppdb, TAGID* ptiWhich);
41TAG (WINAPI *pSdbGetTagFromTagID)(PDB pdb, TAGID tiWhich);
42TAGREF (WINAPI *pSdbGetLayerTagRef)(HSDB hsdb, LPCWSTR layerName);
43
44
45/* TODO: Investigate ApphelpCheckRunApp, for some reason there is not AppCompatData generated... */
46
50
54
55
58DWORD (WINAPI *pSdbGetAppCompatDataSize)(PVOID pData);
59
60
64static const SDBQUERYRESULT_VISTA empty_result = { { 0 } };
65static const SDBQUERYRESULT_VISTA almost_empty = { { 0 }, { 0 }, { 0 }, 0, 0, 0, 0, { 0 }, SHIMREG_DISABLE_LAYER, 0 };
66
67
68#define SHIMDATA_MAGIC 0xAC0DEDAB
69#define MAX_LAYER_LENGTH 256
70
71
72typedef struct ShimData_Win2k3
73{
77
85
86
87
88typedef struct ShimData_Win7
89{
95 DWORD unknown; // 0x14c
97
98typedef struct ShimData_Win10_v1
99{
106 char padding1[0x200];
107 char padding2[0x404]; // Contains some data at the start
113 char padding4[120];
115
116typedef struct ShimData_Win10_v2
117{
124 char padding1[0x200];
125 char padding2[0x2ae + 0x54 + 0x2a + 0x16 + 0x16];
131 char padding4[76];
133
135{
138
139 char spacing1[60];
140
143
144 char spacing2[444];
145
149
150
151C_ASSERT(sizeof(ShimData_Win2k3) == 392);
152C_ASSERT(sizeof(ShimData_Win7) == 1500);
155
160
165
169
173
174
175
176#define SDB_DATABASE_MAIN_SHIM 0x80030000
177
178#define SDBGMEF_IGNORE_ENVIRONMENT 0x1
179
180
182{
189
190
192{
193 SIZE_T dwRead;
194 if (ReadProcessMemory(proc, address, target, size, &dwRead))
195 {
196 ok(dwRead == size, "Expected to read %u bytes, got %lu\n", size, dwRead);
197 return dwRead == size;
198 }
199 ok(0, "RPM failed with %u\n", GetLastError());
200 return FALSE;
201}
202
204{
206 ULONG sizeOut = 0;
208 ok(NT_SUCCESS(status), "Expected NtQI to succeed, but failed with: %x\n", status);
209 memset(info, 0, sizeof(*info));
210 if (NT_SUCCESS(status))
211 {
212 PEB peb = { 0 };
213 if (readproc(proc, pbi.PebBaseAddress, &peb, sizeof(peb)))
214 {
215 MEMORY_BASIC_INFORMATION mbi = { 0 };
216 SIZE_T dwRead;
217
218 info->AppCompatFlags = peb.AppCompatFlags;
219 info->AppCompatFlagsUser = peb.AppCompatFlagsUser;
220 info->AppCompatInfo = peb.AppCompatInfo;
221 if (peb.pShimData == NULL)
222 return TRUE;
223
224 dwRead = VirtualQueryEx(proc, (LPCVOID)peb.pShimData, &mbi, sizeof(mbi));
225 ok(dwRead == sizeof(mbi), "Expected VQE to return %u, got %lu\n", sizeof(mbi), dwRead);
226 if (dwRead == sizeof(mbi) || peb.pShimData == NULL)
227 {
228 info->ShimDataSize = mbi.RegionSize;
229 info->pShimData = malloc(mbi.RegionSize);
230 if (readproc(proc, peb.pShimData, info->pShimData, mbi.RegionSize))
231 return TRUE;
232 free(info->pShimData);
233 info->pShimData = NULL;
234 }
235 }
236 }
237 return FALSE;
238}
239
240static HANDLE create_proc(BOOL suspended)
241{
242 static char proc_name[MAX_PATH] = { 0 };
243 STARTUPINFOA si = {sizeof(si)};
245 BOOL res;
246 if (!proc_name[0])
247 {
248 GetModuleFileNameA(NULL, proc_name, MAX_PATH);
249 }
250
251 res = CreateProcessA(NULL, proc_name, NULL, NULL, TRUE, suspended ? CREATE_SUSPENDED : 0, NULL, NULL, &si, &pi);
252 if (!res)
253 return NULL;
254 CloseHandle(pi.hThread);
255 return pi.hProcess;
256}
257
258static void create_environ(const char* layers[], size_t num)
259{
260 char buf[256] = { 0 };
261 size_t n;
262 for (n = 0; n < num; ++n)
263 {
264 if (n)
265 strcat(buf, " ");
266 strcat(buf, layers[n]);
267 }
268 SetEnvironmentVariableA("__COMPAT_LAYER", buf);
269}
270
271static void ValidateShim(TAGREF trLayer, const char* name)
272{
273 HSDB hsdb = pSdbInitDatabase(SDB_DATABASE_MAIN_SHIM, NULL);
274 ok(hsdb != NULL, "Expected a valid handle\n");
275 if (hsdb)
276 {
277 PDB pdb = NULL;
278 TAGID tagid = 0xdeadbeef;
279 WCHAR nameW[256] = { 0 };
280 BOOL ret;
281
283
284 ret = pSdbTagRefToTagID(hsdb, trLayer, &pdb, &tagid);
285 ok(ret == TRUE, "Expected pSdbTagRefToTagID to succeed\n");
286 if (ret)
287 {
288 TAG tag;
289 ok(pdb != NULL, "Expected pdb to be a valid pointer\n");
290 ok(tagid != 0 && tagid != 0xdeadbeef, "Expected tagid to be a valid tag id, was: 0x%x\n", tagid);
291 tag = pSdbGetTagFromTagID(pdb, tagid);
292 ok(tag == 0x700b, "Expected tag to be 0x700b, was 0x%x\n", (DWORD)tag);
293 }
294
295 pSdbReleaseDatabase(hsdb);
296 }
297}
298
299
300static void Validate_ShimData_Win2k3(PVOID data, size_t count, const char* layers[])
301{
302 //size_t n;
303 ShimData_Win2k3* pShimData = (ShimData_Win2k3*)data;
304
305 ok(!lstrcmpW(pShimData->szModule, L"ShimEng.dll"), "Expected pShimData->Module to be %s, was %s\n", wine_dbgstr_w(L"ShimEng.dll"), wine_dbgstr_w(pShimData->szModule));
306 ok(pShimData->dwMagic == SHIMDATA_MAGIC, "Expected pShimData->dwMagic to be 0x%x, was 0x%x\n", SHIMDATA_MAGIC, pShimData->dwMagic);
307 ok(pShimData->dwSize == sizeof(ShimData_Win2k3), "Expected pShimData->dwSize to be %u, was %u\n", sizeof(ShimData_Win2k3), pShimData->dwSize);
308 ok(pShimData->dwCustomSDBMap == 1, "Expected pShimData->dwCustomSDBMap to be 1, was %u\n", pShimData->dwCustomSDBMap);
309}
310
311static void Validate_ShimData_Win7(PVOID data, WCHAR szApphelp[256], size_t count, const char* layers[])
312{
313 size_t n;
314 ShimData_Win7* pShimData = (ShimData_Win7*)data;
315
316 ok(!lstrcmpW(pShimData->szModule, szApphelp), "Expected pShimData->Module to be %s, was %s\n",
317 wine_dbgstr_w(szApphelp), wine_dbgstr_w(pShimData->szModule));
318 ok(pShimData->dwMagic == SHIMDATA_MAGIC, "Expected pShimData->dwMagic to be 0x%x, was 0x%x\n",
319 SHIMDATA_MAGIC, pShimData->dwMagic);
320 ok(pShimData->dwSize == sizeof(ShimData_Win7), "Expected pShimData->dwSize to be %u, was %u\n",
321 sizeof(ShimData_Win7), pShimData->dwSize);
322 if (pShimData->Query.dwLayerCount != min(count, SDB_MAX_LAYERS))
323 {
324 char buf[250] = {0};
325 GetEnvironmentVariableA("__COMPAT_LAYER", buf, _countof(buf));
326 trace("At test: %s\n", buf);
327 }
329 "Expected LayerCount to be %u, was %u\n", min(count, SDB_MAX_LAYERS), pShimData->Query.dwLayerCount);
330 for (n = 0; n < SDB_MAX_LAYERS; ++n)
331 {
332 if (n < count)
333 {
334 ok(pShimData->Query.atrLayers[n] != 0, "Expected to find a valid layer in index %u / %u\n", n, count);
335 ValidateShim(pShimData->Query.atrLayers[n], layers[n]);
336 }
337 else
338 ok(pShimData->Query.atrLayers[n] == 0, "Expected to find an empty layer in index %u / %u\n", n, count);
339 }
340 ok(pShimData->unknown == 0x14c, "Expected pShimData->unknown to be 0x14c, was 0x%x\n", pShimData->unknown);
341}
342
343static void Validate_ShimData_Win10_v2(PVOID data, WCHAR szApphelp[256], size_t count, const char* layers[])
344{
345 size_t n;
347
348 if (pShimData->dwMagic != SHIMDATA_MAGIC)
349 {
350 skip("Yet another unknown shimdata variant...\n");
351 return;
352 }
353
354 ok(pShimData->dwSize == sizeof(ShimData_Win10_v2), "Expected pShimData->dwSize to be %u, was %u\n",
355 sizeof(ShimData_Win10_v2), pShimData->dwSize);
356 if (pShimData->Query.dwLayerCount != min(count, SDB_MAX_LAYERS))
357 {
358 char buf[250] = {0};
359 GetEnvironmentVariableA("__COMPAT_LAYER", buf, _countof(buf));
360 trace("At test: %s\n", buf);
361 }
363 "Expected LayerCount to be %u, was %u\n", min(count, SDB_MAX_LAYERS), pShimData->Query.dwLayerCount);
364 for (n = 0; n < SDB_MAX_LAYERS; ++n)
365 {
366 if (n < count)
367 {
368 ok(pShimData->Query.atrLayers[n] != 0, "Expected to find a valid layer in index %u / %u\n", n, count);
369 ValidateShim(pShimData->Query.atrLayers[n], layers[n]);
370 }
371 else
372 ok(pShimData->Query.atrLayers[n] == 0, "Expected to find an empty layer in index %u / %u\n", n, count);
373 }
374
375}
376
377static void Validate_ShimData_Win10(PVOID data, WCHAR szApphelp[256], size_t count, const char* layers[])
378{
379 size_t n;
381
382 if (pShimData->dwMagic != SHIMDATA_MAGIC)
383 {
384 Validate_ShimData_Win10_v2(data, szApphelp, count, layers);
385 return;
386 }
387
388
389 ok(!lstrcmpiW(pShimData->szModule, szApphelp), "Expected pShimData->Module to be %s, was %s\n",
390 wine_dbgstr_w(szApphelp), wine_dbgstr_w(pShimData->szModule));
391 ok(pShimData->dwSize == sizeof(ShimData_Win10_v1), "Expected pShimData->dwSize to be %u, was %u\n",
392 sizeof(ShimData_Win10_v1), pShimData->dwSize);
393 if (pShimData->Query.dwLayerCount != min(count, SDB_MAX_LAYERS))
394 {
395 char buf[250] = {0};
396 GetEnvironmentVariableA("__COMPAT_LAYER", buf, _countof(buf));
397 trace("At test: %s\n", buf);
398 }
400 "Expected LayerCount to be %u, was %u\n", min(count, SDB_MAX_LAYERS), pShimData->Query.dwLayerCount);
401 for (n = 0; n < SDB_MAX_LAYERS; ++n)
402 {
403 if (n < count)
404 {
405 ok(pShimData->Query.atrLayers[n] != 0, "Expected to find a valid layer in index %u / %u\n", n, count);
406 ValidateShim(pShimData->Query.atrLayers[n], layers[n]);
407 }
408 else
409 ok(pShimData->Query.atrLayers[n] == 0, "Expected to find an empty layer in index %u / %u\n", n, count);
410 }
411}
412
414{
416 ok(pShimData != NULL, "Expected pShimData\n");
417 if (!pShimData)
418 return;
419
420 if (pShimData->dwMagic != SHIMDATA_MAGIC)
421 {
423 if (pShimData2->dwMagic != SHIMDATA_MAGIC)
424 {
425 skip("Unknown shimdata (win10)\n");
426 return;
427 }
428
429 ok(!lstrcmpiW(pShimData2->szLayer, L""), "Expected pShimData->szLayer to be '', was %s\n", wine_dbgstr_w(pShimData2->szLayer));
430 ok(pShimData2->dwSize == sizeof(ShimData_Win10_v2), "Expected pShimData->dwSize to be %u, was %u\n", sizeof(ShimData_Win10_v2), pShimData2->dwSize);
431 ok(!memcmp(&pShimData2->Query, &empty_result, sizeof(empty_result)), "Expected result to be empty\n");
432 }
433 else
434 {
435 ok(!lstrcmpiW(pShimData->szModule, L""), "Expected pShimData->Module to be '', was %s\n", wine_dbgstr_w(pShimData->szModule));
436 ok(!lstrcmpiW(pShimData->szLayer, L""), "Expected pShimData->szLayer to be '', was %s\n", wine_dbgstr_w(pShimData->szLayer));
437 ok(pShimData->dwSize == sizeof(ShimData_Win10_v1), "Expected pShimData->dwSize to be %u, was %u\n", sizeof(ShimData_Win10_v1), pShimData->dwSize);
438 ok(!memcmp(&pShimData->Query, &empty_result, sizeof(empty_result)), "Expected result to be empty\n");
439 }
440}
441
442static void Test_layers(WCHAR szApphelp[256])
443{
444 static const char* layers[] = {
445 "256Color", "NT4SP5", "DisableNXHideUI", "DisableNXShowUI",
446 "WIN2000SP3", "640X480", /*"DISABLEDWM",*/ "HIGHDPIAWARE",
447 /*"RUNASADMIN",*/ "DISABLETHEMES" /*, "Layer_Win95VersionLie"*/ };
448
449 size_t n;
450 HANDLE proc;
452 BOOL res;
453
454 for (n = 0; n <= (sizeof(layers) / sizeof(layers[0])); ++n)
455 {
456 create_environ(layers, n);
457
462
463 if (!res)
464 {
465 ok(0, "Unable to get process info (%u)!\n", n);
466 continue;
467 }
468
469 if (n == 0)
470 {
471 ok(info.AppCompatFlags.QuadPart == 0, "Expected AppCompatFlags to be 0, was: %s\n", wine_dbgstr_longlong(info.AppCompatFlags.QuadPart));
472 ok(info.AppCompatFlagsUser.QuadPart == 0, "Expected AppCompatFlagsUser to be 0, was: %s\n", wine_dbgstr_longlong(info.AppCompatFlagsUser.QuadPart));
473 ok(info.AppCompatInfo == NULL, "Expected AppCompatInfo to be NULL, was: %p\n", info.AppCompatInfo);
475 {
476 ok(info.pShimData == NULL, "Expected pShimData to be NULL, was: %p\n", info.pShimData);
477 }
478 else
479 {
481 }
482 }
483 else
484 {
485 ok(info.AppCompatFlags.QuadPart == 0, "Expected AppCompatFlags to be 0, was: %s\n", wine_dbgstr_longlong(info.AppCompatFlags.QuadPart));
486 ok(info.AppCompatFlagsUser.QuadPart == 0, "Expected AppCompatFlagsUser to be 0, was: %s\n", wine_dbgstr_longlong(info.AppCompatFlagsUser.QuadPart));
487 ok(info.AppCompatInfo == NULL, "Expected AppCompatInfo to be NULL, was: %p\n", info.AppCompatInfo);
488 ok(info.pShimData != NULL, "Expected pShimData to be valid, was NULL\n");
489 ok(info.ShimDataSize == g_ShimDataSize, "Expected ShimDataSize to be %u, was: %u\n", g_ShimDataSize, info.ShimDataSize);
490 if (info.pShimData)
491 {
493 Validate_ShimData_Win2k3(info.pShimData, n, layers);
494 else if (g_WinVersion < WINVER_WIN10)
495 Validate_ShimData_Win7(info.pShimData, szApphelp, n, layers);
496 else
497 Validate_ShimData_Win10(info.pShimData, szApphelp, n, layers);
498 }
499 }
500 free(info.pShimData);
501 }
502}
503
504
505/*
506[Warn][SdbGetMatchingExe ] __COMPAT_LAYER name cannot exceed 256 characters.
507[Info][SdbpGetPermLayersInternal] Failed to read value info from Key "\Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" Status 0xc0000034
508[Info][SdbpGetPermLayersInternal] Failed to read value info from Key "\REGISTRY\USER\S-1-5-21-4051718696-421402927-393408651-2638\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" Status 0xc0000034
509[Warn][SdbpEnumUserSdb ] Failed to open key "\Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Custom\NotepadReplacer.exe" Status 0xc0000034
510*/
511static void Test_repeatlayer(WCHAR szApphelp[256])
512{
513 static const char* layers[] = {
514 "256Color", "256Color", "256Color", "256Color",
515 "256Color", "256Color", "256Color", "256Color" };
516
517 HANDLE proc;
519 BOOL res;
520
521 SetEnvironmentVariableA("__COMPAT_LAYER", "256Color 256Color 256Color 256Color 256Color 256Color 256Color 256Color");
522
523
528
529 if (res)
530 {
531 ok(info.AppCompatFlags.QuadPart == 0, "Expected AppCompatFlags to be 0, was: %s\n", wine_dbgstr_longlong(info.AppCompatFlags.QuadPart));
532 ok(info.AppCompatFlagsUser.QuadPart == 0, "Expected AppCompatFlagsUser to be 0, was: %s\n", wine_dbgstr_longlong(info.AppCompatFlagsUser.QuadPart));
533 ok(info.AppCompatInfo == 0, "Expected AppCompatInfo to be 0, was: %p\n", info.AppCompatInfo);
534 ok(info.pShimData != NULL, "Expected pShimData to be valid, was NULL\n");
535 ok(info.ShimDataSize == g_ShimDataSize, "Expected ShimDataSize to be %u, was: %u\n", g_ShimDataSize, info.ShimDataSize);
536 if (info.pShimData)
537 {
538 /* Win10 only 'loads' one layer */
540 Validate_ShimData_Win2k3(info.pShimData, SDB_MAX_LAYERS, layers);
541 else if (g_WinVersion < WINVER_WIN10)
542 Validate_ShimData_Win7(info.pShimData, szApphelp, SDB_MAX_LAYERS, layers);
543 else
544 Validate_ShimData_Win10(info.pShimData, szApphelp, 1, layers);
545 }
546 }
547 else
548 {
549 ok(0, "Unable to get process info!\n");
550 }
551
552}
553
554
555TAGREF find_layer(const char* szLayerStart, const char* szLayerEnd)
556{
557 char layer[100] = { 0 };
558 WCHAR layerW[100] = { 0 };
559 strncpy(layer, szLayerStart, szLayerEnd - szLayerStart);
560
561 if (!g_LayerDB)
562 {
563 g_LayerDB = pSdbInitDatabase(SDB_DATABASE_MAIN_SHIM, 0);
564 }
565
566 mbstowcs(layerW, layer, strlen(layer));
567 return pSdbGetLayerTagRef(g_LayerDB, layerW);
568}
569
571{
572 DWORD dwLayerCount = 0, n;
573 TAGREF atrLayers[SDB_MAX_LAYERS] = { 0 };
574
575 const char* layer = layers, *nextlayer;
576 while (layer && *layer)
577 {
578 nextlayer = strchr(layer, ' ');
579 atrLayers[dwLayerCount++] = find_layer(layer, nextlayer ? nextlayer : (layer + strlen(layer)));
580 layer = nextlayer ? (nextlayer+1) : NULL;
581 }
582
584 {
586 result = NULL;
587
588 winetest_ok(!memcmp(&result2->atrExes, &empty_result.atrExes, sizeof(result2->atrExes)), "Expected atrExes to be empty\n");
589 winetest_ok(!memcmp(&result2->atrLayers[dwLayerCount], &empty_result.atrLayers[dwLayerCount], sizeof(result2->atrLayers) - dwLayerCount * sizeof(result2->atrLayers[0])), "Expected atrLayers[+1] to be empty\n");
590 for (n = 0; n < dwLayerCount; ++n)
591 {
592 winetest_ok(result2->atrLayers[n] == atrLayers[n], "Expected atrLayers[%u] to be %x, was %x\n",
593 n, atrLayers[n], result2->atrLayers[n]);
594 }
595 winetest_ok(result2->dwLayerFlags == 0, "Expected dwLayerFlags to be 0, was %u\n", result2->dwLayerFlags);
596 winetest_ok(result2->trApphelp == 0, "Expected trApphelp to be 0, was %u\n", result2->trApphelp);
597 winetest_ok(result2->dwExeCount == 0, "Expected dwExeCount to be 0, was %u\n", result2->dwExeCount);
598 winetest_ok(result2->dwLayerCount == dwLayerCount, "Expected dwLayerCount to be %u, was %u\n", dwLayerCount, result2->dwLayerCount);
599 winetest_ok(!memcmp(&result2->guidID, &empty_result.guidID, sizeof(result2->guidID)), "Expected guidID to be empty\n");
600 winetest_ok(result2->dwFlags == flags, "Expected dwFlags to be 0x%x, was 0x%x\n", flags, result2->dwFlags);
601 winetest_ok(result2->dwCustomSDBMap == 1, "Expected dwCustomSDBMap to be 1, was %u\n", result2->dwCustomSDBMap);
602 winetest_ok(!memcmp(&result2->rgGuidDB[1], &empty_result.rgGuidDB[1], sizeof(result2->rgGuidDB) - sizeof(result2->rgGuidDB[0])), "Expected rgGuidDB[+1] to be empty\n");
603 }
604 else
605 {
606 winetest_ok(!memcmp(&result->atrExes, &empty_result.atrExes, sizeof(empty_result.atrExes)), "Expected atrExes to be empty\n");
607 winetest_ok(!memcmp(&result->adwExeFlags, &empty_result.adwExeFlags, sizeof(empty_result.adwExeFlags)), "Expected adwExeFlags to be empty\n");
608 winetest_ok(!memcmp(&result->atrLayers[dwLayerCount], &empty_result.atrLayers[dwLayerCount], sizeof(empty_result.atrLayers) - dwLayerCount * sizeof(empty_result.atrLayers[0])), "Expected atrLayers[+1] to be empty\n");
609 for (n = 0; n < dwLayerCount; ++n)
610 {
611 winetest_ok(result->atrLayers[n] == atrLayers[n], "Expected atrLayers[%u] to be %x, was %x\n",
612 n, atrLayers[n], result->atrLayers[n]);
613 }
614 winetest_ok(result->dwLayerFlags == 0, "Expected dwLayerFlags to be 0, was %u\n", result->dwLayerFlags);
615 winetest_ok(result->trApphelp == 0, "Expected trApphelp to be 0, was %u\n", result->trApphelp);
616 winetest_ok(result->dwExeCount == 0, "Expected dwExeCount to be 0, was %u\n", result->dwExeCount);
617 winetest_ok(result->dwLayerCount == dwLayerCount, "Expected dwLayerCount to be %u, was %u\n", dwLayerCount, result->dwLayerCount);
618 winetest_ok(!memcmp(&result->guidID, &empty_result.guidID, sizeof(empty_result.guidID)), "Expected guidID to be empty\n");
619 winetest_ok(result->dwFlags == flags, "Expected dwFlags to be 0x%x, was 0x%x\n", flags, result->dwFlags);
620 winetest_ok(result->dwCustomSDBMap == 1, "Expected dwCustomSDBMap to be 1, was %u\n", result->dwCustomSDBMap);
621 winetest_ok(!memcmp(&result->rgGuidDB[1], &empty_result.rgGuidDB[1], sizeof(empty_result.rgGuidDB) - sizeof(empty_result.rgGuidDB[0])), "Expected rgGuidDB[+1] to be empty\n");
622 }
623}
624
625static void Test_Shimdata(SDBQUERYRESULT_VISTA* result, const WCHAR* szLayer)
626{
627 BOOL ret;
628 PVOID pData;
630
631 pData = NULL;
632 dwSize = 0;
633 ret = pSdbPackAppCompatData(g_LayerDB, result, &pData, &dwSize);
634 ok(ret == TRUE, "Expected ret to be TRUE\n");
635
636 if (pData)
637 {
638 ShimData_Win2k3* pWin2k3;
639 ShimData_Win7* pWin7;
640 ShimData_Win10_v1* pWin10;
641 ShimData_Win10_v2* pWin10_v2;
642 SDBQUERYRESULT_VISTA result2 = { { 0 } };
643
644 DWORD res = pSdbGetAppCompatDataSize(pData);
645 ok_int(dwSize, res);
646 switch(dwSize)
647 {
648 case sizeof(ShimData_Win2k3):
649 pWin2k3 = (ShimData_Win2k3*)pData;
650 ok_hex(pWin2k3->dwMagic, SHIMDATA_MAGIC);
651 ok_int(pWin2k3->dwSize, dwSize);
652 ok(pWin2k3->dwCustomSDBMap == 1, "Expected pWin2k3->dwCustomSDBMap to equal 1, was %u for %s\n", pWin2k3->dwCustomSDBMap, wine_dbgstr_w(szLayer));
653 //ok(!memcmp(&pWin2k3->Query, result, sizeof(SDBQUERYRESULT_2k3)), "Expected pWin2k3->Query to equal result\n");
654 //ok_wstr(pWin7->szLayer, szLayer);
655 break;
656 case sizeof(ShimData_Win7):
657 pWin7 = (ShimData_Win7*)pData;
659 ok_int(pWin7->dwSize, dwSize);
660 ok(!memcmp(&pWin7->Query, result, sizeof(*result)), "Expected pWin7->Query to equal result\n");
661 ok_wstr(pWin7->szLayer, szLayer);
662 break;
663 case sizeof(ShimData_Win10_v1):
664 pWin10 = (ShimData_Win10_v1*)pData;
665 ok_hex(pWin10->dwMagic, SHIMDATA_MAGIC);
666 ok_int(pWin10->dwSize, dwSize);
667 ok(!memcmp(&pWin10->Query, result, sizeof(*result)), "Expected pWin10->Query to equal result\n");
668 ok_wstr(pWin10->szLayerEnv, szLayer);
669 ok_wstr(pWin10->szLayer, L"");
670 break;
671 case sizeof(ShimData_Win10_v2):
672 pWin10_v2 = (ShimData_Win10_v2*)pData;
673 ok_hex(pWin10_v2->dwMagic, SHIMDATA_MAGIC);
674 ok_int(pWin10_v2->dwSize, dwSize);
675 ok(!memcmp(&pWin10_v2->Query, result, sizeof(*result)), "Expected pWin10->Query to equal result\n");
676 ok_wstr(pWin10_v2->szLayerEnv, szLayer);
677 ok_wstr(pWin10_v2->szLayer, L"");
678 break;
679 default:
680 skip("Unknown size %d\n", dwSize);
681 break;
682 }
683
684 ret = pSdbUnpackAppCompatData(g_LayerDB, NULL, pData, &result2);
685 ok(ret == TRUE, "Expected ret to be TRUE\n");
686 /* TODO: For some reason 2k3 does not seem to output the database GUIDs,
687 investigate when we have support for multible db's! */
688 if (dwSize == sizeof(ShimData_Win2k3))
689 {
691 SDBQUERYRESULT_2k3* output = (SDBQUERYRESULT_2k3*)&result2;
692 const GUID rgGuidDB0 = {0x11111111, 0x1111, 0x1111, {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}};
693
694 // Check expected data.
695 ok(input->dwLayerCount == 1,
696 "Expected input->dwLayerCount to be 1, was %u for %s\n",
697 input->dwLayerCount, wine_dbgstr_w(szLayer));
698 ok(input->dwCustomSDBMap == 1,
699 "Expected input->dwCustomSDBMap to be 1, was %u for %s\n",
700 input->dwCustomSDBMap, wine_dbgstr_w(szLayer));
701 ok(IsEqualGUID(&input->rgGuidDB[0], &rgGuidDB0),
702 "Expected input->rgGuidDB[0] to be %s, was %s for %s\n",
703 wine_dbgstr_guid(&rgGuidDB0), wine_dbgstr_guid(&input->rgGuidDB[0]), wine_dbgstr_w(szLayer));
704
705 // Check missing data.
706 ok(output->dwLayerCount == 0,
707 "Expected output->dwLayerCount to be 0, was %u for %s\n",
708 output->dwLayerCount, wine_dbgstr_w(szLayer));
709 ok(output->dwCustomSDBMap == 0,
710 "Expected output->dwCustomSDBMap to be 0, was %u for %s\n",
711 output->dwCustomSDBMap, wine_dbgstr_w(szLayer));
712 ok(IsEqualGUID(&output->rgGuidDB[0], &empty_result.rgGuidDB[0]),
713 "Expected output->rgGuidDB[0] to be empty, was %s for %s\n",
714 wine_dbgstr_guid(&output->rgGuidDB[0]), wine_dbgstr_w(szLayer));
715
716 // Fake it for now, so the memcmp works.
717 output->dwLayerCount = input->dwLayerCount;
718 output->dwCustomSDBMap = input->dwCustomSDBMap;
719 output->rgGuidDB[0] = input->rgGuidDB[0];
720 }
721 ok(!memcmp(&result2, result, sizeof(*result)), "Expected result2 to equal result for %s\n", wine_dbgstr_w(szLayer));
722
724 }
725}
726
727
728#define expect_layeronly (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : expect_layeronly_imp
729
730
731static void Test_GetMatchingExe(void)
732{
733 BOOL ret;
734 SDBQUERYRESULT_VISTA result = { { 0 } };
735 WCHAR self[MAX_PATH];
736 DWORD flags = (g_WinVersion < WINVER_VISTA) ? 0 : ((g_WinVersion < WINVER_WIN10) ? 1 : 0x21);
737
739 SetEnvironmentVariableA("__COMPAT_LAYER", NULL);
740
741 /* szPath cannot be NULL! */
742 ret = pSdbGetMatchingExe(NULL, L"", NULL, NULL, 0, &result);
743 ok(ret == FALSE, "Expected ret to be FALSE\n");
744 ok(!memcmp(&result, &empty_result, sizeof(empty_result)), "Expected result to be empty\n");
745
747
748 ret = pSdbGetMatchingExe(NULL, self, NULL, NULL, 0, &result);
749 ok(ret == FALSE, "Expected ret to be FALSE\n");
750 ok(!memcmp(&result, &empty_result, sizeof(empty_result)), "Expected result to be empty\n");
751
753 SetEnvironmentVariableA("__COMPAT_LAYER", "Some_invalid_layer_name");
754
755 ret = pSdbGetMatchingExe(NULL, self, NULL, NULL, 0, &result);
756 ok(ret == FALSE, "Expected ret to be FALSE\n");
758 ok(!memcmp(&result, &empty_result, sizeof(empty_result)), "Expected result to be empty\n");
759 else
760 ok(!memcmp(&result, &almost_empty, sizeof(almost_empty)), "Expected result to be almost empty\n");
761
763 SetEnvironmentVariableA("__COMPAT_LAYER", "256Color");
764
765 ret = pSdbGetMatchingExe(NULL, self, NULL, NULL, 0, &result);
766 ok(ret == TRUE, "Expected ret to be TRUE\n");
767 expect_layeronly(&result, "256Color", flags);
768
769 Test_Shimdata(&result, L"256Color");
770
772 SetEnvironmentVariableA("__COMPAT_LAYER", "640X480");
773
774 ret = pSdbGetMatchingExe(NULL, self, NULL, NULL, 0, &result);
775 ok(ret == TRUE, "Expected ret to be TRUE\n");
776 expect_layeronly(&result, "640X480", flags);
777
778 Test_Shimdata(&result, L"640X480");
779
780 /* HIGHDPIAWARE does not exist in 2k3 */
782 {
784 SetEnvironmentVariableA("__COMPAT_LAYER", "HIGHDPIAWARE");
785
786 ret = pSdbGetMatchingExe(NULL, self, NULL, NULL, 0, &result);
787 ok(ret == TRUE, "Expected ret to be TRUE\n");
788 expect_layeronly(&result, "HIGHDPIAWARE", flags);
789
790 Test_Shimdata(&result, L"HIGHDPIAWARE");
791
793 SetEnvironmentVariableA("__COMPAT_LAYER", "256Color HIGHDPIAWARE 640X480");
794
795 ret = pSdbGetMatchingExe(NULL, self, NULL, NULL, 0, &result);
796 ok(ret == TRUE, "Expected ret to be TRUE\n");
797 expect_layeronly(&result, "256Color HIGHDPIAWARE 640X480", flags);
798
799 Test_Shimdata(&result, L"256Color HIGHDPIAWARE 640X480");
800 }
801}
802
803
805{
811
813 {
814 skip("Unable to translate %s to Nt path\n", wine_dbgstr_w(ApplicationName));
815 return NULL;
816 }
817
818
830
832
833 if (!NT_SUCCESS(Status))
834 return NULL;
835
836 return FileHandle;
837}
838
839
840#define RESET_CHECKRUNAPP_VARS()\
841 do { \
842 if (AppCompatData && AppCompatData != &Query) { RtlFreeHeap(RtlGetProcessHeap(), 0, AppCompatData); } \
843 ExeType = IMAGE_FILE_MACHINE_I386; \
844 SxsDataSize = FusionFlags = Reason = 0; \
845 SxsData = NULL; \
846 memset(&Query, 0, sizeof(Query)); \
847 AppCompatData = &Query; \
848 AppCompatDataSize = 123456; \
849 } while (0)
850
851#define CHECK_BASICS()\
852 do { \
853 ok_hex(ret, TRUE); \
854 ok(AppCompatData != NULL && AppCompatData != &Query, "Expected the pointer to be valid\n"); \
855 ok_hex(AppCompatDataSize, sizeof(SDBQUERYRESULT_VISTA)); \
856 ok(SxsData == NULL, "Expected the pointer to be NULL\n"); \
857 ok_hex(SxsDataSize, 0); \
858 ok_hex(FusionFlags, 0); \
859 } while (0)
860
861/* W10 does not seem to use the flags at all, so with this macro we can still test it below 10. */
862#define CHECKREASON(value, w10dum) (g_ModuleVersion < WINVER_WIN10 ? value : w10dum)
863
864
868{
869 ULONG64 SomeFlag1 = 0;
870 ULONG SomeFlag2 = 0;
871
872 if (pApphelpCheckRunAppEx_w7)
873 {
874 return pApphelpCheckRunAppEx_w7(FileHandle, NULL, NULL, ApplicationName, Environment, ExeType, Reason,
877 }
878
879 if (pApphelpCheckRunAppEx_w10)
880 {
881 return pApphelpCheckRunAppEx_w10(FileHandle, NULL, NULL, ApplicationName, Environment, NULL, ExeType, Reason,
884 }
885
886 return FALSE;
887}
888
889
890
891
892
893static void Test_ApphelpCheckRunApp(WCHAR szApphelp[256])
894{
895 BOOL ret;
897 WCHAR ApplicationName[MAX_PATH], EmptyName[1] = { 0 };
898 DWORD expect_flags = (g_WinVersion < WINVER_WIN10) ? 1 : 0x21;
899
901 PVOID AppCompatData = NULL, SxsData, DuplicatedEnv, Environment;
902 ULONG AppCompatDataSize, SxsDataSize, FusionFlags;
905 int n;
906 /* this are the only interesting bits (with the exception of '1', which is there to invoke the 'default' case) */
907 const int kTestBits = 0x70503;
908
909 if (!pApphelpCheckRunAppEx_w7 && !pApphelpCheckRunAppEx_w10)
910 {
911 skip("No usable ApphelpCheckRunAppEx\n");
912 return;
913 }
914
916
918 SetEnvironmentVariableA("__COMPAT_LAYER", NULL);
919 if (!CreateEnvironmentBlock(&DuplicatedEnv, NULL, TRUE))
920 DuplicatedEnv = NULL;
921 ok(DuplicatedEnv != NULL, "Invalid env (%u)\n", GetLastError());
922
923 /* First with the environment without __COMPAT_LAYER */
925
927 &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize, &FusionFlags);
928
929 CHECK_BASICS();
930 ok_hex(Reason, CHECKREASON(0x30000, 0));
931 ok(!memcmp(AppCompatData, &empty_result, sizeof(empty_result)), "Expected result to be empty\n");
932
933 /* We need this to be set for tests later on. */
934 SetEnvironmentVariableA("__COMPAT_LAYER", "256Color");
935
937 {
938 /* Showing that when an environment is passed in, that is used instead of the current.
939 In Win10 this behavior is no longer observed */
940
942
944 &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize, &FusionFlags);
945
946 CHECK_BASICS();
947 ok_hex(Reason, CHECKREASON(0x30000, 0));
948 ok(!memcmp(AppCompatData, &empty_result, sizeof(empty_result)), "Expected result to be empty\n");
949 }
950
951 for (n = 0; n < 32; ++n)
952 {
953 ULONG ExpectedReason;
954 if (!(kTestBits & (1<<n)))
955 continue;
957 ExpectedReason = Reason = (1 << n);
959 &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize, &FusionFlags);
960
961 CHECK_BASICS();
962 if (ExpectedReason == 2)
963 ExpectedReason = 2;
964 else if (ExpectedReason == 0x100)
965 ExpectedReason = 0x30000;
966 else
967 ExpectedReason |= 0x30000;
968 ok_hex(Reason, CHECKREASON(ExpectedReason, (1 << n)));
969 ok(!memcmp(AppCompatData, &empty_result, sizeof(empty_result)), "Expected result to be empty\n");
970 }
971
973 {
974 /* Now, using a NULL env, showing that the current environment is used.
975 W10 does no longer do this, so we skip this test here. */
977
979
981 &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize, &FusionFlags);
982
983 CHECK_BASICS();
984 ok_hex(Reason, CHECKREASON(0x50000, 0));
985 if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
986 expect_layeronly(AppCompatData, "256Color", expect_flags);
987
988 for (n = 0; n < 32; ++n)
989 {
990 ULONG ExpectedReason;
992 if (!(kTestBits & (1<<n)))
993 continue;
994 ExpectedReason = Reason = (1 << n);
996 &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize, &FusionFlags);
997
998 CHECK_BASICS();
999 if (ExpectedReason == 2)
1000 ExpectedReason = 2;
1001 else if (ExpectedReason == 0x100)
1002 ExpectedReason = 0x50000;
1003 else if (ExpectedReason == 0x400)
1004 ExpectedReason = 0x30400;
1005 else
1006 ExpectedReason |= 0x50000;
1007 ok_hex(Reason, CHECKREASON(ExpectedReason, (1 << n)));
1008 if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
1009 {
1010 if (ExpectedReason != 0x30400)
1011 expect_layeronly(AppCompatData, "256Color", expect_flags);
1012 else
1013 ok(!memcmp(AppCompatData, &empty_result, sizeof(empty_result)), "Expected result to be empty\n");
1014 }
1015 }
1016 }
1017
1018 /* Passing in an environment with __COMPAT_LAYER set */
1020
1022
1024 &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize, &FusionFlags);
1025
1026 CHECK_BASICS();
1027 ok_hex(Reason, CHECKREASON(0x50000, 0));
1028 if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
1029 expect_layeronly(AppCompatData, "256Color", expect_flags);
1030
1031 for (n = 0; n < 32; ++n)
1032 {
1033 ULONG ExpectedReason;
1034 if (!(kTestBits & (1<<n)))
1035 continue;
1037 ExpectedReason = Reason = (1 << n);
1039 &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize, &FusionFlags);
1040
1041 CHECK_BASICS();
1042 if (ExpectedReason == 2)
1043 ExpectedReason = 2;
1044 else if (ExpectedReason == 0x100)
1045 ExpectedReason = 0x50000;
1046 else if (ExpectedReason == 0x400)
1047 ExpectedReason = 0x30400;
1048 else
1049 ExpectedReason |= 0x50000;
1050 ok_hex(Reason, CHECKREASON(ExpectedReason, (1 << n)));
1051 if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
1052 {
1053 if (ExpectedReason != 0x30400 || g_ModuleVersion >= WINVER_WIN10)
1054 expect_layeronly(AppCompatData, "256Color", expect_flags);
1055 else
1056 ok(!memcmp(AppCompatData, &empty_result, sizeof(empty_result)), "Expected result to be empty\n");
1057 }
1058 }
1059
1060 /* NULL file handle still works */
1062
1064 &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize, &FusionFlags);
1065
1066 CHECK_BASICS();
1067 ok_hex(Reason, CHECKREASON(0x50000, 0));
1068 if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
1069 expect_layeronly(AppCompatData, "256Color", expect_flags);
1070
1071 for (n = 0; n < 32; ++n)
1072 {
1073 ULONG ExpectedReason;
1075 if (!(kTestBits & (1<<n)))
1076 continue;
1077 ExpectedReason = Reason = (1 << n);
1079 &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize, &FusionFlags);
1080
1081 CHECK_BASICS();
1082 if (ExpectedReason == 2)
1083 ExpectedReason = 2;
1084 else if (ExpectedReason == 0x100)
1085 ExpectedReason = 0x50000;
1086 else if (ExpectedReason == 0x400)
1087 ExpectedReason = 0x30400;
1088 else
1089 ExpectedReason |= 0x50000;
1090 ok_hex(Reason, CHECKREASON(ExpectedReason, (1 << n)));
1091 if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
1092 {
1093 /* W10 does not use the flags anymore? */
1094 if (ExpectedReason != 0x30400 || g_ModuleVersion >= WINVER_WIN10)
1095 expect_layeronly(AppCompatData, "256Color", expect_flags);
1096 else
1097 ok(!memcmp(AppCompatData, &empty_result, sizeof(empty_result)), "Expected result to be empty\n");
1098 }
1099 }
1100
1101
1102 /* INVALID_HANDLE_VALUE file handle results in failure (according to flags!), but still results in AppCompatData */
1104
1106 &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize, &FusionFlags);
1107
1108 CHECK_BASICS();
1109 ok_hex(Reason, 0);
1110 if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
1111 expect_layeronly(AppCompatData, "256Color", expect_flags);
1112
1113 for (n = 0; n < 32; ++n)
1114 {
1115 ULONG ExpectedReason;
1116 if (!(kTestBits & (1<<n)))
1117 continue;
1119 ExpectedReason = Reason = (1 << n);
1121 &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize, &FusionFlags);
1122
1123 CHECK_BASICS();
1124 if (ExpectedReason == 0x100)
1125 ExpectedReason = 0;
1126 ok_hex(Reason, CHECKREASON(ExpectedReason, (1 << n)));
1127 if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
1128 {
1129 if (ExpectedReason != 0x400 && g_ModuleVersion < WINVER_WIN7)
1130 expect_layeronly(AppCompatData, "256Color", expect_flags);
1131 else
1132 ok(!memcmp(AppCompatData, &empty_result, sizeof(empty_result)), "Expected result to be empty\n");
1133 }
1134 }
1135
1136 /* NULL filename crashes, showing this in the log before going down:
1137[Err ][SdbpGetLongFileName ] Failed to get NT path name for ""
1138[Err ][SdbpCreateSearchDBContext] Unable to parse executable path for "".
1139[Err ][SdbGetMatchingExe ] Failed to create search DB context.
1140*/
1142
1144 &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize, &FusionFlags);
1145
1146 CHECK_BASICS();
1147 ok_hex(Reason, CHECKREASON(0x30000, 0));
1148 if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
1149 ok(!memcmp(AppCompatData, &empty_result, sizeof(empty_result)), "Expected result to be empty\n");
1150
1151 /* 0 ExeType = don't care? */
1153 ExeType = 0;
1154
1156 &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize, &FusionFlags);
1157
1158 CHECK_BASICS();
1159 ok_hex(Reason, CHECKREASON(0x50000, 0));
1160 if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
1161 expect_layeronly(AppCompatData, "256Color", expect_flags);
1162
1163 for (n = 0; n < 32; ++n)
1164 {
1165 ULONG ExpectedReason;
1166 if (!(kTestBits & (1<<n)))
1167 continue;
1169 ExeType = 0;
1170 ExpectedReason = Reason = (1 << n);
1172 &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize, &FusionFlags);
1173
1174 CHECK_BASICS();
1175 if (ExpectedReason == 2)
1176 ExpectedReason = 2;
1177 else if (ExpectedReason == 0x100)
1178 ExpectedReason = 0x50000;
1179 else if (ExpectedReason == 0x400)
1180 ExpectedReason = 0x30400;
1181 else
1182 ExpectedReason |= 0x50000;
1183 ok_hex(Reason, CHECKREASON(ExpectedReason, (1 << n)));
1184 if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
1185 {
1186 if (ExpectedReason != 0x30400 || g_ModuleVersion >= WINVER_WIN10)
1187 expect_layeronly(AppCompatData, "256Color", expect_flags);
1188 else
1189 ok(!memcmp(AppCompatData, &empty_result, sizeof(empty_result)), "Expected result to be empty\n");
1190 }
1191 }
1192
1193
1196
1198 &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize, &FusionFlags);
1199
1200 CHECK_BASICS();
1201 ok_hex(Reason, CHECKREASON(0x50000, 0));
1202 if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
1203 expect_layeronly(AppCompatData, "256Color", expect_flags);
1204
1205 for (n = 0; n < 32; ++n)
1206 {
1207 ULONG ExpectedReason;
1208 if (!(kTestBits & (1<<n)))
1209 continue;
1212 ExpectedReason = Reason = (1 << n);
1214 &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize, &FusionFlags);
1215
1216 CHECK_BASICS();
1217 if (ExpectedReason == 2)
1218 ExpectedReason = 2;
1219 else if (ExpectedReason == 0x100)
1220 ExpectedReason = 0x50000;
1221 else if (ExpectedReason == 0x400)
1222 ExpectedReason = 0x30400;
1223 else
1224 ExpectedReason |= 0x50000;
1225 ok_hex(Reason, CHECKREASON(ExpectedReason, (1 << n)));
1226 if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
1227 {
1228 if (ExpectedReason != 0x30400 || g_ModuleVersion >= WINVER_WIN10)
1229 expect_layeronly(AppCompatData, "256Color", expect_flags);
1230 else
1231 ok(!memcmp(AppCompatData, &empty_result, sizeof(empty_result)), "Expected result to be empty\n");
1232 }
1233 }
1234
1235
1236 if (AppCompatData && AppCompatData != &Query)
1237 RtlFreeHeap(RtlGetProcessHeap(), 0, AppCompatData);
1238
1240 DestroyEnvironmentBlock(DuplicatedEnv);
1242}
1243
1244
1246{
1247 WCHAR szApphelp[MAX_PATH];
1248 ShimData_QueryOffset QueryOffset;
1249 DWORD ShimDataType;
1250 NTSTATUS ExceptionStatus = STATUS_SUCCESS;
1251
1252 //SetEnvironmentVariable("SHIM_DEBUG_LEVEL", "127");
1253 //SetEnvironmentVariable("SHIMENG_DEBUG_LEVEL", "127");
1254
1256
1257 hdll = LoadLibraryA("apphelp.dll");
1258
1259
1260
1263 trace("Detected host: 0x%x, module: 0x%x\n", g_WinVersion, g_ModuleVersion);
1264
1265 GetModuleFileNameW(hdll, szApphelp, _countof(szApphelp));
1266
1267
1268 pSdbGetMatchingExe = (void*)GetProcAddress(hdll, "SdbGetMatchingExe");
1269 pSdbInitDatabase = (void*)GetProcAddress(hdll, "SdbInitDatabase");
1270 pSdbReleaseDatabase = (void*)GetProcAddress(hdll, "SdbReleaseDatabase");
1271 pSdbTagRefToTagID = (void*)GetProcAddress(hdll, "SdbTagRefToTagID");
1272 pSdbGetTagFromTagID = (void*)GetProcAddress(hdll, "SdbGetTagFromTagID");
1273 pSdbGetLayerTagRef = (void*)GetProcAddress(hdll, "SdbGetLayerTagRef");
1274
1275 switch (g_ModuleVersion)
1276 {
1277 case WINVER_WIN7:
1278 pApphelpCheckRunAppEx_w7 = (void*)GetProcAddress(hdll, "ApphelpCheckRunAppEx");
1279 break;
1280 case WINVER_WIN10:
1281 pApphelpCheckRunAppEx_w10 = (void*)GetProcAddress(hdll, "ApphelpCheckRunAppEx");
1282 break;
1283 default:
1284 skip("Unknown apphelp.dll version %x, cannot determine which ApphelpCheckRunApp(Ex) function to use\n", g_ModuleVersion);
1285 break;
1286 }
1287
1288 pSdbPackAppCompatData = (void*)GetProcAddress(hdll, "SdbPackAppCompatData");
1289 pSdbUnpackAppCompatData = (void*)GetProcAddress(hdll, "SdbUnpackAppCompatData");
1290 pSdbGetAppCompatDataSize = (void*)GetProcAddress(hdll, "SdbGetAppCompatDataSize");
1291
1292
1293 memset(&QueryOffset, 0, sizeof(QueryOffset));
1294 QueryOffset.dwMagic_2k3 = QueryOffset.dwMagic_7_10 = QueryOffset.dwMagic_10_v2 = SHIMDATA_MAGIC;
1295 QueryOffset.dwSize_2k3 = 1;
1296 QueryOffset.dwSize_7_10 = 2;
1297 QueryOffset.dwSize_10_v2 = 3;
1298
1299 g_ShimDataSize = g_WinVersion < WINVER_WIN10 ? 4096 : 8192;
1300 _SEH2_TRY
1301 {
1302 ShimDataType = pSdbGetAppCompatDataSize(&QueryOffset);
1303 }
1305 {
1306 ExceptionStatus = _SEH2_GetExceptionCode();
1307 }
1308 _SEH2_END;
1309
1310 ok(ExceptionStatus == STATUS_SUCCESS, "Exception 0x%08x, expected 0x%08x\n", ExceptionStatus, STATUS_SUCCESS);
1311 if (ExceptionStatus != STATUS_SUCCESS)
1312 {
1313 skip("SdbGetAppCompatDataSize not functional\n");
1314 return;
1315 }
1316
1317 /* New version of Win10.. */
1318 if (g_WinVersion == WINVER_WIN10 && ShimDataType == 3)
1319 g_ShimDataSize = 4096;
1320
1322 {
1323 Test_layers(szApphelp);
1324 Test_repeatlayer(szApphelp);
1325 }
1326 else
1327 {
1328 skip("Tests requiring process launch, reported OS version (0x%x) does not match apphelp version (0x%x)\n", g_WinVersion, g_ModuleVersion);
1329 }
1330
1331 {
1333 }
1334
1335 Test_ApphelpCheckRunApp(szApphelp);
1336 if (g_LayerDB)
1337 pSdbReleaseDatabase(g_LayerDB);
1338}
1339
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define SDB_MAX_LAYERS
Definition: apphelp.h:47
#define SHIMREG_DISABLE_LAYER
Definition: apphelp.h:55
#define SDB_MAX_SDBS
Definition: apphelp.h:45
DWORD get_host_winver(void)
Definition: data.c:796
#define WINVER_WIN10
#define WINVER_2003
DWORD get_module_version(HMODULE mod)
Definition: data.c:811
#define SDB_MAX_EXES_2k3
void silence_debug_output(void)
Definition: data.c:841
DWORD TAGREF
DWORD TAGID
static DWORD g_WinVersion
#define WINVER_WIN7
#define WINVER_VISTA
#define ok_hex(expression, result)
Definition: atltest.h:94
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define ok_wstr(x, y)
Definition: atltest.h:130
#define START_TEST(x)
Definition: atltest.h:75
#define ok_int(expression, result)
Definition: atltest.h:134
LONG NTSTATUS
Definition: precomp.h:26
static const WCHAR nameW[]
Definition: main.c:46
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
BOOL Query(LPCTSTR *ServiceArgs, DWORD ArgCount, BOOL bExtended)
Definition: query.c:292
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
static PDB pdb
Definition: db.cpp:172
DWORD dwLayerCount
Definition: db.cpp:875
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp:170
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#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
#define CloseHandle
Definition: compat.h:739
#define ReadProcessMemory(a, b, c, d, e)
Definition: compat.h:758
#define GetProcessHeap()
Definition: compat.h:736
#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 GetEnvironmentVariableA(x, y, z)
Definition: compat.h:754
#define FILE_SHARE_READ
Definition: compat.h:136
BOOL WINAPI FreeEnvironmentStringsW(IN LPWSTR EnvironmentStrings)
Definition: environ.c:389
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableA(IN LPCSTR lpName, IN LPCSTR lpValue)
Definition: environ.c:218
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
DWORD WINAPI GetModuleFileNameA(HINSTANCE hModule, LPSTR lpFilename, DWORD nSize)
Definition: loader.c:539
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4742
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1532
BOOL WINAPI DestroyEnvironmentBlock(IN LPVOID lpEnvironment)
Definition: environment.c:727
BOOL WINAPI CreateEnvironmentBlock(OUT LPVOID *lpEnvironment, IN HANDLE hToken, IN BOOL bInherit)
Definition: environment.c:505
struct _FileName FileName
Definition: fatprocs.h:896
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
Status
Definition: gdiplustypes.h:25
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLuint res
Definition: glext.h:9613
GLuint address
Definition: glext.h:9393
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLbitfield flags
Definition: glext.h:7161
GLenum GLuint GLint GLint layer
Definition: glext.h:7007
GLuint GLuint num
Definition: glext.h:9618
GLenum GLenum GLenum input
Definition: glext.h:9031
GLuint64EXT * result
Definition: glext.h:11304
GLenum target
Definition: glext.h:7315
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
size_t __cdecl mbstowcs(_Out_writes_opt_z_(_MaxCount) wchar_t *_Dest, _In_z_ const char *_Source, _In_ size_t _MaxCount)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
@ ProcessBasicInformation
Definition: winternl.h:394
#define C_ASSERT(e)
Definition: intsafe.h:73
#define wine_dbgstr_w
Definition: kernel32.h:34
unsigned int * PULONG
Definition: retypes.h:1
unsigned int ULONG
Definition: retypes.h:1
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
unsigned __int64 * PULONG64
Definition: imports.h:198
unsigned __int64 ULONG64
Definition: imports.h:198
static DWORD g_ModuleVersion
Definition: env.c:63
static void Test_layers(WCHAR szApphelp[256])
Definition: env.c:442
PVOID PVOID PWCHAR PVOID USHORT PULONG PVOID PULONG PVOID PULONG PULONG PULONG64 PULONG SomeFlag2
Definition: env.c:49
#define SDB_DATABASE_MAIN_SHIM
Definition: env.c:176
HANDLE xOpenFile(WCHAR *ApplicationName)
Definition: env.c:804
#define SHIMDATA_MAGIC
Definition: env.c:68
#define CHECKREASON(value, w10dum)
Definition: env.c:862
static void Test_ApphelpCheckRunApp(WCHAR szApphelp[256])
Definition: env.c:893
LPCWSTR LPCWSTR LPCWSTR DWORD PSDBQUERYRESULT_VISTA pQueryResult
Definition: env.c:37
static HMODULE hdll
Definition: env.c:35
PVOID PVOID PWCHAR PVOID USHORT ExeType
Definition: env.c:47
LPCWSTR pszImageName
Definition: env.c:57
static BOOL get_shiminfo(HANDLE proc, test_RemoteShimInfo *info)
Definition: env.c:203
static void expect_layeronly_imp(SDBQUERYRESULT_VISTA *result, const char *layers, DWORD flags)
Definition: env.c:570
static void ValidateShim(TAGREF trLayer, const char *name)
Definition: env.c:271
static void Validate_ShimData_Win2k3(PVOID data, size_t count, const char *layers[])
Definition: env.c:300
static void Test_GetMatchingExe(void)
Definition: env.c:731
void * PDB
Definition: env.c:29
PVOID PVOID PWCHAR PVOID USHORT PULONG Reason
Definition: env.c:47
TAGREF PDB TAGID * ptiWhich
Definition: env.c:40
TAGREF PDB * ppdb
Definition: env.c:40
LPCWSTR layerName
Definition: env.c:42
PVOID PVOID Unk2
Definition: env.c:47
static BOOL call_ApphelpCheckRunApp(HANDLE FileHandle, PWCHAR ApplicationName, PVOID Environment, USHORT ExeType, PULONG Reason, PVOID *SdbQueryAppCompatData, PULONG SdbQueryAppCompatDataSize, PVOID *SxsData, PULONG SxsDataSize, PULONG FusionFlags)
Definition: env.c:865
PVOID PVOID PWCHAR PVOID USHORT PULONG PVOID * SdbQueryAppCompatData
Definition: env.c:48
PVOID PVOID PWCHAR PVOID USHORT PULONG PVOID PULONG PVOID PULONG SxsDataSize
Definition: env.c:48
PVOID PVOID PWCHAR PVOID USHORT PULONG PVOID PULONG PVOID PULONG PULONG PULONG64 SomeFlag1
Definition: env.c:49
PVOID Unk1
Definition: env.c:47
PVOID PVOID PWCHAR PVOID USHORT PULONG PVOID PULONG PVOID * SxsData
Definition: env.c:48
static void Validate_ShimData_Win10(PVOID data, WCHAR szApphelp[256], size_t count, const char *layers[])
Definition: env.c:377
#define CHECK_BASICS()
Definition: env.c:851
DWORD TAGREF
Definition: env.c:30
#define expect_layeronly
Definition: env.c:728
PSDBQUERYRESULT_VISTA PVOID * ppData
Definition: env.c:56
LPCWSTR szPath
Definition: env.c:37
LPCWSTR LPCWSTR szModuleName
Definition: env.c:37
static const SDBQUERYRESULT_VISTA empty_result
Definition: env.c:64
static void Test_Shimdata(SDBQUERYRESULT_VISTA *result, const WCHAR *szLayer)
Definition: env.c:625
static void Validate_EmptyShimData_Win10(PVOID data)
Definition: env.c:413
static HANDLE create_proc(BOOL suspended)
Definition: env.c:240
PVOID PVOID PWCHAR PVOID USHORT PULONG PVOID PULONG PVOID PULONG PULONG FusionFlags
Definition: env.c:49
PVOID PVOID PWCHAR PVOID Environment
Definition: env.c:47
static void create_environ(const char *layers[], size_t num)
Definition: env.c:258
static const SDBQUERYRESULT_VISTA almost_empty
Definition: env.c:65
PVOID PVOID PWCHAR PVOID PVOID Unk3
Definition: env.c:51
static void Validate_ShimData_Win10_v2(PVOID data, WCHAR szApphelp[256], size_t count, const char *layers[])
Definition: env.c:343
PVOID PVOID PWCHAR PVOID USHORT PULONG PVOID PULONG SdbQueryAppCompatDataSize
Definition: env.c:48
LPCWSTR PVOID pData
Definition: env.c:57
LPCWSTR LPCWSTR LPCWSTR pszEnvironment
Definition: env.c:37
WORD TAG
Definition: env.c:31
#define MAX_LAYER_LENGTH
Definition: env.c:69
LPCWSTR LPCWSTR LPCWSTR DWORD dwFlags
Definition: env.c:37
void * HSDB
Definition: env.c:28
static DWORD g_ShimDataSize
Definition: env.c:62
LPCWSTR pszDatabasePath
Definition: env.c:38
static HSDB g_LayerDB
Definition: env.c:61
TAGREF trWhich
Definition: env.c:40
static BOOL readproc(HANDLE proc, LPVOID address, PVOID target, DWORD size)
Definition: env.c:191
PVOID PVOID PWCHAR ApplicationName
Definition: env.c:47
static void Test_repeatlayer(WCHAR szApphelp[256])
Definition: env.c:511
static void Validate_ShimData_Win7(PVOID data, WCHAR szApphelp[256], size_t count, const char *layers[])
Definition: env.c:311
TAGID tiWhich
Definition: env.c:41
#define RESET_CHECKRUNAPP_VARS()
Definition: env.c:840
TAGREF find_layer(const char *szLayerStart, const char *szLayerEnd)
Definition: env.c:555
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
static refpint_t pi[]
Definition: server.c:96
#define min(a, b)
Definition: monoChain.cc:55
NTSYSAPI BOOLEAN NTAPI RtlDosPathNameToNtPathName_U(_In_opt_z_ PCWSTR DosPathName, _Out_ PUNICODE_STRING NtPathName, _Out_opt_ PCWSTR *NtFileNamePart, _Out_opt_ PRTL_RELATIVE_NAME_U DirectoryInfo)
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3952
#define BOOL
Definition: nt_native.h:43
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_READ_DATA
Definition: nt_native.h:628
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define FILE_EXECUTE
Definition: nt_native.h:642
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define DWORD
Definition: nt_native.h:44
#define IMAGE_FILE_MACHINE_POWERPCFP
Definition: ntimage.h:28
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 HANDLE proc()
Definition: pdb.c:34
unsigned short USHORT
Definition: pedump.c:61
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define offsetof(TYPE, MEMBER)
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:197
void __winetest_cdecl winetest_ok(int condition, const char *msg,...)
#define memset(x, y, z)
Definition: compat.h:39
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _countof(array)
Definition: sndvol32.h:68
DWORD dwMagic_7_10
Definition: env.c:147
char spacing2[444]
Definition: env.c:144
char spacing1[60]
Definition: env.c:139
DWORD dwMagic_2k3
Definition: env.c:142
DWORD dwSize_2k3
Definition: env.c:141
DWORD dwSize_10_v2
Definition: env.c:136
DWORD dwMagic_10_v2
Definition: env.c:137
DWORD dwSize_7_10
Definition: env.c:146
DWORD unk3
Definition: env.c:109
DWORD dwSize
Definition: env.c:101
WCHAR unk4[MAX_LAYER_LENGTH]
Definition: env.c:112
WCHAR processname[MAX_PATH]
Definition: env.c:110
DWORD dwMagic
Definition: env.c:102
DWORD unk1
Definition: env.c:103
char padding4[120]
Definition: env.c:113
DWORD unk2
Definition: env.c:108
char padding1[0x200]
Definition: env.c:106
SDBQUERYRESULT_VISTA Query
Definition: env.c:104
WCHAR szLayer[MAX_LAYER_LENGTH]
Definition: env.c:105
char padding2[0x404]
Definition: env.c:107
WCHAR szLayerEnv[MAX_LAYER_LENGTH]
Definition: env.c:111
WCHAR szModule[260]
Definition: env.c:100
char padding2[0x2ae+0x54+0x2a+0x16+0x16]
Definition: env.c:125
SDBQUERYRESULT_VISTA Query
Definition: env.c:122
WCHAR unk5[MAX_LAYER_LENGTH]
Definition: env.c:130
WCHAR szLayerEnv[MAX_LAYER_LENGTH]
Definition: env.c:129
DWORD unk4
Definition: env.c:127
WCHAR processname[MAX_PATH-2]
Definition: env.c:128
WCHAR szLayer[MAX_LAYER_LENGTH]
Definition: env.c:123
DWORD unk3
Definition: env.c:126
char padding1[0x200]
Definition: env.c:124
DWORD dwSize
Definition: env.c:118
char padding4[76]
Definition: env.c:131
DWORD unk1
Definition: env.c:120
DWORD unk2
Definition: env.c:121
DWORD dwMagic
Definition: env.c:119
TAGREF atrLayers[SDB_MAX_LAYERS]
Definition: env.c:79
WCHAR szModule[34]
Definition: env.c:74
DWORD dwCustomSDBMap
Definition: env.c:82
TAGREF atrExes[SDB_MAX_EXES_2k3]
Definition: env.c:78
DWORD dwMagic
Definition: env.c:76
DWORD dwUnk0
Definition: env.c:80
DWORD dwUnk1
Definition: env.c:81
DWORD dwSize
Definition: env.c:75
GUID rgGuidDB[SDB_MAX_SDBS]
Definition: env.c:83
DWORD dwMagic
Definition: env.c:92
SDBQUERYRESULT_VISTA Query
Definition: env.c:93
DWORD dwSize
Definition: env.c:91
WCHAR szModule[260]
Definition: env.c:90
WCHAR szLayer[MAX_LAYER_LENGTH]
Definition: env.c:94
DWORD unknown
Definition: env.c:95
ULARGE_INTEGER AppCompatFlagsUser
Definition: winternl.h:350
ULARGE_INTEGER AppCompatFlags
Definition: winternl.h:349
PVOID AppCompatInfo
Definition: winternl.h:352
Definition: apphelp.h:30
Definition: fs_rec.h:143
Definition: name.c:39
Definition: ps.c:97
GUID rgGuidDB[SDB_MAX_SDBS]
TAGREF atrLayers[SDB_MAX_LAYERS]
TAGREF atrExes[SDB_MAX_EXES_2k3]
TAGREF atrLayers[SDB_MAX_LAYERS]
TAGREF atrExes[SDB_MAX_EXES_VISTA]
DWORD adwExeFlags[SDB_MAX_EXES_VISTA]
GUID rgGuidDB[SDB_MAX_SDBS]
Definition: ecma_167.h:138
ULARGE_INTEGER AppCompatFlagsUser
Definition: env.c:184
ULARGE_INTEGER AppCompatFlags
Definition: env.c:183
PVOID pShimData
Definition: env.c:185
PVOID AppCompatInfo
Definition: env.c:187
DWORD ShimDataSize
Definition: env.c:186
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint16_t * PWCHAR
Definition: typedefs.h:56
int ret
SIZE_T NTAPI VirtualQueryEx(IN HANDLE hProcess, IN LPCVOID lpAddress, OUT PMEMORY_BASIC_INFORMATION lpBuffer, IN SIZE_T dwLength)
Definition: virtmem.c:236
DWORD WINAPI GetLastError(void)
Definition: except.c:1040
LPWSTR WINAPI GetEnvironmentStringsW(void)
Definition: environ.c:344
#define CREATE_SUSPENDED
Definition: winbase.h:178
_Inout_ PERBANDINFO * pbi
Definition: winddi.h:3917
CONST void * LPCVOID
Definition: windef.h:191
#define WINAPI
Definition: msvc.h:6
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185