From c6ec76c0f1131b8f75c7e62102e26df445717360 Mon Sep 17 00:00:00 2001 From: Fergus Morrow Date: Mon, 15 Feb 2016 01:17:13 +0000 Subject: [PATCH 1/6] Improve example code + add build script --- .gitignore | 1 + example.c | 52 +++++++++++++++++++ smbios_parse.c => lib/smbios_parse.c | 0 lib/smbios_parse.h | 55 ++++++++++++++++++++ smbios_parse.h => lib/smbios_structures.h | 62 ++--------------------- make-example.sh | 13 +++++ 6 files changed, 125 insertions(+), 58 deletions(-) create mode 100644 .gitignore create mode 100644 example.c rename smbios_parse.c => lib/smbios_parse.c (100%) create mode 100644 lib/smbios_parse.h rename smbios_parse.h => lib/smbios_structures.h (87%) create mode 100755 make-example.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..33a9488 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +example diff --git a/example.c b/example.c new file mode 100644 index 0000000..1fa2ed0 --- /dev/null +++ b/example.c @@ -0,0 +1,52 @@ +#include +#include +#include "lib/smbios_parse.h" + +void print_smbios_entry(struct SMBEntryPoint* e); +void print_smbios_data(byte_t* data); + +int main(int argc, const char * argv[]) { + + CFDataRef dataRef; + io_service_t service = MACH_PORT_NULL; + mach_port_t myMasterPort; + + IOMasterPort(MACH_PORT_NULL, &myMasterPort); + service = IOServiceGetMatchingService(myMasterPort, IOServiceMatching("AppleSMBIOS")); + if (!service) { + printf("No \"AppleSMBIOS\" IOService in IORegistry.\n"); + return -1; + } + + + // Retrieve and Parse SMBIOS Entry Point data + + dataRef = (CFDataRef) IORegistryEntryCreateCFProperty(service, + CFSTR("SMBIOS-EPS"), kCFAllocatorDefault, kNilOptions); + + if (!dataRef) { + printf("Unable to retrieve SMBIOS entry point!\n"); + return -1; + } else print_smbios_entry((struct SMBEntryPoint *) CFDataGetBytePtr(dataRef)); + + + // Retrieve and Parse SMBIOS Data + + dataRef = (CFDataRef) IORegistryEntryCreateCFProperty(service, + CFSTR("SMBIOS"), kCFAllocatorDefault, kNilOptions); + + if (!dataRef) { + printf("Unable to retrieve SMBIOS data!\n"); + return -1; + } else print_smbios_data((byte_t*) CFDataGetBytePtr(dataRef)); + + return 0; +} + +void print_smbios_entry(struct SMBEntryPoint* e){ + printf("Address of SMBIOS Entry Point: %p.\n", e); +} + +void print_smbios_data(byte_t* data){ + printf("Address of SMBIOS Data: %p.\n", data); +} \ No newline at end of file diff --git a/smbios_parse.c b/lib/smbios_parse.c similarity index 100% rename from smbios_parse.c rename to lib/smbios_parse.c diff --git a/lib/smbios_parse.h b/lib/smbios_parse.h new file mode 100644 index 0000000..f5769f7 --- /dev/null +++ b/lib/smbios_parse.h @@ -0,0 +1,55 @@ +#include +#include +#include +#include + +typedef uint8_t byte_t; +typedef uint16_t word_t; +typedef uint32_t dword_t; +typedef uint64_t qword_t; + +typedef byte_t str_id; +typedef byte_t enum_t; + +#include "smbios_structures.h" + +// We implement an internal Linked List after parsing +// the SMBIOS table. +typedef struct Entry { + struct Entry* next; + struct header* header; +} Entry; + + + + +/* + * Internal properties + */ +byte_t *smbios_raw_data; +size_t smbios_raw_size; +Entry *smbios_first; +Entry *smbios_current_entry; + + + +/* + * Function Prototypes + */ + + +void smbios_skip(byte_t **x); + +struct header* smbios_extract_values(byte_t type, void *ptr); + +void smbios_parse(const void *raw_smbios, size_t size); + +void smbios_clear(); + +byte_t smbios_current_type(); + +void* smbios_current_structure(); + +int smbios_iterate(); + +void smbios_iterate_reset(); \ No newline at end of file diff --git a/smbios_parse.h b/lib/smbios_structures.h similarity index 87% rename from smbios_parse.h rename to lib/smbios_structures.h index 5129826..db5c33f 100644 --- a/smbios_parse.h +++ b/lib/smbios_structures.h @@ -1,68 +1,14 @@ - - -/* - * Type definitions - */ - typedef uint8_t byte_t; typedef uint16_t word_t; typedef uint32_t dword_t; - -#ifdef _MSC_VER -typedef __int64 qword_t; -#else -#ifdef INT64_C typedef uint64_t qword_t; -#else -typedef (unsigned long long int) qwordt_t; -#endif -#endif typedef byte_t str_id; typedef byte_t enum_t; - -// We implement an internal Linked List after parsing -// the SMBIOS table. -typedef struct Entry { - struct Entry* next; - struct header* header; -} Entry; - - - - -/* - * Internal properties - */ -byte_t *smbios_raw_data; -size_t smbios_raw_size; -Entry *smbios_first; -Entry *smbios_current_entry; - - - -/* - * Function Prototypes - */ - - -void smbios_skip(byte_t **x); - -struct header* smbios_extract_values(byte_t type, void *ptr); - -void smbios_parse(const void *raw_smbios, size_t size); - -void smbios_clear(); - -byte_t smbios_current_type(); - -void* smbios_current_structure(); - -int smbios_iterate(); - -void smbios_iterate_reset(); - +typedef struct SMBEntryPoint { + // tada. +} SMBEntryPoint; /* @@ -301,4 +247,4 @@ struct mem_device { word_t voltage_max; word_t voltage; }; -#pragma pack(pop) \ No newline at end of file +#pragma pack(pop) diff --git a/make-example.sh b/make-example.sh new file mode 100755 index 0000000..3946a32 --- /dev/null +++ b/make-example.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Nothing exciting in here, simple static linking to our PitParser +# Ex. http://tldp.org/HOWTO/Program-Library-HOWTO/more-examples.html + +cc -Wall -g -c -o lib/libsmbios-parse.o lib/smbios_parse.c +ar rcs lib/libsmbios-parse.a lib/libsmbios-parse.o +mv lib/libsmbios-parse.a . +cc -Wall -g -c example.c -o example.o +cc -g -o example example.o -L. -lsmbios-parse -framework IOKit -framework CoreFoundation + +# Do some cleaning up +rm example.o libsmbios-parse.a lib/libsmbios-parse.o \ No newline at end of file From 2042028ce754ad6d5e6e9dcf6c472e6dd54462d7 Mon Sep 17 00:00:00 2001 From: Fergus Morrow Date: Tue, 16 Feb 2016 02:49:05 +0000 Subject: [PATCH 2/6] Use Apple smbios.h, further refactor (pretttty radiccccaaaall) --- example.c | 25 +- lib/smbios.h | 537 ++++++++++++++++++++++++++++++++++++++++ lib/smbios_parse.c | 47 ++-- lib/smbios_parse.h | 72 +++--- lib/smbios_structures.h | 250 ------------------- 5 files changed, 615 insertions(+), 316 deletions(-) create mode 100644 lib/smbios.h delete mode 100644 lib/smbios_structures.h diff --git a/example.c b/example.c index 1fa2ed0..d6c7ecf 100644 --- a/example.c +++ b/example.c @@ -2,8 +2,8 @@ #include #include "lib/smbios_parse.h" -void print_smbios_entry(struct SMBEntryPoint* e); -void print_smbios_data(byte_t* data); +void print_smbios_entry(SMBEntryPoint* e); +void print_smbios_data(SMBByte* data, size_t len); int main(int argc, const char * argv[]) { @@ -27,7 +27,7 @@ int main(int argc, const char * argv[]) { if (!dataRef) { printf("Unable to retrieve SMBIOS entry point!\n"); return -1; - } else print_smbios_entry((struct SMBEntryPoint *) CFDataGetBytePtr(dataRef)); + } else print_smbios_entry((SMBEntryPoint *) CFDataGetBytePtr(dataRef)); // Retrieve and Parse SMBIOS Data @@ -38,15 +38,30 @@ int main(int argc, const char * argv[]) { if (!dataRef) { printf("Unable to retrieve SMBIOS data!\n"); return -1; - } else print_smbios_data((byte_t*) CFDataGetBytePtr(dataRef)); + } else print_smbios_data((SMBByte*) CFDataGetBytePtr(dataRef), (size_t)CFDataGetLength(dataRef)); return 0; } void print_smbios_entry(struct SMBEntryPoint* e){ printf("Address of SMBIOS Entry Point: %p.\n", e); + printf("Version information:\n"); + printf("\t- Major Version: %d\n", e->majorVersion); + printf("\t- Minor Version: %d\n", e->minorVersion); } -void print_smbios_data(byte_t* data){ +void print_smbios_data(SMBByte* data, size_t len){ printf("Address of SMBIOS Data: %p.\n", data); + + smbios_parse(data, len); + + // Although, always check any returned pointers - don't assume they're GOOD + SMBValue *val = smbios_search(kSMBTypeProcessorInformation); + if (val != NULL) { + SMBProcessorInformation *procInfo = (SMBProcessorInformation *)val->structure; + printf("Socket Description: %hhu\n", procInfo->socketDesignation); + } + + // Clear up and free that mem. + smbios_clear(); } \ No newline at end of file diff --git a/lib/smbios.h b/lib/smbios.h new file mode 100644 index 0000000..f0e3c59 --- /dev/null +++ b/lib/smbios.h @@ -0,0 +1,537 @@ +/* + * Copyright (c) 1998-2009 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +// Changed to stdint types (*_t) +// - Fergus Morrow (16/02/2016) +typedef uint8_t SMBString; +typedef uint8_t SMBByte; +typedef uint16_t SMBWord; +typedef uint32_t SMBDWord; +typedef uint64_t SMBQWord; + + +// +// Based on System Management BIOS Reference Specification v2.5 +// + +typedef struct DMIEntryPoint +{ + SMBByte anchor[5]; + SMBByte checksum; + SMBWord tableLength; + SMBDWord tableAddress; + SMBWord structureCount; + SMBByte bcdRevision; +} __attribute__((packed)) DMIEntryPoint; + +typedef struct SMBEntryPoint +{ + SMBByte anchor[4]; + SMBByte checksum; + SMBByte entryPointLength; + SMBByte majorVersion; + SMBByte minorVersion; + SMBWord maxStructureSize; + SMBByte entryPointRevision; + SMBByte formattedArea[5]; + struct DMIEntryPoint dmi; +} __attribute__((packed)) SMBEntryPoint; + +// +// Header common to all SMBIOS structures +// + +typedef struct SMBStructHeader +{ + SMBByte type; + SMBByte length; + SMBWord handle; +} __attribute__((packed)) SMBStructHeader; + +#define SMB_STRUCT_HEADER SMBStructHeader header; + +typedef struct SMBAnchor +{ + const SMBStructHeader * header; + const uint8_t * next; + const uint8_t * end; +} SMBAnchor; + +#define SMB_ANCHOR_IS_VALID(x) \ + ((x) && ((x)->header) && ((x)->next) && ((x)->end)) + +#define SMB_ANCHOR_RESET(x) \ + bzero(x, sizeof(struct SMBAnchor)); + +// +// SMBIOS structure types. +// + +enum { + kSMBTypeBIOSInformation = 0, + kSMBTypeSystemInformation = 1, + kSMBTypeBaseBoard = 2, + kSMBTypeSystemEnclosure = 3, + kSMBTypeProcessorInformation = 4, + kSMBTypeMemoryModule = 6, + kSMBTypeCacheInformation = 7, + kSMBTypeSystemSlot = 9, + kSMBTypeOemStrings = 11, + kSMBTypePhysicalMemoryArray = 16, + kSMBTypeMemoryDevice = 17, + kSMBType32BitMemoryErrorInfo = 18, + kSMBTypeMemoryArrayMappedAddress = 19, + kSMBType64BitMemoryErrorInfo = 33, + + kSMBTypeEndOfTable = 127, + + // Apple Specific Structures. + kSMBTypeFirmwareVolume = 128, + kSMBTypeMemorySPD = 130, + kSMBTypeOemProcessorType = 131, + kSMBTypeOemProcessorBusSpeed = 132, + kSMBTypeOemPlatformFeature = 133, + + // Structures dropped by RevoBoot. + kSMBUnused = 255 +}; + +// +// BIOS Information (Type 0) +// +typedef struct SMBBIOSInformation +{ + SMB_STRUCT_HEADER // Type 0 + SMBString vendor; // BIOS vendor name + SMBString version; // BIOS version + SMBWord startSegment; // BIOS segment start + SMBString releaseDate; // BIOS release date + SMBByte romSize; // (n); 64K * (n+1) bytes + SMBQWord characteristics; // supported BIOS functions +} __attribute__((packed)) SMBBIOSInformation; + +// +// System Information (Type 1) +// + +typedef struct SMBSystemInformation +{ + // 2.0+ spec (8 bytes) + SMB_STRUCT_HEADER // Type 1 + SMBString manufacturer; + SMBString productName; + SMBString version; + SMBString serialNumber; + // 2.1+ spec (25 bytes) + SMBByte uuid[16]; // can be all 0 or all 1's + SMBByte wakeupReason; // reason for system wakeup + // 2.4+ spec (27 bytes) + SMBString SKUNumber; // System SKU# + SMBString family; // Mac, Macmini etc +} __attribute__((packed)) SMBSystemInformation; + +// +// Base Board (Type 2) +// + +typedef struct SMBBaseBoard +{ + SMB_STRUCT_HEADER // Type 2 + SMBString manufacturer; + SMBString product; + SMBString version; + SMBString serialNumber; + SMBString assetTagNumber; + SMBByte featureFlags; + SMBString locationInChassis; + SMBWord chassisHandle; + SMBByte boardType; + SMBByte numberOfContainedHandles; + // 0 - 255 contained handles go here but we do not include + // them in our structure. Be careful to use numberOfContainedHandles + // times sizeof(SMBWord) when computing the actual record size, + // if you need it. +} __attribute__((packed)) SMBBaseBoard; + +// Values for boardType in Type 2 records +enum +{ + kSMBBaseBoardUnknown = 0x01, + kSMBBaseBoardOther = 0x02, + kSMBBaseBoardServerBlade = 0x03, + kSMBBaseBoardConnectivitySwitch = 0x04, + kSMBBaseBoardSystemMgmtModule = 0x05, + kSMBBaseBoardProcessorModule = 0x06, + kSMBBaseBoardIOModule = 0x07, + kSMBBaseBoardMemoryModule = 0x08, + kSMBBaseBoardDaughter = 0x09, + kSMBBaseBoardMotherboard = 0x0A, + kSMBBaseBoardProcessorMemoryModule = 0x0B, + kSMBBaseBoardProcessorIOModule = 0x0C, + kSMBBaseBoardInterconnect = 0x0D, +}; + + +// +// System Enclosure (Type 3) +// + +typedef struct SMBSystemEnclosure +{ + SMB_STRUCT_HEADER // Type 3 + SMBString manufacturer; + SMBByte type; + SMBString version; + SMBString serialNumber; + SMBString assetTagNumber; + SMBByte bootupState; + SMBByte powerSupplyState; + SMBByte thermalState; + SMBByte securityStatus; + SMBDWord oemDefined; +} __attribute__((packed)) SMBSystemEnclosure; + +// +// Processor Information (Type 4) +// + +typedef struct SMBProcessorInformation +{ + // 2.0+ spec (26 bytes) + SMB_STRUCT_HEADER // Type 4 + SMBString socketDesignation; + SMBByte processorType; // CPU = 3 + SMBByte processorFamily; // processor family enum + SMBString manufacturer; + SMBQWord processorID; // based on CPUID + SMBString processorVersion; + SMBByte voltage; // bit7 cleared indicate legacy mode + SMBWord externalClock; // external clock in MHz + SMBWord maximumClock; // max internal clock in MHz + SMBWord currentClock; // current internal clock in MHz + SMBByte status; + SMBByte processorUpgrade; // processor upgrade enum + // 2.1+ spec (32 bytes) + SMBWord L1CacheHandle; + SMBWord L2CacheHandle; + SMBWord L3CacheHandle; + // 2.3+ spec (35 bytes) + SMBString serialNumber; + SMBString assetTag; + SMBString partNumber; + // 2.5+ spec (40 bytes) + SMBByte coreCount; // Number of cores detected by the BIOS. + SMBByte coreEnabled; // Number of cores that are enabled by the BIOS. + SMBByte threadCount; // Number of threads that are supported by this CPU (not per core). + SMBWord processorFuncSupport; // Defines which functions the processor supports. + /* 2.6+ spec (42 bytes) + SMBWord processorFamily; */ +} __attribute__((packed)) SMBProcessorInformation; + +#define kSMBProcessorInformationMinSize 26 + +// +// Memory Module Information (Type 6) +// Obsoleted since SMBIOS version 2.1 +// + +typedef struct SMBMemoryModule +{ + SMB_STRUCT_HEADER // Type 6 + SMBString socketDesignation; + SMBByte bankConnections; + SMBByte currentSpeed; + SMBWord currentMemoryType; + SMBByte installedSize; + SMBByte enabledSize; + SMBByte errorStatus; +} __attribute__((packed)) SMBMemoryModule; + +#define kSMBMemoryModuleSizeNotDeterminable 0x7D +#define kSMBMemoryModuleSizeNotEnabled 0x7E +#define kSMBMemoryModuleSizeNotInstalled 0x7F + +// +// Cache Information (Type 7) +// + +typedef struct SMBCacheInformation +{ + SMB_STRUCT_HEADER // Type 7 + SMBString socketDesignation; + SMBWord cacheConfiguration; + SMBWord maximumCacheSize; + SMBWord installedSize; + SMBWord supportedSRAMType; + SMBWord currentSRAMType; + // 2.1+ spec (12 ??? bytes) + SMBByte cacheSpeed; + SMBByte errorCorrectionType; + SMBByte systemCacheType; + SMBByte associativity; +} __attribute__((packed)) SMBCacheInformation; + +typedef struct SMBSystemSlot +{ + // 2.0+ spec (12 bytes) + SMB_STRUCT_HEADER // Type 9 + SMBString slotDesignation; + SMBByte slotType; + SMBByte slotDataBusWidth; + SMBByte currentUsage; + SMBByte slotLength; + SMBWord slotID; + SMBByte slotCharacteristics1; + // 2.1+ spec (13 bytes) + SMBByte slotCharacteristics2; + // 2.6+ spec (17 bytes) + SMBWord segmentGroupNumber; + SMBByte busNumber; + SMBByte deviceFunctionNumber; +} __attribute__((packed)) SMBSystemSlot; + +// +// OEM Strings - Type 11 (AppleSMBIOS-43) +// +// Note: Used to add IODeviceTree:/rom@0/apple-rom-version (Data) +// + +typedef struct SMBOemStrings +{ + SMB_STRUCT_HEADER // Length is a fixed value (5) + SMBByte count; +} __attribute__((packed)) SMBOemStrings; + +// +// Physical Memory Array (Type 16) +// + +typedef struct SMBPhysicalMemoryArray +{ + // 2.1+ spec (15 bytes) + SMB_STRUCT_HEADER // Type 16 + SMBByte physicalLocation; // physical location + SMBByte arrayUse; // the use for the memory array + SMBByte errorCorrection; // error correction/detection method + SMBDWord maximumCapacity; // maximum memory capacity in kilobytes + SMBWord errorHandle; // handle of a previously detected error + SMBWord numMemoryDevices; // number of memory slots or sockets +} __attribute__((packed)) SMBPhysicalMemoryArray; + +// Memory Array - Use +enum +{ + kSMBMemoryArrayUseOther = 0x01, + kSMBMemoryArrayUseUnknown = 0x02, + kSMBMemoryArrayUseSystemMemory = 0x03, + kSMBMemoryArrayUseVideoMemory = 0x04, + kSMBMemoryArrayUseFlashMemory = 0x05, + kSMBMemoryArrayUseNonVolatileMemory = 0x06, + kSMBMemoryArrayUseCacheMemory = 0x07 +}; + +// Memory Array - Error Correction Types +enum +{ + kSMBMemoryArrayErrorCorrectionTypeOther = 0x01, + kSMBMemoryArrayErrorCorrectionTypeUnknown = 0x02, + kSMBMemoryArrayErrorCorrectionTypeNone = 0x03, + kSMBMemoryArrayErrorCorrectionTypeParity = 0x04, + kSMBMemoryArrayErrorCorrectionTypeSingleBitECC = 0x05, + kSMBMemoryArrayErrorCorrectionTypeMultiBitECC = 0x06, + kSMBMemoryArrayErrorCorrectionTypeCRC = 0x07 +}; + +// +// Memory Device (Type 17) +// + +typedef struct SMBMemoryDevice +{ + // 2.1+ spec (21 bytes) + SMB_STRUCT_HEADER // Type 17 + SMBWord arrayHandle; // handle of the parent memory array + SMBWord errorHandle; // handle of a previously detected error + SMBWord totalWidth; // total width in bits; including ECC bits + SMBWord dataWidth; // data width in bits + SMBWord memorySize; // bit15 is scale, 0 = MB, 1 = KB + SMBByte formFactor; // memory device form factor + SMBByte deviceSet; // parent set of identical memory devices + SMBString deviceLocator; // labeled socket; e.g. "SIMM 3" + SMBString bankLocator; // labeled bank; e.g. "Bank 0" or "A" + SMBByte memoryType; // type of memory + SMBWord memoryTypeDetail; // additional detail on memory type + // 2.3+ spec (27 bytes) + SMBWord memorySpeed; // speed of device in MHz (0 for unknown) + SMBString manufacturer; + SMBString serialNumber; + SMBString assetTag; + SMBString partNumber; + // 2.6+ spec (28 bytes) + SMBByte attributes; +} __attribute__((packed)) SMBMemoryDevice; + +/// +/// Memory Array Mapped Address (Type 19). +/// +/// This structure provides the address mapping for a Physical Memory Array. +/// One structure is present for each contiguous address range described. +/// +typedef struct SMBMemoryArrayMappedAddress +{ + SMB_STRUCT_HEADER // Type 19 + SMBDWord StartingAddress; + SMBDWord EndingAddress; + SMBWord MemoryArrayHandle; + SMBByte PartitionWidth; + // + // Added for SMBIOS v2.7 + // + // SMBQWord ExtendedStartingAddress; + // SMBQWord ExtendedEndingAddress; +} __attribute__((packed)) SMBMemoryArrayMappedAddress; + +// +// Firmware Volume Description (Apple Specific - Type 128) +// + +enum +{ + FW_REGION_RESERVED = 0, + FW_REGION_RECOVERY = 1, + FW_REGION_MAIN = 2, + FW_REGION_NVRAM = 3, + FW_REGION_CONFIG = 4, + FW_REGION_DIAGVAULT = 5, + + NUM_FLASHMAP_ENTRIES = 8 +}; + +typedef struct FW_REGION_INFO +{ + SMBDWord StartAddress; + SMBDWord EndAddress; +} __attribute__((packed)) FW_REGION_INFO; + +typedef struct SMBFirmwareVolume +{ + SMB_STRUCT_HEADER // Type 0x80/128 + SMBByte RegionCount; + SMBByte Reserved[3]; + SMBDWord FirmwareFeatures; + SMBDWord FirmwareFeaturesMask; + SMBByte RegionType[ NUM_FLASHMAP_ENTRIES ]; + FW_REGION_INFO FlashMap[ NUM_FLASHMAP_ENTRIES ]; +} __attribute__((packed)) SMBFirmwareVolume; + +// +// Memory SPD Data (Apple Specific - Type 130) +// + +typedef struct SMBMemorySPD +{ + SMB_STRUCT_HEADER // Type 0x82/130 + SMBWord Type17Handle; + SMBWord Offset; + SMBWord Size; + SMBWord Data[]; +} __attribute__((packed)) SMBMemorySPD; + + +#if (DEBUG_SMBIOS == 4) +static const char * SMBMemoryDeviceTypes[] = +{ + "RAM", /* 00h Undefined */ + "RAM", /* 01h Other */ + "RAM", /* 02h Unknown */ + "DRAM", /* 03h DRAM */ + "EDRAM", /* 04h EDRAM */ + "VRAM", /* 05h VRAM */ + "SRAM", /* 06h SRAM */ + "RAM", /* 07h RAM */ + "ROM", /* 08h ROM */ + "FLASH", /* 09h FLASH */ + "EEPROM", /* 0Ah EEPROM */ + "FEPROM", /* 0Bh FEPROM */ + "EPROM", /* 0Ch EPROM */ + "CDRAM", /* 0Dh CDRAM */ + "3DRAM", /* 0Eh 3DRAM */ + "SDRAM", /* 0Fh SDRAM */ + "SGRAM", /* 10h SGRAM */ + "RDRAM", /* 11h RDRAM */ + "DDR SDRAM", /* 12h DDR */ + "DDR2 SDRAM", /* 13h DDR2 */ + "DDR2 FB-DIMM", /* 14h DDR2 FB-DIMM */ + "RESERVED", /* 15h Reserved */ + "RESERVED", /* 16h Reserved */ + "RESERVED", /* 17h Reserved */ + "DDR3", /* 18h DDR3, chosen in [5776134] */ + "FBD2", /* 19h FBD2 */ + "DDR4", /* 1Ah DDR4 */ + "LPDDR", /* 1Bh LPDDR */ + "LPDDR2", /* 1Ch LPDDR2 */ + "LPDDR3", /* 1Dh LPDDR3 */ + "LPDDR3", /* 1Eh LPDDR5 */ +}; + +static const int kSMBMemoryDeviceTypeCount = sizeof(SMBMemoryDeviceTypes) / sizeof(SMBMemoryDeviceTypes[0]); +#endif + + +// +// OEM – Apple Processor Type (type 0x83/131) +// + +struct SMBOemProcessorType +{ + SMB_STRUCT_HEADER + SMBWord ProcessorType; +} __attribute__((packed)) SMBOemProcessorType; + + +// +// OEM – Apple Processor Bus Speed (type 0x84/132) +// +struct SMBOemProcessorBusSpeed +{ + SMB_STRUCT_HEADER + SMBWord ProcessorBusSpeed; // MT/s unit +} __attribute__((packed)) SMBOemProcessorBusSpeed; + + +// +// OEM – Apple Platform Features (type 0x85/133 / AppleSMBIOS-43) +// +struct SMBOemPlatformFeature +{ + SMB_STRUCT_HEADER + SMBWord PlatformFeature; +} __attribute__((packed)) SMBOemPlatformFeature; + +// +// OEM – Apple SMC Version (type 0x86/134) +// +struct SMBOemSMCVersion +{ + SMB_STRUCT_HEADER + SMBString SMCVersion; +} __attribute__((packed)) SMBOemSMCVersion; \ No newline at end of file diff --git a/lib/smbios_parse.c b/lib/smbios_parse.c index 231f531..81462ce 100644 --- a/lib/smbios_parse.c +++ b/lib/smbios_parse.c @@ -5,9 +5,9 @@ #include "smbios_parse.h" -void smbios_skip(byte_t **x) { +void smbios_skip(SMBByte **x) { // Offset length of header - *x += ((struct header *) x)->length; + *x += ((SMBStructHeader *) x)->length; size_t len = 0; // If value at ptr is 0, then offset by 2 and return, @@ -21,54 +21,43 @@ void smbios_skip(byte_t **x) { } -struct header* smbios_extract_values(byte_t type, void *ptr) { - ptr = NULL; - - // Find the header for the requested type; - struct Entry *entry = smbios_first; +SMBValue* smbios_search(SMBByte type) { + SMBValue *entry = smbios_first; while(entry->next != NULL){ - if(entry->header->type == type) break; - entry = entry->next; - } - - // If it wasn't found, dump out a NULL pointer; - // Leave checking to the user application! - if(entry->header->type != type){ - return ptr; + if (entry->header->type == type) { + return entry; + } } - - // Offset pointer beyond the header, to the region of - // memory containing the values - ptr = ((byte_t *) entry->header) + entry->header->length; - return (struct header *) ptr; + + return (SMBValue *)NULL; } void smbios_parse(const void *raw_smbios, size_t size) { - byte_t *x; + SMBByte *x; smbios_raw_size = size; smbios_raw_data = malloc( smbios_raw_size ); memcpy(smbios_raw_data, raw_smbios, smbios_raw_size); // Potential mem leak here if smbios_first has already been init. - smbios_first = malloc( sizeof(Entry) ); + smbios_first = malloc( sizeof(SMBValue) ); smbios_current_entry = smbios_first; x = smbios_raw_data; - Entry *prev = NULL; + SMBValue *prev = NULL; while( (size_t)(x - smbios_raw_data) < smbios_raw_size ) { if( prev == NULL ){ // First Run - smbios_first->header = (struct header *)x; + smbios_first->header = (SMBStructHeader *)x; prev = smbios_first; continue; } // Ahoy. Potential Memory Leak Here. Please see // clear()! - Entry *e = malloc( sizeof(Entry) ); - e->header = (struct header *)x; + SMBValue *e = malloc( sizeof(SMBValue) ); + e->header = (SMBStructHeader *)x; prev->next = e; prev = e; @@ -79,7 +68,7 @@ void smbios_parse(const void *raw_smbios, size_t size) { void smbios_clear() { // Delete all Entry instances - Entry *entry = smbios_first; + SMBValue *entry = smbios_first; while( entry->next != NULL ){ entry = entry->next; free(entry); @@ -91,13 +80,13 @@ void smbios_clear() { }; -byte_t smbios_current_type(){ +SMBByte smbios_current_type(){ return smbios_current_entry->header->type; } void* smbios_current_structure(){ - return ((byte_t *) smbios_current_entry->header) + smbios_current_entry->header->length; + return ((SMBByte *) smbios_current_entry->header) + smbios_current_entry->header->length; } diff --git a/lib/smbios_parse.h b/lib/smbios_parse.h index f5769f7..6b7931d 100644 --- a/lib/smbios_parse.h +++ b/lib/smbios_parse.h @@ -2,54 +2,62 @@ #include #include #include +#include "smbios.h" -typedef uint8_t byte_t; -typedef uint16_t word_t; -typedef uint32_t dword_t; -typedef uint64_t qword_t; +// Linked List Element +typedef struct SMBValue { + struct SMBValue* next; + SMBStructHeader* header; + void* structure; +} SMBValue; -typedef byte_t str_id; -typedef byte_t enum_t; +// Internals (make static after refactor.) +SMBByte *smbios_raw_data; +size_t smbios_raw_size; +SMBValue *smbios_first; +SMBValue *smbios_current_entry; -#include "smbios_structures.h" -// We implement an internal Linked List after parsing -// the SMBIOS table. -typedef struct Entry { - struct Entry* next; - struct header* header; -} Entry; +// +// Parsing functions; parses the SMBIOS data and generates +// a linked list containing header & structure pointers. +// +// Status: +// The parser code is.. ermm.. interesting. +void smbios_parse(const void *raw_smbios, size_t size); +void smbios_skip(SMBByte **x); +void smbios_clear(); +// +// Search function, returns a pointer to the header entry +// and modifies *ptr to point directly to the entry. +// +// Status: +// Works by iterating through all of the entries, this could +// be avoided by using some form of look-up table. -/* - * Internal properties - */ -byte_t *smbios_raw_data; -size_t smbios_raw_size; -Entry *smbios_first; -Entry *smbios_current_entry; +SMBValue* smbios_search(SMBByte type); +// +// Iterator Methods +// Parser exposes an iterator API for accessing all parsed +// entries. +// Status: +// Needs to be cleaned, but as it simply traverses a linked +// list, I can't see it being too hairy. -/* - * Function Prototypes - */ +SMBByte smbios_current_type(); +void *smbios_current_structure(); +int smbios_iterate(); +void smbios_iterate_reset(); -void smbios_skip(byte_t **x); -struct header* smbios_extract_values(byte_t type, void *ptr); -void smbios_parse(const void *raw_smbios, size_t size); - -void smbios_clear(); -byte_t smbios_current_type(); -void* smbios_current_structure(); -int smbios_iterate(); -void smbios_iterate_reset(); \ No newline at end of file diff --git a/lib/smbios_structures.h b/lib/smbios_structures.h deleted file mode 100644 index db5c33f..0000000 --- a/lib/smbios_structures.h +++ /dev/null @@ -1,250 +0,0 @@ -typedef uint8_t byte_t; -typedef uint16_t word_t; -typedef uint32_t dword_t; -typedef uint64_t qword_t; - -typedef byte_t str_id; -typedef byte_t enum_t; - -typedef struct SMBEntryPoint { - // tada. -} SMBEntryPoint; - - -/* - * SMBIOS Table Structures - */ - - -enum { - smbios_type_bios_info = 0, // Required - smbios_type_system_info = 1, // Required - smbios_type_baseboard_info = 2, - smbios_type_module_info = 2, - smbios_type_system_enclosure = 3, // Required - smbios_type_system_chassis = 3, // Required - smbios_type_processor_info = 4, // Required - smbios_type_memory_controller_info = 5, // Obsolete - smbios_type_memory_module_info = 6, // Obsolete - smbios_type_cache_info = 7, // Required - smbios_type_port_connector_info = 8, - smbios_type_system_slots = 9, // Required - smbios_type_onboard_device_info = 10, // Obsolete - smbios_type_oem_strings = 11, - smbios_type_system_config_options = 12, - smbios_type_language_info = 13, - smbios_type_group_associations = 14, - smbios_type_system_event_log = 15, - smbios_type_memory_array = 16, // Required - smbios_type_memory_device = 17, // Required - smbios_type_memory_error_info_32bit = 18, - smbios_type_memory_array_mapped_addr = 19, // Required - smbios_type_memory_device_mapped_addr = 20, - smbios_type_builtin_pointing_device = 21, - smbios_type_portable_battery = 22, - smbios_type_system_reset = 23, - smbios_type_hardware_security = 24, - smbios_type_system_power_controls = 25, - smbios_type_voltage_probe = 26, - smbios_type_cooling_device = 27, - smbios_type_temperature_probe = 28, - smbios_type_electrical_current_probe = 29, - smbios_type_out_of_band_remote_access = 30, - smbios_type_bis_entry_point = 31, // Required - smbios_type_system_boot_info = 32, // Required - smbios_type_memory_error_info_64bit = 33, - smbios_type_management_device = 34, - smbios_type_management_device_component = 35, - smbios_type_management_device_threshold = 36, - smbios_type_memory_channel = 37, - smbios_type_ipmi_device_info = 38, - smbios_type_system_power_supply = 39, - smbios_type_additional_info = 40, - smbios_type_onboard_device_extinfo = 41, - smbios_type_management_controller_host = 42, - smbios_type_inactive = 126, - smbios_type_end_of_table = 127, // Always last structure -}; - - -#pragma pack(push, 1) -struct header { - byte_t type; - byte_t length; - word_t handle; -}; - -struct string_list { - byte_t count; -}; - -struct bios_info { - // 2.0 - str_id vendor; - str_id version; - word_t starting_segment; - str_id release_date; - byte_t rom_size; - qword_t characteristics; - // 2.4 - byte_t ext_char1; - byte_t ext_char2; - byte_t sb_major; - byte_t sb_minor; - byte_t ec_major; - byte_t ec_minor; -}; - -struct system_info { - // 2.0 - str_id manufacturer; - str_id product_name; - str_id version; - str_id serial_number; - // 2.1 - struct { - dword_t time_low; - word_t time_mid; - word_t time_hi_and_version; - byte_t clock_seq_hi_and_reserved; - byte_t clock_seq_low; - byte_t node[6]; - } uuid; - enum_t wakeup_type; - // 2.4 - str_id sku; - str_id family; -}; - -struct system_chassis { - // 2.0 - str_id manufacturer; - byte_t type; - str_id version; - str_id serial_number; - str_id assert_tag; - // 2.1 - enum_t bootup_state; - enum_t power_supply_state; - enum_t thermal_state; - enum_t security_status; - // 2.3 - dword_t oem; - byte_t height; - byte_t cords; -}; - -struct proc_info { - // 2.0 - str_id socket_designation; - enum_t type; - enum_t family; - str_id manufacturer; - qword_t id; - str_id version; - byte_t voltage; - word_t clock; - word_t speed_max; - word_t speed_cur; - byte_t status; - enum_t upgrade; - // 2.1 - word_t L1; - word_t L2; - word_t L3; - // 2.3 - str_id serial_number; - str_id assert_tag; - str_id part_number; - // 2.5 - byte_t cores; - byte_t cores_enabled; - byte_t threads; - word_t characteristics; - enum_t family2; -}; - -struct cache_info { - // 2.0 - str_id socket_designation; - word_t config; - word_t size_max; - word_t size_cur; - word_t sram_supported; - word_t sram_cur; - // 2.1 - byte_t speed; - enum_t error_correction_type; - enum_t system_cache_type; - enum_t associativity; -}; - -struct slot { - // 2.0 - str_id slot_designation; - enum_t type; - enum_t data_bus_width; - enum_t current_usage; - enum_t length; - word_t id; - byte_t characteristics; - // 2.1 - byte_t characteristics2; - // 2.6 - word_t segment_group; - byte_t bus; - byte_t device; -}; - -typedef struct string_list oem_strings; -typedef struct string_list system_config_options; - -struct lang_info { - byte_t installed_langs; - byte_t flags; - byte_t reserved[15]; - str_id current_lang; -}; - -struct mem_arr { - // 2.1 - enum_t location; - enum_t use; - enum_t error_correction; - dword_t capacity; - word_t error_info_handle; - word_t devices_number; - // 2.7 - qword_t capacity_ext; -}; - -struct mem_device { - // 2.1 - word_t mem_arr_handle; - word_t mem_arr_error_info_handle; - word_t total_width; - word_t data_width; - word_t size; - enum_t form_factor; - byte_t device_set; - str_id device_locator; - str_id bank_locator; - enum_t type; - word_t type_detail; - // 2.3 - word_t speed; - str_id manufacturer; - str_id serial_number; - str_id assert_tag; - str_id part_number; - // 2.6 - byte_t attributes; - // 2.7 - dword_t size_ext; - word_t clock_speed; - // 2.8 - word_t voltage_min; - word_t voltage_max; - word_t voltage; -}; -#pragma pack(pop) From 8bca5ee403dc22d5346432333d7cc057ac9ab44c Mon Sep 17 00:00:00 2001 From: Fergus Morrow Date: Tue, 16 Feb 2016 02:49:42 +0000 Subject: [PATCH 3/6] Fix erroneous blank lines --- lib/smbios_parse.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/lib/smbios_parse.h b/lib/smbios_parse.h index 6b7931d..2997cb8 100644 --- a/lib/smbios_parse.h +++ b/lib/smbios_parse.h @@ -53,11 +53,3 @@ SMBByte smbios_current_type(); void *smbios_current_structure(); int smbios_iterate(); void smbios_iterate_reset(); - - - - - - - - From 17d4d29c603e99ee6c5b622fe934f631ff1d90a7 Mon Sep 17 00:00:00 2001 From: Fergus Morrow Date: Wed, 17 Feb 2016 00:36:13 +0000 Subject: [PATCH 4/6] Refine parsing logic --- example.c | 4 +- lib/smbios_parse.c | 101 ++++++++++++++++++++++----------------------- lib/smbios_parse.h | 12 +++--- 3 files changed, 58 insertions(+), 59 deletions(-) diff --git a/example.c b/example.c index d6c7ecf..daf209e 100644 --- a/example.c +++ b/example.c @@ -48,6 +48,8 @@ void print_smbios_entry(struct SMBEntryPoint* e){ printf("Version information:\n"); printf("\t- Major Version: %d\n", e->majorVersion); printf("\t- Minor Version: %d\n", e->minorVersion); + printf("\t- Entry Point Length: %d\n", e->entryPointLength); + printf("\t- Max Structure Size: %d\n\n", e->maxStructureSize); } void print_smbios_data(SMBByte* data, size_t len){ @@ -63,5 +65,5 @@ void print_smbios_data(SMBByte* data, size_t len){ } // Clear up and free that mem. - smbios_clear(); + smbios_destroy(); } \ No newline at end of file diff --git a/lib/smbios_parse.c b/lib/smbios_parse.c index 81462ce..13010f3 100644 --- a/lib/smbios_parse.c +++ b/lib/smbios_parse.c @@ -1,30 +1,9 @@ -#include -#include -#include -#include - #include "smbios_parse.h" -void smbios_skip(SMBByte **x) { - // Offset length of header - *x += ((SMBStructHeader *) x)->length; - size_t len = 0; - - // If value at ptr is 0, then offset by 2 and return, - // else, get the length of the region in memory untl - // a null byte is encountered, add that to - if (**x == 0) x += 2; - else do { - len = strlen((const char *) x); - *x += len + 1; - } while(len > 0); -} - - SMBValue* smbios_search(SMBByte type) { SMBValue *entry = smbios_first; - while(entry->next != NULL){ - if (entry->header->type == type) { + while (entry->next != NULL) { + if (entry->structure->type == type) { return entry; } } @@ -32,68 +11,86 @@ SMBValue* smbios_search(SMBByte type) { return (SMBValue *)NULL; } +void smbios_fastforward(SMBByte **cursor) { + // If value at ptr is 0, then offset by 2 and return, + // else, get the length of the region in memory untl + // a null byte is encountered, add that to + if (**cursor == 0) cursor += 2; + else do { + len = strlen((const char *) cursor); + *cursor += len + 1; + } while(len > 0); +} void smbios_parse(const void *raw_smbios, size_t size) { - SMBByte *x; - - smbios_raw_size = size; - smbios_raw_data = malloc( smbios_raw_size ); - memcpy(smbios_raw_data, raw_smbios, smbios_raw_size); - + + // Duplicate SMBIOS structure - potentially not required + smbios_dup_data = malloc(size); + memcpy(smbios_dup_data, raw_smbios, size); + // Potential mem leak here if smbios_first has already been init. - smbios_first = malloc( sizeof(SMBValue) ); + smbios_counter = 0; + if (smbios_first != NULL) free(smbios_first); + smbios_first = malloc(sizeof(SMBValue)); smbios_current_entry = smbios_first; - x = smbios_raw_data; - SMBValue *prev = NULL; - while( (size_t)(x - smbios_raw_data) < smbios_raw_size ) { - if( prev == NULL ){ - // First Run - smbios_first->header = (SMBStructHeader *)x; - prev = smbios_first; - continue; - } - - // Ahoy. Potential Memory Leak Here. Please see - // clear()! - SMBValue *e = malloc( sizeof(SMBValue) ); - e->header = (SMBStructHeader *)x; + // Create first SMBValue entry + SMBByte *cursor = smbios_dup_data; + SMBValue *prev = malloc(sizeof(SMBValue)); + prev->structure = (SMBStructHeader *)smbios_dup_data; + smbios_counter = 1; + + // Skip strings and null bytes + cursor += (size_t)prev->structure->length; + smbios_fastforward(&cursor); + + // Iterate and repeat through the rest of the table entries + while (cursor < (smbios_dup_data + size)) { + SMBStructHeader *head = (SMBStructHeader *)cursor; + + // Create new SMBValue element + initialise values + SMBValue *e = malloc(sizeof(SMBValue)); + e->structure = head; prev->next = e; - prev = e; - smbios_skip(&x); + + cursor += (size_t)prev->structure->length;; + + smbios_fastforward(&cursor); + smbios_counter++; } } -void smbios_clear() { +void smbios_destroy() { // Delete all Entry instances SMBValue *entry = smbios_first; - while( entry->next != NULL ){ + while (entry->next != NULL) { + // How the hell was this ever meant to work? entry = entry->next; free(entry); } // Reset raw data - free(smbios_raw_data); + free(smbios_dup_data); smbios_raw_size = 0; }; SMBByte smbios_current_type(){ - return smbios_current_entry->header->type; + return smbios_current_entry->structure->type; } void* smbios_current_structure(){ - return ((SMBByte *) smbios_current_entry->header) + smbios_current_entry->header->length; + return ((SMBByte *) smbios_current_entry->structure) + smbios_current_entry->structure->length; } int smbios_iterate(){ int ret = 0; - if( smbios_current_entry->next != NULL ){ + if (smbios_current_entry->next != NULL) { smbios_current_entry = smbios_current_entry->next; ret = 1; } else { diff --git a/lib/smbios_parse.h b/lib/smbios_parse.h index 2997cb8..2ddb4c6 100644 --- a/lib/smbios_parse.h +++ b/lib/smbios_parse.h @@ -7,15 +7,15 @@ // Linked List Element typedef struct SMBValue { struct SMBValue* next; - SMBStructHeader* header; - void* structure; + SMBStructHeader* structure; } SMBValue; // Internals (make static after refactor.) -SMBByte *smbios_raw_data; -size_t smbios_raw_size; +SMBByte *smbios_dup_data; SMBValue *smbios_first; SMBValue *smbios_current_entry; +size_t smbios_raw_size; +uint8_t smbios_counter; // @@ -26,8 +26,8 @@ SMBValue *smbios_current_entry; // The parser code is.. ermm.. interesting. void smbios_parse(const void *raw_smbios, size_t size); -void smbios_skip(SMBByte **x); -void smbios_clear(); +void smbios_fastforward(SMBByte **cursor); +void smbios_destroy(); // From e726b10095c520f03a0bee29244e8f25ac7e9ba0 Mon Sep 17 00:00:00 2001 From: Fergus Morrow Date: Wed, 17 Feb 2016 00:48:48 +0000 Subject: [PATCH 5/6] Refine parsing logic --- make-example.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make-example.sh b/make-example.sh index 3946a32..917c520 100755 --- a/make-example.sh +++ b/make-example.sh @@ -10,4 +10,4 @@ cc -Wall -g -c example.c -o example.o cc -g -o example example.o -L. -lsmbios-parse -framework IOKit -framework CoreFoundation # Do some cleaning up -rm example.o libsmbios-parse.a lib/libsmbios-parse.o \ No newline at end of file +# rm example.o libsmbios-parse.a lib/libsmbios-parse.o \ No newline at end of file From 89498c3e8fd35b64622a8646c8af9e4322b8a359 Mon Sep 17 00:00:00 2001 From: Fergus Morrow Date: Wed, 17 Feb 2016 01:46:36 +0000 Subject: [PATCH 6/6] Further clean up --- lib/smbios_parse.c | 101 +++++++++++++++++++++++++++------------------ lib/smbios_parse.h | 12 +++--- 2 files changed, 66 insertions(+), 47 deletions(-) diff --git a/lib/smbios_parse.c b/lib/smbios_parse.c index 13010f3..7ea3b90 100644 --- a/lib/smbios_parse.c +++ b/lib/smbios_parse.c @@ -1,26 +1,10 @@ #include "smbios_parse.h" -SMBValue* smbios_search(SMBByte type) { - SMBValue *entry = smbios_first; - while (entry->next != NULL) { - if (entry->structure->type == type) { - return entry; - } - } - return (SMBValue *)NULL; -} +/* + * Parsing Methods + */ -void smbios_fastforward(SMBByte **cursor) { - // If value at ptr is 0, then offset by 2 and return, - // else, get the length of the region in memory untl - // a null byte is encountered, add that to - if (**cursor == 0) cursor += 2; - else do { - len = strlen((const char *) cursor); - *cursor += len + 1; - } while(len > 0); -} void smbios_parse(const void *raw_smbios, size_t size) { @@ -62,45 +46,82 @@ void smbios_parse(const void *raw_smbios, size_t size) { } +void smbios_fastforward(SMBByte **cursor) { + size_t len = 0; + + // If value at ptr is 0, then offset by 2 and return, + // else, get the length of the region in memory untl + // a null byte is encountered, add that to + if (**cursor == 0) cursor += 2; + else do { + len = strlen((const char *) cursor); + *cursor += len + 1; + } while(len > 0); +} + + void smbios_destroy() { // Delete all Entry instances SMBValue *entry = smbios_first; while (entry->next != NULL) { - // How the hell was this ever meant to work? - entry = entry->next; + SMBValue *t = entry->next; free(entry); + entry = t; } - - // Reset raw data + + // Destroy final linked list element + the duplicate SMBIOS data + free(entry); free(smbios_dup_data); - smbios_raw_size = 0; + + // Reset counters + smbios_raw_size = 0; + smbios_counter = 0; }; -SMBByte smbios_current_type(){ - return smbios_current_entry->structure->type; -} +/* + * Retrieval method + */ + +SMBValue* smbios_search(SMBByte type) { + SMBValue *entry = smbios_first; + while (entry->next != NULL) { + if (entry->structure->type == type) { + return entry; + } + } -void* smbios_current_structure(){ - return ((SMBByte *) smbios_current_entry->structure) + smbios_current_entry->structure->length; + return (SMBValue *)NULL; } -int smbios_iterate(){ - int ret = 0; - - if (smbios_current_entry->next != NULL) { - smbios_current_entry = smbios_current_entry->next; - ret = 1; - } else { - smbios_current_entry = smbios_first; +/* + * Iterator Methods + */ + + +bool smbios_iterate(){ + if(smbios_current_entry->next == NULL){ + smbios_current_entry = smbios_first; + return false; } - - return ret; + + smbios_current_entry = smbios_current_entry->next; + return true; } void smbios_iterate_reset() { smbios_current_entry = smbios_first; -} \ No newline at end of file +} + + +SMBByte smbios_current_type(){ + return smbios_current_entry->structure->type; +} + + +SMBStructHeader* smbios_current_structure(){ + return (SMBStructHeader *) smbios_current_entry->structure; +} diff --git a/lib/smbios_parse.h b/lib/smbios_parse.h index 2ddb4c6..5068dfb 100644 --- a/lib/smbios_parse.h +++ b/lib/smbios_parse.h @@ -2,6 +2,7 @@ #include #include #include +#include #include "smbios.h" // Linked List Element @@ -45,11 +46,8 @@ SMBValue* smbios_search(SMBByte type); // Iterator Methods // Parser exposes an iterator API for accessing all parsed // entries. -// Status: -// Needs to be cleaned, but as it simply traverses a linked -// list, I can't see it being too hairy. -SMBByte smbios_current_type(); -void *smbios_current_structure(); -int smbios_iterate(); -void smbios_iterate_reset(); +bool smbios_iterate(); +void smbios_iterate_reset(); +SMBByte smbios_current_type(); +SMBStructHeader* smbios_current_structure();