diff --git a/Demos/Host/ClassDriver/CDCHost/CDCHost.c b/Demos/Host/ClassDriver/CDCHost/CDCHost.c
index 7aa8deeeeb8c24aece537683320e495f6b3a4a35..4f67f3fbeb24f94a9e57c6de43714769680f88c2 100644
--- a/Demos/Host/ClassDriver/CDCHost/CDCHost.c
+++ b/Demos/Host/ClassDriver/CDCHost/CDCHost.c
@@ -72,9 +72,8 @@ int main(void)
 				uint16_t ConfigDescriptorSize;
 				uint8_t  ConfigDescriptorData[512];
 
-				if ((USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful) ||
-				    (ConfigDescriptorSize > sizeof(ConfigDescriptorData)) ||
-					(USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData)))
+				if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
+				                                  sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
 				{
 					printf("Error Retrieving Configuration Descriptor.\r\n");
 					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
diff --git a/Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.c b/Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.c
index c9120d596b76442d8d67684697d1e77ea3c8b155..d22e074008912f7b63e0ca44812701d69138a978 100644
--- a/Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.c
+++ b/Demos/Host/ClassDriver/MassStorageHost/MassStorageHost.c
@@ -71,9 +71,8 @@ int main(void)
 				uint16_t ConfigDescriptorSize;
 				uint8_t  ConfigDescriptorData[512];
 
-				if ((USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful) ||
-				    (ConfigDescriptorSize > sizeof(ConfigDescriptorData)) ||
-					(USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData)))
+				if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
+				                                  sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
 				{
 					printf("Error Retrieving Configuration Descriptor.\r\n");
 					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
diff --git a/Demos/Host/ClassDriver/MouseHost/MouseHost.c b/Demos/Host/ClassDriver/MouseHost/MouseHost.c
index 9f76bc754b2eb02548f081398d68b9646a90b967..844fa334c05fdb4efc2ac5a5def4d40e26456ac4 100644
--- a/Demos/Host/ClassDriver/MouseHost/MouseHost.c
+++ b/Demos/Host/ClassDriver/MouseHost/MouseHost.c
@@ -73,9 +73,8 @@ int main(void)
 				uint16_t ConfigDescriptorSize;
 				uint8_t  ConfigDescriptorData[512];
 
-				if ((USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful) ||
-				    (ConfigDescriptorSize > sizeof(ConfigDescriptorData)) ||
-					(USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData)))
+				if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
+				                                  sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
 				{
 					printf("Error Retrieving Configuration Descriptor.\r\n");
 					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
diff --git a/Demos/Host/ClassDriver/StillImageHost/StillImageHost.c b/Demos/Host/ClassDriver/StillImageHost/StillImageHost.c
index 2f0e5a2d1fe607f79289769bd11ca596b6793798..deb8a5504763edb770570499728c219e83d70a7b 100644
--- a/Demos/Host/ClassDriver/StillImageHost/StillImageHost.c
+++ b/Demos/Host/ClassDriver/StillImageHost/StillImageHost.c
@@ -72,9 +72,8 @@ int main(void)
 				uint16_t ConfigDescriptorSize;
 				uint8_t  ConfigDescriptorData[512];
 
-				if ((USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful) ||
-				    (ConfigDescriptorSize > sizeof(ConfigDescriptorData)) ||
-					(USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData)))
+				if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
+				                                  sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
 				{
 					printf("Error Retrieving Configuration Descriptor.\r\n");
 					LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
diff --git a/Demos/Host/Incomplete/BluetoothHost/ConfigDescriptor.c b/Demos/Host/Incomplete/BluetoothHost/ConfigDescriptor.c
index 948c4fcc65df04fd826002bb0a9cc0e8b65cfcdd..f856262d67f694f4645465764e55eb1ebc304bae 100644
--- a/Demos/Host/Incomplete/BluetoothHost/ConfigDescriptor.c
+++ b/Demos/Host/Incomplete/BluetoothHost/ConfigDescriptor.c
@@ -32,34 +32,30 @@
 
 uint8_t ProcessConfigurationDescriptor(void)
 {
-	uint8_t* ConfigDescriptorData;
-	uint16_t ConfigDescriptorSize;
+	uint8_t  ConfigDescriptorData[512];
+	uint8_t* CurrConfigLocation = ConfigDescriptorData;
+	uint16_t CurrConfigBytesRem;
 	uint8_t  FoundEndpoints = 0;
-	
-	/* Get Configuration Descriptor size from the device */
-	if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful)
-	  return ControlErrorDuringConfigRead;
-	
-	/* Ensure that the Configuration Descriptor isn't too large */
-	if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE)
-	  return DescriptorTooLarge;
-	  
-	/* Allocate enough memory for the entire config descriptor */
-	ConfigDescriptorData = alloca(ConfigDescriptorSize);
 
 	/* Retrieve the entire configuration descriptor into the allocated buffer */
-	USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData);
+	switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
+	{
+		case HOST_GETCONFIG_Successful:
+			break;
+		case HOST_GETCONFIG_InvalidData:
+			return InvalidConfigDataReturned;
+		case HOST_GETCONFIG_BuffOverflow:
+			return DescriptorTooLarge;
+		default:
+			return ControlErrorDuringConfigRead;
+	}
 	
-	/* Validate returned data - ensure first entry is a configuration header descriptor */
-	if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
-	  return InvalidConfigDataReturned;
-
 	/* The bluetooth USB transport addendium mandates that the data (not streaming voice) endpoints
 	   be in the first interface descriptor (interface 0) */
-	USB_GetNextDescriptorOfType(&ConfigDescriptorSize, &ConfigDescriptorData, DTYPE_Interface);
+	USB_GetNextDescriptorOfType(&CurrConfigBytesRem, &CurrConfigLocation, DTYPE_Interface);
 	
 	/* Ensure that an interface was found, and the end of the descriptor was not reached */
-	if (!(ConfigDescriptorSize))
+	if (!(CurrConfigBytesRem))
 	  return NoInterfaceFound;
 
 	/* Get the data IN, data OUT and event notification endpoints for the bluetooth interface */
@@ -67,8 +63,8 @@ uint8_t ProcessConfigurationDescriptor(void)
 	                          (1 << BLUETOOTH_EVENTS_PIPE)))
 	{
 		/* Fetch the next endpoint from the current bluetooth interface */
-		if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
-		                                   NextInterfaceBluetoothDataEndpoint))
+		if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
+		                              NextInterfaceBluetoothDataEndpoint))
 		{
 			/* Descriptor not found, error out */
 			return NoEndpointFound;
diff --git a/Demos/Host/Incomplete/BluetoothHost/DeviceDescriptor.c b/Demos/Host/Incomplete/BluetoothHost/DeviceDescriptor.c
index f68f957c01e30b149b769f2cd777274e9a7fd141..99435210871e640b71ec8856aac0930d22a0b0e8 100644
--- a/Demos/Host/Incomplete/BluetoothHost/DeviceDescriptor.c
+++ b/Demos/Host/Incomplete/BluetoothHost/DeviceDescriptor.c
@@ -41,7 +41,8 @@ uint8_t ProcessDeviceDescriptor(void)
 	/* Validate returned data - ensure the returned data is a device descriptor */
 	if (DeviceDescriptor.Header.Type != DTYPE_Device)
 	  return InvalidDeviceDataReturned;
-	  
+	
+	/* Validate returned device Class, SubClass and Protocol values against the Bluetooth spec values */
 	if ((DeviceDescriptor.Class    != BLUETOOTH_DEVICE_CLASS)    ||
 	    (DeviceDescriptor.SubClass != BLUETOOTH_DEVICE_SUBCLASS) ||
 	    (DeviceDescriptor.Protocol != BLUETOOTH_DEVICE_PROTOCOL))
diff --git a/Demos/Host/LowLevel/CDCHost/ConfigDescriptor.c b/Demos/Host/LowLevel/CDCHost/ConfigDescriptor.c
index f1a57cd74030d3c9655ff170094a3ce5e629133e..f9671e2b3deb306a35213aee7994ac1442179df9 100644
--- a/Demos/Host/LowLevel/CDCHost/ConfigDescriptor.c
+++ b/Demos/Host/LowLevel/CDCHost/ConfigDescriptor.c
@@ -47,30 +47,26 @@
  */
 uint8_t ProcessConfigurationDescriptor(void)
 {
-	uint8_t* ConfigDescriptorData;
-	uint16_t ConfigDescriptorSize;
+	uint8_t  ConfigDescriptorData[512];
+	uint8_t* CurrConfigLocation = ConfigDescriptorData;
+	uint16_t CurrConfigBytesRem;
 	uint8_t  FoundEndpoints = 0;
-	
-	/* Get Configuration Descriptor size from the device */
-	if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful)
-	  return ControlError;
-	
-	/* Ensure that the Configuration Descriptor isn't too large */
-	if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE)
-	  return DescriptorTooLarge;
-	  
-	/* Allocate enough memory for the entire config descriptor */
-	ConfigDescriptorData = alloca(ConfigDescriptorSize);
 
 	/* Retrieve the entire configuration descriptor into the allocated buffer */
-	USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData);
-	
-	/* Validate returned data - ensure first entry is a configuration header descriptor */
-	if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
-	  return InvalidConfigDataReturned;
+	switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
+	{
+		case HOST_GETCONFIG_Successful:
+			break;
+		case HOST_GETCONFIG_InvalidData:
+			return InvalidConfigDataReturned;
+		case HOST_GETCONFIG_BuffOverflow:
+			return DescriptorTooLarge;
+		default:
+			return ControlError;
+	}
 	
 	/* Get the CDC control interface from the configuration descriptor */
-	if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+	if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
 	                              DComp_NextCDCControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
 	{
 		/* Descriptor not found, error out */
@@ -81,14 +77,14 @@ uint8_t ProcessConfigurationDescriptor(void)
 	while (FoundEndpoints != ((1 << CDC_NOTIFICATIONPIPE) | (1 << CDC_DATAPIPE_IN) | (1 << CDC_DATAPIPE_OUT)))
 	{
 		/* Fetch the next bulk or interrupt endpoint from the current CDC interface */
-		if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+		if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
 		                              DComp_NextInterfaceCDCDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
 		{
 			/* Check to see if the control interface's notification pipe has been found, if so search for the data interface */
 			if (FoundEndpoints & (1 << CDC_NOTIFICATIONPIPE))
 			{
 				/* Get the next CDC data interface from the configuration descriptor (CDC class has two CDC interfaces) */
-				if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, 
+				if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, 
 				                              DComp_NextCDCDataInterface) != DESCRIPTOR_SEARCH_COMP_Found)
 				{
 					/* Descriptor not found, error out */
@@ -109,7 +105,7 @@ uint8_t ProcessConfigurationDescriptor(void)
 				Pipe_DisablePipe();
 			
 				/* Get the next CDC control interface from the configuration descriptor (CDC class has two CDC interfaces) */
-				if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+				if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
 				                              DComp_NextCDCControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
 				{
 					/* Descriptor not found, error out */
@@ -118,7 +114,7 @@ uint8_t ProcessConfigurationDescriptor(void)
 			}
 
 			/* Fetch the next bulk or interrupt endpoint from the current CDC interface */
-			if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+			if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
 			                              DComp_NextInterfaceCDCDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
 			{
 				/* Descriptor not found, error out */
diff --git a/Demos/Host/LowLevel/GenericHIDHost/ConfigDescriptor.c b/Demos/Host/LowLevel/GenericHIDHost/ConfigDescriptor.c
index dbec62b637ed1f436d299d47571b977ea6807e8f..dba62fd06dfc9a3590808144b47e26daf786ff7d 100644
--- a/Demos/Host/LowLevel/GenericHIDHost/ConfigDescriptor.c
+++ b/Demos/Host/LowLevel/GenericHIDHost/ConfigDescriptor.c
@@ -47,31 +47,26 @@
  */
 uint8_t ProcessConfigurationDescriptor(void)
 {
-	uint8_t* ConfigDescriptorData;
-	uint16_t ConfigDescriptorSize;
-	
+	uint8_t  ConfigDescriptorData[512];
+	uint8_t* CurrConfigLocation = ConfigDescriptorData;
+	uint16_t CurrConfigBytesRem;
 	uint8_t  FoundEndpoints = 0;
-	
-	/* Get Configuration Descriptor size from the device */
-	if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful)
-	  return ControlError;
-	
-	/* Ensure that the Configuration Descriptor isn't too large */
-	if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE)
-	  return DescriptorTooLarge;
-	  
-	/* Allocate enough memory for the entire config descriptor */
-	ConfigDescriptorData = alloca(ConfigDescriptorSize);
 
 	/* Retrieve the entire configuration descriptor into the allocated buffer */
-	USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData);
-	
-	/* Validate returned data - ensure first entry is a configuration header descriptor */
-	if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
-	  return InvalidConfigDataReturned;
+	switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
+	{
+		case HOST_GETCONFIG_Successful:
+			break;
+		case HOST_GETCONFIG_InvalidData:
+			return InvalidConfigDataReturned;
+		case HOST_GETCONFIG_BuffOverflow:
+			return DescriptorTooLarge;
+		default:
+			return ControlError;
+	}
 	
 	/* Get the HID interface from the configuration descriptor */
-	if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+	if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
 	                              DComp_NextHIDInterface) != DESCRIPTOR_SEARCH_COMP_Found)
 	{
 		/* Descriptor not found, error out */
@@ -81,7 +76,7 @@ uint8_t ProcessConfigurationDescriptor(void)
 	while (FoundEndpoints != ((1 << HID_DATA_IN_PIPE) | (1 << HID_DATA_OUT_PIPE)))
 	{
 		/* Get the next HID interface's data endpoint descriptor */
-		if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+		if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
 		                              DComp_NextInterfaceHIDDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
 		{
 			/* Not all HID devices have an OUT endpoint - if we've reached the end of the HID descriptor
diff --git a/Demos/Host/LowLevel/KeyboardHost/ConfigDescriptor.c b/Demos/Host/LowLevel/KeyboardHost/ConfigDescriptor.c
index 4033060429f319862a80722e2d1c69ba3dce4aec..46fb94ee2c7f867e24b205d623736e84522dab21 100644
--- a/Demos/Host/LowLevel/KeyboardHost/ConfigDescriptor.c
+++ b/Demos/Host/LowLevel/KeyboardHost/ConfigDescriptor.c
@@ -47,29 +47,25 @@
  */
 uint8_t ProcessConfigurationDescriptor(void)
 {
-	uint8_t* ConfigDescriptorData;
-	uint16_t ConfigDescriptorSize;
-	
-	/* Get Configuration Descriptor size from the device */
-	if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful)
-	  return ControlError;
-	
-	/* Ensure that the Configuration Descriptor isn't too large */
-	if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE)
-	  return DescriptorTooLarge;
-	  
-	/* Allocate enough memory for the entire config descriptor */
-	ConfigDescriptorData = alloca(ConfigDescriptorSize);
+	uint8_t  ConfigDescriptorData[512];
+	uint8_t* CurrConfigLocation = ConfigDescriptorData;
+	uint16_t CurrConfigBytesRem;
 
 	/* Retrieve the entire configuration descriptor into the allocated buffer */
-	USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData);
-	
-	/* Validate returned data - ensure first entry is a configuration header descriptor */
-	if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
-	  return InvalidConfigDataReturned;
+	switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
+	{
+		case HOST_GETCONFIG_Successful:
+			break;
+		case HOST_GETCONFIG_InvalidData:
+			return InvalidConfigDataReturned;
+		case HOST_GETCONFIG_BuffOverflow:
+			return DescriptorTooLarge;
+		default:
+			return ControlError;
+	}
 	
 	/* Get the keyboard interface from the configuration descriptor */
-	if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+	if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
 	                              DComp_NextKeyboardInterface) != DESCRIPTOR_SEARCH_COMP_Found)
 	{
 		/* Descriptor not found, error out */
@@ -77,7 +73,7 @@ uint8_t ProcessConfigurationDescriptor(void)
 	}
 
 	/* Get the keyboard interface's data endpoint descriptor */
-	if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+	if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
 	                              DComp_NextInterfaceKeyboardDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
 	{
 		/* Descriptor not found, error out */
diff --git a/Demos/Host/LowLevel/KeyboardHostWithParser/ConfigDescriptor.c b/Demos/Host/LowLevel/KeyboardHostWithParser/ConfigDescriptor.c
index d9fd50f692cdd0b80084e5e9c295fe461360e5c0..7ab0a1887d14e8657ec892f50340312dd3185784 100644
--- a/Demos/Host/LowLevel/KeyboardHostWithParser/ConfigDescriptor.c
+++ b/Demos/Host/LowLevel/KeyboardHostWithParser/ConfigDescriptor.c
@@ -47,29 +47,25 @@
  */
 uint8_t ProcessConfigurationDescriptor(void)
 {
-	uint8_t* ConfigDescriptorData;
-	uint16_t ConfigDescriptorSize;
-	
-	/* Get Configuration Descriptor size from the device */
-	if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful)
-	  return ControlError;
-	
-	/* Ensure that the Configuration Descriptor isn't too large */
-	if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE)
-	  return DescriptorTooLarge;
-	  
-	/* Allocate enough memory for the entire config descriptor */
-	ConfigDescriptorData = alloca(ConfigDescriptorSize);
+	uint8_t  ConfigDescriptorData[512];
+	uint8_t* CurrConfigLocation = ConfigDescriptorData;
+	uint16_t CurrConfigBytesRem;
 
 	/* Retrieve the entire configuration descriptor into the allocated buffer */
-	USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData);
-	
-	/* Validate returned data - ensure first entry is a configuration header descriptor */
-	if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
-	  return InvalidConfigDataReturned;
+	switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
+	{
+		case HOST_GETCONFIG_Successful:
+			break;
+		case HOST_GETCONFIG_InvalidData:
+			return InvalidConfigDataReturned;
+		case HOST_GETCONFIG_BuffOverflow:
+			return DescriptorTooLarge;
+		default:
+			return ControlError;
+	}
 	
 	/* Get the keyboard interface from the configuration descriptor */
-	if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+	if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
 	                              DComp_NextKeyboardInterface) != DESCRIPTOR_SEARCH_COMP_Found)
 	{
 		/* Descriptor not found, error out */
@@ -77,7 +73,7 @@ uint8_t ProcessConfigurationDescriptor(void)
 	}
 	
 	/* Get the keyboard interface's HID descriptor */
-	if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+	if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
 	                              DComp_NextHID) != DESCRIPTOR_SEARCH_COMP_Found)
 	{
 		/* Descriptor not found, error out */
@@ -88,7 +84,7 @@ uint8_t ProcessConfigurationDescriptor(void)
 	HIDReportSize = DESCRIPTOR_CAST(ConfigDescriptorData, USB_Descriptor_HID_t).HIDReportLength;
 
 	/* Get the keyboard interface's data endpoint descriptor */
-	if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+	if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
 	                              DComp_NextInterfaceKeyboardDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
 	{
 		/* Descriptor not found, error out */
diff --git a/Demos/Host/LowLevel/MassStorageHost/ConfigDescriptor.c b/Demos/Host/LowLevel/MassStorageHost/ConfigDescriptor.c
index 9f80b42eeb5742333d9ab92a013d1c6b7e29611e..1ba3244ed7ec7eb0ca71b97902e2673aa89485fe 100644
--- a/Demos/Host/LowLevel/MassStorageHost/ConfigDescriptor.c
+++ b/Demos/Host/LowLevel/MassStorageHost/ConfigDescriptor.c
@@ -47,30 +47,26 @@
  */
 uint8_t ProcessConfigurationDescriptor(void)
 {
-	uint8_t* ConfigDescriptorData;
-	uint16_t ConfigDescriptorSize;
-	uint8_t  FoundEndpoints = 0;
-	
-	/* Get Configuration Descriptor size from the device */
-	if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful)
-	  return ControlError;
-	
-	/* Ensure that the Configuration Descriptor isn't too large */
-	if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE)
-	  return DescriptorTooLarge;
-	  
-	/* Allocate enough memory for the entire config descriptor */
-	ConfigDescriptorData = alloca(ConfigDescriptorSize);
+	uint8_t  ConfigDescriptorData[512];
+	uint8_t* CurrConfigLocation = ConfigDescriptorData;
+	uint16_t CurrConfigBytesRem;
+	uint8_t  FoundEndpoints     = 0;
 
 	/* Retrieve the entire configuration descriptor into the allocated buffer */
-	USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData);
-	
-	/* Validate returned data - ensure first entry is a configuration header descriptor */
-	if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
-	  return InvalidConfigDataReturned;
+	switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
+	{
+		case HOST_GETCONFIG_Successful:
+			break;
+		case HOST_GETCONFIG_InvalidData:
+			return InvalidConfigDataReturned;
+		case HOST_GETCONFIG_BuffOverflow:
+			return DescriptorTooLarge;
+		default:
+			return ControlError;
+	}
 	
 	/* Get the mass storage interface from the configuration descriptor */
-	if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+	if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
 	                              DComp_NextMassStorageInterface) != DESCRIPTOR_SEARCH_COMP_Found)
 	{
 		/* Descriptor not found, error out */
@@ -81,7 +77,7 @@ uint8_t ProcessConfigurationDescriptor(void)
 	while (FoundEndpoints != ((1 << MASS_STORE_DATA_IN_PIPE) | (1 << MASS_STORE_DATA_OUT_PIPE)))
 	{
 		/* Fetch the next bulk endpoint from the current mass storage interface */
-		if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+		if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
 		                              DComp_NextInterfaceBulkDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
 		{
 			/* Descriptor not found, error out */
diff --git a/Demos/Host/LowLevel/MouseHost/ConfigDescriptor.c b/Demos/Host/LowLevel/MouseHost/ConfigDescriptor.c
index e0be70b1b5a2ef407f30eef702210e4f62b36e75..912f146bc6973740a711345ec14d627bfd36334b 100644
--- a/Demos/Host/LowLevel/MouseHost/ConfigDescriptor.c
+++ b/Demos/Host/LowLevel/MouseHost/ConfigDescriptor.c
@@ -47,29 +47,25 @@
  */
 uint8_t ProcessConfigurationDescriptor(void)
 {
-	uint8_t* ConfigDescriptorData;
-	uint16_t ConfigDescriptorSize;
-	
-	/* Get Configuration Descriptor size from the device */
-	if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful)
-	  return ControlError;
-	
-	/* Ensure that the Configuration Descriptor isn't too large */
-	if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE)
-	  return DescriptorTooLarge;
-	  
-	/* Allocate enough memory for the entire config descriptor */
-	ConfigDescriptorData = alloca(ConfigDescriptorSize);
+	uint8_t  ConfigDescriptorData[512];
+	uint8_t* CurrConfigLocation = ConfigDescriptorData;
+	uint16_t CurrConfigBytesRem;
 
 	/* Retrieve the entire configuration descriptor into the allocated buffer */
-	USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData);
-	
-	/* Validate returned data - ensure first entry is a configuration header descriptor */
-	if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
-	  return InvalidConfigDataReturned;
+	switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
+	{
+		case HOST_GETCONFIG_Successful:
+			break;
+		case HOST_GETCONFIG_InvalidData:
+			return InvalidConfigDataReturned;
+		case HOST_GETCONFIG_BuffOverflow:
+			return DescriptorTooLarge;
+		default:
+			return ControlError;
+	}
 	
 	/* Get the mouse interface from the configuration descriptor */
-	if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+	if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
 	                              DComp_NextMouseInterface) != DESCRIPTOR_SEARCH_COMP_Found)
 	{
 		/* Descriptor not found, error out */
@@ -77,7 +73,7 @@ uint8_t ProcessConfigurationDescriptor(void)
 	}
 
 	/* Get the mouse interface's data endpoint descriptor */
-	if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+	if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
 	                              DComp_NextInterfaceMouseDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
 	{
 		/* Descriptor not found, error out */
diff --git a/Demos/Host/LowLevel/MouseHostWithParser/ConfigDescriptor.c b/Demos/Host/LowLevel/MouseHostWithParser/ConfigDescriptor.c
index 1d28351ee2b6ec6cd76cdc8e14041c050d979423..fa06741188028a53893373e3954e2a722b31d246 100644
--- a/Demos/Host/LowLevel/MouseHostWithParser/ConfigDescriptor.c
+++ b/Demos/Host/LowLevel/MouseHostWithParser/ConfigDescriptor.c
@@ -47,29 +47,25 @@
  */
 uint8_t ProcessConfigurationDescriptor(void)
 {
-	uint8_t* ConfigDescriptorData;
-	uint16_t ConfigDescriptorSize;
-	
-	/* Get Configuration Descriptor size from the device */
-	if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful)
-	  return ControlError;
-	
-	/* Ensure that the Configuration Descriptor isn't too large */
-	if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE)
-	  return DescriptorTooLarge;
-	  
-	/* Allocate enough memory for the entire config descriptor */
-	ConfigDescriptorData = alloca(ConfigDescriptorSize);
+	uint8_t  ConfigDescriptorData[512];
+	uint8_t* CurrConfigLocation = ConfigDescriptorData;
+	uint16_t CurrConfigBytesRem;
 
 	/* Retrieve the entire configuration descriptor into the allocated buffer */
-	USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData);
-	
-	/* Validate returned data - ensure first entry is a configuration header descriptor */
-	if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
-	  return InvalidConfigDataReturned;
+	switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
+	{
+		case HOST_GETCONFIG_Successful:
+			break;
+		case HOST_GETCONFIG_InvalidData:
+			return InvalidConfigDataReturned;
+		case HOST_GETCONFIG_BuffOverflow:
+			return DescriptorTooLarge;
+		default:
+			return ControlError;
+	}
 	
 	/* Get the mouse interface from the configuration descriptor */
-	if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+	if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
 	                              DComp_NextMouseInterface) != DESCRIPTOR_SEARCH_COMP_Found)
 	{
 		/* Descriptor not found, error out */
@@ -77,7 +73,7 @@ uint8_t ProcessConfigurationDescriptor(void)
 	}
 	
 	/* Get the mouse interface's HID descriptor */
-	if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+	if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
 	                              DComp_NextHID) != DESCRIPTOR_SEARCH_COMP_Found)
 	{
 		/* Descriptor not found, error out */
@@ -88,7 +84,7 @@ uint8_t ProcessConfigurationDescriptor(void)
 	HIDReportSize = DESCRIPTOR_CAST(ConfigDescriptorData, USB_Descriptor_HID_t).HIDReportLength;
 
 	/* Get the mouse interface's data endpoint descriptor */
-	if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+	if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
 	                              DComp_NextInterfaceMouseDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
 	{
 		/* Descriptor not found, error out */
diff --git a/Demos/Host/LowLevel/PrinterHost/ConfigDescriptor.c b/Demos/Host/LowLevel/PrinterHost/ConfigDescriptor.c
index d4eaff94a1abc11e8cb3f8943318b6a155e08d7d..22d84c5aae530aaf7cde980a55df0bfd16da1e3d 100644
--- a/Demos/Host/LowLevel/PrinterHost/ConfigDescriptor.c
+++ b/Demos/Host/LowLevel/PrinterHost/ConfigDescriptor.c
@@ -36,32 +36,26 @@ uint8_t PrinterAltSetting;
 
 uint8_t ProcessConfigurationDescriptor(void)
 {
-	uint8_t* ConfigDescriptorData;
-	uint16_t ConfigDescriptorSize;
-	uint8_t  ErrorCode;
+	uint8_t  ConfigDescriptorData[512];
+	uint8_t* CurrConfigLocation = ConfigDescriptorData;
+	uint16_t CurrConfigBytesRem;
 	uint8_t  FoundEndpoints = 0;
-	
-	/* Get Configuration Descriptor size from the device */
-	if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful)
-	  return ControlError;
-	
-	/* Ensure that the Configuration Descriptor isn't too large */
-	if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE)
-	  return DescriptorTooLarge;
-	  
-	/* Allocate enough memory for the entire config descriptor */
-	ConfigDescriptorData = alloca(ConfigDescriptorSize);
 
 	/* Retrieve the entire configuration descriptor into the allocated buffer */
-	USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData);
-	
-	/* Validate returned data - ensure first entry is a configuration header descriptor */
-	if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
-	  return InvalidConfigDataReturned;
+	switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
+	{
+		case HOST_GETCONFIG_Successful:
+			break;
+		case HOST_GETCONFIG_InvalidData:
+			return InvalidConfigDataReturned;
+		case HOST_GETCONFIG_BuffOverflow:
+			return DescriptorTooLarge;
+		default:
+			return ControlError;
+	}
 	
 	/* Get the printer interface from the configuration descriptor */
-	if ((ErrorCode = USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
-	                                           DComp_NextBidirectionalPrinterInterface)))
+	if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextBidirectionalPrinterInterface))
 	{
 		/* Descriptor not found, error out */
 		return NoInterfaceFound;
@@ -74,8 +68,7 @@ uint8_t ProcessConfigurationDescriptor(void)
 	while (FoundEndpoints != ((1 << PRINTER_DATA_OUT_PIPE) | (1 << PRINTER_DATA_IN_PIPE)))
 	{
 		/* Fetch the next bulk endpoint from the current printer interface */
-		if ((ErrorCode = USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
-		                                           DComp_NextInterfaceBulkDataEndpoint)))
+		if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextInterfaceBulkDataEndpoint))
 		{
 			/* Descriptor not found, error out */
 			return NoEndpointFound;
diff --git a/Demos/Host/LowLevel/StillImageHost/ConfigDescriptor.c b/Demos/Host/LowLevel/StillImageHost/ConfigDescriptor.c
index a2d4d48dd2a47024c6ac6065ef733d77eb8ee64f..4e7751d710aad43d160d7b9c889a17a9089f6c38 100644
--- a/Demos/Host/LowLevel/StillImageHost/ConfigDescriptor.c
+++ b/Demos/Host/LowLevel/StillImageHost/ConfigDescriptor.c
@@ -47,30 +47,26 @@
  */
 uint8_t ProcessConfigurationDescriptor(void)
 {
-	uint8_t* ConfigDescriptorData;
-	uint16_t ConfigDescriptorSize;
+	uint8_t  ConfigDescriptorData[512];
+	uint8_t* CurrConfigLocation = ConfigDescriptorData;
+	uint16_t CurrConfigBytesRem;
 	uint8_t  FoundEndpoints = 0;
-	
-	/* Get Configuration Descriptor size from the device */
-	if (USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, NULL) != HOST_SENDCONTROL_Successful)
-	  return ControlError;
-	
-	/* Ensure that the Configuration Descriptor isn't too large */
-	if (ConfigDescriptorSize > MAX_CONFIG_DESCRIPTOR_SIZE)
-	  return DescriptorTooLarge;
-	  
-	/* Allocate enough memory for the entire config descriptor */
-	ConfigDescriptorData = alloca(ConfigDescriptorSize);
 
 	/* Retrieve the entire configuration descriptor into the allocated buffer */
-	USB_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData);
-	
-	/* Validate returned data - ensure first entry is a configuration header descriptor */
-	if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
-	  return InvalidConfigDataReturned;
+	switch (USB_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData)))
+	{
+		case HOST_GETCONFIG_Successful:
+			break;
+		case HOST_GETCONFIG_InvalidData:
+			return InvalidConfigDataReturned;
+		case HOST_GETCONFIG_BuffOverflow:
+			return DescriptorTooLarge;
+		default:
+			return ControlError;
+	}
 	
 	/* Get the Still Image interface from the configuration descriptor */
-	if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+	if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
 	                              DComp_NextStillImageInterface) != DESCRIPTOR_SEARCH_COMP_Found)
 	{
 		/* Descriptor not found, error out */
@@ -81,7 +77,7 @@ uint8_t ProcessConfigurationDescriptor(void)
 	while (FoundEndpoints != ((1 << SIMAGE_EVENTS_PIPE) | (1 << SIMAGE_DATA_IN_PIPE) | (1 << SIMAGE_DATA_OUT_PIPE)))
 	{
 		/* Fetch the next endpoint from the current Still Image interface */
-		if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
+		if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation,
 		                              DComp_NextStillImageInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
 		{
 			/* Descriptor not found, error out */
diff --git a/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c b/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c
index 47982b806c948fe85b427bfad5e441568c0008f9..4c6fbfdabe0a8b48280e91b7429ceca5d80fbbe4 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 a9b0b14230a1a2cd9dd3ea21a1f9ebaa2c7656ff..8c4e2c2db126eb62b2b5e5d889833070d8af151b 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 8530f705fe3ae708e74bbae48eadac0735625971..1750bfaeb93cc9dc486b905c42cbf81433598615 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 d83043182b33e823ef9f0ee46293bb633265a8bd..9527a373ce3e7217121344e11b0429276a2fd60b 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>