43 #define SERVICENAME "RXAPI"
44 #define SERVICEDESCRIPTION "%s Service for Open Object Rexx version %d.%d.%d"
46 #define SYNTAX_HELP "Syntax: rxapi opt [/s]\n\n" \
47 "Where opt is exactly one of:\n" \
48 "/i :\tinstall as Service.\n" \
49 "/u :\tuninstall as Service.\n" \
50 "/v :\tshow Version number\n\n" \
51 "The /s (silent) is optional and prevents any messages from displaying."
53 #define APP_LOG_KEYNAME "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\"
64 static SERVICE_DESCRIPTION
Info;
73 TCHAR fileBuf[MAX_PATH];
74 static const char *fileName = NULL;
76 void __cdecl DebugMsg(
const char* pszFormat, ...)
81 sprintf(buf,
"[%s](%lu)(%lu){%d}: ",
SERVICENAME, GetCurrentThreadId(),GetCurrentProcessId(),
83 va_start(arglist, pszFormat);
84 vsprintf(&buf[strlen(buf)], pszFormat, arglist);
88 if ( fileName == NULL )
90 SHGetFolderPath(NULL, CSIDL_COMMON_DOCUMENTS | CSIDL_FLAG_CREATE, NULL, 0, fileBuf);
91 PathAppend(fileBuf,
"apiService.log");
95 stream = fopen(fileName,
"a+");
98 fwrite(buf, 1, strlen(buf), stream);
113 #define WINDOWS_95_98_ME VER_PLATFORM_WIN32_WINDOWS
117 OSVERSIONINFO version_info;
120 version_info.dwOSVersionInfoSize =
sizeof(version_info);
121 GetVersionEx(&version_info);
130 answer = version_info.dwMajorVersion >= 5;
226 case SERVICE_CONTROL_STOP:
231 case SERVICE_CONTROL_PAUSE:
235 case SERVICE_CONTROL_CONTINUE:
239 case SERVICE_CONTROL_INTERROGATE:
243 case SERVICE_CONTROL_SHUTDOWN:
266 m_Status.dwWin32ExitCode = GetLastError();
291 m_Status.dwCurrentState = SERVICE_START_PENDING;
332 SERVICE_TABLE_ENTRY st[] =
343 m_Status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
344 m_Status.dwCurrentState = SERVICE_STOPPED;
345 m_Status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
347 m_Status.dwServiceSpecificExitCode = 0;
351 return StartServiceCtrlDispatcher(st) != 0;
368 SERVICE_STATUS_PROCESS ssp;
369 DWORD startTicks = GetTickCount();
370 DWORD waitTime = timeOut / 20;
372 bool success =
false;
375 if ( ! QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp,
sizeof(SERVICE_STATUS_PROCESS), &needed) )
380 if ( ssp.dwCurrentState == SERVICE_STOPPED )
387 while ( ssp.dwCurrentState == SERVICE_STOP_PENDING )
390 if ( ! QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp,
sizeof(SERVICE_STATUS_PROCESS), &needed) )
395 if ( ssp.dwCurrentState == SERVICE_STOPPED )
401 if ( GetTickCount() - startTicks > timeOut )
409 if ( ! ControlService(hService, SERVICE_CONTROL_STOP, &ss) )
415 while ( ssp.dwCurrentState != SERVICE_STOPPED )
418 if ( ! QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp,
sizeof(SERVICE_STATUS_PROCESS), &needed) )
423 if ( ss.dwCurrentState == SERVICE_STOPPED )
429 if ( GetTickCount() - startTicks > timeOut )
442 SECURITY_DESCRIPTOR sd;
443 PSECURITY_DESCRIPTOR psd = NULL;
446 BOOL bDaclPresent = FALSE;
447 BOOL bDaclDefaulted = FALSE;
453 if ( ! QueryServiceObjectSecurity(hService, DACL_SECURITY_INFORMATION, &psd, 0, &needed) )
455 if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER )
458 psd = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, size);
464 if ( ! QueryServiceObjectSecurity( hService, DACL_SECURITY_INFORMATION, psd, size, &needed) )
476 if ( ! GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl, &bDaclDefaulted) )
482 BuildExplicitAccessWithName(&ea, TEXT(
"Users"), SERVICE_START | SERVICE_STOP | GENERIC_READ, SET_ACCESS, NO_INHERITANCE);
484 dwError = SetEntriesInAcl(1, (PEXPLICIT_ACCESS)&ea, pacl, &pNewAcl);
485 if ( dwError != ERROR_SUCCESS )
491 if ( ! InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION) )
497 if ( ! SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE) )
503 SetServiceObjectSecurity(hService, DACL_SECURITY_INFORMATION, &sd);
506 if( pNewAcl != NULL )
508 LocalFree((HLOCAL)pNewAcl);
512 LocalFree((LPVOID)psd);
524 char szFilePath[_MAX_PATH];
525 SC_HANDLE hService = NULL;
526 char szKey[_MAX_PATH];
529 bool success =
false;
532 SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE | SC_MANAGER_CONNECT);
542 GetModuleFileName(NULL, szKey,
sizeof(szKey));
543 if ( strstr(szKey,
" ") == 0 )
545 strcpy(szFilePath, szKey);
549 _snprintf(szFilePath,
sizeof(szFilePath),
"\"%s\"", szKey);
554 SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, szFilePath, NULL, NULL, NULL, NULL,
557 if ( hService == NULL )
573 Info.lpDescription = szKey;
575 ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &
Info);
587 if ( RegCreateKey(HKEY_LOCAL_MACHINE, szKey, &hKey) == ERROR_SUCCESS )
590 RegSetValueEx(hKey,
"EventMessageFile", 0, REG_EXPAND_SZ, (CONST BYTE*)szFilePath,
591 (DWORD)strlen(szFilePath) + 1);
594 dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE;
595 RegSetValueEx(hKey,
"TypesSupported", 0, REG_DWORD, (CONST BYTE*)&dwData,
sizeof(DWORD));
601 if ( hService != NULL )
603 CloseServiceHandle(hService);
607 CloseServiceHandle(hSCM);
620 bool success =
false;
623 SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
626 SC_HANDLE hService = OpenService(hSCM,
SERVICENAME, DELETE | SERVICE_QUERY_STATUS | SERVICE_STOP);
627 if ( hService != NULL )
636 if ( DeleteService(hService) )
640 CloseServiceHandle(hService);
642 CloseServiceHandle(hSCM);
651 if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE,
APP_LOG_KEYNAME, 0, DELETE, &hKey) == ERROR_SUCCESS )
653 if ( RegDeleteKey(hKey,
SERVICENAME) == ERROR_SUCCESS )
676 SERVICE_STATUS_PROCESS ssp;
679 BOOL success = QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp,
680 sizeof(SERVICE_STATUS_PROCESS), &needed);
684 if ( ssp.dwCurrentState == SERVICE_RUNNING || ssp.dwCurrentState == SERVICE_STOPPED ||
685 ssp.dwCurrentState == SERVICE_STOP_PENDING )
687 return ssp.dwCurrentState == SERVICE_RUNNING;
690 if ( ssp.dwCurrentState == SERVICE_START_PENDING )
693 uint32_t startTicks = GetTickCount();
694 uint32_t oldCheck = ssp.dwCheckPoint;
700 while ( ssp.dwCurrentState == SERVICE_START_PENDING )
708 waitTime = ssp.dwWaitHint / 10;
714 else if ( waitTime > 10000 )
721 BOOL success = QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp,
722 sizeof(SERVICE_STATUS_PROCESS), &needed);
723 if ( ! success || ssp.dwCurrentState == SERVICE_RUNNING )
728 if ( ssp.dwCheckPoint > oldCheck )
731 startTicks = GetTickCount();
732 oldCheck = ssp.dwCheckPoint;
736 if( (GetTickCount() - startTicks) > ssp.dwWaitHint )
745 return ssp.dwCurrentState == SERVICE_RUNNING;
763 SC_HANDLE hSCM = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
768 SC_HANDLE hService = OpenService(hSCM,
SERVICENAME, SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS);
775 LPQUERY_SERVICE_CONFIG pqsc = (LPQUERY_SERVICE_CONFIG)LocalAlloc(LPTR, 4096);
779 if ( QueryServiceConfig(hService, pqsc, 4096, &needed) )
781 if ( pqsc->dwStartType != SERVICE_DISABLED )
797 CloseServiceHandle(hService);
799 CloseServiceHandle(hSCM);
834 errRC = GetLastError();
835 if ( errRC == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT )
846 iRet = system(
"NET start rxapi");
880 size_t len = strlen(cmdLine);
882 if ( cmdLine[0] !=
'/' || len < 2 )
890 char opt = cmdLine[4];
891 if ( opt ==
's' || opt ==
'S' || opt ==
'q' || opt ==
'Q' )
899 switch ( cmdLine[1] )
903 sprintf(msg ,
"%s Version %d.%d.%d\n\nThe service is %s installed",
SERVICENAME,
904 ORX_VER, ORX_REL, ORX_MOD, isInstalled ?
"currently" :
"not");
914 sprintf(msg,
"%s is already installed as a service.",
SERVICENAME);
924 sprintf(msg,
"The %s service was installed\n",
SERVICENAME);
932 sprintf(msg,
"The %s service failed to install.\n"
946 sprintf(msg,
"%s is not installed as a service\n",
SERVICENAME);
956 sprintf(msg,
"%s was uninstalled as a service.\n\n"
957 "(Open Object REXX is not uninstalled.)",
SERVICENAME);
965 sprintf(msg,
"The %s service could not be uninstalled.\n"
1003 int APIENTRY
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int nCmdShow)
1008 if ( strlen(lpCmdLine) != 0 )
void listenForConnections()
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
static SERVICE_STATUS m_Status
bool startAsWindowsService(void)
BOOL OnUserControl(DWORD dwOpcode)
#define SERVICEDESCRIPTION
void setServiceDACL(SC_HANDLE hService)
static SERVICE_STATUS_HANDLE m_hServiceStatus
bool startTheService(void)
ServiceStateType getServiceState(void)
void SetStatus(DWORD dwState)
bool serviceIsRunning(SC_HANDLE hService)
static void WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
bool stopTheService(SC_HANDLE hService, DWORD timeOut)
static SERVICE_DESCRIPTION Info
void processCmdLine(const char *cmdLine)
static void __cdecl Handler(DWORD dwOpcode)
void showMessage(const char *msg, unsigned int icon)
bool isAtLeastVersion(WindowsVersionType type)