[PATCH v4 4/4] ntdll: Partially implement power request functions.

Chip Davis cdavis at codeweavers.com
Fri Sep 27 15:30:32 CDT 2019


These create the object and alter the system execution state, but don't
actually force the computer to stay awake. It should be simple enough to
implement that on Mac OS. Linux might be a problem--in this instance,
we'll probably need to call out to some daemon over DBus.

Signed-off-by: Chip Davis <cdavis at codeweavers.com>
---

Notes:
    v2: Fix object leak.
    v3: Remove half-implemented support for detailed reasons. Fix length passed to server. Put server changes in their own patch.
    v4: Update for test changes. Fix broken build.

 dlls/ntdll/nt.c         | 56 ++++++++++++++++++++++++++++++++++++-----
 dlls/ntdll/tests/info.c | 14 +++++------
 2 files changed, 57 insertions(+), 13 deletions(-)

diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index 21399e0c4310..46f29115253e 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -51,6 +51,7 @@
 #include <time.h>
 
 #define NONAMELESSUNION
+#define NONAMELESSSTRUCT
 #include "ntstatus.h"
 #define WIN32_NO_STATUS
 #include "wine/debug.h"
@@ -3084,9 +3085,32 @@ NTSTATUS WINAPI NtSetThreadExecutionState( EXECUTION_STATE new_state, EXECUTION_
  */
 NTSTATUS WINAPI NtCreatePowerRequest( HANDLE *handle, COUNTED_REASON_CONTEXT *context )
 {
-    FIXME( "(%p, %p): stub\n", handle, context );
+    UNICODE_STRING reason;
+    NTSTATUS status;
+    HMODULE mod = NULL;
+    static const WCHAR emptyW[] = {0};
 
-    return STATUS_NOT_IMPLEMENTED;
+    WARN( "(%p, %p): semi-stub\n", handle, context );
+
+    if (context->Flags & POWER_REQUEST_CONTEXT_SIMPLE_STRING)
+        reason = context->u.SimpleString;
+    else if (context->Flags & POWER_REQUEST_CONTEXT_DETAILED_STRING)
+    {
+        FIXME( "detailed reason strings are not supported\n" );
+        RtlInitUnicodeString( &reason, emptyW );
+    }
+
+    SERVER_START_REQ( create_power_request )
+    {
+        wine_server_add_data( req, reason.Buffer, reason.Length );
+        status = wine_server_call( req );
+        if (!status)
+            *handle = wine_server_ptr_handle( reply->handle );
+    }
+    SERVER_END_REQ;
+
+    if (mod) LdrUnloadDll( mod );
+    return status;
 }
 
 /******************************************************************************
@@ -3095,9 +3119,19 @@ NTSTATUS WINAPI NtCreatePowerRequest( HANDLE *handle, COUNTED_REASON_CONTEXT *co
  */
 NTSTATUS WINAPI NtSetPowerRequest( HANDLE handle, POWER_REQUEST_TYPE type )
 {
-    FIXME( "(%p, %u): stub\n", handle, type );
+    NTSTATUS status;
 
-    return STATUS_NOT_IMPLEMENTED;
+    WARN( "(%p, %u): semi-stub\n", handle, type );
+
+    SERVER_START_REQ( set_power_request )
+    {
+        req->handle = wine_server_obj_handle( handle );
+        req->request = type;
+        status = wine_server_call( req );
+    }
+    SERVER_END_REQ;
+
+    return status;
 }
 
 /******************************************************************************
@@ -3106,9 +3140,19 @@ NTSTATUS WINAPI NtSetPowerRequest( HANDLE handle, POWER_REQUEST_TYPE type )
  */
 NTSTATUS WINAPI NtClearPowerRequest( HANDLE handle, POWER_REQUEST_TYPE type )
 {
-    FIXME( "(%p, %u): stub\n", handle, type );
+    NTSTATUS status;
 
-    return STATUS_NOT_IMPLEMENTED;
+    WARN( "(%p, %u): semi-stub\n", handle, type );
+
+    SERVER_START_REQ( clear_power_request )
+    {
+        req->handle = wine_server_obj_handle( handle );
+        req->request = type;
+        status = wine_server_call( req );
+    }
+    SERVER_END_REQ;
+
+    return status;
 }
 
 #ifdef linux
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index 752660c7b8a4..e42c40d8b80e 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -1150,31 +1150,31 @@ static void test_system_execution_state_power_request(void)
     reason.Flags = POWER_REQUEST_CONTEXT_SIMPLE_STRING;
     reason.Reason.SimpleReasonString = reasonW;
     req = pPowerCreateRequest(&reason);
-    todo_wine ok(req != INVALID_HANDLE_VALUE, "err %u\n", GetLastError());
+    ok(req != INVALID_HANDLE_VALUE, "err %u\n", GetLastError());
 
     ret = pPowerSetRequest(req, PowerRequestSystemRequired);
-    todo_wine ok(ret, "err %u\n", GetLastError());
+    ok(ret, "err %u\n", GetLastError());
 
     status = pNtPowerInformation(SystemExecutionState, NULL, 0, &es, sizeof(es));
     ok(status == STATUS_SUCCESS, "status %08x\n", status);
-    todo_wine ok(es & ES_SYSTEM_REQUIRED, "unexpected execution state 0x%08x\n", es);
+    ok(es & ES_SYSTEM_REQUIRED, "unexpected execution state 0x%08x\n", es);
 
     ret = pPowerClearRequest(req, PowerRequestSystemRequired);
-    todo_wine ok(ret, "err %u\n", GetLastError());
+    ok(ret, "err %u\n", GetLastError());
 
     status = pNtPowerInformation(SystemExecutionState, NULL, 0, &es, sizeof(es));
     ok(status == STATUS_SUCCESS, "status %08x\n", status);
     ok(!(es & ES_SYSTEM_REQUIRED) || (base_es & ES_SYSTEM_REQUIRED), "unexpected execution state 0x%08x\n", es);
 
     ret = pPowerSetRequest(req, PowerRequestDisplayRequired);
-    todo_wine ok(ret, "err %u\n", GetLastError());
+    ok(ret, "err %u\n", GetLastError());
 
     status = pNtPowerInformation(SystemExecutionState, NULL, 0, &es, sizeof(es));
     ok(status == STATUS_SUCCESS, "status %08x\n", status);
-    todo_wine ok(es & ES_DISPLAY_REQUIRED, "unexpected execution state 0x%08x\n", es);
+    ok(es & ES_DISPLAY_REQUIRED, "unexpected execution state 0x%08x\n", es);
 
     ret = CloseHandle(req);
-    todo_wine ok(ret, "err %u\n", GetLastError());
+    ok(ret, "err %u\n", GetLastError());
 
     status = pNtPowerInformation(SystemExecutionState, NULL, 0, &es, sizeof(es));
     ok(status == STATUS_SUCCESS, "status %08x\n", status);
-- 
2.21.0




More information about the wine-devel mailing list