You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

142 lines
4.9 KiB
C

22 years ago
#ifndef SERVICE_H
#define SERVICE_H
/*
MSDN says the commandline in CreateProcess() is limited to 32768 characters
and the application name to MAX_PATH.
A service name and service display name are limited to 256 characters.
A registry key is limited to 255 characters.
A registry value is limited to 16383 characters.
Therefore we limit the service name to accommodate the path under HKLM.
*/
#define EXE_LENGTH PATH_LENGTH
#define CMD_LENGTH 32768
#define KEY_LENGTH 255
#define VALUE_LENGTH 16383
#define SERVICE_NAME_LENGTH 256
#define ACTION_LEN 16
#define NSSM_KERNEL_DRIVER _T("SERVICE_KERNEL_DRIVER")
#define NSSM_FILE_SYSTEM_DRIVER _T("SERVICE_FILE_SYSTEM_DRIVER")
#define NSSM_WIN32_OWN_PROCESS _T("SERVICE_WIN32_OWN_PROCESS")
#define NSSM_WIN32_SHARE_PROCESS _T("SERVICE_WIN32_SHARE_PROCESS")
#define NSSM_INTERACTIVE_PROCESS _T("SERVICE_INTERACTIVE_PROCESS")
#define NSSM_SHARE_INTERACTIVE_PROCESS NSSM_WIN32_SHARE_PROCESS _T("|") NSSM_INTERACTIVE_PROCESS
#define NSSM_UNKNOWN _T("?")
#define NSSM_ROTATE_OFFLINE 0
#define NSSM_ROTATE_ONLINE 1
#define NSSM_ROTATE_ONLINE_ASAP 2
typedef struct {
bool native;
TCHAR name[SERVICE_NAME_LENGTH];
TCHAR displayname[SERVICE_NAME_LENGTH];
TCHAR description[VALUE_LENGTH];
unsigned long startup;
TCHAR *username;
size_t usernamelen;
TCHAR *password;
size_t passwordlen;
unsigned long type;
TCHAR image[PATH_LENGTH];
TCHAR exe[EXE_LENGTH];
TCHAR flags[VALUE_LENGTH];
TCHAR dir[DIR_LENGTH];
TCHAR *env;
__int64 affinity;
unsigned long envlen;
TCHAR *env_extra;
unsigned long env_extralen;
unsigned long priority;
unsigned long no_console;
TCHAR stdin_path[PATH_LENGTH];
unsigned long stdin_sharing;
unsigned long stdin_disposition;
unsigned long stdin_flags;
TCHAR stdout_path[PATH_LENGTH];
unsigned long stdout_sharing;
unsigned long stdout_disposition;
unsigned long stdout_flags;
HANDLE stdout_pipe;
HANDLE stdout_thread;
unsigned long stdout_tid;
TCHAR stderr_path[PATH_LENGTH];
unsigned long stderr_sharing;
unsigned long stderr_disposition;
unsigned long stderr_flags;
HANDLE stderr_pipe;
HANDLE stderr_thread;
unsigned long stderr_tid;
bool rotate_files;
unsigned long rotate_stdout_online;
unsigned long rotate_stderr_online;
unsigned long rotate_seconds;
unsigned long rotate_bytes_low;
unsigned long rotate_bytes_high;
unsigned long default_exit_action;
unsigned long restart_delay;
unsigned long throttle_delay;
unsigned long stop_method;
unsigned long kill_console_delay;
unsigned long kill_window_delay;
unsigned long kill_threads_delay;
SC_HANDLE handle;
SERVICE_STATUS status;
SERVICE_STATUS_HANDLE status_handle;
HANDLE process_handle;
unsigned long pid;
HANDLE wait_handle;
bool stopping;
bool allow_restart;
unsigned long throttle;
CRITICAL_SECTION throttle_section;
bool throttle_section_initialised;
CONDITION_VARIABLE throttle_condition;
HANDLE throttle_timer;
LARGE_INTEGER throttle_duetime;
FILETIME creation_time;
FILETIME exit_time;
Revamped environment variables again. A previous commit changed how environment variables were managed. Initially we were calling SetEnvironmentVariable() on each variable defined in AppEnvironmentExtra prior to starting the service. That behaviour was changed because it was technically incorrect, potentially resulting in NSSM's own environment being harmed. Unfortunately the changed method, creating a new environment block by calling GetEnvironmentStrings() (or using the block from AppEnvironment if that and AppEnvironmentExtra were both defined), failed if users did something like set AppEnvironmentExtra to PATH=C:\bin;%PATH%. That would result in the process being started with a block which included TWO occurrences of the PATH variable; the system-defined one and the appended one. The latter would be ignored, possibly causing the application to fail to start. For this third attempt we now call GetEnvironmentStrings() once at startup, storing the block in a new variable which is only freed at exit. Immediately prior to calling CreateProcess() to start the service we use the new environment functions duplicate_environment() (on AppEnvironment) and set_environment_block() (on AppEnvironmentExtra) to set the variables. Then immediately after calling CreateProcess() we call duplicate_environment() again to restore the original block. Because they are passed to expand_environment_string(), the environment blocks are subject to expansion. That means that setting PATH as described in the example above would work. Trying to append items to the PATH by setting AppEnvironment in a similar way will probably not work. Thanks Bryan Senseman.
11 years ago
TCHAR *initial_env;
} nssm_service_t;
void WINAPI service_main(unsigned long, TCHAR **);
TCHAR *service_control_text(unsigned long);
TCHAR *service_status_text(unsigned long);
void log_service_control(TCHAR *, unsigned long, bool);
22 years ago
unsigned long WINAPI service_control_handler(unsigned long, unsigned long, void *, void *);
int affinity_mask_to_string(__int64, TCHAR **);
int affinity_string_to_mask(TCHAR *, __int64 *);
unsigned long priority_mask();
int priority_constant_to_index(unsigned long);
unsigned long priority_index_to_constant(int);
nssm_service_t *alloc_nssm_service();
void set_nssm_service_defaults(nssm_service_t *);
void cleanup_nssm_service(nssm_service_t *);
SC_HANDLE open_service_manager(unsigned long);
SC_HANDLE open_service(SC_HANDLE, TCHAR *, unsigned long, TCHAR *, unsigned long);
QUERY_SERVICE_CONFIG *query_service_config(const TCHAR *, SC_HANDLE);
int set_service_description(const TCHAR *, SC_HANDLE, TCHAR *);
int get_service_description(const TCHAR *, SC_HANDLE, unsigned long, TCHAR *);
int get_service_startup(const TCHAR *, SC_HANDLE, const QUERY_SERVICE_CONFIG *, unsigned long *);
int get_service_username(const TCHAR *, const QUERY_SERVICE_CONFIG *, TCHAR **, size_t *);
int pre_install_service(int, TCHAR **);
int pre_remove_service(int, TCHAR **);
int pre_edit_service(int, TCHAR **);
int install_service(nssm_service_t *);
int remove_service(nssm_service_t *);
int edit_service(nssm_service_t *, bool);
int control_service(unsigned long, int, TCHAR **);
void set_service_recovery(nssm_service_t *);
int monitor_service(nssm_service_t *);
int start_service(nssm_service_t *);
int stop_service(nssm_service_t *, unsigned long, bool, bool);
22 years ago
void CALLBACK end_service(void *, unsigned char);
void throttle_restart(nssm_service_t *);
int await_shutdown(nssm_service_t *, TCHAR *, unsigned long);
22 years ago
#endif