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 ***************************************************************/
14 // The only global var here, used to mark mem pages as NLS in WinLdrTurnOnPaging()
15 ULONG TotalNLSSize
= 0;
17 BOOLEAN
WinLdrGetNLSNames(LPSTR AnsiName
,
22 WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
23 IN LPCSTR DirectoryPath
,
24 IN LPCSTR AnsiFileName
,
25 IN LPCSTR OemFileName
,
26 IN LPCSTR LanguageFileName
);
29 WinLdrScanRegistry(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
30 IN LPCSTR DirectoryPath
);
33 WinLdrAddDriverToList(LIST_ENTRY
*BootDriverListHead
,
38 /* FUNCTIONS **************************************************************/
41 WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
42 IN LPCSTR DirectoryPath
,
46 CHAR FullHiveName
[256];
48 FILEINFORMATION FileInfo
;
50 ULONG_PTR HiveDataPhysical
;
51 PVOID HiveDataVirtual
;
55 /* Concatenate path and filename to get the full name */
56 strcpy(FullHiveName
, DirectoryPath
);
57 strcat(FullHiveName
, HiveName
);
58 //Print(L"Loading %s...\n", FullHiveName);
59 Status
= ArcOpen(FullHiveName
, OpenReadOnly
, &FileId
);
61 if (Status
!= ESUCCESS
)
63 UiMessageBox("Opening hive file failed!");
67 /* Get the file length */
68 Status
= ArcGetFileInformation(FileId
, &FileInfo
);
70 if (Status
!= ESUCCESS
)
73 UiMessageBox("Hive file has 0 size!");
76 HiveFileSize
= FileInfo
.EndingAddress
.LowPart
;
78 /* Round up the size to page boundary and alloc memory */
79 HiveDataPhysical
= (ULONG_PTR
)MmAllocateMemoryWithType(
80 MM_SIZE_TO_PAGES(HiveFileSize
+ MM_PAGE_SIZE
- 1) << MM_PAGE_SHIFT
,
83 if (HiveDataPhysical
== 0)
86 UiMessageBox("Unable to alloc memory for a hive!");
90 /* Convert address to virtual */
91 HiveDataVirtual
= PaToVa((PVOID
)HiveDataPhysical
);
93 /* Fill LoaderBlock's entries */
94 LoaderBlock
->RegistryLength
= HiveFileSize
;
95 LoaderBlock
->RegistryBase
= HiveDataVirtual
;
97 /* Finally read from file to the memory */
98 Status
= ArcRead(FileId
, (PVOID
)HiveDataPhysical
, HiveFileSize
, &BytesRead
);
99 if (Status
!= ESUCCESS
)
102 UiMessageBox("Unable to read from hive file!");
106 // Add boot filesystem driver to the list
107 FsService
= FsGetServiceName(FileId
);
110 DPRINTM(DPRINT_WINDOWS
, " Adding filesystem service %S\n", FsService
);
111 Status
= WinLdrAddDriverToList(&LoaderBlock
->BootDriverListHead
,
112 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
116 DPRINTM(DPRINT_WINDOWS
, " Failed to add filesystem service\n");
120 DPRINTM(DPRINT_WINDOWS
, " No required filesystem service\n");
127 BOOLEAN
WinLdrInitSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
128 IN LPCSTR DirectoryPath
)
130 CHAR SearchPath
[1024];
133 // There is a simple logic here: try to load usual hive (system), if it
134 // fails, then give system.alt a try, and finally try a system.sav
136 // FIXME: For now we only try system
137 strcpy(SearchPath
, DirectoryPath
);
138 strcat(SearchPath
, "SYSTEM32\\CONFIG\\");
139 Status
= WinLdrLoadSystemHive(LoaderBlock
, SearchPath
, "SYSTEM");
145 // Initialize in-memory registry
146 RegInitializeRegistry();
148 // Import what was loaded
149 Status
= RegImportBinaryHive((PCHAR
)VaToPa(LoaderBlock
->RegistryBase
), LoaderBlock
->RegistryLength
);
152 UiMessageBox("Importing binary hive failed!");
156 // Initialize the 'CurrentControlSet' link
157 if (RegInitCurrentControlSet(FALSE
) != ERROR_SUCCESS
)
159 UiMessageBox("Initializing CurrentControlSet link failed!");
166 BOOLEAN
WinLdrScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
167 IN LPCSTR DirectoryPath
)
169 CHAR SearchPath
[1024];
170 CHAR AnsiName
[256], OemName
[256], LangName
[256];
173 // Scan registry and prepare boot drivers list
174 WinLdrScanRegistry(LoaderBlock
, DirectoryPath
);
176 // Get names of NLS files
177 Status
= WinLdrGetNLSNames(AnsiName
, OemName
, LangName
);
180 UiMessageBox("Getting NLS names from registry failed!");
184 DPRINTM(DPRINT_WINDOWS
, "NLS data %s %s %s\n", AnsiName
, OemName
, LangName
);
187 strcpy(SearchPath
, DirectoryPath
);
188 strcat(SearchPath
, "SYSTEM32\\");
189 Status
= WinLdrLoadNLSData(LoaderBlock
, SearchPath
, AnsiName
, OemName
, LangName
);
190 DPRINTM(DPRINT_WINDOWS
, "NLS data loaded with status %d\n", Status
);
192 /* TODO: Load OEM HAL font */
199 /* PRIVATE FUNCTIONS ******************************************************/
201 // Queries registry for those three file names
202 BOOLEAN
WinLdrGetNLSNames(LPSTR AnsiName
,
206 LONG rc
= ERROR_SUCCESS
;
208 WCHAR szIdBuffer
[80];
209 WCHAR NameBuffer
[80];
212 /* open the codepage key */
213 rc
= RegOpenKey(NULL
,
214 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage",
216 if (rc
!= ERROR_SUCCESS
)
218 //strcpy(szErrorOut, "Couldn't open CodePage registry key");
222 /* get ANSI codepage */
223 BufferSize
= sizeof(szIdBuffer
);
224 rc
= RegQueryValue(hKey
, L
"ACP", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
225 if (rc
!= ERROR_SUCCESS
)
227 //strcpy(szErrorOut, "Couldn't get ACP NLS setting");
231 BufferSize
= sizeof(NameBuffer
);
232 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)NameBuffer
, &BufferSize
);
233 if (rc
!= ERROR_SUCCESS
)
235 //strcpy(szErrorOut, "ACP NLS Setting exists, but isn't readable");
238 sprintf(AnsiName
, "%S", NameBuffer
);
240 /* get OEM codepage */
241 BufferSize
= sizeof(szIdBuffer
);
242 rc
= RegQueryValue(hKey
, L
"OEMCP", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
243 if (rc
!= ERROR_SUCCESS
)
245 //strcpy(szErrorOut, "Couldn't get OEMCP NLS setting");
249 BufferSize
= sizeof(NameBuffer
);
250 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)NameBuffer
, &BufferSize
);
251 if (rc
!= ERROR_SUCCESS
)
253 //strcpy(szErrorOut, "OEMCP NLS setting exists, but isn't readable");
256 sprintf(OemName
, "%S", NameBuffer
);
258 /* open the language key */
259 rc
= RegOpenKey(NULL
,
260 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
262 if (rc
!= ERROR_SUCCESS
)
264 //strcpy(szErrorOut, "Couldn't open Language registry key");
268 /* get the Unicode case table */
269 BufferSize
= sizeof(szIdBuffer
);
270 rc
= RegQueryValue(hKey
, L
"Default", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
271 if (rc
!= ERROR_SUCCESS
)
273 //strcpy(szErrorOut, "Couldn't get Language Default setting");
277 BufferSize
= sizeof(NameBuffer
);
278 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)NameBuffer
, &BufferSize
);
279 if (rc
!= ERROR_SUCCESS
)
281 //strcpy(szErrorOut, "Language Default setting exists, but isn't readable");
284 sprintf(LangName
, "%S", NameBuffer
);
291 WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
292 IN LPCSTR DirectoryPath
,
293 IN LPCSTR AnsiFileName
,
294 IN LPCSTR OemFileName
,
295 IN LPCSTR LanguageFileName
)
300 ULONG LanguageFileId
;
301 ULONG AnsiFileSize
, OemFileSize
, LanguageFileSize
;
303 ULONG_PTR NlsDataBase
;
305 BOOLEAN AnsiEqualsOem
= FALSE
;
306 FILEINFORMATION FileInfo
;
307 ULONG BytesRead
, Status
;
309 /* There may be a case, when OEM and ANSI page coincide */
310 if (!strcmp(AnsiFileName
, OemFileName
))
311 AnsiEqualsOem
= TRUE
;
313 /* Open file with ANSI and store its size */
314 //Print(L"Loading %s...\n", Filename);
315 strcpy(FileName
, DirectoryPath
);
316 strcat(FileName
, AnsiFileName
);
317 Status
= ArcOpen(FileName
, OpenReadOnly
, &AnsiFileId
);
319 if (Status
!= ESUCCESS
)
322 Status
= ArcGetFileInformation(AnsiFileId
, &FileInfo
);
323 if (Status
!= ESUCCESS
)
325 AnsiFileSize
= FileInfo
.EndingAddress
.LowPart
;
326 DPRINTM(DPRINT_WINDOWS
, "AnsiFileSize: %d\n", AnsiFileSize
);
327 ArcClose(AnsiFileId
);
329 /* Open OEM file and store its length */
336 //Print(L"Loading %s...\n", Filename);
337 strcpy(FileName
, DirectoryPath
);
338 strcat(FileName
, OemFileName
);
339 Status
= ArcOpen(FileName
, OpenReadOnly
, &OemFileId
);
341 if (Status
!= ESUCCESS
)
344 Status
= ArcGetFileInformation(OemFileId
, &FileInfo
);
345 if (Status
!= ESUCCESS
)
347 OemFileSize
= FileInfo
.EndingAddress
.LowPart
;
350 DPRINTM(DPRINT_WINDOWS
, "OemFileSize: %d\n", OemFileSize
);
352 /* And finally open the language codepage file and store its length */
353 //Print(L"Loading %s...\n", Filename);
354 strcpy(FileName
, DirectoryPath
);
355 strcat(FileName
, LanguageFileName
);
356 Status
= ArcOpen(FileName
, OpenReadOnly
, &LanguageFileId
);
358 if (Status
!= ESUCCESS
)
361 Status
= ArcGetFileInformation(LanguageFileId
, &FileInfo
);
362 if (Status
!= ESUCCESS
)
364 LanguageFileSize
= FileInfo
.EndingAddress
.LowPart
;
365 ArcClose(LanguageFileId
);
366 DPRINTM(DPRINT_WINDOWS
, "LanguageFileSize: %d\n", LanguageFileSize
);
368 /* Sum up all three length, having in mind that every one of them
369 must start at a page boundary => thus round up each file to a page */
370 TotalSize
= MM_SIZE_TO_PAGES(AnsiFileSize
) +
371 MM_SIZE_TO_PAGES(OemFileSize
) +
372 MM_SIZE_TO_PAGES(LanguageFileSize
);
374 /* Store it for later marking the pages as NlsData type */
375 TotalNLSSize
= TotalSize
;
377 NlsDataBase
= (ULONG_PTR
)MmAllocateMemoryWithType(TotalSize
*MM_PAGE_SIZE
, LoaderNlsData
);
379 if (NlsDataBase
== 0)
382 NlsVirtual
= PaToVa((PVOID
)NlsDataBase
);
383 LoaderBlock
->NlsData
->AnsiCodePageData
= NlsVirtual
;
384 LoaderBlock
->NlsData
->OemCodePageData
= (PVOID
)((PUCHAR
)NlsVirtual
+
385 (MM_SIZE_TO_PAGES(AnsiFileSize
) << MM_PAGE_SHIFT
));
386 LoaderBlock
->NlsData
->UnicodeCodePageData
= (PVOID
)((PUCHAR
)NlsVirtual
+
387 (MM_SIZE_TO_PAGES(AnsiFileSize
) << MM_PAGE_SHIFT
) +
388 (MM_SIZE_TO_PAGES(OemFileSize
) << MM_PAGE_SHIFT
));
390 /* Ansi and OEM data are the same - just set pointers to the same area */
392 LoaderBlock
->NlsData
->OemCodePageData
= LoaderBlock
->NlsData
->AnsiCodePageData
;
395 /* Now actually read the data into memory, starting with Ansi file */
396 strcpy(FileName
, DirectoryPath
);
397 strcat(FileName
, AnsiFileName
);
398 Status
= ArcOpen(FileName
, OpenReadOnly
, &AnsiFileId
);
400 if (Status
!= ESUCCESS
)
403 Status
= ArcRead(AnsiFileId
, VaToPa(LoaderBlock
->NlsData
->AnsiCodePageData
), AnsiFileSize
, &BytesRead
);
405 if (Status
!= ESUCCESS
)
408 ArcClose(AnsiFileId
);
410 /* OEM now, if it doesn't equal Ansi of course */
413 strcpy(FileName
, DirectoryPath
);
414 strcat(FileName
, OemFileName
);
415 Status
= ArcOpen(FileName
, OpenReadOnly
, &OemFileId
);
417 if (Status
!= ESUCCESS
)
420 Status
= ArcRead(OemFileId
, VaToPa(LoaderBlock
->NlsData
->OemCodePageData
), OemFileSize
, &BytesRead
);
422 if (Status
!= ESUCCESS
)
428 /* finally the language file */
429 strcpy(FileName
, DirectoryPath
);
430 strcat(FileName
, LanguageFileName
);
431 Status
= ArcOpen(FileName
, OpenReadOnly
, &LanguageFileId
);
433 if (Status
!= ESUCCESS
)
436 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\n", Filename);
456 UiMessageBox("Error reading NLS file!");
461 WinLdrScanRegistry(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
462 IN LPCSTR DirectoryPath
)
465 FRLDRHKEY hGroupKey
, hOrderKey
, hServiceKey
, hDriverKey
;
466 LPWSTR GroupNameBuffer
;
467 WCHAR ServiceName
[256];
468 ULONG OrderList
[128];
478 WCHAR DriverGroup
[256];
479 ULONG DriverGroupSize
;
482 WCHAR TempImagePath
[256];
486 /* get 'service group order' key */
487 rc
= RegOpenKey(NULL
,
488 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder",
490 if (rc
!= ERROR_SUCCESS
) {
492 DPRINTM(DPRINT_REACTOS
, "Failed to open the 'ServiceGroupOrder' key (rc %d)\n", (int)rc
);
496 /* get 'group order list' key */
497 rc
= RegOpenKey(NULL
,
498 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\GroupOrderList",
500 if (rc
!= ERROR_SUCCESS
) {
502 DPRINTM(DPRINT_REACTOS
, "Failed to open the 'GroupOrderList' key (rc %d)\n", (int)rc
);
506 /* enumerate drivers */
507 rc
= RegOpenKey(NULL
,
508 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services",
510 if (rc
!= ERROR_SUCCESS
) {
512 DPRINTM(DPRINT_REACTOS
, "Failed to open the 'Services' key (rc %d)\n", (int)rc
);
516 /* Get the Name Group */
518 GroupNameBuffer
= MmHeapAlloc(BufferSize
);
519 rc
= RegQueryValue(hGroupKey
, L
"List", NULL
, (PUCHAR
)GroupNameBuffer
, &BufferSize
);
520 DPRINTM(DPRINT_REACTOS
, "RegQueryValue(): rc %d\n", (int)rc
);
521 if (rc
!= ERROR_SUCCESS
)
523 DPRINTM(DPRINT_REACTOS
, "BufferSize: %d \n", (int)BufferSize
);
524 DPRINTM(DPRINT_REACTOS
, "GroupNameBuffer: '%S' \n", GroupNameBuffer
);
526 /* Loop through each group */
527 GroupName
= GroupNameBuffer
;
530 DPRINTM(DPRINT_WINDOWS
, "Driver group: '%S'\n", GroupName
);
532 /* Query the Order */
533 BufferSize
= sizeof(OrderList
);
534 rc
= RegQueryValue(hOrderKey
, GroupName
, NULL
, (PUCHAR
)OrderList
, &BufferSize
);
535 if (rc
!= ERROR_SUCCESS
) OrderList
[0] = 0;
537 /* enumerate all drivers */
538 for (TagIndex
= 1; TagIndex
<= OrderList
[0]; TagIndex
++)
544 /* Get the Driver's Name */
545 ValueSize
= sizeof(ServiceName
);
546 rc
= RegEnumKey(hServiceKey
, Index
, ServiceName
, &ValueSize
);
547 //DPRINTM(DPRINT_REACTOS, "RegEnumKey(): rc %d\n", (int)rc);
549 /* Makre sure it's valid, and check if we're done */
550 if (rc
== ERROR_NO_MORE_ITEMS
)
552 if (rc
!= ERROR_SUCCESS
)
554 MmHeapFree(GroupNameBuffer
);
557 //DPRINTM(DPRINT_REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName);
559 /* open driver Key */
560 rc
= RegOpenKey(hServiceKey
, ServiceName
, &hDriverKey
);
561 if (rc
== ERROR_SUCCESS
)
563 /* Read the Start Value */
564 ValueSize
= sizeof(ULONG
);
565 rc
= RegQueryValue(hDriverKey
, L
"Start", &ValueType
, (PUCHAR
)&StartValue
, &ValueSize
);
566 if (rc
!= ERROR_SUCCESS
) StartValue
= (ULONG
)-1;
567 //DPRINTM(DPRINT_REACTOS, " Start: %x \n", (int)StartValue);
570 ValueSize
= sizeof(ULONG
);
571 rc
= RegQueryValue(hDriverKey
, L
"Tag", &ValueType
, (PUCHAR
)&TagValue
, &ValueSize
);
572 if (rc
!= ERROR_SUCCESS
) TagValue
= (ULONG
)-1;
573 //DPRINTM(DPRINT_REACTOS, " Tag: %x \n", (int)TagValue);
575 /* Read the driver's group */
576 DriverGroupSize
= sizeof(DriverGroup
);
577 rc
= RegQueryValue(hDriverKey
, L
"Group", NULL
, (PUCHAR
)DriverGroup
, &DriverGroupSize
);
578 //DPRINTM(DPRINT_REACTOS, " Group: '%S' \n", DriverGroup);
580 /* Make sure it should be started */
581 if ((StartValue
== 0) &&
582 (TagValue
== OrderList
[TagIndex
]) &&
583 (_wcsicmp(DriverGroup
, GroupName
) == 0)) {
585 /* Get the Driver's Location */
586 ValueSize
= sizeof(TempImagePath
);
587 rc
= RegQueryValue(hDriverKey
, L
"ImagePath", NULL
, (PUCHAR
)TempImagePath
, &ValueSize
);
589 /* Write the whole path if it suceeded, else prepare to fail */
590 if (rc
!= ERROR_SUCCESS
) {
591 DPRINTM(DPRINT_REACTOS
, " ImagePath: not found\n");
592 TempImagePath
[0] = 0;
593 sprintf(ImagePath
, "%s\\system32\\drivers\\%S.sys", DirectoryPath
, ServiceName
);
594 } else if (TempImagePath
[0] != L
'\\') {
595 sprintf(ImagePath
, "%s%S", DirectoryPath
, TempImagePath
);
597 sprintf(ImagePath
, "%S", TempImagePath
);
598 DPRINTM(DPRINT_REACTOS
, " ImagePath: '%s'\n", ImagePath
);
601 DPRINTM(DPRINT_WINDOWS
, " Adding boot driver: '%s'\n", ImagePath
);
603 Status
= WinLdrAddDriverToList(&LoaderBlock
->BootDriverListHead
,
604 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
609 DPRINTM(DPRINT_WINDOWS
, " Failed to add boot driver\n");
612 //DPRINTM(DPRINT_WINDOWS, " 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);
624 /* Get the Driver's Name */
625 ValueSize
= sizeof(ServiceName
);
626 rc
= RegEnumKey(hServiceKey
, Index
, ServiceName
, &ValueSize
);
628 //DPRINTM(DPRINT_REACTOS, "RegEnumKey(): rc %d\n", (int)rc);
629 if (rc
== ERROR_NO_MORE_ITEMS
)
631 if (rc
!= ERROR_SUCCESS
)
633 MmHeapFree(GroupNameBuffer
);
636 //DPRINTM(DPRINT_REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName);
638 /* open driver Key */
639 rc
= RegOpenKey(hServiceKey
, ServiceName
, &hDriverKey
);
640 if (rc
== ERROR_SUCCESS
)
642 /* Read the Start Value */
643 ValueSize
= sizeof(ULONG
);
644 rc
= RegQueryValue(hDriverKey
, L
"Start", &ValueType
, (PUCHAR
)&StartValue
, &ValueSize
);
645 if (rc
!= ERROR_SUCCESS
) StartValue
= (ULONG
)-1;
646 //DPRINTM(DPRINT_REACTOS, " Start: %x \n", (int)StartValue);
649 ValueSize
= sizeof(ULONG
);
650 rc
= RegQueryValue(hDriverKey
, L
"Tag", &ValueType
, (PUCHAR
)&TagValue
, &ValueSize
);
651 if (rc
!= ERROR_SUCCESS
) TagValue
= (ULONG
)-1;
652 //DPRINTM(DPRINT_REACTOS, " Tag: %x \n", (int)TagValue);
654 /* Read the driver's group */
655 DriverGroupSize
= sizeof(DriverGroup
);
656 rc
= RegQueryValue(hDriverKey
, L
"Group", NULL
, (PUCHAR
)DriverGroup
, &DriverGroupSize
);
657 //DPRINTM(DPRINT_REACTOS, " Group: '%S' \n", DriverGroup);
659 for (TagIndex
= 1; TagIndex
<= OrderList
[0]; TagIndex
++) {
660 if (TagValue
== OrderList
[TagIndex
]) break;
663 if ((StartValue
== 0) &&
664 (TagIndex
> OrderList
[0]) &&
665 (_wcsicmp(DriverGroup
, GroupName
) == 0)) {
667 ValueSize
= sizeof(TempImagePath
);
668 rc
= RegQueryValue(hDriverKey
, L
"ImagePath", NULL
, (PUCHAR
)TempImagePath
, &ValueSize
);
669 if (rc
!= ERROR_SUCCESS
) {
670 DPRINTM(DPRINT_REACTOS
, " ImagePath: not found\n");
671 TempImagePath
[0] = 0;
672 sprintf(ImagePath
, "%ssystem32\\drivers\\%S.sys", DirectoryPath
, ServiceName
);
673 } else if (TempImagePath
[0] != L
'\\') {
674 sprintf(ImagePath
, "%s%S", DirectoryPath
, TempImagePath
);
676 sprintf(ImagePath
, "%S", TempImagePath
);
677 DPRINTM(DPRINT_REACTOS
, " ImagePath: '%s'\n", ImagePath
);
679 DPRINTM(DPRINT_WINDOWS
, " Adding boot driver: '%s'\n", ImagePath
);
681 Status
= WinLdrAddDriverToList(&LoaderBlock
->BootDriverListHead
,
682 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
687 DPRINTM(DPRINT_WINDOWS
, " Failed to add boot driver\n");
690 //DPRINTM(DPRINT_WINDOWS, " Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current group '%S')\n",
691 // ServiceName, StartValue, TagValue, DriverGroup, GroupName);
698 /* Move to the next group name */
699 GroupName
= GroupName
+ wcslen(GroupName
) + 1;
702 /* Free allocated memory */
703 MmHeapFree(GroupNameBuffer
);
707 WinLdrAddDriverToList(LIST_ENTRY
*BootDriverListHead
,
712 PBOOT_DRIVER_LIST_ENTRY BootDriverEntry
;
716 BootDriverEntry
= MmHeapAlloc(sizeof(BOOT_DRIVER_LIST_ENTRY
));
718 if (!BootDriverEntry
)
721 // DTE will be filled during actual load of the driver
722 BootDriverEntry
->LdrEntry
= NULL
;
724 // Check - if we have a valid ImagePath, if not - we need to build it
725 // like "System32\\Drivers\\blah.sys"
726 if (ImagePath
&& (wcslen(ImagePath
) > 0))
728 // Just copy ImagePath to the corresponding field in the structure
729 PathLength
= wcslen(ImagePath
) * sizeof(WCHAR
);
731 BootDriverEntry
->FilePath
.Length
= 0;
732 BootDriverEntry
->FilePath
.MaximumLength
= PathLength
+ sizeof(WCHAR
);
733 BootDriverEntry
->FilePath
.Buffer
= MmHeapAlloc(PathLength
);
735 if (!BootDriverEntry
->FilePath
.Buffer
)
737 MmHeapFree(BootDriverEntry
);
741 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->FilePath
, ImagePath
);
742 if (!NT_SUCCESS(Status
))
744 MmHeapFree(BootDriverEntry
->FilePath
.Buffer
);
745 MmHeapFree(BootDriverEntry
);
751 // we have to construct ImagePath ourselves
752 PathLength
= wcslen(ServiceName
)*sizeof(WCHAR
) + sizeof(L
"system32\\drivers\\.sys");
753 BootDriverEntry
->FilePath
.Length
= 0;
754 BootDriverEntry
->FilePath
.MaximumLength
= PathLength
+sizeof(WCHAR
);
755 BootDriverEntry
->FilePath
.Buffer
= MmHeapAlloc(PathLength
);
757 if (!BootDriverEntry
->FilePath
.Buffer
)
759 MmHeapFree(BootDriverEntry
);
763 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->FilePath
, L
"system32\\drivers\\");
764 if (!NT_SUCCESS(Status
))
766 MmHeapFree(BootDriverEntry
->FilePath
.Buffer
);
767 MmHeapFree(BootDriverEntry
);
771 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->FilePath
, ServiceName
);
772 if (!NT_SUCCESS(Status
))
774 MmHeapFree(BootDriverEntry
->FilePath
.Buffer
);
775 MmHeapFree(BootDriverEntry
);
779 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->FilePath
, L
".sys");
780 if (!NT_SUCCESS(Status
))
782 MmHeapFree(BootDriverEntry
->FilePath
.Buffer
);
783 MmHeapFree(BootDriverEntry
);
789 PathLength
= (wcslen(RegistryPath
)+wcslen(ServiceName
))*sizeof(WCHAR
);
790 BootDriverEntry
->RegistryPath
.Length
= 0;
791 BootDriverEntry
->RegistryPath
.MaximumLength
= PathLength
;//+sizeof(WCHAR);
792 BootDriverEntry
->RegistryPath
.Buffer
= MmHeapAlloc(PathLength
);
793 if (!BootDriverEntry
->RegistryPath
.Buffer
)
796 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->RegistryPath
, RegistryPath
);
797 if (!NT_SUCCESS(Status
))
800 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->RegistryPath
, ServiceName
);
801 if (!NT_SUCCESS(Status
))
804 // Insert entry at top of the list
805 InsertTailList(BootDriverListHead
, &BootDriverEntry
->Link
);