From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/kernel32/tests/file.c | 2 -- server/fd.c | 10 +++++++++- 2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index 6b619f9db32..c1b30a4a7c6 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -2186,9 +2186,7 @@ static void test_MoveFileA(void) } CloseHandle(hfile); ret = GetFileAttributesA(source); - todo_wine ok(ret == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND, "GetFileAttributesA: error %ld\n", GetLastError()); - if(ret != INVALID_FILE_ATTRIBUTES) DeleteFileA(source); DeleteFileA(dest);
ret = RemoveDirectoryA(tempdir); diff --git a/server/fd.c b/server/fd.c index 04688c5eb0d..786f5e0bbf9 100644 --- a/server/fd.c +++ b/server/fd.c @@ -2573,7 +2573,15 @@ static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr, da { if (!fstat( fd->unix_fd, &st2 ) && st.st_ino == st2.st_ino && st.st_dev == st2.st_dev) { - if (create_link && !replace) set_error( STATUS_OBJECT_NAME_COLLISION ); + if (!create_link) + { + char src[PATH_MAX], dst[PATH_MAX]; + + /* if it's not the "same" file (by path), it means it's a hardlink, so remove the source */ + if (!realpath( fd->unix_name, src ) || !realpath( name, dst ) || (strcmp( src, dst ) && unlink( src ))) + file_set_error(); + } + else if (!replace) set_error( STATUS_OBJECT_NAME_COLLISION ); free( name ); return; }