| | |
| | | } |
| | | |
| | | debug("registerServiceHandler returning '%d'", returnValue); |
| | | |
| | | |
| | | return returnValue; |
| | | } // registerServiceHandler |
| | | |
| | |
| | | ); |
| | | if (scm == NULL) |
| | | { |
| | | debugError("Failed to open the Service Control Manager. Last error = %d", GetLastError()); |
| | | debugError("Failed to open the Service Control Manager. Last error = %d", |
| | | GetLastError()); |
| | | returnValue = SERVICE_RETURN_ERROR; |
| | | } |
| | | else |
| | |
| | | ); |
| | | if (result != ERROR_SUCCESS) |
| | | { |
| | | debugError("RegSetValueEx('EventMessageFile') failed, result=%d.", result); |
| | | debugError("RegSetValueEx('EventMessageFile') failed, result=%d.", |
| | | result); |
| | | success = FALSE; |
| | | } |
| | | } |
| | |
| | | ); |
| | | if (result != ERROR_SUCCESS) |
| | | { |
| | | debugError("RegSetValueEx('CategoryMessageFile') failed, result=%d.", result); |
| | | debugError("RegSetValueEx('CategoryMessageFile') failed, result=%d.", |
| | | result); |
| | | success = FALSE; |
| | | } |
| | | } |
| | |
| | | ); |
| | | if (result != ERROR_SUCCESS) |
| | | { |
| | | debug("The registry key for service '%s' does not exist, so we do not need to remove it.", serviceName); |
| | | debug("The registry key for service '%s' does not exist, so we do not need to remove it.", |
| | | serviceName); |
| | | // Assume that the registry key does not exist. |
| | | returnValue = TRUE; |
| | | } |
| | |
| | | char* relativePath = "\\locks\\server.lock"; |
| | | char lockFile[MAX_PATH]; |
| | | debug("Determining if the server is running."); |
| | | |
| | | |
| | | if (strlen(relativePath)+strlen(_instanceDir)+1 < MAX_PATH) |
| | | { |
| | | int fd; |
| | | |
| | | sprintf(lockFile, "%s%s", _instanceDir, relativePath); |
| | | debug("When determining whether the server is running, the lock file name is '%s'.", lockFile); |
| | | |
| | | debug("When determining whether the server is running, the lock file name is '%s'.", |
| | | lockFile); |
| | | |
| | | fd = _open(lockFile, _O_RDWR); |
| | | |
| | | if (fd != -1) |
| | |
| | | } |
| | | else |
| | | { |
| | | debug("Could not open lock file '%s', which means the server is not running.", lockFile); |
| | | debug("Could not open lock file '%s', which means the server is not running.", |
| | | lockFile); |
| | | *running = FALSE; |
| | | returnValue = SERVICE_RETURN_ERROR; |
| | | } |
| | |
| | | |
| | | debug("doStartApplication called."); |
| | | |
| | | |
| | | |
| | | if (strlen(relativePath)+strlen(_instanceDir)+1 < COMMAND_SIZE) |
| | | { |
| | | sprintf(command, "\"%s%s\" --windowsNetStart", _instanceDir, relativePath); |
| | |
| | | // Try to see if server is really running |
| | | int nTries = 10; |
| | | BOOL running = FALSE; |
| | | |
| | | debug("doStartApplication: the spawn of the process worked. Command: '%s'", command); |
| | | |
| | | debug( |
| | | "doStartApplication: the spawn of the process worked. Command: '%s'", |
| | | command); |
| | | // Wait to be able to launch the java process in order it to free the lock |
| | | // on the file. |
| | | debug("Sleeping for 3 seconds to allow the process to free the lock."); |
| | |
| | | } |
| | | if (!running) |
| | | { |
| | | debug("Sleeping for 2 seconds to allow the process to free the lock. %d tries remaining.", nTries); |
| | | debug("Sleeping for 2 seconds to allow the process to free the lock. %d tries remaining.", |
| | | nTries); |
| | | Sleep(2000); |
| | | } |
| | | } |
| | |
| | | } |
| | | else |
| | | { |
| | | |
| | | |
| | | returnValue = SERVICE_RETURN_ERROR; |
| | | debug("doStartApplication: spawn failed. Sent command: '%s'", command); |
| | | } |
| | |
| | | // Try to see if server is really stopped |
| | | int nTries = 10; |
| | | BOOL running = TRUE; |
| | | |
| | | |
| | | debug("doStopApplication: the spawn of the process worked."); |
| | | |
| | | |
| | | // Wait to be able to launch the java process in order it to free the lock |
| | | // on the file. |
| | | Sleep(3000); |
| | |
| | | // serviceBinPath the path to the service binary. |
| | | // instanceDir the instanceDirectory. |
| | | // The string stored in serviceBinPath looks like |
| | | // <SERVER_ROOT>/lib/service.exe start <_instanceDir> |
| | | // <SERVER_ROOT>/lib/opends_service.exe start <_instanceDir> |
| | | // It is up to the caller of the function to allocate |
| | | // at least COMMAND_SIZE bytes in serviceBinPath. |
| | | // The function returns SERVICE_RETURN_OK if we could create the binary |
| | |
| | | } |
| | | else |
| | | { |
| | | debug("When determining the service bin path, the module file name is '%s'.", fileName); |
| | | debug( |
| | | "When determining the service bin path, the module file name is '%s'.", |
| | | fileName); |
| | | |
| | | if (result == MAX_PATH) |
| | | { |
| | |
| | | } |
| | | else |
| | | { |
| | | if ((strlen(fileName) + strlen(" start ") + strlen(_instanceDir) + 2 * strlen("\"\"")) |
| | | < COMMAND_SIZE) |
| | | if ((strlen(fileName) + strlen(" start ") + strlen(_instanceDir) + |
| | | 2 * strlen("\"\"")) < COMMAND_SIZE) |
| | | { |
| | | sprintf(serviceBinPath, "\"%s\" start \"%s\"", fileName, |
| | | _instanceDir); |
| | | } |
| | | else |
| | | { |
| | | char * msg = "The name of the resulting windows service command is too long.\n"; |
| | | char * msg = |
| | | "The name of the resulting windows service command is too long.\n"; |
| | | debug(msg); |
| | | // buffer was too small, executable name is probably not valid |
| | | returnValue = SERVICE_RETURN_ERROR; |
| | |
| | | |
| | | strcpy(serviceName, ""); |
| | | |
| | | debug("Attempting to get the service name assuming command to run is '%s'.", cmdToRun); |
| | | debug("Attempting to get the service name assuming command to run is '%s'.", |
| | | cmdToRun); |
| | | |
| | | returnValue = getServiceList(&serviceList, &nbServices); |
| | | |
| | |
| | | } |
| | | else |
| | | { |
| | | debug("The service name found is too long: '%s'", curService.serviceName); |
| | | debug("The service name found is too long: '%s'", |
| | | curService.serviceName); |
| | | } |
| | | break; |
| | | } |
| | |
| | | } |
| | | |
| | | debug("The service name was found to be '%s'.", serviceName); |
| | | |
| | | |
| | | return returnValue; |
| | | |
| | | } // getServiceName |
| | |
| | | debug("Updating the service status. statusToSet=%d win32ExitCode=%d serviceExitCode=%d checkPoint=%d waitHint=%d", |
| | | statusToSet, win32ExitCode, serviceExitCode, |
| | | checkPoint, waitHint); |
| | | |
| | | |
| | | if (statusToSet == SERVICE_START_PENDING) |
| | | { |
| | | debug("Service start pending."); |
| | |
| | | |
| | | if (!success) |
| | | { |
| | | debugError("Failed to set the service status. Last error = %d.", GetLastError()); |
| | | debugError("Failed to set the service status. Last error = %d.", |
| | | GetLastError()); |
| | | returnValue = SERVICE_RETURN_ERROR; |
| | | } |
| | | else |
| | |
| | | // __debugbreak(); |
| | | |
| | | debug("serviceMain called."); |
| | | |
| | | |
| | | code = createServiceBinPath(cmdToRun); |
| | | |
| | | if (code == SERVICE_RETURN_OK) |
| | |
| | | // |
| | | // scm is the SCM handler (must not be NULL) |
| | | // serviceName the name of the service. |
| | | // It is up to the caller of the function to allocate at least COMMAND_SIZE bytes |
| | | // in binPathName. |
| | | // It is up to the caller of the function to allocate at least COMMAND_SIZE |
| | | // bytes in binPathName. |
| | | // The function returns SERVICE_RETURN_OK if we could create the binary |
| | | // path name and SERVICE_RETURN_ERROR otherwise. |
| | | // --------------------------------------------------------------- |
| | |
| | | } |
| | | else |
| | | { |
| | | debug("getBinaryPath: error calling QueryServiceConfig. Code [%d]", errCode); |
| | | debug("getBinaryPath: error calling QueryServiceConfig. Code [%d]", |
| | | errCode); |
| | | break; |
| | | } |
| | | } |
| | |
| | | } |
| | | else |
| | | { |
| | | debug("getBinaryPath: the length of the binary path name is too big. serviceName='%s', binaryPath='%s'", serviceName, serviceConfig->lpBinaryPathName); |
| | | debug("getBinaryPath: the length of the binary path name is too big. serviceName='%s', binaryPath='%s'", |
| | | serviceName, serviceConfig->lpBinaryPathName); |
| | | } |
| | | } |
| | | } |
| | |
| | | if (lastError != ERROR_MORE_DATA) |
| | | { |
| | | returnValue = SERVICE_RETURN_ERROR; |
| | | debug("getServiceList: second try generic error. Code [%d]", lastError); |
| | | debug("getServiceList: second try generic error. Code [%d]", |
| | | lastError); |
| | | } |
| | | else |
| | | { |
| | |
| | | } |
| | | else |
| | | { |
| | | debug("Error getting binary path name of service: %s", l[i].serviceName); |
| | | debug("Error getting binary path name of service: %s", |
| | | l[i].serviceName); |
| | | } |
| | | curService++; |
| | | } |
| | |
| | | int i; |
| | | |
| | | debug("Determining if service name '%s' is in use.", serviceName); |
| | | |
| | | |
| | | // go through the list of services and search for the service name |
| | | if (getServiceList(&serviceList, &nbServices) == SERVICE_RETURN_OK) |
| | | { |
| | |
| | | } |
| | | else |
| | | { |
| | | debugError("Could not determine if the service name '%s' is in use because listing the services failed.", serviceName); |
| | | debugError("Could not determine if the service name '%s' is in use because listing the services failed.", |
| | | serviceName); |
| | | returnValue = SERVICE_RETURN_ERROR; |
| | | } |
| | | return returnValue; |
| | |
| | | } |
| | | |
| | | debug("createServiceName returning serviceName='%s' and returnValue=%d", |
| | | serviceName, returnValue); |
| | | serviceName, returnValue); |
| | | |
| | | return returnValue; |
| | | } // createServiceName |
| | |
| | | // create the service |
| | | if (returnValue == SERVICE_RETURN_OK) |
| | | { |
| | | if (openScm(GENERIC_WRITE, &scm) != SERVICE_RETURN_OK) |
| | | if (openScm(SC_MANAGER_ALL_ACCESS, &scm) != SERVICE_RETURN_OK) |
| | | { |
| | | returnValue = SERVICE_RETURN_ERROR; |
| | | debug("createServiceInScm: openScm did not work."); |
| | |
| | | if ((returnValue == SERVICE_RETURN_OK) && (myService == NULL)) |
| | | { |
| | | DWORD errCode = GetLastError(); |
| | | debugError("Failed to create the service '%s'. Last error = %d.", serviceName, errCode); |
| | | debugError("Failed to create the service '%s'. Last error = %d.", |
| | | serviceName, errCode); |
| | | if (errCode == ERROR_DUPLICATE_SERVICE_NAME) |
| | | { |
| | | returnValue = DUPLICATED_SERVICE_NAME; |
| | |
| | | } |
| | | else |
| | | { |
| | | if (errCode == ERROR_INVALID_HANDLE) |
| | | { |
| | | debugError("The handle seems to be invalid."); |
| | | } |
| | | returnValue = SERVICE_RETURN_ERROR; |
| | | } |
| | | } |
| | |
| | | |
| | | if (!success) |
| | | { |
| | | debugError("Failed to add a description to the service '%s'. Last error = %d.", serviceName, GetLastError()); |
| | | debugError( |
| | | "Failed to add a description to the service '%s'. Last error = %d.", |
| | | serviceName, GetLastError()); |
| | | returnValue = SERVICE_RETURN_ERROR; |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | debug("createServiceInScm returning %d.", returnValue); |
| | | |
| | | |
| | | return returnValue; |
| | | } // createServiceInScm |
| | | |
| | |
| | | SERVICE_STATUS serviceStatus; |
| | | |
| | | debug("Removing service '%s' from the Service Control Manager.", serviceName); |
| | | |
| | | |
| | | returnValue = openScm(GENERIC_WRITE, &scm); |
| | | |
| | | // open the service |
| | |
| | | debug("After opening service myService=%d.", myService); |
| | | if (myService == NULL) |
| | | { |
| | | debugError("Failed to open the service '%s'. Last error = %d", serviceName, GetLastError()); |
| | | debugError("Failed to open the service '%s'. Last error = %d", |
| | | serviceName, GetLastError()); |
| | | returnValue = SERVICE_RETURN_ERROR; |
| | | } |
| | | } |
| | |
| | | ); |
| | | if (!success) |
| | | { |
| | | debugError("Failed to query the status for service '%s'. Last error = %d", serviceName, GetLastError()); |
| | | debugError("Failed to query the status for service '%s'. Last error = %d", |
| | | serviceName, GetLastError()); |
| | | returnValue = SERVICE_RETURN_ERROR; |
| | | } |
| | | } |
| | |
| | | if (!success) |
| | | { |
| | | DWORD errCode = GetLastError(); |
| | | debugError("Failed to stop the service '%s'. Last error = %d.", serviceName, errCode); |
| | | debugError("Failed to stop the service '%s'. Last error = %d.", |
| | | serviceName, errCode); |
| | | if (errCode == ERROR_SERVICE_MARKED_FOR_DELETE) |
| | | { |
| | | returnValue = SERVICE_MARKED_FOR_DELETION; |
| | |
| | | if (!success) |
| | | { |
| | | DWORD errCode = GetLastError(); |
| | | debugError("Failed to delete the service '%s'. Last error = %d.", serviceName, errCode); |
| | | debugError("Failed to delete the service '%s'. Last error = %d.", |
| | | serviceName, errCode); |
| | | if (errCode == ERROR_SERVICE_MARKED_FOR_DELETE) |
| | | { |
| | | returnValue = SERVICE_MARKED_FOR_DELETION; |
| | |
| | | char cmdToRun[COMMAND_SIZE]; |
| | | ServiceReturnCode code; |
| | | |
| | | debug("Creating service displayName='%s' description='%s'.", displayName, description); |
| | | debug("Creating service displayName='%s' description='%s'.", displayName, |
| | | description); |
| | | code = createServiceBinPath(cmdToRun); |
| | | |
| | | if (code == SERVICE_RETURN_OK) |
| | |
| | | strcpy(serviceName, ""); |
| | | debug("Getting service state."); |
| | | code = createServiceBinPath(cmdToRun); |
| | | debug("Created the service bin path. code=%d. cmdToRun='%s'.", code, cmdToRun); |
| | | debug("Created the service bin path. code=%d. cmdToRun='%s'.", code, |
| | | cmdToRun); |
| | | |
| | | if (code == SERVICE_RETURN_OK) |
| | | { |
| | | code = getServiceName(cmdToRun, serviceName); |
| | | |
| | | |
| | | if (code == SERVICE_RETURN_OK) |
| | | { |
| | | // There is a valid serviceName for the command to run, so |
| | |
| | | else |
| | | { |
| | | returnCode = 1; |
| | | debug("Service '%s' is disabled enabled.", serviceName); |
| | | debug("Service '%s' is disabled.", serviceName); |
| | | } |
| | | } |
| | | else |
| | |
| | | char* subcommand; |
| | | int returnCode = 0; |
| | | int i; |
| | | |
| | | |
| | | updateDebugFlag(argv, argc); |
| | | |
| | | debug("main called."); |
| | |
| | | } |
| | | |
| | | debug("main returning %d.", returnCode); |
| | | |
| | | |
| | | return returnCode; |
| | | } // main |
| | | |