Index: base/win/scoped_handle.h |
diff --git a/base/win/scoped_handle.h b/base/win/scoped_handle.h |
index 97fd7a5c79a5884b7c9ce6852987bdac959f0ac8..e04514b6320c686f9246cfa3152682f47ed4ab88 100644 |
--- a/base/win/scoped_handle.h |
+++ b/base/win/scoped_handle.h |
@@ -27,9 +27,13 @@ namespace win { |
// Generic wrapper for raw handles that takes care of closing handles |
// automatically. The class interface follows the style of |
-// the ScopedFILE class with one addition: |
+// the ScopedFILE class with two additions: |
// - IsValid() method can tolerate multiple invalid handle values such as NULL |
// and INVALID_HANDLE_VALUE (-1) for Win32 handles. |
+// - Set() (and the constructors and assignment operators that call it) |
+// preserve the Windows LastError code. This ensures that GetLastError() can |
+// be called after stashing a handle in a GenericScopedHandle object. Doing |
+// this explicitly is necessary because of bug 528394 and VC++ 2015. |
template <class Traits, class Verifier> |
class GenericScopedHandle { |
MOVE_ONLY_TYPE_FOR_CPP_03(GenericScopedHandle, RValue) |
@@ -66,6 +70,8 @@ class GenericScopedHandle { |
void Set(Handle handle) { |
if (handle_ != handle) { |
+ // Preserve old LastError to avoid bug 528394. |
+ auto last_error = GetLastError(); |
rvargas (doing something else)
2015/09/10 22:42:02
nit: use ::GetLastError()
brucedawson
2015/09/10 23:21:46
Done. Same thing for SetLastError().
|
Close(); |
if (Traits::IsHandleValid(handle)) { |
@@ -73,6 +79,7 @@ class GenericScopedHandle { |
Verifier::StartTracking(handle, this, BASE_WIN_GET_CALLER, |
tracked_objects::GetProgramCounter()); |
} |
+ SetLastError(last_error); |
} |
} |