Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

power.c File Reference

#include "precomp.h"
#include <ntcsrmsg.h>
#include "csrmsg.h"
#include "ntddvdeo.h"

Go to the source code of this file.

Classes

struct  tagPOWERREQUEST

Typedefs

typedef tagPOWERREQUEST POWERREQUEST
typedef tagPOWERREQUESTPPOWERREQUEST

Functions

__inline VOID EnterPowerCrit ()
__inline VOID LeavePowerCrit ()
VOID CancelPowerRequest (PPOWERREQUEST pPowerRequest)
NTSTATUS QueuePowerRequest (PKWIN32_POWEREVENT_PARAMETERS Parms)
PPOWERREQUEST UnqueuePowerRequest (VOID)
NTSTATUS InitializePowerRequestList (HANDLE hPowerRequestEvent)
VOID CleanupPowerRequestList (VOID)
VOID DeletePowerRequestList (VOID)
NTSTATUS xxxUserPowerEventCalloutWorker (PKWIN32_POWEREVENT_PARAMETERS Parms)
NTSTATUS UserPowerEventCallout (PKWIN32_POWEREVENT_PARAMETERS Parms)
NTSTATUS xxxUserPowerStateCalloutWorker (VOID)
NTSTATUS UserPowerStateCallout (PKWIN32_POWERSTATE_PARAMETERS Parms)
VOID xxxUserPowerCalloutWorker (VOID)
VOID VideoPortCalloutThread (PVIDEO_WIN32K_CALLBACKS_PARAMS Params)
VOID VideoPortCallout (IN PVOID Params)

Variables

BOOL gbUserInitialized
BOOL fGdiEnabled
LIST_ENTRY gPowerRequestList
PFAST_MUTEX gpPowerRequestMutex
PKEVENT gpEventPowerRequest
BOOL gbHibernate = FALSE
PPOWERREQUEST gpPowerRequestCurrent


Typedef Documentation

typedef struct tagPOWERREQUEST POWERREQUEST
 

typedef struct tagPOWERREQUEST * PPOWERREQUEST
 

Referenced by CleanupPowerRequestList(), QueuePowerRequest(), UnqueuePowerRequest(), and xxxUserPowerCalloutWorker().


Function Documentation

VOID CancelPowerRequest PPOWERREQUEST  pPowerRequest  ) 
 

Definition at line 58 of file power.c.

References tagPOWERREQUEST::Event, EVENT_INCREMENT, FALSE, gpPowerRequestCurrent, KeSetEvent(), and tagPOWERREQUEST::Status.

Referenced by CleanupPowerRequestList(), and xxxUserPowerCalloutWorker().

00060 { 00061 UserAssert(pPowerRequest != gpPowerRequestCurrent); 00062 pPowerRequest->Status = STATUS_UNSUCCESSFUL; 00063 KeSetEvent(&pPowerRequest->Event, EVENT_INCREMENT, FALSE); 00064 }

VOID CleanupPowerRequestList VOID   ) 
 

Definition at line 216 of file power.c.

References CancelPowerRequest(), gbNoMorePowerCallouts, gpPowerRequestMutex, NULL, PPOWERREQUEST, TRUE, and UnqueuePowerRequest().

Referenced by CleanupResources(), and InitiateWin32kCleanup().

00217 { 00218 PPOWERREQUEST pPowerRequest; 00219 00220 /* 00221 * Make sure no new power requests come in. 00222 */ 00223 gbNoMorePowerCallouts = TRUE; 00224 00225 /* 00226 * If we never allocated anything, there's nothing to clean up. 00227 */ 00228 if (gpPowerRequestMutex == NULL) { 00229 return; 00230 } 00231 00232 /* 00233 * Mark any pending power requests as cacelled. 00234 */ 00235 while ((pPowerRequest = UnqueuePowerRequest()) != NULL) { 00236 CancelPowerRequest(pPowerRequest); 00237 } 00238 }

VOID DeletePowerRequestList VOID   ) 
 

Definition at line 250 of file power.c.

References gPowerRequestList, gpPowerRequestMutex, and NULL.

Referenced by Win32kNtUserCleanup().

00251 { 00252 if (gpPowerRequestMutex) { 00253 00254 /* 00255 * Make sure there are no pending power requests. 00256 */ 00257 UserAssert(IsListEmpty(&gPowerRequestList)); 00258 00259 /* 00260 * Free the power request structures. 00261 */ 00262 UserFreePool(gpPowerRequestMutex); 00263 gpPowerRequestMutex = NULL; 00264 } 00265 }

__inline VOID EnterPowerCrit  ) 
 

Definition at line 38 of file power.c.

References ExAcquireFastMutexUnsafe(), gpPowerRequestMutex, KeEnterCriticalRegion, and VOID().

Referenced by QueuePowerRequest(), UnqueuePowerRequest(), UserPowerStateCallout(), and xxxUserPowerStateCalloutWorker().

00038 { 00039 KeEnterCriticalRegion(); 00040 ExAcquireFastMutexUnsafe(gpPowerRequestMutex); 00041 }

NTSTATUS InitializePowerRequestList HANDLE  hPowerRequestEvent  ) 
 

Definition at line 180 of file power.c.

References ExEventObjectType, ExInitializeFastMutex, gpEventPowerRequest, gPowerRequestList, gpPowerRequestMutex, KernelMode, NT_SUCCESS, NTSTATUS(), NULL, ObReferenceObjectByHandle(), and Status.

Referenced by NtUserInitialize().

00182 { 00183 NTSTATUS Status; 00184 00185 InitializeListHead(&gPowerRequestList); 00186 00187 Status = ObReferenceObjectByHandle(hPowerRequestEvent, 00188 EVENT_ALL_ACCESS, 00189 *ExEventObjectType, 00190 KernelMode, 00191 &gpEventPowerRequest, 00192 NULL); 00193 if (!NT_SUCCESS(Status)) { 00194 return Status; 00195 } 00196 00197 gpPowerRequestMutex = UserAllocPoolNonPaged(sizeof(FAST_MUTEX), TAG_POWER); 00198 if (gpPowerRequestMutex == NULL) { 00199 return STATUS_NO_MEMORY; 00200 } 00201 ExInitializeFastMutex(gpPowerRequestMutex); 00202 00203 return STATUS_SUCCESS; 00204 }

__inline VOID LeavePowerCrit  ) 
 

Definition at line 43 of file power.c.

References ExReleaseFastMutexUnsafe(), gpPowerRequestMutex, KeLeaveCriticalRegion, and VOID().

Referenced by QueuePowerRequest(), UnqueuePowerRequest(), UserPowerStateCallout(), and xxxUserPowerStateCalloutWorker().

00043 { 00044 ExReleaseFastMutexUnsafe(gpPowerRequestMutex); 00045 KeLeaveCriticalRegion(); 00046 }

NTSTATUS QueuePowerRequest PKWIN32_POWEREVENT_PARAMETERS  Parms  ) 
 

Definition at line 76 of file power.c.

References EnterCrit, EnterPowerCrit(), tagPOWERREQUEST::Event, EVENT_INCREMENT, FALSE, gbNoMorePowerCallouts, gpEventPowerRequest, gPowerRequestList, gpPowerRequestCurrent, gpPowerRequestMutex, IS_SYSTEM_THREAD, KeInitializeEvent, KernelMode, KeSetEvent(), KeWaitForSingleObject(), LeaveCrit, LeavePowerCrit(), NT_SUCCESS, NTSTATUS(), NULL, tagPOWERREQUEST::Parms, PKWIN32_POWEREVENT_PARAMETERS, tagPOWERREQUEST::PowerRequestLink, PPOWERREQUEST, PsGetCurrentThread, PtiCurrent, tagPOWERREQUEST::Status, Status, ThreadLockPool, ThreadUnlockPool, WrUserRequest, and xxxUserPowerCalloutWorker().

Referenced by UserPowerEventCallout(), and UserPowerStateCallout().

00078 { 00079 NTSTATUS Status = STATUS_SUCCESS; 00080 PPOWERREQUEST pPowerRequest; 00081 TL tlPool; 00082 00083 UserAssert(gpEventPowerRequest != NULL); 00084 UserAssert(gpPowerRequestMutex != NULL); 00085 00086 /* 00087 * Allocate and initialize the power request. 00088 */ 00089 pPowerRequest = UserAllocPoolNonPaged(sizeof(POWERREQUEST), TAG_POWER); 00090 if (pPowerRequest == NULL) { 00091 return STATUS_NO_MEMORY; 00092 } 00093 KeInitializeEvent(&pPowerRequest->Event, SynchronizationEvent, FALSE); 00094 pPowerRequest->Parms = Parms; 00095 00096 /* 00097 * Insert the power request into the list. 00098 */ 00099 EnterPowerCrit(); 00100 if (gbNoMorePowerCallouts) { 00101 Status = STATUS_UNSUCCESSFUL; 00102 } else { 00103 InsertHeadList(&gPowerRequestList, &pPowerRequest->PowerRequestLink); 00104 } 00105 LeavePowerCrit(); 00106 00107 /* 00108 * If this is a system thread or a non-GUI thread, tell CSRSS to do the 00109 * work and wait for it to finish. Otherwise, we'll do the work ourselves. 00110 */ 00111 if (NT_SUCCESS(Status)) { 00112 if (IS_SYSTEM_THREAD(PsGetCurrentThread()) || 00113 W32GetCurrentThread() == NULL) { 00114 KeSetEvent(gpEventPowerRequest, EVENT_INCREMENT, FALSE); 00115 } else { 00116 EnterCrit(); 00117 ThreadLockPool(PtiCurrent(), pPowerRequest, &tlPool); 00118 xxxUserPowerCalloutWorker(); 00119 ThreadUnlockPool(PtiCurrent(), &tlPool); 00120 LeaveCrit(); 00121 } 00122 Status = KeWaitForSingleObject(&pPowerRequest->Event, 00123 WrUserRequest, 00124 KernelMode, 00125 FALSE, 00126 NULL); 00127 00128 if (NT_SUCCESS(Status)) { 00129 Status = pPowerRequest->Status; 00130 } 00131 } 00132 00133 /* 00134 * Free the power request. 00135 */ 00136 UserAssert(pPowerRequest != gpPowerRequestCurrent); 00137 UserFreePool(pPowerRequest); 00138 00139 return Status; 00140 }

PPOWERREQUEST UnqueuePowerRequest VOID   ) 
 

Definition at line 152 of file power.c.

References EnterPowerCrit(), gPowerRequestList, LeavePowerCrit(), NULL, and PPOWERREQUEST.

Referenced by CleanupPowerRequestList(), and xxxUserPowerCalloutWorker().

00153 { 00154 PLIST_ENTRY pEntry; 00155 PPOWERREQUEST pPowerRequest = NULL; 00156 00157 /* 00158 * Remove a power request from the list. 00159 */ 00160 EnterPowerCrit(); 00161 if (!IsListEmpty(&gPowerRequestList)) { 00162 pEntry = RemoveTailList(&gPowerRequestList); 00163 pPowerRequest = CONTAINING_RECORD(pEntry, POWERREQUEST, PowerRequestLink); 00164 } 00165 LeavePowerCrit(); 00166 00167 return pPowerRequest; 00168 }

NTSTATUS UserPowerEventCallout PKWIN32_POWEREVENT_PARAMETERS  Parms  ) 
 

Definition at line 455 of file power.c.

References gbNoMorePowerCallouts, gbVideoInitialized, gpepCSRSS, NTSTATUS(), NULL, and QueuePowerRequest().

00457 { 00458 00459 /* 00460 * Make sure CSRSS is running. 00461 */ 00462 if (!gbVideoInitialized || gbNoMorePowerCallouts) { 00463 return STATUS_UNSUCCESSFUL; 00464 } 00465 00466 UserAssert(gpepCSRSS != NULL); 00467 00468 /* 00469 * Process the power request. 00470 */ 00471 return QueuePowerRequest(Parms); 00472 }

NTSTATUS UserPowerStateCallout PKWIN32_POWERSTATE_PARAMETERS  Parms  ) 
 

Definition at line 608 of file power.c.

References tagPOWERSTATE::bsmParams, BROADCASTSYSTEMMSGPARAMS::dwFlags, EnterPowerCrit(), EVENT_INCREMENT, FALSE, tagPOWERSTATE::fCritical, tagPOWERSTATE::fInProgress, _WIN32_POWERSTATE_PARAMETERS::Flags, tagPOWERSTATE::fOverrideApps, tagPOWERSTATE::fQueryAllowed, tagPOWERSTATE::fUIAllowed, gbNoMorePowerCallouts, gbVideoInitialized, gpepCSRSS, gPowerState, gspwndLogonNotify, KeSetEvent(), LeavePowerCrit(), _WIN32_POWERSTATE_PARAMETERS::MinSystemState, NTSTATUS(), NULL, tagPOWERSTATE::pEvent, PKWIN32_POWERSTATE_PARAMETERS, _WIN32_POWERSTATE_PARAMETERS::Promotion, tagPOWERSTATE::psParams, QueuePowerRequest(), _WIN32_POWERSTATE_PARAMETERS::SystemAction, and TRUE.

00610 { 00611 BOOLEAN Promotion = Parms->Promotion; 00612 POWER_ACTION SystemAction = Parms->SystemAction; 00613 SYSTEM_POWER_STATE MinSystemState = Parms->MinSystemState; 00614 ULONG Flags = Parms->Flags; 00615 00616 /* 00617 * Make sure CSRSS is running. 00618 */ 00619 if (!gbVideoInitialized || gbNoMorePowerCallouts || !gspwndLogonNotify) { 00620 return STATUS_UNSUCCESSFUL; 00621 } 00622 00623 UserAssert(gpepCSRSS != NULL); 00624 00625 EnterPowerCrit(); 00626 00627 /* 00628 * Make sure we're not trying to promote a non-existent request 00629 * or start a new one when we're already doing it. 00630 */ 00631 if ((Promotion && !gPowerState.fInProgress) || 00632 (!Promotion && gPowerState.fInProgress)) { 00633 LeavePowerCrit(); 00634 return STATUS_INVALID_PARAMETER; 00635 } 00636 00637 /* 00638 * Save our state. 00639 */ 00640 gPowerState.fInProgress = TRUE; 00641 gPowerState.fOverrideApps = (Flags & POWER_ACTION_OVERRIDE_APPS) != 0; 00642 gPowerState.fCritical = (Flags & POWER_ACTION_CRITICAL) != 0; 00643 gPowerState.fQueryAllowed = (Flags & POWER_ACTION_QUERY_ALLOWED) != 0; 00644 gPowerState.fUIAllowed = (Flags & POWER_ACTION_UI_ALLOWED) != 0; 00645 gPowerState.psParams.SystemAction = SystemAction; 00646 gPowerState.psParams.MinSystemState = MinSystemState; 00647 gPowerState.psParams.Flags = Flags; 00648 if (gPowerState.fOverrideApps) { 00649 gPowerState.bsmParams.dwFlags = BSF_NOHANG | BSF_FORCEIFHUNG; 00650 } 00651 if (gPowerState.fCritical) { 00652 gPowerState.bsmParams.dwFlags = BSF_NOHANG | BSF_QUERY; 00653 } 00654 if (gPowerState.pEvent) { 00655 KeSetEvent(gPowerState.pEvent, EVENT_INCREMENT, FALSE); 00656 } 00657 00658 LeavePowerCrit(); 00659 00660 /* 00661 * If this is a promotion, we're done. 00662 */ 00663 if (Promotion) { 00664 return STATUS_SUCCESS; 00665 } 00666 00667 /* 00668 * Process the power request. 00669 */ 00670 return QueuePowerRequest(NULL); 00671 }

VOID VideoPortCallout IN PVOID  Params  ) 
 

Definition at line 845 of file power.c.

References CreateSystemThread(), FALSE, NT_SUCCESS, NTSTATUS(), NtWaitForSingleObject(), NULL, Status, and VideoPortCalloutThread().

00848 { 00849 00850 /* 00851 * To make sure this is a system thread, we create a new thread. 00852 */ 00853 00854 HANDLE hThread; 00855 NTSTATUS Status; 00856 00857 // DbgPrint("Callout --- Enter !!!\n"); 00858 00859 Status = CreateSystemThread(VideoPortCalloutThread, Params, &hThread); 00860 if (NT_SUCCESS(Status)) { 00861 Status = NtWaitForSingleObject(hThread, FALSE, NULL); 00862 if (NT_SUCCESS(Status)) { 00863 Status = ((PVIDEO_WIN32K_CALLBACKS_PARAMS)(Params))->Status; 00864 } 00865 ZwClose(hThread); 00866 } 00867 00868 // DbgPrint("Callout --- Leave !!!\n"); 00869 00870 ((PVIDEO_WIN32K_CALLBACKS_PARAMS)(Params))->Status = Status; 00871 }

VOID VideoPortCalloutThread PVIDEO_WIN32K_CALLBACKS_PARAMS  Params  ) 
 

Definition at line 727 of file power.c.

References BusRelations, EnterCrit, FALSE, gbHibernate, gpDispInfo, grpdeskRitInput, InitSystemThread(), IoInvalidateDeviceRelations(), ISCSRSS, KernelMode, LeaveCrit, NT_SUCCESS, NULL, tagDISPLAYINFO::pmdev, TRUE, xxxRestoreCsrssThreadDesktop(), xxxSetCsrssThreadDesktop(), xxxUserChangeDisplaySettings(), and xxxUserResetDisplayDevice().

Referenced by VideoPortCallout().

00730 { 00731 00732 /* 00733 * Convert this thread to GUI if it's not already converted 00734 */ 00735 UserAssert(W32GetCurrentThread() == NULL); 00736 00737 Params->Status = InitSystemThread(NULL); 00738 00739 if (!NT_SUCCESS(Params->Status)) { 00740 return; 00741 } 00742 00743 // DbgPrint("video --- Before CritSect\n"); 00744 EnterCrit(); 00745 // DbgPrint("video --- After CritSect\n"); 00746 00747 00748 switch (Params->CalloutType) { 00749 00750 case VideoWakeupCallout: 00751 gbHibernate = TRUE; 00752 break; 00753 00754 case VideoDisplaySwitchCallout: 00755 { 00756 UNICODE_STRING strDeviceName; 00757 DEVMODEW NewMode; 00758 ULONG bPrune; 00759 00760 if (Params->PhysDisp != NULL) 00761 { 00762 if (DrvDisplaySwitchHandler(Params->PhysDisp, &strDeviceName, &NewMode, &bPrune)) 00763 { 00764 DESKRESTOREDATA drdRestore; 00765 00766 drdRestore.pdeskRestore = NULL; 00767 00768 /* 00769 * CSRSS is not the only process to diliver power callout 00770 */ 00771 00772 if (!ISCSRSS() || 00773 NT_SUCCESS (xxxSetCsrssThreadDesktop(grpdeskRitInput, &drdRestore)) ) 00774 { 00775 if (!DrvQueryMDEVPowerState(gpDispInfo->pmdev)) { 00776 00777 DrvEnableMDEV(gpDispInfo->pmdev, TRUE); 00778 DrvSetMDEVPowerState(gpDispInfo->pmdev, TRUE); 00779 } 00780 00781 xxxUserChangeDisplaySettings(NULL, NULL, NULL, grpdeskRitInput, 00782 ((bPrune) ? 0 : CDS_RAWMODE) | CDS_TRYCLOSEST | CDS_RESET, 0, KernelMode); 00783 00784 if (ISCSRSS()) 00785 { 00786 xxxRestoreCsrssThreadDesktop(&drdRestore); 00787 } 00788 } 00789 } 00790 } 00791 } 00792 00793 // 00794 // If there is a requirement to reenumerate sub-devices 00795 // 00796 if (Params->Param) 00797 { 00798 IoInvalidateDeviceRelations((PDEVICE_OBJECT)Params->Param, BusRelations); 00799 } 00800 00801 Params->Status = STATUS_SUCCESS; 00802 break; 00803 00804 case VideoFindAdapterCallout: 00805 00806 if (Params->Param) { 00807 00808 DrvEnableMDEV(gpDispInfo->pmdev, TRUE); 00809 xxxUserResetDisplayDevice(); 00810 00811 } else { 00812 00813 DrvDisableMDEV(gpDispInfo->pmdev, TRUE); 00814 } 00815 00816 Params->Status = STATUS_SUCCESS; 00817 break; 00818 00819 default: 00820 00821 UserAssert(FALSE); 00822 00823 Params->Status = STATUS_UNSUCCESSFUL; 00824 00825 } 00826 00827 00828 // DbgPrint("video --- Before Leave CritSect\n"); 00829 LeaveCrit(); 00830 // DbgPrint("video --- After Leave CritSect\n"); 00831 00832 00833 return; 00834 }

VOID xxxUserPowerCalloutWorker VOID   ) 
 

Definition at line 684 of file power.c.

References CancelPowerRequest(), EVENT_INCREMENT, FALSE, gpPowerRequestCurrent, KeSetEvent(), NULL, PPOWERREQUEST, PtiCurrent, tagPOWERREQUEST::Status, ThreadLockPoolCleanup, ThreadUnlockPoolCleanup, UnqueuePowerRequest(), xxxUserPowerEventCalloutWorker(), and xxxUserPowerStateCalloutWorker().

Referenced by QueuePowerRequest().

00685 { 00686 PPOWERREQUEST pPowerRequest; 00687 TL tlPool; 00688 00689 while ((pPowerRequest = UnqueuePowerRequest()) != NULL) { 00690 /* 00691 * Make sure the event gets signalled even if the thread dies in a 00692 * callback or the waiting thread might get stuck. 00693 */ 00694 ThreadLockPoolCleanup(PtiCurrent(), pPowerRequest, &tlPool, CancelPowerRequest); 00695 00696 /* 00697 * Call the appropriate power worker function. 00698 */ 00699 gpPowerRequestCurrent = pPowerRequest; 00700 if (pPowerRequest->Parms) { 00701 pPowerRequest->Status = xxxUserPowerEventCalloutWorker(pPowerRequest->Parms); 00702 } else { 00703 pPowerRequest->Status = xxxUserPowerStateCalloutWorker(); 00704 } 00705 gpPowerRequestCurrent = NULL; 00706 00707 /* 00708 * Tell the waiting thread to proceed. 00709 */ 00710 ThreadUnlockPoolCleanup(PtiCurrent(), &tlPool); 00711 KeSetEvent(&pPowerRequest->Event, EVENT_INCREMENT, FALSE); 00712 } 00713 }

NTSTATUS xxxUserPowerEventCalloutWorker PKWIN32_POWEREVENT_PARAMETERS  Parms  ) 
 

Definition at line 274 of file power.c.

References _PostMessage(), BOOL, BusRelations, _WIN32_POWEREVENT_PARAMETERS::Code, BROADCASTSYSTEMMSGPARAMS::dwFlags, BROADCASTSYSTEMMSGPARAMS::dwRecipients, _WIN32_POWEREVENT_PARAMETERS::EventNumber, FALSE, gbHibernate, gbNoMorePowerCallouts, gpDispInfo, grpdeskRitInput, gspwndLogonNotify, IoInvalidateDeviceRelations(), ISCSRSS, KernelMode, NT_SUCCESS, NTSTATUS(), NULL, tagDISPLAYINFO::pmdev, PSPOWEREVENTTYPE, PsW32DisplayState, PsW32EventCode, PsW32FullWake, PsW32GdiOff, PsW32GdiOn, PsW32PowerPolicyChanged, PsW32SystemPowerState, PsW32SystemTime, Status, TRUE, xxxRestoreCsrssThreadDesktop(), xxxSendMessageBSM(), xxxSetCsrssThreadDesktop(), xxxSystemParametersInfo(), xxxUserChangeDisplaySettings(), and xxxUserResetDisplayDevice().

Referenced by xxxUserPowerCalloutWorker().

00276 { 00277 BROADCASTSYSTEMMSGPARAMS bsmParams; 00278 NTSTATUS Status = STATUS_SUCCESS; 00279 PSPOWEREVENTTYPE EventNumber = Parms->EventNumber; 00280 ULONG_PTR Code = Parms->Code; 00281 BOOL bCurrentPowerOn; 00282 00283 /* 00284 * Make sure CSRSS is still running. 00285 */ 00286 if (gbNoMorePowerCallouts) { 00287 return STATUS_UNSUCCESSFUL; 00288 } 00289 00290 switch (EventNumber) { 00291 case PsW32FullWake: 00292 /* 00293 * Let all the applications know that they can resume operation. 00294 */ 00295 bsmParams.dwRecipients = BSM_ALLDESKTOPS; 00296 bsmParams.dwFlags = BSF_QUEUENOTIFYMESSAGE; 00297 xxxSendMessageBSM(NULL, 00298 WM_POWERBROADCAST, 00299 PBT_APMRESUMESUSPEND, 00300 0, 00301 &bsmParams); 00302 break; 00303 00304 case PsW32EventCode: 00305 /* 00306 * Post a message to winlogon, and let them put up a message box 00307 * or play a sound. 00308 */ 00309 00310 if (gspwndLogonNotify) { 00311 _PostMessage(gspwndLogonNotify, WM_LOGONNOTIFY, LOGON_PLAYPOWERSOUND, (ULONG)Code); 00312 Status = STATUS_SUCCESS; 00313 } else { 00314 Status = STATUS_UNSUCCESSFUL; 00315 } 00316 00317 break; 00318 00319 case PsW32PowerPolicyChanged: 00320 /* 00321 * Set video timeout value. 00322 */ 00323 xxxSystemParametersInfo(SPI_SETLOWPOWERTIMEOUT, (ULONG)Code, 0, 0); 00324 xxxSystemParametersInfo(SPI_SETPOWEROFFTIMEOUT, (ULONG)Code, 0, 0); 00325 break; 00326 00327 case PsW32SystemPowerState: 00328 /* 00329 * Let all the applications know that the power status has changed. 00330 */ 00331 bsmParams.dwRecipients = BSM_ALLDESKTOPS; 00332 bsmParams.dwFlags = BSF_POSTMESSAGE; 00333 xxxSendMessageBSM(NULL, 00334 WM_POWERBROADCAST, 00335 PBT_APMPOWERSTATUSCHANGE, 00336 0, 00337 &bsmParams); 00338 break; 00339 00340 case PsW32SystemTime: 00341 /* 00342 * Let all the applications know that the system time has changed. 00343 */ 00344 bsmParams.dwRecipients = BSM_ALLDESKTOPS; 00345 bsmParams.dwFlags = BSF_POSTMESSAGE; 00346 xxxSendMessageBSM(NULL, 00347 WM_TIMECHANGE, 00348 0, 00349 0, 00350 &bsmParams); 00351 break; 00352 00353 case PsW32DisplayState: 00354 /* 00355 * Set video timeout active status. 00356 */ 00357 xxxSystemParametersInfo(SPI_SETLOWPOWERACTIVE, !Code, 0, 0); 00358 xxxSystemParametersInfo(SPI_SETPOWEROFFACTIVE, !Code, 0, 0); 00359 break; 00360 00361 case PsW32GdiOff: 00362 /* 00363 * At this point we will disable the display device 00364 */ 00365 00366 DrvSetMonitorPowerState(gpDispInfo->pmdev, PowerDeviceD3); 00367 00368 bCurrentPowerOn = DrvQueryMDEVPowerState(gpDispInfo->pmdev); 00369 if (bCurrentPowerOn) { 00370 DrvDisableMDEV(gpDispInfo->pmdev, TRUE); 00371 } 00372 DrvSetMDEVPowerState(gpDispInfo->pmdev, FALSE); 00373 00374 break; 00375 00376 case PsW32GdiOn: 00377 /* 00378 * Call video driver to turn the display back on. 00379 */ 00380 bCurrentPowerOn = DrvQueryMDEVPowerState(gpDispInfo->pmdev); 00381 if (!bCurrentPowerOn) { 00382 DrvEnableMDEV(gpDispInfo->pmdev, TRUE); 00383 } 00384 DrvSetMDEVPowerState(gpDispInfo->pmdev, TRUE); 00385 DrvSetMonitorPowerState(gpDispInfo->pmdev, PowerDeviceD0); 00386 00387 /* 00388 * Repaint the whole screen 00389 */ 00390 xxxUserResetDisplayDevice(); 00391 00392 if (gbHibernate) 00393 { 00394 HANDLE pdo; 00395 00396 PVOID PhysDisp = DrvWakeupHandler(&pdo); 00397 00398 if (PhysDisp) 00399 { 00400 UNICODE_STRING strDeviceName; 00401 DEVMODEW NewMode; 00402 ULONG bPrune; 00403 00404 if (DrvDisplaySwitchHandler(PhysDisp, &strDeviceName, &NewMode, &bPrune)) 00405 { 00406 /* 00407 * CSRSS is not the only process to diliver power callout 00408 */ 00409 if (!ISCSRSS()) { 00410 xxxUserChangeDisplaySettings(NULL, NULL, NULL, grpdeskRitInput, 00411 ((bPrune) ? 0 : CDS_RAWMODE) | CDS_TRYCLOSEST | CDS_RESET, 0, KernelMode); 00412 } 00413 else 00414 { 00415 DESKRESTOREDATA drdRestore; 00416 00417 drdRestore.pdeskRestore = NULL; 00418 if (NT_SUCCESS (xxxSetCsrssThreadDesktop(grpdeskRitInput, &drdRestore)) ) 00419 { 00420 xxxUserChangeDisplaySettings(NULL, NULL, NULL, NULL, 00421 ((bPrune) ? 0 : CDS_RAWMODE) | CDS_TRYCLOSEST | CDS_RESET, 0, KernelMode); 00422 xxxRestoreCsrssThreadDesktop(&drdRestore); 00423 } 00424 } 00425 } 00426 00427 // 00428 // If there is a requirement to reenumerate sub-devices 00429 // 00430 if (pdo) 00431 { 00432 IoInvalidateDeviceRelations((PDEVICE_OBJECT)pdo, BusRelations); 00433 } 00434 } 00435 } 00436 gbHibernate = FALSE; 00437 00438 break; 00439 00440 default: 00441 Status = STATUS_NOT_IMPLEMENTED; 00442 break; 00443 } 00444 00445 return Status; 00446 }

NTSTATUS xxxUserPowerStateCalloutWorker VOID   ) 
 

Definition at line 481 of file power.c.

References BOOL, tagPOWERSTATE::bsmParams, BROADCASTSYSTEMMSGPARAMS::dwFlags, BROADCASTSYSTEMMSGPARAMS::dwRecipients, EnterPowerCrit(), FALSE, tagPOWERSTATE::fCritical, fGdiEnabled, tagPOWERSTATE::fInProgress, tagPOWERSTATE::fOverrideApps, tagPOWERSTATE::fQueryAllowed, tagPOWERSTATE::fUIAllowed, gbNoMorePowerCallouts, glinp, gPowerState, gspwndLogonNotify, LeavePowerCrit(), NtGetTickCount(), NTSTATUS(), NULL, tagPOWERSTATE::pEvent, tagPOWERSTATE::psParams, PtiCurrent, Status, ThreadLockAlways, ThreadUnlock, tagLASTINPUT::timeLastInputMessage, xxxSendMessage(), and xxxSendMessageBSM().

Referenced by xxxUserPowerCalloutWorker().

00482 { 00483 BOOL fContinue; 00484 BROADCASTSYSTEMMSGPARAMS bsmParams; 00485 NTSTATUS Status = STATUS_SUCCESS; 00486 TL tlpwnd; 00487 00488 /* 00489 * Make sure CSRSS is still running. 00490 */ 00491 if (gbNoMorePowerCallouts) { 00492 return STATUS_UNSUCCESSFUL; 00493 } 00494 00495 /* 00496 * Store the event so this thread can be promoted later. 00497 */ 00498 EnterPowerCrit(); 00499 gPowerState.pEvent = PtiCurrent()->pEventQueueServer; 00500 LeavePowerCrit(); 00501 00502 if (!gPowerState.fCritical) { 00503 /* 00504 * Ask the applications if we can suspend operation. 00505 */ 00506 if (gPowerState.fQueryAllowed) { 00507 gPowerState.bsmParams.dwRecipients = BSM_ALLDESKTOPS; 00508 gPowerState.bsmParams.dwFlags = BSF_NOHANG | BSF_FORCEIFHUNG; 00509 if (gPowerState.fUIAllowed) { 00510 gPowerState.bsmParams.dwFlags |= BSF_ALLOWSFW; 00511 } 00512 if (gPowerState.fOverrideApps == FALSE) { 00513 gPowerState.bsmParams.dwFlags |= (BSF_QUERY | BSF_NOTIMEOUTIFNOTHUNG); 00514 } 00515 fContinue = xxxSendMessageBSM(NULL, 00516 WM_POWERBROADCAST, 00517 PBT_APMQUERYSUSPEND, 00518 gPowerState.fUIAllowed, 00519 &gPowerState.bsmParams); 00520 00521 /* 00522 * If an app says to abort and we're not in override apps or 00523 * critical mode, send out the suspend failed message and bail. 00524 */ 00525 if (!(fContinue || gPowerState.fOverrideApps || gPowerState.fCritical)) { 00526 gPowerState.bsmParams.dwRecipients = BSM_ALLDESKTOPS; 00527 gPowerState.bsmParams.dwFlags = BSF_QUEUENOTIFYMESSAGE; 00528 xxxSendMessageBSM(NULL, 00529 WM_POWERBROADCAST, 00530 PBT_APMQUERYSUSPENDFAILED, 00531 0, 00532 &gPowerState.bsmParams); 00533 EnterPowerCrit(); 00534 gPowerState.pEvent = NULL; 00535 gPowerState.fInProgress = FALSE; 00536 LeavePowerCrit(); 00537 return STATUS_CANCELLED; 00538 } 00539 } 00540 00541 /* 00542 * Let all the applications know they should suspend operation. 00543 */ 00544 if (!gPowerState.fCritical) { 00545 gPowerState.bsmParams.dwRecipients = BSM_ALLDESKTOPS; 00546 gPowerState.bsmParams.dwFlags = BSF_NOHANG | BSF_FORCEIFHUNG; 00547 xxxSendMessageBSM(NULL, 00548 WM_POWERBROADCAST, 00549 PBT_APMSUSPEND, 00550 0, 00551 &gPowerState.bsmParams); 00552 } 00553 } 00554 00555 /* 00556 * Clear the event so the thread won't wake up prematurely. 00557 */ 00558 EnterPowerCrit(); 00559 gPowerState.pEvent = NULL; 00560 LeavePowerCrit(); 00561 00562 /* 00563 * Look for a Winlogon window to notify. 00564 */ 00565 if (gspwndLogonNotify != NULL) { 00566 gPowerState.psParams.FullScreenMode = !fGdiEnabled; 00567 ThreadLockAlways(gspwndLogonNotify, &tlpwnd); 00568 Status = (NTSTATUS)xxxSendMessage(gspwndLogonNotify, 00569 WM_LOGONNOTIFY, 00570 LOGON_POWERSTATE, 00571 (LPARAM)&gPowerState.psParams); 00572 ThreadUnlock(&tlpwnd); 00573 } 00574 00575 /* 00576 * The power state broadcast is over. 00577 */ 00578 EnterPowerCrit(); 00579 gPowerState.fInProgress = FALSE; 00580 LeavePowerCrit(); 00581 00582 /* 00583 * Tickle the input time so we don't fire up a screen saver right away. 00584 */ 00585 glinp.timeLastInputMessage = NtGetTickCount(); 00586 00587 /* 00588 * Let all the applications know that we're waking up. 00589 */ 00590 bsmParams.dwRecipients = BSM_ALLDESKTOPS; 00591 bsmParams.dwFlags = BSF_QUEUENOTIFYMESSAGE; 00592 xxxSendMessageBSM(NULL, 00593 WM_POWERBROADCAST, 00594 PBT_APMRESUMEAUTOMATIC, 00595 0, 00596 &bsmParams); 00597 00598 return Status; 00599 }


Variable Documentation

BOOL fGdiEnabled
 

Definition at line 22 of file power.c.

BOOL gbHibernate = FALSE
 

Definition at line 27 of file power.c.

Referenced by VideoPortCalloutThread(), and xxxUserPowerEventCalloutWorker().

BOOL gbUserInitialized
 

Definition at line 21 of file power.c.

Referenced by UserInitialize(), and UserThreadCallout().

PKEVENT gpEventPowerRequest
 

Definition at line 26 of file power.c.

Referenced by InitializePowerRequestList(), and QueuePowerRequest().

LIST_ENTRY gPowerRequestList
 

Definition at line 24 of file power.c.

Referenced by DeletePowerRequestList(), InitializePowerRequestList(), QueuePowerRequest(), and UnqueuePowerRequest().

PPOWERREQUEST gpPowerRequestCurrent
 

Definition at line 36 of file power.c.

Referenced by CancelPowerRequest(), QueuePowerRequest(), and xxxUserPowerCalloutWorker().

PFAST_MUTEX gpPowerRequestMutex
 

Definition at line 25 of file power.c.

Referenced by CleanupPowerRequestList(), DeletePowerRequestList(), EnterPowerCrit(), InitializePowerRequestList(), LeavePowerCrit(), and QueuePowerRequest().


Generated on Sat May 15 19:45:17 2004 for test by doxygen 1.3.7