[PATCH v3 4/4] ntdll: Semi-implement power request functions.

Chip Davis cdavis at codeweavers.com
Sun Sep 1 22:43:13 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.

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

diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index a6843c929895..2d64ec4aca45 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 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/powrprof/tests/powrprof.c b/dlls/powrprof/tests/powrprof.c
index ce9f96bfd90d..8fcb862b798f 100644
--- a/dlls/powrprof/tests/powrprof.c
+++ b/dlls/powrprof/tests/powrprof.c
@@ -173,31 +173,31 @@ static void test_system_execution_state_power_request()
     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 = CallNtPowerInformation(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 = CallNtPowerInformation(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 = CallNtPowerInformation(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 = CallNtPowerInformation(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