/// <summary>
        /// Read data from memory window
        /// </summary>
        /// <param name="data"></param>
        /// <param name="bufferDescriptor">Buffer Descriptor point to memory windows</param>
        public NtStatus ReadMemoryWindow(byte[] data, RdmaBufferDescriptorV1 bufferDescriptor)
        {
            foreach (SmbdMemoryWindow mw in memoryWindowList)
            {
                if (mw.BufferDescriptor.Token != bufferDescriptor.Token)
                {
                    continue;
                }
                // get memory window
                if (mw.IsValid)
                {
                    NtStatus status = (NtStatus)RdmaEndpoint.ReadFromMemory(mw.MemoryHandlerId, data);
                    return(status);
                }
                return(NtStatus.STATUS_INVALID_PARAMETER_2);
            }

            return(NtStatus.STATUS_INVALID_PARAMETER_2);
        }
        /// <summary>
        /// Receive data over RDMA
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public NtStatus ReceiveData(TimeSpan timeout, out byte[] data)
        {
            SmbdRequestResult item   = GetRequestResult(timeout, RequestType.Receive);
            NtStatus          status = (NtStatus)item.ResultInfo.Status;

            if (status != NtStatus.STATUS_SUCCESS)
            {
                data = null;
                return(status);
            }

            this.LogEvent(string.Format("Receive {0} bytes from entry 0x{1:X}",
                                        item.ResultInfo.BytesTransferred,
                                        item.EntryIndex));

            data   = new byte[item.ResultInfo.BytesTransferred];
            status = (NtStatus)RdmaEndpoint.ReadFromMemory(
                this.receiveEntries[item.EntryIndex].Segment.MemoryHandler,
                data);
            // reset
            this.receiveEntries[receiveIndex].IsOccupied = false;
            return(status);
        }