1 // Copyright 2014 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.
5 #include "base/files/file_path.h"
6 #include "chrome/common/chrome_utility_messages.h"
7 #include "chrome/utility/image_writer/error_messages.h"
8 #include "chrome/utility/image_writer/image_writer_handler.h"
9 #include "content/public/utility/utility_thread.h"
17 namespace image_writer
{
20 const size_t kStorageQueryBufferSize
= 1024;
23 ImageWriterHandler::ImageWriterHandler() : image_writer_(this) {}
24 ImageWriterHandler::~ImageWriterHandler() {}
26 void ImageWriterHandler::SendSucceeded() {
27 Send(new ChromeUtilityHostMsg_ImageWriter_Succeeded());
28 content::UtilityThread::Get()->ReleaseProcessIfNeeded();
31 void ImageWriterHandler::SendCancelled() {
32 Send(new ChromeUtilityHostMsg_ImageWriter_Cancelled());
33 content::UtilityThread::Get()->ReleaseProcessIfNeeded();
36 void ImageWriterHandler::SendFailed(const std::string
& message
) {
37 Send(new ChromeUtilityHostMsg_ImageWriter_Failed(message
));
38 content::UtilityThread::Get()->ReleaseProcessIfNeeded();
41 void ImageWriterHandler::SendProgress(int64 progress
) {
42 Send(new ChromeUtilityHostMsg_ImageWriter_Progress(progress
));
45 void ImageWriterHandler::Send(IPC::Message
* msg
) {
46 content::UtilityThread::Get()->Send(msg
);
49 bool ImageWriterHandler::OnMessageReceived(const IPC::Message
& message
) {
51 IPC_BEGIN_MESSAGE_MAP(ImageWriterHandler
, message
)
52 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ImageWriter_Write
, OnWriteStart
)
53 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ImageWriter_Verify
, OnVerifyStart
)
54 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ImageWriter_Cancel
, OnCancel
)
55 IPC_MESSAGE_UNHANDLED(handled
= false)
60 void ImageWriterHandler::OnWriteStart(const base::FilePath
& image
,
61 const base::FilePath
& device
) {
62 if (!IsValidDevice(device
)) {
63 Send(new ChromeUtilityHostMsg_ImageWriter_Failed(error::kInvalidDevice
));
67 if (image_writer_
.IsRunning()) {
68 Send(new ChromeUtilityHostMsg_ImageWriter_Failed(
69 error::kOperationAlreadyInProgress
));
72 image_writer_
.Write(image
, device
);
75 void ImageWriterHandler::OnVerifyStart(const base::FilePath
& image
,
76 const base::FilePath
& device
) {
77 if (!IsValidDevice(device
)) {
78 Send(new ChromeUtilityHostMsg_ImageWriter_Failed(error::kInvalidDevice
));
82 if (image_writer_
.IsRunning()) {
83 Send(new ChromeUtilityHostMsg_ImageWriter_Failed(
84 error::kOperationAlreadyInProgress
));
87 image_writer_
.Verify(image
, device
);
90 void ImageWriterHandler::OnCancel() {
91 if (image_writer_
.IsRunning()) {
92 image_writer_
.Cancel();
98 bool ImageWriterHandler::IsValidDevice(const base::FilePath
& device
) {
100 base::win::ScopedHandle
device_handle(
101 CreateFile(device
.value().c_str(),
102 // Desired access, which is none as we only need metadata.
104 // Required to be read + write for devices.
105 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
106 NULL
, // Optional security attributes.
107 OPEN_EXISTING
, // Devices already exist.
108 0, // No optional flags.
109 NULL
)); // No template file.
111 if (!device_handle
) {
112 PLOG(ERROR
) << "Opening device handle failed.";
116 STORAGE_PROPERTY_QUERY query
= STORAGE_PROPERTY_QUERY();
117 query
.PropertyId
= StorageDeviceProperty
;
118 query
.QueryType
= PropertyStandardQuery
;
119 DWORD bytes_returned
;
121 scoped_ptr
<char[]> output_buf(new char[kStorageQueryBufferSize
]);
122 BOOL status
= DeviceIoControl(
123 device_handle
, // Device handle.
124 IOCTL_STORAGE_QUERY_PROPERTY
, // Flag to request device properties.
125 &query
, // Query parameters.
126 sizeof(STORAGE_PROPERTY_QUERY
), // query parameters size.
127 output_buf
.get(), // output buffer.
128 kStorageQueryBufferSize
, // Size of buffer.
129 &bytes_returned
, // Number of bytes returned.
131 NULL
); // Optional unused overlapped perameter.
133 if (status
== FALSE
) {
134 PLOG(ERROR
) << "Storage property query failed.";
138 STORAGE_DEVICE_DESCRIPTOR
* device_descriptor
=
139 reinterpret_cast<STORAGE_DEVICE_DESCRIPTOR
*>(output_buf
.get());
141 if (device_descriptor
->RemovableMedia
)
145 // Other platforms will have to be added as they are supported.
151 } // namespace image_writer