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␊ |
23 | static SMBWord minorVersion;␊ |
24 | ␊ |
25 | static char* getSMBStringForField(SMBStructHeader *structHeader, uint8_t field)␊ |
26 | {␊ |
27 | ␉uint8_t *stringPtr = ((uint8_t *)structHeader) + structHeader->length;␊ |
28 | ␉static char empty[2] = "";␊ |
29 | ␉if (!field)␊ |
30 | ␉␉return empty;␊ |
31 | ␉␊ |
32 | for (field--; field != 0 && strlen((char *)stringPtr) > 0; ␊ |
33 | ␉␉ field--, stringPtr = (uint8_t *)((unsigned long )stringPtr + strlen((char *)stringPtr) + 1));␊ |
34 | ␉␊ |
35 | ␉return ( 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 | {␊ |
60 | ␉self = [super init];␊ |
61 | ␉if (self!=nil)␊ |
62 | ␉{␊ |
63 | ␉␉[ self extractSmBios];␊ |
64 | ␉}␊ |
65 | ␉␊ |
66 | ␉return self;␊ |
67 | }␊ |
68 | ␊ |
69 | -(void) cleanup␊ |
70 | {␊ |
71 | ␉if (buffer!=nil)␊ |
72 | ␉{␊ |
73 | ␉␉delete [] buffer;␊ |
74 | ␉␉buffer = nil;␊ |
75 | ␉␉bufSize=0;␊ |
76 | ␉␉smString = nil;␊ |
77 | ␉}␊ |
78 | ␉␊ |
79 | ␉if (smString!=nil)␊ |
80 | ␉{␊ |
81 | ␉␉[smString release];␊ |
82 | ␉␉smString = nil;␊ |
83 | ␉}␊ |
84 | ␊ |
85 | ␉if (content!=nil) ␊ |
86 | ␉{␊ |
87 | ␉␉[content release];␊ |
88 | ␉␉content = nil;␊ |
89 | ␉}␊ |
90 | }␊ |
91 | ␊ |
92 | -(void) dealloc␊ |
93 | {␊ |
94 | ␉[self cleanup ];␊ |
95 | ␉[super dealloc];␊ |
96 | }␊ |
97 | ␊ |
98 | -(NSString*) description␊ |
99 | {␉␊ |
100 | ␉return [content description];␊ |
101 | }␊ |
102 | ␊ |
103 | -(NSUInteger) extractSmBios␊ |
104 | {␊ |
105 | ␉␊ |
106 | ␉const char* SmbiosCmd = "ioreg -lw0 | grep \"\\\"SMBIOS\\\" = <\"";␊ |
107 | ␉const char* SmbiosTag = "\"SMBIOS\" = <";␊ |
108 | ␉ShellProcess p(SmbiosCmd);␊ |
109 | ␉char line[8192]="";␊ |
110 | ␉const size_t tagLen= strlen(SmbiosTag);␊ |
111 | ␉␊ |
112 | ␉if (p.get_line(line, sizeof(line)) )␊ |
113 | ␉{␊ |
114 | ␉␉const char * p = strstr(line, SmbiosTag)+ tagLen;␊ |
115 | ␉␉std::string s = trim(p, " \t\r\n>");␊ |
116 | ␉␉␊ |
117 | ␉␉// NSLog(@"Found SMBIOS (%d) [%s]", s.length(), s.c_str() );␊ |
118 | ␊ |
119 | ␉␉[self cleanup];␊ |
120 | ␉␉␊ |
121 | ␉␉self.content = [NSMutableDictionary dictionaryWithCapacity:32];␊ |
122 | ␊ |
123 | ␉␉self.smString = [NSString stringWithUTF8String:s.c_str()];␊ |
124 | ␉␉bufSize = s.length()/2;␊ |
125 | ␉␉buffer = new UInt8[bufSize];␊ |
126 | ␉␉␊ |
127 | ␉␉for(size_t pos =0; pos < bufSize; pos++)␊ |
128 | ␉␉{␊ |
129 | ␉␉␉buffer[pos] = (HexToDec(s[pos*2])*16 + HexToDec(s[pos*2+1]));␊ |
130 | ␉␉}␊ |
131 | ␉␉␊ |
132 | ␉␉[self decodeSMBIOSTableFrom:buffer to: buffer+bufSize];␉␉␉␉␊ |
133 | ␉}␊ |
134 | ␉␊ |
135 | ␉return 0;␊ |
136 | }␊ |
137 | ␊ |
138 | -(NSString*) stringFrom:(NSUInteger) start withLen:(NSUInteger) len␊ |
139 | {␊ |
140 | ␉return [smString substringWithRange: NSMakeRange(start*2, len) ];␊ |
141 | }␊ |
142 | ␊ |
143 | -(UInt8) ByteFrom:(NSUInteger) position␊ |
144 | {␊ |
145 | ␉return position < bufSize ? buffer[position]: 0;␊ |
146 | }␊ |
147 | ␊ |
148 | -(BOOL) save:(NSString*) path␊ |
149 | {␊ |
150 | ␉NSString * error;␊ |
151 | ␉id plist = [NSPropertyListSerialization dataFromPropertyList:(id)content␊ |
152 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉ format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];␊ |
153 | ␉␊ |
154 | ␉[plist writeToFile:path atomically:YES];␊ |
155 | ␊ |
156 | ␉return 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 | {␊ |
164 | ␉NSDictionary* innerDict = [NSDictionary dictionaryWithObjects:␊ |
165 | ␉␉[NSArray arrayWithObjects: SHVAL3(vendor, version, releaseDate), nil ] ␊ |
166 | ␉␉␉␉ forKeys: [NSArray arrayWithObjects:@"Vendor", @"Version", @"Release Date", nil]];␊ |
167 | ␊ |
168 | ␉ADD_HANDLE(@"BIOS Information");␊ |
169 | ␉␊ |
170 | ␉DBG("BIOSInformation:\n");␊ |
171 | ␉DBG("\tvendor: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->vendor));␊ |
172 | ␉DBG("\tversion: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->version));␊ |
173 | ␉DBG("\treleaseDate: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->releaseDate));␊ |
174 | ␉DBG("\n");␊ |
175 | }␊ |
176 | ␊ |
177 | //-------------------------------------------------------------------------------------------------------------------------␊ |
178 | // SystemInformation␊ |
179 | //-------------------------------------------------------------------------------------------------------------------------␊ |
180 | -(void) decodeSystemInformation:(SMBSystemInformation *)structHeader␊ |
181 | {␊ |
182 | ␉NSDictionary* innerDict = ␊ |
183 | ␉␉[NSDictionary dictionaryWithObjects:␊ |
184 | ␉␉␉␉␉[NSArray arrayWithObjects: SHVAL4(manufacturer, productName, version, serialNumber), nil ]␊ |
185 | ␉␉␉␉␉␉␉␉␉forKeys: [NSArray arrayWithObjects:@"Manufacturer", @"Product Name", @"Version", @"Serial Number", nil]];␊ |
186 | ␉␊ |
187 | ␉ADD_HANDLE(@"System Information");␊ |
188 | ␉␊ |
189 | ␉DBG("SystemInformation:\n");␊ |
190 | ␉DBG("\tmanufacturer: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer));␊ |
191 | ␉DBG("\tproductName: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->productName));␊ |
192 | ␉DBG("\tversion: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->version));␊ |
193 | ␉DBG("\tserialNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber));␊ |
194 | ␉␊ |
195 | ␉if (minorVersion < 1 || structHeader->header.length < 25)␊ |
196 | ␉{␊ |
197 | ␉␉DBG("\n");␊ |
198 | ␉␉return;␊ |
199 | ␉}␊ |
200 | ␉uint8_t *uuid = structHeader->uuid;␊ |
201 | ␉DBG("\tuuid: %02X%02X%02X%02X-%02X%02X-%02X%02X-%02x%02X-%02X%02X%02X%02X%02X%02X\n",␊ |
202 | ␉␉uuid[0], uuid[1], uuid[2], uuid[3], ␊ |
203 | ␉␉uuid[4], uuid[5], ␊ |
204 | ␉␉uuid[6], uuid[7], ␊ |
205 | ␉␉uuid[8], uuid[9], ␊ |
206 | ␉␉uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);␊ |
207 | ␉DBG("\twakeupReason: 0x%x\n", structHeader->wakeupReason);␊ |
208 | ␉␊ |
209 | ␉if (minorVersion < 4 || structHeader->header.length < 27)␊ |
210 | ␉{␊ |
211 | ␉␉DBG("\n");␊ |
212 | ␉␉return;␊ |
213 | ␉}␊ |
214 | ␉DBG("\tskuNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->skuNumber));␊ |
215 | ␉DBG("\tfamily: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->family));␊ |
216 | ␉DBG("\n");␊ |
217 | }␊ |
218 | ␊ |
219 | //-------------------------------------------------------------------------------------------------------------------------␊ |
220 | // BaseBoard␊ |
221 | //-------------------------------------------------------------------------------------------------------------------------␊ |
222 | -(void) decodeBaseBoard:(SMBBaseBoard *) structHeader␊ |
223 | {␊ |
224 | ␉NSDictionary* innerDict = ␊ |
225 | ␉[NSDictionary dictionaryWithObjects:␊ |
226 | ␉ [NSArray arrayWithObjects: SHVAL7(manufacturer, product, version, serialNumber, assetTagNumber, locationInChassis, boardType), nil ]␊ |
227 | ␉␉␉␉␉␉␉␉forKeys: [NSArray arrayWithObjects:@"Manufacturer", @"Product", @"Version", @"Serial Number", ␊ |
228 | ␉␉␉␉␉␉␉␉␉␉ @"Asset Tag Number", @"Location In Chassis", @"Board Type", nil]];␊ |
229 | ␉␊ |
230 | ␉ADD_HANDLE(@"Base Board");␊ |
231 | ␊ |
232 | ␉DBG("BaseBoard:\n");␊ |
233 | ␉DBG("\tmanufacturer: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer));␊ |
234 | ␉DBG("\tproduct: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->product));␊ |
235 | ␉DBG("\tversion: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->version));␊ |
236 | ␉DBG("\tserialNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber));␊ |
237 | ␉DBG("\tassetTagNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTagNumber));␊ |
238 | ␉DBG("\tlocationInChassis: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->locationInChassis));␊ |
239 | ␉DBG("\tboardType: 0x%X\n", structHeader->boardType);␊ |
240 | ␉DBG("\n");␊ |
241 | }␊ |
242 | ␊ |
243 | //-------------------------------------------------------------------------------------------------------------------------␊ |
244 | // SystemEnclosure␊ |
245 | //-------------------------------------------------------------------------------------------------------------------------␊ |
246 | -(void) decodeSystemEnclosure:(SMBSystemEnclosure *) structHeader␊ |
247 | {␊ |
248 | ␉NSDictionary* innerDict = ␊ |
249 | ␉[NSDictionary dictionaryWithObjects:␊ |
250 | ␉ [NSArray arrayWithObjects: SHVAL5(manufacturer, type, version, serialNumber, assetTagNumber), nil ]␊ |
251 | ␉␉␉␉␉␉␉␉forKeys: [NSArray arrayWithObjects:@"Manufacturer", @"Type", @"Version", @"Serial Number", @"Asset Tag Number", nil]];␊ |
252 | ␉␊ |
253 | ␉ADD_HANDLE(@"System Enclosure");␊ |
254 | ␊ |
255 | ␉DBG("SystemEnclosure:\n");␊ |
256 | ␉DBG("\tmanufacturer: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer));␊ |
257 | ␉DBG("\ttype: %d\n", structHeader->type);␊ |
258 | ␉DBG("\tversion: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->version));␊ |
259 | ␉DBG("\tserialNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber));␊ |
260 | ␉DBG("\tassetTagNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTagNumber));␊ |
261 | ␉DBG("\n");␊ |
262 | }␊ |
263 | ␊ |
264 | //-------------------------------------------------------------------------------------------------------------------------␊ |
265 | // ProcessorInformation␊ |
266 | //-------------------------------------------------------------------------------------------------------------------------␊ |
267 | -(void) decodeProcessorInformation:(SMBProcessorInformation *) structHeader␊ |
268 | {␊ |
269 | ␉NSDictionary* clockDict = ␉[NSDictionary dictionaryWithObjects:␊ |
270 | ␉ [NSArray arrayWithObjects: MHZ(externalClock), MHZ(maximumClock), MHZ(currentClock), nil ]␊ |
271 | ␉␉␉␉␉␉␉␉forKeys: [NSArray arrayWithObjects:@"External", @"Maximum", @"Current", nil]];␊ |
272 | ␉␊ |
273 | ␉NSDictionary* procDict = ␉[NSDictionary dictionaryWithObjects:␊ |
274 | ␉ [NSArray arrayWithObjects: SHVAL(socketDesignation), DEC(processorType), HEX16(processorFamily), SHVAL(manufacturer), ␊ |
275 | ␉ LLX(processorID), SHVAL(processorVersion), nil ]␊ |
276 | ␉␉␉␉␉␉␉␉forKeys: [NSArray arrayWithObjects:@"Socket", @"Type", @"Family", @"Manufacturer", @"ID", @"Version", nil]];␊ |
277 | ␉␊ |
278 | ␉NSDictionary* innerDict = [NSDictionary dictionaryWithObjects:␊ |
279 | ␉ [NSArray arrayWithObjects: procDict, clockDict, nil ]␊ |
280 | ␉␉␉␉␉␉␉forKeys: [NSArray arrayWithObjects:@"Processor", @"Clock", nil]];␊ |
281 | ␉␊ |
282 | ␉ADD_HANDLE(@"Processor Information");␊ |
283 | ␊ |
284 | ␉DBG("ProcessorInformation:\n");␊ |
285 | ␉DBG("\tsocketDesignation: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->socketDesignation));␊ |
286 | ␉DBG("\tprocessorType: %d\n", structHeader->processorType);␊ |
287 | ␉DBG("\tprocessorFamily: 0x%X\n", structHeader->processorFamily);␊ |
288 | ␉DBG("\tmanufacturer: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer));␊ |
289 | ␉DBG("\tprocessorID: 0x%llX\n", structHeader->processorID);␊ |
290 | ␉DBG("\tprocessorVersion: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->processorVersion));␊ |
291 | ␉DBG("\texternalClock: %dMHz\n", structHeader->externalClock);␊ |
292 | ␉DBG("\tmaximumClock: %dMHz\n", structHeader->maximumClock);␊ |
293 | ␉DBG("\tcurrentClock: %dMHz\n", structHeader->currentClock);␊ |
294 | ␉␊ |
295 | ␉if (minorVersion >= 3 && structHeader->header.length >= 35)␊ |
296 | ␉{␊ |
297 | ␉␉DBG("\tserialNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber));␊ |
298 | ␉␉DBG("\tassetTag: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTag));␊ |
299 | ␉␉DBG("\tpartNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->partNumber));␊ |
300 | ␉}␊ |
301 | ␉DBG("\n");␊ |
302 | }␊ |
303 | ␊ |
304 | //-------------------------------------------------------------------------------------------------------------------------␊ |
305 | // MemoryDevice␊ |
306 | //-------------------------------------------------------------------------------------------------------------------------␊ |
307 | -(void) decodeMemoryDevice:(SMBMemoryDevice *) structHeader␊ |
308 | {␊ |
309 | ␉NSDictionary* 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 | ␉␊ |
314 | ␉NSDictionary* 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 | ␉␊ |
319 | ␉NSDictionary* innerDict = [NSDictionary dictionaryWithObjects:␊ |
320 | ␉␉␉␉␉ [NSArray arrayWithObjects: memDict, extmemDict, nil ]␊ |
321 | ␉␉␉␉␉␉␉␉␉␉␉ forKeys: [NSArray arrayWithObjects:@"Information", @"More Information", nil]];␊ |
322 | ␉ADD_HANDLE(@"Memory Device");␊ |
323 | ␉␊ |
324 | ␉DBG("MemoryDevice:\n");␊ |
325 | ␉DBG("\tdeviceLocator: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->deviceLocator));␊ |
326 | ␉DBG("\tbankLocator: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->bankLocator));␊ |
327 | ␉DBG("\tmemoryType: %s\n", SMBMemoryDeviceTypes[structHeader->memoryType]);␊ |
328 | ␉␊ |
329 | ␉if (structHeader->header.length < 27)␊ |
330 | ␉{␉␊ |
331 | ␉␉DBG("\n");␊ |
332 | ␉␉return;␊ |
333 | ␉}␊ |
334 | ␊ |
335 | ␉DBG("\tmemorySpeed: %dMHz\n", structHeader->memorySpeed);␊ |
336 | ␉DBG("\tmanufacturer: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->manufacturer));␊ |
337 | ␉DBG("\tserialNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->serialNumber));␊ |
338 | ␉DBG("\tassetTag: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->assetTag));␊ |
339 | ␉DBG("\tpartNumber: %s\n", getSMBStringForField((SMBStructHeader *)structHeader, structHeader->partNumber));␊ |
340 | ␉DBG("\n");␊ |
341 | }␊ |
342 | ␊ |
343 | //-------------------------------------------------------------------------------------------------------------------------␊ |
344 | // Apple Specific␊ |
345 | //-------------------------------------------------------------------------------------------------------------------------␊ |
346 | -(void) decodeOemProcessorType:(SMBOemProcessorType *)structHeader␊ |
347 | {␊ |
348 | ␉NSDictionary* innerDict = [NSDictionary dictionaryWithObjects: [NSArray arrayWithObjects: SHVAL(ProcessorType), nil ] ␊ |
349 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉ forKeys: [NSArray arrayWithObjects:@"Processor Type", nil]];␊ |
350 | ␉ADD_HANDLE(@"Apple Processor Type");␊ |
351 | ␊ |
352 | ␉DBG("AppleProcessorType:\n");␊ |
353 | ␉DBG("\tProcessorType: 0x%x\n", ((SMBOemProcessorType *)structHeader)->ProcessorType);␊ |
354 | ␉DBG("\n");␊ |
355 | }␊ |
356 | ␊ |
357 | -(void) decodeOemProcessorBusSpeed:(SMBOemProcessorBusSpeed *)structHeader␊ |
358 | {␊ |
359 | ␉NSString * qpi = [NSString stringWithFormat:@"%d.%d GT/s",␊ |
360 | ␉␉␉␉␉ ((SMBOemProcessorBusSpeed *)structHeader)->ProcessorBusSpeed / 1000, ␊ |
361 | ␉␉␉␉␉ (((SMBOemProcessorBusSpeed *)structHeader)->ProcessorBusSpeed / 100) % 10];␊ |
362 | ␉NSDictionary* innerDict = [NSDictionary dictionaryWithObjects:␊ |
363 | ␉␉␉␉␉␉␉ [NSArray arrayWithObjects: qpi, nil ] forKeys: [NSArray arrayWithObjects:@"Bus Speed (QPI)", nil]];␊ |
364 | ␉ADD_HANDLE(@"Apple Processor Bus Speed");␊ |
365 | ␊ |
366 | ␉DBG("AppleProcessorBusSpeed:\n");␊ |
367 | ␉DBG("\tProcessorBusSpeed (QPI): %d.%dGT/s\n", ␊ |
368 | ␉␉((SMBOemProcessorBusSpeed *)structHeader)->ProcessorBusSpeed / 1000, ␊ |
369 | ␉␉(((SMBOemProcessorBusSpeed *)structHeader)->ProcessorBusSpeed / 100) % 10);␊ |
370 | ␉DBG("\n");␊ |
371 | }␊ |
372 | //-------------------------------------------------------------------------------------------------------------------------␊ |
373 | ␊ |
374 | ␊ |
375 | -(void) decodeSMBIOSTableFrom:(uint8_t *) ptr to: (uint8_t*) end␊ |
376 | {␊ |
377 | ␉DBG("\n");␊ |
378 | ␉for (SMBStructHeader *structHeader = (SMBStructHeader*)ptr; structHeader < (SMBStructHeader*)end ;)␊ |
379 | ␉{␊ |
380 | ␉␉// DBG("Type: %d, Length: %d, Handle: 0x%x\n", structHeader->type, structHeader->length, structHeader->handle);␊ |
381 | ␉␉switch (structHeader->type)␊ |
382 | ␉␉{␊ |
383 | ␉␉␉case kSMBTypeBIOSInformation:␊ |
384 | ␉␉␉␉[self decodeBIOSInformation: (SMBBIOSInformation *) structHeader];␊ |
385 | ␉␉␉␉break;␊ |
386 | ␉␉␉␉␊ |
387 | ␉␉␉case kSMBTypeSystemInformation:␊ |
388 | ␉␉␉␉[self decodeSystemInformation: (SMBSystemInformation *)structHeader];␊ |
389 | ␉␉␉␉break;␊ |
390 | ␉␉␉␉␊ |
391 | ␉␉␉case kSMBTypeBaseBoard:␊ |
392 | ␉␉␉␉[self decodeBaseBoard: (SMBBaseBoard *)structHeader];␊ |
393 | ␉␉␉␉break;␊ |
394 | ␉␉␉␉␊ |
395 | ␉␉␉case kSMBTypeSystemEnclosure:␊ |
396 | ␉␉␉␉[self decodeSystemEnclosure:(SMBSystemEnclosure *)structHeader];␊ |
397 | ␉␉␉␉break;␊ |
398 | ␉␉␉␉␊ |
399 | ␉␉␉case kSMBTypeProcessorInformation:␊ |
400 | ␉␉␉␉[self decodeProcessorInformation:(SMBProcessorInformation *)structHeader];␊ |
401 | ␉␉␉␉break;␊ |
402 | ␉␉␉␉␊ |
403 | ␉␉␉case kSMBTypeMemoryDevice:␊ |
404 | ␉␉␉␉[self decodeMemoryDevice:(SMBMemoryDevice *)structHeader];␊ |
405 | ␉␉␉␉break;␊ |
406 | ␉␉␉␉␊ |
407 | ␉␉␉case kSMBTypeOemProcessorType:␊ |
408 | ␉␉␉␉[self decodeOemProcessorType:(SMBOemProcessorType *)structHeader];␊ |
409 | ␉␉␉␉break;␊ |
410 | ␉␉␉␉␊ |
411 | ␉␉␉case kSMBTypeOemProcessorBusSpeed:␊ |
412 | ␉␉␉␉[self decodeOemProcessorBusSpeed:(SMBOemProcessorBusSpeed *)structHeader];␊ |
413 | ␉␉␉␉break;␊ |
414 | ␉␉␉␉␊ |
415 | ␉␉␉case kSMBTypeEndOfTable:␉␉/* Skip, to be added at the end */␊ |
416 | ␉␉␉␉/* Skip all Apple Specific Structures */␊ |
417 | ␉␉␉case kSMBTypeFirmwareVolume:␊ |
418 | ␉␉␉case kSMBTypeMemorySPD:␊ |
419 | ␉␉␉default:␊ |
420 | ␉␉␉{␉␉␉␉␊ |
421 | /*␊ |
422 | ␉␉␉␉NSDictionary* innerDict = [NSDictionary dictionaryWithObjects: [NSArray arrayWithObjects: nil ] forKeys: [NSArray arrayWithObjects:nil]];␊ |
423 | ␉␉␉␉NSString* title = [NSString stringWithFormat:@"Type %d Len=%d (0x%02x)", (int) structHeader->type, structHeader->length, structHeader->handle];␊ |
424 | ␉␉␉␉[dict setValue:innerDict forKey: title ];␊ |
425 | */␊ |
426 | ␉␉␉}␉␉␉␉␊ |
427 | ␉␉␉␉break;␊ |
428 | ␉␉}␊ |
429 | ␉␉␊ |
430 | ␉␉ptr = (uint8_t*) (((unsigned long)structHeader) + structHeader->length);␊ |
431 | ␉␉for (; ((uint16_t *)ptr)[0] != 0; ptr++);␊ |
432 | ␉␉␊ |
433 | ␉␉if (((uint16_t *)ptr)[0] == 0)␊ |
434 | ␉␉␉ptr += 2;␊ |
435 | ␉␉␊ |
436 | ␉␉structHeader = (SMBStructHeader *)ptr;␊ |
437 | ␉}␊ |
438 | ␉DBG("\n");␊ |
439 | }␊ |
440 | ␊ |
441 | //-------------------------------------------------------------------------------------------␊ |
442 | // Outline view datasource methods␊ |
443 | //-------------------------------------------------------------------------------------------␊ |
444 | - (int)outlineView:(NSOutlineView *)ov numberOfChildrenOfItem:(id)item␊ |
445 | {␊ |
446 | ␉// this is called with item == nil when asking how many root items there are␊ |
447 | ␉if (item == nil)␊ |
448 | ␉␉return [self.content count]; // return the number of A's we have␊ |
449 | ␉␊ |
450 | ␉// Here, item will be an A, so we return the count of A's items␊ |
451 | ␉return [[item subitems] count];␊ |
452 | }␊ |
453 | ␊ |
454 | //-------------------------------------------------------------------------------------------␊ |
455 | - (BOOL)outlineView:(NSOutlineView *)ov isItemExpandable:(id)item␊ |
456 | {␊ |
457 | ␉// this is called to ask if a particular item has any child items␊ |
458 | ␉// to determine this, we need to know if it is an A which might have some,␊ |
459 | ␉// or a B, which doesn't have any. This will be called to see if numberOfChildrenOfItem␊ |
460 | ␉// should be called on the item passed in to determine how many.␊ |
461 | ␉␊ |
462 | ␉// Ours, only A's are potentially expandable. They also have to have some subitems␊ |
463 | ␉return [item isKindOfClass:[NSDictionary class]] && [[item subitems] count] > 0;␊ |
464 | }␊ |
465 | ␊ |
466 | //-------------------------------------------------------------------------------------------␊ |
467 | - (id)outlineView:(NSOutlineView *)ov child:(int)index ofItem:(id)item␊ |
468 | {␊ |
469 | ␉// Here, the outline view is asking for the whole child item. Not values␊ |
470 | ␉// within it yet. In our case, both the single root item (nil) and␉A's have␊ |
471 | ␉// childs. This is called after asking numberOfChildrenOfItem. We␉return␊ |
472 | ␉// the children themselves here. When passed nil for item, the␉outline view␊ |
473 | ␉// is asking for the root level items␊ |
474 | ␉␊ |
475 | ␉// Asking for A's␊ |
476 | ␉if (item == nil)␊ |
477 | ␉␉return content;␊ |
478 | ␉␊ |
479 | ␉// Here, item is an A, and it's asking for our B child item at the index␊ |
480 | ␉if ([item isKindOfClass:[NSDictionary class]])␊ |
481 | ␉␉return [[item subitems] objectAtIndex:index];␊ |
482 | ␉␊ |
483 | ␉// shouldn't get here␊ |
484 | ␉return nil;␊ |
485 | }␊ |
486 | ␊ |
487 | //-------------------------------------------------------------------------------------------␊ |
488 | - (id)outlineView:(NSOutlineView *)ov␊ |
489 | objectValueForTableColumn:(NSTableColumn *)tc␊ |
490 | ␉␉ byItem:(id)item␊ |
491 | {␊ |
492 | ␉// Finally, as the last step, this method is called to get the actual␊ |
493 | ␉// values (or display items) for a instance of A or B␊ |
494 | ␉// You can do special cases based on whether you are passed an A or B␊ |
495 | ␉// or simply make this a one liner by calling return [item valueForKey:[tc identifier]],␊ |
496 | ␉// but both A and B have to have the supporting interfaces implemented the same.␊ |
497 | ␉␊ |
498 | ␉// if there is some difference, or you want to trap different things␉depending on␊ |
499 | ␉// which class you are passed as item, you can also check here...␊ |
500 | ␉␊ |
501 | ␉if ([item isKindOfClass:[NSDictionary class]])␊ |
502 | ␉{␊ |
503 | ␉␉// Do something special for A's here to calculate value␊ |
504 | ␉␉// (I'm getting lazy though)␊ |
505 | ␉␉return [item valueForKey:[tc identifier]];␊ |
506 | ␉}␊ |
507 | ␉␊ |
508 | ␉// won't get here␊ |
509 | ␉return item;␊ |
510 | }␊ |
511 | @end␊ |
512 | |