ReactOS 0.4.15-dev-5893-g1bb4167
wlregistry.c
Go to the documentation of this file.
1/*
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)
7 */
8
9/* INCLUDES ***************************************************************/
10
11#include <freeldr.h>
12#include "winldr.h"
13#include "registry.h"
14#include <internal/cmboot.h>
15
16#include <debug.h>
18
19// The only global var here, used to mark mem pages as NLS in WinLdrSetupMemoryLayout()
21
22static BOOLEAN
24 _In_ HKEY ControlSet,
25 _Inout_ PUNICODE_STRING AnsiFileName,
26 _Inout_ PUNICODE_STRING OemFileName,
27 _Inout_ PUNICODE_STRING LangFileName, // CaseTable
28 _Inout_ PUNICODE_STRING OemHalFileName);
29
30static BOOLEAN
32 IN OUT PLIST_ENTRY BootDriverListHead);
33
34
35/* FUNCTIONS **************************************************************/
36
37static BOOLEAN
39 IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
40 IN PCSTR DirectoryPath,
41 IN PCSTR HiveName)
42{
43 ULONG FileId;
44 CHAR FullHiveName[MAX_PATH];
47 ULONG HiveFileSize;
48 PVOID HiveDataPhysical;
49 PVOID HiveDataVirtual;
51
52 /* Concatenate path and filename to get the full name */
53 RtlStringCbCopyA(FullHiveName, sizeof(FullHiveName), DirectoryPath);
54 RtlStringCbCatA(FullHiveName, sizeof(FullHiveName), HiveName);
55
56 NtLdrOutputLoadMsg(FullHiveName, NULL);
57 Status = ArcOpen(FullHiveName, OpenReadOnly, &FileId);
58 if (Status != ESUCCESS)
59 {
60 WARN("Error while opening '%s', Status: %u\n", FullHiveName, Status);
61 return FALSE;
62 }
63
64 /* Get the file length */
66 if (Status != ESUCCESS)
67 {
68 WARN("Hive file has 0 size!\n");
69 ArcClose(FileId);
70 return FALSE;
71 }
72 HiveFileSize = FileInfo.EndingAddress.LowPart;
73
74 /* Round up the size to page boundary and alloc memory */
75 HiveDataPhysical = MmAllocateMemoryWithType(
76 MM_SIZE_TO_PAGES(HiveFileSize + MM_PAGE_SIZE - 1) << MM_PAGE_SHIFT,
78
79 if (HiveDataPhysical == NULL)
80 {
81 WARN("Could not alloc memory for hive!\n");
82 ArcClose(FileId);
83 return FALSE;
84 }
85
86 /* Convert address to virtual */
87 HiveDataVirtual = PaToVa(HiveDataPhysical);
88
89 /* Fill LoaderBlock's entries */
90 LoaderBlock->RegistryLength = HiveFileSize;
91 LoaderBlock->RegistryBase = HiveDataVirtual;
92
93 /* Finally read from file to the memory */
94 Status = ArcRead(FileId, HiveDataPhysical, HiveFileSize, &BytesRead);
95 if (Status != ESUCCESS)
96 {
97 WARN("Error while reading '%s', Status: %u\n", FullHiveName, Status);
98 ArcClose(FileId);
99 return FALSE;
100 }
101
102 // FIXME: HACK: Get the boot filesystem driver name now...
104
105 ArcClose(FileId);
106 return TRUE;
107}
108
111 IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
114{
115 CHAR SearchPath[1024];
116 PCSTR HiveName;
118
119 if (Setup)
120 {
122 HiveName = "SETUPREG.HIV";
123 }
124 else
125 {
126 // There is a simple logic here: try to load usual hive (system), if it
127 // fails, then give system.alt a try, and finally try a system.sav
128
129 // FIXME: For now we only try system
131 RtlStringCbCatA(SearchPath, sizeof(SearchPath), "system32\\config\\");
132 HiveName = "SYSTEM";
133 }
134
135 TRACE("WinLdrInitSystemHive: loading hive %s%s\n", SearchPath, HiveName);
136 Success = WinLdrLoadSystemHive(LoaderBlock, SearchPath, HiveName);
137 if (!Success)
138 {
139 UiMessageBox("Could not load %s hive!", HiveName);
140 return FALSE;
141 }
142
143 /* Import what was loaded */
144 Success = RegImportBinaryHive(VaToPa(LoaderBlock->RegistryBase), LoaderBlock->RegistryLength);
145 if (!Success)
146 {
147 UiMessageBox("Importing binary hive failed!");
148 return FALSE;
149 }
150
151 /* Initialize the 'CurrentControlSet' link */
153 {
154 UiMessageBox("Initializing CurrentControlSet link failed!");
155 return FALSE;
156 }
157
158 return TRUE;
159}
160
163{
167 DECLARE_UNICODE_STRING_SIZE(LangFileName, MAX_PATH); // CaseTable
168 DECLARE_UNICODE_STRING_SIZE(OemHalFileName, MAX_PATH);
169 CHAR SearchPath[1024];
170
171 /* Scan registry and prepare boot drivers list */
172 Success = WinLdrScanRegistry(&LoaderBlock->BootDriverListHead);
173 if (!Success)
174 {
175 UiMessageBox("Failed to load boot drivers!");
176 return FALSE;
177 }
178
179 /* Get names of NLS files */
181 &AnsiFileName,
182 &OemFileName,
183 &LangFileName,
184 &OemHalFileName);
185 if (!Success)
186 {
187 UiMessageBox("Getting NLS names from registry failed!");
188 return FALSE;
189 }
190
191 TRACE("NLS data: '%wZ' '%wZ' '%wZ' '%wZ'\n",
192 &AnsiFileName, &OemFileName, &LangFileName, &OemHalFileName);
193
194 /* Load NLS data */
196 RtlStringCbCatA(SearchPath, sizeof(SearchPath), "system32\\");
197 Success = WinLdrLoadNLSData(LoaderBlock,
199 &AnsiFileName,
200 &OemFileName,
201 &LangFileName,
202 &OemHalFileName);
203 TRACE("NLS data loading %s\n", Success ? "successful" : "failed");
204
205 return TRUE;
206}
207
208
209/* PRIVATE FUNCTIONS ******************************************************/
210
211// Queries registry for those three file names
212static BOOLEAN
214 _In_ HKEY ControlSet,
215 _Inout_ PUNICODE_STRING AnsiFileName,
216 _Inout_ PUNICODE_STRING OemFileName,
217 _Inout_ PUNICODE_STRING LangFileName, // CaseTable
218 _Inout_ PUNICODE_STRING OemHalFileName)
219{
220 LONG rc;
221 HKEY hKey;
223 WCHAR szIdBuffer[80];
224
225 /* Open the CodePage key */
226 rc = RegOpenKey(ControlSet, L"Control\\NLS\\CodePage", &hKey);
227 if (rc != ERROR_SUCCESS)
228 {
229 //TRACE("Couldn't open CodePage registry key\n");
230 return FALSE;
231 }
232
233 /* Get ANSI codepage file */
234 BufferSize = sizeof(szIdBuffer);
235 rc = RegQueryValue(hKey, L"ACP", NULL, (PUCHAR)szIdBuffer, &BufferSize);
236 if (rc != ERROR_SUCCESS)
237 {
238 //TRACE("Couldn't get ACP NLS setting\n");
239 goto Quit;
240 }
241
242 BufferSize = AnsiFileName->MaximumLength;
243 rc = RegQueryValue(hKey, szIdBuffer, NULL,
244 (PUCHAR)AnsiFileName->Buffer, &BufferSize);
245 if (rc != ERROR_SUCCESS)
246 {
247 //TRACE("ACP NLS Setting exists, but isn't readable\n");
248 //goto Quit;
249 AnsiFileName->Length = 0;
250 RtlAppendUnicodeToString(AnsiFileName, L"c_1252.nls"); // HACK: ReactOS bug CORE-6105
251 }
252 else
253 {
254 AnsiFileName->Length = (USHORT)BufferSize - sizeof(UNICODE_NULL);
255 }
256
257 /* Get OEM codepage file */
258 BufferSize = sizeof(szIdBuffer);
259 rc = RegQueryValue(hKey, L"OEMCP", NULL, (PUCHAR)szIdBuffer, &BufferSize);
260 if (rc != ERROR_SUCCESS)
261 {
262 //TRACE("Couldn't get OEMCP NLS setting\n");
263 goto Quit;
264 }
265
266 BufferSize = OemFileName->MaximumLength;
267 rc = RegQueryValue(hKey, szIdBuffer, NULL,
268 (PUCHAR)OemFileName->Buffer, &BufferSize);
269 if (rc != ERROR_SUCCESS)
270 {
271 //TRACE("OEMCP NLS setting exists, but isn't readable\n");
272 //goto Quit;
273 OemFileName->Length = 0;
274 RtlAppendUnicodeToString(OemFileName, L"c_437.nls"); // HACK: ReactOS bug CORE-6105
275 }
276 else
277 {
278 OemFileName->Length = (USHORT)BufferSize - sizeof(UNICODE_NULL);
279 }
280
281 /* Get OEM HAL font file */
282 BufferSize = OemHalFileName->MaximumLength;
283 rc = RegQueryValue(hKey, L"OEMHAL", NULL,
284 (PUCHAR)OemHalFileName->Buffer, &BufferSize);
285 if (rc != ERROR_SUCCESS)
286 {
287 //TRACE("Couldn't get OEMHAL NLS setting\n");
288 //goto Quit;
289 RtlInitEmptyUnicodeString(OemHalFileName, NULL, 0);
290 }
291 else
292 {
293 OemHalFileName->Length = (USHORT)BufferSize - sizeof(UNICODE_NULL);
294 }
295
297
298 /* Open the Language key */
299 rc = RegOpenKey(ControlSet, L"Control\\NLS\\Language", &hKey);
300 if (rc != ERROR_SUCCESS)
301 {
302 //TRACE("Couldn't open Language registry key\n");
303 return FALSE;
304 }
305
306 /* Get the Unicode case table file */
307 BufferSize = sizeof(szIdBuffer);
308 rc = RegQueryValue(hKey, L"Default", NULL, (PUCHAR)szIdBuffer, &BufferSize);
309 if (rc != ERROR_SUCCESS)
310 {
311 //TRACE("Couldn't get Language Default setting\n");
312 goto Quit;
313 }
314
315 BufferSize = LangFileName->MaximumLength;
316 rc = RegQueryValue(hKey, szIdBuffer, NULL,
317 (PUCHAR)LangFileName->Buffer, &BufferSize);
318 if (rc != ERROR_SUCCESS)
319 {
320 //TRACE("Language Default setting exists, but isn't readable\n");
321 //goto Quit;
322 LangFileName->Length = 0;
323 RtlAppendUnicodeToString(LangFileName, L"l_intl.nls");
324 }
325 else
326 {
327 LangFileName->Length = (USHORT)BufferSize - sizeof(UNICODE_NULL);
328 }
329
330Quit:
332 return (rc == ERROR_SUCCESS);
333}
334
338 _In_ PCSTR DirectoryPath,
339 _In_ PCUNICODE_STRING AnsiFileName,
340 _In_ PCUNICODE_STRING OemFileName,
341 _In_ PCUNICODE_STRING LangFileName, // CaseTable
342 _In_ PCUNICODE_STRING OemHalFileName)
343{
346 ULONG AnsiFileId = -1, OemFileId = -1, LangFileId = -1;
347 ULONG AnsiFileSize, OemFileSize, LangFileSize;
348 ULONG TotalSize;
350 PVOID NlsDataBase, NlsVirtual;
351 BOOLEAN AnsiEqualsOem = FALSE;
353
354 /* There may be a case, where OEM and ANSI pages coincide */
355 if (RtlCompareUnicodeString(AnsiFileName, OemFileName, TRUE) == 0)
356 AnsiEqualsOem = TRUE;
357
358 /* Open file with ANSI and store its size */
359 RtlStringCbPrintfA(FileName, sizeof(FileName), "%s%wZ",
360 DirectoryPath, AnsiFileName);
361 Status = ArcOpen(FileName, OpenReadOnly, &AnsiFileId);
362 if (Status != ESUCCESS)
363 {
364 WARN("Error while opening '%s', Status: %u\n", FileName, Status);
365 goto Quit;
366 }
367
368 Status = ArcGetFileInformation(AnsiFileId, &FileInfo);
369 if (Status != ESUCCESS)
370 goto Quit;
371 AnsiFileSize = FileInfo.EndingAddress.LowPart;
372 TRACE("AnsiFileSize: %d\n", AnsiFileSize);
373
374 /* Open OEM file and store its length */
375 if (AnsiEqualsOem)
376 {
377 OemFileSize = 0;
378 }
379 else
380 {
381 RtlStringCbPrintfA(FileName, sizeof(FileName), "%s%wZ",
382 DirectoryPath, OemFileName);
383 Status = ArcOpen(FileName, OpenReadOnly, &OemFileId);
384 if (Status != ESUCCESS)
385 {
386 WARN("Error while opening '%s', Status: %u\n", FileName, Status);
387 goto Quit;
388 }
389
391 if (Status != ESUCCESS)
392 goto Quit;
393 OemFileSize = FileInfo.EndingAddress.LowPart;
394 }
395 TRACE("OemFileSize: %d\n", OemFileSize);
396
397 /* Finally open the language codepage file and store its length */
398 RtlStringCbPrintfA(FileName, sizeof(FileName), "%s%wZ",
399 DirectoryPath, LangFileName);
400 Status = ArcOpen(FileName, OpenReadOnly, &LangFileId);
401 if (Status != ESUCCESS)
402 {
403 WARN("Error while opening '%s', Status: %u\n", FileName, Status);
404 goto Quit;
405 }
406
407 Status = ArcGetFileInformation(LangFileId, &FileInfo);
408 if (Status != ESUCCESS)
409 goto Quit;
410 LangFileSize = FileInfo.EndingAddress.LowPart;
411 TRACE("LangFileSize: %d\n", LangFileSize);
412
413 //
414 // TODO: The OEMHAL file.
415 //
416
417 /* Sum up all three length, having in mind that every one of them
418 must start at a page boundary => thus round up each file to a page */
419 TotalSize = MM_SIZE_TO_PAGES(AnsiFileSize) +
420 MM_SIZE_TO_PAGES(OemFileSize) +
421 MM_SIZE_TO_PAGES(LangFileSize);
422
423 /* Store it for later marking the pages as NlsData type */
424 TotalNLSSize = TotalSize;
425
426 NlsDataBase = MmAllocateMemoryWithType(TotalSize*MM_PAGE_SIZE, LoaderNlsData);
427 if (NlsDataBase == NULL)
428 goto Quit;
429
430 NlsVirtual = PaToVa(NlsDataBase);
431 LoaderBlock->NlsData->AnsiCodePageData = NlsVirtual;
432
433 LoaderBlock->NlsData->OemCodePageData =
434 (PVOID)((ULONG_PTR)NlsVirtual +
435 (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT));
436
437 LoaderBlock->NlsData->UnicodeCodePageData =
438 (PVOID)((ULONG_PTR)NlsVirtual +
439 (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT) +
440 (MM_SIZE_TO_PAGES(OemFileSize) << MM_PAGE_SHIFT));
441
442 /* ANSI and OEM data are the same - just set pointers to the same area */
443 if (AnsiEqualsOem)
444 LoaderBlock->NlsData->OemCodePageData = LoaderBlock->NlsData->AnsiCodePageData;
445
446 /* Now actually read the data into memory, starting with the ANSI file */
447 RtlStringCbPrintfA(FileName, sizeof(FileName), "%s%wZ",
448 DirectoryPath, AnsiFileName);
450 Status = ArcRead(AnsiFileId,
451 VaToPa(LoaderBlock->NlsData->AnsiCodePageData),
452 AnsiFileSize, &BytesRead);
453 if (Status != ESUCCESS)
454 {
455 WARN("Error while reading '%s', Status: %u\n", FileName, Status);
456 goto Quit;
457 }
458
459 /* OEM now, if it isn't the same as the ANSI one */
460 if (!AnsiEqualsOem)
461 {
462 RtlStringCbPrintfA(FileName, sizeof(FileName), "%s%wZ",
463 DirectoryPath, OemFileName);
465 Status = ArcRead(OemFileId,
466 VaToPa(LoaderBlock->NlsData->OemCodePageData),
467 OemFileSize, &BytesRead);
468 if (Status != ESUCCESS)
469 {
470 WARN("Error while reading '%s', Status: %u\n", FileName, Status);
471 goto Quit;
472 }
473 }
474
475 /* Finally the language file */
476 RtlStringCbPrintfA(FileName, sizeof(FileName), "%s%wZ",
477 DirectoryPath, LangFileName);
479 Status = ArcRead(LangFileId,
480 VaToPa(LoaderBlock->NlsData->UnicodeCodePageData),
481 LangFileSize, &BytesRead);
482 if (Status != ESUCCESS)
483 {
484 WARN("Error while reading '%s', Status: %u\n", FileName, Status);
485 goto Quit;
486 }
487
488 //
489 // THIS IS a HACK and should be replaced by actually loading the OEMHAL file!
490 //
491 LoaderBlock->OemFontFile = VaToPa(LoaderBlock->NlsData->UnicodeCodePageData);
492
493 /* Convert NlsTables address to VA */
494 LoaderBlock->NlsData = PaToVa(LoaderBlock->NlsData);
495
496Quit:
497 if (LangFileId != -1)
498 ArcClose(LangFileId);
499 if (OemFileId != -1)
500 ArcClose(OemFileId);
501 if (AnsiFileId != -1)
502 ArcClose(AnsiFileId);
503
504 if (Status != ESUCCESS)
505 UiMessageBox("Error reading NLS file %s", FileName);
506
507 return (Status == ESUCCESS);
508}
509
510static BOOLEAN
512 IN OUT PLIST_ENTRY BootDriverListHead)
513{
515
516 /* Find all boot drivers */
519 BootLoad,
521 BootDriverListHead);
522 if (!Success)
523 goto Quit;
524
525 /* Sort by group/tag */
528 BootDriverListHead);
529 if (!Success)
530 goto Quit;
531
532 /* Remove circular dependencies (cycles) and sort */
533 Success = CmpResolveDriverDependencies(BootDriverListHead);
534 if (!Success)
535 goto Quit;
536
537Quit:
538 /* In case of failure, free the boot driver list */
539 if (!Success)
540 CmpFreeDriverList(SystemHive, BootDriverListHead);
541
542 return Success;
543}
544
576 _Inout_ PLIST_ENTRY DriverListHead,
577 _In_ BOOLEAN InsertAtHead,
578 _In_ PCWSTR DriverName,
579 _In_opt_ PCWSTR ImagePath,
580 _In_opt_ PCWSTR GroupName,
581 _In_ ULONG ErrorControl,
582 _In_ ULONG Tag)
583{
584 PBOOT_DRIVER_NODE DriverNode;
586 BOOLEAN AlreadyInserted;
588 UNICODE_STRING DriverNameU;
591 UNICODE_STRING RegistryString = {0};
592 UNICODE_STRING GroupString = {0};
593
594 /* Check whether the driver is already in the list */
595 RtlInitUnicodeString(&DriverNameU, DriverName);
596 AlreadyInserted = CmpIsDriverInList(DriverListHead,
597 &DriverNameU,
598 &DriverNode);
599 if (AlreadyInserted)
600 {
601 /* If so, we have obtained its node */
602 ASSERT(DriverNode);
603 DriverEntry = &DriverNode->ListEntry;
604 }
605 else
606 {
607 /* Allocate a driver node and initialize it */
608 DriverNode = CmpAllocate(sizeof(BOOT_DRIVER_NODE), FALSE, TAG_CM);
609 if (!DriverNode)
610 return FALSE;
611
612 RtlZeroMemory(DriverNode, sizeof(BOOT_DRIVER_NODE));
613 DriverEntry = &DriverNode->ListEntry;
614
615 /* Driver Name */
616 RtlInitEmptyUnicodeString(&DriverNode->Name,
617 CmpAllocate(DriverNameU.Length, FALSE, TAG_CM),
618 DriverNameU.Length);
619 if (!DriverNode->Name.Buffer)
620 goto Failure;
621
622 if (!NT_SUCCESS(RtlAppendUnicodeStringToString(&DriverNode->Name, &DriverNameU)))
623 goto Failure;
624 }
625
626 /* Check whether we have a valid ImagePath. If not, we need
627 * to build it like "System32\\Drivers\\blah.sys" */
628 if (ImagePath && *ImagePath)
629 {
630 /* Just copy ImagePath to the corresponding field in the structure */
631 PathLength = (USHORT)(wcslen(ImagePath)) * sizeof(WCHAR);
632 RtlInitEmptyUnicodeString(&FilePath,
634 PathLength);
635 if (!FilePath.Buffer)
636 goto Failure;
637
639 goto Failure;
640 }
641 else
642 {
643 /* We have to construct ImagePath ourselves */
644 PathLength = DriverNode->Name.Length + sizeof(L"system32\\drivers\\.sys");
645 RtlInitEmptyUnicodeString(&FilePath,
647 PathLength);
648 if (!FilePath.Buffer)
649 goto Failure;
650
651 if (!NT_SUCCESS(RtlAppendUnicodeToString(&FilePath, L"system32\\drivers\\")) ||
654 {
655 goto Failure;
656 }
657 }
658
659 /* Registry path */
661 L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
662 PathLength = RegistryPath.Length + DriverNode->Name.Length;
663 RtlInitEmptyUnicodeString(&RegistryString,
665 PathLength);
666 if (!RegistryString.Buffer)
667 goto Failure;
668
669 if (!NT_SUCCESS(RtlAppendUnicodeStringToString(&RegistryString, &RegistryPath)) ||
670 !NT_SUCCESS(RtlAppendUnicodeStringToString(&RegistryString, &DriverNode->Name)))
671 {
672 goto Failure;
673 }
674
675 /* Group */
676 if (GroupName && *GroupName)
677 {
678 /*
679 * NOTE: Here we can use our own allocator as we alone maintain the
680 * group string. This is different from the other allocated strings,
681 * where we instead need to use the same (hive) allocator as the
682 * one used by CmpAddDriverToList(), for interoperability purposes.
683 */
684 RtlCreateUnicodeString(&GroupString, GroupName);
685 if (!GroupString.Buffer)
686 goto Failure;
687 }
688 else
689 {
690 RtlInitEmptyUnicodeString(&GroupString, NULL, 0);
691 }
692
693 /* Set or replace the driver node's file path */
694 if (DriverEntry->FilePath.Buffer)
695 {
696 CmpFree(DriverEntry->FilePath.Buffer,
697 DriverEntry->FilePath.MaximumLength);
698 }
699 DriverEntry->FilePath = FilePath;
700 FilePath.Buffer = NULL;
701
702 /* Set or replace the driver node's registry path */
703 if (DriverEntry->RegistryPath.Buffer)
704 {
705 CmpFree(DriverEntry->RegistryPath.Buffer,
706 DriverEntry->RegistryPath.MaximumLength);
707 }
708 DriverEntry->RegistryPath = RegistryString;
709 RegistryString.Buffer = NULL;
710
711 /* Set or replace the driver node's group */
712 if (DriverNode->Group.Buffer)
713 {
714 /*
715 * If the buffer is inside the registry hive's memory, this means that
716 * it has been set by CmpAddDriverToList() to point to some data within
717 * the hive; thus we should not free the buffer but just replace it.
718 * Otherwise, this is a buffer previously allocated by ourselves, that
719 * we can free.
720 *
721 * NOTE: This function does not have an explicit LoaderBlock input
722 * parameter pointer, since it does not need it, except for this
723 * very place. So instead, use the global WinLdrSystemBlock pointer.
724 */
725 PLOADER_PARAMETER_BLOCK LoaderBlock =
727
728 if (!LoaderBlock || !LoaderBlock->RegistryBase || !LoaderBlock->RegistryLength ||
729 ((ULONG_PTR)DriverNode->Group.Buffer <
730 (ULONG_PTR)VaToPa(LoaderBlock->RegistryBase)) ||
731 ((ULONG_PTR)DriverNode->Group.Buffer >=
732 (ULONG_PTR)VaToPa(LoaderBlock->RegistryBase) + LoaderBlock->RegistryLength))
733 {
734 RtlFreeUnicodeString(&DriverNode->Group);
735 }
736 }
737 DriverNode->Group = GroupString;
738 GroupString.Buffer = NULL;
739
740 /* ErrorControl and Tag */
741 DriverNode->ErrorControl = ErrorControl;
742 DriverNode->Tag = Tag;
743
744 /* Insert the entry into the list if it does not exist there already */
745 if (!AlreadyInserted)
746 {
747 if (InsertAtHead)
748 InsertHeadList(DriverListHead, &DriverEntry->Link);
749 else
750 InsertTailList(DriverListHead, &DriverEntry->Link);
751 }
752
753 return TRUE;
754
755Failure:
756 if (GroupString.Buffer)
757 RtlFreeUnicodeString(&GroupString);
758 if (RegistryString.Buffer)
759 CmpFree(RegistryString.Buffer, RegistryString.MaximumLength);
760 if (FilePath.Buffer)
761 CmpFree(FilePath.Buffer, FilePath.MaximumLength);
762
763 /* If it does not exist in the list already, free the allocated
764 * driver node, otherwise keep the original one in place. */
765 if (!AlreadyInserted)
766 {
767 if (DriverEntry->RegistryPath.Buffer)
768 {
769 CmpFree(DriverEntry->RegistryPath.Buffer,
770 DriverEntry->RegistryPath.MaximumLength);
771 }
772 if (DriverEntry->FilePath.Buffer)
773 {
774 CmpFree(DriverEntry->FilePath.Buffer,
775 DriverEntry->FilePath.MaximumLength);
776 }
777 if (DriverNode->Name.Buffer)
778 {
779 CmpFree(DriverNode->Name.Buffer,
780 DriverNode->Name.MaximumLength);
781 }
782 CmpFree(DriverNode, sizeof(BOOT_DRIVER_NODE));
783 }
784
785 return FALSE;
786}
static USHORT PathLength
PCWSTR FilePath
unsigned char BOOLEAN
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE ACPI_HANDLE ACPI_HANDLE *OutHandle ACPI_HANDLE *OutHandle void *Context void *Context ACPI_EVENT_HANDLER Handler UINT32 UINT32 ACPI_GPE_HANDLER void *Context UINT32 ACPI_NOTIFY_HANDLER void *Context ACPI_ADR_SPACE_TYPE ACPI_ADR_SPACE_HANDLER ACPI_ADR_SPACE_SETUP Setup
Definition: acpixf.h:834
#define WARN(fmt,...)
Definition: debug.h:112
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:103
ARC_STATUS ArcClose(ULONG FileId)
Definition: fs.c:220
ARC_STATUS ArcGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
Definition: fs.c:252
ARC_STATUS ArcOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
Definition: fs.c:56
PCWSTR FsGetServiceName(ULONG FileId)
Definition: fs.c:404
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: fs.c:238
PVOID MmAllocateMemoryWithType(SIZE_T MemorySize, TYPE_OF_MEMORY MemoryType)
Definition: mm.c:31
BOOLEAN RegInitCurrentControlSet(_In_ BOOLEAN LastKnownGood)
Definition: registry.c:112
PHHIVE SystemHive
Definition: registry.c:32
HKEY CurrentControlSetKey
Definition: registry.c:33
BOOLEAN RegImportBinaryHive(_In_ PVOID ChunkBase, _In_ ULONG ChunkSize)
Definition: registry.c:66
#define HKEY_TO_HCI(hKey)
Definition: registry.h:28
#define RegCloseKey(hKey)
Definition: registry.h:47
PVOID NTAPI CmpAllocate(_In_ SIZE_T Size, _In_ BOOLEAN Paged, _In_ ULONG Tag)
Definition: bootreg.c:90
VOID NTAPI CmpFree(_In_ PVOID Ptr, _In_ ULONG Quota)
Definition: bootreg.c:105
BOOLEAN NTAPI CmpFindDrivers(_In_ PHHIVE Hive, _In_ HCELL_INDEX ControlSet, _In_ SERVICE_LOAD_TYPE LoadType, _In_opt_ PCWSTR BootFileSystem, _Inout_ PLIST_ENTRY DriverListHead)
Enumerates all drivers within the given control set and load type, present in the "Services" sub-key,...
Definition: cmboot.c:679
BOOLEAN NTAPI CmpResolveDriverDependencies(_Inout_ PLIST_ENTRY DriverListHead)
Removes potential circular dependencies (cycles) and sorts the driver list.
Definition: cmboot.c:1030
BOOLEAN NTAPI CmpSortDriverList(_In_ PHHIVE Hive, _In_ HCELL_INDEX ControlSet, _Inout_ PLIST_ENTRY DriverListHead)
Sorts the driver list, according to the drivers' group load ordering.
Definition: cmboot.c:902
VOID NTAPI CmpFreeDriverList(_In_ PHHIVE Hive, _Inout_ PLIST_ENTRY DriverListHead)
Empties the driver list and frees all allocated driver nodes in it.
Definition: cmboot.c:1224
#define TAG_CM
Definition: cmlib.h:205
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
FORCEINLINE PVOID VaToPa(PVOID Va)
Definition: conversion.h:15
FORCEINLINE PVOID PaToVa(PVOID Pa)
Definition: conversion.h:22
#define BufferSize
Definition: mmc.h:75
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const WCHAR SystemRoot[]
Definition: reg.c:38
#define MAX_PATH
Definition: compat.h:34
DRIVER_INITIALIZE DriverEntry
Definition: condrv.c:21
#define ULONG_PTR
Definition: config.h:101
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
@ Success
Definition: eventcreate.c:712
FxAutoRegKey hKey
Status
Definition: gdiplustypes.h:25
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define TAG_WLDR_NAME
Definition: winldr.h:15
#define ASSERT(a)
Definition: mode.c:44
#define _Inout_
Definition: ms_sal.h:378
#define _In_
Definition: ms_sal.h:308
#define _In_opt_
Definition: ms_sal.h:309
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define UNICODE_NULL
NTSTRSAFEAPI RtlStringCbCatA(_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:625
NTSTRSAFEVAPI RtlStringCbPrintfA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
Definition: ntstrsafe.h:1148
NTSTRSAFEAPI RtlStringCbCopyA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:156
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
@ ESUCCESS
Definition: arc.h:32
@ LoaderNlsData
Definition: arc.h:148
@ LoaderRegistryData
Definition: arc.h:146
ULONG ARC_STATUS
Definition: arc.h:4
@ OpenReadOnly
Definition: arc.h:65
#define TRACE(s)
Definition: solgame.cpp:4
Definition: arc.h:199
UNICODE_STRING Group
Definition: cmboot.h:16
BOOT_DRIVER_LIST_ENTRY ListEntry
Definition: cmboot.h:15
ULONG ErrorControl
Definition: cmboot.h:19
UNICODE_STRING Name
Definition: cmboot.h:17
Definition: typedefs.h:120
ULONG RegistryLength
Definition: arc.h:500
LOADER_PARAMETER_BLOCK LoaderBlock
Definition: winldr.h:48
USHORT MaximumLength
Definition: env_spec_w32.h:370
const uint16_t * PCWSTR
Definition: typedefs.h:57
void * PVOID
Definition: typedefs.h:50
const char * PCSTR
Definition: typedefs.h:52
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
VOID UiMessageBox(PCSTR Format,...)
Definition: ui.c:363
#define DECLARE_UNICODE_STRING_SIZE(_var, _size)
Definition: wdfcore.h:155
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4065
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesRead
Definition: wdfiotarget.h:870
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
#define SearchPath
Definition: winbase.h:3771
VOID NtLdrOutputLoadMsg(_In_ PCSTR FileName, _In_opt_ PCSTR Description)
Definition: winldr.c:54
PCWSTR BootFileSystem
Definition: winldr.c:30
PLOADER_SYSTEM_BLOCK WinLdrSystemBlock
Definition: winldr.c:29
#define RegOpenKey
Definition: winreg.h:519
#define RegQueryValue
Definition: winreg.h:523
ULONG TotalNLSSize
Definition: wlregistry.c:20
static BOOLEAN WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN PCSTR DirectoryPath, IN PCSTR HiveName)
Definition: wlregistry.c:38
BOOLEAN WinLdrLoadNLSData(_Inout_ PLOADER_PARAMETER_BLOCK LoaderBlock, _In_ PCSTR DirectoryPath, _In_ PCUNICODE_STRING AnsiFileName, _In_ PCUNICODE_STRING OemFileName, _In_ PCUNICODE_STRING LangFileName, _In_ PCUNICODE_STRING OemHalFileName)
Definition: wlregistry.c:336
BOOLEAN WinLdrAddDriverToList(_Inout_ PLIST_ENTRY DriverListHead, _In_ BOOLEAN InsertAtHead, _In_ PCWSTR DriverName, _In_opt_ PCWSTR ImagePath, _In_opt_ PCWSTR GroupName, _In_ ULONG ErrorControl, _In_ ULONG Tag)
Inserts the specified driver entry into the driver list, or updates an existing entry with new ImageP...
Definition: wlregistry.c:575
BOOLEAN WinLdrInitSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN PCSTR SystemRoot, IN BOOLEAN Setup)
Definition: wlregistry.c:110
static BOOLEAN WinLdrGetNLSNames(_In_ HKEY ControlSet, _Inout_ PUNICODE_STRING AnsiFileName, _Inout_ PUNICODE_STRING OemFileName, _Inout_ PUNICODE_STRING LangFileName, _Inout_ PUNICODE_STRING OemHalFileName)
Definition: wlregistry.c:213
static BOOLEAN WinLdrScanRegistry(IN OUT PLIST_ENTRY BootDriverListHead)
Definition: wlregistry.c:511
BOOLEAN WinLdrScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN PCSTR SystemRoot)
Definition: wlregistry.c:161
@ BootLoad
Definition: cmtypes.h:996
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175