aboutsummaryrefslogtreecommitdiffstats
path: root/LUFA
diff options
context:
space:
mode:
authorDean Camera <dean@fourwalledcubicle.com>2009-08-31 07:48:32 +0000
committerDean Camera <dean@fourwalledcubicle.com>2009-08-31 07:48:32 +0000
commit7fbb75928749b74a0964ad159159066967191243 (patch)
treeac8533e4dcd4853c6a6f55f08a2e01d73ae3bf72 /LUFA
parent813e6f0318090135c652eb7348b154576faa680c (diff)
downloadlufa-7fbb75928749b74a0964ad159159066967191243.tar.gz
lufa-7fbb75928749b74a0964ad159159066967191243.tar.bz2
lufa-7fbb75928749b74a0964ad159159066967191243.zip
Changed the parameters and behaviour of the USB_GetDeviceConfigDescriptor() function so that it now performs size checks and data validations internally, to simplify user code.
Diffstat (limited to 'LUFA')
-rw-r--r--LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c39
-rw-r--r--LUFA/Drivers/USB/HighLevel/ConfigDescriptor.h36
-rw-r--r--LUFA/ManPages/ChangeLog.txt2
-rw-r--r--LUFA/ManPages/MigrationInformation.txt6
4 files changed, 54 insertions, 29 deletions
diff --git a/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c b/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c
index 47982b806..4c6fbfdab 100644
--- a/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c
+++ b/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c
@@ -31,9 +31,11 @@
#include "ConfigDescriptor.h"
#if defined(USB_CAN_BE_HOST)
-uint8_t USB_GetDeviceConfigDescriptor(uint8_t ConfigNumber, uint16_t* const ConfigSizePtr, void* BufferPtr)
+uint8_t USB_GetDeviceConfigDescriptor(uint8_t ConfigNumber, uint16_t* const ConfigSizePtr,
+ void* BufferPtr, uint16_t BufferSize)
{
uint8_t ErrorCode;
+ uint8_t ConfigHeader[sizeof(USB_Descriptor_Configuration_Header_t)];
USB_ControlRequest = (USB_Request_Header_t)
{
@@ -46,26 +48,27 @@ uint8_t USB_GetDeviceConfigDescriptor(uint8_t ConfigNumber, uint16_t* const Conf
Pipe_SelectPipe(PIPE_CONTROLPIPE);
- if (BufferPtr == NULL)
- {
- uint8_t ConfigHeader[sizeof(USB_Descriptor_Configuration_Header_t)];
+ if ((ErrorCode = USB_Host_SendControlRequest(ConfigHeader)) != HOST_SENDCONTROL_Successful)
+ return ErrorCode;
- ErrorCode = USB_Host_SendControlRequest(ConfigHeader);
+ #if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES)
+ *ConfigSizePtr = DESCRIPTOR_CAST(ConfigHeader, USB_Descriptor_Configuration_Header_t).TotalConfigurationSize;
+ #else
+ *ConfigSizePtr = DESCRIPTOR_CAST(ConfigHeader, USB_Descriptor_Configuration_Header_t).wTotalLength;
+ #endif
- #if defined(USE_NONSTANDARD_DESCRIPTOR_NAMES)
- *ConfigSizePtr = DESCRIPTOR_CAST(ConfigHeader, USB_Descriptor_Configuration_Header_t).TotalConfigurationSize;
- #else
- *ConfigSizePtr = DESCRIPTOR_CAST(ConfigHeader, USB_Descriptor_Configuration_Header_t).wTotalLength;
- #endif
- }
- else
- {
- USB_ControlRequest.wLength = *ConfigSizePtr;
-
- ErrorCode = USB_Host_SendControlRequest(BufferPtr);
- }
+ if (*ConfigSizePtr > BufferSize)
+ return HOST_GETCONFIG_BuffOverflow;
+
+ USB_ControlRequest.wLength = *ConfigSizePtr;
+
+ if ((ErrorCode = USB_Host_SendControlRequest(BufferPtr)) != HOST_SENDCONTROL_Successful)
+ return ErrorCode;
- return ErrorCode;
+ if (DESCRIPTOR_TYPE(BufferPtr) != DTYPE_Configuration)
+ return HOST_GETCONFIG_InvalidData;
+
+ return HOST_GETCONFIG_Successful;
}
#endif
diff --git a/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.h b/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.h
index a9b0b1423..8c4e2c2db 100644
--- a/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.h
+++ b/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.h
@@ -163,6 +163,23 @@
uint8_t USB_GetNextDescriptorComp(uint16_t* BytesRem, uint8_t** CurrConfigLoc, ConfigComparatorPtr_t ComparatorRoutine);
/* Enums: */
+ enum USB_Host_GetConfigDescriptor_ErrorCodes_t
+ {
+ HOST_GETCONFIG_Successful = 0, /**< No error occurred while retrieving the configuration descriptor */
+ HOST_GETCONFIG_DeviceDisconnect = 1, /**< The attached device was disconnected while retrieving the configuration
+ * descriptor
+ */
+ HOST_GETCONFIG_PipeError = 2, /**< An error occurred in the pipe while sending the request */
+ HOST_GETCONFIG_SetupStalled = 3, /**< The attached device stalled the request to retrieve the configuration
+ * descriptor
+ */
+ HOST_GETCONFIG_SoftwareTimeOut = 4, /**< The request or data transfer timed out */
+ HOST_GETCONFIG_BuffOverflow = 5, /**< The device's configuration descriptor is too large to fit into the allocated
+ * buffer
+ */
+ HOST_GETCONFIG_InvalidData = 6, /**< The device returned invalid configuration descriptor data */
+ };
+
/** Enum for return values of a descriptor comparator function. */
enum DSearch_Return_ErrorCodes_t
{
@@ -181,22 +198,19 @@
};
/* Function Prototypes: */
- /** Retrieves the configuration descriptor data or size from an attached device via a standard request.
+ /** Retrieves the configuration descriptor data from an attached device via a standard request into a buffer,
+ * including validity and size checking to prevent a buffer overflow.
*
* \param[in] ConfigNumber Device configuration descriptor number to fetch from the device (usually set to 1 for
* single configuration devices)
+ * \param[in,out] ConfigSizePtr Pointer to a uint16_t for storing the retrieved configuration descriptor size
+ * \param[out] BufferPtr Pointer to the buffer for storing the configuration descriptor data.
+ * \param[out] BufferSize Size of the allocated buffer where the configuration descriptor is to be stored
*
- * \param[in,out] ConfigSizePtr Pointer to a uint16_t for either storing or retrieving the configuration
- * descriptor size
- *
- * \param[out] BufferPtr Pointer to the buffer for storing the configuration descriptor data. If this is
- * NULL, the size of the configuration descriptor will be retrieved instead and
- * placed in the variable pointed to by ConfigSizePtr. If this is non-NULL, the number
- * of bytes indicated by ConfigSizePtr of the configuration descriptor will be loaded
- * into the buffer
+ * \return A value from the \ref USB_Host_GetConfigDescriptor_ErrorCodes_t enum
*/
- uint8_t USB_GetDeviceConfigDescriptor(uint8_t ConfigNumber, uint16_t* const ConfigSizePtr, void* BufferPtr)
- ATTR_NON_NULL_PTR_ARG(2);
+ uint8_t USB_GetDeviceConfigDescriptor(uint8_t ConfigNumber, uint16_t* const ConfigSizePtr, void* BufferPtr,
+ uint16_t BufferSize) ATTR_NON_NULL_PTR_ARG(2, 3);
/** Skips to the next sub-descriptor inside the configuration descriptor of the specified type value.
* The bytes remaining value is automatically decremented.
diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt
index 8530f705f..1750bfaeb 100644
--- a/LUFA/ManPages/ChangeLog.txt
+++ b/LUFA/ManPages/ChangeLog.txt
@@ -29,6 +29,8 @@
* - Added new "Common" section to the class drivers, to hold all mode-independant definitions for clarity
* - Moved SCSI command/sense constants into the Mass Storage Class driver, instead of the user-code
* - Altered the SCSI commands in the LowLevel Mass Storage Host to save on FLASH space by reducing function calls
+ * - Changed the parameters and behaviour of the USB_GetDeviceConfigDescriptor() function so that it now performs size checks
+ * and data validations internally, to simplify user code
*
* <b>Fixed:</b>
* - Fixed possible lockup in the CDC device class driver, when the host sends data that is a multiple of the
diff --git a/LUFA/ManPages/MigrationInformation.txt b/LUFA/ManPages/MigrationInformation.txt
index d83043182..9527a373c 100644
--- a/LUFA/ManPages/MigrationInformation.txt
+++ b/LUFA/ManPages/MigrationInformation.txt
@@ -19,6 +19,12 @@
* - The SPI_Init() routine's parameters have changed, so that the clock polarity and data sampling modes can be set. See
* the SPI_Init() function documentation for more details
*
+ * <b>Host Mode</b>
+ * - The \ref USB_GetDeviceConfigDescriptor() function's parameters and behaviour has changed; the user is required to
+ * preallocate the largest allowable buffer, and pass the size of the buffer to the function. This allows for a single
+ * call to the function to retrieve, size check and validate the Configuration Descriptor rather than having the user
+ * application perform these intermediatary steps.
+ *
* \section Sec_Migration090810 Migrating from 090605 to 090810
*
* <b>All</b>