App-V 5: On that issue with Firefox where you cannot save preferences
If you have had a chance to sequence Firefox within App-V 5, you probably have encountered an issue where none of your preferences seem to be retained after exiting Firefox. Anything from loaded plug-ins, to tab preferences, to even the home page seem to always revert back to the default. This scenario is pretty easy to reproduce with a clean sequencer template and the default App-V sequencer exclusions. I used Firefox 18.0.2 installer to demonstrate this issue.
What is happening?
A user launches Firefox and proceeds to set all of their customizations (Home Page, Tab settings, etc.) with in the options menu (using the Firefox menu on the top left corner.)
After making these changes, exit out of Firefox (ensure the actual process terminates) and re-launch the application. All of those changes within the options menu are gone and you have been reverted back to the “first-launch” Firefox experience. A repeat process and it happens again. And again.
Troubleshooting what is actually happening
So for me, capturing two separate process monitor traces usually helps me sort this out. I started a Process Monitor trace to capture launching Firefox and saving a simple preference. Then I stopped the capture, saved it, and re-launched process monitor in order to capture the exit and re-launch for Firefox. I do this a lot and I will work from the middle. My initial guess was that the issue with saving the preferences actually happened on exit. Before I looked at the process monitor trace, I needed to know how these preferences are actually being stored (in the registry, within a file, etc.)
I found that the preferences are being saved in a file called prefs.js. Interesting. So I pulled up the first process monitor PML I captured and filtered for a path that contained prefs.js.
I found numerous CreateFile, QueryBasicInformation, and CloseFile operations on prefs.js as I was walking the trace through the normal VFS hook/walk functions (Integration symbolic link, “gold” package store, user-mode VFS, etc.) The CreateFile operations seemed to be normal when the desired access was READ, READ EA, SYNCHRONIZE and are successful. However, as I moved on down at the time I started changing settings and clicking OK, I saw that a CreateFile to the same Prefs.js file was failing with ACCESS DENIED. This time the desired access also included a GENERIC WRITE. Odd, these should normally be supported too.
Looking at the second trace where I captured closing and reopening Firefox, I found numerous instances of the failed writes to the prefs.js file. This prefs.js file was located beneath the user’s roaming %APPDATA% folder.
So again, what exactly is happening and why?
This requires a little bit of background. As you may have discovered, virtual assets in App-V (files, folders, registry keys, etc.) are not made invisible. They are not isolated in the sense they are in human readable formats – yet they are still state separated. When processes are hooked by App-V, they still see things virtually as they would in previous versions of App-V. It’s just the job of App-V behind the scenes to redirect everything to the appropriate location.
When you look at the file layouts of an AppV Package from within native explorer, you will see a read-only package beneath the %PROGRAMDATA%\AppV folder. If you look inside C:\Program Files, you will not see the Mozilla Firefox subdirectory. However, if you configure Explorer to launch inside an App-V bubble, you can view the VFS directly as the application sees it. All you have to do is first configure explorer to launch inside a separate process. In any explorer folder window pull up “Folder and Search Options,” select the View tab, and check the box to “Launch Folder Windows in a Separate Process.”
Then using the /APPVVE or /APPVPID extension launch a command prompt inside the virtual environment you would like to view. Then you can spawn an explorer process inside the App-V bubble.
In the figure below, the same folder is viewed with the top window coming from a native explorer process and the bottom from an explorer process running inside the virtual environment of Firefox.
Now using the same bottom window running in the virtual environment, I navigate over to that particular directory where the prefs.js file is.
I open and try to modify it. It prompts me to save it into a different location. The issue reproduces in this manner as well.
While running this process, we are viewing the true virtual package view in which we are combining and merging the view of two different namespaces. The base package or “GOLD Package” and the “User Store” (within the User Profile in %LOCALAPPDATA%.)
While this demonstration was long, I did it to demonstrate something implemented in the complex App-V 5 VFS is a component known as the VFS COW (Copy-on-Write) filter. The COW manages per-user data and package wide data that are stored per-user (in the case of applications that are targeted to the user.) Writes are redirected from the base package location to a COW location inside the user’s profile. This makes it possible for users to have different views of the same package and all changes are isolated between users. It also prevents users from tampering with App-V packages from outside the virtual environment yet it will STILL allow Anti-Virus applications to scan and REMOVE viruses from a virtual application should the rare case in which one would arrive via an App-V package. The mappings maintained inside the registry as shown here for FireFox (based on its GUID.)
One particular item that is also a feature of the COW are the COW Exclusions. Copy-on-Write functionality will not occur for certain file types. In the case of Firefox, it is not a problem with it writing to a COW location, but the file type in which it is trying to write. Files with extensions of EXE, CMD, MSI, COM, BAT, JS, VBS, DLL, and others cannot be modified because it will trigger a new instance of these files within the user’s profile and these extensions are normally associated with executable code or scripts.
How to resolve?
You have a few options here. You can simply exclude the folder containing the file from sequencing or you could take advantage of user state management solutions that work with App-V (UE-V, RES, AppSense, FlexProfiles, etc.)
Is this a Bug?
In the context of App-V, no. Is this a victim of the design of App-V 5? Before you rush to judgment, let me offer you this scenario and that might shed light on who you should be directing your potential outrage against. This particular issue boils down to one simple thing – Firefox saving preferences to a JS file. It is never a good idea for enterprises to have applications that are executable (or executable scripts) to reside in the context of the user’s profile. This is why most enterprises resent Google Chrome and other applications that install executable code into user profile locations. Historically, the AppData folders were also targets of AdWare and Spyware.
Comments
Anonymous
January 01, 2003
Certainly excluding the directories and using other user-state/preference management solutions to manage these settings is a viable option as well. Thank you very much for your contribution.Anonymous
October 24, 2013
Very interesting read, and I love the COW name.Anonymous
October 24, 2013
So are users unable to modify any of those file types listed anywhere within the virtual environment, or does it only apply to specific VFS folders?Anonymous
October 25, 2013
So are you implying that as a native app, Firefox should not use JS the way it does? There should be a PER PACKAGE, or specific file marking in a package, to allow the behavior.Anonymous
October 25, 2013
@DAN - VFS @ TIM - I have never liked the idea of saving preferences in a script. But that is my opinion. As to your second point, thank you very much for your information and insight.Anonymous
December 16, 2013
It took me a while to figure this out, so hopefully this will help the next guy. In the sequencer, before you start... Go to Tools | Options | Exclusion Items. Then add the following string (exactly) as type VFS: [{AppData}]Mozilla That will perform the exclusion correctly. Hope that helps. PS: If you want to MANAGE & Dictate Firefox settings, consider using PolicyPak to do it. We have a video demo here: http://www.policypak.com/integration/policypak-extends-group-policy-to-microsoft-app-v.html Start at the 4:40 mark.