2017-01-12 11:21:04 +00:00
/*
* PROJECT : ReactOS api tests
* LICENSE : GPLv2 + - See COPYING in the top level directory
* PURPOSE : Test for RtlDosApplyFileIsolationRedirection_Ustr
* PROGRAMMER : Giannis Adamopoulos
*/
2017-12-02 20:05:46 +00:00
# include "precomp.h"
2017-01-12 11:21:04 +00:00
# define ok_eq_hex(value, expected) ok((value) == (expected), #value " = 0x%lx, expected 0x%lx\n", value, expected)
# define ok_eq_pointer(value, expected) ok((value) == (expected), #value " = %p, expected %p\n", value, expected)
2017-01-15 00:42:10 +00:00
# define EXPECT_IN_SAME_DIR (WCHAR*)0xdead
2017-01-12 11:21:04 +00:00
UNICODE_STRING DotDll = RTL_CONSTANT_STRING ( L " .DLL " ) ;
2017-01-15 00:42:10 +00:00
struct test_data
{
int testline ;
NTSTATUS ExpectedStatus ;
WCHAR * Param ;
WCHAR * ExpectedSubString ;
} ;
2018-08-23 12:53:57 +00:00
struct test_data Tests [ ] =
2017-01-12 11:21:04 +00:00
{
2017-01-15 00:42:10 +00:00
/* Not redirected file */
{ __LINE__ , STATUS_SXS_KEY_NOT_FOUND , L " somefilesomefile " , NULL } ,
{ __LINE__ , STATUS_SXS_KEY_NOT_FOUND , L " ntdll.dll " , NULL } ,
/* Files redirected with sxs */
{ __LINE__ , STATUS_SUCCESS , L " GDIPLUS " , L " \\ winsxs \\ x86_microsoft.windows.gdiplus_6595b64144ccf1df_1. " } ,
{ __LINE__ , STATUS_SUCCESS , L " GDIPLUS.DLL " , L " \\ winsxs \\ x86_microsoft.windows.gdiplus_6595b64144ccf1df_1. " } ,
{ __LINE__ , STATUS_SUCCESS , L " COMCTL32.DLL " , L " \\ winsxs \\ x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82 " } ,
{ __LINE__ , STATUS_SUCCESS , L " comctl32.DLL " , L " \\ winsxs \\ x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82 " } ,
{ __LINE__ , STATUS_SUCCESS , L " c: \\ windows \\ system32 \\ comctl32.DLL " , L " \\ winsxs \\ x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82 " } ,
2018-08-23 12:53:57 +00:00
/* Files not redirected with sxs */
{ __LINE__ , STATUS_SXS_KEY_NOT_FOUND , L " MSVCR90.DLL " , NULL } ,
{ __LINE__ , STATUS_SXS_KEY_NOT_FOUND , L " c: \\ windows \\ system32 \\ MSVCR90.DLL " , NULL } ,
2017-10-04 08:10:59 +00:00
/* Files defined in the manifest, one exists, one doesn't */
{ __LINE__ , STATUS_SUCCESS , L " deptest.dll " , EXPECT_IN_SAME_DIR } ,
{ __LINE__ , STATUS_SUCCESS , L " adllfile.dll " , EXPECT_IN_SAME_DIR } ,
/* A file that exists in the same dir but isn't mentioned in the manifest */
{ __LINE__ , STATUS_SUCCESS , L " fil1.txt " , EXPECT_IN_SAME_DIR } ,
2017-01-15 00:42:10 +00:00
/* This is a weird case; the source doesn't exist but does get redirected */
{ __LINE__ , STATUS_SUCCESS , L " c: \\ windows \\ system32 \\ gdiplus.DLL " , L " \\ winsxs \\ x86_microsoft.windows.gdiplus_6595b64144ccf1df_1. " } ,
/* But redirecting gdiplus from a different directory doesn't work */
{ __LINE__ , STATUS_SXS_KEY_NOT_FOUND , L " c: \\ GDIPLUS.DLL " , NULL } ,
{ __LINE__ , STATUS_SXS_KEY_NOT_FOUND , L " c: \\ comctl32.DLL " , NULL } ,
/* Redirection based on .local */
{ __LINE__ , STATUS_SUCCESS , L " test " , EXPECT_IN_SAME_DIR } ,
{ __LINE__ , STATUS_SUCCESS , L " test.dll " , EXPECT_IN_SAME_DIR } ,
{ __LINE__ , STATUS_SUCCESS , L " c: \\ test.dll " , EXPECT_IN_SAME_DIR } ,
/* known dlls are also covered */
{ __LINE__ , STATUS_SUCCESS , L " shell32 " , EXPECT_IN_SAME_DIR } ,
{ __LINE__ , STATUS_SUCCESS , L " shell32.dll " , EXPECT_IN_SAME_DIR } ,
{ __LINE__ , STATUS_SUCCESS , L " c: \\ shell32.dll " , EXPECT_IN_SAME_DIR }
} ;
2017-01-12 11:21:04 +00:00
2017-10-04 08:10:59 +00:00
HANDLE _CreateActCtxFromFile ( LPCWSTR FileName , int line )
{
ACTCTXW ActCtx = { sizeof ( ACTCTX ) } ;
HANDLE h ;
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 ;
SetLastError ( 0xdeaddead ) ;
h = CreateActCtxW ( & ActCtx ) ;
ok_ ( __FILE__ , line ) ( h ! = INVALID_HANDLE_VALUE , " CreateActCtx failed for %S \n " , FileName ) ;
2018-08-23 12:53:57 +00:00
// In win10 last error is unchanged and in win2k3 it is ERROR_BAD_EXE_FORMAT
2017-10-04 08:10:59 +00:00
ok_ ( __FILE__ , line ) ( GetLastError ( ) = = ERROR_BAD_EXE_FORMAT | | GetLastError ( ) = = 0xdeaddead , " Wrong last error %lu \n " , GetLastError ( ) ) ;
return h ;
}
2017-01-15 00:42:10 +00:00
void TestRedirection ( void )
{
WCHAR SystemDir [ MAX_PATH ] ;
WCHAR TestPath [ MAX_PATH ] ;
WCHAR ParameterBuffer [ MAX_PATH ] ;
WCHAR * separator ;
2017-01-12 11:21:04 +00:00
NTSTATUS Status ;
2017-01-15 00:42:10 +00:00
int i ;
2017-01-12 11:21:04 +00:00
2017-01-15 00:42:10 +00:00
GetSystemDirectoryW ( SystemDir , MAX_PATH ) ;
GetModuleFileNameW ( NULL , TestPath , MAX_PATH ) ;
separator = wcsrchr ( TestPath , L ' \\ ' ) ;
separator + + ;
* separator = 0 ;
2017-01-12 11:21:04 +00:00
2017-01-15 00:42:10 +00:00
for ( i = 0 ; i < _countof ( Tests ) ; i + + )
{
UNICODE_STRING OriginalName , DynamicString ;
PUNICODE_STRING StringUsed = NULL ;
if ( memcmp ( Tests [ i ] . Param , L " c: \\ windows \\ system32 " , 38 ) = = 0 )
{
wcscpy ( ParameterBuffer , SystemDir ) ;
wcscat ( ParameterBuffer , & Tests [ i ] . Param [ 19 ] ) ;
}
else
{
wcscpy ( ParameterBuffer , Tests [ i ] . Param ) ;
}
RtlInitUnicodeString ( & OriginalName , ParameterBuffer ) ;
RtlInitEmptyUnicodeString ( & DynamicString , NULL , 0 ) ;
Status = RtlDosApplyFileIsolationRedirection_Ustr ( TRUE ,
& OriginalName ,
& DotDll ,
NULL ,
& DynamicString ,
& StringUsed ,
NULL ,
NULL ,
NULL ) ;
2017-01-15 00:49:47 +00:00
ok ( Status = = Tests [ i ] . ExpectedStatus , " %d: Status 0x%lx, expected 0x%lx \n " , Tests [ i ] . testline , Status , Tests [ i ] . ExpectedStatus ) ;
2017-01-15 00:42:10 +00:00
if ( Tests [ i ] . ExpectedSubString & & DynamicString . Buffer = = NULL )
{
ok ( 0 , " %d: Expected a returned string \n " , Tests [ i ] . testline ) ;
}
if ( Tests [ i ] . ExpectedSubString & & DynamicString . Buffer ! = NULL )
{
if ( Tests [ i ] . ExpectedSubString = = EXPECT_IN_SAME_DIR )
{
ok ( wcsstr ( DynamicString . Buffer , TestPath ) ! = 0 , " %d: Expected string %S in %S \n " , Tests [ i ] . testline , TestPath , DynamicString . Buffer ) ;
}
else
{
RtlDowncaseUnicodeString ( & DynamicString , & DynamicString , FALSE ) ;
ok ( wcsstr ( DynamicString . Buffer , Tests [ i ] . ExpectedSubString ) ! = 0 , " %d: Expected string %S in %S \n " , Tests [ i ] . testline , Tests [ i ] . ExpectedSubString , DynamicString . Buffer ) ;
}
}
}
2017-01-12 11:21:04 +00:00
}
2017-10-04 08:10:59 +00:00
void TestBuffers ( )
{
UNICODE_STRING Param , DynamicString , StaticString ;
PUNICODE_STRING StringUsed = NULL ;
NTSTATUS Status ;
WCHAR buffer [ MAX_PATH ] ;
RtlInitEmptyUnicodeString ( & DynamicString , NULL , 0 ) ;
Status = RtlDosApplyFileIsolationRedirection_Ustr ( TRUE ,
2018-08-23 12:53:57 +00:00
NULL ,
2017-10-04 08:10:59 +00:00
NULL ,
NULL ,
& DynamicString ,
& StringUsed ,
NULL ,
NULL ,
NULL ) ;
ok ( Status = = STATUS_INVALID_PARAMETER , " 0x%lx \n " , Status ) ;
RtlInitEmptyUnicodeString ( & Param , NULL , 0 ) ;
RtlInitEmptyUnicodeString ( & DynamicString , NULL , 0 ) ;
Status = RtlDosApplyFileIsolationRedirection_Ustr ( TRUE ,
2018-08-23 12:53:57 +00:00
& Param ,
NULL ,
2017-10-04 08:10:59 +00:00
NULL ,
& DynamicString ,
& StringUsed ,
NULL ,
NULL ,
NULL ) ;
ok ( Status = = STATUS_SXS_KEY_NOT_FOUND , " 0x%lx \n " , Status ) ;
/* Tests for NULL termination of OriginalName */
Param . MaximumLength = Param . Length = 12 * sizeof ( WCHAR ) ;
Param . Buffer = L " comctl32.dllcrapcrap " ;
RtlInitEmptyUnicodeString ( & DynamicString , NULL , 0 ) ;
Status = RtlDosApplyFileIsolationRedirection_Ustr ( TRUE ,
2018-08-23 12:53:57 +00:00
& Param ,
NULL ,
2017-10-04 08:10:59 +00:00
NULL ,
& DynamicString ,
& StringUsed ,
NULL ,
NULL ,
NULL ) ;
ok ( Status = = STATUS_SUCCESS , " \n " ) ;
/* Tests for the Extension parameter */
RtlInitUnicodeString ( & Param , L " comctl32.dll " ) ;
RtlInitEmptyUnicodeString ( & DynamicString , NULL , 0 ) ;
Status = RtlDosApplyFileIsolationRedirection_Ustr ( TRUE ,
2018-08-23 12:53:57 +00:00
& Param ,
NULL ,
2017-10-04 08:10:59 +00:00
NULL ,
& DynamicString ,
& StringUsed ,
NULL ,
NULL ,
NULL ) ;
ok ( Status = = STATUS_SUCCESS , " \n " ) ;
RtlInitUnicodeString ( & Param , L " comctl32 " ) ;
RtlInitEmptyUnicodeString ( & DynamicString , NULL , 0 ) ;
Status = RtlDosApplyFileIsolationRedirection_Ustr ( TRUE ,
2018-08-23 12:53:57 +00:00
& Param ,
NULL ,
2017-10-04 08:10:59 +00:00
NULL ,
& DynamicString ,
& StringUsed ,
NULL ,
NULL ,
NULL ) ;
ok ( Status = = STATUS_SXS_KEY_NOT_FOUND , " 0x%lx \n " , Status ) ;
RtlInitUnicodeString ( & Param , L " comctl32 " ) ;
RtlInitEmptyUnicodeString ( & DynamicString , NULL , 0 ) ;
Status = RtlDosApplyFileIsolationRedirection_Ustr ( TRUE ,
2018-08-23 12:53:57 +00:00
& Param ,
& DotDll ,
2017-10-04 08:10:59 +00:00
NULL ,
& DynamicString ,
& StringUsed ,
NULL ,
NULL ,
NULL ) ;
ok ( Status = = STATUS_SUCCESS , " \n " ) ;
/* Tests for the DynamicString parameter */
RtlInitUnicodeString ( & Param , L " comctl32.dll " ) ;
RtlInitEmptyUnicodeString ( & DynamicString , NULL , 0 ) ;
Status = RtlDosApplyFileIsolationRedirection_Ustr ( TRUE ,
2018-08-23 12:53:57 +00:00
& Param ,
2017-10-04 08:10:59 +00:00
NULL ,
NULL ,
& DynamicString ,
& StringUsed ,
NULL ,
NULL ,
NULL ) ;
ok ( Status = = STATUS_SUCCESS , " \n " ) ;
ok ( DynamicString . Length > 0 , " \n " ) ;
ok ( DynamicString . MaximumLength = = DynamicString . Length + sizeof ( WCHAR ) , " \n " ) ;
if ( DynamicString . Buffer & & DynamicString . Length )
ok ( wcslen ( DynamicString . Buffer ) * sizeof ( WCHAR ) = = DynamicString . Length , " got %d and %d \n " , wcslen ( DynamicString . Buffer ) * sizeof ( WCHAR ) , DynamicString . Length ) ;
else
ok ( DynamicString . Buffer ! = NULL , " Expected non NULL buffer \n " ) ;
ok ( StringUsed = = & DynamicString , " \n " ) ;
/* Tests for the StaticString parameter */
wcscpy ( buffer , L " comctl32.dll " ) ;
StaticString . Buffer = buffer ;
StaticString . Length = sizeof ( L " comctl32.dll " ) ;
StaticString . MaximumLength = sizeof ( buffer ) ;
Param = StaticString ;
Status = RtlDosApplyFileIsolationRedirection_Ustr ( TRUE ,
2018-08-23 12:53:57 +00:00
& Param ,
NULL ,
2017-10-04 08:10:59 +00:00
& StaticString ,
NULL ,
& StringUsed ,
NULL ,
NULL ,
NULL ) ;
ok ( Status = = STATUS_SXS_KEY_NOT_FOUND , " 0x%lx \n " , Status ) ;
wcscpy ( buffer , L " comctl32.dll " ) ;
StaticString . Buffer = buffer ;
StaticString . Length = sizeof ( L " comctl32.dll " ) ;
StaticString . MaximumLength = sizeof ( buffer ) ;
Status = RtlDosApplyFileIsolationRedirection_Ustr ( TRUE ,
2018-08-23 12:53:57 +00:00
& StaticString ,
NULL ,
2017-10-04 08:10:59 +00:00
& StaticString ,
NULL ,
& StringUsed ,
NULL ,
NULL ,
NULL ) ;
ok ( Status = = STATUS_SXS_KEY_NOT_FOUND , " 0x%lx \n " , Status ) ;
RtlInitUnicodeString ( & Param , L " comctl32.dll " ) ;
RtlInitEmptyUnicodeString ( & StaticString , buffer , sizeof ( buffer ) ) ;
Status = RtlDosApplyFileIsolationRedirection_Ustr ( TRUE ,
2018-08-23 12:53:57 +00:00
& Param ,
NULL ,
2017-10-04 08:10:59 +00:00
& StaticString ,
NULL ,
& StringUsed ,
NULL ,
NULL ,
NULL ) ;
ok ( Status = = STATUS_SUCCESS , " \n " ) ;
ok ( StaticString . Length > 0 , " \n " ) ;
ok ( StaticString . MaximumLength = = sizeof ( buffer ) , " \n " ) ;
if ( StaticString . Buffer & & StaticString . Length )
ok ( wcslen ( StaticString . Buffer ) * sizeof ( WCHAR ) = = StaticString . Length , " got %d and %d \n " , wcslen ( StaticString . Buffer ) * sizeof ( WCHAR ) , StaticString . Length ) ;
else
ok ( StaticString . Length ! = 0 , " Expected non 0 lenght \n " ) ;
ok ( StringUsed = = & StaticString , " \n " ) ;
RtlInitEmptyUnicodeString ( & StaticString , buffer , 5 * sizeof ( WCHAR ) ) ;
Status = RtlDosApplyFileIsolationRedirection_Ustr ( TRUE ,
2018-08-23 12:53:57 +00:00
& Param ,
NULL ,
2017-10-04 08:10:59 +00:00
& StaticString ,
NULL ,
& StringUsed ,
NULL ,
NULL ,
NULL ) ;
ok ( Status = = STATUS_BUFFER_TOO_SMALL , " 0x%lx \n " , Status ) ;
RtlInitUnicodeString ( & Param , L " comctl32.dll " ) ;
RtlInitEmptyUnicodeString ( & StaticString , buffer , sizeof ( buffer ) ) ;
RtlInitEmptyUnicodeString ( & DynamicString , NULL , 0 ) ;
Status = RtlDosApplyFileIsolationRedirection_Ustr ( TRUE ,
2018-08-23 12:53:57 +00:00
& Param ,
NULL ,
2017-10-04 08:10:59 +00:00
& StaticString ,
& DynamicString ,
& StringUsed ,
NULL ,
NULL ,
NULL ) ;
ok ( Status = = STATUS_SUCCESS , " \n " ) ;
ok ( StaticString . Length > 0 , " \n " ) ;
ok ( StaticString . MaximumLength = = sizeof ( buffer ) , " \n " ) ;
if ( StaticString . Buffer & & StaticString . Length )
ok ( wcslen ( StaticString . Buffer ) * sizeof ( WCHAR ) = = StaticString . Length , " got %d and %d \n " , wcslen ( StaticString . Buffer ) * sizeof ( WCHAR ) , StaticString . Length ) ;
else
ok ( StaticString . Length ! = 0 , " Expected non 0 lenght \n " ) ;
ok ( DynamicString . Buffer = = NULL , " \n " ) ;
ok ( DynamicString . Length = = 0 , " \n " ) ;
ok ( DynamicString . MaximumLength = = 0 , " \n " ) ;
ok ( StringUsed = = & StaticString , " \n " ) ;
/* Test a small buffer and a dynamic buffer */
RtlInitUnicodeString ( & Param , L " comctl32.dll " ) ;
RtlInitEmptyUnicodeString ( & StaticString , buffer , 5 * sizeof ( WCHAR ) ) ;
RtlInitEmptyUnicodeString ( & DynamicString , NULL , 0 ) ;
StaticString . Buffer [ 0 ] = 1 ;
Status = RtlDosApplyFileIsolationRedirection_Ustr ( TRUE ,
2018-08-23 12:53:57 +00:00
& Param ,
NULL ,
2017-10-04 08:10:59 +00:00
& StaticString ,
& DynamicString ,
& StringUsed ,
NULL ,
NULL ,
NULL ) ;
ok ( Status = = STATUS_SUCCESS , " \n " ) ;
ok ( StaticString . Buffer = = buffer , " \n " ) ;
ok ( StaticString . Length = = 0 , " %d \n " , StaticString . Length ) ;
ok ( StaticString . Buffer [ 0 ] = = 0 , " \n " ) ;
ok ( StaticString . MaximumLength = = 5 * sizeof ( WCHAR ) , " %d \n " , StaticString . MaximumLength ) ;
ok ( DynamicString . Length > 0 , " \n " ) ;
ok ( DynamicString . MaximumLength = = DynamicString . Length + sizeof ( WCHAR ) , " \n " ) ;
if ( DynamicString . Buffer & & DynamicString . Length )
ok ( wcslen ( DynamicString . Buffer ) * sizeof ( WCHAR ) = = DynamicString . Length , " got %d and %d \n " , wcslen ( DynamicString . Buffer ) * sizeof ( WCHAR ) , DynamicString . Length ) ;
else
ok ( DynamicString . Length ! = 0 , " Expected non 0 lenght \n " ) ;
ok ( StringUsed = = & DynamicString , " \n " ) ;
}
2017-01-12 11:21:04 +00:00
START_TEST ( RtlDosApplyFileIsolationRedirection_Ustr )
{
2017-01-15 11:51:06 +00:00
int argc ;
char * * test_argv ;
argc = winetest_get_mainargs ( & test_argv ) ;
if ( argc > = 3 )
{
2017-10-04 08:10:59 +00:00
HANDLE h = _CreateActCtxFromFile ( L " ntdlltest.manifest " , __LINE__ ) ;
BOOL bactivated = FALSE ;
ULONG_PTR cookie ;
2018-08-23 12:53:57 +00:00
2017-10-04 08:10:59 +00:00
if ( h ! = INVALID_HANDLE_VALUE )
bactivated = ActivateActCtx ( h , & cookie ) ;
2017-01-15 11:51:06 +00:00
TestRedirection ( ) ;
2017-10-04 08:10:59 +00:00
TestBuffers ( ) ;
if ( bactivated )
DeactivateActCtx ( 0 , cookie ) ;
2017-01-15 11:51:06 +00:00
}
else
{
WCHAR TestPath [ MAX_PATH ] ;
WCHAR * separator ;
STARTUPINFOW si = { sizeof ( si ) } ;
PROCESS_INFORMATION pi ;
BOOL created ;
GetModuleFileNameW ( NULL , TestPath , MAX_PATH ) ;
separator = wcsrchr ( TestPath , L ' \\ ' ) ;
separator + + ;
wcscpy ( separator , L " testdata \\ ntdll_apitest.exe RtlDosApplyFileIsolationRedirection_Ustr DoTest " ) ;
2018-08-23 12:53:57 +00:00
2017-01-15 11:51:06 +00:00
created = CreateProcessW ( NULL , TestPath , NULL , NULL , FALSE , 0 , NULL , NULL , & si , & pi ) ;
ok ( created , " Expected CreateProcess to succeed \n " ) ;
if ( created )
{
winetest_wait_child_process ( pi . hProcess ) ;
CloseHandle ( pi . hThread ) ;
CloseHandle ( pi . hProcess ) ;
}
}
2018-08-23 12:53:57 +00:00
}