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.

185 lines
4.5 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. #define SERVICE_NAME TEXT("6to4")
  4. HANDLE g_hServiceStatusHandle = INVALID_HANDLE_VALUE;
  5. HANDLE g_hDeviceNotificationHandle = INVALID_HANDLE_VALUE;
  6. SERVICE_STATUS g_ServiceStatus;
  7. VOID
  8. Set6to4ServiceStatus(
  9. IN DWORD dwState,
  10. IN DWORD dwErr)
  11. {
  12. BOOL bOk;
  13. Trace1(FSM, _T("Setting state to %d"), dwState);
  14. g_ServiceStatus.dwCurrentState = dwState;
  15. g_ServiceStatus.dwCheckPoint = 0;
  16. g_ServiceStatus.dwWin32ExitCode= dwErr;
  17. #ifndef STANDALONE
  18. bOk = SetServiceStatus(g_hServiceStatusHandle, &g_ServiceStatus);
  19. if (!bOk) {
  20. Trace0(ERR, _T("SetServiceStatus returned failure"));
  21. }
  22. #endif
  23. if (dwState == SERVICE_STOPPED) {
  24. Cleanup6to4();
  25. // Uninitialize tracing and error logging.
  26. UNINITIALIZE_TRACING_LOGGING();
  27. }
  28. }
  29. DWORD
  30. OnStartup()
  31. {
  32. int i;
  33. DWORD dwErr;
  34. WSADATA wsaData;
  35. ENTER_API();
  36. // Initialize tracing and error logging. Continue irrespective of
  37. // success or failure. NOTE: TracePrintf and ReportEvent both have
  38. // built in checks for validity of TRACEID and LOGHANDLE.
  39. INITIALIZE_TRACING_LOGGING();
  40. TraceEnter("OnStartup");
  41. dwErr = Start6to4();
  42. TraceLeave("OnStartup");
  43. LEAVE_API();
  44. return dwErr;
  45. }
  46. VOID
  47. OnStop(
  48. IN DWORD dwErr)
  49. {
  50. DWORD i;
  51. ENTER_API();
  52. TraceEnter("OnStop");
  53. Set6to4ServiceStatus(SERVICE_STOP_PENDING, dwErr);
  54. if (Stop6to4()) {
  55. Set6to4ServiceStatus(SERVICE_STOPPED, dwErr);
  56. }
  57. if (g_hDeviceNotificationHandle != INVALID_HANDLE_VALUE) {
  58. UnregisterDeviceNotification(g_hDeviceNotificationHandle);
  59. }
  60. TraceLeave("OnStop");
  61. LEAVE_API();
  62. }
  63. ////////////////////////////////////////////////////////////////
  64. // ServiceMain - main entry point called by svchost or by the
  65. // standalone main.
  66. //
  67. DWORD WINAPI
  68. ServiceHandler(
  69. IN DWORD dwControl,
  70. IN DWORD dwEventType,
  71. IN PVOID pvEventData,
  72. IN PVOID pvContext)
  73. {
  74. switch (dwControl) {
  75. case SERVICE_CONTROL_DEVICEEVENT:
  76. if (g_ServiceStatus.dwCurrentState == SERVICE_RUNNING) {
  77. ENTER_API();
  78. ShipwormDeviceChangeNotification(dwEventType, pvEventData);
  79. LEAVE_API();
  80. }
  81. return NO_ERROR;
  82. case SERVICE_CONTROL_STOP:
  83. OnStop(NO_ERROR);
  84. return NO_ERROR;
  85. case SERVICE_CONTROL_PARAMCHANGE:
  86. OnConfigChange();
  87. return NO_ERROR;
  88. default:
  89. Trace2(ANY, L"ServiceHandler %u (%u)", dwControl, dwEventType);
  90. break;
  91. }
  92. return ERROR_CALL_NOT_IMPLEMENTED;
  93. }
  94. VOID WINAPI
  95. ServiceMain(
  96. IN ULONG argc,
  97. IN LPWSTR *argv)
  98. {
  99. DWORD dwErr = NO_ERROR;
  100. DEV_BROADCAST_DEVICEINTERFACE PnpFilter;
  101. do {
  102. #ifndef STANDALONE
  103. g_hServiceStatusHandle = RegisterServiceCtrlHandlerEx(
  104. SERVICE_NAME, ServiceHandler, NULL);
  105. // RegisterServiceCtrlHandler returns NULL on failure
  106. if (g_hServiceStatusHandle == NULL) {
  107. dwErr = GetLastError();
  108. break;
  109. }
  110. // Register for adapter arrival and removal notifications.
  111. ZeroMemory (&PnpFilter, sizeof(PnpFilter));
  112. PnpFilter.dbcc_size = sizeof(PnpFilter);
  113. PnpFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
  114. PnpFilter.dbcc_classguid = GUID_NDIS_LAN_CLASS;
  115. g_hDeviceNotificationHandle = RegisterDeviceNotification (
  116. (HANDLE) g_hServiceStatusHandle,
  117. &PnpFilter,
  118. DEVICE_NOTIFY_SERVICE_HANDLE);
  119. if (g_hDeviceNotificationHandle == NULL) {
  120. dwErr = GetLastError();
  121. break;
  122. }
  123. #endif
  124. ZeroMemory(&g_ServiceStatus, sizeof(g_ServiceStatus));
  125. g_ServiceStatus.dwServiceType =
  126. SERVICE_WIN32_SHARE_PROCESS | SERVICE_INTERACTIVE_PROCESS;
  127. g_ServiceStatus.dwControlsAccepted =
  128. SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PARAMCHANGE;
  129. Set6to4ServiceStatus(SERVICE_START_PENDING, NO_ERROR);
  130. // Do startup processing
  131. dwErr = OnStartup();
  132. if (dwErr) {
  133. break;
  134. }
  135. #ifndef STANDALONE
  136. Set6to4ServiceStatus(SERVICE_RUNNING, NO_ERROR);
  137. // Wait until shutdown time
  138. return;
  139. #endif
  140. } while (FALSE);
  141. #ifndef STANDALONE
  142. OnStop(dwErr);
  143. #endif
  144. return;
  145. }