00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#include "precomp.h"
00021
#pragma hdrstop
00022
00023
#if DBG
00024
int gnNotifies = 0;
00025
#define DBGVERIFYEVENTHOOK(peh) \
00026
HMValidateCatHandleNoSecure(PtoH(peh), TYPE_WINEVENTHOOK); \
00027
UserAssertMsg1((IsValidTag(peh, TAG_WINEVENT)), "event hook %#p: bad tag", peh); \
00028
UserAssertMsg1((peh->eventMin <= peh->eventMax), "event hook %#p: bad range", peh)
00029
#define DBGVERIFYNOTIFY(pNotify) \
00030
UserAssert(pNotify->spEventHook != NULL); \
00031
UserAssert(pNotify->spEventHook->fSync || (pNotify->dwWEFlags & WEF_ASYNC))
00032
#else
00033 #define DBGVERIFYEVENTHOOK(peh)
00034 #define DBGVERIFYNOTIFY(pNotify)
00035
#endif
00036
00037
00038
00039
00040
00041 static NOTIFY notifyCache;
00042 static BOOL fNotifyCacheInUse =
FALSE;
00043
00044
00045
00046
00047
00048 WINEVENTPROC
xxxGetEventProc(
PEVENTHOOK pEventOrg);
00049
PNOTIFY CreateNotify(
PEVENTHOOK peh, DWORD event,
PWND pwnd, LONG idObject,
00050 LONG idChild,
PTHREADINFO ptiEvent, DWORD dwTime);
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
PEVENTHOOK
00068 xxxProcessNotifyWinEvent(
PNOTIFY pNotify)
00069 {
00070 WINEVENTPROC pfn;
00071
PEVENTHOOK pEventHook;
00072
TL tlpEventHook;
00073
PTHREADINFO ptiCurrent =
PtiCurrent();
00074
00075 pEventHook = pNotify->
spEventHook;
00076
DBGVERIFYEVENTHOOK(pEventHook);
00077 UserAssert(pEventHook->
head.cLockObj);
00078
00079
if (((pNotify->
dwWEFlags & (
WEF_ASYNC |
WEF_POSTED)) ==
WEF_ASYNC)
00080 ||
00081 (ptiCurrent->
TIF_flags & (
TIF_SYSTEMTHREAD |
TIF_CSRSSTHREAD |
TIF_INCLEANUP))
00082
00083 ||
00084 (!
RtlEqualLuid(&
GETPTI(pEventHook)->ppi->luidSession, &ptiCurrent->
ppi->
luidSession) &&
00085 !(ptiCurrent->
TIF_flags &
TIF_ALLOWOTHERACCOUNTHOOK))
00086
00087 ||
00088 (
GETPTI(pEventHook)->ppi != ptiCurrent->
ppi &&
00089
IsRestricted(
GETPTI(pEventHook)->pEThread))
00090
00091
#if defined(_WIN64)
00092
||
00093 ((
GETPTI(pEventHook)->TIF_flags &
TIF_WOW64) != (ptiCurrent->
TIF_flags &
TIF_WOW64))
00094
#endif
00095
) {
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
PQ pqReceiver =
GETPTI(pEventHook)->pq;
00115
PEVENTHOOK pEventHookNext = pEventHook->
pehNext;
00116
00117
BEGINATOMICCHECK();
00118
00119
DBGVERIFYNOTIFY(pNotify);
00120 pNotify->
dwWEFlags |=
WEF_POSTED |
WEF_ASYNC;
00121
if (!pqReceiver || (
GETPTI(pEventHook) ==
gptiRit) ||
00122 pEventHook->
fDestroyed ||
00123 !
PostEventMessage(
GETPTI(pEventHook), pqReceiver,
00124
QEVENT_NOTIFYWINEVENT,
00125
NULL, 0, 0, (LPARAM)pNotify)) {
00126
00127
00128
00129
00130
00131
00132 RIPMSG2(RIP_WARNING,
"failed to post NOTIFY at %#p, time %lx\n",
00133 pNotify, pNotify->dwEventTime);
00134
DestroyNotify(pNotify);
00135 }
00136
00137
ENDATOMICCHECK();
00138
00139
if (pEventHookNext) {
00140
DBGVERIFYEVENTHOOK(pEventHookNext);
00141 }
00142
return pEventHookNext;
00143 }
00144
00145
00146
00147
00148
if (pEventHook->
fDestroyed) {
00149
00150
00151
00152
00153 pEventHook = pEventHook->
pehNext;
00154
DestroyNotify(pNotify);
00155
return pEventHook;
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165 UserAssert((pNotify->
dwWEFlags &
WEF_DEFERNOTIFY) == 0);
00166
00167
ThreadLockAlways(pEventHook, &tlpEventHook);
00168
00169 UserAssertMsg1(pNotify->
ptiReceiver ==
NULL,
00170
"pNotify %#p is already in callback! Reentrant?", pNotify);
00171 pNotify->
ptiReceiver = ptiCurrent;
00172
00173
if (!pEventHook->
fSync) {
00174 UserAssert(pEventHook->
ihmod == -1);
00175 pfn = (WINEVENTPROC)pEventHook->
offPfn;
00176 }
else {
00177 pfn =
xxxGetEventProc(pEventHook);
00178 }
00179
if (pfn) {
00180
xxxClientCallWinEventProc(pfn, pEventHook, pNotify);
00181
DBGVERIFYNOTIFY(pNotify);
00182
DBGVERIFYEVENTHOOK(pEventHook);
00183 UserAssert(pEventHook->
head.cLockObj);
00184 }
00185
00186 pNotify->
ptiReceiver =
NULL;
00187
00188
00189
00190
00191
00192
00193 pEventHook = pEventHook->
pehNext;
00194
ThreadUnlock(&tlpEventHook);
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
DestroyNotify(pNotify);
00206
00207
return pEventHook;
00208 }
00209
00210
00211
00212
00213
00214
00215
00216
VOID
00217 xxxFlushDeferredWindowEvents()
00218 {
00219
PNOTIFY pNotify;
00220
DWORD idCurrentThread = W32GetCurrentTID();
00221
00222
if (idCurrentThread == 0) {
00223 RIPMSG0(RIP_ERROR,
"processing deferred notifications before we have a pti!");
00224
00225 }
00226
00227 UserAssert(
IsWinEventNotifyDeferredOK());
00228
00229 pNotify =
gpPendingNotifies;
00230
while (pNotify) {
00231
if (((pNotify->
dwWEFlags &
WEF_DEFERNOTIFY) == 0) ||
00232 (pNotify->
idSenderThread != idCurrentThread)) {
00233
00234 pNotify = pNotify->
pNotifyNext;
00235 }
else {
00236
00237
00238
00239
00240 pNotify->
dwWEFlags &= ~
WEF_DEFERNOTIFY;
00241
#if DBG
00242
gnDeferredWinEvents--;
00243
#endif
00244
00245
00246
00247
00248 UserAssert((pNotify->
dwWEFlags &
WEF_ASYNC) == 0);
00249
xxxProcessNotifyWinEvent(pNotify);
00250
00251
00252
00253
00254 pNotify =
gpPendingNotifies;
00255 }
00256 }
00257 }
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
VOID
00274 xxxWindowEvent(
00275 DWORD event,
00276
PWND pwnd,
00277 LONG idObject,
00278 LONG idChild,
00279 DWORD dwFlags)
00280 {
00281
PEVENTHOOK peh;
00282
PEVENTHOOK pehNext;
00283
PTHREADINFO ptiCurrent, ptiEvent;
00284
DWORD dwTime;
00285
PPROCESSINFO ppiEvent;
00286
DWORD idEventThread;
00287 HANDLE hEventProcess;
00288
PNOTIFY pNotify;
00289
TL tlpwnd;
00290
TL tlpti;
00291
00292
00293
00294
00295 UserAssert(
FWINABLE());
00296
00297
00298
00299
00300
00301
00302
if (
gptiCurrent ==
NULL) {
00303 RIPMSG3(RIP_WARNING,
"Ignore WinEvent %lx %#p %lx... no PtiCurrent yet",
00304 event, pwnd, idObject);
00305
return;
00306 }
00307 ptiCurrent =
PtiCurrent();
00308
00309
00310
00311
00312
if (pwnd &&
TestWF(pwnd,
WFDESTROYED)) {
00313 RIPMSG3(RIP_WARNING,
00314
"Ignore WinEvent %lx %#p %lx... pwnd already destroyed",
00315 event, pwnd, idObject);
00316
return;
00317 }
00318
00319
00320
00321
00322
if (ptiCurrent->
TIF_flags & (
TIF_DISABLEHOOKS |
TIF_INCLEANUP)) {
00323
dwFlags |=
WEF_DEFERNOTIFY;
00324 }
00325
00326
00327
00328
00329
if ((
dwFlags &
WEF_USEPWNDTHREAD) && pwnd) {
00330 ptiEvent =
GETPTI(pwnd);
00331 }
else {
00332 ptiEvent = ptiCurrent;
00333 }
00334 idEventThread =
TIDq(ptiEvent);
00335 ppiEvent = ptiEvent->
ppi;
00336 hEventProcess = ptiEvent->pEThread->Cid.UniqueProcess;
00337
00338 dwTime =
NtGetTickCount();
00339
00340
ThreadLockWithPti(ptiCurrent, pwnd, &tlpwnd);
00341
ThreadLockPti(ptiCurrent, ptiEvent, &tlpti);
00342
00343
00344
00345
00346
00347
if (!(
dwFlags &
WEF_DEFERNOTIFY)) {
00348
xxxFlushDeferredWindowEvents();
00349 }
00350
00351
for (peh =
gpWinEventHooks; peh; peh = pehNext) {
00352
DBGVERIFYEVENTHOOK(peh);
00353 pehNext = peh->
pehNext;
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
if (!peh->
fDestroyed &&
00364 (peh->
eventMin <= event) &&
00365 (event <= peh->
eventMax) &&
00366 (!peh->
hEventProcess || (peh->
hEventProcess == hEventProcess)) &&
00367 (!peh->
fIgnoreOwnProcess || (ppiEvent !=
GETPTI(peh)->ppi)) &&
00368 (!peh->
idEventThread || (peh->
idEventThread == idEventThread)) &&
00369 (!peh->
fIgnoreOwnThread || (ptiEvent !=
GETPTI(peh))) &&
00370
00371
00372 (peh->
head.
pti->
rpdesk == ptiCurrent->
rpdesk))
00373 {
00374
00375
00376
00377
00378
00379
if (
HMIsMarkDestroy(peh)) {
00380
break;
00381 }
00382
00383 UserAssert(peh->
fDestroyed == 0);
00384
00385
if ((pNotify =
CreateNotify(peh, event, pwnd, idObject,
00386 idChild, ptiEvent, dwTime)) ==
NULL) {
00387
break;
00388 }
00389 pNotify->
dwWEFlags |=
dwFlags;
00390
00391
00392
00393
00394
if (pNotify->
dwWEFlags &
WEF_ASYNC) {
00395 pNotify->
dwWEFlags &= ~
WEF_DEFERNOTIFY;
00396 }
00397
00398
if (pNotify->
dwWEFlags &
WEF_DEFERNOTIFY) {
00399
#if DBG
00400
gnDeferredWinEvents++;
00401
#endif
00402
DBGVERIFYNOTIFY(pNotify);
00403 }
else {
00404 pehNext =
xxxProcessNotifyWinEvent(pNotify);
00405 }
00406 }
00407 }
00408
00409
ThreadUnlockPti(ptiCurrent, &tlpti);
00410
ThreadUnlock(&tlpwnd);
00411 }
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
PNOTIFY
00425 CreateNotify(
PEVENTHOOK pEvent, DWORD event,
PWND pwnd, LONG idObject,
00426 LONG idChild,
PTHREADINFO ptiSender, DWORD dwTime)
00427 {
00428
PNOTIFY pNotify;
00429 UserAssert(pEvent !=
NULL);
00430
00431
00432
00433
00434
00435
if (!
fNotifyCacheInUse) {
00436
fNotifyCacheInUse =
TRUE;
00437 pNotify = &
notifyCache;
00438
#if DBG
00439
00440
00441
00442
00443
#endif
00444
}
else {
00445 pNotify = (
PNOTIFY)UserAllocPool(
sizeof(
NOTIFY), TAG_NOTIFY);
00446
if (!pNotify)
00447
return NULL;
00448 }
00449
00450
00451
00452
00453
00454 pNotify->
spEventHook =
NULL;
00455
Lock(&pNotify->
spEventHook, pEvent);
00456 pNotify->
hwnd =
HW(pwnd);
00457 pNotify->
event = event;
00458 pNotify->
idObject = idObject;
00459 pNotify->
idChild = idChild;
00460 pNotify->
idSenderThread =
TIDq(ptiSender);
00461 UserAssert(pNotify->
idSenderThread != 0);
00462 pNotify->
dwEventTime = dwTime;
00463 pNotify->
dwWEFlags = pEvent->
fSync ? 0 :
WEF_ASYNC;
00464 pNotify->
pNotifyNext =
NULL;
00465 pNotify->
ptiReceiver =
NULL;
00466
#if DBG
00467
gnNotifies++;
00468
#endif
00469
00470
00471
00472
00473
00474
00475
if (
gpPendingNotifies) {
00476 UserAssert(
gpLastPendingNotify);
00477 UserAssert(
gpLastPendingNotify->
pNotifyNext ==
NULL);
00478
gpLastPendingNotify->
pNotifyNext = pNotify;
00479 }
else {
00480
gpPendingNotifies = pNotify;
00481 }
00482
gpLastPendingNotify = pNotify;
00483
00484
return pNotify;
00485 }
00486
00487
00488
00489
00490
00491
00492
00493
00494
VOID
00495 RemoveNotify(
PNOTIFY *ppNotify)
00496 {
00497
PNOTIFY pNotifyRemove;
00498
00499 pNotifyRemove = *ppNotify;
00500
00501
00502
00503
00504 *ppNotify = pNotifyRemove->
pNotifyNext;
00505
00506
#if DBG
00507
if (pNotifyRemove->
dwWEFlags &
WEF_DEFERNOTIFY) {
00508 UserAssert(gnDeferredWinEvents > 0);
00509 gnDeferredWinEvents--;
00510 }
00511
#endif
00512
if (*ppNotify ==
NULL) {
00513
00514
00515
00516
00517
if (
gpPendingNotifies ==
NULL) {
00518
gpLastPendingNotify =
NULL;
00519 }
else {
00520
gpLastPendingNotify = CONTAINING_RECORD(ppNotify,
NOTIFY, pNotifyNext);
00521 }
00522 }
00523 UserAssert((
gpPendingNotifies == 0) || (
gpPendingNotifies > (
PNOTIFY)100));
00524
00525
DBGVERIFYEVENTHOOK(pNotifyRemove->
spEventHook);
00526
00527
00528
00529
00530
Unlock(&pNotifyRemove->
spEventHook);
00531
00532
00533
00534
00535
00536
if (pNotifyRemove == &
notifyCache) {
00537 UserAssert(
fNotifyCacheInUse);
00538
fNotifyCacheInUse =
FALSE;
00539 }
else {
00540 UserFreePool(pNotifyRemove);
00541 }
00542
#if DBG
00543
UserAssert(gnNotifies > 0);
00544 gnNotifies--;
00545
#endif
00546
}
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
VOID
00566 DestroyNotify(
PNOTIFY pNotifyDestroy)
00567 {
00568
PNOTIFY *ppNotify;
00569
PNOTIFY pNotifyT;
00570
00571
DBGVERIFYNOTIFY(pNotifyDestroy);
00572
00573
00574
00575
00576
00577
00578
00579 UserAssert((pNotifyDestroy->
ptiReceiver ==
NULL) ||
00580 (pNotifyDestroy->
ptiReceiver ==
PtiCurrent()));
00581
00582 ppNotify = &
gpPendingNotifies;
00583
while (pNotifyT = *ppNotify) {
00584
if (pNotifyT == pNotifyDestroy) {
00585
RemoveNotify(ppNotify);
00586
return;
00587 }
else {
00588 ppNotify = &pNotifyT->
pNotifyNext;
00589 }
00590 }
00591 RIPMSG1(RIP_ERROR,
"DestroyNotify %#p - not found", pNotifyDestroy);
00592 }
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
VOID
00615 FreeThreadsWinEvents(
PTHREADINFO pti)
00616 {
00617
PEVENTHOOK peh, pehNext;
00618
PNOTIFY pn, pnNext;
00619
DWORD idCurrentThread = W32GetCurrentTID();
00620
00621
00622
00623
00624
for (pn =
gpPendingNotifies; pn; pn = pnNext) {
00625 pnNext = pn->
pNotifyNext;
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
if ((pn->
idSenderThread == idCurrentThread &&
00636 pn->
ptiReceiver ==
NULL) || (pn->
ptiReceiver == pti)) {
00637
if ((pn->
dwWEFlags &
WEF_ASYNC) == 0) {
00638 UserAssert((pn->
dwWEFlags &
WEF_POSTED) == 0);
00639
DestroyNotify(pn);
00640 }
00641 }
00642 }
00643
00644 peh =
gpWinEventHooks;
00645
while (peh) {
00646 pehNext = peh->
pehNext;
00647
if (
GETPTI(peh) == pti) {
00648
DestroyEventHook(peh);
00649 }
00650 peh = pehNext;
00651 }
00652
00653
00654
00655
00656
00657 }
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
PEVENTHOOK
00674 _SetWinEventHook(
00675 DWORD eventMin,
00676 DWORD eventMax,
00677 HMODULE hmodWinEventProc,
00678 PUNICODE_STRING pstrLib,
00679 WINEVENTPROC pfnWinEventProc,
00680 HANDLE hEventProcess,
00681 DWORD idEventThread,
00682 DWORD dwFlags)
00683 {
00684
PEVENTHOOK pEventNew;
00685
PTHREADINFO ptiCurrent;
00686
00687
int ihmod;
00688
00689 ptiCurrent =
PtiCurrent();
00690
00691
00692
00693
00694
if (ptiCurrent->
TIF_flags &
TIF_INCLEANUP) {
00695 RIPMSG1(RIP_ERROR,
"SetWinEventHook: Fail call - thread %#p in cleanup", ptiCurrent);
00696
return NULL;
00697 }
00698
00699
00700
00701
00702
if (pfnWinEventProc ==
NULL) {
00703 RIPERR0(ERROR_INVALID_FILTER_PROC, RIP_VERBOSE,
"pfnWinEventProc == NULL");
00704
return NULL;
00705 }
00706
00707
if (eventMin > eventMax) {
00708 RIPERR0(ERROR_INVALID_HOOK_FILTER, RIP_VERBOSE,
"eventMin > eventMax");
00709
return NULL;
00710 }
00711
00712
if (
dwFlags & WINEVENT_INCONTEXT) {
00713
00714
00715
00716
if (hmodWinEventProc ==
NULL) {
00717 RIPERR0(ERROR_HOOK_NEEDS_HMOD, RIP_VERBOSE,
"");
00718
return NULL;
00719 }
else if (pstrLib ==
NULL) {
00720
00721
00722
00723 RIPERR1(ERROR_DLL_NOT_FOUND, RIP_ERROR,
00724
"hmod %#p, but no lib name", hmodWinEventProc);
00725
return NULL;
00726 }
00727 ihmod =
GetHmodTableIndex(pstrLib);
00728
if (ihmod == -1) {
00729 RIPERR0(ERROR_MOD_NOT_FOUND, RIP_VERBOSE,
"");
00730
return NULL;
00731 }
00732 }
else {
00733 ihmod = -1;
00734 hmodWinEventProc = 0;
00735 }
00736
00737
00738
00739
00740
if (idEventThread != 0) {
00741
PTHREADINFO ptiT;
00742
00743 ptiT =
PtiFromThreadId(idEventThread);
00744
if ((ptiT ==
NULL) ||
00745 !(ptiT->
TIF_flags &
TIF_GUITHREADINITIALIZED)) {
00746 RIPERR1(ERROR_INVALID_THREAD_ID, RIP_VERBOSE,
"pti %#p", ptiT);
00747
return NULL;
00748 }
00749 }
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766 pEventNew = (
PEVENTHOOK)
HMAllocObject(ptiCurrent,
NULL,
00767
TYPE_WINEVENTHOOK,
sizeof(
EVENTHOOK));
00768
if (!pEventNew)
00769
return NULL;
00770
00771
00772
00773
00774 pEventNew->
eventMin = (
UINT)eventMin;
00775 pEventNew->
eventMax = (
UINT)eventMax;
00776
00777
00778 pEventNew->
fIgnoreOwnThread = ((
dwFlags & WINEVENT_SKIPOWNTHREAD) != 0);
00779 pEventNew->
fIgnoreOwnProcess = ((
dwFlags & WINEVENT_SKIPOWNPROCESS) != 0);
00780 pEventNew->
fDestroyed =
FALSE;
00781 pEventNew->
fSync = ((
dwFlags & WINEVENT_INCONTEXT) != 0);
00782
00783 pEventNew->
hEventProcess = hEventProcess;
00784 pEventNew->
idEventThread = idEventThread;
00785
00786
00787 pEventNew->
ihmod = ihmod;
00788
00789
00790
00791
00792
00793
if (pEventNew->
ihmod >= 0) {
00794
AddHmodDependency(pEventNew->
ihmod);
00795 }
00796
00797
00798
00799
00800
00801 pEventNew->
offPfn = ((ULONG_PTR)pfnWinEventProc) - ((ULONG_PTR)hmodWinEventProc);
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811 pEventNew->
pehNext =
gpWinEventHooks;
00812
gpWinEventHooks = pEventNew;
00813
SET_SRVIF(
SRVIF_WINEVENTHOOKS);
00814
00815
return pEventNew;
00816 }
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
BOOL
00827 _UnhookWinEvent(
PEVENTHOOK pEventUnhook)
00828 {
00829
DBGVERIFYEVENTHOOK(pEventUnhook);
00830
00831
if (
HMIsMarkDestroy(pEventUnhook) || (
GETPTI(pEventUnhook) !=
PtiCurrent())) {
00832
00833
00834
00835
00836
00837
00838
00839 RIPERR0(ERROR_INVALID_HANDLE, RIP_WARNING,
"_UnhookWinEvent: Invalid event hook");
00840
return FALSE;
00841 }
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
DestroyEventHook(pEventUnhook);
00855
00856
return TRUE;
00857 }
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
VOID
00879 DestroyEventHook(
PEVENTHOOK pEventDestroy)
00880 {
00881
PEVENTHOOK *ppEvent;
00882
PEVENTHOOK pEventT;
00883
00884
DBGVERIFYEVENTHOOK(pEventDestroy);
00885 UserAssert(
gpWinEventHooks);
00886
00887
00888
00889
00890
00891
00892 pEventDestroy->
fDestroyed =
TRUE;
00893
00894
00895
00896
00897
if (!
HMMarkObjectDestroy(pEventDestroy))
00898
return;
00899
00900
00901
00902
00903
for (ppEvent = &
gpWinEventHooks; pEventT = *ppEvent; ppEvent = &pEventT->
pehNext) {
00904
if (pEventT == pEventDestroy) {
00905 *ppEvent = pEventDestroy->
pehNext;
00906
break;
00907 }
00908 }
00909 UserAssert(pEventT);
00910
SET_OR_CLEAR_SRVIF(
SRVIF_WINEVENTHOOKS,
gpWinEventHooks);
00911
00912
00913
00914
00915
if (pEventDestroy->
ihmod >= 0) {
00916
RemoveHmodDependency(pEventDestroy->
ihmod);
00917 }
00918
00919
00920
00921
00922
HMFreeObject(pEventDestroy);
00923
00924
return;
00925 }
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935 WINEVENTPROC
00936 xxxGetEventProc(
PEVENTHOOK pEventOrg) {
00937
PTHREADINFO ptiCurrent;
00938
00939 UserAssert(pEventOrg);
00940 UserAssert(pEventOrg->
fSync);
00941 UserAssert(pEventOrg->
ihmod >= 0);
00942 UserAssert(pEventOrg->
offPfn != 0);
00943
00944
CheckLock(pEventOrg);
00945
00946
00947
00948
00949
00950
if (
HMIsMarkDestroy(pEventOrg)) {
00951
return NULL;
00952 }
00953
00954 ptiCurrent =
PtiCurrent();
00955
00956
00957
00958
00959
00960
if ((pEventOrg->
ihmod != -1) &&
00961 (
TESTHMODLOADED(ptiCurrent, pEventOrg->
ihmod) == 0)) {
00962
00963
00964
00965
00966
00967
00968
if (
xxxLoadHmodIndex(pEventOrg->
ihmod,
FALSE) ==
NULL) {
00969
return NULL;
00970 }
00971 }
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
if (
HMIsMarkDestroy(pEventOrg)) {
00987
return NULL;
00988 }
00989
00990
return (WINEVENTPROC)
PFNHOOK(pEventOrg);
00991 }