[PATCH 4/5] setupapi: Avoid unnecessary buffer allocation in SetupDiCreateDeviceInfoW().

Zebediah Figura z.figura12 at gmail.com
Tue Nov 27 19:55:37 CST 2018


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/setupapi/devinst.c | 132 +++++++++++++++++++++---------------------------
 1 file changed, 58 insertions(+), 74 deletions(-)

diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c
index be7ce641a6..ff7aca089b 100644
--- a/dlls/setupapi/devinst.c
+++ b/dlls/setupapi/devinst.c
@@ -1394,19 +1394,18 @@ static DWORD SETUPDI_DevNameToDevID(LPCWSTR devName)
 /***********************************************************************
  *              SetupDiCreateDeviceInfoW (SETUPAPI.@)
  */
-BOOL WINAPI SetupDiCreateDeviceInfoW(HDEVINFO devinfo, PCWSTR DeviceName,
-        const GUID *ClassGuid, PCWSTR DeviceDescription, HWND hwndParent, DWORD CreationFlags,
-        SP_DEVINFO_DATA *device_data)
+BOOL WINAPI SetupDiCreateDeviceInfoW(HDEVINFO devinfo, const WCHAR *name, const GUID *class,
+        const WCHAR *description, HWND parent, DWORD flags, SP_DEVINFO_DATA *device_data)
 {
+    WCHAR id[MAX_DEVICE_ID_LEN];
     struct DeviceInfoSet *set;
-    BOOL ret = FALSE, allocatedInstanceId = FALSE;
-    LPCWSTR instanceId = NULL;
+    struct device *device;
 
     TRACE("devinfo %p, name %s, class %s, description %s, hwnd %p, flags %#x, device_data %p.\n",
-            devinfo, debugstr_w(DeviceName), debugstr_guid(ClassGuid), debugstr_w(DeviceDescription),
-            hwndParent, CreationFlags, device_data);
+            devinfo, debugstr_w(name), debugstr_guid(class), debugstr_w(description),
+            parent, flags, device_data);
 
-    if (!DeviceName || strlenW(DeviceName) >= MAX_DEVICE_ID_LEN)
+    if (!name || strlenW(name) >= MAX_DEVICE_ID_LEN)
     {
         SetLastError(ERROR_INVALID_DEVINST_NAME);
         return FALSE;
@@ -1415,105 +1414,90 @@ BOOL WINAPI SetupDiCreateDeviceInfoW(HDEVINFO devinfo, PCWSTR DeviceName,
     if (!(set = get_device_set(devinfo)))
         return FALSE;
 
-    if (!ClassGuid)
+    if (!class)
     {
         SetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
     }
 
-    if (!IsEqualGUID(&set->ClassGuid, &GUID_NULL) &&
-        !IsEqualGUID(ClassGuid, &set->ClassGuid))
+    if (!IsEqualGUID(&set->ClassGuid, &GUID_NULL) && !IsEqualGUID(class, &set->ClassGuid))
     {
         SetLastError(ERROR_CLASS_MISMATCH);
         return FALSE;
     }
-    if ((CreationFlags & DICD_GENERATE_ID))
+    if ((flags & DICD_GENERATE_ID))
     {
-        if (strchrW(DeviceName, '\\'))
+        static const WCHAR formatW[] = {'R','O','O','T','\\','%','s','\\','%','0','4','d',0};
+        DWORD devId;
+
+        if (strchrW(name, '\\'))
+        {
             SetLastError(ERROR_INVALID_DEVINST_NAME);
-        else
+            return FALSE;
+        }
+
+        if (set->cDevices)
         {
-            static const WCHAR newDeviceFmt[] = {'R','O','O','T','\\','%','s',
-                '\\','%','0','4','d',0};
-            DWORD devId;
+            DWORD highestDevID = 0;
 
-            if (set->cDevices)
+            LIST_FOR_EACH_ENTRY(device, &set->devices, struct device, entry)
             {
-                DWORD highestDevID = 0;
-                struct device *device;
+                const WCHAR *devName = strrchrW(device->instanceId, '\\');
+                DWORD id;
 
-                LIST_FOR_EACH_ENTRY(device, &set->devices, struct device, entry)
-                {
-                    const WCHAR *devName = strrchrW(device->instanceId, '\\');
-                    DWORD id;
-
-                    if (devName)
-                        devName++;
-                    else
-                        devName = device->instanceId;
-                    id = SETUPDI_DevNameToDevID(devName);
-                    if (id != 0xffffffff && id > highestDevID)
-                        highestDevID = id;
-                }
-                devId = highestDevID + 1;
-            }
-            else
-                devId = 0;
-            /* 17 == lstrlenW(L"Root\\") + lstrlenW("\\") + 1 + %d max size */
-            instanceId = HeapAlloc(GetProcessHeap(), 0,
-                    (17 + lstrlenW(DeviceName)) * sizeof(WCHAR));
-            if (instanceId)
-            {
-                sprintfW((LPWSTR)instanceId, newDeviceFmt, DeviceName,
-                        devId);
-                allocatedInstanceId = TRUE;
-                ret = TRUE;
+                if (devName)
+                    devName++;
+                else
+                    devName = device->instanceId;
+                id = SETUPDI_DevNameToDevID(devName);
+                if (id != 0xffffffff && id > highestDevID)
+                    highestDevID = id;
             }
-            else
-                ret = FALSE;
+            devId = highestDevID + 1;
+        }
+        else
+            devId = 0;
+
+        if (snprintfW(id, ARRAY_SIZE(id), formatW, name, devId) == -1)
+        {
+            SetLastError(ERROR_INVALID_DEVINST_NAME);
+            return FALSE;
         }
     }
     else
     {
-        struct device *device;
-
-        ret = TRUE;
-        instanceId = DeviceName;
+        strcpyW(id, name);
         LIST_FOR_EACH_ENTRY(device, &set->devices, struct device, entry)
         {
-            if (!lstrcmpiW(DeviceName, device->instanceId))
+            if (!lstrcmpiW(name, device->instanceId))
             {
                 SetLastError(ERROR_DEVINST_ALREADY_EXISTS);
-                ret = FALSE;
+                return FALSE;
             }
         }
     }
-    if (ret)
+
+    if (!(device = SETUPDI_CreateDeviceInfo(set, class, id, TRUE)))
+        return FALSE;
+
+    if (description)
     {
-        struct device *device = NULL;
+        SETUPDI_SetDeviceRegistryPropertyW(device, SPDRP_DEVICEDESC,
+                (const BYTE *)description, lstrlenW(description) * sizeof(WCHAR));
+    }
 
-        if ((device = SETUPDI_CreateDeviceInfo(set, ClassGuid, instanceId, TRUE)))
+    if (device_data)
+    {
+        if (device_data->cbSize != sizeof(SP_DEVINFO_DATA))
         {
-            if (DeviceDescription)
-                SETUPDI_SetDeviceRegistryPropertyW(device, SPDRP_DEVICEDESC,
-                    (const BYTE *)DeviceDescription,
-                    lstrlenW(DeviceDescription) * sizeof(WCHAR));
-            if (device_data)
-            {
-                if (device_data->cbSize != sizeof(SP_DEVINFO_DATA))
-                {
-                    SetLastError(ERROR_INVALID_USER_BUFFER);
-                    ret = FALSE;
-                }
-                else
-                    copy_device_data(device_data, device);
-            }
+            SetLastError(ERROR_INVALID_USER_BUFFER);
+            return FALSE;
         }
+        else
+            copy_device_data(device_data, device);
     }
-    if (allocatedInstanceId)
-        HeapFree(GetProcessHeap(), 0, (LPWSTR)instanceId);
 
-    return ret;
+    return TRUE;
 }
 
 /***********************************************************************
-- 
2.14.1




More information about the wine-devel mailing list