/// <summary>
        /// Create NT_TRANSACT_CREATE Server Response 
        /// </summary>
        /// <param name="connection">the connection identified the client</param>
        /// <param name = "fileId">
        /// The SMB file identifier returned by the SMB server for the file or device that was opened or created 
        /// </param>
        /// <param name = "createAction">The action taken. This field MUST be interpreted as follows </param>
        /// <param name = "extFileAttributes">Extended attributes and flags for this file or directory </param>
        /// <param name = "fileType">The file type </param>
        /// <param name = "isDirectory">
        /// A value that indicates whether this is a directory. MUST be nonzero when this is a directory 
        /// </param>
        /// <returns>The SmbNtTransactCreateResponsePacket </returns>
        /// <exception cref="ArgumentNullException">connection must not be null</exception>
        public virtual SmbNtTransactCreateResponsePacket CreateNtTransCreateResponse(
            SmbServerConnection connection,
            ushort fileId,
            uint createAction,
            uint extFileAttributes,
            FileTypeValue fileType,
            bool isDirectory)
        {
            if (connection == null)
            {
                throw new ArgumentNullException("connection");
            }

            SmbNtTransactCreateResponsePacket packet = new SmbNtTransactCreateResponsePacket();

            // get the request packet
            SmbPacket request = connection.GetRequestPacket(connection.MessageId);

            // create smb packet header
            packet.SmbHeader = CifsMessageUtils.CreateSmbHeader(
                SmbCommand.SMB_COM_NT_TRANSACT,
                connection.ProcessId, connection.MessageId, request.SmbHeader.Uid, request.SmbHeader.Tid,
                (SmbFlags)connection.Capability.Flag, (SmbFlags2)connection.Capability.Flags2);

            // update smb parameters
            SMB_COM_NT_TRANSACT_SuccessResponse_SMB_Parameters smbParameters = packet.SmbParameters;

            // reserved 3 bytes.
            smbParameters.Reserved1 = new byte[3];
            smbParameters.Setup = new ushort[0];

            smbParameters.WordCount = (byte)(CifsMessageUtils.GetSize<SMB_COM_NT_TRANSACT_SuccessResponse_SMB_Parameters>(
                smbParameters) / SmbCapability.NUM_BYTES_OF_WORD);

            // update smb data
            SMB_COM_NT_TRANSACT_SuccessResponse_SMB_Data smbData = packet.SmbData;

            // update smbData.ByteCount
            smbData.ByteCount = 0;

            // update nt transaction parameters
            NT_TRANSACT_CREATE_Response_NT_Trans_Parameters ntTransPamameters = packet.NtTransParameters;
            ntTransPamameters.FID = fileId;
            ntTransPamameters.CreateAction = (NtTransactCreateActionValues)createAction;
            ntTransPamameters.ExtFileAttributes = (SMB_EXT_FILE_ATTR)extFileAttributes;
            ntTransPamameters.ResourceType = fileType;
            ntTransPamameters.Directory = (byte)(isDirectory ? 1 : 0);

            // store the parameters and data to packet.
            packet.SmbParameters = smbParameters;
            packet.SmbData = smbData;
            packet.NtTransParameters = ntTransPamameters;

            packet.UpdateCountAndOffset();

            return packet;
        }
        /// <summary>
        /// create the nt transaction packet
        /// </summary>
        /// <param name="request">the request packet</param>
        /// <param name="smbHeader">the smb header of response packet</param>
        /// <param name="channel">the channel contains the packet bytes</param>
        /// <returns>the response packet</returns>
        private SmbPacket CreateNtTransactionResponsePacket(SmbPacket request, SmbHeader smbHeader, Channel channel)
        {
            SmbPacket smbPacket = null;

            if (smbHeader.Status == 0 && channel.Peek<byte>(0) == 0 && channel.Peek<ushort>(1) == 0)
            {
                return smbPacket;
            }

            SmbNtTransactRequestPacket ntTransactRequest = request as SmbNtTransactRequestPacket;
            if (ntTransactRequest == null)
            {
                return smbPacket;
            }

            // find regular packet
            switch ((uint)ntTransactRequest.SmbParameters.Function)
            {
                case (uint)NtTransSubCommand.NT_TRANSACT_RENAME:
                    smbPacket = new SmbNtTransRenameResponsePacket();
                    break;

                case (uint)NtTransSubCommand.NT_TRANSACT_CREATE:
                    smbPacket = new SmbNtTransactCreateResponsePacket();
                    break;

                case (uint)NtTransSubCommand.NT_TRANSACT_IOCTL:

                    NT_TRANSACT_IOCTL_SETUP setup =
                       CifsMessageUtils.ToStuct<NT_TRANSACT_IOCTL_SETUP>(
                       CifsMessageUtils.ToBytesArray<ushort>(ntTransactRequest.SmbParameters.Setup));

                    switch ((NtTransFunctionCode)setup.FunctionCode)
                    {
                        case NtTransFunctionCode.FSCTL_SRV_ENUMERATE_SNAPSHOTS:
                            smbPacket = new SmbNtTransFsctlSrvEnumerateSnapshotsResponsePacket();
                            break;

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

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

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

                    break;

                case (uint)SmbNtTransSubCommand.NT_TRANSACT_QUERY_QUOTA:
                    smbPacket = new SmbNtTransQueryQuotaResponsePacket();
                    break;

                case (uint)SmbNtTransSubCommand.NT_TRANSACT_SET_QUOTA:
                    smbPacket = new SmbNtTransSetQuotaResponsePacket();
                    break;

                default:
                    break;
            }

            return smbPacket;
        }