Alexandre Julliard : kernelbase: Implement GetMappedFileNameA/W.

Alexandre Julliard julliard at winehq.org
Thu Feb 11 15:37:14 CST 2021


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Feb 11 11:01:28 2021 +0100

kernelbase: Implement GetMappedFileNameA/W.

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

---

 dlls/kernelbase/debug.c       | 40 ++++++++++++++++++++++++++++++++++------
 dlls/psapi/tests/psapi_main.c | 28 ++++------------------------
 server/mapping.c              |  5 +++--
 3 files changed, 41 insertions(+), 32 deletions(-)

diff --git a/dlls/kernelbase/debug.c b/dlls/kernelbase/debug.c
index 55d5fcd3551..cbc53e22ac1 100644
--- a/dlls/kernelbase/debug.c
+++ b/dlls/kernelbase/debug.c
@@ -1130,9 +1130,23 @@ DWORD WINAPI DECLSPEC_HOTPATCH GetDeviceDriverFileNameW( void *image_base, WCHAR
  */
 DWORD WINAPI DECLSPEC_HOTPATCH GetMappedFileNameA( HANDLE process, void *addr, char *name, DWORD size )
 {
-    FIXME( "(%p, %p, %p, %d): stub\n", process, addr, name, size );
-    if (name && size) name[0] = 0;
-    return 0;
+    WCHAR nameW[MAX_PATH];
+    DWORD len;
+
+    if (size && !name)
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return 0;
+    }
+    if (!GetMappedFileNameW( process, addr, nameW, MAX_PATH )) return 0;
+    if (!size)
+    {
+        SetLastError( ERROR_INSUFFICIENT_BUFFER );
+        return 0;
+    }
+    len = file_name_WtoA( nameW, wcslen(nameW), name, size );
+    name[min(len, size - 1)] = 0;
+    return len;
 }
 
 
@@ -1142,9 +1156,23 @@ DWORD WINAPI DECLSPEC_HOTPATCH GetMappedFileNameA( HANDLE process, void *addr, c
  */
 DWORD WINAPI DECLSPEC_HOTPATCH GetMappedFileNameW( HANDLE process, void *addr, WCHAR *name, DWORD size )
 {
-    FIXME( "(%p, %p, %p, %d): stub\n", process, addr, name, size );
-    if (name && size) name[0] = 0;
-    return 0;
+    ULONG_PTR buffer[(sizeof(MEMORY_SECTION_NAME) + MAX_PATH * sizeof(WCHAR)) / sizeof(ULONG_PTR)];
+    MEMORY_SECTION_NAME *mem = (MEMORY_SECTION_NAME *)buffer;
+    DWORD len;
+
+    if (size && !name)
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return 0;
+    }
+    if (!set_ntstatus( NtQueryVirtualMemory( process, addr, MemorySectionName, mem, sizeof(buffer), NULL )))
+        return 0;
+
+    len = mem->SectionFileName.Length / sizeof(WCHAR);
+    memcpy( name, mem->SectionFileName.Buffer, min( mem->SectionFileName.Length, size * sizeof(WCHAR) ));
+    if (len >= size) SetLastError( ERROR_INSUFFICIENT_BUFFER );
+    name[min(len, size - 1)] = 0;
+    return len;
 }
 
 
diff --git a/dlls/psapi/tests/psapi_main.c b/dlls/psapi/tests/psapi_main.c
index 91100d30e94..8f94e0b5798 100644
--- a/dlls/psapi/tests/psapi_main.c
+++ b/dlls/psapi/tests/psapi_main.c
@@ -402,27 +402,22 @@ static void test_GetMappedFileName(void)
     SetLastError(0xdeadbeef);
     ret = GetMappedFileNameA(NULL, hMod, szMapPath, sizeof(szMapPath));
     ok(!ret, "GetMappedFileName should fail\n");
-todo_wine
     ok(GetLastError() == ERROR_INVALID_HANDLE, "expected error=ERROR_INVALID_HANDLE but got %d\n", GetLastError());
 
     SetLastError(0xdeadbeef);
     ret = GetMappedFileNameA(hpSR, hMod, szMapPath, sizeof(szMapPath));
     ok(!ret, "GetMappedFileName should fail\n");
-todo_wine
     ok(GetLastError() == ERROR_ACCESS_DENIED, "expected error=ERROR_ACCESS_DENIED but got %d\n", GetLastError());
 
     SetLastError( 0xdeadbeef );
     ret = GetMappedFileNameA(hpQI, hMod, szMapPath, sizeof(szMapPath));
-todo_wine
     ok( ret || broken(GetLastError() == ERROR_UNEXP_NET_ERR), /* win2k */
         "GetMappedFileNameA failed with error %u\n", GetLastError() );
     if (ret)
     {
         ok(ret == strlen(szMapPath), "szMapPath=\"%s\" ret=%d\n", szMapPath, ret);
-        todo_wine
         ok(szMapPath[0] == '\\', "szMapPath=\"%s\"\n", szMapPath);
         szMapBaseName = strrchr(szMapPath, '\\'); /* That's close enough for us */
-        todo_wine
         ok(szMapBaseName && *szMapBaseName, "szMapPath=\"%s\"\n", szMapPath);
         if (szMapBaseName)
         {
@@ -460,36 +455,30 @@ todo_wine
     SetLastError(0xdeadbeef);
     ret = GetMappedFileNameA(GetCurrentProcess(), base, map_name, 0);
     ok(!ret, "GetMappedFileName should fail\n");
-todo_wine
     ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_INSUFFICIENT_BUFFER,
        "wrong error %d\n", GetLastError());
 
     SetLastError(0xdeadbeef);
     ret = GetMappedFileNameA(GetCurrentProcess(), base, 0, sizeof(map_name));
     ok(!ret, "GetMappedFileName should fail\n");
-todo_wine
     ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
 
     SetLastError(0xdeadbeef);
     ret = GetMappedFileNameA(GetCurrentProcess(), base, map_name, 1);
-todo_wine
     ok(ret == 1, "GetMappedFileName error %d\n", GetLastError());
     ok(!map_name[0] || broken(map_name[0] == device_name[0]) /* before win2k */, "expected 0, got %c\n", map_name[0]);
 
     SetLastError(0xdeadbeef);
     ret = GetMappedFileNameA(GetCurrentProcess(), base, map_name, sizeof(map_name));
-todo_wine {
     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);
     ret = GetMappedFileNameW(GetCurrentProcess(), base, map_nameW, ARRAY_SIZE(map_nameW));
-todo_wine {
     ok(ret, "GetMappedFileNameW error %d\n", GetLastError());
     ok(ret > strlen(device_name), "map_name should be longer than device_name\n");
-}
     if (nt_get_mapped_file_name(GetCurrentProcess(), base, nt_map_name, ARRAY_SIZE(nt_map_name)))
     {
         ok(memcmp(map_nameW, nt_map_name, lstrlenW(map_nameW)) == 0, "map name does not start with a device name: %s\n", map_name);
@@ -500,28 +489,24 @@ todo_wine {
 
     SetLastError(0xdeadbeef);
     ret = GetMappedFileNameA(GetCurrentProcess(), base + 0x2000, map_name, sizeof(map_name));
-todo_wine {
     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);
     ret = GetMappedFileNameA(GetCurrentProcess(), base + 0x4000, map_name, sizeof(map_name));
     ok(!ret, "GetMappedFileName should fail\n");
-todo_wine
     ok(GetLastError() == ERROR_UNEXP_NET_ERR, "expected ERROR_UNEXP_NET_ERR, got %d\n", GetLastError());
 
     SetLastError(0xdeadbeef);
     ret = GetMappedFileNameA(GetCurrentProcess(), NULL, map_name, sizeof(map_name));
     ok(!ret, "GetMappedFileName should fail\n");
-todo_wine
     ok(GetLastError() == ERROR_UNEXP_NET_ERR, "expected ERROR_UNEXP_NET_ERR, got %d\n", GetLastError());
 
     SetLastError(0xdeadbeef);
     ret = GetMappedFileNameA(0, base, map_name, sizeof(map_name));
     ok(!ret, "GetMappedFileName should fail\n");
-todo_wine
     ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
 
     UnmapViewOfFile(base);
@@ -540,7 +525,6 @@ todo_wine
     SetLastError(0xdeadbeef);
     ret = GetMappedFileNameA(GetCurrentProcess(), base, map_name, sizeof(map_name));
     ok(!ret, "GetMappedFileName should fail\n");
-todo_wine
     ok(GetLastError() == ERROR_FILE_INVALID, "expected ERROR_FILE_INVALID, got %d\n", GetLastError());
 
     UnmapViewOfFile(base);
@@ -562,11 +546,7 @@ static void test_GetProcessImageFileName(void)
 	    win_skip("GetProcessImageFileName not implemented\n");
             return;
         }
-
-        if(GetLastError() == 0xdeadbeef)
-	    todo_wine ok(0, "failed without error code\n");
-	else
-	    todo_wine ok(0, "failed with %d\n", GetLastError());
+        ok(0, "failed with %d\n", GetLastError());
     }
 
     SetLastError(0xdeadbeef);
@@ -586,7 +566,7 @@ static void test_GetProcessImageFileName(void)
     if(ret && ret1)
     {
         /* Windows returns 2*strlen-1 */
-        todo_wine ok(ret >= strlen(szImgPath), "szImgPath=\"%s\" ret=%d\n", szImgPath, ret);
+        ok(ret >= strlen(szImgPath), "szImgPath=\"%s\" ret=%d\n", szImgPath, ret);
         todo_wine ok(!strcmp(szImgPath, szMapPath), "szImgPath=\"%s\" szMapPath=\"%s\"\n", szImgPath, szMapPath);
     }
 
diff --git a/server/mapping.c b/server/mapping.c
index be026e63f25..9728beca959 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -1234,8 +1234,9 @@ DECL_HANDLER(get_mapping_filename)
     if ((view = find_mapped_addr( process, req->addr )) && get_view_nt_name( view, &name ))
     {
         reply->len = name.len;
-        if (name.len <= get_reply_max_size()) set_reply_data( name.str, name.len );
-        else set_error( STATUS_BUFFER_OVERFLOW );
+        if (name.len > get_reply_max_size()) set_error( STATUS_BUFFER_OVERFLOW );
+        else if (!name.len) set_error( STATUS_FILE_INVALID );
+        else set_reply_data( name.str, name.len );
     }
     else set_error( STATUS_INVALID_ADDRESS );
 




More information about the wine-cvs mailing list