Module: wine Branch: master Commit: df3cb0630df098cab0aa7f422c40ff813e91bd93 URL: http://source.winehq.org/git/wine.git/?a=commit;h=df3cb0630df098cab0aa7f422c...
Author: Juan Lang juan.lang@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);