[PATCH v4 resend 3/4] ntdll: Implement SystemExecutionState handling.
Chip Davis
cdavis at codeweavers.com
Sun Nov 24 20:12:48 CST 2019
Get it from the server in NtPowerInformation(), and change it when
NtSetThreadExecutionState() is called.
Signed-off-by: Chip Davis <cdavis at codeweavers.com>
---
Notes:
v2: Handle thread termination.
v3: Put server changes back in their own patch.
v4: Update for test changes.
dlls/ntdll/nt.c | 33 ++++++++++++++++++++-------------
dlls/ntdll/tests/info.c | 16 ++++++++--------
2 files changed, 28 insertions(+), 21 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index c9b278d3fc9..a0dfec0632a 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -3161,15 +3161,18 @@ NTSTATUS WINAPI NtInitiatePowerAction(
*/
NTSTATUS WINAPI NtSetThreadExecutionState( EXECUTION_STATE new_state, EXECUTION_STATE *old_state )
{
- static EXECUTION_STATE current =
- ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED | ES_USER_PRESENT;
- *old_state = current;
+ NTSTATUS status;
WARN( "(0x%x, %p): stub, harmless.\n", new_state, old_state );
- if (!(current & ES_CONTINUOUS) || (new_state & ES_CONTINUOUS))
- current = new_state;
- return STATUS_SUCCESS;
+ SERVER_START_REQ( set_thread_execution_state )
+ {
+ req->new_state = new_state;
+ status = wine_server_call( req );
+ *old_state = reply->old_state;
+ }
+ SERVER_END_REQ;
+ return status;
}
/******************************************************************************
@@ -3361,13 +3364,17 @@ NTSTATUS WINAPI NtPowerInformation(
return fill_battery_state(lpOutputBuffer);
}
case SystemExecutionState: {
- PULONG ExecutionState = lpOutputBuffer;
- WARN("semi-stub: SystemExecutionState\n"); /* Needed for .NET Framework, but using a FIXME is really noisy. */
- if (lpInputBuffer != NULL)
- return STATUS_INVALID_PARAMETER;
- /* FIXME: The actual state should be the value set by SetThreadExecutionState which is not currently implemented. */
- *ExecutionState = ES_USER_PRESENT;
- return STATUS_SUCCESS;
+ EXECUTION_STATE *exec_state = lpOutputBuffer;
+ NTSTATUS status;
+ if (nOutputBufferSize < sizeof(EXECUTION_STATE))
+ return STATUS_BUFFER_TOO_SMALL;
+ SERVER_START_REQ( get_system_execution_state )
+ {
+ status = wine_server_call( req );
+ if (!status) *exec_state = reply->exec_state;
+ }
+ SERVER_END_REQ;
+ return status;
}
case ProcessorInformation: {
const int cannedMHz = 1000; /* We fake a 1GHz processor if we can't conjure up real values */
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index 8e743320c65..f37b1a68cd0 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -1019,7 +1019,7 @@ static void test_system_execution_state(void)
ok(status == STATUS_SUCCESS, "status %08x\n", status);
old_es = SetThreadExecutionState(ES_SYSTEM_REQUIRED);
- todo_wine ok(old_es == ES_CONTINUOUS, "unexpected execution state 0x%08x\n", old_es);
+ ok(old_es == ES_CONTINUOUS, "unexpected execution state 0x%08x\n", old_es);
old_es = es;
status = pNtPowerInformation(SystemExecutionState, NULL, 0, &es, sizeof(es));
@@ -1027,11 +1027,11 @@ static void test_system_execution_state(void)
ok(es == old_es, "unexpected execution state 0x%08x vs 0x%08x\n", es, old_es);
old_es = SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED);
- todo_wine ok(old_es == ES_CONTINUOUS, "unexpected execution state 0x%08x\n", old_es);
+ ok(old_es == ES_CONTINUOUS, "unexpected execution state 0x%08x\n", old_es);
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);
old_es = SetThreadExecutionState(ES_CONTINUOUS);
ok(old_es == (ES_CONTINUOUS|ES_DISPLAY_REQUIRED), "unexpected execution state 0x%08x\n", old_es);
@@ -1104,23 +1104,23 @@ static void test_system_execution_state_other_thread(void)
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);
es = SetThreadExecutionState(0);
- todo_wine ok(es == ES_CONTINUOUS, "unexpected execution state 0x%08x\n", es);
+ ok(es == ES_CONTINUOUS, "unexpected execution state 0x%08x\n", es);
SignalObjectAndWait(events[1], events[0], INFINITE, FALSE);
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);
es = SetThreadExecutionState(0);
- todo_wine ok(es == ES_CONTINUOUS, "unexpected execution state 0x%08x\n", es);
+ ok(es == ES_CONTINUOUS, "unexpected execution state 0x%08x\n", es);
SignalObjectAndWait(events[1], thread, INFINITE, FALSE);
status = pNtPowerInformation(SystemExecutionState, NULL, 0, &es, sizeof(es));
ok(status == STATUS_SUCCESS, "status %08x\n", status);
ok(es == base_es, "unexpected execution state 0x%08x\n", es);
es = SetThreadExecutionState(0);
- todo_wine ok(es == ES_CONTINUOUS, "unexpected execution state 0x%08x\n", es);
+ ok(es == ES_CONTINUOUS, "unexpected execution state 0x%08x\n", es);
CloseHandle(thread);
CloseHandle(events[0]);
--
2.21.0
More information about the wine-devel
mailing list