mirror of
https://github.com/reactos/reactos.git
synced 2025-04-19 20:19:26 +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_DIDCOMPATINFO | /* 0x00000020 */
|
||||
DI_FLAGSEX_ALLOWEXCLUDEDDRVS | /* 0x00000800 */
|
||||
DI_FLAGSEX_NO_DRVREG_MODIFY; /* 0x00008000 */
|
||||
DI_FLAGSEX_NO_DRVREG_MODIFY | /* 0x00008000 */
|
||||
DI_FLAGSEX_INSTALLEDDRIVER; /* 0x04000000 */
|
||||
BOOL ret = FALSE;
|
||||
|
||||
/* FIXME: add support for more flags */
|
||||
|
|
|
@ -105,26 +105,26 @@ DestroyDriverInfoElement(struct DriverInfoElement* driverInfo)
|
|||
* Helper functions for SetupDiBuildDriverInfoList
|
||||
*/
|
||||
static BOOL
|
||||
AddDriverToList(
|
||||
AddKnownDriverToList(
|
||||
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 SectionName,
|
||||
IN LPCWSTR DriverDescription,
|
||||
IN LPCWSTR ProviderName,
|
||||
IN LPCWSTR ManufacturerName,
|
||||
IN LPCWSTR MatchingId,
|
||||
FILETIME DriverDate,
|
||||
DWORDLONG DriverVersion,
|
||||
IN FILETIME DriverDate,
|
||||
IN DWORDLONG DriverVersion,
|
||||
IN DWORD Rank)
|
||||
{
|
||||
struct DriverInfoElement *driverInfo = NULL;
|
||||
HANDLE hFile = INVALID_HANDLE_VALUE;
|
||||
DWORD RequiredSize = 128; /* Initial buffer size */
|
||||
BOOL Result = FALSE;
|
||||
PLIST_ENTRY PreviousEntry;
|
||||
LPWSTR InfInstallSection = NULL;
|
||||
LPWSTR pDot;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
driverInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(struct DriverInfoElement));
|
||||
|
@ -135,6 +135,9 @@ AddDriverToList(
|
|||
}
|
||||
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.Reserved = (ULONG_PTR)driverInfo;
|
||||
|
||||
|
@ -154,20 +157,13 @@ AddDriverToList(
|
|||
goto cleanup;
|
||||
|
||||
/* Fill SectionName field */
|
||||
Result = SetupGetStringFieldW(
|
||||
&ContextDevice,
|
||||
1,
|
||||
driverInfo->Details.SectionName, LINE_LEN,
|
||||
NULL);
|
||||
if (!Result)
|
||||
goto cleanup;
|
||||
strncpyW(driverInfo->Details.SectionName, SectionName, LINE_LEN);
|
||||
pDot = strchrW(driverInfo->Details.SectionName, '.');
|
||||
if (pDot)
|
||||
*pDot = UNICODE_NULL;
|
||||
|
||||
/* Fill DrvDescription field */
|
||||
Result = SetupGetStringFieldW(
|
||||
&ContextDevice,
|
||||
0, /* Field index */
|
||||
driverInfo->Details.DrvDescription, LINE_LEN,
|
||||
NULL);
|
||||
strncpyW(driverInfo->Details.DrvDescription, DriverDescription, LINE_LEN);
|
||||
|
||||
/* Copy MatchingId information */
|
||||
if (MatchingId)
|
||||
|
@ -183,30 +179,11 @@ AddDriverToList(
|
|||
else
|
||||
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",
|
||||
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->ClassGuid, ClassGuid, sizeof(GUID));
|
||||
driverInfo->Info.DriverType = DriverType;
|
||||
|
@ -233,8 +210,8 @@ AddDriverToList(
|
|||
{
|
||||
struct DriverInfoElement *CurrentDriver;
|
||||
CurrentDriver = CONTAINING_RECORD(PreviousEntry, struct DriverInfoElement, ListEntry);
|
||||
if (CurrentDriver->DriverRank > Rank ||
|
||||
(CurrentDriver->DriverRank == Rank && CurrentDriver->DriverDate.QuadPart < driverInfo->DriverDate.QuadPart))
|
||||
if (CurrentDriver->Params.Rank > Rank ||
|
||||
(CurrentDriver->Params.Rank == Rank && CurrentDriver->DriverDate.QuadPart < driverInfo->DriverDate.QuadPart))
|
||||
{
|
||||
/* Insert before the current item */
|
||||
InsertHeadList(PreviousEntry->Blink, &driverInfo->ListEntry);
|
||||
|
@ -259,7 +236,78 @@ cleanup:
|
|||
}
|
||||
if (hFile != INVALID_HANDLE_VALUE)
|
||||
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;
|
||||
}
|
||||
|
@ -517,6 +565,152 @@ done:
|
|||
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.@)
|
||||
*/
|
||||
|
@ -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 */
|
||||
RequiredSize = strlenW(InstallParams.DriverPath) + 2;
|
||||
|
@ -1380,7 +1662,7 @@ SetupDiSetSelectedDriverW(
|
|||
DriverInfoData->Reserved = (ULONG_PTR)ItemList;
|
||||
ret = TRUE;
|
||||
TRACE("Choosing driver whose rank is 0x%lx\n",
|
||||
(*pDriverInfo)->DriverRank);
|
||||
(*pDriverInfo)->Params.Rank);
|
||||
if (DeviceInfoData)
|
||||
memcpy(&DeviceInfoData->ClassGuid, &(*pDriverInfo)->ClassGuid, sizeof(GUID));
|
||||
}
|
||||
|
@ -1719,6 +2001,58 @@ done:
|
|||
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.@)
|
||||
*/
|
||||
|
|
|
@ -332,7 +332,7 @@
|
|||
@ stdcall SetupDiGetDriverInfoDetailA(ptr ptr ptr ptr long ptr)
|
||||
@ stdcall SetupDiGetDriverInfoDetailW(ptr ptr ptr ptr long ptr)
|
||||
@ stub SetupDiGetDriverInstallParamsA
|
||||
@ stub SetupDiGetDriverInstallParamsW
|
||||
@ stdcall SetupDiGetDriverInstallParamsW(ptr ptr ptr ptr)
|
||||
@ stub SetupDiGetDeviceInterfaceAlias
|
||||
@ stdcall SetupDiGetDeviceInterfaceDetailA(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;
|
||||
|
||||
DWORD DriverRank;
|
||||
SP_DRVINSTALL_PARAMS Params;
|
||||
ULARGE_INTEGER DriverDate;
|
||||
SP_DRVINFO_DATA_V2_W Info;
|
||||
SP_DRVINFO_DETAIL_DATA_W Details;
|
||||
|
|
Loading…
Reference in a new issue