00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
#include "precomp.h"
00016
#pragma hdrstop
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
VOID
00030 WakeWowTask(
00031
PTHREADINFO pti
00032 )
00033 {
00034
PWOWPROCESSINFO pwpi;
00035
00036 pwpi = pti->
ppi->
pwpi;
00037
if (pwpi && !pwpi->
ptiScheduled) {
00038
KeSetEvent(pti->
pEventQueueServer,
EVENT_INCREMENT,
FALSE);
00039 }
00040 }
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 void InsertTask(
00061
PPROCESSINFO ppi,
00062
PTDB ptdbNew)
00063 {
00064
PTDB *pptdb;
00065
PTDB ptdb;
00066
int nPriority;
00067
PWOWPROCESSINFO pwpi = ppi->
pwpi;
00068
00069
CheckCritIn();
00070
00071 UserAssert(pwpi !=
NULL);
00072
00073 pptdb = &pwpi->
ptdbHead;
00074 nPriority = ptdbNew->
nPriority;
00075
00076
while ((ptdb = *pptdb) !=
NULL) {
00077
00078
00079
00080
if (ptdb == ptdbNew) {
00081 *pptdb = ptdbNew->
ptdbNext;
00082
00083
00084
00085
00086
while ((ptdb = *pptdb) !=
NULL) {
00087
if (nPriority < ptdb->
nPriority) {
00088
break;
00089 }
00090
00091 pptdb = &(ptdb->
ptdbNext);
00092 }
00093
break;
00094 }
00095
00096
00097
00098
00099
00100
if (nPriority < ptdb->
nPriority) {
00101
do {
00102
if (ptdb->
ptdbNext == ptdbNew) {
00103 ptdb->
ptdbNext = ptdbNew->
ptdbNext;
00104
break;
00105 }
00106 ptdb = ptdb->
ptdbNext;
00107 }
while (ptdb !=
NULL);
00108
break;
00109 }
00110
00111 pptdb = &(ptdb->
ptdbNext);
00112 }
00113
00114
00115
00116
00117 ptdbNew->
ptdbNext = *pptdb;
00118 *pptdb = ptdbNew;
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 void DestroyTask(
00130
PPROCESSINFO ppi,
00131
PTHREADINFO ptiToRemove)
00132 {
00133
PTDB ptdbToRemove = ptiToRemove->
ptdb;
00134
PTDB ptdb;
00135
PTDB* pptdb;
00136
PWOWPROCESSINFO pwpi = ppi->
pwpi;
00137
00138
00139
CheckCritIn();
00140
BEGINATOMICCHECK();
00141
00142 UserAssert(pwpi !=
NULL);
00143
00144
if (ptdbToRemove !=
NULL) {
00145
00146
if (ptdbToRemove->
TDB_Flags &
TDBF_SETUP) {
00147
00148
00149
00150
00151
00152
PDESKTOPINFO pdeskinfo =
GETDESKINFO(ptiToRemove);
00153
if (pdeskinfo->
spwndShell) {
00154
_PostMessage(pdeskinfo->
spwndShell,
DTM_SETUPAPPRAN, 0, 0);
00155 }
00156 }
00157
00158
00159
00160
if (ptdbToRemove->
pwti) {
00161
PWOWTHREADINFO *ppwti = &
gpwtiFirst;
00162
while (*ppwti != ptdbToRemove->
pwti && (*ppwti)->
pwtiNext !=
NULL) {
00163 ppwti = &((*ppwti)->pwtiNext);
00164 }
00165
if (*ppwti == ptdbToRemove->
pwti) {
00166 *ppwti = ptdbToRemove->
pwti->
pwtiNext;
00167 }
00168
CLOSE_PSEUDO_EVENT(&ptdbToRemove->
pwti->
pIdleEvent);
00169 UserFreePool(ptdbToRemove->
pwti);
00170 }
00171
00172
gpsi->nEvents -= ptdbToRemove->
nEvents;
00173
00174
00175
00176
00177 pptdb = &pwpi->
ptdbHead;
00178
while ((ptdb = *pptdb) !=
NULL) {
00179
00180
00181
00182
if (ptdb == ptdbToRemove) {
00183 *pptdb = ptdb->
ptdbNext;
00184 UserFreePool(ptdbToRemove);
00185 UserAssert(ptiToRemove->
ptdb == ptdbToRemove);
00186 ptiToRemove->
ptdb =
NULL;
00187
break;
00188 }
00189 pptdb = &(ptdb->
ptdbNext);
00190 }
00191 UserAssert(ptdb == ptdbToRemove);
00192 }
00193
ENDATOMICCHECK();
00194
00195
00196
00197
00198
00199
00200
if (pwpi->
ptiScheduled == ptiToRemove) {
00201 pwpi->
ptiScheduled =
NULL;
00202
ExitWowCritSect(ptiToRemove, pwpi);
00203
00204
00205
00206
00207
00208 pwpi->
nTaskLock = 0;
00209
00210
00211
00212
00213
00214
if (pwpi->
ptdbHead !=
NULL) {
00215
PTDB ptdb;
00216
00217
for (ptdb = pwpi->
ptdbHead; ptdb; ptdb = ptdb->
ptdbNext) {
00218
if (ptdb->
nEvents > 0) {
00219
KeSetEvent(ptdb->
pti->
pEventQueueServer,
00220
EVENT_INCREMENT,
FALSE);
00221
break;
00222 }
00223 }
00224
00225
if (!ptdb) {
00226
KeSetEvent(pwpi->
pEventWowExec,
EVENT_INCREMENT,
FALSE);
00227 }
00228 }
00229 }
00230 UserAssert(ptiToRemove != pwpi->
CSOwningThread);
00231
00232 }
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 BOOL xxxSleepTask(
00253 BOOL fInputIdle,
00254 HANDLE hEvent)
00255 {
00256
PTDB ptdb;
00257
PTHREADINFO pti;
00258
PPROCESSINFO ppi;
00259
PWOWPROCESSINFO pwpi;
00260
PSMS psms;
00261
NTSTATUS Status;
00262
int nHandles;
00263 BOOLEAN bWaitedAtLeastOnce;
00264
00265
00266
00267
00268
00269
00270
00271
00272
CheckCritIn();
00273
00274 pti =
PtiCurrent();
00275 ppi = pti->
ppi;
00276 pwpi = ppi->
pwpi;
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 psms = pti->
psmsCurrent;
00287
if (psms && psms->ptiReceiver == pti &&
00288 psms->ptiSender && !(psms->flags &
SMF_REPLY) &&
00289 psms->flags & (
SMF_RECEIVERBUSY |
SMF_RECEIVEDMESSAGE) &&
00290 psms->ptiSender->
TIF_flags &
TIF_16BIT &&
00291 (pwpi != psms->ptiSender->ppi->pwpi || !(pti->
TIF_flags &
TIF_16BIT)) ) {
00292
DirectedScheduleTask(psms->ptiReceiver, psms->ptiSender,
FALSE, psms);
00293 }
00294
00295
00296
00297
00298
00299
if (!(pti->
TIF_flags &
TIF_16BIT)) {
00300
return FALSE;
00301 }
00302
00303
00304
00305
00306
00307
if (pti == pwpi->
ptiScheduled) {
00308
ExitWowCritSect(pti, pwpi);
00309
if (!pwpi->
nTaskLock) {
00310 pwpi->
ptiScheduled =
NULL;
00311 }
00312 }
00313 UserAssert(pti != pwpi->
CSOwningThread);
00314
00315
00316
00317
00318
00319
00320
00321
00322
if (pwpi->
hEventWowExecClient == hEvent) {
00323
InsertTask(ppi, pti->
ptdb);
00324 pti->
pcti->
fsWakeMask = QS_ALLINPUT | QS_EVENT;
00325
if (pti->
pcti->
fsChangeBits & pti->
pcti->
fsWakeMask) {
00326 pti->
ptdb->
nEvents++;
00327
gpsi->nEvents++;
00328 }
00329 }
00330
00331
00332 bWaitedAtLeastOnce =
FALSE;
00333
00334
do {
00335
00336
00337
00338
00339
00340
00341
00342
if (pwpi->
ptiScheduled ==
NULL) {
00343 rescan:
00344
if (pwpi->
nRecvLock >= pwpi->
nSendLock) {
00345
for (ptdb = pwpi->
ptdbHead; ptdb; ptdb = ptdb->
ptdbNext) {
00346
if (ptdb->
nEvents > 0 &&
00347 !(hEvent ==
HEVENT_REMOVEME && ptdb->
pti == pti)) {
00348 pwpi->
ptiScheduled = ptdb->
pti;
00349
break;
00350 }
00351 }
00352
00353
if (bWaitedAtLeastOnce) {
00354
00355
00356
00357
00358
if (pwpi->
ptiScheduled == pti) {
00359
break;
00360 }
00361
00362 }
else {
00363
00364
00365
00366
00367
00368
if (fInputIdle &&
00369 pwpi->
ptiScheduled ==
NULL &&
00370
IsHooked(pti,
WHF_FOREGROUNDIDLE)) {
00371
00372
00373
00374
00375
00376
00377 pwpi->
ptiScheduled = pti;
00378
xxxCallHook(HC_ACTION, 0, 0, WH_FOREGROUNDIDLE);
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388 pwpi->
ptiScheduled =
NULL;
00389 fInputIdle =
FALSE;
00390
goto rescan;
00391 }
00392 }
00393 }
00394
00395
00396
00397
00398
00399
if (pwpi->
ptiScheduled !=
NULL) {
00400
KeSetEvent(pwpi->
ptiScheduled->
pEventQueueServer,
00401
EVENT_INCREMENT,
00402
FALSE
00403 );
00404
00405
00406
00407
00408
00409 }
else if (ppi->W32PF_Flags & W32PF_WAKEWOWEXEC) {
00410
if (pwpi->
hEventWowExecClient == hEvent) {
00411 pwpi->
ptiScheduled = pti;
00412 ppi->W32PF_Flags &= ~W32PF_WAKEWOWEXEC;
00413
InsertTask(ppi, pti->
ptdb);
00414
EnterWowCritSect(pti, pwpi);
00415 UserAssert(pti == pwpi->
ptiScheduled);
00416
return TRUE;
00417 }
else {
00418
KeSetEvent(pwpi->
pEventWowExec,
EVENT_INCREMENT,
FALSE);
00419 }
00420 }
else if ((pti->
TIF_flags &
TIF_SHAREDWOW) && !bWaitedAtLeastOnce) {
00421
if (pwpi->
hEventWowExecClient == hEvent) {
00422
00423
00424
00425
00426
zzzWakeInputIdle(pti);
00427 }
00428 }
00429
00430 }
else if (pwpi->
nTaskLock > 0 && pwpi->
ptiScheduled == pti
00431 && pti->
ptdb->
nEvents > 0) {
00432
KeSetEvent(pwpi->
ptiScheduled->
pEventQueueServer,
00433
EVENT_INCREMENT,
FALSE);
00434 }
00435
00436
00437
00438
00439
if (!(pti->
TIF_flags &
TIF_16BIT)) {
00440
return FALSE;
00441 }
else if (hEvent ==
HEVENT_REMOVEME) {
00442
InsertTask(ppi, pti->
ptdb);
00443
KeClearEvent(pti->
pEventQueueServer);
00444
return FALSE;
00445 }
00446
00447
if (pti->
apEvent ==
NULL) {
00448 pti->
apEvent = UserAllocPoolNonPaged(
POLL_EVENT_CNT *
sizeof(
PKEVENT), TAG_EVENT);
00449
if (pti->
apEvent ==
NULL)
00450
return FALSE;
00451 }
00452
00453
00454
00455
00456 pti->
apEvent[
IEV_TASK] = pti->
pEventQueueServer;
00457
00458
00459
00460
00461
if (pwpi->
hEventWowExecClient == hEvent) {
00462 pti->
apEvent[
IEV_WOWEXEC] = pwpi->
pEventWowExec;
00463 nHandles = 2;
00464 }
else {
00465 nHandles = 1;
00466 }
00467
00468
CheckForClientDeath();
00469
LeaveCrit();
00470
00471
Status =
KeWaitForMultipleObjects(nHandles,
00472 &pti->
apEvent[
IEV_TASK],
00473 WaitAny,
00474
WrUserRequest,
00475
UserMode,
00476
TRUE,
00477
NULL,
00478
NULL);
00479
00480
CheckForClientDeath();
00481
00482
EnterCrit();
00483
00484 bWaitedAtLeastOnce =
TRUE;
00485
00486
00487
if (
Status == STATUS_WAIT_1) {
00488 ppi->W32PF_Flags |= W32PF_WAKEWOWEXEC;
00489 }
else if (
Status == STATUS_USER_APC) {
00490
00491
00492
00493
00494
00495
00496
00497
00498 UserAssert(
PsIsThreadTerminating(
PsGetCurrentThread()));
00499
ClientDeliverUserApc();
00500 }
00501
00502 }
while (pwpi->
ptiScheduled != pti);
00503
00504
00505
00506
00507
00508
00509
00510 pti->
ptdb->
nEvents--;
00511
gpsi->nEvents--;
00512 UserAssert(
gpsi->nEvents >= 0);
00513
00514
InsertTask(ppi, pti->
ptdb);
00515
00516 ppi->W32PF_Flags &= ~W32PF_WAKEWOWEXEC;
00517
00518
EnterWowCritSect(pti, pwpi);
00519 UserAssert(pti == pwpi->
ptiScheduled);
00520
00521
00522
00523
return FALSE;
00524 }
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537 BOOL xxxUserYield(
00538
PTHREADINFO pti)
00539 {
00540
PPROCESSINFO ppi = pti->
ppi;
00541
00542
00543
00544
00545
00546
00547
00548
00549
if (pti->
TIF_flags &
TIF_16BIT) {
00550
if (pti == ppi->
pwpi->
ptiScheduled) {
00551
xxxReceiveMessages(pti);
00552 }
00553 }
else {
00554
xxxReceiveMessages(pti);
00555 }
00556
00557
00558
00559
00560
00561
00562
00563
if ((pti->
TIF_flags &
TIF_16BIT) && (pti->
ptdb !=
NULL)) {
00564
if (pti->
ptdb->
nEvents == 0) {
00565 pti->
ptdb->
nEvents++;
00566
gpsi->nEvents++;
00567 }
00568
InsertTask(ppi, pti->
ptdb);
00569
00570
00571
00572
00573
00574
xxxSleepTask(
TRUE,
NULL);
00575
00576
00577
00578
00579
xxxReceiveMessages(pti);
00580 }
00581
00582
00583
return TRUE;
00584 }
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594 VOID DirectedScheduleTask(
00595
PTHREADINFO ptiOld,
00596
PTHREADINFO ptiNew,
00597 BOOL bSendMsg,
00598 PSMS psms
00599 )
00600 {
00601
PWOWPROCESSINFO pwpiOld;
00602
PWOWPROCESSINFO pwpiNew;
00603
00604
CheckCritIn();
00605
00606 pwpiOld = ptiOld->
ppi->
pwpi;
00607 pwpiNew = ptiNew->
ppi->
pwpi;
00608
00609
00610
00611
00612
00613
00614
00615
if (ptiOld->
TIF_flags &
TIF_16BIT) {
00616
00617
if (pwpiOld->
ptiScheduled == ptiOld) {
00618 ptiOld->
ptdb->
nEvents++;
00619
gpsi->nEvents++;
00620
InsertTask(ptiOld->
ppi, ptiOld->
ptdb);
00621 }
00622
00623
00624
00625
00626
if (pwpiOld != pwpiNew || !(ptiNew->
TIF_flags &
TIF_16BIT)) {
00627
if (bSendMsg) {
00628 pwpiOld->
nSendLock++;
00629 psms->flags |=
SMF_WOWSEND;
00630 }
00631
else if (pwpiOld->
nRecvLock && psms->flags &
SMF_WOWRECEIVE) {
00632 pwpiOld->
nRecvLock--;
00633 psms->flags &= ~
SMF_WOWRECEIVE;
00634 }
00635 }
00636
00637 }
00638
00639
00640
00641
00642
00643
00644
00645
00646
if (ptiNew->
TIF_flags &
TIF_16BIT) {
00647
BOOL bRaisePriority;
00648
00649 ptiNew->
ptdb->
nEvents++;
00650
gpsi->nEvents++;
00651 bRaisePriority = bSendMsg || psms == ptiNew->
psmsSent;
00652
00653
if (bRaisePriority) {
00654 ptiNew->
ptdb->
nPriority--;
00655 }
00656
00657
InsertTask(ptiNew->
ppi, ptiNew->
ptdb);
00658
00659
if (bRaisePriority) {
00660 ptiNew->
ptdb->
nPriority++;
00661
WakeWowTask(ptiNew);
00662 }
00663
00664
00665
00666
00667
if (pwpiOld != pwpiNew || !(ptiOld->
TIF_flags &
TIF_16BIT)) {
00668
if (bSendMsg) {
00669 pwpiNew->
nRecvLock++;
00670 psms->flags |=
SMF_WOWRECEIVE;
00671 }
00672
else if (pwpiNew->
nSendLock && psms->flags &
SMF_WOWSEND) {
00673 pwpiNew->
nSendLock--;
00674 psms->flags &= ~
SMF_WOWSEND;
00675 }
00676 }
00677
00678 }
00679 }
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691 void xxxDirectedYield(
00692 DWORD dwThreadId)
00693 {
00694
PTHREADINFO ptiOld;
00695
PTHREADINFO ptiNew;
00696
00697
CheckCritIn();
00698
00699 ptiOld =
PtiCurrent();
00700
if (!(ptiOld->
TIF_flags &
TIF_16BIT) || !ptiOld->
ppi->
pwpi) {
00701 RIPMSG0(RIP_ERROR,
"DirectedYield called from 32 bit thread!");
00702
return;
00703 }
00704
00705
00706
00707
00708
00709 ptiOld->
ptdb->
nEvents++;
00710
gpsi->nEvents++;
00711
InsertTask(ptiOld->
ppi, ptiOld->
ptdb);
00712
00713
00714
00715
00716
if (dwThreadId != DY_OLDYIELD) {
00717
00718 ptiNew =
PtiFromThreadId(dwThreadId);
00719
if (ptiNew ==
NULL)
00720
return;
00721
00722
if (ptiNew->
TIF_flags &
TIF_16BIT) {
00723 ptiNew->
ptdb->
nEvents++;
00724
gpsi->nEvents++;
00725 ptiNew->
ptdb->
nPriority--;
00726
InsertTask(ptiNew->
ppi, ptiNew->
ptdb);
00727 ptiNew->
ptdb->
nPriority++;
00728 }
00729 }
00730
00731
xxxSleepTask(
TRUE,
NULL);
00732 }
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
#if 0
00748
DWORD CurrentTaskLock(
00749 DWORD hlck)
00750 {
00751
PWOWPROCESSINFO pwpi =
PpiCurrent()->pwpi;
00752
00753
if (!pwpi)
00754
return 0;
00755
00756
if (hlck == 0) {
00757 pwpi->
nTaskLock++;
00758
return ~(
DWORD)pwpi->
ptiScheduled->
ptdb;
00759 }
else if ((~hlck) == (
DWORD)pwpi->
ptiScheduled->
ptdb) {
00760 pwpi->
nTaskLock--;
00761 }
00762
00763
return 0;
00764 }
00765
#endif