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 13namespace base { 14 15ProcessId GetCurrentProcId() { 16 return ::GetCurrentProcessId(); 17} 18 19ProcessHandle GetCurrentProcessHandle() { 20 return ::GetCurrentProcess(); 21} 22 23bool 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 39bool 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 54bool 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 66void CloseProcessHandle(ProcessHandle process) { 67 CloseHandle(process); 68} 69 70ProcessId GetProcId(ProcessHandle process) { 71 // This returns 0 if we have insufficient rights to query the process handle. 72 return GetProcessId(process); 73} 74 75bool 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