From 8eee1b47a22330598b80ebb5171e672cdf4c7e51 Mon Sep 17 00:00:00 2001 From: Kishikawa Katsumi Date: Tue, 23 Jul 2024 04:29:24 +0900 Subject: [PATCH] Fix share type conversion --- Sources/SMBClient/DCERPC.swift | 17 +++--- Sources/SMBClient/SMBClient.swift | 63 +++++++++++++++++++---- Sources/SMBClient/Session.swift | 30 ++++------- Tests/SMBClientTests/SMBClientTests.swift | 12 ++--- 4 files changed, 80 insertions(+), 42 deletions(-) diff --git a/Sources/SMBClient/DCERPC.swift b/Sources/SMBClient/DCERPC.swift index 17ab8fe..e90c1e9 100644 --- a/Sources/SMBClient/DCERPC.swift +++ b/Sources/SMBClient/DCERPC.swift @@ -559,13 +559,16 @@ enum DCERPC { let type: UInt32 let comment: WStr - enum ShareType: UInt32 { - case diskTree = 0x00000000 - case printQueue = 0x00000001 - case device = 0x00000002 - case IPC = 0x00000003 - case special = 0x80000000 - case temporary = 0x40000000 + enum ShareType { + static let diskTree: UInt32 = 0x00000000 + static let printQueue: UInt32 = 0x00000001 + static let device: UInt32 = 0x00000002 + static let ipc: UInt32 = 0x00000003 + static let clusterFS: UInt32 = 0x02000000 + static let clusterSOFS: UInt32 = 0x04000000 + static let clusterDFS: UInt32 = 0x08000000 + static let special: UInt32 = 0x80000000 + static let temporary: UInt32 = 0x40000000 } } } diff --git a/Sources/SMBClient/SMBClient.swift b/Sources/SMBClient/SMBClient.swift index f7aec06..425492c 100644 --- a/Sources/SMBClient/SMBClient.swift +++ b/Sources/SMBClient/SMBClient.swift @@ -164,15 +164,24 @@ public struct Share { public let comment: String public let type: ShareType - public enum ShareType { - case diskDrive - case printQueue - case device - case ipc - case diskDriveAdmin - case printQueueAdmin - case deviceAdmin - case ipcAdmin + public struct ShareType: OptionSet { + typealias ShareInfo = DCERPC.NetShareEnumResponse.ShareInfo1 + + public let rawValue: UInt32 + + public init(rawValue: UInt32) { + self.rawValue = rawValue + } + + public static let diskTree = ShareType([]) + public static let printQueue = ShareType(rawValue: ShareInfo.ShareType.printQueue) + public static let device = ShareType(rawValue: ShareInfo.ShareType.device) + public static let ipc = ShareType(rawValue: ShareInfo.ShareType.ipc) + public static let clusterFS = ShareType(rawValue: ShareInfo.ShareType.clusterFS) + public static let clusterSOFS = ShareType(rawValue: ShareInfo.ShareType.clusterSOFS) + public static let clusterDFS = ShareType(rawValue: ShareInfo.ShareType.clusterDFS) + public static let special = ShareType(rawValue: ShareInfo.ShareType.special) + public static let temporary = ShareType(rawValue: ShareInfo.ShareType.temporary) } } @@ -182,6 +191,42 @@ extension Share: CustomStringConvertible { } } +extension Share.ShareType: CustomStringConvertible { + public var description: String { + typealias ShareType = DCERPC.NetShareEnumResponse.ShareInfo1.ShareType + + var type = [String]() + + switch rawValue & 0x0FFFFFFF { + case ShareType.diskTree: + type.append("Disk") + case ShareType.printQueue: + type.append("Print Queue") + case ShareType.device: + type.append("Device") + case ShareType.ipc: + type.append("IPC") + case ShareType.clusterFS: + type.append("Cluster FS") + case ShareType.clusterDFS: + type.append("Cluster SOFS") + case ShareType.clusterDFS: + type.append("Cluster DFS") + default: + break + } + + if rawValue & 0x80000000 != 0 { + type.append("Special") + } + if rawValue & 0x40000000 != 0 { + type.append("Temporary") + } + + return type.joined(separator: "|") + } +} + public struct File { public let name: String public var size: UInt64 { fileStat.size } diff --git a/Sources/SMBClient/Session.swift b/Sources/SMBClient/Session.swift index fee052d..4c68ce9 100644 --- a/Sources/SMBClient/Session.swift +++ b/Sources/SMBClient/Session.swift @@ -86,26 +86,16 @@ public class Session { try await close(fileId: createResponse.fileId) return shares.compactMap { - switch $0.type { - case 0x0: - return Share(name: $0.name.value, comment: $0.comment.value, type: .diskDrive) - case 0x1: - return Share(name: $0.name.value, comment: $0.comment.value, type: .printQueue) - case 0x2: - return Share(name: $0.name.value, comment: $0.comment.value, type: .device) - case 0x3: - return Share(name: $0.name.value, comment: $0.comment.value, type: .ipc) - case 0x80000000: - return Share(name: $0.name.value, comment: $0.comment.value, type: .diskDriveAdmin) - case 0x80000001: - return Share(name: $0.name.value, comment: $0.comment.value, type: .printQueueAdmin) - case 0x80000002: - return Share(name: $0.name.value, comment: $0.comment.value, type: .deviceAdmin) - case 0x80000003: - return Share(name: $0.name.value, comment: $0.comment.value, type: .ipcAdmin) - default: - return nil + var type = Share.ShareType(rawValue: $0.type & 0x0FFFFFFF) + + if $0.type & Share.ShareType.special.rawValue != 0 { + type.insert(.special) + } + if $0.type & Share.ShareType.temporary.rawValue != 0 { + type.insert(.temporary) } + + return Share(name: $0.name.value, comment: $0.comment.value, type: type) } } @@ -211,7 +201,7 @@ public class Session { let data = try await send(request.encoded()) let response = TreeDisconnect.Response(data: data) - + treeId = 0 connectedTree = nil diff --git a/Tests/SMBClientTests/SMBClientTests.swift b/Tests/SMBClientTests/SMBClientTests.swift index 8e99836..d335017 100644 --- a/Tests/SMBClientTests/SMBClientTests.swift +++ b/Tests/SMBClientTests/SMBClientTests.swift @@ -49,14 +49,14 @@ final class SMBClientTests: XCTestCase { let expectedShares: [String: [Share]] = [ "Alice": [ - Share(name: "Public", comment: "", type: .diskDrive), - Share(name: "Alice Share", comment: "", type: .diskDrive), - Share(name: "IPC$", comment: "IPC Service (Samba Server)", type: .ipcAdmin), + Share(name: "Public", comment: "", type: .diskTree), + Share(name: "Alice Share", comment: "", type: .diskTree), + Share(name: "IPC$", comment: "IPC Service (Samba Server)", type: [.ipc, .special]), ], "Bob": [ - Share(name: "Public", comment: "", type: .diskDrive), - Share(name: "Bob Share", comment: "", type: .diskDrive), - Share(name: "IPC$", comment: "IPC Service (Samba Server)", type: .ipcAdmin), + Share(name: "Public", comment: "", type: .diskTree), + Share(name: "Bob Share", comment: "", type: .diskTree), + Share(name: "IPC$", comment: "IPC Service (Samba Server)", type: [.ipc, .special]), ], ]