[Wine-patches] [eterhack 04/23] usbhub.sys: Add MDL support to URB_FUNCTION_VENDOR_* handler.

Alexander Morozov =?iso-8859-1?q?amorozov_=CE=C1_etersoft=2Eru?=
Пт Июн 5 13:00:04 MSD 2009


---
 dlls/usbhub.sys/usbhub.c |   47 +++++++++++++++++++++++++++------------------
 1 files changed, 28 insertions(+), 19 deletions(-)

diff --git a/dlls/usbhub.sys/usbhub.c b/dlls/usbhub.sys/usbhub.c
index 2c5d936..2a1f00e 100644
--- a/dlls/usbhub.sys/usbhub.c
+++ b/dlls/usbhub.sys/usbhub.c
@@ -257,9 +257,18 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
                 libusb_device_handle *husb;
                 struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST *request =
                         &urb->u.UrbControlVendorClassRequest;
+                unsigned char *req_buf = request->TransferBuffer;
+                ULONG size = request->TransferBufferLength;
 
                 TRACE( "URB_FUNCTION_VENDOR_*\n" );
 
+                if (req_buf == NULL && request->TransferBufferMDL != NULL)
+                    req_buf = request->TransferBufferMDL->MappedSystemVa;
+                if (size && req_buf == NULL)
+                {
+                    status = STATUS_INVALID_PARAMETER;
+                    break;
+                }
                 if (!libusb_open( inst->dev, &husb ))
                 {
                     UCHAR req_type = request->RequestTypeReservedBits | (2 << 5);
@@ -270,17 +279,15 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
                         req_type |= 1;
                     else if (urb->u.UrbHeader.Function == URB_FUNCTION_VENDOR_ENDPOINT)
                         req_type |= 2;
-                    buf = HeapAlloc( GetProcessHeap(), 0,
-                            request->TransferBufferLength );
+                    buf = HeapAlloc( GetProcessHeap(), 0, size );
                     if (buf != NULL)
                     {
-                        memcpy( buf, request->TransferBuffer,
-                                request->TransferBufferLength );
+                        memcpy( buf, req_buf, size );
                         if (request->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
                             req_type |= (1 << 7);
                         ret = libusb_control_transfer( husb, req_type,
                                 request->Request, request->Value, request->Index,
-                                buf, request->TransferBufferLength, 1000 );
+                                buf, size, 1000 );
                         if (ret < 0)
                             ERR( "libusb_control_transfer: %d\n", ret );
                         else
@@ -288,10 +295,8 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
                             if (request->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
                             {
                                 request->TransferBufferLength =
-                                        (ret <= request->TransferBufferLength) ?
-                                        ret : request->TransferBufferLength;
-                                memcpy( request->TransferBuffer, buf,
-                                        request->TransferBufferLength );
+                                        (ret < size) ? ret : size;
+                                memcpy( req_buf, buf, request->TransferBufferLength );
                             }
                             status = STATUS_SUCCESS;
                         }
@@ -486,9 +491,18 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
                 usb_dev_handle *husb;
                 struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST *request =
                         &urb->u.UrbControlVendorClassRequest;
+                unsigned char *req_buf = request->TransferBuffer;
+                ULONG size = request->TransferBufferLength;
 
                 TRACE( "URB_FUNCTION_VENDOR_*\n" );
 
+                if (req_buf == NULL && request->TransferBufferMDL != NULL)
+                    req_buf = request->TransferBufferMDL->MappedSystemVa;
+                if (size && req_buf == NULL)
+                {
+                    status = STATUS_INVALID_PARAMETER;
+                    break;
+                }
                 husb = usb_open( inst->dev );
                 if (husb)
                 {
@@ -500,17 +514,14 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
                         req_type |= 1;
                     else if (urb->u.UrbHeader.Function == URB_FUNCTION_VENDOR_ENDPOINT)
                         req_type |= 2;
-                    buf = HeapAlloc( GetProcessHeap(), 0,
-                            request->TransferBufferLength );
+                    buf = HeapAlloc( GetProcessHeap(), 0, size );
                     if (buf != NULL)
                     {
-                        memcpy( buf, request->TransferBuffer,
-                                request->TransferBufferLength );
+                        memcpy( buf, req_buf, size );
                         if (request->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
                             req_type |= (1 << 7);
                         ret = usb_control_msg( husb, req_type, request->Request,
-                                request->Value, request->Index, buf,
-                                request->TransferBufferLength, 1000 );
+                                request->Value, request->Index, buf, size, 1000 );
                         if (ret < 0)
                             ERR( "%s\n", usb_strerror() );
                         else
@@ -518,10 +529,8 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
                             if (request->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
                             {
                                 request->TransferBufferLength =
-                                        (ret <= request->TransferBufferLength) ?
-                                        ret : request->TransferBufferLength;
-                                memcpy( request->TransferBuffer, buf,
-                                        request->TransferBufferLength );
+                                        (ret < size) ? ret : size;
+                                memcpy( req_buf, buf, request->TransferBufferLength );
                             }
                             status = STATUS_SUCCESS;
                         }
-- 
1.6.3.1



Подробная информация о списке рассылки Wine-patches