-
Writing in HKEY_LOCAL_MACHINE...Access is denied
I have to store some information in the registry under the HKEY_LOCAL_MACHINE
hive. In win NT/2000, the user should have Administrator privileges to write
under HKEY_LOCAL_MACHINE. If he doesn't, there is en error 5 - Access is
denied when trying to open the key with RegOpenKeyEx. Is there a way to
write under the HKEY_LOCAL_MACHINE hive with a user without Administrator
privileges? Maybe by addind the user to the Registry key security or by
programatticly addind Administrator privileges to the user? Someone got
an idea?
Thank you
Martin
-
Re: Writing in HKEY_LOCAL_MACHINE...Access is denied
Run "C:\WINNT\system32\regedt32.exe".
Bring up Local_machine, and set the permissions under the Security menu item.
It works exactly like the file permissions dialog (setting users/groups/access).
-Rob
"Martin" <dubem@harfan.com> wrote:
>
>I have to store some information in the registry under the HKEY_LOCAL_MACHINE
>hive. In win NT/2000, the user should have Administrator privileges to write
>under HKEY_LOCAL_MACHINE. If he doesn't, there is en error 5 - Access is
>denied when trying to open the key with RegOpenKeyEx. Is there a way to
>write under the HKEY_LOCAL_MACHINE hive with a user without Administrator
>privileges? Maybe by addind the user to the Registry key security or by
>programatticly addind Administrator privileges to the user? Someone got
>an idea?
>Thank you
>Martin
-
Re: Writing in HKEY_LOCAL_MACHINE...Access is denied
Run "C:\WINNT\system32\regedt32.exe".
Bring up Local_machine, and set the permissions under the Security menu item.
It works exactly like the file permissions dialog (setting users/groups/access).
-Rob
"Martin" <dubem@harfan.com> wrote:
>
>I have to store some information in the registry under the HKEY_LOCAL_MACHINE
>hive. In win NT/2000, the user should have Administrator privileges to write
>under HKEY_LOCAL_MACHINE. If he doesn't, there is en error 5 - Access is
>denied when trying to open the key with RegOpenKeyEx. Is there a way to
>write under the HKEY_LOCAL_MACHINE hive with a user without Administrator
>privileges? Maybe by addind the user to the Registry key security or by
>programatticly addind Administrator privileges to the user? Someone got
>an idea?
>Thank you
>Martin
-
Re: Writing in HKEY_LOCAL_MACHINE...Access is denied
right...but is there a way to do it by programmation?
"Rob Teixeira" <RobTeixeira@@msn.com> wrote:
>
>
>Run "C:\WINNT\system32\regedt32.exe".
>Bring up Local_machine, and set the permissions under the Security menu
item.
>It works exactly like the file permissions dialog (setting users/groups/access).
>
>-Rob
>
>"Martin" <dubem@harfan.com> wrote:
>>
>>I have to store some information in the registry under the HKEY_LOCAL_MACHINE
>>hive. In win NT/2000, the user should have Administrator privileges to
write
>>under HKEY_LOCAL_MACHINE. If he doesn't, there is en error 5 - Access
is
>>denied when trying to open the key with RegOpenKeyEx. Is there a way
to
>>write under the HKEY_LOCAL_MACHINE hive with a user without Administrator
>>privileges? Maybe by addind the user to the Registry key security or by
>>programatticly addind Administrator privileges to the user? Someone got
>>an idea?
>>Thank you
>>Martin
>
-
Re: Writing in HKEY_LOCAL_MACHINE...Access is denied
right...but is there a way to do it by programmation?
"Rob Teixeira" <RobTeixeira@@msn.com> wrote:
>
>
>Run "C:\WINNT\system32\regedt32.exe".
>Bring up Local_machine, and set the permissions under the Security menu
item.
>It works exactly like the file permissions dialog (setting users/groups/access).
>
>-Rob
>
>"Martin" <dubem@harfan.com> wrote:
>>
>>I have to store some information in the registry under the HKEY_LOCAL_MACHINE
>>hive. In win NT/2000, the user should have Administrator privileges to
write
>>under HKEY_LOCAL_MACHINE. If he doesn't, there is en error 5 - Access
is
>>denied when trying to open the key with RegOpenKeyEx. Is there a way
to
>>write under the HKEY_LOCAL_MACHINE hive with a user without Administrator
>>privileges? Maybe by addind the user to the Registry key security or by
>>programatticly addind Administrator privileges to the user? Someone got
>>an idea?
>>Thank you
>>Martin
>
-
Re: Writing in HKEY_LOCAL_MACHINE...Access is denied
Ah, I thought you meant an either-or situation with the programming part

ADSI is the easiest way to manipulate ACL (access control lists) and user/group
information from VB.
You can find info starting here:
http://msdn.microsoft.com/library/en...asp?frame=true
I think there's even a section in there that covers some issues with setting
registry key ACL.
Under no circumstances should you add a user to an Admin group (the systems-network
support people will lynch you). However, you can modify access to a registry
key. The suggestion is to keep the access as tightly-scoped as possible.
In other words, if you only need a small branch of keys (for settings as
an example), don't open up the ACL for the entire Local_Machine hive.
However, in order to change permissions, the executing thread needs to be
running under admin credentials. So you might want to set thread credentials
to run as local admin in the first place. Do a search in MSDN under "impersonation".
Another alternative is to programmatically launch a program using CreateProcessAsUser
or CreateProcessWithLogonW.
-Rob
"Martin" <dubem@harfan.com> wrote:
>
>right...but is there a way to do it by programmation?
>
>"Rob Teixeira" <RobTeixeira@@msn.com> wrote:
>>
>>
>>Run "C:\WINNT\system32\regedt32.exe".
>>Bring up Local_machine, and set the permissions under the Security menu
>item.
>>It works exactly like the file permissions dialog (setting users/groups/access).
>>
>>-Rob
>>
>>"Martin" <dubem@harfan.com> wrote:
>>>
>>>I have to store some information in the registry under the HKEY_LOCAL_MACHINE
>>>hive. In win NT/2000, the user should have Administrator privileges to
>write
>>>under HKEY_LOCAL_MACHINE. If he doesn't, there is en error 5 - Access
>is
>>>denied when trying to open the key with RegOpenKeyEx. Is there a way
>to
>>>write under the HKEY_LOCAL_MACHINE hive with a user without Administrator
>>>privileges? Maybe by addind the user to the Registry key security or
by
>>>programatticly addind Administrator privileges to the user? Someone
got
>>>an idea?
>>>Thank you
>>>Martin
>>
>
-
Re: Writing in HKEY_LOCAL_MACHINE...Access is denied
Ah, I thought you meant an either-or situation with the programming part

ADSI is the easiest way to manipulate ACL (access control lists) and user/group
information from VB.
You can find info starting here:
http://msdn.microsoft.com/library/en...asp?frame=true
I think there's even a section in there that covers some issues with setting
registry key ACL.
Under no circumstances should you add a user to an Admin group (the systems-network
support people will lynch you). However, you can modify access to a registry
key. The suggestion is to keep the access as tightly-scoped as possible.
In other words, if you only need a small branch of keys (for settings as
an example), don't open up the ACL for the entire Local_Machine hive.
However, in order to change permissions, the executing thread needs to be
running under admin credentials. So you might want to set thread credentials
to run as local admin in the first place. Do a search in MSDN under "impersonation".
Another alternative is to programmatically launch a program using CreateProcessAsUser
or CreateProcessWithLogonW.
-Rob
"Martin" <dubem@harfan.com> wrote:
>
>right...but is there a way to do it by programmation?
>
>"Rob Teixeira" <RobTeixeira@@msn.com> wrote:
>>
>>
>>Run "C:\WINNT\system32\regedt32.exe".
>>Bring up Local_machine, and set the permissions under the Security menu
>item.
>>It works exactly like the file permissions dialog (setting users/groups/access).
>>
>>-Rob
>>
>>"Martin" <dubem@harfan.com> wrote:
>>>
>>>I have to store some information in the registry under the HKEY_LOCAL_MACHINE
>>>hive. In win NT/2000, the user should have Administrator privileges to
>write
>>>under HKEY_LOCAL_MACHINE. If he doesn't, there is en error 5 - Access
>is
>>>denied when trying to open the key with RegOpenKeyEx. Is there a way
>to
>>>write under the HKEY_LOCAL_MACHINE hive with a user without Administrator
>>>privileges? Maybe by addind the user to the Registry key security or
by
>>>programatticly addind Administrator privileges to the user? Someone
got
>>>an idea?
>>>Thank you
>>>Martin
>>
>
-
Re: Writing in HKEY_LOCAL_MACHINE...Access is denied
I can't find any example of how to modify by programmation the security of
a key in the registry. Someone got an example??
Thank you
"Rob Teixeira" <RobTeixeira@@msn.com> wrote:
>
>
>Ah, I thought you meant an either-or situation with the programming part
>
>
>ADSI is the easiest way to manipulate ACL (access control lists) and user/group
>information from VB.
>You can find info starting here:
>
>http://msdn.microsoft.com/library/en...asp?frame=true
>
>I think there's even a section in there that covers some issues with setting
>registry key ACL.
>
>Under no circumstances should you add a user to an Admin group (the systems-network
>support people will lynch you). However, you can modify access to a registry
>key. The suggestion is to keep the access as tightly-scoped as possible.
>In other words, if you only need a small branch of keys (for settings as
>an example), don't open up the ACL for the entire Local_Machine hive.
>
>However, in order to change permissions, the executing thread needs to be
>running under admin credentials. So you might want to set thread credentials
>to run as local admin in the first place. Do a search in MSDN under "impersonation".
>
>Another alternative is to programmatically launch a program using CreateProcessAsUser
>or CreateProcessWithLogonW.
>
>-Rob
>
>"Martin" <dubem@harfan.com> wrote:
>>
>>right...but is there a way to do it by programmation?
>>
>>"Rob Teixeira" <RobTeixeira@@msn.com> wrote:
>>>
>>>
>>>Run "C:\WINNT\system32\regedt32.exe".
>>>Bring up Local_machine, and set the permissions under the Security menu
>>item.
>>>It works exactly like the file permissions dialog (setting users/groups/access).
>>>
>>>-Rob
>>>
>>>"Martin" <dubem@harfan.com> wrote:
>>>>
>>>>I have to store some information in the registry under the HKEY_LOCAL_MACHINE
>>>>hive. In win NT/2000, the user should have Administrator privileges to
>>write
>>>>under HKEY_LOCAL_MACHINE. If he doesn't, there is en error 5 - Access
>>is
>>>>denied when trying to open the key with RegOpenKeyEx. Is there a way
>>to
>>>>write under the HKEY_LOCAL_MACHINE hive with a user without Administrator
>>>>privileges? Maybe by addind the user to the Registry key security or
>by
>>>>programatticly addind Administrator privileges to the user? Someone
>got
>>>>an idea?
>>>>Thank you
>>>>Martin
>>>
>>
>
-
Re: Writing in HKEY_LOCAL_MACHINE...Access is denied
I can't find any example of how to modify by programmation the security of
a key in the registry. Someone got an example??
Thank you
"Rob Teixeira" <RobTeixeira@@msn.com> wrote:
>
>
>Ah, I thought you meant an either-or situation with the programming part
>
>
>ADSI is the easiest way to manipulate ACL (access control lists) and user/group
>information from VB.
>You can find info starting here:
>
>http://msdn.microsoft.com/library/en...asp?frame=true
>
>I think there's even a section in there that covers some issues with setting
>registry key ACL.
>
>Under no circumstances should you add a user to an Admin group (the systems-network
>support people will lynch you). However, you can modify access to a registry
>key. The suggestion is to keep the access as tightly-scoped as possible.
>In other words, if you only need a small branch of keys (for settings as
>an example), don't open up the ACL for the entire Local_Machine hive.
>
>However, in order to change permissions, the executing thread needs to be
>running under admin credentials. So you might want to set thread credentials
>to run as local admin in the first place. Do a search in MSDN under "impersonation".
>
>Another alternative is to programmatically launch a program using CreateProcessAsUser
>or CreateProcessWithLogonW.
>
>-Rob
>
>"Martin" <dubem@harfan.com> wrote:
>>
>>right...but is there a way to do it by programmation?
>>
>>"Rob Teixeira" <RobTeixeira@@msn.com> wrote:
>>>
>>>
>>>Run "C:\WINNT\system32\regedt32.exe".
>>>Bring up Local_machine, and set the permissions under the Security menu
>>item.
>>>It works exactly like the file permissions dialog (setting users/groups/access).
>>>
>>>-Rob
>>>
>>>"Martin" <dubem@harfan.com> wrote:
>>>>
>>>>I have to store some information in the registry under the HKEY_LOCAL_MACHINE
>>>>hive. In win NT/2000, the user should have Administrator privileges to
>>write
>>>>under HKEY_LOCAL_MACHINE. If he doesn't, there is en error 5 - Access
>>is
>>>>denied when trying to open the key with RegOpenKeyEx. Is there a way
>>to
>>>>write under the HKEY_LOCAL_MACHINE hive with a user without Administrator
>>>>privileges? Maybe by addind the user to the Registry key security or
>by
>>>>programatticly addind Administrator privileges to the user? Someone
>got
>>>>an idea?
>>>>Thank you
>>>>Martin
>>>
>>
>
-
Re: Writing in HKEY_LOCAL_MACHINE...Access is denied
Hi,
You should run the API RegCreateKeyEx with the flags REG_OPTION_NON_VOLATILE
and (KEY_CREATE_SUB_KEY Or KEY_SET_VALUE) to let users without admin rights
be able to create/write in the registry.
Most samples on how RegCreateKeyEx works requests the highest possible rights
wich works great on Win9X but returns Errcode 5 on NT-systems. By doing so
the user can write virtually everywhere in the registry, at least those ordinary
places like hkey\local machine\Software... or hkey\current user\software...
Bu no means start juggeling with the user's rights...
Bernie
"Rob Teixeira" <RobTeixeira@@msn.com> wrote:
>
>
>Ah, I thought you meant an either-or situation with the programming part
>
>
>ADSI is the easiest way to manipulate ACL (access control lists) and user/group
>information from VB.
>You can find info starting here:
>
>http://msdn.microsoft.com/library/en...asp?frame=true
>
>I think there's even a section in there that covers some issues with setting
>registry key ACL.
>
>Under no circumstances should you add a user to an Admin group (the systems-network
>support people will lynch you). However, you can modify access to a registry
>key. The suggestion is to keep the access as tightly-scoped as possible.
>In other words, if you only need a small branch of keys (for settings as
>an example), don't open up the ACL for the entire Local_Machine hive.
>
>However, in order to change permissions, the executing thread needs to be
>running under admin credentials. So you might want to set thread credentials
>to run as local admin in the first place. Do a search in MSDN under "impersonation".
>
>Another alternative is to programmatically launch a program using CreateProcessAsUser
>or CreateProcessWithLogonW.
>
>-Rob
>
>"Martin" <dubem@harfan.com> wrote:
>>
>>right...but is there a way to do it by programmation?
>>
>>"Rob Teixeira" <RobTeixeira@@msn.com> wrote:
>>>
>>>
>>>Run "C:\WINNT\system32\regedt32.exe".
>>>Bring up Local_machine, and set the permissions under the Security menu
>>item.
>>>It works exactly like the file permissions dialog (setting users/groups/access).
>>>
>>>-Rob
>>>
>>>"Martin" <dubem@harfan.com> wrote:
>>>>
>>>>I have to store some information in the registry under the HKEY_LOCAL_MACHINE
>>>>hive. In win NT/2000, the user should have Administrator privileges to
>>write
>>>>under HKEY_LOCAL_MACHINE. If he doesn't, there is en error 5 - Access
>>is
>>>>denied when trying to open the key with RegOpenKeyEx. Is there a way
>>to
>>>>write under the HKEY_LOCAL_MACHINE hive with a user without Administrator
>>>>privileges? Maybe by addind the user to the Registry key security or
>by
>>>>programatticly addind Administrator privileges to the user? Someone
>got
>>>>an idea?
>>>>Thank you
>>>>Martin
>>>
>>
>
-
Re: Writing in HKEY_LOCAL_MACHINE...Access is denied
Hi,
You should run the API RegCreateKeyEx with the flags REG_OPTION_NON_VOLATILE
and (KEY_CREATE_SUB_KEY Or KEY_SET_VALUE) to let users without admin rights
be able to create/write in the registry.
Most samples on how RegCreateKeyEx works requests the highest possible rights
wich works great on Win9X but returns Errcode 5 on NT-systems. By doing so
the user can write virtually everywhere in the registry, at least those ordinary
places like hkey\local machine\Software... or hkey\current user\software...
Bu no means start juggeling with the user's rights...
Bernie
"Rob Teixeira" <RobTeixeira@@msn.com> wrote:
>
>
>Ah, I thought you meant an either-or situation with the programming part
>
>
>ADSI is the easiest way to manipulate ACL (access control lists) and user/group
>information from VB.
>You can find info starting here:
>
>http://msdn.microsoft.com/library/en...asp?frame=true
>
>I think there's even a section in there that covers some issues with setting
>registry key ACL.
>
>Under no circumstances should you add a user to an Admin group (the systems-network
>support people will lynch you). However, you can modify access to a registry
>key. The suggestion is to keep the access as tightly-scoped as possible.
>In other words, if you only need a small branch of keys (for settings as
>an example), don't open up the ACL for the entire Local_Machine hive.
>
>However, in order to change permissions, the executing thread needs to be
>running under admin credentials. So you might want to set thread credentials
>to run as local admin in the first place. Do a search in MSDN under "impersonation".
>
>Another alternative is to programmatically launch a program using CreateProcessAsUser
>or CreateProcessWithLogonW.
>
>-Rob
>
>"Martin" <dubem@harfan.com> wrote:
>>
>>right...but is there a way to do it by programmation?
>>
>>"Rob Teixeira" <RobTeixeira@@msn.com> wrote:
>>>
>>>
>>>Run "C:\WINNT\system32\regedt32.exe".
>>>Bring up Local_machine, and set the permissions under the Security menu
>>item.
>>>It works exactly like the file permissions dialog (setting users/groups/access).
>>>
>>>-Rob
>>>
>>>"Martin" <dubem@harfan.com> wrote:
>>>>
>>>>I have to store some information in the registry under the HKEY_LOCAL_MACHINE
>>>>hive. In win NT/2000, the user should have Administrator privileges to
>>write
>>>>under HKEY_LOCAL_MACHINE. If he doesn't, there is en error 5 - Access
>>is
>>>>denied when trying to open the key with RegOpenKeyEx. Is there a way
>>to
>>>>write under the HKEY_LOCAL_MACHINE hive with a user without Administrator
>>>>privileges? Maybe by addind the user to the Registry key security or
>by
>>>>programatticly addind Administrator privileges to the user? Someone
>got
>>>>an idea?
>>>>Thank you
>>>>Martin
>>>
>>
>
-
Re: Writing in HKEY_LOCAL_MACHINE...Access is denied
"Bernie" <magnus.bernroth@rejlers.se> wrote:
>
>Hi,
>
>You should run the API RegCreateKeyEx with the flags REG_OPTION_NON_VOLATILE
>and (KEY_CREATE_SUB_KEY Or KEY_SET_VALUE) to let users without admin rights
>be able to create/write in the registry.
>
>Most samples on how RegCreateKeyEx works requests the highest possible rights
>wich works great on Win9X but returns Errcode 5 on NT-systems. By doing
so
>the user can write virtually everywhere in the registry, at least those
ordinary
>places like hkey\local machine\Software... or hkey\current user\software...
>
>Bu no means start juggeling with the user's rights...
>
>Bernie
Well, what the heck. Try this code. It's on the house!!
Put it in a module and call it's varoius functions. There is a lot of comments
in it, especially concerning the aspect of rights!! Most of it works on 9X,
NT, 2K and XP though some parts haven't been fully tested on all OS's yet
(see the notes inside). I guess the last function GetComputerName() explains
how to simply name the keys as strings...
Option Explicit
'Registry classes....
Private Const HKEY_CLASSES_ROOT = &H80000000
Private Const HKEY_CURRENT_USER = &H80000001
Private Const HKEY_LOCAL_MACHINE = &H80000002
Private Const HKEY_USERS = &H80000003
'Predefined value types (just a few of them used here)...
Private Const REG_NONE = (0) 'No value type
Private Const REG_SZ = (1) 'Unicode null terminated
string
Private Const REG_EXPAND_SZ = (2) 'Unicode null terminated
string with environment variable
Private Const REG_BINARY = (3) 'Binary format
Private Const REG_DWORD = (4) '32-bit number
Private Const REG_DWORD_LITTLE_ENDIAN = (4) '32-bit number (same
as REG_DWORD)
Private Const REG_DWORD_BIG_ENDIAN = (5) '32-bit number
Private Const REG_LINK = (6) 'Symbolic Link (unicode)
Private Const REG_MULTI_SZ = (7) 'Multiple Unicode strings
Private Const REG_RESOURCE_LIST = (8) 'Resource list in resource
map
Private Const REG_FULL_RESOURCE_DESCRIPTOR = (9) 'Resource list in hardware
description
Private Const REG_RESOURCE_REQUIREMENTS_LIST = (10) '??????
Private Const REG_OPTION_NON_VOLATILE = 0
'This is a tricky part when i comes to NT/W2000 to
'handle the security nicely. You should not need to
'be an Admin to make use of the registry when running
'an application. It is the programmers responsibility
'to make these routines work properly...
Private Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End Type
Private Const KEY_QUERY_VALUE = &H1
Private Const KEY_SET_VALUE = &H2
Private Const KEY_CREATE_SUB_KEY = &H4
'Return values from API:s
Private Const ERROR_SUCCESS = 0&
Private Const ERROR_ACCESS_DENIED = 5&
Private Const ERROR_KEY_DOES_NOT_EXIST = 2&
'Predeclared API:s....
'Creates a new key...
Private Declare Function RegCreateKeyEx Lib "advapi32.dll" Alias "RegCreateKeyExA"
(ByVal hKey As Long, ByVal lpSubKey As String, ByVal Reserved As Long, ByVal
lpClass As String, ByVal dwOptions As Long, ByVal samDesired As Long, lpSecurityAttributes
As SECURITY_ATTRIBUTES, phkResult As Long, lpdwDisposition As Long) As Long
'Opens the specific key for further action...
Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal
hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired
As Long, phkResult As Long) As Long
'Gets type and data to from a value name associted with the open key...
Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA"
(ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long,
ByRef lpType As Long, ByVal szData As String, ByRef lpcbData As Long) As
Long
'Sets a new value to an open key...
Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA"
(ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long,
ByVal dwType As Long, ByVal szData As String, ByVal cbData As Long) As Long
'Closes the specified key...
Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
'Deletes a value...
Private Declare Function RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueA"
(ByVal hKey As Long, ByVal lpValueName As String) As Long
'Deletes a key if no subkeys exist...
Private Declare Function RegDeleteKey Lib "advapi32.dll" Alias "RegDeleteKeyA"
(ByVal hKey As Long, ByVal lpSubKey As String) As Long
'
Private Function StripNullTerminator(KeyValue As String) As String
'KeyValue returned is a fixlength string (usually 255 spaces) which has been
populated
'with the value returned from the API. It is populated from left to right
and the returned
'value is terminated with chr(0). After that position only garbage exists.
So we search for
'the first chr(0) and cut off everything from that position.
Dim FirstNullPosition As Integer
FirstNullPosition = InStr(1, KeyValue, vbNullChar)
StripNullTerminator = Left(KeyValue, FirstNullPosition - 1)
End Function
Public Function GetRegistryValue(ByVal KeyName As String, ByVal ValueName
As String, Optional BufferSize As Long) As Variant
'Gets the value in ValueName from the registrybranch KeyName...
'Returns a string with the value. If an error occures Null is returned...
'If a large value is expected the buffer can be increased from its default
255 bytes...
Dim hKey As Long
Dim SubKey As String
Dim dataBuffer As String
Dim Result As Long
Dim RetVal As Long
Dim Value As String
'Determine main key (hKey) and sub key (SubKey) from KeyName...
If InStr(1, KeyName, "HKEY_CLASSES_ROOT\", vbTextCompare) = 1 Then
hKey = HKEY_CLASSES_ROOT
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CLASSES_ROOT\"))
ElseIf InStr(1, KeyName, "HKEY_CURRENT_USER\", vbTextCompare) = 1 Then
hKey = HKEY_CURRENT_USER
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CURRENT_USER\"))
ElseIf InStr(1, KeyName, "HKEY_LOCAL_MACHINE\", vbTextCompare) = 1 Then
hKey = HKEY_LOCAL_MACHINE
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_LOCAL_MACHINE\"))
ElseIf InStr(1, KeyName, "HKEY_USERS\", vbTextCompare) = 1 Then
hKey = HKEY_USERS
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_USERS\"))
Else
'Invalid KeyName...
GoTo GetRegistryValueError
End If
'Create string with spaces as a buffer to be filled by the API...
If BufferSize < 255 Then BufferSize = 255
dataBuffer = Space(BufferSize)
'Open the key for reading only...
RetVal = RegOpenKeyEx(hKey, SubKey, 0, KEY_QUERY_VALUE, Result)
If RetVal = ERROR_ACCESS_DENIED Then
MsgBox "ERROR: Unauthorized attempt to read in registry!", vbCritical,
"ACCESSVIOLATION"
GoTo GetRegistryValueError
ElseIf RetVal = ERROR_SUCCESS Then
'Try to fill up dataBuffer with the value in ValueName...
'It doesn't matter if it was stored as a string or as binary, it
is copied
'into the spacestring in dataBuffer as a binarystring ended with
chr(0) anyway...
RetVal = RegQueryValueEx(Result, ValueName, 0, 0, dataBuffer, BufferSize)
If RetVal = ERROR_SUCCESS Then
'ValueName was found and the value in it is now in the beginning
of dataBuffer...
'Se StripNullTerminator on how to extract it...
GetRegistryValue = StripNullTerminator(dataBuffer)
Else
'ValueName was not found...
GoTo GetRegistryValueError
End If
Else
GoTo GetRegistryValueError
End If
GetRegistryValueExit:
On Error Resume Next
RegCloseKey hKey
RegCloseKey Result
Exit Function
GetRegistryValueError:
GetRegistryValue = Null
GoTo GetRegistryValueExit
End Function
Public Function SetRegistryValue(ByVal KeyName As String, ByVal ValueName
As String, ByVal Value As String, Optional BinaryValue As Boolean) As Boolean
'Sets ValueName in branch KeyName to Value. If it does not exist it is created...
'Returns True if success, otherwise False...
'If BinaryValue = False, Value sets as a string, otherwise as binary...
'The binary value has to be supplied in a string though...
Dim hKey As Long
Dim SubKey As String
Dim Result As Long
Dim RetVal As Long
Dim RegType As Long
Dim SecAttrib As SECURITY_ATTRIBUTES
Dim Disp As Long
'ATTENTION: To remove the value a zerolength string can be passed for
'Win9X. But if that is done with NT4/W2000 the system goes bezerk. Putting
'a chr(0) in the empty string makes it work in all systems. Don't ask
me why,
'-When it works I don't spend any more time thinking of why...
If Len(Value) = 0 Then Value = Chr(0)
'Determine main key (hKey) and sub key (SubKey) from KeyName...
If InStr(1, KeyName, "HKEY_CLASSES_ROOT\", vbTextCompare) = 1 Then
hKey = HKEY_CLASSES_ROOT
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CLASSES_ROOT\"))
ElseIf InStr(1, KeyName, "HKEY_CURRENT_USER\", vbTextCompare) = 1 Then
hKey = HKEY_CURRENT_USER
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CURRENT_USER\"))
ElseIf InStr(1, KeyName, "HKEY_LOCAL_MACHINE\", vbTextCompare) = 1 Then
hKey = HKEY_LOCAL_MACHINE
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_LOCAL_MACHINE\"))
ElseIf InStr(1, KeyName, "HKEY_USERS\", vbTextCompare) = 1 Then
hKey = HKEY_USERS
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_USERS\"))
Else
'Invalid KeyName...
GoTo SetRegistryValueError
End If
'Open the key (creates it if it does not exist)...
'Note that authority asked for is a mix of flags (KEY_CREATE_SUB_KEY
Or KEY_SET_VALUE)
'which is no more than you need for creating and writing in the registry.
All samples I
'have seen used KEY_ALL_ACCESS but in NT4/W2000 you must be Admin to
get it. In Win9X it
'does not matter though...
RetVal = RegCreateKeyEx(hKey, SubKey, 0, "REG_DWORD", REG_OPTION_NON_VOLATILE,
(KEY_CREATE_SUB_KEY Or KEY_SET_VALUE), SecAttrib, Result, Disp)
Select Case RetVal
Case ERROR_ACCESS_DENIED
'Probably NT and somewhere you should not be messing around...
MsgBox "ERROR: Unauthorized attempt to write in registry!", vbCritical,
"ACCESSVIOLATION"
GoTo SetRegistryValueError
Case ERROR_SUCCESS
Case Else
'Unknown error...
MsgBox "ERROR: Unknown error when writing in registry!", vbCritical,
"REGISTRY ERROR"
GoTo SetRegistryValueError
End Select
If BinaryValue = True Then
RegType = REG_BINARY
Else
RegType = REG_SZ
End If
'Put in the data...
RetVal = RegSetValueEx(Result, ValueName, 0, RegType, Value, CLng(Len(Value)
+ 1))
Select Case RetVal
Case ERROR_ACCESS_DENIED
MsgBox "ERROR: Unauthorized attempt to write in registry!", vbCritical,
"ACCESSVIOLATION"
GoTo SetRegistryValueError
Case ERROR_SUCCESS
Case Else
'Unknown error...
MsgBox "ERROR: Unknown error when writing in registry!", vbCritical,
"REGISTRY ERROR"
GoTo SetRegistryValueError
End Select
SetRegistryValue = True
SetRegistryValueExit:
On Error Resume Next
'Close the keys...
RegCloseKey hKey
RegCloseKey Result
Exit Function
SetRegistryValueError:
SetRegistryValue = False
GoTo SetRegistryValueExit
End Function
Public Function DeleteRegistryValue(ByVal KeyName As String, ByVal ValueName
As String) As Boolean
'Deletes a complete ValueName and the value associated with it...
'Returns True if succeded, otherwise False...
Dim hKey As Long
Dim SubKey As String
Dim Result As Long
Dim RetVal As Long
'Determine main key (hKey) and sub key (SubKey) from KeyName...
If InStr(1, KeyName, "HKEY_CLASSES_ROOT\", vbTextCompare) = 1 Then
hKey = HKEY_CLASSES_ROOT
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CLASSES_ROOT\"))
ElseIf InStr(1, KeyName, "HKEY_CURRENT_USER\", vbTextCompare) = 1 Then
hKey = HKEY_CURRENT_USER
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CURRENT_USER\"))
ElseIf InStr(1, KeyName, "HKEY_LOCAL_MACHINE\", vbTextCompare) = 1 Then
hKey = HKEY_LOCAL_MACHINE
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_LOCAL_MACHINE\"))
ElseIf InStr(1, KeyName, "HKEY_USERS\", vbTextCompare) = 1 Then
hKey = HKEY_USERS
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_USERS\"))
Else
'Invalid KeyName...
GoTo DeleteRegistryValueError
End If
'Open the key with Set_Value access...
'Try this on NT/W2000!!! KEY_SET_VALUE should be sufficient according
to SDK documentation
'but who knows that is true...
RetVal = RegOpenKeyEx(hKey, SubKey, 0, KEY_SET_VALUE, Result)
Select Case RetVal
Case ERROR_ACCESS_DENIED
'Probably NT and somewhere you should not be messing around...
MsgBox "ERROR: Unauthorized attempt to write in registry!", vbCritical,
"ACCESSVIOLATION"
GoTo DeleteRegistryValueError
Case ERROR_KEY_DOES_NOT_EXIST
'Key does not exist...
GoTo DeleteRegistryValueError
Case ERROR_SUCCESS
Case Else
'Unknown error...
MsgBox "ERROR: Unknown error when writing in registry!", vbCritical,
"REGISTRY ERROR"
GoTo DeleteRegistryValueError
End Select
'Delete the key's value
RetVal = RegDeleteValue(Result, ValueName)
Select Case RetVal
Case ERROR_SUCCESS
'ValueName was found and deleted...
DeleteRegistryValue = True
Case ERROR_KEY_DOES_NOT_EXIST
'ValueName did not exist...
GoTo DeleteRegistryValueError
Case Else
'Unknown error...
MsgBox "ERROR: Unknown error when writing in registry!", vbCritical,
"REGISTRY ERROR"
GoTo DeleteRegistryValueError
End Select
DeleteRegistryValueExit:
On Error Resume Next
'Close the keys...
RegCloseKey hKey
RegCloseKey Result
Exit Function
DeleteRegistryValueError:
DeleteRegistryValue = False
GoTo DeleteRegistryValueExit
End Function
Public Function DeleteRegistryKey(ByVal KeyName As String) As Boolean
'Deletes a key and all values associated with it.
'Returns True if succeded, otherwise False...
'OS differences:
'Win 9X Deletes each and every subkey as well...
'Win NT/2000 Subkeys must not exist. These must first be handled
' individually from bottom and up...
Dim hKey As Long
Dim SubKey As String
Dim Result As Long
Dim RetVal As Long
'Determine main key (hKey) and sub key (SubKey) from KeyName...
If InStr(1, KeyName, "HKEY_CLASSES_ROOT\", vbTextCompare) = 1 Then
hKey = HKEY_CLASSES_ROOT
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CLASSES_ROOT\"))
ElseIf InStr(1, KeyName, "HKEY_CURRENT_USER\", vbTextCompare) = 1 Then
hKey = HKEY_CURRENT_USER
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CURRENT_USER\"))
ElseIf InStr(1, KeyName, "HKEY_LOCAL_MACHINE\", vbTextCompare) = 1 Then
hKey = HKEY_LOCAL_MACHINE
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_LOCAL_MACHINE\"))
ElseIf InStr(1, KeyName, "HKEY_USERS\", vbTextCompare) = 1 Then
hKey = HKEY_USERS
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_USERS\"))
Else
'Invalid KeyName...
GoTo DeleteRegistryKeyError
End If
'Open the key...
'Try this on NT/W2000!!! KEY_SET_VALUE may not be sufficient to delete
the key...
RetVal = RegOpenKeyEx(hKey, SubKey, 0, KEY_SET_VALUE, Result)
Select Case RetVal
Case ERROR_ACCESS_DENIED
'Probably NT and somewhere you should not be messing around...
MsgBox "ERROR: Unauthorized attempt to write in registry!", vbCritical,
"ACCESSVIOLATION"
GoTo DeleteRegistryKeyError
Case ERROR_KEY_DOES_NOT_EXIST
'Specified key did not exist...
GoTo DeleteRegistryKeyError
Case ERROR_SUCCESS
Case Else
'Unknown error...
MsgBox "ERROR: Unknown error when writing in registry!", vbCritical,
"REGISTRY ERROR"
GoTo DeleteRegistryKeyError
End Select
'Delete the key and all valuenames in it...
RetVal = RegDeleteKey(Result, "")
Select Case RetVal
Case ERROR_SUCCESS
'ValueName was found and deleted...
'With Win9X all subkeys are deleted as well...
DeleteRegistryKey = True
Case ERROR_ACCESS_DENIED
'Happens with NT/W2000 if there are any subkeys attached...
'If so each of them has to be deleted individually from bottom
and up.
'There is a newer API-function, SHDeleteKey in Shlwapi.dll, which
should
'delete each and every subkey as this one does in Win9X, but
I haven't tried
'it out yet...
GoTo DeleteRegistryKeyError
Case Else
'????...
GoTo DeleteRegistryKeyError
End Select
DeleteRegistryKeyExit:
On Error Resume Next
'Close the keys...
RegCloseKey hKey
RegCloseKey Result
Exit Function
DeleteRegistryKeyError:
DeleteRegistryKey = False
GoTo DeleteRegistryKeyExit
End Function
Public Function GetComputerName() As String
'Yeah, there is an API for this, but why not like this when it only
'takes a single row of code to do it?
GetComputerName = GetRegistryValue("HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\ComputerName\Compute rName",
"ComputerName")
End Function
-
Re: Writing in HKEY_LOCAL_MACHINE...Access is denied
"Bernie" <magnus.bernroth@rejlers.se> wrote:
>
>Hi,
>
>You should run the API RegCreateKeyEx with the flags REG_OPTION_NON_VOLATILE
>and (KEY_CREATE_SUB_KEY Or KEY_SET_VALUE) to let users without admin rights
>be able to create/write in the registry.
>
>Most samples on how RegCreateKeyEx works requests the highest possible rights
>wich works great on Win9X but returns Errcode 5 on NT-systems. By doing
so
>the user can write virtually everywhere in the registry, at least those
ordinary
>places like hkey\local machine\Software... or hkey\current user\software...
>
>Bu no means start juggeling with the user's rights...
>
>Bernie
Well, what the heck. Try this code. It's on the house!!
Put it in a module and call it's varoius functions. There is a lot of comments
in it, especially concerning the aspect of rights!! Most of it works on 9X,
NT, 2K and XP though some parts haven't been fully tested on all OS's yet
(see the notes inside). I guess the last function GetComputerName() explains
how to simply name the keys as strings...
Option Explicit
'Registry classes....
Private Const HKEY_CLASSES_ROOT = &H80000000
Private Const HKEY_CURRENT_USER = &H80000001
Private Const HKEY_LOCAL_MACHINE = &H80000002
Private Const HKEY_USERS = &H80000003
'Predefined value types (just a few of them used here)...
Private Const REG_NONE = (0) 'No value type
Private Const REG_SZ = (1) 'Unicode null terminated
string
Private Const REG_EXPAND_SZ = (2) 'Unicode null terminated
string with environment variable
Private Const REG_BINARY = (3) 'Binary format
Private Const REG_DWORD = (4) '32-bit number
Private Const REG_DWORD_LITTLE_ENDIAN = (4) '32-bit number (same
as REG_DWORD)
Private Const REG_DWORD_BIG_ENDIAN = (5) '32-bit number
Private Const REG_LINK = (6) 'Symbolic Link (unicode)
Private Const REG_MULTI_SZ = (7) 'Multiple Unicode strings
Private Const REG_RESOURCE_LIST = (8) 'Resource list in resource
map
Private Const REG_FULL_RESOURCE_DESCRIPTOR = (9) 'Resource list in hardware
description
Private Const REG_RESOURCE_REQUIREMENTS_LIST = (10) '??????
Private Const REG_OPTION_NON_VOLATILE = 0
'This is a tricky part when i comes to NT/W2000 to
'handle the security nicely. You should not need to
'be an Admin to make use of the registry when running
'an application. It is the programmers responsibility
'to make these routines work properly...
Private Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End Type
Private Const KEY_QUERY_VALUE = &H1
Private Const KEY_SET_VALUE = &H2
Private Const KEY_CREATE_SUB_KEY = &H4
'Return values from API:s
Private Const ERROR_SUCCESS = 0&
Private Const ERROR_ACCESS_DENIED = 5&
Private Const ERROR_KEY_DOES_NOT_EXIST = 2&
'Predeclared API:s....
'Creates a new key...
Private Declare Function RegCreateKeyEx Lib "advapi32.dll" Alias "RegCreateKeyExA"
(ByVal hKey As Long, ByVal lpSubKey As String, ByVal Reserved As Long, ByVal
lpClass As String, ByVal dwOptions As Long, ByVal samDesired As Long, lpSecurityAttributes
As SECURITY_ATTRIBUTES, phkResult As Long, lpdwDisposition As Long) As Long
'Opens the specific key for further action...
Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal
hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired
As Long, phkResult As Long) As Long
'Gets type and data to from a value name associted with the open key...
Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA"
(ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long,
ByRef lpType As Long, ByVal szData As String, ByRef lpcbData As Long) As
Long
'Sets a new value to an open key...
Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA"
(ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long,
ByVal dwType As Long, ByVal szData As String, ByVal cbData As Long) As Long
'Closes the specified key...
Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
'Deletes a value...
Private Declare Function RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueA"
(ByVal hKey As Long, ByVal lpValueName As String) As Long
'Deletes a key if no subkeys exist...
Private Declare Function RegDeleteKey Lib "advapi32.dll" Alias "RegDeleteKeyA"
(ByVal hKey As Long, ByVal lpSubKey As String) As Long
'
Private Function StripNullTerminator(KeyValue As String) As String
'KeyValue returned is a fixlength string (usually 255 spaces) which has been
populated
'with the value returned from the API. It is populated from left to right
and the returned
'value is terminated with chr(0). After that position only garbage exists.
So we search for
'the first chr(0) and cut off everything from that position.
Dim FirstNullPosition As Integer
FirstNullPosition = InStr(1, KeyValue, vbNullChar)
StripNullTerminator = Left(KeyValue, FirstNullPosition - 1)
End Function
Public Function GetRegistryValue(ByVal KeyName As String, ByVal ValueName
As String, Optional BufferSize As Long) As Variant
'Gets the value in ValueName from the registrybranch KeyName...
'Returns a string with the value. If an error occures Null is returned...
'If a large value is expected the buffer can be increased from its default
255 bytes...
Dim hKey As Long
Dim SubKey As String
Dim dataBuffer As String
Dim Result As Long
Dim RetVal As Long
Dim Value As String
'Determine main key (hKey) and sub key (SubKey) from KeyName...
If InStr(1, KeyName, "HKEY_CLASSES_ROOT\", vbTextCompare) = 1 Then
hKey = HKEY_CLASSES_ROOT
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CLASSES_ROOT\"))
ElseIf InStr(1, KeyName, "HKEY_CURRENT_USER\", vbTextCompare) = 1 Then
hKey = HKEY_CURRENT_USER
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CURRENT_USER\"))
ElseIf InStr(1, KeyName, "HKEY_LOCAL_MACHINE\", vbTextCompare) = 1 Then
hKey = HKEY_LOCAL_MACHINE
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_LOCAL_MACHINE\"))
ElseIf InStr(1, KeyName, "HKEY_USERS\", vbTextCompare) = 1 Then
hKey = HKEY_USERS
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_USERS\"))
Else
'Invalid KeyName...
GoTo GetRegistryValueError
End If
'Create string with spaces as a buffer to be filled by the API...
If BufferSize < 255 Then BufferSize = 255
dataBuffer = Space(BufferSize)
'Open the key for reading only...
RetVal = RegOpenKeyEx(hKey, SubKey, 0, KEY_QUERY_VALUE, Result)
If RetVal = ERROR_ACCESS_DENIED Then
MsgBox "ERROR: Unauthorized attempt to read in registry!", vbCritical,
"ACCESSVIOLATION"
GoTo GetRegistryValueError
ElseIf RetVal = ERROR_SUCCESS Then
'Try to fill up dataBuffer with the value in ValueName...
'It doesn't matter if it was stored as a string or as binary, it
is copied
'into the spacestring in dataBuffer as a binarystring ended with
chr(0) anyway...
RetVal = RegQueryValueEx(Result, ValueName, 0, 0, dataBuffer, BufferSize)
If RetVal = ERROR_SUCCESS Then
'ValueName was found and the value in it is now in the beginning
of dataBuffer...
'Se StripNullTerminator on how to extract it...
GetRegistryValue = StripNullTerminator(dataBuffer)
Else
'ValueName was not found...
GoTo GetRegistryValueError
End If
Else
GoTo GetRegistryValueError
End If
GetRegistryValueExit:
On Error Resume Next
RegCloseKey hKey
RegCloseKey Result
Exit Function
GetRegistryValueError:
GetRegistryValue = Null
GoTo GetRegistryValueExit
End Function
Public Function SetRegistryValue(ByVal KeyName As String, ByVal ValueName
As String, ByVal Value As String, Optional BinaryValue As Boolean) As Boolean
'Sets ValueName in branch KeyName to Value. If it does not exist it is created...
'Returns True if success, otherwise False...
'If BinaryValue = False, Value sets as a string, otherwise as binary...
'The binary value has to be supplied in a string though...
Dim hKey As Long
Dim SubKey As String
Dim Result As Long
Dim RetVal As Long
Dim RegType As Long
Dim SecAttrib As SECURITY_ATTRIBUTES
Dim Disp As Long
'ATTENTION: To remove the value a zerolength string can be passed for
'Win9X. But if that is done with NT4/W2000 the system goes bezerk. Putting
'a chr(0) in the empty string makes it work in all systems. Don't ask
me why,
'-When it works I don't spend any more time thinking of why...
If Len(Value) = 0 Then Value = Chr(0)
'Determine main key (hKey) and sub key (SubKey) from KeyName...
If InStr(1, KeyName, "HKEY_CLASSES_ROOT\", vbTextCompare) = 1 Then
hKey = HKEY_CLASSES_ROOT
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CLASSES_ROOT\"))
ElseIf InStr(1, KeyName, "HKEY_CURRENT_USER\", vbTextCompare) = 1 Then
hKey = HKEY_CURRENT_USER
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CURRENT_USER\"))
ElseIf InStr(1, KeyName, "HKEY_LOCAL_MACHINE\", vbTextCompare) = 1 Then
hKey = HKEY_LOCAL_MACHINE
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_LOCAL_MACHINE\"))
ElseIf InStr(1, KeyName, "HKEY_USERS\", vbTextCompare) = 1 Then
hKey = HKEY_USERS
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_USERS\"))
Else
'Invalid KeyName...
GoTo SetRegistryValueError
End If
'Open the key (creates it if it does not exist)...
'Note that authority asked for is a mix of flags (KEY_CREATE_SUB_KEY
Or KEY_SET_VALUE)
'which is no more than you need for creating and writing in the registry.
All samples I
'have seen used KEY_ALL_ACCESS but in NT4/W2000 you must be Admin to
get it. In Win9X it
'does not matter though...
RetVal = RegCreateKeyEx(hKey, SubKey, 0, "REG_DWORD", REG_OPTION_NON_VOLATILE,
(KEY_CREATE_SUB_KEY Or KEY_SET_VALUE), SecAttrib, Result, Disp)
Select Case RetVal
Case ERROR_ACCESS_DENIED
'Probably NT and somewhere you should not be messing around...
MsgBox "ERROR: Unauthorized attempt to write in registry!", vbCritical,
"ACCESSVIOLATION"
GoTo SetRegistryValueError
Case ERROR_SUCCESS
Case Else
'Unknown error...
MsgBox "ERROR: Unknown error when writing in registry!", vbCritical,
"REGISTRY ERROR"
GoTo SetRegistryValueError
End Select
If BinaryValue = True Then
RegType = REG_BINARY
Else
RegType = REG_SZ
End If
'Put in the data...
RetVal = RegSetValueEx(Result, ValueName, 0, RegType, Value, CLng(Len(Value)
+ 1))
Select Case RetVal
Case ERROR_ACCESS_DENIED
MsgBox "ERROR: Unauthorized attempt to write in registry!", vbCritical,
"ACCESSVIOLATION"
GoTo SetRegistryValueError
Case ERROR_SUCCESS
Case Else
'Unknown error...
MsgBox "ERROR: Unknown error when writing in registry!", vbCritical,
"REGISTRY ERROR"
GoTo SetRegistryValueError
End Select
SetRegistryValue = True
SetRegistryValueExit:
On Error Resume Next
'Close the keys...
RegCloseKey hKey
RegCloseKey Result
Exit Function
SetRegistryValueError:
SetRegistryValue = False
GoTo SetRegistryValueExit
End Function
Public Function DeleteRegistryValue(ByVal KeyName As String, ByVal ValueName
As String) As Boolean
'Deletes a complete ValueName and the value associated with it...
'Returns True if succeded, otherwise False...
Dim hKey As Long
Dim SubKey As String
Dim Result As Long
Dim RetVal As Long
'Determine main key (hKey) and sub key (SubKey) from KeyName...
If InStr(1, KeyName, "HKEY_CLASSES_ROOT\", vbTextCompare) = 1 Then
hKey = HKEY_CLASSES_ROOT
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CLASSES_ROOT\"))
ElseIf InStr(1, KeyName, "HKEY_CURRENT_USER\", vbTextCompare) = 1 Then
hKey = HKEY_CURRENT_USER
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CURRENT_USER\"))
ElseIf InStr(1, KeyName, "HKEY_LOCAL_MACHINE\", vbTextCompare) = 1 Then
hKey = HKEY_LOCAL_MACHINE
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_LOCAL_MACHINE\"))
ElseIf InStr(1, KeyName, "HKEY_USERS\", vbTextCompare) = 1 Then
hKey = HKEY_USERS
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_USERS\"))
Else
'Invalid KeyName...
GoTo DeleteRegistryValueError
End If
'Open the key with Set_Value access...
'Try this on NT/W2000!!! KEY_SET_VALUE should be sufficient according
to SDK documentation
'but who knows that is true...
RetVal = RegOpenKeyEx(hKey, SubKey, 0, KEY_SET_VALUE, Result)
Select Case RetVal
Case ERROR_ACCESS_DENIED
'Probably NT and somewhere you should not be messing around...
MsgBox "ERROR: Unauthorized attempt to write in registry!", vbCritical,
"ACCESSVIOLATION"
GoTo DeleteRegistryValueError
Case ERROR_KEY_DOES_NOT_EXIST
'Key does not exist...
GoTo DeleteRegistryValueError
Case ERROR_SUCCESS
Case Else
'Unknown error...
MsgBox "ERROR: Unknown error when writing in registry!", vbCritical,
"REGISTRY ERROR"
GoTo DeleteRegistryValueError
End Select
'Delete the key's value
RetVal = RegDeleteValue(Result, ValueName)
Select Case RetVal
Case ERROR_SUCCESS
'ValueName was found and deleted...
DeleteRegistryValue = True
Case ERROR_KEY_DOES_NOT_EXIST
'ValueName did not exist...
GoTo DeleteRegistryValueError
Case Else
'Unknown error...
MsgBox "ERROR: Unknown error when writing in registry!", vbCritical,
"REGISTRY ERROR"
GoTo DeleteRegistryValueError
End Select
DeleteRegistryValueExit:
On Error Resume Next
'Close the keys...
RegCloseKey hKey
RegCloseKey Result
Exit Function
DeleteRegistryValueError:
DeleteRegistryValue = False
GoTo DeleteRegistryValueExit
End Function
Public Function DeleteRegistryKey(ByVal KeyName As String) As Boolean
'Deletes a key and all values associated with it.
'Returns True if succeded, otherwise False...
'OS differences:
'Win 9X Deletes each and every subkey as well...
'Win NT/2000 Subkeys must not exist. These must first be handled
' individually from bottom and up...
Dim hKey As Long
Dim SubKey As String
Dim Result As Long
Dim RetVal As Long
'Determine main key (hKey) and sub key (SubKey) from KeyName...
If InStr(1, KeyName, "HKEY_CLASSES_ROOT\", vbTextCompare) = 1 Then
hKey = HKEY_CLASSES_ROOT
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CLASSES_ROOT\"))
ElseIf InStr(1, KeyName, "HKEY_CURRENT_USER\", vbTextCompare) = 1 Then
hKey = HKEY_CURRENT_USER
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CURRENT_USER\"))
ElseIf InStr(1, KeyName, "HKEY_LOCAL_MACHINE\", vbTextCompare) = 1 Then
hKey = HKEY_LOCAL_MACHINE
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_LOCAL_MACHINE\"))
ElseIf InStr(1, KeyName, "HKEY_USERS\", vbTextCompare) = 1 Then
hKey = HKEY_USERS
SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_USERS\"))
Else
'Invalid KeyName...
GoTo DeleteRegistryKeyError
End If
'Open the key...
'Try this on NT/W2000!!! KEY_SET_VALUE may not be sufficient to delete
the key...
RetVal = RegOpenKeyEx(hKey, SubKey, 0, KEY_SET_VALUE, Result)
Select Case RetVal
Case ERROR_ACCESS_DENIED
'Probably NT and somewhere you should not be messing around...
MsgBox "ERROR: Unauthorized attempt to write in registry!", vbCritical,
"ACCESSVIOLATION"
GoTo DeleteRegistryKeyError
Case ERROR_KEY_DOES_NOT_EXIST
'Specified key did not exist...
GoTo DeleteRegistryKeyError
Case ERROR_SUCCESS
Case Else
'Unknown error...
MsgBox "ERROR: Unknown error when writing in registry!", vbCritical,
"REGISTRY ERROR"
GoTo DeleteRegistryKeyError
End Select
'Delete the key and all valuenames in it...
RetVal = RegDeleteKey(Result, "")
Select Case RetVal
Case ERROR_SUCCESS
'ValueName was found and deleted...
'With Win9X all subkeys are deleted as well...
DeleteRegistryKey = True
Case ERROR_ACCESS_DENIED
'Happens with NT/W2000 if there are any subkeys attached...
'If so each of them has to be deleted individually from bottom
and up.
'There is a newer API-function, SHDeleteKey in Shlwapi.dll, which
should
'delete each and every subkey as this one does in Win9X, but
I haven't tried
'it out yet...
GoTo DeleteRegistryKeyError
Case Else
'????...
GoTo DeleteRegistryKeyError
End Select
DeleteRegistryKeyExit:
On Error Resume Next
'Close the keys...
RegCloseKey hKey
RegCloseKey Result
Exit Function
DeleteRegistryKeyError:
DeleteRegistryKey = False
GoTo DeleteRegistryKeyExit
End Function
Public Function GetComputerName() As String
'Yeah, there is an API for this, but why not like this when it only
'takes a single row of code to do it?
GetComputerName = GetRegistryValue("HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\ComputerName\Compute rName",
"ComputerName")
End Function
-
Re: Writing in HKEY_LOCAL_MACHINE...Access is denied
Bernie,
Thanks for the code, I have this problem with my app and have never got
around to fixing it. But I have say that your error handling is not correct:
MsgBox "ERROR: Unauthorized attempt to read in registry!", vbCritical,
"ACCESSVIOLATION"
What if the user of your code wants to check that a key is accessible and
take some action if it fails. They can't do this without the message box
appearing.
--
Michael Culley
www.vbdotcom.com
"Bernie" <magnus.bernroth@rejlers.se> wrote in message
news:3c04cbb3$1@147.208.176.211...
>
> "Bernie" <magnus.bernroth@rejlers.se> wrote:
> >
> >Hi,
> >
> >You should run the API RegCreateKeyEx with the flags
REG_OPTION_NON_VOLATILE
> >and (KEY_CREATE_SUB_KEY Or KEY_SET_VALUE) to let users without admin
rights
> >be able to create/write in the registry.
> >
> >Most samples on how RegCreateKeyEx works requests the highest possible
rights
> >wich works great on Win9X but returns Errcode 5 on NT-systems. By doing
> so
> >the user can write virtually everywhere in the registry, at least those
> ordinary
> >places like hkey\local machine\Software... or hkey\current
user\software...
> >
> >Bu no means start juggeling with the user's rights...
> >
> >Bernie
>
> Well, what the heck. Try this code. It's on the house!!
>
> Put it in a module and call it's varoius functions. There is a lot of
comments
> in it, especially concerning the aspect of rights!! Most of it works on
9X,
> NT, 2K and XP though some parts haven't been fully tested on all OS's yet
> (see the notes inside). I guess the last function GetComputerName()
explains
> how to simply name the keys as strings...
>
>
> Option Explicit
>
> 'Registry classes....
> Private Const HKEY_CLASSES_ROOT = &H80000000
> Private Const HKEY_CURRENT_USER = &H80000001
> Private Const HKEY_LOCAL_MACHINE = &H80000002
> Private Const HKEY_USERS = &H80000003
>
> 'Predefined value types (just a few of them used here)...
> Private Const REG_NONE = (0) 'No value type
> Private Const REG_SZ = (1) 'Unicode null
terminated
> string
> Private Const REG_EXPAND_SZ = (2) 'Unicode null
terminated
> string with environment variable
> Private Const REG_BINARY = (3) 'Binary format
> Private Const REG_DWORD = (4) '32-bit number
> Private Const REG_DWORD_LITTLE_ENDIAN = (4) '32-bit number (same
> as REG_DWORD)
> Private Const REG_DWORD_BIG_ENDIAN = (5) '32-bit number
> Private Const REG_LINK = (6) 'Symbolic Link
(unicode)
> Private Const REG_MULTI_SZ = (7) 'Multiple Unicode
strings
> Private Const REG_RESOURCE_LIST = (8) 'Resource list in
resource
> map
> Private Const REG_FULL_RESOURCE_DESCRIPTOR = (9) 'Resource list in
hardware
> description
> Private Const REG_RESOURCE_REQUIREMENTS_LIST = (10) '??????
>
> Private Const REG_OPTION_NON_VOLATILE = 0
>
> 'This is a tricky part when i comes to NT/W2000 to
> 'handle the security nicely. You should not need to
> 'be an Admin to make use of the registry when running
> 'an application. It is the programmers responsibility
> 'to make these routines work properly...
> Private Type SECURITY_ATTRIBUTES
> nLength As Long
> lpSecurityDescriptor As Long
> bInheritHandle As Long
> End Type
>
> Private Const KEY_QUERY_VALUE = &H1
> Private Const KEY_SET_VALUE = &H2
> Private Const KEY_CREATE_SUB_KEY = &H4
>
> 'Return values from API:s
> Private Const ERROR_SUCCESS = 0&
> Private Const ERROR_ACCESS_DENIED = 5&
> Private Const ERROR_KEY_DOES_NOT_EXIST = 2&
>
> 'Predeclared API:s....
> 'Creates a new key...
> Private Declare Function RegCreateKeyEx Lib "advapi32.dll" Alias
"RegCreateKeyExA"
> (ByVal hKey As Long, ByVal lpSubKey As String, ByVal Reserved As Long,
ByVal
> lpClass As String, ByVal dwOptions As Long, ByVal samDesired As Long,
lpSecurityAttributes
> As SECURITY_ATTRIBUTES, phkResult As Long, lpdwDisposition As Long) As
Long
>
> 'Opens the specific key for further action...
> Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA"
(ByVal
> hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal
samDesired
> As Long, phkResult As Long) As Long
>
> 'Gets type and data to from a value name associted with the open key...
> Declare Function RegQueryValueEx Lib "advapi32.dll" Alias
"RegQueryValueExA"
> (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As
Long,
> ByRef lpType As Long, ByVal szData As String, ByRef lpcbData As Long) As
> Long
>
> 'Sets a new value to an open key...
> Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA"
> (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long,
> ByVal dwType As Long, ByVal szData As String, ByVal cbData As Long) As
Long
>
> 'Closes the specified key...
> Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As
Long
>
> 'Deletes a value...
> Private Declare Function RegDeleteValue Lib "advapi32.dll" Alias
"RegDeleteValueA"
> (ByVal hKey As Long, ByVal lpValueName As String) As Long
>
> 'Deletes a key if no subkeys exist...
> Private Declare Function RegDeleteKey Lib "advapi32.dll" Alias
"RegDeleteKeyA"
> (ByVal hKey As Long, ByVal lpSubKey As String) As Long
> '
>
> Private Function StripNullTerminator(KeyValue As String) As String
>
> 'KeyValue returned is a fixlength string (usually 255 spaces) which has
been
> populated
> 'with the value returned from the API. It is populated from left to right
> and the returned
> 'value is terminated with chr(0). After that position only garbage exists.
> So we search for
> 'the first chr(0) and cut off everything from that position.
>
> Dim FirstNullPosition As Integer
>
> FirstNullPosition = InStr(1, KeyValue, vbNullChar)
> StripNullTerminator = Left(KeyValue, FirstNullPosition - 1)
>
> End Function
>
> Public Function GetRegistryValue(ByVal KeyName As String, ByVal ValueName
> As String, Optional BufferSize As Long) As Variant
>
> 'Gets the value in ValueName from the registrybranch KeyName...
> 'Returns a string with the value. If an error occures Null is returned...
> 'If a large value is expected the buffer can be increased from its default
> 255 bytes...
>
> Dim hKey As Long
> Dim SubKey As String
> Dim dataBuffer As String
> Dim Result As Long
> Dim RetVal As Long
> Dim Value As String
>
>
> 'Determine main key (hKey) and sub key (SubKey) from KeyName...
> If InStr(1, KeyName, "HKEY_CLASSES_ROOT\", vbTextCompare) = 1 Then
> hKey = HKEY_CLASSES_ROOT
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CLASSES_ROOT\"))
> ElseIf InStr(1, KeyName, "HKEY_CURRENT_USER\", vbTextCompare) = 1 Then
> hKey = HKEY_CURRENT_USER
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CURRENT_USER\"))
> ElseIf InStr(1, KeyName, "HKEY_LOCAL_MACHINE\", vbTextCompare) = 1
Then
> hKey = HKEY_LOCAL_MACHINE
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_LOCAL_MACHINE\"))
> ElseIf InStr(1, KeyName, "HKEY_USERS\", vbTextCompare) = 1 Then
> hKey = HKEY_USERS
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_USERS\"))
> Else
> 'Invalid KeyName...
> GoTo GetRegistryValueError
> End If
>
> 'Create string with spaces as a buffer to be filled by the API...
> If BufferSize < 255 Then BufferSize = 255
> dataBuffer = Space(BufferSize)
>
>
> 'Open the key for reading only...
> RetVal = RegOpenKeyEx(hKey, SubKey, 0, KEY_QUERY_VALUE, Result)
>
>
> If RetVal = ERROR_ACCESS_DENIED Then
> MsgBox "ERROR: Unauthorized attempt to read in registry!",
vbCritical,
> "ACCESSVIOLATION"
> GoTo GetRegistryValueError
> ElseIf RetVal = ERROR_SUCCESS Then
> 'Try to fill up dataBuffer with the value in ValueName...
> 'It doesn't matter if it was stored as a string or as binary, it
> is copied
> 'into the spacestring in dataBuffer as a binarystring ended with
> chr(0) anyway...
> RetVal = RegQueryValueEx(Result, ValueName, 0, 0, dataBuffer,
BufferSize)
> If RetVal = ERROR_SUCCESS Then
> 'ValueName was found and the value in it is now in the
beginning
> of dataBuffer...
> 'Se StripNullTerminator on how to extract it...
> GetRegistryValue = StripNullTerminator(dataBuffer)
> Else
> 'ValueName was not found...
> GoTo GetRegistryValueError
> End If
> Else
> GoTo GetRegistryValueError
> End If
>
>
>
> GetRegistryValueExit:
>
> On Error Resume Next
>
> RegCloseKey hKey
> RegCloseKey Result
>
> Exit Function
>
> GetRegistryValueError:
>
> GetRegistryValue = Null
> GoTo GetRegistryValueExit
>
> End Function
>
> Public Function SetRegistryValue(ByVal KeyName As String, ByVal ValueName
> As String, ByVal Value As String, Optional BinaryValue As Boolean) As
Boolean
>
> 'Sets ValueName in branch KeyName to Value. If it does not exist it is
created...
> 'Returns True if success, otherwise False...
>
> 'If BinaryValue = False, Value sets as a string, otherwise as binary...
> 'The binary value has to be supplied in a string though...
>
> Dim hKey As Long
> Dim SubKey As String
> Dim Result As Long
> Dim RetVal As Long
> Dim RegType As Long
> Dim SecAttrib As SECURITY_ATTRIBUTES
> Dim Disp As Long
>
> 'ATTENTION: To remove the value a zerolength string can be passed for
> 'Win9X. But if that is done with NT4/W2000 the system goes bezerk.
Putting
> 'a chr(0) in the empty string makes it work in all systems. Don't ask
> me why,
> '-When it works I don't spend any more time thinking of why...
> If Len(Value) = 0 Then Value = Chr(0)
>
>
> 'Determine main key (hKey) and sub key (SubKey) from KeyName...
> If InStr(1, KeyName, "HKEY_CLASSES_ROOT\", vbTextCompare) = 1 Then
> hKey = HKEY_CLASSES_ROOT
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CLASSES_ROOT\"))
> ElseIf InStr(1, KeyName, "HKEY_CURRENT_USER\", vbTextCompare) = 1 Then
> hKey = HKEY_CURRENT_USER
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CURRENT_USER\"))
> ElseIf InStr(1, KeyName, "HKEY_LOCAL_MACHINE\", vbTextCompare) = 1
Then
> hKey = HKEY_LOCAL_MACHINE
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_LOCAL_MACHINE\"))
> ElseIf InStr(1, KeyName, "HKEY_USERS\", vbTextCompare) = 1 Then
> hKey = HKEY_USERS
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_USERS\"))
> Else
> 'Invalid KeyName...
> GoTo SetRegistryValueError
> End If
>
>
> 'Open the key (creates it if it does not exist)...
> 'Note that authority asked for is a mix of flags (KEY_CREATE_SUB_KEY
> Or KEY_SET_VALUE)
> 'which is no more than you need for creating and writing in the
registry.
> All samples I
> 'have seen used KEY_ALL_ACCESS but in NT4/W2000 you must be Admin to
> get it. In Win9X it
> 'does not matter though...
> RetVal = RegCreateKeyEx(hKey, SubKey, 0, "REG_DWORD",
REG_OPTION_NON_VOLATILE,
> (KEY_CREATE_SUB_KEY Or KEY_SET_VALUE), SecAttrib, Result, Disp)
>
> Select Case RetVal
> Case ERROR_ACCESS_DENIED
> 'Probably NT and somewhere you should not be messing around...
> MsgBox "ERROR: Unauthorized attempt to write in registry!",
vbCritical,
> "ACCESSVIOLATION"
> GoTo SetRegistryValueError
> Case ERROR_SUCCESS
> Case Else
> 'Unknown error...
> MsgBox "ERROR: Unknown error when writing in registry!",
vbCritical,
> "REGISTRY ERROR"
> GoTo SetRegistryValueError
> End Select
>
> If BinaryValue = True Then
> RegType = REG_BINARY
> Else
> RegType = REG_SZ
> End If
>
> 'Put in the data...
> RetVal = RegSetValueEx(Result, ValueName, 0, RegType, Value,
CLng(Len(Value)
> + 1))
>
> Select Case RetVal
> Case ERROR_ACCESS_DENIED
> MsgBox "ERROR: Unauthorized attempt to write in registry!",
vbCritical,
> "ACCESSVIOLATION"
> GoTo SetRegistryValueError
> Case ERROR_SUCCESS
> Case Else
> 'Unknown error...
> MsgBox "ERROR: Unknown error when writing in registry!",
vbCritical,
> "REGISTRY ERROR"
> GoTo SetRegistryValueError
> End Select
>
> SetRegistryValue = True
>
> SetRegistryValueExit:
>
> On Error Resume Next
>
> 'Close the keys...
> RegCloseKey hKey
> RegCloseKey Result
>
> Exit Function
>
> SetRegistryValueError:
>
> SetRegistryValue = False
> GoTo SetRegistryValueExit
>
> End Function
>
> Public Function DeleteRegistryValue(ByVal KeyName As String, ByVal
ValueName
> As String) As Boolean
>
> 'Deletes a complete ValueName and the value associated with it...
> 'Returns True if succeded, otherwise False...
>
>
> Dim hKey As Long
> Dim SubKey As String
> Dim Result As Long
> Dim RetVal As Long
>
> 'Determine main key (hKey) and sub key (SubKey) from KeyName...
> If InStr(1, KeyName, "HKEY_CLASSES_ROOT\", vbTextCompare) = 1 Then
> hKey = HKEY_CLASSES_ROOT
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CLASSES_ROOT\"))
> ElseIf InStr(1, KeyName, "HKEY_CURRENT_USER\", vbTextCompare) = 1 Then
> hKey = HKEY_CURRENT_USER
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CURRENT_USER\"))
> ElseIf InStr(1, KeyName, "HKEY_LOCAL_MACHINE\", vbTextCompare) = 1
Then
> hKey = HKEY_LOCAL_MACHINE
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_LOCAL_MACHINE\"))
> ElseIf InStr(1, KeyName, "HKEY_USERS\", vbTextCompare) = 1 Then
> hKey = HKEY_USERS
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_USERS\"))
> Else
> 'Invalid KeyName...
> GoTo DeleteRegistryValueError
> End If
>
> 'Open the key with Set_Value access...
> 'Try this on NT/W2000!!! KEY_SET_VALUE should be sufficient according
> to SDK documentation
> 'but who knows that is true...
> RetVal = RegOpenKeyEx(hKey, SubKey, 0, KEY_SET_VALUE, Result)
>
> Select Case RetVal
> Case ERROR_ACCESS_DENIED
> 'Probably NT and somewhere you should not be messing around...
> MsgBox "ERROR: Unauthorized attempt to write in registry!",
vbCritical,
> "ACCESSVIOLATION"
> GoTo DeleteRegistryValueError
> Case ERROR_KEY_DOES_NOT_EXIST
> 'Key does not exist...
> GoTo DeleteRegistryValueError
> Case ERROR_SUCCESS
> Case Else
> 'Unknown error...
> MsgBox "ERROR: Unknown error when writing in registry!",
vbCritical,
> "REGISTRY ERROR"
> GoTo DeleteRegistryValueError
> End Select
>
> 'Delete the key's value
> RetVal = RegDeleteValue(Result, ValueName)
>
> Select Case RetVal
> Case ERROR_SUCCESS
> 'ValueName was found and deleted...
> DeleteRegistryValue = True
> Case ERROR_KEY_DOES_NOT_EXIST
> 'ValueName did not exist...
> GoTo DeleteRegistryValueError
> Case Else
> 'Unknown error...
> MsgBox "ERROR: Unknown error when writing in registry!",
vbCritical,
> "REGISTRY ERROR"
> GoTo DeleteRegistryValueError
> End Select
>
> DeleteRegistryValueExit:
>
> On Error Resume Next
>
> 'Close the keys...
> RegCloseKey hKey
> RegCloseKey Result
>
> Exit Function
>
>
> DeleteRegistryValueError:
>
> DeleteRegistryValue = False
> GoTo DeleteRegistryValueExit
>
> End Function
>
> Public Function DeleteRegistryKey(ByVal KeyName As String) As Boolean
>
> 'Deletes a key and all values associated with it.
> 'Returns True if succeded, otherwise False...
>
> 'OS differences:
> 'Win 9X Deletes each and every subkey as well...
> 'Win NT/2000 Subkeys must not exist. These must first be handled
> ' individually from bottom and up...
>
>
> Dim hKey As Long
> Dim SubKey As String
> Dim Result As Long
> Dim RetVal As Long
>
> 'Determine main key (hKey) and sub key (SubKey) from KeyName...
> If InStr(1, KeyName, "HKEY_CLASSES_ROOT\", vbTextCompare) = 1 Then
> hKey = HKEY_CLASSES_ROOT
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CLASSES_ROOT\"))
> ElseIf InStr(1, KeyName, "HKEY_CURRENT_USER\", vbTextCompare) = 1 Then
> hKey = HKEY_CURRENT_USER
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CURRENT_USER\"))
> ElseIf InStr(1, KeyName, "HKEY_LOCAL_MACHINE\", vbTextCompare) = 1
Then
> hKey = HKEY_LOCAL_MACHINE
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_LOCAL_MACHINE\"))
> ElseIf InStr(1, KeyName, "HKEY_USERS\", vbTextCompare) = 1 Then
> hKey = HKEY_USERS
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_USERS\"))
> Else
> 'Invalid KeyName...
> GoTo DeleteRegistryKeyError
> End If
>
> 'Open the key...
> 'Try this on NT/W2000!!! KEY_SET_VALUE may not be sufficient to delete
> the key...
> RetVal = RegOpenKeyEx(hKey, SubKey, 0, KEY_SET_VALUE, Result)
>
> Select Case RetVal
> Case ERROR_ACCESS_DENIED
> 'Probably NT and somewhere you should not be messing around...
> MsgBox "ERROR: Unauthorized attempt to write in registry!",
vbCritical,
> "ACCESSVIOLATION"
> GoTo DeleteRegistryKeyError
> Case ERROR_KEY_DOES_NOT_EXIST
> 'Specified key did not exist...
> GoTo DeleteRegistryKeyError
> Case ERROR_SUCCESS
> Case Else
> 'Unknown error...
> MsgBox "ERROR: Unknown error when writing in registry!",
vbCritical,
> "REGISTRY ERROR"
> GoTo DeleteRegistryKeyError
> End Select
>
> 'Delete the key and all valuenames in it...
> RetVal = RegDeleteKey(Result, "")
>
> Select Case RetVal
> Case ERROR_SUCCESS
> 'ValueName was found and deleted...
> 'With Win9X all subkeys are deleted as well...
> DeleteRegistryKey = True
> Case ERROR_ACCESS_DENIED
> 'Happens with NT/W2000 if there are any subkeys attached...
> 'If so each of them has to be deleted individually from bottom
> and up.
> 'There is a newer API-function, SHDeleteKey in Shlwapi.dll,
which
> should
> 'delete each and every subkey as this one does in Win9X, but
> I haven't tried
> 'it out yet...
> GoTo DeleteRegistryKeyError
> Case Else
> 220 23322 <3c05ad6f$1@147.208.176.211> article retrieved - head and body follows
From: "Monte Hansen" <monte@nospam.com>
Newsgroups: vb.api
References: <3c03848d$1@147.208.176.211>
Subject: Re: Read Event Logs
Date: Wed, 28 Nov 2001 20:54:28 -0800
Lines: 40
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2600.0000
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000
NNTP-Posting-Host: 24.216.2.116
Message-ID: <3c05ad6f$1@147.208.176.211>
X-Trace: 29 Nov 2001 03:37:19 GMT, 24.216.2.116
Path: 147.208.176.211
Xref: 147.208.176.211 vb.api:23322
ReadEventLog can be tricky, depending upon how it is used. It sounds like
L.J.'s article will get you going. If not, I have a generic EventLog
library, including an EventLogReader that works just like a Recordset. Just
never got around to publishing it.
Let me know if you need it, Alex.
++++++++++++++++++++
Monte Hansen
http://KillerVB.com
++++++++++++++++++++
"Alex Galvao" <slptam@hotmail.com> wrote in message
news:3c03848d$1@147.208.176.211...
>
> Hi all!
>
> I wrote an application, in VB6, that has to clear,write and read some
informations
> at the log event of the W2K.
>
> The clear and write functions worked properly, but i'm getting an error,87
> INVALID PARAMETER, with the CAPI function, altough i suppose
> that everything is all right. Recently i read that there is a bug when
using
> the flag EVENTLOG_SEEK_READ and this is not my case.
>
>
> I hope someone can help me because the Microsoft documentation is not so
> rich in this topic.
>
> Thanks,
> Alex Galvao
> slptam@hotmail.com
>
>
>
>
-
Re: Writing in HKEY_LOCAL_MACHINE...Access is denied
Bernie,
Thanks for the code, I have this problem with my app and have never got
around to fixing it. But I have say that your error handling is not correct:
MsgBox "ERROR: Unauthorized attempt to read in registry!", vbCritical,
"ACCESSVIOLATION"
What if the user of your code wants to check that a key is accessible and
take some action if it fails. They can't do this without the message box
appearing.
--
Michael Culley
www.vbdotcom.com
"Bernie" <magnus.bernroth@rejlers.se> wrote in message
news:3c04cbb3$1@147.208.176.211...
>
> "Bernie" <magnus.bernroth@rejlers.se> wrote:
> >
> >Hi,
> >
> >You should run the API RegCreateKeyEx with the flags
REG_OPTION_NON_VOLATILE
> >and (KEY_CREATE_SUB_KEY Or KEY_SET_VALUE) to let users without admin
rights
> >be able to create/write in the registry.
> >
> >Most samples on how RegCreateKeyEx works requests the highest possible
rights
> >wich works great on Win9X but returns Errcode 5 on NT-systems. By doing
> so
> >the user can write virtually everywhere in the registry, at least those
> ordinary
> >places like hkey\local machine\Software... or hkey\current
user\software...
> >
> >Bu no means start juggeling with the user's rights...
> >
> >Bernie
>
> Well, what the heck. Try this code. It's on the house!!
>
> Put it in a module and call it's varoius functions. There is a lot of
comments
> in it, especially concerning the aspect of rights!! Most of it works on
9X,
> NT, 2K and XP though some parts haven't been fully tested on all OS's yet
> (see the notes inside). I guess the last function GetComputerName()
explains
> how to simply name the keys as strings...
>
>
> Option Explicit
>
> 'Registry classes....
> Private Const HKEY_CLASSES_ROOT = &H80000000
> Private Const HKEY_CURRENT_USER = &H80000001
> Private Const HKEY_LOCAL_MACHINE = &H80000002
> Private Const HKEY_USERS = &H80000003
>
> 'Predefined value types (just a few of them used here)...
> Private Const REG_NONE = (0) 'No value type
> Private Const REG_SZ = (1) 'Unicode null
terminated
> string
> Private Const REG_EXPAND_SZ = (2) 'Unicode null
terminated
> string with environment variable
> Private Const REG_BINARY = (3) 'Binary format
> Private Const REG_DWORD = (4) '32-bit number
> Private Const REG_DWORD_LITTLE_ENDIAN = (4) '32-bit number (same
> as REG_DWORD)
> Private Const REG_DWORD_BIG_ENDIAN = (5) '32-bit number
> Private Const REG_LINK = (6) 'Symbolic Link
(unicode)
> Private Const REG_MULTI_SZ = (7) 'Multiple Unicode
strings
> Private Const REG_RESOURCE_LIST = (8) 'Resource list in
resource
> map
> Private Const REG_FULL_RESOURCE_DESCRIPTOR = (9) 'Resource list in
hardware
> description
> Private Const REG_RESOURCE_REQUIREMENTS_LIST = (10) '??????
>
> Private Const REG_OPTION_NON_VOLATILE = 0
>
> 'This is a tricky part when i comes to NT/W2000 to
> 'handle the security nicely. You should not need to
> 'be an Admin to make use of the registry when running
> 'an application. It is the programmers responsibility
> 'to make these routines work properly...
> Private Type SECURITY_ATTRIBUTES
> nLength As Long
> lpSecurityDescriptor As Long
> bInheritHandle As Long
> End Type
>
> Private Const KEY_QUERY_VALUE = &H1
> Private Const KEY_SET_VALUE = &H2
> Private Const KEY_CREATE_SUB_KEY = &H4
>
> 'Return values from API:s
> Private Const ERROR_SUCCESS = 0&
> Private Const ERROR_ACCESS_DENIED = 5&
> Private Const ERROR_KEY_DOES_NOT_EXIST = 2&
>
> 'Predeclared API:s....
> 'Creates a new key...
> Private Declare Function RegCreateKeyEx Lib "advapi32.dll" Alias
"RegCreateKeyExA"
> (ByVal hKey As Long, ByVal lpSubKey As String, ByVal Reserved As Long,
ByVal
> lpClass As String, ByVal dwOptions As Long, ByVal samDesired As Long,
lpSecurityAttributes
> As SECURITY_ATTRIBUTES, phkResult As Long, lpdwDisposition As Long) As
Long
>
> 'Opens the specific key for further action...
> Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA"
(ByVal
> hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal
samDesired
> As Long, phkResult As Long) As Long
>
> 'Gets type and data to from a value name associted with the open key...
> Declare Function RegQueryValueEx Lib "advapi32.dll" Alias
"RegQueryValueExA"
> (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As
Long,
> ByRef lpType As Long, ByVal szData As String, ByRef lpcbData As Long) As
> Long
>
> 'Sets a new value to an open key...
> Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA"
> (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long,
> ByVal dwType As Long, ByVal szData As String, ByVal cbData As Long) As
Long
>
> 'Closes the specified key...
> Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As
Long
>
> 'Deletes a value...
> Private Declare Function RegDeleteValue Lib "advapi32.dll" Alias
"RegDeleteValueA"
> (ByVal hKey As Long, ByVal lpValueName As String) As Long
>
> 'Deletes a key if no subkeys exist...
> Private Declare Function RegDeleteKey Lib "advapi32.dll" Alias
"RegDeleteKeyA"
> (ByVal hKey As Long, ByVal lpSubKey As String) As Long
> '
>
> Private Function StripNullTerminator(KeyValue As String) As String
>
> 'KeyValue returned is a fixlength string (usually 255 spaces) which has
been
> populated
> 'with the value returned from the API. It is populated from left to right
> and the returned
> 'value is terminated with chr(0). After that position only garbage exists.
> So we search for
> 'the first chr(0) and cut off everything from that position.
>
> Dim FirstNullPosition As Integer
>
> FirstNullPosition = InStr(1, KeyValue, vbNullChar)
> StripNullTerminator = Left(KeyValue, FirstNullPosition - 1)
>
> End Function
>
> Public Function GetRegistryValue(ByVal KeyName As String, ByVal ValueName
> As String, Optional BufferSize As Long) As Variant
>
> 'Gets the value in ValueName from the registrybranch KeyName...
> 'Returns a string with the value. If an error occures Null is returned...
> 'If a large value is expected the buffer can be increased from its default
> 255 bytes...
>
> Dim hKey As Long
> Dim SubKey As String
> Dim dataBuffer As String
> Dim Result As Long
> Dim RetVal As Long
> Dim Value As String
>
>
> 'Determine main key (hKey) and sub key (SubKey) from KeyName...
> If InStr(1, KeyName, "HKEY_CLASSES_ROOT\", vbTextCompare) = 1 Then
> hKey = HKEY_CLASSES_ROOT
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CLASSES_ROOT\"))
> ElseIf InStr(1, KeyName, "HKEY_CURRENT_USER\", vbTextCompare) = 1 Then
> hKey = HKEY_CURRENT_USER
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CURRENT_USER\"))
> ElseIf InStr(1, KeyName, "HKEY_LOCAL_MACHINE\", vbTextCompare) = 1
Then
> hKey = HKEY_LOCAL_MACHINE
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_LOCAL_MACHINE\"))
> ElseIf InStr(1, KeyName, "HKEY_USERS\", vbTextCompare) = 1 Then
> hKey = HKEY_USERS
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_USERS\"))
> Else
> 'Invalid KeyName...
> GoTo GetRegistryValueError
> End If
>
> 'Create string with spaces as a buffer to be filled by the API...
> If BufferSize < 255 Then BufferSize = 255
> dataBuffer = Space(BufferSize)
>
>
> 'Open the key for reading only...
> RetVal = RegOpenKeyEx(hKey, SubKey, 0, KEY_QUERY_VALUE, Result)
>
>
> If RetVal = ERROR_ACCESS_DENIED Then
> MsgBox "ERROR: Unauthorized attempt to read in registry!",
vbCritical,
> "ACCESSVIOLATION"
> GoTo GetRegistryValueError
> ElseIf RetVal = ERROR_SUCCESS Then
> 'Try to fill up dataBuffer with the value in ValueName...
> 'It doesn't matter if it was stored as a string or as binary, it
> is copied
> 'into the spacestring in dataBuffer as a binarystring ended with
> chr(0) anyway...
> RetVal = RegQueryValueEx(Result, ValueName, 0, 0, dataBuffer,
BufferSize)
> If RetVal = ERROR_SUCCESS Then
> 'ValueName was found and the value in it is now in the
beginning
> of dataBuffer...
> 'Se StripNullTerminator on how to extract it...
> GetRegistryValue = StripNullTerminator(dataBuffer)
> Else
> 'ValueName was not found...
> GoTo GetRegistryValueError
> End If
> Else
> GoTo GetRegistryValueError
> End If
>
>
>
> GetRegistryValueExit:
>
> On Error Resume Next
>
> RegCloseKey hKey
> RegCloseKey Result
>
> Exit Function
>
> GetRegistryValueError:
>
> GetRegistryValue = Null
> GoTo GetRegistryValueExit
>
> End Function
>
> Public Function SetRegistryValue(ByVal KeyName As String, ByVal ValueName
> As String, ByVal Value As String, Optional BinaryValue As Boolean) As
Boolean
>
> 'Sets ValueName in branch KeyName to Value. If it does not exist it is
created...
> 'Returns True if success, otherwise False...
>
> 'If BinaryValue = False, Value sets as a string, otherwise as binary...
> 'The binary value has to be supplied in a string though...
>
> Dim hKey As Long
> Dim SubKey As String
> Dim Result As Long
> Dim RetVal As Long
> Dim RegType As Long
> Dim SecAttrib As SECURITY_ATTRIBUTES
> Dim Disp As Long
>
> 'ATTENTION: To remove the value a zerolength string can be passed for
> 'Win9X. But if that is done with NT4/W2000 the system goes bezerk.
Putting
> 'a chr(0) in the empty string makes it work in all systems. Don't ask
> me why,
> '-When it works I don't spend any more time thinking of why...
> If Len(Value) = 0 Then Value = Chr(0)
>
>
> 'Determine main key (hKey) and sub key (SubKey) from KeyName...
> If InStr(1, KeyName, "HKEY_CLASSES_ROOT\", vbTextCompare) = 1 Then
> hKey = HKEY_CLASSES_ROOT
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CLASSES_ROOT\"))
> ElseIf InStr(1, KeyName, "HKEY_CURRENT_USER\", vbTextCompare) = 1 Then
> hKey = HKEY_CURRENT_USER
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CURRENT_USER\"))
> ElseIf InStr(1, KeyName, "HKEY_LOCAL_MACHINE\", vbTextCompare) = 1
Then
> hKey = HKEY_LOCAL_MACHINE
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_LOCAL_MACHINE\"))
> ElseIf InStr(1, KeyName, "HKEY_USERS\", vbTextCompare) = 1 Then
> hKey = HKEY_USERS
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_USERS\"))
> Else
> 'Invalid KeyName...
> GoTo SetRegistryValueError
> End If
>
>
> 'Open the key (creates it if it does not exist)...
> 'Note that authority asked for is a mix of flags (KEY_CREATE_SUB_KEY
> Or KEY_SET_VALUE)
> 'which is no more than you need for creating and writing in the
registry.
> All samples I
> 'have seen used KEY_ALL_ACCESS but in NT4/W2000 you must be Admin to
> get it. In Win9X it
> 'does not matter though...
> RetVal = RegCreateKeyEx(hKey, SubKey, 0, "REG_DWORD",
REG_OPTION_NON_VOLATILE,
> (KEY_CREATE_SUB_KEY Or KEY_SET_VALUE), SecAttrib, Result, Disp)
>
> Select Case RetVal
> Case ERROR_ACCESS_DENIED
> 'Probably NT and somewhere you should not be messing around...
> MsgBox "ERROR: Unauthorized attempt to write in registry!",
vbCritical,
> "ACCESSVIOLATION"
> GoTo SetRegistryValueError
> Case ERROR_SUCCESS
> Case Else
> 'Unknown error...
> MsgBox "ERROR: Unknown error when writing in registry!",
vbCritical,
> "REGISTRY ERROR"
> GoTo SetRegistryValueError
> End Select
>
> If BinaryValue = True Then
> RegType = REG_BINARY
> Else
> RegType = REG_SZ
> End If
>
> 'Put in the data...
> RetVal = RegSetValueEx(Result, ValueName, 0, RegType, Value,
CLng(Len(Value)
> + 1))
>
> Select Case RetVal
> Case ERROR_ACCESS_DENIED
> MsgBox "ERROR: Unauthorized attempt to write in registry!",
vbCritical,
> "ACCESSVIOLATION"
> GoTo SetRegistryValueError
> Case ERROR_SUCCESS
> Case Else
> 'Unknown error...
> MsgBox "ERROR: Unknown error when writing in registry!",
vbCritical,
> "REGISTRY ERROR"
> GoTo SetRegistryValueError
> End Select
>
> SetRegistryValue = True
>
> SetRegistryValueExit:
>
> On Error Resume Next
>
> 'Close the keys...
> RegCloseKey hKey
> RegCloseKey Result
>
> Exit Function
>
> SetRegistryValueError:
>
> SetRegistryValue = False
> GoTo SetRegistryValueExit
>
> End Function
>
> Public Function DeleteRegistryValue(ByVal KeyName As String, ByVal
ValueName
> As String) As Boolean
>
> 'Deletes a complete ValueName and the value associated with it...
> 'Returns True if succeded, otherwise False...
>
>
> Dim hKey As Long
> Dim SubKey As String
> Dim Result As Long
> Dim RetVal As Long
>
> 'Determine main key (hKey) and sub key (SubKey) from KeyName...
> If InStr(1, KeyName, "HKEY_CLASSES_ROOT\", vbTextCompare) = 1 Then
> hKey = HKEY_CLASSES_ROOT
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CLASSES_ROOT\"))
> ElseIf InStr(1, KeyName, "HKEY_CURRENT_USER\", vbTextCompare) = 1 Then
> hKey = HKEY_CURRENT_USER
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CURRENT_USER\"))
> ElseIf InStr(1, KeyName, "HKEY_LOCAL_MACHINE\", vbTextCompare) = 1
Then
> hKey = HKEY_LOCAL_MACHINE
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_LOCAL_MACHINE\"))
> ElseIf InStr(1, KeyName, "HKEY_USERS\", vbTextCompare) = 1 Then
> hKey = HKEY_USERS
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_USERS\"))
> Else
> 'Invalid KeyName...
> GoTo DeleteRegistryValueError
> End If
>
> 'Open the key with Set_Value access...
> 'Try this on NT/W2000!!! KEY_SET_VALUE should be sufficient according
> to SDK documentation
> 'but who knows that is true...
> RetVal = RegOpenKeyEx(hKey, SubKey, 0, KEY_SET_VALUE, Result)
>
> Select Case RetVal
> Case ERROR_ACCESS_DENIED
> 'Probably NT and somewhere you should not be messing around...
> MsgBox "ERROR: Unauthorized attempt to write in registry!",
vbCritical,
> "ACCESSVIOLATION"
> GoTo DeleteRegistryValueError
> Case ERROR_KEY_DOES_NOT_EXIST
> 'Key does not exist...
> GoTo DeleteRegistryValueError
> Case ERROR_SUCCESS
> Case Else
> 'Unknown error...
> MsgBox "ERROR: Unknown error when writing in registry!",
vbCritical,
> "REGISTRY ERROR"
> GoTo DeleteRegistryValueError
> End Select
>
> 'Delete the key's value
> RetVal = RegDeleteValue(Result, ValueName)
>
> Select Case RetVal
> Case ERROR_SUCCESS
> 'ValueName was found and deleted...
> DeleteRegistryValue = True
> Case ERROR_KEY_DOES_NOT_EXIST
> 'ValueName did not exist...
> GoTo DeleteRegistryValueError
> Case Else
> 'Unknown error...
> MsgBox "ERROR: Unknown error when writing in registry!",
vbCritical,
> "REGISTRY ERROR"
> GoTo DeleteRegistryValueError
> End Select
>
> DeleteRegistryValueExit:
>
> On Error Resume Next
>
> 'Close the keys...
> RegCloseKey hKey
> RegCloseKey Result
>
> Exit Function
>
>
> DeleteRegistryValueError:
>
> DeleteRegistryValue = False
> GoTo DeleteRegistryValueExit
>
> End Function
>
> Public Function DeleteRegistryKey(ByVal KeyName As String) As Boolean
>
> 'Deletes a key and all values associated with it.
> 'Returns True if succeded, otherwise False...
>
> 'OS differences:
> 'Win 9X Deletes each and every subkey as well...
> 'Win NT/2000 Subkeys must not exist. These must first be handled
> ' individually from bottom and up...
>
>
> Dim hKey As Long
> Dim SubKey As String
> Dim Result As Long
> Dim RetVal As Long
>
> 'Determine main key (hKey) and sub key (SubKey) from KeyName...
> If InStr(1, KeyName, "HKEY_CLASSES_ROOT\", vbTextCompare) = 1 Then
> hKey = HKEY_CLASSES_ROOT
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CLASSES_ROOT\"))
> ElseIf InStr(1, KeyName, "HKEY_CURRENT_USER\", vbTextCompare) = 1 Then
> hKey = HKEY_CURRENT_USER
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_CURRENT_USER\"))
> ElseIf InStr(1, KeyName, "HKEY_LOCAL_MACHINE\", vbTextCompare) = 1
Then
> hKey = HKEY_LOCAL_MACHINE
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_LOCAL_MACHINE\"))
> ElseIf InStr(1, KeyName, "HKEY_USERS\", vbTextCompare) = 1 Then
> hKey = HKEY_USERS
> SubKey = Right(KeyName, Len(KeyName) - Len("HKEY_USERS\"))
> Else
> 'Invalid KeyName...
> GoTo DeleteRegistryKeyError
> End If
>
> 'Open the key...
> 'Try this on NT/W2000!!! KEY_SET_VALUE may not be sufficient to delete
> the key...
> RetVal = RegOpenKeyEx(hKey, SubKey, 0, KEY_SET_VALUE, Result)
>
> Select Case RetVal
> Case ERROR_ACCESS_DENIED
> 'Probably NT and somewhere you should not be messing around...
> MsgBox "ERROR: Unauthorized attempt to write in registry!",
vbCritical,
> "ACCESSVIOLATION"
> GoTo DeleteRegistryKeyError
> Case ERROR_KEY_DOES_NOT_EXIST
> 'Specified key did not exist...
> GoTo DeleteRegistryKeyError
> Case ERROR_SUCCESS
> Case Else
> 'Unknown error...
> MsgBox "ERROR: Unknown error when writing in registry!",
vbCritical,
> "REGISTRY ERROR"
> GoTo DeleteRegistryKeyError
> End Select
>
> 'Delete the key and all valuenames in it...
> RetVal = RegDeleteKey(Result, "")
>
> Select Case RetVal
> Case ERROR_SUCCESS
> 'ValueName was found and deleted...
> 'With Win9X all subkeys are deleted as well...
> DeleteRegistryKey = True
> Case ERROR_ACCESS_DENIED
> 'Happens with NT/W2000 if there are any subkeys attached...
> 'If so each of them has to be deleted individually from bottom
> and up.
> 'There is a newer API-function, SHDeleteKey in Shlwapi.dll,
which
> should
> 'delete each and every subkey as this one does in Win9X, but
> I haven't tried
> 'it out yet...
> GoTo DeleteRegistryKeyError
> Case Else
> 220 23322 <3c05ad6f$1@147.208.176.211> article retrieved - head and body follows
From: "Monte Hansen" <monte@nospam.com>
Newsgroups: vb.api
References: <3c03848d$1@147.208.176.211>
Subject: Re: Read Event Logs
Date: Wed, 28 Nov 2001 20:54:28 -0800
Lines: 40
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2600.0000
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000
NNTP-Posting-Host: 24.216.2.116
Message-ID: <3c05ad6f$1@147.208.176.211>
X-Trace: 29 Nov 2001 03:37:19 GMT, 24.216.2.116
Path: 147.208.176.211
Xref: 147.208.176.211 vb.api:23322
ReadEventLog can be tricky, depending upon how it is used. It sounds like
L.J.'s article will get you going. If not, I have a generic EventLog
library, including an EventLogReader that works just like a Recordset. Just
never got around to publishing it.
Let me know if you need it, Alex.
++++++++++++++++++++
Monte Hansen
http://KillerVB.com
++++++++++++++++++++
"Alex Galvao" <slptam@hotmail.com> wrote in message
news:3c03848d$1@147.208.176.211...
>
> Hi all!
>
> I wrote an application, in VB6, that has to clear,write and read some
informations
> at the log event of the W2K.
>
> The clear and write functions worked properly, but i'm getting an error,87
> INVALID PARAMETER, with the CAPI function, altough i suppose
> that everything is all right. Recently i read that there is a bug when
using
> the flag EVENTLOG_SEEK_READ and this is not my case.
>
>
> I hope someone can help me because the Microsoft documentation is not so
> rich in this topic.
>
> Thanks,
> Alex Galvao
> slptam@hotmail.com
>
>
>
>
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Development Centers
-- Android Development Center
-- Cloud Development Project Center
-- HTML5 Development Center
-- Windows Mobile Development Center
|