diff --git a/.gitmodules b/.gitmodules index 0a0aa70..06f5511 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,3 +2,6 @@ path = Zsign url = https://github.com/khcrysalis/Zsign-Package branch = package +[submodule "IDeviceKit"] + path = IDeviceKit + url = https://github.com/khcrysalis/IDeviceKit diff --git a/IDeviceKit b/IDeviceKit new file mode 160000 index 0000000..4b4b772 --- /dev/null +++ b/IDeviceKit @@ -0,0 +1 @@ +Subproject commit 4b4b772b82d81082af90403f0d9f519daacdd252 diff --git a/Ksign.xcodeproj/project.pbxproj b/Ksign.xcodeproj/project.pbxproj index 0dfd2f1..21f186e 100644 --- a/Ksign.xcodeproj/project.pbxproj +++ b/Ksign.xcodeproj/project.pbxproj @@ -19,6 +19,9 @@ 336D43982DB7454A00206400 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 336D43972DB7454A00206400 /* MobileCoreServices.framework */; }; 3371F7322DA9ECDD00281AC6 /* Zip in Frameworks */ = {isa = PBXBuildFile; productRef = 3371F7312DA9ECDD00281AC6 /* Zip */; }; 33CF13392DB5ACFB0021D4C5 /* SWCompression in Frameworks */ = {isa = PBXBuildFile; productRef = 33CF13382DB5ACFB0021D4C5 /* SWCompression */; }; + C42CC1AD2F4370F20064A4A2 /* IDevice in Frameworks */ = {isa = PBXBuildFile; productRef = C42CC1AC2F4370F20064A4A2 /* IDevice */; }; + C42CC1AF2F4370F20064A4A2 /* IDeviceSwift in Frameworks */ = {isa = PBXBuildFile; productRef = C42CC1AE2F4370F20064A4A2 /* IDeviceSwift */; }; + C42CC1B12F4370F20064A4A2 /* plist in Frameworks */ = {isa = PBXBuildFile; productRef = C42CC1B02F4370F20064A4A2 /* plist */; }; C451296C2E54F0DC00E94CC7 /* ZIPFoundation in Frameworks */ = {isa = PBXBuildFile; productRef = C451296B2E54F0DB00E94CC7 /* ZIPFoundation */; }; C4CEAE0C2DDF4735007EF880 /* ArArchiveKit in Frameworks */ = {isa = PBXBuildFile; productRef = C4CEAE0B2DDF4735007EF880 /* ArArchiveKit */; }; /* End PBXBuildFile section */ @@ -43,16 +46,8 @@ 3371F6492DA92A1800281AC6 /* Exceptions for "Ksign" folder in "Ksign" target */ = { isa = PBXFileSystemSynchronizedBuildFileExceptionSet; membershipExceptions = ( - Backend/Heartbeat/ConduitInstaller.swift, - Backend/Heartbeat/Heartbeat.swift, - "Backend/Heartbeat/Heartbeat+checks.swift", - "Backend/Heartbeat/Heartbeat+start.swift", Resources/ellekit.deb, - Resources/idevice/libidevice_ffi.a, - "Resources/idevice/libplist-2.0.a", Resources/Info.plist, - "Views/Settings/Tunnel & Pairing/TunnelHeaderCellView.swift", - "Views/Settings/Tunnel & Pairing/TunnelView.swift", ); target = 3379C1B82DA869A1004372DA /* Ksign */; }; @@ -87,7 +82,9 @@ files = ( 330F68FE2DBF7C8600D8C35D /* NimbleViews in Frameworks */, C4CEAE0C2DDF4735007EF880 /* ArArchiveKit in Frameworks */, + C42CC1AF2F4370F20064A4A2 /* IDeviceSwift in Frameworks */, 330F68FC2DBF7C8600D8C35D /* NimbleExtensions in Frameworks */, + C42CC1AD2F4370F20064A4A2 /* IDevice in Frameworks */, 3346F5C22DC329A200C7D508 /* ZsignSwift in Frameworks */, 3346F8492DC6D64800C7D508 /* NimbleJSON in Frameworks */, 330F69012DC03DF500D8C35D /* NimbleExtensions in Frameworks */, @@ -98,6 +95,7 @@ 3305BBAC2DB8944200660D45 /* Vapor in Frameworks */, 3346F83B2DC6C6D100C7D508 /* NukeUI in Frameworks */, 336D43982DB7454A00206400 /* MobileCoreServices.framework in Frameworks */, + C42CC1B12F4370F20064A4A2 /* plist in Frameworks */, C451296C2E54F0DC00E94CC7 /* ZIPFoundation in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -173,6 +171,9 @@ 33693A072DC8BF5B00730215 /* AltSourceKit */, C4CEAE0B2DDF4735007EF880 /* ArArchiveKit */, C451296B2E54F0DB00E94CC7 /* ZIPFoundation */, + C42CC1AC2F4370F20064A4A2 /* IDevice */, + C42CC1AE2F4370F20064A4A2 /* IDeviceSwift */, + C42CC1B02F4370F20064A4A2 /* plist */, ); productName = Feather; productReference = 3379C1B92DA869A1004372DA /* Ksign.app */; @@ -244,6 +245,7 @@ C4CEAE0A2DDF416B007EF880 /* XCRemoteSwiftPackageReference "ArArchiveKit" */, C40422132E119AF900D1F324 /* XCLocalSwiftPackageReference "Zsign" */, C45128062E54E8E900E94CC7 /* XCRemoteSwiftPackageReference "ZIPFoundation" */, + C42CC1AB2F4370F20064A4A2 /* XCLocalSwiftPackageReference "IDeviceKit" */, ); preferredProjectObjectVersion = 77; productRefGroup = 3379C1BA2DA869A1004372DA /* Products */; @@ -667,6 +669,10 @@ isa = XCLocalSwiftPackageReference; relativePath = Zsign; }; + C42CC1AB2F4370F20064A4A2 /* XCLocalSwiftPackageReference "IDeviceKit" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = IDeviceKit; + }; /* End XCLocalSwiftPackageReference section */ /* Begin XCRemoteSwiftPackageReference section */ @@ -782,6 +788,18 @@ package = 33CF13372DB5ACFB0021D4C5 /* XCRemoteSwiftPackageReference "SWCompression" */; productName = SWCompression; }; + C42CC1AC2F4370F20064A4A2 /* IDevice */ = { + isa = XCSwiftPackageProductDependency; + productName = IDevice; + }; + C42CC1AE2F4370F20064A4A2 /* IDeviceSwift */ = { + isa = XCSwiftPackageProductDependency; + productName = IDeviceSwift; + }; + C42CC1B02F4370F20064A4A2 /* plist */ = { + isa = XCSwiftPackageProductDependency; + productName = plist; + }; C451296B2E54F0DB00E94CC7 /* ZIPFoundation */ = { isa = XCSwiftPackageProductDependency; package = C45128062E54E8E900E94CC7 /* XCRemoteSwiftPackageReference "ZIPFoundation" */; diff --git a/Ksign/Backend/Heartbeat/ConduitInstaller.swift b/Ksign/Backend/Heartbeat/ConduitInstaller.swift deleted file mode 100644 index 48b373a..0000000 --- a/Ksign/Backend/Heartbeat/ConduitInstaller.swift +++ /dev/null @@ -1,182 +0,0 @@ -// -// ConduitInstaller.swift -// Feather -// -// Created by samara on 23.04.2025. -// - -import Foundation -import SwiftUICore - -class ConduitInstaller: Identifiable, ObservableObject { - private let _heartbeat = HeartbeatManager.shared - private let _uuid = UUID().uuidString - - typealias AfcClientHandle = OpaquePointer - typealias AfcFileHandle = OpaquePointer - typealias InstallationProxyClientHandle = OpaquePointer - - @ObservedObject var viewModel: InstallerStatusViewModel - - init(viewModel: InstallerStatusViewModel) { - self.viewModel = viewModel - } - - func install(at url: URL) async throws { - var afcClient: AfcClientHandle? - var fileHandle: AfcFileHandle? - var installproxy: InstallationProxyClientHandle? - - try await Task.detached(priority: .userInitiated) { - guard FileManager.default.fileExists(atPath: HeartbeatManager.pairingFile()) else { - throw ConduitInstallerError.missingPairing - } - - guard await self._heartbeat.checkSocketConnection().isConnected else { - throw ConduitInstallerError.missingPairing - } - - defer { - afc_client_free(afcClient) - installation_proxy_client_free(installproxy) - } - - let heartbeat = await self._heartbeat - guard let provider = heartbeat.provider else { - throw ConduitInstallerError.cannotConnectToAFC - } - - guard afc_client_connect_tcp(provider, &afcClient) == IdeviceSuccess else { - throw ConduitInstallerError.cannotConnectToAFC - } - - let stagingDir = "PublicStaging" - - guard afc_make_directory(afcClient, stagingDir) == IdeviceSuccess else { - throw ConduitInstallerError.unableToCreateStaging - } - - let remoteDir = "/\(stagingDir)/\(self._uuid).ipa" - - guard afc_file_open(afcClient, remoteDir, AfcWrOnly, &fileHandle) == IdeviceSuccess else { - throw ConduitInstallerError.unableToCreateStaging - } - - try await self._updateStatus(with: .sendingPayload) - - guard let fileHandle = fileHandle else { - throw ConduitInstallerError.missingFileHandle - } - - let data = try Data(contentsOf: url) - let totalSize = data.count - let chunkSize = 64 * 1024 // 64kb - var totalBytesWritten = 0 - - guard let rawBuffer = data.withUnsafeBytes({ $0.baseAddress })?.assumingMemoryBound(to: UInt8.self) else { - throw ConduitInstallerError.writeErrorAFC - } - - while totalBytesWritten < totalSize { - let bytesLeft = totalSize - totalBytesWritten - let bytesToWrite = min(chunkSize, bytesLeft) - let writePtr = rawBuffer.advanced(by: totalBytesWritten) - - let result = afc_file_write(fileHandle, writePtr, bytesToWrite) - if result != IdeviceSuccess { - throw ConduitInstallerError.writeErrorAFC - } - - totalBytesWritten += bytesToWrite - - let progress = Double(totalBytesWritten) / Double(totalSize) - try await self._updateUploadProgress(with: progress) - } - - guard afc_file_close(fileHandle) == IdeviceSuccess else { - throw ConduitInstallerError.missingFileHandle - } - - try await self._updateStatus(with: .installing) - - guard installation_proxy_connect_tcp(provider, &installproxy) == IdeviceSuccess else { - throw ConduitInstallerError.unableToCreateStaging - } - - let installError: IdeviceErrorCode = remoteDir.withCString { cString in - let context = Unmanaged.passUnretained(self).toOpaque() - - return installation_proxy_install_with_callback( - installproxy, - cString, - nil, // options - Self._installationProgressCallback, - context - ) - } - - guard installError == IdeviceSuccess else { - throw ConduitInstallerError.unableToInstall - } - - try await Task.sleep(nanoseconds: 350_000_000) - try await self._updateStatus(with: .completed(.success(()))) - }.value - } - - private func _updateStatus(with status: InstallerStatus) async throws { - await MainActor.run { - self.viewModel.status = status - } - } - - private func _updateUploadProgress(with status: Double) async throws { - await MainActor.run { - self.viewModel.uploadProgress = status - } - } - - nonisolated - static private let _installationProgressCallback: @convention(c) ( - UInt64, - UnsafeMutableRawPointer? - ) -> Void = { progress, context in - guard let context = context else { return } - let installer = Unmanaged.fromOpaque(context).takeUnretainedValue() - Task { - try? await installer._updateInstallProgress(with: Double(progress) / 100.0) - } - } - - private func _updateInstallProgress(with status: Double) async throws { - await MainActor.run { - self.viewModel.installProgress = status - } - } -} - -private enum ConduitInstallerError: Error, LocalizedError { - case missingPairing - case cannotConnectToAFC - case unableToCreateStaging - case writeErrorAFC - case missingFileHandle - case unableToInstall - - var errorDescription: String? { - switch self { - case .missingPairing: - return "Unable to connect to TCP. Make sure you have loopback VPN enabled and you are on WiFi or Airplane mode." - case .cannotConnectToAFC: - return "Cannot connect to AFC (Apple File Conduit)." - case .unableToCreateStaging: - return "Unable to create the staging directory." - case .writeErrorAFC: - return "Error writing to AFC." - case .missingFileHandle: - return "Missing file handle for AFC operation." - case .unableToInstall: - return "Unable to install specified application. Please check if your app is signed properly and not already installed onto your device with a different certificate." - } - } -} diff --git a/Ksign/Backend/Heartbeat/Heartbeat+checks.swift b/Ksign/Backend/Heartbeat/Heartbeat+checks.swift deleted file mode 100644 index f152bec..0000000 --- a/Ksign/Backend/Heartbeat/Heartbeat+checks.swift +++ /dev/null @@ -1,96 +0,0 @@ -// -// Heartbeat+checks.swift -// Feather -// -// Created by samara on 29.04.2025. -// - -import Foundation - -// MARK: - Class extension: socket -extension HeartbeatManager { - /// Check connection to socket/tunnel - /// - Returns: Tuple for connection status and error message (if any) - func checkSocketConnection(timeoutInSeconds: Double = 2.0) -> (isConnected: Bool, error: String?) { - let socketFD = socket(AF_INET, SOCK_STREAM, 0) - if socketFD == -1 { - return (false, "Failed to create socket") - } - - defer { - close(socketFD) - } - - let flags = fcntl(socketFD, F_GETFL, 0) - if flags == -1 { - return (false, "Failed to get socket flags") - } - if fcntl(socketFD, F_SETFL, flags | O_NONBLOCK) == -1 { - return (false, "Failed to set socket to non-blocking mode") - } - - var addr = sockaddr_in() - memset(&addr, 0, MemoryLayout.size(ofValue: addr)) - addr.sin_family = sa_family_t(AF_INET) - addr.sin_port = CFSwapInt16HostToBig(port) - - guard inet_pton(AF_INET, ipAddress, &addr.sin_addr) == 1 else { - return (false, "Invalid IP address format") - } - - let connectResult = withUnsafePointer(to: &addr) { - $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { sockaddrPtr in - connect(socketFD, sockaddrPtr, socklen_t(MemoryLayout.size)) - } - } - - if connectResult != 0 { - if errno != EINPROGRESS { - return (false, "Failed to connect: \(String(cString: strerror(errno)))") - } - - let writeFds = fd_set() - var writeSet = fd_set() - __darwin_fd_set(socketFD, &writeSet) - - var timeout = timeval() - timeout.tv_sec = Int(timeoutInSeconds) - timeout.tv_usec = __darwin_suseconds_t(Int((timeoutInSeconds - Double(timeout.tv_sec)) * 1_000_000)) - - let selectResult = select(socketFD + 1, nil, &writeSet, nil, &timeout) - - if selectResult == 0 { - return (false, "Connection timed out") - } else if selectResult == -1 { - return (false, "Select failed: \(String(cString: strerror(errno)))") - } - - var error: Int32 = 0 - var len = socklen_t(MemoryLayout.size) - if getsockopt(socketFD, SOL_SOCKET, SO_ERROR, &error, &len) == -1 { - return (false, "Failed to get socket options") - } - - if error != 0 { - return (false, "Connection failed: \(String(cString: strerror(error)))") - } - } - - return (true, nil) - } - /// Retrieves and reads pairing file (if any) - /// - Returns: Pointer to pairing file - func getPairing() -> IdevicePairingFile? { - guard fileManager.fileExists(atPath: Self.pairingFile()) else { - return nil - } - - var pairingFile: IdevicePairingFile? - - guard idevice_pairing_file_read(Self.pairingFile(), &pairingFile) == IdeviceSuccess else { - return nil - } - - return pairingFile - } -} diff --git a/Ksign/Backend/Heartbeat/Heartbeat+start.swift b/Ksign/Backend/Heartbeat/Heartbeat+start.swift deleted file mode 100644 index 18b8883..0000000 --- a/Ksign/Backend/Heartbeat/Heartbeat+start.swift +++ /dev/null @@ -1,224 +0,0 @@ -// -// Heartbeat+start.swift -// Feather -// -// Created by samara on 29.04.2025. -// - -import Foundation -import UIKit - -// MARK: - Class extension: start -extension HeartbeatManager { - /// Starts heartbeat - /// - Parameter forceRestart: Force restarts heartbeat - func start(_ forceRestart: Bool = false) { - restartLock.lock() - defer { restartLock.unlock() } - - restartWorkItem?.cancel() - restartWorkItem = nil - - if isRestartInProgress && !forceRestart { - print("Restart already in progress, ignoring call") - return - } - - let existingThreadIsActive = heartbeatThread?.isExecuting ?? false - if forceRestart { - sessionId = arc4random() - print("Forcing heartbeat restart with new session ID") - } else if existingThreadIsActive { - print("Heartbeat thread already running") - return - } - - if heartbeatThread != nil && !existingThreadIsActive { - heartbeatThread = nil - } - - isRestartInProgress = true - - heartbeatThread = Thread { [weak self] in - guard let self = self else { return } - - self._establishHeartbeat { [weak self] error in - guard let self = self else { return } - - self.restartLock.lock() - defer { self.restartLock.unlock() } - - if let error = error { - print("Heartbeat error: \(error)") - self._scheduleRestart() - } else { - self.restartBackoffTime = 1.0 - self.isRestartInProgress = false - } - } - } - - // Start - if let thread = heartbeatThread { - thread.name = "idevice-heartbeat" - thread.qualityOfService = .background - thread.start() - print("Started new heartbeat thread") - } - } - /// Schedules heartbeat restart if any errors occur - private func _scheduleRestart() { - let workItem = DispatchWorkItem { [weak self] in - guard let self = self else { return } - - self.restartLock.lock() - self.isRestartInProgress = false - self.restartWorkItem = nil - self.restartLock.unlock() - - self.start() - } - - restartWorkItem = workItem - restartBackoffTime = min(restartBackoffTime * 1.5, 30.0) - - print("Scheduling restart in \(restartBackoffTime) seconds") - DispatchQueue.main.asyncAfter(deadline: .now() + restartBackoffTime, execute: workItem) - } - /// Establishes heartbeat - /// - Parameter completion: Completes with optionally an idevice error code - private func _establishHeartbeat( - completion: @escaping (IdeviceErrorCode?) -> Void - ) { - guard let pairingFile = getPairing() else { - completion(nil) - return - } - - sessionId = arc4random() - - guard checkSocketConnection().isConnected else { - print("Socket connection check failed - device unreachable") - completion(NotFound) - return - } - - _startHeartbeat( - pairingFile: pairingFile, - provider: &provider, - sessionId: sessionId - ) { err in - completion(err) - } - } - /// Starts heartbeat - /// - Parameters: - /// - pairingFile: Pointer to pairing file - /// - provider: Pointer to TCP Provider - /// - sessionId: Random sessionID - /// - completion: Completes with optionally an idevice error code - private func _startHeartbeat( - pairingFile: IdevicePairingFile, - provider: inout TcpProviderHandle?, - sessionId: UInt32?, - completion: @escaping (IdeviceErrorCode?) -> Void - ) { - let currentSession = sessionId - - var addr = sockaddr_in() - memset(&addr, 0, MemoryLayout.size(ofValue: addr)) - addr.sin_family = sa_family_t(AF_INET) - addr.sin_port = CFSwapInt16HostToBig(port) - - guard inet_pton(AF_INET, ipAddress, &addr.sin_addr) == 1 else { - print("Invalid IP address") - completion(UnknownErrorType) - return - } - - let result = withUnsafePointer(to: &addr) { - $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { sockaddrPtr in - idevice_tcp_provider_new(sockaddrPtr, pairingFile, "SS-Provider", &provider) - } - } - - if result != IdeviceSuccess { - print("Failed to create TCP provider: \(result)") - completion(result) - return - } - - var heartbeatClient: HeartbeatClientHandle? - let hbConnectResult = heartbeat_connect_tcp(provider, &heartbeatClient) - if hbConnectResult != IdeviceSuccess { - print("Failed to start heartbeat client: \(hbConnectResult)") - - if hbConnectResult == InvalidHostID, fileManager.fileExists(atPath: Self.pairingFile()) { - print("Deleting pairing file, requesting for a new one.") - try? fileManager.removeItem(atPath: Self.pairingFile()) - - DispatchQueue.main.async { - UIAlertController.showAlertWithOk( - title: "InvalidHostID", - message: "Your pairing file is invalid and is incompatible with your device, please import a valid pairing file." - ) - } - } - - completion(hbConnectResult) - return - } - - completion(nil) - - _runHeartbeatLoop( - heartbeatClient: heartbeatClient!, - currentSession: currentSession, - sessionId: sessionId - ) - } - /// Runs heartbeat loop - /// - Parameters: - /// - heartbeatClient: Heartbeat Client pointer - /// - currentSession: "Current" sessionID - /// - sessionId: Random sessionID - private func _runHeartbeatLoop( - heartbeatClient: HeartbeatClientHandle, - currentSession: UInt32?, - sessionId: UInt32? - ) { - var currentInterval: UInt64 = 15 - - while true { - if sessionId != currentSession { - break - } - - var nextInterval: UInt64 = 0 - - let marcoResult = heartbeat_get_marco(heartbeatClient, currentInterval, &nextInterval) - if marcoResult != IdeviceSuccess { - print("heartbeat_get_marco failed: \(marcoResult)") - heartbeat_client_free(heartbeatClient) - return - } - - DispatchQueue.main.async { - NotificationCenter.default.post(name: .heartbeat, object: nil) - } - - #if DEBUG - print("bump \(Date.now.formatted(date: .numeric, time: .standard))") - #endif - - currentInterval = nextInterval + 5 - - let poloResult = heartbeat_send_polo(heartbeatClient) - if poloResult != IdeviceSuccess { - print("heartbeat_send_polo failed: \(poloResult)") - heartbeat_client_free(heartbeatClient) - return - } - } - } -} diff --git a/Ksign/Backend/Heartbeat/Heartbeat.swift b/Ksign/Backend/Heartbeat/Heartbeat.swift deleted file mode 100644 index 08cd53c..0000000 --- a/Ksign/Backend/Heartbeat/Heartbeat.swift +++ /dev/null @@ -1,60 +0,0 @@ -// -// Heartbeat.swift -// Feather -// -// Created by samara on 23.04.2025. -// - -import Foundation -import UIKit.UIApplication -import Combine - -// MARK: - Class -// ـ♡ﮩ٨ـ heartbeat ♪₊˚ -class HeartbeatManager { - static let shared = HeartbeatManager() - - typealias IdevicePairingFile = OpaquePointer - typealias TcpProviderHandle = OpaquePointer - typealias HeartbeatClientHandle = OpaquePointer - - var fileManager = FileManager.default - var provider: TcpProviderHandle? - var heartbeatThread: Thread? - - var sessionId: UInt32? = nil - let ipAddress: String = "10.7.0.1" - let port: UInt16 = UInt16(LOCKDOWN_PORT) - - let restartLock = NSLock() - var isRestartInProgress = false - var restartBackoffTime: TimeInterval = 1.0 - var restartWorkItem: DispatchWorkItem? - var firstRun = false - - var cancellable: AnyCancellable? // Combine - - // One important note is that if a user gets `InvalidHostID -9` from heartbeat - // we need to ask them to reimport a fresh pairingfile, - init() { - #if DEBUG - idevice_init_logger(IdeviceLogLevel.init(3), Disabled, nil) - #endif - - // On first start, just be a normal run, on second and onwards - // we force restart it with a different sessionid - cancellable = NotificationCenter.default - .publisher(for: UIApplication.willEnterForegroundNotification) - .receive(on: DispatchQueue.main) - .sink { notification in - let forceRestart = self.firstRun - self.firstRun = true - self.start(forceRestart) - } - } - /// Returns (idevice) pairing file path - /// - Returns: `Documents/Feather/pairingFile.plist` - static func pairingFile() -> String { - URL.documentsDirectory.appendingPathComponent("pairingFile.plist").path() - } -} diff --git a/Ksign/Backend/Observable/InstallerStatusViewModel.swift b/Ksign/Backend/Observable/InstallerStatusViewModel.swift index 9a46c83..62dc96b 100644 --- a/Ksign/Backend/Observable/InstallerStatusViewModel.swift +++ b/Ksign/Backend/Observable/InstallerStatusViewModel.swift @@ -7,32 +7,9 @@ import Foundation import Combine +import IDeviceSwift -final class InstallerStatusViewModel: ObservableObject { - @Published var status: InstallerStatus - - @Published var uploadProgress: Double = 0.0 - @Published var packageProgress: Double = 0.0 - @Published var installProgress: Double = 0.0 - - var overallProgress: Double { - #if IDEVICE - (installProgress + uploadProgress + packageProgress) / 3.0 - #elseif SERVER - packageProgress - #endif - } - - var isCompleted: Bool { - if case .completed = status { - return true - } - return false - } - - init(status: InstallerStatus = .none) { - self.status = status - } +extension InstallerStatusViewModel { var statusImage: String { switch status { @@ -57,13 +34,3 @@ final class InstallerStatusViewModel: ObservableObject { } } } - -enum InstallerStatus { - case none - case ready - case sendingManifest - case sendingPayload - case installing - case completed(Result) - case broken(Error) -} diff --git a/Ksign/Backend/Server/ServerInstaller.swift b/Ksign/Backend/Server/ServerInstaller.swift index 425a569..873228d 100644 --- a/Ksign/Backend/Server/ServerInstaller.swift +++ b/Ksign/Backend/Server/ServerInstaller.swift @@ -12,6 +12,7 @@ import Vapor import NIOSSL import NIOTLS import SwiftUI +import IDeviceSwift // MARK: - Class class ServerInstaller: Identifiable, ObservableObject { @@ -85,7 +86,7 @@ class ServerInstaller: Identifiable, ObservableObject { _server.shutdown() } - private func _updateStatus(_ newStatus: InstallerStatus) { + private func _updateStatus(_ newStatus: InstallerStatusViewModel.InstallerStatus) { DispatchQueue.main.async { self.viewModel.status = newStatus } diff --git a/Ksign/Extensions/Notification+custom.swift b/Ksign/Extensions/Notification+custom.swift deleted file mode 100644 index c49d8a3..0000000 --- a/Ksign/Extensions/Notification+custom.swift +++ /dev/null @@ -1,12 +0,0 @@ -// -// Notification+custom.swift -// Feather -// -// Created by samara on 29.04.2025. -// - -import Foundation.NSNotification - -extension Notification.Name { - static let heartbeat = Notification.Name("FR.heartBeat") -} diff --git a/Ksign/FeatherApp.swift b/Ksign/FeatherApp.swift index 9ec7557..89ea60a 100644 --- a/Ksign/FeatherApp.swift +++ b/Ksign/FeatherApp.swift @@ -8,13 +8,12 @@ import SwiftUI import Nuke import OSLog +import IDeviceSwift @main struct FeatherApp: App { @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate - #if IDEVICE let heartbeat = HeartbeatManager.shared - #endif @StateObject var downloadManager = DownloadManager.shared @StateObject var accentColorManager = AccentColorManager.shared @StateObject var extractManager = ExtractManager.shared diff --git a/Ksign/Resources/Localizable.xcstrings b/Ksign/Resources/Localizable.xcstrings index 4673525..d10aecc 100644 --- a/Ksign/Resources/Localizable.xcstrings +++ b/Ksign/Resources/Localizable.xcstrings @@ -796,6 +796,17 @@ } } }, + "Advanced Installation Method" : { + "extractionState" : "manual", + "localizations" : { + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tính năng cài đặt nâng cao" + } + } + } + }, "Alert" : { "extractionState" : "manual", "localizations" : { @@ -4885,6 +4896,23 @@ } } }, + "idevice warning" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "This is an advanced installation method that required computer, proceed?" + } + }, + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Đây là phương thức cài đặt nâng cao, yêu cầu phải có máy tính để sử dụng. Bạn có chắc chắn không?" + } + } + } + }, "Import" : { "comment" : "Import repositories", "localizations" : { @@ -5446,6 +5474,17 @@ } } }, + "Installation" : { + "extractionState" : "manual", + "localizations" : { + "vi" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cài đặt" + } + } + } + }, "Installation Type" : { "extractionState" : "manual", "localizations" : { diff --git a/Ksign/Resources/idevice/libidevice_ffi.a b/Ksign/Resources/idevice/libidevice_ffi.a deleted file mode 100644 index 2e1c90f..0000000 Binary files a/Ksign/Resources/idevice/libidevice_ffi.a and /dev/null differ diff --git a/Ksign/Resources/idevice/libplist-2.0.a b/Ksign/Resources/idevice/libplist-2.0.a deleted file mode 100644 index 41adc1d..0000000 Binary files a/Ksign/Resources/idevice/libplist-2.0.a and /dev/null differ diff --git a/Ksign/Supporting Files/Feather-Bridging-Header.h b/Ksign/Supporting Files/Feather-Bridging-Header.h index 9ef91d7..be5185b 100644 --- a/Ksign/Supporting Files/Feather-Bridging-Header.h +++ b/Ksign/Supporting Files/Feather-Bridging-Header.h @@ -2,7 +2,3 @@ // Use this file to import your target's public headers that you would like to expose to Swift. // #include "MachOUtils.h" - -#if IDEVICE == 1 - #include "idevice.h" -#endif diff --git a/Ksign/Supporting Files/idevice/idevice.h b/Ksign/Supporting Files/idevice/idevice.h deleted file mode 100644 index c4cc328..0000000 --- a/Ksign/Supporting Files/idevice/idevice.h +++ /dev/null @@ -1,2792 +0,0 @@ -// Jackson Coxson -// Bindings to idevice - https://github.com/jkcoxson/idevice - -#include -#include -#include -#include -#include -#include "plist/plist.h" - -#define LOCKDOWN_PORT 62078 - -typedef enum AfcFopenMode { - AfcRdOnly = 1, - AfcRw = 2, - AfcWrOnly = 3, - AfcWr = 4, - AfcAppend = 5, - AfcRdAppend = 6, -} AfcFopenMode; - -/** - * Link type for creating hard or symbolic links - */ -typedef enum AfcLinkType { - Hard = 1, - Symbolic = 2, -} AfcLinkType; - -typedef enum IdeviceErrorCode { - IdeviceSuccess = 0, - Socket = -1, - Tls = -2, - TlsBuilderFailed = -3, - Plist = -4, - Utf8 = -5, - UnexpectedResponse = -6, - GetProhibited = -7, - SessionInactive = -8, - InvalidHostID = -9, - NoEstablishedConnection = -10, - HeartbeatSleepyTime = -11, - HeartbeatTimeout = -12, - NotFound = -13, - CdtunnelPacketTooShort = -14, - CdtunnelPacketInvalidMagic = -15, - PacketSizeMismatch = -16, - Json = -17, - DeviceNotFound = -18, - DeviceLocked = -19, - UsbConnectionRefused = -20, - UsbBadCommand = -21, - UsbBadDevice = -22, - UsbBadVersion = -23, - BadBuildManifest = -24, - ImageNotMounted = -25, - Reqwest = -26, - InternalError = -27, - Xpc = -28, - NsKeyedArchiveError = -29, - UnknownAuxValueType = -30, - UnknownChannel = -31, - AddrParseError = -32, - DisableMemoryLimitFailed = -33, - NotEnoughBytes = -34, - Utf8Error = -35, - InvalidArgument = -36, - UnknownErrorType = -37, - AdapterIOFailed = -996, - ServiceNotFound = -997, - BufferTooSmall = -998, - InvalidString = -999, - InvalidArg = -1000, -} IdeviceErrorCode; - -typedef enum IdeviceLogLevel { - Disabled = 0, - ErrorLevel = 1, - Warn = 2, - Info = 3, - Debug = 4, - Trace = 5, -} IdeviceLogLevel; - -typedef enum IdeviceLoggerError { - Success = 0, - FileError = -1, - AlreadyInitialized = -2, - InvalidPathString = -3, -} IdeviceLoggerError; - -typedef struct AdapterHandle AdapterHandle; - -typedef struct AfcClientHandle AfcClientHandle; - -/** - * Handle for an open file on the device - */ -typedef struct AfcFileHandle AfcFileHandle; - -typedef struct AmfiClientHandle AmfiClientHandle; - -typedef struct CoreDeviceProxyHandle CoreDeviceProxyHandle; - -/** - * Opaque handle to a DebugProxyClient - */ -typedef struct DebugProxyAdapterHandle DebugProxyAdapterHandle; - -typedef struct HeartbeatClientHandle HeartbeatClientHandle; - -/** - * Opaque C-compatible handle to an Idevice connection - */ -typedef struct IdeviceHandle IdeviceHandle; - -/** - * Opaque C-compatible handle to a PairingFile - */ -typedef struct IdevicePairingFile IdevicePairingFile; - -typedef struct IdeviceSocketHandle IdeviceSocketHandle; - -typedef struct ImageMounterHandle ImageMounterHandle; - -typedef struct InstallationProxyClientHandle InstallationProxyClientHandle; - -/** - * Opaque handle to a ProcessControlClient - */ -typedef struct LocationSimulationAdapterHandle LocationSimulationAdapterHandle; - -typedef struct LockdowndClientHandle LockdowndClientHandle; - -/** - * Opaque handle to a ProcessControlClient - */ -typedef struct ProcessControlAdapterHandle ProcessControlAdapterHandle; - -/** - * Opaque handle to a RemoteServerClient - */ -typedef struct RemoteServerAdapterHandle RemoteServerAdapterHandle; - -typedef struct SpringBoardServicesClientHandle SpringBoardServicesClientHandle; - -typedef struct TcpProviderHandle TcpProviderHandle; - -typedef struct UsbmuxdAddrHandle UsbmuxdAddrHandle; - -typedef struct UsbmuxdConnectionHandle UsbmuxdConnectionHandle; - -typedef struct UsbmuxdProviderHandle UsbmuxdProviderHandle; - -/** - * Opaque handle to an XPCDevice - */ -typedef struct XPCDeviceAdapterHandle XPCDeviceAdapterHandle; - -typedef struct sockaddr sockaddr; - -/** - * File information structure for C bindings - */ -typedef struct AfcFileInfo { - size_t size; - size_t blocks; - int64_t creation; - int64_t modified; - char *st_nlink; - char *st_ifmt; - char *st_link_target; -} AfcFileInfo; - -/** - * Device information structure for C bindings - */ -typedef struct AfcDeviceInfo { - char *model; - size_t total_bytes; - size_t free_bytes; - size_t block_size; -} AfcDeviceInfo; - -/** - * Represents a debugserver command - */ -typedef struct DebugserverCommandHandle { - char *name; - char **argv; - uintptr_t argv_count; -} DebugserverCommandHandle; - -/** - * Opaque handle to an XPCService - */ -typedef struct XPCServiceHandle { - char *entitlement; - uint16_t port; - bool uses_remote_xpc; - char **features; - uintptr_t features_count; - int64_t service_version; -} XPCServiceHandle; - -/** - * Creates a new Idevice connection - * - * # Arguments - * * [`socket`] - Socket for communication with the device - * * [`label`] - Label for the connection - * * [`idevice`] - On success, will be set to point to a newly allocated Idevice handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `label` must be a valid null-terminated C string - * `idevice` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode idevice_new(struct IdeviceSocketHandle *socket, - const char *label, - struct IdeviceHandle **idevice); - -/** - * Creates a new Idevice connection - * - * # Arguments - * * [`addr`] - The socket address to connect to - * * [`addr_len`] - Length of the socket - * * [`label`] - Label for the connection - * * [`idevice`] - On success, will be set to point to a newly allocated Idevice handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `addr` must be a valid sockaddr - * `label` must be a valid null-terminated C string - * `idevice` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode idevice_new_tcp_socket(const struct sockaddr *addr, - socklen_t addr_len, - const char *label, - struct IdeviceHandle **idevice); - -/** - * Gets the device type - * - * # Arguments - * * [`idevice`] - The Idevice handle - * * [`device_type`] - On success, will be set to point to a newly allocated string containing the device type - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `idevice` must be a valid, non-null pointer to an Idevice handle - * `device_type` must be a valid, non-null pointer to a location where the string pointer will be stored - */ -enum IdeviceErrorCode idevice_get_type(struct IdeviceHandle *idevice, - char **device_type); - -/** - * Performs RSD checkin - * - * # Arguments - * * [`idevice`] - The Idevice handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `idevice` must be a valid, non-null pointer to an Idevice handle - */ -enum IdeviceErrorCode idevice_rsd_checkin(struct IdeviceHandle *idevice); - -/** - * Starts a TLS session - * - * # Arguments - * * [`idevice`] - The Idevice handle - * * [`pairing_file`] - The pairing file to use for TLS - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `idevice` must be a valid, non-null pointer to an Idevice handle - * `pairing_file` must be a valid, non-null pointer to a pairing file handle - */ -enum IdeviceErrorCode idevice_start_session(struct IdeviceHandle *idevice, - const struct IdevicePairingFile *pairing_file); - -/** - * Frees an Idevice handle - * - * # Arguments - * * [`idevice`] - The Idevice handle to free - * - * # Safety - * `idevice` must be a valid pointer to an Idevice handle that was allocated by this library, - * or NULL (in which case this function does nothing) - */ -void idevice_free(struct IdeviceHandle *idevice); - -/** - * Frees a string allocated by this library - * - * # Arguments - * * [`string`] - The string to free - * - * # Safety - * `string` must be a valid pointer to a string that was allocated by this library, - * or NULL (in which case this function does nothing) - */ -void idevice_string_free(char *string); - -/** - * Connects the adapter to a specific port - * - * # Arguments - * * [`handle`] - The adapter handle - * * [`port`] - The port to connect to - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library - */ -enum IdeviceErrorCode adapter_connect(struct AdapterHandle *handle, uint16_t port); - -/** - * Enables PCAP logging for the adapter - * - * # Arguments - * * [`handle`] - The adapter handle - * * [`path`] - The path to save the PCAP file (null-terminated string) - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library - * `path` must be a valid null-terminated string - */ -enum IdeviceErrorCode adapter_pcap(struct AdapterHandle *handle, const char *path); - -/** - * Closes the adapter connection - * - * # Arguments - * * [`handle`] - The adapter handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library - */ -enum IdeviceErrorCode adapter_close(struct AdapterHandle *handle); - -/** - * Sends data through the adapter - * - * # Arguments - * * [`handle`] - The adapter handle - * * [`data`] - The data to send - * * [`length`] - The length of the data - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library - * `data` must be a valid pointer to at least `length` bytes - */ -enum IdeviceErrorCode adapter_send(struct AdapterHandle *handle, - const uint8_t *data, - uintptr_t length); - -/** - * Receives data from the adapter - * - * # Arguments - * * [`handle`] - The adapter handle - * * [`data`] - Pointer to a buffer where the received data will be stored - * * [`length`] - Pointer to store the actual length of received data - * * [`max_length`] - Maximum number of bytes that can be stored in `data` - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library - * `data` must be a valid pointer to at least `max_length` bytes - * `length` must be a valid pointer to a usize - */ -enum IdeviceErrorCode adapter_recv(struct AdapterHandle *handle, - uint8_t *data, - uintptr_t *length, - uintptr_t max_length); - -/** - * Connects to the AFC service using a TCP provider - * - * # Arguments - * * [`provider`] - A TcpProvider - * * [`client`] - On success, will be set to point to a newly allocated AfcClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `provider` must be a valid pointer to a handle allocated by this library - * `client` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode afc_client_connect_tcp(struct TcpProviderHandle *provider, - struct AfcClientHandle **client); - -/** - * Connects to the AFC service using a Usbmuxd provider - * - * # Arguments - * * [`provider`] - A UsbmuxdProvider - * * [`client`] - On success, will be set to point to a newly allocated AfcClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `provider` must be a valid pointer to a handle allocated by this library - * `client` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode afc_client_connect_usbmuxd(struct UsbmuxdProviderHandle *provider, - struct AfcClientHandle **client); - -/** - * Creates a new AfcClient from an existing Idevice connection - * - * # Arguments - * * [`socket`] - An IdeviceSocket handle - * * [`client`] - On success, will be set to point to a newly allocated AfcClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `socket` must be a valid pointer to a handle allocated by this library - * `client` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode afc_client_new(struct IdeviceHandle *socket, struct AfcClientHandle **client); - -/** - * Frees an AfcClient handle - * - * # Arguments - * * [`handle`] - The handle to free - * - * # Safety - * `handle` must be a valid pointer to the handle that was allocated by this library, - * or NULL (in which case this function does nothing) - */ -void afc_client_free(struct AfcClientHandle *handle); - -/** - * Lists the contents of a directory on the device - * - * # Arguments - * * [`client`] - A valid AfcClient handle - * * [`path`] - Path to the directory to list (UTF-8 null-terminated) - * * [`entries`] - Will be set to point to an array of directory entries - * * [`count`] - Will be set to the number of entries - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * All pointers must be valid and non-null - * `path` must be a valid null-terminated C string - */ -enum IdeviceErrorCode afc_list_directory(struct AfcClientHandle *client, - const char *path, - char ***entries, - size_t *count); - -/** - * Creates a new directory on the device - * - * # Arguments - * * [`client`] - A valid AfcClient handle - * * [`path`] - Path of the directory to create (UTF-8 null-terminated) - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - * `path` must be a valid null-terminated C string - */ -enum IdeviceErrorCode afc_make_directory(struct AfcClientHandle *client, const char *path); - -/** - * Retrieves information about a file or directory - * - * # Arguments - * * [`client`] - A valid AfcClient handle - * * [`path`] - Path to the file or directory (UTF-8 null-terminated) - * * [`info`] - Will be populated with file information - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` and `path` must be valid pointers - * `info` must be a valid pointer to an AfcFileInfo struct - */ -enum IdeviceErrorCode afc_get_file_info(struct AfcClientHandle *client, - const char *path, - struct AfcFileInfo *info); - -/** - * Frees memory allocated by afc_get_file_info - * - * # Arguments - * * [`info`] - Pointer to AfcFileInfo struct to free - * - * # Safety - * `info` must be a valid pointer to an AfcFileInfo struct previously returned by afc_get_file_info - */ -void afc_file_info_free(struct AfcFileInfo *info); - -/** - * Retrieves information about the device's filesystem - * - * # Arguments - * * [`client`] - A valid AfcClient handle - * * [`info`] - Will be populated with device information - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` and `info` must be valid pointers - */ -enum IdeviceErrorCode afc_get_device_info(struct AfcClientHandle *client, - struct AfcDeviceInfo *info); - -/** - * Frees memory allocated by afc_get_device_info - * - * # Arguments - * * [`info`] - Pointer to AfcDeviceInfo struct to free - * - * # Safety - * `info` must be a valid pointer to an AfcDeviceInfo struct previously returned by afc_get_device_info - */ -void afc_device_info_free(struct AfcDeviceInfo *info); - -/** - * Removes a file or directory - * - * # Arguments - * * [`client`] - A valid AfcClient handle - * * [`path`] - Path to the file or directory to remove (UTF-8 null-terminated) - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - * `path` must be a valid null-terminated C string - */ -enum IdeviceErrorCode afc_remove_path(struct AfcClientHandle *client, const char *path); - -/** - * Recursively removes a directory and all its contents - * - * # Arguments - * * [`client`] - A valid AfcClient handle - * * [`path`] - Path to the directory to remove (UTF-8 null-terminated) - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - * `path` must be a valid null-terminated C string - */ -enum IdeviceErrorCode afc_remove_path_and_contents(struct AfcClientHandle *client, - const char *path); - -/** - * Opens a file on the device - * - * # Arguments - * * [`client`] - A valid AfcClient handle - * * [`path`] - Path to the file to open (UTF-8 null-terminated) - * * [`mode`] - File open mode - * * [`handle`] - Will be set to a new file handle on success - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * All pointers must be valid and non-null - * `path` must be a valid null-terminated C string - */ -enum IdeviceErrorCode afc_file_open(struct AfcClientHandle *client, - const char *path, - enum AfcFopenMode mode, - struct AfcFileHandle **handle); - -/** - * Closes a file handle - * - * # Arguments - * * [`handle`] - File handle to close - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library - */ -enum IdeviceErrorCode afc_file_close(struct AfcFileHandle *handle); - -/** - * Reads data from an open file - * - * # Arguments - * * [`handle`] - File handle to read from - * * [`data`] - Will be set to point to the read data - * * [`length`] - Will be set to the length of the read data - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * All pointers must be valid and non-null - */ -enum IdeviceErrorCode afc_file_read(struct AfcFileHandle *handle, uint8_t **data, size_t *length); - -/** - * Writes data to an open file - * - * # Arguments - * * [`handle`] - File handle to write to - * * [`data`] - Data to write - * * [`length`] - Length of data to write - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * All pointers must be valid and non-null - * `data` must point to at least `length` bytes - */ -enum IdeviceErrorCode afc_file_write(struct AfcFileHandle *handle, - const uint8_t *data, - size_t length); - -/** - * Creates a hard or symbolic link - * - * # Arguments - * * [`client`] - A valid AfcClient handle - * * [`target`] - Target path of the link (UTF-8 null-terminated) - * * [`source`] - Path where the link should be created (UTF-8 null-terminated) - * * [`link_type`] - Type of link to create - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * All pointers must be valid and non-null - * `target` and `source` must be valid null-terminated C strings - */ -enum IdeviceErrorCode afc_make_link(struct AfcClientHandle *client, - const char *target, - const char *source, - enum AfcLinkType link_type); - -/** - * Renames a file or directory - * - * # Arguments - * * [`client`] - A valid AfcClient handle - * * [`source`] - Current path of the file/directory (UTF-8 null-terminated) - * * [`target`] - New path for the file/directory (UTF-8 null-terminated) - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * All pointers must be valid and non-null - * `source` and `target` must be valid null-terminated C strings - */ -enum IdeviceErrorCode afc_rename_path(struct AfcClientHandle *client, - const char *source, - const char *target); - -/** - * Automatically creates and connects to AMFI service, returning a client handle - * - * # Arguments - * * [`provider`] - A TcpProvider - * * [`client`] - On success, will be set to point to a newly allocated AmfiClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `provider` must be a valid pointer to a handle allocated by this library - * `client` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode amfi_connect_tcp(struct TcpProviderHandle *provider, - struct AmfiClientHandle **client); - -/** - * Automatically creates and connects to AMFI service, returning a client handle - * - * # Arguments - * * [`provider`] - A UsbmuxdProvider - * * [`client`] - On success, will be set to point to a newly allocated AmfiClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `provider` must be a valid pointer to a handle allocated by this library - * `client` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode amfi_connect_usbmuxd(struct UsbmuxdProviderHandle *provider, - struct AmfiClientHandle **client); - -/** - * Automatically creates and connects to AMFI service, returning a client handle - * - * # Arguments - * * [`socket`] - An IdeviceSocket handle - * * [`client`] - On success, will be set to point to a newly allocated AmfiClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `socket` must be a valid pointer to a handle allocated by this library - * `client` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode amfi_new(struct IdeviceHandle *socket, struct AmfiClientHandle **client); - -/** - * Shows the option in the settings UI - * - * # Arguments - * * `client` - A valid AmfiClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - */ -enum IdeviceErrorCode amfi_reveal_developer_mode_option_in_ui(struct AmfiClientHandle *client); - -/** - * Enables developer mode on the device - * - * # Arguments - * * `client` - A valid AmfiClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - */ -enum IdeviceErrorCode amfi_enable_developer_mode(struct AmfiClientHandle *client); - -/** - * Accepts developer mode on the device - * - * # Arguments - * * `client` - A valid AmfiClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - */ -enum IdeviceErrorCode amfi_accept_developer_mode(struct AmfiClientHandle *client); - -/** - * Frees a handle - * - * # Arguments - * * [`handle`] - The handle to free - * - * # Safety - * `handle` must be a valid pointer to the handle that was allocated by this library, - * or NULL (in which case this function does nothing) - */ -void amfi_client_free(struct AmfiClientHandle *handle); - -/** - * Automatically creates and connects to Core Device Proxy, returning a client handle - * - * # Arguments - * * [`provider`] - A TcpProvider - * * [`client`] - On success, will be set to point to a newly allocated CoreDeviceProxy handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `provider` must be a valid pointer to a handle allocated by this library - * `client` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode core_device_proxy_connect_tcp(struct TcpProviderHandle *provider, - struct CoreDeviceProxyHandle **client); - -/** - * Automatically creates and connects to Core Device Proxy, returning a client handle - * - * # Arguments - * * [`provider`] - A UsbmuxdProvider - * * [`client`] - On success, will be set to point to a newly allocated CoreDeviceProxy handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `provider` must be a valid pointer to a handle allocated by this library - * `client` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode core_device_proxy_connect_usbmuxd(struct UsbmuxdProviderHandle *provider, - struct CoreDeviceProxyHandle **client); - -/** - * Automatically creates and connects to Core Device Proxy, returning a client handle - * - * # Arguments - * * [`socket`] - An IdeviceSocket handle - * * [`client`] - On success, will be set to point to a newly allocated CoreDeviceProxy handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `socket` must be a valid pointer to a handle allocated by this library - * `client` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode core_device_proxy_new(struct IdeviceHandle *socket, - struct CoreDeviceProxyHandle **client); - -/** - * Sends data through the CoreDeviceProxy tunnel - * - * # Arguments - * * [`handle`] - The CoreDeviceProxy handle - * * [`data`] - The data to send - * * [`length`] - The length of the data - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library - * `data` must be a valid pointer to at least `length` bytes - */ -enum IdeviceErrorCode core_device_proxy_send(struct CoreDeviceProxyHandle *handle, - const uint8_t *data, - uintptr_t length); - -/** - * Receives data from the CoreDeviceProxy tunnel - * - * # Arguments - * * [`handle`] - The CoreDeviceProxy handle - * * [`data`] - Pointer to a buffer where the received data will be stored - * * [`length`] - Pointer to store the actual length of received data - * * [`max_length`] - Maximum number of bytes that can be stored in `data` - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library - * `data` must be a valid pointer to at least `max_length` bytes - * `length` must be a valid pointer to a usize - */ -enum IdeviceErrorCode core_device_proxy_recv(struct CoreDeviceProxyHandle *handle, - uint8_t *data, - uintptr_t *length, - uintptr_t max_length); - -/** - * Gets the client parameters from the handshake - * - * # Arguments - * * [`handle`] - The CoreDeviceProxy handle - * * [`mtu`] - Pointer to store the MTU value - * * [`address`] - Pointer to store the IP address string (must be at least 16 bytes) - * * [`netmask`] - Pointer to store the netmask string (must be at least 16 bytes) - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library - * `mtu` must be a valid pointer to a u16 - * `address` and `netmask` must be valid pointers to buffers of at least 16 bytes - */ -enum IdeviceErrorCode core_device_proxy_get_client_parameters(struct CoreDeviceProxyHandle *handle, - uint16_t *mtu, - char **address, - char **netmask); - -/** - * Gets the server address from the handshake - * - * # Arguments - * * [`handle`] - The CoreDeviceProxy handle - * * [`address`] - Pointer to store the server address string (must be at least 16 bytes) - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library - * `address` must be a valid pointer to a buffer of at least 16 bytes - */ -enum IdeviceErrorCode core_device_proxy_get_server_address(struct CoreDeviceProxyHandle *handle, - char **address); - -/** - * Gets the server RSD port from the handshake - * - * # Arguments - * * [`handle`] - The CoreDeviceProxy handle - * * [`port`] - Pointer to store the port number - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library - * `port` must be a valid pointer to a u16 - */ -enum IdeviceErrorCode core_device_proxy_get_server_rsd_port(struct CoreDeviceProxyHandle *handle, - uint16_t *port); - -/** - * Creates a software TCP tunnel adapter - * - * # Arguments - * * [`handle`] - The CoreDeviceProxy handle - * * [`adapter`] - Pointer to store the newly created adapter handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library, and never used again - * `adapter` must be a valid pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode core_device_proxy_create_tcp_adapter(struct CoreDeviceProxyHandle *handle, - struct AdapterHandle **adapter); - -/** - * Frees a handle - * - * # Arguments - * * [`handle`] - The handle to free - * - * # Safety - * `handle` must be a valid pointer to the handle that was allocated by this library, - * or NULL (in which case this function does nothing) - */ -void core_device_proxy_free(struct CoreDeviceProxyHandle *handle); - -/** - * Frees a handle - * - * # Arguments - * * [`handle`] - The handle to free - * - * # Safety - * `handle` must be a valid pointer to the handle that was allocated by this library, - * or NULL (in which case this function does nothing) - */ -void adapter_free(struct AdapterHandle *handle); - -/** - * Creates a new DebugserverCommand - * - * # Safety - * Caller must free with debugserver_command_free - */ -struct DebugserverCommandHandle *debugserver_command_new(const char *name, - const char *const *argv, - uintptr_t argv_count); - -/** - * Frees a DebugserverCommand - * - * # Safety - * `command` must be a valid pointer or NULL - */ -void debugserver_command_free(struct DebugserverCommandHandle *command); - -/** - * Creates a new DebugProxyClient - * - * # Arguments - * * [`socket`] - The socket to use for communication - * * [`handle`] - Pointer to store the newly created DebugProxyClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `socket` must be a valid pointer to a handle allocated by this library - * `handle` must be a valid pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode debug_proxy_adapter_new(struct AdapterHandle *socket, - struct DebugProxyAdapterHandle **handle); - -/** - * Frees a DebugProxyClient handle - * - * # Arguments - * * [`handle`] - The handle to free - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library or NULL - */ -void debug_proxy_free(struct DebugProxyAdapterHandle *handle); - -/** - * Sends a command to the debug proxy - * - * # Arguments - * * [`handle`] - The DebugProxyClient handle - * * [`command`] - The command to send - * * [`response`] - Pointer to store the response (caller must free) - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` and `command` must be valid pointers - * `response` must be a valid pointer to a location where the string will be stored - */ -enum IdeviceErrorCode debug_proxy_send_command(struct DebugProxyAdapterHandle *handle, - struct DebugserverCommandHandle *command, - char **response); - -/** - * Reads a response from the debug proxy - * - * # Arguments - * * [`handle`] - The DebugProxyClient handle - * * [`response`] - Pointer to store the response (caller must free) - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` must be a valid pointer - * `response` must be a valid pointer to a location where the string will be stored - */ -enum IdeviceErrorCode debug_proxy_read_response(struct DebugProxyAdapterHandle *handle, - char **response); - -/** - * Sends raw data to the debug proxy - * - * # Arguments - * * [`handle`] - The DebugProxyClient handle - * * [`data`] - The data to send - * * [`len`] - Length of the data - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` must be a valid pointer - * `data` must be a valid pointer to `len` bytes - */ -enum IdeviceErrorCode debug_proxy_send_raw(struct DebugProxyAdapterHandle *handle, - const uint8_t *data, - uintptr_t len); - -/** - * Reads data from the debug proxy - * - * # Arguments - * * [`handle`] - The DebugProxyClient handle - * * [`len`] - Maximum number of bytes to read - * * [`response`] - Pointer to store the response (caller must free) - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` must be a valid pointer - * `response` must be a valid pointer to a location where the string will be stored - */ -enum IdeviceErrorCode debug_proxy_read(struct DebugProxyAdapterHandle *handle, - uintptr_t len, - char **response); - -/** - * Sets the argv for the debug proxy - * - * # Arguments - * * [`handle`] - The DebugProxyClient handle - * * [`argv`] - NULL-terminated array of arguments - * * [`argv_count`] - Number of arguments - * * [`response`] - Pointer to store the response (caller must free) - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` must be a valid pointer - * `argv` must be a valid pointer to `argv_count` C strings or NULL - * `response` must be a valid pointer to a location where the string will be stored - */ -enum IdeviceErrorCode debug_proxy_set_argv(struct DebugProxyAdapterHandle *handle, - const char *const *argv, - uintptr_t argv_count, - char **response); - -/** - * Sends an ACK to the debug proxy - * - * # Arguments - * * [`handle`] - The DebugProxyClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` must be a valid pointer - */ -enum IdeviceErrorCode debug_proxy_send_ack(struct DebugProxyAdapterHandle *handle); - -/** - * Sends a NACK to the debug proxy - * - * # Arguments - * * [`handle`] - The DebugProxyClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` must be a valid pointer - */ -enum IdeviceErrorCode debug_proxy_send_nack(struct DebugProxyAdapterHandle *handle); - -/** - * Sets the ACK mode for the debug proxy - * - * # Arguments - * * [`handle`] - The DebugProxyClient handle - * * [`enabled`] - Whether ACK mode should be enabled - * - * # Safety - * `handle` must be a valid pointer - */ -void debug_proxy_set_ack_mode(struct DebugProxyAdapterHandle *handle, int enabled); - -/** - * Returns the underlying socket from a DebugProxyClient - * - * # Arguments - * * [`handle`] - The handle to get the socket from - * * [`adapter`] - The newly allocated ConnectionHandle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library or NULL, and never used again - */ -enum IdeviceErrorCode debug_proxy_adapter_into_inner(struct DebugProxyAdapterHandle *handle, - struct AdapterHandle **adapter); - -/** - * Automatically creates and connects to Installation Proxy, returning a client handle - * - * # Arguments - * * [`provider`] - A TcpProvider - * * [`client`] - On success, will be set to point to a newly allocated InstallationProxyClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `provider` must be a valid pointer to a handle allocated by this library - * `client` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode heartbeat_connect_tcp(struct TcpProviderHandle *provider, - struct HeartbeatClientHandle **client); - -/** - * Automatically creates and connects to Installation Proxy, returning a client handle - * - * # Arguments - * * [`provider`] - A UsbmuxdProvider - * * [`client`] - On success, will be set to point to a newly allocated InstallationProxyClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `provider` must be a valid pointer to a handle allocated by this library - * `client` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode heartbeat_connect_usbmuxd(struct UsbmuxdProviderHandle *provider, - struct HeartbeatClientHandle **client); - -/** - * Automatically creates and connects to Installation Proxy, returning a client handle - * - * # Arguments - * * [`socket`] - An IdeviceSocket handle - * * [`client`] - On success, will be set to point to a newly allocated InstallationProxyClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `socket` must be a valid pointer to a handle allocated by this library - * `client` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode heartbeat_new(struct IdeviceHandle *socket, - struct HeartbeatClientHandle **client); - -/** - * Sends a polo to the device - * - * # Arguments - * * `client` - A valid HeartbeatClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - */ -enum IdeviceErrorCode heartbeat_send_polo(struct HeartbeatClientHandle *client); - -/** - * Sends a polo to the device - * - * # Arguments - * * `client` - A valid HeartbeatClient handle - * * `interval` - The time to wait for a marco - * * `new_interval` - A pointer to set the requested marco - * - * # Returns - * An error code indicating success or failure. - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - */ -enum IdeviceErrorCode heartbeat_get_marco(struct HeartbeatClientHandle *client, - uint64_t interval, - uint64_t *new_interval); - -/** - * Frees a handle - * - * # Arguments - * * [`handle`] - The handle to free - * - * # Safety - * `handle` must be a valid pointer to the handle that was allocated by this library, - * or NULL (in which case this function does nothing) - */ -void heartbeat_client_free(struct HeartbeatClientHandle *handle); - -/** - * Automatically creates and connects to Installation Proxy, returning a client handle - * - * # Arguments - * * [`provider`] - A TcpProvider - * * [`client`] - On success, will be set to point to a newly allocated InstallationProxyClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `provider` must be a valid pointer to a handle allocated by this library - * `client` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode installation_proxy_connect_tcp(struct TcpProviderHandle *provider, - struct InstallationProxyClientHandle **client); - -/** - * Automatically creates and connects to Installation Proxy, returning a client handle - * - * # Arguments - * * [`provider`] - A UsbmuxdProvider - * * [`client`] - On success, will be set to point to a newly allocated InstallationProxyClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `provider` must be a valid pointer to a handle allocated by this library - * `client` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode installation_proxy_connect_usbmuxd(struct UsbmuxdProviderHandle *provider, - struct InstallationProxyClientHandle **client); - -/** - * Automatically creates and connects to Installation Proxy, returning a client handle - * - * # Arguments - * * [`socket`] - An IdeviceSocket handle - * * [`client`] - On success, will be set to point to a newly allocated InstallationProxyClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `socket` must be a valid pointer to a handle allocated by this library - * `client` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode installation_proxy_new(struct IdeviceHandle *socket, - struct InstallationProxyClientHandle **client); - -/** - * Gets installed apps on the device - * - * # Arguments - * * [`client`] - A valid InstallationProxyClient handle - * * [`application_type`] - The application type to filter by (optional, NULL for "Any") - * * [`bundle_identifiers`] - The identifiers to filter by (optional, NULL for all apps) - * * [`out_result`] - On success, will be set to point to a newly allocated array of PlistRef - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - * `out_result` must be a valid, non-null pointer to a location where the result will be stored - */ -enum IdeviceErrorCode installation_proxy_get_apps(struct InstallationProxyClientHandle *client, - const char *application_type, - const char *const *bundle_identifiers, - size_t bundle_identifiers_len, - void **out_result, - size_t *out_result_len); - -/** - * Frees a handle - * - * # Arguments - * * [`handle`] - The handle to free - * - * # Safety - * `handle` must be a valid pointer to the handle that was allocated by this library, - * or NULL (in which case this function does nothing) - */ -void installation_proxy_client_free(struct InstallationProxyClientHandle *handle); - -/** - * Installs an application package on the device - * - * # Arguments - * * [`client`] - A valid InstallationProxyClient handle - * * [`package_path`] - Path to the .ipa package in the AFC jail - * * [`options`] - Optional installation options as a plist dictionary (can be NULL) - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - * `package_path` must be a valid C string - * `options` must be a valid plist dictionary or NULL - */ -enum IdeviceErrorCode installation_proxy_install(struct InstallationProxyClientHandle *client, - const char *package_path, - void *options); - -/** - * Installs an application package on the device - * - * # Arguments - * * [`client`] - A valid InstallationProxyClient handle - * * [`package_path`] - Path to the .ipa package in the AFC jail - * * [`options`] - Optional installation options as a plist dictionary (can be NULL) - * * [`callback`] - Progress callback function - * * [`context`] - User context to pass to callback - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - * `package_path` must be a valid C string - * `options` must be a valid plist dictionary or NULL - */ -enum IdeviceErrorCode installation_proxy_install_with_callback(struct InstallationProxyClientHandle *client, - const char *package_path, - void *options, - void (*callback)(uint64_t progress, - void *context), - void *context); - -/** - * Upgrades an existing application on the device - * - * # Arguments - * * [`client`] - A valid InstallationProxyClient handle - * * [`package_path`] - Path to the .ipa package in the AFC jail - * * [`options`] - Optional upgrade options as a plist dictionary (can be NULL) - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - * `package_path` must be a valid C string - * `options` must be a valid plist dictionary or NULL - */ -enum IdeviceErrorCode installation_proxy_upgrade(struct InstallationProxyClientHandle *client, - const char *package_path, - void *options); - -/** - * Upgrades an existing application on the device - * - * # Arguments - * * [`client`] - A valid InstallationProxyClient handle - * * [`package_path`] - Path to the .ipa package in the AFC jail - * * [`options`] - Optional upgrade options as a plist dictionary (can be NULL) - * * [`callback`] - Progress callback function - * * [`context`] - User context to pass to callback - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - * `package_path` must be a valid C string - * `options` must be a valid plist dictionary or NULL - */ -enum IdeviceErrorCode installation_proxy_upgrade_with_callback(struct InstallationProxyClientHandle *client, - const char *package_path, - void *options, - void (*callback)(uint64_t progress, - void *context), - void *context); - -/** - * Uninstalls an application from the device - * - * # Arguments - * * [`client`] - A valid InstallationProxyClient handle - * * [`bundle_id`] - Bundle identifier of the application to uninstall - * * [`options`] - Optional uninstall options as a plist dictionary (can be NULL) - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - * `bundle_id` must be a valid C string - * `options` must be a valid plist dictionary or NULL - */ -enum IdeviceErrorCode installation_proxy_uninstall(struct InstallationProxyClientHandle *client, - const char *bundle_id, - void *options); - -/** - * Uninstalls an application from the device - * - * # Arguments - * * [`client`] - A valid InstallationProxyClient handle - * * [`bundle_id`] - Bundle identifier of the application to uninstall - * * [`options`] - Optional uninstall options as a plist dictionary (can be NULL) - * * [`callback`] - Progress callback function - * * [`context`] - User context to pass to callback - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - * `bundle_id` must be a valid C string - * `options` must be a valid plist dictionary or NULL - */ -enum IdeviceErrorCode installation_proxy_uninstall_with_callback(struct InstallationProxyClientHandle *client, - const char *bundle_id, - void *options, - void (*callback)(uint64_t progress, - void *context), - void *context); - -/** - * Checks if the device capabilities match the required capabilities - * - * # Arguments - * * [`client`] - A valid InstallationProxyClient handle - * * [`capabilities`] - Array of plist values representing required capabilities - * * [`capabilities_len`] - Length of the capabilities array - * * [`options`] - Optional check options as a plist dictionary (can be NULL) - * * [`out_result`] - Will be set to true if all capabilities are supported, false otherwise - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - * `capabilities` must be a valid array of plist values or NULL - * `options` must be a valid plist dictionary or NULL - * `out_result` must be a valid pointer to a bool - */ -enum IdeviceErrorCode installation_proxy_check_capabilities_match(struct InstallationProxyClientHandle *client, - void *const *capabilities, - size_t capabilities_len, - void *options, - bool *out_result); - -/** - * Browses installed applications on the device - * - * # Arguments - * * [`client`] - A valid InstallationProxyClient handle - * * [`options`] - Optional browse options as a plist dictionary (can be NULL) - * * [`out_result`] - On success, will be set to point to a newly allocated array of PlistRef - * * [`out_result_len`] - Will be set to the length of the result array - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - * `options` must be a valid plist dictionary or NULL - * `out_result` must be a valid, non-null pointer to a location where the result will be stored - * `out_result_len` must be a valid, non-null pointer to a location where the length will be stored - */ -enum IdeviceErrorCode installation_proxy_browse(struct InstallationProxyClientHandle *client, - void *options, - void **out_result, - size_t *out_result_len); - -/** - * Creates a new ProcessControlClient from a RemoteServerClient - * - * # Arguments - * * [`server`] - The RemoteServerClient to use - * * [`handle`] - Pointer to store the newly created ProcessControlClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `server` must be a valid pointer to a handle allocated by this library - * `handle` must be a valid pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode location_simulation_new(struct RemoteServerAdapterHandle *server, - struct LocationSimulationAdapterHandle **handle); - -/** - * Frees a ProcessControlClient handle - * - * # Arguments - * * [`handle`] - The handle to free - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library or NULL - */ -void location_simulation_free(struct LocationSimulationAdapterHandle *handle); - -/** - * Clears the location set - * - * # Arguments - * * [`handle`] - The LocationSimulation handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * All pointers must be valid or NULL where appropriate - */ -enum IdeviceErrorCode location_simulation_clear(struct LocationSimulationAdapterHandle *handle); - -/** - * Sets the location - * - * # Arguments - * * [`handle`] - The LocationSimulation handle - * * [`latitude`] - The latitude to set - * * [`longitude`] - The longitude to set - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * All pointers must be valid or NULL where appropriate - */ -enum IdeviceErrorCode location_simulation_set(struct LocationSimulationAdapterHandle *handle, - double latitude, - double longitude); - -/** - * Connects to lockdownd service using TCP provider - * - * # Arguments - * * [`provider`] - A TcpProvider - * * [`client`] - On success, will be set to point to a newly allocated LockdowndClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `provider` must be a valid pointer to a handle allocated by this library - * `client` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode lockdownd_connect_tcp(struct TcpProviderHandle *provider, - struct LockdowndClientHandle **client); - -/** - * Connects to lockdownd service using Usbmuxd provider - * - * # Arguments - * * [`provider`] - A UsbmuxdProvider - * * [`client`] - On success, will be set to point to a newly allocated LockdowndClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `provider` must be a valid pointer to a handle allocated by this library - * `client` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode lockdownd_connect_usbmuxd(struct UsbmuxdProviderHandle *provider, - struct LockdowndClientHandle **client); - -/** - * Creates a new LockdowndClient from an existing Idevice connection - * - * # Arguments - * * [`socket`] - An IdeviceSocket handle - * * [`client`] - On success, will be set to point to a newly allocated LockdowndClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `socket` must be a valid pointer to a handle allocated by this library - * `client` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode lockdownd_new(struct IdeviceHandle *socket, - struct LockdowndClientHandle **client); - -/** - * Starts a session with lockdownd - * - * # Arguments - * * `client` - A valid LockdowndClient handle - * * `pairing_file` - An IdevicePairingFile alocated by this library - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - * `pairing_file` must be a valid plist_t containing a pairing file - */ -enum IdeviceErrorCode lockdownd_start_session(struct LockdowndClientHandle *client, - struct IdevicePairingFile *pairing_file); - -/** - * Starts a service through lockdownd - * - * # Arguments - * * `client` - A valid LockdowndClient handle - * * `identifier` - The service identifier to start (null-terminated string) - * * `port` - Pointer to store the returned port number - * * `ssl` - Pointer to store whether SSL should be enabled - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - * `identifier` must be a valid null-terminated string - * `port` and `ssl` must be valid pointers - */ -enum IdeviceErrorCode lockdownd_start_service(struct LockdowndClientHandle *client, - const char *identifier, - uint16_t *port, - bool *ssl); - -/** - * Gets a value from lockdownd - * - * # Arguments - * * `client` - A valid LockdowndClient handle - * * `key` - The value to get (null-terminated string) - * * `domain` - The value to get (null-terminated string) - * * `out_plist` - Pointer to store the returned plist value - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - * `value` must be a valid null-terminated string - * `out_plist` must be a valid pointer to store the plist - */ -enum IdeviceErrorCode lockdownd_get_value(struct LockdowndClientHandle *client, - const char *key, - const char *domain, - void **out_plist); - -/** - * Gets all values from lockdownd - * - * # Arguments - * * `client` - A valid LockdowndClient handle - * * `out_plist` - Pointer to store the returned plist dictionary - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - * `out_plist` must be a valid pointer to store the plist - */ -enum IdeviceErrorCode lockdownd_get_all_values(struct LockdowndClientHandle *client, - void **out_plist); - -/** - * Frees a LockdowndClient handle - * - * # Arguments - * * [`handle`] - The handle to free - * - * # Safety - * `handle` must be a valid pointer to the handle that was allocated by this library, - * or NULL (in which case this function does nothing) - */ -void lockdownd_client_free(struct LockdowndClientHandle *handle); - -/** - * Initializes the logger - * - * # Arguments - * * [`console_level`] - The level to log to the file - * * [`file_level`] - The level to log to the file - * * [`file_path`] - If not null, the file to write logs to - * - * ## Log Level - * 0. Disabled - * 1. Error - * 2. Warn - * 3. Info - * 4. Debug - * 5. Trace - * - * # Returns - * 0 for success, -1 if the file couldn't be created, -2 if a logger has been initialized, -3 for invalid path string - * - * # Safety - * Pass a valid CString for file_path. Pass valid log levels according to the enum - */ -enum IdeviceLoggerError idevice_init_logger(enum IdeviceLogLevel console_level, - enum IdeviceLogLevel file_level, - char *file_path); - -/** - * Connects to the Image Mounter service using a TCP provider - * - * # Arguments - * * [`provider`] - A TcpProvider - * * [`client`] - On success, will be set to point to a newly allocated ImageMounter handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `provider` must be a valid pointer to a handle allocated by this library - * `client` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode image_mounter_connect_tcp(struct TcpProviderHandle *provider, - struct ImageMounterHandle **client); - -/** - * Connects to the Image Mounter service using a Usbmuxd provider - * - * # Arguments - * * [`provider`] - A UsbmuxdProvider - * * [`client`] - On success, will be set to point to a newly allocated ImageMounter handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `provider` must be a valid pointer to a handle allocated by this library - * `client` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode image_mounter_connect_usbmuxd(struct UsbmuxdProviderHandle *provider, - struct ImageMounterHandle **client); - -/** - * Creates a new ImageMounter client from an existing Idevice connection - * - * # Arguments - * * [`socket`] - An IdeviceSocket handle - * * [`client`] - On success, will be set to point to a newly allocated ImageMounter handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `socket` must be a valid pointer to a handle allocated by this library - * `client` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode image_mounter_new(struct IdeviceHandle *socket, - struct ImageMounterHandle **client); - -/** - * Frees an ImageMounter handle - * - * # Arguments - * * [`handle`] - The handle to free - * - * # Safety - * `handle` must be a valid pointer to the handle that was allocated by this library, - * or NULL (in which case this function does nothing) - */ -void image_mounter_free(struct ImageMounterHandle *handle); - -/** - * Gets a list of mounted devices - * - * # Arguments - * * [`client`] - A valid ImageMounter handle - * * [`devices`] - Will be set to point to a slice of device plists on success - * * [`devices_len`] - Will be set to the number of devices copied - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - * `devices` must be a valid, non-null pointer to a location where the plist will be stored - */ -enum IdeviceErrorCode image_mounter_copy_devices(struct ImageMounterHandle *client, - void **devices, - size_t *devices_len); - -/** - * Looks up an image and returns its signature - * - * # Arguments - * * [`client`] - A valid ImageMounter handle - * * [`image_type`] - The type of image to look up - * * [`signature`] - Will be set to point to the signature data on success - * * [`signature_len`] - Will be set to the length of the signature data - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - * `image_type` must be a valid null-terminated C string - * `signature` and `signature_len` must be valid pointers - */ -enum IdeviceErrorCode image_mounter_lookup_image(struct ImageMounterHandle *client, - const char *image_type, - uint8_t **signature, - size_t *signature_len); - -/** - * Uploads an image to the device - * - * # Arguments - * * [`client`] - A valid ImageMounter handle - * * [`image_type`] - The type of image being uploaded - * * [`image`] - Pointer to the image data - * * [`image_len`] - Length of the image data - * * [`signature`] - Pointer to the signature data - * * [`signature_len`] - Length of the signature data - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * All pointers must be valid and non-null - * `image_type` must be a valid null-terminated C string - */ -enum IdeviceErrorCode image_mounter_upload_image(struct ImageMounterHandle *client, - const char *image_type, - const uint8_t *image, - size_t image_len, - const uint8_t *signature, - size_t signature_len); - -/** - * Mounts an image on the device - * - * # Arguments - * * [`client`] - A valid ImageMounter handle - * * [`image_type`] - The type of image being mounted - * * [`signature`] - Pointer to the signature data - * * [`signature_len`] - Length of the signature data - * * [`trust_cache`] - Pointer to trust cache data (optional) - * * [`trust_cache_len`] - Length of trust cache data (0 if none) - * * [`info_plist`] - Pointer to info plist (optional) - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * All pointers must be valid (except optional ones which can be null) - * `image_type` must be a valid null-terminated C string - */ -enum IdeviceErrorCode image_mounter_mount_image(struct ImageMounterHandle *client, - const char *image_type, - const uint8_t *signature, - size_t signature_len, - const uint8_t *trust_cache, - size_t trust_cache_len, - const void *info_plist); - -/** - * Unmounts an image from the device - * - * # Arguments - * * [`client`] - A valid ImageMounter handle - * * [`mount_path`] - The path where the image is mounted - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - * `mount_path` must be a valid null-terminated C string - */ -enum IdeviceErrorCode image_mounter_unmount_image(struct ImageMounterHandle *client, - const char *mount_path); - -/** - * Queries the developer mode status - * - * # Arguments - * * [`client`] - A valid ImageMounter handle - * * [`status`] - Will be set to the developer mode status (1 = enabled, 0 = disabled) - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - * `status` must be a valid pointer - */ -enum IdeviceErrorCode image_mounter_query_developer_mode_status(struct ImageMounterHandle *client, - int *status); - -/** - * Mounts a developer image - * - * # Arguments - * * [`client`] - A valid ImageMounter handle - * * [`image`] - Pointer to the image data - * * [`image_len`] - Length of the image data - * * [`signature`] - Pointer to the signature data - * * [`signature_len`] - Length of the signature data - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * All pointers must be valid and non-null - */ -enum IdeviceErrorCode image_mounter_mount_developer(struct ImageMounterHandle *client, - const uint8_t *image, - size_t image_len, - const uint8_t *signature, - size_t signature_len); - -/** - * Queries the personalization manifest from the device - * - * # Arguments - * * [`client`] - A valid ImageMounter handle - * * [`image_type`] - The type of image to query - * * [`signature`] - Pointer to the signature data - * * [`signature_len`] - Length of the signature data - * * [`manifest`] - Will be set to point to the manifest data on success - * * [`manifest_len`] - Will be set to the length of the manifest data - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * All pointers must be valid and non-null - * `image_type` must be a valid null-terminated C string - */ -enum IdeviceErrorCode image_mounter_query_personalization_manifest(struct ImageMounterHandle *client, - const char *image_type, - const uint8_t *signature, - size_t signature_len, - uint8_t **manifest, - size_t *manifest_len); - -/** - * Queries the nonce from the device - * - * # Arguments - * * [`client`] - A valid ImageMounter handle - * * [`personalized_image_type`] - The type of image to query (optional) - * * [`nonce`] - Will be set to point to the nonce data on success - * * [`nonce_len`] - Will be set to the length of the nonce data - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client`, `nonce`, and `nonce_len` must be valid pointers - * `personalized_image_type` can be NULL - */ -enum IdeviceErrorCode image_mounter_query_nonce(struct ImageMounterHandle *client, - const char *personalized_image_type, - uint8_t **nonce, - size_t *nonce_len); - -/** - * Queries personalization identifiers from the device - * - * # Arguments - * * [`client`] - A valid ImageMounter handle - * * [`image_type`] - The type of image to query (optional) - * * [`identifiers`] - Will be set to point to the identifiers plist on success - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` and `identifiers` must be valid pointers - * `image_type` can be NULL - */ -enum IdeviceErrorCode image_mounter_query_personalization_identifiers(struct ImageMounterHandle *client, - const char *image_type, - void **identifiers); - -/** - * Rolls the personalization nonce - * - * # Arguments - * * [`client`] - A valid ImageMounter handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - */ -enum IdeviceErrorCode image_mounter_roll_personalization_nonce(struct ImageMounterHandle *client); - -/** - * Rolls the cryptex nonce - * - * # Arguments - * * [`client`] - A valid ImageMounter handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - */ -enum IdeviceErrorCode image_mounter_roll_cryptex_nonce(struct ImageMounterHandle *client); - -/** - * Mounts a personalized developer image - * - * # Arguments - * * [`client`] - A valid ImageMounter handle - * * [`provider`] - A valid provider handle - * * [`image`] - Pointer to the image data - * * [`image_len`] - Length of the image data - * * [`trust_cache`] - Pointer to the trust cache data - * * [`trust_cache_len`] - Length of the trust cache data - * * [`build_manifest`] - Pointer to the build manifest data - * * [`build_manifest_len`] - Length of the build manifest data - * * [`info_plist`] - Pointer to info plist (optional) - * * [`unique_chip_id`] - The device's unique chip ID - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * All pointers must be valid (except optional ones which can be null) - */ -enum IdeviceErrorCode image_mounter_mount_personalized_usbmuxd(struct ImageMounterHandle *client, - struct UsbmuxdProviderHandle *provider, - const uint8_t *image, - size_t image_len, - const uint8_t *trust_cache, - size_t trust_cache_len, - const uint8_t *build_manifest, - size_t build_manifest_len, - const void *info_plist, - uint64_t unique_chip_id); - -/** - * Mounts a personalized developer image - * - * # Arguments - * * [`client`] - A valid ImageMounter handle - * * [`provider`] - A valid provider handle - * * [`image`] - Pointer to the image data - * * [`image_len`] - Length of the image data - * * [`trust_cache`] - Pointer to the trust cache data - * * [`trust_cache_len`] - Length of the trust cache data - * * [`build_manifest`] - Pointer to the build manifest data - * * [`build_manifest_len`] - Length of the build manifest data - * * [`info_plist`] - Pointer to info plist (optional) - * * [`unique_chip_id`] - The device's unique chip ID - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * All pointers must be valid (except optional ones which can be null) - */ -enum IdeviceErrorCode image_mounter_mount_personalized_tcp(struct ImageMounterHandle *client, - struct TcpProviderHandle *provider, - const uint8_t *image, - size_t image_len, - const uint8_t *trust_cache, - size_t trust_cache_len, - const uint8_t *build_manifest, - size_t build_manifest_len, - const void *info_plist, - uint64_t unique_chip_id); - -/** - * Mounts a personalized developer image with progress callback - * - * # Arguments - * * [`client`] - A valid ImageMounter handle - * * [`provider`] - A valid provider handle - * * [`image`] - Pointer to the image data - * * [`image_len`] - Length of the image data - * * [`trust_cache`] - Pointer to the trust cache data - * * [`trust_cache_len`] - Length of the trust cache data - * * [`build_manifest`] - Pointer to the build manifest data - * * [`build_manifest_len`] - Length of the build manifest data - * * [`info_plist`] - Pointer to info plist (optional) - * * [`unique_chip_id`] - The device's unique chip ID - * * [`callback`] - Progress callback function - * * [`context`] - User context to pass to callback - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * All pointers must be valid (except optional ones which can be null) - */ -enum IdeviceErrorCode image_mounter_mount_personalized_usbmuxd_with_callback(struct ImageMounterHandle *client, - struct UsbmuxdProviderHandle *provider, - const uint8_t *image, - size_t image_len, - const uint8_t *trust_cache, - size_t trust_cache_len, - const uint8_t *build_manifest, - size_t build_manifest_len, - const void *info_plist, - uint64_t unique_chip_id, - void (*callback)(size_t progress, - size_t total, - void *context), - void *context); - -/** - * Mounts a personalized developer image with progress callback - * - * # Arguments - * * [`client`] - A valid ImageMounter handle - * * [`provider`] - A valid provider handle - * * [`image`] - Pointer to the image data - * * [`image_len`] - Length of the image data - * * [`trust_cache`] - Pointer to the trust cache data - * * [`trust_cache_len`] - Length of the trust cache data - * * [`build_manifest`] - Pointer to the build manifest data - * * [`build_manifest_len`] - Length of the build manifest data - * * [`info_plist`] - Pointer to info plist (optional) - * * [`unique_chip_id`] - The device's unique chip ID - * * [`callback`] - Progress callback function - * * [`context`] - User context to pass to callback - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * All pointers must be valid (except optional ones which can be null) - */ -enum IdeviceErrorCode image_mounter_mount_personalized_tcp_with_callback(struct ImageMounterHandle *client, - struct TcpProviderHandle *provider, - const uint8_t *image, - size_t image_len, - const uint8_t *trust_cache, - size_t trust_cache_len, - const uint8_t *build_manifest, - size_t build_manifest_len, - const void *info_plist, - uint64_t unique_chip_id, - void (*callback)(size_t progress, - size_t total, - void *context), - void *context); - -/** - * Reads a pairing file from the specified path - * - * # Arguments - * * [`path`] - Path to the pairing file - * * [`pairing_file`] - On success, will be set to point to a newly allocated pairing file instance - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `path` must be a valid null-terminated C string - * `pairing_file` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode idevice_pairing_file_read(const char *path, - struct IdevicePairingFile **pairing_file); - -/** - * Parses a pairing file from a byte buffer - * - * # Arguments - * * [`data`] - Pointer to the buffer containing pairing file data - * * [`size`] - Size of the buffer in bytes - * * [`pairing_file`] - On success, will be set to point to a newly allocated pairing file instance - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `data` must be a valid pointer to a buffer of at least `size` bytes - * `pairing_file` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode idevice_pairing_file_from_bytes(const uint8_t *data, - uintptr_t size, - struct IdevicePairingFile **pairing_file); - -/** - * Serializes a pairing file to XML format - * - * # Arguments - * * [`pairing_file`] - The pairing file to serialize - * * [`data`] - On success, will be set to point to a newly allocated buffer containing the serialized data - * * [`size`] - On success, will be set to the size of the allocated buffer - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `pairing_file` must be a valid, non-null pointer to a pairing file instance - * `data` must be a valid, non-null pointer to a location where the buffer pointer will be stored - * `size` must be a valid, non-null pointer to a location where the buffer size will be stored - */ -enum IdeviceErrorCode idevice_pairing_file_serialize(const struct IdevicePairingFile *pairing_file, - uint8_t **data, - uintptr_t *size); - -/** - * Frees a pairing file instance - * - * # Arguments - * * [`pairing_file`] - The pairing file to free - * - * # Safety - * `pairing_file` must be a valid pointer to a pairing file instance that was allocated by this library, - * or NULL (in which case this function does nothing) - */ -void idevice_pairing_file_free(struct IdevicePairingFile *pairing_file); - -/** - * Creates a new ProcessControlClient from a RemoteServerClient - * - * # Arguments - * * [`server`] - The RemoteServerClient to use - * * [`handle`] - Pointer to store the newly created ProcessControlClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `server` must be a valid pointer to a handle allocated by this library - * `handle` must be a valid pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode process_control_new(struct RemoteServerAdapterHandle *server, - struct ProcessControlAdapterHandle **handle); - -/** - * Frees a ProcessControlClient handle - * - * # Arguments - * * [`handle`] - The handle to free - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library or NULL - */ -void process_control_free(struct ProcessControlAdapterHandle *handle); - -/** - * Launches an application on the device - * - * # Arguments - * * [`handle`] - The ProcessControlClient handle - * * [`bundle_id`] - The bundle identifier of the app to launch - * * [`env_vars`] - NULL-terminated array of environment variables (format "KEY=VALUE") - * * [`arguments`] - NULL-terminated array of arguments - * * [`start_suspended`] - Whether to start the app suspended - * * [`kill_existing`] - Whether to kill existing instances of the app - * * [`pid`] - Pointer to store the process ID of the launched app - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * All pointers must be valid or NULL where appropriate - */ -enum IdeviceErrorCode process_control_launch_app(struct ProcessControlAdapterHandle *handle, - const char *bundle_id, - const char *const *env_vars, - uintptr_t env_vars_count, - const char *const *arguments, - uintptr_t arguments_count, - bool start_suspended, - bool kill_existing, - uint64_t *pid); - -/** - * Kills a running process - * - * # Arguments - * * [`handle`] - The ProcessControlClient handle - * * [`pid`] - The process ID to kill - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library - */ -enum IdeviceErrorCode process_control_kill_app(struct ProcessControlAdapterHandle *handle, - uint64_t pid); - -/** - * Disables memory limits for a process - * - * # Arguments - * * [`handle`] - The ProcessControlClient handle - * * [`pid`] - The process ID to modify - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library - */ -enum IdeviceErrorCode process_control_disable_memory_limit(struct ProcessControlAdapterHandle *handle, - uint64_t pid); - -/** - * Creates a TCP provider for idevice - * - * # Arguments - * * [`ip`] - The sockaddr IP to connect to - * * [`pairing_file`] - The pairing file handle to use - * * [`label`] - The label to use with the connection - * * [`provider`] - A pointer to a newly allocated provider - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `ip` must be a valid sockaddr - * `pairing_file` must never be used again - * `label` must be a valid Cstr - * `provider` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode idevice_tcp_provider_new(const struct sockaddr *ip, - struct IdevicePairingFile *pairing_file, - const char *label, - struct TcpProviderHandle **provider); - -/** - * Frees a TcpProvider handle - * - * # Arguments - * * [`provider`] - The provider handle to free - * - * # Safety - * `provider` must be a valid pointer to a TcpProvider handle that was allocated by this library, - * or NULL (in which case this function does nothing) - */ -void tcp_provider_free(struct TcpProviderHandle *provider); - -/** - * Creates a usbmuxd provider for idevice - * - * # Arguments - * * [`addr`] - The UsbmuxdAddr handle to connect to - * * [`tag`] - The tag returned in usbmuxd responses - * * [`udid`] - The UDID of the device to connect to - * * [`device_id`] - The muxer ID of the device to connect to - * * [`pairing_file`] - The pairing file handle to use - * * [`label`] - The label to use with the connection - * * [`provider`] - A pointer to a newly allocated provider - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `addr` must be a valid pointer to UsbmuxdAddrHandle created by this library, and never used again - * `udid` must be a valid CStr - * `pairing_file` must never be used again - * `label` must be a valid Cstr - * `provider` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode usbmuxd_provider_new(struct UsbmuxdAddrHandle *addr, - uint32_t tag, - const char *udid, - uint32_t device_id, - const char *label, - struct UsbmuxdProviderHandle **provider); - -/** - * Frees a UsbmuxdProvider handle - * - * # Arguments - * * [`provider`] - The provider handle to free - * - * # Safety - * `provider` must be a valid pointer to a UsbmuxdProvider handle that was allocated by this library, - * or NULL (in which case this function does nothing) - */ -void usbmuxd_provider_free(struct UsbmuxdProviderHandle *provider); - -/** - * Creates a new RemoteServerClient from a ReadWrite connection - * - * # Arguments - * * [`connection`] - The connection to use for communication - * * [`handle`] - Pointer to store the newly created RemoteServerClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `connection` must be a valid pointer to a handle allocated by this library - * `handle` must be a valid pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode remote_server_adapter_new(struct AdapterHandle *adapter, - struct RemoteServerAdapterHandle **handle); - -/** - * Frees a RemoteServerClient handle - * - * # Arguments - * * [`handle`] - The handle to free - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library or NULL - */ -void remote_server_free(struct RemoteServerAdapterHandle *handle); - -/** - * Returns the underlying connection from a RemoteServerClient - * - * # Arguments - * * [`handle`] - The handle to get the connection from - * * [`connection`] - The newly allocated ConnectionHandle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library or NULL, and never used again - */ -enum IdeviceErrorCode remote_server_adapter_into_inner(struct RemoteServerAdapterHandle *handle, - struct AdapterHandle **connection); - -/** - * Creates a new XPCDevice from an adapter - * - * # Arguments - * * [`adapter`] - The adapter to use for communication - * * [`device`] - Pointer to store the newly created XPCDevice handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `adapter` must be a valid pointer to a handle allocated by this library - * `device` must be a valid pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode xpc_device_new(struct AdapterHandle *adapter, - struct XPCDeviceAdapterHandle **device); - -/** - * Frees an XPCDevice handle - * - * # Arguments - * * [`handle`] - The handle to free - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library or NULL - */ -void xpc_device_free(struct XPCDeviceAdapterHandle *handle); - -/** - * Gets a service by name from the XPCDevice - * - * # Arguments - * * [`handle`] - The XPCDevice handle - * * [`service_name`] - The name of the service to get - * * [`service`] - Pointer to store the newly created XPCService handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library - * `service_name` must be a valid null-terminated C string - * `service` must be a valid pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode xpc_device_get_service(struct XPCDeviceAdapterHandle *handle, - const char *service_name, - struct XPCServiceHandle **service); - -/** - * Returns the adapter in the RemoteXPC Device - * - * # Arguments - * * [`handle`] - The handle to get the adapter from - * * [`adapter`] - The newly allocated AdapterHandle - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library or NULL, and never used again - */ -enum IdeviceErrorCode xpc_device_adapter_into_inner(struct XPCDeviceAdapterHandle *handle, - struct AdapterHandle **adapter); - -/** - * Frees an XPCService handle - * - * # Arguments - * * [`handle`] - The handle to free - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library or NULL - */ -void xpc_service_free(struct XPCServiceHandle *handle); - -/** - * Gets the list of available service names - * - * # Arguments - * * [`handle`] - The XPCDevice handle - * * [`names`] - Pointer to store the array of service names - * * [`count`] - Pointer to store the number of services - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `handle` must be a valid pointer to a handle allocated by this library - * `names` must be a valid pointer to a location where the array will be stored - * `count` must be a valid pointer to a location where the count will be stored - */ -enum IdeviceErrorCode xpc_device_get_service_names(struct XPCDeviceAdapterHandle *handle, - char ***names, - uintptr_t *count); - -/** - * Frees a list of service names - * - * # Arguments - * * [`names`] - The array of service names to free - * * [`count`] - The number of services in the array - * - * # Safety - * `names` must be a valid pointer to an array of `count` C strings - */ -void xpc_device_free_service_names(char **names, uintptr_t count); - -/** - * Connects to the Springboard service using a TCP provider - * - * # Arguments - * * [`provider`] - A TcpProvider - * * [`client`] - On success, will be set to point to a newly allocated SpringBoardServicesClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `provider` must be a valid pointer to a handle allocated by this library - * `client` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode springboard_services_connect_tcp(struct TcpProviderHandle *provider, - struct SpringBoardServicesClientHandle **client); - -/** - * Connects to the Springboard service using a usbmuxd provider - * - * # Arguments - * * [`provider`] - A UsbmuxdProvider - * * [`client`] - On success, will be set to point to a newly allocated SpringBoardServicesClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `provider` must be a valid pointer to a handle allocated by this library - * `client` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode springboard_services_connect_usbmuxd(struct UsbmuxdProviderHandle *provider, - struct SpringBoardServicesClientHandle **client); - -/** - * Creates a new SpringBoardServices client from an existing Idevice connection - * - * # Arguments - * * [`socket`] - An IdeviceSocket handle - * * [`client`] - On success, will be set to point to a newly allocated SpringBoardServicesClient handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `socket` must be a valid pointer to a handle allocated by this library - * `client` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode springboard_services_new(struct IdeviceHandle *socket, - struct SpringBoardServicesClientHandle **client); - -/** - * Gets the icon of the specified app by bundle identifier - * - * # Arguments - * * `client` - A valid SpringBoardServicesClient handle - * * `bundle_identifier` - The identifiers of the app to get icon - * * `out_result` - On success, will be set to point to a newly allocated png data - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `client` must be a valid pointer to a handle allocated by this library - * `out_result` must be a valid, non-null pointer to a location where the result will be stored - */ -enum IdeviceErrorCode springboard_services_get_icon(struct SpringBoardServicesClientHandle *client, - const char *bundle_identifier, - void **out_result, - size_t *out_result_len); - -/** - * Frees an SpringBoardServicesClient handle - * - * # Arguments - * * [`handle`] - The handle to free - * - * # Safety - * `handle` must be a valid pointer to the handle that was allocated by this library, - * or NULL (in which case this function does nothing) - */ -void springboard_services_free(struct SpringBoardServicesClientHandle *handle); - -/** - * Connects to a usbmuxd instance over TCP - * - * # Arguments - * * [`addr`] - The socket address to connect to - * * [`addr_len`] - Length of the socket - * * [`tag`] - A tag that will be returned by usbmuxd responses - * * [`usbmuxd_connection`] - On success, will be set to point to a newly allocated UsbmuxdConnection handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `addr` must be a valid sockaddr - * `usbmuxd_connection` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode idevice_usbmuxd_new_tcp_connection(const struct sockaddr *addr, - socklen_t addr_len, - uint32_t tag, - struct UsbmuxdConnectionHandle **usbmuxd_connection); - -/** - * Connects to a usbmuxd instance over unix socket - * - * # Arguments - * * [`addr`] - The socket path to connect to - * * [`tag`] - A tag that will be returned by usbmuxd responses - * * [`usbmuxd_connection`] - On success, will be set to point to a newly allocated UsbmuxdConnection handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `addr` must be a valid CStr - * `usbmuxd_connection` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode idevice_usbmuxd_new_unix_socket_connection(const char *addr, - uint32_t tag, - struct UsbmuxdConnectionHandle **usbmuxd_connection); - -/** - * Frees a UsbmuxdConnection handle - * - * # Arguments - * * [`usbmuxd_connection`] - The UsbmuxdConnection handle to free - * - * # Safety - * `usbmuxd_connection` must be a valid pointer to a UsbmuxdConnection handle that was allocated by this library, - * or NULL (in which case this function does nothing) - */ -void idevice_usbmuxd_connection_free(struct UsbmuxdConnectionHandle *usbmuxd_connection); - -/** - * Creates a usbmuxd TCP address struct - * - * # Arguments - * * [`addr`] - The socket address to connect to - * * [`addr_len`] - Length of the socket - * * [`usbmuxd_addr`] - On success, will be set to point to a newly allocated UsbmuxdAddr handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `addr` must be a valid sockaddr - * `usbmuxd_Addr` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode idevice_usbmuxd_tcp_addr_new(const struct sockaddr *addr, - socklen_t addr_len, - struct UsbmuxdAddrHandle **usbmuxd_addr); - -/** - * Creates a new UsbmuxdAddr struct with a unix socket - * - * # Arguments - * * [`addr`] - The socket path to connect to - * * [`usbmuxd_addr`] - On success, will be set to point to a newly allocated UsbmuxdAddr handle - * - * # Returns - * An error code indicating success or failure - * - * # Safety - * `addr` must be a valid CStr - * `usbmuxd_addr` must be a valid, non-null pointer to a location where the handle will be stored - */ -enum IdeviceErrorCode idevice_usbmuxd_unix_addr_new(const char *addr, - struct UsbmuxdAddrHandle **usbmuxd_addr); - -/** - * Frees a UsbmuxdAddr handle - * - * # Arguments - * * [`usbmuxd_addr`] - The UsbmuxdAddr handle to free - * - * # Safety - * `usbmuxd_addr` must be a valid pointer to a UsbmuxdAddr handle that was allocated by this library, - * or NULL (in which case this function does nothing) - */ -void idevice_usbmuxd_addr_free(struct UsbmuxdAddrHandle *usbmuxd_addr); diff --git a/Ksign/Supporting Files/idevice/plist/plist.h b/Ksign/Supporting Files/idevice/plist/plist.h deleted file mode 100644 index 2bb947f..0000000 --- a/Ksign/Supporting Files/idevice/plist/plist.h +++ /dev/null @@ -1,1094 +0,0 @@ -/** - * @file plist/plist.h - * @brief Main include of libplist - * \internal - * - * Copyright (c) 2012-2023 Nikias Bassen, All Rights Reserved. - * Copyright (c) 2008-2009 Jonathan Beck, All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef LIBPLIST_H -#define LIBPLIST_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -#if _MSC_VER && _MSC_VER < 1700 - typedef __int8 int8_t; - typedef __int16 int16_t; - typedef __int32 int32_t; - typedef __int64 int64_t; - - typedef unsigned __int8 uint8_t; - typedef unsigned __int16 uint16_t; - typedef unsigned __int32 uint32_t; - typedef unsigned __int64 uint64_t; - -#else -#include -#endif - -#ifdef __llvm__ - #if defined(__has_extension) - #if (__has_extension(attribute_deprecated_with_message)) - #ifndef PLIST_WARN_DEPRECATED - #define PLIST_WARN_DEPRECATED(x) __attribute__((deprecated(x))) - #endif - #else - #ifndef PLIST_WARN_DEPRECATED - #define PLIST_WARN_DEPRECATED(x) __attribute__((deprecated)) - #endif - #endif - #else - #ifndef PLIST_WARN_DEPRECATED - #define PLIST_WARN_DEPRECATED(x) __attribute__((deprecated)) - #endif - #endif -#elif (__GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 5))) - #ifndef PLIST_WARN_DEPRECATED - #define PLIST_WARN_DEPRECATED(x) __attribute__((deprecated(x))) - #endif -#elif defined(_MSC_VER) - #ifndef PLIST_WARN_DEPRECATED - #define PLIST_WARN_DEPRECATED(x) __declspec(deprecated(x)) - #endif -#else - #define PLIST_WARN_DEPRECATED(x) - #pragma message("WARNING: You need to implement DEPRECATED for this compiler") -#endif - -#include -#include - - /** - * \mainpage libplist : A library to handle Apple Property Lists - * \defgroup PublicAPI Public libplist API - */ - /*@{*/ - - - /** - * The basic plist abstract data type. - */ - typedef void *plist_t; - - /** - * The plist dictionary iterator. - */ - typedef void* plist_dict_iter; - - /** - * The plist array iterator. - */ - typedef void* plist_array_iter; - - /** - * The enumeration of plist node types. - */ - typedef enum - { - PLIST_BOOLEAN, /**< Boolean, scalar type */ - PLIST_INT, /**< Integer, scalar type */ - PLIST_REAL, /**< Real, scalar type */ - PLIST_STRING, /**< ASCII string, scalar type */ - PLIST_ARRAY, /**< Ordered array, structured type */ - PLIST_DICT, /**< Unordered dictionary (key/value pair), structured type */ - PLIST_DATE, /**< Date, scalar type */ - PLIST_DATA, /**< Binary data, scalar type */ - PLIST_KEY, /**< Key in dictionaries (ASCII String), scalar type */ - PLIST_UID, /**< Special type used for 'keyed encoding' */ - PLIST_NULL, /**< NULL type */ - PLIST_NONE /**< No type */ - } plist_type; - - /* for backwards compatibility */ - #define PLIST_UINT PLIST_INT - - /** - * libplist error values - */ - typedef enum - { - PLIST_ERR_SUCCESS = 0, /**< operation successful */ - PLIST_ERR_INVALID_ARG = -1, /**< one or more of the parameters are invalid */ - PLIST_ERR_FORMAT = -2, /**< the plist contains nodes not compatible with the output format */ - PLIST_ERR_PARSE = -3, /**< parsing of the input format failed */ - PLIST_ERR_NO_MEM = -4, /**< not enough memory to handle the operation */ - PLIST_ERR_UNKNOWN = -255 /**< an unspecified error occurred */ - } plist_err_t; - - /******************************************** - * * - * Creation & Destruction * - * * - ********************************************/ - - /** - * Create a new root plist_t type #PLIST_DICT - * - * @return the created plist - * @sa #plist_type - */ - plist_t plist_new_dict(void); - - /** - * Create a new root plist_t type #PLIST_ARRAY - * - * @return the created plist - * @sa #plist_type - */ - plist_t plist_new_array(void); - - /** - * Create a new plist_t type #PLIST_STRING - * - * @param val the sting value, encoded in UTF8. - * @return the created item - * @sa #plist_type - */ - plist_t plist_new_string(const char *val); - - /** - * Create a new plist_t type #PLIST_BOOLEAN - * - * @param val the boolean value, 0 is false, other values are true. - * @return the created item - * @sa #plist_type - */ - plist_t plist_new_bool(uint8_t val); - - /** - * Create a new plist_t type #PLIST_INT with an unsigned integer value - * - * @param val the unsigned integer value - * @return the created item - * @sa #plist_type - * @note The value is always stored as uint64_t internally. - * Use #plist_get_uint_val or #plist_get_int_val to get the unsigned or signed value. - */ - plist_t plist_new_uint(uint64_t val); - - /** - * Create a new plist_t type #PLIST_INT with a signed integer value - * - * @param val the signed integer value - * @return the created item - * @sa #plist_type - * @note The value is always stored as uint64_t internally. - * Use #plist_get_uint_val or #plist_get_int_val to get the unsigned or signed value. - */ - plist_t plist_new_int(int64_t val); - - /** - * Create a new plist_t type #PLIST_REAL - * - * @param val the real value - * @return the created item - * @sa #plist_type - */ - plist_t plist_new_real(double val); - - /** - * Create a new plist_t type #PLIST_DATA - * - * @param val the binary buffer - * @param length the length of the buffer - * @return the created item - * @sa #plist_type - */ - plist_t plist_new_data(const char *val, uint64_t length); - - /** - * Create a new plist_t type #PLIST_DATE - * - * @param sec the number of seconds since 01/01/2001 - * @param usec the number of microseconds - * @return the created item - * @sa #plist_type - */ - plist_t plist_new_date(int32_t sec, int32_t usec); - - /** - * Create a new plist_t type #PLIST_UID - * - * @param val the unsigned integer value - * @return the created item - * @sa #plist_type - */ - plist_t plist_new_uid(uint64_t val); - - /** - * Create a new plist_t type #PLIST_NULL - * @return the created item - * @sa #plist_type - * @note This type is not valid for all formats, e.g. the XML format - * does not support it. - */ - plist_t plist_new_null(void); - - /** - * Destruct a plist_t node and all its children recursively - * - * @param plist the plist to free - */ - void plist_free(plist_t plist); - - /** - * Return a copy of passed node and it's children - * - * @param node the plist to copy - * @return copied plist - */ - plist_t plist_copy(plist_t node); - - - /******************************************** - * * - * Array functions * - * * - ********************************************/ - - /** - * Get size of a #PLIST_ARRAY node. - * - * @param node the node of type #PLIST_ARRAY - * @return size of the #PLIST_ARRAY node - */ - uint32_t plist_array_get_size(plist_t node); - - /** - * Get the nth item in a #PLIST_ARRAY node. - * - * @param node the node of type #PLIST_ARRAY - * @param n the index of the item to get. Range is [0, array_size[ - * @return the nth item or NULL if node is not of type #PLIST_ARRAY - */ - plist_t plist_array_get_item(plist_t node, uint32_t n); - - /** - * Get the index of an item. item must be a member of a #PLIST_ARRAY node. - * - * @param node the node - * @return the node index or UINT_MAX if node index can't be determined - */ - uint32_t plist_array_get_item_index(plist_t node); - - /** - * Set the nth item in a #PLIST_ARRAY node. - * The previous item at index n will be freed using #plist_free - * - * @param node the node of type #PLIST_ARRAY - * @param item the new item at index n. The array is responsible for freeing item when it is no longer needed. - * @param n the index of the item to get. Range is [0, array_size[. Assert if n is not in range. - */ - void plist_array_set_item(plist_t node, plist_t item, uint32_t n); - - /** - * Append a new item at the end of a #PLIST_ARRAY node. - * - * @param node the node of type #PLIST_ARRAY - * @param item the new item. The array is responsible for freeing item when it is no longer needed. - */ - void plist_array_append_item(plist_t node, plist_t item); - - /** - * Insert a new item at position n in a #PLIST_ARRAY node. - * - * @param node the node of type #PLIST_ARRAY - * @param item the new item to insert. The array is responsible for freeing item when it is no longer needed. - * @param n The position at which the node will be stored. Range is [0, array_size[. Assert if n is not in range. - */ - void plist_array_insert_item(plist_t node, plist_t item, uint32_t n); - - /** - * Remove an existing position in a #PLIST_ARRAY node. - * Removed position will be freed using #plist_free. - * - * @param node the node of type #PLIST_ARRAY - * @param n The position to remove. Range is [0, array_size[. Assert if n is not in range. - */ - void plist_array_remove_item(plist_t node, uint32_t n); - - /** - * Remove a node that is a child node of a #PLIST_ARRAY node. - * node will be freed using #plist_free. - * - * @param node The node to be removed from its #PLIST_ARRAY parent. - */ - void plist_array_item_remove(plist_t node); - - /** - * Create an iterator of a #PLIST_ARRAY node. - * The allocated iterator should be freed with the standard free function. - * - * @param node The node of type #PLIST_ARRAY - * @param iter Location to store the iterator for the array. - */ - void plist_array_new_iter(plist_t node, plist_array_iter *iter); - - /** - * Increment iterator of a #PLIST_ARRAY node. - * - * @param node The node of type #PLIST_ARRAY. - * @param iter Iterator of the array - * @param item Location to store the item. The caller must *not* free the - * returned item. Will be set to NULL when no more items are left - * to iterate. - */ - void plist_array_next_item(plist_t node, plist_array_iter iter, plist_t *item); - - - /******************************************** - * * - * Dictionary functions * - * * - ********************************************/ - - /** - * Get size of a #PLIST_DICT node. - * - * @param node the node of type #PLIST_DICT - * @return size of the #PLIST_DICT node - */ - uint32_t plist_dict_get_size(plist_t node); - - /** - * Create an iterator of a #PLIST_DICT node. - * The allocated iterator should be freed with the standard free function. - * - * @param node The node of type #PLIST_DICT. - * @param iter Location to store the iterator for the dictionary. - */ - void plist_dict_new_iter(plist_t node, plist_dict_iter *iter); - - /** - * Increment iterator of a #PLIST_DICT node. - * - * @param node The node of type #PLIST_DICT - * @param iter Iterator of the dictionary - * @param key Location to store the key, or NULL. The caller is responsible - * for freeing the the returned string. - * @param val Location to store the value, or NULL. The caller must *not* - * free the returned value. Will be set to NULL when no more - * key/value pairs are left to iterate. - */ - void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val); - - /** - * Get key associated key to an item. Item must be member of a dictionary. - * - * @param node the item - * @param key a location to store the key. The caller is responsible for freeing the returned string. - */ - void plist_dict_get_item_key(plist_t node, char **key); - - /** - * Get the nth item in a #PLIST_DICT node. - * - * @param node the node of type #PLIST_DICT - * @param key the identifier of the item to get. - * @return the item or NULL if node is not of type #PLIST_DICT. The caller should not free - * the returned node. - */ - plist_t plist_dict_get_item(plist_t node, const char* key); - - /** - * Get key node associated to an item. Item must be member of a dictionary. - * - * @param node the item - * @return the key node of the given item, or NULL. - */ - plist_t plist_dict_item_get_key(plist_t node); - - /** - * Set item identified by key in a #PLIST_DICT node. - * The previous item identified by key will be freed using #plist_free. - * If there is no item for the given key a new item will be inserted. - * - * @param node the node of type #PLIST_DICT - * @param item the new item associated to key - * @param key the identifier of the item to set. - */ - void plist_dict_set_item(plist_t node, const char* key, plist_t item); - - /** - * Insert a new item into a #PLIST_DICT node. - * - * @deprecated Deprecated. Use plist_dict_set_item instead. - * - * @param node the node of type #PLIST_DICT - * @param item the new item to insert - * @param key The identifier of the item to insert. - */ - PLIST_WARN_DEPRECATED("use plist_dict_set_item instead") - void plist_dict_insert_item(plist_t node, const char* key, plist_t item); - - /** - * Remove an existing position in a #PLIST_DICT node. - * Removed position will be freed using #plist_free - * - * @param node the node of type #PLIST_DICT - * @param key The identifier of the item to remove. Assert if identifier is not present. - */ - void plist_dict_remove_item(plist_t node, const char* key); - - /** - * Merge a dictionary into another. This will add all key/value pairs - * from the source dictionary to the target dictionary, overwriting - * any existing key/value pairs that are already present in target. - * - * @param target pointer to an existing node of type #PLIST_DICT - * @param source node of type #PLIST_DICT that should be merged into target - */ - void plist_dict_merge(plist_t *target, plist_t source); - - - /******************************************** - * * - * Getters * - * * - ********************************************/ - - /** - * Get the parent of a node - * - * @param node the parent (NULL if node is root) - */ - plist_t plist_get_parent(plist_t node); - - /** - * Get the #plist_type of a node. - * - * @param node the node - * @return the type of the node - */ - plist_type plist_get_node_type(plist_t node); - - /** - * Get the value of a #PLIST_KEY node. - * This function does nothing if node is not of type #PLIST_KEY - * - * @param node the node - * @param val a pointer to a C-string. This function allocates the memory, - * caller is responsible for freeing it. - * @note Use plist_mem_free() to free the allocated memory. - */ - void plist_get_key_val(plist_t node, char **val); - - /** - * Get the value of a #PLIST_STRING node. - * This function does nothing if node is not of type #PLIST_STRING - * - * @param node the node - * @param val a pointer to a C-string. This function allocates the memory, - * caller is responsible for freeing it. Data is UTF-8 encoded. - * @note Use plist_mem_free() to free the allocated memory. - */ - void plist_get_string_val(plist_t node, char **val); - - /** - * Get a pointer to the buffer of a #PLIST_STRING node. - * - * @note DO NOT MODIFY the buffer. Mind that the buffer is only available - * until the plist node gets freed. Make a copy if needed. - * - * @param node The node - * @param length If non-NULL, will be set to the length of the string - * - * @return Pointer to the NULL-terminated buffer. - */ - const char* plist_get_string_ptr(plist_t node, uint64_t* length); - - /** - * Get the value of a #PLIST_BOOLEAN node. - * This function does nothing if node is not of type #PLIST_BOOLEAN - * - * @param node the node - * @param val a pointer to a uint8_t variable. - */ - void plist_get_bool_val(plist_t node, uint8_t * val); - - /** - * Get the unsigned integer value of a #PLIST_INT node. - * This function does nothing if node is not of type #PLIST_INT - * - * @param node the node - * @param val a pointer to a uint64_t variable. - */ - void plist_get_uint_val(plist_t node, uint64_t * val); - - /** - * Get the signed integer value of a #PLIST_INT node. - * This function does nothing if node is not of type #PLIST_INT - * - * @param node the node - * @param val a pointer to a int64_t variable. - */ - void plist_get_int_val(plist_t node, int64_t * val); - - /** - * Get the value of a #PLIST_REAL node. - * This function does nothing if node is not of type #PLIST_REAL - * - * @param node the node - * @param val a pointer to a double variable. - */ - void plist_get_real_val(plist_t node, double *val); - - /** - * Get the value of a #PLIST_DATA node. - * This function does nothing if node is not of type #PLIST_DATA - * - * @param node the node - * @param val a pointer to an unallocated char buffer. This function allocates the memory, - * caller is responsible for freeing it. - * @param length the length of the buffer - * @note Use plist_mem_free() to free the allocated memory. - */ - void plist_get_data_val(plist_t node, char **val, uint64_t * length); - - /** - * Get a pointer to the data buffer of a #PLIST_DATA node. - * - * @note DO NOT MODIFY the buffer. Mind that the buffer is only available - * until the plist node gets freed. Make a copy if needed. - * - * @param node The node - * @param length Pointer to a uint64_t that will be set to the length of the buffer - * - * @return Pointer to the buffer - */ - const char* plist_get_data_ptr(plist_t node, uint64_t* length); - - /** - * Get the value of a #PLIST_DATE node. - * This function does nothing if node is not of type #PLIST_DATE - * - * @param node the node - * @param sec a pointer to an int32_t variable. Represents the number of seconds since 01/01/2001. - * @param usec a pointer to an int32_t variable. Represents the number of microseconds - */ - void plist_get_date_val(plist_t node, int32_t * sec, int32_t * usec); - - /** - * Get the value of a #PLIST_UID node. - * This function does nothing if node is not of type #PLIST_UID - * - * @param node the node - * @param val a pointer to a uint64_t variable. - */ - void plist_get_uid_val(plist_t node, uint64_t * val); - - - /******************************************** - * * - * Setters * - * * - ********************************************/ - - /** - * Set the value of a node. - * Forces type of node to #PLIST_KEY - * - * @param node the node - * @param val the key value - */ - void plist_set_key_val(plist_t node, const char *val); - - /** - * Set the value of a node. - * Forces type of node to #PLIST_STRING - * - * @param node the node - * @param val the string value. The string is copied when set and will be - * freed by the node. - */ - void plist_set_string_val(plist_t node, const char *val); - - /** - * Set the value of a node. - * Forces type of node to #PLIST_BOOLEAN - * - * @param node the node - * @param val the boolean value - */ - void plist_set_bool_val(plist_t node, uint8_t val); - - /** - * Set the value of a node. - * Forces type of node to #PLIST_INT - * - * @param node the node - * @param val the unsigned integer value - */ - void plist_set_uint_val(plist_t node, uint64_t val); - - /** - * Set the value of a node. - * Forces type of node to #PLIST_INT - * - * @param node the node - * @param val the signed integer value - */ - void plist_set_int_val(plist_t node, int64_t val); - - /** - * Set the value of a node. - * Forces type of node to #PLIST_REAL - * - * @param node the node - * @param val the real value - */ - void plist_set_real_val(plist_t node, double val); - - /** - * Set the value of a node. - * Forces type of node to #PLIST_DATA - * - * @param node the node - * @param val the binary buffer. The buffer is copied when set and will - * be freed by the node. - * @param length the length of the buffer - */ - void plist_set_data_val(plist_t node, const char *val, uint64_t length); - - /** - * Set the value of a node. - * Forces type of node to #PLIST_DATE - * - * @param node the node - * @param sec the number of seconds since 01/01/2001 - * @param usec the number of microseconds - */ - void plist_set_date_val(plist_t node, int32_t sec, int32_t usec); - - /** - * Set the value of a node. - * Forces type of node to #PLIST_UID - * - * @param node the node - * @param val the unsigned integer value - */ - void plist_set_uid_val(plist_t node, uint64_t val); - - - /******************************************** - * * - * Import & Export * - * * - ********************************************/ - - /** - * Export the #plist_t structure to XML format. - * - * @param plist the root node to export - * @param plist_xml a pointer to a C-string. This function allocates the memory, - * caller is responsible for freeing it. Data is UTF-8 encoded. - * @param length a pointer to an uint32_t variable. Represents the length of the allocated buffer. - * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure - * @note Use plist_mem_free() to free the allocated memory. - */ - plist_err_t plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length); - - /** - * Export the #plist_t structure to binary format. - * - * @param plist the root node to export - * @param plist_bin a pointer to a char* buffer. This function allocates the memory, - * caller is responsible for freeing it. - * @param length a pointer to an uint32_t variable. Represents the length of the allocated buffer. - * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure - * @note Use plist_mem_free() to free the allocated memory. - */ - plist_err_t plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length); - - /** - * Export the #plist_t structure to JSON format. - * - * @param plist the root node to export - * @param plist_json a pointer to a char* buffer. This function allocates the memory, - * caller is responsible for freeing it. - * @param length a pointer to an uint32_t variable. Represents the length of the allocated buffer. - * @param prettify pretty print the output if != 0 - * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure - * @note Use plist_mem_free() to free the allocated memory. - */ - plist_err_t plist_to_json(plist_t plist, char **plist_json, uint32_t* length, int prettify); - - /** - * Export the #plist_t structure to OpenStep format. - * - * @param plist the root node to export - * @param plist_openstep a pointer to a char* buffer. This function allocates the memory, - * caller is responsible for freeing it. - * @param length a pointer to an uint32_t variable. Represents the length of the allocated buffer. - * @param prettify pretty print the output if != 0 - * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure - * @note Use plist_mem_free() to free the allocated memory. - */ - plist_err_t plist_to_openstep(plist_t plist, char **plist_openstep, uint32_t* length, int prettify); - - - /** - * Import the #plist_t structure from XML format. - * - * @param plist_xml a pointer to the xml buffer. - * @param length length of the buffer to read. - * @param plist a pointer to the imported plist. - * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure - */ - plist_err_t plist_from_xml(const char *plist_xml, uint32_t length, plist_t * plist); - - /** - * Import the #plist_t structure from binary format. - * - * @param plist_bin a pointer to the xml buffer. - * @param length length of the buffer to read. - * @param plist a pointer to the imported plist. - * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure - */ - plist_err_t plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist); - - /** - * Import the #plist_t structure from JSON format. - * - * @param json a pointer to the JSON buffer. - * @param length length of the buffer to read. - * @param plist a pointer to the imported plist. - * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure - */ - plist_err_t plist_from_json(const char *json, uint32_t length, plist_t * plist); - - /** - * Import the #plist_t structure from OpenStep plist format. - * - * @param openstep a pointer to the OpenStep plist buffer. - * @param length length of the buffer to read. - * @param plist a pointer to the imported plist. - * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure - */ - plist_err_t plist_from_openstep(const char *openstep, uint32_t length, plist_t * plist); - - /** - * Import the #plist_t structure from memory data. - * This method will look at the first bytes of plist_data - * to determine if plist_data contains a binary, JSON, or XML plist - * and tries to parse the data in the appropriate format. - * @note This is just a convenience function and the format detection is - * very basic. It checks with plist_is_binary() if the data supposedly - * contains binary plist data, if not it checks if the first byte is - * either '{' or '[' and assumes JSON format, otherwise it will try - * to parse the data as XML. - * - * @param plist_data a pointer to the memory buffer containing plist data. - * @param length length of the buffer to read. - * @param plist a pointer to the imported plist. - * @return PLIST_ERR_SUCCESS on success or a #plist_err_t on failure - */ - plist_err_t plist_from_memory(const char *plist_data, uint32_t length, plist_t * plist); - - /** - * Test if in-memory plist data is in binary format. - * This function will look at the first bytes of plist_data to determine - * if it supposedly contains a binary plist. - * @note The function is not validating the whole memory buffer to check - * if the content is truly a plist, it is only using some heuristic on - * the first few bytes of plist_data. - * - * @param plist_data a pointer to the memory buffer containing plist data. - * @param length length of the buffer to read. - * @return 1 if the buffer is a binary plist, 0 otherwise. - */ - int plist_is_binary(const char *plist_data, uint32_t length); - - /******************************************** - * * - * Utils * - * * - ********************************************/ - - /** - * Get a node from its path. Each path element depends on the associated father node type. - * For Dictionaries, var args are casted to const char*, for arrays, var args are caster to uint32_t - * Search is breath first order. - * - * @param plist the node to access result from. - * @param length length of the path to access - * @return the value to access. - */ - plist_t plist_access_path(plist_t plist, uint32_t length, ...); - - /** - * Variadic version of #plist_access_path. - * - * @param plist the node to access result from. - * @param length length of the path to access - * @param v list of array's index and dic'st key - * @return the value to access. - */ - plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v); - - /** - * Compare two node values - * - * @param node_l left node to compare - * @param node_r rigth node to compare - * @return TRUE is type and value match, FALSE otherwise. - */ - char plist_compare_node_value(plist_t node_l, plist_t node_r); - - #define _PLIST_IS_TYPE(__plist, __plist_type) (__plist && (plist_get_node_type(__plist) == PLIST_##__plist_type)) - - /* Helper macros for the different plist types */ - #define PLIST_IS_BOOLEAN(__plist) _PLIST_IS_TYPE(__plist, BOOLEAN) - #define PLIST_IS_INT(__plist) _PLIST_IS_TYPE(__plist, INT) - #define PLIST_IS_REAL(__plist) _PLIST_IS_TYPE(__plist, REAL) - #define PLIST_IS_STRING(__plist) _PLIST_IS_TYPE(__plist, STRING) - #define PLIST_IS_ARRAY(__plist) _PLIST_IS_TYPE(__plist, ARRAY) - #define PLIST_IS_DICT(__plist) _PLIST_IS_TYPE(__plist, DICT) - #define PLIST_IS_DATE(__plist) _PLIST_IS_TYPE(__plist, DATE) - #define PLIST_IS_DATA(__plist) _PLIST_IS_TYPE(__plist, DATA) - #define PLIST_IS_KEY(__plist) _PLIST_IS_TYPE(__plist, KEY) - #define PLIST_IS_UID(__plist) _PLIST_IS_TYPE(__plist, UID) - /* for backwards compatibility */ - #define PLIST_IS_UINT PLIST_IS_INT - - /** - * Helper function to check the value of a PLIST_BOOL node. - * - * @param boolnode node of type PLIST_BOOL - * @return 1 if the boolean node has a value of TRUE or 0 if FALSE. - */ - int plist_bool_val_is_true(plist_t boolnode); - - /** - * Helper function to test if a given #PLIST_INT node's value is negative - * - * @param intnode node of type PLIST_INT - * @return 1 if the node's value is negative, or 0 if positive. - */ - int plist_int_val_is_negative(plist_t intnode); - - /** - * Helper function to compare the value of a PLIST_INT node against - * a given signed integer value. - * - * @param uintnode node of type PLIST_INT - * @param cmpval value to compare against - * @return 0 if the node's value and cmpval are equal, - * 1 if the node's value is greater than cmpval, - * or -1 if the node's value is less than cmpval. - */ - int plist_int_val_compare(plist_t uintnode, int64_t cmpval); - - /** - * Helper function to compare the value of a PLIST_INT node against - * a given unsigned integer value. - * - * @param uintnode node of type PLIST_INT - * @param cmpval value to compare against - * @return 0 if the node's value and cmpval are equal, - * 1 if the node's value is greater than cmpval, - * or -1 if the node's value is less than cmpval. - */ - int plist_uint_val_compare(plist_t uintnode, uint64_t cmpval); - - /** - * Helper function to compare the value of a PLIST_UID node against - * a given value. - * - * @param uidnode node of type PLIST_UID - * @param cmpval value to compare against - * @return 0 if the node's value and cmpval are equal, - * 1 if the node's value is greater than cmpval, - * or -1 if the node's value is less than cmpval. - */ - int plist_uid_val_compare(plist_t uidnode, uint64_t cmpval); - - /** - * Helper function to compare the value of a PLIST_REAL node against - * a given value. - * - * @note WARNING: Comparing floating point values can give inaccurate - * results because of the nature of floating point values on computer - * systems. While this function is designed to be as accurate as - * possible, please don't rely on it too much. - * - * @param realnode node of type PLIST_REAL - * @param cmpval value to compare against - * @return 0 if the node's value and cmpval are (almost) equal, - * 1 if the node's value is greater than cmpval, - * or -1 if the node's value is less than cmpval. - */ - int plist_real_val_compare(plist_t realnode, double cmpval); - - /** - * Helper function to compare the value of a PLIST_DATE node against - * a given set of seconds and fraction of a second since epoch. - * - * @param datenode node of type PLIST_DATE - * @param cmpsec number of seconds since epoch to compare against - * @param cmpusec fraction of a second in microseconds to compare against - * @return 0 if the node's date is equal to the supplied values, - * 1 if the node's date is greater than the supplied values, - * or -1 if the node's date is less than the supplied values. - */ - int plist_date_val_compare(plist_t datenode, int32_t cmpsec, int32_t cmpusec); - - /** - * Helper function to compare the value of a PLIST_STRING node against - * a given value. - * This function basically behaves like strcmp. - * - * @param strnode node of type PLIST_STRING - * @param cmpval value to compare against - * @return 0 if the node's value and cmpval are equal, - * > 0 if the node's value is lexicographically greater than cmpval, - * or < 0 if the node's value is lexicographically less than cmpval. - */ - int plist_string_val_compare(plist_t strnode, const char* cmpval); - - /** - * Helper function to compare the value of a PLIST_STRING node against - * a given value, while not comparing more than n characters. - * This function basically behaves like strncmp. - * - * @param strnode node of type PLIST_STRING - * @param cmpval value to compare against - * @param n maximum number of characters to compare - * @return 0 if the node's value and cmpval are equal, - * > 0 if the node's value is lexicographically greater than cmpval, - * or < 0 if the node's value is lexicographically less than cmpval. - */ - int plist_string_val_compare_with_size(plist_t strnode, const char* cmpval, size_t n); - - /** - * Helper function to match a given substring in the value of a - * PLIST_STRING node. - * - * @param strnode node of type PLIST_STRING - * @param substr value to match - * @return 1 if the node's value contains the given substring, - * or 0 if not. - */ - int plist_string_val_contains(plist_t strnode, const char* substr); - - /** - * Helper function to compare the value of a PLIST_KEY node against - * a given value. - * This function basically behaves like strcmp. - * - * @param keynode node of type PLIST_KEY - * @param cmpval value to compare against - * @return 0 if the node's value and cmpval are equal, - * > 0 if the node's value is lexicographically greater than cmpval, - * or < 0 if the node's value is lexicographically less than cmpval. - */ - int plist_key_val_compare(plist_t keynode, const char* cmpval); - - /** - * Helper function to compare the value of a PLIST_KEY node against - * a given value, while not comparing more than n characters. - * This function basically behaves like strncmp. - * - * @param keynode node of type PLIST_KEY - * @param cmpval value to compare against - * @param n maximum number of characters to compare - * @return 0 if the node's value and cmpval are equal, - * > 0 if the node's value is lexicographically greater than cmpval, - * or < 0 if the node's value is lexicographically less than cmpval. - */ - int plist_key_val_compare_with_size(plist_t keynode, const char* cmpval, size_t n); - - /** - * Helper function to match a given substring in the value of a - * PLIST_KEY node. - * - * @param keynode node of type PLIST_KEY - * @param substr value to match - * @return 1 if the node's value contains the given substring, - * or 0 if not. - */ - int plist_key_val_contains(plist_t keynode, const char* substr); - - /** - * Helper function to compare the data of a PLIST_DATA node against - * a given blob and size. - * This function basically behaves like memcmp after making sure the - * size of the node's data value is equal to the size of cmpval (n), - * making this a "full match" comparison. - * - * @param datanode node of type PLIST_DATA - * @param cmpval data blob to compare against - * @param n size of data blob passed in cmpval - * @return 0 if the node's data blob and cmpval are equal, - * > 0 if the node's value is lexicographically greater than cmpval, - * or < 0 if the node's value is lexicographically less than cmpval. - */ - int plist_data_val_compare(plist_t datanode, const uint8_t* cmpval, size_t n); - - /** - * Helper function to compare the data of a PLIST_DATA node against - * a given blob and size, while no more than n bytes are compared. - * This function basically behaves like memcmp after making sure the - * size of the node's data value is at least n, making this a - * "starts with" comparison. - * - * @param datanode node of type PLIST_DATA - * @param cmpval data blob to compare against - * @param n size of data blob passed in cmpval - * @return 0 if the node's value and cmpval are equal, - * > 0 if the node's value is lexicographically greater than cmpval, - * or < 0 if the node's value is lexicographically less than cmpval. - */ - int plist_data_val_compare_with_size(plist_t datanode, const uint8_t* cmpval, size_t n); - - /** - * Helper function to match a given data blob within the value of a - * PLIST_DATA node. - * - * @param datanode node of type PLIST_KEY - * @param cmpval data blob to match - * @param n size of data blob passed in cmpval - * @return 1 if the node's value contains the given data blob - * or 0 if not. - */ - int plist_data_val_contains(plist_t datanode, const uint8_t* cmpval, size_t n); - - /** - * Free memory allocated by relevant libplist API calls: - * - plist_to_xml() - * - plist_to_bin() - * - plist_get_key_val() - * - plist_get_string_val() - * - plist_get_data_val() - * - * @param ptr pointer to the memory to free - * - * @note Do not use this function to free plist_t nodes, use plist_free() - * instead. - */ - void plist_mem_free(void* ptr); - - /*@}*/ - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Ksign/Utilities/FR.swift b/Ksign/Utilities/FR.swift index 922468b..177f050 100644 --- a/Ksign/Utilities/FR.swift +++ b/Ksign/Utilities/FR.swift @@ -10,6 +10,7 @@ import UIKit.UIImage import Zsign import NimbleJSON import AltSourceKit +import IDeviceSwift enum FR { static func handlePackageFile( @@ -143,7 +144,6 @@ enum FR { } } - #if IDEVICE static func movePairing(_ url: URL) { let fileManager = FileManager.default let dest = URL.documentsDirectory.appendingPathComponent("pairingFile.plist") @@ -154,7 +154,6 @@ enum FR { HeartbeatManager.shared.start(true) } - #endif #if SERVER static func downloadSSLCertificates( diff --git a/Ksign/Utilities/Handlers/ArchiveHandler.swift b/Ksign/Utilities/Handlers/ArchiveHandler.swift index 62bc45f..944847b 100644 --- a/Ksign/Utilities/Handlers/ArchiveHandler.swift +++ b/Ksign/Utilities/Handlers/ArchiveHandler.swift @@ -9,6 +9,7 @@ import Foundation import UIKit.UIApplication import Zip import SwiftUI +import IDeviceSwift final class ArchiveHandler: NSObject { @ObservedObject var viewModel: InstallerStatusViewModel diff --git a/Ksign/Views/Library/Install/BulkInstallPreviewView.swift b/Ksign/Views/Library/Install/BulkInstallPreviewView.swift index 7b8b7a4..dca0836 100644 --- a/Ksign/Views/Library/Install/BulkInstallPreviewView.swift +++ b/Ksign/Views/Library/Install/BulkInstallPreviewView.swift @@ -27,7 +27,7 @@ struct BulkInstallPreviewView: View { } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) .background(Color(UIColor.secondarySystemBackground)) - .cornerRadius(12) + .cornerRadius(22.5) .padding() } else { LazyVGrid(columns: columns, spacing: 20) { @@ -37,7 +37,7 @@ struct BulkInstallPreviewView: View { } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) .background(Color(UIColor.secondarySystemBackground)) - .cornerRadius(12) + .cornerRadius(22.5) .padding() } } diff --git a/Ksign/Views/Library/Install/BulkInstallProgressView.swift b/Ksign/Views/Library/Install/BulkInstallProgressView.swift index a5798ad..a05db8b 100644 --- a/Ksign/Views/Library/Install/BulkInstallProgressView.swift +++ b/Ksign/Views/Library/Install/BulkInstallProgressView.swift @@ -7,31 +7,28 @@ import SwiftUI import NimbleViews +import IDeviceSwift struct BulkInstallProgressView: View { var app: AppInfoPresentable @StateObject var viewModel = InstallerStatusViewModel() - #if SERVER + @AppStorage("Feather.installationMethod") private var _installationMethod: Int = 0 @AppStorage("Feather.serverMethod") private var _serverMethod: Int = 0 @StateObject var installer: ServerInstaller @State private var _isWebviewPresenting = false - #endif init(app: AppInfoPresentable) { self.app = app let viewModel = InstallerStatusViewModel() self._viewModel = StateObject(wrappedValue: viewModel) - #if SERVER self._installer = StateObject(wrappedValue: try! ServerInstaller(app: app, viewModel: viewModel)) - #endif } var body: some View { VStack { InstallProgressView(app: app, viewModel: viewModel) } - #if SERVER .sheet(isPresented: $_isWebviewPresenting) { SafariRepresentableView(url: installer.pageEndpoint).ignoresSafeArea() } @@ -52,7 +49,6 @@ struct BulkInstallProgressView: View { BackgroundAudioManager.shared.stop() } } - #endif .onAppear(perform: _install) .onAppear { BackgroundAudioManager.shared.start() @@ -70,22 +66,19 @@ struct BulkInstallProgressView: View { let packageUrl = try await handler.archive() - #if SERVER - await MainActor.run { - installer.packageUrl = packageUrl - viewModel.status = .ready + if await _installationMethod == 0 { + await MainActor.run { + installer.packageUrl = packageUrl + viewModel.status = .ready + } + } else if await _installationMethod == 1 { + let proxy = await InstallationProxy(viewModel: viewModel) + try await proxy.install(at: packageUrl, suspend: app.identifier == Bundle.main.bundleIdentifier!) } - #elseif IDEVICE - let handler = await ConduitInstaller(viewModel: viewModel) - try await handler.install(at: packageUrl) - #endif } catch { await MainActor.run { - #if IDEVICE HeartbeatManager.shared.start(true) - #endif - } } } diff --git a/Ksign/Views/Library/Install/InstallPreviewView.swift b/Ksign/Views/Library/Install/InstallPreviewView.swift index 1a60204..43ab736 100644 --- a/Ksign/Views/Library/Install/InstallPreviewView.swift +++ b/Ksign/Views/Library/Install/InstallPreviewView.swift @@ -7,6 +7,7 @@ import SwiftUI import NimbleViews +import IDeviceSwift // MARK: - View struct InstallPreviewView: View { @@ -16,16 +17,13 @@ struct InstallPreviewView: View { @AppStorage("Feather.useShareSheetForArchiving") private var _useShareSheet: Bool = false // Methods - #if SERVER + @AppStorage("Feather.installationMethod") private var _installationMethod: Int = 0 @AppStorage("Feather.serverMethod") private var _serverMethod: Int = 0 @State private var _isWebviewPresenting = false - #endif var app: AppInfoPresentable @StateObject var viewModel: InstallerStatusViewModel - #if SERVER @StateObject var installer: ServerInstaller - #endif @State var isSharing: Bool init(app: AppInfoPresentable, isSharing: Bool = false) { @@ -33,9 +31,7 @@ struct InstallPreviewView: View { self.isSharing = isSharing let viewModel = InstallerStatusViewModel() self._viewModel = StateObject(wrappedValue: viewModel) - #if SERVER self._installer = StateObject(wrappedValue: try! ServerInstaller(app: app, viewModel: viewModel)) - #endif } // MARK: Body @@ -46,16 +42,12 @@ struct InstallPreviewView: View { } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) .background(Color(UIColor.secondarySystemBackground)) - .cornerRadius(12) + .cornerRadius(22.5) .padding() - #if SERVER .sheet(isPresented: $_isWebviewPresenting) { SafariRepresentableView(url: installer.pageEndpoint).ignoresSafeArea() } .onReceive(viewModel.$status) { newStatus in - #if DEBUG - print(newStatus) - #endif if case .ready = newStatus { if _serverMethod == 0 { UIApplication.shared.open(URL(string: installer.iTunesLink)!) @@ -72,7 +64,6 @@ struct InstallPreviewView: View { BackgroundAudioManager.shared.stop() } } - #endif .onAppear(perform: _install) .onAppear { BackgroundAudioManager.shared.start() @@ -100,15 +91,16 @@ struct InstallPreviewView: View { let packageUrl = try await handler.archive() if await !isSharing { - #if SERVER - await MainActor.run { - installer.packageUrl = packageUrl - viewModel.status = .ready - } - #elseif IDEVICE - let handler = await ConduitInstaller(viewModel: viewModel) - try await handler.install(at: packageUrl) - #endif + if await _installationMethod == 0 { + await MainActor.run { + installer.packageUrl = packageUrl + viewModel.status = .ready + } + } + else if await _installationMethod == 1 { + let handler = await InstallationProxy(viewModel: viewModel) + try await handler.install(at: packageUrl, suspend: app.identifier == Bundle.main.bundleIdentifier!) + } } else { let package = try await handler.moveToArchive(packageUrl, shouldOpen: !_useShareSheet) @@ -131,9 +123,7 @@ struct InstallPreviewView: View { title: .localized("Install"), message: error.localizedDescription, action: { - #if IDEVICE HeartbeatManager.shared.start(true) - #endif dismiss() } ) diff --git a/Ksign/Views/Library/Install/InstallProgressView.swift b/Ksign/Views/Library/Install/InstallProgressView.swift index f4adcf1..d6a1dbf 100644 --- a/Ksign/Views/Library/Install/InstallProgressView.swift +++ b/Ksign/Views/Library/Install/InstallProgressView.swift @@ -6,6 +6,7 @@ // import SwiftUI +import IDeviceSwift struct InstallProgressView: View { @State private var _isPulsing = false diff --git a/Ksign/Views/Library/LibraryView.swift b/Ksign/Views/Library/LibraryView.swift index 95ca9df..3c966a5 100644 --- a/Ksign/Views/Library/LibraryView.swift +++ b/Ksign/Views/Library/LibraryView.swift @@ -177,9 +177,7 @@ struct LibraryView: View { .sheet(item: $_selectedInstallAppPresenting) { app in InstallPreviewView(app: app.base, isSharing: app.archive) .presentationDetents([.height(200)]) - .presentationDragIndicator(.visible) - .compatPresentationRadius(21) - } + .presentationDragIndicator(.visible) } .fullScreenCover(item: $_selectedSigningAppPresenting) { app in SigningView(app: app.base, signAndInstall: app.signAndInstall) .compatNavigationTransition(id: app.base.uuid ?? "", ns: _namespace) diff --git a/Ksign/Views/Settings/Installation/InstallationView.swift b/Ksign/Views/Settings/Installation/InstallationView.swift new file mode 100644 index 0000000..dcbb092 --- /dev/null +++ b/Ksign/Views/Settings/Installation/InstallationView.swift @@ -0,0 +1,57 @@ +// +// InstallationView.swift +// Feather +// +// Created by samara on 3.06.2025. +// + +import SwiftUI +import NimbleViews + +// MARK: - View +struct InstallationView: View { + @AppStorage("Feather.installationMethod") private var _installationMethod: Int = 0 + @State private var _showMethodChangedAlert = false + + private let _installationMethods: [String] = [ + .localized("Server"), + .localized("idevice") + ] + + // MARK: Body + var body: some View { + NBList(.localized("Installation")) { + Section { + Picker(.localized("Installation Type"), systemImage: "arrow.down.app", selection: $_installationMethod) { + ForEach(_installationMethods.indices, id: \.description) { index in + Text(_installationMethods[index]).tag(index) + } + } + } footer: { + Text(.localized("Server (Recommended):\nUses a locally hosted server and itms-services:// to install applications.\n\nIDevice (advanced):\nUses a VPN and a pairing file. Writes to AFC and manually calls installd, while monitoring install progress by using a callback\nAdvantage: It is very reliable, does not need SSL certificates or a externally hosted server. Rather, works similarly to a computer.")) + } + + if _installationMethod == 0 { + ServerView() + } else if _installationMethod == 1 { + TunnelView() + } + } + .onChange(of: _installationMethod) { newValue in + guard newValue == 1 else { return } + _showMethodChangedAlert = true + } + .alert(.localized("Advanced Installation Method"), isPresented: $_showMethodChangedAlert) { + Button(.localized("Switch Back"), role: .destructive) { + _installationMethod = 0 + } + Button(.localized("OK"), role: .cancel) {} + } message: { + Text(.localized("idevice warning")) + } + + + .animation(.default, value: _installationMethod) + } +} + diff --git a/Ksign/Views/Settings/Server & SSL/Models/ServerPackModel.swift b/Ksign/Views/Settings/Installation/Server & SSL/Models/ServerPackModel.swift similarity index 100% rename from Ksign/Views/Settings/Server & SSL/Models/ServerPackModel.swift rename to Ksign/Views/Settings/Installation/Server & SSL/Models/ServerPackModel.swift diff --git a/Ksign/Views/Settings/Server & SSL/ServerView.swift b/Ksign/Views/Settings/Installation/Server & SSL/ServerView.swift similarity index 97% rename from Ksign/Views/Settings/Server & SSL/ServerView.swift rename to Ksign/Views/Settings/Installation/Server & SSL/ServerView.swift index 236a994..6d7f423 100644 --- a/Ksign/Views/Settings/Server & SSL/ServerView.swift +++ b/Ksign/Views/Settings/Installation/Server & SSL/ServerView.swift @@ -22,7 +22,7 @@ struct ServerView: View { private let _serverPackUrl = "https://backloop.dev/pack.json" var body: some View { - NBList(.localized("Server & SSL")) { + Group { Section { Picker(.localized("Installation Type"), systemImage: "server.rack", selection: $_serverMethod) { ForEach(_serverMethods.indices, id: \.self) { index in diff --git a/Ksign/Views/Settings/Tunnel & Pairing/TunnelHeaderCellView.swift b/Ksign/Views/Settings/Installation/Tunnel & Pairing/TunnelHeaderCellView.swift similarity index 100% rename from Ksign/Views/Settings/Tunnel & Pairing/TunnelHeaderCellView.swift rename to Ksign/Views/Settings/Installation/Tunnel & Pairing/TunnelHeaderCellView.swift diff --git a/Ksign/Views/Settings/Tunnel & Pairing/TunnelView.swift b/Ksign/Views/Settings/Installation/Tunnel & Pairing/TunnelView.swift similarity index 92% rename from Ksign/Views/Settings/Tunnel & Pairing/TunnelView.swift rename to Ksign/Views/Settings/Installation/Tunnel & Pairing/TunnelView.swift index a7df508..564ead8 100644 --- a/Ksign/Views/Settings/Tunnel & Pairing/TunnelView.swift +++ b/Ksign/Views/Settings/Installation/Tunnel & Pairing/TunnelView.swift @@ -7,6 +7,7 @@ import SwiftUI import NimbleViews +import IDeviceSwift // MARK: - View struct TunnelView: View { @@ -16,7 +17,7 @@ struct TunnelView: View { // MARK: Body var body: some View { - NBList(.localized("Tunnel & Pairing")) { + Group { Section { _tunnelInfo() TunnelHeaderView() @@ -52,8 +53,8 @@ struct TunnelView: View { Button(.localized("Pairing File Guide"), systemImage: "questionmark.circle") { UIApplication.open("https://github.com/StephenDev0/StikDebug-Guide/blob/main/pairing_file.md") } - Button(.localized("Download StosVPN"), systemImage: "arrow.down.app") { - UIApplication.open("https://apps.apple.com/us/app/stosvpn/id6744003051") + Button(.localized("Download LocalDevVPN"), systemImage: "arrow.down.app") { + UIApplication.open("https://apps.apple.com/us/app/localdevvpn/id6755608044") } } } diff --git a/Ksign/Views/Settings/SettingsView.swift b/Ksign/Views/Settings/SettingsView.swift index 38a295b..8d3af0c 100644 --- a/Ksign/Views/Settings/SettingsView.swift +++ b/Ksign/Views/Settings/SettingsView.swift @@ -48,15 +48,9 @@ struct SettingsView: View { NavigationLink(destination: ArchiveView()) { Label(.localized("Archive & Extraction"), systemImage: "archivebox") } - #if SERVER - NavigationLink(destination: ServerView()) { - Label(.localized("Server & SSL"), systemImage: "server.rack") + NavigationLink(destination: InstallationView()) { + Label(.localized("Installation"), systemImage: "server.rack") } - #elseif IDEVICE - NavigationLink(destination: TunnelView()) { - Label(.localized("Tunnel & Pairing"), systemImage: "network") - } - #endif } _directories()