Author: mjansen
Date: Sat Jun 10 20:31:58 2017
New Revision: 74986
URL:
http://svn.reactos.org/svn/reactos?rev=74986&view=rev
Log:
[APPHELP_APITEST] Add tests for ApphelpCheckRunApp[Ex], SdbGetMatchingExe,
Sdb[Un]PackAppCompatData. CORE-13284
Added:
trunk/rostests/apitests/apphelp/env.c (with props)
Modified:
trunk/rostests/apitests/apphelp/CMakeLists.txt
trunk/rostests/apitests/apphelp/apphelp.c
trunk/rostests/apitests/apphelp/apphelp_apitest.h
trunk/rostests/apitests/apphelp/db.cpp
trunk/rostests/apitests/apphelp/testlist.c
Modified: trunk/rostests/apitests/apphelp/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/apphelp/CMakeLis…
==============================================================================
--- trunk/rostests/apitests/apphelp/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/rostests/apitests/apphelp/CMakeLists.txt [iso-8859-1] Sat Jun 10 20:31:58 2017
@@ -5,10 +5,12 @@
apphelp.c
data.c
db.cpp
+ env.c
layerapi.c
testlist.c)
add_executable(apphelp_apitest ${SOURCE})
set_module_type(apphelp_apitest win32cui)
+target_link_libraries(apphelp_apitest ${PSEH_LIB})
add_importlibs(apphelp_apitest advapi32 userenv version shlwapi msvcrt kernel32 ntdll)
add_rostests_file(TARGET apphelp_apitest)
Modified: trunk/rostests/apitests/apphelp/apphelp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/apphelp/apphelp.…
==============================================================================
--- trunk/rostests/apitests/apphelp/apphelp.c [iso-8859-1] (original)
+++ trunk/rostests/apitests/apphelp/apphelp.c [iso-8859-1] Sat Jun 10 20:31:58 2017
@@ -40,11 +40,6 @@
#include "apphelp_apitest.h"
-
-typedef WORD TAG;
-typedef DWORD TAGID;
-typedef DWORD TAGREF;
-typedef UINT64 QWORD;
#define TAG_TYPE_MASK 0xF000
Modified: trunk/rostests/apitests/apphelp/apphelp_apitest.h
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/apphelp/apphelp_…
==============================================================================
--- trunk/rostests/apitests/apphelp/apphelp_apitest.h [iso-8859-1] (original)
+++ trunk/rostests/apitests/apphelp/apphelp_apitest.h [iso-8859-1] Sat Jun 10 20:31:58
2017
@@ -32,6 +32,70 @@
#define WINVER_WIN8 0x0602
#define WINVER_WIN10 0x0a00
+
+typedef WORD TAG;
+typedef DWORD TAGID;
+typedef DWORD TAGREF;
+typedef UINT64 QWORD;
+typedef VOID* PDB;
+typedef VOID* HSDB;
+typedef INT PATH_TYPE;
+
+
+
+#define SDB_MAX_SDBS 16
+#define SDB_MAX_EXES_VISTA 16
+#define SDB_MAX_LAYERS 8
+#define SHIMREG_DISABLE_LAYER (0x00000020)
+
+#define SDBQUERYRESULT_EXPECTED_SIZE_VISTA 456
+
+
+
+typedef struct tagSDBQUERYRESULT_VISTA
+{
+ TAGREF atrExes[SDB_MAX_EXES_VISTA];
+ DWORD adwExeFlags[SDB_MAX_EXES_VISTA];
+ TAGREF atrLayers[SDB_MAX_LAYERS];
+ DWORD dwLayerFlags;
+ TAGREF trApphelp;
+ DWORD dwExeCount;
+ DWORD dwLayerCount;
+ GUID guidID;
+ DWORD dwFlags;
+ DWORD dwCustomSDBMap;
+ GUID rgGuidDB[SDB_MAX_SDBS];
+} SDBQUERYRESULT_VISTA, *PSDBQUERYRESULT_VISTA;
+
+
+#define SDBQUERYRESULT_EXPECTED_SIZE_2k3 344
+
+#define SDB_MAX_EXES_2k3 4
+
+typedef struct tagSDBQUERYRESULT_2k3
+{
+ TAGREF atrExes[SDB_MAX_EXES_2k3];
+ TAGREF atrLayers[SDB_MAX_LAYERS];
+ DWORD dwLayerFlags;
+ TAGREF trApphelp; // probably?
+ DWORD dwExeCount;
+ DWORD dwLayerCount;
+ GUID guidID; // probably?
+ DWORD dwFlags; // probably?
+ DWORD dwCustomSDBMap;
+ GUID rgGuidDB[SDB_MAX_SDBS];
+} SDBQUERYRESULT_2k3, *PSDBQUERYRESULT_2k3;
+
+
+
+
+
+C_ASSERT(sizeof(SDBQUERYRESULT_VISTA) == SDBQUERYRESULT_EXPECTED_SIZE_VISTA);
+C_ASSERT(sizeof(SDBQUERYRESULT_2k3) == SDBQUERYRESULT_EXPECTED_SIZE_2k3);
+
+
+
+
#ifdef __cplusplus
} // extern "C"
#endif
Modified: trunk/rostests/apitests/apphelp/db.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/apphelp/db.cpp?r…
==============================================================================
--- trunk/rostests/apitests/apphelp/db.cpp [iso-8859-1] (original)
+++ trunk/rostests/apitests/apphelp/db.cpp [iso-8859-1] Sat Jun 10 20:31:58 2017
@@ -39,15 +39,6 @@
#include "apphelp_apitest.h"
-
-typedef WORD TAG;
-typedef DWORD TAGID;
-typedef DWORD TAGREF;
-typedef UINT64 QWORD;
-typedef VOID* PDB;
-typedef VOID* HSDB;
-typedef INT PATH_TYPE;
-
#define DOS_PATH 0
#define HID_DATABASE_FULLPATH 2
@@ -138,54 +129,6 @@
#define TAG_DATA_BITS (0x5 | TAG_TYPE_BINARY)
#define TAG_DATABASE_ID (0x7 | TAG_TYPE_BINARY)
-
-#define SDB_MAX_SDBS_VISTA 16
-#define SDB_MAX_EXES_VISTA 16
-#define SDB_MAX_LAYERS_VISTA 8
-
-#define SDBQUERYRESULT_EXPECTED_SIZE_VISTA 456
-
-typedef struct tagSDBQUERYRESULT
-{
- TAGREF atrExes[SDB_MAX_EXES_VISTA];
- DWORD adwExeFlags[SDB_MAX_EXES_VISTA];
- TAGREF atrLayers[SDB_MAX_LAYERS_VISTA];
- DWORD dwLayerFlags;
- TAGREF trApphelp;
- DWORD dwExeCount;
- DWORD dwLayerCount;
- GUID guidID;
- DWORD dwFlags;
- DWORD dwCustomSDBMap;
- GUID rgGuidDB[SDB_MAX_SDBS_VISTA];
-} SDBQUERYRESULT, *PSDBQUERYRESULT;
-
-
-#define SDBQUERYRESULT_EXPECTED_SIZE_2k3 344
-
-#define SDB_MAX_EXES_2k3 4
-#define SDB_MAX_LAYERS_2k3 8
-
-typedef struct tagSDBQUERYRESULT_2k3
-{
- TAGREF atrExes[SDB_MAX_EXES_2k3];
- TAGREF atrLayers[SDB_MAX_LAYERS_2k3];
- DWORD dwLayerFlags;
- TAGREF trApphelp; // probably?
- DWORD dwExeCount;
- DWORD dwLayerCount;
- GUID guidID; // probably?
- DWORD dwFlags; // probably?
- DWORD dwCustomSDBMap;
- GUID rgGuidDB[SDB_MAX_SDBS_VISTA];
-} SDBQUERYRESULT_2k3, *PSDBQUERYRESULT_2k3;
-
-
-
-
-
-C_ASSERT(sizeof(SDBQUERYRESULT) == SDBQUERYRESULT_EXPECTED_SIZE_VISTA);
-C_ASSERT(sizeof(SDBQUERYRESULT_2k3) == SDBQUERYRESULT_EXPECTED_SIZE_2k3);
static HMODULE hdll;
@@ -222,7 +165,7 @@
static BOOL (WINAPI *pSdbGUIDToString)(CONST GUID *, PCWSTR, SIZE_T);
static HSDB (WINAPI *pSdbInitDatabase)(DWORD, LPCWSTR);
static void (WINAPI *pSdbReleaseDatabase)(HSDB);
-static BOOL (WINAPI *pSdbGetMatchingExe)(HSDB hsdb, LPCWSTR path, LPCWSTR module_name,
LPCWSTR env, DWORD flags, PSDBQUERYRESULT result);
+static BOOL (WINAPI *pSdbGetMatchingExe)(HSDB hsdb, LPCWSTR path, LPCWSTR module_name,
LPCWSTR env, DWORD flags, PSDBQUERYRESULT_VISTA result);
static BOOL (WINAPI *pSdbTagRefToTagID)(HSDB hSDB, TAGREF trWhich, PDB *ppdb, TAGID
*ptiWhich);
static BOOL (WINAPI *pSdbTagIDToTagRef)(HSDB hSDB, PDB pdb, TAGID tiWhich, TAGREF
*ptrWhich);
static TAGREF (WINAPI *pSdbGetLayerTagRef)(HSDB hsdb, LPCWSTR layerName);
@@ -1162,7 +1105,7 @@
{
/* First we try without the file at all. */
DeleteFileA(testfile);
- ret = pSdbGetMatchingExe(hsdb, exenameW, NULL, NULL, 0,
(SDBQUERYRESULT*)&query);
+ ret = pSdbGetMatchingExe(hsdb, exenameW, NULL, NULL, 0,
(SDBQUERYRESULT_VISTA*)&query);
ok(ret == 0, "SdbGetMatchingExe should have failed for %d.\n", cur);
/* Now re-try with the correct file */
test_create_file(testfile, "aaaa", 4);
@@ -1185,7 +1128,7 @@
SetEnvironmentVariableA("__COMPAT_LAYER", test_exedata[cur].env_var);
}
- ret = pSdbGetMatchingExe(hsdb, exenameW, NULL, NULL, 0,
(SDBQUERYRESULT*)&query);
+ ret = pSdbGetMatchingExe(hsdb, exenameW, NULL, NULL, 0,
(SDBQUERYRESULT_VISTA*)&query);
ok(ret, "SdbGetMatchingExe should not fail for %d.\n", cur);
exe_count = (test_exedata[cur].env_var == NULL) ? 1 : 0;
@@ -1295,7 +1238,7 @@
if (RtlDosPathNameToNtPathName_U(exenameW, &exenameNT, NULL, NULL))
{
- ret = pSdbGetMatchingExe(hsdb, exenameNT.Buffer, NULL, NULL, 0,
(SDBQUERYRESULT*)&query);
+ ret = pSdbGetMatchingExe(hsdb, exenameNT.Buffer, NULL, NULL, 0,
(SDBQUERYRESULT_VISTA*)&query);
ok(ret, "SdbGetMatchingExe should not fail for %d.\n", cur);
RtlFreeUnicodeString(&exenameNT);
@@ -1594,7 +1537,7 @@
memset(buffer, 0xab, sizeof(buffer));
GetModuleFileNameW(NULL, path, MAX_PATH);
- pSdbGetMatchingExe(NULL, path, NULL, NULL, 0, (SDBQUERYRESULT*)buffer);
+ pSdbGetMatchingExe(NULL, path, NULL, NULL, 0, (SDBQUERYRESULT_VISTA*)buffer);
if (buffer[0] == 0xab)
{
trace("SdbGetMatchingExe didnt do anything, cannot determine SDBQUERYRESULT
size\n");
@@ -1687,7 +1630,7 @@
test_MatchApplications<SDBQUERYRESULT_2k3>();
break;
case 2:
- test_MatchApplications<SDBQUERYRESULT>();
+ test_MatchApplications<SDBQUERYRESULT_VISTA>();
break;
default:
skip("Skipping tests with SDBQUERYRESULT due to a wrong size
reported\n");
Added: trunk/rostests/apitests/apphelp/env.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/apphelp/env.c?re…
==============================================================================
--- trunk/rostests/apitests/apphelp/env.c (added)
+++ trunk/rostests/apitests/apphelp/env.c [iso-8859-1] Sat Jun 10 20:31:58 2017
@@ -0,0 +1,1323 @@
+/*
+ * Copyright 2016, 2017 Mark Jansen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <ntstatus.h>
+#define WIN32_NO_STATUS
+#include <windows.h>
+#include <shlwapi.h>
+#include <winnt.h>
+#include <userenv.h>
+#ifdef __REACTOS__
+#include <ntndk.h>
+#else
+#include <winternl.h>
+#endif
+#include <winerror.h>
+#include <stdio.h>
+
+#include "wine/test.h"
+
+#include "apphelp_apitest.h"
+
+typedef void* HSDB;
+typedef void* PDB;
+typedef DWORD TAGREF;
+typedef WORD TAG;
+
+
+
+static HMODULE hdll;
+
+BOOL(WINAPI *pSdbGetMatchingExe)(HSDB hsdb, LPCWSTR szPath, LPCWSTR szModuleName, LPCWSTR
pszEnvironment, DWORD dwFlags, PSDBQUERYRESULT_VISTA pQueryResult);
+HSDB (WINAPI *pSdbInitDatabase)(DWORD dwFlags, LPCWSTR pszDatabasePath);
+void (WINAPI *pSdbReleaseDatabase)(HSDB hsdb);
+BOOL (WINAPI *pSdbTagRefToTagID)(HSDB hsdb, TAGREF trWhich, PDB* ppdb, TAGID* ptiWhich);
+TAG (WINAPI *pSdbGetTagFromTagID)(PDB pdb, TAGID tiWhich);
+TAGREF (WINAPI *pSdbGetLayerTagRef)(HSDB hsdb, LPCWSTR layerName);
+
+
+/* TODO: Investigate ApphelpCheckRunApp, for some reason there is not AppCompatData
generated... */
+
+BOOL (WINAPI *pApphelpCheckRunAppEx_w7)(HANDLE FileHandle, PVOID Unk1, PVOID Unk2, PWCHAR
ApplicationName, PVOID Environment, USHORT ExeType, PULONG Reason,
+ PVOID* SdbQueryAppCompatData, PULONG
SdbQueryAppCompatDataSize, PVOID* SxsData, PULONG SxsDataSize,
+ PULONG FusionFlags, PULONG64 SomeFlag1, PULONG
SomeFlag2);
+
+BOOL (WINAPI *pApphelpCheckRunAppEx_w10)(HANDLE FileHandle, PVOID Unk1, PVOID Unk2,
PWCHAR ApplicationName, PVOID Environment, PVOID Unk3, USHORT ExeType, PULONG Reason,
+ PVOID* SdbQueryAppCompatData, PULONG
SdbQueryAppCompatDataSize, PVOID* SxsData, PULONG SxsDataSize,
+ PULONG FusionFlags, PULONG64 SomeFlag1, PULONG
SomeFlag2);
+
+
+BOOL (WINAPI *pSdbPackAppCompatData)(HSDB hsdb, PSDBQUERYRESULT_VISTA pQueryResult,
PVOID* ppData, DWORD *dwSize);
+BOOL (WINAPI *pSdbUnpackAppCompatData)(HSDB hsdb, LPCWSTR pszImageName, PVOID pData,
PSDBQUERYRESULT_VISTA pQueryResult);
+DWORD (WINAPI *pSdbGetAppCompatDataSize)(PVOID pData);
+
+
+static HSDB g_LayerDB;
+static DWORD g_ShimDataSize;
+static DWORD g_ModuleVersion;
+static const SDBQUERYRESULT_VISTA empty_result = { { 0 } };
+static const SDBQUERYRESULT_VISTA almost_empty = { { 0 }, { 0 }, { 0 }, 0, 0, 0, 0, { 0
}, SHIMREG_DISABLE_LAYER, 0 };
+
+
+#define SHIMDATA_MAGIC 0xAC0DEDAB
+#define MAX_LAYER_LENGTH 256
+
+
+typedef struct ShimData_Win2k3
+{
+ WCHAR szModule[34];
+ DWORD dwSize;
+ DWORD dwMagic;
+
+ TAGREF atrExes[SDB_MAX_EXES_2k3];
+ TAGREF atrLayers[SDB_MAX_LAYERS];
+ DWORD dwUnk0;
+ DWORD dwUnk1;
+ DWORD dwCustomSDBMap;
+ GUID rgGuidDB[SDB_MAX_SDBS];
+} ShimData_Win2k3;
+
+
+
+typedef struct ShimData_Win7
+{
+ WCHAR szModule[260];
+ DWORD dwSize;
+ DWORD dwMagic;
+ SDBQUERYRESULT_VISTA Query;
+ WCHAR szLayer[MAX_LAYER_LENGTH];
+ DWORD unknown; // 0x14c
+} ShimData_Win7;
+
+typedef struct ShimData_Win10_v1
+{
+ WCHAR szModule[260];
+ DWORD dwSize;
+ DWORD dwMagic;
+ DWORD unk1;
+ SDBQUERYRESULT_VISTA Query;
+ WCHAR szLayer[MAX_LAYER_LENGTH];
+ char padding1[0x200];
+ char padding2[0x404]; // Contains some data at the start
+ DWORD unk2;
+ DWORD unk3;
+ WCHAR processname[MAX_PATH];
+ WCHAR szLayerEnv[MAX_LAYER_LENGTH];
+ WCHAR unk4[MAX_LAYER_LENGTH];
+ char padding4[120];
+} ShimData_Win10_v1;
+
+typedef struct ShimData_Win10_v2
+{
+ DWORD dwSize;
+ DWORD dwMagic;
+ DWORD unk1;
+ DWORD unk2;
+ SDBQUERYRESULT_VISTA Query;
+ WCHAR szLayer[MAX_LAYER_LENGTH];
+ char padding1[0x200];
+ char padding2[0x2ae + 0x54 + 0x2a + 0x16 + 0x16];
+ DWORD unk3;
+ DWORD unk4;
+ WCHAR processname[MAX_PATH-2];
+ WCHAR szLayerEnv[MAX_LAYER_LENGTH];
+ WCHAR unk5[MAX_LAYER_LENGTH];
+ char padding4[76];
+} ShimData_Win10_v2;
+
+typedef struct ShimData_QueryOffset
+{
+ DWORD dwSize_10_v2;
+ DWORD dwMagic_10_v2;
+
+ char spacing1[60];
+
+ DWORD dwSize_2k3;
+ DWORD dwMagic_2k3;
+
+ char spacing2[444];
+
+ DWORD dwSize_7_10;
+ DWORD dwMagic_7_10;
+} ShimData_QueryOffset;
+
+
+C_ASSERT(sizeof(ShimData_Win2k3) == 392);
+C_ASSERT(sizeof(ShimData_Win7) == 1500);
+C_ASSERT(sizeof(ShimData_Win10_v1) == 4712);
+C_ASSERT(sizeof(ShimData_Win10_v2) == 3976);
+
+C_ASSERT(offsetof(ShimData_Win10_v2, dwSize) == 0);
+C_ASSERT(offsetof(ShimData_Win2k3, dwSize) == 68);
+C_ASSERT(offsetof(ShimData_Win7, dwSize) == 520);
+C_ASSERT(offsetof(ShimData_Win10_v1, dwSize) == 520);
+
+C_ASSERT(offsetof(ShimData_Win10_v2, dwMagic) == 4);
+C_ASSERT(offsetof(ShimData_Win2k3, dwMagic) == 72);
+C_ASSERT(offsetof(ShimData_Win7, dwMagic) == 524);
+C_ASSERT(offsetof(ShimData_Win10_v1, dwMagic) == 524);
+
+C_ASSERT(offsetof(ShimData_QueryOffset, dwSize_10_v2) == 0);
+C_ASSERT(offsetof(ShimData_QueryOffset, dwSize_2k3) == 68);
+C_ASSERT(offsetof(ShimData_QueryOffset, dwSize_7_10) == 520);
+
+C_ASSERT(offsetof(ShimData_QueryOffset, dwMagic_10_v2) == 4);
+C_ASSERT(offsetof(ShimData_QueryOffset, dwMagic_2k3) == 72);
+C_ASSERT(offsetof(ShimData_QueryOffset, dwMagic_7_10) == 524);
+
+
+
+#define SDB_DATABASE_MAIN_SHIM 0x80030000
+
+#define SDBGMEF_IGNORE_ENVIRONMENT 0x1
+
+
+typedef struct test_RemoteShimInfo
+{
+ ULARGE_INTEGER AppCompatFlags;
+ ULARGE_INTEGER AppCompatFlagsUser;
+ PVOID pShimData;
+ DWORD ShimDataSize;
+ PVOID AppCompatInfo;
+} test_RemoteShimInfo;
+
+
+static BOOL readproc(HANDLE proc, LPVOID address, PVOID target, DWORD size)
+{
+ SIZE_T dwRead;
+ if (ReadProcessMemory(proc, address, target, size, &dwRead))
+ {
+ ok(dwRead == size, "Expected to read %u bytes, got %lu\n", size,
dwRead);
+ return dwRead == size;
+ }
+ ok(0, "RPM failed with %u\n", GetLastError());
+ return FALSE;
+}
+
+static BOOL get_shiminfo(HANDLE proc, test_RemoteShimInfo* info)
+{
+ PROCESS_BASIC_INFORMATION pbi = { 0 };
+ ULONG sizeOut = 0;
+ NTSTATUS status = NtQueryInformationProcess(proc, ProcessBasicInformation, &pbi,
sizeof(pbi), &sizeOut);
+ ok(NT_SUCCESS(status), "Expected NtQI to succeed, but failed with: %x\n",
status);
+ memset(info, 0, sizeof(*info));
+ if (NT_SUCCESS(status))
+ {
+ PEB peb = { 0 };
+ if (readproc(proc, pbi.PebBaseAddress, &peb, sizeof(peb)))
+ {
+ MEMORY_BASIC_INFORMATION mbi = { 0 };
+ SIZE_T dwRead;
+
+ info->AppCompatFlags = peb.AppCompatFlags;
+ info->AppCompatFlagsUser = peb.AppCompatFlagsUser;
+ info->AppCompatInfo = peb.AppCompatInfo;
+ if (peb.pShimData == NULL)
+ return TRUE;
+
+ dwRead = VirtualQueryEx(proc, (LPCVOID)peb.pShimData, &mbi,
sizeof(mbi));
+ ok(dwRead == sizeof(mbi), "Expected VQE to return %u, got %lu\n",
sizeof(mbi), dwRead);
+ if (dwRead == sizeof(mbi) || peb.pShimData == NULL)
+ {
+ info->ShimDataSize = mbi.RegionSize;
+ info->pShimData = malloc(mbi.RegionSize);
+ if (readproc(proc, peb.pShimData, info->pShimData, mbi.RegionSize))
+ return TRUE;
+ free(info->pShimData);
+ info->pShimData = NULL;
+ }
+ }
+ }
+ return FALSE;
+}
+
+static HANDLE create_proc(BOOL suspended)
+{
+ static char proc_name[MAX_PATH] = { 0 };
+ STARTUPINFOA si = {sizeof(si)};
+ PROCESS_INFORMATION pi;
+ BOOL res;
+ if (!proc_name[0])
+ {
+ GetModuleFileNameA(NULL, proc_name, MAX_PATH);
+ }
+
+ res = CreateProcessA(NULL, proc_name, NULL, NULL, TRUE, suspended ? CREATE_SUSPENDED
: 0, NULL, NULL, &si, &pi);
+ if (!res)
+ return NULL;
+ CloseHandle(pi.hThread);
+ return pi.hProcess;
+}
+
+static void create_environ(const char* layers[], size_t num)
+{
+ char buf[256] = { 0 };
+ size_t n;
+ for (n = 0; n < num; ++n)
+ {
+ if (n)
+ strcat(buf, " ");
+ strcat(buf, layers[n]);
+ }
+ SetEnvironmentVariableA("__COMPAT_LAYER", buf);
+}
+
+static void ValidateShim(TAGREF trLayer, const char* name)
+{
+ HSDB hsdb = pSdbInitDatabase(SDB_DATABASE_MAIN_SHIM, NULL);
+ ok(hsdb != NULL, "Expected a valid handle\n");
+ if (hsdb)
+ {
+ PDB pdb = NULL;
+ TAGID tagid = 0xdeadbeef;
+ WCHAR nameW[256] = { 0 };
+ BOOL ret;
+
+ mbstowcs(nameW, name, strlen(name));
+
+ ret = pSdbTagRefToTagID(hsdb, trLayer, &pdb, &tagid);
+ ok(ret == TRUE, "Expected pSdbTagRefToTagID to succeed\n");
+ if (ret)
+ {
+ TAG tag;
+ ok(pdb != NULL, "Expected pdb to be a valid pointer\n");
+ ok(tagid != 0 && tagid != 0xdeadbeef, "Expected tagid to be a
valid tag id, was: 0x%x\n", tagid);
+ tag = pSdbGetTagFromTagID(pdb, tagid);
+ ok(tag == 0x700b, "Expected tag to be 0x700b, was 0x%x\n",
(DWORD)tag);
+ }
+
+ pSdbReleaseDatabase(hsdb);
+ }
+}
+
+
+static void Validate_ShimData_Win2k3(PVOID data, size_t count, const char* layers[])
+{
+ //size_t n;
+ ShimData_Win2k3* pShimData = (ShimData_Win2k3*)data;
+
+ 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));
+ ok(pShimData->dwMagic == SHIMDATA_MAGIC, "Expected pShimData->dwMagic to
be 0x%x, was 0x%x\n", SHIMDATA_MAGIC, pShimData->dwMagic);
+ ok(pShimData->dwSize == sizeof(ShimData_Win2k3), "Expected
pShimData->dwSize to be %u, was %u\n", sizeof(ShimData_Win2k3),
pShimData->dwSize);
+ ok(pShimData->dwCustomSDBMap == 1, "Expected pShimData->dwCustomSDBMap to
be 1, was %u\n", pShimData->dwCustomSDBMap);
+}
+
+static void Validate_ShimData_Win7(PVOID data, WCHAR szApphelp[256], size_t count, const
char* layers[])
+{
+ size_t n;
+ ShimData_Win7* pShimData = (ShimData_Win7*)data;
+
+ ok(!lstrcmpW(pShimData->szModule, szApphelp), "Expected pShimData->Module
to be %s, was %s\n",
+ wine_dbgstr_w(szApphelp), wine_dbgstr_w(pShimData->szModule));
+ ok(pShimData->dwMagic == SHIMDATA_MAGIC, "Expected pShimData->dwMagic to
be 0x%x, was 0x%x\n",
+ SHIMDATA_MAGIC, pShimData->dwMagic);
+ ok(pShimData->dwSize == sizeof(ShimData_Win7), "Expected pShimData->dwSize
to be %u, was %u\n",
+ sizeof(ShimData_Win7), pShimData->dwSize);
+ if (pShimData->Query.dwLayerCount != min(count, SDB_MAX_LAYERS))
+ {
+ char buf[250] = {0};
+ GetEnvironmentVariableA("__COMPAT_LAYER", buf, _countof(buf));
+ trace("At test: %s\n", buf);
+ }
+ ok(pShimData->Query.dwLayerCount == min(count, SDB_MAX_LAYERS),
+ "Expected LayerCount to be %u, was %u\n", min(count, SDB_MAX_LAYERS),
pShimData->Query.dwLayerCount);
+ for (n = 0; n < SDB_MAX_LAYERS; ++n)
+ {
+ if (n < count)
+ {
+ ok(pShimData->Query.atrLayers[n] != 0, "Expected to find a valid
layer in index %u / %u\n", n, count);
+ ValidateShim(pShimData->Query.atrLayers[n], layers[n]);
+ }
+ else
+ ok(pShimData->Query.atrLayers[n] == 0, "Expected to find an empty
layer in index %u / %u\n", n, count);
+ }
+ ok(pShimData->unknown == 0x14c, "Expected pShimData->unknown to be 0x14c,
was 0x%x\n", pShimData->unknown);
+}
+
+static void Validate_ShimData_Win10_v2(PVOID data, WCHAR szApphelp[256], size_t count,
const char* layers[])
+{
+ size_t n;
+ ShimData_Win10_v2* pShimData = (ShimData_Win10_v2*)data;
+
+ if (pShimData->dwMagic != SHIMDATA_MAGIC)
+ {
+ skip("Yet another unknown shimdata variant...\n");
+ return;
+ }
+
+ ok(pShimData->dwSize == sizeof(ShimData_Win10_v2), "Expected
pShimData->dwSize to be %u, was %u\n",
+ sizeof(ShimData_Win10_v2), pShimData->dwSize);
+ if (pShimData->Query.dwLayerCount != min(count, SDB_MAX_LAYERS))
+ {
+ char buf[250] = {0};
+ GetEnvironmentVariableA("__COMPAT_LAYER", buf, _countof(buf));
+ trace("At test: %s\n", buf);
+ }
+ ok(pShimData->Query.dwLayerCount == min(count, SDB_MAX_LAYERS),
+ "Expected LayerCount to be %u, was %u\n", min(count, SDB_MAX_LAYERS),
pShimData->Query.dwLayerCount);
+ for (n = 0; n < SDB_MAX_LAYERS; ++n)
+ {
+ if (n < count)
+ {
+ ok(pShimData->Query.atrLayers[n] != 0, "Expected to find a valid
layer in index %u / %u\n", n, count);
+ ValidateShim(pShimData->Query.atrLayers[n], layers[n]);
+ }
+ else
+ ok(pShimData->Query.atrLayers[n] == 0, "Expected to find an empty
layer in index %u / %u\n", n, count);
+ }
+
+}
+
+static void Validate_ShimData_Win10(PVOID data, WCHAR szApphelp[256], size_t count, const
char* layers[])
+{
+ size_t n;
+ ShimData_Win10_v1* pShimData = (ShimData_Win10_v1*)data;
+
+ if (pShimData->dwMagic != SHIMDATA_MAGIC)
+ {
+ Validate_ShimData_Win10_v2(data, szApphelp, count, layers);
+ return;
+ }
+
+
+ ok(!lstrcmpiW(pShimData->szModule, szApphelp), "Expected pShimData->Module
to be %s, was %s\n",
+ wine_dbgstr_w(szApphelp), wine_dbgstr_w(pShimData->szModule));
+ ok(pShimData->dwSize == sizeof(ShimData_Win10_v1), "Expected
pShimData->dwSize to be %u, was %u\n",
+ sizeof(ShimData_Win10_v1), pShimData->dwSize);
+ if (pShimData->Query.dwLayerCount != min(count, SDB_MAX_LAYERS))
+ {
+ char buf[250] = {0};
+ GetEnvironmentVariableA("__COMPAT_LAYER", buf, _countof(buf));
+ trace("At test: %s\n", buf);
+ }
+ ok(pShimData->Query.dwLayerCount == min(count, SDB_MAX_LAYERS),
+ "Expected LayerCount to be %u, was %u\n", min(count, SDB_MAX_LAYERS),
pShimData->Query.dwLayerCount);
+ for (n = 0; n < SDB_MAX_LAYERS; ++n)
+ {
+ if (n < count)
+ {
+ ok(pShimData->Query.atrLayers[n] != 0, "Expected to find a valid
layer in index %u / %u\n", n, count);
+ ValidateShim(pShimData->Query.atrLayers[n], layers[n]);
+ }
+ else
+ ok(pShimData->Query.atrLayers[n] == 0, "Expected to find an empty
layer in index %u / %u\n", n, count);
+ }
+}
+
+static void Validate_EmptyShimData_Win10(PVOID data)
+{
+ ShimData_Win10_v1* pShimData = (ShimData_Win10_v1*)data;
+ ok(pShimData != NULL, "Expected pShimData\n");
+ if (!pShimData)
+ return;
+
+ if (pShimData->dwMagic != SHIMDATA_MAGIC)
+ {
+ ShimData_Win10_v2* pShimData2 = (ShimData_Win10_v2*)data;
+ if (pShimData2->dwMagic != SHIMDATA_MAGIC)
+ {
+ skip("Unknown shimdata (win10)\n");
+ return;
+ }
+
+ ok(!lstrcmpiW(pShimData2->szLayer, L""), "Expected
pShimData->szLayer to be '', was %s\n",
wine_dbgstr_w(pShimData2->szLayer));
+ ok(pShimData2->dwSize == sizeof(ShimData_Win10_v2), "Expected
pShimData->dwSize to be %u, was %u\n", sizeof(ShimData_Win10_v2),
pShimData2->dwSize);
+ ok(!memcmp(&pShimData2->Query, &empty_result, sizeof(empty_result)),
"Expected result to be empty\n");
+ }
+ else
+ {
+ ok(!lstrcmpiW(pShimData->szModule, L""), "Expected
pShimData->Module to be '', was %s\n",
wine_dbgstr_w(pShimData->szModule));
+ ok(!lstrcmpiW(pShimData->szLayer, L""), "Expected
pShimData->szLayer to be '', was %s\n",
wine_dbgstr_w(pShimData->szLayer));
+ ok(pShimData->dwSize == sizeof(ShimData_Win10_v1), "Expected
pShimData->dwSize to be %u, was %u\n", sizeof(ShimData_Win10_v1),
pShimData->dwSize);
+ ok(!memcmp(&pShimData->Query, &empty_result, sizeof(empty_result)),
"Expected result to be empty\n");
+ }
+}
+
+static void Test_layers(WCHAR szApphelp[256])
+{
+ static const char* layers[] = {
+ "256Color", "NT4SP5", "DisableNXHideUI",
"DisableNXShowUI",
+ "WIN2000SP3", "640X480", /*"DISABLEDWM",*/
"HIGHDPIAWARE",
+ /*"RUNASADMIN",*/ "DISABLETHEMES" /*,
"Layer_Win95VersionLie"*/ };
+
+ size_t n;
+ HANDLE proc;
+ test_RemoteShimInfo info;
+ BOOL res;
+
+ for (n = 0; n <= (sizeof(layers) / sizeof(layers[0])); ++n)
+ {
+ create_environ(layers, n);
+
+ proc = create_proc(TRUE);
+ res = get_shiminfo(proc, &info);
+ TerminateProcess(proc, 0);
+ CloseHandle(proc);
+
+ if (!res)
+ {
+ ok(0, "Unable to get process info (%u)!\n", n);
+ continue;
+ }
+
+ if (n == 0)
+ {
+ ok(info.AppCompatFlags.QuadPart == 0, "Expected AppCompatFlags to be 0,
was: %s\n", wine_dbgstr_longlong(info.AppCompatFlags.QuadPart));
+ ok(info.AppCompatFlagsUser.QuadPart == 0, "Expected AppCompatFlagsUser
to be 0, was: %s\n", wine_dbgstr_longlong(info.AppCompatFlagsUser.QuadPart));
+ ok(info.AppCompatInfo == NULL, "Expected AppCompatInfo to be NULL, was:
%p\n", info.AppCompatInfo);
+ if (g_WinVersion < WINVER_WIN10)
+ {
+ ok(info.pShimData == NULL, "Expected pShimData to be NULL, was:
%p\n", info.pShimData);
+ }
+ else
+ {
+ Validate_EmptyShimData_Win10(info.pShimData);
+ }
+ }
+ else
+ {
+ ok(info.AppCompatFlags.QuadPart == 0, "Expected AppCompatFlags to be 0,
was: %s\n", wine_dbgstr_longlong(info.AppCompatFlags.QuadPart));
+ ok(info.AppCompatFlagsUser.QuadPart == 0, "Expected AppCompatFlagsUser
to be 0, was: %s\n", wine_dbgstr_longlong(info.AppCompatFlagsUser.QuadPart));
+ ok(info.AppCompatInfo == NULL, "Expected AppCompatInfo to be NULL, was:
%p\n", info.AppCompatInfo);
+ ok(info.pShimData != NULL, "Expected pShimData to be valid, was
NULL\n");
+ ok(info.ShimDataSize == g_ShimDataSize, "Expected ShimDataSize to be %u,
was: %u\n", g_ShimDataSize, info.ShimDataSize);
+ if (info.pShimData)
+ {
+ if (g_WinVersion < WINVER_VISTA)
+ Validate_ShimData_Win2k3(info.pShimData, n, layers);
+ else if (g_WinVersion < WINVER_WIN10)
+ Validate_ShimData_Win7(info.pShimData, szApphelp, n, layers);
+ else
+ Validate_ShimData_Win10(info.pShimData, szApphelp, n, layers);
+ }
+ }
+ free(info.pShimData);
+ }
+}
+
+
+/*
+[Warn][SdbGetMatchingExe ] __COMPAT_LAYER name cannot exceed 256 characters.
+[Info][SdbpGetPermLayersInternal] Failed to read value info from Key
"\Registry\Machine\Software\Microsoft\Windows
NT\CurrentVersion\AppCompatFlags\Layers" Status 0xc0000034
+[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
+[Warn][SdbpEnumUserSdb ] Failed to open key
"\Registry\Machine\Software\Microsoft\Windows
NT\CurrentVersion\AppCompatFlags\Custom\NotepadReplacer.exe" Status 0xc0000034
+*/
+static void Test_repeatlayer(WCHAR szApphelp[256])
+{
+ static const char* layers[] = {
+ "256Color", "256Color", "256Color",
"256Color",
+ "256Color", "256Color", "256Color",
"256Color" };
+
+ HANDLE proc;
+ test_RemoteShimInfo info;
+ BOOL res;
+
+ SetEnvironmentVariableA("__COMPAT_LAYER", "256Color 256Color 256Color
256Color 256Color 256Color 256Color 256Color");
+
+
+ proc = create_proc(TRUE);
+ res = get_shiminfo(proc, &info);
+ TerminateProcess(proc, 0);
+ CloseHandle(proc);
+
+ if (res)
+ {
+ ok(info.AppCompatFlags.QuadPart == 0, "Expected AppCompatFlags to be 0, was:
%s\n", wine_dbgstr_longlong(info.AppCompatFlags.QuadPart));
+ ok(info.AppCompatFlagsUser.QuadPart == 0, "Expected AppCompatFlagsUser to be
0, was: %s\n", wine_dbgstr_longlong(info.AppCompatFlagsUser.QuadPart));
+ ok(info.AppCompatInfo == 0, "Expected AppCompatInfo to be 0, was:
%p\n", info.AppCompatInfo);
+ ok(info.pShimData != NULL, "Expected pShimData to be valid, was
NULL\n");
+ ok(info.ShimDataSize == g_ShimDataSize, "Expected ShimDataSize to be %u,
was: %u\n", g_ShimDataSize, info.ShimDataSize);
+ if (info.pShimData)
+ {
+ /* Win10 only 'loads' one layer */
+ if (g_WinVersion < WINVER_VISTA)
+ Validate_ShimData_Win2k3(info.pShimData, SDB_MAX_LAYERS, layers);
+ else if (g_WinVersion < WINVER_WIN10)
+ Validate_ShimData_Win7(info.pShimData, szApphelp, SDB_MAX_LAYERS,
layers);
+ else
+ Validate_ShimData_Win10(info.pShimData, szApphelp, 1, layers);
+ }
+ }
+ else
+ {
+ ok(0, "Unable to get process info!\n");
+ }
+
+}
+
+
+TAGREF find_layer(const char* szLayerStart, const char* szLayerEnd)
+{
+ char layer[100] = { 0 };
+ WCHAR layerW[100] = { 0 };
+ strncpy(layer, szLayerStart, szLayerEnd - szLayerStart);
+
+ if (!g_LayerDB)
+ {
+ g_LayerDB = pSdbInitDatabase(SDB_DATABASE_MAIN_SHIM, 0);
+ }
+
+ mbstowcs(layerW, layer, strlen(layer));
+ return pSdbGetLayerTagRef(g_LayerDB, layerW);
+}
+
+static void expect_layeronly_imp(SDBQUERYRESULT_VISTA* result, const char* layers, DWORD
flags)
+{
+ DWORD dwLayerCount = 0, n;
+ TAGREF atrLayers[SDB_MAX_LAYERS] = { 0 };
+
+ const char* layer = layers, *nextlayer;
+ while (layer && *layer)
+ {
+ nextlayer = strchr(layer, ' ');
+ atrLayers[dwLayerCount++] = find_layer(layer, nextlayer ? nextlayer : (layer +
strlen(layer)));
+ layer = nextlayer ? (nextlayer+1) : NULL;
+ }
+
+ if (g_ModuleVersion < WINVER_VISTA)
+ {
+ SDBQUERYRESULT_2k3* result2 = (SDBQUERYRESULT_2k3*)result;
+ result = NULL;
+
+ winetest_ok(!memcmp(&result2->atrExes, &empty_result.atrExes,
sizeof(result2->atrExes)), "Expected atrExes to be empty\n");
+ 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");
+ for (n = 0; n < dwLayerCount; ++n)
+ {
+ winetest_ok(result2->atrLayers[n] == atrLayers[n], "Expected
atrLayers[%u] to be %x, was %x\n",
+ n, atrLayers[n], result2->atrLayers[n]);
+ }
+ winetest_ok(result2->dwLayerFlags == 0, "Expected dwLayerFlags to be 0,
was %u\n", result2->dwLayerFlags);
+ winetest_ok(result2->trApphelp == 0, "Expected trApphelp to be 0, was
%u\n", result2->trApphelp);
+ winetest_ok(result2->dwExeCount == 0, "Expected dwExeCount to be 0, was
%u\n", result2->dwExeCount);
+ winetest_ok(result2->dwLayerCount == dwLayerCount, "Expected dwLayerCount
to be %u, was %u\n", dwLayerCount, result2->dwLayerCount);
+ winetest_ok(!memcmp(&result2->guidID, &empty_result.guidID,
sizeof(result2->guidID)), "Expected guidID to be empty\n");
+ winetest_ok(result2->dwFlags == flags, "Expected dwFlags to be 0x%x, was
0x%x\n", flags, result2->dwFlags);
+ winetest_ok(result2->dwCustomSDBMap == 1, "Expected dwCustomSDBMap to be
1, was %u\n", result2->dwCustomSDBMap);
+ winetest_ok(!memcmp(&result2->rgGuidDB[1], &empty_result.rgGuidDB[1],
sizeof(result2->rgGuidDB) - sizeof(result2->rgGuidDB[0])), "Expected
rgGuidDB[+1] to be empty\n");
+ }
+ else
+ {
+ winetest_ok(!memcmp(&result->atrExes, &empty_result.atrExes,
sizeof(empty_result.atrExes)), "Expected atrExes to be empty\n");
+ winetest_ok(!memcmp(&result->adwExeFlags, &empty_result.adwExeFlags,
sizeof(empty_result.adwExeFlags)), "Expected adwExeFlags to be empty\n");
+ 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");
+ for (n = 0; n < dwLayerCount; ++n)
+ {
+ winetest_ok(result->atrLayers[n] == atrLayers[n], "Expected
atrLayers[%u] to be %x, was %x\n",
+ n, atrLayers[n], result->atrLayers[n]);
+ }
+ winetest_ok(result->dwLayerFlags == 0, "Expected dwLayerFlags to be 0,
was %u\n", result->dwLayerFlags);
+ winetest_ok(result->trApphelp == 0, "Expected trApphelp to be 0, was
%u\n", result->trApphelp);
+ winetest_ok(result->dwExeCount == 0, "Expected dwExeCount to be 0, was
%u\n", result->dwExeCount);
+ winetest_ok(result->dwLayerCount == dwLayerCount, "Expected dwLayerCount
to be %u, was %u\n", dwLayerCount, result->dwLayerCount);
+ winetest_ok(!memcmp(&result->guidID, &empty_result.guidID,
sizeof(empty_result.guidID)), "Expected guidID to be empty\n");
+ winetest_ok(result->dwFlags == flags, "Expected dwFlags to be 0x%x, was
0x%x\n", flags, result->dwFlags);
+ winetest_ok(result->dwCustomSDBMap == 1, "Expected dwCustomSDBMap to be
1, was %u\n", result->dwCustomSDBMap);
+ 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");
+ }
+}
+
+static void Test_Shimdata(SDBQUERYRESULT_VISTA* result, const WCHAR* szLayer)
+{
+ BOOL ret;
+ PVOID pData;
+ DWORD dwSize;
+
+ pData = NULL;
+ dwSize = 0;
+ ret = pSdbPackAppCompatData(g_LayerDB, result, &pData, &dwSize);
+ ok(ret == TRUE, "Expected ret to be TRUE\n");
+
+ if (pData)
+ {
+ ShimData_Win2k3* pWin2k3;
+ ShimData_Win7* pWin7;
+ ShimData_Win10_v1* pWin10;
+ ShimData_Win10_v2* pWin10_v2;
+ SDBQUERYRESULT_VISTA result2 = { { 0 } };
+
+ DWORD res = pSdbGetAppCompatDataSize(pData);
+ ok_int(dwSize, res);
+ switch(dwSize)
+ {
+ case sizeof(ShimData_Win2k3):
+ pWin2k3 = (ShimData_Win2k3*)pData;
+ ok_hex(pWin2k3->dwMagic, SHIMDATA_MAGIC);
+ ok_int(pWin2k3->dwSize, dwSize);
+ ok(pWin2k3->dwCustomSDBMap == 1, "Expected pWin2k3->dwCustomSDBMap
to equal 1, was %u for %s\n", pWin2k3->dwCustomSDBMap, wine_dbgstr_w(szLayer));
+ //ok(!memcmp(&pWin2k3->Query, result, sizeof(SDBQUERYRESULT_2k3)),
"Expected pWin2k3->Query to equal result\n");
+ //ok_wstr(pWin7->szLayer, szLayer);
+ break;
+ case sizeof(ShimData_Win7):
+ pWin7 = (ShimData_Win7*)pData;
+ ok_hex(pWin7->dwMagic, SHIMDATA_MAGIC);
+ ok_int(pWin7->dwSize, dwSize);
+ ok(!memcmp(&pWin7->Query, result, sizeof(*result)), "Expected
pWin7->Query to equal result\n");
+ ok_wstr(pWin7->szLayer, szLayer);
+ break;
+ case sizeof(ShimData_Win10_v1):
+ pWin10 = (ShimData_Win10_v1*)pData;
+ ok_hex(pWin10->dwMagic, SHIMDATA_MAGIC);
+ ok_int(pWin10->dwSize, dwSize);
+ ok(!memcmp(&pWin10->Query, result, sizeof(*result)), "Expected
pWin10->Query to equal result\n");
+ ok_wstr(pWin10->szLayerEnv, szLayer);
+ ok_wstr(pWin10->szLayer, L"");
+ break;
+ case sizeof(ShimData_Win10_v2):
+ pWin10_v2 = (ShimData_Win10_v2*)pData;
+ ok_hex(pWin10_v2->dwMagic, SHIMDATA_MAGIC);
+ ok_int(pWin10_v2->dwSize, dwSize);
+ ok(!memcmp(&pWin10_v2->Query, result, sizeof(*result)), "Expected
pWin10->Query to equal result\n");
+ ok_wstr(pWin10_v2->szLayerEnv, szLayer);
+ ok_wstr(pWin10_v2->szLayer, L"");
+ break;
+ default:
+ skip("Unknown size %d\n", dwSize);
+ break;
+ }
+
+ ret = pSdbUnpackAppCompatData(g_LayerDB, NULL, pData, &result2);
+ ok(ret == TRUE, "Expected ret to be TRUE\n");
+ /* TODO: For some reason 2k3 does not seem to output the database GUIDs,
+ investigate when we have support for multible db's! */
+ if (dwSize == sizeof(ShimData_Win2k3))
+ {
+ /* Fake it for now, so the memcmp works. */
+ SDBQUERYRESULT_2k3* input = (SDBQUERYRESULT_2k3*)result;
+ SDBQUERYRESULT_2k3* output = (SDBQUERYRESULT_2k3*)&result2;
+ ok(output->dwCustomSDBMap == 0, "Expected output->dwCustomSDBMap
to be 0, was %u for %s\n", output->dwCustomSDBMap, wine_dbgstr_w(szLayer));
+ output->dwCustomSDBMap = input->dwCustomSDBMap;
+ output->rgGuidDB[0] = input->rgGuidDB[0];
+ }
+ ok(!memcmp(&result2, result, sizeof(result)), "Expected result2 to equal
result for %s\n", wine_dbgstr_w(szLayer));
+
+ RtlFreeHeap(GetProcessHeap(), 0, pData);
+ }
+}
+
+
+#define expect_layeronly (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 :
expect_layeronly_imp
+
+
+static void Test_GetMatchingExe(void)
+{
+ BOOL ret;
+ SDBQUERYRESULT_VISTA result = { { 0 } };
+ WCHAR self[MAX_PATH];
+ DWORD flags = (g_WinVersion < WINVER_VISTA) ? 0 : ((g_WinVersion <
WINVER_WIN10) ? 1 : 0x21);
+
+ GetModuleFileNameW(NULL, self, MAX_PATH);
+ SetEnvironmentVariableA("__COMPAT_LAYER", NULL);
+
+ /* szPath cannot be NULL! */
+ ret = pSdbGetMatchingExe(NULL, L"", NULL, NULL, 0, &result);
+ ok(ret == FALSE, "Expected ret to be FALSE\n");
+ ok(!memcmp(&result, &empty_result, sizeof(empty_result)), "Expected
result to be empty\n");
+
+ result = empty_result;
+
+ ret = pSdbGetMatchingExe(NULL, self, NULL, NULL, 0, &result);
+ ok(ret == FALSE, "Expected ret to be FALSE\n");
+ ok(!memcmp(&result, &empty_result, sizeof(empty_result)), "Expected
result to be empty\n");
+
+ result = empty_result;
+ SetEnvironmentVariableA("__COMPAT_LAYER",
"Some_invalid_layer_name");
+
+ ret = pSdbGetMatchingExe(NULL, self, NULL, NULL, 0, &result);
+ ok(ret == FALSE, "Expected ret to be FALSE\n");
+ if (g_WinVersion < WINVER_WIN10)
+ ok(!memcmp(&result, &empty_result, sizeof(empty_result)), "Expected
result to be empty\n");
+ else
+ ok(!memcmp(&result, &almost_empty, sizeof(almost_empty)), "Expected
result to be almost empty\n");
+
+ result = empty_result;
+ SetEnvironmentVariableA("__COMPAT_LAYER", "256Color");
+
+ ret = pSdbGetMatchingExe(NULL, self, NULL, NULL, 0, &result);
+ ok(ret == TRUE, "Expected ret to be TRUE\n");
+ expect_layeronly(&result, "256Color", flags);
+
+ Test_Shimdata(&result, L"256Color");
+
+ result = empty_result;
+ SetEnvironmentVariableA("__COMPAT_LAYER", "640X480");
+
+ ret = pSdbGetMatchingExe(NULL, self, NULL, NULL, 0, &result);
+ ok(ret == TRUE, "Expected ret to be TRUE\n");
+ expect_layeronly(&result, "640X480", flags);
+
+ Test_Shimdata(&result, L"640X480");
+
+ /* HIGHDPIAWARE does not exist in 2k3 */
+ if (g_WinVersion > WINVER_2003)
+ {
+ result = empty_result;
+ SetEnvironmentVariableA("__COMPAT_LAYER", "HIGHDPIAWARE");
+
+ ret = pSdbGetMatchingExe(NULL, self, NULL, NULL, 0, &result);
+ ok(ret == TRUE, "Expected ret to be TRUE\n");
+ expect_layeronly(&result, "HIGHDPIAWARE", flags);
+
+ Test_Shimdata(&result, L"HIGHDPIAWARE");
+
+ result = empty_result;
+ SetEnvironmentVariableA("__COMPAT_LAYER", "256Color HIGHDPIAWARE
640X480");
+
+ ret = pSdbGetMatchingExe(NULL, self, NULL, NULL, 0, &result);
+ ok(ret == TRUE, "Expected ret to be TRUE\n");
+ expect_layeronly(&result, "256Color HIGHDPIAWARE 640X480", flags);
+
+ Test_Shimdata(&result, L"256Color HIGHDPIAWARE 640X480");
+ }
+}
+
+
+HANDLE xOpenFile(WCHAR* ApplicationName)
+{
+ UNICODE_STRING FileName;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ NTSTATUS Status;
+ HANDLE FileHandle;
+
+ if (!RtlDosPathNameToNtPathName_U(ApplicationName, &FileName, NULL, NULL))
+ {
+ skip("Unable to translate %s to Nt path\n",
wine_dbgstr_w(ApplicationName));
+ return NULL;
+ }
+
+
+ InitializeObjectAttributes(&ObjectAttributes, &FileName,
OBJ_CASE_INSENSITIVE, NULL, NULL);
+ Status = NtOpenFile(&FileHandle,
+ SYNCHRONIZE |
+ FILE_READ_ATTRIBUTES |
+ FILE_READ_DATA |
+ FILE_EXECUTE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ | FILE_SHARE_DELETE,
+ FILE_SYNCHRONOUS_IO_NONALERT |
+ FILE_NON_DIRECTORY_FILE);
+
+ RtlFreeUnicodeString(&FileName);
+
+ if (!NT_SUCCESS(Status))
+ return NULL;
+
+ return FileHandle;
+}
+
+
+#define RESET_CHECKRUNAPP_VARS()\
+ do { \
+ if (AppCompatData && AppCompatData != &Query) {
RtlFreeHeap(RtlGetProcessHeap(), 0, AppCompatData); } \
+ ExeType = IMAGE_FILE_MACHINE_I386; \
+ SxsDataSize = FusionFlags = Reason = 0; \
+ SxsData = NULL; \
+ memset(&Query, 0, sizeof(Query)); \
+ AppCompatData = &Query; \
+ AppCompatDataSize = 123456; \
+ } while (0)
+
+#define CHECK_BASICS()\
+ do { \
+ ok_hex(ret, TRUE); \
+ ok(AppCompatData != NULL && AppCompatData != &Query, "Expected
the pointer to be valid\n"); \
+ ok_hex(AppCompatDataSize, sizeof(SDBQUERYRESULT_VISTA)); \
+ ok(SxsData == NULL, "Expected the pointer to be NULL\n"); \
+ ok_hex(SxsDataSize, 0); \
+ ok_hex(FusionFlags, 0); \
+ } while (0)
+
+/* W10 does not seem to use the flags at all, so with this macro we can still test it
below 10. */
+#define CHECKREASON(value, w10dum) (g_ModuleVersion < WINVER_WIN10 ? value : w10dum)
+
+
+static BOOL call_ApphelpCheckRunApp(HANDLE FileHandle, PWCHAR ApplicationName, PVOID
Environment, USHORT ExeType,
+ PULONG Reason, PVOID* SdbQueryAppCompatData, PULONG
SdbQueryAppCompatDataSize,
+ PVOID* SxsData, PULONG SxsDataSize, PULONG
FusionFlags)
+{
+ ULONG64 SomeFlag1 = 0;
+ ULONG SomeFlag2 = 0;
+
+ if (pApphelpCheckRunAppEx_w7)
+ {
+ return pApphelpCheckRunAppEx_w7(FileHandle, NULL, NULL, ApplicationName,
Environment, ExeType, Reason,
+ SdbQueryAppCompatData, SdbQueryAppCompatDataSize,
SxsData, SxsDataSize,
+ FusionFlags, &SomeFlag1, &SomeFlag2);
+ }
+
+ if (pApphelpCheckRunAppEx_w10)
+ {
+ return pApphelpCheckRunAppEx_w10(FileHandle, NULL, NULL, ApplicationName,
Environment, NULL, ExeType, Reason,
+ SdbQueryAppCompatData, SdbQueryAppCompatDataSize,
SxsData, SxsDataSize,
+ FusionFlags, &SomeFlag1, &SomeFlag2);
+ }
+
+ return FALSE;
+}
+
+
+
+
+
+static void Test_ApphelpCheckRunApp(WCHAR szApphelp[256])
+{
+ BOOL ret;
+ HANDLE FileHandle = NULL;
+ WCHAR ApplicationName[MAX_PATH], EmptyName[1] = { 0 };
+ DWORD expect_flags = (g_WinVersion < WINVER_WIN10) ? 1 : 0x21;
+
+ USHORT ExeType;
+ PVOID AppCompatData = NULL, SxsData, DuplicatedEnv, Environment;
+ ULONG AppCompatDataSize, SxsDataSize, FusionFlags;
+ ULONG Reason;
+ SDBQUERYRESULT_VISTA Query;
+ int n;
+ /* this are the only interesting bits (with the exception of '1', which is
there to invoke the 'default' case) */
+ const int kTestBits = 0x70503;
+
+ if (!pApphelpCheckRunAppEx_w7 && !pApphelpCheckRunAppEx_w10)
+ {
+ skip("No usable ApphelpCheckRunAppEx\n");
+ return;
+ }
+
+ GetModuleFileNameW(NULL, ApplicationName, MAX_PATH);
+
+ FileHandle = xOpenFile(ApplicationName);
+ SetEnvironmentVariableA("__COMPAT_LAYER", NULL);
+ if (!CreateEnvironmentBlock(&DuplicatedEnv, NULL, TRUE))
+ DuplicatedEnv = NULL;
+ ok(DuplicatedEnv != NULL, "Invalid env (%u)\n", GetLastError());
+
+ /* First with the environment without __COMPAT_LAYER */
+ RESET_CHECKRUNAPP_VARS();
+
+ ret = call_ApphelpCheckRunApp(FileHandle, ApplicationName, DuplicatedEnv, ExeType,
&Reason,
+ &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize,
&FusionFlags);
+
+ CHECK_BASICS();
+ ok_hex(Reason, CHECKREASON(0x30000, 0));
+ ok(!memcmp(AppCompatData, &empty_result, sizeof(empty_result)), "Expected
result to be empty\n");
+
+ /* We need this to be set for tests later on. */
+ SetEnvironmentVariableA("__COMPAT_LAYER", "256Color");
+
+ if (g_ModuleVersion < WINVER_WIN10)
+ {
+ /* Showing that when an environment is passed in, that is used instead of the
current.
+ In Win10 this behavior is no longer observed */
+
+ RESET_CHECKRUNAPP_VARS();
+
+ ret = call_ApphelpCheckRunApp(FileHandle, ApplicationName, DuplicatedEnv,
ExeType, &Reason,
+ &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize,
&FusionFlags);
+
+ CHECK_BASICS();
+ ok_hex(Reason, CHECKREASON(0x30000, 0));
+ ok(!memcmp(AppCompatData, &empty_result, sizeof(empty_result)),
"Expected result to be empty\n");
+ }
+
+ for (n = 0; n < 32; ++n)
+ {
+ ULONG ExpectedReason;
+ if (!(kTestBits & (1<<n)))
+ continue;
+ RESET_CHECKRUNAPP_VARS();
+ ExpectedReason = Reason = (1 << n);
+ ret = call_ApphelpCheckRunApp(FileHandle, ApplicationName, DuplicatedEnv,
ExeType, &Reason,
+ &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize,
&FusionFlags);
+
+ CHECK_BASICS();
+ if (ExpectedReason == 2)
+ ExpectedReason = 2;
+ else if (ExpectedReason == 0x100)
+ ExpectedReason = 0x30000;
+ else
+ ExpectedReason |= 0x30000;
+ ok_hex(Reason, CHECKREASON(ExpectedReason, (1 << n)));
+ ok(!memcmp(AppCompatData, &empty_result, sizeof(empty_result)),
"Expected result to be empty\n");
+ }
+
+ if (g_ModuleVersion < WINVER_WIN10)
+ {
+ /* Now, using a NULL env, showing that the current environment is used.
+ W10 does no longer do this, so we skip this test here. */
+ Environment = NULL;
+
+ RESET_CHECKRUNAPP_VARS();
+
+ ret = call_ApphelpCheckRunApp(FileHandle, ApplicationName, Environment, ExeType,
&Reason,
+ &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize,
&FusionFlags);
+
+ CHECK_BASICS();
+ ok_hex(Reason, CHECKREASON(0x50000, 0));
+ if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
+ expect_layeronly(AppCompatData, "256Color", expect_flags);
+
+ for (n = 0; n < 32; ++n)
+ {
+ ULONG ExpectedReason;
+ RESET_CHECKRUNAPP_VARS();
+ if (!(kTestBits & (1<<n)))
+ continue;
+ ExpectedReason = Reason = (1 << n);
+ ret = call_ApphelpCheckRunApp(FileHandle, ApplicationName, Environment,
ExeType, &Reason,
+ &AppCompatData, &AppCompatDataSize, &SxsData,
&SxsDataSize, &FusionFlags);
+
+ CHECK_BASICS();
+ if (ExpectedReason == 2)
+ ExpectedReason = 2;
+ else if (ExpectedReason == 0x100)
+ ExpectedReason = 0x50000;
+ else if (ExpectedReason == 0x400)
+ ExpectedReason = 0x30400;
+ else
+ ExpectedReason |= 0x50000;
+ ok_hex(Reason, CHECKREASON(ExpectedReason, (1 << n)));
+ if (AppCompatData && AppCompatDataSize ==
sizeof(SDBQUERYRESULT_VISTA))
+ {
+ if (ExpectedReason != 0x30400)
+ expect_layeronly(AppCompatData, "256Color", expect_flags);
+ else
+ ok(!memcmp(AppCompatData, &empty_result, sizeof(empty_result)),
"Expected result to be empty\n");
+ }
+ }
+ }
+
+ /* Passing in an environment with __COMPAT_LAYER set */
+ Environment = GetEnvironmentStringsW();
+
+ RESET_CHECKRUNAPP_VARS();
+
+ ret = call_ApphelpCheckRunApp(FileHandle, ApplicationName, Environment, ExeType,
&Reason,
+ &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize,
&FusionFlags);
+
+ CHECK_BASICS();
+ ok_hex(Reason, CHECKREASON(0x50000, 0));
+ if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
+ expect_layeronly(AppCompatData, "256Color", expect_flags);
+
+ for (n = 0; n < 32; ++n)
+ {
+ ULONG ExpectedReason;
+ if (!(kTestBits & (1<<n)))
+ continue;
+ RESET_CHECKRUNAPP_VARS();
+ ExpectedReason = Reason = (1 << n);
+ ret = call_ApphelpCheckRunApp(FileHandle, ApplicationName, Environment, ExeType,
&Reason,
+ &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize,
&FusionFlags);
+
+ CHECK_BASICS();
+ if (ExpectedReason == 2)
+ ExpectedReason = 2;
+ else if (ExpectedReason == 0x100)
+ ExpectedReason = 0x50000;
+ else if (ExpectedReason == 0x400)
+ ExpectedReason = 0x30400;
+ else
+ ExpectedReason |= 0x50000;
+ ok_hex(Reason, CHECKREASON(ExpectedReason, (1 << n)));
+ if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
+ {
+ if (ExpectedReason != 0x30400 || g_ModuleVersion >= WINVER_WIN10)
+ expect_layeronly(AppCompatData, "256Color", expect_flags);
+ else
+ ok(!memcmp(AppCompatData, &empty_result, sizeof(empty_result)),
"Expected result to be empty\n");
+ }
+ }
+
+ /* NULL file handle still works */
+ RESET_CHECKRUNAPP_VARS();
+
+ ret = call_ApphelpCheckRunApp(NULL, ApplicationName, Environment, ExeType,
&Reason,
+ &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize,
&FusionFlags);
+
+ CHECK_BASICS();
+ ok_hex(Reason, CHECKREASON(0x50000, 0));
+ if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
+ expect_layeronly(AppCompatData, "256Color", expect_flags);
+
+ for (n = 0; n < 32; ++n)
+ {
+ ULONG ExpectedReason;
+ RESET_CHECKRUNAPP_VARS();
+ if (!(kTestBits & (1<<n)))
+ continue;
+ ExpectedReason = Reason = (1 << n);
+ ret = call_ApphelpCheckRunApp(NULL, ApplicationName, Environment, ExeType,
&Reason,
+ &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize,
&FusionFlags);
+
+ CHECK_BASICS();
+ if (ExpectedReason == 2)
+ ExpectedReason = 2;
+ else if (ExpectedReason == 0x100)
+ ExpectedReason = 0x50000;
+ else if (ExpectedReason == 0x400)
+ ExpectedReason = 0x30400;
+ else
+ ExpectedReason |= 0x50000;
+ ok_hex(Reason, CHECKREASON(ExpectedReason, (1 << n)));
+ if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
+ {
+ /* W10 does not use the flags anymore? */
+ if (ExpectedReason != 0x30400 || g_ModuleVersion >= WINVER_WIN10)
+ expect_layeronly(AppCompatData, "256Color", expect_flags);
+ else
+ ok(!memcmp(AppCompatData, &empty_result, sizeof(empty_result)),
"Expected result to be empty\n");
+ }
+ }
+
+
+ /* INVALID_HANDLE_VALUE file handle results in failure (according to flags!), but
still results in AppCompatData */
+ RESET_CHECKRUNAPP_VARS();
+
+ ret = call_ApphelpCheckRunApp(INVALID_HANDLE_VALUE, ApplicationName, Environment,
ExeType, &Reason,
+ &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize,
&FusionFlags);
+
+ CHECK_BASICS();
+ ok_hex(Reason, 0);
+ if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
+ expect_layeronly(AppCompatData, "256Color", expect_flags);
+
+ for (n = 0; n < 32; ++n)
+ {
+ ULONG ExpectedReason;
+ if (!(kTestBits & (1<<n)))
+ continue;
+ RESET_CHECKRUNAPP_VARS();
+ ExpectedReason = Reason = (1 << n);
+ ret = call_ApphelpCheckRunApp(INVALID_HANDLE_VALUE, NULL, Environment, ExeType,
&Reason,
+ &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize,
&FusionFlags);
+
+ CHECK_BASICS();
+ if (ExpectedReason == 0x100)
+ ExpectedReason = 0;
+ ok_hex(Reason, CHECKREASON(ExpectedReason, (1 << n)));
+ if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
+ {
+ if (ExpectedReason != 0x400 && g_ModuleVersion < WINVER_WIN10)
+ expect_layeronly(AppCompatData, "256Color", expect_flags);
+ else
+ ok(!memcmp(AppCompatData, &empty_result, sizeof(empty_result)),
"Expected result to be empty\n");
+ }
+ }
+
+ /* NULL filename crashes, showing this in the log before going down:
+[Err ][SdbpGetLongFileName ] Failed to get NT path name for ""
+[Err ][SdbpCreateSearchDBContext] Unable to parse executable path for "".
+[Err ][SdbGetMatchingExe ] Failed to create search DB context.
+*/
+ RESET_CHECKRUNAPP_VARS();
+
+ ret = call_ApphelpCheckRunApp(FileHandle, EmptyName, Environment, ExeType,
&Reason,
+ &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize,
&FusionFlags);
+
+ CHECK_BASICS();
+ ok_hex(Reason, CHECKREASON(0x30000, 0));
+ if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
+ ok(!memcmp(AppCompatData, &empty_result, sizeof(empty_result)),
"Expected result to be empty\n");
+
+ /* 0 ExeType = don't care? */
+ RESET_CHECKRUNAPP_VARS();
+ ExeType = 0;
+
+ ret = call_ApphelpCheckRunApp(FileHandle, ApplicationName, Environment, ExeType,
&Reason,
+ &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize,
&FusionFlags);
+
+ CHECK_BASICS();
+ ok_hex(Reason, CHECKREASON(0x50000, 0));
+ if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
+ expect_layeronly(AppCompatData, "256Color", expect_flags);
+
+ for (n = 0; n < 32; ++n)
+ {
+ ULONG ExpectedReason;
+ if (!(kTestBits & (1<<n)))
+ continue;
+ RESET_CHECKRUNAPP_VARS();
+ ExeType = 0;
+ ExpectedReason = Reason = (1 << n);
+ ret = call_ApphelpCheckRunApp(FileHandle, ApplicationName, Environment, ExeType,
&Reason,
+ &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize,
&FusionFlags);
+
+ CHECK_BASICS();
+ if (ExpectedReason == 2)
+ ExpectedReason = 2;
+ else if (ExpectedReason == 0x100)
+ ExpectedReason = 0x50000;
+ else if (ExpectedReason == 0x400)
+ ExpectedReason = 0x30400;
+ else
+ ExpectedReason |= 0x50000;
+ ok_hex(Reason, CHECKREASON(ExpectedReason, (1 << n)));
+ if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
+ {
+ if (ExpectedReason != 0x30400 || g_ModuleVersion >= WINVER_WIN10)
+ expect_layeronly(AppCompatData, "256Color", expect_flags);
+ else
+ ok(!memcmp(AppCompatData, &empty_result, sizeof(empty_result)),
"Expected result to be empty\n");
+ }
+ }
+
+
+ RESET_CHECKRUNAPP_VARS();
+ ExeType = IMAGE_FILE_MACHINE_POWERPCFP;
+
+ ret = call_ApphelpCheckRunApp(FileHandle, ApplicationName, Environment, ExeType,
&Reason,
+ &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize,
&FusionFlags);
+
+ CHECK_BASICS();
+ ok_hex(Reason, CHECKREASON(0x50000, 0));
+ if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
+ expect_layeronly(AppCompatData, "256Color", expect_flags);
+
+ for (n = 0; n < 32; ++n)
+ {
+ ULONG ExpectedReason;
+ if (!(kTestBits & (1<<n)))
+ continue;
+ RESET_CHECKRUNAPP_VARS();
+ ExeType = IMAGE_FILE_MACHINE_POWERPCFP;
+ ExpectedReason = Reason = (1 << n);
+ ret = call_ApphelpCheckRunApp(FileHandle, ApplicationName, Environment, ExeType,
&Reason,
+ &AppCompatData, &AppCompatDataSize, &SxsData, &SxsDataSize,
&FusionFlags);
+
+ CHECK_BASICS();
+ if (ExpectedReason == 2)
+ ExpectedReason = 2;
+ else if (ExpectedReason == 0x100)
+ ExpectedReason = 0x50000;
+ else if (ExpectedReason == 0x400)
+ ExpectedReason = 0x30400;
+ else
+ ExpectedReason |= 0x50000;
+ ok_hex(Reason, CHECKREASON(ExpectedReason, (1 << n)));
+ if (AppCompatData && AppCompatDataSize == sizeof(SDBQUERYRESULT_VISTA))
+ {
+ if (ExpectedReason != 0x30400 || g_ModuleVersion >= WINVER_WIN10)
+ expect_layeronly(AppCompatData, "256Color", expect_flags);
+ else
+ ok(!memcmp(AppCompatData, &empty_result, sizeof(empty_result)),
"Expected result to be empty\n");
+ }
+ }
+
+
+ if (AppCompatData && AppCompatData != &Query)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, AppCompatData);
+
+ FreeEnvironmentStringsW(Environment);
+ DestroyEnvironmentBlock(DuplicatedEnv);
+ NtClose(FileHandle);
+}
+
+
+START_TEST(env)
+{
+ WCHAR szApphelp[MAX_PATH];
+ ShimData_QueryOffset QueryOffset;
+ DWORD ShimDataType;
+ NTSTATUS ExceptionStatus = STATUS_SUCCESS;
+
+ SetEnvironmentVariable("SHIM_DEBUG_LEVEL", "127");
+ SetEnvironmentVariable("SHIMENG_DEBUG_LEVEL", "127");
+
+ //silence_debug_output();
+
+ hdll = LoadLibraryA("apphelp.dll");
+
+
+
+ g_WinVersion = get_host_winver();
+ g_ModuleVersion = get_module_version(hdll);
+ trace("Detected host: 0x%x, module: 0x%x\n", g_WinVersion,
g_ModuleVersion);
+
+ GetModuleFileNameW(hdll, szApphelp, _countof(szApphelp));
+
+
+ pSdbGetMatchingExe = (void*)GetProcAddress(hdll, "SdbGetMatchingExe");
+ pSdbInitDatabase = (void*)GetProcAddress(hdll, "SdbInitDatabase");
+ pSdbReleaseDatabase = (void*)GetProcAddress(hdll, "SdbReleaseDatabase");
+ pSdbTagRefToTagID = (void*)GetProcAddress(hdll, "SdbTagRefToTagID");
+ pSdbGetTagFromTagID = (void*)GetProcAddress(hdll, "SdbGetTagFromTagID");
+ pSdbGetLayerTagRef = (void*)GetProcAddress(hdll, "SdbGetLayerTagRef");
+
+ switch (g_ModuleVersion)
+ {
+ case WINVER_WIN7:
+ pApphelpCheckRunAppEx_w7 = (void*)GetProcAddress(hdll,
"ApphelpCheckRunAppEx");
+ break;
+ case WINVER_WIN10:
+ pApphelpCheckRunAppEx_w10 = (void*)GetProcAddress(hdll,
"ApphelpCheckRunAppEx");
+ break;
+ default:
+ skip("Unknown apphelp.dll version %x, cannot determine which
ApphelpCheckRunApp(Ex) function to use\n", g_ModuleVersion);
+ break;
+ }
+
+ pSdbPackAppCompatData = (void*)GetProcAddress(hdll,
"SdbPackAppCompatData");
+ pSdbUnpackAppCompatData = (void*)GetProcAddress(hdll,
"SdbUnpackAppCompatData");
+ pSdbGetAppCompatDataSize = (void*)GetProcAddress(hdll,
"SdbGetAppCompatDataSize");
+
+
+ memset(&QueryOffset, 0, sizeof(QueryOffset));
+ QueryOffset.dwMagic_2k3 = QueryOffset.dwMagic_7_10 = QueryOffset.dwMagic_10_v2 =
SHIMDATA_MAGIC;
+ QueryOffset.dwSize_2k3 = 1;
+ QueryOffset.dwSize_7_10 = 2;
+ QueryOffset.dwSize_10_v2 = 3;
+
+ g_ShimDataSize = g_WinVersion < WINVER_WIN10 ? 4096 : 8192;
+ _SEH2_TRY
+ {
+ ShimDataType = pSdbGetAppCompatDataSize(&QueryOffset);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ ExceptionStatus = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ ok(ExceptionStatus == STATUS_SUCCESS, "Exception 0x%08x, expected
0x%08x\n", ExceptionStatus, STATUS_SUCCESS);
+ if (ExceptionStatus != STATUS_SUCCESS)
+ {
+ skip("SdbGetAppCompatDataSize not functional\n");
+ return;
+ }
+
+ if (g_WinVersion == WINVER_WIN10 && ShimDataType == 3)
+ g_ShimDataSize = 4096;
+
+ if (g_WinVersion == g_ModuleVersion)
+ {
+ Test_layers(szApphelp);
+ Test_repeatlayer(szApphelp);
+ }
+ else
+ {
+ skip("Tests requiring process launch, reported OS version (0x%x) does not
match apphelp version (0x%x)\n", g_WinVersion, g_ModuleVersion);
+ }
+
+ {
+ Test_GetMatchingExe();
+ }
+
+ Test_ApphelpCheckRunApp(szApphelp);
+ if (g_LayerDB)
+ pSdbReleaseDatabase(g_LayerDB);
+}
+
Propchange: trunk/rostests/apitests/apphelp/env.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/rostests/apitests/apphelp/testlist.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/apphelp/testlist…
==============================================================================
--- trunk/rostests/apitests/apphelp/testlist.c [iso-8859-1] (original)
+++ trunk/rostests/apitests/apphelp/testlist.c [iso-8859-1] Sat Jun 10 20:31:58 2017
@@ -5,12 +5,14 @@
extern void func_apphelp(void);
extern void func_db(void);
+extern void func_env(void);
extern void func_layerapi(void);
const struct test winetest_testlist[] =
{
{ "apphelp", func_apphelp },
{ "db", func_db },
+ { "env", func_env },
{ "layerapi", func_layerapi },
{ 0, 0 }
};