2017-01-06 18:48:15 +00:00
/*
* 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
*/
2017-12-13 12:48:26 +00:00
# include "precomp.h"
2017-01-06 18:48:15 +00:00
# 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 */
2021-09-13 01:33:14 +00:00
ULONG module_len ;
2017-01-06 18:48:15 +00:00
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 )
{
2017-01-06 22:06:53 +00:00
ACTCTXW ActCtx = { sizeof ( ACTCTX ) } ;
2017-01-06 18:48:15 +00:00
HANDLE h ;
2017-01-06 22:06:53 +00:00
WCHAR buffer [ MAX_PATH ] , * separator ;
ok ( GetModuleFileNameW ( NULL , buffer , MAX_PATH ) , " GetModuleFileName failed \n " ) ;
separator = wcsrchr ( buffer , L ' \\ ' ) ;
if ( separator )
wcscpy ( separator + 1 , FileName ) ;
ActCtx . lpSource = buffer ;
2017-01-06 18:48:15 +00:00
SetLastError ( 0xdeaddead ) ;
h = CreateActCtxW ( & ActCtx ) ;
2017-01-17 23:11:11 +00:00
ok_ ( __FILE__ , line ) ( h ! = INVALID_HANDLE_VALUE , " CreateActCtx failed for %S \n " , FileName ) ;
2021-09-13 01:33:14 +00:00
// In win10 last error is unchanged and in win2k3 it is ERROR_BAD_EXE_FORMAT
2017-01-17 23:11:11 +00:00
ok_ ( __FILE__ , line ) ( GetLastError ( ) = = ERROR_BAD_EXE_FORMAT | | GetLastError ( ) = = 0xdeaddead , " Wrong last error %lu \n " , GetLastError ( ) ) ;
2017-01-06 18:48:15 +00:00
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 ( ) ) ;
}
2017-01-17 23:11:11 +00:00
void TestClassRedirection ( HANDLE h , LPCWSTR ClassToTest , LPCWSTR ExpectedClassPart , LPCWSTR ExpectedModule , ULONG ExpectedClassCount )
2017-01-06 18:48:15 +00:00
{
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 ( ) ) ;
2021-09-13 01:33:14 +00:00
2017-01-06 20:43:58 +00:00
ok ( KeyedData . ulDataFormatVersion = = 1 , " Wrong format version: %lu \n " , KeyedData . ulDataFormatVersion ) ;
2017-01-06 18:48:15 +00:00
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 ;
2021-09-13 01:33:14 +00:00
2017-01-06 20:43:58 +00:00
if ( res = = FALSE | | KeyedData . ulDataFormatVersion ! = 1 | | header = = NULL | | classData = = NULL )
{
skip ( " Can't read data for class. Skipping \n " ) ;
}
else
{
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 - > module_len = = wcslen ( ExpectedModule ) * 2 , " Got name len %lu, expected %d \n " , classData - > module_len , wcslen ( ExpectedModule ) * 2 ) ;
ok ( wcscmp ( ClassLib , ExpectedModule ) = = 0 , " Got %S, expected %S \n " , ClassLib , ExpectedModule ) ;
2017-01-17 23:11:11 +00:00
/* compare only if VersionedClass starts with ExpectedClassPart */
ok ( memcmp ( VersionedClass , ExpectedClassPart , sizeof ( WCHAR ) * wcslen ( ExpectedClassPart ) ) = = 0 , " Expected %S to start with %S \n " , VersionedClass , ExpectedClassPart ) ;
2017-01-06 20:43:58 +00:00
}
2017-01-06 18:48:15 +00:00
}
VOID TestLibDependency ( HANDLE h )
{
ACTCTX_SECTION_KEYED_DATA KeyedData = { 0 } ;
BOOL res ;
struct strsection_header * SectionHeader ;
struct dllredirect_data * redirData ;
2021-09-13 01:33:14 +00:00
struct assemply_data * assemplyData ;
2017-01-06 18:48:15 +00:00
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 ( ) ) ;
2021-09-13 01:33:14 +00:00
2017-01-06 18:48:15 +00:00
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 ;
2017-01-06 20:43:58 +00:00
if ( res = = FALSE | | KeyedData . ulDataFormatVersion ! = 1 | | SectionHeader = = NULL | | redirData = = NULL )
2017-01-06 18:48:15 +00:00
{
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 ) ) ;
2021-09-13 01:33:14 +00:00
ok ( SectionHeader - > count = = 2 , " %lu \n " , SectionHeader - > count ) ; /* 2 dlls? */
2017-01-06 18:48:15 +00:00
ok ( redirData - > size = = sizeof ( * redirData ) , " Got %lu instead of %d \n " , redirData - > size , sizeof ( * redirData ) ) ;
}
2021-09-13 01:33:14 +00:00
2017-01-06 18:48:15 +00:00
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 ; ;
2017-01-06 20:43:58 +00:00
if ( res = = FALSE | | KeyedData . ulDataFormatVersion ! = 1 | | SectionHeader = = NULL | | assemplyData = = NULL )
2017-01-06 18:48:15 +00:00
{
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 ;
2021-09-13 01:33:14 +00:00
2017-01-06 18:48:15 +00:00
ok ( SectionHeader - > magic = = STRSECTION_MAGIC , " %lu \n " , SectionHeader - > magic ) ;
ok ( SectionHeader - > size = = sizeof ( * SectionHeader ) , " Got %lu instead of %d \n " , SectionHeader - > size , sizeof ( * SectionHeader ) ) ;
2021-09-13 01:33:14 +00:00
ok ( SectionHeader - > count = = 2 , " %lu \n " , SectionHeader - > count ) ; /* 2 dlls? */
2017-01-06 18:48:15 +00:00
2021-09-13 01:33:14 +00:00
data_lenght = assemplyData - > size +
assemplyData - > ulEncodedAssemblyIdentityLength +
2017-01-06 18:48:15 +00:00
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 ) ;
2021-09-13 01:33:14 +00:00
2017-01-06 18:48:15 +00:00
/* Use AssemblyDetailedInformationInActivationContext so as to infer the contents of assemplyData */
2021-09-13 01:33:14 +00:00
res = QueryActCtxW ( 0 , h , & KeyedData . ulAssemblyRosterIndex ,
AssemblyDetailedInformationInActivationContext ,
2017-01-06 18:48:15 +00:00
& 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 " ) ;
2021-09-13 01:33:14 +00:00
}
2017-01-06 18:48:15 +00:00
}
START_TEST ( FindActCtxSectionStringW )
{
2017-02-10 00:00:28 +00:00
HANDLE h , h2 ;
ULONG_PTR cookie , cookie2 ;
2017-01-06 18:48:15 +00:00
/*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 " ) ;
2021-09-13 01:33:14 +00:00
2017-01-06 18:48:15 +00:00
/* Class redirection tests */
h = _CreateActCtxFromFile ( L " classtest.manifest " , __LINE__ ) ;
2017-01-06 21:25:53 +00:00
if ( h ! = INVALID_HANDLE_VALUE )
2017-01-06 21:13:46 +00:00
{
_ActivateCtx ( h , & cookie , __LINE__ ) ;
TestClassRedirection ( h , L " Button " , L " 2.2.2.2!Button " , L " testlib.dll " , 5 ) ;
2017-02-10 00:00:28 +00:00
_ActivateCtx ( NULL , & cookie2 , __LINE__ ) ;
TestClassRedirection ( NULL , L " Button " , L " Button " , L " comctl32.dll " , 27 ) ;
_DeactivateCtx ( cookie2 , __LINE__ ) ;
2017-01-06 21:13:46 +00:00
_DeactivateCtx ( cookie , __LINE__ ) ;
}
else
{
skip ( " Failed to create context for classtest.manifest \n " ) ;
}
2021-09-13 01:33:14 +00:00
2017-02-10 00:00:28 +00:00
/* Class redirection tests with multiple contexts in the activation stack */
h2 = _CreateActCtxFromFile ( L " classtest2.manifest " , __LINE__ ) ;
if ( h ! = INVALID_HANDLE_VALUE & & h2 ! = INVALID_HANDLE_VALUE )
{
_ActivateCtx ( h , & cookie , __LINE__ ) ;
_ActivateCtx ( h2 , & cookie2 , __LINE__ ) ;
TestClassRedirection ( NULL , L " Button " , L " Button " , L " comctl32.dll " , 27 ) ;
TestClassRedirection ( h2 , L " MyClass " , L " 1.1.1.1!MyClass " , L " testlib.dll " , 5 ) ;
_DeactivateCtx ( cookie2 , __LINE__ ) ;
TestClassRedirection ( h , L " Button " , L " 2.2.2.2!Button " , L " testlib.dll " , 5 ) ;
_DeactivateCtx ( cookie , __LINE__ ) ;
}
else
{
skip ( " Failed to create context for classtest.manifest \n " ) ;
}
2017-01-06 18:48:15 +00:00
/* Dependency tests */
h = _CreateActCtxFromFile ( L " deptest.manifest " , __LINE__ ) ;
2017-01-06 21:25:53 +00:00
if ( h ! = INVALID_HANDLE_VALUE )
2017-01-06 21:13:46 +00:00
{
_ActivateCtx ( h , & cookie , __LINE__ ) ;
TestLibDependency ( h ) ;
_DeactivateCtx ( cookie , __LINE__ ) ;
}
else
{
skip ( " Failed to create context for deptest.manifest \n " ) ;
2021-09-13 01:33:14 +00:00
}
2017-01-06 18:48:15 +00:00
/* Activate a context that depends on comctl32 v6 and run class tests again */
h = _CreateActCtxFromFile ( L " comctl32dep.manifest " , __LINE__ ) ;
2017-01-06 21:25:53 +00:00
if ( h ! = INVALID_HANDLE_VALUE )
2017-01-06 21:13:46 +00:00
{
_ActivateCtx ( h , & cookie , __LINE__ ) ;
2017-01-17 23:11:11 +00:00
TestClassRedirection ( h , L " Button " , L " 6.0. " , L " comctl32.dll " , 29 ) ;
2017-01-06 21:13:46 +00:00
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__ ) ;
}
else
{
skip ( " Failed to create context for comctl32dep.manifest \n " ) ;
}
2017-01-06 18:48:15 +00:00
}