summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/process_util.h12
-rw-r--r--base/process_util_win.cc52
-rw-r--r--base/win_util.cc2
-rw-r--r--base/win_util.h6
-rw-r--r--chrome/browser/web_applications/web_app.cc1
-rw-r--r--chrome_frame/chrome_active_document.cc1
-rw-r--r--chrome_frame/delete_chrome_history.cc20
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;