Author: fireball Date: Fri Jun 26 13:39:00 2009 New Revision: 41620
URL: http://svn.reactos.org/svn/reactos?rev=41620&view=rev Log: - Implement NtSetThreadExecutionState (in place of what has been committed in r41599 and reverted in 41619).
Modified: trunk/reactos/ntoskrnl/po/power.c
Modified: trunk/reactos/ntoskrnl/po/power.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/po/power.c?rev=416... ============================================================================== --- trunk/reactos/ntoskrnl/po/power.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/po/power.c [iso-8859-1] Fri Jun 26 13:39:00 2009 @@ -588,6 +588,54 @@ NtSetThreadExecutionState(IN EXECUTION_STATE esFlags, OUT EXECUTION_STATE *PreviousFlags) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} + PKTHREAD Thread = KeGetCurrentThread(); + KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); + EXECUTION_STATE PreviousState; + PAGED_CODE(); + + /* Validate flags */ + if (esFlags & ~(ES_CONTINUOUS | ES_USER_PRESENT)) + { + /* Fail the request */ + return STATUS_INVALID_PARAMETER; + } + + /* Check for user parameters */ + if (PreviousMode != KernelMode) + { + /* Protect the probes */ + _SEH2_TRY + { + /* Check if the pointer is valid */ + ProbeForWriteUlong(PreviousFlags); + } + _SEH2_EXCEPT(ExSystemExceptionFilter()) + { + /* It isn't -- fail */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + } + + /* Save the previous state, always masking in the continous flag */ + PreviousState = Thread->PowerState | ES_CONTINUOUS; + + /* Check if we need to update the power state */ + if (esFlags & ES_CONTINUOUS) Thread->PowerState = esFlags; + + /* Protect the write back to user mode */ + _SEH2_TRY + { + /* Return the previous flags */ + *PreviousFlags = PreviousState; + } + _SEH2_EXCEPT(ExSystemExceptionFilter()) + { + /* Something's wrong, fail */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + + /* All is good */ + return STATUS_SUCCESS; +}