/*
 * winsvc.h
 *
 * Windows Service Control Management API.
 *
 * $Id: winsvc.h,v 081e50ff4d56 2020/03/28 14:54:25 keith $
 *
 * Written by Anders Norlander <anorland@hem2.passagen.se>
 * Copyright (C) 1998, 1999, 2001-2003, 2006, 2020, MinGW.org Project
 *
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */
#ifndef _WINSVC_H
#pragma GCC system_header
#define _WINSVC_H

#include <windef.h>

#ifndef WINADVAPI
#define WINADVAPI
#endif

_BEGIN_C_DECLS

#define SERVICES_ACTIVE_DATABASEA      "ServicesActive"
#define SERVICES_ACTIVE_DATABASEW     __AW_STRING_W__(SERVICES_ACTIVE_DATABASEA)
#define SERVICES_ACTIVE_DATABASE      __AW_SUFFIXED__(SERVICES_ACTIVE_DATABASE)

#define SERVICES_FAILED_DATABASEA      "ServicesFailed"
#define SERVICES_FAILED_DATABASEW     __AW_STRING_W__(SERVICES_FAILED_DATABASEA)
#define SERVICES_FAILED_DATABASE      __AW_SUFFIXED__(SERVICES_FAILED_DATABASE)

#define SC_GROUP_IDENTIFIERA	       '+'
#define SC_GROUP_IDENTIFIERW	      __AW_STRING_W__(SC_GROUP_IDENTIFIERA)
#define SC_GROUP_IDENTIFIER	      __AW_SUFFIXED__(SC_GROUP_IDENTIFIER)

#define SC_MANAGER_CONNECT			 1
#define SC_MANAGER_CREATE_SERVICE		 2
#define SC_MANAGER_ENUMERATE_SERVICE		 4
#define SC_MANAGER_LOCK 			 8
#define SC_MANAGER_QUERY_LOCK_STATUS		16
#define SC_MANAGER_MODIFY_BOOT_CONFIG		32

#define SC_MANAGER_ALL_ACCESS		      0xF003F

#define SERVICE_NO_CHANGE		   0xFFFFFFFF

#define SERVICE_STOPPED 			 1
#define SERVICE_START_PENDING			 2
#define SERVICE_STOP_PENDING			 3
#define SERVICE_RUNNING 			 4
#define SERVICE_CONTINUE_PENDING		 5
#define SERVICE_PAUSE_PENDING			 6
#define SERVICE_PAUSED				 7

#define SERVICE_ACCEPT_STOP			 1
#define SERVICE_ACCEPT_PAUSE_CONTINUE		 2
#define SERVICE_ACCEPT_SHUTDOWN 		 4
#define SERVICE_ACCEPT_PARAMCHANGE   		 8
#define SERVICE_ACCEPT_NETBINDCHANGE		16
#define SERVICE_ACCEPT_HARDWAREPROFILECHANGE	32
#define SERVICE_ACCEPT_POWEREVENT		64
#define SERVICE_ACCEPT_SESSIONCHANGE	       128

#define SERVICE_CONTROL_STOP			 1
#define SERVICE_CONTROL_PAUSE			 2
#define SERVICE_CONTROL_CONTINUE		 3
#define SERVICE_CONTROL_INTERROGATE		 4
#define SERVICE_CONTROL_SHUTDOWN		 5
#define SERVICE_CONTROL_PARAMCHANGE		 6
#define SERVICE_CONTROL_NETBINDADD		 7
#define SERVICE_CONTROL_NETBINDREMOVE		 8
#define SERVICE_CONTROL_NETBINDENABLE		 9
#define SERVICE_CONTROL_NETBINDDISABLE		10
#define SERVICE_CONTROL_DEVICEEVENT		11
#define SERVICE_CONTROL_HARDWAREPROFILECHANGE	12
#define SERVICE_CONTROL_POWEREVENT		13
#define SERVICE_CONTROL_SESSIONCHANGE		14

#define SERVICE_ACTIVE				 1
#define SERVICE_INACTIVE			 2
#define SERVICE_STATE_ALL			 3

#define SERVICE_QUERY_CONFIG			 1
#define SERVICE_CHANGE_CONFIG			 2
#define SERVICE_QUERY_STATUS			 4
#define SERVICE_ENUMERATE_DEPENDENTS		 8
#define SERVICE_START				16
#define SERVICE_STOP				32
#define SERVICE_PAUSE_CONTINUE			64
#define SERVICE_INTERROGATE		       128
#define SERVICE_USER_DEFINED_CONTROL	       256

#define SERVICE_ALL_ACCESS		\
  (	STANDARD_RIGHTS_REQUIRED	\
    |	SERVICE_QUERY_CONFIG		\
    |	SERVICE_CHANGE_CONFIG		\
    |	SERVICE_QUERY_STATUS		\
    |	SERVICE_ENUMERATE_DEPENDENTS	\
    |	SERVICE_START			\
    |	SERVICE_STOP			\
    |	SERVICE_PAUSE_CONTINUE		\
    |	SERVICE_INTERROGATE		\
    |	SERVICE_USER_DEFINED_CONTROL	\
  )

#define SERVICE_RUNS_IN_SYSTEM_PROCESS		 1
#define SERVICE_CONFIG_DESCRIPTION		 1
#define SERVICE_CONFIG_FAILURE_ACTIONS		 2

typedef
struct _SERVICE_STATUS
{ DWORD 			 dwServiceType;
  DWORD 			 dwCurrentState;
  DWORD 			 dwControlsAccepted;
  DWORD 			 dwWin32ExitCode;
  DWORD 			 dwServiceSpecificExitCode;
  DWORD 			 dwCheckPoint;
  DWORD 			 dwWaitHint;
} SERVICE_STATUS, *LPSERVICE_STATUS;

typedef
struct _SERVICE_STATUS_PROCESS
{ DWORD 			 dwServiceType;
  DWORD 			 dwCurrentState;
  DWORD 			 dwControlsAccepted;
  DWORD 			 dwWin32ExitCode;
  DWORD 			 dwServiceSpecificExitCode;
  DWORD 			 dwCheckPoint;
  DWORD 			 dwWaitHint;
  DWORD 			 dwProcessId;
  DWORD 			 dwServiceFlags;
} SERVICE_STATUS_PROCESS, *LPSERVICE_STATUS_PROCESS;

typedef
enum _SC_STATUS_TYPE
{ SC_STATUS_PROCESS_INFO   =     0
} SC_STATUS_TYPE;

typedef
enum _SC_ENUM_TYPE
{ SC_ENUM_PROCESS_INFO     =     0
} SC_ENUM_TYPE;

typedef
struct _ENUM_SERVICE_STATUSA
{ LPSTR 			 lpServiceName;
  LPSTR 			 lpDisplayName;
  SERVICE_STATUS		 ServiceStatus;
} ENUM_SERVICE_STATUSA, *LPENUM_SERVICE_STATUSA;

typedef
struct _ENUM_SERVICE_STATUSW
{ LPWSTR			 lpServiceName;
  LPWSTR			 lpDisplayName;
  SERVICE_STATUS		 ServiceStatus;
} ENUM_SERVICE_STATUSW, *LPENUM_SERVICE_STATUSW;

typedef
__AW_ALIAS__(ENUM_SERVICE_STATUS), *LPENUM_SERVICE_STATUS;

typedef
struct _ENUM_SERVICE_STATUS_PROCESSA
{ LPSTR 			 lpServiceName;
  LPSTR 			 lpDisplayName;
  SERVICE_STATUS_PROCESS	 ServiceStatusProcess;
} ENUM_SERVICE_STATUS_PROCESSA, *LPENUM_SERVICE_STATUS_PROCESSA;

typedef
struct _ENUM_SERVICE_STATUS_PROCESSW
{ LPWSTR			 lpServiceName;
  LPWSTR			 lpDisplayName;
  SERVICE_STATUS_PROCESS	 ServiceStatusProcess;
} ENUM_SERVICE_STATUS_PROCESSW, *LPENUM_SERVICE_STATUS_PROCESSW;

typedef
__AW_ALIAS__(ENUM_SERVICE_STATUS_PROCESS), *LPENUM_SERVICE_STATUS_PROCESS;

typedef
struct _QUERY_SERVICE_CONFIGA
{ DWORD 			 dwServiceType;
  DWORD 			 dwStartType;
  DWORD 			 dwErrorControl;
  LPSTR 			 lpBinaryPathName;
  LPSTR 			 lpLoadOrderGroup;
  DWORD 			 dwTagId;
  LPSTR 			 lpDependencies;
  LPSTR 			 lpServiceStartName;
  LPSTR 			 lpDisplayName;
} QUERY_SERVICE_CONFIGA, *LPQUERY_SERVICE_CONFIGA;

typedef
struct _QUERY_SERVICE_CONFIGW
{ DWORD 			 dwServiceType;
  DWORD 			 dwStartType;
  DWORD 			 dwErrorControl;
  LPWSTR			 lpBinaryPathName;
  LPWSTR			 lpLoadOrderGroup;
  DWORD 			 dwTagId;
  LPWSTR			 lpDependencies;
  LPWSTR			 lpServiceStartName;
  LPWSTR			 lpDisplayName;
} QUERY_SERVICE_CONFIGW, *LPQUERY_SERVICE_CONFIGW;

typedef
__AW_ALIAS__(QUERY_SERVICE_CONFIG), *LPQUERY_SERVICE_CONFIG;

typedef
struct _QUERY_SERVICE_LOCK_STATUSA
{ DWORD 			 fIsLocked;
  LPSTR 			 lpLockOwner;
  DWORD 			 dwLockDuration;
} QUERY_SERVICE_LOCK_STATUSA, *LPQUERY_SERVICE_LOCK_STATUSA;

typedef
struct _QUERY_SERVICE_LOCK_STATUSW
{ DWORD 			 fIsLocked;
  LPWSTR			 lpLockOwner;
  DWORD 			 dwLockDuration;
} QUERY_SERVICE_LOCK_STATUSW, *LPQUERY_SERVICE_LOCK_STATUSW;

typedef
__AW_ALIAS__(QUERY_SERVICE_LOCK_STATUS), *LPQUERY_SERVICE_LOCK_STATUS;

typedef void (WINAPI *LPSERVICE_MAIN_FUNCTIONA)( DWORD, LPSTR * );
typedef void (WINAPI *LPSERVICE_MAIN_FUNCTIONW)( DWORD, LPWSTR * );

typedef __AW_ALIAS__(LPSERVICE_MAIN_FUNCTION);

typedef
struct _SERVICE_TABLE_ENTRYA
{ LPSTR 			 lpServiceName;
  LPSERVICE_MAIN_FUNCTIONA	 lpServiceProc;
} SERVICE_TABLE_ENTRYA, *LPSERVICE_TABLE_ENTRYA;

typedef
struct _SERVICE_TABLE_ENTRYW
{ LPWSTR			 lpServiceName;
  LPSERVICE_MAIN_FUNCTIONW	 lpServiceProc;
} SERVICE_TABLE_ENTRYW, *LPSERVICE_TABLE_ENTRYW;

typedef
__AW_ALIAS__(SERVICE_TABLE_ENTRY), *LPSERVICE_TABLE_ENTRY;

DECLARE_HANDLE(SC_HANDLE);

typedef PVOID SC_LOCK;
typedef SC_HANDLE *LPSC_HANDLE;
typedef DWORD SERVICE_STATUS_HANDLE;
typedef VOID (WINAPI *LPHANDLER_FUNCTION) (DWORD);
typedef DWORD (WINAPI *LPHANDLER_FUNCTION_EX) (DWORD, DWORD, LPVOID, LPVOID);

typedef
struct _SERVICE_DESCRIPTIONA
{ LPSTR 			 lpDescription;
} SERVICE_DESCRIPTIONA, *LPSERVICE_DESCRIPTIONA;

typedef
struct _SERVICE_DESCRIPTIONW
{ LPWSTR			 lpDescription;
} SERVICE_DESCRIPTIONW, *LPSERVICE_DESCRIPTIONW;

typedef
__AW_ALIAS__(SERVICE_DESCRIPTION), *LPSERVICE_DESCRIPTION;

typedef
enum _SC_ACTION_TYPE
{ SC_ACTION_NONE           =     0,
  SC_ACTION_RESTART        =     1,
  SC_ACTION_REBOOT         =     2,
  SC_ACTION_RUN_COMMAND    =     3
} SC_ACTION_TYPE;

typedef
struct _SC_ACTION
{ SC_ACTION_TYPE 		 Type;
  DWORD 			 Delay;
} SC_ACTION, *LPSC_ACTION;

typedef
struct _SERVICE_FAILURE_ACTIONSA
{ DWORD 			 dwResetPeriod;
  LPSTR 			 lpRebootMsg;
  LPSTR 			 lpCommand;
  DWORD 			 cActions;
  SC_ACTION			*lpsaActions;
} SERVICE_FAILURE_ACTIONSA, *LPSERVICE_FAILURE_ACTIONSA;

typedef
struct _SERVICE_FAILURE_ACTIONSW
{ DWORD 			 dwResetPeriod;
  LPWSTR			 lpRebootMsg;
  LPWSTR			 lpCommand;
  DWORD 			 cActions;
  SC_ACTION			*lpsaActions;
} SERVICE_FAILURE_ACTIONSW, *LPSERVICE_FAILURE_ACTIONSW;

typedef
__AW_ALIAS__(SERVICE_FAILURE_ACTIONS), *LPSERVICE_FAILURE_ACTIONS;

#define ChangeServiceConfig  \
__AW_SUFFIXED__(ChangeServiceConfig)
WINADVAPI BOOL WINAPI ChangeServiceConfigA
( SC_HANDLE, DWORD, DWORD, DWORD, LPCSTR, LPCSTR, LPDWORD, LPCSTR,
  LPCSTR, LPCSTR, LPCSTR
);
WINADVAPI BOOL WINAPI ChangeServiceConfigW
( SC_HANDLE, DWORD, DWORD, DWORD, LPCWSTR, LPCWSTR, LPDWORD, LPCWSTR,
  LPCWSTR, LPCWSTR, LPCWSTR
);

#define ChangeServiceConfig2  __AW_SUFFIXED__(ChangeServiceConfig2)
WINADVAPI BOOL WINAPI ChangeServiceConfig2A (SC_HANDLE, DWORD, LPVOID);
WINADVAPI BOOL WINAPI ChangeServiceConfig2W (SC_HANDLE, DWORD, LPVOID);

WINADVAPI BOOL WINAPI CloseServiceHandle (SC_HANDLE);
WINADVAPI BOOL WINAPI ControlService (SC_HANDLE, DWORD, LPSERVICE_STATUS);

#define CreateService  \
__AW_SUFFIXED__(CreateService)
WINADVAPI SC_HANDLE WINAPI CreateServiceA
( SC_HANDLE, LPCSTR, LPCSTR, DWORD, DWORD, DWORD, DWORD, LPCSTR,
  LPCSTR, PDWORD, LPCSTR, LPCSTR, LPCSTR
);
WINADVAPI SC_HANDLE WINAPI CreateServiceW
( SC_HANDLE, LPCWSTR, LPCWSTR, DWORD, DWORD, DWORD, DWORD, LPCWSTR,
  LPCWSTR, PDWORD, LPCWSTR, LPCWSTR, LPCWSTR
);

WINADVAPI BOOL WINAPI DeleteService (SC_HANDLE);

#define EnumDependentServices  \
__AW_SUFFIXED__(EnumDependentServices)
WINADVAPI BOOL WINAPI EnumDependentServicesA
( SC_HANDLE, DWORD, LPENUM_SERVICE_STATUSA, DWORD, PDWORD, PDWORD );
WINADVAPI BOOL WINAPI EnumDependentServicesW
( SC_HANDLE, DWORD, LPENUM_SERVICE_STATUSW, DWORD, PDWORD, PDWORD );

#define EnumServicesStatus  \
__AW_SUFFIXED__(EnumServicesStatus)
WINADVAPI BOOL WINAPI EnumServicesStatusA
( SC_HANDLE, DWORD, DWORD, LPENUM_SERVICE_STATUSA, DWORD, PDWORD,
  PDWORD, PDWORD
);
WINADVAPI BOOL WINAPI EnumServicesStatusW
( SC_HANDLE, DWORD, DWORD, LPENUM_SERVICE_STATUSW, DWORD, PDWORD,
  PDWORD, PDWORD
);

#define EnumServicesStatusEx  \
__AW_SUFFIXED__(EnumServicesStatusEx)
WINADVAPI BOOL WINAPI EnumServicesStatusExA
( SC_HANDLE, SC_ENUM_TYPE, DWORD, DWORD, LPBYTE, DWORD, LPDWORD,
  LPDWORD, LPDWORD, LPCSTR
);
WINADVAPI BOOL WINAPI EnumServicesStatusExW
( SC_HANDLE, SC_ENUM_TYPE, DWORD, DWORD, LPBYTE, DWORD, LPDWORD,
  LPDWORD, LPDWORD, LPCWSTR
);

#define GetServiceDisplayName  __AW_SUFFIXED__(GetServiceDisplayName)
WINADVAPI BOOL WINAPI GetServiceDisplayNameA (SC_HANDLE, LPCSTR, LPSTR, PDWORD);
WINADVAPI BOOL WINAPI GetServiceDisplayNameW (SC_HANDLE, LPCWSTR, LPWSTR, PDWORD);

#define GetServiceKeyName  __AW_SUFFIXED__(GetServiceKeyName)
WINADVAPI BOOL WINAPI GetServiceKeyNameA (SC_HANDLE, LPCSTR, LPSTR, PDWORD);
WINADVAPI BOOL WINAPI GetServiceKeyNameW (SC_HANDLE, LPCWSTR, LPWSTR, PDWORD);

WINADVAPI SC_LOCK WINAPI LockServiceDatabase (SC_HANDLE);
WINADVAPI BOOL WINAPI NotifyBootConfigStatus (BOOL);

#define OpenSCManager  __AW_SUFFIXED__(OpenSCManager)
WINADVAPI SC_HANDLE WINAPI OpenSCManagerA (LPCSTR, LPCSTR, DWORD);
WINADVAPI SC_HANDLE WINAPI OpenSCManagerW (LPCWSTR, LPCWSTR, DWORD);

#define OpenService  __AW_SUFFIXED__(OpenService)
WINADVAPI SC_HANDLE WINAPI OpenServiceA (SC_HANDLE, LPCSTR, DWORD);
WINADVAPI SC_HANDLE WINAPI OpenServiceW (SC_HANDLE, LPCWSTR, DWORD);

#define QueryServiceConfig  \
__AW_SUFFIXED__(QueryServiceConfig)
WINADVAPI BOOL WINAPI QueryServiceConfigA
( SC_HANDLE, LPQUERY_SERVICE_CONFIGA, DWORD, PDWORD );
WINADVAPI BOOL WINAPI QueryServiceConfigW
( SC_HANDLE, LPQUERY_SERVICE_CONFIGW, DWORD, PDWORD );

#define QueryServiceConfig2  \
__AW_SUFFIXED__(QueryServiceConfig2)
WINADVAPI BOOL WINAPI QueryServiceConfig2A
( SC_HANDLE, DWORD, LPBYTE, DWORD, LPDWORD );
WINADVAPI BOOL WINAPI QueryServiceConfig2W
( SC_HANDLE, DWORD, LPBYTE, DWORD, LPDWORD );

#define QueryServiceLockStatus  \
__AW_SUFFIXED__(QueryServiceLockStatus)
WINADVAPI BOOL WINAPI QueryServiceLockStatusA
( SC_HANDLE, LPQUERY_SERVICE_LOCK_STATUSA, DWORD, PDWORD );
WINADVAPI BOOL WINAPI QueryServiceLockStatusW
( SC_HANDLE, LPQUERY_SERVICE_LOCK_STATUSW, DWORD, PDWORD );

WINADVAPI BOOL WINAPI QueryServiceObjectSecurity
( SC_HANDLE, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR, DWORD, LPDWORD );

WINADVAPI BOOL WINAPI QueryServiceStatus (SC_HANDLE, LPSERVICE_STATUS );

WINADVAPI BOOL WINAPI QueryServiceStatusEx
( SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD );

#define RegisterServiceCtrlHandler  \
__AW_SUFFIXED__(RegisterServiceCtrlHandler)
WINADVAPI SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerA
( LPCSTR, LPHANDLER_FUNCTION );
WINADVAPI SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerW
( LPCWSTR, LPHANDLER_FUNCTION );

#define RegisterServiceCtrlHandlerEx  \
__AW_SUFFIXED__(RegisterServiceCtrlHandlerEx)
WINADVAPI SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerExA
( LPCSTR, LPHANDLER_FUNCTION_EX, LPVOID );
WINADVAPI SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerExW
( LPCWSTR, LPHANDLER_FUNCTION_EX, LPVOID );

WINADVAPI BOOL WINAPI SetServiceObjectSecurity
( SC_HANDLE, SECURITY_INFORMATION, PSECURITY_DESCRIPTOR );

WINADVAPI BOOL WINAPI SetServiceStatus (SERVICE_STATUS_HANDLE, LPSERVICE_STATUS);

#define StartService  __AW_SUFFIXED__(StartService)
WINADVAPI BOOL WINAPI StartServiceA (SC_HANDLE, DWORD, LPCSTR *);
WINADVAPI BOOL WINAPI StartServiceW (SC_HANDLE, DWORD, LPCWSTR *);

#define StartServiceCtrlDispatcher  __AW_SUFFIXED__(StartServiceCtrlDispatcher)
WINADVAPI BOOL WINAPI StartServiceCtrlDispatcherA (LPSERVICE_TABLE_ENTRYA);
WINADVAPI BOOL WINAPI StartServiceCtrlDispatcherW (LPSERVICE_TABLE_ENTRYW);

WINADVAPI BOOL WINAPI UnlockServiceDatabase (SC_LOCK);

_END_C_DECLS

#endif	/* !_WINSVC_H: $RCSfile: winsvc.h,v $: end of file */
