Пример #1
0
        /// <summary>
        /// Deep copy constructor.
        /// </summary>
        protected SmbTransactionRequestPacket(SmbTransactionRequestPacket packet)
            : base(packet)
        {
            this.InitDefaultValue();

            this.smbParameters.WordCount           = packet.SmbParameters.WordCount;
            this.smbParameters.TotalParameterCount = packet.SmbParameters.TotalParameterCount;
            this.smbParameters.TotalDataCount      = packet.SmbParameters.TotalDataCount;
            this.smbParameters.MaxParameterCount   = packet.SmbParameters.MaxParameterCount;
            this.smbParameters.MaxDataCount        = packet.SmbParameters.MaxDataCount;
            this.smbParameters.MaxSetupCount       = packet.SmbParameters.MaxSetupCount;
            this.smbParameters.Reserved1           = packet.SmbParameters.Reserved1;
            this.smbParameters.Flags           = packet.SmbParameters.Flags;
            this.smbParameters.Timeout         = packet.SmbParameters.Timeout;
            this.smbParameters.Reserved2       = packet.SmbParameters.Reserved2;
            this.smbParameters.ParameterCount  = packet.SmbParameters.ParameterCount;
            this.smbParameters.ParameterOffset = packet.SmbParameters.ParameterOffset;
            this.smbParameters.DataCount       = packet.SmbParameters.DataCount;
            this.smbParameters.DataOffset      = packet.SmbParameters.DataOffset;
            this.smbParameters.SetupCount      = packet.SmbParameters.SetupCount;
            this.smbParameters.Reserved3       = packet.SmbParameters.Reserved3;
            if (packet.smbParameters.Setup != null)
            {
                this.smbParameters.Setup = new ushort[packet.smbParameters.Setup.Length];
                Array.Copy(packet.smbParameters.Setup, this.smbParameters.Setup, packet.smbParameters.Setup.Length);
            }
            else
            {
                this.smbParameters.Setup = new ushort[0];
            }

            this.smbData.ByteCount = packet.SmbData.ByteCount;
            this.smbData.Name      = packet.SmbData.Name;
            if (packet.smbData.Pad1 != null)
            {
                this.smbData.Pad1 = new byte[packet.smbData.Pad1.Length];
                Array.Copy(packet.smbData.Pad1, this.smbData.Pad1, packet.smbData.Pad1.Length);
            }
            else
            {
                this.smbData.Pad1 = new byte[0];
            }

            if (packet.smbData.Trans_Parameters != null)
            {
                this.smbData.Trans_Parameters = new byte[packet.smbData.Trans_Parameters.Length];
                Array.Copy(packet.smbData.Trans_Parameters,
                           this.smbData.Trans_Parameters, packet.smbData.Trans_Parameters.Length);
            }
            else
            {
                this.smbData.Trans_Parameters = new byte[0];
            }

            if (packet.smbData.Pad2 != null)
            {
                this.smbData.Pad2 = new byte[packet.smbData.Pad2.Length];
                Array.Copy(packet.smbData.Pad2, this.smbData.Pad2, packet.smbData.Pad2.Length);
            }
            else
            {
                this.smbData.Pad2 = new byte[0];
            }

            if (packet.smbData.Trans_Data != null)
            {
                this.smbData.Trans_Data = new byte[packet.smbData.Trans_Data.Length];
                Array.Copy(packet.smbData.Trans_Data, this.smbData.Trans_Data, packet.smbData.Trans_Data.Length);
            }
            else
            {
                this.smbData.Trans_Data = new byte[0];
            }
        }
        /// <summary>
        /// Deep copy constructor.
        /// </summary>
        protected SmbTransactionRequestPacket(SmbTransactionRequestPacket packet)
            : base(packet)
        {
            this.InitDefaultValue();

            this.smbParameters.WordCount = packet.SmbParameters.WordCount;
            this.smbParameters.TotalParameterCount = packet.SmbParameters.TotalParameterCount;
            this.smbParameters.TotalDataCount = packet.SmbParameters.TotalDataCount;
            this.smbParameters.MaxParameterCount = packet.SmbParameters.MaxParameterCount;
            this.smbParameters.MaxDataCount = packet.SmbParameters.MaxDataCount;
            this.smbParameters.MaxSetupCount = packet.SmbParameters.MaxSetupCount;
            this.smbParameters.Reserved1 = packet.SmbParameters.Reserved1;
            this.smbParameters.Flags = packet.SmbParameters.Flags;
            this.smbParameters.Timeout = packet.SmbParameters.Timeout;
            this.smbParameters.Reserved2 = packet.SmbParameters.Reserved2;
            this.smbParameters.ParameterCount = packet.SmbParameters.ParameterCount;
            this.smbParameters.ParameterOffset = packet.SmbParameters.ParameterOffset;
            this.smbParameters.DataCount = packet.SmbParameters.DataCount;
            this.smbParameters.DataOffset = packet.SmbParameters.DataOffset;
            this.smbParameters.SetupCount = packet.SmbParameters.SetupCount;
            this.smbParameters.Reserved3 = packet.SmbParameters.Reserved3;
            if (packet.smbParameters.Setup != null)
            {
                this.smbParameters.Setup = new ushort[packet.smbParameters.Setup.Length];
                Array.Copy(packet.smbParameters.Setup, this.smbParameters.Setup, packet.smbParameters.Setup.Length);
            }
            else
            {
                this.smbParameters.Setup = new ushort[0];
            }

            this.smbData.ByteCount = packet.SmbData.ByteCount;
            this.smbData.Name = packet.SmbData.Name;
            if (packet.smbData.Pad1 != null)
            {
                this.smbData.Pad1 = new byte[packet.smbData.Pad1.Length];
                Array.Copy(packet.smbData.Pad1, this.smbData.Pad1, packet.smbData.Pad1.Length);
            }
            else
            {
                this.smbData.Pad1 = new byte[0];
            }

            if (packet.smbData.Trans_Parameters != null)
            {
                this.smbData.Trans_Parameters = new byte[packet.smbData.Trans_Parameters.Length];
                Array.Copy(packet.smbData.Trans_Parameters,
                    this.smbData.Trans_Parameters, packet.smbData.Trans_Parameters.Length);
            }
            else
            {
                this.smbData.Trans_Parameters = new byte[0];
            }

            if (packet.smbData.Pad2 != null)
            {
                this.smbData.Pad2 = new byte[packet.smbData.Pad2.Length];
                Array.Copy(packet.smbData.Pad2, this.smbData.Pad2, packet.smbData.Pad2.Length);
            }
            else
            {
                this.smbData.Pad2 = new byte[0];
            }

            if (packet.smbData.Trans_Data != null)
            {
                this.smbData.Trans_Data = new byte[packet.smbData.Trans_Data.Length];
                Array.Copy(packet.smbData.Trans_Data, this.smbData.Trans_Data, packet.smbData.Trans_Data.Length);
            }
            else
            {
                this.smbData.Trans_Data = new byte[0];
            }
        }
        /// <summary>
        /// Expect a request. If user is not interested in the packet, please call DefaultSendResponse().
        /// </summary>
        /// <param name="timeout">timeout</param>
        /// <param name="connection">the connection between server and client</param>
        /// <param name="session">the session between server and client</param>
        /// <param name="treeConnect">the tree connect between server and client</param>
        /// <param name="open">the file open between server and client</param>
        /// <param name="requestPacket">the request</param>
        public override void ExpectRequest(
            TimeSpan timeout,
            out IFileServiceServerConnection connection,
            out IFileServiceServerSession session,
            out IFileServiceServerTreeConnect treeConnect,
            out IFileServiceServerOpen open,
            out SmbFamilyPacket requestPacket)
        {
            CifsServerPerConnection cifsConnection;
            SmbPacket request = this.cifsServer.ExpectPacket(timeout, out cifsConnection);

            connection    = cifsConnection;
            requestPacket = request;
            session       = null;
            treeConnect   = null;
            open          = null;

            if (request != null)
            {
                session = cifsConnection.GetSession(request.SmbHeader.Uid);
                if (session != null)
                {
                    treeConnect = (session as CifsServerPerSession).GetTreeConnect(request.SmbHeader.Tid);
                    if (treeConnect != null)
                    {
                        ushort fid = 0;
                        SmbTransactionRequestPacket            transactionRequest = request as SmbTransactionRequestPacket;
                        SmbNtTransactIoctlRequestPacket        ioctlRequest       = request as SmbNtTransactIoctlRequestPacket;
                        SmbNtTransactNotifyChangeRequestPacket notifyChange       = request as SmbNtTransactNotifyChangeRequestPacket;

                        if (transactionRequest != null)
                        {
                            //SubCommand(2bytes), FID(2bytes)
                            fid = transactionRequest.SmbParameters.Setup[1];
                        }

                        else if (ioctlRequest != null)
                        {
                            //FunctionCode(4bytes), FID(2bytes), IsFctl(1bytes), IsFlags(1bytes)
                            fid = ioctlRequest.SmbParameters.Setup[2];
                        }
                        else if (notifyChange != null)
                        {
                            //CompletionFilter(4bytes), FID(2bytes), WatchTree(1bytes), Reserved(1bytes)
                            fid = notifyChange.SmbParameters.Setup[2];
                        }
                        else
                        {
                            Type         packetType = request.GetType();
                            PropertyInfo pi         = packetType.GetProperty(
                                "Trans2Parameters", BindingFlags.Instance | BindingFlags.Public);

                            if (pi == null)
                            {
                                pi = packetType.GetProperty(
                                    "NtTransParameters", BindingFlags.Instance | BindingFlags.Public);
                            }
                            if (pi == null)
                            {
                                pi = packetType.GetProperty(
                                    "SmbParameters", BindingFlags.Instance | BindingFlags.Public);
                            }
                            if (pi != null)
                            {
                                object    smbParameters = pi.GetValue(request, null);
                                FieldInfo fi            = smbParameters.GetType().GetField(
                                    "FID",
                                    BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase);
                                if (fi != null)
                                {
                                    fid = (ushort)fi.GetValue(smbParameters);
                                }
                            }
                        }

                        if (fid > 0)
                        {
                            open = (treeConnect as CifsServerPerTreeConnect).GetOpen(fid);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// to split a trans request to a trans request with trans secondary requests.
        /// </summary>
        /// <param name="transRequest">the trans request packet to be split.</param>
        /// <param name="parameterCount">the parameter count with which to split the request packet.</param>
        /// <param name="dataCount">the data count with which to split the request packet.</param>
        /// <returns>a requests array of the split trans request with trans secondary requests.</returns>
        /// <exception cref="System.ArgumentNullException">the transRequest must not be null.</exception>
        public SmbPacket[] CreateTransWith2ndRequests(
            SmbTransactionRequestPacket transRequest,
            int parameterCount,
            int dataCount)
        {
            if (transRequest == null)
            {
                throw new ArgumentNullException("transRequest");
            }

            transRequest.ToBytes();
            transRequest.isDivided = true;

            int paramLength = 0;

            if (transRequest.SmbData.Trans_Parameters != null)
            {
                paramLength = transRequest.SmbData.Trans_Parameters.Length;
            }
            double paramNumber = Math.Ceiling((double)paramLength / parameterCount);
            int dataLength = 0;

            if (transRequest.SmbData.Trans_Data != null)
            {
                dataLength = transRequest.SmbData.Trans_Data.Length;
            }
            int dataNumber = (int)Math.Ceiling((double)dataLength / dataCount);
            double packetCount = paramNumber > dataNumber ? paramNumber : dataNumber;
            List<SmbPacket> packetList = new List<SmbPacket>();

            if (packetCount > 1)
            {
                byte[] transParameters = transRequest.SmbData.Trans_Parameters;
                byte[] transData = transRequest.SmbData.Trans_Data;
                SMB_COM_TRANSACTION_Request_SMB_Data transSmbData = transRequest.SmbData;

                if (paramLength > parameterCount)
                {
                    transSmbData.Trans_Parameters = new byte[parameterCount];
                    Array.Copy(transParameters, transSmbData.Trans_Parameters, parameterCount);
                }

                if (dataLength > dataCount)
                {
                    transSmbData.Trans_Data = new byte[dataCount];
                    Array.Copy(transData, transSmbData.Trans_Data, dataCount);
                }
                transRequest.SmbData = transSmbData;
                transRequest.UpdateCountAndOffset();
                packetList.Add(transRequest);
                int currentIndex = 1;
                int remainedParamCount = transRequest.SmbParameters.TotalParameterCount - parameterCount;
                int remainedDataCount = transRequest.SmbParameters.TotalDataCount - dataCount;

                while (currentIndex < packetCount)
                {
                    SmbTransactionSecondaryRequestPacket packet = new SmbTransactionSecondaryRequestPacket();
                    SmbHeader header = transRequest.SmbHeader;
                    header.Command = SmbCommand.SMB_COM_TRANSACTION_SECONDARY;
                    packet.SmbHeader = header;

                    // Set Smb_Parameters
                    SMB_COM_TRANSACTION_SECONDARY_Request_SMB_Parameters smbParameters =
                        new SMB_COM_TRANSACTION_SECONDARY_Request_SMB_Parameters();
                    smbParameters.WordCount = (byte)(CifsMessageUtils.GetSize<
                        SMB_COM_TRANSACTION_SECONDARY_Request_SMB_Parameters>(smbParameters) / NumBytesOfWord);
                    smbParameters.TotalParameterCount = transRequest.SmbParameters.TotalParameterCount;
                    smbParameters.TotalDataCount = transRequest.SmbParameters.TotalDataCount;

                    // Set Smb_Data
                    SMB_COM_TRANSACTION_SECONDARY_Request_SMB_Data smbData = new SMB_COM_TRANSACTION_SECONDARY_Request_SMB_Data();

                    if (remainedParamCount > parameterCount)
                    {
                        smbData.Trans_Parameters = new byte[parameterCount];
                        Array.Copy(transParameters, parameterCount * currentIndex, smbData.Trans_Parameters, 0, parameterCount);
                        smbParameters.ParameterDisplacement = (ushort)(parameterCount * currentIndex);
                        remainedParamCount -= parameterCount;
                    }
                    else if (remainedParamCount > 0)
                    {
                        smbData.Trans_Parameters = new byte[remainedParamCount];
                        Array.Copy(transParameters, parameterCount * currentIndex, smbData.Trans_Parameters, 0, remainedParamCount);
                        smbParameters.ParameterDisplacement = (ushort)(parameterCount * currentIndex);
                        remainedParamCount -= parameterCount;
                    }
                    else
                    {
                        smbData.Trans_Parameters = new byte[0];
                    }

                    if (remainedDataCount > dataCount)
                    {
                        smbData.Trans_Data = new byte[dataCount];
                        Array.Copy(transData, dataCount * currentIndex, smbData.Trans_Data, 0, dataCount);
                        smbParameters.DataDisplacement = (ushort)(dataCount * currentIndex);
                        remainedDataCount -= dataCount;
                    }
                    else if (remainedDataCount > 0)
                    {
                        smbData.Trans_Data = new byte[remainedDataCount];
                        Array.Copy(transData, dataCount * currentIndex, smbData.Trans_Data, 0, remainedDataCount);
                        smbParameters.DataDisplacement = (ushort)(dataCount * currentIndex);
                        remainedDataCount -= dataCount;
                    }
                    else
                    {
                        smbData.Trans_Data = new byte[0];
                    }

                    packet.SmbParameters = smbParameters;
                    packet.SmbData = smbData;
                    currentIndex++;
                    packet.UpdateCountAndOffset();
                    packetList.Add(packet);
                }
            }
            else
            {
                packetList.Add(transRequest);
            }

            return packetList.ToArray();
        }
        /// <summary>
        /// Create Trans response
        /// </summary>
        /// <param name="connection">the connection on which the response will be sent.</param>
        /// <param name="request">the corresponding request</param>
        /// <returns>the default response to the request.</returns>
        private SmbPacket CreateDefaultTransResponse(
            CifsServerPerConnection connection,
            SmbTransactionRequestPacket request)
        {
            SmbTransSetNmpipeStateRequestPacket setStateRequest = request as SmbTransSetNmpipeStateRequestPacket;
            SmbTransRawReadNmpipeRequestPacket rewReadRequest = request as SmbTransRawReadNmpipeRequestPacket;
            SmbTransQueryNmpipeStateRequestPacket queryStateRequest = request as SmbTransQueryNmpipeStateRequestPacket;
            SmbTransQueryNmpipeInfoRequestPacket queryInfoRequest = request as SmbTransQueryNmpipeInfoRequestPacket;
            SmbTransPeekNmpipeRequestPacket peekStateRequest = request as SmbTransPeekNmpipeRequestPacket;
            SmbTransTransactNmpipeRequestPacket transactRequest = request as SmbTransTransactNmpipeRequestPacket;
            SmbTransRawWriteNmpipeRequestPacket rawWriteRequest = request as SmbTransRawWriteNmpipeRequestPacket;
            SmbTransReadNmpipeRequestPacket readRequest = request as SmbTransReadNmpipeRequestPacket;
            SmbTransWriteNmpipeRequestPacket writeRequest = request as SmbTransWriteNmpipeRequestPacket;
            SmbTransCallNmpipeRequestPacket callRequest = request as SmbTransCallNmpipeRequestPacket;
            SmbTransRapRequestPacket rapRequest = request as SmbTransRapRequestPacket;
            SmbPacket response = null;
            if (setStateRequest != null)
            {
                response = this.CreateTransSetNmpipeStateSuccessResponse(connection, setStateRequest);
            }
            else if (rewReadRequest != null)
            {
                response = this.CreateTransRawReadNmpipeSuccessResponse(connection, rewReadRequest, new byte[0]);
            }
            else if (queryStateRequest != null)
            {
                response = this.CreateTransQueryNmpipeStateSuccessResponse(connection, queryStateRequest,
                    SMB_NMPIPE_STATUS.Endpoint);
            }
            else if (queryInfoRequest != null)
            {
                response = this.CreateTransQueryNmpipeInfoSuccessResponse(connection, queryInfoRequest, 0x0, 0x0, 0x0,
                    0x0, @"\\Cifs\share");
            }
            else if (peekStateRequest != null)
            {
                response = this.CreateTransPeekNmpipeSuccessResponse(connection, peekStateRequest, 0x0, 0x0,
                    SMB_NMPIPE_STATUS.Endpoint, new byte[0]);
            }
            else if (transactRequest != null)
            {
                response = this.CreateTransTransactNmpipeSuccessResponse(connection, transactRequest, new byte[0]);
            }
            else if (rawWriteRequest != null)
            {
                response = this.CreateTransRawWriteNmpipeSuccessResponse(connection, rawWriteRequest);
            }
            else if (readRequest != null)
            {
                response = this.CreateTransReadNmpipeSuccessResponse(connection, readRequest, new byte[0]);
            }
            else if (writeRequest != null)
            {
                response = this.CreateTransWriteNmpipeSuccessResponse(connection, writeRequest);
            }
            else if (callRequest != null)
            {
                response = this.CreateTransCallNmpipeSuccessResponse(connection, callRequest, new byte[0]);
            }
            else if (rapRequest != null)
            {
                response = new SmbTransRapResponsePacket();
                response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request);
            }

            return response;
        }
        public SmbTransactionInterimResponsePacket CreateTransactionInterimResponse(
            CifsServerPerConnection connection,
            SmbTransactionRequestPacket request)
        {
            SmbTransactionInterimResponsePacket response = new SmbTransactionInterimResponsePacket();
            response.SmbHeader = CifsMessageUtils.CreateSmbHeader(connection, request);

            return response;
        }