From 5811447b382ce1197e9c76d676a65515309a5b60 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Thu, 18 Apr 2019 10:37:04 +0200 Subject: [PATCH] setupapi: Revise DrvInfoDetailData struct size calculation Go adds trailing padding to DrvInfoDetailData struct in GOARCH=386 which confuses SetupAPI expecting exactly sizeof(SP_DRVINFO_DETAIL_DATA). Signed-off-by: Simon Rozman --- tun/wintun/setupapi/setupapi_windows.go | 7 +++++-- tun/wintun/setupapi/types_windows.go | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tun/wintun/setupapi/setupapi_windows.go b/tun/wintun/setupapi/setupapi_windows.go index 71732a4..1731f4b 100644 --- a/tun/wintun/setupapi/setupapi_windows.go +++ b/tun/wintun/setupapi/setupapi_windows.go @@ -155,7 +155,10 @@ func SetupDiGetDriverInfoDetail(deviceInfoSet DevInfo, deviceInfoData *DevInfoDa var bufLen uint32 data := (*DrvInfoDetailData)(unsafe.Pointer(&buf[0])) - data.size = uint32(unsafe.Sizeof(*data)) + + // unsafe.Sizeof(data) >= sizeof(SP_DRVINFO_DETAIL_DATA) due to Go trailing padding. SetupAPI expects exactly sizeof(SP_DRVINFO_DETAIL_DATA). + sizeAPI := unsafe.Offsetof(data.hardwareID) + unsafe.Sizeof(data.hardwareID) + data.size = uint32(sizeAPI) err := setupDiGetDriverInfoDetail(deviceInfoSet, deviceInfoData, driverInfoData, data, bufCapacity, &bufLen) if err == nil { @@ -168,7 +171,7 @@ func SetupDiGetDriverInfoDetail(deviceInfoSet DevInfo, deviceInfoData *DevInfoDa // 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 = uint32(unsafe.Sizeof(*data)) + data.size = uint32(sizeAPI) err = setupDiGetDriverInfoDetail(deviceInfoSet, deviceInfoData, driverInfoData, data, bufLen, &bufLen) if err == nil { diff --git a/tun/wintun/setupapi/types_windows.go b/tun/wintun/setupapi/types_windows.go index 8acb31b..a04237d 100644 --- a/tun/wintun/setupapi/types_windows.go +++ b/tun/wintun/setupapi/types_windows.go @@ -28,6 +28,7 @@ const ( // Define maximum string length constants // const ( + ANYSIZE_ARRAY = 1 LINE_LEN = 256 // Windows 9x-compatible maximum for displayable strings coming from a device INF. MAX_INF_STRING_LENGTH = 4096 // Actual maximum size of an INF string (including string substitutions). MAX_INF_SECTION_NAME_LENGTH = 255 // For Windows 9x compatibility, INF section names should be constrained to 32 characters. @@ -378,7 +379,7 @@ type DrvInfoDetailData struct { sectionName [LINE_LEN]uint16 infFileName [windows.MAX_PATH]uint16 drvDescription [LINE_LEN]uint16 - hardwareID [1]uint16 + hardwareID [ANYSIZE_ARRAY]uint16 } func (data *DrvInfoDetailData) GetSectionName() string {