test: event.c Source File

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

# event.c

Go to the documentation of this file.

    00001 /****************************** Module Header ******************************\
    00002 * Module Name: event.c
    00003 *
    00004 * Copyright (c) 1985 - 1999, Microsoft Corporation
    00005 *
    00006 * DDE Manager event module - this is a fancy way of allowing interprocess
    00007 *   communication across security contexts.  This is needed because the
    00008 *   DDE Access Object security may be different than hwnd security so
    00009 *   straight messages arn't good enough.
    00010 *
    00011 * Created: 8/27/91 Sanford Staab
    00012 *
    00013 \***************************************************************************/
    00014
    00015 #include "precomp.h"
    00016 #pragma hdrstop
    00017
    00018
    00019 DWORD MonitorFlags = 0;     // current filter flags being monitored by someone.
    00020
    00021 typedef struct tagMONITOR_COUNT {
    00022     int iCount;
    00023     DWORD flag;
    00024 } MONITOR_COUNT, *PMONITOR_COUNT;
    00025
    00026 #define C_MONITOR_COUNT 10
    00027
    00028 MONITOR_COUNT aMonitorCount[C_MONITOR_COUNT] = {
    00029     { 0, MF_HSZ_INFO },
    00030     { 0, MF_SENDMSGS },
    00031     { 0, MF_POSTMSGS },
    00032     { 0, MF_CALLBACKS },
    00033     { 0, MF_ERRORS },
    00034     { 0, MF_LINKS },
    00035     { 0, MF_CONV },
    00036     { 0, CBF_SKIP_REGISTRATIONS },
    00037     { 0, CBF_SKIP_UNREGISTRATIONS },
    00038     { 0, MF_INTERNAL },
    00039 };
    00040
    00041 #define MONITORED_FLAGS \
    00042     MF_HSZ_INFO |   \
    00043     MF_SENDMSGS |   \
    00044     MF_POSTMSGS |   \
    00045     MF_CALLBACKS |   \
    00046     MF_ERRORS |   \
    00047     MF_LINKS |   \
    00048     MF_CONV |   \
    00049     CBF_SKIP_REGISTRATIONS |   \
    00050     CBF_SKIP_UNREGISTRATIONS |   \
    00051     MF_INTERNAL
    00052
    00053
    00054 /***************************************************************************\
    00055 * ChangeMonitorFlags
    00056 *
    00057 * Description:
    00058 *   Updates the global MonitorFlags variable to reflect the union of all
    00059 *   event types being monitored by DDEML applications.
    00060 *
    00061 * History:
    00062 * 11-26-91   sanfords    Created.
    00063 \***************************************************************************/
    00064 VOID xxxChangeMonitorFlags(
    00065 PSVR_INSTANCE_INFO psii,
    00066 DWORD afCmdNew)
    00067 {
    00068     int i;
    00069     DWORD dwChangedFlags;
    00070     DWORD OldMonitorFlags;
    00071
    00072     CheckCritIn();
    00073
    00074     dwChangedFlags = psii->afCmd ^ afCmdNew;
    00075     if (!(dwChangedFlags & MONITORED_FLAGS)) {
    00076         return;
    00077     }
    00078     psii->afCmd = afCmdNew;
    00079
    00080     OldMonitorFlags = MonitorFlags;
    00081     MonitorFlags = 0;
    00082     for (i = 0; i < C_MONITOR_COUNT; i++) {
    00083         if (dwChangedFlags & aMonitorCount[i].flag) {
    00084             if (aMonitorCount[i].flag & afCmdNew) {
    00085                 aMonitorCount[i].iCount++;
    00086             } else {
    00087                 aMonitorCount[i].iCount--;
    00088             }
    00089         }
    00090         if (aMonitorCount[i].iCount) {
    00091             MonitorFlags |= aMonitorCount[i].flag;
    00092         }
    00093     }
    00094     if (OldMonitorFlags != MonitorFlags) {
    00095         EVENT_PACKET ep;
    00096
    00097         ep.EventType = 0;
    00098         ep.fSense = FALSE;
    00099         ep.cbEventData = sizeof(DWORD);
    00100         ep.Data = MonitorFlags;
    00101         xxxCsEvent(&ep, sizeof(DWORD));
    00102     }
    00103 }
    00104
    00105
    00106
    00107 /***************************************************************************\
    00108 * xxxCsEvent
    00109 *
    00110 * Description:
    00111 *   Handles broadcasting of all types of DDEML events.
    00112 *
    00113 * History:
    00114 * 11-1-91   sanfords    Created.
    00115 * 10-28-97  FritzS    added cbEventData as a passed-in parameter.  This was
    00116                       done because the EVENT_PACKET may be client-side and
    00117                       we capture the count to keep a hostile app from changing
    00118                       the size after data probing.
    00119 \***************************************************************************/
    00120 DWORD xxxCsEvent(
    00121 PEVENT_PACKET pep, WORD cbEventData)
    00122 {
    00123     PSVR_INSTANCE_INFO psiiT;
    00124     PEVENT_PACKET pep2;
    00125     HWND *ahwndEvent = NULL;
    00126     PWND pwnd;
    00127     int cHwndAllocated, i, cTargets;
    00128     TL tlpwnd;
    00129     TL tlpep2;
    00130     TL tlahwndEvent;
    00131     ULONG cbEventPacket;
    00132     PTHREADINFO pti = PtiCurrent();
    00133
    00134     CheckCritIn();
    00135
    00136     /*
    00137      * Copy pep info to a server side stable area
    00138      */
    00139     cbEventPacket = cbEventData + sizeof(EVENT_PACKET) - sizeof(DWORD);
    00140     pep2 = (PEVENT_PACKET)UserAllocPoolWithQuota(cbEventPacket, TAG_DDE5);
    00141     if (pep2 == NULL) {
    00142         return DMLERR_MEMORY_ERROR;
    00143     }
    00144     try {
    00145         RtlCopyMemory((LPSTR)pep2, (LPSTR)pep, cbEventPacket);
    00146     } except (W32ExceptionHandler(FALSE, RIP_WARNING)) {
    00147         UserFreePool(pep2);
    00148         return DMLERR_INVALIDPARAMETER;
    00149     }
    00150
    00151     pep2->cbEventData = cbEventData;
    00152     cTargets = 0;
    00153     cHwndAllocated = 0;
    00154
    00155     for (psiiT = psiiList; psiiT != NULL; psiiT =  psiiT->next) {
    00156         //
    00157         // Don't bother with event windows for instances who's flags
    00158         // indicate they're not interrested in the event.
    00159         //
    00160         if (((psiiT->afCmd & pep2->EventType) && !pep2->fSense) ||
    00161                 (!(psiiT->afCmd & pep2->EventType) && pep2->fSense)) {
    00162             continue;
    00163         }
    00164
    00165         if (cTargets >= cHwndAllocated) {
    00166             if (ahwndEvent == NULL) {
    00167                 cHwndAllocated = 8;
    00168                 ahwndEvent = (HWND *)UserAllocPoolWithQuota(
    00169                         sizeof(HWND) * cHwndAllocated,
    00170                         TAG_DDE6);
    00171             } else {
    00172                 DWORD dwSize = cHwndAllocated * sizeof(HWND);
    00173                 HWND *ahwndEventT = ahwndEvent;
    00174
    00175                 cHwndAllocated += 8;
    00176                 ahwndEvent = (HWND *)UserReAllocPoolWithQuota(ahwndEvent, dwSize,
    00177                         sizeof(HWND) * cHwndAllocated, TAG_DDE7);
    00178                 if (ahwndEvent == NULL) {
    00179                     UserFreePool(ahwndEventT);
    00180                 }
    00181             }
    00182             if (ahwndEvent == NULL) {
    00183                 UserFreePool(pep2);
    00184                 return DMLERR_MEMORY_ERROR;
    00185             }
    00186         }
    00187         ahwndEvent[cTargets++] = PtoH(psiiT->spwndEvent);
    00188     }
    00189
    00190     ThreadLockPool(pti, pep2, &tlpep2);
    00191     if (ahwndEvent != NULL) {
    00192         ThreadLockPool(pti, ahwndEvent, &tlahwndEvent);
    00193         for (i = 0; i < cTargets; i++) {
    00194             /*
    00195              * We need to change contexts for the callback
    00196              */
    00197             pwnd = ValidateHwnd(ahwndEvent[i]);
    00198             if (pwnd != NULL) {
    00199                 ThreadLockAlwaysWithPti(pti, pwnd, &tlpwnd);
    00200                 xxxSendMessage(pwnd, WM_DDEMLEVENT, 0, (LPARAM)pep2);
    00201                 ThreadUnlock(&tlpwnd);
    00202             }
    00203         }
    00204         ThreadUnlockAndFreePool(pti, &tlahwndEvent);
    00205     }
    00206     ThreadUnlockAndFreePool(pti, &tlpep2);
    00207
    00208     return DMLERR_NO_ERROR;
    00209 }
    00210
    00211
    00212
    00213
    00214 /***************************************************************************\
    00215 * xxxEventWndProc
    00216 *
    00217 * Description:
    00218 *   Window proc for DDEML event windows.  These windows serve to get user
    00219 *   into the proper context for callbacks to DDEML applications.
    00220 *
    00221 * History:
    00222 * 11-1-91   sanfords    Created.
    00223 \***************************************************************************/
    00224 LRESULT xxxEventWndProc(
    00225 PWND pwnd,
    00226 UINT message,
    00227 WPARAM wParam,
    00228 LPARAM lParam)
    00229 {
    00230     PSVR_INSTANCE_INFO psii;
    00231
    00232     CheckCritIn();
    00233     CheckLock(pwnd);
    00234
    00235     psii = HMValidateHandleNoRip((HANDLE)_GetWindowLongPtr(pwnd, GWLP_PSII),
    00236                                  TYPE_DDEACCESS);
    00237     if (psii == NULL) {
    00238         goto CallDWP;
    00239     }
    00240
    00241     switch (message) {
    00242     case WM_DDEMLEVENT:
    00243 #define pep ((PEVENT_PACKET)lParam)
    00244         if (((psii->afCmd & pep->EventType) && pep->fSense) ||
    00245                 (!(psii->afCmd & pep->EventType) && !pep->fSense)) {
    00246             ClientEventCallback(psii->pcii, pep);
    00247         }
    00248 #undef pep
    00249         break;
    00250
    00251     case WM_DESTROY:
    00252         xxxChangeMonitorFlags(psii, 0);
    00253         break;
    00254
    00255     default:
    00256 CallDWP:
    00257         return xxxDefWindowProc(pwnd, message, wParam, lParam);
    00258     }
    00259     return 0;
    00260 }
    00261
    00262
    00263
    00264 /***************************************************************************\
    00265 * xxxMessageEvent
    00266 *
    00267 * Description:  Called when a hooked DDE message is sent or posted.  flags
    00268 *   specifies the applicable MF_ flag.  This is called in the server side
    00269 *   context of the sender or poster which may or may not be a DDEML process.
    00270 *   pdmhd contains DDE data extracted and copied from the client side.
    00271 *
    00272 * History:
    00273 * 12-1-91   sanfords    Created.
    00274 \***************************************************************************/
    00275 VOID xxxMessageEvent(
    00276 PWND pwndTo,
    00277 UINT message,
    00278 WPARAM wParam,
    00279 LPARAM lParam,
    00280 DWORD flag,
    00281 PDDEML_MSG_HOOK_DATA pdmhd)
    00282 {
    00283     PEVENT_PACKET pep;
    00284     PWND pwndFrom;
    00285     TL tlpep;
    00286     PTHREADINFO pti;
    00287
    00288     CheckCritIn();
    00289
    00290     pep = (PEVENT_PACKET)UserAllocPoolWithQuota(sizeof(EVENT_PACKET) -
    00291             sizeof(DWORD) + sizeof(MONMSGSTRUCT), TAG_DDE8);
    00292     if (pep == NULL) {
    00293         return;
    00294     }
    00295     pep->EventType = flag;
    00296     pep->fSense = TRUE;
    00297     pep->cbEventData = sizeof(MONMSGSTRUCT);
    00298 #define pmsgs ((MONMSGSTRUCT *)&pep->Data)
    00299     pmsgs->cb = sizeof(MONMSGSTRUCT);
    00300     pmsgs->hwndTo = PtoH(pwndTo);
    00301     pmsgs->dwTime = NtGetTickCount();
    00302
    00303     pwndFrom = RevalidateHwnd((HWND)wParam);
    00304     if (pwndFrom != NULL) {
    00305         pmsgs->hTask = GETPTI(pwndFrom)->pEThread->Cid.UniqueThread;
    00306     } else {
    00307         pmsgs->hTask = 0;
    00308     }
    00309
    00310     pmsgs->wMsg = message;
    00311     pmsgs->wParam = wParam;
    00312     pmsgs->lParam = lParam;
    00313     if (pdmhd != NULL) {
    00314         pmsgs->dmhd = *pdmhd;
    00315     }
    00316 #undef pmsgs
    00317     pti = PtiCurrent();
    00318     ThreadLockPool(pti, pep, &tlpep);
    00319     xxxCsEvent(pep, sizeof(MONMSGSTRUCT));
    00320     ThreadUnlockAndFreePool(pti, &tlpep);
    00321 }