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