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
;
54 /* Concatenate path and filename to get the full name */
55 strcpy(FullHiveName
, DirectoryPath
);
56 strcat(FullHiveName
, HiveName
);
57 //Print(L"Loading %s...\n", FullHiveName);
58 Status
= ArcOpen(FullHiveName
, OpenReadOnly
, &FileId
);
60 if (Status
!= ESUCCESS
)
62 UiMessageBox("Opening hive file failed!");
66 /* Get the file length */
67 Status
= ArcGetFileInformation(FileId
, &FileInfo
);
69 if (Status
!= ESUCCESS
)
72 UiMessageBox("Hive file has 0 size!");
75 HiveFileSize
= FileInfo
.EndingAddress
.LowPart
;
77 /* Round up the size to page boundary and alloc memory */
78 HiveDataPhysical
= (ULONG_PTR
)MmAllocateMemoryWithType(
79 MM_SIZE_TO_PAGES(HiveFileSize
+ MM_PAGE_SIZE
- 1) << MM_PAGE_SHIFT
,
82 if (HiveDataPhysical
== 0)
85 UiMessageBox("Unable to alloc memory for a hive!");
89 /* Convert address to virtual */
90 HiveDataVirtual
= (PVOID
)(KSEG0_BASE
| HiveDataPhysical
);
92 /* Fill LoaderBlock's entries */
93 LoaderBlock
->RegistryLength
= HiveFileSize
;
94 LoaderBlock
->RegistryBase
= HiveDataVirtual
;
96 /* Finally read from file to the memory */
97 Status
= ArcRead(FileId
, (PVOID
)HiveDataPhysical
, HiveFileSize
, &BytesRead
);
99 if (Status
!= ESUCCESS
)
101 UiMessageBox("Unable to read from hive file!");
108 BOOLEAN
WinLdrLoadAndScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
109 IN LPCSTR DirectoryPath
)
111 CHAR SearchPath
[1024];
112 CHAR AnsiName
[256], OemName
[256], LangName
[256];
115 // There is a simple logic here: try to load usual hive (system), if it
116 // fails, then give system.alt a try, and finally try a system.sav
118 // FIXME: For now we only try system
119 strcpy(SearchPath
, DirectoryPath
);
120 strcat(SearchPath
, "SYSTEM32\\CONFIG\\");
121 Status
= WinLdrLoadSystemHive(LoaderBlock
, SearchPath
, "SYSTEM");
127 // Initialize in-memory registry
128 RegInitializeRegistry();
130 // Import what was loaded
131 Status
= RegImportBinaryHive((PCHAR
)VaToPa(LoaderBlock
->RegistryBase
), LoaderBlock
->RegistryLength
);
134 UiMessageBox("Importing binary hive failed!");
138 // Initialize the 'CurrentControlSet' link
139 if (RegInitCurrentControlSet(FALSE
) != ERROR_SUCCESS
)
141 UiMessageBox("Initializing CurrentControlSet link failed!");
145 // Scan registry and prepare boot drivers list
146 WinLdrScanRegistry(LoaderBlock
, DirectoryPath
);
148 // Add boot filesystem driver to the list
149 //FIXME: Use corresponding driver instead of hardcoding
150 Status
= WinLdrAddDriverToList(&LoaderBlock
->BootDriverListHead
,
151 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
156 // Get names of NLS files
157 Status
= WinLdrGetNLSNames(AnsiName
, OemName
, LangName
);
160 UiMessageBox("Getting NLS names from registry failed!");
164 DPRINTM(DPRINT_WINDOWS
, "NLS data %s %s %s\n", AnsiName
, OemName
, LangName
);
167 strcpy(SearchPath
, DirectoryPath
);
168 strcat(SearchPath
, "SYSTEM32\\");
169 Status
= WinLdrLoadNLSData(LoaderBlock
, SearchPath
, AnsiName
, OemName
, LangName
);
170 DPRINTM(DPRINT_WINDOWS
, "NLS data loaded with status %d\n", Status
);
172 /* TODO: Load OEM HAL font */
179 /* PRIVATE FUNCTIONS ******************************************************/
181 // Queries registry for those three file names
182 BOOLEAN
WinLdrGetNLSNames(LPSTR AnsiName
,
186 LONG rc
= ERROR_SUCCESS
;
188 WCHAR szIdBuffer
[80];
189 WCHAR NameBuffer
[80];
192 /* open the codepage key */
193 rc
= RegOpenKey(NULL
,
194 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage",
196 if (rc
!= ERROR_SUCCESS
)
198 //strcpy(szErrorOut, "Couldn't open CodePage registry key");
202 /* get ANSI codepage */
203 BufferSize
= sizeof(szIdBuffer
);
204 rc
= RegQueryValue(hKey
, L
"ACP", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
205 if (rc
!= ERROR_SUCCESS
)
207 //strcpy(szErrorOut, "Couldn't get ACP NLS setting");
211 BufferSize
= sizeof(NameBuffer
);
212 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)NameBuffer
, &BufferSize
);
213 if (rc
!= ERROR_SUCCESS
)
215 //strcpy(szErrorOut, "ACP NLS Setting exists, but isn't readable");
218 sprintf(AnsiName
, "%S", NameBuffer
);
220 /* get OEM codepage */
221 BufferSize
= sizeof(szIdBuffer
);
222 rc
= RegQueryValue(hKey
, L
"OEMCP", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
223 if (rc
!= ERROR_SUCCESS
)
225 //strcpy(szErrorOut, "Couldn't get OEMCP NLS setting");
229 BufferSize
= sizeof(NameBuffer
);
230 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)NameBuffer
, &BufferSize
);
231 if (rc
!= ERROR_SUCCESS
)
233 //strcpy(szErrorOut, "OEMCP NLS setting exists, but isn't readable");
236 sprintf(OemName
, "%S", NameBuffer
);
238 /* open the language key */
239 rc
= RegOpenKey(NULL
,
240 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
242 if (rc
!= ERROR_SUCCESS
)
244 //strcpy(szErrorOut, "Couldn't open Language registry key");
248 /* get the Unicode case table */
249 BufferSize
= sizeof(szIdBuffer
);
250 rc
= RegQueryValue(hKey
, L
"Default", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
251 if (rc
!= ERROR_SUCCESS
)
253 //strcpy(szErrorOut, "Couldn't get Language Default setting");
257 BufferSize
= sizeof(NameBuffer
);
258 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)NameBuffer
, &BufferSize
);
259 if (rc
!= ERROR_SUCCESS
)
261 //strcpy(szErrorOut, "Language Default setting exists, but isn't readable");
264 sprintf(LangName
, "%S", NameBuffer
);
271 WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
272 IN LPCSTR DirectoryPath
,
273 IN LPCSTR AnsiFileName
,
274 IN LPCSTR OemFileName
,
275 IN LPCSTR LanguageFileName
)
280 ULONG LanguageFileId
;
281 ULONG AnsiFileSize
, OemFileSize
, LanguageFileSize
;
283 ULONG_PTR NlsDataBase
;
285 BOOLEAN AnsiEqualsOem
= FALSE
;
286 FILEINFORMATION FileInfo
;
287 ULONG BytesRead
, Status
;
289 /* There may be a case, when OEM and ANSI page coincide */
290 if (!strcmp(AnsiFileName
, OemFileName
))
291 AnsiEqualsOem
= TRUE
;
293 /* Open file with ANSI and store its size */
294 //Print(L"Loading %s...\n", Filename);
295 strcpy(FileName
, DirectoryPath
);
296 strcat(FileName
, AnsiFileName
);
297 Status
= ArcOpen(FileName
, OpenReadOnly
, &AnsiFileId
);
299 if (Status
!= ESUCCESS
)
302 Status
= ArcGetFileInformation(AnsiFileId
, &FileInfo
);
303 if (Status
!= ESUCCESS
)
305 AnsiFileSize
= FileInfo
.EndingAddress
.LowPart
;
306 DPRINTM(DPRINT_WINDOWS
, "AnsiFileSize: %d\n", AnsiFileSize
);
307 ArcClose(AnsiFileId
);
309 /* Open OEM file and store its length */
316 //Print(L"Loading %s...\n", Filename);
317 strcpy(FileName
, DirectoryPath
);
318 strcat(FileName
, OemFileName
);
319 Status
= ArcOpen(FileName
, OpenReadOnly
, &OemFileId
);
321 if (Status
!= ESUCCESS
)
324 Status
= ArcGetFileInformation(OemFileId
, &FileInfo
);
325 if (Status
!= ESUCCESS
)
327 OemFileSize
= FileInfo
.EndingAddress
.LowPart
;
330 DPRINTM(DPRINT_WINDOWS
, "OemFileSize: %d\n", OemFileSize
);
332 /* And finally open the language codepage file and store its length */
333 //Print(L"Loading %s...\n", Filename);
334 strcpy(FileName
, DirectoryPath
);
335 strcat(FileName
, LanguageFileName
);
336 Status
= ArcOpen(FileName
, OpenReadOnly
, &LanguageFileId
);
338 if (Status
!= ESUCCESS
)
341 Status
= ArcGetFileInformation(LanguageFileId
, &FileInfo
);
342 if (Status
!= ESUCCESS
)
344 LanguageFileSize
= FileInfo
.EndingAddress
.LowPart
;
345 ArcClose(LanguageFileId
);
346 DPRINTM(DPRINT_WINDOWS
, "LanguageFileSize: %d\n", LanguageFileSize
);
348 /* Sum up all three length, having in mind that every one of them
349 must start at a page boundary => thus round up each file to a page */
350 TotalSize
= MM_SIZE_TO_PAGES(AnsiFileSize
) +
351 MM_SIZE_TO_PAGES(OemFileSize
) +
352 MM_SIZE_TO_PAGES(LanguageFileSize
);
354 /* Store it for later marking the pages as NlsData type */
355 TotalNLSSize
= TotalSize
;
357 NlsDataBase
= (ULONG_PTR
)MmAllocateMemoryWithType(TotalSize
*MM_PAGE_SIZE
, LoaderNlsData
);
359 if (NlsDataBase
== 0)
362 NlsVirtual
= (PVOID
)(KSEG0_BASE
| NlsDataBase
);
363 LoaderBlock
->NlsData
->AnsiCodePageData
= NlsVirtual
;
364 LoaderBlock
->NlsData
->OemCodePageData
= (PVOID
)((PUCHAR
)NlsVirtual
+
365 (MM_SIZE_TO_PAGES(AnsiFileSize
) << MM_PAGE_SHIFT
));
366 LoaderBlock
->NlsData
->UnicodeCodePageData
= (PVOID
)((PUCHAR
)NlsVirtual
+
367 (MM_SIZE_TO_PAGES(AnsiFileSize
) << MM_PAGE_SHIFT
) +
368 (MM_SIZE_TO_PAGES(OemFileSize
) << MM_PAGE_SHIFT
));
370 /* Ansi and OEM data are the same - just set pointers to the same area */
372 LoaderBlock
->NlsData
->OemCodePageData
= LoaderBlock
->NlsData
->AnsiCodePageData
;
375 /* Now actually read the data into memory, starting with Ansi file */
376 strcpy(FileName
, DirectoryPath
);
377 strcat(FileName
, AnsiFileName
);
378 Status
= ArcOpen(FileName
, OpenReadOnly
, &AnsiFileId
);
380 if (Status
!= ESUCCESS
)
383 Status
= ArcRead(AnsiFileId
, VaToPa(LoaderBlock
->NlsData
->AnsiCodePageData
), AnsiFileSize
, &BytesRead
);
385 if (Status
!= ESUCCESS
)
388 ArcClose(AnsiFileId
);
390 /* OEM now, if it doesn't equal Ansi of course */
393 strcpy(FileName
, DirectoryPath
);
394 strcat(FileName
, OemFileName
);
395 Status
= ArcOpen(FileName
, OpenReadOnly
, &OemFileId
);
397 if (Status
!= ESUCCESS
)
400 Status
= ArcRead(OemFileId
, VaToPa(LoaderBlock
->NlsData
->OemCodePageData
), OemFileSize
, &BytesRead
);
402 if (Status
!= ESUCCESS
)
408 /* finally the language file */
409 strcpy(FileName
, DirectoryPath
);
410 strcat(FileName
, LanguageFileName
);
411 Status
= ArcOpen(FileName
, OpenReadOnly
, &LanguageFileId
);
413 if (Status
!= ESUCCESS
)
416 Status
= ArcRead(LanguageFileId
, VaToPa(LoaderBlock
->NlsData
->UnicodeCodePageData
), LanguageFileSize
, &BytesRead
);
418 if (Status
!= ESUCCESS
)
421 ArcClose(LanguageFileId
);
424 // THIS IS HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK
425 // Should go to WinLdrLoadOemHalFont(), when it will be implemented
427 LoaderBlock
->OemFontFile
= VaToPa(LoaderBlock
->NlsData
->UnicodeCodePageData
);
429 /* Convert NlsTables address to VA */
430 LoaderBlock
->NlsData
= PaToVa(LoaderBlock
->NlsData
);
435 //UiMessageBox("Error reading NLS file %s\n", Filename);
436 UiMessageBox("Error reading NLS file!");
441 WinLdrScanRegistry(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
442 IN LPCSTR DirectoryPath
)
445 FRLDRHKEY hGroupKey
, hOrderKey
, hServiceKey
, hDriverKey
;
446 LPWSTR GroupNameBuffer
;
447 WCHAR ServiceName
[256];
448 ULONG OrderList
[128];
458 WCHAR DriverGroup
[256];
459 ULONG DriverGroupSize
;
462 WCHAR TempImagePath
[256];
466 /* get 'service group order' key */
467 rc
= RegOpenKey(NULL
,
468 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder",
470 if (rc
!= ERROR_SUCCESS
) {
472 DPRINTM(DPRINT_REACTOS
, "Failed to open the 'ServiceGroupOrder' key (rc %d)\n", (int)rc
);
476 /* get 'group order list' key */
477 rc
= RegOpenKey(NULL
,
478 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\GroupOrderList",
480 if (rc
!= ERROR_SUCCESS
) {
482 DPRINTM(DPRINT_REACTOS
, "Failed to open the 'GroupOrderList' key (rc %d)\n", (int)rc
);
486 /* enumerate drivers */
487 rc
= RegOpenKey(NULL
,
488 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services",
490 if (rc
!= ERROR_SUCCESS
) {
492 DPRINTM(DPRINT_REACTOS
, "Failed to open the 'Services' key (rc %d)\n", (int)rc
);
496 /* Get the Name Group */
498 GroupNameBuffer
= MmHeapAlloc(BufferSize
);
499 rc
= RegQueryValue(hGroupKey
, L
"List", NULL
, (PUCHAR
)GroupNameBuffer
, &BufferSize
);
500 DPRINTM(DPRINT_REACTOS
, "RegQueryValue(): rc %d\n", (int)rc
);
501 if (rc
!= ERROR_SUCCESS
)
503 DPRINTM(DPRINT_REACTOS
, "BufferSize: %d \n", (int)BufferSize
);
504 DPRINTM(DPRINT_REACTOS
, "GroupNameBuffer: '%S' \n", GroupNameBuffer
);
506 /* Loop through each group */
507 GroupName
= GroupNameBuffer
;
510 DPRINTM(DPRINT_WINDOWS
, "Driver group: '%S'\n", GroupName
);
512 /* Query the Order */
513 BufferSize
= sizeof(OrderList
);
514 rc
= RegQueryValue(hOrderKey
, GroupName
, NULL
, (PUCHAR
)OrderList
, &BufferSize
);
515 if (rc
!= ERROR_SUCCESS
) OrderList
[0] = 0;
517 /* enumerate all drivers */
518 for (TagIndex
= 1; TagIndex
<= OrderList
[0]; TagIndex
++)
524 /* Get the Driver's Name */
525 ValueSize
= sizeof(ServiceName
);
526 rc
= RegEnumKey(hServiceKey
, Index
, ServiceName
, &ValueSize
);
527 //DPRINTM(DPRINT_REACTOS, "RegEnumKey(): rc %d\n", (int)rc);
529 /* Makre sure it's valid, and check if we're done */
530 if (rc
== ERROR_NO_MORE_ITEMS
)
532 if (rc
!= ERROR_SUCCESS
)
534 MmHeapFree(GroupNameBuffer
);
537 //DPRINTM(DPRINT_REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName);
539 /* open driver Key */
540 rc
= RegOpenKey(hServiceKey
, ServiceName
, &hDriverKey
);
541 if (rc
== ERROR_SUCCESS
)
543 /* Read the Start Value */
544 ValueSize
= sizeof(ULONG
);
545 rc
= RegQueryValue(hDriverKey
, L
"Start", &ValueType
, (PUCHAR
)&StartValue
, &ValueSize
);
546 if (rc
!= ERROR_SUCCESS
) StartValue
= (ULONG
)-1;
547 //DPRINTM(DPRINT_REACTOS, " Start: %x \n", (int)StartValue);
550 ValueSize
= sizeof(ULONG
);
551 rc
= RegQueryValue(hDriverKey
, L
"Tag", &ValueType
, (PUCHAR
)&TagValue
, &ValueSize
);
552 if (rc
!= ERROR_SUCCESS
) TagValue
= (ULONG
)-1;
553 //DPRINTM(DPRINT_REACTOS, " Tag: %x \n", (int)TagValue);
555 /* Read the driver's group */
556 DriverGroupSize
= sizeof(DriverGroup
);
557 rc
= RegQueryValue(hDriverKey
, L
"Group", NULL
, (PUCHAR
)DriverGroup
, &DriverGroupSize
);
558 //DPRINTM(DPRINT_REACTOS, " Group: '%S' \n", DriverGroup);
560 /* Make sure it should be started */
561 if ((StartValue
== 0) &&
562 (TagValue
== OrderList
[TagIndex
]) &&
563 (_wcsicmp(DriverGroup
, GroupName
) == 0)) {
565 /* Get the Driver's Location */
566 ValueSize
= sizeof(TempImagePath
);
567 rc
= RegQueryValue(hDriverKey
, L
"ImagePath", NULL
, (PUCHAR
)TempImagePath
, &ValueSize
);
569 /* Write the whole path if it suceeded, else prepare to fail */
570 if (rc
!= ERROR_SUCCESS
) {
571 DPRINTM(DPRINT_REACTOS
, " ImagePath: not found\n");
572 TempImagePath
[0] = 0;
573 sprintf(ImagePath
, "%s\\system32\\drivers\\%S.sys", DirectoryPath
, ServiceName
);
574 } else if (TempImagePath
[0] != L
'\\') {
575 sprintf(ImagePath
, "%s%S", DirectoryPath
, TempImagePath
);
577 sprintf(ImagePath
, "%S", TempImagePath
);
578 DPRINTM(DPRINT_REACTOS
, " ImagePath: '%s'\n", ImagePath
);
581 DPRINTM(DPRINT_WINDOWS
, " Adding boot driver: '%s'\n", ImagePath
);
583 Status
= WinLdrAddDriverToList(&LoaderBlock
->BootDriverListHead
,
584 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
589 DPRINTM(DPRINT_WINDOWS
, " Failed to add boot driver\n");
592 //DPRINTM(DPRINT_WINDOWS, " Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current Tag %d, current group '%S')\n",
593 // ServiceName, StartValue, TagValue, DriverGroup, OrderList[TagIndex], GroupName);
604 /* Get the Driver's Name */
605 ValueSize
= sizeof(ServiceName
);
606 rc
= RegEnumKey(hServiceKey
, Index
, ServiceName
, &ValueSize
);
608 //DPRINTM(DPRINT_REACTOS, "RegEnumKey(): rc %d\n", (int)rc);
609 if (rc
== ERROR_NO_MORE_ITEMS
)
611 if (rc
!= ERROR_SUCCESS
)
613 MmHeapFree(GroupNameBuffer
);
616 //DPRINTM(DPRINT_REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName);
618 /* open driver Key */
619 rc
= RegOpenKey(hServiceKey
, ServiceName
, &hDriverKey
);
620 if (rc
== ERROR_SUCCESS
)
622 /* Read the Start Value */
623 ValueSize
= sizeof(ULONG
);
624 rc
= RegQueryValue(hDriverKey
, L
"Start", &ValueType
, (PUCHAR
)&StartValue
, &ValueSize
);
625 if (rc
!= ERROR_SUCCESS
) StartValue
= (ULONG
)-1;
626 //DPRINTM(DPRINT_REACTOS, " Start: %x \n", (int)StartValue);
629 ValueSize
= sizeof(ULONG
);
630 rc
= RegQueryValue(hDriverKey
, L
"Tag", &ValueType
, (PUCHAR
)&TagValue
, &ValueSize
);
631 if (rc
!= ERROR_SUCCESS
) TagValue
= (ULONG
)-1;
632 //DPRINTM(DPRINT_REACTOS, " Tag: %x \n", (int)TagValue);
634 /* Read the driver's group */
635 DriverGroupSize
= sizeof(DriverGroup
);
636 rc
= RegQueryValue(hDriverKey
, L
"Group", NULL
, (PUCHAR
)DriverGroup
, &DriverGroupSize
);
637 //DPRINTM(DPRINT_REACTOS, " Group: '%S' \n", DriverGroup);
639 for (TagIndex
= 1; TagIndex
<= OrderList
[0]; TagIndex
++) {
640 if (TagValue
== OrderList
[TagIndex
]) break;
643 if ((StartValue
== 0) &&
644 (TagIndex
> OrderList
[0]) &&
645 (_wcsicmp(DriverGroup
, GroupName
) == 0)) {
647 ValueSize
= sizeof(TempImagePath
);
648 rc
= RegQueryValue(hDriverKey
, L
"ImagePath", NULL
, (PUCHAR
)TempImagePath
, &ValueSize
);
649 if (rc
!= ERROR_SUCCESS
) {
650 DPRINTM(DPRINT_REACTOS
, " ImagePath: not found\n");
651 TempImagePath
[0] = 0;
652 sprintf(ImagePath
, "%ssystem32\\drivers\\%S.sys", DirectoryPath
, ServiceName
);
653 } else if (TempImagePath
[0] != L
'\\') {
654 sprintf(ImagePath
, "%s%S", DirectoryPath
, TempImagePath
);
656 sprintf(ImagePath
, "%S", TempImagePath
);
657 DPRINTM(DPRINT_REACTOS
, " ImagePath: '%s'\n", ImagePath
);
659 DPRINTM(DPRINT_WINDOWS
, " Adding boot driver: '%s'\n", ImagePath
);
661 Status
= WinLdrAddDriverToList(&LoaderBlock
->BootDriverListHead
,
662 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
667 DPRINTM(DPRINT_WINDOWS
, " Failed to add boot driver\n");
670 //DPRINTM(DPRINT_WINDOWS, " Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current group '%S')\n",
671 // ServiceName, StartValue, TagValue, DriverGroup, GroupName);
678 /* Move to the next group name */
679 GroupName
= GroupName
+ wcslen(GroupName
) + 1;
682 /* Free allocated memory */
683 MmHeapFree(GroupNameBuffer
);
687 WinLdrAddDriverToList(LIST_ENTRY
*BootDriverListHead
,
692 PBOOT_DRIVER_LIST_ENTRY BootDriverEntry
;
696 BootDriverEntry
= MmHeapAlloc(sizeof(BOOT_DRIVER_LIST_ENTRY
));
698 if (!BootDriverEntry
)
701 // DTE will be filled during actual load of the driver
702 BootDriverEntry
->LdrEntry
= NULL
;
704 // Check - if we have a valid ImagePath, if not - we need to build it
705 // like "System32\\Drivers\\blah.sys"
706 if (ImagePath
&& (wcslen(ImagePath
) > 0))
708 // Just copy ImagePath to the corresponding field in the structure
709 PathLength
= wcslen(ImagePath
) * sizeof(WCHAR
);
711 BootDriverEntry
->FilePath
.Length
= 0;
712 BootDriverEntry
->FilePath
.MaximumLength
= PathLength
+ sizeof(WCHAR
);
713 BootDriverEntry
->FilePath
.Buffer
= MmHeapAlloc(PathLength
);
715 if (!BootDriverEntry
->FilePath
.Buffer
)
717 MmHeapFree(BootDriverEntry
);
721 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->FilePath
, ImagePath
);
722 if (!NT_SUCCESS(Status
))
724 MmHeapFree(BootDriverEntry
->FilePath
.Buffer
);
725 MmHeapFree(BootDriverEntry
);
731 // we have to construct ImagePath ourselves
732 PathLength
= wcslen(ServiceName
)*sizeof(WCHAR
) + sizeof(L
"system32\\drivers\\.sys");
733 BootDriverEntry
->FilePath
.Length
= 0;
734 BootDriverEntry
->FilePath
.MaximumLength
= PathLength
+sizeof(WCHAR
);
735 BootDriverEntry
->FilePath
.Buffer
= MmHeapAlloc(PathLength
);
737 if (!BootDriverEntry
->FilePath
.Buffer
)
739 MmHeapFree(BootDriverEntry
);
743 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->FilePath
, L
"system32\\drivers\\");
744 if (!NT_SUCCESS(Status
))
746 MmHeapFree(BootDriverEntry
->FilePath
.Buffer
);
747 MmHeapFree(BootDriverEntry
);
751 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->FilePath
, ServiceName
);
752 if (!NT_SUCCESS(Status
))
754 MmHeapFree(BootDriverEntry
->FilePath
.Buffer
);
755 MmHeapFree(BootDriverEntry
);
759 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->FilePath
, L
".sys");
760 if (!NT_SUCCESS(Status
))
762 MmHeapFree(BootDriverEntry
->FilePath
.Buffer
);
763 MmHeapFree(BootDriverEntry
);
769 PathLength
= (wcslen(RegistryPath
)+wcslen(ServiceName
))*sizeof(WCHAR
);
770 BootDriverEntry
->RegistryPath
.Length
= 0;
771 BootDriverEntry
->RegistryPath
.MaximumLength
= PathLength
;//+sizeof(WCHAR);
772 BootDriverEntry
->RegistryPath
.Buffer
= MmHeapAlloc(PathLength
);
773 if (!BootDriverEntry
->RegistryPath
.Buffer
)
776 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->RegistryPath
, RegistryPath
);
777 if (!NT_SUCCESS(Status
))
780 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->RegistryPath
, ServiceName
);
781 if (!NT_SUCCESS(Status
))
784 // Insert entry at top of the list
785 InsertTailList(BootDriverListHead
, &BootDriverEntry
->Link
);