Commit 7ef35b33 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Reimplement file system redirection using NT pathname comparisons.

parent 8e7c6422
......@@ -2133,16 +2133,21 @@ void init_startup_info(void)
/***********************************************************************
* create_startup_info
*/
void *create_startup_info( const RTL_USER_PROCESS_PARAMETERS *params, DWORD *info_size )
void *create_startup_info( const UNICODE_STRING *nt_image, const RTL_USER_PROCESS_PARAMETERS *params,
DWORD *info_size )
{
startup_info_t *info;
UNICODE_STRING dos_image = *nt_image;
DWORD size;
void *ptr;
dos_image.Buffer = get_dos_path( nt_image->Buffer );
dos_image.Length = nt_image->Length - (dos_image.Buffer - nt_image->Buffer) * sizeof(WCHAR);
size = sizeof(*info);
size += params->CurrentDirectory.DosPath.Length;
size += params->DllPath.Length;
size += params->ImagePathName.Length;
size += dos_image.Length;
size += params->CommandLine.Length;
size += params->WindowTitle.Length;
size += params->Desktop.Length;
......@@ -2172,7 +2177,7 @@ void *create_startup_info( const RTL_USER_PROCESS_PARAMETERS *params, DWORD *inf
ptr = info + 1;
info->curdir_len = append_string( &ptr, params, &params->CurrentDirectory.DosPath );
info->dllpath_len = append_string( &ptr, params, &params->DllPath );
info->imagepath_len = append_string( &ptr, params, &params->ImagePathName );
info->imagepath_len = append_string( &ptr, params, &dos_image );
info->cmdline_len = append_string( &ptr, params, &params->CommandLine );
info->title_len = append_string( &ptr, params, &params->WindowTitle );
info->desktop_len = append_string( &ptr, params, &params->Desktop );
......
......@@ -1105,6 +1105,7 @@ static NTSTATUS CDECL load_so_dll( UNICODE_STRING *nt_name, void **module )
{
static const WCHAR soW[] = {'.','s','o',0};
OBJECT_ATTRIBUTES attr;
UNICODE_STRING redir;
pe_image_info_t info;
char *unix_name;
NTSTATUS status;
......@@ -1112,7 +1113,13 @@ static NTSTATUS CDECL load_so_dll( UNICODE_STRING *nt_name, void **module )
if (get_load_order( nt_name ) == LO_DISABLED) return STATUS_DLL_NOT_FOUND;
InitializeObjectAttributes( &attr, nt_name, OBJ_CASE_INSENSITIVE, 0, 0 );
if (nt_to_unix_file_name( &attr, &unix_name, NULL, FILE_OPEN )) return STATUS_DLL_NOT_FOUND;
get_redirect( &attr, &redir );
if (nt_to_unix_file_name( &attr, &unix_name, FILE_OPEN ))
{
free( redir.Buffer );
return STATUS_DLL_NOT_FOUND;
}
/* remove .so extension from Windows name */
len = nt_name->Length / sizeof(WCHAR);
......@@ -1120,6 +1127,7 @@ static NTSTATUS CDECL load_so_dll( UNICODE_STRING *nt_name, void **module )
status = dlopen_dll( unix_name, nt_name, module, &info, FALSE );
free( unix_name );
free( redir.Buffer );
return status;
}
......@@ -1398,8 +1406,7 @@ BOOL is_builtin_path( const UNICODE_STRING *path, WORD *machine )
if (path->Length > wcslen(system_dir) * sizeof(WCHAR) &&
!wcsnicmp( path->Buffer, system_dir, wcslen(system_dir) ))
{
if (NtCurrentTeb64() && NtCurrentTeb64()->TlsSlots[WOW64_TLS_FILESYSREDIR])
*machine = IMAGE_FILE_MACHINE_AMD64;
if (is_wow64) *machine = IMAGE_FILE_MACHINE_AMD64;
goto found;
}
if ((is_win64 || is_wow64) && path->Length > sizeof(wow64W) &&
......@@ -1439,7 +1446,7 @@ static NTSTATUS open_main_image( WCHAR *image, void **module, SECTION_IMAGE_INFO
init_unicode_string( &nt_name, image );
InitializeObjectAttributes( &attr, &nt_name, OBJ_CASE_INSENSITIVE, 0, NULL );
if (nt_to_unix_file_name( &attr, &unix_name, NULL, FILE_OPEN )) return STATUS_DLL_NOT_FOUND;
if (nt_to_unix_file_name( &attr, &unix_name, FILE_OPEN )) return STATUS_DLL_NOT_FOUND;
status = open_dll_file( unix_name, &attr, &mapping );
if (!status)
......@@ -1536,11 +1543,13 @@ NTSTATUS load_start_exe( WCHAR **image, void **module )
{
static const WCHAR startW[] = {'\\','?','?','\\','C',':','\\','w','i','n','d','o','w','s','\\',
's','y','s','t','e','m','3','2','\\','s','t','a','r','t','.','e','x','e',0};
static const WCHAR startwow64W[] = {'\\','?','?','\\','C',':','\\','w','i','n','d','o','w','s','\\',
's','y','s','w','o','w','6','4','\\','s','t','a','r','t','.','e','x','e',0};
UNICODE_STRING nt_name;
NTSTATUS status;
SIZE_T size;
init_unicode_string( &nt_name, startW );
init_unicode_string( &nt_name, is_wow64 ? startwow64W : startW );
status = find_builtin_dll( &nt_name, module, &size, &main_image_info, current_machine, FALSE );
if (status)
{
......
......@@ -267,12 +267,18 @@ static NTSTATUS get_pe_file_info( OBJECT_ATTRIBUTES *attr, HANDLE *handle, pe_im
{
NTSTATUS status;
HANDLE mapping;
IO_STATUS_BLOCK io;
char *unix_name;
*handle = 0;
memset( info, 0, sizeof(*info) );
if ((status = NtOpenFile( handle, GENERIC_READ, attr, &io,
FILE_SHARE_READ | FILE_SHARE_DELETE, FILE_SYNCHRONOUS_IO_NONALERT )))
if (!(status = nt_to_unix_file_name( attr, &unix_name, FILE_OPEN )))
{
status = open_unix_file( handle, unix_name, GENERIC_READ, attr, 0,
FILE_SHARE_READ | FILE_SHARE_DELETE,
FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 );
free( unix_name );
}
if (status)
{
if (is_builtin_path( attr->ObjectName, &info->machine ))
{
......@@ -479,7 +485,7 @@ static NTSTATUS fork_and_exec( OBJECT_ATTRIBUTES *attr, int unixdir,
char *unix_name;
NTSTATUS status;
status = nt_to_unix_file_name( attr, &unix_name, NULL, FILE_OPEN );
status = nt_to_unix_file_name( attr, &unix_name, FILE_OPEN );
if (status) return status;
#ifdef HAVE_PIPE2
......@@ -613,7 +619,7 @@ NTSTATUS WINAPI NtCreateUserProcess( HANDLE *process_handle_ptr, HANDLE *thread_
pe_image_info_t pe_info;
CLIENT_ID id;
HANDLE parent = 0, debug = 0, token = 0;
UNICODE_STRING path = {0};
UNICODE_STRING redir, path = {0};
OBJECT_ATTRIBUTES attr, empty_attr = { sizeof(empty_attr) };
SIZE_T i, attr_count = (ps_attr->TotalLength - sizeof(ps_attr->TotalLength)) / sizeof(PS_ATTRIBUTE);
const PS_ATTRIBUTE *handles_attr = NULL;
......@@ -655,16 +661,19 @@ NTSTATUS WINAPI NtCreateUserProcess( HANDLE *process_handle_ptr, HANDLE *thread_
unixdir = get_unix_curdir( params );
InitializeObjectAttributes( &attr, &path, OBJ_CASE_INSENSITIVE, 0, 0 );
get_redirect( &attr, &redir );
if ((status = get_pe_file_info( &attr, &file_handle, &pe_info )))
{
if (status == STATUS_INVALID_IMAGE_NOT_MZ && !fork_and_exec( &attr, unixdir, params ))
{
memset( info, 0, sizeof(*info) );
free( redir.Buffer );
return STATUS_SUCCESS;
}
goto done;
}
if (!(startup_info = create_startup_info( params, &startup_info_size ))) goto done;
if (!(startup_info = create_startup_info( attr.ObjectName, params, &startup_info_size ))) goto done;
env_size = get_env_size( params, &winedebug );
if ((status = alloc_object_attributes( process_attr, &objattr, &attr_len ))) goto done;
......@@ -830,6 +839,7 @@ done:
if (unixdir != -1) close( unixdir );
free( startup_info );
free( winedebug );
free( redir.Buffer );
return status;
}
......
......@@ -141,7 +141,8 @@ extern struct ldt_copy __wine_ldt_copy DECLSPEC_HIDDEN;
extern void init_environment( int argc, char *argv[], char *envp[] ) DECLSPEC_HIDDEN;
extern void init_startup_info(void) DECLSPEC_HIDDEN;
extern void *create_startup_info( const RTL_USER_PROCESS_PARAMETERS *params, DWORD *info_size ) DECLSPEC_HIDDEN;
extern void *create_startup_info( const UNICODE_STRING *nt_image, const RTL_USER_PROCESS_PARAMETERS *params,
DWORD *info_size ) DECLSPEC_HIDDEN;
extern DWORD ntdll_umbstowcs( const char *src, DWORD srclen, WCHAR *dst, DWORD dstlen ) DECLSPEC_HIDDEN;
extern int ntdll_wcstoumbs( const WCHAR *src, DWORD srclen, char *dst, DWORD dstlen, BOOL strict ) DECLSPEC_HIDDEN;
extern char **build_envp( const WCHAR *envW ) DECLSPEC_HIDDEN;
......@@ -250,8 +251,8 @@ extern NTSTATUS tape_DeviceIoControl( HANDLE device, HANDLE event, PIO_APC_ROUTI
ULONG in_size, void *out_buffer, ULONG out_size ) DECLSPEC_HIDDEN;
extern NTSTATUS errno_to_status( int err ) DECLSPEC_HIDDEN;
extern NTSTATUS nt_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, char **name_ret,
UNICODE_STRING *nt_name, UINT disposition ) DECLSPEC_HIDDEN;
extern BOOL get_redirect( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *redir ) DECLSPEC_HIDDEN;
extern NTSTATUS nt_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, char **name_ret, UINT disposition ) DECLSPEC_HIDDEN;
extern NTSTATUS unix_to_nt_file_name( const char *name, WCHAR **nt ) DECLSPEC_HIDDEN;
extern NTSTATUS get_full_path( const WCHAR *name, const WCHAR *curdir, WCHAR **path ) DECLSPEC_HIDDEN;
extern NTSTATUS open_unix_file( HANDLE *handle, const char *unix_name, ACCESS_MASK access,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment