Home | History | Annotate | Download | only in port_monitor
      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