Application Hive limitations for HKCU

%3CLINGO-SUB%20id%3D%22lingo-sub-2923846%22%20slang%3D%22en-US%22%3EApplication%20Hive%20limitations%20for%20HKCU%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2923846%22%20slang%3D%22en-US%22%3E%3CP%3EWhen%20we%20have%20an%20MSIX%20package%20that%20contains%20a%20Registry.dat%20hive%20with%20REGISTRY%5CUSER%20keys%20and%20name%2Fvalue%20pairs%2C%20the%20behavior%20of%20the%20runtime%20is%2C%20in%20in%20mind%2C%20incorrect%20and%20leads%20to%20many%20issues%20with%20bringing%20traditional%20code%20into%20MSIX.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EThe%20problem%20stems%20from%20situations%20where%20the%20dat%20file%20contains%20some%20initial%20keys%20and%20the%20application%20wants%20to%20add%20subkeys%2C%20and%20sub-subkeys%20under%20some%20of%20those%20entries%20at%20runtime.%26nbsp%3B%20The%20traditional%20app%20usually%20assumes%20that%20attempts%20to%20open%20or%20create%20these%20subkeys%20and%20sub-subkeys%20will%20return%20%22%22PATH_NOT_FOUND%22%2FFILE_NOT_FOUND%22%2F%22ERROR_SUCCESS%22%20return%20codes.%26nbsp%3B%20Given%20a%20native%20app%20and%20an%20attempt%20to%20open%2Fcreate%20a%20HKCU%20key%2C%20that%20is%20the%20only%20response%20you'd%20see%2C%20so%20other%20returns%20are%20not%20expected%20and%20the%20developer%20rarely%20looks%20for%20them.%26nbsp%3B%20Should%20the%20call%20fail%20for%20other%20purposes%20the%20code%20is%20likely%20to%20crash%2C%20or%20at%20best%20the%20developer%20will%20put%20up%20a%20dialog%20to%20say%20the%20installation%20needs%20to%20be%20repaired%2Freplaced.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EA%20specific%20example%20can%20be%20found%20in%20an%20application%20like%20%22Fiddler%22%2C%20when%20repackaged.%26nbsp%3B%20The%20description%20that%20follows%20is%20a%20generic%20one%20to%20explain%20where%20things%20go%20wrong.%26nbsp%3B%20The%20packaged%20app%20crashes%20when%20shut%20down%20and%20there%20is%20nothing%20that%20the%20PSF%20can%20do%20about%20it.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EExample%20Registry.dat%20file%20in%20package%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%20%26nbsp%3B-------------------------------------------------------------------------------------%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%20%26nbsp%3B%5CRESIGITRY%5CUSER%5CSOFTWARE%5CVendor%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%5CRESIGITRY%5CUSER%5CSOFTWARE%5CVendor%5CApp%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%5CRESIGITRY%5CUSER%5CSOFTWARE%5CVendor%5CApp%5CSk1%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20Name%3Dn1%20value%3D%22v1%22%3CBR%20%2F%3E%26nbsp%3B%20%26nbsp%3B%5CRESIGITRY%5CUSER%5CSOFTWARE%5CVendor%5CApp%5CSK1%5CSK1SKA%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%20%26nbsp%3B--------------------------------------------------------------------------------------%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EThe%20app%20calls%20OpenKeyEx%20HKEY_CURRENT_USER%5CSOFTWARE%5CVendor%5CApp%20with%20%22MAXIMUM_ALLOWED%22%20permission%20request%20(Success)%3CBR%20%2F%3EThe%20app%20calls%20OpenKeyEx%20HKEY_CURRENT_USER%5CSOFTWARE%5CVendor%5CApp%5CSK1%20with%20%22MAXIMUM_ALLOWED%22%20permission%20request%20(Success)%3CBR%20%2F%3EThe%20app%20calls%20OpenKeyEx%20HKEY_CURRENT_USER%5CSOFTWARE%5CVendor%5CApp%5CSK2%20with%20%22MAXIMUM_ALLOWED%22%20permission%20request%20(ACCESS_DENIED)%20%26lt%3B--%20This%20should%20be%20FILE_NOT_FOUND%3CBR%20%2F%3EThe%20app%20calls%20CreateKeyEx%20HKEY_CURRENT_USER%5CSOFTWARE%5CVendor%5CApp%5CSK2%20with%20%22MAXIMUM_ALLOWED%22%20permission%20request%20(ACCESS_DENIED)%20%26lt%3B--%20This%20should%20be%20SUCCESS%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EIn%20the%20traditional%20app%20models%2C%20such%20a%20call%20would%20never%20generate%20an%20ACCESS_DENIED%20return%20code%20to%20an%20attempt%20to%20open%2Fcreate%20a%20key%20under%20HKCU%20and%20a%20lot%20of%20existing%20vendor%20code%20does%20not%20check%20for%20that%20error%20(resulting%20in%20using%20a%20null%20handle)%20or%20assumes%20that%20the%20installation%20is%20botched%20and%20asks%20the%20user%20to%20reinstall.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EAdding%20a%20SK2%20key%20to%20the%20Registry.dat%20file%20solves%20this%20issue%2C%20however%20that%20means%20you%20need%20to%20understand%20%3CU%3Eevery%20key%3C%2FU%3E%20that%20the%20app%20might%20expect%20to%20look%20for%20in%20order%20to%20create%20a%20good%20package.%26nbsp%3B%20This%20is%20too%20high%20of%20a%20hurdle%20when%20you%20don't%20have%20access%20to%20the%20vendor%20source%20code%2C%20and%20probably%20even%20for%20the%20vendor%20that%20does%20%3B)%3C%2Fimg%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EI%20would%20suggest%20that%20the%20runtime%20processing%20for%20registry%20requests%20that%20fall%20under%20the%20area%20of%20influence%20of%20the%20Registry.dat%20overlay%20should%20allow%20such%20operations%20to%20proceed%2C%20looking%20into%20the%20redirected%20non-persistent%20overlay%20of%20the%20package%20in%20the%20user's%20profile%20and%20allowing%20key%20enumeration%20and%20creation%20without%20error.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2959191%22%20slang%3D%22en-US%22%3ERe%3A%20Application%20Hive%20limitations%20for%20HKCU%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2959191%22%20slang%3D%22en-US%22%3ESo%20according%20to%20your%20post%20you%20are%20adding%20user%20keys%20(HKCU)%20to%20Registry.dat%2C%20but%20Registry.dat%20can%20only%20contain%20machine%20keys%20(HKLM).%3CBR%20%2F%3E%20%3CBR%20%2F%3EUser%20keys%20should%20be%20added%20to%20User.dat%2C%20not%20Registry.dat.%20Can%20you%20please%20try%20that%20and%20see%20if%20that%20works%3F%3CBR%20%2F%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2971963%22%20slang%3D%22en-US%22%3ERe%3A%20Application%20Hive%20limitations%20for%20HKCU%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2971963%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F144649%22%20target%3D%22_blank%22%3E%40Dian%20Hartono%3C%2FA%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EWell%20let%20me%20clarify.%20I%20did%20intend%20to%20say%20the%20Registry.dat%20as%20that's%20one%20of%20the%20places%20they%20are%20stored%20when%20a%20package%20is%20captured%20by%20the%20Microsoft%20MSIX%20packaging%20tool%20(see%20attached%20image).%20Another%20copy%20of%20the%20user%20portion%20contained%20in%20that%20file%20is%20also%20stored%20in%20the%20User.dat%20file%2C%20so%20whichever%20source%20the%20installer%20uses%20I%20mean%20that%20one.%3C%2FP%3E%0A%3CP%3EBy%20the%20way%2C%20it%20would%20be%20nice%20to%20know%20if%20one%20of%20those%20is%20a%20mistake%20by%20the%20packaging%20tool%20and%20not%20needed%20in%20the%20package.%20My%20tooling%2C%20for%20example%2C%20assumes%20that%20since%20the%20MMPT%20is%20putting%20the%20user%20registry%20keys%20in%20both%20dat%20file%2C%20I%20must%20make%20duplicate%20changes%20in%20both%20of%20those%20files%20when%20editing%20the%20package.%3C%2FP%3E%3C%2FLINGO-BODY%3E
MVP

When we have an MSIX package that contains a Registry.dat hive with REGISTRY\USER keys and name/value pairs, the behavior of the runtime is, in in mind, incorrect and leads to many issues with bringing traditional code into MSIX.

 

The problem stems from situations where the dat file contains some initial keys and the application wants to add subkeys, and sub-subkeys under some of those entries at runtime.  The traditional app usually assumes that attempts to open or create these subkeys and sub-subkeys will return ""PATH_NOT_FOUND"/FILE_NOT_FOUND"/"ERROR_SUCCESS" return codes.  Given a native app and an attempt to open/create a HKCU key, that is the only response you'd see, so other returns are not expected and the developer rarely looks for them.  Should the call fail for other purposes the code is likely to crash, or at best the developer will put up a dialog to say the installation needs to be repaired/replaced.

 

A specific example can be found in an application like "Fiddler", when repackaged.  The description that follows is a generic one to explain where things go wrong.  The packaged app crashes when shut down and there is nothing that the PSF can do about it.

 

Example Registry.dat file in package:

   -------------------------------------------------------------------------------------

   \RESIGITRY\USER\SOFTWARE\Vendor
   \RESIGITRY\USER\SOFTWARE\Vendor\App
   \RESIGITRY\USER\SOFTWARE\Vendor\App\Sk1
                                                                                  Name=n1 value="v1"
   \RESIGITRY\USER\SOFTWARE\Vendor\App\SK1\SK1SKA

   --------------------------------------------------------------------------------------

 

The app calls OpenKeyEx HKEY_CURRENT_USER\SOFTWARE\Vendor\App with "MAXIMUM_ALLOWED" permission request (Success)
The app calls OpenKeyEx HKEY_CURRENT_USER\SOFTWARE\Vendor\App\SK1 with "MAXIMUM_ALLOWED" permission request (Success)
The app calls OpenKeyEx HKEY_CURRENT_USER\SOFTWARE\Vendor\App\SK2 with "MAXIMUM_ALLOWED" permission request (ACCESS_DENIED) <-- This should be FILE_NOT_FOUND
The app calls CreateKeyEx HKEY_CURRENT_USER\SOFTWARE\Vendor\App\SK2 with "MAXIMUM_ALLOWED" permission request (ACCESS_DENIED) <-- This should be SUCCESS

 

In the traditional app models, such a call would never generate an ACCESS_DENIED return code to an attempt to open/create a key under HKCU and a lot of existing vendor code does not check for that error (resulting in using a null handle) or assumes that the installation is botched and asks the user to reinstall.

 

Adding a SK2 key to the Registry.dat file solves this issue, however that means you need to understand every key that the app might expect to look for in order to create a good package.  This is too high of a hurdle when you don't have access to the vendor source code, and probably even for the vendor that does ;)

 

I would suggest that the runtime processing for registry requests that fall under the area of influence of the Registry.dat overlay should allow such operations to proceed, looking into the redirected non-persistent overlay of the package in the user's profile and allowing key enumeration and creation without error.

 

2 Replies
So according to your post you are adding user keys (HKCU) to Registry.dat, but Registry.dat can only contain machine keys (HKLM).

User keys should be added to User.dat, not Registry.dat. Can you please try that and see if that works?

@Dian Hartono 

Well let me clarify. I did intend to say the Registry.dat as that's one of the places they are stored when a package is captured by the Microsoft MSIX packaging tool (see attached image). Another copy of the user portion contained in that file is also stored in the User.dat file, so whichever source the installer uses I mean that one.

By the way, it would be nice to know if one of those is a mistake by the packaging tool and not needed in the package. My tooling, for example, assumes that since the MMPT is putting the user registry keys in both dat file, I must make duplicate changes in both of those files when editing the package.