从 C# 转换为 vb.net 后出错

Error after converting to vb.net from C#

我正在尝试转换 link 中给出的 C# 代码。转换后我遇到了一些错误,但我已经更正了一些。我仍然收到 cbSize = sizeof(TOKEN_ELEVATION_TYPE) 行的错误 错误是:

  • 'sizeof' is not declared. It may be inaccessible due to its protection level. D:\Desktop\WindowsApplication3\WindowsApplication3\Form1.vb 103 26 WindowsApplication3
  • 'TOKEN_ELEVATION_TYPE' is a type and cannot be used as an expression. D:\Desktop\WindowsApplication3\WindowsApplication3\Form1.vb 103 33 WindowsApplication3

我尝试使用Len代替sizeof,但第二个错误仍然存​​在。那么任何人都可以帮助我解决这两个错误。下面是 VB.NET 代码,其中有错误。

Imports System.Runtime.InteropServices
Imports System.Security.Principal
Imports System.ComponentModel

Public Class Form1
    Public Const TOKEN_DUPLICATE As UInt32 = &H2
    Public Const TOKEN_IMPERSONATE As UInt32 = &H4
    Public Const TOKEN_QUERY As UInt32 = &H8
    Public Declare Function GetTokenInformation Lib "advapi32.dll" ( _
   ByVal TokenHandle As IntPtr, ByVal TokenInformationClass As TOKEN_INFORMATION_CLASS, _
   ByVal TokenInformation As IntPtr, ByVal TokenInformationLength As System.UInt32, _
   ByRef ReturnLength As System.UInt32) As Boolean
    Declare Function DuplicateToken Lib "advapi32.dll" (ExistingTokenHandle As IntPtr, _
   SECURITY_IMPERSONATION_LEVEL As Int16, ByRef DuplicateTokenHandle As IntPtr) _
   As Boolean
    Enum TOKEN_ELEVATION_TYPE
        TokenElevationTypeDefault = 1
        TokenElevationTypeFull
        TokenElevationTypeLimited
    End Enum


    Public Enum TOKEN_INFORMATION_CLASS
        TokenUser = 1
        TokenGroups
        TokenPrivileges
        TokenOwner
        TokenPrimaryGroup
        TokenDefaultDacl
        TokenSource
        TokenType
        TokenImpersonationLevel
        TokenStatistics
        TokenRestrictedSids
        TokenSessionId
        TokenGroupsAndPrivileges
        TokenSessionReference
        TokenSandBoxInert
        TokenAuditPolicy
        TokenOrigin
        TokenElevationType
        TokenLinkedToken
        TokenElevation
        TokenHasRestrictions
        TokenAccessInformation
        TokenVirtualizationAllowed
        TokenVirtualizationEnabled
        TokenIntegrityLevel
        TokenUIAccess
        TokenMandatoryPolicy
        TokenLogonSid
        MaxTokenInfoClass
        ' MaxTokenInfoClass should always be the last enum 
    End Enum

    Public Enum SECURITY_IMPERSONATION_LEVEL
        SecurityAnonymous
        SecurityIdentification
        SecurityImpersonation
        SecurityDelegation
    End Enum


    Function IsAdmin() As Boolean
        Dim identity = WindowsIdentity.GetCurrent()
        Return (identity IsNot Nothing AndAlso New WindowsPrincipal(identity).IsInRole(WindowsBuiltInRole.Administrator))
    End Function

    ''' <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>
    Function CanBeAdmin() As Boolean
        Dim fInAdminGroup As Boolean = False
        Dim hToken As IntPtr = IntPtr.Zero
        Dim hTokenToCheck As IntPtr = IntPtr.Zero
        Dim pElevationType As IntPtr = IntPtr.Zero
        Dim pLinkedToken As IntPtr = IntPtr.Zero
        Dim cbSize As Integer = 0

        If IsAdmin() Then
            Return True
        End If

        Try
            ' Check the token for this user
            hToken = WindowsIdentity.GetCurrent().Token

            ' 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 Then
                ' 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)
                Dim cbSizeuint As UInteger = Convert.ToUInt32(cbSize)
                pElevationType = Marshal.AllocHGlobal(cbSize)
                If pElevationType = IntPtr.Zero Then
                    Throw New Win32Exception(Marshal.GetLastWin32Error())
                End If

                ' Retrieve token elevation type information.
                If Not GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenElevationType, pElevationType, cbSizeuint, cbSizeuint) Then
                    Throw New Win32Exception(Marshal.GetLastWin32Error())
                End If

                ' Marshal the TOKEN_ELEVATION_TYPE enum from native to .NET.
                Dim elevType As TOKEN_ELEVATION_TYPE = CType(Marshal.ReadInt32(pElevationType), TOKEN_ELEVATION_TYPE)

                ' If limited, get the linked elevated token for further check.
                If elevType = TOKEN_ELEVATION_TYPE.TokenElevationTypeLimited Then
                    ' Allocate a buffer for the linked token.
                    cbSize = IntPtr.Size
                    Dim cbSizeuint_ee As UInteger = Convert.ToUInt32(cbSize)
                    pLinkedToken = Marshal.AllocHGlobal(cbSize)
                    If pLinkedToken = IntPtr.Zero Then
                        Throw New Win32Exception(Marshal.GetLastWin32Error())
                    End If

                    ' Get the linked token.
                    If Not GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenLinkedToken, pLinkedToken, cbSizeuint_ee, cbSizeuint_ee) Then
                        Throw New Win32Exception(Marshal.GetLastWin32Error())
                    End If

                    ' Marshal the linked token value from native to .NET.
                    hTokenToCheck = Marshal.ReadIntPtr(pLinkedToken)
                End If
            End If

            ' 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 = IntPtr.Zero Then
                If Not DuplicateToken(hToken, CInt(SECURITY_IMPERSONATION_LEVEL.SecurityIdentification), hTokenToCheck) Then
                    Throw New Win32Exception(Marshal.GetLastWin32Error())
                End If
            End If

            ' Check if the token to be checked contains admin SID.
            Dim id As New WindowsIdentity(hTokenToCheck)
            Dim principal As New WindowsPrincipal(id)

            fInAdminGroup = principal.IsInRole(WindowsBuiltInRole.Administrator)
        Catch
            Return False
        Finally
            ' Centralized cleanup for all allocated resources.
            If pElevationType <> IntPtr.Zero Then
                Marshal.FreeHGlobal(pElevationType)
                pElevationType = IntPtr.Zero
            End If
            If pLinkedToken <> IntPtr.Zero Then
                Marshal.FreeHGlobal(pLinkedToken)
                pLinkedToken = IntPtr.Zero
            End If
        End Try

        Return fInAdminGroup
    End Function
    Private Sub Form1_Load(sender As Object, e As EventArgs)
        If CanBeAdmin() Then
            MessageBox.Show("admin")
        Else
            MessageBox.Show("not admin")
        End If
    End Sub
End Class

您可以使用 Marshal.SizeOf 获取基础类型的大小来获得 C# cbSize = sizeof(TOKEN_ELEVATION_TYPE) 的效果。

Dim undertype As Type = [Enum].GetUnderlyingType(GetType(TOKEN_ELEVATION_TYPE))
cbSize = System.Runtime.InteropServices.Marshal.SizeOf(undertype)

当我 运行 它时,undertype 是 System.Int32,cbSize 是 4。