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.
OS = WinXP
I need to change a reg key that is READ ONLY.....
HKLM\SYSTEM\ControlSet001\
Code example would be much appreciated.
Dim key As Microsoft.Win32.RegistryKe y
key = Microsoft.Win32.Registry.C urrentUser .OpenSubKe y("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
key = Microsoft.Win32.Registry.C
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.InteropServ ices
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.S equential, 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.S equential, 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 BuildExplicitAccessWithNam e(
' PEXPLICIT_ACCESS pExplicitAccess,
' LPTSTR pTrusteeName,
' DWORD AccessPermissions,
' ACCESS_MODE AccessMode,
' DWORD Inheritance
');
Declare Auto Sub BuildExplicitAccessWithNam e 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(strPa th, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, Nothing, Nothing, pOldDACL, Nothing, pSecDesc)
If ret <> 0 Then
Win32Error = New Win32Exception(ret)
Throw New Exception(Win32Error.Messa ge)
End If
' build an explicit access structure
BuildExplicitAccessWithNam e(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.Messa ge)
End If
' write the new Security Descriptor/DACL back
ret = SetNamedSecurityInfo(strPa th, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, Nothing, Nothing, pNewDACL, Nothing)
If ret <> 0 Then
Win32Error = New Win32Exception(ret)
Throw New Exception(Win32Error.Messa ge)
End If
' clean up and go home
LocalFree(pNewDACL)
LocalFree(pSecDesc)
End Sub
End Module
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.InteropServ
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
' TRUSTEE_FORM TrusteeForm;
' TRUSTEE_TYPE TrusteeType;
' LPTSTR ptstrName;
'} TRUSTEE, *PTRUSTEE;
<StructLayout(LayoutKind.S
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.S
Public Structure EXPLICIT_ACCESS
Dim grfAccessPermissions As Integer
Dim grfAccessMode As Integer
Dim grfInheritance As Integer
Dim Trustee As Trustee
End Structure
'VOID BuildExplicitAccessWithNam
' PEXPLICIT_ACCESS pExplicitAccess,
' LPTSTR pTrusteeName,
' DWORD AccessPermissions,
' ACCESS_MODE AccessMode,
' DWORD Inheritance
');
Declare Auto Sub BuildExplicitAccessWithNam
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(strPa
If ret <> 0 Then
Win32Error = New Win32Exception(ret)
Throw New Exception(Win32Error.Messa
End If
' build an explicit access structure
BuildExplicitAccessWithNam
' 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.Messa
End If
' write the new Security Descriptor/DACL back
ret = SetNamedSecurityInfo(strPa
If ret <> 0 Then
Win32Error = New Win32Exception(ret)
Throw New Exception(Win32Error.Messa
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
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\C ontrolSet0 01\Enum [1 5 7 17]
\Registry\Machine\SYSTEM\C ontrolSet0 01\Enum\Ro ot\Key
Value = REG_DWORD 0x00000000
and it works...
if anybody wants more info you can get it at:
http://support.microsoft.com/?kbid=237607
In the end I used REGINI.EXE with a script and invoked it from a SHELL
The script goes like this:
\Registry\Machine\SYSTEM\C
\Registry\Machine\SYSTEM\C
Value = REG_DWORD 0x00000000
and it works...
if anybody wants more info you can get it at:
http://support.microsoft.com/?kbid=237607
ASKER
Agreed,
Moderator, please refund points and save as a 0-pt PAQ
Moderator, please refund points and save as a 0-pt PAQ
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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(ln
End Sub
Public Sub Logoff()
Dim blnResult As Boolean
blnResult = RevertToSelf()
End Sub