locked
RegLoadKey RRS feed

  • Question

  • I'm trying to convert this http://support.microsoft.com/kb/297060 sample code into vb.net but I keep getting the error Attempted to read or write protected memory. This is often an indication that other memory is corrupt.(AccessViolationException was unhandled).
    Thanks in advance!
    Friday, February 8, 2008 10:02 AM

Answers

  • This might work for you, or at least get you closer by fixing up the p/invoke. I get an error "The process cannot access the file because it is being used by another process", and it turns up a lot on google. On my computer NTUser.dat is held open by the SYSTEM process.

     

    I was slightly lazy and called adjustTokenPrivileges twice rather than work out how to marshal two LUID_AND_ATTRIBUTES in one TOKEN_PRIVILEGES. You probably need to use an IntPtr for the Privileges field, and marshal the data to it manually.

     

    Code Snippet
    Option Explicit On
    Option
    Strict On

    Imports
    System.Runtime.InteropServices
    Imports System.ComponentModel

    Public Class Form1

        
    Private Structure TOKEN_PRIVILEGES
            
    Public PrivilegeCount As UInteger
            Public Privileges As LUID_AND_ATTRIBUTES
            
    Public Function Size() As Integer
                Return Marshal.SizeOf(Me)
            
    End Function
        End Structure

        Private Structure LUID
            
    Private lowPart As UInt32
            
    Private highPart As Int32
        
    End Structure

        Private Structure LUID_AND_ATTRIBUTES
            
    Public luid As LUID
            
    Public attributes As UInt32
        
    End Structure

        Private Const TOKEN_ADJUST_PRIVLEGES As UInteger = &H20UI
        
    Private Const TOKEN_QUERY As UInteger = &H8UI
        
    Private Const SE_PRIVILEGE_ENABLED As UInteger = &H2UI
        
    Private Const HKEY_CURRENT_USER As UInteger = &H80000001UI
        
    Private Const SE_RESTORE_NAME As String = "SeRestorePrivilege"
        Private Const SE_BACKUP_NAME As String = "SeBackupPrivilege"

        ' System.Diagnostics.Process.Handle
        <DllImport("kernel32")> _
        
    Private Shared Function GetCurrentProcess() As IntPtr
        
    End Function

        <DllImport("advapi32", SetLastError:=True)> _
        
    Private Shared Function OpenProcessToken( _
            
    ByVal ProcessHandle As IntPtr, _
            
    ByVal DesiredAccess As UInteger, _
            
    ByRef TokenHandle As IntPtr) As Integer
        End Function

        <DllImport("advapi32", CharSet:=CharSet.Ansi, SetLastError:=True)> _
        
    Private Shared Function LookupPrivilegeValue( _
            
    ByVal lpSystemName As String, _
            
    ByVal lpName As String, _
            
    ByRef lpLuid As LUID) As Integer
        End Function

        <DllImport("advapi32", CharSet:=CharSet.Ansi, SetLastError:=True)> _
        
    Private Shared Function AdjustTokenPrivileges( _
            
    ByVal TokenHandle As IntPtr, _
            
    ByVal DisableAllPrivileges As Integer, _
            
    ByRef NewState As TOKEN_PRIVILEGES, _
            
    ByVal BufferLength As Integer, _
            
    ByRef PreviousState As TOKEN_PRIVILEGES, _
            
    ByRef ReturnLength As Integer) As Integer
        End Function

        <DllImport("advapi32", CharSet:=CharSet.Ansi, SetLastError:=True)> _
        
    Private Shared Function RegLoadKey( _
            
    ByVal hKey As UInteger, _
            
    ByVal lpSubKey As String, _
            
    ByVal lpFile As String) As Integer
        End Function

        <DllImport("advapi32", CharSet:=CharSet.Ansi, SetLastError:=True)> _
        
    Private Shared Function RegUnLoadKey( _
            
    ByVal hKey As UInteger, _
            
    ByVal lpSubKey As String) As Integer
        End Function

        Private strKeyName As String
        Private MyToken As IntPtr
        
    Private TP1 As TOKEN_PRIVILEGES
        
    Private TP2 As TOKEN_PRIVILEGES
        
    Private hBlob As IntPtr
        
    Private Text1 As New TextBox
        
    Private WithEvents Command1 As New Button
        
    Private WithEvents Command2 As New Button

        
    Sub New()
            InitializeComponent()
            
    Me.Controls.AddRange(New Control() {Text1, Command1, Command2})
            Command1.Location =
    New Point(0, Text1.Bottom + 10)
            Command2.Location =
    New Point(0, Command1.Bottom + 10)
        
    End Sub

        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            strKeyName =
    "keyLoaded"
            Text1.Text = "C:\Documents and Settings\jo0ls\ntuser.dat"
            Command2.Enabled = False

            Dim hProcess As IntPtr = GetCurrentProcess() ' is -1 as it should.

            Dim retVal As Integer = OpenProcessToken( _
                                       hProcess, _
                                       TOKEN_ADJUST_PRIVLEGES
    Or TOKEN_QUERY, MyToken)

            
    If retVal = 0 Then Throw New Win32Exception
            
    Dim RestoreLuid As LUID

            retVal = LookupPrivilegeValue(
    Nothing, SE_RESTORE_NAME, RestoreLuid)

            
    If retVal = 0 Then Throw New Win32Exception
            
    Dim BackupLuid As LUID
            retVal = LookupPrivilegeValue(
    Nothing, SE_BACKUP_NAME, BackupLuid)
            
    If retVal = 0 Then Throw New Win32Exception
            TP1.PrivilegeCount = 1
            TP1.Privileges.attributes = SE_PRIVILEGE_ENABLED
            TP1.Privileges.luid = RestoreLuid
            
    Dim returnLength As Integer = 0
            
    Dim oldPrivileges As TOKEN_PRIVILEGES
            retVal = AdjustTokenPrivileges(MyToken, 0, TP1, TP1.Size, oldPrivileges, returnLength)
            
    If retVal = 0 Then            
                
    Throw New Win32Exception
            
    End If
            TP2.PrivilegeCount = 1
            TP2.Privileges.attributes = SE_PRIVILEGE_ENABLED
            TP2.Privileges.luid = BackupLuid
            retVal = AdjustTokenPrivileges(MyToken, 0, TP2, TP2.Size, oldPrivileges, returnLength)
            
    If retVal = 0 Then
                Throw New Win32Exception
            
    End If

        End Sub

        Private Sub Command1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Command1.Click
            
    Dim retval As Integer = RegLoadKey(HKEY_CURRENT_USER, strKeyName, Text1.Text)
            
    If retval <> 0 Then
                MessageBox.Show(retval & ", " & Hex(retval))
                
    Throw New Win32Exception(retval)
            
    End If
            Command2.Enabled = True
        End Sub

        Private Sub Command2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Command2.Click
            
    Dim retval As Integer = RegUnLoadKey(HKEY_CURRENT_USER, strKeyName)
            
    If retval <> 0 Then
                Throw New Win32Exception
            
    End If
        End Sub

        Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
            
    Dim returnLength As Integer = 0
            
    Dim retval As Integer = AdjustTokenPrivileges(MyToken, 0, TP1, TP1.Size, Nothing, returnLength)
            
    If retval = 0 Then Throw New Win32Exception
            retval = AdjustTokenPrivileges(MyToken, 0, TP2, TP2.Size,
    Nothing, returnLength)
            
    If retval = 0 Then Throw New Win32Exception
        
    End Sub

    End
    Class

     

     

     

     

    Monday, February 11, 2008 2:27 AM

All replies

  • This might work for you, or at least get you closer by fixing up the p/invoke. I get an error "The process cannot access the file because it is being used by another process", and it turns up a lot on google. On my computer NTUser.dat is held open by the SYSTEM process.

     

    I was slightly lazy and called adjustTokenPrivileges twice rather than work out how to marshal two LUID_AND_ATTRIBUTES in one TOKEN_PRIVILEGES. You probably need to use an IntPtr for the Privileges field, and marshal the data to it manually.

     

    Code Snippet
    Option Explicit On
    Option
    Strict On

    Imports
    System.Runtime.InteropServices
    Imports System.ComponentModel

    Public Class Form1

        
    Private Structure TOKEN_PRIVILEGES
            
    Public PrivilegeCount As UInteger
            Public Privileges As LUID_AND_ATTRIBUTES
            
    Public Function Size() As Integer
                Return Marshal.SizeOf(Me)
            
    End Function
        End Structure

        Private Structure LUID
            
    Private lowPart As UInt32
            
    Private highPart As Int32
        
    End Structure

        Private Structure LUID_AND_ATTRIBUTES
            
    Public luid As LUID
            
    Public attributes As UInt32
        
    End Structure

        Private Const TOKEN_ADJUST_PRIVLEGES As UInteger = &H20UI
        
    Private Const TOKEN_QUERY As UInteger = &H8UI
        
    Private Const SE_PRIVILEGE_ENABLED As UInteger = &H2UI
        
    Private Const HKEY_CURRENT_USER As UInteger = &H80000001UI
        
    Private Const SE_RESTORE_NAME As String = "SeRestorePrivilege"
        Private Const SE_BACKUP_NAME As String = "SeBackupPrivilege"

        ' System.Diagnostics.Process.Handle
        <DllImport("kernel32")> _
        
    Private Shared Function GetCurrentProcess() As IntPtr
        
    End Function

        <DllImport("advapi32", SetLastError:=True)> _
        
    Private Shared Function OpenProcessToken( _
            
    ByVal ProcessHandle As IntPtr, _
            
    ByVal DesiredAccess As UInteger, _
            
    ByRef TokenHandle As IntPtr) As Integer
        End Function

        <DllImport("advapi32", CharSet:=CharSet.Ansi, SetLastError:=True)> _
        
    Private Shared Function LookupPrivilegeValue( _
            
    ByVal lpSystemName As String, _
            
    ByVal lpName As String, _
            
    ByRef lpLuid As LUID) As Integer
        End Function

        <DllImport("advapi32", CharSet:=CharSet.Ansi, SetLastError:=True)> _
        
    Private Shared Function AdjustTokenPrivileges( _
            
    ByVal TokenHandle As IntPtr, _
            
    ByVal DisableAllPrivileges As Integer, _
            
    ByRef NewState As TOKEN_PRIVILEGES, _
            
    ByVal BufferLength As Integer, _
            
    ByRef PreviousState As TOKEN_PRIVILEGES, _
            
    ByRef ReturnLength As Integer) As Integer
        End Function

        <DllImport("advapi32", CharSet:=CharSet.Ansi, SetLastError:=True)> _
        
    Private Shared Function RegLoadKey( _
            
    ByVal hKey As UInteger, _
            
    ByVal lpSubKey As String, _
            
    ByVal lpFile As String) As Integer
        End Function

        <DllImport("advapi32", CharSet:=CharSet.Ansi, SetLastError:=True)> _
        
    Private Shared Function RegUnLoadKey( _
            
    ByVal hKey As UInteger, _
            
    ByVal lpSubKey As String) As Integer
        End Function

        Private strKeyName As String
        Private MyToken As IntPtr
        
    Private TP1 As TOKEN_PRIVILEGES
        
    Private TP2 As TOKEN_PRIVILEGES
        
    Private hBlob As IntPtr
        
    Private Text1 As New TextBox
        
    Private WithEvents Command1 As New Button
        
    Private WithEvents Command2 As New Button

        
    Sub New()
            InitializeComponent()
            
    Me.Controls.AddRange(New Control() {Text1, Command1, Command2})
            Command1.Location =
    New Point(0, Text1.Bottom + 10)
            Command2.Location =
    New Point(0, Command1.Bottom + 10)
        
    End Sub

        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            strKeyName =
    "keyLoaded"
            Text1.Text = "C:\Documents and Settings\jo0ls\ntuser.dat"
            Command2.Enabled = False

            Dim hProcess As IntPtr = GetCurrentProcess() ' is -1 as it should.

            Dim retVal As Integer = OpenProcessToken( _
                                       hProcess, _
                                       TOKEN_ADJUST_PRIVLEGES
    Or TOKEN_QUERY, MyToken)

            
    If retVal = 0 Then Throw New Win32Exception
            
    Dim RestoreLuid As LUID

            retVal = LookupPrivilegeValue(
    Nothing, SE_RESTORE_NAME, RestoreLuid)

            
    If retVal = 0 Then Throw New Win32Exception
            
    Dim BackupLuid As LUID
            retVal = LookupPrivilegeValue(
    Nothing, SE_BACKUP_NAME, BackupLuid)
            
    If retVal = 0 Then Throw New Win32Exception
            TP1.PrivilegeCount = 1
            TP1.Privileges.attributes = SE_PRIVILEGE_ENABLED
            TP1.Privileges.luid = RestoreLuid
            
    Dim returnLength As Integer = 0
            
    Dim oldPrivileges As TOKEN_PRIVILEGES
            retVal = AdjustTokenPrivileges(MyToken, 0, TP1, TP1.Size, oldPrivileges, returnLength)
            
    If retVal = 0 Then            
                
    Throw New Win32Exception
            
    End If
            TP2.PrivilegeCount = 1
            TP2.Privileges.attributes = SE_PRIVILEGE_ENABLED
            TP2.Privileges.luid = BackupLuid
            retVal = AdjustTokenPrivileges(MyToken, 0, TP2, TP2.Size, oldPrivileges, returnLength)
            
    If retVal = 0 Then
                Throw New Win32Exception
            
    End If

        End Sub

        Private Sub Command1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Command1.Click
            
    Dim retval As Integer = RegLoadKey(HKEY_CURRENT_USER, strKeyName, Text1.Text)
            
    If retval <> 0 Then
                MessageBox.Show(retval & ", " & Hex(retval))
                
    Throw New Win32Exception(retval)
            
    End If
            Command2.Enabled = True
        End Sub

        Private Sub Command2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Command2.Click
            
    Dim retval As Integer = RegUnLoadKey(HKEY_CURRENT_USER, strKeyName)
            
    If retval <> 0 Then
                Throw New Win32Exception
            
    End If
        End Sub

        Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
            
    Dim returnLength As Integer = 0
            
    Dim retval As Integer = AdjustTokenPrivileges(MyToken, 0, TP1, TP1.Size, Nothing, returnLength)
            
    If retval = 0 Then Throw New Win32Exception
            retval = AdjustTokenPrivileges(MyToken, 0, TP2, TP2.Size,
    Nothing, returnLength)
            
    If retval = 0 Then Throw New Win32Exception
        
    End Sub

    End
    Class

     

     

     

     

    Monday, February 11, 2008 2:27 AM
  • I got it working! Thanks for the help. I got access denied at first but then I realized you were loading the hive into HKEY_CURRENT_USER, instead of HKEY_USERS. I changed the UInteger value in the RegLoadKey and RegUnloadKey functions as well. Thanks for your help!

    Tuesday, February 12, 2008 5:37 AM
  • jo0ls you are my savior :-)  I've been struggling with this for a whole day trying to correct all the conversion errors in my VB6 to VB.net conversion.  I sort of accidentally stumbled across your post when looking up some vb to vb.net conversion information.  Can't thank you enough for taking the time to answer the original poster.

    Mike 
    Monday, June 9, 2008 8:51 PM
  • RegUnloadKey is not unloading the key from the registry I made the change to HKEY_USERS as you did (when I look at regedit after the RegUnloadKey function, which says it completes successfully). Any idea why this would be? I am running Windows7 64-bit.

    Thank you all for the work that was done on this! it is well done and very helpfull!
    Thursday, January 28, 2010 12:59 AM