mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-11-12 09:54:36 +01:00
Clover.app v1.13
Fixed detection of legacy firmware for CloverDaemonNew. Detection of System Serial and OEM manufacturer informations. Startup sound settings in the interface. Installer inform with a sound and an alert window the installation result. Installer now produce the installation log. Installer is now thread safe. The UI is modified to make room forall the new functionalities.
This commit is contained in:
parent
e168d7c74f
commit
1d7e7327c0
@ -21,7 +21,9 @@
|
||||
9552D748236F33CA00C93377 /* CloverDaemonNew in Copy tools */ = {isa = PBXBuildFile; fileRef = 9552D745236F33A700C93377 /* CloverDaemonNew */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
9555AF26238EE53300108C33 /* InstallerOutline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9555AF25238EE53300108C33 /* InstallerOutline.swift */; };
|
||||
9555AF28238EFDAD00108C33 /* DriversCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9555AF27238EFDAD00108C33 /* DriversCollection.swift */; };
|
||||
955689DB23A2728000AD323C /* IO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 955689DA23A2728000AD323C /* IO.swift */; };
|
||||
9556CAF5238DF75600082671 /* InstallerOutline.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9556CAF3238DF75600082671 /* InstallerOutline.xib */; };
|
||||
9558518E23BA3486002CB3D8 /* Speaker.png in Resources */ = {isa = PBXBuildFile; fileRef = 9558518D23BA3485002CB3D8 /* Speaker.png */; };
|
||||
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 */; };
|
||||
@ -199,7 +201,9 @@
|
||||
9552D740236F33A700C93377 /* CloverDaemonNew.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = CloverDaemonNew.xcodeproj; path = CloverDaemonNew/CloverDaemonNew.xcodeproj; sourceTree = "<group>"; };
|
||||
9555AF25238EE53300108C33 /* InstallerOutline.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InstallerOutline.swift; sourceTree = "<group>"; };
|
||||
9555AF27238EFDAD00108C33 /* DriversCollection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DriversCollection.swift; sourceTree = "<group>"; };
|
||||
955689DA23A2728000AD323C /* IO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IO.swift; sourceTree = "<group>"; };
|
||||
9556CAF4238DF75600082671 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/InstallerOutline.xib; sourceTree = "<group>"; };
|
||||
9558518D23BA3485002CB3D8 /* Speaker.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Speaker.png; sourceTree = "<group>"; };
|
||||
955F7C6C238DCD160019D088 /* DiskArbitration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DiskArbitration.framework; path = System/Library/Frameworks/DiskArbitration.framework; sourceTree = SDKROOT; };
|
||||
95609069238C61E200ACD7F7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
||||
9560906C238C624200ACD7F7 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/MainMenu.strings; sourceTree = "<group>"; };
|
||||
@ -401,6 +405,14 @@
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9558518C23BA3472002CB3D8 /* images */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9558518D23BA3485002CB3D8 /* Speaker.png */,
|
||||
);
|
||||
path = images;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
95C51578236B21AE00E4A3A8 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -442,6 +454,7 @@
|
||||
95C51535236B1F7700E4A3A8 /* RunAtLogin.swift */,
|
||||
95E68ACB235B862F002B37A5 /* ViewController.swift */,
|
||||
95E68ADE235B86A1002B37A5 /* bdmesg.swift */,
|
||||
955689DA23A2728000AD323C /* IO.swift */,
|
||||
95E68ADD235B86A1002B37A5 /* Disks.swift */,
|
||||
95E68ADB235B86A1002B37A5 /* Extensions.swift */,
|
||||
954BBE98238196EE0032425F /* Locale.swift */,
|
||||
@ -455,6 +468,7 @@
|
||||
95609068238C61E200ACD7F7 /* MainMenu.xib */,
|
||||
95E68AD9235B8666002B37A5 /* Installer */,
|
||||
95E68ACD235B8632002B37A5 /* Assets.xcassets */,
|
||||
9558518C23BA3472002CB3D8 /* images */,
|
||||
954DECD423899F5F006A9876 /* Bootmanager.png */,
|
||||
95E68AD2235B8632002B37A5 /* Info.plist */,
|
||||
95E68AD3235B8632002B37A5 /* Clover.entitlements */,
|
||||
@ -517,7 +531,7 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 1120;
|
||||
LastUpgradeCheck = 1120;
|
||||
LastUpgradeCheck = 1130;
|
||||
ORGANIZATIONNAME = CloverHackyColor;
|
||||
TargetAttributes = {
|
||||
95E68AC5235B862F002B37A5 = {
|
||||
@ -658,6 +672,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9556CAF5238DF75600082671 /* InstallerOutline.xib in Resources */,
|
||||
9558518E23BA3486002CB3D8 /* Speaker.png in Resources */,
|
||||
956090B7238C890600ACD7F7 /* Installer.xib in Resources */,
|
||||
954DECD523899F5F006A9876 /* Bootmanager.png in Resources */,
|
||||
95E68ACE235B8632002B37A5 /* Assets.xcassets in Resources */,
|
||||
@ -730,6 +745,7 @@
|
||||
95C515222369BAF500E4A3A8 /* NVRAM.swift in Sources */,
|
||||
95C51536236B1F7700E4A3A8 /* RunAtLogin.swift in Sources */,
|
||||
95E68AE0235B86A1002B37A5 /* Extensions.swift in Sources */,
|
||||
955689DB23A2728000AD323C /* IO.swift in Sources */,
|
||||
9555AF26238EE53300108C33 /* InstallerOutline.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@ -970,6 +986,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IBC_WARNINGS = NO;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
@ -1026,6 +1043,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IBC_WARNINGS = NO;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
@ -1039,18 +1057,19 @@
|
||||
95E68AD7235B8632002B37A5 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Clover/Clover.entitlements;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1.12;
|
||||
CURRENT_PROJECT_VERSION = 1.13;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Clover/Frameworks",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = "$(SRCROOT)/Frameworks/ObjectiveGit.framework/Headers/";
|
||||
IBC_WARNINGS = YES;
|
||||
INFOPLIST_FILE = Clover/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@ -1061,7 +1080,7 @@
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Clover/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.12;
|
||||
MARKETING_VERSION = 1.13;
|
||||
OTHER_LDFLAGS = "";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.slice.Clover;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@ -1074,18 +1093,19 @@
|
||||
95E68AD8235B8632002B37A5 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Clover/Clover.entitlements;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1.12;
|
||||
CURRENT_PROJECT_VERSION = 1.13;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Clover/Frameworks",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = "$(SRCROOT)/Frameworks/ObjectiveGit.framework/Headers/";
|
||||
INFOPLIST_FILE = Clover/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@ -1095,7 +1115,7 @@
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Clover/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.12;
|
||||
MARKETING_VERSION = 1.13;
|
||||
OTHER_LDFLAGS = "";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.slice.Clover;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PreviewsEnabled</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
@ -95,6 +95,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSPopoverDelegate {
|
||||
selector: #selector(self.reFreshDisksList),
|
||||
name: Notification.Name("DiskDisappeared"),
|
||||
object: nil)
|
||||
|
||||
NSWorkspace.shared.notificationCenter.addObserver(self,
|
||||
selector: #selector(self.reFreshDisksList),
|
||||
name: NSWorkspace.didMountNotification,
|
||||
@ -139,17 +140,22 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSPopoverDelegate {
|
||||
self.popover?.delegate = self
|
||||
}
|
||||
|
||||
if #available(OSX 10.10, *) {
|
||||
if let button = sender as? NSStatusBarButton {
|
||||
self.popover?.show(relativeTo: button.bounds, of: button, preferredEdge: NSRectEdge.maxY)
|
||||
}
|
||||
} else {
|
||||
if let v = sender as? NSView {
|
||||
self.popover?.show(relativeTo: v.bounds, of: v, preferredEdge: NSRectEdge.maxY)
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
(self.popover?.contentViewController as? SettingsViewController)?.setUpInfo()
|
||||
}
|
||||
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
DispatchQueue.main.async {
|
||||
if #available(OSX 10.10, *) {
|
||||
if let button = sender as? NSStatusBarButton {
|
||||
self.popover?.show(relativeTo: button.bounds, of: button, preferredEdge: NSRectEdge.maxY)
|
||||
}
|
||||
} else {
|
||||
if let v = sender as? NSView {
|
||||
self.popover?.show(relativeTo: v.bounds, of: v, preferredEdge: NSRectEdge.maxY)
|
||||
}
|
||||
}
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
}
|
||||
}
|
||||
|
||||
func popoverShouldDetach(_ popover: NSPopover) -> Bool {
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15504" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15702" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15504"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15702"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@ -12,34 +12,16 @@
|
||||
<window title="Clover" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" titlebarAppearsTransparent="YES" id="QvC-M9-y7g">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="196" y="240" width="342" height="632"/>
|
||||
<rect key="contentRect" x="196" y="240" width="342" height="651"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1600" height="877"/>
|
||||
<value key="minSize" type="size" width="342" height="614"/>
|
||||
<value key="maxSize" type="size" width="342" height="614"/>
|
||||
<value key="minSize" type="size" width="342" height="651"/>
|
||||
<value key="maxSize" type="size" width="342" height="651"/>
|
||||
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="342" height="632"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="342" height="651"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="f5t-Ia-85K">
|
||||
<rect key="frame" x="21" y="603" width="304" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Current revision" id="Re2-vf-XQ6">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="G6z-Xp-lnm">
|
||||
<rect key="frame" x="21" y="580" width="303" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Boot Device:" id="omZ-xs-Wjn">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7kg-2N-6IM">
|
||||
<rect key="frame" x="165" y="134" width="164" height="32"/>
|
||||
<rect key="frame" x="165" y="149" width="164" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Check now" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="UyZ-5I-L9X">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
@ -49,26 +31,8 @@
|
||||
<action selector="checkNow:" target="tSJ-3G-dnL" id="UY0-EP-xVG"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" placeholderIntrinsicWidth="300" placeholderIntrinsicHeight="16" translatesAutoresizingMaskIntoConstraints="NO" id="5CM-EI-thb">
|
||||
<rect key="frame" x="21" y="541" width="304" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="config path:" id="iii-3P-wo8">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="RIu-Gh-Uqo">
|
||||
<rect key="frame" x="17" y="396" width="308" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="NVRAM/bdmesg" id="8j2-3s-fjm">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Xbi-A5-m33">
|
||||
<rect key="frame" x="14" y="191" width="311" height="16"/>
|
||||
<rect key="frame" x="14" y="206" width="311" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Update" id="58l-pb-zEc">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -77,7 +41,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="g5h-bF-3le">
|
||||
<rect key="frame" x="14" y="43" width="311" height="18"/>
|
||||
<rect key="frame" x="14" y="32" width="311" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Run at login" bezelStyle="regularSquare" imagePosition="left" inset="2" id="J8R-ej-fRl">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
@ -87,66 +51,16 @@
|
||||
<action selector="runAtLogin:" target="tSJ-3G-dnL" id="Kfi-uU-9Tq"/>
|
||||
</connections>
|
||||
</button>
|
||||
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="vOr-f4-3wc">
|
||||
<rect key="frame" x="19" y="417" width="304" height="5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
</box>
|
||||
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="NvE-a0-QjT">
|
||||
<rect key="frame" x="16" y="245" width="307" height="5"/>
|
||||
<rect key="frame" x="16" y="260" width="307" height="5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
</box>
|
||||
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="E8G-Gr-UlY">
|
||||
<rect key="frame" x="16" y="65" width="307" height="5"/>
|
||||
<rect key="frame" x="16" y="54" width="307" height="5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
</box>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3iW-Mp-ZEr">
|
||||
<rect key="frame" x="17" y="372" width="102" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Theme:" id="7yo-8b-ZHc">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jR0-Lr-IYX">
|
||||
<rect key="frame" x="18" y="346" width="101" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Sound:" id="UHz-ZM-JLi">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0Zs-Un-dNa" customClass="FWTextField" customModule="Clover" customModuleProvider="target">
|
||||
<rect key="frame" x="125" y="369" width="198" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="DVf-rV-Hrc">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="fixedWidth">
|
||||
<real key="value" value="199"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="WMZ-zj-8k6" customClass="FWTextField" customModule="Clover" customModuleProvider="target">
|
||||
<rect key="frame" x="125" y="343" width="198" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="o0i-cN-QJu">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="fixedWidth">
|
||||
<real key="value" value="199"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1qf-uO-CvA" customClass="FWPopUpButton" customModule="Clover" customModuleProvider="target">
|
||||
<rect key="frame" x="14" y="138" width="155" height="25"/>
|
||||
<rect key="frame" x="14" y="153" width="155" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="lkK-DQ-QK6">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
@ -163,7 +77,7 @@
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="nx7-BI-FIh">
|
||||
<rect key="frame" x="14" y="171" width="311" height="14"/>
|
||||
<rect key="frame" x="14" y="186" width="311" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" title="Check update:" id="fMZ-r2-dlm">
|
||||
<font key="font" metaFont="menu" size="11"/>
|
||||
@ -172,7 +86,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="HPk-Vu-vf0">
|
||||
<rect key="frame" x="14" y="76" width="311" height="14"/>
|
||||
<rect key="frame" x="14" y="91" width="311" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" title="Label" id="v3d-HG-AeW">
|
||||
<font key="font" metaFont="menu" size="11"/>
|
||||
@ -181,48 +95,11 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="bsQ-GS-duU">
|
||||
<rect key="frame" x="16" y="485" width="307" height="5"/>
|
||||
<rect key="frame" x="70" y="497" width="213" height="5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
</box>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="mcY-kx-lap" customClass="FWPopUpButton" customModule="Clover" customModuleProvider="target">
|
||||
<rect key="frame" x="135" y="457" width="191" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="Hzi-CJ-xVH">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<menu key="menu" id="Vb3-8W-CMc"/>
|
||||
</popUpButtonCell>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="fixedWidth">
|
||||
<real key="value" value="189"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<connections>
|
||||
<action selector="mountESP:" target="tSJ-3G-dnL" id="Wd0-O9-Tfa"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Zc5-Dl-jIh">
|
||||
<rect key="frame" x="197" y="420" width="131" height="31"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="umount" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="bhl-e0-nVD">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="umount:" target="tSJ-3G-dnL" id="KqE-Db-Uf1"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="M1w-uF-TFN">
|
||||
<rect key="frame" x="17" y="464" width="114" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Mount" id="s5K-bS-gZa">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zDK-XE-o2Z">
|
||||
<rect key="frame" x="17" y="491" width="312" height="32"/>
|
||||
<rect key="frame" x="10" y="59" width="318" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="E23-ao-JFs">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
@ -233,7 +110,7 @@
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2NR-5W-4rg">
|
||||
<rect key="frame" x="10" y="106" width="319" height="32"/>
|
||||
<rect key="frame" x="10" y="121" width="319" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Button" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="EJg-qm-L18">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
@ -243,21 +120,12 @@
|
||||
<action selector="updateClover:" target="tSJ-3G-dnL" id="kpg-zk-tVv"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Sj4-Yw-RpL">
|
||||
<rect key="frame" x="17" y="452" width="38" height="11"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" controlSize="mini" lineBreakMode="clipping" title="(ESP)" id="TTH-hz-cX2">
|
||||
<font key="font" metaFont="label" size="9"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="2pM-fw-w5V">
|
||||
<rect key="frame" x="16" y="213" width="307" height="5"/>
|
||||
<rect key="frame" x="16" y="228" width="307" height="5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
</box>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jbm-8q-WaH">
|
||||
<rect key="frame" x="17" y="224" width="109" height="17"/>
|
||||
<rect key="frame" x="17" y="239" width="109" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="CloverDaemon" id="gez-2n-CkL">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
@ -266,7 +134,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="MWn-i4-CYn">
|
||||
<rect key="frame" x="136" y="215" width="114" height="32"/>
|
||||
<rect key="frame" x="136" y="230" width="114" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Uninstall" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="w6z-A1-CZt">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
@ -277,11 +145,11 @@
|
||||
</connections>
|
||||
</button>
|
||||
<progressIndicator wantsLayer="YES" fixedFrame="YES" maxValue="100" doubleValue="50" style="bar" translatesAutoresizingMaskIntoConstraints="NO" id="DtR-XE-DfU">
|
||||
<rect key="frame" x="16" y="81" width="307" height="35"/>
|
||||
<rect key="frame" x="16" y="96" width="307" height="35"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
</progressIndicator>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vgX-bN-KyC">
|
||||
<rect key="frame" x="244" y="215" width="85" height="32"/>
|
||||
<rect key="frame" x="244" y="230" width="85" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Install" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="omz-9K-nb4">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
@ -292,7 +160,7 @@
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wDl-KZ-OP0">
|
||||
<rect key="frame" x="21" y="292" width="304" height="14"/>
|
||||
<rect key="frame" x="21" y="307" width="304" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="*Disable Sleep Proxy Client" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="kZm-NL-hOA">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
@ -303,7 +171,7 @@
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wxL-7U-AGQ">
|
||||
<rect key="frame" x="45" y="250" width="280" height="11"/>
|
||||
<rect key="frame" x="21" y="265" width="304" height="11"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" controlSize="mini" lineBreakMode="clipping" title="*Require CloverDaemon" id="yQ9-cU-wtc">
|
||||
<font key="font" metaFont="label" size="9"/>
|
||||
@ -312,7 +180,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="y9x-U8-ayg">
|
||||
<rect key="frame" x="21" y="314" width="304" height="16"/>
|
||||
<rect key="frame" x="21" y="329" width="304" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="*Make filesystem read-write" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="v3W-6S-CK6">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
@ -323,7 +191,7 @@
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8Je-uC-CnS">
|
||||
<rect key="frame" x="15" y="263" width="166" height="27"/>
|
||||
<rect key="frame" x="15" y="278" width="166" height="27"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Read daemon log" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="UZY-ie-enb">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
@ -333,33 +201,8 @@
|
||||
<action selector="readDaemonLog:" target="tSJ-3G-dnL" id="Mo0-RL-dK0"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField autoresizesSubviews="NO" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="K34-kh-yUP" customClass="FWTextField" customModule="Clover" customModuleProvider="target">
|
||||
<rect key="frame" x="33" y="522" width="292" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="truncatingHead" selectable="YES" allowsUndo="NO" focusRingType="none" title="N/A" id="EX6-6q-G8U">
|
||||
<font key="font" metaFont="menu" size="11"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="fixedWidth">
|
||||
<real key="value" value="304"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="l6m-qm-d70">
|
||||
<rect key="frame" x="17" y="428" width="186" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="*auto mount" bezelStyle="regularSquare" imagePosition="left" inset="2" id="tdl-nw-YFd">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="autoMount:" target="tSJ-3G-dnL" id="FNN-jm-HUm"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="eYq-qu-d4Z">
|
||||
<rect key="frame" x="179" y="263" width="149" height="27"/>
|
||||
<rect key="frame" x="179" y="278" width="149" height="27"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Read bdmesg" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="bhg-iF-USh">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
@ -370,7 +213,7 @@
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="V27-tg-6O6">
|
||||
<rect key="frame" x="61" y="11" width="224" height="15"/>
|
||||
<rect key="frame" x="61" y="9" width="224" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" alignment="center" title="Label" id="goU-fD-Ng6">
|
||||
<font key="font" metaFont="menu" size="11"/>
|
||||
@ -379,7 +222,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="f2Z-bB-hZf">
|
||||
<rect key="frame" x="16" y="9" width="18" height="18"/>
|
||||
<rect key="frame" x="16" y="7" width="18" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="bevel" bezelStyle="rounded" image="NSInfo" imagePosition="only" alignment="center" focusRingType="none" imageScaling="proportionallyDown" inset="2" id="8hx-sN-OfR">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
@ -390,7 +233,7 @@
|
||||
</connections>
|
||||
</button>
|
||||
<button focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zcm-bV-rzR">
|
||||
<rect key="frame" x="304" y="9" width="18" height="18"/>
|
||||
<rect key="frame" x="304" y="7" width="18" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="bevel" bezelStyle="rounded" image="NSStopProgressFreestandingTemplate" imagePosition="only" alignment="center" focusRingType="none" imageScaling="proportionallyDown" inset="2" id="2fO-JJ-w1L">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
@ -400,21 +243,450 @@
|
||||
<action selector="closeApp:" target="tSJ-3G-dnL" id="Hjx-e6-JXH"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tPD-gh-zbP">
|
||||
<rect key="frame" x="33" y="561" width="291" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" selectable="YES" allowsUndo="NO" title="N/A" id="EFW-lW-i6c">
|
||||
<tabView fixedFrame="YES" type="noTabsNoBorder" translatesAutoresizingMaskIntoConstraints="NO" id="PGs-4a-XRc" customClass="LITabView" customModule="Clover" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="522" width="342" height="120"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<tabViewItems>
|
||||
<tabViewItem label="Tab" identifier="" id="BAk-3x-mLp">
|
||||
<view key="view" id="ENG-5U-eLE">
|
||||
<rect key="frame" x="0.0" y="0.0" width="342" height="120"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="f5t-Ia-85K">
|
||||
<rect key="frame" x="18" y="101" width="306" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Current revision" id="Re2-vf-XQ6">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="G6z-Xp-lnm">
|
||||
<rect key="frame" x="18" y="78" width="306" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Boot Device:" id="omZ-xs-Wjn">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" placeholderIntrinsicWidth="300" placeholderIntrinsicHeight="16" translatesAutoresizingMaskIntoConstraints="NO" id="5CM-EI-thb">
|
||||
<rect key="frame" x="18" y="39" width="306" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="config path:" id="iii-3P-wo8">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField autoresizesSubviews="NO" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="K34-kh-yUP" customClass="FWTextField" customModule="Clover" customModuleProvider="target">
|
||||
<rect key="frame" x="30" y="20" width="294" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="truncatingHead" selectable="YES" allowsUndo="NO" focusRingType="none" title="N/A" id="EX6-6q-G8U">
|
||||
<font key="font" metaFont="menu" size="11"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="fixedWidth">
|
||||
<real key="value" value="304"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" textCompletion="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tPD-gh-zbP">
|
||||
<rect key="frame" x="30" y="56" width="294" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" selectable="YES" allowsUndo="NO" title="N/A" id="EFW-lW-i6c">
|
||||
<font key="font" metaFont="menu" size="11"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
</view>
|
||||
</tabViewItem>
|
||||
<tabViewItem label="View" identifier="" id="0yV-f2-RVT">
|
||||
<view key="view" ambiguous="YES" id="P12-rN-3e4">
|
||||
<rect key="frame" x="0.0" y="0.0" width="342" height="120"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8Ws-KM-1ul">
|
||||
<rect key="frame" x="18" y="101" width="306" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="System Serial Number:" id="GfB-HS-3EW">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0u3-c1-rfb">
|
||||
<rect key="frame" x="30" y="79" width="294" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" selectable="YES" focusRingType="none" title="N/A" id="PZZ-nm-ERe">
|
||||
<font key="font" metaFont="menu" size="11"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="OFF-nz-jvo">
|
||||
<rect key="frame" x="18" y="57" width="306" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Model:" id="3Sk-aU-UkS">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SQN-cD-fjL">
|
||||
<rect key="frame" x="30" y="39" width="294" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" selectable="YES" focusRingType="none" title="N/A" id="oPZ-3Y-89o">
|
||||
<font key="font" metaFont="menu" size="11"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8Ns-5X-cAP">
|
||||
<rect key="frame" x="18" y="20" width="306" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="board-id:" id="r4l-Ce-RMS">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="MXF-sZ-EBb">
|
||||
<rect key="frame" x="30" y="0.0" width="294" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" selectable="YES" focusRingType="none" title="N/A" id="okN-IH-2al">
|
||||
<font key="font" metaFont="menu" size="11"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
</view>
|
||||
</tabViewItem>
|
||||
<tabViewItem label="Item 2" identifier="" id="BEi-Mi-0vu">
|
||||
<view key="view" id="YPe-Eg-Yeo">
|
||||
<rect key="frame" x="0.0" y="0.0" width="342" height="120"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="QsD-p5-3ia">
|
||||
<rect key="frame" x="18" y="101" width="306" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="OEM Vendor:" id="uAa-hl-4j0">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="84n-SC-fET">
|
||||
<rect key="frame" x="30" y="79" width="294" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" selectable="YES" focusRingType="none" title="N/A" id="HZg-rD-gZv">
|
||||
<font key="font" metaFont="menu" size="11"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="kIt-ye-HGa">
|
||||
<rect key="frame" x="18" y="57" width="306" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="OEM Product:" id="AQC-bY-XBg">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="kfr-wj-0XK">
|
||||
<rect key="frame" x="18" y="20" width="306" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="OEM Board:" id="eKw-DA-nv3">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Aad-0P-4R6">
|
||||
<rect key="frame" x="30" y="39" width="294" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" selectable="YES" focusRingType="none" title="Label" id="J7N-7a-sdN">
|
||||
<font key="font" metaFont="menu" size="11"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="GcV-id-YTZ">
|
||||
<rect key="frame" x="30" y="0.0" width="294" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" selectable="YES" focusRingType="none" title="Label" id="0dT-GZ-Ytt">
|
||||
<font key="font" metaFont="menu" size="11"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
</view>
|
||||
</tabViewItem>
|
||||
<tabViewItem label="Item 3" identifier="" id="Jgk-Bx-tyS">
|
||||
<view key="view" id="4NV-GX-O1K">
|
||||
<rect key="frame" x="0.0" y="0.0" width="342" height="120"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SjP-er-6Hp">
|
||||
<rect key="frame" x="18" y="101" width="306" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="NVRAM:" id="THE-We-1UH">
|
||||
<font key="font" usesAppearanceFont="YES"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="00r-9S-unY">
|
||||
<rect key="frame" x="18" y="64" width="306" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Boot type:" id="pWw-6m-fZo">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="88K-Sj-rjo">
|
||||
<rect key="frame" x="18" y="27" width="306" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="firmware:" id="kyW-hT-U5H">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
</view>
|
||||
</tabViewItem>
|
||||
</tabViewItems>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="tSJ-3G-dnL" id="8es-BM-oQc"/>
|
||||
</connections>
|
||||
</tabView>
|
||||
<segmentedControl verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Nu3-4z-pbg">
|
||||
<rect key="frame" x="256" y="497" width="69" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<segmentedCell key="cell" controlSize="small" borderStyle="border" alignment="left" style="rounded" trackingMode="momentary" id="3O5-bI-89P">
|
||||
<font key="font" metaFont="menu" size="11"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<segments>
|
||||
<segment image="NSLeftFacingTriangleTemplate" width="31"/>
|
||||
<segment image="NSRightFacingTriangleTemplate" width="31" tag="1"/>
|
||||
</segments>
|
||||
</segmentedCell>
|
||||
<connections>
|
||||
<action selector="selectTabInfo:" target="tSJ-3G-dnL" id="3Xr-u6-Maa"/>
|
||||
</connections>
|
||||
</segmentedControl>
|
||||
<tabView fixedFrame="YES" type="noTabsNoBorder" translatesAutoresizingMaskIntoConstraints="NO" id="vwp-hc-6yE" customClass="LITabView" customModule="Clover" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="358" width="342" height="113"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<tabViewItems>
|
||||
<tabViewItem identifier="Mount" id="F4n-I1-4Gq">
|
||||
<view key="view" ambiguous="YES" id="E05-QZ-1bf">
|
||||
<rect key="frame" x="0.0" y="0.0" width="342" height="113"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="mcY-kx-lap" customClass="FWPopUpButton" customModule="Clover" customModuleProvider="target">
|
||||
<rect key="frame" x="155" y="68" width="170" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="Hzi-CJ-xVH">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<menu key="menu" id="Vb3-8W-CMc"/>
|
||||
</popUpButtonCell>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="fixedWidth">
|
||||
<real key="value" value="189"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<connections>
|
||||
<action selector="mountESP:" target="tSJ-3G-dnL" id="Wd0-O9-Tfa"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="M1w-uF-TFN">
|
||||
<rect key="frame" x="21" y="74" width="122" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Mount" id="s5K-bS-gZa">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Sj4-Yw-RpL">
|
||||
<rect key="frame" x="21" y="58" width="52" height="11"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" controlSize="mini" lineBreakMode="clipping" title="(ESP)" id="TTH-hz-cX2">
|
||||
<font key="font" metaFont="label" size="9"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="l6m-qm-d70">
|
||||
<rect key="frame" x="21" y="9" width="304" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="*auto mount" bezelStyle="regularSquare" imagePosition="left" inset="2" id="tdl-nw-YFd">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="autoMount:" target="tSJ-3G-dnL" id="FNN-jm-HUm"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Zc5-Dl-jIh">
|
||||
<rect key="frame" x="185" y="34" width="143" height="31"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="umount" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="bhl-e0-nVD">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="umount:" target="tSJ-3G-dnL" id="KqE-Db-Uf1"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</view>
|
||||
</tabViewItem>
|
||||
<tabViewItem identifier="Theme" id="Th2-UC-6Hh">
|
||||
<view key="view" id="hLu-g7-21T">
|
||||
<rect key="frame" x="0.0" y="0.0" width="342" height="113"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3iW-Mp-ZEr">
|
||||
<rect key="frame" x="21" y="74" width="303" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Theme:" id="7yo-8b-ZHc">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0Zs-Un-dNa" customClass="FWTextField" customModule="Clover" customModuleProvider="target">
|
||||
<rect key="frame" x="20" y="46" width="199" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="DVf-rV-Hrc">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="fixedWidth">
|
||||
<real key="value" value="199"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</textField>
|
||||
</subviews>
|
||||
</view>
|
||||
</tabViewItem>
|
||||
<tabViewItem identifier="Sound" id="T2L-eV-Vwg">
|
||||
<view key="view" id="0ws-um-xJI">
|
||||
<rect key="frame" x="0.0" y="0.0" width="342" height="113"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="TUv-Cs-cf7">
|
||||
<rect key="frame" x="18" y="53" width="307" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="hlk-UE-ZPw" id="7ZL-JE-fT7">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<menu key="menu" id="zSa-aR-ghV">
|
||||
<items>
|
||||
<menuItem title="Item 1" state="on" id="hlk-UE-ZPw"/>
|
||||
<menuItem title="Item 2" id="Z3z-TW-nfP"/>
|
||||
<menuItem title="Item 3" id="Hcf-6X-UU6"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="soundDeviceSelected:" target="tSJ-3G-dnL" id="psL-M9-FnG"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<slider verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Qos-VY-rkt" customClass="SoundSlider" customModule="Clover" customModuleProvider="target">
|
||||
<rect key="frame" x="91" y="2" width="231" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<sliderCell key="cell" controlSize="mini" state="on" alignment="left" maxValue="100" doubleValue="49.494949494949495" tickMarkPosition="above" numberOfTickMarks="100" allowsTickMarkValuesOnly="YES" sliderType="linear" id="ttF-2D-IVS"/>
|
||||
<connections>
|
||||
<action selector="soundSliderDidMove:" target="tSJ-3G-dnL" id="zC1-Ai-Zcr"/>
|
||||
</connections>
|
||||
</slider>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Ok2-So-CvK">
|
||||
<rect key="frame" x="15" y="91" width="292" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" alignment="right" title="Startup Sound" id="Vif-FP-OaO">
|
||||
<font key="font" metaFont="menu" size="11"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zab-LD-DM9">
|
||||
<rect key="frame" x="20" y="2" width="15" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="Speaker" id="mBv-AG-gpg"/>
|
||||
</imageView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DSs-NW-pIa">
|
||||
<rect key="frame" x="42" y="4" width="37" height="11"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" controlSize="mini" lineBreakMode="clipping" title="0%" id="vRT-SW-j4L">
|
||||
<font key="font" metaFont="label" size="9"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="XgO-ZG-KMv">
|
||||
<rect key="frame" x="18" y="25" width="306" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" title="Volume level:" id="ebr-lB-pTD">
|
||||
<font key="font" metaFont="menu" size="11"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="D50-Ay-tcj">
|
||||
<rect key="frame" x="18" y="79" width="292" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" title="Device:" id="sIi-by-bNC">
|
||||
<font key="font" metaFont="menu" size="11"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
</view>
|
||||
</tabViewItem>
|
||||
</tabViewItems>
|
||||
</tabView>
|
||||
<segmentedControl verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4ox-0p-Q9L">
|
||||
<rect key="frame" x="18" y="477" width="104" height="24"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<segmentedCell key="cell" borderStyle="border" alignment="left" style="rounded" trackingMode="selectOne" id="dvq-Ib-bsz">
|
||||
<font key="font" metaFont="system"/>
|
||||
<segments>
|
||||
<segment width="32"/>
|
||||
<segment width="32" selected="YES" tag="1"/>
|
||||
<segment width="32"/>
|
||||
</segments>
|
||||
</segmentedCell>
|
||||
<connections>
|
||||
<action selector="selectFuncTab:" target="tSJ-3G-dnL" id="J4r-xS-rRa"/>
|
||||
</connections>
|
||||
</segmentedControl>
|
||||
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="pyx-t7-n7o">
|
||||
<rect key="frame" x="19" y="347" width="304" height="5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
</box>
|
||||
</subviews>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="Fye-KY-AQk" id="aX8-mH-8mg"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="43" y="406"/>
|
||||
<point key="canvasLocation" x="43" y="415.5"/>
|
||||
</window>
|
||||
<customObject id="Fye-KY-AQk" customClass="SettingsWindowController" customModule="Clover" customModuleProvider="target">
|
||||
<connections>
|
||||
@ -425,21 +697,35 @@
|
||||
<connections>
|
||||
<outlet property="appVersionField" destination="V27-tg-6O6" id="pxR-3a-E0x"/>
|
||||
<outlet property="autoMountButton" destination="l6m-qm-d70" id="0qW-yE-Mqu"/>
|
||||
<outlet property="boardIdField" destination="MXF-sZ-EBb" id="vbJ-VJ-QcR"/>
|
||||
<outlet property="bootDeviceField" destination="tPD-gh-zbP" id="vYU-oa-H3q"/>
|
||||
<outlet property="bootTypeField" destination="00r-9S-unY" id="ukc-fU-Jdl"/>
|
||||
<outlet property="checkNowButton" destination="7kg-2N-6IM" id="cuk-26-Lah"/>
|
||||
<outlet property="closeButton" destination="zcm-bV-rzR" id="wwB-lu-oT7"/>
|
||||
<outlet property="configPathField" destination="K34-kh-yUP" id="zkK-f3-0uj"/>
|
||||
<outlet property="currentRevField" destination="f5t-Ia-85K" id="D7C-Ny-Ehi"/>
|
||||
<outlet property="disbaleSleepProxyButton" destination="wDl-KZ-OP0" id="neq-3a-Zq9"/>
|
||||
<outlet property="disksPopUp" destination="mcY-kx-lap" id="Ie2-4t-td5"/>
|
||||
<outlet property="firmwareVendorfield" destination="88K-Sj-rjo" id="aQy-Dd-8G5"/>
|
||||
<outlet property="infoButton" destination="f2Z-bB-hZf" id="pBL-T9-zoS"/>
|
||||
<outlet property="installCloverButton" destination="zDK-XE-o2Z" id="cJu-LK-DPo"/>
|
||||
<outlet property="installDaemonButton" destination="vgX-bN-KyC" id="dPG-M5-L7J"/>
|
||||
<outlet property="lastUpdateCheckField" destination="HPk-Vu-vf0" id="oFD-7Z-UMC"/>
|
||||
<outlet property="makeRootRWButton" destination="y9x-U8-ayg" id="MWS-t0-efx"/>
|
||||
<outlet property="modelField" destination="SQN-cD-fjL" id="HaD-SS-j8b"/>
|
||||
<outlet property="nativeNVRAMField" destination="SjP-er-6Hp" id="7W6-DR-kpm"/>
|
||||
<outlet property="oemBoardIdField" destination="GcV-id-YTZ" id="yvt-rO-i17"/>
|
||||
<outlet property="oemProductField" destination="Aad-0P-4R6" id="O85-Y0-ZXY"/>
|
||||
<outlet property="oemVendorField" destination="84n-SC-fET" id="UbL-NZ-faa"/>
|
||||
<outlet property="progressBar" destination="DtR-XE-DfU" id="7sf-c8-y5u"/>
|
||||
<outlet property="runAtLoginButton" destination="g5h-bF-3le" id="tXL-6T-4Mj"/>
|
||||
<outlet property="soundField" destination="WMZ-zj-8k6" id="fJF-TL-2W6"/>
|
||||
<outlet property="snField" destination="0u3-c1-rfb" id="TUb-GS-mTb"/>
|
||||
<outlet property="soundDevicePopUp" destination="TUv-Cs-cf7" id="k70-dz-twN"/>
|
||||
<outlet property="soundVolumeField" destination="DSs-NW-pIa" id="JED-7V-T4Y"/>
|
||||
<outlet property="soundVolumeSlider" destination="Qos-VY-rkt" id="RQv-Be-e3q"/>
|
||||
<outlet property="tabViewFunc" destination="vwp-hc-6yE" id="gQE-Kf-hSJ"/>
|
||||
<outlet property="tabViewFuncSelector" destination="4ox-0p-Q9L" id="Tes-Eu-6Tt"/>
|
||||
<outlet property="tabViewInfo" destination="PGs-4a-XRc" id="ghG-r0-tYY"/>
|
||||
<outlet property="themeField" destination="0Zs-Un-dNa" id="gHl-ys-oZv"/>
|
||||
<outlet property="timeIntervalPopUp" destination="1qf-uO-CvA" id="774-SY-GdB"/>
|
||||
<outlet property="unInstallDaemonButton" destination="MWn-i4-CYn" id="r2Y-WW-wd9"/>
|
||||
@ -451,6 +737,9 @@
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="NSInfo" width="32" height="32"/>
|
||||
<image name="NSLeftFacingTriangleTemplate" width="9" height="12"/>
|
||||
<image name="NSRightFacingTriangleTemplate" width="9" height="12"/>
|
||||
<image name="NSStopProgressFreestandingTemplate" width="14" height="14"/>
|
||||
<image name="Speaker" width="32" height="32"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
161
CloverApp/Clover/IO.swift
Normal file
161
CloverApp/Clover/IO.swift
Normal file
@ -0,0 +1,161 @@
|
||||
//
|
||||
// IO.swift
|
||||
// Clover
|
||||
//
|
||||
// Created by vector sigma on 12/12/2019.
|
||||
// Copyright © 2019 CloverHackyColor. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
// MARK: get IODeviceTree:/efi dictionary
|
||||
fileprivate func getEFItree() -> NSMutableDictionary? {
|
||||
var ref: io_registry_entry_t
|
||||
var masterPort = mach_port_t()
|
||||
var oResult: kern_return_t
|
||||
var result: kern_return_t
|
||||
oResult = IOMasterPort(bootstrap_port, &masterPort)
|
||||
|
||||
if oResult != KERN_SUCCESS {
|
||||
return nil
|
||||
}
|
||||
|
||||
ref = IORegistryEntryFromPath(masterPort, "IODeviceTree:/efi")
|
||||
if ref == 0 {
|
||||
return nil
|
||||
}
|
||||
var dict : Unmanaged<CFMutableDictionary>?
|
||||
result = IORegistryEntryCreateCFProperties(ref, &dict, kCFAllocatorDefault, 0)
|
||||
if result != KERN_SUCCESS {
|
||||
IOObjectRelease(ref)
|
||||
return nil
|
||||
}
|
||||
IOObjectRelease(ref)
|
||||
return dict?.takeRetainedValue()
|
||||
}
|
||||
|
||||
/// Get firmware-vendor string.
|
||||
func getFirmawareVendor() -> String? {
|
||||
if let data = getEFItree()?.object(forKey: "firmware-vendor") as? Data {
|
||||
var cleanedData = Data()
|
||||
for i in 0..<data.count {
|
||||
if data[i] != 0x00 {
|
||||
cleanedData.append(data[i])
|
||||
}
|
||||
}
|
||||
cleanedData.append(0x00)
|
||||
return String(bytes: cleanedData, encoding: .utf8)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
/// Get IODeviceTree:/efi/platform Dictionary.
|
||||
fileprivate func getEFIPlatform() -> NSDictionary? {
|
||||
var ref: io_registry_entry_t
|
||||
var masterPort = mach_port_t()
|
||||
var oResult: kern_return_t
|
||||
var result: kern_return_t
|
||||
oResult = IOMasterPort(bootstrap_port, &masterPort)
|
||||
|
||||
if oResult != KERN_SUCCESS {
|
||||
return nil
|
||||
}
|
||||
|
||||
ref = IORegistryEntryFromPath(masterPort, "IODeviceTree:/efi/platform")
|
||||
if ref == 0 {
|
||||
return nil
|
||||
}
|
||||
var dict : Unmanaged<CFMutableDictionary>?
|
||||
result = IORegistryEntryCreateCFProperties(ref, &dict, kCFAllocatorDefault, 0)
|
||||
if result != KERN_SUCCESS {
|
||||
IOObjectRelease(ref)
|
||||
return nil
|
||||
}
|
||||
IOObjectRelease(ref)
|
||||
return dict?.takeRetainedValue()
|
||||
}
|
||||
|
||||
/// Get OEMVendor string.
|
||||
func getOEMVendor() -> String? {
|
||||
if let data = getEFIPlatform()?.object(forKey: "OEMVendor") as? Data {
|
||||
return String(bytes: data, encoding: .utf8)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
/// Get OEMProduct string.
|
||||
func getOEMProduct() -> String? {
|
||||
if let data = getEFIPlatform()?.object(forKey: "OEMProduct") as? Data {
|
||||
return String(bytes: data, encoding: .utf8)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
/// Get OEMBoard string.
|
||||
func getOEMBoard() -> String? {
|
||||
if let data = getEFIPlatform()?.object(forKey: "OEMBoard") as? Data {
|
||||
return String(bytes: data, encoding: .utf8)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
/// Get SystemSerialNumber string.
|
||||
func getSystemSerialNumber() -> String? {
|
||||
if let data = getEFIPlatform()?.object(forKey: "SystemSerialNumber") as? Data {
|
||||
var cleanedData = Data()
|
||||
for i in 0..<data.count {
|
||||
if data[i] != 0x00 {
|
||||
cleanedData.append(data[i])
|
||||
}
|
||||
}
|
||||
cleanedData.append(0x00)
|
||||
return String(bytes: cleanedData, encoding: .utf8)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
/// Get motherboard Model string.
|
||||
func getEFIModel() -> String? {
|
||||
if let data = getEFIPlatform()?.object(forKey: "Model") as? Data {
|
||||
var cleanedData = Data()
|
||||
for i in 0..<data.count {
|
||||
if data[i] != 0x00 {
|
||||
cleanedData.append(data[i])
|
||||
}
|
||||
}
|
||||
cleanedData.append(0x00)
|
||||
return String(bytes: cleanedData, encoding: .utf8)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
/// Get macOS board-id string.
|
||||
func getEFIBoardID() -> String? {
|
||||
if let data = getEFIPlatform()?.object(forKey: "board-id") as? Data {
|
||||
var cleanedData = Data()
|
||||
for i in 0..<data.count {
|
||||
if data[i] != 0x00 {
|
||||
cleanedData.append(data[i])
|
||||
}
|
||||
}
|
||||
cleanedData.append(0x00)
|
||||
return String(bytes: cleanedData, encoding: .utf8)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
/// Determine if the bootloader is a (known) legacy firmware
|
||||
func isLegacyFirmware() -> Bool {
|
||||
var isUEFI = true
|
||||
let fwname = getFirmawareVendor()?.lowercased()
|
||||
|
||||
if fwname!.lowercased().hasPrefix("edk")
|
||||
|| fwname!.lowercased().hasPrefix("chameleon")
|
||||
|| fwname!.lowercased().hasPrefix("enoch")
|
||||
|| fwname!.lowercased().hasPrefix("duet")
|
||||
|| fwname!.lowercased().hasPrefix("clover") {
|
||||
isUEFI = false
|
||||
}
|
||||
|
||||
return !isUEFI
|
||||
}
|
@ -20,6 +20,7 @@ class InstallerWindowController: NSWindowController, NSWindowDelegate {
|
||||
self.viewController = newValue
|
||||
}
|
||||
}
|
||||
|
||||
func windowShouldClose(_ sender: NSWindow) -> Bool {
|
||||
if AppSD.isInstalling {
|
||||
return false
|
||||
@ -742,28 +743,28 @@ class InstallerViewController: NSViewController {
|
||||
let attributes = [/*NSAttributedString.Key.font: font,*/ NSAttributedString.Key.foregroundColor: textColor]
|
||||
|
||||
let astr = NSAttributedString(string: text, attributes: attributes)
|
||||
//DispatchQueue.global(qos: .background).async {
|
||||
DispatchQueue.main.async {
|
||||
if add {
|
||||
self.infoText.textStorage?.append(astr)
|
||||
} else {
|
||||
self.infoText.string = ""
|
||||
self.infoText.textStorage?.append(astr)
|
||||
}
|
||||
|
||||
if scroll {
|
||||
let loc = self.infoText.string.lengthOfBytes(using: String.Encoding.utf8)
|
||||
let range = NSRange(location: loc, length: 0)
|
||||
self.infoText.scrollRangeToVisible(range)
|
||||
} else {
|
||||
self.infoText.scroll(NSPoint.zero)
|
||||
}
|
||||
}
|
||||
//}
|
||||
if add {
|
||||
self.infoText.textStorage?.append(astr)
|
||||
} else {
|
||||
self.infoText.string = ""
|
||||
self.infoText.textStorage?.append(astr)
|
||||
}
|
||||
|
||||
if scroll {
|
||||
let loc = self.infoText.string.lengthOfBytes(using: String.Encoding.utf8)
|
||||
let range = NSRange(location: loc, length: 0)
|
||||
self.infoText.scrollRangeToVisible(range)
|
||||
} else {
|
||||
self.infoText.scroll(NSPoint.zero)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Installation
|
||||
@IBAction func installPressed(_ sender: NSButton!) {
|
||||
if AppSD.isInstalling {
|
||||
NSSound.beep()
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
NSString *targetVol = [CloverappDict objectForKey:@"targetVol"];
|
||||
@ -776,6 +777,9 @@ class InstallerViewController: NSViewController {
|
||||
NSString *cloverv2 = [CloverappDict objectForKey:@"CloverV2"];
|
||||
NSString *boot1installPath = [CloverappDict objectForKey:@"boot1install"];
|
||||
NSString *bootSectorsInstallSrc = [CloverappDict objectForKey:@"bootsectors-install"];
|
||||
NSString *backUpPath = [CloverappDict objectForKey:@"BackUpPath"];
|
||||
NSString *version = [CloverappDict objectForKey:@"version"];
|
||||
BOOL isESP = [[CloverappDict objectForKey:@"isESP"] boolValue];
|
||||
*/
|
||||
|
||||
let Cloverapp = NSMutableDictionary()
|
||||
@ -785,6 +789,7 @@ class InstallerViewController: NSViewController {
|
||||
|
||||
// minimum required arguments
|
||||
Cloverapp.setValue(self.targetVol, forKey: "targetVol")
|
||||
Cloverapp.setValue(self.view.window!.title, forKey: "version")
|
||||
|
||||
let disk = getBSDName(of: self.targetVol) ?? ""
|
||||
Cloverapp.setValue(disk, forKey: "disk")
|
||||
@ -801,6 +806,9 @@ class InstallerViewController: NSViewController {
|
||||
post(text: "Error: can't install on \(filesystem.uppercased()) filesystem.", add: false, color: nil, scroll: false)
|
||||
return
|
||||
}
|
||||
AppSD.isInstalling = true
|
||||
self.installButton.isEnabled = false
|
||||
self.spinner.startAnimation(nil)
|
||||
|
||||
// drivers
|
||||
for sect in self.driversUEFI {
|
||||
@ -845,35 +853,58 @@ class InstallerViewController: NSViewController {
|
||||
}
|
||||
|
||||
// backup in ~/Desktop/EFI_Backup_date
|
||||
self.post(text: "Checking files...\n", add: false, color: nil, scroll: false)
|
||||
if fm.fileExists(atPath: self.targetVol.addPath("EFI/CLOVER")) {
|
||||
self.post(text: "doing the backup...\n", add: false, color: nil, scroll: false)
|
||||
|
||||
let df = DateFormatter()
|
||||
df.dateFormat = "yyyy-MM-dd hh:mm:ss"
|
||||
df.dateFormat = "yyyy-MM-dd_hh-mm-ss"
|
||||
let now = df.string(from: Date())
|
||||
let revIn = findCloverRevision(at: self.targetVol.addPath("EFI")) ?? "0000"
|
||||
let backUpPath = NSHomeDirectory().addPath("Desktop/CloverBackUp/EFI_r\(revIn)_\(now)")
|
||||
do {
|
||||
if !fm.fileExists(atPath: backUpPath.deletingLastPath) {
|
||||
try fm.createDirectory(atPath: backUpPath.deletingLastPath,
|
||||
withIntermediateDirectories: false,
|
||||
attributes: nil)
|
||||
let mediaName = getMediaName(from: getBSDParent(of: disk) ?? "") ?? "NoName"
|
||||
let backUpPath = NSHomeDirectory().addPath("Desktop/CloverBackUp/\(mediaName)/r\(revIn)_\(now)/EFI")
|
||||
if #available(OSX 10.10, *) {
|
||||
DispatchQueue.global(qos: .userInteractive).async {
|
||||
do {
|
||||
if !fm.fileExists(atPath: backUpPath.deletingLastPath) {
|
||||
try fm.createDirectory(atPath: backUpPath.deletingLastPath,
|
||||
withIntermediateDirectories: true,
|
||||
attributes: nil)
|
||||
}
|
||||
try fm.copyItem(atPath: self.targetVol.addPath("EFI"),
|
||||
toPath: backUpPath)
|
||||
//post(text: "backup made at '\(backUpPath)'.\n", add: true, color: nil, scroll: false)
|
||||
Cloverapp.setValue(backUpPath, forKey: "BackUpPath")
|
||||
self.installClover(disk: disk, settingDict: Cloverapp)
|
||||
} catch {
|
||||
DispatchQueue.main.async {
|
||||
self.post(text: "The backup failed:\n", add: true, color: nil, scroll: false)
|
||||
self.post(text: error.localizedDescription, add: false, color: nil, scroll: false)
|
||||
AppSD.isInstalling = false
|
||||
self.installButton.isEnabled = true
|
||||
self.spinner.stopAnimation(nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
try fm.copyItem(atPath: self.targetVol.addPath("EFI"),
|
||||
toPath: backUpPath)
|
||||
|
||||
self.installClover(disk: disk, settingDict: Cloverapp)
|
||||
} catch {
|
||||
post(text: error.localizedDescription, add: false, color: nil, scroll: false)
|
||||
}
|
||||
|
||||
} else {
|
||||
self.installClover(disk: disk, settingDict: Cloverapp)
|
||||
if #available(OSX 10.10, *) {
|
||||
DispatchQueue.global(qos: .userInteractive).async {
|
||||
self.installClover(disk: disk, settingDict: Cloverapp)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func installClover(disk: String, settingDict : NSDictionary) {
|
||||
self.post(text: "Installation begin..", add: false, color: nil, scroll: false)
|
||||
self.post(text: "Installation begin..\n", add: true, color: nil, scroll: false)
|
||||
if !isMountPoint(path: self.targetVol) {
|
||||
NSSound.beep()
|
||||
self.post(text: "Can't find target volume, installation aborted.", add: true, color: nil, scroll: false)
|
||||
DispatchQueue.main.async {
|
||||
NSSound.beep()
|
||||
self.post(text: "Can't find target volume, installation aborted.", add: true, color: nil, scroll: false)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@ -889,70 +920,97 @@ class InstallerViewController: NSViewController {
|
||||
try? fm.removeItem(atPath: "/tmp/Cloverapp")
|
||||
|
||||
if settingDict.write(toFile: "/tmp/Cloverapp", atomically: false) {
|
||||
self.installButton.isEnabled = false
|
||||
AppSD.isInstalling = true
|
||||
self.spinner.startAnimation(nil)
|
||||
|
||||
self.view.window?.level = .floating // just a hack to keep window in front momentarily
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.spinner.startAnimation(nil)
|
||||
self.installButton.isEnabled = false
|
||||
self.view.window?.level = .floating // just a hack to keep window in front momentarily
|
||||
}
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 6.0) {
|
||||
self.view.window?.level = .normal
|
||||
}
|
||||
//DispatchQueue.global(qos: .background).async {
|
||||
let task = Process()
|
||||
let msg = "Install Clover".locale
|
||||
let helperPath = Bundle.main.executablePath!.deletingLastPath.addPath("Cloverhelper")
|
||||
|
||||
let script = "do shell script \"'\(helperPath)'\" with prompt \"\(msg)\" with administrator privileges"
|
||||
|
||||
task.launchPath = "/usr/bin/osascript"
|
||||
task.arguments = ["-e", script]
|
||||
let pipe: Pipe = Pipe()
|
||||
|
||||
let stdOutHandler = { (file: FileHandle!) -> Void in
|
||||
let data = file.availableData
|
||||
//file.closeFile()
|
||||
let output = String(decoding: data, as: UTF8.self)
|
||||
DispatchQueue.main.async {
|
||||
self.view.window?.level = .normal // restore window level to normal
|
||||
self.post(text: "\n" + output, add: true, color: nil, scroll: true)
|
||||
}
|
||||
}
|
||||
|
||||
task.standardOutput = pipe
|
||||
task.standardError = pipe
|
||||
pipe.fileHandleForReading.readabilityHandler = stdOutHandler
|
||||
|
||||
task.terminationHandler = { t in
|
||||
|
||||
if t.terminationStatus == 0 {
|
||||
DispatchQueue.main.async {
|
||||
self.post(text: "\nInstallation succeded.", add: true, color: nil, scroll: true)
|
||||
}
|
||||
} else {
|
||||
NSSound.beep()
|
||||
DispatchQueue.main.async {
|
||||
self.post(text: "\nInstallation failed.", add: true, color: nil, scroll: true)
|
||||
}
|
||||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
AppSD.isInstalling = false
|
||||
self.installButton.isEnabled = true
|
||||
self.spinner.stopAnimation(nil)
|
||||
if isMountPoint(path: self.targetVol) {
|
||||
self.targetVol = getMountPoint(from: disk) ?? ""
|
||||
}
|
||||
AppSD.reFreshDisksList()
|
||||
self.setPreferences(for: self.targetVol)
|
||||
}
|
||||
}
|
||||
task.launch()
|
||||
//}
|
||||
|
||||
let task = Process()
|
||||
let msg = "Install Clover".locale
|
||||
let helperPath = Bundle.main.executablePath!.deletingLastPath.addPath("Cloverhelper")
|
||||
let script = "do shell script \"'\(helperPath)'\" with prompt \"\(msg)\" with administrator privileges"
|
||||
task.launchPath = "/usr/bin/osascript"
|
||||
task.arguments = ["-e", script]
|
||||
let pipe: Pipe = Pipe()
|
||||
|
||||
task.standardOutput = pipe
|
||||
task.standardError = pipe
|
||||
let fh = pipe.fileHandleForReading
|
||||
fh.waitForDataInBackgroundAndNotify()
|
||||
|
||||
var op1 : NSObjectProtocol!
|
||||
op1 = NotificationCenter.default.addObserver(forName: NSNotification.Name.NSFileHandleDataAvailable,
|
||||
object: fh, queue: nil) {
|
||||
notification -> Void in
|
||||
let data = fh.availableData
|
||||
if data.count > 0 {
|
||||
let output = String(decoding: data, as: UTF8.self)
|
||||
DispatchQueue.main.async {
|
||||
if self.view.window?.level != .normal {
|
||||
self.view.window?.level = .normal
|
||||
}
|
||||
|
||||
self.post(text: "\n" + output,
|
||||
add: true,
|
||||
color: nil,
|
||||
scroll: true)
|
||||
}
|
||||
fh.waitForDataInBackgroundAndNotify()
|
||||
} else {
|
||||
NotificationCenter.default.removeObserver(op1 as Any)
|
||||
}
|
||||
}
|
||||
|
||||
var op2 : NSObjectProtocol!
|
||||
op2 = NotificationCenter.default.addObserver(forName: Process.didTerminateNotification,
|
||||
object: task, queue: nil) {
|
||||
notification -> Void in
|
||||
NotificationCenter.default.removeObserver(op2 as Any)
|
||||
let success = (task.terminationStatus == 0)
|
||||
DispatchQueue.main.async {
|
||||
let message = success ? "Installation succeded".locale : "Installation failed".locale
|
||||
self.post(text: "\n\(message).", add: true, color: nil, scroll: true)
|
||||
|
||||
|
||||
NSSound(named: success ? "Glass" : "Basso")?.play()
|
||||
let alert = NSAlert()
|
||||
alert.messageText = message
|
||||
alert.informativeText = success ? "😀" : "😱"
|
||||
alert.alertStyle = success ? .informational : .critical
|
||||
alert.addButton(withTitle: "Ok".locale)
|
||||
|
||||
alert.beginSheetModal(for: self.view.window!) { (reponse) in
|
||||
AppSD.isInstalling = false
|
||||
self.installButton.isEnabled = true
|
||||
self.spinner.stopAnimation(nil)
|
||||
if isMountPoint(path: self.targetVol) {
|
||||
self.targetVol = getMountPoint(from: disk) ?? ""
|
||||
}
|
||||
AppSD.reFreshDisksList()
|
||||
self.setPreferences(for: self.targetVol)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task.launch()
|
||||
task.waitUntilExit()
|
||||
|
||||
} else {
|
||||
NSSound.beep()
|
||||
self.post(text: "Can't write temporary files, installation aborted.", add: true, color: nil, scroll: false)
|
||||
DispatchQueue.main.async {
|
||||
NSSound.beep()
|
||||
self.post(text: "Can't write temporary files, installation aborted.", add: true, color: nil, scroll: false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -720,6 +720,9 @@ class InstallerOutViewController: NSViewController {
|
||||
NSString *cloverv2 = [CloverappDict objectForKey:@"CloverV2"];
|
||||
NSString *boot1installPath = [CloverappDict objectForKey:@"boot1install"];
|
||||
NSString *bootSectorsInstallSrc = [CloverappDict objectForKey:@"bootsectors-install"];
|
||||
NSString *backUpPath = [CloverappDict objectForKey:@"BackUpPath"];
|
||||
NSString *version = [CloverappDict objectForKey:@"version"];
|
||||
BOOL isESP = [[CloverappDict objectForKey:@"isESP"] boolValue];
|
||||
*/
|
||||
|
||||
let Cloverapp = NSMutableDictionary()
|
||||
@ -729,6 +732,7 @@ class InstallerOutViewController: NSViewController {
|
||||
|
||||
// minimum required arguments
|
||||
Cloverapp.setValue(self.targetVol, forKey: "targetVol")
|
||||
Cloverapp.setValue(self.view.window!.title, forKey: "version")
|
||||
|
||||
let disk = getBSDName(of: self.targetVol) ?? ""
|
||||
Cloverapp.setValue(disk, forKey: "disk")
|
||||
@ -789,23 +793,28 @@ class InstallerOutViewController: NSViewController {
|
||||
}
|
||||
|
||||
// backup in ~/Desktop/EFI_Backup_date
|
||||
post(text: "Checking files...\n", add: false, color: nil, scroll: false)
|
||||
if fm.fileExists(atPath: self.targetVol.addPath("EFI/CLOVER")) {
|
||||
let df = DateFormatter()
|
||||
df.dateFormat = "yyyy-MM-dd hh:mm:ss"
|
||||
df.dateFormat = "yyyy-MM-dd_hh-mm-ss"
|
||||
let now = df.string(from: Date())
|
||||
let revIn = findCloverRevision(at: self.targetVol.addPath("EFI")) ?? "0000"
|
||||
let backUpPath = NSHomeDirectory().addPath("Desktop/CloverBackUp/EFI_r\(revIn)_\(now)")
|
||||
let mediaName = getMediaName(from: getBSDParent(of: disk) ?? "") ?? "NoName"
|
||||
let backUpPath = NSHomeDirectory().addPath("Desktop/CloverBackUp/\(mediaName)/r\(revIn)_\(now)/EFI")
|
||||
|
||||
do {
|
||||
if !fm.fileExists(atPath: backUpPath.deletingLastPath) {
|
||||
try fm.createDirectory(atPath: backUpPath.deletingLastPath,
|
||||
withIntermediateDirectories: false,
|
||||
withIntermediateDirectories: true,
|
||||
attributes: nil)
|
||||
}
|
||||
try fm.copyItem(atPath: self.targetVol.addPath("EFI"),
|
||||
toPath: backUpPath)
|
||||
|
||||
//post(text: "backup made at '\(backUpPath)'.\n", add: true, color: nil, scroll: false)
|
||||
Cloverapp.setValue(backUpPath, forKey: "BackUpPath")
|
||||
self.installClover(disk: disk, settingDict: Cloverapp)
|
||||
} catch {
|
||||
post(text: "The backup failed:\n", add: true, color: nil, scroll: false)
|
||||
post(text: error.localizedDescription, add: false, color: nil, scroll: false)
|
||||
}
|
||||
} else {
|
||||
@ -814,7 +823,7 @@ class InstallerOutViewController: NSViewController {
|
||||
}
|
||||
|
||||
func installClover(disk: String, settingDict : NSDictionary) {
|
||||
self.post(text: "Installation begin..", add: false, color: nil, scroll: false)
|
||||
self.post(text: "Installation begin..\n", add: true, color: nil, scroll: false)
|
||||
if !isMountPoint(path: self.targetVol) {
|
||||
NSSound.beep()
|
||||
self.post(text: "Can't find target volume, installation aborted.", add: true, color: nil, scroll: false)
|
||||
@ -847,30 +856,29 @@ class InstallerOutViewController: NSViewController {
|
||||
var err : NSDictionary? = nil
|
||||
let result : NSAppleEventDescriptor = NSAppleScript(source: script)!.executeAndReturnError(&err)
|
||||
|
||||
if (err != nil) {
|
||||
NSSound.beep()
|
||||
self.post(text: result.stringValue ?? "", add: false, color: nil, scroll: true)
|
||||
self.post(text: "\nInstallation failed.", add: true, color: nil, scroll: true)
|
||||
AppSD.isInstalling = false
|
||||
self.spinner.stopAnimation(nil)
|
||||
AppSD.reFreshDisksList()
|
||||
if isMountPoint(path: self.targetVol) {
|
||||
self.targetVol = getMountPoint(from: disk) ?? ""
|
||||
self.installButton.isEnabled = true
|
||||
self.setPreferences(for: self.targetVol)
|
||||
}
|
||||
} else {
|
||||
self.post(text: result.stringValue ?? "", add: false, color: nil, scroll: true)
|
||||
self.post(text: "\nInstallation succeded.", add: true, color: nil, scroll: true)
|
||||
AppSD.isInstalling = false
|
||||
self.spinner.stopAnimation(nil)
|
||||
AppSD.reFreshDisksList()
|
||||
if isMountPoint(path: self.targetVol) {
|
||||
self.targetVol = getMountPoint(from: disk) ?? ""
|
||||
self.installButton.isEnabled = true
|
||||
self.setPreferences(for: self.targetVol)
|
||||
}
|
||||
self.post(text: result.stringValue ?? "", add: false, color: nil, scroll: true)
|
||||
self.spinner.stopAnimation(nil)
|
||||
let message = (err == nil) ? "Installation succeded".locale : "Installation failed".locale
|
||||
self.post(text: "\n\(message).", add: true, color: nil, scroll: true)
|
||||
|
||||
let alert = NSAlert()
|
||||
alert.messageText = message
|
||||
if #available(OSX 10.10, *) {
|
||||
alert.informativeText = (err == nil) ? "😀" : "😱"
|
||||
}
|
||||
alert.alertStyle = (err == nil) ? .informational : .critical
|
||||
alert.addButton(withTitle: "Close".locale)
|
||||
alert.beginSheetModal(for: self.view.window!) { (reponse) in
|
||||
|
||||
}
|
||||
AppSD.isInstalling = false
|
||||
self.installButton.isEnabled = true
|
||||
self.spinner.stopAnimation(nil)
|
||||
if isMountPoint(path: self.targetVol) {
|
||||
self.targetVol = getMountPoint(from: disk) ?? ""
|
||||
}
|
||||
AppSD.reFreshDisksList()
|
||||
self.setPreferences(for: self.targetVol)
|
||||
} else {
|
||||
NSSound.beep()
|
||||
self.post(text: "Can't write temporary files, installation aborted.", add: true, color: nil, scroll: false)
|
||||
|
@ -49,10 +49,20 @@ func localize(view: NSView) {
|
||||
if x.title.count > 0 {
|
||||
x.title = x.title.locale
|
||||
}
|
||||
} else if o is NSTabView {
|
||||
let x = (o as! NSTabView)
|
||||
for i in x.tabViewItems {
|
||||
i.label = i.label.locale
|
||||
if let v = i.view {
|
||||
localize(view: v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if o.subviews.count > 0 {
|
||||
localize(view: o)
|
||||
for v in o.subviews {
|
||||
localize(view: v)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ func setNVRAM(key: String, stringValue: String) {
|
||||
var cmd : String = "do shell script \""
|
||||
cmd += "sudo \(nvram_cmd) \(key)=\(stringValue)" // sudo required otherwise wont work!
|
||||
cmd += "\" with administrator privileges"
|
||||
|
||||
//DispatchQueue.global(qos: .background).async {
|
||||
let script: NSAppleScript? = NSAppleScript(source: cmd)
|
||||
var error : NSDictionary? = nil
|
||||
|
@ -74,7 +74,7 @@ func getLatestReleases(reply: @escaping (String?, String?, String?, String?) ->
|
||||
print("appvers: \(appvers)")
|
||||
*/
|
||||
reply(bootlink, bootvers, applink, appvers)
|
||||
});
|
||||
})
|
||||
|
||||
task.resume()
|
||||
}
|
||||
|
@ -8,16 +8,55 @@
|
||||
|
||||
import Cocoa
|
||||
|
||||
class LITabView: NSTabView {
|
||||
var tabIndex: Int = 0
|
||||
var lastTabIndex: Int {
|
||||
get {
|
||||
return self.tabIndex
|
||||
} set {
|
||||
self.tabIndex = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class SoundSlider : NSSlider {
|
||||
var field : NSTextField?
|
||||
}
|
||||
|
||||
class SettingsViewController: NSViewController, NSTextFieldDelegate, URLSessionDownloadDelegate {
|
||||
// MARK: Variables
|
||||
@IBOutlet var tabViewInfo : LITabView!
|
||||
// tab 0
|
||||
@IBOutlet var currentRevField : NSTextField!
|
||||
@IBOutlet var bootDeviceField : NSTextField!
|
||||
@IBOutlet var configPathField : FWTextField!
|
||||
// tab 1
|
||||
@IBOutlet var snField : NSTextField!
|
||||
@IBOutlet var modelField : NSTextField!
|
||||
@IBOutlet var boardIdField : NSTextField!
|
||||
// tab 2
|
||||
@IBOutlet var oemVendorField : NSTextField!
|
||||
@IBOutlet var oemProductField : NSTextField!
|
||||
@IBOutlet var oemBoardIdField : NSTextField!
|
||||
// tab 3
|
||||
@IBOutlet var nativeNVRAMField : NSTextField!
|
||||
@IBOutlet var bootTypeField : NSTextField!
|
||||
@IBOutlet var firmwareVendorfield : NSTextField!
|
||||
|
||||
@IBOutlet var tabViewFunc : LITabView!
|
||||
@IBOutlet var tabViewFuncSelector : NSSegmentedControl!
|
||||
// tab 0
|
||||
@IBOutlet var disksPopUp : NSPopUpButton!
|
||||
@IBOutlet var autoMountButton : NSButton!
|
||||
@IBOutlet var unmountButton : NSButton!
|
||||
// tab 1
|
||||
@IBOutlet var themeField : FWTextField!
|
||||
@IBOutlet var soundField : FWTextField!
|
||||
// tab 2
|
||||
@IBOutlet var soundDevicePopUp : NSPopUpButton!
|
||||
@IBOutlet var soundVolumeSlider : SoundSlider!
|
||||
@IBOutlet var soundVolumeField : NSTextField!
|
||||
|
||||
@IBOutlet var disbaleSleepProxyButton : NSButton!
|
||||
@IBOutlet var makeRootRWButton : NSButton!
|
||||
@IBOutlet var installDaemonButton : NSButton!
|
||||
@ -50,6 +89,8 @@ class SettingsViewController: NSViewController, NSTextFieldDelegate, URLSessionD
|
||||
|
||||
var loaded : Bool = false
|
||||
|
||||
|
||||
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
if !self.loaded {
|
||||
@ -65,20 +106,33 @@ class SettingsViewController: NSViewController, NSTextFieldDelegate, URLSessionD
|
||||
if #available(OSX 10.10, *) {
|
||||
super.viewDidLoad()
|
||||
}
|
||||
|
||||
var osminorVersion : Int = 9
|
||||
if #available(OSX 10.10, *) {
|
||||
osminorVersion = ProcessInfo().operatingSystemVersion.minorVersion
|
||||
}
|
||||
|
||||
let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as! String + " Beta"
|
||||
self.appVersionField.stringValue = "v\(appVersion)"
|
||||
localize(view: self.view)
|
||||
|
||||
self.view.wantsLayer = true
|
||||
self.view.layer?.backgroundColor = NSColor.clear.cgColor
|
||||
|
||||
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.themeField.delegate = self
|
||||
self.soundField.delegate = self
|
||||
|
||||
self.soundVolumeSlider.field = self.soundVolumeField
|
||||
self.soundVolumeField.stringValue = kNotAvailable.locale
|
||||
self.soundDevicePopUp.removeAllItems()
|
||||
self.soundDevicePopUp.addItem(withTitle: "...")
|
||||
|
||||
let soundDevices = getSoundDevices()
|
||||
if soundDevices.count > 0 {
|
||||
for sd in soundDevices {
|
||||
self.soundDevicePopUp.addItem(withTitle: "\(sd.name) (\(sd.output.locale))")
|
||||
self.soundDevicePopUp.lastItem?.representedObject = sd
|
||||
}
|
||||
}
|
||||
self.soundVolumeSlider.doubleValue = 0
|
||||
|
||||
self.progressBar.isHidden = true
|
||||
|
||||
@ -87,6 +141,26 @@ class SettingsViewController: NSViewController, NSTextFieldDelegate, URLSessionD
|
||||
self.autoMountButton.isEnabled = false
|
||||
self.autoMountButton.isHidden = true
|
||||
|
||||
|
||||
// tab 1
|
||||
self.snField.stringValue = getSystemSerialNumber() ?? kNotAvailable.locale
|
||||
self.modelField.stringValue = getEFIModel() ?? kNotAvailable.locale
|
||||
self.boardIdField.stringValue = getEFIBoardID() ?? kNotAvailable.locale
|
||||
// tab 2
|
||||
self.oemVendorField.stringValue = getOEMVendor() ?? kNotAvailable.locale
|
||||
self.oemProductField.stringValue = getOEMProduct() ?? kNotAvailable.locale
|
||||
self.oemBoardIdField.stringValue = getOEMBoard() ?? kNotAvailable.locale
|
||||
|
||||
self.setUpInfo()
|
||||
self.setUpdateButton()
|
||||
}
|
||||
|
||||
func setUpInfo() {
|
||||
var osminorVersion : Int = 9
|
||||
if #available(OSX 10.10, *) {
|
||||
osminorVersion = ProcessInfo().operatingSystemVersion.minorVersion
|
||||
}
|
||||
|
||||
self.setUpdateInformations()
|
||||
|
||||
let nvram = getNVRAM()
|
||||
@ -98,17 +172,34 @@ class SettingsViewController: NSViewController, NSTextFieldDelegate, URLSessionD
|
||||
self.themeField.stringValue = (nvdata != nil) ? String(decoding: nvdata!, as: UTF8.self) : ""
|
||||
self.themeField.cell?.representedObject = self.themeField.stringValue
|
||||
|
||||
nvdata = nvram?.object(forKey: "Clover.Sound") as? Data
|
||||
if #available(OSX 10.10, *) {
|
||||
self.soundField.placeholderString = kNotAvailable.locale
|
||||
}
|
||||
self.soundField.stringValue = (nvdata != nil) ? String(decoding: nvdata!, as: UTF8.self) : ""
|
||||
self.soundField.cell?.representedObject = self.soundField.stringValue
|
||||
|
||||
nvdata = nvram?.object(forKey: "Clover.RootRW") as? Data
|
||||
var value : String = String(decoding: nvdata ?? Data(), as: UTF8.self)
|
||||
self.makeRootRWButton.state = (value == "true") ? .on : .off
|
||||
|
||||
nvdata = nvram?.object(forKey: "Clover.SoundIndex") as? Data
|
||||
if (nvdata != nil) {
|
||||
let soundIndex = nvdata!.reversed().reduce(0) { $0 << 8 + UInt64($1) }
|
||||
if soundIndex >= 0 && soundIndex <= 20 {
|
||||
for item in self.soundDevicePopUp.itemArray {
|
||||
if let sd = item.representedObject as? SoundDevice {
|
||||
if sd.index == Int(soundIndex) {
|
||||
self.soundDevicePopUp.select(item)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nvdata = nvram?.object(forKey: "Clover.SoundVolume") as? Data
|
||||
if (nvdata != nil) {
|
||||
let volume = nvdata!.reversed().reduce(0) { $0 << 8 + UInt64($1) }
|
||||
if volume >= 0 && volume <= 100 {
|
||||
self.soundVolumeSlider.field?.stringValue = "\(volume)%"
|
||||
self.soundVolumeSlider.doubleValue = Double(volume)
|
||||
}
|
||||
}
|
||||
|
||||
// copy the Swift Framenworks for oldest OSes
|
||||
if osminorVersion < 15 {
|
||||
self.makeRootRWButton.isEnabled = false
|
||||
@ -118,14 +209,31 @@ class SettingsViewController: NSViewController, NSTextFieldDelegate, URLSessionD
|
||||
nvdata = nvram?.object(forKey: "Clover.DisableSleepProxyClient") as? Data
|
||||
value = String(decoding: nvdata ?? Data(), as: UTF8.self)
|
||||
self.disbaleSleepProxyButton.state = (value == "true") ? .on : .off
|
||||
|
||||
|
||||
|
||||
// tab 3
|
||||
let fwname = getFirmawareVendor()
|
||||
self.firmwareVendorfield.stringValue = "Firmware: \(fwname ?? kNotAvailable.locale)"
|
||||
|
||||
let emuvarPresent = nvram?.object(forKey: "EmuVariableUefiPresent") != nil
|
||||
var nvramIsNative : String? = nil
|
||||
let isUEFI : String = isLegacyFirmware() ? "No".locale.lowercased() : "Yes".locale.lowercased()
|
||||
|
||||
|
||||
if isUEFI == "Yes".locale.lowercased() {
|
||||
nvramIsNative = emuvarPresent ? "No".locale.lowercased() : "Yes".locale.lowercased()
|
||||
}
|
||||
|
||||
self.nativeNVRAMField.stringValue = "\("NVRAM is native:".locale) " + (nvramIsNative ?? "unknown".locale)
|
||||
|
||||
self.bootTypeField.stringValue = "UEFI: \(isUEFI)"
|
||||
|
||||
|
||||
let daemonExist = fm.fileExists(atPath: kDaemonPath) && fm.fileExists(atPath: kLaunchPlistPath)
|
||||
self.unInstallDaemonButton.isEnabled = daemonExist
|
||||
|
||||
self.setUpdateButton()
|
||||
self.searchESPDisks()
|
||||
|
||||
|
||||
let itervals = ["never", "daily", "weekly", "monthly"]
|
||||
self.timeIntervalPopUp.removeAllItems()
|
||||
for i in itervals {
|
||||
@ -154,7 +262,7 @@ class SettingsViewController: NSViewController, NSTextFieldDelegate, URLSessionD
|
||||
} else {
|
||||
self.lastUpdateCheckField.stringValue = "\("last checked:".locale) \("never".locale)"
|
||||
}
|
||||
|
||||
|
||||
self.timerUpdate = Timer.scheduledTimer(timeInterval: 60 * 60,
|
||||
target: self,
|
||||
selector: #selector(self.setUpdateTimer),
|
||||
@ -377,20 +485,55 @@ class SettingsViewController: NSViewController, NSTextFieldDelegate, URLSessionD
|
||||
|
||||
// MARK: Controls actions
|
||||
@IBAction func installClover(_ sender: NSButton!) {
|
||||
if #available(OSX 10.11, *) {
|
||||
if (AppSD.installerWC == nil) {
|
||||
AppSD.installerWC = InstallerWindowController.loadFromNib()
|
||||
}
|
||||
|
||||
AppSD.installerWC?.showWindow(self)
|
||||
} else {
|
||||
if (AppSD.installerOutWC == nil) {
|
||||
AppSD.installerOutWC = InstallerOutWindowController.loadFromNib()
|
||||
}
|
||||
|
||||
AppSD.installerOutWC?.showWindow(self)
|
||||
|
||||
let myPath = Bundle.main.bundlePath.lowercased()
|
||||
var isXcode = false
|
||||
var showAlert = false
|
||||
if (myPath.range(of: "/deriveddata/") != nil) {
|
||||
showAlert = true
|
||||
isXcode = true
|
||||
} else if (myPath.range(of: "/apptranslocation/") != nil) {
|
||||
showAlert = true
|
||||
}
|
||||
|
||||
if showAlert {
|
||||
let alert = NSAlert()
|
||||
alert.alertStyle = .critical
|
||||
let path = isXcode ? "Xcode" : "App Trans Location"
|
||||
alert.messageText = "Running from \(path)"
|
||||
|
||||
if isXcode {
|
||||
alert.informativeText = "The Installer should not run from \(path) because it can reuse old resources like old built dependencies (in the DerivedData directory) instead ones from the app bundle in which you may had made changes.\nThis appear to be a bug in the Xcode build system, so please move Clover.app somewhere else for real installations, unless you are a Developer and you're just testing."
|
||||
} else {
|
||||
alert.informativeText = "The Installer cannot run from the \(path) and surely it will fail the installation.\nPlease move Clover.app somewhere else or use\n\nsudo spctl --master-disable\n\nThanks.\n\nP.S. Clover.app is not code signed because this require a paid Apple Developer certificate We cannot effort. If you have doubs, officiale releases are here:\n\n https://github.com/CloverHackyColor/CloverBootloader/releases\n\n..and you can build the app by your self if you prefear as this project is completely open source!"
|
||||
}
|
||||
|
||||
if isXcode {
|
||||
alert.addButton(withTitle: "OK".locale)
|
||||
alert.runModal()
|
||||
} else {
|
||||
alert.addButton(withTitle: "Close".locale)
|
||||
alert.runModal()
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
if #available(OSX 10.11, *) {
|
||||
if (AppSD.installerWC == nil) {
|
||||
AppSD.installerWC = InstallerWindowController.loadFromNib()
|
||||
}
|
||||
|
||||
AppSD.installerWC?.showWindow(self)
|
||||
} else {
|
||||
if (AppSD.installerOutWC == nil) {
|
||||
AppSD.installerOutWC = InstallerOutWindowController.loadFromNib()
|
||||
}
|
||||
|
||||
AppSD.installerOutWC?.showWindow(self)
|
||||
}
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
}
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
}
|
||||
|
||||
@IBAction func installDaemon(_ sender: NSButton!) {
|
||||
@ -492,9 +635,9 @@ class SettingsViewController: NSViewController, NSTextFieldDelegate, URLSessionD
|
||||
func controlTextDidEndEditing(_ obj: Notification) {
|
||||
if let field = obj.object as? NSTextField {
|
||||
let delete : Bool = field.stringValue.count == 0
|
||||
if field == self.themeField || field == soundField {
|
||||
if field == self.themeField {
|
||||
if let old = field.cell?.representedObject as? String {
|
||||
let key = (field == self.themeField) ? "Clover.Theme" : "Clover.Sound"
|
||||
let key = "Clover.Theme"
|
||||
if old != field.stringValue {
|
||||
if delete {
|
||||
deleteNVRAM(key: key)
|
||||
@ -511,6 +654,62 @@ class SettingsViewController: NSViewController, NSTextFieldDelegate, URLSessionD
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func soundSliderDidMove(_ sender: SoundSlider!) {
|
||||
sender.field?.stringValue = "\(Int(sender.doubleValue))%"
|
||||
|
||||
let key = "Clover.SoundVolume"
|
||||
var num = Int(sender.doubleValue)
|
||||
let value = String(format: "%%%02x", UInt8(num))
|
||||
setNVRAM(key: key, stringValue: value)
|
||||
num = 0
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
|
||||
if let nvram = getNVRAM() {
|
||||
if let nvdata = nvram.object(forKey: key) as? Data {
|
||||
let volume = nvdata.reversed().reduce(0) { $0 << 8 + UInt64($1) }
|
||||
num = (volume >= 0 && volume <= 100) ? Int(num) : 0
|
||||
}
|
||||
}
|
||||
sender.field?.stringValue = "\(num)%"
|
||||
sender.doubleValue = Double(num)
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func soundDeviceSelected(_ sender: NSPopUpButton!) {
|
||||
let key = "Clover.SoundIndex"
|
||||
if let sd = sender.selectedItem?.representedObject as? SoundDevice {
|
||||
let value = String(format: "%%%02x", UInt8(sd.index))
|
||||
setNVRAM(key: key, stringValue: value)
|
||||
}
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
|
||||
var index : Int = -1
|
||||
if let nvram = getNVRAM() {
|
||||
if let nvdata = nvram.object(forKey: key) as? Data {
|
||||
let val = nvdata.reversed().reduce(0) { $0 << 8 + UInt64($1) }
|
||||
index = (val >= 0 && val < self.soundDevicePopUp.numberOfItems) ? Int(val) : -1
|
||||
}
|
||||
}
|
||||
|
||||
if index >= 0 {
|
||||
var found = false
|
||||
for item in self.soundDevicePopUp.itemArray {
|
||||
if let sd = item.representedObject as? SoundDevice {
|
||||
if sd.index == index {
|
||||
found = true
|
||||
self.soundDevicePopUp.select(item)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
self.soundDevicePopUp.selectItem(at: 0)
|
||||
}
|
||||
} else {
|
||||
self.soundDevicePopUp.selectItem(at: 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func disableSleepProxy(_ sender: NSButton!) {
|
||||
let key = "Clover.DisableSleepProxyClient"
|
||||
if sender.state == .on {
|
||||
@ -532,7 +731,7 @@ class SettingsViewController: NSViewController, NSTextFieldDelegate, URLSessionD
|
||||
@IBAction func makeRootRW(_ sender: NSButton!) {
|
||||
let key = "Clover.RootRW"
|
||||
if sender.state == .on {
|
||||
setNVRAM(key: key, stringValue: "true"/*, error: &error*/)
|
||||
setNVRAM(key: key, stringValue: "true")
|
||||
} else {
|
||||
deleteNVRAM(key: key)
|
||||
}
|
||||
@ -617,7 +816,6 @@ class SettingsViewController: NSViewController, NSTextFieldDelegate, URLSessionD
|
||||
let secElapsed = Date().timeIntervalSinceReferenceDate - lastCheckDate.timeIntervalSinceReferenceDate
|
||||
|
||||
if secElapsed >= ti {
|
||||
print(secElapsed)
|
||||
self.searchUpdate()
|
||||
}
|
||||
}
|
||||
@ -720,7 +918,7 @@ class SettingsViewController: NSViewController, NSTextFieldDelegate, URLSessionD
|
||||
alert.messageText = "Clover.app v\(appvers!)"
|
||||
alert.informativeText = "\(currVerS) => \(appvers!)"
|
||||
alert.alertStyle = .informational
|
||||
alert.addButton(withTitle: "Update".locale)
|
||||
alert.addButton(withTitle: "Download".locale)
|
||||
alert.addButton(withTitle: "Close".locale)
|
||||
if alert.runModal() == .alertFirstButtonReturn {
|
||||
NSWorkspace.shared.open(url)
|
||||
@ -877,7 +1075,55 @@ class SettingsViewController: NSViewController, NSTextFieldDelegate, URLSessionD
|
||||
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Tab animation
|
||||
extension SettingsViewController: NSTabViewDelegate {
|
||||
@IBAction func selectTabInfo(_ sender: NSSegmentedControl!) {
|
||||
let count = self.tabViewInfo.tabViewItems.count
|
||||
|
||||
let index = self.tabViewInfo.indexOfTabViewItem(self.tabViewInfo.selectedTabViewItem!)
|
||||
|
||||
if sender.selectedSegment == 1 {
|
||||
if index >= (count - 1) {
|
||||
NSSound.beep()
|
||||
return
|
||||
}
|
||||
self.tabViewInfo.selectNextTabViewItem(nil)
|
||||
} else {
|
||||
if index <= 0 {
|
||||
NSSound.beep()
|
||||
return
|
||||
}
|
||||
self.tabViewInfo.selectPreviousTabViewItem(nil)
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func selectFuncTab(_ sender: NSSegmentedControl!) {
|
||||
self.tabViewFunc.selectTabViewItem(at: sender.indexOfSelectedItem)
|
||||
}
|
||||
|
||||
func tabView(_ tabView: NSTabView, didSelect tabViewItem: NSTabViewItem?) {
|
||||
if (tabViewItem != nil) {
|
||||
if let t = tabView as? LITabView {
|
||||
let position = CABasicAnimation(keyPath: "position")
|
||||
|
||||
if t.lastTabIndex > t.indexOfTabViewItem(tabViewItem!) {
|
||||
position.fromValue = NSValue(point: CGPoint(x: CGFloat(tabViewItem!.view!.frame.origin.x - 520), y: CGFloat(tabViewItem!.view!.frame.origin.y)))
|
||||
} else {
|
||||
position.fromValue = NSValue(point: CGPoint(x: CGFloat(tabViewItem!.view!.frame.origin.x + 520), y: CGFloat(tabViewItem!.view!.frame.origin.y)))
|
||||
}
|
||||
position.toValue = NSValue(point: CGPoint(x: CGFloat(tabViewItem!.view!.frame.origin.x), y: CGFloat(tabViewItem!.view!.frame.origin.y)))
|
||||
tabViewItem?.view?.layer?.add(position, forKey: "controlViewPosition")
|
||||
tabViewItem?.view?.animations = [
|
||||
"frameOrigin" : position
|
||||
]
|
||||
|
||||
tabViewItem?.view?.animator().frame.origin = CGPoint(x: CGFloat(tabViewItem!.view!.frame.origin.x), y: CGFloat(tabViewItem!.view!.frame.origin.y))
|
||||
t.lastTabIndex = t.indexOfTabViewItem(tabViewItem!)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Settings Window controller
|
||||
class SettingsWindowController: NSWindowController, NSWindowDelegate {
|
||||
@ -919,3 +1165,4 @@ class SettingsWindowController: NSWindowController, NSWindowDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -104,3 +104,13 @@ func findCloverHashCommit(at EFIdir: String) -> String? {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MARK: get image from CoreType.bundle
|
||||
func getCoreTypeImage(named: String, isTemplate: Bool) -> NSImage? {
|
||||
var image : NSImage? = nil
|
||||
if let ctb = Bundle.init(path: "/System/Library/CoreServices/CoreTypes.bundle") {
|
||||
image = NSImage(byReferencingFile: ctb.path(forResource: named, ofType: "icns", inDirectory: nil) ?? "")
|
||||
}
|
||||
image?.isTemplate = isTemplate
|
||||
return image
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Get Clover boot-log (or compatible)
|
||||
func dumpBootlog() -> String? {
|
||||
var root: io_registry_entry_t
|
||||
var bootLog: CFTypeRef? = nil
|
||||
@ -45,6 +46,7 @@ func dumpBootlog() -> String? {
|
||||
return log
|
||||
}
|
||||
|
||||
/// Get Find the Clover Revision from the boot-log
|
||||
func findCloverRevision() -> String? {
|
||||
let bdmesg = dumpBootlog()
|
||||
var rev : String? = nil
|
||||
@ -60,6 +62,20 @@ func findCloverRevision() -> String? {
|
||||
return rev
|
||||
}
|
||||
|
||||
/// Determine if We're booted with Clover (legay or UEFI)
|
||||
func bootByClover() -> Bool {
|
||||
let bdmesg = dumpBootlog()
|
||||
if (bdmesg != nil) {
|
||||
for line in bdmesg!.components(separatedBy: .newlines) {
|
||||
if (line.range(of: "Starting Clover revision: ") != nil) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/// Find the Clover hash commit (from the boot-log)
|
||||
func findCloverHash() -> String? {
|
||||
let bdmesg = dumpBootlog()
|
||||
var rev : String? = nil
|
||||
@ -76,6 +92,7 @@ func findCloverHash() -> String? {
|
||||
return rev
|
||||
}
|
||||
|
||||
/// Find the UUID of the partition boot device Clover starts from.
|
||||
func findBootPartitionDevice() -> String? {
|
||||
var bsd :String? = nil
|
||||
if let bdmesg : String = dumpBootlog() {
|
||||
@ -115,6 +132,7 @@ func findBootPartitionDevice() -> String? {
|
||||
return bsd
|
||||
}
|
||||
|
||||
/// Find the relative path of the config.plist loaded by Clover.
|
||||
func findConfigPath() -> String? {
|
||||
var path : String? = nil
|
||||
if let log : String = dumpBootlog() {
|
||||
@ -140,3 +158,43 @@ func findConfigPath() -> String? {
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
/// Struct for Start up Sound (name, output, index).
|
||||
struct SoundDevice {
|
||||
var name: String
|
||||
var output: String
|
||||
var index: Int
|
||||
}
|
||||
|
||||
/// Return an array of SoundDevice detected by Clover
|
||||
func getSoundDevices() -> [SoundDevice] {
|
||||
var devices = [SoundDevice]()
|
||||
if let bdmesg = dumpBootlog() {
|
||||
for line in bdmesg.components(separatedBy: .newlines) {
|
||||
// Found Audio Device IDT 92HD91BXX (Headphones) at index 0
|
||||
if (line.range(of: "Found Audio Device ") != nil && line.range(of: " at index ") != nil) {
|
||||
var name = line.components(separatedBy: "Found Audio Device ")[1].components(separatedBy: " at index")[0]
|
||||
let output = name.components(separatedBy: "(")[1].components(separatedBy: ")")[0]
|
||||
name = name.components(separatedBy: " (")[0]
|
||||
let index = line.components(separatedBy: " at index ")[1]
|
||||
if let i : Int = Int(index) {
|
||||
// print("\(name) at index \(i) (\(output))")
|
||||
if i >= 0 {
|
||||
var found = false // avoid duplicates
|
||||
for d in devices {
|
||||
if d.name == name && d.output == output && d.index == i {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
let sd = SoundDevice(name: name, output: output, index: i)
|
||||
devices.append(sd)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return devices
|
||||
}
|
||||
|
BIN
CloverApp/Clover/images/Speaker.png
Normal file
BIN
CloverApp/Clover/images/Speaker.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
@ -14,6 +14,8 @@
|
||||
953DBFDF236F037400B0C4FB /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 953DBFDE236F037400B0C4FB /* main.swift */; };
|
||||
954FF20E2371B13C00C3D94C /* DiskArbitration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 954FF20D2371B13C00C3D94C /* DiskArbitration.framework */; };
|
||||
954FF2102371B16300C3D94C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 954FF20F2371B16300C3D94C /* IOKit.framework */; };
|
||||
956034F623B7185B00E138D9 /* IO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 956034F523B7185A00E138D9 /* IO.swift */; };
|
||||
95A9A87E23B63F570060F1CA /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95A9A87D23B63F570060F1CA /* Constants.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
@ -25,6 +27,8 @@
|
||||
953DBFDE236F037400B0C4FB /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
|
||||
954FF20D2371B13C00C3D94C /* DiskArbitration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DiskArbitration.framework; path = System/Library/Frameworks/DiskArbitration.framework; sourceTree = SDKROOT; };
|
||||
954FF20F2371B16300C3D94C /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
|
||||
956034F523B7185A00E138D9 /* IO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = IO.swift; path = ../../Clover/IO.swift; sourceTree = "<group>"; };
|
||||
95A9A87D23B63F570060F1CA /* Constants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -61,6 +65,8 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
953DBFDE236F037400B0C4FB /* main.swift */,
|
||||
956034F523B7185A00E138D9 /* IO.swift */,
|
||||
95A9A87D23B63F570060F1CA /* Constants.swift */,
|
||||
953D98862377094A003B369E /* Disks.swift */,
|
||||
953B8DEF2370BB5C007E36E3 /* NVRAM.swift */,
|
||||
953B8DED2370BB1A007E36E3 /* bdmesg.swift */,
|
||||
@ -104,7 +110,7 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 1120;
|
||||
LastUpgradeCheck = 1120;
|
||||
LastUpgradeCheck = 1130;
|
||||
ORGANIZATIONNAME = CloverHackyColor;
|
||||
TargetAttributes = {
|
||||
953DBFDA236F037400B0C4FB = {
|
||||
@ -141,6 +147,8 @@
|
||||
953DBFDF236F037400B0C4FB /* main.swift in Sources */,
|
||||
953B8DF02370BB5D007E36E3 /* NVRAM.swift in Sources */,
|
||||
953B8DEE2370BB1A007E36E3 /* bdmesg.swift in Sources */,
|
||||
956034F623B7185B00E138D9 /* IO.swift in Sources */,
|
||||
95A9A87E23B63F570060F1CA /* Constants.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -265,6 +273,7 @@
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@ -287,6 +296,7 @@
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
GCC_WARN_UNUSED_VARIABLE = NO;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
|
20
CloverApp/CloverDaemonNew/CloverDaemonNew/Constants.swift
Normal file
20
CloverApp/CloverDaemonNew/CloverDaemonNew/Constants.swift
Normal file
@ -0,0 +1,20 @@
|
||||
//
|
||||
// Constants.swift
|
||||
// CloverDaemonNew
|
||||
//
|
||||
// Created by vector sigma on 26/12/2019.
|
||||
// Copyright © 2019 CloverHackyColor. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
let wrapperPath = "/Library/Application Support/Clover/CloverWrapper.sh"
|
||||
let frameworksPath = "/Library/Application Support/Clover/Frameworks"
|
||||
let loginWindowPath = "/var/root/Library/Preferences/com.apple.loginwindow.plist"
|
||||
let cloverLogOut = "/Library/Application Support/Clover/CloverLogOut"
|
||||
let cloverDaemonNewPath = "/Library/Application Support/Clover/CloverDaemonNew"
|
||||
let launchPlistPath = "/Library/LaunchDaemons/com.slice.CloverDaemonNew.plist"
|
||||
|
||||
let oldLaunchPlistPath = "/Library/LaunchDaemons/com.projectosx.clover.daemon.plist"
|
||||
let oldLaunchDaemonPath = "/Library/Application Support/Clover/CloverDaemon"
|
||||
let oldLogoutHookPath = "/Library/Application Support/Clover/CloverDaemon-stopservice"
|
@ -8,18 +8,11 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
let daemonVersion = "1.0.9"
|
||||
|
||||
let fm = FileManager.default
|
||||
let daemonVersion = "1.0.8"
|
||||
|
||||
let wrapperPath = "/Library/Application Support/Clover/CloverWrapper.sh"
|
||||
let frameworksPath = "/Library/Application Support/Clover/Frameworks"
|
||||
let loginWindowPath = "/var/root/Library/Preferences/com.apple.loginwindow.plist"
|
||||
let cloverLogOut = "/Library/Application Support/Clover/CloverLogOut"
|
||||
let cloverDaemonNewPath = "/Library/Application Support/Clover/CloverDaemonNew"
|
||||
let launchPlistPath = "/Library/LaunchDaemons/com.slice.CloverDaemonNew.plist"
|
||||
|
||||
let oldLaunchPlistPath = "/Library/LaunchDaemons/com.projectosx.clover.daemon.plist"
|
||||
|
||||
var mountRWCalled = fm.isWritableFile(atPath: "/")
|
||||
|
||||
func execAttr() -> [FileAttributeKey : Any] {
|
||||
var attributes = [FileAttributeKey : Any]()
|
||||
@ -55,15 +48,6 @@ func run(cmd: String) {
|
||||
task.launch()
|
||||
}
|
||||
|
||||
func doJob() {
|
||||
if let nvram = getNVRAM() {
|
||||
checkSleepProxyClient(nvram: nvram)
|
||||
} else {
|
||||
print("nvram not present in this machine.")
|
||||
}
|
||||
exit(EXIT_SUCCESS)
|
||||
}
|
||||
|
||||
func checkSleepProxyClient(nvram: NSDictionary) {
|
||||
let mDNSResponderPath = "/System/Library/LaunchDaemons/com.apple.mDNSResponder.plist"
|
||||
let disableOption = "-DisableSleepProxyClient"
|
||||
@ -72,17 +56,17 @@ func checkSleepProxyClient(nvram: NSDictionary) {
|
||||
|
||||
if let nvdata = nvram.object(forKey: "Clover.DisableSleepProxyClient") as? Data {
|
||||
value = String(decoding: nvdata, as: UTF8.self)
|
||||
print("Clover.DisableSleepProxyClient=\(value)")
|
||||
print("Clover.DisableSleepProxyClient=\(value).")
|
||||
} else {
|
||||
print("Clover.DisableSleepProxyClient is not set.")
|
||||
}
|
||||
|
||||
if !fm.fileExists(atPath: mDNSResponderPath) {
|
||||
print("Error: cannot found \(mDNSResponderPath)")
|
||||
print("Error: cannot found \(mDNSResponderPath).")
|
||||
return
|
||||
}
|
||||
if !fm.isWritableFile(atPath: "/") {
|
||||
print("Cannot go ahead as / is read-only")
|
||||
print("Note: root filesystem is read-only.")
|
||||
return
|
||||
}
|
||||
|
||||
@ -132,40 +116,123 @@ func getLogOutHook() -> String? {
|
||||
}
|
||||
|
||||
func removeCloverRCScripts() {
|
||||
let oldFiles : [String] = ["/etc/rc.boot.d/10.save_and_rotate_boot_log.local",
|
||||
"/etc/rc.boot.d/20.mount_ESP.local",
|
||||
"/etc/rc.boot.d/70.disable_sleep_proxy_client.local.disabled",
|
||||
"/etc/rc.boot.d/70.disable_sleep_proxy_client.local",
|
||||
"/etc/rc.clover.lib",
|
||||
"/etc/rc.shutdown.d/80.save_nvram_plist.local",
|
||||
oldLaunchDaemonPath,
|
||||
oldLaunchPlistPath,
|
||||
oldLogoutHookPath]
|
||||
|
||||
if fm.fileExists(atPath: oldLaunchPlistPath) {
|
||||
print("unloading old CloverDaemon..")
|
||||
run(cmd: "launchctl unload \(oldLaunchPlistPath)")
|
||||
try? fm.removeItem(atPath: oldLaunchPlistPath)
|
||||
if fm.fileExists(atPath: "/Library/Application Support/Clover/CloverDaemon") {
|
||||
try? fm.removeItem(atPath: "/Library/Application Support/Clover/CloverDaemon")
|
||||
}
|
||||
|
||||
if fm.fileExists(atPath: "/Library/Application Support/Clover/CloverDaemon-stopservice") {
|
||||
try? fm.removeItem(atPath: "/Library/Application Support/Clover/CloverDaemon-stopservice")
|
||||
}
|
||||
}
|
||||
|
||||
let oldRCScripts : [String] = ["/etc/rc.boot.d/10.save_and_rotate_boot_log.local",
|
||||
"/etc/rc.boot.d/20.mount_ESP.local",
|
||||
"/etc/rc.boot.d/70.disable_sleep_proxy_client.local.disabled",
|
||||
"/etc/rc.boot.d/70.disable_sleep_proxy_client.local",
|
||||
"/etc/rc.clover.lib",
|
||||
"/etc/rc.shutdown.d/80.save_nvram_plist.local"];
|
||||
|
||||
for rc in oldRCScripts {
|
||||
if fm.fileExists(atPath: rc) {
|
||||
for f in oldFiles {
|
||||
if fm.fileExists(atPath: f) {
|
||||
if !fm.isWritableFile(atPath: "/") {
|
||||
run(cmd: "mount -uw /")
|
||||
sleep(2)
|
||||
sleep(3)
|
||||
}
|
||||
print("Removing \(rc).")
|
||||
print("Removing \(f).")
|
||||
do {
|
||||
try fm.removeItem(atPath: rc)
|
||||
try fm.removeItem(atPath: f)
|
||||
} catch {
|
||||
print(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if getLogOutHook() == oldLogoutHookPath {
|
||||
print("Removing old logoutHook (\(oldLogoutHookPath))..")
|
||||
run(cmd: "defaults delete com.apple.loginwindow LogoutHook")
|
||||
}
|
||||
}
|
||||
|
||||
func installHook() {
|
||||
print("Installing the LogoutHook..")
|
||||
// if a hook exist and is not our one, then add a wrapper
|
||||
if let loh = getLogOutHook() {
|
||||
if loh != cloverLogOut {
|
||||
if fm.fileExists(atPath: loh) {
|
||||
let wrapper =
|
||||
"""
|
||||
#!/bin/sh
|
||||
|
||||
'\(cloverLogOut)'
|
||||
|
||||
# This file is automatically generated by CloverDaemonNew because
|
||||
# it has detected you added a logout script somewhere else.
|
||||
# if you edit this file, be aware that if you start to boot in UEFI
|
||||
# CloverDaemonNew will take care to restore your custom logout script,
|
||||
# but your script must be the last line to be detected again.
|
||||
# The script path must be escaped within '' if contains spaces in the middle.
|
||||
# NOTE: if your will is to add multiple scripts, please add them to
|
||||
# the following script (and so not in this script):
|
||||
|
||||
'\(loh)'
|
||||
"""
|
||||
print("Detected user logout hook at \(loh), merging it with CloverLogOut in CloverWrapper.sh.")
|
||||
do {
|
||||
try wrapper.write(toFile: wrapperPath, atomically: false, encoding: .utf8)
|
||||
try fm.setAttributes(execAttr(), ofItemAtPath: wrapperPath)
|
||||
|
||||
run(cmd: "defaults write com.apple.loginwindow LogoutHook '\(wrapperPath)'")
|
||||
} catch {
|
||||
print(error)
|
||||
}
|
||||
} else {
|
||||
print("Detected user logout hook at \(loh), but the executable did not exist, installing our.")
|
||||
run(cmd: "defaults write com.apple.loginwindow LogoutHook '\(cloverLogOut)'")
|
||||
}
|
||||
} else {
|
||||
print("LogoutHook is already set.")
|
||||
}
|
||||
} else {
|
||||
print("LogoutHook is not set, writing it.")
|
||||
run(cmd: "defaults write com.apple.loginwindow LogoutHook '\(cloverLogOut)'")
|
||||
}
|
||||
}
|
||||
|
||||
func unInstallHook() {
|
||||
// what to do? remove the logout hook if it's our
|
||||
var uninstall = false
|
||||
if let loh = getLogOutHook() {
|
||||
if (loh == cloverLogOut || loh == oldLogoutHookPath){
|
||||
// it is CloverLogOut
|
||||
print("Removing CloverLogOut hook as EmuVariableUefiPresent doesn't exixts.")
|
||||
uninstall = true
|
||||
} else if loh == wrapperPath {
|
||||
print("Removing CloverWrapper.sh logout hook as EmuVariableUefiPresent doesn't exixts.")
|
||||
// it is CloverWrapper.sh. We have to mantain user script!
|
||||
// get the user script path:
|
||||
var scriptPath : String? = nil
|
||||
if let lines = try? String(contentsOf: URL(fileURLWithPath: wrapperPath),
|
||||
encoding: .utf8).components(separatedBy: .newlines) {
|
||||
if lines.count > 0 {
|
||||
scriptPath = lines.last
|
||||
}
|
||||
}
|
||||
|
||||
if scriptPath != nil {
|
||||
if fm.fileExists(atPath: scriptPath!) {
|
||||
print("..but taking user logout hook script at \(scriptPath!).")
|
||||
run(cmd: "defaults write com.apple.loginwindow LogoutHook \(scriptPath!)")
|
||||
} else {
|
||||
uninstall = true
|
||||
}
|
||||
} else {
|
||||
uninstall = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if uninstall {
|
||||
run(cmd: "defaults delete com.apple.loginwindow LogoutHook")
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
@ -222,8 +289,9 @@ func main() {
|
||||
}
|
||||
|
||||
// check options in nvram
|
||||
var mountRWCalled = fm.isWritableFile(atPath: "/")
|
||||
|
||||
let fv = getFirmawareVendor() ?? "unknown"
|
||||
var needsLogoutHook = isLegacyFirmware()
|
||||
print("Firmware vendor is '\(fv)'.")
|
||||
if let nvram = getNVRAM() {
|
||||
if let nvdata = nvram.object(forKey: "Clover.RootRW") as? Data {
|
||||
let value = String(decoding: nvdata, as: UTF8.self)
|
||||
@ -235,80 +303,16 @@ func main() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// using the logout Hook only if EmuVariableUefiPresent
|
||||
let loh = getLogOutHook()
|
||||
|
||||
if (nvram.object(forKey: "EmuVariableUefiPresent") != nil ||
|
||||
nvram.object(forKey: "TestEmuVariableUefiPresent") != nil) {
|
||||
|
||||
// if a hook exist and is not our one, then add a wrapper
|
||||
if (loh != nil) {
|
||||
if loh! != cloverLogOut && fm.fileExists(atPath: loh!) {
|
||||
let wrapper =
|
||||
"""
|
||||
#!/bin/sh
|
||||
|
||||
'\(cloverLogOut)'
|
||||
|
||||
# This file is automatically generated by CloverDaemonNew because
|
||||
# it has detected you added a logout script somewhere else.
|
||||
# if you edit this file, be aware that if you start to boot in UEFI
|
||||
# CloverDaemonNew will take care to restore your custom logout script,
|
||||
# but your script must be the last line to be detected again.
|
||||
# The script path must be escaped within '' if contains spaces in the middle.
|
||||
# NOTE: if your will is to add multiple scripts, please add them to
|
||||
# the following script (and so not in this script):
|
||||
|
||||
'\(loh!)'
|
||||
"""
|
||||
print("Detected user logout hook at \(loh!), merging with it with CloverLogOut in CloverWrapper.sh.")
|
||||
do {
|
||||
try wrapper.write(toFile: wrapperPath, atomically: false, encoding: .utf8)
|
||||
try fm.setAttributes(execAttr(), ofItemAtPath: wrapperPath)
|
||||
|
||||
run(cmd: "defaults write com.apple.loginwindow LogoutHook '\(wrapperPath)'")
|
||||
} catch {
|
||||
print(error)
|
||||
}
|
||||
} else {
|
||||
run(cmd: "defaults write com.apple.loginwindow LogoutHook '\(cloverLogOut)'")
|
||||
}
|
||||
|
||||
|
||||
if !needsLogoutHook {
|
||||
if (nvram.object(forKey: "EmuVariableUefiPresent") != nil ||
|
||||
nvram.object(forKey: "TestEmuVariableUefiPresent") != nil) {
|
||||
print("Found EmuVariableUefiPresent in NVRAM.")
|
||||
needsLogoutHook = true
|
||||
} else {
|
||||
run(cmd: "defaults write com.apple.loginwindow LogoutHook '\(cloverLogOut)'")
|
||||
}
|
||||
|
||||
if !fm.isWritableFile(atPath: "/") {
|
||||
if !mountRWCalled {
|
||||
print("making '/' writable as EmuVariableUefiPresent is present to save nvram.")
|
||||
}
|
||||
run(cmd: "mount -uw /")
|
||||
}
|
||||
} else {
|
||||
// what to do? remove the logout hook if it's our
|
||||
if (loh != nil) {
|
||||
if loh! == cloverLogOut {
|
||||
// it is CloverLogOut
|
||||
print("Removing CloverLogOut hook as EmuVariable is no longer present.")
|
||||
run(cmd: "defaults delete com.apple.loginwindow LogoutHook")
|
||||
} else if loh! == wrapperPath {
|
||||
print("Removing CloverWrapper.sh logout hook as EmuVariable is no longer present.")
|
||||
// it is CloverWrapper.sh. We have to mantain user script!
|
||||
// get the user script path:
|
||||
var script : String? = nil
|
||||
if let lines = try? String(contentsOf: URL(fileURLWithPath: wrapperPath),
|
||||
encoding: .utf8).components(separatedBy: .newlines) {
|
||||
if lines.count > 0 {
|
||||
script = lines.last
|
||||
}
|
||||
}
|
||||
if script != nil {
|
||||
print("..but taking user logout hook script at \(script!).")
|
||||
run(cmd: "defaults write com.apple.loginwindow LogoutHook \(script!)")
|
||||
} else {
|
||||
run(cmd: "defaults delete com.apple.loginwindow LogoutHook")
|
||||
}
|
||||
}
|
||||
print("EmuVariableUefiPresent doesn't exist.")
|
||||
}
|
||||
}
|
||||
|
||||
@ -409,6 +413,12 @@ func main() {
|
||||
} else {
|
||||
print("Error: nvram not present in this System.")
|
||||
}
|
||||
|
||||
if needsLogoutHook {
|
||||
installHook()
|
||||
} else {
|
||||
unInstallHook()
|
||||
}
|
||||
|
||||
print("Logout hook is: \(getLogOutHook() ?? "none")")
|
||||
signal(SIGTERM, SIG_IGN) //preferred
|
||||
@ -417,7 +427,12 @@ func main() {
|
||||
now = df.string(from: Date())
|
||||
print("")
|
||||
print("SIGTERM received at \(now)")
|
||||
doJob()
|
||||
if let nvram = getNVRAM() {
|
||||
checkSleepProxyClient(nvram: nvram)
|
||||
} else {
|
||||
print("nvram not present in this machine.")
|
||||
}
|
||||
exit(EXIT_SUCCESS)
|
||||
}
|
||||
sigtermSource.resume()
|
||||
|
||||
@ -467,10 +482,11 @@ if CommandLine.arguments.contains("--install") {
|
||||
ofItemAtPath: cloverDaemonNewPath)
|
||||
|
||||
|
||||
let logouthookSrc = myPath.deletingLastPath.addPath("CloverLogOut")
|
||||
let logouthookSrc = myPath.deletingLastPath.addPath(cloverLogOut.lastPath)
|
||||
if fm.fileExists(atPath: cloverLogOut) {
|
||||
try fm.removeItem(atPath: cloverLogOut)
|
||||
}
|
||||
|
||||
if fm.fileExists(atPath: logouthookSrc) {
|
||||
try fm.copyItem(atPath: logouthookSrc,
|
||||
toPath: cloverLogOut)
|
||||
@ -478,6 +494,22 @@ if CommandLine.arguments.contains("--install") {
|
||||
ofItemAtPath: cloverLogOut)
|
||||
}
|
||||
|
||||
var needsLogoutHook = isLegacyFirmware()
|
||||
if !needsLogoutHook {
|
||||
if let nvram = getNVRAM() {
|
||||
if (nvram.object(forKey: "EmuVariableUefiPresent") != nil ||
|
||||
nvram.object(forKey: "TestEmuVariableUefiPresent") != nil) {
|
||||
needsLogoutHook = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if needsLogoutHook {
|
||||
installHook()
|
||||
} else {
|
||||
unInstallHook()
|
||||
}
|
||||
|
||||
try fm.setAttributes(launchAttr(), ofItemAtPath: launchPlistPath)
|
||||
if fm.fileExists(atPath: launchPlistPath) {
|
||||
run(cmd: "launchctl unload \(launchPlistPath)")
|
||||
@ -511,6 +543,8 @@ if CommandLine.arguments.contains("--install") {
|
||||
if fm.fileExists(atPath: frameworksPath) {
|
||||
try fm.removeItem(atPath: frameworksPath)
|
||||
}
|
||||
|
||||
unInstallHook()
|
||||
exit(EXIT_SUCCESS)
|
||||
} catch {
|
||||
print(error)
|
||||
|
@ -14,6 +14,7 @@
|
||||
95524B8E2380522A005F6425 /* bdmesg.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95524B8D2380522A005F6425 /* bdmesg.swift */; };
|
||||
95524B9023805233005F6425 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95524B8F23805232005F6425 /* Extensions.swift */; };
|
||||
955F7C70238DCD440019D088 /* DiskArbitration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 955F7C6F238DCD440019D088 /* DiskArbitration.framework */; };
|
||||
95CD16DF23B7A01500303BDB /* IO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95CD16DE23B7A01500303BDB /* IO.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
@ -37,6 +38,7 @@
|
||||
95524B8D2380522A005F6425 /* bdmesg.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = bdmesg.swift; path = ../../Clover/bdmesg.swift; sourceTree = "<group>"; };
|
||||
95524B8F23805232005F6425 /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Extensions.swift; path = ../../Clover/Extensions.swift; sourceTree = "<group>"; };
|
||||
955F7C6F238DCD440019D088 /* DiskArbitration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DiskArbitration.framework; path = System/Library/Frameworks/DiskArbitration.framework; sourceTree = SDKROOT; };
|
||||
95CD16DE23B7A01500303BDB /* IO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = IO.swift; path = ../../Clover/IO.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -72,6 +74,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
95524B7C238051AC005F6425 /* main.swift */,
|
||||
95CD16DE23B7A01500303BDB /* IO.swift */,
|
||||
954BBE962381964F0032425F /* Shared.swift */,
|
||||
95524B8923805210005F6425 /* NVRAM.swift */,
|
||||
95524B8B2380521D005F6425 /* Disks.swift */,
|
||||
@ -152,6 +155,7 @@
|
||||
95524B8A23805210005F6425 /* NVRAM.swift in Sources */,
|
||||
95524B8E2380522A005F6425 /* bdmesg.swift in Sources */,
|
||||
95524B7D238051AC005F6425 /* main.swift in Sources */,
|
||||
95CD16DF23B7A01500303BDB /* IO.swift in Sources */,
|
||||
95524B8C2380521D005F6425 /* Disks.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
let cmdVersion = "1.0.3"
|
||||
let cmdVersion = "1.0.4"
|
||||
let savedNVRAMPath = "/tmp/NVRAM_saved"
|
||||
let NVRAMSavedToRoot = "/tmp/NVRAM_savedToRoot"
|
||||
|
||||
@ -45,24 +45,6 @@ func run(cmd: String) {
|
||||
}
|
||||
|
||||
func saveNVRAM(nvram: NSMutableDictionary, volume: String) {
|
||||
/*
|
||||
if (nvram.object(forKey: "efi-backup-boot-device") != nil) {
|
||||
nvram.removeObject(forKey: "efi-backup-boot-device")
|
||||
}
|
||||
|
||||
if (nvram.object(forKey: "efi-backup-boot-device-data") != nil) {
|
||||
nvram.removeObject(forKey: "efi-backup-boot-device-data")
|
||||
}
|
||||
|
||||
if (nvram.object(forKey: "install-product-url") != nil) {
|
||||
nvram.removeObject(forKey: "install-product-url")
|
||||
}
|
||||
|
||||
if (nvram.object(forKey: "previous-system-uuid") != nil) {
|
||||
nvram.removeObject(forKey: "previous-system-uuid")
|
||||
}
|
||||
*/
|
||||
|
||||
let bsdname = getBSDName(of: volume) ?? ""
|
||||
let uuid = getVolumeUUID(from: bsdname) ?? kNotAvailable
|
||||
if nvram.write(toFile: volume.addPath("nvram.plist"), atomically: false) {
|
||||
@ -112,118 +94,113 @@ func main() {
|
||||
df.locale = Locale(identifier: "en_US")
|
||||
var now = df.string(from: Date())
|
||||
log("- CloverLogOut v\(cmdVersion): logout begin at \(now)")
|
||||
|
||||
if let nvram = getNVRAM() {
|
||||
// Check if we're running from CloverEFI
|
||||
if (nvram.object(forKey: "EmuVariableUefiPresent") != nil ||
|
||||
nvram.object(forKey: "TestEmuVariableUefiPresent") != nil) {
|
||||
|
||||
// we already saved once? Check if the nvram is changed
|
||||
if fm.fileExists(atPath: savedNVRAMPath) {
|
||||
if let old = NSDictionary(contentsOfFile: savedNVRAMPath) {
|
||||
if nvram.isEqual(to: old) {
|
||||
/*
|
||||
We are going to exit but if the nvram is already saved
|
||||
and is saved in the ESP, then remove /.nvram.plist
|
||||
*/
|
||||
if !fm.fileExists(atPath: NVRAMSavedToRoot) {
|
||||
if fm.fileExists(atPath: "/nvram.plist") {
|
||||
do {
|
||||
try fm.removeItem(atPath: "/nvram.plist")
|
||||
} catch {
|
||||
log("\(error)")
|
||||
}
|
||||
// we already saved once? Check if the nvram is changed
|
||||
if fm.fileExists(atPath: savedNVRAMPath) {
|
||||
if let old = NSDictionary(contentsOfFile: savedNVRAMPath) {
|
||||
if nvram.isEqual(to: old) {
|
||||
/*
|
||||
We are going to exit but if the nvram is already saved
|
||||
and is saved in the ESP, then remove /.nvram.plist
|
||||
*/
|
||||
if !fm.fileExists(atPath: NVRAMSavedToRoot) {
|
||||
if fm.fileExists(atPath: "/nvram.plist") {
|
||||
do {
|
||||
try fm.removeItem(atPath: "/nvram.plist")
|
||||
} catch {
|
||||
log("\(error)")
|
||||
}
|
||||
}
|
||||
log("nvram not changed, nothing to do.") // hope user didn't delete it :-)
|
||||
log("- CloverLogOut: end at \(now)")
|
||||
exit(EXIT_SUCCESS)
|
||||
}
|
||||
log("nvram not changed, nothing to do.") // hope user didn't delete it :-)
|
||||
log("- CloverLogOut: end at \(now)")
|
||||
exit(EXIT_SUCCESS)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var disk : String? = nil
|
||||
var espList = [String]()
|
||||
|
||||
/* find all internal ESP in the System as we don't want
|
||||
to save the nvram in a USB pen drive (user will lost the nvram if not plugged in)
|
||||
*/
|
||||
for esp in getAllESPs() {
|
||||
if isInternalDevice(diskOrMtp: esp) {
|
||||
espList.append(esp)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var disk : String? = nil
|
||||
var espList = [String]()
|
||||
|
||||
/* find all internal ESP in the System as we don't want
|
||||
to save the nvram in a USB pen drive (user will lost the nvram if not plugged in)
|
||||
*/
|
||||
for esp in getAllESPs() {
|
||||
if isInternalDevice(diskOrMtp: esp) {
|
||||
espList.append(esp)
|
||||
}
|
||||
|
||||
// find the boot partition device and check if it is a ESP
|
||||
if let bd = findBootPartitionDevice() {
|
||||
if espList.contains(bd) {
|
||||
// boot device is a ESP :-)
|
||||
disk = bd
|
||||
log("Detected ESP \(bd) as boot device.")
|
||||
}
|
||||
}
|
||||
|
||||
// find the boot partition device and check if it is a ESP
|
||||
if let bd = findBootPartitionDevice() {
|
||||
if espList.contains(bd) {
|
||||
// boot device is a ESP :-)
|
||||
disk = bd
|
||||
log("Detected ESP \(bd) as boot device.")
|
||||
}
|
||||
|
||||
if (disk == nil) {
|
||||
// boot device not found
|
||||
if espList.count > 0 {
|
||||
// we have an internal ESP, using that
|
||||
disk = espList[0]
|
||||
log("Will use ESP \(disk!) as boot device is not found.")
|
||||
} else {
|
||||
// use root
|
||||
disk = getBSDName(of: "/")
|
||||
log("Will use / as no boot device nor an internal ESP are found.")
|
||||
}
|
||||
}
|
||||
|
||||
if (disk != nil) {
|
||||
// get the mount point or mount it
|
||||
var mounted : Bool = false
|
||||
if let mp = getMountPoint(from: disk!) {
|
||||
log("\(disk!) was already mounted.")
|
||||
saveNVRAM(nvram: nvram, volume: mp)
|
||||
if espList.contains(disk!) {
|
||||
disableInsexing(for: mp)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if !mounted {
|
||||
log("mounting \(disk!)..")
|
||||
mount(disk: disk!, at: nil) { (result) in
|
||||
if result == true {
|
||||
sleep(1)
|
||||
var attempts = 0
|
||||
repeat {
|
||||
attempts+=1
|
||||
if let mp = getMountPoint(from: disk!) {
|
||||
mounted = true
|
||||
saveNVRAM(nvram: nvram, volume: mp)
|
||||
if espList.contains(disk!) {
|
||||
disableInsexing(for: mp)
|
||||
}
|
||||
sleep(1)
|
||||
umount(disk: disk!, force: true)
|
||||
break
|
||||
}
|
||||
} while (mounted || attempts == 5)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !mounted {
|
||||
log("mount failed for \(disk!).")
|
||||
saveNVRAM(nvram: nvram, volume: "/")
|
||||
}
|
||||
}
|
||||
|
||||
if (disk == nil) {
|
||||
// boot device not found
|
||||
if espList.count > 0 {
|
||||
// we have an internal ESP, using that
|
||||
disk = espList[0]
|
||||
log("Will use ESP on \(disk!) as boot device is not found (or is not internal).")
|
||||
} else {
|
||||
// CloverDaemonNew should have made the fs read-write for us.
|
||||
// use root
|
||||
disk = getBSDName(of: "/")
|
||||
log("Will use / as nor the boot device nor an internal ESP was found.")
|
||||
}
|
||||
}
|
||||
|
||||
if (disk != nil) {
|
||||
// get the mount point or mount it
|
||||
var mounted : Bool = false
|
||||
if let mp = getMountPoint(from: disk!) {
|
||||
log("\(disk!) was already mounted.")
|
||||
saveNVRAM(nvram: nvram, volume: mp)
|
||||
if espList.contains(disk!) {
|
||||
disableInsexing(for: mp)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if !mounted {
|
||||
log("mounting \(disk!)..")
|
||||
mount(disk: disk!, at: nil) { (result) in
|
||||
if result == true {
|
||||
sleep(1)
|
||||
var attempts = 0
|
||||
repeat {
|
||||
attempts+=1
|
||||
if let mp = getMountPoint(from: disk!) {
|
||||
mounted = true
|
||||
saveNVRAM(nvram: nvram, volume: mp)
|
||||
if espList.contains(disk!) {
|
||||
disableInsexing(for: mp)
|
||||
}
|
||||
sleep(1)
|
||||
umount(disk: disk!, force: true)
|
||||
break
|
||||
}
|
||||
} while (mounted || attempts == 5)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !mounted {
|
||||
log("mount failed for \(disk!).")
|
||||
saveNVRAM(nvram: nvram, volume: "/")
|
||||
}
|
||||
} else {
|
||||
log("EmuVariableUefi is not present, nvram will not be saved.")
|
||||
// CloverDaemonNew should have made the fs read-write for us.
|
||||
saveNVRAM(nvram: nvram, volume: "/")
|
||||
}
|
||||
|
||||
} else {
|
||||
log("Error: non nvram to be saved.")
|
||||
log("Error: no nvram to be saved.")
|
||||
}
|
||||
|
||||
now = df.string(from: Date())
|
||||
|
@ -91,7 +91,7 @@
|
||||
956A7AA7238DAD700012F6B0 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 1120;
|
||||
LastUpgradeCheck = 1130;
|
||||
ORGANIZATIONNAME = CloverHackyColor;
|
||||
TargetAttributes = {
|
||||
956A7AAE238DAD700012F6B0 = {
|
||||
@ -267,6 +267,7 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = CloverRunAtLogin/CloverRunAtLogin.entitlements;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
INFOPLIST_FILE = CloverRunAtLogin/Info.plist;
|
||||
@ -284,6 +285,7 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = CloverRunAtLogin/CloverRunAtLogin.entitlements;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
INFOPLIST_FILE = CloverRunAtLogin/Info.plist;
|
||||
|
@ -16,6 +16,8 @@
|
||||
"Current Clover revision" = "Aktuelle Clover revision";
|
||||
"Boot Device:" = "Boot Device:";
|
||||
"config path:" = "Config.plist Pfad:";
|
||||
"Installation succeded" = "Installation succeded";
|
||||
"Installation failed" = "Installation failed";
|
||||
|
||||
"Clover wants to mount %@" = "Clover möchte %@ mounten";
|
||||
"Clover wants to umount %@" = "Clover möchte %@ unmounten";
|
||||
@ -24,6 +26,26 @@
|
||||
"mount point" = "mount point";
|
||||
"*auto mount" = "*auto mount";
|
||||
|
||||
"System Serial Number:" = "System Serial Number:";
|
||||
"Model:" = "Model:";
|
||||
"board-id:" = "board-id:";
|
||||
"OEM Vendor:" = "OEM Vendor:";
|
||||
"OEM Product:" = "OEM Product:";
|
||||
"OEM Board:" = "OEM Board:";
|
||||
"NVRAM is native:" = "NVRAM is native:";
|
||||
"unknown" = "unknown";
|
||||
"Yes" = "Yes";
|
||||
"No" = "No";
|
||||
|
||||
"Startup Sound" = "Startup Sound";
|
||||
"Device:" = "Device:";
|
||||
"Volume level:" = "Volume level:";
|
||||
"LineOut" = "Line Out";
|
||||
"Speaker" = "Speaker";
|
||||
"Headphones" = "Headphones";
|
||||
"Garniture" = "Garniture";
|
||||
"Other" = "Other";
|
||||
|
||||
"true" = "Wahr";
|
||||
"false" = "Falsch";
|
||||
|
||||
@ -39,6 +61,7 @@
|
||||
"Uninstall CloverDaemonNew" = "CloverDaemonNew deinstallieren";
|
||||
|
||||
"Update" = "Update";
|
||||
"Download" = "Download";
|
||||
"Update to r%d" = "Auf Version r%d aktualisieren"; // "Update to r5101"
|
||||
"Check update:" = "Auf Update prüfen:";
|
||||
"Check now" = "Jetzt prüfen";
|
||||
|
@ -16,6 +16,8 @@
|
||||
"Current Clover revision" = "Current Clover revision";
|
||||
"Boot Device:" = "Boot Device:";
|
||||
"config path:" = "config path:";
|
||||
"Installation succeded" = "Installation succeded";
|
||||
"Installation failed" = "Installation failed";
|
||||
|
||||
"Clover wants to mount %@" = "Clover wants to mount %@";
|
||||
"Clover wants to umount %@" = "Clover wants to umount %@";
|
||||
@ -24,6 +26,26 @@
|
||||
"mount point" = "mount point";
|
||||
"*auto mount" = "*auto mount";
|
||||
|
||||
"System Serial Number:" = "System Serial Number:";
|
||||
"Model:" = "Model:";
|
||||
"board-id:" = "board-id:";
|
||||
"OEM Vendor:" = "OEM Vendor:";
|
||||
"OEM Product:" = "OEM Product:";
|
||||
"OEM Board:" = "OEM Board:";
|
||||
"NVRAM is native:" = "NVRAM is native:";
|
||||
"unknown" = "unknown";
|
||||
"Yes" = "Yes";
|
||||
"No" = "No";
|
||||
|
||||
"Startup Sound" = "Startup Sound";
|
||||
"Device:" = "Device:";
|
||||
"Volume level:" = "Volume level:";
|
||||
"LineOut" = "Line Out";
|
||||
"Speaker" = "Speaker";
|
||||
"Headphones" = "Headphones";
|
||||
"Garniture" = "Garniture";
|
||||
"Other" = "Other";
|
||||
|
||||
"true" = "true";
|
||||
"false" = "false";
|
||||
|
||||
@ -39,6 +61,7 @@
|
||||
"Uninstall CloverDaemonNew" = "Uninstall CloverDaemonNew";
|
||||
|
||||
"Update" = "Update";
|
||||
"Download" = "Download";
|
||||
"Update to r%d" = "Update to r%d"; // "Update to r5101"
|
||||
"Check update:" = "Check update:";
|
||||
"Check now" = "Check now";
|
||||
@ -71,7 +94,7 @@ Can also be use if you don't want to upgrade MBR or PBR sectors.";
|
||||
"Clover legacy BIOS boot sectors" = "Clover EFI requires three essential files. (in simple terms)
|
||||
boot0 (On the drive's MBR) responsible for loading boot1.
|
||||
boot1 (On the partition's boot-sector) to finding boot2.
|
||||
boot2 (On the partition's root directory) for loading /EFI/CLOVER/CLOVERIA32.efi or CLOVERX64.efi, and kernel etc.";
|
||||
boot2 (On the partition's root directory) for loading CLOVERX64.efi, and kernel etc.";
|
||||
|
||||
"boot0af" = "Used for BIOS booting on BIOS motherboards.
|
||||
boot0af (boot0 Active First) bootloader try to boot the active partition defined in MBR. If there is no active partition, it will try to boot the first EFI/FAT32/HFS partition (defined in the MBR and then the GPT) with a valid PBR signature.
|
||||
@ -128,7 +151,7 @@ Volume and Audio device (for supported IOAudio devices only).";
|
||||
|
||||
"FirmwareVolume.efi" = "Create FirmwareVolume with cursor images for FileVault2.";
|
||||
|
||||
"FSInject.efi" = "Provide injection of kernel extensions from Clover folder.";
|
||||
"FSInject.efi" = "Provide injection of kernel extensions from Clover folder and allow to force load them from both /System/Library/Extensions and /Library/Extensions.";
|
||||
|
||||
"GrubEXFAT.efi" = "ExFAT filesystem driver from GRUB.";
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
"Current Clover revision" = "Current Clover revision";
|
||||
"Boot device:" = "Boot Device:";
|
||||
"config path:" = "config path:";
|
||||
"Installation succeded" = "Installation succeded";
|
||||
"Installation failed" = "Installation failed";
|
||||
|
||||
"Clover wants to mount %@" = "Clover wants to mount %@";
|
||||
"Clover wants to umount %@" = "Clover wants to umount %@";
|
||||
@ -24,6 +26,26 @@
|
||||
"mount point" = "mount point";
|
||||
"*auto mount" = "*auto mount";
|
||||
|
||||
"System Serial Number:" = "System Serial Number:";
|
||||
"Model:" = "Model:";
|
||||
"board-id:" = "board-id:";
|
||||
"OEM Vendor:" = "OEM Vendor:";
|
||||
"OEM Product:" = "OEM Product:";
|
||||
"OEM Board:" = "OEM Board:";
|
||||
"NVRAM is native:" = "NVRAM is native:";
|
||||
"unknown" = "unknown";
|
||||
"Yes" = "Yes";
|
||||
"No" = "No";
|
||||
|
||||
"Startup Sound" = "Startup Sound";
|
||||
"Device:" = "Device:";
|
||||
"Volume level:" = "Volume level:";
|
||||
"LineOut" = "Line Out";
|
||||
"Speaker" = "Speaker";
|
||||
"Headphones" = "Headphones";
|
||||
"Garniture" = "Garniture";
|
||||
"Other" = "Other";
|
||||
|
||||
"true" = "true";
|
||||
"false" = "false";
|
||||
|
||||
@ -39,6 +61,7 @@
|
||||
"Uninstall CloverDaemonNew" = "Uninstall CloverDaemonNew";
|
||||
|
||||
"Update" = "Update";
|
||||
"Download" = "Download";
|
||||
"Update to r%d" = "Update to r%d"; // "Update to r5101"
|
||||
"Check update:" = "Check update:";
|
||||
"Check now" = "Check now";
|
||||
|
@ -16,6 +16,8 @@
|
||||
"Current Clover revision" = "Version actuelle de Clover";
|
||||
"Boot Device:" = "Périphérique De Démarrage:";
|
||||
"config path:" = "voie d'acces vers config:";
|
||||
"Installation succeded" = "Installation succeded";
|
||||
"Installation failed" = "Installation failed";
|
||||
|
||||
"Clover wants to mount %@" = "Clover desire monter %@";
|
||||
"Clover wants to umount %@" = "Clover desire démonter %@";
|
||||
@ -24,6 +26,26 @@
|
||||
"mount point" = "point d'acces";
|
||||
"*auto mount" = "*monter automatiquement";
|
||||
|
||||
"System Serial Number:" = "System Serial Number:";
|
||||
"Model:" = "Model:";
|
||||
"board-id:" = "board-id:";
|
||||
"OEM Vendor:" = "OEM Vendor:";
|
||||
"OEM Product:" = "OEM Product:";
|
||||
"OEM Board:" = "OEM Board:";
|
||||
"NVRAM is native:" = "NVRAM is native:";
|
||||
"unknown" = "unknown";
|
||||
"Yes" = "Yes";
|
||||
"No" = "No";
|
||||
|
||||
"Startup Sound" = "Startup Sound";
|
||||
"Device:" = "Device:";
|
||||
"Volume level:" = "Volume level:";
|
||||
"LineOut" = "Line Out";
|
||||
"Speaker" = "Speaker";
|
||||
"Headphones" = "Headphones";
|
||||
"Garniture" = "Garniture";
|
||||
"Other" = "Other";
|
||||
|
||||
"true" = "vrai";
|
||||
"false" = "faux";
|
||||
|
||||
@ -39,6 +61,7 @@
|
||||
"Uninstall CloverDaemonNew" = "Desinstaller CloverDaemonNew";
|
||||
|
||||
"Update" = "Mise à jour";
|
||||
"Download" = "Download";
|
||||
"Update to r%d" = "Mise à jour de r%d"; // "Update to r5101"
|
||||
"Check update:" = "Verifier mise à jour:";
|
||||
"Check now" = "Verifier maintenant";
|
||||
|
@ -16,6 +16,8 @@
|
||||
"Current Clover revision" = "Current Clover revision";
|
||||
"Boot Device:" = "Boot Device:";
|
||||
"config path:" = "config path:";
|
||||
"Installation succeded" = "Installation succeded";
|
||||
"Installation failed" = "Installation failed";
|
||||
|
||||
"Clover wants to mount %@" = "Clover wants to mount %@";
|
||||
"Clover wants to umount %@" = "Clover wants to umount %@";
|
||||
@ -24,6 +26,26 @@
|
||||
"mount point" = "mount point";
|
||||
"*auto mount" = "*auto mount";
|
||||
|
||||
"System Serial Number:" = "System Serial Number:";
|
||||
"Model:" = "Model:";
|
||||
"board-id:" = "board-id:";
|
||||
"OEM Vendor:" = "OEM Vendor:";
|
||||
"OEM Product:" = "OEM Product:";
|
||||
"OEM Board:" = "OEM Board:";
|
||||
"NVRAM is native:" = "NVRAM is native:";
|
||||
"unknown" = "unknown";
|
||||
"Yes" = "Yes";
|
||||
"No" = "No";
|
||||
|
||||
"Startup Sound" = "Startup Sound";
|
||||
"Device:" = "Device:";
|
||||
"Volume level:" = "Volume level:";
|
||||
"LineOut" = "Line Out";
|
||||
"Speaker" = "Speaker";
|
||||
"Headphones" = "Headphones";
|
||||
"Garniture" = "Garniture";
|
||||
"Other" = "Other";
|
||||
|
||||
"true" = "true";
|
||||
"false" = "false";
|
||||
|
||||
@ -39,6 +61,7 @@
|
||||
"Uninstall CloverDaemonNew" = "Uninstall CloverDaemonNew";
|
||||
|
||||
"Update" = "Update";
|
||||
"Download" = "Download";
|
||||
"Update to r%d" = "Update to r%d"; // "Update to r5101"
|
||||
"Check update:" = "Check update:";
|
||||
"Check now" = "Check now";
|
||||
|
@ -16,6 +16,8 @@
|
||||
"Current Clover revision" = "Revisi Clover Terkini";
|
||||
"Boot Device:" = "Device Boot:";
|
||||
"config path:" = "Lokasi config:";
|
||||
"Installation succeded" = "Installation succeded";
|
||||
"Installation failed" = "Installation failed";
|
||||
|
||||
"Clover wants to mount %@" = "Clover ingin mount %@";
|
||||
"Clover wants to umount %@" = "Clover ingin umount %@";
|
||||
@ -24,6 +26,26 @@
|
||||
"mount point" = "mount point";
|
||||
"*auto mount" = "*auto mount";
|
||||
|
||||
"System Serial Number:" = "System Serial Number:";
|
||||
"Model:" = "Model:";
|
||||
"board-id:" = "board-id:";
|
||||
"OEM Vendor:" = "OEM Vendor:";
|
||||
"OEM Product:" = "OEM Product:";
|
||||
"OEM Board:" = "OEM Board:";
|
||||
"NVRAM is native:" = "NVRAM is native:";
|
||||
"unknown" = "unknown";
|
||||
"Yes" = "Yes";
|
||||
"No" = "No";
|
||||
|
||||
"Startup Sound" = "Startup Sound";
|
||||
"Device:" = "Device:";
|
||||
"Volume level:" = "Volume level:";
|
||||
"LineOut" = "Line Out";
|
||||
"Speaker" = "Speaker";
|
||||
"Headphones" = "Headphones";
|
||||
"Garniture" = "Garniture";
|
||||
"Other" = "Other";
|
||||
|
||||
"true" = "true";
|
||||
"false" = "false";
|
||||
|
||||
@ -39,6 +61,7 @@
|
||||
"Uninstall CloverDaemonNew" = "Copot CloverDaemonNew";
|
||||
|
||||
"Update" = "Perbarui";
|
||||
"Download" = "Download";
|
||||
"Update to r%d" = "Perbarui ke r%d"; // "Update to r5101"
|
||||
"Check update:" = "Periksa Pembaruan:";
|
||||
"Check now" = "Periksa Sekarang";
|
||||
|
@ -16,6 +16,8 @@
|
||||
"Current Clover revision" = "Revisione corrente";
|
||||
"Boot Device:" = "Disco di avvio:";
|
||||
"config path:" = "percorso config:";
|
||||
"Installation succeded" = "Installazione riuscita";
|
||||
"Installation failed" = "Installazione fallita";
|
||||
|
||||
"Clover wants to mount %@" = "Clover vuole montare %@";
|
||||
"Clover wants to umount %@" = "Clover vuole smontare %@";
|
||||
@ -24,6 +26,26 @@
|
||||
"mount point" = "punto di montaggio";
|
||||
"*auto mount" = "*auto monta";
|
||||
|
||||
"System Serial Number:" = "Numero Seriale di Sistema:";
|
||||
"Model:" = "Modello:";
|
||||
"board-id:" = "Identificativo Scheda:";
|
||||
"OEM Vendor:" = "Venditore OEM:";
|
||||
"OEM Product:" = "Prodotto OEM:";
|
||||
"OEM Board:" = "Scheda OEM:";
|
||||
"NVRAM is native:" = "NVRAM è nativa:";
|
||||
"unknown" = "sconosciuto";
|
||||
"Yes" = "Si";
|
||||
"No" = "No";
|
||||
|
||||
"Startup Sound" = "Suono all'avvio";
|
||||
"Device:" = "Dispositivo:";
|
||||
"Volume level:" = "Volume:";
|
||||
"LineOut" = "Line Out";
|
||||
"Speaker" = "Altoparlanti";
|
||||
"Headphones" = "Cuffie";
|
||||
"Garniture" = "Accessori";
|
||||
"Other" = "Altro";
|
||||
|
||||
"true" = "vero";
|
||||
"false" = "falso";
|
||||
|
||||
@ -39,6 +61,7 @@
|
||||
"Uninstall CloverDaemonNew" = "Disinstalla il demone CloverDaemonNew";
|
||||
|
||||
"Update" = "Aggiorna";
|
||||
"Download" = "Scarica";
|
||||
"Update to r%d" = "Aggiorna a r%d"; // "Update to r5101"
|
||||
"Check update:" = "Controlla:";
|
||||
"Check now" = "Controlla adesso";
|
||||
@ -71,7 +94,7 @@ Può essere usato anche se non si desidera aggiornare i settori MBR o PBR.";
|
||||
"Clover legacy BIOS boot sectors" = "Clover EFI richiede tre file essenziali. (in semplici termini)
|
||||
boot0 (Sul disco MBR) responsabile del caricamento del boot1.
|
||||
boot1 (Settore di avvio della partizione) per trovare il boot2.
|
||||
boot2 (Nella cartella principale della partizione) per caricare /EFI/CLOVER/CLOVERIA32.efi o CLOVERX64.efi, e il kernel etc.";
|
||||
boot2 (Nella cartella principale della partizione) per caricare CLOVERX64.efi, e il kernel etc.";
|
||||
|
||||
"boot0af" = "Necessario per l'avvio da schede madri con BIOS.
|
||||
boot0af (boot0 active first) bootloader cerca di avviare la partizione attiva definita nella MBR. Se non vi è alcuna partizione attiva, tenterà di avviare la prima partizione EFI/FAT32/HFS (definita nella MBR e poi nella GPT) con una signature PBR valida.
|
||||
@ -129,7 +152,7 @@ Necessario anche per accedere ad unità che utilizzano controller RAID, JMicron,
|
||||
|
||||
"FirmwareVolume.efi" = "Crea il FirmwareVolume con ‘cursor images’ per FileVault2.";
|
||||
|
||||
"FSInject.efi" = "Abilita l’iniezione di estensioni del kernel dalle cartelle di Clover.";
|
||||
"FSInject.efi" = "Abilita l’iniezione di estensioni del kernel dalle cartelle di Clover e consente di forzare il caricamento da /System/Library/Extensions e /Library/Extensions.";
|
||||
|
||||
"GrubEXFAT.efi" = "Driver GRUB per il filesystem ExFAT.";
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
"Current Clover revision" = "Current Clover revision";
|
||||
"Boot Device:" = "Boot Device:";
|
||||
"config path:" = "config path:";
|
||||
"Installation succeded" = "Installation succeded";
|
||||
"Installation failed" = "Installation failed";
|
||||
|
||||
"Clover wants to mount %@" = "Clover wants to mount %@";
|
||||
"Clover wants to umount %@" = "Clover wants to umount %@";
|
||||
@ -24,6 +26,26 @@
|
||||
"mount point" = "mount point";
|
||||
"*auto mount" = "*auto mount";
|
||||
|
||||
"System Serial Number:" = "System Serial Number:";
|
||||
"Model:" = "Model:";
|
||||
"board-id:" = "board-id:";
|
||||
"OEM Vendor:" = "OEM Vendor:";
|
||||
"OEM Product:" = "OEM Product:";
|
||||
"OEM Board:" = "OEM Board:";
|
||||
"NVRAM is native:" = "NVRAM is native:";
|
||||
"unknown" = "unknown";
|
||||
"Yes" = "Yes";
|
||||
"No" = "No";
|
||||
|
||||
"Startup Sound" = "Startup Sound";
|
||||
"Device:" = "Device:";
|
||||
"Volume level:" = "Volume level:";
|
||||
"LineOut" = "Line Out";
|
||||
"Speaker" = "Speaker";
|
||||
"Headphones" = "Headphones";
|
||||
"Garniture" = "Garniture";
|
||||
"Other" = "Other";
|
||||
|
||||
"true" = "true";
|
||||
"false" = "false";
|
||||
|
||||
@ -39,6 +61,7 @@
|
||||
"Uninstall CloverDaemonNew" = "Uninstall CloverDaemonNew";
|
||||
|
||||
"Update" = "Update";
|
||||
"Download" = "Download";
|
||||
"Update to r%d" = "Update to r%d"; // "Update to r5101"
|
||||
"Check update:" = "Check update:";
|
||||
"Check now" = "Check now";
|
||||
|
@ -16,6 +16,8 @@
|
||||
"Current Clover revision" = "현재 클로버 리비전";
|
||||
"Boot Device:" = "부트 디스크:";
|
||||
"config path:" = "config 경로:";
|
||||
"Installation succeded" = "Installation succeded";
|
||||
"Installation failed" = "Installation failed";
|
||||
|
||||
"Clover wants to mount %@" = "클로버는 다음 디스크를 마운트: %@";
|
||||
"Clover wants to umount %@" = "클로버는 다음 디스크를 언마운트: %@";
|
||||
@ -24,6 +26,26 @@
|
||||
"mount point" = "마운트 포인트";
|
||||
"*auto mount" = "*자동 마운트";
|
||||
|
||||
"System Serial Number:" = "System Serial Number:";
|
||||
"Model:" = "Model:";
|
||||
"board-id:" = "board-id:";
|
||||
"OEM Vendor:" = "OEM Vendor:";
|
||||
"OEM Product:" = "OEM Product:";
|
||||
"OEM Board:" = "OEM Board:";
|
||||
"NVRAM is native:" = "NVRAM is native:";
|
||||
"unknown" = "unknown";
|
||||
"Yes" = "Yes";
|
||||
"No" = "No";
|
||||
"Startup Sound" = "Startup Sound";
|
||||
"Device:" = "Device:";
|
||||
"Volume level:" = "Volume level:";
|
||||
|
||||
"LineOut" = "Line Out";
|
||||
"Speaker" = "Speaker";
|
||||
"Headphones" = "Headphones";
|
||||
"Garniture" = "Garniture";
|
||||
"Other" = "Other";
|
||||
|
||||
"true" = "예";
|
||||
"false" = "아니오";
|
||||
|
||||
@ -39,6 +61,7 @@
|
||||
"Uninstall CloverDaemonNew" = "새로운 클로버데몬 제거";
|
||||
|
||||
"Update" = "업데이트";
|
||||
"Download" = "Download";
|
||||
"Update to r%d" = "r%d로 업데이트"; // "Update to r5101"
|
||||
"Check update:" = "업데이트 확인:";
|
||||
"Check now" = "지금 확인";
|
||||
|
@ -16,6 +16,8 @@
|
||||
"Current Clover revision" = "Current Clover revision";
|
||||
"Boot Device:" = "Boot Device:";
|
||||
"config path:" = "config path:";
|
||||
"Installation succeded" = "Installation succeded";
|
||||
"Installation failed" = "Installation failed";
|
||||
|
||||
"Clover wants to mount %@" = "Clover wants to mount %@";
|
||||
"Clover wants to umount %@" = "Clover wants to umount %@";
|
||||
@ -24,6 +26,26 @@
|
||||
"mount point" = "mount point";
|
||||
"*auto mount" = "*auto mount";
|
||||
|
||||
"System Serial Number:" = "System Serial Number:";
|
||||
"Model:" = "Model:";
|
||||
"board-id:" = "board-id:";
|
||||
"OEM Vendor:" = "OEM Vendor:";
|
||||
"OEM Product:" = "OEM Product:";
|
||||
"OEM Board:" = "OEM Board:";
|
||||
"NVRAM is native:" = "NVRAM is native:";
|
||||
"unknown" = "unknown";
|
||||
"Yes" = "Yes";
|
||||
"No" = "No";
|
||||
|
||||
"Startup Sound" = "Startup Sound";
|
||||
"Device:" = "Device:";
|
||||
"Volume level:" = "Volume level:";
|
||||
"LineOut" = "Line Out";
|
||||
"Speaker" = "Speaker";
|
||||
"Headphones" = "Headphones";
|
||||
"Garniture" = "Garniture";
|
||||
"Other" = "Other";
|
||||
|
||||
"true" = "true";
|
||||
"false" = "false";
|
||||
|
||||
@ -39,6 +61,7 @@
|
||||
"Uninstall CloverDaemonNew" = "Uninstall CloverDaemonNew";
|
||||
|
||||
"Update" = "Update";
|
||||
"Download" = "Download";
|
||||
"Update to r%d" = "Update to r%d"; // "Update to r5101"
|
||||
"Check update:" = "Check update:";
|
||||
"Check now" = "Check now";
|
||||
|
@ -16,6 +16,8 @@
|
||||
"Current Clover revision" = "Current Clover revision";
|
||||
"Boot Device:" = "Boot Device:";
|
||||
"config path:" = "config path:";
|
||||
"Installation succeded" = "Installation succeded";
|
||||
"Installation failed" = "Installation failed";
|
||||
|
||||
"Clover wants to mount %@" = "Clover wants to mount %@";
|
||||
"Clover wants to umount %@" = "Clover wants to umount %@";
|
||||
@ -24,6 +26,26 @@
|
||||
"mount point" = "mount point";
|
||||
"*auto mount" = "*auto mount";
|
||||
|
||||
"System Serial Number:" = "System Serial Number:";
|
||||
"Model:" = "Model:";
|
||||
"board-id:" = "board-id:";
|
||||
"OEM Vendor:" = "OEM Vendor:";
|
||||
"OEM Product:" = "OEM Product:";
|
||||
"OEM Board:" = "OEM Board:";
|
||||
"NVRAM is native:" = "NVRAM is native:";
|
||||
"unknown" = "unknown";
|
||||
"Yes" = "Yes";
|
||||
"No" = "No";
|
||||
|
||||
"Startup Sound" = "Startup Sound";
|
||||
"Device:" = "Device:";
|
||||
"Volume level:" = "Volume level:";
|
||||
"LineOut" = "Line Out";
|
||||
"Speaker" = "Speaker";
|
||||
"Headphones" = "Headphones";
|
||||
"Garniture" = "Garniture";
|
||||
"Other" = "Other";
|
||||
|
||||
"true" = "true";
|
||||
"false" = "false";
|
||||
|
||||
@ -39,6 +61,7 @@
|
||||
"Uninstall CloverDaemonNew" = "Uninstall CloverDaemonNew";
|
||||
|
||||
"Update" = "Update";
|
||||
"Download" = "Download";
|
||||
"Update to r%d" = "Update to r%d"; // "Update to r5101"
|
||||
"Check update:" = "Check update:";
|
||||
"Check now" = "Check now";
|
||||
|
@ -16,6 +16,8 @@
|
||||
"Current Clover revision" = "Current Clover revision";
|
||||
"Boot Device:" = "Boot Device:";
|
||||
"config path:" = "config path:";
|
||||
"Installation succeded" = "Installation succeded";
|
||||
"Installation failed" = "Installation failed";
|
||||
|
||||
"Clover wants to mount %@" = "Clover wants to mount %@";
|
||||
"Clover wants to umount %@" = "Clover wants to umount %@";
|
||||
@ -24,6 +26,26 @@
|
||||
"mount point" = "mount point";
|
||||
"*auto mount" = "*auto mount";
|
||||
|
||||
"System Serial Number:" = "System Serial Number:";
|
||||
"Model:" = "Model:";
|
||||
"board-id:" = "board-id:";
|
||||
"OEM Vendor:" = "OEM Vendor:";
|
||||
"OEM Product:" = "OEM Product:";
|
||||
"OEM Board:" = "OEM Board:";
|
||||
"NVRAM is native:" = "NVRAM is native:";
|
||||
"unknown" = "unknown";
|
||||
"Yes" = "Yes";
|
||||
"No" = "No";
|
||||
|
||||
"Startup Sound" = "Startup Sound";
|
||||
"Device:" = "Device:";
|
||||
"Volume level:" = "Volume level:";
|
||||
"LineOut" = "Line Out";
|
||||
"Speaker" = "Speaker";
|
||||
"Headphones" = "Headphones";
|
||||
"Garniture" = "Garniture";
|
||||
"Other" = "Other";
|
||||
|
||||
"true" = "true";
|
||||
"false" = "false";
|
||||
|
||||
@ -39,6 +61,7 @@
|
||||
"Uninstall CloverDaemonNew" = "Uninstall CloverDaemonNew";
|
||||
|
||||
"Update" = "Update";
|
||||
"Download" = "Download";
|
||||
"Update to r%d" = "Update to r%d"; // "Update to r5101"
|
||||
"Check update:" = "Check update:";
|
||||
"Check now" = "Check now";
|
||||
|
@ -16,6 +16,8 @@
|
||||
"Current Clover revision" = "Current Clover revision";
|
||||
"Boot Device:" = "Boot Device:";
|
||||
"config path:" = "config path:";
|
||||
"Installation succeded" = "Installation succeded";
|
||||
"Installation failed" = "Installation failed";
|
||||
|
||||
"Clover wants to mount %@" = "Clover wants to mount %@";
|
||||
"Clover wants to umount %@" = "Clover wants to umount %@";
|
||||
@ -24,6 +26,26 @@
|
||||
"mount point" = "mount point";
|
||||
"*auto mount" = "*auto mount";
|
||||
|
||||
"System Serial Number:" = "System Serial Number:";
|
||||
"Model:" = "Model:";
|
||||
"board-id:" = "board-id:";
|
||||
"OEM Vendor:" = "OEM Vendor:";
|
||||
"OEM Product:" = "OEM Product:";
|
||||
"OEM Board:" = "OEM Board:";
|
||||
"NVRAM is native:" = "NVRAM is native:";
|
||||
"unknown" = "unknown";
|
||||
"Yes" = "Yes";
|
||||
"No" = "No";
|
||||
|
||||
"Startup Sound" = "Startup Sound";
|
||||
"Device:" = "Device:";
|
||||
"Volume level:" = "Volume level:";
|
||||
"LineOut" = "Line Out";
|
||||
"Speaker" = "Speaker";
|
||||
"Headphones" = "Headphones";
|
||||
"Garniture" = "Garniture";
|
||||
"Other" = "Other";
|
||||
|
||||
"true" = "true";
|
||||
"false" = "false";
|
||||
|
||||
@ -39,6 +61,7 @@
|
||||
"Uninstall CloverDaemonNew" = "Uninstall CloverDaemonNew";
|
||||
|
||||
"Update" = "Update";
|
||||
"Download" = "Download";
|
||||
"Update to r%d" = "Update to r%d"; // "Update to r5101"
|
||||
"Check update:" = "Check update:";
|
||||
"Check now" = "Check now";
|
||||
|
@ -16,6 +16,8 @@
|
||||
"Current Clover revision" = "Clover atual revisão";
|
||||
"Boot device" = "Dispositivo de Boot";
|
||||
"config path:" = "configurar caminho:";
|
||||
"Installation succeded" = "Installation succeded";
|
||||
"Installation failed" = "Installation failed";
|
||||
|
||||
"Clover wants to mount %@" = "Clover pretende montar %@";
|
||||
"Clover wants to umount %@" = "Clover pretende desmontar %@";
|
||||
@ -24,6 +26,26 @@
|
||||
"mount point" = "ponto de montagem";
|
||||
"auto mount" = "Montagem Auto";
|
||||
|
||||
"System Serial Number:" = "System Serial Number:";
|
||||
"Model:" = "Model:";
|
||||
"board-id:" = "board-id:";
|
||||
"OEM Vendor:" = "OEM Vendor:";
|
||||
"OEM Product:" = "OEM Product:";
|
||||
"OEM Board:" = "OEM Board:";
|
||||
"NVRAM is native:" = "NVRAM is native:";
|
||||
"unknown" = "unknown";
|
||||
"Yes" = "Yes";
|
||||
"No" = "No";
|
||||
|
||||
"Startup Sound" = "Startup Sound";
|
||||
"Device:" = "Device:";
|
||||
"Volume level:" = "Volume level:";
|
||||
"LineOut" = "Line Out";
|
||||
"Speaker" = "Speaker";
|
||||
"Headphones" = "Headphones";
|
||||
"Garniture" = "Garniture";
|
||||
"Other" = "Other";
|
||||
|
||||
"true" = "verdadeiro";
|
||||
"false" = "falso";
|
||||
|
||||
@ -39,6 +61,7 @@
|
||||
"Uninstall CloverDaemonNew" = "Desinstalar CloverDaemonNew";
|
||||
|
||||
"Update" = "Atualizar";
|
||||
"Download" = "Download";
|
||||
"Update to r%d" = "Atualizar para r%d"; // "Update to r5101"
|
||||
"Check update:" = "Verificar Atualizações:";
|
||||
"Check now" = "Verificar agora";
|
||||
|
@ -16,6 +16,8 @@
|
||||
"Current Clover revision" = "Current Clover revision";
|
||||
"Boot Device:" = "Boot Device:";
|
||||
"config path:" = "config path:";
|
||||
"Installation succeded" = "Installation succeded";
|
||||
"Installation failed" = "Installation failed";
|
||||
|
||||
"Clover wants to mount %@" = "Clover wants to mount %@";
|
||||
"Clover wants to umount %@" = "Clover wants to umount %@";
|
||||
@ -24,6 +26,26 @@
|
||||
"mount point" = "mount point";
|
||||
"*auto mount" = "*auto mount";
|
||||
|
||||
"System Serial Number:" = "System Serial Number:";
|
||||
"Model:" = "Model:";
|
||||
"board-id:" = "board-id:";
|
||||
"OEM Vendor:" = "OEM Vendor:";
|
||||
"OEM Product:" = "OEM Product:";
|
||||
"OEM Board:" = "OEM Board:";
|
||||
"NVRAM is native:" = "NVRAM is native:";
|
||||
"unknown" = "unknown";
|
||||
"Yes" = "Yes";
|
||||
"No" = "No";
|
||||
|
||||
"Startup Sound" = "Startup Sound";
|
||||
"Device:" = "Device:";
|
||||
"Volume level:" = "Volume level:";
|
||||
"LineOut" = "Line Out";
|
||||
"Speaker" = "Speaker";
|
||||
"Headphones" = "Headphones";
|
||||
"Garniture" = "Garniture";
|
||||
"Other" = "Other";
|
||||
|
||||
"true" = "true";
|
||||
"false" = "false";
|
||||
|
||||
@ -39,6 +61,7 @@
|
||||
"Uninstall CloverDaemonNew" = "Uninstall CloverDaemonNew";
|
||||
|
||||
"Update" = "Update";
|
||||
"Download" = "Download";
|
||||
"Update to r%d" = "Update to r%d"; // "Update to r5101"
|
||||
"Check update:" = "Check update:";
|
||||
"Check now" = "Check now";
|
||||
|
@ -16,6 +16,8 @@
|
||||
"Current Clover revision" = "Текущая ревизия Clover";
|
||||
"Boot Device:" = "Загрузочное устройство:";
|
||||
"config path:" = "путь к файлу config:";
|
||||
"Installation succeded" = "Installation succeded";
|
||||
"Installation failed" = "Installation failed";
|
||||
|
||||
"Clover wants to mount %@" = "Clover желает смонтировать %@";
|
||||
"Clover wants to umount %@" = "Clover желает размонтировать %@";
|
||||
@ -24,6 +26,26 @@
|
||||
"mount point" = "название тома";
|
||||
"*auto mount" = "*auto mount";
|
||||
|
||||
"System Serial Number:" = "System Serial Number:";
|
||||
"Model:" = "Model:";
|
||||
"board-id:" = "board-id:";
|
||||
"OEM Vendor:" = "OEM Vendor:";
|
||||
"OEM Product:" = "OEM Product:";
|
||||
"OEM Board:" = "OEM Board:";
|
||||
"NVRAM is native:" = "NVRAM is native:";
|
||||
"unknown" = "unknown";
|
||||
"Yes" = "Yes";
|
||||
"No" = "No";
|
||||
|
||||
"Startup Sound" = "Startup Sound";
|
||||
"Device:" = "Device:";
|
||||
"Volume level:" = "Volume level:";
|
||||
"LineOut" = "Line Out";
|
||||
"Speaker" = "Speaker";
|
||||
"Headphones" = "Headphones";
|
||||
"Garniture" = "Garniture";
|
||||
"Other" = "Other";
|
||||
|
||||
"true" = "истина";
|
||||
"false" = "ложь";
|
||||
|
||||
@ -39,6 +61,7 @@
|
||||
"Uninstall CloverDaemonNew" = "Удалить CloverDaemonNew";
|
||||
|
||||
"Update" = "Oбновление";
|
||||
"Download" = "Download";
|
||||
"Update to r%d" = "Обновление до r%d"; // "Update to r5101"
|
||||
"Check update:" = "Проверить обновления:";
|
||||
"Check now" = "Проверь сейчас";
|
||||
|
@ -16,6 +16,8 @@
|
||||
"Current Clover revision" = "Trenutna verzija Clover-a";
|
||||
"Boot Device:" = "Uređaj za podizanje sastava:";
|
||||
"config path:" = "Putanja za konfiguraciju:";
|
||||
"Installation succeded" = "Installation succeded";
|
||||
"Installation failed" = "Installation failed";
|
||||
|
||||
"Clover wants to mount %@" = "Clover želi %@ mount";
|
||||
"Clover wants to umount %@" = "Clover želi %@ unmount";
|
||||
@ -24,6 +26,26 @@
|
||||
"mount point" = "mount point";
|
||||
"*auto mount" = "*auto mount";
|
||||
|
||||
"System Serial Number:" = "System Serial Number:";
|
||||
"Model:" = "Model:";
|
||||
"board-id:" = "board-id:";
|
||||
"OEM Vendor:" = "OEM Vendor:";
|
||||
"OEM Product:" = "OEM Product:";
|
||||
"OEM Board:" = "OEM Board:";
|
||||
"NVRAM is native:" = "NVRAM is native:";
|
||||
"unknown" = "unknown";
|
||||
"Yes" = "Yes";
|
||||
"No" = "No";
|
||||
|
||||
"Startup Sound" = "Startup Sound";
|
||||
"Device:" = "Device:";
|
||||
"Volume level:" = "Volume level:";
|
||||
"LineOut" = "Line Out";
|
||||
"Speaker" = "Speaker";
|
||||
"Headphones" = "Headphones";
|
||||
"Garniture" = "Garniture";
|
||||
"Other" = "Other";
|
||||
|
||||
"true" = "tačno";
|
||||
"false" = "Lažno";
|
||||
|
||||
@ -39,6 +61,7 @@
|
||||
"Uninstall CloverDaemonNew" = "Deinstalirati CloverDaemonNew";
|
||||
|
||||
"Update" = "Ažuriranje";
|
||||
"Download" = "Download";
|
||||
"Update to r%d" = "Ažurirati Verziju r%d Aktuelnu"; // "Update to r5101"
|
||||
"Check update:" = "Proveriti trenutnu verziju:";
|
||||
"Check now" = "Proveriti sada";
|
||||
|
@ -16,6 +16,8 @@
|
||||
"Current Clover revision" = "Current Clover revision";
|
||||
"Boot Device:" = "Boot Device:";
|
||||
"config path:" = "config path:";
|
||||
"Installation succeded" = "Installation succeded";
|
||||
"Installation failed" = "Installation failed";
|
||||
|
||||
"Clover wants to mount %@" = "Clover wants to mount %@";
|
||||
"Clover wants to umount %@" = "Clover wants to umount %@";
|
||||
@ -24,6 +26,26 @@
|
||||
"mount point" = "mount point";
|
||||
"*auto mount" = "*auto mount";
|
||||
|
||||
"System Serial Number:" = "System Serial Number:";
|
||||
"Model:" = "Model:";
|
||||
"board-id:" = "board-id:";
|
||||
"OEM Vendor:" = "OEM Vendor:";
|
||||
"OEM Product:" = "OEM Product:";
|
||||
"OEM Board:" = "OEM Board:";
|
||||
"NVRAM is native:" = "NVRAM is native:";
|
||||
"unknown" = "unknown";
|
||||
"Yes" = "Yes";
|
||||
"No" = "No";
|
||||
|
||||
"Startup Sound" = "Startup Sound";
|
||||
"Device:" = "Device:";
|
||||
"Volume level:" = "Volume level:";
|
||||
"LineOut" = "Line Out";
|
||||
"Speaker" = "Speaker";
|
||||
"Headphones" = "Headphones";
|
||||
"Garniture" = "Garniture";
|
||||
"Other" = "Other";
|
||||
|
||||
"true" = "true";
|
||||
"false" = "false";
|
||||
|
||||
@ -39,6 +61,7 @@
|
||||
"Uninstall CloverDaemonNew" = "Uninstall CloverDaemonNew";
|
||||
|
||||
"Update" = "Update";
|
||||
"Download" = "Download";
|
||||
"Update to r%d" = "Update to r%d"; // "Update to r5101"
|
||||
"Check update:" = "Check update:";
|
||||
"Check now" = "Check now";
|
||||
|
@ -16,6 +16,8 @@
|
||||
"Current Clover revision" = "Current Clover revision";
|
||||
"Boot Device:" = "Boot Device:";
|
||||
"config path:" = "config path:";
|
||||
"Installation succeded" = "Installation succeded";
|
||||
"Installation failed" = "Installation failed";
|
||||
|
||||
"Clover wants to mount %@" = "Clover wants to mount %@";
|
||||
"Clover wants to umount %@" = "Clover wants to umount %@";
|
||||
@ -24,6 +26,26 @@
|
||||
"mount point" = "mount point";
|
||||
"*auto mount" = "*auto mount";
|
||||
|
||||
"System Serial Number:" = "System Serial Number:";
|
||||
"Model:" = "Model:";
|
||||
"board-id:" = "board-id:";
|
||||
"OEM Vendor:" = "OEM Vendor:";
|
||||
"OEM Product:" = "OEM Product:";
|
||||
"OEM Board:" = "OEM Board:";
|
||||
"NVRAM is native:" = "NVRAM is native:";
|
||||
"unknown" = "unknown";
|
||||
"Yes" = "Yes";
|
||||
"No" = "No";
|
||||
|
||||
"Startup Sound" = "Startup Sound";
|
||||
"Device:" = "Device:";
|
||||
"Volume level:" = "Volume level:";
|
||||
"LineOut" = "Line Out";
|
||||
"Speaker" = "Speaker";
|
||||
"Headphones" = "Headphones";
|
||||
"Garniture" = "Garniture";
|
||||
"Other" = "Other";
|
||||
|
||||
"true" = "true";
|
||||
"false" = "false";
|
||||
|
||||
@ -39,6 +61,7 @@
|
||||
"Uninstall CloverDaemonNew" = "Uninstall CloverDaemonNew";
|
||||
|
||||
"Update" = "Update";
|
||||
"Download" = "Download";
|
||||
"Update to r%d" = "Update to r%d"; // "Update to r5101"
|
||||
"Check update:" = "Check update:";
|
||||
"Check now" = "Check now";
|
||||
|
@ -16,6 +16,8 @@
|
||||
"Current Clover revision" = "Current Clover revision";
|
||||
"Boot Device:" = "Boot Device:";
|
||||
"config path:" = "config path:";
|
||||
"Installation succeded" = "Installation succeded";
|
||||
"Installation failed" = "Installation failed";
|
||||
|
||||
"Clover wants to mount %@" = "Clover wants to mount %@";
|
||||
"Clover wants to umount %@" = "Clover wants to umount %@";
|
||||
@ -24,6 +26,26 @@
|
||||
"mount point" = "mount point";
|
||||
"*auto mount" = "*auto mount";
|
||||
|
||||
"System Serial Number:" = "System Serial Number:";
|
||||
"Model:" = "Model:";
|
||||
"board-id:" = "board-id:";
|
||||
"OEM Vendor:" = "OEM Vendor:";
|
||||
"OEM Product:" = "OEM Product:";
|
||||
"OEM Board:" = "OEM Board:";
|
||||
"NVRAM is native:" = "NVRAM is native:";
|
||||
"unknown" = "unknown";
|
||||
"Yes" = "Yes";
|
||||
"No" = "No";
|
||||
|
||||
"Startup Sound" = "Startup Sound";
|
||||
"Device:" = "Device:";
|
||||
"Volume level:" = "Volume level:";
|
||||
"LineOut" = "Line Out";
|
||||
"Speaker" = "Speaker";
|
||||
"Headphones" = "Headphones";
|
||||
"Garniture" = "Garniture";
|
||||
"Other" = "Other";
|
||||
|
||||
"true" = "true";
|
||||
"false" = "false";
|
||||
|
||||
@ -39,6 +61,7 @@
|
||||
"Uninstall CloverDaemonNew" = "Uninstall CloverDaemonNew";
|
||||
|
||||
"Update" = "Update";
|
||||
"Download" = "Download";
|
||||
"Update to r%d" = "Update to r%d"; // "Update to r5101"
|
||||
"Check update:" = "Check update:";
|
||||
"Check now" = "Check now";
|
||||
|
@ -16,6 +16,8 @@
|
||||
"Current Clover revision" = "目前 Clover 版本";
|
||||
"Boot Device:" = "引导设备:";
|
||||
"config path:" = "config 路径:";
|
||||
"Installation succeded" = "Installation succeded";
|
||||
"Installation failed" = "Installation failed";
|
||||
|
||||
"Clover wants to mount %@" = "Clover 想要挂载 %@";
|
||||
"Clover wants to umount %@" = "Clover 想要卸载 %@";
|
||||
@ -24,6 +26,26 @@
|
||||
"mount point" = "挂载点";
|
||||
"*auto mount" = "*auto mount";
|
||||
|
||||
"System Serial Number:" = "System Serial Number:";
|
||||
"Model:" = "Model:";
|
||||
"board-id:" = "board-id:";
|
||||
"OEM Vendor:" = "OEM Vendor:";
|
||||
"OEM Product:" = "OEM Product:";
|
||||
"OEM Board:" = "OEM Board:";
|
||||
"NVRAM is native:" = "NVRAM is native:";
|
||||
"unknown" = "unknown";
|
||||
"Yes" = "Yes";
|
||||
"No" = "No";
|
||||
|
||||
"Startup Sound" = "Startup Sound";
|
||||
"Device:" = "Device:";
|
||||
"Volume level:" = "Volume level:";
|
||||
"LineOut" = "Line Out";
|
||||
"Speaker" = "Speaker";
|
||||
"Headphones" = "Headphones";
|
||||
"Garniture" = "Garniture";
|
||||
"Other" = "Other";
|
||||
|
||||
"true" = "是";
|
||||
"false" = "否";
|
||||
|
||||
@ -39,6 +61,7 @@
|
||||
"Uninstall CloverDaemonNew" = "卸载 CloverDaemonNew";
|
||||
|
||||
"Update" = "更新";
|
||||
"Download" = "Download";
|
||||
"Update to r%d" = "更新到 r%d"; // "Update to r5101"
|
||||
"Check update:" = "检查更新:";
|
||||
"Check now" = "现在检查";
|
||||
|
@ -16,6 +16,8 @@
|
||||
"Current Clover revision" = "Current Clover revision";
|
||||
"Boot Device:" = "Boot Device:";
|
||||
"config path:" = "config path:";
|
||||
"Installation succeded" = "Installation succeded";
|
||||
"Installation failed" = "Installation failed";
|
||||
|
||||
"Clover wants to mount %@" = "Clover wants to mount %@";
|
||||
"Clover wants to umount %@" = "Clover wants to umount %@";
|
||||
@ -24,6 +26,26 @@
|
||||
"mount point" = "mount point";
|
||||
"*auto mount" = "*auto mount";
|
||||
|
||||
"System Serial Number:" = "System Serial Number:";
|
||||
"Model:" = "Model:";
|
||||
"board-id:" = "board-id:";
|
||||
"OEM Vendor:" = "OEM Vendor:";
|
||||
"OEM Product:" = "OEM Product:";
|
||||
"OEM Board:" = "OEM Board:";
|
||||
"NVRAM is native:" = "NVRAM is native:";
|
||||
"unknown" = "unknown";
|
||||
"Yes" = "Yes";
|
||||
"No" = "No";
|
||||
|
||||
"Startup Sound" = "Startup Sound";
|
||||
"Device:" = "Device:";
|
||||
"Volume level:" = "Volume level:";
|
||||
"LineOut" = "Line Out";
|
||||
"Speaker" = "Speaker";
|
||||
"Headphones" = "Headphones";
|
||||
"Garniture" = "Garniture";
|
||||
"Other" = "Other";
|
||||
|
||||
"true" = "true";
|
||||
"false" = "false";
|
||||
|
||||
@ -39,6 +61,7 @@
|
||||
"Uninstall CloverDaemonNew" = "Uninstall CloverDaemonNew";
|
||||
|
||||
"Update" = "Update";
|
||||
"Download" = "Download";
|
||||
"Update to r%d" = "Update to r%d"; // "Update to r5101"
|
||||
"Check update:" = "Check update:";
|
||||
"Check now" = "Check now";
|
||||
|
@ -1,5 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
logPath="/tmp/cltmplog"
|
||||
exec > >(tee -a $logPath) 2>&1
|
||||
# Created by vector sigma on 04/11/2019.
|
||||
# Copyright © 2019 CloverHackyColor. All rights reserved.
|
||||
|
||||
@ -24,8 +26,20 @@ bootslice="${bootdev#*disk*s}"
|
||||
keepmounted=0
|
||||
journaled=0
|
||||
|
||||
saveLog() {
|
||||
/usr/sbin/diskutil mount "$bootdev" > /dev/null 2>&1
|
||||
local mp=$(LC_ALL=C /sbin/mount | egrep "^$bootdev on" | sed 's/^.* on *//;s/ ([^(]*//')
|
||||
|
||||
if [[ -n "$mp" ]]; then
|
||||
if [[ -d "${mp}"/EFI/CLOVER ]] && [[ -f "${logPath}" ]]; then
|
||||
cat "${logPath}" > "${mp}"/EFI/CLOVER/Clover.app_install.log
|
||||
chmod 777 "${mp}"/EFI/CLOVER/Clover.app_install.log
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
echo
|
||||
echo "Installing boot sectors (version of Wed 27 Nov 2019, 22:16)"
|
||||
echo "Installing boot sectors (version of Wed 30 Dec 2019, 20:01)"
|
||||
echo
|
||||
echo "disk: ${disk}"
|
||||
echo "bootdev: ${bootdev}"
|
||||
@ -45,7 +59,7 @@ fi
|
||||
if [ "${partition_scheme}" != FDisk_partition_scheme ] && \
|
||||
[ "${partition_scheme}" != GUID_partition_scheme ]; then
|
||||
echo "Error: unsupported Partition Scheme Map \"${partition_scheme}\"."
|
||||
exit 1
|
||||
saveLog && exit 1
|
||||
fi
|
||||
|
||||
|
||||
@ -53,22 +67,22 @@ if [ "${filesystem}" != fat32 ] && \
|
||||
[ "${filesystem}" != exfat ] && \
|
||||
[ "${filesystem}" != hfs ]; then
|
||||
echo "Error: unsupported filesystem \"${filesystem}\""
|
||||
exit 1
|
||||
saveLog && exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "${boot0}" ]]; then
|
||||
echo "Error: cannot found /tmp/boot0[af-ss] sector."
|
||||
exit 1
|
||||
saveLog && exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "${boot1}" ]]; then
|
||||
echo "Error: cannot found /tmp/boot1[1f32-h-x] sector."
|
||||
exit 1
|
||||
saveLog && exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "${boot1install}" ]]; then
|
||||
echo "Error: cannot found /tmp/boot1-install."
|
||||
exit 1
|
||||
saveLog && exit 1
|
||||
fi
|
||||
|
||||
# chmod +x "${boot1install}"
|
||||
@ -148,17 +162,19 @@ MAKEACTIVE
|
||||
fi
|
||||
|
||||
sleep 2
|
||||
# Now try to remount the partition
|
||||
if [[ "${ESP}" != ESP ]]; then
|
||||
if [[ -n "$mnt_pt" ]]; then
|
||||
/usr/sbin/diskutil mount "$bootdev"
|
||||
fi
|
||||
fi
|
||||
saveLog
|
||||
|
||||
if [[ $journaled -ne 0 ]]; then
|
||||
/usr/sbin/diskutil enableJournal "${disk}"
|
||||
fi
|
||||
|
||||
# Now try to remount the partition
|
||||
if [[ "${ESP}" == ESP ]]; then
|
||||
/usr/sbin/diskutil unmount force $bootdev > /dev/null 2>&1
|
||||
else
|
||||
/usr/sbin/diskutil mount "$bootdev" > /dev/null 2>&1
|
||||
fi
|
||||
|
||||
/bin/rm -rf /tmp/Clover*
|
||||
/bin/rm -rf /tmp/boot1*
|
||||
/bin/rm -rf /tmp/boot2*
|
||||
|
@ -100,7 +100,7 @@
|
||||
958505A12364D36300BCB4A3 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 1120;
|
||||
LastUpgradeCheck = 1130;
|
||||
ORGANIZATIONNAME = CloverHackyColor;
|
||||
TargetAttributes = {
|
||||
958505A82364D36400BCB4A3 = {
|
||||
@ -250,6 +250,7 @@
|
||||
958505B12364D36400BCB4A3 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@ -259,6 +260,7 @@
|
||||
958505B22364D36400BCB4A3 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
@ -15,7 +15,7 @@
|
||||
// TODO: redone in swift as swift command line are now small in size, with no hurry...
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#define ktempLogPath @"/tmp/cloverapp.txt"
|
||||
#define ktempLogPath "/tmp/cltmplog"
|
||||
#define kfm [NSFileManager defaultManager]
|
||||
|
||||
#pragma mark -
|
||||
@ -32,31 +32,70 @@ void cleanUp() {
|
||||
[task launch];
|
||||
}
|
||||
|
||||
void exitWithMessage(const char *format, ...)
|
||||
{
|
||||
va_list arg;
|
||||
va_start (arg, format);
|
||||
vfprintf (stdout, format, arg);
|
||||
va_end (arg);
|
||||
NSString *gTargetVolume;
|
||||
|
||||
void saveLog() {
|
||||
if (gTargetVolume != nil
|
||||
&& [kfm fileExistsAtPath:gTargetVolume]
|
||||
&& [kfm fileExistsAtPath:@ktempLogPath]) {
|
||||
NSString *finalLogPath =
|
||||
[gTargetVolume stringByAppendingPathComponent:@"EFI/CLOVER/Clover.app_install.log"];
|
||||
if ([kfm fileExistsAtPath: finalLogPath]) {
|
||||
[kfm removeItemAtPath:finalLogPath error:nil];
|
||||
}
|
||||
NSData *log = [NSData dataWithContentsOfFile:@ktempLogPath];
|
||||
if (log != nil) {
|
||||
[log writeToFile:finalLogPath atomically:NO];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addToLog(NSString *str) {
|
||||
if (![kfm fileExistsAtPath:@ktempLogPath]) {
|
||||
system([[NSString stringWithFormat:@"echo > %s", ktempLogPath] UTF8String]);
|
||||
}
|
||||
NSFileHandle *fh = [NSFileHandle fileHandleForWritingAtPath:@ktempLogPath];
|
||||
[fh seekToEndOfFile];
|
||||
[fh writeData:[str dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[fh closeFile];
|
||||
}
|
||||
|
||||
void post(NSString *format, ...) {
|
||||
va_list arguments;
|
||||
va_start(arguments, format);
|
||||
NSString *str = [[NSString alloc] initWithFormat:format arguments:arguments];
|
||||
addToLog(str);
|
||||
va_end(arguments);
|
||||
printf("%s", [str UTF8String]);
|
||||
|
||||
}
|
||||
|
||||
void exitWithMessage(NSString *format, ...) {
|
||||
va_list arguments;
|
||||
va_start(arguments, format);
|
||||
NSString *str = [[NSString alloc] initWithFormat:format arguments:arguments];
|
||||
|
||||
va_end(arguments);
|
||||
printf("%s", [str UTF8String]);
|
||||
addToLog(str);
|
||||
saveLog();
|
||||
cleanUp();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
BOOL copyReplace(NSString *source, NSString *dest, NSDictionary *attributes) {
|
||||
NSError *err = nil;
|
||||
NSString *upperDir = [dest stringByDeletingLastPathComponent];
|
||||
|
||||
if ([upperDir isEqualToString:@"/"]) {
|
||||
printf("+ ../%s\n", [dest lastPathComponent].UTF8String);
|
||||
post(@"+ ../%@\n", [dest lastPathComponent]);
|
||||
} else {
|
||||
printf("+ ../%s/%s\n",
|
||||
[[dest stringByDeletingLastPathComponent] lastPathComponent].UTF8String,
|
||||
[dest lastPathComponent].UTF8String);
|
||||
post(@"+ ../%@/%@\n",
|
||||
[[dest stringByDeletingLastPathComponent] lastPathComponent], [dest lastPathComponent]);
|
||||
}
|
||||
|
||||
if (![kfm fileExistsAtPath:source]) {
|
||||
printf("Error: %s doesn't exist\n", source.UTF8String);
|
||||
post(@"Error: %@ doesn't exist\n", source);
|
||||
return NO;
|
||||
}
|
||||
// remove destination if already exist
|
||||
@ -83,7 +122,7 @@ BOOL copyReplace(NSString *source, NSString *dest, NSDictionary *attributes) {
|
||||
|
||||
// print any errors if any
|
||||
if (err != nil) {
|
||||
printf("%s\n", err.description.UTF8String);
|
||||
post(@"%@\n", err.description);
|
||||
}
|
||||
|
||||
return (err == nil);
|
||||
@ -95,18 +134,29 @@ BOOL copyReplace(NSString *source, NSString *dest, NSDictionary *attributes) {
|
||||
|
||||
int main(int argc, char * const * argv) {
|
||||
@autoreleasepool {
|
||||
if ([kfm fileExistsAtPath:@ktempLogPath]) {
|
||||
[kfm removeItemAtPath:@ktempLogPath error:nil];
|
||||
}
|
||||
|
||||
printf("My Path = %s\n", [[NSString stringWithFormat:@"%s", argv[0]] UTF8String]);
|
||||
NSDateFormatter * df = [NSDateFormatter new];
|
||||
[df setDateFormat:@"yyyy-MMM-dd HH:mm:ss"];
|
||||
NSLocale *locale = [[NSLocale alloc]
|
||||
initWithLocaleIdentifier:@"en_US"];
|
||||
[df setLocale:locale];
|
||||
NSString *dateString = [df stringFromDate:[NSDate new]];
|
||||
|
||||
if (geteuid() != 0) {
|
||||
exitWithMessage("Error: you don't have root permissions\n");
|
||||
exitWithMessage(@"Error: you don't have root permissions\n");
|
||||
}
|
||||
|
||||
NSDictionary *CloverappDict = [NSDictionary dictionaryWithContentsOfFile:@"/tmp/Cloverapp"];
|
||||
if (CloverappDict == nil) {
|
||||
exitWithMessage("Error: can't load Cloverapp dictionary\n");
|
||||
exitWithMessage(@"Error: can't load Cloverapp dictionary\n");
|
||||
}
|
||||
cleanUp();
|
||||
|
||||
|
||||
NSString *bootSectorsInstall = @"/tmp/bootsectors-install";
|
||||
|
||||
NSString *targetVol = [CloverappDict objectForKey:@"targetVol"];
|
||||
NSString *disk = [CloverappDict objectForKey:@"disk"];
|
||||
NSString *filesystem = [CloverappDict objectForKey:@"filesystem"];
|
||||
@ -117,18 +167,25 @@ int main(int argc, char * const * argv) {
|
||||
NSString *cloverv2 = [CloverappDict objectForKey:@"CloverV2"];
|
||||
NSString *boot1installPath = [CloverappDict objectForKey:@"boot1install"];
|
||||
NSString *bootSectorsInstallSrc = [CloverappDict objectForKey:@"bootsectors-install"];
|
||||
NSString *bootSectorsInstall = @"/tmp/bootsectors-install";
|
||||
NSString *backUpPath = [CloverappDict objectForKey:@"BackUpPath"];
|
||||
NSString *version = [CloverappDict objectForKey:@"version"];
|
||||
BOOL isESP = [[CloverappDict objectForKey:@"isESP"] boolValue];
|
||||
|
||||
post(@"%@, %@\n\n", version, dateString);
|
||||
post(@"My Path = %s\n", argv[0]);
|
||||
if (backUpPath != nil) {
|
||||
post(@"Backup made at:\n%@.\n", backUpPath);
|
||||
}
|
||||
|
||||
if ([kfm fileExistsAtPath:bootSectorsInstall]) {
|
||||
printf("Note: found old bootsectors-install..removing it..\n");
|
||||
post(@"Note: found old bootsectors-install..removing it..\n");
|
||||
if (![kfm removeItemAtPath:bootSectorsInstall error:nil]) {
|
||||
exitWithMessage("Error: can't remove old bootsectors-install.");
|
||||
exitWithMessage(@"Error: can't remove old bootsectors-install.");
|
||||
}
|
||||
}
|
||||
|
||||
if (bootSectorsInstallSrc != nil) {
|
||||
printf("bootSectorsInstallSrc = %s\n", [bootSectorsInstallSrc UTF8String]);
|
||||
post(@"bootSectorsInstallSrc = %@\n", bootSectorsInstallSrc);
|
||||
}
|
||||
|
||||
BOOL alt = NO;
|
||||
@ -146,19 +203,20 @@ int main(int argc, char * const * argv) {
|
||||
BOOL isDir = NO;
|
||||
|
||||
if (targetVol == nil) {
|
||||
exitWithMessage("Error: option targetVol [path to volume] not specified\n");
|
||||
exitWithMessage(@"Error: option targetVol [path to volume] not specified\n");
|
||||
}
|
||||
gTargetVolume = targetVol;
|
||||
|
||||
if (![kfm fileExistsAtPath:targetVol]) {
|
||||
exitWithMessage("Error: target volume \"%s\" doesn't exist.\n", targetVol.UTF8String);
|
||||
exitWithMessage(@"Error: target volume \"%@\" doesn't exist.\n", targetVol);
|
||||
}
|
||||
|
||||
if (cloverv2 == nil || ![kfm fileExistsAtPath:cloverv2]) {
|
||||
exitWithMessage("Error: cannot found CloverV2 directory\n");
|
||||
exitWithMessage(@"Error: cannot found CloverV2 directory\n");
|
||||
}
|
||||
|
||||
printf("Target volume: %s\n", targetVol.UTF8String);
|
||||
|
||||
post(@"Target volume: %@\n", targetVol);
|
||||
/*
|
||||
// check if target volume is writable
|
||||
NSString *volEnds = targetVol;
|
||||
if (![volEnds hasSuffix:@"/"]) {
|
||||
@ -167,35 +225,35 @@ int main(int argc, char * const * argv) {
|
||||
|
||||
|
||||
if (![kfm isWritableFileAtPath:volEnds]) {
|
||||
exitWithMessage("Error: target volume \"%s\" is not writable.\n", targetVol.UTF8String);
|
||||
exitWithMessage(@"Error: target volume \"%@\" is not writable.\n", targetVol);
|
||||
}
|
||||
|
||||
*/
|
||||
#pragma mark Check paths
|
||||
// check other options before proceed
|
||||
NSString *boot0Path = nil, *boot1Path = nil, *boot2Path = nil;
|
||||
if (boot0 != nil) {
|
||||
printf("boot0: %s\n", boot0.UTF8String);
|
||||
post(@"boot0: %@\n", boot0);
|
||||
[preferences setValue:boot0 forKey:@"boot0"];
|
||||
boot0Path = [[cloverv2 stringByAppendingPathComponent:@"BootSectors"] stringByAppendingPathComponent:boot0];
|
||||
if (![kfm fileExistsAtPath:boot0Path]) {
|
||||
exitWithMessage("Error: cannot found \"%s\".\n", boot0.UTF8String);
|
||||
exitWithMessage(@"Error: cannot found \"%@\".\n", boot0);
|
||||
}
|
||||
}
|
||||
|
||||
if (boot1 != nil) {
|
||||
printf("boot1: %s\n", boot1.UTF8String);
|
||||
post(@"boot1: %@\n", boot1);
|
||||
boot1Path = [[cloverv2 stringByAppendingPathComponent:@"BootSectors"] stringByAppendingPathComponent:boot1];
|
||||
if (![kfm fileExistsAtPath:boot1Path]) {
|
||||
exitWithMessage("Error: cannot found \"%s\".\n", boot1.UTF8String);
|
||||
exitWithMessage(@"Error: cannot found \"%@\".\n", boot1);
|
||||
}
|
||||
}
|
||||
|
||||
if (boot2 != nil) {
|
||||
printf("boot2: %s\n", boot2.UTF8String);
|
||||
post(@"boot2: %@\n", boot2);
|
||||
[preferences setValue:boot2 forKey:@"boot2"];
|
||||
boot2Path = [[cloverv2 stringByAppendingPathComponent:@"Bootloaders/x64"] stringByAppendingPathComponent:boot2];
|
||||
if (![kfm fileExistsAtPath:boot2Path]) {
|
||||
exitWithMessage("Error: cannot found \"%s\".\n", boot2.UTF8String);
|
||||
exitWithMessage(@"Error: cannot found \"%@\".\n", boot2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -216,7 +274,7 @@ int main(int argc, char * const * argv) {
|
||||
}
|
||||
|
||||
if (err != nil) {
|
||||
exitWithMessage("%s\n", err.description.UTF8String);
|
||||
exitWithMessage(@"%@\n", err.description);
|
||||
}
|
||||
|
||||
#pragma mark Create directories
|
||||
@ -225,6 +283,9 @@ int main(int argc, char * const * argv) {
|
||||
@"EFI/CLOVER/ACPI/origin",
|
||||
@"EFI/CLOVER/ACPI/patched",
|
||||
@"EFI/CLOVER/ACPI/WINDOWS",
|
||||
@"EFI/CLOVER/kexts/10",
|
||||
@"EFI/CLOVER/kexts/10_recovery",
|
||||
@"EFI/CLOVER/kexts/10_installer",
|
||||
@"EFI/CLOVER/kexts/10.11",
|
||||
@"EFI/CLOVER/kexts/10.12",
|
||||
@"EFI/CLOVER/kexts/10.13",
|
||||
@ -241,26 +302,26 @@ int main(int argc, char * const * argv) {
|
||||
if (![kfm fileExistsAtPath:fp]) {
|
||||
[kfm createDirectoryAtPath:fp withIntermediateDirectories:YES attributes:attributes error:&err];
|
||||
if (err != nil) {
|
||||
exitWithMessage("%s\n", err.description.UTF8String);
|
||||
exitWithMessage(@"%@\n", err.description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark Install Clover and drivers
|
||||
printf("\nInstalling/Updating Clover:\n");
|
||||
post(@"\nInstalling/Updating Clover:\n");
|
||||
if (!copyReplace([cloverv2 stringByAppendingPathComponent:@"EFI/BOOT/BOOTX64.efi"],
|
||||
[targetVol stringByAppendingPathComponent:@"EFI/BOOT/BOOTX64.efi"],
|
||||
attributes)) {
|
||||
exitWithMessage("Error: cannot copy BOOTX64.efi to destination.\n");
|
||||
exitWithMessage(@"Error: cannot copy BOOTX64.efi to destination.\n");
|
||||
}
|
||||
|
||||
if (!copyReplace([cloverv2 stringByAppendingPathComponent:@"EFI/CLOVER/CLOVERX64.efi"],
|
||||
[targetVol stringByAppendingPathComponent:@"EFI/CLOVER/CLOVERX64.efi"],
|
||||
attributes)) {
|
||||
exitWithMessage("Error: cannot copy CLOVERX64.efi to destination.\n");
|
||||
exitWithMessage(@"Error: cannot copy CLOVERX64.efi to destination.\n");
|
||||
}
|
||||
|
||||
printf("\nInstalling/Updating drivers:\n");
|
||||
post(@"\nInstalling/Updating drivers:\n");
|
||||
NSArray * toDelete = [CloverappDict objectForKey:@"toDelete"];
|
||||
NSArray * UEFI = [CloverappDict objectForKey:@"UEFI"];
|
||||
NSArray * BIOS = [CloverappDict objectForKey:@"BIOS"];
|
||||
@ -272,7 +333,7 @@ int main(int argc, char * const * argv) {
|
||||
NSString *dpath = [UEFI objectAtIndex:i];
|
||||
NSString *dname = [dpath lastPathComponent];
|
||||
if (!copyReplace(dpath, [UEFIdest stringByAppendingPathComponent:dname], attributes)) {
|
||||
exitWithMessage("Error: cannot copy %s to destination.\n", dpath.UTF8String);
|
||||
exitWithMessage(@"Error: cannot copy %@ to destination.\n", dpath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -282,7 +343,7 @@ int main(int argc, char * const * argv) {
|
||||
NSString *dpath = [BIOS objectAtIndex:i];
|
||||
NSString *dname = [dpath lastPathComponent];
|
||||
if (!copyReplace(dpath, [BIOSdest stringByAppendingPathComponent:dname], attributes)) {
|
||||
exitWithMessage("Error: cannot copy %s to destination.\n");
|
||||
exitWithMessage(@"Error: cannot copy %@ to destination.\n", dpath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -292,12 +353,12 @@ int main(int argc, char * const * argv) {
|
||||
NSString *dpath = [toDelete objectAtIndex:i];
|
||||
err = nil;
|
||||
if ([kfm fileExistsAtPath:dpath]) {
|
||||
printf("- ../%s/%s\n",
|
||||
[[dpath stringByDeletingLastPathComponent] lastPathComponent].UTF8String,
|
||||
[dpath lastPathComponent].UTF8String);
|
||||
post(@"- ../%@/%@\n",
|
||||
[[dpath stringByDeletingLastPathComponent] lastPathComponent],
|
||||
[dpath lastPathComponent]);
|
||||
[kfm removeItemAtPath:dpath error:&err];
|
||||
if (err != nil) {
|
||||
exitWithMessage("%s\n", err.description.UTF8String);
|
||||
exitWithMessage(@"%@\n", err.description);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -306,7 +367,7 @@ int main(int argc, char * const * argv) {
|
||||
#pragma mark Install tools
|
||||
NSString *cv2tools = [cloverv2 stringByAppendingPathComponent:@"EFI/CLOVER/tools"];
|
||||
if ([kfm fileExistsAtPath:cv2tools]) {
|
||||
printf("\nInstalling/Updating tools:\n");
|
||||
post(@"\nInstalling/Updating tools:\n");
|
||||
err = nil;
|
||||
NSArray *tools = [kfm contentsOfDirectoryAtPath:cv2tools error:&err];
|
||||
if (err == nil && tools != nil) {
|
||||
@ -317,7 +378,7 @@ int main(int argc, char * const * argv) {
|
||||
[[targetVol stringByAppendingPathComponent:@"EFI/CLOVER/tools"]
|
||||
stringByAppendingPathComponent:t],
|
||||
attributes)) {
|
||||
exitWithMessage("Error: cannot copy %s to destination.\n", t.UTF8String);
|
||||
exitWithMessage(@"Error: cannot copy %@ to destination.\n", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -328,7 +389,7 @@ int main(int argc, char * const * argv) {
|
||||
#pragma mark Install docs
|
||||
NSString *cv2docs = [cloverv2 stringByAppendingPathComponent:@"EFI/CLOVER/doc"];
|
||||
if ([kfm fileExistsAtPath:cv2tools]) {
|
||||
printf("\nInstalling/Updating doc:\n");
|
||||
post(@"\nInstalling/Updating doc:\n");
|
||||
err = nil;
|
||||
NSArray *docs = [kfm contentsOfDirectoryAtPath:cv2docs error:&err];
|
||||
if (err == nil && docs != nil) {
|
||||
@ -342,9 +403,9 @@ int main(int argc, char * const * argv) {
|
||||
stringByAppendingPathComponent:d],
|
||||
docattr)) {
|
||||
|
||||
//exitWithMessage("Error: cannot copy %s to destination.\n", d.UTF8String);
|
||||
//exitWithMessage(@"Error: cannot copy %@ to destination.\n", d);
|
||||
// ... will not fail for a doc..
|
||||
printf("Error: cannot copy %s to destination.\n", d.UTF8String);
|
||||
post(@"Error: cannot copy %@ to destination.\n", d);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -356,7 +417,7 @@ int main(int argc, char * const * argv) {
|
||||
NSString *configPath = [targetVol stringByAppendingPathComponent:@"EFI/CLOVER/config.plist"];
|
||||
NSString *configSamplePath = [cloverv2 stringByAppendingPathComponent:@"EFI/CLOVER/config-sample.plist"];
|
||||
if (![kfm fileExistsAtPath:configPath]) {
|
||||
printf("\nInstalling config.plist:\n");
|
||||
post(@"\nInstalling config.plist:\n");
|
||||
copyReplace(configSamplePath, configPath, attributes);
|
||||
}
|
||||
|
||||
@ -376,7 +437,7 @@ int main(int argc, char * const * argv) {
|
||||
// don't overwrite the theme if already exist as one from CTM can be newer
|
||||
if (theme != nil && ![kfm fileExistsAtPath:
|
||||
[themesDestDir stringByAppendingPathComponent:theme]]) {
|
||||
printf("\nInstalling Theme \"%s\":\n", theme.UTF8String);
|
||||
post(@"\nInstalling Theme \"%@\":\n", theme);
|
||||
copyReplace([themesSourceDir stringByAppendingPathComponent:theme],
|
||||
[themesDestDir stringByAppendingPathComponent:theme],
|
||||
attributes);
|
||||
@ -385,9 +446,9 @@ int main(int argc, char * const * argv) {
|
||||
|
||||
#pragma mark Stage 2 installation
|
||||
if (boot2Path != nil) {
|
||||
printf("\nInstalling stage 2..\n");
|
||||
post(@"\nInstalling stage 2..\n");
|
||||
if (!copyReplace(boot2Path, [targetVol stringByAppendingPathComponent:@"boot"], attributes)) {
|
||||
exitWithMessage("Error: cannot copy bootloader to detination.\n");
|
||||
exitWithMessage(@"Error: cannot copy bootloader to detination.\n");
|
||||
}
|
||||
|
||||
if (alt) {
|
||||
@ -398,7 +459,7 @@ int main(int argc, char * const * argv) {
|
||||
for (int i = 0; i < [files count]; i++) {
|
||||
NSString *f = [files objectAtIndex:i];
|
||||
if ([f hasPrefix:@"boot"]) {
|
||||
printf("\nInstalling stage 2 \"%s (alt)\".\n", f.UTF8String);
|
||||
post(@"\nInstalling stage 2 \"%@ (alt)\".\n", f);
|
||||
copyReplace([altPath stringByAppendingPathComponent: f],
|
||||
[targetVol stringByAppendingPathComponent:f],
|
||||
attributes);
|
||||
@ -414,6 +475,7 @@ int main(int argc, char * const * argv) {
|
||||
[kfm setAttributes:attributes ofItemAtPath:prefPath error:nil];
|
||||
}
|
||||
|
||||
saveLog();
|
||||
#pragma mark Boot sectors installation
|
||||
if (boot0Path != nil && boot1Path != nil && bootSectorsInstallSrc != nil) {
|
||||
// copy bootsectors-install
|
||||
@ -447,7 +509,7 @@ int main(int argc, char * const * argv) {
|
||||
|
||||
task.terminationHandler = ^(NSTask *theTask) {
|
||||
if (theTask.terminationStatus != 0) {
|
||||
exitWithMessage("Error: failed installing boot sectors.");
|
||||
exitWithMessage(@"Error: failed installing boot sectors.\n");
|
||||
}
|
||||
};
|
||||
[task launch];
|
||||
@ -456,10 +518,11 @@ int main(int argc, char * const * argv) {
|
||||
if (data) {
|
||||
NSString *output = [[NSString alloc] initWithData:data
|
||||
encoding:NSUTF8StringEncoding];
|
||||
printf("%s\n", [output UTF8String]);
|
||||
post(@"%@\n", output);
|
||||
}
|
||||
|
||||
} else {
|
||||
saveLog();
|
||||
if (isESP) {
|
||||
NSTask *task = [[NSTask alloc] init];
|
||||
[task setEnvironment:[[NSProcessInfo new] environment]];
|
||||
|
@ -88,7 +88,7 @@
|
||||
95509157238B132100933A7E /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 1120;
|
||||
LastUpgradeCheck = 1130;
|
||||
ORGANIZATIONNAME = CloverHackyColor;
|
||||
TargetAttributes = {
|
||||
9550915E238B132100933A7E = {
|
||||
@ -238,6 +238,7 @@
|
||||
95509167238B132100933A7E /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
@ -246,6 +247,7 @@
|
||||
95509168238B132100933A7E /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user