diff --git a/patches/kernel32-CreateSymbolicLink/0001-kernel32-Implement-CreateSymbolicLink.patch b/patches/kernel32-CreateSymbolicLink/0001-kernel32-Implement-CreateSymbolicLink.patch index 712a9693..570171d8 100644 --- a/patches/kernel32-CreateSymbolicLink/0001-kernel32-Implement-CreateSymbolicLink.patch +++ b/patches/kernel32-CreateSymbolicLink/0001-kernel32-Implement-CreateSymbolicLink.patch @@ -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 -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 --- - 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