// HelloFS - Final Correct Version // Based on Apple FSKit v1 (macOS Sequoia 15+) // CRITICAL: FSFileSystem is unavailable, use FSUnaryFileSystem import Foundation import FSKit // MARK: - Entry Point (FSUnaryFileSystem) // Note: FSKit v1 does NOT have separate Extension class // FSUnaryFileSystem is the entry point directly final class HelloFS: FSUnaryFileSystem { required init() { super.init() print("HelloFS initialized") } func probeResource( _ resource: FSResource, replyHandler: @escaping (FSProbeResult?) -> Void ) { print("HelloFS: Probing resource") // Accept any block device let result = FSProbeResult.usable( resource: resource, identifier: FSResourceIdentifier(uuid: UUID()), userInfo: nil ) replyHandler(result) } func loadResource( _ resource: FSResource, options: FSTaskOptions, replyHandler: @escaping (Error?) -> Void ) { print("HelloFS: Loading resource: \(resource)") // For HelloFS, just return success replyHandler(nil) } func unloadResource( _ resource: FSResource, options: FSTaskOptions, replyHandler: @escaping (Error?) -> Void ) { print("HelloFS: Unloading resource") replyHandler(nil) } } // MARK: - Volume (FSVolume with protocols) final class HelloVolume: FSVolume { var rootItem: HelloItem var items: [String: HelloItem] = [:] init(resource: FSResource) { rootItem = HelloItem(name: "/", type: .directory) super.init(resource: resource) // Add sample file let helloFile = HelloItem(name: "hello.txt", type: .file) helloFile.content = "Hello from HelloFS!\n".data(using: .utf8) items["hello.txt"] = helloFile print("HelloVolume initialized") } } // MARK: - Basic Volume Operations extension HelloVolume: FSVolume.PathConfOperations { func pathconf(_ item: FSItem, conf: FSPathConf) throws -> Int32 { return 255 // Basic value } } extension HelloVolume: FSVolume.OpenCloseOperations { func open(_ item: FSItem, options: FSTaskOptions) throws -> FSFileHandle { return FSFileHandle(rawValue: item.identifier.rawValue) } func close(_ handle: FSFileHandle) throws { // Nothing to do } } extension HelloVolume: FSVolume.IOOperations { func read( _ handle: FSFileHandle, buffer: UnsafeMutableRawBufferPointer, options: FSTaskOptions ) throws -> Int { // Find item by handle for item in items.values { if item.identifier.rawValue == handle.rawValue { if let content = item.content { let copyLength = min(buffer.count, content.count) content.withUnsafeBytes { src in buffer.copyBytes(from: UnsafeRawBufferPointer( start: src.baseAddress, count: copyLength )) } return copyLength } } } return 0 } func write( _ handle: FSFileHandle, buffer: UnsafeRawBufferPointer, options: FSTaskOptions ) throws -> Int { for item in items.values { if item.identifier.rawValue == handle.rawValue { item.content = Data(buffer) return buffer.count } } return 0 } } extension HelloVolume: FSVolume.DirectoryOperations { func lookupItem( named name: FSFileName, inDirectory directory: FSItem ) throws -> (FSItem, FSFileName) { if let item = items[name] { return (item, name) } throw NSError(domain: "HelloFS", code: 2, userInfo: nil) } func enumerateDirectory( _ directory: FSItem, startingAt: UInt64, verifier: inout FSItemVerifier, attributes: FSItem.Attributes, packer: FSItemPacker ) throws { for (name, item) in items { try packer.packItem(item, named: name) } } } // MARK: - File Item final class HelloItem: FSItem { let name: String let type: ItemType var content: Data? private static var nextID: UInt64 = 1 init(name: String, type: ItemType) { self.name = name self.type = type let id = HelloItem.nextID HelloItem.nextID += 1 super.init(identifier: FSItem.Identifier(rawValue: id)) } }