The SVHDX_META_OPERATION_START_REQUEST packet is sent by the client to start a meta-operation on the shared virtual disk file
        public void BVT_Resize()
        {
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "1.	Client opens a shared virtual disk file and expects success.");
            OpenSharedVHD(TestConfig.NameOfSharedVHDS, RSVD_PROTOCOL_VERSION.RSVD_PROTOCOL_VERSION_2);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "2.	Client sends the tunnel operation SVHDX_META_OPERATION_START_REQUEST to resize a VHDSet file and expects success.");

            SVHDX_META_OPERATION_START_REQUEST startRequest = new SVHDX_META_OPERATION_START_REQUEST();
            startRequest.TransactionId = System.Guid.NewGuid();
            startRequest.OperationType = Operation_Type.SvhdxMetaOperationTypeResize;
            SVHDX_META_OPERATION_RESIZE_VIRTUAL_DISK resizeStructure = new SVHDX_META_OPERATION_RESIZE_VIRTUAL_DISK();
            resizeStructure.NewSize = NewSize;

            byte[] payload = client.CreateTunnelMetaOperationStartResizeRequest(
                startRequest,
                resizeStructure);

            SVHDX_TUNNEL_OPERATION_HEADER? header;
            SVHDX_TUNNEL_OPERATION_HEADER? response;
            //For RSVD_TUNNEL_META_OPERATION_START operation code, the IOCTL code should be FSCTL_SVHDX_ASYNC_TUNNEL_REQUEST
            uint status = client.TunnelOperation<SVHDX_TUNNEL_OPERATION_HEADER>(
                true,//true for Async operation, false for non-async operation
                RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_META_OPERATION_START,
                ++RequestIdentifier,
                payload,
                out header,
                out response);
            BaseTestSite.Assert.AreEqual(
                (uint)Smb2Status.STATUS_SUCCESS,
                status,
                "Ioctl should succeed, actual status: {0}",
                GetStatus(status));
            VerifyTunnelOperationHeader(header.Value, RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_META_OPERATION_START, (uint)RsvdStatus.STATUS_SVHDX_SUCCESS, RequestIdentifier);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "3.	Client closes the file.");
            client.CloseSharedVirtualDisk();

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "4.	Client reopens the virtual disk file and expects VirtualSize is changed to 2G.");

            RequestIdentifier = 0;
            Smb2CreateContextResponse[] serverContextResponse;
            OpenSharedVHD(TestConfig.NameOfSharedVHDS, RSVD_PROTOCOL_VERSION.RSVD_PROTOCOL_VERSION_2, null, true, null, out serverContextResponse, null);

            foreach (var context in serverContextResponse)
            {
                System.Type type = context.GetType();

                if (type.Name == "Smb2CreateSvhdxOpenDeviceContextResponseV2")
                {
                    Smb2CreateSvhdxOpenDeviceContextResponseV2 openDeviceContext = context as Smb2CreateSvhdxOpenDeviceContextResponseV2;

                    VerifyFieldInResponse("VirtualSize", NewSize, openDeviceContext.VirtualSize);
                }
            }

            client.CloseSharedVirtualDisk();
        }
        public void BVT_Extract_VHDSet()
        {
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "1.	Client opens a shared virtual disk file and expects success.");
            OpenSharedVHD(TestConfig.NameOfSharedVHDS, RSVD_PROTOCOL_VERSION.RSVD_PROTOCOL_VERSION_2);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "2.	Client sends tunnel operation SVHDX_META_OPERATION_START_REQUEST to server and expects success.");

            System.Guid snapshotId = System.Guid.NewGuid();
            CreateSnapshot(snapshotId);

            SVHDX_META_OPERATION_START_REQUEST startRequest = new SVHDX_META_OPERATION_START_REQUEST();
            startRequest.TransactionId = System.Guid.NewGuid();
            startRequest.OperationType = Operation_Type.SvhdxMetaOperationTypeExtractVHD;
            SVHDX_META_OPERATION_EXTRACT extract = new SVHDX_META_OPERATION_EXTRACT();
            extract.snapshotType = Snapshot_Type.SvhdxSnapshotTypeVM;
            extract.flags = ExtractSnapshot_Flags.SVHDX_EXTRACT_SNAPSHOTS_FLAG_ZERO;
            extract.SourceSnapshotId = snapshotId;

            //Zero indicates that there MUST be no base snapshot and that the extracted disk will not be a differencing VHD.
            extract.SourceLimitSnapshotId = System.Guid.Empty;

            extract.DestinationFileName = Encoding.Unicode.GetBytes(System.Guid.NewGuid().ToString() + "\0");
            extract.DestinationFileNameLength = (uint)extract.DestinationFileName.Length;

            byte[] payload = client.CreateTunnelMetaOperationStartExtractRequest(
                startRequest,
                extract);

            SVHDX_TUNNEL_OPERATION_HEADER? header;
            SVHDX_TUNNEL_OPERATION_HEADER? response;
            //For RSVD_TUNNEL_META_OPERATION_START operation code, the IOCTL code should be FSCTL_SVHDX_ASYNC_TUNNEL_REQUEST
            uint status = client.TunnelOperation<SVHDX_TUNNEL_OPERATION_HEADER>(
                true, //true for Async operation, false for non-async operation
                RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_META_OPERATION_START,
                ++RequestIdentifier,
                payload,
                out header,
                out response);
            BaseTestSite.Assert.AreEqual(
                (uint)Smb2Status.STATUS_SUCCESS,
                status,
                "Ioctl should succeed, actual status: {0}",
                GetStatus(status));
            VerifyTunnelOperationHeader(header.Value, RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_META_OPERATION_START, (uint)RsvdStatus.STATUS_SVHDX_SUCCESS, RequestIdentifier);

            DeleteSnapshot(snapshotId);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "3.	Client closes the file.");
            client.CloseSharedVirtualDisk();
        }
        public void BVT_Convert_VHDFile_to_VHDSetFile()
        {
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "1.	Client opens a shared virtual disk file and expects success.");
            OpenSharedVHD(TestConfig.NameOfSharedVHDX, RSVD_PROTOCOL_VERSION.RSVD_PROTOCOL_VERSION_2);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "2.	Client sends the tunnel operation SVHDX_META_OPERATION_START_REQUEST to convert a VHD file into a VHDSet file and expects success.");

            SVHDX_META_OPERATION_START_REQUEST startRequest = new SVHDX_META_OPERATION_START_REQUEST();
            startRequest.TransactionId = System.Guid.NewGuid();
            startRequest.OperationType = Operation_Type.SvhdxMetaOperationTypeConvertToVHDSet;
            SVHDX_META_OPERATION_CONVERT_TO_VHDSET convert = new SVHDX_META_OPERATION_CONVERT_TO_VHDSET();
            convert.DestinationVhdSetName = TestConfig.NameOfConvertedSharedVHDS;
            convert.DestinationVhdSetNameLength = (uint)(convert.DestinationVhdSetName.Length + 1) * 2;
            byte[] payload = client.CreateTunnelMetaOperationStartConvertToVHDSetRequest(
                startRequest,
                convert);

            SVHDX_TUNNEL_OPERATION_HEADER? header;
            SVHDX_TUNNEL_OPERATION_HEADER? response;
            //For RSVD_TUNNEL_META_OPERATION_START operation code, the IOCTL code should be FSCTL_SVHDX_ASYNC_TUNNEL_REQUEST
            uint status = client.TunnelOperation<SVHDX_TUNNEL_OPERATION_HEADER>(
                true,//true for Async operation, false for non-async operation
                RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_META_OPERATION_START,
                ++RequestIdentifier,
                payload,
                out header,
                out response);
            BaseTestSite.Assert.AreEqual(
                (uint)Smb2Status.STATUS_SUCCESS,
                status,
                "Ioctl should succeed, actual status: {0}",
                GetStatus(status));
            VerifyTunnelOperationHeader(header.Value, RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_META_OPERATION_START, (uint)RsvdStatus.STATUS_SVHDX_SUCCESS, RequestIdentifier);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "3.	Client closes the file.");
            client.CloseSharedVirtualDisk();

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "4.	Client queris the converted disk info and expects the format is changed successfully.");

            CheckDiskFormat();
        }
        public void BVT_Create_Delete_Checkpoint()
        {
            ulong requestId = 0;
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "1.	Client opens a shared virtual disk file and expects success.");
            OpenSharedVHD(TestConfig.NameOfSharedVHDS, requestId++);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "2.	Client sends the first tunnel operation SVHDX_META_OPERATION_START_REQUEST to create a snapshot, with Stage1 set to Initialize and expects success.");
            SVHDX_META_OPERATION_START_REQUEST startRequest = new SVHDX_META_OPERATION_START_REQUEST();
            startRequest.TransactionId = System.Guid.NewGuid();
            startRequest.OperationType = Operation_Type.SvhdxMetaOperationTypeCreateSnapshot;
            startRequest.Padding = new byte[4];
            SVHDX_META_OPERATION_CREATE_SNAPSHOT createsnapshot = new SVHDX_META_OPERATION_CREATE_SNAPSHOT();
            createsnapshot.SnapshotType = Snapshot_Type.SvhdxSnapshotTypeVM;
            createsnapshot.Flags = Snapshot_Flags.SVHDX_SNAPSHOT_DISK_FLAG_ENABLE_CHANGE_TRACKING;
            createsnapshot.Stage1 = Stage_Values.SvhdxSnapshotStageInitialize;
            createsnapshot.Stage2 = Stage_Values.SvhdxSnapshotStageInvalid;
            createsnapshot.Stage3 = Stage_Values.SvhdxSnapshotStageInvalid;
            createsnapshot.Stage4 = Stage_Values.SvhdxSnapshotStageInvalid;
            createsnapshot.Stage5 = Stage_Values.SvhdxSnapshotStageInvalid;
            createsnapshot.Stage6 = Stage_Values.SvhdxSnapshotStageInvalid;
            createsnapshot.SnapshotId = System.Guid.NewGuid();
            createsnapshot.ParametersPayloadSize = (uint)0x00000000;
            createsnapshot.Padding = new byte[24];
            byte[] payload = client.CreateTunnelMetaOperationStartCreateSnapshotRequest(
                startRequest,
                createsnapshot);
            SVHDX_TUNNEL_OPERATION_HEADER? header;
            SVHDX_TUNNEL_OPERATION_HEADER? response;
            //For RSVD_TUNNEL_META_OPERATION_START operation code, the IOCTL code should be FSCTL_SVHDX_ASYNC_TUNNEL_REQUEST
            uint status = client.TunnelOperation<SVHDX_TUNNEL_OPERATION_HEADER>(
                true,//true for Async operation, false for non-async operation
                RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_META_OPERATION_START,
                requestId,
                payload,
                out header,
                out response);
            BaseTestSite.Assert.AreEqual(
                (uint)Smb2Status.STATUS_SUCCESS,
                status,
                "Ioctl should succeed, actual status: {0}",
                GetStatus(status));
            VerifyTunnelOperationHeader(header.Value, RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_META_OPERATION_START, (uint)RsvdStatus.STATUS_SVHDX_SUCCESS, requestId++);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "3.	Client sends the second tunnel operation SVHDX_META_OPERATION_START_REQUEST to create a snapshot and expects success.");
            createsnapshot.Flags = Snapshot_Flags.SVHDX_SNAPSHOT_FLAG_ZERO;
            createsnapshot.Stage1 = Stage_Values.SvhdxSnapshotStageBlockIO;
            createsnapshot.Stage2 = Stage_Values.SvhdxSnapshotStageSwitchObjectStore;
            createsnapshot.Stage3 = Stage_Values.SvhdxSnapshotStageUnblockIO;
            createsnapshot.Stage4 = Stage_Values.SvhdxSnapshotStageFinalize;
            createsnapshot.Stage5 = Stage_Values.SvhdxSnapshotStageInvalid;
            createsnapshot.Stage6 = Stage_Values.SvhdxSnapshotStageInvalid;
            payload = client.CreateTunnelMetaOperationStartCreateSnapshotRequest(
                startRequest,
                createsnapshot);
            //For RSVD_TUNNEL_META_OPERATION_START operation code, the IOCTL code should be FSCTL_SVHDX_ASYNC_TUNNEL_REQUEST
            status = client.TunnelOperation<SVHDX_TUNNEL_OPERATION_HEADER>(
                true,//true for Async operation, false for non-async operation
                RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_META_OPERATION_START,
                requestId,
                payload,
                out header,
                out response);
            BaseTestSite.Assert.AreEqual(
                (uint)Smb2Status.STATUS_SUCCESS,
                status,
                "Ioctl should succeed, actual status: {0}",
                GetStatus(status));
            VerifyTunnelOperationHeader(header.Value, RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_META_OPERATION_START, (uint)RsvdStatus.STATUS_SVHDX_SUCCESS, requestId++);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "4. Verify the snapshot has been created after the operation.");
            DoUntilSucceed(
                () => CheckSnapshotExisted(ref requestId, client, createsnapshot.SnapshotId),
                TestConfig.Timeout,
                "Retry getting the snapshot to make sure it has been created until succeed within timeout span");

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "5.	Client sends the operation SVHDX_TUNNEL_DELETE_SNAPSHOT_REQUEST to delete a snapshot and expects success.");
            SVHDX_TUNNEL_DELETE_SNAPSHOT_REQUEST deleteRequest = new SVHDX_TUNNEL_DELETE_SNAPSHOT_REQUEST();
            deleteRequest.SnapshotId = createsnapshot.SnapshotId;
            deleteRequest.PersistReference = PersistReference_Flags.PersistReferenceFalse;
            deleteRequest.SnapshotType = Snapshot_Type.SvhdxSnapshotTypeVM;
            payload = client.CreateTunnelMetaOperationDeleteSnapshotRequest(
                deleteRequest);
            SVHDX_TUNNEL_OPERATION_HEADER? deleteResponse;
            status = client.TunnelOperation<SVHDX_TUNNEL_OPERATION_HEADER>(
                false,//true for Async operation, false for non-async operation
                RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_DELETE_SNAPSHOT,
                requestId,
                payload,
                out header,
                out deleteResponse);
            BaseTestSite.Assert.AreEqual(
                (uint)Smb2Status.STATUS_SUCCESS,
                status,
                "Ioctl should succeed, actual status: {0}",
                GetStatus(status));

            VerifyTunnelOperationHeader(header.Value, RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_DELETE_SNAPSHOT, (uint)RsvdStatus.STATUS_SVHDX_SUCCESS, requestId++);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "6.	Client closes the file.");
            client.CloseSharedVirtualDisk();
        }
        public void BVT_ApplySnapshot()
        {
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "1.	Client opens a shared virtual disk file and expects success.");
            OpenSharedVHD(TestConfig.NameOfSharedVHDS, RSVD_PROTOCOL_VERSION.RSVD_PROTOCOL_VERSION_2);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "2. Client reads 512 bytes and saves it for later comparation.");
            byte[] byteBeforeChanged = null;
            uint status = client.Read(0, 512, out byteBeforeChanged);
            BaseTestSite.Assert.AreEqual(
                (uint)0,
                status,
                "Read Status should be {0}, actual is {1}", GetStatus(0), GetStatus(status));

            Guid snapshotId = Guid.NewGuid();
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "3.	Client creates a snapshot.");
            CreateSnapshot(snapshotId);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "4.	Client closes the file.");
            client.CloseSharedVirtualDisk();

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "5.	Client reopens the shared virtual disk file and expects success.");

            RequestIdentifier = 0;
            OpenSharedVHD(TestConfig.NameOfSharedVHDS, RSVD_PROTOCOL_VERSION.RSVD_PROTOCOL_VERSION_2);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "6.	Client sends Write request to change the file and expects success.");
            byte[] payload = Smb2Utility.CreateRandomByteArray(512);
            status = client.Write(0, payload);
            BaseTestSite.Assert.AreEqual(
                (uint)0,
                status,
                "Write Status should be {0}, actual is {1}", GetStatus(0), GetStatus(status));

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "7.	Client sends Apply Snapshot request to apply the previous snapshot.");

            SVHDX_APPLY_SNAPSHOT_PARAMS applySnapshot = new SVHDX_APPLY_SNAPSHOT_PARAMS();
            applySnapshot.SnapshotID = snapshotId;
            applySnapshot.SnapshotType = Snapshot_Type.SvhdxSnapshotTypeVM;
            SVHDX_META_OPERATION_START_REQUEST startRequest = new SVHDX_META_OPERATION_START_REQUEST();
            startRequest.TransactionId = Guid.NewGuid();
            startRequest.OperationType = Operation_Type.SvhdxMetaOperationTypeApplySnapshot;
            payload = client.CreateTunnelMetaOperationStartApplySnapshotRequest(startRequest, applySnapshot);
            SVHDX_TUNNEL_OPERATION_HEADER? header;
            SVHDX_TUNNEL_OPERATION_HEADER? response;
            status = client.TunnelOperation<SVHDX_TUNNEL_OPERATION_HEADER>(
                            true,//true for Async operation, false for non-async operation
                            RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_META_OPERATION_START,
                            ++RequestIdentifier,
                            payload,
                            out header,
                            out response);
            BaseTestSite.Assert.AreEqual(
                (uint)Smb2Status.STATUS_SUCCESS,
                status,
                "Ioctl should succeed, actual status: {0}",
                GetStatus(status));
            VerifyTunnelOperationHeader(header.Value, RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_META_OPERATION_START, (uint)RsvdStatus.STATUS_SVHDX_SUCCESS, RequestIdentifier);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "8.	Client rereads 512 bytes and compares it with the previously saved bytes.");
            byte[] byteAfterApplied = null;
            status = client.Read(0, 512, out byteAfterApplied);
            BaseTestSite.Assert.AreEqual(
                (uint)0,
                status,
                "Read Status should be {0}, actual is {1}", GetStatus(0), GetStatus(status));

            bool equal = ArrayUtility.CompareArrays(byteBeforeChanged, byteAfterApplied);
            BaseTestSite.Assert.AreEqual(
                true,
                equal,
                "The bytes after snapshot applied should be the same with the original.");

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "9.	Client deletes the snapshot.");
            DeleteSnapshot(snapshotId);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "10. Client closes the file.");
            client.CloseSharedVirtualDisk();
        }
        public void BVT_Optimize()
        {
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "1.	Client opens a shared virtual disk file and expects success.");
            OpenSharedVHD(TestConfig.NameOfSharedVHDS, RSVD_PROTOCOL_VERSION.RSVD_PROTOCOL_VERSION_2);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "2.	Client sends the tunnel operation SVHDX_META_OPERATION_START_REQUEST with an Optimize request.");

            SVHDX_META_OPERATION_START_REQUEST startRequest = new SVHDX_META_OPERATION_START_REQUEST();
            startRequest.TransactionId = System.Guid.NewGuid();
            startRequest.OperationType = Operation_Type.SvhdxMetaOperationTypeOptimize;

            byte[] payload = client.CreateTunnelMetaOperationStartOptimizeRequest(
                startRequest);

            SVHDX_TUNNEL_OPERATION_HEADER? header;
            SVHDX_TUNNEL_OPERATION_HEADER? response;
            //For RSVD_TUNNEL_META_OPERATION_START operation code, the IOCTL code should be FSCTL_SVHDX_ASYNC_TUNNEL_REQUEST
            uint status = client.TunnelOperation<SVHDX_TUNNEL_OPERATION_HEADER>(
                true,//true for Async operation, false for non-async operation
                RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_META_OPERATION_START,
                ++RequestIdentifier,
                payload,
                out header,
                out response);
            BaseTestSite.Assert.AreEqual(
                (uint)Smb2Status.STATUS_SUCCESS,
                status,
                "Ioctl should succeed, actual status: {0}",
                GetStatus(status));
            VerifyTunnelOperationHeader(header.Value, RSVD_TUNNEL_OPERATION_CODE.RSVD_TUNNEL_META_OPERATION_START, (uint)RsvdStatus.STATUS_SVHDX_SUCCESS, RequestIdentifier);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "3.	Client closes the file.");
            client.CloseSharedVirtualDisk();
        }