Beispiel #1
0
        public TokenProvider Duplicate(uint desiredAccess = 0x02000000)
        {
            if (!TokensApi.DuplicateTokenEx(Token.DangerousGetHandle(), desiredAccess, IntPtr.Zero,
                                            SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, TOKEN_TYPE.TokenPrimary, out var newToken))
            {
                throw new Win32Exception();
            }

            Token.Close();
            Token = newToken;
            return(this);
        }
        public static WindowsIdentity DuplicateToken(WindowsIdentity id)
        {
            SafeTokenHandle duplicateTokenHandle = SafeTokenHandle.InvalidHandle;

            try
            {
                bool bRetVal = DuplicateToken(id.Token, 2, out duplicateTokenHandle);

                if (false == bRetVal)
                {
                    int    nErrorCode = Marshal.GetLastWin32Error();
                    string sResult    = "DuplicateToken() failed with error code: " + nErrorCode + Environment.NewLine;
                    throw new Exception(sResult);
                }

                return(new WindowsIdentity(duplicateTokenHandle.DangerousGetHandle()));
            }
            finally
            {
                if (!duplicateTokenHandle.IsInvalid)
                {
                    duplicateTokenHandle.Close();
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Checks if the Application process has elevated rights
        /// </summary>
        /// <returns>true if the process is elevated, false otherwise</returns>
        /// <exception cref="Win32Exception"><see cref="Win32Exception"/></exception>
        public bool IsProcessElevated()
        {
            bool            fIsElevated;
            SafeTokenHandle hToken          = null;
            var             pTokenElevation = IntPtr.Zero;

            try
            {
                // Open the access token of the current process with TOKEN_QUERY.
                if (!NativeMethods.OpenProcessToken(Process.GetCurrentProcess().Handle,
                                                    NativeMethods.TOKEN_QUERY, out hToken))
                {
                    throw new Win32Exception();
                }

                // Allocate a buffer for the elevation information.
                var cbTokenElevation = Marshal.SizeOf(typeof(TOKEN_ELEVATION));
                pTokenElevation = Marshal.AllocHGlobal(cbTokenElevation);
                if (pTokenElevation == IntPtr.Zero)
                {
                    throw new Win32Exception();
                }

                // Retrieve token elevation information.
                if (!NativeMethods.GetTokenInformation(hToken,
                                                       TOKEN_INFORMATION_CLASS.TokenElevation, pTokenElevation,
                                                       cbTokenElevation, out cbTokenElevation))
                {
                    // When the process is run on operating systems prior to Windows
                    // Vista, GetTokenInformation returns false with the error code
                    // ERROR_INVALID_PARAMETER because TokenElevation is not supported
                    // on those operating systems.
                    throw new Win32Exception();
                }

                // Marshal the TOKEN_ELEVATION struct from native to .NET object.
                var elevation = (TOKEN_ELEVATION)Marshal.PtrToStructure(
                    pTokenElevation, typeof(TOKEN_ELEVATION));

                // TOKEN_ELEVATION.TokenIsElevated is a non-zero value if the token
                // has elevated privileges; otherwise, a zero value.
                fIsElevated = (elevation.TokenIsElevated != 0);
            }
            finally
            {
                // Centralized cleanup for all allocated resources.
                hToken?.Close();

                if (pTokenElevation != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pTokenElevation);
                }
            }

            return(fIsElevated);
        }
        internal static ImpersonationQueryResult QueryImpersonation()
        {
            SafeTokenHandle phThreadToken = null;
            int             num           = System.Security.Principal.Win32.OpenThreadToken(TokenAccessLevels.Query, WinSecurityContext.Thread, out phThreadToken);

            if (phThreadToken != null)
            {
                phThreadToken.Close();
                return(ImpersonationQueryResult.Impersonated);
            }
            if (num == GetHRForWin32Error(5))
            {
                return(ImpersonationQueryResult.Impersonated);
            }
            if (num == GetHRForWin32Error(0x3f0))
            {
                return(ImpersonationQueryResult.NotImpersonated);
            }
            return(ImpersonationQueryResult.Failed);
        }
        /// <summary>
        /// Retrieves user by username and password.
        /// </summary>
        /// <param name="username">User name.</param>
        /// <param name="domain">Domain.</param>
        /// <param name="password">Password.</param>
        /// <exception cref="Exception">If user cannot be authenticated.</exception>
        /// <returns>Authenticated user.</returns>
        public static WindowsIdentity GetUser(string username, string domain, string password)
        {
            SafeTokenHandle existingTokenHandle = SafeTokenHandle.InvalidHandle;

            if (string.IsNullOrEmpty(domain))
            {
                domain = Environment.MachineName;
            }

            try
            {
                const int LOGON32_PROVIDER_DEFAULT  = 0;
                const int LOGON32_LOGON_INTERACTIVE = 2;

                bool impersonated = LogonUser(
                    username,
                    domain,
                    password,
                    LOGON32_LOGON_INTERACTIVE,
                    LOGON32_PROVIDER_DEFAULT,
                    out existingTokenHandle);

                if (false == impersonated)
                {
                    int    errorCode = Marshal.GetLastWin32Error();
                    string result    = "LogonUser() failed with error code: " + errorCode + Environment.NewLine;
                    throw new Exception(result);
                }

                return(new WindowsIdentity(existingTokenHandle.DangerousGetHandle()));
            }
            finally
            {
                if (!existingTokenHandle.IsInvalid)
                {
                    existingTokenHandle.Close();
                }
            }
        }
Beispiel #6
0
        /// <summary>
        ///     The function checks whether the primary access token of the process belongs to user account that is a member of the local Administrators group, even if it currently is not elevated.
        /// </summary>
        /// <returns> Returns true if the primary access token of the process belongs to user account that is a member of the local Administrators group. Returns false if the token does not. </returns>
        /// <exception cref="System.ComponentModel.Win32Exception">
        ///     When any native Windows API call fails, the function throws a Win32Exception
        ///     with the last error code.
        /// </exception>
        public static bool IsUserInAdminGroup()
        {
            var             fInAdminGroup  = false;
            SafeTokenHandle hToken         = null;
            SafeTokenHandle hTokenToCheck  = null;
            var             pElevationType = IntPtr.Zero;
            var             pLinkedToken   = IntPtr.Zero;
            var             cbSize         = 0;

            try {
                // Open the access token of the current process for query and duplicate.
                if (!Advapi32.OpenProcessToken(System.Diagnostics.Process.GetCurrentProcess().Handle, Advapi32.TOKEN_QUERY | Advapi32.TOKEN_DUPLICATE, out hToken))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                // Determine whether system is running Windows Vista or later operating
                // systems (major version >= 6) because they support linked tokens, but
                // previous versions (major version < 6) do not.
                if (Environment.OSVersion.Version.Major >= 6)
                {
                    // Running Windows Vista or later (major version >= 6).
                    // Determine token type: limited, elevated, or default.

                    // Allocate a buffer for the elevation type information.
                    //cbSize = sizeof(TOKEN_ELEVATION_TYPE); // TODO: is this ok?
                    cbSize         = 8;
                    pElevationType = Marshal.AllocHGlobal(cbSize);
                    if (pElevationType == IntPtr.Zero)
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

                    // Retrieve token elevation type information.
                    if (!Advapi32.GetTokenInformation(hToken, TokenInformationClass.TokenElevationType, pElevationType, cbSize, out cbSize))
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

                    // Marshal the TOKEN_ELEVATION_TYPE enum from native to .NET.
                    var elevType = (TokenElevationType)Marshal.ReadInt32(pElevationType);

                    // If limited, get the linked elevated token for further check.
                    if (elevType == TokenElevationType.TokenElevationTypeLimited)
                    {
                        // Allocate a buffer for the linked token.
                        cbSize       = IntPtr.Size;
                        pLinkedToken = Marshal.AllocHGlobal(cbSize);
                        if (pLinkedToken == IntPtr.Zero)
                        {
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                        }

                        // Get the linked token.
                        if (!Advapi32.GetTokenInformation(hToken, TokenInformationClass.TokenLinkedToken, pLinkedToken, cbSize, out cbSize))
                        {
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                        }

                        // Marshal the linked token value from native to .NET.
                        var hLinkedToken = Marshal.ReadIntPtr(pLinkedToken);
                        hTokenToCheck = new SafeTokenHandle(hLinkedToken);
                    }
                }

                // CheckTokenMembership requires an impersonation token. If we just got
                // a linked token, it already is an impersonation token.  If we did not
                // get a linked token, duplicate the original into an impersonation
                // token for CheckTokenMembership.
                if (hTokenToCheck == null)
                {
                    if (!Advapi32.DuplicateToken(hToken, SecurityImpersonationLevel.SecurityIdentification, out hTokenToCheck))
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }
                }

                // Check if the token to be checked contains admin SID.
                var id        = new WindowsIdentity(hTokenToCheck.DangerousGetHandle());
                var principal = new WindowsPrincipal(id);
                fInAdminGroup = principal.IsInRole(WindowsBuiltInRole.Administrator);
            }
            finally {
                // Centralized cleanup for all allocated resources.
                if (hToken != null)
                {
                    hToken.Close();
                    hToken = null;
                }
                if (hTokenToCheck != null)
                {
                    hTokenToCheck.Close();
                    hTokenToCheck = null;
                }
                if (pElevationType != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pElevationType);
                    pElevationType = IntPtr.Zero;
                }
                if (pLinkedToken != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pLinkedToken);
                    pLinkedToken = IntPtr.Zero;
                }
            }

            return(fInAdminGroup);
        }
Beispiel #7
0
        /// <summary>
        ///     The function gets the integrity level of the current process. Integrity level is only available on Windows Vista and newer operating systems, thus GetProcessIntegrityLevel throws a C++ exception if it is called on systems prior to Windows Vista.
        /// </summary>
        /// <returns> Returns the integrity level of the current process. It is usually one of these values: SECURITY_MANDATORY_UNTRUSTED_RID - means untrusted level. It is used by processes started by the Anonymous group. Blocks most write access. (SID: S-1-16-0x0) SECURITY_MANDATORY_LOW_RID - means low integrity level. It is used by Protected Mode Internet Explorer. Blocks write acess to most objects (such as files and registry keys) on the system. (SID: S-1-16-0x1000) SECURITY_MANDATORY_MEDIUM_RID - means medium integrity level. It is used by normal applications being launched while UAC is enabled. (SID: S-1-16-0x2000) SECURITY_MANDATORY_HIGH_RID - means high integrity level. It is used by administrative applications launched through elevation when UAC is enabled, or normal applications if UAC is disabled and the user is an administrator. (SID: S-1-16-0x3000) SECURITY_MANDATORY_SYSTEM_RID - means system integrity level. It is used by services and other system-level applications (such as Wininit, Winlogon, Smss, etc.) (SID: S-1-16-0x4000) </returns>
        /// <exception cref="System.ComponentModel.Win32Exception">
        ///     When any native Windows API call fails, the function throws a Win32Exception
        ///     with the last error code.
        /// </exception>
        public static int GetProcessIntegrityLevel()
        {
            var             IL        = -1;
            SafeTokenHandle hToken    = null;
            var             cbTokenIL = 0;
            var             pTokenIL  = IntPtr.Zero;

            try {
                // Open the access token of the current process with TOKEN_QUERY.
                if (!Advapi32.OpenProcessToken(System.Diagnostics.Process.GetCurrentProcess().Handle, Advapi32.TOKEN_QUERY, out hToken))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                // Then we must query the size of the integrity level information
                // associated with the token. Note that we expect GetTokenInformation
                // to return false with the ERROR_INSUFFICIENT_BUFFER error code
                // because we've given it a null buffer. On exit cbTokenIL will tell
                // the size of the group information.
                if (!Advapi32.GetTokenInformation(hToken, TokenInformationClass.TokenIntegrityLevel, IntPtr.Zero, 0, out cbTokenIL))
                {
                    var error = Marshal.GetLastWin32Error();
                    if (error != Advapi32.ERROR_INSUFFICIENT_BUFFER)
                    {
                        // When the process is run on operating systems prior to
                        // Windows Vista, GetTokenInformation returns false with the
                        // ERROR_INVALID_PARAMETER error code because
                        // TokenIntegrityLevel is not supported on those OS's.
                        throw new Win32Exception(error);
                    }
                }

                // Now we allocate a buffer for the integrity level information.
                pTokenIL = Marshal.AllocHGlobal(cbTokenIL);
                if (pTokenIL == IntPtr.Zero)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                // Now we ask for the integrity level information again. This may fail
                // if an administrator has added this account to an additional group
                // between our first call to GetTokenInformation and this one.
                if (!Advapi32.GetTokenInformation(hToken, TokenInformationClass.TokenIntegrityLevel, pTokenIL, cbTokenIL, out cbTokenIL))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                // Marshal the TOKEN_MANDATORY_LABEL struct from native to .NET object.
                var tokenIL = (TokenMandatoryLabel)Marshal.PtrToStructure(pTokenIL, typeof(TokenMandatoryLabel));

                // Integrity Level SIDs are in the form of S-1-16-0xXXXX. (e.g.
                // S-1-16-0x1000 stands for low integrity level SID). There is one
                // and only one subauthority.
                var pIL = Advapi32.GetSidSubAuthority(tokenIL.Label.Sid, 0);
                IL = Marshal.ReadInt32(pIL);
            }
            finally {
                // Centralized cleanup for all allocated resources.
                if (hToken != null)
                {
                    hToken.Close();
                    hToken = null;
                }
                if (pTokenIL != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pTokenIL);
                    pTokenIL  = IntPtr.Zero;
                    cbTokenIL = 0;
                }
            }

            return(IL);
        }
Beispiel #8
0
        public static bool SetProcessIntegrityLevel(IntPtr provessHandle, MANDATORY_LEVEL integrityLvl)
        {
            bool            isok          = false;
            SafeTokenHandle hToken        = null;
            IntPtr          pIntegritySid = IntPtr.Zero;
            int             cbTokenInfo   = 0;
            IntPtr          pTokenInfo    = IntPtr.Zero;

            try
            {
                if (!NativeMethod.OpenProcessToken(provessHandle,
                                                   NativeMethod.TOKEN_QUERY | NativeMethod.TOKEN_ADJUST_DEFAULT, out hToken))
                {
                    throw new Win32Exception();
                }

                // Create the low integrity SID.
                if (!NativeMethod.AllocateAndInitializeSid(
                        ref NativeMethod.SECURITY_MANDATORY_LABEL_AUTHORITY, 1,
                        (int)integrityLvl,
                        0, 0, 0, 0, 0, 0, 0, out pIntegritySid))
                {
                    throw new Win32Exception();
                }

                TOKEN_MANDATORY_LABEL tml;
                tml.Label.Attributes = NativeMethod.SE_GROUP_INTEGRITY;
                tml.Label.Sid        = pIntegritySid;

                // Marshal the TOKEN_MANDATORY_LABEL struct to the native memory.
                cbTokenInfo = Marshal.SizeOf(tml);
                pTokenInfo  = Marshal.AllocHGlobal(cbTokenInfo);
                Marshal.StructureToPtr(tml, pTokenInfo, false);

                // Set the integrity level in the access token to low.
                if (!NativeMethod.SetTokenInformation(hToken,
                                                      CSCreateLowIntegrityProcess.TOKEN_INFORMATION_CLASS.TokenIntegrityLevel, pTokenInfo,
                                                      cbTokenInfo + NativeMethod.GetLengthSid(pIntegritySid)))
                {
                    throw new Win32Exception();
                }
                isok = true;
            }
            finally
            {
                // Centralized cleanup for all allocated resources.
                if (hToken != null)
                {
                    hToken.Close();
                    hToken = null;
                }
                if (pIntegritySid != IntPtr.Zero)
                {
                    NativeMethod.FreeSid(pIntegritySid);
                    pIntegritySid = IntPtr.Zero;
                }
                if (pTokenInfo != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pTokenInfo);
                    pTokenInfo  = IntPtr.Zero;
                    cbTokenInfo = 0;
                }
            }
            return(isok);
        }
Beispiel #9
0
        /// <summary>
        /// The function launches an application at low integrity level.
        /// </summary>
        /// <param name="commandLine">
        /// The command line to be executed. The maximum length of this string is 32K
        /// characters.
        /// </param>
        /// <param name="selectedIntegrityLevel">
        /// Numeric representation of integrity level with which process has to be started
        /// </param>
        /// <remarks>
        /// To start a low-integrity process,
        /// 1) Duplicate the handle of the current process, which is at medium
        ///    integrity level.
        /// 2) Use SetTokenInformation to set the integrity level in the access token
        ///    to Low.
        /// 3) Use CreateProcessAsUser to create a new process using the handle to
        ///    the low integrity access token.
        /// </remarks>
        public static void CreateSpecificIntegrityProcess(string commandLine, int selectedIntegrityLevel)
        {
            SafeTokenHandle     hToken        = null;
            SafeTokenHandle     hNewToken     = null;
            IntPtr              pIntegritySid = IntPtr.Zero;
            int                 cbTokenInfo   = 0;
            IntPtr              pTokenInfo    = IntPtr.Zero;
            STARTUPINFO         si            = new STARTUPINFO();
            PROCESS_INFORMATION pi            = new PROCESS_INFORMATION();

            try
            {
                // Open the primary access token of the process.
                if (!NativeMethod.OpenProcessToken(Process.GetCurrentProcess().Handle,
                                                   NativeMethod.TOKEN_DUPLICATE | NativeMethod.TOKEN_ADJUST_DEFAULT |
                                                   NativeMethod.TOKEN_QUERY | NativeMethod.TOKEN_ASSIGN_PRIMARY,
                                                   out hToken))
                {
                    throw new Win32Exception();
                }

                // Duplicate the primary token of the current process.
                if (!NativeMethod.DuplicateTokenEx(hToken, 0, IntPtr.Zero,
                                                   SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
                                                   TOKEN_TYPE.TokenPrimary, out hNewToken))
                {
                    throw new Win32Exception();
                }

                // Create the low integrity SID.
                if (!NativeMethod.AllocateAndInitializeSid(
                        ref NativeMethod.SECURITY_MANDATORY_LABEL_AUTHORITY, 1,
                        selectedIntegrityLevel,
                        0, 0, 0, 0, 0, 0, 0, out pIntegritySid))
                {
                    throw new Win32Exception();
                }

                TOKEN_MANDATORY_LABEL tml;
                tml.Label.Attributes = NativeMethod.SE_GROUP_INTEGRITY;
                tml.Label.Sid        = pIntegritySid;

                // Marshal the TOKEN_MANDATORY_LABEL struct to the native memory.
                cbTokenInfo = Marshal.SizeOf(tml);
                pTokenInfo  = Marshal.AllocHGlobal(cbTokenInfo);
                Marshal.StructureToPtr(tml, pTokenInfo, false);

                // Set the integrity level in the access token to low.
                if (!NativeMethod.SetTokenInformation(hNewToken,
                                                      TOKEN_INFORMATION_CLASS.TokenIntegrityLevel, pTokenInfo,
                                                      cbTokenInfo + NativeMethod.GetLengthSid(pIntegritySid)))
                {
                    throw new Win32Exception();
                }

                // Create the new process at the Low integrity level.
                si.cb = Marshal.SizeOf(si);
                if (!NativeMethod.CreateProcessAsUser(hNewToken, null, commandLine,
                                                      IntPtr.Zero, IntPtr.Zero, false, 0, IntPtr.Zero, null, ref si,
                                                      out pi))
                {
                    throw new Win32Exception();
                }
            }
            finally
            {
                // Centralized cleanup for all allocated resources.
                if (hToken != null)
                {
                    hToken.Close();
                    hToken = null;
                }
                if (hNewToken != null)
                {
                    hNewToken.Close();
                    hNewToken = null;
                }
                if (pIntegritySid != IntPtr.Zero)
                {
                    NativeMethod.FreeSid(pIntegritySid);
                    pIntegritySid = IntPtr.Zero;
                }
                if (pTokenInfo != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pTokenInfo);
                    pTokenInfo  = IntPtr.Zero;
                    cbTokenInfo = 0;
                }
                if (pi.hProcess != IntPtr.Zero)
                {
                    NativeMethod.CloseHandle(pi.hProcess);
                    pi.hProcess = IntPtr.Zero;
                }
                if (pi.hThread != IntPtr.Zero)
                {
                    NativeMethod.CloseHandle(pi.hThread);
                    pi.hThread = IntPtr.Zero;
                }
            }
        }
Beispiel #10
0
        private void ChangeProcessIL_button_Click(object sender, EventArgs e)
        {
            int    ID     = Int32.Parse(Table.CurrentCell.Value.ToString());
            string IL_str = ProcessIL_comboBox.Text.ToString();
            int    IL     = 0x00000000;

            if (IL_str == "Ненадежный")
            {
                IL = 0x00000000;
            }
            else if (IL_str == "Низкий")
            {
                IL = 0x00001000;
            }
            else if (IL_str == "Средний")
            {
                IL = 0x00002000;
            }

            SafeTokenHandle hToken        = null;
            IntPtr          pIntegritySid = IntPtr.Zero;
            int             cbTokenInfo   = 0;
            IntPtr          pTokenInfo    = IntPtr.Zero;

            try
            {
                if (!NativeMethod.OpenProcessToken(Process.GetProcessById(ID).Handle,
                                                   NativeMethod.TOKEN_DUPLICATE | NativeMethod.TOKEN_ADJUST_DEFAULT |
                                                   NativeMethod.TOKEN_QUERY | NativeMethod.TOKEN_ASSIGN_PRIMARY,
                                                   out hToken))
                {
                    throw new Win32Exception();
                }

                // Распределение памяти под идентификатор безопасности
                // и инициализация его полей
                if (!NativeMethod.AllocateAndInitializeSid(
                        ref NativeMethod.SECURITY_MANDATORY_LABEL_AUTHORITY, 1,
                        IL,
                        0, 0, 0, 0, 0, 0, 0, out pIntegritySid))
                {
                    throw new Win32Exception();
                }

                TOKEN_MANDATORY_LABEL tml;
                tml.Label.Attributes = NativeMethod.SE_GROUP_INTEGRITY;
                tml.Label.Sid        = pIntegritySid;

                cbTokenInfo = Marshal.SizeOf(tml);
                pTokenInfo  = Marshal.AllocHGlobal(cbTokenInfo);
                Marshal.StructureToPtr(tml, pTokenInfo, false);

                if (!NativeMethod.SetTokenInformation(hToken,
                                                      ChangeProcessIL.TOKEN_INFORMATION_CLASS.TokenIntegrityLevel, pTokenInfo,
                                                      cbTokenInfo + NativeMethod.GetLengthSid(pIntegritySid)))
                {
                    throw new Win32Exception();
                }
            }
            catch (Exception err)
            {
                string error_message = "Функция: изменение уровня целостности" + Environment.NewLine +
                                       "Имя процесса: " + Process.GetProcessById(ID).ProcessName + Environment.NewLine +
                                       "Исключение: " + err.Message.ToString() + Environment.NewLine + Environment.NewLine;

                StreamWriter Log_file = new StreamWriter("Exceptions_LOG.txt", false);
                Log_file.WriteLine(error_message);
                Log_file.Close();
            }
            finally
            {
                if (hToken != null)
                {
                    hToken.Close();
                    hToken = null;
                }
                if (pIntegritySid != IntPtr.Zero)
                {
                    NativeMethod.FreeSid(pIntegritySid);
                    pIntegritySid = IntPtr.Zero;
                }
                if (pTokenInfo != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pTokenInfo);
                    pTokenInfo  = IntPtr.Zero;
                    cbTokenInfo = 0;
                }
            }
        }
Beispiel #11
0
 public void Close() => tokenHandle.Close();