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
);
52 //Print(L"Loading %s...\n", FullHiveName);
53 Status
= ArcOpen(FullHiveName
, OpenReadOnly
, &FileId
);
54 if (Status
!= ESUCCESS
)
56 UiMessageBox("Opening hive file failed!");
60 /* Get the file length */
61 Status
= ArcGetFileInformation(FileId
, &FileInfo
);
62 if (Status
!= ESUCCESS
)
65 UiMessageBox("Hive file has 0 size!");
68 HiveFileSize
= FileInfo
.EndingAddress
.LowPart
;
70 /* Round up the size to page boundary and alloc memory */
71 HiveDataPhysical
= (ULONG_PTR
)MmAllocateMemoryWithType(
72 MM_SIZE_TO_PAGES(HiveFileSize
+ MM_PAGE_SIZE
- 1) << MM_PAGE_SHIFT
,
75 if (HiveDataPhysical
== 0)
78 UiMessageBox("Unable to alloc memory for a hive!");
82 /* Convert address to virtual */
83 HiveDataVirtual
= PaToVa((PVOID
)HiveDataPhysical
);
85 /* Fill LoaderBlock's entries */
86 LoaderBlock
->RegistryLength
= HiveFileSize
;
87 LoaderBlock
->RegistryBase
= HiveDataVirtual
;
89 /* Finally read from file to the memory */
90 Status
= ArcRead(FileId
, (PVOID
)HiveDataPhysical
, HiveFileSize
, &BytesRead
);
91 if (Status
!= ESUCCESS
)
94 UiMessageBox("Unable to read from hive file!");
98 /* Add boot filesystem driver to the list */
99 FsService
= FsGetServiceName(FileId
);
103 TRACE(" Adding filesystem service %S\n", FsService
);
104 Success
= WinLdrAddDriverToList(&LoaderBlock
->BootDriverListHead
,
105 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
109 TRACE(" Failed to add filesystem service\n");
113 TRACE(" No required filesystem service\n");
121 WinLdrInitSystemHive(
122 IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
126 CHAR SearchPath
[1024];
132 strcpy(SearchPath
, SystemRoot
);
133 HiveName
= "SETUPREG.HIV";
137 // There is a simple logic here: try to load usual hive (system), if it
138 // fails, then give system.alt a try, and finally try a system.sav
140 // FIXME: For now we only try system
141 strcpy(SearchPath
, SystemRoot
);
142 strcat(SearchPath
, "system32\\config\\");
146 ERR("WinLdrInitSystemHive: try to load hive %s%s\n", SearchPath
, HiveName
);
147 Success
= WinLdrLoadSystemHive(LoaderBlock
, SearchPath
, HiveName
);
149 /* Fail if failed... */
153 /* Import what was loaded */
154 Success
= RegImportBinaryHive(VaToPa(LoaderBlock
->RegistryBase
), LoaderBlock
->RegistryLength
);
157 UiMessageBox("Importing binary hive failed!");
161 /* Initialize the 'CurrentControlSet' link */
162 if (RegInitCurrentControlSet(FALSE
) != ERROR_SUCCESS
)
164 UiMessageBox("Initializing CurrentControlSet link failed!");
171 BOOLEAN
WinLdrScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
172 IN LPCSTR DirectoryPath
)
174 CHAR SearchPath
[1024];
175 CHAR AnsiName
[256], OemName
[256], LangName
[256];
178 /* Scan registry and prepare boot drivers list */
179 WinLdrScanRegistry(&LoaderBlock
->BootDriverListHead
, DirectoryPath
);
181 /* Get names of NLS files */
182 Success
= WinLdrGetNLSNames(AnsiName
, OemName
, LangName
);
185 UiMessageBox("Getting NLS names from registry failed!");
189 TRACE("NLS data %s %s %s\n", AnsiName
, OemName
, LangName
);
192 strcpy(SearchPath
, DirectoryPath
);
193 strcat(SearchPath
, "system32\\");
194 Success
= WinLdrLoadNLSData(LoaderBlock
, SearchPath
, AnsiName
, OemName
, LangName
);
195 TRACE("NLS data loading %s\n", Success
? "successful" : "failed");
197 /* TODO: Load OEM HAL font */
198 // In HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage,
199 // REG_SZ value "OEMHAL"
205 /* PRIVATE FUNCTIONS ******************************************************/
207 // Queries registry for those three file names
209 WinLdrGetNLSNames(LPSTR AnsiName
,
213 LONG rc
= ERROR_SUCCESS
;
215 WCHAR szIdBuffer
[80];
216 WCHAR NameBuffer
[80];
219 /* open the codepage key */
220 rc
= RegOpenKey(NULL
,
221 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage",
223 if (rc
!= ERROR_SUCCESS
)
225 //strcpy(szErrorOut, "Couldn't open CodePage registry key");
229 /* Get ANSI codepage */
230 BufferSize
= sizeof(szIdBuffer
);
231 rc
= RegQueryValue(hKey
, L
"ACP", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
232 if (rc
!= ERROR_SUCCESS
)
234 //strcpy(szErrorOut, "Couldn't get ACP NLS setting");
238 BufferSize
= sizeof(NameBuffer
);
239 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)NameBuffer
, &BufferSize
);
240 if (rc
!= ERROR_SUCCESS
)
242 //strcpy(szErrorOut, "ACP NLS Setting exists, but isn't readable");
244 wcscpy(NameBuffer
, L
"c_1252.nls"); // HACK: ReactOS bug CORE-6105
246 sprintf(AnsiName
, "%S", NameBuffer
);
248 /* Get OEM codepage */
249 BufferSize
= sizeof(szIdBuffer
);
250 rc
= RegQueryValue(hKey
, L
"OEMCP", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
251 if (rc
!= ERROR_SUCCESS
)
253 //strcpy(szErrorOut, "Couldn't get OEMCP NLS setting");
257 BufferSize
= sizeof(NameBuffer
);
258 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)NameBuffer
, &BufferSize
);
259 if (rc
!= ERROR_SUCCESS
)
261 //strcpy(szErrorOut, "OEMCP NLS setting exists, but isn't readable");
263 wcscpy(NameBuffer
, L
"c_437.nls"); // HACK: ReactOS bug CORE-6105
265 sprintf(OemName
, "%S", NameBuffer
);
267 /* Open the language key */
268 rc
= RegOpenKey(NULL
,
269 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
271 if (rc
!= ERROR_SUCCESS
)
273 //strcpy(szErrorOut, "Couldn't open Language registry key");
277 /* Get the Unicode case table */
278 BufferSize
= sizeof(szIdBuffer
);
279 rc
= RegQueryValue(hKey
, L
"Default", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
280 if (rc
!= ERROR_SUCCESS
)
282 //strcpy(szErrorOut, "Couldn't get Language Default setting");
286 BufferSize
= sizeof(NameBuffer
);
287 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)NameBuffer
, &BufferSize
);
288 if (rc
!= ERROR_SUCCESS
)
290 //strcpy(szErrorOut, "Language Default setting exists, but isn't readable");
293 sprintf(LangName
, "%S", NameBuffer
);
299 WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
300 IN LPCSTR DirectoryPath
,
301 IN LPCSTR AnsiFileName
,
302 IN LPCSTR OemFileName
,
303 IN LPCSTR LanguageFileName
)
308 ULONG LanguageFileId
;
309 ULONG AnsiFileSize
, OemFileSize
, LanguageFileSize
;
311 ULONG_PTR NlsDataBase
;
313 BOOLEAN AnsiEqualsOem
= FALSE
;
314 FILEINFORMATION FileInfo
;
318 /* There may be a case, when OEM and ANSI page coincide */
319 if (!strcmp(AnsiFileName
, OemFileName
))
320 AnsiEqualsOem
= TRUE
;
322 /* Open file with ANSI and store its size */
323 //Print(L"Loading %s...\n", Filename);
324 strcpy(FileName
, DirectoryPath
);
325 strcat(FileName
, AnsiFileName
);
326 Status
= ArcOpen(FileName
, OpenReadOnly
, &AnsiFileId
);
327 if (Status
!= ESUCCESS
)
330 Status
= ArcGetFileInformation(AnsiFileId
, &FileInfo
);
331 if (Status
!= ESUCCESS
)
333 AnsiFileSize
= FileInfo
.EndingAddress
.LowPart
;
334 TRACE("AnsiFileSize: %d\n", AnsiFileSize
);
335 ArcClose(AnsiFileId
);
337 /* Open OEM file and store its length */
344 //Print(L"Loading %s...\n", Filename);
345 strcpy(FileName
, DirectoryPath
);
346 strcat(FileName
, OemFileName
);
347 Status
= ArcOpen(FileName
, OpenReadOnly
, &OemFileId
);
348 if (Status
!= ESUCCESS
)
351 Status
= ArcGetFileInformation(OemFileId
, &FileInfo
);
352 if (Status
!= ESUCCESS
)
354 OemFileSize
= FileInfo
.EndingAddress
.LowPart
;
357 TRACE("OemFileSize: %d\n", OemFileSize
);
359 /* And finally open the language codepage file and store its length */
360 //Print(L"Loading %s...\n", Filename);
361 strcpy(FileName
, DirectoryPath
);
362 strcat(FileName
, LanguageFileName
);
363 Status
= ArcOpen(FileName
, OpenReadOnly
, &LanguageFileId
);
364 if (Status
!= ESUCCESS
)
367 Status
= ArcGetFileInformation(LanguageFileId
, &FileInfo
);
368 if (Status
!= ESUCCESS
)
370 LanguageFileSize
= FileInfo
.EndingAddress
.LowPart
;
371 ArcClose(LanguageFileId
);
372 TRACE("LanguageFileSize: %d\n", LanguageFileSize
);
374 /* Sum up all three length, having in mind that every one of them
375 must start at a page boundary => thus round up each file to a page */
376 TotalSize
= MM_SIZE_TO_PAGES(AnsiFileSize
) +
377 MM_SIZE_TO_PAGES(OemFileSize
) +
378 MM_SIZE_TO_PAGES(LanguageFileSize
);
380 /* Store it for later marking the pages as NlsData type */
381 TotalNLSSize
= TotalSize
;
383 NlsDataBase
= (ULONG_PTR
)MmAllocateMemoryWithType(TotalSize
*MM_PAGE_SIZE
, LoaderNlsData
);
385 if (NlsDataBase
== 0)
388 NlsVirtual
= PaToVa((PVOID
)NlsDataBase
);
389 LoaderBlock
->NlsData
->AnsiCodePageData
= NlsVirtual
;
390 LoaderBlock
->NlsData
->OemCodePageData
= (PVOID
)((PUCHAR
)NlsVirtual
+
391 (MM_SIZE_TO_PAGES(AnsiFileSize
) << MM_PAGE_SHIFT
));
392 LoaderBlock
->NlsData
->UnicodeCodePageData
= (PVOID
)((PUCHAR
)NlsVirtual
+
393 (MM_SIZE_TO_PAGES(AnsiFileSize
) << MM_PAGE_SHIFT
) +
394 (MM_SIZE_TO_PAGES(OemFileSize
) << MM_PAGE_SHIFT
));
396 /* Ansi and OEM data are the same - just set pointers to the same area */
398 LoaderBlock
->NlsData
->OemCodePageData
= LoaderBlock
->NlsData
->AnsiCodePageData
;
401 /* Now actually read the data into memory, starting with Ansi file */
402 strcpy(FileName
, DirectoryPath
);
403 strcat(FileName
, AnsiFileName
);
404 Status
= ArcOpen(FileName
, OpenReadOnly
, &AnsiFileId
);
405 if (Status
!= ESUCCESS
)
408 Status
= ArcRead(AnsiFileId
, VaToPa(LoaderBlock
->NlsData
->AnsiCodePageData
), AnsiFileSize
, &BytesRead
);
409 if (Status
!= ESUCCESS
)
412 ArcClose(AnsiFileId
);
414 /* OEM now, if it doesn't equal Ansi of course */
417 strcpy(FileName
, DirectoryPath
);
418 strcat(FileName
, OemFileName
);
419 Status
= ArcOpen(FileName
, OpenReadOnly
, &OemFileId
);
420 if (Status
!= ESUCCESS
)
423 Status
= ArcRead(OemFileId
, VaToPa(LoaderBlock
->NlsData
->OemCodePageData
), OemFileSize
, &BytesRead
);
424 if (Status
!= ESUCCESS
)
430 /* finally the language file */
431 strcpy(FileName
, DirectoryPath
);
432 strcat(FileName
, LanguageFileName
);
433 Status
= ArcOpen(FileName
, OpenReadOnly
, &LanguageFileId
);
434 if (Status
!= ESUCCESS
)
437 Status
= ArcRead(LanguageFileId
, VaToPa(LoaderBlock
->NlsData
->UnicodeCodePageData
), LanguageFileSize
, &BytesRead
);
438 if (Status
!= ESUCCESS
)
441 ArcClose(LanguageFileId
);
444 // THIS IS HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK
445 // Should go to WinLdrLoadOemHalFont(), when it will be implemented
447 LoaderBlock
->OemFontFile
= VaToPa(LoaderBlock
->NlsData
->UnicodeCodePageData
);
449 /* Convert NlsTables address to VA */
450 LoaderBlock
->NlsData
= PaToVa(LoaderBlock
->NlsData
);
455 UiMessageBox("Error reading NLS file %s", FileName
);
460 WinLdrScanRegistry(IN OUT PLIST_ENTRY BootDriverListHead
,
461 IN LPCSTR DirectoryPath
)
464 HKEY hGroupKey
, hOrderKey
, hServiceKey
, hDriverKey
;
465 LPWSTR GroupNameBuffer
;
466 WCHAR ServiceName
[256];
467 ULONG OrderList
[128];
477 WCHAR DriverGroup
[256];
478 ULONG DriverGroupSize
;
481 WCHAR TempImagePath
[256];
485 /* get 'service group order' key */
486 rc
= RegOpenKey(NULL
,
487 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder",
489 if (rc
!= ERROR_SUCCESS
) {
491 TRACE_CH(REACTOS
, "Failed to open the 'ServiceGroupOrder' key (rc %d)\n", (int)rc
);
495 /* get 'group order list' key */
496 rc
= RegOpenKey(NULL
,
497 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\GroupOrderList",
499 if (rc
!= ERROR_SUCCESS
) {
501 TRACE_CH(REACTOS
, "Failed to open the 'GroupOrderList' key (rc %d)\n", (int)rc
);
505 /* enumerate drivers */
506 rc
= RegOpenKey(NULL
,
507 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services",
509 if (rc
!= ERROR_SUCCESS
) {
511 TRACE_CH(REACTOS
, "Failed to open the 'Services' key (rc %d)\n", (int)rc
);
515 /* Get the Name Group */
517 GroupNameBuffer
= FrLdrHeapAlloc(BufferSize
, TAG_WLDR_NAME
);
518 rc
= RegQueryValue(hGroupKey
, L
"List", NULL
, (PUCHAR
)GroupNameBuffer
, &BufferSize
);
519 TRACE_CH(REACTOS
, "RegQueryValue(): rc %d\n", (int)rc
);
520 if (rc
!= ERROR_SUCCESS
)
522 TRACE_CH(REACTOS
, "BufferSize: %d \n", (int)BufferSize
);
523 TRACE_CH(REACTOS
, "GroupNameBuffer: '%S' \n", GroupNameBuffer
);
525 /* Loop through each group */
526 GroupName
= GroupNameBuffer
;
529 TRACE("Driver group: '%S'\n", GroupName
);
531 /* Query the Order */
532 BufferSize
= sizeof(OrderList
);
533 rc
= RegQueryValue(hOrderKey
, GroupName
, NULL
, (PUCHAR
)OrderList
, &BufferSize
);
534 if (rc
!= ERROR_SUCCESS
) OrderList
[0] = 0;
536 /* enumerate all drivers */
537 for (TagIndex
= 1; TagIndex
<= OrderList
[0]; TagIndex
++)
543 /* Get the Driver's Name */
544 ValueSize
= sizeof(ServiceName
);
545 rc
= RegEnumKey(hServiceKey
, Index
, ServiceName
, &ValueSize
, &hDriverKey
);
546 TRACE("RegEnumKey(): rc %d\n", (int)rc
);
548 /* Make sure it's valid, and check if we're done */
549 if (rc
== ERROR_NO_MORE_ITEMS
)
551 if (rc
!= ERROR_SUCCESS
)
553 FrLdrHeapFree(GroupNameBuffer
, TAG_WLDR_NAME
);
556 //TRACE_CH(REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName);
558 /* Read the Start Value */
559 ValueSize
= sizeof(ULONG
);
560 rc
= RegQueryValue(hDriverKey
, L
"Start", &ValueType
, (PUCHAR
)&StartValue
, &ValueSize
);
561 if (rc
!= ERROR_SUCCESS
) StartValue
= (ULONG
)-1;
562 //TRACE_CH(REACTOS, " Start: %x \n", (int)StartValue);
565 ValueSize
= sizeof(ULONG
);
566 rc
= RegQueryValue(hDriverKey
, L
"Tag", &ValueType
, (PUCHAR
)&TagValue
, &ValueSize
);
567 if (rc
!= ERROR_SUCCESS
) TagValue
= (ULONG
)-1;
568 //TRACE_CH(REACTOS, " Tag: %x \n", (int)TagValue);
570 /* Read the driver's group */
571 DriverGroupSize
= sizeof(DriverGroup
);
572 rc
= RegQueryValue(hDriverKey
, L
"Group", NULL
, (PUCHAR
)DriverGroup
, &DriverGroupSize
);
573 //TRACE_CH(REACTOS, " Group: '%S' \n", DriverGroup);
575 /* Make sure it should be started */
576 if ((StartValue
== 0) &&
577 (TagValue
== OrderList
[TagIndex
]) &&
578 (_wcsicmp(DriverGroup
, GroupName
) == 0))
580 /* Get the Driver's Location */
581 ValueSize
= sizeof(TempImagePath
);
582 rc
= RegQueryValue(hDriverKey
, L
"ImagePath", NULL
, (PUCHAR
)TempImagePath
, &ValueSize
);
584 /* Write the whole path if it succeeded, else prepare to fail */
585 if (rc
!= ERROR_SUCCESS
)
587 TRACE_CH(REACTOS
, "ImagePath: not found\n");
588 TempImagePath
[0] = 0;
589 sprintf(ImagePath
, "%s\\system32\\drivers\\%S.sys", DirectoryPath
, ServiceName
);
591 else if (TempImagePath
[0] != L
'\\')
593 sprintf(ImagePath
, "%s%S", DirectoryPath
, TempImagePath
);
597 sprintf(ImagePath
, "%S", TempImagePath
);
598 TRACE_CH(REACTOS
, "ImagePath: '%s'\n", ImagePath
);
601 TRACE("Adding boot driver: '%s'\n", ImagePath
);
603 Success
= WinLdrAddDriverToList(BootDriverListHead
,
604 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
608 ERR("Failed to add boot driver\n");
612 //TRACE(" Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current Tag %d, current group '%S')\n",
613 // ServiceName, StartValue, TagValue, DriverGroup, OrderList[TagIndex], GroupName);
623 /* Get the Driver's Name */
624 ValueSize
= sizeof(ServiceName
);
625 rc
= RegEnumKey(hServiceKey
, Index
, ServiceName
, &ValueSize
, &hDriverKey
);
627 //TRACE_CH(REACTOS, "RegEnumKey(): rc %d\n", (int)rc);
628 if (rc
== ERROR_NO_MORE_ITEMS
)
630 if (rc
!= ERROR_SUCCESS
)
632 FrLdrHeapFree(GroupNameBuffer
, TAG_WLDR_NAME
);
635 TRACE("Service %d: '%S'\n", (int)Index
, ServiceName
);
637 /* Read the Start Value */
638 ValueSize
= sizeof(ULONG
);
639 rc
= RegQueryValue(hDriverKey
, L
"Start", &ValueType
, (PUCHAR
)&StartValue
, &ValueSize
);
640 if (rc
!= ERROR_SUCCESS
) StartValue
= (ULONG
)-1;
641 //TRACE_CH(REACTOS, " Start: %x \n", (int)StartValue);
644 ValueSize
= sizeof(ULONG
);
645 rc
= RegQueryValue(hDriverKey
, L
"Tag", &ValueType
, (PUCHAR
)&TagValue
, &ValueSize
);
646 if (rc
!= ERROR_SUCCESS
) TagValue
= (ULONG
)-1;
647 //TRACE_CH(REACTOS, " Tag: %x \n", (int)TagValue);
649 /* Read the driver's group */
650 DriverGroupSize
= sizeof(DriverGroup
);
651 rc
= RegQueryValue(hDriverKey
, L
"Group", NULL
, (PUCHAR
)DriverGroup
, &DriverGroupSize
);
652 //TRACE_CH(REACTOS, " Group: '%S' \n", DriverGroup);
654 for (TagIndex
= 1; TagIndex
<= OrderList
[0]; TagIndex
++)
656 if (TagValue
== OrderList
[TagIndex
]) break;
659 if ((StartValue
== 0) &&
660 (TagIndex
> OrderList
[0]) &&
661 (_wcsicmp(DriverGroup
, GroupName
) == 0))
663 ValueSize
= sizeof(TempImagePath
);
664 rc
= RegQueryValue(hDriverKey
, L
"ImagePath", NULL
, (PUCHAR
)TempImagePath
, &ValueSize
);
665 if (rc
!= ERROR_SUCCESS
)
667 TRACE_CH(REACTOS
, "ImagePath: not found\n");
668 TempImagePath
[0] = 0;
669 sprintf(ImagePath
, "%ssystem32\\drivers\\%S.sys", DirectoryPath
, ServiceName
);
671 else if (TempImagePath
[0] != L
'\\')
673 sprintf(ImagePath
, "%s%S", DirectoryPath
, TempImagePath
);
677 sprintf(ImagePath
, "%S", TempImagePath
);
678 TRACE_CH(REACTOS
, "ImagePath: '%s'\n", ImagePath
);
680 TRACE(" Adding boot driver: '%s'\n", ImagePath
);
682 Success
= WinLdrAddDriverToList(BootDriverListHead
,
683 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
687 ERR(" Failed to add boot driver\n");
691 //TRACE(" Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current group '%S')\n",
692 // ServiceName, StartValue, TagValue, DriverGroup, GroupName);
698 /* Move to the next group name */
699 GroupName
= GroupName
+ wcslen(GroupName
) + 1;
702 /* Free allocated memory */
703 FrLdrHeapFree(GroupNameBuffer
, TAG_WLDR_NAME
);
708 InsertInBootDriverList(
709 PLIST_ENTRY BootDriverListHead
,
710 PBOOT_DRIVER_LIST_ENTRY BootDriverEntry
)
712 PBOOT_DRIVER_LIST_ENTRY DriverEntry
;
713 PLIST_ENTRY ListEntry
;
715 ASSERT(BootDriverEntry
->FilePath
.Buffer
!= NULL
);
716 ASSERT(BootDriverEntry
->RegistryPath
.Buffer
!= NULL
);
718 for (ListEntry
= BootDriverListHead
->Flink
;
719 ListEntry
!= BootDriverListHead
;
720 ListEntry
= ListEntry
->Flink
)
722 DriverEntry
= CONTAINING_RECORD(ListEntry
,
723 BOOT_DRIVER_LIST_ENTRY
,
725 if ((DriverEntry
->FilePath
.Buffer
!= NULL
) &&
726 RtlEqualUnicodeString(&BootDriverEntry
->FilePath
,
727 &DriverEntry
->FilePath
,
733 if ((DriverEntry
->RegistryPath
.Buffer
!= NULL
) &&
734 RtlEqualUnicodeString(&BootDriverEntry
->RegistryPath
,
735 &DriverEntry
->RegistryPath
,
742 InsertTailList(BootDriverListHead
, &BootDriverEntry
->Link
);
747 WinLdrAddDriverToList(LIST_ENTRY
*BootDriverListHead
,
752 PBOOT_DRIVER_LIST_ENTRY BootDriverEntry
;
756 BootDriverEntry
= FrLdrHeapAlloc(sizeof(BOOT_DRIVER_LIST_ENTRY
), TAG_WLDR_BDE
);
758 if (!BootDriverEntry
)
761 // DTE will be filled during actual load of the driver
762 BootDriverEntry
->LdrEntry
= NULL
;
764 // Check - if we have a valid ImagePath, if not - we need to build it
765 // like "System32\\Drivers\\blah.sys"
766 if (ImagePath
&& (ImagePath
[0] != 0))
768 // Just copy ImagePath to the corresponding field in the structure
769 PathLength
= (USHORT
)wcslen(ImagePath
) * sizeof(WCHAR
) + sizeof(UNICODE_NULL
);
771 BootDriverEntry
->FilePath
.Length
= 0;
772 BootDriverEntry
->FilePath
.MaximumLength
= PathLength
;
773 BootDriverEntry
->FilePath
.Buffer
= FrLdrHeapAlloc(PathLength
, TAG_WLDR_NAME
);
775 if (!BootDriverEntry
->FilePath
.Buffer
)
777 FrLdrHeapFree(BootDriverEntry
, TAG_WLDR_BDE
);
781 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->FilePath
, ImagePath
);
782 if (!NT_SUCCESS(Status
))
784 FrLdrHeapFree(BootDriverEntry
->FilePath
.Buffer
, TAG_WLDR_NAME
);
785 FrLdrHeapFree(BootDriverEntry
, TAG_WLDR_BDE
);
791 // we have to construct ImagePath ourselves
792 PathLength
= (USHORT
)wcslen(ServiceName
)*sizeof(WCHAR
) + sizeof(L
"system32\\drivers\\.sys");
793 BootDriverEntry
->FilePath
.Length
= 0;
794 BootDriverEntry
->FilePath
.MaximumLength
= PathLength
;
795 BootDriverEntry
->FilePath
.Buffer
= FrLdrHeapAlloc(PathLength
, TAG_WLDR_NAME
);
797 if (!BootDriverEntry
->FilePath
.Buffer
)
799 FrLdrHeapFree(BootDriverEntry
, TAG_WLDR_NAME
);
803 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->FilePath
, L
"system32\\drivers\\");
804 if (!NT_SUCCESS(Status
))
806 FrLdrHeapFree(BootDriverEntry
->FilePath
.Buffer
, TAG_WLDR_NAME
);
807 FrLdrHeapFree(BootDriverEntry
, TAG_WLDR_NAME
);
811 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->FilePath
, ServiceName
);
812 if (!NT_SUCCESS(Status
))
814 FrLdrHeapFree(BootDriverEntry
->FilePath
.Buffer
, TAG_WLDR_NAME
);
815 FrLdrHeapFree(BootDriverEntry
, TAG_WLDR_NAME
);
819 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->FilePath
, L
".sys");
820 if (!NT_SUCCESS(Status
))
822 FrLdrHeapFree(BootDriverEntry
->FilePath
.Buffer
, TAG_WLDR_NAME
);
823 FrLdrHeapFree(BootDriverEntry
, TAG_WLDR_NAME
);
829 PathLength
= (USHORT
)(wcslen(RegistryPath
) + wcslen(ServiceName
))*sizeof(WCHAR
) + sizeof(UNICODE_NULL
);
830 BootDriverEntry
->RegistryPath
.Length
= 0;
831 BootDriverEntry
->RegistryPath
.MaximumLength
= PathLength
;
832 BootDriverEntry
->RegistryPath
.Buffer
= FrLdrHeapAlloc(PathLength
, TAG_WLDR_NAME
);
833 if (!BootDriverEntry
->RegistryPath
.Buffer
)
836 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->RegistryPath
, RegistryPath
);
837 if (!NT_SUCCESS(Status
))
840 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->RegistryPath
, ServiceName
);
841 if (!NT_SUCCESS(Status
))
844 // Insert entry into the list
845 if (!InsertInBootDriverList(BootDriverListHead
, BootDriverEntry
))
847 // It was already there, so delete our entry
848 if (BootDriverEntry
->FilePath
.Buffer
) FrLdrHeapFree(BootDriverEntry
->FilePath
.Buffer
, TAG_WLDR_NAME
);
849 if (BootDriverEntry
->RegistryPath
.Buffer
) FrLdrHeapFree(BootDriverEntry
->RegistryPath
.Buffer
, TAG_WLDR_NAME
);
850 FrLdrHeapFree(BootDriverEntry
, TAG_WLDR_BDE
);