private void InitializeClient(LeasingClientInfo clientInfo, ModelDialectRevision dialect, bool isClientSupportDirectoryLeasing = false)
        {
            #region Connect to server
            switch (testConfig.UnderlyingTransport)
            {
                case Smb2TransportType.Tcp:
                    Site.Assert.IsTrue(
                        testConfig.SutIPAddress != null && testConfig.SutIPAddress != System.Net.IPAddress.None,
                        "Server IP should not be empty when transport type is TCP.");
                    Site.Log.Add(LogEntryKind.Debug, "Connect to server {0} over TCP", testConfig.SutIPAddress.ToString());
                    clientInfo.Client.ConnectOverTCP(testConfig.SutIPAddress);
                    break;
                case Smb2TransportType.NetBios:
                    Site.Assert.IsFalse(string.IsNullOrEmpty(testConfig.SutComputerName), "Server name should not be null when transport type is NetBIOS.");
                    Site.Log.Add(LogEntryKind.Debug, "Connect to server {0} over NetBios", testConfig.SutComputerName);
                    clientInfo.Client.ConnectOverNetbios(testConfig.SutComputerName);
                    break;
                default:
                    Site.Assert.Fail("The transport type is {0}, but currently only Tcp and NetBIOS are supported.", testConfig.UnderlyingTransport);
                    break;
            }
            #endregion

            uint status = 0;
            Packet_Header responseHeader = new Packet_Header();
            DialectRevision selectedDialect;
            DialectRevision[] dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(dialect));
            NEGOTIATE_Response negotiatePayload;

            #region Negotiate
            status = clientInfo.Client.Negotiate(0, 1, Packet_Header_Flags_Values.NONE, clientInfo.MessageId++,
                dialects, SecurityMode_Values.NONE, isClientSupportDirectoryLeasing ? Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING : Capabilities_Values.NONE,
                clientInfo.ClientGuid,
                out selectedDialect,
                out clientInfo.ServerGssToken,
                out responseHeader,
                out negotiatePayload);
            Site.Assert.AreEqual(ModelUtility.GetDialectRevision(dialect), negotiatePayload.DialectRevision,
                "DialectRevision 0x{0:x4} is expected.", (ushort)ModelUtility.GetDialectRevision(dialect));
            Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "Negotiation is expected success");
            clientInfo.Dialect = selectedDialect;

            #region Validate Negotiate Response
            if (Smb2Utility.IsSmb3xFamily(selectedDialect))
            {
                Site.Assert.AreEqual<bool>(leasingConfig.IsLeasingSupported,
                    negotiatePayload.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_LEASING),
                    "Expect that the Capabilities in the response {0} SMB2_GLOBAL_CAP_LEASING 0x00000002.", leasingConfig.IsLeasingSupported ? "contains" : "does not contain");
                Site.Assert.AreEqual<bool>(leasingConfig.IsDirectoryLeasingSupported & isClientSupportDirectoryLeasing,
                    negotiatePayload.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING),
                    "Expect that the Capabilities in the response {0} SMB2_GLOBAL_CAP_DIRECTORY_LEASING 0x00000020.",
                    leasingConfig.IsDirectoryLeasingSupported & isClientSupportDirectoryLeasing ? "contains" : "does not contain");
            }
            else if (selectedDialect == DialectRevision.Smb21)
            {
                Site.Assert.AreEqual<bool>(leasingConfig.IsLeasingSupported,
                    negotiatePayload.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_LEASING),
                    "Expect that the Capabilities in the response {0} SMB2_GLOBAL_CAP_LEASING 0x00000002.", leasingConfig.IsLeasingSupported ? "contains" : "does not contain");
                Site.Assert.IsFalse(negotiatePayload.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING),
                    "Expect that the Capabilities in the response does not contain SMB2_GLOBAL_CAP_DIRECTORY_LEASING 0x00000020.");
            }
            else
            {
                Site.Assert.IsFalse(negotiatePayload.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_LEASING),
                    "Expect that the Capabilities in the response does not contain SMB2_GLOBAL_CAP_LEASING 0x00000002.");
                Site.Assert.IsFalse(negotiatePayload.Capabilities.HasFlag(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING),
                    "Expect that the Capabilities in the response does not contain SMB2_GLOBAL_CAP_DIRECTORY_LEASING 0x00000020.");
            }
            #endregion
            #endregion

            #region SESSION_SETUP
            Packet_Header header;
            SESSION_SETUP_Response sessionSetupResponse;

            SspiClientSecurityContext sspiClientGss =
                new SspiClientSecurityContext(
                    testConfig.DefaultSecurityPackage,
                    testConfig.AccountCredential,
                    Smb2Utility.GetCifsServicePrincipalName(testConfig.SutComputerName),
                    ClientSecurityContextAttribute.None,
                    SecurityTargetDataRepresentation.SecurityNativeDrep);

            // Server GSS token is used only for Negotiate authentication when enabled
            if (testConfig.DefaultSecurityPackage == SecurityPackageType.Negotiate && testConfig.UseServerGssToken)
                sspiClientGss.Initialize(clientInfo.ServerGssToken);
            else
                sspiClientGss.Initialize(null);

            do
            {
                status = clientInfo.Client.SessionSetup(
                    1,
                    64,
                    Packet_Header_Flags_Values.NONE,
                    clientInfo.MessageId++,
                    clientInfo.SessionId,
                    SESSION_SETUP_Request_Flags.NONE,
                    SESSION_SETUP_Request_SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED,
                    SESSION_SETUP_Request_Capabilities_Values.NONE,
                    0,
                    sspiClientGss.Token,
                    out clientInfo.SessionId,
                    out clientInfo.ServerGssToken,
                    out header,
                    out sessionSetupResponse);

                if ((status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED || status == Smb2Status.STATUS_SUCCESS) &&
                    clientInfo.ServerGssToken != null && clientInfo.ServerGssToken.Length > 0)
                {
                    sspiClientGss.Initialize(clientInfo.ServerGssToken);
                }
            } while (status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED);

            if (status == Smb2Status.STATUS_SUCCESS)
            {
                clientInfo.SessionKey = sspiClientGss.SessionKey;
                clientInfo.Client.GenerateCryptoKeys(clientInfo.SessionId, clientInfo.SessionKey, true, false);
            }

            clientInfo.GrantedCredit = header.CreditRequestResponse;
            Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "SessionSetup should succeed, actual status is {0}", Smb2Status.GetStatusCode(status));
            #endregion

            #region TREE_CONNECT to share
            TREE_CONNECT_Response treeConnectPayload;
            status = clientInfo.Client.TreeConnect(1, 1, clientInfo.Flags, clientInfo.MessageId++, clientInfo.SessionId, uncSharePath,
                out clientInfo.TreeId, out header, out treeConnectPayload);
            Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "TreeConnect to {0} should succeed, actual status is {1}", uncSharePath, Smb2Status.GetStatusCode(status));
            if (treeConnectPayload.ShareFlags.HasFlag(ShareFlags_Values.SHAREFLAG_FORCE_LEVELII_OPLOCK))
            {
                Site.Assert.Inconclusive("This test case is not applicable for the share whose ShareFlags includes SHAREFLAG_FORCE_LEVELII_OPLOCK.");
            }
            if (treeConnectPayload.Capabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_SCALEOUT))
            {
                Site.Assert.Inconclusive("This test case is not applicable for the share whose Capabilities includes SHARE_CAP_SCALEOUT.");
            }
            #endregion
        }
        private void CreateFile(ModelDialectRevision dialect, string target, bool isDirectory)
        {
            LeasingClientInfo clientInfo = new LeasingClientInfo(testConfig.Timeout, testConfig);
            clientInfo.File = target;

            InitializeClient(clientInfo, dialect);

            Packet_Header header;
            CREATE_Response createResponse;
            Smb2CreateContextResponse[] serverCreateContexts;
            uint status = 0;

            status = clientInfo.Client.Create(1, 64, clientInfo.Flags, clientInfo.MessageId++, clientInfo.SessionId, clientInfo.TreeId, clientInfo.File,
                AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE | AccessMask.DELETE,
                ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_WRITE | ShareAccess_Values.FILE_SHARE_DELETE,
                isDirectory ? CreateOptions_Values.FILE_DIRECTORY_FILE : CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                CreateDisposition_Values.FILE_OPEN_IF,
                File_Attributes.NONE,
                ImpersonationLevel_Values.Impersonation,
                SecurityFlags_Values.NONE,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                null,
                out clientInfo.FileId,
                out serverCreateContexts,
                out header,
                out createResponse);
            clientInfo.GrantedCredit = header.CreditRequestResponse;
            Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "Create a file {0} should succeed, actual status is {1}", clientInfo.File, Smb2Status.GetStatusCode(status));

            clientInfo.Cleanup();
        }
        private void DeleteFile(ModelDialectRevision dialect, string target, bool isDirectory)
        {
            LeasingClientInfo clientInfo = new LeasingClientInfo(testConfig.Timeout, testConfig);

            InitializeClient(clientInfo, dialect);

            Packet_Header header;
            CREATE_Response createResponse;
            Smb2CreateContextResponse[] serverCreateContexts;
            uint status = 0;

            status = clientInfo.Client.Create(1, 64, clientInfo.Flags, clientInfo.MessageId++, clientInfo.SessionId, clientInfo.TreeId, target,
                AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE | AccessMask.DELETE,
                ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_WRITE | ShareAccess_Values.FILE_SHARE_DELETE,
                (isDirectory ? CreateOptions_Values.FILE_DIRECTORY_FILE : CreateOptions_Values.FILE_NON_DIRECTORY_FILE) | CreateOptions_Values.FILE_DELETE_ON_CLOSE,
                CreateDisposition_Values.FILE_OPEN_IF,
                File_Attributes.NONE,
                ImpersonationLevel_Values.Impersonation,
                SecurityFlags_Values.NONE,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                null,
                out clientInfo.FileId,
                out serverCreateContexts,
                out header,
                out createResponse);
            clientInfo.GrantedCredit = header.CreditRequestResponse;

            FileDispositionInformation deleteInfo;
            deleteInfo.DeletePending = 1;

            byte[] inputBuffer;
            inputBuffer = TypeMarshal.ToBytes<FileDispositionInformation>(deleteInfo);

            SET_INFO_Response responsePayload;
            clientInfo.Client.SetInfo(
                1,
                1,
                clientInfo.Flags,
                clientInfo.MessageId++,
                clientInfo.SessionId,
                clientInfo.TreeId,
                SET_INFO_Request_InfoType_Values.SMB2_0_INFO_FILE,
                (byte)FileInformationClasses.FileDispositionInformation,
                SET_INFO_Request_AdditionalInformation_Values.NONE,
                clientInfo.FileId,
                inputBuffer,
                out header,
                out responsePayload);
            clientInfo.Cleanup();
        }
        public void SetupConnection(ModelDialectRevision dialect, ClientSupportDirectoryLeasingType clientSupportDirectoryLeasingType)
        {
            string parentDirectory = "LeasingDir_" + Guid.NewGuid().ToString();
            CreateFile(dialect, parentDirectory, true);

            originalClient = new LeasingClientInfo(testConfig.Timeout, testConfig);
            originalClient.ParentDirectory = parentDirectory;
            originalClient.File = parentDirectory + "\\" + Guid.NewGuid().ToString();

            originalClient.Client.LeaseBreakNotificationReceived += new Action<Packet_Header, LEASE_BREAK_Notification_Packet>(OnLeaseBreakNotificationReceived);

            bool isClientSupportDirectoryLeasing = clientSupportDirectoryLeasingType == ClientSupportDirectoryLeasingType.ClientSupportDirectoryLeasing;
            InitializeClient(originalClient, dialect, isClientSupportDirectoryLeasing);

            clients.Add(new LeasingClientInfo(testConfig.Timeout, testConfig, originalClient.ClientGuid)); // SameClientId
            clients.Add(new LeasingClientInfo(testConfig.Timeout, testConfig, originalClient.ClientGuid)); // SameClientGuidDifferentLeaseKey
            clients.Add(new LeasingClientInfo(testConfig.Timeout, testConfig)); // Second client

            clients[(int)OperatorType.SameClientId].Client.LeaseBreakNotificationReceived += new Action<Packet_Header, LEASE_BREAK_Notification_Packet>(clients[(int)OperatorType.SameClientId].OnLeaseBreakNotificationReceived);
        }