1// +build windows,!appengine 2 3package maxminddb 4 5// Windows support largely borrowed from mmap-go. 6// 7// Copyright 2011 Evan Shaw. All rights reserved. 8// Use of this source code is governed by a BSD-style 9// license that can be found in the LICENSE file. 10 11import ( 12 "errors" 13 "os" 14 "reflect" 15 "sync" 16 "unsafe" 17 18 "github.com/ooni/psiphon/oopsi/golang.org/x/sys/windows" 19) 20 21type memoryMap []byte 22 23// Windows 24var handleLock sync.Mutex 25var handleMap = map[uintptr]windows.Handle{} 26 27func mmap(fd int, length int) (data []byte, err error) { 28 h, errno := windows.CreateFileMapping(windows.Handle(fd), nil, 29 uint32(windows.PAGE_READONLY), 0, uint32(length), nil) 30 if h == 0 { 31 return nil, os.NewSyscallError("CreateFileMapping", errno) 32 } 33 34 addr, errno := windows.MapViewOfFile(h, uint32(windows.FILE_MAP_READ), 0, 35 0, uintptr(length)) 36 if addr == 0 { 37 return nil, os.NewSyscallError("MapViewOfFile", errno) 38 } 39 handleLock.Lock() 40 handleMap[addr] = h 41 handleLock.Unlock() 42 43 m := memoryMap{} 44 dh := m.header() 45 dh.Data = addr 46 dh.Len = length 47 dh.Cap = dh.Len 48 49 return m, nil 50} 51 52func (m *memoryMap) header() *reflect.SliceHeader { 53 return (*reflect.SliceHeader)(unsafe.Pointer(m)) 54} 55 56func flush(addr, len uintptr) error { 57 errno := windows.FlushViewOfFile(addr, len) 58 return os.NewSyscallError("FlushViewOfFile", errno) 59} 60 61func munmap(b []byte) (err error) { 62 m := memoryMap(b) 63 dh := m.header() 64 65 addr := dh.Data 66 length := uintptr(dh.Len) 67 68 flush(addr, length) 69 err = windows.UnmapViewOfFile(addr) 70 if err != nil { 71 return err 72 } 73 74 handleLock.Lock() 75 defer handleLock.Unlock() 76 handle, ok := handleMap[addr] 77 if !ok { 78 // should be impossible; we would've errored above 79 return errors.New("unknown base address") 80 } 81 delete(handleMap, addr) 82 83 e := windows.CloseHandle(windows.Handle(handle)) 84 return os.NewSyscallError("CloseHandle", e) 85} 86