Source file src/cmd/vendor/golang.org/x/telemetry/internal/mmap/mmap_windows.go

     1  // Copyright 2011 The Go Authors.  All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package mmap
     6  
     7  import (
     8  	"fmt"
     9  	"os"
    10  	"syscall"
    11  	"unsafe"
    12  
    13  	"golang.org/x/sys/windows"
    14  )
    15  
    16  func mmapFile(f *os.File) (*Data, error) {
    17  	st, err := f.Stat()
    18  	if err != nil {
    19  		return nil, err
    20  	}
    21  	size := st.Size()
    22  	if size == 0 {
    23  		return &Data{f, nil, nil}, nil
    24  	}
    25  	// set the min and max sizes to zero to map the whole file, as described in
    26  	// https://learn.microsoft.com/en-us/windows/win32/memory/creating-a-file-mapping-object#file-mapping-size
    27  	h, err := windows.CreateFileMapping(windows.Handle(f.Fd()), nil, syscall.PAGE_READWRITE, 0, 0, nil)
    28  	if err != nil {
    29  		return nil, fmt.Errorf("CreateFileMapping %s: %w", f.Name(), err)
    30  	}
    31  	// the mapping extends from zero to the end of the file mapping
    32  	// https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-mapviewoffile
    33  	addr, err := windows.MapViewOfFile(h, syscall.FILE_MAP_READ|syscall.FILE_MAP_WRITE, 0, 0, 0)
    34  	if err != nil {
    35  		return nil, fmt.Errorf("MapViewOfFile %s: %w", f.Name(), err)
    36  	}
    37  	// Note: previously, we called windows.VirtualQuery here to get the exact
    38  	// size of the memory mapped region, but VirtualQuery reported sizes smaller
    39  	// than the actual file size (hypothesis: VirtualQuery only reports pages in
    40  	// a certain state, and newly written pages may not be counted).
    41  	return &Data{f, unsafe.Slice((*byte)(unsafe.Pointer(addr)), size), h}, nil
    42  }
    43  
    44  func munmapFile(d *Data) error {
    45  	err := windows.UnmapViewOfFile(uintptr(unsafe.Pointer(&d.Data[0])))
    46  	x, ok := d.Windows.(windows.Handle)
    47  	if ok {
    48  		windows.CloseHandle(x)
    49  	}
    50  	d.f.Close()
    51  	return err
    52  }
    53  

View as plain text