diff options
Diffstat (limited to 'chromium/base/win')
33 files changed, 691 insertions, 150 deletions
diff --git a/chromium/base/win/async_operation_unittest.cc b/chromium/base/win/async_operation_unittest.cc index b29e181db3f..2309c230623 100644 --- a/chromium/base/win/async_operation_unittest.cc +++ b/chromium/base/win/async_operation_unittest.cc @@ -56,6 +56,19 @@ struct DECLSPEC_UUID("9e49373c-200c-4715-abd7-4214ba669c81") } }; +#ifdef NTDDI_WIN10_VB // Windows 10.0.19041 +// Specialization templates that used to be in windows.foundation.h, removed in +// the 10.0.19041.0 SDK, so placed here instead. +template <> +struct __declspec(uuid("968b9665-06ed-5774-8f53-8edeabd5f7b5")) + IAsyncOperation<int> : IAsyncOperation_impl<int> {}; + +template <> +struct __declspec(uuid("d60cae9d-88cb-59f1-8576-3fba44796be8")) + IAsyncOperationCompletedHandler<int> + : IAsyncOperationCompletedHandler_impl<int> {}; +#endif + } // namespace Foundation } // namespace Windows } // namespace ABI diff --git a/chromium/base/win/atl.h b/chromium/base/win/atl.h index f87b7f1aeec..464438ed11c 100644 --- a/chromium/base/win/atl.h +++ b/chromium/base/win/atl.h @@ -1,6 +1,7 @@ // Copyright 2018 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. + #ifndef BASE_WIN_ATL_H_ #define BASE_WIN_ATL_H_ @@ -9,10 +10,6 @@ // Undefine before windows header will make the poisonous defines #include "base/win/windows_undefines.inc" -#ifndef _ATL_NO_EXCEPTIONS -#define _ATL_NO_EXCEPTIONS -#endif - // atlwin.h relies on std::void_t, but libc++ doesn't define it unless // _LIBCPP_STD_VER > 14. Workaround this by manually defining it. #include <type_traits> @@ -23,6 +20,9 @@ using void_t = void; } #endif +// Declare our own exception thrower (atl_throw.h includes atldef.h). +#include "base/win/atl_throw.h" + #include <atlbase.h> #include <atlcom.h> #include <atlctl.h> diff --git a/chromium/base/win/atl_throw.cc b/chromium/base/win/atl_throw.cc new file mode 100644 index 00000000000..2da52e85e68 --- /dev/null +++ b/chromium/base/win/atl_throw.cc @@ -0,0 +1,25 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/win/atl_throw.h" + +#include <winerror.h> + +#include "base/compiler_specific.h" +#include "base/debug/alias.h" +#include "base/immediate_crash.h" +#include "base/process/memory.h" + +namespace base { +namespace win { + +NOINLINE void __stdcall AtlThrowImpl(HRESULT hr) { + base::debug::Alias(&hr); + if (hr == E_OUTOFMEMORY) + base::TerminateBecauseOutOfMemory(0); + IMMEDIATE_CRASH(); +} + +} // namespace win +} // namespace base diff --git a/chromium/base/win/atl_throw.h b/chromium/base/win/atl_throw.h new file mode 100644 index 00000000000..b90cb1f638b --- /dev/null +++ b/chromium/base/win/atl_throw.h @@ -0,0 +1,43 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_WIN_ATL_THROW_H_ +#define BASE_WIN_ATL_THROW_H_ + +#ifdef __ATLDEF_H__ +#error atl_throw.h must be included before atldef.h. +#endif + +#include "base/base_export.h" +#include "base/win/windows_types.h" + +// Defining _ATL_NO_EXCEPTIONS causes ATL to raise a structured exception +// instead of throwing a CAtlException. While crashpad will eventually handle +// this, the HRESULT that caused the problem is lost. So, in addition, define +// our own custom AtlThrow function (_ATL_CUSTOM_THROW). +#ifndef _ATL_NO_EXCEPTIONS +#define _ATL_NO_EXCEPTIONS +#endif + +#define _ATL_CUSTOM_THROW +#define AtlThrow ::base::win::AtlThrowImpl + +namespace base { +namespace win { + +// Crash the process forthwith in case of ATL errors. +[[noreturn]] BASE_EXPORT void __stdcall AtlThrowImpl(HRESULT hr); + +} // namespace win +} // namespace base + +#include <atldef.h> + +// atldef.h mistakenly leaves out the declaration of this function when +// _ATL_CUSTOM_THROW is defined. +namespace ATL { +ATL_NOINLINE __declspec(noreturn) inline void WINAPI AtlThrowLastWin32(); +} + +#endif // BASE_WIN_ATL_THROW_H_ diff --git a/chromium/base/win/com_init_check_hook.cc b/chromium/base/win/com_init_check_hook.cc index 034c6ec4b31..df24953a43a 100644 --- a/chromium/base/win/com_init_check_hook.cc +++ b/chromium/base/win/com_init_check_hook.cc @@ -10,6 +10,7 @@ #include <stdint.h> #include <string.h> +#include "base/notreached.h" #include "base/strings/stringprintf.h" #include "base/synchronization/lock.h" #include "base/win/com_init_util.h" diff --git a/chromium/base/win/com_init_check_hook.h b/chromium/base/win/com_init_check_hook.h index f143adee869..28a0db30558 100644 --- a/chromium/base/win/com_init_check_hook.h +++ b/chromium/base/win/com_init_check_hook.h @@ -6,7 +6,7 @@ #define BASE_WIN_COM_INIT_CHECK_HOOK_H_ #include "base/base_export.h" -#include "base/logging.h" +#include "base/check_op.h" #include "base/macros.h" #include "build/build_config.h" diff --git a/chromium/base/win/com_init_util.cc b/chromium/base/win/com_init_util.cc index 4064a2a8899..9c1773cd395 100644 --- a/chromium/base/win/com_init_util.cc +++ b/chromium/base/win/com_init_util.cc @@ -8,6 +8,7 @@ #include <winternl.h> #include "base/logging.h" +#include "base/notreached.h" namespace base { namespace win { diff --git a/chromium/base/win/com_init_util.h b/chromium/base/win/com_init_util.h index be5a1b4c5b7..906244cf7e2 100644 --- a/chromium/base/win/com_init_util.h +++ b/chromium/base/win/com_init_util.h @@ -6,7 +6,7 @@ #define BASE_WIN_COM_INIT_UTIL_H_ #include "base/base_export.h" -#include "base/logging.h" +#include "base/check_op.h" namespace base { namespace win { diff --git a/chromium/base/win/dispatch_stub.cc b/chromium/base/win/dispatch_stub.cc new file mode 100644 index 00000000000..562f9526483 --- /dev/null +++ b/chromium/base/win/dispatch_stub.cc @@ -0,0 +1,40 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/win/dispatch_stub.h" + +namespace base { +namespace win { +namespace test { + +IFACEMETHODIMP DispatchStub::GetTypeInfoCount(UINT*) { + return E_NOTIMPL; +} + +IFACEMETHODIMP DispatchStub::GetTypeInfo(UINT, LCID, ITypeInfo**) { + return E_NOTIMPL; +} + +IFACEMETHODIMP DispatchStub::GetIDsOfNames(REFIID, + LPOLESTR*, + UINT, + LCID, + DISPID*) { + return E_NOTIMPL; +} + +IFACEMETHODIMP DispatchStub::Invoke(DISPID, + REFIID, + LCID, + WORD, + DISPPARAMS*, + VARIANT*, + EXCEPINFO*, + UINT*) { + return E_NOTIMPL; +} + +} // namespace test +} // namespace win +} // namespace base diff --git a/chromium/base/win/dispatch_stub.h b/chromium/base/win/dispatch_stub.h new file mode 100644 index 00000000000..85e4acc3db2 --- /dev/null +++ b/chromium/base/win/dispatch_stub.h @@ -0,0 +1,43 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_WIN_DISPATCH_STUB_H_ +#define BASE_WIN_DISPATCH_STUB_H_ + +#include <wrl/client.h> +#include <wrl/implements.h> + +namespace base { +namespace win { +namespace test { + +// An unimplemented IDispatch subclass for testing purposes. +class DispatchStub + : public Microsoft::WRL::RuntimeClass< + Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, + IDispatch> { + public: + DispatchStub() = default; + DispatchStub(const DispatchStub&) = delete; + DispatchStub& operator=(const DispatchStub&) = delete; + + // IDispatch: + IFACEMETHODIMP GetTypeInfoCount(UINT*) override; + IFACEMETHODIMP GetTypeInfo(UINT, LCID, ITypeInfo**) override; + IFACEMETHODIMP GetIDsOfNames(REFIID, LPOLESTR*, UINT, LCID, DISPID*) override; + IFACEMETHODIMP Invoke(DISPID, + REFIID, + LCID, + WORD, + DISPPARAMS*, + VARIANT*, + EXCEPINFO*, + UINT*) override; +}; + +} // namespace test +} // namespace win +} // namespace base + +#endif // BASE_WIN_DISPATCH_STUB_H_ diff --git a/chromium/base/win/map.h b/chromium/base/win/map.h index ef995ecf027..cee80e65e0e 100644 --- a/chromium/base/win/map.h +++ b/chromium/base/win/map.h @@ -10,7 +10,8 @@ #include <map> -#include "base/logging.h" +#include "base/check_op.h" +#include "base/notreached.h" #include "base/stl_util.h" #include "base/win/vector.h" #include "base/win/winrt_foundation_helpers.h" diff --git a/chromium/base/win/post_async_results.h b/chromium/base/win/post_async_results.h index 5df42252d66..81fb18f81e4 100644 --- a/chromium/base/win/post_async_results.h +++ b/chromium/base/win/post_async_results.h @@ -16,6 +16,7 @@ #include "base/bind.h" #include "base/callback.h" #include "base/location.h" +#include "base/logging.h" #include "base/threading/thread_task_runner_handle.h" namespace base { diff --git a/chromium/base/win/reference_unittest.cc b/chromium/base/win/reference_unittest.cc index 4116872cce6..a83f3f5ff90 100644 --- a/chromium/base/win/reference_unittest.cc +++ b/chromium/base/win/reference_unittest.cc @@ -9,6 +9,24 @@ #include "testing/gtest/include/gtest/gtest.h" +#ifdef NTDDI_WIN10_VB // Windows 10.0.19041 +// Specialization templates that used to be in windows.foundation.h, removed in +// the 10.0.19041.0 SDK, so placed here instead. +namespace ABI { +namespace Windows { +namespace Foundation { +template <> +struct __declspec(uuid("3c00fd60-2950-5939-a21a-2d12c5a01b8a")) IReference<bool> + : IReference_impl<Internal::AggregateType<bool, boolean>> {}; + +template <> +struct __declspec(uuid("548cefbd-bc8a-5fa0-8df2-957440fc8bf4")) IReference<int> + : IReference_impl<int> {}; +} // namespace Foundation +} // namespace Windows +} // namespace ABI +#endif + namespace base { namespace win { diff --git a/chromium/base/win/scoped_bstr.h b/chromium/base/win/scoped_bstr.h index 2fc70e341c9..9dbe3b2d525 100644 --- a/chromium/base/win/scoped_bstr.h +++ b/chromium/base/win/scoped_bstr.h @@ -11,7 +11,7 @@ #include <stddef.h> #include "base/base_export.h" -#include "base/logging.h" +#include "base/check.h" #include "base/macros.h" #include "base/strings/string_piece.h" diff --git a/chromium/base/win/scoped_co_mem.h b/chromium/base/win/scoped_co_mem.h index 8c4eac2e856..457d69fabba 100644 --- a/chromium/base/win/scoped_co_mem.h +++ b/chromium/base/win/scoped_co_mem.h @@ -7,7 +7,7 @@ #include <objbase.h> -#include "base/logging.h" +#include "base/check.h" #include "base/macros.h" namespace base { diff --git a/chromium/base/win/scoped_devinfo.h b/chromium/base/win/scoped_devinfo.h new file mode 100644 index 00000000000..37a3a0f765a --- /dev/null +++ b/chromium/base/win/scoped_devinfo.h @@ -0,0 +1,24 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_WIN_SCOPED_DEVINFO_H_ +#define BASE_WIN_SCOPED_DEVINFO_H_ + +#include <setupapi.h> + +#include "base/scoped_generic.h" + +namespace base { +namespace win { + +struct DevInfoScopedTraits { + static HDEVINFO InvalidValue() { return INVALID_HANDLE_VALUE; } + static void Free(HDEVINFO h) { SetupDiDestroyDeviceInfoList(h); } +}; +using ScopedDevInfo = base::ScopedGeneric<HDEVINFO, DevInfoScopedTraits>; + +} // namespace win +} // namespace base + +#endif // BASE_WIN_SCOPED_DEVINFO_H_ diff --git a/chromium/base/win/scoped_handle.h b/chromium/base/win/scoped_handle.h index 02c25336493..76a9b006751 100644 --- a/chromium/base/win/scoped_handle.h +++ b/chromium/base/win/scoped_handle.h @@ -8,10 +8,10 @@ #include "base/win/windows_types.h" #include "base/base_export.h" +#include "base/check_op.h" #include "base/compiler_specific.h" #include "base/gtest_prod_util.h" #include "base/location.h" -#include "base/logging.h" #include "base/macros.h" // TODO(rvargas): remove this with the rest of the verifier. diff --git a/chromium/base/win/scoped_hdc.h b/chromium/base/win/scoped_hdc.h index 4532d91bb2d..b5ca3c0a07d 100644 --- a/chromium/base/win/scoped_hdc.h +++ b/chromium/base/win/scoped_hdc.h @@ -7,8 +7,8 @@ #include <windows.h> +#include "base/check.h" #include "base/debug/gdi_debug_util_win.h" -#include "base/logging.h" #include "base/macros.h" #include "base/win/scoped_handle.h" diff --git a/chromium/base/win/scoped_propvariant.h b/chromium/base/win/scoped_propvariant.h index 0f1d5c85417..78e3e728ef7 100644 --- a/chromium/base/win/scoped_propvariant.h +++ b/chromium/base/win/scoped_propvariant.h @@ -7,7 +7,7 @@ #include <propidl.h> -#include "base/logging.h" +#include "base/check_op.h" #include "base/macros.h" namespace base { diff --git a/chromium/base/win/scoped_safearray.h b/chromium/base/win/scoped_safearray.h index 2b52bf98673..e7f3d7d1415 100644 --- a/chromium/base/win/scoped_safearray.h +++ b/chromium/base/win/scoped_safearray.h @@ -8,7 +8,8 @@ #include <objbase.h> #include "base/base_export.h" -#include "base/logging.h" +#include "base/check_op.h" +#include "base/macros.h" namespace base { namespace win { diff --git a/chromium/base/win/scoped_select_object.h b/chromium/base/win/scoped_select_object.h index d4b1a816fc7..81b2f93cbfc 100644 --- a/chromium/base/win/scoped_select_object.h +++ b/chromium/base/win/scoped_select_object.h @@ -7,7 +7,7 @@ #include <windows.h> -#include "base/logging.h" +#include "base/check.h" #include "base/macros.h" namespace base { diff --git a/chromium/base/win/scoped_variant.cc b/chromium/base/win/scoped_variant.cc index 2b0d74094e7..b4ce8117ea5 100644 --- a/chromium/base/win/scoped_variant.cc +++ b/chromium/base/win/scoped_variant.cc @@ -4,6 +4,7 @@ #include "base/win/scoped_variant.h" +#include "base/check.h" #include "base/logging.h" namespace base { diff --git a/chromium/base/win/scoped_variant_unittest.cc b/chromium/base/win/scoped_variant_unittest.cc index 31575846bc7..437efc2298b 100644 --- a/chromium/base/win/scoped_variant_unittest.cc +++ b/chromium/base/win/scoped_variant_unittest.cc @@ -8,9 +8,12 @@ #include <utility> +#include "base/win/dispatch_stub.h" #include "base/win/scoped_variant.h" #include "testing/gtest/include/gtest/gtest.h" +using base::win::test::DispatchStub; + namespace base { namespace win { @@ -28,41 +31,6 @@ void InitializeVariantWithBstr(VARIANT* var) { V_BSTR(var) = ::SysAllocString(kTestString); } -// An unimplemented IDispatch subclass. -class DispatchStub - : public Microsoft::WRL::RuntimeClass< - Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, - IDispatch> { - public: - DispatchStub() = default; - DispatchStub(const DispatchStub&) = delete; - DispatchStub& operator=(const DispatchStub&) = delete; - - // IDispatch: - IFACEMETHODIMP GetTypeInfoCount(UINT*) override { return E_NOTIMPL; } - IFACEMETHODIMP GetTypeInfo(UINT, LCID, ITypeInfo**) override { - return E_NOTIMPL; - } - IFACEMETHODIMP GetIDsOfNames(REFIID, - LPOLESTR*, - UINT, - LCID, - DISPID*) override { - return E_NOTIMPL; - } - - IFACEMETHODIMP Invoke(DISPID, - REFIID, - LCID, - WORD, - DISPPARAMS*, - VARIANT*, - EXCEPINFO*, - UINT*) override { - return E_NOTIMPL; - } -}; - void ExpectRefCount(ULONG expected_refcount, IUnknown* object) { // In general, code should not check the values of AddRef() and Release(). // However, tests need to validate that ScopedVariant safely owns a COM object diff --git a/chromium/base/win/shortcut.h b/chromium/base/win/shortcut.h index e1a271f90c6..57694dfc7f7 100644 --- a/chromium/base/win/shortcut.h +++ b/chromium/base/win/shortcut.h @@ -10,8 +10,8 @@ #include <stdint.h> #include "base/base_export.h" +#include "base/check.h" #include "base/files/file_path.h" -#include "base/logging.h" namespace base { namespace win { diff --git a/chromium/base/win/typed_event_handler.h b/chromium/base/win/typed_event_handler.h deleted file mode 100644 index fd62782f8a7..00000000000 --- a/chromium/base/win/typed_event_handler.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_WIN_TYPED_EVENT_HANDLER_H_ -#define BASE_WIN_TYPED_EVENT_HANDLER_H_ - -#include <windows.foundation.collections.h> -#include <wrl/implements.h> - -#include <utility> - -#include "base/callback.h" - -namespace base { -namespace win { - -// This file provides an implementation of Windows::Foundation's -// ITypedEventHandler. It serves as a thin wrapper around a RepeatingCallback, -// that forwards the arguments to its |Invoke| method to the callback's |Run| -// method. -template <typename SenderT, typename ArgsT> -class TypedEventHandler - : public Microsoft::WRL::RuntimeClass< - Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, - ABI::Windows::Foundation::ITypedEventHandler<SenderT, ArgsT>> { - public: - using SenderAbiT = - typename ABI::Windows::Foundation::Internal::GetAbiType<SenderT>::type; - using ArgsAbiT = - typename ABI::Windows::Foundation::Internal::GetAbiType<ArgsT>::type; - - using Handler = base::RepeatingCallback<HRESULT(SenderAbiT, ArgsAbiT)>; - - explicit TypedEventHandler(Handler handler) : handler_(std::move(handler)) {} - - // ABI::Windows::Foundation::ITypedEventHandler: - IFACEMETHODIMP Invoke(SenderAbiT sender, ArgsAbiT args) override { - return handler_.Run(std::move(sender), std::move(args)); - } - - private: - Handler handler_; -}; - -} // namespace win -} // namespace base - -#endif // BASE_WIN_TYPED_EVENT_HANDLER_H_ diff --git a/chromium/base/win/typed_event_handler_unittest.cc b/chromium/base/win/typed_event_handler_unittest.cc deleted file mode 100644 index 76dba80cd97..00000000000 --- a/chromium/base/win/typed_event_handler_unittest.cc +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/win/typed_event_handler.h" - -#include <windows.foundation.h> - -#include "base/test/bind_test_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace base { -namespace win { - -TEST(TypedEventHandlerTest, InvokeSuccess) { - bool called_callback = false; - TypedEventHandler<IInspectable*, IInspectable*> handler( - base::BindLambdaForTesting([&](IInspectable* sender, IInspectable* args) { - EXPECT_EQ(reinterpret_cast<IInspectable*>(0x01), sender); - EXPECT_EQ(reinterpret_cast<IInspectable*>(0x02), args); - called_callback = true; - return S_OK; - })); - - EXPECT_FALSE(called_callback); - HRESULT hr = handler.Invoke(reinterpret_cast<IInspectable*>(0x01), - reinterpret_cast<IInspectable*>(0x02)); - EXPECT_TRUE(called_callback); - EXPECT_EQ(S_OK, hr); -} - -TEST(TypedEventHandlerTest, InvokeFail) { - bool called_callback = false; - TypedEventHandler<IInspectable*, IInspectable*> handler( - base::BindLambdaForTesting([&](IInspectable* sender, IInspectable* args) { - EXPECT_EQ(nullptr, sender); - EXPECT_EQ(nullptr, args); - called_callback = true; - return E_FAIL; - })); - - EXPECT_FALSE(called_callback); - HRESULT hr = handler.Invoke(nullptr, nullptr); - EXPECT_TRUE(called_callback); - EXPECT_EQ(E_FAIL, hr); -} - -} // namespace win -} // namespace base diff --git a/chromium/base/win/variant_util.h b/chromium/base/win/variant_util.h new file mode 100644 index 00000000000..24f60e58c63 --- /dev/null +++ b/chromium/base/win/variant_util.h @@ -0,0 +1,151 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_WIN_VARIANT_UTIL_H_ +#define BASE_WIN_VARIANT_UTIL_H_ + +#include "base/logging.h" + +namespace base { +namespace win { +namespace internal { + +// Returns true if a VARIANT of type |self| can be assigned to a +// variant of type |other|. +// Does not allow converting unsigned <-> signed or converting between +// different sized types, but does allow converting IDispatch* -> IUnknown*. +constexpr bool VarTypeIsConvertibleTo(VARTYPE self, VARTYPE other) { + // IDispatch inherits from IUnknown, so it's safe to + // upcast a VT_DISPATCH into an IUnknown*. + return (self == other) || (self == VT_DISPATCH && other == VT_UNKNOWN); +} + +// VartypeToNativeType contains the underlying |Type| and offset to the +// VARIANT union member related to the |ElementVartype| for simple types. +template <VARTYPE ElementVartype> +struct VartypeToNativeType final {}; + +template <> +struct VartypeToNativeType<VT_BOOL> final { + using Type = VARIANT_BOOL; + static constexpr VARIANT_BOOL VARIANT::*kMemberOffset = &VARIANT::boolVal; +}; + +template <> +struct VartypeToNativeType<VT_I1> final { + using Type = int8_t; + static constexpr CHAR VARIANT::*kMemberOffset = &VARIANT::cVal; +}; + +template <> +struct VartypeToNativeType<VT_UI1> final { + using Type = uint8_t; + static constexpr BYTE VARIANT::*kMemberOffset = &VARIANT::bVal; +}; + +template <> +struct VartypeToNativeType<VT_I2> final { + using Type = int16_t; + static constexpr SHORT VARIANT::*kMemberOffset = &VARIANT::iVal; +}; + +template <> +struct VartypeToNativeType<VT_UI2> final { + using Type = uint16_t; + static constexpr USHORT VARIANT::*kMemberOffset = &VARIANT::uiVal; +}; + +template <> +struct VartypeToNativeType<VT_I4> final { + using Type = int32_t; + static constexpr LONG VARIANT::*kMemberOffset = &VARIANT::lVal; +}; + +template <> +struct VartypeToNativeType<VT_UI4> final { + using Type = uint32_t; + static constexpr ULONG VARIANT::*kMemberOffset = &VARIANT::ulVal; +}; + +template <> +struct VartypeToNativeType<VT_I8> final { + using Type = int64_t; + static constexpr LONGLONG VARIANT::*kMemberOffset = &VARIANT::llVal; +}; + +template <> +struct VartypeToNativeType<VT_UI8> final { + using Type = uint64_t; + static constexpr ULONGLONG VARIANT::*kMemberOffset = &VARIANT::ullVal; +}; + +template <> +struct VartypeToNativeType<VT_R4> final { + using Type = float; + static constexpr FLOAT VARIANT::*kMemberOffset = &VARIANT::fltVal; +}; + +template <> +struct VartypeToNativeType<VT_R8> final { + using Type = double; + static constexpr DOUBLE VARIANT::*kMemberOffset = &VARIANT::dblVal; +}; + +template <> +struct VartypeToNativeType<VT_DATE> final { + using Type = DATE; + static constexpr DATE VARIANT::*kMemberOffset = &VARIANT::date; +}; + +template <> +struct VartypeToNativeType<VT_BSTR> final { + using Type = BSTR; + static constexpr BSTR VARIANT::*kMemberOffset = &VARIANT::bstrVal; +}; + +template <> +struct VartypeToNativeType<VT_UNKNOWN> final { + using Type = IUnknown*; + static constexpr IUnknown* VARIANT::*kMemberOffset = &VARIANT::punkVal; +}; + +template <> +struct VartypeToNativeType<VT_DISPATCH> final { + using Type = IDispatch*; + static constexpr IDispatch* VARIANT::*kMemberOffset = &VARIANT::pdispVal; +}; + +// VariantUtil contains the underlying |Type| and helper methods +// related to the |ElementVartype| for simple types. +template <VARTYPE ElementVartype> +struct VariantUtil final { + using Type = typename VartypeToNativeType<ElementVartype>::Type; + static constexpr bool IsConvertibleTo(VARTYPE vartype) { + return VarTypeIsConvertibleTo(ElementVartype, vartype); + } + static constexpr bool IsConvertibleFrom(VARTYPE vartype) { + return VarTypeIsConvertibleTo(vartype, ElementVartype); + } + // Get the associated VARIANT union member value. + // Returns the value owned by the VARIANT without affecting the lifetime + // of managed contents. + // e.g. Does not affect IUnknown* reference counts or allocate a BSTR. + static Type RawGet(const VARIANT& var) { + DCHECK(IsConvertibleFrom(V_VT(&var))); + return var.*VartypeToNativeType<ElementVartype>::kMemberOffset; + } + // Set the associated VARIANT union member value. + // The caller is responsible for handling the lifetime of managed contents. + // e.g. Incrementing IUnknown* reference counts or allocating a BSTR. + static void RawSet(VARIANT* var, Type value) { + DCHECK(IsConvertibleTo(V_VT(var))); + var->*VartypeToNativeType<ElementVartype>::kMemberOffset = value; + } +}; + +} // namespace internal +} // namespace win +} // namespace base + +#endif // BASE_WIN_VARIANT_UTIL_H_ diff --git a/chromium/base/win/variant_util_unittest.cc b/chromium/base/win/variant_util_unittest.cc new file mode 100644 index 00000000000..f15634afe60 --- /dev/null +++ b/chromium/base/win/variant_util_unittest.cc @@ -0,0 +1,266 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <stdint.h> +#include <wrl/client.h> +#include <wrl/implements.h> + +#include <set> +#include <utility> + +#include "base/stl_util.h" +#include "base/win/dispatch_stub.h" +#include "base/win/scoped_bstr.h" +#include "base/win/variant_util.h" +#include "testing/gtest/include/gtest/gtest.h" + +using base::win::internal::VariantUtil; +using base::win::test::DispatchStub; + +namespace base { +namespace win { + +namespace { + +static constexpr VARTYPE kSupportedVartypes[] = { + VT_BOOL, VT_I1, VT_UI1, VT_I2, VT_UI2, VT_I4, VT_UI4, VT_I8, + VT_UI8, VT_R4, VT_R8, VT_DATE, VT_BSTR, VT_UNKNOWN, VT_DISPATCH}; + +template <VARTYPE ElementVartype> +static bool TestIsConvertibleTo(const std::set<VARTYPE>& allowed_vartypes) { + for (VARTYPE vartype : kSupportedVartypes) { + if (VariantUtil<ElementVartype>::IsConvertibleTo(vartype) != + base::Contains(allowed_vartypes, vartype)) { + return false; + } + } + return true; +} + +template <VARTYPE ElementVartype> +static bool TestIsConvertibleFrom(const std::set<VARTYPE>& allowed_vartypes) { + for (VARTYPE vartype : kSupportedVartypes) { + if (VariantUtil<ElementVartype>::IsConvertibleFrom(vartype) != + base::Contains(allowed_vartypes, vartype)) { + return false; + } + } + return true; +} + +} // namespace + +TEST(VariantUtilTest, VariantTypeBool) { + VARIANT variant; + V_VT(&variant) = VT_BOOL; + + VariantUtil<VT_BOOL>::RawSet(&variant, VARIANT_TRUE); + EXPECT_EQ(V_BOOL(&variant), VARIANT_TRUE); + EXPECT_EQ(VariantUtil<VT_BOOL>::RawGet(variant), VARIANT_TRUE); + + const std::set<VARTYPE> allowed_vartypes = {VT_BOOL}; + EXPECT_TRUE(TestIsConvertibleTo<VT_BOOL>(allowed_vartypes)); + EXPECT_TRUE(TestIsConvertibleFrom<VT_BOOL>(allowed_vartypes)); +} + +TEST(VariantUtilTest, VariantTypeI1) { + VARIANT variant; + V_VT(&variant) = VT_I1; + + VariantUtil<VT_I1>::RawSet(&variant, 34); + EXPECT_EQ(V_I1(&variant), 34); + EXPECT_EQ(VariantUtil<VT_I1>::RawGet(variant), 34); + + const std::set<VARTYPE> allowed_vartypes = {VT_I1}; + EXPECT_TRUE(TestIsConvertibleTo<VT_I1>(allowed_vartypes)); + EXPECT_TRUE(TestIsConvertibleFrom<VT_I1>(allowed_vartypes)); +} + +TEST(VariantUtilTest, VariantTypeUI1) { + VARIANT variant; + V_VT(&variant) = VT_UI1; + + VariantUtil<VT_UI1>::RawSet(&variant, 34U); + EXPECT_EQ(V_UI1(&variant), 34U); + EXPECT_EQ(VariantUtil<VT_UI1>::RawGet(variant), 34U); + + const std::set<VARTYPE> allowed_vartypes = {VT_UI1}; + EXPECT_TRUE(TestIsConvertibleTo<VT_UI1>(allowed_vartypes)); + EXPECT_TRUE(TestIsConvertibleFrom<VT_UI1>(allowed_vartypes)); +} + +TEST(VariantUtilTest, VariantTypeI2) { + VARIANT variant; + V_VT(&variant) = VT_I2; + + VariantUtil<VT_I2>::RawSet(&variant, 8738); + EXPECT_EQ(V_I2(&variant), 8738); + EXPECT_EQ(VariantUtil<VT_I2>::RawGet(variant), 8738); + + const std::set<VARTYPE> allowed_vartypes = {VT_I2}; + EXPECT_TRUE(TestIsConvertibleTo<VT_I2>(allowed_vartypes)); + EXPECT_TRUE(TestIsConvertibleFrom<VT_I2>(allowed_vartypes)); +} + +TEST(VariantUtilTest, VariantTypeUI2) { + VARIANT variant; + V_VT(&variant) = VT_UI2; + + VariantUtil<VT_UI2>::RawSet(&variant, 8738U); + EXPECT_EQ(V_UI2(&variant), 8738U); + EXPECT_EQ(VariantUtil<VT_UI2>::RawGet(variant), 8738U); + + const std::set<VARTYPE> allowed_vartypes = {VT_UI2}; + EXPECT_TRUE(TestIsConvertibleTo<VT_UI2>(allowed_vartypes)); + EXPECT_TRUE(TestIsConvertibleFrom<VT_UI2>(allowed_vartypes)); +} + +TEST(VariantUtilTest, VariantTypeI4) { + VARIANT variant; + V_VT(&variant) = VT_I4; + + VariantUtil<VT_I4>::RawSet(&variant, 572662306); + EXPECT_EQ(V_I4(&variant), 572662306); + EXPECT_EQ(VariantUtil<VT_I4>::RawGet(variant), 572662306); + + const std::set<VARTYPE> allowed_vartypes = {VT_I4}; + EXPECT_TRUE(TestIsConvertibleTo<VT_I4>(allowed_vartypes)); + EXPECT_TRUE(TestIsConvertibleFrom<VT_I4>(allowed_vartypes)); +} + +TEST(VariantUtilTest, VariantTypeUI4) { + VARIANT variant; + V_VT(&variant) = VT_UI4; + + VariantUtil<VT_UI4>::RawSet(&variant, 572662306U); + EXPECT_EQ(V_UI4(&variant), 572662306U); + EXPECT_EQ(VariantUtil<VT_UI4>::RawGet(variant), 572662306U); + + const std::set<VARTYPE> allowed_vartypes = {VT_UI4}; + EXPECT_TRUE(TestIsConvertibleTo<VT_UI4>(allowed_vartypes)); + EXPECT_TRUE(TestIsConvertibleFrom<VT_UI4>(allowed_vartypes)); +} + +TEST(VariantUtilTest, VariantTypeI8) { + VARIANT variant; + V_VT(&variant) = VT_I8; + + VariantUtil<VT_I8>::RawSet(&variant, 2459565876494606882); + EXPECT_EQ(V_I8(&variant), 2459565876494606882); + EXPECT_EQ(VariantUtil<VT_I8>::RawGet(variant), 2459565876494606882); + + const std::set<VARTYPE> allowed_vartypes = {VT_I8}; + EXPECT_TRUE(TestIsConvertibleTo<VT_I8>(allowed_vartypes)); + EXPECT_TRUE(TestIsConvertibleFrom<VT_I8>(allowed_vartypes)); +} + +TEST(VariantUtilTest, VariantTypeUI8) { + VARIANT variant; + V_VT(&variant) = VT_UI8; + + VariantUtil<VT_UI8>::RawSet(&variant, 2459565876494606882U); + EXPECT_EQ(V_UI8(&variant), 2459565876494606882U); + EXPECT_EQ(VariantUtil<VT_UI8>::RawGet(variant), 2459565876494606882U); + + const std::set<VARTYPE> allowed_vartypes = {VT_UI8}; + EXPECT_TRUE(TestIsConvertibleTo<VT_UI8>(allowed_vartypes)); + EXPECT_TRUE(TestIsConvertibleFrom<VT_UI8>(allowed_vartypes)); +} + +TEST(VariantUtilTest, VariantTypeR4) { + VARIANT variant; + V_VT(&variant) = VT_R4; + + VariantUtil<VT_R4>::RawSet(&variant, 3.14159f); + EXPECT_EQ(V_R4(&variant), 3.14159f); + EXPECT_EQ(VariantUtil<VT_R4>::RawGet(variant), 3.14159f); + + const std::set<VARTYPE> allowed_vartypes = {VT_R4}; + EXPECT_TRUE(TestIsConvertibleTo<VT_R4>(allowed_vartypes)); + EXPECT_TRUE(TestIsConvertibleFrom<VT_R4>(allowed_vartypes)); +} + +TEST(VariantUtilTest, VariantTypeR8) { + VARIANT variant; + V_VT(&variant) = VT_R8; + + VariantUtil<VT_R8>::RawSet(&variant, 3.14159); + EXPECT_EQ(V_R8(&variant), 3.14159); + EXPECT_EQ(VariantUtil<VT_R8>::RawGet(variant), 3.14159); + + const std::set<VARTYPE> allowed_vartypes = {VT_R8}; + EXPECT_TRUE(TestIsConvertibleTo<VT_R8>(allowed_vartypes)); + EXPECT_TRUE(TestIsConvertibleFrom<VT_R8>(allowed_vartypes)); +} + +TEST(VariantUtilTest, VariantTypeDate) { + SYSTEMTIME sys_time; + ::GetSystemTime(&sys_time); + DATE date; + ::SystemTimeToVariantTime(&sys_time, &date); + + VARIANT variant; + V_VT(&variant) = VT_DATE; + + VariantUtil<VT_DATE>::RawSet(&variant, date); + EXPECT_EQ(V_DATE(&variant), date); + EXPECT_EQ(VariantUtil<VT_DATE>::RawGet(variant), date); + + const std::set<VARTYPE> allowed_vartypes = {VT_DATE}; + EXPECT_TRUE(TestIsConvertibleTo<VT_DATE>(allowed_vartypes)); + EXPECT_TRUE(TestIsConvertibleFrom<VT_DATE>(allowed_vartypes)); +} + +TEST(VariantUtilTest, VariantTypeBstr) { + ScopedBstr scoped_bstr; + scoped_bstr.Allocate(L"some text"); + + VARIANT variant; + V_VT(&variant) = VT_BSTR; + + VariantUtil<VT_BSTR>::RawSet(&variant, scoped_bstr.Get()); + EXPECT_EQ(V_BSTR(&variant), scoped_bstr.Get()); + EXPECT_EQ(VariantUtil<VT_BSTR>::RawGet(variant), scoped_bstr.Get()); + + const std::set<VARTYPE> allowed_vartypes = {VT_BSTR}; + EXPECT_TRUE(TestIsConvertibleTo<VT_BSTR>(allowed_vartypes)); + EXPECT_TRUE(TestIsConvertibleFrom<VT_BSTR>(allowed_vartypes)); +} + +TEST(VariantUtilTest, VariantTypeUnknown) { + Microsoft::WRL::ComPtr<IUnknown> unknown = + Microsoft::WRL::Make<DispatchStub>(); + + VARIANT variant; + V_VT(&variant) = VT_UNKNOWN; + + VariantUtil<VT_UNKNOWN>::RawSet(&variant, unknown.Get()); + EXPECT_EQ(V_UNKNOWN(&variant), unknown.Get()); + EXPECT_EQ(VariantUtil<VT_UNKNOWN>::RawGet(variant), unknown.Get()); + + const std::set<VARTYPE> allow_convertible_to = {VT_UNKNOWN}; + const std::set<VARTYPE> allow_convertible_from = {VT_UNKNOWN, VT_DISPATCH}; + EXPECT_TRUE(TestIsConvertibleTo<VT_UNKNOWN>(allow_convertible_to)); + EXPECT_TRUE(TestIsConvertibleFrom<VT_UNKNOWN>(allow_convertible_from)); +} + +TEST(VariantUtilTest, VariantTypeDispatch) { + Microsoft::WRL::ComPtr<IDispatch> dispatch = + Microsoft::WRL::Make<DispatchStub>(); + + VARIANT variant; + V_VT(&variant) = VT_DISPATCH; + + VariantUtil<VT_DISPATCH>::RawSet(&variant, dispatch.Get()); + EXPECT_EQ(V_DISPATCH(&variant), dispatch.Get()); + EXPECT_EQ(VariantUtil<VT_DISPATCH>::RawGet(variant), dispatch.Get()); + + const std::set<VARTYPE> allow_convertible_to = {VT_UNKNOWN, VT_DISPATCH}; + const std::set<VARTYPE> allow_convertible_from = {VT_DISPATCH}; + EXPECT_TRUE(TestIsConvertibleTo<VT_DISPATCH>(allow_convertible_to)); + EXPECT_TRUE(TestIsConvertibleFrom<VT_DISPATCH>(allow_convertible_from)); +} + +} // namespace win +} // namespace base diff --git a/chromium/base/win/vector.h b/chromium/base/win/vector.h index 1d96710b95d..654061fa3ec 100644 --- a/chromium/base/win/vector.h +++ b/chromium/base/win/vector.h @@ -15,8 +15,8 @@ #include <vector> #include "base/base_export.h" +#include "base/check_op.h" #include "base/containers/flat_map.h" -#include "base/logging.h" #include "base/win/winrt_foundation_helpers.h" namespace base { diff --git a/chromium/base/win/vector_unittest.cc b/chromium/base/win/vector_unittest.cc index b2cce5228f8..459e54026f6 100644 --- a/chromium/base/win/vector_unittest.cc +++ b/chromium/base/win/vector_unittest.cc @@ -39,6 +39,43 @@ struct __declspec(uuid("050e4b78-71b2-43ff-bf7c-f6ba589aced9")) VectorChangedEventHandler<Uri*> : VectorChangedEventHandler_impl<UriPtrAggregate> {}; +#ifdef NTDDI_WIN10_VB // Windows 10.0.19041 +// Specialization templates that used to be in windows.foundation.h, removed in +// the 10.0.19041.0 SDK, so placed here instead. +template <> +struct __declspec(uuid("b939af5b-b45d-5489-9149-61442c1905fe")) IVector<int> + : IVector_impl<int> {}; + +template <> +struct __declspec(uuid("8d720cdf-3934-5d3f-9a55-40e8063b086a")) IVectorView<int> + : IVectorView_impl<int> {}; + +template <> +struct __declspec(uuid("bfea7f78-50c2-5f1d-a6ea-9e978d2699ff")) IIterator<int> + : IIterator_impl<int> {}; + +template <> +struct __declspec(uuid("81a643fb-f51c-5565-83c4-f96425777b66")) IIterable<int> + : IIterable_impl<int> {}; + +template <> +struct __declspec(uuid("0d82bd8d-fe62-5d67-a7b9-7886dd75bc4e")) IVector<Uri*> + : IVector_impl<Internal::AggregateType<Uri*, IUriRuntimeClass*>> {}; + +template <> +struct __declspec(uuid("4b8385bd-a2cd-5ff1-bf74-7ea580423e50")) + IVectorView<Uri*> + : IVectorView_impl<Internal::AggregateType<Uri*, IUriRuntimeClass*>> {}; + +template <> +struct __declspec(uuid("1c157d0f-5efe-5cec-bbd6-0c6ce9af07a5")) IIterator<Uri*> + : IIterator_impl<Internal::AggregateType<Uri*, IUriRuntimeClass*>> {}; + +template <> +struct __declspec(uuid("b0d63b78-78ad-5e31-b6d8-e32a0e16c447")) IIterable<Uri*> + : IIterable_impl<Internal::AggregateType<Uri*, IUriRuntimeClass*>> {}; +#endif + } // namespace Collections } // namespace Foundation } // namespace Windows diff --git a/chromium/base/win/windows_version.cc b/chromium/base/win/windows_version.cc index 0905602ee96..1c4580feab9 100644 --- a/chromium/base/win/windows_version.cc +++ b/chromium/base/win/windows_version.cc @@ -245,6 +245,8 @@ OSInfo::WOW64Status OSInfo::GetWOW64StatusForProcess(HANDLE process_handle) { // static Version OSInfo::MajorMinorBuildToVersion(int major, int minor, int build) { if (major == 10) { + if (build >= 19041) + return Version::WIN10_20H1; if (build >= 18362) return Version::WIN10_19H1; if (build >= 17763) diff --git a/chromium/base/win/windows_version.h b/chromium/base/win/windows_version.h index 7b70619e27f..95bd9fca4c4 100644 --- a/chromium/base/win/windows_version.h +++ b/chromium/base/win/windows_version.h @@ -50,6 +50,7 @@ enum class Version { WIN10_RS4 = 12, // Redstone 4: Version 1803, Build 17134. WIN10_RS5 = 13, // Redstone 5: Version 1809, Build 17763. WIN10_19H1 = 14, // 19H1: Version 1903, Build 18362. + WIN10_20H1 = 15, // 20H1: Version 2004, Build 19041. // On edit, update tools\metrics\histograms\enums.xml "WindowsVersion" and // "GpuBlacklistFeatureTestResultsWindows2". WIN_LAST, // Indicates error condition. diff --git a/chromium/base/win/windows_version_unittest.cc b/chromium/base/win/windows_version_unittest.cc index bd9d5048944..b5ca8b46080 100644 --- a/chromium/base/win/windows_version_unittest.cc +++ b/chromium/base/win/windows_version_unittest.cc @@ -19,7 +19,9 @@ TEST(WindowsVersion, GetVersionExAndKernelVersionMatch) { TEST(OSInfo, MajorMinorBuildToVersion) { EXPECT_EQ(OSInfo::MajorMinorBuildToVersion(10, 0, 32767), - Version::WIN10_19H1); + Version::WIN10_20H1); + EXPECT_EQ(OSInfo::MajorMinorBuildToVersion(10, 0, 19041), + Version::WIN10_20H1); EXPECT_EQ(OSInfo::MajorMinorBuildToVersion(10, 0, 18362), Version::WIN10_19H1); EXPECT_EQ(OSInfo::MajorMinorBuildToVersion(10, 0, 17763), Version::WIN10_RS5); |