Introduction to the Protected Mode API
Protected Mode helps reduce the severity of threats to Windows Internet Explorer 7 and its extensions by eliminating the silent installation of malicious code through software vulnerabilities. Protected Mode accomplishes this goal using the integrity mechanisms of Windows Vista which restrict access to processes, files, and registry keys with higher integrity levels. The Protected Mode API enables software vendors to develop extensions and add-ons for Windows Internet Explorer that can interact with the file system and registry from a low integrity process, such as Protected Mode Internet Explorer.
This topic contains the following sections.
- Finding Low Integrity Write Locations
- Saving Files in Protected Mode
- Related topics
Finding Low Integrity Write Locations
Extensions written for Internet Explorer 7 should write files and settings to a low integrity location, such as the Temporary Internet Files folder, by default. Low integrity locations enable write access for processes with a low privilege level. Writing to a low integrity location helps protect the system against potentially malicious data from the Internet.
To determine if Internet Explorer is running in Protected Mode, call the IEIsProtectedModeProcess function. To find a low integrity file or registry location that an in-process Internet Explorer extension can write to, call the IEGetWriteableFolderPath function or the IEGetWriteableHKCU function.
The following example uses the Protected Mode API to detect the integrity level of Internet Explorer and choose a low integrity write location for a registry setting.
#include iepmapi.h
HRESULT WriteSetting(LPCTSTR pszKey, LPCTSTR pszValue, LPCTSTR pszData)
{
BOOL bIsProtected;
HRESULT hr = IEIsProtectedModeProcess(&bIsProtected);
if (SUCCEEDED(hr) && bIsProtected)
{
HKEY hKey;
hr = IEGetWriteableHKCU(&hKey);
if (SUCCEEDED(hr))
{
HKEY hMyKey;
DWORD dwDisposition;
LONG lRes = RegCreateKeyEx(
hKey, // Low integrity write location
pszKey, // Specified sub-key
0L, // Reserved
NULL, // Class
REG_OPTION_NON_VOLATILE,
KEY_SET_VALUE,
NULL, // Security Descriptor
&hMyKey, // NEW or EXISTING key
&dwDisposition);
if (ERROR_SUCCESS == lRes)
{
lRes = RegSetValueEx(hMyKey, pszValue, NULL, REG_SZ,
(CONST BYTE*)pszData, strlen(pszData) + 1));
hr = HRESULT_FROM_WIN32(lRes);
RegCloseKey(hMyKey);
}
else
hr = HRESULT_FROM_WIN32(lRes);
// Close the low integrity handle
RegCloseKey(hKey);
}
}
else
{
// IE not in protected mode
}
return hr;
}
Saving Files in Protected Mode
When Microsoft ActiveX controls and other extensions are running in Protected Mode, they cannot directly download files outside the Temporary Internet Files, History, Cookies, and Temp folders. File operations that attempt to write to other locations are intercepted and redirected to a "virtualized" location in a low integrity area. To save a file outside the virtualized location, extensions can use the following two Protected Mode API functions.
- IEShowSaveFileDialog—Call this function with a target location of the file that you want the user to save to. The user is prompted with the Save As dialog box, and the function returns the destination file path that the user specified.
- IESaveFile—Call this function with the handle returned from the previous operation and the temporary file path to the download location. The Protected Mode User Broker process copies the file from the temporary location to the target location. To free the associated memory without saving the file, call IECancelSaveFile.
The following example shows how to use the Protect Mode API to perform an elevated privilege file save operation. In this example, the data is written to a temporary location prior to the save operation, which copies the file in a user-mode operation to a higher privileged area. If the file has already been downloaded to the Internet cache, this step is not necessary.
#include iepmapi.h
// NOTE: Caller must free *ppszDest with CoTaskMemFree
HRESULT SaveFileData(
LPWSTR pszName, // Desired file name and path
BYTE* pbData, // Data for save
UINT cbBytes, // Count of bytes in pbData
LPWSTR* ppszDest) // OUT: final save location
{
LPWSTR pszTempPath;
HRESULT hr;
hr = IEGetWriteableFolderPath(
FOLDERID_InternetCache, // Temporary Internet Files
&pszTempPath);
if (S_OK == hr) // S_FALSE means no access to folder
{
// Create a temporary file.
TCHAR szTempName[MAX_PATH];
GetTempFileNameW(
pszTempPath, // Directory for temp files
_T("tmp"), // Temp file name prefix
0, // Create unique name
szTempName); // Buffer for name
HANDLE hTempFile;
hTempFile = CreateFile(
(LPTSTR)szTempName, // File name
GENERIC_READ | GENERIC_WRITE, // Open for read/write
0, // Do not share
NULL, // Default security
CREATE_ALWAYS, // Overwrite existing file
FILE_ATTRIBUTE_NORMAL, // Normal file
NULL); // No template
if (INVALID_HANDLE_VALUE != hTempFile)
{
DWORD dwBytesWritten;
// Save the file
WriteFile(hTempFile, pbData, cbBytes,
&dwBytesWritten, NULL);
ASSERT(dwBytesWritten == cbBytes);
CloseHandle(hTempFile);
// Show the SaveAs dialog
hr = SaveFileProtected(pszName,
(LPWSTR)szTempName, ppszDest);
DeleteFile((LPCTSTR)szTempName);
}
else
{
// Could not create temporary file
hr = HRESULT_FROM_WIN32(GetLastError());
}
// Free memory
CoTaskMemFree(pszTempPath);
}
return hr;
}
// RETURNS: S_OK, or S_FALSE if canceled.
// NOTE: Caller must free *ppszDest with CoTaskMemFree
HRESULT SaveFileProtected(
LPWSTR pszName, // Desired name and path
LPWSTR pszSource, // Current file location
LPWSTR *ppszDest) // OUT: path to saved file
{
LPCWSTR pszExt = L"Text Files|*.txt|All Files|*.*|";
LPCWSTR pszDefExt = L"txt";
HANDLE hState; // No need to call CloseHandle on this
if (ppszDest) *ppszDest = NULL;
HRESULT hr = IEShowSaveFileDialog(
g_hwnd, // Application window (global)
pszName, // Initial filename and path
NULL, // Use path from filename
pszExt, // Extension filter list
pszDefExt, // Default extension
1, // Filter index
OFN_ENABLESIZING | OFN_NOREADONLYRETURN | OFN_OVERWRITEPROMPT,
ppszDest, // Selected destination
&hState); // Used to complete the operation
if (S_OK == hr) // S_FALSE if user cancels the operation
{
hr = IESaveFile(hState, pszSource);
hState = NULL; // hState SHOULD NOT be used again; set to NULL
}
return hr;
}
Related topics
Understanding and Working in Protected Mode Internet Explorer