/*======================================================================================// | // |Copyright (c) 1998, 1999 Sequent Computer Systems, Incorporated // | // |Description: // | // |---------------------------------------------------------------------------------------// | This file contains the ProcCon NT service install and remove functions // |---------------------------------------------------------------------------------------// | // |Created: // | // | Jarl McDonald 07-98 // | // |Revision History: // | Jarl McDonald 19-08-99 change service start type to auto // | // |=======================================================================================*/ #include "ProcConSvc.h" //======================================================================================== // function to install the ProcCon service... no input or output // Note: installation also includes the EventLog entries necessary to // resolve our event log messages. // void PCInstallService(int argc, TCHAR **argv) { TCHAR path[MAX_PATH], err[512]; // Use security descriptor that allows admin access for our registry data. // Post-installation the access list may need to be tailored. SECURITY_ATTRIBUTES adminAttr; if ( !PCBuildAdminSecAttr( adminAttr ) ) { const VOID *args[] = { NULL, PROCCON_SVC_DISP_NAME }; PCLogErrStdout( PC_SERVICE_UNABLE_TO_INSTALL, GetLastError(), args ); return; } // Get our module name -- needed to install service and error log message file... if ( !GetModuleFileName( NULL, path, MAX_PATH ) ) { const VOID *args[] = { NULL, PROCCON_SVC_DISP_NAME }; PCLogErrStdout( PC_SERVICE_UNABLE_TO_INSTALL, GetLastError(), args ); return; } // Open SCM and install ourselves... SC_HANDLE hSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE ); PCULONG32 rc = GetLastError(); TCHAR *acct = NULL, *pswd = NULL; if ( argc > 0 ) acct = argv[0]; if ( argc > 1 ) pswd = argv[1]; if ( hSCManager ) { SC_HANDLE hService = CreateService( hSCManager, // SCManager database PROCCON_SVC_NAME, // name of service PROCCON_SVC_DISP_NAME, // name to display GENERIC_READ, // desired access SERVICE_WIN32_OWN_PROCESS, // service type SERVICE_AUTO_START, // start type -- auto by MS req. SERVICE_ERROR_NORMAL, // error control type path, // service's binary NULL, // no load ordering group NULL, // no tag identifier TEXT(""), // dependencies acct, // account or NULL pswd); // password or NULL // If installed, add related registry keys... rc = GetLastError(); if ( hService ) { PCLogStdout( PC_SERVICE_SERVICE_INSTALLED, PROCCON_SVC_DISP_NAME ); CloseServiceHandle(hService); HKEY hKey; PCULONG32 regDisp, types = 0x07; TCHAR key[512]; // Add registry key describing service... PCBuildBaseKey( key ); rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE, key, 0, KEY_READ + KEY_WRITE, &hKey ); if ( rc != ERROR_SUCCESS ) { const VOID *args[] = { NULL, PROCCON_SVC_DISP_NAME, key }; PCLogErrStdout( PC_SERVICE_REGISTRY_OPEN_FAILED, rc, args ); } else { rc = RegSetValueEx( hKey, PROCCON_SERVICE_DESCRIPTION_NAME, NULL, REG_SZ, (UCHAR *) PROCCON_SERVICE_DESCRIPTION, (_tcslen( PROCCON_SERVICE_DESCRIPTION ) + 1) * sizeof(TCHAR) ); if ( rc != ERROR_SUCCESS ) { const VOID *args[] = { NULL, PROCCON_SVC_DISP_NAME, PROCCON_SERVICE_DESCRIPTION_NAME }; PCLogErrStdout( PC_SERVICE_ADD_VALUE_SERVICE_DESC_FAILED, rc, args ); } RegCloseKey( hKey ); } // Add registry key describing server application... rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE, PROCCON_SERVER_APP_KEY, 0, KEY_SET_VALUE, &hKey ); if ( rc != ERROR_SUCCESS ) { const VOID *args[] = { NULL, PROCCON_SVC_DISP_NAME, PROCCON_SERVER_APP_KEY }; PCLogErrStdout( PC_SERVICE_APP_KEY_OPEN_FAILED, rc, args ); } else { rc = RegSetValueEx( hKey, PROCCON_SERVER_APP_VALUE_NAME, NULL, REG_SZ, (UCHAR *) PROCCON_SVC_DISP_NAME, (_tcslen( PROCCON_SVC_DISP_NAME ) + 1) * sizeof(TCHAR) ); if ( rc == ERROR_SUCCESS ) PCLogStdout( PC_SERVICE_APP_KEY_CREATED, PROCCON_SVC_DISP_NAME ); else { const VOID *args[] = { NULL, PROCCON_SVC_DISP_NAME, PROCCON_SERVER_APP_VALUE_NAME }; PCLogErrStdout( PC_SERVICE_APP_KEY_ADD_FAILED, rc, args ); } RegCloseKey( hKey ); } // Add registry key to support ProcCon event log messages... // NULL security attribute is used to cause inheritance of attributes. PCBuildMsgKey( key ); rc = RegCreateKeyEx( HKEY_LOCAL_MACHINE, key, 0, TEXT(""), 0, KEY_READ + KEY_WRITE, NULL, &hKey, ®Disp ); if ( rc != ERROR_SUCCESS ) { const VOID *args[] = { NULL, PROCCON_SVC_DISP_NAME, key }; PCLogErrStdout( PC_SERVICE_REG_KEY_CREATE_FAILED, rc, args ); } else { BOOL fname = TRUE; rc = RegSetValueEx( hKey, EVENT_MSG_FILE_NAME, NULL, REG_SZ, (UCHAR *) path, (_tcslen( path ) + 1) * sizeof(path[0]) ); if ( rc == ERROR_SUCCESS ) { fname = FALSE; rc = RegSetValueEx( hKey, EVENT_MSG_TYPES_SUPPORT, NULL, REG_DWORD, (UCHAR *) &types, sizeof( types ) ); } if ( rc != ERROR_SUCCESS ) { const VOID *args[] = { NULL, PROCCON_SVC_DISP_NAME, fname ? EVENT_MSG_FILE_NAME : EVENT_MSG_TYPES_SUPPORT }; PCLogErrStdout( PC_SERVICE_EVENTLOG_REG_SETUP_FAILED, rc, args ); } else { PCLogStdout( PC_SERVICE_EVENTLOG_REG_SETUP, PROCCON_SVC_DISP_NAME ); } RegCloseKey( hKey ); } // Add registry keys to support ProcCon... // Security attribute for the PARAMETERS key is local administrators only. // Security attribute for the access keys is local administrators only also. PCBuildParmKey( key ); rc = RegCreateKeyEx( HKEY_LOCAL_MACHINE, key, 0, TEXT(""), 0, KEY_READ + KEY_WRITE, &adminAttr, &hKey, ®Disp ); if ( rc != ERROR_SUCCESS ) { const VOID *args[] = { NULL, PROCCON_SVC_DISP_NAME, key }; PCLogErrStdout( PC_SERVICE_PARAM_KEY_CREATE_FAILED, rc, args ); } else { rc = RegSetValueEx( hKey, PROCCON_DATA_NAMERULES, NULL, REG_MULTI_SZ, (UCHAR *) TEXT("\0\0"), 2 * sizeof(TCHAR) ); if ( rc != ERROR_SUCCESS ) { const VOID *args[] = { NULL, PROCCON_SVC_DISP_NAME, PROCCON_DATA_NAMERULES }; PCLogErrStdout( PC_SERVICE_PARAM_DATA_UPDATE_FAILED, rc, args ); } else { HKEY hTemp; for ( int i = 0; i < ENTRY_COUNT( accessKeyList ); ++i ) { rc = RegCreateKeyEx( hKey, accessKeyList[i], 0, TEXT(""), 0, KEY_WRITE, &adminAttr, &hTemp, ®Disp ); if ( rc == ERROR_SUCCESS ) RegCloseKey( hTemp ); else { const VOID *args[] = { NULL, PROCCON_SVC_DISP_NAME, accessKeyList[i] }; PCLogErrStdout( PC_SERVICE_PARAM_DATA_UPDATE_FAILED, rc, args ); break; } } } if ( rc == ERROR_SUCCESS ) { PCLogStdout( PC_SERVICE_PARAM_DATA_CREATED, PROCCON_SVC_DISP_NAME ); } RegCloseKey( hKey ); } } else { const VOID *args[] = { NULL, PROCCON_SVC_DISP_NAME }; PCLogErrStdout( PC_SERVICE_CREATESERVICE_FAILED, rc, args ); } CloseServiceHandle(hSCManager); } else { PCLogErrStdout( PC_SERVICE_OPENSCMGR_FAILED, rc, NULL ); } PCFreeSecAttr( adminAttr ); } //============================================================================================= // function to remove (deinstall) the service... no input or output // void PCRemoveService(int argc, TCHAR **argv) { TCHAR err[512]; // Open SCM and service then proceed with stop and delete... SC_HANDLE hSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if ( hSCManager ) { SC_HANDLE hService = OpenService( hSCManager, PROCCON_SVC_NAME, SERVICE_ALL_ACCESS ); if ( hService ) { // try to stop the service... if ( ControlService( hService, SERVICE_CONTROL_STOP, &ssStatus ) ) { PCLogStdout( PC_SERVICE_STOPPING, PROCCON_SVC_DISP_NAME ); Sleep( 1000 ); while( QueryServiceStatus( hService, &ssStatus ) ) { if ( ssStatus.dwCurrentState == SERVICE_STOP_PENDING ) { PCLogStdout( PC_SERVICE_DOT ); Sleep( 1000 ); } else break; } if ( ssStatus.dwCurrentState == SERVICE_STOPPED ) { PCLogStdout( PC_SERVICE_STOPPING_STOPPED, PROCCON_SVC_DISP_NAME ); } else { PCLogStdout( PC_SERVICE_FAILED_TO_STOP, PROCCON_SVC_DISP_NAME ); } } // now remove the service... if( DeleteService( hService ) ) { PCLogStdout( PC_SERVICE_REG_ENTRIES_REMOVED, PROCCON_SVC_DISP_NAME ); } else { PCLogErrStdout( PC_SERVICE_DELETE_SVC_FAILED, GetLastError(), NULL ); } CloseServiceHandle( hService ); } else { PCLogErrStdout( PC_SERVICE_OPEN_SVC_FAILED, GetLastError(), NULL ); } CloseServiceHandle( hSCManager ); } else { PCLogErrStdout( PC_SERVICE_OPENSCMGR_FAILED, GetLastError(), NULL ); } HKEY hKey; TCHAR key[512]; // now remove server application registry keys... PCULONG32 rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE, PROCCON_SERVER_APP_KEY, 0, KEY_SET_VALUE, &hKey ); if ( rc == ERROR_SUCCESS ) { rc = RegDeleteValue( hKey, PROCCON_SERVER_APP_VALUE_NAME ); RegCloseKey( hKey ); } if ( rc == ERROR_SUCCESS ) { PCLogStdout( PC_SERVICE_APP_REG_ENTRY_DELETED, PROCCON_SVC_DISP_NAME ); } else if ( rc != ERROR_FILE_NOT_FOUND ) { const VOID *args[] = { NULL, PROCCON_SVC_DISP_NAME, PROCCON_SERVER_APP_VALUE_NAME }; PCLogErrStdout( PC_SERVICE_APP_REG_ENTRY_DEL_FAILED, rc, args ); } // now remove message registry keys... PCBuildMsgKey( key ); rc = RegDeleteKey( HKEY_LOCAL_MACHINE, key ); if ( rc == ERROR_SUCCESS || rc == ERROR_KEY_DELETED ) { PCLogStdout( PC_SERVICE_EVTLOG_REG_DELETED, PROCCON_SVC_DISP_NAME ); } else if ( rc != ERROR_FILE_NOT_FOUND ) { const VOID *args[] = { NULL, PROCCON_SVC_DISP_NAME, key }; PCLogErrStdout( PC_SERVICE_EVTLOG_REG_DEL_FAILED, rc, args ); } // now attempt removal of parameter registry keys... // (Delete of the service should have already deleted the Parameters sub-key) PCBuildParmKey( key ); rc = PCDeleteKeyTree( HKEY_LOCAL_MACHINE, key ); // PCDeleteKeyTree does not return ERROR_KEY_DELETED or ERROR_FILE_NOT_FOUND if ( rc != ERROR_SUCCESS ) { const VOID *args[] = { NULL, PROCCON_SVC_DISP_NAME, key }; PCLogErrStdout( PC_SERVICE_REG_TREE_DEL_FAILED, rc, args ); } } void PCWriteStdout( PTCHAR Buffer, DWORD BufferLen ) { DWORD Written; static BOOL ConsoleWorks = TRUE; static HANDLE StdOutHandle = INVALID_HANDLE_VALUE; if (StdOutHandle == INVALID_HANDLE_VALUE) { StdOutHandle = GetStdHandle(STD_OUTPUT_HANDLE); } if (ConsoleWorks) { ConsoleWorks = WriteConsole(StdOutHandle, Buffer, BufferLen, &Written, NULL); } if (! ConsoleWorks) { WriteFile(StdOutHandle, Buffer, BufferLen * sizeof(TCHAR), &Written, NULL); } } void CDECL PCLogStdout( const PCULONG32 msgCode, ... ) { va_list args; PTCHAR Buffer; DWORD BufferLen; va_start(args, msgCode); BufferLen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE, NULL, msgCode, 0, (LPWSTR) &Buffer, 1, &args); va_end(args); if (BufferLen) { PCWriteStdout(Buffer, BufferLen); LocalFree(Buffer); } } void PCLogErrStdout( const PCULONG32 msgCode, const PCULONG32 errCode, const VOID **args ) { PTCHAR Buffer; PTCHAR ErrBuffer; DWORD BufferLen; DWORD ErrBufferLen; ErrBufferLen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, 0, errCode, 0, (LPWSTR) &ErrBuffer, 1, NULL); if (ErrBufferLen) { if (args) { args[0] = ErrBuffer; } BufferLen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE | (args ? FORMAT_MESSAGE_ARGUMENT_ARRAY : 0), NULL, msgCode, 0, (LPWSTR) &Buffer, 1, (va_list *) (args ? (PVOID) args : (PVOID) ErrBuffer)); if (BufferLen) { PCWriteStdout(Buffer, BufferLen); LocalFree(Buffer); } LocalFree(ErrBuffer); } } // End of PCService.cpp //============================================================================J McDonald fecit====//