build: upgrade dependencies and build with go 1.21
This commit is contained in:
		
							
								
								
									
										1
									
								
								vendor/github.com/Microsoft/go-winio/.gitattributes
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/Microsoft/go-winio/.gitattributes
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
* text=auto eol=lf
 | 
			
		||||
							
								
								
									
										9
									
								
								vendor/github.com/Microsoft/go-winio/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/Microsoft/go-winio/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1 +1,10 @@
 | 
			
		||||
.vscode/
 | 
			
		||||
 | 
			
		||||
*.exe
 | 
			
		||||
 | 
			
		||||
# testing
 | 
			
		||||
testdata
 | 
			
		||||
 | 
			
		||||
# go workspaces
 | 
			
		||||
go.work
 | 
			
		||||
go.work.sum
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										149
									
								
								vendor/github.com/Microsoft/go-winio/.golangci.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								vendor/github.com/Microsoft/go-winio/.golangci.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,149 @@
 | 
			
		||||
run:
 | 
			
		||||
  skip-dirs:
 | 
			
		||||
    - pkg/etw/sample
 | 
			
		||||
 | 
			
		||||
linters:
 | 
			
		||||
  enable:
 | 
			
		||||
    # style
 | 
			
		||||
    - containedctx # struct contains a context
 | 
			
		||||
    - dupl # duplicate code
 | 
			
		||||
    - errname # erorrs are named correctly
 | 
			
		||||
    - nolintlint # "//nolint" directives are properly explained
 | 
			
		||||
    - revive # golint replacement
 | 
			
		||||
    - unconvert # unnecessary conversions
 | 
			
		||||
    - wastedassign
 | 
			
		||||
 | 
			
		||||
    # bugs, performance, unused, etc ...
 | 
			
		||||
    - contextcheck # function uses a non-inherited context
 | 
			
		||||
    - errorlint # errors not wrapped for 1.13
 | 
			
		||||
    - exhaustive # check exhaustiveness of enum switch statements
 | 
			
		||||
    - gofmt # files are gofmt'ed
 | 
			
		||||
    - gosec # security
 | 
			
		||||
    - nilerr # returns nil even with non-nil error
 | 
			
		||||
    - unparam # unused function params
 | 
			
		||||
 | 
			
		||||
issues:
 | 
			
		||||
  exclude-rules:
 | 
			
		||||
    # err is very often shadowed in nested scopes
 | 
			
		||||
    - linters:
 | 
			
		||||
        - govet
 | 
			
		||||
      text: '^shadow: declaration of "err" shadows declaration'
 | 
			
		||||
 | 
			
		||||
    # ignore long lines for skip autogen directives
 | 
			
		||||
    - linters:
 | 
			
		||||
        - revive
 | 
			
		||||
      text: "^line-length-limit: "
 | 
			
		||||
      source: "^//(go:generate|sys) "
 | 
			
		||||
 | 
			
		||||
    #TODO: remove after upgrading to go1.18
 | 
			
		||||
    # ignore comment spacing for nolint and sys directives
 | 
			
		||||
    - linters:
 | 
			
		||||
        - revive
 | 
			
		||||
      text: "^comment-spacings: no space between comment delimiter and comment text"
 | 
			
		||||
      source: "//(cspell:|nolint:|sys |todo)"
 | 
			
		||||
 | 
			
		||||
    # not on go 1.18 yet, so no any
 | 
			
		||||
    - linters:
 | 
			
		||||
        - revive
 | 
			
		||||
      text: "^use-any: since GO 1.18 'interface{}' can be replaced by 'any'"
 | 
			
		||||
 | 
			
		||||
    # allow unjustified ignores of error checks in defer statements
 | 
			
		||||
    - linters:
 | 
			
		||||
        - nolintlint
 | 
			
		||||
      text: "^directive `//nolint:errcheck` should provide explanation"
 | 
			
		||||
      source: '^\s*defer '
 | 
			
		||||
 | 
			
		||||
    # allow unjustified ignores of error lints for io.EOF
 | 
			
		||||
    - linters:
 | 
			
		||||
        - nolintlint
 | 
			
		||||
      text: "^directive `//nolint:errorlint` should provide explanation"
 | 
			
		||||
      source: '[=|!]= io.EOF'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
linters-settings:
 | 
			
		||||
  exhaustive:
 | 
			
		||||
    default-signifies-exhaustive: true
 | 
			
		||||
  govet:
 | 
			
		||||
    enable-all: true
 | 
			
		||||
    disable:
 | 
			
		||||
      # struct order is often for Win32 compat
 | 
			
		||||
      # also, ignore pointer bytes/GC issues for now until performance becomes an issue
 | 
			
		||||
      - fieldalignment
 | 
			
		||||
    check-shadowing: true
 | 
			
		||||
  nolintlint:
 | 
			
		||||
    allow-leading-space: false
 | 
			
		||||
    require-explanation: true
 | 
			
		||||
    require-specific: true
 | 
			
		||||
  revive:
 | 
			
		||||
    # revive is more configurable than static check, so likely the preferred alternative to static-check
 | 
			
		||||
    # (once the perf issue is solved: https://github.com/golangci/golangci-lint/issues/2997)
 | 
			
		||||
    enable-all-rules:
 | 
			
		||||
      true
 | 
			
		||||
      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md
 | 
			
		||||
    rules:
 | 
			
		||||
      # rules with required arguments
 | 
			
		||||
      - name: argument-limit
 | 
			
		||||
        disabled: true
 | 
			
		||||
      - name: banned-characters
 | 
			
		||||
        disabled: true
 | 
			
		||||
      - name: cognitive-complexity
 | 
			
		||||
        disabled: true
 | 
			
		||||
      - name: cyclomatic
 | 
			
		||||
        disabled: true
 | 
			
		||||
      - name: file-header
 | 
			
		||||
        disabled: true
 | 
			
		||||
      - name: function-length
 | 
			
		||||
        disabled: true
 | 
			
		||||
      - name: function-result-limit
 | 
			
		||||
        disabled: true
 | 
			
		||||
      - name: max-public-structs
 | 
			
		||||
        disabled: true
 | 
			
		||||
      # geneally annoying rules
 | 
			
		||||
      - name: add-constant # complains about any and all strings and integers
 | 
			
		||||
        disabled: true
 | 
			
		||||
      - name: confusing-naming # we frequently use "Foo()" and "foo()" together
 | 
			
		||||
        disabled: true
 | 
			
		||||
      - name: flag-parameter # excessive, and a common idiom we use
 | 
			
		||||
        disabled: true
 | 
			
		||||
      - name: unhandled-error # warns over common fmt.Print* and io.Close; rely on errcheck instead
 | 
			
		||||
        disabled: true
 | 
			
		||||
      # general config
 | 
			
		||||
      - name: line-length-limit
 | 
			
		||||
        arguments:
 | 
			
		||||
          - 140
 | 
			
		||||
      - name: var-naming
 | 
			
		||||
        arguments:
 | 
			
		||||
          - []
 | 
			
		||||
          - - CID
 | 
			
		||||
            - CRI
 | 
			
		||||
            - CTRD
 | 
			
		||||
            - DACL
 | 
			
		||||
            - DLL
 | 
			
		||||
            - DOS
 | 
			
		||||
            - ETW
 | 
			
		||||
            - FSCTL
 | 
			
		||||
            - GCS
 | 
			
		||||
            - GMSA
 | 
			
		||||
            - HCS
 | 
			
		||||
            - HV
 | 
			
		||||
            - IO
 | 
			
		||||
            - LCOW
 | 
			
		||||
            - LDAP
 | 
			
		||||
            - LPAC
 | 
			
		||||
            - LTSC
 | 
			
		||||
            - MMIO
 | 
			
		||||
            - NT
 | 
			
		||||
            - OCI
 | 
			
		||||
            - PMEM
 | 
			
		||||
            - PWSH
 | 
			
		||||
            - RX
 | 
			
		||||
            - SACl
 | 
			
		||||
            - SID
 | 
			
		||||
            - SMB
 | 
			
		||||
            - TX
 | 
			
		||||
            - VHD
 | 
			
		||||
            - VHDX
 | 
			
		||||
            - VMID
 | 
			
		||||
            - VPCI
 | 
			
		||||
            - WCOW
 | 
			
		||||
            - WIM
 | 
			
		||||
							
								
								
									
										1
									
								
								vendor/github.com/Microsoft/go-winio/CODEOWNERS
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/Microsoft/go-winio/CODEOWNERS
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
  * @microsoft/containerplat
 | 
			
		||||
							
								
								
									
										85
									
								
								vendor/github.com/Microsoft/go-winio/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										85
									
								
								vendor/github.com/Microsoft/go-winio/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
# go-winio
 | 
			
		||||
# go-winio [](https://github.com/microsoft/go-winio/actions/workflows/ci.yml)
 | 
			
		||||
 | 
			
		||||
This repository contains utilities for efficiently performing Win32 IO operations in
 | 
			
		||||
Go. Currently, this is focused on accessing named pipes and other file handles, and
 | 
			
		||||
@@ -11,12 +11,79 @@ package.
 | 
			
		||||
 | 
			
		||||
Please see the LICENSE file for licensing information.
 | 
			
		||||
 | 
			
		||||
This project has adopted the [Microsoft Open Source Code of
 | 
			
		||||
Conduct](https://opensource.microsoft.com/codeofconduct/). For more information
 | 
			
		||||
see the [Code of Conduct
 | 
			
		||||
FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact
 | 
			
		||||
[opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional
 | 
			
		||||
questions or comments.
 | 
			
		||||
## Contributing
 | 
			
		||||
 | 
			
		||||
Thanks to natefinch for the inspiration for this library. See https://github.com/natefinch/npipe
 | 
			
		||||
for another named pipe implementation.
 | 
			
		||||
This project welcomes contributions and suggestions.
 | 
			
		||||
Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that
 | 
			
		||||
you have the right to, and actually do, grant us the rights to use your contribution.
 | 
			
		||||
For details, visit [Microsoft CLA](https://cla.microsoft.com).
 | 
			
		||||
 | 
			
		||||
When you submit a pull request, a CLA-bot will automatically determine whether you need to
 | 
			
		||||
provide a CLA and decorate the PR appropriately (e.g., label, comment).
 | 
			
		||||
Simply follow the instructions provided by the bot.
 | 
			
		||||
You will only need to do this once across all repos using our CLA.
 | 
			
		||||
 | 
			
		||||
Additionally, the pull request pipeline requires the following steps to be performed before
 | 
			
		||||
mergining.
 | 
			
		||||
 | 
			
		||||
### Code Sign-Off
 | 
			
		||||
 | 
			
		||||
We require that contributors sign their commits using [`git commit --signoff`][git-commit-s]
 | 
			
		||||
to certify they either authored the work themselves or otherwise have permission to use it in this project.
 | 
			
		||||
 | 
			
		||||
A range of commits can be signed off using [`git rebase --signoff`][git-rebase-s].
 | 
			
		||||
 | 
			
		||||
Please see [the developer certificate](https://developercertificate.org) for more info,
 | 
			
		||||
as well as to make sure that you can attest to the rules listed.
 | 
			
		||||
Our CI uses the DCO Github app to ensure that all commits in a given PR are signed-off.
 | 
			
		||||
 | 
			
		||||
### Linting
 | 
			
		||||
 | 
			
		||||
Code must pass a linting stage, which uses [`golangci-lint`][lint].
 | 
			
		||||
The linting settings are stored in [`.golangci.yaml`](./.golangci.yaml), and can be run
 | 
			
		||||
automatically with VSCode by adding the following to your workspace or folder settings:
 | 
			
		||||
 | 
			
		||||
```json
 | 
			
		||||
    "go.lintTool": "golangci-lint",
 | 
			
		||||
    "go.lintOnSave": "package",
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Additional editor [integrations options are also available][lint-ide].
 | 
			
		||||
 | 
			
		||||
Alternatively, `golangci-lint` can be [installed locally][lint-install] and run from the repo root:
 | 
			
		||||
 | 
			
		||||
```shell
 | 
			
		||||
# use . or specify a path to only lint a package
 | 
			
		||||
# to show all lint errors, use flags "--max-issues-per-linter=0 --max-same-issues=0"
 | 
			
		||||
> golangci-lint run ./...
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Go Generate
 | 
			
		||||
 | 
			
		||||
The pipeline checks that auto-generated code, via `go generate`, are up to date.
 | 
			
		||||
 | 
			
		||||
This can be done for the entire repo:
 | 
			
		||||
 | 
			
		||||
```shell
 | 
			
		||||
> go generate ./...
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Code of Conduct
 | 
			
		||||
 | 
			
		||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
 | 
			
		||||
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
 | 
			
		||||
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
 | 
			
		||||
 | 
			
		||||
## Special Thanks
 | 
			
		||||
 | 
			
		||||
Thanks to [natefinch][natefinch] for the inspiration for this library.
 | 
			
		||||
See [npipe](https://github.com/natefinch/npipe) for another named pipe implementation.
 | 
			
		||||
 | 
			
		||||
[lint]: https://golangci-lint.run/
 | 
			
		||||
[lint-ide]: https://golangci-lint.run/usage/integrations/#editor-integration
 | 
			
		||||
[lint-install]: https://golangci-lint.run/usage/install/#local-installation
 | 
			
		||||
 | 
			
		||||
[git-commit-s]: https://git-scm.com/docs/git-commit#Documentation/git-commit.txt--s
 | 
			
		||||
[git-rebase-s]: https://git-scm.com/docs/git-rebase#Documentation/git-rebase.txt---signoff
 | 
			
		||||
 | 
			
		||||
[natefinch]: https://github.com/natefinch
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										41
									
								
								vendor/github.com/Microsoft/go-winio/SECURITY.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								vendor/github.com/Microsoft/go-winio/SECURITY.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.7 BLOCK -->
 | 
			
		||||
 | 
			
		||||
## Security
 | 
			
		||||
 | 
			
		||||
Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
 | 
			
		||||
 | 
			
		||||
If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.
 | 
			
		||||
 | 
			
		||||
## Reporting Security Issues
 | 
			
		||||
 | 
			
		||||
**Please do not report security vulnerabilities through public GitHub issues.**
 | 
			
		||||
 | 
			
		||||
Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).
 | 
			
		||||
 | 
			
		||||
If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com).  If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
 | 
			
		||||
 | 
			
		||||
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 
 | 
			
		||||
 | 
			
		||||
Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
 | 
			
		||||
 | 
			
		||||
  * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
 | 
			
		||||
  * Full paths of source file(s) related to the manifestation of the issue
 | 
			
		||||
  * The location of the affected source code (tag/branch/commit or direct URL)
 | 
			
		||||
  * Any special configuration required to reproduce the issue
 | 
			
		||||
  * Step-by-step instructions to reproduce the issue
 | 
			
		||||
  * Proof-of-concept or exploit code (if possible)
 | 
			
		||||
  * Impact of the issue, including how an attacker might exploit the issue
 | 
			
		||||
 | 
			
		||||
This information will help us triage your report more quickly.
 | 
			
		||||
 | 
			
		||||
If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.
 | 
			
		||||
 | 
			
		||||
## Preferred Languages
 | 
			
		||||
 | 
			
		||||
We prefer all communications to be in English.
 | 
			
		||||
 | 
			
		||||
## Policy
 | 
			
		||||
 | 
			
		||||
Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).
 | 
			
		||||
 | 
			
		||||
<!-- END MICROSOFT SECURITY.MD BLOCK -->
 | 
			
		||||
							
								
								
									
										48
									
								
								vendor/github.com/Microsoft/go-winio/backup.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										48
									
								
								vendor/github.com/Microsoft/go-winio/backup.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,3 +1,4 @@
 | 
			
		||||
//go:build windows
 | 
			
		||||
// +build windows
 | 
			
		||||
 | 
			
		||||
package winio
 | 
			
		||||
@@ -7,11 +8,12 @@ import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"syscall"
 | 
			
		||||
	"unicode/utf16"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/sys/windows"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//sys backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupRead
 | 
			
		||||
@@ -24,7 +26,7 @@ const (
 | 
			
		||||
	BackupAlternateData
 | 
			
		||||
	BackupLink
 | 
			
		||||
	BackupPropertyData
 | 
			
		||||
	BackupObjectId
 | 
			
		||||
	BackupObjectId //revive:disable-line:var-naming ID, not Id
 | 
			
		||||
	BackupReparseData
 | 
			
		||||
	BackupSparseBlock
 | 
			
		||||
	BackupTxfsData
 | 
			
		||||
@@ -34,14 +36,16 @@ const (
 | 
			
		||||
	StreamSparseAttributes = uint32(8)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//nolint:revive // var-naming: ALL_CAPS
 | 
			
		||||
const (
 | 
			
		||||
	WRITE_DAC              = 0x40000
 | 
			
		||||
	WRITE_OWNER            = 0x80000
 | 
			
		||||
	ACCESS_SYSTEM_SECURITY = 0x1000000
 | 
			
		||||
	WRITE_DAC              = windows.WRITE_DAC
 | 
			
		||||
	WRITE_OWNER            = windows.WRITE_OWNER
 | 
			
		||||
	ACCESS_SYSTEM_SECURITY = windows.ACCESS_SYSTEM_SECURITY
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// BackupHeader represents a backup stream of a file.
 | 
			
		||||
type BackupHeader struct {
 | 
			
		||||
	//revive:disable-next-line:var-naming ID, not Id
 | 
			
		||||
	Id         uint32 // The backup stream ID
 | 
			
		||||
	Attributes uint32 // Stream attributes
 | 
			
		||||
	Size       int64  // The size of the stream in bytes
 | 
			
		||||
@@ -49,8 +53,8 @@ type BackupHeader struct {
 | 
			
		||||
	Offset     int64  // The offset of the stream in the file (for BackupSparseBlock only).
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type win32StreamId struct {
 | 
			
		||||
	StreamId   uint32
 | 
			
		||||
type win32StreamID struct {
 | 
			
		||||
	StreamID   uint32
 | 
			
		||||
	Attributes uint32
 | 
			
		||||
	Size       uint64
 | 
			
		||||
	NameSize   uint32
 | 
			
		||||
@@ -71,7 +75,7 @@ func NewBackupStreamReader(r io.Reader) *BackupStreamReader {
 | 
			
		||||
// Next returns the next backup stream and prepares for calls to Read(). It skips the remainder of the current stream if
 | 
			
		||||
// it was not completely read.
 | 
			
		||||
func (r *BackupStreamReader) Next() (*BackupHeader, error) {
 | 
			
		||||
	if r.bytesLeft > 0 {
 | 
			
		||||
	if r.bytesLeft > 0 { //nolint:nestif // todo: flatten this
 | 
			
		||||
		if s, ok := r.r.(io.Seeker); ok {
 | 
			
		||||
			// Make sure Seek on io.SeekCurrent sometimes succeeds
 | 
			
		||||
			// before trying the actual seek.
 | 
			
		||||
@@ -82,16 +86,16 @@ func (r *BackupStreamReader) Next() (*BackupHeader, error) {
 | 
			
		||||
				r.bytesLeft = 0
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if _, err := io.Copy(ioutil.Discard, r); err != nil {
 | 
			
		||||
		if _, err := io.Copy(io.Discard, r); err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	var wsi win32StreamId
 | 
			
		||||
	var wsi win32StreamID
 | 
			
		||||
	if err := binary.Read(r.r, binary.LittleEndian, &wsi); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	hdr := &BackupHeader{
 | 
			
		||||
		Id:         wsi.StreamId,
 | 
			
		||||
		Id:         wsi.StreamID,
 | 
			
		||||
		Attributes: wsi.Attributes,
 | 
			
		||||
		Size:       int64(wsi.Size),
 | 
			
		||||
	}
 | 
			
		||||
@@ -102,7 +106,7 @@ func (r *BackupStreamReader) Next() (*BackupHeader, error) {
 | 
			
		||||
		}
 | 
			
		||||
		hdr.Name = syscall.UTF16ToString(name)
 | 
			
		||||
	}
 | 
			
		||||
	if wsi.StreamId == BackupSparseBlock {
 | 
			
		||||
	if wsi.StreamID == BackupSparseBlock {
 | 
			
		||||
		if err := binary.Read(r.r, binary.LittleEndian, &hdr.Offset); err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
@@ -147,8 +151,8 @@ func (w *BackupStreamWriter) WriteHeader(hdr *BackupHeader) error {
 | 
			
		||||
		return fmt.Errorf("missing %d bytes", w.bytesLeft)
 | 
			
		||||
	}
 | 
			
		||||
	name := utf16.Encode([]rune(hdr.Name))
 | 
			
		||||
	wsi := win32StreamId{
 | 
			
		||||
		StreamId:   hdr.Id,
 | 
			
		||||
	wsi := win32StreamID{
 | 
			
		||||
		StreamID:   hdr.Id,
 | 
			
		||||
		Attributes: hdr.Attributes,
 | 
			
		||||
		Size:       uint64(hdr.Size),
 | 
			
		||||
		NameSize:   uint32(len(name) * 2),
 | 
			
		||||
@@ -203,7 +207,7 @@ func (r *BackupFileReader) Read(b []byte) (int, error) {
 | 
			
		||||
	var bytesRead uint32
 | 
			
		||||
	err := backupRead(syscall.Handle(r.f.Fd()), b, &bytesRead, false, r.includeSecurity, &r.ctx)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, &os.PathError{"BackupRead", r.f.Name(), err}
 | 
			
		||||
		return 0, &os.PathError{Op: "BackupRead", Path: r.f.Name(), Err: err}
 | 
			
		||||
	}
 | 
			
		||||
	runtime.KeepAlive(r.f)
 | 
			
		||||
	if bytesRead == 0 {
 | 
			
		||||
@@ -216,7 +220,7 @@ func (r *BackupFileReader) Read(b []byte) (int, error) {
 | 
			
		||||
// the underlying file.
 | 
			
		||||
func (r *BackupFileReader) Close() error {
 | 
			
		||||
	if r.ctx != 0 {
 | 
			
		||||
		backupRead(syscall.Handle(r.f.Fd()), nil, nil, true, false, &r.ctx)
 | 
			
		||||
		_ = backupRead(syscall.Handle(r.f.Fd()), nil, nil, true, false, &r.ctx)
 | 
			
		||||
		runtime.KeepAlive(r.f)
 | 
			
		||||
		r.ctx = 0
 | 
			
		||||
	}
 | 
			
		||||
@@ -242,7 +246,7 @@ func (w *BackupFileWriter) Write(b []byte) (int, error) {
 | 
			
		||||
	var bytesWritten uint32
 | 
			
		||||
	err := backupWrite(syscall.Handle(w.f.Fd()), b, &bytesWritten, false, w.includeSecurity, &w.ctx)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, &os.PathError{"BackupWrite", w.f.Name(), err}
 | 
			
		||||
		return 0, &os.PathError{Op: "BackupWrite", Path: w.f.Name(), Err: err}
 | 
			
		||||
	}
 | 
			
		||||
	runtime.KeepAlive(w.f)
 | 
			
		||||
	if int(bytesWritten) != len(b) {
 | 
			
		||||
@@ -255,7 +259,7 @@ func (w *BackupFileWriter) Write(b []byte) (int, error) {
 | 
			
		||||
// close the underlying file.
 | 
			
		||||
func (w *BackupFileWriter) Close() error {
 | 
			
		||||
	if w.ctx != 0 {
 | 
			
		||||
		backupWrite(syscall.Handle(w.f.Fd()), nil, nil, true, false, &w.ctx)
 | 
			
		||||
		_ = backupWrite(syscall.Handle(w.f.Fd()), nil, nil, true, false, &w.ctx)
 | 
			
		||||
		runtime.KeepAlive(w.f)
 | 
			
		||||
		w.ctx = 0
 | 
			
		||||
	}
 | 
			
		||||
@@ -271,7 +275,13 @@ func OpenForBackup(path string, access uint32, share uint32, createmode uint32)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	h, err := syscall.CreateFile(&winPath[0], access, share, nil, createmode, syscall.FILE_FLAG_BACKUP_SEMANTICS|syscall.FILE_FLAG_OPEN_REPARSE_POINT, 0)
 | 
			
		||||
	h, err := syscall.CreateFile(&winPath[0],
 | 
			
		||||
		access,
 | 
			
		||||
		share,
 | 
			
		||||
		nil,
 | 
			
		||||
		createmode,
 | 
			
		||||
		syscall.FILE_FLAG_BACKUP_SEMANTICS|syscall.FILE_FLAG_OPEN_REPARSE_POINT,
 | 
			
		||||
		0)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		err = &os.PathError{Op: "open", Path: path, Err: err}
 | 
			
		||||
		return nil, err
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										22
									
								
								vendor/github.com/Microsoft/go-winio/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								vendor/github.com/Microsoft/go-winio/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
// This package provides utilities for efficiently performing Win32 IO operations in Go.
 | 
			
		||||
// Currently, this package is provides support for genreal IO and management of
 | 
			
		||||
//   - named pipes
 | 
			
		||||
//   - files
 | 
			
		||||
//   - [Hyper-V sockets]
 | 
			
		||||
//
 | 
			
		||||
// This code is similar to Go's [net] package, and uses IO completion ports to avoid
 | 
			
		||||
// blocking IO on system threads, allowing Go to reuse the thread to schedule other goroutines.
 | 
			
		||||
//
 | 
			
		||||
// This limits support to Windows Vista and newer operating systems.
 | 
			
		||||
//
 | 
			
		||||
// Additionally, this package provides support for:
 | 
			
		||||
//   - creating and managing GUIDs
 | 
			
		||||
//   - writing to [ETW]
 | 
			
		||||
//   - opening and manageing VHDs
 | 
			
		||||
//   - parsing [Windows Image files]
 | 
			
		||||
//   - auto-generating Win32 API code
 | 
			
		||||
//
 | 
			
		||||
// [Hyper-V sockets]: https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/user-guide/make-integration-service
 | 
			
		||||
// [ETW]: https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/event-tracing-for-windows--etw-
 | 
			
		||||
// [Windows Image files]: https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/work-with-windows-images
 | 
			
		||||
package winio
 | 
			
		||||
							
								
								
									
										8
									
								
								vendor/github.com/Microsoft/go-winio/ea.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/Microsoft/go-winio/ea.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -33,7 +33,7 @@ func parseEa(b []byte) (ea ExtendedAttribute, nb []byte, err error) {
 | 
			
		||||
	err = binary.Read(bytes.NewReader(b), binary.LittleEndian, &info)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		err = errInvalidEaBuffer
 | 
			
		||||
		return
 | 
			
		||||
		return ea, nb, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	nameOffset := fileFullEaInformationSize
 | 
			
		||||
@@ -43,7 +43,7 @@ func parseEa(b []byte) (ea ExtendedAttribute, nb []byte, err error) {
 | 
			
		||||
	nextOffset := int(info.NextEntryOffset)
 | 
			
		||||
	if valueLen+valueOffset > len(b) || nextOffset < 0 || nextOffset > len(b) {
 | 
			
		||||
		err = errInvalidEaBuffer
 | 
			
		||||
		return
 | 
			
		||||
		return ea, nb, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ea.Name = string(b[nameOffset : nameOffset+nameLen])
 | 
			
		||||
@@ -52,7 +52,7 @@ func parseEa(b []byte) (ea ExtendedAttribute, nb []byte, err error) {
 | 
			
		||||
	if info.NextEntryOffset != 0 {
 | 
			
		||||
		nb = b[info.NextEntryOffset:]
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
	return ea, nb, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DecodeExtendedAttributes decodes a list of EAs from a FILE_FULL_EA_INFORMATION
 | 
			
		||||
@@ -67,7 +67,7 @@ func DecodeExtendedAttributes(b []byte) (eas []ExtendedAttribute, err error) {
 | 
			
		||||
		eas = append(eas, ea)
 | 
			
		||||
		b = nb
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
	return eas, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func writeEa(buf *bytes.Buffer, ea *ExtendedAttribute, last bool) error {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										88
									
								
								vendor/github.com/Microsoft/go-winio/file.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										88
									
								
								vendor/github.com/Microsoft/go-winio/file.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,3 +1,4 @@
 | 
			
		||||
//go:build windows
 | 
			
		||||
// +build windows
 | 
			
		||||
 | 
			
		||||
package winio
 | 
			
		||||
@@ -10,18 +11,23 @@ import (
 | 
			
		||||
	"sync/atomic"
 | 
			
		||||
	"syscall"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/sys/windows"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//sys cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) = CancelIoEx
 | 
			
		||||
//sys createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) = CreateIoCompletionPort
 | 
			
		||||
//sys getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) = GetQueuedCompletionStatus
 | 
			
		||||
//sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes
 | 
			
		||||
//sys wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) = ws2_32.WSAGetOverlappedResult
 | 
			
		||||
 | 
			
		||||
type atomicBool int32
 | 
			
		||||
 | 
			
		||||
func (b *atomicBool) isSet() bool { return atomic.LoadInt32((*int32)(b)) != 0 }
 | 
			
		||||
func (b *atomicBool) setFalse()   { atomic.StoreInt32((*int32)(b), 0) }
 | 
			
		||||
func (b *atomicBool) setTrue()    { atomic.StoreInt32((*int32)(b), 1) }
 | 
			
		||||
 | 
			
		||||
//revive:disable-next-line:predeclared Keep "new" to maintain consistency with "atomic" pkg
 | 
			
		||||
func (b *atomicBool) swap(new bool) bool {
 | 
			
		||||
	var newInt int32
 | 
			
		||||
	if new {
 | 
			
		||||
@@ -30,11 +36,6 @@ func (b *atomicBool) swap(new bool) bool {
 | 
			
		||||
	return atomic.SwapInt32((*int32)(b), newInt) == 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1
 | 
			
		||||
	cFILE_SKIP_SET_EVENT_ON_HANDLE        = 2
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	ErrFileClosed = errors.New("file has already been closed")
 | 
			
		||||
	ErrTimeout    = &timeoutError{}
 | 
			
		||||
@@ -42,28 +43,28 @@ var (
 | 
			
		||||
 | 
			
		||||
type timeoutError struct{}
 | 
			
		||||
 | 
			
		||||
func (e *timeoutError) Error() string   { return "i/o timeout" }
 | 
			
		||||
func (e *timeoutError) Timeout() bool   { return true }
 | 
			
		||||
func (e *timeoutError) Temporary() bool { return true }
 | 
			
		||||
func (*timeoutError) Error() string   { return "i/o timeout" }
 | 
			
		||||
func (*timeoutError) Timeout() bool   { return true }
 | 
			
		||||
func (*timeoutError) Temporary() bool { return true }
 | 
			
		||||
 | 
			
		||||
type timeoutChan chan struct{}
 | 
			
		||||
 | 
			
		||||
var ioInitOnce sync.Once
 | 
			
		||||
var ioCompletionPort syscall.Handle
 | 
			
		||||
 | 
			
		||||
// ioResult contains the result of an asynchronous IO operation
 | 
			
		||||
// ioResult contains the result of an asynchronous IO operation.
 | 
			
		||||
type ioResult struct {
 | 
			
		||||
	bytes uint32
 | 
			
		||||
	err   error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ioOperation represents an outstanding asynchronous Win32 IO
 | 
			
		||||
// ioOperation represents an outstanding asynchronous Win32 IO.
 | 
			
		||||
type ioOperation struct {
 | 
			
		||||
	o  syscall.Overlapped
 | 
			
		||||
	ch chan ioResult
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func initIo() {
 | 
			
		||||
func initIO() {
 | 
			
		||||
	h, err := createIoCompletionPort(syscall.InvalidHandle, 0, 0, 0xffffffff)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
@@ -79,6 +80,7 @@ type win32File struct {
 | 
			
		||||
	wg            sync.WaitGroup
 | 
			
		||||
	wgLock        sync.RWMutex
 | 
			
		||||
	closing       atomicBool
 | 
			
		||||
	socket        bool
 | 
			
		||||
	readDeadline  deadlineHandler
 | 
			
		||||
	writeDeadline deadlineHandler
 | 
			
		||||
}
 | 
			
		||||
@@ -91,15 +93,15 @@ type deadlineHandler struct {
 | 
			
		||||
	timedout    atomicBool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// makeWin32File makes a new win32File from an existing file handle
 | 
			
		||||
// makeWin32File makes a new win32File from an existing file handle.
 | 
			
		||||
func makeWin32File(h syscall.Handle) (*win32File, error) {
 | 
			
		||||
	f := &win32File{handle: h}
 | 
			
		||||
	ioInitOnce.Do(initIo)
 | 
			
		||||
	ioInitOnce.Do(initIO)
 | 
			
		||||
	_, err := createIoCompletionPort(h, ioCompletionPort, 0, 0xffffffff)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	err = setFileCompletionNotificationModes(h, cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS|cFILE_SKIP_SET_EVENT_ON_HANDLE)
 | 
			
		||||
	err = setFileCompletionNotificationModes(h, windows.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS|windows.FILE_SKIP_SET_EVENT_ON_HANDLE)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
@@ -109,17 +111,23 @@ func makeWin32File(h syscall.Handle) (*win32File, error) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func MakeOpenFile(h syscall.Handle) (io.ReadWriteCloser, error) {
 | 
			
		||||
	return makeWin32File(h)
 | 
			
		||||
	// If we return the result of makeWin32File directly, it can result in an
 | 
			
		||||
	// interface-wrapped nil, rather than a nil interface value.
 | 
			
		||||
	f, err := makeWin32File(h)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return f, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// closeHandle closes the resources associated with a Win32 handle
 | 
			
		||||
// closeHandle closes the resources associated with a Win32 handle.
 | 
			
		||||
func (f *win32File) closeHandle() {
 | 
			
		||||
	f.wgLock.Lock()
 | 
			
		||||
	// Atomically set that we are closing, releasing the resources only once.
 | 
			
		||||
	if !f.closing.swap(true) {
 | 
			
		||||
		f.wgLock.Unlock()
 | 
			
		||||
		// cancel all IO and wait for it to complete
 | 
			
		||||
		cancelIoEx(f.handle, nil)
 | 
			
		||||
		_ = cancelIoEx(f.handle, nil)
 | 
			
		||||
		f.wg.Wait()
 | 
			
		||||
		// at this point, no new IO can start
 | 
			
		||||
		syscall.Close(f.handle)
 | 
			
		||||
@@ -135,9 +143,14 @@ func (f *win32File) Close() error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// prepareIo prepares for a new IO operation.
 | 
			
		||||
// IsClosed checks if the file has been closed.
 | 
			
		||||
func (f *win32File) IsClosed() bool {
 | 
			
		||||
	return f.closing.isSet()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// prepareIO prepares for a new IO operation.
 | 
			
		||||
// The caller must call f.wg.Done() when the IO is finished, prior to Close() returning.
 | 
			
		||||
func (f *win32File) prepareIo() (*ioOperation, error) {
 | 
			
		||||
func (f *win32File) prepareIO() (*ioOperation, error) {
 | 
			
		||||
	f.wgLock.RLock()
 | 
			
		||||
	if f.closing.isSet() {
 | 
			
		||||
		f.wgLock.RUnlock()
 | 
			
		||||
@@ -150,7 +163,7 @@ func (f *win32File) prepareIo() (*ioOperation, error) {
 | 
			
		||||
	return c, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ioCompletionProcessor processes completed async IOs forever
 | 
			
		||||
// ioCompletionProcessor processes completed async IOs forever.
 | 
			
		||||
func ioCompletionProcessor(h syscall.Handle) {
 | 
			
		||||
	for {
 | 
			
		||||
		var bytes uint32
 | 
			
		||||
@@ -164,15 +177,17 @@ func ioCompletionProcessor(h syscall.Handle) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// asyncIo processes the return value from ReadFile or WriteFile, blocking until
 | 
			
		||||
// todo: helsaawy - create an asyncIO version that takes a context
 | 
			
		||||
 | 
			
		||||
// asyncIO processes the return value from ReadFile or WriteFile, blocking until
 | 
			
		||||
// the operation has actually completed.
 | 
			
		||||
func (f *win32File) asyncIo(c *ioOperation, d *deadlineHandler, bytes uint32, err error) (int, error) {
 | 
			
		||||
	if err != syscall.ERROR_IO_PENDING {
 | 
			
		||||
func (f *win32File) asyncIO(c *ioOperation, d *deadlineHandler, bytes uint32, err error) (int, error) {
 | 
			
		||||
	if err != syscall.ERROR_IO_PENDING { //nolint:errorlint // err is Errno
 | 
			
		||||
		return int(bytes), err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if f.closing.isSet() {
 | 
			
		||||
		cancelIoEx(f.handle, &c.o)
 | 
			
		||||
		_ = cancelIoEx(f.handle, &c.o)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var timeout timeoutChan
 | 
			
		||||
@@ -186,16 +201,20 @@ func (f *win32File) asyncIo(c *ioOperation, d *deadlineHandler, bytes uint32, er
 | 
			
		||||
	select {
 | 
			
		||||
	case r = <-c.ch:
 | 
			
		||||
		err = r.err
 | 
			
		||||
		if err == syscall.ERROR_OPERATION_ABORTED {
 | 
			
		||||
		if err == syscall.ERROR_OPERATION_ABORTED { //nolint:errorlint // err is Errno
 | 
			
		||||
			if f.closing.isSet() {
 | 
			
		||||
				err = ErrFileClosed
 | 
			
		||||
			}
 | 
			
		||||
		} else if err != nil && f.socket {
 | 
			
		||||
			// err is from Win32. Query the overlapped structure to get the winsock error.
 | 
			
		||||
			var bytes, flags uint32
 | 
			
		||||
			err = wsaGetOverlappedResult(f.handle, &c.o, &bytes, false, &flags)
 | 
			
		||||
		}
 | 
			
		||||
	case <-timeout:
 | 
			
		||||
		cancelIoEx(f.handle, &c.o)
 | 
			
		||||
		_ = cancelIoEx(f.handle, &c.o)
 | 
			
		||||
		r = <-c.ch
 | 
			
		||||
		err = r.err
 | 
			
		||||
		if err == syscall.ERROR_OPERATION_ABORTED {
 | 
			
		||||
		if err == syscall.ERROR_OPERATION_ABORTED { //nolint:errorlint // err is Errno
 | 
			
		||||
			err = ErrTimeout
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -203,13 +222,14 @@ func (f *win32File) asyncIo(c *ioOperation, d *deadlineHandler, bytes uint32, er
 | 
			
		||||
	// runtime.KeepAlive is needed, as c is passed via native
 | 
			
		||||
	// code to ioCompletionProcessor, c must remain alive
 | 
			
		||||
	// until the channel read is complete.
 | 
			
		||||
	// todo: (de)allocate *ioOperation via win32 heap functions, instead of needing to KeepAlive?
 | 
			
		||||
	runtime.KeepAlive(c)
 | 
			
		||||
	return int(r.bytes), err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Read reads from a file handle.
 | 
			
		||||
func (f *win32File) Read(b []byte) (int, error) {
 | 
			
		||||
	c, err := f.prepareIo()
 | 
			
		||||
	c, err := f.prepareIO()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
@@ -221,13 +241,13 @@ func (f *win32File) Read(b []byte) (int, error) {
 | 
			
		||||
 | 
			
		||||
	var bytes uint32
 | 
			
		||||
	err = syscall.ReadFile(f.handle, b, &bytes, &c.o)
 | 
			
		||||
	n, err := f.asyncIo(c, &f.readDeadline, bytes, err)
 | 
			
		||||
	n, err := f.asyncIO(c, &f.readDeadline, bytes, err)
 | 
			
		||||
	runtime.KeepAlive(b)
 | 
			
		||||
 | 
			
		||||
	// Handle EOF conditions.
 | 
			
		||||
	if err == nil && n == 0 && len(b) != 0 {
 | 
			
		||||
		return 0, io.EOF
 | 
			
		||||
	} else if err == syscall.ERROR_BROKEN_PIPE {
 | 
			
		||||
	} else if err == syscall.ERROR_BROKEN_PIPE { //nolint:errorlint // err is Errno
 | 
			
		||||
		return 0, io.EOF
 | 
			
		||||
	} else {
 | 
			
		||||
		return n, err
 | 
			
		||||
@@ -236,7 +256,7 @@ func (f *win32File) Read(b []byte) (int, error) {
 | 
			
		||||
 | 
			
		||||
// Write writes to a file handle.
 | 
			
		||||
func (f *win32File) Write(b []byte) (int, error) {
 | 
			
		||||
	c, err := f.prepareIo()
 | 
			
		||||
	c, err := f.prepareIO()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
@@ -248,7 +268,7 @@ func (f *win32File) Write(b []byte) (int, error) {
 | 
			
		||||
 | 
			
		||||
	var bytes uint32
 | 
			
		||||
	err = syscall.WriteFile(f.handle, b, &bytes, &c.o)
 | 
			
		||||
	n, err := f.asyncIo(c, &f.writeDeadline, bytes, err)
 | 
			
		||||
	n, err := f.asyncIO(c, &f.writeDeadline, bytes, err)
 | 
			
		||||
	runtime.KeepAlive(b)
 | 
			
		||||
	return n, err
 | 
			
		||||
}
 | 
			
		||||
@@ -265,6 +285,10 @@ func (f *win32File) Flush() error {
 | 
			
		||||
	return syscall.FlushFileBuffers(f.handle)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *win32File) Fd() uintptr {
 | 
			
		||||
	return uintptr(f.handle)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *deadlineHandler) set(deadline time.Time) error {
 | 
			
		||||
	d.setLock.Lock()
 | 
			
		||||
	defer d.setLock.Unlock()
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										57
									
								
								vendor/github.com/Microsoft/go-winio/fileinfo.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										57
									
								
								vendor/github.com/Microsoft/go-winio/fileinfo.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,3 +1,4 @@
 | 
			
		||||
//go:build windows
 | 
			
		||||
// +build windows
 | 
			
		||||
 | 
			
		||||
package winio
 | 
			
		||||
@@ -5,29 +6,27 @@ 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
 | 
			
		||||
	_                                                       uint32 // padding
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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 +35,40 @@ 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 +79,12 @@ 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)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										575
									
								
								vendor/github.com/Microsoft/go-winio/hvsock.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										575
									
								
								vendor/github.com/Microsoft/go-winio/hvsock.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,575 @@
 | 
			
		||||
//go:build windows
 | 
			
		||||
// +build windows
 | 
			
		||||
 | 
			
		||||
package winio
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"net"
 | 
			
		||||
	"os"
 | 
			
		||||
	"syscall"
 | 
			
		||||
	"time"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/sys/windows"
 | 
			
		||||
 | 
			
		||||
	"github.com/Microsoft/go-winio/internal/socket"
 | 
			
		||||
	"github.com/Microsoft/go-winio/pkg/guid"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const afHVSock = 34 // AF_HYPERV
 | 
			
		||||
 | 
			
		||||
// Well known Service and VM IDs
 | 
			
		||||
// https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/user-guide/make-integration-service#vmid-wildcards
 | 
			
		||||
 | 
			
		||||
// HvsockGUIDWildcard is the wildcard VmId for accepting connections from all partitions.
 | 
			
		||||
func HvsockGUIDWildcard() guid.GUID { // 00000000-0000-0000-0000-000000000000
 | 
			
		||||
	return guid.GUID{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HvsockGUIDBroadcast is the wildcard VmId for broadcasting sends to all partitions.
 | 
			
		||||
func HvsockGUIDBroadcast() guid.GUID { // ffffffff-ffff-ffff-ffff-ffffffffffff
 | 
			
		||||
	return guid.GUID{
 | 
			
		||||
		Data1: 0xffffffff,
 | 
			
		||||
		Data2: 0xffff,
 | 
			
		||||
		Data3: 0xffff,
 | 
			
		||||
		Data4: [8]uint8{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HvsockGUIDLoopback is the Loopback VmId for accepting connections to the same partition as the connector.
 | 
			
		||||
func HvsockGUIDLoopback() guid.GUID { // e0e16197-dd56-4a10-9195-5ee7a155a838
 | 
			
		||||
	return guid.GUID{
 | 
			
		||||
		Data1: 0xe0e16197,
 | 
			
		||||
		Data2: 0xdd56,
 | 
			
		||||
		Data3: 0x4a10,
 | 
			
		||||
		Data4: [8]uint8{0x91, 0x95, 0x5e, 0xe7, 0xa1, 0x55, 0xa8, 0x38},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HvsockGUIDSiloHost is the address of a silo's host partition:
 | 
			
		||||
//   - The silo host of a hosted silo is the utility VM.
 | 
			
		||||
//   - The silo host of a silo on a physical host is the physical host.
 | 
			
		||||
func HvsockGUIDSiloHost() guid.GUID { // 36bd0c5c-7276-4223-88ba-7d03b654c568
 | 
			
		||||
	return guid.GUID{
 | 
			
		||||
		Data1: 0x36bd0c5c,
 | 
			
		||||
		Data2: 0x7276,
 | 
			
		||||
		Data3: 0x4223,
 | 
			
		||||
		Data4: [8]byte{0x88, 0xba, 0x7d, 0x03, 0xb6, 0x54, 0xc5, 0x68},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HvsockGUIDChildren is the wildcard VmId for accepting connections from the connector's child partitions.
 | 
			
		||||
func HvsockGUIDChildren() guid.GUID { // 90db8b89-0d35-4f79-8ce9-49ea0ac8b7cd
 | 
			
		||||
	return guid.GUID{
 | 
			
		||||
		Data1: 0x90db8b89,
 | 
			
		||||
		Data2: 0xd35,
 | 
			
		||||
		Data3: 0x4f79,
 | 
			
		||||
		Data4: [8]uint8{0x8c, 0xe9, 0x49, 0xea, 0xa, 0xc8, 0xb7, 0xcd},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HvsockGUIDParent is the wildcard VmId for accepting connections from the connector's parent partition.
 | 
			
		||||
// Listening on this VmId accepts connection from:
 | 
			
		||||
//   - Inside silos: silo host partition.
 | 
			
		||||
//   - Inside hosted silo: host of the VM.
 | 
			
		||||
//   - Inside VM: VM host.
 | 
			
		||||
//   - Physical host: Not supported.
 | 
			
		||||
func HvsockGUIDParent() guid.GUID { // a42e7cda-d03f-480c-9cc2-a4de20abb878
 | 
			
		||||
	return guid.GUID{
 | 
			
		||||
		Data1: 0xa42e7cda,
 | 
			
		||||
		Data2: 0xd03f,
 | 
			
		||||
		Data3: 0x480c,
 | 
			
		||||
		Data4: [8]uint8{0x9c, 0xc2, 0xa4, 0xde, 0x20, 0xab, 0xb8, 0x78},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// hvsockVsockServiceTemplate is the Service GUID used for the VSOCK protocol.
 | 
			
		||||
func hvsockVsockServiceTemplate() guid.GUID { // 00000000-facb-11e6-bd58-64006a7986d3
 | 
			
		||||
	return guid.GUID{
 | 
			
		||||
		Data2: 0xfacb,
 | 
			
		||||
		Data3: 0x11e6,
 | 
			
		||||
		Data4: [8]uint8{0xbd, 0x58, 0x64, 0x00, 0x6a, 0x79, 0x86, 0xd3},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// An HvsockAddr is an address for a AF_HYPERV socket.
 | 
			
		||||
type HvsockAddr struct {
 | 
			
		||||
	VMID      guid.GUID
 | 
			
		||||
	ServiceID guid.GUID
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type rawHvsockAddr struct {
 | 
			
		||||
	Family    uint16
 | 
			
		||||
	_         uint16
 | 
			
		||||
	VMID      guid.GUID
 | 
			
		||||
	ServiceID guid.GUID
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ socket.RawSockaddr = &rawHvsockAddr{}
 | 
			
		||||
 | 
			
		||||
// Network returns the address's network name, "hvsock".
 | 
			
		||||
func (*HvsockAddr) Network() string {
 | 
			
		||||
	return "hvsock"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (addr *HvsockAddr) String() string {
 | 
			
		||||
	return fmt.Sprintf("%s:%s", &addr.VMID, &addr.ServiceID)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// VsockServiceID returns an hvsock service ID corresponding to the specified AF_VSOCK port.
 | 
			
		||||
func VsockServiceID(port uint32) guid.GUID {
 | 
			
		||||
	g := hvsockVsockServiceTemplate() // make a copy
 | 
			
		||||
	g.Data1 = port
 | 
			
		||||
	return g
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (addr *HvsockAddr) raw() rawHvsockAddr {
 | 
			
		||||
	return rawHvsockAddr{
 | 
			
		||||
		Family:    afHVSock,
 | 
			
		||||
		VMID:      addr.VMID,
 | 
			
		||||
		ServiceID: addr.ServiceID,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (addr *HvsockAddr) fromRaw(raw *rawHvsockAddr) {
 | 
			
		||||
	addr.VMID = raw.VMID
 | 
			
		||||
	addr.ServiceID = raw.ServiceID
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sockaddr returns a pointer to and the size of this struct.
 | 
			
		||||
//
 | 
			
		||||
// Implements the [socket.RawSockaddr] interface, and allows use in
 | 
			
		||||
// [socket.Bind] and [socket.ConnectEx].
 | 
			
		||||
func (r *rawHvsockAddr) Sockaddr() (unsafe.Pointer, int32, error) {
 | 
			
		||||
	return unsafe.Pointer(r), int32(unsafe.Sizeof(rawHvsockAddr{})), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sockaddr interface allows use with `sockets.Bind()` and `.ConnectEx()`.
 | 
			
		||||
func (r *rawHvsockAddr) FromBytes(b []byte) error {
 | 
			
		||||
	n := int(unsafe.Sizeof(rawHvsockAddr{}))
 | 
			
		||||
 | 
			
		||||
	if len(b) < n {
 | 
			
		||||
		return fmt.Errorf("got %d, want %d: %w", len(b), n, socket.ErrBufferSize)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	copy(unsafe.Slice((*byte)(unsafe.Pointer(r)), n), b[:n])
 | 
			
		||||
	if r.Family != afHVSock {
 | 
			
		||||
		return fmt.Errorf("got %d, want %d: %w", r.Family, afHVSock, socket.ErrAddrFamily)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HvsockListener is a socket listener for the AF_HYPERV address family.
 | 
			
		||||
type HvsockListener struct {
 | 
			
		||||
	sock *win32File
 | 
			
		||||
	addr HvsockAddr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ net.Listener = &HvsockListener{}
 | 
			
		||||
 | 
			
		||||
// HvsockConn is a connected socket of the AF_HYPERV address family.
 | 
			
		||||
type HvsockConn struct {
 | 
			
		||||
	sock          *win32File
 | 
			
		||||
	local, remote HvsockAddr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ net.Conn = &HvsockConn{}
 | 
			
		||||
 | 
			
		||||
func newHVSocket() (*win32File, error) {
 | 
			
		||||
	fd, err := syscall.Socket(afHVSock, syscall.SOCK_STREAM, 1)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, os.NewSyscallError("socket", err)
 | 
			
		||||
	}
 | 
			
		||||
	f, err := makeWin32File(fd)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		syscall.Close(fd)
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	f.socket = true
 | 
			
		||||
	return f, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ListenHvsock listens for connections on the specified hvsock address.
 | 
			
		||||
func ListenHvsock(addr *HvsockAddr) (_ *HvsockListener, err error) {
 | 
			
		||||
	l := &HvsockListener{addr: *addr}
 | 
			
		||||
	sock, err := newHVSocket()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, l.opErr("listen", err)
 | 
			
		||||
	}
 | 
			
		||||
	sa := addr.raw()
 | 
			
		||||
	err = socket.Bind(windows.Handle(sock.handle), &sa)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, l.opErr("listen", os.NewSyscallError("socket", err))
 | 
			
		||||
	}
 | 
			
		||||
	err = syscall.Listen(sock.handle, 16)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, l.opErr("listen", os.NewSyscallError("listen", err))
 | 
			
		||||
	}
 | 
			
		||||
	return &HvsockListener{sock: sock, addr: *addr}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *HvsockListener) opErr(op string, err error) error {
 | 
			
		||||
	return &net.OpError{Op: op, Net: "hvsock", Addr: &l.addr, Err: err}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Addr returns the listener's network address.
 | 
			
		||||
func (l *HvsockListener) Addr() net.Addr {
 | 
			
		||||
	return &l.addr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Accept waits for the next connection and returns it.
 | 
			
		||||
func (l *HvsockListener) Accept() (_ net.Conn, err error) {
 | 
			
		||||
	sock, err := newHVSocket()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, l.opErr("accept", err)
 | 
			
		||||
	}
 | 
			
		||||
	defer func() {
 | 
			
		||||
		if sock != nil {
 | 
			
		||||
			sock.Close()
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
	c, err := l.sock.prepareIO()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, l.opErr("accept", err)
 | 
			
		||||
	}
 | 
			
		||||
	defer l.sock.wg.Done()
 | 
			
		||||
 | 
			
		||||
	// AcceptEx, per documentation, requires an extra 16 bytes per address.
 | 
			
		||||
	//
 | 
			
		||||
	// https://docs.microsoft.com/en-us/windows/win32/api/mswsock/nf-mswsock-acceptex
 | 
			
		||||
	const addrlen = uint32(16 + unsafe.Sizeof(rawHvsockAddr{}))
 | 
			
		||||
	var addrbuf [addrlen * 2]byte
 | 
			
		||||
 | 
			
		||||
	var bytes uint32
 | 
			
		||||
	err = syscall.AcceptEx(l.sock.handle, sock.handle, &addrbuf[0], 0 /* rxdatalen */, addrlen, addrlen, &bytes, &c.o)
 | 
			
		||||
	if _, err = l.sock.asyncIO(c, nil, bytes, err); err != nil {
 | 
			
		||||
		return nil, l.opErr("accept", os.NewSyscallError("acceptex", err))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	conn := &HvsockConn{
 | 
			
		||||
		sock: sock,
 | 
			
		||||
	}
 | 
			
		||||
	// The local address returned in the AcceptEx buffer is the same as the Listener socket's
 | 
			
		||||
	// address. However, the service GUID reported by GetSockName is different from the Listeners
 | 
			
		||||
	// socket, and is sometimes the same as the local address of the socket that dialed the
 | 
			
		||||
	// address, with the service GUID.Data1 incremented, but othertimes is different.
 | 
			
		||||
	// todo: does the local address matter? is the listener's address or the actual address appropriate?
 | 
			
		||||
	conn.local.fromRaw((*rawHvsockAddr)(unsafe.Pointer(&addrbuf[0])))
 | 
			
		||||
	conn.remote.fromRaw((*rawHvsockAddr)(unsafe.Pointer(&addrbuf[addrlen])))
 | 
			
		||||
 | 
			
		||||
	// initialize the accepted socket and update its properties with those of the listening socket
 | 
			
		||||
	if err = windows.Setsockopt(windows.Handle(sock.handle),
 | 
			
		||||
		windows.SOL_SOCKET, windows.SO_UPDATE_ACCEPT_CONTEXT,
 | 
			
		||||
		(*byte)(unsafe.Pointer(&l.sock.handle)), int32(unsafe.Sizeof(l.sock.handle))); err != nil {
 | 
			
		||||
		return nil, conn.opErr("accept", os.NewSyscallError("setsockopt", err))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sock = nil
 | 
			
		||||
	return conn, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Close closes the listener, causing any pending Accept calls to fail.
 | 
			
		||||
func (l *HvsockListener) Close() error {
 | 
			
		||||
	return l.sock.Close()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HvsockDialer configures and dials a Hyper-V Socket (ie, [HvsockConn]).
 | 
			
		||||
type HvsockDialer struct {
 | 
			
		||||
	// Deadline is the time the Dial operation must connect before erroring.
 | 
			
		||||
	Deadline time.Time
 | 
			
		||||
 | 
			
		||||
	// Retries is the number of additional connects to try if the connection times out, is refused,
 | 
			
		||||
	// or the host is unreachable
 | 
			
		||||
	Retries uint
 | 
			
		||||
 | 
			
		||||
	// RetryWait is the time to wait after a connection error to retry
 | 
			
		||||
	RetryWait time.Duration
 | 
			
		||||
 | 
			
		||||
	rt *time.Timer // redial wait timer
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Dial the Hyper-V socket at addr.
 | 
			
		||||
//
 | 
			
		||||
// See [HvsockDialer.Dial] for more information.
 | 
			
		||||
func Dial(ctx context.Context, addr *HvsockAddr) (conn *HvsockConn, err error) {
 | 
			
		||||
	return (&HvsockDialer{}).Dial(ctx, addr)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Dial attempts to connect to the Hyper-V socket at addr, and returns a connection if successful.
 | 
			
		||||
// Will attempt (HvsockDialer).Retries if dialing fails, waiting (HvsockDialer).RetryWait between
 | 
			
		||||
// retries.
 | 
			
		||||
//
 | 
			
		||||
// Dialing can be cancelled either by providing (HvsockDialer).Deadline, or cancelling ctx.
 | 
			
		||||
func (d *HvsockDialer) Dial(ctx context.Context, addr *HvsockAddr) (conn *HvsockConn, err error) {
 | 
			
		||||
	op := "dial"
 | 
			
		||||
	// create the conn early to use opErr()
 | 
			
		||||
	conn = &HvsockConn{
 | 
			
		||||
		remote: *addr,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !d.Deadline.IsZero() {
 | 
			
		||||
		var cancel context.CancelFunc
 | 
			
		||||
		ctx, cancel = context.WithDeadline(ctx, d.Deadline)
 | 
			
		||||
		defer cancel()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// preemptive timeout/cancellation check
 | 
			
		||||
	if err = ctx.Err(); err != nil {
 | 
			
		||||
		return nil, conn.opErr(op, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sock, err := newHVSocket()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, conn.opErr(op, err)
 | 
			
		||||
	}
 | 
			
		||||
	defer func() {
 | 
			
		||||
		if sock != nil {
 | 
			
		||||
			sock.Close()
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	sa := addr.raw()
 | 
			
		||||
	err = socket.Bind(windows.Handle(sock.handle), &sa)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, conn.opErr(op, os.NewSyscallError("bind", err))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c, err := sock.prepareIO()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, conn.opErr(op, err)
 | 
			
		||||
	}
 | 
			
		||||
	defer sock.wg.Done()
 | 
			
		||||
	var bytes uint32
 | 
			
		||||
	for i := uint(0); i <= d.Retries; i++ {
 | 
			
		||||
		err = socket.ConnectEx(
 | 
			
		||||
			windows.Handle(sock.handle),
 | 
			
		||||
			&sa,
 | 
			
		||||
			nil, // sendBuf
 | 
			
		||||
			0,   // sendDataLen
 | 
			
		||||
			&bytes,
 | 
			
		||||
			(*windows.Overlapped)(unsafe.Pointer(&c.o)))
 | 
			
		||||
		_, err = sock.asyncIO(c, nil, bytes, err)
 | 
			
		||||
		if i < d.Retries && canRedial(err) {
 | 
			
		||||
			if err = d.redialWait(ctx); err == nil {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		break
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, conn.opErr(op, os.NewSyscallError("connectex", err))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// update the connection properties, so shutdown can be used
 | 
			
		||||
	if err = windows.Setsockopt(
 | 
			
		||||
		windows.Handle(sock.handle),
 | 
			
		||||
		windows.SOL_SOCKET,
 | 
			
		||||
		windows.SO_UPDATE_CONNECT_CONTEXT,
 | 
			
		||||
		nil, // optvalue
 | 
			
		||||
		0,   // optlen
 | 
			
		||||
	); err != nil {
 | 
			
		||||
		return nil, conn.opErr(op, os.NewSyscallError("setsockopt", err))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// get the local name
 | 
			
		||||
	var sal rawHvsockAddr
 | 
			
		||||
	err = socket.GetSockName(windows.Handle(sock.handle), &sal)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, conn.opErr(op, os.NewSyscallError("getsockname", err))
 | 
			
		||||
	}
 | 
			
		||||
	conn.local.fromRaw(&sal)
 | 
			
		||||
 | 
			
		||||
	// one last check for timeout, since asyncIO doesn't check the context
 | 
			
		||||
	if err = ctx.Err(); err != nil {
 | 
			
		||||
		return nil, conn.opErr(op, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	conn.sock = sock
 | 
			
		||||
	sock = nil
 | 
			
		||||
 | 
			
		||||
	return conn, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// redialWait waits before attempting to redial, resetting the timer as appropriate.
 | 
			
		||||
func (d *HvsockDialer) redialWait(ctx context.Context) (err error) {
 | 
			
		||||
	if d.RetryWait == 0 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if d.rt == nil {
 | 
			
		||||
		d.rt = time.NewTimer(d.RetryWait)
 | 
			
		||||
	} else {
 | 
			
		||||
		// should already be stopped and drained
 | 
			
		||||
		d.rt.Reset(d.RetryWait)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	select {
 | 
			
		||||
	case <-ctx.Done():
 | 
			
		||||
	case <-d.rt.C:
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// stop and drain the timer
 | 
			
		||||
	if !d.rt.Stop() {
 | 
			
		||||
		<-d.rt.C
 | 
			
		||||
	}
 | 
			
		||||
	return ctx.Err()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// assumes error is a plain, unwrapped syscall.Errno provided by direct syscall.
 | 
			
		||||
func canRedial(err error) bool {
 | 
			
		||||
	//nolint:errorlint // guaranteed to be an Errno
 | 
			
		||||
	switch err {
 | 
			
		||||
	case windows.WSAECONNREFUSED, windows.WSAENETUNREACH, windows.WSAETIMEDOUT,
 | 
			
		||||
		windows.ERROR_CONNECTION_REFUSED, windows.ERROR_CONNECTION_UNAVAIL:
 | 
			
		||||
		return true
 | 
			
		||||
	default:
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (conn *HvsockConn) opErr(op string, err error) error {
 | 
			
		||||
	// translate from "file closed" to "socket closed"
 | 
			
		||||
	if errors.Is(err, ErrFileClosed) {
 | 
			
		||||
		err = socket.ErrSocketClosed
 | 
			
		||||
	}
 | 
			
		||||
	return &net.OpError{Op: op, Net: "hvsock", Source: &conn.local, Addr: &conn.remote, Err: err}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (conn *HvsockConn) Read(b []byte) (int, error) {
 | 
			
		||||
	c, err := conn.sock.prepareIO()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, conn.opErr("read", err)
 | 
			
		||||
	}
 | 
			
		||||
	defer conn.sock.wg.Done()
 | 
			
		||||
	buf := syscall.WSABuf{Buf: &b[0], Len: uint32(len(b))}
 | 
			
		||||
	var flags, bytes uint32
 | 
			
		||||
	err = syscall.WSARecv(conn.sock.handle, &buf, 1, &bytes, &flags, &c.o, nil)
 | 
			
		||||
	n, err := conn.sock.asyncIO(c, &conn.sock.readDeadline, bytes, err)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		var eno windows.Errno
 | 
			
		||||
		if errors.As(err, &eno) {
 | 
			
		||||
			err = os.NewSyscallError("wsarecv", eno)
 | 
			
		||||
		}
 | 
			
		||||
		return 0, conn.opErr("read", err)
 | 
			
		||||
	} else if n == 0 {
 | 
			
		||||
		err = io.EOF
 | 
			
		||||
	}
 | 
			
		||||
	return n, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (conn *HvsockConn) Write(b []byte) (int, error) {
 | 
			
		||||
	t := 0
 | 
			
		||||
	for len(b) != 0 {
 | 
			
		||||
		n, err := conn.write(b)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return t + n, err
 | 
			
		||||
		}
 | 
			
		||||
		t += n
 | 
			
		||||
		b = b[n:]
 | 
			
		||||
	}
 | 
			
		||||
	return t, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (conn *HvsockConn) write(b []byte) (int, error) {
 | 
			
		||||
	c, err := conn.sock.prepareIO()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, conn.opErr("write", err)
 | 
			
		||||
	}
 | 
			
		||||
	defer conn.sock.wg.Done()
 | 
			
		||||
	buf := syscall.WSABuf{Buf: &b[0], Len: uint32(len(b))}
 | 
			
		||||
	var bytes uint32
 | 
			
		||||
	err = syscall.WSASend(conn.sock.handle, &buf, 1, &bytes, 0, &c.o, nil)
 | 
			
		||||
	n, err := conn.sock.asyncIO(c, &conn.sock.writeDeadline, bytes, err)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		var eno windows.Errno
 | 
			
		||||
		if errors.As(err, &eno) {
 | 
			
		||||
			err = os.NewSyscallError("wsasend", eno)
 | 
			
		||||
		}
 | 
			
		||||
		return 0, conn.opErr("write", err)
 | 
			
		||||
	}
 | 
			
		||||
	return n, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Close closes the socket connection, failing any pending read or write calls.
 | 
			
		||||
func (conn *HvsockConn) Close() error {
 | 
			
		||||
	return conn.sock.Close()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (conn *HvsockConn) IsClosed() bool {
 | 
			
		||||
	return conn.sock.IsClosed()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// shutdown disables sending or receiving on a socket.
 | 
			
		||||
func (conn *HvsockConn) shutdown(how int) error {
 | 
			
		||||
	if conn.IsClosed() {
 | 
			
		||||
		return socket.ErrSocketClosed
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err := syscall.Shutdown(conn.sock.handle, how)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		// If the connection was closed, shutdowns fail with "not connected"
 | 
			
		||||
		if errors.Is(err, windows.WSAENOTCONN) ||
 | 
			
		||||
			errors.Is(err, windows.WSAESHUTDOWN) {
 | 
			
		||||
			err = socket.ErrSocketClosed
 | 
			
		||||
		}
 | 
			
		||||
		return os.NewSyscallError("shutdown", err)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CloseRead shuts down the read end of the socket, preventing future read operations.
 | 
			
		||||
func (conn *HvsockConn) CloseRead() error {
 | 
			
		||||
	err := conn.shutdown(syscall.SHUT_RD)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return conn.opErr("closeread", err)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CloseWrite shuts down the write end of the socket, preventing future write operations and
 | 
			
		||||
// notifying the other endpoint that no more data will be written.
 | 
			
		||||
func (conn *HvsockConn) CloseWrite() error {
 | 
			
		||||
	err := conn.shutdown(syscall.SHUT_WR)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return conn.opErr("closewrite", err)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LocalAddr returns the local address of the connection.
 | 
			
		||||
func (conn *HvsockConn) LocalAddr() net.Addr {
 | 
			
		||||
	return &conn.local
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RemoteAddr returns the remote address of the connection.
 | 
			
		||||
func (conn *HvsockConn) RemoteAddr() net.Addr {
 | 
			
		||||
	return &conn.remote
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetDeadline implements the net.Conn SetDeadline method.
 | 
			
		||||
func (conn *HvsockConn) SetDeadline(t time.Time) error {
 | 
			
		||||
	// todo: implement `SetDeadline` for `win32File`
 | 
			
		||||
	if err := conn.SetReadDeadline(t); err != nil {
 | 
			
		||||
		return fmt.Errorf("set read deadline: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	if err := conn.SetWriteDeadline(t); err != nil {
 | 
			
		||||
		return fmt.Errorf("set write deadline: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetReadDeadline implements the net.Conn SetReadDeadline method.
 | 
			
		||||
func (conn *HvsockConn) SetReadDeadline(t time.Time) error {
 | 
			
		||||
	return conn.sock.SetReadDeadline(t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetWriteDeadline implements the net.Conn SetWriteDeadline method.
 | 
			
		||||
func (conn *HvsockConn) SetWriteDeadline(t time.Time) error {
 | 
			
		||||
	return conn.sock.SetWriteDeadline(t)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										2
									
								
								vendor/github.com/Microsoft/go-winio/internal/fs/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/Microsoft/go-winio/internal/fs/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
// This package contains Win32 filesystem functionality.
 | 
			
		||||
package fs
 | 
			
		||||
							
								
								
									
										202
									
								
								vendor/github.com/Microsoft/go-winio/internal/fs/fs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								vendor/github.com/Microsoft/go-winio/internal/fs/fs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,202 @@
 | 
			
		||||
//go:build windows
 | 
			
		||||
 | 
			
		||||
package fs
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"golang.org/x/sys/windows"
 | 
			
		||||
 | 
			
		||||
	"github.com/Microsoft/go-winio/internal/stringbuffer"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//go:generate go run github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go fs.go
 | 
			
		||||
 | 
			
		||||
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew
 | 
			
		||||
//sys CreateFile(name string, access AccessMask, mode FileShareMode, sa *syscall.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) [failretval==windows.InvalidHandle] = CreateFileW
 | 
			
		||||
 | 
			
		||||
const NullHandle windows.Handle = 0
 | 
			
		||||
 | 
			
		||||
// AccessMask defines standard, specific, and generic rights.
 | 
			
		||||
//
 | 
			
		||||
//	Bitmask:
 | 
			
		||||
//	 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
 | 
			
		||||
//	 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
 | 
			
		||||
//	+---------------+---------------+-------------------------------+
 | 
			
		||||
//	|G|G|G|G|Resvd|A| StandardRights|         SpecificRights        |
 | 
			
		||||
//	|R|W|E|A|     |S|               |                               |
 | 
			
		||||
//	+-+-------------+---------------+-------------------------------+
 | 
			
		||||
//
 | 
			
		||||
//	GR     Generic Read
 | 
			
		||||
//	GW     Generic Write
 | 
			
		||||
//	GE     Generic Exectue
 | 
			
		||||
//	GA     Generic All
 | 
			
		||||
//	Resvd  Reserved
 | 
			
		||||
//	AS     Access Security System
 | 
			
		||||
//
 | 
			
		||||
// https://learn.microsoft.com/en-us/windows/win32/secauthz/access-mask
 | 
			
		||||
//
 | 
			
		||||
// https://learn.microsoft.com/en-us/windows/win32/secauthz/generic-access-rights
 | 
			
		||||
//
 | 
			
		||||
// https://learn.microsoft.com/en-us/windows/win32/fileio/file-access-rights-constants
 | 
			
		||||
type AccessMask = windows.ACCESS_MASK
 | 
			
		||||
 | 
			
		||||
//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
 | 
			
		||||
const (
 | 
			
		||||
	// Not actually any.
 | 
			
		||||
	//
 | 
			
		||||
	// For CreateFile: "query certain metadata such as file, directory, or device attributes without accessing that file or device"
 | 
			
		||||
	// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew#parameters
 | 
			
		||||
	FILE_ANY_ACCESS AccessMask = 0
 | 
			
		||||
 | 
			
		||||
	// Specific Object Access
 | 
			
		||||
	// from ntioapi.h
 | 
			
		||||
 | 
			
		||||
	FILE_READ_DATA      AccessMask = (0x0001) // file & pipe
 | 
			
		||||
	FILE_LIST_DIRECTORY AccessMask = (0x0001) // directory
 | 
			
		||||
 | 
			
		||||
	FILE_WRITE_DATA AccessMask = (0x0002) // file & pipe
 | 
			
		||||
	FILE_ADD_FILE   AccessMask = (0x0002) // directory
 | 
			
		||||
 | 
			
		||||
	FILE_APPEND_DATA          AccessMask = (0x0004) // file
 | 
			
		||||
	FILE_ADD_SUBDIRECTORY     AccessMask = (0x0004) // directory
 | 
			
		||||
	FILE_CREATE_PIPE_INSTANCE AccessMask = (0x0004) // named pipe
 | 
			
		||||
 | 
			
		||||
	FILE_READ_EA         AccessMask = (0x0008) // file & directory
 | 
			
		||||
	FILE_READ_PROPERTIES AccessMask = FILE_READ_EA
 | 
			
		||||
 | 
			
		||||
	FILE_WRITE_EA         AccessMask = (0x0010) // file & directory
 | 
			
		||||
	FILE_WRITE_PROPERTIES AccessMask = FILE_WRITE_EA
 | 
			
		||||
 | 
			
		||||
	FILE_EXECUTE  AccessMask = (0x0020) // file
 | 
			
		||||
	FILE_TRAVERSE AccessMask = (0x0020) // directory
 | 
			
		||||
 | 
			
		||||
	FILE_DELETE_CHILD AccessMask = (0x0040) // directory
 | 
			
		||||
 | 
			
		||||
	FILE_READ_ATTRIBUTES AccessMask = (0x0080) // all
 | 
			
		||||
 | 
			
		||||
	FILE_WRITE_ATTRIBUTES AccessMask = (0x0100) // all
 | 
			
		||||
 | 
			
		||||
	FILE_ALL_ACCESS      AccessMask = (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF)
 | 
			
		||||
	FILE_GENERIC_READ    AccessMask = (STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE)
 | 
			
		||||
	FILE_GENERIC_WRITE   AccessMask = (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE)
 | 
			
		||||
	FILE_GENERIC_EXECUTE AccessMask = (STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE)
 | 
			
		||||
 | 
			
		||||
	SPECIFIC_RIGHTS_ALL AccessMask = 0x0000FFFF
 | 
			
		||||
 | 
			
		||||
	// Standard Access
 | 
			
		||||
	// from ntseapi.h
 | 
			
		||||
 | 
			
		||||
	DELETE       AccessMask = 0x0001_0000
 | 
			
		||||
	READ_CONTROL AccessMask = 0x0002_0000
 | 
			
		||||
	WRITE_DAC    AccessMask = 0x0004_0000
 | 
			
		||||
	WRITE_OWNER  AccessMask = 0x0008_0000
 | 
			
		||||
	SYNCHRONIZE  AccessMask = 0x0010_0000
 | 
			
		||||
 | 
			
		||||
	STANDARD_RIGHTS_REQUIRED AccessMask = 0x000F_0000
 | 
			
		||||
 | 
			
		||||
	STANDARD_RIGHTS_READ    AccessMask = READ_CONTROL
 | 
			
		||||
	STANDARD_RIGHTS_WRITE   AccessMask = READ_CONTROL
 | 
			
		||||
	STANDARD_RIGHTS_EXECUTE AccessMask = READ_CONTROL
 | 
			
		||||
 | 
			
		||||
	STANDARD_RIGHTS_ALL AccessMask = 0x001F_0000
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type FileShareMode uint32
 | 
			
		||||
 | 
			
		||||
//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
 | 
			
		||||
const (
 | 
			
		||||
	FILE_SHARE_NONE        FileShareMode = 0x00
 | 
			
		||||
	FILE_SHARE_READ        FileShareMode = 0x01
 | 
			
		||||
	FILE_SHARE_WRITE       FileShareMode = 0x02
 | 
			
		||||
	FILE_SHARE_DELETE      FileShareMode = 0x04
 | 
			
		||||
	FILE_SHARE_VALID_FLAGS FileShareMode = 0x07
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type FileCreationDisposition uint32
 | 
			
		||||
 | 
			
		||||
//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
 | 
			
		||||
const (
 | 
			
		||||
	// from winbase.h
 | 
			
		||||
 | 
			
		||||
	CREATE_NEW        FileCreationDisposition = 0x01
 | 
			
		||||
	CREATE_ALWAYS     FileCreationDisposition = 0x02
 | 
			
		||||
	OPEN_EXISTING     FileCreationDisposition = 0x03
 | 
			
		||||
	OPEN_ALWAYS       FileCreationDisposition = 0x04
 | 
			
		||||
	TRUNCATE_EXISTING FileCreationDisposition = 0x05
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// CreateFile and co. take flags or attributes together as one parameter.
 | 
			
		||||
// Define alias until we can use generics to allow both
 | 
			
		||||
 | 
			
		||||
// https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
 | 
			
		||||
type FileFlagOrAttribute uint32
 | 
			
		||||
 | 
			
		||||
//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
 | 
			
		||||
const ( // from winnt.h
 | 
			
		||||
	FILE_FLAG_WRITE_THROUGH       FileFlagOrAttribute = 0x8000_0000
 | 
			
		||||
	FILE_FLAG_OVERLAPPED          FileFlagOrAttribute = 0x4000_0000
 | 
			
		||||
	FILE_FLAG_NO_BUFFERING        FileFlagOrAttribute = 0x2000_0000
 | 
			
		||||
	FILE_FLAG_RANDOM_ACCESS       FileFlagOrAttribute = 0x1000_0000
 | 
			
		||||
	FILE_FLAG_SEQUENTIAL_SCAN     FileFlagOrAttribute = 0x0800_0000
 | 
			
		||||
	FILE_FLAG_DELETE_ON_CLOSE     FileFlagOrAttribute = 0x0400_0000
 | 
			
		||||
	FILE_FLAG_BACKUP_SEMANTICS    FileFlagOrAttribute = 0x0200_0000
 | 
			
		||||
	FILE_FLAG_POSIX_SEMANTICS     FileFlagOrAttribute = 0x0100_0000
 | 
			
		||||
	FILE_FLAG_OPEN_REPARSE_POINT  FileFlagOrAttribute = 0x0020_0000
 | 
			
		||||
	FILE_FLAG_OPEN_NO_RECALL      FileFlagOrAttribute = 0x0010_0000
 | 
			
		||||
	FILE_FLAG_FIRST_PIPE_INSTANCE FileFlagOrAttribute = 0x0008_0000
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type FileSQSFlag = FileFlagOrAttribute
 | 
			
		||||
 | 
			
		||||
//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
 | 
			
		||||
const ( // from winbase.h
 | 
			
		||||
	SECURITY_ANONYMOUS      FileSQSFlag = FileSQSFlag(SecurityAnonymous << 16)
 | 
			
		||||
	SECURITY_IDENTIFICATION FileSQSFlag = FileSQSFlag(SecurityIdentification << 16)
 | 
			
		||||
	SECURITY_IMPERSONATION  FileSQSFlag = FileSQSFlag(SecurityImpersonation << 16)
 | 
			
		||||
	SECURITY_DELEGATION     FileSQSFlag = FileSQSFlag(SecurityDelegation << 16)
 | 
			
		||||
 | 
			
		||||
	SECURITY_SQOS_PRESENT     FileSQSFlag = 0x00100000
 | 
			
		||||
	SECURITY_VALID_SQOS_FLAGS FileSQSFlag = 0x001F0000
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// GetFinalPathNameByHandle flags
 | 
			
		||||
//
 | 
			
		||||
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfinalpathnamebyhandlew#parameters
 | 
			
		||||
type GetFinalPathFlag uint32
 | 
			
		||||
 | 
			
		||||
//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
 | 
			
		||||
const (
 | 
			
		||||
	GetFinalPathDefaultFlag GetFinalPathFlag = 0x0
 | 
			
		||||
 | 
			
		||||
	FILE_NAME_NORMALIZED GetFinalPathFlag = 0x0
 | 
			
		||||
	FILE_NAME_OPENED     GetFinalPathFlag = 0x8
 | 
			
		||||
 | 
			
		||||
	VOLUME_NAME_DOS  GetFinalPathFlag = 0x0
 | 
			
		||||
	VOLUME_NAME_GUID GetFinalPathFlag = 0x1
 | 
			
		||||
	VOLUME_NAME_NT   GetFinalPathFlag = 0x2
 | 
			
		||||
	VOLUME_NAME_NONE GetFinalPathFlag = 0x4
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// getFinalPathNameByHandle facilitates calling the Windows API GetFinalPathNameByHandle
 | 
			
		||||
// with the given handle and flags. It transparently takes care of creating a buffer of the
 | 
			
		||||
// correct size for the call.
 | 
			
		||||
//
 | 
			
		||||
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfinalpathnamebyhandlew
 | 
			
		||||
func GetFinalPathNameByHandle(h windows.Handle, flags GetFinalPathFlag) (string, error) {
 | 
			
		||||
	b := stringbuffer.NewWString()
 | 
			
		||||
	//TODO: can loop infinitely if Win32 keeps returning the same (or a larger) n?
 | 
			
		||||
	for {
 | 
			
		||||
		n, err := windows.GetFinalPathNameByHandle(h, b.Pointer(), b.Cap(), uint32(flags))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return "", err
 | 
			
		||||
		}
 | 
			
		||||
		// If the buffer wasn't large enough, n will be the total size needed (including null terminator).
 | 
			
		||||
		// Resize and try again.
 | 
			
		||||
		if n > b.Cap() {
 | 
			
		||||
			b.ResizeTo(n)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		// If the buffer is large enough, n will be the size not including the null terminator.
 | 
			
		||||
		// Convert to a Go string and return.
 | 
			
		||||
		return b.String(), nil
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								vendor/github.com/Microsoft/go-winio/internal/fs/security.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/Microsoft/go-winio/internal/fs/security.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
package fs
 | 
			
		||||
 | 
			
		||||
// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-security_impersonation_level
 | 
			
		||||
type SecurityImpersonationLevel int32 // C default enums underlying type is `int`, which is Go `int32`
 | 
			
		||||
 | 
			
		||||
// Impersonation levels
 | 
			
		||||
const (
 | 
			
		||||
	SecurityAnonymous      SecurityImpersonationLevel = 0
 | 
			
		||||
	SecurityIdentification SecurityImpersonationLevel = 1
 | 
			
		||||
	SecurityImpersonation  SecurityImpersonationLevel = 2
 | 
			
		||||
	SecurityDelegation     SecurityImpersonationLevel = 3
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										64
									
								
								vendor/github.com/Microsoft/go-winio/internal/fs/zsyscall_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								vendor/github.com/Microsoft/go-winio/internal/fs/zsyscall_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
//go:build windows
 | 
			
		||||
 | 
			
		||||
// Code generated by 'go generate' using "github.com/Microsoft/go-winio/tools/mkwinsyscall"; DO NOT EDIT.
 | 
			
		||||
 | 
			
		||||
package fs
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"syscall"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/sys/windows"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var _ unsafe.Pointer
 | 
			
		||||
 | 
			
		||||
// Do the interface allocations only once for common
 | 
			
		||||
// Errno values.
 | 
			
		||||
const (
 | 
			
		||||
	errnoERROR_IO_PENDING = 997
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
 | 
			
		||||
	errERROR_EINVAL     error = syscall.EINVAL
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// errnoErr returns common boxed Errno values, to prevent
 | 
			
		||||
// allocations at runtime.
 | 
			
		||||
func errnoErr(e syscall.Errno) error {
 | 
			
		||||
	switch e {
 | 
			
		||||
	case 0:
 | 
			
		||||
		return errERROR_EINVAL
 | 
			
		||||
	case errnoERROR_IO_PENDING:
 | 
			
		||||
		return errERROR_IO_PENDING
 | 
			
		||||
	}
 | 
			
		||||
	// TODO: add more here, after collecting data on the common
 | 
			
		||||
	// error values see on Windows. (perhaps when running
 | 
			
		||||
	// all.bat?)
 | 
			
		||||
	return e
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
 | 
			
		||||
 | 
			
		||||
	procCreateFileW = modkernel32.NewProc("CreateFileW")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func CreateFile(name string, access AccessMask, mode FileShareMode, sa *syscall.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.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 AccessMask, mode FileShareMode, sa *syscall.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.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 = windows.Handle(r0)
 | 
			
		||||
	if handle == windows.InvalidHandle {
 | 
			
		||||
		err = errnoErr(e1)
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								vendor/github.com/Microsoft/go-winio/internal/socket/rawaddr.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								vendor/github.com/Microsoft/go-winio/internal/socket/rawaddr.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
package socket
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"unsafe"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// RawSockaddr allows structs to be used with [Bind] and [ConnectEx]. The
 | 
			
		||||
// struct must meet the Win32 sockaddr requirements specified here:
 | 
			
		||||
// https://docs.microsoft.com/en-us/windows/win32/winsock/sockaddr-2
 | 
			
		||||
//
 | 
			
		||||
// Specifically, the struct size must be least larger than an int16 (unsigned short)
 | 
			
		||||
// for the address family.
 | 
			
		||||
type RawSockaddr interface {
 | 
			
		||||
	// Sockaddr returns a pointer to the RawSockaddr and its struct size, allowing
 | 
			
		||||
	// for the RawSockaddr's data to be overwritten by syscalls (if necessary).
 | 
			
		||||
	//
 | 
			
		||||
	// It is the callers responsibility to validate that the values are valid; invalid
 | 
			
		||||
	// pointers or size can cause a panic.
 | 
			
		||||
	Sockaddr() (unsafe.Pointer, int32, error)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										179
									
								
								vendor/github.com/Microsoft/go-winio/internal/socket/socket.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								vendor/github.com/Microsoft/go-winio/internal/socket/socket.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,179 @@
 | 
			
		||||
//go:build windows
 | 
			
		||||
 | 
			
		||||
package socket
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"syscall"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
 | 
			
		||||
	"github.com/Microsoft/go-winio/pkg/guid"
 | 
			
		||||
	"golang.org/x/sys/windows"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//go:generate go run github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go socket.go
 | 
			
		||||
 | 
			
		||||
//sys getsockname(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) [failretval==socketError] = ws2_32.getsockname
 | 
			
		||||
//sys getpeername(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) [failretval==socketError] = ws2_32.getpeername
 | 
			
		||||
//sys bind(s windows.Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socketError] = ws2_32.bind
 | 
			
		||||
 | 
			
		||||
const socketError = uintptr(^uint32(0))
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// todo(helsaawy): create custom error types to store the desired vs actual size and addr family?
 | 
			
		||||
 | 
			
		||||
	ErrBufferSize     = errors.New("buffer size")
 | 
			
		||||
	ErrAddrFamily     = errors.New("address family")
 | 
			
		||||
	ErrInvalidPointer = errors.New("invalid pointer")
 | 
			
		||||
	ErrSocketClosed   = fmt.Errorf("socket closed: %w", net.ErrClosed)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// todo(helsaawy): replace these with generics, ie: GetSockName[S RawSockaddr](s windows.Handle) (S, error)
 | 
			
		||||
 | 
			
		||||
// GetSockName writes the local address of socket s to the [RawSockaddr] rsa.
 | 
			
		||||
// If rsa is not large enough, the [windows.WSAEFAULT] is returned.
 | 
			
		||||
func GetSockName(s windows.Handle, rsa RawSockaddr) error {
 | 
			
		||||
	ptr, l, err := rsa.Sockaddr()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("could not retrieve socket pointer and size: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// although getsockname returns WSAEFAULT if the buffer is too small, it does not set
 | 
			
		||||
	// &l to the correct size, so--apart from doubling the buffer repeatedly--there is no remedy
 | 
			
		||||
	return getsockname(s, ptr, &l)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetPeerName returns the remote address the socket is connected to.
 | 
			
		||||
//
 | 
			
		||||
// See [GetSockName] for more information.
 | 
			
		||||
func GetPeerName(s windows.Handle, rsa RawSockaddr) error {
 | 
			
		||||
	ptr, l, err := rsa.Sockaddr()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("could not retrieve socket pointer and size: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return getpeername(s, ptr, &l)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Bind(s windows.Handle, rsa RawSockaddr) (err error) {
 | 
			
		||||
	ptr, l, err := rsa.Sockaddr()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("could not retrieve socket pointer and size: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return bind(s, ptr, l)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// "golang.org/x/sys/windows".ConnectEx and .Bind only accept internal implementations of the
 | 
			
		||||
// their sockaddr interface, so they cannot be used with HvsockAddr
 | 
			
		||||
// Replicate functionality here from
 | 
			
		||||
// https://cs.opensource.google/go/x/sys/+/master:windows/syscall_windows.go
 | 
			
		||||
 | 
			
		||||
// The function pointers to `AcceptEx`, `ConnectEx` and `GetAcceptExSockaddrs` must be loaded at
 | 
			
		||||
// runtime via a WSAIoctl call:
 | 
			
		||||
// https://docs.microsoft.com/en-us/windows/win32/api/Mswsock/nc-mswsock-lpfn_connectex#remarks
 | 
			
		||||
 | 
			
		||||
type runtimeFunc struct {
 | 
			
		||||
	id   guid.GUID
 | 
			
		||||
	once sync.Once
 | 
			
		||||
	addr uintptr
 | 
			
		||||
	err  error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *runtimeFunc) Load() error {
 | 
			
		||||
	f.once.Do(func() {
 | 
			
		||||
		var s windows.Handle
 | 
			
		||||
		s, f.err = windows.Socket(windows.AF_INET, windows.SOCK_STREAM, windows.IPPROTO_TCP)
 | 
			
		||||
		if f.err != nil {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		defer windows.CloseHandle(s) //nolint:errcheck
 | 
			
		||||
 | 
			
		||||
		var n uint32
 | 
			
		||||
		f.err = windows.WSAIoctl(s,
 | 
			
		||||
			windows.SIO_GET_EXTENSION_FUNCTION_POINTER,
 | 
			
		||||
			(*byte)(unsafe.Pointer(&f.id)),
 | 
			
		||||
			uint32(unsafe.Sizeof(f.id)),
 | 
			
		||||
			(*byte)(unsafe.Pointer(&f.addr)),
 | 
			
		||||
			uint32(unsafe.Sizeof(f.addr)),
 | 
			
		||||
			&n,
 | 
			
		||||
			nil, // overlapped
 | 
			
		||||
			0,   // completionRoutine
 | 
			
		||||
		)
 | 
			
		||||
	})
 | 
			
		||||
	return f.err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// todo: add `AcceptEx` and `GetAcceptExSockaddrs`
 | 
			
		||||
	WSAID_CONNECTEX = guid.GUID{ //revive:disable-line:var-naming ALL_CAPS
 | 
			
		||||
		Data1: 0x25a207b9,
 | 
			
		||||
		Data2: 0xddf3,
 | 
			
		||||
		Data3: 0x4660,
 | 
			
		||||
		Data4: [8]byte{0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	connectExFunc = runtimeFunc{id: WSAID_CONNECTEX}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func ConnectEx(
 | 
			
		||||
	fd windows.Handle,
 | 
			
		||||
	rsa RawSockaddr,
 | 
			
		||||
	sendBuf *byte,
 | 
			
		||||
	sendDataLen uint32,
 | 
			
		||||
	bytesSent *uint32,
 | 
			
		||||
	overlapped *windows.Overlapped,
 | 
			
		||||
) error {
 | 
			
		||||
	if err := connectExFunc.Load(); err != nil {
 | 
			
		||||
		return fmt.Errorf("failed to load ConnectEx function pointer: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	ptr, n, err := rsa.Sockaddr()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return connectEx(fd, ptr, n, sendBuf, sendDataLen, bytesSent, overlapped)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BOOL LpfnConnectex(
 | 
			
		||||
//   [in]           SOCKET s,
 | 
			
		||||
//   [in]           const sockaddr *name,
 | 
			
		||||
//   [in]           int namelen,
 | 
			
		||||
//   [in, optional] PVOID lpSendBuffer,
 | 
			
		||||
//   [in]           DWORD dwSendDataLength,
 | 
			
		||||
//   [out]          LPDWORD lpdwBytesSent,
 | 
			
		||||
//   [in]           LPOVERLAPPED lpOverlapped
 | 
			
		||||
// )
 | 
			
		||||
 | 
			
		||||
func connectEx(
 | 
			
		||||
	s windows.Handle,
 | 
			
		||||
	name unsafe.Pointer,
 | 
			
		||||
	namelen int32,
 | 
			
		||||
	sendBuf *byte,
 | 
			
		||||
	sendDataLen uint32,
 | 
			
		||||
	bytesSent *uint32,
 | 
			
		||||
	overlapped *windows.Overlapped,
 | 
			
		||||
) (err error) {
 | 
			
		||||
	// todo: after upgrading to 1.18, switch from syscall.Syscall9 to syscall.SyscallN
 | 
			
		||||
	r1, _, e1 := syscall.Syscall9(connectExFunc.addr,
 | 
			
		||||
		7,
 | 
			
		||||
		uintptr(s),
 | 
			
		||||
		uintptr(name),
 | 
			
		||||
		uintptr(namelen),
 | 
			
		||||
		uintptr(unsafe.Pointer(sendBuf)),
 | 
			
		||||
		uintptr(sendDataLen),
 | 
			
		||||
		uintptr(unsafe.Pointer(bytesSent)),
 | 
			
		||||
		uintptr(unsafe.Pointer(overlapped)),
 | 
			
		||||
		0,
 | 
			
		||||
		0)
 | 
			
		||||
	if r1 == 0 {
 | 
			
		||||
		if e1 != 0 {
 | 
			
		||||
			err = error(e1)
 | 
			
		||||
		} else {
 | 
			
		||||
			err = syscall.EINVAL
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										72
									
								
								vendor/github.com/Microsoft/go-winio/internal/socket/zsyscall_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								vendor/github.com/Microsoft/go-winio/internal/socket/zsyscall_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
			
		||||
//go:build windows
 | 
			
		||||
 | 
			
		||||
// Code generated by 'go generate' using "github.com/Microsoft/go-winio/tools/mkwinsyscall"; DO NOT EDIT.
 | 
			
		||||
 | 
			
		||||
package socket
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"syscall"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/sys/windows"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var _ unsafe.Pointer
 | 
			
		||||
 | 
			
		||||
// Do the interface allocations only once for common
 | 
			
		||||
// Errno values.
 | 
			
		||||
const (
 | 
			
		||||
	errnoERROR_IO_PENDING = 997
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
 | 
			
		||||
	errERROR_EINVAL     error = syscall.EINVAL
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// errnoErr returns common boxed Errno values, to prevent
 | 
			
		||||
// allocations at runtime.
 | 
			
		||||
func errnoErr(e syscall.Errno) error {
 | 
			
		||||
	switch e {
 | 
			
		||||
	case 0:
 | 
			
		||||
		return errERROR_EINVAL
 | 
			
		||||
	case errnoERROR_IO_PENDING:
 | 
			
		||||
		return errERROR_IO_PENDING
 | 
			
		||||
	}
 | 
			
		||||
	// TODO: add more here, after collecting data on the common
 | 
			
		||||
	// error values see on Windows. (perhaps when running
 | 
			
		||||
	// all.bat?)
 | 
			
		||||
	return e
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	modws2_32 = windows.NewLazySystemDLL("ws2_32.dll")
 | 
			
		||||
 | 
			
		||||
	procbind        = modws2_32.NewProc("bind")
 | 
			
		||||
	procgetpeername = modws2_32.NewProc("getpeername")
 | 
			
		||||
	procgetsockname = modws2_32.NewProc("getsockname")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func bind(s windows.Handle, name unsafe.Pointer, namelen int32) (err error) {
 | 
			
		||||
	r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
 | 
			
		||||
	if r1 == socketError {
 | 
			
		||||
		err = errnoErr(e1)
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getpeername(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) {
 | 
			
		||||
	r1, _, e1 := syscall.Syscall(procgetpeername.Addr(), 3, uintptr(s), uintptr(name), uintptr(unsafe.Pointer(namelen)))
 | 
			
		||||
	if r1 == socketError {
 | 
			
		||||
		err = errnoErr(e1)
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getsockname(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) {
 | 
			
		||||
	r1, _, e1 := syscall.Syscall(procgetsockname.Addr(), 3, uintptr(s), uintptr(name), uintptr(unsafe.Pointer(namelen)))
 | 
			
		||||
	if r1 == socketError {
 | 
			
		||||
		err = errnoErr(e1)
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										132
									
								
								vendor/github.com/Microsoft/go-winio/internal/stringbuffer/wstring.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								vendor/github.com/Microsoft/go-winio/internal/stringbuffer/wstring.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,132 @@
 | 
			
		||||
package stringbuffer
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"sync"
 | 
			
		||||
	"unicode/utf16"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// TODO: worth exporting and using in mkwinsyscall?
 | 
			
		||||
 | 
			
		||||
// Uint16BufferSize is the buffer size in the pool, chosen somewhat arbitrarily to accommodate
 | 
			
		||||
// large path strings:
 | 
			
		||||
// MAX_PATH (260) + size of volume GUID prefix (49) + null terminator = 310.
 | 
			
		||||
const MinWStringCap = 310
 | 
			
		||||
 | 
			
		||||
// use *[]uint16 since []uint16 creates an extra allocation where the slice header
 | 
			
		||||
// is copied to heap and then referenced via pointer in the interface header that sync.Pool
 | 
			
		||||
// stores.
 | 
			
		||||
var pathPool = sync.Pool{ // if go1.18+ adds Pool[T], use that to store []uint16 directly
 | 
			
		||||
	New: func() interface{} {
 | 
			
		||||
		b := make([]uint16, MinWStringCap)
 | 
			
		||||
		return &b
 | 
			
		||||
	},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newBuffer() []uint16 { return *(pathPool.Get().(*[]uint16)) }
 | 
			
		||||
 | 
			
		||||
// freeBuffer copies the slice header data, and puts a pointer to that in the pool.
 | 
			
		||||
// This avoids taking a pointer to the slice header in WString, which can be set to nil.
 | 
			
		||||
func freeBuffer(b []uint16) { pathPool.Put(&b) }
 | 
			
		||||
 | 
			
		||||
// WString is a wide string buffer ([]uint16) meant for storing UTF-16 encoded strings
 | 
			
		||||
// for interacting with Win32 APIs.
 | 
			
		||||
// Sizes are specified as uint32 and not int.
 | 
			
		||||
//
 | 
			
		||||
// It is not thread safe.
 | 
			
		||||
type WString struct {
 | 
			
		||||
	// type-def allows casting to []uint16 directly, use struct to prevent that and allow adding fields in the future.
 | 
			
		||||
 | 
			
		||||
	// raw buffer
 | 
			
		||||
	b []uint16
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewWString returns a [WString] allocated from a shared pool with an
 | 
			
		||||
// initial capacity of at least [MinWStringCap].
 | 
			
		||||
// Since the buffer may have been previously used, its contents are not guaranteed to be empty.
 | 
			
		||||
//
 | 
			
		||||
// The buffer should be freed via [WString.Free]
 | 
			
		||||
func NewWString() *WString {
 | 
			
		||||
	return &WString{
 | 
			
		||||
		b: newBuffer(),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *WString) Free() {
 | 
			
		||||
	if b.empty() {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	freeBuffer(b.b)
 | 
			
		||||
	b.b = nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ResizeTo grows the buffer to at least c and returns the new capacity, freeing the
 | 
			
		||||
// previous buffer back into pool.
 | 
			
		||||
func (b *WString) ResizeTo(c uint32) uint32 {
 | 
			
		||||
	// allready sufficient (or n is 0)
 | 
			
		||||
	if c <= b.Cap() {
 | 
			
		||||
		return b.Cap()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if c <= MinWStringCap {
 | 
			
		||||
		c = MinWStringCap
 | 
			
		||||
	}
 | 
			
		||||
	// allocate at-least double buffer size, as is done in [bytes.Buffer] and other places
 | 
			
		||||
	if c <= 2*b.Cap() {
 | 
			
		||||
		c = 2 * b.Cap()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	b2 := make([]uint16, c)
 | 
			
		||||
	if !b.empty() {
 | 
			
		||||
		copy(b2, b.b)
 | 
			
		||||
		freeBuffer(b.b)
 | 
			
		||||
	}
 | 
			
		||||
	b.b = b2
 | 
			
		||||
	return c
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Buffer returns the underlying []uint16 buffer.
 | 
			
		||||
func (b *WString) Buffer() []uint16 {
 | 
			
		||||
	if b.empty() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	return b.b
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Pointer returns a pointer to the first uint16 in the buffer.
 | 
			
		||||
// If the [WString.Free] has already been called, the pointer will be nil.
 | 
			
		||||
func (b *WString) Pointer() *uint16 {
 | 
			
		||||
	if b.empty() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	return &b.b[0]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String returns the returns the UTF-8 encoding of the UTF-16 string in the buffer.
 | 
			
		||||
//
 | 
			
		||||
// It assumes that the data is null-terminated.
 | 
			
		||||
func (b *WString) String() string {
 | 
			
		||||
	// Using [windows.UTF16ToString] would require importing "golang.org/x/sys/windows"
 | 
			
		||||
	// and would make this code Windows-only, which makes no sense.
 | 
			
		||||
	// So copy UTF16ToString code into here.
 | 
			
		||||
	// If other windows-specific code is added, switch to [windows.UTF16ToString]
 | 
			
		||||
 | 
			
		||||
	s := b.b
 | 
			
		||||
	for i, v := range s {
 | 
			
		||||
		if v == 0 {
 | 
			
		||||
			s = s[:i]
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return string(utf16.Decode(s))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Cap returns the underlying buffer capacity.
 | 
			
		||||
func (b *WString) Cap() uint32 {
 | 
			
		||||
	if b.empty() {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	return b.cap()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *WString) cap() uint32 { return uint32(cap(b.b)) }
 | 
			
		||||
func (b *WString) empty() bool { return b == nil || b.cap() == 0 }
 | 
			
		||||
							
								
								
									
										312
									
								
								vendor/github.com/Microsoft/go-winio/pipe.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										312
									
								
								vendor/github.com/Microsoft/go-winio/pipe.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,51 +1,76 @@
 | 
			
		||||
//go:build windows
 | 
			
		||||
// +build windows
 | 
			
		||||
 | 
			
		||||
package winio
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"net"
 | 
			
		||||
	"os"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"syscall"
 | 
			
		||||
	"time"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/sys/windows"
 | 
			
		||||
 | 
			
		||||
	"github.com/Microsoft/go-winio/internal/fs"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//sys connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) = ConnectNamedPipe
 | 
			
		||||
//sys createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error)  [failretval==syscall.InvalidHandle] = CreateNamedPipeW
 | 
			
		||||
//sys createFile(name string, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateFileW
 | 
			
		||||
//sys getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo
 | 
			
		||||
//sys getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW
 | 
			
		||||
//sys localAlloc(uFlags uint32, length uint32) (ptr uintptr) = LocalAlloc
 | 
			
		||||
//sys 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) = ntdll.NtCreateNamedPipeFile
 | 
			
		||||
//sys rtlNtStatusToDosError(status ntStatus) (winerr error) = ntdll.RtlNtStatusToDosErrorNoTeb
 | 
			
		||||
//sys rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntStatus) = ntdll.RtlDosPathNameToNtPathName_U
 | 
			
		||||
//sys rtlDefaultNpAcl(dacl *uintptr) (status ntStatus) = ntdll.RtlDefaultNpAcl
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	cERROR_PIPE_BUSY      = syscall.Errno(231)
 | 
			
		||||
	cERROR_NO_DATA        = syscall.Errno(232)
 | 
			
		||||
	cERROR_PIPE_CONNECTED = syscall.Errno(535)
 | 
			
		||||
	cERROR_SEM_TIMEOUT    = syscall.Errno(121)
 | 
			
		||||
type ioStatusBlock struct {
 | 
			
		||||
	Status, Information uintptr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	cPIPE_ACCESS_DUPLEX            = 0x3
 | 
			
		||||
	cFILE_FLAG_FIRST_PIPE_INSTANCE = 0x80000
 | 
			
		||||
	cSECURITY_SQOS_PRESENT         = 0x100000
 | 
			
		||||
	cSECURITY_ANONYMOUS            = 0
 | 
			
		||||
type objectAttributes struct {
 | 
			
		||||
	Length             uintptr
 | 
			
		||||
	RootDirectory      uintptr
 | 
			
		||||
	ObjectName         *unicodeString
 | 
			
		||||
	Attributes         uintptr
 | 
			
		||||
	SecurityDescriptor *securityDescriptor
 | 
			
		||||
	SecurityQoS        uintptr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	cPIPE_REJECT_REMOTE_CLIENTS = 0x8
 | 
			
		||||
type unicodeString struct {
 | 
			
		||||
	Length        uint16
 | 
			
		||||
	MaximumLength uint16
 | 
			
		||||
	Buffer        uintptr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	cPIPE_UNLIMITED_INSTANCES = 255
 | 
			
		||||
type securityDescriptor struct {
 | 
			
		||||
	Revision byte
 | 
			
		||||
	Sbz1     byte
 | 
			
		||||
	Control  uint16
 | 
			
		||||
	Owner    uintptr
 | 
			
		||||
	Group    uintptr
 | 
			
		||||
	Sacl     uintptr //revive:disable-line:var-naming SACL, not Sacl
 | 
			
		||||
	Dacl     uintptr //revive:disable-line:var-naming DACL, not Dacl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	cNMPWAIT_USE_DEFAULT_WAIT = 0
 | 
			
		||||
	cNMPWAIT_NOWAIT           = 1
 | 
			
		||||
type ntStatus int32
 | 
			
		||||
 | 
			
		||||
	cPIPE_TYPE_MESSAGE = 4
 | 
			
		||||
 | 
			
		||||
	cPIPE_READMODE_MESSAGE = 2
 | 
			
		||||
)
 | 
			
		||||
func (status ntStatus) Err() error {
 | 
			
		||||
	if status >= 0 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	return rtlNtStatusToDosError(status)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// ErrPipeListenerClosed is returned for pipe operations on listeners that have been closed.
 | 
			
		||||
	// This error should match net.errClosing since docker takes a dependency on its text.
 | 
			
		||||
	ErrPipeListenerClosed = errors.New("use of closed network connection")
 | 
			
		||||
	ErrPipeListenerClosed = net.ErrClosed
 | 
			
		||||
 | 
			
		||||
	errPipeWriteClosed = errors.New("pipe has been closed for write")
 | 
			
		||||
)
 | 
			
		||||
@@ -72,9 +97,10 @@ func (f *win32Pipe) RemoteAddr() net.Addr {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *win32Pipe) SetDeadline(t time.Time) error {
 | 
			
		||||
	f.SetReadDeadline(t)
 | 
			
		||||
	f.SetWriteDeadline(t)
 | 
			
		||||
	return nil
 | 
			
		||||
	if err := f.SetReadDeadline(t); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return f.SetWriteDeadline(t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CloseWrite closes the write side of a message pipe in byte mode.
 | 
			
		||||
@@ -113,14 +139,14 @@ func (f *win32MessageBytePipe) Read(b []byte) (int, error) {
 | 
			
		||||
		return 0, io.EOF
 | 
			
		||||
	}
 | 
			
		||||
	n, err := f.win32File.Read(b)
 | 
			
		||||
	if err == io.EOF {
 | 
			
		||||
	if err == io.EOF { //nolint:errorlint
 | 
			
		||||
		// If this was the result of a zero-byte read, then
 | 
			
		||||
		// it is possible that the read was due to a zero-size
 | 
			
		||||
		// message. Since we are simulating CloseWrite with a
 | 
			
		||||
		// zero-byte message, ensure that all future Read() calls
 | 
			
		||||
		// also return EOF.
 | 
			
		||||
		f.readEOF = true
 | 
			
		||||
	} else if err == syscall.ERROR_MORE_DATA {
 | 
			
		||||
	} else if err == syscall.ERROR_MORE_DATA { //nolint:errorlint // err is Errno
 | 
			
		||||
		// ERROR_MORE_DATA indicates that the pipe's read mode is message mode
 | 
			
		||||
		// and the message still has more bytes. Treat this as a success, since
 | 
			
		||||
		// this package presents all named pipes as byte streams.
 | 
			
		||||
@@ -129,7 +155,7 @@ func (f *win32MessageBytePipe) Read(b []byte) (int, error) {
 | 
			
		||||
	return n, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s pipeAddress) Network() string {
 | 
			
		||||
func (pipeAddress) Network() string {
 | 
			
		||||
	return "pipe"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -137,33 +163,68 @@ func (s pipeAddress) String() string {
 | 
			
		||||
	return string(s)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// tryDialPipe attempts to dial the pipe at `path` until `ctx` cancellation or timeout.
 | 
			
		||||
func tryDialPipe(ctx context.Context, path *string, access fs.AccessMask) (syscall.Handle, error) {
 | 
			
		||||
	for {
 | 
			
		||||
		select {
 | 
			
		||||
		case <-ctx.Done():
 | 
			
		||||
			return syscall.Handle(0), ctx.Err()
 | 
			
		||||
		default:
 | 
			
		||||
			wh, err := fs.CreateFile(*path,
 | 
			
		||||
				access,
 | 
			
		||||
				0,   // mode
 | 
			
		||||
				nil, // security attributes
 | 
			
		||||
				fs.OPEN_EXISTING,
 | 
			
		||||
				fs.FILE_FLAG_OVERLAPPED|fs.SECURITY_SQOS_PRESENT|fs.SECURITY_ANONYMOUS,
 | 
			
		||||
				0, // template file handle
 | 
			
		||||
			)
 | 
			
		||||
			h := syscall.Handle(wh)
 | 
			
		||||
			if err == nil {
 | 
			
		||||
				return h, nil
 | 
			
		||||
			}
 | 
			
		||||
			if err != windows.ERROR_PIPE_BUSY { //nolint:errorlint // err is Errno
 | 
			
		||||
				return h, &os.PathError{Err: err, Op: "open", Path: *path}
 | 
			
		||||
			}
 | 
			
		||||
			// Wait 10 msec and try again. This is a rather simplistic
 | 
			
		||||
			// view, as we always try each 10 milliseconds.
 | 
			
		||||
			time.Sleep(10 * time.Millisecond)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DialPipe connects to a named pipe by path, timing out if the connection
 | 
			
		||||
// takes longer than the specified duration. If timeout is nil, then we use
 | 
			
		||||
// a default timeout of 5 seconds.  (We do not use WaitNamedPipe.)
 | 
			
		||||
// a default timeout of 2 seconds.  (We do not use WaitNamedPipe.)
 | 
			
		||||
func DialPipe(path string, timeout *time.Duration) (net.Conn, error) {
 | 
			
		||||
	var absTimeout time.Time
 | 
			
		||||
	if timeout != nil {
 | 
			
		||||
		absTimeout = time.Now().Add(*timeout)
 | 
			
		||||
	} else {
 | 
			
		||||
		absTimeout = time.Now().Add(time.Second * 2)
 | 
			
		||||
		absTimeout = time.Now().Add(2 * time.Second)
 | 
			
		||||
	}
 | 
			
		||||
	ctx, cancel := context.WithDeadline(context.Background(), absTimeout)
 | 
			
		||||
	defer cancel()
 | 
			
		||||
	conn, err := DialPipeContext(ctx, path)
 | 
			
		||||
	if errors.Is(err, context.DeadlineExceeded) {
 | 
			
		||||
		return nil, ErrTimeout
 | 
			
		||||
	}
 | 
			
		||||
	return conn, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DialPipeContext attempts to connect to a named pipe by `path` until `ctx`
 | 
			
		||||
// cancellation or timeout.
 | 
			
		||||
func DialPipeContext(ctx context.Context, path string) (net.Conn, error) {
 | 
			
		||||
	return DialPipeAccess(ctx, path, syscall.GENERIC_READ|syscall.GENERIC_WRITE)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DialPipeAccess attempts to connect to a named pipe by `path` with `access` until `ctx`
 | 
			
		||||
// cancellation or timeout.
 | 
			
		||||
func DialPipeAccess(ctx context.Context, path string, access uint32) (net.Conn, error) {
 | 
			
		||||
	var err error
 | 
			
		||||
	var h syscall.Handle
 | 
			
		||||
	for {
 | 
			
		||||
		h, err = createFile(path, syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_OVERLAPPED|cSECURITY_SQOS_PRESENT|cSECURITY_ANONYMOUS, 0)
 | 
			
		||||
		if err != cERROR_PIPE_BUSY {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		if time.Now().After(absTimeout) {
 | 
			
		||||
			return nil, ErrTimeout
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Wait 10 msec and try again. This is a rather simplistic
 | 
			
		||||
		// view, as we always try each 10 milliseconds.
 | 
			
		||||
		time.Sleep(time.Millisecond * 10)
 | 
			
		||||
	}
 | 
			
		||||
	h, err = tryDialPipe(ctx, &path, fs.AccessMask(access))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, &os.PathError{Op: "open", Path: path, Err: err}
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var flags uint32
 | 
			
		||||
@@ -180,7 +241,7 @@ func DialPipe(path string, timeout *time.Duration) (net.Conn, error) {
 | 
			
		||||
 | 
			
		||||
	// If the pipe is in message mode, return a message byte pipe, which
 | 
			
		||||
	// supports CloseWrite().
 | 
			
		||||
	if flags&cPIPE_TYPE_MESSAGE != 0 {
 | 
			
		||||
	if flags&windows.PIPE_TYPE_MESSAGE != 0 {
 | 
			
		||||
		return &win32MessageBytePipe{
 | 
			
		||||
			win32Pipe: win32Pipe{win32File: f, path: path},
 | 
			
		||||
		}, nil
 | 
			
		||||
@@ -194,43 +255,105 @@ type acceptResponse struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type win32PipeListener struct {
 | 
			
		||||
	firstHandle        syscall.Handle
 | 
			
		||||
	path               string
 | 
			
		||||
	securityDescriptor []byte
 | 
			
		||||
	config             PipeConfig
 | 
			
		||||
	acceptCh           chan (chan acceptResponse)
 | 
			
		||||
	closeCh            chan int
 | 
			
		||||
	doneCh             chan int
 | 
			
		||||
	firstHandle syscall.Handle
 | 
			
		||||
	path        string
 | 
			
		||||
	config      PipeConfig
 | 
			
		||||
	acceptCh    chan (chan acceptResponse)
 | 
			
		||||
	closeCh     chan int
 | 
			
		||||
	doneCh      chan int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func makeServerPipeHandle(path string, securityDescriptor []byte, c *PipeConfig, first bool) (syscall.Handle, error) {
 | 
			
		||||
	var flags uint32 = cPIPE_ACCESS_DUPLEX | syscall.FILE_FLAG_OVERLAPPED
 | 
			
		||||
	if first {
 | 
			
		||||
		flags |= cFILE_FLAG_FIRST_PIPE_INSTANCE
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var mode uint32 = cPIPE_REJECT_REMOTE_CLIENTS
 | 
			
		||||
	if c.MessageMode {
 | 
			
		||||
		mode |= cPIPE_TYPE_MESSAGE
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sa := &syscall.SecurityAttributes{}
 | 
			
		||||
	sa.Length = uint32(unsafe.Sizeof(*sa))
 | 
			
		||||
	if securityDescriptor != nil {
 | 
			
		||||
		len := uint32(len(securityDescriptor))
 | 
			
		||||
		sa.SecurityDescriptor = localAlloc(0, len)
 | 
			
		||||
		defer localFree(sa.SecurityDescriptor)
 | 
			
		||||
		copy((*[0xffff]byte)(unsafe.Pointer(sa.SecurityDescriptor))[:], securityDescriptor)
 | 
			
		||||
	}
 | 
			
		||||
	h, err := createNamedPipe(path, flags, mode, cPIPE_UNLIMITED_INSTANCES, uint32(c.OutputBufferSize), uint32(c.InputBufferSize), 0, sa)
 | 
			
		||||
func makeServerPipeHandle(path string, sd []byte, c *PipeConfig, first bool) (syscall.Handle, error) {
 | 
			
		||||
	path16, err := syscall.UTF16FromString(path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, &os.PathError{Op: "open", Path: path, Err: err}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var oa objectAttributes
 | 
			
		||||
	oa.Length = unsafe.Sizeof(oa)
 | 
			
		||||
 | 
			
		||||
	var ntPath unicodeString
 | 
			
		||||
	if err := rtlDosPathNameToNtPathName(&path16[0],
 | 
			
		||||
		&ntPath,
 | 
			
		||||
		0,
 | 
			
		||||
		0,
 | 
			
		||||
	).Err(); err != nil {
 | 
			
		||||
		return 0, &os.PathError{Op: "open", Path: path, Err: err}
 | 
			
		||||
	}
 | 
			
		||||
	defer localFree(ntPath.Buffer)
 | 
			
		||||
	oa.ObjectName = &ntPath
 | 
			
		||||
	oa.Attributes = windows.OBJ_CASE_INSENSITIVE
 | 
			
		||||
 | 
			
		||||
	// The security descriptor is only needed for the first pipe.
 | 
			
		||||
	if first {
 | 
			
		||||
		if sd != nil {
 | 
			
		||||
			l := uint32(len(sd))
 | 
			
		||||
			sdb := localAlloc(0, l)
 | 
			
		||||
			defer localFree(sdb)
 | 
			
		||||
			copy((*[0xffff]byte)(unsafe.Pointer(sdb))[:], sd)
 | 
			
		||||
			oa.SecurityDescriptor = (*securityDescriptor)(unsafe.Pointer(sdb))
 | 
			
		||||
		} else {
 | 
			
		||||
			// Construct the default named pipe security descriptor.
 | 
			
		||||
			var dacl uintptr
 | 
			
		||||
			if err := rtlDefaultNpAcl(&dacl).Err(); err != nil {
 | 
			
		||||
				return 0, fmt.Errorf("getting default named pipe ACL: %w", err)
 | 
			
		||||
			}
 | 
			
		||||
			defer localFree(dacl)
 | 
			
		||||
 | 
			
		||||
			sdb := &securityDescriptor{
 | 
			
		||||
				Revision: 1,
 | 
			
		||||
				Control:  windows.SE_DACL_PRESENT,
 | 
			
		||||
				Dacl:     dacl,
 | 
			
		||||
			}
 | 
			
		||||
			oa.SecurityDescriptor = sdb
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	typ := uint32(windows.FILE_PIPE_REJECT_REMOTE_CLIENTS)
 | 
			
		||||
	if c.MessageMode {
 | 
			
		||||
		typ |= windows.FILE_PIPE_MESSAGE_TYPE
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	disposition := uint32(windows.FILE_OPEN)
 | 
			
		||||
	access := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE | syscall.SYNCHRONIZE)
 | 
			
		||||
	if first {
 | 
			
		||||
		disposition = windows.FILE_CREATE
 | 
			
		||||
		// By not asking for read or write access, the named pipe file system
 | 
			
		||||
		// will put this pipe into an initially disconnected state, blocking
 | 
			
		||||
		// client connections until the next call with first == false.
 | 
			
		||||
		access = syscall.SYNCHRONIZE
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	timeout := int64(-50 * 10000) // 50ms
 | 
			
		||||
 | 
			
		||||
	var (
 | 
			
		||||
		h    syscall.Handle
 | 
			
		||||
		iosb ioStatusBlock
 | 
			
		||||
	)
 | 
			
		||||
	err = ntCreateNamedPipeFile(&h,
 | 
			
		||||
		access,
 | 
			
		||||
		&oa,
 | 
			
		||||
		&iosb,
 | 
			
		||||
		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE,
 | 
			
		||||
		disposition,
 | 
			
		||||
		0,
 | 
			
		||||
		typ,
 | 
			
		||||
		0,
 | 
			
		||||
		0,
 | 
			
		||||
		0xffffffff,
 | 
			
		||||
		uint32(c.InputBufferSize),
 | 
			
		||||
		uint32(c.OutputBufferSize),
 | 
			
		||||
		&timeout).Err()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, &os.PathError{Op: "open", Path: path, Err: err}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	runtime.KeepAlive(ntPath)
 | 
			
		||||
	return h, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *win32PipeListener) makeServerPipe() (*win32File, error) {
 | 
			
		||||
	h, err := makeServerPipeHandle(l.path, l.securityDescriptor, &l.config, false)
 | 
			
		||||
	h, err := makeServerPipeHandle(l.path, nil, &l.config, false)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
@@ -265,7 +388,7 @@ func (l *win32PipeListener) makeConnectedServerPipe() (*win32File, error) {
 | 
			
		||||
		p.Close()
 | 
			
		||||
		p = nil
 | 
			
		||||
		err = <-ch
 | 
			
		||||
		if err == nil || err == ErrFileClosed {
 | 
			
		||||
		if err == nil || err == ErrFileClosed { //nolint:errorlint // err is Errno
 | 
			
		||||
			err = ErrPipeListenerClosed
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -287,12 +410,12 @@ func (l *win32PipeListener) listenerRoutine() {
 | 
			
		||||
				p, err = l.makeConnectedServerPipe()
 | 
			
		||||
				// If the connection was immediately closed by the client, try
 | 
			
		||||
				// again.
 | 
			
		||||
				if err != cERROR_NO_DATA {
 | 
			
		||||
				if err != windows.ERROR_NO_DATA { //nolint:errorlint // err is Errno
 | 
			
		||||
					break
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			responseCh <- acceptResponse{p, err}
 | 
			
		||||
			closed = err == ErrPipeListenerClosed
 | 
			
		||||
			closed = err == ErrPipeListenerClosed //nolint:errorlint // err is Errno
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	syscall.Close(l.firstHandle)
 | 
			
		||||
@@ -314,10 +437,10 @@ type PipeConfig struct {
 | 
			
		||||
	// when the pipe is in message mode.
 | 
			
		||||
	MessageMode bool
 | 
			
		||||
 | 
			
		||||
	// InputBufferSize specifies the size the input buffer, in bytes.
 | 
			
		||||
	// InputBufferSize specifies the size of the input buffer, in bytes.
 | 
			
		||||
	InputBufferSize int32
 | 
			
		||||
 | 
			
		||||
	// OutputBufferSize specifies the size the input buffer, in bytes.
 | 
			
		||||
	// OutputBufferSize specifies the size of the output buffer, in bytes.
 | 
			
		||||
	OutputBufferSize int32
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -341,47 +464,28 @@ func ListenPipe(path string, c *PipeConfig) (net.Listener, error) {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	// Create a client handle and connect it.  This results in the pipe
 | 
			
		||||
	// instance always existing, so that clients see ERROR_PIPE_BUSY
 | 
			
		||||
	// rather than ERROR_FILE_NOT_FOUND.  This ties the first instance
 | 
			
		||||
	// up so that no other instances can be used.  This would have been
 | 
			
		||||
	// cleaner if the Win32 API matched CreateFile with ConnectNamedPipe
 | 
			
		||||
	// instead of CreateNamedPipe.  (Apparently created named pipes are
 | 
			
		||||
	// considered to be in listening state regardless of whether any
 | 
			
		||||
	// active calls to ConnectNamedPipe are outstanding.)
 | 
			
		||||
	h2, err := createFile(path, 0, 0, nil, syscall.OPEN_EXISTING, cSECURITY_SQOS_PRESENT|cSECURITY_ANONYMOUS, 0)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		syscall.Close(h)
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	// Close the client handle. The server side of the instance will
 | 
			
		||||
	// still be busy, leading to ERROR_PIPE_BUSY instead of
 | 
			
		||||
	// ERROR_NOT_FOUND, as long as we don't close the server handle,
 | 
			
		||||
	// or disconnect the client with DisconnectNamedPipe.
 | 
			
		||||
	syscall.Close(h2)
 | 
			
		||||
	l := &win32PipeListener{
 | 
			
		||||
		firstHandle:        h,
 | 
			
		||||
		path:               path,
 | 
			
		||||
		securityDescriptor: sd,
 | 
			
		||||
		config:             *c,
 | 
			
		||||
		acceptCh:           make(chan (chan acceptResponse)),
 | 
			
		||||
		closeCh:            make(chan int),
 | 
			
		||||
		doneCh:             make(chan int),
 | 
			
		||||
		firstHandle: h,
 | 
			
		||||
		path:        path,
 | 
			
		||||
		config:      *c,
 | 
			
		||||
		acceptCh:    make(chan (chan acceptResponse)),
 | 
			
		||||
		closeCh:     make(chan int),
 | 
			
		||||
		doneCh:      make(chan int),
 | 
			
		||||
	}
 | 
			
		||||
	go l.listenerRoutine()
 | 
			
		||||
	return l, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func connectPipe(p *win32File) error {
 | 
			
		||||
	c, err := p.prepareIo()
 | 
			
		||||
	c, err := p.prepareIO()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	defer p.wg.Done()
 | 
			
		||||
 | 
			
		||||
	err = connectNamedPipe(p.handle, &c.o)
 | 
			
		||||
	_, err = p.asyncIo(c, nil, 0, err)
 | 
			
		||||
	if err != nil && err != cERROR_PIPE_CONNECTED {
 | 
			
		||||
	_, err = p.asyncIO(c, nil, 0, err)
 | 
			
		||||
	if err != nil && err != windows.ERROR_PIPE_CONNECTED { //nolint:errorlint // err is Errno
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										232
									
								
								vendor/github.com/Microsoft/go-winio/pkg/guid/guid.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										232
									
								
								vendor/github.com/Microsoft/go-winio/pkg/guid/guid.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,232 @@
 | 
			
		||||
// Package guid provides a GUID type. The backing structure for a GUID is
 | 
			
		||||
// identical to that used by the golang.org/x/sys/windows GUID type.
 | 
			
		||||
// There are two main binary encodings used for a GUID, the big-endian encoding,
 | 
			
		||||
// and the Windows (mixed-endian) encoding. See here for details:
 | 
			
		||||
// https://en.wikipedia.org/wiki/Universally_unique_identifier#Encoding
 | 
			
		||||
package guid
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"crypto/rand"
 | 
			
		||||
	"crypto/sha1" //nolint:gosec // not used for secure application
 | 
			
		||||
	"encoding"
 | 
			
		||||
	"encoding/binary"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strconv"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//go:generate go run golang.org/x/tools/cmd/stringer -type=Variant -trimprefix=Variant -linecomment
 | 
			
		||||
 | 
			
		||||
// Variant specifies which GUID variant (or "type") of the GUID. It determines
 | 
			
		||||
// how the entirety of the rest of the GUID is interpreted.
 | 
			
		||||
type Variant uint8
 | 
			
		||||
 | 
			
		||||
// The variants specified by RFC 4122 section 4.1.1.
 | 
			
		||||
const (
 | 
			
		||||
	// VariantUnknown specifies a GUID variant which does not conform to one of
 | 
			
		||||
	// the variant encodings specified in RFC 4122.
 | 
			
		||||
	VariantUnknown Variant = iota
 | 
			
		||||
	VariantNCS
 | 
			
		||||
	VariantRFC4122 // RFC 4122
 | 
			
		||||
	VariantMicrosoft
 | 
			
		||||
	VariantFuture
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Version specifies how the bits in the GUID were generated. For instance, a
 | 
			
		||||
// version 4 GUID is randomly generated, and a version 5 is generated from the
 | 
			
		||||
// hash of an input string.
 | 
			
		||||
type Version uint8
 | 
			
		||||
 | 
			
		||||
func (v Version) String() string {
 | 
			
		||||
	return strconv.FormatUint(uint64(v), 10)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ = (encoding.TextMarshaler)(GUID{})
 | 
			
		||||
var _ = (encoding.TextUnmarshaler)(&GUID{})
 | 
			
		||||
 | 
			
		||||
// NewV4 returns a new version 4 (pseudorandom) GUID, as defined by RFC 4122.
 | 
			
		||||
func NewV4() (GUID, error) {
 | 
			
		||||
	var b [16]byte
 | 
			
		||||
	if _, err := rand.Read(b[:]); err != nil {
 | 
			
		||||
		return GUID{}, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g := FromArray(b)
 | 
			
		||||
	g.setVersion(4) // Version 4 means randomly generated.
 | 
			
		||||
	g.setVariant(VariantRFC4122)
 | 
			
		||||
 | 
			
		||||
	return g, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewV5 returns a new version 5 (generated from a string via SHA-1 hashing)
 | 
			
		||||
// GUID, as defined by RFC 4122. The RFC is unclear on the encoding of the name,
 | 
			
		||||
// and the sample code treats it as a series of bytes, so we do the same here.
 | 
			
		||||
//
 | 
			
		||||
// Some implementations, such as those found on Windows, treat the name as a
 | 
			
		||||
// big-endian UTF16 stream of bytes. If that is desired, the string can be
 | 
			
		||||
// encoded as such before being passed to this function.
 | 
			
		||||
func NewV5(namespace GUID, name []byte) (GUID, error) {
 | 
			
		||||
	b := sha1.New() //nolint:gosec // not used for secure application
 | 
			
		||||
	namespaceBytes := namespace.ToArray()
 | 
			
		||||
	b.Write(namespaceBytes[:])
 | 
			
		||||
	b.Write(name)
 | 
			
		||||
 | 
			
		||||
	a := [16]byte{}
 | 
			
		||||
	copy(a[:], b.Sum(nil))
 | 
			
		||||
 | 
			
		||||
	g := FromArray(a)
 | 
			
		||||
	g.setVersion(5) // Version 5 means generated from a string.
 | 
			
		||||
	g.setVariant(VariantRFC4122)
 | 
			
		||||
 | 
			
		||||
	return g, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func fromArray(b [16]byte, order binary.ByteOrder) GUID {
 | 
			
		||||
	var g GUID
 | 
			
		||||
	g.Data1 = order.Uint32(b[0:4])
 | 
			
		||||
	g.Data2 = order.Uint16(b[4:6])
 | 
			
		||||
	g.Data3 = order.Uint16(b[6:8])
 | 
			
		||||
	copy(g.Data4[:], b[8:16])
 | 
			
		||||
	return g
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (g GUID) toArray(order binary.ByteOrder) [16]byte {
 | 
			
		||||
	b := [16]byte{}
 | 
			
		||||
	order.PutUint32(b[0:4], g.Data1)
 | 
			
		||||
	order.PutUint16(b[4:6], g.Data2)
 | 
			
		||||
	order.PutUint16(b[6:8], g.Data3)
 | 
			
		||||
	copy(b[8:16], g.Data4[:])
 | 
			
		||||
	return b
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FromArray constructs a GUID from a big-endian encoding array of 16 bytes.
 | 
			
		||||
func FromArray(b [16]byte) GUID {
 | 
			
		||||
	return fromArray(b, binary.BigEndian)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ToArray returns an array of 16 bytes representing the GUID in big-endian
 | 
			
		||||
// encoding.
 | 
			
		||||
func (g GUID) ToArray() [16]byte {
 | 
			
		||||
	return g.toArray(binary.BigEndian)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FromWindowsArray constructs a GUID from a Windows encoding array of bytes.
 | 
			
		||||
func FromWindowsArray(b [16]byte) GUID {
 | 
			
		||||
	return fromArray(b, binary.LittleEndian)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ToWindowsArray returns an array of 16 bytes representing the GUID in Windows
 | 
			
		||||
// encoding.
 | 
			
		||||
func (g GUID) ToWindowsArray() [16]byte {
 | 
			
		||||
	return g.toArray(binary.LittleEndian)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (g GUID) String() string {
 | 
			
		||||
	return fmt.Sprintf(
 | 
			
		||||
		"%08x-%04x-%04x-%04x-%012x",
 | 
			
		||||
		g.Data1,
 | 
			
		||||
		g.Data2,
 | 
			
		||||
		g.Data3,
 | 
			
		||||
		g.Data4[:2],
 | 
			
		||||
		g.Data4[2:])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FromString parses a string containing a GUID and returns the GUID. The only
 | 
			
		||||
// format currently supported is the `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
 | 
			
		||||
// format.
 | 
			
		||||
func FromString(s string) (GUID, error) {
 | 
			
		||||
	if len(s) != 36 {
 | 
			
		||||
		return GUID{}, fmt.Errorf("invalid GUID %q", s)
 | 
			
		||||
	}
 | 
			
		||||
	if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
 | 
			
		||||
		return GUID{}, fmt.Errorf("invalid GUID %q", s)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var g GUID
 | 
			
		||||
 | 
			
		||||
	data1, err := strconv.ParseUint(s[0:8], 16, 32)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return GUID{}, fmt.Errorf("invalid GUID %q", s)
 | 
			
		||||
	}
 | 
			
		||||
	g.Data1 = uint32(data1)
 | 
			
		||||
 | 
			
		||||
	data2, err := strconv.ParseUint(s[9:13], 16, 16)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return GUID{}, fmt.Errorf("invalid GUID %q", s)
 | 
			
		||||
	}
 | 
			
		||||
	g.Data2 = uint16(data2)
 | 
			
		||||
 | 
			
		||||
	data3, err := strconv.ParseUint(s[14:18], 16, 16)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return GUID{}, fmt.Errorf("invalid GUID %q", s)
 | 
			
		||||
	}
 | 
			
		||||
	g.Data3 = uint16(data3)
 | 
			
		||||
 | 
			
		||||
	for i, x := range []int{19, 21, 24, 26, 28, 30, 32, 34} {
 | 
			
		||||
		v, err := strconv.ParseUint(s[x:x+2], 16, 8)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return GUID{}, fmt.Errorf("invalid GUID %q", s)
 | 
			
		||||
		}
 | 
			
		||||
		g.Data4[i] = uint8(v)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return g, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (g *GUID) setVariant(v Variant) {
 | 
			
		||||
	d := g.Data4[0]
 | 
			
		||||
	switch v {
 | 
			
		||||
	case VariantNCS:
 | 
			
		||||
		d = (d & 0x7f)
 | 
			
		||||
	case VariantRFC4122:
 | 
			
		||||
		d = (d & 0x3f) | 0x80
 | 
			
		||||
	case VariantMicrosoft:
 | 
			
		||||
		d = (d & 0x1f) | 0xc0
 | 
			
		||||
	case VariantFuture:
 | 
			
		||||
		d = (d & 0x0f) | 0xe0
 | 
			
		||||
	case VariantUnknown:
 | 
			
		||||
		fallthrough
 | 
			
		||||
	default:
 | 
			
		||||
		panic(fmt.Sprintf("invalid variant: %d", v))
 | 
			
		||||
	}
 | 
			
		||||
	g.Data4[0] = d
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Variant returns the GUID variant, as defined in RFC 4122.
 | 
			
		||||
func (g GUID) Variant() Variant {
 | 
			
		||||
	b := g.Data4[0]
 | 
			
		||||
	if b&0x80 == 0 {
 | 
			
		||||
		return VariantNCS
 | 
			
		||||
	} else if b&0xc0 == 0x80 {
 | 
			
		||||
		return VariantRFC4122
 | 
			
		||||
	} else if b&0xe0 == 0xc0 {
 | 
			
		||||
		return VariantMicrosoft
 | 
			
		||||
	} else if b&0xe0 == 0xe0 {
 | 
			
		||||
		return VariantFuture
 | 
			
		||||
	}
 | 
			
		||||
	return VariantUnknown
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (g *GUID) setVersion(v Version) {
 | 
			
		||||
	g.Data3 = (g.Data3 & 0x0fff) | (uint16(v) << 12)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Version returns the GUID version, as defined in RFC 4122.
 | 
			
		||||
func (g GUID) Version() Version {
 | 
			
		||||
	return Version((g.Data3 & 0xF000) >> 12)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarshalText returns the textual representation of the GUID.
 | 
			
		||||
func (g GUID) MarshalText() ([]byte, error) {
 | 
			
		||||
	return []byte(g.String()), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UnmarshalText takes the textual representation of a GUID, and unmarhals it
 | 
			
		||||
// into this GUID.
 | 
			
		||||
func (g *GUID) UnmarshalText(text []byte) error {
 | 
			
		||||
	g2, err := FromString(string(text))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	*g = g2
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								vendor/github.com/Microsoft/go-winio/pkg/guid/guid_nonwindows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								vendor/github.com/Microsoft/go-winio/pkg/guid/guid_nonwindows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
//go:build !windows
 | 
			
		||||
// +build !windows
 | 
			
		||||
 | 
			
		||||
package guid
 | 
			
		||||
 | 
			
		||||
// GUID represents a GUID/UUID. It has the same structure as
 | 
			
		||||
// golang.org/x/sys/windows.GUID so that it can be used with functions expecting
 | 
			
		||||
// that type. It is defined as its own type as that is only available to builds
 | 
			
		||||
// targeted at `windows`. The representation matches that used by native Windows
 | 
			
		||||
// code.
 | 
			
		||||
type GUID struct {
 | 
			
		||||
	Data1 uint32
 | 
			
		||||
	Data2 uint16
 | 
			
		||||
	Data3 uint16
 | 
			
		||||
	Data4 [8]byte
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								vendor/github.com/Microsoft/go-winio/pkg/guid/guid_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								vendor/github.com/Microsoft/go-winio/pkg/guid/guid_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
//go:build windows
 | 
			
		||||
// +build windows
 | 
			
		||||
 | 
			
		||||
package guid
 | 
			
		||||
 | 
			
		||||
import "golang.org/x/sys/windows"
 | 
			
		||||
 | 
			
		||||
// GUID represents a GUID/UUID. It has the same structure as
 | 
			
		||||
// golang.org/x/sys/windows.GUID so that it can be used with functions expecting
 | 
			
		||||
// that type. It is defined as its own type so that stringification and
 | 
			
		||||
// marshaling can be supported. The representation matches that used by native
 | 
			
		||||
// Windows code.
 | 
			
		||||
type GUID windows.GUID
 | 
			
		||||
							
								
								
									
										27
									
								
								vendor/github.com/Microsoft/go-winio/pkg/guid/variant_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/Microsoft/go-winio/pkg/guid/variant_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
// Code generated by "stringer -type=Variant -trimprefix=Variant -linecomment"; DO NOT EDIT.
 | 
			
		||||
 | 
			
		||||
package guid
 | 
			
		||||
 | 
			
		||||
import "strconv"
 | 
			
		||||
 | 
			
		||||
func _() {
 | 
			
		||||
	// An "invalid array index" compiler error signifies that the constant values have changed.
 | 
			
		||||
	// Re-run the stringer command to generate them again.
 | 
			
		||||
	var x [1]struct{}
 | 
			
		||||
	_ = x[VariantUnknown-0]
 | 
			
		||||
	_ = x[VariantNCS-1]
 | 
			
		||||
	_ = x[VariantRFC4122-2]
 | 
			
		||||
	_ = x[VariantMicrosoft-3]
 | 
			
		||||
	_ = x[VariantFuture-4]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const _Variant_name = "UnknownNCSRFC 4122MicrosoftFuture"
 | 
			
		||||
 | 
			
		||||
var _Variant_index = [...]uint8{0, 7, 10, 18, 27, 33}
 | 
			
		||||
 | 
			
		||||
func (i Variant) String() string {
 | 
			
		||||
	if i >= Variant(len(_Variant_index)-1) {
 | 
			
		||||
		return "Variant(" + strconv.FormatInt(int64(i), 10) + ")"
 | 
			
		||||
	}
 | 
			
		||||
	return _Variant_name[_Variant_index[i]:_Variant_index[i+1]]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										37
									
								
								vendor/github.com/Microsoft/go-winio/privilege.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										37
									
								
								vendor/github.com/Microsoft/go-winio/privilege.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,3 +1,4 @@
 | 
			
		||||
//go:build windows
 | 
			
		||||
// +build windows
 | 
			
		||||
 | 
			
		||||
package winio
 | 
			
		||||
@@ -24,19 +25,15 @@ import (
 | 
			
		||||
//sys lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) = advapi32.LookupPrivilegeDisplayNameW
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	SE_PRIVILEGE_ENABLED = 2
 | 
			
		||||
	//revive:disable-next-line:var-naming ALL_CAPS
 | 
			
		||||
	SE_PRIVILEGE_ENABLED = windows.SE_PRIVILEGE_ENABLED
 | 
			
		||||
 | 
			
		||||
	ERROR_NOT_ALL_ASSIGNED syscall.Errno = 1300
 | 
			
		||||
	//revive:disable-next-line:var-naming ALL_CAPS
 | 
			
		||||
	ERROR_NOT_ALL_ASSIGNED syscall.Errno = windows.ERROR_NOT_ALL_ASSIGNED
 | 
			
		||||
 | 
			
		||||
	SeBackupPrivilege  = "SeBackupPrivilege"
 | 
			
		||||
	SeRestorePrivilege = "SeRestorePrivilege"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	securityAnonymous = iota
 | 
			
		||||
	securityIdentification
 | 
			
		||||
	securityImpersonation
 | 
			
		||||
	securityDelegation
 | 
			
		||||
	SeBackupPrivilege   = "SeBackupPrivilege"
 | 
			
		||||
	SeRestorePrivilege  = "SeRestorePrivilege"
 | 
			
		||||
	SeSecurityPrivilege = "SeSecurityPrivilege"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
@@ -50,11 +47,9 @@ type PrivilegeError struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *PrivilegeError) Error() string {
 | 
			
		||||
	s := ""
 | 
			
		||||
	s := "Could not enable privilege "
 | 
			
		||||
	if len(e.privileges) > 1 {
 | 
			
		||||
		s = "Could not enable privileges "
 | 
			
		||||
	} else {
 | 
			
		||||
		s = "Could not enable privilege "
 | 
			
		||||
	}
 | 
			
		||||
	for i, p := range e.privileges {
 | 
			
		||||
		if i != 0 {
 | 
			
		||||
@@ -93,7 +88,7 @@ func RunWithPrivileges(names []string, fn func() error) error {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func mapPrivileges(names []string) ([]uint64, error) {
 | 
			
		||||
	var privileges []uint64
 | 
			
		||||
	privileges := make([]uint64, 0, len(names))
 | 
			
		||||
	privNameMutex.Lock()
 | 
			
		||||
	defer privNameMutex.Unlock()
 | 
			
		||||
	for _, name := range names {
 | 
			
		||||
@@ -126,7 +121,7 @@ func enableDisableProcessPrivilege(names []string, action uint32) error {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p, _ := windows.GetCurrentProcess()
 | 
			
		||||
	p := windows.CurrentProcess()
 | 
			
		||||
	var token windows.Token
 | 
			
		||||
	err = windows.OpenProcessToken(p, windows.TOKEN_ADJUST_PRIVILEGES|windows.TOKEN_QUERY, &token)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@@ -139,10 +134,10 @@ func enableDisableProcessPrivilege(names []string, action uint32) error {
 | 
			
		||||
 | 
			
		||||
func adjustPrivileges(token windows.Token, privileges []uint64, action uint32) error {
 | 
			
		||||
	var b bytes.Buffer
 | 
			
		||||
	binary.Write(&b, binary.LittleEndian, uint32(len(privileges)))
 | 
			
		||||
	_ = binary.Write(&b, binary.LittleEndian, uint32(len(privileges)))
 | 
			
		||||
	for _, p := range privileges {
 | 
			
		||||
		binary.Write(&b, binary.LittleEndian, p)
 | 
			
		||||
		binary.Write(&b, binary.LittleEndian, action)
 | 
			
		||||
		_ = binary.Write(&b, binary.LittleEndian, p)
 | 
			
		||||
		_ = binary.Write(&b, binary.LittleEndian, action)
 | 
			
		||||
	}
 | 
			
		||||
	prevState := make([]byte, b.Len())
 | 
			
		||||
	reqSize := uint32(0)
 | 
			
		||||
@@ -150,7 +145,7 @@ func adjustPrivileges(token windows.Token, privileges []uint64, action uint32) e
 | 
			
		||||
	if !success {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if err == ERROR_NOT_ALL_ASSIGNED {
 | 
			
		||||
	if err == ERROR_NOT_ALL_ASSIGNED { //nolint:errorlint // err is Errno
 | 
			
		||||
		return &PrivilegeError{privileges}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
@@ -176,7 +171,7 @@ func getPrivilegeName(luid uint64) string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newThreadToken() (windows.Token, error) {
 | 
			
		||||
	err := impersonateSelf(securityImpersonation)
 | 
			
		||||
	err := impersonateSelf(windows.SecurityImpersonation)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								vendor/github.com/Microsoft/go-winio/reparse.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/Microsoft/go-winio/reparse.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,3 +1,6 @@
 | 
			
		||||
//go:build windows
 | 
			
		||||
// +build windows
 | 
			
		||||
 | 
			
		||||
package winio
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
@@ -113,16 +116,16 @@ func EncodeReparsePoint(rp *ReparsePoint) []byte {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var b bytes.Buffer
 | 
			
		||||
	binary.Write(&b, binary.LittleEndian, &data)
 | 
			
		||||
	_ = binary.Write(&b, binary.LittleEndian, &data)
 | 
			
		||||
	if !rp.IsMountPoint {
 | 
			
		||||
		flags := uint32(0)
 | 
			
		||||
		if relative {
 | 
			
		||||
			flags |= 1
 | 
			
		||||
		}
 | 
			
		||||
		binary.Write(&b, binary.LittleEndian, flags)
 | 
			
		||||
		_ = binary.Write(&b, binary.LittleEndian, flags)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	binary.Write(&b, binary.LittleEndian, ntTarget16)
 | 
			
		||||
	binary.Write(&b, binary.LittleEndian, target16)
 | 
			
		||||
	_ = binary.Write(&b, binary.LittleEndian, ntTarget16)
 | 
			
		||||
	_ = binary.Write(&b, binary.LittleEndian, target16)
 | 
			
		||||
	return b.Bytes()
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										64
									
								
								vendor/github.com/Microsoft/go-winio/sd.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										64
									
								
								vendor/github.com/Microsoft/go-winio/sd.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,23 +1,25 @@
 | 
			
		||||
//go:build windows
 | 
			
		||||
// +build windows
 | 
			
		||||
 | 
			
		||||
package winio
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"syscall"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/sys/windows"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//sys lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) = advapi32.LookupAccountNameW
 | 
			
		||||
//sys lookupAccountSid(systemName *uint16, sid *byte, name *uint16, nameSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) = advapi32.LookupAccountSidW
 | 
			
		||||
//sys convertSidToStringSid(sid *byte, str **uint16) (err error) = advapi32.ConvertSidToStringSidW
 | 
			
		||||
//sys convertStringSidToSid(str *uint16, sid **byte) (err error) = advapi32.ConvertStringSidToSidW
 | 
			
		||||
//sys convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) = advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW
 | 
			
		||||
//sys convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) = advapi32.ConvertSecurityDescriptorToStringSecurityDescriptorW
 | 
			
		||||
//sys localFree(mem uintptr) = LocalFree
 | 
			
		||||
//sys getSecurityDescriptorLength(sd uintptr) (len uint32) = advapi32.GetSecurityDescriptorLength
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	cERROR_NONE_MAPPED = syscall.Errno(1332)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type AccountLookupError struct {
 | 
			
		||||
	Name string
 | 
			
		||||
	Err  error
 | 
			
		||||
@@ -28,8 +30,10 @@ func (e *AccountLookupError) Error() string {
 | 
			
		||||
		return "lookup account: empty account name specified"
 | 
			
		||||
	}
 | 
			
		||||
	var s string
 | 
			
		||||
	switch e.Err {
 | 
			
		||||
	case cERROR_NONE_MAPPED:
 | 
			
		||||
	switch {
 | 
			
		||||
	case errors.Is(e.Err, windows.ERROR_INVALID_SID):
 | 
			
		||||
		s = "the security ID structure is invalid"
 | 
			
		||||
	case errors.Is(e.Err, windows.ERROR_NONE_MAPPED):
 | 
			
		||||
		s = "not found"
 | 
			
		||||
	default:
 | 
			
		||||
		s = e.Err.Error()
 | 
			
		||||
@@ -37,6 +41,8 @@ func (e *AccountLookupError) Error() string {
 | 
			
		||||
	return "lookup account " + e.Name + ": " + s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *AccountLookupError) Unwrap() error { return e.Err }
 | 
			
		||||
 | 
			
		||||
type SddlConversionError struct {
 | 
			
		||||
	Sddl string
 | 
			
		||||
	Err  error
 | 
			
		||||
@@ -46,15 +52,19 @@ func (e *SddlConversionError) Error() string {
 | 
			
		||||
	return "convert " + e.Sddl + ": " + e.Err.Error()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *SddlConversionError) Unwrap() error { return e.Err }
 | 
			
		||||
 | 
			
		||||
// LookupSidByName looks up the SID of an account by name
 | 
			
		||||
//
 | 
			
		||||
//revive:disable-next-line:var-naming SID, not Sid
 | 
			
		||||
func LookupSidByName(name string) (sid string, err error) {
 | 
			
		||||
	if name == "" {
 | 
			
		||||
		return "", &AccountLookupError{name, cERROR_NONE_MAPPED}
 | 
			
		||||
		return "", &AccountLookupError{name, windows.ERROR_NONE_MAPPED}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var sidSize, sidNameUse, refDomainSize uint32
 | 
			
		||||
	err = lookupAccountName(nil, name, nil, &sidSize, nil, &refDomainSize, &sidNameUse)
 | 
			
		||||
	if err != nil && err != syscall.ERROR_INSUFFICIENT_BUFFER {
 | 
			
		||||
	if err != nil && err != syscall.ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint // err is Errno
 | 
			
		||||
		return "", &AccountLookupError{name, err}
 | 
			
		||||
	}
 | 
			
		||||
	sidBuffer := make([]byte, sidSize)
 | 
			
		||||
@@ -73,6 +83,42 @@ func LookupSidByName(name string) (sid string, err error) {
 | 
			
		||||
	return sid, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LookupNameBySid looks up the name of an account by SID
 | 
			
		||||
//
 | 
			
		||||
//revive:disable-next-line:var-naming SID, not Sid
 | 
			
		||||
func LookupNameBySid(sid string) (name string, err error) {
 | 
			
		||||
	if sid == "" {
 | 
			
		||||
		return "", &AccountLookupError{sid, windows.ERROR_NONE_MAPPED}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sidBuffer, err := windows.UTF16PtrFromString(sid)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", &AccountLookupError{sid, err}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var sidPtr *byte
 | 
			
		||||
	if err = convertStringSidToSid(sidBuffer, &sidPtr); err != nil {
 | 
			
		||||
		return "", &AccountLookupError{sid, err}
 | 
			
		||||
	}
 | 
			
		||||
	defer localFree(uintptr(unsafe.Pointer(sidPtr)))
 | 
			
		||||
 | 
			
		||||
	var nameSize, refDomainSize, sidNameUse uint32
 | 
			
		||||
	err = lookupAccountSid(nil, sidPtr, nil, &nameSize, nil, &refDomainSize, &sidNameUse)
 | 
			
		||||
	if err != nil && err != windows.ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint // err is Errno
 | 
			
		||||
		return "", &AccountLookupError{sid, err}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	nameBuffer := make([]uint16, nameSize)
 | 
			
		||||
	refDomainBuffer := make([]uint16, refDomainSize)
 | 
			
		||||
	err = lookupAccountSid(nil, sidPtr, &nameBuffer[0], &nameSize, &refDomainBuffer[0], &refDomainSize, &sidNameUse)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", &AccountLookupError{sid, err}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	name = windows.UTF16ToString(nameBuffer)
 | 
			
		||||
	return name, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SddlToSecurityDescriptor(sddl string) ([]byte, error) {
 | 
			
		||||
	var sdBuffer uintptr
 | 
			
		||||
	err := convertStringSecurityDescriptorToSecurityDescriptor(sddl, 1, &sdBuffer, nil)
 | 
			
		||||
@@ -87,7 +133,7 @@ func SddlToSecurityDescriptor(sddl string) ([]byte, error) {
 | 
			
		||||
 | 
			
		||||
func SecurityDescriptorToSddl(sd []byte) (string, error) {
 | 
			
		||||
	var sddl *uint16
 | 
			
		||||
	// The returned string length seems to including an aribtrary number of terminating NULs.
 | 
			
		||||
	// The returned string length seems to include an arbitrary number of terminating NULs.
 | 
			
		||||
	// Don't use it.
 | 
			
		||||
	err := convertSecurityDescriptorToStringSecurityDescriptor(&sd[0], 1, 0xff, &sddl, nil)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								vendor/github.com/Microsoft/go-winio/syscall.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/Microsoft/go-winio/syscall.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,3 +1,5 @@
 | 
			
		||||
//go:build windows
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
//go:generate go run github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go ./*.go
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								vendor/github.com/Microsoft/go-winio/tools.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/Microsoft/go-winio/tools.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
//go:build tools
 | 
			
		||||
 | 
			
		||||
package winio
 | 
			
		||||
 | 
			
		||||
import _ "golang.org/x/tools/cmd/stringer"
 | 
			
		||||
							
								
								
									
										587
									
								
								vendor/github.com/Microsoft/go-winio/zsyscall_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										587
									
								
								vendor/github.com/Microsoft/go-winio/zsyscall_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,4 +1,6 @@
 | 
			
		||||
// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
 | 
			
		||||
//go:build windows
 | 
			
		||||
 | 
			
		||||
// Code generated by 'go generate' using "github.com/Microsoft/go-winio/tools/mkwinsyscall"; DO NOT EDIT.
 | 
			
		||||
 | 
			
		||||
package winio
 | 
			
		||||
 | 
			
		||||
@@ -19,6 +21,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 +29,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,213 +40,62 @@ func errnoErr(e syscall.Errno) error {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	modkernel32 = windows.NewLazySystemDLL("kernel32.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")
 | 
			
		||||
	procConnectNamedPipe                                     = modkernel32.NewProc("ConnectNamedPipe")
 | 
			
		||||
	procCreateNamedPipeW                                     = modkernel32.NewProc("CreateNamedPipeW")
 | 
			
		||||
	procCreateFileW                                          = modkernel32.NewProc("CreateFileW")
 | 
			
		||||
	procWaitNamedPipeW                                       = modkernel32.NewProc("WaitNamedPipeW")
 | 
			
		||||
	procGetNamedPipeInfo                                     = modkernel32.NewProc("GetNamedPipeInfo")
 | 
			
		||||
	procGetNamedPipeHandleStateW                             = modkernel32.NewProc("GetNamedPipeHandleStateW")
 | 
			
		||||
	procLocalAlloc                                           = modkernel32.NewProc("LocalAlloc")
 | 
			
		||||
	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")
 | 
			
		||||
	procConvertStringSidToSidW                               = modadvapi32.NewProc("ConvertStringSidToSidW")
 | 
			
		||||
	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")
 | 
			
		||||
	procLookupAccountSidW                                    = modadvapi32.NewProc("LookupAccountSidW")
 | 
			
		||||
	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")
 | 
			
		||||
	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")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) {
 | 
			
		||||
	r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0)
 | 
			
		||||
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
 | 
			
		||||
	}
 | 
			
		||||
	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 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 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 waitNamedPipe(name string, timeout uint32) (err error) {
 | 
			
		||||
	var _p0 *uint16
 | 
			
		||||
	_p0, err = syscall.UTF16PtrFromString(name)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	return _waitNamedPipe(_p0, timeout)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func _waitNamedPipe(name *uint16, timeout uint32) (err error) {
 | 
			
		||||
	r1, _, e1 := syscall.Syscall(procWaitNamedPipeW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(timeout), 0)
 | 
			
		||||
	if r1 == 0 {
 | 
			
		||||
		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 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
 | 
			
		||||
}
 | 
			
		||||
@@ -251,11 +103,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
 | 
			
		||||
}
 | 
			
		||||
@@ -272,126 +120,89 @@ 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)
 | 
			
		||||
func convertStringSidToSid(str *uint16, sid **byte) (err error) {
 | 
			
		||||
	r1, _, e1 := syscall.Syscall(procConvertStringSidToSidW.Addr(), 2, uintptr(unsafe.Pointer(str)), uintptr(unsafe.Pointer(sid)), 0)
 | 
			
		||||
	if r1 == 0 {
 | 
			
		||||
		if e1 != 0 {
 | 
			
		||||
			err = errnoErr(e1)
 | 
			
		||||
		} else {
 | 
			
		||||
			err = syscall.EINVAL
 | 
			
		||||
		}
 | 
			
		||||
		err = errnoErr(e1)
 | 
			
		||||
	}
 | 
			
		||||
	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
 | 
			
		||||
	}
 | 
			
		||||
	r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0)
 | 
			
		||||
func lookupAccountSid(systemName *uint16, sid *byte, name *uint16, nameSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
 | 
			
		||||
	r1, _, e1 := syscall.Syscall9(procLookupAccountSidW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameSize)), 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 getCurrentThread() (h syscall.Handle) {
 | 
			
		||||
	r0, _, _ := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0)
 | 
			
		||||
	h = syscall.Handle(r0)
 | 
			
		||||
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)
 | 
			
		||||
	if r1 == 0 {
 | 
			
		||||
		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
 | 
			
		||||
	}
 | 
			
		||||
	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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -412,53 +223,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
 | 
			
		||||
}
 | 
			
		||||
@@ -471,22 +256,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
 | 
			
		||||
}
 | 
			
		||||
@@ -499,22 +276,144 @@ 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 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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										21
									
								
								vendor/github.com/Microsoft/hcsshim/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/Microsoft/hcsshim/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,21 +0,0 @@
 | 
			
		||||
The MIT License (MIT)
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2015 Microsoft
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
in the Software without restriction, including without limitation the rights
 | 
			
		||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
SOFTWARE.
 | 
			
		||||
							
								
								
									
										51
									
								
								vendor/github.com/Microsoft/hcsshim/osversion/osversion.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										51
									
								
								vendor/github.com/Microsoft/hcsshim/osversion/osversion.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,51 +0,0 @@
 | 
			
		||||
package osversion
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/sys/windows"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// OSVersion is a wrapper for Windows version information
 | 
			
		||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx
 | 
			
		||||
type OSVersion struct {
 | 
			
		||||
	Version      uint32
 | 
			
		||||
	MajorVersion uint8
 | 
			
		||||
	MinorVersion uint8
 | 
			
		||||
	Build        uint16
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724833(v=vs.85).aspx
 | 
			
		||||
type osVersionInfoEx struct {
 | 
			
		||||
	OSVersionInfoSize uint32
 | 
			
		||||
	MajorVersion      uint32
 | 
			
		||||
	MinorVersion      uint32
 | 
			
		||||
	BuildNumber       uint32
 | 
			
		||||
	PlatformID        uint32
 | 
			
		||||
	CSDVersion        [128]uint16
 | 
			
		||||
	ServicePackMajor  uint16
 | 
			
		||||
	ServicePackMinor  uint16
 | 
			
		||||
	SuiteMask         uint16
 | 
			
		||||
	ProductType       byte
 | 
			
		||||
	Reserve           byte
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get gets the operating system version on Windows.
 | 
			
		||||
// The calling application must be manifested to get the correct version information.
 | 
			
		||||
func Get() OSVersion {
 | 
			
		||||
	var err error
 | 
			
		||||
	osv := OSVersion{}
 | 
			
		||||
	osv.Version, err = windows.GetVersion()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		// GetVersion never fails.
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
	osv.MajorVersion = uint8(osv.Version & 0xFF)
 | 
			
		||||
	osv.MinorVersion = uint8(osv.Version >> 8 & 0xFF)
 | 
			
		||||
	osv.Build = uint16(osv.Version >> 16)
 | 
			
		||||
	return osv
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (osv OSVersion) ToString() string {
 | 
			
		||||
	return fmt.Sprintf("%d.%d.%d", osv.MajorVersion, osv.MinorVersion, osv.Build)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								vendor/github.com/Microsoft/hcsshim/osversion/windowsbuilds.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/Microsoft/hcsshim/osversion/windowsbuilds.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,10 +0,0 @@
 | 
			
		||||
package osversion
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
 | 
			
		||||
	// RS2 was a client-only release in case you're asking why it's not in the list.
 | 
			
		||||
	RS1 = 14393
 | 
			
		||||
	RS3 = 16299
 | 
			
		||||
	RS4 = 17134
 | 
			
		||||
	RS5 = 17763
 | 
			
		||||
)
 | 
			
		||||
		Reference in New Issue
	
	Block a user