/// <summary>
        /// Read data from server, start at the positon indicated by offset
        /// </summary>
        /// <param name="timeout">The pending time to get server's response</param>
        /// <param name="offset">From where it will read</param>
        /// <param name="length">The length of the data client wants to read</param>
        /// <param name="data">The read data</param>
        /// <returns>
        /// a uint value that specifies the status of response packet.
        /// </returns>
        /// <exception cref="System.InvalidOperationException">Thrown if there is any error occurred</exception>
        public override uint Read(TimeSpan timeout, ulong offset, uint length, out byte[] data)
        {
            this.internalTimeout = timeout;

            SmbReadAndxRequestPacket request = smbClient.CreateReadRequest(this.fid, (ushort)length, (uint)offset);

            if (this.isSignRequired)
            {
                request.Sign(this.NextSequenceNumber, this.sessionKey);
            }

            uint status = 0;
            SmbReadAndxResponsePacket response =
                this.SendAndExpectSmbPacket(request, internalTimeout, out status) as SmbReadAndxResponsePacket;

            data = ArrayUtility.SubArray <byte>(response.SmbData.Data, 0);

            return(SmbMessageUtils.CheckStatus(status));
        }
        /// <summary>
        /// Execute a transacted exchange against a named pipe.
        /// </summary>
        /// <param name="timeout">The pending time to get server's response</param>
        /// <param name="writeData">the written data to the named pipe</param>
        /// <param name="readData">The read data from the named pipe</param>
        /// <returns>
        /// a uint value that specifies the status of response packet.
        /// </returns>
        /// <exception cref="System.InvalidOperationException">Thrown if there is any error occurred</exception>
        public uint Transaction(TimeSpan timeout, byte[] writeData, out byte[] readData)
        {
            this.internalTimeout = timeout;

            SmbTransTransactNmpipeRequestPacket request = smbClient.CreateTransTransactNamedPipeRequest(this.fid, TransSmbParametersFlags.NONE, writeData, smbClient.Capability.MaxDataCount);

            if (this.isSignRequired)
            {
                request.Sign(this.NextSequenceNumber, this.sessionKey);
            }

            uint status = 0;
            SmbTransTransactNmpipeResponsePacket response =
                this.SendAndExpectSmbPacket(request, internalTimeout, out status) as SmbTransTransactNmpipeResponsePacket;

            readData = ArrayUtility.SubArray <byte>(response.TransData.ReadData, 0);

            return(SmbMessageUtils.CheckStatus(status));
        }
        /// <summary>
        /// Do IO control on remote server
        /// </summary>
        /// <param name="ctlCode">The control code</param>
        /// <param name="isFsCtl">Indicate if the control code is a file system control code</param>
        /// <param name="input">The input data of io control</param>
        /// <param name="output">The output data of io control</param>
        /// <returns>
        /// a uint value that specifies the status of response packet.
        /// </returns>
        /// <exception cref="System.InvalidOperationException">Thrown when meet an transport error</exception>
        private uint InternalIoControl(uint ctlCode, bool isFsCtl, byte[] input, out byte[] output)
        {
            SmbNtTransactIoctlRequestPacket request =
                smbClient.CreateNTTransIOCtlRequest(this.fid, isFsCtl, 0x00, ctlCode, input);

            if (this.isSignRequired)
            {
                request.Sign(this.NextSequenceNumber, this.sessionKey);
            }

            uint status = 0;
            SmbNtTransactIoctlResponsePacket response =
                this.SendAndExpectSmbPacket(request, internalTimeout, out status) as SmbNtTransactIoctlResponsePacket;

            output = null;
            if (response != null)
            {
                output = response.NtTransData.Data;
            }

            return(SmbMessageUtils.CheckStatus(status));
        }
        /// <summary>
        /// Write data to server. cifs/smb implementation of this interface should pay attention to offset.
        /// They may not accept ulong as offset
        /// </summary>
        /// <param name="timeout">The pending time to get server's response</param>
        /// <param name="offset">The offset of the file from where client wants to start writing</param>
        /// <param name="data">The data which will be written to server</param>
        /// <returns>
        /// a uint value that specifies the status of response packet.
        /// </returns>
        /// <exception cref="System.InvalidOperationException">Thrown if there is any error occurred</exception>
        public override uint Write(TimeSpan timeout, ulong offset, byte[] data)
        {
            this.internalTimeout = timeout;

            SmbWriteAndxRequestPacket request = smbClient.CreateWriteRequest(this.fid, (uint)offset, data);

            SMB_COM_WRITE_ANDX_Request_SMB_Parameters param = request.SmbParameters;

            // get the high 4 bytes
            param.OffsetHigh = (uint)(offset >> 32);

            request.SmbParameters = param;

            if (this.isSignRequired)
            {
                request.Sign(this.NextSequenceNumber, this.sessionKey);
            }

            uint status = 0;

            this.SendAndExpectSmbPacket(request, internalTimeout, out status);

            return(SmbMessageUtils.CheckStatus(status));
        }