ADVAPI32: Implement QueryServiceStatusEx

Rolf Kalbermatter r.kalbermatter at hccnet.nl
Fri Apr 20 03:36:19 CDT 2007


Changelog
  dlls/advapi32/service.c
  include/winsvc.h
   - Implement QueryServiceStatusEx based on the code used in
QueryServiceStatus

Based on the patch submitted by Anastasius Focht posted under
http://bugs.winehq.org/show_bug.cgi?id=5809#c7

Rolf Kalbermatter
-------------- next part --------------
>From 695811e0779ffc51886a1a6c6ce512e6af435339 Mon Sep 17 00:00:00 2001
From: Rolf Kalbermatter <r.kalbermatter at hccnet.nl>
Date: Fri, 20 Apr 2007 08:12:10 +0200
Subject: [PATCH] Implement QueryServiceStatusEx
---
 dlls/advapi32/service.c |   71 +++++++++++++++++++++++++++++++++++++++++++++--
 include/winsvc.h        |    9 ++++++
 2 files changed, 77 insertions(+), 3 deletions(-)

diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c
index 60f8dca..ca1b085 100644
--- a/dlls/advapi32/service.c
+++ b/dlls/advapi32/service.c
@@ -1635,9 +1635,74 @@ BOOL WINAPI QueryServiceStatusEx(SC_HAND
                         LPBYTE lpBuffer, DWORD cbBufSize,
                         LPDWORD pcbBytesNeeded)
 {
-    FIXME("stub\n");
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    struct sc_service *hsvc;
+    DWORD size, type, val;
+    HANDLE pipe;
+    LONG r;
+    LPSERVICE_STATUS_PROCESS pSvcStatusData;
+
+    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)
+    {
+        SetLastError( ERROR_INVALID_HANDLE );
+        return FALSE;
+    }
+
+    /* FIXME: this would be the pid from service_start_process() */
+    pSvcStatusData->dwProcessId = 0;
+    /* service is running in a process that is not a system process */
+    pSvcStatusData->dwServiceFlags = 0;
+
+    pipe = service_open_pipe(hsvc->name);
+    if (pipe != INVALID_HANDLE_VALUE)
+    {
+        r = service_get_status(pipe, &pSvcStatusData->status);
+        CloseHandle(pipe);
+        if (r)
+            return TRUE;
+    }
+
+    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->status.dwServiceType = val;
+    pSvcStatusData->status.dwCurrentState            = SERVICE_STOPPED;  /* stopped */
+    pSvcStatusData->status.dwControlsAccepted        = 0;
+    pSvcStatusData->status.dwWin32ExitCode           = ERROR_SERVICE_NEVER_STARTED;
+    pSvcStatusData->status.dwServiceSpecificExitCode = 0;
+    pSvcStatusData->status.dwCheckPoint              = 0;
+    pSvcStatusData->status.dwWaitHint                = 0;
+
+    return TRUE;
 }
 
 /******************************************************************************
diff --git a/include/winsvc.h b/include/winsvc.h
index 93ccaf6..eeb9539 100644
--- a/include/winsvc.h
+++ b/include/winsvc.h
@@ -131,6 +131,15 @@ typedef struct _SERVICE_STATUS {
   DWORD dwWaitHint;
 } SERVICE_STATUS, *LPSERVICE_STATUS;
 
+/* Service status process structure */
+
+typedef struct _SERVICE_STATUS_PROCESS
+{
+  SERVICE_STATUS status;
+  DWORD dwProcessId;
+  DWORD dwServiceFlags;
+} SERVICE_STATUS_PROCESS, *LPSERVICE_STATUS_PROCESS;
+
 typedef enum _SC_STATUS_TYPE {
   SC_STATUS_PROCESS_INFO      = 0
 } SC_STATUS_TYPE;
-- 
1.4.1



More information about the wine-patches mailing list