mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-04 13:27:28 +00:00
setupapi: Create symbolic link value when interface is created.
This commit is contained in:
parent
d34ec8b8a1
commit
df3cb0630d
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue