diff --git a/Sources/SMBClient.swift b/Sources/SMBClient.swift index bebda8b..fd53bc0 100644 --- a/Sources/SMBClient.swift +++ b/Sources/SMBClient.swift @@ -70,6 +70,7 @@ class SMB2ProtocolClient: FPSStreamTask { }) return mId } + func sendTreeDisconnect(id treeId: UInt32, completionHandler: SimpleCompletionHandler) -> UInt64 { let mId = messageId() let smbHeader = SMB2.Header(command: .TREE_DISCONNECT, creditRequestResponse: 111, messageId: mId, treeId: treeId, sessionId: sessionId) @@ -98,9 +99,10 @@ class SMB2ProtocolClient: FPSStreamTask { } return currentMessageID } - - // MARK: create and analyse messages - +} + +// MARK: create and analyse messages +extension SMB2ProtocolClient { func determineSMBVersion(_ data: Data) -> Float { let smbverChar: Int8 = Int8(bitPattern: data.first ?? 0) let version = 0 - smbverChar @@ -116,7 +118,7 @@ class SMB2ProtocolClient: FPSStreamTask { throw SMBFileProviderError.incompatibleHeader } let headersize = MemoryLayout.size - let header: SMB1.Header = decode(data) + let header: SMB1.Header = data.scanValue()! var blocks = [(params: [UInt16], message: Data?)]() var offset = headersize while offset < data.count { @@ -128,7 +130,7 @@ class SMB2ProtocolClient: FPSStreamTask { offset += MemoryLayout.size var rawParamWords = [UInt8](buffer[offset..<(offset + paramWordsCount * 2)]) let paramData = Data(bytesNoCopy: UnsafeMutablePointer(&rawParamWords), count: rawParamWords.count, deallocator: .free) - paramWords = decode(paramData) + paramWords = paramData.scanValue()! offset += paramWordsCount * 2 let messageBytesCount = Int(UInt16(buffer[0]) + UInt16(buffer[1]) << 8) offset += MemoryLayout.size @@ -154,7 +156,7 @@ class SMB2ProtocolClient: FPSStreamTask { let headerData = data.subdata(in: 0.. Data { - var headerv = header - var result = encode(&headerv) + var result = Data(value: header) for block in blocks { var paramWordsCount = UInt8(block.params?.count ?? 0) result.append(¶mWordsCount, count: MemoryLayout.size(ofValue: paramWordsCount)) @@ -219,8 +220,7 @@ class SMB2ProtocolClient: FPSStreamTask { } func createSMB2Message(header: SMB2.Header, message: SMBRequest) -> Data { - var headerv = header - var result = encode(&headerv) + var result = Data(value: header) result.append(message.data()) return result } diff --git a/Sources/SMBFileProvider.swift b/Sources/SMBFileProvider.swift index fd2f3c0..5992ad5 100644 --- a/Sources/SMBFileProvider.swift +++ b/Sources/SMBFileProvider.swift @@ -8,7 +8,7 @@ import Foundation -open class SMBFileProvider: FileProvider, FileProviderMonitor { +class SMBFileProvider: FileProvider, FileProviderMonitor { open static var type: String = "Samba" open var isPathRelative: Bool = true open var baseURL: URL? diff --git a/Sources/SMBTypes/SMB2DataTypes.swift b/Sources/SMBTypes/SMB2DataTypes.swift index 52a0f9c..c2f4e35 100644 --- a/Sources/SMBTypes/SMB2DataTypes.swift +++ b/Sources/SMBTypes/SMB2DataTypes.swift @@ -12,10 +12,26 @@ protocol SMBRequest { func data() -> Data } +extension SMBRequest { + func data() -> Data { + return Data(value: self) + } +} + protocol SMBResponse { init? (data: Data) } +extension SMBResponse { + init? (data: Data) { + if let v: Self = data.scanValue() { + self = v + } else { + return nil + } + } +} + protocol IOCtlRequestProtocol: SMBRequest {} protocol IOCtlResponseProtocol: SMBResponse {} diff --git a/Sources/SMBTypes/SMB2FileHandle.swift b/Sources/SMBTypes/SMB2FileHandle.swift index eccfbb8..602e68a 100644 --- a/Sources/SMBTypes/SMB2FileHandle.swift +++ b/Sources/SMBTypes/SMB2FileHandle.swift @@ -40,7 +40,7 @@ extension SMB2 { header.contextLength = 0 //result.appendData(nameData) } - var result = encode(&header) + var result = Data(value: header) result.append(body) return result } @@ -186,7 +186,7 @@ extension SMB2 { guard data.count >= MemoryLayout.size else { return nil } - self.header = decode(data) + self.header = data.scanValue()! if self.header.contextsOffset > 0 { var contexts = [CreateContext]() var contextOffset = Int(self.header.contextsOffset) - MemoryLayout.size @@ -195,14 +195,9 @@ extension SMB2 { self.contexts = contexts return } - let contextDataHeader = data.subdata(in: contextOffset..<(contextOffset + MemoryLayout.size)) - if let lastContextHeader = CreateContext(data: contextDataHeader) { - let lastContextLen = Int(lastContextHeader.header.dataOffset) + Int(lastContextHeader.header.dataLength) - contextOffset - let lastContextData = data.subdata(in: contextOffset..<(contextOffset + lastContextLen)) - if let newContext = CreateContext(data: lastContextData) { - contexts.append(newContext) - } - contextOffset = Int(lastContextHeader.header.next) - MemoryLayout.size + while contextOffset > 0, let context: CreateContext = data.scanValue(start: contextOffset) { + contexts.append(context) + contextOffset = Int(context.header.next) - MemoryLayout.size } } self.contexts = contexts @@ -244,12 +239,12 @@ extension SMB2 { guard data.count > headersize else { return nil } - self.header = decode(data) + self.header = data.scanValue()! self.buffer = data.subdata(in: headersize.. Data { - var result = encode(header) + var result = Data(value: header) result.append(buffer) return result } @@ -377,10 +372,6 @@ extension SMB2 { self.flags = [] self.reserved2 = 0 } - - func data() -> Data { - return encode(self) - } } struct CloseResponse: SMBResponse { @@ -394,10 +385,6 @@ extension SMB2 { let allocationSize: UInt64 let endOfFile: UInt64 let fileAttributes: FileAttributes - - init? (data: Data) { - self = decode(data) - } } struct CloseFlags: OptionSet { @@ -426,10 +413,6 @@ extension SMB2 { self.reserved = 0 self.reserved2 = 0 } - - func data() -> Data { - return encode(self) - } } struct FlushResponse: SMBResponse { @@ -440,9 +423,5 @@ extension SMB2 { self.size = 4 self.reserved = 0 } - - init? (data: Data) { - self = decode(data) - } } } diff --git a/Sources/SMBTypes/SMB2FileOperation.swift b/Sources/SMBTypes/SMB2FileOperation.swift index 7289e23..87615ff 100644 --- a/Sources/SMBTypes/SMB2FileOperation.swift +++ b/Sources/SMBTypes/SMB2FileOperation.swift @@ -43,10 +43,6 @@ extension SMB2 { self.channelBuffer = 0 } - func data() -> Data { - return encode(read) - } - struct Flags: OptionSet { let rawValue: UInt8 @@ -75,7 +71,7 @@ extension SMB2 { guard data.count > 16 else { return nil } - self.header = decode(data) + self.header = data.scanValue()! let headersize = MemoryLayout
.size self.buffer = data.subdata(in: headersize.. Data { - var result = encode(self.header) + var result = Data(value: self.header) if let channelInfo = channelInfo { result.append(channelInfo.data()) } @@ -151,20 +147,12 @@ extension SMB2 { fileprivate let remaining: UInt32 fileprivate let channelInfoOffset: UInt16 fileprivate let channelInfoLength: UInt16 - - init?(data: Data) { - self = decode(data) - } } struct ChannelInfo: SMBRequest { let offset: UInt64 let token: UInt32 let length: UInt32 - - func data() -> Data { - return encode(data) - } } // MARK: SMB2 Lock @@ -175,10 +163,6 @@ extension SMB2 { let flags: LockElement.Flags fileprivate let reserved: UInt32 - func data() -> Data { - return encode(self) - } - struct Flags: OptionSet { let rawValue: UInt32 @@ -203,9 +187,9 @@ extension SMB2 { } func data() -> Data { - var result = encode(header) + var result = Data(value: header) for lock in locks { - result.append(encode(lock)) + result.append(Data(value: lock)) } return result } @@ -226,10 +210,6 @@ extension SMB2 { self.size = 4 self.reserved = 0 } - - init? (data: Data) { - self = decode(data) - } } // MARK: SMB2 Cancel @@ -242,9 +222,5 @@ extension SMB2 { self.size = 4 self.reserved = 0 } - - func data() -> Data { - return encode(self) - } } } diff --git a/Sources/SMBTypes/SMB2IOCtl.swift b/Sources/SMBTypes/SMB2IOCtl.swift index 063b484..9fbdd40 100644 --- a/Sources/SMBTypes/SMB2IOCtl.swift +++ b/Sources/SMBTypes/SMB2IOCtl.swift @@ -26,7 +26,7 @@ extension SMB2 { } func data() -> Data { - var result = encode(self.header) + var result = Data(value: self.header) if let reqData = requestData?.data() { result.append(reqData) } @@ -68,7 +68,7 @@ extension SMB2 { let responseData: IOCtlResponseProtocol? init?(data: Data) { - self.header = decode(data) + self.header = data.scanValue()! let endRange = Int(self.header.outputOffset - 64) + Int(self.header.outputCount) let response = data.subdata(in: Int(self.header.outputOffset - 64).. Data { - var result = encode(sourceKey) - result.append(encode(chunkCount)) - var reserved: UInt32 = 0 - result.append(encode(&reserved)) + var result = Data(value: sourceKey) + result.append(Data(value: chunkCount)) + let reserved: UInt32 = 0 + result.append(Data(value: reserved)) return Data() } @@ -152,10 +152,6 @@ extension SMB2 { let targetOffset: UInt64 let length: UInt32 fileprivate let reserved: UInt32 - - func data() -> Data { - return encode(self) - } } } @@ -182,10 +178,6 @@ extension SMB2 { self.length = length self.offset = offset } - - func data() -> Data { - return encode(self) - } } struct ResilencyRequest: IOCtlRequestProtocol { @@ -197,10 +189,6 @@ extension SMB2 { self.timeout = timeout self.reserved = 0 } - - func data() -> Data { - return encode(self) - } } struct ValidateNegotiateInfo: IOCtlRequestProtocol { @@ -213,8 +201,8 @@ extension SMB2 { } func data() -> Data { - var result = encode(self.header) - dialects.forEach { result.append(encode($0)) } + var result = Data(value: self.header) + dialects.forEach { result.append(Data(value: $0)) } return result } @@ -234,10 +222,6 @@ extension SMB2 { let chunksCount: UInt32 let chunksBytesWritten: UInt32 let totalBytesWriiten: UInt32 - - init?(data: Data) { - self = decode(data) - } } // SRV_ENUMERATE_SNAPSHOTS @@ -247,8 +231,9 @@ extension SMB2 { let snapshots: [SMBTime] init?(data: Data) { - self.count = decode(data) - self.returnedCount = decode(data.subdata(in: 4..<8)) + guard data.count > 8 else { return nil } + self.count = data.scanValue()! + self.returnedCount = data.scanValue(start: 4)! //let size: UInt32 = decode(data.subdataWithRange(NSRange(location: 8, length: 4))) var snapshots = [SMBTime]() let dateFormatter = DateFormatter() @@ -258,7 +243,7 @@ extension SMB2 { if data.count < offset + 48 { return nil } - let datestring = String(data: data.subdata(in: offset..<(offset + 48)), encoding: .utf16) + let datestring = data.scanString(start: offset, length: 48, encoding: .utf16) if let datestring = datestring, let date = dateFormatter.date(from: datestring) { snapshots.append(SMBTime(date: date)) } @@ -271,32 +256,21 @@ extension SMB2 { let key: (UInt64, UInt64, UInt64) fileprivate let contextLength: UInt32 fileprivate let context: UInt32 - - init?(data: Data) { - self = decode(data) - } } struct ReadHash: IOCtlResponseProtocol { // TODO: Implement IOCTL READ_HASH - - init?(data: Data) { - self = decode(data) - } } struct NetworkInterfaceInfo: IOCtlResponseProtocol { let items: [NetworkInterfaceInfo.Item] init?(data: Data) { - let count = data.count / MemoryLayout.size - guard count > 0 else { - return nil - } var items = [Item]() - for i in 0...size)..<((i + 1) * MemoryLayout.size)) - items.append(decode(itemdata)) + var offset = 0 + while let item: Item = data.scanValue(start: offset) { + items.append(item) + offset += MemoryLayout.size } self.items = items } @@ -335,15 +309,11 @@ extension SMB2 { static let ipv6: sa_family_t = 0x17 var sockaddr: sockaddr_in { - var sockaddrStorage = self.sockaddrStorage - let data = Data(bytes: &sockaddrStorage, count: 16) - return decode(data) + return Data.mapMemory(from: self.sockaddrStorage)! } var sockaddr6: sockaddr_in6 { - var sockaddrStorage = self.sockaddrStorage - let data = Data(bytes: &sockaddrStorage, count: 28) - return decode(data) + return Data.mapMemory(from: self.sockaddrStorage)! } } } @@ -356,10 +326,6 @@ extension SMB2 { var dialect: (major: Int, minor: Int) { return (major: Int(_dialect & 0xFF), minor: Int(_dialect >> 8)) } - - init?(data: Data) { - self = decode(data) - } } } diff --git a/Sources/SMBTypes/SMB2Notification.swift b/Sources/SMBTypes/SMB2Notification.swift index ee8f3e5..9996aae 100644 --- a/Sources/SMBTypes/SMB2Notification.swift +++ b/Sources/SMBTypes/SMB2Notification.swift @@ -28,10 +28,6 @@ extension SMB2 { self.reserved = 0 } - func data() -> Data { - return encode(self) - } - struct Flags: OptionSet { let rawValue: UInt16 @@ -89,19 +85,14 @@ extension SMB2 { var offset = 0 while i < maxLoop { - let nextOffsetData = data.subdata(in: offset..<(offset + 4)) - let nextOffset: UInt32 = decode(nextOffsetData) - - let actionData = data.subdata(in: (offset + 4)..<(offset + 8)) - let actionValue: UInt32 = decode(actionData) + let nextOffset: UInt32 = data.scanValue(start: offset) ?? 0 + let actionValue: UInt32 = data.scanValue(start: offset + 4) ?? 0 guard let action = FileNotifyAction(rawValue: actionValue) else { continue } - let fileLenData = data.subdata(in: (offset + 8)..<(offset + 12)) - let fileNameLen = Int(decode(fileLenData) as UInt32) - let fileNameData = data.subdata(in: (offset + 12)..<(offset + 12 + fileNameLen)) - let fileName = String(data: fileNameData, encoding: .utf16) ?? "" + let fileNameLen = Int(data.scanValue(start: offset + 8) as UInt32? ?? 0) + let fileName = data.scanString(start: offset + 12, length: fileNameLen, encoding: .utf16) ?? "" result.append((action: action, fileName: fileName)) offset += Int(nextOffset) diff --git a/Sources/SMBTypes/SMB2Query.swift b/Sources/SMBTypes/SMB2Query.swift index 7c9b25f..3efaf6f 100644 --- a/Sources/SMBTypes/SMB2Query.swift +++ b/Sources/SMBTypes/SMB2Query.swift @@ -28,7 +28,7 @@ extension SMB2 { } func data() -> Data { - var result = encode(header) + var result = Data(value: header) if let patternData = searchPattern?.data(using: .utf16) { result.append(patternData) } @@ -68,43 +68,24 @@ extension SMB2 { var result = [(header: SMB2FilesInformationHeader, fileName: String)]() while true { let header: SMB2FilesInformationHeader - let headersize: Int switch type { case .fileDirectoryInformation: - headersize = MemoryLayout.size - let headerData = buffer.subdata(in: offset..<(offset + headersize)) - let h: FileDirectoryInformationHeader = decode(headerData) - header = h + header = buffer.scanValue(start: offset) as FileDirectoryInformationHeader! case .fileFullDirectoryInformation: - headersize = MemoryLayout.size - let headerData = buffer.subdata(in: offset..<(offset + headersize)) - let h: FileFullDirectoryInformationHeader = decode(headerData) - header = h + header = buffer.scanValue(start: offset) as FileFullDirectoryInformationHeader! case .fileIdFullDirectoryInformation: - headersize = MemoryLayout.size - let headerData = buffer.subdata(in: offset..<(offset + headersize)) - let h: FileIdFullDirectoryInformationHeader = decode(headerData) - header = h + header = buffer.scanValue(start: offset) as FileIdFullDirectoryInformationHeader! case .fileBothDirectoryInformation: - headersize = MemoryLayout.size - let headerData = buffer.subdata(in: offset..<(offset + headersize)) - let h: FileBothDirectoryInformationHeader = decode(headerData) - header = h + header = buffer.scanValue(start: offset) as FileBothDirectoryInformationHeader! case .fileIdBothDirectoryInformation: - headersize = MemoryLayout.size - let headerData = buffer.subdata(in: offset..<(offset + headersize)) - let h: FileIdBothDirectoryInformationHeader = decode(headerData) - header = h + header = buffer.scanValue(start: offset) as FileIdBothDirectoryInformationHeader! case .fileNamesInformation: - headersize = MemoryLayout.size - let headerData = buffer.subdata(in: offset..<(offset + headersize)) - let h: FileNamesInformationHeader = decode(headerData) - header = h + header = buffer.scanValue(start: offset) as FileNamesInformationHeader! default: return [] } - let fnData = buffer.subdata(in: (offset + headersize)..<(offset + headersize + Int(header.fileNameLength))) - let fileName = String(data: fnData, encoding: .utf16) ?? "" + let headersize = MemoryLayout.size(ofValue: header) + let fileName = buffer.scanString(start: headersize, length: Int(header.fileNameLength), encoding: .utf16) ?? "" result.append((header: header, fileName: fileName)) if header.nextEntryOffset == 0 { break @@ -115,8 +96,8 @@ extension SMB2 { } init? (data: Data) { - let offset = Int(decode(data.subdata(in: 2..<4)) as UInt16) - let length = Int(decode(data.subdata(in: 4..<8)) as UInt32) + let offset = Int(data.scanValue(start: 2) as UInt16!) + let length = Int(data.scanValue(start: 4) as UInt32!) guard data.count > offset + length else { return nil } @@ -143,8 +124,8 @@ extension SMB2 { } let strLength = UInt8(strData.count) let nextOffset = UInt32(4 + 1 + strData.count) - var data = encode(nextOffset) - data.append(encode(strLength)) + var data = Data(value: nextOffset) + data.append(Data(value: strLength)) data.append(strData) data.count += 1 let padSize = (data.count) % 4 @@ -170,8 +151,7 @@ extension SMB2 { // TODO: Implement QUOTA_INFO init func data() -> Data { - let headerData = encode(header) - var result = headerData + var result = Data(value: header) if let buffer = buffer { result.append(buffer) } @@ -208,8 +188,7 @@ extension SMB2 { let buffer: Data init?(data: Data) { - let structSizeData = data.subdata(in: 0..<2) - let structSize: UInt16 = decode(structSizeData) + let structSize: UInt16 = data.scanValue()! guard structSize == 9 else { return nil } @@ -217,10 +196,9 @@ extension SMB2 { /*let offsetData = data.subdataWithRange(NSRange(location: 2, length: 2)) let offset: UInt16 = decode(offsetData)*/ - let lengthData = data.subdata(in: 4..<8) - let length = Int(decode(lengthData) as UInt32) + let length = Int(data.scanValue(start: 4) as UInt32!) - guard data.count >= 8 + Int(length) else { + guard data.count >= 8 + length else { return nil } @@ -228,40 +206,38 @@ extension SMB2 { } var asAccessInformation: FileAccessInformation { - return decode(buffer) + return buffer.scanValue()! } var asAlignmentInformation: FileAlignmentInformation { - return decode(buffer) + return buffer.scanValue()! } var asAllInformation: (header: FileAllInformationHeader, name: String) { - let header: FileAllInformationHeader = decode(buffer) + let header: FileAllInformationHeader = buffer.scanValue()! let headersize = MemoryLayout.size - let nameData = buffer.subdata(in: headersize..<(headersize + Int(header.nameLength))) - let name = String(data: nameData, encoding: .utf16) ?? "" + let name = buffer.scanString(start: headersize, length: Int(header.nameLength), encoding: .utf16) ?? "" return (header, name) } var asAlternateNameInformation: String { - let b = (buffer as NSData).bytes.bindMemory(to: CChar.self, capacity: buffer.count) - return String(cString: b, encoding: .utf16) ?? "" + return buffer.scanString(start: 0, length: buffer.count, encoding: .utf16) ?? "" } var asAttributeTagInformation: FileAttributeTagInformation { - return decode(buffer) + return buffer.scanValue()! } var asBasicInformation: FileBasicInformation { - return decode(buffer) + return buffer.scanValue()! } var asCompressionInformation: FileCompressionInformation { - return decode(buffer) + return buffer.scanValue()! } var asEaInformation: FileEaInformation { - return decode(buffer) + return buffer.scanValue()! } var asFullEaInformation: FileFullEaInformation { @@ -270,83 +246,80 @@ extension SMB2 { } var asInternalInformation: FileInternalInformation { - return decode(buffer) + return buffer.scanValue()! } var asModeInformation: FileModeInformation { - return decode(buffer) + return buffer.scanValue()! } var asNetworkOpenInformation: FileNetworkOpenInformation { - return decode(buffer) + return buffer.scanValue()! } var asPipeInformation: FilePipeInformation { - return decode(buffer) + return buffer.scanValue()! } var asPipeLocalInformation: FilePipeLocalInformation { - return decode(buffer) + return buffer.scanValue()! } var asPipeRemoteInformation: FilePipeRemoteInformation { - return decode(buffer) + return buffer.scanValue()! } var asPositionInformation: FilePositionInformation { - return decode(buffer) + return buffer.scanValue()! } var asStandardInformation: FileStandardInformation { - return decode(buffer) + return buffer.scanValue()! } var asStreamInformation: (header: FileStreamInformationHeader, name: String) { - let header: FileStreamInformationHeader = decode(buffer) + let header: FileStreamInformationHeader = buffer.scanValue()! let headersize = MemoryLayout.size - let nameData = buffer.subdata(in: headersize..<(headersize + Int(header.streamNameLength))) - let name = String(data: nameData, encoding: .utf16) ?? "" + let name = buffer.scanString(start: headersize, length: Int(header.streamNameLength), encoding: .utf16) ?? "" return (header, name) } var asFsVolumeInformation: (header: FileFsVolumeInformationHeader, name: String) { - let header: FileFsVolumeInformationHeader = decode(buffer) + let header: FileFsVolumeInformationHeader = buffer.scanValue()! let headersize = MemoryLayout.size - let nameData = buffer.subdata(in: headersize..<(headersize + Int(header.labelLength))) - let name = String(data: nameData, encoding: .utf16) ?? "" + let name = buffer.scanString(start: headersize, length: Int(header.labelLength), encoding: .utf16) ?? "" return (header, name) } var asFsSizeInformation: FileFsSizeInformation { - return decode(buffer) + return buffer.scanValue()! } var asFsDeviceInformation: FileFsDeviceInformation { - return decode(buffer) + return buffer.scanValue()! } var asFsAttributeInformation: (header: FileFsAttributeInformationHeader, name: String) { - let header: FileFsAttributeInformationHeader = decode(buffer) + let header: FileFsAttributeInformationHeader = buffer.scanValue()! let headersize = MemoryLayout.size - let nameData = buffer.subdata(in: headersize..<(headersize + Int(header.nameLength))) - let name = String(data: nameData, encoding: .utf16) ?? "" + let name = buffer.scanString(start: headersize, length: Int(header.nameLength), encoding: .utf16) ?? "" return (header, name) } var asFsControlInformation: FileFsControlInformation { - return decode(buffer) + return buffer.scanValue()! } var asFsFullSizeInformation: FileFsFullSizeInformation { - return decode(buffer) + return buffer.scanValue()! } var asFsObjectIdInformation: FileFsObjectIdInformation { - return decode(buffer) + return buffer.scanValue()! } var asFsSectorSizeInformation: FileFsSectorSizeInformation { - return decode(buffer) + return buffer.scanValue()! } } } diff --git a/Sources/SMBTypes/SMB2QueryTypes.swift b/Sources/SMBTypes/SMB2QueryTypes.swift index 4ff3267..e7cd137 100644 --- a/Sources/SMBTypes/SMB2QueryTypes.swift +++ b/Sources/SMBTypes/SMB2QueryTypes.swift @@ -127,10 +127,6 @@ extension SMB2 { let allocationSize: UInt64 let fileAttributes: FileAttributes let fileNameLength : UInt32 - - init?(data: Data) { - self = decode(data) - } } struct FileFullDirectoryInformationHeader: SMB2FilesInformationHeader { @@ -145,10 +141,6 @@ extension SMB2 { let fileAttributes: FileAttributes let fileNameLength : UInt32 let extendedAttributesSize: UInt32 - - init?(data: Data) { - self = decode(data) - } } struct FileIdFullDirectoryInformationHeader: SMB2FilesInformationHeader { @@ -165,10 +157,6 @@ extension SMB2 { let extendedAttributesSize: UInt32 fileprivate let reserved: UInt32 let fileId: FileId - - init?(data: Data) { - self = decode(data) - } } struct FileBothDirectoryInformationHeader: SMB2FilesInformationHeader { @@ -187,14 +175,9 @@ extension SMB2 { fileprivate let reserved: UInt8 fileprivate let _shortName: FileShortNameType var shortName: String? { - let s = encode(_shortName) - var d = s - d.count = Int(shortNameLen) - return String(data: d, encoding: .utf16) - } - - init?(data: Data) { - self = decode(data) + var data = Data(value: _shortName) + data.count = Int(shortNameLen) + return String(data: data, encoding: .utf16) } } @@ -214,27 +197,18 @@ extension SMB2 { fileprivate let reserved: UInt8 fileprivate let _shortName: FileShortNameType var shortName: String? { - let s = encode(_shortName) - var d = s - d.count = Int(shortNameLen) - return String(data: d, encoding: .utf16) + var data = Data(value: _shortName) + data.count = Int(shortNameLen) + return String(data: data, encoding: .utf16) } fileprivate let reserved2: UInt16 let fileId : FileId - - init?(data: Data) { - self = decode(data) - } } struct FileNamesInformationHeader: SMB2FilesInformationHeader { let nextEntryOffset: UInt32 let fileIndex: UInt32 let fileNameLength : UInt32 - - init?(data: Data) { - self = decode(data) - } } typealias FileShortNameType = (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, diff --git a/Sources/SMBTypes/SMB2Session.swift b/Sources/SMBTypes/SMB2Session.swift index 7ab5aea..f2fe922 100644 --- a/Sources/SMBTypes/SMB2Session.swift +++ b/Sources/SMBTypes/SMB2Session.swift @@ -43,13 +43,11 @@ extension SMB2 { var contextData = Data() for context in contexts { - var contextType = context.type.rawValue - contextData.append(UnsafeBufferPointer(start: &contextType, count: 2)) - var dataLen = UInt16(context.data.count) + contextData.append(Data(value: context.type.rawValue)) contextData.count += 4 - contextData.append(UnsafeBufferPointer(start: &dataLen, count: 2)) + contextData.append(Data(value: UInt16(context.data.count))) } - var result = encode(&header) + var result = Data(value: header) result.append(dialectData as Data) result.append(contextData as Data) return result @@ -97,10 +95,10 @@ extension SMB2 { let contexts: [(type: NegotiateContextType, data: Data)] init? (data: Data) { - if data.count < 64 { + guard data.count >= 64 else { return nil } - self.header = decode(data) + self.header = data.scanValue()! if Int(header.size) != 65 { return nil } @@ -194,7 +192,7 @@ extension SMB2 { var header = self.header header.bufferOffset = UInt16(MemoryLayout.size + MemoryLayout.size) header.bufferLength = UInt16(buffer?.count ?? 0) - var result = encode(&header) + var result = Data(value: header) if let buffer = self.buffer { result.append(buffer) } @@ -240,10 +238,10 @@ extension SMB2 { let buffer: Data? init? (data: Data) { - if data.count < 64 { + guard data.count >= 64 else { return nil } - self.header = decode(data) + self.header = data.scanValue()! if Int(header.size) != 9 { return nil } @@ -297,14 +295,6 @@ extension SMB2 { self.size = 4 self.reserved = 0 } - - init? (data: Data) { - self = decode(data) - } - - func data() -> Data { - return encode(self) - } } // MARK: SMB2 Echo @@ -317,13 +307,5 @@ extension SMB2 { self.size = 4 self.reserved = 0 } - - init? (data: Data) { - self = decode(data) - } - - func data() -> Data { - return encode(self) - } } } diff --git a/Sources/SMBTypes/SMB2SetInfo.swift b/Sources/SMBTypes/SMB2SetInfo.swift index eed1395..6232b44 100644 --- a/Sources/SMBTypes/SMB2SetInfo.swift +++ b/Sources/SMBTypes/SMB2SetInfo.swift @@ -14,10 +14,10 @@ extension SMB2 { let header: Header let buffer: Data? - - func data() -> Data { - return Data() + var result = Data(value: header) + result.append(buffer ?? Data()) + return result } struct Header { @@ -38,9 +38,5 @@ extension SMB2 { init() { self.size = 2 } - - init? (data: Data) { - self = decode(data) - } } } diff --git a/Sources/SMBTypes/SMB2Tree.swift b/Sources/SMBTypes/SMB2Tree.swift index c666d96..147db53 100644 --- a/Sources/SMBTypes/SMB2Tree.swift +++ b/Sources/SMBTypes/SMB2Tree.swift @@ -34,7 +34,7 @@ extension SMB2 { var header = self.header header.pathOffset = UInt16(MemoryLayout.size + MemoryLayout.size) header.pathLength = UInt16(buffer?.count ?? 0) - var result = encode(&header) + var result = Data(value: header) if let buffer = self.buffer { result.append(buffer) } @@ -77,13 +77,6 @@ extension SMB2 { let capabilities: TreeConnectResponse.Capabilities let maximalAccess: FileAccessMask - init? (data: Data) { - if data.count != 16 { - return nil - } - self = decode(data) - } - enum ShareType: UInt8 { case UNKNOWN = 0x00 case DISK = 0x01 @@ -139,13 +132,5 @@ extension SMB2 { self.size = 4 self.reserved = 0 } - - init? (data: Data) { - self = decode(data) - } - - func data() -> Data { - return encode(self) - } } } diff --git a/Sources/SMBTypes/SMB2Types.swift b/Sources/SMBTypes/SMB2Types.swift index 185cac8..944f652 100644 --- a/Sources/SMBTypes/SMB2Types.swift +++ b/Sources/SMBTypes/SMB2Types.swift @@ -8,22 +8,33 @@ import Foundation -internal func encode(_ value: inout T) -> Data { - return withUnsafePointer(to: &value) { p in - Data(bytes: p, count: MemoryLayout.size(ofValue: value)) +extension Data { + init(value: T) { + var value = value + self = Data(buffer: UnsafeBufferPointer(start: &value, count: MemoryLayout.size(ofValue: value))) } -} - -internal func encode(_ value: T) -> Data { - var value = value - return encode(&value) -} - -internal func decode(_ data: Data) -> T { - let pointer = UnsafeMutablePointer.allocate(capacity: MemoryLayout.size) - (data as NSData).getBytes(pointer, length: MemoryLayout.size) - return pointer.move() + func scanValue() -> T? { + guard MemoryLayout.size <= self.count else { return nil } + return self.withUnsafeBytes { $0.pointee } + } + + func scanValue(start: Int) -> T? { + let length = MemoryLayout.size + guard self.count >= start + length else { return nil } + return self.subdata(in: start.. String? { + guard self.count >= start + length else { return nil } + return String(data: self.subdata(in: start..(from: T) -> U? { + guard MemoryLayout.size >= MemoryLayout.size else { return nil } + let data = Data(value: from) + return data.scanValue() + } } protocol FileProviderSMBHeader { diff --git a/Sources/SMBTypes/SMBErrorType.swift b/Sources/SMBTypes/SMBErrorType.swift index e7e139b..a5fe645 100644 --- a/Sources/SMBTypes/SMBErrorType.swift +++ b/Sources/SMBTypes/SMBErrorType.swift @@ -10,7 +10,7 @@ import Foundation /// Error Types and Description -public enum NTStatus: UInt32, Error, CustomStringConvertible { +enum NTStatus: UInt32, Error, CustomStringConvertible { case SUCCESS = 0x00000000 case NOT_IMPLEMENTED = 0xC0000002 case INVALID_DEVICE_REQUEST = 0xC0000010