/*++

Copyright (c) 1991  Microsoft Corporation

Module Name:

    svcctl.idl

Abstract:

    This is the IDL file that describes the RPC interface for the
    remotable NetService API.

Author:

    Dan Lafferty (danl)     03-Feb-1992

Environment:

    User Mode -Win32

Revision History:

    03-Feb-1992     danl
        Created

--*/

//
// Interface Attributes
//

[
    uuid(367ABB81-9844-35F1-AD32-98F038001003),
    version(2.0),
#ifdef __midl
	ms_union,
#endif // __midl
    pointer_default(unique)
]

//
// Interface Keyword
//

interface svcctl

//
// Interface Body
//

{
import   "imports.idl";

//
// Define handle types
//

typedef [handle]         wchar_t *  SVCCTL_HANDLEW;
typedef [handle]            LPSTR   SVCCTL_HANDLEA;
typedef [context_handle]    PVOID   SC_RPC_HANDLE;
typedef [context_handle]    PVOID   SC_RPC_LOCK;

typedef SC_RPC_HANDLE       *LPSC_RPC_HANDLE;
typedef SC_RPC_LOCK         *LPSC_RPC_LOCK;


//
// This Data Structure is used in specifying an array of string pointers
// used to pass command line arguments into StartService.
//

typedef struct _STRING_PTRSA {
    [string] LPSTR      StringPtr;
} STRING_PTRSA, *PSTRING_PTRSA, *LPSTRING_PTRSA;

typedef struct _STRING_PTRSW {
    [string] wchar_t  *  StringPtr;
} STRING_PTRSW, *PSTRING_PTRSW, *LPSTRING_PTRSW;

//////////////////////////////////////////////////////////////////////////////
// FUNCTION PROTOTYPES
//////////////////////////////////////////////////////////////////////////////


DWORD
RCloseServiceHandle(
    [in,out]  LPSC_RPC_HANDLE   hSCObject
    );

DWORD
RControlService(
    [in]    SC_RPC_HANDLE       hService,
    [in]    DWORD               dwControl,
    [out]   LPSERVICE_STATUS    lpServiceStatus
    );

DWORD
RDeleteService(
    [in]    SC_RPC_HANDLE       hService
    );

DWORD
RLockServiceDatabase(
    [in]        SC_RPC_HANDLE   hSCManager,
    [out]       LPSC_RPC_LOCK   lpLock
    );

DWORD
RQueryServiceObjectSecurity(
    [in]  SC_RPC_HANDLE             hService,
    [in]  SECURITY_INFORMATION      dwSecurityInformation,
    [out,size_is(cbBufSize)] LPBYTE lpSecurityDescriptor,
    [in]  DWORD                     cbBufSize,
    [out] LPDWORD                   pcbBytesNeeded
    );

DWORD
RSetServiceObjectSecurity(
    [in]  SC_RPC_HANDLE             hService,
    [in]  SECURITY_INFORMATION      dwSecurityInformation,
    [in,size_is(cbBufSize)] LPBYTE  lpSecurityDescriptor,
    [in]  DWORD                     cbBufSize
    );

DWORD
RQueryServiceStatus(
    [in]  SC_RPC_HANDLE     hService,
    [out] LPSERVICE_STATUS  lpServiceStatus
    );

DWORD
RSetServiceStatus(
    [in]    SC_RPC_HANDLE     hServiceStatus,
    [in]    LPSERVICE_STATUS  lpServiceStatus
    );

DWORD
RUnlockServiceDatabase(
    [in,out]    LPSC_RPC_LOCK       Lock
    );

DWORD
RNotifyBootConfigStatus(
    [in,string,unique] SVCCTL_HANDLEW   lpMachineName,
    [in]               DWORD            BootAcceptable
    );

//////////////////////////////////////////////////////////////////////////////
// UNICODE FUNCTION PROTOTYPES
//////////////////////////////////////////////////////////////////////////////

DWORD
RI_ScSetServiceBitsW(
    [in]    SC_RPC_HANDLE               hServiceStatus,
    [in]    DWORD                       dwServiceBits,
    [in]    DWORD                       bSetBitsOn,
    [in]    DWORD                       bUpdateImmediately,
    [in,string,unique] wchar_t *        pszTransportName
    );

DWORD
RChangeServiceConfigW(
    [in]    SC_RPC_HANDLE           hService,
    [in]    DWORD                   dwServiceType,
    [in]    DWORD                   dwStartType,
    [in]    DWORD                   dwErrorControl,
    [in,string,unique] wchar_t *    lpBinaryPathName,
    [in,string,unique] wchar_t *    lpLoadOrderGroup,
    [in,out,unique] LPDWORD         lpdwTagId,
    [in,unique,size_is(dwDependSize)] LPBYTE lpDependencies,
    [in]    DWORD                   dwDependSize,
    [in,string,unique] wchar_t *    lpServiceStartName,
    [in,unique,size_is(dwPwSize)] LPBYTE lpPassword,
    [in]        DWORD               dwPwSize,
    [in,string,unique] wchar_t *    lpDisplayName
    );

DWORD
RCreateServiceW(
    [in]        SC_RPC_HANDLE       hSCManager,
    [in,string] wchar_t *           lpServiceName,
    [in,string,unique] wchar_t *    lpDisplayName,
    [in]        DWORD               dwDesiredAccess,
    [in]        DWORD               dwServiceType,
    [in]        DWORD               dwStartType,
    [in]        DWORD               dwErrorControl,
    [in,string] wchar_t *           lpBinaryPathName,
    [in,string,unique] wchar_t *    lpLoadOrderGroup,
    [in,out,unique] LPDWORD         lpdwTagId,
    [in,unique,size_is(dwDependSize)] LPBYTE lpDependencies,
    [in]    DWORD                   dwDependSize,
    [in,string,unique] wchar_t *    lpServiceStartName,
    [in,unique,size_is(dwPwSize)] LPBYTE lpPassword,
    [in]        DWORD               dwPwSize,
    [out]       LPSC_RPC_HANDLE     lpServiceHandle
    );

DWORD
REnumDependentServicesW(
    [in]            SC_RPC_HANDLE   hService,
    [in]            DWORD           dwServiceState,
    [out,size_is(cbBufSize)] LPBYTE lpServices,
    [in]            DWORD           cbBufSize,
    [out]           LPDWORD         pcbBytesNeeded,
    [out]           LPDWORD         lpServicesReturned
    );

DWORD
REnumServicesStatusW(
    [in]  SC_RPC_HANDLE                 hSCManager,
    [in]  DWORD                         dwServiceType,
    [in]  DWORD                         dwServiceState,
    [out,size_is(cbBufSize)] LPBYTE     lpBuffer,
    [in]  DWORD                         cbBufSize,
    [out] LPDWORD                       pcbBytesNeeded,
    [out] LPDWORD                       lpServicesReturned,
    [in,out,unique] LPDWORD             lpResumeIndex
    );

DWORD
ROpenSCManagerW(
    [in,string,unique] SVCCTL_HANDLEW   lpMachineName,
    [in,string,unique] wchar_t *        lpDatabaseName,
    [in]        DWORD                   dwDesiredAccess,
    [out]       LPSC_RPC_HANDLE         lpScHandle
    );

DWORD
ROpenServiceW(
    [in]        SC_RPC_HANDLE   hSCManager,
    [in,string] wchar_t *       lpServiceName,
    [in]        DWORD           dwDesiredAccess,
    [out]       LPSC_RPC_HANDLE lpServiceHandle
    );

DWORD
RQueryServiceConfigW(
    [in]    SC_RPC_HANDLE           hService,
    [out]   LPQUERY_SERVICE_CONFIGW lpServiceConfig,
    [in]    DWORD                   cbBufSize,
    [out]   LPDWORD                 pcbBytesNeeded
    );

DWORD
RQueryServiceLockStatusW(
    [in]    SC_RPC_HANDLE                   hSCManager,
    [out]   LPQUERY_SERVICE_LOCK_STATUSW    lpLockStatus,
    [in]    DWORD                           cbBufSize,
    [out]   LPDWORD                         pcbBytesNeeded
    );

DWORD
RStartServiceW(
    [in] SC_RPC_HANDLE                          hService,
    [in] DWORD                                  argc,
    [in,unique,size_is(argc)] LPSTRING_PTRSW    argv
    );

DWORD
RGetServiceDisplayNameW(
    [in]                                  SC_RPC_HANDLE   hSCManager,
    [in,string]                           wchar_t *       lpServiceName,
    [out,string, size_is(*lpcchBuffer+1)] wchar_t *       lpDisplayName,
    [in,out]                              LPDWORD         lpcchBuffer
    );

DWORD
RGetServiceKeyNameW(
    [in]                                  SC_RPC_HANDLE   hSCManager,
    [in,string]                           wchar_t *       lpDisplayName,
    [out,string, size_is(*lpcchBuffer+1)] wchar_t *       lpServiceName,
    [in,out]                              LPDWORD         lpcchBuffer
    );



//////////////////////////////////////////////////////////////////////////////
// ANSI FUNCTION PROTOTYPES
//////////////////////////////////////////////////////////////////////////////


DWORD
RI_ScSetServiceBitsA(
    [in]    SC_RPC_HANDLE               hServiceStatus,
    [in]    DWORD                       dwServiceBits,
    [in]    DWORD                       bSetBitsOn,
    [in]    DWORD                       bUpdateImmediately,
    [in,out,string,unique] LPSTR        pszTransportName
    );

DWORD
RChangeServiceConfigA(
    [in]    SC_RPC_HANDLE       hService,
    [in]    DWORD               dwServiceType,
    [in]    DWORD               dwStartType,
    [in]    DWORD               dwErrorControl,
    [in,string,unique] LPSTR    lpBinaryPathName,
    [in,string,unique] LPSTR    lpLoadOrderGroup,
    [in,out,unique] LPDWORD     lpdwTagId,
    [in,unique,size_is(dwDependSize)] LPBYTE lpDependencies,
    [in]    DWORD                   dwDependSize,
    [in,string,unique] LPSTR    lpServiceStartName,
    [in,unique,size_is(dwPwSize)] LPBYTE lpPassword,
    [in]        DWORD           dwPwSize,
    [in,string,unique] LPSTR    lpDisplayName
    );

DWORD
RCreateServiceA(
    [in]        SC_RPC_HANDLE   hSCManager,
    [in,string] LPSTR           lpServiceName,
    [in,string,unique] LPSTR    lpDisplayName,
    [in]        DWORD           dwDesiredAccess,
    [in]        DWORD           dwServiceType,
    [in]        DWORD           dwStartType,
    [in]        DWORD           dwErrorControl,
    [in,string] LPSTR           lpBinaryPathName,
    [in,string,unique] LPSTR    lpLoadOrderGroup,
    [in,out,unique] LPDWORD     lpdwTagId,
    [in,unique,size_is(dwDependSize)] LPBYTE lpDependencies,
    [in]    DWORD                   dwDependSize,
    [in,string,unique] LPSTR      lpServiceStartName,
    [in,unique,size_is(dwPwSize)] LPBYTE lpPassword,
    [in]        DWORD           dwPwSize,
    [out]       LPSC_RPC_HANDLE lpServiceHandle
    );

DWORD
REnumDependentServicesA(
    [in]            SC_RPC_HANDLE   hService,
    [in]            DWORD           dwServiceState,
    [out,size_is(cbBufSize)] LPBYTE lpServices,
    [in]            DWORD           cbBufSize,
    [out]           LPDWORD         pcbBytesNeeded,
    [out]           LPDWORD         lpServicesReturned
    );

DWORD
REnumServicesStatusA(
    [in]  SC_RPC_HANDLE                 hSCManager,
    [in]  DWORD                         dwServiceType,
    [in]  DWORD                         dwServiceState,
    [out,size_is(cbBufSize)] LPBYTE     lpBuffer,
    [in]  DWORD                         cbBufSize,
    [out] LPDWORD                       pcbBytesNeeded,
    [out] LPDWORD                       lpServicesReturned,
    [in,out,unique] LPDWORD             lpResumeIndex
    );

DWORD
ROpenSCManagerA(
    [in,string,unique] SVCCTL_HANDLEA   lpMachineName,
    [in,string,unique] LPSTR            lpDatabaseName,
    [in]        DWORD                   dwDesiredAccess,
    [out]       LPSC_RPC_HANDLE         lpScHandle
    );

DWORD
ROpenServiceA(
    [in]        SC_RPC_HANDLE   hSCManager,
    [in,string] LPSTR           lpServiceName,
    [in]        DWORD           dwDesiredAccess,
    [out]       LPSC_RPC_HANDLE lpServiceHandle
    );

DWORD
RQueryServiceConfigA(
    [in]    SC_RPC_HANDLE           hService,
    [out]   LPQUERY_SERVICE_CONFIGA lpServiceConfig,
    [in]    DWORD                   cbBufSize,
    [out]   LPDWORD                 pcbBytesNeeded
    );

DWORD
RQueryServiceLockStatusA(
    [in]    SC_RPC_HANDLE                   hSCManager,
    [out]   LPQUERY_SERVICE_LOCK_STATUSA    lpLockStatus,
    [in]    DWORD                           cbBufSize,
    [out]   LPDWORD                         pcbBytesNeeded
    );

DWORD
RStartServiceA(
    [in] SC_RPC_HANDLE                          hService,
    [in] DWORD                                  argc,
    [in,unique,size_is(argc)] LPSTRING_PTRSA    argv
    );

DWORD
RGetServiceDisplayNameA(
    [in]                        SC_RPC_HANDLE   hSCManager,
    [in,string]                 LPSTR           lpServiceName,
    [out,string,
        size_is(*lpcchBuffer)]  LPSTR           lpDisplayName,
    [in,out]                    LPDWORD         lpcchBuffer
    );

DWORD
RGetServiceKeyNameA(
    [in]                        SC_RPC_HANDLE   hSCManager,
    [in,string]                 LPSTR           lpDisplayName,
    [out,string,
        size_is(*lpcchBuffer)]  LPSTR           lpKeyName,
    [in,out]                    LPDWORD         lpcchBuffer
    );


/////////////////////////////////////////////////////////////////////////////
// Functions below this point are not in Windows NT version 3.51 or earlier
/////////////////////////////////////////////////////////////////////////////

// Internal only
DWORD
RI_ScGetCurrentGroupStateW(
    [in]    SC_RPC_HANDLE               hSCManager,
    [in,string,unique] wchar_t *        pszGroupName,
    [out]   LPDWORD                     pdwCurrentState
    );

// Internal only
DWORD
REnumServiceGroupW(
    [in]  SC_RPC_HANDLE                 hSCManager,
    [in]  DWORD                         dwServiceType,
    [in]  DWORD                         dwServiceState,
    [out,size_is(cbBufSize)] LPBYTE     lpBuffer,
    [in]  DWORD                         cbBufSize,
    [out] LPDWORD                       pcbBytesNeeded,
    [out] LPDWORD                       lpServicesReturned,
    [in,out,unique] LPDWORD             lpResumeIndex,
    [in,string,unique] LPCWSTR          pszGroupName
    );

/////////////////////////////////////////////////////////////////////////////
// Functions below this point are not in Windows NT version 4.0 or earlier
//
// (Note that new functions must always be added at the end, otherwise
// function calls are mismatched when client and server talk different
// versions of the interface)
/////////////////////////////////////////////////////////////////////////////

//
// This is a union of all the types of pointers to input data that can be
// passed to ChangeServiceConfig2
//
typedef struct _SC_RPC_CONFIG_INFOA
{
    DWORD               dwInfoLevel;
    [switch_is(dwInfoLevel)] union
    {
    [case(1)]                       // SERVICE_CONFIG_DESCRIPTION
        LPSERVICE_DESCRIPTIONA     psd;
    [case(2)]                       // SERVICE_CONFIG_FAILURE_ACTIONS
        LPSERVICE_FAILURE_ACTIONSA psfa;
    };
} SC_RPC_CONFIG_INFOA;

typedef struct _SC_RPC_CONFIG_INFOW
{
    DWORD               dwInfoLevel;
    [switch_is(dwInfoLevel)] union
    {
    [case(1)]                       // SERVICE_CONFIG_DESCRIPTION
        LPSERVICE_DESCRIPTIONW     psd;
    [case(2)]                       // SERVICE_CONFIG_FAILURE_ACTIONS
        LPSERVICE_FAILURE_ACTIONSW psfa;
    };
} SC_RPC_CONFIG_INFOW;


DWORD
RChangeServiceConfig2A(
    [in]    SC_RPC_HANDLE           hService,
    [in]    SC_RPC_CONFIG_INFOA     Info
    );

DWORD
RChangeServiceConfig2W(
    [in]    SC_RPC_HANDLE           hService,
    [in]    SC_RPC_CONFIG_INFOW     Info
    );

DWORD
RQueryServiceConfig2A(
    [in]    SC_RPC_HANDLE           hService,
    [in]    DWORD                   dwInfoLevel,
    [out,size_is(cbBufSize)] LPBYTE lpBuffer,
    [in]    DWORD                   cbBufSize,
    [out]   LPDWORD                 pcbBytesNeeded
    );

DWORD
RQueryServiceConfig2W(
    [in]    SC_RPC_HANDLE           hService,
    [in]    DWORD                   dwInfoLevel,
    [out,size_is(cbBufSize)] LPBYTE lpBuffer,
    [in]    DWORD                   cbBufSize,
    [out]   LPDWORD                 pcbBytesNeeded
    );

DWORD
RQueryServiceStatusEx(
    [in]    SC_RPC_HANDLE           hService,
    [in]    SC_STATUS_TYPE          InfoLevel,
    [out,size_is(cbBufSize)] LPBYTE lpBuffer,
    [in]    DWORD                   cbBufSize,
    [out]   LPDWORD                 pcbBytesNeeded
    );

DWORD
REnumServicesStatusExA (
    [in]  SC_RPC_HANDLE              hSCManager,
    [in]  SC_ENUM_TYPE               InfoLevel,
    [in]  DWORD                      dwServiceType,
    [in]  DWORD                      dwServiceState,
    [out,size_is(cbBufSize)] LPBYTE  lpBuffer,
    [in]  DWORD                      cbBufSize,
    [out] LPDWORD                    pcbBytesNeeded,
    [out] LPDWORD                    lpServicesReturned,
    [in,out,unique] LPDWORD          lpResumeIndex,
    [in,string,unique] LPCSTR        pszGroupName
    );

DWORD
REnumServicesStatusExW (
    [in]  SC_RPC_HANDLE              hSCManager,
    [in]  SC_ENUM_TYPE               InfoLevel,
    [in]  DWORD                      dwServiceType,
    [in]  DWORD                      dwServiceState,
    [out,size_is(cbBufSize)] LPBYTE  lpBuffer,
    [in]  DWORD                      cbBufSize,
    [out] LPDWORD                    pcbBytesNeeded,
    [out] LPDWORD                    lpServicesReturned,
    [in,out,unique] LPDWORD          lpResumeIndex,
    [in,string,unique] LPCWSTR       pszGroupName
    );

/////////////////////////////////////////////////////////////////////////////
// Functions below this point are not in Windows NT version 5.0 or earlier
//
// (Note that new functions must always be added at the end, otherwise
// function calls are mismatched when client and server talk different
// versions of the interface)
/////////////////////////////////////////////////////////////////////////////

DWORD
RI_ScSendTSMessage (
    [in] SC_RPC_HANDLE               hSCManager,
    [in] DWORD                       OpCode,
    [in] DWORD                       dwEvent,
    [in] DWORD                       cbData,
    [in,size_is(cbData)] LPBYTE      lpData
    );


/////////////////////////////////////////////////////////////////////////////
//
// IN THE FUTURE .....
//
// MIDL will support marshalling structures directly into the user's buffer.
// To do this, the server side must know how big the buffer should be
// for the server code.  The server code must fill in the buffer.
// The [byte_count(bufferSize)] attribute is used in the .acf file to tell
// it the RPC server stub what size buffer needs to be allocated.
//
// byte_count is similar to all_nodes.  all_nodes tells the MIDL client stubs
// to allocate one buffer into which is unmarshall the entire tree.
// byte_count tells the MIDL client stubs to unmarshall the entire tree into
// the user-provided buffer using the buffer size limits specified with
// the attribute.
//
//
// The strange syntax below uses size_is to allow the .IDL file to stand
// alone (without the .acf file) and operate correctly using a DEC or HP
// MIDL compiler.  However, without the .ACF file,  the instructions in
// the .IDL file indicate that the top level structures will be placed
// in the users buffer, but the lower level data will be placed in MIDL
// allocated buffers.  - In a NON-all_nodes fashion.
//
// Note that cbBufSize/sizeof(ENUM_SERVICE_STATUS) will always be larger
// than lpServicesReturned.  The size_is attribute tells the server side
// how much memory to allocate in the case where there is no .acf file.
//
// After the next drop of the MIDL complier, Donna will still need to
// fix MIDL so that it allows size_is and byte_count to apply to the
// same parameter.  Perhaps we need approval from Dov.
//
//
//
//DWORD
//REnumServicesStatusW(
//    [in]  SC_RPC_HANDLE                 hSCManager,
//    [in]  DWORD                         dwServiceType,
//    [in]  DWORD                         dwServiceState,
//
//    [out,size_is(cbBufSize/sizeof(ENUM_SERVICE_STATUS),
//    length_is(*lpServicesReturned)] LPENUM_SERVICE_STATUS   lpServices,
//
//    [out] PDWORD                        pcbReturned,
//    [in]  DWORD                         cbBufSize,
//    [out] LPDWORD                       pcbBytesNeeded,
//    [out] LPDWORD                       lpServicesReturned,
//    [in,out,unique] LPDWORD             lpResumeHandle
//    );

}
