Link to home
Start Free TrialLog in
Avatar of twedds
twedds

asked on

Does anybody know how to change registry permissions from VB.

Does anybody know how to change registry permissions from VB.

OS = WinXP

I need to change a reg key that is READ ONLY.....

HKLM\SYSTEM\ControlSet001\Enum

Code example would be much appreciated.
Avatar of Mikal613
Mikal613
Flag of United States of America image

Never tried this in 2000, but it works in NT.

You could try impersonation code when you access the key.  Call Logon to make the code behave in the security context of the user you specify.  Call logoff again to reset security context of the running code.

Declare Function RevertToSelf Lib "advapi32.dll" () As Long

Declare Function LogonUser Lib "advapi32.dll" Alias "LogonUserA" (ByVal lpszUsername As String, ByVal
lpszDomain As String, ByVal lpszPassword As String, ByVal dwLogonType As Long, ByVal dwLogonProvider
As Long, phToken As Long) As Long

Declare Function ImpersonateLoggedOnUser Lib "advapi32.dll" (ByVal hToken As Long) As Long

Const LOGON32_LOGON_INTERACTIVE = 2
Const LOGON32_PROVIDER_DEFAULT = 0


Public Sub Logon(ByVal strAdminUser As String, ByVal strAdminPassword As String, ByVal strAdminDomain
As String)
 
 Dim lngTokenHandle, lngLogonType, lngLogonProvider As Long
 Dim blnResult As Boolean
 
 lngLogonType = LOGON32_LOGON_INTERACTIVE
 lngLogonProvider = LOGON32_PROVIDER_DEFAULT
 
 blnResult = RevertToSelf()
 
 blnResult = LogonUser(strAdminUser, strAdminDomain, strAdminPassword, lngLogonType, lngLogonProvider,
lngTokenHandle)
                                                     
 blnResult = ImpersonateLoggedOnUser(lngTokenHandle)
End Sub

Public Sub Logoff()
 Dim blnResult As Boolean
 
 blnResult = RevertToSelf()
End Sub
Avatar of osmodean
osmodean

Dim key As Microsoft.Win32.RegistryKey
key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Names", True)
key.DeleteValue("Name")

Compiling the Code

Replace the "Names" parameter with the name of a key that exists directly under the HKEY_CURRENT_USER node of the registry.

Replace the "Name" parameter with the name of a value that exists directly under the "Names" node.

Changing the True parameter to False makes the key read-only, and you will not be able to delete it using the key variable.

I suggest setting the second parameter to "True"

Usefull tutorials on registries:

http://www.planet-source-code.com/vb/scripts/ShowCode.asp?lngWId=1&txtCodeId=1881
http://www.codetoad.com/vb_modify_registry.asp
Unfortuneately it's rather hard to do...

Here is an examble using VB.Net (sorry... that's the only sample, I had handy) and it's designed for setting permissions on files (so there's obviously some work to do to make it work on registry keys).   Anyway, at least you'd get a sense for the level of effort required to do what you want.

Imports System.Runtime.InteropServices
Imports System.IO
Imports System.ComponentModel
Module SetPerms3
    ' Type of Securable Object we are operating in this sample code
    Private Const SE_FILE_OBJECT = 1&

    ' The Security Information constants required
    Private Const DACL_SECURITY_INFORMATION = 4&
    Private Const SET_ACCESS = 2&

    ' Standard access rights extracted from WinNT.h
    Private Const SYNCHRONIZE = &H100000
    Private Const READ_CONTROL = &H20000
    Private Const WRITE_DAC = &H40000
    Private Const WRITE_OWNER = &H80000
    Private Const STANDARD_RIGHTS_READ = (READ_CONTROL)
    Private Const STANDARD_RIGHTS_WRITE = (READ_CONTROL)
    Private Const DELETE = &H10000
    Private Const DELETE_CHILD = &H40
    Private Const ALL_ACCESS = &HF0000 Or SYNCHRONIZE Or &H1FF

    ' Generic access rights extracted from WinNT.h
    Private Const GENERIC_ALL = &H10000000
    Private Const GENERIC_EXECUTE = &H20000000
    Private Const GENERIC_READ = &H80000000
    Private Const GENERIC_WRITE = &H40000000

    ' Inheritance Flags
    Private Const CONTAINER_INHERIT_ACE = &H2
    Private Const OBJECT_INHERIT_ACE = &H1

    'typedef struct _TRUSTEE {
    '  PTRUSTEE pMultipleTrustee;
    '  MULTIPLE_TRUSTEE_OPERATION MultipleTrusteeOperation;
    '  TRUSTEE_FORM TrusteeForm;
    '  TRUSTEE_TYPE TrusteeType;
    '  LPTSTR ptstrName;
    '} TRUSTEE, *PTRUSTEE;
    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto, Pack:=4)> _
    Public Structure TRUSTEE
        Dim pMultipleTrustee As Integer ' must be null, so no need for IntPtr
        Dim MultipleTrusteeOperation As Integer
        Dim TrusteeForm As Integer
        Dim TrusteeType As Integer
        Dim ptstrName As String
    End Structure

    'typedef struct _EXPLICIT_ACCESS {
    '  DWORD grfAccessPermissions;
    '  ACCESS_MODE grfAccessMode;
    '  DWORD grfInheritance;
    '  TRUSTEE Trustee;
    '} EXPLICIT_ACCESS, *PEXPLICIT_ACCESS;
    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto, Pack:=4)> _
    Public Structure EXPLICIT_ACCESS
        Dim grfAccessPermissions As Integer
        Dim grfAccessMode As Integer
        Dim grfInheritance As Integer
        Dim Trustee As Trustee
    End Structure

    'VOID BuildExplicitAccessWithName(
    '  PEXPLICIT_ACCESS pExplicitAccess,
    '  LPTSTR pTrusteeName,
    '  DWORD AccessPermissions,
    '  ACCESS_MODE AccessMode,
    '  DWORD Inheritance
    ');
    Declare Auto Sub BuildExplicitAccessWithName Lib "AdvAPI32.DLL" ( _
    ByRef pExplicitAccess As EXPLICIT_ACCESS, _
    ByVal pTrusteeName As String, _
    ByVal AccessPermissions As Integer, _
    ByVal AccessMode As Short, _
    ByVal Inheritance As Integer)

    'DWORD SetEntriesInAcl(
    '  ULONG cCountOfExplicitEntries,
    '  PEXPLICIT_ACCESS pListOfExplicitEntries,
    '  PACL OldAcl,
    '  PACL* NewAcl
    ');
    Declare Auto Function SetEntriesInAcl Lib "AdvAPI32.DLL" ( _
    ByVal cCountOfExplicitEntries As Integer, _
    ByRef pListOfExplicitEntries As EXPLICIT_ACCESS, _
    ByVal OldAcl As IntPtr, _
    ByRef NewAcl As IntPtr) As Integer

    'DWORD GetNamedSecurityInfo(
    '  LPTSTR pObjectName,
    '  SE_OBJECT_TYPE ObjectType,
    '  SECURITY_INFORMATION SecurityInfo,
    '  PSID* ppsidOwner,
    '  PSID* ppsidGroup,
    '  PACL* ppDacl,
    '  PACL* ppSacl,
    '  PSECURITY_DESCRIPTOR* ppSecurityDescriptor
    ');
    Declare Auto Function GetNamedSecurityInfo Lib "AdvAPI32.DLL" ( _
    ByVal pObjectName As String, _
    ByVal ObjectType As Integer, _
    ByVal SecurityInfo As Integer, _
    ByRef ppsidOwner As IntPtr, _
    ByRef ppsidGroup As IntPtr, _
    ByRef ppDacl As IntPtr, _
    ByRef ppSacl As IntPtr, _
    ByRef ppSecurityDescriptor As IntPtr) As Integer

    'DWORD SetNamedSecurityInfo(
    '  LPTSTR pObjectName,
    '  SE_OBJECT_TYPE ObjectType,
    '  SECURITY_INFORMATION SecurityInfo,
    '  PSID psidOwner,
    '  PSID psidGroup,
    '  PACL pDacl,
    '  PACL pSacl
    ');
    Declare Auto Function SetNamedSecurityInfo Lib "AdvAPI32.DLL" ( _
    ByVal pObjectName As String, _
    ByVal ObjectType As Integer, _
    ByVal SecurityInfo As Integer, _
    ByVal psidOwner As IntPtr, _
    ByVal psidGroup As IntPtr, _
    ByVal pDacl As IntPtr, _
    ByVal pSacl As IntPtr) As Integer

    Public Declare Function LocalFree Lib "kernel32" ( _
    ByVal hMem As IntPtr) As Integer

    Sub SetPermissions(ByRef strPath As String, ByVal strUserName As String, ByVal strPerm As String)
        Dim pSecDesc, pNewDACL, pOldDACL As IntPtr
        Dim ea As EXPLICIT_ACCESS
        Dim Win32Error As Win32Exception
        Dim ret, iPerm As Integer
        Dim bIsFile As Boolean

        ' Do a quick sanity check!
        bIsFile = True
        If File.Exists(strPath) = False Then
            If Directory.Exists(strPath) = False Then
                Throw New Exception("File or Directory not found")
            End If
            bIsFile = False
        End If

        ' Translate the desired permissions
        Select Case strPerm
            Case "Full Control"
                iPerm = ALL_ACCESS
            Case "Modify"
                iPerm = ALL_ACCESS And Not (WRITE_DAC Or WRITE_OWNER Or DELETE_CHILD)
            Case "Read & Execute"
                iPerm = GENERIC_READ Or GENERIC_EXECUTE
            Case "List Folder Contents"
                If bIsFile = False Then
                    Throw New Exception("Permission argument not applicable to files")
                End If
                iPerm = GENERIC_EXECUTE
            Case "Read"
                iPerm = GENERIC_READ
            Case "Write"
                iPerm = GENERIC_WRITE
            Case Else
                Throw New Exception("Invalid permission argument")
        End Select

        ' get the Security Descriptor and DACL
        ret = GetNamedSecurityInfo(strPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, Nothing, Nothing, pOldDACL, Nothing, pSecDesc)
        If ret <> 0 Then
            Win32Error = New Win32Exception(ret)
            Throw New Exception(Win32Error.Message)
        End If

        ' build an explicit access structure
        BuildExplicitAccessWithName(ea, strUserName, iPerm, SET_ACCESS, CONTAINER_INHERIT_ACE Or OBJECT_INHERIT_ACE)

        ' merge this Explict Access with the existing DACL
        ret = SetEntriesInAcl(1, ea, pOldDACL, pNewDACL)
        If ret <> 0 Then
            Win32Error = New Win32Exception(ret)
            Throw New Exception(Win32Error.Message)
        End If

        ' write the new Security Descriptor/DACL back
        ret = SetNamedSecurityInfo(strPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, Nothing, Nothing, pNewDACL, Nothing)
        If ret <> 0 Then
            Win32Error = New Win32Exception(ret)
            Throw New Exception(Win32Error.Message)
        End If

        ' clean up and go home
        LocalFree(pNewDACL)
        LocalFree(pSecDesc)
    End Sub
End Module
impersonation i
Those registry keys are set with SYSTEM as the only user with write permission.... that's a little hard to do with impersonsation
Avatar of twedds

ASKER

Thanks for all the comments....

In the end I used REGINI.EXE with a script and invoked it from a SHELL

The script goes like this:

\Registry\Machine\SYSTEM\ControlSet001\Enum [1 5 7 17]
\Registry\Machine\SYSTEM\ControlSet001\Enum\Root\Key
      Value = REG_DWORD 0x00000000

and it works...

if anybody wants more info you can get it at:

http://support.microsoft.com/?kbid=237607
Avatar of twedds

ASKER

Agreed,

Moderator, please refund points and save as a 0-pt PAQ
ASKER CERTIFIED SOLUTION
Avatar of PAQ_Man
PAQ_Man
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial