// // SMB2FileOperation.swift // ExtDownloader // // Created by Amir Abbas Mousavian on 4/30/95. // Copyright © 1395 Mousavian. All rights reserved. // import Foundation extension SMB2 { // MARK: SMB2 Read struct ReadRequest: SMBRequestBody { static var command: SMB2.Command = .READ let size: UInt16 fileprivate let padding: UInt8 let flags: ReadRequest.Flags let length: UInt32 let offset: UInt64 let fileId: FileId let minimumLength: UInt32 let channel: Channel let remainingBytes: UInt32 fileprivate let channelInfoOffset: UInt16 fileprivate let channelInfoLength: UInt16 fileprivate let channelBuffer: UInt8 init (fileId: FileId, offset: UInt64, length: UInt32, flags: ReadRequest.Flags = [], minimumLength: UInt32 = 0, remainingBytes: UInt32 = 0, channel: Channel = .NONE) { self.size = 49 self.padding = 0 self.flags = flags self.length = length self.offset = offset self.fileId = fileId self.minimumLength = minimumLength self.channel = channel self.remainingBytes = remainingBytes self.channelInfoOffset = 0 self.channelInfoLength = 0 self.channelBuffer = 0 } struct Flags: OptionSet { let rawValue: UInt8 init(rawValue: UInt8) { self.rawValue = rawValue } static let UNBUFFERED = Flags(rawValue: 0x01) } } struct ReadRespone: SMBResponseBody { struct Header { let size: UInt16 let offset: UInt8 fileprivate let reserved: UInt8 let length: UInt32 let remaining: UInt32 fileprivate let reserved2: UInt32 } let header: ReadRespone.Header let buffer: Data init?(data: Data) { guard data.count > 16 else { return nil } self.header = data.scanValue()! let headersize = MemoryLayout
.size self.buffer = data.subdata(in: headersize...size + MemoryLayout.size) channelInfoLength = UInt16(MemoryLayout.size) } let dataOffset = UInt16(MemoryLayout.size + MemoryLayout.size) + channelInfoLength self.header = WriteRequest.Header(size: UInt16(49), dataOffset: dataOffset, length: UInt32(data.count), offset: offset, fileId: fileId, channel: channel, remainingBytes: remainingBytes, channelInfoOffset: channelInfoOffset, channelInfoLength: channelInfoLength, flags: flags) self.channelInfo = channelInfo self.fileData = data } // codebeat:enable[ARITY] func data() -> Data { var result = Data(value: self.header) if let channelInfo = channelInfo { result.append(channelInfo.data()) } result.append(fileData) return result } struct Flags: OptionSet { let rawValue: UInt32 init(rawValue: UInt32) { self.rawValue = rawValue } static let THROUGH = Flags(rawValue: 0x00000001) static let UNBUFFERED = Flags(rawValue: 0x00000002) } } struct WriteResponse: SMBResponseBody { let size: UInt16 fileprivate let reserved: UInt16 let writtenBytes: UInt32 fileprivate let remaining: UInt32 fileprivate let channelInfoOffset: UInt16 fileprivate let channelInfoLength: UInt16 } struct ChannelInfo: SMBRequestBody { static var command: SMB2.Command = .WRITE let offset: UInt64 let token: UInt32 let length: UInt32 } // MARK: SMB2 Lock struct LockElement: SMBRequestBody { static var command: SMB2.Command = .LOCK let offset: UInt64 let length: UInt64 let flags: LockElement.Flags fileprivate let reserved: UInt32 struct Flags: OptionSet { let rawValue: UInt32 init(rawValue: UInt32) { self.rawValue = rawValue } static let SHARED_LOCK = Flags(rawValue: 0x00000001) static let EXCLUSIVE_LOCK = Flags(rawValue: 0x00000002) static let UNLOCK = Flags(rawValue: 0x00000004) static let FAIL_IMMEDIATELY = Flags(rawValue: 0x00000010) } } struct LockRequest: SMBRequestBody { static var command: SMB2.Command = .LOCK let header: LockRequest.Header let locks: [LockElement] init(fileId: FileId,locks: [LockElement], lockSequenceNumber : Int8 = 0, lockSequenceIndex: UInt32 = 0) { self.header = LockRequest.Header(size: 48, lockCount: UInt16(locks.count), lockSequence: UInt32(lockSequenceNumber << 28) + lockSequenceIndex, fileId: fileId) self.locks = locks } func data() -> Data { var result = Data(value: header) for lock in locks { result.append(Data(value: lock)) } return result } struct Header { let size: UInt16 fileprivate let lockCount: UInt16 let lockSequence: UInt32 let fileId : FileId } } struct LockResponse: SMBResponseBody { let size: UInt16 let reserved: UInt16 init() { self.size = 4 self.reserved = 0 } } // MARK: SMB2 Cancel struct CancelRequest: SMBRequestBody { static var command: SMB2.Command = .CANCEL let size: UInt16 let reserved: UInt16 init() { self.size = 4 self.reserved = 0 } } }