Applications expect a path starting with a drive like '\Device\Harddisk1' instead of a drive letter.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51687 Signed-off-by: Matias Zuniga matias.nicolas.zc@gmail.com --- dlls/ntdll/unix/virtual.c | 76 ++++++++++++++++++++++++++++++++--- dlls/psapi/tests/psapi_main.c | 5 +-- 2 files changed, 71 insertions(+), 10 deletions(-)
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index 8a1e35b6387..04eddf0e6f1 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -133,6 +133,8 @@ struct file_view } \ } while (0);
+#define SYMBOLIC_LINK_QUERY 0x0001 + /* per-page protection flags */ #define VPROT_READ 0x01 #define VPROT_WRITE 0x02 @@ -4273,34 +4275,96 @@ static NTSTATUS get_working_set_ex( HANDLE process, LPCVOID addr, return STATUS_SUCCESS; }
+static NTSTATUS read_nt_symlink( UNICODE_STRING *name, WCHAR *target, DWORD size ) +{ + NTSTATUS status; + OBJECT_ATTRIBUTES attr; + HANDLE handle; + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.Attributes = OBJ_CASE_INSENSITIVE; + attr.ObjectName = name; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + + if (!(status = NtOpenSymbolicLinkObject( &handle, SYMBOLIC_LINK_QUERY, &attr ))) + { + UNICODE_STRING targetW; + targetW.Buffer = target; + targetW.MaximumLength = (size - 1) * sizeof(WCHAR); + status = NtQuerySymbolicLinkObject( handle, &targetW, NULL ); + if (!status) target[targetW.Length / sizeof(WCHAR)] = 0; + NtClose( handle ); + } + return status; +} + +static NTSTATUS follow_device_symlink( WCHAR *buffer, SIZE_T max_path_len, WCHAR *name, SIZE_T *current_path_len ) +{ + WCHAR *p = buffer; + NTSTATUS status = STATUS_SUCCESS; + SIZE_T devname_len = 6; // e.g. ??\C: + UNICODE_STRING devname; + DWORD target_len; + + if (*current_path_len >= devname_len * sizeof(WCHAR) && name[devname_len - 1] == ':') { + devname.Buffer = name; + devname.Length = devname_len * sizeof(WCHAR); + if (!(status = read_nt_symlink( &devname, p, (max_path_len - *current_path_len) / sizeof(WCHAR) + devname_len + 1 ))) + { + target_len = lstrlenW(p); + *current_path_len -= devname_len * sizeof(WCHAR); // skip the device name + p += target_len; + + memcpy( p, name + devname_len, *current_path_len ); + *current_path_len += target_len * sizeof(WCHAR); + } + } + else memcpy( p, name, *current_path_len ); + + return status; +} + static NTSTATUS get_memory_section_name( HANDLE process, LPCVOID addr, MEMORY_SECTION_NAME *info, SIZE_T len, SIZE_T *ret_len ) { + SIZE_T current_path_len, max_path_len; + WCHAR *name; NTSTATUS status;
if (!info) return STATUS_ACCESS_VIOLATION; + max_path_len = len - sizeof(*info) - sizeof(WCHAR); // dont count null char + if (!(name = malloc( max_path_len ))) return STATUS_NO_MEMORY;
SERVER_START_REQ( get_mapping_filename ) { req->process = wine_server_obj_handle( process ); req->addr = wine_server_client_ptr( addr ); if (len > sizeof(*info) + sizeof(WCHAR)) - wine_server_set_reply( req, info + 1, len - sizeof(*info) - sizeof(WCHAR) ); + wine_server_set_reply( req, name, max_path_len ); status = wine_server_call( req ); if (!status || status == STATUS_BUFFER_OVERFLOW) { - if (ret_len) *ret_len = sizeof(*info) + reply->len + sizeof(WCHAR); - if (len < sizeof(*info)) status = STATUS_INFO_LENGTH_MISMATCH; + current_path_len = reply->len; + if (len < sizeof(*info)) + { + status = STATUS_INFO_LENGTH_MISMATCH; + } + else if (!status) status = follow_device_symlink( (WCHAR *)(info + 1), max_path_len, name, ¤t_path_len); + + if (ret_len) *ret_len = sizeof(*info) + current_path_len + sizeof(WCHAR); if (!status) { info->SectionFileName.Buffer = (WCHAR *)(info + 1); - info->SectionFileName.Length = reply->len; - info->SectionFileName.MaximumLength = reply->len + sizeof(WCHAR); - info->SectionFileName.Buffer[reply->len / sizeof(WCHAR)] = 0; + info->SectionFileName.Length = current_path_len; + info->SectionFileName.MaximumLength = current_path_len + sizeof(WCHAR); + info->SectionFileName.Buffer[current_path_len / sizeof(WCHAR)] = 0; } } } SERVER_END_REQ; + free(name); return status; }
diff --git a/dlls/psapi/tests/psapi_main.c b/dlls/psapi/tests/psapi_main.c index c4a740310a4..d6fb8e69384 100644 --- a/dlls/psapi/tests/psapi_main.c +++ b/dlls/psapi/tests/psapi_main.c @@ -471,7 +471,6 @@ static void test_GetMappedFileName(void) ret = GetMappedFileNameA(GetCurrentProcess(), base, map_name, sizeof(map_name)); ok(ret, "GetMappedFileName error %d\n", GetLastError()); ok(ret > strlen(device_name), "map_name should be longer than device_name\n"); - todo_wine ok(memcmp(map_name, device_name, strlen(device_name)) == 0, "map name does not start with a device name: %s\n", map_name);
SetLastError(0xdeadbeef); @@ -482,7 +481,6 @@ static void test_GetMappedFileName(void) { ok(memcmp(map_nameW, nt_map_name, lstrlenW(map_nameW)) == 0, "map name does not start with a device name: %s\n", map_name); WideCharToMultiByte(CP_ACP, 0, map_nameW, -1, map_name, MAX_PATH, NULL, NULL); - todo_wine ok(memcmp(map_name, device_name, strlen(device_name)) == 0, "map name does not start with a device name: %s\n", map_name); }
@@ -490,7 +488,6 @@ static void test_GetMappedFileName(void) ret = GetMappedFileNameA(GetCurrentProcess(), base + 0x2000, map_name, sizeof(map_name)); ok(ret, "GetMappedFileName error %d\n", GetLastError()); ok(ret > strlen(device_name), "map_name should be longer than device_name\n"); - todo_wine ok(memcmp(map_name, device_name, strlen(device_name)) == 0, "map name does not start with a device name: %s\n", map_name);
SetLastError(0xdeadbeef); @@ -566,7 +563,7 @@ static void test_GetProcessImageFileName(void) { /* Windows returns 2*strlen-1 */ ok(ret >= strlen(szImgPath), "szImgPath="%s" ret=%d\n", szImgPath, ret); - todo_wine ok(!strcmp(szImgPath, szMapPath), "szImgPath="%s" szMapPath="%s"\n", szImgPath, szMapPath); + ok(!strcmp(szImgPath, szMapPath), "szImgPath="%s" szMapPath="%s"\n", szImgPath, szMapPath); }
SetLastError(0xdeadbeef);
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=97665
Your paranoid android.
=== debiant2 (32 bit report) ===
ntdll: info.c:2685: Test failed: got c0000017 info.c:2687: Test failed: Wrong count 3735928559 info.c:2717: Test failed: got c0000017
=== debiant2 (32 bit Chinese:China report) ===
ntdll: info.c:2685: Test failed: got c0000017 info.c:2687: Test failed: Wrong count 3735928559 info.c:2717: Test failed: got c0000017
=== debiant2 (32 bit WoW report) ===
ntdll: info.c:2685: Test failed: got c0000017 info.c:2687: Test failed: Wrong count 3735928559 info.c:2717: Test failed: got c0000017
=== debiant2 (64 bit WoW report) ===
ntdll: info.c:2685: Test failed: got c0000017 info.c:2687: Test failed: Wrong count 3735928559 info.c:2717: Test failed: got c0000017