| Index: base/win/scoped_process_information.cc
|
| diff --git a/base/win/scoped_process_information.cc b/base/win/scoped_process_information.cc
|
| index bb2463774a8a326ffb769d7aadf6852bf53e802f..634a538eece513e8218a47a9ae72fb36bb54b005 100644
|
| --- a/base/win/scoped_process_information.cc
|
| +++ b/base/win/scoped_process_information.cc
|
| @@ -6,6 +6,7 @@
|
|
|
| #include "base/logging.h"
|
| #include "base/win/scoped_handle.h"
|
| +#include "base/win/windows_version.h"
|
|
|
| namespace base {
|
| namespace win {
|
| @@ -20,11 +21,49 @@ bool CheckAndDuplicateHandle(HANDLE source, ScopedHandle* target) {
|
| return true;
|
|
|
| HANDLE temp = NULL;
|
| - if (!::DuplicateHandle(::GetCurrentProcess(), source,
|
| - ::GetCurrentProcess(), &temp, 0, FALSE,
|
| - DUPLICATE_SAME_ACCESS)) {
|
| - DPLOG(ERROR) << "Failed to duplicate a handle.";
|
| - return false;
|
| +
|
| + // TODO(shrikant): Remove following code as soon as we gather some
|
| + // information regarding AppContainer related DuplicateHandle failures that
|
| + // only seem to happen on certain machine and only random launches (normally
|
| + // renderer launches seem to succeed even on those machines.)
|
| + if (base::win::GetVersion() == base::win::VERSION_WIN8 ||
|
| + base::win::GetVersion() == base::win::VERSION_WIN8_1) {
|
| + typedef LONG (WINAPI *NtDuplicateObject)(
|
| + IN HANDLE SourceProcess,
|
| + IN HANDLE SourceHandle,
|
| + IN HANDLE TargetProcess,
|
| + OUT PHANDLE TargetHandle,
|
| + IN ACCESS_MASK DesiredAccess,
|
| + IN ULONG Attributes,
|
| + IN ULONG Options);
|
| +
|
| + typedef ULONG (WINAPI *RtlNtStatusToDosError)(IN LONG Status);
|
| +
|
| + NtDuplicateObject nt_duplicate_object =
|
| + reinterpret_cast<NtDuplicateObject>(::GetProcAddress(
|
| + GetModuleHandle(L"ntdll.dll"), "NtDuplicateObject"));
|
| + if (nt_duplicate_object != NULL) {
|
| + LONG status = nt_duplicate_object(::GetCurrentProcess(), source,
|
| + ::GetCurrentProcess(), &temp,
|
| + 0, FALSE, DUPLICATE_SAME_ACCESS);
|
| + if (status < 0) {
|
| + DPLOG(ERROR) << "Failed to duplicate a handle.";
|
| + RtlNtStatusToDosError ntstatus_to_doserror =
|
| + reinterpret_cast<RtlNtStatusToDosError>(::GetProcAddress(
|
| + GetModuleHandle(L"ntdll.dll"), "RtlNtStatusToDosError"));
|
| + if (ntstatus_to_doserror != NULL) {
|
| + ::SetLastError(ntstatus_to_doserror(status));
|
| + }
|
| + return false;
|
| + }
|
| + }
|
| + } else {
|
| + if (!::DuplicateHandle(::GetCurrentProcess(), source,
|
| + ::GetCurrentProcess(), &temp, 0, FALSE,
|
| + DUPLICATE_SAME_ACCESS)) {
|
| + DPLOG(ERROR) << "Failed to duplicate a handle.";
|
| + return false;
|
| + }
|
| }
|
| target->Set(temp);
|
| return true;
|
|
|