Exemplo n.º 1
0
        /// <summary>
        /// find the nt transaction packets
        /// </summary>
        /// <param name="command">the command of nt transaction</param>
        /// <param name="setup">the setup contains the sub command</param>
        /// <returns>the target nt transaction packet</returns>
        private static SmbPacket FindTheNtTransPacket(NtTransSubCommand command, byte[] setup)
        {
            SmbPacket smbPacket = null;

            switch (command)
            {
            case NtTransSubCommand.NT_TRANSACT_CREATE:
                smbPacket = new SmbNtTransactCreateRequestPacket();
                break;

            case NtTransSubCommand.NT_TRANSACT_RENAME:
                smbPacket = new SmbNtTransRenameRequestPacket();
                break;

            case NtTransSubCommand.NT_TRANSACT_IOCTL:
                NT_TRANSACT_IOCTL_SETUP subCommand = CifsMessageUtils.ToStuct <NT_TRANSACT_IOCTL_SETUP>(setup);
                switch ((NtTransFunctionCode)subCommand.FunctionCode)
                {
                case NtTransFunctionCode.FSCTL_SRV_ENUMERATE_SNAPSHOTS:
                    smbPacket = new SmbNtTransFsctlSrvEnumerateSnapshotsRequestPacket();
                    break;

                case NtTransFunctionCode.FSCTL_SRV_REQUEST_RESUME_KEY:
                    smbPacket = new SmbNtTransFsctlSrvRequestResumeKeyRequestPacket();
                    break;

                case NtTransFunctionCode.FSCTL_SRV_COPYCHUNK:
                    smbPacket = new SmbNtTransFsctlSrvCopyChunkRequestPacket();
                    break;

                default:
                    smbPacket = new SmbNtTransactIoctlRequestPacket();
                    break;
                }
                break;

            default:
                switch ((SmbNtTransSubCommand)command)
                {
                case SmbNtTransSubCommand.NT_TRANSACT_QUERY_QUOTA:
                    smbPacket = new SmbNtTransQueryQuotaRequestPacket();
                    break;

                case SmbNtTransSubCommand.NT_TRANSACT_SET_QUOTA:
                    smbPacket = new SmbNtTransSetQuotaRequestPacket();
                    break;
                }
                break;
            }

            return(smbPacket);
        }
        /// <summary>
        /// Create NTTransIOCtlCopyChunk request for client to copy chunk to server file. 
        /// </summary>
        /// <param name = "messageId">the id of message, used to identity the request and the server response. </param>
        /// <param name = "sessionUid">the valid session id, must be response by server of the session setup request. </param>
        /// <param name = "treeId">the valid tree connect id, must be response by server of the tree connect. </param>
        /// <param name = "flags">
        /// The Flags field contains individual flags, as specified in [CIFS] sections 2.4.2 and 3.1.1. 
        /// </param>
        /// <param name = "flags2">
        /// The Flags2 field contains individual bit flags that, depending on the negotiated SMB dialect, indicate   
        /// various client and server capabilities. 
        /// </param>
        /// <param name = "fileId">the valid file id to operation on, response by server. </param>
        /// <param name = "isFsctl">
        /// This field is TRUE if the command is a file system control command and the FID is a file system control  
        /// device. Otherwise, the command is a device control command and FID is an I/O device. 
        /// </param>
        /// <param name = "isFlags">
        /// If bit 0 is set, the command is to be applied to a share root handle. The share MUST be a Distributed File 
        ///  System (DFS) type 
        /// </param>
        /// <param name = "copychunkResumeKey">
        /// A 24-byte resume key generated by the SMB server that can be subsequently used by the client to uniquely  
        /// identify the open source file in a FSCTL_SRV_COPYCHUNK request. 
        /// </param>
        /// <param name = "list">
        /// A concatenated list of copychunk blocks. This field is as specified in section 2.2.14.7.3.1. 
        /// </param>
        /// <returns>a nt transaction rename request packet </returns>
        /// <exception cref = "ArgumentNullException">list must not be null </exception>
        /// <exception cref = "ArgumentException">
        /// The number of entries in the copychunk list. MUST NOT be 0. 
        /// </exception>
        private SmbNtTransFsctlSrvCopyChunkRequestPacket CreateNTTransIOCtlCopyChunkRequest(
            ushort messageId,
            ushort sessionUid,
            ushort treeId,
            SmbHeader_Flags_Values flags,
            SmbHeader_Flags2_Values flags2,
            ushort fileId,
            bool isFsctl,
            byte isFlags,
            byte[] copychunkResumeKey,
            NT_TRANSACT_COPY_CHUNK_List[] list)
        {
            if (list == null)
            {
                throw new ArgumentNullException("list");
            }

            if (list.Length == 0)
            {
                throw new ArgumentException(
                    "The number of entries in the copychunk list. MUST NOT be 0.", "list");
            }

            SmbNtTransFsctlSrvCopyChunkRequestPacket request = new SmbNtTransFsctlSrvCopyChunkRequestPacket(
                this.cifsClient.CreateNtTransactIoctlRequest(
                messageId, sessionUid, treeId, (SmbFlags)flags, (SmbFlags2)flags2,
                this.capability.MaxSetupCount, this.capability.MaxParameterCount, this.capability.MaxDataCount,
                (uint)NtTransFunctionCode.FSCTL_SRV_COPYCHUNK, fileId, isFsctl, isFlags, null));

            // update the copy chunk trans data.
            NT_TRANSACT_COPY_CHUNK_Request_NT_Trans_Data ntTransData = request.NtTransData;

            ntTransData.CopyChunkResumeKey = copychunkResumeKey;
            ntTransData.ChunkCount = (uint)list.Length;
            ntTransData.List = list;

            request.NtTransData = ntTransData;

            request.UpdateCountAndOffset();

            return request;
        }
 /// <summary>
 /// Deep copy constructor. 
 /// </summary>
 public SmbNtTransFsctlSrvCopyChunkRequestPacket(
     SmbNtTransFsctlSrvCopyChunkRequestPacket packet)
     : base(packet)
 {
 }
 /// <summary>
 /// Deep copy constructor.
 /// </summary>
 public SmbNtTransFsctlSrvCopyChunkRequestPacket(
     SmbNtTransFsctlSrvCopyChunkRequestPacket packet)
     : base(packet)
 {
 }
        /// <summary>
        /// NT_TRANSACT_IOCTL Client Request.
        /// </summary>
        /// <param name="messageId">Message ID used to identify the message.</param>
        /// <param name="sessionId">Session ID used to identify the session.</param>
        /// <param name="treeId">Tree ID used to identify the tree connection.</param>
        /// <param name="isSigned">
        /// Indicate whether the SUT has message signing enabled or required.
        /// </param>
        /// <param name="fid">The file identifier.</param>
        /// <param name="copychunkResumeKeysize">The server resume key for a source file.</param>
        /// <param name="sourceOffset">The offset in the source file to copy from.</param>
        /// <param name="targetOffset">The offset in the target file to copy to.</param>
        /// <param name="length">The number of bytes to copy from the source file to the target file.</param>
        public void FsctlSrvCopyChunkRequest(
            int messageId,
            int sessionId,
            int treeId,
            bool isSigned,
            int fid,
            string copychunkResumeKeysize,
            int sourceOffset,
            int targetOffset,
            int length)
        {
            #region Create Packet

            SmbNtTransFsctlSrvCopyChunkRequestPacket smbPacket = new SmbNtTransFsctlSrvCopyChunkRequestPacket();
            ushort uid = (ushort)this.uId[(uint)sessionId];

            byte[] copyChunkResumeKey = null;
            if (copychunkResumeKeysize == CopyChunkResumeKey)
            {
                copyChunkResumeKey = SmbAdapter.resumeKey;
            }
            else
            {
                copyChunkResumeKey = new byte[24];
                for (int i = 0; i < 24; i++)
                {
                    copyChunkResumeKey[i] = 0x10;
                }
            }

            byte isFlags = byte.MinValue;
            NT_TRANSACT_COPY_CHUNK_List list = new NT_TRANSACT_COPY_CHUNK_List();
            list.Length = (uint)this.copyWordCount;
            list.SourceOffset = (ulong)sourceOffset;
            list.DestinationOffset = (ulong)targetOffset;

            smbPacket = this.smbClientStack.CreateNTTransIOCtlCopyChunkRequest(
                (ushort)this.fId[(uint)fid],
                true,
                isFlags,
                copyChunkResumeKey,
                list);

            if (isSigned)
            {
                NamespaceCifs.CifsClientPerConnection connection =
                    this.smbClientStack.Context.GetConnection(ConnectionId);

                NamespaceCifs.CifsClientPerSession session =
                    this.smbClientStack.Context.GetSession(ConnectionId, uid);

                smbPacket.Sign(connection.ClientNextSendSequenceNumber, session.SessionKey);
            }

            #endregion

            #region Send and Receive ExpectPacket

            this.smbClientStack.SendPacket(smbPacket);
            StackPacket response = this.smbClientStack.ExpectPacket(this.timeout);

            NamespaceCifs.SmbPacket smbPacketResponse = (NamespaceCifs.SmbPacket)response;
            this.QueryUidTable(smbPacketResponse);
            this.QueryTidTable(smbPacketResponse);

            VerifyTransport(smbPacketResponse);
            VerifyCommonMessageSyntax(smbPacketResponse);

            if (response.GetType() == typeof(SmbErrorResponsePacket))
            {
                SmbErrorResponsePacket smbErrorResponsePacket = response as SmbErrorResponsePacket;
                NamespaceCifs.SmbHeader smbErrorHeader = smbErrorResponsePacket.SmbHeader;
                this.ErrorResponse(smbErrorHeader.Mid + this.addMidMark, (MessageStatus)smbErrorHeader.Status);
            }
            else
            {
                SmbNtTransFsctlSrvCopyChunkResponsePacket smbFsctlSrvCopyChunkPacket
                    = response as SmbNtTransFsctlSrvCopyChunkResponsePacket;

                NamespaceCifs.SmbHeader ntTransFsctlSrvCopyChunkResponseHeader = smbFsctlSrvCopyChunkPacket.SmbHeader;

                VerifyMessageSyntaxFsctlSrvCopychunkResponse(smbFsctlSrvCopyChunkPacket);

                this.FsctlSrvCopyChunkResponse(
                    ntTransFsctlSrvCopyChunkResponseHeader.Mid + this.addMidMark,
                    this.QueryUidTable(smbPacketResponse),
                    this.QueryTidTable(smbPacketResponse),
                    (smbPacketResponse).IsSignRequired,
                    (MessageStatus)ntTransFsctlSrvCopyChunkResponseHeader.Status);
            }

            #endregion
        }
        /// <summary>
        /// find the nt transaction packets
        /// </summary>
        /// <param name="command">the command of nt transaction</param>
        /// <param name="setup">the setup contains the sub command</param>
        /// <returns>the target nt transaction packet</returns>
        private static SmbPacket FindTheNtTransPacket(NtTransSubCommand command, byte[] setup)
        {
            SmbPacket smbPacket = null;
            switch (command)
            {
                case NtTransSubCommand.NT_TRANSACT_CREATE:
                    smbPacket = new SmbNtTransactCreateRequestPacket();
                    break;

                case NtTransSubCommand.NT_TRANSACT_RENAME:
                    smbPacket = new SmbNtTransRenameRequestPacket();
                    break;

                case NtTransSubCommand.NT_TRANSACT_IOCTL:
                    NT_TRANSACT_IOCTL_SETUP subCommand = CifsMessageUtils.ToStuct<NT_TRANSACT_IOCTL_SETUP>(setup);
                    switch ((NtTransFunctionCode)subCommand.FunctionCode)
                    {
                        case NtTransFunctionCode.FSCTL_SRV_ENUMERATE_SNAPSHOTS:
                            smbPacket = new SmbNtTransFsctlSrvEnumerateSnapshotsRequestPacket();
                            break;

                        case NtTransFunctionCode.FSCTL_SRV_REQUEST_RESUME_KEY:
                            smbPacket = new SmbNtTransFsctlSrvRequestResumeKeyRequestPacket();
                            break;

                        case NtTransFunctionCode.FSCTL_SRV_COPYCHUNK:
                            smbPacket = new SmbNtTransFsctlSrvCopyChunkRequestPacket();
                            break;

                        default:
                            smbPacket = new SmbNtTransactIoctlRequestPacket();
                            break;
                    }
                    break;

                default:
                    switch ((SmbNtTransSubCommand)command)
                    {
                        case SmbNtTransSubCommand.NT_TRANSACT_QUERY_QUOTA:
                            smbPacket = new SmbNtTransQueryQuotaRequestPacket();
                            break;

                        case SmbNtTransSubCommand.NT_TRANSACT_SET_QUOTA:
                            smbPacket = new SmbNtTransSetQuotaRequestPacket();
                            break;
                    }
                    break;
            }

            return smbPacket;
        }