Using the WRPMitigation Fix
Applies To: Windows 7, Windows Vista
This section includes information about using the WRPMitigation compatibility fix, including the usage and API-related information.
WRPMitigation
The WRPMitigation compatibility fix is designed to resolve issues with applications that are attempting to access or modify critical system files and registry keys that are protected by Windows® Resource Protection (WRP). WRP only allows the Windows Update Service, known in the access control list (ACL) as "Trusted Installer", to have full control of the file. This compatibility fix can be applied to the following files:
msiexec.exe
regasm.exe
regsvr32.exe
odbcconf.exe.
You cannot configure the compatibility fix to apply to any other applications that contain a User Account Control (UAC) manifest.
Investigating the Issue
The symptoms of a WRP-related issue frequently appear similar to the symptoms of UAC or Standard User issues. However, running the application with elevated privileges will not resolve the issue. Instead, the application will still receive Access Denied return codes.
Intercepted APIs
The following list provides detailed information about the APIs that are intercepted by the WRPMitigation compatibility fix.
API | Description | ||
---|---|---|---|
AccessCheck |
Calls the AccessCheck API. If the call fails, and the file is WRP-protected, then the compatibility fix will set the AccessStatus return value to TRUE. |
||
CopyFileA |
Calls the CopyFileA API. If the call fails (returning a value of ERROR_ACCESS_DENIED or ERROR_ALREADY_EXISTS), and the file is WRP-protected, then the compatibility fix will clear the last error and set the return value to TRUE. |
||
CopyFileW |
Calls the CopyFileW API. If the call fails (returning a value of ERROR_ACCESS_DENIED or ERROR_ALREADY_EXISTS), and the file is WRP-protected, then the compatibility fix will clear the last error and set the return value to TRUE. |
||
CopyFileExA |
Calls the CopyFileExA API. If the call fails (returning a value of ERROR_ACCESS_DENIED or ERROR_ALREADY_EXISTS), and the file is WRP-protected, then the compatibility fix will clear the last error and set the return value to TRUE. |
||
CopyFileExW |
Calls the CopyFileExW API. If the call fails (returning a value of ERROR_ACCESS_DENIED or ERROR_ALREADY_EXISTS), and the file is WRP-protected, then the compatibility fix will clear the last error and set the return value to TRUE. |
||
CreateFileA |
Calls the CreateFileA API. If the API does not return a valid handle, and the last error is ERROR_ACCESS_DENIED, then the compatibility fix will verify if the file is WRP-protected. If the file is not WRP-protected, the fix will create a file in the temp directory (named by using the GetTempFileName function call) and the fix will return the handle to this file.
|
||
CreateFileW |
Calls the CreateFileA API. If the API does not return a valid handle, and the last error is ERROR_ACCESS_DENIED, then the compatibility fix will verify if the file is WRP-protected. If the file is not WRP-protected, the fix will create a file in the temp directory (named by using the GetTempFileName function call) and then the fix will return the handle to this file. Note This compatibility fix will not intercept this API if the application is protected by Software Passport, a third-party copy-protection program.
|
||
DeleteFileA |
Calls the DeleteFileA API. If the call fails (returning a value of ERROR_ACCESS_DENIED or ERROR_ALREADY_EXISTS), and the file is WRP-protected, then the compatibility fix will clear the last error and set the return value to TRUE. |
||
DeleteFileW |
Calls the DeleteFileW API. If the call fails (returning a value of ERROR_ACCESS_DENIED or ERROR_ALREADY_EXISTS), and the file is WRP-protected, then the compatibility fix will clear the last error and set the return value to TRUE. |
||
MoveFileA |
Calls the MoveFileA API. If the call fails (returning a value of ERROR_ACCESS_DENIED or ERROR_ALREADY_EXISTS), and the file is WRP-protected, then the compatibility fix will clear the last error and set the return value to TRUE. |
||
MoveFileW |
Calls the MoveFileW API. If the call fails (returning a value of ERROR_ACCESS_DENIED or ERROR_ALREADY_EXISTS), and the file is WRP-protected, then the compatibility fix will clear the last error and set the return value to TRUE. |
||
MoveFileExA |
Calls the MoveFileExA API. If the call fails (returning a value of ERROR_ACCESS_DENIED or ERROR_ALREADY_EXISTS), and the file is WRP-protected, then the compatibility fix will clear the last error and set the return value to TRUE. |
||
MoveFileExW |
Calls the MoveFileExW API. If the call fails (returning a value of ERROR_ACCESS_DENIED or ERROR_ALREADY_EXISTS), and the file is WRP-protected, then the compatibility fix will clear the last error and set the return value to TRUE. |
||
OpenFile |
Calls the OpenFile API. If the call fails (returning error values of hFile = HFILE_ERROR and GetLastError() = ERROR_ACCESS_DENIED), and the file is WRP-protected, then the compatibility fix will retry the API, requesting only OF_READ permissions, and returning the result of this operation. |
||
_lopen |
Calls the _lopen API. If the call fails (returning error values of hFile = HFILE_ERROR and GetLastError() = ERROR_ACCESS_DENIED), and the file is WRP-protected, then the compatibility fix will retry the API, requesting only OF_READ permissions, and returning the result of this operation. |
||
_lcreat |
Calls the _lcreat API. If the call fails (returning error values of hFile = HFILE_ERROR and GetLastError() = ERROR_ACCESS_DENIED), and the file is WRP-protected, then the compatibility fix will retry the API, requesting only OF_READ permissions, and returning the result of this operation. |
||
_lwrite |
Calls the _lwrite API. If the call fails (returning an error of bytesWritten = 0xffffffff and GetLastError() = ERROR_ACCESS_DENIED), and the file is WRP-protected, then the compatibility fix will set the bytesWritten value to be equal to the uBytes argument that is supplied as if it succeeded. |
||
PrivCopyFileExW |
Calls the PrivCopyFileExW API. If the call fails (returning a value of ERROR_ACCESS_DENIED or ERROR_ALREADY_EXISTS), and the file is WRP-protected, then the compatibility fix will clear the last error and set the return value to TRUE. |
||
SetFileAttributesA |
Calls the SetFileAttributesA API. If the call fails (returning a value of ERROR_ACCESS_DENIED or ERROR_ALREADY_EXISTS), and the file is WRP-protected, then the compatibility fix will clear the last error and set the return value to TRUE. |
||
SetFileAttributesW |
Calls the SetFileAttributesW API. If the call fails (returning a value of ERROR_ACCESS_DENIED or ERROR_ALREADY_EXISTS), and the file is WRP-protected, then the compatibility fix will clear the last error and set the return value to TRUE. |
||
VerInstallFileA |
Calls the VerInstallFileA API. If the call fails (returning a result of dwResult = VIF_ACCESSVIOLATION or VIF_CANNOTDELETE), and the file is WRP-protected, then the compatibility fix will return a value of DWORD=0. |
||
VerInstallFileW |
Calls the VerInstallFileW API. If the call fails (returning a result of dwResult = VIF_ACCESSVIOLATION or VIF_CANNOTDELETE), and the file is WRP-protected, then the compatibility fix will return a value of DWORD=0. |
||
Calls the VerInstallFileW API. If the call fails (returning a result of dwResult = VIF_ACCESSVIOLATION or VIF_CANNOTDELETE), and the file is WRP-protected, then the compatibility fix will return a value of DWORD=0. |
|||
RegCreateKeyA |
Calls the RegCreateKeyA API. If the call fails, (returning an error result of ERROR_ACCESS_DENIED), then the compatibility fix will retry requesting the KEY_READ value. If the second call fails, (returning ERROR_FILE_NOT_FOUND), then the fix will check whether the parent key is WRP protected. If the parent key is protected, then the compatibility fix will set the status to NO_ERROR. If the second call succeeds, (returning NO_ERROR), then the fix will check to see if that key is WRP-protected. If the file is protected, then the fix will set the status to NO_ERROR. If the file is not protected, then the compatibility fix will close the read-only registry key and return a NULL value. |
||
RegCreateKeyW |
Calls the RegCreateKeyW API. If the call fails, (returning an error result of ERROR_ACCESS_DENIED), then the compatibility fix will retry requesting the KEY_READ value. If the second call fails, (returning ERROR_FILE_NOT_FOUND), then the fix will check whether the parent key is WRP protected. If the parent key is protected, then the compatibility fix will set the status to NO_ERROR. If the second call succeeds, (returning NO_ERROR), then the fix will check to see if that key is WRP-protected. If the file is protected, then the fix will set the status to NO_ERROR. If the file is not protected, then the compatibility fix will close the read-only registry key and return a NULL value. |
||
RegCreateKeyExA |
Calls the RegCreateKeyExA API. If the call fails, (returning an error result of ERROR_ACCESS_DENIED), then the compatibility fix will retry requesting the KEY_READ value. If the second call fails, (returning ERROR_FILE_NOT_FOUND), then the fix will check whether the parent key is WRP protected. If the parent key is protected, then the compatibility fix will set the status to NO_ERROR. If the second call succeeds, (returning NO_ERROR), then the fix will check to see if that key is WRP-protected. If the file is protected, then the fix will set the status to NO_ERROR. If the file is not protected, then the compatibility fix will close the read-only registry key and return a NULL value. |
||
RegCreateKeyExW |
Calls the RegCreateKeyExW API. If the call fails, (returning an error result of ERROR_ACCESS_DENIED), then the compatibility fix will retry requesting the KEY_READ value. If the second call fails, (returning ERROR_FILE_NOT_FOUND), then the fix will check whether the parent key is WRP protected. If the parent key is protected, then the compatibility fix will set the status to NO_ERROR. If the second call succeeds, (returning NO_ERROR), then the fix will check to see if that key is WRP-protected. If the file is protected, then the fix will set the status to NO_ERROR. If the file is not protected, then the compatibility fix will close the read-only registry key and return a NULL value. |
||
RegOpenKeyExA |
Calls the RegOpenKeyExA API. If the call fails, (returning an error result of ERROR_ACCESS_DENIED), then the compatibility fix will retry requesting the KEY_READ value. If the second call fails, (returning ERROR_FILE_NOT_FOUND), then the fix will check whether the parent key is WRP protected. If the parent key is protected, then the compatibility fix will set the status to NO_ERROR. If the second call succeeds, (returning NO_ERROR), then the fix will check to see if that key is WRP-protected. If the file is protected, then the fix will set the status to NO_ERROR. If the file is not protected, then the compatibility fix will close the read-only registry key and return a rNULL value. |
||
RegOpenKeyExW |
Calls the RegOpenKeyExW API. If the call fails, (returning an error result of ERROR_ACCESS_DENIED), then the compatibility fix will retry requesting the KEY_READ value. If the second call fails, (returning ERROR_FILE_NOT_FOUND), then the fix will check whether the parent key is WRP protected. If the parent key is protected, then the compatibility fix will set the status to NO_ERROR. If the second call succeeds, (returning NO_ERROR), then the fix will check to see if that key is WRP-protected. If the file is protected, then the fix will set the status to NO_ERROR. If the file is not protected, then the compatibility fix will close the read-only registry key and return a NULL value. |
||
RegSetValueA |
Calls the RegSetValueA API. If it fails (returning ERROR_ACCESS_DENIED) and the key is WRP protected, then the compatibility fix returns NO_ERROR. If the call fails (returning a value of ERROR_ACCESS_DENIED or ERROR_ALREADY_EXISTS), and the file is WRP-protected, then the compatibility fix will clear the last error and set the return value to TRUE. |
||
RegSetValueW |
Calls the RegSetValueW API. If the call fails (returning a value of ERROR_ACCESS_DENIED), and the file is WRP-protected, then the compatibility fix will return a value of NO_ERROR. |
||
RegSetValueExA |
Calls the RegSetValueExA API. If the call fails (returning a value of ERROR_ACCESS_DENIED), and the file is WRP-protected, then the compatibility fix will return a value of NO_ERROR. |
||
RegSetValueExW |
Calls the RegSetValueExW API. If the call fails (returning a value of ERROR_ACCESS_DENIED), and the file is WRP-protected, then the compatibility fix will return a value of NO_ERROR. |
||
RegDeleteValueA |
Calls the RegDeleteValueA API. If the call fails (returning a value of ERROR_ACCESS_DENIED), and the file is WRP-protected, then the compatibility fix will return a value of NO_ERROR. |
||
RegDeleteValueW |
Calls the RegDeleteValueW API. If the call fails (returning a value of ERROR_ACCESS_DENIED), and the file is WRP-protected, then the compatibility fix will return a value of NO_ERROR. |
||
SetFileSecurityA |
Calls the SetFileSecurityA API. If the call fails (returning a value of ERROR_ACCESS_DENIED or ERROR_ALREADY_EXISTS), and the file is WRP-protected, then the compatibility fix will clear the last error and set the return value to TRUE. |
||
SetFileSecurityW |
Calls the SetFileSecurityW API. If the call fails (returning a value of ERROR_ACCESS_DENIED or ERROR_ALREADY_EXISTS), and the file is WRP-protected, then the compatibility fix will clear the last error and set the return value to TRUE. |
Included and Excluded Modules
The following table provides details for the modules that are included and excluded by the WRPMitigation compatibility fix.
Module Name | Included or Excluded |
---|---|
* |
Included |
RSTRTMGR.DLL |
Excluded |
Fixing Your Code
The applications that most commonly require the WRPMitigation fix are setup applications that were not detected as installers by the setup-detection process. When creating an application installer and detecting dependencies, you should strive to differentiate between core operating-system files and application files. At runtime, you can determine if a file is WRP-protected using the SfcIsFileProtected API, and if a registry key is protected by using the SfcIsKeyProtected API.