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