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

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
service.c
Abstract:
part of app that runs as an NT service.
Author:
Charlie Wickham (charlwi) 03-Oct-1999
Revision History:
--*/
#define UNICODE 1
#define _UNICODE 1
#define LOG_CURRENT_MODULE LOG_MODULE_CLUSPW
#include <windows.h>
#include <winsvc.h>
#include <stdio.h>
#include "clusrtl.h"
#include "cluspw.h"
/* External */
/* Static */
SERVICE_STATUS ServiceStatus = {
SERVICE_WIN32_OWN_PROCESS, // dwServiceType
SERVICE_RUNNING, // dwCurrentState
0, // dwControlsAccepted
ERROR_SUCCESS, // dwWin32ExitCode
ERROR_SUCCESS, // dwServiceSpecificExitCode
1, // dwCheckPoint
30000 // dwWaitHint - 30 seconds
};
/* Forward */
/* End Forward */
VOID
DbgPrint(
PCHAR FormatString,
...
)
/*++
Routine Description:
Description
Arguments:
None
Return Value:
None
--*/
{
CHAR szOutBuffer[1024];
va_list argList;
va_start( argList, FormatString );
FormatMessageA(FORMAT_MESSAGE_FROM_STRING,
FormatString,
0,
0,
szOutBuffer,
sizeof(szOutBuffer) / sizeof(szOutBuffer[0]),
&argList);
va_end( argList );
OutputDebugStringA( szOutBuffer );
}
VOID WINAPI
ControlHandler(
DWORD fdwControl // requested control code
)
/*++
Routine Description:
Description
Arguments:
None
Return Value:
None
--*/
{
DbgPrint("Received service control %1!08X!\n", fdwControl);
return;
}
VOID WINAPI
ServiceMain(
DWORD argc,
LPTSTR argv[]
)
{
PIPE_RESULT_MSG resultMsg;
DWORD nodeNameSize = sizeof( NodeName );
BOOL success;
DWORD bytesWritten;
WCHAR cluspwFile[ MAX_PATH ];
DWORD byteCount;
DWORD status;
SERVICE_STATUS_HANDLE statusHandle;
//
// Initialize service to receive service requests by registering the
// control handler.
//
statusHandle = RegisterServiceCtrlHandler( CLUSPW_SERVICE_NAME, ControlHandler );
if ( statusHandle == NULL ) {
status = GetLastError();
DbgPrint("can't get service status handle - %1!u!\n", status);
return;
}
SetServiceStatus(statusHandle, &ServiceStatus);
//
// parse the args used to start the service
//
status = ParseArgs( argc, argv );
if ( status != ERROR_SUCCESS ) {
DbgPrint("ParseArgs failed - %1!d!\n", status);
goto cleanup;
}
//
// get the node name to stuff in each result msg
//
#if (_WIN32_WINNT > 0x04FF)
success = GetComputerNameEx(ComputerNamePhysicalNetBIOS,
NodeName,
&nodeNameSize);
#else
success = GetComputerName( NodeName, &nodeNameSize );
#endif
if ( !success ) {
status = GetLastError();
DbgPrint("GetComputerName failed - %1!d!\n", status );
status = ERROR_SUCCESS;
}
DbgPrint( "Opening pipe %1!ws!\n", ResultPipeName );
//
// open the named pipe on which to write msgs and final result
//
success = WaitNamedPipe( ResultPipeName, NMPWAIT_WAIT_FOREVER );
if ( success ) {
PipeHandle = CreateFile(ResultPipeName,
GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if ( PipeHandle == INVALID_HANDLE_VALUE ) {
status = GetLastError();
DbgPrint("CreateFile on result pipe failed - %1!d!\n", status );
}
}
else {
status = GetLastError();
DbgPrint("WaitNamedPipe on result pipe failed - %1!d!\n", status );
goto cleanup;
}
//
// update the password cache
//
wcscpy( resultMsg.NodeName, NodeName );
resultMsg.MsgType = MsgTypeFinalStatus;
resultMsg.Status = ChangeCachedPassword(UserName,
DomainName,
NewPassword);
if ( resultMsg.Status == ERROR_SUCCESS ) {
ClRtlLogPrint(LOG_NOISE,
"[CPW] Cluster service account password successfully updated.\n");
CL_LOGCLUSINFO( SERVICE_PASSWORD_CHANGE_SUCCESS );
} else {
ClRtlLogPrint(LOG_CRITICAL,
"[CPW] Cluster service account password update failed - %u.\n",
status);
ClusterLogEvent0(LOG_CRITICAL,
LOG_CURRENT_MODULE,
__FILE__,
__LINE__,
SERVICE_PASSWORD_CHANGE_FAILED,
sizeof( resultMsg.Status ),
(PVOID)&resultMsg.Status);
}
DbgPrint("Final Result: %1!d!\n", resultMsg.Status );
success = WriteFile(PipeHandle,
&resultMsg,
sizeof( resultMsg ),
&bytesWritten,
NULL);
if ( !success ) {
DbgPrint("WriteFile failed in wmain - %1!d!\n", GetLastError() );
DbgPrint("final status: %1!d!\n", resultMsg.Status);
}
CloseHandle( PipeHandle );
//
// let SCM know we're shutting down
//
cleanup:
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = status;
SetServiceStatus(statusHandle, &ServiceStatus);
} // ServiceMain
VOID
ServiceStartup(
VOID
)
/*++
Routine Description:
Description
Arguments:
None
Return Value:
None
--*/
{
SERVICE_TABLE_ENTRY dispatchTable[] = {
{ CLUSPW_SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain },
{ NULL, NULL }
};
DWORD status;
DWORD logLevel = 0;
status = ClRtlInitialize( FALSE, &logLevel );
if ( status != ERROR_SUCCESS ) {
DbgPrint("Couldn't initialize cluster RTL - %d\n", status );
} else {
ClRtlLogPrint(LOG_NOISE,
"[CPW] Initiating cluster service account password update\n");
}
CL_LOGCLUSINFO( SERVICE_PASSWORD_CHANGE_INITIATED );
//
// this part runs on the cluster nodes; validate that we're really
// running in the correct environment
//
#if 0
byteCount = GetModuleFileName( NULL, cluspwFile, sizeof( cluspwFile ));
if ( wcsstr( cluspwFile, L"admin$" ) == NULL ) {
DbgPrint("-z is not a valid option\n");
return ERROR_INVALID_PARAMETER;
}
#endif
if ( !StartServiceCtrlDispatcher(dispatchTable)) {
status = GetLastError();
DbgPrint("StartServiceCtrlDispatcher failed - %1!d!\n", status);
}
} // ServiceMain
/* end service.c */