internal SMB2Command WaitForCommand(SMB2CommandName commandName) { const int TimeOut = 5000; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); while (stopwatch.ElapsedMilliseconds < TimeOut) { lock (m_incomingQueueLock) { for (int index = 0; index < m_incomingQueue.Count; index++) { SMB2Command command = m_incomingQueue[index]; if (command.CommandName == commandName) { m_incomingQueue.RemoveAt(index); return(command); } } } m_incomingQueueEventHandle.WaitOne(100); } return(null); }
public byte[] Signature; // 16 bytes (present if SMB2_FLAGS_SIGNED is set) public SMB2Header(SMB2CommandName commandName) { ProtocolId = ProtocolSignature; StructureSize = Length; Command = commandName; Signature = new byte[16]; }
public SMB2Header(byte[] buffer, int offset) { ProtocolId = ByteReader.ReadBytes(buffer, offset + 0, 4); StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + 4); CreditCharge = LittleEndianConverter.ToUInt16(buffer, offset + 6); Status = (NTStatus)LittleEndianConverter.ToUInt32(buffer, offset + 8); Command = (SMB2CommandName)LittleEndianConverter.ToUInt16(buffer, offset + 12); Credits = LittleEndianConverter.ToUInt16(buffer, offset + 14); Flags = (SMB2PacketHeaderFlags)LittleEndianConverter.ToUInt32(buffer, offset + 16); NextCommand = LittleEndianConverter.ToUInt32(buffer, offset + 20); MessageID = LittleEndianConverter.ToUInt64(buffer, offset + 24); if ((Flags & SMB2PacketHeaderFlags.AsyncCommand) > 0) { AsyncID = LittleEndianConverter.ToUInt64(buffer, offset + 32); } else { Reserved = LittleEndianConverter.ToUInt32(buffer, offset + 32); TreeID = LittleEndianConverter.ToUInt32(buffer, offset + 36); } SessionID = LittleEndianConverter.ToUInt64(buffer, offset + 40); if ((Flags & SMB2PacketHeaderFlags.Signed) > 0) { Signature = ByteReader.ReadBytes(buffer, offset + 48, 16); } }
public static SMB2Command ReadRequest(byte[] buffer, int offset) { SMB2CommandName commandName = (SMB2CommandName)LittleEndianConverter.ToUInt16(buffer, offset + 12); return(commandName switch { SMB2CommandName.Negotiate => new NegotiateRequest(buffer, offset), SMB2CommandName.SessionSetup => new SessionSetupRequest(buffer, offset), SMB2CommandName.Logoff => new LogoffRequest(buffer, offset), SMB2CommandName.TreeConnect => new TreeConnectRequest(buffer, offset), SMB2CommandName.TreeDisconnect => new TreeDisconnectRequest(buffer, offset), SMB2CommandName.Create => new CreateRequest(buffer, offset), SMB2CommandName.Close => new CloseRequest(buffer, offset), SMB2CommandName.Flush => new FlushRequest(buffer, offset), SMB2CommandName.Read => new ReadRequest(buffer, offset), SMB2CommandName.Write => new WriteRequest(buffer, offset), SMB2CommandName.Lock => new LockRequest(buffer, offset), SMB2CommandName.IOCtl => new IOCtlRequest(buffer, offset), SMB2CommandName.Cancel => new CancelRequest(buffer, offset), SMB2CommandName.Echo => new EchoRequest(buffer, offset), SMB2CommandName.QueryDirectory => new QueryDirectoryRequest(buffer, offset), SMB2CommandName.ChangeNotify => new ChangeNotifyRequest(buffer, offset), SMB2CommandName.QueryInfo => new QueryInfoRequest(buffer, offset), SMB2CommandName.SetInfo => new SetInfoRequest(buffer, offset), _ => throw new InvalidDataException("Invalid SMB2 command 0x" + ((ushort)commandName).ToString("X4")) });
public ErrorResponse(SMB2CommandName commandName, NTStatus status, byte[] errorData) : base(commandName) { Header.IsResponse = true; StructureSize = DeclaredSize; Header.Status = status; ErrorData = errorData; }
internal SMB2Command WaitForCommand(SMB2CommandName commandName) { const int TimeOut = 5000; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); while (stopwatch.ElapsedMilliseconds < TimeOut) { lock (m_incomingQueueLock) { for (int index = 0; index < m_incomingQueue.Count; index++) { SMB2Command command = m_incomingQueue[index]; if (command.CommandName == commandName) { m_incomingQueue.RemoveAt(index); // [MS-SMB2] 3.2.5.1.5 if (command.Header.Status == NTStatus.STATUS_PENDING) { // TODO: Increase timeout continue; } return(command); } } } m_incomingQueueEventHandle.WaitOne(100); } return(null); }
internal SMB2Command WaitForCommand(SMB2CommandName commandName, ulong messageId) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); try { while (stopwatch.ElapsedMilliseconds < TimeOut) { lock (m_incomingQueueLock) { for (int index = 0; index < m_incomingQueue.Count; index++) { SMB2Command command = m_incomingQueue[index]; if (command.CommandName == commandName && command.Header.MessageID == messageId) { m_incomingQueue.RemoveAt(index); if (command.Header.Status == NTStatus.STATUS_PENDING) { break; } return(command); } } } m_incomingQueueEventHandle.WaitOne(IncomingQueueTimeoutMillis); } } finally { stopwatch.Stop(); } return(null); }
internal SMB2Command WaitForCommand(SMB2CommandName commandName) { var result = waitForCommand(commandName); if ((result != null) && (result.Header.Status == NTStatus.STATUS_PENDING)) { result = waitForCommand(commandName); } return(result); }
public static SMB2Command ReadRequest(byte[] buffer, int offset) { SMB2CommandName Command = (SMB2CommandName)LittleEndianConverter.ToUInt16(buffer, offset + 12); switch (Command) { case SMB2CommandName.Negotiate: return(new NegotiateRequest(buffer, offset)); case SMB2CommandName.SessionSetup: return(new SessionSetupRequest(buffer, offset)); case SMB2CommandName.Logoff: return(new LogoffRequest(buffer, offset)); case SMB2CommandName.TreeConnect: return(new TreeConnectRequest(buffer, offset)); case SMB2CommandName.TreeDisconnect: return(new TreeDisconnectRequest(buffer, offset)); case SMB2CommandName.Create: return(new CreateRequest(buffer, offset)); case SMB2CommandName.Close: return(new CloseRequest(buffer, offset)); case SMB2CommandName.Flush: return(new FlushRequest(buffer, offset)); case SMB2CommandName.Read: return(new ReadRequest(buffer, offset)); case SMB2CommandName.Write: return(new WriteRequest(buffer, offset)); case SMB2CommandName.Lock: return(new LockRequest(buffer, offset)); case SMB2CommandName.IOCtl: return(new IOCtlRequest(buffer, offset)); case SMB2CommandName.Cancel: return(new CancelRequest(buffer, offset)); case SMB2CommandName.Echo: return(new EchoRequest(buffer, offset)); case SMB2CommandName.QueryDirectory: return(new QueryDirectoryRequest(buffer, offset)); case SMB2CommandName.ChangeNotify: return(new ChangeNotifyRequest(buffer, offset)); case SMB2CommandName.QueryInfo: return(new QueryInfoRequest(buffer, offset)); case SMB2CommandName.SetInfo: return(new SetInfoRequest(buffer, offset)); default: throw new System.IO.InvalidDataException("Invalid SMB2 command in buffer"); } }
public SMB2Command(SMB2CommandName commandName) { Header = new SMB2Header(commandName); }
private SMB2Command WaitForCommand(SMB2CommandName commandName) { return(m_client.WaitForCommand(commandName)); }
public static SMB2Command ReadResponse(byte[] buffer, int offset) { SMB2CommandName commandName = (SMB2CommandName)LittleEndianConverter.ToUInt16(buffer, offset + 12); ushort structureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0); switch (commandName) { case SMB2CommandName.Negotiate: { if (structureSize == NegotiateResponse.DeclaredSize) { return(new NegotiateResponse(buffer, offset)); } else if (structureSize == ErrorResponse.DeclaredSize) { return(new ErrorResponse(buffer, offset)); } else { throw new InvalidDataException(); } } case SMB2CommandName.SessionSetup: { // SESSION_SETUP Response and ERROR Response have the same declared StructureSize of 9. if (structureSize == SessionSetupResponse.DeclaredSize) { NTStatus status = (NTStatus)LittleEndianConverter.ToUInt32(buffer, offset + 8); if (status == NTStatus.STATUS_SUCCESS || status == NTStatus.STATUS_MORE_PROCESSING_REQUIRED) { return(new SessionSetupResponse(buffer, offset)); } else { return(new ErrorResponse(buffer, offset)); } } else { throw new InvalidDataException(); } } case SMB2CommandName.Logoff: { if (structureSize == LogoffResponse.DeclaredSize) { return(new LogoffResponse(buffer, offset)); } else if (structureSize == ErrorResponse.DeclaredSize) { return(new ErrorResponse(buffer, offset)); } else { throw new InvalidDataException(); } } case SMB2CommandName.TreeConnect: { if (structureSize == TreeConnectResponse.DeclaredSize) { return(new TreeConnectResponse(buffer, offset)); } else if (structureSize == ErrorResponse.DeclaredSize) { return(new ErrorResponse(buffer, offset)); } else { throw new InvalidDataException(); } } case SMB2CommandName.TreeDisconnect: { if (structureSize == TreeDisconnectResponse.DeclaredSize) { return(new TreeDisconnectResponse(buffer, offset)); } else if (structureSize == ErrorResponse.DeclaredSize) { return(new ErrorResponse(buffer, offset)); } else { throw new InvalidDataException(); } } case SMB2CommandName.Create: { if (structureSize == CreateResponse.DeclaredSize) { return(new CreateResponse(buffer, offset)); } else if (structureSize == ErrorResponse.DeclaredSize) { return(new ErrorResponse(buffer, offset)); } else { throw new InvalidDataException(); } } case SMB2CommandName.Close: { if (structureSize == CloseResponse.DeclaredSize) { return(new CloseResponse(buffer, offset)); } else if (structureSize == ErrorResponse.DeclaredSize) { return(new ErrorResponse(buffer, offset)); } else { throw new InvalidDataException(); } } case SMB2CommandName.Flush: { if (structureSize == FlushResponse.DeclaredSize) { return(new FlushResponse(buffer, offset)); } else if (structureSize == ErrorResponse.DeclaredSize) { return(new ErrorResponse(buffer, offset)); } else { throw new InvalidDataException(); } } case SMB2CommandName.Read: { if (structureSize == SMB2.ReadResponse.DeclaredSize) { return(new ReadResponse(buffer, offset)); } else if (structureSize == ErrorResponse.DeclaredSize) { return(new ErrorResponse(buffer, offset)); } else { throw new InvalidDataException(); } } case SMB2CommandName.Write: { if (structureSize == WriteResponse.DeclaredSize) { return(new WriteResponse(buffer, offset)); } else if (structureSize == ErrorResponse.DeclaredSize) { return(new ErrorResponse(buffer, offset)); } else { throw new InvalidDataException(); } } case SMB2CommandName.Lock: { if (structureSize == LockResponse.DeclaredSize) { return(new LockResponse(buffer, offset)); } else if (structureSize == ErrorResponse.DeclaredSize) { return(new ErrorResponse(buffer, offset)); } else { throw new InvalidDataException(); } } case SMB2CommandName.IOCtl: { if (structureSize == IOCtlResponse.DeclaredSize) { return(new IOCtlResponse(buffer, offset)); } else if (structureSize == ErrorResponse.DeclaredSize) { return(new ErrorResponse(buffer, offset)); } else { throw new InvalidDataException(); } } case SMB2CommandName.Cancel: { if (structureSize == ErrorResponse.DeclaredSize) { return(new ErrorResponse(buffer, offset)); } else { throw new InvalidDataException(); } } case SMB2CommandName.Echo: { if (structureSize == EchoResponse.DeclaredSize) { return(new EchoResponse(buffer, offset)); } else if (structureSize == ErrorResponse.DeclaredSize) { return(new ErrorResponse(buffer, offset)); } else { throw new InvalidDataException(); } } case SMB2CommandName.QueryDirectory: { // QUERY_DIRECTORY Response and ERROR Response have the same declared StructureSize of 9. if (structureSize == QueryDirectoryResponse.DeclaredSize) { NTStatus status = (NTStatus)LittleEndianConverter.ToUInt32(buffer, offset + 8); if (status == NTStatus.STATUS_SUCCESS) { return(new QueryDirectoryResponse(buffer, offset)); } else { return(new ErrorResponse(buffer, offset)); } } else { throw new InvalidDataException(); } } case SMB2CommandName.ChangeNotify: { // CHANGE_NOTIFY Response and ERROR Response have the same declared StructureSize of 9. if (structureSize == ChangeNotifyResponse.DeclaredSize) { NTStatus status = (NTStatus)LittleEndianConverter.ToUInt32(buffer, offset + 8); if (status == NTStatus.STATUS_SUCCESS || status == NTStatus.STATUS_NOTIFY_CLEANUP || status == NTStatus.STATUS_NOTIFY_ENUM_DIR) { return(new ChangeNotifyResponse(buffer, offset)); } else { return(new ErrorResponse(buffer, offset)); } } else { throw new InvalidDataException(); } } case SMB2CommandName.QueryInfo: { // QUERY_INFO Response and ERROR Response have the same declared StructureSize of 9. if (structureSize == QueryInfoResponse.DeclaredSize) { NTStatus status = (NTStatus)LittleEndianConverter.ToUInt32(buffer, offset + 8); if (status == NTStatus.STATUS_SUCCESS || status == NTStatus.STATUS_BUFFER_OVERFLOW) { return(new QueryInfoResponse(buffer, offset)); } else { return(new ErrorResponse(buffer, offset)); } } else { throw new InvalidDataException(); } } case SMB2CommandName.SetInfo: { if (structureSize == SetInfoResponse.DeclaredSize) { return(new SetInfoResponse(buffer, offset)); } else if (structureSize == ErrorResponse.DeclaredSize) { return(new ErrorResponse(buffer, offset)); } else { throw new InvalidDataException(); } } default: throw new InvalidDataException("Invalid SMB2 command 0x" + ((ushort)commandName).ToString("X4")); } }
public ErrorResponse(SMB2CommandName commandName) : base(commandName) { Header.IsResponse = true; StructureSize = DeclaredSize; }
public ErrorResponse(SMB2CommandName commandName, NTStatus status) : base(commandName) { Header.IsResponse = true; Header.Status = status; StructureSize = DeclaredSize; }