| // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "base/process/process_info.h" | |
| #include <windows.h> | |
| #include <memory> | |
| #include "base/logging.h" | |
| #include "base/memory/ptr_util.h" | |
| #include "base/time/time.h" | |
| #include "base/win/scoped_handle.h" | |
| #include "starboard/types.h" | |
| namespace base { | |
| namespace { | |
| HANDLE GetCurrentProcessToken() { | |
| HANDLE process_token; | |
| OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &process_token); | |
| DCHECK(process_token != NULL && process_token != INVALID_HANDLE_VALUE); | |
| return process_token; | |
| } | |
| } // namespace | |
| // static | |
| const Time CurrentProcessInfo::CreationTime() { | |
| FILETIME creation_time = {}; | |
| FILETIME ignore1 = {}; | |
| FILETIME ignore2 = {}; | |
| FILETIME ignore3 = {}; | |
| if (!::GetProcessTimes(::GetCurrentProcess(), &creation_time, &ignore1, | |
| &ignore2, &ignore3)) { | |
| return Time(); | |
| } | |
| return Time::FromFileTime(creation_time); | |
| } | |
| IntegrityLevel GetCurrentProcessIntegrityLevel() { | |
| HANDLE process_token(GetCurrentProcessToken()); | |
| DWORD token_info_length = 0; | |
| if (::GetTokenInformation(process_token, TokenIntegrityLevel, nullptr, 0, | |
| &token_info_length) || | |
| ::GetLastError() != ERROR_INSUFFICIENT_BUFFER) { | |
| NOTREACHED(); | |
| return INTEGRITY_UNKNOWN; | |
| } | |
| auto token_label_bytes = std::make_unique<char[]>(token_info_length); | |
| TOKEN_MANDATORY_LABEL* token_label = | |
| reinterpret_cast<TOKEN_MANDATORY_LABEL*>(token_label_bytes.get()); | |
| if (!::GetTokenInformation(process_token, TokenIntegrityLevel, token_label, | |
| token_info_length, &token_info_length)) { | |
| NOTREACHED(); | |
| return INTEGRITY_UNKNOWN; | |
| } | |
| DWORD integrity_level = *::GetSidSubAuthority( | |
| token_label->Label.Sid, | |
| static_cast<DWORD>(*::GetSidSubAuthorityCount(token_label->Label.Sid) - | |
| 1)); | |
| if (integrity_level < SECURITY_MANDATORY_LOW_RID) | |
| return UNTRUSTED_INTEGRITY; | |
| if (integrity_level < SECURITY_MANDATORY_MEDIUM_RID) | |
| return LOW_INTEGRITY; | |
| if (integrity_level >= SECURITY_MANDATORY_MEDIUM_RID && | |
| integrity_level < SECURITY_MANDATORY_HIGH_RID) { | |
| return MEDIUM_INTEGRITY; | |
| } | |
| if (integrity_level >= SECURITY_MANDATORY_HIGH_RID) | |
| return HIGH_INTEGRITY; | |
| NOTREACHED(); | |
| return INTEGRITY_UNKNOWN; | |
| } | |
| bool IsCurrentProcessElevated() { | |
| HANDLE process_token(GetCurrentProcessToken()); | |
| // Unlike TOKEN_ELEVATION_TYPE which returns TokenElevationTypeDefault when | |
| // UAC is turned off, TOKEN_ELEVATION returns whether the process is elevated. | |
| DWORD size; | |
| TOKEN_ELEVATION elevation; | |
| if (!GetTokenInformation(process_token, TokenElevation, &elevation, | |
| sizeof(elevation), &size)) { | |
| PLOG(ERROR) << "GetTokenInformation() failed"; | |
| return false; | |
| } | |
| return !!elevation.TokenIsElevated; | |
| } | |
| } // namespace base |