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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/utility/image_writer/image_writer.cc
diff --git a/chrome/utility/image_writer/image_writer.cc b/chrome/utility/image_writer/image_writer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ac6aa9f3e84546d27b7b576c3351c50e46827cd7
--- /dev/null
+++ b/chrome/utility/image_writer/image_writer.cc
@@ -0,0 +1,298 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this image code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/platform_file.h"
+#include "chrome/utility/image_writer/error_messages.h"
+#include "chrome/utility/image_writer/image_writer.h"
+#include "chrome/utility/image_writer/image_writer_handler.h"
+#include "content/public/utility/utility_thread.h"
+
+namespace chrome {
+namespace image_writer {
+
+const int kProgressComplete = 100;
+const int kBurningBlockSize = 8 * 1024; // 8 KiB
+
+ImageWriter::ImageWriter(base::WeakPtr<ImageWriterHandler> handler)
+ : image_file_(base::kInvalidPlatformFileValue),
+ device_file_(base::kInvalidPlatformFileValue),
+ total_bytes_(0),
+ cancelled_(false),
+ handler_(handler) {
+}
+
+void ImageWriter::Write(const base::FilePath& image_path,
+ const base::FilePath& device_path) {
+ DVLOG(0) << "Starting write from " << image_path.value()
+ << " to " << device_path.value();
+
+ if ((image_file_ != base::kInvalidPlatformFileValue
+ || device_file_ != base::kInvalidPlatformFileValue)
+ && handler_) {
+ handler_->SendFailed(error::kOperationAlreadyInProgress);
+ return;
+ }
+
+ image_path_ = image_path;
+ device_path_ = device_path;
+
+ base::PlatformFileError error;
+
+ image_file_ = base::CreatePlatformFile(
+ image_path_,
+ base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ,
+ NULL,
+ &error);
+
+ if (error != base::PLATFORM_FILE_OK) {
+ DLOG(ERROR) << "Unable to open file for read: " << image_path_.value();
+ Error(error::kOpenImage);
+ return;
+ }
+
+ device_file_ = base::CreatePlatformFile(
+ device_path_,
+ base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE,
+ NULL,
+ &error);
+
+ if (error != base::PLATFORM_FILE_OK) {
+ DLOG(ERROR) << "Unable to open file for write: " << device_path_.value();
+ Error(error::kOpenDevice);
+ return;
+ }
+
+ PostTask(base::Bind(&ImageWriter::WriteChunk, this));
+}
+
+void ImageWriter::Verify(const base::FilePath& image_path,
+ const base::FilePath& device_path) {
+ DVLOG(0) << "Starting verification of " << image_path.value()
+ << " and " << device_path.value();
+
+ if ((image_file_ != base::kInvalidPlatformFileValue
+ || device_file_ != base::kInvalidPlatformFileValue)
+ && handler_) {
+ handler_->SendFailed(error::kOperationAlreadyInProgress);
+ return;
+ }
+
+ image_path_ = image_path;
+ device_path_ = device_path;
+
+ base::PlatformFileError error;
+
+ image_file_ = base::CreatePlatformFile(
+ image_path_,
+ base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ,
+ NULL,
+ &error);
+
+ if (error != base::PLATFORM_FILE_OK) {
+ DLOG(ERROR) << "Unable to open file for read: " << image_path_.value();
+ Error(error::kOpenImage);
+ return;
+ }
+
+ device_file_ = base::CreatePlatformFile(
+ device_path_,
+ base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ,
+ NULL,
+ &error);
+
+ if (error != base::PLATFORM_FILE_OK) {
+ DLOG(ERROR) << "Unable to open file for read: " << device_path_.value();
+ Error(error::kOpenDevice);
+ return;
+ }
+
+ PostTask(base::Bind(&ImageWriter::VerifyChunk, this));
+}
+
+void ImageWriter::Cancel() {
+ CleanUp();
+ cancelled_ = true;
+}
+
+ImageWriter::~ImageWriter() {
+}
+
+void ImageWriter::PostTask(const base::Closure& task) {
+ base::MessageLoop::current()->PostTask(FROM_HERE, task);
+}
+
+void ImageWriter::PostProgress(int progress) {
+ if (handler_)
+ handler_->SendProgress(progress);
+}
+
+void ImageWriter::Error(const std::string& message) {
+ CleanUp();
+
+ if (handler_)
+ handler_->SendFailed(message);
+}
+
+void ImageWriter::WriteChunk() {
+
+ if (cancelled_) {
+ return;
+ }
+
+ char buffer[kBurningBlockSize];
+ base::PlatformFileInfo info;
+ int image_size;
+
+ if (base::GetPlatformFileInfo(image_file_, &info)) {
+ image_size = info.size;
+ } else {
+ Error(error::kReadImage);
+ }
+
+ int bytes_read = base::ReadPlatformFileAtCurrentPos(image_file_,
+ buffer,
+ kBurningBlockSize);
+
+ if (bytes_read > 0) {
+ int bytes_written = base::WritePlatformFileAtCurrentPos(device_file_,
+ buffer,
+ bytes_read);
+ if (bytes_written != bytes_read) {
+ Error(error::kWriteImage);
+ return;
+ }
+
+ int percent_prev = kProgressComplete * total_bytes_ / image_size;
+ int percent_curr = kProgressComplete *
+ (total_bytes_ + bytes_written) / image_size;
+
+ if (percent_curr > percent_prev) {
+ PostProgress(percent_curr);
+ }
+
+ total_bytes_ += bytes_written;
+
+ PostTask(base::Bind(&ImageWriter::WriteChunk, this));
+ } else if (bytes_read == 0 && total_bytes_ == image_size) {
+ // End of file.
+ DLOG(INFO) << "Image write operation complete. Total bytes transferred: "
+ << total_bytes_;
+ PostTask(base::Bind(&ImageWriter::WriteComplete, this));
+ } else {
+ // Unable to read entire file.
+ DLOG(ERROR) << "Image write operation failed. Total bytes tranferred: "
+ << total_bytes_;
+ Error(error::kReadImage);
+ }
+}
+
+void ImageWriter::WriteComplete() {
+
+ DVLOG(2) << "Completed write of " << image_path_.value();
+ PostProgress(kProgressComplete);
+
+ if (CleanUp() && handler_) {
+ handler_->SendSucceeded();
+ }
+}
+
+void ImageWriter::VerifyChunk() {
+
+ if (cancelled_) {
+ return;
+ }
+
+ char image_buffer[kBurningBlockSize];
+ char device_buffer[kBurningBlockSize];
+ base::PlatformFileInfo info;
+ int image_size;
+
+ if (base::GetPlatformFileInfo(image_file_, &info)) {
+ image_size = info.size;
+ } else {
+ Error(error::kReadImage);
+ }
+
+ int bytes_read = base::ReadPlatformFileAtCurrentPos(image_file_,
+ image_buffer,
+ kBurningBlockSize);
+
+ if (bytes_read > 0) {
+ if (base::ReadPlatformFileAtCurrentPos(device_file_,
+ device_buffer,
+ kBurningBlockSize)
+ != bytes_read) {
+ DLOG(ERROR) << "Image verification failed at offset " << total_bytes_
+ << " with " << bytes_read << " bytes read.";
+ Error(error::kVerificationFailed);
+ return;
+ }
+
+ for (int i = 0; i < bytes_read; i++) {
+ if (image_buffer[i] != device_buffer[i]) {
+ DLOG(ERROR) << "Image verification failed at offset " << total_bytes_ + i
+ << " with " << bytes_read << " bytes read.";
+ Error(error::kVerificationFailed);
+ return;
+ }
+ }
+
+ int percent_prev = kProgressComplete * total_bytes_ / image_size;
+ int percent_curr = kProgressComplete *
+ (total_bytes_ + bytes_read) / image_size;
+
+ if (percent_curr > percent_prev) {
+ PostProgress(percent_curr);
+ }
+
+ total_bytes_ += bytes_read;
+
+ PostTask(base::Bind(&ImageWriter::VerifyChunk, this));
+ } else if (bytes_read == 0 && total_bytes_ == image_size) {
+ // End of file.
+ DLOG(INFO) << "Image verification operation complete. "
+ << "Total bytes checked: " << total_bytes_;
+ PostTask(base::Bind(&ImageWriter::VerifyComplete, this));
+ } else {
+ // Unable to read entire file.
+ DLOG(ERROR) << "Image verification failed at offset: " << total_bytes_;
+ Error(error::kVerificationFailed);
+ }
+}
+
+void ImageWriter::VerifyComplete() {
+
+ DVLOG(2) << "Completed verification of " << image_path_.value();
+ PostProgress(kProgressComplete);
+
+ if (CleanUp() && handler_) {
+ handler_->SendSucceeded();
+ }
+}
+
+bool ImageWriter::CleanUp() {
+ bool success = true;
+
+ total_bytes_ = 0;
+ cancelled_ = false;
+
+ if (image_file_ != base::kInvalidPlatformFileValue
+ && !base::ClosePlatformFile(image_file_)) {
+ image_file_ = base::kInvalidPlatformFileValue;
+ Error(error::kCloseImage);
+ success = false;
+ }
+
+ if (device_file_ != base::kInvalidPlatformFileValue
+ && !base::ClosePlatformFile(device_file_)) {
+ device_file_ = base::kInvalidPlatformFileValue;
+ Error(error::kCloseDevice);
+ success = false;
+ }
+
+ return success;
+}
+
+} // namespace image_writer
+} // namespace chrome

Powered by Google App Engine
This is Rietveld 408576698