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.
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"
16 VERSION_PRE_XP_SP2
= 0, // Not supported.
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.
24 VERSION_WIN_LAST
, // Indicates error condition.
28 // Whether a process is running under WOW64 (the wrapper that allows 32-bit
29 // processes to run on 64-bit versions of Windows). This will return
30 // WOW64_DISABLED for both "32-bit Chrome on 32-bit Windows" and "64-bit
31 // Chrome on 64-bit Windows". WOW64_UNKNOWN means "an error occurred", e.g.
32 // the process does not have sufficient access rights to determine this.
33 enum WOW64Status
{ WOW64_DISABLED
, WOW64_ENABLED
, WOW64_UNKNOWN
, };
35 WOW64Status
GetWOW64StatusForCurrentProcess() {
36 typedef BOOL(WINAPI
* IsWow64ProcessFunc
)(HANDLE
, PBOOL
);
37 IsWow64ProcessFunc is_wow64_process
= reinterpret_cast<IsWow64ProcessFunc
>(
38 GetProcAddress(GetModuleHandle(L
"kernel32.dll"), "IsWow64Process"));
39 if (!is_wow64_process
)
40 return WOW64_DISABLED
;
41 BOOL is_wow64
= FALSE
;
42 if (!is_wow64_process(GetCurrentProcess(), &is_wow64
))
44 return is_wow64
? WOW64_ENABLED
: WOW64_DISABLED
;
46 #endif // !defined(_WIN64)
50 struct VersionNumber
{
62 OSVERSIONINFOEX version_info
= {sizeof(version_info
)};
63 GetVersionEx(reinterpret_cast<OSVERSIONINFO
*>(&version_info
));
64 version_number_
.major
= version_info
.dwMajorVersion
;
65 version_number_
.minor
= version_info
.dwMinorVersion
;
66 version_number_
.build
= version_info
.dwBuildNumber
;
67 if ((version_number_
.major
== 5) && (version_number_
.minor
> 0)) {
68 // Treat XP Pro x64, Home Server, and Server 2003 R2 as Server 2003.
70 (version_number_
.minor
== 1) ? VERSION_XP_SP2
: VERSION_SERVER_2003
;
71 if (version_
== VERSION_XP_SP2
&& version_info
.wServicePackMajor
< 2)
72 version_
= VERSION_PRE_XP_SP2
;
73 } else if (version_number_
.major
== 6) {
74 switch (version_number_
.minor
) {
76 // Treat Windows Server 2008 the same as Windows Vista.
77 version_
= VERSION_VISTA
;
80 // Treat Windows Server 2008 R2 the same as Windows 7.
81 version_
= VERSION_WIN7
;
84 // Treat Windows Server 2012 the same as Windows 8.
85 version_
= VERSION_WIN8
;
88 version_
= VERSION_WIN8_1
;
91 } else if (version_number_
.major
== 10) {
92 version_
= VERSION_WIN10
;
93 } else if (version_number_
.major
> 6) {
94 version_
= VERSION_WIN_LAST
;
96 version_
= VERSION_PRE_XP_SP2
;
99 service_pack_
.major
= version_info
.wServicePackMajor
;
100 service_pack_
.minor
= version_info
.wServicePackMinor
;
103 Version
version() const { return version_
; }
104 VersionNumber
version_number() const { return version_number_
; }
105 ServicePack
service_pack() const { return service_pack_
; }
109 VersionNumber version_number_
;
110 ServicePack service_pack_
;
112 DISALLOW_COPY_AND_ASSIGN(OSInfo
);
117 sandbox::ServiceResolverThunk
* GetThunk(bool relaxed
) {
118 // Create a thunk via the appropriate ServiceResolver instance.
119 sandbox::ServiceResolverThunk
* thunk
= NULL
;
121 // No thunks for unsupported OS versions.
123 if (os_info
.version() <= VERSION_PRE_XP_SP2
)
126 // Pseudo-handle, no need to close.
127 HANDLE current_process
= ::GetCurrentProcess();
130 // ServiceResolverThunk can handle all the formats in 64-bit (instead only
131 // handling one like it does in 32-bit versions).
132 thunk
= new sandbox::ServiceResolverThunk(current_process
, relaxed
);
134 if (GetWOW64StatusForCurrentProcess() == WOW64_ENABLED
) {
135 if (os_info
.version() >= VERSION_WIN8
)
136 thunk
= new sandbox::Wow64W8ResolverThunk(current_process
, relaxed
);
138 thunk
= new sandbox::Wow64ResolverThunk(current_process
, relaxed
);
139 } else if (os_info
.version() >= VERSION_WIN8
) {
140 thunk
= new sandbox::Win8ResolverThunk(current_process
, relaxed
);
142 thunk
= new sandbox::ServiceResolverThunk(current_process
, relaxed
);