Home | History | Annotate | Download | only in process
      1 // Copyright (c) 2011 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 "base/process/process.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/memory/scoped_ptr.h"
      9 #include "base/win/windows_version.h"
     10 
     11 namespace base {
     12 
     13 void Process::Close() {
     14   if (!process_)
     15     return;
     16 
     17   // Don't call CloseHandle on a pseudo-handle.
     18   if (process_ != ::GetCurrentProcess())
     19     ::CloseHandle(process_);
     20 
     21   process_ = NULL;
     22 }
     23 
     24 void Process::Terminate(int result_code) {
     25   if (!process_)
     26     return;
     27 
     28   // Call NtTerminateProcess directly, without going through the import table,
     29   // which might have been hooked with a buggy replacement by third party
     30   // software. http://crbug.com/81449.
     31   HMODULE module = GetModuleHandle(L"ntdll.dll");
     32   typedef UINT (WINAPI *TerminateProcessPtr)(HANDLE handle, UINT code);
     33   TerminateProcessPtr terminate_process = reinterpret_cast<TerminateProcessPtr>(
     34       GetProcAddress(module, "NtTerminateProcess"));
     35   terminate_process(process_, result_code);
     36 }
     37 
     38 bool Process::IsProcessBackgrounded() const {
     39   if (!process_)
     40     return false;  // Failure case.
     41   DWORD priority = GetPriority();
     42   if (priority == 0)
     43     return false;  // Failure case.
     44   return ((priority == BELOW_NORMAL_PRIORITY_CLASS) ||
     45           (priority == IDLE_PRIORITY_CLASS));
     46 }
     47 
     48 bool Process::SetProcessBackgrounded(bool value) {
     49   if (!process_)
     50     return false;
     51   // Vista and above introduce a real background mode, which not only
     52   // sets the priority class on the threads but also on the IO generated
     53   // by it. Unfortunately it can only be set for the calling process.
     54   DWORD priority;
     55   if ((base::win::GetVersion() >= base::win::VERSION_VISTA) &&
     56       (process_ == ::GetCurrentProcess())) {
     57     priority = value ? PROCESS_MODE_BACKGROUND_BEGIN :
     58                        PROCESS_MODE_BACKGROUND_END;
     59   } else {
     60     priority = value ? BELOW_NORMAL_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS;
     61   }
     62 
     63   return (::SetPriorityClass(process_, priority) != 0);
     64 }
     65 
     66 ProcessId Process::pid() const {
     67   if (process_ == 0)
     68     return 0;
     69 
     70   return GetProcId(process_);
     71 }
     72 
     73 bool Process::is_current() const {
     74   return process_ == GetCurrentProcess();
     75 }
     76 
     77 // static
     78 Process Process::Current() {
     79   return Process(::GetCurrentProcess());
     80 }
     81 
     82 // static
     83 bool Process::CanBackgroundProcesses() {
     84   return true;
     85 }
     86 
     87 int Process::GetPriority() const {
     88   DCHECK(process_);
     89   return ::GetPriorityClass(process_);
     90 }
     91 
     92 }  // namespace base
     93