Module: wine Branch: master Commit: a63c9356a4fcaeea42eb31752c6ac0323b75daf2 URL: http://source.winehq.org/git/wine.git/?a=commit;h=a63c9356a4fcaeea42eb31752c...
Author: Juan Lang juan.lang@gmail.com Date: Fri Sep 21 11:38:55 2007 -0700
setupapi: 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 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);
- 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 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); - 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(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);