setupapi: Merge _SP_DRVINFO_DETAIL_DATA and DrvInfoDetailData

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2019-02-07 23:45:11 +01:00
parent b662896cf4
commit c4988999ac
4 changed files with 60 additions and 55 deletions

View file

@ -146,36 +146,38 @@ func (deviceInfoSet DevInfo) SetSelectedDriver(deviceInfoData *DevInfoData, driv
return SetupDiSetSelectedDriver(deviceInfoSet, deviceInfoData, driverInfoData)
}
//sys setupDiGetDriverInfoDetail(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData, driverInfoDetailData *_SP_DRVINFO_DETAIL_DATA, driverInfoDetailDataSize uint32, requiredSize *uint32) (err error) = setupapi.SetupDiGetDriverInfoDetailW
//sys setupDiGetDriverInfoDetail(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData, driverInfoDetailData *DrvInfoDetailData, driverInfoDetailDataSize uint32, requiredSize *uint32) (err error) = setupapi.SetupDiGetDriverInfoDetailW
// SetupDiGetDriverInfoDetail function retrieves driver information detail for a device information set or a particular device information element in the device information set.
func SetupDiGetDriverInfoDetail(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) (driverInfoDetailData *DrvInfoDetailData, err error) {
func SetupDiGetDriverInfoDetail(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) (*DrvInfoDetailData, error) {
const bufCapacity = 0x800
buf := [bufCapacity]byte{}
var bufLen uint32
_data := (*_SP_DRVINFO_DETAIL_DATA)(unsafe.Pointer(&buf[0]))
_data.Size = uint32(unsafe.Sizeof(*_data))
data := (*DrvInfoDetailData)(unsafe.Pointer(&buf[0]))
data.size = uint32(unsafe.Sizeof(*data))
err = setupDiGetDriverInfoDetail(deviceInfoSet, deviceInfoData, driverInfoData, _data, bufCapacity, &bufLen)
err := setupDiGetDriverInfoDetail(deviceInfoSet, deviceInfoData, driverInfoData, data, bufCapacity, &bufLen)
if err == nil {
// The buffer was was sufficiently big.
return _data.toGo(bufLen), nil
data.size = bufLen
return data, nil
}
if errWin, ok := err.(syscall.Errno); ok && errWin == windows.ERROR_INSUFFICIENT_BUFFER {
// The buffer was too small. Now that we got the required size, create another one big enough and retry.
buf := make([]byte, bufLen)
_data := (*_SP_DRVINFO_DETAIL_DATA)(unsafe.Pointer(&buf[0]))
_data.Size = uint32(unsafe.Sizeof(*_data))
data := (*DrvInfoDetailData)(unsafe.Pointer(&buf[0]))
data.size = uint32(unsafe.Sizeof(*data))
err = setupDiGetDriverInfoDetail(deviceInfoSet, deviceInfoData, driverInfoData, _data, bufLen, &bufLen)
err = setupDiGetDriverInfoDetail(deviceInfoSet, deviceInfoData, driverInfoData, data, bufLen, &bufLen)
if err == nil {
return _data.toGo(bufLen), nil
data.size = bufLen
return data, nil
}
}
return
return nil, err
}
// GetDriverInfoDetail method retrieves driver information detail for a device information set or a particular device information element in the device information set.

View file

@ -217,11 +217,12 @@ func TestDevInfo_BuildDriverInfoList(t *testing.T) {
if driverDetailData.IsCompatible("foobar-aab6e3a4-144e-4786-88d3-6cec361e1edd") {
t.Error("Invalid HWID compatibitlity reported")
}
if !driverDetailData.IsCompatible(strings.ToUpper(driverDetailData.HardwareID)) {
if !driverDetailData.IsCompatible(strings.ToUpper(driverDetailData.GetHardwareID())) {
t.Error("HWID compatibitlity missed")
}
for k := range driverDetailData.CompatIDs {
if !driverDetailData.IsCompatible(strings.ToUpper(driverDetailData.CompatIDs[k])) {
a := driverDetailData.GetCompatIDs()
for k := range a {
if !driverDetailData.IsCompatible(strings.ToUpper(a[k])) {
t.Error("HWID compatibitlity missed")
}
}

View file

@ -368,75 +368,77 @@ func (data *DrvInfoData) IsNewer(driverDate windows.Filetime, driverVersion uint
return false
}
type _SP_DRVINFO_DETAIL_DATA struct {
Size uint32
// DrvInfoDetailData is driver information details structure (provides detailed information about a particular driver information structure)
type DrvInfoDetailData struct {
size uint32 // On input, this must be exactly the sizeof(DrvInfoDetailData). On output, we set this member to the actual size of structure data.
InfDate windows.Filetime
CompatIDsOffset uint32
CompatIDsLength uint32
compatIDsOffset uint32
compatIDsLength uint32
_ uintptr
SectionName [LINE_LEN]uint16
InfFileName [windows.MAX_PATH]uint16
DrvDescription [LINE_LEN]uint16
HardwareID [1]uint16
sectionName [LINE_LEN]uint16
infFileName [windows.MAX_PATH]uint16
drvDescription [LINE_LEN]uint16
hardwareID [1]uint16
}
func (_data *_SP_DRVINFO_DETAIL_DATA) toGo(bufLen uint32) (DriverInfoDetailData *DrvInfoDetailData) {
DriverInfoDetailData = &DrvInfoDetailData{
InfDate: _data.InfDate,
SectionName: windows.UTF16ToString(_data.SectionName[:]),
InfFileName: windows.UTF16ToString(_data.InfFileName[:]),
DrvDescription: windows.UTF16ToString(_data.DrvDescription[:]),
CompatIDs: []string{},
func (data *DrvInfoDetailData) GetSectionName() string {
return windows.UTF16ToString(data.sectionName[:])
}
bufW := _data.getBuf(bufLen)
if _data.CompatIDsOffset > 1 {
DriverInfoDetailData.HardwareID = windows.UTF16ToString(bufW[:wcslen(bufW)])
func (data *DrvInfoDetailData) GetInfFileName() string {
return windows.UTF16ToString(data.infFileName[:])
}
if _data.CompatIDsLength > 0 {
bufW = bufW[_data.CompatIDsOffset : _data.CompatIDsOffset+_data.CompatIDsLength]
func (data *DrvInfoDetailData) GetDrvDescription() string {
return windows.UTF16ToString(data.drvDescription[:])
}
func (data *DrvInfoDetailData) GetHardwareID() string {
if data.compatIDsOffset > 1 {
bufW := data.getBuf()
return windows.UTF16ToString(bufW[:wcslen(bufW)])
}
return ""
}
func (data *DrvInfoDetailData) GetCompatIDs() []string {
a := make([]string, 0)
if data.compatIDsLength > 0 {
bufW := data.getBuf()
bufW = bufW[data.compatIDsOffset : data.compatIDsOffset+data.compatIDsLength]
for i := 0; i < len(bufW); {
j := i + wcslen(bufW[i:])
if i < j {
DriverInfoDetailData.CompatIDs = append(DriverInfoDetailData.CompatIDs, windows.UTF16ToString(bufW[i:j]))
a = append(a, windows.UTF16ToString(bufW[i:j]))
}
i = j + 1
}
}
return
return a
}
func (_data *_SP_DRVINFO_DETAIL_DATA) getBuf(bufLen uint32) []uint16 {
len := (bufLen - uint32(unsafe.Offsetof(_data.HardwareID))) / 2
func (data *DrvInfoDetailData) getBuf() []uint16 {
len := (data.size - uint32(unsafe.Offsetof(data.hardwareID))) / 2
sl := struct {
addr *uint16
len int
cap int
}{&_data.HardwareID[0], int(len), int(len)}
}{&data.hardwareID[0], int(len), int(len)}
return *(*[]uint16)(unsafe.Pointer(&sl))
}
// DrvInfoDetailData is driver information details structure (provides detailed information about a particular driver information structure)
type DrvInfoDetailData struct {
InfDate windows.Filetime
SectionName string
InfFileName string
DrvDescription string
HardwareID string
CompatIDs []string
}
// IsCompatible method tests if given hardware ID matches the driver or is listed on the compatible ID list.
func (driverInfoDetailData *DrvInfoDetailData) IsCompatible(hwid string) bool {
func (data *DrvInfoDetailData) IsCompatible(hwid string) bool {
hwidLC := strings.ToLower(hwid)
if strings.ToLower(driverInfoDetailData.HardwareID) == hwidLC {
if strings.ToLower(data.GetHardwareID()) == hwidLC {
return true
}
for i := range driverInfoDetailData.CompatIDs {
if strings.ToLower(driverInfoDetailData.CompatIDs[i]) == hwidLC {
a := data.GetCompatIDs()
for i := range a {
if strings.ToLower(a[i]) == hwidLC {
return true
}
}

View file

@ -187,7 +187,7 @@ func SetupDiSetSelectedDriver(deviceInfoSet DevInfo, deviceInfoData *DevInfoData
return
}
func setupDiGetDriverInfoDetail(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData, driverInfoDetailData *_SP_DRVINFO_DETAIL_DATA, driverInfoDetailDataSize uint32, requiredSize *uint32) (err error) {
func setupDiGetDriverInfoDetail(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData, driverInfoDetailData *DrvInfoDetailData, driverInfoDetailDataSize uint32, requiredSize *uint32) (err error) {
r1, _, e1 := syscall.Syscall6(procSetupDiGetDriverInfoDetailW.Addr(), 6, uintptr(deviceInfoSet), uintptr(unsafe.Pointer(deviceInfoData)), uintptr(unsafe.Pointer(driverInfoData)), uintptr(unsafe.Pointer(driverInfoDetailData)), uintptr(driverInfoDetailDataSize), uintptr(unsafe.Pointer(requiredSize)))
if r1 == 0 {
if e1 != 0 {