Home | History | Annotate | Download | only in process
      1 // Copyright (c) 2013 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_handle.h"
      6 
      7 #include <windows.h>
      8 
      9 #include "base/memory/scoped_ptr.h"
     10 #include "base/win/scoped_handle.h"
     11 #include "base/win/windows_version.h"
     12 
     13 namespace base {
     14 
     15 ProcessId GetCurrentProcId() {
     16   return ::GetCurrentProcessId();
     17 }
     18 
     19 ProcessHandle GetCurrentProcessHandle() {
     20   return ::GetCurrentProcess();
     21 }
     22 
     23 bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle) {
     24   // We try to limit privileges granted to the handle. If you need this
     25   // for test code, consider using OpenPrivilegedProcessHandle instead of
     26   // adding more privileges here.
     27   ProcessHandle result = OpenProcess(PROCESS_TERMINATE |
     28                                      PROCESS_QUERY_INFORMATION |
     29                                      SYNCHRONIZE,
     30                                      FALSE, pid);
     31 
     32   if (result == NULL)
     33     return false;
     34 
     35   *handle = result;
     36   return true;
     37 }
     38 
     39 bool OpenPrivilegedProcessHandle(ProcessId pid, ProcessHandle* handle) {
     40   ProcessHandle result = OpenProcess(PROCESS_DUP_HANDLE |
     41                                      PROCESS_TERMINATE |
     42                                      PROCESS_QUERY_INFORMATION |
     43                                      PROCESS_VM_READ |
     44                                      SYNCHRONIZE,
     45                                      FALSE, pid);
     46 
     47   if (result == NULL)
     48     return false;
     49 
     50   *handle = result;
     51   return true;
     52 }
     53 
     54 bool OpenProcessHandleWithAccess(ProcessId pid,
     55                                  uint32 access_flags,
     56                                  ProcessHandle* handle) {
     57   ProcessHandle result = OpenProcess(access_flags, FALSE, pid);
     58 
     59   if (result == NULL)
     60     return false;
     61 
     62   *handle = result;
     63   return true;
     64 }
     65 
     66 void CloseProcessHandle(ProcessHandle process) {
     67   CloseHandle(process);
     68 }
     69 
     70 ProcessId GetProcId(ProcessHandle process) {
     71   // This returns 0 if we have insufficient rights to query the process handle.
     72   return GetProcessId(process);
     73 }
     74 
     75 bool GetProcessIntegrityLevel(ProcessHandle process, IntegrityLevel *level) {
     76   if (!level)
     77     return false;
     78 
     79   if (win::GetVersion() < base::win::VERSION_VISTA)
     80     return false;
     81 
     82   HANDLE process_token;
     83   if (!OpenProcessToken(process, TOKEN_QUERY | TOKEN_QUERY_SOURCE,
     84       &process_token))
     85     return false;
     86 
     87   win::ScopedHandle scoped_process_token(process_token);
     88 
     89   DWORD token_info_length = 0;
     90   if (GetTokenInformation(process_token, TokenIntegrityLevel, NULL, 0,
     91                           &token_info_length) ||
     92       GetLastError() != ERROR_INSUFFICIENT_BUFFER)
     93     return false;
     94 
     95   scoped_ptr<char[]> token_label_bytes(new char[token_info_length]);
     96   if (!token_label_bytes.get())
     97     return false;
     98 
     99   TOKEN_MANDATORY_LABEL* token_label =
    100       reinterpret_cast<TOKEN_MANDATORY_LABEL*>(token_label_bytes.get());
    101   if (!token_label)
    102     return false;
    103 
    104   if (!GetTokenInformation(process_token, TokenIntegrityLevel, token_label,
    105                            token_info_length, &token_info_length))
    106     return false;
    107 
    108   DWORD integrity_level = *GetSidSubAuthority(token_label->Label.Sid,
    109       (DWORD)(UCHAR)(*GetSidSubAuthorityCount(token_label->Label.Sid)-1));
    110 
    111   if (integrity_level < SECURITY_MANDATORY_MEDIUM_RID) {
    112     *level = LOW_INTEGRITY;
    113   } else if (integrity_level >= SECURITY_MANDATORY_MEDIUM_RID &&
    114       integrity_level < SECURITY_MANDATORY_HIGH_RID) {
    115     *level = MEDIUM_INTEGRITY;
    116   } else if (integrity_level >= SECURITY_MANDATORY_HIGH_RID) {
    117     *level = HIGH_INTEGRITY;
    118   } else {
    119     NOTREACHED();
    120     return false;
    121   }
    122 
    123   return true;
    124 }
    125 
    126 }  // namespace base
    127