mirror of
https://github.com/reactos/reactos.git
synced 2024-11-20 06:15:26 +00:00
[FREELDR:NTLDR] Use NTOS kernel's CMBOOT functions to enumerate and build the boot-time driver list.
They are correct and are more performant. - Rewrite WinLdrAddDriverToList() on the model of CmpAddDriverToList() with support for CmpIsDriverInList(). - Disable RegEnumKey() as it is now unused.
This commit is contained in:
parent
02e659d248
commit
94874baf19
7 changed files with 336 additions and 432 deletions
|
@ -48,6 +48,7 @@ list(APPEND FREELDR_BOOTLIB_SOURCE
|
|||
lib/mm/heap.c)
|
||||
|
||||
list(APPEND FREELDR_NTLDR_SOURCE
|
||||
${REACTOS_SOURCE_DIR}/ntoskrnl/config/cmboot.c
|
||||
ntldr/conversion.c
|
||||
ntldr/registry.c
|
||||
ntldr/winldr.c
|
||||
|
|
|
@ -242,6 +242,7 @@ GetNextPathElement(
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
LONG
|
||||
RegEnumKey(
|
||||
_In_ HKEY Key,
|
||||
|
@ -312,6 +313,7 @@ RegEnumKey(
|
|||
TRACE("RegEnumKey done -> %u, '%.*S'\n", *NameSize, *NameSize, Name);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
LONG
|
||||
RegOpenKey(
|
||||
|
|
|
@ -44,6 +44,7 @@ extern HKEY CurrentControlSetKey;
|
|||
*/
|
||||
#define RegCloseKey(hKey) (ERROR_SUCCESS)
|
||||
|
||||
#if 0
|
||||
LONG
|
||||
RegEnumKey(
|
||||
_In_ HKEY Key,
|
||||
|
@ -51,6 +52,7 @@ RegEnumKey(
|
|||
_Out_ PWCHAR Name,
|
||||
_Inout_ PULONG NameSize,
|
||||
_Out_opt_ PHKEY SubKey);
|
||||
#endif
|
||||
|
||||
LONG
|
||||
RegOpenKey(
|
||||
|
|
|
@ -135,17 +135,22 @@ SetupLdrInitErrataInf(
|
|||
}
|
||||
|
||||
static VOID
|
||||
SetupLdrScanBootDrivers(PLIST_ENTRY BootDriverListHead, HINF InfHandle, PCSTR SearchPath)
|
||||
SetupLdrScanBootDrivers(
|
||||
_Inout_ PLIST_ENTRY BootDriverListHead,
|
||||
_In_ HINF InfHandle,
|
||||
_In_ PCSTR SearchPath)
|
||||
{
|
||||
INFCONTEXT InfContext, dirContext;
|
||||
BOOLEAN Success;
|
||||
PCSTR Media, DriverName, dirIndex, ImagePath;
|
||||
WCHAR ServiceName[256];
|
||||
WCHAR ImagePathW[256];
|
||||
BOOLEAN Success;
|
||||
WCHAR ImagePathW[MAX_PATH];
|
||||
WCHAR DriverNameW[256];
|
||||
|
||||
/* Open inf section */
|
||||
UNREFERENCED_PARAMETER(SearchPath);
|
||||
|
||||
/* Open INF section */
|
||||
if (!InfFindFirstLine(InfHandle, "SourceDisksFiles", NULL, &InfContext))
|
||||
return;
|
||||
goto Quit;
|
||||
|
||||
/* Load all listed boot drivers */
|
||||
do
|
||||
|
@ -158,30 +163,51 @@ SetupLdrScanBootDrivers(PLIST_ENTRY BootDriverListHead, HINF InfHandle, PCSTR Se
|
|||
InfFindFirstLine(InfHandle, "Directories", dirIndex, &dirContext) &&
|
||||
InfGetDataField(&dirContext, 1, &ImagePath))
|
||||
{
|
||||
/* Convert name to widechar */
|
||||
swprintf(ServiceName, L"%S", DriverName);
|
||||
|
||||
/* Prepare image path */
|
||||
swprintf(ImagePathW, L"%S", ImagePath);
|
||||
wcscat(ImagePathW, L"\\");
|
||||
wcscat(ImagePathW, ServiceName);
|
||||
RtlStringCbPrintfW(ImagePathW, sizeof(ImagePathW),
|
||||
L"%S\\%S", ImagePath, DriverName);
|
||||
|
||||
/* Remove .sys extension */
|
||||
ServiceName[wcslen(ServiceName) - 4] = 0;
|
||||
/* Convert name to unicode and remove .sys extension */
|
||||
RtlStringCbPrintfW(DriverNameW, sizeof(DriverNameW),
|
||||
L"%S", DriverName);
|
||||
DriverNameW[wcslen(DriverNameW) - 4] = UNICODE_NULL;
|
||||
|
||||
/* Add it to the list */
|
||||
Success = WinLdrAddDriverToList(BootDriverListHead,
|
||||
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
|
||||
FALSE,
|
||||
DriverNameW,
|
||||
ImagePathW,
|
||||
ServiceName);
|
||||
NULL,
|
||||
SERVICE_ERROR_NORMAL,
|
||||
-1);
|
||||
if (!Success)
|
||||
{
|
||||
ERR("Could not add boot driver '%s', '%s'\n", SearchPath, DriverName);
|
||||
return;
|
||||
ERR("Could not add boot driver '%s'\n", DriverName);
|
||||
/* Ignore and continue adding other drivers */
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (InfFindNextLine(&InfContext, &InfContext));
|
||||
|
||||
Quit:
|
||||
/* Finally, add the boot filesystem driver to the list */
|
||||
if (BootFileSystem)
|
||||
{
|
||||
TRACE("Adding filesystem driver %S\n", BootFileSystem);
|
||||
Success = WinLdrAddDriverToList(BootDriverListHead,
|
||||
FALSE,
|
||||
BootFileSystem,
|
||||
NULL,
|
||||
L"Boot File System",
|
||||
SERVICE_ERROR_CRITICAL,
|
||||
-1);
|
||||
if (!Success)
|
||||
ERR("Failed to add filesystem driver %S\n", BootFileSystem);
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("No required filesystem driver\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "winldr.h"
|
||||
#include "ntldropts.h"
|
||||
#include "registry.h"
|
||||
#include <internal/cmboot.h>
|
||||
|
||||
#include <debug.h>
|
||||
DBG_DEFAULT_CHANNEL(WINDOWS);
|
||||
|
@ -26,6 +27,7 @@ extern BOOLEAN WinLdrTerminalConnected;
|
|||
extern VOID WinLdrSetupEms(IN PCSTR BootOptions);
|
||||
|
||||
PLOADER_SYSTEM_BLOCK WinLdrSystemBlock;
|
||||
/**/PCWSTR BootFileSystem = NULL;/**/
|
||||
|
||||
BOOLEAN VirtualBias = FALSE;
|
||||
BOOLEAN SosEnabled = FALSE;
|
||||
|
@ -363,23 +365,30 @@ WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
|
|||
PCSTR BootPath)
|
||||
{
|
||||
PLIST_ENTRY NextBd;
|
||||
PBOOT_DRIVER_NODE DriverNode;
|
||||
PBOOT_DRIVER_LIST_ENTRY BootDriver;
|
||||
BOOLEAN Success;
|
||||
BOOLEAN ret = TRUE;
|
||||
|
||||
// Walk through the boot drivers list
|
||||
/* Walk through the boot drivers list */
|
||||
NextBd = LoaderBlock->BootDriverListHead.Flink;
|
||||
|
||||
while (NextBd != &LoaderBlock->BootDriverListHead)
|
||||
{
|
||||
BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, Link);
|
||||
DriverNode = CONTAINING_RECORD(NextBd,
|
||||
BOOT_DRIVER_NODE,
|
||||
ListEntry.Link);
|
||||
BootDriver = &DriverNode->ListEntry;
|
||||
|
||||
TRACE("BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
|
||||
BootDriver->LdrEntry, &BootDriver->RegistryPath);
|
||||
/* Get the next list entry as we may remove the current one on failure */
|
||||
NextBd = BootDriver->Link.Flink;
|
||||
|
||||
TRACE("BootDriver %wZ DTE %08X RegPath: %wZ\n",
|
||||
&BootDriver->FilePath, BootDriver->LdrEntry,
|
||||
&BootDriver->RegistryPath);
|
||||
|
||||
// Paths are relative (FIXME: Are they always relative?)
|
||||
|
||||
// Load it
|
||||
/* Load it */
|
||||
UiIndicateProgress();
|
||||
Success = WinLdrLoadDeviceDriver(&LoaderBlock->LoadOrderListHead,
|
||||
BootPath,
|
||||
|
@ -388,23 +397,25 @@ WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
|
|||
&BootDriver->LdrEntry);
|
||||
if (Success)
|
||||
{
|
||||
// Convert the RegistryPath and DTE addresses to VA since we are not going to use it anymore
|
||||
/* Convert the addresses to VA since we are not going to use them anymore */
|
||||
BootDriver->RegistryPath.Buffer = PaToVa(BootDriver->RegistryPath.Buffer);
|
||||
BootDriver->FilePath.Buffer = PaToVa(BootDriver->FilePath.Buffer);
|
||||
BootDriver->LdrEntry = PaToVa(BootDriver->LdrEntry);
|
||||
|
||||
if (DriverNode->Group.Buffer)
|
||||
DriverNode->Group.Buffer = PaToVa(DriverNode->Group.Buffer);
|
||||
DriverNode->Name.Buffer = PaToVa(DriverNode->Name.Buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Loading failed - cry loudly
|
||||
ERR("Can't load boot driver '%wZ'!\n", &BootDriver->FilePath);
|
||||
UiMessageBox("Can't load boot driver '%wZ'!", &BootDriver->FilePath);
|
||||
/* Loading failed: cry loudly */
|
||||
ERR("Cannot load boot driver '%wZ'!\n", &BootDriver->FilePath);
|
||||
UiMessageBox("Cannot load boot driver '%wZ'!", &BootDriver->FilePath);
|
||||
ret = FALSE;
|
||||
|
||||
// Remove it from the list and try to continue
|
||||
RemoveEntryList(NextBd);
|
||||
/* Remove it from the list and try to continue */
|
||||
RemoveEntryList(&BootDriver->Link);
|
||||
}
|
||||
|
||||
NextBd = BootDriver->Link.Flink;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -61,6 +61,7 @@ typedef struct _LOADER_SYSTEM_BLOCK
|
|||
} LOADER_SYSTEM_BLOCK, *PLOADER_SYSTEM_BLOCK;
|
||||
|
||||
extern PLOADER_SYSTEM_BLOCK WinLdrSystemBlock;
|
||||
/**/extern PCWSTR BootFileSystem;/**/
|
||||
|
||||
|
||||
// conversion.c
|
||||
|
@ -71,7 +72,6 @@ VOID List_PaToVa(_In_ LIST_ENTRY *ListEntry);
|
|||
#endif
|
||||
VOID ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start);
|
||||
|
||||
|
||||
// winldr.c
|
||||
extern BOOLEAN SosEnabled;
|
||||
#ifdef _M_IX86
|
||||
|
@ -117,14 +117,6 @@ WinLdrInitSystemHive(
|
|||
BOOLEAN WinLdrScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
IN PCSTR SystemRoot);
|
||||
|
||||
// winldr.c
|
||||
VOID
|
||||
WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
PCSTR Options,
|
||||
PCSTR SystemPath,
|
||||
PCSTR BootPath,
|
||||
USHORT VersionToBoot);
|
||||
|
||||
BOOLEAN
|
||||
WinLdrLoadNLSData(
|
||||
_Inout_ PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
|
@ -135,10 +127,22 @@ WinLdrLoadNLSData(
|
|||
_In_ PCUNICODE_STRING OemHalFileName);
|
||||
|
||||
BOOLEAN
|
||||
WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead,
|
||||
PWSTR RegistryPath,
|
||||
PWSTR ImagePath,
|
||||
PWSTR ServiceName);
|
||||
WinLdrAddDriverToList(
|
||||
_Inout_ PLIST_ENTRY DriverListHead,
|
||||
_In_ BOOLEAN InsertAtHead,
|
||||
_In_ PCWSTR DriverName,
|
||||
_In_opt_ PCWSTR ImagePath,
|
||||
_In_opt_ PCWSTR GroupName,
|
||||
_In_ ULONG ErrorControl,
|
||||
_In_ ULONG Tag);
|
||||
|
||||
// winldr.c
|
||||
VOID
|
||||
WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||
PCSTR Options,
|
||||
PCSTR SystemPath,
|
||||
PCSTR BootPath,
|
||||
USHORT VersionToBoot);
|
||||
|
||||
VOID
|
||||
WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <freeldr.h>
|
||||
#include "winldr.h"
|
||||
#include "registry.h"
|
||||
#include <internal/cmboot.h>
|
||||
|
||||
#include <debug.h>
|
||||
DBG_DEFAULT_CHANNEL(WINDOWS);
|
||||
|
@ -26,9 +27,9 @@ WinLdrGetNLSNames(
|
|||
_Inout_ PUNICODE_STRING LangFileName, // CaseTable
|
||||
_Inout_ PUNICODE_STRING OemHalFileName);
|
||||
|
||||
static VOID
|
||||
WinLdrScanRegistry(IN OUT PLIST_ENTRY BootDriverListHead,
|
||||
IN PCSTR SystemRoot);
|
||||
static BOOLEAN
|
||||
WinLdrScanRegistry(
|
||||
IN OUT PLIST_ENTRY BootDriverListHead);
|
||||
|
||||
|
||||
/* FUNCTIONS **************************************************************/
|
||||
|
@ -47,7 +48,6 @@ WinLdrLoadSystemHive(
|
|||
PVOID HiveDataPhysical;
|
||||
PVOID HiveDataVirtual;
|
||||
ULONG BytesRead;
|
||||
PCWSTR FsService;
|
||||
|
||||
/* Concatenate path and filename to get the full name */
|
||||
RtlStringCbCopyA(FullHiveName, sizeof(FullHiveName), DirectoryPath);
|
||||
|
@ -99,23 +99,8 @@ WinLdrLoadSystemHive(
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* Add boot filesystem driver to the list */
|
||||
FsService = FsGetServiceName(FileId);
|
||||
if (FsService)
|
||||
{
|
||||
BOOLEAN Success;
|
||||
TRACE("Adding filesystem service %S\n", FsService);
|
||||
Success = WinLdrAddDriverToList(&LoaderBlock->BootDriverListHead,
|
||||
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
|
||||
NULL,
|
||||
(PWSTR)FsService);
|
||||
if (!Success)
|
||||
TRACE("Failed to add filesystem service\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("No required filesystem service\n");
|
||||
}
|
||||
// FIXME: HACK: Get the boot filesystem driver name now...
|
||||
BootFileSystem = FsGetServiceName(FileId);
|
||||
|
||||
ArcClose(FileId);
|
||||
return TRUE;
|
||||
|
@ -184,7 +169,12 @@ BOOLEAN WinLdrScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
|||
CHAR SearchPath[1024];
|
||||
|
||||
/* Scan registry and prepare boot drivers list */
|
||||
WinLdrScanRegistry(&LoaderBlock->BootDriverListHead, SystemRoot);
|
||||
Success = WinLdrScanRegistry(&LoaderBlock->BootDriverListHead);
|
||||
if (!Success)
|
||||
{
|
||||
UiMessageBox("Failed to load boot drivers!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Get names of NLS files */
|
||||
Success = WinLdrGetNLSNames(CurrentControlSetKey,
|
||||
|
@ -517,412 +507,280 @@ Quit:
|
|||
return (Status == ESUCCESS);
|
||||
}
|
||||
|
||||
static VOID
|
||||
WinLdrScanRegistry(IN OUT PLIST_ENTRY BootDriverListHead,
|
||||
IN PCSTR SystemRoot)
|
||||
static BOOLEAN
|
||||
WinLdrScanRegistry(
|
||||
IN OUT PLIST_ENTRY BootDriverListHead)
|
||||
{
|
||||
LONG rc = 0;
|
||||
HKEY hOrderKey, hServiceKey, hGroupKey, hDriverKey;
|
||||
PWSTR GroupNameBuffer = NULL;
|
||||
WCHAR ServiceName[256];
|
||||
ULONG OrderList[128];
|
||||
ULONG BufferSize;
|
||||
ULONG Index;
|
||||
ULONG TagIndex;
|
||||
PWSTR GroupName;
|
||||
|
||||
ULONG ValueSize;
|
||||
ULONG ValueType;
|
||||
ULONG StartValue;
|
||||
ULONG TagValue;
|
||||
WCHAR DriverGroup[256];
|
||||
ULONG DriverGroupSize;
|
||||
|
||||
CHAR ImagePath[256];
|
||||
WCHAR TempImagePath[256];
|
||||
|
||||
BOOLEAN Success;
|
||||
|
||||
/* Get 'group order list' key */
|
||||
rc = RegOpenKey(CurrentControlSetKey, L"Control\\GroupOrderList", &hOrderKey);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
TRACE_CH(REACTOS, "Failed to open the 'GroupOrderList' key (rc %d)\n", (int)rc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get 'services' key */
|
||||
rc = RegOpenKey(CurrentControlSetKey, L"Services", &hServiceKey);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
TRACE_CH(REACTOS, "Failed to open the 'Services' key (rc %d)\n", (int)rc);
|
||||
RegCloseKey(hOrderKey);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get 'service group order' key */
|
||||
rc = RegOpenKey(CurrentControlSetKey, L"Control\\ServiceGroupOrder", &hGroupKey);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
TRACE_CH(REACTOS, "Failed to open the 'ServiceGroupOrder' key (rc %d)\n", (int)rc);
|
||||
/* Find all boot drivers */
|
||||
Success = CmpFindDrivers(SystemHive,
|
||||
(HCELL_INDEX)CurrentControlSetKey,
|
||||
BootLoad,
|
||||
BootFileSystem,
|
||||
BootDriverListHead);
|
||||
if (!Success)
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
/* Get the Group Order List */
|
||||
BufferSize = 4096;
|
||||
GroupNameBuffer = FrLdrHeapAlloc(BufferSize, TAG_WLDR_NAME);
|
||||
if (!GroupNameBuffer)
|
||||
{
|
||||
TRACE_CH(REACTOS, "Failed to allocate buffer\n");
|
||||
RegCloseKey(hGroupKey);
|
||||
/* Sort by group/tag */
|
||||
Success = CmpSortDriverList(SystemHive,
|
||||
(HCELL_INDEX)CurrentControlSetKey,
|
||||
BootDriverListHead);
|
||||
if (!Success)
|
||||
goto Quit;
|
||||
}
|
||||
rc = RegQueryValue(hGroupKey, L"List", NULL, (PUCHAR)GroupNameBuffer, &BufferSize);
|
||||
RegCloseKey(hGroupKey);
|
||||
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
TRACE_CH(REACTOS, "Failed to query the 'List' value (rc %d)\n", (int)rc);
|
||||
/* Remove circular dependencies (cycles) and sort */
|
||||
Success = CmpResolveDriverDependencies(BootDriverListHead);
|
||||
if (!Success)
|
||||
goto Quit;
|
||||
}
|
||||
TRACE_CH(REACTOS, "BufferSize: %d\n", (int)BufferSize);
|
||||
TRACE_CH(REACTOS, "GroupNameBuffer: '%S'\n", GroupNameBuffer);
|
||||
|
||||
/* Loop through each group */
|
||||
GroupName = GroupNameBuffer;
|
||||
while (*GroupName)
|
||||
{
|
||||
TRACE("Driver group: '%S'\n", GroupName);
|
||||
|
||||
/* Query the Order */
|
||||
BufferSize = sizeof(OrderList);
|
||||
rc = RegQueryValue(hOrderKey, GroupName, NULL, (PUCHAR)OrderList, &BufferSize);
|
||||
if (rc != ERROR_SUCCESS) OrderList[0] = 0;
|
||||
|
||||
/* Enumerate all drivers */
|
||||
for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++)
|
||||
{
|
||||
for (Index = 0; TRUE; Index++)
|
||||
{
|
||||
/* Get the Driver's Name */
|
||||
ValueSize = sizeof(ServiceName);
|
||||
rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize, &hDriverKey);
|
||||
TRACE("RegEnumKey(): rc %d\n", (int)rc);
|
||||
|
||||
/* Make sure it's valid, and check if we're done */
|
||||
if (rc == ERROR_NO_MORE_ITEMS)
|
||||
break;
|
||||
if (rc != ERROR_SUCCESS)
|
||||
goto Quit;
|
||||
//TRACE_CH(REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName);
|
||||
|
||||
/* Read the Start Value */
|
||||
ValueSize = sizeof(ULONG);
|
||||
rc = RegQueryValue(hDriverKey, L"Start", &ValueType, (PUCHAR)&StartValue, &ValueSize);
|
||||
if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1;
|
||||
//TRACE_CH(REACTOS, " Start: %x\n", (int)StartValue);
|
||||
|
||||
/* Read the Tag */
|
||||
ValueSize = sizeof(ULONG);
|
||||
rc = RegQueryValue(hDriverKey, L"Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize);
|
||||
if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1;
|
||||
//TRACE_CH(REACTOS, " Tag: %x\n", (int)TagValue);
|
||||
|
||||
/* Read the driver's group */
|
||||
DriverGroupSize = sizeof(DriverGroup);
|
||||
rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize);
|
||||
//TRACE_CH(REACTOS, " Group: '%S'\n", DriverGroup);
|
||||
|
||||
/* Make sure it should be started */
|
||||
if ((StartValue == 0) &&
|
||||
(TagValue == OrderList[TagIndex]) &&
|
||||
(_wcsicmp(DriverGroup, GroupName) == 0))
|
||||
{
|
||||
/* Get the Driver's Location */
|
||||
ValueSize = sizeof(TempImagePath);
|
||||
rc = RegQueryValue(hDriverKey, L"ImagePath", NULL, (PUCHAR)TempImagePath, &ValueSize);
|
||||
|
||||
/* Write the whole path if it succeeded, else prepare to fail */
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
TRACE_CH(REACTOS, "ImagePath: not found\n");
|
||||
TempImagePath[0] = 0;
|
||||
RtlStringCbPrintfA(ImagePath, sizeof(ImagePath), "%s\\system32\\drivers\\%S.sys", SystemRoot, ServiceName);
|
||||
}
|
||||
else if (TempImagePath[0] != L'\\')
|
||||
{
|
||||
RtlStringCbPrintfA(ImagePath, sizeof(ImagePath), "%s%S", SystemRoot, TempImagePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlStringCbPrintfA(ImagePath, sizeof(ImagePath), "%S", TempImagePath);
|
||||
TRACE_CH(REACTOS, "ImagePath: '%s'\n", ImagePath);
|
||||
}
|
||||
|
||||
TRACE("Adding boot driver: '%s'\n", ImagePath);
|
||||
|
||||
Success = WinLdrAddDriverToList(BootDriverListHead,
|
||||
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
|
||||
TempImagePath,
|
||||
ServiceName);
|
||||
if (!Success)
|
||||
ERR("Failed to add boot driver\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
//TRACE(" Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current Tag %d, current group '%S')\n",
|
||||
// ServiceName, StartValue, TagValue, DriverGroup, OrderList[TagIndex], GroupName);
|
||||
}
|
||||
|
||||
RegCloseKey(hDriverKey);
|
||||
}
|
||||
}
|
||||
|
||||
for (Index = 0; TRUE; Index++)
|
||||
{
|
||||
/* Get the Driver's Name */
|
||||
ValueSize = sizeof(ServiceName);
|
||||
rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize, &hDriverKey);
|
||||
|
||||
//TRACE_CH(REACTOS, "RegEnumKey(): rc %d\n", (int)rc);
|
||||
if (rc == ERROR_NO_MORE_ITEMS)
|
||||
break;
|
||||
if (rc != ERROR_SUCCESS)
|
||||
goto Quit;
|
||||
TRACE("Service %d: '%S'\n", (int)Index, ServiceName);
|
||||
|
||||
/* Read the Start Value */
|
||||
ValueSize = sizeof(ULONG);
|
||||
rc = RegQueryValue(hDriverKey, L"Start", &ValueType, (PUCHAR)&StartValue, &ValueSize);
|
||||
if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1;
|
||||
//TRACE_CH(REACTOS, " Start: %x\n", (int)StartValue);
|
||||
|
||||
/* Read the Tag */
|
||||
ValueSize = sizeof(ULONG);
|
||||
rc = RegQueryValue(hDriverKey, L"Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize);
|
||||
if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1;
|
||||
//TRACE_CH(REACTOS, " Tag: %x\n", (int)TagValue);
|
||||
|
||||
/* Read the driver's group */
|
||||
DriverGroupSize = sizeof(DriverGroup);
|
||||
rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize);
|
||||
//TRACE_CH(REACTOS, " Group: '%S'\n", DriverGroup);
|
||||
|
||||
for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++)
|
||||
{
|
||||
if (TagValue == OrderList[TagIndex]) break;
|
||||
}
|
||||
|
||||
if ((StartValue == 0) &&
|
||||
(TagIndex > OrderList[0]) &&
|
||||
(_wcsicmp(DriverGroup, GroupName) == 0))
|
||||
{
|
||||
ValueSize = sizeof(TempImagePath);
|
||||
rc = RegQueryValue(hDriverKey, L"ImagePath", NULL, (PUCHAR)TempImagePath, &ValueSize);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
TRACE_CH(REACTOS, "ImagePath: not found\n");
|
||||
TempImagePath[0] = 0;
|
||||
RtlStringCbPrintfA(ImagePath, sizeof(ImagePath), "%ssystem32\\drivers\\%S.sys", SystemRoot, ServiceName);
|
||||
}
|
||||
else if (TempImagePath[0] != L'\\')
|
||||
{
|
||||
RtlStringCbPrintfA(ImagePath, sizeof(ImagePath), "%s%S", SystemRoot, TempImagePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlStringCbPrintfA(ImagePath, sizeof(ImagePath), "%S", TempImagePath);
|
||||
TRACE_CH(REACTOS, "ImagePath: '%s'\n", ImagePath);
|
||||
}
|
||||
TRACE(" Adding boot driver: '%s'\n", ImagePath);
|
||||
|
||||
Success = WinLdrAddDriverToList(BootDriverListHead,
|
||||
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
|
||||
TempImagePath,
|
||||
ServiceName);
|
||||
if (!Success)
|
||||
ERR(" Failed to add boot driver\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
//TRACE(" Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current group '%S')\n",
|
||||
// ServiceName, StartValue, TagValue, DriverGroup, GroupName);
|
||||
}
|
||||
|
||||
RegCloseKey(hDriverKey);
|
||||
}
|
||||
|
||||
/* Move to the next group name */
|
||||
GroupName = GroupName + wcslen(GroupName) + 1;
|
||||
}
|
||||
|
||||
Quit:
|
||||
/* Free allocated memory */
|
||||
if (GroupNameBuffer)
|
||||
FrLdrHeapFree(GroupNameBuffer, TAG_WLDR_NAME);
|
||||
/* In case of failure, free the boot driver list */
|
||||
if (!Success)
|
||||
CmpFreeDriverList(SystemHive, BootDriverListHead);
|
||||
|
||||
/* Close the registry key handles */
|
||||
RegCloseKey(hServiceKey);
|
||||
RegCloseKey(hOrderKey);
|
||||
return Success;
|
||||
}
|
||||
|
||||
static
|
||||
/**
|
||||
* @brief
|
||||
* Inserts the specified driver entry into the driver list, or updates
|
||||
* an existing entry with new ImagePath, ErrorControl, Group and Tag values.
|
||||
*
|
||||
* @param[in,out] DriverListHead
|
||||
* The driver list where to insert the driver entry.
|
||||
*
|
||||
* @param[in] InsertAtHead
|
||||
* Whether to insert the driver at the head (TRUE) or at the tail (FALSE)
|
||||
* of the driver list.
|
||||
*
|
||||
* @param[in] DriverName
|
||||
* The driver's name.
|
||||
*
|
||||
* @param[in] ImagePath
|
||||
* Optional path the the driver's image. If none is specified,
|
||||
* a default path is constructed out of the driver's name.
|
||||
*
|
||||
* @param[in] GroupName
|
||||
* Optional driver group name.
|
||||
*
|
||||
* @param[in] ErrorControl
|
||||
* @param[in] Tag
|
||||
* The ErrorControl and group Tag values for the driver.
|
||||
*
|
||||
* @return
|
||||
* TRUE if the driver has been inserted into the list or updated, FALSE if not.
|
||||
**/
|
||||
BOOLEAN
|
||||
InsertInBootDriverList(
|
||||
PLIST_ENTRY BootDriverListHead,
|
||||
PBOOT_DRIVER_LIST_ENTRY BootDriverEntry)
|
||||
WinLdrAddDriverToList(
|
||||
_Inout_ PLIST_ENTRY DriverListHead,
|
||||
_In_ BOOLEAN InsertAtHead,
|
||||
_In_ PCWSTR DriverName,
|
||||
_In_opt_ PCWSTR ImagePath,
|
||||
_In_opt_ PCWSTR GroupName,
|
||||
_In_ ULONG ErrorControl,
|
||||
_In_ ULONG Tag)
|
||||
{
|
||||
PBOOT_DRIVER_NODE DriverNode;
|
||||
PBOOT_DRIVER_LIST_ENTRY DriverEntry;
|
||||
PLIST_ENTRY ListEntry;
|
||||
|
||||
ASSERT(BootDriverEntry->FilePath.Buffer != NULL);
|
||||
ASSERT(BootDriverEntry->RegistryPath.Buffer != NULL);
|
||||
|
||||
for (ListEntry = BootDriverListHead->Flink;
|
||||
ListEntry != BootDriverListHead;
|
||||
ListEntry = ListEntry->Flink)
|
||||
{
|
||||
DriverEntry = CONTAINING_RECORD(ListEntry,
|
||||
BOOT_DRIVER_LIST_ENTRY,
|
||||
Link);
|
||||
if ((DriverEntry->FilePath.Buffer != NULL) &&
|
||||
RtlEqualUnicodeString(&BootDriverEntry->FilePath,
|
||||
&DriverEntry->FilePath,
|
||||
TRUE))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((DriverEntry->RegistryPath.Buffer != NULL) &&
|
||||
RtlEqualUnicodeString(&BootDriverEntry->RegistryPath,
|
||||
&DriverEntry->RegistryPath,
|
||||
TRUE))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
InsertTailList(BootDriverListHead, &BootDriverEntry->Link);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead,
|
||||
PWSTR RegistryPath,
|
||||
PWSTR ImagePath,
|
||||
PWSTR ServiceName)
|
||||
{
|
||||
PBOOT_DRIVER_LIST_ENTRY BootDriverEntry;
|
||||
NTSTATUS Status;
|
||||
BOOLEAN AlreadyInserted;
|
||||
USHORT PathLength;
|
||||
UNICODE_STRING DriverNameU;
|
||||
UNICODE_STRING RegistryPath;
|
||||
UNICODE_STRING FilePath = {0};
|
||||
UNICODE_STRING RegistryString = {0};
|
||||
UNICODE_STRING GroupString = {0};
|
||||
|
||||
BootDriverEntry = FrLdrHeapAlloc(sizeof(BOOT_DRIVER_LIST_ENTRY), TAG_WLDR_BDE);
|
||||
if (!BootDriverEntry)
|
||||
return FALSE;
|
||||
|
||||
// DTE will be filled during actual load of the driver
|
||||
BootDriverEntry->LdrEntry = NULL;
|
||||
|
||||
// Check - if we have a valid ImagePath, if not - we need to build it
|
||||
// like "System32\\Drivers\\blah.sys"
|
||||
if (ImagePath && (ImagePath[0] != 0))
|
||||
/* Check whether the driver is already in the list */
|
||||
RtlInitUnicodeString(&DriverNameU, DriverName);
|
||||
AlreadyInserted = CmpIsDriverInList(DriverListHead,
|
||||
&DriverNameU,
|
||||
&DriverNode);
|
||||
if (AlreadyInserted)
|
||||
{
|
||||
// Just copy ImagePath to the corresponding field in the structure
|
||||
PathLength = (USHORT)wcslen(ImagePath) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
|
||||
|
||||
BootDriverEntry->FilePath.Length = 0;
|
||||
BootDriverEntry->FilePath.MaximumLength = PathLength;
|
||||
BootDriverEntry->FilePath.Buffer = FrLdrHeapAlloc(PathLength, TAG_WLDR_NAME);
|
||||
if (!BootDriverEntry->FilePath.Buffer)
|
||||
{
|
||||
FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ImagePath);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME);
|
||||
FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE);
|
||||
return FALSE;
|
||||
}
|
||||
/* If so, we have obtained its node */
|
||||
ASSERT(DriverNode);
|
||||
DriverEntry = &DriverNode->ListEntry;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we have to construct ImagePath ourselves
|
||||
PathLength = (USHORT)wcslen(ServiceName)*sizeof(WCHAR) + sizeof(L"system32\\drivers\\.sys");
|
||||
BootDriverEntry->FilePath.Length = 0;
|
||||
BootDriverEntry->FilePath.MaximumLength = PathLength;
|
||||
BootDriverEntry->FilePath.Buffer = FrLdrHeapAlloc(PathLength, TAG_WLDR_NAME);
|
||||
if (!BootDriverEntry->FilePath.Buffer)
|
||||
{
|
||||
FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE);
|
||||
/* Allocate a driver node and initialize it */
|
||||
DriverNode = CmpAllocate(sizeof(BOOT_DRIVER_NODE), FALSE, TAG_CM);
|
||||
if (!DriverNode)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L"system32\\drivers\\");
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME);
|
||||
FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE);
|
||||
return FALSE;
|
||||
}
|
||||
RtlZeroMemory(DriverNode, sizeof(BOOT_DRIVER_NODE));
|
||||
DriverEntry = &DriverNode->ListEntry;
|
||||
|
||||
Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ServiceName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME);
|
||||
FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE);
|
||||
return FALSE;
|
||||
}
|
||||
/* Driver Name */
|
||||
RtlInitEmptyUnicodeString(&DriverNode->Name,
|
||||
CmpAllocate(DriverNameU.Length, FALSE, TAG_CM),
|
||||
DriverNameU.Length);
|
||||
if (!DriverNode->Name.Buffer)
|
||||
goto Failure;
|
||||
|
||||
Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L".sys");
|
||||
if (!NT_SUCCESS(Status))
|
||||
if (!NT_SUCCESS(RtlAppendUnicodeStringToString(&DriverNode->Name, &DriverNameU)))
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
/* Check whether we have a valid ImagePath. If not, we need
|
||||
* to build it like "System32\\Drivers\\blah.sys" */
|
||||
if (ImagePath && *ImagePath)
|
||||
{
|
||||
/* Just copy ImagePath to the corresponding field in the structure */
|
||||
PathLength = (USHORT)(wcslen(ImagePath)) * sizeof(WCHAR);
|
||||
RtlInitEmptyUnicodeString(&FilePath,
|
||||
CmpAllocate(PathLength, FALSE, TAG_WLDR_NAME),
|
||||
PathLength);
|
||||
if (!FilePath.Buffer)
|
||||
goto Failure;
|
||||
|
||||
if (!NT_SUCCESS(RtlAppendUnicodeToString(&FilePath, ImagePath)))
|
||||
goto Failure;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We have to construct ImagePath ourselves */
|
||||
PathLength = DriverNode->Name.Length + sizeof(L"system32\\drivers\\.sys");
|
||||
RtlInitEmptyUnicodeString(&FilePath,
|
||||
CmpAllocate(PathLength, FALSE, TAG_WLDR_NAME),
|
||||
PathLength);
|
||||
if (!FilePath.Buffer)
|
||||
goto Failure;
|
||||
|
||||
if (!NT_SUCCESS(RtlAppendUnicodeToString(&FilePath, L"system32\\drivers\\")) ||
|
||||
!NT_SUCCESS(RtlAppendUnicodeStringToString(&FilePath, &DriverNode->Name)) ||
|
||||
!NT_SUCCESS(RtlAppendUnicodeToString(&FilePath, L".sys")))
|
||||
{
|
||||
FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME);
|
||||
FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE);
|
||||
return FALSE;
|
||||
goto Failure;
|
||||
}
|
||||
}
|
||||
|
||||
// Add registry path
|
||||
PathLength = (USHORT)(wcslen(RegistryPath) + wcslen(ServiceName))*sizeof(WCHAR) + sizeof(UNICODE_NULL);
|
||||
BootDriverEntry->RegistryPath.Length = 0;
|
||||
BootDriverEntry->RegistryPath.MaximumLength = PathLength;
|
||||
BootDriverEntry->RegistryPath.Buffer = FrLdrHeapAlloc(PathLength, TAG_WLDR_NAME);
|
||||
if (!BootDriverEntry->RegistryPath.Buffer)
|
||||
/* Registry path */
|
||||
RtlInitUnicodeString(&RegistryPath,
|
||||
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
|
||||
PathLength = RegistryPath.Length + DriverNode->Name.Length;
|
||||
RtlInitEmptyUnicodeString(&RegistryString,
|
||||
CmpAllocate(PathLength, FALSE, TAG_WLDR_NAME),
|
||||
PathLength);
|
||||
if (!RegistryString.Buffer)
|
||||
goto Failure;
|
||||
|
||||
if (!NT_SUCCESS(RtlAppendUnicodeStringToString(&RegistryString, &RegistryPath)) ||
|
||||
!NT_SUCCESS(RtlAppendUnicodeStringToString(&RegistryString, &DriverNode->Name)))
|
||||
{
|
||||
FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME);
|
||||
FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE);
|
||||
return FALSE;
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
Status = RtlAppendUnicodeToString(&BootDriverEntry->RegistryPath, RegistryPath);
|
||||
if (!NT_SUCCESS(Status))
|
||||
/* Group */
|
||||
if (GroupName && *GroupName)
|
||||
{
|
||||
FrLdrHeapFree(BootDriverEntry->RegistryPath.Buffer, TAG_WLDR_NAME);
|
||||
FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME);
|
||||
FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE);
|
||||
return FALSE;
|
||||
/*
|
||||
* NOTE: Here we can use our own allocator as we alone maintain the
|
||||
* group string. This is different from the other allocated strings,
|
||||
* where we instead need to use the same (hive) allocator as the
|
||||
* one used by CmpAddDriverToList(), for interoperability purposes.
|
||||
*/
|
||||
RtlCreateUnicodeString(&GroupString, GroupName);
|
||||
if (!GroupString.Buffer)
|
||||
goto Failure;
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlInitEmptyUnicodeString(&GroupString, NULL, 0);
|
||||
}
|
||||
|
||||
Status = RtlAppendUnicodeToString(&BootDriverEntry->RegistryPath, ServiceName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
/* Set or replace the driver node's file path */
|
||||
if (DriverEntry->FilePath.Buffer)
|
||||
{
|
||||
FrLdrHeapFree(BootDriverEntry->RegistryPath.Buffer, TAG_WLDR_NAME);
|
||||
FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME);
|
||||
FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE);
|
||||
return FALSE;
|
||||
CmpFree(DriverEntry->FilePath.Buffer,
|
||||
DriverEntry->FilePath.MaximumLength);
|
||||
}
|
||||
DriverEntry->FilePath = FilePath;
|
||||
FilePath.Buffer = NULL;
|
||||
|
||||
// Insert entry into the list
|
||||
if (!InsertInBootDriverList(BootDriverListHead, BootDriverEntry))
|
||||
/* Set or replace the driver node's registry path */
|
||||
if (DriverEntry->RegistryPath.Buffer)
|
||||
{
|
||||
// It was already there, so delete our entry
|
||||
FrLdrHeapFree(BootDriverEntry->RegistryPath.Buffer, TAG_WLDR_NAME);
|
||||
FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME);
|
||||
FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE);
|
||||
CmpFree(DriverEntry->RegistryPath.Buffer,
|
||||
DriverEntry->RegistryPath.MaximumLength);
|
||||
}
|
||||
DriverEntry->RegistryPath = RegistryString;
|
||||
RegistryString.Buffer = NULL;
|
||||
|
||||
/* Set or replace the driver node's group */
|
||||
if (DriverNode->Group.Buffer)
|
||||
{
|
||||
/*
|
||||
* If the buffer is inside the registry hive's memory, this means that
|
||||
* it has been set by CmpAddDriverToList() to point to some data within
|
||||
* the hive; thus we should not free the buffer but just replace it.
|
||||
* Otherwise, this is a buffer previously allocated by ourselves, that
|
||||
* we can free.
|
||||
*
|
||||
* NOTE: This function does not have an explicit LoaderBlock input
|
||||
* parameter pointer, since it does not need it, except for this
|
||||
* very place. So instead, use the global WinLdrSystemBlock pointer.
|
||||
*/
|
||||
PLOADER_PARAMETER_BLOCK LoaderBlock =
|
||||
(WinLdrSystemBlock ? &WinLdrSystemBlock->LoaderBlock : NULL);
|
||||
|
||||
if (!LoaderBlock || !LoaderBlock->RegistryBase || !LoaderBlock->RegistryLength ||
|
||||
((ULONG_PTR)DriverNode->Group.Buffer <
|
||||
(ULONG_PTR)VaToPa(LoaderBlock->RegistryBase)) ||
|
||||
((ULONG_PTR)DriverNode->Group.Buffer >=
|
||||
(ULONG_PTR)VaToPa(LoaderBlock->RegistryBase) + LoaderBlock->RegistryLength))
|
||||
{
|
||||
RtlFreeUnicodeString(&DriverNode->Group);
|
||||
}
|
||||
}
|
||||
DriverNode->Group = GroupString;
|
||||
GroupString.Buffer = NULL;
|
||||
|
||||
/* ErrorControl and Tag */
|
||||
DriverNode->ErrorControl = ErrorControl;
|
||||
DriverNode->Tag = Tag;
|
||||
|
||||
/* Insert the entry into the list if it does not exist there already */
|
||||
if (!AlreadyInserted)
|
||||
{
|
||||
if (InsertAtHead)
|
||||
InsertHeadList(DriverListHead, &DriverEntry->Link);
|
||||
else
|
||||
InsertTailList(DriverListHead, &DriverEntry->Link);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
Failure:
|
||||
if (GroupString.Buffer)
|
||||
RtlFreeUnicodeString(&GroupString);
|
||||
if (RegistryString.Buffer)
|
||||
CmpFree(RegistryString.Buffer, RegistryString.MaximumLength);
|
||||
if (FilePath.Buffer)
|
||||
CmpFree(FilePath.Buffer, FilePath.MaximumLength);
|
||||
|
||||
/* If it does not exist in the list already, free the allocated
|
||||
* driver node, otherwise keep the original one in place. */
|
||||
if (!AlreadyInserted)
|
||||
{
|
||||
if (DriverEntry->RegistryPath.Buffer)
|
||||
{
|
||||
CmpFree(DriverEntry->RegistryPath.Buffer,
|
||||
DriverEntry->RegistryPath.MaximumLength);
|
||||
}
|
||||
if (DriverEntry->FilePath.Buffer)
|
||||
{
|
||||
CmpFree(DriverEntry->FilePath.Buffer,
|
||||
DriverEntry->FilePath.MaximumLength);
|
||||
}
|
||||
if (DriverNode->Name.Buffer)
|
||||
{
|
||||
CmpFree(DriverNode->Name.Buffer,
|
||||
DriverNode->Name.MaximumLength);
|
||||
}
|
||||
CmpFree(DriverNode, sizeof(BOOT_DRIVER_NODE));
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue