diff --git a/com/stream.go b/com/stream.go index b0f7b9d..b2c4bdf 100644 --- a/com/stream.go +++ b/com/stream.go @@ -179,103 +179,6 @@ func (o SequentialStream) Write(b []byte) (int, error) { return p.Write(b) } -func (abi *IStreamABI) Seek(offset int64, whence int) (n int64, _ error) { - var hr wingoes.HRESULT - method := unsafe.Slice(abi.Vtbl, 14)[5] - - if runtime.GOARCH == "386" { - words := (*[2]uintptr)(unsafe.Pointer(&offset)) - rc, _, _ := syscall.SyscallN( - method, - uintptr(unsafe.Pointer(abi)), - words[0], - words[1], - uintptr(uint32(whence)), - uintptr(unsafe.Pointer(&n)), - ) - hr = wingoes.HRESULT(rc) - } else { - rc, _, _ := syscall.SyscallN( - method, - uintptr(unsafe.Pointer(abi)), - uintptr(offset), - uintptr(uint32(whence)), - uintptr(unsafe.Pointer(&n)), - ) - hr = wingoes.HRESULT(rc) - } - - if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { - return 0, e - } - - return n, nil -} - -func (abi *IStreamABI) SetSize(newSize uint64) error { - var hr wingoes.HRESULT - method := unsafe.Slice(abi.Vtbl, 14)[6] - - if runtime.GOARCH == "386" { - words := (*[2]uintptr)(unsafe.Pointer(&newSize)) - rc, _, _ := syscall.SyscallN( - method, - uintptr(unsafe.Pointer(abi)), - words[0], - words[1], - ) - hr = wingoes.HRESULT(rc) - } else { - rc, _, _ := syscall.SyscallN( - method, - uintptr(unsafe.Pointer(abi)), - uintptr(newSize), - ) - hr = wingoes.HRESULT(rc) - } - - if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { - return e - } - - return nil -} - -func (abi *IStreamABI) CopyTo(dest *IStreamABI, numBytesToCopy uint64) (bytesRead, bytesWritten uint64, _ error) { - var hr wingoes.HRESULT - method := unsafe.Slice(abi.Vtbl, 14)[7] - - if runtime.GOARCH == "386" { - words := (*[2]uintptr)(unsafe.Pointer(&numBytesToCopy)) - rc, _, _ := syscall.SyscallN( - method, - uintptr(unsafe.Pointer(abi)), - uintptr(unsafe.Pointer(dest)), - words[0], - words[1], - uintptr(unsafe.Pointer(&bytesRead)), - uintptr(unsafe.Pointer(&bytesWritten)), - ) - hr = wingoes.HRESULT(rc) - } else { - rc, _, _ := syscall.SyscallN( - method, - uintptr(unsafe.Pointer(abi)), - uintptr(unsafe.Pointer(dest)), - uintptr(numBytesToCopy), - uintptr(unsafe.Pointer(&bytesRead)), - uintptr(unsafe.Pointer(&bytesWritten)), - ) - hr = wingoes.HRESULT(rc) - } - - if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { - return bytesRead, bytesWritten, e - } - - return bytesRead, bytesWritten, nil -} - func (abi *IStreamABI) Commit(flags STGC) error { method := unsafe.Slice(abi.Vtbl, 14)[8] @@ -306,76 +209,6 @@ func (abi *IStreamABI) Revert() error { return nil } -func (abi *IStreamABI) LockRegion(offset, numBytes uint64, lockType LOCKTYPE) error { - var hr wingoes.HRESULT - method := unsafe.Slice(abi.Vtbl, 14)[10] - - if runtime.GOARCH == "386" { - oWords := (*[2]uintptr)(unsafe.Pointer(&offset)) - nWords := (*[2]uintptr)(unsafe.Pointer(&numBytes)) - rc, _, _ := syscall.SyscallN( - method, - uintptr(unsafe.Pointer(abi)), - oWords[0], - oWords[1], - nWords[0], - nWords[1], - uintptr(lockType), - ) - hr = wingoes.HRESULT(rc) - } else { - rc, _, _ := syscall.SyscallN( - method, - uintptr(unsafe.Pointer(abi)), - uintptr(offset), - uintptr(numBytes), - uintptr(lockType), - ) - hr = wingoes.HRESULT(rc) - } - - if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { - return e - } - - return nil -} - -func (abi *IStreamABI) UnlockRegion(offset, numBytes uint64, lockType LOCKTYPE) error { - var hr wingoes.HRESULT - method := unsafe.Slice(abi.Vtbl, 14)[11] - - if runtime.GOARCH == "386" { - oWords := (*[2]uintptr)(unsafe.Pointer(&offset)) - nWords := (*[2]uintptr)(unsafe.Pointer(&numBytes)) - rc, _, _ := syscall.SyscallN( - method, - uintptr(unsafe.Pointer(abi)), - oWords[0], - oWords[1], - nWords[0], - nWords[1], - uintptr(lockType), - ) - hr = wingoes.HRESULT(rc) - } else { - rc, _, _ := syscall.SyscallN( - method, - uintptr(unsafe.Pointer(abi)), - uintptr(offset), - uintptr(numBytes), - uintptr(lockType), - ) - hr = wingoes.HRESULT(rc) - } - - if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { - return e - } - - return nil -} - func (abi *IStreamABI) Stat(flags STATFLAG) (*STATSTG, error) { result := new(STATSTG) method := unsafe.Slice(abi.Vtbl, 14)[12] diff --git a/com/stream_386.go b/com/stream_386.go new file mode 100644 index 0000000..6737941 --- /dev/null +++ b/com/stream_386.go @@ -0,0 +1,130 @@ +// Copyright (c) 2023 Tailscale Inc & AUTHORS. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build windows + +package com + +import ( + "math" + "syscall" + "unsafe" + + "github.com/dblohm7/wingoes" +) + +const maxStreamRWLen = math.MaxInt32 + +func (abi *IStreamABI) Seek(offset int64, whence int) (n int64, _ error) { + var hr wingoes.HRESULT + method := unsafe.Slice(abi.Vtbl, 14)[5] + + words := (*[2]uintptr)(unsafe.Pointer(&offset)) + rc, _, _ := syscall.SyscallN( + method, + uintptr(unsafe.Pointer(abi)), + words[0], + words[1], + uintptr(uint32(whence)), + uintptr(unsafe.Pointer(&n)), + ) + hr = wingoes.HRESULT(rc) + + if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { + return 0, e + } + + return n, nil +} + +func (abi *IStreamABI) SetSize(newSize uint64) error { + var hr wingoes.HRESULT + method := unsafe.Slice(abi.Vtbl, 14)[6] + + words := (*[2]uintptr)(unsafe.Pointer(&newSize)) + rc, _, _ := syscall.SyscallN( + method, + uintptr(unsafe.Pointer(abi)), + words[0], + words[1], + ) + hr = wingoes.HRESULT(rc) + + if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { + return e + } + + return nil +} + +func (abi *IStreamABI) CopyTo(dest *IStreamABI, numBytesToCopy uint64) (bytesRead, bytesWritten uint64, _ error) { + var hr wingoes.HRESULT + method := unsafe.Slice(abi.Vtbl, 14)[7] + + words := (*[2]uintptr)(unsafe.Pointer(&numBytesToCopy)) + rc, _, _ := syscall.SyscallN( + method, + uintptr(unsafe.Pointer(abi)), + uintptr(unsafe.Pointer(dest)), + words[0], + words[1], + uintptr(unsafe.Pointer(&bytesRead)), + uintptr(unsafe.Pointer(&bytesWritten)), + ) + hr = wingoes.HRESULT(rc) + + if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { + return bytesRead, bytesWritten, e + } + + return bytesRead, bytesWritten, nil +} + +func (abi *IStreamABI) LockRegion(offset, numBytes uint64, lockType LOCKTYPE) error { + var hr wingoes.HRESULT + method := unsafe.Slice(abi.Vtbl, 14)[10] + + oWords := (*[2]uintptr)(unsafe.Pointer(&offset)) + nWords := (*[2]uintptr)(unsafe.Pointer(&numBytes)) + rc, _, _ := syscall.SyscallN( + method, + uintptr(unsafe.Pointer(abi)), + oWords[0], + oWords[1], + nWords[0], + nWords[1], + uintptr(lockType), + ) + hr = wingoes.HRESULT(rc) + + if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { + return e + } + + return nil +} + +func (abi *IStreamABI) UnlockRegion(offset, numBytes uint64, lockType LOCKTYPE) error { + var hr wingoes.HRESULT + method := unsafe.Slice(abi.Vtbl, 14)[11] + + oWords := (*[2]uintptr)(unsafe.Pointer(&offset)) + nWords := (*[2]uintptr)(unsafe.Pointer(&numBytes)) + rc, _, _ := syscall.SyscallN( + method, + uintptr(unsafe.Pointer(abi)), + oWords[0], + oWords[1], + nWords[0], + nWords[1], + uintptr(lockType), + ) + hr = wingoes.HRESULT(rc) + + if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { + return e + } + + return nil +} diff --git a/com/stream_not386.go b/com/stream_not386.go index 7b82a40..a0593f6 100644 --- a/com/stream_not386.go +++ b/com/stream_not386.go @@ -8,6 +8,109 @@ package com import ( "math" + "syscall" + "unsafe" + + "github.com/dblohm7/wingoes" ) const maxStreamRWLen = math.MaxUint32 + +func (abi *IStreamABI) Seek(offset int64, whence int) (n int64, _ error) { + var hr wingoes.HRESULT + method := unsafe.Slice(abi.Vtbl, 14)[5] + + rc, _, _ := syscall.SyscallN( + method, + uintptr(unsafe.Pointer(abi)), + uintptr(offset), + uintptr(uint32(whence)), + uintptr(unsafe.Pointer(&n)), + ) + hr = wingoes.HRESULT(rc) + + if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { + return 0, e + } + + return n, nil +} + +func (abi *IStreamABI) SetSize(newSize uint64) error { + var hr wingoes.HRESULT + method := unsafe.Slice(abi.Vtbl, 14)[6] + + rc, _, _ := syscall.SyscallN( + method, + uintptr(unsafe.Pointer(abi)), + uintptr(newSize), + ) + hr = wingoes.HRESULT(rc) + + if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { + return e + } + + return nil +} + +func (abi *IStreamABI) CopyTo(dest *IStreamABI, numBytesToCopy uint64) (bytesRead, bytesWritten uint64, _ error) { + var hr wingoes.HRESULT + method := unsafe.Slice(abi.Vtbl, 14)[7] + + rc, _, _ := syscall.SyscallN( + method, + uintptr(unsafe.Pointer(abi)), + uintptr(unsafe.Pointer(dest)), + uintptr(numBytesToCopy), + uintptr(unsafe.Pointer(&bytesRead)), + uintptr(unsafe.Pointer(&bytesWritten)), + ) + hr = wingoes.HRESULT(rc) + + if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { + return bytesRead, bytesWritten, e + } + + return bytesRead, bytesWritten, nil +} + +func (abi *IStreamABI) LockRegion(offset, numBytes uint64, lockType LOCKTYPE) error { + var hr wingoes.HRESULT + method := unsafe.Slice(abi.Vtbl, 14)[10] + + rc, _, _ := syscall.SyscallN( + method, + uintptr(unsafe.Pointer(abi)), + uintptr(offset), + uintptr(numBytes), + uintptr(lockType), + ) + hr = wingoes.HRESULT(rc) + + if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { + return e + } + + return nil +} + +func (abi *IStreamABI) UnlockRegion(offset, numBytes uint64, lockType LOCKTYPE) error { + var hr wingoes.HRESULT + method := unsafe.Slice(abi.Vtbl, 14)[11] + + rc, _, _ := syscall.SyscallN( + method, + uintptr(unsafe.Pointer(abi)), + uintptr(offset), + uintptr(numBytes), + uintptr(lockType), + ) + hr = wingoes.HRESULT(rc) + + if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { + return e + } + + return nil +} diff --git a/com/stream_test.go b/com/stream_test.go index 67037ef..9297c52 100644 --- a/com/stream_test.go +++ b/com/stream_test.go @@ -47,7 +47,7 @@ func memoryStream(t *testing.T, useLegacy bool) { // Only try this on supported 64-bit archs so that the test doesn't run the // risk of crashing due to OOM. if runtime.GOARCH != "386" { - tooBig := make([]byte, maxStreamRWLen+1) + tooBig := getTooBigSlice() _, err = newMemoryStreamInternal(tooBig, useLegacy) if err == nil { t.Errorf("Unexpected success creating too-large memory stream") diff --git a/com/stream_test_386.go b/com/stream_test_386.go new file mode 100644 index 0000000..5dfaa8f --- /dev/null +++ b/com/stream_test_386.go @@ -0,0 +1,11 @@ +// Copyright (c) 2024 Tailscale Inc & AUTHORS. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build windows + +package com + +func getTooBigSlice() []byte { + return nil +} diff --git a/com/stream_test_not386.go b/com/stream_test_not386.go new file mode 100644 index 0000000..9a3db1b --- /dev/null +++ b/com/stream_test_not386.go @@ -0,0 +1,11 @@ +// Copyright (c) 2024 Tailscale Inc & AUTHORS. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build windows && !386 + +package com + +func getTooBigSlice() []byte { + return make([]byte, maxStreamRWLen+1) +}