From 1c5e975c8bb56c194970525849c1e4aa6fecd136 Mon Sep 17 00:00:00 2001 From: Muntashir Al-Islam Date: Sat, 18 Aug 2018 20:38:38 +0600 Subject: [PATCH] Added option to output JSON, Updated PCI IDs, bump to version 1.6 --- DPCIManager.xcodeproj/project.pbxproj | 20 +++++++++---- DPCIManager/DPCIManager-Prefix.pch | 2 +- DPCIManager/JSON.h | 20 +++++++++++++ DPCIManager/JSON.m | 41 +++++++++++++++++++++++++++ DPCIManager/PCI.h | 3 +- DPCIManager/PCI.m | 31 +++++++++++++++++++- dspci/main.m | 21 ++++++++++---- 7 files changed, 123 insertions(+), 15 deletions(-) create mode 100644 DPCIManager/JSON.h create mode 100644 DPCIManager/JSON.m diff --git a/DPCIManager.xcodeproj/project.pbxproj b/DPCIManager.xcodeproj/project.pbxproj index 166a734..69a39d8 100644 --- a/DPCIManager.xcodeproj/project.pbxproj +++ b/DPCIManager.xcodeproj/project.pbxproj @@ -3,10 +3,12 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 50; objects = { /* Begin PBXBuildFile section */ + 8716DE1D2128553200C47DE6 /* JSON.m in Sources */ = {isa = PBXBuildFile; fileRef = 8716DE1C2128553200C47DE6 /* JSON.m */; }; + 8716DE1F21285D0D00C47DE6 /* JSON.m in Sources */ = {isa = PBXBuildFile; fileRef = 8716DE1C2128553200C47DE6 /* JSON.m */; }; B00D8CF41685487D00D39BA8 /* FD44Copier in CopyFiles */ = {isa = PBXBuildFile; fileRef = B00D8CF11685486C00D39BA8 /* FD44Copier */; }; B02571401601496400B0E1EB /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B025713F1601496400B0E1EB /* Cocoa.framework */; }; B025714C1601496400B0E1EB /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = B025714B1601496400B0E1EB /* main.m */; }; @@ -67,6 +69,8 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 8716DE1B212854C500C47DE6 /* JSON.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSON.h; sourceTree = ""; }; + 8716DE1C2128553200C47DE6 /* JSON.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JSON.m; sourceTree = ""; }; B00D8CF11685486C00D39BA8 /* FD44Copier */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = FD44Copier; sourceTree = SOURCE_ROOT; }; B025713B1601496400B0E1EB /* DPCIManager.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DPCIManager.app; sourceTree = BUILT_PRODUCTS_DIR; }; B025713F1601496400B0E1EB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; @@ -186,6 +190,8 @@ B05AE9BA162A500B005190E4 /* Task.h */, B05AE9BB162A500B005190E4 /* Task.m */, B02571461601496400B0E1EB /* Supporting Files */, + 8716DE1B212854C500C47DE6 /* JSON.h */, + 8716DE1C2128553200C47DE6 /* JSON.m */, ); path = DPCIManager; sourceTree = ""; @@ -281,10 +287,10 @@ isa = PBXProject; attributes = { LastUpgradeCheck = 0450; - ORGANIZATIONNAME = Sourceforge; + ORGANIZATIONNAME = ""; }; buildConfigurationList = B02571351601496300B0E1EB /* Build configuration list for PBXProject "DPCIManager" */; - compatibilityVersion = "Xcode 3.2"; + compatibilityVersion = "Xcode 9.3"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( @@ -343,6 +349,7 @@ B025714C1601496400B0E1EB /* main.m in Sources */, B02571531601496400B0E1EB /* AppDelegate.m in Sources */, B07193831623B776006D5666 /* PCI.m in Sources */, + 8716DE1D2128553200C47DE6 /* JSON.m in Sources */, B08396ED1627F137003427F4 /* Match.m in Sources */, B05AE9BC162A500B005190E4 /* Task.m in Sources */, B09012811705921600D0F913 /* Hardware.m in Sources */, @@ -354,6 +361,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 8716DE1F21285D0D00C47DE6 /* JSON.m in Sources */, B0F67A8E1696BE6D0059FD30 /* PCI.m in Sources */, B0F67A851696BDDD0059FD30 /* main.m in Sources */, ); @@ -395,7 +403,7 @@ CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; - CURRENT_MARKETING_VERSION = 1.5; + CURRENT_MARKETING_VERSION = 1.6; CURRENT_PROJECT_VERSION = 256; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; @@ -425,9 +433,9 @@ CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; - CURRENT_MARKETING_VERSION = 1.5; + CURRENT_MARKETING_VERSION = 1.6; CURRENT_PROJECT_VERSION = 256; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEBUG_INFORMATION_FORMAT = dwarf; DEPLOYMENT_POSTPROCESSING = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_ENABLE_OBJC_EXCEPTIONS = YES; diff --git a/DPCIManager/DPCIManager-Prefix.pch b/DPCIManager/DPCIManager-Prefix.pch index 8168adb..2011943 100644 --- a/DPCIManager/DPCIManager-Prefix.pch +++ b/DPCIManager/DPCIManager-Prefix.pch @@ -17,7 +17,7 @@ NS_INLINE NSError* ModalError(NSError *error){ } NS_INLINE void ModalErrorWithDict(NSDictionary *err){ if (err && [[err objectForKey:NSAppleScriptErrorNumber] integerValue] != -128) - NSRunCriticalAlertPanel([err objectForKey:NSAppleScriptErrorMessage], [err objectForKey:NSAppleScriptErrorBriefMessage], nil, nil, nil); + NSRunCriticalAlertPanel([err objectForKey:NSAppleScriptErrorMessage], @"%@", [err objectForKey:NSAppleScriptErrorBriefMessage], nil, nil, nil); } NS_INLINE NSOpenPanel* DirectoryChooser() { NSOpenPanel *temp = [NSOpenPanel openPanel]; diff --git a/DPCIManager/JSON.h b/DPCIManager/JSON.h new file mode 100644 index 0000000..82596c5 --- /dev/null +++ b/DPCIManager/JSON.h @@ -0,0 +1,20 @@ +// +// JSON.h +// DPCIManager +// +// Created by Muntashir Al-Islam on 8/18/18. +// See: https://stackoverflow.com/a/20262259/4147849 +// + +#ifndef JSON_h +#define JSON_h + +@interface NSDictionary (BVJSONString) +-(NSString*) bv_jsonStringWithPrettyPrint:(BOOL) prettyPrint; +@end + +@interface NSArray (BVJSONString) +- (NSString *)bv_jsonStringWithPrettyPrint:(BOOL)prettyPrint; +@end + +#endif /* JSON_h */ diff --git a/DPCIManager/JSON.m b/DPCIManager/JSON.m new file mode 100644 index 0000000..299ffd8 --- /dev/null +++ b/DPCIManager/JSON.m @@ -0,0 +1,41 @@ +// +// JSON.m +// DPCIManager +// +// Created by Muntashir Al-Islam on 8/18/18. +// See: https://stackoverflow.com/a/20262259/4147849 +// + +#import "JSON.h" + +@implementation NSDictionary (BVJSONString) +-(NSString*) bv_jsonStringWithPrettyPrint:(BOOL) prettyPrint { + NSError *error; + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self + options:(NSJSONWritingOptions) (prettyPrint ? NSJSONWritingPrettyPrinted : 0) + error:&error]; + + if (! jsonData) { + NSLog(@"%s: error: %@", __func__, error.localizedDescription); + return @"{}"; + } else { + return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + } +} +@end + +@implementation NSArray (BVJSONString) +-(NSString*) bv_jsonStringWithPrettyPrint:(BOOL) prettyPrint { + NSError *error; + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self + options:(NSJSONWritingOptions) (prettyPrint ? NSJSONWritingPrettyPrinted : 0) + error:&error]; + + if (! jsonData) { + NSLog(@"%s: error: %@", __func__, error.localizedDescription); + return @"[]"; + } else { + return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + } +} +@end diff --git a/DPCIManager/PCI.h b/DPCIManager/PCI.h index 02fca44..97785c3 100644 --- a/DPCIManager/PCI.h +++ b/DPCIManager/PCI.h @@ -26,6 +26,7 @@ @property NSString *subClassString; @property (readonly) NSString *fullClassString; @property (readonly) NSString *lspciString; +@property (readonly) NSDictionary *lspciDictionary; @property (readonly) long fullID; @property (readonly) long fullSubID; @property (readonly) short bdf; @@ -64,4 +65,4 @@ +(BOOL)allowsReverseTransformation; +(Class)transformedValueClass; -(id)transformedValue:(id)value; -@end \ No newline at end of file +@end diff --git a/DPCIManager/PCI.m b/DPCIManager/PCI.m index 74c7526..7ec2d76 100644 --- a/DPCIManager/PCI.m +++ b/DPCIManager/PCI.m @@ -109,6 +109,35 @@ -(NSString *)fullClassString{ -(NSString *)lspciString{ return [NSString stringWithFormat:@"%02lx:%02lx.%01lx %@ [%04lx]: %@ %@ [%04lx:%04lx]%@%@", [[bus objectAtIndex:0] integerValue], [[bus objectAtIndex:1] integerValue], [[bus objectAtIndex:2] integerValue], subClassString, pciClassCode.integerValue>>8, vendorString, deviceString, shadowVendor.integerValue, shadowDevice.integerValue, !revision.integerValue?@"":[NSString stringWithFormat:@" (rev %02lx)", revision.integerValue], !subDevice.integerValue?@"":[NSString stringWithFormat:@" (subsys %04lx:%04lx)", subVendor.integerValue, subDevice.integerValue]]; } +-(NSDictionary *)lspciDictionary{ + NSDictionary *lspci_dict = @{ + // BusNumber:DeviceNumber.FunctionNumber + @"BDF": [NSString stringWithFormat:@"%02lx:%02lx.%01lx", [[bus objectAtIndex:0] integerValue], [[bus objectAtIndex:1] integerValue], [[bus objectAtIndex:2] integerValue]], + // Device's Class + @"Class": @{ + @"Name": subClassString, + @"Code": [NSString stringWithFormat:@"%04lx", pciClassCode.integerValue>>8] + }, + // Device Info + @"Info": @{ + @"Name": vendorString, + @"Vendor": deviceString + }, + // Device ID + @"ID": @{ + @"DeviceID": [NSString stringWithFormat:@"%04lx", shadowDevice.integerValue], + @"VendorID": [NSString stringWithFormat:@"%04lx", shadowVendor.integerValue] + }, + // Subsystem ID + @"SubsysID": @{ + @"DeviceID": [NSString stringWithFormat:@"%04lx", subDevice.integerValue], + @"VendorID": [NSString stringWithFormat:@"%04lx", subVendor.integerValue] + }, + // Revision + @"Rev": [NSString stringWithFormat:@"%02lx", revision.integerValue] + }; + return lspci_dict; +} -(long)fullID{ return device.integerValue<<16 | vendor.integerValue; } @@ -303,4 +332,4 @@ +(Class)transformedValueClass{ -(id)transformedValue:(id)value{ return [NSString stringWithFormat:@"%04lX", [(NSNumber *)value integerValue]]; } -@end \ No newline at end of file +@end diff --git a/dspci/main.m b/dspci/main.m index 492004a..d5ffad3 100644 --- a/dspci/main.m +++ b/dspci/main.m @@ -8,14 +8,19 @@ #import #import +#import #import "PCI.h" +#import "JSON.h" + +// Arguments +#define JSONData "JSONData" int main(int argc, const char * argv[]) { - @autoreleasepool { - - // insert code here... + // Parse Arguments: currently only JSONData + BOOL printJSON = (argc > 1 && strcmp(JSONData,argv[1]) == 0) ? true : false; + // Main begins unsigned long len; char *handle = strdup(getsectdata("__TEXT", "__pci_ids", &len)); NSMutableDictionary *classes = [NSMutableDictionary dictionary]; @@ -23,8 +28,8 @@ int main(int argc, const char * argv[]) NSNumber *currentClass; NSNumber *currentVendor; char buffer[LINE_MAX]; + if(!printJSON) printf("Using PCI.IDs %s\n", buffer); sscanf(strstr(handle, "Version:"), "Version: %[^\n]", buffer); - printf("Using PCI.IDs %s\n", buffer); long device_id, subclass_id; char *buf; bool class_parse = false; @@ -72,6 +77,7 @@ int main(int argc, const char * argv[]) if (IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching("IOPCIDevice"), &itThis) == KERN_SUCCESS) { io_service_t service; NSMutableArray *devices = [NSMutableArray array]; + NSMutableArray *devicesJSON = [NSMutableArray array]; while((service = IOIteratorNext(itThis))){ pciDevice *device = [pciDevice create:service classes:classes vendors:vendors]; if (device.fullID + device.fullSubID > 0) [devices addObject:device]; @@ -80,8 +86,11 @@ int main(int argc, const char * argv[]) IOObjectRelease(itThis); for (pciDevice *device in [devices sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { return [obj1 bdf] - [obj2 bdf]; - }]) - printf("%s\n", device.lspciString.UTF8String); + }]){ + if(printJSON) [devicesJSON addObject:device.lspciDictionary]; + else printf("%s\n", device.lspciString.UTF8String); + } + if(printJSON) printf("%s\n", [devicesJSON bv_jsonStringWithPrettyPrint:true].UTF8String); } }