Zebediah Figura : wineusb.sys: Avoid hard-coding ID string lengths.

Alexandre Julliard julliard at winehq.org
Thu May 12 15:55:49 CDT 2022


Module: wine
Branch: master
Commit: 9f835268212de17bb4bd620b08796b29e09597ae
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=9f835268212de17bb4bd620b08796b29e09597ae

Author: Zebediah Figura <zfigura at codeweavers.com>
Date:   Wed May 11 19:01:48 2022 -0500

wineusb.sys: Avoid hard-coding ID string lengths.

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/wineusb.sys/wineusb.c | 83 ++++++++++++++++++++++++++++++++--------------
 1 file changed, 58 insertions(+), 25 deletions(-)

diff --git a/dlls/wineusb.sys/wineusb.c b/dlls/wineusb.sys/wineusb.c
index e0d4bab957d..261140165bc 100644
--- a/dlls/wineusb.sys/wineusb.c
+++ b/dlls/wineusb.sys/wineusb.c
@@ -300,30 +300,66 @@ static NTSTATUS fdo_pnp(IRP *irp)
     return IoCallDriver(bus_pdo, irp);
 }
 
-static void get_device_id(const struct usb_device *device, WCHAR *buffer)
+struct string_buffer
+{
+    WCHAR *string;
+    size_t len;
+};
+
+static void WINAPIV append_id(struct string_buffer *buffer, const WCHAR *format, ...)
+{
+    __ms_va_list args;
+    WCHAR *string;
+    int len;
+
+    __ms_va_start(args, format);
+
+    len = _vsnwprintf(NULL, 0, format, args) + 1;
+    if (!(string = ExAllocatePool(PagedPool, (buffer->len + len) * sizeof(WCHAR))))
+    {
+        if (buffer->string)
+            ExFreePool(buffer->string);
+        buffer->string = NULL;
+        return;
+    }
+    if (buffer->string)
+    {
+        memcpy(string, buffer->string, buffer->len * sizeof(WCHAR));
+        ExFreePool(buffer->string);
+    }
+    _vsnwprintf(string + buffer->len, len, format, args);
+    buffer->string = string;
+    buffer->len += len;
+
+    __ms_va_end(args);
+}
+
+static const WCHAR emptyW[] = {0};
+
+static void get_device_id(const struct usb_device *device, struct string_buffer *buffer)
 {
     static const WCHAR formatW[] = {'U','S','B','\\','V','I','D','_','%','0','4','X',
             '&','P','I','D','_','%','0','4','X',0};
     struct libusb_device_descriptor desc;
 
     libusb_get_device_descriptor(device->libusb_device, &desc);
-    sprintfW(buffer, formatW, desc.idVendor, desc.idProduct);
+    append_id(buffer, formatW, desc.idVendor, desc.idProduct);
 }
 
-static void get_hardware_ids(const struct usb_device *device, WCHAR *buffer)
+static void get_hardware_ids(const struct usb_device *device, struct string_buffer *buffer)
 {
     static const WCHAR formatW[] = {'U','S','B','\\','V','I','D','_','%','0','4','X',
                 '&','P','I','D','_','%','0','4','X','&','R','E','V','_','%','0','4','X',0};
     struct libusb_device_descriptor desc;
 
     libusb_get_device_descriptor(device->libusb_device, &desc);
-    buffer += sprintfW(buffer, formatW, desc.idVendor, desc.idProduct, desc.bcdDevice) + 1;
+
+    append_id(buffer, formatW, desc.idVendor, desc.idProduct, desc.bcdDevice);
     get_device_id(device, buffer);
-    buffer += strlenW(buffer) + 1;
-    *buffer = 0;
+    append_id(buffer, emptyW);
 }
 
-static void get_compatible_ids(const struct usb_device *device, WCHAR *buffer)
+static void get_compatible_ids(const struct usb_device *device, struct string_buffer *buffer)
 {
     static const WCHAR prot_format[] = {'U','S','B','\\','C','l','a','s','s','_','%','0','2','x',
             '&','S','u','b','C','l','a','s','s','_','%','0','2','x',
@@ -336,40 +372,34 @@ static void get_compatible_ids(const struct usb_device *device, WCHAR *buffer)
 
     libusb_get_device_descriptor(device->libusb_device, &device_desc);
 
-    buffer += sprintfW(buffer, prot_format, device_desc.bDeviceClass, device_desc.bDeviceSubClass,
-            device_desc.bDeviceProtocol) + 1;
-    buffer += sprintfW(buffer, subclass_format, device_desc.bDeviceClass, device_desc.bDeviceSubClass) + 1;
-    buffer += sprintfW(buffer, class_format, device_desc.bDeviceClass) + 1;
-    *buffer = 0;
+    append_id(buffer, prot_format, device_desc.bDeviceClass,
+            device_desc.bDeviceSubClass, device_desc.bDeviceProtocol);
+    append_id(buffer, subclass_format, device_desc.bDeviceClass, device_desc.bDeviceSubClass);
+    append_id(buffer, class_format, device_desc.bDeviceClass);
+    append_id(buffer, emptyW);
 }
 
 static NTSTATUS query_id(const struct usb_device *device, IRP *irp, BUS_QUERY_ID_TYPE type)
 {
-    WCHAR *id = NULL;
+    static const WCHAR instance_idW[] = {'0',0};
+    struct string_buffer buffer = {0};
 
     switch (type)
     {
         case BusQueryDeviceID:
-            if ((id = ExAllocatePool(PagedPool, 28 * sizeof(WCHAR))))
-                get_device_id(device, id);
+            get_device_id(device, &buffer);
             break;
 
         case BusQueryInstanceID:
-            if ((id = ExAllocatePool(PagedPool, 2 * sizeof(WCHAR))))
-            {
-                id[0] = '0';
-                id[1] = 0;
-            }
+            append_id(&buffer, instance_idW);
             break;
 
         case BusQueryHardwareIDs:
-            if ((id = ExAllocatePool(PagedPool, (28 + 37 + 1) * sizeof(WCHAR))))
-                get_hardware_ids(device, id);
+            get_hardware_ids(device, &buffer);
             break;
 
         case BusQueryCompatibleIDs:
-            if ((id = ExAllocatePool(PagedPool, (33 + 25 + 13 + 1) * sizeof(WCHAR))))
-                get_compatible_ids(device, id);
+            get_compatible_ids(device, &buffer);
             break;
 
         default:
@@ -377,7 +407,10 @@ static NTSTATUS query_id(const struct usb_device *device, IRP *irp, BUS_QUERY_ID
             return irp->IoStatus.Status;
     }
 
-    irp->IoStatus.Information = (ULONG_PTR)id;
+    if (!buffer.string)
+        return STATUS_NO_MEMORY;
+
+    irp->IoStatus.Information = (ULONG_PTR)buffer.string;
     return STATUS_SUCCESS;
 }
 




More information about the wine-cvs mailing list