Skip to content

Commit c8ea6b0

Browse files
roman-mazurqmuntal
authored andcommitted
windows: fix EnumProcesses to pass the correct array size
Implementation generated directly with mkwinsyscall has a wrong assumption about the expected value for PIDs buffer size. This change adds some small manual code that converts the input slice length to the number of bytes of the array backing the slice. A test is also added. It fails with the previous implementation. Fixes golang/go#60223 Change-Id: I5e2414acb29c6c949e5e6acd328043f8a8883887 Reviewed-on: https://go-review.googlesource.com/c/sys/+/495995 Commit-Queue: Quim Muntal <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Bryan Mills <[email protected]> Run-TryBot: Quim Muntal <[email protected]> Reviewed-by: Quim Muntal <[email protected]> Reviewed-by: Heschi Kreinick <[email protected]>
1 parent 352d833 commit c8ea6b0

File tree

3 files changed

+36
-7
lines changed

3 files changed

+36
-7
lines changed

windows/syscall_windows.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ func NewCallbackCDecl(fn interface{}) uintptr {
405405
//sys VerQueryValue(block unsafe.Pointer, subBlock string, pointerToBufferPointer unsafe.Pointer, bufSize *uint32) (err error) = version.VerQueryValueW
406406

407407
// Process Status API (PSAPI)
408-
//sys EnumProcesses(processIds []uint32, bytesReturned *uint32) (err error) = psapi.EnumProcesses
408+
//sys enumProcesses(processIds *uint32, nSize uint32, bytesReturned *uint32) (err error) = psapi.EnumProcesses
409409
//sys EnumProcessModules(process Handle, module *Handle, cb uint32, cbNeeded *uint32) (err error) = psapi.EnumProcessModules
410410
//sys EnumProcessModulesEx(process Handle, module *Handle, cb uint32, cbNeeded *uint32, filterFlag uint32) (err error) = psapi.EnumProcessModulesEx
411411
//sys GetModuleInformation(process Handle, module Handle, modinfo *ModuleInfo, cb uint32) (err error) = psapi.GetModuleInformation
@@ -1354,6 +1354,17 @@ func SetsockoptIPv6Mreq(fd Handle, level, opt int, mreq *IPv6Mreq) (err error) {
13541354
return syscall.EWINDOWS
13551355
}
13561356

1357+
func EnumProcesses(processIds []uint32, bytesReturned *uint32) error {
1358+
// EnumProcesses syscall expects the size parameter to be in bytes, but the code generated with mksyscall uses
1359+
// the length of the processIds slice instead. Hence, this wrapper function is added to fix the discrepancy.
1360+
var p *uint32
1361+
if len(processIds) > 0 {
1362+
p = &processIds[0]
1363+
}
1364+
size := uint32(len(processIds) * 4)
1365+
return enumProcesses(p, size, bytesReturned)
1366+
}
1367+
13571368
func Getpid() (pid int) { return int(GetCurrentProcessId()) }
13581369

13591370
func FindFirstFile(name *uint16, data *Win32finddata) (handle Handle, err error) {

windows/syscall_windows_test.go

+22
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,28 @@ func TestWinVerifyTrust(t *testing.T) {
717717

718718
}
719719

720+
func TestEnumProcesses(t *testing.T) {
721+
var (
722+
pids [2]uint32
723+
outSize uint32
724+
)
725+
err := windows.EnumProcesses(pids[:], &outSize)
726+
if err != nil {
727+
t.Fatalf("unable to enumerate processes: %v", err)
728+
}
729+
730+
// Regression check for go.dev/issue/60223
731+
if outSize != 8 {
732+
t.Errorf("unexpected bytes returned: %d", outSize)
733+
}
734+
// Most likely, this should be [0, 4].
735+
// 0 is the system idle pseudo-process. 4 is the initial system process ID.
736+
// This test expects that at least one of the PIDs is not 0.
737+
if pids[0] == 0 && pids[1] == 0 {
738+
t.Errorf("all PIDs are 0")
739+
}
740+
}
741+
720742
func TestProcessModules(t *testing.T) {
721743
process, err := windows.GetCurrentProcess()
722744
if err != nil {

windows/zsyscall_windows.go

+2-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)