Commit a63c9356 authored by Juan Lang's avatar Juan Lang Committed by Alexandre Julliard

setupapi: Implement SetupDiGetDeviceInterfaceDetailA/W.

parent 6bd4ed73
......@@ -2308,13 +2308,63 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(
PDWORD RequiredSize,
PSP_DEVINFO_DATA DeviceInfoData)
{
struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
struct InterfaceInfo *info;
DWORD bytesNeeded = offsetof(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath)
+ 1;
BOOL ret = FALSE;
FIXME("(%p, %p, %p, %d, %p, %p)\n", DeviceInfoSet,
TRACE("(%p, %p, %p, %d, %p, %p)\n", DeviceInfoSet,
DeviceInterfaceData, DeviceInterfaceDetailData,
DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
if (!DeviceInfoSet || DeviceInfoSet == (HDEVINFO)INVALID_HANDLE_VALUE ||
set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (!DeviceInterfaceData ||
DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) ||
!DeviceInterfaceData->Reserved)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (DeviceInterfaceDetailData && (DeviceInterfaceDetailData->cbSize <
offsetof(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath) + sizeof(char) ||
DeviceInterfaceDetailData->cbSize > sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A)))
{
SetLastError(ERROR_INVALID_USER_BUFFER);
return FALSE;
}
if (!DeviceInterfaceDetailData && DeviceInterfaceDetailDataSize)
{
SetLastError(ERROR_INVALID_USER_BUFFER);
return FALSE;
}
info = (struct InterfaceInfo *)DeviceInterfaceData->Reserved;
if (info->symbolicLink)
bytesNeeded += WideCharToMultiByte(CP_ACP, 0, info->symbolicLink, -1,
NULL, 0, NULL, NULL);
if (DeviceInterfaceDetailDataSize >= bytesNeeded)
{
if (info->symbolicLink)
WideCharToMultiByte(CP_ACP, 0, info->symbolicLink, -1,
DeviceInterfaceDetailData->DevicePath,
DeviceInterfaceDetailDataSize -
offsetof(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath),
NULL, NULL);
else
DeviceInterfaceDetailData->DevicePath[0] = '\0';
ret = TRUE;
}
else
{
if (RequiredSize)
*RequiredSize = bytesNeeded;
SetLastError(ERROR_INSUFFICIENT_BUFFER);
}
return ret;
}
......@@ -2329,10 +2379,59 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(
PDWORD RequiredSize,
PSP_DEVINFO_DATA DeviceInfoData)
{
FIXME("(%p, %p, %p, %d, %p, %p): stub\n", DeviceInfoSet,
struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
struct InterfaceInfo *info;
DWORD bytesNeeded = offsetof(SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath)
+ sizeof(WCHAR); /* include NULL terminator */
BOOL ret = FALSE;
TRACE("(%p, %p, %p, %d, %p, %p)\n", DeviceInfoSet,
DeviceInterfaceData, DeviceInterfaceDetailData,
DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
if (!DeviceInfoSet || DeviceInfoSet == (HDEVINFO)INVALID_HANDLE_VALUE ||
set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (!DeviceInterfaceData ||
DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) ||
!DeviceInterfaceData->Reserved)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (DeviceInterfaceDetailData && (DeviceInterfaceDetailData->cbSize <
offsetof(SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath) + sizeof(WCHAR) ||
DeviceInterfaceDetailData->cbSize > sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W)))
{
SetLastError(ERROR_INVALID_USER_BUFFER);
return FALSE;
}
if (!DeviceInterfaceDetailData && DeviceInterfaceDetailDataSize)
{
SetLastError(ERROR_INVALID_USER_BUFFER);
return FALSE;
}
info = (struct InterfaceInfo *)DeviceInterfaceData->Reserved;
if (info->symbolicLink)
bytesNeeded += lstrlenW(info->symbolicLink);
if (DeviceInterfaceDetailDataSize >= bytesNeeded)
{
if (info->symbolicLink)
lstrcpyW(DeviceInterfaceDetailData->DevicePath, info->symbolicLink);
else
DeviceInterfaceDetailData->DevicePath[0] = '\0';
ret = TRUE;
}
else
{
if (RequiredSize)
*RequiredSize = bytesNeeded;
SetLastError(ERROR_INSUFFICIENT_BUFFER);
}
return ret;
}
struct PropertyMapEntry
......
......@@ -440,7 +440,6 @@ static void testGetDeviceInterfaceDetail(void)
SetLastError(0xdeadbeef);
ret = pSetupDiGetDeviceInterfaceDetailA(set, NULL, NULL, 0, NULL,
NULL);
todo_wine
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
ret = pSetupDiCreateDeviceInfoA(set, "ROOT\\LEGACY_BOGUS\\0000", &guid,
......@@ -453,19 +452,16 @@ static void testGetDeviceInterfaceDetail(void)
SetLastError(0xdeadbeef);
ret = pSetupDiGetDeviceInterfaceDetailA(set, &interfaceData, NULL,
0, NULL, NULL);
todo_wine
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
"Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
SetLastError(0xdeadbeef);
ret = pSetupDiGetDeviceInterfaceDetailA(set, &interfaceData, NULL,
100, NULL, NULL);
todo_wine
ok(!ret && GetLastError() == ERROR_INVALID_USER_BUFFER,
"Expected ERROR_INVALID_USER_BUFFER, got %08x\n", GetLastError());
SetLastError(0xdeadbeef);
ret = pSetupDiGetDeviceInterfaceDetailA(set, &interfaceData, NULL,
0, &size, NULL);
todo_wine
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
"Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
......@@ -478,7 +474,6 @@ static void testGetDeviceInterfaceDetail(void)
SetLastError(0xdeadbeef);
ret = pSetupDiGetDeviceInterfaceDetailA(set, &interfaceData, detail,
size, &size, NULL);
todo_wine
ok(!ret && GetLastError() == ERROR_INVALID_USER_BUFFER,
"Expected ERROR_INVALID_USER_BUFFER, got %08x\n", GetLastError());
detail->cbSize = size;
......@@ -491,7 +486,6 @@ static void testGetDeviceInterfaceDetail(void)
detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
ret = pSetupDiGetDeviceInterfaceDetailA(set, &interfaceData, detail,
size, &size, NULL);
todo_wine
ok(ret, "SetupDiGetDeviceInterfaceDetailA failed: %d\n",
GetLastError());
HeapFree(GetProcessHeap(), 0, buf);
......
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