summaryrefslogtreecommitdiff
path: root/vendor/github.com/ncruces/go-sqlite3/internal/util/mmap_windows.go
blob: fdf6f439aa83252fcf77bbc8ac6e6cb43a451abb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//go:build !sqlite3_nosys

package util

import (
	"context"
	"os"
	"reflect"
	"unsafe"

	"github.com/tetratelabs/wazero/api"
	"golang.org/x/sys/windows"
)

type MappedRegion struct {
	windows.Handle
	Data []byte
	addr uintptr
}

func MapRegion(ctx context.Context, mod api.Module, f *os.File, offset int64, size int32) (*MappedRegion, error) {
	h, err := windows.CreateFileMapping(windows.Handle(f.Fd()), nil, windows.PAGE_READWRITE, 0, 0, nil)
	if h == 0 {
		return nil, err
	}

	a, err := windows.MapViewOfFile(h, windows.FILE_MAP_WRITE,
		uint32(offset>>32), uint32(offset), uintptr(size))
	if a == 0 {
		windows.CloseHandle(h)
		return nil, err
	}

	res := &MappedRegion{Handle: h, addr: a}
	// SliceHeader, although deprecated, avoids a go vet warning.
	sh := (*reflect.SliceHeader)(unsafe.Pointer(&res.Data))
	sh.Len = int(size)
	sh.Cap = int(size)
	sh.Data = a
	return res, nil
}

func (r *MappedRegion) Unmap() error {
	if r.Data == nil {
		return nil
	}
	err := windows.UnmapViewOfFile(r.addr)
	if err != nil {
		return err
	}
	r.Data = nil
	return windows.CloseHandle(r.Handle)
}