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.
201 lines
4.5 KiB
201 lines
4.5 KiB
/*
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
Panic.cpp
|
|
|
|
Abstract:
|
|
Sets up a Key board hook on calling SetPanicHook and removes the KeyBoard hook on calling
|
|
ClearPanicHook. Calling SetPanicHook creates a new thread which waits for the setting of an
|
|
named event. And on the setting of the named event it Invokes the script function pointer
|
|
passed to SetPanicHook.
|
|
|
|
Revision History:
|
|
created a-josem 1/3/01
|
|
revised a-josem 1/4/01 Added comments and function headers.
|
|
|
|
*/
|
|
|
|
// Panic.cpp : Implementation of CPanic
|
|
#include "stdafx.h"
|
|
#include "SAFRCFileDlg.h"
|
|
#include "Panic.h"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CPanic
|
|
CHookHnd CPanic::m_Hook;
|
|
HANDLE CPanic::m_hPanicThread = NULL;
|
|
LPSTREAM g_spStream = NULL;
|
|
BOOL g_bHookActive = FALSE;
|
|
/*++
|
|
Routine Description:
|
|
Destructor, In case the m_hEvent is not set it sets the event and exits. Setting of
|
|
the event makes the Panic watch thread to come out of wait.
|
|
|
|
Arguments:
|
|
None
|
|
|
|
Return Value:
|
|
None
|
|
--*/
|
|
|
|
CPanic::~CPanic()
|
|
{
|
|
g_bHookActive = FALSE;
|
|
if (m_hEvent)
|
|
{
|
|
SetEvent(m_hEvent);
|
|
}
|
|
}
|
|
|
|
/*++
|
|
Routine Description:
|
|
Called from script to setup a Panic Keyboard Hook. It also Marshalls the IDispatch ptr
|
|
to LPSTREAM to be used by the Panic watch thread. If the Panic watch thread is not created
|
|
this function creates the thread.
|
|
|
|
Arguments:
|
|
iDisp - Function pointer to the JavaScript function passed from script
|
|
|
|
Return Value:
|
|
S_OK on success.
|
|
--*/
|
|
STDMETHODIMP CPanic::SetPanicHook(IDispatch *iDisp)
|
|
{
|
|
m_Hook.SetHook();
|
|
if (iDisp)
|
|
{
|
|
if (m_ptrScriptFncPtr != iDisp)
|
|
{
|
|
m_ptrScriptFncPtr = iDisp;
|
|
g_bHookActive = TRUE;
|
|
CoMarshalInterThreadInterfaceInStream(IID_IDispatch,iDisp,&g_spStream);
|
|
if (m_hPanicThread != NULL)
|
|
{
|
|
if (WAIT_TIMEOUT != WaitForSingleObject(m_hPanicThread,0) )
|
|
{
|
|
if (m_hPanicThread != NULL)
|
|
{
|
|
CloseHandle(m_hPanicThread);
|
|
m_hPanicThread = NULL;
|
|
}
|
|
DWORD ThreadId;
|
|
m_hPanicThread = CreateThread(NULL,0,PanicThread,this,0,&ThreadId);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DWORD ThreadId;
|
|
m_hPanicThread = CreateThread(NULL,0,PanicThread,this,0,&ThreadId);
|
|
}
|
|
}
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
/*++
|
|
Routine Description:
|
|
Clears the PanicHook. And Sets the Event so that the thread comes out of wait and exits
|
|
gracefully.
|
|
|
|
Arguments:
|
|
None
|
|
|
|
Return Value:
|
|
S_OK on success.
|
|
--*/
|
|
STDMETHODIMP CPanic::ClearPanicHook()
|
|
{
|
|
m_Hook.UnHook();
|
|
m_ptrScriptFncPtr = NULL;
|
|
g_bHookActive = FALSE;
|
|
if (m_hEvent)
|
|
{
|
|
SetEvent(m_hEvent);
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
/*++
|
|
Routine Description:
|
|
The thread function creates an Event and waits for the Event to be set. The event is set
|
|
when the Panic key is pressed. It immediately comes out of the wait state and calls the
|
|
Javascript function.
|
|
|
|
Arguments:
|
|
lpParameter - CPanic Object address
|
|
|
|
Return Value:
|
|
S_OK on success.
|
|
--*/
|
|
DWORD WINAPI CPanic::PanicThread(LPVOID lpParameter)
|
|
{
|
|
CoInitialize(NULL);
|
|
CPanic *ptrThis = (CPanic *)lpParameter;
|
|
|
|
if (g_spStream)
|
|
{
|
|
CComPtr<IDispatch> ptrIDisp;
|
|
CoGetInterfaceAndReleaseStream(g_spStream,IID_IDispatch,(void**)&ptrIDisp);
|
|
g_spStream = NULL;
|
|
|
|
ptrThis->m_hEvent = CreateEvent(NULL,FALSE,FALSE,_T(EventName));
|
|
HRESULT hr;
|
|
|
|
while (g_bHookActive == TRUE)
|
|
{
|
|
DWORD dwWaitResult = WaitForMultipleObjects(1,&(ptrThis->m_hEvent),TRUE,INFINITE);
|
|
|
|
switch (dwWaitResult)
|
|
{
|
|
case WAIT_OBJECT_0:
|
|
{
|
|
if ((ptrIDisp != NULL) && (g_bHookActive == TRUE))
|
|
{
|
|
DISPPARAMS disp = { NULL, NULL, 0, 0 };
|
|
hr = ptrIDisp->Invoke(0x0, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
ResetEvent(ptrThis->m_hEvent);
|
|
}
|
|
if (ptrThis->m_hEvent)
|
|
{
|
|
CloseHandle(ptrThis->m_hEvent);
|
|
ptrThis->m_hEvent = NULL;
|
|
}
|
|
}
|
|
|
|
CoUninitialize();
|
|
return 0;
|
|
}
|
|
|
|
/*++
|
|
Routine Description:
|
|
Called when ever a key board event occurs. It handles only WM_KEYUP of Esc Key.
|
|
|
|
Arguments:
|
|
code
|
|
wParam
|
|
lParam
|
|
|
|
Return Value:
|
|
returns what ever CallNextHookEx returns.
|
|
--*/
|
|
LRESULT CALLBACK KeyboardProc(int code,WPARAM wParam,LPARAM lParam)
|
|
{
|
|
if (code == HC_ACTION)
|
|
{
|
|
if ((wParam == 27) & (lParam >> 31))
|
|
{
|
|
HANDLE hEvent = CreateEvent(NULL,FALSE,FALSE,_T(EventName));
|
|
if (hEvent)
|
|
{
|
|
SetEvent(hEvent);
|
|
CloseHandle(hEvent);
|
|
}
|
|
}
|
|
}
|
|
return CallNextHookEx(CPanic::m_Hook.m_hHook,code,wParam,lParam);
|
|
}
|