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.
 
 
 
 
 
 

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);
}