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.

220 lines
5.2 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. regsvc.c
  5. Abstract:
  6. This module contains the implementation of the remote registry
  7. service.
  8. It just initialize and starts the registry RPC server. The service
  9. is supposed automatically started by SC at boot, and then restarted
  10. if something goes wrong.
  11. Used \nt\private\samples\service as a template
  12. Author:
  13. Dragos C. Sambotin (dragoss) 21-May-1999
  14. Revision History:
  15. Dragos C. Sambotin (dragoss) 10-Aug-2000
  16. - converted to a dll to be loaded inside a svchost.exe instance
  17. - used base\screg\sc\svchost\sample\server as a template
  18. --*/
  19. #include <nt.h>
  20. #include <ntrtl.h>
  21. #include <nturtl.h>
  22. #include <windows.h>
  23. #include <ntrpcp.h>
  24. #include <svcs.h>
  25. #include "..\perflib\ntconreg.h"
  26. SERVICE_STATUS_HANDLE g_hStatus;
  27. SERVICE_STATUS g_status;
  28. BOOLEAN g_FirstTime = TRUE;
  29. PSVCHOST_GLOBAL_DATA g_svcsGlobalData = NULL;
  30. BOOL
  31. InitializeWinreg( VOID );
  32. BOOL
  33. ShutdownWinreg(VOID);
  34. BOOL
  35. StartWinregRPCServer( VOID );
  36. VOID
  37. SvchostPushServiceGlobals(
  38. PSVCHOST_GLOBAL_DATA pGlobals
  39. )
  40. {
  41. g_svcsGlobalData = pGlobals;
  42. }
  43. VOID
  44. UpdateServiceStatus (DWORD dwCurrentState,
  45. DWORD dwWin32ExitCode,
  46. DWORD dwWaitHint)
  47. {
  48. static DWORD dwCheckPoint = 1;
  49. ASSERT (g_hStatus);
  50. if (dwCurrentState == SERVICE_START_PENDING) {
  51. g_status.dwControlsAccepted = 0;
  52. } else {
  53. g_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
  54. }
  55. g_status.dwCurrentState = dwCurrentState;
  56. g_status.dwWin32ExitCode = dwWin32ExitCode;
  57. g_status.dwWaitHint = dwWaitHint;
  58. if ( ( dwCurrentState == SERVICE_RUNNING ) || ( dwCurrentState == SERVICE_STOPPED ) ) {
  59. g_status.dwCheckPoint = 0;
  60. } else {
  61. g_status.dwCheckPoint = dwCheckPoint++;
  62. }
  63. SetServiceStatus (g_hStatus, &g_status);
  64. }
  65. VOID
  66. StopService()
  67. {
  68. //
  69. // Terminate the registry RPC server
  70. //
  71. ShutdownWinreg();
  72. g_svcsGlobalData = NULL;
  73. // report the status to the service control manager.
  74. //
  75. UpdateServiceStatus (SERVICE_STOPPED,NO_ERROR,0);
  76. }
  77. //+---------------------------------------------------------------------------
  78. // ServiceHandler - Called by the service controller at various times.
  79. //
  80. // type of LPHANDLER_FUNCTION
  81. //
  82. VOID
  83. WINAPI
  84. ServiceHandler (
  85. DWORD dwOpcode)
  86. {
  87. switch (dwOpcode)
  88. {
  89. case SERVICE_CONTROL_STOP:
  90. UpdateServiceStatus (SERVICE_STOP_PENDING,ERROR_SERVICE_SPECIFIC_ERROR,3000);
  91. StopService();
  92. break;
  93. case SERVICE_CONTROL_PAUSE:
  94. case SERVICE_CONTROL_CONTINUE:
  95. case SERVICE_CONTROL_INTERROGATE:
  96. case SERVICE_CONTROL_SHUTDOWN:
  97. default:
  98. // This may not be need, but refresh our status to the service
  99. // controller.
  100. //
  101. ASSERT (g_hStatus);
  102. SetServiceStatus (g_hStatus, &g_status);
  103. break;
  104. }
  105. }
  106. //+---------------------------------------------------------------------------
  107. // ServiceMain - Called by svchost when starting this service.
  108. //
  109. // type of LPSERVICE_MAIN_FUNCTIONW
  110. //
  111. VOID
  112. WINAPI
  113. ServiceMain (
  114. DWORD argc,
  115. PWSTR argv[])
  116. {
  117. RPC_STATUS Status;
  118. // Since we run in svchost.exe, we must have the 'share process' bit set.
  119. //
  120. ZeroMemory (&g_status, sizeof(g_status));
  121. g_status.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
  122. g_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
  123. ASSERT( g_svcsGlobalData != NULL );
  124. // Register the service control handler.
  125. //
  126. //DbgPrint( "Starting Remote Registry Service\n" );
  127. g_hStatus = RegisterServiceCtrlHandler (TEXT("RemoteRegistry"), ServiceHandler);
  128. if (g_hStatus)
  129. {
  130. UpdateServiceStatus (SERVICE_START_PENDING,NO_ERROR,3000);
  131. // now svchost.exe does it for us
  132. //RpcpInitRpcServer();
  133. if (!PerfRegInitialize()) {
  134. goto ErrorExit;
  135. }
  136. if( g_FirstTime ) {
  137. if( !InitializeWinreg() ) {
  138. goto ErrorExit;
  139. }
  140. g_FirstTime = FALSE;
  141. } else {
  142. // just restart RPC service
  143. if( !StartWinregRPCServer() ) {
  144. goto ErrorExit;
  145. }
  146. }
  147. Status = RpcServerRegisterAuthInfo( NULL, RPC_C_AUTHN_WINNT, NULL, NULL );
  148. if( Status ) {
  149. goto Cleanup;
  150. }
  151. Status = RpcServerRegisterAuthInfo( NULL, RPC_C_AUTHN_GSS_NEGOTIATE, NULL, NULL);
  152. if( Status ) {
  153. goto Cleanup;
  154. }
  155. UpdateServiceStatus (SERVICE_RUNNING,NO_ERROR,0);
  156. return;
  157. Cleanup:
  158. //
  159. // Terminate the registry RPC server
  160. //
  161. ShutdownWinreg();
  162. ErrorExit:
  163. // report the status to the service control manager.
  164. //
  165. UpdateServiceStatus (SERVICE_STOPPED,NO_ERROR,0);
  166. //DbgPrint( "RegisterServiceCtrlHandler failed! (1)\n" );
  167. }
  168. else
  169. {
  170. DbgPrint( "RegisterServiceCtrlHandler failed! %d\n", GetLastError() );
  171. }
  172. }