mirror of
https://github.com/reactos/reactos.git
synced 2025-07-25 11:04:05 +00:00
[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
This commit is contained in:
parent
81532227b6
commit
9d91a2e8ce
1 changed files with 26 additions and 2 deletions
|
@ -140,8 +140,13 @@ ScmGetDriverStatus(PSERVICE lpService,
|
||||||
|
|
||||||
DPRINT1("ScmGetDriverStatus() called\n");
|
DPRINT1("ScmGetDriverStatus() called\n");
|
||||||
|
|
||||||
|
/* Zero output buffer if any */
|
||||||
|
if (lpServiceStatus != NULL)
|
||||||
|
{
|
||||||
memset(lpServiceStatus, 0, sizeof(SERVICE_STATUS));
|
memset(lpServiceStatus, 0, sizeof(SERVICE_STATUS));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Select the appropriate object directory based on driver type */
|
||||||
if (lpService->Status.dwServiceType == SERVICE_KERNEL_DRIVER)
|
if (lpService->Status.dwServiceType == SERVICE_KERNEL_DRIVER)
|
||||||
{
|
{
|
||||||
RtlInitUnicodeString(&DirName, L"\\Driver");
|
RtlInitUnicodeString(&DirName, L"\\Driver");
|
||||||
|
@ -158,6 +163,7 @@ ScmGetDriverStatus(PSERVICE lpService,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
/* Open the object directory where loaded drivers are */
|
||||||
Status = NtOpenDirectoryObject(&DirHandle,
|
Status = NtOpenDirectoryObject(&DirHandle,
|
||||||
DIRECTORY_QUERY | DIRECTORY_TRAVERSE,
|
DIRECTORY_QUERY | DIRECTORY_TRAVERSE,
|
||||||
&ObjectAttributes);
|
&ObjectAttributes);
|
||||||
|
@ -167,12 +173,14 @@ ScmGetDriverStatus(PSERVICE lpService,
|
||||||
return RtlNtStatusToDosError(Status);
|
return RtlNtStatusToDosError(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Allocate a buffer big enough for querying the object */
|
||||||
BufferLength = sizeof(OBJECT_DIRECTORY_INFORMATION) +
|
BufferLength = sizeof(OBJECT_DIRECTORY_INFORMATION) +
|
||||||
2 * MAX_PATH * sizeof(WCHAR);
|
2 * MAX_PATH * sizeof(WCHAR);
|
||||||
DirInfo = (OBJECT_DIRECTORY_INFORMATION*) HeapAlloc(GetProcessHeap(),
|
DirInfo = (OBJECT_DIRECTORY_INFORMATION*) HeapAlloc(GetProcessHeap(),
|
||||||
HEAP_ZERO_MEMORY,
|
HEAP_ZERO_MEMORY,
|
||||||
BufferLength);
|
BufferLength);
|
||||||
|
|
||||||
|
/* Now, start browsing entry by entry */
|
||||||
Index = 0;
|
Index = 0;
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
|
@ -183,19 +191,23 @@ ScmGetDriverStatus(PSERVICE lpService,
|
||||||
FALSE,
|
FALSE,
|
||||||
&Index,
|
&Index,
|
||||||
&DataLength);
|
&DataLength);
|
||||||
|
/* End of enumeration, the driver was not found */
|
||||||
if (Status == STATUS_NO_MORE_ENTRIES)
|
if (Status == STATUS_NO_MORE_ENTRIES)
|
||||||
{
|
{
|
||||||
DPRINT("No more services\n");
|
DPRINT("No more services\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Other error, fail */
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
DPRINT("Comparing: '%S' '%wZ'\n", lpService->lpServiceName, &DirInfo->Name);
|
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)
|
if (_wcsicmp(lpService->lpServiceName, DirInfo->Name.Buffer) == 0)
|
||||||
{
|
{
|
||||||
|
/* That's our driver, bail out! */
|
||||||
DPRINT1("Found: '%S' '%wZ'\n",
|
DPRINT1("Found: '%S' '%wZ'\n",
|
||||||
lpService->lpServiceName, &DirInfo->Name);
|
lpService->lpServiceName, &DirInfo->Name);
|
||||||
bFound = TRUE;
|
bFound = TRUE;
|
||||||
|
@ -204,17 +216,27 @@ ScmGetDriverStatus(PSERVICE lpService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Release resources we don't need */
|
||||||
HeapFree(GetProcessHeap(),
|
HeapFree(GetProcessHeap(),
|
||||||
0,
|
0,
|
||||||
DirInfo);
|
DirInfo);
|
||||||
NtClose(DirHandle);
|
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);
|
DPRINT1("Status: %lx\n", Status);
|
||||||
return RtlNtStatusToDosError(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) &&
|
if ((bFound != FALSE) &&
|
||||||
(lpService->Status.dwCurrentState != SERVICE_STOP_PENDING))
|
(lpService->Status.dwCurrentState != SERVICE_STOP_PENDING))
|
||||||
{
|
{
|
||||||
|
@ -235,6 +257,7 @@ ScmGetDriverStatus(PSERVICE lpService,
|
||||||
lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;
|
lpService->Status.dwWin32ExitCode = ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Not found, return it's stopped */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lpService->Status.dwCurrentState = SERVICE_STOPPED;
|
lpService->Status.dwCurrentState = SERVICE_STOPPED;
|
||||||
|
@ -248,6 +271,7 @@ ScmGetDriverStatus(PSERVICE lpService,
|
||||||
lpService->Status.dwWin32ExitCode = ERROR_GEN_FAILURE;
|
lpService->Status.dwWin32ExitCode = ERROR_GEN_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Copy service status if required */
|
||||||
if (lpServiceStatus != NULL)
|
if (lpServiceStatus != NULL)
|
||||||
{
|
{
|
||||||
memcpy(lpServiceStatus,
|
memcpy(lpServiceStatus,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue