2 * PROJECT: EFI Windows Loader
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: boot/freeldr/freeldr/windows/wlregistry.c
5 * PURPOSE: Registry support functions
6 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
9 /* INCLUDES ***************************************************************/
16 DBG_DEFAULT_CHANNEL(WINDOWS
);
18 // The only global var here, used to mark mem pages as NLS in WinLdrSetupMemoryLayout()
19 ULONG TotalNLSSize
= 0;
22 WinLdrGetNLSNames(LPSTR AnsiName
,
27 WinLdrScanRegistry(IN OUT PLIST_ENTRY BootDriverListHead
,
28 IN LPCSTR DirectoryPath
);
31 /* FUNCTIONS **************************************************************/
35 IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
36 IN PCSTR DirectoryPath
,
40 CHAR FullHiveName
[MAX_PATH
];
42 FILEINFORMATION FileInfo
;
44 ULONG_PTR HiveDataPhysical
;
45 PVOID HiveDataVirtual
;
49 /* Concatenate path and filename to get the full name */
50 strcpy(FullHiveName
, DirectoryPath
);
51 strcat(FullHiveName
, HiveName
);
53 Status
= ArcOpen(FullHiveName
, OpenReadOnly
, &FileId
);
54 if (Status
!= ESUCCESS
)
56 WARN("Error while opening '%s', Status: %u\n", FullHiveName
, Status
);
57 UiMessageBox("Opening hive file failed!");
61 /* Get the file length */
62 Status
= ArcGetFileInformation(FileId
, &FileInfo
);
63 if (Status
!= ESUCCESS
)
66 UiMessageBox("Hive file has 0 size!");
69 HiveFileSize
= FileInfo
.EndingAddress
.LowPart
;
71 /* Round up the size to page boundary and alloc memory */
72 HiveDataPhysical
= (ULONG_PTR
)MmAllocateMemoryWithType(
73 MM_SIZE_TO_PAGES(HiveFileSize
+ MM_PAGE_SIZE
- 1) << MM_PAGE_SHIFT
,
76 if (HiveDataPhysical
== 0)
79 UiMessageBox("Unable to alloc memory for a hive!");
83 /* Convert address to virtual */
84 HiveDataVirtual
= PaToVa((PVOID
)HiveDataPhysical
);
86 /* Fill LoaderBlock's entries */
87 LoaderBlock
->RegistryLength
= HiveFileSize
;
88 LoaderBlock
->RegistryBase
= HiveDataVirtual
;
90 /* Finally read from file to the memory */
91 Status
= ArcRead(FileId
, (PVOID
)HiveDataPhysical
, HiveFileSize
, &BytesRead
);
92 if (Status
!= ESUCCESS
)
95 WARN("Error while reading '%s', Status: %u\n", FullHiveName
, Status
);
96 UiMessageBox("Unable to read from hive file!");
100 /* Add boot filesystem driver to the list */
101 FsService
= FsGetServiceName(FileId
);
105 TRACE(" Adding filesystem service %S\n", FsService
);
106 Success
= WinLdrAddDriverToList(&LoaderBlock
->BootDriverListHead
,
107 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
111 TRACE(" Failed to add filesystem service\n");
115 TRACE(" No required filesystem service\n");
123 WinLdrInitSystemHive(
124 IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
128 CHAR SearchPath
[1024];
134 strcpy(SearchPath
, SystemRoot
);
135 HiveName
= "SETUPREG.HIV";
139 // There is a simple logic here: try to load usual hive (system), if it
140 // fails, then give system.alt a try, and finally try a system.sav
142 // FIXME: For now we only try system
143 strcpy(SearchPath
, SystemRoot
);
144 strcat(SearchPath
, "system32\\config\\");
148 TRACE("WinLdrInitSystemHive: loading hive %s%s\n", SearchPath
, HiveName
);
149 Success
= WinLdrLoadSystemHive(LoaderBlock
, SearchPath
, HiveName
);
151 /* Fail if failed... */
155 /* Import what was loaded */
156 Success
= RegImportBinaryHive(VaToPa(LoaderBlock
->RegistryBase
), LoaderBlock
->RegistryLength
);
159 UiMessageBox("Importing binary hive failed!");
163 /* Initialize the 'CurrentControlSet' link */
164 if (RegInitCurrentControlSet(FALSE
) != ERROR_SUCCESS
)
166 UiMessageBox("Initializing CurrentControlSet link failed!");
173 BOOLEAN
WinLdrScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
174 IN LPCSTR DirectoryPath
)
176 CHAR SearchPath
[1024];
177 CHAR AnsiName
[256], OemName
[256], LangName
[256];
180 /* Scan registry and prepare boot drivers list */
181 WinLdrScanRegistry(&LoaderBlock
->BootDriverListHead
, DirectoryPath
);
183 /* Get names of NLS files */
184 Success
= WinLdrGetNLSNames(AnsiName
, OemName
, LangName
);
187 UiMessageBox("Getting NLS names from registry failed!");
191 TRACE("NLS data %s %s %s\n", AnsiName
, OemName
, LangName
);
194 strcpy(SearchPath
, DirectoryPath
);
195 strcat(SearchPath
, "system32\\");
196 Success
= WinLdrLoadNLSData(LoaderBlock
, SearchPath
, AnsiName
, OemName
, LangName
);
197 TRACE("NLS data loading %s\n", Success
? "successful" : "failed");
199 /* TODO: Load OEM HAL font */
200 // In HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage,
201 // REG_SZ value "OEMHAL"
207 /* PRIVATE FUNCTIONS ******************************************************/
209 // Queries registry for those three file names
211 WinLdrGetNLSNames(LPSTR AnsiName
,
215 LONG rc
= ERROR_SUCCESS
;
217 WCHAR szIdBuffer
[80];
218 WCHAR NameBuffer
[80];
221 /* open the codepage key */
222 rc
= RegOpenKey(NULL
,
223 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage",
225 if (rc
!= ERROR_SUCCESS
)
227 //strcpy(szErrorOut, "Couldn't open CodePage registry key");
231 /* Get ANSI codepage */
232 BufferSize
= sizeof(szIdBuffer
);
233 rc
= RegQueryValue(hKey
, L
"ACP", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
234 if (rc
!= ERROR_SUCCESS
)
236 //strcpy(szErrorOut, "Couldn't get ACP NLS setting");
240 BufferSize
= sizeof(NameBuffer
);
241 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)NameBuffer
, &BufferSize
);
242 if (rc
!= ERROR_SUCCESS
)
244 //strcpy(szErrorOut, "ACP NLS Setting exists, but isn't readable");
246 wcscpy(NameBuffer
, L
"c_1252.nls"); // HACK: ReactOS bug CORE-6105
248 sprintf(AnsiName
, "%S", NameBuffer
);
250 /* Get OEM codepage */
251 BufferSize
= sizeof(szIdBuffer
);
252 rc
= RegQueryValue(hKey
, L
"OEMCP", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
253 if (rc
!= ERROR_SUCCESS
)
255 //strcpy(szErrorOut, "Couldn't get OEMCP NLS setting");
259 BufferSize
= sizeof(NameBuffer
);
260 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)NameBuffer
, &BufferSize
);
261 if (rc
!= ERROR_SUCCESS
)
263 //strcpy(szErrorOut, "OEMCP NLS setting exists, but isn't readable");
265 wcscpy(NameBuffer
, L
"c_437.nls"); // HACK: ReactOS bug CORE-6105
267 sprintf(OemName
, "%S", NameBuffer
);
269 /* Open the language key */
270 rc
= RegOpenKey(NULL
,
271 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
273 if (rc
!= ERROR_SUCCESS
)
275 //strcpy(szErrorOut, "Couldn't open Language registry key");
279 /* Get the Unicode case table */
280 BufferSize
= sizeof(szIdBuffer
);
281 rc
= RegQueryValue(hKey
, L
"Default", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
282 if (rc
!= ERROR_SUCCESS
)
284 //strcpy(szErrorOut, "Couldn't get Language Default setting");
288 BufferSize
= sizeof(NameBuffer
);
289 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)NameBuffer
, &BufferSize
);
290 if (rc
!= ERROR_SUCCESS
)
292 //strcpy(szErrorOut, "Language Default setting exists, but isn't readable");
295 sprintf(LangName
, "%S", NameBuffer
);
301 WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
302 IN LPCSTR DirectoryPath
,
303 IN LPCSTR AnsiFileName
,
304 IN LPCSTR OemFileName
,
305 IN LPCSTR LanguageFileName
)
310 ULONG LanguageFileId
;
311 ULONG AnsiFileSize
, OemFileSize
, LanguageFileSize
;
313 ULONG_PTR NlsDataBase
;
315 BOOLEAN AnsiEqualsOem
= FALSE
;
316 FILEINFORMATION FileInfo
;
320 /* There may be a case, when OEM and ANSI page coincide */
321 if (!strcmp(AnsiFileName
, OemFileName
))
322 AnsiEqualsOem
= TRUE
;
324 /* Open file with ANSI and store its size */
325 strcpy(FileName
, DirectoryPath
);
326 strcat(FileName
, AnsiFileName
);
327 Status
= ArcOpen(FileName
, OpenReadOnly
, &AnsiFileId
);
328 if (Status
!= ESUCCESS
)
330 WARN("Error while opening '%s', Status: %u\n", FileName
, Status
);
334 Status
= ArcGetFileInformation(AnsiFileId
, &FileInfo
);
335 if (Status
!= ESUCCESS
)
337 AnsiFileSize
= FileInfo
.EndingAddress
.LowPart
;
338 TRACE("AnsiFileSize: %d\n", AnsiFileSize
);
339 ArcClose(AnsiFileId
);
341 /* Open OEM file and store its length */
348 //Print(L"Loading %s...\n", Filename);
349 strcpy(FileName
, DirectoryPath
);
350 strcat(FileName
, OemFileName
);
351 Status
= ArcOpen(FileName
, OpenReadOnly
, &OemFileId
);
352 if (Status
!= ESUCCESS
)
354 WARN("Error while opening '%s', Status: %u\n", FileName
, Status
);
358 Status
= ArcGetFileInformation(OemFileId
, &FileInfo
);
359 if (Status
!= ESUCCESS
)
361 OemFileSize
= FileInfo
.EndingAddress
.LowPart
;
364 TRACE("OemFileSize: %d\n", OemFileSize
);
366 /* And finally open the language codepage file and store its length */
367 //Print(L"Loading %s...\n", Filename);
368 strcpy(FileName
, DirectoryPath
);
369 strcat(FileName
, LanguageFileName
);
370 Status
= ArcOpen(FileName
, OpenReadOnly
, &LanguageFileId
);
371 if (Status
!= ESUCCESS
)
373 WARN("Error while opening '%s', Status: %u\n", FileName
, Status
);
377 Status
= ArcGetFileInformation(LanguageFileId
, &FileInfo
);
378 if (Status
!= ESUCCESS
)
380 LanguageFileSize
= FileInfo
.EndingAddress
.LowPart
;
381 ArcClose(LanguageFileId
);
382 TRACE("LanguageFileSize: %d\n", LanguageFileSize
);
384 /* Sum up all three length, having in mind that every one of them
385 must start at a page boundary => thus round up each file to a page */
386 TotalSize
= MM_SIZE_TO_PAGES(AnsiFileSize
) +
387 MM_SIZE_TO_PAGES(OemFileSize
) +
388 MM_SIZE_TO_PAGES(LanguageFileSize
);
390 /* Store it for later marking the pages as NlsData type */
391 TotalNLSSize
= TotalSize
;
393 NlsDataBase
= (ULONG_PTR
)MmAllocateMemoryWithType(TotalSize
*MM_PAGE_SIZE
, LoaderNlsData
);
395 if (NlsDataBase
== 0)
398 NlsVirtual
= PaToVa((PVOID
)NlsDataBase
);
399 LoaderBlock
->NlsData
->AnsiCodePageData
= NlsVirtual
;
400 LoaderBlock
->NlsData
->OemCodePageData
= (PVOID
)((PUCHAR
)NlsVirtual
+
401 (MM_SIZE_TO_PAGES(AnsiFileSize
) << MM_PAGE_SHIFT
));
402 LoaderBlock
->NlsData
->UnicodeCodePageData
= (PVOID
)((PUCHAR
)NlsVirtual
+
403 (MM_SIZE_TO_PAGES(AnsiFileSize
) << MM_PAGE_SHIFT
) +
404 (MM_SIZE_TO_PAGES(OemFileSize
) << MM_PAGE_SHIFT
));
406 /* Ansi and OEM data are the same - just set pointers to the same area */
408 LoaderBlock
->NlsData
->OemCodePageData
= LoaderBlock
->NlsData
->AnsiCodePageData
;
411 /* Now actually read the data into memory, starting with Ansi file */
412 strcpy(FileName
, DirectoryPath
);
413 strcat(FileName
, AnsiFileName
);
414 Status
= ArcOpen(FileName
, OpenReadOnly
, &AnsiFileId
);
415 if (Status
!= ESUCCESS
)
417 WARN("Error while opening '%s', Status: %u\n", FileName
, Status
);
421 Status
= ArcRead(AnsiFileId
, VaToPa(LoaderBlock
->NlsData
->AnsiCodePageData
), AnsiFileSize
, &BytesRead
);
422 if (Status
!= ESUCCESS
)
424 WARN("Error while reading '%s', Status: %u\n", FileName
, Status
);
428 ArcClose(AnsiFileId
);
430 /* OEM now, if it doesn't equal Ansi of course */
433 strcpy(FileName
, DirectoryPath
);
434 strcat(FileName
, OemFileName
);
435 Status
= ArcOpen(FileName
, OpenReadOnly
, &OemFileId
);
436 if (Status
!= ESUCCESS
)
438 WARN("Error while opening '%s', Status: %u\n", FileName
, Status
);
442 Status
= ArcRead(OemFileId
, VaToPa(LoaderBlock
->NlsData
->OemCodePageData
), OemFileSize
, &BytesRead
);
443 if (Status
!= ESUCCESS
)
445 WARN("Error while reading '%s', Status: %u\n", FileName
, Status
);
452 /* finally the language file */
453 strcpy(FileName
, DirectoryPath
);
454 strcat(FileName
, LanguageFileName
);
455 Status
= ArcOpen(FileName
, OpenReadOnly
, &LanguageFileId
);
456 if (Status
!= ESUCCESS
)
458 WARN("Error while opening '%s', Status: %u\n", FileName
, Status
);
462 Status
= ArcRead(LanguageFileId
, VaToPa(LoaderBlock
->NlsData
->UnicodeCodePageData
), LanguageFileSize
, &BytesRead
);
463 if (Status
!= ESUCCESS
)
465 WARN("Error while reading '%s', Status: %u\n", FileName
, Status
);
469 ArcClose(LanguageFileId
);
472 // THIS IS HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK
473 // Should go to WinLdrLoadOemHalFont(), when it will be implemented
475 LoaderBlock
->OemFontFile
= VaToPa(LoaderBlock
->NlsData
->UnicodeCodePageData
);
477 /* Convert NlsTables address to VA */
478 LoaderBlock
->NlsData
= PaToVa(LoaderBlock
->NlsData
);
483 UiMessageBox("Error reading NLS file %s", FileName
);
488 WinLdrScanRegistry(IN OUT PLIST_ENTRY BootDriverListHead
,
489 IN LPCSTR DirectoryPath
)
492 HKEY hGroupKey
, hOrderKey
, hServiceKey
, hDriverKey
;
493 LPWSTR GroupNameBuffer
;
494 WCHAR ServiceName
[256];
495 ULONG OrderList
[128];
505 WCHAR DriverGroup
[256];
506 ULONG DriverGroupSize
;
509 WCHAR TempImagePath
[256];
513 /* get 'service group order' key */
514 rc
= RegOpenKey(NULL
,
515 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder",
517 if (rc
!= ERROR_SUCCESS
) {
519 TRACE_CH(REACTOS
, "Failed to open the 'ServiceGroupOrder' key (rc %d)\n", (int)rc
);
523 /* get 'group order list' key */
524 rc
= RegOpenKey(NULL
,
525 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\GroupOrderList",
527 if (rc
!= ERROR_SUCCESS
) {
529 TRACE_CH(REACTOS
, "Failed to open the 'GroupOrderList' key (rc %d)\n", (int)rc
);
533 /* enumerate drivers */
534 rc
= RegOpenKey(NULL
,
535 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services",
537 if (rc
!= ERROR_SUCCESS
) {
539 TRACE_CH(REACTOS
, "Failed to open the 'Services' key (rc %d)\n", (int)rc
);
543 /* Get the Name Group */
545 GroupNameBuffer
= FrLdrHeapAlloc(BufferSize
, TAG_WLDR_NAME
);
546 rc
= RegQueryValue(hGroupKey
, L
"List", NULL
, (PUCHAR
)GroupNameBuffer
, &BufferSize
);
547 TRACE_CH(REACTOS
, "RegQueryValue(): rc %d\n", (int)rc
);
548 if (rc
!= ERROR_SUCCESS
)
550 TRACE_CH(REACTOS
, "BufferSize: %d \n", (int)BufferSize
);
551 TRACE_CH(REACTOS
, "GroupNameBuffer: '%S' \n", GroupNameBuffer
);
553 /* Loop through each group */
554 GroupName
= GroupNameBuffer
;
557 TRACE("Driver group: '%S'\n", GroupName
);
559 /* Query the Order */
560 BufferSize
= sizeof(OrderList
);
561 rc
= RegQueryValue(hOrderKey
, GroupName
, NULL
, (PUCHAR
)OrderList
, &BufferSize
);
562 if (rc
!= ERROR_SUCCESS
) OrderList
[0] = 0;
564 /* enumerate all drivers */
565 for (TagIndex
= 1; TagIndex
<= OrderList
[0]; TagIndex
++)
571 /* Get the Driver's Name */
572 ValueSize
= sizeof(ServiceName
);
573 rc
= RegEnumKey(hServiceKey
, Index
, ServiceName
, &ValueSize
, &hDriverKey
);
574 TRACE("RegEnumKey(): rc %d\n", (int)rc
);
576 /* Make sure it's valid, and check if we're done */
577 if (rc
== ERROR_NO_MORE_ITEMS
)
579 if (rc
!= ERROR_SUCCESS
)
581 FrLdrHeapFree(GroupNameBuffer
, TAG_WLDR_NAME
);
584 //TRACE_CH(REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName);
586 /* Read the Start Value */
587 ValueSize
= sizeof(ULONG
);
588 rc
= RegQueryValue(hDriverKey
, L
"Start", &ValueType
, (PUCHAR
)&StartValue
, &ValueSize
);
589 if (rc
!= ERROR_SUCCESS
) StartValue
= (ULONG
)-1;
590 //TRACE_CH(REACTOS, " Start: %x \n", (int)StartValue);
593 ValueSize
= sizeof(ULONG
);
594 rc
= RegQueryValue(hDriverKey
, L
"Tag", &ValueType
, (PUCHAR
)&TagValue
, &ValueSize
);
595 if (rc
!= ERROR_SUCCESS
) TagValue
= (ULONG
)-1;
596 //TRACE_CH(REACTOS, " Tag: %x \n", (int)TagValue);
598 /* Read the driver's group */
599 DriverGroupSize
= sizeof(DriverGroup
);
600 rc
= RegQueryValue(hDriverKey
, L
"Group", NULL
, (PUCHAR
)DriverGroup
, &DriverGroupSize
);
601 //TRACE_CH(REACTOS, " Group: '%S' \n", DriverGroup);
603 /* Make sure it should be started */
604 if ((StartValue
== 0) &&
605 (TagValue
== OrderList
[TagIndex
]) &&
606 (_wcsicmp(DriverGroup
, GroupName
) == 0))
608 /* Get the Driver's Location */
609 ValueSize
= sizeof(TempImagePath
);
610 rc
= RegQueryValue(hDriverKey
, L
"ImagePath", NULL
, (PUCHAR
)TempImagePath
, &ValueSize
);
612 /* Write the whole path if it succeeded, else prepare to fail */
613 if (rc
!= ERROR_SUCCESS
)
615 TRACE_CH(REACTOS
, "ImagePath: not found\n");
616 TempImagePath
[0] = 0;
617 RtlStringCbPrintfA(ImagePath
, sizeof(ImagePath
), "%s\\system32\\drivers\\%S.sys", DirectoryPath
, ServiceName
);
619 else if (TempImagePath
[0] != L
'\\')
621 RtlStringCbPrintfA(ImagePath
, sizeof(ImagePath
), "%s%S", DirectoryPath
, TempImagePath
);
625 RtlStringCbPrintfA(ImagePath
, sizeof(ImagePath
), "%S", TempImagePath
);
626 TRACE_CH(REACTOS
, "ImagePath: '%s'\n", ImagePath
);
629 TRACE("Adding boot driver: '%s'\n", ImagePath
);
631 Success
= WinLdrAddDriverToList(BootDriverListHead
,
632 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
636 ERR("Failed to add boot driver\n");
640 //TRACE(" Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current Tag %d, current group '%S')\n",
641 // ServiceName, StartValue, TagValue, DriverGroup, OrderList[TagIndex], GroupName);
651 /* Get the Driver's Name */
652 ValueSize
= sizeof(ServiceName
);
653 rc
= RegEnumKey(hServiceKey
, Index
, ServiceName
, &ValueSize
, &hDriverKey
);
655 //TRACE_CH(REACTOS, "RegEnumKey(): rc %d\n", (int)rc);
656 if (rc
== ERROR_NO_MORE_ITEMS
)
658 if (rc
!= ERROR_SUCCESS
)
660 FrLdrHeapFree(GroupNameBuffer
, TAG_WLDR_NAME
);
663 TRACE("Service %d: '%S'\n", (int)Index
, ServiceName
);
665 /* Read the Start Value */
666 ValueSize
= sizeof(ULONG
);
667 rc
= RegQueryValue(hDriverKey
, L
"Start", &ValueType
, (PUCHAR
)&StartValue
, &ValueSize
);
668 if (rc
!= ERROR_SUCCESS
) StartValue
= (ULONG
)-1;
669 //TRACE_CH(REACTOS, " Start: %x \n", (int)StartValue);
672 ValueSize
= sizeof(ULONG
);
673 rc
= RegQueryValue(hDriverKey
, L
"Tag", &ValueType
, (PUCHAR
)&TagValue
, &ValueSize
);
674 if (rc
!= ERROR_SUCCESS
) TagValue
= (ULONG
)-1;
675 //TRACE_CH(REACTOS, " Tag: %x \n", (int)TagValue);
677 /* Read the driver's group */
678 DriverGroupSize
= sizeof(DriverGroup
);
679 rc
= RegQueryValue(hDriverKey
, L
"Group", NULL
, (PUCHAR
)DriverGroup
, &DriverGroupSize
);
680 //TRACE_CH(REACTOS, " Group: '%S' \n", DriverGroup);
682 for (TagIndex
= 1; TagIndex
<= OrderList
[0]; TagIndex
++)
684 if (TagValue
== OrderList
[TagIndex
]) break;
687 if ((StartValue
== 0) &&
688 (TagIndex
> OrderList
[0]) &&
689 (_wcsicmp(DriverGroup
, GroupName
) == 0))
691 ValueSize
= sizeof(TempImagePath
);
692 rc
= RegQueryValue(hDriverKey
, L
"ImagePath", NULL
, (PUCHAR
)TempImagePath
, &ValueSize
);
693 if (rc
!= ERROR_SUCCESS
)
695 TRACE_CH(REACTOS
, "ImagePath: not found\n");
696 TempImagePath
[0] = 0;
697 RtlStringCbPrintfA(ImagePath
, sizeof(ImagePath
), "%ssystem32\\drivers\\%S.sys", DirectoryPath
, ServiceName
);
699 else if (TempImagePath
[0] != L
'\\')
701 RtlStringCbPrintfA(ImagePath
, sizeof(ImagePath
), "%s%S", DirectoryPath
, TempImagePath
);
705 RtlStringCbPrintfA(ImagePath
, sizeof(ImagePath
), "%S", TempImagePath
);
706 TRACE_CH(REACTOS
, "ImagePath: '%s'\n", ImagePath
);
708 TRACE(" Adding boot driver: '%s'\n", ImagePath
);
710 Success
= WinLdrAddDriverToList(BootDriverListHead
,
711 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
715 ERR(" Failed to add boot driver\n");
719 //TRACE(" Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current group '%S')\n",
720 // ServiceName, StartValue, TagValue, DriverGroup, GroupName);
726 /* Move to the next group name */
727 GroupName
= GroupName
+ wcslen(GroupName
) + 1;
730 /* Free allocated memory */
731 FrLdrHeapFree(GroupNameBuffer
, TAG_WLDR_NAME
);
736 InsertInBootDriverList(
737 PLIST_ENTRY BootDriverListHead
,
738 PBOOT_DRIVER_LIST_ENTRY BootDriverEntry
)
740 PBOOT_DRIVER_LIST_ENTRY DriverEntry
;
741 PLIST_ENTRY ListEntry
;
743 ASSERT(BootDriverEntry
->FilePath
.Buffer
!= NULL
);
744 ASSERT(BootDriverEntry
->RegistryPath
.Buffer
!= NULL
);
746 for (ListEntry
= BootDriverListHead
->Flink
;
747 ListEntry
!= BootDriverListHead
;
748 ListEntry
= ListEntry
->Flink
)
750 DriverEntry
= CONTAINING_RECORD(ListEntry
,
751 BOOT_DRIVER_LIST_ENTRY
,
753 if ((DriverEntry
->FilePath
.Buffer
!= NULL
) &&
754 RtlEqualUnicodeString(&BootDriverEntry
->FilePath
,
755 &DriverEntry
->FilePath
,
761 if ((DriverEntry
->RegistryPath
.Buffer
!= NULL
) &&
762 RtlEqualUnicodeString(&BootDriverEntry
->RegistryPath
,
763 &DriverEntry
->RegistryPath
,
770 InsertTailList(BootDriverListHead
, &BootDriverEntry
->Link
);
775 WinLdrAddDriverToList(LIST_ENTRY
*BootDriverListHead
,
780 PBOOT_DRIVER_LIST_ENTRY BootDriverEntry
;
784 BootDriverEntry
= FrLdrHeapAlloc(sizeof(BOOT_DRIVER_LIST_ENTRY
), TAG_WLDR_BDE
);
786 if (!BootDriverEntry
)
789 // DTE will be filled during actual load of the driver
790 BootDriverEntry
->LdrEntry
= NULL
;
792 // Check - if we have a valid ImagePath, if not - we need to build it
793 // like "System32\\Drivers\\blah.sys"
794 if (ImagePath
&& (ImagePath
[0] != 0))
796 // Just copy ImagePath to the corresponding field in the structure
797 PathLength
= (USHORT
)wcslen(ImagePath
) * sizeof(WCHAR
) + sizeof(UNICODE_NULL
);
799 BootDriverEntry
->FilePath
.Length
= 0;
800 BootDriverEntry
->FilePath
.MaximumLength
= PathLength
;
801 BootDriverEntry
->FilePath
.Buffer
= FrLdrHeapAlloc(PathLength
, TAG_WLDR_NAME
);
803 if (!BootDriverEntry
->FilePath
.Buffer
)
805 FrLdrHeapFree(BootDriverEntry
, TAG_WLDR_BDE
);
809 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->FilePath
, ImagePath
);
810 if (!NT_SUCCESS(Status
))
812 FrLdrHeapFree(BootDriverEntry
->FilePath
.Buffer
, TAG_WLDR_NAME
);
813 FrLdrHeapFree(BootDriverEntry
, TAG_WLDR_BDE
);
819 // we have to construct ImagePath ourselves
820 PathLength
= (USHORT
)wcslen(ServiceName
)*sizeof(WCHAR
) + sizeof(L
"system32\\drivers\\.sys");
821 BootDriverEntry
->FilePath
.Length
= 0;
822 BootDriverEntry
->FilePath
.MaximumLength
= PathLength
;
823 BootDriverEntry
->FilePath
.Buffer
= FrLdrHeapAlloc(PathLength
, TAG_WLDR_NAME
);
825 if (!BootDriverEntry
->FilePath
.Buffer
)
827 FrLdrHeapFree(BootDriverEntry
, TAG_WLDR_NAME
);
831 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->FilePath
, L
"system32\\drivers\\");
832 if (!NT_SUCCESS(Status
))
834 FrLdrHeapFree(BootDriverEntry
->FilePath
.Buffer
, TAG_WLDR_NAME
);
835 FrLdrHeapFree(BootDriverEntry
, TAG_WLDR_NAME
);
839 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->FilePath
, ServiceName
);
840 if (!NT_SUCCESS(Status
))
842 FrLdrHeapFree(BootDriverEntry
->FilePath
.Buffer
, TAG_WLDR_NAME
);
843 FrLdrHeapFree(BootDriverEntry
, TAG_WLDR_NAME
);
847 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->FilePath
, L
".sys");
848 if (!NT_SUCCESS(Status
))
850 FrLdrHeapFree(BootDriverEntry
->FilePath
.Buffer
, TAG_WLDR_NAME
);
851 FrLdrHeapFree(BootDriverEntry
, TAG_WLDR_NAME
);
857 PathLength
= (USHORT
)(wcslen(RegistryPath
) + wcslen(ServiceName
))*sizeof(WCHAR
) + sizeof(UNICODE_NULL
);
858 BootDriverEntry
->RegistryPath
.Length
= 0;
859 BootDriverEntry
->RegistryPath
.MaximumLength
= PathLength
;
860 BootDriverEntry
->RegistryPath
.Buffer
= FrLdrHeapAlloc(PathLength
, TAG_WLDR_NAME
);
861 if (!BootDriverEntry
->RegistryPath
.Buffer
)
864 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->RegistryPath
, RegistryPath
);
865 if (!NT_SUCCESS(Status
))
868 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->RegistryPath
, ServiceName
);
869 if (!NT_SUCCESS(Status
))
872 // Insert entry into the list
873 if (!InsertInBootDriverList(BootDriverListHead
, BootDriverEntry
))
875 // It was already there, so delete our entry
876 if (BootDriverEntry
->FilePath
.Buffer
) FrLdrHeapFree(BootDriverEntry
->FilePath
.Buffer
, TAG_WLDR_NAME
);
877 if (BootDriverEntry
->RegistryPath
.Buffer
) FrLdrHeapFree(BootDriverEntry
->RegistryPath
.Buffer
, TAG_WLDR_NAME
);
878 FrLdrHeapFree(BootDriverEntry
, TAG_WLDR_BDE
);