static enum { NSSM_EXIT_RESTART, NSSM_EXIT_IGNORE, NSSM_EXIT_REALLY, NSSM_EXIT_UNCLEAN } exit_actions;\r
static const char *exit_action_strings[] = { "Restart", "Ignore", "Exit", "Suicide", 0 };\r
\r
static enum { NSSM_EXIT_RESTART, NSSM_EXIT_IGNORE, NSSM_EXIT_REALLY, NSSM_EXIT_UNCLEAN } exit_actions;\r
static const char *exit_action_strings[] = { "Restart", "Ignore", "Exit", "Suicide", 0 };\r
\r
/* Initialise status */\r
ZeroMemory(&service_status, sizeof(service_status));\r
service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS;\r
/* Initialise status */\r
ZeroMemory(&service_status, sizeof(service_status));\r
service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS;\r
- throttle_timer = CreateWaitableTimer(0, 1, 0);\r
- if (! throttle_timer) {\r
- log_event(EVENTLOG_WARNING_TYPE, NSSM_EVENT_CREATEWAITABLETIMER_FAILED, service_name, error_string(GetLastError()), 0);\r
+ if (use_critical_section) InitializeCriticalSection(&throttle_section);\r
+ else {\r
+ throttle_timer = CreateWaitableTimer(0, 1, 0);\r
+ if (! throttle_timer) {\r
+ log_event(EVENTLOG_WARNING_TYPE, NSSM_EVENT_CREATEWAITABLETIMER_FAILED, service_name, error_string(GetLastError()), 0);\r
+ }\r
}\r
log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_STARTED_SERVICE, exe, flags, service_name, dir, 0);\r
\r
}\r
log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_STARTED_SERVICE, exe, flags, service_name, dir, 0);\r
\r
if (! RegisterWaitForSingleObject(&wait_handle, process_handle, end_service, (void *) pid, INFINITE, WT_EXECUTEONLYONCE | WT_EXECUTELONGFUNCTION)) {\r
log_event(EVENTLOG_WARNING_TYPE, NSSM_EVENT_REGISTERWAITFORSINGLEOBJECT_FAILED, service_name, exe, error_string(GetLastError()), 0);\r
}\r
if (! RegisterWaitForSingleObject(&wait_handle, process_handle, end_service, (void *) pid, INFINITE, WT_EXECUTEONLYONCE | WT_EXECUTELONGFUNCTION)) {\r
log_event(EVENTLOG_WARNING_TYPE, NSSM_EVENT_REGISTERWAITFORSINGLEOBJECT_FAILED, service_name, exe, error_string(GetLastError()), 0);\r
}\r
/* "0x" + 8 x hex + NULL */\r
text = (char *) HeapAlloc(GetProcessHeap(), 0, 11);\r
if (! text) {\r
/* "0x" + 8 x hex + NULL */\r
text = (char *) HeapAlloc(GetProcessHeap(), 0, 11);\r
if (! text) {\r
- log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OUT_OF_MEMORY, "control code", "log_service_control", 0);\r
+ log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OUT_OF_MEMORY, "control code", "log_service_control()", 0);\r
return;\r
}\r
if (_snprintf_s(text, 11, _TRUNCATE, "0x%08x", control) < 0) {\r
return;\r
}\r
if (_snprintf_s(text, 11, _TRUNCATE, "0x%08x", control) < 0) {\r
- log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OUT_OF_MEMORY, "control code", "log_service_control", 0);\r
+ log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OUT_OF_MEMORY, "control code", "log_service_control()", 0);\r
\r
case SERVICE_CONTROL_CONTINUE:\r
log_service_control(service_name, control, true);\r
\r
case SERVICE_CONTROL_CONTINUE:\r
log_service_control(service_name, control, true);\r
- ZeroMemory(&throttle_duetime, sizeof(throttle_duetime));\r
- SetWaitableTimer(throttle_timer, &throttle_duetime, 0, 0, 0, 0);\r
+ if (use_critical_section) imports.WakeConditionVariable(&throttle_condition);\r
+ else {\r
+ if (! throttle_timer) return ERROR_CALL_NOT_IMPLEMENTED;\r
+ ZeroMemory(&throttle_duetime, sizeof(throttle_duetime));\r
+ SetWaitableTimer(throttle_timer, &throttle_duetime, 0, 0, 0, 0);\r
+ }\r
service_status.dwCurrentState = SERVICE_CONTINUE_PENDING;\r
service_status.dwWaitHint = throttle_milliseconds() + NSSM_WAITHINT_MARGIN;\r
log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_RESET_THROTTLE, service_name, 0);\r
service_status.dwCurrentState = SERVICE_CONTINUE_PENDING;\r
service_status.dwWaitHint = throttle_milliseconds() + NSSM_WAITHINT_MARGIN;\r
log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_RESET_THROTTLE, service_name, 0);\r
- _snprintf_s(code, sizeof(code), _TRUNCATE, "%d", exitcode);\r
+ _snprintf_s(code, sizeof(code), _TRUNCATE, "%lu", exitcode);\r
log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_ENDED_SERVICE, exe, service_name, code, 0);\r
}\r
\r
/* Clean up. */\r
log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_ENDED_SERVICE, exe, service_name, code, 0);\r
}\r
\r
/* Clean up. */\r
kill_process_tree(service_name, stop_method, pid, exitcode, pid, &creation_time, &exit_time);\r
\r
/*\r
kill_process_tree(service_name, stop_method, pid, exitcode, pid, &creation_time, &exit_time);\r
\r
/*\r
/* Fake a crash so pre-Vista service managers will run recovery actions. */\r
case NSSM_EXIT_UNCLEAN:\r
log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_EXIT_UNCLEAN, service_name, code, exit_action_strings[action], 0);\r
/* Fake a crash so pre-Vista service managers will run recovery actions. */\r
case NSSM_EXIT_UNCLEAN:\r
log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_EXIT_UNCLEAN, service_name, code, exit_action_strings[action], 0);\r
if (throttle > 7) throttle = 8;\r
\r
char threshold[8], milliseconds[8];\r
if (throttle > 7) throttle = 8;\r
\r
char threshold[8], milliseconds[8];\r
- _snprintf_s(threshold, sizeof(threshold), _TRUNCATE, "%d", throttle_delay);\r
- _snprintf_s(milliseconds, sizeof(milliseconds), _TRUNCATE, "%d", ms);\r
+ _snprintf_s(threshold, sizeof(threshold), _TRUNCATE, "%lu", throttle_delay);\r
+ _snprintf_s(milliseconds, sizeof(milliseconds), _TRUNCATE, "%lu", ms);\r
log_event(EVENTLOG_WARNING_TYPE, NSSM_EVENT_THROTTLED, service_name, threshold, milliseconds, 0);\r
\r
log_event(EVENTLOG_WARNING_TYPE, NSSM_EVENT_THROTTLED, service_name, threshold, milliseconds, 0);\r
\r
ZeroMemory(&throttle_duetime, sizeof(throttle_duetime));\r
throttle_duetime.QuadPart = 0 - (ms * 10000LL);\r
SetWaitableTimer(throttle_timer, &throttle_duetime, 0, 0, 0, 0);\r
ZeroMemory(&throttle_duetime, sizeof(throttle_duetime));\r
throttle_duetime.QuadPart = 0 - (ms * 10000LL);\r
SetWaitableTimer(throttle_timer, &throttle_duetime, 0, 0, 0, 0);\r
service_status.dwCurrentState = SERVICE_PAUSED;\r
SetServiceStatus(service_handle, &service_status);\r
\r
service_status.dwCurrentState = SERVICE_PAUSED;\r
SetServiceStatus(service_handle, &service_status);\r
\r
- if (throttle_timer) WaitForSingleObject(throttle_timer, INFINITE);\r
- else Sleep(ms);\r
+ if (use_critical_section) {\r
+ imports.SleepConditionVariableCS(&throttle_condition, &throttle_section, ms);\r
+ LeaveCriticalSection(&throttle_section);\r
+ }\r
+ else {\r
+ if (throttle_timer) WaitForSingleObject(throttle_timer, INFINITE);\r
+ else Sleep(ms);\r
+ }\r