public static SMBIOSStructure BeginParseSMBIOS() { byte *memPtr = SMBIOS.SearchEntryPointTable(); EntryPointTable entry = new EntryPointTable(); //We dont return an address since we need to use a pointer that //its inside the table entry.Parse(memPtr); //entry.GetTableAddress(); SMBIOSStructure smbiosStructure = SMBIOS.ParseStructures(entry); smbiosStructure.EntryPointTable = entry; return(smbiosStructure); }
//We go byte by byte MANUALLY to parse the table. //The field that is assigned is autodocumented //We use the BitConverter for words and qwords (2 bytes and 8 bytes, respectively); public override byte *Parse() { byte *newAddress = BeginningAddress; int i; int j; //Begin the header parse this.Type = BeginningAddress[0]; this.Length = BeginningAddress[1]; byte[] tmp = new byte[2]; tmp[0] = BeginningAddress[2]; tmp[1] = BeginningAddress[3]; this.Handle = BitConverter.ToUInt16(tmp, 0); //Create a new byte array in which we will do the parsing //This array will contain the formatted section of the table byte[] parseArray = new byte[Convert.ToInt32(this.Length)]; for (int k = 0; k < this.Length; k++) { //Copy the formatted section byte to byte parseArray[k] = BeginningAddress[k]; } //Start parsing the formatted section using the previously created array //We do a 'best effort parse' which means that we parse until we go out of bounds of the array //Then we finish with an exception //This has two main advantages: //1. No need to check for versions since we do the parsing in function of the length //2. The parsing is quite robust since we do using the length parameter (which we assume it is //always right) //TODO: method for this try try { VendorID = parseArray[4]; VersionID = parseArray[5]; tmp[0] = parseArray[6]; tmp[1] = parseArray[7]; StartingAddressSegment = BitConverter.ToUInt16(tmp, 0); ReleaseDateID = parseArray[8]; ROMSize = parseArray[9]; tmp = new byte[8]; for (int k = 0; k < 8; k++) { //Since we left in 10... tmp[k] = parseArray[k + 10]; } Characteristics = BitConverter.ToUInt64(tmp, 0); //Begin to parse the optional characteristics //Since it is an optional field, we need to calculate its size first //Formula: Length - 12h == Length - 18 //var size = Length - 18; // I dont know if the specification is incorrect but i count 22 bytes, not 18 (you must // count the system bios bytes and firmware (since they are 22 bytes). // Might be a misintrepretation of the specification var size = Length - 22; // If there is no optional characteristic, skip if (size > 0) { OptionalCharacteristics = new byte[size]; //We start whre we left (18) for (int k = 0; k < size; k++) { OptionalCharacteristics[k] = parseArray[k + 18]; } } SystemBiosMajorRelease = parseArray[size + 18]; SystemBiosMinorRelease = parseArray[size + 19]; EmbeddedControllerFirmwareMajorRelease = parseArray[size + 20]; EmbeddedControllerFirmwareMinorRelease = parseArray[size + 21]; //This will not work in bochs since its version is 2.4 size += 2; tmp = new byte[2]; tmp[0] = parseArray[size + 22]; tmp[1] = parseArray[size + 23]; ExtendedBiosROMSize = BitConverter.ToUInt16(tmp, 0); } catch (IndexOutOfRangeException ex) { } //We have finished parsing the formatted area so we need to recompute the pointer //We start now the unformatted area //NOTE: we cannot sum this.Length directly. Gives IL2CPU error. newAddress = BeginningAddress + Convert.ToInt32(this.Length); //Parse the first string int[] tmpArray = new int[3]; tmpArray[0] = VendorID; tmpArray[1] = ReleaseDateID; tmpArray[2] = VersionID; //TODO: method for this for (int q = 0; q < 3; q++) { for (int w = 1; w < 3 - q; w++) { if (tmpArray[w - 1] > tmpArray[w]) { var tmp2 = tmpArray[w - 1]; tmpArray[w - 1] = tmpArray[w]; tmpArray[w] = tmp2; } } } //Array of strings from the formatted section string[] stringArray = SMBIOS.ParseStrings(newAddress); int iteration = -1; foreach (int t in tmpArray) { if (t == 255 | t == 0) { continue; } //We increment the index first so the first string is 0 //The numbers doesn't have to be correlative i.e //Doesn;'t have to be 1,2,3 it could be 1,2,15 //Thus, we cannot use t to index the array iteration++; if (t == VendorID) { Vendor = stringArray[iteration]; } else if (t == ReleaseDateID) { ReleaseDate = stringArray[iteration]; } else if (t == VersionID) { Version = stringArray[iteration]; } else { continue; } } //We need to recompute the pointer after parsing. return(SMBIOS.RecomputePointer(newAddress, stringArray)); }
public override unsafe byte *Parse() { byte *currentAddress; //We need a function to do parse a word //Parse the header Type = beginningAddress[0]; Length = beginningAddress[1]; byte[] tmp = new byte[2]; tmp[0] = beginningAddress[2]; tmp[1] = beginningAddress[3]; Handle = BitConverter.ToUInt16(tmp, 0); //Create the array in which we will do the parsing //Se biosInfo.cs comment //byte[] parseArray = new byte[Convert.ToInt32(this.Length)]; byte[] parseArray = new byte[this.Length]; for (int i = 0; i < this.Length; i++) { parseArray[i] = beginningAddress[i]; } //Parse using parseArray try { SocketDesignationID = parseArray[4]; ProcessorType = parseArray[5]; ProcessorFamily = parseArray[6]; ProcessorManufacturerID = parseArray[7]; tmp = new byte[8]; for (int i = 0; i < 8; i++) { tmp[i] = parseArray[i + 8]; } ProcessorID = BitConverter.ToUInt64(tmp, 0); //Processor id is the result of doing the CPUID instruction in x86 //Processor ID (in x86) its compound of two parts //The first DWORD is the EAX part when the EAX part is put to 1 //The second DWORD is the EDX part. //Store the EAX part of ProcessorID (since in x86 its as doing a CPUID instruction) tmp = new byte[4]; for (int i = 0; i < 4; i++) { tmp[i] = parseArray[i + 8]; } CPUIDEAX = BitConverter.ToUInt32(tmp, 0); //Store the EDX part of ProcessorID tmp = new byte[4]; for (int i = 4; i < 8; i++) { tmp[i - 4] = parseArray[i + 8]; } CPUIDEDX = BitConverter.ToUInt32(tmp, 0); ProcessorVersionID = parseArray[16]; Voltage = parseArray[17]; tmp = new byte[2]; tmp[0] = parseArray[18]; tmp[1] = parseArray[19]; ExternalClock = BitConverter.ToUInt16(tmp, 0); tmp = new byte[2]; tmp[0] = parseArray[20]; tmp[1] = parseArray[21]; MaxSpeed = BitConverter.ToUInt16(tmp, 0); tmp = new byte[2]; tmp[0] = parseArray[22]; tmp[1] = parseArray[23]; CurrentSpeed = BitConverter.ToUInt16(tmp, 0); Status = parseArray[24]; ProcessorUpgrade = parseArray[25]; tmp = new byte[2]; tmp[0] = parseArray[26]; tmp[1] = parseArray[27]; L1HandleCache = BitConverter.ToUInt16(tmp, 0); tmp = new byte[2]; tmp[0] = parseArray[28]; tmp[1] = parseArray[29]; L2HandleCache = BitConverter.ToUInt16(tmp, 0); tmp = new byte[2]; tmp[0] = parseArray[30]; tmp[1] = parseArray[31]; L3HandleCache = BitConverter.ToUInt16(tmp, 0); SerialNumberID = parseArray[32]; AssetTagID = parseArray[33]; PartNumberID = parseArray[34]; CoreCount = parseArray[35]; CoreEnabled = parseArray[36]; ThreadCount = parseArray[37]; tmp = new byte[2]; tmp[0] = parseArray[38]; tmp[1] = parseArray[39]; ProcessorCharacteristics = BitConverter.ToUInt16(tmp, 0); tmp = new byte[2]; tmp[0] = parseArray[40]; tmp[1] = parseArray[41]; ProcessorFamily2 = BitConverter.ToUInt16(tmp, 0); tmp = new byte[2]; tmp[0] = parseArray[42]; tmp[1] = parseArray[43]; CoreCount2 = BitConverter.ToUInt16(tmp, 0); tmp = new byte[2]; tmp[0] = parseArray[44]; tmp[1] = parseArray[45]; CoreEnabled2 = BitConverter.ToUInt16(tmp, 0); tmp = new byte[2]; tmp[0] = parseArray[46]; tmp[1] = parseArray[47]; ThreadCount2 = BitConverter.ToUInt16(tmp, 0); } catch (IndexOutOfRangeException ex) { } currentAddress = beginningAddress + Convert.ToInt32(Length); var stringArray = SMBIOS.ParseStrings(currentAddress); StoreStrings(stringArray); return(SMBIOS.RecomputePointer(currentAddress, stringArray)); }