Commit dfcfc98e authored by Alexandre Julliard's avatar Alexandre Julliard

RtlSetCurrentDirectory_U: store a handle to the current directory

along with its name.
parent 684b65cd
...@@ -617,7 +617,7 @@ static RTL_USER_PROCESS_PARAMETERS *init_user_process_params( size_t info_size ) ...@@ -617,7 +617,7 @@ static RTL_USER_PROCESS_PARAMETERS *init_user_process_params( size_t info_size )
params->AllocationSize = size; params->AllocationSize = size;
/* make sure the strings are valid */ /* make sure the strings are valid */
fix_unicode_string( &params->CurrentDirectoryName, (char *)info_size ); fix_unicode_string( &params->CurrentDirectory.DosPath, (char *)info_size );
fix_unicode_string( &params->DllPath, (char *)info_size ); fix_unicode_string( &params->DllPath, (char *)info_size );
fix_unicode_string( &params->ImagePathName, (char *)info_size ); fix_unicode_string( &params->ImagePathName, (char *)info_size );
fix_unicode_string( &params->CommandLine, (char *)info_size ); fix_unicode_string( &params->CommandLine, (char *)info_size );
...@@ -685,13 +685,13 @@ static BOOL process_init( char *argv[], char **environ ) ...@@ -685,13 +685,13 @@ static BOOL process_init( char *argv[], char **environ )
wine_server_fd_to_handle( 2, GENERIC_WRITE|SYNCHRONIZE, TRUE, &params->hStdError ); wine_server_fd_to_handle( 2, GENERIC_WRITE|SYNCHRONIZE, TRUE, &params->hStdError );
/* <hack: to be changed later on> */ /* <hack: to be changed later on> */
params->CurrentDirectoryName.Length = 3 * sizeof(WCHAR); params->CurrentDirectory.DosPath.Length = 3 * sizeof(WCHAR);
params->CurrentDirectoryName.MaximumLength = RtlGetLongestNtPathLength() * sizeof(WCHAR); params->CurrentDirectory.DosPath.MaximumLength = RtlGetLongestNtPathLength() * sizeof(WCHAR);
params->CurrentDirectoryName.Buffer = RtlAllocateHeap( GetProcessHeap(), 0, params->CurrentDirectoryName.MaximumLength); params->CurrentDirectory.DosPath.Buffer = RtlAllocateHeap( GetProcessHeap(), 0, params->CurrentDirectory.DosPath.MaximumLength);
params->CurrentDirectoryName.Buffer[0] = 'C'; params->CurrentDirectory.DosPath.Buffer[0] = 'C';
params->CurrentDirectoryName.Buffer[1] = ':'; params->CurrentDirectory.DosPath.Buffer[1] = ':';
params->CurrentDirectoryName.Buffer[2] = '\\'; params->CurrentDirectory.DosPath.Buffer[2] = '\\';
params->CurrentDirectoryName.Buffer[3] = '\0'; params->CurrentDirectory.DosPath.Buffer[3] = '\0';
/* </hack: to be changed later on> */ /* </hack: to be changed later on> */
} }
else else
......
...@@ -442,12 +442,13 @@ static WIN16_SUBSYSTEM_TIB *allocate_win16_tib( TDB *pTask ) ...@@ -442,12 +442,13 @@ static WIN16_SUBSYSTEM_TIB *allocate_win16_tib( TDB *pTask )
else tib->exe_name = NULL; else tib->exe_name = NULL;
RtlAcquirePebLock(); RtlAcquirePebLock();
curdir = &NtCurrentTeb()->Peb->ProcessParameters->CurrentDirectoryName; curdir = &NtCurrentTeb()->Peb->ProcessParameters->CurrentDirectory.DosPath;
tib->curdir.MaximumLength = sizeof(tib->curdir_buffer); tib->curdir.DosPath.MaximumLength = sizeof(tib->curdir_buffer);
tib->curdir.Length = min( curdir->Length, tib->curdir.MaximumLength-sizeof(WCHAR) ); tib->curdir.DosPath.Length = min( curdir->Length, tib->curdir.DosPath.MaximumLength-sizeof(WCHAR) );
tib->curdir.Buffer = tib->curdir_buffer; tib->curdir.DosPath.Buffer = tib->curdir_buffer;
memcpy( tib->curdir_buffer, curdir->Buffer, tib->curdir.Length ); tib->curdir.Handle = 0;
tib->curdir_buffer[tib->curdir.Length/sizeof(WCHAR)] = 0; memcpy( tib->curdir_buffer, curdir->Buffer, tib->curdir.DosPath.Length );
tib->curdir_buffer[tib->curdir.DosPath.Length/sizeof(WCHAR)] = 0;
RtlReleasePebLock(); RtlReleasePebLock();
return tib; return tib;
} }
......
...@@ -348,7 +348,7 @@ PRTL_USER_PROCESS_PARAMETERS WINAPI RtlNormalizeProcessParams( RTL_USER_PROCESS_ ...@@ -348,7 +348,7 @@ PRTL_USER_PROCESS_PARAMETERS WINAPI RtlNormalizeProcessParams( RTL_USER_PROCESS_
{ {
if (params && !(params->Flags & PROCESS_PARAMS_FLAG_NORMALIZED)) if (params && !(params->Flags & PROCESS_PARAMS_FLAG_NORMALIZED))
{ {
normalize( params, &params->CurrentDirectoryName.Buffer ); normalize( params, &params->CurrentDirectory.DosPath.Buffer );
normalize( params, &params->DllPath.Buffer ); normalize( params, &params->DllPath.Buffer );
normalize( params, &params->ImagePathName.Buffer ); normalize( params, &params->ImagePathName.Buffer );
normalize( params, &params->CommandLine.Buffer ); normalize( params, &params->CommandLine.Buffer );
...@@ -374,7 +374,7 @@ PRTL_USER_PROCESS_PARAMETERS WINAPI RtlDeNormalizeProcessParams( RTL_USER_PROCES ...@@ -374,7 +374,7 @@ PRTL_USER_PROCESS_PARAMETERS WINAPI RtlDeNormalizeProcessParams( RTL_USER_PROCES
{ {
if (params && (params->Flags & PROCESS_PARAMS_FLAG_NORMALIZED)) if (params && (params->Flags & PROCESS_PARAMS_FLAG_NORMALIZED))
{ {
denormalize( params, &params->CurrentDirectoryName.Buffer ); denormalize( params, &params->CurrentDirectory.DosPath.Buffer );
denormalize( params, &params->DllPath.Buffer ); denormalize( params, &params->DllPath.Buffer );
denormalize( params, &params->ImagePathName.Buffer ); denormalize( params, &params->ImagePathName.Buffer );
denormalize( params, &params->CommandLine.Buffer ); denormalize( params, &params->CommandLine.Buffer );
...@@ -425,7 +425,7 @@ NTSTATUS WINAPI RtlCreateProcessParameters( RTL_USER_PROCESS_PARAMETERS **result ...@@ -425,7 +425,7 @@ NTSTATUS WINAPI RtlCreateProcessParameters( RTL_USER_PROCESS_PARAMETERS **result
RtlAcquirePebLock(); RtlAcquirePebLock();
cur_params = NtCurrentTeb()->Peb->ProcessParameters; cur_params = NtCurrentTeb()->Peb->ProcessParameters;
if (!DllPath) DllPath = &cur_params->DllPath; if (!DllPath) DllPath = &cur_params->DllPath;
if (!CurrentDirectoryName) CurrentDirectoryName = &cur_params->CurrentDirectoryName; if (!CurrentDirectoryName) CurrentDirectoryName = &cur_params->CurrentDirectory.DosPath;
if (!CommandLine) CommandLine = ImagePathName; if (!CommandLine) CommandLine = ImagePathName;
if (!Environment) Environment = cur_params->Environment; if (!Environment) Environment = cur_params->Environment;
if (!WindowTitle) WindowTitle = &empty_str; if (!WindowTitle) WindowTitle = &empty_str;
...@@ -456,7 +456,7 @@ NTSTATUS WINAPI RtlCreateProcessParameters( RTL_USER_PROCESS_PARAMETERS **result ...@@ -456,7 +456,7 @@ NTSTATUS WINAPI RtlCreateProcessParameters( RTL_USER_PROCESS_PARAMETERS **result
/* all other fields are zero */ /* all other fields are zero */
ptr = params + 1; ptr = params + 1;
append_unicode_string( &ptr, CurrentDirectoryName, &params->CurrentDirectoryName ); append_unicode_string( &ptr, CurrentDirectoryName, &params->CurrentDirectory.DosPath );
append_unicode_string( &ptr, DllPath, &params->DllPath ); append_unicode_string( &ptr, DllPath, &params->DllPath );
append_unicode_string( &ptr, ImagePathName, &params->ImagePathName ); append_unicode_string( &ptr, ImagePathName, &params->ImagePathName );
append_unicode_string( &ptr, CommandLine, &params->CommandLine ); append_unicode_string( &ptr, CommandLine, &params->CommandLine );
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "winbase.h" #include "winbase.h"
#include "winreg.h" #include "winreg.h"
#include "winternl.h" #include "winternl.h"
#include "winioctl.h"
#include "wine/unicode.h" #include "wine/unicode.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "wine/library.h" #include "wine/library.h"
...@@ -542,9 +543,9 @@ static ULONG get_full_path_helper(LPCWSTR name, LPWSTR buffer, ULONG size) ...@@ -542,9 +543,9 @@ static ULONG get_full_path_helper(LPCWSTR name, LPWSTR buffer, ULONG size)
RtlAcquirePebLock(); RtlAcquirePebLock();
if (NtCurrentTeb()->Tib.SubSystemTib) /* FIXME: hack */ if (NtCurrentTeb()->Tib.SubSystemTib) /* FIXME: hack */
cd = &((WIN16_SUBSYSTEM_TIB *)NtCurrentTeb()->Tib.SubSystemTib)->curdir; cd = &((WIN16_SUBSYSTEM_TIB *)NtCurrentTeb()->Tib.SubSystemTib)->curdir.DosPath;
else else
cd = &NtCurrentTeb()->Peb->ProcessParameters->CurrentDirectoryName; cd = &NtCurrentTeb()->Peb->ProcessParameters->CurrentDirectory.DosPath;
switch (type = RtlDetermineDosPathNameType_U(name)) switch (type = RtlDetermineDosPathNameType_U(name))
{ {
...@@ -855,9 +856,9 @@ NTSTATUS WINAPI RtlGetCurrentDirectory_U(ULONG buflen, LPWSTR buf) ...@@ -855,9 +856,9 @@ NTSTATUS WINAPI RtlGetCurrentDirectory_U(ULONG buflen, LPWSTR buf)
RtlAcquirePebLock(); RtlAcquirePebLock();
if (NtCurrentTeb()->Tib.SubSystemTib) /* FIXME: hack */ if (NtCurrentTeb()->Tib.SubSystemTib) /* FIXME: hack */
us = &((WIN16_SUBSYSTEM_TIB *)NtCurrentTeb()->Tib.SubSystemTib)->curdir; us = &((WIN16_SUBSYSTEM_TIB *)NtCurrentTeb()->Tib.SubSystemTib)->curdir.DosPath;
else else
us = &NtCurrentTeb()->Peb->ProcessParameters->CurrentDirectoryName; us = &NtCurrentTeb()->Peb->ProcessParameters->CurrentDirectory.DosPath;
len = us->Length / sizeof(WCHAR); len = us->Length / sizeof(WCHAR);
if (us->Buffer[len - 1] == '\\' && us->Buffer[len - 2] != ':') if (us->Buffer[len - 1] == '\\' && us->Buffer[len - 2] != ':')
...@@ -884,66 +885,68 @@ NTSTATUS WINAPI RtlGetCurrentDirectory_U(ULONG buflen, LPWSTR buf) ...@@ -884,66 +885,68 @@ NTSTATUS WINAPI RtlGetCurrentDirectory_U(ULONG buflen, LPWSTR buf)
*/ */
NTSTATUS WINAPI RtlSetCurrentDirectory_U(const UNICODE_STRING* dir) NTSTATUS WINAPI RtlSetCurrentDirectory_U(const UNICODE_STRING* dir)
{ {
UNICODE_STRING* curdir; FILE_FS_DEVICE_INFORMATION device_info;
NTSTATUS nts = STATUS_SUCCESS; OBJECT_ATTRIBUTES attr;
ULONG size; UNICODE_STRING newdir;
PWSTR buf = NULL; IO_STATUS_BLOCK io;
CURDIR *curdir;
TRACE("(%s)\n", debugstr_w(dir->Buffer)); HANDLE handle;
NTSTATUS nts;
ULONG size;
PWSTR ptr;
newdir.Buffer = NULL;
RtlAcquirePebLock(); RtlAcquirePebLock();
if (NtCurrentTeb()->Tib.SubSystemTib) /* FIXME: hack */ if (NtCurrentTeb()->Tib.SubSystemTib) /* FIXME: hack */
curdir = &((WIN16_SUBSYSTEM_TIB *)NtCurrentTeb()->Tib.SubSystemTib)->curdir; curdir = &((WIN16_SUBSYSTEM_TIB *)NtCurrentTeb()->Tib.SubSystemTib)->curdir;
else else
curdir = &NtCurrentTeb()->Peb->ProcessParameters->CurrentDirectoryName; curdir = &NtCurrentTeb()->Peb->ProcessParameters->CurrentDirectory;
size = curdir->MaximumLength;
buf = RtlAllocateHeap(GetProcessHeap(), 0, size); if (!RtlDosPathNameToNtPathName_U( dir->Buffer, &newdir, NULL, NULL ))
if (buf == NULL)
{
nts = STATUS_NO_MEMORY;
goto out;
}
size = RtlGetFullPathName_U(dir->Buffer, size, buf, 0);
if (!size)
{ {
nts = STATUS_OBJECT_NAME_INVALID; nts = STATUS_OBJECT_NAME_INVALID;
goto out; goto out;
} }
switch (RtlDetermineDosPathNameType_U(buf)) attr.Length = sizeof(attr);
attr.RootDirectory = 0;
attr.Attributes = OBJ_CASE_INSENSITIVE;
attr.ObjectName = &newdir;
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
nts = NtOpenFile( &handle, 0, &attr, &io, 0, FILE_DIRECTORY_FILE );
if (nts != STATUS_SUCCESS) goto out;
/* don't keep the directory handle open on removable media */
if (!NtQueryVolumeInformationFile( handle, &io, &device_info,
sizeof(device_info), FileFsDeviceInformation ) &&
(device_info.Characteristics & FILE_REMOVABLE_MEDIA))
{ {
case ABSOLUTE_DRIVE_PATH: NtClose( handle );
case UNC_PATH: handle = 0;
break;
default:
FIXME("Don't support those cases yes\n");
nts = STATUS_NOT_IMPLEMENTED;
goto out;
} }
/* FIXME: should check that the directory actually exists, if (curdir->Handle) NtClose( curdir->Handle );
* and fill CurrentDirectoryHandle accordingly curdir->Handle = handle;
*/
/* append trailing \ if missing */ /* append trailing \ if missing */
if (buf[size / sizeof(WCHAR) - 1] != '\\') size = newdir.Length / sizeof(WCHAR);
{ ptr = newdir.Buffer;
buf[size / sizeof(WCHAR)] = '\\'; ptr += 4; /* skip \??\ prefix */
buf[size / sizeof(WCHAR) + 1] = '\0'; size -= 4;
size += sizeof(WCHAR); if (size && ptr[size - 1] != '\\') ptr[size++] = '\\';
}
memmove(curdir->Buffer, buf, size + sizeof(WCHAR)); memcpy( curdir->DosPath.Buffer, ptr, size * sizeof(WCHAR));
curdir->Length = size; curdir->DosPath.Buffer[size] = 0;
curdir->DosPath.Length = size * sizeof(WCHAR);
out: TRACE( "curdir now %s %p\n", debugstr_w(curdir->DosPath.Buffer), curdir->Handle );
if (buf) RtlFreeHeap(GetProcessHeap(), 0, buf);
out:
RtlFreeUnicodeString( &newdir );
RtlReleasePebLock(); RtlReleasePebLock();
return nts; return nts;
} }
...@@ -143,7 +143,7 @@ typedef struct ...@@ -143,7 +143,7 @@ typedef struct
/* the following fields do not exist under Windows */ /* the following fields do not exist under Windows */
UNICODE_STRING exe_str; /* exe name string pointed to by exe_name */ UNICODE_STRING exe_str; /* exe name string pointed to by exe_name */
UNICODE_STRING curdir; /* current directory */ CURDIR curdir; /* current directory */
WCHAR curdir_buffer[MAX_PATH]; WCHAR curdir_buffer[MAX_PATH];
} WIN16_SUBSYSTEM_TIB; } WIN16_SUBSYSTEM_TIB;
......
...@@ -106,8 +106,7 @@ typedef struct _RTL_USER_PROCESS_PARAMETERS ...@@ -106,8 +106,7 @@ typedef struct _RTL_USER_PROCESS_PARAMETERS
HANDLE hStdInput; HANDLE hStdInput;
HANDLE hStdOutput; HANDLE hStdOutput;
HANDLE hStdError; HANDLE hStdError;
UNICODE_STRING CurrentDirectoryName; CURDIR CurrentDirectory;
HANDLE CurrentDirectoryHandle;
UNICODE_STRING DllPath; UNICODE_STRING DllPath;
UNICODE_STRING ImagePathName; UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine; UNICODE_STRING CommandLine;
......
...@@ -329,7 +329,7 @@ static void dump_varargs_startup_info( size_t size ) ...@@ -329,7 +329,7 @@ static void dump_varargs_startup_info( size_t size )
fprintf( stderr, "hStdInput=%p,", params.hStdInput ); fprintf( stderr, "hStdInput=%p,", params.hStdInput );
fprintf( stderr, "hStdOutput=%p,", params.hStdOutput ); fprintf( stderr, "hStdOutput=%p,", params.hStdOutput );
fprintf( stderr, "hStdError=%p,", params.hStdError ); fprintf( stderr, "hStdError=%p,", params.hStdError );
fprintf( stderr, "CurrentDirectoryHandle=%p,", params.CurrentDirectoryHandle ); fprintf( stderr, "CurrentDirectory.Handle=%p,", params.CurrentDirectory.Handle );
fprintf( stderr, "dwX=%ld,", params.dwX ); fprintf( stderr, "dwX=%ld,", params.dwX );
fprintf( stderr, "dwY=%ld,", params.dwY ); fprintf( stderr, "dwY=%ld,", params.dwY );
fprintf( stderr, "dwXSize=%ld,", params.dwXSize ); fprintf( stderr, "dwXSize=%ld,", params.dwXSize );
...@@ -339,8 +339,8 @@ static void dump_varargs_startup_info( size_t size ) ...@@ -339,8 +339,8 @@ static void dump_varargs_startup_info( size_t size )
fprintf( stderr, "dwFillAttribute=%lx,", params.dwFillAttribute ); fprintf( stderr, "dwFillAttribute=%lx,", params.dwFillAttribute );
fprintf( stderr, "dwFlags=%lx,", params.dwFlags ); fprintf( stderr, "dwFlags=%lx,", params.dwFlags );
fprintf( stderr, "wShowWindow=%lx,", params.wShowWindow ); fprintf( stderr, "wShowWindow=%lx,", params.wShowWindow );
fprintf( stderr, "CurrentDirectoryName=L\"" ); fprintf( stderr, "CurrentDirectory.DosPath=L\"" );
dump_inline_unicode_string( &params.CurrentDirectoryName, cur_data, size ); dump_inline_unicode_string( &params.CurrentDirectory.DosPath, cur_data, size );
fprintf( stderr, "\",DllPath=L\"" ); fprintf( stderr, "\",DllPath=L\"" );
dump_inline_unicode_string( &params.DllPath, cur_data, size ); dump_inline_unicode_string( &params.DllPath, cur_data, size );
fprintf( stderr, "\",ImagePathName=L\"" ); fprintf( stderr, "\",ImagePathName=L\"" );
......
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