setupapi: unify ERROR_INSUFFICIENT_BUFFER handling
Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
parent
e924280baa
commit
a1a97d1e41
@ -150,34 +150,21 @@ func (deviceInfoSet DevInfo) SetSelectedDriver(deviceInfoData *DevInfoData, driv
|
|||||||
|
|
||||||
// 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) (*DrvInfoDetailData, error) {
|
func SetupDiGetDriverInfoDetail(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, driverInfoData *DrvInfoData) (*DrvInfoDetailData, error) {
|
||||||
const bufCapacity = 0x800
|
reqSize := uint32(2048)
|
||||||
buf := [bufCapacity]byte{}
|
for {
|
||||||
var bufLen uint32
|
buf := make([]byte, reqSize)
|
||||||
|
|
||||||
data := (*DrvInfoDetailData)(unsafe.Pointer(&buf[0]))
|
data := (*DrvInfoDetailData)(unsafe.Pointer(&buf[0]))
|
||||||
data.size = sizeofDrvInfoDetailData
|
data.size = sizeofDrvInfoDetailData
|
||||||
|
err := setupDiGetDriverInfoDetail(deviceInfoSet, deviceInfoData, driverInfoData, data, uint32(len(buf)), &reqSize)
|
||||||
err := setupDiGetDriverInfoDetail(deviceInfoSet, deviceInfoData, driverInfoData, data, bufCapacity, &bufLen)
|
if err == windows.ERROR_INSUFFICIENT_BUFFER {
|
||||||
if err == nil {
|
continue
|
||||||
// The buffer was was sufficiently big.
|
|
||||||
data.size = bufLen
|
|
||||||
return data, nil
|
|
||||||
}
|
}
|
||||||
|
if err != nil {
|
||||||
if errWin, ok := err.(windows.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 := (*DrvInfoDetailData)(unsafe.Pointer(&buf[0]))
|
|
||||||
data.size = sizeofDrvInfoDetailData
|
|
||||||
|
|
||||||
err = setupDiGetDriverInfoDetail(deviceInfoSet, deviceInfoData, driverInfoData, data, bufLen, &bufLen)
|
|
||||||
if err == nil {
|
|
||||||
data.size = bufLen
|
|
||||||
return data, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, err
|
return nil, err
|
||||||
|
}
|
||||||
|
data.size = reqSize
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DriverInfoDetail method retrieves driver information detail for a device information set or a particular device information element in the device information set.
|
// DriverInfoDetail method retrieves driver information detail for a device information set or a particular device information element in the device information set.
|
||||||
@ -238,24 +225,19 @@ func (deviceInfoSet DevInfo) OpenDevRegKey(DeviceInfoData *DevInfoData, Scope DI
|
|||||||
|
|
||||||
// SetupDiGetDeviceRegistryProperty function retrieves a specified Plug and Play device property.
|
// SetupDiGetDeviceRegistryProperty function retrieves a specified Plug and Play device property.
|
||||||
func SetupDiGetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, property SPDRP) (value interface{}, err error) {
|
func SetupDiGetDeviceRegistryProperty(deviceInfoSet DevInfo, deviceInfoData *DevInfoData, property SPDRP) (value interface{}, err error) {
|
||||||
buf := make([]byte, 0x100)
|
reqSize := uint32(256)
|
||||||
var dataType, bufLen uint32
|
for {
|
||||||
err = setupDiGetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property, &dataType, &buf[0], uint32(cap(buf)), &bufLen)
|
var dataType uint32
|
||||||
if err == nil {
|
buf := make([]byte, reqSize)
|
||||||
// The buffer was sufficiently big.
|
err = setupDiGetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property, &dataType, &buf[0], uint32(len(buf)), &reqSize)
|
||||||
return getRegistryValue(buf[:bufLen], dataType)
|
if err == windows.ERROR_INSUFFICIENT_BUFFER {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
if err != nil {
|
||||||
if errWin, ok := err.(windows.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)
|
|
||||||
err = setupDiGetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property, &dataType, &buf[0], uint32(cap(buf)), &bufLen)
|
|
||||||
if err == nil {
|
|
||||||
return getRegistryValue(buf[:bufLen], dataType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
}
|
||||||
|
return getRegistryValue(buf[:reqSize], dataType)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRegistryValue(buf []byte, dataType uint32) (interface{}, error) {
|
func getRegistryValue(buf []byte, dataType uint32) (interface{}, error) {
|
||||||
@ -442,10 +424,6 @@ func SetupDiClassGuidsFromNameEx(className string, machineName string) ([]window
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const bufCapacity = 4
|
|
||||||
var buf [bufCapacity]windows.GUID
|
|
||||||
var bufLen uint32
|
|
||||||
|
|
||||||
var machineNameUTF16 *uint16
|
var machineNameUTF16 *uint16
|
||||||
if machineName != "" {
|
if machineName != "" {
|
||||||
machineNameUTF16, err = windows.UTF16PtrFromString(machineName)
|
machineNameUTF16, err = windows.UTF16PtrFromString(machineName)
|
||||||
@ -454,22 +432,18 @@ func SetupDiClassGuidsFromNameEx(className string, machineName string) ([]window
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = setupDiClassGuidsFromNameEx(classNameUTF16, &buf[0], bufCapacity, &bufLen, machineNameUTF16, 0)
|
reqSize := uint32(4)
|
||||||
if err == nil {
|
for {
|
||||||
// The GUID array was sufficiently big. Return its slice.
|
buf := make([]windows.GUID, reqSize)
|
||||||
return buf[:bufLen], nil
|
err = setupDiClassGuidsFromNameEx(classNameUTF16, &buf[0], uint32(len(buf)), &reqSize, machineNameUTF16, 0)
|
||||||
|
if err == windows.ERROR_INSUFFICIENT_BUFFER {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
if err != nil {
|
||||||
if errWin, ok := err.(windows.Errno); ok && errWin == windows.ERROR_INSUFFICIENT_BUFFER {
|
|
||||||
// The GUID array was too small. Now that we got the required size, create another one big enough and retry.
|
|
||||||
buf := make([]windows.GUID, bufLen)
|
|
||||||
err = setupDiClassGuidsFromNameEx(classNameUTF16, &buf[0], bufLen, &bufLen, machineNameUTF16, 0)
|
|
||||||
if err == nil {
|
|
||||||
return buf[:bufLen], nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, err
|
return nil, err
|
||||||
|
}
|
||||||
|
return buf[:reqSize], nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//sys setupDiGetSelectedDevice(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (err error) = setupapi.SetupDiGetSelectedDevice
|
//sys setupDiGetSelectedDevice(deviceInfoSet DevInfo, deviceInfoData *DevInfoData) (err error) = setupapi.SetupDiGetSelectedDevice
|
||||||
|
Loading…
Reference in New Issue
Block a user