Windows Resource Protection (WRP) and ActiveX Control Installation on Windows Vista

I came across this problem today with a customer – Windows Resource Protection preventing ActiveX control installation on Windows Vista.

First, some background. Windows Resource Protection is the feature we put in place to help keep Windows in a known state. For example, if we make a change to user32.dll, we may also need to make a change to shell32.dll to accommodate this change, so the update will contain both files. If an application then comes along and writes an older version of shell32.dll, it may no longer work with the newer version of user32.dll. The operating system is no longer in a known and tested state.

Of course, a lot of applications try to drop them anyway, and for application compatibility reasons we don’t want to just break them. So, we had conflicting goals. On XP, we would address this with System File Protection (SFP). Essentially, we would watch these files, and if you changed them, we would go ahead and let you do that, but then we’d come along a few seconds later and replace them with the original version. The application doesn’t fail, but Windows still returns to a known and tested state. It seemed like a good solution at the time. However, there are a couple of issues with this.

First, since we are copying the original files back, people figured out that the files had to come from somewhere, and they figured out where that somewhere was. They would then copy a file to that somewhere first, then copy the Windows file in its location, and when we triggered that it was changed we would copy it over … from the location you just put your stuff in! So you could get around it.

Second, the amount of time it would take to replace files might be too long. I had one game application that had 4 CDs for the install. About 1 CD worth of content was most every file from Windows. When they build the installer, apparently they weren’t sure that Windows would be there. Fair enough, we would notice that the installer did that, and then copy the original files back, and no harm done. However, at uninstall, it removed all of these Windows files, because it thought it had dropped them. Then, before the few seconds had passed, it would prompt for a reboot. If you immediately say “yes”, then it reboots – without those Windows files. Which makes it really hard to boot, because critical files are gone. I had to do a repair install of Windows. At 7pm. On a Sunday. With a flight the next morning. Not my best night.

Clearly, there was room for improvement. So, in Windows Vista, we just don’t let you write to Windows operating system files at all. They are ACL’d to only allow the TrustedInstaller ACE to write to them, and this is handled by the TrustedInstaller service, which Windows Update calls into. But we knew that apps will still break, and compatibility is hugely important, so we took another compatibility approach: we just lie. With the WRPMitigation shim, you can try to write to a protected file, and we’ll tell you that you did. We won’t actually let you, but we’ll let you think you did. It turns out that that’s enough just about all of the time.

Now, you can apply that shim manually, or we’ll apply it for you if we detect that you are a setup using the UAC setup-detection heuristics. We also apply the shim to regsvr32.exe.

Now that we have that out of the way, we were investigating an issue where an ActiveX control wouldn’t install. We would navigate to a page, it would prompt for control installation, we would approve it, but then we’d just see the placeholder. It never installed. What was going on?

So, we opened the source view and searched for the object tag. We then pointed our browser to the cab file it was looking for, so it would download and we could save it to the desktop. We then extracted the CAB, and took a look. Here’s the ini file that we found in the cab (file names elided to protect the guilty):

; Sample INF file for clientautomation.dll
; version signature (same for both NT and Win95) do not remove

<the application’s code>.dll=<the application’s code>.dll

; needed DLL
[<the application’s code>.dll]
clsid={<the applicaton’s GUID>}


;end of INF file

The DestDir entry for msscript.ocx is interesting – it wants to drop the file in the system directory. We took a look to see if we could find it, and indeed msscript.ocx is already in the system32 directory, and it happens to be a WRP protected file. So it can’t drop it! (What they were actually trying to drop was the Windows 2000 version of this file.) And, since IE doesn’t have WRPMitigation applied, the installer never succeeded.

So, we just went ahead and created a new CAB file to test out. We removed msscript.ocx, and modified the ini file to remove the references to msscript, and gave it a go – the ActiveX control worked just fine, and functionality was restored.

Another compatibility bug closed.

Comments (20)

  1. Good Point says:

    I had a question about files protected by WRP.

    In experimenting, if I modify the Administrator’s ACE to allow for delete (for example) an Administrator still can’t delete the file (fails with error 5, Access Denied).

    But if I change ownership on the file to Administrator, then the delete will be allowed.  I have found the same to be true for directories that are protected from creating new files.

    Is something else at work here?  (It seems for ‘normal’ files/directories modifying the DACL is enough.)

  2. cjacks says:

    Good Point -

    While you can get around WRP if you fight hard enough with taking ownership, doing so is generally a really bad idea. I am not sure what you are trying to achieve.


  3. Good Point says:

    I should have been clear, I wasn’t trying to achieve anything by deleting/modifying the protected file.  I can’t remember how it came up, but it was something I saw and I couldn’t figure out why a DACL that says an account should be able to so something was being denied.

    In searching I did find a TechNet article that did say changing the owner of the file will allow the action, but gave no reason as to why.

    I’m not 100% certain, but I believe that it was a file that was owner by TrustedInstaller, but SfcIsFileProtected() said it wasn’t a protected file.

    It seems that there is another layer of protection (beyond the DACL on the file) and I was wondering what that is?

  4. cjacks says:

    Hi Good Point,

    An AccessCheck is all about the ACL, but they can be complicated at times.

    First, there is the notion of CREATOR OWNER, which can be confusing things when you take ownership. See

    Second, if you’re on Windows Vista, UAC can flip the Administrator ACE’s Deny Only bit, which confuses things. You can have it in your token, but you can’t use it to be granted permission to do something.

    Finally, you have mandatory integrity control, which adds the trust level of the process as something you can secure objects with.

    Can you run icacls on the object in question and let me know what the ACL is, and then run whoami /all with the same account? That could reveal what is going on.


  5. Anuradha says:

    I am trying to simply connect to my VPN and active X is not installing on my PC though I have allowed it. What is the use in having an expensive new OS if I have to master it just so that I would be able to use it?I am a simple user trying to work from home using my laptop (Vista)

  6. cjacks says:

    Hi Anuradha,

    What is the VPN software that you are trying to use? You may need to get a more current version – not all of it is compatible.


  7. Good Point says:

    Chris, thank you for your time on this.

    I chose a file that is on any Vista install (I think) and displays this behavior.  The file is C:Program FilesInternet Explorersqmapi.dll.  SfcIsFileProtected() returns TRUE indicating that it is a protected file.

    I take ownership of the file and change the permissions to allow full control, yet DeleteFile() fails with error 5, Access Denied.

    icacls shows:

    sqmapi.dll  No permissions are set. All users have full control.

    Successfully processed 1 files; Failed processing 0 files

    whoami /all shows:



    User Name           SID                                      

    =================== ==========================================

    ctdevadministrator S-1-5-21-583907252-630328440-725345543-500



    Group Name                           Type             SID                                        Attributes                                                    

    ==================================== ================ ========================================== ===============================================================

    Everyone                             Well-known group S-1-1-0                                    Mandatory group, Enabled by default, Enabled group            

    BUILTINUsers                        Alias            S-1-5-32-545                               Mandatory group, Enabled by default, Enabled group            

    BUILTINAdministrators               Alias            S-1-5-32-544                               Mandatory group, Enabled by default, Enabled group, Group owner

    NT AUTHORITYINTERACTIVE             Well-known group S-1-5-4                                    Mandatory group, Enabled by default, Enabled group            

    NT AUTHORITYAuthenticated Users     Well-known group S-1-5-11                                   Mandatory group, Enabled by default, Enabled group            

    NT AUTHORITYThis Organization       Well-known group S-1-5-15                                   Mandatory group, Enabled by default, Enabled group            

    LOCAL                                Well-known group S-1-2-0                                    Mandatory group, Enabled by default, Enabled group            

    CTDEVGroup Policy Creator Owners    Group            S-1-5-21-583907252-630328440-725345543-520 Mandatory group, Enabled by default, Enabled group            

    CTDEVDomain Admins                  Group            S-1-5-21-583907252-630328440-725345543-512 Mandatory group, Enabled by default, Enabled group            

    CTDEVSchema Admins                  Group            S-1-5-21-583907252-630328440-725345543-518 Mandatory group, Enabled by default, Enabled group            

    CTDEVEnterprise Admins              Group            S-1-5-21-583907252-630328440-725345543-519 Mandatory group, Enabled by default, Enabled group            

    Mandatory LabelHigh Mandatory Level Unknown SID type S-1-16-12288                               Mandatory group, Enabled by default, Enabled group            



    Privilege Name                  Description                               State  

    =============================== ========================================= ========

    SeIncreaseQuotaPrivilege        Adjust memory quotas for a process        Disabled

    SeSecurityPrivilege             Manage auditing and security log          Disabled

    SeTakeOwnershipPrivilege        Take ownership of files or other objects  Disabled

    SeLoadDriverPrivilege           Load and unload device drivers            Disabled

    SeSystemProfilePrivilege        Profile system performance                Disabled

    SeSystemtimePrivilege           Change the system time                    Disabled

    SeProfileSingleProcessPrivilege Profile single process                    Disabled

    SeIncreaseBasePriorityPrivilege Increase scheduling priority              Disabled

    SeCreatePagefilePrivilege       Create a pagefile                         Disabled

    SeBackupPrivilege               Back up files and directories             Disabled

    SeRestorePrivilege              Restore files and directories             Disabled

    SeShutdownPrivilege             Shut down the system                      Disabled

    SeDebugPrivilege                Debug programs                            Disabled

    SeSystemEnvironmentPrivilege    Modify firmware environment values        Disabled

    SeChangeNotifyPrivilege         Bypass traverse checking                  Enabled

    SeRemoteShutdownPrivilege       Force shutdown from a remote system       Disabled

    SeUndockPrivilege               Remove computer from docking station      Disabled

    SeManageVolumePrivilege         Perform volume maintenance tasks          Disabled

    SeImpersonatePrivilege          Impersonate a client after authentication Enabled

    SeCreateGlobalPrivilege         Create global objects                     Enabled

    SeIncreaseWorkingSetPrivilege   Increase a process working set            Disabled

    SeTimeZonePrivilege             Change the time zone                      Disabled

    SeCreateSymbolicLinkPrivilege   Create symbolic links                     Disabled

  8. cjacks says:

    Defeating WRP isn’t a supported scenario. I’d dump your resource ACL using icacls and make sure that everything remains as you set it. If that isn’t helpful, you can always set a bp on AccessCheck* in the debugger and find out what’s going on. But WRP is implemented with ACLs and not any additional mechanisms.

  9. Bud Mosc says:

    I tried several times to install the Vista SP1. Each time I encountered the same error code. I tried each resolution suggested to no avail. When I ran the System File checker tool, it indicated that there were corrupted files in WRP that could not be corrected. Any suggestions on how to fix this? Vista now freezes often as a result and I do not have a restore point early that resolved the issue.

  10. Dale Johnson says:


    My reason for wanting access to Trusted Installer owned files and folders is simple. After running Beta versions of Vista and now a temporary version of it for the past 25 days because I now have a new CPU chip and Motherboard, I need to install a new licensed version of Vista. The problem is that all of these older versions have eaten up all of my Hard Drive space so I don’t have room to do my install. These interim installs are entwined with data files and such so reformatting of drives or partitions is out of the question.

    So quite simply, I need to delete these interim installs that are cluttering up my drives.

    Without permission to do so, I can’t get rid of these files and folders that Vista believes are part of the operating system but are no longer so.

    So how do I get rid of this clutter if I can’t get ownership powers enough to be able to delete them entirely?

    While increased security is admirable it isn’t of very much use if you can never get rid of the older versions of the operating system. When I boot up I get a list of about 6-7 operating systems to choose from. Out of those, only two are actually valid and then only until I can install my final operating system, when I can transfer the info from them and then they will be also obsolete. Needless to say, 6-7 obsolete versions of an operating system take up an awful lot of disk space, particularly one as huge as Vista is.

  11. cjacks says:

    Hi Dale,

    If you are an admin, you can elevate and take ownership of any file that you’d like, including WRP files, and once you have ownership you can modify the ACLs. This isn’t a security feature – it’s a reliability feature. So, you can get the powers to delete them entirely.



  12. exold says:

    Chris: A fine line indeed between helping and helping Too Much. Having to draw that line is one of the disadvantages of having both Enormous Mystical Knowledge and Speaking Public Face, of course. I thought you did a very good job here!

  13. Every now and again, I bump up against a setup application (it’s almost always a setup application) that

  14. cquirke says:


    In these comments, you said "This isn’t a security feature – it’s a reliability feature".

    With that in mind, I ask: Is there feedback from ChkDsk and AutoChk to WRP, that would trigger file replacement if these processes had to "fix" a core OS code file?  There should be, and it should apply to both the "live" files and the source files that are used to perform the replacements.

  15. cjacks says:

    Hi cquirke,

    There are no more "replacement" files – you just have the one copy now. sfc.exe will still do this, but it needs the original media.



  16. tarterp says:

    Your note on WFP is incorrect. Users weren’t just able to write to the replacement directory, by default: %windir%system32dllcache.

    There is a thread inside winlogon started by SfcInitProt() from sfc_os.dll (sfc.dll for W2k). This thread watches for file integrity according to sfcfiles.dll. If a file is to be deleted from its original location it will be recovered from its backup. If the backup’s checksum fails integrity check then I friendly pop up will appear asking for your installation CD. There are many ways around this:

    – Write a program to use the hidden ordinal exports in sfc_os.dll. export 2 disables until reboot, export 5 disables for one minute on a specific file.

    – Create a hack of sfcfiles.dll and have it replaced on reboot.

    – Create a hack of sfc_os.dll to revert it to W2k functionality. Then set the HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionWinlogonSFCDisable key to 0xFFFFFF9D

  17. ccl1111 says:

    Thank you, thank you, thank you!

    I had a .dll that SFC could not repair & was almost at the point of formatting & reinstalling from scratch. Though I understand it’s not a best practice, I was able to take ownership of it and replace it with a good version – thanks to your explanation.

    Even if it only buys me a bit of time, you’ve prevented me from having to reinstall my machine for a while.

    Thank you!                                      

  18. Seabass says:

    Chris, I am having the exact same issue as Bud Mosc, and I can’t find help ANYWHERE! My computer came with Vista Home Premium loaded. For whatever reason, it cannot update. I have tried installing SP1, but I get an error code (80070490) that is not referenced ANYWHERE in the MSknowledgebase nor on the Internet in general. I ran a sfc /scannow & it says that corrupt WRP files were found, but when I try to view the CBS log as administrator, it just gives me another prompt. I can’t even defrag.

    I clicked the link you gave Bud above, but it’s defunct. Is there a new page we could reference?

    Any other ideas besides restoring? I REALLY want to avoid that.

    PS – How can there be an error code that’s not in the kb?

  19. cjacks says:

    Hi Seabass,

    80070490 translates to ERROR_NOT_FOUND (Element not found) – without knowing what threw the error, I’m not sure exactly what it indicates. But you can get free SP1 support from – I just verified that this link still works.