ReactOS 0.4.16-dev-141-g4c84e19
power.c File Reference
#include <win32k.h>
Include dependency graph for power.c:

Go to the source code of this file.

Functions

 DBG_DEFAULT_CHANNEL (UserPowerManager)
 
static VOID IntHandlePowerEventWorker (_In_ PWIN32_POWEREVENT_PARAMETERS pParameters)
 Handles a power event as a result from an incoming power callout from the kernel power manager.
 
static NTSTATUS IntValidateWin32PowerParams (_In_ PWIN32_POWEREVENT_PARAMETERS pParameters)
 Validates the power event parameters that come from a power callout from the kernel power manager.
 
static PWIN32POWERCALLOUT IntGetNextPowerCallout (_In_ PWIN32POWERCALLOUT pPowerCallout)
 Gets the next pending power callout from the global queue list and returns it to the caller. Note that the returned power callout is delisted from the list.
 
static VOID IntDeployPowerCallout (VOID)
 Deploys all pending power callouts to appropriate power callout workers.
 
static VOID IntEnlistPowerCallout (_In_ PWIN32POWERCALLOUT pPowerCallout)
 Enlists a newly allocated power callout into the queue list for later processing.
 
NTSTATUS NTAPI IntInitWin32PowerManagement (_In_ HANDLE hPowerRequestEvent)
 Initializes the power management side of Win32 kernel-mode subsystem component. This enables communication between the power manager of the NT kernel and Win32k.
 
NTSTATUS NTAPI IntWin32PowerManagementCleanup (VOID)
 Cleanup procedure that frees all the allocated resources by the power manager. It is triggered during Win32k subsystem unloading.
 
NTSTATUS NTAPI IntHandlePowerEvent (_In_ PWIN32_POWEREVENT_PARAMETERS pWin32PwrEventParams)
 Handles an incoming power event callout from the NT power manager.
 
NTSTATUS NTAPI IntHandlePowerState (_In_ PWIN32_POWERSTATE_PARAMETERS pWin32PwrStateParams)
 Handles an incoming power state callout from the NT power manager.
 

Variables

LIST_ENTRY gPowerCalloutsQueueList
 
PFAST_MUTEX gpPowerCalloutMutexLock
 
PKEVENT gpPowerRequestCalloutEvent
 
PKTHREAD gpPowerCalloutMutexOwnerThread
 

Function Documentation

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( UserPowerManager  )

◆ IntDeployPowerCallout()

static VOID IntDeployPowerCallout ( VOID  )
static

Deploys all pending power callouts to appropriate power callout workers.

Definition at line 160 of file power.c.

161{
162 PWIN32POWERCALLOUT pWin32PwrCallout;
163
164 /* Lock the entire USER subsystem down as we do particular stuff */
166
167 /*
168 * FIXME: While we did indeed lock the USER subsystem, there is a risk
169 * of the current calling thread might die or hang, so we should probably
170 * lock the thread while we deploy our power callout. The thread info
171 * provides a thread lock field for this purpose (see the ptl member from
172 * the _THREADINFO structure) but ReactOS lacks implementation to handle
173 * this. Suppose a thread happens to get into this fate, the power callout
174 * would never get signaled...
175 */
176
177 /* Deploy all the pending power callouts to the appropriate callout workers */
179 for (pWin32PwrCallout = IntGetNextPowerCallout(NULL);
180 pWin32PwrCallout != NULL;
181 pWin32PwrCallout = IntGetNextPowerCallout(pWin32PwrCallout))
182 {
183 if (pWin32PwrCallout->Type == POWER_CALLOUT_EVENT)
184 {
185 IntHandlePowerEventWorker(&pWin32PwrCallout->Params);
186 }
187 else // POWER_CALLOUT_STATE
188 {
189 ERR("Power state callout management is currently not implemented!\n");
190 }
191
192 /* We are done with this power callout */
193 ExFreePoolWithTag(pWin32PwrCallout, USERTAG_POWER);
194 }
195
196 /* Release what we locked */
198 UserLeave();
199}
#define ERR(fmt,...)
Definition: precomp.h:57
#define NULL
Definition: types.h:112
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:258
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:249
@ POWER_CALLOUT_EVENT
Definition: power.h:15
FORCEINLINE VOID IntReleasePowerCalloutLock(VOID)
Definition: power.h:87
FORCEINLINE VOID IntAcquirePowerCalloutLock(VOID)
Definition: power.h:78
POWER_CALLOUT_TYPE Type
Definition: power.h:31
WIN32_POWEREVENT_PARAMETERS Params
Definition: power.h:34
static PWIN32POWERCALLOUT IntGetNextPowerCallout(_In_ PWIN32POWERCALLOUT pPowerCallout)
Gets the next pending power callout from the global queue list and returns it to the caller....
Definition: power.c:121
static VOID IntHandlePowerEventWorker(_In_ PWIN32_POWEREVENT_PARAMETERS pParameters)
Handles a power event as a result from an incoming power callout from the kernel power manager.
Definition: power.c:34
#define USERTAG_POWER
Definition: tags.h:263

Referenced by IntEnlistPowerCallout().

◆ IntEnlistPowerCallout()

static VOID IntEnlistPowerCallout ( _In_ PWIN32POWERCALLOUT  pPowerCallout)
static

Enlists a newly allocated power callout into the queue list for later processing.

Parameters
[in]pPowerCalloutA pointer to a power callout that is to be inserted into the queue list.

Definition at line 212 of file power.c.

214{
215 PETHREAD CurrentThread;
216
217 /* Enlist it to the queue already */
219 InsertTailList(&gPowerCalloutsQueueList, &pPowerCallout->Link);
221
222 /*
223 * We have to let CSRSS process this power callout if one of the
224 * following conditions is TRUE for the current calling thread:
225 *
226 * - The process of the calling thread is a system process;
227 * - The process of the calling thread is attached;
228 * - The current calling thread is not a Win32 thread.
229 *
230 * For the second point, we cannot process the power callout ourselves
231 * as we must lock down USER exclusively for our own purpose, which requires
232 * us to be in a critical section. So we do not want to fiddle with a process
233 * that is attached with others.
234 */
235 CurrentThread = PsGetCurrentThread();
236 if (PsIsSystemThread(CurrentThread) ||
238 !IntIsThreadWin32Thread(CurrentThread))
239 {
240 /* Alert CSRSS of the presence of an enqueued power callout */
242 return;
243 }
244
245 /* Handle this power callout ourselves */
247}
#define FALSE
Definition: types.h:117
#define InsertTailList(ListHead, Entry)
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
BOOLEAN NTAPI PsIsSystemThread(IN PETHREAD Thread)
Definition: thread.c:878
FORCEINLINE BOOL IntIsThreadWin32Thread(_In_ PETHREAD Thread)
Definition: power.h:99
BOOLEAN NTAPI KeIsAttachedProcess(VOID)
Definition: procobj.c:693
LIST_ENTRY gPowerCalloutsQueueList
Definition: power.c:15
static VOID IntDeployPowerCallout(VOID)
Deploys all pending power callouts to appropriate power callout workers.
Definition: power.c:160
PKEVENT gpPowerRequestCalloutEvent
Definition: power.c:17
#define EVENT_INCREMENT
Definition: iotypes.h:597

Referenced by IntHandlePowerEvent().

◆ IntGetNextPowerCallout()

static PWIN32POWERCALLOUT IntGetNextPowerCallout ( _In_ PWIN32POWERCALLOUT  pPowerCallout)
static

Gets the next pending power callout from the global queue list and returns it to the caller. Note that the returned power callout is delisted from the list.

Parameters
[in]pPowerCalloutA pointer to a power callout entry that was previously returned by the same function. If this parameter is set to NULL the function will return the first callout entry from the list. Otherwise the function will return the next callout entry of the current power callout.
Returns
Returns a pointer to a power callout to the caller. If the list is empty then it will return NULL.
Remarks
The caller ASSUMES responsibility to lock down the power callout list before it begins enumerating the global list!

Definition at line 121 of file power.c.

123{
125 PWIN32POWERCALLOUT pPowerCalloutEntry = NULL;
126
127 /* Ensure the current calling thread owns the power callout lock */
129
130 /* This list is empty, acknowledge the caller */
132 {
133 return NULL;
134 }
135
136 /* The caller supplied a NULL argument, give them the first entry */
137 if (!pPowerCallout)
138 {
140 }
141 else
142 {
143 /* Otherwise give the caller the next power callout entry from the list */
144 Entry = pPowerCallout->Link.Flink;
145 }
146
147 /* Delist the power callout entry from the list and give it to caller */
148 pPowerCalloutEntry = CONTAINING_RECORD(Entry, WIN32POWERCALLOUT, Link);
149 RemoveEntryList(&pPowerCalloutEntry->Link);
150 return pPowerCalloutEntry;
151}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define ASSERT_POWER_CALLOUT_LOCK_ACQUIRED()
Definition: power.h:40
base of all file and directory entries
Definition: entries.h:83
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY Link
Definition: power.h:25
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
static int Link(const char **args)
Definition: vfdcmd.c:2414

Referenced by IntDeployPowerCallout(), and IntWin32PowerManagementCleanup().

◆ IntHandlePowerEvent()

NTSTATUS NTAPI IntHandlePowerEvent ( _In_ PWIN32_POWEREVENT_PARAMETERS  pWin32PwrEventParams)

Handles an incoming power event callout from the NT power manager.

Parameters
[in]pWin32PwrEventParamsA pointer to power event parameters that is given by the NT power manager of the kernel.
Returns
Returns STATUS_UNSUCCESSFUL if the Client/Server subsystem is not running, of which power callouts cannot be handled. Returns STATUS_INVALID_PARAMETER if the provided power event parameters are not valid. Returns STATUS_INSUFFICIENT_RESOURCES if there is a lack of memory to allocate for the power callout. Otherwise it returns STATUS_SUCCESS to indicate the power callout was handled successfully.

Definition at line 362 of file power.c.

364{
365 PWIN32POWERCALLOUT pWin32PwrCallout;
367
368 /*
369 * CSRSS is not running. As a consequence, the USER subsystem is neither
370 * up and running as the Client/Server subsystem is responsible to fire
371 * up other subsystems. Another case is that the system undergoes shutdown
372 * and Win32k cleanup is currently in effect. Either way, just quit.
373 */
374 if (!gpepCSRSS)
375 {
376 TRACE("CSRSS is not running, bailing out\n");
377 return STATUS_UNSUCCESSFUL;
378 }
379
380 /* Validate the power event parameters, just to be sure we have not gotten anything else */
381 Status = IntValidateWin32PowerParams(pWin32PwrEventParams);
382 if (!NT_SUCCESS(Status))
383 {
384 ERR("Could not deploy power callout, invalid Win32 power parameters!\n");
385 return Status;
386 }
387
388 /* Allocate pool of memory for this power callout */
389 pWin32PwrCallout = ExAllocatePoolZero(NonPagedPool,
390 sizeof(WIN32POWERCALLOUT),
392 if (pWin32PwrCallout == NULL)
393 {
394 ERR("Allocating memory for Win32 power callout failed\n");
396 }
397
398 /* Fill the necessary power datum */
399 pWin32PwrCallout->Type = POWER_CALLOUT_EVENT;
400 pWin32PwrCallout->Params.EventNumber = pWin32PwrEventParams->EventNumber;
401 pWin32PwrCallout->Params.Code = pWin32PwrEventParams->Code;
402
403 /* Enqueue this power request for later processing */
404 IntEnlistPowerCallout(pWin32PwrCallout);
405 return STATUS_SUCCESS;
406}
LONG NTSTATUS
Definition: precomp.h:26
PEPROCESS gpepCSRSS
Definition: csr.c:15
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define NonPagedPool
Definition: env_spec_w32.h:307
Status
Definition: gdiplustypes.h:25
FORCEINLINE PVOID ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
Definition: precomp.h:45
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE(s)
Definition: solgame.cpp:4
PSPOWEREVENTTYPE EventNumber
Definition: pstypes.h:1617
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
static VOID IntEnlistPowerCallout(_In_ PWIN32POWERCALLOUT pPowerCallout)
Enlists a newly allocated power callout into the queue list for later processing.
Definition: power.c:212
static NTSTATUS IntValidateWin32PowerParams(_In_ PWIN32_POWEREVENT_PARAMETERS pParameters)
Validates the power event parameters that come from a power callout from the kernel power manager.
Definition: power.c:82

Referenced by DriverEntry().

◆ IntHandlePowerEventWorker()

static VOID IntHandlePowerEventWorker ( _In_ PWIN32_POWEREVENT_PARAMETERS  pParameters)
static

Handles a power event as a result from an incoming power callout from the kernel power manager.

Parameters
[in]pParametersA pointer to the power event parameters containing the power event type and sub-code serving as additional datum for that power event type.

Definition at line 34 of file power.c.

36{
37 PSPOWEREVENTTYPE PwrEventType;
38 ULONG Code;
39
40 /* Cache the power event parameters and handle the power callout */
41 PwrEventType = pParameters->EventNumber;
42 Code = pParameters->Code;
43 switch (PwrEventType)
44 {
45 case PsW32SystemTime:
46 {
47 /*
48 * The power manager of the kernel notified us of an impending
49 * time change, broadcast this notification to all present windows.
50 */
53 0,
54 0);
55 break;
56 }
57
58 default:
59 {
60 TRACE("Power event of type %d is currently UNIMPLEMENTED (code %lu)\n", PwrEventType, Code);
61 break;
62 }
63 }
64}
#define Code
Definition: deflate.h:80
@ PsW32SystemTime
Definition: pstypes.h:451
enum _PSPOWEREVENTTYPE PSPOWEREVENTTYPE
uint32_t ULONG
Definition: typedefs.h:59
_In_ UCHAR _In_ UCHAR _In_ ULONG Code
Definition: wdfdevice.h:1701
BOOL FASTCALL UserSendNotifyMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:2090
#define HWND_BROADCAST
Definition: winuser.h:1207
#define WM_TIMECHANGE
Definition: winuser.h:1637

Referenced by IntDeployPowerCallout().

◆ IntHandlePowerState()

NTSTATUS NTAPI IntHandlePowerState ( _In_ PWIN32_POWERSTATE_PARAMETERS  pWin32PwrStateParams)

Handles an incoming power state callout from the NT power manager.

Parameters
[in]pWin32PwrStateParamsA pointer to power state parameters that is given by the NT power manager of the kernel.

Definition at line 419 of file power.c.

421{
422 /* FIXME */
423 ERR("IntHandlePowerState is UNIMPLEMENTED\n");
425}
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239

Referenced by DriverEntry().

◆ IntInitWin32PowerManagement()

NTSTATUS NTAPI IntInitWin32PowerManagement ( _In_ HANDLE  hPowerRequestEvent)

Initializes the power management side of Win32 kernel-mode subsystem component. This enables communication between the power manager of the NT kernel and Win32k.

Parameters
[in]hPowerRequestEventA handle to the global power request event, provided by the Winsrv module. This allows CSRSS to be notified of power callouts that cannot be handled by Win32k.
Returns
Returns STATUS_INSUFFICIENT_RESOURCES if pool allocation for the power callout lock has failed due to lack of necessary memory. A failure NTSTATUS code is returned if the power request event could not be referenced. Otherwise STATUS_SUCCESS is returned to indicate the power management has initialized successfully.

Definition at line 271 of file power.c.

273{
275
276 /* Allocate memory pool for the power callout mutex */
278 sizeof(FAST_MUTEX),
281 {
282 ERR("Failed to allocate pool of memory for the power callout mutex\n");
284 }
285
286 /* Initialize the mutex and owner thread */
289
290 /* Initialize the global queue list and the power callout (aka request) event object */
292 Status = ObReferenceObjectByHandle(hPowerRequestEvent,
297 NULL);
298 if (!NT_SUCCESS(Status))
299 {
300 ERR("Failed to reference the power callout event handle (Status 0x%08lx)\n", Status);
302 return Status;
303 }
304
305 return STATUS_SUCCESS;
306}
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
#define KernelMode
Definition: asm.h:34
POBJECT_TYPE ExEventObjectType
Definition: event.c:18
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
PFAST_MUTEX gpPowerCalloutMutexLock
Definition: power.c:16
PKTHREAD gpPowerCalloutMutexOwnerThread
Definition: power.c:18
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
FAST_MUTEX
Definition: extypes.h:17

Referenced by NtUserInitialize().

◆ IntValidateWin32PowerParams()

static NTSTATUS IntValidateWin32PowerParams ( _In_ PWIN32_POWEREVENT_PARAMETERS  pParameters)
static

Validates the power event parameters that come from a power callout from the kernel power manager.

Parameters
[in]pParametersA pointer to the power event parameters containing the power event type of which is to be validated against valid power events.
Returns
Returns STATUS_INVALID_PARAMETER if the captured power event type is unknown, otherwise STATUS_SUCCESS is returned.

Definition at line 82 of file power.c.

84{
85 PSPOWEREVENTTYPE PwrEventType;
86
87 /* Capture the event number and check if it is within bounds */
88 PwrEventType = pParameters->EventNumber;
89 if (PwrEventType < PsW32FullWake || PwrEventType > PsW32MonitorOff)
90 {
91 TRACE("Unknown event number found -> %d\n", PwrEventType);
93 }
94
95 return STATUS_SUCCESS;
96}
@ PsW32MonitorOff
Definition: pstypes.h:459
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135

Referenced by IntHandlePowerEvent().

◆ IntWin32PowerManagementCleanup()

NTSTATUS NTAPI IntWin32PowerManagementCleanup ( VOID  )

Cleanup procedure that frees all the allocated resources by the power manager. It is triggered during Win32k subsystem unloading.

Definition at line 315 of file power.c.

316{
317 PWIN32POWERCALLOUT pWin32PwrCallout;
318
319 /* Dereference the power request event */
322
323 /*
324 * Enumerate all pending power callouts and free them. We do not
325 * need to do this with the lock held as the CSR process is tore
326 * apart during Win32k cleanup, so future power callouts would not
327 * be allowed anyway, therefore we are safe.
328 */
329 for (pWin32PwrCallout = IntGetNextPowerCallout(NULL);
330 pWin32PwrCallout != NULL;
331 pWin32PwrCallout = IntGetNextPowerCallout(pWin32PwrCallout))
332 {
333 ExFreePoolWithTag(pWin32PwrCallout, USERTAG_POWER);
334 }
335
336 /* Tear apart the power callout lock mutex */
339 return STATUS_SUCCESS;
340}
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by _Function_class_().

Variable Documentation

◆ gPowerCalloutsQueueList

LIST_ENTRY gPowerCalloutsQueueList

◆ gpPowerCalloutMutexLock

◆ gpPowerCalloutMutexOwnerThread

PKTHREAD gpPowerCalloutMutexOwnerThread

◆ gpPowerRequestCalloutEvent

PKEVENT gpPowerRequestCalloutEvent