88 lines
1.7 KiB
Go
88 lines
1.7 KiB
Go
//go:build windows
|
|
|
|
package mem
|
|
|
|
import (
|
|
"syscall"
|
|
"unsafe"
|
|
)
|
|
|
|
func reserve(total_address_space uintptr) ([]byte, error) {
|
|
addr, _, err := _VirtualAlloc.Call(0, total_address_space, _MEM_RESERVE, _PAGE_NOACCESS)
|
|
if addr == 0 {
|
|
return nil, err
|
|
}
|
|
|
|
return unsafe.Slice((*byte)(unsafe.Pointer(addr)), total_address_space), nil
|
|
}
|
|
|
|
func release(reserved []byte) error {
|
|
res, _, err := _VirtualFree.Call(uintptr(unsafe.Pointer(&reserved[0])), 0, _MEM_RELEASE)
|
|
if res == 0 {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func commit(reserved []byte, access Access) error {
|
|
ret, _, err := _VirtualAlloc.Call(
|
|
uintptr(unsafe.Pointer(&reserved[0])),
|
|
uintptr(len(reserved)),
|
|
_MEM_COMMIT,
|
|
uintptr(access_to_prot(access)),
|
|
)
|
|
if ret == 0 {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func decommit(committed []byte) error {
|
|
ret, _, err := _VirtualFree.Call(
|
|
uintptr(unsafe.Pointer(&committed[0])),
|
|
uintptr(len(committed)),
|
|
_MEM_DECOMMIT,
|
|
)
|
|
if ret == 0 {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
var (
|
|
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
|
_VirtualAlloc = kernel32.NewProc("VirtualAlloc")
|
|
_VirtualFree = kernel32.NewProc("VirtualFree")
|
|
)
|
|
|
|
const (
|
|
_MEM_COMMIT = 0x1000
|
|
_MEM_RESERVE = 0x2000
|
|
_MEM_DECOMMIT = 0x4000
|
|
_MEM_RELEASE = 0x8000
|
|
|
|
_PAGE_NOACCESS = 0x01
|
|
_PAGE_READONLY = 0x02
|
|
_PAGE_READWRITE = 0x04
|
|
|
|
_PAGE_EXECUTE_READ = 0x20
|
|
_PAGE_EXECUTE_READWRITE = 0x40
|
|
)
|
|
|
|
func access_to_prot(access Access) uint32 {
|
|
switch access {
|
|
case AccessRead | AccessWrite | AccessExecute:
|
|
return _PAGE_EXECUTE_READWRITE
|
|
case AccessRead | AccessExecute:
|
|
return _PAGE_EXECUTE_READ
|
|
case AccessRead | AccessWrite:
|
|
return _PAGE_READWRITE
|
|
case AccessRead:
|
|
return _PAGE_READONLY
|
|
default:
|
|
return _PAGE_NOACCESS
|
|
}
|
|
}
|