mirror of
https://github.com/reactos/reactos.git
synced 2025-04-20 12:29:56 +00:00
Implement SetupDiGetDriverInstallParamsW
Add support for DI_FLAGSEX_INSTALLEDDRIVER svn path=/trunk/; revision=24322
This commit is contained in:
parent
b0e0c40c5d
commit
3f47783c54
4 changed files with 382 additions and 47 deletions
|
@ -1898,7 +1898,8 @@ CheckDeviceInstallParameters(
|
||||||
DI_FLAGSEX_DIDINFOLIST | /* 0x00000010 */
|
DI_FLAGSEX_DIDINFOLIST | /* 0x00000010 */
|
||||||
DI_FLAGSEX_DIDCOMPATINFO | /* 0x00000020 */
|
DI_FLAGSEX_DIDCOMPATINFO | /* 0x00000020 */
|
||||||
DI_FLAGSEX_ALLOWEXCLUDEDDRVS | /* 0x00000800 */
|
DI_FLAGSEX_ALLOWEXCLUDEDDRVS | /* 0x00000800 */
|
||||||
DI_FLAGSEX_NO_DRVREG_MODIFY; /* 0x00008000 */
|
DI_FLAGSEX_NO_DRVREG_MODIFY | /* 0x00008000 */
|
||||||
|
DI_FLAGSEX_INSTALLEDDRIVER; /* 0x04000000 */
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
|
|
||||||
/* FIXME: add support for more flags */
|
/* FIXME: add support for more flags */
|
||||||
|
|
|
@ -105,26 +105,26 @@ DestroyDriverInfoElement(struct DriverInfoElement* driverInfo)
|
||||||
* Helper functions for SetupDiBuildDriverInfoList
|
* Helper functions for SetupDiBuildDriverInfoList
|
||||||
*/
|
*/
|
||||||
static BOOL
|
static BOOL
|
||||||
AddDriverToList(
|
AddKnownDriverToList(
|
||||||
IN PLIST_ENTRY DriverListHead,
|
IN PLIST_ENTRY DriverListHead,
|
||||||
IN DWORD DriverType, /* SPDIT_CLASSDRIVER or SPDIT_COMPATDRIVER */
|
IN DWORD DriverType, /* SPDIT_CLASSDRIVER or SPDIT_COMPATDRIVER */
|
||||||
IN LPGUID ClassGuid,
|
IN LPGUID ClassGuid,
|
||||||
IN INFCONTEXT ContextDevice,
|
|
||||||
IN struct InfFileDetails *InfFileDetails,
|
IN struct InfFileDetails *InfFileDetails,
|
||||||
IN LPCWSTR InfFile,
|
IN LPCWSTR InfFile,
|
||||||
|
IN LPCWSTR SectionName,
|
||||||
|
IN LPCWSTR DriverDescription,
|
||||||
IN LPCWSTR ProviderName,
|
IN LPCWSTR ProviderName,
|
||||||
IN LPCWSTR ManufacturerName,
|
IN LPCWSTR ManufacturerName,
|
||||||
IN LPCWSTR MatchingId,
|
IN LPCWSTR MatchingId,
|
||||||
FILETIME DriverDate,
|
IN FILETIME DriverDate,
|
||||||
DWORDLONG DriverVersion,
|
IN DWORDLONG DriverVersion,
|
||||||
IN DWORD Rank)
|
IN DWORD Rank)
|
||||||
{
|
{
|
||||||
struct DriverInfoElement *driverInfo = NULL;
|
struct DriverInfoElement *driverInfo = NULL;
|
||||||
HANDLE hFile = INVALID_HANDLE_VALUE;
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
||||||
DWORD RequiredSize = 128; /* Initial buffer size */
|
|
||||||
BOOL Result = FALSE;
|
BOOL Result = FALSE;
|
||||||
PLIST_ENTRY PreviousEntry;
|
PLIST_ENTRY PreviousEntry;
|
||||||
LPWSTR InfInstallSection = NULL;
|
LPWSTR pDot;
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
|
|
||||||
driverInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(struct DriverInfoElement));
|
driverInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(struct DriverInfoElement));
|
||||||
|
@ -135,6 +135,9 @@ AddDriverToList(
|
||||||
}
|
}
|
||||||
memset(driverInfo, 0, sizeof(struct DriverInfoElement));
|
memset(driverInfo, 0, sizeof(struct DriverInfoElement));
|
||||||
|
|
||||||
|
driverInfo->Params.cbSize = sizeof(SP_DRVINSTALL_PARAMS);
|
||||||
|
driverInfo->Params.Reserved = (ULONG_PTR)driverInfo;
|
||||||
|
|
||||||
driverInfo->Details.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
|
driverInfo->Details.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
|
||||||
driverInfo->Details.Reserved = (ULONG_PTR)driverInfo;
|
driverInfo->Details.Reserved = (ULONG_PTR)driverInfo;
|
||||||
|
|
||||||
|
@ -154,20 +157,13 @@ AddDriverToList(
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
/* Fill SectionName field */
|
/* Fill SectionName field */
|
||||||
Result = SetupGetStringFieldW(
|
strncpyW(driverInfo->Details.SectionName, SectionName, LINE_LEN);
|
||||||
&ContextDevice,
|
pDot = strchrW(driverInfo->Details.SectionName, '.');
|
||||||
1,
|
if (pDot)
|
||||||
driverInfo->Details.SectionName, LINE_LEN,
|
*pDot = UNICODE_NULL;
|
||||||
NULL);
|
|
||||||
if (!Result)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
/* Fill DrvDescription field */
|
/* Fill DrvDescription field */
|
||||||
Result = SetupGetStringFieldW(
|
strncpyW(driverInfo->Details.DrvDescription, DriverDescription, LINE_LEN);
|
||||||
&ContextDevice,
|
|
||||||
0, /* Field index */
|
|
||||||
driverInfo->Details.DrvDescription, LINE_LEN,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
/* Copy MatchingId information */
|
/* Copy MatchingId information */
|
||||||
if (MatchingId)
|
if (MatchingId)
|
||||||
|
@ -183,30 +179,11 @@ AddDriverToList(
|
||||||
else
|
else
|
||||||
driverInfo->MatchingId = NULL;
|
driverInfo->MatchingId = NULL;
|
||||||
|
|
||||||
/* Get inf install section */
|
|
||||||
Result = FALSE;
|
|
||||||
RequiredSize = 128; /* Initial buffer size */
|
|
||||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
|
||||||
while (!Result && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
|
||||||
{
|
|
||||||
HeapFree(GetProcessHeap(), 0, InfInstallSection);
|
|
||||||
InfInstallSection = HeapAlloc(GetProcessHeap(), 0, RequiredSize * sizeof(WCHAR));
|
|
||||||
if (!InfInstallSection)
|
|
||||||
goto cleanup;
|
|
||||||
Result = SetupGetStringFieldW(
|
|
||||||
&ContextDevice,
|
|
||||||
1, /* Field index */
|
|
||||||
InfInstallSection, RequiredSize,
|
|
||||||
&RequiredSize);
|
|
||||||
}
|
|
||||||
if (!Result)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
TRACE("Adding driver '%s' [%s/%s] (Rank 0x%lx)\n",
|
TRACE("Adding driver '%s' [%s/%s] (Rank 0x%lx)\n",
|
||||||
debugstr_w(driverInfo->Details.DrvDescription), debugstr_w(InfFile),
|
debugstr_w(driverInfo->Details.DrvDescription), debugstr_w(InfFile),
|
||||||
debugstr_w(InfInstallSection), Rank);
|
debugstr_w(SectionName), Rank);
|
||||||
|
|
||||||
driverInfo->DriverRank = Rank;
|
driverInfo->Params.Rank = Rank;
|
||||||
memcpy(&driverInfo->DriverDate, &DriverDate, sizeof(FILETIME));
|
memcpy(&driverInfo->DriverDate, &DriverDate, sizeof(FILETIME));
|
||||||
memcpy(&driverInfo->ClassGuid, ClassGuid, sizeof(GUID));
|
memcpy(&driverInfo->ClassGuid, ClassGuid, sizeof(GUID));
|
||||||
driverInfo->Info.DriverType = DriverType;
|
driverInfo->Info.DriverType = DriverType;
|
||||||
|
@ -233,8 +210,8 @@ AddDriverToList(
|
||||||
{
|
{
|
||||||
struct DriverInfoElement *CurrentDriver;
|
struct DriverInfoElement *CurrentDriver;
|
||||||
CurrentDriver = CONTAINING_RECORD(PreviousEntry, struct DriverInfoElement, ListEntry);
|
CurrentDriver = CONTAINING_RECORD(PreviousEntry, struct DriverInfoElement, ListEntry);
|
||||||
if (CurrentDriver->DriverRank > Rank ||
|
if (CurrentDriver->Params.Rank > Rank ||
|
||||||
(CurrentDriver->DriverRank == Rank && CurrentDriver->DriverDate.QuadPart < driverInfo->DriverDate.QuadPart))
|
(CurrentDriver->Params.Rank == Rank && CurrentDriver->DriverDate.QuadPart < driverInfo->DriverDate.QuadPart))
|
||||||
{
|
{
|
||||||
/* Insert before the current item */
|
/* Insert before the current item */
|
||||||
InsertHeadList(PreviousEntry->Blink, &driverInfo->ListEntry);
|
InsertHeadList(PreviousEntry->Blink, &driverInfo->ListEntry);
|
||||||
|
@ -259,7 +236,78 @@ cleanup:
|
||||||
}
|
}
|
||||||
if (hFile != INVALID_HANDLE_VALUE)
|
if (hFile != INVALID_HANDLE_VALUE)
|
||||||
CloseHandle(hFile);
|
CloseHandle(hFile);
|
||||||
HeapFree(GetProcessHeap(), 0, InfInstallSection);
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL
|
||||||
|
AddDriverToList(
|
||||||
|
IN PLIST_ENTRY DriverListHead,
|
||||||
|
IN DWORD DriverType, /* SPDIT_CLASSDRIVER or SPDIT_COMPATDRIVER */
|
||||||
|
IN LPGUID ClassGuid,
|
||||||
|
IN INFCONTEXT ContextDevice,
|
||||||
|
IN struct InfFileDetails *InfFileDetails,
|
||||||
|
IN LPCWSTR InfFile,
|
||||||
|
IN LPCWSTR ProviderName,
|
||||||
|
IN LPCWSTR ManufacturerName,
|
||||||
|
IN LPCWSTR MatchingId,
|
||||||
|
IN FILETIME DriverDate,
|
||||||
|
IN DWORDLONG DriverVersion,
|
||||||
|
IN DWORD Rank)
|
||||||
|
{
|
||||||
|
LPWSTR SectionName = NULL;
|
||||||
|
LPWSTR DriverDescription = NULL;
|
||||||
|
BOOL Result;
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
|
||||||
|
/* Read SectionName */
|
||||||
|
SectionName = MyMalloc(LINE_LEN);
|
||||||
|
if (!SectionName)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
ZeroMemory(SectionName, LINE_LEN);
|
||||||
|
Result = SetupGetStringFieldW(
|
||||||
|
&ContextDevice,
|
||||||
|
1,
|
||||||
|
SectionName, LINE_LEN,
|
||||||
|
NULL);
|
||||||
|
if (!Result)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
/* Read DriverDescription */
|
||||||
|
DriverDescription = MyMalloc(LINE_LEN);
|
||||||
|
if (!DriverDescription)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
ZeroMemory(DriverDescription, LINE_LEN);
|
||||||
|
Result = SetupGetStringFieldW(
|
||||||
|
&ContextDevice,
|
||||||
|
0, /* Field index */
|
||||||
|
DriverDescription, LINE_LEN,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
ret = AddKnownDriverToList(
|
||||||
|
DriverListHead,
|
||||||
|
DriverType,
|
||||||
|
ClassGuid,
|
||||||
|
InfFileDetails,
|
||||||
|
InfFile,
|
||||||
|
SectionName,
|
||||||
|
DriverDescription,
|
||||||
|
ProviderName,
|
||||||
|
ManufacturerName,
|
||||||
|
MatchingId,
|
||||||
|
DriverDate,
|
||||||
|
DriverVersion,
|
||||||
|
Rank);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
MyFree(SectionName);
|
||||||
|
MyFree(DriverDescription);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -517,6 +565,152 @@ done:
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if WIN32_WINNT < 0x0600
|
||||||
|
/* WARNING:
|
||||||
|
* This code has been copied from advapi32/reg/reg.c,
|
||||||
|
* so this dll can be tested as is on Windows XP
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define RRF_RT_REG_NONE (1 << 0)
|
||||||
|
#define RRF_RT_REG_SZ (1 << 1)
|
||||||
|
#define RRF_RT_REG_EXPAND_SZ (1 << 2)
|
||||||
|
#define RRF_RT_REG_BINARY (1 << 3)
|
||||||
|
#define RRF_RT_REG_DWORD (1 << 4)
|
||||||
|
#define RRF_RT_REG_MULTI_SZ (1 << 5)
|
||||||
|
#define RRF_RT_REG_QWORD (1 << 6)
|
||||||
|
#define RRF_RT_DWORD (RRF_RT_REG_BINARY | RRF_RT_REG_DWORD)
|
||||||
|
#define RRF_RT_QWORD (RRF_RT_REG_BINARY | RRF_RT_REG_QWORD)
|
||||||
|
#define RRF_NOEXPAND (1 << 28)
|
||||||
|
#define RRF_ZEROONFAILURE (1 << 29)
|
||||||
|
|
||||||
|
static VOID
|
||||||
|
RegpApplyRestrictions( DWORD dwFlags, DWORD dwType, DWORD cbData,
|
||||||
|
PLONG ret )
|
||||||
|
{
|
||||||
|
/* Check if the type is restricted by the passed flags */
|
||||||
|
if (*ret == ERROR_SUCCESS || *ret == ERROR_MORE_DATA)
|
||||||
|
{
|
||||||
|
DWORD dwMask = 0;
|
||||||
|
|
||||||
|
switch (dwType)
|
||||||
|
{
|
||||||
|
case REG_NONE: dwMask = RRF_RT_REG_NONE; break;
|
||||||
|
case REG_SZ: dwMask = RRF_RT_REG_SZ; break;
|
||||||
|
case REG_EXPAND_SZ: dwMask = RRF_RT_REG_EXPAND_SZ; break;
|
||||||
|
case REG_MULTI_SZ: dwMask = RRF_RT_REG_MULTI_SZ; break;
|
||||||
|
case REG_BINARY: dwMask = RRF_RT_REG_BINARY; break;
|
||||||
|
case REG_DWORD: dwMask = RRF_RT_REG_DWORD; break;
|
||||||
|
case REG_QWORD: dwMask = RRF_RT_REG_QWORD; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dwFlags & dwMask)
|
||||||
|
{
|
||||||
|
/* Type is not restricted, check for size mismatch */
|
||||||
|
if (dwType == REG_BINARY)
|
||||||
|
{
|
||||||
|
DWORD cbExpect = 0;
|
||||||
|
|
||||||
|
if ((dwFlags & RRF_RT_DWORD) == RRF_RT_DWORD)
|
||||||
|
cbExpect = 4;
|
||||||
|
else if ((dwFlags & RRF_RT_DWORD) == RRF_RT_QWORD)
|
||||||
|
cbExpect = 8;
|
||||||
|
|
||||||
|
if (cbExpect && cbData != cbExpect)
|
||||||
|
*ret = ERROR_DATATYPE_MISMATCH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else *ret = ERROR_UNSUPPORTED_TYPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static LONG WINAPI
|
||||||
|
RegGetValueW( HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue,
|
||||||
|
DWORD dwFlags, LPDWORD pdwType, PVOID pvData,
|
||||||
|
LPDWORD pcbData )
|
||||||
|
{
|
||||||
|
DWORD dwType, cbData = pcbData ? *pcbData : 0;
|
||||||
|
PVOID pvBuf = NULL;
|
||||||
|
LONG ret;
|
||||||
|
|
||||||
|
TRACE("(%p,%s,%s,%ld,%p,%p,%p=%ld)\n",
|
||||||
|
hKey, debugstr_w(pszSubKey), debugstr_w(pszValue), dwFlags, pdwType,
|
||||||
|
pvData, pcbData, cbData);
|
||||||
|
|
||||||
|
if ((dwFlags & RRF_RT_REG_EXPAND_SZ) && !(dwFlags & RRF_NOEXPAND))
|
||||||
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (pszSubKey && pszSubKey[0])
|
||||||
|
{
|
||||||
|
ret = RegOpenKeyExW(hKey, pszSubKey, 0, KEY_QUERY_VALUE, &hKey);
|
||||||
|
if (ret != ERROR_SUCCESS) return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = RegQueryValueExW(hKey, pszValue, NULL, &dwType, pvData, &cbData);
|
||||||
|
|
||||||
|
/* If we are going to expand we need to read in the whole the value even
|
||||||
|
* if the passed buffer was too small as the expanded string might be
|
||||||
|
* smaller than the unexpanded one and could fit into cbData bytes. */
|
||||||
|
if ((ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) &&
|
||||||
|
(dwType == REG_EXPAND_SZ && !(dwFlags & RRF_NOEXPAND)))
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
if (pvBuf) HeapFree(GetProcessHeap(), 0, pvBuf);
|
||||||
|
|
||||||
|
pvBuf = HeapAlloc(GetProcessHeap(), 0, cbData);
|
||||||
|
if (!pvBuf)
|
||||||
|
{
|
||||||
|
ret = ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == ERROR_MORE_DATA)
|
||||||
|
ret = RegQueryValueExW(hKey, pszValue, NULL,
|
||||||
|
&dwType, pvBuf, &cbData);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Even if cbData was large enough we have to copy the
|
||||||
|
* string since ExpandEnvironmentStrings can't handle
|
||||||
|
* overlapping buffers. */
|
||||||
|
CopyMemory(pvBuf, pvData, cbData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Both the type or the value itself could have been modified in
|
||||||
|
* between so we have to keep retrying until the buffer is large
|
||||||
|
* enough or we no longer have to expand the value. */
|
||||||
|
} while (dwType == REG_EXPAND_SZ && ret == ERROR_MORE_DATA);
|
||||||
|
|
||||||
|
if (ret == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
if (dwType == REG_EXPAND_SZ)
|
||||||
|
{
|
||||||
|
cbData = ExpandEnvironmentStringsW(pvBuf, pvData,
|
||||||
|
pcbData ? *pcbData : 0);
|
||||||
|
dwType = REG_SZ;
|
||||||
|
if(pcbData && cbData > *pcbData)
|
||||||
|
ret = ERROR_MORE_DATA;
|
||||||
|
}
|
||||||
|
else if (pcbData)
|
||||||
|
CopyMemory(pvData, pvBuf, *pcbData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pvBuf) HeapFree(GetProcessHeap(), 0, pvBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pszSubKey && pszSubKey[0])
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
|
||||||
|
RegpApplyRestrictions(dwFlags, dwType, cbData, &ret);
|
||||||
|
|
||||||
|
if (pcbData && ret != ERROR_SUCCESS && (dwFlags & RRF_ZEROONFAILURE))
|
||||||
|
ZeroMemory(pvData, *pcbData);
|
||||||
|
|
||||||
|
if (pdwType) *pdwType = dwType;
|
||||||
|
if (pcbData) *pcbData = cbData;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif /* End of code copied from advapi32/reg/reg.c */
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* SetupDiBuildDriverInfoList (SETUPAPI.@)
|
* SetupDiBuildDriverInfoList (SETUPAPI.@)
|
||||||
*/
|
*/
|
||||||
|
@ -592,7 +786,95 @@ SetupDiBuildDriverInfoList(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (InstallParams.Flags & DI_ENUMSINGLEINF)
|
if (InstallParams.FlagsEx & DI_FLAGSEX_INSTALLEDDRIVER)
|
||||||
|
{
|
||||||
|
HKEY hDriverKey;
|
||||||
|
WCHAR InfFileName[MAX_PATH];
|
||||||
|
WCHAR InfFileSection[MAX_PATH];
|
||||||
|
ULONG RequiredSize;
|
||||||
|
struct DeviceInfoElement *devInfo = (struct DeviceInfoElement *)DeviceInfoData->Reserved;
|
||||||
|
struct InfFileDetails *infFileDetails = NULL;
|
||||||
|
FILETIME DriverDate;
|
||||||
|
LONG rc;
|
||||||
|
DWORD len;
|
||||||
|
|
||||||
|
/* Prepend inf directory name to file name */
|
||||||
|
len = sizeof(InfFileName) / sizeof(InfFileName[0]);
|
||||||
|
RequiredSize = GetSystemWindowsDirectoryW(InfFileName, len);
|
||||||
|
if (RequiredSize == 0 || RequiredSize >= len)
|
||||||
|
goto done;
|
||||||
|
if (*InfFileName && InfFileName[strlenW(InfFileName) - 1] != '\\')
|
||||||
|
strcatW(InfFileName, BackSlash);
|
||||||
|
strcatW(InfFileName, InfDirectory);
|
||||||
|
|
||||||
|
/* Read some information from registry, before creating the driver structure */
|
||||||
|
hDriverKey = SetupDiOpenDevRegKey(
|
||||||
|
DeviceInfoSet,
|
||||||
|
DeviceInfoData,
|
||||||
|
DICS_FLAG_GLOBAL,
|
||||||
|
0,
|
||||||
|
DIREG_DRV,
|
||||||
|
KEY_QUERY_VALUE);
|
||||||
|
if (hDriverKey == INVALID_HANDLE_VALUE)
|
||||||
|
goto done;
|
||||||
|
RequiredSize = len - strlenW(InfFileName);
|
||||||
|
rc = RegGetValueW(
|
||||||
|
hDriverKey,
|
||||||
|
NULL,
|
||||||
|
REGSTR_VAL_INFPATH,
|
||||||
|
RRF_RT_REG_SZ,
|
||||||
|
NULL,
|
||||||
|
&InfFileName[strlenW(InfFileName)],
|
||||||
|
&RequiredSize);
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
SetLastError(rc);
|
||||||
|
CloseHandle(hDriverKey);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
RequiredSize = sizeof(InfFileSection);
|
||||||
|
rc = RegGetValueW(
|
||||||
|
hDriverKey,
|
||||||
|
NULL,
|
||||||
|
REGSTR_VAL_INFSECTION,
|
||||||
|
RRF_RT_REG_SZ,
|
||||||
|
NULL,
|
||||||
|
InfFileSection,
|
||||||
|
&RequiredSize);
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
SetLastError(rc);
|
||||||
|
CloseHandle(hDriverKey);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
TRACE("Current driver in %s/%s\n", debugstr_w(InfFileName), debugstr_w(InfFileSection));
|
||||||
|
infFileDetails = CreateInfFileDetails(InfFileName);
|
||||||
|
if (!infFileDetails)
|
||||||
|
{
|
||||||
|
CloseHandle(hDriverKey);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
DriverDate.dwLowDateTime = DriverDate.dwHighDateTime = 0; /* FIXME */
|
||||||
|
CloseHandle(hDriverKey);
|
||||||
|
ret = AddKnownDriverToList(
|
||||||
|
pDriverListHead,
|
||||||
|
SPDIT_COMPATDRIVER,
|
||||||
|
&devInfo->ClassGuid,
|
||||||
|
infFileDetails,
|
||||||
|
InfFileName,
|
||||||
|
InfFileSection, /* Yes, we don't care of section extension */
|
||||||
|
L"DriverDescription", /* FIXME */
|
||||||
|
L"ProviderName", /* FIXME */
|
||||||
|
L"ManufacturerName", /* FIXME */
|
||||||
|
L"MatchingId", /* FIXME */
|
||||||
|
DriverDate,
|
||||||
|
0, /* FIXME: DriverVersion */
|
||||||
|
0);
|
||||||
|
if (!ret)
|
||||||
|
DereferenceInfFile(infFileDetails);
|
||||||
|
Result = FALSE;
|
||||||
|
}
|
||||||
|
else if (InstallParams.Flags & DI_ENUMSINGLEINF)
|
||||||
{
|
{
|
||||||
/* InstallParams.DriverPath contains the name of a .inf file */
|
/* InstallParams.DriverPath contains the name of a .inf file */
|
||||||
RequiredSize = strlenW(InstallParams.DriverPath) + 2;
|
RequiredSize = strlenW(InstallParams.DriverPath) + 2;
|
||||||
|
@ -1380,7 +1662,7 @@ SetupDiSetSelectedDriverW(
|
||||||
DriverInfoData->Reserved = (ULONG_PTR)ItemList;
|
DriverInfoData->Reserved = (ULONG_PTR)ItemList;
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
TRACE("Choosing driver whose rank is 0x%lx\n",
|
TRACE("Choosing driver whose rank is 0x%lx\n",
|
||||||
(*pDriverInfo)->DriverRank);
|
(*pDriverInfo)->Params.Rank);
|
||||||
if (DeviceInfoData)
|
if (DeviceInfoData)
|
||||||
memcpy(&DeviceInfoData->ClassGuid, &(*pDriverInfo)->ClassGuid, sizeof(GUID));
|
memcpy(&DeviceInfoData->ClassGuid, &(*pDriverInfo)->ClassGuid, sizeof(GUID));
|
||||||
}
|
}
|
||||||
|
@ -1719,6 +2001,58 @@ done:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* SetupDiGetDriverInstallParamsW (SETUPAPI.@)
|
||||||
|
*/
|
||||||
|
BOOL WINAPI
|
||||||
|
SetupDiGetDriverInstallParamsW(
|
||||||
|
IN HDEVINFO DeviceInfoSet,
|
||||||
|
IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
|
||||||
|
IN PSP_DRVINFO_DATA_W DriverInfoData,
|
||||||
|
OUT PSP_DRVINSTALL_PARAMS DriverInstallParams)
|
||||||
|
{
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
|
||||||
|
TRACE("%p %p %p %p\n", DeviceInfoSet, DeviceInfoData, DriverInfoData, DriverInstallParams);
|
||||||
|
|
||||||
|
if (!DeviceInfoSet || !DriverInfoData || !DriverInstallParams)
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
else if (DeviceInfoSet == (HDEVINFO)INVALID_HANDLE_VALUE)
|
||||||
|
SetLastError(ERROR_INVALID_HANDLE);
|
||||||
|
else if (((struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEV_INFO_SET_MAGIC)
|
||||||
|
SetLastError(ERROR_INVALID_HANDLE);
|
||||||
|
else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
|
||||||
|
SetLastError(ERROR_INVALID_USER_BUFFER);
|
||||||
|
else if (DriverInfoData->cbSize != sizeof(SP_DRVINFO_DATA_V1_W) && DriverInfoData->cbSize != sizeof(SP_DRVINFO_DATA_V2_W))
|
||||||
|
SetLastError(ERROR_INVALID_USER_BUFFER);
|
||||||
|
else if (DriverInstallParams->cbSize != sizeof(SP_DRVINSTALL_PARAMS))
|
||||||
|
SetLastError(ERROR_INVALID_USER_BUFFER);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SP_DEVINSTALL_PARAMS InstallParams;
|
||||||
|
|
||||||
|
InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
|
||||||
|
if (SetupDiGetDeviceInstallParamsW(DeviceInfoSet, DeviceInfoData, &InstallParams))
|
||||||
|
{
|
||||||
|
struct DriverInfoElement *driverInfo;
|
||||||
|
driverInfo = (struct DriverInfoElement *)InstallParams.Reserved;
|
||||||
|
if (driverInfo == NULL)
|
||||||
|
SetLastError(ERROR_NO_DRIVER_SELECTED);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(
|
||||||
|
DriverInstallParams,
|
||||||
|
&driverInfo->Params,
|
||||||
|
DriverInstallParams->cbSize);
|
||||||
|
ret = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("Returning %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* SetupDiSelectBestCompatDrv (SETUPAPI.@)
|
* SetupDiSelectBestCompatDrv (SETUPAPI.@)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -332,7 +332,7 @@
|
||||||
@ stdcall SetupDiGetDriverInfoDetailA(ptr ptr ptr ptr long ptr)
|
@ stdcall SetupDiGetDriverInfoDetailA(ptr ptr ptr ptr long ptr)
|
||||||
@ stdcall SetupDiGetDriverInfoDetailW(ptr ptr ptr ptr long ptr)
|
@ stdcall SetupDiGetDriverInfoDetailW(ptr ptr ptr ptr long ptr)
|
||||||
@ stub SetupDiGetDriverInstallParamsA
|
@ stub SetupDiGetDriverInstallParamsA
|
||||||
@ stub SetupDiGetDriverInstallParamsW
|
@ stdcall SetupDiGetDriverInstallParamsW(ptr ptr ptr ptr)
|
||||||
@ stub SetupDiGetDeviceInterfaceAlias
|
@ stub SetupDiGetDeviceInterfaceAlias
|
||||||
@ stdcall SetupDiGetDeviceInterfaceDetailA(long ptr ptr long ptr ptr)
|
@ stdcall SetupDiGetDeviceInterfaceDetailA(long ptr ptr long ptr ptr)
|
||||||
@ stdcall SetupDiGetDeviceInterfaceDetailW(long ptr ptr long ptr ptr)
|
@ stdcall SetupDiGetDeviceInterfaceDetailW(long ptr ptr long ptr ptr)
|
||||||
|
|
|
@ -95,7 +95,7 @@ struct DriverInfoElement /* Element of DeviceInfoSet.DriverListHead and DeviceIn
|
||||||
{
|
{
|
||||||
LIST_ENTRY ListEntry;
|
LIST_ENTRY ListEntry;
|
||||||
|
|
||||||
DWORD DriverRank;
|
SP_DRVINSTALL_PARAMS Params;
|
||||||
ULARGE_INTEGER DriverDate;
|
ULARGE_INTEGER DriverDate;
|
||||||
SP_DRVINFO_DATA_V2_W Info;
|
SP_DRVINFO_DATA_V2_W Info;
|
||||||
SP_DRVINFO_DETAIL_DATA_W Details;
|
SP_DRVINFO_DETAIL_DATA_W Details;
|
||||||
|
|
Loading…
Reference in a new issue