tags:

views:

280

answers:

2

The question pretty much says it all.

I have an app with an older component that doesn't work right if runtime themes are enabled. But if I don't enable them, the app always ends up messing with the virtual store.

Thanks!

Update:

Using Mark's solution below, the application no longer writes to the Virtual Store. But, now it won't access a tdb file (Tiny Database file) that it needs. This tdb file is the same file that was being written to the Virtual store. Any ideas on how I can give it access to the tdb file and still prevent writing the Virtual Store?

+4  A: 

You need to add a manifest (resource) to your exe.

In the manifest is an XML Resource with content similar to that below. The TrustInfo is the key section that causes the VirtualStore not to be used.

This example has the Microsoft.Windows.Common-Controls assembly referenced which enables runtime themes. If you remove that from the manifest you can still keep the TrustInfo section.

Vista uses the TrustInfo to decide that the application "knows" about the UAC restrictions and does not use the VirtualStore for that application

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity
    type="win32"
    name="Delphi 7"
    version="7.1.0.0" 
    processorArchitecture="*"/>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity
        type="win32"
        name="Microsoft.Windows.Common-Controls"
        version="6.0.0.0"
        publicKeyToken="6595b64144ccf1df"
        language="*"
        processorArchitecture="*"/>
    </dependentAssembly>
  </dependency>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel
          level="asInvoker"
          uiAccess="false"/>
        </requestedPrivileges>
    </security>
  </trustInfo>
</assembly> 

Here are two pages with more detail on how to create and use the manifest files:
http://ruminatedrumblings.blogspot.com/2008/03/vista-uac-manifest.html
http://delphi.about.com/library/bluc/text/uc111601a.htm

And a Microsoft page on the Application Manifest Schema:
http://msdn.microsoft.com/en-us/library/bb756929.aspx

Of course once you do this you will no longer be able to write data to c:\program files\ or other protected locations with UAC turned on. That is why Microsoft created the virtual store in the first place. It is intended to keep old applications running that expected to be able to write to those (now protected) locations.

You have a few different options:

1: Change the file location

Move the tdb file to a different location. This is the ideal case but can require the most code changes. See the question "Correct way to design around Windows UAC Limitations" for some suggestions. The Microsoft recommendation is to store data that the user does not name under the "Application Data" folder. I tried this but it makes it very hard for users to find the data to move it to a different computer. I have moved all of my user data, even if the user does not specifically save the file, to the My Documents folder. That way when they get a new computer they can just move "My Documents" (and most do anyway) and all of my application data will move as well.

2: Change the permissions on the file to allow standard users to read/write the file. Either your installer could do this or you could updated it after the fact, but you will need to be running as administrator to make the change.

3: Force your application to run as administrator. If you set the execution level be "requireAdministrator" as Sertac notes you will be able to write to the files, but then your users will get a UAC Elevation prompt every time they run your application.

Also note that if you are upgrading users who have been running and saving data to the Virtual Store there is nothing that automatically moves that data to the new location. Once you add the manifest to your application it will start to see the files that are actually under c:\program files*. You may need to look for files in the virtual store and copy them to the new location for the user. Below is an example. In my case license files were stored under the install directory. After I upgraded my application I needed to look for the old license files and move them to the new location:

procedure TResetMain.CopyVirtFiles();
var
  VirtLicDir: string;
  NewLicDir: string;
  FileOp: TSHFileOp;

  TempPath : array[0..MAX_PATH] of Char;
begin


  SHGetFolderPath(Application.Handle, CSIDL_LOCAL_APPDATA, 0, 0, TempPath);
  VirtLicDir := TempPath + '\VirtualStore\Program Files\My Company\Licenses';

  NewLicDir := GetMyConfigDir();
  if NewLicDir <> '' then
  begin
    NewLicDir := IncludeTrailingPathDelimiter(NewLicDir) + 'User Licenses';
  end;

  // If the Virtual license directory exists but not the new directory we
  // know this is the first time the updated application has been run
  // and we need to move the files to the correct location.
  if DirectoryExists(VirtLicDir) and Not DirectoryExists(NewLicDir) then
  begin
    ForceDirectories(NewLicDir);

    FileOp := TSHFileOp.Create(nil);

    FileOp.FileList.Add(VirtLicDir + '\*.*');
    FileOp.Destination := NewLicDir;

    FileOp.Action := faMove;
    FileOp.SHOptions := [ofFilesOnly, ofNoConfirmation, ofNoConfirmMKDir, ofRenameOnCollision, ofSilent];
    FileOp.Execute;

    FreeAndNil(FileOp);
  end;

end;
Mark Elder
Shouldn't the execution level be "requireAdministrator" in order to be able to write to ProgramFiles etc..?
Sertac Akyuz
@Mark, I tried your solution, and the application no longer writes to the Virtual Store. But, now it won't access a tdb file (Tiny Database file) that it needs. This tdb file is the same file that was being written to the Virtual store. Any ideas on how I can give it access to the tdb file and still prevent writing the Virtual Store?
croceldon
I'll edit my answer to include some options.
Mark Elder
+2  A: 

A few alternatives to Mark's answer.

  • Right click and select "run as administrator".
  • Modify the compatibility properties of the application to include "run this program as an administrator".
  • Rename the executable to include one of the words of "install", "update", "setup", "patch".
  • Include one of the mentioned words in version information, for instance set "Internal Name" to "MyApplication install". Specifics here.
  • If the UAC dialog or running elevated is unacceptable, modify permissions on folders or files where the application needs to write. For instance if the component is dropping a log file on "MyApplication\Logs" set security on "Logs" so that "Everyone" has "Full Control" on the folder. Do not forget to delete "..\AppData\VirtualStore\Program Files\MyApplication\Logs" for this to have effect.
Sertac Akyuz
Everyone????!!!!! FullControl?????!!!!!! If needed, give the *least* privileges needed to work, not full privileges to the whole world. I suggest you to check what the real implications of your suggestion are, and learn what standard group and standard privileges contains and enable
ldsandon
@ldsandon - > >"FullControl?????!!!!!!" - You think administrators do not have full control access to files and folders? - >"Everyone????!!!!!" - If you want everyone to be able to run your program, then yes. - >"..check what the real implications.." How's that different than running elevated? There are some advantages and disadvantages. The permissions are persisted but f.i. to a "Logs" folder. At least you're not giving full control to all of the system.. I suggest you to consider giving some thought before bashing an answer. At least when the subject is not in coverage of your expertese..
Sertac Akyuz
"Everyone" is not "Users". Please check what "Everyone" really means. Administrators have full control, but you're giving full control to everybody! what if "everybody" drops somthing there and have someone with elevated privileges run it? With proper settings you do not need elevation at all - which is something you should avoid when possible. And about my expertise, feel free to check my profile, I suggest you to improve *your* expertise, because it is clear your knowledge of Windows security is very limited.
ldsandon
>"Administrators have full control, but" - I'm giving full control to "everybody" on a folder. If you let them run with elevation, you're giving "Users" full control on "everything".>"what if "everybody" drops somthing" - They'll not be able to execute it, there's no privilege elevation in this solution. Read the answer! >"With proper settings you do not need elevation at all" - That's the point, if you do not let the thing write on this whatever file, you've to give users elevation in order for the program to function. Not good! >"expertise.." - I hope you're not charging for this expertise.
Sertac Akyuz
Please explain why you choose the "Everyone" group and not the "Users" one, and why "Full control" and not more limited privileges, excluding "execute", for example. If you give "full control", you can do whatever you like in that folder, including changing security, and if you give that permission to "everyone", you are using the broadest group. You just used lazily the broadest privileges, oh yet, it surely works, but that's not security. And here my expertise is free, don't worry.
ldsandon
> "why you choose the "Everyone" group" - That's not a deliberate choice. As I've told in the first comment-answer, whoever you like to run the application, choose them. I have no knowledge whether this particular app should be able to be run by guests or whatever. Implications: note that if unauthenticated access to the system is already restricted it won't make a difference.
Sertac Akyuz
> "why "Full control" - Again, I wouldn't know the particular requirements. If "Write" is OK so be it. If it should execute sth. then put it. This is a generalization of the solution, yes.. it doesn't delve into possible details, yes.. Implications: an "everybody" puts malicious code into the folder, but since it requires elevation they can't run it. Bummer!
Sertac Akyuz
> "give "full control", you can do whatever you like in that folder, including changing security" - What for? They're already in full control of the folder. Note that even if they've got full control, they can't take away the "ownership", not without an UAC credentials prompt. Then again, nothing can take away the right of "taking back the ownership" from an admin, nothing! But as an expert, you knew this already of course. Implications: A malicious guest comes and modifies security to deny access to a user. Now the user has to appeal to his admin. Oh, I'm sorry to have caused this trouble..
Sertac Akyuz
> "You just used lazily the broadest privileges" - Sure. This was supposed to be a quick answer which would show where to start loooking. This is no course material, or security discussion or blog entry or whatever. I'm not expected to produce a customized solution. Then again, had I known that this would turn into a daily-commenting job, I would be more careful.
Sertac Akyuz
> "my expertise is free" - I have no intention to make use of your "expertise", I was just wondering if I should pity your customers. You do not object to having users run with elevated privileges, but you do object to setting a "full control" permission on a folder to prevent that. You, simply, have no place in security business. As lazy as I am, being ridiculous is different. My favorite one is >"what if "everybody" drops somthing there and have someone with elevated privileges run it?". You know what? As ridiculous as your comments are, entertaining they're as well. So keep them comin'.
Sertac Akyuz
Ok, you're the classic guy who believes to know everything and refuses to learn, and don't either read what people writes, and just use personal attack to hide behind. One day you'll learn it the hard way. As a security professional, it was not entertaining to read your complete misunderstanding of Windows security, because I know how much bad code is out there and how many machines at risk because people like you just look for a shortcut instead of a proper solution.
ldsandon
Ok, then the other way around.. Case: you don't mess with permissions and let a (malevolent) user run the program with elevated privileges. Implications: The user takes full control of the system (with many (if not most) thick client qui/desktop applications this is the case, with other applications depends on what and how the application does - and this is not a security flaw on the OS's part). -- I've listed the implications of my "lazy" answer one by one, now go compare the implications! And note that I'm responding only to what you are saying - there is no personal attack from here.
Sertac Akyuz