Using VB6 with Win32API Calls to Add and Change Registry Keys/Entries - Cannot Change the Value for an Entry I just Created???

I'm using the standard fare of Win32API calls to add registry keys on XP machines.

I'm adding a number of keys to the HKEY_LOCAL_MACHINE\Software\CustomCompany\CustomSoftware....
location. Here's the problem I'm having:

I add a key. I add an entry to the key. No problem.

If I now go back and try to SET the value of this key, I get a long return of 5 (access_denied).

So, I can create the thing no problem - but once it is created, I can't seem to change the value?

This seems like it has something to do with the access rights on the key. When I attempt to change the value of the entries, I'm using this call (just an alias to RegSetValueEx):

longstatus = RegSetValueExString(hTargetKey, targetEntry, 0, REG_SZ, newValue, Len(newValue))

Everytime I try to change one of these values that I just created, I get an access denied return.

Here's the call I use to originally create the keys:

longstatus = RegCreateKeyEx("HKEY_LOCAL_MACHINE", "SOFTWARE\Custom...", 0, vbNullString, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, secAttributes.lpSecurityDescriptor, hTargetKey, lFuncBehavior)

I'm assuming the issue is the security descriptor. All I'm doing for this descriptor is the following:

Dim secAttributes as SECURITY_ATTRIBUTES
secAttributes.nLength = Len(secAttributes)
secAttributes.bInheritHandle = CLng(True)

This will take someone far more versed in how the Windows security access stuff works than I. What do I need to do for this to work correctly? I want ANY user to be able to change the values of these keys (they will be changed by the program running, which will be utilized by any user on the computer).

EDIT: Wanted to add also that while I am NOT using an administrator account to do this, the user account running the software DOES seem to have the ability to change these values! After using the software to CREATE the keys and entries, I am fully capable of going into REGEDIT and modifying the entry values. The issue is that I can't seem to do the same using the API calls.
Also do NOT want to use a scripted system to do this, as I am unsure of the status/allowance of the user abilities in places this may be installed. Surely there is a simple thing I am overlooking when it comes to using the correct security information when either CREATING or attempting to EDIT the entries.
ImusadeAsked:
Who is Participating?
 
nffvrxqgrcfqvvcConnect With a Mentor Commented:
Line 54: Your opening the key with only KEY_EXECUTE... This is the same as KEY_READ but when you then go to make the call at line: 61 it fails because you only have KEY_READ access so attempting to (WRITE) fails.
You need to add KEY_WRITE (0x20006) bit
KEY_EXECUTE Or KEY_WRITE...
KEY_READ Or KEY_WRITE

Problem should be fixed and working :)

0
 
corneliu_newsCommented:
on Registry Editor, right click /permissions and add permissions for user you are using
0
 
nffvrxqgrcfqvvcCommented:
Actually the Access Denied error seems to indicate otherwise! If it's a standard account you don't have access to HKEY_LOCAL_MACHINE\Software.. However a Standard User can access HKEY_CURRENT_USER\Software. Also a Standard User should be able to (READ) keys and values by default. But they can't Create,Modify...
You also don't need the security descriptor you can pass (null pointert) or 0 for this parameter.
Another problem could be KEY_ALL_ACCESS... This means you want every right but would only be reasonable if you running as administrator... You should use specific access rights for the action you want.. For example because a standard user can read most parts of the registry using KEY_ALL_ACCESS might fail because the user doesn't have the ability to create,modify.. but if you passed only KEY_READ instead it would succeed.
You can do a simple test by using HKEY_CURRENT_USER .... see if you get the access denied.
Also I should ask because I don't see in your example but are you closing the key handle?
RegCloseKey(hTargetKey)
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
ImusadeAuthor Commented:
I'll give this a shot - the thing that is baffling is that I have NO trouble creating the keys/entries through the API calls.

I can then go into the registry editor and change these values (in HKEY_LOCAL_MACHINE, using a non-admin account, same account used to create the key/entry via software) - again no problem.

But using the RegSetValueEx call, I can NOT make any changes. Confusing to say the least. Should it not follow that if I have the user access to make the change in the registry editor, I should also have user access to change the value through the API system?
0
 
nffvrxqgrcfqvvcCommented:
What type of user are they? Did you or the system administrator grant these users special rights to to access the registry in such as way? If it's a standard account with the least privileges by default the regedit should also fail for creating keys or values in HKEY_LOCAL_MACHINE. Also the only possible way I can see the regedit program able to access in such a way is if it was executed using RunAs or is running in the context of the Administrator OR if the system administrator specifically granted these permissions to the user account. Otherwise the API and RegEdit should give the same behavior.
<< the thing that is baffling is that I have NO trouble creating the keys/entries through the API calls >>
So your saying now you don't have problem with creating keys with the API?
If the users do have permissions then it's code issue... If regedit isn't running in the context of administrator then it's a code issue and would need to see how you access the registry using your current code.
0
 
ImusadeAuthor Commented:
Engl1044 - I have ALWAYS been able to create keys and entrys with the API (reread the original post).

The problem is once I create them, I cannot go back and modify them with the API (though I can with Regedit).

Yes, it seems baffling - something is awry here. The behavior of the API call and the Regedit should be the same for the same user.

Also, I DID create the key and attempt to modify the key in the HKEY_CURRENT_USER subset. Same exact problem.

I am at a loss on this one. Based on everything I'm understanding about this, though, if I had to pick a point in the code systems where things may be incorrect, I'd wonder about the SECURITY_ATTRIBUTES and SECURITY_DESCRIPTOR structures. Whether I pass an empty attributes structure OR a null, I'm getting this access denied result.

So, let's go at it like this:
 Using REGEDIT:
   I CAN create keys.
   I CAN create entries.
   I CAN modify keys.
   I CAN modify entries.

 Using API Calls from Program:
   I CAN create keys.
   I CAN create entries.
   I CANNOT modify keys.
   I CANNOT modify entries.

ALL under the same user?! What am I missing?
0
 
nffvrxqgrcfqvvcCommented:
Are you closing the key handles when your finished? I asked this in the previous post but I don't see your reply for that question... Where is your code and where is your RegCloseKey() calls.
0
 
ImusadeAuthor Commented:
I am closing the key handles.

Below are two functions - one CREATES a key, subkey, and entry. It works fine. The next attempts to modify a key that was just created by this same method. It fails with the access_denied return. You'll notice I have a commented out attempt to actually just delete this entry and recreate it - this also fails with a return of access_denied.
Public Function InstallSystemRegistry() As Boolean
    On Error GoTo ErrorHandler
    Dim baseInstallKey As Long: baseInstallKey = HKEY_LOCAL_MACHINE             'Root key...
    Dim targetKey As String                                                     'Subkey we want to open/create...
    Dim hTargetKey As Long                                                      'Handle to opened/created key...
    Dim secAttributes As SECURITY_ATTRIBUTES                                    'Type for security attributes (null)...
    Dim lFuncBehavior As Long                                                   'Descriptor detailing whether function performed OPEN or CREATE...
    Dim targetEntryKey As String                                                'Entry we want to create/modify...
    Dim lpszEntryValue As String                                                'Null-terminated string we want to create/modify in RE_SZ entry...
    Dim lEntryValue As Long                                                     'Long we want to create/modify in REG_DWORD entry...
    
    InstallSystemRegistry = False
    
    secAttributes.nLength = Len(secAttributes)
    secAttributes.bInheritHandle = CLng(True)
    targetKey = "SOFTWARE\CompanyName"
    longstatus = RegCreateKeyEx(baseInstallKey, targetKey, 0, vbNullString, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, secAttributes.lpSecurityDescriptor, hTargetKey, lFuncBehavior)
    If longstatus = ERROR_SUCCESS Then
        RegCloseKey hTargetKey
        targetKey = targetKey & "\SoftwareName"
        longstatus = RegCreateKeyEx(baseInstallKey, targetKey, 0, vbNullString, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, secAttributes.lpSecurityDescriptor, hTargetKey, lFuncBehavior)
        If longstatus = ERROR_SUCCESS Then
'SECTION:   This entry is a record of the version being installed...
            targetEntryKey = "Version"
            lpszEntryValue = PROPHECYSOFTWAREVERSION & Chr$(0)
            longstatus = RegSetValueExString(hTargetKey, targetEntryKey, 0, REG_SZ, lpszEntryValue, Len(lpszEntryValue))
            If longstatus <> ERROR_SUCCESS Then
                RegCloseKey hTargetKey
                Exit Function
            End If

            RegCloseKey hTargetKey
            InstallSystemRegistry = True
        End If
    End If
    Exit Function
ErrorHandler:
    InstallSystemRegistry = False
End Function



Private Function SetRegistryPSSInstallDirectory(ByVal newValue As String) As Boolean
    On Error GoTo ErrorHandler
    Dim baseInstallKey As Long: baseInstallKey = HKEY_LOCAL_MACHINE                                         'Root key...
    Dim targetKey As String: targetKey = "SOFTWARE\CompanyName\SoftwareName"                                'Subkey we want to open...
    Dim targetEntry As String: targetEntry = "InstallDirectory"                                             'Entry we want to read...
    Dim hTargetKey As Long                                                                                  'Handle to opened key...
    Dim lType As Long                                                                                       'Represents the type of registry entry found...
    Dim lBufferLength As Long                                                                               'Length of entry: for strings includes termination value), for longs will be 4...
    
    SetRegistryPSSInstallDirectory = False
    newValue = newValue & Chr$(0)
    longstatus = RegOpenKeyEx(baseInstallKey, targetKey, 0, KEY_EXECUTE, hTargetKey)
    If hTargetKey <> 0 Then
        longstatus = RegQueryValueExNULL(hTargetKey, targetEntry, 0, lType, 0, lBufferLength)
        If longstatus = ERROR_SUCCESS Then
            If lType = REG_SZ Then
                'longstatus = RegDeleteValue(hTargetKey, targetEntry)
                'If longstatus = ERROR_SUCCESS Then
                    longstatus = RegSetValueExString(hTargetKey, targetEntry, 0, REG_SZ, newValue, Len(newValue))
                    If longstatus = ERROR_SUCCESS Then
                        SetRegistryPSSInstallDirectory = True
                    End If
                'End If
            End If
        End If
        longstatus = RegCloseKey(hTargetKey)
    End If
    Exit Function
ErrorHandler:
    SetRegistryPSSInstallDirectory = False
End Function

Open in new window

0
 
LeithauserCommented:
You you add error code tot he program so that if you get this error, the program deltes the key and then recreates it? I know that is an unpleasant workaround, but it might do the trick if all else fails..
0
 
ImusadeAuthor Commented:
Absolutely wonderful.
0
 
ImusadeAuthor Commented:
EGL1044: You are the best. Wow, do I feel dumb.

I spent forever ensuring I was creating the keys with the correct access modifier. I neglected to check that when I reopened them to make changes.

Very nice - dumb mistake on my part, and excellent catch on yours!
0
All Courses

From novice to tech pro — start learning today.