[PATCH] kernelbase: Implement GetOverlappedResultEx().

Zebediah Figura z.figura12 at gmail.com
Thu Nov 28 18:19:21 CST 2019


Mentioned in https://bugs.winehq.org/show_bug.cgi?id=38830.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/kernel32/kernel32.spec     |  1 +
 dlls/kernel32/tests/pipe.c      | 54 +++++++++++++++++++++++++++++++++
 dlls/kernelbase/file.c          | 23 ++++++++++++--
 dlls/kernelbase/kernelbase.spec |  2 +-
 include/winbase.h               |  1 +
 5 files changed, 77 insertions(+), 4 deletions(-)

diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec
index 82e10850a8..172be2a6e2 100644
--- a/dlls/kernel32/kernel32.spec
+++ b/dlls/kernel32/kernel32.spec
@@ -760,6 +760,7 @@
 @ stdcall GetNumberOfConsoleMouseButtons(ptr)
 @ stdcall -import GetOEMCP()
 @ stdcall -import GetOverlappedResult(long ptr ptr long)
+@ stdcall -import GetOverlappedResultEx(long ptr ptr long long)
 @ stdcall GetUserPreferredUILanguages(long ptr ptr ptr)
 @ stdcall GetPackageFullName(long ptr ptr)
 @ stdcall -import GetPhysicallyInstalledSystemMemory(ptr)
diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c
index d8d5726f1a..20f3450c6d 100644
--- a/dlls/kernel32/tests/pipe.c
+++ b/dlls/kernel32/tests/pipe.c
@@ -42,6 +42,7 @@ static BOOL (WINAPI *pGetNamedPipeClientProcessId)(HANDLE,ULONG*);
 static BOOL (WINAPI *pGetNamedPipeServerProcessId)(HANDLE,ULONG*);
 static BOOL (WINAPI *pGetNamedPipeClientSessionId)(HANDLE,ULONG*);
 static BOOL (WINAPI *pGetNamedPipeServerSessionId)(HANDLE,ULONG*);
+static BOOL (WINAPI *pGetOverlappedResultEx)(HANDLE,OVERLAPPED *,DWORD *,DWORD,BOOL);
 
 static BOOL user_apc_ran;
 static void CALLBACK user_apc(ULONG_PTR param)
@@ -4065,6 +4066,57 @@ static void test_nowait(DWORD pipe_type)
     ok(CloseHandle(pipewrite), "CloseHandle for the write pipe failed\n");
 }
 
+static void test_GetOverlappedResultEx(void)
+{
+    HANDLE client, server;
+    OVERLAPPED ovl;
+    char buffer[8000];
+    DWORD ret_size;
+    BOOL ret;
+
+    if (!pGetOverlappedResultEx)
+    {
+        win_skip("GetOverlappedResultEx() is not available\n");
+        return;
+    }
+
+    create_overlapped_pipe(PIPE_TYPE_BYTE, &client, &server);
+
+    overlapped_write_async(client, buffer, sizeof(buffer), &ovl);
+
+    user_apc_ran = FALSE;
+    QueueUserAPC(user_apc, GetCurrentThread(), 0);
+
+    SetLastError(0xdeadbeef);
+    ret = pGetOverlappedResultEx(client, &ovl, &ret_size, 0, FALSE);
+    ok(!ret, "expected failure\n");
+    ok(GetLastError() == ERROR_IO_INCOMPLETE, "wrong error %u\n", GetLastError());
+    ok(!user_apc_ran, "APC should not have run\n");
+
+    SetLastError(0xdeadbeef);
+    ret = pGetOverlappedResultEx(client, &ovl, &ret_size, 0, TRUE);
+    ok(!ret, "expected failure\n");
+    ok(GetLastError() == ERROR_IO_INCOMPLETE, "wrong error %u\n", GetLastError());
+    ok(!user_apc_ran, "APC should not have run\n");
+
+    SetLastError(0xdeadbeef);
+    ret = pGetOverlappedResultEx(client, &ovl, &ret_size, 10, FALSE);
+    ok(!ret, "expected failure\n");
+    ok(GetLastError() == WAIT_TIMEOUT, "wrong error %u\n", GetLastError());
+    ok(!user_apc_ran, "APC should not have run\n");
+
+    SetLastError(0xdeadbeef);
+    ret = pGetOverlappedResultEx(client, &ovl, &ret_size, 10, TRUE);
+    ok(!ret, "expected failure\n");
+    ok(GetLastError() == WAIT_IO_COMPLETION, "wrong error %u\n", GetLastError());
+    ok(user_apc_ran, "APC should have run\n");
+
+    CloseHandle(ovl.hEvent);
+
+    CloseHandle(client);
+    CloseHandle(server);
+}
+
 START_TEST(pipe)
 {
     char **argv;
@@ -4080,6 +4132,7 @@ START_TEST(pipe)
     pGetNamedPipeServerProcessId = (void *) GetProcAddress(hmod, "GetNamedPipeServerProcessId");
     pGetNamedPipeClientSessionId = (void *) GetProcAddress(hmod, "GetNamedPipeClientSessionId");
     pGetNamedPipeServerSessionId = (void *) GetProcAddress(hmod, "GetNamedPipeServerSessionId");
+    pGetOverlappedResultEx = (void *)GetProcAddress(hmod, "GetOverlappedResultEx");
 
     argc = winetest_get_mainargs(&argv);
 
@@ -4134,4 +4187,5 @@ START_TEST(pipe)
     test_wait_pipe();
     test_nowait(PIPE_TYPE_BYTE);
     test_nowait(PIPE_TYPE_MESSAGE);
+    test_GetOverlappedResultEx();
 }
diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c
index aa2ebfcc69..8e601c7cb2 100644
--- a/dlls/kernelbase/file.c
+++ b/dlls/kernelbase/file.c
@@ -2002,21 +2002,38 @@ DWORD WINAPI DECLSPEC_HOTPATCH GetFileType( HANDLE file )
  */
 BOOL WINAPI DECLSPEC_HOTPATCH GetOverlappedResult( HANDLE file, LPOVERLAPPED overlapped,
                                                    LPDWORD result, BOOL wait )
+{
+    return GetOverlappedResultEx( file, overlapped, result, wait ? INFINITE : 0, FALSE );
+}
+
+
+/***********************************************************************
+ *	GetOverlappedResultEx   (kernelbase.@)
+ */
+BOOL WINAPI DECLSPEC_HOTPATCH GetOverlappedResultEx( HANDLE file, OVERLAPPED *overlapped,
+                                                     DWORD *result, DWORD timeout, BOOL alertable )
 {
     NTSTATUS status;
+    DWORD ret;
 
-    TRACE( "(%p %p %p %x)\n", file, overlapped, result, wait );
+    TRACE( "(%p %p %p %u %d)\n", file, overlapped, result, timeout, alertable );
 
     status = overlapped->Internal;
     if (status == STATUS_PENDING)
     {
-        if (!wait)
+        if (!timeout)
         {
             SetLastError( ERROR_IO_INCOMPLETE );
             return FALSE;
         }
-        if (WaitForSingleObject( overlapped->hEvent ? overlapped->hEvent : file, INFINITE ) == WAIT_FAILED)
+        ret = WaitForSingleObjectEx( overlapped->hEvent ? overlapped->hEvent : file, timeout, alertable );
+        if (ret == WAIT_FAILED)
             return FALSE;
+        else if (ret)
+        {
+            SetLastError(ret);
+            return FALSE;
+        }
 
         status = overlapped->Internal;
         if (status == STATUS_PENDING) status = STATUS_SUCCESS;
diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec
index 14ee402089..ed5d1f73f8 100644
--- a/dlls/kernelbase/kernelbase.spec
+++ b/dlls/kernelbase/kernelbase.spec
@@ -584,7 +584,7 @@
 # @ stub GetOsManufacturingMode
 # @ stub GetOsSafeBootMode
 @ stdcall GetOverlappedResult(long ptr ptr long)
-# @ stub GetOverlappedResultEx
+@ stdcall GetOverlappedResultEx(long ptr ptr long long)
 # @ stub GetPackageApplicationContext
 # @ stub GetPackageApplicationIds
 # @ stub GetPackageApplicationProperty
diff --git a/include/winbase.h b/include/winbase.h
index 8b30c5a69a..2d01dcb606 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -2215,6 +2215,7 @@ WINBASEAPI BOOL        WINAPI GetNumaProximityNodeEx(ULONG,PUSHORT);
 WINADVAPI  BOOL        WINAPI GetNumberOfEventLogRecords(HANDLE,PDWORD);
 WINADVAPI  BOOL        WINAPI GetOldestEventLogRecord(HANDLE,PDWORD);
 WINBASEAPI BOOL        WINAPI GetOverlappedResult(HANDLE,LPOVERLAPPED,LPDWORD,BOOL);
+WINBASEAPI BOOL        WINAPI GetOverlappedResultEx(HANDLE,OVERLAPPED*,DWORD*,DWORD,BOOL);
 WINBASEAPI DWORD       WINAPI GetPriorityClass(HANDLE);
 WINADVAPI  BOOL        WINAPI GetPrivateObjectSecurity(PSECURITY_DESCRIPTOR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,DWORD,PDWORD);
 WINBASEAPI UINT        WINAPI GetPrivateProfileIntA(LPCSTR,LPCSTR,INT,LPCSTR);
-- 
2.24.0




More information about the wine-devel mailing list