Juan Lang : setupapi: Implement SetupDiGetDeviceInterfaceDetailA/W.
Alexandre Julliard
julliard at winehq.org
Mon Sep 24 08:08:02 CDT 2007
Module: wine
Branch: master
Commit: a63c9356a4fcaeea42eb31752c6ac0323b75daf2
URL: http://source.winehq.org/git/wine.git/?a=commit;h=a63c9356a4fcaeea42eb31752c6ac0323b75daf2
Author: Juan Lang <juan.lang at 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);
More information about the wine-cvs
mailing list