diff options
-rw-r--r-- | base/process_util.h | 12 | ||||
-rw-r--r-- | base/process_util_win.cc | 52 | ||||
-rw-r--r-- | base/win_util.cc | 2 | ||||
-rw-r--r-- | base/win_util.h | 6 | ||||
-rw-r--r-- | chrome/browser/web_applications/web_app.cc | 1 | ||||
-rw-r--r-- | chrome_frame/chrome_active_document.cc | 1 | ||||
-rw-r--r-- | chrome_frame/delete_chrome_history.cc | 20 |
7 files changed, 90 insertions, 4 deletions
diff --git a/base/process_util.h b/base/process_util.h index dbb0f13..dae3d46 100644 --- a/base/process_util.h +++ b/base/process_util.h @@ -145,6 +145,18 @@ void CloseSuperfluousFds(const InjectiveMultimap& saved_map); #endif #if defined(OS_WIN) + +enum IntegrityLevel { + INTEGRITY_UNKNOWN, + LOW_INTEGRITY, + MEDIUM_INTEGRITY, + HIGH_INTEGRITY, +}; +// Determine the integrity level of the specified process. Returns false +// if the system does not support integrity levels (pre-Vista) or in the case +// of an underlying system failure. +bool GetProcessIntegrityLevel(ProcessHandle process, IntegrityLevel *level); + // Runs the given application name with the given command line. Normally, the // first command line argument should be the path to the process, and don't // forget to quote it. diff --git a/base/process_util_win.cc b/base/process_util_win.cc index 428fe25..fb7bdb8 100644 --- a/base/process_util_win.cc +++ b/base/process_util_win.cc @@ -18,6 +18,7 @@ #include "base/logging.h" #include "base/scoped_handle_win.h" #include "base/scoped_ptr.h" +#include "base/win_util.h" // userenv.dll is required for CreateEnvironmentBlock(). #pragma comment(lib, "userenv.lib") @@ -139,6 +140,57 @@ ProcessId GetProcId(ProcessHandle process) { return 0; } +bool GetProcessIntegrityLevel(ProcessHandle process, IntegrityLevel *level) { + if (!level) + return false; + + if (win_util::GetWinVersion() < win_util::WINVERSION_VISTA) + return false; + + HANDLE process_token; + if (!OpenProcessToken(process, TOKEN_QUERY | TOKEN_QUERY_SOURCE, + &process_token)) + return false; + + ScopedHandle scoped_process_token(process_token); + + DWORD token_info_length = 0; + if (GetTokenInformation(process_token, TokenIntegrityLevel, NULL, 0, + &token_info_length) || + GetLastError() != ERROR_INSUFFICIENT_BUFFER) + return false; + + scoped_array<char> token_label_bytes(new char[token_info_length]); + if (!token_label_bytes.get()) + return false; + + TOKEN_MANDATORY_LABEL* token_label = + reinterpret_cast<TOKEN_MANDATORY_LABEL*>(token_label_bytes.get()); + if (!token_label) + return false; + + if (!GetTokenInformation(process_token, TokenIntegrityLevel, token_label, + token_info_length, &token_info_length)) + return false; + + DWORD integrity_level = *GetSidSubAuthority(token_label->Label.Sid, + (DWORD)(UCHAR)(*GetSidSubAuthorityCount(token_label->Label.Sid)-1)); + + if (integrity_level < SECURITY_MANDATORY_MEDIUM_RID) { + *level = LOW_INTEGRITY; + } else if (integrity_level >= SECURITY_MANDATORY_MEDIUM_RID && + integrity_level < SECURITY_MANDATORY_HIGH_RID) { + *level = MEDIUM_INTEGRITY; + } else if (integrity_level >= SECURITY_MANDATORY_HIGH_RID) { + *level = HIGH_INTEGRITY; + } else { + NOTREACHED(); + return false; + } + + return true; +} + bool LaunchApp(const std::wstring& cmdline, bool wait, bool start_hidden, ProcessHandle* process_handle) { STARTUPINFO startup_info = {0}; diff --git a/base/win_util.cc b/base/win_util.cc index 66dbbe0..4ff89a9 100644 --- a/base/win_util.cc +++ b/base/win_util.cc @@ -4,8 +4,10 @@ #include "base/win_util.h" +#include <aclapi.h> #include <propvarutil.h> #include <sddl.h> +#include <shlobj.h> #include "base/logging.h" #include "base/registry.h" diff --git a/base/win_util.h b/base/win_util.h index 3a33732..f580004 100644 --- a/base/win_util.h +++ b/base/win_util.h @@ -7,13 +7,15 @@ #pragma once #include <windows.h> -#include <aclapi.h> -#include <shlobj.h> #include <string> #include "base/keyboard_codes.h" +struct IPropertyStore; +struct _tagpropertykey; +typedef _tagpropertykey PROPERTYKEY; + namespace win_util { // NOTE: Keep these in order so callers can do things like diff --git a/chrome/browser/web_applications/web_app.cc b/chrome/browser/web_applications/web_app.cc index c79527c..ae4bc68 100644 --- a/chrome/browser/web_applications/web_app.cc +++ b/chrome/browser/web_applications/web_app.cc @@ -6,6 +6,7 @@ #if defined(OS_WIN) #include <shellapi.h> +#include <shlobj.h> #endif // defined(OS_WIN) #include <algorithm> diff --git a/chrome_frame/chrome_active_document.cc b/chrome_frame/chrome_active_document.cc index 1c967f0..a4833b2 100644 --- a/chrome_frame/chrome_active_document.cc +++ b/chrome_frame/chrome_active_document.cc @@ -11,6 +11,7 @@ #include <mshtmcid.h> #include <shdeprecated.h> #include <shlguid.h> +#include <shlobj.h> #include <shobjidl.h> #include <tlogstg.h> #include <urlmon.h> diff --git a/chrome_frame/delete_chrome_history.cc b/chrome_frame/delete_chrome_history.cc index 1b4b7b9..19eccf3 100644 --- a/chrome_frame/delete_chrome_history.cc +++ b/chrome_frame/delete_chrome_history.cc @@ -5,9 +5,10 @@ // Implementation of DeleteChromeHistory #include "chrome_frame/delete_chrome_history.h" -#include "chrome_frame/chrome_frame_activex.h" #include "chrome/browser/browsing_data_remover.h" -#include "utils.h" + +#include "chrome_frame/chrome_frame_activex.h" +#include "chrome_frame/utils.h" // Below other header to avoid symbol pollution. #define INITGUID @@ -57,6 +58,21 @@ STDMETHODIMP DeleteChromeHistory::DeleteBrowsingHistory(DWORD flags) { // in lieu of sending an IPC when it seems appropriate. Since we assume this // happens in one-off fashion, don't attempt to pack REMOVE_* arguments. // Instead, have the browser process clobber all history. + // + // IE8 on Vista launches us twice when the user asks to delete browsing data - + // once in low integrity and once in medium integrity. The low integrity + // instance will fail to connect to the automation server and restart it in an + // effort to connect. Thus, we detect if we are in that circumstance and exit + // silently. + base::IntegrityLevel integrity_level; + if (win_util::GetWinVersion() >= win_util::WINVERSION_VISTA && + !base::GetProcessIntegrityLevel(base::GetCurrentProcessHandle(), + &integrity_level)) { + return E_UNEXPECTED; + } + if (integrity_level == base::LOW_INTEGRITY) { + return S_OK; + } if (!InitializeAutomation(GetHostProcessName(false), L"", false, false, GURL(), GURL())) { return E_UNEXPECTED; |