ReactOS  0.4.15-dev-5130-gc1c1279
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. More...
 

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;
590  UNICODE_STRING FilePath = {0};
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 
638  if (!NT_SUCCESS(RtlAppendUnicodeToString(&FilePath, ImagePath)))
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 
755 Failure:
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 }
BOOT_DRIVER_LIST_ENTRY ListEntry
Definition: cmboot.h:15
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define TRUE
Definition: types.h:120
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
ULONG ErrorControl
Definition: cmboot.h:19
PVOID NTAPI CmpAllocate(_In_ SIZE_T Size, _In_ BOOLEAN Paged, _In_ ULONG Tag)
Definition: bootreg.c:90
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
#define InsertTailList(ListHead, Entry)
static USHORT PathLength
PCWSTR FilePath
uint32_t ULONG_PTR
Definition: typedefs.h:65
Definition: arc.h:198
#define L(x)
Definition: ntvdm.h:50
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
LOADER_PARAMETER_BLOCK LoaderBlock
Definition: winldr.h:48
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define TAG_WLDR_NAME
Definition: winldr.h:15
UNICODE_STRING Name
Definition: cmboot.h:17
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI CmpFree(_In_ PVOID Ptr, _In_ ULONG Quota)
Definition: bootreg.c:105
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define TAG_CM
Definition: cmlib.h:205
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4061
UNICODE_STRING Group
Definition: cmboot.h:16
DRIVER_INITIALIZE DriverEntry
Definition: condrv.c:21
unsigned short USHORT
Definition: pedump.c:61
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define NULL
Definition: types.h:112
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
FORCEINLINE PVOID VaToPa(PVOID Va)
Definition: conversion.h:15
ULONG RegistryLength
Definition: arc.h:500
PLOADER_SYSTEM_BLOCK WinLdrSystemBlock
Definition: winldr.c:29

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 
296  RegCloseKey(hKey);
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 
330 Quit:
331  RegCloseKey(hKey);
332  return (rc == ERROR_SUCCESS);
333 }
#define ERROR_SUCCESS
Definition: deptool.c:10
unsigned char * PUCHAR
Definition: retypes.h:3
#define L(x)
Definition: ntvdm.h:50
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
long LONG
Definition: pedump.c:60
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned short USHORT
Definition: pedump.c:61
FxAutoRegKey hKey
#define NULL
Definition: types.h:112
#define RegQueryValue
Definition: winreg.h:523
unsigned int ULONG
Definition: retypes.h:1
#define RegOpenKey
Definition: winreg.h:519
#define RegCloseKey(hKey)
Definition: registry.h:47
#define BufferSize
Definition: mmc.h:75
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:251

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 BOOLEAN Physical 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:828
#define TRUE
Definition: types.h:120
BOOLEAN RegImportBinaryHive(_In_ PVOID ChunkBase, _In_ ULONG ChunkSize)
Definition: registry.c:66
char CHAR
Definition: xmlstorage.h:175
BOOLEAN RegInitCurrentControlSet(_In_ BOOLEAN LastKnownGood)
Definition: registry.c:112
#define SearchPath
Definition: winbase.h:3761
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 FALSE
Definition: types.h:117
VOID UiMessageBox(PCSTR Format,...)
Definition: ui.c:363
unsigned char BOOLEAN
#define TRACE(s)
Definition: solgame.cpp:4
static const WCHAR SystemRoot[]
Definition: reg.c:38
static BOOLEAN WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN PCSTR DirectoryPath, IN PCSTR HiveName)
Definition: wlregistry.c:38
FORCEINLINE PVOID VaToPa(PVOID Va)
Definition: conversion.h:15
const char * PCSTR
Definition: typedefs.h:52
NTSTRSAFEAPI RtlStringCbCatA(_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:625

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 
390  Status = ArcGetFileInformation(OemFileId, &FileInfo);
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 
496 Quit:
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 }
Definition: arc.h:32
#define TRUE
Definition: types.h:120
char CHAR
Definition: xmlstorage.h:175
#define WARN(fmt,...)
Definition: debug.h:112
ULONG ARC_STATUS
Definition: arc.h:4
_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:859
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
VOID UiMessageBox(PCSTR Format,...)
Definition: ui.c:363
unsigned char BOOLEAN
void * PVOID
Definition: retypes.h:9
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
Status
Definition: gdiplustypes.h:24
#define TRACE(s)
Definition: solgame.cpp:4
VOID NtLdrOutputLoadMsg(_In_ PCSTR FileName, _In_opt_ PCSTR Description)
Definition: winldr.c:54
#define MAX_PATH
Definition: compat.h:34
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: fs.c:236
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
PVOID MmAllocateMemoryWithType(SIZE_T MemorySize, TYPE_OF_MEMORY MemoryType)
Definition: mm.c:31
ULONG TotalNLSSize
Definition: wlregistry.c:20
#define NULL
Definition: types.h:112
ARC_STATUS ArcClose(ULONG FileId)
Definition: fs.c:218
ARC_STATUS ArcGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
Definition: fs.c:250
struct FileInfo FileInfo
FORCEINLINE PVOID PaToVa(PVOID Pa)
Definition: conversion.h:22
ARC_STATUS ArcOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
Definition: fs.c:56
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE PVOID VaToPa(PVOID Va)
Definition: conversion.h:15

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 }
Definition: arc.h:32
#define TRUE
Definition: types.h:120
char CHAR
Definition: xmlstorage.h:175
#define WARN(fmt,...)
Definition: debug.h:112
ULONG ARC_STATUS
Definition: arc.h:4
_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:859
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 FALSE
Definition: types.h:117
PCWSTR FsGetServiceName(ULONG FileId)
Definition: fs.c:402
PCWSTR BootFileSystem
Definition: winldr.c:30
Status
Definition: gdiplustypes.h:24
VOID NtLdrOutputLoadMsg(_In_ PCSTR FileName, _In_opt_ PCSTR Description)
Definition: winldr.c:54
#define MAX_PATH
Definition: compat.h:34
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: fs.c:236
PVOID MmAllocateMemoryWithType(SIZE_T MemorySize, TYPE_OF_MEMORY MemoryType)
Definition: mm.c:31
#define NULL
Definition: types.h:112
ARC_STATUS ArcClose(ULONG FileId)
Definition: fs.c:218
ARC_STATUS ArcGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
Definition: fs.c:250
struct FileInfo FileInfo
FORCEINLINE PVOID PaToVa(PVOID Pa)
Definition: conversion.h:22
ARC_STATUS ArcOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
Definition: fs.c:56
unsigned int ULONG
Definition: retypes.h:1
NTSTRSAFEAPI RtlStringCbCatA(_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:625

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 
537 Quit:
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
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
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
HKEY CurrentControlSetKey
Definition: registry.c:33
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
unsigned char BOOLEAN
PCWSTR BootFileSystem
Definition: winldr.c:30
BOOLEAN NTAPI CmpResolveDriverDependencies(_Inout_ PLIST_ENTRY DriverListHead)
Removes potential circular dependencies (cycles) and sorts the driver list.
Definition: cmboot.c:1030
#define HKEY_TO_HCI(hKey)
Definition: registry.h:28

Referenced by WinLdrScanSystemHive().

◆ WinLdrScanSystemHive()

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

Definition at line 161 of file wlregistry.c.

163 {
165  DECLARE_UNICODE_STRING_SIZE(AnsiFileName, MAX_PATH);
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,
198  SearchPath,
199  &AnsiFileName,
200  &OemFileName,
201  &LangFileName,
202  &OemHalFileName);
203  TRACE("NLS data loading %s\n", Success ? "successful" : "failed");
204 
205  return TRUE;
206 }
#define TRUE
Definition: types.h:120
char CHAR
Definition: xmlstorage.h:175
#define SearchPath
Definition: winbase.h:3761
NTSTRSAFEAPI RtlStringCbCopyA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:156
HKEY CurrentControlSetKey
Definition: registry.c:33
#define FALSE
Definition: types.h:117
VOID UiMessageBox(PCSTR Format,...)
Definition: ui.c:363
unsigned char BOOLEAN
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
#define TRACE(s)
Definition: solgame.cpp:4
static const WCHAR SystemRoot[]
Definition: reg.c:38
#define MAX_PATH
Definition: compat.h:34
#define DECLARE_UNICODE_STRING_SIZE(_var, _size)
Definition: wdfcore.h:155
static BOOLEAN WinLdrScanRegistry(IN OUT PLIST_ENTRY BootDriverListHead)
Definition: wlregistry.c:511
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
NTSTRSAFEAPI RtlStringCbCatA(_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:625

Referenced by LoadAndBootWindows().

Variable Documentation

◆ TotalNLSSize

ULONG TotalNLSSize = 0

Definition at line 20 of file wlregistry.c.

Referenced by WinLdrLoadNLSData().