2 * PROJECT: EFI Windows Loader
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: freeldr/winldr/wlregistry.c
5 * PURPOSE: Registry support functions
6 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
9 /* INCLUDES ***************************************************************/
21 // The only global var here, used to mark mem pages as NLS in WinLdrTurnOnPaging()
22 ULONG TotalNLSSize
= 0;
24 BOOLEAN
WinLdrGetNLSNames(LPSTR AnsiName
,
29 WinLdrScanRegistry(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
30 IN LPCSTR DirectoryPath
);
33 WinLdrAddDriverToList(LIST_ENTRY
*BootDriverListHead
,
39 WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
40 IN LPCSTR DirectoryPath
,
41 IN LPCSTR AnsiFileName
,
42 IN LPCSTR OemFileName
,
43 IN LPCSTR LanguageFileName
);
46 /* FUNCTIONS **************************************************************/
49 WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
50 IN LPCSTR DirectoryPath
,
54 CHAR FullHiveName
[256];
57 ULONG_PTR HiveDataPhysical
;
58 PVOID HiveDataVirtual
;
60 /* Concatenate path and filename to get the full name */
61 strcpy(FullHiveName
, DirectoryPath
);
62 strcat(FullHiveName
, HiveName
);
63 //Print(L"Loading %s...\n", FullHiveName);
64 FileHandle
= FsOpenFile(FullHiveName
);
66 if (FileHandle
== NULL
)
68 UiMessageBox("Opening hive file failed!");
72 /* Get the file length */
73 HiveFileSize
= FsGetFileSize(FileHandle
);
75 if (HiveFileSize
== 0)
77 FsCloseFile(FileHandle
);
78 UiMessageBox("Hive file has 0 size!");
82 /* Round up the size to page boundary and alloc memory */
83 HiveDataPhysical
= (ULONG_PTR
)MmAllocateMemory(
84 MM_SIZE_TO_PAGES(HiveFileSize
+ MM_PAGE_SIZE
- 1) << MM_PAGE_SHIFT
);
86 if (HiveDataPhysical
== 0)
88 FsCloseFile(FileHandle
);
89 UiMessageBox("Unable to alloc memory for a hive!");
93 /* Convert address to virtual */
95 HiveDataVirtual
= (PVOID
)(KSEG0_BASE
| HiveDataPhysical
);
97 HiveDataVirtual
= (PVOID
)HiveDataPhysical
;
100 /* Fill LoaderBlock's entries */
101 LoaderBlock
->RegistryLength
= HiveFileSize
;
102 LoaderBlock
->RegistryBase
= HiveDataVirtual
;
104 /* Finally read from file to the memory */
105 Status
= FsReadFile(FileHandle
, HiveFileSize
, NULL
, (PVOID
)HiveDataPhysical
);
106 FsCloseFile(FileHandle
);
109 UiMessageBox("Unable to read from hive file!");
117 /* PRIVATE FUNCTIONS ******************************************************/
119 // Queries registry for those three file names
120 BOOLEAN
WinLdrGetNLSNames(LPSTR AnsiName
,
124 LONG rc
= ERROR_SUCCESS
;
126 WCHAR szIdBuffer
[80];
127 WCHAR NameBuffer
[80];
130 /* open the codepage key */
131 rc
= RegOpenKey(NULL
,
132 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage",
134 if (rc
!= ERROR_SUCCESS
)
136 //strcpy(szErrorOut, "Couldn't open CodePage registry key");
140 /* get ANSI codepage */
141 BufferSize
= sizeof(szIdBuffer
);
142 rc
= RegQueryValue(hKey
, L
"ACP", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
143 if (rc
!= ERROR_SUCCESS
)
145 //strcpy(szErrorOut, "Couldn't get ACP NLS setting");
149 BufferSize
= sizeof(NameBuffer
);
150 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)NameBuffer
, &BufferSize
);
151 if (rc
!= ERROR_SUCCESS
)
153 //strcpy(szErrorOut, "ACP NLS Setting exists, but isn't readable");
156 sprintf(AnsiName
, "%S", NameBuffer
);
158 /* get OEM codepage */
159 BufferSize
= sizeof(szIdBuffer
);
160 rc
= RegQueryValue(hKey
, L
"OEMCP", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
161 if (rc
!= ERROR_SUCCESS
)
163 //strcpy(szErrorOut, "Couldn't get OEMCP NLS setting");
167 BufferSize
= sizeof(NameBuffer
);
168 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)NameBuffer
, &BufferSize
);
169 if (rc
!= ERROR_SUCCESS
)
171 //strcpy(szErrorOut, "OEMCP NLS setting exists, but isn't readable");
174 sprintf(OemName
, "%S", NameBuffer
);
176 /* open the language key */
177 rc
= RegOpenKey(NULL
,
178 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
180 if (rc
!= ERROR_SUCCESS
)
182 //strcpy(szErrorOut, "Couldn't open Language registry key");
186 /* get the Unicode case table */
187 BufferSize
= sizeof(szIdBuffer
);
188 rc
= RegQueryValue(hKey
, L
"Default", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
189 if (rc
!= ERROR_SUCCESS
)
191 //strcpy(szErrorOut, "Couldn't get Language Default setting");
195 BufferSize
= sizeof(NameBuffer
);
196 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)NameBuffer
, &BufferSize
);
197 if (rc
!= ERROR_SUCCESS
)
199 //strcpy(szErrorOut, "Language Default setting exists, but isn't readable");
202 sprintf(LangName
, "%S", NameBuffer
);
207 BOOLEAN
WinLdrLoadAndScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
208 IN LPCSTR DirectoryPath
)
210 CHAR SearchPath
[1024];
211 CHAR AnsiName
[256], OemName
[256], LangName
[256];
214 // There is a simple logic here: try to load usual hive (system), if it
215 // fails, then give system.alt a try, and finally try a system.sav
217 // FIXME: For now we only try system
218 strcpy(SearchPath
, DirectoryPath
);
219 strcat(SearchPath
, "SYSTEM32\\CONFIG\\");
220 Status
= WinLdrLoadSystemHive(LoaderBlock
, SearchPath
, "SYSTEM");
226 // Initialize in-memory registry
227 RegInitializeRegistry();
229 // Import what was loaded
230 Status
= RegImportBinaryHive((PCHAR
)VaToPa(LoaderBlock
->RegistryBase
), LoaderBlock
->RegistryLength
);
233 UiMessageBox("Importing binary hive failed!");
237 // Initialize the 'CurrentControlSet' link
238 if (RegInitCurrentControlSet(FALSE
) != ERROR_SUCCESS
)
240 UiMessageBox("Initializing CurrentControlSet link failed!");
244 Status
= WinLdrGetNLSNames(AnsiName
, OemName
, LangName
);
247 UiMessageBox("Getting NLS names from registry failed!");
251 DbgPrint((DPRINT_WINDOWS
, "NLS data %s %s %s\n", AnsiName
, OemName
, LangName
));
253 /* Load NLS data, should be moved to WinLdrLoadAndScanSystemHive() */
254 strcpy(SearchPath
, DirectoryPath
);
255 strcat(SearchPath
, "SYSTEM32\\");
256 Status
= WinLdrLoadNLSData(LoaderBlock
, SearchPath
, AnsiName
, OemName
, LangName
);
257 DbgPrint((DPRINT_WINDOWS
, "NLS data loaded with status %d\n", Status
));
263 /* PRIVATE FUNCTIONS ******************************************************/
266 WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
267 IN LPCSTR DirectoryPath
,
268 IN LPCSTR AnsiFileName
,
269 IN LPCSTR OemFileName
,
270 IN LPCSTR LanguageFileName
)
273 PFILE AnsiFileHandle
;
275 PFILE LanguageFileHandle
;
276 ULONG AnsiFileSize
, OemFileSize
, LanguageFileSize
;
278 ULONG_PTR NlsDataBase
;
280 BOOLEAN Status
, AnsiEqualsOem
= FALSE
;
282 /* There may be a case, when OEM and ANSI page coincide */
283 if (!strcmp(AnsiFileName
, OemFileName
))
284 AnsiEqualsOem
= TRUE
;
286 /* Open file with ANSI and store its size */
287 //Print(L"Loading %s...\n", Filename);
288 strcpy(FileName
, DirectoryPath
);
289 strcat(FileName
, AnsiFileName
);
290 AnsiFileHandle
= FsOpenFile(FileName
);
292 if (AnsiFileHandle
== NULL
)
295 AnsiFileSize
= FsGetFileSize(AnsiFileHandle
);
296 DbgPrint((DPRINT_WINDOWS
, "AnsiFileSize: %d\n", AnsiFileSize
));
297 FsCloseFile(AnsiFileHandle
);
299 /* Open OEM file and store its length */
306 //Print(L"Loading %s...\n", Filename);
307 strcpy(FileName
, DirectoryPath
);
308 strcat(FileName
, OemFileName
);
309 OemFileHandle
= FsOpenFile(FileName
);
311 if (OemFileHandle
== NULL
)
314 OemFileSize
= FsGetFileSize(OemFileHandle
);
315 FsCloseFile(OemFileHandle
);
317 DbgPrint((DPRINT_WINDOWS
, "OemFileSize: %d\n", OemFileSize
));
319 /* And finally open the language codepage file and store its length */
320 //Print(L"Loading %s...\n", Filename);
321 strcpy(FileName
, DirectoryPath
);
322 strcat(FileName
, LanguageFileName
);
323 LanguageFileHandle
= FsOpenFile(FileName
);
325 if (LanguageFileHandle
== NULL
)
328 LanguageFileSize
= FsGetFileSize(LanguageFileHandle
);
329 FsCloseFile(LanguageFileHandle
);
330 DbgPrint((DPRINT_WINDOWS
, "LanguageFileSize: %d\n", LanguageFileSize
));
332 /* Sum up all three length, having in mind that every one of them
333 must start at a page boundary => thus round up each file to a page */
334 TotalSize
= MM_SIZE_TO_PAGES(AnsiFileSize
) +
335 MM_SIZE_TO_PAGES(OemFileSize
) +
336 MM_SIZE_TO_PAGES(LanguageFileSize
);
338 /* Store it for later marking the pages as NlsData type */
339 TotalNLSSize
= TotalSize
;
341 NlsDataBase
= (ULONG_PTR
)MmAllocateMemory(TotalSize
*MM_PAGE_SIZE
);
343 if (NlsDataBase
== 0)
347 NlsVirtual
= (PVOID
)(KSEG0_BASE
| NlsDataBase
);
348 #elif defined(_M_PPC)
349 NlsVirtual
= (PVOID
)NlsDataBase
;
351 LoaderBlock
->NlsData
->AnsiCodePageData
= NlsVirtual
;
352 LoaderBlock
->NlsData
->OemCodePageData
= (PVOID
)((PUCHAR
)NlsVirtual
+
353 (MM_SIZE_TO_PAGES(AnsiFileSize
) << MM_PAGE_SHIFT
));
354 LoaderBlock
->NlsData
->UnicodeCodePageData
= (PVOID
)((PUCHAR
)NlsVirtual
+
355 (MM_SIZE_TO_PAGES(AnsiFileSize
) << MM_PAGE_SHIFT
) +
356 (MM_SIZE_TO_PAGES(OemFileSize
) << MM_PAGE_SHIFT
));
358 /* Ansi and OEM data are the same - just set pointers to the same area */
360 LoaderBlock
->NlsData
->OemCodePageData
= LoaderBlock
->NlsData
->AnsiCodePageData
;
363 /* Now actually read the data into memory, starting with Ansi file */
364 strcpy(FileName
, DirectoryPath
);
365 strcat(FileName
, AnsiFileName
);
366 AnsiFileHandle
= FsOpenFile(FileName
);
368 if (AnsiFileHandle
== NULL
)
371 Status
= FsReadFile(AnsiFileHandle
, AnsiFileSize
, NULL
, VaToPa(LoaderBlock
->NlsData
->AnsiCodePageData
));
376 FsCloseFile(AnsiFileHandle
);
378 /* OEM now, if it doesn't equal Ansi of course */
381 strcpy(FileName
, DirectoryPath
);
382 strcat(FileName
, OemFileName
);
383 OemFileHandle
= FsOpenFile(FileName
);
385 if (OemFileHandle
== NULL
)
388 Status
= FsReadFile(OemFileHandle
, OemFileSize
, NULL
, VaToPa(LoaderBlock
->NlsData
->OemCodePageData
));
393 FsCloseFile(AnsiFileHandle
);
396 /* finally the language file */
397 strcpy(FileName
, DirectoryPath
);
398 strcat(FileName
, LanguageFileName
);
399 LanguageFileHandle
= FsOpenFile(FileName
);
401 if (LanguageFileHandle
== NULL
)
404 Status
= FsReadFile(LanguageFileHandle
, LanguageFileSize
, NULL
, VaToPa(LoaderBlock
->NlsData
->UnicodeCodePageData
));
409 FsCloseFile(LanguageFileHandle
);
412 // THIS IS HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK
413 // Should go to WinLdrLoadOemHalFont(), when it will be implemented
415 LoaderBlock
->OemFontFile
= VaToPa(LoaderBlock
->NlsData
->UnicodeCodePageData
);
417 /* Convert NlsTables address to VA */
418 LoaderBlock
->NlsData
= PaToVa(LoaderBlock
->NlsData
);
423 //UiMessageBox("Error reading NLS file %s\n", Filename);
424 UiMessageBox("Error reading NLS file!");
429 WinLdrScanRegistry(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
430 IN LPCSTR DirectoryPath
)
433 FRLDRHKEY hGroupKey
, hOrderKey
, hServiceKey
, hDriverKey
;
434 WCHAR GroupNameBuffer
[512];
435 WCHAR ServiceName
[256];
436 ULONG OrderList
[128];
446 WCHAR DriverGroup
[256];
447 ULONG DriverGroupSize
;
450 WCHAR TempImagePath
[256];
454 /* get 'service group order' key */
455 rc
= RegOpenKey(NULL
,
456 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder",
458 if (rc
!= ERROR_SUCCESS
) {
460 DbgPrint((DPRINT_REACTOS
, "Failed to open the 'ServiceGroupOrder' key (rc %d)\n", (int)rc
));
464 /* get 'group order list' key */
465 rc
= RegOpenKey(NULL
,
466 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\GroupOrderList",
468 if (rc
!= ERROR_SUCCESS
) {
470 DbgPrint((DPRINT_REACTOS
, "Failed to open the 'GroupOrderList' key (rc %d)\n", (int)rc
));
474 /* enumerate drivers */
475 rc
= RegOpenKey(NULL
,
476 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services",
478 if (rc
!= ERROR_SUCCESS
) {
480 DbgPrint((DPRINT_REACTOS
, "Failed to open the 'Services' key (rc %d)\n", (int)rc
));
484 /* Get the Name Group */
485 BufferSize
= sizeof(GroupNameBuffer
);
486 rc
= RegQueryValue(hGroupKey
, L
"List", NULL
, (PUCHAR
)GroupNameBuffer
, &BufferSize
);
487 DbgPrint((DPRINT_REACTOS
, "RegQueryValue(): rc %d\n", (int)rc
));
488 if (rc
!= ERROR_SUCCESS
)
490 DbgPrint((DPRINT_REACTOS
, "BufferSize: %d \n", (int)BufferSize
));
491 DbgPrint((DPRINT_REACTOS
, "GroupNameBuffer: '%S' \n", GroupNameBuffer
));
493 /* Loop through each group */
494 GroupName
= GroupNameBuffer
;
497 DbgPrint((DPRINT_WINDOWS
, "Driver group: '%S'\n", GroupName
));
499 /* Query the Order */
500 BufferSize
= sizeof(OrderList
);
501 rc
= RegQueryValue(hOrderKey
, GroupName
, NULL
, (PUCHAR
)OrderList
, &BufferSize
);
502 if (rc
!= ERROR_SUCCESS
) OrderList
[0] = 0;
504 /* enumerate all drivers */
505 for (TagIndex
= 1; TagIndex
<= OrderList
[0]; TagIndex
++)
511 /* Get the Driver's Name */
512 ValueSize
= sizeof(ServiceName
);
513 rc
= RegEnumKey(hServiceKey
, Index
, ServiceName
, &ValueSize
);
514 //DbgPrint((DPRINT_REACTOS, "RegEnumKey(): rc %d\n", (int)rc));
516 /* Makre sure it's valid, and check if we're done */
517 if (rc
== ERROR_NO_MORE_ITEMS
)
519 if (rc
!= ERROR_SUCCESS
)
521 //DbgPrint((DPRINT_REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName));
523 /* open driver Key */
524 rc
= RegOpenKey(hServiceKey
, ServiceName
, &hDriverKey
);
525 if (rc
== ERROR_SUCCESS
)
527 /* Read the Start Value */
528 ValueSize
= sizeof(ULONG
);
529 rc
= RegQueryValue(hDriverKey
, L
"Start", &ValueType
, (PUCHAR
)&StartValue
, &ValueSize
);
530 if (rc
!= ERROR_SUCCESS
) StartValue
= (ULONG
)-1;
531 //DbgPrint((DPRINT_REACTOS, " Start: %x \n", (int)StartValue));
534 ValueSize
= sizeof(ULONG
);
535 rc
= RegQueryValue(hDriverKey
, L
"Tag", &ValueType
, (PUCHAR
)&TagValue
, &ValueSize
);
536 if (rc
!= ERROR_SUCCESS
) TagValue
= (ULONG
)-1;
537 //DbgPrint((DPRINT_REACTOS, " Tag: %x \n", (int)TagValue));
539 /* Read the driver's group */
540 DriverGroupSize
= sizeof(DriverGroup
);
541 rc
= RegQueryValue(hDriverKey
, L
"Group", NULL
, (PUCHAR
)DriverGroup
, &DriverGroupSize
);
542 //DbgPrint((DPRINT_REACTOS, " Group: '%S' \n", DriverGroup));
544 /* Make sure it should be started */
545 if ((StartValue
== 0) &&
546 (TagValue
== OrderList
[TagIndex
]) &&
547 (_wcsicmp(DriverGroup
, GroupName
) == 0)) {
549 /* Get the Driver's Location */
550 ValueSize
= sizeof(TempImagePath
);
551 rc
= RegQueryValue(hDriverKey
, L
"ImagePath", NULL
, (PUCHAR
)TempImagePath
, &ValueSize
);
553 /* Write the whole path if it suceeded, else prepare to fail */
554 if (rc
!= ERROR_SUCCESS
) {
555 DbgPrint((DPRINT_REACTOS
, " ImagePath: not found\n"));
556 TempImagePath
[0] = 0;
557 sprintf(ImagePath
, "%s\\system32\\drivers\\%S.sys", DirectoryPath
, ServiceName
);
558 } else if (TempImagePath
[0] != L
'\\') {
559 sprintf(ImagePath
, "%s%S", DirectoryPath
, TempImagePath
);
561 sprintf(ImagePath
, "%S", TempImagePath
);
562 DbgPrint((DPRINT_REACTOS
, " ImagePath: '%s'\n", ImagePath
));
565 DbgPrint((DPRINT_WINDOWS
, " Adding boot driver: '%s'\n", ImagePath
));
567 Status
= WinLdrAddDriverToList(&LoaderBlock
->BootDriverListHead
,
568 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
573 DbgPrint((DPRINT_WINDOWS
, " Failed to add boot driver\n"));
576 //DbgPrint((DPRINT_REACTOS, " Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current Tag %d, current group '%S')\n",
577 // ServiceName, StartValue, TagValue, DriverGroup, OrderList[TagIndex], GroupName));
588 /* Get the Driver's Name */
589 ValueSize
= sizeof(ServiceName
);
590 rc
= RegEnumKey(hServiceKey
, Index
, ServiceName
, &ValueSize
);
592 //DbgPrint((DPRINT_REACTOS, "RegEnumKey(): rc %d\n", (int)rc));
593 if (rc
== ERROR_NO_MORE_ITEMS
)
595 if (rc
!= ERROR_SUCCESS
)
597 //DbgPrint((DPRINT_REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName));
599 /* open driver Key */
600 rc
= RegOpenKey(hServiceKey
, ServiceName
, &hDriverKey
);
601 if (rc
== ERROR_SUCCESS
)
603 /* Read the Start Value */
604 ValueSize
= sizeof(ULONG
);
605 rc
= RegQueryValue(hDriverKey
, L
"Start", &ValueType
, (PUCHAR
)&StartValue
, &ValueSize
);
606 if (rc
!= ERROR_SUCCESS
) StartValue
= (ULONG
)-1;
607 //DbgPrint((DPRINT_REACTOS, " Start: %x \n", (int)StartValue));
610 ValueSize
= sizeof(ULONG
);
611 rc
= RegQueryValue(hDriverKey
, L
"Tag", &ValueType
, (PUCHAR
)&TagValue
, &ValueSize
);
612 if (rc
!= ERROR_SUCCESS
) TagValue
= (ULONG
)-1;
613 //DbgPrint((DPRINT_REACTOS, " Tag: %x \n", (int)TagValue));
615 /* Read the driver's group */
616 DriverGroupSize
= sizeof(DriverGroup
);
617 rc
= RegQueryValue(hDriverKey
, L
"Group", NULL
, (PUCHAR
)DriverGroup
, &DriverGroupSize
);
618 //DbgPrint((DPRINT_REACTOS, " Group: '%S' \n", DriverGroup));
620 for (TagIndex
= 1; TagIndex
<= OrderList
[0]; TagIndex
++) {
621 if (TagValue
== OrderList
[TagIndex
]) break;
624 if ((StartValue
== 0) &&
625 (TagIndex
> OrderList
[0]) &&
626 (_wcsicmp(DriverGroup
, GroupName
) == 0)) {
628 ValueSize
= sizeof(TempImagePath
);
629 rc
= RegQueryValue(hDriverKey
, L
"ImagePath", NULL
, (PUCHAR
)TempImagePath
, &ValueSize
);
630 if (rc
!= ERROR_SUCCESS
) {
631 DbgPrint((DPRINT_REACTOS
, " ImagePath: not found\n"));
632 TempImagePath
[0] = 0;
633 sprintf(ImagePath
, "%ssystem32\\drivers\\%S.sys", DirectoryPath
, ServiceName
);
634 } else if (TempImagePath
[0] != L
'\\') {
635 sprintf(ImagePath
, "%s%S", DirectoryPath
, TempImagePath
);
637 sprintf(ImagePath
, "%S", TempImagePath
);
638 DbgPrint((DPRINT_REACTOS
, " ImagePath: '%s'\n", ImagePath
));
640 DbgPrint((DPRINT_WINDOWS
, " Adding boot driver: '%s'\n", ImagePath
));
642 Status
= WinLdrAddDriverToList(&LoaderBlock
->BootDriverListHead
,
643 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
648 DbgPrint((DPRINT_WINDOWS
, " Failed to add boot driver\n"));
651 //DbgPrint((DPRINT_REACTOS, " Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current group '%S')\n",
652 // ServiceName, StartValue, TagValue, DriverGroup, GroupName));
659 /* Move to the next group name */
660 GroupName
= GroupName
+ wcslen(GroupName
) + 1;
665 WinLdrAddDriverToList(LIST_ENTRY
*BootDriverListHead
,
670 PBOOT_DRIVER_LIST_ENTRY BootDriverEntry
;
674 BootDriverEntry
= MmAllocateMemory(sizeof(BOOT_DRIVER_LIST_ENTRY
));
676 if (!BootDriverEntry
)
679 // DTE will be filled during actual load of the driver
680 BootDriverEntry
->DataTableEntry
= NULL
;
682 // Check - if we have a valid ImagePath, if not - we need to build it
683 // like "System32\\Drivers\\blah.sys"
684 if (ImagePath
&& (wcslen(ImagePath
) > 0))
686 // Just copy ImagePath to the corresponding field in the structure
687 PathLength
= wcslen(ImagePath
) * sizeof(WCHAR
);
689 BootDriverEntry
->FilePath
.Length
= 0;
690 BootDriverEntry
->FilePath
.MaximumLength
= PathLength
+ sizeof(WCHAR
);
691 BootDriverEntry
->FilePath
.Buffer
= MmAllocateMemory(PathLength
);
693 if (!BootDriverEntry
->FilePath
.Buffer
)
696 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->FilePath
, ImagePath
);
697 if (!NT_SUCCESS(Status
))
702 // we have to construct ImagePath ourselves
703 PathLength
= wcslen(ServiceName
)*sizeof(WCHAR
) + sizeof(L
"system32\\drivers\\.sys");;
704 BootDriverEntry
->FilePath
.Length
= 0;
705 BootDriverEntry
->FilePath
.MaximumLength
= PathLength
+sizeof(WCHAR
);
706 BootDriverEntry
->FilePath
.Buffer
= MmAllocateMemory(PathLength
);
708 if (!BootDriverEntry
->FilePath
.Buffer
)
711 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->FilePath
, L
"system32\\drivers\\");
712 if (!NT_SUCCESS(Status
))
715 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->FilePath
, ServiceName
);
716 if (!NT_SUCCESS(Status
))
719 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->FilePath
, L
".sys");
720 if (!NT_SUCCESS(Status
))
725 PathLength
= wcslen(RegistryPath
)*sizeof(WCHAR
);
726 BootDriverEntry
->RegistryPath
.Length
= 0;
727 BootDriverEntry
->RegistryPath
.MaximumLength
= PathLength
+sizeof(WCHAR
);
728 BootDriverEntry
->RegistryPath
.Buffer
= MmAllocateMemory(PathLength
);
729 if (!BootDriverEntry
->RegistryPath
.Buffer
)
732 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->RegistryPath
, RegistryPath
);
733 if (!NT_SUCCESS(Status
))
736 // Insert entry at top of the list
737 InsertHeadList(BootDriverListHead
, &BootDriverEntry
->ListEntry
);