1
2
3
4
5 package mmap
6
7 import (
8 "fmt"
9 "os"
10 "syscall"
11 "unsafe"
12
13 "internal/syscall/windows"
14 )
15
16 func mmapFile(f *os.File) (Data, error) {
17 st, err := f.Stat()
18 if err != nil {
19 return Data{}, err
20 }
21 size := st.Size()
22 if size == 0 {
23 return Data{f, nil}, nil
24 }
25 h, err := syscall.CreateFileMapping(syscall.Handle(f.Fd()), nil, syscall.PAGE_READONLY, 0, 0, nil)
26 if err != nil {
27 return Data{}, fmt.Errorf("CreateFileMapping %s: %w", f.Name(), err)
28 }
29
30 addr, err := syscall.MapViewOfFile(h, syscall.FILE_MAP_READ, 0, 0, 0)
31 if err != nil {
32 return Data{}, fmt.Errorf("MapViewOfFile %s: %w", f.Name(), err)
33 }
34 var info windows.MemoryBasicInformation
35 err = windows.VirtualQuery(addr, &info, unsafe.Sizeof(info))
36 if err != nil {
37 return Data{}, fmt.Errorf("VirtualQuery %s: %w", f.Name(), err)
38 }
39 data := unsafe.Slice((*byte)(unsafe.Pointer(addr)), int(info.RegionSize))
40 return Data{f, data}, nil
41 }
42
View as plain text