Source code of Windows XP (NT5)
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.

208 lines
5.3 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. SetEvent( wakeupEvent );
  77. break;
  78. case SERVICE_CONTROL_INTERROGATE:
  79. MSG_LOG(TRACE,"Control Request = INTERROGATE\n",0);
  80. MsgStatusUpdate (UPDATE_ONLY);
  81. break;
  82. case SERVICE_CONTROL_DEVICEEVENT:
  83. MSG_LOG(TRACE,"Control Request = DEVICEEVENT\n",0);
  84. if (dwEventType == DBT_DEVICEARRIVAL
  85. ||
  86. dwEventType == DBT_DEVICEREMOVECOMPLETE)
  87. {
  88. NTSTATUS ntStatus;
  89. if (s_hNeverSetEvent == NULL)
  90. {
  91. s_hNeverSetEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  92. if (s_hNeverSetEvent == NULL)
  93. {
  94. MsgStatusUpdate(UPDATE_ONLY);
  95. break;
  96. }
  97. }
  98. //
  99. // Assert that we're only getting the notifications we requested.
  100. // If this fails, we'll do an extra rescan of the LANAs but find
  101. // no changes and therefore do no extra work past that.
  102. //
  103. ASSERT(lpEventData
  104. &&
  105. ((PDEV_BROADCAST_DEVICEINTERFACE) lpEventData)->dbcc_devicetype
  106. == DBT_DEVTYP_DEVICEINTERFACE);
  107. MSG_LOG1(TRACE," Device has been %s\n",
  108. (dwEventType == DBT_DEVICEARRIVAL ? "added" : "removed"));
  109. //
  110. // We're currently waiting on LAN adapter install/removal, which does
  111. // not directly coincide with NetBios binding/unbinding. We need to
  112. // wait about 5 seconds to allow NetBios itself to process the event.
  113. // Don't do this synchronously or else sleep/hibernate takes 5 seconds
  114. // per LAN adapter to occur.
  115. //
  116. if (g_hNetTimeoutEvent == NULL)
  117. {
  118. ntStatus = RtlRegisterWait(&g_hNetTimeoutEvent, // Work item handle
  119. s_hNeverSetEvent, // Waitable handle
  120. MsgNetEventCompletion, // Callback
  121. NULL, // pContext
  122. 5000, // Timeout
  123. WT_EXECUTEONLYONCE | // One-shot and potentially lengthy
  124. WT_EXECUTELONGFUNCTION);
  125. if (!NT_SUCCESS(ntStatus))
  126. {
  127. MSG_LOG1(ERROR,
  128. "MsgrCtrlHandler: RtlRegisterWait failed %x\n",
  129. ntStatus);
  130. //
  131. // Asynchronous failed -- do it synchronously
  132. //
  133. Sleep(5000);
  134. SetEvent(wakeupEvent);
  135. }
  136. }
  137. }
  138. //
  139. // As long as we're here...
  140. //
  141. MsgStatusUpdate (UPDATE_ONLY);
  142. break;
  143. default:
  144. MSG_LOG(TRACE,"Control Request = OTHER (%#x)!!!\n", dwControl);
  145. ASSERT(FALSE);
  146. dwRetVal = ERROR_CALL_NOT_IMPLEMENTED;
  147. }
  148. return dwRetVal;
  149. }