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

Side by Side Diff: chrome/utility/image_writer/image_writer.cc

Issue 61643015: Adds imageWriterPrivate support for Windows (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Reorganization and test updates. Created 7 years, 1 month 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 (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this image code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/platform_file.h"
6 #include "chrome/utility/image_writer/error_messages.h"
7 #include "chrome/utility/image_writer/image_writer.h"
8 #include "chrome/utility/image_writer/image_writer_handler.h"
9 #include "content/public/utility/utility_thread.h"
10
11 namespace chrome {
12 namespace image_writer {
13
14 const int kProgressComplete = 100;
15 const int kBurningBlockSize = 8 * 1024; // 8 KiB
16
17 ImageWriter::ImageWriter(base::WeakPtr<ImageWriterHandler> handler)
18 : image_file_(base::kInvalidPlatformFileValue),
19 device_file_(base::kInvalidPlatformFileValue),
20 total_bytes_(0),
21 cancelled_(false),
22 handler_(handler) {
23 }
24
25 void ImageWriter::Write(const base::FilePath& image_path,
26 const base::FilePath& device_path) {
27 DVLOG(0) << "Starting write from " << image_path.value()
28 << " to " << device_path.value();
29
30 if ((image_file_ != base::kInvalidPlatformFileValue
31 || device_file_ != base::kInvalidPlatformFileValue)
32 && handler_) {
33 handler_->SendFailed(error::kOperationAlreadyInProgress);
34 return;
35 }
36
37 image_path_ = image_path;
38 device_path_ = device_path;
39
40 base::PlatformFileError error;
41
42 image_file_ = base::CreatePlatformFile(
43 image_path_,
44 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ,
45 NULL,
46 &error);
47
48 if (error != base::PLATFORM_FILE_OK) {
49 DLOG(ERROR) << "Unable to open file for read: " << image_path_.value();
50 Error(error::kOpenImage);
51 return;
52 }
53
54 device_file_ = base::CreatePlatformFile(
55 device_path_,
56 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE,
57 NULL,
58 &error);
59
60 if (error != base::PLATFORM_FILE_OK) {
61 DLOG(ERROR) << "Unable to open file for write: " << device_path_.value();
62 Error(error::kOpenDevice);
63 return;
64 }
65
66 PostTask(base::Bind(&ImageWriter::WriteChunk, this));
67 }
68
69 void ImageWriter::Verify(const base::FilePath& image_path,
70 const base::FilePath& device_path) {
71 DVLOG(0) << "Starting verification of " << image_path.value()
72 << " and " << device_path.value();
73
74 if ((image_file_ != base::kInvalidPlatformFileValue
75 || device_file_ != base::kInvalidPlatformFileValue)
76 && handler_) {
77 handler_->SendFailed(error::kOperationAlreadyInProgress);
78 return;
79 }
80
81 image_path_ = image_path;
82 device_path_ = device_path;
83
84 base::PlatformFileError error;
85
86 image_file_ = base::CreatePlatformFile(
87 image_path_,
88 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ,
89 NULL,
90 &error);
91
92 if (error != base::PLATFORM_FILE_OK) {
93 DLOG(ERROR) << "Unable to open file for read: " << image_path_.value();
94 Error(error::kOpenImage);
95 return;
96 }
97
98 device_file_ = base::CreatePlatformFile(
99 device_path_,
100 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ,
101 NULL,
102 &error);
103
104 if (error != base::PLATFORM_FILE_OK) {
105 DLOG(ERROR) << "Unable to open file for read: " << device_path_.value();
106 Error(error::kOpenDevice);
107 return;
108 }
109
110 PostTask(base::Bind(&ImageWriter::VerifyChunk, this));
111 }
112
113 void ImageWriter::Cancel() {
114 CleanUp();
115 cancelled_ = true;
116 }
117
118 ImageWriter::~ImageWriter() {
119 }
120
121 void ImageWriter::PostTask(const base::Closure& task) {
122 base::MessageLoop::current()->PostTask(FROM_HERE, task);
123 }
124
125 void ImageWriter::PostProgress(int progress) {
126 if (handler_)
127 handler_->SendProgress(progress);
128 }
129
130 void ImageWriter::Error(const std::string& message) {
131 CleanUp();
132
133 if (handler_)
134 handler_->SendFailed(message);
135 }
136
137 void ImageWriter::WriteChunk() {
138
139 if (cancelled_) {
140 return;
141 }
142
143 char buffer[kBurningBlockSize];
144 base::PlatformFileInfo info;
145 int image_size;
146
147 if (base::GetPlatformFileInfo(image_file_, &info)) {
148 image_size = info.size;
149 } else {
150 Error(error::kReadImage);
151 }
152
153 int bytes_read = base::ReadPlatformFileAtCurrentPos(image_file_,
154 buffer,
155 kBurningBlockSize);
156
157 if (bytes_read > 0) {
158 int bytes_written = base::WritePlatformFileAtCurrentPos(device_file_,
159 buffer,
160 bytes_read);
161 if (bytes_written != bytes_read) {
162 Error(error::kWriteImage);
163 return;
164 }
165
166 int percent_prev = kProgressComplete * total_bytes_ / image_size;
167 int percent_curr = kProgressComplete *
168 (total_bytes_ + bytes_written) / image_size;
169
170 if (percent_curr > percent_prev) {
171 PostProgress(percent_curr);
172 }
173
174 total_bytes_ += bytes_written;
175
176 PostTask(base::Bind(&ImageWriter::WriteChunk, this));
177 } else if (bytes_read == 0 && total_bytes_ == image_size) {
178 // End of file.
179 DLOG(INFO) << "Image write operation complete. Total bytes transferred: "
180 << total_bytes_;
181 PostTask(base::Bind(&ImageWriter::WriteComplete, this));
182 } else {
183 // Unable to read entire file.
184 DLOG(ERROR) << "Image write operation failed. Total bytes tranferred: "
185 << total_bytes_;
186 Error(error::kReadImage);
187 }
188 }
189
190 void ImageWriter::WriteComplete() {
191
192 DVLOG(2) << "Completed write of " << image_path_.value();
193 PostProgress(kProgressComplete);
194
195 if (CleanUp() && handler_) {
196 handler_->SendSucceeded();
197 }
198 }
199
200 void ImageWriter::VerifyChunk() {
201
202 if (cancelled_) {
203 return;
204 }
205
206 char image_buffer[kBurningBlockSize];
207 char device_buffer[kBurningBlockSize];
208 base::PlatformFileInfo info;
209 int image_size;
210
211 if (base::GetPlatformFileInfo(image_file_, &info)) {
212 image_size = info.size;
213 } else {
214 Error(error::kReadImage);
215 }
216
217 int bytes_read = base::ReadPlatformFileAtCurrentPos(image_file_,
218 image_buffer,
219 kBurningBlockSize);
220
221 if (bytes_read > 0) {
222 if (base::ReadPlatformFileAtCurrentPos(device_file_,
223 device_buffer,
224 kBurningBlockSize)
225 != bytes_read) {
226 DLOG(ERROR) << "Image verification failed at offset " << total_bytes_
227 << " with " << bytes_read << " bytes read.";
228 Error(error::kVerificationFailed);
229 return;
230 }
231
232 for (int i = 0; i < bytes_read; i++) {
233 if (image_buffer[i] != device_buffer[i]) {
234 DLOG(ERROR) << "Image verification failed at offset " << total_bytes_ + i
235 << " with " << bytes_read << " bytes read.";
236 Error(error::kVerificationFailed);
237 return;
238 }
239 }
240
241 int percent_prev = kProgressComplete * total_bytes_ / image_size;
242 int percent_curr = kProgressComplete *
243 (total_bytes_ + bytes_read) / image_size;
244
245 if (percent_curr > percent_prev) {
246 PostProgress(percent_curr);
247 }
248
249 total_bytes_ += bytes_read;
250
251 PostTask(base::Bind(&ImageWriter::VerifyChunk, this));
252 } else if (bytes_read == 0 && total_bytes_ == image_size) {
253 // End of file.
254 DLOG(INFO) << "Image verification operation complete. "
255 << "Total bytes checked: " << total_bytes_;
256 PostTask(base::Bind(&ImageWriter::VerifyComplete, this));
257 } else {
258 // Unable to read entire file.
259 DLOG(ERROR) << "Image verification failed at offset: " << total_bytes_;
260 Error(error::kVerificationFailed);
261 }
262 }
263
264 void ImageWriter::VerifyComplete() {
265
266 DVLOG(2) << "Completed verification of " << image_path_.value();
267 PostProgress(kProgressComplete);
268
269 if (CleanUp() && handler_) {
270 handler_->SendSucceeded();
271 }
272 }
273
274 bool ImageWriter::CleanUp() {
275 bool success = true;
276
277 total_bytes_ = 0;
278 cancelled_ = false;
279
280 if (image_file_ != base::kInvalidPlatformFileValue
281 && !base::ClosePlatformFile(image_file_)) {
282 image_file_ = base::kInvalidPlatformFileValue;
283 Error(error::kCloseImage);
284 success = false;
285 }
286
287 if (device_file_ != base::kInvalidPlatformFileValue
288 && !base::ClosePlatformFile(device_file_)) {
289 device_file_ = base::kInvalidPlatformFileValue;
290 Error(error::kCloseDevice);
291 success = false;
292 }
293
294 return success;
295 }
296
297 } // namespace image_writer
298 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698