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