Chameleon Applications

Chameleon Applications Svn Source Tree

Root/trunk/ChameleonPrefPane/Sources/SmbiosExtractor.mm

  • Property svn:executable set to *
1//
2// SmbiosExtractor.mm
3// ChameleonPrefPane
4//
5// Created by Rekursor on 11-11-27.
6//
7
8#import "SmbiosExtractor.h"
9#include "ShellProcess.h"
10#include "string_util.h"
11#include "smbios.h"
12#include "PropertyList.h"
13#include "smbios.h"
14#include <stdio.h>
15#ifndef DEBUG_SMBIOS
16#define DEBUG_SMBIOS 0
17#endif
18#if 0
19#define DBG(x...)printf(x)
20#else
21#define DBG(x...)
22#endif
23static SMBWord minorVersion;
24
25static char* getSMBStringForField(SMBStructHeader *structHeader, uint8_t field)
26{
27uint8_t *stringPtr = ((uint8_t *)structHeader) + structHeader->length;
28static char empty[2] = "";
29if (!field)
30return empty;
31
32 for (field--; field != 0 && strlen((char *)stringPtr) > 0;
33 field--, stringPtr = (uint8_t *)((unsigned long )stringPtr + strlen((char *)stringPtr) + 1));
34
35return ( char*) (stringPtr ? (char*) stringPtr : empty);
36}
37
38#define SHVAL(field) [NSString stringWithUTF8String: getSMBStringForField((SMBStructHeader *)structHeader, structHeader->field)]
39#define SHVAL2(f,g) SHVAL(f),SHVAL(g)
40#define SHVAL3(f,g,h) SHVAL2(f,g),SHVAL(h)
41#define SHVAL4(f,g,h,i) SHVAL2(f,g),SHVAL2(h,i)
42#define SHVAL5(f,g,h,i,j) SHVAL4(f,g,h,i),SHVAL(j)
43#define SHVAL6(f,g,h,i,j,k) SHVAL5(f,g,h,i,j),SHVAL(k)
44#define SHVAL7(f,g,h,i,j,k,l) SHVAL6(f,g,h,i,j,k),SHVAL(l)
45
46#define MHZ(f) [NSString stringWithFormat:@"%d MHZ", (int)structHeader->f]
47#define DEC(f) [NSString stringWithFormat:@"%d", (int)structHeader->f]
48#define LLX(f) [NSString stringWithFormat:@"%llX", structHeader->f]
49#define HEX32(f) [NSString stringWithFormat:@"0x%08X", (int)structHeader->f]
50#define HEX16(f) [NSString stringWithFormat:@"0x%04X", (int)structHeader->f]
51#define HEX8(f) [NSString stringWithFormat:@"%0x02X", (int)structHeader->f]
52
53@implementation SmbiosExtractor
54
55@synthesize content;
56@synthesize smString;
57@synthesize bufSize;
58-(id) init
59{
60self = [super init];
61if (self!=nil)
62{
63[ self extractSmBios];
64}
65
66return self;
67}
68
69-(void) cleanup
70{
71if (buffer!=nil)
72{
73delete [] buffer;
74buffer = nil;
75bufSize=0;
76smString = nil;
77}
78
79if (smString!=nil)
80{
81[smString release];
82smString = nil;
83}
84
85if (content!=nil)
86{
87[content release];
88content = nil;
89}
90}
91
92-(void) dealloc
93{
94[self cleanup ];
95[super dealloc];
96}
97
98-(NSString*) description
99{
100return [content description];
101}
102
103-(NSUInteger) extractSmBios
104{
105
106const char* SmbiosCmd = "ioreg -lw0 | grep \"\\\"SMBIOS\\\" = <\"";
107const char* SmbiosTag = "\"SMBIOS\" = <";
108ShellProcess p(SmbiosCmd);
109char line[8192]="";
110const size_t tagLen= strlen(SmbiosTag);
111
112if (p.get_line(line, sizeof(line)) )
113{
114const char * p = strstr(line, SmbiosTag)+ tagLen;
115std::string s = trim(p, " \t\r\n>");
116
117// NSLog(@"Found SMBIOS (%d) [%s]", s.length(), s.c_str() );
118
119[self cleanup];
120
121self.content = [NSMutableDictionary dictionaryWithCapacity:32];
122
123self.smString = [NSString stringWithUTF8String:s.c_str()];
124bufSize = s.length()/2;
125buffer = new UInt8[bufSize];
126
127for(size_t pos =0; pos < bufSize; pos++)
128{
129buffer[pos] = (HexToDec(s[pos*2])*16 + HexToDec(s[pos*2+1]));
130}
131
132[self decodeSMBIOSTableFrom:buffer to: buffer+bufSize];
133}
134
135return 0;
136}
137
138-(NSString*) stringFrom:(NSUInteger) start withLen:(NSUInteger) len
139{
140return [smString substringWithRange: NSMakeRange(start*2, len) ];
141}
142
143-(UInt8) ByteFrom:(NSUInteger) position
144{
145return position < bufSize ? buffer[position]: 0;
146}
147
148-(BOOL) save:(NSString*) path
149{
150NSString * error;
151id plist = [NSPropertyListSerialization dataFromPropertyList:(id)content
152 format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];
153
154[plist writeToFile:path atomically:YES];
155
156return YES;
157}
158#define ADD_HANDLE(text) [content setValue:innerDict forKey: [NSString stringWithFormat:@"%@ (0x%02x)", text, (int) structHeader->header.handle] ]
159//-------------------------------------------------------------------------------------------------------------------------
160// BIOSInformation
161//-------------------------------------------------------------------------------------------------------------------------
162-(void) decodeBIOSInformation:(SMBBIOSInformation *)structHeader
163{
164NSDictionary* innerDict = [NSDictionary dictionaryWithObjects:
165[NSArray arrayWithObjects: SHVAL3(vendor, version, releaseDate), nil ]
166 forKeys: [NSArray arrayWithObjects:@"Vendor", @"Version", @"Release Date", nil]];
167
168ADD_HANDLE(@"BIOS Information");
169
170DBG("BIOSInformation:\n");
171DBG("\tvendor: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->vendor));
172DBG("\tversion: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->version));
173DBG("\treleaseDate: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->releaseDate));
174DBG("\n");
175}
176
177//-------------------------------------------------------------------------------------------------------------------------
178// SystemInformation
179//-------------------------------------------------------------------------------------------------------------------------
180-(void) decodeSystemInformation:(SMBSystemInformation *)structHeader
181{
182NSDictionary* innerDict =
183[NSDictionary dictionaryWithObjects:
184[NSArray arrayWithObjects: SHVAL4(manufacturer, productName, version, serialNumber), nil ]
185forKeys: [NSArray arrayWithObjects:@"Manufacturer", @"Product Name", @"Version", @"Serial Number", nil]];
186
187ADD_HANDLE(@"System Information");
188
189DBG("SystemInformation:\n");
190DBG("\tmanufacturer: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer));
191DBG("\tproductName: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->productName));
192DBG("\tversion: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->version));
193DBG("\tserialNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber));
194
195if (minorVersion < 1 || structHeader->header.length < 25)
196{
197DBG("\n");
198return;
199}
200uint8_t *uuid = structHeader->uuid;
201DBG("\tuuid: %02X%02X%02X%02X-%02X%02X-%02X%02X-%02x%02X-%02X%02X%02X%02X%02X%02X\n",
202uuid[0], uuid[1], uuid[2], uuid[3],
203uuid[4], uuid[5],
204uuid[6], uuid[7],
205uuid[8], uuid[9],
206uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
207DBG("\twakeupReason: 0x%x\n", structHeader->wakeupReason);
208
209if (minorVersion < 4 || structHeader->header.length < 27)
210{
211DBG("\n");
212return;
213}
214DBG("\tskuNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->skuNumber));
215DBG("\tfamily: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->family));
216DBG("\n");
217}
218
219//-------------------------------------------------------------------------------------------------------------------------
220// BaseBoard
221//-------------------------------------------------------------------------------------------------------------------------
222-(void) decodeBaseBoard:(SMBBaseBoard *) structHeader
223{
224NSDictionary* innerDict =
225[NSDictionary dictionaryWithObjects:
226 [NSArray arrayWithObjects: SHVAL7(manufacturer, product, version, serialNumber, assetTagNumber, locationInChassis, boardType), nil ]
227forKeys: [NSArray arrayWithObjects:@"Manufacturer", @"Product", @"Version", @"Serial Number",
228 @"Asset Tag Number", @"Location In Chassis", @"Board Type", nil]];
229
230ADD_HANDLE(@"Base Board");
231
232DBG("BaseBoard:\n");
233DBG("\tmanufacturer: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer));
234DBG("\tproduct: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->product));
235DBG("\tversion: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->version));
236DBG("\tserialNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber));
237DBG("\tassetTagNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTagNumber));
238DBG("\tlocationInChassis: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->locationInChassis));
239DBG("\tboardType: 0x%X\n", structHeader->boardType);
240DBG("\n");
241}
242
243//-------------------------------------------------------------------------------------------------------------------------
244// SystemEnclosure
245//-------------------------------------------------------------------------------------------------------------------------
246-(void) decodeSystemEnclosure:(SMBSystemEnclosure *) structHeader
247{
248NSDictionary* innerDict =
249[NSDictionary dictionaryWithObjects:
250 [NSArray arrayWithObjects: SHVAL5(manufacturer, type, version, serialNumber, assetTagNumber), nil ]
251forKeys: [NSArray arrayWithObjects:@"Manufacturer", @"Type", @"Version", @"Serial Number", @"Asset Tag Number", nil]];
252
253ADD_HANDLE(@"System Enclosure");
254
255DBG("SystemEnclosure:\n");
256DBG("\tmanufacturer: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer));
257DBG("\ttype: %d\n", structHeader->type);
258DBG("\tversion: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->version));
259DBG("\tserialNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber));
260DBG("\tassetTagNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTagNumber));
261DBG("\n");
262}
263
264//-------------------------------------------------------------------------------------------------------------------------
265// ProcessorInformation
266//-------------------------------------------------------------------------------------------------------------------------
267-(void) decodeProcessorInformation:(SMBProcessorInformation *) structHeader
268{
269NSDictionary* clockDict = [NSDictionary dictionaryWithObjects:
270 [NSArray arrayWithObjects: MHZ(externalClock), MHZ(maximumClock), MHZ(currentClock), nil ]
271forKeys: [NSArray arrayWithObjects:@"External", @"Maximum", @"Current", nil]];
272
273NSDictionary* procDict = [NSDictionary dictionaryWithObjects:
274 [NSArray arrayWithObjects: SHVAL(socketDesignation), DEC(processorType), HEX16(processorFamily), SHVAL(manufacturer),
275 LLX(processorID), SHVAL(processorVersion), nil ]
276forKeys: [NSArray arrayWithObjects:@"Socket", @"Type", @"Family", @"Manufacturer", @"ID", @"Version", nil]];
277
278NSDictionary* innerDict = [NSDictionary dictionaryWithObjects:
279 [NSArray arrayWithObjects: procDict, clockDict, nil ]
280forKeys: [NSArray arrayWithObjects:@"Processor", @"Clock", nil]];
281
282ADD_HANDLE(@"Processor Information");
283
284DBG("ProcessorInformation:\n");
285DBG("\tsocketDesignation: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->socketDesignation));
286DBG("\tprocessorType: %d\n", structHeader->processorType);
287DBG("\tprocessorFamily: 0x%X\n", structHeader->processorFamily);
288DBG("\tmanufacturer: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer));
289DBG("\tprocessorID: 0x%llX\n", structHeader->processorID);
290DBG("\tprocessorVersion: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->processorVersion));
291DBG("\texternalClock: %dMHz\n", structHeader->externalClock);
292DBG("\tmaximumClock: %dMHz\n", structHeader->maximumClock);
293DBG("\tcurrentClock: %dMHz\n", structHeader->currentClock);
294
295if (minorVersion >= 3 && structHeader->header.length >= 35)
296{
297DBG("\tserialNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber));
298DBG("\tassetTag: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTag));
299DBG("\tpartNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->partNumber));
300}
301DBG("\n");
302}
303
304//-------------------------------------------------------------------------------------------------------------------------
305// MemoryDevice
306//-------------------------------------------------------------------------------------------------------------------------
307-(void) decodeMemoryDevice:(SMBMemoryDevice *) structHeader
308{
309NSDictionary* memDict = [NSDictionary dictionaryWithObjects:
310 [NSArray arrayWithObjects: SHVAL2(deviceLocator, bankLocator),
311 [NSString stringWithUTF8String: SMBMemoryDeviceTypes[structHeader->memoryType]], nil ]
312 forKeys: [NSArray arrayWithObjects:@"Device Locator", @"Bank Locator", @"Memory Type", nil]];
313
314NSDictionary* extmemDict = (structHeader->header.length < 27) ? nil :
315[NSDictionary dictionaryWithObjects:
316 [NSArray arrayWithObjects: MHZ(memorySpeed), SHVAL4(manufacturer, serialNumber, assetTag, partNumber), nil ]
317 forKeys: [NSArray arrayWithObjects:@"Memory Speed", @"Manufacturer", @"Serial Number", @"Asset Tag", @"Part Number", nil]];
318
319NSDictionary* innerDict = [NSDictionary dictionaryWithObjects:
320 [NSArray arrayWithObjects: memDict, extmemDict, nil ]
321 forKeys: [NSArray arrayWithObjects:@"Information", @"More Information", nil]];
322ADD_HANDLE(@"Memory Device");
323
324DBG("MemoryDevice:\n");
325DBG("\tdeviceLocator: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->deviceLocator));
326DBG("\tbankLocator: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->bankLocator));
327DBG("\tmemoryType: %s\n", SMBMemoryDeviceTypes[structHeader->memoryType]);
328
329if (structHeader->header.length < 27)
330{
331DBG("\n");
332return;
333}
334
335DBG("\tmemorySpeed: %dMHz\n", structHeader->memorySpeed);
336DBG("\tmanufacturer: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer));
337DBG("\tserialNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber));
338DBG("\tassetTag: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTag));
339DBG("\tpartNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->partNumber));
340DBG("\n");
341}
342
343//-------------------------------------------------------------------------------------------------------------------------
344// Apple Specific
345//-------------------------------------------------------------------------------------------------------------------------
346-(void) decodeOemProcessorType:(SMBOemProcessorType *)structHeader
347{
348NSDictionary* innerDict = [NSDictionary dictionaryWithObjects: [NSArray arrayWithObjects: SHVAL(ProcessorType), nil ]
349 forKeys: [NSArray arrayWithObjects:@"Processor Type", nil]];
350ADD_HANDLE(@"Apple Processor Type");
351
352DBG("AppleProcessorType:\n");
353DBG("\tProcessorType: 0x%x\n", ((SMBOemProcessorType *)structHeader)->ProcessorType);
354DBG("\n");
355}
356
357-(void) decodeOemProcessorBusSpeed:(SMBOemProcessorBusSpeed *)structHeader
358{
359NSString * qpi = [NSString stringWithFormat:@"%d.%d GT/s",
360 ((SMBOemProcessorBusSpeed *)structHeader)->ProcessorBusSpeed / 1000,
361 (((SMBOemProcessorBusSpeed *)structHeader)->ProcessorBusSpeed / 100) % 10];
362NSDictionary* innerDict = [NSDictionary dictionaryWithObjects:
363 [NSArray arrayWithObjects: qpi, nil ] forKeys: [NSArray arrayWithObjects:@"Bus Speed (QPI)", nil]];
364ADD_HANDLE(@"Apple Processor Bus Speed");
365
366DBG("AppleProcessorBusSpeed:\n");
367DBG("\tProcessorBusSpeed (QPI): %d.%dGT/s\n",
368((SMBOemProcessorBusSpeed *)structHeader)->ProcessorBusSpeed / 1000,
369(((SMBOemProcessorBusSpeed *)structHeader)->ProcessorBusSpeed / 100) % 10);
370DBG("\n");
371}
372//-------------------------------------------------------------------------------------------------------------------------
373
374
375-(void) decodeSMBIOSTableFrom:(uint8_t *) ptr to: (uint8_t*) end
376{
377DBG("\n");
378for (SMBStructHeader *structHeader = (SMBStructHeader*)ptr; structHeader < (SMBStructHeader*)end ;)
379{
380// DBG("Type: %d, Length: %d, Handle: 0x%x\n", structHeader->type, structHeader->length, structHeader->handle);
381switch (structHeader->type)
382{
383case kSMBTypeBIOSInformation:
384[self decodeBIOSInformation: (SMBBIOSInformation *) structHeader];
385break;
386
387case kSMBTypeSystemInformation:
388[self decodeSystemInformation: (SMBSystemInformation *)structHeader];
389break;
390
391case kSMBTypeBaseBoard:
392[self decodeBaseBoard: (SMBBaseBoard *)structHeader];
393break;
394
395case kSMBTypeSystemEnclosure:
396[self decodeSystemEnclosure:(SMBSystemEnclosure *)structHeader];
397break;
398
399case kSMBTypeProcessorInformation:
400[self decodeProcessorInformation:(SMBProcessorInformation *)structHeader];
401break;
402
403case kSMBTypeMemoryDevice:
404[self decodeMemoryDevice:(SMBMemoryDevice *)structHeader];
405break;
406
407case kSMBTypeOemProcessorType:
408[self decodeOemProcessorType:(SMBOemProcessorType *)structHeader];
409break;
410
411case kSMBTypeOemProcessorBusSpeed:
412[self decodeOemProcessorBusSpeed:(SMBOemProcessorBusSpeed *)structHeader];
413break;
414
415case kSMBTypeEndOfTable:/* Skip, to be added at the end */
416/* Skip all Apple Specific Structures */
417case kSMBTypeFirmwareVolume:
418case kSMBTypeMemorySPD:
419default:
420{
421/*
422NSDictionary* innerDict = [NSDictionary dictionaryWithObjects: [NSArray arrayWithObjects: nil ] forKeys: [NSArray arrayWithObjects:nil]];
423NSString* title = [NSString stringWithFormat:@"Type %d Len=%d (0x%02x)", (int) structHeader->type, structHeader->length, structHeader->handle];
424[dict setValue:innerDict forKey: title ];
425 */
426}
427break;
428}
429
430ptr = (uint8_t*) (((unsigned long)structHeader) + structHeader->length);
431for (; ((uint16_t *)ptr)[0] != 0; ptr++);
432
433if (((uint16_t *)ptr)[0] == 0)
434ptr += 2;
435
436structHeader = (SMBStructHeader *)ptr;
437}
438DBG("\n");
439}
440
441
442
443@end
444

Archive Download this file

Revision: 383