[KERNEL32_APITEST] -Add tests for FindActCtxSectionStringW.
authorGiannis Adamopoulos <gadamopoulos@reactos.org>
Fri, 6 Jan 2017 18:48:15 +0000 (18:48 +0000)
committerGiannis Adamopoulos <gadamopoulos@reactos.org>
Fri, 6 Jan 2017 18:48:15 +0000 (18:48 +0000)
svn path=/trunk/; revision=73505

rostests/apitests/kernel32/CMakeLists.txt
rostests/apitests/kernel32/FindActCtxSectionStringW.c [new file with mode: 0644]
rostests/apitests/kernel32/classtest.manifest [new file with mode: 0644]
rostests/apitests/kernel32/comctl32dep.manifest [new file with mode: 0644]
rostests/apitests/kernel32/dep1.manifest [new file with mode: 0644]
rostests/apitests/kernel32/deptest.manifest [new file with mode: 0644]
rostests/apitests/kernel32/testlist.c

index 3965712..d371ca1 100644 (file)
@@ -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 (file)
index 0000000..dbe8ec1
--- /dev/null
@@ -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 <stdarg.h>
+#include <stdio.h>
+
+#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 <pshpack1.h>
+
+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 <poppack.h>
+
+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 (file)
index 0000000..9f0856c
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">\r
+  <assemblyIdentity type="win32" name="ReactOS-TestLib" version="2.2.2.2" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df"/>\r
+  <file name="testlib.dll">\r
+    <windowClass>Button</windowClass>\r
+    <windowClass>ButtonListBox</windowClass>\r
+    <windowClass>ComboBoxEx32</windowClass>\r
+    <windowClass>ComboLBox</windowClass>\r
+    <windowClass>Combobox</windowClass>\r
+  </file>\r
+</assembly>\r
diff --git a/rostests/apitests/kernel32/comctl32dep.manifest b/rostests/apitests/kernel32/comctl32dep.manifest
new file mode 100644 (file)
index 0000000..0da554f
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">\r
+<dependency>\r
+    <dependentAssembly>\r
+        <assemblyIdentity\r
+            type="win32"\r
+            name="Microsoft.Windows.Common-Controls"\r
+            version="6.0.0.0"\r
+            publicKeyToken="6595b64144ccf1df"\r
+            processorArchitecture="*"\r
+            language="*"\r
+        />\r
+    </dependentAssembly>\r
+</dependency>\r
+</assembly>
\ No newline at end of file
diff --git a/rostests/apitests/kernel32/dep1.manifest b/rostests/apitests/kernel32/dep1.manifest
new file mode 100644 (file)
index 0000000..726a4f2
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">\r
+  <assemblyIdentity type="win32" name="dep1" version="0.4.4.0" processorArchitecture="x86" />\r
+  <file name="dep1.dll"/>\r
+</assembly>\r
diff --git a/rostests/apitests/kernel32/deptest.manifest b/rostests/apitests/kernel32/deptest.manifest
new file mode 100644 (file)
index 0000000..0e4103d
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">\r
+  <assemblyIdentity type="win32" name="ReactOS-deptest" version="1.0.0.0"/>\r
+  <dependency>\r
+          <dependentAssembly>\r
+              <assemblyIdentity\r
+                  type="win32"\r
+                  name="dep1"\r
+                  version="0.4.4.0" \r
+                  processorArchitecture="x86"\r
+                  />\r
+          </dependentAssembly>\r
+  </dependency>  \r
+  <file name="deptest.dll"/>\r
+</assembly>\r
index 3673c06..37e46bc 100644 (file)
@@ -4,6 +4,7 @@
 #include <apitest.h>
 
 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 },