Welcome to MSDN Blogs Sign in | Join | Help

Chris Jackson's Semantic Consonance

Windows Application Compatibility in the Real World
Using the CorrectFilePaths Shim to Redirect Files on Windows Vista

The last time around, I suggested that you avoid using the acredir.dll shims - RedirectRegistry and RedirectFiles. As alternatives, I recommended VirtualRegistry and CorrectFilePaths.

Of course, I have already gone into some details on how to use VirtualRegistry to achieve that, but I haven't gone in to any details on CorrectFilePaths yet. And, unfortunately, the documentation isn't much help as of the 5.0.1 release (as I said - stay tuned to the documentation for future releases, as this is something we are working on). In fact, here is all that the documentation tells you:

"Corrects file paths that changed between Windows 95 or Windows 98 and Windows XP Professional. This compatibility fix works by converting the file paths to the correct location for Windows XP Professional in the APIs. For example, a Windows 95 path of C:\Windows\Write.exe is converted to C:\Windows\System32\Write.exe."

While this is true, it is not comprehensive (and is, therefore, not as helpful as you probably want it to be). You see, CorrectFilePaths does apply a number of default corrections, but the real power is your ability to add additional corrections. (You can also configure the shim to not apply the default corrections, using the -b switch.The b stands for base, or bare, or whatever helps you to remember it.)

To add additional paths to correct, you once again have to go into the parameters dialog box. For this, once you have selected (and checked off) the CorrectFilePaths shim, you then need to click the Parameters button. Then, at the command line, you can enter the pairs of file paths you would like to have corrected, using the syntax "old path;new path".

The quotes I have used are not accidental. You see, part of mastering the use of shims on Windows is learning the intricacies of the command lines, and the person who developers each shim is responsible for parsing that command line. In this instance, the command line happens to be space delimited. So, if your paths contain spaces, you'll want to quote them. However, you don't want to quote each path (which is probably what I would have guessed), so "old path";"new path" is wrong. Rather, you want to quote the entire pair, and repeat this for each individual pair if you want to correct more than one path.

Here is an example command line from a redirection that I applied, to illustrate:

“C:\Windows\Downloaded Program Files\StockViewer.ini;%userappdata%\StockViewer.ini”

Now, one thing you may have noticed is that I have used what appears to be an environment variable. Let's talk about that.

There are a couple of reasons why we anticipated having to use CorrectFilePaths: hard coded file paths, and permissions issues. We either want to redirect a hard coded path, or we want to redirect from a location where a standard user won't have permissions to write to one where they do. (An aside about that: you may be asking why we would need to do this, given that File and Registry Virtualization in Windows Vista will redirect from per-machine locations to per-user locations. Well, we only correct the directories Program Files, ProgramData, and Windows. There are still plenty of applications out there who feel that they are "too important" to be lumped in with the other applications you have installed under Program Files, so they install in the root of the drive. We don't redirect for arbitrary directories, just for these three, so applications like this are going to need a big of a nudge from you.)

Clearly, with hard coded paths being one thing we're trying to fix, we don't want you to have to include hard coded paths in your command line, so we added the ability to get at known locations without that. But, since all you get is a command line, we didn't want to limit you just to environment variables, so we give you a slight variation that lets you get at the value from either an API or a known folder. Specifically, you can choose to use the following variables:

%windir% = value from GetWindowsDirectoryW
%systemroot% = value from GetWindowsDirectoryW
%systemdrive% = first two characters from GetWindowsDirectoryW
%systemdir% = value from GetSystemDirectoryW
%username% = value from GetUserNameW
%programfiles% = value from ShGetFolderPathW(..., CSIDL_PROGRAM_FILES, ...)
%userstartmenu% = value from ShGetFolderPathW(..., CSIDL_STARTMENU, ...)
%allstartmenu% = value from ShGetFolderPathW(..., CSIDL_COMMON_STARTMENU, ...)
%userdesktop% = value from ShGetFolderPathW(..., CSIDL_DESKTOPDIRECTORY, ...)
%alldesktop% = value from ShGetFolderPathW(..., CSIDL_COMMON_DESKTOPDIRECTORY, ...)
%userfavorites% = value from ShGetFolderPathW(..., CSIDL_FAVORITES, ...)
%allfavorites% = value from ShGetFolderPathW(..., CSIDL_COMMON_FAVORITES, ...)
%userappdata% = value from ShGetFolderPathW(..., CSIDL_APPDATA, ...)
%allappdata% = value from ShGetFolderPathW(..., CSIDL_COMMON_APPDATA, ...)
%allusersprofile% = value from GetAllUsersProfileDirectoryW
%userprofile% = value from GetUserProfileDirectoryW
%appexedir% = value from GetModuleFileNameW

So, you can use CorrectFilePaths to redirect to one restricted or moved location to a better one, leveraging these variables to locate the correct spot on a particular installation.

There are some additional details on this shim and how it can be configured. Specifically, we cover a huge set of APIs, you can add some more, or turn some off. But this isn't something you typically have to do. So, instead, I figured I'd give you the stuff you're actually likely to need, and include the rest in the less narrative documentation.

Posted: Monday, October 15, 2007 11:51 AM by Chris Jackson

Comments

scotthcw said:

Hi Chris,

Thanks for your post here and it helps a lot!

However, I have a Q here:

Would CorrectFilePaths Shim redirect all the access to the new path?

For example, if I want to write to file "asdf.log" in "C:\Program Files\[Apps Folder]" which is locked, then I apply the CorrectFilePaths Shim in this case, it would redirect to the new path ("C:\Users\[Logon_User_Name]\AppData\Local\VirtualStore\") and write to it successfully.

However, in my case, the application still need to read to "qwer.cfg" in "C:\Program Files\[Apps Folder]", but it try to find the "qwer.cfg" in new path.

Do you have any idea in this case? Or am I choosing the incorrect Shim fix?

Thank you.

# November 30, 2007 4:32 AM

Chris Jackson said:

scotthcw,

If the applicaiton is trying to write to %programfiles% then Windows Vista's file and registry virtualization should fix that up without you having to manually intervene. Check out the UAC File Virtualization event log if that's not happening.

CorrectFilePaths is a path swapper. While virtualization is pretty sopohisticated, and does copy on write, CFP just replaces the path in the API call, whether your reading, writing, etc. You'd have to shim the specific file you want to redirect to the full path of the file in the new location to grab just a single file.

Chris

# December 1, 2007 3:38 AM

Patric said:

Hi Chris,

Could you have more than one redirection on the command line? If so, how do you separate them? Or could you add more than one CorrectFilePaths shims but with different redirections?

Thank you!

# December 5, 2007 3:58 AM

Chris Jackson said:

Hi Patric,

Separate multiple redirections with spaces. (That's why you have to quote redirection pairs that have spaces in the path - so we don't parse them incorrectly.)

Chris

# December 5, 2007 4:19 AM

Hana said:

Hi Chris,

May I know if Shim can apply on installation issue?

For example, I would like to make an application that originally installed to [Directory A], and use CorrectFilePaths Shim to make it install to [Directory B], is it possible?

Thanks you...

# January 8, 2008 8:21 PM

Chris Jackson said:

Hi Hana,

Is it an exe or an msi? If it's an exe, you can shim it up the same way you could shim up any other exe - all of that works the same. If it's an msi, that's a different story - the best approach would be to create an msi transform to redirect to the alternate directory.

Thanks,

Chris

# January 9, 2008 9:31 AM

Hana said:

Thanks Chris,

It's an msi, do you mean apply the Shim on msiexec.exe to redirect to the alternate directory?

Thanks,

Hana

# January 10, 2008 1:10 AM

Chris Jackson said:

Hi Hana,

No, don't shim up msiexec, or you'll be shimming every msi that there is (which is not a good idea). We're tossing around the idea of allowing shims on msis but it's not there right now.

Since MSI is nothing more than a database, and it can be transformed, in this case it's just easier to create an mst (MSI Transform) to redirect rather than trying to shim.

Chris

# January 10, 2008 9:45 AM

Bruce Taylor said:

Can this be used to redirect a file that is generated based on date?  We have an app that creates a c:\ddmmyy.log type file (sadly) which I need to look after.  

ACT is taking some understanding any pointer on that one?  BT.

# January 13, 2008 11:38 PM

Chris Jackson said:

Hi Bruce,

Unfortunately, CorrectFilePaths doesn't have the notion of variables to take arbitrary file names from one location and use the same name in another directory, so it doesn't help you here.

You could redirect just the beginning of the path, but since it's at the root, you'd be redirecting absolutely everything, which is almost guaranteed to break it worse than it's broken now.

Chris

# January 14, 2008 8:16 PM

Amit Ranjan said:

Hi Chris

I have shimmed an application having file path issues in vista. But when I tested that application on another Vista Machine, the patch did'nt worked. So, I want to know two things:

1. What's the procedure for deploying the shimmed application?

2. As we are using sdb for keeping database of shims, So Is there any way to ship it without such files or to ship standalone shimmed executable.

With regards

Amit Ranjan

# February 27, 2008 10:58 PM

Chris Jackson said:

Hi Amit,

You deploy the fixes by installing the shim database (running sdbinst.exe against the .sdb file). You will need to install the database on the second machine before the fixes are applied. We do not modify the executables directly at any point, so you always have to deploy the sdb before the fixes will be applied.

Thanks,

Chris

# February 27, 2008 11:13 PM

Amit Ranjan said:

Hi Chris,

As you told , for deploying the patched application we need to install the database first and then to run the app. I did, but its not working.Below is what I did:

I copied the file to %WinDir%/AppPatch/Custom folder of another machine and then register it using sdbinst.exe from command line. used this sdbinst.exe c:\windows\apppatch\demoApp.sdb, the message appeared database installed successfully. then I ran application... but the app crashed. it means that the patched was'nt applied properly.

So where and what is missing...

we are using Vista Business version 6.0(Build 6000). I am not able to figure out.

Thanks

Amit Ranjan

# February 28, 2008 1:01 AM

Amit Ranjan said:

Hi Chris,

Also I missed one thing to tell you, I installed the database using Compatability Administrator and even after that the shim was not working. Where as it's working on mine machine.

# February 28, 2008 1:07 AM

Amit Ranjan said:

Also, Is it possible to create our own custom shims for compatibility Administrator.

# February 28, 2008 1:10 AM

Chris Jackson said:

Amit - you do not need to copy to %windir%\apppatch\custom. When you install using sdbinst, we generate a guid and place a properly registered copy in there - you shouldn't have to ever put something there manually.

If it's working shimmed on one machine, but not on another, then clearly there is a difference between the two machines that is causing the failure. Perhaps PCA has applied some other shim, perhaps the ACLs are set differently - you'll need to research what is going on. If you're using CorrectFilePaths, perhaps you're redirecting to a location that doesn't exist on that box, and it's just causing a different failure. Try using ProcMon to see what is going on.

You are not able to create custom shims.

Thanks,

Chris

# February 28, 2008 4:50 PM

Amit Ranjan said:

Hi Chris,

One more query...Can I edit or view the parameters  added to the built-in shimmed application? Is there any way?

This will help a lot in application fixing process.

Thanks in advance.

Amit Ranjan

# March 2, 2008 11:52 PM

Chris Jackson said:

Hi Amit,

Sure. Just start up Comptibility Administrator with the /x command line switch.

Thanks,

Chris

# March 3, 2008 4:10 PM

Joe said:

Chris,

This information was very useful.  I fell into the trap thinking RedirectFiles was what I needed and couldn't get it to work.  I wish there was better reference/help information on the all the shims.

We have some apps that like to write to the Windows folder or protected areas of the registry, so that changes made by a user is seen by all user on that device.  The Vista virtualation doesn't work because it sticks these in the users own area not accessible by others.  If I use the CorrectFilePath or the VirtualRegistry shims, where is the recommended place on Vista to redirect these if I need all users to have read/write access?

Thanks,

Joe

# March 14, 2008 4:13 PM

Chris Jackson said:

Hi Joe,

I like to summarize the principles of LUA as: you get to hose your own session and documents, but you can't hose other people's stuff, or the box.

If you allow people to share write access to something, then you break out of that box and gain the ability to hose other people's stuff.

That being said, there are plenty of legitimate reasons to share between multiple users of the box, as long as you are sure that you need to do this. For developers, that's where we recommend writing to ProgramData. You could do the same by redirecting to %allappdata% and then sticking things there. Just like we tell developers, you take responsibility for setting up the ACLs as you need, to grant whoever you want write access to this directory.

Some people also just save the step of the redirect and just loosen the ACLs on the files in place, making sure that you don't just loosen them on a whole directory (like %programfiles%) but instead just on the specific file that you need.

Thanks,

Chris

# March 15, 2008 12:39 AM

Chris Jackson's Semantic Consonance said:

A while back, I write about the Correct File Paths shim . Since that time, I've heard from a number of

# April 5, 2008 9:44 AM

Mike said:

What is the purpose of the Module information panel?  Does it need to be filled out in order to make work?

# April 24, 2008 3:41 PM

Chris Jackson said:

Hi Mike,

If you want to make sure that you specifically include a module (dll) that is loaded into the process with this shim, regardless of whether it is statically or dynamically loaded, then you can include that module in the module list.

The module I most commonly find myself typing here, when I need to use it, is msvbvm60.dll - which you need for most every VB6 application you are shimming.

HTH!

Thanks,

Chris

# April 28, 2008 10:18 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Page view tracker