00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
#include "precomp.h"
00014
#pragma hdrstop
00015
00016
VOID DestroyProcessesObjects(
PPROCESSINFO ppi);
00017
VOID DestroyThreadsMessages(
PQ pq,
PTHREADINFO pti);
00018
void CheckProcessForeground(
PTHREADINFO pti);
00019
void ScreenSaverCheck(
PTHREADINFO pti);
00020
DWORD xxxPollAndWaitForSingleObject(
PKEVENT pEvent, PVOID pExecObject,
00021 DWORD dwMilliseconds);
00022
00023
NTSTATUS InitiateShutdown(
PETHREAD Thread, PULONG lpdwFlags);
00024
NTSTATUS EndShutdown(
PETHREAD Thread, NTSTATUS StatusShutdown);
00025
void SetVDMCursorBounds(LPRECT lprc);
00026
NTSTATUS InitQEntryLookaside(VOID);
00027
void SetAppStarting (
PPROCESSINFO ppi);
00028
00029
#pragma alloc_text(INIT, InitQEntryLookaside)
00030
00031 PW32PROCESS
gpwpCalcFirst;
00032
00033
#if DBG
00034
#define MSG_SENT 0
00035
#define MSG_POST 1
00036
#define MSG_RECV 2
00037
#define MSG_PEEK 3
00038
VOID TraceDdeMsg(UINT msg, HWND hwndFrom, HWND hwndTo, UINT code);
00039
#else
00040 #define TraceDdeMsg(m, h1, h2, c)
00041
#endif // DBG
00042
00043 PPAGED_LOOKASIDE_LIST QLookaside;
00044 PPAGED_LOOKASIDE_LIST QEntryLookaside;
00045
00046
#if DBG
00047
void DebugValidateMLIST(
PMLIST pml)
00048 {
00049
int c;
00050
PQMSG pqmsg;
00051
00052
00053
00054
00055 UserAssert(!pml->
pqmsgRead || !pml->
pqmsgRead->
pqmsgPrev);
00056 UserAssert(!pml->
pqmsgWriteLast || !pml->
pqmsgWriteLast->
pqmsgNext);
00057
00058
00059
00060
00061
c = pml->
cMsgs;
00062 UserAssert(
c >= 0);
00063 pqmsg = pml->
pqmsgRead;
00064
while (--
c >= 0) {
00065 UserAssert(pqmsg);
00066
if (
c == 0) {
00067 UserAssert(pqmsg == pml->
pqmsgWriteLast);
00068 }
00069
00070 pqmsg = pqmsg->
pqmsgNext;
00071 }
00072
00073 UserAssert(!pqmsg);
00074
00075
00076
00077
00078
c = pml->
cMsgs;
00079 pqmsg = pml->
pqmsgWriteLast;
00080
while (--
c >= 0) {
00081 UserAssert(pqmsg);
00082
if (
c == 0) {
00083 UserAssert(pqmsg == pml->
pqmsgRead);
00084 }
00085
00086 pqmsg = pqmsg->
pqmsgPrev;
00087 }
00088
00089 UserAssert(!pqmsg);
00090 }
00091
00092
void DebugValidateMLISTandQMSG(
PMLIST pml,
PQMSG pqmsg)
00093 {
00094
PQMSG pqmsgT;
00095
00096
DebugValidateMLIST(pml);
00097
for (pqmsgT = pml->
pqmsgRead; pqmsgT; pqmsgT = pqmsgT->
pqmsgNext) {
00098
if (pqmsgT == pqmsg) {
00099
return;
00100 }
00101 }
00102
00103 UserAssert(pqmsgT == pqmsg);
00104 }
00105
00106
#else
00107 #define DebugValidateMLIST(pml)
00108 #define DebugValidateMLISTandQMSG(pml, pqmsg)
00109
#endif
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 BOOL xxxSetProcessInitState(
00121
PEPROCESS Process,
00122 DWORD dwFlags)
00123 {
00124 PW32PROCESS W32Process;
00125
NTSTATUS Status;
00126
00127
CheckCritIn();
00128 UserAssert(
IsWinEventNotifyDeferredOK());
00129
00130
00131
00132
00133 W32Process = (PW32PROCESS)Process->
Win32Process;
00134
if (W32Process ==
NULL) {
00135
Status = AllocateW32Process(Process);
00136
if (!
NT_SUCCESS(
Status)) {
00137
return FALSE;
00138 }
00139 W32Process = (PW32PROCESS)Process->
Win32Process;
00140
#if DBG
00141
00142
00143
00144
00145
00146
00147
if ((W32Process->W32PF_Flags & W32PF_PROCESSCONNECTED) == 0) {
00148 UserAssert((W32Process->W32PF_Flags & W32PF_APPSTARTING) == 0);
00149 }
00150
#endif
00151
}
00152
00153
00154
00155
00156
DeferWinEventNotify();
00157
if (
dwFlags == 0) {
00158
if (!(W32Process->W32PF_Flags & W32PF_WOW)) {
00159
00160
00161
00162
00163
if (W32Process->W32PF_Flags & W32PF_STARTGLASS) {
00164 W32Process->W32PF_Flags &= ~W32PF_STARTGLASS;
00165
zzzCalcStartCursorHide(
NULL, 0);
00166 }
00167
00168
00169
00170
00171
00172 W32Process->W32PF_Flags |= W32PF_CONSOLEAPPLICATION;
00173
SET_PSEUDO_EVENT(&W32Process->InputIdleEvent);
00174 }
00175 }
else if (!(W32Process->W32PF_Flags & W32PF_INITIALIZED)) {
00176 W32Process->W32PF_Flags |= W32PF_INITIALIZED;
00177
00178
00179
00180
00181
00182
00183
SET_PUDF(
PUDF_ALLOWFOREGROUNDACTIVATE);
00184 TAGMSG1(DBGTAG_FOREGROUND,
"xxxSetProcessInitState set PUDF. %#p", W32Process);
00185
00186
00187
00188
00189
00190
if (Process ==
gpepCSRSS) {
00191
dwFlags |= STARTF_FORCEOFFFEEDBACK;
00192 }
00193
00194
00195
00196
00197
00198
if (
dwFlags & STARTF_FORCEOFFFEEDBACK) {
00199 W32Process->W32PF_Flags |= W32PF_FORCEOFFFEEDBACK;
00200
zzzCalcStartCursorHide(
NULL, 0);
00201 }
else if (
dwFlags & STARTF_FORCEONFEEDBACK) {
00202
zzzCalcStartCursorHide(W32Process, 2000);
00203 }
00204 }
00205
00206
00207
00208
EndDeferWinEventNotifyWithoutProcessing();
00209
return TRUE;
00210 }
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 BOOL CheckAllowForeground(
00223
PEPROCESS pep)
00224 {
00225
BOOL fCreator =
TRUE;
00226 HANDLE hpid = (HANDLE)
pep->InheritedFromUniqueProcessId;
00227 LUID luid;
00228 PACCESS_TOKEN pat;
00229
PEPROCESS pepParent;
00230
PPROCESSINFO ppiParent;
00231
UINT uAncestors = 0;
00232
BOOL fAllowForeground =
FALSE;
00233
NTSTATUS Status;
00234
00235
do {
00236
00237
00238
00239
LeaveCrit();
00240
Status =
LockProcessByClientId(hpid, &pepParent);
00241
EnterCrit();
00242
if (!
NT_SUCCESS(
Status)) {
00243
00244
00245
00246
00247
00248
00249
00250
00251
if (
HasForegroundActivateRight(
pep->InheritedFromUniqueProcessId)) {
00252 fAllowForeground =
TRUE;
00253 }
00254
break;
00255 }
00256
00257 ppiParent =
PpiFromProcess(pepParent);
00258
if (ppiParent ==
NULL) {
00259
UnlockProcess(pepParent);
00260
break;
00261 }
00262
00263
00264
00265
00266
00267
if (!fCreator
00268 && (
IsShellProcess(ppiParent)
00269 || ((ppiParent->
rpwinsta !=
NULL)
00270 && (ppiParent->
rpwinsta->
dwWSF_Flags &
WSF_NOIO)))) {
00271
00272
UnlockProcess(pepParent);
00273
break;
00274 }
00275 fAllowForeground =
CanForceForeground(ppiParent);
00276
if (!fAllowForeground) {
00277
00278
00279
00280
00281
00282
00283
if (ppiParent->
ptiList !=
NULL
00284 && (ppiParent->
ptiList->
TIF_flags &
TIF_ALLOWFOREGROUNDACTIVATE)) {
00285 fAllowForeground =
TRUE;
00286 }
00287
00288
if (!fAllowForeground){
00289
00290
00291
00292 hpid = (HANDLE)pepParent->
InheritedFromUniqueProcessId;
00293
00294
00295
00296
00297
if (fCreator) {
00298 fCreator =
FALSE;
00299 pat =
PsReferencePrimaryToken(pepParent);
00300
if (pat !=
NULL) {
00301
Status =
SeQueryAuthenticationIdToken(pat, &luid);
00302
if (
NT_SUCCESS(
Status)) {
00303 fAllowForeground =
RtlEqualLuid(&luid, &
luidSystem);
00304
00305
00306
00307
00308
00309
if (fAllowForeground) {
00310 ppiParent->W32PF_Flags |=
W32PF_ALLOWSETFOREGROUND;
00311 }
00312 }
00313
ObDereferenceObject(pat);
00314 }
00315 }
00316 }
00317 }
00318
UnlockProcess(pepParent);
00319
00320
00321
00322
00323 }
while (!fAllowForeground && (uAncestors++ < 5));
00324
00325
return fAllowForeground ||
GiveUpForeground();
00326 }
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341 void xxxUserNotifyConsoleApplication(
00342 PCONSOLE_PROCESS_INFO pcpi)
00343 {
00344
NTSTATUS Status;
00345
PEPROCESS Process;
00346
BOOL retval;
00347
00348
00349
00350
00351
LeaveCrit();
00352
Status =
LockProcessByClientId((HANDLE)LongToHandle( pcpi->dwProcessID ), &Process);
00353
EnterCrit();
00354
00355
if (!
NT_SUCCESS(
Status)) {
00356 RIPMSG2(RIP_WARNING,
"xxxUserNotifyConsoleApplication: Failed with Process ID == %X, Status = %x\n",
00357 pcpi->dwProcessID,
Status);
00358
return;
00359 }
00360
00361 retval =
xxxSetProcessInitState(Process, 0);
00362
00363
00364
00365
00366
00367
00368
if (retval) {
00369
if (pcpi->dwFlags & CPI_NEWPROCESSWINDOW) {
00370
PPROCESSINFO ppiCurrent =
PpiCurrent();
00371
if (
CheckAllowForeground(Process)) {
00372
if (!(ppiCurrent->W32PF_Flags & W32PF_APPSTARTING)) {
00373
SetAppStarting(ppiCurrent);
00374 }
00375
SET_PUDF(
PUDF_ALLOWFOREGROUNDACTIVATE);
00376 TAGMSG0(DBGTAG_FOREGROUND,
"xxxUserNotifyConsoleApplication set PUDF");
00377 ppiCurrent->W32PF_Flags |= W32PF_ALLOWFOREGROUNDACTIVATE;
00378 }
00379
00380 TAGMSG3(DBGTAG_FOREGROUND,
"xxxUserNotifyConsoleApplication %s W32PF %#p-%#p",
00381 ((ppiCurrent->W32PF_Flags & W32PF_ALLOWFOREGROUNDACTIVATE) ?
"set" :
"NOT"),
00382 ppiCurrent,
PpiFromProcess(Process));
00383 }
00384 }
else {
00385 RIPMSG1(RIP_WARNING,
"xxxUserNotifyConsoleApplication - SetProcessInitState failed on %#p", Process);
00386 }
00387
00388
00389
00390
UnlockProcess(Process);
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404 void UserSetConsoleProcessWindowStation(
00405 DWORD idProcess,
00406 HWINSTA hwinsta
00407 )
00408 {
00409
NTSTATUS Status;
00410
PEPROCESS Process;
00411
00412
00413
00414
00415
LeaveCrit();
00416
Status =
LockProcessByClientId((HANDLE)LongToHandle( idProcess ), &Process);
00417
EnterCrit();
00418
00419
if (!
NT_SUCCESS(
Status)) {
00420 RIPMSG2(RIP_WARNING,
"UserSetConsoleProcessWindowStation: Failed with Process ID == %X, Status = %x\n",
00421 idProcess,
Status);
00422
return;
00423 }
00424
00425 Process->
Win32WindowStation = hwinsta;
00426
00427
UnlockProcess(Process);
00428 }
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 BOOL xxxUserNotifyProcessCreate(
00446 DWORD idProcess,
00447 DWORD idParentThread,
00448 ULONG_PTR dwData,
00449 DWORD dwFlags)
00450 {
00451
PEPROCESS Process;
00452
PETHREAD Thread;
00453
PTHREADINFO pti;
00454
NTSTATUS Status;
00455
BOOL retval;
00456
00457
CheckCritIn();
00458
00459
00460
GiveForegroundActivateRight((HANDLE)idProcess);
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
if ((
dwFlags & 0xb) != 0) {
00476
LeaveCrit();
00477
Status =
LockProcessByClientId((HANDLE)LongToHandle( idProcess ), &Process);
00478
EnterCrit();
00479
00480
if (!
NT_SUCCESS(
Status)) {
00481 RIPMSG2(RIP_WARNING,
"xxxUserNotifyProcessCreate: Failed with Process ID == %X, Status = %x\n",
00482 idProcess,
Status);
00483
return FALSE;
00484 }
00485
00486 retval =
xxxSetProcessInitState(Process, ((
dwFlags & 1) ? STARTF_FORCEONFEEDBACK : STARTF_FORCEOFFFEEDBACK));
00487
if (!retval) {
00488 RIPMSG1(RIP_WARNING,
"xxxUserNotifyProcessCreate - SetProcessInitState failed on %#p", Process);
00489 }
00490
if (
dwFlags & 0x8) {
00491
if (Process->
Win32Process)
00492 ((PW32PROCESS)Process->
Win32Process)->W32PF_Flags |= W32PF_WOW;
00493 }
00494
00495
UnlockProcess(Process);
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
LeaveCrit();
00510
Status =
LockThreadByClientId((HANDLE)LongToHandle( idParentThread ), &Thread);
00511
EnterCrit();
00512
00513
if (!
NT_SUCCESS(
Status)) {
00514 RIPMSG2(RIP_WARNING,
"xxxUserNotifyProcessCreate: Failed with Thread ID == %X, Status = %x\n",
00515 idParentThread,
Status);
00516
return FALSE;
00517 }
00518
00519 pti =
PtiFromThread(Thread);
00520
if (pti && (pti->
TIF_flags &
TIF_16BIT)) {
00521 pti->
TIF_flags |=
TIF_ALLOWFOREGROUNDACTIVATE;
00522 TAGMSG1(DBGTAG_FOREGROUND,
"xxxUserNotifyProcessCreate set TIF %#p", pti);
00523 }
00524
00525
UnlockThread(Thread);
00526
00527 }
else if (
dwFlags == 4) {
00528
00529
00530
00531
00532
00533
PWOWTHREADINFO pwti;
00534
00535
00536
00537
00538
for (pwti =
gpwtiFirst; pwti !=
NULL; pwti = pwti->
pwtiNext) {
00539
if (pwti->
idTask == idProcess) {
00540
break;
00541 }
00542 }
00543
00544
00545
00546
00547
00548
if (pwti ==
NULL) {
00549 pwti = (
PWOWTHREADINFO)UserAllocPoolWithQuota(
00550
sizeof(
WOWTHREADINFO), TAG_WOWTHREADINFO);
00551
if (pwti ==
NULL) {
00552
return FALSE;
00553 }
00554
INIT_PSEUDO_EVENT(&pwti->
pIdleEvent);
00555 pwti->
idTask = idProcess;
00556 pwti->
pwtiNext =
gpwtiFirst;
00557
gpwtiFirst = pwti;
00558 }
else {
00559
RESET_PSEUDO_EVENT(&pwti->
pIdleEvent);
00560 }
00561
00562 pwti->
idWaitObject = dwData;
00563
LeaveCrit();
00564
Status =
LockThreadByClientId((HANDLE)LongToHandle( idParentThread ), &Thread);
00565
EnterCrit();
00566
if (!
NT_SUCCESS(
Status))
00567
return FALSE;
00568
00569
if (!
NT_SUCCESS(
Status)) {
00570 RIPMSG2(RIP_WARNING,
"xxxUserNotifyProcessCreate: Failed with Thread ID == %X, Status = %x\n",
00571 idParentThread,
Status);
00572
return FALSE;
00573 }
00574
00575 pwti->
idParentProcess = HandleToUlong(Thread->
Cid.UniqueProcess);
00576
UnlockThread(Thread);
00577 }
00578
00579
return TRUE;
00580 }
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591 void zzzCalcStartCursorHide(
00592 PW32PROCESS pwp,
00593 DWORD timeAdd)
00594 {
00595
DWORD timeNow;
00596 PW32PROCESS pwpT;
00597 PW32PROCESS *ppwpT;
00598
00599
00600 timeNow =
NtGetTickCount();
00601
00602
if (pwp !=
NULL) {
00603
00604
00605
00606
00607
00608
if (!(pwp->W32PF_Flags & W32PF_STARTGLASS)) {
00609
00610
00611
00612
00613
for (pwpT =
gpwpCalcFirst; pwpT !=
NULL; pwpT = pwpT->NextStart) {
00614
if (pwpT == pwp)
00615
break;
00616 }
00617
00618
if (pwpT != pwp) {
00619 pwp->NextStart =
gpwpCalcFirst;
00620
gpwpCalcFirst = pwp;
00621 }
00622 }
00623 pwp->StartCursorHideTime = timeAdd + timeNow;
00624 pwp->W32PF_Flags |= W32PF_STARTGLASS;
00625 }
00626
00627
gtimeStartCursorHide = 0;
00628
for (ppwpT = &
gpwpCalcFirst; (pwpT = *ppwpT) !=
NULL; ) {
00629
00630
00631
00632
00633
00634
if (!(pwpT->W32PF_Flags & W32PF_STARTGLASS) ||
00635 (pwpT->W32PF_Flags & W32PF_FORCEOFFFEEDBACK)) {
00636 *ppwpT = pwpT->NextStart;
00637
continue;
00638 }
00639
00640
00641
00642
00643
if (
gtimeStartCursorHide < pwpT->StartCursorHideTime)
00644
gtimeStartCursorHide = pwpT->StartCursorHideTime;
00645
00646
00647
00648
00649
00650
if (
ComputeTickDelta(timeNow, pwpT->StartCursorHideTime) > 0) {
00651 pwpT->W32PF_Flags &= ~W32PF_STARTGLASS;
00652 *ppwpT = pwpT->NextStart;
00653
continue;
00654 }
00655
00656
00657
00658
00659 ppwpT = &pwpT->NextStart;
00660 }
00661
00662
00663
00664
00665
00666
if (
gtimeStartCursorHide <= timeNow)
00667
gtimeStartCursorHide = 0;
00668
00669
00670
00671
00672
00673
zzzUpdateCursorImage();
00674 }
00675
00676
00677 #define QUERY_VALUE_BUFFER 80
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687 PUNICODE_STRING
gpastrSetupExe;
00688 int giSetupExe;
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702 BOOL SetAppImeCompatFlags(
00703
PTHREADINFO pti,
00704 PUNICODE_STRING pstrModName,
00705 PUNICODE_STRING pstrBaseFileName)
00706 {
00707
DWORD dwImeFlags = 0;
00708 WCHAR szHex[
QUERY_VALUE_BUFFER];
00709 WORD wPrimaryLangID;
00710 LCID lcid;
00711
int iSetup;
00712
BOOL fSetup =
FALSE;
00713
int iAppName;
00714
int cAppNames;
00715 PUNICODE_STRING rgpstrAppNames[2];
00716 UNICODE_STRING strHex;
00717
00718
00719
00720
00721 UserAssert(pti->
ppi ==
PpiCurrent());
00722
00723
00724
00725
00726 UserAssert(0 == pstrModName->Buffer[ pstrModName->Length /
sizeof(WCHAR) ]);
00727
00728
if (
FastGetProfileStringW(
00729
NULL,
00730
PMAP_IMECOMPAT,
00731 pstrModName->Buffer,
00732
NULL,
00733 szHex,
00734
sizeof(szHex)
00735 )) {
00736
00737
00738
00739
00740
00741
00742
RtlInitUnicodeString(&strHex, szHex);
00743
RtlUnicodeStringToInteger(&strHex, 0, (PULONG)&dwImeFlags);
00744 }
00745
00746
00747
00748
00749
00750
00751
00752
00753 ZwQueryDefaultLocale(
FALSE, &lcid);
00754 wPrimaryLangID = PRIMARYLANGID(lcid);
00755
00756
if ((wPrimaryLangID == LANG_KOREAN || wPrimaryLangID == LANG_JAPANESE) &&
00757 (LOWORD(pti->
dwExpWinVer) <=
VER31)) {
00758
00759
00760
00761 pti->
ppi->
dwImeCompatFlags = dwImeFlags;
00762 }
else {
00763 pti->
ppi->
dwImeCompatFlags = dwImeFlags & (IMECOMPAT_NOFINALIZECOMPSTR | IMECOMPAT_HYDRACLIENT);
00764
if (dwImeFlags & IMECOMPAT_NOFINALIZECOMPSTR) {
00765 RIPMSG1(RIP_WARNING,
"IMECOMPAT_NOFINALIZECOMPSTR is set to ppi=0x%p", pti->
ppi);
00766 }
00767
if (dwImeFlags & IMECOMPAT_HYDRACLIENT) {
00768 RIPMSG1(RIP_WARNING,
"IMECOMPAT_HYDRACLIENT is set to ppi=0x%p", pti->
ppi);
00769 }
00770 }
00771
00772
00773
if (
gpastrSetupExe ==
NULL) {
00774
return fSetup;
00775 }
00776
00777 rgpstrAppNames[0] = pstrModName;
00778 cAppNames = 1;
00779
if (pstrBaseFileName) {
00780 rgpstrAppNames[1] = pstrBaseFileName;
00781 cAppNames = 2;
00782 }
00783
00784
for (iAppName = 0;
00785 iAppName < cAppNames && !fSetup;
00786 iAppName++) {
00787
00788 iSetup = 0;
00789
while (iSetup <
giSetupExe) {
00790
int i;
00791
if ((i =
RtlCompareUnicodeString(rgpstrAppNames[iAppName], &(
gpastrSetupExe[iSetup]),
TRUE)) == 0) {
00792 fSetup =
TRUE;
00793
break;
00794 }
00795 iSetup++;
00796 }
00797 }
00798
00799
return fSetup;
00800 }
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814 BOOL SetAppCompatFlags(
00815
PTHREADINFO pti)
00816 {
00817
DWORD dwFlags = 0;
00818
DWORD dwFlags2 = 0;
00819 WCHAR szHex[
QUERY_VALUE_BUFFER];
00820 WCHAR szKey[90];
00821 WCHAR *pchStart, *pchEnd;
00822
DWORD cb;
00823 PUNICODE_STRING pstrAppName;
00824 UNICODE_STRING strKey;
00825 UNICODE_STRING strImageName;
00826 ULONG cbSize;
00827
typedef struct tagCompat2Key {
00828
DWORD dwCompatFlags2;
00829
DWORD dwMajorVersion;
00830
DWORD dwMinorVersion;
00831
DWORD dwBuildNumber;
00832
DWORD dwPlatformId;
00833 } COMPAT2KEY, *PCOMPAT2KEY;
00834 COMPAT2KEY Compat2Key;
00835
00836
00837
00838
00839 UserAssert(pti->
ppi ==
PpiCurrent());
00840
00841 UserAssert(pti->
ppi->
ptiList);
00842
00843 UserAssert(!(pti->
TIF_flags &
TIF_16BIT));
00844
00845
00846
00847
00848 UserAssert(pti == pti->
ppi->
ptiList);
00849
00850
if (pti->
ptiSibling) {
00851 pti->
pClientInfo->
dwCompatFlags = pti->
dwCompatFlags = pti->
ptiSibling->
dwCompatFlags;
00852 pti->
pClientInfo->
dwCompatFlags2 = pti->
dwCompatFlags2 = pti->
ptiSibling->
dwCompatFlags2;
00853
return FALSE;
00854 }
00855
00856
try {
00857
00858
00859
00860
00861
00862
00863
00864
if (pti->
pstrAppName !=
NULL)
00865 pstrAppName = pti->
pstrAppName;
00866
else {
00867
struct _RTL_USER_PROCESS_PARAMETERS *ProcessParameters = pti->pEThread->ThreadsProcess->Peb->ProcessParameters;
00868
00869
ProbeForRead(ProcessParameters,
sizeof(*ProcessParameters),
sizeof(
BYTE));
00870 strImageName =
ProbeAndReadUnicodeString(&ProcessParameters->ImagePathName);
00871
ProbeForReadUnicodeStringBuffer(strImageName);
00872 pstrAppName = &strImageName;
00873 }
00874 pchStart = pchEnd = pstrAppName->Buffer +
00875 (pstrAppName->Length /
sizeof(WCHAR));
00876
00877
00878
00879
00880
while (
TRUE) {
00881
if (pchEnd == pstrAppName->Buffer) {
00882 pchEnd = pchStart;
00883
break;
00884 }
00885
00886
if (*pchEnd == TEXT(
'.'))
00887
break;
00888
00889 pchEnd--;
00890 }
00891
00892
00893
00894
00895 pchStart = pchEnd;
00896
00897
while (pchStart != pstrAppName->Buffer) {
00898
if (*pchStart == TEXT(
'\\') || *pchStart == TEXT(
':')) {
00899 pchStart++;
00900
break;
00901 }
00902
00903 pchStart--;
00904 }
00905
00906
#define MODULESUFFIXSIZE (8*sizeof(WCHAR))
00907
#define MAXMODULENAMELEN (sizeof(szKey) - MODULESUFFIXSIZE)
00908
00909
00910
00911
00912
00913 cb = (
DWORD)(pchEnd - pchStart) *
sizeof(WCHAR);
00914
if (cb >=
MAXMODULENAMELEN)
00915 cb =
MAXMODULENAMELEN -
sizeof(WCHAR);
00916 RtlCopyMemory(szKey, pchStart, cb);
00917 } except (W32ExceptionHandler(
FALSE, RIP_ERROR)) {
00918
return FALSE;
00919 }
00920
00921 szKey[(cb /
sizeof(WCHAR))] = 0;
00922
#undef MAXMODULENAMELEN
00923
00924
if (
FastGetProfileStringW(
00925
NULL,
00926
PMAP_COMPAT32,
00927 szKey,
00928
NULL,
00929 szHex,
00930
sizeof(szHex)
00931 )) {
00932
00933 UNICODE_STRING strHex;
00934
00935
00936
00937
00938
00939
00940
RtlInitUnicodeString(&strHex, szHex);
00941
RtlUnicodeStringToInteger(&strHex, 0, (PULONG)&
dwFlags);
00942 }
00943
00944 pti->
dwCompatFlags =
dwFlags;
00945 pti->
pClientInfo->
dwCompatFlags =
dwFlags;
00946
00947
00948
00949
00950 {
00951 PIMAGE_NT_HEADERS pnthdr;
00952
USHORT uMinorImage, uMajorImage;
00953 PWCHAR pWritePtr = szKey + cb/
sizeof(WCHAR);
00954
00955
try {
00956 pnthdr =
RtlImageNtHeader(pti->pEThread->ThreadsProcess->SectionBaseAddress);
00957
if (pnthdr !=
NULL) {
00958 uMinorImage = pnthdr->OptionalHeader.MinorImageVersion & 0xFF;
00959 uMajorImage = pnthdr->OptionalHeader.MajorImageVersion & 0xFF;
00960 }
else {
00961 uMinorImage = uMajorImage = 0;
00962 }
00963 } except (W32ExceptionHandler(
FALSE, RIP_ERROR)) {
00964
goto Compat2Failed;
00965 }
00966 swprintf(pWritePtr,
L"%u.%u", uMajorImage, uMinorImage);
00967 }
00968 cbSize =
FastGetProfileValue(
00969
NULL,
00970
PMAP_COMPAT2,
00971 szKey,
00972
NULL,
00973 (LPBYTE)&Compat2Key,
00974
sizeof(Compat2Key));
00975
00976
00977
00978
00979
00980
00981
if (cbSize >=
sizeof(
DWORD)) {
00982 pti->
dwCompatFlags2 = pti->
pClientInfo->
dwCompatFlags2 = Compat2Key.dwCompatFlags2;
00983
00984
if (cbSize >=
sizeof(COMPAT2KEY) && Compat2Key.dwMajorVersion != 0) {
00985 PPEB Peb = pti->pEThread->ThreadsProcess->Peb;
00986
00987 Peb->OSMajorVersion = Compat2Key.dwMajorVersion;
00988 Peb->OSMinorVersion = Compat2Key.dwMinorVersion;
00989 Peb->OSBuildNumber = (
USHORT)(Compat2Key.dwBuildNumber);
00990 Peb->OSPlatformId = Compat2Key.dwPlatformId;
00991 }
00992 }
00993
00994 Compat2Failed:
00995
00996
00997
00998 szKey[(cb /
sizeof(WCHAR))] = 0;
00999
RtlInitUnicodeString(&strKey, szKey);
01000
01001
return SetAppImeCompatFlags(pti, &strKey,
NULL);
01002 }
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014 DWORD GetAppCompatFlags(
01015
PTHREADINFO pti)
01016 {
01017
01018
01019
if (pti ==
NULL)
01020 pti =
PtiCurrentShared();
01021
01022
return pti->
dwCompatFlags;
01023 }
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033 DWORD GetAppCompatFlags2(
01034 WORD wVer)
01035 {
01036
return GetAppCompatFlags2ForPti(
PtiCurrentShared(), wVer);
01037 }
01038
01039 DWORD GetAppImeCompatFlags(
01040
PTHREADINFO pti)
01041 {
01042
if (pti ==
NULL) {
01043 pti =
PtiCurrentShared();
01044 }
01045
01046 UserAssert(pti->
ppi);
01047
return pti->
ppi->
dwImeCompatFlags;
01048 }
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059 VOID CheckAppStarting(
PWND pwnd, UINT message, UINT_PTR nID, LPARAM lParam)
01060 {
01061 LARGE_INTEGER liStartingTimeout;
01062
PPROCESSINFO *pppi = &
gppiStarting;
01063
01064
KeQuerySystemTime(&liStartingTimeout);
01065 liStartingTimeout.QuadPart -= (LONGLONG)(
CMSAPPSTARTINGTIMEOUT * 10000);
01066
while (*pppi !=
NULL) {
01067
if (liStartingTimeout.QuadPart > (*pppi)->Process->CreateTime.QuadPart) {
01068 (*pppi)->W32PF_Flags &= ~(W32PF_APPSTARTING | W32PF_ALLOWFOREGROUNDACTIVATE);
01069 TAGMSG1(DBGTAG_FOREGROUND,
"CheckAppStarting clear W32PF %#p", *pppi);
01070 *pppi = (*pppi)->
ppiNext;
01071 }
else {
01072 pppi = &(*pppi)->
ppiNext;
01073 }
01074 }
01075
01076 TAGMSG0(DBGTAG_FOREGROUND,
"Removing all entries from ghCanActivateForegroundPIDs array");
01077 RtlZeroMemory(
ghCanActivateForegroundPIDs,
sizeof(
ghCanActivateForegroundPIDs));
01078
return;
01079 UNREFERENCED_PARAMETER(pwnd);
01080 UNREFERENCED_PARAMETER(message);
01081 UNREFERENCED_PARAMETER(nID);
01082 UNREFERENCED_PARAMETER(lParam);
01083 }
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094 void SetAppStarting (
PPROCESSINFO ppi)
01095 {
01096
static UINT_PTR guAppStartingId = 0;
01097
01098
01099
01100 UserAssert((ppi->W32PF_Flags & W32PF_APPSTARTING) == 0);
01101
01102
01103
01104
01105
01106
01107 UserAssert((ppi->W32PF_Flags & W32PF_PROCESSCONNECTED));
01108
01109 ppi->W32PF_Flags |= W32PF_APPSTARTING;
01110 ppi->
ppiNext =
gppiStarting;
01111
gppiStarting = ppi;
01112
01113
01114
01115
01116
if (
gptmrMaster !=
NULL) {
01117 guAppStartingId =
InternalSetTimer(
NULL, guAppStartingId,
01118
CMSAPPSTARTINGTIMEOUT +
CMSHUNGAPPTIMEOUT,
01119
CheckAppStarting, TMRF_RIT | TMRF_ONESHOT);
01120 }
01121 }
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131 void ClearAppStarting (
PPROCESSINFO ppi)
01132 {
01133
REMOVE_FROM_LIST(
PROCESSINFO,
gppiStarting, ppi, ppiNext);
01134 ppi->W32PF_Flags &= ~W32PF_APPSTARTING;
01135 }
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147 NTSTATUS zzzInitTask(
01148 UINT dwExpWinVer,
01149 DWORD dwAppCompatFlags,
01150 PUNICODE_STRING pstrModName,
01151 PUNICODE_STRING pstrBaseFileName,
01152 DWORD hTaskWow,
01153 DWORD dwHotkey,
01154 DWORD idTask,
01155 DWORD dwX,
01156 DWORD dwY,
01157 DWORD dwXSize,
01158 DWORD dwYSize)
01159 {
01160
PTHREADINFO ptiCurrent;
01161
PTDB ptdb;
01162
PPROCESSINFO ppi;
01163
PWOWTHREADINFO pwti;
01164
01165 ptiCurrent =
PtiCurrent();
01166 ppi = ptiCurrent->
ppi;
01167
01168
01169
01170
01171
01172
01173
if (ptiCurrent->
pstrAppName !=
NULL)
01174 UserFreePool(ptiCurrent->
pstrAppName);
01175 ptiCurrent->
pstrAppName = UserAllocPoolWithQuota(
sizeof(UNICODE_STRING) +
01176 pstrModName->Length +
sizeof(WCHAR), TAG_TEXT);
01177
if (ptiCurrent->
pstrAppName !=
NULL) {
01178 ptiCurrent->
pstrAppName->Buffer = (PWCHAR)(ptiCurrent->
pstrAppName + 1);
01179
try {
01180 RtlCopyMemory(ptiCurrent->
pstrAppName->Buffer, pstrModName->Buffer,
01181 pstrModName->Length);
01182 ptiCurrent->
pstrAppName->Buffer[pstrModName->Length /
sizeof(WCHAR)] = 0;
01183 } except (W32ExceptionHandler(
FALSE, RIP_WARNING)) {
01184 UserFreePool(ptiCurrent->
pstrAppName);
01185 ptiCurrent->
pstrAppName =
NULL;
01186
return STATUS_OBJECT_NAME_INVALID;
01187 }
01188 ptiCurrent->
pstrAppName->MaximumLength = pstrModName->Length +
sizeof(WCHAR);
01189 ptiCurrent->
pstrAppName->Length = pstrModName->Length;
01190 }
else
01191
return STATUS_OBJECT_NAME_INVALID;
01192
01193
01194
01195
01196
if (!(ppi->W32PF_Flags & W32PF_APPSTARTING)) {
01197
SetAppStarting(ppi);
01198 }
01199
01200
01201
01202
01203
01204
01205
01206 ppi->
usi.
dwFlags &= ~STARTF_USESHOWWINDOW;
01207
01208
01209
01210
01211
if (dwHotkey != 0) {
01212 ppi->
dwHotkey = dwHotkey;
01213 }
01214
01215
01216
01217
01218 ppi->
usi.
cb =
sizeof(ppi->
usi);
01219
01220
if (dwX == CW_USEDEFAULT || dwX ==
CW2_USEDEFAULT) {
01221 ppi->
usi.
dwFlags &= ~STARTF_USEPOSITION;
01222 }
else {
01223 ppi->
usi.
dwFlags |= STARTF_USEPOSITION;
01224 ppi->
usi.
dwX = dwX;
01225 ppi->
usi.
dwY = dwY;
01226 }
01227
01228
01229
01230
01231
if (dwXSize == CW_USEDEFAULT || dwXSize ==
CW2_USEDEFAULT) {
01232 ppi->
usi.
dwFlags &= ~STARTF_USESIZE;
01233 }
else {
01234 ppi->
usi.
dwFlags |= STARTF_USESIZE;
01235 ppi->
usi.
dwXSize = dwXSize;
01236 ppi->
usi.
dwYSize = dwYSize;
01237 }
01238
01239
01240
01241
01242
if ((ptdb = (
PTDB)UserAllocPoolWithQuota(
sizeof(
TDB), TAG_WOWTDB)) ==
NULL)
01243
return STATUS_NO_MEMORY;
01244 ptiCurrent->
ptdb = ptdb;
01245
01246
01247
01248
01249
01250 ptiCurrent->
TIF_flags |=
TIF_16BIT |
TIF_FIRSTIDLE;
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260 ptdb->
pwti =
NULL;
01261
if (idTask) {
01262 ptiCurrent->
TIF_flags |=
TIF_SHAREDWOW;
01263
01264
01265
01266
01267
if (idTask != (
DWORD)-1) {
01268
for (pwti =
gpwtiFirst; pwti !=
NULL; pwti = pwti->
pwtiNext) {
01269
if (pwti->
idTask == idTask) {
01270 ptdb->
pwti = pwti;
01271
break;
01272 }
01273 }
01274
#if DBG
01275
if (pwti ==
NULL) {
01276 RIPMSG0(RIP_WARNING,
"InitTask couldn't find WOW struct\n");
01277 }
01278
#endif
01279
}
01280 }
01281 ptiCurrent->
pClientInfo->
dwTIFlags |= ptiCurrent->
TIF_flags;
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
DeferWinEventNotify();
01292
if (!
FJOURNALRECORD() && !
FJOURNALPLAYBACK())
01293
zzzReattachThreads(
FALSE);
01294
01295
01296
01297
01298
01299 ptdb->
hTaskWow = LOWORD(hTaskWow);
01300
01301
01302
01303
01304
zzzCalcStartCursorHide((PW32PROCESS)ppi, 5000);
01305
01306
01307
01308
01309
01310 ptiCurrent->
dwExpWinVer = dwExpWinVer;
01311 ptiCurrent->
pClientInfo->
dwExpWinVer = dwExpWinVer;
01312
01313
01314
01315
01316
#define NORMAL_PRIORITY_TASK 10
01317
01318
01319
01320
01321
01322
01323 ptdb->
nPriority =
NORMAL_PRIORITY_TASK;
01324 ptdb->
nEvents = 0;
01325 ptdb->
pti = ptiCurrent;
01326 ptdb->
ptdbNext =
NULL;
01327 ptdb->
TDB_Flags = 0;
01328
01329
InsertTask(ppi, ptdb);
01330
zzzEndDeferWinEventNotify();
01331
01332 ptiCurrent->
dwCompatFlags = dwAppCompatFlags;
01333 ptiCurrent->
pClientInfo->
dwCompatFlags = dwAppCompatFlags;
01334
01335 UserAssert(ptiCurrent->
ppi->
ptiList);
01336
01337
01338
01339
01340
01341
01342
01343
try {
01344
if (
SetAppImeCompatFlags(ptiCurrent, ptiCurrent->
pstrAppName,
01345 pstrBaseFileName)) {
01346
01347
01348
01349 ptdb->
TDB_Flags =
TDBF_SETUP;
01350 ppi->W32PF_Flags |= W32PF_SETUPAPP;
01351 }
01352 } except (W32ExceptionHandler(
FALSE, RIP_WARNING)) {
01353 }
01354
01355
01356
01357
01358
01359
01360 ppi->pwpi->ptiScheduled = ptiCurrent;
01361 ppi->pwpi->CSLockCount = -1;
01362
01363
EnterWowCritSect(ptiCurrent, ppi->pwpi);
01364
01365
01366
01367
01368
zzzShowStartGlass(10000);
01369
01370
return STATUS_SUCCESS;
01371 }
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382 void zzzShowStartGlass(
01383 DWORD dwTimeout)
01384 {
01385
PPROCESSINFO ppi;
01386
01387
01388
01389
01390
01391
01392
01393 ppi =
PpiCurrent();
01394
if (ppi->W32PF_Flags & W32PF_SHOWSTARTGLASSCALLED) {
01395
01396
01397
01398
01399
SET_PUDF(
PUDF_ALLOWFOREGROUNDACTIVATE);
01400 TAGMSG0(DBGTAG_FOREGROUND,
"zzzShowStartGlass set PUDF");
01401 ppi->W32PF_Flags |= W32PF_ALLOWFOREGROUNDACTIVATE;
01402 TAGMSG1(DBGTAG_FOREGROUND,
"zzzShowStartGlass set W32PF %#p", ppi);
01403 }
01404 ppi->W32PF_Flags |= W32PF_SHOWSTARTGLASSCALLED;
01405
01406
01407
01408
01409
zzzCalcStartCursorHide((PW32PROCESS)ppi, dwTimeout);
01410 }
01411
01412
01413
01414
01415
01416 PQ GetJournallingQueue(
PTHREADINFO pti)
01417 {
01418
PHOOK phook;
01419
01420
01421
01422
if ((pti->
TIF_flags &
TIF_DONTJOURNALATTACH)
01423 || (pti->
rpdesk ==
NULL)) {
01424
01425
return NULL;
01426 }
01427
01428
01429
01430 phook =
PhkFirstGlobalValid(pti, WH_JOURNALPLAYBACK);
01431
if (phook ==
NULL) {
01432 phook =
PhkFirstGlobalValid(pti, WH_JOURNALRECORD);
01433 }
01434
01435
01436
01437 UserAssert((phook ==
NULL)
01438 ^
IsHooked(pti, (
WHF_FROM_WH(WH_JOURNALPLAYBACK) |
WHF_FROM_WH(WH_JOURNALRECORD))));
01439
01440
01441
01442
01443
return ((phook ==
NULL) ?
NULL :
GETPTI(phook)->pq);
01444 }
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458 void ClearQueueServerEvent (WORD wWakeMask)
01459 {
01460
PTHREADINFO ptiCurrent =
PtiCurrent();
01461 UserAssert(wWakeMask != 0);
01462 ptiCurrent->
pcti->
fsWakeMask = wWakeMask;
01463
KeClearEvent(ptiCurrent->
pEventQueueServer);
01464 }
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474 ULONG
ParseReserved(
01475 WCHAR *pchReserved,
01476 WCHAR *pchFind)
01477 {
01478 ULONG dw;
01479 WCHAR *pch, *pchT, ch;
01480 UNICODE_STRING uString;
01481
01482 dw = 0;
01483
if (pchReserved !=
NULL && (pch = wcsstr(pchReserved, pchFind)) !=
NULL) {
01484 pch += wcslen(pchFind);
01485
01486 pchT = pch;
01487
while (*pchT >=
'0' && *pchT <=
'9')
01488 pchT++;
01489
01490 ch = *pchT;
01491 *pchT = 0;
01492
RtlInitUnicodeString(&uString, pch);
01493 *pchT = ch;
01494
01495
RtlUnicodeStringToInteger(&uString, 0, &dw);
01496 }
01497
01498
return dw;
01499 }
01500
01501 NTSTATUS xxxCreateThreadInfo(
01502
PETHREAD pEThread,
01503 BOOL IsSystemThread)
01504 {
01505
DWORD dwTIFlags = 0;
01506
PPROCESSINFO ppi;
01507
PTHREADINFO ptiCurrent;
01508
PEPROCESS pEProcess = pEThread->
ThreadsProcess;
01509
PUSERSTARTUPINFO pusi;
01510 PRTL_USER_PROCESS_PARAMETERS ProcessParams;
01511
PDESKTOP pdesk =
NULL;
01512 HDESK hdesk =
NULL;
01513 HWINSTA hwinsta;
01514
PQ pq;
01515
NTSTATUS Status;
01516
BOOL fFirstThread;
01517 PTEB pteb = NtCurrentTeb();
01518
TL tlpdesk;
01519
01520
CheckCritIn();
01521 UserAssert(
IsWinEventNotifyDeferredOK());
01522
01523
ValidateProcessSessionId(pEProcess);
01524
01525
01526
01527
01528
01529
if (
gbCleanedUpResources) {
01530 RIPMSG0(RIP_ERROR,
"No more GUI threads should be created");
01531
return STATUS_PROCESS_IS_TERMINATING;
01532 }
01533
01534
01535
01536
01537
gdwGuiThreads++;
01538
01539
01540
01541
01542
01543
01544
01545
if (IsSystemThread) {
01546 dwTIFlags =
TIF_SYSTEMTHREAD |
TIF_DONTATTACHQUEUE |
TIF_DISABLEIME;
01547 }
01548
01549
if (!(dwTIFlags &
TIF_SYSTEMTHREAD) && pEProcess ==
gpepCSRSS) {
01550 dwTIFlags =
TIF_CSRSSTHREAD |
TIF_DONTATTACHQUEUE |
TIF_DISABLEIME;
01551 }
01552
01553 ProcessParams = (pEProcess->
Peb ? pEProcess->
Peb->ProcessParameters :
NULL);
01554
01555
01556
01557
01558 ppi =
PpiCurrent();
01559
01560
#if defined(_WIN64)
01561
01562
01563
01564
01565
01566
if (ppi->W32PF_Flags & W32PF_WOW64) {
01567 dwTIFlags |=
TIF_WOW64;
01568 }
01569
#endif //defined(_WIN64)
01570
01571
01572
01573
01574
if (
gpidLogon == pEThread->
Cid.UniqueProcess) {
01575
if (ppi->
ptiList !=
NULL) {
01576 dwTIFlags |=
TIF_DISABLEIME;
01577 RIPMSG1(RIP_VERBOSE,
"WinLogon, second or other thread. pti=%x", pEThread->
Tcb.
Win32Thread);
01578 }
01579 }
01580
01581
01582
01583
01584
01585
01586
01587 ptiCurrent = (
PTHREADINFO)pEThread->
Tcb.
Win32Thread;
01588
01589 ptiCurrent->
TIF_flags = dwTIFlags;
01590
Lock(&ptiCurrent->
spklActive,
gspklBaseLayout);
01591 ptiCurrent->
pcti = &(ptiCurrent->
cti);
01592
01593
01594
01595
01596
01597
if (ppi->W32PF_Flags & W32PF_DISABLEIME)
01598 ptiCurrent->
TIF_flags |=
TIF_DISABLEIME;
01599
01600
01601
01602
01603
01604
01605 UserAssert(ppi !=
NULL);
01606
01607 ptiCurrent->
ppi = ppi;
01608 ptiCurrent->
ptiSibling = ppi->
ptiList;
01609 ppi->
ptiList = ptiCurrent;
01610 ppi->
cThreads++;
01611
01612
01613
if (pteb !=
NULL)
01614 pteb->Win32ThreadInfo = ptiCurrent;
01615
01616
01617
01618
01619
if (dwTIFlags &
TIF_SYSTEMTHREAD) {
01620 ptiCurrent->
pClientInfo = UserAllocPoolWithQuota(
sizeof(
CLIENTINFO),
01621 TAG_CLIENTTHREADINFO);
01622
if (ptiCurrent->
pClientInfo ==
NULL) {
01623
Status = STATUS_NO_MEMORY;
01624
goto CreateThreadInfoFailed;
01625 }
01626 }
else {
01627
01628
01629
01630
01631 UserAssert(NtCurrentTeb() !=
NULL);
01632 ptiCurrent->
pClientInfo = ((
PCLIENTINFO)((NtCurrentTeb())->Win32ClientInfo));
01633
01634
01635
01636
01637
if (((PW32PROCESS)ppi)->W32PF_Flags & W32PF_RESTRICTED) {
01638 ptiCurrent->
TIF_flags |=
TIF_RESTRICTED;
01639 }
01640 }
01641
01642
01643
01644
01645
01646
Status = ZwCreateEvent(&ptiCurrent->
hEventQueueClient,
01647 EVENT_ALL_ACCESS,
01648
NULL,
01649 SynchronizationEvent,
01650
FALSE);
01651
01652
if (
NT_SUCCESS(
Status)) {
01653
Status =
ObReferenceObjectByHandle(ptiCurrent->
hEventQueueClient,
01654 EVENT_ALL_ACCESS,
01655 *
ExEventObjectType,
01656
UserMode,
01657 &ptiCurrent->
pEventQueueServer,
01658
NULL);
01659
if (
NT_SUCCESS(
Status)) {
01660
Status =
ProtectHandle(ptiCurrent->
hEventQueueClient,
TRUE);
01661 }
else if (
Status == STATUS_INVALID_HANDLE) {
01662 ptiCurrent->
hEventQueueClient =
NULL;
01663 }
01664 }
01665
if (!
NT_SUCCESS(
Status)) {
01666
goto CreateThreadInfoFailed;
01667 }
01668
01669
01670
01671
01672
01673 fFirstThread = !(ppi->W32PF_Flags & W32PF_THREADCONNECTED);
01674 ppi->W32PF_Flags |= W32PF_THREADCONNECTED;
01675
01676
01677
01678
01679
01680
if (ProcessParams) {
01681
01682 pusi = &ppi->
usi;
01683
01684
if ((pusi->
cb == 0) && (ProcessParams->WindowFlags != 0)) {
01685 pusi->
cb =
sizeof(
USERSTARTUPINFO);
01686 pusi->
dwX = ProcessParams->StartingX;
01687 pusi->
dwY = ProcessParams->StartingY;
01688 pusi->
dwXSize = ProcessParams->CountX;
01689 pusi->
dwYSize = ProcessParams->CountY;
01690 pusi->
dwFlags = ProcessParams->WindowFlags;
01691 pusi->
wShowWindow = (WORD)ProcessParams->ShowWindowFlags;
01692 }
01693
01694
if (fFirstThread) {
01695
01696
01697
01698
01699
01700
01701
01702
01703
if (ProcessParams->WindowFlags & STARTF_USEHOTKEY) {
01704 ppi->
dwHotkey = HandleToUlong(ProcessParams->StandardInput);
01705 }
else {
01706 ppi->
dwHotkey =
ParseReserved(ProcessParams->ShellInfo.Buffer,
01707
L"hotkey.");
01708 }
01709
01710
01711
01712
01713 UserAssert(!ppi->
hMonitor);
01714
if (ProcessParams->WindowFlags & STARTF_HASSHELLDATA) {
01715 HMONITOR hMonitor;
01716
01717 hMonitor = (HMONITOR)(ProcessParams->StandardOutput);
01718
if (
ValidateHmonitor(hMonitor)) {
01719 ppi->
hMonitor = hMonitor;
01720 }
01721 }
01722 }
01723 }
01724
01725
01726
01727
01728
01729 UserAssert(ptiCurrent->
rpdesk ==
NULL);
01730
if (!(ptiCurrent->
TIF_flags & (
TIF_SYSTEMTHREAD |
TIF_CSRSSTHREAD)) &&
01731
grpWinStaList) {
01732
01733
BOOL bShutDown =
FALSE;
01734
01735 hdesk =
xxxResolveDesktop(
01736 NtCurrentProcess(),
01737 &ProcessParams->DesktopInfo,
01738 &hwinsta, (ProcessParams->WindowFlags & STARTF_DESKTOPINHERIT),
01739 &bShutDown);
01740
01741
if (hdesk ==
NULL) {
01742
01743
if (bShutDown) {
01744
01745
01746
01747 ULONG_PTR adwParameters[5] = {0, 0, 0, 0, MB_DEFAULT_DESKTOP_ONLY};
01748 ULONG ErrorResponse;
01749
01750
LeaveCrit();
01751
01752
ExRaiseHardError((
NTSTATUS)STATUS_DLL_INIT_FAILED_LOGOFF,
01753
ARRAY_SIZE(adwParameters),
01754 0,
01755 adwParameters,
01756 OptionOkNoWait,
01757 &ErrorResponse);
01758
01759 ZwTerminateProcess(NtCurrentProcess(), STATUS_DLL_INIT_FAILED);
01760
01761
EnterCrit();
01762 }
01763
01764
Status = STATUS_DLL_INIT_FAILED;
01765
goto CreateThreadInfoFailed;
01766
01767 }
else {
01768
01769
xxxSetProcessWindowStation(hwinsta,
KernelMode);
01770
01771
01772
01773
01774
Status =
ObReferenceObjectByHandle(
01775 hdesk,
01776 0,
01777 *
ExDesktopObjectType,
01778
KernelMode,
01779 &pdesk,
01780
NULL);
01781
01782
if (!
NT_SUCCESS(
Status)) {
01783 UserAssert(pdesk ==
NULL);
01784
goto CreateThreadInfoFailed;
01785 }
01786
01787
ThreadLockDesktop(ptiCurrent, pdesk, &tlpdesk, LDLT_FN_CREATETHREADINFO);
01788
01789
ObDereferenceObject(pdesk);
01790
01791
01792
01793
01794
if ((ppi->
hdeskStartup ==
NULL) &&
01795 (pEProcess->
UniqueProcessId !=
gpidLogon)) {
01796
01797
LockDesktop(&ppi->
rpdeskStartup, pdesk, LDL_PPI_DESKSTARTUP2, (ULONG_PTR)ppi);
01798 ppi->hdeskStartup = hdesk;
01799 }
01800 }
01801 }
01802
01803
01804
01805
01806
01807
if (pEProcess->
Peb !=
NULL)
01808 ptiCurrent->
dwExpWinVer =
RtlGetExpWinVer(pEProcess->
SectionBaseAddress);
01809
else
01810 ptiCurrent->
dwExpWinVer =
VER40;
01811
01812 ptiCurrent->
pClientInfo->
dwExpWinVer = ptiCurrent->
dwExpWinVer;
01813 ptiCurrent->
pClientInfo->
dwTIFlags = ptiCurrent->
TIF_flags;
01814
01815
if (ptiCurrent->
spklActive) {
01816 ptiCurrent->
pClientInfo->
CodePage = ptiCurrent->
spklActive->
CodePage;
01817 ptiCurrent->
pClientInfo->
hKL = ptiCurrent->
spklActive->
hkl;
01818 }
else {
01819 ptiCurrent->
pClientInfo->
CodePage = CP_ACP;
01820 ptiCurrent->
pClientInfo->
hKL = 0;
01821 }
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
BEGINATOMICCHECK();
01834
zzzSetDesktop(ptiCurrent, pdesk, hdesk);
01835
ENDATOMICCHECK();
01836
01837
01838
01839
01840
01841
if (pdesk ==
grpdeskRitInput) {
01842
PQ pq;
01843 UserAssert((pdesk ==
NULL) || (ptiCurrent->
pDeskInfo == pdesk->
pDeskInfo));
01844 UserAssert(ptiCurrent->
rpdesk == pdesk);
01845 pq =
GetJournallingQueue(ptiCurrent);
01846
if (pq !=
NULL) {
01847 ptiCurrent->
pq = pq;
01848 pq->
cThreads++;
01849 }
01850 }
01851
01852
01853
01854
01855
if (ptiCurrent->
pq ==
NULL) {
01856
if ((pq =
AllocQueue(
NULL,
NULL)) ==
NULL) {
01857
Status = STATUS_NO_MEMORY;
01858
goto CreateThreadInfoFailed;
01859 }
01860
01861
01862
01863 ptiCurrent->
pq = pq;
01864 pq->
ptiMouse = pq->
ptiKeyboard = ptiCurrent;
01865 pq->
cThreads++;
01866 }
01867
01868
01869
01870
01871
01872
01873
01874
01875
if (ProcessParams && ProcessParams->WindowFlags & STARTF_SCREENSAVER) {
01876
01877
if (fFirstThread) {
01878 UserAssert(
gppiScreenSaver ==
NULL);
01879
01880
01881
01882
01883
01884
if (
gpidLogon == 0 || pEProcess->
InheritedFromUniqueProcessId !=
gpidLogon) {
01885 RIPMSG0(RIP_WARNING,
"Only the Logon process can launch a screen saver.");
01886 ProcessParams->WindowFlags &= ~STARTF_SCREENSAVER;
01887
goto NotAScreenSaver;
01888 }
01889
01890
gppiScreenSaver = ppi;
01891
gptSSCursor =
gpsi->ptCursor;
01892 ppi->W32PF_Flags |= W32PF_SCREENSAVER;
01893 }
01894
#if DBG
01895
else {
01896 UserAssert(ppi->W32PF_Flags & W32PF_SCREENSAVER);
01897 }
01898
#endif
01899
01900
SetForegroundPriority(ptiCurrent,
TRUE);
01901
01902
if (fFirstThread) {
01903 ppi->W32PF_Flags |= W32PF_IDLESCREENSAVER;
01904 }
01905
01906
01907
01908
01909 ptiCurrent->
TIF_flags |=
TIF_DISABLEIME;
01910 }
01911
01912 NotAScreenSaver:
01913
01914
01915
01916
01917
if (!(ptiCurrent->
TIF_flags & (
TIF_SYSTEMTHREAD |
TIF_CSRSSTHREAD))) {
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
if (!(ppi->W32PF_Flags & W32PF_CLASSESREGISTERED)) {
01928
if (!
LW_RegisterWindows(
FALSE)) {
01929 RIPMSG0(RIP_WARNING,
"xxxCreateThreadInfo: LW_RegisterWindows failed");
01930
Status = STATUS_UNSUCCESSFUL;
01931
goto CreateThreadInfoFailed;
01932 }
01933 ppi->W32PF_Flags |= W32PF_CLASSESREGISTERED;
01934
if (ptiCurrent->
pClientInfo) {
01935 ptiCurrent->
pClientInfo->
CI_flags |=
CI_REGISTERCLASSES;
01936 }
01937 }
01938
01939
if (fFirstThread) {
01940
01941
01942
01943
01944
01945
DeferWinEventNotify();
01946
zzzCalcStartCursorHide((PW32PROCESS)pEProcess->
Win32Process, 5000);
01947
EndDeferWinEventNotifyWithoutProcessing();
01948
01949
01950
01951
01952
if (
grpWinStaList && ppi->
rpwinsta ==
NULL) {
01953 RIPERR0(ERROR_CAN_NOT_COMPLETE, RIP_WARNING,
"System is not initialized\n");
01954
Status = STATUS_UNSUCCESSFUL;
01955
goto CreateThreadInfoFailed;
01956 }
01957 }
01958 }
else {
01959
01960
01961
01962
01963
01964
if ((
SYSCUR(ARROW) !=
NULL) &&
01965 !(ppi->W32PF_Flags & W32PF_CLASSESREGISTERED)) {
01966
01967 ppi->W32PF_Flags |= W32PF_CLASSESREGISTERED;
01968
if (!
LW_RegisterWindows(ptiCurrent->
TIF_flags &
TIF_SYSTEMTHREAD)) {
01969 RIPMSG0(RIP_WARNING,
"xxxCreateThreadInfo: LW_RegisterWindows failed");
01970
Status = STATUS_UNSUCCESSFUL;
01971
goto CreateThreadInfoFailed;
01972 }
01973 }
01974 }
01975
01976
01977
01978
01979
01980
01981
SET_TIME_LAST_READ(ptiCurrent);
01982
01983
01984
01985
01986
01987
if (ppi->W32PF_Flags & W32PF_WAITFORINPUTIDLE)
01988 ptiCurrent->
TIF_flags |=
TIF_WAITFORINPUTIDLE;
01989
01990
01991
01992
01993 ptiCurrent->
TIF_flags |=
TIF_GUITHREADINITIALIZED;
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
if (!(ppi->W32PF_Flags & (W32PF_ALLOWFOREGROUNDACTIVATE | W32PF_APPSTARTING))) {
02012
if (((
gptiForeground !=
NULL) && (ppi ==
gptiForeground->
ppi))
02013 || ((
glinp.
ptiLastWoken !=
NULL) && (ppi ==
glinp.
ptiLastWoken->
ppi))) {
02014
02015 ptiCurrent->
TIF_flags |=
TIF_ALLOWFOREGROUNDACTIVATE;
02016 TAGMSG1(DBGTAG_FOREGROUND,
"xxxCreateThreadInfo set TIF %#p", ptiCurrent);
02017 }
02018 }
02019
02020
if (
IS_IME_ENABLED()) {
02021
02022
02023
02024
CreateInputContext(0);
02025 }
02026
02027
02028
02029
02030
if (!(dwTIFlags & (
TIF_SYSTEMTHREAD |
TIF_CSRSSTHREAD))) {
02031
02032
if (
SetAppCompatFlags(ptiCurrent)) {
02033
02034
02035
02036 ppi->W32PF_Flags |= W32PF_SETUPAPP;
02037 }
02038
02039
Status =
ClientThreadSetup();
02040
if (!
NT_SUCCESS(
Status)) {
02041 RIPMSG1(RIP_WARNING,
"ClientThreadSetup failed with NTSTATUS %lx",
Status);
02042
goto CreateThreadInfoFailed;
02043 }
02044 }
02045
02046
if ((
NT_SUCCESS(
Status) && fFirstThread) &&
02047 !(ppi->W32PF_Flags & W32PF_CONSOLEAPPLICATION)) {
02048
02049
02050
02051
02052
02053
02054
PlayEventSound(
USER_SOUND_OPEN);
02055 }
02056
02057
02058
02059
02060
02061
02062
02063
02064
if (pdesk !=
NULL) {
02065
if (pdesk->
dwDTFlags &
DF_DESTROYED) {
02066 RIPMSG1(RIP_WARNING,
"xxxCreateThreadInfo: pdesk destroyed:%#p", pdesk);
02067
Status = STATUS_UNSUCCESSFUL;
02068
goto CreateThreadInfoFailed;
02069 }
02070
ThreadUnlockDesktop(ptiCurrent, &tlpdesk, LDUT_FN_CREATETHREADINFO1);
02071 }
02072
02073
02074
02075 UserAssert(
NT_SUCCESS(
Status));
02076
02077
return Status;
02078
02079 CreateThreadInfoFailed:
02080
02081 RIPMSG2(RIP_WARNING,
"xxxCreateThreadInfo: failed: pti %#p pdesk %#p",
02082 ptiCurrent, pdesk);
02083
02084
if (pdesk !=
NULL) {
02085
ThreadUnlockDesktop(ptiCurrent, &tlpdesk, LDUT_FN_CREATETHREADINFO2);
02086 }
02087
xxxDestroyThreadInfo();
02088
return Status;
02089 }
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102 PQ AllocQueue(
02103
PTHREADINFO ptiKeyState,
02104
02105
PQ pq)
02106 {
02107
USHORT cLockCount;
02108
02109
if (pq ==
NULL) {
02110 pq =
ExAllocateFromPagedLookasideList(
QLookaside);
02111
if (pq ==
NULL) {
02112
return NULL;
02113 }
02114 cLockCount = 0;
02115 }
else {
02116
DebugValidateMLIST(&pq->
mlInput);
02117
02118
02119
02120 cLockCount = pq->
cLockCount;
02121 }
02122 RtlZeroMemory(pq,
sizeof(
Q));
02123 pq->
cLockCount = cLockCount;
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
if (ptiKeyState) {
02141 RtlCopyMemory(pq->
afKeyState, ptiKeyState->
pq->
afKeyState,
CBKEYSTATE);
02142 }
else {
02143 RtlCopyMemory(pq->
afKeyState,
gafAsyncKeyState,
CBKEYSTATE);
02144 }
02145
02146
02147
02148
02149
02150
if (
02151 !
TEST_GTERMF(
GTERMF_MOUSE)) {
02152 pq->
iCursorLevel--;
02153 }
02154
02155
02156
02157
LockQCursor(pq,
SYSCUR(WAIT));
02158
02159
DebugValidateMLIST(&pq->
mlInput);
02160
return pq;
02161 }
02162
02163
02164
02165
02166
02167
02168 VOID FreeQueue(
02169
PQ pq)
02170 {
02171
#if DBG
02172
02173
02174
02175
02176
02177
02178
02179 pq->
QF_flags &= ~
QF_INDESTROY;
02180
#endif
02181
02182 UserAssertMsg0(pq !=
gpqForeground,
"FreeQueue(gpqForeground) !");
02183 UserAssertMsg0(pq !=
gpqForegroundPrev,
"FreeQueue(gpqForegroundPrev) !");
02184 UserAssertMsg0(pq !=
gpqCursor,
"FreeQueue(gpqCursor) !");
02185
ExFreeToPagedLookasideList(
QLookaside, pq);
02186 }
02187
02188
02189
02190
02191
02192
02193 VOID FreeCachedQueues(
02194 VOID)
02195 {
02196
if (
QLookaside !=
NULL) {
02197
ExDeletePagedLookasideList(
QLookaside);
02198 UserFreePool(
QLookaside);
02199
QLookaside =
NULL;
02200 }
02201 }
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211 void zzzDestroyQueue(
02212
PQ pq,
02213
PTHREADINFO pti)
02214 {
02215
PTHREADINFO ptiT;
02216
PTHREADINFO ptiAny, ptiBestMouse, ptiBestKey;
02217 PLIST_ENTRY pHead, pEntry;
02218
02219
#if DBG
02220
USHORT cDying = 0;
02221
#endif
02222
02223
BOOL fSetFMouseMoved =
FALSE;
02224
02225
DebugValidateMLIST(&pq->
mlInput);
02226
02227 UserAssert(pq->
cThreads);
02228 pq->
cThreads--;
02229
02230
if (pq->
cThreads != 0) {
02231
02232
02233
02234
02235
02236
if (pq->
ptiSysLock == pti) {
02237
CheckSysLock(6, pq,
NULL);
02238 pq->
ptiSysLock =
NULL;
02239 }
02240
02241
if ((pq->
ptiKeyboard == pti) || (pq->
ptiMouse == pti)) {
02242
02243
02244
02245
02246 ptiAny =
NULL;
02247 ptiBestMouse =
NULL;
02248 ptiBestKey =
NULL;
02249
02250 pHead = &pti->
rpdesk->
PtiList;
02251
for (pEntry = pHead->Flink; pEntry != pHead; pEntry = pEntry->Flink) {
02252 ptiT = CONTAINING_RECORD(pEntry,
THREADINFO, PtiLink);
02253
02254
02255
02256
02257
02258
if ((ptiT->
TIF_flags &
TIF_INCLEANUP) || (ptiT->
pq != pq)) {
02259
#if DBG
02260
if (ptiT->
pq == pq && (ptiT->
TIF_flags &
TIF_INCLEANUP))
02261 cDying++;
02262
#endif
02263
continue;
02264 }
02265
02266 ptiAny = ptiT;
02267
02268
if (pti->
pcti->
fsWakeBits & QS_MOUSE) {
02269
if (ptiT->pcti->fsWakeMask & QS_MOUSE)
02270 ptiBestMouse = ptiT;
02271 }
02272
02273
if (pti->
pcti->
fsWakeBits & QS_KEY) {
02274
if (ptiT->pcti->fsWakeMask & QS_KEY)
02275 ptiBestKey = ptiT;
02276 }
02277 }
02278
02279
if (ptiBestMouse ==
NULL)
02280 ptiBestMouse = ptiAny;
02281
if (ptiBestKey ==
NULL)
02282 ptiBestKey = ptiAny;
02283
02284
02285
02286
02287
02288
02289
02290
02291
if (ptiBestMouse !=
NULL)
02292
SetWakeBit(ptiBestMouse, pti->
pcti->
fsWakeBits & QS_MOUSE);
02293
if (ptiBestKey !=
NULL)
02294
SetWakeBit(ptiBestKey, pti->
pcti->
fsWakeBits & QS_KEY);
02295
02296
if (pq->
ptiKeyboard == pti)
02297 pq->
ptiKeyboard = ptiBestKey;
02298
02299
if (pq->
ptiMouse == pti)
02300 pq->
ptiMouse = ptiBestMouse;
02301
02302
#if DBG
02303
02304
02305
02306
if (pq->
cThreads != cDying && (pq->
ptiKeyboard ==
NULL || pq->
ptiMouse ==
NULL)) {
02307 RIPMSG6(RIP_ERROR,
02308
"pq %#p pq->cThreads %x cDying %x pti %#p ptiK %#p ptiM %#p",
02309 pq, pq->
cThreads, cDying, pti, pq->
ptiKeyboard, pq->
ptiMouse);
02310 }
02311
#endif
02312
}
02313
02314
return;
02315 }
02316
02317
02318
02319
02320
02321
UnlockCaptureWindow(pq);
02322
Unlock(&pq->
spwndFocus);
02323
Unlock(&pq->
spwndActive);
02324
Unlock(&pq->
spwndActivePrev);
02325
Unlock(&pq->
caret.
spwnd);
02326
LockQCursor(pq,
NULL);
02327
02328
#if DBG
02329
02330
02331
02332
02333
02334
02335
02336 pq->
QF_flags |=
QF_INDESTROY;
02337
#endif
02338
02339
02340
02341
02342
FreeMessageList(&pq->
mlInput);
02343
02344
02345
02346
02347
02348
02349
if (
gpqForeground == pq) {
02350
gpqForeground =
NULL;
02351 }
02352
02353
if (
gpqForegroundPrev == pq) {
02354
gpqForegroundPrev =
NULL;
02355 }
02356
02357
if (
gpqCursor == pq) {
02358
gpqCursor =
NULL;
02359 fSetFMouseMoved =
TRUE;
02360 }
02361
02362
if (pq->
cLockCount == 0) {
02363
FreeQueue(pq);
02364 }
02365
02366
if (fSetFMouseMoved) {
02367
zzzSetFMouseMoved();
02368 }
02369
02370 }
02371
02372
02373
02374
02375
02376
02377
02378
02379
02380
02381
02382
02383
02384
02385 VOID UserDeleteW32Thread (PW32THREAD pW32Thread)
02386 {
02387
PTHREADINFO pti = (
PTHREADINFO)pW32Thread;
02388
02389 BEGIN_REENTERCRIT();
02390
02391
02392
02393
02394
if (pW32Thread->RefCount == 0) {
02395
02396
02397
02398
02399
if (pti->
pEventQueueServer !=
NULL) {
02400
ObDereferenceObject(pti->
pEventQueueServer);
02401 }
02402
if (pti->
apEvent !=
NULL) {
02403 UserFreePool(pti->
apEvent);
02404 }
02405
02406
02407
02408
02409
if (pti->
pstrAppName !=
NULL) {
02410 UserFreePool(pti->
pstrAppName);
02411 }
02412
02413
02414
02415
02416
02417
if (pti->
pq !=
NULL) {
02418
02419 UserAssert(pti->
pq->
cLockCount);
02420 --(pti->
pq->
cLockCount);
02421
02422
if ((pti->
pq->
cLockCount == 0)
02423 && (pti->
pq->
cThreads == 0)) {
02424
FreeQueue(pti->
pq);
02425 }
02426
02427 }
02428
02429
02430
02431 UserAssert(pti->
pqAttach ==
NULL);
02432
#if 0
02433
if (pti->
pqAttach !=
NULL) {
02434
02435 UserAssert(pti->
pqAttach->
cLockCount);
02436 --(pti->
pqAttach->
cLockCount);
02437
02438
if ((pti->
pqAttach->
cLockCount == 0)
02439 && (pti->
pqAttach->
cThreads == 0)) {
02440
FreeQueue(pti->
pqAttach);
02441 }
02442
02443 }
02444
#endif
02445
02446
02447
02448
if (pti->
rpdesk !=
NULL) {
02449
UnlockDesktop(&pti->
rpdesk, LDU_PTI_DESK, (ULONG_PTR)pti);
02450 }
02451
02452
02453
02454
02455 InterlockedCompareExchangePointer(&pW32Thread->pEThread->Tcb.Win32Thread,
NULL, pW32Thread);
02456 Win32FreePool(pW32Thread);
02457 }
02458
02459 END_REENTERCRIT();
02460 }
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475 VOID UserDeleteW32Process(PW32PROCESS pW32Process)
02476 {
02477
PPROCESSINFO ppi = (
PPROCESSINFO)pW32Process;
02478
02479 BEGIN_REENTERCRIT();
02480
02481
02482
02483
02484
if (pW32Process->RefCount == 0) {
02485
02486
02487
02488
02489
02490
EnterHandleFlagsCrit();
02491
02492
02493
02494
02495
if (ppi->
bmHandleFlags.Buffer) {
02496 UserFreePool(ppi->
bmHandleFlags.Buffer);
02497
RtlInitializeBitMap(&ppi->
bmHandleFlags,
NULL, 0);
02498 }
02499
02500
02501
02502
02503 InterlockedCompareExchangePointer(&pW32Process->Process->Win32Process,
NULL, pW32Process);
02504 Win32FreePool(pW32Process);
02505
02506
02507
02508
02509
LeaveHandleFlagsCrit();
02510 }
02511
02512 END_REENTERCRIT();
02513 }
02514
02515
02516
02517
02518
02519
02520
02521 __inline
BOOL FLastGuiThread(
PTHREADINFO pti)
02522 {
02523
return (pti->
ppi &&
02524 pti->
ppi->
ptiList == pti &&
02525 pti->
ptiSibling ==
NULL);
02526 }
02527
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546
02547
02548
02549
02550
02551
02552 VOID xxxDestroyThreadInfo(VOID)
02553 {
02554
PTHREADINFO ptiCurrent;
02555
PTHREADINFO *ppti;
02556
02557 ptiCurrent =
PtiCurrent();
02558 UserAssert (ptiCurrent !=
NULL);
02559 UserAssert(
IsWinEventNotifyDeferredOK());
02560
02561
02562
02563
02564
if (
gptiBlockInput == ptiCurrent) {
02565
gptiBlockInput =
NULL;
02566 }
02567
02568
02569
02570
02571 ptiCurrent->
TIF_flags |= (
TIF_DONTATTACHQUEUE |
TIF_INCLEANUP);
02572
02573
02574
02575
02576
02577
PatchThreadWindows(ptiCurrent);
02578
02579
02580
02581
02582
02583
if (ptiCurrent->
pmsd !=
NULL) {
02584
xxxCancelTrackingForThread(ptiCurrent);
02585 }
02586
02587
02588
02589
02590
if (ptiCurrent->
pmsd !=
NULL) {
02591
Unlock(&ptiCurrent->
pmsd->
spwnd);
02592 UserFreePool(ptiCurrent->
pmsd);
02593 ptiCurrent->
pmsd =
NULL;
02594 }
02595
02596
02597
02598
02599 {
02600
PWINDOWSTATION pwinsta;
02601 pwinsta =
_GetProcessWindowStation(
NULL);
02602
if (pwinsta !=
NULL) {
02603
if (pwinsta->
ptiClipLock == ptiCurrent) {
02604
xxxCloseClipboard(pwinsta);
02605 }
02606
if (pwinsta->
ptiDrawingClipboard == ptiCurrent) {
02607 pwinsta->
ptiDrawingClipboard =
NULL;
02608 }
02609 }
02610 }
02611
02612
02613
02614
02615
while (ptiCurrent->
pMenuState !=
NULL) {
02616
PMENUSTATE pMenuState;
02617
PPOPUPMENU ppopupmenuRoot;
02618
02619 pMenuState = ptiCurrent->
pMenuState;
02620 ppopupmenuRoot = pMenuState->
pGlobalPopupMenu;
02621
02622
02623
02624
02625
if (ptiCurrent == pMenuState->
ptiMenuStateOwner) {
02626
02627
02628
02629
02630 pMenuState->
dwLockCount = 0;
02631
02632
02633
02634
02635
if (pMenuState->
fModelessMenu) {
02636
xxxEndMenuLoop(pMenuState, ppopupmenuRoot);
02637
xxxMNEndMenuState(
TRUE);
02638 }
else {
02639 pMenuState->
fInsideMenuLoop =
FALSE;
02640 ptiCurrent->
pq->
QF_flags &= ~
QF_CAPTURELOCKED;
02641
xxxMNCloseHierarchy(ppopupmenuRoot, pMenuState);
02642
xxxMNEndMenuState(ppopupmenuRoot->
fIsMenuBar || ppopupmenuRoot->
fDestroyed);
02643 }
02644 }
else {
02645
02646
02647
02648
02649
02650
02651
02652 UserAssert((ppopupmenuRoot->
spwndNotify !=
NULL)
02653 && (
GETPTI(ppopupmenuRoot->
spwndNotify) == ptiCurrent));
02654
02655
02656
02657
02658 UserAssert(pMenuState->
pmnsPrev ==
NULL);
02659
break;
02660 }
02661
02662 }
02663
02664
#if DBG
02665
02666
02667
02668
if ((ptiCurrent->
rpdesk !=
NULL) && (ptiCurrent->
rpdesk->
spwndMenu !=
NULL)) {
02669 UserAssert(ptiCurrent !=
GETPTI(ptiCurrent->
rpdesk->
spwndMenu));
02670 }
02671
#endif
02672
02673
02674
02675
02676
if (ptiCurrent->
pSBTrack) {
02677
Unlock(&ptiCurrent->
pSBTrack->
spwndSB);
02678
Unlock(&ptiCurrent->
pSBTrack->
spwndSBNotify);
02679
Unlock(&ptiCurrent->
pSBTrack->
spwndTrack);
02680 UserFreePool(ptiCurrent->
pSBTrack);
02681 ptiCurrent->
pSBTrack =
NULL;
02682 }
02683
02684
02685
02686
02687
02688
if (ptiCurrent->
ppi !=
NULL && ptiCurrent->
ppi->
ptiMainThread == ptiCurrent)
02689 ptiCurrent->
ppi->
ptiMainThread =
NULL;
02690
02691
while (ptiCurrent->
psiiList !=
NULL) {
02692
xxxDestroyThreadDDEObject(ptiCurrent, ptiCurrent->
psiiList);
02693 }
02694
02695
if (ptiCurrent->
TIF_flags &
TIF_PALETTEAWARE) {
02696
PWND pwnd;
02697
TL tlpwnd;
02698
02699 UserAssert(ptiCurrent->
rpdesk !=
NULL);
02700
02701 pwnd = ptiCurrent->
rpdesk->
pDeskInfo->
spwnd;
02702
02703
ThreadLock(pwnd, &tlpwnd);
02704
xxxFlushPalette(pwnd);
02705
ThreadUnlock(&tlpwnd);
02706 }
02707
02708
02709
02710
02711
02712
if (
FLastGuiThread(ptiCurrent) && (
gppiFullscreen == ptiCurrent->
ppi)) {
02713
xxxUserChangeDisplaySettings(
NULL,
NULL,
NULL,
NULL, 0, 0,
KernelMode);
02714
02715 UserAssert(
gppiFullscreen != ptiCurrent->
ppi);
02716 }
02717
02718
02719
02720
02721
02722
02723
02724
02725
02726
02727
02728
DestroyThreadsTimers(ptiCurrent);
02729
02730
02731
02732
02733
FreeThreadsWindowHooks();
02734
02735
02736
02737
02738 {
02739
PBWL pbwl, pbwlNext;
02740
for (pbwl =
gpbwlList; pbwl !=
NULL; ) {
02741 pbwlNext = pbwl->
pbwlNext;
02742
if (pbwl->
ptiOwner == ptiCurrent) {
02743
FreeHwndList(pbwl);
02744 }
02745 pbwl = pbwlNext;
02746 }
02747 }
02748
02749
02750
02751
02752
DestroyThreadsHotKeys();
02753
02754
DestroyThreadsObjects();
02755
02756
02757
02758
02759
02760
FreeThreadsWinEvents(ptiCurrent);
02761
02762
02763
02764
02765
Unlock(&ptiCurrent->
spklActive);
02766
02767
02768
02769
02770
02771
if (
gdwGuiThreads == 1) {
02772
CleanupResources();
02773 }
02774
02775
02776
if (
FLastGuiThread(ptiCurrent)) {
02777
02778
02779
02780
02781
if (ptiCurrent->
ppi->W32PF_Flags & W32PF_SETUPAPP) {
02782
PDESKTOPINFO pdeskinfo =
GETDESKINFO(ptiCurrent);
02783
if (pdeskinfo->
spwndShell) {
02784
_PostMessage(pdeskinfo->
spwndShell,
DTM_SETUPAPPRAN, 0, 0);
02785 }
02786 }
02787
02788
DestroyProcessesClasses(ptiCurrent->
ppi);
02789 ptiCurrent->
ppi->W32PF_Flags &= ~(W32PF_CLASSESREGISTERED);
02790
02791
02792
DestroyProcessesObjects(ptiCurrent->
ppi);
02793 }
02794
02795
#ifdef FE_IME
02796
02797
02798
02799
Unlock(&ptiCurrent->
spDefaultImc);
02800
#endif
02801
02802
if (ptiCurrent->
pq !=
NULL) {
02803
02804
02805
02806 ptiCurrent->
pq->
iCursorLevel -= ptiCurrent->
iCursorLevel;
02807
02808
02809
02810
02811
02812
if (ptiCurrent->
pq->
cThreads != 1)
02813 {
02814
gpdeskRecalcQueueAttach = ptiCurrent->
rpdesk;
02815
02816
02817
02818
02819 UserAssert(ptiCurrent->
TIF_flags &
TIF_INCLEANUP);
02820 UserAssert(
gbExitInProgress ==
FALSE);
02821
zzzSetFMouseMoved();
02822 }
02823 }
02824
02825
02826
02827
02828 ppti = &
PpiCurrent()->ptiList;
02829
if (*ppti !=
NULL) {
02830
while (*ppti != ptiCurrent && (*ppti)->
ptiSibling !=
NULL) {
02831 ppti = &((*ppti)->ptiSibling);
02832 }
02833
if (*ppti == ptiCurrent) {
02834 *ppti = ptiCurrent->
ptiSibling;
02835 ptiCurrent->
ptiSibling =
NULL;
02836 }
02837 }
02838
02839 {
02840
PDESKTOP rpdesk;
02841
PATTACHINFO *ppai;
02842
02843
02844
02845
02846
02847
02848
02849 rpdesk =
NULL;
02850
LockDesktop(&rpdesk, ptiCurrent->
rpdesk, LDL_FN_DESTROYTHREADINFO, (ULONG_PTR)
PtiCurrent());
02851
02852
02853
02854
02855
02856
02857
SendMsgCleanup(ptiCurrent);
02858
02859
02860
02861
02862
02863
if (ptiCurrent->
cEnterCount) {
02864 BOOLEAN
bool;
02865
02866 RIPMSG1(RIP_WARNING,
"Thread exiting with stack locked. pti:%#p\n", ptiCurrent);
02867
bool =
KeSetKernelStackSwapEnable(
TRUE);
02868 ptiCurrent->
cEnterCount = 0;
02869 UserAssert(!
bool);
02870 }
02871
02872
if (ptiCurrent->
ppi !=
NULL) {
02873 ptiCurrent->
ppi->
cThreads--;
02874 UserAssert(ptiCurrent->
ppi->
cThreads >= 0);
02875 }
02876
02877
02878
02879
02880
if (ptiCurrent->
TIF_flags &
TIF_16BIT) {
02881
if ((ptiCurrent->
ptdb) && (ptiCurrent->
ptdb->
hTaskWow != 0)) {
02882
_WOWCleanup(
NULL, ptiCurrent->
ptdb->
hTaskWow);
02883 }
02884
DestroyTask(ptiCurrent->
ppi, ptiCurrent);
02885 }
02886
02887
if (ptiCurrent->
hEventQueueClient !=
NULL) {
02888
ProtectHandle(ptiCurrent->
hEventQueueClient,
FALSE);
02889 ZwClose(ptiCurrent->
hEventQueueClient);
02890 ptiCurrent->
hEventQueueClient =
NULL;
02891 }
02892
02893
02894
if (
gspwndInternalCapture !=
NULL) {
02895
if (
GETPTI(
gspwndInternalCapture) == ptiCurrent) {
02896
Unlock(&
gspwndInternalCapture);
02897 }
02898 }
02899
02900
02901
02902
02903
02904
if (
gptiForeground == ptiCurrent) {
02905
if (
FWINABLE()) {
02906
02907
02908
02909
xxxWindowEvent(EVENT_OBJECT_FOCUS,
NULL, OBJID_CLIENT, INDEXID_CONTAINER,
WEF_ASYNC);
02910
xxxWindowEvent(EVENT_SYSTEM_FOREGROUND,
NULL, OBJID_WINDOW, INDEXID_CONTAINER,
WEF_ASYNC);
02911 }
02912
02913
02914
02915
02916
02917
02918 UserAssert(rpdesk !=
NULL);
02919
02920
if (rpdesk->
pDeskInfo->
spwndProgman)
02921
_PostMessage(rpdesk->
pDeskInfo->
spwndProgman,
guiActivateShellWindow, 0, 0);
02922
02923
02924
02925
02926
SetForegroundThread(
NULL);
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936
02937
02938
02939
02940
02941
02942
02943
02944 }
02945
02946
02947
02948
02949
02950
02951
if (ptiCurrent ==
glinp.
ptiLastWoken) {
02952 UserAssert(
PpiCurrent() == ptiCurrent->
ppi);
02953
if (ptiCurrent->
ppi->
ptiList !=
NULL) {
02954 UserAssert (ptiCurrent != ptiCurrent->
ppi->
ptiList);
02955
glinp.
ptiLastWoken = ptiCurrent->
ppi->
ptiList;
02956 }
else {
02957
glinp.
ptiLastWoken =
gptiForeground;
02958 }
02959 }
02960
02961
02962
02963
02964
if (
gptiShutdownNotify == ptiCurrent) {
02965
gptiShutdownNotify =
NULL;
02966 }
02967
if (
gptiTasklist == ptiCurrent) {
02968
gptiTasklist =
NULL;
02969 }
02970
if (
gHardErrorHandler.
pti == ptiCurrent) {
02971
gHardErrorHandler.
pti =
NULL;
02972 }
02973
02974
02975
02976
02977
02978
02979
02980
if (ptiCurrent->
pq !=
NULL) {
02981 UserAssert(ptiCurrent->
pq != ptiCurrent->
pqAttach);
02982
DestroyThreadsMessages(ptiCurrent->
pq, ptiCurrent);
02983 (ptiCurrent->
pq->
cLockCount)++;
02984
zzzDestroyQueue(ptiCurrent->
pq, ptiCurrent);
02985 }
02986
02987
02988
02989
02990 UserAssert(ptiCurrent->
pqAttach ==
NULL);
02991
#if 0
02992
if (ptiCurrent->
pqAttach !=
NULL) {
02993
DestroyThreadsMessages(ptiCurrent->
pqAttach, ptiCurrent);
02994 (ptiCurrent->
pqAttach->
cLockCount)++;
02995
zzzDestroyQueue(ptiCurrent->
pqAttach, ptiCurrent);
02996 }
02997
#endif
02998
02999
03000
03001
03002
if (ptiCurrent->
rpdesk !=
NULL) {
03003 RemoveEntryList(&ptiCurrent->
PtiLink);
03004 InitializeListHead(&ptiCurrent->
PtiLink);
03005 }
03006
03007
FreeMessageList(&ptiCurrent->
mlPost);
03008
03009
03010
03011
03012 ppai = &
gpai;
03013
while ((*ppai) !=
NULL) {
03014
if ((*ppai)->pti1 == ptiCurrent || (*ppai)->pti2 == ptiCurrent) {
03015
PATTACHINFO paiKill = *ppai;
03016 *ppai = (*ppai)->
paiNext;
03017 UserFreePool((HLOCAL)paiKill);
03018 }
else {
03019 ppai = &(*ppai)->
paiNext;
03020 }
03021 }
03022
03023
03024
03025
03026
03027
MarkThreadsObjects(ptiCurrent);
03028
03029
03030
03031
03032
if (rpdesk && ptiCurrent->
pcti !=
NULL && ptiCurrent->
pcti != &(ptiCurrent->
cti)) {
03033
DesktopFree(rpdesk, ptiCurrent->
pcti);
03034 ptiCurrent->
pcti = &(ptiCurrent->
cti);
03035 }
03036
03037
03038
03039
03040
if (ptiCurrent->
TIF_flags &
TIF_SYSTEMTHREAD && ptiCurrent->
pClientInfo !=
NULL) {
03041 UserFreePool(ptiCurrent->
pClientInfo);
03042 ptiCurrent->
pClientInfo =
NULL;
03043 }
03044
03045
03046
03047
03048
03049
UnlockDesktop(&rpdesk, LDU_FN_DESTROYTHREADINFO, (ULONG_PTR)
PtiCurrent());
03050 }
03051
03052
03053
03054
03055
gdwGuiThreads--;
03056 }
03057
03058
03059
03060
03061
03062
03063
03064
03065
03066
03067
03068 void CleanEventMessage(
03069
PQMSG pqmsg)
03070 {
03071
PASYNCSENDMSG pmsg;
03072
03073
03074
03075
03076
03077
switch (pqmsg->
dwQEvent) {
03078
case QEVENT_SETWINDOWPOS:
03079 UserFreePool((
PSMWP)pqmsg->
msg.wParam);
03080
break;
03081
03082
case QEVENT_UPDATEKEYSTATE:
03083 UserFreePool((
PBYTE)pqmsg->
msg.wParam);
03084
break;
03085
03086
case QEVENT_NOTIFYWINEVENT:
03087
DestroyNotify((
PNOTIFY)pqmsg->
msg.lParam);
03088
break;
03089
03090
case QEVENT_ASYNCSENDMSG:
03091 pmsg = (
PASYNCSENDMSG)pqmsg->
msg.wParam;
03092
UserDeleteAtom((ATOM)pmsg->
lParam);
03093 UserFreePool(pmsg);
03094
break;
03095 }
03096 }
03097
03098
03099
03100
03101
03102
03103
03104
03105
03106 VOID FreeMessageList(
03107
PMLIST pml)
03108 {
03109
PQMSG pqmsg;
03110
03111
DebugValidateMLIST(pml);
03112
03113
while ((pqmsg = pml->
pqmsgRead) !=
NULL) {
03114
CleanEventMessage(pqmsg);
03115
DelQEntry(pml, pqmsg);
03116 }
03117
03118
DebugValidateMLIST(pml);
03119 }
03120
03121
03122
03123
03124
03125
03126
03127
03128 VOID DestroyThreadsMessages(
03129
PQ pq,
03130
PTHREADINFO pti)
03131 {
03132
PQMSG pqmsg;
03133
PQMSG pqmsgNext;
03134
03135
DebugValidateMLIST(&pq->
mlInput);
03136
03137 pqmsg = pq->
mlInput.
pqmsgRead;
03138
while (pqmsg !=
NULL) {
03139 pqmsgNext = pqmsg->
pqmsgNext;
03140
if (pqmsg->
pti == pti) {
03141
03142
03143
03144
03145
if (pq->
idSysPeek == (ULONG_PTR)pqmsg) {
03146
CheckPtiSysPeek(8, pq, 0);
03147 pq->
idSysPeek = 0;
03148 }
03149
CleanEventMessage(pqmsg);
03150
DelQEntry(&pq->
mlInput, pqmsg);
03151 }
03152 pqmsg = pqmsgNext;
03153 }
03154
03155
DebugValidateMLIST(&pq->
mlInput);
03156 }
03157
03158
03159
03160
03161
03162
03163
03164
03165
03166
03167
03168
NTSTATUS
03169 InitQEntryLookaside()
03170 {
03171
QEntryLookaside = UserAllocPoolNonPaged(
sizeof(
PAGED_LOOKASIDE_LIST), TAG_LOOKASIDE);
03172
if (
QEntryLookaside ==
NULL) {
03173
return STATUS_NO_MEMORY;
03174 }
03175
03176
ExInitializePagedLookasideList(
QEntryLookaside,
03177
NULL,
03178
NULL,
03179
SESSION_POOL_MASK,
03180
sizeof(
QMSG),
03181 TAG_QMSG,
03182 16);
03183
03184
QLookaside = UserAllocPoolNonPaged(
sizeof(
PAGED_LOOKASIDE_LIST), TAG_LOOKASIDE);
03185
if (
QLookaside ==
NULL) {
03186
return STATUS_NO_MEMORY;
03187 }
03188
03189
ExInitializePagedLookasideList(
QLookaside,
03190
NULL,
03191
NULL,
03192
SESSION_POOL_MASK,
03193
sizeof(
Q),
03194 TAG_Q,
03195 16);
03196
return STATUS_SUCCESS;
03197 }
03198
03199
03200
03201
03202
03203
03204
03205
03206
03207
03208 PQMSG AllocQEntry(
03209
PMLIST pml)
03210 {
03211
PQMSG pqmsg;
03212
03213
DebugValidateMLIST(pml);
03214
03215
if (pml->
cMsgs >=
gUserPostMessageLimit) {
03216 RIPMSG3(RIP_WARNING,
"AllocQEntry: # of post messages exceeds the limit(%d) in pti=0x%p, pml=0x%p",
03217
gUserPostMessageLimit, W32GetCurrentThread(), pml);
03218
return NULL;
03219 }
03220
03221
03222
03223
03224
if ((pqmsg =
ExAllocateFromPagedLookasideList(
QEntryLookaside)) ==
NULL) {
03225
return NULL;
03226 }
03227
03228 RtlZeroMemory(pqmsg,
sizeof(*pqmsg));
03229
03230
if (pml->
pqmsgWriteLast !=
NULL) {
03231 pml->
pqmsgWriteLast->
pqmsgNext = pqmsg;
03232 pqmsg->
pqmsgPrev = pml->
pqmsgWriteLast;
03233 pml->
pqmsgWriteLast = pqmsg;
03234 }
else {
03235 pml->
pqmsgWriteLast = pml->
pqmsgRead = pqmsg;
03236 }
03237
03238 pml->
cMsgs++;
03239
03240
DebugValidateMLISTandQMSG(pml, pqmsg);
03241
03242
return pqmsg;
03243 }
03244
03245
03246
03247
03248
03249
03250
03251
03252
03253 void DelQEntry(
03254
PMLIST pml,
03255
PQMSG pqmsg)
03256 {
03257
DebugValidateMLISTandQMSG(pml, pqmsg);
03258 UserAssert((
int)pml->
cMsgs > 0);
03259 UserAssert(pml->
pqmsgRead);
03260 UserAssert(pml->
pqmsgWriteLast);
03261
03262
03263
03264
03265
if (pqmsg->
pqmsgPrev !=
NULL)
03266 pqmsg->
pqmsgPrev->
pqmsgNext = pqmsg->
pqmsgNext;
03267
03268
if (pqmsg->
pqmsgNext !=
NULL)
03269 pqmsg->
pqmsgNext->
pqmsgPrev = pqmsg->
pqmsgPrev;
03270
03271
03272
03273
03274
if (pml->
pqmsgRead == pqmsg)
03275 pml->
pqmsgRead = pqmsg->
pqmsgNext;
03276
03277
if (pml->
pqmsgWriteLast == pqmsg)
03278 pml->
pqmsgWriteLast = pqmsg->
pqmsgPrev;
03279
03280
03281
03282
03283 pml->
cMsgs--;
03284
03285
ExFreeToPagedLookasideList(
QEntryLookaside, pqmsg);
03286
03287
DebugValidateMLIST(pml);
03288 }
03289
03290
03291
03292
03293
03294
03295
03296
03297
03298
03299
03300
03301 void CheckRemoveHotkeyBit(
03302
PTHREADINFO pti,
03303
PMLIST pml)
03304 {
03305
PQMSG pqmsg;
03306
DWORD cHotkeys;
03307
03308
03309
03310
03311
03312 cHotkeys = 0;
03313
for (pqmsg = pml->
pqmsgRead; pqmsg !=
NULL; pqmsg = pqmsg->
pqmsgNext) {
03314
if (pqmsg->
msg.message == WM_HOTKEY)
03315 cHotkeys++;
03316 }
03317
03318
03319
03320
03321
if (cHotkeys <= 1) {
03322 pti->
pcti->
fsWakeBits &= ~QS_HOTKEY;
03323 pti->
pcti->
fsChangeBits &= ~QS_HOTKEY;
03324 }
03325 }
03326
03327
03328
03329
03330
03331
03332
03333
03334
03335
03336 PQMSG FindQMsg(
03337
PTHREADINFO pti,
03338
PMLIST pml,
03339
PWND pwndFilter,
03340 UINT msgMin,
03341 UINT msgMax,
03342 BOOL bProcessAck)
03343 {
03344
PWND pwnd;
03345
PQMSG pqmsgRead;
03346
PQMSG pqmsgRet =
NULL;
03347
UINT message;
03348
03349
DebugValidateMLIST(pml);
03350
03351 pqmsgRead = pml->
pqmsgRead;
03352
03353
while (pqmsgRead !=
NULL) {
03354
03355
03356
03357
03358
03359
03360 pwnd =
RevalidateHwnd(pqmsgRead->
msg.hwnd);
03361
03362
if (pwnd ==
NULL && pqmsgRead->
msg.hwnd !=
NULL) {
03363
03364
03365
03366
03367
03368
if (pqmsgRead->
msg.message == WM_HOTKEY) {
03369
CheckRemoveHotkeyBit(pti, pml);
03370 }
03371
03372
03373
03374
03375
03376
03377
03378
03379
03380
03381
03382
03383
if ((pti->
pq->
idSysLock == (ULONG_PTR)pqmsgRead)
03384 && (pti->
pq->
ptiSysLock == pti)) {
03385
03386 RIPMSG2(RIP_VERBOSE,
"FindQMsg: Unlocking queue:%#p. Msg:%#lx",
03387 pti->
pq, pqmsgRead->
msg.message);
03388 pti->
pq->
ptiSysLock =
NULL;
03389 }
03390
03391
DelQEntry(pml, pqmsgRead);
03392
goto nextMsgFromPml;
03393 }
03394
03395
03396
03397
03398
if (bProcessAck && (
PtoH(pwndFilter) == pqmsgRead->
msg.hwnd) &&
03399 (pqmsgRead->
msg.message == (WM_DDE_ACK |
MSGFLAG_DDE_MID_THUNK))) {
03400
03401
PXSTATE pxs;
03402
03403 pxs = (
PXSTATE)
HMValidateHandleNoRip((HANDLE)pqmsgRead->
msg.lParam,
TYPE_DDEXACT);
03404
03405
if (pxs !=
NULL && (pxs->
flags &
XS_FREEPXS)) {
03406
FreeDdeXact(pxs);
03407
DelQEntry(pml, pqmsgRead);
03408
goto nextMsgFromPml;
03409 }
03410 }
03411
03412
03413
03414
03415
03416
if (!
CheckPwndFilter(pwnd, pwndFilter))
03417
goto nextMsg;
03418
03419
03420
03421
03422
03423 message = pqmsgRead->
msg.message;
03424
if (
CheckMsgFilter(message,
03425 (WM_DDE_FIRST + 1) |
MSGFLAG_DDE_MID_THUNK,
03426 WM_DDE_LAST |
MSGFLAG_DDE_MID_THUNK)) {
03427 message = message & ~
MSGFLAG_DDE_MID_THUNK;
03428 }
03429
03430
if (!
CheckMsgFilter(message, msgMin, msgMax))
03431
goto nextMsg;
03432
03433
03434
03435
03436
03437
if (!bProcessAck) {
03438
DebugValidateMLIST(pml);
03439
return pqmsgRead;
03440 }
03441
03442
if (pqmsgRet ==
NULL) {
03443 pqmsgRet = pqmsgRead;
03444 }
03445 nextMsg:
03446 pqmsgRead = pqmsgRead->
pqmsgNext;
03447
continue;
03448
03449 nextMsgFromPml:
03450 pqmsgRead = pml->
pqmsgRead;
03451
continue;
03452 }
03453
03454
DebugValidateMLIST(pml);
03455
return pqmsgRet;
03456 }
03457
03458
03459
03460
03461
03462
03463
03464
03465
03466 BOOL CheckQuitMessage(
03467
PTHREADINFO pti,
03468 LPMSG lpMsg,
03469 BOOL fRemoveMsg)
03470 {
03471
03472
03473
03474
03475
if (pti->
cQuit != 0 && pti->
mlPost.
cMsgs == 0) {
03476
03477
03478
03479
03480
if (fRemoveMsg)
03481 pti->
cQuit = 0;
03482
StoreMessage(lpMsg,
NULL, WM_QUIT, (
DWORD)pti->
exitCode, 0, 0);
03483
return TRUE;
03484 }
03485
03486
return FALSE;
03487 }
03488
03489
03490
03491
03492
03493
03494
03495
03496
03497
03498
03499 BOOL xxxReadPostMessage(
03500
PTHREADINFO pti,
03501 LPMSG lpMsg,
03502
PWND pwndFilter,
03503 UINT msgMin,
03504 UINT msgMax,
03505 BOOL fRemoveMsg)
03506 {
03507
PQMSG pqmsg;
03508
PMLIST pmlPost;
03509
03510
03511
03512
03513
if (
CheckQuitMessage(pti, lpMsg, fRemoveMsg))
03514
return TRUE;
03515
03516
03517
03518
03519
03520 pmlPost = &pti->
mlPost;
03521 pqmsg =
FindQMsg(pti, pmlPost, pwndFilter, msgMin, msgMax,
FALSE);
03522
if (pqmsg ==
NULL) {
03523
03524
03525
03526
03527
03528
if (
CheckQuitMessage(pti, lpMsg, fRemoveMsg))
03529
return TRUE;
03530 }
else {
03531
03532
03533
03534 pti->
timeLast = pqmsg->
msg.time;
03535
if (!RtlEqualMemory(&pti->
ptLast, &pqmsg->
msg.pt,
sizeof(POINT))) {
03536 pti->
TIF_flags |=
TIF_MSGPOSCHANGED;
03537 }
03538 pti->
ptLast = pqmsg->
msg.pt;
03539
03540 pti->
idLast = (ULONG_PTR)pqmsg;
03541 pti->
pq->
ExtraInfo = pqmsg->
ExtraInfo;
03542
03543
03544
03545
03546
03547
03548 *lpMsg = pqmsg->
msg;
03549
if (!fRemoveMsg) {
03550 pti->
idLast = 1;
03551 }
else {
03552
03553
03554
03555
03556
03557
if (pmlPost->
pqmsgRead->
msg.message == WM_HOTKEY) {
03558
CheckRemoveHotkeyBit(pti, pmlPost);
03559 }
03560
03561
03562
03563
03564
03565
03566
03567
03568
if (pti->
TIF_flags &
TIF_SPINNING)
03569
CheckProcessForeground(pti);
03570
03571
DelQEntry(pmlPost, pqmsg);
03572 }
03573
03574
03575
03576
03577
if (
CheckMsgFilter(lpMsg->message,
03578 (WM_DDE_FIRST + 1) |
MSGFLAG_DDE_MID_THUNK,
03579 WM_DDE_LAST |
MSGFLAG_DDE_MID_THUNK)) {
03580
03581
03582
03583 lpMsg->message &= (
UINT)~
MSGFLAG_DDE_MID_THUNK;
03584
03585
03586
03587
03588
xxxDDETrackGetMessageHook(lpMsg);
03589
03590
03591
03592
03593
03594
03595
03596
if (!fRemoveMsg) {
03597
if (pqmsg ==
FindQMsg(pti, pmlPost, pwndFilter, msgMin, msgMax,
FALSE)) {
03598 pqmsg->
msg = *lpMsg;
03599 }
03600 }
03601 }
03602
#if DBG
03603
else if (
CheckMsgFilter(lpMsg->message, WM_DDE_FIRST, WM_DDE_LAST)) {
03604
if (fRemoveMsg) {
03605
TraceDdeMsg(lpMsg->message, (HWND)lpMsg->wParam, lpMsg->hwnd, MSG_RECV);
03606 }
else {
03607
TraceDdeMsg(lpMsg->message, (HWND)lpMsg->wParam, lpMsg->hwnd, MSG_PEEK);
03608 }
03609 }
03610
#endif
03611
}
03612
03613
03614
03615
03616
03617
if (pmlPost->
cMsgs == 0 && pti->
cQuit == 0) {
03618 pti->
pcti->
fsWakeBits &= ~(QS_POSTMESSAGE | QS_ALLPOSTMESSAGE);
03619 pti->
pcti->
fsChangeBits &= ~QS_ALLPOSTMESSAGE;
03620 }
03621
03622
return pqmsg !=
NULL;
03623 }
03624
03625
#ifdef HUNGAPP_GHOSTING
03626
03627
03628
03629
03630
03631
03632
03633
03634
03635
void xxxProcessHungThreadEvent(
PWND pwnd)
03636 {
03637
PTHREADINFO ptiCurrent =
PtiCurrent();
03638
PWND pwndGhost;
03639 HWND hwnd;
03640
TL tlpwndT1, tlpwndT2;
03641
03642
CheckLock(pwnd);
03643
03644
03645
03646
03647
03648
SET_TIME_LAST_READ(ptiCurrent);
03649
03650 pwndGhost = FindGhost(pwnd);
03651
03652
ThreadLockAlwaysWithPti(ptiCurrent, pwndGhost, &tlpwndT1);
03653
ThreadLockAlwaysWithPti(ptiCurrent, pwnd, &tlpwndT2);
03654
03655
if (pwndGhost !=
NULL) {
03656
PCHECKPOINT pcp, pcpGhost;
03657
03658
03659
03660
03661
03662
if (
TestWF(pwndGhost, WFMAXIMIZED)) {
03663
xxxMinMaximize(pwnd, SW_MAXIMIZE, MINMAX_KEEPHIDDEN);
03664 }
else if (
TestWF(pwndGhost, WFMINIMIZED)) {
03665
xxxMinMaximize(pwnd, SW_SHOWMINNOACTIVE, MINMAX_KEEPHIDDEN);
03666 }
else {
03667
DWORD dwFlags;
03668
PTHREADINFO pti =
GETPTI(pwndGhost);
03669
03670
03671
03672
03673
03674
if (pti->
pq ==
gpqForeground && pti->
pq->
spwndActive == pwndGhost) {
03675
dwFlags = 0;
03676
GETPTI(pwnd)->TIF_flags |=
TIF_ALLOWFOREGROUNDACTIVATE;
03677 }
else {
03678
dwFlags = SWP_NOACTIVATE;
03679 }
03680
03681
03682
03683
03684
03685
xxxSetWindowPos(pwnd, pwndGhost,
03686 pwndGhost->
rcWindow.left, pwndGhost->
rcWindow.top,
03687 pwndGhost->
rcWindow.right - pwndGhost->
rcWindow.left,
03688 pwndGhost->
rcWindow.bottom - pwndGhost->
rcWindow.top,
03689 dwFlags);
03690 }
03691
03692
03693
03694
03695
03696
if ((pcpGhost = (
PCHECKPOINT)
_GetProp(pwndGhost,
03697 PROP_CHECKPOINT, PROPF_INTERNAL)) !=
NULL) {
03698
03699
if ((pcp = (
PCHECKPOINT)
_GetProp(pwnd,
03700 PROP_CHECKPOINT, PROPF_INTERNAL)) ==
NULL) {
03701 pcp =
CkptRestore(pwnd, &pwnd->
rcWindow);
03702 }
03703
03704
if (pcp !=
NULL) {
03705 RtlCopyMemory(pcp, pcpGhost,
sizeof(
CHECKPOINT));
03706 }
03707 }
03708 }
03709
03710
03711
03712
03713
03714
SetVisible(pwnd, SV_SET);
03715 RemoveGhost(pwnd);
03716
03717
03718
03719
03720 hwnd =
PtoHq(pwnd);
03721
PostShellHookMessages(HSHELL_WINDOWCREATED, (LPARAM)hwnd);
03722
xxxCallHook(HSHELL_WINDOWCREATED, (WPARAM)hwnd, (LPARAM)0, WH_SHELL);
03723
03724
03725
03726
03727
xxxRedrawWindow(pwnd, NULL, NULL, RDW_INVALIDATE | RDW_ERASE |
03728 RDW_ALLCHILDREN | RDW_FRAME);
03729
03730
ThreadUnlock(&tlpwndT2);
03731
ThreadUnlock(&tlpwndT1);
03732 }
03733
03734
#else // HUNGAPP_GHOSTING
03735
03736 void xxxProcessHungThreadEvent(
PWND pwnd)
03737 {
03738
CheckLock(pwnd);
03739
03740
if (
TestWF(pwnd,
WFVISIBLE)) {
03741 RIPMSG0(RIP_WARNING,
"xxxProcessHungThreadEvent: window is already visible");
03742 }
else {
03743
SetVisible(pwnd,
SV_SET);
03744
03745
if (
TestWF(pwnd,
WFMINIMIZED)) {
03746 RIPMSG0(RIP_WARNING,
"xxxProcessHungThreadEvent: window is already minmized");
03747 }
else {
03748
xxxMinMaximize(pwnd, SW_SHOWMINNOACTIVE,
MINMAX_KEEPHIDDEN);
03749 }
03750 }
03751 }
03752
03753
#endif // HUNGAPP_GHOSTING
03754
03755 BEEPPROC pfnBP[] = {
03756
UpSiren,
03757
DownSiren,
03758
LowBeep,
03759
HighBeep,
03760
KeyClick};
03761
03762
03763
03764
03765
03766
03767
03768
03769
03770
03771
03772 VOID xxxProcessEventMessage(
03773
PTHREADINFO ptiCurrent,
03774
PQMSG pqmsg)
03775 {
03776
PWND pwnd;
03777
TL tlpwndT;
03778
TL tlMsg;
03779
PQ pq;
03780
03781 UserAssert(
IsWinEventNotifyDeferredOK());
03782 UserAssert(ptiCurrent ==
PtiCurrent());
03783
03784
ThreadLockPoolCleanup(ptiCurrent, pqmsg, &tlMsg,
CleanEventMessage);
03785
03786 pq = ptiCurrent->
pq;
03787
switch (pqmsg->
dwQEvent) {
03788
case QEVENT_DESTROYWINDOW:
03789
03790
03791
03792
03793
03794 pwnd =
RevalidateHwnd((HWND)pqmsg->
msg.wParam);
03795
if (pwnd !=
NULL) {
03796
if (!
TestWF(pwnd,
WFCHILD))
03797
xxxDestroyWindow(pwnd);
03798
else {
03799
ThreadLockAlwaysWithPti(ptiCurrent, pwnd, &tlpwndT);
03800
xxxFreeWindow(pwnd, &tlpwndT);
03801 }
03802 }
03803
break;
03804
03805
case QEVENT_SHOWWINDOW:
03806
03807
03808
03809
03810
03811
03812
03813
03814 pwnd =
RevalidateHwnd((HWND)pqmsg->
msg.wParam);
03815
if (pwnd !=
NULL && !
TestWF(pwnd,
WFINDESTROY)) {
03816
ThreadLockAlwaysWithPti(ptiCurrent, pwnd, &tlpwndT);
03817
xxxShowWindow(pwnd, (
DWORD)pqmsg->
msg.lParam);
03818
03819
03820
03821
03822
if ((pqmsg->
msg.message & WPF_ASYNCWINDOWPLACEMENT)
03823 &&
TestWF(pwnd,
WFMINIMIZED)) {
03824
03825
WPUpdateCheckPointSettings(pwnd, (
UINT)pqmsg->
msg.message);
03826 }
03827
ThreadUnlock(&tlpwndT);
03828 }
03829
break;
03830
03831
case QEVENT_NOTIFYWINEVENT:
03832 UserAssert(((
PNOTIFY)pqmsg->
msg.lParam)->dwWEFlags &
WEF_POSTED);
03833 UserAssert(((
PNOTIFY)pqmsg->
msg.lParam)->dwWEFlags &
WEF_ASYNC);
03834
xxxProcessNotifyWinEvent((
PNOTIFY)pqmsg->
msg.lParam);
03835
break;
03836
03837
case QEVENT_SETWINDOWPOS:
03838
03839
03840
03841
03842
03843
03844
03845
xxxProcessSetWindowPosEvent((
PSMWP)pqmsg->
msg.wParam);
03846
break;
03847
03848
case QEVENT_UPDATEKEYSTATE:
03849
03850
03851
03852
03853
03854
ProcessUpdateKeyStateEvent(pq, (
PBYTE)pqmsg->
msg.wParam, (
PBYTE)pqmsg->
msg.wParam +
CBKEYSTATE);
03855
break;
03856
03857
case QEVENT_ACTIVATE:
03858 {
03859
if (pqmsg->
msg.lParam == 0) {
03860
03861
03862
03863
03864
03865
03866
03867
xxxCancelTracking();
03868
03869
03870
03871
03872
03873
03874
zzzClipCursor(
NULL);
03875
LockWindowUpdate2(
NULL,
TRUE);
03876
03877
03878
03879
03880 pq = ptiCurrent->
pq;
03881
03882
03883
03884
03885
03886
03887
03888
03889
if ((pqmsg->
msg.wParam != 0) && (pq->
spwndActive !=
NULL) &&
03890 (pq ==
gpqForeground)) {
03891
PWND pwndActive;
03892
03893
ThreadLockAlwaysWithPti(ptiCurrent, pwndActive = pq->
spwndActive, &tlpwndT);
03894
xxxSendMessage(pwndActive, WM_NCACTIVATE,
TRUE, 0);
03895
xxxUpdateTray(pwndActive);
03896
xxxSetWindowPos(pwndActive,
PWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
03897
ThreadUnlock(&tlpwndT);
03898 }
else if (pq !=
gpqForeground) {
03899
03900
03901
03902
03903 ptiCurrent->
TIF_flags &= ~
TIF_ALLOWFOREGROUNDACTIVATE;
03904 TAGMSG1(DBGTAG_FOREGROUND,
"xxxProcessEventMessage clear TIF %#p", ptiCurrent);
03905 ptiCurrent->
ppi->W32PF_Flags &= ~W32PF_ALLOWFOREGROUNDACTIVATE;
03906 TAGMSG1(DBGTAG_FOREGROUND,
"xxxProcessEventMessage clear W32PF %#p", ptiCurrent->
ppi);
03907 }
03908
03909 }
else {
03910
03911 pwnd =
RevalidateHwnd((HWND)pqmsg->
msg.lParam);
03912
if (pwnd ==
NULL)
03913
break;
03914
03915
ThreadLockAlwaysWithPti(ptiCurrent, pwnd, &tlpwndT);
03916
03917
03918
03919
03920
if (
gpqForeground ==
NULL) {
03921
xxxSetForegroundWindow2(pwnd, ptiCurrent, 0);
03922 }
else {
03923
if (pwnd != pq->
spwndActive) {
03924
if (
xxxActivateThisWindow(pwnd, (
UINT)pqmsg->
msg.wParam,
03925 (
ATW_SETFOCUS |
ATW_ASYNC) |
03926 ((pqmsg->
msg.message &
PEM_ACTIVATE_NOZORDER) ?
ATW_NOZORDER : 0))) {
03927
03928
03929
03930
03931
03932
03933
if (
TestUP(ACTIVEWINDOWTRACKING)) {
03934
zzzActiveCursorTracking(pwnd);
03935 }
03936 }
03937 }
else {
03938
BOOL fActive = (
GETPTI(pwnd)->pq ==
gpqForeground);
03939
03940
xxxSendMessage(pwnd, WM_NCACTIVATE,
03941 (
DWORD)(fActive), 0);
03942
if (fActive) {
03943
xxxUpdateTray(pwnd);
03944 }
03945
03946
03947
03948
03949
if (fActive && !(pqmsg->
msg.message &
PEM_ACTIVATE_NOZORDER))
03950
xxxSetWindowPos(pwnd,
PWND_TOP, 0, 0, 0, 0,
03951 SWP_NOSIZE | SWP_NOMOVE);
03952 }
03953 }
03954
03955
03956
03957
03958
03959
03960
03961
03962
if (pqmsg->
msg.message &
PEM_ACTIVATE_RESTORE) {
03963
if (
TestWF(pwnd,
WFMINIMIZED)) {
03964
_PostMessage(pwnd, WM_SYSCOMMAND, SC_RESTORE, 0);
03965 }
03966 }
03967
03968
ThreadUnlock(&tlpwndT);
03969 }
03970
03971 }
03972
break;
03973
03974
case QEVENT_DEACTIVATE:
03975
xxxDeactivate(ptiCurrent, (
DWORD)pqmsg->
msg.wParam);
03976
break;
03977
03978
case QEVENT_CANCELMODE:
03979
if (pq->
spwndCapture !=
NULL) {
03980
ThreadLockAlwaysWithPti(ptiCurrent, pq->
spwndCapture, &tlpwndT);
03981
xxxSendMessage(pq->
spwndCapture, WM_CANCELMODE, 0, 0);
03982
ThreadUnlock(&tlpwndT);
03983
03984
03985
03986
03987
03988
03989
SetWakeBit(ptiCurrent, QS_MOUSEMOVE);
03990 }
03991
break;
03992
03993
03994
case QEVENT_POSTMESSAGE:
03995
03996
03997
03998
03999
04000
04001
04002
04003
04004
04005
04006
if (pwnd =
RevalidateHwnd((HWND)pqmsg->
msg.hwnd)) {
04007
04008
_PostMessage(pwnd,pqmsg->
msg.message,pqmsg->
msg.wParam,pqmsg->
msg.lParam);
04009 }
04010
break;
04011
04012
04013
case QEVENT_ASYNCSENDMSG:
04014
xxxProcessAsyncSendMessage((
PASYNCSENDMSG)pqmsg->
msg.wParam);
04015
break;
04016
04017
case QEVENT_HUNGTHREAD:
04018 pwnd =
RevalidateHwnd((HWND)pqmsg->
msg.hwnd);
04019
if (pwnd !=
NULL) {
04020
ThreadLockAlwaysWithPti(ptiCurrent, pwnd, &tlpwndT);
04021
xxxProcessHungThreadEvent(pwnd);
04022
ThreadUnlock(&tlpwndT);
04023 }
04024
break;
04025
04026
case QEVENT_CANCELMOUSEMOVETRK: {
04027
04028
04029
04030
04031
PDESKTOP pdesk = ptiCurrent->
rpdesk;
04032 pwnd =
RevalidateHwnd((HWND)pqmsg->
msg.hwnd);
04033
04034
04035
04036
04037 UserAssert(!(pqmsg->
msg.message &
DF_TRACKMOUSELEAVE)
04038 || !(pdesk->
dwDTFlags &
DF_TRACKMOUSELEAVE)
04039 || (
PtoHq(pdesk->
spwndTrack) != pqmsg->
msg.hwnd)
04040 || !((pdesk->
htEx == HTCLIENT) ^ ((
int)pqmsg->
msg.wParam == HTCLIENT)));
04041
04042
04043
04044
if ((pdesk->
dwDTFlags &
DF_MOUSEMOVETRK)
04045 && (
PtoHq(pdesk->
spwndTrack) == pqmsg->
msg.hwnd)
04046 && (pdesk->
htEx == (
int)pqmsg->
msg.wParam)) {
04047
04048
04049
04050
break;
04051 }
04052
04053
04054
04055
if (pdesk->
dwDTFlags &
DF_TOOLTIPACTIVE) {
04056 pqmsg->
msg.lParam &= ~
DF_TOOLTIP;
04057 }
04058
04059
04060
04061
if (pwnd !=
NULL) {
04062
ThreadLockAlwaysWithPti(ptiCurrent, pwnd, &tlpwndT);
04063
xxxCancelMouseMoveTracking(pqmsg->
msg.message, pwnd,
04064 (
int)pqmsg->
msg.wParam,
04065 (
DWORD)pqmsg->
msg.lParam);
04066
ThreadUnlock(&tlpwndT);
04067 }
else if ((pqmsg->
msg.lParam &
DF_TOOLTIP)
04068 && (pqmsg->
msg.message &
DF_TOOLTIPSHOWING)) {
04069
04070
04071
04072
04073 pwnd = pdesk->
spwndTooltip;
04074
ThreadLockAlwaysWithPti(ptiCurrent, pwnd, &tlpwndT);
04075
xxxResetTooltip((
PTOOLTIPWND)pwnd);
04076
ThreadUnlock(&tlpwndT);
04077 }
04078 }
04079
break;
04080
04081
case QEVENT_RITACCESSIBILITY:
04082
if (
IsHooked(ptiCurrent,
WHF_SHELL)) {
04083
xxxCallHook((
UINT)pqmsg->
msg.wParam,
04084 (WPARAM)pqmsg->
msg.lParam,
04085 (LPARAM)0,
04086 WH_SHELL);
04087 }
04088
04089
PostShellHookMessages((
UINT)pqmsg->
msg.wParam, pqmsg->
msg.lParam);
04090
break;
04091
04092
case QEVENT_RITSOUND:
04093
04094
04095
04096
switch(pqmsg->
msg.message) {
04097
case RITSOUND_UPSIREN:
04098
case RITSOUND_DOWNSIREN:
04099
case RITSOUND_LOWBEEP:
04100
case RITSOUND_HIGHBEEP:
04101
case RITSOUND_KEYCLICK:
04102 (
pfnBP[pqmsg->
msg.message])();
04103
break;
04104
04105
case RITSOUND_DOBEEP:
04106
switch(pqmsg->
msg.wParam) {
04107
case RITSOUND_UPSIREN:
04108
case RITSOUND_DOWNSIREN:
04109
case RITSOUND_LOWBEEP:
04110
case RITSOUND_HIGHBEEP:
04111
case RITSOUND_KEYCLICK:
04112
DoBeep(
pfnBP[pqmsg->
msg.wParam], (
DWORD)pqmsg->
msg.lParam);
04113 }
04114
break;
04115 }
04116
break;
04117
04118
case QEVENT_APPCOMMAND: {
04119
04120
04121
04122
THREADINFO *ptiWindowOwner;
04123
int cmd;
04124
UINT keystate;
04125
04126
04127
04128
04129
04130
04131 UserAssert( pqmsg->
msg.lParam >= VK_APPCOMMAND_FIRST &&
04132 pqmsg->
msg.lParam <= VK_APPCOMMAND_LAST );
04133
04134
04135
04136
04137
04138
04139
04140 pwnd = ptiCurrent->
pq->
spwndFocus;
04141
if (!pwnd) {
04142 pwnd = ptiCurrent->
pq->
spwndActive;
04143
if (!pwnd ) {
04144
04145
04146
04147
04148
04149
break;
04150 }
04151 }
04152
04153
04154
04155
04156
04157 ptiWindowOwner =
GETPTI(pwnd);
04158
if (ptiCurrent != ptiWindowOwner) {
04159
04160
04161
04162
PostEventMessage(ptiWindowOwner, ptiWindowOwner->
pq,
QEVENT_APPCOMMAND,
04163
NULL, 0, (WPARAM)0, pqmsg->
msg.lParam);
04164
04165
04166
04167
04168
04169
break;
04170 }
04171
04172 cmd = APPCOMMAND_FIRST + ((
UINT)pqmsg->
msg.lParam - VK_APPCOMMAND_FIRST);
04173 keystate =
GetMouseKeyFlags(ptiWindowOwner->
pq);
04174 pqmsg->
msg.lParam = MAKELPARAM(keystate, cmd);
04175
04176
04177
04178
04179
04180
ThreadLockAlwaysWithPti(ptiCurrent, pwnd, &tlpwndT);
04181
xxxSendMessage(pwnd, WM_APPCOMMAND, (WPARAM)pwnd, pqmsg->
msg.lParam);
04182
ThreadUnlock(&tlpwndT);
04183
04184
break;
04185 }
04186
default:
04187 RIPMSG1(RIP_ERROR,
"xxxProcessEventMessage Bad pqmsg->dwQEvent:%#lx", pqmsg->
dwQEvent);
04188
break;
04189 }
04190
04191
ThreadUnlockPoolCleanup(ptiCurrent, &tlMsg);
04192 }
04193
04194
04195
04196
04197
04198
04199
04200
04201
04202
04203 #define QS_TEST_AND_CLEAR (QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_SENDMESSAGE)
04204 #define QS_TEST (QS_MOUSEBUTTON | QS_KEY)
04205
04206 BOOL _GetInputState(VOID)
04207 {
04208
if (LOWORD(
_GetQueueStatus(
QS_TEST_AND_CLEAR)) &
QS_TEST) {
04209
return TRUE;
04210 }
else {
04211
return FALSE;
04212 }
04213 }
04214
04215
#undef QS_TEST_AND_CLEAR
04216
#undef QS_TEST
04217
04218
04219
04220
04221
04222
04223
04224
04225
04226
04227
04228 DWORD _GetQueueStatus(
04229 UINT flags)
04230 {
04231
PTHREADINFO ptiCurrent;
04232
UINT fsChangeBits;
04233
04234 ptiCurrent =
PtiCurrentShared();
04235
04236 flags &= (QS_ALLINPUT | QS_ALLPOSTMESSAGE | QS_TRANSFER);
04237
04238 fsChangeBits = ptiCurrent->
pcti->
fsChangeBits;
04239
04240
04241
04242
04243
04244
04245 ptiCurrent->
pcti->
fsChangeBits &= ~flags;
04246
04247
04248
04249
04250
return MAKELONG(fsChangeBits & flags,
04251 (ptiCurrent->
pcti->
fsWakeBits | ptiCurrent->
pcti->
fsWakeBitsJournal) & flags);
04252 }
04253
04254
04255
04256
04257
04258
04259
04260
04261
04262
04263
04264
04265
04266
04267
#ifdef LOCK_MOUSE_CODE
04268
#pragma alloc_text(MOUSE, xxxMsgWaitForMultipleObjects)
04269
#endif
04270
04271 DWORD xxxMsgWaitForMultipleObjects(
04272 DWORD nCount,
04273 PVOID *apObjects,
04274
MSGWAITCALLBACK pfnNonMsg,
04275
PKWAIT_BLOCK WaitBlockArray)
04276 {
04277
PTHREADINFO ptiCurrent =
PtiCurrent();
04278
NTSTATUS Status;
04279
04280 ptiCurrent =
PtiCurrent();
04281 UserAssert(
IsWinEventNotifyDeferredOK());
04282
04283
04284
04285
04286
04287
ClearQueueServerEvent(QS_ALLINPUT | QS_EVENT);
04288
04289
04290
04291
04292
apObjects[nCount] = ptiCurrent->
pEventQueueServer;
04293
04294
04295
04296
04297
04298
if (!(ptiCurrent->
pcti->
fsChangeBits & QS_ALLINPUT)) {
04299
04300
04301
04302
04303
04304
if (ptiCurrent->
TIF_flags &
TIF_SPINNING) {
04305
CheckProcessForeground(ptiCurrent);
04306 }
04307 ptiCurrent->
pClientInfo->
cSpins = 0;
04308
04309
if (ptiCurrent ==
gptiForeground &&
04310
IsHooked(ptiCurrent,
WHF_FOREGROUNDIDLE)) {
04311
xxxCallHook(HC_ACTION, 0, 0, WH_FOREGROUNDIDLE);
04312 }
04313
04314
CheckForClientDeath();
04315
04316
04317
04318
04319
04320
zzzWakeInputIdle(ptiCurrent);
04321
04322 Again:
04323
LeaveCrit();
04324
04325
Status =
KeWaitForMultipleObjects(nCount + 1,
apObjects,
04326 WaitAny,
WrUserRequest,
04327
UserMode,
FALSE,
04328
NULL, WaitBlockArray);
04329
04330
EnterCrit();
04331
04332
CheckForClientDeath();
04333
04334 UserAssert(
NT_SUCCESS(
Status));
04335
04336
04337
if ((
Status == STATUS_WAIT_0) && (pfnNonMsg !=
NULL)) {
04338
04339
04340
04341 pfnNonMsg(
DEVICE_TYPE_MOUSE);
04342
04343
04344
04345
04346
04347
04348 ptiCurrent->
pcti->
fsWakeMask = QS_ALLINPUT | QS_EVENT;
04349
goto Again;
04350 }
04351
04352
if (
Status == (
NTSTATUS)(STATUS_WAIT_0 + nCount)) {
04353
04354
04355
04356
04357
04358
SleepInputIdle(ptiCurrent);
04359 }
04360 }
else {
04361
Status = nCount;
04362 }
04363
04364
04365
04366
04367 ptiCurrent->
pcti->
fsWakeMask = 0;
04368
04369
return (
DWORD)
Status;
04370 }
04371
04372
04373
04374
04375
04376
04377
04378
04379
04380
04381
04382 BOOL xxxSleepThread(
04383 UINT fsWakeMask,
04384 DWORD Timeout,
04385 BOOL fInputIdle)
04386 {
04387
PTHREADINFO ptiCurrent;
04388 LARGE_INTEGER li, *pli;
04389
NTSTATUS status = STATUS_SUCCESS;
04390
BOOL fExclusive = fsWakeMask & QS_EXCLUSIVE;
04391 WORD fsWakeMaskSaved;
04392
04393 UserAssert(
IsWinEventNotifyDeferredOK());
04394
04395
if (fExclusive) {
04396
04397
04398
04399
04400 fsWakeMask = fsWakeMask & ~QS_EXCLUSIVE;
04401 }
04402
04403
if (Timeout) {
04404
04405
04406
04407
04408
04409 li.QuadPart = Int32x32To64(-10000, Timeout);
04410 pli = &li;
04411 }
else
04412 pli =
NULL;
04413
04414
CheckCritIn();
04415
04416 ptiCurrent =
PtiCurrent();
04417
04418 fsWakeMaskSaved = ptiCurrent->
pcti->
fsWakeMask;
04419
04420
while (
TRUE) {
04421
04422
04423
04424
04425
if (ptiCurrent->
pcti->
fsChangeBits & fsWakeMask) {
04426
04427
04428
04429
04430
04431
04432
04433 ptiCurrent->
pcti->
fsWakeMask = fsWakeMaskSaved;
04434
04435
04436
04437
04438
04439
SET_TIME_LAST_READ(ptiCurrent);
04440
return TRUE;
04441 }
04442
04443
04444
04445
04446
if (!fExclusive && ptiCurrent->
pcti->
fsWakeBits & QS_SENDMESSAGE) {
04447
xxxReceiveMessages(ptiCurrent);
04448
04449
04450
04451
04452 ptiCurrent->
pcti->
fsChangeBits |= (ptiCurrent->
pcti->
fsWakeBits & ptiCurrent->
fsChangeBitsRemoved);
04453 ptiCurrent->
fsChangeBitsRemoved = 0;
04454 }
04455
04456
04457
04458
04459
04460
if (ptiCurrent->
ppi->
cSysExpunge !=
gcSysExpunge) {
04461 ptiCurrent->
ppi->
cSysExpunge =
gcSysExpunge;
04462
if (ptiCurrent->
ppi->
dwhmodLibLoadedMask &
gdwSysExpungeMask)
04463
xxxDoSysExpunge(ptiCurrent);
04464 }
04465
04466
04467
04468
04469
04470
ClearQueueServerEvent((WORD)(fsWakeMask | (fExclusive ? 0 : QS_SENDMESSAGE)));
04471
04472
04473
04474
04475
if (status == STATUS_TIMEOUT) {
04476 RIPERR1(ERROR_TIMEOUT, RIP_VERBOSE,
"SleepThread: The timeout has expired %lX", Timeout);
04477
return FALSE;
04478 }
04479
04480
04481
04482
04483
04484
04485
if (status == STATUS_USER_APC) {
04486
ClientDeliverUserApc();
04487
return FALSE;
04488 }
04489
04490
04491
04492
04493
04494
if (
gPowerState.
pEvent == ptiCurrent->
pEventQueueServer) {
04495
if (
gPowerState.
fCritical) {
04496
return FALSE;
04497 }
04498 }
04499
04500 UserAssert(status == STATUS_SUCCESS);
04501
04502
04503
04504
04505
04506
04507
04508
04509
if (!(ptiCurrent->
pcti->
fsChangeBits & ptiCurrent->
pcti->
fsWakeMask)) {
04510
04511
04512
04513
04514
if (fInputIdle) {
04515
if (ptiCurrent->
TIF_flags &
TIF_SPINNING) {
04516
CheckProcessForeground(ptiCurrent);
04517 }
04518 ptiCurrent->
pClientInfo->
cSpins = 0;
04519 }
04520
04521
04522
if (!(ptiCurrent->
TIF_flags &
TIF_16BIT)) {
04523
if (fInputIdle && ptiCurrent ==
gptiForeground &&
04524
IsHooked(ptiCurrent,
WHF_FOREGROUNDIDLE)) {
04525
xxxCallHook(HC_ACTION, 0, 0, WH_FOREGROUNDIDLE);
04526 }
04527
04528
CheckForClientDeath();
04529
04530
04531
04532
04533
04534
if (fInputIdle)
04535
zzzWakeInputIdle(ptiCurrent);
04536
04537
xxxSleepTask(fInputIdle,
NULL);
04538
04539
LeaveCrit();
04540 status =
KeWaitForSingleObject(ptiCurrent->pEventQueueServer,
04541
WrUserRequest,
UserMode,
FALSE, pli);
04542
CheckForClientDeath();
04543
EnterCrit();
04544
04545
04546
04547
04548
04549
SleepInputIdle(ptiCurrent);
04550
04551
04552
04553
04554 }
else {
04555
if (fInputIdle)
04556
zzzWakeInputIdle(ptiCurrent);
04557
04558
xxxSleepTask(fInputIdle,
NULL);
04559 }
04560 }
04561 }
04562 }
04563
04564
04565
04566
04567
04568
04569
04570
04571
04572
04573
04574
04575
04576
04577
04578 VOID SetWakeBit(
04579
PTHREADINFO pti,
04580 UINT wWakeBit)
04581 {
04582
CheckCritIn();
04583
04584 UserAssert(pti);
04585
04586
04587
04588
04589
04590
if (wWakeBit & QS_MOUSE)
04591 pti->
pq->
ptiMouse = pti;
04592
04593
if (wWakeBit & QS_KEY)
04594 pti->
pq->
ptiKeyboard = pti;
04595
04596
04597
04598
04599
04600
04601 pti->
pcti->
fsWakeBits |= wWakeBit;
04602 pti->
pcti->
fsChangeBits |= wWakeBit;
04603
04604
04605
04606
04607
04608
if ((wWakeBit & QS_INPUT)
04609 && (pti->
ppi->W32PF_Flags & W32PF_IDLESCREENSAVER)) {
04610
if ((wWakeBit & QS_MOUSEMOVE)
04611 && (
gpsi->ptCursor.x ==
gptSSCursor.x)
04612 && (
gpsi->ptCursor.y ==
gptSSCursor.y)) {
04613
goto SkipScreenSaverStuff;
04614 }
04615
04616
04617
04618
04619
04620 pti->
ppi->W32PF_Flags &= ~W32PF_IDLESCREENSAVER;
04621
SetForegroundPriority(pti,
TRUE);
04622 }
04623
04624 SkipScreenSaverStuff:
04625
if (wWakeBit & pti->
pcti->
fsWakeMask) {
04626
04627
04628
04629
if (pti->
TIF_flags &
TIF_16BIT) {
04630 pti->
ptdb->
nEvents++;
04631
gpsi->nEvents++;
04632
WakeWowTask(pti);
04633 }
else {
04634
KeSetEvent(pti->
pEventQueueServer, 2,
FALSE);
04635 }
04636 }
04637 }
04638
04639
04640
04641
04642
04643
04644
04645
04646
04647
04648
04649 void TransferWakeBit(
04650
PTHREADINFO pti,
04651 UINT message)
04652 {
04653
PTHREADINFO ptiT;
04654
UINT fsMask;
04655
04656
04657
04658
04659
04660 fsMask =
CalcWakeMask(message, message, 0) & (QS_MOUSE | QS_KEY);
04661
04662
04663
04664
04665
04666
if (!(pti->
pcti->
fsWakeBits & fsMask)) {
04667
04668
04669
04670
04671
04672
if (fsMask & QS_KEY) {
04673 ptiT = pti->
pq->
ptiKeyboard;
04674 pti->
pq->
ptiKeyboard = pti;
04675 }
else {
04676 ptiT = pti->
pq->
ptiMouse;
04677 pti->
pq->
ptiMouse = pti;
04678 }
04679 ptiT->
pcti->
fsWakeBits &= ~fsMask;
04680
04681
04682
04683
04684
04685 pti->
pcti->
fsWakeBits |= fsMask;
04686 pti->
pcti->
fsChangeBits |= fsMask;
04687 }
04688 }
04689
04690
04691
04692
04693
04694
04695
04696
04697
04698
04699
04700 VOID ClearWakeBit(
04701
PTHREADINFO pti,
04702 UINT wWakeBit,
04703 BOOL fSysCheck)
04704 {
04705
04706
04707
04708
04709
04710
04711
04712
if (fSysCheck) {
04713
if (pti->
pq->
mlInput.
cMsgs != 0 ||
FJOURNALPLAYBACK())
04714
return;
04715
if (pti->
pq->
QF_flags &
QF_MOUSEMOVED)
04716 wWakeBit &= ~QS_MOUSEMOVE;
04717 }
04718
04719
04720
04721
04722 pti->
pcti->
fsWakeBits &= ~wWakeBit;
04723 }
04724
04725
04726
04727
04728
04729
04730
04731
04732
04733
04734
04735
04736
04737 PTHREADINFO PtiFromThreadId(
04738 DWORD dwThreadId)
04739 {
04740
PETHREAD pEThread;
04741
PTHREADINFO pti;
04742
04743
04744
04745
04746
04747
04748
04749
04750
if (!
NT_SUCCESS(
LockThreadByClientId((HANDLE)LongToHandle( dwThreadId ), &pEThread)))
04751
return NULL;
04752
04753
04754
04755
04756
04757
04758
04759
if (!
PsIsThreadTerminating(pEThread)) {
04760 pti =
PtiFromThread(pEThread);
04761 }
else {
04762 pti =
NULL;
04763 }
04764
04765
04766
04767
04768
if (pti !=
NULL) {
04769
try {
04770
if (pti->pEThread->Cid.UniqueThread != (HANDLE)LongToHandle( dwThreadId )) {
04771 pti =
NULL;
04772 }
else if (!(pti->
TIF_flags &
TIF_GUITHREADINITIALIZED)) {
04773 RIPMSG1(RIP_WARNING,
"PtiFromThreadId: pti %#p not initialized", pti);
04774 pti =
NULL;
04775 }
else if (pti->
TIF_flags &
TIF_INCLEANUP) {
04776 RIPMSG1(RIP_WARNING,
"PtiFromThreadId: pti %#p in cleanup", pti);
04777 pti =
NULL;
04778 }
04779 } except (W32ExceptionHandler(
FALSE, RIP_WARNING)) {
04780 pti =
NULL;
04781 }
04782 }
04783
04784
UnlockThread(pEThread);
04785
04786
return pti;
04787 }
04788
04789
04790
04791
04792
04793
04794
04795
04796
04797
04798
04799 void StoreMessage(
04800 LPMSG pmsg,
04801
PWND pwnd,
04802 UINT message,
04803 WPARAM wParam,
04804 LPARAM lParam,
04805 DWORD time)
04806 {
04807
CheckCritIn();
04808
04809 pmsg->hwnd =
HW(pwnd);
04810 pmsg->message = message;
04811 pmsg->wParam = wParam;
04812 pmsg->lParam = lParam;
04813 pmsg->time = (time != 0 ? time :
NtGetTickCount());
04814
04815 pmsg->pt =
gpsi->ptCursor;
04816 }
04817
04818
04819
04820
04821
04822
04823
04824
04825
04826
04827
04828
04829
04830
04831 void StoreQMessage(
04832
PQMSG pqmsg,
04833
PWND pwnd,
04834 UINT message,
04835 WPARAM wParam,
04836 LPARAM lParam,
04837 DWORD time,
04838 DWORD dwQEvent,
04839 ULONG_PTR dwExtraInfo)
04840 {
04841
CheckCritIn();
04842
04843 pqmsg->
msg.hwnd =
HW(pwnd);
04844 pqmsg->
msg.message = message;
04845 pqmsg->
msg.wParam = wParam;
04846 pqmsg->
msg.lParam = lParam;
04847 pqmsg->
msg.time = (time == 0) ?
NtGetTickCount() : time;
04848
04849
#ifdef REDIRECTION
04850
if (message >= WM_MOUSEFIRST && message <= WM_MOUSELAST) {
04851 pqmsg->
msg.pt.x = LOWORD(lParam);
04852 pqmsg->
msg.pt.y = HIWORD(lParam);
04853 }
else {
04854 pqmsg->
msg.pt =
gpsi->ptCursor;
04855 }
04856
#else
04857
pqmsg->
msg.pt =
gpsi->ptCursor;
04858
#endif
04859
pqmsg->
dwQEvent = dwQEvent;
04860 pqmsg->
ExtraInfo = dwExtraInfo;
04861 }
04862
04863
04864
04865
04866
04867
04868
04869
04870
04871
04872
04873
04874 NTSTATUS xxxInitProcessInfo(
04875 PW32PROCESS pwp)
04876 {
04877
PPROCESSINFO ppi = (
PPROCESSINFO)pwp;
04878
NTSTATUS Status;
04879
04880
CheckCritIn();
04881
04882
04883
04884
04885
if (pwp->W32PF_Flags & W32PF_PROCESSCONNECTED) {
04886
return STATUS_ALREADY_WIN32;
04887 }
04888 pwp->W32PF_Flags |= W32PF_PROCESSCONNECTED;
04889
04890
#if defined(_WIN64)
04891
04892
04893
04894
if (pwp->Process->Wow64Process) {
04895 pwp->W32PF_Flags |= W32PF_WOW64;
04896 }
04897
#endif
04898
04899
04900
04901
04902
04903 UserVerify(
xxxSetProcessInitState(pwp->Process, STARTF_FORCEOFFFEEDBACK));
04904
04905
04906
04907
04908
SetAppStarting(ppi);
04909
04910
04911
04912 ppi->
ppiNextRunning =
gppiList;
04913
gppiList = ppi;
04914
04915
04916
04917
04918
04919
04920
04921
04922
04923
04924
if (
TEST_PUDF(
PUDF_ALLOWFOREGROUNDACTIVATE) &&
CheckAllowForeground(pwp->Process)) {
04925 ppi->W32PF_Flags |= W32PF_ALLOWFOREGROUNDACTIVATE;
04926 }
04927 TAGMSG2(DBGTAG_FOREGROUND,
"xxxInitProcessInfo %s W32PF %#p",
04928 ((ppi->W32PF_Flags & W32PF_ALLOWFOREGROUNDACTIVATE) ?
"set" :
"NOT"),
04929 ppi);
04930
04931
04932
04933
04934
04935
04936
Status =
GetProcessLuid(
NULL, &ppi->luidSession);
04937 UserAssert(
NT_SUCCESS(
Status));
04938
04939
04940
04941
04942 ppi->cSysExpunge =
gcSysExpunge;
04943
04944
04945
04946
04947
04948 ppi->dwLpkEntryPoints = 0;
04949
04950
return STATUS_SUCCESS;
04951 }
04952
04953
04954
04955
04956
04957
04958
04959
04960
04961
04962
04963
04964
04965
04966
04967
04968
04969
04970
04971
04972
04973
04974
04975
04976 BOOL DestroyProcessInfo(
04977 PW32PROCESS pwp)
04978 {
04979
PPROCESSINFO ppi = (
PPROCESSINFO)pwp;
04980
PDESKTOPVIEW pdv, pdvNext;
04981
BOOL fHadThreads;
04982
PPUBOBJ ppo;
04983
04984
CheckCritIn();
04985
04986
04987
04988
04989
04990
04991
CLOSE_PSEUDO_EVENT(&pwp->InputIdleEvent);
04992
04993
04994
04995
04996
04997
04998
BEGINATOMICCHECK();
04999
DeferWinEventNotify();
05000
if (pwp->W32PF_Flags & W32PF_STARTGLASS) {
05001 pwp->W32PF_Flags &= ~W32PF_STARTGLASS;
05002
zzzCalcStartCursorHide(
NULL, 0);
05003 }
05004
05005
05006
05007
05008
EndDeferWinEventNotifyWithoutProcessing();
05009
ENDATOMICCHECK();
05010
05011
05012
05013
05014
if (!(pwp->W32PF_Flags & W32PF_PROCESSCONNECTED)) {
05015
return FALSE;
05016 }
05017
05018
05019
05020
05021
05022
05023
if ((ppi->W32PF_Flags & W32PF_IOWINSTA) &&
05024 !(ppi->W32PF_Flags & W32PF_CONSOLEAPPLICATION) &&
05025 (
gspwndLogonNotify !=
NULL) &&
05026 !(ppi->
rpwinsta->
dwWSF_Flags &
WSF_OPENLOCK)) {
05027
05028
PTHREADINFO pti =
GETPTI(
gspwndLogonNotify);
05029
PQMSG pqmsg;
05030
05031
if ((pqmsg =
AllocQEntry(&pti->
mlPost)) !=
NULL) {
05032
StoreQMessage(pqmsg,
gspwndLogonNotify, WM_LOGONNOTIFY,
05033 LOGON_PLAYEVENTSOUND,
USER_SOUND_CLOSE, 0, 0, 0);
05034
05035
SetWakeBit(pti, QS_POSTMESSAGE | QS_ALLPOSTMESSAGE);
05036 }
05037
05038 }
05039
05040
05041
05042
05043
05044
05045
if (
IsShellProcess(ppi)) {
05046
05047
05048
05049
05050
05051 ppi->
rpdeskStartup->
pDeskInfo->
ppiShellProcess =
NULL;
05052
05053
05054
05055
05056
if ((
gspwndLogonNotify !=
NULL) &&
05057 !(ppi->
rpwinsta->
dwWSF_Flags &
WSF_OPENLOCK)) {
05058
05059
PTHREADINFO pti =
GETPTI(
gspwndLogonNotify);
05060
PQMSG pqmsg;
05061
05062
if ((pqmsg =
AllocQEntry(&pti->
mlPost)) !=
NULL) {
05063
StoreQMessage(pqmsg,
gspwndLogonNotify, WM_LOGONNOTIFY,
05064 LOGON_RESTARTSHELL, ppi->Process->ExitStatus, 0, 0, 0);
05065
SetWakeBit(pti, QS_POSTMESSAGE | QS_ALLPOSTMESSAGE);
05066 }
05067 }
05068 }
05069
05070
if (ppi->
cThreads)
05071 RIPMSG1(RIP_ERROR,
"Disconnect with %d threads remaining\n", ppi->
cThreads);
05072
05073
05074
05075
05076
if (ppi->W32PF_Flags & W32PF_APPSTARTING) {
05077
05078
05079
05080
05081
05082
05083
05084
GiveForegroundActivateRight(ppi->Process->UniqueProcessId);
05085
ClearAppStarting(ppi);
05086 }
05087
05088
05089
05090
05091
REMOVE_FROM_LIST(
PROCESSINFO,
gppiList, ppi, ppiNextRunning);
05092
05093
05094
05095
05096
05097
05098 fHadThreads = ppi->W32PF_Flags & W32PF_THREADCONNECTED;
05099
if (fHadThreads) {
05100
05101
05102
05103
05104
05105
05106
if (ppi->W32PF_Flags & W32PF_OWNDCCLEANUP) {
05107
DelayedDestroyCacheDC();
05108 }
05109
05110
#if DBG
05111
{
05112
PHE pheT, pheMax;
05113
05114
05115
05116
05117
05118
05119 pheMax = &
gSharedInfo.
aheList[
giheLast];
05120
for (pheT =
gSharedInfo.
aheList; pheT <= pheMax; pheT++) {
05121
05122
05123
05124
05125 UserAssertMsg0(
05126 pheT->
bFlags &
HANDLEF_DESTROY ||
05127 !(
gahti[pheT->
bType].bObjectCreateFlags &
OCF_PROCESSOWNED) ||
05128 (
PPROCESSINFO)pheT->
pOwner != ppi,
05129
"We should have no process objects left for this process!");
05130 }
05131 }
05132
#endif
05133
}
05134
05135
if (pwp->UserHandleCount)
05136 RIPMSG1(RIP_ERROR,
"Disconnect with %d User handle objects remaining\n", pwp->UserHandleCount);
05137
05138
05139
05140
05141
for (ppo =
gpPublicObjectList;
05142 ppo !=
NULL;
05143 ppo = ppo->
next) {
05144
if (ppo->
pid == pwp->W32Pid) {
05145 ppo->
pid = OBJECT_OWNER_PUBLIC;
05146 }
05147 }
05148
05149
05150
if (
gppiScreenSaver == ppi) {
05151 UserAssert(ppi->W32PF_Flags & W32PF_SCREENSAVER);
05152
05153
gppiScreenSaver =
NULL;
05154 }
05155
05156
if (
gppiForegroundOld == ppi) {
05157
gppiForegroundOld =
NULL;
05158 }
05159
05160
UnlockWinSta(&ppi->
rpwinsta);
05161
UnlockDesktop(&ppi->
rpdeskStartup, LDU_PPI_DESKSTARTUP3, (ULONG_PTR)ppi);
05162
05163
05164
05165
05166
05167
if (ppi->hdeskStartup) {
05168 UserVerify(
NT_SUCCESS(
CloseProtectedHandle(ppi->hdeskStartup)));
05169 ppi->hdeskStartup =
NULL;
05170 }
05171
05172
05173
05174
05175 ppi->W32PF_Flags |= W32PF_TERMINATED;
05176
05177
05178
05179
05180
if (ppi->pwpi) {
05181
PWOWPROCESSINFO pwpi = ppi->pwpi;
05182
05183
ObDereferenceObject(pwpi->
pEventWowExec);
05184
05185
REMOVE_FROM_LIST(
WOWPROCESSINFO,
gpwpiFirstWow, pwpi, pwpiNext);
05186
05187 UserFreePool(pwpi);
05188 ppi->pwpi =
NULL;
05189 }
05190
05191
05192
05193
05194 pdv = ppi->pdvList;
05195
while (pdv) {
05196 pdvNext = pdv->
pdvNext;
05197 UserFreePool(pdv);
05198 pdv = pdvNext;
05199 }
05200 ppi->pdvList =
NULL;
05201
05202
05203
05204
05205
if (ppi ==
gppiInputProvider) {
05206
gppiInputProvider =
NULL;
05207 }
05208
05209
05210
05211
if (ppi ==
gppiLockSFW) {
05212
gppiLockSFW =
NULL;
05213 }
05214
05215
return fHadThreads;
05216 }
05217
05218
05219
05220
05221
05222
05223 VOID ClearWakeMask(VOID)
05224 {
05225
PtiCurrent()->pcti->fsWakeMask = 0;
05226 }
05227
05228
05229
05230
05231
05232
05233
05234
05235
05236
05237
05238 HANDLE
xxxGetInputEvent(
05239 DWORD dwWakeMask)
05240 {
05241
PTHREADINFO ptiCurrent;
05242 WORD wFlags = HIWORD(dwWakeMask);
05243 UserAssert(
IsWinEventNotifyDeferredOK());
05244
05245 ptiCurrent =
PtiCurrent();
05246
05247
05248
05249
05250
05251
05252
if (
GetInputBits(ptiCurrent->
pcti, LOWORD(dwWakeMask), (wFlags & MWMO_INPUTAVAILABLE))) {
05253
KeSetEvent(ptiCurrent->
pEventQueueServer, 2,
FALSE);
05254
return ptiCurrent->
hEventQueueClient;
05255 }
05256
05257
05258
05259
05260
if (ptiCurrent ==
gptiForeground &&
05261
IsHooked(ptiCurrent,
WHF_FOREGROUNDIDLE)) {
05262
xxxCallHook(HC_ACTION, 0, 0, WH_FOREGROUNDIDLE);
05263 }
05264
05265
CheckForClientDeath();
05266
05267
05268
05269
05270
05271
05272
05273
if (dwWakeMask & (QS_POSTMESSAGE | QS_INPUT)) {
05274 ptiCurrent->
ppi->
ptiMainThread = ptiCurrent;
05275 }
05276
05277
05278
05279
05280
05281
05282
zzzWakeInputIdle(ptiCurrent);
05283
05284
05285
05286
05287
ClearQueueServerEvent((WORD)(dwWakeMask | QS_EVENT));
05288
05289
05290
05291
05292 ptiCurrent->
pClientInfo->
cSpins = 0;
05293
if (ptiCurrent->
TIF_flags &
TIF_SPINNING) {
05294
CheckProcessForeground(ptiCurrent);
05295 }
05296
05297 UserAssert(ptiCurrent->
pcti->
fsWakeMask != 0);
05298
return ptiCurrent->
hEventQueueClient;
05299 }
05300
05301
05302
05303
05304
05305
05306
05307
05308
05309
05310 DWORD xxxWaitForInputIdle(
05311 ULONG_PTR idProcess,
05312 DWORD dwMilliseconds,
05313 BOOL fSharedWow)
05314 {
05315
PTHREADINFO ptiCurrent;
05316
PTHREADINFO pti;
05317
PEPROCESS Process;
05318 PW32PROCESS W32Process;
05319
PPROCESSINFO ppi;
05320
DWORD dwResult;
05321
NTSTATUS Status;
05322
TL tlProcess;
05323
05324 ptiCurrent =
PtiCurrent();
05325
05326
05327
05328
05329
05330
05331
05332
05333
05334
05335
if (fSharedWow) {
05336
PWOWTHREADINFO pwti;
05337
05338
05339
05340
05341
05342
for (pwti =
gpwtiFirst; pwti !=
NULL; pwti = pwti->
pwtiNext) {
05343
if (pwti->
idParentProcess == HandleToUlong(ptiCurrent->pEThread->Cid.UniqueProcess) &&
05344 pwti->
idWaitObject == idProcess) {
05345
break;
05346 }
05347 }
05348
05349
05350
05351
05352
if (pwti ==
NULL) {
05353 RIPMSG0(RIP_WARNING,
"WaitForInputIdle couldn't find 16-bit task\n");
05354
return (
DWORD)-1;
05355 }
05356
05357
05358
05359
05360 dwResult =
WaitOnPseudoEvent(&pwti->
pIdleEvent, dwMilliseconds);
05361
if (dwResult == STATUS_ABANDONED) {
05362 dwResult =
xxxPollAndWaitForSingleObject(pwti->
pIdleEvent,
05363
NULL,
05364 dwMilliseconds);
05365 }
05366
return dwResult;
05367
05368 }
05369
05370
05371
05372
05373 UserAssert(!(ptiCurrent->
TIF_flags &
TIF_SYSTEMTHREAD));
05374
05375
05376
05377
05378
if (ptiCurrent->pEThread->Cid.UniqueProcess == (HANDLE)idProcess &&
05379 ptiCurrent == ptiCurrent->
ppi->
ptiMainThread) {
05380 RIPMSG0(RIP_WARNING,
"WaitForInputIdle waiting on self\n");
05381
return (
DWORD)-1;
05382 }
05383
05384
05385
05386
05387
LeaveCrit();
05388
Status =
LockProcessByClientId((HANDLE)idProcess, &Process);
05389
EnterCrit();
05390
05391
if (!
NT_SUCCESS(
Status))
05392
return (
DWORD)-1;
05393
05394
if (Process->
ExitProcessCalled) {
05395
UnlockProcess(Process);
05396
return (
DWORD)-1;
05397 }
05398
05399 W32Process = (PW32PROCESS)Process->
Win32Process;
05400
05401
05402
05403
05404
if (W32Process ==
NULL) {
05405 RIPMSG0(RIP_WARNING,
"WaitForInputIdle process not GUI process\n");
05406
UnlockProcess(Process);
05407
return (
DWORD)-1;
05408 }
05409
05410
05411 ppi = (
PPROCESSINFO)W32Process;
05412
05413
05414
05415
05416
if (W32Process->W32PF_Flags & W32PF_CONSOLEAPPLICATION) {
05417 RIPMSG0(RIP_WARNING,
"WaitForInputIdle process is console process\n");
05418
UnlockProcess(Process);
05419
return (
DWORD)-1;
05420 }
05421
05422
05423
05424
05425
CheckForClientDeath();
05426
05427
05428
05429
05430 ppi->W32PF_Flags |= W32PF_WAITFORINPUTIDLE;
05431
for (pti = ppi->
ptiList; pti !=
NULL; pti = pti->
ptiSibling) {
05432 pti->
TIF_flags |=
TIF_WAITFORINPUTIDLE;
05433 }
05434
05435
05436
05437
05438
05439 LockW32Process(W32Process, &tlProcess);
05440
UnlockProcess(Process);
05441
05442 dwResult =
WaitOnPseudoEvent(&W32Process->InputIdleEvent, dwMilliseconds);
05443
if (dwResult == STATUS_ABANDONED) {
05444 dwResult =
xxxPollAndWaitForSingleObject(W32Process->InputIdleEvent,
05445 Process,
05446 dwMilliseconds);
05447 }
05448
05449
05450
05451
05452 ppi->W32PF_Flags &= ~W32PF_WAITFORINPUTIDLE;
05453
for (pti = ppi->
ptiList; pti !=
NULL; pti = pti->
ptiSibling) {
05454 pti->
TIF_flags &= ~
TIF_WAITFORINPUTIDLE;
05455 }
05456
05457 UnlockW32Process(&tlProcess);
05458
05459
return dwResult;
05460 }
05461
05462
05463 #define INTERMEDIATE_TIMEOUT (500) // 1/2 second
05464
05465
05466
05467
05468
05469
05470
05471
05472
05473
05474
05475
05476
05477
05478
05479
05480
05481 DWORD xxxPollAndWaitForSingleObject(
05482
PKEVENT pEvent,
05483 PVOID pExecObject,
05484 DWORD dwMilliseconds)
05485 {
05486
DWORD dwIntermediateMilliseconds, dwStartTickCount;
05487
PTHREADINFO ptiCurrent;
05488
UINT cEvent = 2;
05489
NTSTATUS Status = -1;
05490 LARGE_INTEGER li;
05491
TL tlEvent;
05492
05493 ptiCurrent =
PtiCurrent();
05494
05495
if (ptiCurrent->
apEvent ==
NULL) {
05496 ptiCurrent->
apEvent = UserAllocPoolNonPaged(
POLL_EVENT_CNT *
sizeof(
PKEVENT), TAG_EVENT);
05497
if (ptiCurrent->
apEvent ==
NULL)
05498
return (
DWORD)-1;
05499 }
05500
05501
05502
05503
05504
05505
05506
05507
05508
ThreadLockObject(pEvent, &tlEvent);
05509
05510
05511
05512
05513
05514
if (pExecObject) {
05515 cEvent++;
05516 }
05517
05518
05519
05520
05521
ClearQueueServerEvent(QS_SENDMESSAGE);
05522
05523
05524
05525
05526
05527
05528
05529
05530
05531
05532
05533
if (ptiCurrent->
TIF_flags &
TIF_16BIT) {
05534
xxxSleepTask(
FALSE,
HEVENT_REMOVEME);
05535
05536 }
05537
05538 dwStartTickCount =
NtGetTickCount();
05539
while (
TRUE) {
05540
if (dwMilliseconds >
INTERMEDIATE_TIMEOUT) {
05541 dwIntermediateMilliseconds =
INTERMEDIATE_TIMEOUT;
05542
05543
05544
05545
05546
05547
if (dwMilliseconds != INFINITE) {
05548
DWORD dwNewTickCount =
NtGetTickCount();
05549
DWORD dwDelta =
ComputePastTickDelta(dwNewTickCount, dwStartTickCount);
05550 dwStartTickCount = dwNewTickCount;
05551
if (dwDelta < dwMilliseconds) {
05552 dwMilliseconds -= dwDelta;
05553 }
else {
05554 dwMilliseconds = 0;
05555 }
05556 }
05557 }
else {
05558 dwIntermediateMilliseconds = dwMilliseconds;
05559 dwMilliseconds = 0;
05560 }
05561
05562
05563
05564
05565
05566
if (dwIntermediateMilliseconds != INFINITE)
05567 li.QuadPart = Int32x32To64(-10000, dwIntermediateMilliseconds);
05568
05569
05570
05571
05572
05573 ptiCurrent->
apEvent[
IEV_IDLE] = pEvent;
05574 ptiCurrent->
apEvent[
IEV_INPUT] = ptiCurrent->
pEventQueueServer;
05575 ptiCurrent->
apEvent[
IEV_EXEC] = pExecObject;
05576
05577
LeaveCrit();
05578
05579
Status =
KeWaitForMultipleObjects(cEvent,
05580 &ptiCurrent->
apEvent[
IEV_IDLE],
05581 WaitAny,
05582
WrUserRequest,
05583
UserMode,
05584
FALSE,
05585 (dwIntermediateMilliseconds == INFINITE ?
05586
NULL : &li),
05587
NULL);
05588
05589
EnterCrit();
05590
05591
if (!
NT_SUCCESS(
Status)) {
05592
Status = -1;
05593 }
else {
05594
05595
05596
05597
05598
05599
05600
if (
Status == STATUS_USER_APC) {
05601
ClientDeliverUserApc();
05602
Status = -1;
05603 }
05604 }
05605
05606
if (ptiCurrent->
pcti->
fsChangeBits & QS_SENDMESSAGE) {
05607
05608
05609
05610
05611
if (ptiCurrent->
TIF_flags &
TIF_16BIT) {
05612
xxxDirectedYield(DY_OLDYIELD);
05613 }
05614
05615
xxxReceiveMessages(ptiCurrent);
05616
05617
if (ptiCurrent->
TIF_flags &
TIF_16BIT) {
05618
xxxSleepTask(
FALSE,
HEVENT_REMOVEME);
05619
05620 }
05621 }
05622
05623
05624
05625
05626
05627
05628
if (
Status != STATUS_TIMEOUT &&
Status != 1)
05629
break;
05630
05631
if (dwMilliseconds == 0) {
05632
05633
05634
05635
if (
Status == 1)
05636
Status = WAIT_TIMEOUT;
05637
break;
05638 }
05639
05640 }
05641
05642
05643
05644
05645
if (ptiCurrent->
TIF_flags &
TIF_16BIT) {
05646
xxxDirectedYield(DY_OLDYIELD);
05647 }
05648
05649
05650
05651
05652
ThreadUnlockObject(&tlEvent);
05653
05654
return Status;
05655 }
05656
05657
05658
05659
05660
05661
05662
05663
05664
05665
05666
05667
05668
05669
05670
05671 DWORD WaitOnPseudoEvent(
05672 HANDLE *phE,
05673 DWORD dwMilliseconds)
05674 {
05675 HANDLE hEvent;
05676
NTSTATUS Status;
05677
05678
CheckCritIn();
05679
if (*phE ==
PSEUDO_EVENT_OFF) {
05680
if (!
NT_SUCCESS(ZwCreateEvent(&hEvent, EVENT_ALL_ACCESS,
NULL,
05681 NotificationEvent,
FALSE))) {
05682 UserAssert(!
"Could not create event on the fly.");
05683
if (dwMilliseconds != INFINITE) {
05684
return STATUS_TIMEOUT;
05685 }
else {
05686
return (
DWORD)-1;
05687 }
05688 }
05689
Status =
ObReferenceObjectByHandle(hEvent, EVENT_ALL_ACCESS, *
ExEventObjectType,
05690
KernelMode, phE,
NULL);
05691 ZwClose(hEvent);
05692
if (!
NT_SUCCESS(
Status))
05693
return (
DWORD)-1;
05694 }
else if (*phE ==
PSEUDO_EVENT_ON) {
05695
return STATUS_WAIT_0;
05696 }
05697
return(STATUS_ABANDONED);
05698 }
05699
05700
05701
05702
05703
05704
05705
05706
05707
05708
05709
05710
05711
05712
05713 NTSTATUS xxxSetCsrssThreadDesktop(
PDESKTOP pdesk, PDESKRESTOREDATA pdrdRestore)
05714 {
05715
PTHREADINFO ptiCurrent =
PtiCurrent();
05716
NTSTATUS Status = STATUS_SUCCESS;
05717 MSG
msg;
05718
05719
05720
05721
05722 UserAssert(
ISCSRSS());
05723 UserAssert(pdrdRestore);
05724 UserAssert(pdrdRestore->pdeskRestore ==
NULL);
05725
05726
if (pdesk->
dwDTFlags &
DF_DESTROYED) {
05727 RIPMSG1(RIP_WARNING,
"xxxSetCsrssThreadDesktop: pdesk 0x%x destroyed",
05728 pdesk);
05729
return STATUS_UNSUCCESSFUL;
05730 }
05731
05732
05733
05734
05735
05736 pdrdRestore->pdeskRestore = ptiCurrent->
rpdesk;
05737
05738
if (pdrdRestore->pdeskRestore !=
NULL) {
05739
Status =
ObReferenceObjectByPointer(pdrdRestore->pdeskRestore,
05740 MAXIMUM_ALLOWED,
05741 *
ExDesktopObjectType,
05742
KernelMode);
05743
05744
if (!
NT_SUCCESS(
Status)) {
05745 pdrdRestore->pdeskRestore =
NULL;
05746 pdrdRestore->hdeskNew =
NULL;
05747
return Status;
05748 }
05749
LogDesktop(pdrdRestore->pdeskRestore, LD_REF_FN_SETCSRSSTHREADDESKTOP,
TRUE, (ULONG_PTR)
PtiCurrent());
05750 }
05751
05752
Status =
ObOpenObjectByPointer(
05753 pdesk,
05754 0,
05755
NULL,
05756 EVENT_ALL_ACCESS,
05757
NULL,
05758
KernelMode,
05759 &(pdrdRestore->hdeskNew));
05760
05761
05762
if (!
NT_SUCCESS(
Status)) {
05763 RIPNTERR2(
Status, RIP_WARNING,
"SetCsrssThreadDesktop, can't open handle, pdesk %#p. Status: %#x", pdesk,
Status);
05764
if (pdrdRestore->pdeskRestore) {
05765
LogDesktop(pdrdRestore->pdeskRestore, LD_DEREF_FN_SETCSRSSTHREADDESKTOP1,
FALSE, (ULONG_PTR)
PtiCurrent());
05766
ObDereferenceObject(pdrdRestore->pdeskRestore);
05767 pdrdRestore->pdeskRestore =
NULL;
05768 }
05769 pdrdRestore->hdeskNew =
NULL;
05770
return Status;
05771 }
05772
05773
05774
05775
if (pdesk != ptiCurrent->
rpdesk) {
05776
05777
05778
05779
if (ptiCurrent->
rpdesk) {
05780
while (
xxxPeekMessage(&
msg,
NULL, 0, 0, PM_REMOVE | PM_NOYIELD))
05781
xxxDispatchMessage(&
msg);
05782 }
05783
05784
if (!
xxxSetThreadDesktop(
NULL, pdesk)) {
05785 RIPMSG1(RIP_WARNING,
"xxxSetCsrssThreadDesktop: xxxSetThreadDesktop(%#p) failed", pdesk);
05786
Status = STATUS_INVALID_HANDLE;
05787
05788
05789
05790
if (pdrdRestore->pdeskRestore !=
NULL) {
05791
LogDesktop(pdrdRestore->pdeskRestore, LD_DEREF_FN_SETCSRSSTHREADDESKTOP1,
FALSE, (ULONG_PTR)
PtiCurrent());
05792
ObDereferenceObject(pdrdRestore->pdeskRestore);
05793 pdrdRestore->pdeskRestore =
NULL;
05794 }
05795
CloseProtectedHandle(pdrdRestore->hdeskNew);
05796 pdrdRestore->hdeskNew =
NULL;
05797 }
05798 }
05799
05800 UserAssert(
NT_SUCCESS(
Status));
05801
return Status;
05802 }
05803
05804 NTSTATUS xxxRestoreCsrssThreadDesktop(PDESKRESTOREDATA pdrdRestore)
05805 {
05806
PTHREADINFO ptiCurrent =
PtiCurrent();
05807
NTSTATUS Status = STATUS_SUCCESS;
05808 MSG
msg;
05809
05810
05811
05812
05813 UserAssert(
ISCSRSS());
05814 UserAssert(pdrdRestore);
05815
05816
05817
05818
05819
if (pdrdRestore->pdeskRestore != ptiCurrent->
rpdesk) {
05820
05821
05822
05823
if (ptiCurrent->
rpdesk) {
05824
while (
xxxPeekMessage(&
msg,
NULL, 0, 0, PM_REMOVE | PM_NOYIELD))
05825
xxxDispatchMessage(&
msg);
05826 }
05827
05828
if (!
xxxSetThreadDesktop(
NULL, pdrdRestore->pdeskRestore)) {
05829 RIPMSG1(RIP_WARNING,
"xxxRestoreCsrssThreadDesktop: xxxRestoreThreadDesktop(%#p) failed", pdrdRestore->pdeskRestore);
05830
Status = STATUS_INVALID_HANDLE;
05831 }
05832 }
05833
05834
05835
05836
05837
05838
if (pdrdRestore->pdeskRestore !=
NULL) {
05839
LogDesktop(pdrdRestore->pdeskRestore, LD_DEREF_FN_SETCSRSSTHREADDESKTOP2,
FALSE, 0);
05840
ObDereferenceObject(pdrdRestore->pdeskRestore);
05841 pdrdRestore->pdeskRestore =
NULL;
05842 }
05843
05844
if(pdrdRestore->hdeskNew) {
05845
CloseProtectedHandle(pdrdRestore->hdeskNew);
05846 UserAssert(
NT_SUCCESS(
Status));
05847 pdrdRestore->hdeskNew =
NULL;
05848 }
05849
return Status;
05850 }
05851
05852
05853
05854
05855
05856
05857 ULONG
GetTaskName(
05858
PTHREADINFO pti,
05859 PWSTR Buffer,
05860 ULONG BufferLength)
05861 {
05862 ANSI_STRING strAppName;
05863 UNICODE_STRING strAppNameU;
05864
NTSTATUS Status;
05865 ULONG NameLength = 0;
05866
05867
if (pti ==
NULL) {
05868 *
Buffer = 0;
05869
return 0;
05870 }
05871
if (pti->
pstrAppName !=
NULL) {
05872 NameLength =
min(pti->
pstrAppName->Length +
sizeof(WCHAR), BufferLength);
05873 RtlCopyMemory(
Buffer, pti->
pstrAppName->Buffer, NameLength);
05874 }
else {
05875
RtlInitAnsiString(&strAppName, pti->pEThread->ThreadsProcess->ImageFileName);
05876
if (BufferLength <
sizeof(WCHAR))
05877 NameLength = (strAppName.Length + 1) *
sizeof(WCHAR);
05878
else {
05879 strAppNameU.Buffer =
Buffer;
05880 strAppNameU.MaximumLength = (
SHORT)BufferLength -
sizeof(WCHAR);
05881
Status =
RtlAnsiStringToUnicodeString(&strAppNameU, &strAppName,
05882
FALSE);
05883
if (
NT_SUCCESS(
Status))
05884 NameLength = strAppNameU.Length +
sizeof(WCHAR);
05885 }
05886 }
05887
Buffer[(NameLength /
sizeof(WCHAR)) - 1] = 0;
05888
05889
return NameLength;
05890 }
05891
05892
05893
05894
05895
05896
05897
05898
05899
05900
05901 NTSTATUS xxxQueryInformationThread(
05902 IN HANDLE hThread,
05903 IN USERTHREADINFOCLASS ThreadInfoClass,
05904 OUT PVOID ThreadInformation,
05905 IN ULONG ThreadInformationLength,
05906 OUT PULONG ReturnLength OPTIONAL)
05907 {
05908 PUSERTHREAD_SHUTDOWN_INFORMATION pShutdown;
05909 PUSERTHREAD_WOW_INFORMATION pWow;
05910
PETHREAD Thread;
05911
PTHREADINFO pti;
05912
NTSTATUS Status = STATUS_SUCCESS;
05913 ULONG LocalReturnLength = 0;
05914
DWORD dwClientFlags;
05915
05916 UNREFERENCED_PARAMETER(ThreadInformationLength);
05917
05918
05919
05920 UserAssert(
ISCSRSS());
05921
05922
Status =
ObReferenceObjectByHandle(hThread,
05923 THREAD_QUERY_INFORMATION,
05924 *
PsThreadType,
05925
UserMode,
05926 &Thread,
05927
NULL);
05928
if (!
NT_SUCCESS(
Status))
05929
return Status;
05930
05931 pti =
PtiFromThread(Thread);
05932
05933
switch (ThreadInfoClass) {
05934
case UserThreadShutdownInformation:
05935 LocalReturnLength =
sizeof(USERTHREAD_SHUTDOWN_INFORMATION);
05936 UserAssert(ThreadInformationLength ==
sizeof(USERTHREAD_SHUTDOWN_INFORMATION));
05937 pShutdown = ThreadInformation;
05938
05939
05940
05941
05942
05943 dwClientFlags = pShutdown->dwFlags;
05944 UserAssert(FIELD_OFFSET(USERTHREAD_SHUTDOWN_INFORMATION, drdRestore)
05945 == (
sizeof(USERTHREAD_SHUTDOWN_INFORMATION) -
sizeof(DESKRESTOREDATA)));
05946 RtlZeroMemory(pShutdown,
05947
sizeof(USERTHREAD_SHUTDOWN_INFORMATION) -
sizeof(DESKRESTOREDATA));
05948
05949
05950
05951
05952
05953
05954
if (pti !=
NULL && pti->
rpdesk !=
NULL &&
05955 !(pti->
rpdesk->
rpwinstaParent->
dwWSF_Flags &
WSF_NOIO))
05956 pShutdown->hwndDesktop =
HW(pti->
rpdesk->
pDeskInfo->
spwnd);
05957
05958
05959
05960
05961
05962
if (Thread->
Cid.UniqueProcess ==
gpidLogon) {
05963
05964
05965
05966 pShutdown->StatusShutdown =
SHUTDOWN_KNOWN_PROCESS;
05967 }
else if (pti ==
NULL || pti->
rpdesk ==
NULL) {
05968
05969
05970
05971
05972
05973 pShutdown->StatusShutdown =
SHUTDOWN_UNKNOWN_PROCESS;
05974 }
05975
05976
05977
05978
05979
if (pti !=
NULL && pti->
cWindows != 0)
05980 pShutdown->dwFlags |= USER_THREAD_GUI;
05981
05982
05983
05984
05985
05986
05987
if ((pShutdown->dwFlags & USER_THREAD_GUI) &&
05988 pShutdown->StatusShutdown == 0) {
05989
05990
05991
05992
05993
05994
05995
PTHREADINFO ptiCurrent =
PtiCurrent();
05996 UserAssert(pti->
rpdesk !=
NULL);
05997
05998
if (ptiCurrent->
rpdesk != pti->
rpdesk) {
05999
06000
06001
06002
06003
06004
06005
if (ptiCurrent->
rpdesk !=
NULL) {
06006
Status =
xxxRestoreCsrssThreadDesktop(&pShutdown->drdRestore);
06007 UserAssert(pti ==
PtiFromThread(Thread));
06008 }
06009
if (
NT_SUCCESS(
Status)) {
06010
Status =
xxxSetCsrssThreadDesktop(pti->
rpdesk, &pShutdown->drdRestore);
06011 UserAssert(pti ==
PtiFromThread(Thread));
06012 }
06013 }
06014
06015
06016
06017
06018
06019
06020
if (!(dwClientFlags &
WMCS_NORETRY)) {
06021
if (
NT_SUCCESS(
Status)) {
06022
#if DBG
06023
BOOL fSwitch =
06024
#endif
06025
xxxSwitchDesktop(pti->
rpdesk->
rpwinstaParent, pti->
rpdesk,
FALSE);
06026
#if DBG
06027
UserAssert(pti ==
PtiFromThread(Thread));
06028
if (!fSwitch) {
06029
if ((pti->
rpdesk->
rpwinstaParent ==
NULL)
06030 || !(pti->
rpdesk->
rpwinstaParent->
dwWSF_Flags &
WSF_NOIO)) {
06031
06032
if (!(pti->
rpdesk->
rpwinstaParent->
dwWSF_Flags &
WSF_REALSHUTDOWN))
06033 RIPMSG1(RIP_ERROR,
"UserThreadShutdownInformation: xxxSwitchDesktop failed. pti:%#p", pti);
06034
06035 }
06036 }
06037
#endif
06038
}
06039 }
06040 }
06041
break;
06042
06043
case UserThreadFlags:
06044 LocalReturnLength =
sizeof(
DWORD);
06045
if (pti ==
NULL)
06046
Status = STATUS_INVALID_HANDLE;
06047
else {
06048 UserAssert(ThreadInformationLength ==
sizeof(
DWORD));
06049 *(LPDWORD)ThreadInformation = pti->
TIF_flags;
06050 }
06051
break;
06052
06053
case UserThreadTaskName:
06054 LocalReturnLength =
GetTaskName(pti, ThreadInformation, ThreadInformationLength);
06055
break;
06056
06057
case UserThreadWOWInformation:
06058 LocalReturnLength =
sizeof(USERTHREAD_WOW_INFORMATION);
06059 UserAssert(ThreadInformationLength ==
sizeof(USERTHREAD_WOW_INFORMATION));
06060 pWow = ThreadInformation;
06061 RtlZeroMemory(pWow,
sizeof(USERTHREAD_WOW_INFORMATION));
06062
06063
06064
06065
06066
06067
if (pti && pti->
TIF_flags &
TIF_16BIT) {
06068 pWow->lpfnWowExitTask = pti->
ppi->
pwpi->
lpfnWowExitTask;
06069
if (pti->
ptdb)
06070 pWow->hTaskWow = pti->
ptdb->
hTaskWow;
06071
else
06072 pWow->hTaskWow = 0;
06073 }
06074
break;
06075
06076
case UserThreadHungStatus:
06077 LocalReturnLength =
sizeof(
DWORD);
06078 UserAssert(ThreadInformationLength >=
sizeof(
DWORD));
06079
06080
06081
06082
06083
if (pti)
06084 *(PDWORD)ThreadInformation =
06085 (
DWORD)
FHungApp(pti, (
DWORD)*(PDWORD)ThreadInformation);
06086
else
06087 *(PDWORD)ThreadInformation =
FALSE;
06088
break;
06089
06090
default:
06091
Status = STATUS_INVALID_INFO_CLASS;
06092 UserAssert(
FALSE);
06093
break;
06094 }
06095
06096
if (ARGUMENT_PRESENT(ReturnLength) ) {
06097 *ReturnLength = LocalReturnLength;
06098 }
06099
06100
UnlockThread(Thread);
06101
06102
return Status;
06103 }
06104
06105
06106
06107
06108
06109
06110
06111
06112
06113
06114 NTSTATUS xxxSetInformationThread(
06115 IN HANDLE hThread,
06116 IN USERTHREADINFOCLASS ThreadInfoClass,
06117 IN PVOID ThreadInformation,
06118 IN ULONG ThreadInformationLength)
06119 {
06120 PUSERTHREAD_FLAGS pFlags;
06121 HANDLE hClientThread;
06122
DWORD dwOldFlags;
06123
PTHREADINFO ptiT;
06124
NTSTATUS Status = STATUS_SUCCESS;
06125
PETHREAD Thread;
06126
PETHREAD ThreadClient;
06127
PTHREADINFO pti;
06128 HANDLE
CsrPortHandle;
06129
06130 UNREFERENCED_PARAMETER(ThreadInformationLength);
06131
06132
06133
06134
06135 UserAssert(
ISCSRSS());
06136
06137
Status =
ObReferenceObjectByHandle(hThread,
06138 THREAD_SET_INFORMATION,
06139 *
PsThreadType,
06140
UserMode,
06141 &Thread,
06142
NULL);
06143
if (!
NT_SUCCESS(
Status))
06144
return Status;
06145
06146 pti =
PtiFromThread(Thread);
06147
06148
switch (ThreadInfoClass) {
06149
case UserThreadFlags:
06150
if (pti ==
NULL)
06151
Status = STATUS_INVALID_HANDLE;
06152
else {
06153 UserAssert(ThreadInformationLength ==
sizeof(USERTHREAD_FLAGS));
06154 pFlags = ThreadInformation;
06155 dwOldFlags = pti->
TIF_flags;
06156 pti->
TIF_flags ^= ((dwOldFlags ^ pFlags->dwFlags) & pFlags->dwMask);
06157 }
06158
break;
06159
06160
case UserThreadHungStatus:
06161
if (pti ==
NULL)
06162
Status = STATUS_INVALID_HANDLE;
06163
else {
06164
06165
06166
06167
06168
SET_TIME_LAST_READ(pti);
06169 }
06170
break;
06171
06172
case UserThreadInitiateShutdown:
06173 UserAssert(ThreadInformationLength ==
sizeof(ULONG));
06174
Status =
InitiateShutdown(Thread, (PULONG)ThreadInformation);
06175
break;
06176
06177
case UserThreadEndShutdown:
06178 UserAssert(ThreadInformationLength ==
sizeof(
NTSTATUS));
06179
Status =
EndShutdown(Thread, *(
NTSTATUS *)ThreadInformation);
06180
break;
06181
06182
case UserThreadUseDesktop:
06183 UserAssert(ThreadInformationLength ==
sizeof(USERTHREAD_USEDESKTOPINFO));
06184
if (pti ==
NULL) {
06185
Status = STATUS_INVALID_HANDLE;
06186
break;
06187 }
06188
06189
06190
06191
06192
06193
06194
06195 hClientThread = ((PUSERTHREAD_USEDESKTOPINFO)ThreadInformation)->hThread;
06196
if (hClientThread !=
NULL) {
06197
Status =
ObReferenceObjectByHandle(hClientThread,
06198 THREAD_QUERY_INFORMATION,
06199 *
PsThreadType,
06200
UserMode,
06201 &ThreadClient,
06202
NULL);
06203
if (!
NT_SUCCESS(
Status))
06204
break;
06205
06206 ptiT =
PtiFromThread(ThreadClient);
06207
if ((ptiT ==
NULL) || (ptiT->
rpdesk ==
NULL)) {
06208
Status = STATUS_INVALID_HANDLE;
06209
goto DerefClientThread;
06210 }
06211
Status =
xxxSetCsrssThreadDesktop(ptiT->
rpdesk, &((PUSERTHREAD_USEDESKTOPINFO)ThreadInformation)->drdRestore);
06212 }
else {
06213
Status =
xxxRestoreCsrssThreadDesktop(&((PUSERTHREAD_USEDESKTOPINFO)ThreadInformation)->drdRestore);
06214 }
06215
06216
06217
if (hClientThread !=
NULL) {
06218 DerefClientThread:
06219
ObDereferenceObject(ThreadClient);
06220 }
06221
break;
06222
06223
case UserThreadUseActiveDesktop:
06224 {
06225 UserAssert(ThreadInformationLength ==
sizeof(USERTHREAD_USEDESKTOPINFO));
06226
if (pti ==
NULL ||
grpdeskRitInput ==
NULL) {
06227
Status = STATUS_INVALID_HANDLE;
06228
break;
06229 }
06230
Status =
xxxSetCsrssThreadDesktop(
grpdeskRitInput,
06231 &((PUSERTHREAD_USEDESKTOPINFO)ThreadInformation)->drdRestore);
06232
break;
06233 }
06234
case UserThreadCsrApiPort:
06235
06236
06237
06238
06239
if (Thread->
ThreadsProcess !=
gpepCSRSS) {
06240
Status = STATUS_ACCESS_DENIED;
06241
break;
06242 }
06243
06244 UserAssert(ThreadInformationLength ==
sizeof(HANDLE));
06245
06246
06247
06248
06249
if (
CsrApiPort !=
NULL)
06250
break;
06251
06252
CsrPortHandle = *(PHANDLE)ThreadInformation;
06253
Status =
ObReferenceObjectByHandle(
06254
CsrPortHandle,
06255 0,
06256
NULL,
06257
UserMode,
06258 &
CsrApiPort,
06259
NULL);
06260
if (!
NT_SUCCESS(
Status)) {
06261
CsrApiPort =
NULL;
06262 RIPMSG1(RIP_WARNING,
06263
"CSR port reference failed, Status=%#lx",
06264
Status);
06265 }
06266
06267
break;
06268
06269
default:
06270
Status = STATUS_INVALID_INFO_CLASS;
06271 UserAssert(
FALSE);
06272
break;
06273 }
06274
06275
UnlockThread(Thread);
06276
06277
return Status;
06278 }
06279
06280
#ifdef USE_MIRRORING
06281
06282
06283
06284
06285
06286
06287
06288
06289
BOOL _GetProcessDefaultLayout(
06290 OUT DWORD *pdwDefaultLayout)
06291 {
06292
NTSTATUS Status = STATUS_SUCCESS;
06293
06294
06295
06296
06297
06298
if (
PsGetCurrentProcess() ==
gpepCSRSS) {
06299
return FALSE;
06300 }
06301
06302
try {
06303 *pdwDefaultLayout =
PpiCurrent()->dwLayout;
06304 } except (W32ExceptionHandler(FALSE, RIP_WARNING)) {
06305
Status = GetExceptionCode();
06306 }
06307
06308
return NT_SUCCESS(Status);
06309 }
06310
06311
06312
06313
06314
06315
06316
06317
06318
06319
BOOL _SetProcessDefaultLayout(
06320 IN DWORD dwDefaultLayout)
06321 {
06322
06323
06324
06325 UserAssert(
PsGetCurrentProcess() != gpepCSRSS);
06326
06327
06328
06329
06330
if (dwDefaultLayout & ~LAYOUT_ORIENTATIONMASK)
06331 {
06332 RIPERR1(ERROR_INVALID_PARAMETER,
06333 RIP_WARNING,
06334
"Calling SetProcessDefaultLayout with invalid layout = %lX",
06335 dwDefaultLayout);
06336
return FALSE;
06337 }
06338
06339
06340
06341
06342
PpiCurrent()->dwLayout = dwDefaultLayout;
06343
06344
return TRUE;
06345 }
06346
#endif
06347
06348
06349
06350
06351
06352
06353
06354
06355
06356
06357 NTSTATUS SetInformationProcess(
06358 IN HANDLE hProcess,
06359 IN USERPROCESSINFOCLASS ProcessInfoClass,
06360 IN PVOID ProcessInformation,
06361 IN ULONG ProcessInformationLength)
06362 {
06363 PUSERPROCESS_FLAGS pFlags;
06364
DWORD dwOldFlags;
06365
NTSTATUS Status = STATUS_SUCCESS;
06366
PEPROCESS Process;
06367
PPROCESSINFO ppi;
06368
06369 UNREFERENCED_PARAMETER(ProcessInformationLength);
06370
06371 UserAssert(
ISCSRSS());
06372
06373
Status =
ObReferenceObjectByHandle(hProcess,
06374 PROCESS_SET_INFORMATION,
06375 *
PsProcessType,
06376
UserMode,
06377 &Process,
06378
NULL);
06379
if (!
NT_SUCCESS(
Status)) {
06380
return Status;
06381 }
06382
06383 ppi =
PpiFromProcess(Process);
06384
06385
switch (ProcessInfoClass) {
06386
case UserProcessFlags:
06387
if (ppi ==
NULL) {
06388
Status = STATUS_INVALID_HANDLE;
06389 }
else {
06390 UserAssert(ProcessInformationLength ==
sizeof(USERPROCESS_FLAGS));
06391 pFlags = ProcessInformation;
06392 dwOldFlags = ppi->W32PF_Flags;
06393 ppi->W32PF_Flags ^= ((dwOldFlags ^ pFlags->dwFlags) & pFlags->dwMask);
06394 }
06395
break;
06396
06397
default:
06398
Status = STATUS_INVALID_INFO_CLASS;
06399 UserAssert(
FALSE);
06400
break;
06401 }
06402
06403
UnlockProcess(Process);
06404
06405
return Status;
06406 }
06407
06408
06409
06410
06411
06412
06413
06414
06415
06416
06417
06418
06419 VOID xxxSetConsoleCaretInfo(
06420 PCONSOLE_CARET_INFO pcci)
06421 {
06422
PWND pwnd;
06423
TL tlpwnd;
06424
06425
if (
FWINABLE()) {
06426 pwnd =
ValidateHwnd(pcci->hwnd);
06427
if (pwnd && pwnd->
head.rpdesk) {
06428 pwnd->
head.rpdesk->cciConsole = *pcci;
06429
ThreadLock(pwnd, &tlpwnd);
06430
xxxWindowEvent(EVENT_OBJECT_LOCATIONCHANGE, pwnd, OBJID_CARET, INDEXID_CONTAINER,
WEF_ASYNC);
06431
ThreadUnlock(&tlpwnd);
06432 }
06433 }
06434 }
06435
06436
06437
06438
06439
06440
06441
06442
06443
06444
06445 NTSTATUS xxxConsoleControl(
06446 IN CONSOLECONTROL ConsoleControl,
06447 IN PVOID ConsoleInformation,
06448 IN ULONG ConsoleInformationLength)
06449 {
06450 PCONSOLEDESKTOPCONSOLETHREAD pDesktopConsole;
06451 PCONSOLEWINDOWSTATIONPROCESS pConsoleWindowStationInfo;
06452
PDESKTOP pdesk;
06453
DWORD dwThreadIdOld;
06454
NTSTATUS Status = STATUS_SUCCESS;
06455
06456 UNREFERENCED_PARAMETER(ConsoleInformationLength);
06457 UserAssert(
ISCSRSS());
06458
06459
switch (ConsoleControl) {
06460
case ConsoleDesktopConsoleThread:
06461 UserAssert(ConsoleInformationLength ==
sizeof(CONSOLEDESKTOPCONSOLETHREAD));
06462 pDesktopConsole = (PCONSOLEDESKTOPCONSOLETHREAD)ConsoleInformation;
06463
06464
Status =
ObReferenceObjectByHandle(
06465 pDesktopConsole->hdesk,
06466 0,
06467 *
ExDesktopObjectType,
06468
UserMode,
06469 &pdesk,
06470
NULL);
06471
if (!
NT_SUCCESS(
Status))
06472
return Status;
06473
06474
LogDesktop(pdesk, LD_REF_FN_CONSOLECONTROL1,
TRUE, (ULONG_PTR)
PtiCurrent());
06475
06476 dwThreadIdOld = pdesk->
dwConsoleThreadId;
06477
06478
if (pDesktopConsole->dwThreadId != (
DWORD)-1) {
06479 pdesk->
dwConsoleThreadId =
06480 pDesktopConsole->dwThreadId;
06481 }
06482
06483 pDesktopConsole->dwThreadId = dwThreadIdOld;
06484
LogDesktop(pdesk, LD_DEREF_FN_CONSOLECONTROL1,
FALSE, (ULONG_PTR)
PtiCurrent());
06485
ObDereferenceObject(pdesk);
06486
break;
06487
06488
case ConsoleClassAtom:
06489 UserAssert(ConsoleInformationLength ==
sizeof(ATOM));
06490
gatomConsoleClass = *(ATOM *)ConsoleInformation;
06491
break;
06492
06493
case ConsoleNotifyConsoleApplication:
06494
06495
06496
06497
06498
06499 UserAssert(ConsoleInformationLength ==
sizeof(CONSOLE_PROCESS_INFO));
06500
xxxUserNotifyConsoleApplication((PCONSOLE_PROCESS_INFO)ConsoleInformation);
06501
break;
06502
06503
case ConsoleSetVDMCursorBounds:
06504 UserAssert((ConsoleInformation ==
NULL) ||
06505 (ConsoleInformationLength ==
sizeof(RECT)));
06506
SetVDMCursorBounds(ConsoleInformation);
06507
break;
06508
06509
case ConsolePublicPalette:
06510 UserAssert(ConsoleInformationLength ==
sizeof(HPALETTE));
06511 GreSetPaletteOwner(*(HPALETTE *)ConsoleInformation, OBJECT_OWNER_PUBLIC);
06512
break;
06513
06514
case ConsoleWindowStationProcess:
06515 UserAssert(ConsoleInformationLength ==
sizeof(CONSOLEWINDOWSTATIONPROCESS));
06516
06517 pConsoleWindowStationInfo = (PCONSOLEWINDOWSTATIONPROCESS)ConsoleInformation;
06518
UserSetConsoleProcessWindowStation(pConsoleWindowStationInfo->dwProcessId,
06519 pConsoleWindowStationInfo->hwinsta);
06520
break;
06521
06522
#if defined(FE_IME)
06523
06524
06525
06526
06527
06528
06529
case ConsoleRegisterConsoleIME:
06530 {
06531 PCONSOLE_REGISTER_CONSOLEIME RegConIMEInfo;
06532
DWORD dwConsoleIMEThreadIdOld;
06533
06534 UserAssert(ConsoleInformationLength ==
sizeof(CONSOLE_REGISTER_CONSOLEIME));
06535
06536 RegConIMEInfo = (PCONSOLE_REGISTER_CONSOLEIME)ConsoleInformation;
06537 RegConIMEInfo->dwConsoleInputThreadId = 0;
06538
06539
Status =
ObReferenceObjectByHandle(
06540 RegConIMEInfo->hdesk,
06541 0,
06542 *
ExDesktopObjectType,
06543
UserMode,
06544 &pdesk,
06545
NULL);
06546
if (!
NT_SUCCESS(
Status))
06547
return Status;
06548
06549
LogDesktop(pdesk, LD_REF_FN_CONSOLECONTROL2,
TRUE, (ULONG_PTR)
PtiCurrent());
06550
06551
Status = STATUS_SUCCESS;
06552
if (pdesk->
dwConsoleThreadId)
06553 {
06554
06555
06556
06557 RegConIMEInfo->dwConsoleInputThreadId = pdesk->
dwConsoleThreadId;
06558
06559 dwConsoleIMEThreadIdOld = pdesk->
dwConsoleIMEThreadId;
06560
06561
if (RegConIMEInfo->dwAction != REGCONIME_QUERY) {
06562
PTHREADINFO ptiConsoleIME;
06563
06564
if ((ptiConsoleIME =
PtiFromThreadId(RegConIMEInfo->dwThreadId)) !=
NULL)
06565 {
06566
if ( (RegConIMEInfo->dwAction == REGCONIME_REGISTER) &&
06567 !(ptiConsoleIME->
TIF_flags &
TIF_DONTATTACHQUEUE) )
06568 {
06569
06570
06571
06572 ptiConsoleIME->
TIF_flags |=
TIF_DONTATTACHQUEUE;
06573 pdesk->
dwConsoleIMEThreadId = RegConIMEInfo->dwThreadId;
06574 }
06575
else if ( (RegConIMEInfo->dwAction == REGCONIME_UNREGISTER) &&
06576 (ptiConsoleIME->
TIF_flags &
TIF_DONTATTACHQUEUE) )
06577 {
06578
06579
06580
06581 ptiConsoleIME->
TIF_flags &= ~
TIF_DONTATTACHQUEUE;
06582 pdesk->
dwConsoleIMEThreadId = 0;
06583 }
06584
else if (RegConIMEInfo->dwAction == REGCONIME_TERMINATE)
06585 {
06586
06587
06588
06589 pdesk->
dwConsoleIMEThreadId = 0;
06590 }
06591 }
06592
else if (RegConIMEInfo->dwAction == REGCONIME_TERMINATE)
06593 {
06594
06595
06596
06597 pdesk->
dwConsoleIMEThreadId = 0;
06598 }
06599
else
06600
Status = STATUS_ACCESS_DENIED;
06601 }
06602 RegConIMEInfo->dwThreadId = dwConsoleIMEThreadIdOld;
06603 }
06604
LogDesktop(pdesk, LD_DEREF_FN_CONSOLECONTROL2,
FALSE, (ULONG_PTR)
PtiCurrent());
06605
ObDereferenceObject(pdesk);
06606
return Status;
06607 }
06608
break;
06609
#endif
06610
06611
case ConsoleFullscreenSwitch:
06612 UserAssert(ConsoleInformationLength ==
sizeof(CONSOLE_FULLSCREEN_SWITCH));
06613
xxxbFullscreenSwitch(((PCONSOLE_FULLSCREEN_SWITCH)ConsoleInformation)->bFullscreenSwitch,
06614 ((PCONSOLE_FULLSCREEN_SWITCH)ConsoleInformation)->hwnd);
06615
break;
06616
06617
case ConsoleSetCaretInfo:
06618 UserAssert(ConsoleInformationLength ==
sizeof(CONSOLE_CARET_INFO));
06619
xxxSetConsoleCaretInfo((PCONSOLE_CARET_INFO)ConsoleInformation);
06620
break;
06621
06622
default:
06623 RIPMSG0(RIP_ERROR,
"xxxConsoleControl - invalid control class\n");
06624 UserAssert(
FALSE);
06625
return STATUS_INVALID_INFO_CLASS;
06626 }
06627
return STATUS_SUCCESS;
06628 }