OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/win/scoped_process_information.h" | 5 #include "base/win/scoped_process_information.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/win/scoped_handle.h" | 8 #include "base/win/scoped_handle.h" |
| 9 #include "base/win/windows_version.h" |
9 | 10 |
10 namespace base { | 11 namespace base { |
11 namespace win { | 12 namespace win { |
12 | 13 |
13 namespace { | 14 namespace { |
14 | 15 |
15 // Duplicates source into target, returning true upon success. |target| is | 16 // Duplicates source into target, returning true upon success. |target| is |
16 // guaranteed to be untouched in case of failure. Succeeds with no side-effects | 17 // guaranteed to be untouched in case of failure. Succeeds with no side-effects |
17 // if source is NULL. | 18 // if source is NULL. |
18 bool CheckAndDuplicateHandle(HANDLE source, ScopedHandle* target) { | 19 bool CheckAndDuplicateHandle(HANDLE source, ScopedHandle* target) { |
19 if (!source) | 20 if (!source) |
20 return true; | 21 return true; |
21 | 22 |
22 HANDLE temp = NULL; | 23 HANDLE temp = NULL; |
23 if (!::DuplicateHandle(::GetCurrentProcess(), source, | 24 |
24 ::GetCurrentProcess(), &temp, 0, FALSE, | 25 // TODO(shrikant): Remove following code as soon as we gather some |
25 DUPLICATE_SAME_ACCESS)) { | 26 // information regarding AppContainer related DuplicateHandle failures that |
26 DPLOG(ERROR) << "Failed to duplicate a handle."; | 27 // only seem to happen on certain machine and only random launches (normally |
27 return false; | 28 // renderer launches seem to succeed even on those machines.) |
| 29 if (base::win::GetVersion() == base::win::VERSION_WIN8 || |
| 30 base::win::GetVersion() == base::win::VERSION_WIN8_1) { |
| 31 typedef LONG (WINAPI *NtDuplicateObject)( |
| 32 IN HANDLE SourceProcess, |
| 33 IN HANDLE SourceHandle, |
| 34 IN HANDLE TargetProcess, |
| 35 OUT PHANDLE TargetHandle, |
| 36 IN ACCESS_MASK DesiredAccess, |
| 37 IN ULONG Attributes, |
| 38 IN ULONG Options); |
| 39 |
| 40 typedef ULONG (WINAPI *RtlNtStatusToDosError)(IN LONG Status); |
| 41 |
| 42 NtDuplicateObject nt_duplicate_object = |
| 43 reinterpret_cast<NtDuplicateObject>(::GetProcAddress( |
| 44 GetModuleHandle(L"ntdll.dll"), "NtDuplicateObject")); |
| 45 if (nt_duplicate_object != NULL) { |
| 46 LONG status = nt_duplicate_object(::GetCurrentProcess(), source, |
| 47 ::GetCurrentProcess(), &temp, |
| 48 0, FALSE, DUPLICATE_SAME_ACCESS); |
| 49 if (status < 0) { |
| 50 DPLOG(ERROR) << "Failed to duplicate a handle."; |
| 51 RtlNtStatusToDosError ntstatus_to_doserror = |
| 52 reinterpret_cast<RtlNtStatusToDosError>(::GetProcAddress( |
| 53 GetModuleHandle(L"ntdll.dll"), "RtlNtStatusToDosError")); |
| 54 if (ntstatus_to_doserror != NULL) { |
| 55 ::SetLastError(ntstatus_to_doserror(status)); |
| 56 } |
| 57 return false; |
| 58 } |
| 59 } |
| 60 } else { |
| 61 if (!::DuplicateHandle(::GetCurrentProcess(), source, |
| 62 ::GetCurrentProcess(), &temp, 0, FALSE, |
| 63 DUPLICATE_SAME_ACCESS)) { |
| 64 DPLOG(ERROR) << "Failed to duplicate a handle."; |
| 65 return false; |
| 66 } |
28 } | 67 } |
29 target->Set(temp); | 68 target->Set(temp); |
30 return true; | 69 return true; |
31 } | 70 } |
32 | 71 |
33 } // namespace | 72 } // namespace |
34 | 73 |
35 ScopedProcessInformation::ScopedProcessInformation() | 74 ScopedProcessInformation::ScopedProcessInformation() |
36 : process_id_(0), thread_id_(0) { | 75 : process_id_(0), thread_id_(0) { |
37 } | 76 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 return process_handle_.Take(); | 138 return process_handle_.Take(); |
100 } | 139 } |
101 | 140 |
102 HANDLE ScopedProcessInformation::TakeThreadHandle() { | 141 HANDLE ScopedProcessInformation::TakeThreadHandle() { |
103 thread_id_ = 0; | 142 thread_id_ = 0; |
104 return thread_handle_.Take(); | 143 return thread_handle_.Take(); |
105 } | 144 } |
106 | 145 |
107 } // namespace win | 146 } // namespace win |
108 } // namespace base | 147 } // namespace base |
OLD | NEW |