00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
#include "precomp.h"
00013
#pragma hdrstop
00014
00015
#include <ntcsrmsg.h>
00016
#include "csrmsg.h"
00017
#include "ntddvdeo.h"
00018
00019
#pragma alloc_text(INIT, InitializePowerRequestList)
00020
00021 extern BOOL gbUserInitialized;
00022 extern BOOL fGdiEnabled;
00023
00024 LIST_ENTRY
gPowerRequestList;
00025 PFAST_MUTEX gpPowerRequestMutex;
00026 PKEVENT gpEventPowerRequest;
00027 BOOL gbHibernate =
FALSE;
00028
00029 typedef struct tagPOWERREQUEST {
00030 LIST_ENTRY
PowerRequestLink;
00031 KEVENT Event;
00032 NTSTATUS Status;
00033 PKWIN32_POWEREVENT_PARAMETERS Parms;
00034 }
POWERREQUEST, *
PPOWERREQUEST;
00035
00036 PPOWERREQUEST gpPowerRequestCurrent;
00037
00038 __inline
VOID EnterPowerCrit() {
00039
KeEnterCriticalRegion();
00040
ExAcquireFastMutexUnsafe(
gpPowerRequestMutex);
00041 }
00042
00043 __inline
VOID LeavePowerCrit() {
00044
ExReleaseFastMutexUnsafe(
gpPowerRequestMutex);
00045
KeLeaveCriticalRegion();
00046 }
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
VOID
00058 CancelPowerRequest(
00059 PPOWERREQUEST pPowerRequest)
00060 {
00061 UserAssert(pPowerRequest !=
gpPowerRequestCurrent);
00062 pPowerRequest->
Status = STATUS_UNSUCCESSFUL;
00063
KeSetEvent(&pPowerRequest->
Event,
EVENT_INCREMENT,
FALSE);
00064 }
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
NTSTATUS
00076 QueuePowerRequest(
00077
PKWIN32_POWEREVENT_PARAMETERS Parms)
00078 {
00079
NTSTATUS Status = STATUS_SUCCESS;
00080
PPOWERREQUEST pPowerRequest;
00081
TL tlPool;
00082
00083 UserAssert(
gpEventPowerRequest !=
NULL);
00084 UserAssert(
gpPowerRequestMutex !=
NULL);
00085
00086
00087
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
00098
00099
EnterPowerCrit();
00100
if (
gbNoMorePowerCallouts) {
00101
Status = STATUS_UNSUCCESSFUL;
00102 }
else {
00103 InsertHeadList(&
gPowerRequestList, &pPowerRequest->
PowerRequestLink);
00104 }
00105
LeavePowerCrit();
00106
00107
00108
00109
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
00135
00136 UserAssert(pPowerRequest !=
gpPowerRequestCurrent);
00137 UserFreePool(pPowerRequest);
00138
00139
return Status;
00140 }
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
PPOWERREQUEST
00152 UnqueuePowerRequest(VOID)
00153 {
00154 PLIST_ENTRY pEntry;
00155
PPOWERREQUEST pPowerRequest =
NULL;
00156
00157
00158
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 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
NTSTATUS
00180 InitializePowerRequestList(
00181 HANDLE hPowerRequestEvent)
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 }
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
VOID
00216 CleanupPowerRequestList(VOID)
00217 {
00218
PPOWERREQUEST pPowerRequest;
00219
00220
00221
00222
00223
gbNoMorePowerCallouts =
TRUE;
00224
00225
00226
00227
00228
if (
gpPowerRequestMutex ==
NULL) {
00229
return;
00230 }
00231
00232
00233
00234
00235
while ((pPowerRequest =
UnqueuePowerRequest()) !=
NULL) {
00236
CancelPowerRequest(pPowerRequest);
00237 }
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
VOID
00250 DeletePowerRequestList(VOID)
00251 {
00252
if (
gpPowerRequestMutex) {
00253
00254
00255
00256
00257 UserAssert(IsListEmpty(&
gPowerRequestList));
00258
00259
00260
00261
00262 UserFreePool(
gpPowerRequestMutex);
00263
gpPowerRequestMutex =
NULL;
00264 }
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00274 NTSTATUS xxxUserPowerEventCalloutWorker(
00275
PKWIN32_POWEREVENT_PARAMETERS Parms)
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
00285
00286
if (
gbNoMorePowerCallouts) {
00287
return STATUS_UNSUCCESSFUL;
00288 }
00289
00290
switch (EventNumber) {
00291
case PsW32FullWake:
00292
00293
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
00307
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
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
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
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
00356
00357
xxxSystemParametersInfo(SPI_SETLOWPOWERACTIVE, !Code, 0, 0);
00358
xxxSystemParametersInfo(SPI_SETPOWEROFFACTIVE, !Code, 0, 0);
00359
break;
00360
00361
case PsW32GdiOff:
00362
00363
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
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
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
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
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 }
00447
00448
00449
00450
00451
00452
00453
00454
00455 NTSTATUS UserPowerEventCallout(
00456
PKWIN32_POWEREVENT_PARAMETERS Parms)
00457 {
00458
00459
00460
00461
00462
if (!
gbVideoInitialized ||
gbNoMorePowerCallouts) {
00463
return STATUS_UNSUCCESSFUL;
00464 }
00465
00466 UserAssert(
gpepCSRSS !=
NULL);
00467
00468
00469
00470
00471
return QueuePowerRequest(Parms);
00472 }
00473
00474
00475
00476
00477
00478
00479
00480
00481 NTSTATUS xxxUserPowerStateCalloutWorker(VOID)
00482 {
00483
BOOL fContinue;
00484
BROADCASTSYSTEMMSGPARAMS bsmParams;
00485
NTSTATUS Status = STATUS_SUCCESS;
00486
TL tlpwnd;
00487
00488
00489
00490
00491
if (
gbNoMorePowerCallouts) {
00492
return STATUS_UNSUCCESSFUL;
00493 }
00494
00495
00496
00497
00498
EnterPowerCrit();
00499
gPowerState.
pEvent =
PtiCurrent()->pEventQueueServer;
00500
LeavePowerCrit();
00501
00502
if (!
gPowerState.
fCritical) {
00503
00504
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
00523
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
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
00557
00558
EnterPowerCrit();
00559
gPowerState.
pEvent =
NULL;
00560
LeavePowerCrit();
00561
00562
00563
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
00577
00578
EnterPowerCrit();
00579
gPowerState.
fInProgress =
FALSE;
00580
LeavePowerCrit();
00581
00582
00583
00584
00585
glinp.
timeLastInputMessage =
NtGetTickCount();
00586
00587
00588
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 }
00600
00601
00602
00603
00604
00605
00606
00607
00608 NTSTATUS UserPowerStateCallout(
00609
PKWIN32_POWERSTATE_PARAMETERS Parms)
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
00618
00619
if (!
gbVideoInitialized ||
gbNoMorePowerCallouts || !
gspwndLogonNotify) {
00620
return STATUS_UNSUCCESSFUL;
00621 }
00622
00623 UserAssert(
gpepCSRSS !=
NULL);
00624
00625
EnterPowerCrit();
00626
00627
00628
00629
00630
00631
if ((Promotion && !
gPowerState.
fInProgress) ||
00632 (!Promotion &&
gPowerState.
fInProgress)) {
00633
LeavePowerCrit();
00634
return STATUS_INVALID_PARAMETER;
00635 }
00636
00637
00638
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
00662
00663
if (Promotion) {
00664
return STATUS_SUCCESS;
00665 }
00666
00667
00668
00669
00670
return QueuePowerRequest(
NULL);
00671 }
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
VOID
00684 xxxUserPowerCalloutWorker(VOID)
00685 {
00686
PPOWERREQUEST pPowerRequest;
00687
TL tlPool;
00688
00689
while ((pPowerRequest =
UnqueuePowerRequest()) !=
NULL) {
00690
00691
00692
00693
00694
ThreadLockPoolCleanup(
PtiCurrent(), pPowerRequest, &tlPool,
CancelPowerRequest);
00695
00696
00697
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
00709
00710
ThreadUnlockPoolCleanup(
PtiCurrent(), &tlPool);
00711
KeSetEvent(&pPowerRequest->Event,
EVENT_INCREMENT,
FALSE);
00712 }
00713 }
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
VOID
00727 VideoPortCalloutThread(
00728 PVIDEO_WIN32K_CALLBACKS_PARAMS Params
00729 )
00730 {
00731
00732
00733
00734
00735 UserAssert(W32GetCurrentThread() ==
NULL);
00736
00737 Params->Status =
InitSystemThread(
NULL);
00738
00739
if (!
NT_SUCCESS(Params->Status)) {
00740
return;
00741 }
00742
00743
00744
EnterCrit();
00745
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
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
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
00829
LeaveCrit();
00830
00831
00832
00833
return;
00834 }
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
VOID
00845 VideoPortCallout(
00846 IN PVOID Params
00847 )
00848 {
00849
00850
00851
00852
00853
00854 HANDLE hThread;
00855
NTSTATUS Status;
00856
00857
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
00869
00870 ((PVIDEO_WIN32K_CALLBACKS_PARAMS)(Params))->Status =
Status;
00871 }