Juan Lang : setupapi: Create symbolic link value when interface is created.

Alexandre Julliard julliard at winehq.org
Mon Sep 24 08:08:03 CDT 2007


Module: wine
Branch: master
Commit: df3cb0630df098cab0aa7f422c40ff813e91bd93
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=df3cb0630df098cab0aa7f422c40ff813e91bd93

Author: Juan Lang <juan.lang at gmail.com>
Date:   Fri Sep 21 11:56:45 2007 -0700

setupapi: Create symbolic link value when interface is created.

---

 dlls/setupapi/devinst.c       |   63 ++++++++++++++++++++++++++++++++--------
 dlls/setupapi/tests/devinst.c |    2 -
 2 files changed, 50 insertions(+), 15 deletions(-)

diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c
index c71d17f..08a78f3 100644
--- a/dlls/setupapi/devinst.c
+++ b/dlls/setupapi/devinst.c
@@ -129,6 +129,18 @@ struct DeviceInfo
     struct InterfaceInstances *interfaces;
 };
 
+static void SETUPDI_GuidToString(const GUID *guid, LPWSTR guidStr)
+{
+    static const WCHAR fmt[] = {'{','%','0','8','X','-','%','0','4','X','-',
+        '%','0','4','X','-','%','0','2','X','%','0','2','X','-','%','0','2',
+        'X','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','%',
+        '0','2','X','}',0};
+
+    sprintfW(guidStr, fmt, guid->Data1, guid->Data2, guid->Data3,
+        guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
+        guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
+}
+
 static void SETUPDI_FreeInterfaceInstances(struct InterfaceInstances *instances)
 {
     DWORD i;
@@ -205,6 +217,41 @@ static BOOL SETUPDI_FindInterfaceInstance(
     return found;
 }
 
+static LPWSTR SETUPDI_CreateSymbolicLinkPath(LPCWSTR instanceId,
+        const GUID *InterfaceClassGuid, LPCWSTR ReferenceString)
+{
+    static const WCHAR fmt[] = {'\\','\\','?','\\','%','s','#','%','s',0};
+    WCHAR guidStr[39];
+    DWORD len;
+    LPWSTR ret;
+
+    SETUPDI_GuidToString(InterfaceClassGuid, guidStr);
+    /* omit length of format specifiers, but include NULL terminator: */
+    len = lstrlenW(fmt) - 4 + 1;
+    len += lstrlenW(instanceId) + lstrlenW(guidStr);
+    if (ReferenceString)
+    {
+        /* space for a hash between string and reference string: */
+        len += lstrlenW(ReferenceString) + 1;
+    }
+    ret = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+    if (ret)
+    {
+        int printed = sprintfW(ret, fmt, instanceId, guidStr);
+        LPWSTR ptr;
+
+        /* replace '\\' with '#' after the "\\\\?\\" beginning */
+        for (ptr = strchrW(ret + 4, '\\'); ptr; ptr = strchrW(ptr + 1, '\\'))
+            *ptr = '#';
+        if (ReferenceString)
+        {
+            ret[printed - 1] = '\\';
+            lstrcpyW(ret + printed, ReferenceString);
+        }
+    }
+    return ret;
+}
+
 /* Adds an interface with the given interface class and reference string to
  * the device, if it doesn't already exist in the device.  If iface is not
  * NULL, returns a pointer to the newly added (or already existing) interface.
@@ -285,7 +332,9 @@ static BOOL SETUPDI_AddInterfaceInstance(struct DeviceInfo *devInfo,
                 if (ifaceInfo)
                 {
                     ret = TRUE;
-                    ifaceInfo->symbolicLink = NULL;
+                    ifaceInfo->symbolicLink = SETUPDI_CreateSymbolicLinkPath(
+                            devInfo->instanceId, InterfaceClassGuid,
+                            ReferenceString);
                     if (ReferenceString)
                     {
                         ifaceInfo->referenceString =
@@ -425,18 +474,6 @@ static void SETUPDI_FreeDeviceInfo(struct DeviceInfo *devInfo)
     HeapFree(GetProcessHeap(), 0, devInfo);
 }
 
-static void SETUPDI_GuidToString(const GUID *guid, LPWSTR guidStr)
-{
-    static const WCHAR fmt[] = {'{','%','0','8','X','-','%','0','4','X','-',
-        '%','0','4','X','-','%','0','2','X','%','0','2','X','-','%','0','2',
-        'X','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','%',
-        '0','2','X','}',0};
-
-    sprintfW(guidStr, fmt, guid->Data1, guid->Data2, guid->Data3,
-        guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
-        guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
-}
-
 /* Adds a device with GUID guid and identifer devInst to set.  Allocates a
  * struct DeviceInfo, and points the returned device info's Reserved member
  * to it.  "Phantom" devices are deleted from the registry when closed.
diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c
index d8a434f..0b58e4e 100644
--- a/dlls/setupapi/tests/devinst.c
+++ b/dlls/setupapi/tests/devinst.c
@@ -482,7 +482,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 = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
@@ -490,7 +489,6 @@ static void testGetDeviceInterfaceDetail(void)
                     size, &size, NULL);
             ok(ret, "SetupDiGetDeviceInterfaceDetailA failed: %d\n",
                     GetLastError());
-            todo_wine
             ok(!lstrcmpiA(path, detail->DevicePath), "Unexpected path %s\n",
                     detail->DevicePath);
             HeapFree(GetProcessHeap(), 0, buf);




More information about the wine-cvs mailing list