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.

248 lines
7.0 KiB

  1. // Copyright (C) 1997-1999 by Microsoft Corporation. All rights reserved.
  2. //
  3. // ----------------------------------------------------------------------
  4. // Additions/ Bug fixes 1999 Anil Kumar
  5. //
  6. // InitMSAA calls InitHelperThread, which creates (duh) a helper thread.
  7. // In a past version, the WinEventProc would process the WinEvents by
  8. // calling AccessibleObjectFromEvent on some events, then calling
  9. // AddEventInfoToStack for all events.
  10. // Problem is that the objects obtained in the main thread cannot be
  11. // used in the helper thread. So now the helper thread will get it's
  12. // own IAccessibleObjects when it processes the events, and all
  13. // IAccessible objects will be created, used, and released by the
  14. // helper thread.
  15. //
  16. #define STRICT
  17. #include <windows.h>
  18. #include <windowsx.h>
  19. #include <oleacc.h>
  20. #include <objbase.h>
  21. #include "keys.h" // for ProcessWinEvent
  22. #include "list.h" // include list.h before helpthd.h, GINFO needs CList
  23. #include "HelpThd.h"
  24. //
  25. // global variables
  26. //
  27. GINFO gInfo;
  28. //
  29. // Local function prototypes
  30. //
  31. BOOL OnHelperThreadEvent (void);
  32. DWORD MsgWaitForSingleObject(HANDLE hEvent, DWORD dwTimeout);
  33. /*************************************************************************
  34. Function:
  35. Purpose:
  36. Inputs:
  37. Returns:
  38. History:
  39. *************************************************************************/
  40. DWORD WINAPI HelperThreadProc(LPVOID lpParameter)
  41. {
  42. HRESULT hr;
  43. DWORD dwWakeup;
  44. // start COM on this thread
  45. // SteveDon: CoInitializeEx is supported on both Win95 and WinNT, according to
  46. // the SDK docs. Exported from ole32.dll, and defined in objbase.h.
  47. // The thing is, for it to be defined, _WIN32_WINNT must be #defined and
  48. // greater than 0x0400. But since CoInitialize(NULL) is equivalent to
  49. // CoInitializeEx (NULL,COINIT_APARTMENTTHREADED), we'll just do the
  50. // former so it works for sure on both 95 and NT
  51. //
  52. hr = CoInitialize (NULL);
  53. if (FAILED (hr))
  54. {
  55. DBPRINTF (TEXT("CoInitialize on helper thread returned 0x%lX\r\n"),hr);
  56. return (hr);
  57. }
  58. // GetGUIThreadInfo (called from acc_getState) will fail if both threads
  59. // are not on the same desktop.
  60. SetThreadDesktop(GetThreadDesktop( g_tidMain )); // ROBSI: 10-10-99
  61. MSG msg;
  62. while (TRUE)
  63. {
  64. DWORD dwObj = WAIT_FAILED;
  65. dwObj = MsgWaitForMultipleObjects(1, &gInfo.hHelperEvent, FALSE, INFINITE, QS_ALLINPUT );
  66. // Proccess the WinEvent
  67. if ( dwObj == WAIT_OBJECT_0 )
  68. {
  69. // OnHelperThreadEvent will return FALSE when it gets
  70. // the EndHelper event, which means we can terminate
  71. // the helper thread.
  72. if (!OnHelperThreadEvent())
  73. {
  74. DBPRINTF( TEXT("Terminating HelperThreadProc") );
  75. CoUninitialize();
  76. return 0;
  77. }
  78. }
  79. // procces messages that are sent to us. The only message we expect is
  80. // WM_TIMER message
  81. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  82. {
  83. TranslateMessage(&msg);
  84. DispatchMessage(&msg);
  85. }
  86. }
  87. return 0;
  88. }
  89. /*************************************************************************
  90. Function:
  91. Purpose:
  92. Inputs:
  93. Returns:
  94. History:
  95. *************************************************************************/
  96. BOOL OnHelperThreadEvent (void)
  97. {
  98. Sleep(100); // was this added by Paul? Not sure why it is here...
  99. STACKABLE_EVENT_INFO sei;
  100. while(RemoveInfoFromStack(&sei))
  101. {
  102. switch(sei.m_Action)
  103. {
  104. case STACKABLE_EVENT_INFO::EndHelper:
  105. return (FALSE);
  106. case STACKABLE_EVENT_INFO::NewEvent:
  107. __try
  108. {
  109. ProcessWinEvent(sei.event, sei.hwndMsg, sei.idObject,
  110. sei.idChild, sei.idThread, sei.dwmsEventTime);
  111. }
  112. __except(EXCEPTION_EXECUTE_HANDLER)
  113. {
  114. DBPRINTF(TEXT("ProcessWinEvent Exception event=0x%x, hwndMsg=0x%x, idObject=0x%x, idChild=0x%x, idThread=0x%x, dwmsEventTime=0x%x\r\n"),
  115. sei.event, sei.hwndMsg, sei.idObject, sei.idChild, sei.idThread, sei.dwmsEventTime);
  116. }
  117. break;
  118. default:
  119. break;
  120. } // end switch sei.m_Action
  121. } // end while RemoveInfoFromStack
  122. return (TRUE);
  123. } // end OnHelperThreadEvent
  124. /*************************************************************************
  125. Function:
  126. Purpose:
  127. Inputs:
  128. Returns:
  129. History:
  130. *************************************************************************/
  131. void AddEventInfoToStack(DWORD event,HWND hwndMsg, LONG idObject, LONG idChild,
  132. DWORD idThread, DWORD dwmsEventTime)
  133. {
  134. STACKABLE_EVENT_INFO sei;
  135. sei.m_Action = STACKABLE_EVENT_INFO::NewEvent;
  136. sei.event = event;
  137. sei.hwndMsg = hwndMsg;
  138. sei.idObject = idObject;
  139. sei.idChild = idChild;
  140. sei.idThread = idThread;
  141. sei.dwmsEventTime = dwmsEventTime;
  142. EnterCriticalSection(&gInfo.HelperCritSect);
  143. gInfo.EventInfoList.Add(&sei,sizeof(sei));
  144. LeaveCriticalSection(&gInfo.HelperCritSect);
  145. SetEvent(gInfo.hHelperEvent);
  146. }
  147. /*************************************************************************
  148. Function:
  149. Purpose:
  150. Inputs:
  151. Returns:
  152. History:
  153. *************************************************************************/
  154. BOOL RemoveInfoFromStack(STACKABLE_EVENT_INFO *pEventInfo)
  155. {
  156. BOOL bReturn = TRUE;
  157. EnterCriticalSection(&gInfo.HelperCritSect);
  158. bReturn = !(gInfo.EventInfoList.IsEmpty());
  159. if (bReturn)
  160. gInfo.EventInfoList.RemoveHead(pEventInfo);
  161. LeaveCriticalSection(&gInfo.HelperCritSect);
  162. return bReturn;
  163. }
  164. /*************************************************************************
  165. Function:
  166. Purpose:
  167. Inputs:
  168. Returns:
  169. History:
  170. *************************************************************************/
  171. void InitHelperThread()
  172. {
  173. DWORD dwThreadId;
  174. g_tidMain = GetCurrentThreadId(); // ROBSI: 10-10-99
  175. InitializeCriticalSection(&gInfo.HelperCritSect);
  176. gInfo.hHelperEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  177. gInfo.hHelperThread = CreateThread(NULL, 0, HelperThreadProc, NULL, 0,
  178. &dwThreadId);
  179. }
  180. /*************************************************************************
  181. Function:
  182. Purpose:
  183. Inputs:
  184. Returns:
  185. History:
  186. *************************************************************************/
  187. void UnInitHelperThread()
  188. {
  189. STACKABLE_EVENT_INFO sei;
  190. EnterCriticalSection(&gInfo.HelperCritSect);
  191. // Force only one event in the queue
  192. gInfo.EventInfoList.RemoveAll();
  193. sei.m_Action = STACKABLE_EVENT_INFO::EndHelper;
  194. gInfo.EventInfoList.Add(&sei,sizeof(sei));
  195. LeaveCriticalSection(&gInfo.HelperCritSect);
  196. SetEvent(gInfo.hHelperEvent);
  197. // Wait for the thread to die
  198. // note the last sei will be freed by deconstructor
  199. // Donot wait for eternity here!! Do not care really during Exit!!
  200. WaitForSingleObject(gInfo.hHelperThread, 3000);
  201. }