Files
Amir Abbas 9cc9a6a96a Improving documentation
- Renaming OneDriveProvider.SubAddress to Route
- Refactors to improve codebeat score
2017-10-10 11:07:28 +03:30

222 lines
9.2 KiB
Swift

//
// CIFSTypes.swift
// ExtDownloader
//
// Created by Amir Abbas Mousavian on 4/30/95.
// Copyright © 1395 Mousavian. All rights reserved.
//
import Foundation
// codebeat:disable[TOO_MANY_IVARS]
// SMB/CIFS Types
struct SMB1 {
struct Header { // 32 bytes
// header is always \u{ff}SMB
let protocolID: UInt32
static let protocolConst: UInt32 = 0x424d53ff
fileprivate var _command: UInt8
var command: Command {
get {
return Command(rawValue: _command) ?? .INVALID
}
set {
_command = newValue.rawValue
}
}
// error messages from the server to the client
fileprivate var _status: (UInt8, UInt8, UInt8, UInt8)
var error: (Class: UInt8, code: UInt16) {
get {
return (_status.0, UInt16(_status.2) + (UInt16(_status.3) << 8))
}
set {
_status = (newValue.Class, 0, UInt8(newValue.code & 0xff), UInt8(newValue.code >> 8))
}
}
var ntStatus: UInt32 {
get {
let statusLo = UInt32(_status.0) + UInt32(_status.1) << 8
let statusHi = UInt32(_status.2) + UInt32(_status.3) << 8
return statusHi << 16 + statusLo
}
set {
_status = (UInt8(newValue & 0xff), UInt8(newValue >> 8 & 0xff), UInt8(newValue >> 16 & 0xff), UInt8(newValue >> 24 & 0xff))
}
}
var flags: Flags
var flags2: Flags2
var pidHigh: UInt16
// encryption key used for validating messages over connectionless transports
fileprivate var _securityKey: (UInt16, UInt16)
var securityKey: UInt32 {
get {
return UInt32(_securityKey.1) << 16 + UInt32(_securityKey.0)
}
set {
_securityKey = (UInt16(newValue & 0xffff), UInt16(newValue >> 16))
}
}
/// Connection identifier
var securityCID: UInt16
/// Identifier of the sequence of a message over connectionless transports
var securitySequenceNumber: UInt16
fileprivate var ununsed: UInt16
var treeId: UInt16
var pidLow: UInt16
var userId: UInt16
var multiplexId: UInt16
var pid: UInt32 {
get {
return UInt32(pidLow) + UInt32(pidHigh) << 16
}
set {
pidLow = UInt16(newValue & 0xffff)
pidHigh = UInt16(newValue >> 16)
}
}
// codebeat:disable[ARITY]
init(command: Command, treeId: UInt16, pid: UInt32, userId: UInt16, multiplexId: UInt16, flags: Flags, flags2: Flags2 = [.LONG_NAMES, .ERR_STATUS, .UNICODE], ntStatus: UInt32 = 0, securityKey: UInt32 = 0, securityCID: UInt16 = 0, securitySequenceNumber: UInt16 = 0) {
self.protocolID = Header.protocolConst
self._command = command.rawValue
_status = (UInt8(ntStatus & 0xff), UInt8(ntStatus >> 8 & 0xff), UInt8(ntStatus >> 16 & 0xff), UInt8(ntStatus >> 24 & 0xff))
self.flags = flags
self.flags2 = flags2
self._securityKey = (UInt16(securityKey & 0xffff), UInt16(securityKey >> 16))
self.securityCID = securityCID
self.securitySequenceNumber = securitySequenceNumber
self.ununsed = 0
self.treeId = treeId
self.pidLow = UInt16(pid & 0xffff)
self.pidHigh = UInt16(pid >> 16)
self.userId = userId
self.multiplexId = multiplexId
}
// codebeat:enable[ARITY]
}
struct Flags: OptionSet {
let rawValue: UInt8
init(rawValue: UInt8) {
self.rawValue = rawValue
}
/** This bit is set (1) in the NEGOTIATE (0x72) Response if the server supports
* LOCK_AND_READ (0x13) and WRITE_AND_UNLOCK (0x14) commands. */
static let LOCK_AND_READ_OK = Flags(rawValue: 0x01)
static let BUF_AVAIL = Flags(rawValue: 0x02)
static let CASE_INSENSITIVE = Flags(rawValue: 0x08)
static let CANONICALIZED_PATHS = Flags(rawValue: 0x10)
static let OPLOCK = Flags(rawValue: 0x20)
static let OPBATCH = Flags(rawValue: 0x40)
/** When on, this message is being sent from the server in response to a client request. */
static let REPLY = Flags(rawValue: 0x80)
}
struct Flags2: OptionSet {
let rawValue: UInt16
init(rawValue: UInt16) {
self.rawValue = rawValue
}
/** Client: the message MAY contain long file names. */
static let LONG_NAMES = Flags2(rawValue: 0x0001)
/** Client: the client is aware of extended attributes (EAs). */
static let EAS = Flags2(rawValue: 0x0002)
/** Client: the client is requesting signing (if signing is not yet active) or the message
* being sent is signed. This bit is used on the SMB header of an SESSION_SETUP_ANDX */
static let SMB_SECURITY_SIGNATURE = Flags2(rawValue: 0x0004)
/// Reserved but not implemented.
static let IS_LONG_NAME = Flags2(rawValue: 0x0040)
/** client aware of Extended Security negotiation */
static let EXT_SEC = Flags2(rawValue: 0x0800)
/** any pathnames in this SMB SHOULD be resolved in the Distributed File System (DFS) */
static let DFS = Flags2(rawValue: 0x1000)
/**
* This flag is useful only on a read request. If the bit is set, then the client MAY read
* the file if the client does not have read permission but does have execute permission. */
static let PAGING_IO = Flags2(rawValue: 0x2000) // READ_IF_EXECUTE
/**
* Client: the server MUST return errors as 32-bit NTSTATUS codes in the response
* Server: the Status field in the header is formatted as an NTSTATUS cod */
static let ERR_STATUS = Flags2(rawValue: 0x4000)
/**
* Each field that contains a string in this SMB message MUST be encoded
* as an array of 16-bit Unicode characters */
static let UNICODE = Flags2(rawValue: 0x8000)
}
enum Command: UInt8 {
case CREATE_DIRECTORY = 0x00
case DELETE_DIRECTORY = 0x01
case OPEN = 0x02
case CREATE = 0x03
case CLOSE = 0x04
case FLUSH = 0x05
case DELETE = 0x06
case RENAME = 0x07
case QUERY_INFORMATION = 0x08
case SET_INFORMATION = 0x09
case READ = 0x0A
case WRITE = 0x0B
case LOCK_BYTE_RANGE = 0x0C
case UNLOCK_BYTE_RANGE = 0x0D
case CREATE_TEMPORARY = 0x0E
case CREATE_NEW = 0x0F
case CHECK_DIRECTORY = 0x10
case PROCESS_EXIT = 0x11
case SEEK = 0x12
case LOCK_AND_READ = 0x13
case WRITE_AND_UNLOCK = 0x14
case READ_RAW = 0x1A
case READ_MPX = 0x1B
case READ_MPX_SECONDARY = 0x1C
case WRITE_RAW = 0x1D
case WRITE_MPX = 0x1E
case WRITE_COMPLETE = 0x20
case SET_INFORMATION2 = 0x22
case QUERY_INFORMATION2 = 0x23
case LOCKING_ANDX = 0x24
case TRANSACTION = 0x25
case TRANSACTION_SECONDARY = 0x26
case IOCTL = 0x27
case IOCTL_SECONDARY = 0x28
case COPY = 0x29
case MOVE = 0x2A
case ECHO = 0x2B
case WRITE_AND_CLOSE = 0x2C
case OPEN_ANDX = 0x2D
case READ_ANDX = 0x2E
case WRITE_ANDX = 0x2F
case CLOSE_AND_TREE_DISC = 0x31
case TRANSACTION2 = 0x32
case TRANSACTION2_SECONDARY = 0x33
case FIND_CLOSE2 = 0x34
case FIND_NOTIFY_CLOSE = 0x35
case TREE_CONNECT = 0x70
case TREE_DISCONNECT = 0x71
case NEGOTIATE = 0x72
case SESSION_SETUP_ANDX = 0x73
case LOGOFF_ANDX = 0x74
case TREE_CONNECT_ANDX = 0x75
case QUERY_INFORMATION_DISK = 0x80
case SEARCH = 0x81
case FIND = 0x82
case FIND_UNIQUE = 0x83
case NT_TRANSACT = 0xA0
case NT_TRANSACT_SECONDARY = 0xA1
case NT_CREATE_ANDX = 0xA2
case NT_CANCEL = 0xA4
case OPEN_PRINT_FILE = 0xC0
case WRITE_PRINT_FILE = 0xC1
case CLOSE_PRINT_FILE = 0xC2
case GET_PRINT_QUEUE = 0xC3
case READ_BULK = 0xD8
case WRITE_BULK = 0xD9
case WRITE_BULK_DATA = 0xDA
case INVALID = 0xFE
}
}
// codebeat:enable[TOO_MANY_IVARS]