/// <summary>
        /// Tunnel operations to the shared virtual disk file
        /// </summary>
        /// <typeparam name="ResponseT">Type of the operation response</typeparam>
        /// <param name="isAsyncOperation">Indicate whether the tunnel operation is async or not</param>
        /// <param name="code">Operation code</param>
        /// <param name="requestId">A value that uniquely identifies an operation request and response for all requests sent by this client</param>
        /// <param name="requestStructure">The marshalled tunnel structure of the request</param>
        /// <param name="responseHeader">Tunnel operation header of the response packet</param>
        /// <param name="response">Tunnel operation response of the smb2 response packet</param>
        /// <returns>Status of the smb2 response packet</returns>
        public uint TunnelOperation <ResponseT>(
            bool isAsyncOperation,
            RSVD_TUNNEL_OPERATION_CODE code,
            ulong requestId,
            byte[] requestStructure,
            out SVHDX_TUNNEL_OPERATION_HEADER?responseHeader,
            out ResponseT?response) where ResponseT : struct
        {
            SVHDX_TUNNEL_OPERATION_HEADER header = new SVHDX_TUNNEL_OPERATION_HEADER();

            header.OperationCode = code;
            header.RequestId     = requestId;

            byte[] payload = TypeMarshal.ToBytes(header);

            if (null != requestStructure)
            {
                payload = payload.Concat(requestStructure).ToArray();
            }

            CtlCode_Values ctlCode = isAsyncOperation ? CtlCode_Values.FSCTL_SVHDX_ASYNC_TUNNEL_REQUEST : CtlCode_Values.FSCTL_SVHDX_SYNC_TUNNEL_REQUEST;

            transport.SendIoctlPayload(ctlCode, payload);

            uint smb2Status;

            transport.ExpectIoctlPayload(out smb2Status, out payload);

            response       = null;
            responseHeader = null;
            if (smb2Status != Smb2Status.STATUS_SUCCESS)
            {
                return(smb2Status);
            }

            responseHeader = TypeMarshal.ToStruct <SVHDX_TUNNEL_OPERATION_HEADER>(payload);

            // If the response does not contain Header only, parse the resonse body.
            if (responseHeader.Value.Status == 0 && typeof(ResponseT) != typeof(SVHDX_TUNNEL_OPERATION_HEADER))
            {
                response = TypeMarshal.ToStruct <ResponseT>(payload.Skip(Marshal.SizeOf(responseHeader)).ToArray());
            }
            else
            {
                // The operation failed, so no response body.
                // Or the response only contains header, no response body.
            }

            return(smb2Status);
        }
        /// <summary>
        /// Verify the Tunnel Operation Header
        /// </summary>
        /// <param name="header">The received Tunnel Operation Header</param>
        /// <param name="code">The operation code</param>
        /// <param name="status">The received status</param>
        /// <param name="requestId">The request ID</param>
        public void VerifyTunnelOperationHeader(SVHDX_TUNNEL_OPERATION_HEADER header, RSVD_TUNNEL_OPERATION_CODE code, uint status, ulong requestId)
        {
            BaseTestSite.Assert.AreEqual(
                code,
                header.OperationCode,
                "Operation code should be {0}, actual is {1}", code, header.OperationCode);

            BaseTestSite.Assert.AreEqual(
                status,
                header.Status,
                "Status should be {0}, actual is {1}", GetStatus(status), GetStatus(header.Status));

            BaseTestSite.Assert.AreEqual(
                requestId,
                header.RequestId,
                "The RequestId should be {0}, actual is {1}", requestId, header.RequestId);
        }