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

  1. /*
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. Panic.cpp
  5. Abstract:
  6. Sets up a Key board hook on calling SetPanicHook and removes the KeyBoard hook on calling
  7. ClearPanicHook. Calling SetPanicHook creates a new thread which waits for the setting of an
  8. named event. And on the setting of the named event it Invokes the script function pointer
  9. passed to SetPanicHook.
  10. Revision History:
  11. created a-josem 1/3/01
  12. revised a-josem 1/4/01 Added comments and function headers.
  13. */
  14. // Panic.cpp : Implementation of CPanic
  15. #include "stdafx.h"
  16. #include "SAFRCFileDlg.h"
  17. #include "Panic.h"
  18. /////////////////////////////////////////////////////////////////////////////
  19. // CPanic
  20. CHookHnd CPanic::m_Hook;
  21. HANDLE CPanic::m_hPanicThread = NULL;
  22. LPSTREAM g_spStream = NULL;
  23. BOOL g_bHookActive = FALSE;
  24. /*++
  25. Routine Description:
  26. Destructor, In case the m_hEvent is not set it sets the event and exits. Setting of
  27. the event makes the Panic watch thread to come out of wait.
  28. Arguments:
  29. None
  30. Return Value:
  31. None
  32. --*/
  33. CPanic::~CPanic()
  34. {
  35. g_bHookActive = FALSE;
  36. if (m_hEvent)
  37. {
  38. SetEvent(m_hEvent);
  39. }
  40. }
  41. /*++
  42. Routine Description:
  43. Called from script to setup a Panic Keyboard Hook. It also Marshalls the IDispatch ptr
  44. to LPSTREAM to be used by the Panic watch thread. If the Panic watch thread is not created
  45. this function creates the thread.
  46. Arguments:
  47. iDisp - Function pointer to the JavaScript function passed from script
  48. Return Value:
  49. S_OK on success.
  50. --*/
  51. STDMETHODIMP CPanic::SetPanicHook(IDispatch *iDisp)
  52. {
  53. m_Hook.SetHook();
  54. if (iDisp)
  55. {
  56. if (m_ptrScriptFncPtr != iDisp)
  57. {
  58. m_ptrScriptFncPtr = iDisp;
  59. g_bHookActive = TRUE;
  60. CoMarshalInterThreadInterfaceInStream(IID_IDispatch,iDisp,&g_spStream);
  61. if (m_hPanicThread != NULL)
  62. {
  63. if (WAIT_TIMEOUT != WaitForSingleObject(m_hPanicThread,0) )
  64. {
  65. if (m_hPanicThread != NULL)
  66. {
  67. CloseHandle(m_hPanicThread);
  68. m_hPanicThread = NULL;
  69. }
  70. DWORD ThreadId;
  71. m_hPanicThread = CreateThread(NULL,0,PanicThread,this,0,&ThreadId);
  72. }
  73. }
  74. else
  75. {
  76. DWORD ThreadId;
  77. m_hPanicThread = CreateThread(NULL,0,PanicThread,this,0,&ThreadId);
  78. }
  79. }
  80. }
  81. return S_OK;
  82. }
  83. /*++
  84. Routine Description:
  85. Clears the PanicHook. And Sets the Event so that the thread comes out of wait and exits
  86. gracefully.
  87. Arguments:
  88. None
  89. Return Value:
  90. S_OK on success.
  91. --*/
  92. STDMETHODIMP CPanic::ClearPanicHook()
  93. {
  94. m_Hook.UnHook();
  95. m_ptrScriptFncPtr = NULL;
  96. g_bHookActive = FALSE;
  97. if (m_hEvent)
  98. {
  99. SetEvent(m_hEvent);
  100. }
  101. return S_OK;
  102. }
  103. /*++
  104. Routine Description:
  105. The thread function creates an Event and waits for the Event to be set. The event is set
  106. when the Panic key is pressed. It immediately comes out of the wait state and calls the
  107. Javascript function.
  108. Arguments:
  109. lpParameter - CPanic Object address
  110. Return Value:
  111. S_OK on success.
  112. --*/
  113. DWORD WINAPI CPanic::PanicThread(LPVOID lpParameter)
  114. {
  115. CoInitialize(NULL);
  116. CPanic *ptrThis = (CPanic *)lpParameter;
  117. if (g_spStream)
  118. {
  119. CComPtr<IDispatch> ptrIDisp;
  120. CoGetInterfaceAndReleaseStream(g_spStream,IID_IDispatch,(void**)&ptrIDisp);
  121. g_spStream = NULL;
  122. ptrThis->m_hEvent = CreateEvent(NULL,FALSE,FALSE,_T(EventName));
  123. HRESULT hr;
  124. while (g_bHookActive == TRUE)
  125. {
  126. DWORD dwWaitResult = WaitForMultipleObjects(1,&(ptrThis->m_hEvent),TRUE,INFINITE);
  127. switch (dwWaitResult)
  128. {
  129. case WAIT_OBJECT_0:
  130. {
  131. if ((ptrIDisp != NULL) && (g_bHookActive == TRUE))
  132. {
  133. DISPPARAMS disp = { NULL, NULL, 0, 0 };
  134. hr = ptrIDisp->Invoke(0x0, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
  135. }
  136. break;
  137. }
  138. }
  139. ResetEvent(ptrThis->m_hEvent);
  140. }
  141. if (ptrThis->m_hEvent)
  142. {
  143. CloseHandle(ptrThis->m_hEvent);
  144. ptrThis->m_hEvent = NULL;
  145. }
  146. }
  147. CoUninitialize();
  148. return 0;
  149. }
  150. /*++
  151. Routine Description:
  152. Called when ever a key board event occurs. It handles only WM_KEYUP of Esc Key.
  153. Arguments:
  154. code
  155. wParam
  156. lParam
  157. Return Value:
  158. returns what ever CallNextHookEx returns.
  159. --*/
  160. LRESULT CALLBACK KeyboardProc(int code,WPARAM wParam,LPARAM lParam)
  161. {
  162. if (code == HC_ACTION)
  163. {
  164. if ((wParam == 27) & (lParam >> 31))
  165. {
  166. HANDLE hEvent = CreateEvent(NULL,FALSE,FALSE,_T(EventName));
  167. if (hEvent)
  168. {
  169. SetEvent(hEvent);
  170. CloseHandle(hEvent);
  171. }
  172. }
  173. }
  174. return CallNextHookEx(CPanic::m_Hook.m_hHook,code,wParam,lParam);
  175. }