From: Elizabeth Figura zfigura@codeweavers.com
Since we are essentially adding a flag to get_nt_and_unix_names(), we also pass this flag correctly for other functions, opening the reparse point where the behaviour is implicit: NtQueryAttributesFile(), NtQueryFullAttributesFile(), FileRenameInformation, and FileLinkInformation. --- dlls/ntdll/tests/file.c | 76 ++++++++++++++++------------------ dlls/ntdll/unix/file.c | 63 ++++++++++++++++------------ dlls/ntdll/unix/loader.c | 4 +- dlls/ntdll/unix/process.c | 4 +- dlls/ntdll/unix/registry.c | 2 +- dlls/ntdll/unix/unix_private.h | 2 +- 6 files changed, 77 insertions(+), 74 deletions(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 7016ca166f9..ac7a0dcf3db 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -6270,25 +6270,22 @@ static void test_reparse_points(void)
status = NtCreateFile( &handle2, GENERIC_ALL, &attr, &io, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN_IF, FILE_NON_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT, NULL, 0 ); - todo_wine ok( status == STATUS_FILE_IS_A_DIRECTORY, "got %#lx\n", status ); + ok( status == STATUS_FILE_IS_A_DIRECTORY, "got %#lx\n", status ); status = NtCreateFile( &handle2, GENERIC_ALL, &attr, &io, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN_IF, FILE_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT, NULL, 0 ); - todo_wine ok( !status, "got %#lx\n", status ); - if (!status) - { - status = NtQueryInformationFile( handle2, &io, &tag_info, sizeof(tag_info), FileAttributeTagInformation ); - ok( !status, "got %#lx\n", status ); - todo_wine ok( tag_info.FileAttributes == (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT), - "got attributes %#lx\n", tag_info.FileAttributes ); - todo_wine ok( tag_info.ReparseTag == IO_REPARSE_TAG_MOUNT_POINT, "got tag %#lx\n", tag_info.ReparseTag ); - status = NtQueryInformationFile( handle2, &io, &std_info, sizeof(std_info), FileStandardInformation ); - ok( !status, "got %#lx\n", status ); - ok( !std_info.AllocationSize.QuadPart, "got size %#I64x\n", std_info.AllocationSize.QuadPart ); - ok( !std_info.EndOfFile.QuadPart, "got eof %#I64x\n", std_info.EndOfFile.QuadPart ); - ok( std_info.NumberOfLinks == 1, "got %lu links\n", std_info.NumberOfLinks ); - ok( std_info.Directory == TRUE, "got directory %u\n", std_info.Directory ); - NtClose( handle2 ); - } + ok( !status, "got %#lx\n", status ); + status = NtQueryInformationFile( handle2, &io, &tag_info, sizeof(tag_info), FileAttributeTagInformation ); + ok( !status, "got %#lx\n", status ); + todo_wine ok( tag_info.FileAttributes == (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT), + "got attributes %#lx\n", tag_info.FileAttributes ); + todo_wine ok( tag_info.ReparseTag == IO_REPARSE_TAG_MOUNT_POINT, "got tag %#lx\n", tag_info.ReparseTag ); + status = NtQueryInformationFile( handle2, &io, &std_info, sizeof(std_info), FileStandardInformation ); + ok( !status, "got %#lx\n", status ); + ok( !std_info.AllocationSize.QuadPart, "got size %#I64x\n", std_info.AllocationSize.QuadPart ); + ok( !std_info.EndOfFile.QuadPart, "got eof %#I64x\n", std_info.EndOfFile.QuadPart ); + ok( std_info.NumberOfLinks == 1, "got %lu links\n", std_info.NumberOfLinks ); + ok( std_info.Directory == TRUE, "got directory %u\n", std_info.Directory ); + NtClose( handle2 );
/* alter the target in-place */ data_size = init_reparse_mount_point( &data, L"\??\C:\bogus" ); @@ -6577,34 +6574,31 @@ static void test_reparse_points(void) status = NtOpenFile( &handle2, GENERIC_READ | SYNCHRONIZE, &attr, &io, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN_REPARSE_POINT | FILE_SYNCHRONOUS_IO_NONALERT ); - todo_wine ok( !status, "got %#lx\n", status ); + ok( !status, "got %#lx\n", status );
guid_data2 = malloc( data_size + 1 ); - if (!status) - { - memset( guid_data2, 0xcc, data_size + 1 ); - io.Information = 1; - status = NtFsControlFile( handle2, NULL, NULL, NULL, &io, FSCTL_GET_REPARSE_POINT, NULL, 0, guid_data2, sizeof(REPARSE_GUID_DATA_BUFFER) - 1 ); - ok( status == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", status ); - ok( io.Information == 1, "got size %#Ix\n", io.Information ); - status = NtFsControlFile( handle2, NULL, NULL, NULL, &io, FSCTL_GET_REPARSE_POINT, NULL, 0, guid_data2, data_size - 1); - ok( status == STATUS_BUFFER_OVERFLOW, "got %#lx\n", status ); - ok( io.Information == data_size - 1, "expected size %#Ix, got %#Ix\n", data_size, io.Information ); - ok( !memcmp( guid_data, guid_data2, data_size - 1 ), "buffers didn't match\n" ); + memset( guid_data2, 0xcc, data_size + 1 ); + io.Information = 1; + status = NtFsControlFile( handle2, NULL, NULL, NULL, &io, FSCTL_GET_REPARSE_POINT, NULL, 0, guid_data2, sizeof(REPARSE_GUID_DATA_BUFFER) - 1 ); + ok( status == STATUS_BUFFER_TOO_SMALL, "got %#lx\n", status ); + ok( io.Information == 1, "got size %#Ix\n", io.Information ); + status = NtFsControlFile( handle2, NULL, NULL, NULL, &io, FSCTL_GET_REPARSE_POINT, NULL, 0, guid_data2, data_size - 1); + ok( status == STATUS_BUFFER_OVERFLOW, "got %#lx\n", status ); + ok( io.Information == data_size - 1, "expected size %#Ix, got %#Ix\n", data_size, io.Information ); + ok( !memcmp( guid_data, guid_data2, data_size - 1 ), "buffers didn't match\n" );
- io.Information = 1; - status = NtFsControlFile( handle2, NULL, NULL, NULL, &io, FSCTL_GET_REPARSE_POINT, NULL, 0, guid_data2, data_size + 1); - ok( !status, "got %#lx\n", status ); - ok( io.Information == data_size, "expected size %#Ix, got %#Ix\n", data_size, io.Information ); - ok( !memcmp( guid_data, guid_data2, data_size ), "buffers didn't match\n" ); + io.Information = 1; + status = NtFsControlFile( handle2, NULL, NULL, NULL, &io, FSCTL_GET_REPARSE_POINT, NULL, 0, guid_data2, data_size + 1); + ok( !status, "got %#lx\n", status ); + ok( io.Information == data_size, "expected size %#Ix, got %#Ix\n", data_size, io.Information ); + ok( !memcmp( guid_data, guid_data2, data_size ), "buffers didn't match\n" );
- ret = ReadFile( handle2, buffer, sizeof(buffer), &size, NULL ); - ok( ret == TRUE, "got error %lu\n", GetLastError() ); - ok( size == 4, "got size %lu\n", size ); - ok( !memcmp( buffer, "data", size ), "got data %s\n", debugstr_an( buffer, size )); + ret = ReadFile( handle2, buffer, sizeof(buffer), &size, NULL ); + ok( ret == TRUE, "got error %lu\n", GetLastError() ); + ok( size == 4, "got size %lu\n", size ); + ok( !memcmp( buffer, "data", size ), "got data %s\n", debugstr_an( buffer, size ));
- CloseHandle( handle2 ); - } + CloseHandle( handle2 );
status = NtOpenFile( &handle2, GENERIC_READ, &attr, &io, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0 ); @@ -7227,7 +7221,7 @@ out:
swprintf( path, ARRAY_SIZE(path), L"%s/testreparse_dir", temp_path ); ret = RemoveDirectoryW( path ); - todo_wine ok( ret == TRUE, "got error %lu\n", GetLastError() ); + ok( ret == TRUE, "got error %lu\n", GetLastError() );
CloseHandle( temp_dir ); } diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index a6873bb2f79..23c181650ed 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -3460,7 +3460,7 @@ done:
static NTSTATUS resolve_reparse_point( int fd, int root_fd, OBJECT_ATTRIBUTES *attr, UNICODE_STRING *nt_name, unsigned int nt_pos, unsigned int reparse_len, char **unix_name, - int unix_len, int pos, UINT disposition, BOOL is_unix, unsigned int reparse_count ); + int unix_len, int pos, UINT disposition, BOOL open_reparse, BOOL is_unix, unsigned int reparse_count );
/****************************************************************************** @@ -3470,7 +3470,7 @@ static NTSTATUS resolve_reparse_point( int fd, int root_fd, OBJECT_ATTRIBUTES *a */ static NTSTATUS lookup_unix_name( int root_fd, OBJECT_ATTRIBUTES *attr, UNICODE_STRING *nt_name, unsigned int nt_pos, char **buffer, int unix_len, int pos, - UINT disposition, BOOL is_unix, unsigned int reparse_count ) + UINT disposition, BOOL open_reparse, BOOL is_unix, unsigned int reparse_count ) { static const WCHAR invalid_charsW[] = { INVALID_NT_CHARS, '/', 0 }; const WCHAR *name = attr->ObjectName->Buffer + nt_pos; @@ -3559,14 +3559,21 @@ static NTSTATUS lookup_unix_name( int root_fd, OBJECT_ATTRIBUTES *attr, UNICODE_ memcpy( reparse_name, name, (end - name) * sizeof(WCHAR) ); reparse_name[end - name] = '?';
- if (!find_file_in_dir( root_fd, unix_name, pos, reparse_name, end - name + 1, is_unix ) - && (reparse_fd = openat( root_fd, unix_name, O_RDONLY )) >= 0) + if (!name_len && open_reparse) { - status = resolve_reparse_point( reparse_fd, root_fd, attr, nt_name, nt_pos, next - name, buffer, - unix_len, pos, disposition, is_unix, reparse_count ); - close( reparse_fd ); - free( reparse_name ); - return status; + status = find_file_in_dir( root_fd, unix_name, pos, reparse_name, end - name + 1, is_unix ); + } + else + { + if (!find_file_in_dir( root_fd, unix_name, pos, reparse_name, end - name + 1, is_unix ) + && (reparse_fd = openat( root_fd, unix_name, O_RDONLY )) >= 0) + { + status = resolve_reparse_point( reparse_fd, root_fd, attr, nt_name, nt_pos, next - name, buffer, + unix_len, pos, disposition, open_reparse, is_unix, reparse_count ); + close( reparse_fd ); + free( reparse_name ); + return status; + } } }
@@ -3612,7 +3619,8 @@ static NTSTATUS lookup_unix_name( int root_fd, OBJECT_ATTRIBUTES *attr, UNICODE_ * nt_to_unix_file_name_no_root */ static NTSTATUS nt_to_unix_file_name_no_root( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *nt_name, - char **unix_name_ret, UINT disposition, unsigned int reparse_count ) + char **unix_name_ret, UINT disposition, + BOOL open_reparse, unsigned int reparse_count ) { static const WCHAR unixW[] = {'u','n','i','x'}; static const WCHAR invalid_charsW[] = { INVALID_NT_CHARS, 0 }; @@ -3707,7 +3715,7 @@ static NTSTATUS nt_to_unix_file_name_no_root( OBJECT_ATTRIBUTES *attr, UNICODE_S nt_pos += prefix_len;
status = lookup_unix_name( AT_FDCWD, attr, nt_name, nt_pos, &unix_name, unix_len, - pos, disposition, is_unix, reparse_count ); + pos, disposition, open_reparse, is_unix, reparse_count ); if (status == STATUS_SUCCESS || status == STATUS_NO_SUCH_FILE) { *unix_name_ret = unix_name; @@ -3730,7 +3738,7 @@ static NTSTATUS nt_to_unix_file_name_no_root( OBJECT_ATTRIBUTES *attr, UNICODE_S * returned, but the unix name is still filled in properly. */ static NTSTATUS nt_to_unix_file_name( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *nt_name, - char **name_ret, UINT disposition ) + char **name_ret, UINT disposition, BOOL open_reparse ) { enum server_fd_type type; int root_fd, needs_close; @@ -3740,7 +3748,7 @@ static NTSTATUS nt_to_unix_file_name( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *n NTSTATUS status;
if (!attr->RootDirectory) /* without root dir fall back to normal lookup */ - return nt_to_unix_file_name_no_root( attr, nt_name, name_ret, disposition, 0 ); + return nt_to_unix_file_name_no_root( attr, nt_name, name_ret, disposition, open_reparse, 0 );
name = attr->ObjectName->Buffer; name_len = attr->ObjectName->Length / sizeof(WCHAR); @@ -3761,7 +3769,7 @@ static NTSTATUS nt_to_unix_file_name( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *n else { status = lookup_unix_name( root_fd, attr, nt_name, 0, &unix_name, unix_len, - 1, disposition, FALSE, 0 ); + 1, disposition, open_reparse, FALSE, 0 ); if (needs_close) close( root_fd ); } } @@ -3866,7 +3874,7 @@ static WCHAR *collapse_path( WCHAR *path )
static NTSTATUS resolve_absolute_reparse_point( const WCHAR *target, unsigned int target_len, OBJECT_ATTRIBUTES *attr, UNICODE_STRING *nt_name, const WCHAR *remainder, unsigned int remainder_len, - char **unix_name, UINT disposition, unsigned int reparse_count ) + char **unix_name, UINT disposition, BOOL open_reparse, unsigned int reparse_count ) { WCHAR *new_nt_name; char *new_unix_name; @@ -3893,7 +3901,7 @@ static NTSTATUS resolve_absolute_reparse_point( const WCHAR *target, unsigned in attr->RootDirectory = 0; attr->ObjectName = nt_name;
- status = nt_to_unix_file_name_no_root( attr, nt_name, &new_unix_name, disposition, reparse_count ); + status = nt_to_unix_file_name_no_root( attr, nt_name, &new_unix_name, disposition, open_reparse, reparse_count ); if (!status || status == STATUS_NO_SUCH_FILE) { free( *unix_name ); @@ -3905,7 +3913,7 @@ static NTSTATUS resolve_absolute_reparse_point( const WCHAR *target, unsigned in
static NTSTATUS resolve_reparse_point( int fd, int root_fd, OBJECT_ATTRIBUTES *attr, UNICODE_STRING *nt_name, unsigned int nt_pos, unsigned int reparse_len, char **unix_name, int unix_len, int pos, - UINT disposition, BOOL is_unix, unsigned int reparse_count ) + UINT disposition, BOOL open_reparse, BOOL is_unix, unsigned int reparse_count ) { const WCHAR *name = attr->ObjectName->Buffer; unsigned int name_len = attr->ObjectName->Length / sizeof(WCHAR); @@ -3947,7 +3955,7 @@ static NTSTATUS resolve_reparse_point( int fd, int root_fd, OBJECT_ATTRIBUTES *a USHORT target_len = data->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
status = resolve_absolute_reparse_point( target, target_len, attr, nt_name, remainder, remainder_len, - unix_name, disposition, reparse_count ); + unix_name, disposition, open_reparse, reparse_count ); break; }
@@ -4113,7 +4121,7 @@ static void remove_trailing_backslash( OBJECT_ATTRIBUTES *attr, UNICODE_STRING * * nt_name.Buffer and unix_name must be freed by caller in all cases. */ NTSTATUS get_nt_and_unix_names( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *nt_name, - char **unix_name_ret, UINT disposition ) + char **unix_name_ret, UINT disposition, BOOL open_reparse ) { ULONG lenA, lenW = attr->ObjectName->Length / sizeof(WCHAR); UNICODE_STRING *orig = attr->ObjectName; @@ -4147,7 +4155,7 @@ NTSTATUS get_nt_and_unix_names( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *nt_name #ifndef _WIN64 get_redirect( attr, nt_name ); #endif - status = nt_to_unix_file_name( attr, nt_name, unix_name_ret, disposition ); + status = nt_to_unix_file_name( attr, nt_name, unix_name_ret, disposition, open_reparse ); }
if (!status || status == STATUS_NO_SUCH_FILE) @@ -4274,7 +4282,7 @@ NTSTATUS ntdll_get_unix_file_name( const WCHAR *dos, char **unix_name, UINT disp
if (status) return status; InitializeObjectAttributes( &attr, &nt_name, 0, 0, NULL ); - status = get_nt_and_unix_names( &attr, &true_nt_name, &buffer, disposition ); + status = get_nt_and_unix_names( &attr, &true_nt_name, &buffer, disposition, FALSE ); free( nt_name.Buffer ); free( true_nt_name.Buffer );
@@ -4412,7 +4420,8 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU status = file_id_to_unix_file_name( &new_attr, &unix_name, &nt_name ); if (!status) new_attr.ObjectName = &nt_name; } - else status = get_nt_and_unix_names( &new_attr, &nt_name, &unix_name, disposition ); + else status = get_nt_and_unix_names( &new_attr, &nt_name, &unix_name, disposition, + options & FILE_OPEN_REPARSE_POINT );
if (status == STATUS_BAD_DEVICE_TYPE) { @@ -4593,7 +4602,7 @@ NTSTATUS WINAPI NtDeleteFile( OBJECT_ATTRIBUTES *attr ) UNICODE_STRING nt_name; OBJECT_ATTRIBUTES new_attr = *attr;
- if (!(status = get_nt_and_unix_names( &new_attr, &nt_name, &unix_name, FILE_OPEN ))) + if (!(status = get_nt_and_unix_names( &new_attr, &nt_name, &unix_name, FILE_OPEN, FALSE ))) { if (!(status = open_unix_file( &handle, unix_name, GENERIC_READ | GENERIC_WRITE | DELETE, &new_attr, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN, @@ -4617,7 +4626,7 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr, UNICODE_STRING nt_name; OBJECT_ATTRIBUTES new_attr = *attr;
- if (!(status = get_nt_and_unix_names( &new_attr, &nt_name, &unix_name, FILE_OPEN ))) + if (!(status = get_nt_and_unix_names( &new_attr, &nt_name, &unix_name, FILE_OPEN, TRUE ))) { ULONG attributes; struct stat st; @@ -4646,7 +4655,7 @@ NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC UNICODE_STRING nt_name; OBJECT_ATTRIBUTES new_attr = *attr;
- if (!(status = get_nt_and_unix_names( &new_attr, &nt_name, &unix_name, FILE_OPEN ))) + if (!(status = get_nt_and_unix_names( &new_attr, &nt_name, &unix_name, FILE_OPEN, TRUE ))) { ULONG attributes; struct stat st; @@ -5167,7 +5176,7 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, name_str.Length = info->FileNameLength; name_str.MaximumLength = info->FileNameLength + sizeof(WCHAR); InitializeObjectAttributes( &attr, &name_str, OBJ_CASE_INSENSITIVE, info->RootDirectory, NULL ); - status = get_nt_and_unix_names( &attr, &nt_name, &unix_name, FILE_OPEN_IF ); + status = get_nt_and_unix_names( &attr, &nt_name, &unix_name, FILE_OPEN_IF, TRUE ); if (status == STATUS_SUCCESS || status == STATUS_NO_SUCH_FILE) { SERVER_START_REQ( set_fd_name_info ) @@ -5212,7 +5221,7 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, name_str.Length = info->FileNameLength; name_str.MaximumLength = info->FileNameLength + sizeof(WCHAR); InitializeObjectAttributes( &attr, &name_str, OBJ_CASE_INSENSITIVE, info->RootDirectory, NULL ); - status = get_nt_and_unix_names( &attr, &nt_name, &unix_name, FILE_OPEN_IF ); + status = get_nt_and_unix_names( &attr, &nt_name, &unix_name, FILE_OPEN_IF, TRUE ); if (status == STATUS_SUCCESS || status == STATUS_NO_SUCH_FILE) { SERVER_START_REQ( set_fd_name_info ) diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 12b071eebd9..2b200cafa26 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -980,7 +980,7 @@ static NTSTATUS load_so_dll( void *args )
if (get_load_order( nt_name ) == LO_DISABLED) return STATUS_DLL_NOT_FOUND; InitializeObjectAttributes( &attr, nt_name, OBJ_CASE_INSENSITIVE, 0, 0 ); - if (!get_nt_and_unix_names( &attr, &true_nt_name, &unix_name, FILE_OPEN )) + if (!get_nt_and_unix_names( &attr, &true_nt_name, &unix_name, FILE_OPEN, FALSE )) { /* remove .so extension from Windows name */ len = nt_name->Length / sizeof(WCHAR); @@ -1481,7 +1481,7 @@ static NTSTATUS open_main_image( UNICODE_STRING *nt_name, void **module, SECTION if (loadorder == LO_DISABLED) NtTerminateProcess( GetCurrentProcess(), STATUS_DLL_NOT_FOUND );
InitializeObjectAttributes( &attr, nt_name, OBJ_CASE_INSENSITIVE, 0, NULL ); - if (get_nt_and_unix_names( &attr, &true_nt_name, &unix_name, FILE_OPEN )) return STATUS_DLL_NOT_FOUND; + if (get_nt_and_unix_names( &attr, &true_nt_name, &unix_name, FILE_OPEN, FALSE )) return STATUS_DLL_NOT_FOUND;
status = open_dll_file( unix_name, &attr, &mapping ); if (!status) diff --git a/dlls/ntdll/unix/process.c b/dlls/ntdll/unix/process.c index cd8b2994c1e..880b070c60e 100644 --- a/dlls/ntdll/unix/process.c +++ b/dlls/ntdll/unix/process.c @@ -256,7 +256,7 @@ static unsigned int get_pe_file_info( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *n
*handle = 0; memset( info, 0, sizeof(*info) ); - if (!(status = get_nt_and_unix_names( attr, nt_name, unix_name, FILE_OPEN ))) + if (!(status = get_nt_and_unix_names( attr, nt_name, unix_name, FILE_OPEN, FALSE ))) { status = open_unix_file( handle, *unix_name, GENERIC_READ, attr, 0, FILE_SHARE_READ | FILE_SHARE_DELETE, @@ -340,7 +340,7 @@ static int get_unix_curdir( const RTL_USER_PROCESS_PARAMETERS *params ) nt_name.Length = wcslen( nt_name.Buffer ) * sizeof(WCHAR);
InitializeObjectAttributes( &attr, &nt_name, OBJ_CASE_INSENSITIVE, 0, NULL ); - status = get_nt_and_unix_names( &attr, &true_nt_name, &unix_name, FILE_OPEN ); + status = get_nt_and_unix_names( &attr, &true_nt_name, &unix_name, FILE_OPEN, FALSE ); if (status) goto done; status = open_unix_file( &handle, unix_name, FILE_TRAVERSE | SYNCHRONIZE, &attr, 0, FILE_SHARE_READ | FILE_SHARE_DELETE, diff --git a/dlls/ntdll/unix/registry.c b/dlls/ntdll/unix/registry.c index 9341e14549b..24515d4dbbe 100644 --- a/dlls/ntdll/unix/registry.c +++ b/dlls/ntdll/unix/registry.c @@ -733,7 +733,7 @@ NTSTATUS WINAPI NtLoadKeyEx( const OBJECT_ATTRIBUTES *attr, OBJECT_ATTRIBUTES *f if (roothandle) FIXME("roothandle is not filled\n"); if (iostatus) FIXME("iostatus is not filled\n");
- if (!(ret = get_nt_and_unix_names( &new_attr, &nt_name, &unix_name, FILE_OPEN ))) + if (!(ret = get_nt_and_unix_names( &new_attr, &nt_name, &unix_name, FILE_OPEN, FALSE ))) { ret = open_unix_file( &key, unix_name, GENERIC_READ | SYNCHRONIZE, &new_attr, 0, 0, FILE_OPEN, 0, NULL, 0 ); diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index 941c05f2bc2..2a552a96c57 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -358,7 +358,7 @@ extern struct async_fileio *alloc_fileio( DWORD size, async_callback_t callback, extern void release_fileio( struct async_fileio *io ); extern NTSTATUS errno_to_status( int err ); extern NTSTATUS get_nt_and_unix_names( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *nt_name, - char **unix_name, UINT disposition ); + char **unix_name, UINT disposition, BOOL open_reparse ); extern NTSTATUS unix_to_nt_file_name( const char *unix_name, WCHAR **nt, UINT disposition ); extern NTSTATUS get_full_path( char *name, const WCHAR *curdir, UNICODE_STRING *nt_name ); extern NTSTATUS get_nt_path( const WCHAR *name, UNICODE_STRING *nt_name );