/// <summary>
        /// Register memory windows
        /// </summary>
        /// <param name="size">Size of memory to register</param>
        /// <param name="flag"></param>
        /// <param name="reversed">if it is true, little-endian and big-endian will be reversed in bufferDescriptor</param>
        /// <param name="bufferDescriptor">Buffer Descriptor point to memory windows</param>
        /// <returns></returns>
        public NtStatus RegisterMemoryWindow(
            uint size,
            RdmaOperationReadWriteFlag flag,
            bool reversed,
            out RdmaBufferDescriptorV1 bufferDescriptor)
        {
            bufferDescriptor = new RdmaBufferDescriptorV1();

            // regiser the buffer
            SmbdMemoryWindow memoryWindow = new SmbdMemoryWindow();

            memoryWindow.IsValid = true;
            NtStatus status = (NtStatus)rdmaAdapter.RegisterMemory(size, out memoryWindow.MemoryHandlerId);

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

            // create memory window
            SmbdRequest invalidRequest = new SmbdRequest();

            invalidRequest.Type = RequestType.Invalid;
            status = (NtStatus)rdmaAdapter.CreateMemoryWindow(invalidRequest.ResultId,
                                                              out memoryWindow.RdmaMW);
            memoryWindow.InvalidResultId = invalidRequest.ResultId;
            if (status != NtStatus.STATUS_SUCCESS)
            {
                return(status);
            }
            // invalid notification request has been submitted
            requestCount++;
            rdmaNotificationSemaphore.Release();

            // bind
            UInt64 resultId;

            status = (NtStatus)rdmaEndpoint.Bind(
                memoryWindow.MemoryHandlerId,
                memoryWindow.RdmaMW,
                flag,
                reversed,
                out memoryWindow.BufferDescriptor, out resultId);

            if (status != NtStatus.STATUS_SUCCESS)
            {
                return(status);
            }
            lock (locker)
            {
                this.receiveRequestList.Add(invalidRequest);
            }

            SmbdRequestResult requestResult = GetRequestResult(new TimeSpan(0, 0, 5), RequestType.Bind);

            this.LogEvent(string.Format("Bind memory window with result id: {0}. And get notification with id: {1}, status: {2}",
                                        resultId,
                                        requestResult.ResultId,
                                        requestResult.ResultInfo.Status
                                        ));

            status = (NtStatus)requestResult.ResultInfo.Status;
            if (status != NtStatus.STATUS_SUCCESS)
            {
                return(status);
            }

            this.memoryWindowList.Add(memoryWindow);
            bufferDescriptor = memoryWindow.BufferDescriptor;
            return(status);
        }
        /// <summary>
        /// Register memory windows
        /// </summary>
        /// <param name="size">Size of memory to register</param>
        /// <param name="flag"></param>
        /// <param name="reversed">if it is true, little-endian and big-endian will be reversed in bufferDescriptor</param>
        /// <param name="bufferDescriptor">Buffer Descriptor point to memory windows</param>
        /// <returns></returns>
        public NtStatus RegisterMemoryWindow(
            uint size,
            RdmaOperationReadWriteFlag flag,
            bool reversed,
            out RdmaBufferDescriptorV1 bufferDescriptor)
        {
            bufferDescriptor = new RdmaBufferDescriptorV1();

            // regiser the buffer
            SmbdMemoryWindow memoryWindow = new SmbdMemoryWindow();
            memoryWindow.IsValid = true;
            NtStatus status = (NtStatus)rdmaAdapter.RegisterMemory(size, out memoryWindow.MemoryHandlerId);
            if (status != NtStatus.STATUS_SUCCESS)
            {
                return status;
            }

            // create memory window
            SmbdRequest invalidRequest = new SmbdRequest();
            invalidRequest.Type = RequestType.Invalid;
            status = (NtStatus)rdmaAdapter.CreateMemoryWindow(invalidRequest.ResultId,
                out memoryWindow.RdmaMW);
            memoryWindow.InvalidResultId = invalidRequest.ResultId;
            if (status != NtStatus.STATUS_SUCCESS)
            {
                return status;
            }
            // invalid notification request has been submitted
            requestCount++;
            rdmaNotificationSemaphore.Release();

            // bind
            UInt64 resultId;
            status = (NtStatus)rdmaEndpoint.Bind(
                memoryWindow.MemoryHandlerId,
                memoryWindow.RdmaMW,
                flag,
                reversed,
                out memoryWindow.BufferDescriptor, out resultId);

            if (status != NtStatus.STATUS_SUCCESS)
            {
                return status;
            }
            lock (locker)
            {
                this.receiveRequestList.Add(invalidRequest);
            }

            SmbdRequestResult requestResult = GetRequestResult(new TimeSpan(0, 0, 5), RequestType.Bind);
            this.LogEvent(string.Format("Bind memory window with result id: {0}. And get notification with id: {1}, status: {2}",
                resultId,
                requestResult.ResultId,
                requestResult.ResultInfo.Status
                ));

            status = (NtStatus)requestResult.ResultInfo.Status;
            if (status != NtStatus.STATUS_SUCCESS)
            {
                return status;
            }

            this.memoryWindowList.Add(memoryWindow);
            bufferDescriptor = memoryWindow.BufferDescriptor;
            return status;
        }