/** * @brief * PbsCommMain - getting used when pbs is running as a service in the server. * * @param[in] dwArgc - argument count. * @param[in] rgszArgv- argument values. * * @return void */ void WINAPI PbsCommMain(DWORD dwArgc, LPTSTR *rgszArgv) { DWORD dwTID; DWORD dwWait; SERVICE_STATUS ss; DWORD i; DWORD exitCode = 0; struct arg_param *pap; g_ssHandle = RegisterServiceCtrlHandler(g_PbsCommName, PbsCommHandler); if (g_ssHandle == 0) { ErrorMessage("RegisterServiceCtrlHandler"); } pap = create_arg_param(); if (pap == NULL) return; pap->argc = dwArgc; for (i=0; i < dwArgc; i++) { pap->argv[i] = strdup(rgszArgv[i]); } g_hthreadMain = (HANDLE) _beginthreadex(0, 0, main_thread, pap, 0, &dwTID); if (g_hthreadMain == 0) { (void)free_arg_param(pap); ErrorMessage("CreateThread"); } dwWait = WaitForSingleObject(g_hthreadMain, INFINITE); if (dwWait != WAIT_OBJECT_0) { (void)free_arg_param(pap); ErrorMessage("WaitForSingleObject"); } GetExitCodeThread(g_hthreadMain, &exitCode); // NOTE: Update the global service state variable to indicate // that the server has STOPPED. Use this to ACK the SCM // that the service has stopped using SetServiceStatus. ZeroMemory(&ss, sizeof(ss)); ss.dwServiceType = SERVICE_WIN32_OWN_PROCESS; ss.dwCurrentState = SERVICE_STOPPED; ss.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; if (exitCode == 0) ss.dwWin32ExitCode = 0; else if (exitCode == 1) ss.dwWin32ExitCode = ERROR_BAD_CONFIGURATION; else if (exitCode == 2) ss.dwWin32ExitCode = CO_E_LAUNCH_PERMSSION_DENIED; if (g_ssHandle != 0) SetServiceStatus(g_ssHandle, &ss); free_arg_param(pap); }
/** * @brief * PBS_INTERACTIVE service's main function. * * @param[in] dwArgc - number of agrument * @param[in] rgszArgv - pointer to argument * * @return * Nothing. (void) * */ void WINAPI pbsinteractiveMain(DWORD dwArgc, LPTSTR *rgszArgv) { DWORD dwTID; DWORD dwWait; DWORD i; SERVICE_STATUS SvcSts; struct arg_param *pap; /* Register service control handler for PBS_INTERACTIVE service*/ g_ssHandle = RegisterServiceCtrlHandler(g_PbsInteractiveName, pbsinteractiveHandler); if (g_ssHandle == 0) { ErrorMessage("RegisterServiceCtrlHandler"); return 1; } /* Check for argument */ if (dwArgc > 1) { /* Argumet found, create argument structure to pass given argument into main thread of PBS_INTERACTIVE service */ pap = create_arg_param(); if (pap == NULL) ErrorMessage("create_arg_param"); return 1; pap->argc = dwArgc; for (i=0; i < dwArgc; i++) { if ((pap->argv[i] = _strdup(rgszArgv[i])) == NULL) { free_arg_param(pap); ErrorMessage("strdup"); return 1; } } } else { /* Argument not found, pass NULL argument instead of argument structure into main thread of PBS_INTERACTIVE service */ pap = NULL; } /* Create and start execution of main thread of PBS_INTERACTIVE service */ pbsinteractiveThreadH = (HANDLE)_beginthreadex(0, 0, pbsinteractiveMainThread, pap, 0, &dwTID); if (pbsinteractiveThreadH == 0) { free_arg_param(pap); ErrorMessage("CreateThread"); return 1; } /* Wait to finish main thread of PBS_INTERACTIVE service for infinite time */ dwWait = WaitForSingleObject(pbsinteractiveThreadH, INFINITE); if (dwWait != WAIT_OBJECT_0) { free_arg_param(pap); ErrorMessage("WaitForSingleObject"); return 1; } /* Execution of main thread of PBS_INTERACTIVE service is finished, stop PBS_INTERACTIVE service */ free_arg_param(pap); ZeroMemory(&SvcSts, sizeof(SvcSts)); SvcSts.dwServiceType = SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS; SvcSts.dwCurrentState = SERVICE_STOPPED; SvcSts.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; if (g_ssHandle != 0) { SetServiceStatus(g_ssHandle, &SvcSts); } }
/** * @brief * main - the initialization and main loop of pbs_comm * * @param[in] argc - argument count. * @param[in] argv - argument values. * * @return int * @retval 0 - success */ main(int argc, char *argv[]) { SC_HANDLE schManager; SC_HANDLE schSelf; int reg = 0; int unreg = 0; TCHAR szFileName[MAX_PATH]; /*the real deal or just pbs_version and exit*/ execution_mode(argc, argv); if (argc > 1) { if (strcmp(argv[1], "-R") == 0) reg = 1; else if (strcmp(argv[1], "-U") == 0) unreg = 1; else if (strcmp(argv[1], "-N") == 0) stalone = 1; } if (reg || unreg) { schManager = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS); if (schManager == 0) { ErrorMessage("OpenSCManager"); } if (reg) { GetModuleFileName(0, szFileName, sizeof(szFileName)/sizeof(*szFileName)); printf("Installing service %s\n", g_PbsCommName); schSelf = CreateService(schManager, g_PbsCommName, __TEXT("PBS COMM"), SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, replace_space(szFileName, ""), 0, 0, 0, 0, 0); if (schSelf) { printf("Service %s installed succesfully!\n", g_PbsCommName); } else { ErrorMessage("CreateService"); } if (schSelf != 0) CloseServiceHandle(schSelf); } else if (unreg) { schSelf = OpenService(schManager, g_PbsCommName, DELETE); if (schSelf) { if (DeleteService(schSelf)) { printf("Service %s uninstalled successfully!\n", g_PbsCommName); } else { ErrorMessage("DeleteService"); } } else { ErrorMessage("OpenService failed"); } if (schSelf != 0) CloseServiceHandle(schSelf); } if (schManager != 0) CloseServiceHandle(schManager); } else if (stalone) { struct arg_param *pap; int i, j; pap = create_arg_param(); if (pap == NULL) ErrorMessage("create_arg_param"); pap->argc = argc-1; /* don't pass the second argument */ for (i=j=0; i < argc; i++) { if (i == 1) continue; pap->argv[j] = strdup(argv[i]); j++; } main_thread((void *)pap); free_arg_param(pap); } else { /* running as a service */ SERVICE_TABLE_ENTRY rgste[] = { {(TCHAR*)g_PbsCommName, PbsCommMain }, { 0, 0 } }; if (getenv("PBS_CONF_FILE") == NULL) { char conf_path[80]; char *p; char psave; struct stat sbuf; if (p = strstr(argv[0], "exec")) { psave = *p; *p = '\0'; _snprintf(conf_path, 79, "%spbs.conf", argv[0]); *p = psave; if (stat(conf_path, &sbuf) == 0) { setenv("PBS_CONF_FILE", conf_path, 1); } } } if (!StartServiceCtrlDispatcher(rgste)) { ErrorMessage("StartServiceCntrlDispatcher"); } } return (0); }