From 2bebddf5ee0d9856668e4cc7221cd3e61fc6e1c3 Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Fri, 6 Jan 2017 18:48:15 +0000 Subject: [PATCH] [KERNEL32_APITEST] -Add tests for FindActCtxSectionStringW. svn path=/trunk/; revision=73505 --- rostests/apitests/kernel32/CMakeLists.txt | 14 +- .../kernel32/FindActCtxSectionStringW.c | 286 ++++++++++++++++++ rostests/apitests/kernel32/classtest.manifest | 11 + .../apitests/kernel32/comctl32dep.manifest | 15 + rostests/apitests/kernel32/dep1.manifest | 5 + rostests/apitests/kernel32/deptest.manifest | 15 + rostests/apitests/kernel32/testlist.c | 2 + 7 files changed, 347 insertions(+), 1 deletion(-) create mode 100644 rostests/apitests/kernel32/FindActCtxSectionStringW.c create mode 100644 rostests/apitests/kernel32/classtest.manifest create mode 100644 rostests/apitests/kernel32/comctl32dep.manifest create mode 100644 rostests/apitests/kernel32/dep1.manifest create mode 100644 rostests/apitests/kernel32/deptest.manifest diff --git a/rostests/apitests/kernel32/CMakeLists.txt b/rostests/apitests/kernel32/CMakeLists.txt index 3965712e307..d371ca1052e 100644 --- a/rostests/apitests/kernel32/CMakeLists.txt +++ b/rostests/apitests/kernel32/CMakeLists.txt @@ -1,6 +1,7 @@ list(APPEND SOURCE dosdev.c + FindActCtxSectionStringW.c FindFiles.c GetComputerNameEx.c GetCurrentDirectory.c @@ -22,5 +23,16 @@ list(APPEND SOURCE add_executable(kernel32_apitest ${SOURCE}) target_link_libraries(kernel32_apitest wine ${PSEH_LIB}) set_module_type(kernel32_apitest win32cui) -add_importlibs(kernel32_apitest advapi32 gdi32 user32 shlwapi msvcrt kernel32 ntdll) +add_delay_importlibs(kernel32_apitest advapi32 shlwapi) +add_importlibs(kernel32_apitest msvcrt kernel32 ntdll) add_cd_file(TARGET kernel32_apitest DESTINATION reactos/bin FOR all) + +list(APPEND MANIFEST_FILES + classtest.manifest + comctl32dep.manifest + dep1.manifest + deptest.manifest) + +foreach(item ${MANIFEST_FILES}) + add_cd_file(FILE "${CMAKE_CURRENT_SOURCE_DIR}/${item}" DESTINATION reactos/bin FOR all) +endforeach(item) diff --git a/rostests/apitests/kernel32/FindActCtxSectionStringW.c b/rostests/apitests/kernel32/FindActCtxSectionStringW.c new file mode 100644 index 00000000000..dbe8ec115d6 --- /dev/null +++ b/rostests/apitests/kernel32/FindActCtxSectionStringW.c @@ -0,0 +1,286 @@ +/* + * Unit test suite for virtual substituted drive functions. + * + * Copyright 2017 Giannis Adamopoulos + * + * 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 +#include + +#include "wine/test.h" +#include "windef.h" +#include "winbase.h" +#include "winerror.h" + +#define STRSECTION_MAGIC 0x64487353 /* dHsS */ + +struct strsection_header +{ + DWORD magic; + ULONG size; + DWORD unk1[3]; + ULONG count; + ULONG index_offset; + DWORD unk2[2]; + ULONG global_offset; + ULONG global_len; +}; + +struct wndclass_redirect_data +{ + ULONG size; + DWORD res; + ULONG name_len; + ULONG name_offset; /* versioned name offset */ + ULONG module_len; + ULONG module_offset; /* container name offset to the section base */ +}; + +struct dllredirect_data +{ + ULONG size; + ULONG unk; + DWORD res[3]; +}; + +#include + +struct assemply_data +{ + ULONG size; + DWORD ulFlags; + DWORD ulEncodedAssemblyIdentityLength; + DWORD ulEncodedAssemblyIdentityOffset; /* offset to the section base */ + DWORD ulManifestPathType; + DWORD ulManifestPathLength; + DWORD ulManifestPathOffset; /* offset to the section base */ + LARGE_INTEGER liManifestLastWriteTime; + DWORD unk3[11]; + DWORD ulAssemblyDirectoryNameLength; + DWORD ulAssemblyDirectoryNameOffset; /* offset to the section base */ + DWORD unk4[3]; /* In win10 there are two more fields */ +}; + +#include + +HANDLE _CreateActCtxFromFile(LPCWSTR FileName, int line) +{ + ACTCTXW ActCtx = {sizeof(ACTCTX), 0, FileName}; + HANDLE h; + + SetLastError(0xdeaddead); + h = CreateActCtxW(&ActCtx); + ok_(__FILE__, line)(h != INVALID_HANDLE_VALUE, "CreateActCtx failed\n"); + // In win10 last error is unchanged and in win2k3 it is ERROR_BAD_EXE_FORMAT + ok_(__FILE__, line)(GetLastError() == ERROR_BAD_EXE_FORMAT, "Wrong last error. Expected %d, got %lu\n", ERROR_BAD_EXE_FORMAT, GetLastError()); + + return h; +} + +VOID _ActivateCtx(HANDLE h, ULONG_PTR *cookie, int line) +{ + BOOL res; + + SetLastError(0xdeaddead); + res = ActivateActCtx(h, cookie); + ok_(__FILE__, line)(res == TRUE, "ActivateActCtx failed\n"); + ok_(__FILE__, line)(GetLastError() == 0xdeaddead, "Wrong last error. Expected %lu, got %lu\n", (DWORD)(0xdeaddead), GetLastError()); +} + +VOID _DeactivateCtx(ULONG_PTR cookie, int line) +{ + BOOL res; + + SetLastError(0xdeaddead); + res = DeactivateActCtx(0, cookie); + ok_(__FILE__, line)(res == TRUE, "DeactivateActCtx failed\n"); + ok_(__FILE__, line)(GetLastError() == 0xdeaddead, "Wrong last error. Expected %lu, got %lu\n", (DWORD)(0xdeaddead), GetLastError()); +} + +void TestClassRedirection(HANDLE h, LPCWSTR ClassToTest, LPCWSTR ExpectedClassName, LPCWSTR ExpectedModule, ULONG ExpectedClassCount) +{ + ACTCTX_SECTION_KEYED_DATA KeyedData = { 0 }; + BOOL res; + struct strsection_header *header; + struct wndclass_redirect_data *classData; + LPCWSTR VersionedClass, ClassLib; + int data_lenght; + + SetLastError(0xdeaddead); + KeyedData.cbSize = sizeof(KeyedData); + res = FindActCtxSectionStringW(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, + NULL, + ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, + ClassToTest, + &KeyedData); + ok(res == TRUE, "FindActCtxSectionString failed\n"); + ok(GetLastError() == 0xdeaddead, "Wrong last error. Expected %lu, got %lu\n", (DWORD)(0xdeaddead), GetLastError()); + + ok(KeyedData.ulDataFormatVersion == 1, "Wrong format version: %lu", KeyedData.ulDataFormatVersion); + ok(KeyedData.hActCtx == h, "Wrong handle\n"); + ok(KeyedData.lpSectionBase != NULL, "Expected non null lpSectionBase\n"); + ok(KeyedData.lpData != NULL, "Expected non null lpData\n"); + header = (struct strsection_header*)KeyedData.lpSectionBase; + classData = (struct wndclass_redirect_data*)KeyedData.lpData; + + ok(header->magic == STRSECTION_MAGIC, "%lu\n", header->magic ); + ok(header->size == sizeof(*header), "Got %lu instead of %d\n", header->size, sizeof(*header)); + ok(header->count == ExpectedClassCount, "Expected %lu classes, got %lu\n", ExpectedClassCount, header->count ); + + VersionedClass = (WCHAR*)((BYTE*)classData + classData->name_offset); + ClassLib = (WCHAR*)((BYTE*)header + classData->module_offset); + data_lenght = classData->size + classData->name_len + classData->module_len + 2*sizeof(WCHAR); + ok(KeyedData.ulLength == data_lenght, "Got lenght %lu instead of %d\n", KeyedData.ulLength, data_lenght); + ok(classData->size == sizeof(*classData), "Got %lu instead of %d\n", classData->size, sizeof(*classData)); + ok(classData->res == 0, "Got res %lu\n", classData->res); + ok(classData->name_len == wcslen(ExpectedClassName) * 2, "Got name len %lu, expected %d\n", classData->name_len, wcslen(ExpectedClassName) *2); + ok(classData->module_len == wcslen(ExpectedModule) * 2, "Got name len %lu, expected %d\n", classData->module_len, wcslen(ExpectedModule) *2); + ok(wcscmp(VersionedClass, ExpectedClassName) == 0, "Got %S, expected %S\n", VersionedClass, ExpectedClassName); + ok(wcscmp(ClassLib, ExpectedModule) == 0, "Got %S, expected %S\n", ClassLib, ExpectedModule); +} + +VOID TestLibDependency(HANDLE h) +{ + ACTCTX_SECTION_KEYED_DATA KeyedData = { 0 }; + BOOL res; + struct strsection_header *SectionHeader; + struct dllredirect_data *redirData; + struct assemply_data *assemplyData; + + SetLastError(0xdeaddead); + KeyedData.cbSize = sizeof(KeyedData); + res = FindActCtxSectionStringW(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, + NULL, + ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION, + L"dep1.dll", + &KeyedData); + ok(res == TRUE, "FindActCtxSectionString failed\n"); + ok(GetLastError() == 0xdeaddead, "Wrong last error. Expected %lu, got %lu\n", (DWORD)(0xdeaddead), GetLastError()); + + ok(KeyedData.ulDataFormatVersion == 1, "Wrong format version: %lu", KeyedData.ulDataFormatVersion); + ok(KeyedData.hActCtx == h, "Wrong handle\n"); + ok(KeyedData.lpSectionBase != NULL, "Expected non null lpSectionBase\n"); + ok(KeyedData.lpData != NULL, "Expected non null lpData\n"); + SectionHeader = (struct strsection_header*)KeyedData.lpSectionBase; + redirData = (struct dllredirect_data *)KeyedData.lpData; + + if(res == FALSE || KeyedData.ulDataFormatVersion != 1) + { + skip("Can't read data for dep1.dll. Skipping\n"); + } + else + { + ok(SectionHeader->magic == STRSECTION_MAGIC, "%lu\n", SectionHeader->magic ); + ok(SectionHeader->size == sizeof(*SectionHeader), "Got %lu instead of %d\n", SectionHeader->size, sizeof(*SectionHeader)); + ok(SectionHeader->count == 2, "%lu\n", SectionHeader->count ); /* 2 dlls? */ + ok(redirData->size == sizeof(*redirData), "Got %lu instead of %d\n", redirData->size, sizeof(*redirData)); + } + + SetLastError(0xdeaddead); + KeyedData.cbSize = sizeof(KeyedData); + res = FindActCtxSectionStringW(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, + NULL, + ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION, + L"dep1", + &KeyedData); + ok(res == TRUE, "FindActCtxSectionString failed\n"); + ok(GetLastError() == 0xdeaddead, "Wrong last error. Expected %lu, got %lu\n", (DWORD)(0xdeaddead), GetLastError()); + ok(KeyedData.ulDataFormatVersion == 1, "Wrong format version: %lu", KeyedData.ulDataFormatVersion); + ok(KeyedData.hActCtx == h, "Wrong handle\n"); + ok(KeyedData.lpSectionBase != NULL, "Expected non null lpSectionBase\n"); + ok(KeyedData.lpData != NULL, "Expected non null lpData\n"); + SectionHeader = (struct strsection_header*)KeyedData.lpSectionBase; + assemplyData = (struct assemply_data*)KeyedData.lpData;; + + if(res == FALSE || KeyedData.ulDataFormatVersion != 1) + { + skip("Can't read data for dep1. Skipping\n"); + } + else + { + LPCWSTR AssemblyIdentity, ManifestPath, AssemblyDirectory; + int data_lenght; + DWORD buffer[256]; + PACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION details = (PACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION)buffer; + + ok(SectionHeader->magic == STRSECTION_MAGIC, "%lu\n", SectionHeader->magic ); + ok(SectionHeader->size == sizeof(*SectionHeader), "Got %lu instead of %d\n", SectionHeader->size, sizeof(*SectionHeader)); + ok(SectionHeader->count == 2, "%lu\n", SectionHeader->count ); /* 2 dlls? */ + + data_lenght = assemplyData->size + + assemplyData->ulEncodedAssemblyIdentityLength + + assemplyData->ulManifestPathLength + + assemplyData->ulAssemblyDirectoryNameLength + 2 * sizeof(WCHAR); + ok(assemplyData->size == sizeof(*assemplyData), "Got %lu instead of %d\n", assemplyData->size, sizeof(*assemplyData)); + ok(KeyedData.ulLength == data_lenght, "Got lenght %lu instead of %d\n", KeyedData.ulLength, data_lenght); + + AssemblyIdentity = (WCHAR*)((BYTE*)SectionHeader + assemplyData->ulEncodedAssemblyIdentityOffset); + ManifestPath = (WCHAR*)((BYTE*)SectionHeader + assemplyData->ulManifestPathOffset); + AssemblyDirectory = (WCHAR*)((BYTE*)SectionHeader + assemplyData->ulAssemblyDirectoryNameOffset); + + /* Use AssemblyDetailedInformationInActivationContext so as to infer the contents of assemplyData */ + res = QueryActCtxW(0, h, &KeyedData.ulAssemblyRosterIndex, + AssemblyDetailedInformationInActivationContext, + &buffer, sizeof(buffer), NULL); + ok(res == TRUE, "QueryActCtxW failed\n"); + ok(assemplyData->ulFlags == details->ulFlags, "\n"); + ok(assemplyData->ulEncodedAssemblyIdentityLength == details->ulEncodedAssemblyIdentityLength, "\n"); + ok(assemplyData->ulManifestPathType == details->ulManifestPathType, "\n"); + ok(assemplyData->ulManifestPathLength == details->ulManifestPathLength, "\n"); + ok(assemplyData->ulAssemblyDirectoryNameLength == details->ulAssemblyDirectoryNameLength, "\n"); + ok(assemplyData->liManifestLastWriteTime.QuadPart == details->liManifestLastWriteTime.QuadPart, "\n"); + + ok(wcscmp(ManifestPath, details->lpAssemblyManifestPath) == 0, "Expected path %S, got %S\n", details->lpAssemblyManifestPath, ManifestPath); + ok(wcscmp(AssemblyDirectory, details->lpAssemblyDirectoryName) == 0, "Expected path %S, got %S\n", details->lpAssemblyManifestPath, ManifestPath); + + /* It looks like that AssemblyIdentity isn't null terminated */ + ok(memcmp(AssemblyIdentity, details->lpAssemblyEncodedAssemblyIdentity, assemplyData->ulEncodedAssemblyIdentityLength) == 0, "Got wrong AssemblyIdentity\n"); + } +} + +START_TEST(FindActCtxSectionStringW) +{ + HANDLE h; + ULONG_PTR cookie; + + /*First run the redirection tests without using our own actctx */ + TestClassRedirection(NULL, L"Button", L"Button", L"comctl32.dll", 27); + /* Something activates an activation context that mentions comctl32 but comctl32 is not loaded */ + ok( GetModuleHandleW(L"comctl32.dll") == NULL, "Expected comctl32 not to be loaded\n"); + ok( GetModuleHandleW(L"user32.dll") == NULL, "Expected user32 not to be loaded\n"); + + /* Class redirection tests */ + h = _CreateActCtxFromFile(L"classtest.manifest", __LINE__); + _ActivateCtx(h, &cookie, __LINE__); + TestClassRedirection(h, L"Button", L"2.2.2.2!Button", L"testlib.dll", 5); + _DeactivateCtx(cookie, __LINE__); + + /* Dependency tests */ + h = _CreateActCtxFromFile(L"deptest.manifest", __LINE__); + _ActivateCtx(h, &cookie, __LINE__); + TestLibDependency(h); + _DeactivateCtx(cookie, __LINE__); + + /* Activate a context that depends on comctl32 v6 and run class tests again */ + h = _CreateActCtxFromFile(L"comctl32dep.manifest", __LINE__); + _ActivateCtx(h, &cookie, __LINE__); + TestClassRedirection(h, L"Button", L"6.0.3790.1830!Button", L"comctl32.dll", 29); + ok( GetModuleHandleW(L"comctl32.dll") == NULL, "Expected comctl32 not to be loaded\n"); + ok( GetModuleHandleW(L"user32.dll") == NULL, "Expected user32 not to be loaded\n"); + _DeactivateCtx(cookie, __LINE__); + +} \ No newline at end of file diff --git a/rostests/apitests/kernel32/classtest.manifest b/rostests/apitests/kernel32/classtest.manifest new file mode 100644 index 00000000000..9f0856cfe3d --- /dev/null +++ b/rostests/apitests/kernel32/classtest.manifest @@ -0,0 +1,11 @@ + + + + + Button + ButtonListBox + ComboBoxEx32 + ComboLBox + Combobox + + diff --git a/rostests/apitests/kernel32/comctl32dep.manifest b/rostests/apitests/kernel32/comctl32dep.manifest new file mode 100644 index 00000000000..0da554f8758 --- /dev/null +++ b/rostests/apitests/kernel32/comctl32dep.manifest @@ -0,0 +1,15 @@ + + + + + + + + \ No newline at end of file diff --git a/rostests/apitests/kernel32/dep1.manifest b/rostests/apitests/kernel32/dep1.manifest new file mode 100644 index 00000000000..726a4f2fa2f --- /dev/null +++ b/rostests/apitests/kernel32/dep1.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/rostests/apitests/kernel32/deptest.manifest b/rostests/apitests/kernel32/deptest.manifest new file mode 100644 index 00000000000..0e4103d56a2 --- /dev/null +++ b/rostests/apitests/kernel32/deptest.manifest @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/rostests/apitests/kernel32/testlist.c b/rostests/apitests/kernel32/testlist.c index 3673c06dcea..37e46bc21e2 100644 --- a/rostests/apitests/kernel32/testlist.c +++ b/rostests/apitests/kernel32/testlist.c @@ -4,6 +4,7 @@ #include extern void func_dosdev(void); +extern void func_FindActCtxSectionStringW(void); extern void func_FindFiles(void); extern void func_GetComputerNameEx(void); extern void func_GetCurrentDirectory(void); @@ -24,6 +25,7 @@ extern void func_WideCharToMultiByte(void); const struct test winetest_testlist[] = { { "dosdev", func_dosdev }, + { "FindActCtxSectionStringW", func_FindActCtxSectionStringW }, { "FindFiles", func_FindFiles }, { "GetComputerNameEx", func_GetComputerNameEx }, { "GetCurrentDirectory", func_GetCurrentDirectory },