00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
#include "precomp.h"
00014
#pragma hdrstop
00015
00016
00017
00018
00019
00020 #define HKF_SYSTEM 0x01
00021 #define HKF_TASK 0x02
00022 #define HKF_JOURNAL 0x04 // JOURNAL the mouse on set
00023 #define HKF_NZRET 0x08 // Always return NZ hook for <=3.0 compatibility
00024 #define HKF_INTERSENDABLE 0x10 // OK to call hookproc in context of hooking thread
00025 #define HKF_LOWLEVEL 0x20 // Low level hook
00026
00027 CONST
int ampiHookError[
CWINHOOKS] = {
00028 0,
00029 0,
00030 -1,
00031 0,
00032 0,
00033 0,
00034 0,
00035 0,
00036 0,
00037 0,
00038 0,
00039 0,
00040 0,
00041 0,
00042 0,
00043 0
00044
#ifdef REDIRECTION
00045
,0
00046
#endif // REDIRECTION
00047
};
00048
00049 CONST
BYTE abHookFlags[
CWINHOOKS] = {
00050
HKF_SYSTEM |
HKF_TASK |
HKF_NZRET ,
00051
HKF_SYSTEM |
HKF_JOURNAL |
HKF_INTERSENDABLE ,
00052
HKF_SYSTEM |
HKF_JOURNAL |
HKF_INTERSENDABLE ,
00053
HKF_SYSTEM |
HKF_TASK |
HKF_NZRET |
HKF_INTERSENDABLE ,
00054
HKF_SYSTEM |
HKF_TASK ,
00055
HKF_SYSTEM |
HKF_TASK ,
00056
HKF_SYSTEM |
HKF_TASK ,
00057
HKF_SYSTEM ,
00058
HKF_SYSTEM |
HKF_TASK |
HKF_INTERSENDABLE ,
00059
HKF_SYSTEM |
HKF_TASK ,
00060
HKF_SYSTEM |
HKF_TASK ,
00061
HKF_SYSTEM |
HKF_TASK ,
00062
HKF_SYSTEM |
HKF_TASK ,
00063
HKF_SYSTEM |
HKF_TASK ,
00064
HKF_SYSTEM |
HKF_LOWLEVEL |
HKF_INTERSENDABLE ,
00065
HKF_SYSTEM |
HKF_LOWLEVEL |
HKF_INTERSENDABLE
00066
00067
#ifdef REDIRECTION
00068
,
HKF_SYSTEM |
HKF_LOWLEVEL |
HKF_INTERSENDABLE
00069
#endif // REDIRECTION
00070
};
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
#if (WM_KEYFIRST != 0x100) || \
00100
(WM_KEYLAST != 0x108) || \
00101
(WM_KEYDOWN & 0x2) || \
00102
(WM_KEYUP & 0x2) || \
00103
(WM_SYSKEYDOWN & 0x2) || \
00104
(WM_SYSKEYUP & 0x2) || \
00105
!(WM_CHAR & 0x02) || \
00106
!(WM_DEADCHAR & 0x02) || \
00107
!(WM_SYSCHAR & 0x02) || \
00108
!(WM_SYSDEADCHAR & 0x02)
00109
#error "unexpected value in keyboard messages."
00110
#endif
00111
00112
00113
#if DBG
00114
00115
BOOL IsCharMsg(UINT msg)
00116 {
00117 UserAssert(msg >= WM_KEYFIRST && msg < WM_KEYLAST);
00118
00119
return msg & 0x02;
00120 }
00121
00122
#define IS_CHAR_MSG(msg) IsCharMsg(msg)
00123
00124
#else
00125
00126 #define IS_CHAR_MSG(msg) ((msg) & 0x02)
00127
00128
#endif
00129
00130
00131
00132
00133
void UnlinkHook(
PHOOK phkFree);
00134
00135
00136
00137
00138
00139
00140
00141
00142
#if DBG
00143
PHOOK * DbgValidateThisHook (
PHOOK phk,
int iType,
PTHREADINFO ptiHooked)
00144 {
00145
CheckCritIn();
00146
00147
00148
00149 UserAssert(!(phk->
flags & ~HF_DBGUSED));
00150
00151
00152
00153 UserAssert(phk->
iHook == iType);
00154
00155
00156
00157
if (phk->
flags &
HF_GLOBAL) {
00158 UserAssert(phk->
ptiHooked == NULL);
00159
if (phk->
rpdesk !=
NULL) {
00160 UserAssert(
GETPTI(phk) == gptiRit);
00161
return &phk->
rpdesk->
pDeskInfo->
aphkStart[iType + 1];
00162 }
else {
00163
return &
GETPTI(phk)->pDeskInfo->aphkStart[iType + 1];
00164 }
00165 }
else {
00166 UserAssert((phk->
ptiHooked == ptiHooked)
00167 || (abHookFlags[iType + 1] & HKF_INTERSENDABLE));
00168
00169
return &(phk->
ptiHooked->
aphkStart[iType + 1]);
00170 }
00171 }
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
void DbgValidatefsHook(
PHOOK phk,
int nFilterType,
PTHREADINFO pti, BOOL fGlobal)
00183 {
00184
CheckCritIn();
00185
00186
00187
00188
00189
if (pti ==
NULL) {
00190 fGlobal = (phk->
flags &
HF_GLOBAL);
00191
if (fGlobal) {
00192 pti =
GETPTI(phk);
00193 }
else {
00194 pti = phk->
ptiHooked;
00195 UserAssert(pti != NULL);
00196 }
00197 }
00198
00199
if (fGlobal) {
00200
if ((phk !=
NULL) ^
IsGlobalHooked(pti,
WHF_FROM_WH(nFilterType))) {
00201
PHOOK phkTemp = pti->
pDeskInfo->
aphkStart[nFilterType + 1];
00202
while ((phkTemp !=
NULL) && !(phkTemp->
flags & HF_INCHECKWHF)) {
00203 phkTemp = phkTemp->
phkNext;
00204 }
00205 UserAssert(phkTemp != NULL);
00206 }
00207 }
else {
00208
if ((phk !=
NULL) ^
IsHooked(pti,
WHF_FROM_WH(nFilterType))) {
00209
PHOOK phkTemp = pti->
aphkStart[nFilterType + 1];
00210
while ((phkTemp !=
NULL) && !(phkTemp->
flags & HF_INCHECKWHF)) {
00211 phkTemp = phkTemp->
phkNext;
00212 }
00213
if (phkTemp ==
NULL) {
00214 phkTemp = pti->
pDeskInfo->
aphkStart[nFilterType + 1];
00215
while ((phkTemp !=
NULL) && !(phkTemp->
flags & HF_INCHECKWHF)) {
00216 phkTemp = phkTemp->
phkNext;
00217 }
00218 }
00219 UserAssert(phkTemp != NULL);
00220 }
00221 }
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
void DbgValidateHooks (
PHOOK phk,
int iType)
00231 {
00232
PHOOK *pphkStart, *pphkNext;
00233
if (phk ==
NULL) {
00234
return;
00235 }
00236
00237
00238
00239 UserAssert(!(phk->
flags & (HF_DESTROYED | HF_FREED)));
00240
00241
00242
00243
DbgValidatefsHook(phk, iType, NULL, FALSE);
00244
00245
00246
00247 pphkStart = DbgValidateThisHook(phk, iType, phk->
ptiHooked);
00248
00249
00250
00251 UserAssert(*pphkStart != NULL);
00252
00253
00254
00255
00256 pphkNext = pphkStart;
00257
while ((*pphkNext != phk) && (*pphkNext !=
NULL)) {
00258 UserAssert(pphkStart == DbgValidateThisHook(*pphkNext, iType, phk->
ptiHooked));
00259 pphkNext = &(*pphkNext)->
phkNext;
00260 }
00261
00262
00263
00264 UserAssert(*pphkNext == phk);
00265
00266
00267
00268
while (*pphkNext !=
NULL) {
00269 UserAssert(pphkStart == DbgValidateThisHook(*pphkNext, iType, phk->
ptiHooked));
00270 pphkNext = &(*pphkNext)->
phkNext;
00271 }
00272 }
00273
#else
00274 #define DbgValidatefsHook(phk, nFilterType, pti, fGlobal)
00275
#endif
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 BOOL zzzJournalAttach(
00286
PTHREADINFO pti,
00287 BOOL fAttach)
00288 {
00289
PTHREADINFO ptiT;
00290
PQ pq;
00291 PLIST_ENTRY pHead, pEntry;
00292
00293
00294
00295
00296
00297
00298
if (fAttach) {
00299
if ((pq =
AllocQueue(pti,
NULL)) ==
NULL)
00300
return FALSE;
00301
00302 pHead = &pti->
rpdesk->
PtiList;
00303
for (pEntry = pHead->Flink; pEntry != pHead; pEntry = pEntry->Flink) {
00304 ptiT = CONTAINING_RECORD(pEntry,
THREADINFO, PtiLink);
00305
00306
00307
00308
00309
00310
if (!(ptiT->
TIF_flags & (
TIF_DONTJOURNALATTACH |
TIF_INCLEANUP))) {
00311 ptiT->
pqAttach = pq;
00312 ptiT->
pqAttach->
cThreads++;
00313 }
00314 }
00315 }
00316
00317
return zzzReattachThreads(fAttach);
00318 }
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339 void InterQueueMsgCleanup (DWORD dwTimeFromLastRead)
00340 {
00341
PSMS *ppsms;
00342
PSMS psmsNext;
00343
00344
CheckCritIn();
00345
00346
00347
00348
00349
for (ppsms = &
gpsmsList; *ppsms; ) {
00350 psmsNext = (*ppsms)->psmsNext;
00351
00352
00353
00354
if (((*ppsms)->ptiSender !=
NULL)
00355 && ((*ppsms)->ptiReceiver !=
NULL)
00356 && ((*ppsms)->ptiSender->pq != (*ppsms)->ptiReceiver->pq)) {
00357
00358
00359
00360
if (
FHungApp ((*ppsms)->ptiReceiver, dwTimeFromLastRead)) {
00361
00362
switch ((*ppsms)->message) {
00363
00364
00365
00366
case WM_NCACTIVATE:
00367
case WM_ACTIVATEAPP:
00368
case WM_ACTIVATE:
00369
case WM_SETFOCUS:
00370
case WM_KILLFOCUS:
00371
case WM_QUERYNEWPALETTE:
00372
00373
00374
00375
case WM_INPUTLANGCHANGE:
00376 RIPMSG3 (RIP_WARNING,
"InterQueueMsgCleanup: ptiSender:%#p ptiReceiver:%#p message:%#lx",
00377 (*ppsms)->ptiSender, (*ppsms)->ptiReceiver, (*ppsms)->message);
00378
ReceiverDied(*ppsms, ppsms);
00379
break;
00380
00381 }
00382
00383 }
00384
00385 }
00386
00387
00388
00389
00390
if (*ppsms != psmsNext)
00391 ppsms = &(*ppsms)->psmsNext;
00392
00393 }
00394 }
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404 void zzzCancelJournalling(
void)
00405 {
00406
PTHREADINFO ptiCancelJournal;
00407
PHOOK phook;
00408
PHOOK phookNext;
00409
00410
00411
00412
00413
00414
00415
00416
00417
#if DBG
00418
if (
gwMouseOwnerButton)
00419 RIPMSG1(RIP_WARNING,
00420
"gwMouseOwnerButton=%x, being cleared forcibly\n",
00421
gwMouseOwnerButton);
00422
#endif
00423
gwMouseOwnerButton = 0;
00424
00425
00426
00427
00428
00429
00430
DeferWinEventNotify();
00431 UserAssert(
gptiRit->
pDeskInfo ==
grpdeskRitInput->
pDeskInfo);
00432 phook =
PhkFirstGlobalValid(
gptiRit, WH_JOURNALPLAYBACK);
00433
while (phook !=
NULL) {
00434 ptiCancelJournal = phook->
head.pti;
00435
00436
if (ptiCancelJournal !=
NULL) {
00437
00438
00439
00440
_PostThreadMessage(ptiCancelJournal, WM_CANCELJOURNAL, 0, 0);
00441
00442
00443
00444
00445
00446
00447
00448
SendMsgCleanup(ptiCancelJournal);
00449 }
00450
00451 phookNext =
PhkNextValid(phook);
00452
zzzUnhookWindowsHookEx(phook);
00453 phook = phookNext;
00454 }
00455
zzzEndDeferWinEventNotify();
00456
00457
00458
00459
00460
DeferWinEventNotify();
00461 UserAssert(
gptiRit->
pDeskInfo ==
grpdeskRitInput->
pDeskInfo);
00462 phook =
PhkFirstGlobalValid(
gptiRit, WH_JOURNALRECORD);
00463
while (phook !=
NULL) {
00464 ptiCancelJournal = phook->
head.pti;
00465
00466
if (ptiCancelJournal !=
NULL) {
00467
00468
00469
00470
_PostThreadMessage(ptiCancelJournal, WM_CANCELJOURNAL, 0, 0);
00471
00472
00473
00474
00475
00476
00477
00478
SendMsgCleanup(ptiCancelJournal);
00479 }
00480
00481 phookNext =
PhkNextValid(phook);
00482
zzzUnhookWindowsHookEx(phook);
00483 phook = phookNext;
00484 }
00485
zzzEndDeferWinEventNotify();
00486
00487
00488
00489
00490
00491
InterQueueMsgCleanup(
CMSWAITTOKILLTIMEOUT);
00492
00493
00494
00495
00496
gppiLockSFW =
NULL;
00497
00498
00499
00500
00501
00502
00503
if (
grpdeskRitInput &&
grpdeskRitInput->
pDeskInfo) {
00504
PWND pwndDesktop =
grpdeskRitInput->
pDeskInfo->
spwnd;
00505
00506
if (pwndDesktop &&
TestWF(pwndDesktop,
WFDISABLED)) {
00507
ClrWF(pwndDesktop,
WFDISABLED);
00508 }
00509 }
00510 }
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528 PROC
zzzSetWindowsHookAW(
00529
int nFilterType,
00530 PROC pfnFilterProc,
00531 DWORD dwFlags)
00532 {
00533
PHOOK phk;
00534
00535 phk =
zzzSetWindowsHookEx(
NULL,
NULL,
PtiCurrent(),
00536 nFilterType, pfnFilterProc,
dwFlags);
00537
00538
00539
00540
00541
00542
if (phk ==
NULL) {
00543
return (PROC)-1;
00544 }
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
if ((phk->
phkNext !=
NULL) || (
abHookFlags[nFilterType + 1] &
HKF_NZRET)) {
00555
return (PROC)phk;
00556 }
00557
00558
return NULL;
00559 }
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576 PHOOK zzzSetWindowsHookEx(
00577 HANDLE hmod,
00578 PUNICODE_STRING pstrLib,
00579
PTHREADINFO ptiThread,
00580
int nFilterType,
00581 PROC pfnFilterProc,
00582 DWORD dwFlags)
00583 {
00584 ACCESS_MASK amDesired;
00585
PHOOK phkNew;
00586
TL tlphkNew;
00587
PHOOK *pphkStart;
00588
PTHREADINFO ptiCurrent;
00589
00590
00591
00592
00593
if ((nFilterType < WH_MIN) || (nFilterType > WH_MAX)) {
00594 RIPERR0(ERROR_INVALID_HOOK_FILTER, RIP_VERBOSE,
"");
00595
return NULL;
00596 }
00597
00598
00599
00600
00601
if (pfnFilterProc ==
NULL) {
00602 RIPERR0(ERROR_INVALID_FILTER_PROC, RIP_VERBOSE,
"");
00603
return NULL;
00604 }
00605
00606 ptiCurrent =
PtiCurrent();
00607
00608
if (ptiThread ==
NULL) {
00609
00610
00611
00612
00613
if (hmod ==
NULL) {
00614 RIPERR0(ERROR_HOOK_NEEDS_HMOD, RIP_VERBOSE,
"");
00615
return NULL;
00616 }
00617 }
else {
00618
00619
00620
00621
00622
if (!(
abHookFlags[nFilterType + 1] &
HKF_TASK)) {
00623 RIPERR0(ERROR_GLOBAL_ONLY_HOOK, RIP_VERBOSE,
"");
00624
return NULL;
00625 }
00626
00627
00628
00629
00630
if (ptiThread->
rpdesk != ptiCurrent->
rpdesk) {
00631 RIPERR0(ERROR_ACCESS_DENIED,
00632 RIP_WARNING,
00633
"Access denied to desktop in zzzSetWindowsHookEx - can't hook other desktops");
00634
00635
return NULL;
00636 }
00637
00638
if (ptiCurrent->
ppi != ptiThread->
ppi) {
00639
00640
00641
00642
00643
if (hmod ==
NULL) {
00644 RIPERR0(ERROR_HOOK_NEEDS_HMOD, RIP_VERBOSE,
"");
00645
return NULL;
00646 }
00647
00648
00649
00650
00651
00652
00653
if ((!
RtlEqualLuid(&ptiThread->
ppi->
luidSession,
00654 &ptiCurrent->
ppi->
luidSession)) &&
00655 !(ptiThread->
TIF_flags &
TIF_ALLOWOTHERACCOUNTHOOK)) {
00656
00657 RIPERR0(ERROR_ACCESS_DENIED,
00658 RIP_WARNING,
00659
"Access denied to other user in zzzSetWindowsHookEx");
00660
00661
return NULL;
00662 }
00663
00664
if ((ptiThread->
TIF_flags & (
TIF_CSRSSTHREAD |
TIF_SYSTEMTHREAD)) &&
00665 !(
abHookFlags[nFilterType + 1] &
HKF_INTERSENDABLE)) {
00666
00667
00668
00669
00670
00671 RIPERR1(ERROR_HOOK_TYPE_NOT_ALLOWED,
00672 RIP_WARNING,
00673
"nFilterType (%ld) not allowed in zzzSetWindowsHookEx",
00674 nFilterType);
00675
00676
return NULL;
00677 }
00678 }
00679 }
00680
00681
00682
00683
00684
switch( nFilterType ) {
00685
case WH_JOURNALRECORD:
00686 amDesired = DESKTOP_JOURNALRECORD;
00687
break;
00688
00689
case WH_JOURNALPLAYBACK:
00690 amDesired = DESKTOP_JOURNALPLAYBACK;
00691
break;
00692
00693
default:
00694 amDesired = DESKTOP_HOOKCONTROL;
00695
break;
00696 }
00697
00698
if (!
RtlAreAllAccessesGranted(ptiCurrent->
amdesk, amDesired)) {
00699 RIPERR0(ERROR_ACCESS_DENIED,
00700 RIP_WARNING,
00701
"Access denied to desktop in zzzSetWindowsHookEx");
00702
00703
return NULL;
00704 }
00705
00706
if (amDesired != DESKTOP_HOOKCONTROL &&
00707 (ptiCurrent->
rpdesk->
rpwinstaParent->
dwWSF_Flags &
WSF_NOIO)) {
00708 RIPERR0(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION,
00709 RIP_WARNING,
00710
"Journal hooks invalid on a desktop belonging to a non-interactive WindowStation.");
00711
00712
return NULL;
00713 }
00714
00715
#if 0
00716
00717
00718
00719
if (
abHookFlags[nFilterType + 1] &
HKF_JOURNAL) {
00720
00721
00722
00723
00724
00725
00726
if (ptiCurrent->
pDeskInfo->asphkStart[nFilterType + 1] !=
NULL) {
00727 RIPERR0(ERROR_JOURNAL_HOOK_SET, RIP_VERBOSE,
"");
00728
return NULL;
00729 }
00730 }
00731
#endif
00732
00733
00734
00735
00736 phkNew = (
PHOOK)
HMAllocObject(ptiCurrent, ptiCurrent->
rpdesk,
00737
TYPE_HOOK,
sizeof(
HOOK));
00738
if (phkNew ==
NULL) {
00739
return NULL;
00740 }
00741
00742
00743
00744
00745
00746
00747 phkNew->
ihmod = -1;
00748
if (hmod !=
NULL) {
00749
00750
#if defined(WX86)
00751
00752 phkNew->
flags |= (
dwFlags &
HF_WX86KNOWNDLL);
00753
00754
#endif
00755
00756 phkNew->
ihmod =
GetHmodTableIndex(pstrLib);
00757
00758
if (phkNew->
ihmod == -1) {
00759 RIPERR0(ERROR_MOD_NOT_FOUND, RIP_VERBOSE,
"");
00760
HMFreeObject((PVOID)phkNew);
00761
return NULL;
00762 }
00763
00764
00765
00766
00767
00768
if (phkNew->
ihmod >= 0) {
00769
AddHmodDependency(phkNew->
ihmod);
00770 }
00771 }
00772
00773
00774
00775
00776
00777
00778
if (ptiThread !=
NULL) {
00779 pphkStart = &ptiThread->
aphkStart[nFilterType + 1];
00780
00781
00782
00783
00784 ptiThread->
fsHooks |=
WHF_FROM_WH(nFilterType);
00785
00786
00787
00788
00789
if (ptiThread->
pClientInfo) {
00790
BOOL fAttached;
00791
00792
00793
00794
00795
00796
if (ptiThread->
ppi != ptiCurrent->
ppi) {
00797
KeAttachProcess(&ptiThread->
ppi->Process->Pcb);
00798 fAttached =
TRUE;
00799 }
else
00800 fAttached =
FALSE;
00801
00802 ptiThread->
pClientInfo->
fsHooks = ptiThread->
fsHooks;
00803
00804
if (fAttached)
00805
KeDetachProcess();
00806 }
00807
00808
00809
00810
00811 phkNew->
ptiHooked = ptiThread;
00812
00813 }
else {
00814 pphkStart = &ptiCurrent->
pDeskInfo->
aphkStart[nFilterType + 1];
00815 phkNew->
flags |=
HF_GLOBAL;
00816
00817
00818
00819
00820 ptiCurrent->
pDeskInfo->
fsHooks |=
WHF_FROM_WH(nFilterType);
00821
00822 phkNew->
ptiHooked =
NULL;
00823 }
00824
00825
00826
00827
00828 phkNew->
flags |= (
dwFlags &
HF_ANSI);
00829
00830
00831
00832
00833
00834 phkNew->
iHook = nFilterType;
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844 phkNew->
offPfn = ((ULONG_PTR)pfnFilterProc) - ((ULONG_PTR)hmod);
00845
00846
#ifdef HOOKBATCH
00847
phkNew->cEventMessages = 0;
00848 phkNew->iCurrentEvent = 0;
00849 phkNew->CacheTimeOut = 0;
00850 phkNew->aEventCache =
NULL;
00851
#endif //HOOKBATCH
00852
00853
00854
00855
00856 phkNew->
phkNext = *pphkStart;
00857 *pphkStart = phkNew;
00858
00859
00860
00861
00862
00863
00864
if (
abHookFlags[nFilterType + 1] &
HKF_JOURNAL) {
00865
00866
00867
00868
00869
00870
ThreadLockAlwaysWithPti(ptiCurrent, phkNew, &tlphkNew);
00871
if (!
zzzJournalAttach(ptiCurrent,
TRUE)) {
00872 RIPMSG1(RIP_WARNING,
"zzzJournalAttach failed, so abort hook %#p", phkNew);
00873
if (
ThreadUnlock(&tlphkNew) !=
NULL) {
00874
zzzUnhookWindowsHookEx(phkNew);
00875 }
00876
return NULL;
00877 }
00878
if ((phkNew =
ThreadUnlock(&tlphkNew)) ==
NULL) {
00879
return NULL;
00880 }
00881 }
00882
00883 UserAssert(phkNew !=
NULL);
00884
00885
00886
00887
00888
00889
00890
00891
00892 UserAssert(ptiCurrent->pEThread &&
THREAD_TO_PROCESS(ptiCurrent->pEThread));
00893
00894
00895
00896
00897
00898
00899
if ((phkNew->flags &
HF_GLOBAL) &&
00900 (
abHookFlags[nFilterType + 1] &
HKF_INTERSENDABLE)) {
00901
00902 ptiCurrent->
TIF_flags |=
TIF_GLOBALHOOKER;
00903
KeSetPriorityThread(&ptiCurrent->pEThread->Tcb, LOW_REALTIME_PRIORITY-2);
00904
00905
if (
abHookFlags[nFilterType + 1] &
HKF_JOURNAL) {
00906
ThreadLockAlwaysWithPti(ptiCurrent, phkNew, &tlphkNew);
00907
00908
00909
00910
00911
00912
zzzSetFMouseMoved();
00913 phkNew =
ThreadUnlock(&tlphkNew);
00914
00915
00916
00917
00918
if (nFilterType == WH_JOURNALPLAYBACK) {
00919
gppiInputProvider = ptiCurrent->
ppi;
00920 }
00921 }
else {
00922 UserAssert(nFilterType != WH_JOURNALPLAYBACK);
00923 }
00924 }
else {
00925 UserAssert(!(
abHookFlags[nFilterType + 1] &
HKF_JOURNAL));
00926 UserAssert(nFilterType != WH_JOURNALPLAYBACK);
00927 }
00928
00929
00930
00931
00932
00933
00934
00935
00936
DbgValidateHooks(phkNew, phkNew->iHook);
00937
return phkNew;
00938 }
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961 LRESULT
xxxCallNextHookEx(
00962
int nCode,
00963 WPARAM wParam,
00964 LPARAM lParam)
00965 {
00966
BOOL bAnsiHook;
00967
00968
if (
PtiCurrent()->sphkCurrent ==
NULL) {
00969
return 0;
00970 }
00971
00972
return xxxCallHook2(
PhkNextValid(
PtiCurrent()->sphkCurrent), nCode, wParam, lParam, &bAnsiHook);
00973 }
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986 VOID CheckWHFBits(
00987
PTHREADINFO pti,
00988
int nFilterType)
00989 {
00990
BOOL fClearThreadBits;
00991
BOOL fClearDesktopBits;
00992
PHOOK phook;
00993
00994
00995
00996
00997
00998
00999 fClearThreadBits =
TRUE;
01000 fClearDesktopBits =
TRUE;
01001
01002
01003
01004 phook =
PhkFirstValid(pti, nFilterType);
01005
if (phook !=
NULL) {
01006
01007
01008
01009
01010
01011
if (phook->
flags &
HF_GLOBAL) {
01012 fClearDesktopBits =
FALSE;
01013 }
else {
01014
01015
01016
01017 fClearThreadBits =
FALSE;
01018
01019
01020
01021
01022 phook =
PhkFirstGlobalValid(pti, nFilterType);
01023 fClearDesktopBits = (phook ==
NULL);
01024 }
01025 }
01026
01027
if (fClearThreadBits) {
01028 pti->
fsHooks &= ~(
WHF_FROM_WH(nFilterType));
01029
01030
01031
01032
if (pti->
pClientInfo) {
01033
BOOL fAttached;
01034
01035
01036
01037
01038
if (pti->
ppi !=
PpiCurrent()) {
01039
KeAttachProcess(&pti->
ppi->Process->Pcb);
01040 fAttached =
TRUE;
01041 }
else
01042 fAttached =
FALSE;
01043
01044 pti->
pClientInfo->
fsHooks = pti->
fsHooks;
01045
01046
if (fAttached)
01047
KeDetachProcess();
01048 }
01049 }
01050
01051
if (fClearDesktopBits) {
01052 pti->
pDeskInfo->
fsHooks &= ~(
WHF_FROM_WH(nFilterType));
01053 }
01054 }
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068 BOOL zzzUnhookWindowsHook(
01069
int nFilterType,
01070 PROC pfnFilterProc)
01071 {
01072
PHOOK phk;
01073
PTHREADINFO ptiCurrent;
01074
01075
if ((nFilterType < WH_MIN) || (nFilterType > WH_MAX)) {
01076 RIPERR0(ERROR_INVALID_HOOK_FILTER, RIP_VERBOSE,
"");
01077
return FALSE;
01078 }
01079
01080 ptiCurrent =
PtiCurrent();
01081
01082
for (phk =
PhkFirstValid(ptiCurrent, nFilterType); phk !=
NULL; phk =
PhkNextValid(phk)) {
01083
01084
01085
01086
if (
PFNHOOK(phk) == pfnFilterProc) {
01087
01088
01089
01090
01091
01092
if (
GETPTI(phk) != ptiCurrent) {
01093 RIPERR0(ERROR_ACCESS_DENIED,
01094 RIP_WARNING,
01095
"Access denied in zzzUnhookWindowsHook: "
01096
"this thread is not the same as that which set the hook");
01097
01098
return FALSE;
01099 }
01100
01101
return zzzUnhookWindowsHookEx( phk );
01102 }
01103 }
01104
01105
01106
01107
01108 RIPERR0(ERROR_HOOK_NOT_INSTALLED, RIP_VERBOSE,
"");
01109
return FALSE;
01110 }
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126 BOOL zzzUnhookWindowsHookEx(
01127
PHOOK phkFree)
01128 {
01129
PTHREADINFO pti;
01130
01131 pti =
GETPTI(phkFree);
01132
01133
01134
01135
01136
if (phkFree->
flags &
HF_DESTROYED) {
01137 RIPMSG1(RIP_WARNING,
"_UnhookWindowsHookEx(%#p) already destroyed", phkFree);
01138
return FALSE;
01139 }
01140
01141
01142
01143
01144
if (
abHookFlags[phkFree->
iHook + 1] &
HKF_JOURNAL) {
01145
zzzJournalAttach(pti,
FALSE);
01146
01147
01148
01149
01150
01151
01152
01153
01154 }
01155
01156
01157
01158
01159
01160
FreeHook(phkFree);
01161
01162
01163
01164
01165
01166
if (pti->
TIF_flags &
TIF_GLOBALHOOKER) {
01167
int iHook;
01168
PHOOK phk;
01169
for (iHook = WH_MIN ; iHook <= WH_MAX ; ++iHook) {
01170
01171
01172
01173
if (!(
abHookFlags[iHook + 1] &
HKF_INTERSENDABLE)) {
01174
continue;
01175 }
01176
01177
01178
01179
01180
for (phk =
PhkFirstGlobalValid(pti, iHook);
01181 phk !=
NULL; phk =
PhkNextValid(phk)) {
01182
01183
if (
GETPTI(phk) == pti) {
01184
goto StillHasGlobalHooks;
01185 }
01186 }
01187 }
01188 pti->
TIF_flags &= ~
TIF_GLOBALHOOKER;
01189 }
01190
01191 StillHasGlobalHooks:
01192
01193
01194
01195
return TRUE;
01196 }
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210 BOOL _CallMsgFilter(
01211 LPMSG pmsg,
01212
int nCode)
01213 {
01214
PTHREADINFO pti;
01215
01216 pti =
PtiCurrent();
01217
01218
01219
01220
01221
01222
01223
if (
IsHooked(pti,
WHF_SYSMSGFILTER) &&
xxxCallHook(nCode, 0, (LPARAM)pmsg,
01224 WH_SYSMSGFILTER)) {
01225
return TRUE;
01226 }
01227
01228
if (
IsHooked(pti,
WHF_MSGFILTER)) {
01229
return (
BOOL)
xxxCallHook(nCode, 0, (LPARAM)pmsg, WH_MSGFILTER);
01230 }
01231
01232
return FALSE;
01233 }
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246 int xxxCallHook(
01247
int nCode,
01248 WPARAM wParam,
01249 LPARAM lParam,
01250
int iHook)
01251 {
01252
BOOL bAnsiHook;
01253
01254
return (
int)
xxxCallHook2(
PhkFirstValid(
PtiCurrent(), iHook), nCode, wParam, lParam, &bAnsiHook);
01255 }
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288 LRESULT
xxxCallHook2(
01289
PHOOK phkCall,
01290
int nCode,
01291 WPARAM wParam,
01292 LPARAM lParam,
01293 LPBOOL lpbAnsiHook)
01294 {
01295
UINT iHook;
01296
PHOOK phkSave;
01297 LONG_PTR nRet;
01298
PTHREADINFO ptiCurrent;
01299
BOOL fLoadSuccess;
01300
TL tlphkCall;
01301
TL tlphkSave;
01302
BYTE bHookFlags;
01303
BOOL fMustIntersend;
01304
01305
CheckCritIn();
01306
01307
if (phkCall ==
NULL) {
01308
return 0;
01309 }
01310
01311 iHook = phkCall->
iHook;
01312
01313 ptiCurrent =
PtiCurrent();
01314
01315
01316
01317
01318
if (ptiCurrent ==
gptiRit) {
01319
switch (iHook) {
01320
case WH_MOUSE_LL:
01321
case WH_KEYBOARD_LL:
01322
01323
#ifdef REDIRECTION
01324
case WH_HITTEST:
01325
#endif // REDIRECTION
01326
01327
break;
01328
01329
default:
01330
return 0;
01331 }
01332 }
01333
01334
01335
01336
01337
01338
if ( ptiCurrent->
TIF_flags & (
TIF_INCLEANUP |
TIF_DISABLEHOOKS) ||
01339 ((ptiCurrent->
rpdesk ==
NULL) && (phkCall->
iHook != WH_MOUSE_LL))) {
01340
return ampiHookError[iHook + 1];
01341 }
01342
01343
01344
01345
01346
01347
do {
01348 *lpbAnsiHook = phkCall->
flags &
HF_ANSI;
01349 bHookFlags =
abHookFlags[phkCall->
iHook + 1];
01350
01351
01352
01353
01354
01355
01356
01357
if ((phkCall->
iHook == WH_SHELL) && (ptiCurrent->
TIF_flags &
TIF_CSRSSTHREAD)) {
01358
if ((nCode == HSHELL_LANGUAGE) || (nCode == HSHELL_WINDOWACTIVATED) ||
01359 (nCode == HSHELL_APPCOMMAND)) {
01360 bHookFlags |=
HKF_INTERSENDABLE;
01361 }
01362 }
01363
01364
if ((phkCall->
iHook == WH_SHELL) && (ptiCurrent->
TIF_flags &
TIF_SYSTEMTHREAD)) {
01365
if ((nCode == HSHELL_ACCESSIBILITYSTATE) ) {
01366 bHookFlags |=
HKF_INTERSENDABLE;
01367 }
01368 }
01369
01370 fMustIntersend =
01371 (
GETPTI(phkCall) != ptiCurrent) &&
01372 (
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383 (bHookFlags & (
HKF_JOURNAL |
HKF_LOWLEVEL))
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393 ||
01394 (
GETPTI(phkCall)->TIF_flags &
TIF_16BIT &&
01395 ( !(ptiCurrent->
TIF_flags &
TIF_16BIT) ||
01396 ptiCurrent->
ppi !=
GETPTI(phkCall)->ppi))
01397
01398
#if defined(_WIN64)
01399
01400
01401
01402
01403
01404
01405
01406 ||
01407 ( (
GETPTI(phkCall)->TIF_flags &
TIF_WOW64) !=
01408 (ptiCurrent->
TIF_flags &
TIF_WOW64)
01409 )
01410
01411
#endif
01412
01413
01414
01415
01416
01417 ||
01418 ( ptiCurrent->
TIF_flags & (
TIF_CSRSSTHREAD |
TIF_SYSTEMTHREAD) &&
01419
GETPTI(phkCall)->ppi != ptiCurrent->
ppi)
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430 ||
01431 ( phkCall->
flags &
HF_GLOBAL &&
01432 !
RtlEqualLuid(&
GETPTI(phkCall)->ppi->luidSession, &ptiCurrent->
ppi->
luidSession) &&
01433 !(ptiCurrent->
TIF_flags &
TIF_ALLOWOTHERACCOUNTHOOK) &&
01434 !
RtlEqualLuid(&
GETPTI(phkCall)->ppi->luidSession, &
luidSystem))
01435
01436
01437
01438
01439
01440 ||
01441 (
GETPTI(phkCall)->ppi != ptiCurrent->
ppi &&
01442
IsRestricted(
GETPTI(phkCall)->pEThread))
01443 );
01444
01445
01446
01447
01448
01449
01450
ThreadLockAlwaysWithPti(ptiCurrent, phkCall, &tlphkCall);
01451
01452
if (!fMustIntersend) {
01453
01454
01455
01456
01457
if ((phkCall->
ihmod != -1) &&
01458 (
TESTHMODLOADED(ptiCurrent, phkCall->
ihmod) == 0)) {
01459
01460
BOOL bWx86KnownDll;
01461
01462
01463
01464
01465
01466
01467 bWx86KnownDll = (phkCall->
flags &
HF_WX86KNOWNDLL) != 0;
01468 fLoadSuccess = (
xxxLoadHmodIndex(phkCall->
ihmod, bWx86KnownDll) !=
NULL);
01469
01470
01471
01472
01473
01474
if (!fLoadSuccess) {
01475
goto LoopAgain;
01476 }
01477 }
01478
01479
01480
01481
01482
if (
IsHooked(ptiCurrent,
WHF_DEBUG) && (phkCall->
iHook != WH_DEBUG)) {
01483 DEBUGHOOKINFO debug;
01484
01485 debug.idThread =
TIDq(ptiCurrent);
01486 debug.idThreadInstaller = 0;
01487 debug.code = nCode;
01488 debug.wParam = wParam;
01489 debug.lParam = lParam;
01490
01491
if (
xxxCallHook(HC_ACTION, phkCall->
iHook, (LPARAM)&debug, WH_DEBUG)) {
01492
01493
01494
01495
01496
goto LoopAgain;
01497 }
01498 }
01499
01500
01501
01502
01503
01504
if (
HMIsMarkDestroy(phkCall)) {
01505
goto LoopAgain;
01506 }
01507
01508
01509
01510
01511
01512
01513
01514
#if DBG
01515
if (phkCall->
flags &
HF_GLOBAL) {
01516 UserAssert(phkCall->
ptiHooked ==
NULL);
01517 }
else {
01518 UserAssert(phkCall->
ptiHooked == ptiCurrent);
01519 }
01520
#endif
01521
phkSave = ptiCurrent->
sphkCurrent;
01522
ThreadLockWithPti(ptiCurrent, phkSave, &tlphkSave);
01523
01524
Lock(&ptiCurrent->
sphkCurrent, phkCall);
01525
if (ptiCurrent->
pClientInfo)
01526 ptiCurrent->
pClientInfo->
phkCurrent = phkCall;
01527
01528 nRet =
xxxHkCallHook(phkCall, nCode, wParam, lParam);
01529
01530
Lock(&ptiCurrent->
sphkCurrent, phkSave);
01531
if (ptiCurrent->
pClientInfo)
01532 ptiCurrent->
pClientInfo->
phkCurrent = phkSave;
01533
01534
ThreadUnlock(&tlphkSave);
01535
01536
01537
01538
01539
if (phkCall->
flags &
HF_HOOKFAULTED) {
01540
PHOOK phkFault;
01541
01542 phkCall =
PhkNextValid(phkCall);
01543 phkFault =
ThreadUnlock(&tlphkCall);
01544
if (phkFault !=
NULL) {
01545
FreeHook(phkFault);
01546 }
01547
01548
continue;
01549 }
01550
01551
01552
01553
01554
01555
ThreadUnlock(&tlphkCall);
01556
01557
return nRet;
01558
01559 }
else if (bHookFlags &
HKF_INTERSENDABLE) {
01560
01561
01562
01563
01564
01565
HOOKMSGSTRUCT hkmp;
01566
int timeout = 200;
01567
01568 hkmp.
lParam = lParam;
01569 hkmp.
phk = phkCall;
01570 hkmp.
nCode = nCode;
01571
01572
01573
01574
01575 phkSave = ptiCurrent->
sphkCurrent;
01576
01577
ThreadLockWithPti(ptiCurrent, phkSave, &tlphkSave);
01578
01579
Lock(&ptiCurrent->
sphkCurrent, phkCall);
01580
if (ptiCurrent->
pClientInfo)
01581 ptiCurrent->
pClientInfo->
phkCurrent = phkCall;
01582
01583
01584
01585
01586
if (bHookFlags &
HKF_LOWLEVEL)
01587 timeout =
gnllHooksTimeout;
01588
01589
01590
01591
01592
01593
01594
if (((bHookFlags &
HKF_LOWLEVEL) == 0) &&
01595 ( (bHookFlags &
HKF_JOURNAL) ||
01596 !(ptiCurrent->
TIF_flags & (
TIF_CSRSSTHREAD |
TIF_SYSTEMTHREAD)))) {
01597
01598 nRet =
xxxInterSendMsgEx(
NULL, WM_HOOKMSG, wParam,
01599 (LPARAM)&hkmp, ptiCurrent,
GETPTI(phkCall),
NULL);
01600 }
else {
01601
01602
01603
01604
01605
01606
INTRSENDMSGEX ism;
01607
01608 ism.
fuCall =
ISM_TIMEOUT;
01609 ism.
fuSend = SMTO_ABORTIFHUNG | SMTO_NORMAL;
01610 ism.
uTimeout = timeout;
01611 ism.
lpdwResult = &nRet;
01612
01613
01614
01615
01616
01617
01618
if ((ptiCurrent->
TIF_flags &
TIF_DOSEMULATOR) ||
01619
FHungApp(
GETPTI(phkCall),
CMSHUNGAPPTIMEOUT) ||
01620 !
xxxInterSendMsgEx(
NULL, WM_HOOKMSG, wParam,
01621 (LPARAM)&hkmp, ptiCurrent,
GETPTI(phkCall), &ism)) {
01622 nRet =
ampiHookError[iHook + 1];
01623 }
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
if ((bHookFlags &
HKF_LOWLEVEL) && nRet) {
01634
SET_TIME_LAST_READ(
GETPTI(phkCall));
01635 }
01636 }
01637
01638
Lock(&ptiCurrent->
sphkCurrent, phkSave);
01639
if (ptiCurrent->
pClientInfo)
01640 ptiCurrent->
pClientInfo->
phkCurrent = phkSave;
01641
01642
ThreadUnlock(&tlphkSave);
01643
ThreadUnlock(&tlphkCall);
01644
return nRet;
01645 }
01646
01647
01648 LoopAgain:
01649 phkCall =
PhkNextValid(phkCall);
01650
ThreadUnlock(&tlphkCall);
01651 }
while (phkCall !=
NULL);
01652
01653
return ampiHookError[iHook + 1];
01654 }
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666 BOOL xxxCallMouseHook(
01667 UINT message,
01668 PMOUSEHOOKSTRUCTEX pmhs,
01669 BOOL fRemove)
01670 {
01671
BOOL bAnsiHook;
01672
01673
01674
01675
01676
if (
xxxCallHook2(
PhkFirstValid(
PtiCurrent(), WH_MOUSE), fRemove ?
01677 HC_ACTION : HC_NOREMOVE, (
DWORD)message, (LPARAM)pmhs, &bAnsiHook)) {
01678
return TRUE;
01679 }
01680
01681
return FALSE;
01682 }
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695 void xxxCallJournalRecordHook(
01696
PQMSG pqmsg)
01697 {
01698 EVENTMSG emsg;
01699
BOOL bAnsiHook;
01700
01701
01702
01703
01704 emsg.message = pqmsg->
msg.message;
01705 emsg.time = pqmsg->
msg.time;
01706
01707
if (
RevalidateHwnd(pqmsg->
msg.hwnd)) {
01708 emsg.hwnd = pqmsg->
msg.hwnd;
01709 }
else {
01710 emsg.hwnd =
NULL;
01711 }
01712
01713
if ((emsg.message >= WM_MOUSEFIRST) && (emsg.message <= WM_MOUSELAST)) {
01714 emsg.paramL = (
UINT)pqmsg->
msg.pt.x;
01715 emsg.paramH = (
UINT)pqmsg->
msg.pt.y;
01716
01717 }
else if ((emsg.message >= WM_KEYFIRST) && (emsg.message <= WM_KEYLAST)) {
01718
BYTE bScanCode =
LOBYTE(HIWORD(pqmsg->
msg.lParam));
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
if ((LOWORD(pqmsg->
msg.wParam) == VK_PACKET) && (bScanCode == 0)) {
01730
01731
01732
01733
01734 emsg.paramL = (
UINT)MAKELONG(pqmsg->
msg.wParam,
PtiCurrent()->wchInjected);
01735 }
else {
01736 emsg.paramL = MAKELONG(MAKEWORD(pqmsg->
msg.wParam, bScanCode),0);
01737 }
01738 emsg.paramH = bScanCode;
01739
01740 UserAssert((emsg.message != WM_CHAR) &&
01741 (emsg.message != WM_DEADCHAR) &&
01742 (emsg.message != WM_SYSCHAR) &&
01743 (emsg.message != WM_SYSDEADCHAR));
01744
01745
01746
01747
if (pqmsg->
msg.lParam & 0x01000000) {
01748 emsg.paramH |= 0x8000;
01749 }
01750
01751 }
else {
01752 RIPMSG2(RIP_WARNING,
01753
"Bad journal record message!\n"
01754
" message = 0x%08lx\n"
01755
" dwQEvent = 0x%08lx",
01756 pqmsg->
msg.message,
01757 pqmsg->
dwQEvent);
01758 }
01759
01760
01761
01762
01763
xxxCallHook2(
PhkFirstGlobalValid(
PtiCurrent(), WH_JOURNALRECORD), HC_ACTION, 0,
01764 (LPARAM)&emsg, &bAnsiHook);
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
if ((pqmsg->
msg.message >= WM_MOUSEFIRST) && (pqmsg->
msg.message <= WM_MOUSELAST)) {
01779 pqmsg->
msg.pt.x = emsg.paramL;
01780 pqmsg->
msg.pt.y = emsg.paramH;
01781
01782 }
else if ((pqmsg->
msg.message >= WM_KEYFIRST) && (pqmsg->
msg.message <= WM_KEYLAST)) {
01783 (
BYTE)pqmsg->
msg.wParam = (
BYTE)emsg.paramL;
01784 ((
PBYTE)&pqmsg->
msg.lParam)[2] =
HIBYTE(LOWORD(emsg.paramL));
01785 }
01786 }
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797 DWORD xxxCallJournalPlaybackHook(
01798
PQMSG pqmsg)
01799 {
01800 EVENTMSG emsg;
01801 LONG
dt;
01802
PWND pwnd;
01803 WPARAM wParam;
01804 LPARAM lParam;
01805 POINT pt;
01806
PTHREADINFO ptiCurrent;
01807
BOOL bAnsiHook;
01808
PHOOK phkCall;
01809
TL tlphkCall;
01810
01811 UserAssert(
IsWinEventNotifyDeferredOK());
01812
01813 TryNextEvent:
01814
01815
01816
01817
01818
01819 emsg.time =
NtGetTickCount();
01820 ptiCurrent =
PtiCurrent();
01821 pwnd =
NULL;
01822
01823 phkCall =
PhkFirstGlobalValid(ptiCurrent, WH_JOURNALPLAYBACK);
01824
ThreadLockWithPti(ptiCurrent, phkCall, &tlphkCall);
01825
01826
dt = (
DWORD)
xxxCallHook2(phkCall, HC_GETNEXT, 0, (LPARAM)&emsg, &bAnsiHook);
01827
01828
01829
01830
01831
if (
dt == 0xFFFFFFFF) {
01832
ThreadUnlock(&tlphkCall);
01833
return dt;
01834 }
01835
01836
01837
01838
01839 pqmsg->
msg.message = emsg.message;
01840
01841
if (
dt > 0) {
01842
if (ptiCurrent->
TIF_flags &
TIF_IGNOREPLAYBACKDELAY) {
01843
01844
01845
01846
01847 RIPMSG1(RIP_WARNING,
"Journal Playback delay ignored (%lx)", emsg.message);
01848 ptiCurrent->
TIF_flags &= ~
TIF_IGNOREPLAYBACKDELAY;
01849
dt = 0;
01850 }
else {
01851
ThreadUnlock(&tlphkCall);
01852
return dt;
01853 }
01854 }
01855
01856
01857
01858
01859
01860
if ((emsg.message >= WM_MOUSEFIRST) && (emsg.message <= WM_MOUSELAST)) {
01861
01862 pt.x = (
int)emsg.paramL;
01863 pt.y = (
int)emsg.paramH;
01864
01865 lParam = MAKELONG(LOWORD(pt.x), LOWORD(pt.y));
01866 wParam = 0;
01867
01868
01869
01870
01871
01872
if (pt.x !=
gpsi->ptCursor.x || pt.y !=
gpsi->ptCursor.y) {
01873
zzzInternalSetCursorPos(pt.x, pt.y);
01874 }
01875
01876 }
else if ((emsg.message >= WM_KEYFIRST) && (emsg.message <= WM_KEYLAST)) {
01877
UINT wExtraStuff = 0;
01878
01879
if ((emsg.message == WM_KEYUP) || (emsg.message == WM_SYSKEYUP)) {
01880 wExtraStuff |= 0x8000;
01881 }
01882
01883
if ((emsg.message == WM_SYSKEYUP) || (emsg.message == WM_SYSKEYDOWN)) {
01884 wExtraStuff |= 0x2000;
01885 }
01886
01887
if (emsg.paramH & 0x8000) {
01888 wExtraStuff |= 0x0100;
01889 }
01890
01891
if (
TestKeyStateDown(ptiCurrent->
pq, (
BYTE)emsg.paramL)) {
01892 wExtraStuff |= 0x4000;
01893 }
01894 lParam = MAKELONG(1, (
UINT)((emsg.paramH & 0xFF) | wExtraStuff));
01895
01896
if ((LOWORD(emsg.paramL) == VK_PACKET) && (
LOBYTE(emsg.paramH) == 0)) {
01897
01898
01899
01900
01901 ptiCurrent->
wchInjected = HIWORD(emsg.paramL);
01902 }
else {
01903
01904
01905
01906
01907
01908
01909
DWORD dwMask = 0xff;
01910
01911
01912
01913
01914
01915
01916
01917
01918
if (!bAnsiHook ||
IS_DBCS_ENABLED()) {
01919
if (
IS_CHAR_MSG(emsg.message)) {
01920 RIPMSG1(RIP_VERBOSE,
"Unusual char message(%x) passed through JournalPlayback.", emsg.message);
01921
01922
01923
01924 dwMask = 0xffff;
01925 }
01926 }
01927
01928 wParam = emsg.paramL & dwMask;
01929 }
01930
01931 }
else if (emsg.message == WM_QUEUESYNC) {
01932
if (emsg.paramL == 0) {
01933 pwnd = ptiCurrent->
pq->
spwndActive;
01934 }
else {
01935
if ((pwnd =
RevalidateHwnd((HWND)IntToPtr( emsg.paramL ))) ==
NULL)
01936 pwnd = ptiCurrent->
pq->
spwndActive;
01937 }
01938
01939 }
else {
01940
01941
01942
01943
01944
01945
if (phkCall ==
NULL || phkCall->
offPfn == 0
L) {
01946
01947
ThreadUnlock(&tlphkCall);
01948
return 0xFFFFFFFF;
01949 }
01950
01951 RIPMSG1(RIP_WARNING,
01952
"Bad journal playback message=0x%08lx",
01953 emsg.message);
01954
01955
xxxCallHook(HC_SKIP, 0, 0, WH_JOURNALPLAYBACK);
01956
ThreadUnlock(&tlphkCall);
01957
goto TryNextEvent;
01958 }
01959
01960
StoreQMessage(pqmsg, pwnd, emsg.message, wParam, lParam, 0, 0, 0);
01961
01962
ThreadUnlock(&tlphkCall);
01963
return 0;
01964 }
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976 VOID FreeHook(
01977
PHOOK phkFree)
01978 {
01979
01980
01981
01982 UserAssert(!(phkFree->
flags & HF_FREED));
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
if (!(phkFree->
flags &
HF_DESTROYED)) {
01994
DbgValidateHooks (phkFree, phkFree->
iHook);
01995 phkFree->
flags |=
HF_DESTROYED;
01996
01997
01998
01999
02000
02001
02002
02003
#if DBG
02004
phkFree->
flags |= HF_INCHECKWHF;
02005
#endif
02006
UserAssert((phkFree->
ptiHooked !=
NULL) || (phkFree->
flags &
HF_GLOBAL));
02007
CheckWHFBits(phkFree->
ptiHooked !=
NULL
02008 ? phkFree->
ptiHooked
02009 :
GETPTI(phkFree),
02010 phkFree->iHook);
02011
#if DBG
02012
phkFree->flags &= ~HF_INCHECKWHF;
02013
#endif
02014
}
02015
02016
02017
02018
02019
if (!
HMMarkObjectDestroy((PVOID)phkFree)) {
02020
return;
02021 }
02022
02023
02024
02025
UnlinkHook(phkFree);
02026
02027
02028
02029
02030
if (phkFree->ihmod >= 0) {
02031
RemoveHmodDependency(phkFree->ihmod);
02032 }
02033
02034
#ifdef HOOKBATCH
02035
02036
02037
02038
if (phkFree->aEventCache) {
02039 UserFreePool(phkFree->aEventCache);
02040 phkFree->aEventCache =
NULL;
02041 }
02042
#endif //HOOKBATCH
02043
02044
#if DBG
02045
phkFree->flags |= HF_FREED;
02046
#endif
02047
02048
HMFreeObject((PVOID)phkFree);
02049
return;
02050 }
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061 void UnlinkHook(
02062
PHOOK phkFree)
02063 {
02064
PHOOK *pphkNext;
02065
PTHREADINFO ptiT;
02066
02067
CheckCritIn();
02068
02069
02070
02071
02072
if (phkFree->
flags &
HF_GLOBAL) {
02073 pphkNext = &
GETPTI(phkFree)->pDeskInfo->aphkStart[phkFree->
iHook + 1];
02074 }
else {
02075 ptiT = phkFree->
ptiHooked;
02076
if (ptiT ==
NULL) {
02077
02078
02079
02080
return;
02081 }
else {
02082
02083
02084
02085 phkFree->
ptiHooked =
NULL;
02086 }
02087 pphkNext = &(ptiT->
aphkStart[phkFree->
iHook + 1]);
02088
02089
02090
02091 UserAssert(*pphkNext !=
NULL);
02092 }
02093
02094
02095
02096
while ((*pphkNext != phkFree) && (*pphkNext !=
NULL)) {
02097 pphkNext = &(*pphkNext)->
phkNext;
02098 }
02099
02100
02101
02102
02103
if (*pphkNext ==
NULL) {
02104 UserAssert(phkFree->
flags &
HF_GLOBAL);
02105
02106
02107
02108
if (phkFree->
rpdesk !=
NULL) {
02109 UserAssert(
GETPTI(phkFree) ==
gptiRit);
02110 UserAssert(phkFree->
rpdesk !=
NULL);
02111 UserAssert(phkFree->
rpdesk->
pDeskInfo !=
gptiRit->
pDeskInfo);
02112
02113 pphkNext = &phkFree->
rpdesk->
pDeskInfo->
aphkStart[phkFree->
iHook + 1];
02114 }
else {
02115 UserAssert(
GETPTI(phkFree)->pDeskInfo != phkFree->
head.rpdesk->pDeskInfo);
02116 pphkNext = &phkFree->
head.rpdesk->pDeskInfo->aphkStart[phkFree->
iHook + 1];
02117 }
02118
02119 UserAssert(*pphkNext !=
NULL);
02120
while ((*pphkNext != phkFree) && (*pphkNext !=
NULL)) {
02121 pphkNext = &(*pphkNext)->
phkNext;
02122 }
02123 }
02124
02125
02126
02127 UserAssert(*pphkNext == phkFree);
02128
02129
02130
02131 *pphkNext = phkFree->
phkNext;
02132 phkFree->
phkNext =
NULL;
02133
02134
02135
02136
if (phkFree->rpdesk !=
NULL) {
02137 UserAssert(phkFree->flags &
HF_GLOBAL);
02138 UserAssert(
GETPTI(phkFree) ==
gptiRit);
02139
UnlockDesktop(&phkFree->rpdesk, LDU_HOOK_DESK, 0);
02140 }
02141 }
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151 PHOOK PhkFirstGlobalValid(
PTHREADINFO pti,
int nFilterType)
02152 {
02153
PHOOK phk;
02154
02155
CheckCritIn();
02156 phk = pti->
pDeskInfo->
aphkStart[nFilterType + 1];
02157
02158
02159
02160
02161
if ((phk !=
NULL) && (phk->
flags &
HF_DESTROYED)) {
02162 phk =
PhkNextValid(phk);
02163 }
02164
02165
02166
02167
02168
DbgValidatefsHook(phk, nFilterType, pti,
TRUE);
02169
DbgValidateHooks(phk, nFilterType);
02170
return phk;
02171 }
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183 PHOOK PhkFirstValid(
02184
PTHREADINFO pti,
02185
int nFilterType)
02186 {
02187
PHOOK phk;
02188
CheckCritIn();
02189
02190
02191
02192
02193 phk = pti->
aphkStart[nFilterType + 1];
02194
02195
02196
02197
if (phk ==
NULL) {
02198 phk = pti->
pDeskInfo->
aphkStart[nFilterType + 1];
02199 }
02200
02201
02202
02203
02204
if ((phk !=
NULL) && (phk->
flags &
HF_DESTROYED)) {
02205 phk =
PhkNextValid(phk);
02206 }
02207
02208
02209
02210
02211
02212
DbgValidatefsHook(phk, nFilterType, pti,
FALSE);
02213
DbgValidateHooks(phk, nFilterType);
02214
return phk;
02215 }
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227 VOID FreeThreadsWindowHooks(VOID)
02228 {
02229
int iHook;
02230
PHOOK phk, phkNext;
02231
PTHREADINFO ptiCurrent =
PtiCurrent();
02232
02233
02234
02235
02236
if (ptiCurrent ==
NULL || ptiCurrent->
rpdesk ==
NULL) {
02237
return;
02238 }
02239
02240
02241
02242
02243
Unlock(&ptiCurrent->
sphkCurrent);
02244
02245 UserAssert(ptiCurrent->
TIF_flags &
TIF_INCLEANUP);
02246
02247
02248
02249
02250
02251
02252
02253
02254
for (iHook = WH_MIN ; iHook <= WH_MAX ; ++iHook) {
02255
02256
02257
02258
02259
02260 phk = ptiCurrent->
aphkStart[iHook + 1];
02261
if (phk ==
NULL) {
02262 phk = ptiCurrent->
pDeskInfo->
aphkStart[iHook + 1];
02263 UserAssert((phk ==
NULL) || (phk->
flags &
HF_GLOBAL));
02264 }
02265
02266
while (phk !=
NULL) {
02267
02268
02269
02270
02271 phkNext = phk->
phkNext;
02272
if ((phkNext ==
NULL) && !(phk->
flags &
HF_GLOBAL)) {
02273 phkNext = ptiCurrent->
pDeskInfo->
aphkStart[iHook + 1];
02274 UserAssert((phkNext ==
NULL) || (phkNext->
flags &
HF_GLOBAL));
02275 }
02276
02277
02278
02279
02280
02281
02282
if (!(phk->
flags &
HF_GLOBAL)) {
02283 UserAssert(ptiCurrent == phk->
ptiHooked);
02284
UnlinkHook(phk);
02285 phk->
flags |=
HF_DESTROYED;
02286 phk->
phkNext =
NULL;
02287 }
02288
02289
02290
02291
if (
GETPTI(phk) == ptiCurrent) {
02292
FreeHook(phk);
02293 }
02294
02295 phk = phkNext;
02296 }
02297
02298
02299
02300 UserAssert(ptiCurrent->
aphkStart[iHook + 1] ==
NULL);
02301 }
02302
02303
02304
02305
02306 ptiCurrent->
fsHooks = 0;
02307 }
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318 VOID zzzRegisterSystemThread (DWORD dwFlags, DWORD dwReserved)
02319 {
02320
PTHREADINFO ptiCurrent;
02321
02322 UserAssert(dwReserved == 0);
02323
02324
if (dwReserved != 0)
02325
return;
02326
02327 ptiCurrent =
PtiCurrent();
02328
02329
if (
dwFlags & RST_DONTATTACHQUEUE)
02330 ptiCurrent->
TIF_flags |=
TIF_DONTATTACHQUEUE;
02331
02332
if (
dwFlags & RST_DONTJOURNALATTACH) {
02333 ptiCurrent->
TIF_flags |=
TIF_DONTJOURNALATTACH;
02334
02335
02336
02337
02338
02339
02340
if (
FJOURNALPLAYBACK() ||
FJOURNALRECORD()) {
02341
zzzJournalAttach(ptiCurrent,
FALSE);
02342
zzzJournalAttach(ptiCurrent,
TRUE);
02343 }
02344 }
02345 }
02346
02347
#ifdef REDIRECTION
02348
02349
02350
02351
02352
02353
02354
BOOL
02355 xxxGetCursorPos(
02356 LPPOINT lpPt)
02357 {
02358 POINT pt;
02359
02360
CheckCritIn();
02361
02362
02363
02364
02365
if (!
IsHooked(
PtiCurrent(), WHF_CBT))
02366
return TRUE;
02367
02368
try {
02369
ProbeForWrite(lpPt,
sizeof(RECT), DATAALIGN);
02370 RtlCopyMemory(&pt, lpPt,
sizeof(RECT));
02371 } except (W32ExceptionHandler(FALSE, RIP_WARNING)) {
02372
return FALSE;
02373 }
02374
02375
xxxCallHook(HCBT_GETCURSORPOS, 0, (LPARAM)&pt, WH_CBT);
02376
02377
try {
02378 RtlCopyMemory(lpPt, &pt,
sizeof(RECT));
02379 } except (W32ExceptionHandler(FALSE, RIP_WARNING)) {
02380
return FALSE;
02381 }
02382
02383
return TRUE;
02384 }
02385
02386
#endif // REDIRECTION
02387