From: Chip Davis Subject: [PATCH v4 resend 4/4] ntdll: Partially implement power request functions. Message-Id: <20191125021249.50751-4-cdavis@codeweavers.com> Date: Sun, 24 Nov 2019 20:12:49 -0600 In-Reply-To: <20191125021249.50751-3-cdavis@codeweavers.com> References: <20191125021249.50751-1-cdavis@codeweavers.com> <20191125021249.50751-2-cdavis@codeweavers.com> <20191125021249.50751-3-cdavis@codeweavers.com> 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 --- 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 a0dfec0632a..ceda544a4df 100644 --- a/dlls/ntdll/nt.c +++ b/dlls/ntdll/nt.c @@ -64,6 +64,7 @@ #endif #define NONAMELESSUNION +#define NONAMELESSSTRUCT #include "ntstatus.h" #define WIN32_NO_STATUS #include "wine/debug.h" @@ -3181,9 +3182,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; } /****************************************************************************** @@ -3192,9 +3216,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; } /****************************************************************************** @@ -3203,9 +3237,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 f37b1a68cd0..e710e54b1ad 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