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

// Copyright (C) 1997-1999 by Microsoft Corporation. All rights reserved.
//
// ----------------------------------------------------------------------
// Additions/ Bug fixes 1999 Anil Kumar
//
// InitMSAA calls InitHelperThread, which creates (duh) a helper thread.
// In a past version, the WinEventProc would process the WinEvents by
// calling AccessibleObjectFromEvent on some events, then calling
// AddEventInfoToStack for all events.
// Problem is that the objects obtained in the main thread cannot be
// used in the helper thread. So now the helper thread will get it's
// own IAccessibleObjects when it processes the events, and all
// IAccessible objects will be created, used, and released by the
// helper thread.
//
#define STRICT
#include <windows.h>
#include <windowsx.h>
#include <oleacc.h>
#include <objbase.h>
#include "keys.h" // for ProcessWinEvent
#include "list.h" // include list.h before helpthd.h, GINFO needs CList
#include "HelpThd.h"
//
// global variables
//
GINFO gInfo;
//
// Local function prototypes
//
BOOL OnHelperThreadEvent (void);
DWORD MsgWaitForSingleObject(HANDLE hEvent, DWORD dwTimeout);
/*************************************************************************
Function:
Purpose:
Inputs:
Returns:
History:
*************************************************************************/
DWORD WINAPI HelperThreadProc(LPVOID lpParameter)
{
HRESULT hr;
DWORD dwWakeup;
// start COM on this thread
// SteveDon: CoInitializeEx is supported on both Win95 and WinNT, according to
// the SDK docs. Exported from ole32.dll, and defined in objbase.h.
// The thing is, for it to be defined, _WIN32_WINNT must be #defined and
// greater than 0x0400. But since CoInitialize(NULL) is equivalent to
// CoInitializeEx (NULL,COINIT_APARTMENTTHREADED), we'll just do the
// former so it works for sure on both 95 and NT
//
hr = CoInitialize (NULL);
if (FAILED (hr))
{
DBPRINTF (TEXT("CoInitialize on helper thread returned 0x%lX\r\n"),hr);
return (hr);
}
// GetGUIThreadInfo (called from acc_getState) will fail if both threads
// are not on the same desktop.
SetThreadDesktop(GetThreadDesktop( g_tidMain )); // ROBSI: 10-10-99
MSG msg;
while (TRUE)
{
DWORD dwObj = WAIT_FAILED;
dwObj = MsgWaitForMultipleObjects(1, &gInfo.hHelperEvent, FALSE, INFINITE, QS_ALLINPUT );
// Proccess the WinEvent
if ( dwObj == WAIT_OBJECT_0 )
{
// OnHelperThreadEvent will return FALSE when it gets
// the EndHelper event, which means we can terminate
// the helper thread.
if (!OnHelperThreadEvent())
{
DBPRINTF( TEXT("Terminating HelperThreadProc") );
CoUninitialize();
return 0;
}
}
// procces messages that are sent to us. The only message we expect is
// WM_TIMER message
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return 0;
}
/*************************************************************************
Function:
Purpose:
Inputs:
Returns:
History:
*************************************************************************/
BOOL OnHelperThreadEvent (void)
{
Sleep(100); // was this added by Paul? Not sure why it is here...
STACKABLE_EVENT_INFO sei;
while(RemoveInfoFromStack(&sei))
{
switch(sei.m_Action)
{
case STACKABLE_EVENT_INFO::EndHelper:
return (FALSE);
case STACKABLE_EVENT_INFO::NewEvent:
__try
{
ProcessWinEvent(sei.event, sei.hwndMsg, sei.idObject,
sei.idChild, sei.idThread, sei.dwmsEventTime);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DBPRINTF(TEXT("ProcessWinEvent Exception event=0x%x, hwndMsg=0x%x, idObject=0x%x, idChild=0x%x, idThread=0x%x, dwmsEventTime=0x%x\r\n"),
sei.event, sei.hwndMsg, sei.idObject, sei.idChild, sei.idThread, sei.dwmsEventTime);
}
break;
default:
break;
} // end switch sei.m_Action
} // end while RemoveInfoFromStack
return (TRUE);
} // end OnHelperThreadEvent
/*************************************************************************
Function:
Purpose:
Inputs:
Returns:
History:
*************************************************************************/
void AddEventInfoToStack(DWORD event,HWND hwndMsg, LONG idObject, LONG idChild,
DWORD idThread, DWORD dwmsEventTime)
{
STACKABLE_EVENT_INFO sei;
sei.m_Action = STACKABLE_EVENT_INFO::NewEvent;
sei.event = event;
sei.hwndMsg = hwndMsg;
sei.idObject = idObject;
sei.idChild = idChild;
sei.idThread = idThread;
sei.dwmsEventTime = dwmsEventTime;
EnterCriticalSection(&gInfo.HelperCritSect);
gInfo.EventInfoList.Add(&sei,sizeof(sei));
LeaveCriticalSection(&gInfo.HelperCritSect);
SetEvent(gInfo.hHelperEvent);
}
/*************************************************************************
Function:
Purpose:
Inputs:
Returns:
History:
*************************************************************************/
BOOL RemoveInfoFromStack(STACKABLE_EVENT_INFO *pEventInfo)
{
BOOL bReturn = TRUE;
EnterCriticalSection(&gInfo.HelperCritSect);
bReturn = !(gInfo.EventInfoList.IsEmpty());
if (bReturn)
gInfo.EventInfoList.RemoveHead(pEventInfo);
LeaveCriticalSection(&gInfo.HelperCritSect);
return bReturn;
}
/*************************************************************************
Function:
Purpose:
Inputs:
Returns:
History:
*************************************************************************/
void InitHelperThread()
{
DWORD dwThreadId;
g_tidMain = GetCurrentThreadId(); // ROBSI: 10-10-99
InitializeCriticalSection(&gInfo.HelperCritSect);
gInfo.hHelperEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
gInfo.hHelperThread = CreateThread(NULL, 0, HelperThreadProc, NULL, 0,
&dwThreadId);
}
/*************************************************************************
Function:
Purpose:
Inputs:
Returns:
History:
*************************************************************************/
void UnInitHelperThread()
{
STACKABLE_EVENT_INFO sei;
EnterCriticalSection(&gInfo.HelperCritSect);
// Force only one event in the queue
gInfo.EventInfoList.RemoveAll();
sei.m_Action = STACKABLE_EVENT_INFO::EndHelper;
gInfo.EventInfoList.Add(&sei,sizeof(sei));
LeaveCriticalSection(&gInfo.HelperCritSect);
SetEvent(gInfo.hHelperEvent);
// Wait for the thread to die
// note the last sei will be freed by deconstructor
// Donot wait for eternity here!! Do not care really during Exit!!
WaitForSingleObject(gInfo.hHelperThread, 3000);
}