15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Most of this code is copied from various classes in 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// src/chrome/browser/policy. In particular, look at 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// configuration_policy_provider_delegate_win.{h,cc} 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// configuration_policy_loader_win.{h,cc} 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is a reduction of the functionality in those classes. 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/host/policy_hack/policy_watcher.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <userenv.h> 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 205e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string16.h" 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/object_watcher.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/registry.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// userenv.dll is required for RegisterGPNotification(). 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma comment(lib, "userenv.lib") 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::win::RegKey; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace policy_hack { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kRegistrySubKey[] = L"SOFTWARE\\Policies\\Google\\Chrome"; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PolicyWatcherWin : 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public PolicyWatcher, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public base::win::ObjectWatcher::Delegate { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit PolicyWatcherWin( 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> task_runner) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : PolicyWatcher(task_runner), 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_policy_changed_event_(false, false), 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) machine_policy_changed_event_(false, false), 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_policy_watcher_failed_(false), 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) machine_policy_watcher_failed_(false) { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~PolicyWatcherWin() { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void StartWatchingInternal() OVERRIDE { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(OnPolicyWatcherThread()); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!RegisterGPNotification(user_policy_changed_event_.handle(), false)) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLOG(WARNING) << "Failed to register user group policy notification"; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_policy_watcher_failed_ = true; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!RegisterGPNotification(machine_policy_changed_event_.handle(), true)) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLOG(WARNING) << "Failed to register machine group policy notification."; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) machine_policy_watcher_failed_ = true; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Reload(); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void StopWatchingInternal() OVERRIDE { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(OnPolicyWatcherThread()); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!UnregisterGPNotification(user_policy_changed_event_.handle())) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLOG(WARNING) << "Failed to unregister user group policy notification"; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!UnregisterGPNotification(machine_policy_changed_event_.handle())) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLOG(WARNING) << 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Failed to unregister machine group policy notification."; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_policy_watcher_.StopWatching(); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) machine_policy_watcher_.StopWatching(); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Updates the watchers and schedules the reload task if appropriate. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetupWatches() { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(OnPolicyWatcherThread()); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!user_policy_watcher_failed_ && 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !user_policy_watcher_.GetWatchedObject() && 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !user_policy_watcher_.StartWatching( 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_policy_changed_event_.handle(), this)) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Failed to start watch for user policy change event"; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_policy_watcher_failed_ = true; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!machine_policy_watcher_failed_ && 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !machine_policy_watcher_.GetWatchedObject() && 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !machine_policy_watcher_.StartWatching( 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) machine_policy_changed_event_.handle(), this)) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Failed to start watch for machine policy change event"; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) machine_policy_watcher_failed_ = true; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (user_policy_watcher_failed_ || machine_policy_watcher_failed_) { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleFallbackReloadTask(); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetRegistryPolicyString(const std::string& value_name, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* result) const { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // presubmit: allow wstring 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring value_name_wide = UTF8ToWide(value_name); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // presubmit: allow wstring 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring value; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RegKey policy_key(HKEY_LOCAL_MACHINE, kRegistrySubKey, KEY_READ); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (policy_key.ReadValue(value_name_wide.c_str(), &value) == 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR_SUCCESS) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = WideToUTF8(value); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (policy_key.Open(HKEY_CURRENT_USER, kRegistrySubKey, KEY_READ) == 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR_SUCCESS) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (policy_key.ReadValue(value_name_wide.c_str(), &value) == 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR_SUCCESS) { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = WideToUTF8(value); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetRegistryPolicyInteger(const std::string& value_name, 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32* result) const { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // presubmit: allow wstring 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring value_name_wide = UTF8ToWide(value_name); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD value = 0; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RegKey policy_key(HKEY_LOCAL_MACHINE, kRegistrySubKey, KEY_READ); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (policy_key.ReadValueDW(value_name_wide.c_str(), &value) == 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR_SUCCESS) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = value; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (policy_key.Open(HKEY_CURRENT_USER, kRegistrySubKey, KEY_READ) == 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR_SUCCESS) { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (policy_key.ReadValueDW(value_name_wide.c_str(), &value) == 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR_SUCCESS) { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = value; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetRegistryPolicyBoolean(const std::string& value_name, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* result) const { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 local_result = 0; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ret = GetRegistryPolicyInteger(value_name, &local_result); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = local_result != 0; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::DictionaryValue> Load() { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::DictionaryValue> policy(new base::DictionaryValue()); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (base::DictionaryValue::Iterator i(Defaults()); 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !i.IsAtEnd(); i.Advance()) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& policy_name = i.key(); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i.value().GetType() == base::DictionaryValue::TYPE_BOOLEAN) { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool bool_value; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetRegistryPolicyBoolean(policy_name, &bool_value)) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) policy->SetBoolean(policy_name, bool_value); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i.value().GetType() == base::DictionaryValue::TYPE_STRING) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string string_value; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetRegistryPolicyString(policy_name, &string_value)) { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) policy->SetString(policy_name, string_value); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return policy.Pass(); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Post a reload notification and update the watch machinery. 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Reload() { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(OnPolicyWatcherThread()); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetupWatches(); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DictionaryValue> new_policy(Load()); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdatePolicies(new_policy.get()); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ObjectWatcher::Delegate overrides: 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnObjectSignaled(HANDLE object) { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(OnPolicyWatcherThread()); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(object == user_policy_changed_event_.handle() || 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) object == machine_policy_changed_event_.handle()) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "unexpected object signaled policy reload, obj = " 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << std::showbase << std::hex << object; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Reload(); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WaitableEvent user_policy_changed_event_; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WaitableEvent machine_policy_changed_event_; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::ObjectWatcher user_policy_watcher_; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::ObjectWatcher machine_policy_watcher_; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool user_policy_watcher_failed_; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool machine_policy_watcher_failed_; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PolicyWatcher* PolicyWatcher::Create( 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> task_runner) { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new PolicyWatcherWin(task_runner); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace policy_hack 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace remoting 226