Skip to content

Commit bbe751e

Browse files
committed
refactor: deprecate old methods and point to upstream lib
deprecate methods implemented in the upstream x/sys/windows library remove pkg/errors dependency and use native error wrapping
1 parent 548f212 commit bbe751e

File tree

9 files changed

+78
-241
lines changed

9 files changed

+78
-241
lines changed

constants.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,9 @@
2121
package windows
2222

2323
const (
24-
// This process access rights are missing from Go's syscall package as of 1.10.3
25-
26-
// PROCESS_VM_READ right allows to read memory from the target process.
24+
// Deprecated: use x/sys/windows
2725
PROCESS_VM_READ = 0x10
2826

29-
// PROCESS_QUERY_LIMITED_INFORMATION right allows to access a subset of the
30-
// information granted by PROCESS_QUERY_INFORMATION. Not available in XP
31-
// and Server 2003.
27+
// Deprecated: use x/sys/windows
3228
PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
3329
)

doc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@ package windows
2020

2121
// Use "GOOS=windows go generate -v -x" to generate the sources.
2222
// Add -trace to enable debug prints around syscalls.
23-
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -systemdll=true -output=zsyscall_windows.go kernel32.go version.go psapi.go ntdll.go
23+
//go:generate go run golang.org/x/sys/windows/mkwinsyscall -systemdll=true -output=zsyscall_windows.go kernel32.go version.go psapi.go ntdll.go
2424
//go:generate go run .ci/scripts/fix_generated.go -input zsyscall_windows.go
2525
//go:generate go-licenser

go.mod

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@ module github.com/elastic/go-windows
33
go 1.17
44

55
require (
6-
github.com/pkg/errors v0.8.1
76
github.com/stretchr/testify v1.3.0
8-
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a
7+
golang.org/x/sys v0.24.0
98
)
109

1110
require (

go.sum

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
22
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3-
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
4-
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
53
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
64
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
75
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
86
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
97
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
10-
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ=
11-
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
8+
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
9+
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=

kernel32.go

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,20 @@
2121
package windows
2222

2323
import (
24+
"errors"
2425
"fmt"
2526
"syscall"
2627
"time"
2728
"unsafe"
2829

29-
"github.com/pkg/errors"
30+
"golang.org/x/sys/windows"
3031
)
3132

3233
// Syscalls
3334
//sys _GetNativeSystemInfo(systemInfo *SystemInfo) = kernel32.GetNativeSystemInfo
3435
//sys _GetTickCount64() (millis uint64, err error) = kernel32.GetTickCount64
3536
//sys _GetSystemTimes(idleTime *syscall.Filetime, kernelTime *syscall.Filetime, userTime *syscall.Filetime) (err error) = kernel32.GetSystemTimes
3637
//sys _GlobalMemoryStatusEx(buffer *MemoryStatusEx) (err error) = kernel32.GlobalMemoryStatusEx
37-
//sys _ReadProcessMemory(handle syscall.Handle, baseAddress uintptr, buffer uintptr, size uintptr, numRead *uintptr) (err error) = kernel32.ReadProcessMemory
3838
//sys _GetProcessHandleCount(handle syscall.Handle, pdwHandleCount *uint32) (err error) = kernel32.GetProcessHandleCount
3939

4040
var (
@@ -194,7 +194,7 @@ func GetSystemTimes() (idle, kernel, user time.Duration, err error) {
194194
var idleTime, kernelTime, userTime syscall.Filetime
195195
err = _GetSystemTimes(&idleTime, &kernelTime, &userTime)
196196
if err != nil {
197-
return 0, 0, 0, errors.Wrap(err, "GetSystemTimes failed")
197+
return 0, 0, 0, fmt.Errorf("GetSystemTimes failed: %w", err)
198198
}
199199

200200
idle = FiletimeToDuration(&idleTime)
@@ -219,32 +219,30 @@ func GlobalMemoryStatusEx() (MemoryStatusEx, error) {
219219
memoryStatusEx := MemoryStatusEx{length: sizeofMemoryStatusEx}
220220
err := _GlobalMemoryStatusEx(&memoryStatusEx)
221221
if err != nil {
222-
return MemoryStatusEx{}, errors.Wrap(err, "GlobalMemoryStatusEx failed")
222+
return MemoryStatusEx{}, fmt.Errorf("GlobalMemoryStatusEx failed: %w", err)
223223
}
224224

225225
return memoryStatusEx, nil
226226
}
227227

228-
// ReadProcessMemory reads from another process memory. The Handle needs to have
229-
// the PROCESS_VM_READ right.
230-
// A zero-byte read is a no-op, no error is returned.
231-
func ReadProcessMemory(handle syscall.Handle, baseAddress uintptr, dest []byte) (numRead uintptr, err error) {
228+
// Deprecated: use x/sys/windows
229+
func ReadProcessMemory(handle syscall.Handle, baseAddress uintptr, dest []byte) (uintptr, error) {
232230
n := len(dest)
233231
if n == 0 {
234232
return 0, nil
235233
}
236-
if err = _ReadProcessMemory(handle, baseAddress, uintptr(unsafe.Pointer(&dest[0])), uintptr(n), &numRead); err != nil {
237-
return 0, err
238-
}
239-
return numRead, nil
234+
235+
var numRead uintptr
236+
err := windows.ReadProcessMemory(windows.Handle(handle), baseAddress, &dest[0], uintptr(n), &numRead)
237+
return numRead, err
240238
}
241239

242240
// GetProcessHandleCount retrieves the number of open handles of a process.
243241
// https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-getprocesshandlecount
244242
func GetProcessHandleCount(process syscall.Handle) (uint32, error) {
245243
var count uint32
246244
if err := _GetProcessHandleCount(process, &count); err != nil {
247-
return 0, errors.Wrap(err, "GetProcessHandleCount failed")
245+
return 0, fmt.Errorf("GetProcessHandleCount failed: %w", err)
248246
}
249247
return count, nil
250248
}

ntdll.go

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import (
2424
"fmt"
2525
"syscall"
2626
"unsafe"
27+
28+
"golang.org/x/sys/windows"
2729
)
2830

2931
const (
@@ -108,20 +110,11 @@ type RtlUserProcessParameters struct {
108110
CommandLine UnicodeString
109111
}
110112

111-
// Syscalls
112-
// Warning: NtQueryInformationProcess is an unsupported API that can change
113-
// in future versions of Windows. Available from XP to Windows 10.
114-
//sys _NtQueryInformationProcess(handle syscall.Handle, infoClass uint32, info uintptr, infoLen uint32, returnLen *uint32) (ntStatus uint32) = ntdll.NtQueryInformationProcess
115-
116-
// NtQueryInformationProcess is a wrapper for ntdll.NtQueryInformationProcess.
117-
// The handle must have the PROCESS_QUERY_INFORMATION access right.
118-
// Returns an error of type NTStatus.
119-
func NtQueryInformationProcess(handle syscall.Handle, infoClass ProcessInfoClass, info unsafe.Pointer, infoLen uint32) (returnedLen uint32, err error) {
120-
status := _NtQueryInformationProcess(handle, uint32(infoClass), uintptr(info), infoLen, &returnedLen)
121-
if status != 0 {
122-
return returnedLen, NTStatus(status)
123-
}
124-
return returnedLen, nil
113+
// Deprecated: use x/sys/windows
114+
func NtQueryInformationProcess(handle syscall.Handle, infoClass ProcessInfoClass, info unsafe.Pointer, infoLen uint32) (uint32, error) {
115+
var returnedLen uint32
116+
err := windows.NtQueryInformationProcess(windows.Handle(handle), int32(infoClass), info, infoLen, &returnedLen)
117+
return returnedLen, err
125118
}
126119

127120
// Error prints the wrapped NTSTATUS in hex form.

psapi.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,16 @@
2121
package windows
2222

2323
import (
24+
"fmt"
2425
"syscall"
2526
"unsafe"
2627

27-
"github.com/pkg/errors"
28+
"golang.org/x/sys/windows"
2829
)
2930

3031
// Syscalls
3132
//sys _GetProcessMemoryInfo(handle syscall.Handle, psmemCounters *ProcessMemoryCountersEx, cb uint32) (err error) = psapi.GetProcessMemoryInfo
3233
//sys _GetProcessImageFileNameA(handle syscall.Handle, imageFileName *byte, nSize uint32) (len uint32, err error) = psapi.GetProcessImageFileNameA
33-
//sys _EnumProcesses(lpidProcess *uint32, cb uint32, lpcbNeeded *uint32) (err error) = psapi.EnumProcesses
3434

3535
var (
3636
sizeofProcessMemoryCountersEx = uint32(unsafe.Sizeof(ProcessMemoryCountersEx{}))
@@ -59,7 +59,7 @@ type ProcessMemoryCountersEx struct {
5959
func GetProcessMemoryInfo(process syscall.Handle) (ProcessMemoryCountersEx, error) {
6060
var info ProcessMemoryCountersEx
6161
if err := _GetProcessMemoryInfo(process, &info, sizeofProcessMemoryCountersEx); err != nil {
62-
return ProcessMemoryCountersEx{}, errors.Wrap(err, "GetProcessMemoryInfo failed")
62+
return ProcessMemoryCountersEx{}, fmt.Errorf("GetProcessMemoryInfo failed: %w", err)
6363
}
6464
return info, nil
6565
}
@@ -91,7 +91,7 @@ func GetProcessImageFileName(handle syscall.Handle) (string, error) {
9191
func EnumProcesses() (pids []uint32, err error) {
9292
for nAlloc, nGot := uint32(128), uint32(0); ; nAlloc *= 2 {
9393
pids = make([]uint32, nAlloc)
94-
if err = _EnumProcesses(&pids[0], nAlloc*4, &nGot); err != nil {
94+
if err = windows.EnumProcesses(pids, &nGot); err != nil {
9595
return nil, err
9696
}
9797
if nGot/4 < nAlloc {

version.go

Lines changed: 23 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,14 @@
2121
package windows
2222

2323
import (
24+
"errors"
2425
"fmt"
2526
"unsafe"
2627

27-
"github.com/pkg/errors"
28+
"golang.org/x/sys/windows"
2829
)
2930

30-
// Syscalls
31-
//sys _GetFileVersionInfo(filename string, reserved uint32, dataLen uint32, data *byte) (success bool, err error) [!success] = version.GetFileVersionInfoW
32-
//sys _GetFileVersionInfoSize(filename string, handle uintptr) (size uint32, err error) = version.GetFileVersionInfoSizeW
33-
//sys _VerQueryValueW(data *byte, subBlock string, pBuffer *uintptr, len *uint32) (success bool, err error) [!success] = version.VerQueryValueW
34-
35-
// FixedFileInfo contains version information for a file. This information is
36-
// language and code page independent. This is an equivalent representation of
37-
// VS_FIXEDFILEINFO.
38-
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms646997(v=vs.85).aspx
31+
// Deprecated: use x/sys/windows
3932
type FixedFileInfo struct {
4033
Signature uint32
4134
StrucVersion uint32
@@ -84,32 +77,27 @@ func (d VersionData) QueryValue(key string) (string, error) {
8477
CodePage uint16
8578
}
8679

80+
var langCodePage *LangAndCodePage
81+
langCodeLen := uint32(unsafe.Sizeof(*langCodePage))
82+
if err := windows.VerQueryValue(unsafe.Pointer(&d[0]), `\VarFileInfo\Translation`, (unsafe.Pointer)(&langCodePage), &langCodeLen); err != nil || langCodeLen == 0 {
83+
return "", fmt.Errorf("failed to get list of languages: %w", err)
84+
}
85+
8786
var dataPtr uintptr
8887
var size uint32
89-
if _, err := _VerQueryValueW(&d[0], `\VarFileInfo\Translation`, &dataPtr, &size); err != nil || size == 0 {
90-
return "", errors.Wrap(err, "failed to get list of languages")
88+
subBlock := fmt.Sprintf(`\StringFileInfo\%04x%04x\%v`, langCodePage.Language, langCodePage.CodePage, key)
89+
if err := windows.VerQueryValue(unsafe.Pointer(&d[0]), subBlock, (unsafe.Pointer)(&dataPtr), &size); err != nil || langCodeLen == 0 {
90+
return "", fmt.Errorf("failed to query %v: %w", subBlock, err)
9191
}
9292

9393
offset := int(dataPtr - (uintptr)(unsafe.Pointer(&d[0])))
9494
if offset <= 0 || offset > len(d)-1 {
9595
return "", errors.New("invalid address")
9696
}
9797

98-
l := *(*LangAndCodePage)(unsafe.Pointer(&d[offset]))
99-
100-
subBlock := fmt.Sprintf(`\StringFileInfo\%04x%04x\%v`, l.Language, l.CodePage, key)
101-
if _, err := _VerQueryValueW(&d[0], subBlock, &dataPtr, &size); err != nil || size == 0 {
102-
return "", errors.Wrapf(err, "failed to query %v", subBlock)
103-
}
104-
105-
offset = int(dataPtr - (uintptr)(unsafe.Pointer(&d[0])))
106-
if offset <= 0 || offset > len(d)-1 {
107-
return "", errors.New("invalid address")
108-
}
109-
11098
str, _, err := UTF16BytesToString(d[offset : offset+int(size)*2])
11199
if err != nil {
112-
return "", errors.Wrap(err, "failed to decode UTF16 data")
100+
return "", fmt.Errorf("failed to decode UTF16 data: %w", err)
113101
}
114102

115103
return str, nil
@@ -119,40 +107,32 @@ func (d VersionData) QueryValue(key string) (string, error) {
119107
// version-information resource. It queries the root block to get the
120108
// VS_FIXEDFILEINFO value.
121109
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms647464(v=vs.85).aspx
122-
func (d VersionData) FixedFileInfo() (*FixedFileInfo, error) {
110+
func (d VersionData) FixedFileInfo() (*windows.VS_FIXEDFILEINFO, error) {
123111
if len(d) == 0 {
124112
return nil, errors.New("use GetFileVersionInfo to initialize VersionData")
125113
}
126114

127-
var dataPtr uintptr
128-
var size uint32
129-
if _, err := _VerQueryValueW(&d[0], `\`, &dataPtr, &size); err != nil {
130-
return nil, errors.Wrap(err, "VerQueryValue failed for \\")
131-
}
132-
133-
offset := int(dataPtr - (uintptr)(unsafe.Pointer(&d[0])))
134-
if offset <= 0 || offset > len(d)-1 {
135-
return nil, errors.New("invalid address")
115+
var fixedInfo *windows.VS_FIXEDFILEINFO
116+
fixedInfoLen := uint32(unsafe.Sizeof(*fixedInfo))
117+
if err := windows.VerQueryValue(unsafe.Pointer(&d[0]), `\`, (unsafe.Pointer)(&fixedInfo), &fixedInfoLen); err != nil {
118+
return nil, fmt.Errorf("VerQueryValue failed for \\ : %w", err)
136119
}
137120

138-
// Make a copy of the struct.
139-
ffi := *(*FixedFileInfo)(unsafe.Pointer(&d[offset]))
140-
141-
return &ffi, nil
121+
return fixedInfo, nil
142122
}
143123

144124
// GetFileVersionInfo retrieves version information for the specified file.
145125
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms647003(v=vs.85).aspx
146126
func GetFileVersionInfo(filename string) (VersionData, error) {
147-
size, err := _GetFileVersionInfoSize(filename, 0)
127+
size, err := windows.GetFileVersionInfoSize(filename, nil)
148128
if err != nil {
149-
return nil, errors.Wrap(err, "GetFileVersionInfoSize failed")
129+
return nil, fmt.Errorf("GetFileVersionInfoSize failed: %w", err)
150130
}
151131

152132
data := make(VersionData, size)
153-
_, err = _GetFileVersionInfo(filename, 0, uint32(len(data)), &data[0])
133+
err = windows.GetFileVersionInfo(filename, 0, uint32(len(data)), unsafe.Pointer(&data[0]))
154134
if err != nil {
155-
return nil, errors.Wrap(err, "GetFileVersionInfo failed")
135+
return nil, fmt.Errorf("GetFileVersionInfo failed: %w", err)
156136
}
157137

158138
return data, nil

0 commit comments

Comments
 (0)