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.

225 lines
6.2 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. sighandl.c
  5. Abstract:
  6. The Messenger Service ControlHandling routines. This file contains
  7. the following functions:
  8. MsgrCtrlHandler
  9. uninstall
  10. Author:
  11. Dan Lafferty (danl) 17-Jul-1991
  12. Environment:
  13. User Mode -Win32
  14. Revision History:
  15. 17-Jul-1991 danl
  16. Ported from LM2.0
  17. --*/
  18. //
  19. // Includes
  20. //
  21. #include "msrv.h" // Message server declarations
  22. #include <winsvc.h> // SERVICE_STOP
  23. #include <dbt.h> // DBT_DEVICEARRIVAL, DBT_DEVICEREMOVECOMPLETE
  24. #include <netlib.h> // UNUSED macro
  25. #include <msgdbg.h> // MSG_LOG
  26. #include "msgdata.h"
  27. DWORD
  28. MsgrCtrlHandler(
  29. IN DWORD dwControl,
  30. IN DWORD dwEventType,
  31. IN LPVOID lpEventData,
  32. IN LPVOID lpContext
  33. )
  34. /*++
  35. Routine Description:
  36. This function receives control requests that come in from the
  37. Service Controller
  38. Arguments:
  39. dwControl - This is the control code.
  40. dwEventType - In the case of a PnP control, the PNP event that occurred
  41. lpEventData - Event-specific data for PnP controls
  42. lpContext - Context data
  43. Return Value:
  44. --*/
  45. {
  46. DWORD dwRetVal = NO_ERROR;
  47. static HANDLE s_hNeverSetEvent;
  48. MSG_LOG(TRACE,"Control Request Received\n",0);
  49. switch (dwControl) {
  50. case SERVICE_CONTROL_SHUTDOWN:
  51. MSG_LOG(TRACE,"Control Request = SHUTDOWN\n",0);
  52. // Fall through
  53. case SERVICE_CONTROL_STOP:
  54. MSG_LOG(TRACE,"Control Request = STOP\n",0);
  55. //
  56. // Start the de-installation. This call includes the sending of
  57. // the new status to the Service Controller.
  58. //
  59. //
  60. // Update the Service Status to the pending state. And wake up
  61. // the display thread (if running) so it will read it.
  62. //
  63. MsgStatusUpdate (STOPPING);
  64. if (s_hNeverSetEvent != NULL)
  65. {
  66. CloseHandle(s_hNeverSetEvent);
  67. s_hNeverSetEvent = NULL;
  68. }
  69. //
  70. // In Hydra case, the display thread never goes asleep.
  71. //
  72. if (!g_IsTerminalServer)
  73. {
  74. MsgDisplayThreadWakeup();
  75. }
  76. MsgConfigurationLock(MSG_GET_SHARED, "MsgrCtrlHandler");
  77. //
  78. // If a message or LANA addition/removal message came in at the same time
  79. // as the stop/shutdown control, it's possible that MsgNetEventCompletion
  80. // has already run with the state set to STOPPING, in which case it's already
  81. // done cleanup, so we don't need to (and shouldn't) set the wakeupEvent.
  82. //
  83. if (wakeupEvent != NULL)
  84. {
  85. SetEvent( wakeupEvent );
  86. }
  87. MsgConfigurationLock(MSG_RELEASE, "MsgrCtrlHandler");
  88. break;
  89. case SERVICE_CONTROL_INTERROGATE:
  90. MSG_LOG(TRACE,"Control Request = INTERROGATE\n",0);
  91. MsgStatusUpdate (UPDATE_ONLY);
  92. break;
  93. case SERVICE_CONTROL_DEVICEEVENT:
  94. MSG_LOG(TRACE,"Control Request = DEVICEEVENT\n",0);
  95. if (dwEventType == DBT_DEVICEARRIVAL
  96. ||
  97. dwEventType == DBT_DEVICEREMOVECOMPLETE)
  98. {
  99. NTSTATUS ntStatus;
  100. if (s_hNeverSetEvent == NULL)
  101. {
  102. s_hNeverSetEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  103. if (s_hNeverSetEvent == NULL)
  104. {
  105. MsgStatusUpdate(UPDATE_ONLY);
  106. break;
  107. }
  108. }
  109. //
  110. // Assert that we're only getting the notifications we requested.
  111. // If this fails, we'll do an extra rescan of the LANAs but find
  112. // no changes and therefore do no extra work past that.
  113. //
  114. ASSERT(lpEventData
  115. &&
  116. ((PDEV_BROADCAST_DEVICEINTERFACE) lpEventData)->dbcc_devicetype
  117. == DBT_DEVTYP_DEVICEINTERFACE);
  118. MSG_LOG1(TRACE," Device has been %s\n",
  119. (dwEventType == DBT_DEVICEARRIVAL ? "added" : "removed"));
  120. //
  121. // We're currently waiting on LAN adapter install/removal, which does
  122. // not directly coincide with NetBios binding/unbinding. We need to
  123. // wait about 5 seconds to allow NetBios itself to process the event.
  124. // Don't do this synchronously or else sleep/hibernate takes 5 seconds
  125. // per LAN adapter to occur.
  126. //
  127. if (g_hNetTimeoutEvent == NULL)
  128. {
  129. ntStatus = RtlRegisterWait(&g_hNetTimeoutEvent, // Work item handle
  130. s_hNeverSetEvent, // Waitable handle
  131. MsgNetEventCompletion, // Callback
  132. NULL, // pContext
  133. 5000, // Timeout
  134. WT_EXECUTEONLYONCE | // One-shot and potentially lengthy
  135. WT_EXECUTELONGFUNCTION);
  136. if (!NT_SUCCESS(ntStatus))
  137. {
  138. MSG_LOG1(ERROR,
  139. "MsgrCtrlHandler: RtlRegisterWait failed %x\n",
  140. ntStatus);
  141. //
  142. // Asynchronous failed -- do it synchronously
  143. //
  144. Sleep(5000);
  145. MsgConfigurationLock(MSG_GET_SHARED, "MsgrCtrlHandler");
  146. SetEvent(wakeupEvent);
  147. MsgConfigurationLock(MSG_GET_SHARED, "MsgrCtrlHandler");
  148. }
  149. }
  150. }
  151. //
  152. // As long as we're here...
  153. //
  154. MsgStatusUpdate (UPDATE_ONLY);
  155. break;
  156. default:
  157. MSG_LOG(TRACE,"Control Request = OTHER (%#x)!!!\n", dwControl);
  158. ASSERT(FALSE);
  159. dwRetVal = ERROR_CALL_NOT_IMPLEMENTED;
  160. }
  161. return dwRetVal;
  162. }