https://git.reactos.org/?p=reactos.git;a=commitdiff;h=47281571546797043d7f5dad0bf5da5372055274

commit 47281571546797043d7f5dad0bf5da5372055274
Author:     Eric Kohl <[email protected]>
AuthorDate: Sat Feb 17 19:26:06 2018 +0100
Commit:     Eric Kohl <[email protected]>
CommitDate: Sat Feb 17 19:28:16 2018 +0100

    [SC] Implement missing query/queryex options
    - PrintService: Print optional display name.
    - MainUsage: Print missing query options.
    - Parse query options and use them to enumerate services.
---
 base/applications/sc/control.c |   1 +
 base/applications/sc/print.c   |   4 +
 base/applications/sc/query.c   | 361 ++++++++++++++++++++++++++++-------------
 base/applications/sc/sc.h      |   2 +-
 base/applications/sc/start.c   |   1 +
 base/applications/sc/usage.c   |   8 +-
 6 files changed, 261 insertions(+), 116 deletions(-)

diff --git a/base/applications/sc/control.c b/base/applications/sc/control.c
index de212dd230..5e5a4e84ac 100644
--- a/base/applications/sc/control.c
+++ b/base/applications/sc/control.c
@@ -96,6 +96,7 @@ Control(DWORD Control,
     StatusEx.dwServiceFlags = 0;
 
     PrintService(ServiceName,
+                 NULL,
                  &StatusEx,
                  FALSE);
 
diff --git a/base/applications/sc/print.c b/base/applications/sc/print.c
index caf82a4ae6..f08402207f 100644
--- a/base/applications/sc/print.c
+++ b/base/applications/sc/print.c
@@ -11,11 +11,15 @@
 
 VOID
 PrintService(LPCTSTR lpServiceName,
+             LPCTSTR lpDisplayName,
              LPSERVICE_STATUS_PROCESS pStatus,
              BOOL bExtended)
 {
     _tprintf(_T("SERVICE_NAME: %s\n"), lpServiceName);
 
+    if (lpDisplayName)
+        _tprintf(_T("DISPLAY_NAME: %s\n"), lpDisplayName);
+
     // Re-use PrintServiceStatus(), as SERVICE_STATUS_PROCESS is in fact an 
extension of SERVICE_STATUS.
     PrintServiceStatus((LPSERVICE_STATUS)pStatus);
 
diff --git a/base/applications/sc/query.c b/base/applications/sc/query.c
index d9d925f3ec..54e04277b2 100644
--- a/base/applications/sc/query.c
+++ b/base/applications/sc/query.c
@@ -4,25 +4,11 @@
  * FILE:        base/applications/sc/query.c
  * PURPOSE:     queries service info
  * COPYRIGHT:   Copyright 2005 - 2006 Ged Murphy <[email protected]>
- *
- */
-/*
- * TODO:
- * Allow calling of 2 options e.g.:
- *    type= driver state= inactive
+ *              Copyright 2018 Eric Kohl <[email protected]>
  */
 
 #include "sc.h"
 
-LPTSTR QueryOpts[] = {
-    _T("type="),
-    _T("state="),
-    _T("bufsize="),
-    _T("ri="),
-    _T("group="),
-};
-
-
 LPSERVICE_STATUS_PROCESS
 QueryService(LPCTSTR ServiceName)
 {
@@ -84,17 +70,20 @@ fail:
 }
 
 
-static BOOL
+static
+DWORD
 EnumServices(ENUM_SERVICE_STATUS_PROCESS **pServiceStatus,
-             DWORD ServiceType,
-             DWORD ServiceState)
+             DWORD dwServiceType,
+             DWORD dwServiceState,
+             DWORD dwBufferSize,
+             DWORD dwResumeIndex,
+             LPCTSTR pszGroupName)
 {
     SC_HANDLE hSCManager;
-    DWORD BufSize = 0;
     DWORD BytesNeeded = 0;
-    DWORD ResumeHandle = 0;
+    DWORD ResumeHandle = dwResumeIndex;
     DWORD NumServices = 0;
-    DWORD Ret;
+    BOOL Ret;
 
     hSCManager = OpenSCManager(NULL,
                                NULL,
@@ -102,42 +91,49 @@ EnumServices(ENUM_SERVICE_STATUS_PROCESS **pServiceStatus,
     if (hSCManager == NULL)
     {
         ReportLastError();
-        return FALSE;
+        return 0;
     }
 
-    Ret = EnumServicesStatusEx(hSCManager,
-                               SC_ENUM_PROCESS_INFO,
-                               ServiceType,
-                               ServiceState,
-                               (LPBYTE)*pServiceStatus,
-                               BufSize,
-                               &BytesNeeded,
-                               &NumServices,
-                               &ResumeHandle,
-                               0);
-
-    if ((Ret == 0) && (GetLastError() == ERROR_MORE_DATA))
+    if (dwBufferSize == 0)
     {
-        *pServiceStatus = (ENUM_SERVICE_STATUS_PROCESS *)
-                          HeapAlloc(GetProcessHeap(),
-                                    0,
-                                    BytesNeeded);
-        if (*pServiceStatus != NULL)
+        Ret = EnumServicesStatusEx(hSCManager,
+                                   SC_ENUM_PROCESS_INFO,
+                                   dwServiceType,
+                                   dwServiceState,
+                                   (LPBYTE)*pServiceStatus,
+                                   dwBufferSize,
+                                   &BytesNeeded,
+                                   &NumServices,
+                                   &ResumeHandle,
+                                   pszGroupName);
+        if ((Ret == 0) && (GetLastError() != ERROR_MORE_DATA))
         {
-            if (EnumServicesStatusEx(hSCManager,
-                                     SC_ENUM_PROCESS_INFO,
-                                     ServiceType,
-                                     ServiceState,
-                                     (LPBYTE)*pServiceStatus,
-                                     BytesNeeded,
-                                     &BytesNeeded,
-                                     &NumServices,
-                                     &ResumeHandle,
-                                     0))
-            {
-                CloseServiceHandle(hSCManager);
-                return NumServices;
-            }
+            ReportLastError();
+            return 0;
+        }
+
+        dwBufferSize = BytesNeeded;
+    }
+
+    *pServiceStatus = (ENUM_SERVICE_STATUS_PROCESS *)
+                      HeapAlloc(GetProcessHeap(),
+                                0,
+                                dwBufferSize);
+    if (*pServiceStatus != NULL)
+    {
+        if (EnumServicesStatusEx(hSCManager,
+                                 SC_ENUM_PROCESS_INFO,
+                                 dwServiceType,
+                                 dwServiceState,
+                                 (LPBYTE)*pServiceStatus,
+                                 dwBufferSize,
+                                 &BytesNeeded,
+                                 &NumServices,
+                                 &ResumeHandle,
+                                 pszGroupName))
+        {
+            CloseServiceHandle(hSCManager);
+            return NumServices;
         }
     }
 
@@ -151,6 +147,147 @@ EnumServices(ENUM_SERVICE_STATUS_PROCESS **pServiceStatus,
 }
 
 
+static
+BOOL
+ParseQueryArguments(
+    IN LPCTSTR *ServiceArgs,
+    IN INT ArgCount,
+    OUT PDWORD pdwServiceType,
+    OUT PDWORD pdwServiceState,
+    OUT PDWORD pdwBufferSize,
+    OUT PDWORD pdwResumeIndex,
+    OUT LPCTSTR *ppszGroupName,
+    OUT LPCTSTR *ppszServiceName)
+{
+    INT TmpCount, TmpIndex;
+    DWORD dwValue;
+
+    TmpCount = ArgCount;
+    TmpIndex = 0;
+    while (TmpCount > 0)
+    {
+        if (!lstrcmpi(ServiceArgs[TmpIndex], _T("type=")))
+        {
+            TmpIndex++;
+            TmpCount--;
+
+            if (TmpCount > 0)
+            {
+                if (!lstrcmpi(ServiceArgs[TmpIndex], _T("service")))
+                {
+                    *pdwServiceType = SERVICE_WIN32;
+                }
+                else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("driver")))
+                {
+                    *pdwServiceType = SERVICE_DRIVER;
+                }
+                else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("all")))
+                {
+                    *pdwServiceType = SERVICE_TYPE_ALL;
+                }
+                else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("interact")))
+                {
+                    *pdwServiceType |= SERVICE_INTERACTIVE_PROCESS;
+                }
+                else
+                {
+                    _tprintf(_T("ERROR following \"type=\"!\nMust be 
\"driver\" or \"service\"\n"));
+                    return FALSE;
+                }
+
+                TmpIndex++;
+                TmpCount--;
+            }
+        }
+        else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("state=")))
+        {
+            TmpIndex++;
+            TmpCount--;
+
+            if (TmpCount > 0)
+            {
+                if (!lstrcmpi(ServiceArgs[TmpIndex], _T("active")))
+                {
+                    *pdwServiceState = SERVICE_ACTIVE;
+                }
+                else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("inactive")))
+                {
+                    *pdwServiceState = SERVICE_INACTIVE;
+                }
+                else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("all")))
+                {
+                    *pdwServiceState = SERVICE_STATE_ALL;
+                }
+                else
+                {
+                    _tprintf(_T("ERROR following \"state=\"!\nMust be 
\"inactive\" or \"all\"\n"));
+                    return FALSE;
+                }
+
+                TmpIndex++;
+                TmpCount--;
+            }
+        }
+        else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("bufsize=")))
+        {
+            TmpIndex++;
+            TmpCount--;
+
+            if (TmpCount > 0)
+            {
+                dwValue = _tcstoul(ServiceArgs[TmpIndex], NULL, 10);
+                if (dwValue > 0)
+                {
+                    *pdwBufferSize = dwValue;
+                }
+
+                TmpIndex++;
+                TmpCount--;
+            }
+        }
+        else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("ri=")))
+        {
+            TmpIndex++;
+            TmpCount--;
+
+            if (TmpCount >= 0)
+            {
+                dwValue = _tcstoul(ServiceArgs[TmpIndex], NULL, 10);
+                if (dwValue > 0)
+                {
+                    *pdwResumeIndex = dwValue;
+                }
+
+                TmpIndex++;
+                TmpCount--;
+            }
+        }
+        else if (!lstrcmpi(ServiceArgs[TmpIndex], _T("group=")))
+        {
+            TmpIndex++;
+            TmpCount--;
+
+            if (TmpCount > 0)
+            {
+                *ppszGroupName = ServiceArgs[TmpIndex];
+
+                TmpIndex++;
+                TmpCount--;
+            }
+        }
+        else
+        {
+            *ppszServiceName = ServiceArgs[TmpIndex];
+
+            TmpIndex++;
+            TmpCount--;
+        }
+    }
+
+    return TRUE;
+}
+
+
 BOOL
 Query(LPCTSTR *ServiceArgs,
       DWORD ArgCount,
@@ -158,17 +295,18 @@ Query(LPCTSTR *ServiceArgs,
 {
     LPENUM_SERVICE_STATUS_PROCESS pServiceStatus = NULL;
     DWORD NumServices = 0;
-    //DWORD ServiceType;
-    //DWORD ServiceState;
-    BOOL bServiceName = TRUE;
-    DWORD OptSize, i;
-
-    LPCTSTR *TmpArgs;
-    INT TmpCnt;
+    DWORD dwServiceType = SERVICE_WIN32;
+    DWORD dwServiceState = SERVICE_ACTIVE;
+    DWORD dwBufferSize = 0;
+    DWORD dwResumeIndex = 0;
+    LPCTSTR pszGroupName = NULL;
+    LPCTSTR pszServiceName = NULL;
+    DWORD i;
 
 #ifdef SCDBG
-    TmpArgs = ServiceArgs;
-    TmpCnt = ArgCount;
+    LPCTSTR *TmpArgs = ServiceArgs;
+    INT TmpCnt = ArgCount;
+
     _tprintf(_T("Arguments:\n"));
     while (TmpCnt)
     {
@@ -179,66 +317,69 @@ Query(LPCTSTR *ServiceArgs,
     _tprintf(_T("\n"));
 #endif /* SCDBG */
 
-    /* display all running services and drivers */
-    if (ArgCount == 0)
-    {
-        NumServices = EnumServices(&pServiceStatus,
-                                   SERVICE_WIN32,
-                                   SERVICE_ACTIVE);
-
-        if (NumServices != 0)
-        {
-            for (i=0; i < NumServices; i++)
-            {
-                PrintService(pServiceStatus[i].lpServiceName,
-                             &pServiceStatus[i].ServiceStatusProcess,
-                             bExtended);
-            }
-
-            _tprintf(_T("number : %lu\n"), NumServices);
-
-            if (pServiceStatus)
-                HeapFree(GetProcessHeap(), 0, pServiceStatus);
-
-            return TRUE;
-        }
-
+    /* Parse arguments */
+    if (!ParseQueryArguments(ServiceArgs,
+                             ArgCount,
+                             &dwServiceType,
+                             &dwServiceState,
+                             &dwBufferSize,
+                             &dwResumeIndex,
+                             &pszGroupName,
+                             &pszServiceName))
         return FALSE;
-    }
 
-    TmpArgs = ServiceArgs;
-    TmpCnt = ArgCount;
-    OptSize = sizeof(QueryOpts) / sizeof(QueryOpts[0]);
-    while (TmpCnt--)
+#ifdef SCDBG
+    _tprintf(_T("Service type: %lx\n"), dwServiceType);
+    _tprintf(_T("Service state: %lx\n"), dwServiceState);
+    _tprintf(_T("Buffer size: %lu\n"), dwBufferSize);
+    _tprintf(_T("Resume index: %lu\n"), dwResumeIndex);
+    _tprintf(_T("Group name: %s\n"), pszGroupName);
+    _tprintf(_T("Service name: %s\n"), pszServiceName);
+#endif
+
+    if (pszServiceName)
     {
-        for (i=0; i < OptSize; i++)
-        {
-            if (!lstrcmpi(*TmpArgs, QueryOpts[i]))
-            {
-                bServiceName = FALSE;
-            }
-        }
-        TmpArgs++;
-    }
-
-
-    /* FIXME: parse options */
-
+        /* Print only the requested service */
 
-    /* print only the service requested */
-    if (bServiceName)
-    {
         LPSERVICE_STATUS_PROCESS pStatus;
-        LPCTSTR ServiceName = *ServiceArgs;
 
-        pStatus = QueryService(ServiceName);
+        pStatus = QueryService(pszServiceName);
         if (pStatus)
         {
-            PrintService(ServiceName,
+            PrintService(pszServiceName,
+                         NULL,
                          pStatus,
                          bExtended);
         }
     }
+    else
+    {
+        /* Print all matching services */
+
+        NumServices = EnumServices(&pServiceStatus,
+                                   dwServiceType,
+                                   dwServiceState,
+                                   dwBufferSize,
+                                   dwResumeIndex,
+                                   pszGroupName);
+        if (NumServices == 0)
+            return FALSE;
+
+        for (i = 0; i < NumServices; i++)
+        {
+            PrintService(pServiceStatus[i].lpServiceName,
+                         pServiceStatus[i].lpDisplayName,
+                         &pServiceStatus[i].ServiceStatusProcess,
+                         bExtended);
+        }
+
+#ifdef SCDBG
+        _tprintf(_T("number : %lu\n"), NumServices);
+#endif
+
+        if (pServiceStatus)
+            HeapFree(GetProcessHeap(), 0, pServiceStatus);
+    }
 
     return TRUE;
 }
diff --git a/base/applications/sc/sc.h b/base/applications/sc/sc.h
index 3dbacee0c8..a896da6855 100644
--- a/base/applications/sc/sc.h
+++ b/base/applications/sc/sc.h
@@ -56,7 +56,7 @@ BOOL GetKeyName(LPCTSTR ServiceName);
 BOOL EnumDepend(LPCTSTR ServiceName);
 
 /* print and error functions */
-VOID PrintService(LPCTSTR ServiceName, LPSERVICE_STATUS_PROCESS pStatus, BOOL 
bExtended);
+VOID PrintService(LPCTSTR ServiceName, LPCTSTR DisplayName, 
LPSERVICE_STATUS_PROCESS pStatus, BOOL bExtended);
 VOID PrintServiceStatus(LPSERVICE_STATUS pStatus);
 VOID ReportLastError(VOID);
 
diff --git a/base/applications/sc/start.c b/base/applications/sc/start.c
index 676355ce2f..598a6355c7 100644
--- a/base/applications/sc/start.c
+++ b/base/applications/sc/start.c
@@ -68,6 +68,7 @@ BOOL Start(LPCTSTR ServiceName, LPCTSTR *ServiceArgs, INT 
ArgCount)
     if (pServiceInfo != NULL)
     {
         PrintService(ServiceName,
+                     NULL,
                      pServiceInfo,
                      TRUE);
 
diff --git a/base/applications/sc/usage.c b/base/applications/sc/usage.c
index 4bcf049f9d..d04907d212 100644
--- a/base/applications/sc/usage.c
+++ b/base/applications/sc/usage.c
@@ -68,14 +68,12 @@ VOID MainUsage(VOID)
         _T("             (default = service)\n")
         _T("    state=   State of services to enumerate (inactive, all)\n")
         _T("             (default = active)\n")
-/*
         _T("    bufsize= The size (in bytes) of the enumeration buffer\n")
         _T("             (default = 4096)\n")
         _T("    ri=      The resume index number at which to begin the 
enumeration\n")
         _T("             (default = 0)\n")
         _T("    group=   Service group to enumerate\n")
         _T("             (default = all groups)\n")
-*/
         _T("SYNTAX EXAMPLES\n")
         _T("sc query                - Enumerates status for active services & 
drivers\n")
         _T("sc query messenger      - Displays status for the messenger 
service\n")
@@ -83,9 +81,9 @@ VOID MainUsage(VOID)
         _T("sc query type= driver   - Enumerates only active drivers\n")
         _T("sc query type= service  - Enumerates only Win32 services\n")
         _T("sc query state= all     - Enumerates all services & drivers\n")
-//        _T("sc query bufsize= 50    - Enumerates with a 50 byte buffer.\n")
-//        _T("sc query ri= 14         - Enumerates with resume index = 14\n")
-//        _T("sc queryex group= ""    - Enumerates active services not in a 
group\n")
+        _T("sc query bufsize= 50    - Enumerates with a 50 byte buffer.\n")
+        _T("sc query ri= 14         - Enumerates with resume index = 14\n")
+        _T("sc queryex group= ""    - Enumerates active services not in a 
group\n")
         _T("sc query type= service type= interact - Enumerates all interactive 
services\n")
         _T("sc query type= driver group= NDIS     - Enumerates all NDIS 
drivers\n"));
     }

Reply via email to