Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

sendmsg.c File Reference

#include "precomp.h"
#include "pnp.h"

Go to the source code of this file.

Defines

#define IsASwitchWnd(pw)   (gpsi->atomSysClass[ICLS_SWITCH] == pw->pcls->atomClassName)
#define IsOleMainThreadWnd(pw)   (gaOleMainThreadWndClass == pw->pcls->atomClassName)
#define fBroadcastProc(pwnd)   (!(ISAMENU(pwnd) || IsASwitchWnd(pwnd) || IsOleMainThreadWnd(pwnd)))
#define XXXSENDMESSAGETOCLIENT(pwnd, message, wParam, lParam, psms, fLock)
#define NoString   0
#define IsAnsiString   1
#define IsUnicodeString   2

Functions

VOID UnlinkSendListSms (PSMS, PSMS *)
VOID ReceiverDied (PSMS, PSMS *)
VOID SenderDied (PSMS, PSMS *)
NTSTATUS InitSMSLookaside (VOID)
PVOID StubAllocSMS (POOL_TYPE PoolType, SIZE_T uBytes, ULONG iTag)
VOID StubFreeSMS (PVOID p)
NTSTATUS InitSMSLookaside ()
PSMS AllocSMS (VOID)
void FreeSMS (PSMS psms)
BOOL _ReplyMessage (LRESULT lRet)
VOID UserLogError (PCWSTR pwszError, ULONG cbError, NTSTATUS ErrorCode)
BOOL xxxSendBSMtoDesktop (PWND pwndDesk, UINT message, WPARAM wParam, LPARAM lParam, LPBROADCASTSYSTEMMSGPARAMS pbsmParams)
LONG xxxSendMessageBSM (PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam, LPBROADCASTSYSTEMMSGPARAMS pbsmParams)
LRESULT xxxSendMessageFF (PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam, ULONG_PTR xParam)
LRESULT xxxSendMessageEx (PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam, ULONG_PTR xParam)
LRESULT xxxSendMessage (PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam)
LRESULT xxxSendMessageTimeout (PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam, UINT fuFlags, UINT uTimeout, PLONG_PTR lpdwResult)
void QueueNotifyMessage (PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam)
VOID xxxSystemBroadcastMessage (UINT message, WPARAM wParam, LPARAM lParam, UINT wCmd, PBROADCASTMSG pbcm)
BOOL xxxSendNotifyMessage (PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam)
BOOL xxxSendMessageCallback (PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam, SENDASYNCPROC lpResultCallBack, ULONG_PTR dwData, BOOL fClientRequest)
LRESULT xxxInterSendMsgEx (PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam, PTHREADINFO ptiSender, PTHREADINFO ptiReceiver, PINTRSENDMSGEX pism)
VOID xxxReceiveMessage (PTHREADINFO ptiReceiver)
VOID SendMsgCleanup (PTHREADINFO ptiCurrent)
VOID ClearSendMessages (PWND pwnd)
void xxxSendSizeMessage (PWND pwnd, UINT cmdSize)
VOID xxxProcessAsyncSendMessage (PASYNCSENDMSG pmsg)
LONG xxxBroadcastMessage (PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam, UINT wCmd, PBROADCASTMSG pbcm)

Variables

PPAGED_LOOKASIDE_LIST SMSLookaside


Define Documentation

#define fBroadcastProc pwnd   )     (!(ISAMENU(pwnd) || IsASwitchWnd(pwnd) || IsOleMainThreadWnd(pwnd)))
 

Definition at line 98 of file kernel/sendmsg.c.

Referenced by xxxSendBSMtoDesktop().

#define IsAnsiString   1
 

Definition at line 1293 of file kernel/sendmsg.c.

Referenced by xxxInterSendMsgEx().

#define IsASwitchWnd pw   )     (gpsi->atomSysClass[ICLS_SWITCH] == pw->pcls->atomClassName)
 

Definition at line 18 of file kernel/sendmsg.c.

#define IsOleMainThreadWnd pw   )     (gaOleMainThreadWndClass == pw->pcls->atomClassName)
 

Definition at line 21 of file kernel/sendmsg.c.

#define IsUnicodeString   2
 

Definition at line 1294 of file kernel/sendmsg.c.

Referenced by xxxInterSendMsgEx().

#define NoString   0
 

Definition at line 1292 of file kernel/sendmsg.c.

Referenced by NlsKbdInitializePerSystem(), and xxxInterSendMsgEx().

#define XXXSENDMESSAGETOCLIENT pwnd,
message,
wParam,
lParam,
psms,
fLock   ) 
 

Definition at line 705 of file kernel/sendmsg.c.

Referenced by xxxReceiveMessage(), xxxSendMessageCallback(), and xxxSendMessageTimeout().


Function Documentation

BOOL _ReplyMessage LRESULT  lRet  ) 
 

Definition at line 198 of file kernel/sendmsg.c.

References BOOL, CheckCritIn, DirectedScheduleTask(), tagINTERSENDMSGEX::dwData, FALSE, tagINTERSENDMSGEX::fuCall, INTRSENDMSGEX, ISM_CALLBACK, ISM_CB_CLIENT, ISM_REPLY, L, tagINTERSENDMSGEX::lpResultCallBack, tagINTERSENDMSGEX::lRet, NULL, PSMS, tagTHREADINFO::psmsCurrent, PtiCurrent, SetWakeBit(), SMF_CB_CLIENT, SMF_CB_REQUEST, SMF_REPLY, SMF_SENDERDIED, ThreadLockWithPti, ThreadUnlock, TIF_16BIT, tagTHREADINFO::TIF_flags, TRUE, xxxInterSendMsgEx(), and xxxSleepTask().

00200 { 00201 PTHREADINFO ptiCurrent; 00202 PSMS psms; 00203 00204 CheckCritIn(); 00205 00206 ptiCurrent = PtiCurrent(); 00207 00208 /* 00209 * Are we processing a SendMessage? 00210 */ 00211 psms = ptiCurrent->psmsCurrent; 00212 if (psms == NULL) 00213 return FALSE; 00214 00215 /* 00216 * See if the reply has been made already. 00217 */ 00218 if (psms->flags & SMF_REPLY) 00219 return FALSE; 00220 00221 /* 00222 * Blow off the rest of the call if the SMS came 00223 * from xxxSendNotifyMessage(). Obviously there's 00224 * no one around to reply to in the case. 00225 */ 00226 if (psms->ptiSender != NULL) { 00227 00228 /* 00229 * Reply to this message. The sender should not free the SMS 00230 * because the receiver still considers it valid. Thus we 00231 * mark it with a special bit indicating it has been replied 00232 * to. We wait until both the sender and receiver are done 00233 * with the sms before we free it. 00234 */ 00235 psms->lRet = lRet; 00236 psms->flags |= SMF_REPLY; 00237 00238 /* 00239 * Wake up the sender. 00240 * ??? why don't we test that psms == ptiSender->psmsSent? 00241 */ 00242 SetWakeBit(psms->ptiSender, QS_SMSREPLY); 00243 } else if (psms->flags & SMF_CB_REQUEST) { 00244 00245 /* 00246 * From SendMessageCallback REQUEST callback. Send the message 00247 * back with a the REPLY value. 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, 0L, 0L, 00265 NULL, psms->ptiCallBackSender, &ism ); 00266 00267 ThreadUnlock(&tlpwnd); 00268 } 00269 } 00270 00271 /* 00272 * We have 4 conditions to satisfy: 00273 * 00274 * 16 - 16 : receiver yields if sender is waiting for this reply 00275 * 32 - 16 : receiver yields if sender is waiting for this reply 00276 * 16 - 32 : no yield required 00277 * 32 - 32 : No yielding required. 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 }

PSMS AllocSMS VOID   ) 
 

Definition at line 164 of file kernel/sendmsg.c.

References ExAllocateFromPagedLookasideList(), PSMS, and SMSLookaside.

Referenced by xxxInterSendMsgEx().

00166 { 00167 return ExAllocateFromPagedLookasideList(SMSLookaside); 00168 }

VOID ClearSendMessages PWND  pwnd  ) 
 

Definition at line 2400 of file kernel/sendmsg.c.

Referenced by xxxFreeWindow().

02409 : 02410 * 01-13-91 DavidPe Ported. 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 * Grab the next one beforehand in case we free the current one. 02425 */ 02426 psmsNext = psms->psmsNext; 02427 02428 if (psms->spwnd == pwnd) { 02429 02430 /* 02431 * If the sender has died, then mark this receiver free so the 02432 * receiver will destroy it in its processing. 02433 */ 02434 if (psms->flags & SMF_SENDERDIED) { 02435 psms->flags |= SMF_REPLY | SMF_RECEIVERFREE; 02436 } else { 02437 /* 02438 * The sender is alive. If the receiver hasn't replied to 02439 * this yet, make a reply so the sender gets it. Make sure 02440 * the receiver is the one free it so we don't have a race 02441 * condition. 02442 */ 02443 if (!(psms->flags & SMF_REPLY)) { 02444 02445 /* 02446 * The sms is either still on the receive list 02447 * or is currently being received. Since the sender 02448 * is alive, we want the sender to get the reply 02449 * to this SMS. If it hasn't been received, take 02450 * it off the receive list and reply to it. If it 02451 * has been received, then just leave it alone: 02452 * it'll get replied to normally. 02453 */ 02454 if (psms->flags & SMF_CB_REQUEST) { 02455 /* 02456 * From SendMessageCallback REQUEST callback. Send the 02457 * message back with a the REPLY value. 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 = 0L; /* null return */ 02470 02471 ThreadLock(psms->spwnd, &tlpwnd); 02472 02473 xxxInterSendMsgEx(psms->spwnd, psms->message, 0L, 0L, 02474 NULL, psms->ptiCallBackSender, &ism ); 02475 02476 ThreadUnlock(&tlpwnd); 02477 } else if (!(psms->flags & SMF_RECEIVERBUSY)) { 02478 /* 02479 * If there is no sender, this is a notification 02480 * message (nobody to reply to). In this case, 02481 * just set the SMF_REPLY bit (SMF_RECEIVERFREE 02482 * is already set) and this'll cause ReceiveMessage 02483 * to just free this SMS and return. 02484 */ 02485 if (psms->ptiSender == NULL) { 02486 psms->flags |= SMF_REPLY; 02487 } else { 02488 /* 02489 * There is a sender, and it wants a reply: take 02490 * this SMS off the receive list, and reply 02491 * to the sender. 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 * Reply to this message so the sender 02506 * wakes up. 02507 */ 02508 psms->flags |= SMF_REPLY; 02509 psms->lRet = 0; 02510 psms->psmsReceiveNext = NULL; 02511 SetWakeBit(psms->ptiSender, QS_SMSREPLY); 02512 02513 /* 02514 * 16 bit senders need to be notifed that sends completed 02515 * otherwise it may wait for a very long time for the reply. 02516 */ 02517 if (psms->ptiSender->TIF_flags & TIF_16BIT) { 02518 DirectedScheduleTask(psms->ptiReceiver, psms->ptiSender, FALSE, psms); 02519 } 02520 } }

void FreeSMS PSMS  psms  ) 
 

Definition at line 178 of file kernel/sendmsg.c.

References ExFreeToPagedLookasideList(), and SMSLookaside.

Referenced by Win32kNtUserCleanup(), and xxxInterSendMsgEx().

00180 { 00181 ExFreeToPagedLookasideList(SMSLookaside, psms); 00182 }

NTSTATUS InitSMSLookaside  ) 
 

Definition at line 137 of file kernel/sendmsg.c.

References ExInitializePagedLookasideList(), NULL, POOL_QUOTA_FAIL_INSTEAD_OF_RAISE, SMS, SMSLookaside, StubAllocSMS(), and StubFreeSMS().

Referenced by Win32UserInitialize().

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 }

NTSTATUS InitSMSLookaside VOID   ) 
 

void QueueNotifyMessage PWND  pwnd,
UINT  message,
WPARAM  wParam,
LPARAM  lParam
 

Definition at line 969 of file kernel/sendmsg.c.

Referenced by CancelInputState(), DoQueuedSyncPaint(), xxxActivateApp(), xxxResetDisplayDevice(), and xxxSendBSMtoDesktop().

00987 {

VOID ReceiverDied PSMS  ,
PSMS
 

Definition at line 2534 of file kernel/sendmsg.c.

References DirectedScheduleTask(), tagINTERSENDMSGEX::dwData, FALSE, tagCLIENTTHREADINFO::fsChangeBits, tagCLIENTTHREADINFO::fsWakeBits, tagINTERSENDMSGEX::fuCall, ISM_CALLBACK, ISM_CB_CLIENT, ISM_REPLY, L, tagINTERSENDMSGEX::lpResultCallBack, tagINTERSENDMSGEX::lRet, NULL, tagTHREADINFO::pcti, PSMS, tagTHREADINFO::psmsReceiveList, SetWakeBit(), SMF_CB_CLIENT, SMF_CB_REQUEST, SMF_RECEIVERBUSY, SMF_RECEIVERDIED, SMF_RECEIVERFREE, SMF_REPLY, SMF_SENDERDIED, ThreadLock, ThreadUnlock, TIF_16BIT, tagTHREADINFO::TIF_flags, TIF_INCLEANUP, UnlinkSendListSms(), Unlock, VOID(), and xxxInterSendMsgEx().

02543 : 02544 * 01-13-91 DavidPe Ported. 02545 \***********************************************************************/ 02546 02547 VOID ReceiverDied( 02548 PSMS psms, 02549 PSMS *ppsmsUnlink) 02550 { 02551 PSMS *ppsms; 02552 PTHREADINFO ptiReceiver; 02553 PTHREADINFO ptiSender; 02554 02555 /* 02556 * mark that the receiver died 02557 */ 02558 ptiReceiver = psms->ptiReceiver; 02559 psms->ptiReceiver = NULL; 02560 psms->flags |= SMF_RECEIVERDIED; 02561 02562 /* 02563 * Unlink sms from thread if it is not dying. We need to do 02564 * this for journal cleanup. 02565 */ 02566 if (!(ptiReceiver->TIF_flags & TIF_INCLEANUP)) { 02567 02568 /* 02569 * unlink sms from the receiver's receive list 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 * clear the QS_SENDMESSAGE bit if there are no more messages 02582 */ 02583 if (ptiReceiver->psmsReceiveList == NULL) { 02584 ptiReceiver->pcti->fsWakeBits &= ~QS_SENDMESSAGE; 02585 ptiReceiver->pcti->fsChangeBits &= ~QS_SENDMESSAGE; 02586 } 02587 } else { 02588 02589 /* 02590 * The receiver thread is dying. Clear the received flag 02591 * so that if there is a sender, it will free the sms. 02592 */ 02593 psms->flags &= ~SMF_RECEIVERBUSY; 02594 } 02595 02596 psms->psmsReceiveNext = NULL; 02597 02598 /* 02599 * Check if the sender died or if the receiver was marked to 02600 * free the sms. 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 * From SendMessageCallback REQUEST callback. Send the message 02609 * back with a the REPLY value. 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 = 0L; /* null return */ 02622 02623 ThreadLock(psms->spwnd, &tlpwnd); 02624 02625 xxxInterSendMsgEx(psms->spwnd, psms->message, 0L, 0L, 02626 NULL, psms->ptiCallBackSender, &ism ); 02627 02628 ThreadUnlock(&tlpwnd); 02629 } 02630 02631 /* 02632 * If the receiver is not processing the message, free it. 02633 */ 02634 if (!(psms->flags & SMF_RECEIVERBUSY)) 02635 UnlinkSendListSms(psms, ppsmsUnlink); 02636 return; 02637 02638 } else if (!(psms->flags & SMF_REPLY)) { 02639 02640 /* 02641 * fake a reply 02642 */ 02643 psms->flags |= SMF_REPLY; 02644 psms->lRet = 0; 02645 psms->ptiReceiver = NULL; 02646 02647 /* 02648 * wake the sender if he was waiting for us 02649 */ 02650 SetWakeBit(psms->ptiSender, QS_SMSREPLY); 02651 } else { 02652 /* 02653 * There is a reply. We know the receiver is dying, so clear the 02654 * SMF_RECEIVERFREE bit or the sender won't free this SMS! 02655 * Although the sender's wake bit has already been set by the 02656 * call to ClearSendMessages() earlier in the cleanup code, 02657 * set it here again for safety. 02658 * 02659 * ??? Why would SMF_RECEIVERFREE be set? 02660 */ 02661 psms->flags &= ~SMF_RECEIVERFREE; 02662 SetWakeBit(psms->ptiSender, QS_SMSREPLY); 02663 } 02664 02665 /* 02666 * If the sender is a WOW task, that task is now blocked in the non- 02667 * preemptive scheduler waiting for a reply. DestroyTask will * clean this up (even if ptiReceiver is 32-bit).

VOID SenderDied PSMS  ,
PSMS
 

Definition at line 2680 of file kernel/sendmsg.c.

Referenced by SendMsgCleanup().

02689 : 02690 * 01-13-91 DavidPe Ported. 02691 \***********************************************************************/ 02692 02693 VOID SenderDied( 02694 PSMS psms, 02695 PSMS *ppsmsUnlink) 02696 { 02697 PTHREADINFO ptiSender; 02698 BOOL fReply = FALSE; 02699 02700 /* 02701 * mark the death 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 * There are two cases where we leave the sms alone so the receiver 02712 * can handle the message and then free the sms itself. 02713 * 02714 * 1. When the receiver is processing the message. 02715 * 02716 * 2. When the message has not yet been received. 02717 */ 02718 02719 /* 02720 * If the receiver is processing the message, make it free the sms. 02721 * Fake a reply for journal cancel. 02722 */ 02723 if (psms->flags & SMF_RECEIVERBUSY) { 02724 psms->flags |= SMF_RECEIVERFREE; 02725 fReply = TRUE; 02726 } 02727 02728 /* 02729 * This sms may be in the process of being sent, but has not yet 02730 * been received. In so, fake a reply and wake the sender. 02731 * The last thread to touch the sms, either the sender or 02732 * receiver, will free the sms. 02733 */ 02734 if (ptiSender->psmsSent == psms) 02735 fReply = TRUE; 02736 02737 /* 02738 * If journalling is being cancelled and reply needs to be made, 02739 * fake a reply and return. 02740 */ 02741 if (!(ptiSender->TIF_flags & TIF_INCLEANUP) && fReply) { 02742 02743 /* 02744 * fake a reply 02745 */ 02746 psms->flags |= SMF_REPLY; 02747 psms->lRet = 0; 02748 02749 /* 02750 * wake the sender if he was waiting for us 02751 */ 02752 SetWakeBit(ptiSender, QS_SMSREPLY); 02753 return; 02754 } 02755 02756 /* 02757 * If the receiver isn't dead, check to see if it has honestly replied to * this SMS. If it has not replied, leave it alone so the receiver can

VOID SendMsgCleanup PTHREADINFO  ptiCurrent  ) 
 

Definition at line 2364 of file kernel/sendmsg.c.

References CheckCritIn, gpsmsList, PSMS, ReceiverDied(), SenderDied(), and VOID().

Referenced by xxxDestroyThreadInfo(), and zzzCancelJournalling().

02364 : free sms 02365 * R replied, R dies: no problem 02366 * 02367 * double death: 02368 * R no reply, S dies, R dies: free sms 02369 * R no reply, R dies, S dies: free sms 02370 * R replied, S dies, R dies: sms freed when S dies, as in single death 02371 * R replied, R dies, S dies: sms freed when S dies, as in single death 02372 * 02373 * History: 02374 * 01-13-91 DavidPe Ported. 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 ||

PVOID StubAllocSMS POOL_TYPE  PoolType,
SIZE_T  uBytes,
ULONG  iTag
 

Definition at line 111 of file kernel/sendmsg.c.

Referenced by InitSMSLookaside().

00115 { 00116 return UserAllocPool(uBytes, iTag); 00117 00118 UNREFERENCED_PARAMETER(PoolType); 00119 }

VOID StubFreeSMS PVOID  p  ) 
 

Definition at line 121 of file kernel/sendmsg.c.

References VOID().

Referenced by InitSMSLookaside().

00123 { 00124 UserFreePool(p); 00125 }

VOID UnlinkSendListSms PSMS  ,
PSMS
 

Definition at line 2770 of file kernel/sendmsg.c.

Referenced by ReceiverDied(), xxxInterSendMsgEx(), and xxxReceiveMessage().

02779 : 02780 * 01-13-91 DavidPe Ported. 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 * Remember ahead of time if the psms we're unlinking is also the 02804 * head of the sms send list (so we know if we need to update this field 02805 * member in every SMS in this list). 02806 */ 02807 fUpdateSendList = (psms == psms->psmsSendList); 02808 02809 /* 02810 * Unlink sms from the sendlist chain. This effectively unlinks the SMS 02811 * and updates psms->psmsSendList with the right head.... 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 * Update psmsSendList if necessary. psms->psmsSendList has been updated 02824 * with the right sms send list head... distribute this head to all other 02825 * sms's in this chain if this sms we're removing the current head. 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 * This unlinks an sms structure from the global gpsmsList and frees it. 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 *ppsmsUnlink = psms->psmsNext;

VOID UserLogError PCWSTR  pwszError,
ULONG  cbError,
NTSTATUS  ErrorCode
 

Definition at line 292 of file kernel/sendmsg.c.

References gpWin32kDriverObject, IoAllocateErrorLogEntry(), and IoWriteErrorLogEntry().

Referenced by xxxSendBSMtoDesktop().

00296 { 00297 PIO_ERROR_LOG_PACKET perrLogEntry; 00298 00299 /* 00300 * Allocate an error packet, fill it out, and write it to the log. 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 }

LONG xxxBroadcastMessage PWND  pwnd,
UINT  message,
WPARAM  wParam,
LPARAM  lParam,
UINT  wCmd,
PBROADCASTMSG  pbcm
 

Definition at line 2937 of file kernel/sendmsg.c.

Referenced by _PostMessage(), xxxBroadcastDisplaySettingsChange(), xxxSendMessageCallback(), xxxSendMessageTimeout(), xxxSystemBroadcastMessage(), and xxxUserResetDisplayDevice().

02946 : 02947 * 02-21-91 DavidPe Created. 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 * Handle special system-wide broadcasts. 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 * Probe and capture the string. 02989 */ 02990 if (lParam) { 02991 UINT cbAlloc; 02992 NTSTATUS Status; 02993 02994 /* 02995 * Allocate a temp buffer and convert 02996 * the string to Unicode 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 * We automatically broadcast a WM_TIMECHANGE message whenever the 03046 * kernel tells us the time has changed, so blow off any apps who 03047 * are trying to do the same thing. 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 * Make sure this hwnd is still around. 03076 */ 03077 if ((pwnd = RevalidateHwnd(*phwnd)) == NULL) 03078 continue; 03079 03080 /* 03081 * Make sure this window can handle broadcast messages 03082 */ 03083 if (!fBroadcastProc(pwnd)) 03084 continue; 03085 03086 if (fPrivateMessage && TestWF(pwnd, WFWIN40COMPAT)) { // Don't broadcast 03087 continue; // private message 03088 } // to 4.0 apps. 03089 03090 /* 03091 * Don't bother sending palette messages to windows that are not 03092 * visible on threads that are not palette aware. 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 * Convert strings to atoms for the post. 03119 */ 03120 if (pstr) 03121 Atom = UserAddAtom(pstr->Buffer, FALSE); 03122 if (!Atom) { 03123 lRet = FALSE; 03124 break; 03125 } 03126 } 03127 03128 /* 03129 * These messages need to be able to cross 03130 * desktops so PostEvent 'em. 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 * A regular kind of guy. No desktop crossing. 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 * Intra-process messages are synchronous; 22238. 03171 * WM_PALETTECHANGED was being sent after the WM_DESTROY 03172 * but console thread must not be synchronous. 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 * Don't broadcast-post to owned windows (Win3.1 compatiblilty) 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 FreeHwndList(pbwl);

LRESULT xxxInterSendMsgEx PWND  pwnd,
UINT  message,
WPARAM  wParam,
LPARAM  lParam,
PTHREADINFO  ptiSender,
PTHREADINFO  ptiReceiver,
PINTRSENDMSGEX  pism
 

Definition at line 1296 of file kernel/sendmsg.c.

References AllocSMS(), _LARGE_STRING::bAnsi, BOOL, _LARGE_STRING::Buffer, tagTHREADINFO::cEnterCount, CheckCritIn, CMSHUNGAPPTIMEOUT, DirectedScheduleTask(), tagINTERSENDMSGEX::dwData, DWORD, EFPASSWORD, FALSE, FHungApp(), FNID_EDIT, FreeSMS(), tagCLIENTTHREADINFO::fsChangeBits, tagINTERSENDMSGEX::fuCall, tagINTERSENDMSGEX::fuSend, GETFNID, GETPTI, gpsmsList, INT, IS_SYSTEM_ADDRESS, IsAnsiString, ISM_CALLBACK, ISM_CB_CLIENT, ISM_REPLY, IsUnicodeString, KeSetKernelStackSwapEnable(), _LARGE_STRING::Length, Lock, tagINTERSENDMSGEX::lpdwResult, tagINTERSENDMSGEX::lpResultCallBack, LPVOID, tagINTERSENDMSGEX::lRet, _LARGE_STRING::MaximumLength, _MDICREATESTRUCTEX::mdics, NoString, NtGetTickCount(), NULL, PBYTE, tagTHREADINFO::pcti, PpiCurrent, PSMS, tagTHREADINFO::psmsCurrent, tagTHREADINFO::psmsReceiveList, tagTHREADINFO::psmsSent, PtiCurrent, SetWakeBit(), SMF_CB_CLIENT, SMF_CB_REPLY, SMF_CB_REQUEST, SMF_CB_SERVER, SMF_RECEIVEDMESSAGE, SMF_RECEIVERBUSY, SMF_RECEIVERFREE, SMF_REPLY, _MDICREATESTRUCTEX::strClass, strncpycch(), _MDICREATESTRUCTEX::strTitle, TestWF, TIF_16BIT, tagTHREADINFO::TIF_flags, TIF_INCLEANUP, TRUE, UINT, UnlinkSendListSms(), tagINTERSENDMSGEX::uTimeout, wcsncpycch(), and xxxSleepThread().

Referenced by _ReplyMessage(), ReceiverDied(), xxxCallHook2(), xxxReceiveMessage(), xxxSendMessageCallback(), and xxxSendMessageTimeout().

01301 : 01302 * 07-13-92 ChrisBl Created/extended from xxxInterSendMsg 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 * If the sender is dying, fail the call 01337 */ 01338 if ((ptiSender != NULL) && (ptiSender->TIF_flags & TIF_INCLEANUP)) 01339 return 0; 01340 01341 /* 01342 * Some messages cannot be sent across process because we don't know how to thunk them 01343 * Fail attempts to read passwords across processes. 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 * Alloc SMS structure. 01365 */ 01366 psms = AllocSMS(); 01367 if (psms == NULL) { 01368 01369 /* 01370 * Set to zero so xxxSendNotifyMessage would return FALSE. 01371 */ 01372 return 0; 01373 } 01374 01375 /* 01376 * Prepare to capture variable length data from client 01377 * space. Addresses have already been probed. Fixed-length 01378 * data is probed and captured in the message thunk. 01379 */ 01380 psms->pvCapture = NULL; 01381 cbCapture = cbOutput = 0; 01382 lpCapture = (LPBYTE)lParam; 01383 01384 /* 01385 * For messages with indirect data, set cbCapture and lpCapture 01386 * (if not lParam) as approp. 01387 */ 01388 try { 01389 switch (message) { 01390 case WM_COPYGLOBALDATA: // fnCOPYGLOBALDATA 01391 cbCapture = (DWORD)wParam; 01392 break; 01393 01394 case WM_COPYDATA: // fnCOPYDATA 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: // fnINLPCREATESTRUCT 01404 case WM_NCCREATE: // fnINLPCREATESTRUCT 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: // fnINLPHELPINFOSTRUCT 01410 phelpinfo = (LPHELPINFO)lParam; 01411 cbCapture = phelpinfo->cbSize; 01412 break; 01413 01414 case WM_WINHELP: // fnINLPHLPSTRUCT 01415 phlp = (LPHLP)lParam; 01416 cbCapture = phlp->cbData; 01417 break; 01418 01419 case WM_MDICREATE: // fnINLPMDICREATESTRUCT 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: // INLBOXSTRING calls fnINSTRING 01429 case LB_INSERTSTRING: // INLBOXSTRING calls fnINSTRING 01430 case LB_SELECTSTRING: // INLBOXSTRING calls fnINSTRING 01431 case LB_FINDSTRING: // INLBOXSTRING calls fnINSTRING 01432 case LB_FINDSTRINGEXACT: // INLBOXSTRING calls fnINSTRING 01433 /* 01434 * See if the control is ownerdraw and does not have the LBS_HASSTRINGS 01435 * style. If so, treat lParam as a DWORD. 01436 */ 01437 if (pwnd && !(pwnd->style & LBS_HASSTRINGS) && 01438 (pwnd->style & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE))) { 01439 /* 01440 * Treat lParam as a dword. 01441 */ 01442 break; 01443 } else { 01444 goto fnINSTRINGThunk; 01445 } 01446 break; 01447 01448 case CB_ADDSTRING: // INCBOXSTRING calls fnINSTRING 01449 case CB_INSERTSTRING: // INCBOXSTRING calls fnINSTRING 01450 case CB_SELECTSTRING: // INCBOXSTRING calls fnINSTRING 01451 case CB_FINDSTRING: // INCBOXSTRING calls fnINSTRING 01452 case CB_FINDSTRINGEXACT: // INCBOXSTRING calls fnINSTRING 01453 /* 01454 * See if the control is ownerdraw and does not have the CBS_HASSTRINGS 01455 * style. If so, treat lParam as a DWORD. 01456 */ 01457 if (pwnd && !(pwnd->style & CBS_HASSTRINGS) && 01458 (pwnd->style & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE))) { 01459 01460 /* 01461 * Treat lParam as a dword. 01462 */ 01463 break; 01464 } else { 01465 goto fnINSTRINGThunk; 01466 } 01467 break; 01468 01469 case EM_REPLACESEL: // fnINSTRINGNULL 01470 case WM_SETTEXT: // fnINSTRINGNULL 01471 case WM_WININICHANGE: // fnINSTRINGNULL 01472 if (lParam == 0) 01473 break; 01474 01475 /* 01476 * Fall through 01477 */ 01478 01479 case CB_DIR: // fnINSTRING 01480 case LB_ADDFILE: // fnINSTRING 01481 case LB_DIR: // fnINSTRING 01482 case WM_DEVMODECHANGE: // fnINSTRING 01483 fnINSTRINGThunk: 01484 01485 /* 01486 * Only capture strings if they are not in system space 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 * Only capture data if lParam is a pointer and 01501 * the data is not in system space 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: // fnPOPTINLPUINT 01513 case LB_SETTABSTOPS: // fnPOPTINLPUINT 01514 case LB_GETSELITEMS: // fnPOUTLPINT 01515 cbCapture = (UINT)wParam * sizeof(INT); 01516 break; 01517 01518 case EM_GETLINE: // fnINCNTOUTSTRING 01519 case WM_ASKCBFORMATNAME: // fnINCNTOUTSTRINGNULL 01520 case WM_GETTEXT: // fnOUTSTRING 01521 case LB_GETTEXT: // fnOUTLBOXSTRING 01522 case CB_GETLBTEXT: // fnOUTCBOXSTRING 01523 01524 /* 01525 * Only allocate output buffer if the real one is not in system space 01526 */ 01527 str = *(PLARGE_STRING)lParam; 01528 /* 01529 * Bug 18108. For WM_GETTEXT only copy the actual string and not the 01530 * the maximum size into the output buffer 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 * now actually copy memory from lpCapture to psms->pvCapture 01549 * and fixup any references to the indirect data to point to 01550 * psms->pvCapture. 01551 */ 01552 switch (message) { 01553 case WM_COPYDATA: // fnCOPYDATA 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: // fnINLPMDICREATESTRUCT 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: // fnINSTRING 01579 case LB_FINDSTRING: // INLBOXSTRING calls fnINSTRING 01580 case LB_FINDSTRINGEXACT: // INLBOXSTRING calls fnINSTRING 01581 case CB_FINDSTRING: // INCBOXSTRING calls fnINSTRING 01582 case CB_FINDSTRINGEXACT: // INCBOXSTRING calls fnINSTRING 01583 case LB_ADDFILE: // fnINSTRING 01584 case LB_ADDSTRING: // INLBOXSTRING calls fnINSTRING 01585 case LB_INSERTSTRING: // INLBOXSTRING calls fnINSTRING 01586 case LB_SELECTSTRING: // INLBOXSTRING calls fnINSTRING 01587 case CB_ADDSTRING: // INCBOXSTRING calls fnINSTRING 01588 case CB_INSERTSTRING: // INCBOXSTRING calls fnINSTRING 01589 case CB_SELECTSTRING: // INCBOXSTRING calls fnINSTRING 01590 case LB_DIR: // fnINSTRING 01591 case WM_DEVMODECHANGE: // fnINSTRING 01592 case EM_REPLACESEL: // fnINSTRINGNULL 01593 case WM_SETTEXT: // fnINSTRINGNULL 01594 case WM_WININICHANGE: // fnINSTRINGNULL 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: // fnINCNTOUTSTRING 01606 *(WORD *)psms->pvCapture = *(WORD *)str.Buffer; 01607 01608 /* 01609 * Fall through 01610 */ 01611 case WM_ASKCBFORMATNAME: // fnINCNTOUTSTRINGNULL 01612 case WM_GETTEXT: // fnOUTSTRING 01613 case LB_GETTEXT: // fnOUTLBOXSTRING 01614 case CB_GETLBTEXT: // fnOUTCBOXSTRING 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 * Copy message parms 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 * Link into gpsmsList 01655 */ 01656 psms->psmsNext = gpsmsList; 01657 gpsmsList = psms; 01658 01659 /* 01660 * Time stamp message 01661 */ 01662 psms->tSent = NtGetTickCount(); 01663 01664 /* 01665 * Set queue fields 01666 */ 01667 psms->ptiReceiver = ptiReceiver; 01668 psms->ptiSender = ptiSender; 01669 psms->ptiCallBackSender = NULL; 01670 01671 if ((pism != NULL) && (pism->fuCall & ISM_CALLBACK)) { 01672 /* 01673 * Setup for a SendMessageCallback 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 { /* REQUEST */ 01683 psms->flags |= SMF_CB_REQUEST; 01684 psms->ptiCallBackSender = PtiCurrent(); 01685 } 01686 } 01687 01688 /* 01689 * Add SMS to the end of the ptiReceiver's receive list 01690 */ 01691 ppsms = &ptiReceiver->psmsReceiveList; 01692 while (*ppsms != NULL) { 01693 ppsms = &((*ppsms)->psmsReceiveNext); 01694 } 01695 *ppsms = psms; 01696 01697 /* 01698 * Link this SMS into the SendMsg chain. Of course only do this if 01699 * it's not from a xxxSendNotifyMessage() call. 01700 * 01701 * The psmsSendNext field implements a chain of messages being 01702 * processed because of an initial SendMsg call. For example, if 01703 * thread A sends message M1 to thread B, which causes B to send 01704 * message M2 to thread C, the SendMsg chain is M1->M2. If the 01705 * system hangs in this situation, the chain is traversed to find 01706 * the offending thread (C). 01707 * 01708 * psms->psmsSendList always points to the head of this list so 01709 * we can tell where to begin a list traversal. 01710 * 01711 * ptiSender->psmsCurrent is the last SMS in the chain. 01712 */ 01713 #if DBG 01714 if (ptiSender != NULL && ptiSender->psmsCurrent != NULL) { 01715 /* 01716 * sending queue is currently processing a message sent to it, 01717 * so append SMS to the chain. Link in the new sms because 01718 * psmsSendNext may be pointing to a replied-to message. 01719 */ 01720 psms->psmsSendNext = ptiSender->psmsCurrent->psmsSendNext; 01721 ptiSender->psmsCurrent->psmsSendNext = psms; 01722 psms->psmsSendList = ptiSender->psmsCurrent->psmsSendList; 01723 01724 } else { 01725 /* 01726 * sending queue is initiating a send sequence, so put sms at 01727 * the head of the chain 01728 */ 01729 psms->psmsSendList = psms; 01730 } 01731 #endif 01732 01733 if (ptiSender != NULL) { 01734 /* 01735 * ptiSender->psmsSent marks the most recent message sent from this 01736 * thread that has not yet been replied to. Save the previous value 01737 * on the stack so it can be restored when we get the reply. 01738 * 01739 * This way when an "older" SMS for this thread gets a reply before 01740 * the "current" one does, the thread does get woken up. 01741 */ 01742 psmsSentSave = ptiSender->psmsSent; 01743 ptiSender->psmsSent = psms; 01744 } else { 01745 01746 /* 01747 * Set SMF_RECEIVERFREE since we'll be returning to 01748 * xxxSendNotifyMessage() right away and won't get a 01749 * chance to free it. 01750 */ 01751 psms->flags |= SMF_RECEIVERFREE; 01752 } 01753 01754 #ifdef DEBUG_SMS 01755 ValidateSmsSendLists(psms); 01756 #endif 01757 01758 /* 01759 * If we're not being called from xxxSendNotifyMessage() or 01760 * SendMessageCallback(), then sleep while we wait for the reply. 01761 */ 01762 if (ptiSender == NULL) { 01763 /* 01764 * Wake receiver for the sent message 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 * Wake up the receiver thread. 01776 */ 01777 SetWakeBit(ptiReceiver, QS_SENDMESSAGE); 01778 01779 /* 01780 * We have 4 sending cases: 01781 * 01782 * 16 - 16 : yield to the 16 bit receiver 01783 * 32 - 16 : no yielding required 01784 * 16 - 32 : sender yields while receiver processes the message 01785 * 32 - 32 : no yielding required. 01786 */ 01787 if (ptiSender->TIF_flags & TIF_16BIT || ptiReceiver->TIF_flags & TIF_16BIT) { 01788 DirectedScheduleTask(ptiSender, ptiReceiver, TRUE, psms); 01789 } 01790 01791 /* 01792 * Put this thread to sleep until the reply arrives. First clear 01793 * the QS_SMSREPLY bit, then leave the semaphore and go to sleep. 01794 * 01795 * IMPORTANT: The QS_SMSREPLY bit is not cleared once we get a 01796 * reply because of the following case: 01797 * 01798 * We've recursed a second level into SendMessage() when the first level 01799 * receiver thread dies, causing exit list processing to simulate 01800 * a reply to the first message. When the second level send returns, 01801 * SleepThread() is called again to get the first reply. 01802 * 01803 * Keeping QS_SMSREPLY set causes this call to SleepThread() 01804 * to return without going to sleep to wait for the reply that has 01805 * already happened. 01806 */ 01807 if ( pism != NULL ) { 01808 if (pism->fuSend & SMTO_BLOCK) { 01809 /* 01810 * only wait for a return, all other events will 01811 * be ignored until timeout or return 01812 */ 01813 uWakeMask |= QS_EXCLUSIVE; 01814 } 01815 01816 uTimeout = pism->uTimeout; 01817 } 01818 01819 01820 /* 01821 * Don't swap this guys stack while sleeping during a sendmessage 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 * If SendMessageTimeout, sleep for timeout amount, else wait 01836 * forever. Since this is not technically a transition to an 01837 * idle condition, indicate that this sleep is not going "idle". 01838 */ 01839 fTimeOut = !xxxSleepThread(uWakeMask, uTimeout, FALSE); 01840 /* 01841 * If a timeout occurs, and the SMTO_NOTIMEOUTIFNOTHUNG bit is set, 01842 * and the app is still calling GetMessage(), then just try again. 01843 * This probably means that the receiver has put up some UI in 01844 * response to this message but the user hasn't completed the 01845 * interaction yet. 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 * The reply bit should always be set! (even if we timed out). That 01860 * is because if we're recursed into intersendmsg, we're going to 01861 * return to the first intersendmsg's call to SleepThread() - and 01862 * it needs to return back to intersendmsgex to see if its sms 01863 * has been replied to. 01864 */ 01865 SetWakeBit(ptiSender, QS_SMSREPLY); 01866 01867 /* 01868 * Copy out captured data. If cbOutput != 0 we know 01869 * that the output buffer is in user-mode address 01870 * space. 01871 */ 01872 if (!fTimeOut && cbOutput) { 01873 PBYTE pbOutput; 01874 INT len; 01875 01876 /* 01877 * Probe output buffer if it is in the user's address space 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--; //Length includes terminating NULL char 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 { //IsUnicodeString 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 * Return 0 to indicate an error. 01910 */ 01911 psms->lRet = 0; 01912 } 01913 } 01914 01915 /* 01916 * we now have the reply -- restore psmsSent and save the return value 01917 */ 01918 ptiSender->psmsSent = psmsSentSave; 01919 01920 if (pism == NULL) { 01921 lRet = psms->lRet; 01922 } else { 01923 /* 01924 * save the values off for a SendMesssageTimeOut 01925 */ 01926 *pism->lpdwResult = psms->lRet; 01927 lRet = (!fTimeOut) ? TRUE : FALSE; /* do this to ensure ret is T or F... */ 01928 01929 /* 01930 * If we did timeout and no reply was received, rely on 01931 * the receiver to free the sms. 01932 */ 01933 if (!(psms->flags & SMF_REPLY)) 01934 psms->flags |= SMF_REPLY | SMF_RECEIVERFREE; 01935 } 01936 01937 /* 01938 * If the reply came while the receiver is still processing 01939 * the sms, force the receiver to free the sms. This can occur 01940 * via timeout, ReplyMessage or journal cancel. 01941 */ 01942 if ((psms->flags & (SMF_RECEIVERBUSY | SMF_RECEIVEDMESSAGE)) != 01943 SMF_RECEIVEDMESSAGE) { 01944 psms->flags |= SMF_RECEIVERFREE; 01945 } 01946 01947 /* 01948 * Unlink the SMS structure from both the SendMsg chain and gpsmsList * list and free it. This sms could be anywhere in the chain.

VOID xxxProcessAsyncSendMessage PASYNCSENDMSG  pmsg  ) 
 

Definition at line 2891 of file kernel/sendmsg.c.

Referenced by xxxProcessEventMessage().

02900 : 02901 * 05-12-94 JimA Created. 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); pmsg->lParam = 0;

VOID xxxReceiveMessage PTHREADINFO  ptiReceiver  ) 
 

Definition at line 1964 of file kernel/sendmsg.c.

References BOOL, CallClientProcA, CheckCritIn, tagCLIENTTHREADINFO::CTIF_flags, CTIF_INSENDMESSAGE, DirectedScheduleTask(), tagINTERSENDMSGEX::dwData, FALSE, tagCLIENTTHREADINFO::fsChangeBits, tagCLIENTTHREADINFO::fsWakeBits, tagINTERSENDMSGEX::fuCall, HW, tagHOOK::iHook, IsHooked, ISM_CALLBACK, ISM_CB_CLIENT, ISM_REPLY, L, tagHOOKMSGSTRUCT::lParam, tagINTERSENDMSGEX::lpResultCallBack, _CWPRETSTRUCTEX::lResult, tagINTERSENDMSGEX::lRet, tagHOOKMSGSTRUCT::nCode, NULL, tagTHREADINFO::pcti, tagHOOKMSGSTRUCT::phk, PHOOKMSGSTRUCT, PSMS, tagTHREADINFO::psmsCurrent, tagTHREADINFO::psmsReceiveList, _CWPSTRUCTEX::psmsSender, _CWPRETSTRUCTEX::psmsSender, tagTHREADINFO::psmsSent, SET_FLAG, SET_OR_CLEAR_FLAG, SetWakeBit(), SMF_CB_CLIENT, SMF_CB_REPLY, SMF_CB_REQUEST, SMF_RECEIVEDMESSAGE, SMF_RECEIVERBUSY, SMF_RECEIVERDIED, SMF_RECEIVERFREE, SMF_REPLY, SMF_SENDERDIED, TestWF, ThreadLock, ThreadUnlock, TIF_16BIT, tagTHREADINFO::TIF_flags, TRUE, UnlinkSendListSms(), VOID(), WFSERVERSIDEPROC, WHF_CALLWNDPROC, WHF_CALLWNDPROCRET, xxxCallHook(), xxxCallHook2(), xxxInterSendMsgEx(), XXXSENDMESSAGETOCLIENT, and xxxSleepTask().

01971 : 01972 * 01-13-91 DavidPe Ported. 01973 * 01-23-91 DavidPe Add xxxSendNotifyMessage() support. 01974 * 07-14-92 ChrisBl Added xxxSendMessageCallback support. 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 * Get the SMS and unlink it from the list of SMSs we've received 01990 */ 01991 psms = ptiReceiver->psmsReceiveList; 01992 01993 /* 01994 * This can be NULL because an SMS can be removed in our cleanup 01995 * code without clearing the QS_SENDMESSAGE bit. 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 * We've taken the SMS off the receive list - mark the SMS with this 02008 * information - used during cleanup. 02009 */ 02010 psms->flags |= SMF_RECEIVERBUSY | SMF_RECEIVEDMESSAGE; 02011 02012 /* 02013 * Clear QS_SENDMESSAGE wakebit if list is now empty 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 * From SendMessageCallback REPLY to callback. We need to call 02025 * the call back function to give the return value. 02026 * Don't process any this message, just mechanism for notification 02027 * the sender's thread lock is already gone, so we need to re-lock here. 02028 */ 02029 if (ptiSender == NULL) { 02030 ThreadLock(psms->spwnd, &tlpwnd); 02031 } 02032 02033 if (psms->flags & SMF_CB_CLIENT) { 02034 /* 02035 * Application-defined callback proc is neither Unicode nor ANSI 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 * Don't process message if it has been replied to already or 02050 * if the sending or receiving thread has died 02051 */ 02052 02053 /* 02054 * Set new psmsCurrent for this queue, saving the current one 02055 */ 02056 psmsCurrentSave = ptiReceiver->psmsCurrent; 02057 ptiReceiver->psmsCurrent = psms; 02058 SET_FLAG(ptiReceiver->pcti->CTIF_flags, CTIF_INSENDMESSAGE); 02059 02060 /* 02061 * If this SMS originated from a xxxSendNotifyMessage() or a 02062 * xxxSendMessageCallback() call, the sender's thread lock is 02063 * already gone, so we need to re-lock here. 02064 */ 02065 if (ptiSender == NULL) { 02066 ThreadLock(psms->spwnd, &tlpwnd); 02067 } 02068 02069 if (psms->message == WM_HOOKMSG) { 02070 union { 02071 EVENTMSG emsg; // WH_JOURNALRECORD/PLAYBACK 02072 MOUSEHOOKSTRUCTEX mhs; // WH_MOUSE 02073 KBDLLHOOKSTRUCT kbds; // WH_KEYBORD_LL 02074 MSLLHOOKSTRUCT mslls;// WH_MOUSE_LL 02075 #ifdef REDIRECTION 02076 HTHOOKSTRUCT ht; // WH_HITTEST 02077 #endif // REDIRECTION 02078 } LocalData; 02079 PVOID pSendersData; 02080 PHOOKMSGSTRUCT phkmp; 02081 int iHook; 02082 BOOL bAnsiHook; 02083 02084 /* 02085 * Some hook types (eg: WH_JOURNALPLAYBACK) pass pointers to 02086 * data in the calling thread's stack. We must copy this to our 02087 * own (called thread's) stack for safety because of the way this 02088 * "message" is handled and in case the calling thread dies. #13577 02089 * 02090 * Originally only WH_JOURNALRECORD and WH_JOURNALPLAYBACK went 02091 * through this code, but now all sorts of hooks do. 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 * Fall thru... 02130 */ 02131 pSendersData = NULL; 02132 break; 02133 02134 default: 02135 /* 02136 * No pointers: wParam & lParam can be sent as is. 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 * Copy back data only if the sender hasn't died or timed out 02149 * (timed out messages are marked SMF_REPLY by the sending thread) 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 * Call WH_CALLWNDPROC if it's installed and the window is not marked 02181 * as destroyed. 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 * Unlike Win3.1, NT and Win95 ignore any changes the app makes 02196 * to the CWPSTRUCT contents. If this behavior reverts to 02197 * Win3.1 semantics, we will need to copy the new parameters 02198 * from cwps. 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 * If this window's proc is meant to be executed from the server side 02210 * we'll just stay inside the semaphore and call it directly. Note 02211 * how we don't convert the pwnd into an hwnd before calling the proc. 02212 */ 02213 lRet = psms->spwnd->lpfnWndProc(psms->spwnd, psms->message, 02214 psms->wParam, psms->lParam); 02215 02216 ThreadUnlock(&tlpwndKernel); 02217 } else { 02218 /* 02219 * Call the client or xxxDefWindowProc. 02220 */ 02221 XXXSENDMESSAGETOCLIENT(psms->spwnd, psms->message, psms->wParam, psms->lParam, 02222 psms, TRUE); 02223 } 02224 02225 /* 02226 * Call WH_CALLWNDPROCRET if it's installed. 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 * Unlike Win3.1, NT and Win95 ignore any changes the app makes 02241 * to the CWPSTRUCT contents. 02242 */ 02243 xxxCallHook(HC_ACTION, TRUE, (LPARAM)&cwps, WH_CALLWNDPROCRET); 02244 02245 /* 02246 * Unlike Win3.1, NT and Win95 ignore any changes the app makes 02247 * to the CWPSTRUCT contents. If this behavior reverts to 02248 * Win3.1 semantics, we will need to copy the new parameters 02249 * from cwps. 02250 */ 02251 } 02252 } 02253 } 02254 02255 if ((psms->flags & (SMF_CB_REQUEST | SMF_REPLY)) == SMF_CB_REQUEST) { 02256 02257 /* 02258 * From SendMessageCallback REQUEST callback. Send the message 02259 * back with a the REPLY value. 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, 0L, 0L, 02274 NULL, psms->ptiCallBackSender, &ism ); 02275 } 02276 } 02277 02278 if (ptiSender == NULL) { 02279 ThreadUnlock(&tlpwnd); 02280 } 02281 02282 /* 02283 * Restore receiver's original psmsCurrent. 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 * We're done with this sms, so the appropriate thread 02297 * can now free it. 02298 */ 02299 psms->flags &= ~SMF_RECEIVERBUSY; 02300 02301 /* 02302 * Free the sms and return without reply if the 02303 * SMF_RECEIVERFREE bit is set. Handily, this does just what we 02304 * want for xxxSendNotifyMessage() since we set SMF_RECEIVERFREE 02305 * in that case. 02306 */ 02307 if (psms->flags & SMF_RECEIVERFREE) { 02308 UnlinkSendListSms(psms, NULL); 02309 return; 02310 } 02311 02312 /* 02313 * Set reply flag and return value if this message has not already 02314 * been replied to with ReplyMessage(). 02315 */ 02316 if (!(psms->flags & SMF_REPLY)) { 02317 psms->lRet = lRet; 02318 psms->flags |= SMF_REPLY; 02319 02320 /* 02321 * Tell the sender, the reply is done 02322 */ 02323 if (ptiSender != NULL) { 02324 /* 02325 * Wake up the sender thread. 02326 */ 02327 SetWakeBit(ptiSender, QS_SMSREPLY); 02328 02329 /* 02330 * We have 4 conditions to satisfy: 02331 * 02332 * 16 - 16 : yielding required, if sender is waiting for this reply 02333 * 32 - 16 : yielding required, if sender is waiting for this reply 02334 * 16 - 32 : no yielding required 02335 * 32 - 32 : No yielding required. 02336 */

BOOL xxxSendBSMtoDesktop PWND  pwndDesk,
UINT  message,
WPARAM  wParam,
LPARAM  lParam,
LPBROADCASTSYSTEMMSGPARAMS  pbsmParams
 

Definition at line 315 of file kernel/sendmsg.c.

References _PostMessage(), BOOL, BuildHwndList(), BWL_ENUMLIST, CanForceForeground(), CMSWAITTOKILLTIMEOUT, DWORD, fBroadcastProc, FreeHwndList(), GETPDESK, GETPTI, GetTaskName(), glinp, grpdeskRitInput, LPBROADCASTSYSTEMMSGPARAMS, NULL, tagTHREADINFO::ppi, tagTHREADINFO::pq, PtiCurrent, tagLASTINPUT::ptiLastWoken, QueueNotifyMessage(), RevalidateHwnd, tagBWL::rghwnd, tagWND::spwndChild, TestWF, ThreadLockAlwaysWithPti, ThreadUnlock, TIF_CSRSSTHREAD, tagTHREADINFO::TIF_flags, TRUE, UserLogError(), WFWIN40COMPAT, xxxSendMessageTimeout(), and xxxSendNotifyMessage().

Referenced by xxxSendMessageBSM().

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 * Does the caller want to allow the receivers to take the foreground 00343 * while processing the notification? 00344 */ 00345 /* 00346 * Bug 412159. In order to allow the AppsHelp window to come to the 00347 * foreground we set ptiLastWoken to NULL, which will allow any window 00348 * to come to the foreground after a CD's been inserted. 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 * Make sure this hwnd is still around. 00363 */ 00364 if ((pwnd = RevalidateHwnd(*phwnd)) == NULL) 00365 continue; 00366 00367 if (pbsmParams->dwFlags & BSF_IGNORECURRENTTASK) { 00368 // Don't deal with windows in the current task. 00369 if (GETPTI(pwnd)->pq == ptiCurrent->pq) 00370 continue; 00371 } 00372 00373 00374 /* 00375 * Make sure this window can handle broadcast messages 00376 */ 00377 00378 if (!fBroadcastProc(pwnd)) { 00379 continue; 00380 } 00381 00382 if (fPrivateMessage && TestWF(pwnd, WFWIN40COMPAT)) { // Don't broadcast 00383 continue; // private message 00384 } // to 4.0 apps. 00385 00386 ThreadLockAlwaysWithPti(ptiCurrent, pwnd, &tlpwnd); 00387 00388 // Now, send message; This could be a query; so, remember the return value. 00389 if (pbsmParams->dwFlags & BSF_POSTMESSAGE) { 00390 _PostMessage(pwnd, message, wParam, lParam); 00391 } else if (pbsmParams->dwFlags & BSF_SENDNOTIFYMESSAGE) { 00392 /* 00393 * We don't want to wait for an answer, but we don't want to use 00394 * PostMessage either. This is useful if you need to maintain the 00395 * order in which messages are delivered, but you only want to 00396 * wait for some of them. See WM_POWERBROADCAST for an example. 00397 */ 00398 xxxSendNotifyMessage(pwnd, message, wParam, lParam); 00399 } else if (pbsmParams->dwFlags & BSF_QUEUENOTIFYMESSAGE) { 00400 /* 00401 * We don't want to wait for an answer, but we don't want to use 00402 * PostMessage either. This is useful if you need to maintain the 00403 * order in which messages are delivered, but you only want to 00404 * wait for some of them. See WM_POWERBROADCAST for an example. 00405 */ 00406 QueueNotifyMessage(pwnd, message, wParam, lParam); 00407 } else { 00408 /* 00409 * pbsmParams->dwFlags can be changed while we loop here 00410 * so we need to check it in every iteration. 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 // For old messages, returning 0 means a deny 00429 if(message == WM_QUERYENDSESSION) 00430 fReturnValue = (dwResult != 0); 00431 else 00432 // For all new messages, returning BROADCAST_QUERY_DENY is 00433 // the way to deny a query. 00434 fReturnValue = (dwResult != BROADCAST_QUERY_DENY); 00435 } 00436 } else { 00437 fReturnValue = fForce; 00438 } 00439 00440 /* 00441 * If our query was denied, return immediately. 00442 */ 00443 if (fReturnValue == 0) { 00444 if (message == WM_POWERBROADCAST && wParam == PBT_APMQUERYSUSPEND) { 00445 WCHAR wchTask[40]; 00446 ULONG cbTask; 00447 00448 /* 00449 * Get the application name and log an error. 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 }

LRESULT xxxSendMessage PWND  pwnd,
UINT  message,
WPARAM  wParam,
LPARAM  lParam
 

Definition at line 688 of file kernel/sendmsg.c.

References NULL, and xxxSendMessageTimeout().

Referenced by xxxActivateApp(), xxxActivateThisWindow(), xxxActiveWindowTracking(), xxxCalcValidRects(), xxxChangeClipboardChain(), xxxCheckImeShowStatus(), xxxClientShutdown2(), xxxCreateWindowEx(), xxxCsEvent(), xxxDeactivate(), xxxDefWindowProc(), xxxDesktopWndProc(), xxxDestroyWindow(), xxxDoScroll(), xxxDoSend(), xxxDragObject(), xxxDrawClipboard(), xxxDW_SendDestroyMessages(), xxxDWP_NCMouse(), xxxDWP_ProcessVirtKey(), xxxDWP_SetCursor(), xxxDWPPrint(), xxxEnableScrollBar(), xxxEnableWindow(), xxxFlashWindow(), xxxFocusSetInputContext(), xxxFreeWindow(), xxxGetControlColor(), xxxGetMenuBarInfo(), xxxGetRenderData(), xxxHandleMenuMessages(), xxxHandleNCMouseGuys(), xxxHandleWindowPosChanged(), xxxImmActivateLayout(), xxxInitSendValidateMinMaxInfo(), xxxInternalActivateKeyboardLayout(), xxxMakeWindowForegroundWithState(), xxxMenuWindowProc(), xxxMetricsRecalc(), xxxMinMaximize(), xxxMNCancel(), xxxMNChar(), xxxMNCloseHierarchy(), xxxMNDestroyHandler(), xxxMNFindWindowFromPoint(), xxxMNGetBitmapSize(), xxxMNHideNextHierarchy(), xxxMNKeyDown(), xxxMNLoop(), xxxMNMouseMove(), xxxMNOpenHierarchy(), xxxMNSelectItem(), xxxMNStartMenu(), xxxMNStartMenuState(), xxxMNUpdateShownMenu(), xxxMouseActivate(), xxxMoveSize(), xxxMS_TrackMove(), xxxProcessEventMessage(), xxxSBWndProc(), xxxScanSysQueue(), xxxScrollWindowEx(), xxxSendChangedMsgs(), xxxSendClipboardMessage(), xxxSendEraseBkgnd(), xxxSendFocusMessages(), xxxSendHelpMessage(), xxxSendMenuDrawItemMessage(), xxxSendMessageToUI(), xxxSendNCPaint(), xxxSendOpenStatusNotify(), xxxSetForegroundWindow2(), xxxSetScrollBar(), xxxSetWindowStyle(), xxxShowOwnedWindows(), xxxShowWindow(), xxxSwitchDesktop(), xxxSwpActivate(), xxxSysCommand(), xxxTA_AccelerateMenu(), xxxTM_MoveDragRect(), xxxTooltipWndProc(), xxxTrackInitSize(), xxxTrackPopupMenuEx(), xxxTranslateAccelerator(), xxxUpdateWindow2(), xxxUserPowerStateCalloutWorker(), and xxxWindowHitTest2().

00693 { 00694 return xxxSendMessageTimeout( pwnd, message, wParam, lParam, 00695 SMTO_NORMAL, 0, NULL ); 00696 }

LONG xxxSendMessageBSM PWND  pwnd,
UINT  message,
WPARAM  wParam,
LPARAM  lParam,
LPBROADCASTSYSTEMMSGPARAMS  pbsmParams
 

Definition at line 466 of file kernel/sendmsg.c.

References EnterCrit, FALSE, gbRemoteSession, grpWinStaList, IoPnPDeliverServicePowerNotification(), LeaveCrit, NULL, tagDESKTOP::pDeskInfo, PtiCurrent, tagWINDOWSTATION::rpdeskList, tagDESKTOP::rpdeskNext, tagWINDOWSTATION::rpwinstaNext, tagDESKTOPINFO::spwnd, ThreadLockDesktop, ThreadLockExchangeDesktop, ThreadLockExchangeWinSta, ThreadLockWinSta, ThreadUnlockDesktop, ThreadUnlockWinSta, TRUE, and xxxSendBSMtoDesktop().

Referenced by xxxUserPowerEventCalloutWorker(), xxxUserPowerStateCalloutWorker(), and xxxWrapSendMessageBSM().

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 * Walk through all windowstations and desktop looking for 00485 * top-level windows. 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 * If our query was denied, return immediately. 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 * If this is a power broadcast, inform any service that cares. 00514 */ 00515 if (message == WM_POWERBROADCAST && !gbRemoteSession) { 00516 LeaveCrit(); 00517 00518 /* 00519 * If it's a query, deliver it synchronously to pickup the return code 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 }

BOOL xxxSendMessageCallback PWND  pwnd,
UINT  message,
WPARAM  wParam,
LPARAM  lParam,
SENDASYNCPROC  lpResultCallBack,
ULONG_PTR  dwData,
BOOL  fClientRequest
 

Definition at line 1114 of file kernel/sendmsg.c.

References BMSG_SENDMSGCALLBACK, BMSG_SENDNOTIFYMSG, BOOL, CallClientProcA, tagBROADCASTMSG::cb, CheckCritIn, CheckLock, tagINTERSENDMSGEX::dwData, FALSE, tagINTERSENDMSGEX::fuCall, GETPTI, HWq, IsHooked, ISM_CALLBACK, ISM_CB_CLIENT, L, tagWND::lpfnWndProc, tagINTERSENDMSGEX::lpResultCallBack, _CWPRETSTRUCTEX::lResult, NULL, _CWPSTRUCTEX::psmsSender, _CWPRETSTRUCTEX::psmsSender, PtiCurrent, PWND_BROADCAST, TESTSYNCONLYMESSAGE, TestWF, TRUE, UINT, WFSERVERSIDEPROC, WHF_CALLWNDPROC, WHF_CALLWNDPROCRET, xxxBroadcastMessage(), xxxCallHook(), xxxInterSendMsgEx(), and XXXSENDMESSAGETOCLIENT.

Referenced by NtUserSendMessageCallback(), xxxCapture(), xxxFocusSetInputContext(), xxxPaintIconsInSwitchWindow(), and xxxSendNotifyMessage().

01123 : 01124 * 07-13-92 ChrisBl Created/extended from SendNotifyMessage 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 * See if this is a queued notify message. 01142 */ 01143 fQueuedNotify = FALSE; 01144 if (lpResultCallBack == NULL && dwData == 1L) 01145 fQueuedNotify = TRUE; 01146 01147 /* 01148 * First check to see if this message takes DWORDs only. If it does not, 01149 * fail the call. Cannot allow an app to post a message with pointers or 01150 * handles in it - this can cause the server to fault and cause other 01151 * problems - such as causing apps in separate address spaces to fault. 01152 * (or even an app in the same address space to fault!) 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 * Is this a BroadcastMsg()? 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 * Do inter-thread call if window thead differs from current thread. 01187 * We pass NULL for ptiSender to tell xxxInterSendMsgEx() that this is 01188 * a xxxSendNotifyMessage() and that there's no need for a reply. 01189 * 01190 * If this is a queued notify, always call InterSendMsgEx() so that 01191 * we queue it up and return - we don't do callbacks here with queued 01192 * notifies. 01193 */ 01194 if (fQueuedNotify || ptiCurrent != GETPTI(pwnd)) { 01195 INTRSENDMSGEX ism; 01196 PINTRSENDMSGEX pism = NULL; 01197 01198 if (lpResultCallBack != NULL) { /* CallBack request */ 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 * Call WH_CALLWNDPROC if it's installed. 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 * Unlike Win3.1, NT and Win95 ignore any changes the app makes 01222 * to the CWPSTRUCT contents. 01223 */ 01224 xxxCallHook(HC_ACTION, FALSE, (LPARAM)&cwps, WH_CALLWNDPROC); 01225 01226 /* 01227 * Unlike Win3.1, NT and Win95 ignore any changes the app makes 01228 * to the CWPSTRUCT contents. If this behavior reverts to 01229 * Win3.1 semantics, we will need to copy the new parameters 01230 * from cwps. 01231 */ 01232 } 01233 01234 /* 01235 * If this window's proc is meant to be executed from the server side 01236 * we'll just stay inside the semaphore and call it directly. Note 01237 * how we don't convert the pwnd into an hwnd before calling the proc. 01238 */ 01239 if (TestWF(pwnd, WFSERVERSIDEPROC)) { 01240 lRet = pwnd->lpfnWndProc(pwnd, message, wParam, lParam); 01241 } else { 01242 /* 01243 * Call the client or xxxDefWindowProc. pwnd is already locked 01244 */ 01245 XXXSENDMESSAGETOCLIENT(pwnd, message, wParam, lParam, NULL, FALSE); 01246 } 01247 01248 if (lpResultCallBack != NULL) { 01249 /* 01250 * Call the callback funtion for the return value 01251 */ 01252 if (fClientRequest) { 01253 /* 01254 * The application-defined callback proc is neither Unicode/ANSI 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 * Call WH_CALLWNDPROCRET if it's installed. 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 * Unlike Win3.1, NT and Win95 ignore any changes the app makes 01278 * to the CWPSTRUCT contents. */

LRESULT xxxSendMessageEx PWND  pwnd,
UINT  message,
WPARAM  wParam,
LPARAM  lParam,
ULONG_PTR  xParam
 

Definition at line 609 of file kernel/sendmsg.c.

References FALSE, tagSNDMSGTIMEOUT::fuFlags, L, tagSNDMSGTIMEOUT::lSMTOResult, tagSNDMSGTIMEOUT::lSMTOReturn, NT_SUCCESS, NTSTATUS(), NULL, ProbeForWrite(), PsGetCurrentThread, SNDMSGTIMEOUT, Status, tagSNDMSGTIMEOUT::uTimeout, and xxxSendMessageTimeout().

Referenced by InitFunctionTables(), and xxxSendMessageFF().

00615 { 00616 /* 00617 * extract values from the xParam if from TimeOut call 00618 * This should be the only way this function is ever 00619 * called, but check it just in case... 00620 */ 00621 if (xParam != 0L) { 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 * Probe all read arguments 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 * put the result back into the client 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 * Return the lResult so our thunks are happy. 00662 */ 00663 return lResult; 00664 } 00665 00666 return xxxSendMessageTimeout(pwnd, message, wParam, 00667 lParam, SMTO_NORMAL, 0, NULL ); 00668 }

LRESULT xxxSendMessageFF PWND  pwnd,
UINT  message,
WPARAM  wParam,
LPARAM  lParam,
ULONG_PTR  xParam
 

Definition at line 556 of file kernel/sendmsg.c.

References L, NULL, PWND_BROADCAST, xxxSendMessageEx(), and xxxSendMessageTimeout().

Referenced by InitFunctionTables().

00562 { 00563 DBG_UNREFERENCED_PARAMETER(pwnd); 00564 00565 /* 00566 * Call xxxSendMessage() to do broadcasting rather than calling 00567 * broadcast from here in case any internal code that calls 00568 * sendmessage passes a -1 (that way the internal code doesn't 00569 * need to know about this weird routine). 00570 */ 00571 if (xParam != 0L) { 00572 /* 00573 * SendMessageTimeout call 00574 */ 00575 return xxxSendMessageEx(PWND_BROADCAST, message, wParam, lParam, xParam); 00576 } else { 00577 /* 00578 * Normal SendMessage call 00579 */ 00580 return xxxSendMessageTimeout(PWND_BROADCAST, message, wParam, 00581 lParam, SMTO_NORMAL, 0, NULL ); 00582 } 00583 }

LRESULT xxxSendMessageTimeout PWND  pwnd,
UINT  message,
WPARAM  wParam,
LPARAM  lParam,
UINT  fuFlags,
UINT  uTimeout,
PLONG_PTR  lpdwResult
 

Definition at line 764 of file kernel/sendmsg.c.

References BMSG_SENDMSG, BMSG_SENDMSGTIMEOUT, BROADCASTMSG, CheckCritIn, CheckLock, CMSWAITTOKILLTIMEOUT, CWPRETSTRUCTEX, CWPSTRUCTEX, FALSE, FHungApp(), tagINTERSENDMSGEX::fuCall, tagINTERSENDMSGEX::fuSend, GETPTI, guDdeSendTimeout, HMIsMarkDestroy, HWq, IsHooked, ISM_TIMEOUT, KeGetCurrentThread, KERNEL_STACK_MINIMUM_RESERVE, L, tagINTERSENDMSGEX::lpdwResult, tagWND::lpfnWndProc, _CWPRETSTRUCTEX::lResult, NULL, PBROADCASTMSG, PINTRSENDMSGEX, _CWPSTRUCTEX::psmsSender, _CWPRETSTRUCTEX::psmsSender, PtiCurrent, PWND_BROADCAST, TestWF, tagBROADCASTMSG::to, TRUE, UINT, tagINTERSENDMSGEX::uTimeout, WFSERVERSIDEPROC, WHF_CALLWNDPROC, WHF_CALLWNDPROCRET, xxxBroadcastMessage(), xxxCallHook(), xxxDDETrackSendHook(), xxxDefWindowProc(), xxxInterSendMsgEx(), and XXXSENDMESSAGETOCLIENT.

Referenced by DrawSwitchWndHilite(), xxxGetWindowSmIcon(), xxxImmUnloadLayout(), xxxNextWindow(), xxxQueryDropObject(), xxxSendBSMtoDesktop(), xxxSendClipboardMessage(), xxxSendMessage(), xxxSendMessageEx(), xxxSendMessageFF(), xxxSendMinRectMessages(), xxxSystemParametersInfo(), and xxxWrapSendMessage().

00770 : 00771 * the value returned by the window procedure, or NULL if there is an error 00772 * 00773 * History: 00774 * 07-13-92 ChrisBl Created/extended from SendMessage 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; // holder for DDE_INITIATE case 00789 00790 CheckCritIn(); 00791 00792 if (lpdwResult != NULL) 00793 *lpdwResult = 0L; 00794 00795 /* 00796 * Is this a BroadcastMsg()? 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 * Even though apps should only send WM_DDE_INITIATE or WM_DDE_ACK 00819 * messages, we hook them all so DDESPY can monitor them. 00820 */ 00821 if (!xxxDDETrackSendHook(pwnd, message, wParam, lParam)) { 00822 return 0; 00823 } 00824 if (message == WM_DDE_INITIATE && guDdeSendTimeout) { 00825 /* 00826 * This hack prevents DDE apps from locking up because some 00827 * bozo in the system has a top level window and is not 00828 * processing messages. guDdeSendTimeout is registry set. 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 * Do inter-thread call if window queue differs from current queue 00842 */ 00843 if (ptiCurrent != GETPTI(pwnd)) { 00844 INTRSENDMSGEX ism; 00845 PINTRSENDMSGEX pism = NULL; 00846 00847 /* 00848 * If this window is a zombie, don't allow inter-thread send messages 00849 * to it. 00850 */ 00851 if (HMIsMarkDestroy(pwnd)) 00852 return xxxDefWindowProc(pwnd, message, wParam, lParam); 00853 00854 if ( lpdwResult != NULL ) { 00855 /* 00856 * fail if we think the thread is hung 00857 */ 00858 if ((fuFlags & SMTO_ABORTIFHUNG) && FHungApp(GETPTI(pwnd), CMSWAITTOKILLTIMEOUT)) 00859 return 0; 00860 00861 /* 00862 * Setup for a InterSend time-out call 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 * Call WH_CALLWNDPROC if it's installed and the window is not marked 00879 * as destroyed. 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 * Unlike Win3.1, NT and Win95 ignore any changes the app makes 00892 * to the CWPSTRUCT contents. 00893 */ 00894 xxxCallHook(HC_ACTION, FALSE, (LPARAM)&cwps, WH_CALLWNDPROC); 00895 00896 /* 00897 * Unlike Win3.1, NT and Win95 ignore any changes the app makes 00898 * to the CWPSTRUCT contents. If this behavior reverts to 00899 * Win3.1 semantics, we will need to copy the new parameters 00900 * from cwps. 00901 */ 00902 } 00903 00904 /* 00905 * If this window's proc is meant to be executed from the server side 00906 * we'll just stay inside the semaphore and call it directly. Note 00907 * how we don't convert the pwnd into an hwnd before calling the proc. 00908 */ 00909 if (TestWF(pwnd, WFSERVERSIDEPROC)) { 00910 00911 /* 00912 * We have a number of places where we do recursion in User. This often goes 00913 * through SendMessage (when we send a message to the parent for example) which 00914 * can eat the amount of stack we have 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 { /* time-out call */ 00926 *lpdwResult = lRet; 00927 return TRUE; 00928 } 00929 } 00930 00931 /* 00932 * Call the client or xxxDefWindowProc. pwnd is already locked. 00933 */ 00934 XXXSENDMESSAGETOCLIENT(pwnd, message, wParam, lParam, NULL, FALSE); 00935 00936 /* 00937 * Call WH_CALLWNDPROCRET if it's installed. 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 * Unlike Win3.1, NT and Win95 ignore any changes the app makes 00951 * to the CWPSTRUCT contents. 00952 */ 00953 xxxCallHook(HC_ACTION, FALSE, (LPARAM)&cwps, WH_CALLWNDPROCRET); 00954 00955 /* 00956 * Unlike Win3.1, NT and Win95 ignore any changes the app makes * to the CWPSTRUCT contents. If this behavior reverts to

BOOL xxxSendNotifyMessage PWND  pwnd,
UINT  message,
WPARAM  wParam,
LPARAM  lParam
 

Definition at line 1069 of file kernel/sendmsg.c.

References BMSG_SENDNOTIFYMSG, BOOL, L, NULL, PWND_BROADCAST, xxxSendMessageCallback(), and xxxSystemBroadcastMessage().

Referenced by FullScreenCleanup(), NtUserSendNotifyMessage(), xxxActivateThisWindow(), xxxBroadcastPaletteChanged(), xxxDesktopWndProc(), xxxDrawClipboard(), xxxMNLoop(), xxxNextWindow(), xxxOldNextWindow(), xxxSendBSMtoDesktop(), xxxSendClipboardMessage(), xxxSendMenuSelect(), xxxSetDeskPattern(), xxxSetDeskWallpaper(), and xxxSetSysColors().

01077 : 01078 * 01-23-91 DavidPe Created. 01079 * 07-14-92 ChrisBl Will return T/F if in same thread, as documented 01080 \***********************************************************************/ 01081 01082 BOOL xxxSendNotifyMessage( 01083 PWND pwnd, 01084 UINT message, 01085 WPARAM wParam, 01086 LPARAM lParam) 01087 { 01088 /* 01089 * If this is a broadcast of one of the system 01090 * notification messages, send it to all top-level 01091 * windows in the system. 01092 */ 01093 if (pwnd == PWND_BROADCAST) { 01094 switch (message) { 01095 case WM_WININICHANGE: 01096 case WM_DEVMODECHANGE: case WM_SPOOLERSTATUS:

void xxxSendSizeMessage PWND  pwnd,
UINT  cmdSize
 

Definition at line 2861 of file kernel/sendmsg.c.

Referenced by xxxCreateWindowEx(), xxxHandleWindowPosChanged(), and xxxShowWindow().

02870 : 02871 * 10-19-90 darrinm Ported from Win 3.0 sources. 02872 \***************************************************************************/ 02873 02874 void xxxSendSizeMessage( 02875 PWND pwnd, 02876 UINT cmdSize) 02877 { 02878 RECT rc; CheckLock(pwnd);

VOID xxxSystemBroadcastMessage UINT  message,
WPARAM  wParam,
LPARAM  lParam,
UINT  wCmd,
PBROADCASTMSG  pbcm
 

Definition at line 1002 of file kernel/sendmsg.c.

References BMSG_SENDMSG, BMSG_SENDNOTIFYMSG, grpWinStaList, NULL, tagDESKTOP::pDeskInfo, PtiCurrent, tagTHREADINFO::rpdesk, tagWINDOWSTATION::rpdeskList, tagDESKTOP::rpdeskNext, tagWINDOWSTATION::rpwinstaNext, tagDESKTOP::rpwinstaParent, tagDESKTOPINFO::spwnd, ThreadLockDesktop, ThreadLockExchangeDesktop, ThreadLockExchangeWinSta, ThreadLockWinSta, ThreadUnlockDesktop, ThreadUnlockWinSta, UINT, VOID(), and xxxBroadcastMessage().

Referenced by xxxSendNotifyMessage().

01011 : 01012 * 05-12-94 JimA Created. 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 * Walk through all windowstations and desktop looking for 01030 * top-level windows. 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 * Bug 276814. Don't recurse calling again xxxBroadcastMessage if there 01049 * is no window on this desktop. */


Variable Documentation

PPAGED_LOOKASIDE_LIST SMSLookaside
 

Definition at line 34 of file kernel/sendmsg.c.

Referenced by AllocSMS(), FreeSMS(), InitSMSLookaside(), and Win32kNtUserCleanup().


Generated on Sat May 15 19:45:35 2004 for test by doxygen 1.3.7