コード例 #1
0
        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);
        }
コード例 #2
0
        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];
        }
コード例 #3
0
 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);
     }
 }
コード例 #4
0
ファイル: SMB2Command.cs プロジェクト: SonnyX/SMB-Client
        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"))
            });
コード例 #5
0
 public ErrorResponse(SMB2CommandName commandName, NTStatus status, byte[] errorData) : base(commandName)
 {
     Header.IsResponse = true;
     StructureSize     = DeclaredSize;
     Header.Status     = status;
     ErrorData         = errorData;
 }
コード例 #6
0
        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);
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        internal SMB2Command WaitForCommand(SMB2CommandName commandName)
        {
            var result = waitForCommand(commandName);

            if ((result != null) && (result.Header.Status == NTStatus.STATUS_PENDING))
            {
                result = waitForCommand(commandName);
            }

            return(result);
        }
コード例 #9
0
ファイル: SMB2Command.cs プロジェクト: ciamberlini/SMBLibrary
        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");
            }
        }
コード例 #10
0
ファイル: SMB2Command.cs プロジェクト: ciamberlini/SMBLibrary
 public SMB2Command(SMB2CommandName commandName)
 {
     Header = new SMB2Header(commandName);
 }
コード例 #11
0
 private SMB2Command WaitForCommand(SMB2CommandName commandName)
 {
     return(m_client.WaitForCommand(commandName));
 }
コード例 #12
0
        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"));
            }
        }
コード例 #13
0
 public ErrorResponse(SMB2CommandName commandName) : base(commandName)
 {
     Header.IsResponse = true;
     StructureSize     = DeclaredSize;
 }
コード例 #14
0
 public ErrorResponse(SMB2CommandName commandName, NTStatus status) : base(commandName)
 {
     Header.IsResponse = true;
     Header.Status     = status;
     StructureSize     = DeclaredSize;
 }