Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Side by Side Diff: chrome/utility/importer/edge_database_reader_win.cc

Issue 1465853002: Implement support for importing favorites from Edge on Windows 10. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added missing include files Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/utility/importer/edge_database_reader_win.h"
6
7 #include <windows.h>
8
9 #include <vector>
10
11 namespace {
12
13 // This is an arbitary size chosen for the database error message buffer.
14 const size_t kErrorMessageSize = 1024;
15 // This is the page size of the Edge data. It's unlikely to change.
16 const JET_API_PTR kEdgeDatabasePageSize = 8192;
17 // This is the code page value for a Unicode (UCS-2) column.
18 const unsigned short kJetUnicodeCodePage = 1200;
19
20 template <typename T>
21 bool ValidateAndConvertValueGeneric(const JET_COLTYP match_column_type,
22 const JET_COLTYP column_type,
23 const std::vector<uint8_t>& column_data,
24 T* value) {
25 if ((column_type == match_column_type) && (column_data.size() == sizeof(T))) {
26 memcpy(value, &column_data[0], sizeof(T));
27 return true;
28 }
29 return false;
30 }
31
32 bool ValidateAndConvertValue(const JET_COLTYP column_type,
33 const std::vector<uint8_t>& column_data,
34 bool* value) {
35 if ((column_type == JET_coltypBit) && (column_data.size() == 1)) {
36 *value = (column_data[0] & 1) == 1;
37 return true;
38 }
39 return false;
40 }
41
42 bool ValidateAndConvertValue(const JET_COLTYP column_type,
43 const std::vector<uint8_t>& column_data,
44 base::string16* value) {
45 if ((column_type == JET_coltypLongText) &&
46 ((column_data.size() % sizeof(base::char16)) == 0)) {
47 base::string16& value_ref = *value;
48 size_t char_length = column_data.size() / sizeof(base::char16);
49 value_ref.resize(char_length);
50 memcpy(&value_ref[0], &column_data[0], column_data.size());
51 // Remove any trailing NUL characters.
52 while (char_length > 0) {
53 if (value_ref[char_length - 1])
54 break;
55 char_length--;
56 }
57 value_ref.resize(char_length);
58 return true;
59 }
60 return false;
61 }
62
63 bool ValidateAndConvertValue(const JET_COLTYP column_type,
64 const std::vector<uint8_t>& column_data,
65 GUID* value) {
66 return ValidateAndConvertValueGeneric(JET_coltypGUID, column_type,
67 column_data, value);
68 }
69
70 bool ValidateAndConvertValue(const JET_COLTYP column_type,
71 const std::vector<uint8_t>& column_data,
72 int32_t* value) {
73 return ValidateAndConvertValueGeneric(JET_coltypLong, column_type,
74 column_data, value);
75 }
76
77 bool ValidateAndConvertValue(const JET_COLTYP column_type,
78 const std::vector<uint8_t>& column_data,
79 int64_t* value) {
80 return ValidateAndConvertValueGeneric(JET_coltypLongLong, column_type,
81 column_data, value);
82 }
83
84 bool ValidateAndConvertValue(const JET_COLTYP column_type,
85 const std::vector<uint8_t>& column_data,
86 FILETIME* value) {
87 return ValidateAndConvertValueGeneric(JET_coltypLongLong, column_type,
88 column_data, value);
89 }
90
91 bool ValidateAndConvertValue(const JET_COLTYP column_type,
92 const std::vector<uint8_t>& column_data,
93 uint32_t* value) {
94 return ValidateAndConvertValueGeneric(JET_coltypUnsignedLong, column_type,
95 column_data, value);
96 }
97
98 } // namespace
99
100 base::string16 EdgeErrorObject::GetErrorMessage() const {
101 WCHAR error_message[kErrorMessageSize] = {};
102 JET_API_PTR err = last_error_;
103 JET_ERR result = JetGetSystemParameter(JET_instanceNil, JET_sesidNil,
104 JET_paramErrorToString, &err,
105 error_message, sizeof(error_message));
106 if (result != JET_errSuccess)
107 return L"";
108
109 return error_message;
110 }
111
112 bool EdgeErrorObject::SetLastError(JET_ERR error) {
113 last_error_ = error;
114 return error == JET_errSuccess;
115 }
116
117 EdgeDatabaseTableEnumerator::EdgeDatabaseTableEnumerator(
118 const base::string16& table_name,
119 JET_SESID session_id,
120 JET_TABLEID table_id)
121 : table_id_(table_id), table_name_(table_name), session_id_(session_id) {}
122
123 EdgeDatabaseTableEnumerator::~EdgeDatabaseTableEnumerator() {
124 if (table_id_ != JET_tableidNil)
125 JetCloseTable(session_id_, table_id_);
126 }
127
128 bool EdgeDatabaseTableEnumerator::Reset() {
129 return SetLastError(JetMove(session_id_, table_id_, JET_MoveFirst, 0));
130 }
131
132 bool EdgeDatabaseTableEnumerator::Next() {
133 return SetLastError(JetMove(session_id_, table_id_, JET_MoveNext, 0));
134 }
135
136 template <typename T>
137 bool EdgeDatabaseTableEnumerator::RetrieveColumn(
138 const base::string16& column_name,
139 T* value) {
140 const JET_COLUMNBASE& column_base = GetColumnByName(column_name);
141 if (column_base.cbMax == 0) {
142 SetLastError(JET_errColumnNotFound);
143 return false;
144 }
145 if (column_base.coltyp == JET_coltypLongText &&
146 column_base.cp != kJetUnicodeCodePage) {
147 SetLastError(JET_errInvalidColumnType);
148 return false;
149 }
150 std::vector<uint8_t> column_data(column_base.cbMax);
151 unsigned long actual_size = 0;
152 JET_ERR err = JetRetrieveColumn(session_id_, table_id_, column_base.columnid,
153 &column_data[0], column_data.size(),
154 &actual_size, 0, nullptr);
155 SetLastError(err);
156 if (err != JET_errSuccess && err != JET_wrnColumnNull) {
157 return false;
158 }
159
160 if (err == JET_errSuccess) {
161 column_data.resize(actual_size);
162 if (!ValidateAndConvertValue(column_base.coltyp, column_data, value)) {
163 SetLastError(JET_errInvalidColumnType);
ananta 2015/12/02 21:33:11 Should there be a trace error here?
forshaw 2015/12/02 21:56:11 I expect if this fails then the entire import woul
164 return false;
165 }
166 } else {
167 *value = T();
168 }
169
170 return true;
171 }
172
173 // Explicitly instantiate implementations of RetrieveColumn for various types.
174 template bool EdgeDatabaseTableEnumerator::RetrieveColumn(const base::string16&,
175 bool*);
176 template bool EdgeDatabaseTableEnumerator::RetrieveColumn(const base::string16&,
177 FILETIME*);
178 template bool EdgeDatabaseTableEnumerator::RetrieveColumn(const base::string16&,
179 GUID*);
180 template bool EdgeDatabaseTableEnumerator::RetrieveColumn(const base::string16&,
181 int32_t*);
182 template bool EdgeDatabaseTableEnumerator::RetrieveColumn(const base::string16&,
183 int64_t*);
184 template bool EdgeDatabaseTableEnumerator::RetrieveColumn(const base::string16&,
185 base::string16*);
186 template bool EdgeDatabaseTableEnumerator::RetrieveColumn(const base::string16&,
187 uint32_t*);
188
189 const JET_COLUMNBASE& EdgeDatabaseTableEnumerator::GetColumnByName(
190 const base::string16& column_name) {
191 auto found_col = columns_by_name_.find(column_name);
192 if (found_col == columns_by_name_.end()) {
193 JET_COLUMNBASE column_base = {};
194 column_base.cbStruct = sizeof(JET_COLUMNBASE);
195 if (!SetLastError(JetGetTableColumnInfo(
196 session_id_, table_id_, column_name.c_str(), &column_base,
197 sizeof(column_base), JET_ColInfoBase))) {
198 // 0 indicates an invalid column.
199 column_base.cbMax = 0;
200 }
201 columns_by_name_[column_name] = column_base;
202 found_col = columns_by_name_.find(column_name);
203 }
204 return found_col->second;
205 }
206
207 EdgeDatabaseReader::~EdgeDatabaseReader() {
208 // We don't need to collect other ID handles, terminating instance
209 // is enough to shut the entire session down.
210 if (instance_id_ != JET_instanceNil)
211 JetTerm(instance_id_);
212 }
213
214 bool EdgeDatabaseReader::OpenDatabase(const base::string16& database_file) {
215 if (IsOpen()) {
216 SetLastError(JET_errOneDatabasePerSession);
217 return false;
218 }
219 if (!SetLastError(JetSetSystemParameter(nullptr, JET_sesidNil,
220 JET_paramDatabasePageSize,
221 kEdgeDatabasePageSize, nullptr)))
222 return false;
223 if (!SetLastError(JetCreateInstance(&instance_id_, L"EdgeDataImporter")))
224 return false;
225 if (!SetLastError(JetSetSystemParameter(&instance_id_, JET_sesidNil,
226 JET_paramRecovery, 0, L"Off")))
227 return false;
228 if (!SetLastError(JetInit(&instance_id_)))
229 return false;
230 if (!SetLastError(
231 JetBeginSession(instance_id_, &session_id_, nullptr, nullptr)))
232 return false;
233 if (!SetLastError(JetAttachDatabase2(session_id_, database_file.c_str(), 0,
234 JET_bitDbReadOnly)))
235 return false;
236 if (!SetLastError(JetOpenDatabase(session_id_, database_file.c_str(), nullptr,
237 &db_id_, JET_bitDbReadOnly)))
238 return false;
239 return true;
240 }
241
242 scoped_ptr<EdgeDatabaseTableEnumerator> EdgeDatabaseReader::OpenTableEnumerator(
243 const base::string16& table_name) {
244 JET_TABLEID table_id;
245
246 if (!IsOpen()) {
247 SetLastError(JET_errDatabaseNotFound);
248 return nullptr;
249 }
250
251 if (!SetLastError(JetOpenTable(session_id_, db_id_, table_name.c_str(),
252 nullptr, 0, JET_bitTableReadOnly, &table_id)))
253 return nullptr;
254
255 return make_scoped_ptr(
256 new EdgeDatabaseTableEnumerator(table_name, session_id_, table_id));
257 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698