ReactOS  0.4.15-dev-5146-g069b08d
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 CmpFullCpuID = "%s Family %u Model %u Stepping %u";
19 {
20  "Ver",
21  "Rev",
22  "Rel",
23  "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9",
24  "v 0", "v 1", "v 2", "v 3", "v 4", "v 5", "v 6", "v 7", "v 8", "v 9",
25  NULL
26 };
27 
29 
30 /* FUNCTIONS *****************************************************************/
31 
32 BOOLEAN
33 NTAPI
35  IN ULONG BiosLength,
37  IN BOOLEAN FromBios)
38 {
39  CHAR LastDate[11] = {0}, CurrentDate[11];
40  PCHAR p, pp;
41 
42  /* Skip the signature and the magic, and loop the BIOS ROM */
43  p = BiosStart + 2;
44  pp = BiosStart + BiosLength - 5;
45  while (p < pp)
46  {
47  /* Check for xx/yy/zz which we assume to be a date */
48  if ((p[0] == '/') &&
49  (p[3] == '/') &&
50  (isdigit(p[-1])) &&
51  (isdigit(p[1])) &&
52  (isdigit(p[2])) &&
53  (isdigit(p[4])) &&
54  (isdigit(p[5])))
55  {
56  /* Copy the string proper */
57  RtlMoveMemory(&CurrentDate[5], p - 2, 5);
58 
59  /* Add a 0 if the month only has one digit */
60  if (!isdigit(CurrentDate[5])) CurrentDate[5] = '0';
61 
62  /* Now copy the year */
63  CurrentDate[2] = p[4];
64  CurrentDate[3] = p[5];
65  CurrentDate[4] = CurrentDate[7] = CurrentDate[10] = ANSI_NULL;
66 
67  /* If the date comes from the BIOS, check if it's a 4-digit year */
68  if ((FromBios) &&
69  (isdigit(p[6])) &&
70  (isdigit(p[7])) &&
71  ((RtlEqualMemory(&p[4], "19", 2)) ||
72  (RtlEqualMemory(&p[4], "20", 2))))
73  {
74  /* Copy the year proper */
75  CurrentDate[0] = p[4];
76  CurrentDate[1] = p[5];
77  CurrentDate[2] = p[6];
78  CurrentDate[3] = p[7];
79  }
80  else
81  {
82  /* Otherwise, we'll just assume anything under 80 is 2000 */
83  if (strtoul(&CurrentDate[2], NULL, 10) < 80)
84  {
85  /* Hopefully your BIOS wasn't made in 1979 */
86  CurrentDate[0] = '2';
87  CurrentDate[1] = '0';
88  }
89  else
90  {
91  /* Anything over 80, was probably made in the 1900s... */
92  CurrentDate[0] = '1';
93  CurrentDate[1] = '9';
94  }
95  }
96 
97  /* Add slashes where we previously had NULLs */
98  CurrentDate[4] = CurrentDate[7] = '/';
99 
100  /* Check which date is newer */
101  if (memcmp(LastDate, CurrentDate, 10) < 0)
102  {
103  /* Found a newer date, select it */
104  RtlMoveMemory(LastDate, CurrentDate, 10);
105  }
106 
107  p += 2;
108  }
109  p++;
110  }
111 
112  /* Make sure we found a date */
113  if (LastDate[0])
114  {
115  /* Copy the year at the pp, and keep only the last two digits */
116  RtlMoveMemory(BiosDate, &LastDate[5], 5);
117  BiosDate[5] = '/';
118  BiosDate[6] = LastDate[2];
119  BiosDate[7] = LastDate[3];
120  BiosDate[8] = ANSI_NULL;
121  return TRUE;
122  }
123 
124  /* No date found, return empty string */
125  BiosDate[0] = ANSI_NULL;
126  return FALSE;
127 }
128 
129 BOOLEAN
130 NTAPI
132  IN ULONG BiosLength,
134 {
135  CHAR Buffer[128];
136  PCHAR p, pp;
137  USHORT i;
138 
139  /* Check if we were given intitial data for the search */
140  if (BiosStart)
141  {
142  /* Save it for later use */
143  CmpBiosBegin = BiosStart;
144  CmpBiosSearchStart = BiosStart + 1;
145  CmpBiosSearchEnd = BiosStart + BiosLength - 2;
146  }
147 
148  /* Now loop the BIOS area */
149  for (;;)
150  {
151  /* Start an initial search looking for numbers and periods */
152  pp = NULL;
154  {
155  /* Check if we have an "x.y" version string */
156  if ((*CmpBiosSearchStart == '.') &&
157  (*(CmpBiosSearchStart + 1) >= '0') &&
158  (*(CmpBiosSearchStart + 1) <= '9') &&
159  (*(CmpBiosSearchStart - 1) >= '0') &&
160  (*(CmpBiosSearchStart - 1) <= '9'))
161  {
162  /* Start looking in this area for the actual BIOS Version */
163  pp = CmpBiosSearchStart;
164  break;
165  }
166  else
167  {
168  /* Keep searching */
170  }
171  }
172 
173  /* Break out if we're went past the BIOS area */
175 
176  /* Move to the next 2 bytes */
177  CmpBiosSearchStart += 2;
178 
179  /* Null-terminate our scratch buffer and start the string here */
180  Buffer[127] = ANSI_NULL;
181  p = &Buffer[127];
182 
183  /* Go back one character since we're doing this backwards */
184  pp--;
185 
186  /* Loop the identifier we found as long as it's valid */
187  i = 0;
188  while ((i++ < 127) &&
189  (pp >= CmpBiosBegin) &&
190  (*pp >= ' ') &&
191  (*pp != '$'))
192  {
193  /* Copy the character */
194  *--p = *pp--;
195  }
196 
197  /* Go past the last character since we went backwards */
198  pp++;
199 
200  /* Loop the strings we recognize */
201  for (i = 0; CmpBiosStrings[i]; i++)
202  {
203  /* Check if a match was found */
204  if (strstr(p, CmpBiosStrings[i])) goto Match;
205  }
206  }
207 
208 Match:
209  /* Skip until we find a space */
210  for (; *pp == ' '; pp++);
211 
212  /* Loop the final string */
213  i = 0;
214  do
215  {
216  /* Copy the character into the final string */
217  BiosVersion[i] = *pp++;
218  } while ((++i < 127) &&
219  (pp <= (CmpBiosSearchEnd + 1)) &&
220  (*pp >= ' ') &&
221  (*pp != '$'));
222 
223  /* Null-terminate the version string */
225  return TRUE;
226 }
227 
228 NTSTATUS
229 NTAPI
231 {
232  UNICODE_STRING KeyName, ValueName, Data, SectionName;
234  ULONG HavePae, Length, TotalLength = 0, i, Disposition;
237  HANDLE KeyHandle, BiosHandle, SystemHandle, FpuHandle, SectionHandle;
238  CONFIGURATION_COMPONENT_DATA ConfigData;
239  CHAR Buffer[128];
240  CPU_INFO CpuInfo;
241  ULONG ExtendedId;
242  PKPRCB Prcb;
243  USHORT IndexTable[MaximumType + 1] = {0};
244  ANSI_STRING TempString;
245  PCHAR PartialString = NULL, BiosVersion;
246  CHAR CpuString[48];
248  LARGE_INTEGER ViewBase = {{0, 0}};
249  ULONG_PTR VideoRomBase;
250  PCHAR CurrentVersion;
253 
254  /* Open the SMSS Memory Management key */
256  L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\"
257  L"Control\\Session Manager\\Memory Management");
259  &KeyName,
261  NULL,
262  NULL);
264  if (NT_SUCCESS(Status))
265  {
266  /* Detect if PAE is enabled */
267  HavePae = SharedUserData->ProcessorFeatures[PF_PAE_ENABLED];
268 
269  /* Set the value */
270  RtlInitUnicodeString(&ValueName, L"PhysicalAddressExtension");
272  &ValueName,
273  0,
274  REG_DWORD,
275  &HavePae,
276  sizeof(HavePae));
277 
278  /* Close the key */
280  }
281 
282  /* Open the hardware description key */
284  L"\\Registry\\Machine\\Hardware\\Description\\System");
286  &KeyName,
288  NULL,
289  NULL);
290  Status = NtOpenKey(&SystemHandle, KEY_READ | KEY_WRITE, &ObjectAttributes);
291  if (!NT_SUCCESS(Status))
292  return Status;
293 
294  /* Create the BIOS Information key */
296  L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\"
297  L"Control\\BIOSINFO");
299  &KeyName,
301  NULL,
302  NULL);
303  Status = NtCreateKey(&BiosHandle,
306  0,
307  NULL,
309  &Disposition);
310  if (!NT_SUCCESS(Status))
311  {
312  NtClose(SystemHandle);
313  return Status;
314  }
315 
316  /* Create the CPU Key, and check if it already existed */
317  RtlInitUnicodeString(&KeyName, L"CentralProcessor");
319  &KeyName,
321  SystemHandle,
322  NULL);
326  0,
327  NULL,
328  0,
329  &Disposition);
331 
332  /* The key shouldn't already exist */
334  {
335  /* Allocate the configuration data for cmconfig.c */
338  TAG_CM);
340  {
341  // FIXME: Cleanup stuff!!
343  }
344 
345  /* Loop all CPUs */
346  for (i = 0; i < KeNumberProcessors; i++)
347  {
348 #ifdef _M_AMD64
349  PCHAR FamilyId;
350 #endif
351  /* Get the PRCB */
352  Prcb = KiProcessorBlock[i];
353 
354  /* Setup the Configuration Entry for the Processor */
355  RtlZeroMemory(&ConfigData, sizeof(ConfigData));
356  ConfigData.ComponentEntry.Class = ProcessorClass;
357  ConfigData.ComponentEntry.Type = CentralProcessor;
358  ConfigData.ComponentEntry.Key = i;
360  ConfigData.ComponentEntry.Identifier = Buffer;
361 
362 #if defined(_M_IX86)
363  /* Check if the CPU doesn't support CPUID */
364  if (!Prcb->CpuID)
365  {
366  /* Build 80x86-style string for older CPUs */
367  sprintf(Buffer,
368  "80%u86-%c%x",
369  Prcb->CpuType,
370  (Prcb->CpuStep >> 8) + 'A',
371  Prcb->CpuStep & 0xff);
372  }
373  else
374  {
375  /* Build full ID string for newer CPUs */
376  sprintf(Buffer,
377  CmpFullCpuID,
378  "x86",
379  Prcb->CpuType,
380  (Prcb->CpuStep >> 8),
381  Prcb->CpuStep & 0xff);
382  }
383 #elif defined(_M_AMD64)
384  if (Prcb->CpuVendor == CPU_VIA)
385  {
386  /* This is VIA64 family */
387  FamilyId = "VIA64";
388  }
389  else if (Prcb->CpuVendor == CPU_AMD)
390  {
391  /* This is AMD64 family */
392  FamilyId = "AMD64";
393  }
394  else
395  {
396  /* This is generic EM64T family */
397  FamilyId = "EM64T";
398  }
399 
400  /* ID string has the same style for all 64-bit CPUs */
401  sprintf(Buffer,
402  CmpFullCpuID,
403  FamilyId,
404  Prcb->CpuType,
405  (Prcb->CpuStep >> 8),
406  Prcb->CpuStep & 0xff);
407 #else
408 #error Unknown architecture
409 #endif
410 
411  /* Save the ID string length now that we've created it */
413 
414  /* Initialize the registry configuration node for it */
415  Status = CmpInitializeRegistryNode(&ConfigData,
416  SystemHandle,
417  &KeyHandle,
419  0xFFFFFFFF,
420  IndexTable);
421  if (!NT_SUCCESS(Status))
422  {
423  NtClose(BiosHandle);
424  NtClose(SystemHandle);
425  return Status;
426  }
427 
428  /* Check if we have an FPU */
429  if (KeI386NpxPresent)
430  {
431  /* Setup the Configuration Entry for the FPU */
432  RtlZeroMemory(&ConfigData, sizeof(ConfigData));
433  ConfigData.ComponentEntry.Class = ProcessorClass;
434  ConfigData.ComponentEntry.Type = FloatingPointProcessor;
435  ConfigData.ComponentEntry.Key = i;
437  ConfigData.ComponentEntry.Identifier = Buffer;
438 
439  /* For 386 cpus, the CPU pp is the identifier */
440  if (Prcb->CpuType == 3) strcpy(Buffer, "80387");
441 
442  /* Save the ID string length now that we've created it */
444 
445  /* Initialize the registry configuration node for it */
446  Status = CmpInitializeRegistryNode(&ConfigData,
447  SystemHandle,
448  &FpuHandle,
450  0xFFFFFFFF,
451  IndexTable);
452  if (!NT_SUCCESS(Status))
453  {
454  /* We failed, close all the opened handles and return */
456  NtClose(BiosHandle);
457  NtClose(SystemHandle);
458  return Status;
459  }
460 
461  /* Close this new handle */
462  NtClose(FpuHandle);
463 
464  /* Stay on this CPU only */
466  if (!Prcb->CpuID)
467  {
468  /* Uh oh, no CPUID! Should not happen as we don't support 80386 and older 80486 */
469  ASSERT(FALSE);
470  }
471  else
472  {
473  /* Check if we have extended CPUID that supports name ID */
474  KiCpuId(&CpuInfo, 0x80000000);
475  ExtendedId = CpuInfo.Eax;
476  if (ExtendedId >= 0x80000004)
477  {
478  /* Do all the CPUIDs required to get the full name */
479  PartialString = CpuString;
480  for (ExtendedId = 2; ExtendedId <= 4; ExtendedId++)
481  {
482  /* Do the CPUID and save the name string */
483  KiCpuId(&CpuInfo, 0x80000000 | ExtendedId);
484  ((PULONG)PartialString)[0] = CpuInfo.Eax;
485  ((PULONG)PartialString)[1] = CpuInfo.Ebx;
486  ((PULONG)PartialString)[2] = CpuInfo.Ecx;
487  ((PULONG)PartialString)[3] = CpuInfo.Edx;
488 
489  /* Go to the next name string */
490  PartialString += 16;
491  }
492 
493  /* Null-terminate it */
494  CpuString[47] = ANSI_NULL;
495  }
496  }
497 
498  /* Go back to user affinity */
500 
501  /* Check if we have a CPU Name */
502  if (PartialString)
503  {
504  /* Convert it to Unicode */
505  RtlInitAnsiString(&TempString, CpuString);
506  if (NT_SUCCESS(RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE)))
507  {
508  /* Add it to the registry */
509  RtlInitUnicodeString(&ValueName, L"ProcessorNameString");
511  &ValueName,
512  0,
513  REG_SZ,
514  Data.Buffer,
515  Data.Length + sizeof(UNICODE_NULL));
516 
517  /* ROS: Save a copy for bugzilla reporting */
519  {
520  /* Do not fail for this */
522  }
523 
524  /* Free the temporary buffer */
526  }
527  }
528 
529  /* Check if we had a Vendor ID */
530  if (Prcb->VendorString[0])
531  {
532  /* Convert it to Unicode */
533  RtlInitAnsiString(&TempString, Prcb->VendorString);
534  if (NT_SUCCESS(RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE)))
535  {
536  /* Add it to the registry */
537  RtlInitUnicodeString(&ValueName, L"VendorIdentifier");
539  &ValueName,
540  0,
541  REG_SZ,
542  Data.Buffer,
543  Data.Length + sizeof(UNICODE_NULL));
544 
545  /* Free the temporary buffer */
547  }
548  }
549 
550  /* Check if we have features bits */
551  if (Prcb->FeatureBits)
552  {
553  /* Add them to the registry */
554  RtlInitUnicodeString(&ValueName, L"FeatureSet");
556  &ValueName,
557  0,
558  REG_DWORD,
559  &Prcb->FeatureBits,
560  sizeof(Prcb->FeatureBits));
561  }
562 
563  /* Check if we detected the CPU Speed */
564  if (Prcb->MHz)
565  {
566  /* Add it to the registry */
569  &ValueName,
570  0,
571  REG_DWORD,
572  &Prcb->MHz,
573  sizeof(Prcb->MHz));
574  }
575 
576  /* Check if we have an update signature */
577  if (Prcb->UpdateSignature.QuadPart)
578  {
579  /* Add it to the registry */
580  RtlInitUnicodeString(&ValueName, L"Update Signature");
582  &ValueName,
583  0,
584  REG_BINARY,
585  &Prcb->UpdateSignature,
586  sizeof(Prcb->UpdateSignature));
587  }
588 
589  /* Close the processor handle */
591 
592  /* FIXME: Detect CPU mismatches */
593  }
594  }
595 
596  /* Free the configuration data */
598  }
599 
600  /* Open physical memory */
601  RtlInitUnicodeString(&SectionName, L"\\Device\\PhysicalMemory");
603  &SectionName,
605  NULL,
606  NULL);
607  Status = ZwOpenSection(&SectionHandle,
610  if (!NT_SUCCESS(Status))
611  {
612  /* We failed, close all the opened handles and return */
613  // NtClose(KeyHandle);
614  NtClose(BiosHandle);
615  NtClose(SystemHandle);
616  /* 'Quickie' closes KeyHandle */
617  goto Quickie;
618  }
619 
620  /* Map the first 1KB of memory to get the IVT */
622  Status = ZwMapViewOfSection(SectionHandle,
624  &BaseAddress,
625  0,
626  ViewSize,
627  &ViewBase,
628  &ViewSize,
629  ViewUnmap,
630  MEM_DOS_LIM,
632  if (!NT_SUCCESS(Status))
633  {
634  /* Assume default */
635  VideoRomBase = 0xC0000;
636  }
637  else
638  {
639  /* Calculate the base address from the vector */
640  VideoRomBase = (*((PULONG)BaseAddress + 0x10) >> 12) & 0xFFFF0;
641  VideoRomBase += *((PULONG)BaseAddress + 0x10) & 0xFFF0;
642 
643  /* Now get to the actual ROM Start and make sure it's not invalid*/
644  VideoRomBase &= 0xFFFF8000;
645  if (VideoRomBase < 0xC0000) VideoRomBase = 0xC0000;
646 
647  /* And unmap the section */
648  ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
649  }
650 
651  /* Allocate BIOS Version pp Buffer */
653 
654  /* Setup settings to map the 64K BIOS ROM */
655  BaseAddress = 0;
656  ViewSize = 16 * PAGE_SIZE;
657  ViewBase.LowPart = 0xF0000;
658  ViewBase.HighPart = 0;
659 
660  /* Map it */
661  Status = ZwMapViewOfSection(SectionHandle,
663  &BaseAddress,
664  0,
665  ViewSize,
666  &ViewBase,
667  &ViewSize,
668  ViewUnmap,
669  MEM_DOS_LIM,
671  if (NT_SUCCESS(Status))
672  {
673  /* Scan the ROM to get the BIOS Date */
675  {
676  /* Convert it to Unicode */
677  RtlInitAnsiString(&TempString, Buffer);
678  if (NT_SUCCESS(RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE)))
679  {
680  /* Write the date into the registry */
681  RtlInitUnicodeString(&ValueName, L"SystemBiosDate");
682  Status = NtSetValueKey(SystemHandle,
683  &ValueName,
684  0,
685  REG_SZ,
686  Data.Buffer,
687  Data.Length + sizeof(UNICODE_NULL));
688 
689  /* Free the string */
691  }
692 
693  if (BiosHandle)
694  {
695  /* Get the BIOS Date Identifier */
696  RtlCopyMemory(Buffer, (PCHAR)BaseAddress + (16 * PAGE_SIZE - 11), 8);
697  Buffer[8] = ANSI_NULL;
698 
699  /* Convert it to unicode */
700  RtlInitAnsiString(&TempString, Buffer);
701  Status = RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
702  if (NT_SUCCESS(Status))
703  {
704  /* Save it to the registry */
705  Status = NtSetValueKey(BiosHandle,
706  &ValueName,
707  0,
708  REG_SZ,
709  Data.Buffer,
710  Data.Length + sizeof(UNICODE_NULL));
711 
712  /* ROS: Save a copy for bugzilla reporting */
714  KeRosBiosDate.Length = 0;
715 
716  /* Free the string */
718  }
719 
720  /* Close the bios information handle */
721  NtClose(BiosHandle);
722  }
723  }
724 
725  /* Get the BIOS Version */
727  {
728  /* Start at the beginning of our buffer */
729  CurrentVersion = BiosVersion;
730  do
731  {
732  /* Convert to Unicode */
733  RtlInitAnsiString(&TempString, Buffer);
734  Status = RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
735  if (!NT_SUCCESS(Status))
736  break;
737 
738  /* Calculate the length of this string and copy it in */
739  Length = Data.Length + sizeof(UNICODE_NULL);
740  RtlMoveMemory(CurrentVersion, Data.Buffer, Length);
741 
742  /* Free the unicode string */
744 
745  /* Update the total length and see if we're out of space */
746  TotalLength += Length;
747  if (TotalLength + 256 + sizeof(UNICODE_NULL) > PAGE_SIZE)
748  {
749  /* One more string would push us out, so stop here */
750  break;
751  }
752 
753  /* Go to the next string inside the multi-string buffer */
754  CurrentVersion += Length;
755 
756  /* Query the next BIOS Version */
757  } while (CmpGetBiosVersion(NULL, 0, Buffer));
758 
759  /* Check if we found any strings at all */
760  if (TotalLength)
761  {
762  /* Add the final null-terminator */
763  *(PWSTR)CurrentVersion = UNICODE_NULL;
764  TotalLength += sizeof(UNICODE_NULL);
765 
766  /* Write the BIOS Version to the registry */
767  RtlInitUnicodeString(&ValueName, L"SystemBiosVersion");
768  Status = NtSetValueKey(SystemHandle,
769  &ValueName,
770  0,
771  REG_MULTI_SZ,
772  BiosVersion,
773  TotalLength);
774 
775  /* ROS: Save a copy for bugzilla reporting */
778  }
779  }
780 
781  /* Unmap the section */
782  ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
783  }
784 
785  /* Now prepare for Video BIOS Mapping of 32KB */
786  BaseAddress = 0;
787  ViewSize = 8 * PAGE_SIZE;
788  ViewBase.QuadPart = VideoRomBase;
789 
790  /* Map it */
791  Status = ZwMapViewOfSection(SectionHandle,
793  &BaseAddress,
794  0,
795  ViewSize,
796  &ViewBase,
797  &ViewSize,
798  ViewUnmap,
799  MEM_DOS_LIM,
801  if (NT_SUCCESS(Status))
802  {
803  /* Scan the ROM to get the BIOS Date */
805  {
806  /* Convert it to Unicode */
807  RtlInitAnsiString(&TempString, Buffer);
808  if (NT_SUCCESS(RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE)))
809  {
810  /* Write the date into the registry */
811  RtlInitUnicodeString(&ValueName, L"VideoBiosDate");
812  Status = NtSetValueKey(SystemHandle,
813  &ValueName,
814  0,
815  REG_SZ,
816  Data.Buffer,
817  Data.Length + sizeof(UNICODE_NULL));
818 
819  /* ROS: Save a copy for bugzilla reporting */
822 
823  /* Free the string */
825  }
826  }
827 
828  /* Get the Video BIOS Version */
830  {
831  /* Start at the beginning of our buffer */
832  CurrentVersion = BiosVersion;
833  do
834  {
835  /* Convert to Unicode */
836  RtlInitAnsiString(&TempString, Buffer);
837  if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE)))
838  break;
839 
840  /* Calculate the length of this string and copy it in */
841  Length = Data.Length + sizeof(UNICODE_NULL);
842  RtlMoveMemory(CurrentVersion, Data.Buffer, Length);
843 
844  /* Free the unicode string */
846 
847  /* Update the total length and see if we're out of space */
848  TotalLength += Length;
849  if (TotalLength + 256 + sizeof(UNICODE_NULL) > PAGE_SIZE)
850  {
851  /* One more string would push us out, so stop here */
852  break;
853  }
854 
855  /* Go to the next string inside the multi-string buffer */
856  CurrentVersion += Length;
857 
858  /* Query the next BIOS Version */
859  } while (CmpGetBiosVersion(NULL, 0, Buffer));
860 
861  /* Check if we found any strings at all */
862  if (TotalLength)
863  {
864  /* Add the final null-terminator */
865  *(PWSTR)CurrentVersion = UNICODE_NULL;
866  TotalLength += sizeof(UNICODE_NULL);
867 
868  /* Write the BIOS Version to the registry */
869  RtlInitUnicodeString(&ValueName, L"VideoBiosVersion");
870  Status = NtSetValueKey(SystemHandle,
871  &ValueName,
872  0,
873  REG_MULTI_SZ,
874  BiosVersion,
875  TotalLength);
876 
877  /* ROS: Save a copy for bugzilla reporting */
880  }
881  }
882 
883  /* Unmap the section */
884  ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
885  }
886 
887  /* Close the section */
888  ZwClose(SectionHandle);
889 
890  /* Free the BIOS version string buffer */
892 
893 Quickie:
894  /* Close the processor handle */
896  return STATUS_SUCCESS;
897 }
ULONG IdentifierLength
Definition: arc.h:112
signed char * PCHAR
Definition: retypes.h:7
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
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 STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
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:240
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
ULONG Edx
Definition: ketypes.h:304
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define REG_BINARY
Definition: nt_native.h:1496
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
ULONG FeatureBits
Definition: ketypes.h:804
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:56
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
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG _In_opt_ PVOID Data
Definition: wdfdevice.h:4527
char CHAR
Definition: xmlstorage.h:175
ULONG MHz
Definition: ketypes.h:600
LONG NTSTATUS
Definition: precomp.h:26
UCHAR VendorString[13]
Definition: ketypes.h:802
ULONG KeI386NpxPresent
Definition: cpu.c:25
#define AFFINITY_MASK(Id)
Definition: ke.h:159
PCHAR CmpBiosStrings[]
Definition: cmhardwr.c:18
_In_ ULONG TotalLength
Definition: usbdlib.h:158
ULONG Ebx
Definition: ketypes.h:302
_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:65
#define sprintf(buf, format,...)
Definition: sprintf.c:55
LARGE_INTEGER UpdateSignature
Definition: ketypes.h:805
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
#define L(x)
Definition: ntvdm.h:50
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
CONFIGURATION_TYPE Type
Definition: arc.h:105
unsigned char BOOLEAN
USHORT CpuStep
Definition: ketypes.h:590
Definition: bufpool.h:45
#define REG_CREATED_NEW_KEY
Definition: nt_native.h:1084
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2697
#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:28
Status
Definition: gdiplustypes.h:24
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_WRITE
Definition: nt_native.h:1031
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
NTSTATUS NTAPI CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: cmhardwr.c:21
#define ASSERT(a)
Definition: mode.c:44
NTSYSAPI ULONG NTAPI RtlEqualMemory(CONST VOID *Source1, CONST VOID *Source2, ULONG Length)
NTSTATUS NTAPI 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
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
CONFIGURATION_CLASS Class
Definition: arc.h:104
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
UNICODE_STRING KeRosBiosDate
Definition: bug.c:33
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
UCHAR CpuVendor
Definition: ketypes.h:605
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
WCHAR * PWCH
Definition: ntbasedef.h:410
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:240
#define SharedUserData
CONFIGURATION_COMPONENT ComponentEntry
Definition: arc.h:121
#define TAG_CM
Definition: cmlib.h:205
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
ULONG Ecx
Definition: ketypes.h:303
ULONG LowPart
Definition: typedefs.h:106
#define PAGE_SIZE
Definition: env_spec_w32.h:49
PCHAR CmpBiosSearchStart
Definition: cmhardwr.c:28
UNICODE_STRING KeRosVideoBiosDate
Definition: bug.c:34
static const CHAR BiosDate[]
Definition: bios32.c:141
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
PCM_FULL_RESOURCE_DESCRIPTOR CmpConfigurationData
Definition: cmdata.c:37
UINT64 SetMember
Definition: ketypes.h:583
ULONG_PTR SIZE_T
Definition: typedefs.h:80
UNICODE_STRING KeRosVideoBiosVersion
Definition: bug.c:34
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
UNICODE_STRING KeRosProcessorName
Definition: bug.c:33
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
#define NULL
Definition: types.h:112
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:859
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
_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
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
PCHAR CmpBiosBegin
Definition: cmhardwr.c:28
UNICODE_STRING KeRosBiosVersion
Definition: bug.c:33
#define STATUS_SUCCESS
Definition: shellext.h:65
GLfloat GLfloat p
Definition: glext.h:8902
BOOLEAN NTAPI CmpGetBiosVersion(IN PCHAR BiosStart, IN ULONG BiosLength, IN PCHAR BiosVersion)
Definition: cmhardwr.c:131
CHAR CpuID
Definition: ketypes.h:586
NTSYSAPI NTSTATUS NTAPI ZwOpenSection(_Out_ PHANDLE SectionHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
#define REG_DWORD
Definition: sdbapi.c:596
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
BOOLEAN NTAPI CmpGetBiosDate(IN PCHAR BiosStart, IN ULONG BiosLength, IN PCHAR BiosDate, IN BOOLEAN FromBios)
Definition: cmhardwr.c:34
PCHAR CmpFullCpuID
Definition: cmhardwr.c:17
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG Eax
Definition: ketypes.h:301
#define PAGE_READWRITE
Definition: nt_native.h:1304
CHAR CpuType
Definition: ketypes.h:585
#define REG_SZ
Definition: layer.c:22