diff --git a/CloverApp/Clover.xcodeproj/project.pbxproj b/CloverApp/Clover.xcodeproj/project.pbxproj index 7188a1efc..3d8e90214 100644 --- a/CloverApp/Clover.xcodeproj/project.pbxproj +++ b/CloverApp/Clover.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + 952EB6AF24018B4500BEB0F8 /* gfxutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 952EB6A924018B4400BEB0F8 /* gfxutil.c */; }; + 952EB6B024018B4500BEB0F8 /* utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 952EB6AA24018B4400BEB0F8 /* utils.c */; }; + 952EB6B124018B4500BEB0F8 /* efidevp.c in Sources */ = {isa = PBXBuildFile; fileRef = 952EB6AE24018B4500BEB0F8 /* efidevp.c */; }; 9533718323709517003F1AF4 /* bootsectors-install in Resources */ = {isa = PBXBuildFile; fileRef = 9533718223709517003F1AF4 /* bootsectors-install */; }; 9533718523709A36003F1AF4 /* bootsectors-install in Copy CloverV2 */ = {isa = PBXBuildFile; fileRef = 9533718223709517003F1AF4 /* bootsectors-install */; }; 953BC20323720C0A0039755D /* FixedWidthViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 953BC20223720C0A0039755D /* FixedWidthViews.swift */; }; @@ -31,6 +34,7 @@ 955F7C6D238DCD170019D088 /* DiskArbitration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 955F7C6C238DCD160019D088 /* DiskArbitration.framework */; }; 9560906A238C61E200ACD7F7 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 95609068238C61E200ACD7F7 /* MainMenu.xib */; }; 956090B7238C890600ACD7F7 /* Installer.xib in Resources */ = {isa = PBXBuildFile; fileRef = 956090B9238C890600ACD7F7 /* Installer.xib */; }; + 95696B7B2401829800AFAD37 /* GengConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95696B7A2401829800AFAD37 /* GengConfig.swift */; }; 9569EC42238DD772003AD72C /* Settings.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9569EC44238DD772003AD72C /* Settings.xib */; }; 958861DA235F75FB00B64173 /* Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 958861D9235F75FB00B64173 /* Driver.swift */; }; 95C515222369BAF500E4A3A8 /* NVRAM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95C515212369BAF500E4A3A8 /* NVRAM.swift */; }; @@ -175,6 +179,12 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 952EB6A924018B4400BEB0F8 /* gfxutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gfxutil.c; sourceTree = ""; }; + 952EB6AA24018B4400BEB0F8 /* utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = utils.c; sourceTree = ""; }; + 952EB6AB24018B4500BEB0F8 /* gfxutil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gfxutil.h; sourceTree = ""; }; + 952EB6AC24018B4500BEB0F8 /* utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utils.h; sourceTree = ""; }; + 952EB6AD24018B4500BEB0F8 /* efidevp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = efidevp.h; sourceTree = ""; }; + 952EB6AE24018B4500BEB0F8 /* efidevp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = efidevp.c; sourceTree = ""; }; 9533718223709517003F1AF4 /* bootsectors-install */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "bootsectors-install"; sourceTree = SOURCE_ROOT; }; 953BC20223720C0A0039755D /* FixedWidthViews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FixedWidthViews.swift; sourceTree = ""; }; 9542ABB82373780C00DC03E6 /* boot1-inst.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "boot1-inst.xcodeproj"; path = "../CloverPackage/utils/boot1-install/boot1-inst.xcodeproj"; sourceTree = ""; }; @@ -277,6 +287,7 @@ 95609101238C89C300ACD7F7 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Installer.strings; sourceTree = ""; }; 95609103238C89C600ACD7F7 /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/Installer.strings; sourceTree = ""; }; 95609105238C89C900ACD7F7 /* vi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = vi; path = vi.lproj/Installer.strings; sourceTree = ""; }; + 95696B7A2401829800AFAD37 /* GengConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GengConfig.swift; sourceTree = ""; }; 9569EC43238DD772003AD72C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/Settings.xib; sourceTree = ""; }; 9569EC46238DD77A003AD72C /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Settings.strings; sourceTree = ""; }; 9569EC48238DD77C003AD72C /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = bg.lproj/Settings.strings; sourceTree = ""; }; @@ -349,6 +360,19 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 952EB6A824018B2400BEB0F8 /* GfxUtil */ = { + isa = PBXGroup; + children = ( + 952EB6AE24018B4500BEB0F8 /* efidevp.c */, + 952EB6AD24018B4500BEB0F8 /* efidevp.h */, + 952EB6A924018B4400BEB0F8 /* gfxutil.c */, + 952EB6AB24018B4500BEB0F8 /* gfxutil.h */, + 952EB6AA24018B4400BEB0F8 /* utils.c */, + 952EB6AC24018B4500BEB0F8 /* utils.h */, + ); + path = GfxUtil; + sourceTree = ""; + }; 9542ABB92373780C00DC03E6 /* Products */ = { isa = PBXGroup; children = ( @@ -444,9 +468,11 @@ 95E68AC8235B862F002B37A5 /* Clover */ = { isa = PBXGroup; children = ( + 952EB6A824018B2400BEB0F8 /* GfxUtil */, 955BEE1123C6B43C00425AB0 /* ThemeManager */, 95E68AC9235B862F002B37A5 /* AppDelegate.swift */, 95C5152E236A0A7400E4A3A8 /* SettingsView.swift */, + 95696B7A2401829800AFAD37 /* GengConfig.swift */, 95C51535236B1F7700E4A3A8 /* RunAtLogin.swift */, 95E68ACB235B862F002B37A5 /* ViewController.swift */, 95E68ADE235B86A1002B37A5 /* bdmesg.swift */, @@ -716,6 +742,7 @@ buildActionMask = 2147483647; files = ( 95E68AE5235B89D9002B37A5 /* Installer.swift in Sources */, + 952EB6B124018B4500BEB0F8 /* efidevp.c in Sources */, 95E68AE1235B86A1002B37A5 /* Shared.swift in Sources */, 95E68ACC235B862F002B37A5 /* ViewController.swift in Sources */, 95E68AE2235B86A1002B37A5 /* Disks.swift in Sources */, @@ -728,11 +755,14 @@ 95E68AE3235B86A1002B37A5 /* bdmesg.swift in Sources */, 95C5152F236A0A7400E4A3A8 /* SettingsView.swift in Sources */, 9555AF28238EFDAD00108C33 /* DriversCollection.swift in Sources */, + 952EB6AF24018B4500BEB0F8 /* gfxutil.c in Sources */, 953BC20323720C0A0039755D /* FixedWidthViews.swift in Sources */, + 95696B7B2401829800AFAD37 /* GengConfig.swift in Sources */, 95E50076238ABA56002F3869 /* Tasks.swift in Sources */, 95C515222369BAF500E4A3A8 /* NVRAM.swift in Sources */, 95C51536236B1F7700E4A3A8 /* RunAtLogin.swift in Sources */, 95E68AE0235B86A1002B37A5 /* Extensions.swift in Sources */, + 952EB6B024018B4500BEB0F8 /* utils.c in Sources */, 955689DB23A2728000AD323C /* IO.swift in Sources */, 9555AF26238EE53300108C33 /* InstallerOutline.swift in Sources */, 955BEE1723C6B49C00425AB0 /* ThemeManagerVC.swift in Sources */, @@ -1049,12 +1079,21 @@ CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1.15; + CURRENT_PROJECT_VERSION = 1.16; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Clover/Frameworks", ); - HEADER_SEARCH_PATHS = "$(SRCROOT)/Frameworks/ObjectiveGit.framework/Headers/"; + HEADER_SEARCH_PATHS = ( + "$(SRCROOT)/Frameworks/ObjectiveGit.framework/Headers/", + ../MdePkg/Include/X64, + "../MdePkg/**", + ../MdeModulePkg/Include, + ../IntelFrameworkPkg/Include, + ../rEFIt_UEFI/refit, + ../rEFIt_UEFI/libeg, + ../Include, + ); IBC_WARNINGS = YES; INFOPLIST_FILE = Clover/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -1065,7 +1104,7 @@ "$(inherited)", "$(PROJECT_DIR)/Clover/Frameworks", ); - MARKETING_VERSION = 1.15; + MARKETING_VERSION = 1.16; OTHER_LDFLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = org.slice.Clover; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1085,12 +1124,21 @@ CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1.15; + CURRENT_PROJECT_VERSION = 1.16; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Clover/Frameworks", ); - HEADER_SEARCH_PATHS = "$(SRCROOT)/Frameworks/ObjectiveGit.framework/Headers/"; + HEADER_SEARCH_PATHS = ( + "$(SRCROOT)/Frameworks/ObjectiveGit.framework/Headers/", + ../MdePkg/Include/X64, + "../MdePkg/**", + ../MdeModulePkg/Include, + ../IntelFrameworkPkg/Include, + ../rEFIt_UEFI/refit, + ../rEFIt_UEFI/libeg, + ../Include, + ); INFOPLIST_FILE = Clover/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -1100,7 +1148,7 @@ "$(inherited)", "$(PROJECT_DIR)/Clover/Frameworks", ); - MARKETING_VERSION = 1.15; + MARKETING_VERSION = 1.16; OTHER_LDFLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = org.slice.Clover; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/CloverApp/Clover/AppDelegate.swift b/CloverApp/Clover/AppDelegate.swift index c560c4c66..f4c31563d 100644 --- a/CloverApp/Clover/AppDelegate.swift +++ b/CloverApp/Clover/AppDelegate.swift @@ -13,7 +13,8 @@ let AppSD = NSApplication.shared.delegate as! AppDelegate let localeBundle = Bundle(path: Bundle.main.sharedSupportPath! + "/Lang.bundle") @NSApplicationMain -class AppDelegate: NSObject, NSApplicationDelegate, NSPopoverDelegate { +final class AppDelegate: NSObject, NSApplicationDelegate, NSPopoverDelegate { + let CloverRevision : Int = Int(findCloverRevision() ?? "0") ?? 0 var isInstalling : Bool = false var isInstallerOpen : Bool = false var themeUser = UDs.string(forKey: kThemeUserKey) ?? kDefaultThemeUser diff --git a/CloverApp/Clover/Base.lproj/Settings.xib b/CloverApp/Clover/Base.lproj/Settings.xib index 13766be0d..ae0129cf2 100644 --- a/CloverApp/Clover/Base.lproj/Settings.xib +++ b/CloverApp/Clover/Base.lproj/Settings.xib @@ -174,7 +174,7 @@ - + @@ -524,7 +524,7 @@ - + @@ -555,7 +555,7 @@ - + @@ -618,7 +618,7 @@ - + @@ -630,7 +630,7 @@ - + @@ -690,7 +690,7 @@ - + @@ -717,7 +717,7 @@ - + @@ -725,10 +725,30 @@ + + + + + + + + + + - + @@ -736,6 +756,7 @@ + diff --git a/CloverApp/Clover/Clover-Bridging-Header.h b/CloverApp/Clover/Clover-Bridging-Header.h index 817a4dd01..b17b599fd 100644 --- a/CloverApp/Clover/Clover-Bridging-Header.h +++ b/CloverApp/Clover/Clover-Bridging-Header.h @@ -2,4 +2,22 @@ // Use this file to import your target's public headers that you would like to expose to Swift. // +#ifndef CLOVERAPPLICATION +#define CLOVERAPPLICATION 1 +#endif + +#ifdef DEBUG +#define DEBUG_BACKUP DEBUG // backup original +#undef DEBUG +#endif + +#include "../../rEFIt_UEFI/Platform/Platform.h" + +#ifdef DEBUG_BACKUP +#undef DEBUG +#define DEBUG DEBUG_BACKUP // restore original +#endif + #import "NSWindowFix.h" +#import "gfxutil.h" +#import "efidevp.h" diff --git a/CloverApp/Clover/Extensions.swift b/CloverApp/Clover/Extensions.swift index 58989356e..2e635f680 100644 --- a/CloverApp/Clover/Extensions.swift +++ b/CloverApp/Clover/Extensions.swift @@ -61,6 +61,64 @@ extension String { } } +extension NSNumber { + var hexString: String { + if (self.intValue > 0xFFFF) { + return String(format: "0x%08llx", self.intValue) + } else { + return String(format: "0x%04llx", self.intValue) + } + } +} + +extension Int { + var data: Data { + var num = self + return Data(bytes: &num, count: MemoryLayout.size) + } +} + +extension UInt8 { + var data: Data { + var num = self + return Data(bytes: &num, count: MemoryLayout.size) + } +} +extension UInt16 { + var data: Data { + var num = self + return Data(bytes: &num, count: MemoryLayout.size) + } +} + +extension UInt32 { + var data: Data { + var num = self + return Data(bytes: &num, count: MemoryLayout.size) + } +} + +extension Data { + func toPointer() -> UnsafePointer? { + + let buffer = UnsafeMutablePointer.allocate(capacity: self.count) + let stream = OutputStream(toBuffer: buffer, capacity: self.count) + + stream.open() + let value = self.withUnsafeBytes { + $0.baseAddress?.assumingMemoryBound(to: UInt8.self) + } + guard let val = value else { + return nil + } + + stream.write(val, maxLength: self.count) + + stream.close() + + return UnsafePointer(buffer) + } +} extension URL { // https://stackoverflow.com/questions/38343186/write-extend-file-attributes-swift-example?answertab=active#tab-top diff --git a/CloverApp/Clover/FixedWidthViews.swift b/CloverApp/Clover/FixedWidthViews.swift index 2c1971705..c35675a29 100644 --- a/CloverApp/Clover/FixedWidthViews.swift +++ b/CloverApp/Clover/FixedWidthViews.swift @@ -8,7 +8,7 @@ import Cocoa -class FWPopUpButton: NSPopUpButton { +final class FWPopUpButton: NSPopUpButton { private var pfixedWidth : CGFloat = 50 @IBInspectable var fixedWidth: CGFloat { get { @@ -22,7 +22,7 @@ class FWPopUpButton: NSPopUpButton { } } -class FWButton: NSButton { +final class FWButton: NSButton { private var pfixedWidth : CGFloat = 50 @IBInspectable var fixedWidth: CGFloat { get { @@ -36,7 +36,7 @@ class FWButton: NSButton { } } -class FWTextField: NSTextField { +final class FWTextField: NSTextField { private var pfixedWidth : CGFloat = 50 @IBInspectable var fixedWidth: CGFloat { get { diff --git a/CloverApp/Clover/GengConfig.swift b/CloverApp/Clover/GengConfig.swift new file mode 100644 index 000000000..b4e54c3c3 --- /dev/null +++ b/CloverApp/Clover/GengConfig.swift @@ -0,0 +1,864 @@ +// +// GengConfig.swift +// Clover +// +// Created by vector sigma on 22/02/2020. +// Copyright © 2020 CloverHackyColor. All rights reserved. +// + + +import Foundation + +extension Mirror { + var data: Data { + var d : Data = Data() + for child in self.children { + d.append(child.value as! UInt8) + } + return d + } + + var dataString: String { + var str : String = "" + for child in self.children { + str += String(format: "%02x", child.value as! UInt8) + } + return str + } + + var CHAR16String: String? { + var data : Data = Data() + for child in self.children { + let u16 = child.value as! UInt16 + let u80 = UInt8(u16 >> 8) + let u81 = UInt8(u16 & 0x00ff) + if u80 != 0x00 { + data.append(u80) + } + if u81 != 0x00 { + data.append(u81) + } + } + return String(data: data, encoding: .utf8) + } + + var CHAR8String: String? { + var chars : [Character] = [Character]() + for child in self.children { + if let byte = UInt8(exactly: child.value as! Int8) { + if byte != 0x00 { + let char = Character(UnicodeScalar(byte)) + chars.append(char) + } + } + } + return String(chars) + } + + var labels : [String] { + var l : [String] = [String]() + for child in self.children { + if (child.label != nil) { + l.append(child.label!) + } + } + return l + } +} + +extension EFI_GUID { + var uuidString: String? { + var data : Data = Data() + data.append(Data1.data) + data.append(Data2.data) + data.append(Data3.data) + data.append(Mirror(reflecting: Data4).data) + var str = "" + for i in 0.. [String : Any]? { + var Fixes = [String : Any]() + /* + FixDsdt is UINT32. FixesNew array indexes reflect bit field + */ + let FixesNew = ["AddDTGP", "FixDarwin", "FixShutdown", "AddMCHC", + "FixHPET", "FakeLPC", "FixIPIC", "FixSBUS", + "FixDisplay", "FixIDE", "FixSATA", "FixFirewire", + "FixUSB", "FixLAN", "FixAirport", "FixHDA", + "FixDarwin7", "FixRTC", "FixTMR", "AddIMEI", + "FixIntelGfx", "FixWAK", "DeleteUnused", "FixADP1", + "AddPNLF", "FixS3D", "FixACST", "AddHDMI", + "FixRegions", "FixHeaders", "FixMutex"] + + let FixesOld = ["AddDTGP_0001", "FixDarwin_0002", "FixShutdown_0004", "AddMCHC_0008", + "FixHPET_0010", "FakeLPC_0020", "FixIPIC_0040", "FixSBUS_0080", + "FixDisplay_0100", "FixIDE_0200", "FixSATA_0400", "FixFirewire_0800", + "FixUSB_1000", "FixLAN_2000", "FixAirport_4000", "FixHDA_8000", "FixHDA", + "FixDarwin7_10000", "FIX_RTC_20000", "FIX_TMR_40000", "AddIMEI_80000", + "FIX_INTELGFX_100000", "FIX_WAK_200000", "DeleteUnused_400000", "FIX_ADP1_800000", + "AddPNLF_1000000", "FIX_S3D_2000000", "FIX_ACST_4000000", "AddHDMI_8000000", + "FixRegions_10000000", "FixHeaders_20000000", "FixHeaders"] + + var found = false + + for child in Mirror(reflecting: self).children { + if child.label != nil && child.label! == "FixDsdt" { + found = true + let FixDsdt : UINT32 = child.value as! UINT32 + if AppSD.CloverRevision >= 4006 { + for i in 0.. 0 + } + } else { + for i in 0.. 0 + } + } + + break + } + } + + if !found { + print("SETTINGS_DATA: label 'FixDsdt' not found.") + return nil + } + + return Fixes + } + + func getDropOEM_DSM() -> [String : Any]? { + var dict = [String : Any]() + /* + DropOEM_DSM is UINT16. dsms array indexes reflect bit field + */ + let dsms = ["ATI", + "NVidia", + "IntelGFX", + "HDA", + "HDMI", + "LAN", + "WIFI", + "SATA", + "IDE", + "LPC", + "SmBUS", + "USB", + "Firewire"] + + var found = false + + for child in Mirror(reflecting: self).children { + if child.label != nil && child.label! == "DropOEM_DSM" { + found = true + let DropOEM_DSM : UINT16 = child.value as! UINT16 + for i in 0.. 0 + } + + break + } + } + + if !found { + print("SETTINGS_DATA: label 'DropOEM_DSM' not found.") + return nil + } + + return dict + } + + func kpValue(for label: String, type: SETTINGS_DATA_TYPE) -> Any? { + var found = false + var value : Any? = nil + if self.labels.contains("KernelAndKextPatches") { + for child in Mirror(reflecting: self.KernelAndKextPatches).children { + if child.label != nil && child.label! == label { + //print(child.label!) + switch type { + case .CHAR8String: + value = Mirror(reflecting: child.value).CHAR8String + case .CHAR16String: + value = Mirror(reflecting: child.value).CHAR16String + case .DataString: + value = Mirror(reflecting: child.value).dataString + case .UUIDString: + if let eg = child.value as? EFI_GUID { + value = eg.uuidString + } + case .HexString: + value = NSNumber(value: Int("\(child.value)")!).hexString + case .BOOLEAN: + value = NSNumber(value: child.value as! BOOLEAN).boolValue + case .INTEGER: + value = Int("\(child.value)") + } + found = true + break + } + } + } + + if !found { + print("KernelAndKextPatches: label '\(label)' not found.") + return nil + } + + if value == nil { + print("KernelAndKextPatches: value for label '\(label)' is nil.") + return nil + } + return value + } + + func value(for label: String, type: SETTINGS_DATA_TYPE) -> Any? { + var found = false + var value : Any? = nil + for child in Mirror(reflecting: self).children { + if child.label != nil && child.label! == label { + //print(child.label!) + switch type { + case .CHAR8String: + value = Mirror(reflecting: child.value).CHAR8String + case .CHAR16String: + value = Mirror(reflecting: child.value).CHAR16String + case .DataString: + value = Mirror(reflecting: child.value).dataString + case .UUIDString: + if let eg = child.value as? EFI_GUID { + value = eg.uuidString + } + case .HexString: + value = NSNumber(value: Int("\(child.value)")!).hexString + case .BOOLEAN: + value = NSNumber(value: child.value as! BOOLEAN).boolValue + case .INTEGER: + if child.label! == "flagstate" { + value = NSNumber(value: self.flagstate.0).intValue + } else { + value = Int("\(child.value)") + } + } + found = true + break + } + } + + if !found { + print("SETTINGS_DATA: label '\(label)' not found.") + return nil + } + + if value == nil { + print("SETTINGS_DATA: value for label '\(label)' is nil.") + return nil + } + + return value + } +} + +final class CloverConfig: NSObject { + private var config = [String: Any]() + func generateCloverConfig() -> [String: Any]? { + + if AppSD.CloverRevision <= 3250 { + print("Clover gen Config: Clover Revision too old or just not Clover.") + return nil + } + if let data = getCloverSettingsData() { + + var s : SETTINGS_DATA = SETTINGS_DATA() + + withUnsafeMutablePointer(to: &s) { pointer in + let bound = pointer.withMemoryRebound(to: UInt8.self, capacity: data.count) { $0 } + data.enumerated().forEach { (bound + $0.offset).pointee = $0.element } + } + + self.config["ConfigName"] = s.value(for: "ConfigName", type: .CHAR16String) + + // MARK: ACPI + var ACPI = [String : Any]() + ACPI["ResetAddress"] = s.value(for: "ResetAddr", type: .HexString) + ACPI["ResetValue"] = s.value(for: "ResetVal", type: .HexString) + ACPI["HaltEnabler"] = s.value(for: "SlpSmiEnable", type: .BOOLEAN) + ACPI["PatchAPIC"] = s.value(for: "PatchNMI", type: .BOOLEAN) + ACPI["smartUPS"] = s.value(for: "smartUPS", type: .BOOLEAN) + ACPI["AutoMerge"] = s.value(for: "AutoMerge", type: .BOOLEAN) + ACPI["DisableASPM"] = s.value(for: "NoASPM", type: .BOOLEAN) + ACPI["FixHeaders"] = s.value(for: "FixHeaders", type: .BOOLEAN) + ACPI["FixMCFG"] = s.value(for: "FixMCFG", type: .BOOLEAN) + + // MARK: ACPI->DSDT + var DSDT = [String : Any]() + + DSDT["Name"] = s.value(for: "DsdtName", type: .CHAR16String) + DSDT["Debug"] = s.value(for: "DebugDSDT", type: .BOOLEAN) + DSDT["ReuseFFFF"] = s.value(for: "ReuseFFFF", type: .BOOLEAN) + DSDT["SuspendOverride"] = s.value(for: "SuspendOverride", type: .BOOLEAN) + DSDT["Rtc8Allowed"] = s.value(for: "Rtc8Allowed", type: .BOOLEAN) + DSDT["#Patches count"] = s.value(for: "PatchDsdtNum", type: .INTEGER) + + // MARK: ACPI->DSDT->Fixes + DSDT["Fixes"] = s.getDSDTFixes() + + // MARK: ACPI->DSDT->Patches + var Patches = [Any]() + var PatchesDict1 = [String : Any]() + PatchesDict1["Comment"] = "This is for sample" + PatchesDict1["Disabled"] = true + PatchesDict1["Find"] = "_NOT_SHOWN_" + PatchesDict1["Replace"] = "_NOT_SHOWN_" + Patches.append(PatchesDict1) + DSDT["Patches"] = Patches + + // MARK: ACPI->DSDT->DropOEM_DSM + DSDT["DropOEM_DSM"] = s.getDropOEM_DSM() + + ACPI["DSDT"] = DSDT + + // MARK: ACPI->SSDT + var SSDT = [String : Any]() + SSDT["DropOem"] = s.value(for: "DropSSDT", type: .BOOLEAN) + SSDT["#DoubleFirstState"] = s.value(for: "DoubleFirstState", type: .BOOLEAN) + SSDT["#MinMultiplier"] = s.value(for: "MinMultiplier", type: .INTEGER) + SSDT["#MaxMultiplier"] = s.value(for: "MaxMultiplier", type: .INTEGER) + SSDT["#PLimitDict"] = s.value(for: "PLimitDict", type: .INTEGER) + SSDT["#UnderVoltStep"] = s.value(for: "UnderVoltStep", type: .INTEGER) + SSDT["#PluginType"] = s.value(for: "PluginType", type: .INTEGER) + SSDT["#UseSystemIO"] = s.value(for: "EnableISS", type: .BOOLEAN) + SSDT["#EnableC2"] = s.value(for: "EnableC2", type: .BOOLEAN) + SSDT["#EnableC4"] = s.value(for: "EnableC4", type: .BOOLEAN) + SSDT["#EnableC6"] = s.value(for: "EnableC6", type: .BOOLEAN) + SSDT["#EnableC7"] = s.value(for: "EnableC7", type: .BOOLEAN) + SSDT["#C3Latency"] = s.value(for: "C3Latency", type: .INTEGER) + SSDT["NoDynamicExtract"] = s.value(for: "NoDynamicExtract", type: .BOOLEAN) + + // MARK: ACPI->SSDT->Generate + var Generate = [String : Any]() + Generate["PStates"] = s.value(for: "GeneratePStates", type: .BOOLEAN) + Generate["CStates"] = s.value(for: "GenerateCStates", type: .BOOLEAN) + Generate["APSN"] = s.value(for: "GenerateAPSN", type: .BOOLEAN) + Generate["APLF"] = s.value(for: "GenerateAPLF", type: .BOOLEAN) + Generate["PluginType"] = s.value(for: "GeneratePluginType", type: .BOOLEAN) + + if Generate.keys.count > 0 { + SSDT["Generate"] = Generate + } + + ACPI["SSDT"] = SSDT + + // MARK: ACPI->DropTables + var DropTables = [Any]() + var DropTablesDict1 = [String : Any]() + DropTablesDict1["#Signature"] = "_NOT_SHOWN_" + DropTablesDict1["#TableId"] = "_NOT_SHOWN_" + DropTablesDict1["#Length"] = 0 + DropTables.append(DropTablesDict1) + ACPI["DropTables"] = DropTables + + // MARK: ACPI->SortedOrder + var SortedOrder = [Any]() + SortedOrder.append("SSDT-1.aml") + ACPI["#Sorted ACPI tables Count"] = s.value(for: "SortedACPICount", type: .INTEGER) + ACPI["#SortedOrder"] = SortedOrder + + // MARK: ACPI->RenameDevices + if AppSD.CloverRevision >= 4468 { + var RenameDevices = [String : Any]() + RenameDevices["#_SB.PCI0.RP01.PXSX"] = "ARPT" + RenameDevices["_SB.PCI0.RP02.PXSX"] = "XHC2" + ACPI["#RenameDevices"] = RenameDevices + } + + self.config["ACPI"] = ACPI + + // MARK: Boot + var Boot = [String: Any]() + Boot["Arguments"] = s.value(for: "BootArgs", type: .CHAR8String) + Boot["Legacy"] = s.value(for: "LegacyBoot", type: .CHAR16String) + Boot["XMPDetection"] = s.value(for: "XMPDetection", type: .INTEGER) + Boot["Debug"] = s.value(for: "Debug", type: .BOOLEAN) + Boot["#Timeout"] = "_NOT_SHOWN_" + Boot["Fast"] = false + Boot["#CustomLogo"] = "_NOT_SHOWN_" + Boot["#NeverHibernate"] = false + Boot["#StrictHibernate"] = false + Boot["#RtcHibernateAware"] = false + Boot["NeverDoRecovery"] = s.value(for: "NeverDoRecovery", type: .BOOLEAN) + Boot["SkipHibernateTimeout"] = s.value(for: "SkipHibernateTimeout", type: .BOOLEAN) + Boot["DisableCloverHotkeys"] = s.value(for: "DisableCloverHotkeys", type: .BOOLEAN) + Boot["LegacyBiosDefaultEntry"] = s.value(for: "LegacyBiosDefaultEntry", type: .INTEGER) + + if Boot.keys.count > 0 { + self.config["Boot"] = Boot + } + + // MARK: BootGraphics + var BootGraphics = [String: Any]() + BootGraphics["DefaultBackgroundColor"] = s.value(for: "DefaultBackgroundColor", type: .HexString) + BootGraphics["UIScale"] = s.value(for: "UIScale", type: .INTEGER) + BootGraphics["EFILoginHiDPI"] = s.value(for: "EFILoginHiDPI", type: .INTEGER) + BootGraphics["flagstate"] = s.value(for: "flagstate", type: .INTEGER) + + if BootGraphics.keys.count > 0 { + self.config["BootGraphics"] = BootGraphics + } + + // MARK: CPU + var CPU = [String: Any]() + CPU["Type"] = s.value(for: "CpuType", type: .HexString) + CPU["FrequencyMHz"] = s.value(for: "CpuFreqMHz", type: .INTEGER) + CPU["#BusSpeedkHz"] = s.value(for: "BusSpeed", type: .INTEGER) + CPU["QPI"] = s.value(for: "QPI", type: .INTEGER) + CPU["SavingMode"] = s.value(for: "SavingMode", type: .INTEGER) + CPU["#UseARTFrequency"] = s.value(for: "UseARTFreq", type: .BOOLEAN) + CPU["#TurboDisable"] = s.value(for: "Turbo", type: .BOOLEAN) + CPU["#HWPEnable"] = s.value(for: "HWP", type: .BOOLEAN) + CPU["#HWPValue"] = s.value(for: "HWPValue", type: .INTEGER) + CPU["EnabledCores"] = s.value(for: "EnabledCores", type: .INTEGER) + CPU["#TDP"] = s.value(for: "TDP", type: .BOOLEAN) + CPU["#QEMU"] = s.value(for: "QEMU", type: .BOOLEAN) + + if CPU.keys.count > 0 { + self.config["CPU"] = CPU + } + + // MARK: Devices + var Devices = [String: Any]() + Devices["#Inject"] = s.value(for: "StringInjector", type: .BOOLEAN) + Devices["#Properties"] = "_NOT_SHOWN_" + Devices["#NoDefaultProperties"] = s.value(for: "NoDefaultProperties", type: .BOOLEAN) + Devices["UseIntelHDMI"] = s.value(for: "UseIntelHDMI", type: .BOOLEAN) + Devices["ForceHPET"] = s.value(for: "ForceHPET", type: .BOOLEAN) + Devices["#SetIntelBacklight"] = s.value(for: "IntelBacklight", type: .BOOLEAN) + Devices["#SetIntelMaxBacklight"] = s.value(for: "IntelMaxBacklight", type: .BOOLEAN) + Devices["#IntelMaxValue"] = s.value(for: "IntelMaxValue", type: .INTEGER) + + + // MARK: Devices->AddProperties + var AddProperties = [Any]() + var AddPropertiesDict1 = [String: Any]() + + AddPropertiesDict1["#Device"] = "XXX" + AddPropertiesDict1["#Disabled"] = true + AddPropertiesDict1["#Key"] = "AAPL,XXX" + AddPropertiesDict1["#Value"] = NSNumber(value: 0xFFFF).hexString + AddProperties.append(AddPropertiesDict1) + Devices["AddProperties"] = AddProperties + + // MARK: Devices->Properties + if AppSD.CloverRevision >= 4466 { + if let data = getDevicePropertiesData()?.toPointer() { + var Properties = [String : Any]() + let gfx : GFX_HEADER? = parse_binary(data).pointee + var block = gfx?.blocks + + repeat { + var entry = block?.pointee.entries + if let dpath = ConvertDevicePathToAscii(block!.pointee.devpath, 1, 1) { + let blockKey = String(cString: dpath) + var blockDict = [String: Any]() + repeat { + if entry != nil { + let key = String(cString: entry!.pointee.key) + let count = Int(entry!.pointee.val_len) + switch entry!.pointee.val_type { + case DATA_INT8: fallthrough + case DATA_INT16: fallthrough + case DATA_INT32: fallthrough + case DATA_BINARY: + let data = Data(bytes: entry!.pointee.val, count: count) + blockDict[key] = data + case DATA_STRING: + let str = String(cString: entry!.pointee.val) + blockDict[key] = str + default: + // we should not be here as all the types are enumerated + break + } + entry = entry!.pointee.next + } + } while (entry != nil) + + if blockDict.keys.count > 0 { + Properties[blockKey] = blockDict + } + } + + block = block?.pointee.next + } while (block != nil) + Devices["Properties"] = Properties + } + } + + + // MARK: Devices->FakeID + var FakeID = [String : Any]() + FakeID["ATI"] = s.value(for: "FakeATI", type: .HexString) + FakeID["NVidia"] = s.value(for: "FakeNVidia", type: .HexString) + FakeID["IntelGFX"] = s.value(for: "FakeIntel", type: .HexString) + FakeID["LAN"] = s.value(for: "FakeLAN", type: .HexString) + FakeID["WIFI"] = s.value(for: "FakeWIFI", type: .HexString) + FakeID["SATA"] = s.value(for: "FakeSATA", type: .HexString) + FakeID["XHCI"] = s.value(for: "FakeXHCI", type: .HexString) + FakeID["IMEI"] = s.value(for: "FakeIMEI", type: .HexString) + + if FakeID.keys.count > 0 { + Devices["FakeID"] = FakeID + } + + // MARK: Devices->Audio + var Audio = [String : Any]() + if s.labels.contains("HDAInjection") && NSNumber(value: s.HDAInjection).boolValue { + Audio["#Inject"] = s.value(for: "HDALayoutId", type: .INTEGER) + } else { + Audio["#Inject"] = s.value(for: "HDAInjection", type: .BOOLEAN) + } + Audio["#ResetHDA"] = s.value(for: "ResetHDA", type: .BOOLEAN) + + if Audio.keys.count > 0 { + Devices["Audio"] = Audio + } + + // MARK: Devices->USB + var USB = [String : Any]() + USB["Inject"] = s.value(for: "USBInjection", type: .BOOLEAN) + USB["FixOwnership"] = s.value(for: "USBFixOwnership", type: .BOOLEAN) + USB["AddClockID"] = s.value(for: "InjectClockID", type: .BOOLEAN) + USB["HighCurrent"] = s.value(for: "HighCurrent", type: .BOOLEAN) + + if USB.keys.count > 0 { + Devices["USB"] = USB + } + + self.config["Devices"] = Devices + + // MARK: Graphics + var Graphics = [String : Any]() + Graphics["LoadVBios"] = s.value(for: "LoadVBios", type: .BOOLEAN) + Graphics["PatchVBios"] = s.value(for: "PatchVBios", type: .BOOLEAN) + Graphics["VideoPorts"] = s.value(for: "VideoPorts", type: .INTEGER) + Graphics["VRAM"] = s.value(for: "VRAM", type: .INTEGER) + Graphics["DualLink"] = s.value(for: "DualLink", type: .INTEGER) + + // MARK: Graphics (ATI specific) + Graphics["FBName"] = s.value(for: "FBName", type: .CHAR16String) + Graphics["RadeonDeInit"] = s.value(for: "DeInit", type: .BOOLEAN) + + // MARK: Graphics (NVIDIA specific) + Graphics["display-cfg"] = s.value(for: "Dcfg", type: .DataString) + Graphics["NVCAP"] = s.value(for: "NVCAP", type: .DataString) + Graphics["NvidiaGeneric"] = s.value(for: "NvidiaGeneric", type: .BOOLEAN) + Graphics["NvidiaNoEFI"] = s.value(for: "NvidiaNoEFI", type: .BOOLEAN) + Graphics["NvidiaSingle"] = s.value(for: "NvidiaSingle", type: .BOOLEAN) + + // MARK: Graphics (NVIDIA Intel) + Graphics["ig-platform-id"] = s.value(for: "IgPlatform", type: .HexString) + Graphics["#PatchVBiosBytes Count"] = s.value(for: "PatchVBiosBytesCount", type: .INTEGER) + + // MARK: Graphics->Inject + var Inject = [String : Any]() + Inject["ATI"] = s.value(for: "InjectATI", type: .BOOLEAN) + Inject["NVidia"] = s.value(for: "InjectNVidia", type: .BOOLEAN) + Inject["Intel"] = s.value(for: "InjectIntel", type: .BOOLEAN) + + if Inject.keys.count > 0 { + Graphics["Inject"] = Inject + } + + // MARK: Graphics->PatchVBiosBytes + var PatchVBiosBytes = [Any]() + Graphics["#PatchVBiosBytes Count"] = s.value(for: "PatchVBiosBytesCount", type: .INTEGER) + var PatchVBiosBytesDict1 = [String : Any]() + PatchVBiosBytesDict1["#Find"] = "_NOT_SHOWN_" + PatchVBiosBytesDict1["#Replace"] = "_NOT_SHOWN_" + PatchVBiosBytes.append(PatchVBiosBytesDict1) + Graphics["#PatchVBiosBytes"] = PatchVBiosBytes + + // MARK: Graphics->EDID + if AppSD.CloverRevision >= 3737 { + var EDID = [String : Any]() + if AppSD.CloverRevision >= 4058 { + EDID["Inject"] = s.value(for: "InjectEDID", type: .INTEGER) + EDID["#VendorID"] = s.value(for: "VendorEDID", type: .HexString) + EDID["#ProductID"] = s.value(for: "ProductEDID", type: .HexString) + EDID["#Custom"] = "_NOT_SHOWN_" + + } else { + EDID["InjectEDID"] = s.value(for: "InjectEDID", type: .BOOLEAN) + EDID["#CustomEDID"] = "_NOT_SHOWN_" + } + + if EDID.keys.count > 0 { + Graphics["EDID"] = EDID + } + } + if Graphics.keys.count > 0 { + self.config["Graphics"] = Graphics + } + + // MARK: GUI + var GUI = [String: Any]() + GUI["#Language"] = s.value(for: "Language", type: .CHAR8String) + GUI["#Theme"] = "embedded" + GUI["TextOnly"] = false + GUI["CustomIcons"] = false + // MARK: GUI->Mouse + var Mouse = [String: Any]() + Mouse["Enabled"] = s.value(for: "PointerEnabled", type: .BOOLEAN) + Mouse["Speed"] = s.value(for: "PointerSpeed", type: .INTEGER) + Mouse["Mirror"] = s.value(for: "PointerMirror", type: .BOOLEAN) + if Mouse.keys.count > 0 { + GUI["Mouse"] = Mouse + } + // MARK: GUI->Hide + var Hide = [String]() + Hide.append("VolumeName_NOT_SHOWN") + Hide.append("VolumeUUID_NOT_SHOWN") + Hide.append("EntryPath_NOT_SHOWN") + GUI["Hide"] = Hide + // MARK: GUI->Scan + var Scan = [String: Any]() + Scan["Comment"] = "These values wrong, they present for sample" + Scan["#Entries"] = true + Scan["#Tool"] = true + Scan["#Legacy"] = true + GUI["Scan"] = Scan + + // MARK: GUI->Custom + var Custom = [String: Any]() + Custom["Comment"] = "These values wrong, they present for sample" + // MARK: GUI->Custom->Entries + var Entries = [Any]() + // MARK: GUI->Custom->Entries->example dict + var EntriesDict1 = [String: Any]() + EntriesDict1["Comment"] = "These values wrong, they present for sample" + EntriesDict1["#Volume"] = "VolumeUUID_NOT_SHOWN" + EntriesDict1["#Path"] = "_NOT_SHOWN_" + EntriesDict1["#Type"] = "_NOT_SHOWN_" + EntriesDict1["#Arguments"] = "_NOT_SHOWN_" + EntriesDict1["#AddArguments"] = "-v" + EntriesDict1["#Title"] = "_NOT_SHOWN_" + EntriesDict1["#FullTitle"] = "_NOT_SHOWN_" + EntriesDict1["#Image"] = "_NOT_SHOWN_" + EntriesDict1["#Hotkey"] = "_NOT_SHOWN_" + EntriesDict1["#Disabled"] = true + EntriesDict1["#InjectKexts"] = true + // EntriesDict1["#NoCaches"] = false // how to boot without cache??? + EntriesDict1["#Hidden"] = true + // MARK: GUI->Custom->Entries->example dict->SubEntries + var SubEntries = [Any]() + var SubEntriesDict1 = [String: Any]() + SubEntriesDict1["#Title"] = "_NOT_SHOWN_" + SubEntriesDict1["#AddArguments"] = "_NOT_SHOWN_" + + SubEntries.append(SubEntriesDict1) + EntriesDict1["SubEntries"] = SubEntries + Entries.append(EntriesDict1) + Custom["Entries"] = Entries + + // MARK: GUI->Custom->Legacy + var Legacy = [Any]() + var LegacyDict1 = [String: Any]() + LegacyDict1["#Volume"] = "VolumeUUID_NOT_SHOWN" + LegacyDict1["#Type"] = "_NOT_SHOWN_" + LegacyDict1["#Title"] = "_NOT_SHOWN_" + LegacyDict1["#Hotkey"] = "_NOT_SHOWN_" + LegacyDict1["#Disabled"] = true + LegacyDict1["#Hidden"] = true + Legacy.append(LegacyDict1) + Custom["Legacy"] = Legacy + + // MARK: GUI->Custom->Tool + var Tool = [Any]() + var ToolDict1 = [String: Any]() + ToolDict1["#Volume"] = "VolumeUUID_NOT_SHOWN" + ToolDict1["#Path"] = "_NOT_SHOWN_" + ToolDict1["#Type"] = "_NOT_SHOWN_" + ToolDict1["#Title"] = "_NOT_SHOWN_" + ToolDict1["#Arguments"] = "_NOT_SHOWN_" + ToolDict1["#Hotkey"] = "_NOT_SHOWN_" + ToolDict1["#Disabled"] = true + ToolDict1["#Hidden"] = true + Tool.append(ToolDict1) + Custom["Tool"] = Tool + + GUI["Custom"] = Custom + self.config["GUI"] = GUI + + // MARK: KernelAndKextPatches + var KernelAndKextPatches = [String : Any]() + + KernelAndKextPatches["#Debug"] = s.kpValue(for: "KPDebug", type: .BOOLEAN) + KernelAndKextPatches["KernelCpu"] = s.kpValue(for: "KPKernelCpu", type: .BOOLEAN) + KernelAndKextPatches["KernelLapic"] = s.kpValue(for: "KPKernelLapic", type: .BOOLEAN) + if AppSD.CloverRevision >= 4250 { + KernelAndKextPatches["KernelXCPM"] = s.kpValue(for: "KPKernelXCPM", type: .BOOLEAN) + } else { + KernelAndKextPatches["KernelIvyXCPM"] = s.kpValue(for: "KernelIvyXCPM", type: .BOOLEAN) + } + KernelAndKextPatches["KernelPm"] = s.kpValue(for: "KPKernelPm", type: .BOOLEAN) + if AppSD.CloverRevision >= 4152 { + KernelAndKextPatches["AppleIntelCPUPM"] = s.kpValue(for: "KPAppleIntelCPUPM", type: .BOOLEAN) + } else { + KernelAndKextPatches["AsusAICPUPM"] = s.kpValue(for: "KPAsusAICPUPM", type: .BOOLEAN) + } + + KernelAndKextPatches["AppleRTC"] = s.kpValue(for: "KPAppleRTC", type: .BOOLEAN) + KernelAndKextPatches["DellSMBIOSPatch"] = s.kpValue(for: "KPDELLSMBIOS", type: .BOOLEAN) + KernelAndKextPatches["#Number of KextsToPatch"] = s.kpValue(for: "NrKexts", type: .INTEGER) + KernelAndKextPatches["#Number of Patchs To Kernel"] = s.kpValue(for: "NrKernels", type: .INTEGER) + KernelAndKextPatches["#FakeCPUID"] = s.kpValue(for: "FakeCPUID", type: .HexString) + + // MARK: KernelAndKextPatches->KextsToPatch + var KextsToPatch = [Any]() + var KextsToPatchDict1 = [String : Any]() + KextsToPatchDict1["Comment"] = "this is a sample" + KextsToPatchDict1["#Name"] = "AppleUSBXHCIPCI" + KextsToPatchDict1["#Find"] = "_NOT_SHOWN_" + KextsToPatchDict1["#Replace"] = "_NOT_SHOWN_" + + if AppSD.CloverRevision >= 3327 { + KextsToPatchDict1["#Disabled"] = true + } + if AppSD.CloverRevision >= 3580 { + KextsToPatchDict1["#MatchOS"] = "10.11.6,10.12.x" + } + if AppSD.CloverRevision >= 3920 { + KextsToPatchDict1["#MatchBuild"] = "16D1111" + } + KextsToPatch.append(KextsToPatchDict1) + KernelAndKextPatches["#KextsToPatch"] = KextsToPatch + + self.config["KernelAndKextPatches"] = KernelAndKextPatches + + // MARK: RtVariables + if AppSD.CloverRevision >= 3250 { + var RtVariables = [String : Any]() + RtVariables["#ROM"] = "UseMacAddr0" + RtVariables["#MLB"] = s.value(for: "BoardSerialNumber", type: .CHAR8String) + RtVariables["CsrActiveConfig"] = s.value(for: "CsrActiveConfig", type: .HexString) + RtVariables["BooterConfig"] = s.value(for: "BooterConfig", type: .HexString) + + self.config["RtVariables"] = RtVariables + } + + // MARK: SMBIOS + var SMBIOS = [String: Any]() + // SMBIOS TYPE0 + SMBIOS["BiosVendor"] = s.value(for: "VendorName", type: .CHAR8String) + SMBIOS["BiosVersion"] = s.value(for: "RomVersion", type: .CHAR8String) + SMBIOS["BiosReleaseDate"] = s.value(for: "ReleaseDate", type: .CHAR8String) + // SMBIOS TYPE1 + SMBIOS["Manufacturer"] = s.value(for: "ManufactureName", type: .CHAR8String) + SMBIOS["ProductName"] = s.value(for: "ProductName", type: .CHAR8String) + SMBIOS["Version"] = s.value(for: "SerialNr", type: .CHAR8String) + SMBIOS["SerialNumber"] = s.value(for: "ReleaseDate", type: .CHAR8String) + SMBIOS["SmUUID"] = s.value(for: "SmUUID", type: .UUIDString) + SMBIOS["Family"] = s.value(for: "FamilyName", type: .CHAR8String) + // SMBIOS TYPE2 + SMBIOS["BoardManufacturer"] = s.value(for: "BoardManufactureName", type: .CHAR8String) + SMBIOS["BoardSerialNumber"] = s.value(for: "BoardSerialNumber", type: .CHAR8String) + SMBIOS["Board-ID"] = s.value(for: "BoardNumber", type: .CHAR8String) + SMBIOS["BoardVersion"] = s.value(for: "BoardVersion", type: .CHAR8String) + SMBIOS["BoardType"] = s.value(for: "BoardType", type: .INTEGER) + SMBIOS["LocationInChassis"] = s.value(for: "LocationInChassis", type: .CHAR8String) + SMBIOS["ChassisManufacturer"] = s.value(for: "ChassisManufacturer", type: .CHAR8String) + SMBIOS["ChassisAssetTag"] = s.value(for: "ChassisAssetTag", type: .CHAR8String) + SMBIOS["ChassisType"] = s.value(for: "ChassisType", type: .HexString) + SMBIOS["Mobile"] = s.value(for: "Mobile", type: .BOOLEAN) + // SMBIOS TYPE17 + SMBIOS["Trust"] = s.value(for: "TrustSMBIOS", type: .BOOLEAN) + SMBIOS["OEMProduct"] = s.value(for: "OEMProduct", type: .CHAR8String) + SMBIOS["OEMVendor"] = s.value(for: "OEMVendor", type: .CHAR8String) + SMBIOS["OEMBoard"] = s.value(for: "OEMBoard", type: .CHAR8String) + + if AppSD.CloverRevision >= 3368 { + if (s.PlatformFeature != 0xFFFF) { + SMBIOS["PlatformFeature"] = s.value(for: "PlatformFeature", type: .HexString) + } + } + + if s.labels.contains("InjectMemoryTables") && NSNumber(value: s.InjectMemoryTables).boolValue { + // MARK: SMBIOS->Memory + var Memory = [String: Any]() + Memory["Comment"] = "there are no real data here" + Memory["#SlotCount"] = 0 + Memory["#Channels"] = 0 + // MARK: SMBIOS->Memory->Modules + var Modules = [Any]() + var ModulesDict1 = [String: Any]() + ModulesDict1["#Slot"] = 0 + ModulesDict1["#Size"] = 0 + ModulesDict1["#Vendor"] = s.value(for: "MemoryManufacturer", type: .CHAR8String) + ModulesDict1["#Serial"] = s.value(for: "MemorySerialNumber", type: .CHAR8String) + ModulesDict1["#Part"] = s.value(for: "MemoryPartNumber", type: .CHAR8String) + ModulesDict1["#Frequency"] = s.value(for: "MemorySpeed", type: .CHAR8String) + ModulesDict1["#Type"] = "DDRx" + Modules.append(ModulesDict1) + Memory["Modules"] = Modules + SMBIOS["Memory"] = Memory + } + // MARK: SMBIOS->Slots + var Slots = [Any]() + var SlotsDict1 = [String: Any]() + SlotsDict1["Comment"] = "there is a sample" + SlotsDict1["Device"] = "WIFI" + SlotsDict1["ID"] = 5 + SlotsDict1["Type"] = 1 + SlotsDict1["Name"] = "Airport" + Slots.append(SlotsDict1) + SMBIOS["Slots"] = Slots + + self.config["SMBIOS"] = SMBIOS + + + // MARK: SystemParameters + var SystemParameters = [String: Any]() + SystemParameters["CustomUUID"] = s.value(for: "CustomUuid", type: .CHAR16String) + SystemParameters["InjectSystemID"] = s.value(for: "InjectSystemID", type: .BOOLEAN) + SystemParameters["BacklightLevel"] = s.value(for: "BacklightLevel", type: .HexString) + SystemParameters["NvidiaWeb"] = s.value(for: "NvidiaWeb", type: .BOOLEAN) + SystemParameters["#InjectKexts"] = "Detect" + self.config["SystemParameters"] = SystemParameters + + return self.config + } + + return nil + } +} + + + diff --git a/CloverApp/Clover/GfxUtil/efidevp.c b/CloverApp/Clover/GfxUtil/efidevp.c new file mode 100644 index 000000000..d64ed8c0f --- /dev/null +++ b/CloverApp/Clover/GfxUtil/efidevp.c @@ -0,0 +1,462 @@ +#include +#include +#include +#include +#include "efidevp.h" + +/* From utils.c */ +extern void CatPrintf(char *target, const char *format, ...); +extern void *MallocCopy(unsigned int size, void *buf); + +/* + * Get parameter in a pair of parentheses follow the given node name. + * For example, given the "Pci(0,1)" and NodeName "Pci", it returns "0,1". + */ +char *GetParamByNodeName (CHAR8 *Str, CHAR8 *NodeName) +{ + CHAR8 *ParamStr; + CHAR8 *StrPointer; + UINT32 NodeNameLength; + UINT32 ParameterLength; + + // Check whether the node name matchs + NodeNameLength = (UINT32)strlen (NodeName); + if (strncasecmp(Str, NodeName, NodeNameLength) != 0) + { + return NULL; + } + + ParamStr = Str + NodeNameLength; + if (!IS_LEFT_PARENTH (*ParamStr)) + { + return NULL; + } + + // Skip the found '(' and find first occurrence of ')' + ParamStr++; + ParameterLength = 0; + StrPointer = ParamStr; + + while (!IS_NULL (*StrPointer)) + { + if (IS_RIGHT_PARENTH (*StrPointer)) + { + break; + } + StrPointer++; + ParameterLength++; + } + + if (IS_NULL (*StrPointer)) + { + // ')' not found + return NULL; + } + + ParamStr = MallocCopy ((ParameterLength + 1), ParamStr); + if (ParamStr == NULL) + { + return NULL; + } + // Terminate the parameter string + ParamStr[ParameterLength] = '\0'; + + return ParamStr; +} + +/* Get current sub-string from a string list, before return + * the list header is moved to next sub-string. The sub-string is separated + * by the specified character. For example, the separator is ',', the string + * list is "2,0,3", it returns "2", the remain list move to "0,3" + */ +CHAR8 *SplitStr (CHAR8 **List, CHAR8 Separator) +{ + char *Str; + char *ReturnStr; + + Str = *List; + ReturnStr = Str; + + if (IS_NULL (*Str)) + { + return ReturnStr; + } + + // Find first occurrence of the separator + while (!IS_NULL (*Str)) + { + if (*Str == Separator) + { + break; + } + Str++; + } + + if (*Str == Separator) + { + // Find a sub-string, terminate it + *Str = '\0'; + Str++; + } + + // Move to next sub-string + *List = Str; + + return ReturnStr; +} + +CHAR8 *GetNextParamStr (CHAR8 **List) +{ + // The separator is comma + return SplitStr (List, ','); +} + +// Get one device node from entire device path text. +CHAR8 *GetNextDeviceNodeStr (CHAR8 **DevicePath, BOOLEAN *IsInstanceEnd) +{ + CHAR8 *Str; + CHAR8 *ReturnStr; + UINT32 ParenthesesStack; + + Str = *DevicePath; + if (IS_NULL (*Str)) + { + return NULL; + } + + // Skip the leading '/', '(', ')' and ',' + while (!IS_NULL (*Str)) + { + if (!IS_SLASH (*Str) && !IS_COMMA (*Str) && !IS_LEFT_PARENTH (*Str) && !IS_RIGHT_PARENTH (*Str)) + { + break; + } + Str++; + } + + ReturnStr = Str; + + // Scan for the separator of this device node, '/' or ',' + ParenthesesStack = 0; + while (!IS_NULL (*Str)) + { + if ((IS_COMMA (*Str) || IS_SLASH (*Str)) && (ParenthesesStack == 0)) + { + break; + } + + if (IS_LEFT_PARENTH (*Str)) + { + ParenthesesStack++; + } + else if (IS_RIGHT_PARENTH (*Str)) + { + ParenthesesStack--; + } + + Str++; + } + + if (ParenthesesStack != 0) + { + // The '(' doesn't pair with ')', invalid device path text + return NULL; + } + + if (IS_COMMA (*Str)) + { + *IsInstanceEnd = 1; + *Str = '\0'; + Str++; + } + else + { + *IsInstanceEnd = 0; + if (!IS_NULL (*Str)) + { + *Str = '\0'; + Str++; + } + } + + *DevicePath = Str; + + return ReturnStr; +} + +/* + * Function unpacks a device path data structure so that all the nodes of a device path + * are naturally aligned. + */ +EFI_DEVICE_PATH_P *UnpackDevicePath (EFI_DEVICE_PATH_P *DevPath) +{ + EFI_DEVICE_PATH_P *Src; + EFI_DEVICE_PATH_P *Dest; + EFI_DEVICE_PATH_P *NewPath; + UINT32 Size; + UINT32 Count; + + if (DevPath == NULL) + { + return NULL; + } + + // Walk device path and round sizes to valid boundries + Src = DevPath; + Size = 0; + for (Count = 0;;Count++) + { + if(Count > MAX_DEVICE_PATH_LEN) + { + // BugBug: Code to catch bogus device path + fprintf(stderr, "UnpackDevicePath: Cannot find device path end! Probably a bogus device path\n"); + return NULL; + } + Size += DevicePathNodeLength (Src); + Size += ALIGN_SIZE (Size); + + if (IsDevicePathEnd (Src)) + { + break; + } + + Src = (EFI_DEVICE_PATH_P *) NextDevicePathNode (Src); + } + + // Allocate space for the unpacked path + NewPath = (EFI_DEVICE_PATH_P *)(UINT8*)calloc(Size, sizeof(UINT8)); + + if (NewPath != NULL) + { + + assert(((UINT32) NewPath) % MIN_ALIGNMENT_SIZE == 0); + + // Copy each node + Src = DevPath; + Dest = NewPath; + for (;;) + { + Size = DevicePathNodeLength (Src); + memcpy(Dest, Src, Size); + Size += ALIGN_SIZE (Size); + SetDevicePathNodeLength (Dest, Size); + Dest->Type |= EFI_DP_TYPE_UNPACKED; + Dest = (EFI_DEVICE_PATH_P *) (((UINT8 *) Dest) + Size); + + if (IsDevicePathEnd (Src)) + { + break; + } + + Src = (EFI_DEVICE_PATH_P *) NextDevicePathNode (Src); + } + } + + return NewPath; +} + +// Returns the size of the device path, in bytes. +UINT32 DevicePathSize (const EFI_DEVICE_PATH_P *DevicePath) +{ + const EFI_DEVICE_PATH_P*Start; + UINT32 Count = 0; + + if (DevicePath == NULL) + { + return 0; + } + + // Search for the end of the device path structure + Start = (EFI_DEVICE_PATH_P*) DevicePath; + for (Count = 0;!IsDevicePathEnd(DevicePath);Count++) + { + if(Count > MAX_DEVICE_PATH_LEN) + { + // BugBug: Code to catch bogus device path + fprintf(stderr, "DevicePathSize: Cannot find device path end! Probably a bogus device path\n"); + return 0; + } + DevicePath = NextDevicePathNode (DevicePath); + } + + // Compute the size and add back in the size of the end device path structure + return ((UINT32) DevicePath - (UINT32) Start) + sizeof (EFI_DEVICE_PATH_P); +} + +// Creates a device node +EFI_DEVICE_PATH_P*CreateDeviceNode (UINT8 NodeType, UINT8 NodeSubType, UINT16 NodeLength) +{ + EFI_DEVICE_PATH_P*Node; + + if (NodeLength < sizeof (EFI_DEVICE_PATH_P)) + { + return NULL; + } + + Node = (EFI_DEVICE_PATH_P*) (UINT8*)calloc ((UINT32) NodeLength, sizeof(UINT8)); + if (Node != NULL) + { + Node->Type = NodeType; + Node->SubType = NodeSubType; + SetDevicePathNodeLength (Node, NodeLength); + } + + return Node; +} + +// Duplicate a device path structure. +EFI_DEVICE_PATH_P*DuplicateDevicePathP (EFI_DEVICE_PATH_P *DevicePath) +{ + EFI_DEVICE_PATH_P*NewDevicePath; + UINT32 Size; + + if (DevicePath == NULL) + { + return NULL; + } + + // Compute the size + Size = DevicePathSize (DevicePath); + if (Size == 0) + { + return NULL; + } + + // Allocate space for duplicate device path + NewDevicePath = MallocCopy(Size, DevicePath); + + return NewDevicePath; +} + +void EisaIdToText (UINT32 EisaId, CHAR8 *Text) +{ + CHAR8 PnpIdStr[17]; + + //SPrint ("%X", 0x0a03) => "0000000000000A03" + snprintf(PnpIdStr, 17, "%X", EisaId >> 16); + snprintf(Text,0,"%c%c%c%s",'@' + ((EisaId >> 10) & 0x1f),'@' + ((EisaId >> 5) & 0x1f),'@' + ((EisaId >> 0) & 0x1f), PnpIdStr + (16 - 4)); +} + +void DevPathToTextPci (CHAR8 *Str, void *DevPath, BOOLEAN DisplayOnly, BOOLEAN AllowShortcuts) +{ + PCI_DEVICE_PATH_P *Pci; + + Pci = DevPath; + CatPrintf(Str, "Pci(0x%x,0x%x)", Pci->Device, Pci->Function); +} + +void DevPathToTextAcpi (CHAR8 *Str, void *DevPath, BOOLEAN DisplayOnly, BOOLEAN AllowShortcuts) +{ + ACPI_HID_DEVICE_PATH_P *Acpi; + + Acpi = DevPath; + if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) + { + switch (EISA_ID_TO_NUM (Acpi->HID)) + { + case 0x0a03: + CatPrintf(Str, "PciRoot(0x%x)", Acpi->UID); + break; + default: + CatPrintf(Str, "Acpi(PNP%04x,0x%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID); + break; + } + } + else + { + CatPrintf(Str, "Acpi(0x%08x,0x%x)", Acpi->HID, Acpi->UID); + } +} + +void DevPathToTextEndInstance (CHAR8 *Str, void *DevPath, BOOLEAN DisplayOnly, BOOLEAN AllowShortcuts) +{ + CatPrintf(Str, ","); +} + +void DevPathToTextNodeUnknown (CHAR8 *Str, void *DevPath, BOOLEAN DisplayOnly, BOOLEAN AllowShortcuts) +{ + CatPrintf(Str, "?"); +} + +DEVICE_PATH_TO_TEXT_TABLE DevPathToTextTable[] = +{ + HARDWARE_DEVICE_PATH, + HW_PCI_DP, + DevPathToTextPci, + ACPI_DEVICE_PATH, + ACPI_DP, + DevPathToTextAcpi, + END_DEVICE_PATH_TYPE, + END_INSTANCE_DEVICE_PATH_SUBTYPE, + DevPathToTextEndInstance, + 0, + 0, + NULL +}; + +// Convert a device path to its text representation. +CHAR8 *ConvertDevicePathToAscii (const EFI_DEVICE_PATH_P*DevicePath, BOOLEAN DisplayOnly, BOOLEAN AllowShortcuts) +{ + CHAR8 *Str; + EFI_DEVICE_PATH_P *DevPathNode; + EFI_DEVICE_PATH_P *UnpackDevPath; + UINT32 Index; + UINT32 NewSize; + void (*DumpNode) (CHAR8 *, void *, BOOLEAN, BOOLEAN); + + if (DevicePath == NULL) + { + return NULL; + } + + Str = (CHAR8 *)calloc(MAX_PATH_LEN, sizeof(CHAR8)); + + // Unpacked the device path + UnpackDevPath = UnpackDevicePath ((EFI_DEVICE_PATH_P*) DevicePath); + assert(UnpackDevPath != NULL); + + // Process each device path node + DevPathNode = UnpackDevPath; + while (!IsDevicePathEnd (DevPathNode)) + { + // Find the handler to dump this device path node + DumpNode = NULL; + for (Index = 0; DevPathToTextTable[Index].Function; Index += 1) + { + if (DevicePathType (DevPathNode) == DevPathToTextTable[Index].Type && + DevicePathSubType (DevPathNode) == DevPathToTextTable[Index].SubType) + { + DumpNode = DevPathToTextTable[Index].Function; + break; + } + } + // If not found, use a generic function + if (!DumpNode) + { + DumpNode = DevPathToTextNodeUnknown; + } + + // Put a path seperator in if needed + if (strlen(Str) && DumpNode != DevPathToTextEndInstance) + { + if (*(Str + strlen(Str) - 1) != ',') + { + CatPrintf(Str, "/"); + } + } + // Print this node of the device path + DumpNode (Str, DevPathNode, DisplayOnly, AllowShortcuts); + + // Next device path node + DevPathNode = NextDevicePathNode (DevPathNode); + } + + // Shrink pool used for string allocation + free(UnpackDevPath); + NewSize = ((UINT32)strlen(Str) + 1); + Str = realloc(Str, NewSize); + assert(Str != NULL); + Str[strlen(Str)] = 0; + return Str; +} + diff --git a/CloverApp/Clover/GfxUtil/efidevp.h b/CloverApp/Clover/GfxUtil/efidevp.h new file mode 100644 index 000000000..bfb057f26 --- /dev/null +++ b/CloverApp/Clover/GfxUtil/efidevp.h @@ -0,0 +1,152 @@ +#ifndef _DEVPATH_H +#define _DEVPATH_H + +#define MAX_PATH_LEN 4096 +#define MAX_DEVICE_PATH_LEN 1000 + +#define MIN_ALIGNMENT_SIZE 4 +#define ALIGN_SIZE(a) ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0) + +#ifndef IS_COMMA +#define IS_COMMA(a) ((a) == ',') +#define IS_HYPHEN(a) ((a) == '-') +#define IS_DOT(a) ((a) == '.') +#define IS_LEFT_PARENTH(a) ((a) == '(') +#define IS_RIGHT_PARENTH(a) ((a) == ')') +#define IS_SLASH(a) ((a) == '/') +#define IS_NULL(a) ((a) == '\0') + +typedef signed char INT8; +typedef unsigned char UINT8; +typedef UINT8 BOOLEAN; +typedef char CHAR8; +typedef short INT16; +typedef unsigned short UINT16; +typedef int INT32; +typedef unsigned int UINT32; +typedef long long INT64; +typedef unsigned long long UINT64; +#endif + +typedef struct _EFI_DEVICE_PATH_P_TAG +{ + UINT8 Type; + UINT8 SubType; + UINT8 Length[2]; + +} EFI_DEVICE_PATH_P; + + +typedef struct +{ + UINT8 Type; + UINT8 SubType; + void (*Function) (CHAR8 *, void *, BOOLEAN, BOOLEAN); +} DEVICE_PATH_TO_TEXT_TABLE; + +typedef struct +{ + CHAR8 *DevicePathNodeText; + EFI_DEVICE_PATH_P * (*Function) (CHAR8 *); +} DEVICE_PATH_FROM_TEXT_TABLE; + +#define EFI_DP_TYPE_MASK 0x7F +#define EFI_DP_TYPE_UNPACKED 0x80 +#define END_DEVICE_PATH_TYPE 0x7f +#ifndef END_ENTIRE_DEVICE_PATH_SUBTYPE +#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff +#endif +#define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01 +#ifndef END_DEVICE_PATH_LENGTH +#define END_DEVICE_PATH_LENGTH (sizeof(EFI_DEVICE_PATH_P)) +#endif +#define DP_IS_END_TYPE(a) +#define DP_IS_END_SUBTYPE(a) ( ((a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE ) + +#define DevicePathType(a) ( ((a)->Type) & EFI_DP_TYPE_MASK ) +#define DevicePathSubType(a) ( (a)->SubType ) +#define DevicePathNodeLength(a) ( ((a)->Length[0]) | ((a)->Length[1] << 8) ) +#define NextDevicePathNode(a) ( (EFI_DEVICE_PATH_P *) ( ((unsigned char *) (a)) + DevicePathNodeLength(a))) +#define IsDevicePathEndType(a) ( DevicePathType(a) == END_DEVICE_PATH_TYPE ) +#define IsDevicePathEndSubType(a) ( (a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE ) +#define IsDevicePathEnd(a) ( IsDevicePathEndType(a) && IsDevicePathEndSubType(a) ) +#define IsDevicePathUnpacked(a) ( (a)->Type & EFI_DP_TYPE_UNPACKED ) + + +#define SetDevicePathNodeLength(a,l) { \ + (a)->Length[0] = (UINT8) (l); \ + (a)->Length[1] = (UINT8) ((l) >> 8); \ + } + +#define SetDevicePathEndNode(a) { \ + (a)->Type = END_DEVICE_PATH_TYPE; \ + (a)->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE; \ + (a)->Length[0] = sizeof(EFI_DEVICE_PATH_P); \ + (a)->Length[1] = 0; \ + } + +// ****** PCI ******* +#define HARDWARE_DEVICE_PATH 0x01 + +#define HW_PCI_DP 0x01 + +typedef struct _PCI_DEVICE_PATH +{ + EFI_DEVICE_PATH_P Header; + unsigned char Function; + unsigned char Device; +} PCI_DEVICE_PATH_P; + +// ****** ACPI ******* +#define ACPI_DEVICE_PATH 0x02 + +#define ACPI_DP 0x01 + +typedef struct _ACPI_HID_DEVICE_PATH +{ + EFI_DEVICE_PATH_P Header; + UINT32 HID; + UINT32 UID; +} ACPI_HID_DEVICE_PATH_P; + +// +// EISA ID Macro +// EISA ID Definition 32-bits +// bits[15:0] - three character compressed ASCII EISA ID. +// bits[31:16] - binary number +// Compressed ASCII is 5 bits per character 0b00001 = 'A' 0b11010 = 'Z' +// +#define PNP_EISA_ID_CONST 0x41d0 +//#define EISA_ID(_Name, _Num) ((UINT32) ((_Name) | (_Num) << 16)) +#define EISA_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId))) +//#define EFI_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId))) + +#define PNP_EISA_ID_MASK 0xffff +#define EISA_ID_TO_NUM(_Id) ((_Id) >> 16) + +void EisaIdFromText (CHAR8 *Text, UINT32 *EisaId); + +// Convert a device node to its text representation. +//CHAR8 *ConvertDeviceNodeToText (const EFI_DEVICE_PATH_P *DeviceNode, BOOLEAN DisplayOnly, BOOLEAN AllowShortcuts); + +// Convert a device path to its text representation. +CHAR8 *ConvertDevicePathToAscii (const EFI_DEVICE_PATH_P *DeviceNode, BOOLEAN DisplayOnly, BOOLEAN AllowShortcuts); + +// Convert text to the binary representation of a device node. +//EFI_DEVICE_PATH_P*ConvertTextToDeviceNode (const CHAR8 *TextDeviceNode); + +// Convert text to the binary representation of a device path. +//EFI_DEVICE_PATH_P*ConvertTextToDevicePath (const CHAR8 *TextDevicePath); + +// Returns the size of the device path, in bytes. +UINT32 DevicePathSize (const EFI_DEVICE_PATH_P *DevicePath); + +// Function is used to append a device path node to the end of another device path. +//EFI_DEVICE_PATH_P*AppendDevicePathNode (EFI_DEVICE_PATH_P *Src1, EFI_DEVICE_PATH_P *Node); + +// Function is used to insert a device path node to the start of another device path. +//EFI_DEVICE_PATH_P*InsertDevicePathNode (EFI_DEVICE_PATH_P *Src1, EFI_DEVICE_PATH_P *Node); + +//io_iterator_t RecursiveFindDevicePath(io_iterator_t iterator, const io_string_t search, const io_name_t plane, EFI_DEVICE_PATH_P**DevicePath, BOOLEAN *match); + +#endif diff --git a/CloverApp/Clover/GfxUtil/gfxutil.c b/CloverApp/Clover/GfxUtil/gfxutil.c new file mode 100644 index 000000000..9593854df --- /dev/null +++ b/CloverApp/Clover/GfxUtil/gfxutil.c @@ -0,0 +1,290 @@ +/* + * Created by mcmatrix on 07.01.08. + * Copyright 2008 mcmatrix. All rights reserved. + * + */ + +#include +#include +#include +#include "utils.h" +#include "efidevp.h" +#include "gfxutil.h" + +#define MAX_DEVICE_PATH_LEN 1000 +//#define NULL (void*)0 + +int is_string(unsigned char * buffer, int size) +{ + int i; + + for(i = 0; i < size - 1; i++) + { + if(!(IS_ALPHANUMMARK( buffer[i]))) return 0; + } + if (buffer[size - 1] == 0) return 1; + else + return 0; +} + + +static int readbin(unsigned char **data, unsigned int *size, unsigned char **dat, unsigned int len) +{ + unsigned char *d = *data; + unsigned int s = *size; + + if( s != 0 ) + { + *dat = (unsigned char *)calloc(len, sizeof(unsigned char)); + if (!dat) + { + fprintf(stderr, "read_binary: out of memory\n"); + return 0; + } + + if(((unsigned int)(len)) <= s) + { + memcpy((*dat),d,len); + *data = d + len; + *size = s - len; + return 1; + } + } + printf("read_binary: invalid binary data\n"); + return 0; +} + +/* + * Returns zero if the data is badly formatted. + */ +static int uni2str(unsigned char *d, unsigned int length, char **str, unsigned int *len) +{ + unsigned unich; + + if(length != 0) + { + /* Allocate space for the converted string */ + // Two unicode characters make up 1 buffer byte. Round up + if((*str = (char *)calloc( length*2 + 1, sizeof(char))) == 0) + { + fprintf(stderr, "unicode2str: out of memory\n"); + return 0; + } + + /* Convert the string from Unicode into UTF-8 */ + *len = 0; + while(length >= 2) + { + unich = READ_UINT16(d); + d += 2; + if(unich < 0x80) + { + (*str)[*len] = (char)unich; + ++(*len); + } + else if(unich < (1 << 11)) + { + (*str)[*len] = (char)(0xC0 | (unich >> 6)); + ++(*len); + (*str)[*len] = (char)(0x80 | (unich & 0x3F)); + ++(*len); + } + else + { + (*str)[*len] = (char)(0xE0 | (unich >> 12)); + ++(*len); + (*str)[*len] = (char)(0x80 | ((unich >> 6) & 0x3F)); + ++(*len); + (*str)[*len] = (char)(0x80 | (unich & 0x3F)); + ++(*len); + } + length -= 2; + } + (*str)[*len] = '\0'; + return 1; + } + printf("unicode2str: invalid binary unicode data\n"); + return 0; +} + +unsigned char _nibbleValue(unsigned char hexchar) +{ + unsigned char val; + + if(hexchar >= '0' && hexchar <= '9') + val = hexchar - '0'; + else if(hexchar >= 'A' && hexchar <= 'F') + val = hexchar - 'A' + 10; + else if(hexchar >= 'a' && hexchar <= 'f') + val = hexchar - 'a' + 10; + else + val = 0xff; + return(val); + +} + +// this reads gfx binary info and parses it +GFX_HEADER *parse_binary(const unsigned char *bp) +{ + GFX_HEADER *gfx_header = (GFX_HEADER *) NULL; + // head points to the first node in list, end points to the last node in list + GFX_BLOCKHEADER *gfx_blockheader = (GFX_BLOCKHEADER *) NULL; + GFX_BLOCKHEADER *gfx_blockheader_head = (GFX_BLOCKHEADER *) NULL; + GFX_BLOCKHEADER *gfx_blockheader_end = (GFX_BLOCKHEADER *) NULL; + GFX_ENTRY *gfx_entry = (GFX_ENTRY *) NULL; + GFX_ENTRY *gfx_entry_head = (GFX_ENTRY *) NULL; + GFX_ENTRY *gfx_entry_end = (GFX_ENTRY *) NULL; + unsigned char *data, *bin, *tmp = 0, *dpathtmp = 0, *src = 0; + char * str; + unsigned int str_len, data_len, size, length; + int i,j; + src = (unsigned char *)bp; + + //read header data + gfx_header = (GFX_HEADER *)calloc(1, sizeof(GFX_HEADER)); + if(!gfx_header) + { + fprintf(stderr, "parse_binary: out of memory\n"); + return NULL; + } + + gfx_header->filesize = READ_UINT32(src); + src+=4; + + gfx_header->var1 = READ_UINT32(src); + src+=4; + + gfx_header->countofblocks = READ_UINT32(src); + src+=4; + + //read blocks + gfx_blockheader_head = NULL; + gfx_blockheader_end = NULL; + for(i=0;icountofblocks;i++) + { + //create new block + gfx_blockheader = (GFX_BLOCKHEADER *)calloc(1, sizeof(GFX_BLOCKHEADER)); + if(!gfx_blockheader) + { + fprintf(stderr, "parse_binary: out of memory\n"); + return NULL; + } + //read block data + gfx_blockheader->blocksize = READ_UINT32(src); + src+=4; + + gfx_blockheader->records = READ_UINT32(src); + src+=4; + + size = gfx_blockheader->blocksize; + + tmp = (unsigned char *)src; + + unsigned int Count; + // read device path data until devpath end node 0x0004FF7F + for (Count = 0;;Count++) + { + if(Count > MAX_DEVICE_PATH_LEN) + { + // BugBug: Code to catch bogus device path + fprintf(stderr, "parse_binary: Cannot find device path end! Probably a bogus device path.\n"); + return NULL; + } + if( READ_UINT32(tmp) == 0x0004ff7f || READ_UINT32(tmp) == 0x0004ffff ) + { + tmp+=4; + break; + } + tmp++; + } + + // read device path data + gfx_blockheader->devpath_len = abs((int)tmp - (int)src); + readbin(&src, &size, &dpathtmp,gfx_blockheader->devpath_len); + gfx_blockheader->devpath = (struct _EFI_DEVICE_PATH_P_TAG *)dpathtmp; + + gfx_entry_head = NULL; + gfx_entry_end = NULL; + for(j=1;j <= gfx_blockheader->records;j++) + { + length = READ_UINT32(src); + length -= 4; src += 4; size -=4; + if(readbin(&src, &size, &bin, length)) + { + if(!uni2str(bin, length, &str, &str_len)) + { + return NULL; + } + } + else + { + return NULL; + } + + data_len = READ_UINT32(src); + data_len -= 4; src += 4; size -=4; + if(!readbin(&src, &size, &data, data_len)) + { + return NULL; + } + + gfx_entry = (GFX_ENTRY *)calloc(1, sizeof(GFX_ENTRY)); + if(!gfx_entry) + { + fprintf(stderr, "parse_binary: out of memory\n"); + return NULL; + } + //read entries + gfx_entry->bkey = bin; + gfx_entry->bkey_len = length; + gfx_entry->key = str; + gfx_entry->key_len = str_len; + gfx_entry->val_type = DATA_BINARY; // set default data type + gfx_entry->val = data; + gfx_entry->val_len = data_len; + + switch(data_len) + { + case sizeof(UINT8): // int8 + gfx_entry->val_type = DATA_INT8; + break; + case sizeof(UINT16): //int16 + gfx_entry->val_type = DATA_INT16; + break; + case sizeof(UINT32): //int32 + gfx_entry->val_type = DATA_INT32; + break; + default: + gfx_entry->val_type = DATA_BINARY; + break; + } + + // detect strings + if(gfx_entry->val_type == DATA_BINARY && is_string(data, data_len)) + { + gfx_entry->val_type = DATA_STRING; + } + + if(!gfx_entry_head) // if there are no nodes in list then + gfx_entry_head = gfx_entry; // set head to this new node + if(gfx_entry_end) + gfx_entry_end->next = gfx_entry; // link in new node to the end of the list + gfx_entry->next = NULL; // set next field to signify the end of list + gfx_entry_end = gfx_entry; // adjust end to point to the last node + } + + gfx_blockheader->entries = gfx_entry_head; + + if(!gfx_blockheader_head) // if there are no nodes in list then + gfx_blockheader_head = gfx_blockheader; // set head to this new node + if(gfx_blockheader_end) + gfx_blockheader_end->next = gfx_blockheader;// link in new node to the end of the list + gfx_blockheader->next = NULL; // set next field to signify the end of list + gfx_blockheader_end = gfx_blockheader; // adjust end to point to the last node + } + + gfx_header->blocks = gfx_blockheader_head; + + return (gfx_header); +} + diff --git a/CloverApp/Clover/GfxUtil/gfxutil.h b/CloverApp/Clover/GfxUtil/gfxutil.h new file mode 100644 index 000000000..9d714dcf2 --- /dev/null +++ b/CloverApp/Clover/GfxUtil/gfxutil.h @@ -0,0 +1,75 @@ +/* + * Created by mcmatrix on 08.01.08. + * Copyright 2008 mcmatrix All rights reserved. + * + */ + +// Constants +#define MAX_FILENAME 255 +#define DETECT_NUMBERS 1 +//#define NULL (void*)0 + +typedef enum DATA_TYPES +{ + DATA_INT8 = 1, + DATA_INT16 = 2, + DATA_INT32 = 3, + DATA_BINARY = 4, + DATA_STRING = 5 + +} DATA_TYPES; + +typedef enum FILE_TYPES +{ + FILE_BIN = 1, + FILE_HEX = 2, + FILE_XML = 3 + +} FILE_TYPES; + +typedef struct SETTINGS +{ + char ifile[MAX_FILENAME]; // input filename + FILE_TYPES ifile_type; // input file type + char ofile[MAX_FILENAME]; // output filename + FILE_TYPES ofile_type; // output file type + int verbose; // verbose mode + int detect_strings; // detect strings from binary data + int detect_numbers; // detect numberic data from binary +} SETTINGS; + +// gfx main header +typedef struct GFX_HEADER +{ + unsigned int filesize; // filesize + unsigned int var1; // unknown + unsigned int countofblocks; // count of datablocks + struct GFX_BLOCKHEADER * blocks; // pointer to datablock +} GFX_HEADER; + +// gfx block header +typedef struct GFX_BLOCKHEADER +{ + unsigned int blocksize; // datablock size + unsigned int records; // records count + struct _EFI_DEVICE_PATH_P_TAG *devpath; // device address binary + unsigned int devpath_len; // device address binary len + struct GFX_ENTRY * entries; // pointer to block entries + struct GFX_BLOCKHEADER * next; // pointer to next datablock +} GFX_BLOCKHEADER; + +// gfx data entries +typedef struct GFX_ENTRY +{ + unsigned char *bkey; // unicode key binary value + unsigned int bkey_len; // binary unicode key length + char *key; // ascii key value + unsigned int key_len; // ascii key length + unsigned char *val; // data binary value + unsigned int val_len; // binary data length + DATA_TYPES val_type; // binary data type + struct GFX_ENTRY * next; +} GFX_ENTRY; + +GFX_HEADER *parse_binary(const unsigned char *bp); +//CFDictionaryRef CreateGFXDictionary(GFX_HEADER * gfx); diff --git a/CloverApp/Clover/GfxUtil/utils.c b/CloverApp/Clover/GfxUtil/utils.c new file mode 100644 index 000000000..d0fb3c038 --- /dev/null +++ b/CloverApp/Clover/GfxUtil/utils.c @@ -0,0 +1,625 @@ +#include +#include +#include +#include +#include +#include "utils.h" + +void assertion(int condition, char * message) +{ + if (condition == 0) + { + fprintf(stderr, "error: %s.\n", message); + exit(1); + } +} + +unsigned long UTF16ReadChar(const unsigned short *str, int len, int *posn) +{ + unsigned long ch = (unsigned long)(str[*posn]); + unsigned long low; + if(ch < (unsigned long)0xD800 || ch > (unsigned long)0xDBFF) + { + /* Regular 16-bit character, or a low surrogate in the + wrong position for UTF-16 */ + ++(*posn); + return ch; + } + else if((*posn + 2) <= len && + (low = (unsigned long)(str[*posn + 1])) >= (unsigned long)0xDC00 && + low <= (unsigned long)0xDFFF) + { + /* Surrogate character */ + *posn += 2; + return ((ch - (unsigned long)0xD800) << 10) + (low & 0x03FF) + + (unsigned long)0x10000; + } + else + { + /* High surrogate without a low surrogate following it */ + ++(*posn); + return ch; + } +} +typedef unsigned short UINT16; +typedef unsigned char UINT8; + +unsigned long UTF16ReadCharAsBytes(const void *_str, int len, int *posn) +{ + const unsigned char *str = (const unsigned char *)_str; + unsigned long ch; + unsigned long low; + if((*posn + 2) > len) + { + /* We have a character left over, which is an error. + But we have to do something, so return it as-is */ + ch = (unsigned long)(str[*posn]); + ++(*posn); + return ch; + } +// ch = (unsigned long)(READ_UINT16(str + *posn)); + ch = (unsigned long)str[*posn] + (unsigned long)str[*posn+1] * 256; + *posn += 2; + if(ch < (unsigned long)0xD800 || ch > (unsigned long)0xDBFF) + { + /* Regular 16-bit character, or a low surrogate in the + wrong position for UTF-16 */ + return ch; + } + if((*posn + 2) > len) + { + /* Not enough bytes: return the high surrogate as-is */ + return ch; + } +// low = (unsigned long)(READ_UINT16(str + *posn)); + low = (unsigned long)str[*posn] + (unsigned long)str[*posn+1] * 256; + if(low < (unsigned long)0xDC00 || low > (unsigned long)0xDFFF) + { + /* High surrogate without a low surrogate following it */ + return ch; + } + *posn += 2; + return ((ch - (unsigned long)0xD800) << 10) + (low & 0x03FF) + + (unsigned long)0x10000; +} + +int UTF16WriteChar(unsigned short *buf, unsigned long ch) +{ + if(buf) + { + if(ch < (unsigned long)0x10000) + { + *buf = (unsigned short)ch; + return 1; + } + else if(ch < (unsigned long)0x110000) + { + ch -= 0x10000; + buf[0] = (unsigned short)((ch >> 10) + 0xD800); + buf[1] = (unsigned short)((ch & 0x03FF) + 0xDC00); + return 2; + } + else + { + return 0; + } + } + else + { + if(ch < (unsigned long)0x10000) + { + return 1; + } + else if(ch < (unsigned long)0x110000) + { + return 2; + } + else + { + return 0; + } + } +} + +int UTF16WriteCharAsBytes(void *_buf, unsigned long ch) +{ + if(_buf) + { + unsigned char *buf = (unsigned char *)_buf; + if(ch < (unsigned long)0x10000) + { + buf[0] = (unsigned char)ch; + buf[1] = (unsigned char)(ch >> 8); + return 2; + } + else if(ch < (unsigned long)0x110000) + { + unsigned tempch; + ch -= 0x10000; + tempch = (unsigned)((ch >> 10) + 0xD800); + buf[0] = (unsigned char)tempch; + buf[1] = (unsigned char)(tempch >> 8); + tempch = (unsigned)((ch & 0x03FF) + 0xDC00); + buf[2] = (unsigned char)tempch; + buf[3] = (unsigned char)(tempch >> 8); + return 4; + } + else + { + return 0; + } + } + else + { + if(ch < (unsigned long)0x10000) + { + return 2; + } + else if(ch < (unsigned long)0x110000) + { + return 4; + } + else + { + return 0; + } + } +} + +unsigned long UTF8ReadChar(const void *_str, int len, int *posn) +{ + const char *str = (const char *)_str; + char ch = str[*posn]; + unsigned long result; + if((ch & 0x80) == 0) + { + /* Single-byte UTF-8 encoding */ + ++(*posn); + return (unsigned long)ch; + } + else if((ch & (char)0xE0) == (char)0xC0 && (*posn + 2) <= len) + { + /* Two-byte UTF-8 encoding */ + result = ((((unsigned long)(ch & 0x1F)) << 6) | + ((unsigned long)(str[(*posn) + 1] & 0x3F))); + (*posn) += 2; + return result; + } + else if((ch & (char)0xF0) == (char)0xE0 && (*posn + 3) <= len) + { + /* Three-byte UTF-8 encoding */ + result = ((((unsigned long)(ch & 0x0F)) << 12) | + (((unsigned long)(str[(*posn) + 1] & 0x3F)) << 6) | + ((unsigned long)(str[(*posn) + 2] & 0x3F))); + (*posn) += 3; + return result; + } + else if((ch & (char)0xF8) == (char)0xF0 && (*posn + 4) <= len) + { + /* Four-byte UTF-8 encoding */ + result = ((((unsigned long)(ch & 0x07)) << 18) | + (((unsigned long)(str[(*posn) + 1] & 0x3F)) << 12) | + (((unsigned long)(str[(*posn) + 2] & 0x3F)) << 6) | + ((unsigned long)(str[(*posn) + 3] & 0x3F))); + (*posn) += 4; + return result; + } + else if((ch & (char)0xFC) == (char)0xF8 && (*posn + 5) <= len) + { + /* Five-byte UTF-8 encoding */ + result = ((((unsigned long)(ch & 0x03)) << 24) | + (((unsigned long)(str[(*posn) + 1] & 0x3F)) << 18) | + (((unsigned long)(str[(*posn) + 2] & 0x3F)) << 12) | + (((unsigned long)(str[(*posn) + 3] & 0x3F)) << 6) | + ((unsigned long)(str[(*posn) + 4] & 0x3F))); + (*posn) += 5; + return result; + } + else if((ch & (char)0xFC) == (char)0xFC && (*posn + 6) <= len) + { + /* Six-byte UTF-8 encoding */ + result = ((((unsigned long)(ch & 0x03)) << 30) | + (((unsigned long)(str[(*posn) + 1] & 0x3F)) << 24) | + (((unsigned long)(str[(*posn) + 2] & 0x3F)) << 18) | + (((unsigned long)(str[(*posn) + 3] & 0x3F)) << 12) | + (((unsigned long)(str[(*posn) + 4] & 0x3F)) << 6) | + ((unsigned long)(str[(*posn) + 5] & 0x3F))); + (*posn) += 6; + return result; + } + else + { + /* Invalid UTF-8 encoding: treat as an 8-bit Latin-1 character */ + ++(*posn); + return (((unsigned long)ch) & 0xFF); + } +} + +int UTF8WriteChar(char *str, unsigned long ch) +{ + if(str) + { + /* Write the character to the buffer */ + if(!ch) + { + /* Encode embedded NUL's as 0xC0 0x80 so that code + that uses C-style strings doesn't get confused */ + str[0] = (char)0xC0; + str[1] = (char)0x80; + return 2; + } + else if(ch < (unsigned long)0x80) + { + str[0] = (char)ch; + return 1; + } + else if(ch < (((unsigned long)1) << 11)) + { + str[0] = (char)(0xC0 | (ch >> 6)); + str[1] = (char)(0x80 | (ch & 0x3F)); + return 2; + } + else if(ch < (((unsigned long)1) << 16)) + { + str[0] = (char)(0xE0 | (ch >> 12)); + str[1] = (char)(0x80 | ((ch >> 6) & 0x3F)); + str[2] = (char)(0x80 | (ch & 0x3F)); + return 3; + } + else if(ch < (((unsigned long)1) << 21)) + { + str[0] = (char)(0xF0 | (ch >> 18)); + str[1] = (char)(0x80 | ((ch >> 12) & 0x3F)); + str[2] = (char)(0x80 | ((ch >> 6) & 0x3F)); + str[3] = (char)(0x80 | (ch & 0x3F)); + return 4; + } + else if(ch < (((unsigned long)1) << 26)) + { + str[0] = (char)(0xF8 | (ch >> 24)); + str[1] = (char)(0x80 | ((ch >> 18) & 0x3F)); + str[2] = (char)(0x80 | ((ch >> 12) & 0x3F)); + str[3] = (char)(0x80 | ((ch >> 6) & 0x3F)); + str[4] = (char)(0x80 | (ch & 0x3F)); + return 5; + } + else + { + str[0] = (char)(0xFC | (ch >> 30)); + str[1] = (char)(0x80 | ((ch >> 24) & 0x3F)); + str[2] = (char)(0x80 | ((ch >> 18) & 0x3F)); + str[3] = (char)(0x80 | ((ch >> 12) & 0x3F)); + str[4] = (char)(0x80 | ((ch >> 6) & 0x3F)); + str[5] = (char)(0x80 | (ch & 0x3F)); + return 6; + } + } + else + { + /* Determine the length of the character */ + if(!ch) + { + return 2; + } + else if(ch < (unsigned long)0x80) + { + return 1; + } + else if(ch < (((unsigned long)1) << 11)) + { + return 2; + } + else if(ch < (((unsigned long)1) << 16)) + { + return 3; + } + else if(ch < (((unsigned long)1) << 21)) + { + return 4; + } + else if(ch < (((unsigned long)1) << 26)) + { + return 5; + } + else + { + return 6; + } + } +} + +// Skip the leading white space and '0x' or '0X' of a integer string +char * TrimHexStr (char *Str, int *IsHex) +{ + *IsHex = 0; + + // skip preceeding white space + while (*Str && *Str == ' ') + { + Str += 1; + } + + // skip preceeding zeros + while (*Str && *Str == '0') + { + Str += 1; + } + // skip preceeding character 'x' + if (*Str && (*Str == 'x' || *Str == 'X')) + { + Str += 1; + *IsHex = 1; + } + + return Str; +} + +// Convert hex string to uint +unsigned int Xtoi (char *Str, unsigned int *Bytes) +{ + unsigned int u; + unsigned int Length; + + assert(Str != NULL); + + // convert hex digits + u = 0; + Length = sizeof (unsigned int); + HexStringToBuf ((unsigned char *) &u, &Length, Str, Bytes); + + return u; +} + +// Convert hex string to 64 bit data. +void Xtoi64 (char *Str, unsigned long *Data, unsigned int *Bytes) +{ + unsigned int Length; + + *Data = 0; + Length = sizeof (unsigned long); + HexStringToBuf ((unsigned char *) Data, &Length, Str, Bytes); +} + +// Convert decimal string to uint +unsigned int Dtoi (char *str) +{ + unsigned int u; + char c; + unsigned int m; + unsigned int n; + + assert(str != NULL); + + m = (unsigned int) -1 / 10; + n = (unsigned int) -1 % 10; + + // skip preceeding white space + while (*str && *str == ' ') + { + str += 1; + } + + // convert digits + u = 0; + c = *(str++); + while (c) + { + if (c >= '0' && c <= '9') + { + if ((u > m) || ((u == m) && ((c - '0') > (int)n))) + { + return (unsigned int) -1; + } + u = (u * 10) + c - '0'; + } else { + break; + } + c = *(str++); + } + + return u; +} + +// Convert decimal string to uint +void Dtoi64 (char *str,unsigned long *Data) +{ + unsigned long u; + char c; + unsigned long m; + unsigned long n; + + assert(str != NULL); + assert(Data != NULL); + + // skip preceeding white space + while (*str && *str == ' ') + { + str += 1; + } + + // convert digits + u = 0; + c = *(str++); + while (c) { + if (c >= '0' && c <= '9') + { + m = u << 3; + n = u << 1; + u = m + n + c - '0'; + } else { + break; + } + + c = *(str++); + } + + *Data = u; +} + +// Convert integer string to uint. +unsigned int Strtoi (char *Str, unsigned int *Bytes) +{ + int IsHex; + + Str = TrimHexStr (Str, &IsHex); + + if (IsHex) + { + return Xtoi (Str, Bytes); + } else { + return Dtoi (Str); + } +} + +// Convert integer string to 64 bit data. +void Strtoi64 (char *Str, unsigned long *Data, unsigned int *Bytes) +{ + int IsHex; + + Str = TrimHexStr (Str, &IsHex); + + if (IsHex) { + Xtoi64 (Str, Data, Bytes); + } else { + Dtoi64 (Str, Data); + } +} + +int StrToBuf (unsigned char *Buf, unsigned int BufferLength, char *Str) +{ + unsigned int Index; + unsigned int StrLength; + unsigned char Digit = 0; + unsigned char Byte; + + // Two hex char make up one byte + StrLength = BufferLength * sizeof (char); + + for(Index = 0; Index < StrLength; Index++, Str++) + { + + IsCharHexDigit (&Digit, *Str); + + // For odd charaters, write the upper nibble for each buffer byte, + // and for even characters, the lower nibble. + + if ((Index & 1) == 0) + { + Byte = Digit << 4; + } else { + Byte = Buf[Index / 2]; + Byte &= 0xF0; + Byte |= Digit; + } + + Buf[Index / 2] = Byte; + } + + return 1; +} + +/* Converts Unicode string to binary buffer. + * The conversion may be partial. + * The first character in the string that is not hex digit stops the conversion. + * At a minimum, any blob of data could be represented as a hex string. + */ +int HexStringToBuf (unsigned char *Buf, unsigned int *Len, char *Str, unsigned int *ConvertedStrLen) +{ + unsigned int HexCnt; + unsigned int Idx; + unsigned int BufferLength; + unsigned char Digit; + unsigned char Byte; + + // Find out how many hex characters the string has. + for (Idx = 0, HexCnt = 0; IsCharHexDigit (&Digit, Str[Idx]); Idx++, HexCnt++); + + if (HexCnt == 0) + { + *Len = 0; + return 1; + } + + // Two Unicode characters make up 1 buffer byte. Round up. + BufferLength = (HexCnt + 1) / 2; + + // Test if buffer is passed enough. + if (BufferLength > (*Len)) + { + *Len = BufferLength; + return 0; + } + + *Len = BufferLength; + + for (Idx = 0; Idx < HexCnt; Idx++) + { + IsCharHexDigit (&Digit, Str[HexCnt - 1 - Idx]); + + // For odd charaters, write the lower nibble for each buffer byte, + // and for even characters, the upper nibble. + if ((Idx & 1) == 0) { + Byte = Digit; + } else { + Byte = Buf[Idx / 2]; + Byte &= 0x0F; + Byte |= Digit << 4; + } + + Buf[Idx / 2] = Byte; + } + + if (ConvertedStrLen != NULL) { + *ConvertedStrLen = HexCnt; + } + + return 1; +} + +// Determines if a Unicode character is a hexadecimal digit. +int IsCharHexDigit (unsigned char *Digit, char Char) +{ + if ((Char >= '0') && (Char <= '9')) + { + *Digit = (unsigned char) (Char - '0'); + return 1; + } + + if ((Char >= 'A') && (Char <= 'F')) + { + *Digit = (unsigned char) (Char - 'A' + 0xA); + return 1; + } + + if ((Char >= 'a') && (Char <= 'f')) + { + *Digit = (unsigned char) (Char - 'a' + 0xA); + return 1; + } + + return 0; +} + +void CatPrintf(char *target, const char *format, ...) +{ + va_list varargs; + + while(*target) target++; + + va_start(varargs, format); + vsprintf(target, format, varargs); + va_end(varargs); +} + +void *MallocCopy(unsigned int size, void *buf) +{ + void *new = NULL; + + if( (new = (void *)malloc(size * sizeof(void) ) ) != NULL) + { + memcpy(new, buf, size); + } + + return new; +} + diff --git a/CloverApp/Clover/GfxUtil/utils.h b/CloverApp/Clover/GfxUtil/utils.h new file mode 100644 index 000000000..bfa990ac4 --- /dev/null +++ b/CloverApp/Clover/GfxUtil/utils.h @@ -0,0 +1,204 @@ +#ifndef _UTILS_H +#define _UTILS_H + +/* + * Define the 8-bit and 16-bit numeric types. + * +typedef signed char INT8; +typedef unsigned char UINT8; +typedef UINT8 BOOLEAN; +typedef char CHAR8; +typedef short INT16; +typedef unsigned short UINT16; +typedef int INT32; +typedef unsigned int UINT32; +typedef long long INT64; +typedef unsigned long long UINT64; +typedef float FLOAT; +typedef double DOUBLE; +*/ +/* + * alpha = lowalpha | upalpha + */ +#define IS_ALPHA(x) (IS_LOWALPHA(x) || IS_UPALPHA(x)) + +/* + * lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | + * "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | + * "u" | "v" | "w" | "x" | "y" | "z" + */ +#define IS_LOWALPHA(x) (((unsigned char)(x) >= 'a') && ((unsigned char)(x) <= 'z')) + +/* + * upalpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | + * "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | + * "U" | "V" | "W" | "X" | "Y" | "Z" + */ +#define IS_UPALPHA(x) (((unsigned char)(x) >= 'A') && ((unsigned char)(x) <= 'Z')) + +#ifdef IS_DIGIT +#undef IS_DIGIT +#endif +/* + * digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" + */ +#define IS_DIGIT(x) (((unsigned char)(x) >= '0') && ((unsigned char)(x) <= '9')) + +/* + * alphanum = alpha | digit + */ +#define IS_ALPHANUM(x) (IS_ALPHA(x) || IS_DIGIT(x)) + +/* + * hex = digit | "A" | "B" | "C" | "D" | "E" | "F" | + * "a" | "b" | "c" | "d" | "e" | "f" + */ +#ifndef IS_HEX +#define IS_HEX(x) ((IS_DIGIT(x)) || (((unsigned char)(x) >= 'a') && ((unsigned char)(x) <= 'f')) || \ + (((unsigned char)(x) >= 'A') && ((unsigned char)(x) <= 'F'))) +#endif +/* + * mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" | ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | "," | + * "[" | "]" + */ + +#define IS_MARK(x) (((unsigned char)(x) == '-') || ((unsigned char)(x) == '_') || ((unsigned char)(x) == '.') || ((unsigned char)(x) == '!') || ((unsigned char)(x) == '~') || ((unsigned char)(x) == '*') || ((unsigned char)(x) == '\'') || \ + ((unsigned char)(x) == '(') || ((unsigned char)(x) == ')') || ((unsigned char)(x) == ';') || ((unsigned char)(x) == '/') || ((unsigned char)(x) == '?') || ((unsigned char)(x) == ':') || ((unsigned char)(x) == '@') || ((unsigned char)(x) == '&') || ((unsigned char)(x) == '=') || \ + ((unsigned char)(x) == '+') || ((unsigned char)(x) == '$') || ((unsigned char)(x) == ',') || ((unsigned char)(x) == '[') || ((unsigned char)(x) == ']')) + +#define IS_SPACE(x) (((unsigned char)(x) == ' ')) + +/* + * alphanummark = alphanum | mark + */ +#define IS_ALPHANUMMARK(x) (IS_ALPHANUM(x) || IS_MARK(x) || IS_SPACE(x)) + +/* + * Read little-endian values of various sizes from memory buffers. + */ +#define _READ_BYTE(buf,offset) ((UINT32)(UINT8)(((UINT8 *)(buf))[(offset)])) +#define _READ_BYTE_SHIFT(buf,offset,shift) (((UINT32)(UINT8)(((UINT8 *)(buf))[(offset)])) << (shift)) + +#define READ_INT8(buf) ((INT8)(_READ_BYTE((buf), 0))) +#define READ_UINT8(buf) ((UINT8)(_READ_BYTE((buf), 0))) +#define READ_INT16(buf) ((INT16)(_READ_BYTE((buf), 0) | _READ_BYTE_SHIFT((buf), 1, 8))) +#define READ_UINT16(buf) ((UINT16)(_READ_BYTE((buf), 0) | _READ_BYTE_SHIFT((buf), 1, 8))) +#define READ_INT32(buf) ((INT32)(_READ_BYTE((buf), 0) | _READ_BYTE_SHIFT((buf), 1, 8) | _READ_BYTE_SHIFT((buf), 2, 16) | _READ_BYTE_SHIFT((buf), 3, 24))) +#define READ_UINT32(buf) ((UINT32)(_READ_BYTE((buf), 0) | _READ_BYTE_SHIFT((buf), 1, 8) | _READ_BYTE_SHIFT((buf), 2, 16) | _READ_BYTE_SHIFT((buf), 3, 24))) +#define READ_INT64(buf) (((INT64)(READ_UINT32((buf)))) | (((INT64)(READ_INT32(((UINT8 *)(buf)) + 4))) << 32)) +#define READ_UINT64(buf) (((UINT64)(READ_UINT32((buf)))) | (((UINT64)(READ_UINT32(((UINT8 *)(buf)) + 4))) << 32)) + +/* + * Write little-endian values of various sizes to memory buffers. + */ +#define WRITE_UINT8(buf, value) \ + do { \ + (buf)[0] = (unsigned char)(value & 0xFF); \ + } while (0) +#define WRITE_UINT16(buf, value) \ + do { \ + (buf)[0] = (unsigned char)(value & 0xFF); \ + (buf)[1] = (unsigned char)(((value) >> 8) & 0xFF); \ + } while (0) +#define WRITE_INT16(buf, value) WRITE_UINT16((buf), (UINT16)(value)) +#define WRITE_UINT32(buf, value) \ + do { \ + (buf)[0] = (unsigned char)(value & 0xFF); \ + (buf)[1] = (unsigned char)(((value) >> 8) & 0xFF); \ + (buf)[2] = (unsigned char)(((value) >> 16) & 0xFF); \ + (buf)[3] = (unsigned char)(((value) >> 24) & 0xFF); \ + } while (0) +#define WRITE_INT32(buf, value) WRITE_UINT32((buf), (UINT32)(value)) +#define WRITE_UINT64(buf, value) \ + do { \ + (buf)[0] = (unsigned char)(value & 0xFF); \ + (buf)[1] = (unsigned char)(((value) >> 8) & 0xFF); \ + (buf)[2] = (unsigned char)(((value) >> 16) & 0xFF); \ + (buf)[3] = (unsigned char)(((value) >> 24) & 0xFF); \ + (buf)[4] = (unsigned char)(((value) >> 32) & 0xFF); \ + (buf)[5] = (unsigned char)(((value) >> 40) & 0xFF); \ + (buf)[6] = (unsigned char)(((value) >> 48) & 0xFF); \ + (buf)[7] = (unsigned char)(((value) >> 56) & 0xFF); \ + } while (0) +#define WRITE_INT64(buf, value) WRITE_UINT64((buf), (UINT64)(value)) + +void assertion(int condition, char * message); + +/* + * Read a UTF-8 character from a string position. + */ +unsigned long UTF8ReadChar(const void *str, int len, int *posn); + +/* + * Write a UTF-8 character to a buffer. Returns the + * number of bytes used. If the buffer is NULL, then + * return the number of bytes needed. + */ +int UTF8WriteChar(char *str, unsigned long ch); + +/* + * Read a UTF-16 character from a 16-bit string position. + * "len" and "posn" are indexes into a 16-bit array. + */ +unsigned long UTF16ReadChar(const unsigned short *str, int len, int *posn); + +/* + * Read a UTF-16 character from a string as little-endian values. + * "len" and "posn" are indexes into a byte array. + */ +unsigned long UTF16ReadCharAsBytes(const void *str, int len, int *posn); + +/* + * Convert a 32-bit Unicode character into UTF-16. Returns the + * number of 16-bit characters required (1 or 2), or zero if + * the character cannot be represented using UTF-16. If "buf" + * is NULL, then return the number of characters required. + */ +int UTF16WriteChar(unsigned short *buf, unsigned long ch); + +/* + * Convert a 32-bit Unicode character into UTF-16, and store it + * using little-endian bytes at "buf". Returns the number of + * bytes (2 or 4), or zero if the character cannot be represented. + * If "buf" is NULL, then return the number of bytes required. + */ +int UTF16WriteCharAsBytes(void *buf, unsigned long ch); + +// Skip the leading white space and '0x' or '0X' of a integer string +char * TrimHexStr (char *Str, int *IsHex); + +// Convert hex string to uint +unsigned int Xtoi (char *Str, unsigned int *Bytes); + +// Convert hex string to 64 bit data. +void Xtoi64 (char *Str, unsigned long *Data, unsigned int *Bytes); + +// Convert decimal string to uint +unsigned int Dtoi (char *str); + +// Convert decimal string to uint +void Dtoi64 (char *str,unsigned long *Data); + +// Convert integer string to uint. +unsigned int Strtoi (char *Str, unsigned int *Bytes); + +// Convert integer string to 64 bit data. +void Strtoi64 (char *Str, unsigned long *Data, unsigned int *Bytes); + +int StrToBuf (unsigned char *Buf, unsigned int BufferLength, char *Str); + +/* Converts Unicode string to binary buffer. + * The conversion may be partial. + * The first character in the string that is not hex digit stops the conversion. + * At a minimum, any blob of data could be represented as a hex string. + */ +int HexStringToBuf (unsigned char *Buf, unsigned int *Len, char *Str, unsigned int *ConvertedStrLen); + +// Determines if a Unicode character is a hexadecimal digit. +int IsCharHexDigit (unsigned char *Digit, char Char); + +void CatPrintf(char *target, const char *format, ...); + + +void *MallocCopy(unsigned int size, void *buf); +#endif diff --git a/CloverApp/Clover/IO.swift b/CloverApp/Clover/IO.swift index f31b469bb..4d87dd77d 100644 --- a/CloverApp/Clover/IO.swift +++ b/CloverApp/Clover/IO.swift @@ -49,6 +49,22 @@ func getFirmawareVendor() -> String? { return nil } +/// Get device-properties data. +func getDevicePropertiesData() -> Data? { + if let data = getEFItree()?.object(forKey: "device-properties") as? Data { + return data + } + return nil +} + +/// Get Clover Settings data. +func getCloverSettingsData() -> Data? { + if let data = getEFIPlatform()?.object(forKey: "Settings") as? Data { + return data + } + return nil +} + /// Get IODeviceTree:/efi/platform Dictionary. fileprivate func getEFIPlatform() -> NSDictionary? { var ref: io_registry_entry_t diff --git a/CloverApp/Clover/Installer/Driver.swift b/CloverApp/Clover/Installer/Driver.swift index 556f6ca4e..0cc8e1f9a 100644 --- a/CloverApp/Clover/Installer/Driver.swift +++ b/CloverApp/Clover/Installer/Driver.swift @@ -13,7 +13,7 @@ enum EFIkind: String { case bios = "BIOS" } -class EFIDriver { +final class EFIDriver { private var internalState : NSControl.StateValue = .off var dest : String var src : String diff --git a/CloverApp/Clover/Installer/DriversCollection.swift b/CloverApp/Clover/Installer/DriversCollection.swift index 9e2578135..e661606f8 100644 --- a/CloverApp/Clover/Installer/DriversCollection.swift +++ b/CloverApp/Clover/Installer/DriversCollection.swift @@ -20,7 +20,7 @@ let kUnknownUEFISection = "UEFI, but not from this installer" let kUnknownBIOSSection = "BIOS, but not from this installer" // MARK: ItemTextFieldCell (NSTextFieldCell sub class) -class ItemTextFieldCell: NSTextFieldCell { +final class ItemTextFieldCell: NSTextFieldCell { override func drawingRect(forBounds rect: NSRect) -> NSRect { var nr = super.drawingRect(forBounds: rect) let size = self.cellSize(forBounds: rect) @@ -34,7 +34,7 @@ class ItemTextFieldCell: NSTextFieldCell { } // MARK: ItemTextField (NSTextfield sub class) -class ItemTextField: NSTextField { +final class ItemTextField: NSTextField { var trackingArea: NSTrackingArea? = nil override init(frame frameRect: NSRect) { super.init(frame: frameRect) @@ -79,7 +79,7 @@ class ItemTextField: NSTextField { } // MARK: CollectionViewItem (NSCollectionViewItem sub class) -class CollectionViewItem: NSCollectionViewItem { +final class CollectionViewItem: NSCollectionViewItem { var driver : EFIDriver? = nil var installerController : InstallerViewController? = nil var installerOutController : InstallerOutViewController? = nil @@ -442,7 +442,7 @@ class CollectionViewItem: NSCollectionViewItem { } // MARK: HeaderView (NSView sub class) -class HeaderView: NSView { +final class HeaderView: NSView { public let field: NSTextField = { let f = NSTextField() if #available(OSX 10.10, *) { diff --git a/CloverApp/Clover/Installer/Installer.swift b/CloverApp/Clover/Installer/Installer.swift index 21738f835..1795c5ec6 100644 --- a/CloverApp/Clover/Installer/Installer.swift +++ b/CloverApp/Clover/Installer/Installer.swift @@ -10,7 +10,7 @@ import Cocoa // MARK: Installer Window controller -class InstallerWindowController: NSWindowController, NSWindowDelegate { +final class InstallerWindowController: NSWindowController, NSWindowDelegate { var viewController : NSViewController? = nil override var contentViewController: NSViewController? { get { @@ -84,7 +84,7 @@ class InstallerWindowController: NSWindowController, NSWindowDelegate { } // MARK: InstallerViewController (NSViewController sub class) -class InstallerViewController: NSViewController { +final class InstallerViewController: NSViewController { // MARK: variables var targetVol : String = "" diff --git a/CloverApp/Clover/Installer/InstallerOutline.swift b/CloverApp/Clover/Installer/InstallerOutline.swift index 8a31d83c5..11cbe4587 100644 --- a/CloverApp/Clover/Installer/InstallerOutline.swift +++ b/CloverApp/Clover/Installer/InstallerOutline.swift @@ -9,7 +9,7 @@ import Cocoa // MARK: Installer Window controller -class InstallerOutWindowController: NSWindowController, NSWindowDelegate { +final class InstallerOutWindowController: NSWindowController, NSWindowDelegate { var viewController : NSViewController? = nil override var contentViewController: NSViewController? { get { @@ -68,7 +68,7 @@ class InstallerOutWindowController: NSWindowController, NSWindowDelegate { } } -class InstallerOutViewController: NSViewController { +final class InstallerOutViewController: NSViewController { // MARK: variables var targetVol : String = "" diff --git a/CloverApp/Clover/Releases.swift b/CloverApp/Clover/Releases.swift index d68c0f6e1..758151ebf 100644 --- a/CloverApp/Clover/Releases.swift +++ b/CloverApp/Clover/Releases.swift @@ -51,13 +51,14 @@ func getLatestReleases(reply: @escaping (String?, String?, String?, String?) -> for line in reponse.components(separatedBy: .newlines) { if (line.range(of: "href=\"/CloverHackyColor/CloverBootloader/releases/download/") != nil) { applink = line.components(separatedBy: "href=\"")[1] - //applink = "/CloverHackyColor/CloverBootloader/releases/download/5099/Clover.app-v1.15-5099.zip\" rel=\"nofollow\" class=\"d-flex flex-items-center min-width-0\">" + //applink = "/CloverHackyColor/CloverBootloader/releases/download/5099/Clover.app_v1.17_r5104.pkg.zip\" rel=\"nofollow\" class=\"d-flex flex-items-center min-width-0\">" applink = "https://github.com\(applink!.components(separatedBy: "\"")[0])" - - if applink!.lastPath.hasPrefix("Clover.app-v") && applink!.hasSuffix(".zip") { - // Clover.app-v1.15-5099.zip - appvers = applink!.components(separatedBy: "Clover.app-v")[1] - appvers = appvers!.components(separatedBy: "-")[0] + + if applink!.lastPath.hasPrefix("Clover.app_v") && applink!.hasSuffix(".zip") { + // Clover.app_v1.17_r5104.pkg.zip + appvers = applink!.components(separatedBy: "Clover.app_v")[1] + //print(appvers) + appvers = appvers!.components(separatedBy: "_r")[0] break } } diff --git a/CloverApp/Clover/SettingsView.swift b/CloverApp/Clover/SettingsView.swift index c3a7a95db..b1d5984a8 100644 --- a/CloverApp/Clover/SettingsView.swift +++ b/CloverApp/Clover/SettingsView.swift @@ -8,7 +8,7 @@ import Cocoa -class LITabView: NSTabView { +final class LITabView: NSTabView { private var drawBack : Bool = false var tabIndex: Int = 0 var lastTabIndex: Int { @@ -32,11 +32,11 @@ class LITabView: NSTabView { } } -class SoundSlider : NSSlider { +final class SoundSlider : NSSlider { var field : NSTextField? } -class SettingsViewController: NSViewController, NSTextFieldDelegate, URLSessionDownloadDelegate { +final class SettingsViewController: NSViewController, NSTextFieldDelegate, URLSessionDownloadDelegate { // MARK: Variables @IBOutlet var tabViewInfo : LITabView! // tab 0 @@ -130,6 +130,7 @@ class SettingsViewController: NSViewController, NSTextFieldDelegate, URLSessionD self.tabViewFuncSelector.setImage(getCoreTypeImage(named: "SidebarInternalDisk", isTemplate: true), forSegment: 0) self.tabViewFuncSelector.setImage(getCoreTypeImage(named: "SidebarMoviesFolder", isTemplate: true), forSegment: 1) self.tabViewFuncSelector.setImage(getCoreTypeImage(named: "SidebarMusicFolder", isTemplate: true), forSegment: 2) + self.tabViewFuncSelector.setImage(getCoreTypeImage(named: "SidebarDocumentsFolder", isTemplate: true), forSegment: 3) // sync self.tabViewFuncSelector.selectSegment(withTag: 0) self.tabViewFunc.selectTabViewItem(at: 0) @@ -577,6 +578,38 @@ class SettingsViewController: NSViewController, NSTextFieldDelegate, URLSessionD } } + @IBAction func generateConfig(_ sender: NSButton!) { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) { + if var conf = CloverConfig().generateCloverConfig() { + let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as! String + conf["GenTool"] = "Clover r\(AppSD.CloverRevision) by Clover.app v\(appVersion)" + let configName : String = (conf["ConfigName"] as? String ?? "config") + let dir = NSHomeDirectory().addPath("Desktop/Clover_config") + let fullPath = dir.addPath("\(configName).plist") + var isDir : ObjCBool = false + if fm.fileExists(atPath: dir, isDirectory: &isDir) { + if !isDir.boolValue { + try? fm.removeItem(atPath: dir) + } + } + + if !fm.fileExists(atPath: dir) { + try? fm.createDirectory(atPath: dir, + withIntermediateDirectories: false, + attributes: nil) + } + if NSDictionary(dictionary: conf).write(toFile: fullPath, + atomically: false) { + NSWorkspace.shared.openFile(dir) + } else { + NSSound.beep() + } + } else { + NSSound.beep() + } + } + } + @IBAction func installClover(_ sender: NSButton!) { let myPath = Bundle.main.bundlePath.lowercased() @@ -1193,7 +1226,7 @@ extension SettingsViewController: NSTabViewDelegate { } @IBAction func selectFuncTab(_ sender: NSSegmentedControl!) { - self.tabViewFunc.selectTabViewItem(at: sender.indexOfSelectedItem) + self.tabViewFunc.animator().selectTabViewItem(at: sender.indexOfSelectedItem) } func tabView(_ tabView: NSTabView, didSelect tabViewItem: NSTabViewItem?) { @@ -1221,7 +1254,7 @@ extension SettingsViewController: NSTabViewDelegate { } // MARK: Settings Window controller -class SettingsWindowController: NSWindowController, NSWindowDelegate { +final class SettingsWindowController: NSWindowController, NSWindowDelegate { var viewController : NSViewController? = nil override var contentViewController: NSViewController? { get { diff --git a/CloverApp/Clover/ThemeManager/ThemeManager.swift b/CloverApp/Clover/ThemeManager/ThemeManager.swift index 1cff1b249..868eead46 100644 --- a/CloverApp/Clover/ThemeManager/ThemeManager.swift +++ b/CloverApp/Clover/ThemeManager/ThemeManager.swift @@ -22,7 +22,7 @@ enum ThemeDownload { let kCloverThemeAttributeKey = "org.cloverTheme.sha" -class ThemeManager: NSObject, URLSessionDataDelegate { +final class ThemeManager: NSObject, URLSessionDataDelegate { var delegate : ThemeManagerVC? private var user : String private var repo : String @@ -53,10 +53,10 @@ class ThemeManager: NSObject, URLSessionDataDelegate { var themes = [String]() if self.getSha() != nil { let themesIndexPath = self.themeManagerIndexDir.addPath("Themes") - if let files = try? fm.contentsOfDirectory(atPath: themesIndexPath) { + if let files : [String] = try? fm.contentsOfDirectory(atPath: themesIndexPath) { for f in files { - let theme = f.deletingFileExtension - let ext = f.fileExtension + let theme : String = f.deletingFileExtension + let ext : String = f.fileExtension if ext == "plist" { themes.append(theme) } @@ -67,16 +67,16 @@ class ThemeManager: NSObject, URLSessionDataDelegate { } public func getThemes(completion: @escaping ([String]) -> ()) { - var themes = [String]() - let themesIndexPath = self.themeManagerIndexDir.addPath("Themes") + var themes : [String] = [String]() + let themesIndexPath : String = self.themeManagerIndexDir.addPath("Themes") self.getInfo(urlString: urlBaseStr) { (success) in do { - let files = try fm.contentsOfDirectory(atPath: themesIndexPath) + let files : [String] = try fm.contentsOfDirectory(atPath: themesIndexPath) for f in files { - let theme = f.deletingFileExtension - let ext = f.fileExtension + let theme : String = f.deletingFileExtension + let ext : String = f.fileExtension if ext == "plist" { themes.append(theme) } @@ -92,11 +92,11 @@ class ThemeManager: NSObject, URLSessionDataDelegate { /// Return the sha string only if the sha exist, and only if Themes directory exists. func getSha() -> String? { var sha : String? = nil - let themesPath = "\(self.themeManagerIndexDir)/Themes" - let shaPath = "\(self.themeManagerIndexDir)/sha" + let themesPath : String = "\(self.themeManagerIndexDir)/Themes" + let shaPath : String = "\(self.themeManagerIndexDir)/sha" if fm.fileExists(atPath: themesPath) && fm.fileExists(atPath: shaPath) { - if let data = try? Data(contentsOf: URL(fileURLWithPath: shaPath)) { + if let data : Data = try? Data(contentsOf: URL(fileURLWithPath: shaPath)) { sha = String(data: data, encoding: .utf8) if ((sha != nil) && (sha!.count < 40)) { sha = nil @@ -116,8 +116,8 @@ class ThemeManager: NSObject, URLSessionDataDelegate { private func downloadloadFile(at url: String, dst: String, completion: @escaping (Bool) -> ()) { - if let validURL = URL(string: self.normalize(url)) { - let upperDir = dst.deletingLastPath + if let validURL : URL = URL(string: self.normalize(url)) { + let upperDir : String = dst.deletingLastPath if !fm.fileExists(atPath: upperDir) { do { try fm.createDirectory(atPath: upperDir, @@ -129,7 +129,7 @@ class ThemeManager: NSObject, URLSessionDataDelegate { return } } - var request = URLRequest(url: validURL) + var request : URLRequest = URLRequest(url: validURL) request.httpMethod = "GET" request.setValue(userAgent, forHTTPHeaderField: "User-Agent") @@ -166,7 +166,7 @@ class ThemeManager: NSObject, URLSessionDataDelegate { private func getInfo(urlString: String, completion: @escaping (Bool) -> ()) { if let url = URL(string: self.normalize(urlString)) { - var request = URLRequest(url: url) + var request : URLRequest = URLRequest(url: url) request.httpMethod = "GET" request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type") request.setValue(userAgent, forHTTPHeaderField: "User-Agent") @@ -226,7 +226,7 @@ class ThemeManager: NSObject, URLSessionDataDelegate { return } - let shaPath = "\(self.themeManagerIndexDir)/\(sha)" + let shaPath : String = "\(self.themeManagerIndexDir)/\(sha)" do { if !fm.fileExists(atPath: shaPath) { @@ -258,9 +258,9 @@ class ThemeManager: NSObject, URLSessionDataDelegate { if let path = obj["path"] as? String { if !path.hasPrefix(".") && type == "blob" { // .gitignore, .DS_Store - let themeName = path.components(separatedBy: "/")[0] - let plistPath = "\(self.themeManagerIndexDir)/\(sha)/\(themeName).plist" - let theme = NSMutableArray(contentsOfFile: plistPath) ?? NSMutableArray() + let themeName : String = path.components(separatedBy: "/")[0] + let plistPath : String = "\(self.themeManagerIndexDir)/\(sha)/\(themeName).plist" + let theme : NSMutableArray = NSMutableArray(contentsOfFile: plistPath) ?? NSMutableArray() if !theme.contains(path) { theme.add(path) } @@ -328,8 +328,8 @@ class ThemeManager: NSObject, URLSessionDataDelegate { /// Return the path for a given theme, if the download succeded public func download(theme: String, down: ThemeDownload, completion: @escaping (String?) -> ()) { if let sha = getSha() { - let shaPath = self.basePath.addPath(sha) - let themeDest = (down == .complete) + let shaPath : String = self.basePath.addPath(sha) + let themeDest : String = (down == .complete) ? self.themeManagerIndexDir.addPath("Downloads").addPath(theme) : shaPath.addPath(theme) @@ -344,12 +344,12 @@ class ThemeManager: NSObject, URLSessionDataDelegate { } catch {} } - let plistPath = "\(themeManagerIndexDir)/Themes/\(theme).plist" + let plistPath : String = "\(themeManagerIndexDir)/Themes/\(theme).plist" - if let files = NSArray(contentsOfFile: plistPath) as? [String] { - let fc = files.count + if let files : [String] = NSArray(contentsOfFile: plistPath) as? [String] { + let fc : Int = files.count if fc > 0 { - var broken = false + var broken : Bool = false let dg = DispatchGroup() for i in 0..= 11) - -XCODEBUILD_OPTIONS=-project 'Clover.xcodeproj' CONFIGURATION_BUILD_DIR=$(CURDIR)/build DEPLOYMENT_LOCATION=NO -ifeq "$(XCODE_VERSION_GE_11)" "1" - XCODEBUILD_OPTIONS += ARCHS=x86_64 VALID_ARCHS=x86_64 ONLY_ACTIVE_ARCH=YES - XCODEBUILD_OPTIONS += -configuration 'Release' - XCODEBUILD_OPTIONS += -scheme 'Clover' -else - $(error Xcode 11 or greater and swift 5 or greater are requested) -endif - CloverApp: - @echo "Building Clover.app..." - - @/usr/bin/xcodebuild $(XCODEBUILD_OPTIONS) $(BUILD_ACTION) >/dev/null @echo [XCODE] $(PROGRAMS) + @package/build.sh + clean: - @/usr/bin/xcodebuild $(XCODEBUILD_OPTIONS) clean >/dev/null + @/usr/bin/xcodebuild -project 'Clover.xcodeproj' -scheme 'Clover' clean >/dev/null @rm -rf build *~ @echo [CLEAN] $(PROGRAMS) diff --git a/CloverApp/package/Resources/background.png b/CloverApp/package/Resources/background.png new file mode 100644 index 000000000..d2f4220d5 Binary files /dev/null and b/CloverApp/package/Resources/background.png differ diff --git a/CloverApp/package/Scripts/postinstall b/CloverApp/package/Scripts/postinstall new file mode 100755 index 000000000..fbecfc4b4 --- /dev/null +++ b/CloverApp/package/Scripts/postinstall @@ -0,0 +1,5 @@ +#!/bin/bash + +xattr -rc /Applications/Clover.app +sleep 3 +open /Applications/Clover.app diff --git a/CloverApp/package/Scripts/preinstall b/CloverApp/package/Scripts/preinstall new file mode 100755 index 000000000..3b2769e6a --- /dev/null +++ b/CloverApp/package/Scripts/preinstall @@ -0,0 +1,4 @@ +#!/bin/bash + +killall Clover || true +rm -rf /Applications/Clover.app diff --git a/CloverApp/package/build.sh b/CloverApp/package/build.sh new file mode 100755 index 000000000..0ec299071 --- /dev/null +++ b/CloverApp/package/build.sh @@ -0,0 +1,79 @@ +#!/bin/bash + +cd "$(dirname $([ -L $0 ] && readlink $0 || echo $0))" + +declare -r ROOT="$PWD" +declare -r CLOVERROOT=$(dirname $(dirname $ROOT)) +declare -r SYM_PATH="${CLOVERROOT}"/CloverPackage/sym +declare -r BUILD_PATH="${CLOVERROOT}"/CloverApp/build +declare -r APP_PATH="${BUILD_PATH}"/Clover.app + +xcodeVer() { + /usr/bin/xcodebuild -version 2> /dev/null | head -n 1 | awk '{ print $2 }' +} + +xcodeMajorVer() { + xcodeVer | awk -F '.' '{ print $1 }' +} + +xcodeCheck() { +local xmv=$(xcodeMajorVer) +if [[ $xmv -lt 11 ]]; then + echo "Clover.app require Xcode 11 or newer, nothing done." + exit 0 +fi +echo "using Xcode $(xcodeVer)" +} + +buildapp() { +echo "- Building Clover.app..." +cd "${CLOVERROOT}"/CloverApp +/usr/bin/xcodebuild -project 'Clover.xcodeproj' \ + CONFIGURATION_BUILD_DIR=${BUILD_PATH} \ + EPLOYMENT_LOCATION=NO \ + -scheme 'Clover' >/dev/null +} + +buildpkg() { +echo "- Building Clover.app package installer.." +cd "${ROOT}" +local INFO="${APP_PATH}"/Contents/Info.plist +local APPVERSION=$(defaults read "${INFO}" CFBundleShortVersionString) +local PKGNAME="Clover.app_v${APPVERSION}.pkg" + +if [[ -d "${CLOVERROOT}"/.git ]];then + PKGNAME="Clover.app_v${APPVERSION}_r$( git -C "${CLOVERROOT}" describe --tags --abbrev=0 ).pkg" +fi + +rm -f "${SYM_PATH}"/Clover.app*.pkg +rm -f "${SYM_PATH}"/Clover.app*.zip +rm -rf "${BUILD_PATH}"/package +mkdir -p "${BUILD_PATH}"/package/temp/Applications +cp -R "${APP_PATH}" "${BUILD_PATH}"/package/temp/Applications/ + +pkgbuild --root "${BUILD_PATH}"/package/temp \ + --version "${APPVERSION}" \ + --scripts "${ROOT}"/Scripts \ + --component-plist package.plist \ + --install-location / \ + "${BUILD_PATH}"/package/CloverApp.pkg + +awk -v n=5 -v s=" Clover.app v${APPVERSION}" 'NR == n {print s} {print}' distribution.xml | \ + sed -e "s/VERSION/${APPVERSION}/g" > "${BUILD_PATH}"/package/Distribution + +cd "${BUILD_PATH}"/package +productbuild --distribution ./Distribution \ + --resources "${ROOT}"/Resources \ + --package-path ./CloverApp.pkg \ + "${SYM_PATH}/${PKGNAME}" + +(cd "${SYM_PATH}" ; zip ${PKGNAME}.zip ${PKGNAME} ) + +rm -rf "${BUILD_PATH}"/package +rm -f "${SYM_PATH}"/Clover.app*.pkg +open "${SYM_PATH}" +} + +xcodeCheck +buildapp +buildpkg diff --git a/CloverApp/package/distribution.xml b/CloverApp/package/distribution.xml new file mode 100644 index 000000000..017baf19b --- /dev/null +++ b/CloverApp/package/distribution.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + CloverApp.pkg + diff --git a/CloverApp/package/package.plist b/CloverApp/package/package.plist new file mode 100644 index 000000000..75a2362fc --- /dev/null +++ b/CloverApp/package/package.plist @@ -0,0 +1,18 @@ + + + + + + BundleHasStrictIdentifier + + BundleIsRelocatable + + BundleIsVersionChecked + + BundleOverwriteAction + upgrade + RootRelativeBundlePath + Applications/Clover.app + + + diff --git a/CloverPackage/utils/Makefile b/CloverPackage/utils/Makefile index 9b1e9ece4..d98cde368 100644 --- a/CloverPackage/utils/Makefile +++ b/CloverPackage/utils/Makefile @@ -2,6 +2,6 @@ include $(CURDIR)/Make.rules #fdisk440 out #clover-genconfig temporary out -SUBDIRS = boot1-install partutil bdmesg espfinder +SUBDIRS = boot1-install partutil bdmesg clover-genconfig espfinder all: all-recursive diff --git a/CloverPackage/utils/clover-genconfig/clover-genconfig.c b/CloverPackage/utils/clover-genconfig/clover-genconfig.c index eafa9fe6e..51347d653 100644 --- a/CloverPackage/utils/clover-genconfig/clover-genconfig.c +++ b/CloverPackage/utils/clover-genconfig/clover-genconfig.c @@ -35,6 +35,10 @@ cc -o genconfig clover-genconfig.c gfxutil.c -framework CoreFoundation -framewor // EDK2 includes //#include +#ifndef CLOVERAPPLICATION +#define CLOVERAPPLICATION 1 +#endif + #define __DEBUG_LIB_H__ #define _STRUCT_X86_THREAD_STATE32 #define _STRUCT_X86_THREAD_STATE64 diff --git a/buildme b/buildme index a9ec43369..ae78819b8 100755 --- a/buildme +++ b/buildme @@ -205,22 +205,8 @@ if [[ "$SYSNAME" == Darwin ]]; then if [[ -f "${CLOVERROOT}"/CloverPackage/CloverV2/EFI/CLOVER/CLOVERX64.efi ]]; then cd "${CLOVERROOT}"/CloverApp echo "[BUILD APP]" - echo "(Require Xcode 11 or greater)" checkXCODE make - local infoPlist=${CLOVERROOT}"/CloverApp/build/Clover.app/Contents/Info.plist" - local caVer=$(defaults read "${infoPlist}" CFBundleShortVersionString) - if [[ -d "${CLOVERROOT}"/.git ]];then - local aname="Clover.app-v${caVer}-$( git -C "${CLOVERROOT}" describe --tags --abbrev=0 ).zip" - else - local aname="Clover.app-v${caVer}.zip" - fi - rm -f "${CLOVERROOT}"/CloverPackage/sym/Clover.app*.zip - mkdir -p "${CLOVERROOT}"/CloverPackage/sym - - cd "${CLOVERROOT}"/CloverApp/build - zip -qq -r -y "${CLOVERROOT}"/CloverPackage/sym/${aname} Clover.app/ - open "${CLOVERROOT}"/CloverPackage/sym else echo && echo "please, build Clover first!" sleep 3 diff --git a/rEFIt_UEFI/Platform/Platform.h b/rEFIt_UEFI/Platform/Platform.h index 5a4a606a4..aa6d438eb 100755 --- a/rEFIt_UEFI/Platform/Platform.h +++ b/rEFIt_UEFI/Platform/Platform.h @@ -95,7 +95,10 @@ extern "C" { #include "string.h" #include "boot.h" //#include "PiBootMode.h" +#ifndef CLOVERAPPLICATION #include "../refit/IO.h" +#endif + #include "device_inject.h" #ifdef __cplusplus