ReactOS  0.4.13-dev-443-g10f00f8
wlregistry.c
Go to the documentation of this file.
1 /*
2  * PROJECT: EFI Windows Loader
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: boot/freeldr/freeldr/windows/wlregistry.c
5  * PURPOSE: Registry support functions
6  * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
7  */
8 
9 /* INCLUDES ***************************************************************/
10 
11 #include <freeldr.h>
12 #include "winldr.h"
13 #include "registry.h"
14 
15 #include <debug.h>
16 DBG_DEFAULT_CHANNEL(WINDOWS);
17 
18 // The only global var here, used to mark mem pages as NLS in WinLdrSetupMemoryLayout()
20 
21 static BOOLEAN
22 WinLdrGetNLSNames(LPSTR AnsiName,
23  LPSTR OemName,
24  LPSTR LangName);
25 
26 static VOID
27 WinLdrScanRegistry(IN OUT PLIST_ENTRY BootDriverListHead,
28  IN LPCSTR DirectoryPath);
29 
30 
31 /* FUNCTIONS **************************************************************/
32 
33 static BOOLEAN
35  IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
36  IN PCSTR DirectoryPath,
37  IN PCSTR HiveName)
38 {
39  ULONG FileId;
40  CHAR FullHiveName[MAX_PATH];
43  ULONG HiveFileSize;
44  ULONG_PTR HiveDataPhysical;
45  PVOID HiveDataVirtual;
47  PCWSTR FsService;
48 
49  /* Concatenate path and filename to get the full name */
50  strcpy(FullHiveName, DirectoryPath);
51  strcat(FullHiveName, HiveName);
52  //Print(L"Loading %s...\n", FullHiveName);
53  Status = ArcOpen(FullHiveName, OpenReadOnly, &FileId);
54  if (Status != ESUCCESS)
55  {
56  UiMessageBox("Opening hive file failed!");
57  return FALSE;
58  }
59 
60  /* Get the file length */
62  if (Status != ESUCCESS)
63  {
64  ArcClose(FileId);
65  UiMessageBox("Hive file has 0 size!");
66  return FALSE;
67  }
68  HiveFileSize = FileInfo.EndingAddress.LowPart;
69 
70  /* Round up the size to page boundary and alloc memory */
71  HiveDataPhysical = (ULONG_PTR)MmAllocateMemoryWithType(
72  MM_SIZE_TO_PAGES(HiveFileSize + MM_PAGE_SIZE - 1) << MM_PAGE_SHIFT,
74 
75  if (HiveDataPhysical == 0)
76  {
77  ArcClose(FileId);
78  UiMessageBox("Unable to alloc memory for a hive!");
79  return FALSE;
80  }
81 
82  /* Convert address to virtual */
83  HiveDataVirtual = PaToVa((PVOID)HiveDataPhysical);
84 
85  /* Fill LoaderBlock's entries */
86  LoaderBlock->RegistryLength = HiveFileSize;
87  LoaderBlock->RegistryBase = HiveDataVirtual;
88 
89  /* Finally read from file to the memory */
90  Status = ArcRead(FileId, (PVOID)HiveDataPhysical, HiveFileSize, &BytesRead);
91  if (Status != ESUCCESS)
92  {
93  ArcClose(FileId);
94  UiMessageBox("Unable to read from hive file!");
95  return FALSE;
96  }
97 
98  /* Add boot filesystem driver to the list */
99  FsService = FsGetServiceName(FileId);
100  if (FsService)
101  {
103  TRACE(" Adding filesystem service %S\n", FsService);
104  Success = WinLdrAddDriverToList(&LoaderBlock->BootDriverListHead,
105  L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
106  NULL,
107  (LPWSTR)FsService);
108  if (!Success)
109  TRACE(" Failed to add filesystem service\n");
110  }
111  else
112  {
113  TRACE(" No required filesystem service\n");
114  }
115 
116  ArcClose(FileId);
117  return TRUE;
118 }
119 
120 BOOLEAN
122  IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
124  IN BOOLEAN Setup)
125 {
126  CHAR SearchPath[1024];
127  PCSTR HiveName;
129 
130  if (Setup)
131  {
133  HiveName = "SETUPREG.HIV";
134  }
135  else
136  {
137  // There is a simple logic here: try to load usual hive (system), if it
138  // fails, then give system.alt a try, and finally try a system.sav
139 
140  // FIXME: For now we only try system
142  strcat(SearchPath, "system32\\config\\");
143  HiveName = "SYSTEM";
144  }
145 
146  TRACE("WinLdrInitSystemHive: loading hive %s%s\n", SearchPath, HiveName);
147  Success = WinLdrLoadSystemHive(LoaderBlock, SearchPath, HiveName);
148 
149  /* Fail if failed... */
150  if (!Success)
151  return FALSE;
152 
153  /* Import what was loaded */
154  Success = RegImportBinaryHive(VaToPa(LoaderBlock->RegistryBase), LoaderBlock->RegistryLength);
155  if (!Success)
156  {
157  UiMessageBox("Importing binary hive failed!");
158  return FALSE;
159  }
160 
161  /* Initialize the 'CurrentControlSet' link */
163  {
164  UiMessageBox("Initializing CurrentControlSet link failed!");
165  return FALSE;
166  }
167 
168  return TRUE;
169 }
170 
172  IN LPCSTR DirectoryPath)
173 {
174  CHAR SearchPath[1024];
175  CHAR AnsiName[256], OemName[256], LangName[256];
177 
178  /* Scan registry and prepare boot drivers list */
179  WinLdrScanRegistry(&LoaderBlock->BootDriverListHead, DirectoryPath);
180 
181  /* Get names of NLS files */
182  Success = WinLdrGetNLSNames(AnsiName, OemName, LangName);
183  if (!Success)
184  {
185  UiMessageBox("Getting NLS names from registry failed!");
186  return FALSE;
187  }
188 
189  TRACE("NLS data %s %s %s\n", AnsiName, OemName, LangName);
190 
191  /* Load NLS data */
192  strcpy(SearchPath, DirectoryPath);
193  strcat(SearchPath, "system32\\");
194  Success = WinLdrLoadNLSData(LoaderBlock, SearchPath, AnsiName, OemName, LangName);
195  TRACE("NLS data loading %s\n", Success ? "successful" : "failed");
196 
197  /* TODO: Load OEM HAL font */
198  // In HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage,
199  // REG_SZ value "OEMHAL"
200 
201  return TRUE;
202 }
203 
204 
205 /* PRIVATE FUNCTIONS ******************************************************/
206 
207 // Queries registry for those three file names
208 static BOOLEAN
210  LPSTR OemName,
211  LPSTR LangName)
212 {
213  LONG rc = ERROR_SUCCESS;
214  HKEY hKey;
215  WCHAR szIdBuffer[80];
216  WCHAR NameBuffer[80];
218 
219  /* open the codepage key */
220  rc = RegOpenKey(NULL,
221  L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage",
222  &hKey);
223  if (rc != ERROR_SUCCESS)
224  {
225  //strcpy(szErrorOut, "Couldn't open CodePage registry key");
226  return FALSE;
227  }
228 
229  /* Get ANSI codepage */
230  BufferSize = sizeof(szIdBuffer);
231  rc = RegQueryValue(hKey, L"ACP", NULL, (PUCHAR)szIdBuffer, &BufferSize);
232  if (rc != ERROR_SUCCESS)
233  {
234  //strcpy(szErrorOut, "Couldn't get ACP NLS setting");
235  return FALSE;
236  }
237 
238  BufferSize = sizeof(NameBuffer);
239  rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)NameBuffer, &BufferSize);
240  if (rc != ERROR_SUCCESS)
241  {
242  //strcpy(szErrorOut, "ACP NLS Setting exists, but isn't readable");
243  //return FALSE;
244  wcscpy(NameBuffer, L"c_1252.nls"); // HACK: ReactOS bug CORE-6105
245  }
246  sprintf(AnsiName, "%S", NameBuffer);
247 
248  /* Get OEM codepage */
249  BufferSize = sizeof(szIdBuffer);
250  rc = RegQueryValue(hKey, L"OEMCP", NULL, (PUCHAR)szIdBuffer, &BufferSize);
251  if (rc != ERROR_SUCCESS)
252  {
253  //strcpy(szErrorOut, "Couldn't get OEMCP NLS setting");
254  return FALSE;
255  }
256 
257  BufferSize = sizeof(NameBuffer);
258  rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)NameBuffer, &BufferSize);
259  if (rc != ERROR_SUCCESS)
260  {
261  //strcpy(szErrorOut, "OEMCP NLS setting exists, but isn't readable");
262  //return FALSE;
263  wcscpy(NameBuffer, L"c_437.nls"); // HACK: ReactOS bug CORE-6105
264  }
265  sprintf(OemName, "%S", NameBuffer);
266 
267  /* Open the language key */
268  rc = RegOpenKey(NULL,
269  L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
270  &hKey);
271  if (rc != ERROR_SUCCESS)
272  {
273  //strcpy(szErrorOut, "Couldn't open Language registry key");
274  return FALSE;
275  }
276 
277  /* Get the Unicode case table */
278  BufferSize = sizeof(szIdBuffer);
279  rc = RegQueryValue(hKey, L"Default", NULL, (PUCHAR)szIdBuffer, &BufferSize);
280  if (rc != ERROR_SUCCESS)
281  {
282  //strcpy(szErrorOut, "Couldn't get Language Default setting");
283  return FALSE;
284  }
285 
286  BufferSize = sizeof(NameBuffer);
287  rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)NameBuffer, &BufferSize);
288  if (rc != ERROR_SUCCESS)
289  {
290  //strcpy(szErrorOut, "Language Default setting exists, but isn't readable");
291  return FALSE;
292  }
293  sprintf(LangName, "%S", NameBuffer);
294 
295  return TRUE;
296 }
297 
298 BOOLEAN
300  IN LPCSTR DirectoryPath,
301  IN LPCSTR AnsiFileName,
302  IN LPCSTR OemFileName,
303  IN LPCSTR LanguageFileName)
304 {
305  CHAR FileName[255];
306  ULONG AnsiFileId;
307  ULONG OemFileId;
308  ULONG LanguageFileId;
309  ULONG AnsiFileSize, OemFileSize, LanguageFileSize;
310  ULONG TotalSize;
311  ULONG_PTR NlsDataBase;
312  PVOID NlsVirtual;
313  BOOLEAN AnsiEqualsOem = FALSE;
317 
318  /* There may be a case, when OEM and ANSI page coincide */
319  if (!strcmp(AnsiFileName, OemFileName))
320  AnsiEqualsOem = TRUE;
321 
322  /* Open file with ANSI and store its size */
323  //Print(L"Loading %s...\n", Filename);
324  strcpy(FileName, DirectoryPath);
325  strcat(FileName, AnsiFileName);
326  Status = ArcOpen(FileName, OpenReadOnly, &AnsiFileId);
327  if (Status != ESUCCESS)
328  goto Failure;
329 
330  Status = ArcGetFileInformation(AnsiFileId, &FileInfo);
331  if (Status != ESUCCESS)
332  goto Failure;
333  AnsiFileSize = FileInfo.EndingAddress.LowPart;
334  TRACE("AnsiFileSize: %d\n", AnsiFileSize);
335  ArcClose(AnsiFileId);
336 
337  /* Open OEM file and store its length */
338  if (AnsiEqualsOem)
339  {
340  OemFileSize = 0;
341  }
342  else
343  {
344  //Print(L"Loading %s...\n", Filename);
345  strcpy(FileName, DirectoryPath);
346  strcat(FileName, OemFileName);
347  Status = ArcOpen(FileName, OpenReadOnly, &OemFileId);
348  if (Status != ESUCCESS)
349  goto Failure;
350 
351  Status = ArcGetFileInformation(OemFileId, &FileInfo);
352  if (Status != ESUCCESS)
353  goto Failure;
354  OemFileSize = FileInfo.EndingAddress.LowPart;
355  ArcClose(OemFileId);
356  }
357  TRACE("OemFileSize: %d\n", OemFileSize);
358 
359  /* And finally open the language codepage file and store its length */
360  //Print(L"Loading %s...\n", Filename);
361  strcpy(FileName, DirectoryPath);
362  strcat(FileName, LanguageFileName);
363  Status = ArcOpen(FileName, OpenReadOnly, &LanguageFileId);
364  if (Status != ESUCCESS)
365  goto Failure;
366 
367  Status = ArcGetFileInformation(LanguageFileId, &FileInfo);
368  if (Status != ESUCCESS)
369  goto Failure;
370  LanguageFileSize = FileInfo.EndingAddress.LowPart;
371  ArcClose(LanguageFileId);
372  TRACE("LanguageFileSize: %d\n", LanguageFileSize);
373 
374  /* Sum up all three length, having in mind that every one of them
375  must start at a page boundary => thus round up each file to a page */
376  TotalSize = MM_SIZE_TO_PAGES(AnsiFileSize) +
377  MM_SIZE_TO_PAGES(OemFileSize) +
378  MM_SIZE_TO_PAGES(LanguageFileSize);
379 
380  /* Store it for later marking the pages as NlsData type */
381  TotalNLSSize = TotalSize;
382 
383  NlsDataBase = (ULONG_PTR)MmAllocateMemoryWithType(TotalSize*MM_PAGE_SIZE, LoaderNlsData);
384 
385  if (NlsDataBase == 0)
386  goto Failure;
387 
388  NlsVirtual = PaToVa((PVOID)NlsDataBase);
389  LoaderBlock->NlsData->AnsiCodePageData = NlsVirtual;
390  LoaderBlock->NlsData->OemCodePageData = (PVOID)((PUCHAR)NlsVirtual +
391  (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT));
392  LoaderBlock->NlsData->UnicodeCodePageData = (PVOID)((PUCHAR)NlsVirtual +
393  (MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT) +
394  (MM_SIZE_TO_PAGES(OemFileSize) << MM_PAGE_SHIFT));
395 
396  /* Ansi and OEM data are the same - just set pointers to the same area */
397  if (AnsiEqualsOem)
398  LoaderBlock->NlsData->OemCodePageData = LoaderBlock->NlsData->AnsiCodePageData;
399 
400 
401  /* Now actually read the data into memory, starting with Ansi file */
402  strcpy(FileName, DirectoryPath);
403  strcat(FileName, AnsiFileName);
404  Status = ArcOpen(FileName, OpenReadOnly, &AnsiFileId);
405  if (Status != ESUCCESS)
406  goto Failure;
407 
408  Status = ArcRead(AnsiFileId, VaToPa(LoaderBlock->NlsData->AnsiCodePageData), AnsiFileSize, &BytesRead);
409  if (Status != ESUCCESS)
410  goto Failure;
411 
412  ArcClose(AnsiFileId);
413 
414  /* OEM now, if it doesn't equal Ansi of course */
415  if (!AnsiEqualsOem)
416  {
417  strcpy(FileName, DirectoryPath);
418  strcat(FileName, OemFileName);
419  Status = ArcOpen(FileName, OpenReadOnly, &OemFileId);
420  if (Status != ESUCCESS)
421  goto Failure;
422 
423  Status = ArcRead(OemFileId, VaToPa(LoaderBlock->NlsData->OemCodePageData), OemFileSize, &BytesRead);
424  if (Status != ESUCCESS)
425  goto Failure;
426 
427  ArcClose(OemFileId);
428  }
429 
430  /* finally the language file */
431  strcpy(FileName, DirectoryPath);
432  strcat(FileName, LanguageFileName);
433  Status = ArcOpen(FileName, OpenReadOnly, &LanguageFileId);
434  if (Status != ESUCCESS)
435  goto Failure;
436 
437  Status = ArcRead(LanguageFileId, VaToPa(LoaderBlock->NlsData->UnicodeCodePageData), LanguageFileSize, &BytesRead);
438  if (Status != ESUCCESS)
439  goto Failure;
440 
441  ArcClose(LanguageFileId);
442 
443  //
444  // THIS IS HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK
445  // Should go to WinLdrLoadOemHalFont(), when it will be implemented
446  //
447  LoaderBlock->OemFontFile = VaToPa(LoaderBlock->NlsData->UnicodeCodePageData);
448 
449  /* Convert NlsTables address to VA */
450  LoaderBlock->NlsData = PaToVa(LoaderBlock->NlsData);
451 
452  return TRUE;
453 
454 Failure:
455  UiMessageBox("Error reading NLS file %s", FileName);
456  return FALSE;
457 }
458 
459 static VOID
461  IN LPCSTR DirectoryPath)
462 {
463  LONG rc = 0;
464  HKEY hGroupKey, hOrderKey, hServiceKey, hDriverKey;
465  LPWSTR GroupNameBuffer;
466  WCHAR ServiceName[256];
467  ULONG OrderList[128];
469  ULONG Index;
470  ULONG TagIndex;
471  LPWSTR GroupName;
472 
473  ULONG ValueSize;
475  ULONG StartValue;
476  ULONG TagValue;
477  WCHAR DriverGroup[256];
478  ULONG DriverGroupSize;
479 
480  CHAR ImagePath[256];
481  WCHAR TempImagePath[256];
482 
484 
485  /* get 'service group order' key */
486  rc = RegOpenKey(NULL,
487  L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder",
488  &hGroupKey);
489  if (rc != ERROR_SUCCESS) {
490 
491  TRACE_CH(REACTOS, "Failed to open the 'ServiceGroupOrder' key (rc %d)\n", (int)rc);
492  return;
493  }
494 
495  /* get 'group order list' key */
496  rc = RegOpenKey(NULL,
497  L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\GroupOrderList",
498  &hOrderKey);
499  if (rc != ERROR_SUCCESS) {
500 
501  TRACE_CH(REACTOS, "Failed to open the 'GroupOrderList' key (rc %d)\n", (int)rc);
502  return;
503  }
504 
505  /* enumerate drivers */
506  rc = RegOpenKey(NULL,
507  L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services",
508  &hServiceKey);
509  if (rc != ERROR_SUCCESS) {
510 
511  TRACE_CH(REACTOS, "Failed to open the 'Services' key (rc %d)\n", (int)rc);
512  return;
513  }
514 
515  /* Get the Name Group */
516  BufferSize = 4096;
517  GroupNameBuffer = FrLdrHeapAlloc(BufferSize, TAG_WLDR_NAME);
518  rc = RegQueryValue(hGroupKey, L"List", NULL, (PUCHAR)GroupNameBuffer, &BufferSize);
519  TRACE_CH(REACTOS, "RegQueryValue(): rc %d\n", (int)rc);
520  if (rc != ERROR_SUCCESS)
521  return;
522  TRACE_CH(REACTOS, "BufferSize: %d \n", (int)BufferSize);
523  TRACE_CH(REACTOS, "GroupNameBuffer: '%S' \n", GroupNameBuffer);
524 
525  /* Loop through each group */
526  GroupName = GroupNameBuffer;
527  while (*GroupName)
528  {
529  TRACE("Driver group: '%S'\n", GroupName);
530 
531  /* Query the Order */
532  BufferSize = sizeof(OrderList);
533  rc = RegQueryValue(hOrderKey, GroupName, NULL, (PUCHAR)OrderList, &BufferSize);
534  if (rc != ERROR_SUCCESS) OrderList[0] = 0;
535 
536  /* enumerate all drivers */
537  for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++)
538  {
539  Index = 0;
540 
541  while (TRUE)
542  {
543  /* Get the Driver's Name */
544  ValueSize = sizeof(ServiceName);
545  rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize, &hDriverKey);
546  TRACE("RegEnumKey(): rc %d\n", (int)rc);
547 
548  /* Make sure it's valid, and check if we're done */
549  if (rc == ERROR_NO_MORE_ITEMS)
550  break;
551  if (rc != ERROR_SUCCESS)
552  {
553  FrLdrHeapFree(GroupNameBuffer, TAG_WLDR_NAME);
554  return;
555  }
556  //TRACE_CH(REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName);
557 
558  /* Read the Start Value */
559  ValueSize = sizeof(ULONG);
560  rc = RegQueryValue(hDriverKey, L"Start", &ValueType, (PUCHAR)&StartValue, &ValueSize);
561  if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1;
562  //TRACE_CH(REACTOS, " Start: %x \n", (int)StartValue);
563 
564  /* Read the Tag */
565  ValueSize = sizeof(ULONG);
566  rc = RegQueryValue(hDriverKey, L"Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize);
567  if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1;
568  //TRACE_CH(REACTOS, " Tag: %x \n", (int)TagValue);
569 
570  /* Read the driver's group */
571  DriverGroupSize = sizeof(DriverGroup);
572  rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize);
573  //TRACE_CH(REACTOS, " Group: '%S' \n", DriverGroup);
574 
575  /* Make sure it should be started */
576  if ((StartValue == 0) &&
577  (TagValue == OrderList[TagIndex]) &&
578  (_wcsicmp(DriverGroup, GroupName) == 0))
579  {
580  /* Get the Driver's Location */
581  ValueSize = sizeof(TempImagePath);
582  rc = RegQueryValue(hDriverKey, L"ImagePath", NULL, (PUCHAR)TempImagePath, &ValueSize);
583 
584  /* Write the whole path if it succeeded, else prepare to fail */
585  if (rc != ERROR_SUCCESS)
586  {
587  TRACE_CH(REACTOS, "ImagePath: not found\n");
588  TempImagePath[0] = 0;
589  sprintf(ImagePath, "%s\\system32\\drivers\\%S.sys", DirectoryPath, ServiceName);
590  }
591  else if (TempImagePath[0] != L'\\')
592  {
593  sprintf(ImagePath, "%s%S", DirectoryPath, TempImagePath);
594  }
595  else
596  {
597  sprintf(ImagePath, "%S", TempImagePath);
598  TRACE_CH(REACTOS, "ImagePath: '%s'\n", ImagePath);
599  }
600 
601  TRACE("Adding boot driver: '%s'\n", ImagePath);
602 
603  Success = WinLdrAddDriverToList(BootDriverListHead,
604  L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
605  TempImagePath,
606  ServiceName);
607  if (!Success)
608  ERR("Failed to add boot driver\n");
609  }
610  else
611  {
612  //TRACE(" Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current Tag %d, current group '%S')\n",
613  // ServiceName, StartValue, TagValue, DriverGroup, OrderList[TagIndex], GroupName);
614  }
615 
616  Index++;
617  }
618  }
619 
620  Index = 0;
621  while (TRUE)
622  {
623  /* Get the Driver's Name */
624  ValueSize = sizeof(ServiceName);
625  rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize, &hDriverKey);
626 
627  //TRACE_CH(REACTOS, "RegEnumKey(): rc %d\n", (int)rc);
628  if (rc == ERROR_NO_MORE_ITEMS)
629  break;
630  if (rc != ERROR_SUCCESS)
631  {
632  FrLdrHeapFree(GroupNameBuffer, TAG_WLDR_NAME);
633  return;
634  }
635  TRACE("Service %d: '%S'\n", (int)Index, ServiceName);
636 
637  /* Read the Start Value */
638  ValueSize = sizeof(ULONG);
639  rc = RegQueryValue(hDriverKey, L"Start", &ValueType, (PUCHAR)&StartValue, &ValueSize);
640  if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1;
641  //TRACE_CH(REACTOS, " Start: %x \n", (int)StartValue);
642 
643  /* Read the Tag */
644  ValueSize = sizeof(ULONG);
645  rc = RegQueryValue(hDriverKey, L"Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize);
646  if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1;
647  //TRACE_CH(REACTOS, " Tag: %x \n", (int)TagValue);
648 
649  /* Read the driver's group */
650  DriverGroupSize = sizeof(DriverGroup);
651  rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize);
652  //TRACE_CH(REACTOS, " Group: '%S' \n", DriverGroup);
653 
654  for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++)
655  {
656  if (TagValue == OrderList[TagIndex]) break;
657  }
658 
659  if ((StartValue == 0) &&
660  (TagIndex > OrderList[0]) &&
661  (_wcsicmp(DriverGroup, GroupName) == 0))
662  {
663  ValueSize = sizeof(TempImagePath);
664  rc = RegQueryValue(hDriverKey, L"ImagePath", NULL, (PUCHAR)TempImagePath, &ValueSize);
665  if (rc != ERROR_SUCCESS)
666  {
667  TRACE_CH(REACTOS, "ImagePath: not found\n");
668  TempImagePath[0] = 0;
669  sprintf(ImagePath, "%ssystem32\\drivers\\%S.sys", DirectoryPath, ServiceName);
670  }
671  else if (TempImagePath[0] != L'\\')
672  {
673  sprintf(ImagePath, "%s%S", DirectoryPath, TempImagePath);
674  }
675  else
676  {
677  sprintf(ImagePath, "%S", TempImagePath);
678  TRACE_CH(REACTOS, "ImagePath: '%s'\n", ImagePath);
679  }
680  TRACE(" Adding boot driver: '%s'\n", ImagePath);
681 
682  Success = WinLdrAddDriverToList(BootDriverListHead,
683  L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
684  TempImagePath,
685  ServiceName);
686  if (!Success)
687  ERR(" Failed to add boot driver\n");
688  }
689  else
690  {
691  //TRACE(" Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current group '%S')\n",
692  // ServiceName, StartValue, TagValue, DriverGroup, GroupName);
693  }
694 
695  Index++;
696  }
697 
698  /* Move to the next group name */
699  GroupName = GroupName + wcslen(GroupName) + 1;
700  }
701 
702  /* Free allocated memory */
703  FrLdrHeapFree(GroupNameBuffer, TAG_WLDR_NAME);
704 }
705 
706 static
707 BOOLEAN
709  PLIST_ENTRY BootDriverListHead,
710  PBOOT_DRIVER_LIST_ENTRY BootDriverEntry)
711 {
713  PLIST_ENTRY ListEntry;
714 
715  ASSERT(BootDriverEntry->FilePath.Buffer != NULL);
716  ASSERT(BootDriverEntry->RegistryPath.Buffer != NULL);
717 
718  for (ListEntry = BootDriverListHead->Flink;
719  ListEntry != BootDriverListHead;
720  ListEntry = ListEntry->Flink)
721  {
722  DriverEntry = CONTAINING_RECORD(ListEntry,
724  Link);
725  if ((DriverEntry->FilePath.Buffer != NULL) &&
726  RtlEqualUnicodeString(&BootDriverEntry->FilePath,
727  &DriverEntry->FilePath,
728  TRUE))
729  {
730  return FALSE;
731  }
732 
733  if ((DriverEntry->RegistryPath.Buffer != NULL) &&
734  RtlEqualUnicodeString(&BootDriverEntry->RegistryPath,
735  &DriverEntry->RegistryPath,
736  TRUE))
737  {
738  return FALSE;
739  }
740  }
741 
742  InsertTailList(BootDriverListHead, &BootDriverEntry->Link);
743  return TRUE;
744 }
745 
746 BOOLEAN
747 WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead,
749  LPWSTR ImagePath,
751 {
752  PBOOT_DRIVER_LIST_ENTRY BootDriverEntry;
755 
756  BootDriverEntry = FrLdrHeapAlloc(sizeof(BOOT_DRIVER_LIST_ENTRY), TAG_WLDR_BDE);
757 
758  if (!BootDriverEntry)
759  return FALSE;
760 
761  // DTE will be filled during actual load of the driver
762  BootDriverEntry->LdrEntry = NULL;
763 
764  // Check - if we have a valid ImagePath, if not - we need to build it
765  // like "System32\\Drivers\\blah.sys"
766  if (ImagePath && (ImagePath[0] != 0))
767  {
768  // Just copy ImagePath to the corresponding field in the structure
769  PathLength = (USHORT)wcslen(ImagePath) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
770 
771  BootDriverEntry->FilePath.Length = 0;
772  BootDriverEntry->FilePath.MaximumLength = PathLength;
774 
775  if (!BootDriverEntry->FilePath.Buffer)
776  {
777  FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE);
778  return FALSE;
779  }
780 
781  Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ImagePath);
782  if (!NT_SUCCESS(Status))
783  {
784  FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME);
785  FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE);
786  return FALSE;
787  }
788  }
789  else
790  {
791  // we have to construct ImagePath ourselves
792  PathLength = (USHORT)wcslen(ServiceName)*sizeof(WCHAR) + sizeof(L"system32\\drivers\\.sys");
793  BootDriverEntry->FilePath.Length = 0;
794  BootDriverEntry->FilePath.MaximumLength = PathLength;
796 
797  if (!BootDriverEntry->FilePath.Buffer)
798  {
799  FrLdrHeapFree(BootDriverEntry, TAG_WLDR_NAME);
800  return FALSE;
801  }
802 
803  Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L"system32\\drivers\\");
804  if (!NT_SUCCESS(Status))
805  {
806  FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME);
807  FrLdrHeapFree(BootDriverEntry, TAG_WLDR_NAME);
808  return FALSE;
809  }
810 
811  Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ServiceName);
812  if (!NT_SUCCESS(Status))
813  {
814  FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME);
815  FrLdrHeapFree(BootDriverEntry, TAG_WLDR_NAME);
816  return FALSE;
817  }
818 
819  Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L".sys");
820  if (!NT_SUCCESS(Status))
821  {
822  FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME);
823  FrLdrHeapFree(BootDriverEntry, TAG_WLDR_NAME);
824  return FALSE;
825  }
826  }
827 
828  // Add registry path
830  BootDriverEntry->RegistryPath.Length = 0;
831  BootDriverEntry->RegistryPath.MaximumLength = PathLength;
833  if (!BootDriverEntry->RegistryPath.Buffer)
834  return FALSE;
835 
837  if (!NT_SUCCESS(Status))
838  return FALSE;
839 
841  if (!NT_SUCCESS(Status))
842  return FALSE;
843 
844  // Insert entry into the list
845  if (!InsertInBootDriverList(BootDriverListHead, BootDriverEntry))
846  {
847  // It was already there, so delete our entry
848  if (BootDriverEntry->FilePath.Buffer) FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME);
849  if (BootDriverEntry->RegistryPath.Buffer) FrLdrHeapFree(BootDriverEntry->RegistryPath.Buffer, TAG_WLDR_NAME);
850  FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE);
851  }
852 
853  return TRUE;
854 }
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
FORCEINLINE VOID FrLdrHeapFree(PVOID MemoryPointer, ULONG Tag)
Definition: mm.h:170
#define ERROR_SUCCESS
Definition: deptool.c:10
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:816
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:95
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: arc.h:32
BOOLEAN RegImportBinaryHive(_In_ PVOID ChunkBase, _In_ ULONG ChunkSize)
Definition: registry.c:56
unsigned char * PUCHAR
Definition: retypes.h:3
char CHAR
Definition: xmlstorage.h:175
_In_ PCWSTR _In_z_ PCWSTR _In_ ULONG ValueType
Definition: rtlfuncs.h:4000
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead, LPWSTR RegistryPath, LPWSTR ImagePath, LPWSTR ServiceName)
Definition: wlregistry.c:747
ULONG ARC_STATUS
Definition: arc.h:4
#define InsertTailList(ListHead, Entry)
char * LPSTR
Definition: xmlstorage.h:182
static USHORT PathLength
UNICODE_STRING FilePath
Definition: arc.h:201
static int Link(const char **args)
Definition: vfdcmd.c:2414
LONG RegInitCurrentControlSet(_In_ BOOLEAN LastKnownGood)
Definition: registry.c:93
#define SearchPath
Definition: winbase.h:3714
uint32_t ULONG_PTR
Definition: typedefs.h:63
Definition: arc.h:198
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define UNICODE_NULL
long LONG
Definition: pedump.c:60
VOID UiMessageBox(PCSTR Format,...)
Definition: ui.c:347
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
BOOLEAN WinLdrInitSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN PCSTR SystemRoot, IN BOOLEAN Setup)
Definition: wlregistry.c:121
const char * LPCSTR
Definition: xmlstorage.h:183
void * PVOID
Definition: retypes.h:9
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define RegEnumKey
Definition: winreg.h:509
FORCEINLINE PVOID FrLdrHeapAlloc(SIZE_T MemorySize, ULONG Tag)
Definition: mm.h:163
#define TRACE(s)
Definition: solgame.cpp:4
LPTSTR ServiceName
Definition: ServiceMain.c:15
static const WCHAR SystemRoot[]
Definition: reg.c:38
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define MAX_PATH
Definition: compat.h:26
static const UCHAR Index[8]
Definition: usbohci.c:18
#define BufferSize
Definition: classpnp.h:419
BOOLEAN WinLdrScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN LPCSTR DirectoryPath)
Definition: wlregistry.c:171
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: fs.c:237
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
BOOLEAN WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN LPCSTR DirectoryPath, IN LPCSTR AnsiFileName, IN LPCSTR OemFileName, IN LPCSTR LanguageFileName)
Definition: wlregistry.c:299
PVOID MmAllocateMemoryWithType(SIZE_T MemorySize, TYPE_OF_MEMORY MemoryType)
Definition: mm.c:31
static VOID WinLdrScanRegistry(IN OUT PLIST_ENTRY BootDriverListHead, IN LPCSTR DirectoryPath)
Definition: wlregistry.c:460
#define TAG_WLDR_NAME
Definition: winldr.h:28
Definition: typedefs.h:117
static BOOLEAN WinLdrGetNLSNames(LPSTR AnsiName, LPSTR OemName, LPSTR LangName)
Definition: wlregistry.c:209
Status
Definition: gdiplustypes.h:24
DBG_DEFAULT_CHANNEL(WINDOWS)
#define ERR(fmt,...)
Definition: debug.h:109
#define TRACE_CH(ch, fmt,...)
Definition: debug.h:107
UNICODE_STRING RegistryPath
Definition: arc.h:202
DRIVER_INITIALIZE DriverEntry
Definition: condrv.c:21
unsigned short USHORT
Definition: pedump.c:61
struct _LDR_DATA_TABLE_ENTRY * LdrEntry
Definition: arc.h:203
static BOOLEAN WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, IN PCSTR DirectoryPath, IN PCSTR HiveName)
Definition: wlregistry.c:34
ULONG TotalNLSSize
Definition: wlregistry.c:19
ARC_STATUS ArcClose(ULONG FileId)
Definition: fs.c:219
LIST_ENTRY Link
Definition: arc.h:200
ARC_STATUS ArcGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
Definition: fs.c:251
#define OUT
Definition: typedefs.h:39
struct FileInfo FileInfo
FORCEINLINE PVOID PaToVa(PVOID Pa)
Definition: conversion.h:22
#define RegQueryValue
Definition: winreg.h:523
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
ARC_STATUS ArcOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
Definition: fs.c:57
unsigned int ULONG
Definition: retypes.h:1
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define ULONG_PTR
Definition: config.h:101
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
FORCEINLINE PVOID VaToPa(PVOID Va)
Definition: conversion.h:15
const char * PCSTR
Definition: typedefs.h:51
WCHAR * LPWSTR
Definition: xmlstorage.h:184
IN PDCB IN POEM_STRING OemName
Definition: fatprocs.h:1294
#define RegOpenKey
Definition: winreg.h:519
LPCWSTR FsGetServiceName(ULONG FileId)
Definition: fs.c:460
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesRead
Definition: fltkernel.h:1255
#define TAG_WLDR_BDE
Definition: winldr.h:27
static BOOLEAN InsertInBootDriverList(PLIST_ENTRY BootDriverListHead, PBOOT_DRIVER_LIST_ENTRY BootDriverEntry)
Definition: wlregistry.c:708