• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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 <stdint.h>
6 #include <windows.h>
7 
8 #include "base/basictypes.h"
9 #include "sandbox/win/src/interception_internal.h"
10 #include "sandbox/win/src/internal_types.h"
11 #include "sandbox/win/src/sandbox_utils.h"
12 #include "sandbox/win/src/service_resolver.h"
13 
14 namespace {
15 enum Version {
16   VERSION_PRE_XP_SP2 = 0,  // Not supported.
17   VERSION_XP_SP2,
18   VERSION_SERVER_2003,  // Also includes XP Pro x64 and Server 2003 R2.
19   VERSION_VISTA,        // Also includes Windows Server 2008.
20   VERSION_WIN7,         // Also includes Windows Server 2008 R2.
21   VERSION_WIN8,         // Also includes Windows Server 2012.
22   VERSION_WIN8_1,
23   VERSION_WIN_LAST,  // Indicates error condition.
24 };
25 
26 // Whether a process is running under WOW64 (the wrapper that allows 32-bit
27 // processes to run on 64-bit versions of Windows).  This will return
28 // WOW64_DISABLED for both "32-bit Chrome on 32-bit Windows" and "64-bit
29 // Chrome on 64-bit Windows".  WOW64_UNKNOWN means "an error occurred", e.g.
30 // the process does not have sufficient access rights to determine this.
31 enum WOW64Status { WOW64_DISABLED, WOW64_ENABLED, WOW64_UNKNOWN, };
32 
GetWOW64StatusForCurrentProcess()33 WOW64Status GetWOW64StatusForCurrentProcess() {
34   typedef BOOL(WINAPI * IsWow64ProcessFunc)(HANDLE, PBOOL);
35   IsWow64ProcessFunc is_wow64_process = reinterpret_cast<IsWow64ProcessFunc>(
36       GetProcAddress(GetModuleHandle(L"kernel32.dll"), "IsWow64Process"));
37   if (!is_wow64_process)
38     return WOW64_DISABLED;
39   BOOL is_wow64 = FALSE;
40   if (!is_wow64_process(GetCurrentProcess(), &is_wow64))
41     return WOW64_UNKNOWN;
42   return is_wow64 ? WOW64_ENABLED : WOW64_DISABLED;
43 }
44 
45 class OSInfo {
46  public:
47   struct VersionNumber {
48     int major;
49     int minor;
50     int build;
51   };
52 
53   struct ServicePack {
54     int major;
55     int minor;
56   };
57 
OSInfo()58   OSInfo() {
59     OSVERSIONINFOEX version_info = {sizeof(version_info)};
60     GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&version_info));
61     version_number_.major = version_info.dwMajorVersion;
62     version_number_.minor = version_info.dwMinorVersion;
63     version_number_.build = version_info.dwBuildNumber;
64     if ((version_number_.major == 5) && (version_number_.minor > 0)) {
65       // Treat XP Pro x64, Home Server, and Server 2003 R2 as Server 2003.
66       version_ =
67           (version_number_.minor == 1) ? VERSION_XP_SP2 : VERSION_SERVER_2003;
68       if (version_ == VERSION_XP_SP2 && version_info.wServicePackMajor < 2)
69         version_ = VERSION_PRE_XP_SP2;
70     } else if (version_number_.major == 6) {
71       switch (version_number_.minor) {
72         case 0:
73           // Treat Windows Server 2008 the same as Windows Vista.
74           version_ = VERSION_VISTA;
75           break;
76         case 1:
77           // Treat Windows Server 2008 R2 the same as Windows 7.
78           version_ = VERSION_WIN7;
79           break;
80         case 2:
81           // Treat Windows Server 2012 the same as Windows 8.
82           version_ = VERSION_WIN8;
83           break;
84         default:
85           version_ = VERSION_WIN8_1;
86           break;
87       }
88     } else if (version_number_.major > 6) {
89       version_ = VERSION_WIN_LAST;
90     } else {
91       version_ = VERSION_PRE_XP_SP2;
92     }
93 
94     service_pack_.major = version_info.wServicePackMajor;
95     service_pack_.minor = version_info.wServicePackMinor;
96   }
97 
version() const98   Version version() const { return version_; }
version_number() const99   VersionNumber version_number() const { return version_number_; }
service_pack() const100   ServicePack service_pack() const { return service_pack_; }
101 
102  private:
103   Version version_;
104   VersionNumber version_number_;
105   ServicePack service_pack_;
106 
107   DISALLOW_COPY_AND_ASSIGN(OSInfo);
108 };
109 
110 }  // namespace
111 
GetThunk(bool relaxed)112 sandbox::ServiceResolverThunk* GetThunk(bool relaxed) {
113   // Create a thunk via the appropriate ServiceResolver instance.
114   sandbox::ServiceResolverThunk* thunk = NULL;
115 
116   // No thunks for unsupported OS versions.
117   OSInfo os_info;
118   if (os_info.version() <= VERSION_PRE_XP_SP2)
119     return thunk;
120 
121   // Pseudo-handle, no need to close.
122   HANDLE current_process = ::GetCurrentProcess();
123 
124 #if defined(_WIN64)
125   // ServiceResolverThunk can handle all the formats in 64-bit (instead only
126   // handling one like it does in 32-bit versions).
127   thunk = new sandbox::ServiceResolverThunk(current_process, relaxed);
128 #else
129   if (GetWOW64StatusForCurrentProcess() == WOW64_ENABLED) {
130     if (os_info.version() >= VERSION_WIN8)
131       thunk = new sandbox::Wow64W8ResolverThunk(current_process, relaxed);
132     else
133       thunk = new sandbox::Wow64ResolverThunk(current_process, relaxed);
134   } else if (os_info.version() >= VERSION_WIN8) {
135     thunk = new sandbox::Win8ResolverThunk(current_process, relaxed);
136   } else {
137     thunk = new sandbox::ServiceResolverThunk(current_process, relaxed);
138   }
139 #endif
140 
141   return thunk;
142 }
143