Alexandre Julliard : ntdll: Fix returned status code for paths with a trailing slash.

Alexandre Julliard julliard at winehq.org
Tue Jun 28 15:53:09 CDT 2022


Module: wine
Branch: master
Commit: 3af025879583dff92540e29a92031a1078296484
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=3af025879583dff92540e29a92031a1078296484

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Jun 28 13:16:51 2022 +0200

ntdll: Fix returned status code for paths with a trailing slash.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/kernel32/tests/file.c | 25 ++++---------------------
 dlls/ntdll/tests/file.c    |  5 +----
 dlls/ntdll/tests/path.c    | 11 +++++------
 dlls/ntdll/unix/file.c     |  7 +++++--
 dlls/ucrtbase/tests/misc.c |  2 +-
 server/fd.c                |  6 +++++-
 6 files changed, 21 insertions(+), 35 deletions(-)

diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c
index bd8d8c91b2f..b29e2c3dc4e 100644
--- a/dlls/kernel32/tests/file.c
+++ b/dlls/kernel32/tests/file.c
@@ -432,27 +432,10 @@ static void test__lcreat( void )
     ok( ret, "DeleteFile failed (%ld)\n", GetLastError(  ) );
 
     filehandle=_lcreat (slashname, 0); /* illegal name */
-    if (HFILE_ERROR==filehandle) {
-      err=GetLastError ();
-      ok (err==ERROR_INVALID_NAME || err==ERROR_PATH_NOT_FOUND,
-          "creating file \"%s\" failed with error %d\n", slashname, err);
-    } else { /* only NT succeeds */
-      _lclose(filehandle);
-      find=FindFirstFileA (slashname, &search_results);
-      if (INVALID_HANDLE_VALUE!=find)
-      {
-        ret = FindClose (find);
-        ok (0 != ret, "FindClose complains (%ld)\n", GetLastError ());
-        slashname[strlen(slashname)-1]=0;
-        ok (!strcmp (slashname, search_results.cFileName),
-            "found unexpected name \"%s\"\n", search_results.cFileName);
-        ok (FILE_ATTRIBUTE_ARCHIVE==search_results.dwFileAttributes,
-            "attributes of file \"%s\" are 0x%04lx\n", search_results.cFileName,
-            search_results.dwFileAttributes);
-      }
-    ret = DeleteFileA( slashname );
-    ok( ret, "DeleteFile failed (%ld)\n", GetLastError(  ) );
-    }
+    ok( filehandle == HFILE_ERROR, "succeeded\n" );
+    err=GetLastError ();
+    ok (err==ERROR_INVALID_NAME || err==ERROR_PATH_NOT_FOUND,
+        "creating file \"%s\" failed with error %d\n", slashname, err);
 
     filehandle=_lcreat (filename, 8); /* illegal attribute */
     if (HFILE_ERROR==filehandle)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index f8ef38f38c2..065a9251c2a 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -4255,15 +4255,12 @@ static void test_NtCreateFile(void)
 
     status = pNtCreateFile( &handle, GENERIC_READ, &attr, &io, NULL,
                             0, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_CREATE, 0, NULL, 0);
-    todo_wine
     ok( status == STATUS_OBJECT_NAME_INVALID, "failed %s %lx\n", debugstr_w(nameW.Buffer), status );
-    if (!status) DeleteFileW( path );
     status = pNtCreateFile( &handle, GENERIC_READ, &attr, &io, NULL,
                             0, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_CREATE,
                             FILE_DIRECTORY_FILE, NULL, 0);
-    todo_wine
     ok( !status, "failed %s %lx\n", debugstr_w(nameW.Buffer), status );
-    if (!status) RemoveDirectoryW( path );
+    RemoveDirectoryW( path );
 }
 
 static void test_read_write(void)
diff --git a/dlls/ntdll/tests/path.c b/dlls/ntdll/tests/path.c
index d5d6e9c217a..4732f6a6aa8 100644
--- a/dlls/ntdll/tests/path.c
+++ b/dlls/ntdll/tests/path.c
@@ -627,7 +627,7 @@ static void test_RtlDosPathNameToNtPathName_U(void)
 
 static void test_nt_names(void)
 {
-    static const struct { const WCHAR *root, *name; NTSTATUS expect, broken; BOOL todo; } tests[] =
+    static const struct { const WCHAR *root, *name; NTSTATUS expect, broken; } tests[] =
     {
         { NULL, L"\\??\\C:\\windows\\system32\\kernel32.dll", STATUS_SUCCESS },
         { NULL, L"\\??\\C:\\\\windows\\system32\\kernel32.dll", STATUS_SUCCESS, STATUS_OBJECT_NAME_INVALID },
@@ -652,9 +652,9 @@ static void test_nt_names(void)
         { NULL, L"\\??\\C:\\windows\\SyStEm32\\", STATUS_FILE_IS_A_DIRECTORY },
         { NULL, L"\\??\\C:\\windows\\system32\\\\", STATUS_OBJECT_NAME_INVALID },
         { NULL, L"\\??\\C:\\windows\\system32\\foobar\\", STATUS_OBJECT_NAME_NOT_FOUND },
-        { NULL, L"\\??\\C:\\windows\\system32\\kernel32.dll\\", STATUS_OBJECT_NAME_INVALID, 0, TRUE },
+        { NULL, L"\\??\\C:\\windows\\system32\\kernel32.dll\\", STATUS_OBJECT_NAME_INVALID },
         { NULL, L"\\??\\C:\\windows\\system32\\kernel32.dll\\foo", STATUS_OBJECT_PATH_NOT_FOUND },
-        { NULL, L"\\??\\C:\\windows\\system32\\Kernel32.Dll\\", STATUS_OBJECT_NAME_INVALID, 0, TRUE },
+        { NULL, L"\\??\\C:\\windows\\system32\\Kernel32.Dll\\", STATUS_OBJECT_NAME_INVALID },
         { NULL, L"\\??\\C:\\windows\\system32\\Kernel32.Dll\\foo", STATUS_OBJECT_PATH_NOT_FOUND },
         { NULL, L"\\??\\C:\\windows\\sys\001", STATUS_OBJECT_NAME_INVALID },
         { L"\\??\\", NULL, STATUS_OBJECT_NAME_INVALID },
@@ -678,9 +678,9 @@ static void test_nt_names(void)
         { L"\\??\\C:\\windows\\", L"SyStEm32\\", STATUS_FILE_IS_A_DIRECTORY },
         { L"\\??\\C:\\windows\\", L"system32\\\\", STATUS_OBJECT_NAME_INVALID },
         { L"\\??\\C:\\windows\\", L"system32\\foobar\\", STATUS_OBJECT_NAME_NOT_FOUND },
-        { L"\\??\\C:\\windows\\", L"system32\\kernel32.dll\\", STATUS_OBJECT_NAME_INVALID, 0, TRUE },
+        { L"\\??\\C:\\windows\\", L"system32\\kernel32.dll\\", STATUS_OBJECT_NAME_INVALID },
         { L"\\??\\C:\\windows\\", L"system32\\kernel32.dll\\foo", STATUS_OBJECT_PATH_NOT_FOUND },
-        { L"\\??\\C:\\windows\\", L"system32\\Kernel32.Dll\\", STATUS_OBJECT_NAME_INVALID, 0, TRUE },
+        { L"\\??\\C:\\windows\\", L"system32\\Kernel32.Dll\\", STATUS_OBJECT_NAME_INVALID },
         { L"\\??\\C:\\windows\\", L"system32\\Kernel32.Dll\\foo", STATUS_OBJECT_PATH_NOT_FOUND },
         { L"\\??\\C:\\windows\\", L"\\system32\\kernel32.dll", STATUS_INVALID_PARAMETER },
         { L"\\??\\C:\\windows\\", L"/system32\\kernel32.dll", STATUS_OBJECT_NAME_INVALID },
@@ -720,7 +720,6 @@ static void test_nt_names(void)
         }
         if (attr.RootDirectory) NtClose( attr.RootDirectory );
         if (handle) NtClose( handle );
-        todo_wine_if( tests[i].todo )
         ok( status == tests[i].expect || broken( tests[i].broken && status == tests[i].broken ),
             "%u: got %lx / %lx for %s + %s\n", i, status, tests[i].expect,
             debugstr_w( tests[i].root ), debugstr_w( tests[i].name ));
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index 4873f7f093c..e09e8cafc82 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -3187,7 +3187,7 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
 
         /* grow the buffer if needed */
 
-        if (unix_len - pos < MAX_DIR_ENTRY_LEN + 2)
+        if (unix_len - pos < MAX_DIR_ENTRY_LEN + 3)
         {
             char *new_name;
             unix_len += 2 * MAX_DIR_ENTRY_LEN;
@@ -3208,7 +3208,9 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
                     if (ret > 0 && ret <= MAX_DIR_ENTRY_LEN)
                     {
                         unix_name[pos] = '/';
-                        unix_name[pos + 1 + ret] = 0;
+                        pos += ret + 1;
+                        if (end < next) unix_name[pos++] = '/';
+                        unix_name[pos] = 0;
                         status = STATUS_NO_SUCH_FILE;
                         break;
                     }
@@ -3218,6 +3220,7 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
             {
                 status = STATUS_OBJECT_NAME_COLLISION;
             }
+            if (end < next) strcat( unix_name, "/" );
         }
         else if (status == STATUS_OBJECT_NAME_NOT_FOUND) status = STATUS_OBJECT_PATH_NOT_FOUND;
 
diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c
index 9cc50d85d78..069de0787b7 100644
--- a/dlls/ucrtbase/tests/misc.c
+++ b/dlls/ucrtbase/tests/misc.c
@@ -1309,7 +1309,7 @@ static void test__stat32(void)
         ok(!ret, "_stat32('%s') returned %d\n", path, ret);
         strcat(path, "\\");
         ret = _stat32(path, &buf);
-        todo_wine ok(ret, "_stat32('%s') returned %d\n", path, ret);
+        ok(ret, "_stat32('%s') returned %d\n", path, ret);
         close(fd);
         remove(path);
     }
diff --git a/server/fd.c b/server/fd.c
index 1b4b98b0e76..eaebe044f37 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -1959,7 +1959,11 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam
 
         if (fd->unix_fd == -1)
         {
-            file_set_error();
+            /* check for trailing slash on file path */
+            if ((errno == ENOENT || errno == ENOTDIR) && name[strlen(name) - 1] == '/')
+                set_error( STATUS_OBJECT_NAME_INVALID );
+            else
+                file_set_error();
             goto error;
         }
     }




More information about the wine-cvs mailing list