1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
// Copyright 2017 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/scoped_hstring.h"
#include <winstring.h>
#include "base/strings/string_piece.h"
#include "base/strings/utf_string_conversions.h"
namespace base {
namespace {
static bool g_load_succeeded = false;
FARPROC LoadComBaseFunction(const char* function_name) {
static HMODULE const handle = ::LoadLibrary(L"combase.dll");
return handle ? ::GetProcAddress(handle, function_name) : nullptr;
}
decltype(&::WindowsCreateString) GetWindowsCreateString() {
static decltype(&::WindowsCreateString) const function =
reinterpret_cast<decltype(&::WindowsCreateString)>(
LoadComBaseFunction("WindowsCreateString"));
return function;
}
decltype(&::WindowsDeleteString) GetWindowsDeleteString() {
static decltype(&::WindowsDeleteString) const function =
reinterpret_cast<decltype(&::WindowsDeleteString)>(
LoadComBaseFunction("WindowsDeleteString"));
return function;
}
decltype(&::WindowsGetStringRawBuffer) GetWindowsGetStringRawBuffer() {
static decltype(&::WindowsGetStringRawBuffer) const function =
reinterpret_cast<decltype(&::WindowsGetStringRawBuffer)>(
LoadComBaseFunction("WindowsGetStringRawBuffer"));
return function;
}
HRESULT WindowsCreateString(const base::char16* src,
uint32_t len,
HSTRING* out_hstr) {
decltype(&::WindowsCreateString) create_string_func =
GetWindowsCreateString();
if (!create_string_func)
return E_FAIL;
return create_string_func(src, len, out_hstr);
}
HRESULT WindowsDeleteString(HSTRING hstr) {
decltype(&::WindowsDeleteString) delete_string_func =
GetWindowsDeleteString();
if (!delete_string_func)
return E_FAIL;
return delete_string_func(hstr);
}
const base::char16* WindowsGetStringRawBuffer(HSTRING hstr, uint32_t* out_len) {
decltype(&::WindowsGetStringRawBuffer) get_string_raw_buffer_func =
GetWindowsGetStringRawBuffer();
if (!get_string_raw_buffer_func) {
*out_len = 0;
return nullptr;
}
return get_string_raw_buffer_func(hstr, out_len);
}
} // namespace
namespace internal {
// static
void ScopedHStringTraits::Free(HSTRING hstr) {
base::WindowsDeleteString(hstr);
}
} // namespace internal
namespace win {
// static
ScopedHString ScopedHString::Create(StringPiece16 str) {
DCHECK(g_load_succeeded);
HSTRING hstr;
HRESULT hr = base::WindowsCreateString(str.data(), str.length(), &hstr);
if (SUCCEEDED(hr))
return ScopedHString(hstr);
DLOG(ERROR) << "Failed to create HSTRING" << std::hex << hr;
return ScopedHString(nullptr);
}
ScopedHString ScopedHString::Create(StringPiece str) {
return Create(UTF8ToWide(str));
}
ScopedHString::ScopedHString(HSTRING hstr) : ScopedGeneric(hstr) {
DCHECK(g_load_succeeded);
}
// static
bool ScopedHString::ResolveCoreWinRTStringDelayload() {
// TODO(finnur): Add AssertIOAllowed once crbug.com/770193 is fixed.
static const bool load_succeeded = []() {
bool success = GetWindowsCreateString() && GetWindowsDeleteString() &&
GetWindowsGetStringRawBuffer();
g_load_succeeded = success;
return success;
}();
return load_succeeded;
}
StringPiece16 ScopedHString::Get() const {
UINT32 length = 0;
const wchar_t* buffer = base::WindowsGetStringRawBuffer(get(), &length);
return StringPiece16(buffer, length);
}
std::string ScopedHString::GetAsUTF8() const {
std::string result;
const StringPiece16 wide_string = Get();
WideToUTF8(wide_string.data(), wide_string.length(), &result);
return result;
}
} // namespace win
} // namespace base
|