module winsvc;

/*
** link with advapi32.lib
*/

export extern ( Windows )
{

const char[] SERVICES_ACTIVE_DATABASE = "ServicesActive";
const char[] SERVICES_FAILED_DATABASE = "ServicesFailed";
const char SC_GROUP_IDENTIFIER = '+';

const uint SERVICE_NO_CHANGE = 0xffffffff;

enum : uint
{
	SERVICE_ACTIVE = 0x00000001,
	SERVICE_INACTIVE = 0x00000002,
	SERVICE_STATE_ALL = 0x00000003
}

enum : uint
{
	SERVICE_CONTROL_STOP = 0x00000001,
	SERVICE_CONTROL_PAUSE = 0x00000002,
	SERVICE_CONTROL_CONTINUE = 0x00000003,
	SERVICE_CONTROL_INTERROGATE = 0x00000004,
	SERVICE_CONTROL_SHUTDOWN = 0x00000005,
	SERVICE_CONTROL_PARAMCHANGE = 0x00000006,
	SERVICE_CONTROL_NETBINDADD = 0x00000007,
	SERVICE_CONTROL_NETBINDREMOVE = 0x00000008,
	SERVICE_CONTROL_NETBINDENABLE = 0x00000009,
	SERVICE_CONTROL_NETBINDDISABLE = 0x0000000A,
	SERVICE_CONTROL_DEVICEEVENT = 0x0000000B,
	SERVICE_CONTROL_HARDWAREPROFILECHANGE = 0x0000000C,
	SERVICE_CONTROL_POWEREVENT = 0x0000000D,
	SERVICE_CONTROL_SESSIONCHANGE = 0x0000000E
}


enum : uint
{
	SERVICE_STOPPED = 0x00000001,
	SERVICE_START_PENDING = 0x00000002,
	SERVICE_STOP_PENDING = 0x00000003,
	SERVICE_RUNNING = 0x00000004,
	SERVICE_CONTINUE_PENDING = 0x00000005,
	SERVICE_PAUSE_PENDING = 0x00000006,
	SERVICE_PAUSED = 0x00000007
}

enum : uint
{
	SERVICE_ACCEPT_STOP = 0x00000001,
	SERVICE_ACCEPT_PAUSE_CONTINUE = 0x00000002,
	SERVICE_ACCEPT_SHUTDOWN = 0x00000004,
	SERVICE_ACCEPT_PARAMCHANGE = 0x00000008,
	SERVICE_ACCEPT_NETBINDCHANGE = 0x00000010,
	SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 0x00000020,
	SERVICE_ACCEPT_POWEREVENT = 0x00000040,
	SERVICE_ACCEPT_SESSIONCHANGE = 0x00000080
}

enum : uint
{
	SC_MANAGER_CONNECT = 0x0001,
	SC_MANAGER_CREATE_SERVICE = 0x0002,
	SC_MANAGER_ENUMERATE_SERVICE = 0x0004,
	SC_MANAGER_LOCK = 0x0008,
	SC_MANAGER_QUERY_LOCK_STATUS = 0x0010,
	SC_MANAGER_MODIFY_BOOT_CONFIG = 0x0020,
	SC_MANAGER_ALL_ACCESS = 0x000F003f
}


enum : uint
{
	SERVICE_QUERY_CONFIG = 0x0001,
	SERVICE_CHANGE_CONFIG = 0x0002,
	SERVICE_QUERY_STATUS = 0x0004,
	SERVICE_ENUMERATE_DEPENDENTS = 0x0008,
	SERVICE_START = 0x0010,
	SERVICE_STOP = 0x0020,
	SERVICE_PAUSE_CONTINUE = 0x0040,
	SERVICE_INTERROGATE = 0x0080,
	SERVICE_USER_DEFINED_CONTROL = 0x0100,
	SERVICE_ALL_ACCESS = 0x000F01ff
}

const uint SERVICE_RUNS_IN_SYSTEM_PROCESS = 0x00000001;

enum
{
	SERVICE_CONFIG_DESCRIPTION = 1,
	SERVICE_CONFIG_FAILURE_ACTIONS = 2
}

struct SERVICE_DESCRIPTION
{
	char * lpDescription;
}
alias SERVICE_DESCRIPTION * LPSERVICE_DESCRIPTION;

enum SC_ACTION_TYPE
{
	SC_ACTION_NONE = 0,
	SC_ACTION_RESTART = 1,
	SC_ACTION_REBOOT = 2,
	SC_ACTION_RUN_COMMAND = 3
}

struct SC_ACTION
{
	SC_ACTION_TYPE Type;
	uint Delay;
}
alias SC_ACTION * LPSC_ACTION;

struct SERVICE_FAILURE_ACTIONS
{
	uint dwResetPeriod;
	char * lpRebootMsg;
	char * lpCommand;
	uint cActions;
	SC_ACTION * lpsaActions;
}
alias SERVICE_FAILURE_ACTIONS * LPSERVICE_FAILURE_ACTIONS;

alias void * SC_HANDLE;
alias SC_HANDLE * LPSC_HANDLE;

alias void * SERVICE_STATUS_HANDLE;

enum SC_STATUS_TYPE
{
	SC_STATUS_PROCESS_INFO = 0
}

enum SC_ENUM_TYPE
{
	SC_ENUM_PROCESS_INFO = 0
}

struct SERVICE_STATUS
{
	uint dwServiceType;
	uint dwCurrentState;
	uint dwControlsAccepted;
	uint dwWin32ExitCode;
	uint dwServiceSpecificExitCode;
	uint dwCheckPoint;
	uint dwWaitHint;
}
alias SERVICE_STATUS * LPSERVICE_STATUS;

struct SERVICE_STATUS_PROCESS
{
	uint dwServiceType;
	uint dwCurrentState;
	uint dwControlsAccepted;
	uint dwWin32ExitCode;
	uint dwServiceSpecificExitCode;
	uint dwCheckPoint;
	uint dwWaitHint;
	uint dwProcessId;
	uint dwServiceFlags;
}
alias SERVICE_STATUS_PROCESS * LPSERVICE_STATUS_PROCESS;


struct ENUM_SERVICE_STATUS
{
	char * lpServiceName;
	char * lpDisplayName;
	SERVICE_STATUS ServiceStatus;
}
alias ENUM_SERVICE_STATUS * LPENUM_SERVICE_STATUS;


struct ENUM_SERVICE_STATUS_PROCESS
{
	char * lpServiceName;
	char * lpDisplayName;
	SERVICE_STATUS_PROCESS ServiceStatusProcess;
}
alias ENUM_SERVICE_STATUS_PROCESS * LPENUM_SERVICE_STATUS_PROCESS;

alias void * SC_LOCK;

struct QUERY_SERVICE_LOCK_STATUS
{
	uint fIsLocked;
	char * lpLockOwner;
	uint dwLockDuration;
}
alias QUERY_SERVICE_LOCK_STATUS * LPQUERY_SERVICE_LOCK_STATUS;

struct QUERY_SERVICE_CONFIG
{
	uint dwServiceType;
	uint dwStartType;
	uint dwErrorControl;
	char * lpBinaryPathName;
	char * lpLoadOrderGroup;
	uint dwTagId;
	char * lpDependencies;
	char * lpServiceStartName;
	char * lpDisplayName;
}
alias QUERY_SERVICE_CONFIG * LPQUERY_SERVICE_CONFIG;


alias void (* LPSERVICE_MAIN_FUNCTION)
(
	uint dwNumServicesArgs,
	char * * lpServiceArgVectors
);

struct SERVICE_TABLE_ENTRY
{
	char * lpServiceName;
	LPSERVICE_MAIN_FUNCTION lpServiceProc;
}

alias SERVICE_TABLE_ENTRY * LPSERVICE_TABLE_ENTRY;


alias void (* LPHANDLER_FUNCTION)
(
	uint dwControl
);


alias void (* LPHANDLER_FUNCTION_EX)
(
	uint dwControl,
	uint dwEventType,
	void * lpEventData,
	void * lpContext
);


int
ChangeServiceConfigA
(
	SC_HANDLE hService,
	uint dwServiceType,
	uint dwStartType,
	uint dwErrorControl,
	char * lpBinaryPathName,
	char * lpLoadOrderGroup,
	uint * lpdwTagId,
	char * lpDependencies,
	char * lpServiceStartName,
	char * lpPassword,
	char * lpDisplayName
);

int
ChangeServiceConfigW
(
	SC_HANDLE hService,
	uint dwServiceType,
	uint dwStartType,
	uint dwErrorControl,
	char * lpBinaryPathName,
	char * lpLoadOrderGroup,
	uint * lpdwTagId,
	char * lpDependencies,
	char * lpServiceStartName,
	char * lpPassword,
	char * lpDisplayName
);

version ( UNICODE )
{
	alias ChangeServiceConfigW ChangeServiceConfig;
}
else
{
	alias ChangeServiceConfigA ChangeServiceConfig;
}


int
ChangeServiceConfig2A
(
	SC_HANDLE hService,
	uint dwInfoLevel,
	void * lpInfo
);

int
ChangeServiceConfig2W
(
	SC_HANDLE hService,
	uint dwInfoLevel,
	void * lpInfo
);

version ( UNICODE )
{
	alias ChangeServiceConfig2W ChangeServiceConfig2;
}
else
{
	alias ChangeServiceConfig2A ChangeServiceConfig2;
}


int
CloseServiceHandle
(
	SC_HANDLE hSCObject
);

int
ControlService
(
	SC_HANDLE hService,
	uint dwControl,
	LPSERVICE_STATUS lpServiceStatus
);

SC_HANDLE
CreateServiceA
(
	SC_HANDLE hSCManager,
	char * lpServiceName,
	char * lpDisplayName,
	uint dwDesiredAccess,
	uint dwServiceType,
	uint dwStartType,
	uint dwErrorControl,
	char * lpBinaryPathName,
	char * lpLoadOrderGroup,
	uint * lpdwTagId,
	char * lpDependencies,
	char * lpServiceStartName,
	char * lpPassword
);

SC_HANDLE
CreateServiceW
(
	SC_HANDLE hSCManager,
	char * lpServiceName,
	char * lpDisplayName,
	uint dwDesiredAccess,
	uint dwServiceType,
	uint dwStartType,
	uint dwErrorControl,
	char * lpBinaryPathName,
	char * lpLoadOrderGroup,
	uint * lpdwTagId,
	char * lpDependencies,
	char * lpServiceStartName,
	char * lpPassword
);

version ( UNICODE )
{
	alias CreateServiceW CreateService;
}
else
{
	alias CreateServiceA CreateService;
}


int
DeleteService
(
	SC_HANDLE hService
);


int
EnumDependentServicesA
(
	SC_HANDLE hService,
	uint dwServiceState,
	LPENUM_SERVICE_STATUS lpServices,
	uint cbBufSize,
	uint * pcbBytesNeeded,
	uint * lpServicesReturned
);

int
EnumDependentServicesW
(
	SC_HANDLE hService,
	uint dwServiceState,
	LPENUM_SERVICE_STATUS lpServices,
	uint cbBufSize,
	uint * pcbBytesNeeded,
	uint * lpServicesReturned
);

version ( UNICODE )
{
	alias EnumDependentServicesW EnumDependentServices;
}
else
{
	alias EnumDependentServicesA EnumDependentServices;
}


int
EnumServicesStatusA
(
	SC_HANDLE hSCManager,
	uint dwServiceType,
	uint dwServiceState,
	LPENUM_SERVICE_STATUS lpServices,
	uint cbBufSize,
	uint * pcbBytesNeeded,
	uint * lpServicesReturned,
	uint * lpResumeHandle
);

int
EnumServicesStatusW
(
	SC_HANDLE hSCManager,
	uint dwServiceType,
	uint dwServiceState,
	LPENUM_SERVICE_STATUS lpServices,
	uint cbBufSize,
	uint * pcbBytesNeeded,
	uint * lpServicesReturned,
	uint * lpResumeHandle
);

version ( UNICODE )
{
	alias EnumServicesStatusW EnumServicesStatus;
}
else
{
	alias EnumServicesStatusA EnumServicesStatus;
}


int
EnumServicesStatusExA
(
	SC_HANDLE hSCManager,
	SC_ENUM_TYPE InfoLevel,
	uint dwServiceType,
	uint dwServiceState,
	ubyte * lpServices,
	uint cbBufSize,
	uint * pcbBytesNeeded,
	uint * lpServicesReturned,
	uint * lpResumeHandle,
	char * pszGroupName
);

int
EnumServicesStatusExW
(
	SC_HANDLE hSCManager,
	SC_ENUM_TYPE InfoLevel,
	uint dwServiceType,
	uint dwServiceState,
	ubyte * lpServices,
	uint cbBufSize,
	uint * pcbBytesNeeded,
	uint * lpServicesReturned,
	uint * lpResumeHandle,
	char * pszGroupName
);

version ( UNICODE )
{
	alias EnumServicesStatusExW EnumServicesStatusEx;
}
else
{
	alias EnumServicesStatusExA EnumServicesStatusEx;
}


int
GetServiceKeyNameA
(
	SC_HANDLE hSCManager,
	char * lpDisplayName,
	char * lpServiceName,
	uint * lpcchBuffer
);

int
GetServiceKeyNameW
(
	SC_HANDLE hSCManager,
	char * lpDisplayName,
	char * lpServiceName,
	uint * lpcchBuffer
);

version ( UNICODE )
{
	alias GetServiceKeyNameW GetServiceKeyName;
}
else
{
	alias GetServiceKeyNameA GetServiceKeyName;
}


int
GetServiceDisplayNameA
(
	SC_HANDLE hSCManager,
	char * lpServiceName,
	char * lpDisplayName,
	uint * lpcchBuffer
);

int
GetServiceDisplayNameW
(
	SC_HANDLE hSCManager,
	char * lpServiceName,
	char * lpDisplayName,
	uint * lpcchBuffer
);

version ( UNICODE )
{
	alias GetServiceDisplayNameW GetServiceDisplayName;
}
else
{
	alias GetServiceDisplayNameA GetServiceDisplayName;
}

SC_LOCK
LockServiceDatabase
(
	SC_HANDLE hSCManager
);


int
NotifyBootConfigStatus
(
	int BootAcceptable
);


SC_HANDLE
OpenSCManagerA
(
	char * lpMachineName,
	char * lpDatabaseName,
	uint dwDesiredAccess
);

SC_HANDLE
OpenSCManagerW
(
	char * lpMachineName,
	char * lpDatabaseName,
	uint dwDesiredAccess
);

version ( UNICODE )
{
	alias OpenSCManagerW OpenSCManager;
}
else
{
	alias OpenSCManagerA OpenSCManager;
}


SC_HANDLE
OpenServiceA
(
	SC_HANDLE hSCManager,
	char * lpServiceName,
	uint dwDesiredAccess
);

SC_HANDLE
OpenServiceW
(
	SC_HANDLE hSCManager,
	char * lpServiceName,
	uint dwDesiredAccess
);

version ( UNICODE )
{
	alias OpenServiceW OpenService;
}
else
{
	alias OpenServiceA OpenService;
}

int
QueryServiceConfigA
(
	SC_HANDLE hService,
	LPQUERY_SERVICE_CONFIG lpServiceConfig,
	uint cbBufSize,
	uint * pcbBytesNeeded
);

int
QueryServiceConfigW
(
	SC_HANDLE hService,
	LPQUERY_SERVICE_CONFIG lpServiceConfig,
	uint cbBufSize,
	uint * pcbBytesNeeded
);

version ( UNICODE )
{
	alias QueryServiceConfigW QueryServiceConfig;
}
else
{
	alias QueryServiceConfigA QueryServiceConfig;
}


int
QueryServiceConfig2A
(
	SC_HANDLE hService,
	uint dwInfoLevel,
	ubyte * lpBuffer,
	uint cbBufSize,
	uint * pcbBytesNeeded
);

int
QueryServiceConfig2W
(
	SC_HANDLE hService,
	uint dwInfoLevel,
	ubyte * lpBuffer,
	uint cbBufSize,
	uint * pcbBytesNeeded
);

version ( UNICODE )
{
	alias QueryServiceConfig2W QueryServiceConfig2;
}
else
{
	alias QueryServiceConfig2A QueryServiceConfig2;
}


int
QueryServiceLockStatusA
(
	SC_HANDLE hSCManager,
	LPQUERY_SERVICE_LOCK_STATUS lpLockStatus,
	uint cbBufSize,
	uint * pcbBytesNeeded
);

int
QueryServiceLockStatusW
(
	SC_HANDLE hSCManager,
	LPQUERY_SERVICE_LOCK_STATUS lpLockStatus,
	uint cbBufSize,
	uint * pcbBytesNeeded
);

version ( UNICODE )
{
	alias QueryServiceLockStatusW QueryServiceLockStatus;
}
else
{
	alias QueryServiceLockStatusA QueryServiceLockStatus;
}


alias void * PSECURITY_DESCRIPTOR;
alias uint SECURITY_INFORMATION;


int
QueryServiceObjectSecurity
(
	SC_HANDLE hService,
	SECURITY_INFORMATION dwSecurityInformation,
	PSECURITY_DESCRIPTOR lpSecurityDescriptor,
	uint cbBufSize,
	uint * pcbBytesNeeded
);

int
QueryServiceStatus
(
	SC_HANDLE hService,
	LPSERVICE_STATUS lpServiceStatus
);


int
QueryServiceStatusEx
(
	SC_HANDLE hService,
	SC_STATUS_TYPE InfoLevel,
	ubyte * lpBuffer,
	uint cbBufSize,
	uint * pcbBytesNeeded
);


SERVICE_STATUS_HANDLE
RegisterServiceCtrlHandlerA
(
	char * lpServiceName,
	LPHANDLER_FUNCTION lpHandlerProc
);

SERVICE_STATUS_HANDLE
RegisterServiceCtrlHandlerW
(
	char * lpServiceName,
	LPHANDLER_FUNCTION lpHandlerProc
);

version ( UNICODE )
{
	alias RegisterServiceCtrlHandlerW RegisterServiceCtrlHandler;
}
else
{
	alias RegisterServiceCtrlHandlerA RegisterServiceCtrlHandler;
}


SERVICE_STATUS_HANDLE
RegisterServiceCtrlHandlerExA
(
	char * lpServiceName,
	LPHANDLER_FUNCTION_EX lpHandlerProc,
	void * lpContext
);

SERVICE_STATUS_HANDLE
RegisterServiceCtrlHandlerExW
(
	char * lpServiceName,
	LPHANDLER_FUNCTION_EX lpHandlerProc,
	void * lpContext
);

version ( UNICODE )
{
	alias RegisterServiceCtrlHandlerExW RegisterServiceCtrlHandlerEx;
}
else
{
	alias RegisterServiceCtrlHandlerExA RegisterServiceCtrlHandlerEx;
}


int
SetServiceObjectSecurity
(
	SC_HANDLE hService,
	SECURITY_INFORMATION dwSecurityInformation,
	PSECURITY_DESCRIPTOR lpSecurityDescriptor
);

int
SetServiceStatus
(
	SERVICE_STATUS_HANDLE hServiceStatus,
	LPSERVICE_STATUS lpServiceStatus
);


int
StartServiceCtrlDispatcherA
(
	SERVICE_TABLE_ENTRY * lpServiceStartTable
);

int
StartServiceCtrlDispatcherW
(
	SERVICE_TABLE_ENTRY * lpServiceStartTable
);

version ( UNICODE )
{
	alias StartServiceCtrlDispatcherW StartServiceCtrlDispatcher;
}
else
{
	alias StartServiceCtrlDispatcherA StartServiceCtrlDispatcher;
}


int
StartServiceA
(
	SC_HANDLE hService,
	uint dwNumServiceArgs,
	char * * lpServiceArgVectors
);

int
StartServiceW
(
	SC_HANDLE hService,
	uint dwNumServiceArgs,
	char * * lpServiceArgVectors
);

version ( UNICODE )
{
	alias StartServiceW StartService;
}
else
{
	alias StartServiceA StartService;
}


int
UnlockServiceDatabase
(
	SC_LOCK ScLock
);

} // extern ( Windows )