|  | // 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" | 
|  |  | 
|  | 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) { | 
|  | 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)) { | 
|  | 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_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 |