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.

214 lines
4.8 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. SERVICE_STATUS_HANDLE g_hStatus;
  26. SERVICE_STATUS g_status;
  27. BOOLEAN g_FirstTime = TRUE;
  28. PSVCHOST_GLOBAL_DATA g_svcsGlobalData = NULL;
  29. BOOL
  30. InitializeWinreg( VOID );
  31. BOOL
  32. ShutdownWinreg(VOID);
  33. BOOL
  34. StartWinregRPCServer( VOID );
  35. VOID
  36. SvchostPushServiceGlobals(
  37. PSVCHOST_GLOBAL_DATA pGlobals
  38. )
  39. {
  40. g_svcsGlobalData = pGlobals;
  41. }
  42. VOID
  43. UpdateServiceStatus (DWORD dwCurrentState,
  44. DWORD dwWin32ExitCode,
  45. DWORD dwWaitHint)
  46. {
  47. static DWORD dwCheckPoint = 1;
  48. ASSERT (g_hStatus);
  49. if (dwCurrentState == SERVICE_START_PENDING) {
  50. g_status.dwControlsAccepted = 0;
  51. } else {
  52. g_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
  53. }
  54. g_status.dwCurrentState = dwCurrentState;
  55. g_status.dwWin32ExitCode = dwWin32ExitCode;
  56. g_status.dwWaitHint = dwWaitHint;
  57. if ( ( dwCurrentState == SERVICE_RUNNING ) || ( dwCurrentState == SERVICE_STOPPED ) ) {
  58. g_status.dwCheckPoint = 0;
  59. } else {
  60. g_status.dwCheckPoint = dwCheckPoint++;
  61. }
  62. SetServiceStatus (g_hStatus, &g_status);
  63. }
  64. VOID
  65. StopService()
  66. {
  67. //
  68. // Terminate the registry RPC server
  69. //
  70. ShutdownWinreg();
  71. g_svcsGlobalData = NULL;
  72. // report the status to the service control manager.
  73. //
  74. UpdateServiceStatus (SERVICE_STOPPED,NO_ERROR,0);
  75. }
  76. //+---------------------------------------------------------------------------
  77. // ServiceHandler - Called by the service controller at various times.
  78. //
  79. // type of LPHANDLER_FUNCTION
  80. //
  81. VOID
  82. WINAPI
  83. ServiceHandler (
  84. DWORD dwOpcode)
  85. {
  86. switch (dwOpcode)
  87. {
  88. case SERVICE_CONTROL_STOP:
  89. UpdateServiceStatus (SERVICE_STOP_PENDING,ERROR_SERVICE_SPECIFIC_ERROR,3000);
  90. StopService();
  91. break;
  92. case SERVICE_CONTROL_PAUSE:
  93. case SERVICE_CONTROL_CONTINUE:
  94. case SERVICE_CONTROL_INTERROGATE:
  95. case SERVICE_CONTROL_SHUTDOWN:
  96. default:
  97. // This may not be need, but refresh our status to the service
  98. // controller.
  99. //
  100. ASSERT (g_hStatus);
  101. SetServiceStatus (g_hStatus, &g_status);
  102. break;
  103. }
  104. }
  105. //+---------------------------------------------------------------------------
  106. // ServiceMain - Called by svchost when starting this service.
  107. //
  108. // type of LPSERVICE_MAIN_FUNCTIONW
  109. //
  110. VOID
  111. WINAPI
  112. ServiceMain (
  113. DWORD argc,
  114. PWSTR argv[])
  115. {
  116. RPC_STATUS Status;
  117. // Since we run in svchost.exe, we must have the 'share process' bit set.
  118. //
  119. ZeroMemory (&g_status, sizeof(g_status));
  120. g_status.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
  121. g_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
  122. ASSERT( g_svcsGlobalData != NULL );
  123. // Register the service control handler.
  124. //
  125. //DbgPrint( "Starting Remote Registry Service\n" );
  126. g_hStatus = RegisterServiceCtrlHandler (TEXT("RemoteRegistry"), ServiceHandler);
  127. if (g_hStatus)
  128. {
  129. UpdateServiceStatus (SERVICE_START_PENDING,NO_ERROR,3000);
  130. // now svchost.exe does it for us
  131. //RpcpInitRpcServer();
  132. if( g_FirstTime ) {
  133. if( !InitializeWinreg() ) {
  134. goto ErrorExit;
  135. }
  136. g_FirstTime = FALSE;
  137. } else {
  138. // just restart RPC service
  139. if( !StartWinregRPCServer() ) {
  140. goto ErrorExit;
  141. }
  142. }
  143. Status = RpcServerRegisterAuthInfo( NULL, RPC_C_AUTHN_WINNT, NULL, NULL );
  144. if( Status ) {
  145. goto Cleanup;
  146. }
  147. Status = RpcServerRegisterAuthInfo( NULL, RPC_C_AUTHN_GSS_NEGOTIATE, NULL, NULL);
  148. if( Status ) {
  149. goto Cleanup;
  150. }
  151. UpdateServiceStatus (SERVICE_RUNNING,NO_ERROR,0);
  152. return;
  153. Cleanup:
  154. //
  155. // Terminate the registry RPC server
  156. //
  157. ShutdownWinreg();
  158. ErrorExit:
  159. // report the status to the service control manager.
  160. //
  161. UpdateServiceStatus (SERVICE_STOPPED,NO_ERROR,0);
  162. //DbgPrint( "RegisterServiceCtrlHandler failed! (1)\n" );
  163. }
  164. else
  165. {
  166. DbgPrint( "RegisterServiceCtrlHandler failed! %d\n", GetLastError() );
  167. }
  168. }