setupapi: Avoid unnecessary buffer allocation in SetupDiCreateDeviceInfoW().
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
81d2b419b8
commit
462c74bcdb
@ -1394,19 +1394,18 @@ static DWORD SETUPDI_DevNameToDevID(LPCWSTR devName)
|
|||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* SetupDiCreateDeviceInfoW (SETUPAPI.@)
|
* SetupDiCreateDeviceInfoW (SETUPAPI.@)
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI SetupDiCreateDeviceInfoW(HDEVINFO devinfo, PCWSTR DeviceName,
|
BOOL WINAPI SetupDiCreateDeviceInfoW(HDEVINFO devinfo, const WCHAR *name, const GUID *class,
|
||||||
const GUID *ClassGuid, PCWSTR DeviceDescription, HWND hwndParent, DWORD CreationFlags,
|
const WCHAR *description, HWND parent, DWORD flags, SP_DEVINFO_DATA *device_data)
|
||||||
SP_DEVINFO_DATA *device_data)
|
|
||||||
{
|
{
|
||||||
|
WCHAR id[MAX_DEVICE_ID_LEN];
|
||||||
struct DeviceInfoSet *set;
|
struct DeviceInfoSet *set;
|
||||||
BOOL ret = FALSE, allocatedInstanceId = FALSE;
|
struct device *device;
|
||||||
LPCWSTR instanceId = NULL;
|
|
||||||
|
|
||||||
TRACE("devinfo %p, name %s, class %s, description %s, hwnd %p, flags %#x, device_data %p.\n",
|
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),
|
devinfo, debugstr_w(name), debugstr_guid(class), debugstr_w(description),
|
||||||
hwndParent, CreationFlags, device_data);
|
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);
|
SetLastError(ERROR_INVALID_DEVINST_NAME);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -1415,32 +1414,31 @@ BOOL WINAPI SetupDiCreateDeviceInfoW(HDEVINFO devinfo, PCWSTR DeviceName,
|
|||||||
if (!(set = get_device_set(devinfo)))
|
if (!(set = get_device_set(devinfo)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!ClassGuid)
|
if (!class)
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsEqualGUID(&set->ClassGuid, &GUID_NULL) &&
|
if (!IsEqualGUID(&set->ClassGuid, &GUID_NULL) && !IsEqualGUID(class, &set->ClassGuid))
|
||||||
!IsEqualGUID(ClassGuid, &set->ClassGuid))
|
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_CLASS_MISMATCH);
|
SetLastError(ERROR_CLASS_MISMATCH);
|
||||||
return FALSE;
|
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};
|
||||||
SetLastError(ERROR_INVALID_DEVINST_NAME);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
static const WCHAR newDeviceFmt[] = {'R','O','O','T','\\','%','s',
|
|
||||||
'\\','%','0','4','d',0};
|
|
||||||
DWORD devId;
|
DWORD devId;
|
||||||
|
|
||||||
|
if (strchrW(name, '\\'))
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_INVALID_DEVINST_NAME);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (set->cDevices)
|
if (set->cDevices)
|
||||||
{
|
{
|
||||||
DWORD highestDevID = 0;
|
DWORD highestDevID = 0;
|
||||||
struct device *device;
|
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY(device, &set->devices, struct device, entry)
|
LIST_FOR_EACH_ENTRY(device, &set->devices, struct device, entry)
|
||||||
{
|
{
|
||||||
@ -1459,61 +1457,47 @@ BOOL WINAPI SetupDiCreateDeviceInfoW(HDEVINFO devinfo, PCWSTR DeviceName,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
devId = 0;
|
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;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ret = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
struct device *device;
|
|
||||||
|
|
||||||
ret = TRUE;
|
if (snprintfW(id, ARRAY_SIZE(id), formatW, name, devId) == -1)
|
||||||
instanceId = DeviceName;
|
{
|
||||||
|
SetLastError(ERROR_INVALID_DEVINST_NAME);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpyW(id, name);
|
||||||
LIST_FOR_EACH_ENTRY(device, &set->devices, struct device, entry)
|
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);
|
SetLastError(ERROR_DEVINST_ALREADY_EXISTS);
|
||||||
ret = FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
struct device *device = NULL;
|
|
||||||
|
|
||||||
if ((device = SETUPDI_CreateDeviceInfo(set, ClassGuid, instanceId, TRUE)))
|
if (!(device = SETUPDI_CreateDeviceInfo(set, class, id, TRUE)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (description)
|
||||||
{
|
{
|
||||||
if (DeviceDescription)
|
|
||||||
SETUPDI_SetDeviceRegistryPropertyW(device, SPDRP_DEVICEDESC,
|
SETUPDI_SetDeviceRegistryPropertyW(device, SPDRP_DEVICEDESC,
|
||||||
(const BYTE *)DeviceDescription,
|
(const BYTE *)description, lstrlenW(description) * sizeof(WCHAR));
|
||||||
lstrlenW(DeviceDescription) * sizeof(WCHAR));
|
}
|
||||||
|
|
||||||
if (device_data)
|
if (device_data)
|
||||||
{
|
{
|
||||||
if (device_data->cbSize != sizeof(SP_DEVINFO_DATA))
|
if (device_data->cbSize != sizeof(SP_DEVINFO_DATA))
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_INVALID_USER_BUFFER);
|
SetLastError(ERROR_INVALID_USER_BUFFER);
|
||||||
ret = FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
copy_device_data(device_data, device);
|
copy_device_data(device_data, device);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
if (allocatedInstanceId)
|
|
||||||
HeapFree(GetProcessHeap(), 0, (LPWSTR)instanceId);
|
|
||||||
|
|
||||||
return ret;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
Loading…
x
Reference in New Issue
Block a user