diff --git a/backuptar/tar.go b/backuptar/tar.go index 088a43c..cb461ca 100644 --- a/backuptar/tar.go +++ b/backuptar/tar.go @@ -16,6 +16,7 @@ import ( "time" "github.com/Microsoft/go-winio" + "golang.org/x/sys/windows" ) const ( @@ -297,11 +298,11 @@ func FileInfoFromHeader(hdr *tar.Header) (name string, size int64, fileInfo *win size = hdr.Size } fileInfo = &winio.FileBasicInfo{ - LastAccessTime: syscall.NsecToFiletime(hdr.AccessTime.UnixNano()), - LastWriteTime: syscall.NsecToFiletime(hdr.ModTime.UnixNano()), - ChangeTime: syscall.NsecToFiletime(hdr.ChangeTime.UnixNano()), + LastAccessTime: windows.NsecToFiletime(hdr.AccessTime.UnixNano()), + LastWriteTime: windows.NsecToFiletime(hdr.ModTime.UnixNano()), + ChangeTime: windows.NsecToFiletime(hdr.ChangeTime.UnixNano()), // Default to ModTime, we'll pull hdrCreationTime below if present - CreationTime: syscall.NsecToFiletime(hdr.ModTime.UnixNano()), + CreationTime: windows.NsecToFiletime(hdr.ModTime.UnixNano()), } if attrStr, ok := hdr.PAXRecords[hdrFileAttributes]; ok { attr, err := strconv.ParseUint(attrStr, 10, 32) @@ -319,7 +320,7 @@ func FileInfoFromHeader(hdr *tar.Header) (name string, size int64, fileInfo *win if err != nil { return "", 0, nil, err } - fileInfo.CreationTime = syscall.NsecToFiletime(creationTime.UnixNano()) + fileInfo.CreationTime = windows.NsecToFiletime(creationTime.UnixNano()) } return } diff --git a/fileinfo.go b/fileinfo.go index ada2fba..3ab6bff 100644 --- a/fileinfo.go +++ b/fileinfo.go @@ -5,21 +5,14 @@ package winio import ( "os" "runtime" - "syscall" "unsafe" -) -//sys getFileInformationByHandleEx(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) = GetFileInformationByHandleEx -//sys setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) = SetFileInformationByHandle - -const ( - fileBasicInfo = 0 - fileIDInfo = 0x12 + "golang.org/x/sys/windows" ) // FileBasicInfo contains file access time and file attributes information. type FileBasicInfo struct { - CreationTime, LastAccessTime, LastWriteTime, ChangeTime syscall.Filetime + CreationTime, LastAccessTime, LastWriteTime, ChangeTime windows.Filetime FileAttributes uint32 pad uint32 // padding } @@ -27,7 +20,7 @@ type FileBasicInfo struct { // GetFileBasicInfo retrieves times and attributes for a file. func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) { bi := &FileBasicInfo{} - if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil { + if err := windows.GetFileInformationByHandleEx(windows.Handle(f.Fd()), windows.FileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil { return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err} } runtime.KeepAlive(f) @@ -36,13 +29,32 @@ func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) { // SetFileBasicInfo sets times and attributes for a file. func SetFileBasicInfo(f *os.File, bi *FileBasicInfo) error { - if err := setFileInformationByHandle(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil { + if err := windows.SetFileInformationByHandle(windows.Handle(f.Fd()), windows.FileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil { return &os.PathError{Op: "SetFileInformationByHandle", Path: f.Name(), Err: err} } runtime.KeepAlive(f) return nil } +// FileStandardInfo contains extended information for the file. +// FILE_STANDARD_INFO in WinBase.h +// https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_standard_info +type FileStandardInfo struct { + AllocationSize, EndOfFile int64 + NumberOfLinks uint32 + DeletePending, Directory bool +} + +// GetFileStandardInfo retrieves ended information for the file. +func GetFileStandardInfo(f *os.File) (*FileStandardInfo, error) { + si := &FileStandardInfo{} + if err := windows.GetFileInformationByHandleEx(windows.Handle(f.Fd()), windows.FileStandardInfo, (*byte)(unsafe.Pointer(si)), uint32(unsafe.Sizeof(*si))); err != nil { + return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err} + } + runtime.KeepAlive(f) + return si, nil +} + // FileIDInfo contains the volume serial number and file ID for a file. This pair should be // unique on a system. type FileIDInfo struct { @@ -53,7 +65,7 @@ type FileIDInfo struct { // GetFileID retrieves the unique (volume, file ID) pair for a file. func GetFileID(f *os.File) (*FileIDInfo, error) { fileID := &FileIDInfo{} - if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileIDInfo, (*byte)(unsafe.Pointer(fileID)), uint32(unsafe.Sizeof(*fileID))); err != nil { + if err := windows.GetFileInformationByHandleEx(windows.Handle(f.Fd()), windows.FileIdInfo, (*byte)(unsafe.Pointer(fileID)), uint32(unsafe.Sizeof(*fileID))); err != nil { return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err} } runtime.KeepAlive(f) diff --git a/fileinfo_test.go b/fileinfo_test.go new file mode 100644 index 0000000..e79700b --- /dev/null +++ b/fileinfo_test.go @@ -0,0 +1,134 @@ +package winio + +import ( + "io/ioutil" + "os" + "testing" + + "golang.org/x/sys/windows" +) + +// Checks if current matches expected. Note that AllocationSize is filesystem-specific, +// so we check that the current.AllocationSize is >= expected.AllocationSize. +// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/5afa7f66-619c-48f3-955f-68c4ece704ae +func checkFileStandardInfo(t *testing.T, current, expected *FileStandardInfo) { + if current.AllocationSize < expected.AllocationSize { + t.Fatalf("FileStandardInfo unexpectedly had AllocationSize %d, expecting >=%d", current.AllocationSize, expected.AllocationSize) + } + + if current.EndOfFile != expected.EndOfFile { + t.Fatalf("FileStandardInfo unexpectedly had EndOfFile %d, expecting %d", current.EndOfFile, expected.EndOfFile) + } + + if current.NumberOfLinks != expected.NumberOfLinks { + t.Fatalf("FileStandardInfo unexpectedly had NumberOfLinks %d, expecting %d", current.NumberOfLinks, expected.NumberOfLinks) + } + + if current.DeletePending != expected.DeletePending { + if current.DeletePending { + t.Fatalf("FileStandardInfo unexpectedly DeletePending") + } else { + t.Fatalf("FileStandardInfo unexpectedly not DeletePending") + } + } + + if current.Directory != expected.Directory { + if current.Directory { + t.Fatalf("FileStandardInfo unexpectedly Directory") + } else { + t.Fatalf("FileStandardInfo unexpectedly not Directory") + } + } +} + +func TestGetFileStandardInfo_File(t *testing.T) { + f, err := ioutil.TempFile("", "tst") + if err != nil { + t.Fatal(err) + } + defer f.Close() + defer os.Remove(f.Name()) + + expectedFileInfo := &FileStandardInfo{ + AllocationSize: 0, + EndOfFile: 0, + NumberOfLinks: 1, + DeletePending: false, + Directory: false, + } + + info, err := GetFileStandardInfo(f) + if err != nil { + t.Fatal(err) + } + checkFileStandardInfo(t, info, expectedFileInfo) + + bytesWritten, err := f.Write([]byte("0123456789")) + if err != nil { + t.Fatal(err) + } + + expectedFileInfo.EndOfFile = int64(bytesWritten) + expectedFileInfo.AllocationSize = int64(bytesWritten) + + info, err = GetFileStandardInfo(f) + if err != nil { + t.Fatal(err) + } + checkFileStandardInfo(t, info, expectedFileInfo) + + linkName := f.Name() + ".link" + + if err = os.Link(f.Name(), linkName); err != nil { + t.Fatal(err) + } + defer os.Remove(linkName) + + expectedFileInfo.NumberOfLinks = 2 + + info, err = GetFileStandardInfo(f) + if err != nil { + t.Fatal(err) + } + checkFileStandardInfo(t, info, expectedFileInfo) + + os.Remove(linkName) + + expectedFileInfo.NumberOfLinks = 1 + + info, err = GetFileStandardInfo(f) + if err != nil { + t.Fatal(err) + } + checkFileStandardInfo(t, info, expectedFileInfo) +} + +func TestGetFileStandardInfo_Directory(t *testing.T) { + tempDir, err := ioutil.TempDir("", "tst") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tempDir) + + // os.Open returns the Search Handle, not the Directory Handle + // See https://github.com/golang/go/issues/13738 + f, err := OpenForBackup(tempDir, windows.GENERIC_READ, 0, windows.OPEN_EXISTING) + if err != nil { + t.Fatal(err) + } + defer f.Close() + + expectedFileInfo := &FileStandardInfo{ + AllocationSize: 0, + EndOfFile: 0, + NumberOfLinks: 1, + DeletePending: false, + Directory: true, + } + + info, err := GetFileStandardInfo(f) + if err != nil { + t.Fatal(err) + } + checkFileStandardInfo(t, info, expectedFileInfo) +} diff --git a/pkg/etw/mksyscall_windows.go b/pkg/etw/mksyscall_windows.go index 549d183..36a7059 100644 --- a/pkg/etw/mksyscall_windows.go +++ b/pkg/etw/mksyscall_windows.go @@ -33,6 +33,9 @@ like func declarations if //sys is replaced by func, but: //sys LoadLibrary(libname string) (handle uint32, err error) [failretval==-1] = LoadLibraryA and is [failretval==0] by default. +* If the function name ends in a "?", then the function not existing is non- + fatal, and an error will be returned instead of panicking. + Usage: mksyscall_windows [flags] [path ...] @@ -107,14 +110,20 @@ func (p *Param) tmpVar() string { // BoolTmpVarCode returns source code for bool temp variable. func (p *Param) BoolTmpVarCode() string { - const code = `var %s uint32 - if %s { - %s = 1 - } else { - %s = 0 + const code = `var %[1]s uint32 + if %[2]s { + %[1]s = 1 }` - tmp := p.tmpVar() - return fmt.Sprintf(code, tmp, p.Name, tmp, tmp) + return fmt.Sprintf(code, p.tmpVar(), p.Name) +} + +// BoolPointerTmpVarCode returns source code for bool temp variable. +func (p *Param) BoolPointerTmpVarCode() string { + const code = `var %[1]s uint32 + if *%[2]s { + %[1]s = 1 + }` + return fmt.Sprintf(code, p.tmpVar(), p.Name) } // SliceTmpVarCode returns source code for slice temp variable. @@ -152,6 +161,8 @@ func (p *Param) TmpVarCode() string { switch { case p.Type == "bool": return p.BoolTmpVarCode() + case p.Type == "*bool": + return p.BoolPointerTmpVarCode() case strings.HasPrefix(p.Type, "[]"): return p.SliceTmpVarCode() default: @@ -159,6 +170,16 @@ func (p *Param) TmpVarCode() string { } } +// TmpVarReadbackCode returns source code for reading back the temp variable into the original variable. +func (p *Param) TmpVarReadbackCode() string { + switch { + case p.Type == "*bool": + return fmt.Sprintf("*%s = %s != 0", p.Name, p.tmpVar()) + default: + return "" + } +} + // TmpVarHelperCode returns source code for helper's temp variable. func (p *Param) TmpVarHelperCode() string { if p.Type != "string" { @@ -174,6 +195,8 @@ func (p *Param) SyscallArgList() []string { t := p.HelperType() var s string switch { + case t == "*bool": + s = fmt.Sprintf("unsafe.Pointer(&%s)", p.tmpVar()) case t[0] == '*': s = fmt.Sprintf("unsafe.Pointer(%s)", p.Name) case t == "bool": @@ -218,10 +241,11 @@ func join(ps []*Param, fn func(*Param) string, sep string) string { // Rets describes function return parameters. type Rets struct { - Name string - Type string - ReturnsError bool - FailCond string + Name string + Type string + ReturnsError bool + FailCond string + fnMaybeAbsent bool } // ErrorVarName returns error variable name for r. @@ -252,6 +276,8 @@ func (r *Rets) List() string { s := join(r.ToParams(), func(p *Param) string { return p.Name + " " + p.Type }, ", ") if len(s) > 0 { s = "(" + s + ")" + } else if r.fnMaybeAbsent { + s = "(err error)" } return s } @@ -280,17 +306,13 @@ func (r *Rets) SetReturnValuesCode() string { func (r *Rets) useLongHandleErrorCode(retvar string) string { const code = `if %s { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = %sEINVAL - } + err = errnoErr(e1) }` cond := retvar + " == 0" if r.FailCond != "" { cond = strings.Replace(r.FailCond, "failretval", retvar, 1) } - return fmt.Sprintf(code, cond, syscalldot()) + return fmt.Sprintf(code, cond) } // SetErrorCode returns source code that sets return parameters. @@ -455,6 +477,10 @@ func newFn(s string) (*Fn, error) { default: return nil, errors.New("Could not extract dll name from \"" + f.src + "\"") } + if n := f.dllfuncname; strings.HasSuffix(n, "?") { + f.dllfuncname = n[:len(n)-1] + f.Rets.fnMaybeAbsent = true + } return f, nil } @@ -553,6 +579,22 @@ func (f *Fn) HelperCallParamList() string { return strings.Join(a, ", ") } +// MaybeAbsent returns source code for handling functions that are possibly unavailable. +func (p *Fn) MaybeAbsent() string { + if !p.Rets.fnMaybeAbsent { + return "" + } + const code = `%[1]s = proc%[2]s.Find() + if %[1]s != nil { + return + }` + errorVar := p.Rets.ErrorVarName() + if errorVar == "" { + errorVar = "err" + } + return fmt.Sprintf(code, errorVar, p.DLLFuncName()) +} + // IsUTF16 is true, if f is W (utf16) function. It is false // for all A (ascii) functions. func (f *Fn) IsUTF16() bool { @@ -657,6 +699,7 @@ func (src *Source) DLLs() []string { r = append(r, name) } } + sort.Strings(r) return r } @@ -691,6 +734,13 @@ func (src *Source) ParseFile(path string) error { return err } src.Files = append(src.Files, path) + sort.Slice(src.Funcs, func(i, j int) bool { + fi, fj := src.Funcs[i], src.Funcs[j] + if fi.DLLName() == fj.DLLName() { + return fi.DLLFuncName() < fj.DLLFuncName() + } + return fi.DLLName() < fj.DLLName() + }) // get package name fset := token.NewFileSet() @@ -850,6 +900,7 @@ const ( var ( errERROR_IO_PENDING error = {{syscalldot}}Errno(errnoERROR_IO_PENDING) + errERROR_EINVAL error = {{syscalldot}}EINVAL ) // errnoErr returns common boxed Errno values, to prevent @@ -857,7 +908,7 @@ var ( func errnoErr(e {{syscalldot}}Errno) error { switch e { case 0: - return nil + return errERROR_EINVAL case errnoERROR_IO_PENDING: return errERROR_IO_PENDING } @@ -889,7 +940,7 @@ func {{.Name}}({{.ParamList}}) {{template "results" .}}{ {{define "funcbody"}} func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{ -{{template "tmpvars" .}} {{template "syscall" .}} +{{template "maybeabsent" .}} {{template "tmpvars" .}} {{template "syscall" .}} {{template "tmpvarsreadback" .}} {{template "seterror" .}}{{template "printtrace" .}} return } {{end}} @@ -897,6 +948,9 @@ func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{ {{define "helpertmpvars"}}{{range .Params}}{{if .TmpVarHelperCode}} {{.TmpVarHelperCode}} {{end}}{{end}}{{end}} +{{define "maybeabsent"}}{{if .MaybeAbsent}}{{.MaybeAbsent}} +{{end}}{{end}} + {{define "tmpvars"}}{{range .Params}}{{if .TmpVarCode}} {{.TmpVarCode}} {{end}}{{end}}{{end}} @@ -904,6 +958,9 @@ func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{ {{define "syscall"}}{{.Rets.SetReturnValuesCode}}{{.Syscall}}(proc{{.DLLFuncName}}.Addr(), {{.ParamCount}}, {{.SyscallParamList}}){{end}} +{{define "tmpvarsreadback"}}{{range .Params}}{{if .TmpVarReadbackCode}} +{{.TmpVarReadbackCode}}{{end}}{{end}}{{end}} + {{define "seterror"}}{{if .Rets.SetErrorCode}} {{.Rets.SetErrorCode}} {{end}}{{end}} diff --git a/pkg/etw/zsyscall_windows.go b/pkg/etw/zsyscall_windows.go index 4e8a719..719b13d 100644 --- a/pkg/etw/zsyscall_windows.go +++ b/pkg/etw/zsyscall_windows.go @@ -19,6 +19,7 @@ const ( var ( errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) + errERROR_EINVAL error = syscall.EINVAL ) // errnoErr returns common boxed Errno values, to prevent @@ -26,7 +27,7 @@ var ( func errnoErr(e syscall.Errno) error { switch e { case 0: - return nil + return errERROR_EINVAL case errnoERROR_IO_PENDING: return errERROR_IO_PENDING } @@ -40,9 +41,9 @@ var ( modadvapi32 = windows.NewLazySystemDLL("advapi32.dll") procEventRegister = modadvapi32.NewProc("EventRegister") + procEventSetInformation = modadvapi32.NewProc("EventSetInformation") procEventUnregister = modadvapi32.NewProc("EventUnregister") procEventWriteTransfer = modadvapi32.NewProc("EventWriteTransfer") - procEventSetInformation = modadvapi32.NewProc("EventSetInformation") ) func eventRegister(providerId *windows.GUID, callback uintptr, callbackContext uintptr, providerHandle *providerHandle) (win32err error) { @@ -53,22 +54,6 @@ func eventRegister(providerId *windows.GUID, callback uintptr, callbackContext u return } -func eventUnregister_64(providerHandle providerHandle) (win32err error) { - r0, _, _ := syscall.Syscall(procEventUnregister.Addr(), 1, uintptr(providerHandle), 0, 0) - if r0 != 0 { - win32err = syscall.Errno(r0) - } - return -} - -func eventWriteTransfer_64(providerHandle providerHandle, descriptor *eventDescriptor, activityID *windows.GUID, relatedActivityID *windows.GUID, dataDescriptorCount uint32, dataDescriptors *eventDataDescriptor) (win32err error) { - r0, _, _ := syscall.Syscall6(procEventWriteTransfer.Addr(), 6, uintptr(providerHandle), uintptr(unsafe.Pointer(descriptor)), uintptr(unsafe.Pointer(activityID)), uintptr(unsafe.Pointer(relatedActivityID)), uintptr(dataDescriptorCount), uintptr(unsafe.Pointer(dataDescriptors))) - if r0 != 0 { - win32err = syscall.Errno(r0) - } - return -} - func eventSetInformation_64(providerHandle providerHandle, class eventInfoClass, information uintptr, length uint32) (win32err error) { r0, _, _ := syscall.Syscall6(procEventSetInformation.Addr(), 4, uintptr(providerHandle), uintptr(class), uintptr(information), uintptr(length), 0, 0) if r0 != 0 { @@ -77,6 +62,22 @@ func eventSetInformation_64(providerHandle providerHandle, class eventInfoClass, return } +func eventSetInformation_32(providerHandle_low uint32, providerHandle_high uint32, class eventInfoClass, information uintptr, length uint32) (win32err error) { + r0, _, _ := syscall.Syscall6(procEventSetInformation.Addr(), 5, uintptr(providerHandle_low), uintptr(providerHandle_high), uintptr(class), uintptr(information), uintptr(length), 0) + if r0 != 0 { + win32err = syscall.Errno(r0) + } + return +} + +func eventUnregister_64(providerHandle providerHandle) (win32err error) { + r0, _, _ := syscall.Syscall(procEventUnregister.Addr(), 1, uintptr(providerHandle), 0, 0) + if r0 != 0 { + win32err = syscall.Errno(r0) + } + return +} + func eventUnregister_32(providerHandle_low uint32, providerHandle_high uint32) (win32err error) { r0, _, _ := syscall.Syscall(procEventUnregister.Addr(), 2, uintptr(providerHandle_low), uintptr(providerHandle_high), 0) if r0 != 0 { @@ -85,6 +86,14 @@ func eventUnregister_32(providerHandle_low uint32, providerHandle_high uint32) ( return } +func eventWriteTransfer_64(providerHandle providerHandle, descriptor *eventDescriptor, activityID *windows.GUID, relatedActivityID *windows.GUID, dataDescriptorCount uint32, dataDescriptors *eventDataDescriptor) (win32err error) { + r0, _, _ := syscall.Syscall6(procEventWriteTransfer.Addr(), 6, uintptr(providerHandle), uintptr(unsafe.Pointer(descriptor)), uintptr(unsafe.Pointer(activityID)), uintptr(unsafe.Pointer(relatedActivityID)), uintptr(dataDescriptorCount), uintptr(unsafe.Pointer(dataDescriptors))) + if r0 != 0 { + win32err = syscall.Errno(r0) + } + return +} + func eventWriteTransfer_32(providerHandle_low uint32, providerHandle_high uint32, descriptor *eventDescriptor, activityID *windows.GUID, relatedActivityID *windows.GUID, dataDescriptorCount uint32, dataDescriptors *eventDataDescriptor) (win32err error) { r0, _, _ := syscall.Syscall9(procEventWriteTransfer.Addr(), 7, uintptr(providerHandle_low), uintptr(providerHandle_high), uintptr(unsafe.Pointer(descriptor)), uintptr(unsafe.Pointer(activityID)), uintptr(unsafe.Pointer(relatedActivityID)), uintptr(dataDescriptorCount), uintptr(unsafe.Pointer(dataDescriptors)), 0, 0) if r0 != 0 { @@ -92,11 +101,3 @@ func eventWriteTransfer_32(providerHandle_low uint32, providerHandle_high uint32 } return } - -func eventSetInformation_32(providerHandle_low uint32, providerHandle_high uint32, class eventInfoClass, information uintptr, length uint32) (win32err error) { - r0, _, _ := syscall.Syscall6(procEventSetInformation.Addr(), 5, uintptr(providerHandle_low), uintptr(providerHandle_high), uintptr(class), uintptr(information), uintptr(length), 0) - if r0 != 0 { - win32err = syscall.Errno(r0) - } - return -} diff --git a/pkg/process/syscall.go b/pkg/process/syscall.go index 598d0cc..980105f 100644 --- a/pkg/process/syscall.go +++ b/pkg/process/syscall.go @@ -6,7 +6,7 @@ import ( "golang.org/x/sys/windows" ) -//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go syscall.go +//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go syscall.go //sys enumProcesses(pids *uint32, bufferSize uint32, retBufferSize *uint32) (err error) = kernel32.K32EnumProcesses //sys getProcessMemoryInfo(process handle, memCounters *ProcessMemoryCountersEx, size uint32) (err error) = kernel32.K32GetProcessMemoryInfo diff --git a/pkg/process/zsyscall_windows.go b/pkg/process/zsyscall_windows.go index a1f1a10..405206b 100644 --- a/pkg/process/zsyscall_windows.go +++ b/pkg/process/zsyscall_windows.go @@ -19,6 +19,7 @@ const ( var ( errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) + errERROR_EINVAL error = syscall.EINVAL ) // errnoErr returns common boxed Errno values, to prevent @@ -26,7 +27,7 @@ var ( func errnoErr(e syscall.Errno) error { switch e { case 0: - return nil + return errERROR_EINVAL case errnoERROR_IO_PENDING: return errERROR_IO_PENDING } @@ -47,11 +48,7 @@ var ( func enumProcesses(pids *uint32, bufferSize uint32, retBufferSize *uint32) (err error) { r1, _, e1 := syscall.Syscall(procK32EnumProcesses.Addr(), 3, uintptr(unsafe.Pointer(pids)), uintptr(bufferSize), uintptr(unsafe.Pointer(retBufferSize))) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -59,11 +56,7 @@ func enumProcesses(pids *uint32, bufferSize uint32, retBufferSize *uint32) (err func getProcessMemoryInfo(process handle, memCounters *ProcessMemoryCountersEx, size uint32) (err error) { r1, _, e1 := syscall.Syscall(procK32GetProcessMemoryInfo.Addr(), 3, uintptr(process), uintptr(unsafe.Pointer(memCounters)), uintptr(size)) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -71,11 +64,7 @@ func getProcessMemoryInfo(process handle, memCounters *ProcessMemoryCountersEx, func queryFullProcessImageName(process handle, flags uint32, buffer *uint16, bufferSize *uint32) (err error) { r1, _, e1 := syscall.Syscall6(procQueryFullProcessImageNameW.Addr(), 4, uintptr(process), uintptr(flags), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(bufferSize)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } diff --git a/pkg/security/mksyscall_windows.go b/pkg/security/mksyscall_windows.go index 7647734..d52b613 100644 --- a/pkg/security/mksyscall_windows.go +++ b/pkg/security/mksyscall_windows.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// Hard-coding unicode mode for VHD library. + // +build ignore /* @@ -22,7 +24,7 @@ like func declarations if //sys is replaced by func, but: * If the return parameter is an error number, it must be named err. -* If go func name needs to be different from it's winapi dll name, +* If go func name needs to be different from its winapi dll name, the winapi name could be specified at the end, after "=" sign, like //sys LoadLibrary(libname string) (handle uint32, err error) = LoadLibraryA @@ -33,6 +35,9 @@ like func declarations if //sys is replaced by func, but: //sys LoadLibrary(libname string) (handle uint32, err error) [failretval==-1] = LoadLibraryA and is [failretval==0] by default. +* If the function name ends in a "?", then the function not existing is non- + fatal, and an error will be returned instead of panicking. + Usage: mksyscall_windows [flags] [path ...] @@ -69,7 +74,6 @@ var ( filename = flag.String("output", "", "output file name (standard output if omitted)") printTraceFlag = flag.Bool("trace", false, "generate print statement after every syscall") systemDLL = flag.Bool("systemdll", true, "whether all DLLs should be loaded from the Windows system directory") - winio = flag.Bool("winio", false, "import go-winio") ) func trim(s string) string { @@ -108,14 +112,20 @@ func (p *Param) tmpVar() string { // BoolTmpVarCode returns source code for bool temp variable. func (p *Param) BoolTmpVarCode() string { - const code = `var %s uint32 - if %s { - %s = 1 - } else { - %s = 0 + const code = `var %[1]s uint32 + if %[2]s { + %[1]s = 1 }` - tmp := p.tmpVar() - return fmt.Sprintf(code, tmp, p.Name, tmp, tmp) + return fmt.Sprintf(code, p.tmpVar(), p.Name) +} + +// BoolPointerTmpVarCode returns source code for bool temp variable. +func (p *Param) BoolPointerTmpVarCode() string { + const code = `var %[1]s uint32 + if *%[2]s { + %[1]s = 1 + }` + return fmt.Sprintf(code, p.tmpVar(), p.Name) } // SliceTmpVarCode returns source code for slice temp variable. @@ -153,6 +163,8 @@ func (p *Param) TmpVarCode() string { switch { case p.Type == "bool": return p.BoolTmpVarCode() + case p.Type == "*bool": + return p.BoolPointerTmpVarCode() case strings.HasPrefix(p.Type, "[]"): return p.SliceTmpVarCode() default: @@ -160,6 +172,16 @@ func (p *Param) TmpVarCode() string { } } +// TmpVarReadbackCode returns source code for reading back the temp variable into the original variable. +func (p *Param) TmpVarReadbackCode() string { + switch { + case p.Type == "*bool": + return fmt.Sprintf("*%s = %s != 0", p.Name, p.tmpVar()) + default: + return "" + } +} + // TmpVarHelperCode returns source code for helper's temp variable. func (p *Param) TmpVarHelperCode() string { if p.Type != "string" { @@ -175,6 +197,8 @@ func (p *Param) SyscallArgList() []string { t := p.HelperType() var s string switch { + case t == "*bool": + s = fmt.Sprintf("unsafe.Pointer(&%s)", p.tmpVar()) case t[0] == '*': s = fmt.Sprintf("unsafe.Pointer(%s)", p.Name) case t == "bool": @@ -219,10 +243,11 @@ func join(ps []*Param, fn func(*Param) string, sep string) string { // Rets describes function return parameters. type Rets struct { - Name string - Type string - ReturnsError bool - FailCond string + Name string + Type string + ReturnsError bool + FailCond string + fnMaybeAbsent bool } // ErrorVarName returns error variable name for r. @@ -253,6 +278,8 @@ func (r *Rets) List() string { s := join(r.ToParams(), func(p *Param) string { return p.Name + " " + p.Type }, ", ") if len(s) > 0 { s = "(" + s + ")" + } else if r.fnMaybeAbsent { + s = "(err error)" } return s } @@ -281,17 +308,13 @@ func (r *Rets) SetReturnValuesCode() string { func (r *Rets) useLongHandleErrorCode(retvar string) string { const code = `if %s { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = %sEINVAL - } + err = errnoErr(e1) }` cond := retvar + " == 0" if r.FailCond != "" { cond = strings.Replace(r.FailCond, "failretval", retvar, 1) } - return fmt.Sprintf(code, cond, syscalldot()) + return fmt.Sprintf(code, cond) } // SetErrorCode returns source code that sets return parameters. @@ -299,12 +322,6 @@ func (r *Rets) SetErrorCode() string { const code = `if r0 != 0 { %s = %sErrno(r0) }` - const hrCode = `if int32(r0) < 0 { - if r0&0x1fff0000 == 0x00070000 { - r0 &= 0xffff - } - %s = %sErrno(r0) - }` if r.Name == "" && !r.ReturnsError { return "" } @@ -312,11 +329,7 @@ func (r *Rets) SetErrorCode() string { return r.useLongHandleErrorCode("r1") } if r.Type == "error" { - if r.Name == "hr" { - return fmt.Sprintf(hrCode, r.Name, syscalldot()) - } else { - return fmt.Sprintf(code, r.Name, syscalldot()) - } + return fmt.Sprintf(code, r.Name, syscalldot()) } s := "" switch { @@ -339,7 +352,6 @@ type Fn struct { Params []*Param Rets *Rets PrintTrace bool - confirmproc bool dllname string dllfuncname string src string @@ -467,9 +479,9 @@ func newFn(s string) (*Fn, error) { default: return nil, errors.New("Could not extract dll name from \"" + f.src + "\"") } - if f.dllfuncname[len(f.dllfuncname)-1] == '?' { - f.confirmproc = true - f.dllfuncname = f.dllfuncname[0 : len(f.dllfuncname)-1] + if n := f.dllfuncname; strings.HasSuffix(n, "?") { + f.dllfuncname = n[:len(n)-1] + f.Rets.fnMaybeAbsent = true } return f, nil } @@ -490,10 +502,6 @@ func (f *Fn) DLLFuncName() string { return f.dllfuncname } -func (f *Fn) ConfirmProc() bool { - return f.confirmproc -} - // ParamList returns source code for function f parameters. func (f *Fn) ParamList() string { return join(f.Params, func(p *Param) string { return p.Name + " " + p.Type }, ", ") @@ -573,6 +581,22 @@ func (f *Fn) HelperCallParamList() string { return strings.Join(a, ", ") } +// MaybeAbsent returns source code for handling functions that are possibly unavailable. +func (p *Fn) MaybeAbsent() string { + if !p.Rets.fnMaybeAbsent { + return "" + } + const code = `%[1]s = proc%[2]s.Find() + if %[1]s != nil { + return + }` + errorVar := p.Rets.ErrorVarName() + if errorVar == "" { + errorVar = "err" + } + return fmt.Sprintf(code, errorVar, p.DLLFuncName()) +} + // IsUTF16 is true, if f is W (utf16) function. It is false // for all A (ascii) functions. func (_ *Fn) IsUTF16() bool { @@ -606,18 +630,6 @@ func (f *Fn) HasStringParam() bool { return false } -var uniqDllFuncName = make(map[string]bool) - -// IsNotDuplicate is true if f is not a duplicated function -func (f *Fn) IsNotDuplicate() bool { - funcName := f.DLLFuncName() - if uniqDllFuncName[funcName] == false { - uniqDllFuncName[funcName] = true - return true - } - return false -} - // HelperName returns name of function f helper. func (f *Fn) HelperName() string { if !f.HasStringParam() { @@ -645,7 +657,7 @@ func (src *Source) ExternalImport(pkg string) { } // ParseFiles parses files listed in fs and extracts all syscall -// functions listed in sys comments. It returns source files +// functions listed in sys comments. It returns source files // and functions collection *Source if successful. func ParseFiles(fs []string) (*Source, error) { src := &Source{ @@ -675,6 +687,7 @@ func (src *Source) DLLs() []string { r = append(r, name) } } + sort.Strings(r) return r } @@ -709,6 +722,13 @@ func (src *Source) ParseFile(path string) error { return err } src.Files = append(src.Files, path) + sort.Slice(src.Funcs, func(i, j int) bool { + fi, fj := src.Funcs[i], src.Funcs[j] + if fi.DLLName() == fj.DLLName() { + return fi.DLLFuncName() < fj.DLLFuncName() + } + return fi.DLLName() < fj.DLLName() + }) // get package name fset := token.NewFileSet() @@ -725,7 +745,7 @@ func (src *Source) ParseFile(path string) error { return nil } -// IsStdRepo returns true if src is part of standard library. +// IsStdRepo reports whether src is part of standard library. func (src *Source) IsStdRepo() (bool, error) { if len(src.Files) == 0 { return false, errors.New("no input files provided") @@ -776,9 +796,6 @@ func (src *Source) Generate(w io.Writer) error { src.ExternalImport("golang.org/x/sys/windows") } } - if *winio { - src.ExternalImport("github.com/Microsoft/go-winio") - } if packageName != "syscall" { src.Import("syscall") } @@ -790,9 +807,6 @@ func (src *Source) Generate(w io.Writer) error { if !*systemDLL { return syscalldot() + "NewLazyDLL(" + arg + ")" } - if strings.HasPrefix(dll, "api_") || strings.HasPrefix(dll, "ext_") { - arg = strings.Replace(arg, "_", "-", -1) - } switch pkgtype { case pkgStd: return syscalldot() + "NewLazyDLL(sysdll.Add(" + arg + "))" @@ -852,7 +866,7 @@ func main() { // TODO: use println instead to print in the following template const srcTemplate = ` -{{define "main"}}// Code generated mksyscall_windows.exe DO NOT EDIT +{{define "main"}}// Code generated by 'go generate'; DO NOT EDIT. package {{packagename}} @@ -874,6 +888,7 @@ const ( var ( errERROR_IO_PENDING error = {{syscalldot}}Errno(errnoERROR_IO_PENDING) + errERROR_EINVAL error = {{syscalldot}}EINVAL ) // errnoErr returns common boxed Errno values, to prevent @@ -881,7 +896,7 @@ var ( func errnoErr(e {{syscalldot}}Errno) error { switch e { case 0: - return nil + return errERROR_EINVAL case errnoERROR_IO_PENDING: return errERROR_IO_PENDING } @@ -902,7 +917,7 @@ var ( {{define "dlls"}}{{range .DLLs}} mod{{.}} = {{newlazydll .}} {{end}}{{end}} -{{define "funcnames"}}{{range .Funcs}}{{if .IsNotDuplicate}} proc{{.DLLFuncName}} = mod{{.DLLName}}.NewProc("{{.DLLFuncName}}"){{end}} +{{define "funcnames"}}{{range .Funcs}} proc{{.DLLFuncName}} = mod{{.DLLName}}.NewProc("{{.DLLFuncName}}") {{end}}{{end}} {{define "helperbody"}} @@ -913,7 +928,7 @@ func {{.Name}}({{.ParamList}}) {{template "results" .}}{ {{define "funcbody"}} func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{ -{{template "tmpvars" .}} {{template "syscallcheck" .}}{{template "syscall" .}} +{{template "maybeabsent" .}} {{template "tmpvars" .}} {{template "syscall" .}} {{template "tmpvarsreadback" .}} {{template "seterror" .}}{{template "printtrace" .}} return } {{end}} @@ -921,6 +936,9 @@ func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{ {{define "helpertmpvars"}}{{range .Params}}{{if .TmpVarHelperCode}} {{.TmpVarHelperCode}} {{end}}{{end}}{{end}} +{{define "maybeabsent"}}{{if .MaybeAbsent}}{{.MaybeAbsent}} +{{end}}{{end}} + {{define "tmpvars"}}{{range .Params}}{{if .TmpVarCode}} {{.TmpVarCode}} {{end}}{{end}}{{end}} @@ -928,11 +946,8 @@ func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{ {{define "syscall"}}{{.Rets.SetReturnValuesCode}}{{.Syscall}}(proc{{.DLLFuncName}}.Addr(), {{.ParamCount}}, {{.SyscallParamList}}){{end}} -{{define "syscallcheck"}}{{if .ConfirmProc}}if {{.Rets.ErrorVarName}} = proc{{.DLLFuncName}}.Find(); {{.Rets.ErrorVarName}} != nil { - return -} -{{end}}{{end}} - +{{define "tmpvarsreadback"}}{{range .Params}}{{if .TmpVarReadbackCode}} +{{.TmpVarReadbackCode}}{{end}}{{end}}{{end}} {{define "seterror"}}{{if .Rets.SetErrorCode}} {{.Rets.SetErrorCode}} {{end}}{{end}} diff --git a/pkg/security/zsyscall_windows.go b/pkg/security/zsyscall_windows.go index 0f0c0de..4a90cb3 100644 --- a/pkg/security/zsyscall_windows.go +++ b/pkg/security/zsyscall_windows.go @@ -1,4 +1,4 @@ -// Code generated mksyscall_windows.exe DO NOT EDIT +// Code generated by 'go generate'; DO NOT EDIT. package security @@ -19,6 +19,7 @@ const ( var ( errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) + errERROR_EINVAL error = syscall.EINVAL ) // errnoErr returns common boxed Errno values, to prevent @@ -26,7 +27,7 @@ var ( func errnoErr(e syscall.Errno) error { switch e { case 0: - return nil + return errERROR_EINVAL case errnoERROR_IO_PENDING: return errERROR_IO_PENDING } @@ -40,30 +41,14 @@ var ( modadvapi32 = windows.NewLazySystemDLL("advapi32.dll") procGetSecurityInfo = modadvapi32.NewProc("GetSecurityInfo") - procSetSecurityInfo = modadvapi32.NewProc("SetSecurityInfo") procSetEntriesInAclW = modadvapi32.NewProc("SetEntriesInAclW") + procSetSecurityInfo = modadvapi32.NewProc("SetSecurityInfo") ) func getSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, ppsidOwner **uintptr, ppsidGroup **uintptr, ppDacl *uintptr, ppSacl *uintptr, ppSecurityDescriptor *uintptr) (err error) { r1, _, e1 := syscall.Syscall9(procGetSecurityInfo.Addr(), 8, uintptr(handle), uintptr(objectType), uintptr(si), uintptr(unsafe.Pointer(ppsidOwner)), uintptr(unsafe.Pointer(ppsidGroup)), uintptr(unsafe.Pointer(ppDacl)), uintptr(unsafe.Pointer(ppSacl)), uintptr(unsafe.Pointer(ppSecurityDescriptor)), 0) if r1 != 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, psidOwner uintptr, psidGroup uintptr, pDacl uintptr, pSacl uintptr) (err error) { - r1, _, e1 := syscall.Syscall9(procSetSecurityInfo.Addr(), 7, uintptr(handle), uintptr(objectType), uintptr(si), uintptr(psidOwner), uintptr(psidGroup), uintptr(pDacl), uintptr(pSacl), 0, 0) - if r1 != 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -71,11 +56,15 @@ func setSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, psidOw func setEntriesInAcl(count uintptr, pListOfEEs uintptr, oldAcl uintptr, newAcl *uintptr) (err error) { r1, _, e1 := syscall.Syscall6(procSetEntriesInAclW.Addr(), 4, uintptr(count), uintptr(pListOfEEs), uintptr(oldAcl), uintptr(unsafe.Pointer(newAcl)), 0, 0) if r1 != 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) + } + return +} + +func setSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, psidOwner uintptr, psidGroup uintptr, pDacl uintptr, pSacl uintptr) (err error) { + r1, _, e1 := syscall.Syscall9(procSetSecurityInfo.Addr(), 7, uintptr(handle), uintptr(objectType), uintptr(si), uintptr(psidOwner), uintptr(psidGroup), uintptr(pDacl), uintptr(pSacl), 0, 0) + if r1 != 0 { + err = errnoErr(e1) } return } diff --git a/syscall.go b/syscall.go index 5cb52bc..5955c99 100644 --- a/syscall.go +++ b/syscall.go @@ -1,3 +1,3 @@ package winio -//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go file.go pipe.go sd.go fileinfo.go privilege.go backup.go hvsock.go +//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go file.go pipe.go sd.go fileinfo.go privilege.go backup.go hvsock.go diff --git a/vhd/mksyscall_windows.go b/vhd/mksyscall_windows.go index 75d4714..d52b613 100644 --- a/vhd/mksyscall_windows.go +++ b/vhd/mksyscall_windows.go @@ -24,7 +24,7 @@ like func declarations if //sys is replaced by func, but: * If the return parameter is an error number, it must be named err. -* If go func name needs to be different from it's winapi dll name, +* If go func name needs to be different from its winapi dll name, the winapi name could be specified at the end, after "=" sign, like //sys LoadLibrary(libname string) (handle uint32, err error) = LoadLibraryA @@ -35,6 +35,9 @@ like func declarations if //sys is replaced by func, but: //sys LoadLibrary(libname string) (handle uint32, err error) [failretval==-1] = LoadLibraryA and is [failretval==0] by default. +* If the function name ends in a "?", then the function not existing is non- + fatal, and an error will be returned instead of panicking. + Usage: mksyscall_windows [flags] [path ...] @@ -109,14 +112,20 @@ func (p *Param) tmpVar() string { // BoolTmpVarCode returns source code for bool temp variable. func (p *Param) BoolTmpVarCode() string { - const code = `var %s uint32 - if %s { - %s = 1 - } else { - %s = 0 + const code = `var %[1]s uint32 + if %[2]s { + %[1]s = 1 }` - tmp := p.tmpVar() - return fmt.Sprintf(code, tmp, p.Name, tmp, tmp) + return fmt.Sprintf(code, p.tmpVar(), p.Name) +} + +// BoolPointerTmpVarCode returns source code for bool temp variable. +func (p *Param) BoolPointerTmpVarCode() string { + const code = `var %[1]s uint32 + if *%[2]s { + %[1]s = 1 + }` + return fmt.Sprintf(code, p.tmpVar(), p.Name) } // SliceTmpVarCode returns source code for slice temp variable. @@ -154,6 +163,8 @@ func (p *Param) TmpVarCode() string { switch { case p.Type == "bool": return p.BoolTmpVarCode() + case p.Type == "*bool": + return p.BoolPointerTmpVarCode() case strings.HasPrefix(p.Type, "[]"): return p.SliceTmpVarCode() default: @@ -161,6 +172,16 @@ func (p *Param) TmpVarCode() string { } } +// TmpVarReadbackCode returns source code for reading back the temp variable into the original variable. +func (p *Param) TmpVarReadbackCode() string { + switch { + case p.Type == "*bool": + return fmt.Sprintf("*%s = %s != 0", p.Name, p.tmpVar()) + default: + return "" + } +} + // TmpVarHelperCode returns source code for helper's temp variable. func (p *Param) TmpVarHelperCode() string { if p.Type != "string" { @@ -176,6 +197,8 @@ func (p *Param) SyscallArgList() []string { t := p.HelperType() var s string switch { + case t == "*bool": + s = fmt.Sprintf("unsafe.Pointer(&%s)", p.tmpVar()) case t[0] == '*': s = fmt.Sprintf("unsafe.Pointer(%s)", p.Name) case t == "bool": @@ -220,10 +243,11 @@ func join(ps []*Param, fn func(*Param) string, sep string) string { // Rets describes function return parameters. type Rets struct { - Name string - Type string - ReturnsError bool - FailCond string + Name string + Type string + ReturnsError bool + FailCond string + fnMaybeAbsent bool } // ErrorVarName returns error variable name for r. @@ -254,6 +278,8 @@ func (r *Rets) List() string { s := join(r.ToParams(), func(p *Param) string { return p.Name + " " + p.Type }, ", ") if len(s) > 0 { s = "(" + s + ")" + } else if r.fnMaybeAbsent { + s = "(err error)" } return s } @@ -282,17 +308,13 @@ func (r *Rets) SetReturnValuesCode() string { func (r *Rets) useLongHandleErrorCode(retvar string) string { const code = `if %s { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = %sEINVAL - } + err = errnoErr(e1) }` cond := retvar + " == 0" if r.FailCond != "" { cond = strings.Replace(r.FailCond, "failretval", retvar, 1) } - return fmt.Sprintf(code, cond, syscalldot()) + return fmt.Sprintf(code, cond) } // SetErrorCode returns source code that sets return parameters. @@ -457,6 +479,10 @@ func newFn(s string) (*Fn, error) { default: return nil, errors.New("Could not extract dll name from \"" + f.src + "\"") } + if n := f.dllfuncname; strings.HasSuffix(n, "?") { + f.dllfuncname = n[:len(n)-1] + f.Rets.fnMaybeAbsent = true + } return f, nil } @@ -468,7 +494,7 @@ func (f *Fn) DLLName() string { return f.dllname } -// DLLFuncName returns DLL function name for function f. +// DLLName returns DLL function name for function f. func (f *Fn) DLLFuncName() string { if f.dllfuncname == "" { return f.Name @@ -555,9 +581,25 @@ func (f *Fn) HelperCallParamList() string { return strings.Join(a, ", ") } +// MaybeAbsent returns source code for handling functions that are possibly unavailable. +func (p *Fn) MaybeAbsent() string { + if !p.Rets.fnMaybeAbsent { + return "" + } + const code = `%[1]s = proc%[2]s.Find() + if %[1]s != nil { + return + }` + errorVar := p.Rets.ErrorVarName() + if errorVar == "" { + errorVar = "err" + } + return fmt.Sprintf(code, errorVar, p.DLLFuncName()) +} + // IsUTF16 is true, if f is W (utf16) function. It is false // for all A (ascii) functions. -func (f *Fn) IsUTF16() bool { +func (_ *Fn) IsUTF16() bool { return true } @@ -615,7 +657,7 @@ func (src *Source) ExternalImport(pkg string) { } // ParseFiles parses files listed in fs and extracts all syscall -// functions listed in sys comments. It returns source files +// functions listed in sys comments. It returns source files // and functions collection *Source if successful. func ParseFiles(fs []string) (*Source, error) { src := &Source{ @@ -645,6 +687,7 @@ func (src *Source) DLLs() []string { r = append(r, name) } } + sort.Strings(r) return r } @@ -679,6 +722,13 @@ func (src *Source) ParseFile(path string) error { return err } src.Files = append(src.Files, path) + sort.Slice(src.Funcs, func(i, j int) bool { + fi, fj := src.Funcs[i], src.Funcs[j] + if fi.DLLName() == fj.DLLName() { + return fi.DLLFuncName() < fj.DLLFuncName() + } + return fi.DLLName() < fj.DLLName() + }) // get package name fset := token.NewFileSet() @@ -695,7 +745,7 @@ func (src *Source) ParseFile(path string) error { return nil } -// IsStdRepo returns true if src is part of standard library. +// IsStdRepo reports whether src is part of standard library. func (src *Source) IsStdRepo() (bool, error) { if len(src.Files) == 0 { return false, errors.New("no input files provided") @@ -816,7 +866,7 @@ func main() { // TODO: use println instead to print in the following template const srcTemplate = ` -{{define "main"}}// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT +{{define "main"}}// Code generated by 'go generate'; DO NOT EDIT. package {{packagename}} @@ -838,6 +888,7 @@ const ( var ( errERROR_IO_PENDING error = {{syscalldot}}Errno(errnoERROR_IO_PENDING) + errERROR_EINVAL error = {{syscalldot}}EINVAL ) // errnoErr returns common boxed Errno values, to prevent @@ -845,7 +896,7 @@ var ( func errnoErr(e {{syscalldot}}Errno) error { switch e { case 0: - return nil + return errERROR_EINVAL case errnoERROR_IO_PENDING: return errERROR_IO_PENDING } @@ -877,7 +928,7 @@ func {{.Name}}({{.ParamList}}) {{template "results" .}}{ {{define "funcbody"}} func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{ -{{template "tmpvars" .}} {{template "syscall" .}} +{{template "maybeabsent" .}} {{template "tmpvars" .}} {{template "syscall" .}} {{template "tmpvarsreadback" .}} {{template "seterror" .}}{{template "printtrace" .}} return } {{end}} @@ -885,6 +936,9 @@ func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{ {{define "helpertmpvars"}}{{range .Params}}{{if .TmpVarHelperCode}} {{.TmpVarHelperCode}} {{end}}{{end}}{{end}} +{{define "maybeabsent"}}{{if .MaybeAbsent}}{{.MaybeAbsent}} +{{end}}{{end}} + {{define "tmpvars"}}{{range .Params}}{{if .TmpVarCode}} {{.TmpVarCode}} {{end}}{{end}}{{end}} @@ -892,6 +946,9 @@ func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{ {{define "syscall"}}{{.Rets.SetReturnValuesCode}}{{.Syscall}}(proc{{.DLLFuncName}}.Addr(), {{.ParamCount}}, {{.SyscallParamList}}){{end}} +{{define "tmpvarsreadback"}}{{range .Params}}{{if .TmpVarReadbackCode}} +{{.TmpVarReadbackCode}}{{end}}{{end}}{{end}} + {{define "seterror"}}{{if .Rets.SetErrorCode}} {{.Rets.SetErrorCode}} {{end}}{{end}} diff --git a/vhd/vhd.go b/vhd/vhd.go index 382e526..b03b789 100644 --- a/vhd/vhd.go +++ b/vhd/vhd.go @@ -11,7 +11,7 @@ import ( "golang.org/x/sys/windows" ) -//go:generate go run mksyscall_windows.go -output zvhd.go vhd.go +//go:generate go run mksyscall_windows.go -output zvhd_windows.go vhd.go //sys createVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, createVirtualDiskFlags uint32, providerSpecificFlags uint32, parameters *CreateVirtualDiskParameters, overlapped *syscall.Overlapped, handle *syscall.Handle) (err error) [failretval != 0] = virtdisk.CreateVirtualDisk //sys openVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *OpenVirtualDiskParameters, handle *syscall.Handle) (err error) [failretval != 0] = virtdisk.OpenVirtualDisk diff --git a/vhd/zvhd.go b/vhd/zvhd_windows.go similarity index 90% rename from vhd/zvhd.go rename to vhd/zvhd_windows.go index d8b737a..572f7b4 100644 --- a/vhd/zvhd.go +++ b/vhd/zvhd_windows.go @@ -1,6 +1,4 @@ -// +build windows - -// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT +// Code generated by 'go generate'; DO NOT EDIT. package vhd @@ -21,6 +19,7 @@ const ( var ( errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) + errERROR_EINVAL error = syscall.EINVAL ) // errnoErr returns common boxed Errno values, to prevent @@ -28,7 +27,7 @@ var ( func errnoErr(e syscall.Errno) error { switch e { case 0: - return nil + return errERROR_EINVAL case errnoERROR_IO_PENDING: return errERROR_IO_PENDING } @@ -41,13 +40,21 @@ func errnoErr(e syscall.Errno) error { var ( modvirtdisk = windows.NewLazySystemDLL("virtdisk.dll") - procCreateVirtualDisk = modvirtdisk.NewProc("CreateVirtualDisk") - procOpenVirtualDisk = modvirtdisk.NewProc("OpenVirtualDisk") procAttachVirtualDisk = modvirtdisk.NewProc("AttachVirtualDisk") + procCreateVirtualDisk = modvirtdisk.NewProc("CreateVirtualDisk") procDetachVirtualDisk = modvirtdisk.NewProc("DetachVirtualDisk") procGetVirtualDiskPhysicalPath = modvirtdisk.NewProc("GetVirtualDiskPhysicalPath") + procOpenVirtualDisk = modvirtdisk.NewProc("OpenVirtualDisk") ) +func attachVirtualDisk(handle syscall.Handle, securityDescriptor *uintptr, attachVirtualDiskFlag uint32, providerSpecificFlags uint32, parameters *AttachVirtualDiskParameters, overlapped *syscall.Overlapped) (err error) { + r1, _, e1 := syscall.Syscall6(procAttachVirtualDisk.Addr(), 6, uintptr(handle), uintptr(unsafe.Pointer(securityDescriptor)), uintptr(attachVirtualDiskFlag), uintptr(providerSpecificFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(overlapped))) + if r1 != 0 { + err = errnoErr(e1) + } + return +} + func createVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, createVirtualDiskFlags uint32, providerSpecificFlags uint32, parameters *CreateVirtualDiskParameters, overlapped *syscall.Overlapped, handle *syscall.Handle) (err error) { var _p0 *uint16 _p0, err = syscall.UTF16PtrFromString(path) @@ -60,11 +67,23 @@ func createVirtualDisk(virtualStorageType *VirtualStorageType, path string, virt func _createVirtualDisk(virtualStorageType *VirtualStorageType, path *uint16, virtualDiskAccessMask uint32, securityDescriptor *uintptr, createVirtualDiskFlags uint32, providerSpecificFlags uint32, parameters *CreateVirtualDiskParameters, overlapped *syscall.Overlapped, handle *syscall.Handle) (err error) { r1, _, e1 := syscall.Syscall9(procCreateVirtualDisk.Addr(), 9, uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(unsafe.Pointer(securityDescriptor)), uintptr(createVirtualDiskFlags), uintptr(providerSpecificFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(handle))) if r1 != 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) + } + return +} + +func detachVirtualDisk(handle syscall.Handle, detachVirtualDiskFlags uint32, providerSpecificFlags uint32) (err error) { + r1, _, e1 := syscall.Syscall(procDetachVirtualDisk.Addr(), 3, uintptr(handle), uintptr(detachVirtualDiskFlags), uintptr(providerSpecificFlags)) + if r1 != 0 { + err = errnoErr(e1) + } + return +} + +func getVirtualDiskPhysicalPath(handle syscall.Handle, diskPathSizeInBytes *uint32, buffer *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procGetVirtualDiskPhysicalPath.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(diskPathSizeInBytes)), uintptr(unsafe.Pointer(buffer))) + if r1 != 0 { + err = errnoErr(e1) } return } @@ -81,47 +100,7 @@ func openVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtua func _openVirtualDisk(virtualStorageType *VirtualStorageType, path *uint16, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *OpenVirtualDiskParameters, handle *syscall.Handle) (err error) { r1, _, e1 := syscall.Syscall6(procOpenVirtualDisk.Addr(), 6, uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(openVirtualDiskFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(handle))) if r1 != 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func attachVirtualDisk(handle syscall.Handle, securityDescriptor *uintptr, attachVirtualDiskFlag uint32, providerSpecificFlags uint32, parameters *AttachVirtualDiskParameters, overlapped *syscall.Overlapped) (err error) { - r1, _, e1 := syscall.Syscall6(procAttachVirtualDisk.Addr(), 6, uintptr(handle), uintptr(unsafe.Pointer(securityDescriptor)), uintptr(attachVirtualDiskFlag), uintptr(providerSpecificFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(overlapped))) - if r1 != 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func detachVirtualDisk(handle syscall.Handle, detachVirtualDiskFlags uint32, providerSpecificFlags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procDetachVirtualDisk.Addr(), 3, uintptr(handle), uintptr(detachVirtualDiskFlags), uintptr(providerSpecificFlags)) - if r1 != 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func getVirtualDiskPhysicalPath(handle syscall.Handle, diskPathSizeInBytes *uint32, buffer *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procGetVirtualDiskPhysicalPath.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(diskPathSizeInBytes)), uintptr(unsafe.Pointer(buffer))) - if r1 != 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } diff --git a/zsyscall_windows.go b/zsyscall_windows.go index e26b01f..176ff75 100644 --- a/zsyscall_windows.go +++ b/zsyscall_windows.go @@ -19,6 +19,7 @@ const ( var ( errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) + errERROR_EINVAL error = syscall.EINVAL ) // errnoErr returns common boxed Errno values, to prevent @@ -26,7 +27,7 @@ var ( func errnoErr(e syscall.Errno) error { switch e { case 0: - return nil + return errERROR_EINVAL case errnoERROR_IO_PENDING: return errERROR_IO_PENDING } @@ -37,243 +38,62 @@ func errnoErr(e syscall.Errno) error { } var ( - modkernel32 = windows.NewLazySystemDLL("kernel32.dll") - modws2_32 = windows.NewLazySystemDLL("ws2_32.dll") - modntdll = windows.NewLazySystemDLL("ntdll.dll") modadvapi32 = windows.NewLazySystemDLL("advapi32.dll") + modkernel32 = windows.NewLazySystemDLL("kernel32.dll") + modntdll = windows.NewLazySystemDLL("ntdll.dll") + modws2_32 = windows.NewLazySystemDLL("ws2_32.dll") - procCancelIoEx = modkernel32.NewProc("CancelIoEx") - procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort") - procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus") - procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes") - procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult") - procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe") - procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW") - procCreateFileW = modkernel32.NewProc("CreateFileW") - procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo") - procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW") - procLocalAlloc = modkernel32.NewProc("LocalAlloc") - procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile") - procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb") - procRtlDosPathNameToNtPathName_U = modntdll.NewProc("RtlDosPathNameToNtPathName_U") - procRtlDefaultNpAcl = modntdll.NewProc("RtlDefaultNpAcl") - procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW") + procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges") + procConvertSecurityDescriptorToStringSecurityDescriptorW = modadvapi32.NewProc("ConvertSecurityDescriptorToStringSecurityDescriptorW") procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW") procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW") - procConvertSecurityDescriptorToStringSecurityDescriptorW = modadvapi32.NewProc("ConvertSecurityDescriptorToStringSecurityDescriptorW") - procLocalFree = modkernel32.NewProc("LocalFree") procGetSecurityDescriptorLength = modadvapi32.NewProc("GetSecurityDescriptorLength") - procGetFileInformationByHandleEx = modkernel32.NewProc("GetFileInformationByHandleEx") - procSetFileInformationByHandle = modkernel32.NewProc("SetFileInformationByHandle") - procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges") procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf") - procRevertToSelf = modadvapi32.NewProc("RevertToSelf") - procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken") - procGetCurrentThread = modkernel32.NewProc("GetCurrentThread") - procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW") - procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW") + procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW") procLookupPrivilegeDisplayNameW = modadvapi32.NewProc("LookupPrivilegeDisplayNameW") + procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW") + procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW") + procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken") + procRevertToSelf = modadvapi32.NewProc("RevertToSelf") procBackupRead = modkernel32.NewProc("BackupRead") procBackupWrite = modkernel32.NewProc("BackupWrite") + procCancelIoEx = modkernel32.NewProc("CancelIoEx") + procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe") + procCreateFileW = modkernel32.NewProc("CreateFileW") + procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort") + procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW") + procGetCurrentThread = modkernel32.NewProc("GetCurrentThread") + procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW") + procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo") + procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus") + procLocalAlloc = modkernel32.NewProc("LocalAlloc") + procLocalFree = modkernel32.NewProc("LocalFree") + procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes") + procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile") + procRtlDefaultNpAcl = modntdll.NewProc("RtlDefaultNpAcl") + procRtlDosPathNameToNtPathName_U = modntdll.NewProc("RtlDosPathNameToNtPathName_U") + procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb") + procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult") procbind = modws2_32.NewProc("bind") ) -func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) { - r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount), 0, 0) - newport = syscall.Handle(r0) - if newport == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) { - r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) { +func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) { var _p0 uint32 - if wait { + if releaseAll { _p0 = 1 - } else { - _p0 = 0 } - r1, _, e1 := syscall.Syscall6(procWSAGetOverlappedResult.Addr(), 5, uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags)), 0) + r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize))) + success = r0 != 0 + if true { + err = errnoErr(e1) + } + return +} + +func convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(secInfo), uintptr(unsafe.Pointer(sddl)), uintptr(unsafe.Pointer(sddlSize)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) { - r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(name) - if err != nil { - return - } - return _createNamedPipe(_p0, flags, pipeMode, maxInstances, outSize, inSize, defaultTimeout, sa) -} - -func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) { - r0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0) - handle = syscall.Handle(r0) - if handle == syscall.InvalidHandle { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func createFile(name string, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(name) - if err != nil { - return - } - return _createFile(_p0, access, mode, sa, createmode, attrs, templatefile) -} - -func _createFile(name *uint16, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) { - r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0) - handle = syscall.Handle(r0) - if handle == syscall.InvalidHandle { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func localAlloc(uFlags uint32, length uint32) (ptr uintptr) { - r0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(uFlags), uintptr(length), 0) - ptr = uintptr(r0) - return -} - -func ntCreateNamedPipeFile(pipe *syscall.Handle, access uint32, oa *objectAttributes, iosb *ioStatusBlock, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntstatus) { - r0, _, _ := syscall.Syscall15(procNtCreateNamedPipeFile.Addr(), 14, uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout)), 0) - status = ntstatus(r0) - return -} - -func rtlNtStatusToDosError(status ntstatus) (winerr error) { - r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(status), 0, 0) - if r0 != 0 { - winerr = syscall.Errno(r0) - } - return -} - -func rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntstatus) { - r0, _, _ := syscall.Syscall6(procRtlDosPathNameToNtPathName_U.Addr(), 4, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(ntName)), uintptr(filePart), uintptr(reserved), 0, 0) - status = ntstatus(r0) - return -} - -func rtlDefaultNpAcl(dacl *uintptr) (status ntstatus) { - r0, _, _ := syscall.Syscall(procRtlDefaultNpAcl.Addr(), 1, uintptr(unsafe.Pointer(dacl)), 0, 0) - status = ntstatus(r0) - return -} - -func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(accountName) - if err != nil { - return - } - return _lookupAccountName(systemName, _p0, sid, sidSize, refDomain, refDomainSize, sidNameUse) -} - -func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -281,11 +101,7 @@ func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidS func convertSidToStringSid(sid *byte, str **uint16) (err error) { r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -302,126 +118,73 @@ func convertStringSecurityDescriptorToSecurityDescriptor(str string, revision ui func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision uint32, sd *uintptr, size *uint32) (err error) { r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(secInfo), uintptr(unsafe.Pointer(sddl)), uintptr(unsafe.Pointer(sddlSize)), 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func localFree(mem uintptr) { - syscall.Syscall(procLocalFree.Addr(), 1, uintptr(mem), 0, 0) - return -} - func getSecurityDescriptorLength(sd uintptr) (len uint32) { r0, _, _ := syscall.Syscall(procGetSecurityDescriptorLength.Addr(), 1, uintptr(sd), 0, 0) len = uint32(r0) return } -func getFileInformationByHandleEx(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetFileInformationByHandle.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) { - var _p0 uint32 - if releaseAll { - _p0 = 1 - } else { - _p0 = 0 - } - r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize))) - success = r0 != 0 - if true { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - func impersonateSelf(level uint32) (err error) { r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(level), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func revertToSelf() (err error) { - r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0) +func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(accountName) + if err != nil { + return + } + return _lookupAccountName(systemName, _p0, sid, sidSize, refDomain, refDomainSize, sidNameUse) +} + +func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) { + r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) { - var _p0 uint32 - if openAsSelf { - _p0 = 1 - } else { - _p0 = 0 +func lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(systemName) + if err != nil { + return } - r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0) + return _lookupPrivilegeDisplayName(_p0, name, buffer, size, languageId) +} + +func _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procLookupPrivilegeDisplayNameW.Addr(), 5, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func getCurrentThread() (h syscall.Handle) { - r0, _, _ := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0) - h = syscall.Handle(r0) +func lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(systemName) + if err != nil { + return + } + return _lookupPrivilegeName(_p0, luid, buffer, size) +} + +func _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } return } @@ -442,53 +205,27 @@ func lookupPrivilegeValue(systemName string, name string, luid *uint64) (err err func _lookupPrivilegeValue(systemName *uint16, name *uint16, luid *uint64) (err error) { r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid))) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(systemName) - if err != nil { - return +func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) { + var _p0 uint32 + if openAsSelf { + _p0 = 1 } - return _lookupPrivilegeName(_p0, luid, buffer, size) -} - -func _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0) + r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(systemName) - if err != nil { - return - } - return _lookupPrivilegeDisplayName(_p0, name, buffer, size, languageId) -} - -func _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procLookupPrivilegeDisplayNameW.Addr(), 5, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId)), 0) +func revertToSelf() (err error) { + r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -501,22 +238,14 @@ func backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, proce var _p1 uint32 if abort { _p1 = 1 - } else { - _p1 = 0 } var _p2 uint32 if processSecurity { _p2 = 1 - } else { - _p2 = 0 } r1, _, e1 := syscall.Syscall9(procBackupRead.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesRead)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } @@ -529,22 +258,162 @@ func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, p var _p1 uint32 if abort { _p1 = 1 - } else { - _p1 = 0 } var _p2 uint32 if processSecurity { _p2 = 1 - } else { - _p2 = 0 } r1, _, e1 := syscall.Syscall9(procBackupWrite.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesWritten)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) + } + return +} + +func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) { + r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) { + r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func createFile(name string, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(name) + if err != nil { + return + } + return _createFile(_p0, access, mode, sa, createmode, attrs, templatefile) +} + +func _createFile(name *uint16, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) { + r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0) + handle = syscall.Handle(r0) + if handle == syscall.InvalidHandle { + err = errnoErr(e1) + } + return +} + +func createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) { + r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount), 0, 0) + newport = syscall.Handle(r0) + if newport == 0 { + err = errnoErr(e1) + } + return +} + +func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(name) + if err != nil { + return + } + return _createNamedPipe(_p0, flags, pipeMode, maxInstances, outSize, inSize, defaultTimeout, sa) +} + +func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) { + r0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0) + handle = syscall.Handle(r0) + if handle == syscall.InvalidHandle { + err = errnoErr(e1) + } + return +} + +func getCurrentThread() (h syscall.Handle) { + r0, _, _ := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0) + h = syscall.Handle(r0) + return +} + +func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) { + r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func localAlloc(uFlags uint32, length uint32) (ptr uintptr) { + r0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(uFlags), uintptr(length), 0) + ptr = uintptr(r0) + return +} + +func localFree(mem uintptr) { + syscall.Syscall(procLocalFree.Addr(), 1, uintptr(mem), 0, 0) + return +} + +func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) { + r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func ntCreateNamedPipeFile(pipe *syscall.Handle, access uint32, oa *objectAttributes, iosb *ioStatusBlock, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntstatus) { + r0, _, _ := syscall.Syscall15(procNtCreateNamedPipeFile.Addr(), 14, uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout)), 0) + status = ntstatus(r0) + return +} + +func rtlDefaultNpAcl(dacl *uintptr) (status ntstatus) { + r0, _, _ := syscall.Syscall(procRtlDefaultNpAcl.Addr(), 1, uintptr(unsafe.Pointer(dacl)), 0, 0) + status = ntstatus(r0) + return +} + +func rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntstatus) { + r0, _, _ := syscall.Syscall6(procRtlDosPathNameToNtPathName_U.Addr(), 4, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(ntName)), uintptr(filePart), uintptr(reserved), 0, 0) + status = ntstatus(r0) + return +} + +func rtlNtStatusToDosError(status ntstatus) (winerr error) { + r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(status), 0, 0) + if r0 != 0 { + winerr = syscall.Errno(r0) + } + return +} + +func wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) { + var _p0 uint32 + if wait { + _p0 = 1 + } + r1, _, e1 := syscall.Syscall6(procWSAGetOverlappedResult.Addr(), 5, uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags)), 0) + if r1 == 0 { + err = errnoErr(e1) } return } @@ -552,11 +421,7 @@ func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, p func bind(s syscall.Handle, name unsafe.Pointer, namelen int32) (err error) { r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen)) if r1 == socketError { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return }