From b7092222463f67036d8dc46d5ff20901b38910c1 Mon Sep 17 00:00:00 2001 From: Juan Lang Date: Fri, 21 Sep 2007 11:38:55 -0700 Subject: [PATCH] Implement SetupDiGetDeviceInterfaceDetailA/W --- dlls/setupapi/devinst.c | 107 +++++++++++++++++++++++++++++++++++++++-- dlls/setupapi/tests/devinst.c | 6 -- 2 files changed, 103 insertions(+), 10 deletions(-) diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 0fd13fc..c71d17f 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -2308,13 +2308,63 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDet 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); - SetLastError(ERROR_INVALID_HANDLE); + 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 SetupDiGetDeviceInterfaceDet 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); - return FALSE; + + 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 diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c index d6d1cfc..1a9614a 100644 --- a/dlls/setupapi/tests/devinst.c +++ b/dlls/setupapi/tests/devinst.c @@ -440,7 +440,6 @@ static void testGetDeviceInterfaceDetail 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 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 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 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); -- 1.4.1