mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 12:49:45 +00:00
services: Move SetServiceStatus and QueryServiceStatusEx to services.exe.
This commit is contained in:
parent
010dcb168b
commit
b48714b148
@ -645,29 +645,6 @@ static BOOL service_handle_get_status(HANDLE pipe, const service_data *service)
|
||||
sizeof service->status, &count, NULL);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* service_get_status
|
||||
*/
|
||||
static BOOL service_get_status(HANDLE pipe, LPSERVICE_STATUS_PROCESS status)
|
||||
{
|
||||
DWORD cmd[2], count = 0;
|
||||
BOOL r;
|
||||
|
||||
cmd[0] = WINESERV_GETSTATUS;
|
||||
cmd[1] = 0;
|
||||
r = WriteFile( pipe, cmd, sizeof cmd, &count, NULL );
|
||||
if (!r || count != sizeof cmd)
|
||||
{
|
||||
ERR("service protocol error - failed to write pipe!\n");
|
||||
return r;
|
||||
}
|
||||
r = ReadFile( pipe, status, sizeof *status, &count, NULL );
|
||||
if (!r || count != sizeof *status)
|
||||
ERR("service protocol error - failed to read pipe "
|
||||
"r = %d count = %d!\n", r, count);
|
||||
return r;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* service_send_control
|
||||
*/
|
||||
@ -1014,8 +991,8 @@ BOOL WINAPI UnlockServiceDatabase (SC_LOCK ScLock)
|
||||
BOOL WINAPI
|
||||
SetServiceStatus( SERVICE_STATUS_HANDLE hService, LPSERVICE_STATUS lpStatus )
|
||||
{
|
||||
ULONG_PTR index = HandleToULong(hService) - 1;
|
||||
BOOL r = FALSE;
|
||||
struct sc_service *hsvc;
|
||||
DWORD err;
|
||||
|
||||
TRACE("%p %x %x %x %x %x %x %x\n", hService,
|
||||
lpStatus->dwServiceType, lpStatus->dwCurrentState,
|
||||
@ -1023,16 +1000,24 @@ SetServiceStatus( SERVICE_STATUS_HANDLE hService, LPSERVICE_STATUS lpStatus )
|
||||
lpStatus->dwServiceSpecificExitCode, lpStatus->dwCheckPoint,
|
||||
lpStatus->dwWaitHint);
|
||||
|
||||
EnterCriticalSection( &service_cs );
|
||||
if (index < nb_services)
|
||||
hsvc = sc_handle_get_handle_data((SC_HANDLE)hService, SC_HTYPE_SERVICE);
|
||||
if (!hsvc)
|
||||
{
|
||||
memcpy( &services[index]->status, lpStatus, sizeof(SERVICE_STATUS) );
|
||||
TRACE("Set service status to %d\n",services[index]->status.dwCurrentState);
|
||||
r = TRUE;
|
||||
SetLastError( ERROR_INVALID_HANDLE );
|
||||
return FALSE;
|
||||
}
|
||||
LeaveCriticalSection( &service_cs );
|
||||
|
||||
return r;
|
||||
err = svcctl_SetServiceStatus( hsvc->hdr.server_handle, lpStatus );
|
||||
if (err != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(err);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (lpStatus->dwCurrentState == SERVICE_STOPPED)
|
||||
CloseServiceHandle((SC_HANDLE)hService);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@ -1695,11 +1680,12 @@ BOOL WINAPI QueryServiceStatus(SC_HANDLE hService,
|
||||
{
|
||||
SERVICE_STATUS_PROCESS SvcStatusData;
|
||||
BOOL ret;
|
||||
DWORD dummy;
|
||||
|
||||
TRACE("%p %p\n", hService, lpservicestatus);
|
||||
|
||||
ret = QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&SvcStatusData,
|
||||
sizeof(SERVICE_STATUS_PROCESS), NULL);
|
||||
sizeof(SERVICE_STATUS_PROCESS), &dummy);
|
||||
if (ret) memcpy(lpservicestatus, &SvcStatusData, sizeof(SERVICE_STATUS)) ;
|
||||
return ret;
|
||||
}
|
||||
@ -1726,35 +1712,10 @@ BOOL WINAPI QueryServiceStatusEx(SC_HANDLE hService, SC_STATUS_TYPE InfoLevel,
|
||||
LPDWORD pcbBytesNeeded)
|
||||
{
|
||||
struct sc_service *hsvc;
|
||||
DWORD size, type, val;
|
||||
HANDLE pipe;
|
||||
LONG r;
|
||||
LPSERVICE_STATUS_PROCESS pSvcStatusData;
|
||||
DWORD err;
|
||||
|
||||
TRACE("%p %d %p %d %p\n", hService, InfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
|
||||
|
||||
if (InfoLevel != SC_STATUS_PROCESS_INFO)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_LEVEL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pSvcStatusData = (LPSERVICE_STATUS_PROCESS) lpBuffer;
|
||||
if (pSvcStatusData == NULL)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (cbBufSize < sizeof(SERVICE_STATUS_PROCESS))
|
||||
{
|
||||
if( pcbBytesNeeded != NULL)
|
||||
*pcbBytesNeeded = sizeof(SERVICE_STATUS_PROCESS);
|
||||
|
||||
SetLastError( ERROR_INSUFFICIENT_BUFFER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
hsvc = sc_handle_get_handle_data(hService, SC_HTYPE_SERVICE);
|
||||
if (!hsvc)
|
||||
{
|
||||
@ -1762,31 +1723,13 @@ BOOL WINAPI QueryServiceStatusEx(SC_HANDLE hService, SC_STATUS_TYPE InfoLevel,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pipe = service_open_pipe(hsvc->name);
|
||||
if (pipe != INVALID_HANDLE_VALUE)
|
||||
err = svcctl_QueryServiceStatusEx(hsvc->hdr.server_handle, InfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
|
||||
if (err != ERROR_SUCCESS)
|
||||
{
|
||||
r = service_get_status(pipe, pSvcStatusData);
|
||||
CloseHandle(pipe);
|
||||
if (r)
|
||||
return TRUE;
|
||||
SetLastError(err);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TRACE("Failed to read service status\n");
|
||||
|
||||
/* read the service type from the registry */
|
||||
size = sizeof(val);
|
||||
r = RegQueryValueExA(hsvc->hkey, "Type", NULL, &type, (LPBYTE)&val, &size);
|
||||
if (r != ERROR_SUCCESS || type != REG_DWORD)
|
||||
val = 0;
|
||||
|
||||
pSvcStatusData->dwServiceType = val;
|
||||
pSvcStatusData->dwCurrentState = SERVICE_STOPPED; /* stopped */
|
||||
pSvcStatusData->dwControlsAccepted = 0;
|
||||
pSvcStatusData->dwWin32ExitCode = ERROR_SERVICE_NEVER_STARTED;
|
||||
pSvcStatusData->dwServiceSpecificExitCode = 0;
|
||||
pSvcStatusData->dwCheckPoint = 0;
|
||||
pSvcStatusData->dwWaitHint = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -2569,11 +2512,21 @@ SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerExA( LPCSTR name, LPHANDL
|
||||
SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerExW( LPCWSTR lpServiceName,
|
||||
LPHANDLER_FUNCTION_EX lpHandlerProc, LPVOID lpContext )
|
||||
{
|
||||
SERVICE_STATUS_HANDLE handle = 0;
|
||||
SC_HANDLE hService;
|
||||
SC_HANDLE hSCM;
|
||||
unsigned int i;
|
||||
BOOL found = FALSE;
|
||||
|
||||
TRACE("%s %p %p\n", debugstr_w(lpServiceName), lpHandlerProc, lpContext);
|
||||
|
||||
hSCM = OpenSCManagerW( NULL, NULL, SC_MANAGER_CONNECT );
|
||||
if (!hSCM)
|
||||
return NULL;
|
||||
hService = OpenServiceW( hSCM, lpServiceName, SERVICE_SET_STATUS );
|
||||
CloseServiceHandle(hSCM);
|
||||
if (!hService)
|
||||
return NULL;
|
||||
|
||||
EnterCriticalSection( &service_cs );
|
||||
for (i = 0; i < nb_services; i++)
|
||||
{
|
||||
@ -2581,13 +2534,20 @@ SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerExW( LPCWSTR lpServiceNam
|
||||
{
|
||||
services[i]->handler = lpHandlerProc;
|
||||
services[i]->context = lpContext;
|
||||
handle = ULongToHandle( i + 1 );
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection( &service_cs );
|
||||
|
||||
return handle;
|
||||
if (!found)
|
||||
{
|
||||
CloseServiceHandle(hService);
|
||||
SetLastError(ERROR_SERVICE_DOES_NOT_EXIST);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (SERVICE_STATUS_HANDLE)hService;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -44,6 +44,9 @@ interface svcctl
|
||||
typedef [handle] LPCWSTR MACHINE_HANDLEW;
|
||||
typedef [context_handle] void *SC_RPC_HANDLE;
|
||||
|
||||
/* undocumented access rights */
|
||||
cpp_quote("#define SERVICE_SET_STATUS 0x8000")
|
||||
|
||||
cpp_quote("#if 0 /* already defined in winsvc.h */")
|
||||
typedef struct _QUERY_SERVICE_CONFIGW {
|
||||
DWORD dwServiceType;
|
||||
@ -56,6 +59,20 @@ typedef struct _QUERY_SERVICE_CONFIGW {
|
||||
[unique] LPWSTR lpServiceStartName;
|
||||
[unique] LPWSTR lpDisplayName;
|
||||
} QUERY_SERVICE_CONFIGW, *LPQUERY_SERVICE_CONFIGW;
|
||||
|
||||
typedef struct _SERVICE_STATUS {
|
||||
DWORD dwServiceType;
|
||||
DWORD dwCurrentState;
|
||||
DWORD dwControlsAccepted;
|
||||
DWORD dwWin32ExitCode;
|
||||
DWORD dwServiceSpecificExitCode;
|
||||
DWORD dwCheckPoint;
|
||||
DWORD dwWaitHint;
|
||||
} SERVICE_STATUS, *LPSERVICE_STATUS;
|
||||
|
||||
typedef enum _SC_STATUS_TYPE {
|
||||
SC_STATUS_PROCESS_INFO = 0
|
||||
} SC_STATUS_TYPE;
|
||||
cpp_quote("#endif")
|
||||
|
||||
|
||||
@ -69,6 +86,12 @@ cpp_quote("#endif")
|
||||
[in] SC_RPC_HANDLE hService
|
||||
);
|
||||
|
||||
/* Compatible with Windows function 0x07 */
|
||||
DWORD svcctl_SetServiceStatus(
|
||||
[in] SC_RPC_HANDLE hServiceStatus,
|
||||
[in] LPSERVICE_STATUS lpServiceStatus
|
||||
);
|
||||
|
||||
/* Compatible with Windows function 0x0b */
|
||||
DWORD svcctl_ChangeServiceConfigW(
|
||||
[in] SC_RPC_HANDLE hService,
|
||||
@ -142,4 +165,13 @@ cpp_quote("#endif")
|
||||
[out,size_is(cchBufSize)] WCHAR lpBuffer[],
|
||||
[in] DWORD cchBufSize,
|
||||
[out] DWORD *cchLength);
|
||||
|
||||
/* Untested with Windows function 0x28 */
|
||||
DWORD svcctl_QueryServiceStatusEx(
|
||||
[in] SC_RPC_HANDLE hService,
|
||||
[in] SC_STATUS_TYPE InfoLevel,
|
||||
[out,size_is(cbBufSize)] BYTE *lpBuffer,
|
||||
[in] DWORD cbBufSize,
|
||||
[out] LPDWORD pcbBytesNeeded
|
||||
);
|
||||
}
|
||||
|
@ -570,6 +570,79 @@ DWORD svcctl_ChangeServiceConfigW(
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
DWORD svcctl_SetServiceStatus(
|
||||
SC_RPC_HANDLE hServiceStatus,
|
||||
LPSERVICE_STATUS lpServiceStatus)
|
||||
{
|
||||
struct sc_service *service;
|
||||
DWORD err;
|
||||
|
||||
WINE_TRACE("(%p, %p)\n", hServiceStatus, lpServiceStatus);
|
||||
|
||||
if ((err = validate_service_handle(hServiceStatus, SERVICE_SET_STATUS, &service)) != 0)
|
||||
return err;
|
||||
|
||||
lock_services();
|
||||
/* FIXME: be a bit more discriminant about what parts of the status we set
|
||||
* and check that fields are valid */
|
||||
service->service_entry->status.dwServiceType = lpServiceStatus->dwServiceType;
|
||||
service->service_entry->status.dwCurrentState = lpServiceStatus->dwCurrentState;
|
||||
service->service_entry->status.dwControlsAccepted = lpServiceStatus->dwControlsAccepted;
|
||||
service->service_entry->status.dwWin32ExitCode = lpServiceStatus->dwWin32ExitCode;
|
||||
service->service_entry->status.dwServiceSpecificExitCode = lpServiceStatus->dwServiceSpecificExitCode;
|
||||
service->service_entry->status.dwCheckPoint = lpServiceStatus->dwCheckPoint;
|
||||
service->service_entry->status.dwWaitHint = lpServiceStatus->dwWaitHint;
|
||||
unlock_services();
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
DWORD svcctl_QueryServiceStatusEx(
|
||||
SC_RPC_HANDLE hService,
|
||||
SC_STATUS_TYPE InfoLevel,
|
||||
BYTE *lpBuffer,
|
||||
DWORD cbBufSize,
|
||||
LPDWORD pcbBytesNeeded)
|
||||
{
|
||||
struct sc_service *service;
|
||||
DWORD err;
|
||||
LPSERVICE_STATUS_PROCESS pSvcStatusData;
|
||||
|
||||
if ((err = validate_service_handle(hService, SERVICE_QUERY_STATUS, &service)) != 0)
|
||||
return err;
|
||||
|
||||
if (InfoLevel != SC_STATUS_PROCESS_INFO)
|
||||
return ERROR_INVALID_LEVEL;
|
||||
|
||||
pSvcStatusData = (LPSERVICE_STATUS_PROCESS) lpBuffer;
|
||||
if (pSvcStatusData == NULL)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (cbBufSize < sizeof(SERVICE_STATUS_PROCESS))
|
||||
{
|
||||
if( pcbBytesNeeded != NULL)
|
||||
*pcbBytesNeeded = sizeof(SERVICE_STATUS_PROCESS);
|
||||
|
||||
return ERROR_INSUFFICIENT_BUFFER;
|
||||
}
|
||||
|
||||
lock_services();
|
||||
|
||||
pSvcStatusData->dwServiceType = service->service_entry->status.dwServiceType;
|
||||
pSvcStatusData->dwCurrentState = service->service_entry->status.dwCurrentState;
|
||||
pSvcStatusData->dwControlsAccepted = service->service_entry->status.dwControlsAccepted;
|
||||
pSvcStatusData->dwWin32ExitCode = service->service_entry->status.dwWin32ExitCode;
|
||||
pSvcStatusData->dwServiceSpecificExitCode = service->service_entry->status.dwServiceSpecificExitCode;
|
||||
pSvcStatusData->dwCheckPoint = service->service_entry->status.dwCheckPoint;
|
||||
pSvcStatusData->dwWaitHint = service->service_entry->status.dwWaitHint;
|
||||
pSvcStatusData->dwProcessId = service->service_entry->status.dwProcessId;
|
||||
pSvcStatusData->dwServiceFlags = service->service_entry->status.dwServiceFlags;
|
||||
|
||||
unlock_services();
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
DWORD svcctl_CloseServiceHandle(
|
||||
SC_RPC_HANDLE *handle)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user