00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
#include "precomp.h"
00015
#include "pnp.h"
00016
#pragma hdrstop
00017
00018 #define IsASwitchWnd( pw ) \
00019
(gpsi->atomSysClass[ICLS_SWITCH] == pw->pcls->atomClassName)
00020
00021 #define IsOleMainThreadWnd( pw ) \
00022
(gaOleMainThreadWndClass == pw->pcls->atomClassName)
00023
00024
VOID UnlinkSendListSms(PSMS, PSMS *);
00025
VOID ReceiverDied(PSMS, PSMS *);
00026
VOID SenderDied(PSMS, PSMS *);
00027
NTSTATUS InitSMSLookaside(VOID);
00028
00029
#pragma alloc_text(INIT, InitSMSLookaside)
00030
00031
00032
00033
00034 PPAGED_LOOKASIDE_LIST SMSLookaside;
00035
00036
#ifdef DEBUG_SMS
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
void ValidateSmsSendLists(PSMS psms)
00047 {
00048
PSMS psmsT2;
00049
PSMS psmsT3;
00050
00051
00052
00053
00054
if (psms !=
NULL) {
00055
for (psmsT2 =
gpsmsList; psmsT2 !=
NULL; psmsT2 = psmsT2->psmsNext) {
00056
if (psmsT2 == psms)
00057
break;
00058 }
00059
00060 UserAssertMsg1(psmsT2 !=
NULL,
"sms %x is not on global sms list\n", psms);
00061 }
00062
00063
00064
00065
00066
for (psmsT2 =
gpsmsList; psmsT2 !=
NULL; psmsT2 = psmsT2->psmsNext) {
00067
if (psmsT2->ptiSender !=
NULL) {
00068
for (psmsT3 = psmsT2->psmsSendList; psmsT3 !=
NULL;
00069 psmsT3 = psmsT3->psmsSendNext) {
00070
if (psmsT3 == psmsT2)
00071
break;
00072 }
00073
00074 UserAssertMsg2(psmsT3 !=
NULL,
00075
"sms %x is not on send list %x\n",
00076 psmsT2,
00077 psmsT2->psmsSendList);
00078 }
00079 }
00080 }
00081
#endif
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 #define fBroadcastProc( pwnd ) \
00099
(!(ISAMENU(pwnd) || IsASwitchWnd(pwnd) || IsOleMainThreadWnd(pwnd)))
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 PVOID
StubAllocSMS(
00112 POOL_TYPE PoolType,
00113 SIZE_T uBytes,
00114 ULONG iTag)
00115 {
00116
return UserAllocPool(uBytes, iTag);
00117
00118 UNREFERENCED_PARAMETER(PoolType);
00119 }
00120
00121 VOID StubFreeSMS(
00122 PVOID p)
00123 {
00124 UserFreePool(p);
00125 }
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
NTSTATUS
00137 InitSMSLookaside()
00138 {
00139
SMSLookaside = UserAllocPoolNonPaged(
sizeof(
PAGED_LOOKASIDE_LIST), TAG_LOOKASIDE);
00140
if (
SMSLookaside ==
NULL) {
00141
return STATUS_NO_MEMORY;
00142 }
00143
00144
ExInitializePagedLookasideList(
SMSLookaside,
00145
StubAllocSMS,
00146
StubFreeSMS,
00147
POOL_QUOTA_FAIL_INSTEAD_OF_RAISE,
00148
sizeof(
SMS),
00149 TAG_SMS,
00150 8);
00151
00152
return STATUS_SUCCESS;
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 PSMS AllocSMS(
00165 VOID)
00166 {
00167
return ExAllocateFromPagedLookasideList(
SMSLookaside);
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 void FreeSMS(
00179 PSMS psms)
00180 {
00181
ExFreeToPagedLookasideList(
SMSLookaside, psms);
00182 }
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 BOOL _ReplyMessage(
00199 LRESULT lRet)
00200 {
00201
PTHREADINFO ptiCurrent;
00202
PSMS psms;
00203
00204
CheckCritIn();
00205
00206 ptiCurrent =
PtiCurrent();
00207
00208
00209
00210
00211 psms = ptiCurrent->
psmsCurrent;
00212
if (psms ==
NULL)
00213
return FALSE;
00214
00215
00216
00217
00218
if (psms->flags &
SMF_REPLY)
00219
return FALSE;
00220
00221
00222
00223
00224
00225
00226
if (psms->ptiSender !=
NULL) {
00227
00228
00229
00230
00231
00232
00233
00234
00235 psms->lRet = lRet;
00236 psms->flags |=
SMF_REPLY;
00237
00238
00239
00240
00241
00242
SetWakeBit(psms->ptiSender, QS_SMSREPLY);
00243 }
else if (psms->flags &
SMF_CB_REQUEST) {
00244
00245
00246
00247
00248
00249
TL tlpwnd;
00250
INTRSENDMSGEX ism;
00251
00252 psms->flags |=
SMF_REPLY;
00253
00254
if (!(psms->flags &
SMF_SENDERDIED)) {
00255 ism.
fuCall =
ISM_CALLBACK |
ISM_REPLY;
00256
if (psms->flags &
SMF_CB_CLIENT)
00257 ism.
fuCall |=
ISM_CB_CLIENT;
00258 ism.
lpResultCallBack = psms->lpResultCallBack;
00259 ism.
dwData = psms->dwData;
00260 ism.
lRet = lRet;
00261
00262
ThreadLockWithPti(ptiCurrent, psms->spwnd, &tlpwnd);
00263
00264
xxxInterSendMsgEx(psms->spwnd, psms->message, 0
L, 0
L,
00265
NULL, psms->ptiCallBackSender, &ism );
00266
00267
ThreadUnlock(&tlpwnd);
00268 }
00269 }
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
if (psms->ptiSender &&
00280 (psms->ptiSender->TIF_flags &
TIF_16BIT || ptiCurrent->
TIF_flags &
TIF_16BIT)) {
00281
00282
DirectedScheduleTask(ptiCurrent, psms->ptiSender,
FALSE, psms);
00283
if (ptiCurrent->
TIF_flags &
TIF_16BIT && psms->ptiSender->psmsSent == psms) {
00284
xxxSleepTask(
TRUE,
NULL);
00285 }
00286 }
00287
00288
return TRUE;
00289 }
00290
00291
VOID
00292 UserLogError(
00293 PCWSTR pwszError,
00294 ULONG cbError,
00295 NTSTATUS ErrorCode)
00296 {
00297 PIO_ERROR_LOG_PACKET perrLogEntry;
00298
00299
00300
00301
00302 perrLogEntry = (PIO_ERROR_LOG_PACKET)
IoAllocateErrorLogEntry(
gpWin32kDriverObject,
00303 (UCHAR)(cbError +
sizeof(IO_ERROR_LOG_PACKET)));
00304
if (perrLogEntry) {
00305 perrLogEntry->ErrorCode = ErrorCode;
00306
if (cbError) {
00307 perrLogEntry->NumberOfStrings = 1;
00308 perrLogEntry->StringOffset = FIELD_OFFSET(IO_ERROR_LOG_PACKET, DumpData);
00309 RtlCopyMemory(perrLogEntry->DumpData, pwszError, cbError);
00310 }
00311
IoWriteErrorLogEntry(perrLogEntry);
00312 }
00313 }
00314
00315 BOOL xxxSendBSMtoDesktop(
00316
PWND pwndDesk,
00317 UINT message,
00318 WPARAM wParam,
00319 LPARAM lParam,
00320
LPBROADCASTSYSTEMMSGPARAMS pbsmParams)
00321 {
00322
PBWL pbwl;
00323 HWND *phwnd;
00324
PWND pwnd;
00325
TL tlpwnd;
00326
BOOL fReturnValue =
TRUE;
00327
PTHREADINFO ptiCurrent =
PtiCurrent();
00328
BOOL fPrivateMessage = (message >= WM_USER) && (message < MAXINTATOM);
00329
00330
00331
if (fPrivateMessage) {
00332 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING,
"Attempt to broadcast a private message");
00333 }
00334
00335 pbwl =
BuildHwndList(pwndDesk->
spwndChild,
BWL_ENUMLIST,
NULL);
00336
00337
if (pbwl ==
NULL)
00338
return 0;
00339
00340
if (!(pbsmParams->dwFlags & BSF_POSTMESSAGE)) {
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
if((pbsmParams->dwFlags & BSF_ALLOWSFW) &&
00351 (
GETPDESK(pwndDesk) ==
grpdeskRitInput) &&
00352 ((ptiCurrent->
TIF_flags &
TIF_CSRSSTHREAD)
00353 ||
CanForceForeground(ptiCurrent->
ppi))) {
00354
glinp.
ptiLastWoken =
NULL;
00355 }
00356
00357 }
00358
00359
for (phwnd = pbwl->
rghwnd; *phwnd != (HWND)1; phwnd++) {
00360
00361
00362
00363
00364
if ((pwnd =
RevalidateHwnd(*phwnd)) ==
NULL)
00365
continue;
00366
00367
if (pbsmParams->dwFlags & BSF_IGNORECURRENTTASK) {
00368
00369
if (
GETPTI(pwnd)->pq == ptiCurrent->
pq)
00370
continue;
00371 }
00372
00373
00374
00375
00376
00377
00378
if (!
fBroadcastProc(pwnd)) {
00379
continue;
00380 }
00381
00382
if (fPrivateMessage &&
TestWF(pwnd,
WFWIN40COMPAT)) {
00383
continue;
00384 }
00385
00386
ThreadLockAlwaysWithPti(ptiCurrent, pwnd, &tlpwnd);
00387
00388
00389
if (pbsmParams->dwFlags & BSF_POSTMESSAGE) {
00390
_PostMessage(pwnd, message, wParam, lParam);
00391 }
else if (pbsmParams->dwFlags & BSF_SENDNOTIFYMESSAGE) {
00392
00393
00394
00395
00396
00397
00398
xxxSendNotifyMessage(pwnd, message, wParam, lParam);
00399 }
else if (pbsmParams->dwFlags & BSF_QUEUENOTIFYMESSAGE) {
00400
00401
00402
00403
00404
00405
00406
QueueNotifyMessage(pwnd, message, wParam, lParam);
00407 }
else {
00408
00409
00410
00411
00412
BOOL fNoHang = (
BOOL)pbsmParams->dwFlags & BSF_NOHANG;
00413
BOOL fForce = (
BOOL)pbsmParams->dwFlags & BSF_FORCEIFHUNG;
00414
DWORD dwTimeout;
00415 ULONG_PTR dwResult = 0;
00416
00417
if (fNoHang)
00418 dwTimeout =
CMSWAITTOKILLTIMEOUT;
00419
else
00420 dwTimeout = 0;
00421
00422
if (
xxxSendMessageTimeout(pwnd, message, wParam, lParam,
00423 (fNoHang ? SMTO_ABORTIFHUNG : SMTO_NORMAL) |
00424 ((pbsmParams->dwFlags & BSF_NOTIMEOUTIFNOTHUNG) ? SMTO_NOTIMEOUTIFNOTHUNG : 0),
00425 dwTimeout, &dwResult)) {
00426
00427
if (pbsmParams->dwFlags & BSF_QUERY) {
00428
00429
if(message == WM_QUERYENDSESSION)
00430 fReturnValue = (dwResult != 0);
00431
else
00432
00433
00434 fReturnValue = (dwResult != BROADCAST_QUERY_DENY);
00435 }
00436 }
else {
00437 fReturnValue = fForce;
00438 }
00439
00440
00441
00442
00443
if (fReturnValue == 0) {
00444
if (message == WM_POWERBROADCAST && wParam == PBT_APMQUERYSUSPEND) {
00445 WCHAR wchTask[40];
00446 ULONG cbTask;
00447
00448
00449
00450
00451 cbTask =
GetTaskName(
GETPTI(pwnd), wchTask,
sizeof(wchTask));
00452
UserLogError(wchTask, cbTask, WARNING_POWER_QUERYSUSPEND_CANCELLED);
00453 }
00454
ThreadUnlock(&tlpwnd);
00455
break;
00456 }
00457 }
00458
ThreadUnlock(&tlpwnd);
00459 }
00460
00461
FreeHwndList(pbwl);
00462
00463
return fReturnValue;
00464 }
00465
00466 LONG
xxxSendMessageBSM(
00467
PWND pwnd,
00468 UINT message,
00469 WPARAM wParam,
00470 LPARAM lParam,
00471 LPBROADCASTSYSTEMMSGPARAMS pbsmParams)
00472
00473 {
00474
PTHREADINFO ptiCurrent =
PtiCurrent();
00475 LONG lRet;
00476
00477
if (pbsmParams->dwRecipients & BSM_ALLDESKTOPS) {
00478
PWINDOWSTATION pwinsta;
00479
PDESKTOP pdesk;
00480
TL tlpwinsta;
00481
TL tlpdesk;
00482
00483
00484
00485
00486
00487
ThreadLockWinSta(ptiCurrent,
NULL, &tlpwinsta);
00488
ThreadLockDesktop(ptiCurrent,
NULL, &tlpdesk, LDLT_FN_SENDMESSAGEBSM);
00489
for (pwinsta =
grpWinStaList; pwinsta !=
NULL; ) {
00490
ThreadLockExchangeWinSta(ptiCurrent, pwinsta, &tlpwinsta);
00491
for (pdesk = pwinsta->
rpdeskList; pdesk !=
NULL; ) {
00492
ThreadLockExchangeDesktop(ptiCurrent, pdesk, &tlpdesk, LDLT_FN_SENDMESSAGEBSM);
00493
00494 lRet =
xxxSendBSMtoDesktop(pdesk->
pDeskInfo->
spwnd,
00495 message, wParam, lParam, pbsmParams);
00496
00497
00498
00499
00500
if ((lRet == 0) && (pbsmParams->dwFlags & BSF_QUERY)) {
00501
ThreadUnlockDesktop(ptiCurrent, &tlpdesk, LDUT_FN_SENDMESSAGEBSM1);
00502
ThreadUnlockWinSta(ptiCurrent, &tlpwinsta);
00503
return 0;
00504 }
00505 pdesk = pdesk->
rpdeskNext;
00506 }
00507 pwinsta = pwinsta->
rpwinstaNext;
00508 }
00509
ThreadUnlockDesktop(ptiCurrent, &tlpdesk, LDUT_FN_SENDMESSAGEBSM2);
00510
ThreadUnlockWinSta(ptiCurrent, &tlpwinsta);
00511
00512
00513
00514
00515
if (message == WM_POWERBROADCAST && !
gbRemoteSession) {
00516
LeaveCrit();
00517
00518
00519
00520
00521
if ((wParam == PBT_APMQUERYSUSPEND) ||
00522 (wParam == PBT_APMQUERYSTANDBY)) {
00523 lRet =
IoPnPDeliverServicePowerNotification((ULONG)wParam,
TRUE);
00524 }
else {
00525 lRet =
IoPnPDeliverServicePowerNotification((ULONG)wParam,
FALSE);
00526
00527 }
00528
EnterCrit();
00529 }
00530
00531 }
else {
00532 lRet =
xxxSendBSMtoDesktop(pwnd, message, wParam, lParam,
00533 pbsmParams);
00534 }
00535
00536
return lRet;
00537 }
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556 LRESULT
xxxSendMessageFF(
00557
PWND pwnd,
00558 UINT message,
00559 WPARAM wParam,
00560 LPARAM lParam,
00561 ULONG_PTR xParam)
00562 {
00563 DBG_UNREFERENCED_PARAMETER(pwnd);
00564
00565
00566
00567
00568
00569
00570
00571
if (xParam != 0
L) {
00572
00573
00574
00575
return xxxSendMessageEx(
PWND_BROADCAST, message, wParam, lParam, xParam);
00576 }
else {
00577
00578
00579
00580
return xxxSendMessageTimeout(
PWND_BROADCAST, message, wParam,
00581 lParam, SMTO_NORMAL, 0,
NULL );
00582 }
00583 }
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609 LRESULT
xxxSendMessageEx(
00610
PWND pwnd,
00611 UINT message,
00612 WPARAM wParam,
00613 LPARAM lParam,
00614 ULONG_PTR xParam)
00615 {
00616
00617
00618
00619
00620
00621
if (xParam != 0
L) {
00622 LRESULT lRet;
00623 LRESULT lResult;
00624
NTSTATUS Status;
00625
SNDMSGTIMEOUT smto;
00626
PETHREAD Thread =
PsGetCurrentThread();
00627
00628
if (Thread ==
NULL)
00629
return FALSE;
00630
00631
00632
00633
00634
try {
00635
ProbeForWrite((PVOID)xParam,
sizeof(smto),
sizeof(ULONG));
00636 smto = *(
SNDMSGTIMEOUT *)xParam;
00637
Status = STATUS_SUCCESS;
00638 } except (W32ExceptionHandler(
FALSE, RIP_WARNING)) {
00639
Status = GetExceptionCode();
00640 }
00641
if ( !
NT_SUCCESS(
Status) ) {
00642
return FALSE;
00643 }
00644
00645 lRet =
xxxSendMessageTimeout(pwnd, message, wParam, lParam,
00646 smto.
fuFlags, smto.
uTimeout, &lResult );
00647
00648
00649
00650
00651 smto.
lSMTOResult = lResult;
00652 smto.
lSMTOReturn = lRet;
00653
00654
try {
00655 *(
SNDMSGTIMEOUT *)xParam = smto;
00656 } except (W32ExceptionHandler(
FALSE, RIP_WARNING)) {
00657 lResult =
FALSE;
00658 }
00659
00660
00661
00662
00663
return lResult;
00664 }
00665
00666
return xxxSendMessageTimeout(pwnd, message, wParam,
00667 lParam, SMTO_NORMAL, 0,
NULL );
00668 }
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688 LRESULT
xxxSendMessage(
00689
PWND pwnd,
00690 UINT message,
00691 WPARAM wParam,
00692 LPARAM lParam)
00693 {
00694
return xxxSendMessageTimeout( pwnd, message, wParam, lParam,
00695 SMTO_NORMAL, 0,
NULL );
00696 }
00697
00698
00699
00700
00701
00702
00703
00704
00705 #define XXXSENDMESSAGETOCLIENT(pwnd, message, wParam, lParam, psms, fLock) \
00706
{ \
00707
00708
00709
00710
00711 \
00712 DWORD dwSCMSFlags = TestWF((pwnd), WFANSIPROC) ? SCMS_FLAGS_ANSI : 0; \
00713 WORD fnid = GETFNID((pwnd)); \
00714 if ((fnid >= FNID_CONTROLSTART && fnid <= FNID_CONTROLEND) && \
00715 ((ULONG_PTR)(pwnd)->lpfnWndProc == FNID_TO_CLIENT_PFNW(fnid) || \
00716 (ULONG_PTR)(pwnd)->lpfnWndProc == FNID_TO_CLIENT_PFNA(fnid))) { \
00717 PWNDMSG pwm = &gSharedInfo.awmControl[fnid - FNID_START] ; \
00718
00719
00720
00721 \
00722 if (pwm->abMsgs && (((message) > pwm->maxMsgs) || \
00723 !((pwm->abMsgs)[(message) / 8] & (1 << ((message) & 7))))) { \
00724
00725
00726
00727
00728
00729
00730 \
00731 if (TestWF((pwnd), WFDIALOGWINDOW)) { \
00732 lRet = ScSendMessageSMS((pwnd), (message), (wParam), (lParam), \
00733 dwSCMSFlags, (PROC)(FNID_TO_CLIENT_PFNWORKER(fnid)), \
00734 dwSCMSFlags, (psms)); \
00735 } else { \
00736 TL tlpwnd; \
00737 if (fLock) { \
00738 ThreadLock((pwnd), &tlpwnd); \
00739 } \
00740 lRet = xxxDefWindowProc((pwnd), (message), (wParam), (lParam)); \
00741 if (fLock) { \
00742 ThreadUnlock(&tlpwnd); \
00743 } \
00744 } \
00745 } else { \
00746 lRet = ScSendMessageSMS((pwnd), (message), (wParam), (lParam), \
00747 dwSCMSFlags, (PROC)(FNID_TO_CLIENT_PFNWORKER(fnid)), \
00748 dwSCMSFlags, (psms)); \
00749 } \
00750 } else { \
00751 lRet = ScSendMessageSMS((pwnd), (message), (wParam), (lParam), \
00752 (ULONG_PTR)(pwnd)->lpfnWndProc, \
00753 gpsi->apfnClientW.pfnDispatchMessage, dwSCMSFlags, (psms)); \
00754 } \
00755 }
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777 LRESULT
xxxSendMessageTimeout(
00778
PWND pwnd,
00779 UINT message,
00780 WPARAM wParam,
00781 LPARAM lParam,
00782 UINT fuFlags,
00783 UINT uTimeout,
00784 PLONG_PTR lpdwResult)
00785 {
00786 LRESULT lRet;
00787
PTHREADINFO ptiCurrent;
00788 ULONG_PTR uResult;
00789
00790
CheckCritIn();
00791
00792
if (lpdwResult !=
NULL)
00793 *lpdwResult = 0
L;
00794
00795
00796
00797
00798
if (pwnd ==
PWND_BROADCAST) {
00799
BROADCASTMSG bcm;
00800
PBROADCASTMSG pbcm =
NULL;
00801
UINT uCmd =
BMSG_SENDMSG;
00802
00803
if (lpdwResult !=
NULL) {
00804 uCmd =
BMSG_SENDMSGTIMEOUT;
00805 bcm.
to.fuFlags = fuFlags;
00806 bcm.
to.uTimeout = uTimeout;
00807 bcm.
to.lpdwResult = lpdwResult;
00808 pbcm = &bcm;
00809 }
00810
00811
return xxxBroadcastMessage(
NULL, message, wParam, lParam, uCmd, pbcm );
00812 }
00813
00814
CheckLock(pwnd);
00815
00816
if (message >= WM_DDE_FIRST && message <= WM_DDE_LAST) {
00817
00818
00819
00820
00821
if (!
xxxDDETrackSendHook(pwnd, message, wParam, lParam)) {
00822
return 0;
00823 }
00824
if (message == WM_DDE_INITIATE &&
guDdeSendTimeout) {
00825
00826
00827
00828
00829
00830
if (lpdwResult ==
NULL) {
00831 lpdwResult = &uResult;
00832 }
00833 fuFlags |= SMTO_ABORTIFHUNG;
00834 uTimeout =
guDdeSendTimeout;
00835 }
00836 }
00837
00838 ptiCurrent =
PtiCurrent();
00839
00840
00841
00842
00843
if (ptiCurrent !=
GETPTI(pwnd)) {
00844
INTRSENDMSGEX ism;
00845
PINTRSENDMSGEX pism =
NULL;
00846
00847
00848
00849
00850
00851
if (
HMIsMarkDestroy(pwnd))
00852
return xxxDefWindowProc(pwnd, message, wParam, lParam);
00853
00854
if ( lpdwResult !=
NULL ) {
00855
00856
00857
00858
if ((fuFlags & SMTO_ABORTIFHUNG) &&
FHungApp(
GETPTI(pwnd),
CMSWAITTOKILLTIMEOUT))
00859
return 0;
00860
00861
00862
00863
00864 ism.
fuCall =
ISM_TIMEOUT;
00865 ism.
fuSend = fuFlags;
00866 ism.
uTimeout = uTimeout;
00867 ism.
lpdwResult = lpdwResult;
00868 pism = &ism;
00869 }
00870
00871 lRet =
xxxInterSendMsgEx(pwnd, message, wParam, lParam,
00872 ptiCurrent,
GETPTI(pwnd), pism );
00873
00874
return lRet;
00875 }
00876
00877
00878
00879
00880
00881
if (
IsHooked(ptiCurrent,
WHF_CALLWNDPROC)) {
00882
CWPSTRUCTEX cwps;
00883
00884 cwps.hwnd =
HWq(pwnd);
00885 cwps.message = message;
00886 cwps.wParam = wParam;
00887 cwps.lParam = lParam;
00888 cwps.
psmsSender =
NULL;
00889
00890
00891
00892
00893
00894
xxxCallHook(HC_ACTION,
FALSE, (LPARAM)&cwps, WH_CALLWNDPROC);
00895
00896
00897
00898
00899
00900
00901
00902 }
00903
00904
00905
00906
00907
00908
00909
if (
TestWF(pwnd,
WFSERVERSIDEPROC)) {
00910
00911
00912
00913
00914
00915
00916
if (((ULONG_PTR)&uResult - (ULONG_PTR)
KeGetCurrentThread()->StackLimit) <
KERNEL_STACK_MINIMUM_RESERVE) {
00917 RIPMSG1(RIP_ERROR,
"SendMessage: Thread recursing in User with message %lX; failing", message);
00918
return FALSE;
00919 }
00920
00921 lRet = pwnd->
lpfnWndProc(pwnd, message, wParam, lParam);
00922
00923
if ( lpdwResult ==
NULL ) {
00924
return lRet;
00925 }
else {
00926 *lpdwResult = lRet;
00927
return TRUE;
00928 }
00929 }
00930
00931
00932
00933
00934
XXXSENDMESSAGETOCLIENT(pwnd, message, wParam, lParam,
NULL,
FALSE);
00935
00936
00937
00938
00939
if (
IsHooked(ptiCurrent,
WHF_CALLWNDPROCRET)) {
00940
CWPRETSTRUCTEX cwps;
00941
00942 cwps.hwnd =
HWq(pwnd);
00943 cwps.message = message;
00944 cwps.wParam = wParam;
00945 cwps.lParam = lParam;
00946 cwps.
lResult = lRet;
00947 cwps.
psmsSender =
NULL;
00948
00949
00950
00951
00952
00953
xxxCallHook(HC_ACTION,
FALSE, (LPARAM)&cwps, WH_CALLWNDPROCRET);
00954
00955
00956
00957
00958
00959
00960
00961 }
00962
00963
if ( lpdwResult !=
NULL ) {
00964 *lpdwResult = lRet;
00965
return TRUE;
00966 }
00967
00968
return lRet;
00969 }
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
void QueueNotifyMessage(
00983
PWND pwnd,
00984 UINT message,
00985 WPARAM wParam,
00986 LPARAM lParam)
00987 {
00988
TL tlpwnd;
00989
BEGINATOMICCHECK();
00990
00991
00992
00993
00994
00995
ThreadLock(pwnd, &tlpwnd);
00996
xxxSendMessageCallback(pwnd, message, wParam, lParam,
NULL, 1
L, 0);
00997
ThreadUnlock(&tlpwnd);
00998
ENDATOMICCHECK();
00999 }
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
VOID xxxSystemBroadcastMessage(
01016 UINT message,
01017 WPARAM wParam,
01018 LPARAM lParam,
01019 UINT wCmd,
01020
PBROADCASTMSG pbcm)
01021 {
01022
PTHREADINFO ptiCurrent =
PtiCurrent();
01023
PWINDOWSTATION pwinsta;
01024
PDESKTOP pdesk;
01025
TL tlpwinsta;
01026
TL tlpdesk;
01027
01028
01029
01030
01031
01032
ThreadLockWinSta(ptiCurrent,
NULL, &tlpwinsta);
01033
ThreadLockDesktop(ptiCurrent,
NULL, &tlpdesk, LDLT_FN_SYSTEMBROADCASTMESSAGE);
01034
for (pwinsta =
grpWinStaList; pwinsta !=
NULL; ) {
01035
UINT wCmd1;
01036
01037
if ((wCmd ==
BMSG_SENDMSG) && (pwinsta != ptiCurrent->
rpdesk->
rpwinstaParent))
01038 wCmd1 =
BMSG_SENDNOTIFYMSG;
01039
else
01040 wCmd1 = wCmd;
01041
01042
ThreadLockExchangeWinSta(ptiCurrent, pwinsta, &tlpwinsta);
01043
for (pdesk = pwinsta->
rpdeskList; pdesk !=
NULL; ) {
01044
01045
ThreadLockExchangeDesktop(ptiCurrent, pdesk, &tlpdesk, LDLT_FN_SYSTEMBROADCASTMESSAGE);
01046
01047
01048
01049
01050
01051
if (pdesk->
pDeskInfo->
spwnd !=
NULL) {
01052
xxxBroadcastMessage(pdesk->
pDeskInfo->
spwnd, message, wParam, lParam,
01053 wCmd1, pbcm);
01054 }
01055
01056 pdesk = pdesk->
rpdeskNext;
01057 }
01058 pwinsta = pwinsta->
rpwinstaNext;
01059 }
01060
ThreadUnlockDesktop(ptiCurrent, &tlpdesk, LDUT_FN_SYSTEMBROADCASTMESSAGE);
01061
ThreadUnlockWinSta(ptiCurrent, &tlpwinsta);
01062 }
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
BOOL xxxSendNotifyMessage(
01083
PWND pwnd,
01084 UINT message,
01085 WPARAM wParam,
01086 LPARAM lParam)
01087 {
01088
01089
01090
01091
01092
01093
if (pwnd ==
PWND_BROADCAST) {
01094
switch (message) {
01095
case WM_WININICHANGE:
01096
case WM_DEVMODECHANGE:
01097
case WM_SPOOLERSTATUS:
01098
xxxSystemBroadcastMessage(message, wParam, lParam,
01099
BMSG_SENDNOTIFYMSG,
NULL);
01100
return 1;
01101
01102
default:
01103
break;
01104 }
01105 }
01106
01107
return xxxSendMessageCallback( pwnd, message, wParam, lParam,
01108
NULL, 0
L, 0 );
01109 }
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
BOOL xxxSendMessageCallback(
01128
PWND pwnd,
01129 UINT message,
01130 WPARAM wParam,
01131 LPARAM lParam,
01132 SENDASYNCPROC lpResultCallBack,
01133 ULONG_PTR dwData,
01134 BOOL fClientRequest)
01135 {
01136 LRESULT lRet;
01137
PTHREADINFO ptiCurrent;
01138
BOOL fQueuedNotify;
01139
01140
01141
01142
01143 fQueuedNotify =
FALSE;
01144
if (lpResultCallBack ==
NULL && dwData == 1
L)
01145 fQueuedNotify =
TRUE;
01146
01147
01148
01149
01150
01151
01152
01153
01154
if (
TESTSYNCONLYMESSAGE(message, wParam)) {
01155 RIPERR1(ERROR_MESSAGE_SYNC_ONLY, RIP_WARNING,
01156
"Trying to non-synchronously send a structure msg=%lX", message);
01157
return FALSE;
01158 }
01159
01160
CheckCritIn();
01161
01162
01163
01164
01165
if (pwnd ==
PWND_BROADCAST) {
01166
BROADCASTMSG bcm;
01167
PBROADCASTMSG pbcm =
NULL;
01168
UINT uCmd =
BMSG_SENDNOTIFYMSG;
01169
01170
if (lpResultCallBack !=
NULL) {
01171 uCmd =
BMSG_SENDMSGCALLBACK;
01172 bcm.
cb.lpResultCallBack = lpResultCallBack;
01173 bcm.
cb.dwData = dwData;
01174 bcm.
cb.bClientRequest = fClientRequest;
01175 pbcm = &bcm;
01176 }
01177
01178
return xxxBroadcastMessage(
NULL, message, wParam, lParam, uCmd, pbcm );
01179 }
01180
01181
CheckLock(pwnd);
01182
01183 ptiCurrent =
PtiCurrent();
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
if (fQueuedNotify || ptiCurrent !=
GETPTI(pwnd)) {
01195
INTRSENDMSGEX ism;
01196
PINTRSENDMSGEX pism =
NULL;
01197
01198
if (lpResultCallBack !=
NULL) {
01199 ism.
fuCall =
ISM_CALLBACK | (fClientRequest ?
ISM_CB_CLIENT : 0);
01200 ism.
lpResultCallBack = lpResultCallBack;
01201 ism.
dwData = dwData;
01202 pism = &ism;
01203 }
01204
return (
BOOL)
xxxInterSendMsgEx(pwnd, message, wParam, lParam,
01205
NULL,
GETPTI(pwnd), pism );
01206 }
01207
01208
01209
01210
01211
if (!fQueuedNotify &&
IsHooked(ptiCurrent,
WHF_CALLWNDPROC)) {
01212
CWPSTRUCTEX cwps;
01213
01214 cwps.hwnd =
HWq(pwnd);
01215 cwps.message = message;
01216 cwps.wParam = wParam;
01217 cwps.lParam = lParam;
01218 cwps.
psmsSender =
NULL;
01219
01220
01221
01222
01223
01224
xxxCallHook(HC_ACTION,
FALSE, (LPARAM)&cwps, WH_CALLWNDPROC);
01225
01226
01227
01228
01229
01230
01231
01232 }
01233
01234
01235
01236
01237
01238
01239
if (
TestWF(pwnd,
WFSERVERSIDEPROC)) {
01240 lRet = pwnd->
lpfnWndProc(pwnd, message, wParam, lParam);
01241 }
else {
01242
01243
01244
01245
XXXSENDMESSAGETOCLIENT(pwnd, message, wParam, lParam,
NULL,
FALSE);
01246 }
01247
01248
if (lpResultCallBack !=
NULL) {
01249
01250
01251
01252
if (fClientRequest) {
01253
01254
01255
01256
CallClientProcA(pwnd, message, dwData, lRet,
01257 (ULONG_PTR)lpResultCallBack);
01258 }
else {
01259 (*lpResultCallBack)((HWND)pwnd, message, dwData, lRet);
01260 }
01261 }
01262
01263
01264
01265
01266
if (!fQueuedNotify &&
IsHooked(ptiCurrent,
WHF_CALLWNDPROCRET)) {
01267
CWPRETSTRUCTEX cwps;
01268
01269 cwps.hwnd =
HWq(pwnd);
01270 cwps.message = message;
01271 cwps.wParam = wParam;
01272 cwps.lParam = lParam;
01273 cwps.
lResult = lRet;
01274 cwps.
psmsSender =
NULL;
01275
01276
01277
01278
01279
01280
xxxCallHook(HC_ACTION,
FALSE, (LPARAM)&cwps, WH_CALLWNDPROCRET);
01281
01282
01283
01284
01285
01286
01287
01288 }
01289
01290
return TRUE;
01291 }
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
#define NoString 0
01306
#define IsAnsiString 1
01307
#define IsUnicodeString 2
01308
01309 LRESULT
xxxInterSendMsgEx(
01310
PWND pwnd,
01311 UINT message,
01312 WPARAM wParam,
01313 LPARAM lParam,
01314
PTHREADINFO ptiSender,
01315
PTHREADINFO ptiReceiver,
01316
PINTRSENDMSGEX pism)
01317 {
01318
PSMS psms, *ppsms;
01319
PSMS psmsSentSave;
01320 LRESULT lRet = 0;
01321
DWORD cbCapture, cbOutput;
01322
PBYTE lpCapture;
01323 PCOPYDATASTRUCT pcds;
01324
PMDICREATESTRUCTEX pmdics;
01325 LPHLP phlp;
01326 LPHELPINFO phelpinfo;
01327
LARGE_STRING str;
01328 LPARAM lParamSave;
01329
UINT fString =
NoString;
01330 BOOLEAN bWasSwapEnabled;
01331
01332
CheckCritIn();
01333
01334
01335
01336
01337
01338
if ((ptiSender !=
NULL) && (ptiSender->
TIF_flags &
TIF_INCLEANUP))
01339
return 0;
01340
01341
01342
01343
01344
01345
if (pwnd &&
GETPTI(pwnd)->ppi !=
PpiCurrent()) {
01346
switch (message) {
01347
case WM_NOTIFY:
01348 RIPMSG0(RIP_WARNING | RIP_THERESMORE,
"xxxInterSendMsgEx: message cannot be sent across processes");
01349 RIPMSG4(RIP_WARNING | RIP_THERESMORE,
" pwnd:%#p message:%#x wParam:%#p lParam:%#p", pwnd, message, wParam, lParam);
01350
return 0;
01351
01352
case WM_GETTEXT:
01353
case EM_GETLINE:
01354
case EM_SETPASSWORDCHAR:
01355
if ((
GETFNID(pwnd) ==
FNID_EDIT) &&
TestWF(pwnd,
EFPASSWORD)) {
01356 RIPERR0(ERROR_ACCESS_DENIED, RIP_WARNING,
"Can't access protected edit control");
01357
return 0;
01358 }
01359
break;
01360 }
01361 }
01362
01363
01364
01365
01366 psms =
AllocSMS();
01367
if (psms ==
NULL) {
01368
01369
01370
01371
01372
return 0;
01373 }
01374
01375
01376
01377
01378
01379
01380 psms->pvCapture =
NULL;
01381 cbCapture = cbOutput = 0;
01382 lpCapture = (LPBYTE)lParam;
01383
01384
01385
01386
01387
01388
try {
01389
switch (message) {
01390
case WM_COPYGLOBALDATA:
01391 cbCapture = (
DWORD)wParam;
01392
break;
01393
01394
case WM_COPYDATA:
01395 pcds = (PCOPYDATASTRUCT)lParam;
01396
if (pcds->lpData) {
01397 cbCapture =
sizeof(COPYDATASTRUCT) + pcds->cbData;
01398 }
else {
01399 cbCapture =
sizeof(COPYDATASTRUCT);
01400 }
01401
break;
01402
01403
case WM_CREATE:
01404
case WM_NCCREATE:
01405 RIPERR0(ERROR_ACCESS_DENIED, RIP_WARNING,
"Can't Intersend WM_CREATE or WM_NCCREATE message");
01406
FreeSMS(psms);
01407
return 0;
01408
01409
case WM_HELP:
01410 phelpinfo = (LPHELPINFO)lParam;
01411 cbCapture = phelpinfo->cbSize;
01412
break;
01413
01414
case WM_WINHELP:
01415 phlp = (LPHLP)lParam;
01416 cbCapture = phlp->cbData;
01417
break;
01418
01419
case WM_MDICREATE:
01420 pmdics = (
PMDICREATESTRUCTEX)lParam;
01421 cbCapture = pmdics->
strTitle.
MaximumLength +
01422 pmdics->
strClass.
MaximumLength;
01423 UserAssert(pmdics->
strClass.
Buffer ==
NULL || pmdics->
strClass.
Buffer == pmdics->
mdics.szClass);
01424
if (pmdics->
strTitle.
Buffer)
01425 UserAssert(pmdics->
strTitle.
Buffer == pmdics->
mdics.szTitle);
01426
break;
01427
01428
case LB_ADDSTRING:
01429
case LB_INSERTSTRING:
01430
case LB_SELECTSTRING:
01431
case LB_FINDSTRING:
01432
case LB_FINDSTRINGEXACT:
01433
01434
01435
01436
01437
if (pwnd && !(pwnd->style & LBS_HASSTRINGS) &&
01438 (pwnd->style & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE))) {
01439
01440
01441
01442
break;
01443 }
else {
01444
goto fnINSTRINGThunk;
01445 }
01446
break;
01447
01448
case CB_ADDSTRING:
01449
case CB_INSERTSTRING:
01450
case CB_SELECTSTRING:
01451
case CB_FINDSTRING:
01452
case CB_FINDSTRINGEXACT:
01453
01454
01455
01456
01457
if (pwnd && !(pwnd->style & CBS_HASSTRINGS) &&
01458 (pwnd->style & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE))) {
01459
01460
01461
01462
01463
break;
01464 }
else {
01465
goto fnINSTRINGThunk;
01466 }
01467
break;
01468
01469
case EM_REPLACESEL:
01470
case WM_SETTEXT:
01471
case WM_WININICHANGE:
01472
if (lParam == 0)
01473
break;
01474
01475
01476
01477
01478
01479
case CB_DIR:
01480
case LB_ADDFILE:
01481
case LB_DIR:
01482
case WM_DEVMODECHANGE:
01483 fnINSTRINGThunk:
01484
01485
01486
01487
01488 str = *(
PLARGE_STRING)lParam;
01489 lParam = (LPARAM)&str;
01490
01491
if (!
IS_SYSTEM_ADDRESS(str.
Buffer))
01492 cbCapture = str.
Length +
sizeof(WCHAR);
01493
break;
01494
01495
case WM_DEVICECHANGE:
01496
if (lParam == 0)
01497
break;
01498
01499
01500
01501
01502
01503
if ((wParam & 0x8000) != 0x8000)
01504
break;
01505
01506
if (!
IS_SYSTEM_ADDRESS((
LPVOID)lParam)) {
01507 cbCapture = *((
DWORD *)lpCapture);
01508 UserAssert(
FALSE);
01509 }
01510
break;
01511
01512
case EM_SETTABSTOPS:
01513
case LB_SETTABSTOPS:
01514
case LB_GETSELITEMS:
01515 cbCapture = (
UINT)wParam *
sizeof(
INT);
01516
break;
01517
01518
case EM_GETLINE:
01519
case WM_ASKCBFORMATNAME:
01520
case WM_GETTEXT:
01521
case LB_GETTEXT:
01522
case CB_GETLBTEXT:
01523
01524
01525
01526
01527 str = *(
PLARGE_STRING)lParam;
01528
01529
01530
01531
01532
if(str.
bAnsi) {
01533 fString =
IsAnsiString ;
01534 }
else {
01535 fString =
IsUnicodeString ;
01536 }
01537 lParam = (LPARAM)&str;
01538
if (!
IS_SYSTEM_ADDRESS(str.
Buffer))
01539 cbCapture = str.
MaximumLength;
01540
break;
01541 }
01542
if (cbCapture &&
01543 (psms->pvCapture = UserAllocPoolWithQuota(cbCapture, TAG_SMS_CAPTURE)) !=
NULL) {
01544
01545 lParamSave = lParam;
01546
01547
01548
01549
01550
01551
01552
switch (message) {
01553
case WM_COPYDATA:
01554 {
01555 PCOPYDATASTRUCT pcdsNew = (PCOPYDATASTRUCT)psms->pvCapture;
01556 lParam = (LPARAM)pcdsNew;
01557 RtlCopyMemory(pcdsNew, pcds,
sizeof(COPYDATASTRUCT));
01558
if (pcds->lpData) {
01559 pcdsNew->lpData = (PVOID)((
PBYTE)pcdsNew +
sizeof(COPYDATASTRUCT));
01560 RtlCopyMemory(pcdsNew->lpData, pcds->lpData, pcds->cbData);
01561 }
01562 }
01563
break;
01564
case WM_MDICREATE:
01565
if (pmdics->
strClass.
Buffer) {
01566 RtlCopyMemory(psms->pvCapture, pmdics->
strClass.
Buffer,
01567 pmdics->
strClass.
MaximumLength);
01568 pmdics->
mdics.szClass = (LPWSTR)psms->pvCapture;
01569 }
01570
if (pmdics->
strTitle.
Length) {
01571 lpCapture = (
PBYTE)psms->pvCapture + pmdics->
strClass.
MaximumLength;
01572 RtlCopyMemory(lpCapture, pmdics->
strTitle.
Buffer,
01573 pmdics->
strTitle.
MaximumLength);
01574 pmdics->
mdics.szTitle = (LPWSTR)lpCapture;
01575 }
01576
break;
01577
01578
case CB_DIR:
01579
case LB_FINDSTRING:
01580
case LB_FINDSTRINGEXACT:
01581
case CB_FINDSTRING:
01582
case CB_FINDSTRINGEXACT:
01583
case LB_ADDFILE:
01584
case LB_ADDSTRING:
01585
case LB_INSERTSTRING:
01586
case LB_SELECTSTRING:
01587
case CB_ADDSTRING:
01588
case CB_INSERTSTRING:
01589
case CB_SELECTSTRING:
01590
case LB_DIR:
01591
case WM_DEVMODECHANGE:
01592
case EM_REPLACESEL:
01593
case WM_SETTEXT:
01594
case WM_WININICHANGE:
01595 RtlCopyMemory(psms->pvCapture, str.
Buffer, cbCapture);
01596 str.
Buffer = psms->pvCapture;
01597
break;
01598
01599
case LB_GETSELITEMS:
01600 cbOutput = cbCapture;
01601 RtlCopyMemory(psms->pvCapture, lpCapture, cbCapture);
01602 lParam = (LPARAM)psms->pvCapture;
01603
break;
01604
01605
case EM_GETLINE:
01606 *(WORD *)psms->pvCapture = *(WORD *)str.
Buffer;
01607
01608
01609
01610
01611
case WM_ASKCBFORMATNAME:
01612
case WM_GETTEXT:
01613
case LB_GETTEXT:
01614
case CB_GETLBTEXT:
01615 cbOutput = cbCapture;
01616 lParamSave = (LPARAM)str.
Buffer;
01617 str.
Buffer = psms->pvCapture;
01618
break;
01619
01620
default:
01621 RtlCopyMemory(psms->pvCapture, lpCapture, cbCapture);
01622 lParam = (LPARAM)psms->pvCapture;
01623
break;
01624 }
01625 }
01626 } except (W32ExceptionHandler(
FALSE, RIP_WARNING)) {
01627
if (psms->pvCapture !=
NULL)
01628 UserFreePool(psms->pvCapture);
01629
FreeSMS(psms);
01630
return 0;
01631 }
01632
01633
if (cbCapture && psms->pvCapture ==
NULL) {
01634
FreeSMS(psms);
01635
return 0;
01636 }
01637
01638
01639
01640
01641 psms->spwnd =
NULL;
01642 psms->psmsReceiveNext =
NULL;
01643
#if DBG
01644
psms->psmsSendList =
NULL;
01645 psms->psmsSendNext =
NULL;
01646
#endif
01647
Lock(&(psms->spwnd), pwnd);
01648 psms->message = message;
01649 psms->wParam = wParam;
01650 psms->lParam = lParam;
01651 psms->flags = 0;
01652
01653
01654
01655
01656 psms->psmsNext =
gpsmsList;
01657
gpsmsList = psms;
01658
01659
01660
01661
01662 psms->tSent =
NtGetTickCount();
01663
01664
01665
01666
01667 psms->ptiReceiver = ptiReceiver;
01668 psms->ptiSender = ptiSender;
01669 psms->ptiCallBackSender =
NULL;
01670
01671
if ((pism !=
NULL) && (pism->
fuCall &
ISM_CALLBACK)) {
01672
01673
01674
01675 psms->flags |= (pism->
fuCall &
ISM_CB_CLIENT) ?
SMF_CB_CLIENT :
SMF_CB_SERVER;
01676 psms->lpResultCallBack = pism->
lpResultCallBack;
01677 psms->dwData = pism->
dwData;
01678
01679
if (pism->
fuCall &
ISM_REPLY) {
01680 psms->flags |=
SMF_CB_REPLY;
01681 psms->lRet = pism->
lRet;
01682 }
else {
01683 psms->flags |=
SMF_CB_REQUEST;
01684 psms->ptiCallBackSender =
PtiCurrent();
01685 }
01686 }
01687
01688
01689
01690
01691 ppsms = &ptiReceiver->
psmsReceiveList;
01692
while (*ppsms !=
NULL) {
01693 ppsms = &((*ppsms)->psmsReceiveNext);
01694 }
01695 *ppsms = psms;
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
#if DBG
01714
if (ptiSender !=
NULL && ptiSender->
psmsCurrent !=
NULL) {
01715
01716
01717
01718
01719
01720 psms->psmsSendNext = ptiSender->
psmsCurrent->psmsSendNext;
01721 ptiSender->
psmsCurrent->psmsSendNext = psms;
01722 psms->psmsSendList = ptiSender->
psmsCurrent->psmsSendList;
01723
01724 }
else {
01725
01726
01727
01728
01729 psms->psmsSendList = psms;
01730 }
01731
#endif
01732
01733
if (ptiSender !=
NULL) {
01734
01735
01736
01737
01738
01739
01740
01741
01742 psmsSentSave = ptiSender->
psmsSent;
01743 ptiSender->
psmsSent = psms;
01744 }
else {
01745
01746
01747
01748
01749
01750
01751 psms->flags |=
SMF_RECEIVERFREE;
01752 }
01753
01754
#ifdef DEBUG_SMS
01755
ValidateSmsSendLists(psms);
01756
#endif
01757
01758
01759
01760
01761
01762
if (ptiSender ==
NULL) {
01763
01764
01765
01766
SetWakeBit(ptiReceiver, QS_SENDMESSAGE);
01767
01768
return (LONG)
TRUE;
01769 }
else {
01770
BOOL fTimeOut =
FALSE;
01771
UINT uTimeout = 0;
01772
UINT uWakeMask = QS_SMSREPLY;
01773
01774
01775
01776
01777
SetWakeBit(ptiReceiver, QS_SENDMESSAGE);
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
if (ptiSender->
TIF_flags &
TIF_16BIT || ptiReceiver->
TIF_flags &
TIF_16BIT) {
01788
DirectedScheduleTask(ptiSender, ptiReceiver,
TRUE, psms);
01789 }
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
if ( pism !=
NULL ) {
01808
if (pism->
fuSend & SMTO_BLOCK) {
01809
01810
01811
01812
01813 uWakeMask |= QS_EXCLUSIVE;
01814 }
01815
01816 uTimeout = pism->
uTimeout;
01817 }
01818
01819
01820
01821
01822
01823
if (ptiSender->
cEnterCount == 0) {
01824 bWasSwapEnabled =
KeSetKernelStackSwapEnable(
FALSE);
01825 }
else {
01826 UserAssert(ptiSender->
cEnterCount > 0);
01827 }
01828 ptiSender->
cEnterCount++;
01829
01830
01831
while (!(psms->flags &
SMF_REPLY) && !fTimeOut) {
01832 ptiSender->
pcti->
fsChangeBits &= ~QS_SMSREPLY;
01833
01834
01835
01836
01837
01838
01839 fTimeOut = !
xxxSleepThread(uWakeMask, uTimeout,
FALSE);
01840
01841
01842
01843
01844
01845
01846
01847
if (fTimeOut && pism && (pism->
fuSend & SMTO_NOTIMEOUTIFNOTHUNG) &&
01848 !
FHungApp(ptiReceiver,
CMSHUNGAPPTIMEOUT)) {
01849 fTimeOut =
FALSE;
01850 }
01851 }
01852
01853 UserAssert(ptiSender->
cEnterCount > 0);
01854
if (--ptiSender->
cEnterCount == 0) {
01855
KeSetKernelStackSwapEnable(bWasSwapEnabled);
01856 }
01857
01858
01859
01860
01861
01862
01863
01864
01865
SetWakeBit(ptiSender, QS_SMSREPLY);
01866
01867
01868
01869
01870
01871
01872
if (!fTimeOut && cbOutput) {
01873
PBYTE pbOutput;
01874
INT len;
01875
01876
01877
01878
01879
01880 pbOutput = (
PBYTE)lParamSave;
01881
try {
01882
if(fString ==
NoString) {
01883 RtlCopyMemory((
PBYTE)pbOutput, psms->pvCapture,
01884 cbOutput);
01885 }
else if(fString ==
IsAnsiString) {
01886 len =
strncpycch((LPSTR)pbOutput,(LPCSTR)psms->pvCapture,
01887 cbOutput);
01888
#if DBG
01889
len--;
01890
if(len != psms->lRet) {
01891 RIPMSG0(RIP_WARNING,
01892
"Length of the copied string being returned is diffrent from the actual string length");
01893 }
01894
#endif
01895
}
else {
01896 len =
wcsncpycch((LPWSTR)pbOutput,(LPCWSTR)psms->pvCapture,
01897 cbOutput/
sizeof(WCHAR));
01898
#if DBG
01899
len--;
01900
if(len != psms->lRet) {
01901 RIPMSG0(RIP_WARNING,
01902
"Length of the copied string being returned is diffrent from the actual string length");
01903 }
01904
#endif
01905
}
01906 } except (W32ExceptionHandler(
FALSE, RIP_WARNING)) {
01907
01908
01909
01910
01911 psms->lRet = 0;
01912 }
01913 }
01914
01915
01916
01917
01918 ptiSender->
psmsSent = psmsSentSave;
01919
01920
if (pism ==
NULL) {
01921 lRet = psms->lRet;
01922 }
else {
01923
01924
01925
01926 *pism->
lpdwResult = psms->lRet;
01927 lRet = (!fTimeOut) ?
TRUE :
FALSE;
01928
01929
01930
01931
01932
01933
if (!(psms->flags &
SMF_REPLY))
01934 psms->flags |=
SMF_REPLY |
SMF_RECEIVERFREE;
01935 }
01936
01937
01938
01939
01940
01941
01942
if ((psms->flags & (
SMF_RECEIVERBUSY |
SMF_RECEIVEDMESSAGE)) !=
01943
SMF_RECEIVEDMESSAGE) {
01944 psms->flags |=
SMF_RECEIVERFREE;
01945 }
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
if (!(psms->flags &
SMF_RECEIVERFREE)) {
01956
UnlinkSendListSms(psms,
NULL);
01957 }
01958 }
01959
01960
return lRet;
01961 }
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
VOID xxxReceiveMessage(
01978
PTHREADINFO ptiReceiver)
01979 {
01980
PSMS psms;
01981
PSMS psmsCurrentSave;
01982
PTHREADINFO ptiSender;
01983 LRESULT lRet = 0;
01984
TL tlpwnd;
01985
01986
CheckCritIn();
01987
01988
01989
01990
01991 psms = ptiReceiver->
psmsReceiveList;
01992
01993
01994
01995
01996
01997
if (psms ==
NULL) {
01998 ptiReceiver->
pcti->
fsWakeBits &= ~QS_SENDMESSAGE;
01999 ptiReceiver->
pcti->
fsChangeBits &= ~QS_SENDMESSAGE;
02000
return;
02001 }
02002
02003 ptiReceiver->
psmsReceiveList = psms->psmsReceiveNext;
02004 psms->psmsReceiveNext =
NULL;
02005
02006
02007
02008
02009
02010 psms->flags |=
SMF_RECEIVERBUSY |
SMF_RECEIVEDMESSAGE;
02011
02012
02013
02014
02015
if (ptiReceiver->
psmsReceiveList ==
NULL) {
02016 ptiReceiver->
pcti->
fsWakeBits &= ~QS_SENDMESSAGE;
02017 ptiReceiver->
pcti->
fsChangeBits &= ~QS_SENDMESSAGE;
02018 }
02019
02020 ptiSender = psms->ptiSender;
02021
02022
if (psms->flags &
SMF_CB_REPLY) {
02023
02024
02025
02026
02027
02028
02029
if (ptiSender ==
NULL) {
02030
ThreadLock(psms->spwnd, &tlpwnd);
02031 }
02032
02033
if (psms->flags &
SMF_CB_CLIENT) {
02034
02035
02036
02037
CallClientProcA(psms->spwnd, psms->message, psms->dwData,
02038 psms->lRet, (ULONG_PTR)psms->lpResultCallBack);
02039 }
else {
02040 psms->lpResultCallBack(
HW(psms->spwnd), psms->message,
02041 psms->dwData, psms->lRet);
02042 }
02043
02044
if (ptiSender ==
NULL) {
02045
ThreadUnlock(&tlpwnd);
02046 }
02047 }
else if (!(psms->flags & (
SMF_REPLY |
SMF_SENDERDIED |
SMF_RECEIVERDIED))) {
02048
02049
02050
02051
02052
02053
02054
02055
02056 psmsCurrentSave = ptiReceiver->
psmsCurrent;
02057 ptiReceiver->
psmsCurrent = psms;
02058
SET_FLAG(ptiReceiver->
pcti->
CTIF_flags,
CTIF_INSENDMESSAGE);
02059
02060
02061
02062
02063
02064
02065
if (ptiSender ==
NULL) {
02066
ThreadLock(psms->spwnd, &tlpwnd);
02067 }
02068
02069
if (psms->message == WM_HOOKMSG) {
02070
union {
02071 EVENTMSG emsg;
02072 MOUSEHOOKSTRUCTEX mhs;
02073 KBDLLHOOKSTRUCT kbds;
02074 MSLLHOOKSTRUCT mslls;
02075
#ifdef REDIRECTION
02076
HTHOOKSTRUCT ht;
02077
#endif // REDIRECTION
02078
} LocalData;
02079 PVOID pSendersData;
02080
PHOOKMSGSTRUCT phkmp;
02081
int iHook;
02082
BOOL bAnsiHook;
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093 phkmp = (
PHOOKMSGSTRUCT)psms->
lParam;
02094 pSendersData = (PVOID)(phkmp->
lParam);
02095 iHook = phkmp->
phk->
iHook;
02096
02097
switch (iHook) {
02098
case WH_JOURNALRECORD:
02099
case WH_JOURNALPLAYBACK:
02100
if (pSendersData)
02101 LocalData.emsg = *(PEVENTMSG)pSendersData;
02102
break;
02103
02104
case WH_MOUSE:
02105
if (pSendersData)
02106 LocalData.mhs = *(LPMOUSEHOOKSTRUCTEX)pSendersData;
02107
break;
02108
02109
case WH_KEYBOARD_LL:
02110
if (pSendersData)
02111 LocalData.kbds = *(LPKBDLLHOOKSTRUCT)pSendersData;
02112
break;
02113
02114
case WH_MOUSE_LL:
02115
if (pSendersData)
02116 LocalData.mslls = *(LPMSLLHOOKSTRUCT)pSendersData;
02117
break;
02118
02119
#ifdef REDIRECTION
02120
case WH_HITTEST:
02121
if (pSendersData)
02122 LocalData.ht = *(LPHTHOOKSTRUCT)pSendersData;
02123
break;
02124
#endif // REDIRECTION
02125
02126
case WH_KEYBOARD:
02127
case WH_SHELL:
02128
02129
02130
02131 pSendersData =
NULL;
02132
break;
02133
02134
default:
02135
02136
02137
02138 RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING,
"Receive hook %d", iHook);
02139 pSendersData =
NULL;
02140
break;
02141 }
02142
02143
02144 lRet =
xxxCallHook2(phkmp->
phk, phkmp->
nCode, psms->wParam,
02145 pSendersData ? (LPARAM)&LocalData : phkmp->
lParam, &bAnsiHook);
02146
02147
02148
02149
02150
02151
if (!(psms->flags & (
SMF_SENDERDIED|
SMF_REPLY)) && pSendersData) {
02152
switch (iHook) {
02153
case WH_JOURNALRECORD:
02154
case WH_JOURNALPLAYBACK:
02155 *(PEVENTMSG)pSendersData = LocalData.emsg;
02156
break;
02157
02158
case WH_KEYBOARD_LL:
02159 *(LPKBDLLHOOKSTRUCT)pSendersData = LocalData.kbds;
02160
break;
02161
02162
case WH_MOUSE_LL:
02163 *(LPMSLLHOOKSTRUCT)pSendersData = LocalData.mslls;
02164
break;
02165
02166
case WH_MOUSE:
02167 *(LPMOUSEHOOKSTRUCTEX)pSendersData = LocalData.mhs;
02168
break;
02169
02170
#ifdef REDIRECTION
02171
case WH_HITTEST:
02172 *(LPHTHOOKSTRUCT)pSendersData = LocalData.ht;
02173
break;
02174
#endif // REDIRECTION
02175
}
02176 }
02177
02178 }
else {
02179
02180
02181
02182
02183
if (
IsHooked(ptiReceiver,
WHF_CALLWNDPROC)) {
02184
CWPSTRUCTEX cwps;
02185
02186 cwps.hwnd =
HW(psms->spwnd);
02187 cwps.message = psms->message;
02188 cwps.wParam = psms->wParam;
02189 cwps.lParam = psms->lParam;
02190 cwps.
psmsSender = psms;
02191
02192
xxxCallHook(HC_ACTION,
TRUE, (LPARAM)&cwps, WH_CALLWNDPROC);
02193
02194
02195
02196
02197
02198
02199
02200 }
02201
02202
if (!(psms->flags & (
SMF_REPLY |
SMF_SENDERDIED |
SMF_RECEIVERDIED)) &&
02203 psms->spwnd !=
NULL) {
02204
if (
TestWF(psms->spwnd,
WFSERVERSIDEPROC)) {
02205
TL tlpwndKernel;
02206
02207
ThreadLock(psms->spwnd, &tlpwndKernel);
02208
02209
02210
02211
02212
02213 lRet = psms->spwnd->lpfnWndProc(psms->spwnd, psms->message,
02214 psms->wParam, psms->lParam);
02215
02216
ThreadUnlock(&tlpwndKernel);
02217 }
else {
02218
02219
02220
02221
XXXSENDMESSAGETOCLIENT(psms->spwnd, psms->message, psms->wParam, psms->lParam,
02222 psms,
TRUE);
02223 }
02224
02225
02226
02227
02228
if (
IsHooked(ptiReceiver,
WHF_CALLWNDPROCRET) &&
02229 !(psms->flags &
SMF_SENDERDIED)) {
02230
CWPRETSTRUCTEX cwps;
02231
02232 cwps.hwnd =
HW(psms->spwnd);
02233 cwps.message = psms->message;
02234 cwps.wParam = psms->wParam;
02235 cwps.lParam = psms->lParam;
02236 cwps.
lResult = lRet;
02237 cwps.
psmsSender = psms;
02238
02239
02240
02241
02242
02243
xxxCallHook(HC_ACTION,
TRUE, (LPARAM)&cwps, WH_CALLWNDPROCRET);
02244
02245
02246
02247
02248
02249
02250
02251 }
02252 }
02253 }
02254
02255
if ((psms->flags & (
SMF_CB_REQUEST |
SMF_REPLY)) ==
SMF_CB_REQUEST) {
02256
02257
02258
02259
02260
02261
INTRSENDMSGEX ism;
02262
02263 psms->flags |=
SMF_REPLY;
02264
02265
if (!(psms->flags &
SMF_SENDERDIED)) {
02266 ism.
fuCall =
ISM_CALLBACK |
ISM_REPLY;
02267
if (psms->flags &
SMF_CB_CLIENT)
02268 ism.
fuCall |=
ISM_CB_CLIENT;
02269 ism.
lpResultCallBack = psms->lpResultCallBack;
02270 ism.
dwData = psms->dwData;
02271 ism.
lRet = lRet;
02272
02273
xxxInterSendMsgEx(psms->spwnd, psms->message, 0
L, 0
L,
02274
NULL, psms->ptiCallBackSender, &ism );
02275 }
02276 }
02277
02278
if (ptiSender ==
NULL) {
02279
ThreadUnlock(&tlpwnd);
02280 }
02281
02282
02283
02284
02285 ptiReceiver->
psmsCurrent = psmsCurrentSave;
02286
SET_OR_CLEAR_FLAG(ptiReceiver->
pcti->
CTIF_flags,
02287
CTIF_INSENDMESSAGE,
02288 ptiReceiver->
psmsCurrent);
02289
02290
#ifdef DEBUG_SMS
02291
ValidateSmsSendLists(psmsCurrentSave);
02292
#endif
02293
}
02294
02295
02296
02297
02298
02299 psms->flags &= ~
SMF_RECEIVERBUSY;
02300
02301
02302
02303
02304
02305
02306
02307
if (psms->flags &
SMF_RECEIVERFREE) {
02308
UnlinkSendListSms(psms,
NULL);
02309
return;
02310 }
02311
02312
02313
02314
02315
02316
if (!(psms->flags &
SMF_REPLY)) {
02317 psms->lRet = lRet;
02318 psms->flags |=
SMF_REPLY;
02319
02320
02321
02322
02323
if (ptiSender !=
NULL) {
02324
02325
02326
02327
SetWakeBit(ptiSender, QS_SMSREPLY);
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
if (ptiSender->
TIF_flags &
TIF_16BIT || ptiReceiver->
TIF_flags &
TIF_16BIT) {
02339
DirectedScheduleTask(ptiReceiver, ptiSender,
FALSE, psms);
02340
if (ptiReceiver->
TIF_flags &
TIF_16BIT &&
02341 ptiSender->
psmsSent == psms)
02342 {
02343
xxxSleepTask(
TRUE,
NULL);
02344 }
02345 }
02346 }
02347 }
02348
02349 }
02350
02351
02352
02353
02354
02355
02356
02357
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376
02377
VOID SendMsgCleanup(
02378
PTHREADINFO ptiCurrent)
02379 {
02380
PSMS *ppsms;
02381
PSMS psmsNext;
02382
02383
CheckCritIn();
02384
02385
for (ppsms = &
gpsmsList; *ppsms; ) {
02386 psmsNext = (*ppsms)->psmsNext;
02387
02388
if ((*ppsms)->ptiSender == ptiCurrent ||
02389 (*ppsms)->ptiCallBackSender == ptiCurrent) {
02390
SenderDied(*ppsms, ppsms);
02391 }
else if ((*ppsms)->ptiReceiver == ptiCurrent) {
02392
ReceiverDied(*ppsms, ppsms);
02393 }
02394
02395
02396
02397
02398
if (*ppsms != psmsNext)
02399 ppsms = &(*ppsms)->psmsNext;
02400 }
02401 }
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
VOID ClearSendMessages(
02414
PWND pwnd)
02415 {
02416
PSMS psms, psmsNext;
02417
PSMS *ppsms;
02418
02419
CheckCritIn();
02420
02421 psms =
gpsmsList;
02422
while (psms !=
NULL) {
02423
02424
02425
02426 psmsNext = psms->psmsNext;
02427
02428
if (psms->spwnd == pwnd) {
02429
02430
02431
02432
02433
02434
if (psms->flags &
SMF_SENDERDIED) {
02435 psms->flags |=
SMF_REPLY |
SMF_RECEIVERFREE;
02436 }
else {
02437
02438
02439
02440
02441
02442
02443
if (!(psms->flags &
SMF_REPLY)) {
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
if (psms->flags &
SMF_CB_REQUEST) {
02455
02456
02457
02458
02459
TL tlpwnd;
02460
INTRSENDMSGEX ism;
02461
02462 psms->flags |=
SMF_REPLY;
02463
02464 ism.
fuCall =
ISM_CALLBACK |
ISM_REPLY;
02465
if (psms->flags &
SMF_CB_CLIENT)
02466 ism.
fuCall |=
ISM_CB_CLIENT;
02467 ism.
lpResultCallBack = psms->lpResultCallBack;
02468 ism.
dwData = psms->dwData;
02469 ism.
lRet = 0
L;
02470
02471
ThreadLock(psms->spwnd, &tlpwnd);
02472
02473
xxxInterSendMsgEx(psms->spwnd, psms->message, 0
L, 0
L,
02474
NULL, psms->ptiCallBackSender, &ism );
02475
02476
ThreadUnlock(&tlpwnd);
02477 }
else if (!(psms->flags &
SMF_RECEIVERBUSY)) {
02478
02479
02480
02481
02482
02483
02484
02485
if (psms->ptiSender ==
NULL) {
02486 psms->flags |=
SMF_REPLY;
02487 }
else {
02488
02489
02490
02491
02492
02493
for (ppsms = &(psms->ptiReceiver->psmsReceiveList);
02494 *ppsms !=
NULL;
02495 ppsms = &((*ppsms)->psmsReceiveNext)) {
02496
02497
if (*ppsms == psms) {
02498 *ppsms = psms->psmsReceiveNext;
02499
break;
02500 }
02501 }
02502
02503
02504
02505
02506
02507
02508 psms->flags |=
SMF_REPLY;
02509 psms->lRet = 0;
02510 psms->psmsReceiveNext =
NULL;
02511
SetWakeBit(psms->ptiSender, QS_SMSREPLY);
02512
02513
02514
02515
02516
02517
if (psms->ptiSender->TIF_flags &
TIF_16BIT) {
02518
DirectedScheduleTask(psms->ptiReceiver, psms->ptiSender,
FALSE, psms);
02519 }
02520 }
02521 }
02522 }
02523 }
02524
02525
02526
02527
02528
Unlock(&psms->spwnd);
02529 }
02530
02531 psms = psmsNext;
02532 }
02533 }
02534
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546
02547
VOID ReceiverDied(
02548 PSMS psms,
02549 PSMS *ppsmsUnlink)
02550 {
02551
PSMS *ppsms;
02552
PTHREADINFO ptiReceiver;
02553
PTHREADINFO ptiSender;
02554
02555
02556
02557
02558 ptiReceiver = psms->ptiReceiver;
02559 psms->ptiReceiver =
NULL;
02560 psms->flags |=
SMF_RECEIVERDIED;
02561
02562
02563
02564
02565
02566
if (!(ptiReceiver->
TIF_flags &
TIF_INCLEANUP)) {
02567
02568
02569
02570
02571
for (ppsms = &(ptiReceiver->
psmsReceiveList); *ppsms !=
NULL;
02572 ppsms = &((*ppsms)->psmsReceiveNext)) {
02573
02574
if (*ppsms == psms) {
02575 *ppsms = psms->psmsReceiveNext;
02576
break;
02577 }
02578 }
02579
02580
02581
02582
02583
if (ptiReceiver->
psmsReceiveList ==
NULL) {
02584 ptiReceiver->
pcti->
fsWakeBits &= ~QS_SENDMESSAGE;
02585 ptiReceiver->
pcti->
fsChangeBits &= ~QS_SENDMESSAGE;
02586 }
02587 }
else {
02588
02589
02590
02591
02592
02593 psms->flags &= ~
SMF_RECEIVERBUSY;
02594 }
02595
02596 psms->psmsReceiveNext =
NULL;
02597
02598
02599
02600
02601
02602
if (psms->ptiSender ==
NULL) {
02603
02604
if (!(psms->flags &
SMF_SENDERDIED) &&
02605 (psms->flags & (
SMF_CB_REQUEST |
SMF_REPLY)) ==
SMF_CB_REQUEST) {
02606
02607
02608
02609
02610
02611
TL tlpwnd;
02612
INTRSENDMSGEX ism;
02613
02614 psms->flags |=
SMF_REPLY;
02615
02616 ism.
fuCall =
ISM_CALLBACK |
ISM_REPLY;
02617
if (psms->flags &
SMF_CB_CLIENT)
02618 ism.
fuCall |=
ISM_CB_CLIENT;
02619 ism.
lpResultCallBack = psms->lpResultCallBack;
02620 ism.
dwData = psms->dwData;
02621 ism.
lRet = 0
L;
02622
02623
ThreadLock(psms->spwnd, &tlpwnd);
02624
02625
xxxInterSendMsgEx(psms->spwnd, psms->message, 0
L, 0
L,
02626
NULL, psms->ptiCallBackSender, &ism );
02627
02628
ThreadUnlock(&tlpwnd);
02629 }
02630
02631
02632
02633
02634
if (!(psms->flags &
SMF_RECEIVERBUSY))
02635
UnlinkSendListSms(psms, ppsmsUnlink);
02636
return;
02637
02638 }
else if (!(psms->flags &
SMF_REPLY)) {
02639
02640
02641
02642
02643 psms->flags |=
SMF_REPLY;
02644 psms->lRet = 0;
02645 psms->ptiReceiver =
NULL;
02646
02647
02648
02649
02650
SetWakeBit(psms->ptiSender, QS_SMSREPLY);
02651 }
else {
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661 psms->flags &= ~
SMF_RECEIVERFREE;
02662
SetWakeBit(psms->ptiSender, QS_SMSREPLY);
02663 }
02664
02665
02666
02667
02668
02669
02670 ptiSender = psms->ptiSender;
02671
if (ptiSender->
TIF_flags &
TIF_16BIT) {
02672
DirectedScheduleTask(ptiReceiver, ptiSender,
FALSE, psms);
02673 }
02674
02675
02676
02677
02678
02679
Unlock(&psms->spwnd);
02680 }
02681
02682
02683
02684
02685
02686
02687
02688
02689
02690
02691
02692
02693
VOID SenderDied(
02694 PSMS psms,
02695 PSMS *ppsmsUnlink)
02696 {
02697
PTHREADINFO ptiSender;
02698
BOOL fReply =
FALSE;
02699
02700
02701
02702
02703
if (psms->ptiSender !=
NULL)
02704 ptiSender = psms->ptiSender;
02705
else
02706 ptiSender = psms->ptiCallBackSender;
02707 psms->ptiSender =
NULL;
02708 psms->flags |=
SMF_SENDERDIED;
02709
02710
02711
02712
02713
02714
02715
02716
02717
02718
02719
02720
02721
02722
02723
if (psms->flags &
SMF_RECEIVERBUSY) {
02724 psms->flags |=
SMF_RECEIVERFREE;
02725 fReply =
TRUE;
02726 }
02727
02728
02729
02730
02731
02732
02733
02734
if (ptiSender->
psmsSent == psms)
02735 fReply =
TRUE;
02736
02737
02738
02739
02740
02741
if (!(ptiSender->
TIF_flags &
TIF_INCLEANUP) && fReply) {
02742
02743
02744
02745
02746 psms->flags |=
SMF_REPLY;
02747 psms->lRet = 0;
02748
02749
02750
02751
02752
SetWakeBit(ptiSender, QS_SMSREPLY);
02753
return;
02754 }
02755
02756
02757
02758
02759
02760
02761
02762
02763
02764
if ((psms->flags &
SMF_RECEIVERDIED) ||
02765 (psms->flags & (
SMF_REPLY |
SMF_RECEIVERFREE)) ==
SMF_REPLY) {
02766
UnlinkSendListSms(psms, ppsmsUnlink);
02767 }
else {
02768 psms->flags |=
SMF_RECEIVERFREE;
02769 }
02770 }
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780
02781
02782
02783
VOID UnlinkSendListSms(
02784 PSMS psms,
02785 PSMS *ppsmsUnlink)
02786 {
02787
#if DBG
02788
PSMS psmsT;
02789
BOOL fUpdateSendList;
02790
PSMS *ppsms;
02791
#endif
02792
02793
CheckCritIn();
02794
02795
#ifdef DEBUG_SMS
02796
ValidateSmsSendLists(psms);
02797
#endif
02798
02799 UserAssert(psms->psmsReceiveNext ==
NULL);
02800
02801
#if DBG
02802
02803
02804
02805
02806
02807 fUpdateSendList = (psms == psms->psmsSendList);
02808
02809
02810
02811
02812
02813 ppsms = &(psms->psmsSendList);
02814
while (*ppsms !=
NULL) {
02815
if (*ppsms == psms) {
02816 *ppsms = psms->psmsSendNext;
02817
break;
02818 }
02819 ppsms = &(*ppsms)->psmsSendNext;
02820 }
02821
02822
02823
02824
02825
02826
02827
if (fUpdateSendList) {
02828
for (psmsT = psms->psmsSendList; psmsT !=
NULL;
02829 psmsT = psmsT->psmsSendNext) {
02830 psmsT->psmsSendList = psms->psmsSendList;
02831 }
02832 }
02833
02834 psms->psmsSendList =
NULL;
02835
#endif
02836
02837
02838
02839
02840
if (ppsmsUnlink ==
NULL) {
02841 ppsmsUnlink = &
gpsmsList;
02842
02843
while (*ppsmsUnlink && (*ppsmsUnlink != psms)) {
02844 ppsmsUnlink = &((*ppsmsUnlink)->psmsNext);
02845 }
02846 }
02847
02848 UserAssert(*ppsmsUnlink);
02849
02850 *ppsmsUnlink = psms->psmsNext;
02851
02852
Unlock(&psms->spwnd);
02853
02854
#if DBG
02855
UserAssert(!(psms == psms->psmsSendList && psms->psmsSendNext != NULL));
02856
#endif
02857
02858
if (psms->pvCapture)
02859 UserFreePool(psms->pvCapture);
02860
02861 FreeSMS(psms);
02862 }
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
void xxxSendSizeMessage(
02875
PWND pwnd,
02876 UINT cmdSize)
02877 {
02878 RECT rc;
02879
CheckLock(pwnd);
02880
02881
02882
02883
02884
02885
02886
02887
_GetClientRect(pwnd, &rc);
02888
02889
xxxSendMessage(pwnd, WM_SIZE, cmdSize,
02890 MAKELONG(rc.right - rc.left, rc.bottom - rc.top));
02891 }
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904
VOID xxxProcessAsyncSendMessage(
02905
PASYNCSENDMSG pmsg)
02906 {
02907
PWND pwnd;
02908
TL tlpwndT;
02909 WCHAR awchString[
MAX_PATH];
02910 ATOM Atom = 0;
02911
LARGE_UNICODE_STRING str;
02912
02913 pwnd =
RevalidateHwnd(pmsg->
hwnd);
02914
if (pwnd !=
NULL) {
02915
ThreadLockAlways(pwnd, &tlpwndT);
02916
switch (pmsg->
message) {
02917
case WM_WININICHANGE:
02918
case WM_DEVMODECHANGE:
02919
if (pmsg->
lParam) {
02920
if (
UserGetAtomName((ATOM)pmsg->
lParam, awchString,
sizeof(awchString))) {
02921 Atom = (ATOM)pmsg->
lParam;
02922
RtlInitLargeUnicodeString(&str, awchString, (
UINT)-1);
02923 pmsg->
lParam = (LPARAM)&str;
02924 }
else {
02925 UserAssert(
FALSE);
02926 pmsg->
lParam = 0;
02927 }
02928 }
02929
break;
02930 }
02931
xxxSendMessage(pwnd, pmsg->
message, pmsg->
wParam, pmsg->
lParam);
02932
ThreadUnlock(&tlpwndT);
02933 }
02934
if (Atom) {
02935
UserDeleteAtom(Atom);
02936 }
02937 UserFreePool(pmsg);
02938 }
02939
02940
02941
02942
02943
02944
02945
02946
02947
02948
02949
02950 LONG
xxxBroadcastMessage(
02951
PWND pwnd,
02952 UINT message,
02953 WPARAM wParam,
02954 LPARAM lParam,
02955 UINT wCmd,
02956
PBROADCASTMSG pbcm)
02957 {
02958
PBWL pbwl;
02959 HWND *phwnd;
02960
TL tlpwnd;
02961
PASYNCSENDMSG pmsg;
02962
PPROCESSINFO ppiCurrent;
02963 LONG lRet =
TRUE;
02964
TL tlPool;
02965
PTHREADINFO ptiCurrent =
PtiCurrent();
02966
BOOL fPrivateMessage = (message >= WM_USER) && (message < MAXINTATOM);
02967
02968
if (fPrivateMessage) {
02969 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING,
"Attempt to broadcast a private message");
02970 }
02971
02972
if (pwnd ==
NULL) {
02973
LARGE_UNICODE_STRING str;
02974
PLARGE_STRING pstr;
02975
02976
02977
02978
02979
switch (message) {
02980
case WM_SPOOLERSTATUS:
02981
xxxSystemBroadcastMessage(message, wParam, lParam, wCmd, pbcm);
02982
return 1;
02983
02984
case WM_WININICHANGE:
02985
case WM_DEVMODECHANGE:
02986
02987
02988
02989
02990
if (lParam) {
02991
UINT cbAlloc;
02992
NTSTATUS Status;
02993
02994
02995
02996
02997
02998 pstr = ((
PLARGE_STRING)lParam);
02999
if (pstr->
bAnsi)
03000 cbAlloc = (pstr->
Length + 1) *
sizeof(WCHAR);
03001
else
03002 cbAlloc = pstr->
Length +
sizeof(WCHAR);
03003 str.
Buffer = UserAllocPoolWithQuota(cbAlloc, TAG_SMS_STRING);
03004
if (str.
Buffer ==
NULL) {
03005
return 0;
03006 }
03007 str.
MaximumLength = cbAlloc;
03008 str.
bAnsi =
FALSE;
03009
try {
03010
if (pstr->
bAnsi) {
03011
Status =
RtlMultiByteToUnicodeN(
03012 (PWCH)str.
Buffer,
03013 cbAlloc,
03014 &cbAlloc,
03015 (PCH)pstr->
Buffer,
03016 pstr->
Length
03017 );
03018 str.
Length = cbAlloc;
03019 }
else {
03020 str.
Length = pstr->
Length;
03021 RtlCopyMemory(str.
Buffer, pstr->
Buffer, str.
Length);
03022
Status = STATUS_SUCCESS;
03023 }
03024 str.
Buffer[str.
Length /
sizeof(WCHAR)] = 0;
03025 } except (W32ExceptionHandler(FALSE, RIP_WARNING)) {
03026
Status = GetExceptionCode();
03027 }
03028
if (!
NT_SUCCESS(Status)) {
03029 UserFreePool(str.
Buffer);
03030
return 0;
03031 }
03032 pstr->
Buffer = str.
Buffer;
03033 }
03034
if (lParam) {
03035
ThreadLockPool(ptiCurrent, str.
Buffer, &tlPool);
03036 }
03037
xxxSystemBroadcastMessage(message, wParam,
03038 lParam ? (LPARAM)&str : 0, wCmd, pbcm);
03039
if (lParam)
03040
ThreadUnlockAndFreePool(ptiCurrent, &tlPool);
03041
return 1;
03042
03043
case WM_TIMECHANGE:
03044
03045
03046
03047
03048
03049
if (!(ptiCurrent->
TIF_flags &
TIF_SYSTEMTHREAD)) {
03050 RIPMSG0(RIP_WARNING,
"Only system should broadcast WM_TIMECHANGE");
03051
return 0;
03052 }
03053
break;
03054 }
03055
03056 UserAssert(ptiCurrent->
rpdesk);
03057
03058 pwnd = ptiCurrent->
rpdesk->
pDeskInfo->
spwnd;
03059
03060
if (pwnd ==
NULL) {
03061 RIPERR0(ERROR_ACCESS_DENIED, RIP_WARNING,
"sender must have an associated desktop");
03062
return 0;
03063 }
03064 }
03065
03066 pbwl =
BuildHwndList(pwnd->
spwndChild, BWL_ENUMLIST, NULL);
03067
if (pbwl ==
NULL)
03068
return 0;
03069
03070 ppiCurrent =
PpiCurrent();
03071
03072
for (phwnd = pbwl->
rghwnd; *phwnd != (HWND)1; phwnd++) {
03073
03074
03075
03076
03077
if ((pwnd =
RevalidateHwnd(*phwnd)) ==
NULL)
03078
continue;
03079
03080
03081
03082
03083
if (!
fBroadcastProc(pwnd))
03084
continue;
03085
03086
if (fPrivateMessage &&
TestWF(pwnd, WFWIN40COMPAT)) {
03087
continue;
03088 }
03089
03090
03091
03092
03093
03094
if ((message == WM_PALETTEISCHANGING || message == WM_PALETTECHANGED) &&
03095 !
TestWF(pwnd, WFVISIBLE) &&
03096 !(
GETPTI(pwnd)->TIF_flags &
TIF_PALETTEAWARE)) {
03097
continue;
03098 }
03099
03100
ThreadLockAlways(pwnd, &tlpwnd);
03101
03102
switch (wCmd) {
03103
case BMSG_SENDMSG:
03104
xxxSendMessage(pwnd, message, wParam, lParam);
03105
break;
03106
03107
case BMSG_SENDNOTIFYMSG:
03108 {
03109 ATOM Atom = 0;
03110
03111
switch (message) {
03112
case WM_WININICHANGE:
03113
case WM_DEVMODECHANGE:
03114
if (lParam) {
03115
PLARGE_STRING pstr = (
PLARGE_STRING)lParam;
03116
03117
03118
03119
03120
if (pstr)
03121 Atom =
UserAddAtom(pstr->
Buffer, FALSE);
03122
if (!Atom) {
03123 lRet =
FALSE;
03124
break;
03125 }
03126 }
03127
03128
03129
03130
03131
03132 pmsg = UserAllocPool(
sizeof(
ASYNCSENDMSG),
03133 TAG_SMS_ASYNC);
03134
if (pmsg ==
NULL) {
03135
goto CleanupAtom;
03136 }
03137
03138 pmsg->
hwnd = *phwnd;
03139 pmsg->
message = message;
03140 pmsg->
wParam = wParam;
03141 pmsg->
lParam = Atom;
03142
03143
if (!
PostEventMessage(
GETPTI(pwnd),
GETPTI(pwnd)->pq,
03144 QEVENT_ASYNCSENDMSG,NULL, 0,
03145 (WPARAM)pmsg, 0)) {
03146
03147 UserFreePool(pmsg);
03148 CleanupAtom:
03149
if (Atom) {
03150
UserDeleteAtom(Atom);
03151 }
03152 lRet =
FALSE;
03153 }
03154
break;
03155
03156
default:
03157
03158
03159
03160
xxxSendNotifyMessage(pwnd, message, wParam, lParam);
03161
break;
03162 }
03163 }
03164
break;
03165
03166
case BMSG_SENDNOTIFYMSGPROCESS:
03167 UserAssert(message != WM_WININICHANGE && message != WM_DEVMODECHANGE);
03168
03169
03170
03171
03172
03173
03174
if ((
GETPTI(pwnd)->ppi == ppiCurrent) && !(
GETPTI(pwnd)->TIF_flags &
TIF_CSRSSTHREAD)) {
03175
xxxSendMessage(pwnd, message, wParam, lParam);
03176 }
else {
03177
xxxSendNotifyMessage(pwnd, message, wParam, lParam);
03178 }
03179
break;
03180
03181
case BMSG_POSTMSG:
03182
03183
03184
03185
if (pwnd->
spwndOwner ==
NULL)
03186
_PostMessage(pwnd, message, wParam, lParam);
03187
break;
03188
03189
case BMSG_SENDMSGCALLBACK:
03190
xxxSendMessageCallback(pwnd, message, wParam, lParam,
03191 pbcm->
cb.lpResultCallBack, pbcm->
cb.dwData, pbcm->
cb.bClientRequest);
03192
break;
03193
03194
case BMSG_SENDMSGTIMEOUT:
03195
xxxSendMessageTimeout(pwnd, message, wParam, lParam,
03196 pbcm->
to.fuFlags, pbcm->
to.uTimeout, pbcm->
to.lpdwResult);
03197
break;
03198 }
03199
03200
ThreadUnlock(&tlpwnd);
03201 }
03202
03203
FreeHwndList(pbwl);
03204
03205
03206
03207
03208
03209
03210
03211
03212
03213
03214
return 1;
03215 }