Updated kernel32-CreateSymbolicLink patchset

This commit is contained in:
Alistair Leslie-Hughes 2019-02-05 11:06:09 +11:00
parent d25f4cf2e2
commit fd3b0a7361

View File

@ -1,37 +1,31 @@
From 327d3f06bed9eea26c9bae06bc525bbd175e8333 Mon Sep 17 00:00:00 2001
From 75f520b3a9a877c3f75bb6bae05e4e1b997af52a Mon Sep 17 00:00:00 2001
From: Gijs Vermeulen <gijsvrm@gmail.com>
Date: Tue, 29 Jan 2019 23:34:54 +0100
Subject: [PATCH] kernel32: Implement CreateSymbolicLink
Date: Mon, 4 Feb 2019 15:16:39 +0100
Subject: [PATCH] kernel32: Implement CreateSymbolicLink.
Signed-off-by: Gijs Vermeulen <gijsvrm@gmail.com>
---
dlls/kernel32/path.c | 73 ++++++++++++++++++++++++++++++++--
dlls/msvcp120/tests/msvcp120.c | 47 +++++++++++-----------
2 files changed, 93 insertions(+), 27 deletions(-)
dlls/kernel32/path.c | 72 ++++++++++++++++++++++++++++++++--
dlls/msvcp120/tests/msvcp120.c | 51 ++++++++++++------------
2 files changed, 94 insertions(+), 29 deletions(-)
diff --git a/dlls/kernel32/path.c b/dlls/kernel32/path.c
index 4f760940bfd..dae74dc2bc0 100644
index cf1c768970..cb8540389e 100644
--- a/dlls/kernel32/path.c
+++ b/dlls/kernel32/path.c
@@ -2145,8 +2145,56 @@ WCHAR * CDECL wine_get_dos_file_name( LPCSTR str )
@@ -2079,8 +2079,55 @@ WCHAR * CDECL wine_get_dos_file_name( LPCSTR str )
*/
BOOLEAN WINAPI CreateSymbolicLinkW(LPCWSTR link, LPCWSTR target, DWORD flags)
{
- FIXME("(%s %s %d): stub\n", debugstr_w(link), debugstr_w(target), flags);
- return TRUE;
+ NTSTATUS status;
+ NTSTATUS status, temp;
+ UNICODE_STRING nt_dest, nt_source;
+ ANSI_STRING unix_dest, unix_source;
+ BOOL ret = FALSE;
+
+ TRACE("(%s, %s, %d)\n", debugstr_w(link), debugstr_w(target), flags);
+
+ if(GetFileAttributesW(target) & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ FIXME("Directories are not supported\n");
+ return TRUE;
+ }
+
+ nt_dest.Buffer = nt_source.Buffer = NULL;
+ if (!RtlDosPathNameToNtPathName_U( link, &nt_dest, NULL, NULL ) ||
+ !RtlDosPathNameToNtPathName_U( target, &nt_source, NULL, NULL ))
@ -41,26 +35,31 @@ index 4f760940bfd..dae74dc2bc0 100644
+ }
+
+ unix_source.Buffer = unix_dest.Buffer = NULL;
+ status = wine_nt_to_unix_file_name( &nt_source, &unix_source, FILE_OPEN, FALSE );
+ if (!status)
+ {
+ status = wine_nt_to_unix_file_name( &nt_dest, &unix_dest, FILE_CREATE, FALSE );
+ if (!status) /* destination must not exist */
+ status = STATUS_OBJECT_NAME_EXISTS;
+ else if (status == STATUS_NO_SUCH_FILE)
+ status = STATUS_SUCCESS;
+ }
+ temp = wine_nt_to_unix_file_name( &nt_source, &unix_source, FILE_OPEN_IF, FALSE );
+ status = wine_nt_to_unix_file_name( &nt_dest, &unix_dest, FILE_CREATE, FALSE );
+ if (!status) /* destination must not exist */
+ status = STATUS_OBJECT_NAME_EXISTS;
+ else if (status == STATUS_NO_SUCH_FILE)
+ status = STATUS_SUCCESS;
+
+ if (status)
+ SetLastError( RtlNtStatusToDosError(status) );
+ else if (!symlink( unix_source.Buffer, unix_dest.Buffer ))
+ {
+ TRACE("Symlinked '%s' to '%s'\n", debugstr_a( unix_dest.Buffer ),
+ debugstr_a( unix_source.Buffer ));
+ ret = TRUE;
+ }
+ SetLastError( RtlNtStatusToDosError(status) );
+ else
+ FILE_SetDosError();
+ {
+ if(temp != STATUS_NO_SUCH_FILE && GetFileAttributesW(target) & FILE_ATTRIBUTE_DIRECTORY && strstr(unix_dest.Buffer, unix_source.Buffer))
+ {
+ FIXME("Symlinking a directory inside that directory is not supported.\n");
+ ret = TRUE;
+ }
+ else if (!symlink( unix_source.Buffer, unix_dest.Buffer ))
+ {
+ TRACE("Symlinked '%s' to '%s'\n", debugstr_a( unix_dest.Buffer ),
+ debugstr_a( unix_source.Buffer ));
+ ret = TRUE;
+ }
+ else
+ FILE_SetDosError();
+ }
+
+ RtlFreeAnsiString( &unix_source );
+ RtlFreeAnsiString( &unix_dest );
@ -72,7 +71,7 @@ index 4f760940bfd..dae74dc2bc0 100644
}
/*************************************************************************
@@ -2154,8 +2202,25 @@ BOOLEAN WINAPI CreateSymbolicLinkW(LPCWSTR link, LPCWSTR target, DWORD flags)
@@ -2088,8 +2135,25 @@ BOOLEAN WINAPI CreateSymbolicLinkW(LPCWSTR link, LPCWSTR target, DWORD flags)
*/
BOOLEAN WINAPI CreateSymbolicLinkA(LPCSTR link, LPCSTR target, DWORD flags)
{
@ -101,7 +100,7 @@ index 4f760940bfd..dae74dc2bc0 100644
/*************************************************************************
diff --git a/dlls/msvcp120/tests/msvcp120.c b/dlls/msvcp120/tests/msvcp120.c
index 70fc0c13dc1..5bb507c7b6b 100644
index 70fc0c13dc..0aa5225295 100644
--- a/dlls/msvcp120/tests/msvcp120.c
+++ b/dlls/msvcp120/tests/msvcp120.c
@@ -1648,7 +1648,7 @@ static void test_tr2_sys__Stat(void)
@ -153,7 +152,7 @@ index 70fc0c13dc1..5bb507c7b6b 100644
- ok(p_tr2_sys__File_size(tests[i].new_path) == 0, "tr2_sys__Symlink(): expect 0, got %s\n", wine_dbgstr_longlong(p_tr2_sys__File_size(tests[i].new_path)));
+ {
+ todo_wine_if(tests[i].is_todo)
+ ok(p_tr2_sys__File_size(tests[i].new_path) == 0, "tr2_sys__Symlink(): test %d expect: 0, got %s\n", i+1, wine_dbgstr_longlong(p_tr2_sys__File_size(tests[i].new_path)));
+ ok(p_tr2_sys__File_size(tests[i].new_path) == 0, "tr2_sys__Symlink(): expect 0, got %s\n", wine_dbgstr_longlong(p_tr2_sys__File_size(tests[i].new_path)));
+ }
}
@ -162,10 +161,11 @@ index 70fc0c13dc1..5bb507c7b6b 100644
- todo_wine ok(DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link to exist\n");
- todo_wine ok(DeleteFileA("tr2_test_dir/f1_link_link"), "expect tr2_test_dir/f1_link_link to exist\n");
+ ok(DeleteFileA("tr2_test_dir/f1_link_link"), "expect tr2_test_dir/f1_link_link to exist\n");
todo_wine ok(DeleteFileA("not_exist_link"), "expect not_exist_link to exist\n");
todo_wine ok(DeleteFileA("dir_link"), "expect dir_link to exist\n");
+ ok(DeleteFileA("f1_link"), "expect f1_link to exist\n");
+ ok(DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link to exist\n");
+ ok(DeleteFileA("f1_link"), "expect f1_link to exist\n");
todo_wine ok(DeleteFileA("not_exist_link"), "expect not_exist_link to exist\n");
- todo_wine ok(DeleteFileA("dir_link"), "expect dir_link to exist\n");
+ todo_wine ok(DeleteFileA("dir_link"), "expect dir_link to exist, got %d\n", GetLastError());
+ ok(DeleteFileA("f1"), "expect f1 to exist\n");
ret = p_tr2_sys__Remove_dir("tr2_test_dir");
ok(ret == 1, "tr2_sys__Remove_dir(): expect 1 got %d\n", ret);
@ -193,16 +193,18 @@ index 70fc0c13dc1..5bb507c7b6b 100644
};
GetCurrentDirectoryA(MAX_PATH, current_path);
@@ -2048,8 +2050,7 @@ static void test_tr2_sys__Unlink(void)
@@ -2048,9 +2050,8 @@ static void test_tr2_sys__Unlink(void)
for(i=0; i<ARRAY_SIZE(tests); i++) {
errno = 0xdeadbeef;
ret = p_tr2_sys__Unlink(tests[i].path);
- todo_wine_if(tests[i].is_todo)
- ok(ret == tests[i].last_error, "tr2_sys__Unlink(): test %d expect: %d, got %d\n",
- i+1, tests[i].last_error, ret);
+ ok(ret == tests[i].last_error, "tr2_sys__Unlink(): test %d expect: %d, got %d\n",
i+1, tests[i].last_error, ret);
+ i+1, tests[i].last_error, ret);
ok(errno == 0xdeadbeef, "tr2_sys__Unlink(): test %d errno expect: 0xdeadbeef, got %d\n", i+1, ret);
}
--
2.20.1