From 0f80d4b61966af776365486c139c3e6238b984d9 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Fri, 27 Feb 2015 01:16:40 +0300 Subject: [PATCH] services: Make RPC interface compatible with native. --- dlls/advapi32/service.c | 66 ++++- include/wine/svcctl.idl | 540 ++++++++++++++++++++++++++++++++++------ programs/services/rpc.c | 318 +++++++++++++++++++++-- 3 files changed, 819 insertions(+), 105 deletions(-) diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c index f2d37cacfd2..8e4dda89dec 100644 --- a/dlls/advapi32/service.c +++ b/dlls/advapi32/service.c @@ -150,8 +150,7 @@ static inline DWORD multisz_cb(LPCWSTR wmultisz) /****************************************************************************** * RPC connection with services.exe */ - -DECLSPEC_HIDDEN handle_t __RPC_USER MACHINE_HANDLEW_bind(MACHINE_HANDLEW MachineName) +static handle_t rpc_wstr_bind(RPC_WSTR str) { WCHAR transport[] = SVCCTL_TRANSPORT; WCHAR endpoint[] = SVCCTL_ENDPOINT; @@ -159,7 +158,7 @@ DECLSPEC_HIDDEN handle_t __RPC_USER MACHINE_HANDLEW_bind(MACHINE_HANDLEW Machine RPC_STATUS status; handle_t rpc_handle; - status = RpcStringBindingComposeW(NULL, transport, (RPC_WSTR)MachineName, endpoint, NULL, &binding_str); + status = RpcStringBindingComposeW(NULL, transport, str, endpoint, NULL, &binding_str); if (status != RPC_S_OK) { ERR("RpcStringBindingComposeW failed (%d)\n", (DWORD)status); @@ -178,11 +177,63 @@ DECLSPEC_HIDDEN handle_t __RPC_USER MACHINE_HANDLEW_bind(MACHINE_HANDLEW Machine return rpc_handle; } +static handle_t rpc_cstr_bind(RPC_CSTR str) +{ + RPC_CSTR transport = (RPC_CSTR)SVCCTL_TRANSPORTA; + RPC_CSTR endpoint = (RPC_CSTR)SVCCTL_ENDPOINTA; + RPC_CSTR binding_str; + RPC_STATUS status; + handle_t rpc_handle; + + status = RpcStringBindingComposeA(NULL, transport, str, endpoint, NULL, &binding_str); + if (status != RPC_S_OK) + { + ERR("RpcStringBindingComposeW failed (%d)\n", (DWORD)status); + return NULL; + } + + status = RpcBindingFromStringBindingA(binding_str, &rpc_handle); + RpcStringFreeA(&binding_str); + + if (status != RPC_S_OK) + { + ERR("Couldn't connect to services.exe: error code %u\n", (DWORD)status); + return NULL; + } + + return rpc_handle; +} + +DECLSPEC_HIDDEN handle_t __RPC_USER MACHINE_HANDLEA_bind(MACHINE_HANDLEA MachineName) +{ + return rpc_cstr_bind((RPC_CSTR)MachineName); +} + +DECLSPEC_HIDDEN void __RPC_USER MACHINE_HANDLEA_unbind(MACHINE_HANDLEA MachineName, handle_t h) +{ + RpcBindingFree(&h); +} + +DECLSPEC_HIDDEN handle_t __RPC_USER MACHINE_HANDLEW_bind(MACHINE_HANDLEW MachineName) +{ + return rpc_wstr_bind((RPC_WSTR)MachineName); +} + DECLSPEC_HIDDEN void __RPC_USER MACHINE_HANDLEW_unbind(MACHINE_HANDLEW MachineName, handle_t h) { RpcBindingFree(&h); } +DECLSPEC_HIDDEN handle_t __RPC_USER SVCCTL_HANDLEW_bind(SVCCTL_HANDLEW MachineName) +{ + return rpc_wstr_bind((RPC_WSTR)MachineName); +} + +DECLSPEC_HIDDEN void __RPC_USER SVCCTL_HANDLEW_unbind(SVCCTL_HANDLEW MachineName, handle_t h) +{ + RpcBindingFree(&h); +} + static LONG WINAPI rpc_filter(EXCEPTION_POINTERS *eptr) { return I_RpcExceptionFilter(eptr->ExceptionRecord->ExceptionCode); @@ -1387,7 +1438,7 @@ QueryServiceConfigW( SC_HANDLE hService, __TRY { - err = svcctl_QueryServiceConfigW(hService, &config); + err = svcctl_QueryServiceConfigW(hService, &config, cbBufSize, pcbBytesNeeded); } __EXCEPT(rpc_filter) { @@ -1745,9 +1796,6 @@ EnumServicesStatusExW( SC_HANDLE hmngr, SC_ENUM_TYPE level, DWORD type, DWORD st TRACE("%p %u 0x%x 0x%x %p %u %p %p %p %s\n", hmngr, level, type, state, buffer, size, needed, returned, resume_handle, debugstr_w(group)); - if (resume_handle) - FIXME("resume handle not supported\n"); - if (level != SC_ENUM_PROCESS_INFO) { SetLastError( ERROR_INVALID_LEVEL ); @@ -1768,8 +1816,8 @@ EnumServicesStatusExW( SC_HANDLE hmngr, SC_ENUM_TYPE level, DWORD type, DWORD st __TRY { - err = svcctl_EnumServicesStatusExW( hmngr, type, state, buffer, size, needed, - returned, group ); + err = svcctl_EnumServicesStatusExW( hmngr, SC_ENUM_PROCESS_INFO, type, state, buffer, size, needed, + returned, resume_handle, group ); } __EXCEPT(rpc_filter) { diff --git a/include/wine/svcctl.idl b/include/wine/svcctl.idl index 7409b17b30b..e8463b542ab 100644 --- a/include/wine/svcctl.idl +++ b/include/wine/svcctl.idl @@ -26,7 +26,9 @@ import "wtypes.idl"; */ cpp_quote("#include \"winsvc.h\"") cpp_quote("#define SVCCTL_TRANSPORT {'n','c','a','c','n','_','n','p',0}") +cpp_quote("#define SVCCTL_TRANSPORTA \"ncacn_np\"") cpp_quote("#define SVCCTL_ENDPOINT {'\\\\','p','i','p','e','\\\\','s','v','c','c','t','l',0}") +cpp_quote("#define SVCCTL_ENDPOINTA \"\\\\pipe\\\\svcctl\"") /* Not the Windows event name - if needed the true one can be found in Inside Windows */ cpp_quote("#define SVCCTL_STARTED_EVENT {'_','_','w','i','n','e','_','S','v','c','c','t','l','S','t','a','r','t','e','d',0}") @@ -57,13 +59,30 @@ interface svcctl { /* handle types */ typedef [handle] LPCWSTR MACHINE_HANDLEW; + typedef [handle] LPCSTR MACHINE_HANDLEA; + typedef [handle] LPCWSTR SVCCTL_HANDLEW; typedef [context_handle] void *SC_RPC_HANDLE; typedef [context_handle] void *SC_RPC_LOCK; + typedef [context_handle] void *SC_NOTIFY_RPC_HANDLE; + + typedef DWORD SECURITY_INFORMATION; /* undocumented access rights */ cpp_quote("#define SERVICE_SET_STATUS 0x8000") cpp_quote("#if 0 /* already defined in winsvc.h */") +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; @@ -90,8 +109,12 @@ typedef enum _SC_STATUS_TYPE { SC_STATUS_PROCESS_INFO = 0 } SC_STATUS_TYPE; +typedef struct _SERVICE_DESCRIPTIONA { + LPSTR lpDescription; +} SERVICE_DESCRIPTIONA,*LPSERVICE_DESCRIPTIONA; + typedef struct _SERVICE_DESCRIPTIONW { - LPWSTR lpDescription; + LPWSTR lpDescription; } SERVICE_DESCRIPTIONW,*LPSERVICE_DESCRIPTIONW; typedef enum _SC_ACTION_TYPE { @@ -106,6 +129,14 @@ typedef struct _SC_ACTION { DWORD Delay; } SC_ACTION,*LPSC_ACTION; +typedef struct _SERVICE_FAILURE_ACTIONSA { + DWORD dwResetPeriod; + [unique] LPSTR lpRebootMsg; + [unique] LPSTR lpCommand; + DWORD cActions; + [size_is(cActions)] SC_ACTION *lpsaActions; +} SERVICE_FAILURE_ACTIONSA,*LPSERVICE_FAILURE_ACTIONSA; + typedef struct _SERVICE_FAILURE_ACTIONSW { DWORD dwResetPeriod; [unique] LPWSTR lpRebootMsg; @@ -138,12 +169,46 @@ typedef struct _SERVICE_PRESHUTDOWN_INFO { #define SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO 6 #define SERVICE_CONFIG_PRESHUTDOWN_INFO 7 +#define SERVICE_NOTIFY_STATUS_CHANGE_1 1 +#define SERVICE_NOTIFY_STATUS_CHANGE_2 2 + typedef struct _ENUM_SERVICE_STATUSW { LPWSTR lpServiceName; LPWSTR lpDisplayName; SERVICE_STATUS ServiceStatus; } ENUM_SERVICE_STATUSW, *LPENUM_SERVICE_STATUSW; +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 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_ENUM_TYPE { + SC_ENUM_PROCESS_INFO = 0 +} SC_ENUM_TYPE; + cpp_quote("#endif") typedef struct _SERVICE_RPC_REQUIRED_PRIVILEGES_INFO { @@ -164,56 +229,151 @@ typedef struct _SC_RPC_CONFIG_INFOW { }; } SC_RPC_CONFIG_INFOW; - /* Compatible with Windows function 0x00 */ +typedef struct _SC_RPC_CONFIG_INFOA { + DWORD dwInfoLevel; + [switch_is(dwInfoLevel)] union { + [case(SERVICE_CONFIG_DESCRIPTION)] SERVICE_DESCRIPTIONA *descr; + [case(SERVICE_CONFIG_FAILURE_ACTIONS)] SERVICE_FAILURE_ACTIONSA *actions; + [case(SERVICE_CONFIG_DELAYED_AUTO_START_INFO)] SERVICE_DELAYED_AUTO_START_INFO *delayedstart; + [case(SERVICE_CONFIG_FAILURE_ACTIONS_FLAG)] SERVICE_FAILURE_ACTIONS_FLAG *actionsflag; + [case(SERVICE_CONFIG_SERVICE_SID_INFO)] SERVICE_SID_INFO *sid; + [case(SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO)] SERVICE_RPC_REQUIRED_PRIVILEGES_INFO *privinfo; + [case(SERVICE_CONFIG_PRESHUTDOWN_INFO)] SERVICE_PRESHUTDOWN_INFO *preshutdown; + }; +} SC_RPC_CONFIG_INFOA; + +typedef struct _SERVICE_NOTIFY_STATUS_CHANGE_PARAMS_1 { + ULONGLONG ullThreadId; + DWORD dwNotifyMask; + UCHAR CallbackAddressArray[16]; + UCHAR CallbackParamAddressArray[16]; + SERVICE_STATUS_PROCESS ServiceStatus; + DWORD dwNotificationStatus; + DWORD dwSequence; +} SERVICE_NOTIFY_STATUS_CHANGE_PARAMS_1, *PSERVICE_NOTIFY_STATUS_CHANGE_PARAMS_1; + +typedef struct _SERVICE_NOTIFY_STATUS_CHANGE_PARAMS_2 { + ULONGLONG ullThreadId; + DWORD dwNotifyMask; + UCHAR CallbackAddressArray[16]; + UCHAR CallbackParamAddressArray[16]; + SERVICE_STATUS_PROCESS ServiceStatus; + DWORD dwNotificationStatus; + DWORD dwSequence; + DWORD dwNotificationTriggered; + [string] LPWSTR pszServiceNames; +} SERVICE_NOTIFY_STATUS_CHANGE_PARAMS_2, *PSERVICE_NOTIFY_STATUS_CHANGE_PARAMS_2; + +typedef struct _SC_RPC_NOTIFY_PARAMS { + DWORD dwInfoLevel; + [switch_is(dwInfoLevel)] union { + [case(SERVICE_NOTIFY_STATUS_CHANGE_1)] SERVICE_NOTIFY_STATUS_CHANGE_PARAMS_1 *params1; + [case(SERVICE_NOTIFY_STATUS_CHANGE_2)] SERVICE_NOTIFY_STATUS_CHANGE_PARAMS_2 *params; + }; +} SC_RPC_NOTIFY_PARAMS; + +typedef struct _SC_RPC_NOTIFY_PARAMS_LIST { + DWORD cElements; + [size_is(cElements)] SC_RPC_NOTIFY_PARAMS NotifyParamsArray[]; +} SC_RPC_NOTIFY_PARAMS_LIST, *PSC_RPC_NOTIFY_PARAMS_LIST; + +typedef struct _SERVICE_CONTROL_STATUS_REASON_IN_PARAMSA { + DWORD dwReason; + [string] LPSTR pszComment; +} SERVICE_CONTROL_STATUS_REASON_IN_PARAMSA, *PSERVICE_CONTROL_STATUS_REASON_IN_PARAMSA; + +typedef struct _SERVICE_CONTROL_STATUS_REASON_IN_PARAMSW { + DWORD dwReason; + [string] LPWSTR pszComment; +} SERVICE_CONTROL_STATUS_REASON_IN_PARAMSW, *PSERVICE_CONTROL_STATUS_REASON_IN_PARAMSW; + +typedef [switch_type(DWORD)] union _SC_RPC_SERVICE_CONTROL_IN_PARAMSA { + [case(1)] PSERVICE_CONTROL_STATUS_REASON_IN_PARAMSA psrInParams; +} SC_RPC_SERVICE_CONTROL_IN_PARAMSA, *PSC_RPC_SERVICE_CONTROL_IN_PARAMSA; + +typedef [switch_type(DWORD)] union _SC_RPC_SERVICE_CONTROL_IN_PARAMSW { + [case(1)] PSERVICE_CONTROL_STATUS_REASON_IN_PARAMSW psrInParams; +} SC_RPC_SERVICE_CONTROL_IN_PARAMSW, *PSC_RPC_SERVICE_CONTROL_IN_PARAMSW; + +typedef struct _SERVICE_CONTROL_STATUS_REASON_OUT_PARAMS { + SERVICE_STATUS_PROCESS ServiceStatus; +} SERVICE_CONTROL_STATUS_REASON_OUT_PARAMS, *PSERVICE_CONTROL_STATUS_REASON_OUT_PARAMS; + +typedef [switch_type(DWORD)] union _SC_RPC_SERVICE_CONTROL_OUT_PARAMSA { + [case(1)] PSERVICE_CONTROL_STATUS_REASON_OUT_PARAMS psrOutParams; +} SC_RPC_SERVICE_CONTROL_OUT_PARAMSA, *PSC_RPC_SERVICE_CONTROL_OUT_PARAMSA; + +typedef [switch_type(DWORD)] union _SC_RPC_SERVICE_CONTROL_OUT_PARAMSW { + [case(1)] PSERVICE_CONTROL_STATUS_REASON_OUT_PARAMS psrOutParams; +} SC_RPC_SERVICE_CONTROL_OUT_PARAMSW, *PSC_RPC_SERVICE_CONTROL_OUT_PARAMSW; + + /* Function 0 */ DWORD svcctl_CloseServiceHandle( [in,out] SC_RPC_HANDLE *handle ); - /* Compatible with Windows function 0x01 */ + /* Function 1 */ DWORD svcctl_ControlService( [in] SC_RPC_HANDLE hService, [in] DWORD dwControl, [out] SERVICE_STATUS *lpServiceStatus ); - /* Compatible with Windows function 0x02 */ + /* Function 2 */ DWORD svcctl_DeleteService( [in] SC_RPC_HANDLE hService ); - /* Compatible with Windows function 0x03 */ + /* Function 3 */ DWORD svcctl_LockServiceDatabase( [in] SC_RPC_HANDLE hSCManager, [out] SC_RPC_LOCK *phLock ); - /* Not compatible with Windows function 0x04 */ - DWORD svcctl_QueryServiceObjectSecurity(/* FIXME */); + /* Function 4 */ + DWORD svcctl_QueryServiceObjectSecurity( + [in] SC_RPC_HANDLE service, + [in] SECURITY_INFORMATION info, + [out, size_is(buf_size)] BYTE *descriptor, + [in] DWORD buf_size, + [out] DWORD *needed_size + ); - /* Not compatible with Windows function 0x05 */ - DWORD svcctl_SetServiceObjectSecurity(/* FIXME */); + /* Function 5 */ + DWORD svcctl_SetServiceObjectSecurity( + [in] SC_RPC_HANDLE service, + [in] SECURITY_INFORMATION info, + [in, size_is(buf_size)] BYTE *descriptor, + [in] DWORD buf_size + ); - /* Not compatible with Windows function 0x06 */ - DWORD svcctl_QueryServiceStatus(/* FIXME */); + /* Function 6 */ + DWORD svcctl_QueryServiceStatus( + [in] SC_RPC_HANDLE service, + [out] SERVICE_STATUS *status + ); - /* Compatible with Windows function 0x07 */ + /* Function 7 */ DWORD svcctl_SetServiceStatus( [in] SC_RPC_HANDLE hServiceStatus, [in] LPSERVICE_STATUS lpServiceStatus ); - /* Compatible with Windows function 0x08 */ + /* Function 8 */ DWORD svcctl_UnlockServiceDatabase( [in,out] SC_RPC_LOCK *phLock ); - /* Not compatible with Windows function 0x09 */ - DWORD svcctl_NotifyBootConfigStatus(/* FIXME */); + /* Function 9 */ + DWORD svcctl_NotifyBootConfigStatus( + [in, string, unique] SVCCTL_HANDLEW machinename, + [in] DWORD boot_acceptable + ); - /* Not compatible with Windows function 0x0a */ + /* Not compatible with Windows function 10 */ DWORD svcctl_SCSetServiceBitsW(/* FIXME */); - /* Compatible with Windows function 0x0b */ + /* Function 11 */ DWORD svcctl_ChangeServiceConfigW( [in] SC_RPC_HANDLE hService, [in] DWORD dwServiceType, @@ -230,7 +390,7 @@ typedef struct _SC_RPC_CONFIG_INFOW { [in,unique] LPCWSTR lpDisplayName ); - /* Compatible with Windows function 0x0c */ + /* Function 12 */ DWORD svcctl_CreateServiceW( [in] SC_RPC_HANDLE hSCManager, [in] LPCWSTR lpServiceName, @@ -250,10 +410,17 @@ typedef struct _SC_RPC_CONFIG_INFOW { [out] SC_RPC_HANDLE *phService ); - /* Not compatible with Windows function 0x0d */ - DWORD svcctl_EnumDependentServicesW(/* FIXME */); + /* Function 13 */ + DWORD svcctl_EnumDependentServicesW( + [in] SC_RPC_HANDLE service, + [in] DWORD state, + [out, size_is(buf_size)] BYTE *services, + [in] DWORD buf_size, + [out] DWORD *needed_size, + [out] DWORD *services_ret + ); - /* Compatible with Windows function 0x0e */ + /* Function 14 */ DWORD svcctl_EnumServicesStatusW( [in] SC_RPC_HANDLE hmngr, [in] DWORD type, @@ -265,7 +432,7 @@ typedef struct _SC_RPC_CONFIG_INFOW { [in,out,unique] LPDWORD resume ); - /* Compatible with Windows function 0x0f */ + /* Function 15 */ DWORD svcctl_OpenSCManagerW( [in,unique] MACHINE_HANDLEW MachineName, [in,unique] LPCWSTR DatabaseName, @@ -273,7 +440,7 @@ typedef struct _SC_RPC_CONFIG_INFOW { [out] SC_RPC_HANDLE *handle ); - /* Compatible with Windows function 0x10 */ + /* Function 16 */ DWORD svcctl_OpenServiceW( [in] SC_RPC_HANDLE hSCManager, [in] LPCWSTR lpServiceName, @@ -281,89 +448,194 @@ typedef struct _SC_RPC_CONFIG_INFOW { [out] SC_RPC_HANDLE *phService ); - /* Windows function 0x11 must be using a different prototype - not compatible */ + /* Function 17 */ DWORD svcctl_QueryServiceConfigW( [in] SC_RPC_HANDLE hService, - [out] QUERY_SERVICE_CONFIGW *config); + [out] QUERY_SERVICE_CONFIGW *config, + [in] DWORD buf_size, + [out] DWORD *needed_size); - /* Not compatible with Windows function 0x12 */ - DWORD svcctl_QueryServiceLockStatusW(/* FIXME */); + /* Function 18 */ + DWORD svcctl_QueryServiceLockStatusW( + [in] SC_RPC_HANDLE scmanager, + [out] QUERY_SERVICE_LOCK_STATUSW *status, + [in] DWORD buf_size, + [out] DWORD *needed_size + ); - /* Untested with Windows function 0x13 */ + /* Function 19 */ DWORD svcctl_StartServiceW( [in] SC_RPC_HANDLE hService, [in] DWORD dwNumServiceArgs, [in,unique,size_is(dwNumServiceArgs)] LPCWSTR *lpServiceArgVectors ); - /* Compatible with Windows function 0x14 */ + /* Function 20 */ DWORD svcctl_GetServiceDisplayNameW( [in] SC_RPC_HANDLE hSCManager, [in] LPCWSTR lpServiceName, [out,string,size_is(*cchBufSize+1)] WCHAR lpBuffer[], [in,out] DWORD *cchBufSize); - /* Compatible with Windows function 0x15 */ + /* Function 21 */ DWORD svcctl_GetServiceKeyNameW( [in] SC_RPC_HANDLE hSCManager, [in] LPCWSTR lpServiceDisplayName, [out,string,size_is(*cchBufSize+1)] WCHAR lpBuffer[], [in,out] DWORD *cchBufSize); - /* Not compatible with Windows function 0x16 */ + /* Not compatible with Windows function 22 */ DWORD svcctl_SCSetServiceBitsA(/* FIXME */); - /* Not compatible with Windows function 0x17 */ - DWORD svcctl_ChangeServiceConfigA(/* FIXME */); + /* Function 23 */ + DWORD svcctl_ChangeServiceConfigA( + [in] SC_RPC_HANDLE service, + [in] DWORD service_type, + [in] DWORD start_type, + [in] DWORD error_control, + [in, string, unique] LPSTR binarypath, + [in, string, unique] LPSTR loadordergroup, + [in, out, unique] DWORD *tagid, + [in, unique, size_is(depend_size)] BYTE *dependencies, + [in] DWORD depend_size, + [in, string, unique] LPSTR startname, + [in, unique, size_is(password_size)] BYTE *password, + [in] DWORD password_size, + [in, string, unique] LPSTR displayname + ); - /* Not compatible with Windows function 0x18 */ - DWORD svcctl_CreateServiceA(/* FIXME */); + /* Function 24 */ + DWORD svcctl_CreateServiceA( + [in] SC_RPC_HANDLE scmanager, + [in] LPCSTR servicename, + [in, unique] LPCSTR displayname, + [in] DWORD desiredaccess, + [in] DWORD service_type, + [in] DWORD start_type, + [in] DWORD error_control, + [in] LPCSTR binarypath, + [in, unique] LPCSTR loadordergroup, + [in, out, unique] DWORD *tagid, + [in, unique, size_is(depend_size)] const BYTE *dependencies, + [in] DWORD depend_size, + [in, unique] LPCSTR startname, + [in, unique, size_is(password_size)] const BYTE *password, + [in] DWORD password_size, + [out] SC_RPC_HANDLE *service + ); - /* Not compatible with Windows function 0x19 */ - DWORD svcctl_EnumDependentServicesA(/* FIXME */); + /* Function 25 */ + DWORD svcctl_EnumDependentServicesA( + [in] SC_RPC_HANDLE service, + [in] DWORD state, + [out, size_is(buf_size)] BYTE *services, + [in] DWORD buf_size, + [out] DWORD *needed_size, + [out] DWORD *services_ret + ); - /* Not compatible with Windows function 0x1a */ - DWORD svcctl_EnumServicesStatusA(/* FIXME */); + /* Function 26 */ + DWORD svcctl_EnumServicesStatusA( + [in] SC_RPC_HANDLE hmngr, + [in] DWORD type, + [in] DWORD state, + [out, size_is(size)] BYTE *buffer, + [in] DWORD size, + [out] DWORD *needed, + [out] DWORD *returned, + [in,out,unique] DWORD *resume + ); - /* Not compatible with Windows function 0x1b */ - DWORD svcctl_OpenSCManagerA(/* FIXME */); + /* Function 27 */ + DWORD svcctl_OpenSCManagerA( + [in,unique] MACHINE_HANDLEA MachineName, + [in,unique] LPCSTR DatabaseName, + [in] DWORD dwAccessMask, + [out] SC_RPC_HANDLE *handle + ); - /* Not compatible with Windows function 0x1c */ - DWORD svcctl_OpenServiceA(/* FIXME */); + /* Function 28 */ + DWORD svcctl_OpenServiceA( + [in] SC_RPC_HANDLE hSCManager, + [in] LPCSTR lpServiceName, + [in] DWORD dwDesiredAccess, + [out] SC_RPC_HANDLE *phService + ); - /* Not compatible with Windows function 0x1d */ - DWORD svcctl_QueryServiceConfigA(/* FIXME */); + /* Function 29 */ + DWORD svcctl_QueryServiceConfigA( + [in] SC_RPC_HANDLE hService, + [out] QUERY_SERVICE_CONFIGA *config, + [in] DWORD buf_size, + [out] DWORD *needed_size); - /* Not compatible with Windows function 0x1e */ - DWORD svcctl_QueryServiceLockStatusA(/* FIXME */); + /* Function 30 */ + DWORD svcctl_QueryServiceLockStatusA( + [in] SC_RPC_HANDLE scmanager, + [out] QUERY_SERVICE_LOCK_STATUSA *status, + [in] DWORD buf_size, + [out] DWORD *needed_size + ); - /* Not compatible with Windows function 0x1f */ - DWORD svcctl_StartServiceA(/* FIXME */); + /* Function 31 */ + DWORD svcctl_StartServiceA( + [in] SC_RPC_HANDLE service, + [in] DWORD argc, + [in, unique, size_is(argc)] LPCSTR *args + ); - /* Not compatible with Windows function 0x20 */ - DWORD svcctl_GetServiceDisplayNameA(/* FIXME */); + /* Function 32 */ + DWORD svcctl_GetServiceDisplayNameA( + [in] SC_RPC_HANDLE hSCManager, + [in] LPCSTR servicename, + [out, string, size_is(*buf_size+1)] CHAR buffer[], + [in, out] DWORD *buf_size); - /* Not compatible with Windows function 0x21 */ - DWORD svcctl_GetServiceKeyNameA(/* FIXME */); + /* Function 33 */ + DWORD svcctl_GetServiceKeyNameA( + [in] SC_RPC_HANDLE hSCManager, + [in] LPCSTR servicename, + [out, string, size_is(*buf_size+1)] CHAR buffer[], + [in, out] DWORD *buf_size); - /* Not compatible with Windows function 0x22 */ + /* Not compatible with Windows function 34 */ DWORD svcctl_GetCurrentGroupStateW(/* FIXME */); - /* Not compatible with Windows function 0x23 */ - DWORD svcctl_EnumServiceGroupW(/* FIXME */); + /* Function 35 */ + DWORD svcctl_EnumServiceGroupW( + [in] SC_RPC_HANDLE scmanager, + [in] DWORD service_type, + [in] DWORD service_state, + [out, size_is(buf_size)] BYTE *buffer, + [in] DWORD buf_size, + [out] DWORD *needed_size, + [out] DWORD *returned_size, + [in, out, unique] DWORD *resume_index, + [in, string, unique] LPCWSTR groupname + ); - /* Not compatible with Windows function 0x24 */ - DWORD svcctl_ChangeServiceConfig2A(/* FIXME */); + /* Function 36 */ + DWORD svcctl_ChangeServiceConfig2A( + [in] SC_RPC_HANDLE service, + [in] SC_RPC_CONFIG_INFOA info + ); - /* Compatible with Windows function 0x25 */ + /* Function 37 */ DWORD svcctl_ChangeServiceConfig2W( - [in] SC_RPC_HANDLE hService, - [in] SC_RPC_CONFIG_INFOW config); + [in] SC_RPC_HANDLE service, + [in] SC_RPC_CONFIG_INFOW info + ); - /* Not compatible with Windows function 0x26 */ - DWORD svcctl_QueryServiceConfig2A(/* FIXME */); + /* Function 38 */ + DWORD svcctl_QueryServiceConfig2A( + [in] SC_RPC_HANDLE service, + [in] DWORD info_level, + [out, size_is(buf_size)] BYTE *buffer, + [in] DWORD buf_size, + [out] DWORD *needed_size + ); - /* Untested with Windows function 0x27 */ + /* Function 39 */ DWORD svcctl_QueryServiceConfig2W( [in] SC_RPC_HANDLE hService, [in] DWORD InfoLevel, @@ -372,7 +644,7 @@ typedef struct _SC_RPC_CONFIG_INFOW { [out] LPDWORD pcbBytesNeeded ); - /* Untested with Windows function 0x28 */ + /* Function 40 */ DWORD svcctl_QueryServiceStatusEx( [in] SC_RPC_HANDLE hService, [in] SC_STATUS_TYPE InfoLevel, @@ -381,14 +653,136 @@ typedef struct _SC_RPC_CONFIG_INFOW { [out] LPDWORD pcbBytesNeeded ); + /* Function 41 */ + DWORD svcctl_EnumServicesStatusExA( + [in] SC_RPC_HANDLE scmanager, + [in] SC_ENUM_TYPE info_level, + [in] DWORD service_type, + [in] DWORD service_state, + [out, size_is(buf_size)] BYTE *buffer, + [in] DWORD buf_size, + [out] DWORD *needed_size, + [out] DWORD *services_count, + [in, out, unique] DWORD *resume_index, + [in, string, unique] LPCSTR groupname + ); + + /* Function 42 */ DWORD svcctl_EnumServicesStatusExW( - [in] SC_RPC_HANDLE hmngr, - [in] DWORD type, - [in] DWORD state, - [out,size_is(size)] BYTE *buffer, - [in] DWORD size, - [out] LPDWORD needed, - [out] LPDWORD returned, - [in,unique] LPCWSTR group + [in] SC_RPC_HANDLE scmanager, + [in] SC_ENUM_TYPE info_level, + [in] DWORD service_type, + [in] DWORD service_state, + [out, size_is(buf_size)] BYTE *buffer, + [in] DWORD buf_size, + [out] DWORD *needed_size, + [out] DWORD *services_count, + [in, out, unique] DWORD *resume_index, + [in, string, unique] LPCWSTR groupname + ); + + /* Not compatible with Windows function 43 */ + DWORD svcctl_unknown43(/*FIXME*/); + + /* Function 44 */ + DWORD svcctl_CreateServiceWOW64A( + [in] SC_RPC_HANDLE scmanager, + [in, string] LPCSTR servicename, + [in, string, unique] LPCSTR displayname, + [in] DWORD accessmask, + [in] DWORD service_type, + [in] DWORD start_type, + [in] DWORD error_control, + [in, string] LPCSTR imagepath, + [in, string, unique] LPCSTR loadordergroup, + [in, out, unique] DWORD *tagid, + [in, unique, size_is(depend_size)] const BYTE *dependencies, + [in] DWORD depend_size, + [in, string, unique] LPCSTR start_name, + [in, unique, size_is(password_size)] const BYTE *password, + [in] DWORD password_size, + [out] SC_RPC_HANDLE *service + ); + + /* Function 45 */ + DWORD svcctl_CreateServiceWOW64W( + [in] SC_RPC_HANDLE scmanager, + [in, string] LPCWSTR servicename, + [in, string, unique] LPCWSTR displayname, + [in] DWORD accessmask, + [in] DWORD service_type, + [in] DWORD start_type, + [in] DWORD error_control, + [in, string] LPCWSTR imagepath, + [in, string, unique] LPCWSTR loadordergroup, + [in, out, unique] DWORD *tagid, + [in, unique, size_is(depend_size)] const BYTE *dependencies, + [in] DWORD depend_size, + [in, string, unique] LPCWSTR start_name, + [in, unique, size_is(password_size)] const BYTE *password, + [in] DWORD password_size, + [out] SC_RPC_HANDLE *service + ); + + /* Not compatible with Windows function 46 */ + DWORD svcctl_unknown46(/*FIXME*/); + + /* Function 47 */ + DWORD svcctl_NotifyServiceStatusChange( + [in] SC_RPC_HANDLE service, + [in] SC_RPC_NOTIFY_PARAMS params, + [in] GUID *clientprocessguid, + [out] GUID *scmprocessguid, + [out] BOOL *createremotequeue, + [out] SC_NOTIFY_RPC_HANDLE *notify + ); + + /* Function 48 */ + DWORD svcctl_GetNotifyResults( + [in] SC_NOTIFY_RPC_HANDLE notify, + [out] SC_RPC_NOTIFY_PARAMS_LIST *params + ); + + /* Function 49 */ + DWORD svcctl_CloseNotifyHandle( + [in, out] SC_NOTIFY_RPC_HANDLE *notify, + [out] BOOL *apc_fired + ); + + /* Function 50 */ + DWORD svcctl_ControlServiceExA( + [in] SC_RPC_HANDLE service, + [in] DWORD control, + [in] DWORD info_level, + [in, switch_is(info_level)] SC_RPC_SERVICE_CONTROL_IN_PARAMSA *in_params, + [out, switch_is(info_level)] SC_RPC_SERVICE_CONTROL_OUT_PARAMSA *out_params + ); + + /* Function 51 */ + DWORD svcctl_ControlServiceExW( + [in] SC_RPC_HANDLE service, + [in] DWORD control, + [in] DWORD info_level, + [in, switch_is(info_level)] SC_RPC_SERVICE_CONTROL_IN_PARAMSW *in_params, + [out, switch_is(info_level)] SC_RPC_SERVICE_CONTROL_OUT_PARAMSW *out_params + ); + + /* Not compatible with Windows function 52 */ + DWORD svcctl_unknown52(); + + /* Not compatible with Windows function 53 */ + DWORD svcctl_unknown53(); + + /* Not compatible with Windows function 54 */ + DWORD svcctl_unknown54(); + + /* Not compatible with Windows function 55 */ + DWORD svcctl_unknown55(); + + /* Function 56 */ + DWORD svcctl_QueryServiceConfigEx( + [in] SC_RPC_HANDLE service, + [in] DWORD info_level, + [out] SC_RPC_CONFIG_INFOW *info ); } diff --git a/programs/services/rpc.c b/programs/services/rpc.c index 0d74b5ba27a..d8ae11759e3 100644 --- a/programs/services/rpc.c +++ b/programs/services/rpc.c @@ -585,7 +585,9 @@ DWORD __cdecl svcctl_DeleteService( DWORD __cdecl svcctl_QueryServiceConfigW( SC_RPC_HANDLE hService, - QUERY_SERVICE_CONFIGW *config) + QUERY_SERVICE_CONFIGW *config, + DWORD buf_size, + DWORD *needed_size) { struct sc_service_handle *service; DWORD err; @@ -1367,14 +1369,32 @@ static BOOL match_group(const WCHAR *g1, const WCHAR *g2) return FALSE; } +DWORD __cdecl svcctl_EnumServicesStatusExA( + SC_RPC_HANDLE scmanager, + SC_ENUM_TYPE info_level, + DWORD service_type, + DWORD service_state, + BYTE *buffer, + DWORD buf_size, + DWORD *needed_size, + DWORD *services_count, + DWORD *resume_index, + LPCSTR groupname) +{ + WINE_FIXME("\n"); + return ERROR_CALL_NOT_IMPLEMENTED; +} + DWORD __cdecl svcctl_EnumServicesStatusExW( SC_RPC_HANDLE hmngr, + SC_ENUM_TYPE info_level, DWORD type, DWORD state, BYTE *buffer, DWORD size, LPDWORD needed, LPDWORD returned, + DWORD *resume_handle, LPCWSTR group) { DWORD err, sz, total_size, num_services; @@ -1386,6 +1406,9 @@ DWORD __cdecl svcctl_EnumServicesStatusExW( WINE_TRACE("(%p, 0x%x, 0x%x, %p, %u, %p, %p, %s)\n", hmngr, type, state, buffer, size, needed, returned, wine_dbgstr_w(group)); + if (resume_handle) + FIXME("resume handle not supported\n"); + if (!type || !state) return ERROR_INVALID_PARAMETER; @@ -1452,26 +1475,177 @@ DWORD __cdecl svcctl_EnumServicesStatusExW( return ERROR_SUCCESS; } -DWORD __cdecl svcctl_QueryServiceObjectSecurity(void) +DWORD __cdecl svcctl_unknown43(void) { WINE_FIXME("\n"); return ERROR_CALL_NOT_IMPLEMENTED; } -DWORD __cdecl svcctl_SetServiceObjectSecurity(void) +DWORD __cdecl svcctl_CreateServiceWOW64A( + SC_RPC_HANDLE scmanager, + LPCSTR servicename, + LPCSTR displayname, + DWORD accessmask, + DWORD service_type, + DWORD start_type, + DWORD error_control, + LPCSTR imagepath, + LPCSTR loadordergroup, + DWORD *tagid, + const BYTE *dependencies, + DWORD depend_size, + LPCSTR start_name, + const BYTE *password, + DWORD password_size, + SC_RPC_HANDLE *service) { WINE_FIXME("\n"); return ERROR_CALL_NOT_IMPLEMENTED; } -DWORD __cdecl svcctl_QueryServiceStatus(void) +DWORD __cdecl svcctl_CreateServiceWOW64W( + SC_RPC_HANDLE scmanager, + LPCWSTR servicename, + LPCWSTR displayname, + DWORD accessmask, + DWORD service_type, + DWORD start_type, + DWORD error_control, + LPCWSTR imagepath, + LPCWSTR loadordergroup, + DWORD *tagid, + const BYTE *dependencies, + DWORD depend_size, + LPCWSTR start_name, + const BYTE *password, + DWORD password_size, + SC_RPC_HANDLE *service) { WINE_FIXME("\n"); return ERROR_CALL_NOT_IMPLEMENTED; } +DWORD __cdecl svcctl_unknown46(void) +{ + WINE_FIXME("\n"); + return ERROR_CALL_NOT_IMPLEMENTED; +} -DWORD __cdecl svcctl_NotifyBootConfigStatus(void) +DWORD __cdecl svcctl_NotifyServiceStatusChange( + SC_RPC_HANDLE service, + SC_RPC_NOTIFY_PARAMS params, + GUID *clientprocessguid, + GUID *scmprocessguid, + BOOL *createremotequeue, + SC_NOTIFY_RPC_HANDLE *notify) +{ + WINE_FIXME("\n"); + return ERROR_CALL_NOT_IMPLEMENTED; +} + +DWORD __cdecl svcctl_GetNotifyResults( + SC_NOTIFY_RPC_HANDLE notify, + SC_RPC_NOTIFY_PARAMS_LIST *params) +{ + WINE_FIXME("\n"); + return ERROR_CALL_NOT_IMPLEMENTED; +} + +DWORD __cdecl svcctl_CloseNotifyHandle( + SC_NOTIFY_RPC_HANDLE *notify, + BOOL *apc_fired) +{ + WINE_FIXME("\n"); + return ERROR_CALL_NOT_IMPLEMENTED; +} + +DWORD __cdecl svcctl_ControlServiceExA( + SC_RPC_HANDLE service, + DWORD control, + DWORD info_level, + SC_RPC_SERVICE_CONTROL_IN_PARAMSA *in_params, + SC_RPC_SERVICE_CONTROL_OUT_PARAMSA *out_params) +{ + WINE_FIXME("\n"); + return ERROR_CALL_NOT_IMPLEMENTED; +} + +DWORD __cdecl svcctl_ControlServiceExW( + SC_RPC_HANDLE service, + DWORD control, + DWORD info_level, + SC_RPC_SERVICE_CONTROL_IN_PARAMSW *in_params, + SC_RPC_SERVICE_CONTROL_OUT_PARAMSW *out_params) +{ + WINE_FIXME("\n"); + return ERROR_CALL_NOT_IMPLEMENTED; +} + +DWORD __cdecl svcctl_unknown52(void) +{ + WINE_FIXME("\n"); + return ERROR_CALL_NOT_IMPLEMENTED; +} + +DWORD __cdecl svcctl_unknown53(void) +{ + WINE_FIXME("\n"); + return ERROR_CALL_NOT_IMPLEMENTED; +} + +DWORD __cdecl svcctl_unknown54(void) +{ + WINE_FIXME("\n"); + return ERROR_CALL_NOT_IMPLEMENTED; +} + +DWORD __cdecl svcctl_unknown55(void) +{ + WINE_FIXME("\n"); + return ERROR_CALL_NOT_IMPLEMENTED; +} + +DWORD __cdecl svcctl_QueryServiceConfigEx( + SC_RPC_HANDLE service, + DWORD info_level, + SC_RPC_CONFIG_INFOW *info) +{ + WINE_FIXME("\n"); + return ERROR_CALL_NOT_IMPLEMENTED; +} + +DWORD __cdecl svcctl_QueryServiceObjectSecurity( + SC_RPC_HANDLE service, + SECURITY_INFORMATION info, + BYTE *descriptor, + DWORD buf_size, + DWORD *needed_size) +{ + WINE_FIXME("\n"); + return ERROR_CALL_NOT_IMPLEMENTED; +} + +DWORD __cdecl svcctl_SetServiceObjectSecurity( + SC_RPC_HANDLE service, + SECURITY_INFORMATION info, + BYTE *descriptor, + DWORD buf_size) +{ + WINE_FIXME("\n"); + return ERROR_CALL_NOT_IMPLEMENTED; +} + +DWORD __cdecl svcctl_QueryServiceStatus( + SC_RPC_HANDLE service, + SERVICE_STATUS *status) +{ + WINE_FIXME("\n"); + return ERROR_CALL_NOT_IMPLEMENTED; +} + +DWORD __cdecl svcctl_NotifyBootConfigStatus( + SVCCTL_HANDLEW machinename, + DWORD boot_acceptable) { WINE_FIXME("\n"); return ERROR_CALL_NOT_IMPLEMENTED; @@ -1483,14 +1657,23 @@ DWORD __cdecl svcctl_SCSetServiceBitsW(void) return ERROR_CALL_NOT_IMPLEMENTED; } - -DWORD __cdecl svcctl_EnumDependentServicesW(void) +DWORD __cdecl svcctl_EnumDependentServicesW( + SC_RPC_HANDLE service, + DWORD state, + BYTE *services, + DWORD buf_size, + DWORD *needed_size, + DWORD *services_ret) { WINE_FIXME("\n"); return ERROR_CALL_NOT_IMPLEMENTED; } -DWORD __cdecl svcctl_QueryServiceLockStatusW(void) +DWORD __cdecl svcctl_QueryServiceLockStatusW( + SC_RPC_HANDLE scmanager, + QUERY_SERVICE_LOCK_STATUSW *status, + DWORD buf_size, + DWORD *needed_size) { WINE_FIXME("\n"); return ERROR_CALL_NOT_IMPLEMENTED; @@ -1502,67 +1685,137 @@ DWORD __cdecl svcctl_SCSetServiceBitsA(void) return ERROR_CALL_NOT_IMPLEMENTED; } -DWORD __cdecl svcctl_ChangeServiceConfigA(void) +DWORD __cdecl svcctl_ChangeServiceConfigA( + SC_RPC_HANDLE service, + DWORD service_type, + DWORD start_type, + DWORD error_control, + LPSTR binarypath, + LPSTR loadordergroup, + DWORD *tagid, + BYTE *dependencies, + DWORD depend_size, + LPSTR startname, + BYTE *password, + DWORD password_size, + LPSTR displayname) { WINE_FIXME("\n"); return ERROR_CALL_NOT_IMPLEMENTED; } -DWORD __cdecl svcctl_CreateServiceA(void) +DWORD __cdecl svcctl_CreateServiceA( + SC_RPC_HANDLE scmanager, + LPCSTR servicename, + LPCSTR displayname, + DWORD desiredaccess, + DWORD service_type, + DWORD start_type, + DWORD error_control, + LPCSTR binarypath, + LPCSTR loadordergroup, + DWORD *tagid, + const BYTE *dependencies, + DWORD depend_size, + LPCSTR startname, + const BYTE *password, + DWORD password_size, + SC_RPC_HANDLE *service) { WINE_FIXME("\n"); return ERROR_CALL_NOT_IMPLEMENTED; } -DWORD __cdecl svcctl_EnumDependentServicesA(void) +DWORD __cdecl svcctl_EnumDependentServicesA( + SC_RPC_HANDLE service, + DWORD state, + BYTE *services, + DWORD buf_size, + DWORD *needed_size, + DWORD *services_ret) { WINE_FIXME("\n"); return ERROR_CALL_NOT_IMPLEMENTED; } -DWORD __cdecl svcctl_EnumServicesStatusA(void) +DWORD __cdecl svcctl_EnumServicesStatusA( + SC_RPC_HANDLE hmngr, + DWORD type, + DWORD state, + BYTE *buffer, + DWORD size, + DWORD *needed, + DWORD *returned, + DWORD *resume) { WINE_FIXME("\n"); return ERROR_CALL_NOT_IMPLEMENTED; } -DWORD __cdecl svcctl_OpenSCManagerA(void) +DWORD __cdecl svcctl_OpenSCManagerA( + MACHINE_HANDLEA MachineName, + LPCSTR DatabaseName, + DWORD dwAccessMask, + SC_RPC_HANDLE *handle) { WINE_FIXME("\n"); return ERROR_CALL_NOT_IMPLEMENTED; } -DWORD __cdecl svcctl_OpenServiceA(void) +DWORD __cdecl svcctl_OpenServiceA( + SC_RPC_HANDLE hSCManager, + LPCSTR lpServiceName, + DWORD dwDesiredAccess, + SC_RPC_HANDLE *phService) { WINE_FIXME("\n"); return ERROR_CALL_NOT_IMPLEMENTED; } -DWORD __cdecl svcctl_QueryServiceConfigA(void) +DWORD __cdecl svcctl_QueryServiceConfigA( + SC_RPC_HANDLE hService, + QUERY_SERVICE_CONFIGA *config, + DWORD buf_size, + DWORD *needed_size) { WINE_FIXME("\n"); return ERROR_CALL_NOT_IMPLEMENTED; } -DWORD __cdecl svcctl_QueryServiceLockStatusA(void) +DWORD __cdecl svcctl_QueryServiceLockStatusA( + SC_RPC_HANDLE scmanager, + QUERY_SERVICE_LOCK_STATUSA *status, + DWORD buf_size, + DWORD *needed_size) { WINE_FIXME("\n"); return ERROR_CALL_NOT_IMPLEMENTED; } -DWORD __cdecl svcctl_StartServiceA(void) +DWORD __cdecl svcctl_StartServiceA( + SC_RPC_HANDLE service, + DWORD argc, + LPCSTR *args) { WINE_FIXME("\n"); return ERROR_CALL_NOT_IMPLEMENTED; } -DWORD __cdecl svcctl_GetServiceDisplayNameA(void) +DWORD __cdecl svcctl_GetServiceDisplayNameA( + SC_RPC_HANDLE hSCManager, + LPCSTR servicename, + CHAR buffer[], + DWORD *buf_size) { WINE_FIXME("\n"); return ERROR_CALL_NOT_IMPLEMENTED; } -DWORD __cdecl svcctl_GetServiceKeyNameA(void) +DWORD __cdecl svcctl_GetServiceKeyNameA( + SC_RPC_HANDLE hSCManager, + LPCSTR servicename, + CHAR buffer[], + DWORD *buf_size) { WINE_FIXME("\n"); return ERROR_CALL_NOT_IMPLEMENTED; @@ -1574,25 +1827,40 @@ DWORD __cdecl svcctl_GetCurrentGroupStateW(void) return ERROR_CALL_NOT_IMPLEMENTED; } -DWORD __cdecl svcctl_EnumServiceGroupW(void) +DWORD __cdecl svcctl_EnumServiceGroupW( + SC_RPC_HANDLE scmanager, + DWORD service_type, + DWORD service_state, + BYTE *buffer, + DWORD buf_size, + DWORD *needed_size, + DWORD *returned_size, + DWORD *resume_index, + LPCWSTR groupname) { WINE_FIXME("\n"); return ERROR_CALL_NOT_IMPLEMENTED; } -DWORD __cdecl svcctl_ChangeServiceConfig2A(void) +DWORD __cdecl svcctl_ChangeServiceConfig2A( + SC_RPC_HANDLE service, + SC_RPC_CONFIG_INFOA info) { WINE_FIXME("\n"); return ERROR_CALL_NOT_IMPLEMENTED; } -DWORD __cdecl svcctl_QueryServiceConfig2A(void) +DWORD __cdecl svcctl_QueryServiceConfig2A( + SC_RPC_HANDLE service, + DWORD info_level, + BYTE *buffer, + DWORD buf_size, + DWORD *needed_size) { WINE_FIXME("\n"); return ERROR_CALL_NOT_IMPLEMENTED; } - DWORD RPC_Init(void) { WCHAR transport[] = SVCCTL_TRANSPORT; @@ -1723,6 +1991,10 @@ void __RPC_USER SC_RPC_HANDLE_rundown(SC_RPC_HANDLE handle) SC_RPC_HANDLE_destroy(handle); } +void __RPC_USER SC_NOTIFY_RPC_HANDLE_rundown(SC_NOTIFY_RPC_HANDLE handle) +{ +} + void __RPC_FAR * __RPC_USER MIDL_user_allocate(SIZE_T len) { return HeapAlloc(GetProcessHeap(), 0, len);