Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ntdll/directory.c | 8 ++++++++ dlls/ntdll/tests/file.c | 22 +++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c index b8cfe507ed..0df6c1ce42 100644 --- a/dlls/ntdll/directory.c +++ b/dlls/ntdll/directory.c @@ -2674,8 +2674,16 @@ NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_STRING * NTSTATUS status; BOOLEAN check_case = !(attr->Attributes & OBJ_CASE_INSENSITIVE);
+ if (!attr->ObjectName->Buffer && attr->ObjectName->Length) + return STATUS_ACCESS_VIOLATION; + if (!attr->RootDirectory) /* without root dir fall back to normal lookup */ + { + if (!attr->ObjectName->Buffer) + return STATUS_OBJECT_PATH_SYNTAX_BAD; + return wine_nt_to_unix_file_name( attr->ObjectName, unix_name_ret, disposition, check_case ); + }
name = attr->ObjectName->Buffer; name_len = attr->ObjectName->Length / sizeof(WCHAR); diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 31c18454f0..4243a7631c 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -144,16 +144,36 @@ static void create_file_test(void) static const WCHAR pathInvalidDosW[] = {'\','D','o','s','D','e','v','i','c','e','s','\',0}; static const char testdata[] = "Hello World"; FILE_NETWORK_OPEN_INFORMATION info; + UNICODE_STRING nameW, null_string; NTSTATUS status; HANDLE dir, file; WCHAR path[MAX_PATH]; OBJECT_ATTRIBUTES attr; IO_STATUS_BLOCK io; - UNICODE_STRING nameW; LARGE_INTEGER offset; char buf[32]; DWORD ret;
+ attr.Length = sizeof(attr); + attr.RootDirectory = NULL; + attr.ObjectName = &null_string; + attr.Attributes = 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + + null_string.Buffer = NULL; + null_string.Length = 256; + + /* try various open modes and options on directories */ + status = pNtCreateFile( &dir, GENERIC_READ|GENERIC_WRITE, &attr, &io, NULL, 0, + FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, FILE_DIRECTORY_FILE, NULL, 0 ); + ok( status == STATUS_ACCESS_VIOLATION, "Got unexpected status %#x.\n", status ); + + null_string.Length = 0; + status = pNtCreateFile( &dir, GENERIC_READ|GENERIC_WRITE, &attr, &io, NULL, 0, + FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, FILE_DIRECTORY_FILE, NULL, 0 ); + ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "Got unexpected status %#x.\n", status ); + GetCurrentDirectoryW( MAX_PATH, path ); pRtlDosPathNameToNtPathName_U( path, &nameW, NULL, NULL ); attr.Length = sizeof(attr);
Undefined result is due to RtlUnicodeToUTF8N() not setting output length on error which is a correct behaviour according to existing tests.
'Planet Zoo' is affected which passes NULL object name buffer to NtCreateFile().
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ntdll/locale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/ntdll/locale.c b/dlls/ntdll/locale.c index a28f5d0f58..da29241517 100644 --- a/dlls/ntdll/locale.c +++ b/dlls/ntdll/locale.c @@ -1020,7 +1020,7 @@ DWORD ntdll_umbstowcs( const char *src, DWORD srclen, WCHAR *dst, DWORD dstlen ) */ int ntdll_wcstoumbs( const WCHAR *src, DWORD srclen, char *dst, DWORD dstlen, BOOL strict ) { - DWORD i, reslen; + DWORD i, reslen = 0;
if (!unix_table.CodePage) RtlUnicodeToUTF8N( dst, dstlen, &reslen, src, srclen * sizeof(WCHAR) );
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=70457
Your paranoid android.
=== debiant (build log) ===
The task timed out
=== debiant (build log) ===
The task timed out
Files names are case insensitive on NTFS by default regardless of the OBJ_CASE_INSENSITIVE object attribute.
'Planet Zoo' which calls NtCreateFile() directly and does not specify the attribute depends on that.
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/kernel32/path.c | 4 ++-- dlls/ntdll/directory.c | 8 ++++---- dlls/ntdll/loader.c | 2 +- dlls/ntdll/process.c | 4 ++-- dlls/ntdll/tests/file.c | 2 +- include/winternl.h | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/dlls/kernel32/path.c b/dlls/kernel32/path.c index 93759592c4..587ed59229 100644 --- a/dlls/kernel32/path.c +++ b/dlls/kernel32/path.c @@ -714,7 +714,7 @@ BOOL WINAPI RemoveDirectoryW( LPCWSTR path ) return FALSE; }
- status = wine_nt_to_unix_file_name( &nt_name, &unix_name, FILE_OPEN, FALSE ); + status = wine_nt_to_unix_file_name( &nt_name, &unix_name, FILE_OPEN ); RtlFreeUnicodeString( &nt_name ); if (!set_ntstatus( status )) { @@ -793,7 +793,7 @@ char * CDECL wine_get_unix_file_name( LPCWSTR dosW ) NTSTATUS status;
if (!RtlDosPathNameToNtPathName_U( dosW, &nt_name, NULL, NULL )) return NULL; - status = wine_nt_to_unix_file_name( &nt_name, &unix_name, FILE_OPEN_IF, FALSE ); + status = wine_nt_to_unix_file_name( &nt_name, &unix_name, FILE_OPEN_IF ); RtlFreeUnicodeString( &nt_name ); if (status && status != STATUS_NO_SUCH_FILE) { diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c index 0df6c1ce42..e92570acda 100644 --- a/dlls/ntdll/directory.c +++ b/dlls/ntdll/directory.c @@ -2672,7 +2672,6 @@ NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_STRING * char *unix_name; int name_len, unix_len; NTSTATUS status; - BOOLEAN check_case = !(attr->Attributes & OBJ_CASE_INSENSITIVE);
if (!attr->ObjectName->Buffer && attr->ObjectName->Length) return STATUS_ACCESS_VIOLATION; @@ -2682,7 +2681,7 @@ NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_STRING * if (!attr->ObjectName->Buffer) return STATUS_OBJECT_PATH_SYNTAX_BAD;
- return wine_nt_to_unix_file_name( attr->ObjectName, unix_name_ret, disposition, check_case ); + return wine_nt_to_unix_file_name( attr->ObjectName, unix_name_ret, disposition ); }
name = attr->ObjectName->Buffer; @@ -2712,7 +2711,7 @@ NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_STRING * if ((old_cwd = open( ".", O_RDONLY )) != -1 && fchdir( root_fd ) != -1) { status = lookup_unix_name( name, name_len, &unix_name, unix_len, 1, - disposition, check_case ); + disposition, FALSE ); if (fchdir( old_cwd ) == -1) chdir( "/" ); } else status = FILE_GetNtStatus(); @@ -2749,7 +2748,7 @@ NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_STRING * * returned, but the unix name is still filled in properly. */ NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret, - UINT disposition, BOOLEAN check_case ) + UINT disposition ) { static const WCHAR unixW[] = {'u','n','i','x'}; static const WCHAR invalid_charsW[] = { INVALID_NT_CHARS, 0 }; @@ -2761,6 +2760,7 @@ NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRI char *unix_name; int pos, ret, name_len, unix_len, prefix_len; WCHAR prefix[MAX_DIR_ENTRY_LEN + 1]; + BOOLEAN check_case = FALSE; BOOLEAN is_unix = FALSE;
name = nameW->Buffer; diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 5705dd38d0..cc5d07a285 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -2967,7 +2967,7 @@ static NTSTATUS load_so_dll( LPCWSTR load_path, const UNICODE_STRING *nt_name,
if (!so_name) { - if (wine_nt_to_unix_file_name( nt_name, &unix_name, FILE_OPEN, FALSE )) + if (wine_nt_to_unix_file_name( nt_name, &unix_name, FILE_OPEN )) return STATUS_DLL_NOT_FOUND;
/* remove .so extension from Windows name */ diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c index 28aa671f47..1202f61589 100644 --- a/dlls/ntdll/process.c +++ b/dlls/ntdll/process.c @@ -1457,7 +1457,7 @@ static char *get_unix_curdir( const RTL_USER_PROCESS_PARAMETERS *params )
if (!RtlDosPathNameToNtPathName_U( params->CurrentDirectory.DosPath.Buffer, &nt_name, NULL, NULL )) return NULL; - status = wine_nt_to_unix_file_name( &nt_name, &unix_name, FILE_OPEN_IF, FALSE ); + status = wine_nt_to_unix_file_name( &nt_name, &unix_name, FILE_OPEN_IF ); RtlFreeUnicodeString( &nt_name ); if (status && status != STATUS_NO_SUCH_FILE) return NULL; return unix_name.Buffer; @@ -1478,7 +1478,7 @@ static NTSTATUS fork_and_exec( UNICODE_STRING *path, const RTL_USER_PROCESS_PARA ANSI_STRING unix_name; NTSTATUS status;
- status = wine_nt_to_unix_file_name( path, &unix_name, FILE_OPEN, FALSE ); + status = wine_nt_to_unix_file_name( path, &unix_name, FILE_OPEN ); if (status) return status;
#ifdef HAVE_PIPE2 diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 4243a7631c..f42f6173fb 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -369,7 +369,7 @@ static void open_file_test(void) attr.Length = sizeof(attr); attr.RootDirectory = 0; attr.ObjectName = &nameW; - attr.Attributes = OBJ_CASE_INSENSITIVE; + attr.Attributes = 0; attr.SecurityDescriptor = NULL; attr.SecurityQualityOfService = NULL; status = pNtOpenFile( &dir, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io, diff --git a/include/winternl.h b/include/winternl.h index f36419da78..c7653cd2a1 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -3129,7 +3129,7 @@ NTSYSAPI void WINAPI TpWaitForWork(TP_WORK *,BOOL); /* Wine internal functions */
NTSYSAPI NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret, - UINT disposition, BOOLEAN check_case ); + UINT disposition ); NTSYSAPI NTSTATUS CDECL wine_unix_to_nt_file_name( const ANSI_STRING *name, UNICODE_STRING *nt );
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=70458
Your paranoid android.
=== debiant (build log) ===
The task timed out
=== debiant (build log) ===
The task timed out
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=70456
Your paranoid android.
=== debiant (build log) ===
The task timed out
=== debiant (build log) ===
The task timed out