OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/api/usb/usb_api.h" | 5 #include "chrome/browser/extensions/api/usb/usb_api.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 "Error setting alternate interface setting."; | 57 "Error setting alternate interface setting."; |
58 static const char* kErrorConvertDirection = "Invalid transfer direction."; | 58 static const char* kErrorConvertDirection = "Invalid transfer direction."; |
59 static const char* kErrorConvertRecipient = "Invalid transfer recipient."; | 59 static const char* kErrorConvertRecipient = "Invalid transfer recipient."; |
60 static const char* kErrorConvertRequestType = "Invalid request type."; | 60 static const char* kErrorConvertRequestType = "Invalid request type."; |
61 static const char* kErrorMalformedParameters = "Error parsing parameters."; | 61 static const char* kErrorMalformedParameters = "Error parsing parameters."; |
62 static const char* kErrorNoDevice = "No such device."; | 62 static const char* kErrorNoDevice = "No such device."; |
63 static const char* kErrorPermissionDenied = | 63 static const char* kErrorPermissionDenied = |
64 "Permission to access device was denied"; | 64 "Permission to access device was denied"; |
65 static const char* kErrorInvalidTransferLength = "Transfer length must be a " | 65 static const char* kErrorInvalidTransferLength = "Transfer length must be a " |
66 "positive number less than 104,857,600."; | 66 "positive number less than 104,857,600."; |
| 67 static const char* kErrorInvalidNumberOfPackets = "Number of packets must be a " |
| 68 "positive number less than 4,194,304."; |
| 69 static const char* kErrorInvalidPacketLength = "Packet length must be a " |
| 70 "positive number less than 65,536."; |
67 | 71 |
68 static const size_t kMaxTransferLength = 100 * 1024 * 1024; | 72 static const size_t kMaxTransferLength = 100 * 1024 * 1024; |
| 73 static const int kMaxPackets = 4 * 1024 * 1024; |
| 74 static const int kMaxPacketLength = 64 * 1024; |
| 75 |
69 static UsbDevice* device_for_test_ = NULL; | 76 static UsbDevice* device_for_test_ = NULL; |
70 | 77 |
71 static bool ConvertDirection(const Direction& input, | 78 static bool ConvertDirection(const Direction& input, |
72 UsbDevice::TransferDirection* output) { | 79 UsbDevice::TransferDirection* output) { |
73 switch (input) { | 80 switch (input) { |
74 case usb::DIRECTION_IN: | 81 case usb::DIRECTION_IN: |
75 *output = UsbDevice::INBOUND; | 82 *output = UsbDevice::INBOUND; |
76 return true; | 83 return true; |
77 case usb::DIRECTION_OUT: | 84 case usb::DIRECTION_OUT: |
78 *output = UsbDevice::OUTBOUND; | 85 *output = UsbDevice::OUTBOUND; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 return true; | 150 return true; |
144 } | 151 } |
145 } | 152 } |
146 return false; | 153 return false; |
147 } | 154 } |
148 | 155 |
149 template<class T> | 156 template<class T> |
150 static scoped_refptr<net::IOBuffer> CreateBufferForTransfer( | 157 static scoped_refptr<net::IOBuffer> CreateBufferForTransfer( |
151 const T& input, UsbDevice::TransferDirection direction, size_t size) { | 158 const T& input, UsbDevice::TransferDirection direction, size_t size) { |
152 | 159 |
153 if (size > kMaxTransferLength) | 160 if (size >= kMaxTransferLength) |
154 return NULL; | 161 return NULL; |
155 | 162 |
156 // Allocate a |size|-bytes buffer, or a one-byte buffer if |size| is 0. This | 163 // Allocate a |size|-bytes buffer, or a one-byte buffer if |size| is 0. This |
157 // is due to an impedance mismatch between IOBuffer and URBs. An IOBuffer | 164 // is due to an impedance mismatch between IOBuffer and URBs. An IOBuffer |
158 // cannot represent a zero-length buffer, while an URB can. | 165 // cannot represent a zero-length buffer, while an URB can. |
159 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(std::max( | 166 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(std::max( |
160 static_cast<size_t>(1), size)); | 167 static_cast<size_t>(1), size)); |
161 | 168 |
162 if (direction == UsbDevice::INBOUND) { | 169 if (direction == UsbDevice::INBOUND) { |
163 return buffer; | 170 return buffer; |
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
621 const IsochronousTransferInfo& transfer = parameters_->transfer_info; | 628 const IsochronousTransferInfo& transfer = parameters_->transfer_info; |
622 const GenericTransferInfo& generic_transfer = transfer.transfer_info; | 629 const GenericTransferInfo& generic_transfer = transfer.transfer_info; |
623 | 630 |
624 size_t size = 0; | 631 size_t size = 0; |
625 UsbDevice::TransferDirection direction; | 632 UsbDevice::TransferDirection direction; |
626 | 633 |
627 if (!ConvertDirectionSafely(generic_transfer.direction, &direction)) { | 634 if (!ConvertDirectionSafely(generic_transfer.direction, &direction)) { |
628 AsyncWorkCompleted(); | 635 AsyncWorkCompleted(); |
629 return; | 636 return; |
630 } | 637 } |
631 | |
632 if (!GetTransferSize(generic_transfer, &size)) { | 638 if (!GetTransferSize(generic_transfer, &size)) { |
633 CompleteWithError(kErrorInvalidTransferLength); | 639 CompleteWithError(kErrorInvalidTransferLength); |
634 return; | 640 return; |
635 } | 641 } |
| 642 if (transfer.packets < 0 || transfer.packets >= kMaxPackets) { |
| 643 CompleteWithError(kErrorInvalidNumberOfPackets); |
| 644 return; |
| 645 } |
| 646 unsigned int packets = transfer.packets; |
| 647 if (transfer.packet_length < 0 || |
| 648 transfer.packet_length >= kMaxPacketLength) { |
| 649 CompleteWithError(kErrorInvalidPacketLength); |
| 650 return; |
| 651 } |
| 652 unsigned int packet_length = transfer.packet_length; |
| 653 const uint64 total_length = packets * packet_length; |
| 654 if (packets > size || total_length > size) { |
| 655 CompleteWithError(kErrorTransferLength); |
| 656 return; |
| 657 } |
636 | 658 |
637 scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer( | 659 scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer( |
638 generic_transfer, direction, size); | 660 generic_transfer, direction, size); |
639 if (!buffer) { | 661 if (!buffer) { |
640 CompleteWithError(kErrorMalformedParameters); | 662 CompleteWithError(kErrorMalformedParameters); |
641 return; | 663 return; |
642 } | 664 } |
643 | 665 |
644 device->device()->IsochronousTransfer(direction, generic_transfer.endpoint, | 666 device->device()->IsochronousTransfer(direction, generic_transfer.endpoint, |
645 buffer, size, transfer.packets, transfer.packet_length, 0, base::Bind( | 667 buffer, size, packets, packet_length, 0, base::Bind( |
646 &UsbIsochronousTransferFunction::OnCompleted, this)); | 668 &UsbIsochronousTransferFunction::OnCompleted, this)); |
647 } | 669 } |
648 | 670 |
649 } // namespace extensions | 671 } // namespace extensions |
OLD | NEW |