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) 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. // 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 const bufCapacity = 0x800
buf := [bufCapacity]byte{} buf := [bufCapacity]byte{}
var bufLen uint32 var bufLen uint32
_data := (*_SP_DRVINFO_DETAIL_DATA)(unsafe.Pointer(&buf[0])) data := (*DrvInfoDetailData)(unsafe.Pointer(&buf[0]))
_data.Size = uint32(unsafe.Sizeof(*_data)) 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 { if err == nil {
// The buffer was was sufficiently big. // 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 { 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. // The buffer was too small. Now that we got the required size, create another one big enough and retry.
buf := make([]byte, bufLen) buf := make([]byte, bufLen)
_data := (*_SP_DRVINFO_DETAIL_DATA)(unsafe.Pointer(&buf[0])) data := (*DrvInfoDetailData)(unsafe.Pointer(&buf[0]))
_data.Size = uint32(unsafe.Sizeof(*_data)) 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 { 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. // 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") { if driverDetailData.IsCompatible("foobar-aab6e3a4-144e-4786-88d3-6cec361e1edd") {
t.Error("Invalid HWID compatibitlity reported") 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") t.Error("HWID compatibitlity missed")
} }
for k := range driverDetailData.CompatIDs { a := driverDetailData.GetCompatIDs()
if !driverDetailData.IsCompatible(strings.ToUpper(driverDetailData.CompatIDs[k])) { for k := range a {
if !driverDetailData.IsCompatible(strings.ToUpper(a[k])) {
t.Error("HWID compatibitlity missed") t.Error("HWID compatibitlity missed")
} }
} }

View file

@ -368,75 +368,77 @@ func (data *DrvInfoData) IsNewer(driverDate windows.Filetime, driverVersion uint
return false return false
} }
type _SP_DRVINFO_DETAIL_DATA struct { // DrvInfoDetailData is driver information details structure (provides detailed information about a particular driver information structure)
Size uint32 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 InfDate windows.Filetime
CompatIDsOffset uint32 compatIDsOffset uint32
CompatIDsLength uint32 compatIDsLength uint32
_ uintptr _ uintptr
SectionName [LINE_LEN]uint16 sectionName [LINE_LEN]uint16
InfFileName [windows.MAX_PATH]uint16 infFileName [windows.MAX_PATH]uint16
DrvDescription [LINE_LEN]uint16 drvDescription [LINE_LEN]uint16
HardwareID [1]uint16 hardwareID [1]uint16
} }
func (_data *_SP_DRVINFO_DETAIL_DATA) toGo(bufLen uint32) (DriverInfoDetailData *DrvInfoDetailData) { func (data *DrvInfoDetailData) GetSectionName() string {
DriverInfoDetailData = &DrvInfoDetailData{ return windows.UTF16ToString(data.sectionName[:])
InfDate: _data.InfDate,
SectionName: windows.UTF16ToString(_data.SectionName[:]),
InfFileName: windows.UTF16ToString(_data.InfFileName[:]),
DrvDescription: windows.UTF16ToString(_data.DrvDescription[:]),
CompatIDs: []string{},
} }
bufW := _data.getBuf(bufLen) func (data *DrvInfoDetailData) GetInfFileName() string {
return windows.UTF16ToString(data.infFileName[:])
if _data.CompatIDsOffset > 1 {
DriverInfoDetailData.HardwareID = windows.UTF16ToString(bufW[:wcslen(bufW)])
} }
if _data.CompatIDsLength > 0 { func (data *DrvInfoDetailData) GetDrvDescription() string {
bufW = bufW[_data.CompatIDsOffset : _data.CompatIDsOffset+_data.CompatIDsLength] 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); { for i := 0; i < len(bufW); {
j := i + wcslen(bufW[i:]) j := i + wcslen(bufW[i:])
if i < j { if i < j {
DriverInfoDetailData.CompatIDs = append(DriverInfoDetailData.CompatIDs, windows.UTF16ToString(bufW[i:j])) a = append(a, windows.UTF16ToString(bufW[i:j]))
} }
i = j + 1 i = j + 1
} }
} }
return return a
} }
func (_data *_SP_DRVINFO_DETAIL_DATA) getBuf(bufLen uint32) []uint16 { func (data *DrvInfoDetailData) getBuf() []uint16 {
len := (bufLen - uint32(unsafe.Offsetof(_data.HardwareID))) / 2 len := (data.size - uint32(unsafe.Offsetof(data.hardwareID))) / 2
sl := struct { sl := struct {
addr *uint16 addr *uint16
len int len int
cap int cap int
}{&_data.HardwareID[0], int(len), int(len)} }{&data.hardwareID[0], int(len), int(len)}
return *(*[]uint16)(unsafe.Pointer(&sl)) 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. // 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) hwidLC := strings.ToLower(hwid)
if strings.ToLower(driverInfoDetailData.HardwareID) == hwidLC { if strings.ToLower(data.GetHardwareID()) == hwidLC {
return true return true
} }
for i := range driverInfoDetailData.CompatIDs { a := data.GetCompatIDs()
if strings.ToLower(driverInfoDetailData.CompatIDs[i]) == hwidLC { for i := range a {
if strings.ToLower(a[i]) == hwidLC {
return true return true
} }
} }

View file

@ -187,7 +187,7 @@ func SetupDiSetSelectedDriver(deviceInfoSet DevInfo, deviceInfoData *DevInfoData
return 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))) 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 r1 == 0 {
if e1 != 0 { if e1 != 0 {