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.

304 lines
6.9 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. service.c
  5. Abstract:
  6. part of app that runs as an NT service.
  7. Author:
  8. Charlie Wickham (charlwi) 03-Oct-1999
  9. Revision History:
  10. --*/
  11. #define UNICODE 1
  12. #define _UNICODE 1
  13. #define LOG_CURRENT_MODULE LOG_MODULE_CLUSPW
  14. #include <windows.h>
  15. #include <winsvc.h>
  16. #include <stdio.h>
  17. #include "clusrtl.h"
  18. #include "cluspw.h"
  19. /* External */
  20. /* Static */
  21. SERVICE_STATUS ServiceStatus = {
  22. SERVICE_WIN32_OWN_PROCESS, // dwServiceType
  23. SERVICE_RUNNING, // dwCurrentState
  24. 0, // dwControlsAccepted
  25. ERROR_SUCCESS, // dwWin32ExitCode
  26. ERROR_SUCCESS, // dwServiceSpecificExitCode
  27. 1, // dwCheckPoint
  28. 30000 // dwWaitHint - 30 seconds
  29. };
  30. /* Forward */
  31. /* End Forward */
  32. VOID
  33. DbgPrint(
  34. PCHAR FormatString,
  35. ...
  36. )
  37. /*++
  38. Routine Description:
  39. Description
  40. Arguments:
  41. None
  42. Return Value:
  43. None
  44. --*/
  45. {
  46. CHAR szOutBuffer[1024];
  47. va_list argList;
  48. va_start( argList, FormatString );
  49. FormatMessageA(FORMAT_MESSAGE_FROM_STRING,
  50. FormatString,
  51. 0,
  52. 0,
  53. szOutBuffer,
  54. sizeof(szOutBuffer) / sizeof(szOutBuffer[0]),
  55. &argList);
  56. va_end( argList );
  57. OutputDebugStringA( szOutBuffer );
  58. }
  59. VOID WINAPI
  60. ControlHandler(
  61. DWORD fdwControl // requested control code
  62. )
  63. /*++
  64. Routine Description:
  65. Description
  66. Arguments:
  67. None
  68. Return Value:
  69. None
  70. --*/
  71. {
  72. DbgPrint("Received service control %1!08X!\n", fdwControl);
  73. return;
  74. }
  75. VOID WINAPI
  76. ServiceMain(
  77. DWORD argc,
  78. LPTSTR argv[]
  79. )
  80. {
  81. PIPE_RESULT_MSG resultMsg;
  82. DWORD nodeNameSize = sizeof( NodeName );
  83. BOOL success;
  84. DWORD bytesWritten;
  85. WCHAR cluspwFile[ MAX_PATH ];
  86. DWORD byteCount;
  87. DWORD status;
  88. SERVICE_STATUS_HANDLE statusHandle;
  89. //
  90. // Initialize service to receive service requests by registering the
  91. // control handler.
  92. //
  93. statusHandle = RegisterServiceCtrlHandler( CLUSPW_SERVICE_NAME, ControlHandler );
  94. if ( statusHandle == NULL ) {
  95. status = GetLastError();
  96. DbgPrint("can't get service status handle - %1!u!\n", status);
  97. return;
  98. }
  99. SetServiceStatus(statusHandle, &ServiceStatus);
  100. //
  101. // parse the args used to start the service
  102. //
  103. status = ParseArgs( argc, argv );
  104. if ( status != ERROR_SUCCESS ) {
  105. DbgPrint("ParseArgs failed - %1!d!\n", status);
  106. goto cleanup;
  107. }
  108. //
  109. // get the node name to stuff in each result msg
  110. //
  111. #if (_WIN32_WINNT > 0x04FF)
  112. success = GetComputerNameEx(ComputerNamePhysicalNetBIOS,
  113. NodeName,
  114. &nodeNameSize);
  115. #else
  116. success = GetComputerName( NodeName, &nodeNameSize );
  117. #endif
  118. if ( !success ) {
  119. status = GetLastError();
  120. DbgPrint("GetComputerName failed - %1!d!\n", status );
  121. status = ERROR_SUCCESS;
  122. }
  123. DbgPrint( "Opening pipe %1!ws!\n", ResultPipeName );
  124. //
  125. // open the named pipe on which to write msgs and final result
  126. //
  127. success = WaitNamedPipe( ResultPipeName, NMPWAIT_WAIT_FOREVER );
  128. if ( success ) {
  129. PipeHandle = CreateFile(ResultPipeName,
  130. GENERIC_WRITE,
  131. 0,
  132. NULL,
  133. OPEN_EXISTING,
  134. 0,
  135. NULL);
  136. if ( PipeHandle == INVALID_HANDLE_VALUE ) {
  137. status = GetLastError();
  138. DbgPrint("CreateFile on result pipe failed - %1!d!\n", status );
  139. }
  140. }
  141. else {
  142. status = GetLastError();
  143. DbgPrint("WaitNamedPipe on result pipe failed - %1!d!\n", status );
  144. goto cleanup;
  145. }
  146. //
  147. // update the password cache
  148. //
  149. wcscpy( resultMsg.NodeName, NodeName );
  150. resultMsg.MsgType = MsgTypeFinalStatus;
  151. resultMsg.Status = ChangeCachedPassword(UserName,
  152. DomainName,
  153. NewPassword);
  154. if ( resultMsg.Status == ERROR_SUCCESS ) {
  155. ClRtlLogPrint(LOG_NOISE,
  156. "[CPW] Cluster service account password successfully updated.\n");
  157. CL_LOGCLUSINFO( SERVICE_PASSWORD_CHANGE_SUCCESS );
  158. } else {
  159. ClRtlLogPrint(LOG_CRITICAL,
  160. "[CPW] Cluster service account password update failed - %u.\n",
  161. status);
  162. ClusterLogEvent0(LOG_CRITICAL,
  163. LOG_CURRENT_MODULE,
  164. __FILE__,
  165. __LINE__,
  166. SERVICE_PASSWORD_CHANGE_FAILED,
  167. sizeof( resultMsg.Status ),
  168. (PVOID)&resultMsg.Status);
  169. }
  170. DbgPrint("Final Result: %1!d!\n", resultMsg.Status );
  171. success = WriteFile(PipeHandle,
  172. &resultMsg,
  173. sizeof( resultMsg ),
  174. &bytesWritten,
  175. NULL);
  176. if ( !success ) {
  177. DbgPrint("WriteFile failed in wmain - %1!d!\n", GetLastError() );
  178. DbgPrint("final status: %1!d!\n", resultMsg.Status);
  179. }
  180. CloseHandle( PipeHandle );
  181. //
  182. // let SCM know we're shutting down
  183. //
  184. cleanup:
  185. ServiceStatus.dwCurrentState = SERVICE_STOPPED;
  186. ServiceStatus.dwWin32ExitCode = status;
  187. SetServiceStatus(statusHandle, &ServiceStatus);
  188. } // ServiceMain
  189. VOID
  190. ServiceStartup(
  191. VOID
  192. )
  193. /*++
  194. Routine Description:
  195. Description
  196. Arguments:
  197. None
  198. Return Value:
  199. None
  200. --*/
  201. {
  202. SERVICE_TABLE_ENTRY dispatchTable[] = {
  203. { CLUSPW_SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain },
  204. { NULL, NULL }
  205. };
  206. DWORD status;
  207. DWORD logLevel = 0;
  208. status = ClRtlInitialize( FALSE, &logLevel );
  209. if ( status != ERROR_SUCCESS ) {
  210. DbgPrint("Couldn't initialize cluster RTL - %d\n", status );
  211. } else {
  212. ClRtlLogPrint(LOG_NOISE,
  213. "[CPW] Initiating cluster service account password update\n");
  214. }
  215. CL_LOGCLUSINFO( SERVICE_PASSWORD_CHANGE_INITIATED );
  216. //
  217. // this part runs on the cluster nodes; validate that we're really
  218. // running in the correct environment
  219. //
  220. #if 0
  221. byteCount = GetModuleFileName( NULL, cluspwFile, sizeof( cluspwFile ));
  222. if ( wcsstr( cluspwFile, L"admin$" ) == NULL ) {
  223. DbgPrint("-z is not a valid option\n");
  224. return ERROR_INVALID_PARAMETER;
  225. }
  226. #endif
  227. if ( !StartServiceCtrlDispatcher(dispatchTable)) {
  228. status = GetLastError();
  229. DbgPrint("StartServiceCtrlDispatcher failed - %1!d!\n", status);
  230. }
  231. } // ServiceMain
  232. /* end service.c */