public void NegotiateRequest(ModelDialectRevision maxSmbVersionClientSupported, SigningFlagType signingFlagType, SigningEnabledType signingEnabledType, SigningRequiredType signingRequiredType)
        {
            testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress);

            DialectRevision[] dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(maxSmbVersionClientSupported));
            Packet_Header_Flags_Values headerFlags = (signingFlagType == SigningFlagType.SignedFlagSet) ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE;

            SigningEnabledType resSigningEnabledType = SigningEnabledType.SigningEnabledNotSet;
            SigningRequiredType resSigningRequiredType = SigningRequiredType.SigningRequiredNotSet;
            uint status = testClient.Negotiate(
                headerFlags,
                dialects,
                GetNegotiateSecurityMode(signingEnabledType, signingRequiredType),
                checker: (header, response) =>
                {
                    resSigningEnabledType =
                        response.SecurityMode.HasFlag(NEGOTIATE_Response_SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED) ?
                        SigningEnabledType.SigningEnabledSet : SigningEnabledType.SigningEnabledNotSet;
                    resSigningRequiredType =
                        response.SecurityMode.HasFlag(NEGOTIATE_Response_SecurityMode_Values.NEGOTIATE_SIGNING_REQUIRED) ?
                        SigningRequiredType.SigningRequiredSet : SigningRequiredType.SigningRequiredNotSet;
                });

            NegotiateResponse((ModelSmb2Status)status, resSigningEnabledType, resSigningRequiredType, signingConfig);
        }
Exemplo n.º 2
0
        public void BVT_SMB2Basic_CancelRegisteredChangeNotify()
        {
            uint status;
            string testDirectory = CreateTestDirectory(TestConfig.SutComputerName, TestConfig.BasicFileShare);
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Test directory \"{0}\" was created on share \"{1}\"", testDirectory, TestConfig.BasicFileShare);

            client1 = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            client1.Smb2Client.ChangeNotifyResponseReceived += new Action<FILE_NOTIFY_INFORMATION[],Packet_Header,CHANGE_NOTIFY_Response>(OnChangeNotifyResponseReceived);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start a client to create a file by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT; CREATE");
            client1.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
            status = client1.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
            status = client1.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            uint treeId1;
            status = client1.TreeConnect(uncSharePath, out treeId1);
            Smb2CreateContextResponse[] serverCreateContexts;
            FILEID fileId1;
            status = client1.Create(
                treeId1,
                testDirectory,
                CreateOptions_Values.FILE_DIRECTORY_FILE,
                out fileId1,
                out serverCreateContexts);

            BaseTestSite.Log.Add(
                LogEntryKind.Comment,
                "Client starts to register CHANGE_NOTIFY on directory \"{0}\"", testDirectory);
            client1.ChangeNotify(treeId1, fileId1, CompletionFilter_Values.FILE_NOTIFY_CHANGE_LAST_ACCESS);

            BaseTestSite.Log.Add(
                LogEntryKind.Comment,
                "Client starts to cancel the registered CHANGE_NOTIFY on directory \"{0}\"", testDirectory);
            client1.Cancel();

            BaseTestSite.Assert.IsTrue(
                changeNotificationReceived.WaitOne(TestConfig.WaitTimeoutInMilliseconds),
                "Change notification should be received within {0} milliseconds", TestConfig.WaitTimeoutInMilliseconds);

            BaseTestSite.Assert.AreNotEqual(
                Smb2Status.STATUS_SUCCESS,
                receivedChangeNotifyHeader.Status, "CHANGE_NOTIFY is not expected to success after cancel, actually server returns {0}.",
                Smb2Status.GetStatusCode(receivedChangeNotifyHeader.Status));
            BaseTestSite.CaptureRequirementIfAreEqual(
                Smb2Status.STATUS_CANCELLED,
                receivedChangeNotifyHeader.Status,
                RequirementCategory.STATUS_CANCELLED.Id,
                RequirementCategory.STATUS_CANCELLED.Description);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF");
            client1.Close(treeId1, fileId1);
            client1.TreeDisconnect(treeId1);
            client1.LogOff();
        }
 /// <summary>
 /// Initialize the two clients. And register Oplock/Lease break notification event.
 /// </summary>
 public void Preparation()
 {
     oplockClient = InitializeClient(testConfig.SutIPAddress, out treeIdOplock);
     oplockClient.Smb2Client.OplockBreakNotificationReceived += new Action<Packet_Header, OPLOCK_BREAK_Notification_Packet>(OnLeaseBreakNotificationReceived);
     leaseClient = InitializeClient(testConfig.SutIPAddress, out treeIdLease);
     leaseClient.Smb2Client.LeaseBreakNotificationReceived += new Action<Packet_Header, LEASE_BREAK_Notification_Packet>(OnLeaseBreakNotificationReceived);
     fileName = "MixedOplockLeaseModel_" + Guid.NewGuid() + ".txt";
 }
        public override void Reset()
        {
            base.Reset();

            if (testClient != null)
            {
                testClient.Disconnect();
                testClient = null;
            }
        }
Exemplo n.º 5
0
        public override void Reset()
        {
            base.Reset();

            if (testClient != null)
            {
                testClient.Disconnect();
                testClient = null;
            }
        }
        protected override void TestInitialize()
        {
            base.TestInitialize();

            clientGuid = Guid.NewGuid();

            mainChannelClient        = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            alternativeChannelClient = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);

            ReadIpAddressesFromTestConfig(out clientIps, out serverIps);
        }
Exemplo n.º 7
0
 protected override void TestInitialize()
 {
     base.TestInitialize();
     fileName  = "OpLock" + Guid.NewGuid() + ".txt";
     sharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare);
     client1   = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
     client2   = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
     client1.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
     client2.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
     OpLockNotificationReceived = new ManualResetEvent(false);
 }
Exemplo n.º 8
0
        protected bool TryReadFile(Smb2FunctionalClient client, AccountCredential user, string sharePath, string fileName)
        {
            bool accessSucceed = true;

            BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends NEGOTIATE message.");
            client.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);
            BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends SESSION_SETUP message using account: {0}@{1}.", user.AccountName, user.DomainName);
            client.SessionSetup(TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, user, false);

            uint treeId;

            BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends TREE_CONNECT message to access share: {0}.", sharePath);
            client.TreeConnect(sharePath, out treeId);

            FILEID fileId;

            Smb2CreateContextResponse[] createContexResponse;

            BaseTestSite.Log.Add(LogEntryKind.Debug, "Client sends CREATE request.");
            uint status = client.Create(
                treeId,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out createContexResponse,
                accessMask: AccessMask.FILE_READ_DATA | AccessMask.FILE_READ_ATTRIBUTES,
                createDisposition: CreateDisposition_Values.FILE_OPEN,
                checker: (header, response) =>
            {
                if (header.Status == Smb2Status.STATUS_SUCCESS)
                {
                    BaseTestSite.Log.Add(LogEntryKind.Debug, "Successfully opened the file with Access Mask: FILE_READ_DATA | FILE_READ_ATTRIBUTES.");
                    accessSucceed = true;
                }
                else if (header.Status == Smb2Status.STATUS_ACCESS_DENIED)
                {
                    BaseTestSite.Log.Add(LogEntryKind.Debug, "Fail to open the file with Access Mask: FILE_READ_DATA | FILE_READ_ATTRIBUTES.");
                    accessSucceed = false;
                }
                else
                {
                    BaseTestSite.Assert.Fail("Unexpected error code in CREATE response: {0}", Smb2Status.GetStatusCode(header.Status));
                }
            });

            if (status == Smb2Status.STATUS_SUCCESS)
            {
                BaseTestSite.Log.Add(LogEntryKind.Debug, "Tear down the client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF.");
                client.Close(treeId, fileId);
            }
            client.TreeDisconnect(treeId);
            client.LogOff();
            return(accessSucceed);
        }
        protected override void TestInitialize()
        {
            base.TestInitialize();

            #region Check Applicability
            TestConfig.CheckDialect(DialectRevision.Smb30);
            TestConfig.CheckIOCTL(CtlCode_Values.FSCTL_OFFLOAD_READ, CtlCode_Values.FSCTL_OFFLOAD_WRITE);
            #endregion

            client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
        }
Exemplo n.º 10
0
        /// <summary>
        /// Attempt to trigger LeaseBreakNotification from a separate client
        /// </summary>
        /// <param name="client">Client to trigger LeaseBreakNotification</param>
        /// <param name="requestDialect">Negotiate dialects</param>
        /// <param name="isDirectory">True value indicating to open a directory, false for a file</param>
        /// <param name="requestedLeaseState">LeaseState when open the directory or file</param>
        /// <param name="accessMask">AccessMask when open the directory or file</param>
        private void TriggerBreakFromClient(
            Smb2FunctionalClient client,
            DialectRevision[] requestDialect,
            bool isDirectory,
            LeaseStateValues requestedLeaseState,
            AccessMask accessMask)
        {
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Trigger a lease break notification by accessing same file/directory from a separate client with LeaseState {0} and AccessMask {1}", requestedLeaseState, accessMask);
            #region Negotiate
            status = client.Negotiate(
                requestDialect,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES);
            #endregion

            #region SESSION_SETUP
            status = client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            #endregion

            #region TREE_CONNECT to share
            uint treeId;
            status = client.TreeConnect(uncSharePath, out treeId);
            #endregion

            #region CREATE
            FILEID fileId;
            Smb2CreateContextResponse[] serverCreateContexts;
            status = client.Create(
                treeId,
                isDirectory ? testDirectory : fileName,
                isDirectory ? CreateOptions_Values.FILE_DIRECTORY_FILE : CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE,
                new Smb2CreateContextRequest[]
            {
                new Smb2CreateRequestLeaseV2
                {
                    LeaseKey   = Guid.NewGuid(),
                    LeaseState = requestedLeaseState
                }
            },
                accessMask: accessMask);
            #endregion
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Finish triggering lease break notification");
        }
Exemplo n.º 11
0
        protected override void TestInitialize()
        {
            base.TestInitialize();
            sharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare);
            fileName  = GetTestFileName(sharePath);

            clientBeforeDisconnection = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            clientAfterDisconnection  = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            clientBeforeDisconnection.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
            clientAfterDisconnection.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
        }
        public void ReEstablishResilientOpenRequest(ModelUser user)
        {
            reconnectClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);

            AccountCredential account = testConfig.AccountCredential;

            if (user == ModelUser.DefaultUser)
            {
                account = testConfig.AccountCredential;
            }
            else if (user == ModelUser.DiffUser)
            {
                account = testConfig.NonAdminAccountCredential;
            }

            // Connect to Share
            ConnectToShare(
                Site,
                testConfig,
                reconnectClient,
                new DialectRevision[] { dialect },
                clientGuid,
                account,
                out dialect,
                out treeId);


            // Reconnect to the Open
            Smb2CreateContextResponse[] createContextResponse;

            testConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_DURABLE_HANDLE_RECONNECT);

            uint status = reconnectClient.Create(
                treeId,
                fileName,
                CreateOptions_Values.NONE,
                out fileId,
                out createContextResponse,
                createContexts: new Smb2CreateContextRequest[]
            {
                new Smb2CreateDurableHandleReconnect()
                {
                    Data = fileId
                }
            },
                checker: (header, response) =>
            {
                // do nothing, skip the exception
            }
                );

            ReEstablishResilientOpenResponse((ModelSmb2Status)status);
        }
Exemplo n.º 13
0
        public void SetupConnection(ModelDialectRevision maxSmbVersionClientSupported, ClientSupportsEncryptionType clientSupportsEncryptionType)
        {
            // Set checkEncrypt to false to not check if the response from the server is actually encrypted.
            testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site, checkEncrypt: false);
            testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress);
            testClient.Smb2Client.Disconnected += new Action(OnServerDisconnected);

            DialectRevision[] dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(maxSmbVersionClientSupported));

            //Set capabilities according to isClientSupportsEncryption
            Capabilities_Values commonCapability     = Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES;
            Capabilities_Values encryptionCapability = (clientSupportsEncryptionType == ClientSupportsEncryptionType.ClientSupportsEncryption) ? (commonCapability | Capabilities_Values.GLOBAL_CAP_ENCRYPTION) : commonCapability;

            uint               status;
            DialectRevision    selectedDialect;
            NEGOTIATE_Response?negotiateResponse = null;

            status = testClient.Negotiate(
                dialects,
                testConfig.IsSMB1NegotiateEnabled,
                capabilityValue: encryptionCapability,
                checker: (header, response) =>
            {
                Site.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "{0} should succeed", header.Command);

                negotiateResponse = response;
            },
                ifHandleRejectUnencryptedAccessSeparately: true,
                ifAddGLOBAL_CAP_ENCRYPTION: false,
                addDefaultEncryption: true
                );

            selectedDialect = negotiateResponse.Value.DialectRevision;

            if ((selectedDialect == DialectRevision.Smb30 || selectedDialect == DialectRevision.Smb302) && clientSupportsEncryptionType == ClientSupportsEncryptionType.ClientSupportsEncryption)
            {
                /// TD section 3.3.5.4
                /// SMB2_GLOBAL_CAP_ENCRYPTION if Connection.Dialect is "3.0" or "3.0.2", the server supports encryption,
                /// and SMB2_GLOBAL_CAP_ENCRYPTION is set in the Capabilities field of the request
                Site.Assert.IsTrue(
                    negotiateResponse.Value.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_ENCRYPTION),
                    "SMB2_GLOBAL_CAP_ENCRYPTION should be set in the negotiate response.");
            }
            else
            {
                Site.Assert.IsFalse(
                    negotiateResponse.Value.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_ENCRYPTION),
                    "SMB2_GLOBAL_CAP_ENCRYPTION should not be set in the negotiate response.");
            }
        }
        protected override void TestInitialize()
        {
            base.TestInitialize();

            clientGuid = Guid.NewGuid();

            mainChannelClient        = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            alternativeChannelClient = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);

            fileName = string.Format("{0}_{1}.txt", CurrentTestCaseName, Guid.NewGuid());
            ReadIpAddressesFromTestConfig(out clientIps, out serverIps);
        }
 private void ConnectToShare(Smb2FunctionalClient client, Guid clientGuid, string uncShareName, out uint treeId)
 {
     client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.FileServerNameContainingSharedVHD, TestConfig.FileServerIPContainingSharedVHD);
     client.Negotiate(
         TestConfig.RequestDialects,
         TestConfig.IsSMB1NegotiateEnabled,
         SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED,
         Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES,
         clientGuid);
     client.SessionSetup(TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, false);
     client.TreeConnect(Smb2Utility.GetUncPath(TestConfig.FileServerNameContainingSharedVHD, TestConfig.ShareContainingSharedVHD), out treeId);
 }
Exemplo n.º 16
0
        protected override void TestInitialize()
        {
            base.TestInitialize();

            smb2client = null;

            //The SMB2 server MUST reserve -1 for invalid FileId
            fileId = FILEID.Invalid;

            // The SMB2 server MUST reserve -1 for invalid TreeId.
            treeId = 0xFFFF;
        }
        private void OpenFileAndResilientRequest(
            Smb2FunctionalClient client,
            Guid clientGuid,
            string fileName,
            uint timeoutInMilliSeconds,
            out FILEID fileId)
        {
            uint treeId;

            // connect to share
            ConnectToShare(
                client,
                clientGuid,
                out treeId);
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Connect to share '{0}' on server '{1}'", testConfig.BasicFileShare, testConfig.SutComputerName);

            // open file
            Smb2CreateContextResponse[] createContextResponse;
            client.Create(
                treeId,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out createContextResponse
                );
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Create Open with file name '{0}'", fileName);


            // resiliency request
            Packet_Header  ioCtlHeader;
            IOCTL_Response ioCtlResponse;

            byte[] inputInResponse;
            byte[] outputInResponse;
            client.ResiliencyRequest(
                treeId,
                fileId,
                timeoutInMilliSeconds,
                (uint)Marshal.SizeOf(typeof(NETWORK_RESILIENCY_Request)),
                out ioCtlHeader,
                out ioCtlResponse,
                out inputInResponse,
                out outputInResponse
                );
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Resiliency request with timeout {0} milliseconds", timeoutInMilliSeconds);
        }
        protected override void TestInitialize()
        {
            base.TestInitialize();

            clientGuid           = Guid.NewGuid();
            clientBeforeFailover = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            clientAfterFailover  = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);

            accessIpList = Dns.GetHostAddresses(TestConfig.ClusteredFileServerName);
            uncSharePath = Smb2Utility.GetUncPath(TestConfig.ClusteredFileServerName, TestConfig.ClusteredFileShare);
            contentWrite = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb);
            fileName     = GetTestFileName(uncSharePath);
        }
        protected override void TestInitialize()
        {
            base.TestInitialize();

            clientGuid           = Guid.NewGuid();
            clientBeforeFailover = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            clientAfterFailover  = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);

            accessIpList = Dns.GetHostEntry(TestConfig.ClusteredFileServerName).AddressList;
            uncSharePath = Smb2Utility.GetUncPath(TestConfig.ClusteredFileServerName, TestConfig.ClusteredFileShare);
            contentWrite = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb);
            fileName     = string.Format("{0}_{1}.txt", CurrentTestCaseName, Guid.NewGuid());
        }
Exemplo n.º 20
0
        protected override void TestInitialize()
        {
            base.TestInitialize();

            clientForInitialOpen = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            clientForReOpen      = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);

            appInstanceId = Guid.NewGuid();
            contentWrite  = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb);

            uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare);
            fileName     = GetTestFileName(uncSharePath);
        }
Exemplo n.º 21
0
        private void Compound_RelatedRequests(string fileName, bool isEncrypted)
        {
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Initialize the test client.");
            Smb2FunctionalClient client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            uint treeId;

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Connect to the SMB2 basic share by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT.");
            ConnectToShare(client, out treeId);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Construct Create packet.");
            Smb2CreateRequestPacket createPacket = ConstructCreatePacket(client.SessionId, treeId, fileName);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Construct Write packet, flag FLAGS_RELATED_OPERATIONS is set.");
            Smb2WriteRequestPacket writePacket = ConstructRelatedWritePacket();

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Construct Close packet, flag FLAGS_RELATED_OPERATIONS is set.");
            Smb2CloseRequestPacket closePacket = ConstructRelatedClosePacket();

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Send {0}compounded Create, Write and Close requests to SUT.", isEncrypted ? "encrypted " : "");
            List <Smb2SinglePacket> requestPackets = new List <Smb2SinglePacket>();

            requestPackets.Add(createPacket);
            requestPackets.Add(writePacket);
            requestPackets.Add(closePacket);

            if (isEncrypted)
            {
                // Enable encryption
                client.EnableSessionSigningAndEncryption(enableSigning: testConfig.SendSignedRequest, enableEncryption: true);
            }
            List <Smb2SinglePacket> responsePackets = client.SendAndReceiveCompoundPacket(requestPackets);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Verify responses to the compounded request.");
            foreach (var responsePacket in responsePackets)
            {
                if (TestConfig.Platform == Platform.WindowsServer2016 && responsePacket.Header.Status != Smb2Status.STATUS_SUCCESS)
                {
                }
                else
                {
                    BaseTestSite.Assert.AreEqual(
                        Smb2Status.STATUS_SUCCESS,
                        responsePacket.Header.Status,
                        "{0} should succeed, actual status is {1}", responsePacket.Header.Command, Smb2Status.GetStatusCode(responsePacket.Header.Status));
                }
            }

            client.TreeDisconnect(treeId);
            client.LogOff();
            client.Disconnect();
        }
Exemplo n.º 22
0
        private void OpenFile(Smb2FunctionalClient smbClient, Guid clientGuid, string fileName, out uint treeId, out FILEID fileId)
        {
            ConnectToShare(smbClient, clientGuid, out treeId);
            BaseTestSite.Log.Add(LogEntryKind.Debug, "Connect to share '{0}' on server '{1}'", TestConfig.ShareName, TestConfig.ShareServerName);

            Smb2CreateContextResponse[] createContextResponse;
            smbClient.Create(
                treeId,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out createContextResponse);
            BaseTestSite.Log.Add(LogEntryKind.Debug, "Create Open with file name '{0}'", fileName);
        }
Exemplo n.º 23
0
        private void ConnectToShare(
            Smb2FunctionalClient client,
            Guid clientGuid,
            out uint treeId)
        {
            client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.CAShareServerName, TestConfig.CAShareServerIP);

            // Negotiate
            client.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES,
                clientGuid: clientGuid,
                checker: (header, response) =>
            {
                BaseTestSite.Assert.AreEqual <NtStatus>(
                    NtStatus.STATUS_SUCCESS,
                    (NtStatus)header.Status,
                    "Negotiate should be successfully");

                TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response);
                TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES, response);
            }
                );

            // SMB2 SESSION SETUP
            client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.CAShareServerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            // SMB2 Tree Connect
            client.TreeConnect(
                Smb2Utility.GetUncPath(TestConfig.CAShareServerName, TestConfig.CAShareName),
                out treeId,
                checker: (header, response) =>
            {
                BaseTestSite.Assert.AreEqual <NtStatus>(
                    NtStatus.STATUS_SUCCESS,
                    (NtStatus)header.Status,
                    "TreeConnect should be successfully");

                // Check IsCA
                BaseTestSite.Assert.IsTrue(
                    response.Capabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY),
                    "Share should support capabilities of SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY ");
            });
        }
Exemplo n.º 24
0
        public void InvalidCreateRequestStructureSize()
        {
            uint status;

            client1 = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, this.Site);
            client1.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);

            status = client1.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled);

            status = client1.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            uint treeId;

            status = client1.TreeConnect(uncSharePath, out treeId);
            string fileName = "BVT_SMB2Basic_InvalidCreateRequestStructureSize" + Guid.NewGuid();

            FILEID fileID;

            Smb2CreateContextResponse[] serverCreateContexts;

            // [MS-SMB2] Section 2.2.13 SMB2 CREATE Request
            // StructureSize (2 bytes):  The client MUST set this field to 57, indicating the size of the request structure, not including the header.
            // The client MUST set it to this value regardless of how long Buffer[] actually is in the request being sent.

            // So set the StuctureSize to 58 here to make "the size of the SMB2 CREATE Request is less than specified in the StructureSize field".
            client1.BeforeSendingPacket(ReplacePacketByStructureSize);
            status = client1.Create(
                treeId,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileID,
                out serverCreateContexts,
                checker: (header, response) => { });

            BaseTestSite.Assert.AreEqual(
                Smb2Status.STATUS_INVALID_PARAMETER,
                status,
                "The size of the SMB2 CREATE Request (excluding the SMB2 header) is less than specified in the StructureSize field, then the request MUST be failed with STATUS_ INVALID_PARAMETER");

            client1.TreeDisconnect(treeId);
            client1.LogOff();
        }
        /// <summary>
        /// Negotiate, SessionSetup and TreeConnect
        /// </summary>
        public void SetupConnection(ModelDialectRevision dialect, ModelCapabilities capabilities, SecurityMode_Values securityMode)
        {
            #region Connect to server
            testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress);
            #endregion

            // It MUST be a GUID generated by the client, if the Dialects field contains a value other than 0x0202. Otherwise, the client MUST set this to 0.
            Guid clientGuid = (dialect == ModelDialectRevision.Smb2002) ? Guid.Empty : Guid.NewGuid();

            #region negotiate
            testClient.Negotiate(
                Packet_Header_Flags_Values.NONE,
                Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(dialect)),
                securityMode,
                (Capabilities_Values)capabilities,
                clientGuid,
                (header, response) =>
            {
                Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed", header.Command);
                negotiateResponse = response;
            });
            #endregion

            #region session setup
            testClient.SessionSetup(
                testConfig.DefaultSecurityPackage,
                testConfig.SutComputerName,
                testConfig.AccountCredential,
                testConfig.UseServerGssToken,
                (SESSION_SETUP_Request_SecurityMode_Values)securityMode);
            #endregion

            #region treeconnect
            testClient.TreeConnect(
                Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare),
                out treeId);
            #endregion

            Connection_Dialect            = ModelUtility.GetModelDialectRevision(negotiateResponse.DialectRevision);
            Connection_ClientCapabilities = (Capabilities_Values)capabilities;
            if (dialect >= ModelDialectRevision.Smb30) // GLOBAL_CAP_ENCRYPTION will be added in Functional client when dialect >= SMB30
            {
                Connection_ClientCapabilities |= Capabilities_Values.GLOBAL_CAP_ENCRYPTION;
            }
            Connection_ClientSecurityMode = securityMode;
            Connection_ClientGuid         = clientGuid;
        }
        public void ReadConfig(out ResilientHandleServerConfig config)
        {
            resilientHandleConfig = new ResilientHandleServerConfig
            {
                MaxSmbVersionSupported         = ModelUtility.GetModelDialectRevision(testConfig.MaxSmbVersionSupported),
                IsIoCtlCodeResiliencySupported = testConfig.IsIoCtlCodeSupported(CtlCode_Values.FSCTL_LMR_REQUEST_RESILIENCY),
                Platform = testConfig.Platform >= Platform.WindowsServer2016 ? Platform.WindowsServer2016 : testConfig.Platform
            };
            config = resilientHandleConfig;

            prepareOpenClient = null;
            Site.Log.Add(LogEntryKind.Debug, resilientHandleConfig.ToString());

            // Resilient only applies only to servers that implement the SMB 2.1 or the SMB 3.x dialect family.
            testConfig.CheckDialect(DialectRevision.Smb21);
        }
        /// <summary>
        /// The two client connects to the two IP addresses of scaleout file server
        /// Negotiate, SessionSetup, TreeConnect
        /// </summary>
        private Smb2FunctionalClient InitializeClient(IPAddress ip, out uint treeId)
        {
            Smb2FunctionalClient client = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            client.ConnectToServerOverTCP(ip);
            client.Negotiate(
                Smb2Utility.GetDialects(DialectRevision.Smb21),
                testConfig.IsSMB1NegotiateEnabled);
            client.SessionSetup(
                testConfig.DefaultSecurityPackage,
                testConfig.ScaleOutFileServerName,
                testConfig.AccountCredential,
                testConfig.UseServerGssToken);
            client.TreeConnect(Smb2Utility.GetUncPath(testConfig.ScaleOutFileServerName, testConfig.CAShareName), out treeId);

            return client;
        }
Exemplo n.º 28
0
        private void OplockBreakAcknowledgment(Smb2FunctionalClient client)
        {
            OPLOCK_BREAK_Acknowledgment_OplockLevel_Values acknowledgementOplockLevel = default(OPLOCK_BREAK_Acknowledgment_OplockLevel_Values);

            //OpLockBreakNotifyReceived.OplockLevel can only be one of the next two values, otherwise AssertionError will be got in OnOpLockBreakNotificationReceived
            if (OpLockBreakNotifyReceived.OplockLevel == OPLOCK_BREAK_Notification_Packet_OplockLevel_Values.OPLOCK_LEVEL_II)
            {
                acknowledgementOplockLevel = OPLOCK_BREAK_Acknowledgment_OplockLevel_Values.OPLOCK_LEVEL_II;
            }
            else if (OpLockBreakNotifyReceived.OplockLevel == OPLOCK_BREAK_Notification_Packet_OplockLevel_Values.OPLOCK_LEVEL_NONE)
            {
                acknowledgementOplockLevel = OPLOCK_BREAK_Acknowledgment_OplockLevel_Values.OPLOCK_LEVEL_NONE;
            }

            client.OplockAcknowledgement(treeId, fileId, acknowledgementOplockLevel);
        }
Exemplo n.º 29
0
        public void Send_Multiple_Requests()
        {
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Initialize the test client.");
            Smb2FunctionalClient client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            uint treeId;

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Connect to the SMB2 basic share by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT.");
            ConnectToShare(client, out treeId);

            List <Smb2SinglePacket> requestPackets = new List <Smb2SinglePacket>();

            for (int i = 1; i <= 10; i++)
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Construct the {0} Create packet.", i);
                string fileName = string.Format("FileNew_{0}_{1}.txt", i, Guid.NewGuid());

                Task <Smb2CreateRequestPacket> t1 = Task <Smb2CreateRequestPacket> .Factory.StartNew(() =>
                                                                                                     ConstructCreatePacket(client.SessionId, treeId, fileName));

                requestPackets.Add(t1.Result);
            }

            client.EnableSessionSigningAndEncryption(enableSigning: testConfig.SendSignedRequest, enableEncryption: false);

            Task <List <ulong> > sendRequest = Task <List <ulong> > .Factory.StartNew(() => client.SendCompoundPacket(requestPackets));

            List <Smb2SinglePacket> responsePackets = client.ReceiveCompoundPacket(sendRequest.Result);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Verify responses to the compounded request.");
            foreach (var responsePacket in responsePackets)
            {
                if (TestConfig.Platform == Platform.WindowsServer2016 && responsePacket.Header.Status != Smb2Status.STATUS_SUCCESS)
                {
                }
                else
                {
                    BaseTestSite.Assert.AreEqual(
                        Smb2Status.STATUS_SUCCESS,
                        responsePacket.Header.Status,
                        "{0} should succeed, actual status is {1}", responsePacket.Header.Command, Smb2Status.GetStatusCode(responsePacket.Header.Status));
                }
            }

            client.TreeDisconnect(treeId);
            client.LogOff();
            client.Disconnect();
        }
        private void Initialize()
        {
            smb2ClientMainChannel        = null;
            smb2ClientAlternativeChannel = null;
            prepared = false;

            setIntegrityInfo.ChecksumAlgorithm = FSCTL_SET_INTEGRITY_INFO_INPUT_CHECKSUMALGORITHM.CHECKSUM_TYPE_CRC64;
            setIntegrityInfo.Flags             = FSCTL_SET_INTEGRITY_INFO_INPUT_FLAGS.FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF;
            setIntegrityInfo.Reserved          = FSCTL_SET_INTEGRITY_INFO_INPUT_RESERVED.V1;

            endOfFileInformation.EndOfFile = 2048;
            fileNameMainChannel            = Guid.NewGuid().ToString();
            leaseKeyMainChannel            = Guid.NewGuid();
            clientGuidMainChannel          = Guid.NewGuid();
            createGuidMainChannel          = Guid.NewGuid();
            clientCapabilitiesMainChannel  = Capabilities_Values.NONE;
        }
        public override void Reset()
        {
            try
            {
                testClient.LogOff();
                testClient.Disconnect();
            }
            catch
            {
            }
            finally
            {
                testClient = null;
            }

            base.Reset();
        }
        protected override void TestInitialize()
        {
            base.TestInitialize();

            testConfig = new SqosTestConfig(BaseTestSite);

            BaseTestSite.DefaultProtocolDocShortName = "MS-SQOS";

            BaseTestSite.Log.Add(LogEntryKind.Debug, "SecurityPackage for authentication: " + TestConfig.DefaultSecurityPackage);

            client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            treeId = 0;
            fileId = FILEID.Zero;

            #region Check Applicability
            TestConfig.CheckIOCTL(CtlCode_Values.FSCTL_STORAGE_QOS_CONTROL);
            #endregion
        }
        /// <summary>
        /// Initialize the test client by
        /// ConnectToServer, Negotiate, SessionSetup and TreeConnect
        /// </summary>
        private Smb2FunctionalClient InitializeClient(IPAddress ip, out uint treeId)
        {
            Smb2FunctionalClient client = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);

            client.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, ip);

            client.Negotiate(
                // Model cases only test Dialect lower than 3.11
                Smb2Utility.GetDialects(testConfig.MaxSmbVersionClientSupported < DialectRevision.Smb311 ? testConfig.MaxSmbVersionClientSupported : DialectRevision.Smb302),
                testConfig.IsSMB1NegotiateEnabled);
            client.SessionSetup(
                testConfig.DefaultSecurityPackage,
                testConfig.SutComputerName,
                testConfig.AccountCredential,
                testConfig.UseServerGssToken);
            client.TreeConnect(Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare), out treeId);
            return(client);
        }
        public override void Reset()
        {
            if (smb2ClientMainChannel != null)
            {
                smb2ClientMainChannel.Disconnect();
                smb2ClientMainChannel = null;
            }

            if (smb2ClientAlternativeChannel != null)
            {
                smb2ClientAlternativeChannel.Disconnect();
                smb2ClientAlternativeChannel = null;
            }

            Initialize();

            base.Reset();
        }
        /// <summary>
        /// Negotiate, SessionSetup and TreeConnect
        /// </summary>
        public void SetupConnection(ModelDialectRevision dialect, ModelCapabilities capabilities, SecurityMode_Values securityMode)
        {
            #region Connect to server
            testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress);
            #endregion

            // It MUST be a GUID generated by the client, if the Dialects field contains a value other than 0x0202. Otherwise, the client MUST set this to 0.
            Guid clientGuid = (dialect == ModelDialectRevision.Smb2002) ? Guid.Empty : Guid.NewGuid();

            #region negotiate
            testClient.Negotiate(
                Packet_Header_Flags_Values.NONE,
                Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(dialect)),
                securityMode,
                (Capabilities_Values)capabilities,
                clientGuid,
                (header, response) =>
                {
                    Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed", header.Command);
                    negotiateResponse = response;
                });
            #endregion

            #region session setup
            testClient.SessionSetup(
                testConfig.DefaultSecurityPackage,
                testConfig.SutComputerName,
                testConfig.AccountCredential,
                testConfig.UseServerGssToken,
                (SESSION_SETUP_Request_SecurityMode_Values)securityMode);
            #endregion

            #region treeconnect
            testClient.TreeConnect(
                Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare),
                out treeId);
            #endregion

            Connection_Dialect = ModelUtility.GetModelDialectRevision(negotiateResponse.DialectRevision);
            Connection_ClientCapabilities = (Capabilities_Values)capabilities;
            Connection_ClientSecurityMode = securityMode;
            Connection_ClientGuid = clientGuid;
        }
 /// <summary>
 /// Acknowledge LeaseBreakNotification received from server
 /// </summary>
 /// <param name="client">Client to send the acknowledgement</param>
 /// <param name="treeId">TreeId associated to send the acknowledgement</param>
 /// <param name="leaseBreakNotify">LeaseBreakNotification received from server</param>
 protected virtual void AcknowledgeLeaseBreak(Smb2FunctionalClient client, uint treeId, LEASE_BREAK_Notification_Packet leaseBreakNotify)
 {
     if (receivedLeaseBreakNotify.Flags == LEASE_BREAK_Notification_Packet_Flags_Values.SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED)
     {
         BaseTestSite.Log.Add(
             LogEntryKind.Debug,
             "Server requires an LEASE_BREAK_ACK on this LEASE_BREAK_NOTIFY");
         // Will add verification for response after SDK change
         uint status = client.LeaseBreakAcknowledgment(treeId, leaseBreakNotify.LeaseKey, leaseBreakNotify.NewLeaseState);
         BaseTestSite.Assert.AreEqual(
             Smb2Status.STATUS_SUCCESS,
             status,
             "LeaseBreakAcknowledgement should succeed, actual status is {0}", Smb2Status.GetStatusCode(status));
     }
     else
     {
         BaseTestSite.Log.Add(
             LogEntryKind.Debug,
             "Server does not require an LEASE_BREAK_ACK on this LEASE_BREAK_NOTIFY");
     }
 }
        public void SetupConnection(ModelSessionSecurityContext securityContext)
        {
            testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress);

            // SMB2 Negotiate
            // Model cases only test Dialect lower than 3.11
            DialectRevision[] dialects =
                Smb2Utility.GetDialects(testConfig.MaxSmbVersionClientSupported < DialectRevision.Smb311 ? testConfig.MaxSmbVersionClientSupported : DialectRevision.Smb302);
            testClient.Negotiate(
                dialects,
                testConfig.IsSMB1NegotiateEnabled);

            // SMB2 SESSION SETUP
            AccountCredential account = null;
            switch (securityContext)
            {
                case ModelSessionSecurityContext.Admin:
                    account = testConfig.AccountCredential;
                    break;
                case ModelSessionSecurityContext.NonAdmin:
                    account = testConfig.NonAdminAccountCredential;
                    break;
                default:
                    throw new InvalidOperationException(securityContext + " is not supported.");
            }

            testClient.SessionSetup(
                testConfig.DefaultSecurityPackage,
                testConfig.SutComputerName,
                account,
                testConfig.UseServerGssToken);

            // reset TreeId
            this.treeId = 0;
        }
        private void ClientTearDown(Smb2FunctionalClient client, uint treeId, FILEID fileId)
        {
            status = client.Close(treeId, fileId);

            status = client.TreeDisconnect(treeId);

            status = client.LogOff();
        }
        public void DirectoryLeasing_BreakReadCachingByChildRenamed()
        {
            #region Prepare test directory and test file
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Create test directory and test file.");
            uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare);
            testDirectory = CreateTestDirectory(TestConfig.SutComputerName, TestConfig.BasicFileShare);
            fileName = "DirectoryLeasing_BreakReadCachingByChildRenamed_" + Guid.NewGuid().ToString() + ".txt";
            sutProtocolController.CreateFile(uncSharePath + "\\" + testDirectory, fileName, string.Empty);
            #endregion

            #region Initialize test clients
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Initialize test clients.");

            Guid clientGuidRequestingLease = Guid.NewGuid();
            Smb2FunctionalClient clientRequestingLease = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);

            Guid clientGuidTriggeringBreak = Guid.NewGuid();
            Smb2FunctionalClient clientTriggeringBreak = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);

            clientRequestingLease.Smb2Client.LeaseBreakNotificationReceived +=
                new Action<Packet_Header, LEASE_BREAK_Notification_Packet>(base.OnLeaseBreakNotificationReceived);

            clientRequestingLease.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
            clientTriggeringBreak.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
            #endregion

            #region CREATE an open to request lease
            uint treeIdClientRequestingLease;
            FILEID fileIdClientRequestingLease;
            LeaseStateValues requestedLeaseState = LeaseStateValues.SMB2_LEASE_READ_CACHING;

            // Add expected NewLeaseState
            expectedNewLeaseState = LeaseStateValues.SMB2_LEASE_NONE;

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client attempts to request lease {0} on directory {1}", requestedLeaseState, testDirectory);
            status = CreateOpenFromClient(clientRequestingLease, clientGuidRequestingLease, testDirectory, true, requestedLeaseState, AccessMask.GENERIC_READ, out treeIdClientRequestingLease, out fileIdClientRequestingLease);
            BaseTestSite.Assert.AreEqual(
                Smb2Status.STATUS_SUCCESS,
                status,
                "Create an open to {0} should succeed, actual status is {1}", testDirectory, Smb2Status.GetStatusCode(status));
            #endregion
            // Create a timer that signals the delegate to invoke CheckBreakNotification
            Timer timer = new Timer(base.CheckBreakNotification, treeIdClientRequestingLease, 0, Timeout.Infinite);
            base.clientToAckLeaseBreak = clientRequestingLease;

            #region Attempt to trigger lease break by renaming child item
            uint treeIdClientTriggeringBreak;
            FILEID fileIdClientTriggeringBreak;
            AccessMask accessMaskTrigger = AccessMask.DELETE;
            string targeName = testDirectory + "\\" + fileName;
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "A separate client attempts to access directory {0} to trigger lease break by renaming it", testDirectory);
            status = CreateOpenFromClient(clientTriggeringBreak, clientGuidTriggeringBreak, targeName, false, LeaseStateValues.SMB2_LEASE_NONE, accessMaskTrigger, out treeIdClientTriggeringBreak, out fileIdClientTriggeringBreak);
            BaseTestSite.Assert.AreEqual(
                Smb2Status.STATUS_SUCCESS,
                status,
                "Create an open to {0} should succeed, actual status is {1}", targeName, Smb2Status.GetStatusCode(status));

            #region SetFileAttributes with FileRenameInformation to rename child item
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "SetFileAttributes with FileRenameInformation to rename child item.");

            string newName = "Renamed_" + fileName;
            FileRenameInformation fileRenameInfo;
            fileRenameInfo.ReplaceIfExists = TypeMarshal.ToBytes(false)[0];
            fileRenameInfo.Reserved = new byte[7];
            fileRenameInfo.RootDirectory = FileRenameInformation_RootDirectory_Values.V1;
            fileRenameInfo.FileName = Encoding.Unicode.GetBytes(newName);
            fileRenameInfo.FileNameLength = (uint)fileRenameInfo.FileName.Length;

            byte[] inputBuffer;
            inputBuffer = TypeMarshal.ToBytes<FileRenameInformation>(fileRenameInfo);

            status = clientTriggeringBreak.SetFileAttributes(
                        treeIdClientTriggeringBreak,
                        (byte)FileInformationClasses.FileRenameInformation,
                        fileIdClientTriggeringBreak,
                        inputBuffer,
                        (header, response) => { });
            #endregion

            ClientTearDown(clientTriggeringBreak, treeIdClientTriggeringBreak, fileIdClientTriggeringBreak);
            #endregion
        }
        /// <summary>
        /// Initialize the test client by 
        /// ConnectToServer, Negotiate, SessionSetup and TreeConnect
        /// </summary>
        private Smb2FunctionalClient InitializeClient(IPAddress ip, out uint treeId)
        {
            Smb2FunctionalClient client = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            client.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, ip);

            client.Negotiate(
                // Model cases only test Dialect lower than 3.11
                Smb2Utility.GetDialects(testConfig.MaxSmbVersionClientSupported < DialectRevision.Smb311 ? testConfig.MaxSmbVersionClientSupported : DialectRevision.Smb302),
                testConfig.IsSMB1NegotiateEnabled);
            client.SessionSetup(
                testConfig.DefaultSecurityPackage,
                testConfig.SutComputerName,
                testConfig.AccountCredential,
                testConfig.UseServerGssToken);
            client.TreeConnect(Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare), out treeId);
            return client;
        }
        /// <summary>
        /// Reset all member variables before running next test case
        /// </summary>
        public override void Reset()
        {
            if (oplockClient != null)
            {
                oplockClient.Disconnect();
                oplockClient = null;
            }

            if (leaseClient != null)
            {
                leaseClient.Disconnect();
                leaseClient = null;
            }

            fileName = null;
            breakType = ModelBreakType.NoBreak;
            treeIdOplock = 0;
            treeIdLease = 0;
            alreadyRequested = false;
            grantedLeaseState = LeaseStateValues.SMB2_LEASE_NONE;
            grantedOplockLevel = OplockLevel_Values.OPLOCK_LEVEL_NONE;

            base.Reset();
        }
        /// <summary>
        /// 1. Prepare the test file
        /// The two clients connects to the two Nodes of the scaleout file server, including: Negotiate, SessionSetup, TreeConnect
        /// </summary>
        public void Preparation()
        {
            PrepareTestFile();

            firstClient = InitializeClient(testConfig.ScaleOutFileServerIP1, out treeId1);
            firstClient.Smb2Client.LeaseBreakNotificationReceived += new Action<Packet_Header, LEASE_BREAK_Notification_Packet>(OnLeaseBreakNotificationReceived);

            secondClient = InitializeClient(testConfig.ScaleOutFileServerIP2, out treeId2);
        }
        protected override void TestInitialize()
        {
            base.TestInitialize();

            testConfig = new SqosTestConfig(BaseTestSite);

            BaseTestSite.DefaultProtocolDocShortName = "MS-SQOS";

            BaseTestSite.Log.Add(LogEntryKind.Debug, "SecurityPackage for authentication: " + TestConfig.DefaultSecurityPackage);

            client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            treeId = 0;
            fileId = FILEID.Zero;

            #region Check Applicability
            TestConfig.CheckIOCTL(CtlCode_Values.FSCTL_STORAGE_QOS_CONTROL);
            #endregion
        }
 /// <summary>
 /// Create operation for Open operation
 /// </summary>
 private uint OpenCreate(
     Smb2FunctionalClient client,
     uint treeIdAfterDisconnection,
     string fileName,
     out FILEID fileIdAfterDisconnection,
     out Smb2CreateContextResponse[] serverCreateContexts,
     RequestedOplockLevel_Values requestedOplocklevel,
     Smb2CreateContextRequest[] openContext)
 {
     return client.Create(
         treeIdAfterDisconnection,
         fileName,
         CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
         out fileIdAfterDisconnection,
         out serverCreateContexts,
         requestedOplocklevel,
         openContext,
         shareAccess: ShareAccess_Values.NONE,
         checker: (header, response) =>
         {
         });
 }
        private void FileServerFailoverTest(string server, FileServerType fsType, bool reconnectWithoutFailover = false)
        {
            int ret = 0;
            uint callId = 0;
            IPAddress currentAccessIpAddr = null;
            WITNESS_INTERFACE_INFO registerInterface = new WITNESS_INTERFACE_INFO();
            WITNESS_INTERFACE_LIST interfaceList = new WITNESS_INTERFACE_LIST();

            currentAccessIpAddr = SWNTestUtility.GetCurrentAccessIP(server);
            BaseTestSite.Log.Add(LogEntryKind.Debug, "Get current file server IP: {0}.", currentAccessIpAddr);

            #region Register SWN witness
            if (witnessType == WitnessType.SwnWitness)
            {
                if (TestConfig.IsWindowsPlatform && fsType == FileServerType.ScaleOutFileServer)
                {
                    // Windows Server: when stopping a non-owner node of ScaleOutFS, no notication will be sent by SMB witness.
                    // So get one IP of the owner node of ScaleOutFS to access.
                    string resourceOwnerNode = sutController.GetClusterResourceOwner(server);
                    IPAddress[] ownerIpList = Dns.GetHostEntry(resourceOwnerNode).AddressList;
                    foreach (var ip in ownerIpList)
                    {
                        BaseTestSite.Log.Add(LogEntryKind.Debug, "Owner IP: {0}", ip);
                    }
                    if (!ownerIpList.Contains(currentAccessIpAddr))
                    {
                        currentAccessIpAddr = null;
                        IPAddress[] accessIpList = Dns.GetHostEntry(server).AddressList;
                        foreach (var ip in accessIpList)
                        {
                            if (ownerIpList.Contains(ip))
                            {
                                currentAccessIpAddr = ip;
                                break;
                            }
                        }
                        BaseTestSite.Assert.IsNotNull(currentAccessIpAddr, "IP should not be null.");
                        BaseTestSite.Log.Add(LogEntryKind.Debug, "Get the owner IP {0} as file server IP.", currentAccessIpAddr);
                    }

                    DoUntilSucceed(() => SWNTestUtility.BindServer(swnClientForInterface, currentAccessIpAddr,
                        TestConfig.DomainName, TestConfig.UserName, TestConfig.UserPassword, TestConfig.DefaultSecurityPackage,
                        TestConfig.DefaultRpceAuthenticationLevel, TestConfig.Timeout, resourceOwnerNode), TestConfig.FailoverTimeout,
                        "Retry BindServer until succeed within timeout span");
                }
                else
                {
                    DoUntilSucceed(() => SWNTestUtility.BindServer(swnClientForInterface, currentAccessIpAddr,
                        TestConfig.DomainName, TestConfig.UserName, TestConfig.UserPassword, TestConfig.DefaultSecurityPackage,
                        TestConfig.DefaultRpceAuthenticationLevel, TestConfig.Timeout, server), TestConfig.FailoverTimeout,
                        "Retry BindServer until succeed within timeout span");
                }

                DoUntilSucceed(() =>
                {
                    ret = swnClientForInterface.WitnessrGetInterfaceList(out interfaceList);
                    BaseTestSite.Assert.AreEqual<SwnErrorCode>(
                        SwnErrorCode.ERROR_SUCCESS,
                        (SwnErrorCode)ret,
                        "WitnessrGetInterfaceList returns with result code = 0x{0:x8}", ret);
                    return SWNTestUtility.VerifyInterfaceList(interfaceList, TestConfig.Platform);
                }, TestConfig.FailoverTimeout, "Retry to call WitnessrGetInterfaceList until succeed within timeout span.");

                SWNTestUtility.GetRegisterInterface(interfaceList, out registerInterface);

                DoUntilSucceed(() => SWNTestUtility.BindServer(swnClientForWitness,
                    (registerInterface.Flags & (uint)SwnNodeFlagsValue.IPv4) != 0 ? new IPAddress(registerInterface.IPV4) : SWNTestUtility.ConvertIPV6(registerInterface.IPV6),
                    TestConfig.DomainName, TestConfig.UserName, TestConfig.UserPassword, TestConfig.DefaultSecurityPackage,
                    TestConfig.DefaultRpceAuthenticationLevel, TestConfig.Timeout, registerInterface.InterfaceGroupName), TestConfig.FailoverTimeout,
                    "Retry BindServer until succeed within timeout span");

                string clientName = Guid.NewGuid().ToString();

                BaseTestSite.Log.Add(LogEntryKind.Debug, "Register witness:");
                BaseTestSite.Log.Add(LogEntryKind.Debug, "\tNetName: {0}", SWNTestUtility.GetPrincipleName(TestConfig.DomainName, server));
                BaseTestSite.Log.Add(LogEntryKind.Debug, "\tIPAddress: {0}", currentAccessIpAddr.ToString());
                BaseTestSite.Log.Add(LogEntryKind.Debug, "\tClient Name: {0}", clientName);

                ret = swnClientForWitness.WitnessrRegister(SwnVersion.SWN_VERSION_1, SWNTestUtility.GetPrincipleName(TestConfig.DomainName, server),
                    currentAccessIpAddr.ToString(), clientName, out pContext);
                BaseTestSite.Assert.AreEqual<SwnErrorCode>(
                    SwnErrorCode.ERROR_SUCCESS,
                    (SwnErrorCode)ret,
                    "WitnessrRegister returns with result code = 0x{0:x8}", ret);
                BaseTestSite.Assert.IsNotNull(
                    pContext,
                    "Expect pContext is not null.");

                callId = swnClientForWitness.WitnessrAsyncNotify(pContext);
                BaseTestSite.Assert.AreNotEqual<uint>(
                    0,
                    callId,
                    "WitnessrAsyncNotify returns callId = {0}", callId);
            }
            #endregion

            #region Create a file and write content
            string uncSharePath = Smb2Utility.GetUncPath(server, TestConfig.ClusteredFileShare);
            string content = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb);
            string testDirectory = CreateTestDirectory(uncSharePath);
            string file = Path.Combine(testDirectory, Guid.NewGuid().ToString());
            Guid clientGuid = Guid.NewGuid();
            Guid createGuid = Guid.NewGuid();

            DoUntilSucceed(() => WriteContentBeforeFailover(fsType, server, currentAccessIpAddr, uncSharePath, file, content, clientGuid, createGuid),
                    TestConfig.FailoverTimeout,
                    "Before failover, retry Write content until succeed within timeout span.");
            #endregion

            #region Disable accessed node

            if (TestConfig.IsWindowsPlatform)
            {
                AssignCurrentAccessNode(server, fsType, currentAccessIpAddr);
            }

            if (!reconnectWithoutFailover)
            {
                BaseTestSite.Log.Add(
                    LogEntryKind.TestStep,
                    "Disable owner node for general file server or the node currently provides the access for scale-out file server.");
                FailoverServer(currentAccessIpAddr, server, fsType);
            }

            #endregion

            #region Wait for available server
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Wait for available server.");
            if (witnessType == WitnessType.None)
            {
                if (fsType == FileServerType.GeneralFileServer)
                {
                    currentAccessIpAddr = null;
                    IPAddress[] accessIpList = Dns.GetHostEntry(server).AddressList;
                    DoUntilSucceed(() =>
                    {
                        foreach (IPAddress ipAddress in accessIpList)
                        {
                            Smb2FunctionalClient pingClient = new Smb2FunctionalClient(TestConfig.FailoverTimeout, TestConfig, BaseTestSite);

                            try
                            {
                                pingClient.ConnectToServerOverTCP(ipAddress);
                                pingClient.Disconnect();
                                pingClient = null;

                                currentAccessIpAddr = ipAddress;
                                return true;
                            }
                            catch
                            {
                            }
                        }
                        return false;
                    }, TestConfig.FailoverTimeout, "Retry to ping to server until succeed within timeout span");
                }
                else
                {
                    currentAccessIpAddr = null;

                    IPAddress[] accessIpList = Dns.GetHostEntry(server).AddressList;
                    foreach (IPAddress ipAddress in accessIpList)
                    {
                        if (TestConfig.IsWindowsPlatform)
                        {
                            // When setting failover mode to StopNodeService for Windows, SMB2 servers on two nodes can still be accessed by the client.
                            // So the client needs to get the new node to access it after failover by comparing host name.
                            if (string.Compare(currentAccessNode, Dns.GetHostEntry(ipAddress).HostName, true) == 0)
                            {
                                continue;
                            }
                        }
                        Smb2FunctionalClient pingClient = new Smb2FunctionalClient(TestConfig.FailoverTimeout, TestConfig, BaseTestSite);

                        try
                        {
                            pingClient.ConnectToServerOverTCP(ipAddress);
                            pingClient.Disconnect();
                            pingClient = null;

                            currentAccessIpAddr = ipAddress;
                            break;
                        }
                        catch
                        {
                        }
                    }
                }
            }
            else if (witnessType == WitnessType.SwnWitness)
            {
                // Verifying for notification
                RESP_ASYNC_NOTIFY respNotify;
                do
                {
                    // Wait the notification
                    ret = swnClientForWitness.ExpectWitnessrAsyncNotify(callId, out respNotify);
                    BaseTestSite.Assert.AreEqual<SwnErrorCode>(
                        SwnErrorCode.ERROR_SUCCESS,
                        (SwnErrorCode)ret,
                        "ExpectWitnessrAsyncNotify returns with result code = 0x{0:x8}", ret);
                    SWNTestUtility.PrintNotification(respNotify);

                    RESOURCE_CHANGE[] resourceChangeList;
                    SwnUtility.ParseResourceChange(respNotify, out resourceChangeList);
                    BaseTestSite.Assert.AreEqual<uint>(0x00000001, respNotify.NumberOfMessages, "Expect NumberOfMessages is set to 1.");

                    if (resourceChangeList[0].ChangeType == (uint)SwnResourceChangeType.RESOURCE_STATE_AVAILABLE)
                    {
                        // Verify RESP_ASYNC_NOTIFY, the resource is available
                        SWNTestUtility.VerifyResourceChange(respNotify, SwnResourceChangeType.RESOURCE_STATE_AVAILABLE);
                        break;
                    }

                    // Verify RESP_ASYNC_NOTIFY, the resource is unavailable
                    SWNTestUtility.VerifyResourceChange(respNotify, SwnResourceChangeType.RESOURCE_STATE_UNAVAILABLE);

                    callId = swnClientForWitness.WitnessrAsyncNotify(pContext);
                    BaseTestSite.Assert.AreNotEqual<uint>(0, callId, "WitnessrAsyncNotify returns callId = {0}", callId);
                } while (true);

                ret = swnClientForWitness.WitnessrUnRegister(pContext);
                BaseTestSite.Assert.AreEqual<SwnErrorCode>(
                    SwnErrorCode.ERROR_SUCCESS,
                    (SwnErrorCode)ret,
                    "WitnessrUnRegister returns with result code = 0x{0:x8}", ret);
                pContext = IntPtr.Zero;
                swnClientForWitness.SwnUnbind(TestConfig.Timeout);

                if (fsType == FileServerType.ScaleOutFileServer)
                {
                    // For scale-out file server case, retrieve and use another access IP for connection
                    currentAccessIpAddr =
                        (registerInterface.Flags & (uint)SwnNodeFlagsValue.IPv4) != 0 ? new IPAddress(registerInterface.IPV4) : SWNTestUtility.ConvertIPV6(registerInterface.IPV6);
                }
            }
            #endregion

            #region Read content and close the file
            DoUntilSucceed(() => ReadContentAfterFailover(server, currentAccessIpAddr, uncSharePath, file, content, clientGuid, createGuid),
                    TestConfig.FailoverTimeout,
                    "After failover, retry Read content until succeed within timeout span.");
            #endregion
        }
 private void Logoff(Smb2FunctionalClient client)
 {
     client.LogOff();
     client.Disconnect();
 }
        /// <summary>
        /// Verify if server grant lease state as expected
        /// </summary>
        /// <param name="requestedLeaseState">Requested lease state from client</param>
        /// <param name="expectedGrantedLeaseState">Expected lease state that server granted</param>
        private void VerifyGrantedLeaseState(LeaseStateValues requestedLeaseState, LeaseStateValues expectedGrantedLeaseState)
        {
            Guid clientGuid = Guid.NewGuid();
            string testDirectory = "DirectoryLeasing_GrantedLeaseState_" + clientGuid.ToString();

            #region Connect to share
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Connect to share {0}.", uncSharePath);

            Smb2FunctionalClient client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);

            #region Negotiate
            Capabilities_Values clientCapabilities =
                Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU
                | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES;
            client.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED,
                clientCapabilities,
                clientGuid,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
                {
                    BaseTestSite.Assert.AreEqual(
                        Smb2Status.STATUS_SUCCESS,
                        header.Status,
                        "NEGOTIATE should succeed.");

                    TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response);
                    TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING, response);
                });

            #endregion

            #region SessionSetup
            status = client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            BaseTestSite.Assert.AreEqual(
                Smb2Status.STATUS_SUCCESS,
                status,
                "SessionSetup should succeed, actual status is {0}", Smb2Status.GetStatusCode(status));
            #endregion

            #region TreeConnect
            uint treeId;
            status = client.TreeConnect(uncSharePath, out treeId);

            BaseTestSite.Assert.AreEqual(
                Smb2Status.STATUS_SUCCESS,
                status,
                "TreeConnect should succeed, actual status is {0}", Smb2Status.GetStatusCode(status));
            #endregion
            #endregion

            #region CREATE open to directory with lease
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "CREATE open to directory with lease.");
            Smb2CreateContextResponse[] serverCreateContexts;
            FILEID fileId;
            status = client.Create(
                treeId,
                testDirectory,
                CreateOptions_Values.FILE_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE,
                new Smb2CreateContextRequest[]
                {
                    new Smb2CreateRequestLeaseV2
                    {
                        LeaseKey = clientGuid,
                        LeaseState = requestedLeaseState
                    }
                },
                accessMask: AccessMask.GENERIC_ALL,
                shareAccess: ShareAccess_Values.FILE_SHARE_READ,
                checker: (header, response) => { });

            BaseTestSite.Assert.AreEqual(
                Smb2Status.STATUS_SUCCESS,
                status,
                "Create an open on directory should succeed, actual status is {0}", Smb2Status.GetStatusCode(status));
            #endregion

            #region Verify server granted lease state
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Verify server granted lease state.");

            BaseTestSite.Assert.AreNotEqual(
                null,
                serverCreateContexts,
                "Server should return granted lease state");
            foreach (Smb2CreateContextResponse serverCreateContext in serverCreateContexts)
            {
                Smb2CreateResponseLeaseV2 createResponseLeaseV2 = serverCreateContext as Smb2CreateResponseLeaseV2;
                if (createResponseLeaseV2 != null)
                {
                    BaseTestSite.Assert.AreEqual(
                        expectedGrantedLeaseState,
                        createResponseLeaseV2.LeaseState,
                        "Server granted lease state {0} should be the same as {1}", createResponseLeaseV2.LeaseState, expectedGrantedLeaseState);
                    break;
                }
            }
            #endregion
        }
        /// <summary>
        /// Reset all member variables before running next test case
        /// </summary>
        public override void Reset()
        {
            if (firstClient != null)
            {
                firstClient.Disconnect();
                firstClient = null;
            }

            if (secondClient != null)
            {
                secondClient.Disconnect();
                secondClient = null;
            }

            fileName = null;
            leaseBreakState = LeaseBreakState.NoLeaseBreak;
            treeId1 = 0;
            treeId2 = 0;
            fileId1 = FILEID.Zero;
            fileId2 = FILEID.Zero;
            base.Reset();
        }
        protected override void TestInitialize()
        {
            base.TestInitialize();

            ReadIpAddressesFromTestConfig(out clientIps, out serverIps);
            BaseTestSite.Assert.IsTrue(
                clientIps.Count > 1,
                "Client should have more than one IP address");
            BaseTestSite.Assert.IsTrue(
                serverIps.Count > 1,
                "Server should have more than one IP address");

            mainChannelClient = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            alternativeChannelClient = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);

            clientGuid = Guid.NewGuid();
            uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare);
            fileName = string.Format("{0}_{1}.txt", CurrentTestCaseName, Guid.NewGuid());
            testDirectory = CreateTestDirectory(uncSharePath);
            contentWrite = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb);
        }
 /// <summary>
 /// Create operation for PrepareOpen operation
 /// </summary>
 private void PrepareOpenCreate(
     Smb2FunctionalClient client,
     uint treeIdBeforeDisconnection,
     string fileName,
     out FILEID fileIdBeforDisconnection,
     out Smb2CreateContextResponse[] serverCreateContexts,
     RequestedOplockLevel_Values requestedOplocklevel,
     Smb2CreateContextRequest[] prepareContext)
 {
     client.Create(
         treeIdBeforeDisconnection,
         fileName,
         CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
         out fileIdBeforDisconnection,
         out serverCreateContexts,
         requestedOplocklevel,
         prepareContext,
         shareAccess: ShareAccess_Values.NONE,
         checker: (HASH_HEADER, response) =>
         {
         });
 }
        public void DirectoryLeasing_BreakReadCachingByChildModified()
        {
            #region Prepare test directory and test file
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Create test directory and test file.");
            uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare);
            fileName = "DirectoryLeasing_BreakReadCachingByChildModified_" + Guid.NewGuid().ToString() + ".txt";
            testDirectory = CreateTestDirectory(TestConfig.SutComputerName, TestConfig.BasicFileShare);
            sutProtocolController.CreateFile(uncSharePath + "\\" + testDirectory, fileName, string.Empty);
            #endregion

            #region Initialize test clients
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Initialize test clients.");

            Guid clientGuidRequestingLease = Guid.NewGuid();
            Smb2FunctionalClient clientRequestingLease = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);

            Guid clientGuidTriggeringBreak = Guid.NewGuid();
            Smb2FunctionalClient clientTriggeringBreak = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);

            clientRequestingLease.Smb2Client.LeaseBreakNotificationReceived +=
                new Action<Packet_Header, LEASE_BREAK_Notification_Packet>(base.OnLeaseBreakNotificationReceived);

            clientRequestingLease.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
            clientTriggeringBreak.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
            #endregion

            #region CREATE an open to request lease
            uint treeIdClientRequestingLease;
            FILEID fileIdClientRequestingLease;
            LeaseStateValues requestedLeaseState = LeaseStateValues.SMB2_LEASE_READ_CACHING;

            // Add expected NewLeaseState
            expectedNewLeaseState = LeaseStateValues.SMB2_LEASE_NONE;

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client attempts to request lease {0} on directory {1}", requestedLeaseState, testDirectory);
            status = CreateOpenFromClient(clientRequestingLease, clientGuidRequestingLease, testDirectory, true, requestedLeaseState, AccessMask.GENERIC_READ, out treeIdClientRequestingLease, out fileIdClientRequestingLease);
            BaseTestSite.Assert.AreEqual(
                Smb2Status.STATUS_SUCCESS,
                status,
                "Create an open to {0} should succeed, actual status is {1}", testDirectory, Smb2Status.GetStatusCode(status));
            #endregion
            // Create a timer that signals the delegate to invoke CheckBreakNotification
            Timer timer = new Timer(base.CheckBreakNotification, treeIdClientRequestingLease, 0, Timeout.Infinite);
            base.clientToAckLeaseBreak = clientRequestingLease;

            #region Attempt to trigger lease break by modifying child item
            uint treeIdClientTriggeringBreak;
            FILEID fileIdClientTriggeringBreak;
            AccessMask accessMaskTrigger = AccessMask.GENERIC_WRITE;
            string targetName = testDirectory + "\\" + fileName;
            string contentWrite = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb);
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "A separate client attempts to access directory {0} to trigger lease break by modifying inner file", testDirectory);
            status = CreateOpenFromClient(clientTriggeringBreak, clientGuidTriggeringBreak, targetName, false, LeaseStateValues.SMB2_LEASE_NONE, accessMaskTrigger, out treeIdClientTriggeringBreak, out fileIdClientTriggeringBreak);
            BaseTestSite.Assert.AreEqual(
                Smb2Status.STATUS_SUCCESS,
                status,
                "Create an open to {0} should succeed, actual status is {1}", testDirectory, Smb2Status.GetStatusCode(status));

            status = clientTriggeringBreak.Write(treeIdClientTriggeringBreak, fileIdClientTriggeringBreak, contentWrite);

            ClientTearDown(clientTriggeringBreak, treeIdClientTriggeringBreak, fileIdClientTriggeringBreak);
            #endregion
        }
        /// <summary>
        /// Create an open from client, this include NEGOTIATE and SESSION_SETUP with server, TREE_CONNECT to the share and CREATE an open to file/directory
        /// </summary>
        /// <param name="client">Client used to take the operation</param>
        /// <param name="clientGuid">Client GUID for negotiation</param>
        /// <param name="targetName">File/directory name for the open</param>
        /// <param name="isDirectory">Set true if create open to a directory, set false if create open to a file</param>
        /// <param name="accessMask">Desired access when create the open</param>
        /// <param name="treeId">Out param for tree id used to connect to the share</param>
        /// <param name="fileId">Out param for file id that is associated with the open</param>
        /// <param name="shareAccess">Optional param for share access when create the open</param>
        /// <returns>Status value returned from CREATE request</returns>
        private uint CreateOpenFromClient(Smb2FunctionalClient client, Guid clientGuid, string targetName, bool isDirectory, LeaseStateValues requestLeaseState, AccessMask accessMask, out uint treeId, out FILEID fileId, ShareAccess_Values shareAccess = ShareAccess_Values.FILE_SHARE_DELETE | ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_WRITE)
        {
            #region Negotiate
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client {0} sends NEGOTIATE request with the following capabilities: Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES.", clientGuid.ToString());
            client.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES,
                clientGuid: clientGuid,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
                {
                    BaseTestSite.Assert.AreEqual(
                        Smb2Status.STATUS_SUCCESS,
                        header.Status,
                        "Negotiation is expected success, actually server returns {0}", Smb2Status.GetStatusCode(header.Status));

                    TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response);
                    TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING, response);
                });
            #endregion

            #region SESSION_SETUP
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client {0} sends SESSION_SETUP request.", clientGuid.ToString());
            status = client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            #endregion

            #region TREE_CONNECT to share
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client {0} sends TREE_CONNECT request.", clientGuid.ToString());
            status = client.TreeConnect(uncSharePath, out treeId);
            #endregion

            #region CREATE
            Smb2CreateContextResponse[] serverCreateContexts;
            CreateOptions_Values createOptions;

            if (isDirectory)
            {
                createOptions = CreateOptions_Values.FILE_DIRECTORY_FILE;
            }
            else
            {
                createOptions = CreateOptions_Values.FILE_NON_DIRECTORY_FILE;
            }

            // Include FILE_DELETE_ON_CLOSE if accessMask has DELETE
            if ((accessMask & AccessMask.DELETE) == AccessMask.DELETE)
            {
                createOptions = createOptions | CreateOptions_Values.FILE_DELETE_ON_CLOSE;
            }

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client {0} sends CREATE request with the lease state in SMB2_CREATE_REQUEST_LEASE_V2 set to {1}.", clientGuid.ToString(), requestLeaseState);
            status = client.Create(
                treeId,
                targetName,
                createOptions,
                out fileId,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE,
                new Smb2CreateContextRequest[]
                {
                    new Smb2CreateRequestLeaseV2
                    {
                        LeaseKey = clientGuid,
                        LeaseState = requestLeaseState
                    }
                },
                accessMask: accessMask,
                shareAccess: shareAccess,
                checker: (header, response) => { });

            return status;
            #endregion
        }
        /// <summary>
        /// Common method used to connect to target server, including the following message sequences:
        /// 1. Negotiate
        /// 2. Session Setup
        /// 3. Tree Connect
        /// </summary>
        /// <param name="smb2Dialect"></param>
        /// <param name="client"></param>
        /// <param name="clientGuid"></param>
        /// <param name="account"></param>
        /// <param name="connectShareType"></param>
        /// <param name="treeId"></param>
        /// <param name="clientBeforeDisconnection"></param>
        protected virtual void Connect(DialectRevision smb2Dialect, Smb2FunctionalClient client, Guid clientGuid, AccountCredential account, ConnectShareType connectShareType, out uint treeId, Smb2FunctionalClient clientBeforeDisconnection)
        {
            DialectRevision[] requestDialect = Smb2Utility.GetDialects(smb2Dialect);
            Capabilities_Values clientCapabilities = Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES;
            SecurityMode_Values clientSecurityMode = SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED;

            IPAddress targetIPAddress = (connectShareType == ConnectShareType.CAShare) ? testConfig.CAShareServerIP : testConfig.SutIPAddress;
            string targetServer = (connectShareType == ConnectShareType.CAShare) ? testConfig.CAShareServerName : testConfig.SutComputerName;

            client.ConnectToServer(TestConfig.UnderlyingTransport, targetServer, targetIPAddress);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends NEGOTIATE request.", clientGuid);
            client.Negotiate(
                requestDialect,
                TestConfig.IsSMB1NegotiateEnabled,
                clientSecurityMode,
                clientCapabilities,
                clientGuid);

            if (null != clientBeforeDisconnection)
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends SESSION_SETUP request to reconnect to the previous session.", clientGuid);
                client.ReconnectSessionSetup(
                    clientBeforeDisconnection,
                    testConfig.DefaultSecurityPackage,
                    targetServer,
                    account,
                    testConfig.UseServerGssToken);
            }
            else
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends SESSION_SETUP request.", clientGuid);
                client.SessionSetup(
                    testConfig.DefaultSecurityPackage,
                    targetServer,
                    account,
                    testConfig.UseServerGssToken);
            }

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends TREE_CONNECT request.", clientGuid);
            client.TreeConnect(
                durableHandleUncSharePath,
                out treeId,
                checker: (header, response) =>
                {
                    BaseTestSite.Log.Add(
                        LogEntryKind.Debug,
                        "Capabilities in TREE_CONNECT response: {0}", response.Capabilities);

                    BaseTestSite.Assert.AreEqual(
                        Smb2Status.STATUS_SUCCESS,
                        header.Status,
                        "{0} should be successful", header.Command);

                    if (connectShareType == ConnectShareType.CAShare)
                    {
                        BaseTestSite.Assert.AreEqual(
                            Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY,
                            Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY & response.Capabilities,
                            "The share should have SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY capability");
                    }

                    if (connectShareType == ConnectShareType.BasicShare)
                    {
                        BaseTestSite.Assert.AreNotEqual(
                            Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY,
                            Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY & response.Capabilities,
                            "The share should not have SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY capability");
                    }
                });
        }
        /// <summary>
        /// Read and write file within byte lock range when the file is locked or unlocked
        /// </summary>
        /// <param name="isLocked">Set true to indicate that byte lock range is taken on the file</param>
        /// <param name="serverName">Name of file server to access</param>
        /// <param name="targetFileName">Target file name to read and write</param>
        private void ValidateByteLockRangeFromAnotherClient(bool isLocked, string serverName, string targetFileName)
        {
            uint status = 0;

            Smb2FunctionalClient client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);

            client = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);
            client.ConnectToServer(TestConfig.UnderlyingTransport, serverName, currentAccessIp);

            status = client.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled);

            status = client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                serverName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            uint treeId;
            status = client.TreeConnect(uncSharePath, out treeId);

            Smb2CreateContextResponse[] serverCreateContexts;
            FILEID fileId;
            status = client.Create(
                treeId,
                targetFileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts);

            string data;
            Random random = new Random();
            uint offset = (uint)random.Next(0, TestConfig.WriteBufferLengthInKb * 1024 - 1);
            uint length = (uint)random.Next(0, (int)(TestConfig.WriteBufferLengthInKb * 1024 - offset));
            status = client.Read(treeId, fileId, offset, length, out data);

            status = client.Write(treeId, fileId, contentWrite, checker: (header, response) => { });
            if (isLocked)
            {
                BaseTestSite.Assert.AreNotEqual(
                    Smb2Status.STATUS_SUCCESS,
                    status,
                    "Write content to locked range of file from different client is not expected to success");
                BaseTestSite.CaptureRequirementIfAreEqual(
                    Smb2Status.STATUS_FILE_LOCK_CONFLICT,
                    status,
                    RequirementCategory.STATUS_FILE_LOCK_CONFLICT.Id,
                    RequirementCategory.STATUS_FILE_LOCK_CONFLICT.Description);
            }
            else
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    status,
                    "Write content in file should succeed, actual status is {0}", Smb2Status.GetStatusCode(status));
            }
        }
        public void PrepareOpen(
            ModelDialectRevision clientMaxDialect,
            PersistentBitType persistentBit,
            CAShareType connectToCAShare,
            ModelHandleType modelHandleType,
            OplockLeaseType oplockLeaseType)
        {
            // Lease V2 cases only apply on the server implements SMB 3.x family.
            if (oplockLeaseType == OplockLeaseType.LeaseV2)
                testConfig.CheckDialect(DialectRevision.Smb30);

            // Lease V1 cases only apply on the server implements SMB 2.1 and 3.x family.
            if (oplockLeaseType == OplockLeaseType.LeaseV1)
                testConfig.CheckDialect(DialectRevision.Smb21);

            if ((oplockLeaseType == OplockLeaseType.LeaseV1 || oplockLeaseType == OplockLeaseType.LeaseV2)
                && !testConfig.IsLeasingSupported)
                Site.Assert.Inconclusive("Test case is applicable in servers that support leasing.");

            requestDialect = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(clientMaxDialect));
            clientCapabilities = Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING |
                    Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL;
            if (persistentBit == PersistentBitType.PersistentBitSet)
            {
                clientCapabilities |= Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES;
            }

            clientGuid = Guid.NewGuid();
            requestedContext = oplockLeaseType;
            isCAShare = (connectToCAShare == CAShareType.CAShare);
            IPAddress targetIPAddress;
            string targetServer;

            #region Connect to Common Share or CA Share
            if (!isCAShare)
            {
                sharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare);
                fileName = "PrepareHandle_ConnectTo_CommonShareFile_" + Guid.NewGuid() + ".txt";
                targetIPAddress = testConfig.SutIPAddress;
                targetServer = testConfig.SutComputerName;
            }
            else
            {
                sharePath = Smb2Utility.GetUncPath(testConfig.CAShareServerName, testConfig.CAShareName);
                fileName = "PrepareHandle_ConnectTo_CAShareFile_" + Guid.NewGuid().ToString() + ".txt";
                targetIPAddress = testConfig.CAShareServerIP;
                targetServer = testConfig.CAShareServerName;
            }

            testClientBeforeDisconnection = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClientBeforeDisconnection.CreditGoal = 20;
            testClientBeforeDisconnection.ConnectToServer(testConfig.UnderlyingTransport, targetServer, targetIPAddress);

            testClientBeforeDisconnection.Negotiate(
                requestDialect,
                testConfig.IsSMB1NegotiateEnabled,
                capabilityValue: clientCapabilities,
                clientGuid: clientGuid,
                checker: (header, response) =>
                {
                    if (Smb2Utility.IsSmb3xFamily(response.DialectRevision)
                        && handleConfig.IsPersistentHandleSupported
                        && persistentBit == PersistentBitType.PersistentBitSet)
                    {
                        Site.Assert.IsTrue(
                            response.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES),
                            "The server MUST set SMB2_GLOBAL_CAP_PERSISTENT_HANDLES if Connection.Dialect belongs to the SMB 3.x dialect family, " +
                            "SMB2_GLOBAL_CAP_PERSISTENT_HANDLES is set in the Capabilities field of the request, and the server supports persistent handles. " +
                            "Actual capabilities are {0}", response.Capabilities);
                    }
                });

            testClientBeforeDisconnection.SessionSetup(
                    testConfig.DefaultSecurityPackage,
                    targetServer,
                    testConfig.AccountCredential,
                    testConfig.UseServerGssToken);

            testClientBeforeDisconnection.TreeConnect(sharePath, out treeIdBeforeDisconnection);

            #endregion

            #region Create operation according to the handle type and context
            Smb2CreateContextRequest[] prepareRequestContext = null;
            Smb2CreateContextResponse[] serverCreateContexts = null;
            RequestedOplockLevel_Values requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE;

            switch (oplockLeaseType)
            {
                case OplockLeaseType.LeaseV1:
                    {
                        testConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE);

                        prepareRequestContext = GetPrepareOpenCreateContext(modelHandleType, oplockLeaseType);
                        requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE;
                    }
                    break;
                case OplockLeaseType.LeaseV2:
                    {
                        testConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE_V2);

                        prepareRequestContext = GetPrepareOpenCreateContext(modelHandleType, oplockLeaseType);
                        requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE;
                    }
                    break;

                case OplockLeaseType.BatchOplock:
                    {
                        prepareRequestContext = GetPrepareOpenHandleContext(modelHandleType);
                        requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH;
                    }
                    break;

                case OplockLeaseType.NoOplockOrLease:
                    {
                        prepareRequestContext = GetPrepareOpenHandleContext(modelHandleType);
                        requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE;
                    }
                    break;
            }

            PrepareOpenCreate(
                testClientBeforeDisconnection,
                treeIdBeforeDisconnection,
                fileName,
                out fileIdBeforDisconnection,
                out serverCreateContexts,
                requestedOplockLevel,
                prepareRequestContext);

            #endregion
        }
        /// <summary>
        /// The two client connects to the two IP addresses of scaleout file server
        /// Negotiate, SessionSetup, TreeConnect
        /// </summary>
        private Smb2FunctionalClient InitializeClient(IPAddress ip, out uint treeId)
        {
            Smb2FunctionalClient client = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            client.ConnectToServerOverTCP(ip);
            client.Negotiate(
                Smb2Utility.GetDialects(DialectRevision.Smb21),
                testConfig.IsSMB1NegotiateEnabled);
            client.SessionSetup(
                testConfig.DefaultSecurityPackage,
                testConfig.ScaleOutFileServerName,
                testConfig.AccountCredential,
                testConfig.UseServerGssToken);
            client.TreeConnect(Smb2Utility.GetUncPath(testConfig.ScaleOutFileServerName, testConfig.CAShareName), out treeId);

            return client;
        }
        private void SendCreateRequestWithSpecificAppInstanceversion(
            Smb2FunctionalClient client,
            Guid appInstanceId,
            ulong? appInstanceVersionHigh,
            ulong? appInstanceVersionLow,
            DialectRevision dialect,
            uint expectedCreateResponseStatus,
            out uint treeId,
            out FILEID fileId
            )
        {
            #region Client connects to Server
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client connects to the file server by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT");
            client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress, TestConfig.ClientNic1IPAddress);
            client.Negotiate(Smb2Utility.GetDialects(dialect), TestConfig.IsSMB1NegotiateEnabled);
            client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            client.TreeConnect(uncSharePath, out treeId);

            Smb2CreateContextResponse[] serverCreateContexts;
            Smb2CreateAppInstanceVersion appInstanceVersion = new Smb2CreateAppInstanceVersion();
            Smb2CreateContextRequest[] clientCreateContexts;

            if (appInstanceVersionHigh.HasValue && appInstanceVersionLow.HasValue)
            {
                appInstanceVersion.AppInstanceVersionHigh = appInstanceVersionHigh.Value;
                appInstanceVersion.AppInstanceVersionLow = appInstanceVersionLow.Value;
                clientCreateContexts =
                new Smb2CreateContextRequest[] {
                    new Smb2CreateAppInstanceId
                    {
                        AppInstanceId = appInstanceId
                    },
                    appInstanceVersion
                };
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends CREATE request with AppInstanceVersionHigh = {0}, AppInstanceVersionLow = {1}.", appInstanceVersion.AppInstanceVersionHigh, appInstanceVersion.AppInstanceVersionLow);
            }
            else
            {
                clientCreateContexts =
                new Smb2CreateContextRequest[] {
                    new Smb2CreateAppInstanceId
                    {
                        AppInstanceId = appInstanceId
                    }
                };
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends CREATE request without AppInstanceVersion.");
            }

            client.Create(
                treeId,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                clientCreateContexts,
                shareAccess: ShareAccess_Values.NONE,
                checker: (header, response) =>
                {
                    BaseTestSite.Assert.AreEqual(
                        expectedCreateResponseStatus,
                        header.Status,
                        (expectedCreateResponseStatus == Smb2Status.STATUS_SUCCESS ?
                        "The open will be closed. Create should succeed. Actually server returns with {0}."
                        : "The open cannot be closed. Create should not succeed. Actually server returns with {0}."),
                        Smb2Status.GetStatusCode(header.Status));
                });

            #endregion
        }
        public void ReconnectOpenRequest(
            DurableV1ReconnectContext durableV1ReconnectContext,
            DurableV2ReconnectContext durableV2ReconnectContext,
            OplockLeaseType oplockLeaseType,
            LeaseKeyDifferentialType leaseKeyDifferentialType,
            ClientIdType clientIdType,
            CreateGuidType createGuidType)
        {
            if ((oplockLeaseType == OplockLeaseType.LeaseV1 || oplockLeaseType == OplockLeaseType.LeaseV2)
                && !testConfig.IsLeasingSupported)
                Site.Assert.Inconclusive("Test case is applicable in servers that support leasing.");

            bool isSameLeaseKey = (leaseKeyDifferentialType == LeaseKeyDifferentialType.SameLeaseKey);
            bool isSameClient = (clientIdType == ClientIdType.SameClient);
            bool isSameCreateGuid = (createGuidType == CreateGuidType.SameCreateGuid);

            FILEID fileIdAfterDisconnection;
            Smb2CreateContextResponse[] serverCreateContexts;
            IPAddress targetIPAddress;
            string targetServer;
            string targetShare;

            #region Construct Create Contexts
            Smb2CreateContextRequest[] smb2CreateContextRequest = GetOpenFileCreateContext(
                DurableV1RequestContext.DurableV1RequestContextNotExist,
                DurableV2RequestContext.DurableV2RequestContextNotExist,
                durableV1ReconnectContext,
                durableV2ReconnectContext,
                oplockLeaseType,
                isSameLeaseKey,
                isSameCreateGuid);
            #endregion

            #region Client reconnect to server

            Site.Log.Add(LogEntryKind.Debug, "Client reconnect to server");

            #region Reconnect to Common Share or CA Share
            if (!isCAShare)
            {
                targetIPAddress = testConfig.SutIPAddress;
                targetServer = testConfig.SutComputerName;
                targetShare = testConfig.BasicFileShare;
            }
            else
            {
                targetIPAddress = testConfig.CAShareServerIP;
                targetServer = testConfig.CAShareServerName;
                targetShare = testConfig.CAShareName;
            }

            // Connect to Server
            testClientAfterDisconnection = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClientAfterDisconnection.CreditGoal = 10;
            testClientAfterDisconnection.ConnectToServer(testConfig.UnderlyingTransport, targetServer, targetIPAddress);

            // Negotiate
            testClientAfterDisconnection.Negotiate(
                requestDialect,
                testConfig.IsSMB1NegotiateEnabled,
                capabilityValue: clientCapabilities,
                // If the reconnect use the same client guid, then keep client guid the same value, otherwise use a new client guid.
                clientGuid: (isSameClient ? clientGuid : Guid.NewGuid()));

            uint status = testClientAfterDisconnection.SessionSetup(
                testConfig.DefaultSecurityPackage,
                targetServer,
                testConfig.AccountCredential,
                testConfig.UseServerGssToken);
            Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "Reconnect Session Setup should be successful, actual status is {0}", Smb2Status.GetStatusCode(status));

            // TreeConnect
            testClientAfterDisconnection.TreeConnect(sharePath, out treeIdAfterDisconnection);

            #endregion

            #region Send Create request according to different context combination

            RequestedOplockLevel_Values requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE;
            switch (oplockLeaseType)
            {
                case OplockLeaseType.NoOplockOrLease:
                    {
                        requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE;
                    }
                    break;

                case OplockLeaseType.BatchOplock:
                    {
                        requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH;
                    }
                    break;

                case OplockLeaseType.LeaseV1:
                case OplockLeaseType.LeaseV2:
                    {
                        requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE;
                    }
                    break;
            }

            status = OpenCreate(
                testClientAfterDisconnection,
                treeIdAfterDisconnection,
                fileName,
                out fileIdAfterDisconnection,
                out serverCreateContexts,
                requestedOplockLevel,
                smb2CreateContextRequest);

            #endregion

            DurableHandleResponseContext durableHandleResponse;
            LeaseResponseContext leaseResponse;
            CheckResponseContexts(serverCreateContexts, out durableHandleResponse, out leaseResponse);
            OpenResponse((ModelSmb2Status)status, durableHandleResponse, leaseResponse, handleConfig);

            testClientAfterDisconnection.TreeDisconnect(treeIdAfterDisconnection);
            testClientAfterDisconnection.LogOff();

            #endregion
        }
        public void DirectoryLeasing_BreakHandleCachingByParentDeleted()
        {
            #region Prepare test directory
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Create test directory.");
            uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare);
            string parentDirectory = "ParentDirectory_" + Guid.NewGuid().ToString();
            sutProtocolController.CreateDirectory(uncSharePath, parentDirectory);
            testDirectory = CreateTestDirectory(TestConfig.SutComputerName, TestConfig.BasicFileShare + "\\" + parentDirectory);
            #endregion

            #region Initialize test clients
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Initialize test clients.");

            Guid clientGuidRequestingLease = Guid.NewGuid();
            Smb2FunctionalClient clientRequestingLease = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);

            Guid clientGuidTriggeringBreak = Guid.NewGuid();
            Smb2FunctionalClient clientTriggeringBreak = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);

            clientRequestingLease.Smb2Client.LeaseBreakNotificationReceived +=
                new Action<Packet_Header, LEASE_BREAK_Notification_Packet>(base.OnLeaseBreakNotificationReceived);

            clientRequestingLease.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
            clientTriggeringBreak.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);
            #endregion

            #region CREATE an open to request lease
            uint treeIdClientRequestingLease;
            FILEID fileIdClientRequestingLease;
            string targetName = parentDirectory + "\\" + testDirectory;
            LeaseStateValues requestedLeaseState = LeaseStateValues.SMB2_LEASE_READ_CACHING | LeaseStateValues.SMB2_LEASE_HANDLE_CACHING;

            // Add expected NewLeaseState
            expectedNewLeaseState = LeaseStateValues.SMB2_LEASE_READ_CACHING;

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client attempts to request lease {0} on directory {1}", requestedLeaseState, testDirectory);
            status = CreateOpenFromClient(clientRequestingLease, clientGuidRequestingLease, targetName, true, requestedLeaseState, AccessMask.GENERIC_READ, out treeIdClientRequestingLease, out fileIdClientRequestingLease);
            BaseTestSite.Assert.AreEqual(
                Smb2Status.STATUS_SUCCESS,
                status,
                "Create an open to {0} should succeed, actual status is {1}", testDirectory, Smb2Status.GetStatusCode(status));
            #endregion
            // Create a timer that signals the delegate to invoke CheckBreakNotification
            Timer timer = new Timer(base.CheckBreakNotification, treeIdClientRequestingLease, 0, Timeout.Infinite);
            base.clientToAckLeaseBreak = clientRequestingLease;

            #region Attempt to trigger lease break by deleting parent directory
            uint treeIdClientTriggeringBreak;
            FILEID fileIdClientTriggeringBreak;
            AccessMask accessMaskTrigger = AccessMask.DELETE;
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "A separate client attempts to trigger lease break by deleting its parent directory");
            status = CreateOpenFromClient(clientTriggeringBreak, clientGuidTriggeringBreak, parentDirectory, true, LeaseStateValues.SMB2_LEASE_NONE, accessMaskTrigger, out treeIdClientTriggeringBreak, out fileIdClientTriggeringBreak);
            BaseTestSite.Assert.AreEqual(
                Smb2Status.STATUS_SUCCESS,
                status,
                "Create an open to {0} should succeed", parentDirectory);

            #region set FileDispositionInformation for deletion
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Set FileDispositionInformation for deletion.");

            FileDispositionInformation fileDispositionInfo;
            fileDispositionInfo.DeletePending = 1;  // Set 1 to indicate directory SHOULD be delted when the open closed
            byte[] inputBuffer = TypeMarshal.ToBytes<FileDispositionInformation>(fileDispositionInfo);
            status = clientTriggeringBreak.SetFileAttributes(
                        treeIdClientTriggeringBreak,
                        (byte)FileInformationClasses.FileDispositionInformation,
                        fileIdClientTriggeringBreak,
                        inputBuffer,
                        (header, response) =>
                        {
                            BaseTestSite.Assert.AreNotEqual(
                                Smb2Status.STATUS_SUCCESS,
                                header.Status,
                                "Setting FileDispositionInformation to the parent directory for deletion when child is opened by others is not expected to SUCCESS. " +
                                "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status));
                            BaseTestSite.CaptureRequirementIfAreEqual(
                                Smb2Status.STATUS_DIRECTORY_NOT_EMPTY,
                                header.Status,
                                RequirementCategory.STATUS_DIRECTORY_NOT_EMPTY.Id,
                                RequirementCategory.STATUS_DIRECTORY_NOT_EMPTY.Description);
                        });

            status = clientTriggeringBreak.Close(treeIdClientTriggeringBreak, fileIdClientTriggeringBreak);
            #endregion

            #region CREATE an open to parent directory again
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "CREATE an open to parent directory again.");

            // Currently we need an additional CREATE to open the parent directory to trigger the lease break
            // which is the same way when Windows attempt to delete the parent directory when child is opened by others
            Smb2CreateContextResponse[] serverCreateContexts;
            status = clientTriggeringBreak.Create(
                treeIdClientTriggeringBreak,
                targetName,
                CreateOptions_Values.FILE_DIRECTORY_FILE | CreateOptions_Values.FILE_DELETE_ON_CLOSE,
                out fileIdClientTriggeringBreak,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE,
                new Smb2CreateContextRequest[]
                {
                    new Smb2CreateRequestLeaseV2
                    {
                        LeaseKey = clientGuidTriggeringBreak,
                        LeaseState = LeaseStateValues.SMB2_LEASE_NONE
                    }
                },
                accessMask: accessMaskTrigger);
            #endregion
            #endregion
        }
        public void OpenRequest(
            ModelDialectRevision clientMaxDialect,
            PersistentBitType persistentBit,
            CAShareType connectToCAShare,
            OplockLeaseType oplockLeaseType,
            DurableV1RequestContext durableV1RequestContext,
            DurableV2RequestContext durableV2RequestContext,
            DurableV1ReconnectContext durableV1ReconnectContext,
            DurableV2ReconnectContext durableV2ReconnectContext)
        {
            requestDialect = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(clientMaxDialect));
            clientCapabilities = Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING |
                    Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL;
            if (persistentBit == PersistentBitType.PersistentBitSet)
            {
                clientCapabilities |= Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES;
            }

            clientGuid = Guid.NewGuid();
            requestedContext = oplockLeaseType;
            isCAShare = (connectToCAShare == CAShareType.CAShare);
            IPAddress targetIPAddress;
            string targetServer;

            #region Connect to Common Share or CA Share
            if (!isCAShare)
            {
                sharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare);
                fileName = "PrepareHandle_ConnectTo_CommonShareFile_" + Guid.NewGuid() + ".txt";
                targetIPAddress = testConfig.SutIPAddress;
                targetServer = testConfig.SutComputerName;
            }
            else
            {
                sharePath = Smb2Utility.GetUncPath(testConfig.CAShareServerName, testConfig.CAShareName);
                fileName = "PrepareHandle_ConnectTo_CAShareFile_" + Guid.NewGuid().ToString() + ".txt";
                targetIPAddress = testConfig.CAShareServerIP;
                targetServer = testConfig.CAShareServerName;
            }

            testClientBeforeDisconnection = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClientBeforeDisconnection.CreditGoal = 20;
            testClientBeforeDisconnection.ConnectToServer(testConfig.UnderlyingTransport, targetServer, targetIPAddress);

            testClientBeforeDisconnection.Negotiate(
                requestDialect,
                testConfig.IsSMB1NegotiateEnabled,
                capabilityValue: clientCapabilities,
                clientGuid: clientGuid,
                checker: (header, response) =>
                {
                    if (Smb2Utility.IsSmb3xFamily(response.DialectRevision)
                        && handleConfig.IsPersistentHandleSupported
                        && persistentBit == PersistentBitType.PersistentBitSet)
                    {
                        Site.Assert.IsTrue(
                            response.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES),
                            "The server MUST set SMB2_GLOBAL_CAP_PERSISTENT_HANDLES if Connection.Dialect belongs to the SMB 3.x dialect family, " +
                            "SMB2_GLOBAL_CAP_PERSISTENT_HANDLES is set in the Capabilities field of the request, and the server supports persistent handles. " +
                            "Actual capabilities are {0}", response.Capabilities);
                    }
                });

            testClientBeforeDisconnection.SessionSetup(
                    testConfig.DefaultSecurityPackage,
                    targetServer,
                    testConfig.AccountCredential,
                    testConfig.UseServerGssToken);

            testClientBeforeDisconnection.TreeConnect(sharePath, out treeIdBeforeDisconnection);

            #endregion

            #region Construct Create Contexts
            Smb2CreateContextRequest[] smb2CreateContextRequest = GetOpenFileCreateContext(
                durableV1RequestContext,
                durableV2RequestContext,
                durableV1ReconnectContext,
                durableV2ReconnectContext,
                oplockLeaseType,
                false,
                false);
            #endregion

            #region Send Create request according to different context combination
            RequestedOplockLevel_Values requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE;
            switch (oplockLeaseType)
            {
                case OplockLeaseType.NoOplockOrLease:
                    {
                        requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE;
                    }
                    break;

                case OplockLeaseType.BatchOplock:
                    {
                        requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH;
                    }
                    break;

                case OplockLeaseType.LeaseV1:
                case OplockLeaseType.LeaseV2:
                    {
                        requestedOplockLevel = RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE;
                    }
                    break;
            }

            FILEID fileId;
            Smb2CreateContextResponse[] serverCreateContexts;
            uint status = OpenCreate(
                testClientBeforeDisconnection,
                treeIdBeforeDisconnection,
                fileName,
                out fileId,
                out serverCreateContexts,
                requestedOplockLevel,
                smb2CreateContextRequest);

            #endregion

            DurableHandleResponseContext durableHandleResponse;
            LeaseResponseContext leaseResponse;
            CheckResponseContexts(serverCreateContexts, out durableHandleResponse, out leaseResponse);
            OpenResponse((ModelSmb2Status)status, durableHandleResponse, leaseResponse, handleConfig);

            testClientBeforeDisconnection.TreeDisconnect(treeIdAfterDisconnection, (header, response) => { });
            testClientBeforeDisconnection.LogOff();
        }