Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

327 lines
9.3 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: event.c
  3. *
  4. * Copyright (c) 1985 - 1999, Microsoft Corporation
  5. *
  6. * DDE Manager event module - this is a fancy way of allowing interprocess
  7. * communication across security contexts. This is needed because the
  8. * DDE Access Object security may be different than hwnd security so
  9. * straight messages arn't good enough.
  10. *
  11. * Created: 8/27/91 Sanford Staab
  12. *
  13. \***************************************************************************/
  14. #include "precomp.h"
  15. #pragma hdrstop
  16. DWORD MonitorFlags = 0; // current filter flags being monitored by someone.
  17. typedef struct tagMONITOR_COUNT {
  18. int iCount;
  19. DWORD flag;
  20. } MONITOR_COUNT, *PMONITOR_COUNT;
  21. #define C_MONITOR_COUNT 10
  22. MONITOR_COUNT aMonitorCount[C_MONITOR_COUNT] = {
  23. { 0, MF_HSZ_INFO },
  24. { 0, MF_SENDMSGS },
  25. { 0, MF_POSTMSGS },
  26. { 0, MF_CALLBACKS },
  27. { 0, MF_ERRORS },
  28. { 0, MF_LINKS },
  29. { 0, MF_CONV },
  30. { 0, CBF_SKIP_REGISTRATIONS },
  31. { 0, CBF_SKIP_UNREGISTRATIONS },
  32. { 0, MF_INTERNAL },
  33. };
  34. #define MONITORED_FLAGS \
  35. MF_HSZ_INFO | \
  36. MF_SENDMSGS | \
  37. MF_POSTMSGS | \
  38. MF_CALLBACKS | \
  39. MF_ERRORS | \
  40. MF_LINKS | \
  41. MF_CONV | \
  42. CBF_SKIP_REGISTRATIONS | \
  43. CBF_SKIP_UNREGISTRATIONS | \
  44. MF_INTERNAL
  45. /***************************************************************************\
  46. * ChangeMonitorFlags
  47. *
  48. * Description:
  49. * Updates the global MonitorFlags variable to reflect the union of all
  50. * event types being monitored by DDEML applications.
  51. *
  52. * History:
  53. * 11-26-91 sanfords Created.
  54. \***************************************************************************/
  55. VOID xxxChangeMonitorFlags(
  56. PSVR_INSTANCE_INFO psii,
  57. DWORD afCmdNew)
  58. {
  59. int i;
  60. DWORD dwChangedFlags;
  61. DWORD OldMonitorFlags;
  62. CheckCritIn();
  63. dwChangedFlags = psii->afCmd ^ afCmdNew;
  64. /*
  65. * Due to the way MONITORED_FLAGS was defined, this if stmt is always
  66. * false. Since it's been this way since day 1, it's now a feature.
  67. * Bug #105937.
  68. *
  69. * if (!(dwChangedFlags & MONITORED_FLAGS)) {
  70. * return;
  71. * }
  72. */
  73. psii->afCmd = afCmdNew;
  74. OldMonitorFlags = MonitorFlags;
  75. MonitorFlags = 0;
  76. for (i = 0; i < C_MONITOR_COUNT; i++) {
  77. if (dwChangedFlags & aMonitorCount[i].flag) {
  78. if (aMonitorCount[i].flag & afCmdNew) {
  79. aMonitorCount[i].iCount++;
  80. } else {
  81. aMonitorCount[i].iCount--;
  82. }
  83. }
  84. if (aMonitorCount[i].iCount) {
  85. MonitorFlags |= aMonitorCount[i].flag;
  86. }
  87. }
  88. if (OldMonitorFlags != MonitorFlags) {
  89. EVENT_PACKET ep;
  90. ep.EventType = 0;
  91. ep.fSense = FALSE;
  92. ep.cbEventData = sizeof(DWORD);
  93. ep.Data = MonitorFlags;
  94. xxxCsEvent(&ep, sizeof(DWORD));
  95. }
  96. }
  97. /***************************************************************************\
  98. * xxxCsEvent
  99. *
  100. * Description:
  101. * Handles broadcasting of all types of DDEML events.
  102. *
  103. * History:
  104. * 11-1-91 sanfords Created.
  105. * 10-28-97 FritzS added cbEventData as a passed-in parameter. This was
  106. done because the EVENT_PACKET may be client-side and
  107. we capture the count to keep a hostile app from changing
  108. the size after data probing.
  109. \***************************************************************************/
  110. DWORD xxxCsEvent(
  111. PEVENT_PACKET pep, WORD cbEventData)
  112. {
  113. PSVR_INSTANCE_INFO psiiT;
  114. PEVENT_PACKET pep2;
  115. HWND *ahwndEvent = NULL;
  116. PWND pwnd;
  117. int cHwndAllocated, i, cTargets;
  118. TL tlpwnd;
  119. TL tlpep2;
  120. TL tlahwndEvent;
  121. ULONG cbEventPacket;
  122. PTHREADINFO pti = PtiCurrent();
  123. CheckCritIn();
  124. /*
  125. * Copy pep info to a server side stable area
  126. */
  127. cbEventPacket = cbEventData + sizeof(EVENT_PACKET) - sizeof(DWORD);
  128. pep2 = (PEVENT_PACKET)UserAllocPoolWithQuota(cbEventPacket, TAG_DDE5);
  129. if (pep2 == NULL) {
  130. return DMLERR_MEMORY_ERROR;
  131. }
  132. try {
  133. RtlCopyMemory((LPSTR)pep2, (LPSTR)pep, cbEventPacket);
  134. } except (W32ExceptionHandler(FALSE, RIP_WARNING)) {
  135. UserFreePool(pep2);
  136. return DMLERR_INVALIDPARAMETER;
  137. }
  138. pep2->cbEventData = cbEventData;
  139. cTargets = 0;
  140. cHwndAllocated = 0;
  141. for (psiiT = psiiList; psiiT != NULL; psiiT = psiiT->next) {
  142. //
  143. // Don't bother with event windows for instances who's flags
  144. // indicate they're not interrested in the event.
  145. //
  146. if (((psiiT->afCmd & pep2->EventType) && !pep2->fSense) ||
  147. (!(psiiT->afCmd & pep2->EventType) && pep2->fSense)) {
  148. continue;
  149. }
  150. if (cTargets >= cHwndAllocated) {
  151. if (ahwndEvent == NULL) {
  152. cHwndAllocated = 8;
  153. ahwndEvent = (HWND *)UserAllocPoolWithQuota(
  154. sizeof(HWND) * cHwndAllocated,
  155. TAG_DDE6);
  156. } else {
  157. DWORD dwSize = cHwndAllocated * sizeof(HWND);
  158. HWND *ahwndEventT = ahwndEvent;
  159. cHwndAllocated += 8;
  160. ahwndEvent = (HWND *)UserReAllocPoolWithQuota(ahwndEvent, dwSize,
  161. sizeof(HWND) * cHwndAllocated, TAG_DDE7);
  162. if (ahwndEvent == NULL) {
  163. UserFreePool(ahwndEventT);
  164. }
  165. }
  166. if (ahwndEvent == NULL) {
  167. UserFreePool(pep2);
  168. return DMLERR_MEMORY_ERROR;
  169. }
  170. }
  171. ahwndEvent[cTargets++] = PtoH(psiiT->spwndEvent);
  172. }
  173. ThreadLockPool(pti, pep2, &tlpep2);
  174. if (ahwndEvent != NULL) {
  175. ThreadLockPool(pti, ahwndEvent, &tlahwndEvent);
  176. for (i = 0; i < cTargets; i++) {
  177. /*
  178. * We need to change contexts for the callback
  179. */
  180. pwnd = ValidateHwnd(ahwndEvent[i]);
  181. if (pwnd != NULL) {
  182. ThreadLockAlwaysWithPti(pti, pwnd, &tlpwnd);
  183. xxxSendMessage(pwnd, WM_DDEMLEVENT, 0, (LPARAM)pep2);
  184. ThreadUnlock(&tlpwnd);
  185. }
  186. }
  187. ThreadUnlockAndFreePool(pti, &tlahwndEvent);
  188. }
  189. ThreadUnlockAndFreePool(pti, &tlpep2);
  190. return DMLERR_NO_ERROR;
  191. }
  192. /***************************************************************************\
  193. * xxxEventWndProc
  194. *
  195. * Description:
  196. * Window proc for DDEML event windows. These windows serve to get user
  197. * into the proper context for callbacks to DDEML applications.
  198. *
  199. * History:
  200. * 11-1-91 sanfords Created.
  201. \***************************************************************************/
  202. LRESULT xxxEventWndProc(
  203. PWND pwnd,
  204. UINT message,
  205. WPARAM wParam,
  206. LPARAM lParam)
  207. {
  208. PSVR_INSTANCE_INFO psii;
  209. CheckCritIn();
  210. CheckLock(pwnd);
  211. psii = HMValidateHandleNoRip((HANDLE)_GetWindowLongPtr(pwnd, GWLP_PSII),
  212. TYPE_DDEACCESS);
  213. if (psii == NULL) {
  214. goto CallDWP;
  215. }
  216. switch (message) {
  217. case WM_DDEMLEVENT:
  218. #define pep ((PEVENT_PACKET)lParam)
  219. if (((psii->afCmd & pep->EventType) && pep->fSense) ||
  220. (!(psii->afCmd & pep->EventType) && !pep->fSense)) {
  221. ClientEventCallback(psii->pcii, pep);
  222. }
  223. #undef pep
  224. break;
  225. case WM_DESTROY:
  226. xxxChangeMonitorFlags(psii, 0);
  227. break;
  228. default:
  229. CallDWP:
  230. return xxxDefWindowProc(pwnd, message, wParam, lParam);
  231. }
  232. return 0;
  233. }
  234. /***************************************************************************\
  235. * xxxMessageEvent
  236. *
  237. * Description: Called when a hooked DDE message is sent or posted. flags
  238. * specifies the applicable MF_ flag. This is called in the server side
  239. * context of the sender or poster which may or may not be a DDEML process.
  240. * pdmhd contains DDE data extracted and copied from the client side.
  241. *
  242. * History:
  243. * 12-1-91 sanfords Created.
  244. \***************************************************************************/
  245. VOID xxxMessageEvent(
  246. PWND pwndTo,
  247. UINT message,
  248. WPARAM wParam,
  249. LPARAM lParam,
  250. DWORD flag,
  251. PDDEML_MSG_HOOK_DATA pdmhd)
  252. {
  253. PEVENT_PACKET pep;
  254. PWND pwndFrom;
  255. TL tlpep;
  256. PTHREADINFO pti;
  257. CheckCritIn();
  258. pep = (PEVENT_PACKET)UserAllocPoolWithQuota(sizeof(EVENT_PACKET) -
  259. sizeof(DWORD) + sizeof(MONMSGSTRUCT), TAG_DDE8);
  260. if (pep == NULL) {
  261. return;
  262. }
  263. pep->EventType = flag;
  264. pep->fSense = TRUE;
  265. pep->cbEventData = sizeof(MONMSGSTRUCT);
  266. #define pmsgs ((MONMSGSTRUCT *)&pep->Data)
  267. pmsgs->cb = sizeof(MONMSGSTRUCT);
  268. pmsgs->hwndTo = PtoH(pwndTo);
  269. pmsgs->dwTime = NtGetTickCount();
  270. pwndFrom = RevalidateHwnd((HWND)wParam);
  271. if (pwndFrom != NULL) {
  272. pmsgs->hTask = GETPTIID(GETPTI(pwndFrom));
  273. } else {
  274. pmsgs->hTask = 0;
  275. }
  276. pmsgs->wMsg = message;
  277. pmsgs->wParam = wParam;
  278. pmsgs->lParam = lParam;
  279. if (pdmhd != NULL) {
  280. pmsgs->dmhd = *pdmhd;
  281. }
  282. #undef pmsgs
  283. pti = PtiCurrent();
  284. ThreadLockPool(pti, pep, &tlpep);
  285. xxxCsEvent(pep, sizeof(MONMSGSTRUCT));
  286. ThreadUnlockAndFreePool(pti, &tlpep);
  287. }