ReactOS 0.4.15-dev-6656-gbbb33a6
wlregistry.c File Reference
#include <freeldr.h>
#include "winldr.h"
#include "registry.h"
#include <internal/cmboot.h>
#include <debug.h>
Include dependency graph for wlregistry.c:

Go to the source code of this file.

Functions

 DBG_DEFAULT_CHANNEL (WINDOWS)
 
static BOOLEAN WinLdrGetNLSNames (_In_ HKEY ControlSet, _Inout_ PUNICODE_STRING AnsiFileName, _Inout_ PUNICODE_STRING OemFileName, _Inout_ PUNICODE_STRING LangFileName, _Inout_ PUNICODE_STRING OemHalFileName)
 
static BOOLEAN WinLdrScanRegistry (IN OUT PLIST_ENTRY BootDriverListHead)
 
static BOOLEAN WinLdrLoadSystemHive (IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN PCSTR DirectoryPath, IN PCSTR HiveName)
 
BOOLEAN WinLdrInitSystemHive (IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN PCSTR SystemRoot, IN BOOLEAN Setup)
 
BOOLEAN WinLdrScanSystemHive (IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN PCSTR SystemRoot)
 
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)
 
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 ImagePath, ErrorControl, Group and Tag values.
 

Variables

ULONG TotalNLSSize = 0
 

Function Documentation

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( WINDOWS  )

◆ WinLdrAddDriverToList()

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 ImagePath, ErrorControl, Group and Tag values.

Parameters
[in,out]DriverListHeadThe driver list where to insert the driver entry.
[in]InsertAtHeadWhether to insert the driver at the head (TRUE) or at the tail (FALSE) of the driver list.
[in]DriverNameThe driver's name.
[in]ImagePathOptional path the the driver's image. If none is specified, a default path is constructed out of the driver's name.
[in]GroupNameOptional driver group name.
[in]ErrorControl
[in]TagThe ErrorControl and group Tag values for the driver.
Returns
TRUE if the driver has been inserted into the list or updated, FALSE if not.

Definition at line 575 of file wlregistry.c.

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
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
#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
#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
DRIVER_INITIALIZE DriverEntry
Definition: condrv.c:21
#define ULONG_PTR
Definition: config.h:101
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
_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
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 L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
Definition: arc.h:246
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
ULONG RegistryLength
Definition: arc.h:547
LOADER_PARAMETER_BLOCK LoaderBlock
Definition: winldr.h:48
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
_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
PLOADER_SYSTEM_BLOCK WinLdrSystemBlock
Definition: winldr.c:29
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by SetupLdrScanBootDrivers().

◆ WinLdrGetNLSNames()

static BOOLEAN WinLdrGetNLSNames ( _In_ HKEY  ControlSet,
_Inout_ PUNICODE_STRING  AnsiFileName,
_Inout_ PUNICODE_STRING  OemFileName,
_Inout_ PUNICODE_STRING  LangFileName,
_Inout_ PUNICODE_STRING  OemHalFileName 
)
static

Definition at line 213 of file wlregistry.c.

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}
#define RegCloseKey(hKey)
Definition: registry.h:47
#define BufferSize
Definition: mmc.h:75
#define ERROR_SUCCESS
Definition: deptool.c:10
FxAutoRegKey hKey
#define UNICODE_NULL
long LONG
Definition: pedump.c:60
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
#define RegOpenKey
Definition: winreg.h:519
#define RegQueryValue
Definition: winreg.h:523

Referenced by WinLdrScanSystemHive().

◆ WinLdrInitSystemHive()

BOOLEAN WinLdrInitSystemHive ( IN OUT PLOADER_PARAMETER_BLOCK  LoaderBlock,
IN PCSTR  SystemRoot,
IN BOOLEAN  Setup 
)

Definition at line 110 of file wlregistry.c.

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}
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
BOOLEAN RegInitCurrentControlSet(_In_ BOOLEAN LastKnownGood)
Definition: registry.c:112
BOOLEAN RegImportBinaryHive(_In_ PVOID ChunkBase, _In_ ULONG ChunkSize)
Definition: registry.c:66
static const WCHAR SystemRoot[]
Definition: reg.c:38
@ Success
Definition: eventcreate.c:712
NTSTRSAFEAPI RtlStringCbCatA(_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:625
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 TRACE(s)
Definition: solgame.cpp:4
const char * PCSTR
Definition: typedefs.h:52
VOID UiMessageBox(PCSTR Format,...)
Definition: ui.c:357
#define SearchPath
Definition: winbase.h:3825
static BOOLEAN WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN PCSTR DirectoryPath, IN PCSTR HiveName)
Definition: wlregistry.c:38
char CHAR
Definition: xmlstorage.h:175

Referenced by LoadAndBootWindows(), and LoadReactOSSetup().

◆ WinLdrLoadNLSData()

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 at line 336 of file wlregistry.c.

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}
#define WARN(fmt,...)
Definition: debug.h:112
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
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
FORCEINLINE PVOID PaToVa(PVOID Pa)
Definition: conversion.h:22
#define MAX_PATH
Definition: compat.h:34
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
Status
Definition: gdiplustypes.h:25
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
@ ESUCCESS
Definition: arc.h:32
@ LoaderNlsData
Definition: arc.h:195
ULONG ARC_STATUS
Definition: arc.h:4
@ OpenReadOnly
Definition: arc.h:65
void * PVOID
Definition: typedefs.h:50
_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
VOID NtLdrOutputLoadMsg(_In_ PCSTR FileName, _In_opt_ PCSTR Description)
Definition: winldr.c:54
ULONG TotalNLSSize
Definition: wlregistry.c:20

Referenced by SetupLdrLoadNlsData(), and WinLdrScanSystemHive().

◆ WinLdrLoadSystemHive()

static BOOLEAN WinLdrLoadSystemHive ( IN OUT PLOADER_PARAMETER_BLOCK  LoaderBlock,
IN PCSTR  DirectoryPath,
IN PCSTR  HiveName 
)
static

Definition at line 38 of file wlregistry.c.

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}
PCWSTR FsGetServiceName(ULONG FileId)
Definition: fs.c:404
@ LoaderRegistryData
Definition: arc.h:193
PCWSTR BootFileSystem
Definition: winldr.c:30

Referenced by WinLdrInitSystemHive().

◆ WinLdrScanRegistry()

static BOOLEAN WinLdrScanRegistry ( IN OUT PLIST_ENTRY  BootDriverListHead)
static

Definition at line 511 of file wlregistry.c.

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}
PHHIVE SystemHive
Definition: registry.c:32
HKEY CurrentControlSetKey
Definition: registry.c:33
#define HKEY_TO_HCI(hKey)
Definition: registry.h:28
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
@ BootLoad
Definition: cmtypes.h:996

Referenced by WinLdrScanSystemHive().

◆ WinLdrScanSystemHive()

BOOLEAN WinLdrScanSystemHive ( IN OUT PLOADER_PARAMETER_BLOCK  LoaderBlock,
IN PCSTR  SystemRoot 
)

Definition at line 161 of file wlregistry.c.

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}
#define DECLARE_UNICODE_STRING_SIZE(_var, _size)
Definition: wdfcore.h:155
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
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

Referenced by LoadAndBootWindows().

Variable Documentation

◆ TotalNLSSize

ULONG TotalNLSSize = 0

Definition at line 20 of file wlregistry.c.

Referenced by WinLdrLoadNLSData().