// mmap memory maps a DB's data file. // Based on: https://github.com/edsrzf/mmap-go func mmap(db *DB, sz int) error { if !db.readOnly { // Truncate the database to the size of the mmap. if err := db.file.Truncate(int64(sz)); err != nil { return fmt.Errorf("truncate: %s", err) } } // Open a file mapping handle. sizelo := uint32(sz >> 32) sizehi := uint32(sz) & 0xffffffff h, errno := syscall.CreateFileMapping(syscall.Handle(db.file.Fd()), nil, syscall.PAGE_READONLY, sizelo, sizehi, nil) if h == 0 { return os.NewSyscallError("CreateFileMapping", errno) } // Create the memory map. addr, errno := syscall.MapViewOfFile(h, syscall.FILE_MAP_READ, 0, 0, uintptr(sz)) if addr == 0 { return os.NewSyscallError("MapViewOfFile", errno) } // Close mapping handle. if err := syscall.CloseHandle(syscall.Handle(h)); err != nil { return os.NewSyscallError("CloseHandle", err) } // Convert to a byte array. db.data = ((*[maxMapSize]byte)(unsafe.Pointer(addr))) db.datasz = sz return nil }
// Implement mmap for windows func map_file(file *os.File, offset, size int) ([]byte, error) { // create the mapping handle h, err := syscall.CreateFileMapping(syscall.Handle(file.Fd()), nil, syscall.PAGE_READONLY, 0, uint32(size), nil) if err != nil { return nil, err } // perform the file map operation addr, err := syscall.MapViewOfFile(h, syscall.FILE_MAP_READ, uint32(offset>>32), uint32(offset), uintptr(size)) if err != nil { return nil, err } // store the mapping handle win_mapper_mutex.Lock() win_mapper_handle[addr] = h win_mapper_mutex.Unlock() // Slice memory layout sl := reflect.SliceHeader{Data: addr, Len: size, Cap: size} // Use unsafe to turn sl into a []byte. bp := *(*[]byte)(unsafe.Pointer(&sl)) return bp, err }
func mmap(hfile uintptr, off int64, len int) (uintptr, error) { flProtect := uint32(syscall.PAGE_READONLY) dwDesiredAccess := uint32(syscall.FILE_MAP_READ) flProtect = syscall.PAGE_READWRITE dwDesiredAccess = syscall.FILE_MAP_WRITE // The maximum size is the area of the file, starting from 0, // that we wish to allow to be mappable. It is the sum of // the length the user requested, plus the offset where that length // is starting from. This does not map the data into memory. maxSizeHigh := uint32((off + int64(len)) >> 32) maxSizeLow := uint32((off + int64(len)) & 0xFFFFFFFF) // TODO: Do we need to set some security attributes? It might help portability. h, errno := syscall.CreateFileMapping(syscall.Handle(hfile), nil, flProtect, maxSizeHigh, maxSizeLow, nil) if h == 0 { return 0, os.NewSyscallError("CreateFileMapping", errno) } // Actually map a view of the data into memory. The view's size // is the length the user requested. fileOffsetHigh := uint32(off >> 32) fileOffsetLow := uint32(off & 0xFFFFFFFF) addr, errno := syscall.MapViewOfFile(h, dwDesiredAccess, fileOffsetHigh, fileOffsetLow, uintptr(len)) if addr == 0 { return 0, os.NewSyscallError("MapViewOfFile", errno) } return addr, nil }
func mmap(f *os.File, offset int64, length int) (out []byte, err error) { // Open a file mapping handle. sizelo := uint32(length >> 32) sizehi := uint32(length) & 0xffffffff sharedHandle, errno := openSharedFile(f) if errno != nil { return nil, os.NewSyscallError("CreateFile", errno) } h, errno := syscall.CreateFileMapping(syscall.Handle(sharedHandle.Fd()), nil, syscall.PAGE_READONLY, sizelo, sizehi, nil) if h == 0 { return nil, os.NewSyscallError("CreateFileMapping", errno) } // Create the memory map. addr, errno := syscall.MapViewOfFile(h, syscall.FILE_MAP_READ, 0, 0, uintptr(length)) if addr == 0 { return nil, os.NewSyscallError("MapViewOfFile", errno) } handleLock.Lock() handleMap[addr] = h fileMap[addr] = sharedHandle handleLock.Unlock() // Convert to a byte array. hdr := (*reflect.SliceHeader)(unsafe.Pointer(&out)) hdr.Data = uintptr(unsafe.Pointer(addr)) hdr.Len = length hdr.Cap = length return }
func mmapFile(f *os.File) mmapData { st, err := f.Stat() if err != nil { log.Fatal(err) } size := st.Size() if int64(int(size+4095)) != size+4095 { log.Fatalf("%s: too large for mmap", f.Name()) } if size == 0 { return mmapData{f, nil, nil} } h, err := syscall.CreateFileMapping(syscall.Handle(f.Fd()), nil, syscall.PAGE_READONLY, uint32(size>>32), uint32(size), nil) if err != nil { log.Fatalf("CreateFileMapping %s: %v", f.Name(), err) } defer syscall.CloseHandle(syscall.Handle(h)) addr, err := syscall.MapViewOfFile(h, syscall.FILE_MAP_READ, 0, 0, 0) if err != nil { log.Fatalf("MapViewOfFile %s: %v", f.Name(), err) } data := (*[1 << 30]byte)(unsafe.Pointer(addr)) return mmapData{f, data[:size], data[:]} }
func Open(filename string) (mf *memfile, err error) { f, err := os.Open(filename) if err != nil { return nil, err } defer f.Close() fs, err := f.Stat() if err != nil { return nil, err } fsize := fs.Size() fmap, err := syscall.CreateFileMapping(syscall.Handle(f.Fd()), nil, syscall.PAGE_READONLY, 0, uint32(fsize), nil) if err != nil { return nil, err } defer syscall.CloseHandle(fmap) ptr, err := syscall.MapViewOfFile(fmap, syscall.FILE_MAP_READ, 0, 0, uintptr(fsize)) if err != nil { return nil, err } defer func() { if recover() != nil { mf = nil err = errors.New("Failed option a file") } }() return &memfile{ptr, fsize, (*[1 << 30]byte)(unsafe.Pointer(ptr))[:fsize]}, nil }
func mmap(fd uintptr, off int64, l, inprot int) (sli []byte, err error) { flProtect := uint32(syscall.PAGE_READONLY) dwDesiredAccess := uint32(syscall.FILE_MAP_READ) switch { case inprot&WRITE != 0: flProtect = syscall.PAGE_READWRITE dwDesiredAccess = syscall.FILE_MAP_WRITE case inprot&RDWR != 0: flProtect = syscall.PAGE_READWRITE dwDesiredAccess = syscall.FILE_MAP_WRITE } h, errno := syscall.CreateFileMapping(syscall.Handle(fd), nil, flProtect, 0, uint32(l), nil) if h == 0 { return nil, os.NewSyscallError("CreateFileMapping", errno) } addr, errno := syscall.MapViewOfFile(h, dwDesiredAccess, uint32(off>>32), uint32(off&0xFFFFFFFF), uintptr(l)) if addr == 0 { return nil, os.NewSyscallError("MapViewOfFile", errno) } handleLock.Lock() handleMap[addr] = h handleLock.Unlock() var header = struct { d uintptr l, c int }{addr, l, l} sli = *(*[]byte)(unsafe.Pointer(&header)) return sli, nil }
func mmap(len int, prot, flags, hfile uintptr, off int64) ([]byte, error) { flProtect := uint32(syscall.PAGE_READONLY) dwDesiredAccess := uint32(syscall.FILE_MAP_READ) switch { case prot© != 0: flProtect = syscall.PAGE_WRITECOPY dwDesiredAccess = syscall.FILE_MAP_COPY case prot&RDWR != 0: flProtect = syscall.PAGE_READWRITE dwDesiredAccess = syscall.FILE_MAP_WRITE } if prot&EXEC != 0 { flProtect <<= 4 dwDesiredAccess |= syscall.FILE_MAP_EXECUTE } // The maximum size is the area of the file, starting from 0, // that we wish to allow to be mappable. It is the sum of // the length the user requested, plus the offset where that length // is starting from. This does not map the data into memory. maxSizeHigh := uint32((off + int64(len)) >> 32) maxSizeLow := uint32((off + int64(len)) & 0xFFFFFFFF) // TODO: Do we need to set some security attributes? It might help portability. h, errno := syscall.CreateFileMapping(syscall.Handle(hfile), nil, flProtect, maxSizeHigh, maxSizeLow, nil) if h == 0 { return nil, os.NewSyscallError("CreateFileMapping", errno) } // Actually map a view of the data into memory. The view's size // is the length the user requested. fileOffsetHigh := uint32(off >> 32) fileOffsetLow := uint32(off & 0xFFFFFFFF) addr, errno := syscall.MapViewOfFile(h, dwDesiredAccess, fileOffsetHigh, fileOffsetLow, uintptr(len)) if addr == 0 { return nil, os.NewSyscallError("MapViewOfFile", errno) } handleLock.Lock() handleMap[addr] = h handleLock.Unlock() m := MMap{} dh := m.header() dh.Data = addr dh.Len = len dh.Cap = dh.Len return m, nil }
func (m *mmap) mapFile() error { h, err := syscall.CreateFileMapping(syscall.Handle(m.src.Fd()), nil, syscall.PAGE_READONLY, uint32(m.sz>>32), uint32(m.sz), nil) if err != nil { return err } m.handle = uintptr(h) // for later unmapping addr, err := syscall.MapViewOfFile(h, syscall.FILE_MAP_READ, 0, 0, 0) if err != nil { return err } m.buf = []byte{} slcHead := (*reflect.SliceHeader)(unsafe.Pointer(&m.buf)) slcHead.Data = addr slcHead.Len = int(m.sz) slcHead.Cap = int(m.sz) return nil }
// Open memory-maps the named file for reading. func Open(filename string) (*ReaderAt, error) { f, err := os.Open(filename) if err != nil { return nil, err } defer f.Close() fi, err := f.Stat() if err != nil { return nil, err } size := fi.Size() if size == 0 { return &ReaderAt{}, nil } if size < 0 { return nil, fmt.Errorf("mmap: file %q has negative size", filename) } if size != int64(int(size)) { return nil, fmt.Errorf("mmap: file %q is too large", filename) } low, high := uint32(size), uint32(size>>32) fmap, err := syscall.CreateFileMapping(syscall.Handle(f.Fd()), nil, syscall.PAGE_READONLY, high, low, nil) if err != nil { return nil, err } defer syscall.CloseHandle(fmap) ptr, err := syscall.MapViewOfFile(fmap, syscall.FILE_MAP_READ, 0, 0, uintptr(size)) if err != nil { return nil, err } data := (*[1 << 30]byte)(unsafe.Pointer(ptr))[:size] r := &ReaderAt{data: data} if debug { var p *byte if len(data) != 0 { p = &data[0] } println("mmap", r, p) } runtime.SetFinalizer(r, (*ReaderAt).Close) return r, nil }
func (agent *Pagent) Connect() error { var err (error) agent.Hwnd, err = FindWindow(syscall.StringToUTF16Ptr("Pageant"), syscall.StringToUTF16Ptr("Pageant")) if err != nil { return err } agent.Fmap, err = syscall.CreateFileMapping(syscall.InvalidHandle, nil, syscall.PAGE_READWRITE, 0, 8129, syscall.StringToUTF16Ptr(MAPNAME)) if err != nil { return errors.New("CreateFileMapping failed..") } agent.SharedMemory, err = syscall.MapViewOfFile(agent.Fmap, syscall.FILE_MAP_WRITE, 0, 0, 0) if err != nil { return errors.New("Was not able to map agent..") } agent.Data = (*[MAX_MSG_LEN]byte)(unsafe.Pointer(agent.SharedMemory)) return nil }
func createMapping(name string, size int) (*Mapping, []byte) { f, err := os.OpenFile(name, os.O_RDWR, 0) if err != nil { log.Fatalf("failed to open comm file: %v", err) } defer f.Close() mapping, err := syscall.CreateFileMapping(syscall.InvalidHandle, nil, syscall.PAGE_READWRITE, 0, uint32(size), nil) if err != nil { log.Fatalf("failed to create file mapping: %v", err) } const FILE_MAP_ALL_ACCESS = 0xF001F addr, err := syscall.MapViewOfFile(mapping, FILE_MAP_ALL_ACCESS, 0, 0, uintptr(size)) if err != nil { log.Fatalf("failed to mmap comm file: %v", err) } hdr := reflect.SliceHeader{addr, size, size} mem := *(*[]byte)(unsafe.Pointer(&hdr)) mem[0] = 1 // test access return &Mapping{mapping, addr}, mem }
func mmap(len int, prot, flags, hfile uintptr, off int64) ([]byte, error) { if int(uint32(len)) != len { panic("file is too large to map") } flProtect := uint32(syscall.PAGE_READONLY) dwDesiredAccess := uint32(syscall.FILE_MAP_READ) switch { case prot© != 0: flProtect = syscall.PAGE_WRITECOPY dwDesiredAccess = syscall.FILE_MAP_COPY case prot&RDWR != 0: flProtect = syscall.PAGE_READWRITE dwDesiredAccess = syscall.FILE_MAP_WRITE } if prot&EXEC != 0 { flProtect <<= 4 dwDesiredAccess |= syscall.FILE_MAP_EXECUTE } // TODO: Do we need to set some security attributes? It might help portability. h, errno := syscall.CreateFileMapping(syscall.Handle(hfile), nil, flProtect, 0, uint32(len), nil) if h == 0 { return nil, os.NewSyscallError("CreateFileMapping", errno) } addr, errno := syscall.MapViewOfFile(h, dwDesiredAccess, uint32(off>>32), uint32(off&0xFFFFFFFF), uintptr(len)) if addr == 0 { return nil, os.NewSyscallError("MapViewOfFile", errno) } handleLock.Lock() handleMap[addr] = h handleLock.Unlock() m := MMap{} dh := m.header() dh.Data = addr dh.Len = len dh.Cap = dh.Len return m, nil }
// Windows mmap always mapes the entire file regardless of the specified length. func mmap(length int, hfile uintptr) ([]byte, error) { h, errno := syscall.CreateFileMapping(syscall.Handle(hfile), nil, syscall.PAGE_READWRITE, 0, 0, nil) if h == 0 { return nil, os.NewSyscallError("CreateFileMapping", errno) } addr, errno := syscall.MapViewOfFile(h, syscall.FILE_MAP_WRITE, 0, 0, 0) if addr == 0 { return nil, os.NewSyscallError("MapViewOfFile", errno) } handleLock.Lock() handleMap[addr] = h handleLock.Unlock() m := MMap{} dh := m.header() dh.Data = addr dh.Len = length dh.Cap = length return m, nil }
// Windows mmap always mapes the entire file regardless of the specified length. func mmap(length int, prot, flags, hfile uintptr, off int64) ([]byte, error) { flProtect := uint32(syscall.PAGE_READONLY) dwDesiredAccess := uint32(syscall.FILE_MAP_READ) switch { case prot© != 0: flProtect = syscall.PAGE_WRITECOPY dwDesiredAccess = syscall.FILE_MAP_COPY case prot&RDWR != 0: flProtect = syscall.PAGE_READWRITE dwDesiredAccess = syscall.FILE_MAP_WRITE } if prot&EXEC != 0 { flProtect <<= 4 dwDesiredAccess |= syscall.FILE_MAP_EXECUTE } h, errno := syscall.CreateFileMapping(syscall.Handle(hfile), nil, flProtect, 0, 0, nil) if h == 0 { return nil, os.NewSyscallError("CreateFileMapping", errno) } addr, errno := syscall.MapViewOfFile(h, dwDesiredAccess, uint32(off>>32), uint32(off&0xFFFFFFFF), 0) if addr == 0 { return nil, os.NewSyscallError("MapViewOfFile", errno) } handleLock.Lock() handleMap[addr] = h handleLock.Unlock() m := MMap{} dh := m.header() dh.Data = addr dh.Len = length dh.Cap = length return m, nil }
func mmap(fd int, length int) (data []byte, err error) { h, errno := syscall.CreateFileMapping(syscall.Handle(fd), nil, uint32(syscall.PAGE_READONLY), 0, uint32(length), nil) if h == 0 { return nil, os.NewSyscallError("CreateFileMapping", errno) } addr, errno := syscall.MapViewOfFile(h, uint32(syscall.FILE_MAP_READ), 0, 0, uintptr(length)) if addr == 0 { return nil, os.NewSyscallError("MapViewOfFile", errno) } handleLock.Lock() handleMap[addr] = h handleLock.Unlock() m := MMap{} dh := m.header() dh.Data = addr dh.Len = length dh.Cap = dh.Len return m, nil }