ReactOS 0.4.15-dev-7958-gcd0bb1a
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.

Typedefs

typedef enum _BAD_HIVE_REASON BAD_HIVE_REASON
 
typedef enum _BAD_HIVE_REASONPBAD_HIVE_REASON
 

Enumerations

enum  _BAD_HIVE_REASON { GoodHive = 1 , CorruptHive , NoHive , NoHiveAlloc }
 

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 (_Inout_ PLOADER_PARAMETER_BLOCK LoaderBlock, _In_ PCSTR DirectoryPath, _In_ PCSTR HiveName, _Out_ PBAD_HIVE_REASON Reason)
 
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
 

Typedef Documentation

◆ BAD_HIVE_REASON

◆ PBAD_HIVE_REASON

Enumeration Type Documentation

◆ _BAD_HIVE_REASON

Enumerator
GoodHive 
CorruptHive 
NoHive 
NoHiveAlloc 

Definition at line 34 of file wlregistry.c.

35{
36 GoodHive = 1,
38 NoHive,
enum _BAD_HIVE_REASON BAD_HIVE_REASON
enum _BAD_HIVE_REASON * PBAD_HIVE_REASON
@ CorruptHive
Definition: wlregistry.c:37
@ GoodHive
Definition: wlregistry.c:36
@ NoHiveAlloc
Definition: wlregistry.c:39
@ NoHive
Definition: wlregistry.c:38

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 645 of file wlregistry.c.

653{
654 PBOOT_DRIVER_NODE DriverNode;
656 BOOLEAN AlreadyInserted;
658 UNICODE_STRING DriverNameU;
661 UNICODE_STRING RegistryString = {0};
662 UNICODE_STRING GroupString = {0};
663
664 /* Check whether the driver is already in the list */
665 RtlInitUnicodeString(&DriverNameU, DriverName);
666 AlreadyInserted = CmpIsDriverInList(DriverListHead,
667 &DriverNameU,
668 &DriverNode);
669 if (AlreadyInserted)
670 {
671 /* If so, we have obtained its node */
672 ASSERT(DriverNode);
673 DriverEntry = &DriverNode->ListEntry;
674 }
675 else
676 {
677 /* Allocate a driver node and initialize it */
678 DriverNode = CmpAllocate(sizeof(BOOT_DRIVER_NODE), FALSE, TAG_CM);
679 if (!DriverNode)
680 return FALSE;
681
682 RtlZeroMemory(DriverNode, sizeof(BOOT_DRIVER_NODE));
683 DriverEntry = &DriverNode->ListEntry;
684
685 /* Driver Name */
686 RtlInitEmptyUnicodeString(&DriverNode->Name,
687 CmpAllocate(DriverNameU.Length, FALSE, TAG_CM),
688 DriverNameU.Length);
689 if (!DriverNode->Name.Buffer)
690 goto Failure;
691
692 if (!NT_SUCCESS(RtlAppendUnicodeStringToString(&DriverNode->Name, &DriverNameU)))
693 goto Failure;
694 }
695
696 /* Check whether we have a valid ImagePath. If not, we need
697 * to build it like "System32\\Drivers\\blah.sys" */
698 if (ImagePath && *ImagePath)
699 {
700 /* Just copy ImagePath to the corresponding field in the structure */
701 PathLength = (USHORT)(wcslen(ImagePath)) * sizeof(WCHAR);
702 RtlInitEmptyUnicodeString(&FilePath,
704 PathLength);
705 if (!FilePath.Buffer)
706 goto Failure;
707
709 goto Failure;
710 }
711 else
712 {
713 /* We have to construct ImagePath ourselves */
714 PathLength = DriverNode->Name.Length + sizeof(L"system32\\drivers\\.sys");
715 RtlInitEmptyUnicodeString(&FilePath,
717 PathLength);
718 if (!FilePath.Buffer)
719 goto Failure;
720
721 if (!NT_SUCCESS(RtlAppendUnicodeToString(&FilePath, L"system32\\drivers\\")) ||
724 {
725 goto Failure;
726 }
727 }
728
729 /* Registry path */
731 L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
732 PathLength = RegistryPath.Length + DriverNode->Name.Length;
733 RtlInitEmptyUnicodeString(&RegistryString,
735 PathLength);
736 if (!RegistryString.Buffer)
737 goto Failure;
738
739 if (!NT_SUCCESS(RtlAppendUnicodeStringToString(&RegistryString, &RegistryPath)) ||
740 !NT_SUCCESS(RtlAppendUnicodeStringToString(&RegistryString, &DriverNode->Name)))
741 {
742 goto Failure;
743 }
744
745 /* Group */
746 if (GroupName && *GroupName)
747 {
748 /*
749 * NOTE: Here we can use our own allocator as we alone maintain the
750 * group string. This is different from the other allocated strings,
751 * where we instead need to use the same (hive) allocator as the
752 * one used by CmpAddDriverToList(), for interoperability purposes.
753 */
754 RtlCreateUnicodeString(&GroupString, GroupName);
755 if (!GroupString.Buffer)
756 goto Failure;
757 }
758 else
759 {
760 RtlInitEmptyUnicodeString(&GroupString, NULL, 0);
761 }
762
763 /* Set or replace the driver node's file path */
764 if (DriverEntry->FilePath.Buffer)
765 {
766 CmpFree(DriverEntry->FilePath.Buffer,
767 DriverEntry->FilePath.MaximumLength);
768 }
769 DriverEntry->FilePath = FilePath;
770 FilePath.Buffer = NULL;
771
772 /* Set or replace the driver node's registry path */
773 if (DriverEntry->RegistryPath.Buffer)
774 {
775 CmpFree(DriverEntry->RegistryPath.Buffer,
776 DriverEntry->RegistryPath.MaximumLength);
777 }
778 DriverEntry->RegistryPath = RegistryString;
779 RegistryString.Buffer = NULL;
780
781 /* Set or replace the driver node's group */
782 if (DriverNode->Group.Buffer)
783 {
784 /*
785 * If the buffer is inside the registry hive's memory, this means that
786 * it has been set by CmpAddDriverToList() to point to some data within
787 * the hive; thus we should not free the buffer but just replace it.
788 * Otherwise, this is a buffer previously allocated by ourselves, that
789 * we can free.
790 *
791 * NOTE: This function does not have an explicit LoaderBlock input
792 * parameter pointer, since it does not need it, except for this
793 * very place. So instead, use the global WinLdrSystemBlock pointer.
794 */
795 PLOADER_PARAMETER_BLOCK LoaderBlock =
797
798 if (!LoaderBlock || !LoaderBlock->RegistryBase || !LoaderBlock->RegistryLength ||
799 ((ULONG_PTR)DriverNode->Group.Buffer <
800 (ULONG_PTR)VaToPa(LoaderBlock->RegistryBase)) ||
801 ((ULONG_PTR)DriverNode->Group.Buffer >=
802 (ULONG_PTR)VaToPa(LoaderBlock->RegistryBase) + LoaderBlock->RegistryLength))
803 {
804 RtlFreeUnicodeString(&DriverNode->Group);
805 }
806 }
807 DriverNode->Group = GroupString;
808 GroupString.Buffer = NULL;
809
810 /* ErrorControl and Tag */
811 DriverNode->ErrorControl = ErrorControl;
812 DriverNode->Tag = Tag;
813
814 /* Insert the entry into the list if it does not exist there already */
815 if (!AlreadyInserted)
816 {
817 if (InsertAtHead)
818 InsertHeadList(DriverListHead, &DriverEntry->Link);
819 else
820 InsertTailList(DriverListHead, &DriverEntry->Link);
821 }
822
823 return TRUE;
824
825Failure:
826 if (GroupString.Buffer)
827 RtlFreeUnicodeString(&GroupString);
828 if (RegistryString.Buffer)
829 CmpFree(RegistryString.Buffer, RegistryString.MaximumLength);
830 if (FilePath.Buffer)
831 CmpFree(FilePath.Buffer, FilePath.MaximumLength);
832
833 /* If it does not exist in the list already, free the allocated
834 * driver node, otherwise keep the original one in place. */
835 if (!AlreadyInserted)
836 {
837 if (DriverEntry->RegistryPath.Buffer)
838 {
839 CmpFree(DriverEntry->RegistryPath.Buffer,
840 DriverEntry->RegistryPath.MaximumLength);
841 }
842 if (DriverEntry->FilePath.Buffer)
843 {
844 CmpFree(DriverEntry->FilePath.Buffer,
845 DriverEntry->FilePath.MaximumLength);
846 }
847 if (DriverNode->Name.Buffer)
848 {
849 CmpFree(DriverNode->Name.Buffer,
850 DriverNode->Name.MaximumLength);
851 }
852 CmpFree(DriverNode, sizeof(BOOT_DRIVER_NODE));
853 }
854
855 return FALSE;
856}
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:212
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 283 of file wlregistry.c.

289{
290 LONG rc;
291 HKEY hKey;
293 WCHAR szIdBuffer[80];
294
295 /* Open the CodePage key */
296 rc = RegOpenKey(ControlSet, L"Control\\NLS\\CodePage", &hKey);
297 if (rc != ERROR_SUCCESS)
298 {
299 //TRACE("Couldn't open CodePage registry key\n");
300 return FALSE;
301 }
302
303 /* Get ANSI codepage file */
304 BufferSize = sizeof(szIdBuffer);
305 rc = RegQueryValue(hKey, L"ACP", NULL, (PUCHAR)szIdBuffer, &BufferSize);
306 if (rc != ERROR_SUCCESS)
307 {
308 //TRACE("Couldn't get ACP NLS setting\n");
309 goto Quit;
310 }
311
312 BufferSize = AnsiFileName->MaximumLength;
313 rc = RegQueryValue(hKey, szIdBuffer, NULL,
314 (PUCHAR)AnsiFileName->Buffer, &BufferSize);
315 if (rc != ERROR_SUCCESS)
316 {
317 //TRACE("ACP NLS Setting exists, but isn't readable\n");
318 //goto Quit;
319 AnsiFileName->Length = 0;
320 RtlAppendUnicodeToString(AnsiFileName, L"c_1252.nls"); // HACK: ReactOS bug CORE-6105
321 }
322 else
323 {
324 AnsiFileName->Length = (USHORT)BufferSize - sizeof(UNICODE_NULL);
325 }
326
327 /* Get OEM codepage file */
328 BufferSize = sizeof(szIdBuffer);
329 rc = RegQueryValue(hKey, L"OEMCP", NULL, (PUCHAR)szIdBuffer, &BufferSize);
330 if (rc != ERROR_SUCCESS)
331 {
332 //TRACE("Couldn't get OEMCP NLS setting\n");
333 goto Quit;
334 }
335
336 BufferSize = OemFileName->MaximumLength;
337 rc = RegQueryValue(hKey, szIdBuffer, NULL,
338 (PUCHAR)OemFileName->Buffer, &BufferSize);
339 if (rc != ERROR_SUCCESS)
340 {
341 //TRACE("OEMCP NLS setting exists, but isn't readable\n");
342 //goto Quit;
343 OemFileName->Length = 0;
344 RtlAppendUnicodeToString(OemFileName, L"c_437.nls"); // HACK: ReactOS bug CORE-6105
345 }
346 else
347 {
348 OemFileName->Length = (USHORT)BufferSize - sizeof(UNICODE_NULL);
349 }
350
351 /* Get OEM HAL font file */
352 BufferSize = OemHalFileName->MaximumLength;
353 rc = RegQueryValue(hKey, L"OEMHAL", NULL,
354 (PUCHAR)OemHalFileName->Buffer, &BufferSize);
355 if (rc != ERROR_SUCCESS)
356 {
357 //TRACE("Couldn't get OEMHAL NLS setting\n");
358 //goto Quit;
359 RtlInitEmptyUnicodeString(OemHalFileName, NULL, 0);
360 }
361 else
362 {
363 OemHalFileName->Length = (USHORT)BufferSize - sizeof(UNICODE_NULL);
364 }
365
367
368 /* Open the Language key */
369 rc = RegOpenKey(ControlSet, L"Control\\NLS\\Language", &hKey);
370 if (rc != ERROR_SUCCESS)
371 {
372 //TRACE("Couldn't open Language registry key\n");
373 return FALSE;
374 }
375
376 /* Get the Unicode case table file */
377 BufferSize = sizeof(szIdBuffer);
378 rc = RegQueryValue(hKey, L"Default", NULL, (PUCHAR)szIdBuffer, &BufferSize);
379 if (rc != ERROR_SUCCESS)
380 {
381 //TRACE("Couldn't get Language Default setting\n");
382 goto Quit;
383 }
384
385 BufferSize = LangFileName->MaximumLength;
386 rc = RegQueryValue(hKey, szIdBuffer, NULL,
387 (PUCHAR)LangFileName->Buffer, &BufferSize);
388 if (rc != ERROR_SUCCESS)
389 {
390 //TRACE("Language Default setting exists, but isn't readable\n");
391 //goto Quit;
392 LangFileName->Length = 0;
393 RtlAppendUnicodeToString(LangFileName, L"l_intl.nls");
394 }
395 else
396 {
397 LangFileName->Length = (USHORT)BufferSize - sizeof(UNICODE_NULL);
398 }
399
400Quit:
402 return (rc == ERROR_SUCCESS);
403}
#define RegCloseKey(hKey)
Definition: registry.h:49
#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 125 of file wlregistry.c.

129{
130 CHAR SearchPath[1024];
131 PVOID ChunkBase;
132 PCSTR HiveName;
135
136 /* Load the corresponding text-mode setup system hive or the standard hive */
137 if (Setup)
138 {
140 HiveName = "SETUPREG.HIV";
141 }
142 else
143 {
145 RtlStringCbCatA(SearchPath, sizeof(SearchPath), "system32\\config\\");
146 HiveName = "SYSTEM";
147 }
148
149 TRACE("WinLdrInitSystemHive: loading hive %s%s\n", SearchPath, HiveName);
150 Success = WinLdrLoadSystemHive(LoaderBlock, SearchPath, HiveName, &Reason);
151 if (!Success)
152 {
153 /* Check whether the SYSTEM hive does not exist or is too corrupt to be read */
154 if (Reason == CorruptHive || Reason == NoHive)
155 {
156 /* Try loading the alternate hive, the main hive should be recovered later */
157 goto LoadAlternateHive;
158 }
159
160 /* We are failing for other reason, bail out */
161 UiMessageBox("Could not load %s hive!", HiveName);
162 return FALSE;
163 }
164
165 /* Import what was loaded */
166 Success = RegImportBinaryHive(VaToPa(LoaderBlock->RegistryBase), LoaderBlock->RegistryLength, SearchPath, FALSE);
167 if (!Success)
168 {
169 /*
170 * Importing of the SYSTEM hive failed. The scenarios that would
171 * have made this possible are the following:
172 *
173 * 1. The primary hive is corrupt beyond repair (such as when
174 * core FS structures are total toast);
175 *
176 * 2. Repairing the hive could with a LOG could not recover it
177 * to the fullest. This is the case when the hive and LOG have
178 * diverged too much, or are mismatched, or the containing healthy
179 * data in the LOG was not marked as dirty that could be copied
180 * into the primary hive;
181 *
182 * 3. LOG is bad (e.g. corrupt dirty vector);
183 *
184 * 4. LOG does not physically exist on the backing storage.
185 *
186 * 5. SYSTEM hive does not physically exist or it is a 0 bytes file
187 * (the latter case still counts as corruption).
188 *
189 * With the hope to boot the system, load the mirror counterpart
190 * of the main hive, the alternate. The kernel should be able to recover
191 * the main hive later on as soon as it starts writing to it.
192 */
193LoadAlternateHive:
194 HiveName = "SYSTEM.ALT";
195 Success = WinLdrLoadSystemHive(LoaderBlock, SearchPath, HiveName, &Reason);
196 if (!Success)
197 {
198 UiMessageBox("Could not load %s hive!", HiveName);
199 return FALSE;
200 }
201
202 /* Retry importing it again */
203 Success = RegImportBinaryHive(VaToPa(LoaderBlock->RegistryBase), LoaderBlock->RegistryLength, SearchPath, TRUE);
204 if (!Success)
205 {
206 UiMessageBox("Importing binary hive failed!");
207 return FALSE;
208 }
209
210 /*
211 * Acknowledge the kernel we recovered the SYSTEM hive
212 * on our side by loading the alternate variant of the hive.
213 */
214 WARN("SYSTEM hive does not exist or is corrupt and SYSTEM.ALT has been loaded!\n");
215 ChunkBase = VaToPa(LoaderBlock->RegistryBase);
216 ((PHBASE_BLOCK)ChunkBase)->BootRecover = HBOOT_BOOT_RECOVERED_BY_ALTERNATE_HIVE;
217 }
218
219 // FIXME: Load SYSTEM.SAV if GUI setup installation is still in progress
220
221 /* Initialize the 'CurrentControlSet' link */
223 {
224 UiMessageBox("Initializing CurrentControlSet link failed!");
225 return FALSE;
226 }
227
228 return TRUE;
229}
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
VOID UiMessageBox(_In_ PCSTR Format,...)
Definition: ui.c:359
BOOLEAN RegInitCurrentControlSet(_In_ BOOLEAN LastKnownGood)
Definition: registry.c:525
BOOLEAN RegImportBinaryHive(_In_ PVOID ChunkBase, _In_ ULONG ChunkSize, _In_ PCSTR SearchPath, _In_ BOOLEAN LoadAlternate)
Imports the SYSTEM binary hive from the registry base chunk that's been provided by the loader block.
Definition: registry.c:449
static const WCHAR SystemRoot[]
Definition: reg.c:38
@ Success
Definition: eventcreate.c:712
#define HBOOT_BOOT_RECOVERED_BY_ALTERNATE_HIVE
Definition: hivedata.h:96
struct _HBASE_BLOCK * PHBASE_BLOCK
PVOID PVOID PWCHAR PVOID USHORT PULONG Reason
Definition: env.c:47
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
#define SearchPath
Definition: winbase.h:3900
static BOOLEAN WinLdrLoadSystemHive(_Inout_ PLOADER_PARAMETER_BLOCK LoaderBlock, _In_ PCSTR DirectoryPath, _In_ PCSTR HiveName, _Out_ PBAD_HIVE_REASON Reason)
Definition: wlregistry.c:45
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 406 of file wlregistry.c.

413{
416 ULONG AnsiFileId = -1, OemFileId = -1, LangFileId = -1;
417 ULONG AnsiFileSize, OemFileSize, LangFileSize;
418 ULONG TotalSize;
420 PVOID NlsDataBase, NlsVirtual;
421 BOOLEAN AnsiEqualsOem = FALSE;
423
424 /* There may be a case, where OEM and ANSI pages coincide */
425 if (RtlCompareUnicodeString(AnsiFileName, OemFileName, TRUE) == 0)
426 AnsiEqualsOem = TRUE;
427
428 /* Open file with ANSI and store its size */
429 RtlStringCbPrintfA(FileName, sizeof(FileName), "%s%wZ",
430 DirectoryPath, AnsiFileName);
431 Status = ArcOpen(FileName, OpenReadOnly, &AnsiFileId);
432 if (Status != ESUCCESS)
433 {
434 WARN("Error while opening '%s', Status: %u\n", FileName, Status);
435 goto Quit;
436 }
437
438 Status = ArcGetFileInformation(AnsiFileId, &FileInfo);
439 if (Status != ESUCCESS)
440 goto Quit;
441 AnsiFileSize = FileInfo.EndingAddress.LowPart;
442 TRACE("AnsiFileSize: %d\n", AnsiFileSize);
443
444 /* Open OEM file and store its length */
445 if (AnsiEqualsOem)
446 {
447 OemFileSize = 0;
448 }
449 else
450 {
451 RtlStringCbPrintfA(FileName, sizeof(FileName), "%s%wZ",
452 DirectoryPath, OemFileName);
453 Status = ArcOpen(FileName, OpenReadOnly, &OemFileId);
454 if (Status != ESUCCESS)
455 {
456 WARN("Error while opening '%s', Status: %u\n", FileName, Status);
457 goto Quit;
458 }
459
461 if (Status != ESUCCESS)
462 goto Quit;
463 OemFileSize = FileInfo.EndingAddress.LowPart;
464 }
465 TRACE("OemFileSize: %d\n", OemFileSize);
466
467 /* Finally open the language codepage file and store its length */
468 RtlStringCbPrintfA(FileName, sizeof(FileName), "%s%wZ",
469 DirectoryPath, LangFileName);
470 Status = ArcOpen(FileName, OpenReadOnly, &LangFileId);
471 if (Status != ESUCCESS)
472 {
473 WARN("Error while opening '%s', Status: %u\n", FileName, Status);
474 goto Quit;
475 }
476
477 Status = ArcGetFileInformation(LangFileId, &FileInfo);
478 if (Status != ESUCCESS)
479 goto Quit;
480 LangFileSize = FileInfo.EndingAddress.LowPart;
481 TRACE("LangFileSize: %d\n", LangFileSize);
482
483 //
484 // TODO: The OEMHAL file.
485 //
486
487 /* Sum up all three length, having in mind that every one of them
488 must start at a page boundary => thus round up each file to a page */
489 TotalSize = MM_SIZE_TO_PAGES(AnsiFileSize) +
490 MM_SIZE_TO_PAGES(OemFileSize) +
491 MM_SIZE_TO_PAGES(LangFileSize);
492
493 /* Store it for later marking the pages as NlsData type */
494 TotalNLSSize = TotalSize;
495
496 NlsDataBase = MmAllocateMemoryWithType(TotalSize*MM_PAGE_SIZE, LoaderNlsData);
497 if (NlsDataBase == NULL)
498 goto Quit;
499
500 NlsVirtual = PaToVa(NlsDataBase);
501 LoaderBlock->NlsData->AnsiCodePageData = NlsVirtual;
502
503 LoaderBlock->NlsData->OemCodePageData =
504 (PVOID)((ULONG_PTR)NlsVirtual +
505 (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT));
506
507 LoaderBlock->NlsData->UnicodeCodePageData =
508 (PVOID)((ULONG_PTR)NlsVirtual +
509 (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT) +
510 (MM_SIZE_TO_PAGES(OemFileSize) << MM_PAGE_SHIFT));
511
512 /* ANSI and OEM data are the same - just set pointers to the same area */
513 if (AnsiEqualsOem)
514 LoaderBlock->NlsData->OemCodePageData = LoaderBlock->NlsData->AnsiCodePageData;
515
516 /* Now actually read the data into memory, starting with the ANSI file */
517 RtlStringCbPrintfA(FileName, sizeof(FileName), "%s%wZ",
518 DirectoryPath, AnsiFileName);
520 Status = ArcRead(AnsiFileId,
521 VaToPa(LoaderBlock->NlsData->AnsiCodePageData),
522 AnsiFileSize, &BytesRead);
523 if (Status != ESUCCESS)
524 {
525 WARN("Error while reading '%s', Status: %u\n", FileName, Status);
526 goto Quit;
527 }
528
529 /* OEM now, if it isn't the same as the ANSI one */
530 if (!AnsiEqualsOem)
531 {
532 RtlStringCbPrintfA(FileName, sizeof(FileName), "%s%wZ",
533 DirectoryPath, OemFileName);
535 Status = ArcRead(OemFileId,
536 VaToPa(LoaderBlock->NlsData->OemCodePageData),
537 OemFileSize, &BytesRead);
538 if (Status != ESUCCESS)
539 {
540 WARN("Error while reading '%s', Status: %u\n", FileName, Status);
541 goto Quit;
542 }
543 }
544
545 /* Finally the language file */
546 RtlStringCbPrintfA(FileName, sizeof(FileName), "%s%wZ",
547 DirectoryPath, LangFileName);
549 Status = ArcRead(LangFileId,
550 VaToPa(LoaderBlock->NlsData->UnicodeCodePageData),
551 LangFileSize, &BytesRead);
552 if (Status != ESUCCESS)
553 {
554 WARN("Error while reading '%s', Status: %u\n", FileName, Status);
555 goto Quit;
556 }
557
558 //
559 // THIS IS a HACK and should be replaced by actually loading the OEMHAL file!
560 //
561 LoaderBlock->OemFontFile = VaToPa(LoaderBlock->NlsData->UnicodeCodePageData);
562
563 /* Convert NlsTables address to VA */
564 LoaderBlock->NlsData = PaToVa(LoaderBlock->NlsData);
565
566Quit:
567 if (LangFileId != -1)
568 ArcClose(LangFileId);
569 if (OemFileId != -1)
570 ArcClose(OemFileId);
571 if (AnsiFileId != -1)
572 ArcClose(AnsiFileId);
573
574 if (Status != ESUCCESS)
575 UiMessageBox("Error reading NLS file %s", FileName);
576
577 return (Status == ESUCCESS);
578}
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 ( _Inout_ PLOADER_PARAMETER_BLOCK  LoaderBlock,
_In_ PCSTR  DirectoryPath,
_In_ PCSTR  HiveName,
_Out_ PBAD_HIVE_REASON  Reason 
)
static

Definition at line 45 of file wlregistry.c.

50{
51 ULONG FileId;
52 CHAR FullHiveName[MAX_PATH];
55 ULONG HiveFileSize;
56 PVOID HiveDataPhysical;
57 PVOID HiveDataVirtual;
59
60 /* Do not setup any bad reason for now */
62
63 /* Concatenate path and filename to get the full name */
64 RtlStringCbCopyA(FullHiveName, sizeof(FullHiveName), DirectoryPath);
65 RtlStringCbCatA(FullHiveName, sizeof(FullHiveName), HiveName);
66
67 NtLdrOutputLoadMsg(FullHiveName, NULL);
68 Status = ArcOpen(FullHiveName, OpenReadOnly, &FileId);
69 if (Status != ESUCCESS)
70 {
71 WARN("Error while opening '%s', Status: %u\n", FullHiveName, Status);
72 *Reason = NoHive;
73 return FALSE;
74 }
75
76 /* Get the file length */
78 if (Status != ESUCCESS)
79 {
80 WARN("Hive file has 0 size!\n");
82 ArcClose(FileId);
83 return FALSE;
84 }
85 HiveFileSize = FileInfo.EndingAddress.LowPart;
86
87 /* Round up the size to page boundary and alloc memory */
88 HiveDataPhysical = MmAllocateMemoryWithType(
89 MM_SIZE_TO_PAGES(HiveFileSize + MM_PAGE_SIZE - 1) << MM_PAGE_SHIFT,
91
92 if (HiveDataPhysical == NULL)
93 {
94 WARN("Could not alloc memory for hive!\n");
96 ArcClose(FileId);
97 return FALSE;
98 }
99
100 /* Convert address to virtual */
101 HiveDataVirtual = PaToVa(HiveDataPhysical);
102
103 /* Fill LoaderBlock's entries */
104 LoaderBlock->RegistryLength = HiveFileSize;
105 LoaderBlock->RegistryBase = HiveDataVirtual;
106
107 /* Finally read from file to the memory */
108 Status = ArcRead(FileId, HiveDataPhysical, HiveFileSize, &BytesRead);
109 if (Status != ESUCCESS)
110 {
111 WARN("Error while reading '%s', Status: %u\n", FullHiveName, Status);
113 ArcClose(FileId);
114 return FALSE;
115 }
116
117 // FIXME: HACK: Get the boot filesystem driver name now...
119
120 ArcClose(FileId);
121 return TRUE;
122}
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 581 of file wlregistry.c.

583{
585
586 /* Find all boot drivers */
589 BootLoad,
591 BootDriverListHead);
592 if (!Success)
593 goto Quit;
594
595 /* Sort by group/tag */
598 BootDriverListHead);
599 if (!Success)
600 goto Quit;
601
602 /* Remove circular dependencies (cycles) and sort */
603 Success = CmpResolveDriverDependencies(BootDriverListHead);
604 if (!Success)
605 goto Quit;
606
607Quit:
608 /* In case of failure, free the boot driver list */
609 if (!Success)
610 CmpFreeDriverList(SystemHive, BootDriverListHead);
611
612 return Success;
613}
PHHIVE SystemHive
Definition: registry.c:33
HKEY CurrentControlSetKey
Definition: registry.c:34
#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 231 of file wlregistry.c.

233{
237 DECLARE_UNICODE_STRING_SIZE(LangFileName, MAX_PATH); // CaseTable
238 DECLARE_UNICODE_STRING_SIZE(OemHalFileName, MAX_PATH);
239 CHAR SearchPath[1024];
240
241 /* Scan registry and prepare boot drivers list */
242 Success = WinLdrScanRegistry(&LoaderBlock->BootDriverListHead);
243 if (!Success)
244 {
245 UiMessageBox("Failed to load boot drivers!");
246 return FALSE;
247 }
248
249 /* Get names of NLS files */
251 &AnsiFileName,
252 &OemFileName,
253 &LangFileName,
254 &OemHalFileName);
255 if (!Success)
256 {
257 UiMessageBox("Getting NLS names from registry failed!");
258 return FALSE;
259 }
260
261 TRACE("NLS data: '%wZ' '%wZ' '%wZ' '%wZ'\n",
262 &AnsiFileName, &OemFileName, &LangFileName, &OemHalFileName);
263
264 /* Load NLS data */
266 RtlStringCbCatA(SearchPath, sizeof(SearchPath), "system32\\");
267 Success = WinLdrLoadNLSData(LoaderBlock,
269 &AnsiFileName,
270 &OemFileName,
271 &LangFileName,
272 &OemHalFileName);
273 TRACE("NLS data loading %s\n", Success ? "successful" : "failed");
274
275 return TRUE;
276}
#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:406
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:283
static BOOLEAN WinLdrScanRegistry(IN OUT PLIST_ENTRY BootDriverListHead)
Definition: wlregistry.c:581

Referenced by LoadAndBootWindows().

Variable Documentation

◆ TotalNLSSize

ULONG TotalNLSSize = 0

Definition at line 20 of file wlregistry.c.

Referenced by WinLdrLoadNLSData().