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

            swnClientForInterface = new SwnClient();
            swnClientForWitness = new SwnClient();
            pContext = IntPtr.Zero;
            witnessType = WitnessType.None;
        }
        /// <summary>
        /// Bind RPC server.
        /// </summary>
        /// <param name="swnClient">SWN rpc client</param>
        /// <param name="networkAddress">RPC network address</param>
        /// <param name="domainName">Domain name</param>
        /// <param name="userName">User name</param>
        /// <param name="password">Password</param>
        /// <param name="securityPackage">Security package</param>
        /// <param name="authLevel">Authentication level</param>
        /// <param name="timeout">Timeout</param>
        /// <param name="serverComputerName">ServerComputerName</param>
        /// <returns>Return true if success, otherwise return false</returns>
        public static bool BindServer(SwnClient swnClient, IPAddress networkAddress, string domainName, string userName, string password,
            SecurityPackageType securityPackage, RpceAuthenticationLevel authLevel, TimeSpan timeout,string serverComputerName = null)
        {
            AccountCredential accountCredential = new AccountCredential(domainName, userName, password);
            string cifsServicePrincipalName = string.Empty;
            if (!string.IsNullOrEmpty(serverComputerName))
            {
                cifsServicePrincipalName = "cifs/" + serverComputerName;
            }
            else
            {
                IPHostEntry hostEntry = null;
                try
                {
                    hostEntry = Dns.GetHostEntry(networkAddress);
                }
                catch (Exception ex)
                {
                    throw new Exception(string.Format("Failed to resolve network address {0} with exception: {1}", networkAddress.ToString(), ex.Message));
                }

                if (hostEntry != null && !string.IsNullOrEmpty(hostEntry.HostName))
                {
                    cifsServicePrincipalName = "cifs/" + hostEntry.HostName;
                }
                else
                {
                    throw new Exception("Failed to get HostName from network address " + networkAddress.ToString());
                }
            }
            ClientSecurityContext securityContext =
                new SspiClientSecurityContext(
                    securityPackage,
                    accountCredential,
                    cifsServicePrincipalName,
                    ClientSecurityContextAttribute.Connection
                        | ClientSecurityContextAttribute.DceStyle
                        | ClientSecurityContextAttribute.Integrity
                        | ClientSecurityContextAttribute.ReplayDetect
                        | ClientSecurityContextAttribute.SequenceDetect
                        | ClientSecurityContextAttribute.UseSessionKey,
                    SecurityTargetDataRepresentation.SecurityNativeDrep);

            try
            {
                //Bind
                BaseTestSite.Log.Add(LogEntryKind.Debug, "Start to Bind RPC to {0}.", networkAddress.ToString());
                swnClient.SwnBind(networkAddress.ToString(), accountCredential, securityContext, authLevel, timeout);
            }
            catch (Exception ex)
            {
                BaseTestSite.Log.Add(LogEntryKind.Debug,
                    "Bind server {0} failed. Exception: {1}",
                    networkAddress.ToString(),
                    ex.Message);
                swnClient.SwnUnbind(timeout);
                return false;
            }

            BaseTestSite.Log.Add(LogEntryKind.Debug, "Bind server {0} successfully.", networkAddress.ToString());
            return true;
        }
        private void SWNRegister(SwnRegisterType registerType, SwnVersion expectedVersion)
        {
            WITNESS_INTERFACE_INFO registerInterface;
            IntPtr pDuplicateContext = IntPtr.Zero;
            swnClientForInterface = new SwnClient();
            swnClientForWitness = new SwnClient();
            string server = TestConfig.ClusteredFileServerName;

            IPAddress currentAccessIpAddr = SWNTestUtility.GetCurrentAccessIP(server);

            #region Get SWN witness interface list
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Get SWN witness interface list.");

            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");

            int ret;
            WITNESS_INTERFACE_LIST interfaceList = new WITNESS_INTERFACE_LIST();

            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");

            swnClientForInterface.SwnUnbind(TestConfig.Timeout);
            swnClientForInterface = null;

            SWNTestUtility.GetRegisterInterface(interfaceList, out registerInterface);

            SWNTestUtility.CheckVersion(expectedVersion, (SwnVersion)registerInterface.Version);
            #endregion

            #region Register SWN witness
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Register SWN witness with {0}.", registerType.ToString());

            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), TestConfig.FailoverTimeout,
                "Retry BindServer until succeed within timeout span");

            SwnVersion registerVersion;
            if (SwnVersion.SWN_VERSION_2 == expectedVersion)
                registerVersion = (registerType == SwnRegisterType.InvalidVersion ? SwnVersion.SWN_VERSION_1 : SwnVersion.SWN_VERSION_2);
            else
                registerVersion = (registerType == SwnRegisterType.InvalidVersion ? SwnVersion.SWN_VERSION_2 : SwnVersion.SWN_VERSION_1);
            string registerNetName =
                (registerType == SwnRegisterType.InvalidNetName ? "XXXXInvalid.contoso.comXXXX" : SWNTestUtility.GetPrincipleName(TestConfig.DomainName, server));
            string accessIpAddr =
                (registerType == SwnRegisterType.InvalidIpAddress ? "255.255.255.255" : currentAccessIpAddr.ToString());
            string registerClientName = Guid.NewGuid().ToString();
            string shareName =
                (registerType == SwnRegisterType.InvalidShareName ? "XXXXInvalidShareNameXXXX" : TestConfig.ClusteredFileShare);
            uint keepAliveTimout =
                (registerType == SwnRegisterType.KeepAliveTimeout ? (uint)10 : (uint)120);

            BaseTestSite.Log.Add(LogEntryKind.Debug, "Register witness:");
            BaseTestSite.Log.Add(LogEntryKind.Debug, "\tVersion: {0:x8}", (uint)registerVersion);
            BaseTestSite.Log.Add(LogEntryKind.Debug, "\tNetName: {0}", registerNetName);
            BaseTestSite.Log.Add(LogEntryKind.Debug, "\tShareName: {0}", shareName);
            BaseTestSite.Log.Add(LogEntryKind.Debug, "\tIpAddress: {0}", accessIpAddr);
            BaseTestSite.Log.Add(LogEntryKind.Debug, "\tClientName: {0}", registerClientName);
            if (SwnVersion.SWN_VERSION_2 == expectedVersion)
            {
                ret = swnClientForWitness.WitnessrRegisterEx(registerVersion,
                    registerNetName,
                    shareName,
                    accessIpAddr,
                    registerClientName,
                    WitnessrRegisterExFlagsValue.WITNESS_REGISTER_NONE,
                    keepAliveTimout,
                    out pContext);
            }
            else
            {
                ret = swnClientForWitness.WitnessrRegister(registerVersion,
                    registerNetName,
                    accessIpAddr,
                    registerClientName,
                    out pContext);
            }

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Verify server response for WitnessrRegister request.");

            // TDI to be filed, original fix for TDI 66777 and 69401 is not accurate, need clarify in new TDI
            // Windows server won't fail the request if the target resource being monitored is ScaleOut FS share when request containst invalid IP address or invalid share name
            // TODO: Test case should have ability to choose different server, otherwise we do not need such condition
            bool isScaleOutFsShare = ShareContainsSofs(server, Smb2Utility.GetUncPath(server, TestConfig.ClusteredFileShare));

            if (registerType == SwnRegisterType.InvalidNetName)
            {
                BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_INVALID_PARAMETER, (SwnErrorCode)ret, "WitnessrRegister returns with result code = 0x{0:x8}", ret);
            }
            else if (registerType == SwnRegisterType.InvalidVersion)
            {
                BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_REVISION_MISMATCH, (SwnErrorCode)ret, "WitnessrRegister returns with result code = 0x{0:x8}", ret);
            }
            else if (registerType == SwnRegisterType.InvalidIpAddress)
            {
                if (!isScaleOutFsShare)
                {
                    BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrRegister returns with result code = 0x{0:x8}", ret);
                }
                else
                {
                    BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_INVALID_STATE, (SwnErrorCode)ret, "WitnessrRegister returns with result code = 0x{0:x8}", ret);
                }
            }
            else if (registerType == SwnRegisterType.InvalidShareName)
            {
                if (!isScaleOutFsShare)
                {
                    BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrRegister returns with result code = 0x{0:x8}", ret);
                }
                else
                {
                    BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_INVALID_STATE, (SwnErrorCode)ret, "WitnessrRegister returns with result code = 0x{0:x8}", ret);
                }
            }
            else
            {
                BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrRegister returns with result code = 0x{0:x8}", ret);
            }

            if (registerType == SwnRegisterType.InvalidUnRegister)
            {
                ret = swnClientForWitness.WitnessrUnRegister(pContext);
                BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrUnRegister returns with result code = 0x{0:x8}", ret);

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

            if (registerType == SwnRegisterType.InvalidRequest)
            {
                ret = swnClientForWitness.WitnessrUnRegister(pContext);
                BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_SUCCESS, (SwnErrorCode)ret, "WitnessrUnRegister returns with result code = 0x{0:x8}", ret);

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

                RESP_ASYNC_NOTIFY respNotify;
                ret = swnClientForWitness.ExpectWitnessrAsyncNotify(callId, out respNotify);
                BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_NOT_FOUND, (SwnErrorCode)ret, "ExpectWitnessrAsyncNotify returns with result code = 0x{0:x8}", ret);

                pContext = IntPtr.Zero;
                swnClientForWitness.SwnUnbind(TestConfig.Timeout);
            }

            if (registerType == SwnRegisterType.KeepAliveTimeout)
            {
                uint callId;
                callId = swnClientForWitness.WitnessrAsyncNotify(pContext);
                BaseTestSite.Assert.AreNotEqual<uint>(0, callId, "WitnessrAsyncNotify returns callId = {0}", callId);

                RESP_ASYNC_NOTIFY respNotify;
                ret = swnClientForWitness.ExpectWitnessrAsyncNotify(callId, out respNotify);
                BaseTestSite.Assert.AreEqual<SwnErrorCode>(SwnErrorCode.ERROR_TIMEOUT, (SwnErrorCode)ret, "ExpectWitnessrAsyncNotify returns with result code = 0x{0:x8}", ret);

                pContext = IntPtr.Zero;
                swnClientForWitness.SwnUnbind(TestConfig.Timeout);
            }
            #endregion

            #region Cleanup
            pContext = IntPtr.Zero;
            swnClientForWitness.SwnUnbind(TestConfig.Timeout);
            swnClientForWitness = null;
            #endregion
        }
        // Use TestInitialize to run code before running every test in the class
        protected override void TestInitialize()
        {
            base.TestInitialize();

            swnClientForInterface = null;
            swnClientForWitness = null;
            pContext = IntPtr.Zero;
        }
        // Use TestCleanup to run code after every test in a class have run
        protected override void TestCleanup()
        {
            if (pContext != IntPtr.Zero)
            {
                if (swnClientForWitness != null)
                {
                    swnClientForWitness.WitnessrUnRegister(pContext);
                }
                pContext = IntPtr.Zero;
            }

            try
            {
                if (swnClientForInterface != null)
                {
                    swnClientForInterface.SwnUnbind(TestConfig.Timeout);
                    swnClientForInterface = null;
                }
                if (swnClientForWitness != null)
                {
                    swnClientForWitness.SwnUnbind(TestConfig.Timeout);
                    swnClientForInterface = null;
                }
            }
            catch (Exception ex)
            {
                BaseTestSite.Log.Add(LogEntryKind.Warning, "TestCleanup: Unexpected Exception: {0}", ex);
            }

            base.TestCleanup();
        }
        static void Main(string[] args)
        {
            SwnClient client = new SwnClient();
            string serverName = "GeneralFS";
            string serverAddr = "192.168.1.200";
            string resourceName = "GeneralFS";
            string clientName = Guid.NewGuid().ToString();

            int retVar = 0;
            TimeSpan timeOut = new TimeSpan(0, 0, 10);
            AccountCredential accountCredential = new AccountCredential("contoso.com", "Administrator", "Password01!");
            NlmpClientCredential nlmpCredential = new NlmpClientCredential(serverName, "contoso.com", "Administrator", "Password01!");
            ClientSecurityContext securityContext = new NlmpClientSecurityContext(nlmpCredential);

            //Bind to server
            client.SwnBind(serverName, accountCredential, securityContext,
                RpceAuthenticationLevel.RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, timeOut);

            //Get interface list
            WITNESS_INTERFACE_LIST interfaceList;
            try
            {
                retVar = client.WitnessGetInterfaceList(out interfaceList);
                Console.WriteLine("Call WitnessGetInterfaceList: " + retVar);
            }
            catch (TimeoutException)
            {
                client.SwnUnbind(timeOut);
                return;
            }

            string swnServerName = "";

            foreach (var info in interfaceList.InterfaceInfo)
            {
                if ((info.Flags & (uint)SwnNodeFlagsValue.INTERFACE_WITNESS) != 0)
                {
                    if ((info.Flags & (uint)SwnNodeFlagsValue.IPv4) != 0)
                    {
                        swnServerName = (new IPAddress(info.IPV4)).ToString();
                    }
                    else if ((info.Flags & (uint)SwnNodeFlagsValue.IPv6) != 0)
                    {
                        byte[] ipv6 = new byte[16];
                        Buffer.BlockCopy(info.IPV6, 0, ipv6, 0, 16);
                        swnServerName = (new IPAddress(ipv6)).ToString();
                    }
                    else
                    {
                        throw new ArgumentException();
                    }
                    break;
                }
            }

            SwnClient client2 = new SwnClient();
            client2.SwnBind(swnServerName, accountCredential, securityContext,
                RpceAuthenticationLevel.RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, timeOut);

            //Registration
            IntPtr pContext;
            retVar = client2.WitnessRegister(SwnVersion.SWN_VERSION_1, resourceName, serverAddr, clientName, out pContext);
            Console.WriteLine("Call WitnessRegister: " + retVar);

            uint callId = 0;
            try
            {
                RESP_ASYNC_NOTIFY respNotify;
                callId = client2.WitnessAsyncNotify(pContext);
                Console.WriteLine("Call WitnessAsyncNotify: " + callId);

                retVar = client2.WitnessAsyncNotifyExpect(callId, out respNotify);
                Console.WriteLine("Call WitnessAsyncNotify: " + retVar);
                Console.WriteLine("NumberOfMessages: " + respNotify.NumberOfMessages);
                Console.WriteLine("Length: " + respNotify.Length);
                PrintNotification(respNotify);

                callId = client2.WitnessAsyncNotify(pContext);
                Console.WriteLine("Call WitnessAsyncNotify: " + callId);

                retVar = client2.WitnessAsyncNotifyExpect(callId, out respNotify);
                Console.WriteLine("Call WitnessAsyncNotify: " + retVar);
                Console.WriteLine("NumberOfMessages: " + respNotify.NumberOfMessages);
                Console.WriteLine("Length: " + respNotify.Length);
                PrintNotification(respNotify);
            }
            catch (TimeoutException)
            {
                Console.WriteLine("Throw a TimeoutException.");
            }

            //UnRegistration
            retVar = client2.WitnessUnRegister(pContext);
            Console.WriteLine("Call WitnessUnRegister: " + retVar);

            client2.SwnUnbind(timeOut);
            client.SwnUnbind(timeOut);

            Console.ReadKey();
        }