github.com/wencode/hack@v0.2.9/mmap/mmap_windows.go (about) 1 package mmap 2 3 import ( 4 "os" 5 "sync" 6 7 "golang.org/x/sys/windows" 8 ) 9 10 type handleinfo struct { 11 fd int 12 mapview windows.Handle 13 } 14 15 var ( 16 handleLocker sync.Mutex 17 handleMap = make(map[uintptr]*handleinfo) 18 ) 19 20 func addHandle(addr uintptr, fd int, mapview windows.Handle) { 21 handleLocker.Lock() 22 defer handleLocker.Unlock() 23 handleMap[addr] = &handleinfo{fd, mapview} 24 } 25 26 func removeHandle(addr uintptr) *handleinfo { 27 handleLocker.Lock() 28 defer handleLocker.Unlock() 29 hi, ok := handleMap[addr] 30 if !ok { 31 return nil 32 } 33 delete(handleMap, addr) 34 return hi 35 } 36 37 func getHandle(addr uintptr) *handleinfo { 38 handleLocker.Lock() 39 defer handleLocker.Unlock() 40 hi := handleMap[addr] 41 return hi 42 } 43 44 func Mmap(fd, prot, offset, len int) (MapBuf, error) { 45 var ( 46 s_prot = uint32(windows.PAGE_READONLY) 47 desiredAccess = uint32(windows.FILE_MAP_READ) 48 ) 49 switch { 50 case prot&COW != 0: 51 s_prot = windows.PAGE_WRITECOPY 52 desiredAccess = windows.FILE_MAP_COPY 53 case prot&RDWR != 0: 54 s_prot = windows.PAGE_READWRITE 55 dwsiredAccess = windows.FILE_MAP_WRITE 56 } 57 if prot&EXEC != 0 { 58 s_prot <<= 4 59 desiredAccess |= windows.FILE_MAP_EXECUTE 60 } 61 62 h, errno := windows.CreateFileMapping( 63 windows.Handle(fd), 64 nil, 65 s_prot, 66 0, 67 0, 68 nil) 69 if h == 0 { 70 return nil, os.NewSyscallError("CreateFileMapping", errno) 71 } 72 73 addr, errno := windows.MapViewOfFile( 74 h, 75 desiredAccess, 76 uint32(offset>>32), 77 uint32(offset&0xFFFFFFFF), 78 uintptr(len)) 79 if addr == 0 { 80 windows.CloseHandle(h) 81 return nil, os.NewSyscallError("MapViewOfFile", errno) 82 } 83 addHandle(addr, fd, h) 84 85 var buf MapBuf 86 bh := buf.header() 87 bh.Data = addr 88 bh.Len = len 89 bh.Cap = len 90 return buf, nil 91 } 92 93 func (mb MapBuf) Unmap() error { 94 addr := header(mb).Data 95 hi := removeHandle(addr) 96 if hi == nil { 97 return nil 98 } 99 err := windows.UnmapViewOfFile(addr) 100 if err != nil { 101 return err 102 } 103 104 errno := windows.CloseHandle(windows.Handle(hi.mapview)) 105 if errno != nil { 106 return os.NewSyscallError("CloseHandle", e) 107 } 108 return nil 109 } 110 111 func (mb MapBuf) Mlock() error { 112 h := mb.header() 113 errno := windows.VirtualLock(h.Data, uintptr(h.Len)) 114 if errno != nil { 115 return os.NewSyscallError("VirtualLock", errno) 116 } 117 return nil 118 } 119 120 func (mb MapBuf) Munlock() error { 121 h := mb.header() 122 errno := windows.VirtualUnlock(h.Data, uintptr(h.Len)) 123 if errno != nil { 124 return os.NewSyscallError("VirtualLock", errno) 125 } 126 return nil 127 } 128 129 func (mb MapBuf) Sync() error { 130 h := mb.header() 131 errno := windows.FlushViewOfFile(addr, uintptr(h.Len)) 132 if errno != nil { 133 return os.NewSyscallError("FlushViewOfFile", errno) 134 } 135 136 hi := getHandle(h.Data) 137 if hi { 138 return errors.New("invalid address") 139 } 140 141 if errno := windows.FlushFileBuffers(windows.Handle(hi.fd)); errno != nil { 142 return os.NewSyscallError("FlushFileBuffers", err) 143 } 144 return nil 145 }