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 DBG_DEFAULT_CHANNEL(WINDOWS
);
16 // The only global var here, used to mark mem pages as NLS in WinLdrSetupMemoryLayout()
17 ULONG TotalNLSSize
= 0;
20 WinLdrGetNLSNames(LPSTR AnsiName
,
25 WinLdrScanRegistry(IN OUT PLIST_ENTRY BootDriverListHead
,
26 IN LPCSTR DirectoryPath
);
29 /* FUNCTIONS **************************************************************/
32 WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
33 IN LPCSTR DirectoryPath
,
37 CHAR FullHiveName
[256];
39 FILEINFORMATION FileInfo
;
41 ULONG_PTR HiveDataPhysical
;
42 PVOID HiveDataVirtual
;
46 /* Concatenate path and filename to get the full name */
47 strcpy(FullHiveName
, DirectoryPath
);
48 strcat(FullHiveName
, HiveName
);
49 //Print(L"Loading %s...\n", FullHiveName);
50 Status
= ArcOpen(FullHiveName
, OpenReadOnly
, &FileId
);
52 if (Status
!= ESUCCESS
)
54 UiMessageBox("Opening hive file failed!");
58 /* Get the file length */
59 Status
= ArcGetFileInformation(FileId
, &FileInfo
);
61 if (Status
!= ESUCCESS
)
64 UiMessageBox("Hive file has 0 size!");
67 HiveFileSize
= FileInfo
.EndingAddress
.LowPart
;
69 /* Round up the size to page boundary and alloc memory */
70 HiveDataPhysical
= (ULONG_PTR
)MmAllocateMemoryWithType(
71 MM_SIZE_TO_PAGES(HiveFileSize
+ MM_PAGE_SIZE
- 1) << MM_PAGE_SHIFT
,
74 if (HiveDataPhysical
== 0)
77 UiMessageBox("Unable to alloc memory for a hive!");
81 /* Convert address to virtual */
82 HiveDataVirtual
= PaToVa((PVOID
)HiveDataPhysical
);
84 /* Fill LoaderBlock's entries */
85 LoaderBlock
->RegistryLength
= HiveFileSize
;
86 LoaderBlock
->RegistryBase
= HiveDataVirtual
;
88 /* Finally read from file to the memory */
89 Status
= ArcRead(FileId
, (PVOID
)HiveDataPhysical
, HiveFileSize
, &BytesRead
);
90 if (Status
!= ESUCCESS
)
93 UiMessageBox("Unable to read from hive file!");
97 // Add boot filesystem driver to the list
98 FsService
= FsGetServiceName(FileId
);
101 TRACE(" Adding filesystem service %S\n", FsService
);
102 Status
= WinLdrAddDriverToList(&LoaderBlock
->BootDriverListHead
,
103 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
107 TRACE(" Failed to add filesystem service\n");
111 TRACE(" No required filesystem service\n");
118 BOOLEAN
WinLdrInitSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
119 IN LPCSTR DirectoryPath
)
121 CHAR SearchPath
[1024];
124 // There is a simple logic here: try to load usual hive (system), if it
125 // fails, then give system.alt a try, and finally try a system.sav
127 // FIXME: For now we only try system
128 strcpy(SearchPath
, DirectoryPath
);
129 strcat(SearchPath
, "SYSTEM32\\CONFIG\\");
130 Status
= WinLdrLoadSystemHive(LoaderBlock
, SearchPath
, "SYSTEM");
136 // Initialize in-memory registry
137 RegInitializeRegistry();
139 // Import what was loaded
140 Status
= RegImportBinaryHive((PCHAR
)VaToPa(LoaderBlock
->RegistryBase
), LoaderBlock
->RegistryLength
);
143 UiMessageBox("Importing binary hive failed!");
147 // Initialize the 'CurrentControlSet' link
148 if (RegInitCurrentControlSet(FALSE
) != ERROR_SUCCESS
)
150 UiMessageBox("Initializing CurrentControlSet link failed!");
157 BOOLEAN
WinLdrScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
158 IN LPCSTR DirectoryPath
)
160 CHAR SearchPath
[1024];
161 CHAR AnsiName
[256], OemName
[256], LangName
[256];
164 // Scan registry and prepare boot drivers list
165 WinLdrScanRegistry(&LoaderBlock
->BootDriverListHead
, DirectoryPath
);
167 // Get names of NLS files
168 Status
= WinLdrGetNLSNames(AnsiName
, OemName
, LangName
);
171 UiMessageBox("Getting NLS names from registry failed!");
175 TRACE("NLS data %s %s %s\n", AnsiName
, OemName
, LangName
);
178 strcpy(SearchPath
, DirectoryPath
);
179 strcat(SearchPath
, "SYSTEM32\\");
180 Status
= WinLdrLoadNLSData(LoaderBlock
, SearchPath
, AnsiName
, OemName
, LangName
);
181 TRACE("NLS data loaded with status %d\n", Status
);
183 /* TODO: Load OEM HAL font */
190 /* PRIVATE FUNCTIONS ******************************************************/
192 // Queries registry for those three file names
194 WinLdrGetNLSNames(LPSTR AnsiName
,
198 LONG rc
= ERROR_SUCCESS
;
200 WCHAR szIdBuffer
[80];
201 WCHAR NameBuffer
[80];
204 /* open the codepage key */
205 rc
= RegOpenKey(NULL
,
206 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage",
208 if (rc
!= ERROR_SUCCESS
)
210 //strcpy(szErrorOut, "Couldn't open CodePage registry key");
214 /* get ANSI codepage */
215 BufferSize
= sizeof(szIdBuffer
);
216 rc
= RegQueryValue(hKey
, L
"ACP", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
217 if (rc
!= ERROR_SUCCESS
)
219 //strcpy(szErrorOut, "Couldn't get ACP NLS setting");
223 BufferSize
= sizeof(NameBuffer
);
224 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)NameBuffer
, &BufferSize
);
225 if (rc
!= ERROR_SUCCESS
)
227 //strcpy(szErrorOut, "ACP NLS Setting exists, but isn't readable");
229 wcscpy(NameBuffer
, L
"c_1252.nls"); // HACK: ReactOS bug #6727
231 sprintf(AnsiName
, "%S", NameBuffer
);
233 /* get OEM codepage */
234 BufferSize
= sizeof(szIdBuffer
);
235 rc
= RegQueryValue(hKey
, L
"OEMCP", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
236 if (rc
!= ERROR_SUCCESS
)
238 //strcpy(szErrorOut, "Couldn't get OEMCP NLS setting");
242 BufferSize
= sizeof(NameBuffer
);
243 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)NameBuffer
, &BufferSize
);
244 if (rc
!= ERROR_SUCCESS
)
246 //strcpy(szErrorOut, "OEMCP NLS setting exists, but isn't readable");
248 wcscpy(NameBuffer
, L
"c_437.nls"); // HACK: ReactOS bug #6727
250 sprintf(OemName
, "%S", NameBuffer
);
252 /* open the language key */
253 rc
= RegOpenKey(NULL
,
254 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
256 if (rc
!= ERROR_SUCCESS
)
258 //strcpy(szErrorOut, "Couldn't open Language registry key");
262 /* get the Unicode case table */
263 BufferSize
= sizeof(szIdBuffer
);
264 rc
= RegQueryValue(hKey
, L
"Default", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
265 if (rc
!= ERROR_SUCCESS
)
267 //strcpy(szErrorOut, "Couldn't get Language Default setting");
271 BufferSize
= sizeof(NameBuffer
);
272 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)NameBuffer
, &BufferSize
);
273 if (rc
!= ERROR_SUCCESS
)
275 //strcpy(szErrorOut, "Language Default setting exists, but isn't readable");
278 sprintf(LangName
, "%S", NameBuffer
);
285 WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock
,
286 IN LPCSTR DirectoryPath
,
287 IN LPCSTR AnsiFileName
,
288 IN LPCSTR OemFileName
,
289 IN LPCSTR LanguageFileName
)
294 ULONG LanguageFileId
;
295 ULONG AnsiFileSize
, OemFileSize
, LanguageFileSize
;
297 ULONG_PTR NlsDataBase
;
299 BOOLEAN AnsiEqualsOem
= FALSE
;
300 FILEINFORMATION FileInfo
;
301 ULONG BytesRead
, Status
;
303 /* There may be a case, when OEM and ANSI page coincide */
304 if (!strcmp(AnsiFileName
, OemFileName
))
305 AnsiEqualsOem
= TRUE
;
307 /* Open file with ANSI and store its size */
308 //Print(L"Loading %s...\n", Filename);
309 strcpy(FileName
, DirectoryPath
);
310 strcat(FileName
, AnsiFileName
);
311 Status
= ArcOpen(FileName
, OpenReadOnly
, &AnsiFileId
);
313 if (Status
!= ESUCCESS
)
316 Status
= ArcGetFileInformation(AnsiFileId
, &FileInfo
);
317 if (Status
!= ESUCCESS
)
319 AnsiFileSize
= FileInfo
.EndingAddress
.LowPart
;
320 TRACE("AnsiFileSize: %d\n", AnsiFileSize
);
321 ArcClose(AnsiFileId
);
323 /* Open OEM file and store its length */
330 //Print(L"Loading %s...\n", Filename);
331 strcpy(FileName
, DirectoryPath
);
332 strcat(FileName
, OemFileName
);
333 Status
= ArcOpen(FileName
, OpenReadOnly
, &OemFileId
);
335 if (Status
!= ESUCCESS
)
338 Status
= ArcGetFileInformation(OemFileId
, &FileInfo
);
339 if (Status
!= ESUCCESS
)
341 OemFileSize
= FileInfo
.EndingAddress
.LowPart
;
344 TRACE("OemFileSize: %d\n", OemFileSize
);
346 /* And finally open the language codepage file and store its length */
347 //Print(L"Loading %s...\n", Filename);
348 strcpy(FileName
, DirectoryPath
);
349 strcat(FileName
, LanguageFileName
);
350 Status
= ArcOpen(FileName
, OpenReadOnly
, &LanguageFileId
);
352 if (Status
!= ESUCCESS
)
355 Status
= ArcGetFileInformation(LanguageFileId
, &FileInfo
);
356 if (Status
!= ESUCCESS
)
358 LanguageFileSize
= FileInfo
.EndingAddress
.LowPart
;
359 ArcClose(LanguageFileId
);
360 TRACE("LanguageFileSize: %d\n", LanguageFileSize
);
362 /* Sum up all three length, having in mind that every one of them
363 must start at a page boundary => thus round up each file to a page */
364 TotalSize
= MM_SIZE_TO_PAGES(AnsiFileSize
) +
365 MM_SIZE_TO_PAGES(OemFileSize
) +
366 MM_SIZE_TO_PAGES(LanguageFileSize
);
368 /* Store it for later marking the pages as NlsData type */
369 TotalNLSSize
= TotalSize
;
371 NlsDataBase
= (ULONG_PTR
)MmAllocateMemoryWithType(TotalSize
*MM_PAGE_SIZE
, LoaderNlsData
);
373 if (NlsDataBase
== 0)
376 NlsVirtual
= PaToVa((PVOID
)NlsDataBase
);
377 LoaderBlock
->NlsData
->AnsiCodePageData
= NlsVirtual
;
378 LoaderBlock
->NlsData
->OemCodePageData
= (PVOID
)((PUCHAR
)NlsVirtual
+
379 (MM_SIZE_TO_PAGES(AnsiFileSize
) << MM_PAGE_SHIFT
));
380 LoaderBlock
->NlsData
->UnicodeCodePageData
= (PVOID
)((PUCHAR
)NlsVirtual
+
381 (MM_SIZE_TO_PAGES(AnsiFileSize
) << MM_PAGE_SHIFT
) +
382 (MM_SIZE_TO_PAGES(OemFileSize
) << MM_PAGE_SHIFT
));
384 /* Ansi and OEM data are the same - just set pointers to the same area */
386 LoaderBlock
->NlsData
->OemCodePageData
= LoaderBlock
->NlsData
->AnsiCodePageData
;
389 /* Now actually read the data into memory, starting with Ansi file */
390 strcpy(FileName
, DirectoryPath
);
391 strcat(FileName
, AnsiFileName
);
392 Status
= ArcOpen(FileName
, OpenReadOnly
, &AnsiFileId
);
394 if (Status
!= ESUCCESS
)
397 Status
= ArcRead(AnsiFileId
, VaToPa(LoaderBlock
->NlsData
->AnsiCodePageData
), AnsiFileSize
, &BytesRead
);
399 if (Status
!= ESUCCESS
)
402 ArcClose(AnsiFileId
);
404 /* OEM now, if it doesn't equal Ansi of course */
407 strcpy(FileName
, DirectoryPath
);
408 strcat(FileName
, OemFileName
);
409 Status
= ArcOpen(FileName
, OpenReadOnly
, &OemFileId
);
411 if (Status
!= ESUCCESS
)
414 Status
= ArcRead(OemFileId
, VaToPa(LoaderBlock
->NlsData
->OemCodePageData
), OemFileSize
, &BytesRead
);
416 if (Status
!= ESUCCESS
)
422 /* finally the language file */
423 strcpy(FileName
, DirectoryPath
);
424 strcat(FileName
, LanguageFileName
);
425 Status
= ArcOpen(FileName
, OpenReadOnly
, &LanguageFileId
);
427 if (Status
!= ESUCCESS
)
430 Status
= ArcRead(LanguageFileId
, VaToPa(LoaderBlock
->NlsData
->UnicodeCodePageData
), LanguageFileSize
, &BytesRead
);
432 if (Status
!= ESUCCESS
)
435 ArcClose(LanguageFileId
);
438 // THIS IS HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK
439 // Should go to WinLdrLoadOemHalFont(), when it will be implemented
441 LoaderBlock
->OemFontFile
= VaToPa(LoaderBlock
->NlsData
->UnicodeCodePageData
);
443 /* Convert NlsTables address to VA */
444 LoaderBlock
->NlsData
= PaToVa(LoaderBlock
->NlsData
);
449 //UiMessageBox("Error reading NLS file %s\n", Filename);
450 UiMessageBox("Error reading NLS file!");
455 WinLdrScanRegistry(IN OUT PLIST_ENTRY BootDriverListHead
,
456 IN LPCSTR DirectoryPath
)
459 FRLDRHKEY hGroupKey
, hOrderKey
, hServiceKey
, hDriverKey
;
460 LPWSTR GroupNameBuffer
;
461 WCHAR ServiceName
[256];
462 ULONG OrderList
[128];
472 WCHAR DriverGroup
[256];
473 ULONG DriverGroupSize
;
476 WCHAR TempImagePath
[256];
480 /* get 'service group order' key */
481 rc
= RegOpenKey(NULL
,
482 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder",
484 if (rc
!= ERROR_SUCCESS
) {
486 TRACE_CH(REACTOS
, "Failed to open the 'ServiceGroupOrder' key (rc %d)\n", (int)rc
);
490 /* get 'group order list' key */
491 rc
= RegOpenKey(NULL
,
492 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\GroupOrderList",
494 if (rc
!= ERROR_SUCCESS
) {
496 TRACE_CH(REACTOS
, "Failed to open the 'GroupOrderList' key (rc %d)\n", (int)rc
);
500 /* enumerate drivers */
501 rc
= RegOpenKey(NULL
,
502 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services",
504 if (rc
!= ERROR_SUCCESS
) {
506 TRACE_CH(REACTOS
, "Failed to open the 'Services' key (rc %d)\n", (int)rc
);
510 /* Get the Name Group */
512 GroupNameBuffer
= MmHeapAlloc(BufferSize
);
513 rc
= RegQueryValue(hGroupKey
, L
"List", NULL
, (PUCHAR
)GroupNameBuffer
, &BufferSize
);
514 TRACE_CH(REACTOS
, "RegQueryValue(): rc %d\n", (int)rc
);
515 if (rc
!= ERROR_SUCCESS
)
517 TRACE_CH(REACTOS
, "BufferSize: %d \n", (int)BufferSize
);
518 TRACE_CH(REACTOS
, "GroupNameBuffer: '%S' \n", GroupNameBuffer
);
520 /* Loop through each group */
521 GroupName
= GroupNameBuffer
;
524 TRACE("Driver group: '%S'\n", GroupName
);
526 /* Query the Order */
527 BufferSize
= sizeof(OrderList
);
528 rc
= RegQueryValue(hOrderKey
, GroupName
, NULL
, (PUCHAR
)OrderList
, &BufferSize
);
529 if (rc
!= ERROR_SUCCESS
) OrderList
[0] = 0;
531 /* enumerate all drivers */
532 for (TagIndex
= 1; TagIndex
<= OrderList
[0]; TagIndex
++)
538 /* Get the Driver's Name */
539 ValueSize
= sizeof(ServiceName
);
540 rc
= RegEnumKey(hServiceKey
, Index
, ServiceName
, &ValueSize
);
541 //TRACE_CH(REACTOS, "RegEnumKey(): rc %d\n", (int)rc);
543 /* Makre sure it's valid, and check if we're done */
544 if (rc
== ERROR_NO_MORE_ITEMS
)
546 if (rc
!= ERROR_SUCCESS
)
548 MmHeapFree(GroupNameBuffer
);
551 //TRACE_CH(REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName);
553 /* open driver Key */
554 rc
= RegOpenKey(hServiceKey
, ServiceName
, &hDriverKey
);
555 if (rc
== ERROR_SUCCESS
)
557 /* Read the Start Value */
558 ValueSize
= sizeof(ULONG
);
559 rc
= RegQueryValue(hDriverKey
, L
"Start", &ValueType
, (PUCHAR
)&StartValue
, &ValueSize
);
560 if (rc
!= ERROR_SUCCESS
) StartValue
= (ULONG
)-1;
561 //TRACE_CH(REACTOS, " Start: %x \n", (int)StartValue);
564 ValueSize
= sizeof(ULONG
);
565 rc
= RegQueryValue(hDriverKey
, L
"Tag", &ValueType
, (PUCHAR
)&TagValue
, &ValueSize
);
566 if (rc
!= ERROR_SUCCESS
) TagValue
= (ULONG
)-1;
567 //TRACE_CH(REACTOS, " Tag: %x \n", (int)TagValue);
569 /* Read the driver's group */
570 DriverGroupSize
= sizeof(DriverGroup
);
571 rc
= RegQueryValue(hDriverKey
, L
"Group", NULL
, (PUCHAR
)DriverGroup
, &DriverGroupSize
);
572 //TRACE_CH(REACTOS, " Group: '%S' \n", DriverGroup);
574 /* Make sure it should be started */
575 if ((StartValue
== 0) &&
576 (TagValue
== OrderList
[TagIndex
]) &&
577 (_wcsicmp(DriverGroup
, GroupName
) == 0)) {
579 /* Get the Driver's Location */
580 ValueSize
= sizeof(TempImagePath
);
581 rc
= RegQueryValue(hDriverKey
, L
"ImagePath", NULL
, (PUCHAR
)TempImagePath
, &ValueSize
);
583 /* Write the whole path if it suceeded, else prepare to fail */
584 if (rc
!= ERROR_SUCCESS
) {
585 TRACE_CH(REACTOS
, "ImagePath: not found\n");
586 TempImagePath
[0] = 0;
587 sprintf(ImagePath
, "%s\\system32\\drivers\\%S.sys", DirectoryPath
, ServiceName
);
588 } else if (TempImagePath
[0] != L
'\\') {
589 sprintf(ImagePath
, "%s%S", DirectoryPath
, TempImagePath
);
591 sprintf(ImagePath
, "%S", TempImagePath
);
592 TRACE_CH(REACTOS
, "ImagePath: '%s'\n", ImagePath
);
595 TRACE("Adding boot driver: '%s'\n", ImagePath
);
597 Status
= WinLdrAddDriverToList(BootDriverListHead
,
598 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
603 ERR("Failed to add boot driver\n");
606 //TRACE(" Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current Tag %d, current group '%S')\n",
607 // ServiceName, StartValue, TagValue, DriverGroup, OrderList[TagIndex], GroupName);
618 /* Get the Driver's Name */
619 ValueSize
= sizeof(ServiceName
);
620 rc
= RegEnumKey(hServiceKey
, Index
, ServiceName
, &ValueSize
);
622 //TRACE_CH(REACTOS, "RegEnumKey(): rc %d\n", (int)rc);
623 if (rc
== ERROR_NO_MORE_ITEMS
)
625 if (rc
!= ERROR_SUCCESS
)
627 MmHeapFree(GroupNameBuffer
);
630 //TRACE_CH(REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName);
632 /* open driver Key */
633 rc
= RegOpenKey(hServiceKey
, ServiceName
, &hDriverKey
);
634 if (rc
== ERROR_SUCCESS
)
636 /* Read the Start Value */
637 ValueSize
= sizeof(ULONG
);
638 rc
= RegQueryValue(hDriverKey
, L
"Start", &ValueType
, (PUCHAR
)&StartValue
, &ValueSize
);
639 if (rc
!= ERROR_SUCCESS
) StartValue
= (ULONG
)-1;
640 //TRACE_CH(REACTOS, " Start: %x \n", (int)StartValue);
643 ValueSize
= sizeof(ULONG
);
644 rc
= RegQueryValue(hDriverKey
, L
"Tag", &ValueType
, (PUCHAR
)&TagValue
, &ValueSize
);
645 if (rc
!= ERROR_SUCCESS
) TagValue
= (ULONG
)-1;
646 //TRACE_CH(REACTOS, " Tag: %x \n", (int)TagValue);
648 /* Read the driver's group */
649 DriverGroupSize
= sizeof(DriverGroup
);
650 rc
= RegQueryValue(hDriverKey
, L
"Group", NULL
, (PUCHAR
)DriverGroup
, &DriverGroupSize
);
651 //TRACE_CH(REACTOS, " Group: '%S' \n", DriverGroup);
653 for (TagIndex
= 1; TagIndex
<= OrderList
[0]; TagIndex
++) {
654 if (TagValue
== OrderList
[TagIndex
]) break;
657 if ((StartValue
== 0) &&
658 (TagIndex
> OrderList
[0]) &&
659 (_wcsicmp(DriverGroup
, GroupName
) == 0)) {
661 ValueSize
= sizeof(TempImagePath
);
662 rc
= RegQueryValue(hDriverKey
, L
"ImagePath", NULL
, (PUCHAR
)TempImagePath
, &ValueSize
);
663 if (rc
!= ERROR_SUCCESS
) {
664 TRACE_CH(REACTOS
, "ImagePath: not found\n");
665 TempImagePath
[0] = 0;
666 sprintf(ImagePath
, "%ssystem32\\drivers\\%S.sys", DirectoryPath
, ServiceName
);
667 } else if (TempImagePath
[0] != L
'\\') {
668 sprintf(ImagePath
, "%s%S", DirectoryPath
, TempImagePath
);
670 sprintf(ImagePath
, "%S", TempImagePath
);
671 TRACE_CH(REACTOS
, "ImagePath: '%s'\n", ImagePath
);
673 TRACE(" Adding boot driver: '%s'\n", ImagePath
);
675 Status
= WinLdrAddDriverToList(BootDriverListHead
,
676 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
681 ERR(" Failed to add boot driver\n");
684 //TRACE(" Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current group '%S')\n",
685 // ServiceName, StartValue, TagValue, DriverGroup, GroupName);
692 /* Move to the next group name */
693 GroupName
= GroupName
+ wcslen(GroupName
) + 1;
696 /* Free allocated memory */
697 MmHeapFree(GroupNameBuffer
);
701 WinLdrAddDriverToList(LIST_ENTRY
*BootDriverListHead
,
706 PBOOT_DRIVER_LIST_ENTRY BootDriverEntry
;
710 BootDriverEntry
= MmHeapAlloc(sizeof(BOOT_DRIVER_LIST_ENTRY
));
712 if (!BootDriverEntry
)
715 // DTE will be filled during actual load of the driver
716 BootDriverEntry
->LdrEntry
= NULL
;
718 // Check - if we have a valid ImagePath, if not - we need to build it
719 // like "System32\\Drivers\\blah.sys"
720 if (ImagePath
&& (wcslen(ImagePath
) > 0))
722 // Just copy ImagePath to the corresponding field in the structure
723 PathLength
= wcslen(ImagePath
) * sizeof(WCHAR
) + sizeof(UNICODE_NULL
);
725 BootDriverEntry
->FilePath
.Length
= 0;
726 BootDriverEntry
->FilePath
.MaximumLength
= PathLength
;
727 BootDriverEntry
->FilePath
.Buffer
= MmHeapAlloc(PathLength
);
729 if (!BootDriverEntry
->FilePath
.Buffer
)
731 MmHeapFree(BootDriverEntry
);
735 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->FilePath
, ImagePath
);
736 if (!NT_SUCCESS(Status
))
738 MmHeapFree(BootDriverEntry
->FilePath
.Buffer
);
739 MmHeapFree(BootDriverEntry
);
745 // we have to construct ImagePath ourselves
746 PathLength
= wcslen(ServiceName
)*sizeof(WCHAR
) + sizeof(L
"system32\\drivers\\.sys");
747 BootDriverEntry
->FilePath
.Length
= 0;
748 BootDriverEntry
->FilePath
.MaximumLength
= PathLength
;
749 BootDriverEntry
->FilePath
.Buffer
= MmHeapAlloc(PathLength
);
751 if (!BootDriverEntry
->FilePath
.Buffer
)
753 MmHeapFree(BootDriverEntry
);
757 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->FilePath
, L
"system32\\drivers\\");
758 if (!NT_SUCCESS(Status
))
760 MmHeapFree(BootDriverEntry
->FilePath
.Buffer
);
761 MmHeapFree(BootDriverEntry
);
765 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->FilePath
, ServiceName
);
766 if (!NT_SUCCESS(Status
))
768 MmHeapFree(BootDriverEntry
->FilePath
.Buffer
);
769 MmHeapFree(BootDriverEntry
);
773 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->FilePath
, L
".sys");
774 if (!NT_SUCCESS(Status
))
776 MmHeapFree(BootDriverEntry
->FilePath
.Buffer
);
777 MmHeapFree(BootDriverEntry
);
783 PathLength
= (wcslen(RegistryPath
) + wcslen(ServiceName
))*sizeof(WCHAR
) + sizeof(UNICODE_NULL
);
784 BootDriverEntry
->RegistryPath
.Length
= 0;
785 BootDriverEntry
->RegistryPath
.MaximumLength
= PathLength
;
786 BootDriverEntry
->RegistryPath
.Buffer
= MmHeapAlloc(PathLength
);
787 if (!BootDriverEntry
->RegistryPath
.Buffer
)
790 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->RegistryPath
, RegistryPath
);
791 if (!NT_SUCCESS(Status
))
794 Status
= RtlAppendUnicodeToString(&BootDriverEntry
->RegistryPath
, ServiceName
);
795 if (!NT_SUCCESS(Status
))
798 // Insert entry at top of the list
799 InsertTailList(BootDriverListHead
, &BootDriverEntry
->Link
);