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

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: Cleanup and now working on Windows with minimal changes. Created 6 years, 10 months 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 2013 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 kBurningBlockSize = 0x100000;
15
16 ImageWriter::ImageWriter(base::WeakPtr<ImageWriterHandler> handler)
17 : image_file_(base::kInvalidPlatformFileValue),
18 device_file_(base::kInvalidPlatformFileValue),
19 total_bytes_(0),
20 cancelled_(false),
21 handler_(handler) {}
22
23 void ImageWriter::Write(const base::FilePath& image_path,
24 const base::FilePath& device_path) {
25 if ((image_file_ != base::kInvalidPlatformFileValue ||
26 device_file_ != base::kInvalidPlatformFileValue) &&
27 handler_) {
28 handler_->SendFailed(error::kOperationAlreadyInProgress);
29 return;
30 }
31
32 image_path_ = image_path;
33 device_path_ = device_path;
34 total_bytes_ = 0;
35
36 base::PlatformFileError error;
37
38 image_file_ = base::CreatePlatformFile(
39 image_path_,
40 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ,
41 NULL,
42 &error);
43
44 if (error != base::PLATFORM_FILE_OK) {
45 DLOG(ERROR) << "Unable to open file for read: " << image_path_.value();
46 Error(error::kOpenImage);
47 return;
48 }
49
50 #if defined(OS_WIN)
51 device_file_ = CreateFile(device_path.value().c_str(),
52 GENERIC_WRITE,
53 FILE_SHARE_WRITE,
54 NULL,
55 OPEN_EXISTING,
56 FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
57 INVALID_HANDLE_VALUE);
58
59 if (device_file_ == base::kInvalidPlatformFileValue) {
60 Error(error::kOpenDevice);
61 return;
62 }
63 #else
64 device_file_ = base::CreatePlatformFile(
65 device_path_,
66 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE,
67 NULL,
68 &error);
69
70 if (error != base::PLATFORM_FILE_OK) {
71 DLOG(ERROR) << "Unable to open file for write(" << error
72 << "): " << device_path_.value();
73 Error(error::kOpenDevice);
74 return;
75 }
76 #endif
77
78 PostProgress(0);
79
80 PostTask(base::Bind(&ImageWriter::WriteChunk, this));
81 }
82
83 void ImageWriter::Verify(const base::FilePath& image_path,
84 const base::FilePath& device_path) {
85 if ((image_file_ != base::kInvalidPlatformFileValue ||
86 device_file_ != base::kInvalidPlatformFileValue) &&
87 handler_) {
88 handler_->SendFailed(error::kOperationAlreadyInProgress);
89 return;
90 }
91
92 image_path_ = image_path;
93 device_path_ = device_path;
94 total_bytes_ = 0;
95
96 base::PlatformFileError error;
97
98 image_file_ = base::CreatePlatformFile(
99 image_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: " << image_path_.value();
106 Error(error::kOpenImage);
107 return;
108 }
109
110 device_file_ = base::CreatePlatformFile(
111 device_path_,
112 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ,
113 NULL,
114 &error);
115
116 if (error != base::PLATFORM_FILE_OK) {
117 DLOG(ERROR) << "Unable to open file for read: " << device_path_.value();
118 Error(error::kOpenDevice);
119 return;
120 }
121
122 PostProgress(0);
123
124 PostTask(base::Bind(&ImageWriter::VerifyChunk, this));
125 }
126
127 void ImageWriter::Cancel() {
128 CleanUp();
129 if (handler_) {
130 handler_->SendCancelled();
131 }
132 cancelled_ = true;
133 }
134
135 ImageWriter::~ImageWriter() {}
136
137 void ImageWriter::PostTask(const base::Closure& task) {
138 base::MessageLoop::current()->PostTask(FROM_HERE, task);
139 }
140
141 void ImageWriter::PostProgress(int64 progress) {
142 if (handler_)
143 handler_->SendProgress(progress);
144 }
145
146 void ImageWriter::Error(const std::string& message) {
147 CleanUp();
148
149 if (handler_)
150 handler_->SendFailed(message);
151 }
152
153 void ImageWriter::WriteChunk() {
154 if (cancelled_) {
155 return;
156 }
157
158 scoped_ptr<char[]> buffer(new char[kBurningBlockSize]);
159 base::PlatformFileInfo info;
160
161 int bytes_read = base::ReadPlatformFile(
162 image_file_, total_bytes_, buffer.get(), kBurningBlockSize);
163
164 if (bytes_read > 0) {
165 int bytes_written = base::WritePlatformFile(
166 device_file_, total_bytes_, buffer.get(), kBurningBlockSize);
167
168 if (bytes_written < bytes_read) {
169 Error(error::kWriteImage);
170 return;
171 }
172
173 total_bytes_ += bytes_read;
174 PostProgress(total_bytes_);
175
176 PostTask(base::Bind(&ImageWriter::WriteChunk, this));
177 } else if (bytes_read == 0) {
178 // End of file.
179 PostTask(base::Bind(&ImageWriter::WriteComplete, this));
180 } else {
181 // Unable to read entire file.
182 Error(error::kReadImage);
183 }
184 }
185
186 void ImageWriter::WriteComplete() {
187 base::FlushPlatformFile(device_file_);
188 if (CleanUp() && handler_) {
189 handler_->SendSucceeded();
190 }
191 }
192
193 void ImageWriter::VerifyChunk() {
194 if (cancelled_) {
195 return;
196 }
197
198 scoped_ptr<char[]> image_buffer(new char[kBurningBlockSize]);
199 scoped_ptr<char[]> device_buffer(new char[kBurningBlockSize]);
200 base::PlatformFileInfo info;
201 int image_size;
202
203 if (base::GetPlatformFileInfo(image_file_, &info)) {
204 image_size = info.size;
205 } else {
206 Error(error::kReadImage);
207 }
208
209 int bytes_read = base::ReadPlatformFile(
210 image_file_, total_bytes_, image_buffer.get(), kBurningBlockSize);
211
212 if (bytes_read > 0) {
213 if (base::ReadPlatformFile(device_file_,
214 total_bytes_,
215 device_buffer.get(),
216 kBurningBlockSize) < 0) {
217 LOG(ERROR) << "Failed to read " << kBurningBlockSize << " bytes of "
218 << "device at offset " << total_bytes_;
219 Error(error::kReadDevice);
220 return;
221 }
222
223 if (memcmp(image_buffer.get(), device_buffer.get(), bytes_read) != 0) {
224 LOG(ERROR) << "Write verification failed when comparing " << bytes_read
225 << " bytes at " << total_bytes_;
226 Error(error::kVerificationFailed);
227 return;
228 }
229
230 total_bytes_ += bytes_read;
231 PostProgress(total_bytes_);
232
233 PostTask(base::Bind(&ImageWriter::VerifyChunk, this));
234 } else if (bytes_read == 0 && total_bytes_ == image_size) {
235 // End of file.
236 PostTask(base::Bind(&ImageWriter::VerifyComplete, this));
237 } else {
238 // Unable to read entire file.
239 LOG(ERROR) << "Failed to read " << kBurningBlockSize << " bytes of image "
240 << "at offset " << total_bytes_;
241 Error(error::kReadImage);
242 }
243 }
244
245 void ImageWriter::VerifyComplete() {
246 if (CleanUp() && handler_) {
247 handler_->SendSucceeded();
248 }
249 }
250
251 bool ImageWriter::CleanUp() {
252 bool success = true;
253
254 total_bytes_ = 0;
255 cancelled_ = false;
256
257 if (image_file_ != base::kInvalidPlatformFileValue &&
258 !base::ClosePlatformFile(image_file_)) {
259 if (handler_)
260 handler_->SendFailed(error::kCloseImage);
261 success = false;
262 }
263 image_file_ = base::kInvalidPlatformFileValue;
264
265 if (device_file_ != base::kInvalidPlatformFileValue &&
266 !base::ClosePlatformFile(device_file_)) {
267 if (handler_)
268 handler_->SendFailed(error::kCloseDevice);
269 success = false;
270 }
271 device_file_ = base::kInvalidPlatformFileValue;
272
273 return success;
274 }
275
276 } // namespace image_writer
277 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698