Commit d15262e4 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

setupapi: Fill the required size in SetupDiGetDeviceInterfaceDetail() also on success.

parent 5711f03e
...@@ -2976,15 +2976,15 @@ BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo) ...@@ -2976,15 +2976,15 @@ BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)
*/ */
BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(HDEVINFO devinfo, SP_DEVICE_INTERFACE_DATA *iface_data, BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(HDEVINFO devinfo, SP_DEVICE_INTERFACE_DATA *iface_data,
SP_DEVICE_INTERFACE_DETAIL_DATA_A *DeviceInterfaceDetailData, SP_DEVICE_INTERFACE_DETAIL_DATA_A *DeviceInterfaceDetailData,
DWORD DeviceInterfaceDetailDataSize, DWORD *RequiredSize, SP_DEVINFO_DATA *device_data) DWORD DeviceInterfaceDetailDataSize, DWORD *ret_size, SP_DEVINFO_DATA *device_data)
{ {
struct device_iface *iface; struct device_iface *iface;
DWORD bytesNeeded = FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath[1]); DWORD bytesNeeded = FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath[1]);
BOOL ret = FALSE; BOOL ret = FALSE;
TRACE("devinfo %p, iface_data %p, detail_data %p, size %ld, needed %p, device_data %p.\n", TRACE("devinfo %p, iface_data %p, detail_data %p, size %ld, ret_size %p, device_data %p.\n",
devinfo, iface_data, DeviceInterfaceDetailData, DeviceInterfaceDetailDataSize, devinfo, iface_data, DeviceInterfaceDetailData, DeviceInterfaceDetailDataSize,
RequiredSize, device_data); ret_size, device_data);
if (!(iface = get_device_iface(devinfo, iface_data))) if (!(iface = get_device_iface(devinfo, iface_data)))
return FALSE; return FALSE;
...@@ -3004,6 +3004,10 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(HDEVINFO devinfo, SP_DEVICE_INTERFA ...@@ -3004,6 +3004,10 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(HDEVINFO devinfo, SP_DEVICE_INTERFA
if (iface->symlink) if (iface->symlink)
bytesNeeded += WideCharToMultiByte(CP_ACP, 0, iface->symlink, -1, bytesNeeded += WideCharToMultiByte(CP_ACP, 0, iface->symlink, -1,
NULL, 0, NULL, NULL) - 1; NULL, 0, NULL, NULL) - 1;
if (ret_size)
*ret_size = bytesNeeded;
if (DeviceInterfaceDetailDataSize >= bytesNeeded) if (DeviceInterfaceDetailDataSize >= bytesNeeded)
{ {
if (iface->symlink) if (iface->symlink)
...@@ -3019,8 +3023,6 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(HDEVINFO devinfo, SP_DEVICE_INTERFA ...@@ -3019,8 +3023,6 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(HDEVINFO devinfo, SP_DEVICE_INTERFA
} }
else else
{ {
if (RequiredSize)
*RequiredSize = bytesNeeded;
SetLastError(ERROR_INSUFFICIENT_BUFFER); SetLastError(ERROR_INSUFFICIENT_BUFFER);
} }
...@@ -3035,16 +3037,16 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(HDEVINFO devinfo, SP_DEVICE_INTERFA ...@@ -3035,16 +3037,16 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(HDEVINFO devinfo, SP_DEVICE_INTERFA
*/ */
BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(HDEVINFO devinfo, SP_DEVICE_INTERFACE_DATA *iface_data, BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(HDEVINFO devinfo, SP_DEVICE_INTERFACE_DATA *iface_data,
SP_DEVICE_INTERFACE_DETAIL_DATA_W *DeviceInterfaceDetailData, SP_DEVICE_INTERFACE_DETAIL_DATA_W *DeviceInterfaceDetailData,
DWORD DeviceInterfaceDetailDataSize, DWORD *RequiredSize, SP_DEVINFO_DATA *device_data) DWORD DeviceInterfaceDetailDataSize, DWORD *ret_size, SP_DEVINFO_DATA *device_data)
{ {
struct device_iface *iface; struct device_iface *iface;
DWORD bytesNeeded = offsetof(SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath) DWORD bytesNeeded = offsetof(SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath)
+ sizeof(WCHAR); /* include NULL terminator */ + sizeof(WCHAR); /* include NULL terminator */
BOOL ret = FALSE; BOOL ret = FALSE;
TRACE("devinfo %p, iface_data %p, detail_data %p, size %ld, needed %p, device_data %p.\n", TRACE("devinfo %p, iface_data %p, detail_data %p, size %ld, ret_size %p, device_data %p.\n",
devinfo, iface_data, DeviceInterfaceDetailData, DeviceInterfaceDetailDataSize, devinfo, iface_data, DeviceInterfaceDetailData, DeviceInterfaceDetailDataSize,
RequiredSize, device_data); ret_size, device_data);
if (!(iface = get_device_iface(devinfo, iface_data))) if (!(iface = get_device_iface(devinfo, iface_data)))
return FALSE; return FALSE;
...@@ -3064,6 +3066,10 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(HDEVINFO devinfo, SP_DEVICE_INTERFA ...@@ -3064,6 +3066,10 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(HDEVINFO devinfo, SP_DEVICE_INTERFA
if (iface->symlink) if (iface->symlink)
bytesNeeded += sizeof(WCHAR) * lstrlenW(iface->symlink); bytesNeeded += sizeof(WCHAR) * lstrlenW(iface->symlink);
if (ret_size)
*ret_size = bytesNeeded;
if (DeviceInterfaceDetailDataSize >= bytesNeeded) if (DeviceInterfaceDetailDataSize >= bytesNeeded)
{ {
if (iface->symlink) if (iface->symlink)
...@@ -3075,8 +3081,6 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(HDEVINFO devinfo, SP_DEVICE_INTERFA ...@@ -3075,8 +3081,6 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(HDEVINFO devinfo, SP_DEVICE_INTERFA
} }
else else
{ {
if (RequiredSize)
*RequiredSize = bytesNeeded;
SetLastError(ERROR_INSUFFICIENT_BUFFER); SetLastError(ERROR_INSUFFICIENT_BUFFER);
} }
......
...@@ -1257,14 +1257,14 @@ static void test_device_iface_detail(void) ...@@ -1257,14 +1257,14 @@ static void test_device_iface_detail(void)
ret = SetupDiGetDeviceInterfaceDetailA(set, &iface, detail, expected_size, &size, NULL); ret = SetupDiGetDeviceInterfaceDetailA(set, &iface, detail, expected_size, &size, NULL);
ok(ret, "Failed to get interface detail, error %#lx.\n", GetLastError()); ok(ret, "Failed to get interface detail, error %#lx.\n", GetLastError());
ok(!strcasecmp(path, detail->DevicePath), "Got unexpected path %s.\n", detail->DevicePath); ok(!strcasecmp(path, detail->DevicePath), "Got unexpected path %s.\n", detail->DevicePath);
todo_wine ok(size == expected_size, "Expected size %lu, got %lu.\n", expected_size, size); ok(size == expected_size, "Expected size %lu, got %lu.\n", expected_size, size);
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
size = 0xdeadbeef; size = 0xdeadbeef;
ret = SetupDiGetDeviceInterfaceDetailA(set, &iface, detail, expected_size * 2, &size, NULL); ret = SetupDiGetDeviceInterfaceDetailA(set, &iface, detail, expected_size * 2, &size, NULL);
ok(ret, "Failed to get interface detail, error %#lx.\n", GetLastError()); ok(ret, "Failed to get interface detail, error %#lx.\n", GetLastError());
ok(!strcasecmp(path, detail->DevicePath), "Got unexpected path %s.\n", detail->DevicePath); ok(!strcasecmp(path, detail->DevicePath), "Got unexpected path %s.\n", detail->DevicePath);
todo_wine ok(size == expected_size, "Expected size %lu, got %lu.\n", expected_size, size); ok(size == expected_size, "Expected size %lu, got %lu.\n", expected_size, size);
expected_size = FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath[strlen(path) + 1]); expected_size = FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath[strlen(path) + 1]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment