Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / rlz / win / lib / process_info.cc
1 // Copyright (c) 2012 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 // Information about the current process.
6
7 #include "rlz/win/lib/process_info.h"
8
9 #include <windows.h>
10
11 #include "base/memory/scoped_ptr.h"
12 #include "base/process/process_handle.h"
13 #include "base/strings/string16.h"
14 #include "base/win/scoped_handle.h"
15 #include "base/win/win_util.h"
16 #include "base/win/windows_version.h"
17 #include "rlz/lib/assert.h"
18
19 namespace {
20
21 HRESULT GetElevationType(PTOKEN_ELEVATION_TYPE elevation) {
22   if (!elevation)
23     return E_POINTER;
24
25   *elevation = TokenElevationTypeDefault;
26
27   if (base::win::GetVersion() < base::win::VERSION_VISTA)
28     return E_FAIL;
29
30   HANDLE process_token;
31   if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &process_token))
32     return HRESULT_FROM_WIN32(GetLastError());
33
34   base::win::ScopedHandle scoped_process_token(process_token);
35
36   DWORD size;
37   TOKEN_ELEVATION_TYPE elevation_type;
38   if (!GetTokenInformation(process_token, TokenElevationType, &elevation_type,
39                            sizeof(elevation_type), &size)) {
40     return HRESULT_FROM_WIN32(GetLastError());
41   }
42
43   *elevation = elevation_type;
44   return S_OK;
45 }
46
47 // based on http://msdn2.microsoft.com/en-us/library/aa376389.aspx
48 bool GetUserGroup(long* group) {
49   if (!group)
50     return false;
51
52   *group = 0;
53
54   // groups are listed in DECREASING order of importance
55   // (eg. If a user is a member of both the admin group and
56   // the power user group, it is more useful to list the user
57   // as an admin)
58   DWORD user_groups[] =  {DOMAIN_ALIAS_RID_ADMINS,
59                           DOMAIN_ALIAS_RID_POWER_USERS};
60   SID_IDENTIFIER_AUTHORITY nt_authority = SECURITY_NT_AUTHORITY;
61
62   for (int i = 0; i < arraysize(user_groups) && *group == 0; ++i) {
63     PSID current_group;
64     if (AllocateAndInitializeSid(&nt_authority, 2,
65                                  SECURITY_BUILTIN_DOMAIN_RID,
66                                  user_groups[i], 0, 0, 0, 0,
67                                  0, 0, &current_group)) {
68       BOOL current_level;
69       if (CheckTokenMembership(NULL, current_group, &current_level) &&
70           current_level) {
71         *group = user_groups[i];
72       }
73
74       FreeSid(current_group);
75     }
76   }
77
78   return group != 0;
79 }
80 }  //anonymous
81
82
83 namespace rlz_lib {
84
85 bool ProcessInfo::IsRunningAsSystem() {
86   static base::string16 user_sid;
87   if (user_sid.empty()) {
88     if (!base::win::GetUserSidString(&user_sid))
89       return false;
90   }
91   return (user_sid == L"S-1-5-18");
92 }
93
94 bool ProcessInfo::HasAdminRights() {
95   static bool evaluated = false;
96   static bool has_rights = false;
97
98   if (!evaluated) {
99     if (IsRunningAsSystem()) {
100       has_rights = true;
101     } else if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
102       TOKEN_ELEVATION_TYPE elevation;
103       base::IntegrityLevel level;
104
105       if (SUCCEEDED(GetElevationType(&elevation)) &&
106         base::GetProcessIntegrityLevel(base::GetCurrentProcessHandle(), &level))
107         has_rights = (elevation == TokenElevationTypeFull) ||
108                      (level == base::HIGH_INTEGRITY);
109     } else {
110       long group = 0;
111       if (GetUserGroup(&group))
112         has_rights = (group == DOMAIN_ALIAS_RID_ADMINS);
113     }
114   }
115
116   evaluated = true;
117   if (!has_rights)
118     ASSERT_STRING("ProcessInfo::HasAdminRights: Does not have admin rights.");
119
120   return has_rights;
121 }
122
123 };  // namespace