OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 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 "chrome/common/chrome_utility_messages.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 #if defined(OS_WIN) |
| 12 #include <windows.h> |
| 13 #include <setupapi.h> |
| 14 #include <winioctl.h> |
| 15 #endif |
| 16 |
| 17 namespace image_writer { |
| 18 |
| 19 ImageWriterHandler::ImageWriterHandler() : image_writer_(this) {} |
| 20 ImageWriterHandler::~ImageWriterHandler() {} |
| 21 |
| 22 void ImageWriterHandler::SendSucceeded() { |
| 23 Send(new ChromeUtilityHostMsg_ImageWriter_Succeeded()); |
| 24 content::UtilityThread::Get()->ReleaseProcessIfNeeded(); |
| 25 } |
| 26 |
| 27 void ImageWriterHandler::SendCancelled() { |
| 28 Send(new ChromeUtilityHostMsg_ImageWriter_Cancelled()); |
| 29 content::UtilityThread::Get()->ReleaseProcessIfNeeded(); |
| 30 } |
| 31 |
| 32 void ImageWriterHandler::SendFailed(const std::string& message) { |
| 33 Send(new ChromeUtilityHostMsg_ImageWriter_Failed(message)); |
| 34 content::UtilityThread::Get()->ReleaseProcessIfNeeded(); |
| 35 } |
| 36 |
| 37 void ImageWriterHandler::SendProgress(int64 progress) { |
| 38 Send(new ChromeUtilityHostMsg_ImageWriter_Progress(progress)); |
| 39 } |
| 40 |
| 41 void ImageWriterHandler::Send(IPC::Message* msg) { |
| 42 content::UtilityThread::Get()->Send(msg); |
| 43 } |
| 44 |
| 45 bool ImageWriterHandler::OnMessageReceived(const IPC::Message& message) { |
| 46 bool handled = true; |
| 47 IPC_BEGIN_MESSAGE_MAP(ImageWriterHandler, message) |
| 48 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ImageWriter_Write, OnWriteStart) |
| 49 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ImageWriter_Verify, OnVerifyStart) |
| 50 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ImageWriter_Cancel, OnCancel) |
| 51 IPC_MESSAGE_UNHANDLED(handled = false) |
| 52 IPC_END_MESSAGE_MAP() |
| 53 return handled; |
| 54 } |
| 55 |
| 56 void ImageWriterHandler::OnWriteStart(const base::FilePath& image, |
| 57 const base::FilePath& device) { |
| 58 if (!IsValidDevice(device)) { |
| 59 Send(new ChromeUtilityHostMsg_ImageWriter_Failed(error::kInvalidDevice)); |
| 60 return; |
| 61 } |
| 62 |
| 63 if (image_writer_.IsRunning()) { |
| 64 Send(new ChromeUtilityHostMsg_ImageWriter_Failed( |
| 65 error::kOperationAlreadyInProgress)); |
| 66 return; |
| 67 } |
| 68 image_writer_.Write(image, device); |
| 69 } |
| 70 |
| 71 void ImageWriterHandler::OnVerifyStart(const base::FilePath& image, |
| 72 const base::FilePath& device) { |
| 73 if (!IsValidDevice(device)) { |
| 74 Send(new ChromeUtilityHostMsg_ImageWriter_Failed(error::kInvalidDevice)); |
| 75 return; |
| 76 } |
| 77 |
| 78 if (image_writer_.IsRunning()) { |
| 79 Send(new ChromeUtilityHostMsg_ImageWriter_Failed( |
| 80 error::kOperationAlreadyInProgress)); |
| 81 return; |
| 82 } |
| 83 image_writer_.Verify(image, device); |
| 84 } |
| 85 |
| 86 void ImageWriterHandler::OnCancel() { |
| 87 if (image_writer_.IsRunning()) { |
| 88 image_writer_.Cancel(); |
| 89 } else { |
| 90 SendCancelled(); |
| 91 } |
| 92 } |
| 93 |
| 94 bool ImageWriterHandler::IsValidDevice(const base::FilePath& device) { |
| 95 #if defined(OS_WIN) |
| 96 base::string16 device16 = device.AsUTF16Unsafe(); |
| 97 base::win::ScopedHandle device_handle( |
| 98 CreateFile(device16.c_str(), |
| 99 // Desired access, which is none as we only need metadata. |
| 100 0, |
| 101 // Required to be read + write for devices. |
| 102 FILE_SHARE_READ | FILE_SHARE_WRITE, |
| 103 NULL, // Optional security attributes. |
| 104 OPEN_EXISTING, // Devices already exist. |
| 105 0, // No optional flags. |
| 106 NULL)); // No template file. |
| 107 |
| 108 if (!device_handle) { |
| 109 PLOG(ERROR) << "Opening device handle failed."; |
| 110 return false; |
| 111 } |
| 112 |
| 113 STORAGE_PROPERTY_QUERY query = STORAGE_PROPERTY_QUERY(); |
| 114 query.PropertyId = StorageDeviceProperty; |
| 115 query.QueryType = PropertyStandardQuery; |
| 116 DWORD bytes_returned; |
| 117 |
| 118 scoped_ptr<char[]> output_buf(new char[1024]); |
| 119 BOOL status = DeviceIoControl( |
| 120 device_handle, // Device handle. |
| 121 IOCTL_STORAGE_QUERY_PROPERTY, // Flag to request device properties. |
| 122 &query, // Query parameters. |
| 123 sizeof(STORAGE_PROPERTY_QUERY), // query parameters size. |
| 124 output_buf.get(), // output buffer. |
| 125 1024, // Size of buffer. |
| 126 &bytes_returned, // Number of bytes returned. |
| 127 // Must not be null. |
| 128 NULL); // Optional unused overlapped perameter. |
| 129 |
| 130 if (status == FALSE) { |
| 131 PLOG(ERROR) << "Storage property query failed."; |
| 132 return false; |
| 133 } |
| 134 |
| 135 STORAGE_DEVICE_DESCRIPTOR* device_descriptor = |
| 136 reinterpret_cast<STORAGE_DEVICE_DESCRIPTOR*>(output_buf.get()); |
| 137 |
| 138 if (device_descriptor->RemovableMedia) |
| 139 return true; |
| 140 #endif |
| 141 |
| 142 // Other platforms will have to be added as they are supported. |
| 143 return false; |
| 144 } |
| 145 |
| 146 } // namespace image_writer |
OLD | NEW |