[SETUPAPI]

- Implement SetupDiInstallDeviceInterfaces, SetupDiCreateDeviceInterfaceRegKeyW which are required to store device specific information

svn path=/trunk/; revision=44644
This commit is contained in:
Johannes Anderwald 2009-12-18 04:37:15 +00:00
parent 9eb97bd05d
commit f814e48ad5
3 changed files with 198 additions and 14 deletions

View file

@ -2628,7 +2628,14 @@ HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW(
HINF InfHandle, HINF InfHandle,
PCWSTR InfSectionName) PCWSTR InfSectionName)
{ {
HKEY hKey, hDevKey;
LPWSTR SymbolicLink;
DWORD Length, Index;
LONG rc;
WCHAR bracedGuidString[39];
struct DeviceInterface *DevItf;
struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet; struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
TRACE("%p %p %d %08x %p %p\n", DeviceInfoSet, DeviceInterfaceData, Reserved, TRACE("%p %p %d %08x %p %p\n", DeviceInfoSet, DeviceInterfaceData, Reserved,
samDesired, InfHandle, InfSectionName); samDesired, InfHandle, InfSectionName);
@ -2651,11 +2658,79 @@ HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW(
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
FIXME("%p %p %d %08x %p %p\n", DeviceInfoSet, DeviceInterfaceData, Reserved, hKey = SetupDiOpenClassRegKeyExW(&DeviceInterfaceData->InterfaceClassGuid, samDesired, DIOCR_INTERFACE, NULL, NULL);
samDesired, InfHandle, InfSectionName); if (hKey == INVALID_HANDLE_VALUE)
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); {
hKey = SetupDiOpenClassRegKeyExW(NULL, samDesired, DIOCR_INTERFACE, NULL, NULL);
if (hKey == INVALID_HANDLE_VALUE)
{
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
SETUPDI_GuidToString(&DeviceInterfaceData->InterfaceClassGuid, bracedGuidString);
if (RegCreateKeyExW(hKey, bracedGuidString, 0, NULL, 0, samDesired, NULL, &hDevKey, NULL) != ERROR_SUCCESS)
{
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
RegCloseKey(hKey);
hKey = hDevKey;
}
DevItf = (struct DeviceInterface *)DeviceInterfaceData->Reserved;
Length = (wcslen(DevItf->SymbolicLink)+1) * sizeof(WCHAR);
SymbolicLink = HeapAlloc(GetProcessHeap(), 0, Length);
if (!SymbolicLink)
{
RegCloseKey(hKey);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return INVALID_HANDLE_VALUE;
}
wcscpy(SymbolicLink, DevItf->SymbolicLink);
Index = 0;
while(SymbolicLink[Index])
{
if (SymbolicLink[Index] == L'\\')
{
SymbolicLink[Index] = L'#';
}
Index++;
}
rc = RegCreateKeyExW(hKey, SymbolicLink, 0, NULL, 0, samDesired, NULL, &hDevKey, NULL);
RegCloseKey(hKey);
HeapFree(GetProcessHeap(), 0, SymbolicLink);
if (rc == ERROR_SUCCESS)
{
if (InfHandle && InfSectionName)
{
if (!SetupInstallFromInfSection(NULL /*FIXME */,
InfHandle,
InfSectionName,
SPINST_INIFILES | SPINST_REGISTRY | SPINST_INI2REG | SPINST_FILES | SPINST_BITREG | SPINST_REGSVR | SPINST_UNREGSVR | SPINST_PROFILEITEMS | SPINST_COPYINF,
hDevKey,
NULL,
0,
set->SelectedDevice->InstallParams.InstallMsgHandler,
set->SelectedDevice->InstallParams.InstallMsgHandlerContext,
INVALID_HANDLE_VALUE,
NULL))
{
RegCloseKey(hDevKey);
return INVALID_HANDLE_VALUE;
}
}
}
SetLastError(rc);
return hDevKey;
}
/*********************************************************************** /***********************************************************************
* SetupDiDeleteDeviceInterfaceRegKey (SETUPAPI.@) * SetupDiDeleteDeviceInterfaceRegKey (SETUPAPI.@)
@ -3611,6 +3686,7 @@ HKEY WINAPI SetupDiOpenClassRegKeyExW(
key = INVALID_HANDLE_VALUE; key = INVALID_HANDLE_VALUE;
} }
} }
return key; return key;
} }

View file

@ -292,22 +292,118 @@ cleanup:
return rc; return rc;
} }
static LPWSTR
CreateSymbolicLink(
IN LPGUID InterfaceGuid,
IN LPCWSTR ReferenceString,
IN struct DeviceInfo *devInfo)
{
DWORD Length, Index, Offset;
LPWSTR Key;
Length = wcslen(devInfo->instanceId) + 4 /* prepend ##?# */ + 41 /* #{GUID} + */ + 1 /* zero byte */;
Key = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length * sizeof(WCHAR));
if (!Key)
return NULL;
wcscpy(Key, L"##?#");
wcscat(Key, devInfo->instanceId);
for(Index = 4; Index < Length; Index++)
{
if (Key[Index] == L'\\')
{
Key[Index] = L'#';
}
}
wcscat(Key, L"#");
Offset = wcslen(Key);
pSetupStringFromGuid(InterfaceGuid, Key + Offset, Length - Offset);
return Key;
}
static BOOL static BOOL
InstallOneInterface( InstallOneInterface(
IN LPGUID InterfaceGuid, IN LPGUID InterfaceGuid,
IN LPCWSTR ReferenceString, IN LPCWSTR ReferenceString,
IN LPCWSTR InterfaceSection, IN LPCWSTR InterfaceSection,
IN UINT InterfaceFlags) IN UINT InterfaceFlags,
IN HINF hInf,
IN HDEVINFO DeviceInfoSet,
IN struct DeviceInfo *devInfo)
{ {
BOOL ret;
HKEY hKey, hRefKey;
LPWSTR Path;
SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
PLIST_ENTRY InterfaceListEntry;
struct DeviceInterface *DevItf = NULL;
if (InterfaceFlags != 0) if (InterfaceFlags != 0)
{ {
SetLastError(ERROR_INVALID_PARAMETER); SetLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
FIXME("Need to InstallOneInterface(%s %s %s %u)\n", debugstr_guid(InterfaceGuid), TRACE("Need to InstallOneInterface(%s %s %s %u) hInf %p DeviceInfoSet %p devInfo %p instanceId %s\n", debugstr_guid(InterfaceGuid),
debugstr_w(ReferenceString), debugstr_w(InterfaceSection), InterfaceFlags); debugstr_w(ReferenceString), debugstr_w(InterfaceSection), InterfaceFlags, hInf, DeviceInfoSet, devInfo, debugstr_w(devInfo->instanceId));
return TRUE;
Path = CreateSymbolicLink(InterfaceGuid, ReferenceString, devInfo);
if (!Path)
return FALSE;
CreateDeviceInterface(devInfo, Path, InterfaceGuid, &DevItf);
HeapFree(GetProcessHeap(), 0, Path);
if (!DevItf)
{
return FALSE;
}
InsertTailList(&devInfo->InterfaceListHead, &DevItf->ListEntry);
memcpy(&DeviceInterfaceData.InterfaceClassGuid, &DevItf->InterfaceClassGuid, sizeof(GUID));
DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
DeviceInterfaceData.Flags = DevItf->Flags;
DeviceInterfaceData.Reserved = (ULONG_PTR)DevItf;
hKey = SetupDiCreateDeviceInterfaceRegKeyW(DeviceInfoSet, &DeviceInterfaceData, 0, KEY_ALL_ACCESS, NULL, 0);
HeapFree(GetProcessHeap(), 0, DevItf);
if (hKey == INVALID_HANDLE_VALUE)
{
return FALSE;
}
if (ReferenceString)
{
Path = HeapAlloc(GetProcessHeap(), 0, (wcslen(ReferenceString) + 2) * sizeof(WCHAR));
if (!Path)
{
RegCloseKey(hKey);
return FALSE;
}
wcscpy(Path, L"#");
wcscat(Path, ReferenceString);
if (RegCreateKeyExW(hKey, Path, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hRefKey, NULL) != ERROR_SUCCESS)
{
ERR("failed to create key %s %lx\n", debugstr_w(Path), GetLastError());
HeapFree(GetProcessHeap(), 0, Path);
return FALSE;
}
RegCloseKey(hKey);
hKey = hRefKey;
HeapFree(GetProcessHeap(), 0, Path);
}
return SetupInstallFromInfSectionW(NULL, /* FIXME */ hInf, InterfaceSection, SPINST_REGISTRY, hKey, NULL, 0, NULL, NULL, NULL, NULL);
} }
/*********************************************************************** /***********************************************************************
@ -335,7 +431,8 @@ SetupDiInstallDeviceInterfaces(
SetLastError(ERROR_INVALID_USER_BUFFER); SetLastError(ERROR_INVALID_USER_BUFFER);
else else
{ {
struct DriverInfoElement *SelectedDriver; struct DeviceInfo *devInfo;
struct DriverInfoElement *SelectedDriver = NULL;
SP_DEVINSTALL_PARAMS_W InstallParams; SP_DEVINSTALL_PARAMS_W InstallParams;
WCHAR SectionName[MAX_PATH]; WCHAR SectionName[MAX_PATH];
DWORD SectionNameLength = 0; DWORD SectionNameLength = 0;
@ -347,6 +444,8 @@ SetupDiInstallDeviceInterfaces(
GUID InterfaceGuid; GUID InterfaceGuid;
BOOL Result; BOOL Result;
devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W); InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
Result = SetupDiGetDeviceInstallParamsW(DeviceInfoSet, DeviceInfoData, &InstallParams); Result = SetupDiGetDeviceInstallParamsW(DeviceInfoSet, DeviceInfoData, &InstallParams);
if (!Result) if (!Result)
@ -402,11 +501,15 @@ SetupDiInstallDeviceInterfaces(
ret = GetStringField(&ContextInterface, 3, &InterfaceSection); ret = GetStringField(&ContextInterface, 3, &InterfaceSection);
if (!ret) if (!ret)
goto cleanup; {
/* ReferenceString is optional */
InterfaceSection = ReferenceString;
ReferenceString = NULL;
}
ret = SetupGetIntField( ret = SetupGetIntField(
&ContextInterface, &ContextInterface,
4, /* Field index */ (ReferenceString ? 4 : 3), /* Field index */
&InterfaceFlags); &InterfaceFlags);
if (!ret) if (!ret)
{ {
@ -421,10 +524,11 @@ SetupDiInstallDeviceInterfaces(
} }
/* Install Interface */ /* Install Interface */
ret = InstallOneInterface(&InterfaceGuid, ReferenceString, InterfaceSection, InterfaceFlags); ret = InstallOneInterface(&InterfaceGuid, ReferenceString, InterfaceSection, InterfaceFlags, SelectedDriver->InfFileDetails->hInf, DeviceInfoSet, devInfo);
cleanup: cleanup:
MyFree(InterfaceGuidString); MyFree(InterfaceGuidString);
if (ReferenceString)
MyFree(ReferenceString); MyFree(ReferenceString);
MyFree(InterfaceSection); MyFree(InterfaceSection);
InterfaceGuidString = ReferenceString = InterfaceSection = NULL; InterfaceGuidString = ReferenceString = InterfaceSection = NULL;

View file

@ -334,6 +334,10 @@ FreeFunctionPointer(
IN HMODULE ModulePointer, IN HMODULE ModulePointer,
IN PVOID FunctionPointer); IN PVOID FunctionPointer);
DWORD
WINAPI
pSetupStringFromGuid(LPGUID lpGUID, PWSTR pString, DWORD dwStringLen);
DWORD WINAPI CaptureAndConvertAnsiArg(LPCSTR pSrc, LPWSTR *pDst); DWORD WINAPI CaptureAndConvertAnsiArg(LPCSTR pSrc, LPWSTR *pDst);
VOID WINAPI MyFree(LPVOID lpMem); VOID WINAPI MyFree(LPVOID lpMem);