first commit

This commit is contained in:
2025-08-22 17:42:23 -04:00
commit a6c09a5890
120 changed files with 11443 additions and 0 deletions

View File

@ -0,0 +1,78 @@
//go:build windows
package kernel32
import (
"sync/atomic"
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
type (
heapHandle = uintptr
win32Error uint32
heapFlags uint32
)
const (
heapNone heapFlags = 0
heapZeroMemory heapFlags = 8 // The allocated memory will be initialized to zero.
)
var (
libKernel32 = windows.NewLazySystemDLL("kernel32.dll")
pHeapFree uintptr
pHeapAlloc uintptr
pGetProcessHeap uintptr
hHeap heapHandle
)
func init() {
hHeap, _ = getProcessHeap()
}
// Malloc allocates the given amount of bytes in the heap
func Malloc(size uintptr) unsafe.Pointer {
return heapAlloc(hHeap, heapZeroMemory, size)
}
// Free releases the given unsafe pointer from the heap
func Free(inst unsafe.Pointer) {
_, _ = heapFree(hHeap, heapNone, inst)
}
// https://docs.microsoft.com/en-us/windows/win32/api/heapapi/nf-heapapi-heapalloc
func heapAlloc(hHeap heapHandle, dwFlags heapFlags, dwBytes uintptr) unsafe.Pointer {
addr := getProcAddr(&pHeapAlloc, libKernel32, "HeapAlloc")
allocatedPtr, _, _ := syscall.SyscallN(addr, hHeap, uintptr(dwFlags), dwBytes)
// Since this pointer is allocated in the heap by Windows, it will never be
// GCd by Go, so this is a safe operation.
// But linter thinks it is not (probably because we are not using CGO) and fails.
return unsafe.Pointer(allocatedPtr) //nolint:gosec,govet
}
// https://docs.microsoft.com/en-us/windows/win32/api/heapapi/nf-heapapi-heapfree
func heapFree(hHeap heapHandle, dwFlags heapFlags, lpMem unsafe.Pointer) (bool, win32Error) {
addr := getProcAddr(&pHeapFree, libKernel32, "HeapFree")
ret, _, err := syscall.SyscallN(addr, hHeap, uintptr(dwFlags), uintptr(lpMem))
return ret == 0, win32Error(err)
}
func getProcessHeap() (heapHandle, win32Error) {
addr := getProcAddr(&pGetProcessHeap, libKernel32, "GetProcessHeap")
ret, _, err := syscall.SyscallN(addr)
return ret, win32Error(err)
}
func getProcAddr(pAddr *uintptr, lib *windows.LazyDLL, procName string) uintptr {
addr := atomic.LoadUintptr(pAddr)
if addr == 0 {
addr = lib.NewProc(procName).Addr()
atomic.StoreUintptr(pAddr, addr)
}
return addr
}