1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "cloud_print/virtual_driver/win/port_monitor/port_monitor.h" 6 7 #include <lmcons.h> 8 #include <shellapi.h> 9 #include <shlobj.h> 10 #include <strsafe.h> 11 #include <userenv.h> 12 #include <windows.h> 13 #include <winspool.h> 14 15 #include "base/at_exit.h" 16 #include "base/command_line.h" 17 #include "base/file_util.h" 18 #include "base/logging.h" 19 #include "base/path_service.h" 20 #include "base/process/process.h" 21 #include "base/strings/string16.h" 22 #include "base/win/registry.h" 23 #include "base/win/scoped_handle.h" 24 #include "base/win/windows_version.h" 25 #include "chrome/common/chrome_switches.h" 26 #include "cloud_print/common/win/cloud_print_utils.h" 27 #include "cloud_print/virtual_driver/win/port_monitor/spooler_win.h" 28 #include "cloud_print/virtual_driver/win/virtual_driver_consts.h" 29 #include "cloud_print/virtual_driver/win/virtual_driver_helpers.h" 30 31 namespace cloud_print { 32 33 const wchar_t kChromeExePath[] = L"google\\chrome\\application\\chrome.exe"; 34 const wchar_t kChromeExePathRegValue[] = L"PathToChromeExe"; 35 const wchar_t kChromeProfilePathRegValue[] = L"PathToChromeProfile"; 36 const bool kIsUnittest = false; 37 38 namespace { 39 40 // Returns true if Xps support is installed. 41 bool XpsIsInstalled() { 42 base::FilePath xps_path; 43 if (!SUCCEEDED(GetPrinterDriverDir(&xps_path))) { 44 return false; 45 } 46 xps_path = xps_path.Append(L"mxdwdrv.dll"); 47 if (!base::PathExists(xps_path)) { 48 return false; 49 } 50 return true; 51 } 52 53 // Returns true if registration/unregistration can be attempted. 54 bool CanRegister() { 55 if (!XpsIsInstalled()) { 56 return false; 57 } 58 if (base::win::GetVersion() >= base::win::VERSION_VISTA) { 59 base::IntegrityLevel level = base::INTEGRITY_UNKNOWN; 60 if (!GetProcessIntegrityLevel(base::GetCurrentProcessHandle(), &level)) { 61 return false; 62 } 63 if (level != base::HIGH_INTEGRITY) { 64 return false; 65 } 66 } 67 return true; 68 } 69 70 } // namespace 71 72 73 } // namespace cloud_print 74 75 HRESULT WINAPI DllRegisterServer(void) { 76 base::AtExitManager at_exit_manager; 77 if (!cloud_print::CanRegister()) { 78 return E_ACCESSDENIED; 79 } 80 MONITOR_INFO_2 monitor_info = {0}; 81 // YUCK!!! I can either copy the constant, const_cast, or define my own 82 // MONITOR_INFO_2 that will take const strings. 83 base::FilePath dll_path(cloud_print::GetPortMonitorDllName()); 84 monitor_info.pDLLName = const_cast<LPWSTR>(dll_path.value().c_str()); 85 monitor_info.pName = const_cast<LPWSTR>(dll_path.value().c_str()); 86 if (AddMonitor(NULL, 2, reinterpret_cast<BYTE*>(&monitor_info))) { 87 return S_OK; 88 } 89 return cloud_print::GetLastHResult(); 90 } 91 92 HRESULT WINAPI DllUnregisterServer(void) { 93 base::AtExitManager at_exit_manager; 94 if (!cloud_print::CanRegister()) { 95 return E_ACCESSDENIED; 96 } 97 base::FilePath dll_path(cloud_print::GetPortMonitorDllName()); 98 if (DeleteMonitor(NULL, 99 NULL, 100 const_cast<LPWSTR>(dll_path.value().c_str()))) { 101 return S_OK; 102 } 103 return cloud_print::GetLastHResult(); 104 } 105