process_handle_win.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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