https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9d91a2e8cea8b17fdf64171724ed07fda4546aab

commit 9d91a2e8cea8b17fdf64171724ed07fda4546aab
Author: Pierre Schweitzer <[email protected]>
AuthorDate: Fri Dec 8 22:45:04 2017 +0100

    [SERVICES] Fix querying the status of a registered but not started driver.
    The current implementation was broken and some dead code was never called; 
always failing before.
    This fix revives this dead code!
    Extra fix: avoid derefencing potential null-ptr.
    And also, as bonus, comment the function so that logic can be easily 
understood.
    
    CORE-14062
---
 base/system/services/driver.c | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/base/system/services/driver.c b/base/system/services/driver.c
index 34be894659..4248ac95c9 100644
--- a/base/system/services/driver.c
+++ b/base/system/services/driver.c
@@ -140,8 +140,13 @@ ScmGetDriverStatus(PSERVICE lpService,
 
     DPRINT1("ScmGetDriverStatus() called\n");
 
-    memset(lpServiceStatus, 0, sizeof(SERVICE_STATUS));
+    /* Zero output buffer if any */
+    if (lpServiceStatus != NULL)
+    {
+        memset(lpServiceStatus, 0, sizeof(SERVICE_STATUS));
+    }
 
+    /* Select the appropriate object directory based on driver type */
     if (lpService->Status.dwServiceType == SERVICE_KERNEL_DRIVER)
     {
         RtlInitUnicodeString(&DirName, L"\\Driver");
@@ -158,6 +163,7 @@ ScmGetDriverStatus(PSERVICE lpService,
                                NULL,
                                NULL);
 
+    /* Open the object directory where loaded drivers are */
     Status = NtOpenDirectoryObject(&DirHandle,
                                    DIRECTORY_QUERY | DIRECTORY_TRAVERSE,
                                    &ObjectAttributes);
@@ -167,12 +173,14 @@ ScmGetDriverStatus(PSERVICE lpService,
         return RtlNtStatusToDosError(Status);
     }
 
+    /* Allocate a buffer big enough for querying the object */
     BufferLength = sizeof(OBJECT_DIRECTORY_INFORMATION) +
                    2 * MAX_PATH * sizeof(WCHAR);
     DirInfo = (OBJECT_DIRECTORY_INFORMATION*) HeapAlloc(GetProcessHeap(),
                         HEAP_ZERO_MEMORY,
                         BufferLength);
 
+    /* Now, start browsing entry by entry */
     Index = 0;
     while (TRUE)
     {
@@ -183,19 +191,23 @@ ScmGetDriverStatus(PSERVICE lpService,
                                         FALSE,
                                         &Index,
                                         &DataLength);
+        /* End of enumeration, the driver was not found */
         if (Status == STATUS_NO_MORE_ENTRIES)
         {
             DPRINT("No more services\n");
             break;
         }
 
+        /* Other error, fail */
         if (!NT_SUCCESS(Status))
             break;
 
         DPRINT("Comparing: '%S'  '%wZ'\n", lpService->lpServiceName, 
&DirInfo->Name);
 
+        /* Compare names to check whether it matches our driver */
         if (_wcsicmp(lpService->lpServiceName, DirInfo->Name.Buffer) == 0)
         {
+            /* That's our driver, bail out! */
             DPRINT1("Found: '%S'  '%wZ'\n",
                     lpService->lpServiceName, &DirInfo->Name);
             bFound = TRUE;
@@ -204,17 +216,27 @@ ScmGetDriverStatus(PSERVICE lpService,
         }
     }
 
+    /* Release resources we don't need */
     HeapFree(GetProcessHeap(),
              0,
              DirInfo);
     NtClose(DirHandle);
 
-    if (!NT_SUCCESS(Status))
+    /* Only quit if there's a failure
+     * Not having found the driver is legit!
+     * It means the driver was registered as a service, but not loaded
+     * We have not to fail in that situation, but to return proper status
+     */
+    if (!NT_SUCCESS(Status) && Status != STATUS_NO_MORE_ENTRIES)
     {
         DPRINT1("Status: %lx\n", Status);
         return RtlNtStatusToDosError(Status);
     }
 
+    /* Now, we have two cases:
+     * We found the driver: it means it's running
+     * We didn't find the driver: it wasn't running
+     */
     if ((bFound != FALSE) &&
         (lpService->Status.dwCurrentState != SERVICE_STOP_PENDING))
     {
@@ -235,6 +257,7 @@ ScmGetDriverStatus(PSERVICE lpService,
                 lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;
         }
     }
+    /* Not found, return it's stopped */
     else
     {
         lpService->Status.dwCurrentState = SERVICE_STOPPED;
@@ -248,6 +271,7 @@ ScmGetDriverStatus(PSERVICE lpService,
             lpService->Status.dwWin32ExitCode = ERROR_GEN_FAILURE;
     }
 
+    /* Copy service status if required */
     if (lpServiceStatus != NULL)
     {
         memcpy(lpServiceStatus,

Reply via email to