//go:build windows && !go1.26 package sequential import ( "os" "unsafe" "golang.org/x/sys/windows" ) func openFileSequential(name string, flag int, _ os.FileMode) (file *os.File, err error) { if name == "" { return nil, &os.PathError{Op: "open", Path: name, Err: windows.ERROR_FILE_NOT_FOUND} } r, e := openSequential(name, flag|windows.O_CLOEXEC) if e != nil { return nil, &os.PathError{Op: "open", Path: name, Err: e} } return os.NewFile(uintptr(r), name), nil } func makeInheritSa() *windows.SecurityAttributes { var sa windows.SecurityAttributes sa.Length = uint32(unsafe.Sizeof(sa)) sa.InheritHandle = 1 return &sa } func openSequential(path string, mode int) (fd windows.Handle, err error) { if len(path) == 0 { return windows.InvalidHandle, windows.ERROR_FILE_NOT_FOUND } pathp, err := windows.UTF16PtrFromString(path) if err != nil { return windows.InvalidHandle, err } var access uint32 switch mode & (windows.O_RDONLY | windows.O_WRONLY | windows.O_RDWR) { case windows.O_RDONLY: access = windows.GENERIC_READ case windows.O_WRONLY: access = windows.GENERIC_WRITE case windows.O_RDWR: access = windows.GENERIC_READ | windows.GENERIC_WRITE } if mode&windows.O_CREAT != 0 { access |= windows.GENERIC_WRITE } if mode&windows.O_APPEND != 0 { access &^= windows.GENERIC_WRITE access |= windows.FILE_APPEND_DATA } sharemode := uint32(windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE) var sa *windows.SecurityAttributes if mode&windows.O_CLOEXEC == 0 { sa = makeInheritSa() } var createmode uint32 switch { case mode&(windows.O_CREAT|windows.O_EXCL) == (windows.O_CREAT | windows.O_EXCL): createmode = windows.CREATE_NEW case mode&(windows.O_CREAT|windows.O_TRUNC) == (windows.O_CREAT | windows.O_TRUNC): createmode = windows.CREATE_ALWAYS case mode&windows.O_CREAT == windows.O_CREAT: createmode = windows.OPEN_ALWAYS case mode&windows.O_TRUNC == windows.O_TRUNC: createmode = windows.TRUNCATE_EXISTING default: createmode = windows.OPEN_EXISTING } // Use FILE_FLAG_SEQUENTIAL_SCAN rather than FILE_ATTRIBUTE_NORMAL as implemented in golang. // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea#FILE_FLAG_SEQUENTIAL_SCAN h, e := windows.CreateFile(pathp, access, sharemode, sa, createmode, windows.FILE_FLAG_SEQUENTIAL_SCAN, 0) return h, e }