ReactOS  r75907
cmhardwr.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/config/i386/cmhardwr.c
5  * PURPOSE: Configuration Manager - Hardware-Specific Code
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include "ntoskrnl.h"
12 #define NDEBUG
13 #include "debug.h"
14 
15 /* GLOBALS *******************************************************************/
16 
17 PCHAR CmpID1 = "80%u86-%c%x";
18 PCHAR CmpID2 = "x86 Family %u Model %u Stepping %u";
20 {
21  "Ver",
22  "Rev",
23  "Rel",
24  "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9",
25  "v 0", "v 1", "v 2", "v 3", "v 4", "v 5", "v 6", "v 7", "v 8", "v 9",
26  NULL
27 };
28 
30 
31 /* FUNCTIONS *****************************************************************/
32 
33 BOOLEAN
34 NTAPI
36  IN ULONG BiosLength,
38  IN BOOLEAN FromBios)
39 {
40  CHAR LastDate[11] = {0}, CurrentDate[11];
41  PCHAR p, pp;
42 
43  /* Skip the signature and the magic, and loop the BIOS ROM */
44  p = BiosStart + 2;
45  pp = BiosStart + BiosLength - 5;
46  while (p < pp)
47  {
48  /* Check for xx/yy/zz which we assume to be a date */
49  if ((p[0] == '/') &&
50  (p[3] == '/') &&
51  (isdigit(p[-1])) &&
52  (isdigit(p[1])) &&
53  (isdigit(p[2])) &&
54  (isdigit(p[4])) &&
55  (isdigit(p[5])))
56  {
57  /* Copy the string proper */
58  RtlMoveMemory(&CurrentDate[5], p - 2, 5);
59 
60  /* Add a 0 if the month only has one digit */
61  if (!isdigit(CurrentDate[5])) CurrentDate[5] = '0';
62 
63  /* Now copy the year */
64  CurrentDate[2] = p[4];
65  CurrentDate[3] = p[5];
66  CurrentDate[4] = CurrentDate[7] = CurrentDate[10] = ANSI_NULL;
67 
68  /* If the date comes from the BIOS, check if it's a 4-digit year */
69  if ((FromBios) &&
70  (isdigit(p[6])) &&
71  (isdigit(p[7])) &&
72  ((RtlEqualMemory(&p[4], "19", 2)) ||
73  (RtlEqualMemory(&p[4], "20", 2))))
74  {
75  /* Copy the year proper */
76  CurrentDate[0] = p[4];
77  CurrentDate[1] = p[5];
78  CurrentDate[2] = p[6];
79  CurrentDate[3] = p[7];
80  }
81  else
82  {
83  /* Otherwise, we'll just assume anything under 80 is 2000 */
84  if (strtoul(&CurrentDate[2], NULL, 10) < 80)
85  {
86  /* Hopefully your BIOS wasn't made in 1979 */
87  CurrentDate[0] = '2';
88  CurrentDate[1] = '0';
89  }
90  else
91  {
92  /* Anything over 80, was probably made in the 1900s... */
93  CurrentDate[0] = '1';
94  CurrentDate[1] = '9';
95  }
96  }
97 
98  /* Add slashes where we previously had NULLs */
99  CurrentDate[4] = CurrentDate[7] = '/';
100 
101  /* Check which date is newer */
102  if (memcmp(LastDate, CurrentDate, 10) < 0)
103  {
104  /* Found a newer date, select it */
105  RtlMoveMemory(LastDate, CurrentDate, 10);
106  }
107 
108  p += 2;
109  }
110  p++;
111  }
112 
113  /* Make sure we found a date */
114  if (LastDate[0])
115  {
116  /* Copy the year at the pp, and keep only the last two digits */
117  RtlMoveMemory(BiosDate, &LastDate[5], 5);
118  BiosDate[5] = '/';
119  BiosDate[6] = LastDate[2];
120  BiosDate[7] = LastDate[3];
121  BiosDate[8] = ANSI_NULL;
122  return TRUE;
123  }
124 
125  /* No date found, return empty string */
126  BiosDate[0] = ANSI_NULL;
127  return FALSE;
128 }
129 
130 BOOLEAN
131 NTAPI
133  IN ULONG BiosLength,
135 {
136  CHAR Buffer[128];
137  PCHAR p, pp;
138  USHORT i;
139 
140  /* Check if we were given intitial data for the search */
141  if (BiosStart)
142  {
143  /* Save it for later use */
144  CmpBiosBegin = BiosStart;
145  CmpBiosSearchStart = BiosStart + 1;
146  CmpBiosSearchEnd = BiosStart + BiosLength - 2;
147  }
148 
149  /* Now loop the BIOS area */
150  for (;;)
151  {
152  /* Start an initial search looking for numbers and periods */
153  pp = NULL;
155  {
156  /* Check if we have an "x.y" version string */
157  if ((*CmpBiosSearchStart == '.') &&
158  (*(CmpBiosSearchStart + 1) >= '0') &&
159  (*(CmpBiosSearchStart + 1) <= '9') &&
160  (*(CmpBiosSearchStart - 1) >= '0') &&
161  (*(CmpBiosSearchStart - 1) <= '9'))
162  {
163  /* Start looking in this area for the actual BIOS Version */
164  pp = CmpBiosSearchStart;
165  break;
166  }
167  else
168  {
169  /* Keep searching */
171  }
172  }
173 
174  /* Break out if we're went past the BIOS area */
176 
177  /* Move to the next 2 bytes */
178  CmpBiosSearchStart += 2;
179 
180  /* Null-terminate our scratch buffer and start the string here */
181  Buffer[127] = ANSI_NULL;
182  p = &Buffer[127];
183 
184  /* Go back one character since we're doing this backwards */
185  pp--;
186 
187  /* Loop the identifier we found as long as it's valid */
188  i = 0;
189  while ((i++ < 127) &&
190  (pp >= CmpBiosBegin) &&
191  (*pp >= ' ') &&
192  (*pp != '$'))
193  {
194  /* Copy the character */
195  *--p = *pp--;
196  }
197 
198  /* Go past the last character since we went backwards */
199  pp++;
200 
201  /* Loop the strings we recognize */
202  for (i = 0; CmpBiosStrings[i]; i++)
203  {
204  /* Check if a match was found */
205  if (strstr(p, CmpBiosStrings[i])) goto Match;
206  }
207  }
208 
209 Match:
210  /* Skip until we find a space */
211  for (; *pp == ' '; pp++);
212 
213  /* Loop the final string */
214  i = 0;
215  do
216  {
217  /* Copy the character into the final string */
218  BiosVersion[i] = *pp++;
219  } while ((++i < 127) &&
220  (pp <= (CmpBiosSearchEnd + 1)) &&
221  (*pp >= ' ') &&
222  (*pp != '$'));
223 
224  /* Null-terminate the version string */
225  BiosVersion[i] = ANSI_NULL;
226  return TRUE;
227 }
228 
229 VOID
230 NTAPI
232 {
233  CPU_INFO CpuInfo;
234  ULONG BrandId, Signature;
235 
236  /* Get the Brand Id */
237  KiCpuId(&CpuInfo, 0x00000001);
238  Signature = CpuInfo.Eax;
239  BrandId = CpuInfo.Ebx & 0xFF;
240 
241  switch (BrandId)
242  {
243  case 0x01:
244  strcpy(CpuString, "Intel(R) Celeron(R) processor");
245  break;
246  case 0x02:
247  case 0x04:
248  strcpy(CpuString, "Intel(R) Pentium(R) III processor");
249  break;
250  case 0x03:
251  if(Signature == 0x000006B1)
252  strcpy(CpuString, "Intel(R) Celeron(R) processor");
253  else
254  strcpy(CpuString, "Intel(R) Pentium(R) III Xeon(R) processor");
255  break;
256  case 0x06:
257  strcpy(CpuString, "Mobile Intel(R) Pentium(R) III Processor-M");
258  break;
259  case 0x08:
260  if(Signature >= 0x00000F13)
261  strcpy(CpuString, "Intel(R) Genuine Processor");
262  else
263  strcpy(CpuString, "Intel(R) Pentium(R) 4 processor");
264  break;
265  case 0x09:
266  strcpy(CpuString, "Intel(R) Pentium(R) 4 processor");
267  break;
268  case 0x0B:
269  if(Signature >= 0x00000F13)
270  strcpy(CpuString, "Intel(R) Xeon(R) processor");
271  else
272  strcpy(CpuString, "Intel(R) Xeon(R) processor MP");
273  break;
274  case 0x0C:
275  strcpy(CpuString, "Intel(R) Xeon(R) processor MP");
276  break;
277  case 0x0E:
278  if(Signature >= 0x00000F13)
279  strcpy(CpuString, "Mobile Intel(R) Pentium(R) 4 processor-M");
280  else
281  strcpy(CpuString, "Intel(R) Xeon(R) processor");
282  break;
283  case 0x12:
284  strcpy(CpuString, "Intel(R) Celeron(R) M processor");
285  break;
286  case 0x07:
287  case 0x0F:
288  case 0x13:
289  case 0x17:
290  strcpy(CpuString, "Mobile Intel(R) Celeron(R) processor");
291  break;
292  case 0x0A:
293  case 0x14:
294  strcpy(CpuString, "Intel(R) Celeron(R) Processor");
295  break;
296  case 0x15:
297  strcpy(CpuString, "Mobile Genuine Intel(R) Processor");
298  break;
299  case 0x16:
300  strcpy(CpuString, "Intel(R) Pentium(R) M processor");
301  break;
302  default:
303  strcpy(CpuString, "Unknown Intel processor");
304  }
305 }
306 
307 VOID
308 NTAPI
310 {
311  /* Check if we have a Vendor String */
312  if (Prcb->VendorString[0])
313  {
314  strcpy(CpuString, Prcb->VendorString);
315  }
316  else
317  {
318  strcpy(CpuString, "Unknown x86 processor");
319  }
320 }
321 
322 NTSTATUS
323 NTAPI
325 {
326  UNICODE_STRING KeyName, ValueName, Data, SectionName;
328  ULONG HavePae, Length, TotalLength = 0, i, Disposition;
331  HANDLE KeyHandle, BiosHandle, SystemHandle, FpuHandle, SectionHandle;
332  CONFIGURATION_COMPONENT_DATA ConfigData;
333  CHAR Buffer[128];
334  CPU_INFO CpuInfo;
335  ULONG VendorId, ExtendedId;
336  PKPRCB Prcb;
337  USHORT IndexTable[MaximumType + 1] = {0};
338  ANSI_STRING TempString;
339  PCHAR PartialString = NULL, BiosVersion;
340  CHAR CpuString[48];
342  LARGE_INTEGER ViewBase = {{0, 0}};
343  ULONG_PTR VideoRomBase;
344  PCHAR CurrentVersion;
347 
348  /* Open the SMSS Memory Management key */
349  RtlInitUnicodeString(&KeyName,
350  L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\"
351  L"Control\\Session Manager\\Memory Management");
352  InitializeObjectAttributes(&ObjectAttributes,
353  &KeyName,
355  NULL,
356  NULL);
357  Status = NtOpenKey(&KeyHandle, KEY_READ | KEY_WRITE, &ObjectAttributes);
358  if (NT_SUCCESS(Status))
359  {
360  /* Detect if PAE is enabled */
361  HavePae = SharedUserData->ProcessorFeatures[PF_PAE_ENABLED];
362 
363  /* Set the value */
364  RtlInitUnicodeString(&ValueName, L"PhysicalAddressExtension");
365  NtSetValueKey(KeyHandle,
366  &ValueName,
367  0,
368  REG_DWORD,
369  &HavePae,
370  sizeof(HavePae));
371 
372  /* Close the key */
373  NtClose(KeyHandle);
374  }
375 
376  /* Open the hardware description key */
377  RtlInitUnicodeString(&KeyName,
378  L"\\Registry\\Machine\\Hardware\\Description\\System");
379  InitializeObjectAttributes(&ObjectAttributes,
380  &KeyName,
382  NULL,
383  NULL);
384  Status = NtOpenKey(&SystemHandle, KEY_READ | KEY_WRITE, &ObjectAttributes);
385  if (!NT_SUCCESS(Status))
386  return Status;
387 
388  /* Create the BIOS Information key */
389  RtlInitUnicodeString(&KeyName,
390  L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\"
391  L"Control\\BIOSINFO");
392  InitializeObjectAttributes(&ObjectAttributes,
393  &KeyName,
395  NULL,
396  NULL);
397  Status = NtCreateKey(&BiosHandle,
399  &ObjectAttributes,
400  0,
401  NULL,
403  &Disposition);
404  if (ExpInTextModeSetup)
405  {
406  if (!NT_SUCCESS(Status))
407  BiosHandle = NULL;
408  }
409  else if (!NT_SUCCESS(Status))
410  {
411  NtClose(SystemHandle);
412  return Status;
413  }
414 
415  /* Create the CPU Key, and check if it already existed */
416  RtlInitUnicodeString(&KeyName, L"CentralProcessor");
417  InitializeObjectAttributes(&ObjectAttributes,
418  &KeyName,
420  SystemHandle,
421  NULL);
422  Status = NtCreateKey(&KeyHandle,
424  &ObjectAttributes,
425  0,
426  NULL,
427  0,
428  &Disposition);
429  NtClose(KeyHandle);
430 
431  /* The key shouldn't already exist */
432  if (Disposition == REG_CREATED_NEW_KEY)
433  {
434  /* Allocate the configuration data for cmconfig.c */
437  TAG_CM);
439  {
440  // FIXME: Cleanup stuff!!
442  }
443 
444  /* Loop all CPUs */
445  for (i = 0; i < KeNumberProcessors; i++)
446  {
447  /* Get the PRCB */
448  Prcb = KiProcessorBlock[i];
449 
450  /* Setup the Configuration Entry for the Processor */
451  RtlZeroMemory(&ConfigData, sizeof(ConfigData));
452  ConfigData.ComponentEntry.Class = ProcessorClass;
453  ConfigData.ComponentEntry.Type = CentralProcessor;
454  ConfigData.ComponentEntry.Key = i;
456  ConfigData.ComponentEntry.Identifier = Buffer;
457 
458  /* Check if the CPU doesn't support CPUID */
459  if (!Prcb->CpuID)
460  {
461  /* Build ID1-style string for older CPUs */
462  sprintf(Buffer,
463  CmpID1,
464  Prcb->CpuType,
465  (Prcb->CpuStep >> 8) + 'A',
466  Prcb->CpuStep & 0xff);
467  }
468  else
469  {
470  /* Build ID2-style string for newer CPUs */
471  sprintf(Buffer,
472  CmpID2,
473  Prcb->CpuType,
474  (Prcb->CpuStep >> 8),
475  Prcb->CpuStep & 0xff);
476  }
477 
478  /* Save the ID string length now that we've created it */
479  ConfigData.ComponentEntry.IdentifierLength = (ULONG)strlen(Buffer) + 1;
480 
481  /* Initialize the registry configuration node for it */
482  Status = CmpInitializeRegistryNode(&ConfigData,
483  SystemHandle,
484  &KeyHandle,
486  0xFFFFFFFF,
487  IndexTable);
488  if (!NT_SUCCESS(Status))
489  {
490  NtClose(BiosHandle);
491  NtClose(SystemHandle);
492  return Status;
493  }
494 
495  /* Check if we have an FPU */
496  if (KeI386NpxPresent)
497  {
498  /* Setup the Configuration Entry for the FPU */
499  RtlZeroMemory(&ConfigData, sizeof(ConfigData));
500  ConfigData.ComponentEntry.Class = ProcessorClass;
501  ConfigData.ComponentEntry.Type = FloatingPointProcessor;
502  ConfigData.ComponentEntry.Key = i;
504  ConfigData.ComponentEntry.Identifier = Buffer;
505 
506  /* For 386 cpus, the CPU pp is the identifier */
507  if (Prcb->CpuType == 3) strcpy(Buffer, "80387");
508 
509  /* Save the ID string length now that we've created it */
510  ConfigData.ComponentEntry.IdentifierLength = (ULONG)strlen(Buffer) + 1;
511 
512  /* Initialize the registry configuration node for it */
513  Status = CmpInitializeRegistryNode(&ConfigData,
514  SystemHandle,
515  &FpuHandle,
517  0xFFFFFFFF,
518  IndexTable);
519  if (!NT_SUCCESS(Status))
520  {
521  /* We failed, close all the opened handles and return */
522  NtClose(KeyHandle);
523  NtClose(BiosHandle);
524  NtClose(SystemHandle);
525  return Status;
526  }
527 
528  /* Close this new handle */
529  NtClose(FpuHandle);
530 
531  /* Stay on this CPU only */
533  if (!Prcb->CpuID)
534  {
535  /* Uh oh, no CPUID! */
536  PartialString = CpuString;
537  CmpGetVendorString(Prcb, PartialString);
538  }
539  else
540  {
541  /* Check if we have extended CPUID that supports name ID */
542  KiCpuId(&CpuInfo, 0x80000000);
543  ExtendedId = CpuInfo.Eax;
544  if (ExtendedId >= 0x80000004)
545  {
546  /* Do all the CPUIDs required to get the full name */
547  PartialString = CpuString;
548  for (ExtendedId = 2; ExtendedId <= 4; ExtendedId++)
549  {
550  /* Do the CPUID and save the name string */
551  KiCpuId(&CpuInfo, 0x80000000 | ExtendedId);
552  ((PULONG)PartialString)[0] = CpuInfo.Eax;
553  ((PULONG)PartialString)[1] = CpuInfo.Ebx;
554  ((PULONG)PartialString)[2] = CpuInfo.Ecx;
555  ((PULONG)PartialString)[3] = CpuInfo.Edx;
556 
557  /* Go to the next name string */
558  PartialString += 16;
559  }
560 
561  /* Null-terminate it */
562  CpuString[47] = ANSI_NULL;
563  }
564  else
565  {
566  KiCpuId(&CpuInfo, 0x00000000);
567  VendorId = CpuInfo.Ebx;
568  PartialString = CpuString;
569  switch (VendorId)
570  {
571  case 'uneG': /* Intel */
572  CmpGetIntelBrandString(PartialString);
573  break;
574  case 'htuA': /* AMD */
575  /* FIXME */
576  CmpGetVendorString(Prcb, PartialString);
577  break;
578  default:
579  CmpGetVendorString(Prcb, PartialString);
580  }
581  }
582  }
583 
584  /* Go back to user affinity */
586 
587  /* Check if we have a CPU Name */
588  if (PartialString)
589  {
590  /* Convert it to Unicode */
591  RtlInitAnsiString(&TempString, CpuString);
592  RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
593 
594  /* Add it to the registry */
595  RtlInitUnicodeString(&ValueName, L"ProcessorNameString");
596  Status = NtSetValueKey(KeyHandle,
597  &ValueName,
598  0,
599  REG_SZ,
600  Data.Buffer,
601  Data.Length + sizeof(UNICODE_NULL));
602 
603  /* ROS: Save a copy for bugzilla reporting */
604  RtlCreateUnicodeString(&KeRosProcessorName, Data.Buffer);
605 
606  /* Free the temporary buffer */
607  RtlFreeUnicodeString(&Data);
608  }
609 
610  /* Check if we had a Vendor ID */
611  if (Prcb->VendorString[0])
612  {
613  /* Convert it to Unicode */
614  RtlInitAnsiString(&TempString, Prcb->VendorString);
615  RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
616 
617  /* Add it to the registry */
618  RtlInitUnicodeString(&ValueName, L"VendorIdentifier");
619  Status = NtSetValueKey(KeyHandle,
620  &ValueName,
621  0,
622  REG_SZ,
623  Data.Buffer,
624  Data.Length + sizeof(UNICODE_NULL));
625 
626  /* Free the temporary buffer */
627  RtlFreeUnicodeString(&Data);
628  }
629 
630  /* Check if we have features bits */
631  if (Prcb->FeatureBits)
632  {
633  /* Add them to the registry */
634  RtlInitUnicodeString(&ValueName, L"FeatureSet");
635  Status = NtSetValueKey(KeyHandle,
636  &ValueName,
637  0,
638  REG_DWORD,
639  &Prcb->FeatureBits,
640  sizeof(Prcb->FeatureBits));
641  }
642 
643  /* Check if we detected the CPU Speed */
644  if (Prcb->MHz)
645  {
646  /* Add it to the registry */
647  RtlInitUnicodeString(&ValueName, L"~MHz");
648  Status = NtSetValueKey(KeyHandle,
649  &ValueName,
650  0,
651  REG_DWORD,
652  &Prcb->MHz,
653  sizeof(Prcb->MHz));
654  }
655 
656  /* Check if we have an update signature */
657  if (Prcb->UpdateSignature.QuadPart)
658  {
659  /* Add it to the registry */
660  RtlInitUnicodeString(&ValueName, L"Update Signature");
661  Status = NtSetValueKey(KeyHandle,
662  &ValueName,
663  0,
664  REG_BINARY,
665  &Prcb->UpdateSignature,
666  sizeof(Prcb->UpdateSignature));
667  }
668 
669  /* Close the processor handle */
670  NtClose(KeyHandle);
671 
672  /* FIXME: Detect CPU mismatches */
673  }
674  }
675 
676  /* Free the configuration data */
678  }
679 
680  /* Open physical memory */
681  RtlInitUnicodeString(&SectionName, L"\\Device\\PhysicalMemory");
682  InitializeObjectAttributes(&ObjectAttributes,
683  &SectionName,
685  NULL,
686  NULL);
687  Status = ZwOpenSection(&SectionHandle,
689  &ObjectAttributes);
690  if (!NT_SUCCESS(Status))
691  {
692  /* We failed, close all the opened handles and return */
693  // NtClose(KeyHandle);
694  NtClose(BiosHandle);
695  NtClose(SystemHandle);
696  /* 'Quickie' closes KeyHandle */
697  goto Quickie;
698  }
699 
700  /* Map the first 1KB of memory to get the IVT */
701  ViewSize = PAGE_SIZE;
702  Status = ZwMapViewOfSection(SectionHandle,
704  &BaseAddress,
705  0,
706  ViewSize,
707  &ViewBase,
708  &ViewSize,
709  ViewUnmap,
710  MEM_DOS_LIM,
712  if (!NT_SUCCESS(Status))
713  {
714  /* Assume default */
715  VideoRomBase = 0xC0000;
716  }
717  else
718  {
719  /* Calculate the base address from the vector */
720  VideoRomBase = (*((PULONG)BaseAddress + 0x10) >> 12) & 0xFFFF0;
721  VideoRomBase += *((PULONG)BaseAddress + 0x10) & 0xFFF0;
722 
723  /* Now get to the actual ROM Start and make sure it's not invalid*/
724  VideoRomBase &= 0xFFFF8000;
725  if (VideoRomBase < 0xC0000) VideoRomBase = 0xC0000;
726 
727  /* And unmap the section */
728  ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
729  }
730 
731  /* Allocate BIOS Version pp Buffer */
733 
734  /* Setup settings to map the 64K BIOS ROM */
735  BaseAddress = 0;
736  ViewSize = 16 * PAGE_SIZE;
737  ViewBase.LowPart = 0xF0000;
738  ViewBase.HighPart = 0;
739 
740  /* Map it */
741  Status = ZwMapViewOfSection(SectionHandle,
743  &BaseAddress,
744  0,
745  ViewSize,
746  &ViewBase,
747  &ViewSize,
748  ViewUnmap,
749  MEM_DOS_LIM,
751  if (NT_SUCCESS(Status))
752  {
753  /* Scan the ROM to get the BIOS Date */
754  if (CmpGetBiosDate(BaseAddress, 16 * PAGE_SIZE, Buffer, TRUE))
755  {
756  /* Convert it to Unicode */
757  RtlInitAnsiString(&TempString, Buffer);
758  RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
759 
760  /* Write the date into the registry */
761  RtlInitUnicodeString(&ValueName, L"SystemBiosDate");
762  Status = NtSetValueKey(SystemHandle,
763  &ValueName,
764  0,
765  REG_SZ,
766  Data.Buffer,
767  Data.Length + sizeof(UNICODE_NULL));
768 
769  /* Free the string */
770  RtlFreeUnicodeString(&Data);
771 
772  if (BiosHandle)
773  {
774  /* Get the BIOS Date Identifier */
775  RtlCopyMemory(Buffer, (PCHAR)BaseAddress + (16 * PAGE_SIZE - 11), 8);
776  Buffer[8] = ANSI_NULL;
777 
778  /* Convert it to unicode */
779  RtlInitAnsiString(&TempString, Buffer);
780  Status = RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
781  if (NT_SUCCESS(Status))
782  {
783  /* Save it to the registry */
784  Status = NtSetValueKey(BiosHandle,
785  &ValueName,
786  0,
787  REG_SZ,
788  Data.Buffer,
789  Data.Length + sizeof(UNICODE_NULL));
790 
791  /* ROS: Save a copy for bugzilla reporting */
792  RtlCreateUnicodeString(&KeRosBiosDate, Data.Buffer);
793 
794  /* Free the string */
795  RtlFreeUnicodeString(&Data);
796  }
797 
798  /* Close the bios information handle */
799  NtClose(BiosHandle);
800  }
801  }
802 
803  /* Get the BIOS Version */
804  if (CmpGetBiosVersion(BaseAddress, 16 * PAGE_SIZE, Buffer))
805  {
806  /* Start at the beginning of our buffer */
807  CurrentVersion = BiosVersion;
808  do
809  {
810  /* Convert to Unicode */
811  RtlInitAnsiString(&TempString, Buffer);
812  RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
813 
814  /* Calculate the length of this string and copy it in */
815  Length = Data.Length + sizeof(UNICODE_NULL);
816  RtlMoveMemory(CurrentVersion, Data.Buffer, Length);
817 
818  /* Free the unicode string */
819  RtlFreeUnicodeString(&Data);
820 
821  /* Update the total length and see if we're out of space */
822  TotalLength += Length;
823  if (TotalLength + 256 + sizeof(UNICODE_NULL) > PAGE_SIZE)
824  {
825  /* One more string would push us out, so stop here */
826  break;
827  }
828 
829  /* Go to the next string inside the multi-string buffer */
830  CurrentVersion += Length;
831 
832  /* Query the next BIOS Version */
833  } while (CmpGetBiosVersion(NULL, 0, Buffer));
834 
835  /* Check if we found any strings at all */
836  if (TotalLength)
837  {
838  /* Add the final null-terminator */
839  *(PWSTR)CurrentVersion = UNICODE_NULL;
840  TotalLength += sizeof(UNICODE_NULL);
841 
842  /* Write the BIOS Version to the registry */
843  RtlInitUnicodeString(&ValueName, L"SystemBiosVersion");
844  Status = NtSetValueKey(SystemHandle,
845  &ValueName,
846  0,
847  REG_MULTI_SZ,
848  BiosVersion,
849  TotalLength);
850 
851  /* ROS: Save a copy for bugzilla reporting */
852  RtlCreateUnicodeString(&KeRosBiosVersion, (PWCH)BiosVersion);
853  }
854  }
855 
856  /* Unmap the section */
857  ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
858  }
859 
860  /* Now prepare for Video BIOS Mapping of 32KB */
861  BaseAddress = 0;
862  ViewSize = 8 * PAGE_SIZE;
863  ViewBase.QuadPart = VideoRomBase;
864 
865  /* Map it */
866  Status = ZwMapViewOfSection(SectionHandle,
868  &BaseAddress,
869  0,
870  ViewSize,
871  &ViewBase,
872  &ViewSize,
873  ViewUnmap,
874  MEM_DOS_LIM,
876  if (NT_SUCCESS(Status))
877  {
878  /* Scan the ROM to get the BIOS Date */
879  if (CmpGetBiosDate(BaseAddress, 8 * PAGE_SIZE, Buffer, FALSE))
880  {
881  /* Convert it to Unicode */
882  RtlInitAnsiString(&TempString, Buffer);
883  RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
884 
885  /* Write the date into the registry */
886  RtlInitUnicodeString(&ValueName, L"VideoBiosDate");
887  Status = NtSetValueKey(SystemHandle,
888  &ValueName,
889  0,
890  REG_SZ,
891  Data.Buffer,
892  Data.Length + sizeof(UNICODE_NULL));
893 
894  /* ROS: Save a copy for bugzilla reporting */
895  RtlCreateUnicodeString(&KeRosVideoBiosDate, Data.Buffer);
896 
897  /* Free the string */
898  RtlFreeUnicodeString(&Data);
899  }
900 
901  /* Get the Video BIOS Version */
902  if (CmpGetBiosVersion(BaseAddress, 8 * PAGE_SIZE, Buffer))
903  {
904  /* Start at the beginning of our buffer */
905  CurrentVersion = BiosVersion;
906  do
907  {
908  /* Convert to Unicode */
909  RtlInitAnsiString(&TempString, Buffer);
910  RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
911 
912  /* Calculate the length of this string and copy it in */
913  Length = Data.Length + sizeof(UNICODE_NULL);
914  RtlMoveMemory(CurrentVersion, Data.Buffer, Length);
915 
916  /* Free the unicode string */
917  RtlFreeUnicodeString(&Data);
918 
919  /* Update the total length and see if we're out of space */
920  TotalLength += Length;
921  if (TotalLength + 256 + sizeof(UNICODE_NULL) > PAGE_SIZE)
922  {
923  /* One more string would push us out, so stop here */
924  break;
925  }
926 
927  /* Go to the next string inside the multi-string buffer */
928  CurrentVersion += Length;
929 
930  /* Query the next BIOS Version */
931  } while (CmpGetBiosVersion(NULL, 0, Buffer));
932 
933  /* Check if we found any strings at all */
934  if (TotalLength)
935  {
936  /* Add the final null-terminator */
937  *(PWSTR)CurrentVersion = UNICODE_NULL;
938  TotalLength += sizeof(UNICODE_NULL);
939 
940  /* Write the BIOS Version to the registry */
941  RtlInitUnicodeString(&ValueName, L"VideoBiosVersion");
942  Status = NtSetValueKey(SystemHandle,
943  &ValueName,
944  0,
945  REG_MULTI_SZ,
946  BiosVersion,
947  TotalLength);
948 
949  /* ROS: Save a copy for bugzilla reporting */
950  RtlCreateUnicodeString(&KeRosVideoBiosVersion, (PWCH)BiosVersion);
951  }
952  }
953 
954  /* Unmap the section */
955  ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
956  }
957 
958  /* Close the section */
959  ZwClose(SectionHandle);
960 
961  /* Free the BIOS version string buffer */
962  if (BiosVersion) ExFreePoolWithTag(BiosVersion, TAG_CM);
963 
964 Quickie:
965  /* Close the processor handle */
966  NtClose(KeyHandle);
967  return STATUS_SUCCESS;
968 }
DWORD *typedef PVOID
Definition: winlogon.h:52
ULONG IdentifierLength
Definition: arc.h:112
signed char * PCHAR
Definition: retypes.h:7
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4692
ULONG CmpConfigurationAreaSize
Definition: cmdata.c:36
#define IN
Definition: typedefs.h:39
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS NTAPI NtCreateKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG TitleIndex, IN PUNICODE_STRING Class OPTIONAL, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL)
Definition: ntapi.c:24
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4692
Definition: bidi.c:75
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define REG_BINARY
Definition: nt_native.h:1496
#define KEY_READ
Definition: nt_native.h:1023
ULONG FeatureBits
Definition: ketypes.h:799
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
return STATUS_SUCCESS
Definition: btrfs.c:2664
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
VOID NTAPI KeRevertToUserAffinityThread(VOID)
Definition: thrdobj.c:1030
static const CHAR BiosVersion[]
Definition: bios32.c:139
char CHAR
Definition: xmlstorage.h:175
ULONG MHz
Definition: ketypes.h:595
PVOID *typedef PWSTR
Definition: winlogon.h:57
UCHAR VendorString[13]
Definition: ketypes.h:797
PVOID ULONG ULONG PULONG Data
Definition: oprghdlr.h:14
ULONG KeI386NpxPresent
Definition: cpu.c:31
#define AFFINITY_MASK(Id)
Definition: ke.h:148
PCHAR CmpBiosStrings[]
Definition: cmhardwr.c:19
_In_ ULONG TotalLength
Definition: usbdlib.h:145
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:50
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
VOID NTAPI KeSetSystemAffinityThread(IN KAFFINITY Affinity)
Definition: thrdobj.c:1116
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
uint32_t ULONG_PTR
Definition: typedefs.h:64
#define sprintf(buf, format,...)
Definition: sprintf.c:55
LARGE_INTEGER UpdateSignature
Definition: ketypes.h:800
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
GLenum GLclampf GLint i
Definition: glfuncs.h:14
VOID NTAPI CmpGetVendorString(IN PKPRCB Prcb, OUT PCHAR CpuString)
Definition: cmhardwr.c:309
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
#define ANSI_NULL
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define pp
Definition: hlsl.yy.c:986
CONFIGURATION_TYPE Type
Definition: arc.h:105
USHORT CpuStep
Definition: ketypes.h:585
smooth NULL
Definition: ftsmooth.c:513
NTSTATUS NTAPI INIT_FUNCTION CmpInitializeRegistryNode(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry, IN HANDLE NodeHandle, OUT PHANDLE NewHandle, IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber, IN PUSHORT DeviceIndexTable)
Definition: cmconfig.c:20
Definition: bufpool.h:45
#define REG_CREATED_NEW_KEY
Definition: nt_native.h:1084
ULONG Eax
Definition: ketypes.h:296
#define isdigit(c)
Definition: acclib.h:68
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define MEM_DOS_LIM
Definition: mmtypes.h:89
PCHAR CmpBiosSearchEnd
Definition: cmhardwr.c:29
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_WRITE
Definition: nt_native.h:1031
unsigned char BOOLEAN
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
NTSTATUS NTAPI CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: cmhardwr.c:21
NTSYSAPI ULONG NTAPI RtlEqualMemory(CONST VOID *Source1, CONST VOID *Source2, ULONG Length)
ULONG Ebx
Definition: ketypes.h:297
CONFIGURATION_CLASS Class
Definition: arc.h:104
ULONG Ecx
Definition: ketypes.h:298
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
UNICODE_STRING KeRosBiosDate
Definition: bug.c:37
VOID NTAPI CmpGetIntelBrandString(OUT PCHAR CpuString)
Definition: cmhardwr.c:231
PCHAR CmpID2
Definition: cmhardwr.c:18
UINTN VOID * Buffer
Definition: acefiex.h:370
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3392
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
WCHAR * PWCH
Definition: ntbasedef.h:409
#define SharedUserData
CONFIGURATION_COMPONENT ComponentEntry
Definition: arc.h:121
#define TAG_CM
Definition: cmlib.h:203
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
VOID UINTN Length
Definition: acefiex.h:744
PCHAR CmpID1
Definition: cmhardwr.c:17
ULONG LowPart
Definition: typedefs.h:105
#define PAGE_SIZE
Definition: env_spec_w32.h:49
PCHAR CmpBiosSearchStart
Definition: cmhardwr.c:29
#define REG_DWORD
Definition: nt_native.h:1497
UNICODE_STRING KeRosVideoBiosDate
Definition: bug.c:38
static const CHAR BiosDate[]
Definition: bios32.c:141
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
PCM_FULL_RESOURCE_DESCRIPTOR CmpConfigurationData
Definition: cmdata.c:37
Status
Definition: gdiplustypes.h:24
UINT64 SetMember
Definition: ketypes.h:578
ULONG_PTR SIZE_T
Definition: typedefs.h:79
UNICODE_STRING KeRosVideoBiosVersion
Definition: bug.c:38
#define NT_SUCCESS(StatCode)
Definition: cmd.c:149
BOOLEAN ExpInTextModeSetup
Definition: init.c:66
DWORD *typedef HANDLE
Definition: winlogon.h:52
LONG NTSTATUS
Definition: DriverTester.h:11
UNICODE_STRING KeRosProcessorName
Definition: bug.c:37
unsigned short USHORT
Definition: pedump.c:61
#define PF_PAE_ENABLED
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
PKPRCB KiProcessorBlock[]
Definition: krnlinit.c:32
unsigned int * PULONG
Definition: retypes.h:1
NTSYSAPI NTSTATUS NTAPI NtSetValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN ULONG TitleIndex OPTIONAL, IN ULONG Type, IN PVOID Data, IN ULONG DataSize)
Definition: ntapi.c:617
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:120
#define OUT
Definition: typedefs.h:40
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:404
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
PCHAR CmpBiosBegin
Definition: cmhardwr.c:29
UNICODE_STRING KeRosBiosVersion
Definition: bug.c:37
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1097
GLfloat GLfloat p
Definition: glext.h:8902
BOOLEAN NTAPI CmpGetBiosVersion(IN PCHAR BiosStart, IN ULONG BiosLength, IN PCHAR BiosVersion)
Definition: cmhardwr.c:132
ULONG Edx
Definition: ketypes.h:299
CHAR CpuID
Definition: ketypes.h:581
NTSYSAPI NTSTATUS NTAPI ZwOpenSection(_Out_ PHANDLE SectionHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
static const WCHAR Signature[]
Definition: parser.c:141
BOOLEAN NTAPI CmpGetBiosDate(IN PCHAR BiosStart, IN ULONG BiosLength, IN PCHAR BiosDate, IN BOOLEAN FromBios)
Definition: cmhardwr.c:35
LONGLONG QuadPart
Definition: typedefs.h:113
#define PAGE_READWRITE
Definition: nt_native.h:1304
CHAR CpuType
Definition: ketypes.h:580
#define REG_SZ
Definition: layer.c:22