Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1246
  • Last Modified:

Accessing registry in VC++ app with standard UAC level (Vista/7)

An application I'm working on cannot even read a HKEY_CURRENT_USER key when accessing at a standard UAC level under Vista or Win7. It comes up with a file not found error. Yet when accessing as an administration user (though not at the administrative level), no problem which is strange, again as I don't access with administrative priviledges. It is a VC++ app and the manifest is set to 'asInvoker' plus the manifest is included with the file. The installation is done with InstallShield Express with specific permissions set for the registry to Everyone and no domain; just blank.

I accessed another HKEY_CURRENT_USER area of the registry and didn't get an error.

I also ran Microsoft's Application Compatibility Toolkit and it indicates the a virtual registry should be used. I find that strange as all registry accesses are to HKCU keys.

To make sure the manifest is working correctly I raised the required level in the manifest to that needing administrative priviledges and when I did that I couldn't debug as the debugger didn't have administrative priviledges. That way I know that the manifest is being properly linked into the application. I would also imagine that I shouldn't be having the problem I'm having as the application is accepted as a regular application.

What must I do to fix this problem so anyone with any security level can install and use this application?
0
RJV
Asked:
RJV
  • 14
  • 10
  • 2
  • +1
1 Solution
 
Subrat (C++ windows/Linux)Software EngineerCommented:
hope ImpersonateLoggedonUser() might solve your problem.
0
 
Todd GerbertIT ConsultantCommented:
That's a bit of a non sequitur, eh? ;)

If by "virtual registry" you're talking about the registry virtualization of UAC I'm not sure that's something you have a choice of whether or not to use, and shouldn't apply since you're linking a UAC manifest (I believe file/registry virtualization only applies to applications without a UAC manifest).

Are you certain the permissions on the registry key in question are set such that they allow access for the user running the application?
0
 
RJVAuthor Commented:
First, I'm very glad to receive a response -- more than one in fact.

Subtrat2009, I'll check it out.

tgerbert, yes I am talking of registry virtualization. From what I understand in the documentation, the lack of a manifest file means, as you pointed out, registry virtualization. So, since there is a manifest (Visual Studio 2010 includes it by default), why would registry virtualization occur?

You asked it I'm certain that the permissions (in the manifest) allow acces,s and I would answer that I presume yes. The app is installed with InstallShield Express. Under "Organize Your Setup" InstallShield defaults Locked-Down Permissions to Custom InstallShield handling. That means you set the first element in the path and everything else below it is set accordingly. According to Flexera this is the best alternative.

But as I am unable to read the key (remembering that according to the documentation I dug through, reading always is possible) I tested by changing Locked-Down Persmissions to Traditional Windows Installer Handling and then patiently (more often impatiently) set each element of the path, and the key. I of course made sure reading was enabled and most often write too, though never create. None of that helped.

As you now doubt read, I tried UAC Execution Level as: asInvoker, highestAvailable and requireAdministrator -- the last just to see if the manifest was working.

So, what might I be missing? Why is it that it works when I log on as an administrator and not as a regular user (which also has no log on, on purpose as I want to test for all situations)? Might where I access the registry influence anything? Namely before the app is fully loaded (though again, why work with one permission level and not another).
0
Fill in the form and get your FREE NFR key NOW!

Veeam is happy to provide a FREE NFR server license to certified engineers, trainers, and bloggers.  It allows for the non‑production use of Veeam Agent for Microsoft Windows. This license is valid for five workstations and two servers.

 
Todd GerbertIT ConsultantCommented:
Not the permissions in the manifest, the permissions set on the registry key itself.  I would expect that normally everything under HKCU would be readable by the user, but it's entirely possible a key's permissions have been set such that the user is prohibited from reading it.

What key are you reading, and how?
0
 
RJVAuthor Commented:
tgerbert, according to Flexera by using their Custom InstallShield Handling (of security) you can set the security on one key and it will propagate to all subkeys. Thus I've right clicked on the key and set this:

    Domain:  left blank
    User: Everyone
    Advanced Permissions (button):
          Query Value, Set Value, Enumerate Subkeys, Notify, Read Control

Despite what they say I've set the above on each of these under HKEY_CURRENT_USER:

    Software\CompanyName\AppName\Settings

The value I'm reading (filePathStr) has no specific permissions and is a string accessed as follows:

   HKEY hKey;
   CString strSubKey = "Software\\CompanyName\\AppName\\Settings"
   RegOpenKeyEx( HKEY_CURRENT_USER, strSubkey, NULL, KEY_QUERY_VALUE, &hKey );

The problem hits when opening the key so I won't head into the string step to get the value.

As a matter of curiosity I tried accessing:
   "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders"
...and that works so what you say makes sense.

I might note that the Windows Vista I'm accessing is under VMWare. While I don't imagine that to be the problem I found it curious that Microsoft's Application Compatibility Toolkit not only indicated the need for virtualization but also flagged VistaRTMVersionLie. I have no idea what this means (nothing new there as it seems the more I learn the less I know!) but wonder if this isn't related to something with VMWare.

Subtrat2009, I tried ImpersonateLoggedonUser() and no luck. I also tried RegOpenCurrentUser() but no luck with that.
0
 
RJVAuthor Commented:
A bit more information.

I installed on Windows 7 as a standard user. When I do that I am automatically offered two alternatives by InstallShield:  Install For All Users or Install For One User (or similar; not exact wording). When I install for All Users the app works exactly as it should. When I install for the single user it actually crashes. I then look for the folders that should have been created in Program Files and none exist.

I have a feeling something similar is happening in Vista. I hope this helps you guys identify what might be going on.
0
 
RJVAuthor Commented:
Reviewing what happened on Windows 7 as a standard user, it's clear that it failed at the same point as on Vista: registry access. As you pointed out, tgerbert, the standard user doesn't have access to the key. From what I see on InstallShield, it lets you set the specific permissions for the key. I haven't found where I can stipulate that the key can be accessed by a standard user level. Am I missing something? How do I make sure the standard user has access to all HKCU parts of the app's registry?
0
 
trinitrotolueneDirector - Software EngineeringCommented:
Sorry for jumping in late but this is something I have encountered....if I understand you correctly the registry keys are created by your application.

Have you taken care to set the security descriptor for the keys you are accessing?

http://msdn.microsoft.com/en-us/library/ms724878(v=vs.85).aspx

and you might also want to give the reg.exe utility mentioned here a try
http://msdn.microsoft.com/en-us/library/bb530198.aspx
0
 
RJVAuthor Commented:
Hi trinitrotoluene. I'm glad you jumped in as I do have to resolve this matter asap. In answer to your question, I created the registry keys before, out of the application, with the registry editor. I could have done it with the app but when uninstalling anything, all registry entries should be removed. So I used InstallShield's functions to copy those registry keys over and it handles updating the registry, which it does normally. Where can one change the security descriptors? That might be the cause of the problem as I did that with Admin rights (a natural must by the way I did it). InstallShield lets you set permissions, but that doesn't impact the levels.

Might reg.exe do the trick I just mentioned about setting levels? I'll give it a try but your experience no doubt will help even more.

The twist in this whole story is something I just did. To try to identify what's going on I created a simple app and just had it access a string in the registry. Then I created a registry entry as I did above, with the problem app. Finally I loaded the InstallShield file also of the problem app and then saved it with a different name after the few necessary changes. I even made a point of not setting any registry persmissions, leaving them at default (as I had originally with the problem app). Finally I installed under Vista and lo and behold, everything worked normally...! Hopes high, but comparisons with the manifest showed both to be the same. There's only one extra line in the original manifest which I haven't been able to get rid of yet (VS2010 blocked that). Might there be somewhere else to look?

Still, a slightly more positive step but still no closer to the why.
0
 
RJVAuthor Commented:
trinitrotoluene, I just tried reg.exe, trying to see the flags set on the key. It came back that the operation can only be done on HKLM keys, and my problem are with HKCU keys -- which I understand shouldn't even be an issue.
0
 
Todd GerbertIT ConsultantCommented:
Don't set any permissions on keys in HKEY_CURRENT_USER in your InstallShield project. New sub-keys will inherit permissions from the parent (HKCU\Software in this case), which should be appropriate in almost every case.

Virtualization (in the context of UAC) is something that will only apply in the absence of a UAC manifest, and only in cases where writes are made to files in %WinDir% or %ProgramFiles%, or writes made to system-wide registry hives (such as HKEY_LOCAL_MACHINE).

VistaRTMVersionLie means that an application is checking for a version of Windows and not finding it (e.g. an application checks if WindowsVersion == 5, but the correct way to check would be if WindowsVersion >= 5), so Windows can lie to the application to make it's version check work.

Generally applications should always be installed as an administrator. Installing as a standard user will result in the application being installed in the user's profile somewhere (e.g. C:\Users\RJV\AppData\Blah\Blah) because non-administrators don't have write permissions to C:\Program Files.

Install for Single User vs. All Users will affect the installation location of some items - e.g. if you setup a key in HKEY_LOCAL_MACHINE in and install the package for single user those keys will actually be written to HKEY_CURRENT_USER.  You will probably want install for all users.

>> When I install for All Users the app works exactly as it should. When I install for the single user it actually crashes. - Do you mean the installation crashes, or the install finishes but the application crashes?

There are no "levels", no such thing.  Registry keys just have a set of permissions, just like files, for allow/permit various tasks (e.g. read, write, delete, etc). Some system-related keys are protected and require that you be an administrator, and under UAC there's an extra step to becoming an administrator: when you logon as an administrator you initially receive a more limited user token, to become full administrator a process must be elevated - the asInvoker, highestAvailable settings control whether or not Windows will automatically elevate the process. None of this UAC stuff applies to you since you're working in HKCU.

Delete the keys from your registry, and delete them from your InstallShield project. Then re-add them to your InstallShield project, and don't modify their permissions.
0
 
RJVAuthor Commented:
tgerbert, thanks for clarifying all the bits and pieces I've found all over the place and not clearly in one place. I had followed those bits and pieces so I'm glad from your input that I've indeed gone on the right track.

You made two interesting points. First, I did design getting to the information be it installed for a Single User or All Users. I did that thinking of the typical user and even knowledgeable user that installs as a Standard User and accepts the demand to raise to the Administrative level. BTW, when I say level I meant: Standard or Admin... levels. As I mentioned, under Win7 I chose All Users and it worked, and didn't when I chose Single User. However, Vista doesn't have that option and seems to just install as a Single User, thereby causing the problem. Is there any way one can force the installation (i.e. InstallShield) only to install to All Users?

I'll give changing the registry a shot too in the meantime.

Thanks for clarifying VistaRTMVersionLie. I had to figure out what was what, particularly if an XP, to make sure I got the right paths when starting up. I test the major version and the minor version to make sure I get the right one but evidently Microsoft's tool doesn't see that.

To wrap up, I am curious why the simple app I created worked under Vista (thus Single User). In retrospect, I also created a key, so here's hoping on the key front!
0
 
Todd GerbertIT ConsultantCommented:
There's a setting in the MSI database, which you should be able to change in your InstallShield project, that's called "ALLUSERS" - try searching through the InstallShield help file for that term.

If you install while logged on as an administrator it probably installed for All Users, whereas a non-administrator installing it would result in an Single User install.  Single user is probably not what you want, you'll need to make sure you don't make any assumptions about the locations of any files or permissions that the user possesses.
0
 
RJVAuthor Commented:
tgerbert, I'll dig through InstallShield and see what I find. They do have that option but also let it change to Single User, invisibly to the installer, so I hope I can find where I can lock it in.

I actually have coded not to make assumptions as to where things are located. Windows XP does a "royal" job of putting things in odd places and one can't afford to ignore that platform. Even then, it never crossed my mind that there might be issues reading a key, particularly an HKCU key.

People do stupid things. Problem is, we think it's stupid but then they think we're stupid for not taking them into account. So I have to imagine that they will install as standard users, so then best make sure it always installs for All Users. I'll let you know what I come up with.
0
 
Todd GerbertIT ConsultantCommented:
If you don't allow for Single User installation (e.g. set "ALLUSERS" to 2 - or whatever) then they'd just get a message saying "you have to be an administrator" when they try to install it, otherwise if they are an administrator it'll just install for all users.

HKCU shouldn't be affected either way.  My concern was that you inadvertetly made the permissions on the registry keys in your InstallShield project too restrictive, which is why I suggested removing and re-setting them.
0
 
Todd GerbertIT ConsultantCommented:
A typical MSI installation requires administrative privileges to install, and always installs for All Users.  It's rare to see otherwise.
0
 
RJVAuthor Commented:
tgerbert, InstallShield's default setting is 1, All Users, which is what I've used. 2 allows it to install to Single User or All Users. The reason I don't think that's happening (only All Users) is that when I installed to Windows 7 it offered both alternatives even though set for only one. I tried both possibilities yesterday and as you pointed out, the Single User alternative put the files in a completely different place (not even in Program Files). Under Vista it installed like All Users (no option offered) yet I encounter the problem.

InstallShield always forces the user to elevate to an Administrator. From what happens and where files are placed, it doesn't follow the Administrative rules prevail but the logged user's rules. Probably if you backed up and logged on to an administrative account and installed for All Users, all would work. I haven't tested that as I know there will be pesky standard users and lazy administrative helper users who won't change log ons to install the app.

The irony in all of this too is that InstallShield says they let MSI handle installations. Also both are considered the standard. But, InstallShield has its own unique security permissions, more extensive than Microsoft's, which makes one wonder about their using MSI to install.

I'm still tearing InstallShield up looking that All Users needle.
0
 
trinitrotolueneDirector - Software EngineeringCommented:
>>>>"In answer to your question, I created the registry keys before, out of the application, with the registry editor."

Could you try changing this and try creating it from within your application?

These are the functions to do it

http://msdn.microsoft.com/en-us/library/ms724878%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/aa379314%28v=vs.85%29.aspx
0
 
RJVAuthor Commented:
trinitrotoluene, I had created them internally originally just for test purposes but removed them as it becomes messy when uninstalling. By letting the installer handle their installation, it will also remove them when uninstalling.

Having said that, one should have read access to all keys in all parts of the registry and restricted to the HKCU in terms of writing, or in another virtualized area should the app be deemed incompatible. I understand only the lack of a manifest file should trigger that incompatibility.

For some strange reason the app is being considered incompatible even though there is a manifest that is also configured properly. Something else is triggering the incompatible flag and most probably the OS decided that the key should be somewhere else -- such as in a virtualized area. The error I get is not because access is blocked but because the path is considered wrong. Probably a compatibility fix will also fix this problem.

Back to creating the key, it most probably would be placed in the virtualized area of the registry. Beyond not being removed should the app be uninstalled, one runs the risk in the future as Microsoft has indicated it will no longer support virtualization. Finally, a new app designed with the latest but which is considered outdated -- well, it doesn't make that much sense.

What else then would make the app incompatible with the latest?
0
 
Todd GerbertIT ConsultantCommented:
>> For some strange reason the app is being considered incompatible even though there is a manifest that is also configured properly
Note that you have linked a UAC manifest to your application, but the application that's responsible for creating the registry keys is the installer - which may or may not have it's own UAC manifest, but that's probably a moot point since UAC does a very good job of auto-detecting installers, and is not likely significant to the problem at hand anyway.


>> Back to creating the key, it most probably would be placed in the virtualized area of the registry.
Doubtful.  Writes to HKCU would never be redirected under any circumstance.


I think we're making this much more complicated than it should be.  RJV, is your application 64-bit, and if not are you installing on a 32- or 64-bit version of Windows?  Have you double-checked that the spelling of the key in your program's code matches the spelling of the key you've setup in the installer project?
0
 
RJVAuthor Commented:
Good questions tgerbert. It's a 32-bit application installed always on 32-bit operating systems.

Spelling is correct on the keys. Also otherwise they wouldn't work with the original testing, nor when logged on as an administrator (without administrative priviledges on the app).

You're not only right on the installer but InstallShield generates an .msi file so really, it becomes a regular Windows installation.
0
 
Todd GerbertIT ConsultantCommented:
@RJV

I don't seem to be able to duplicate your problem - but I'm starting to suspect it's as simple as you're installing the application as a different user than who is running the application. e.g. The user "Bob" runs the installer, is prompted by UAC to provide administrative credentials and Bob happily enters the login information for DOMAIN\Administrator.  Now your installer is running as DOMAIN\Administrator, so when it writes keys to HKCU it's writing them to DOMAIN\Administrator's user hive. After the installation completes Bob tries to run the application, but it fails because the registry keys were never created under Bob's HKCU.

I suggest making ALLUSERS = "1" and Require Administrative Privileges = "Yes" under the "Organize Your Setup" -> "General Information" section. This will force an administrator to perform the installation (which is very typical, but that's up to you - as far as how you want your application to install & run).

Adjust your application's start-up routine to check for, and create if necessary, the registry keys you expect to find under HKCU.
0
 
RJVAuthor Commented:
tgerbert, that's something I had thought about and your reasoning makes sense in that the installation already is ALLUSERS = 1. I have a feeling it might be a bit of that plus another problem I discovered.

I already had tried Procmon to see what's going on under the surface. The volume of info was so large I couldn't isolate our application. Late yesterday, searching around I found a filtering solution by chance and right here. Now I can see the bad registry accesses. Curiously, what seems set restrictions off is when sockets get initialized. While that code is standard application code (VC++), it accesses another area of the registry to read from it. When that happens the application's registry access in generlal gets blocked.

So now I have to figure out how to not to take that info account and cause the problem, before the other issue is reviewed. I even managed to create an application and replicated the problem, as it happens as all users or as a single user.

Indeed, if I can make all users mandatory the issue you mentioned would be avoided.
0
 
Todd GerbertIT ConsultantCommented:
You're making this far more complicated than it really is (I think).  Don't read more into the problem than there really is, otherwise you will quickly go insane.

1) All Users or Single User is irrelevant, the fact remains you should check for the existance of registry keys before attempting to read values they contain, as opposed to assuming they're accessible.

2) You can make an all-users installation mandatory (see my comments in http:#a35698724). 99.99999999% of applications install this way. It will be nothing new to the users or IT staff performing the installation.

3) If you're in the mood to be nice to your users and IT staff you can set ALLUSERS="" or ALLUSERS="2" - but be prepared for more than one copy of your program to be installed on a given computer (different versions even), and make sure your installer does not attempt to perform any action a standard user would not have permissions to do (e.g. write to C:\Windows), also be prepared for each installed copy per machine to see different registry values under HKLM.

4) Are you saying WSAStartup() is failing? Or that once WSAStartup() is called you can no longer access the registry?
0
 
RJVAuthor Commented:
tgerbert, solved. Your analysis was correct. If the user logs on and installs as a Single User, but to install you need administrative priviledges, that Single User won't be able to access as the priviledged user (as it were) is the administrator. This is part of the problem.

The other part is that the user should be included in an HKLM key and not an HKCU key. Unknown to me, as the documentation I had access to was unclear, the standard user can write to an existing HKLM key. The standard user cannot create a key there; only the administrator. By moving the keys to HKLM the problem is fully solved as All Users become fully acceptable.

I'm awarding you the points as your analysis was instrumental to helping resolve the problem.
0
 
Todd GerbertIT ConsultantCommented:
>> the standard user can write to an existing HKLM key

Only if someone or something set permissions on the key to allow that - by default keys under HKLM are read/write for Administrators and SYSTEM, and read-only for everyone else.
0
 
RJVAuthor Commented:
Well, tgerbert, as this problem had to be resolved as soon as possible, I also wound up submitting it to Microsoft. It was they who said I should use HKLM. As was pointed out, HKCU is not for All Users but only Single Users. The app cannot create keys there. After the change, the problem went away. The keys were read with no problem at all. I'll be testing much more comprehensively, particularly to check out writes of values. I'll post the results to you as soon as I have them.
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 14
  • 10
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now