Win32 IO-related utilities for Go

go-winio Build Status

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 for using named pipes as a net transport.

This code relies on IO completion ports to avoid blocking IO on system threads, allowing Go to reuse the thread to schedule another goroutine. This limits support to Windows Vista and newer operating systems. This is similar to the implementation of network sockets in Go's net package.

Please see the LICENSE file for licensing information.

Contributing

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 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.

We also require that contributors sign their commits using git commit -s or git commit --signoff to certify they either authored the work themselves or otherwise have permission to use it in this project. Please see 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.

Code of Conduct

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

Special Thanks

Thanks to natefinch for the inspiration for this library. See https://github.com/natefinch/npipe for another named pipe implementation.

Owner
Microsoft
Open source projects and samples from Microsoft
Microsoft
Comments
  • fixes #67 DialPipe problem with multiple calls / waiting for busy pipe

    fixes #67 DialPipe problem with multiple calls / waiting for busy pipe

    (I believe this change also should be used instead of PR #75 -- that PR is potentially extraordinarily buggy.)

    This changes a few things to try to ensure that we never wind up with a result of ERROR_FILE_NOT_FOUND, due to a race between closing the last pipe instance and opening the next.

    First we keep an "open" client instance (unused) while the listener is open, so that we are guaranteed to always have an active pipe instance. This means attempts to open while no other instances exist result in ERROR_PIPE_BUSY instead of ERROR_FILE_NOT_FOUND.

    Second we have changed the loop for dialing to eliminate a race condition that is more or less inherent in WaitNamedPipe when synchronizing with CreateFile. The real timeout needs to be some larger value than the WaitNamedPipe timeout, and furthermore WaitNamedPipe is not very nice with the Go runtime, since it is a blocking system call. Instead we just put the goroutine to sleep for 10 milliseconds, and keep retrying the CreateFile until the maximum timeout is reached. If no timeout is specified we assume a reasonable and large default of 5 seconds, which is similar to a TCP connection timeout.

    This isn't perfect, as a client attempting to connect to an extremely busy pipe server can be starved out by other clients coming in while it is in that brief sleep, but this potential race was already present with WaitNamedPipe. The numerous retries (by default 500 retries!) mean its pretty unlikely to occur, and if a single client hits the race once, it has an excellent chance of getting in the next cycle.

    (A real "fix" that is completely race free and fair would require changes in the underlying Named Pipe implementation, or some other kind of external coordination.)

  • Retry named pipe connection on race condition

    Retry named pipe connection on race condition

    If the named pipe server does not have an outstanding call to ConnectNamedPipe() at the time the client calls CreateFile() or WaitNamedPipe(), the client can receive ERROR_FILE_NOT_FOUND and ERROR_BAD_PATHNAME errors. When that's the case, there is no choice but to retry after a short delay in the hope that next time, the server will be able to accept the connection.

    This error occurs infrequently in low traffic situations, but it manifests quite reliably when clients open concurrent connections and/or open many short-lived connections in a short period of time.

    Fixes #67.

  • Apply read and write deadlines to pending IO

    Apply read and write deadlines to pending IO

    In order to upgrade to go1.8 all IO operations including previous pending IO must have the deadline set when SetReadDeadline or SetWriteDeadline is called.

    This moves the timeout cancelation responsibility out of the wait routine and into timers in the deadline code.

    @jstarks PTAL

    Signed-off-by: Darren Stahl [email protected]

  • file: Fix race in closing

    file: Fix race in closing

    Hello!

    It looks like there's a race condition created in (*win32File).closeHandle() where multiple concurrent goroutines are accessing the (*win32File).closing field. This shows up in the go race detector. This change adds a lock around the closing field to remove the race.

    Thanks! Sam

  • provide access to underlying file handle

    provide access to underlying file handle

    It is convenient to be able to pull off the underlying file handle to pass to other Win32 functions that aren't supported by this library.

    This change adds an Fd() uintptr method to the file implementation (matches the os.File method of the same name).

  • DialPipe problem with multiple calls / waiting for busy pipe

    DialPipe problem with multiple calls / waiting for busy pipe

    Currently there is some work in progress (https://github.com/portainer/portainer/pull/1186) to add mapped named pipe support into Portainer so it will be easier to run it in a Windows container ( docker run -u ContainerAdministrator -it -v //./pipe/docker_engine://./pipe/docker_engine -p 9000:9000 stefanscherer/portainer:insider -H npipe:////./pipe/docker_engine )

    We're using winio.DialPipe() to connect to the Docker engine from inside a microsoft/nanoserver-insider container.

    At the moment we see problems in Portainer as it sometimes makes multiple requests requested by the web frontend. Here's a WireShark screenshot with the problem.

    bildschirmfoto 2017-09-17 um 07 42 23

    The two /api/endpoints/1/docker/xx GET requests use separate connections and run in parallel. One of the calls aborts with "open //./pipe/docker_engine: The system cannot find the file specified."

    I have seen the check for cERROR_PIPE_BUSY and first thought that createFile() returns cERROR_FILE_NOT_FOUND and aborts immediatelly.

    We are using the default timeout right now

        return winio.DialPipe(namedPipePath, nil)
    

    but I also tried giving a 5 second timeout

        timeout := 5000 * time.Millisecond
        return winio.DialPipe(namedPipePath, &timeout)
    

    Digging deeper it seems like the waitNamedPipe() just does not wait long enough or cannot start wait for the pipe.

    Adding some Println in DialPipe I now see this running Portainer in the second DialPipe call:

    DialPipe createFile err All pipe instances are busy. DialPipe waitNamedPipe ms 4998 DialPipe waitNamedPipe returns err The system cannot find the file specified. DialPipe returns err The system cannot find the file specified.

    The problem is that waitNamedPipe returns immediatelly and does not wait the given 5000 milliseconds.

    How can we make DialPipe more reliable?

  • HVsock Registry Application Registration

    HVsock Registry Application Registration

    Using Hyper-V sockets requires registering the application in the Windows Registry.

    This PR adds (de)registration functionality for an application name/GUID.

    This PR is split from #235

    Signed-off-by: Hamza El-Saawy [email protected]

  • Fix regression in DetachVhd

    Fix regression in DetachVhd

    When opening a disk for detach mode no parameters are required. This regression was introduced when the OpenVirtualDisk method was added. Moving the code back to the previous openVirtualDisk internal method so we can pass nil parameters.

    Signed-off-by: Justin Terry (VM) [email protected]

  • Prevent data race when closing active file

    Prevent data race when closing active file

    The race usually happens when closeHandle() and prepareIo() are called concurrently; the former tries to set closing to true the latter tries to read its value.

    In order to avoid this issue, we added a lock around the variable.

    Signed-off-by: Kenfe-Mickael Laventure [email protected]

  • Added runtime.KeepAlive for the new stricter 1.8 GC

    Added runtime.KeepAlive for the new stricter 1.8 GC

    fixes #41

    As far as I can tell, this should contain all the runtime.KeepAlive calls needed to conform to the new argument liveness guarantees in Go1.8.x

    It turns out that the main issue was due to passing a Go pointer via native calls to the ioCompletionProcessor, causing the new garbage collection rules to cleanup the struct containing the channel even though it did not have a finalizer.

    /cc @jhowardmsft @jstarks PTAL

    Thanks @mappu for the initial investigation and repro test.

    This also updates zsyscall_windows.go with the new 1.8 go generated code, though it is not related to the KeepAlive, it should be done with the update to 1.8.

    Signed-off-by: Darren Stahl [email protected]

  • Implement `winio.GetFileStandardInfo`

    Implement `winio.GetFileStandardInfo`

    This get-only API will be useful for detecting when a file has multiple links to it.

    Specifically, I plan to use this to provide an optimisation for https://github.com/microsoft/hcsshim/pull/901 (or afterwards, it's not a blocker...) by only attempting to recognise hard-links for files which have multiple links.

    See https://github.com/TBBle/hcsshim/compare/base-layer-manipulation...TBBle:hack-base-layer-manipulation-with-branched-go-winio for the example use-case.

  • Set FILE_FLAG_FIRST_PIPE_INSTANCE flag

    Set FILE_FLAG_FIRST_PIPE_INSTANCE flag

    Is it possible to set FILE_FLAG_FIRST_PIPE_INSTANCE when creating listener. It seems theres no API exposing this when calling winio.ListenPipe(...). We need this functionality as it will prevent Instance Creation Race Conditions as detailed here https://csandker.io/2021/01/10/Offensive-Windows-IPC-1-NamedPipes.html#instance-creation-race-condition.

    I noticed the comment on listener call here https://github.com/microsoft/go-winio/blob/650a2e464c7458a1d355d7bb5affad1eec1bfbb6/pipe.go#L444

    Is this enforced? From testing I noticed if I try to run a second listener with same pipe, same configs it gave me open \\.\pipe\pipename: Access is denied.

    Does this ensure no instances of the pipe were created before me?

  • go.mod: update dependencies

    go.mod: update dependencies

    • follow-up to https://github.com/microsoft/go-winio/pull/266

    go.mod: golang.org/x/sys v0.1.0

    The golang.org/x/,, projects now tag releases, so updating to the first tagged release.

    go.mod: github.com/sirupsen/logrus v1.9.0

    Updating to the current release, which has been out for a while, and most projects have already updated to this version, so let's update it here as well to reduces the number of versions in the dependency tree.

    full diff: https://github.com/sirupsen/logrus/compare/v1.7.0...v1.9.0

  • pkg/etw/sample: remove dependency on github.com/sirupsen/logrus

    pkg/etw/sample: remove dependency on github.com/sirupsen/logrus

    It looks like for the purpose of the example "a" logger was needed, so not strictly logrus (probably fmt.Println() would've worked even).

    This patch removes logrus as dependency for the example. The only remaining use of logrus in this repository is now in the pkg/etc/etwlogrus package, which does need logrus, but (possibly) could become its own module if we want to remove logrus as dependency of go-winio itself.

  • go.mod: remove golang.org/x/tools dependency

    go.mod: remove golang.org/x/tools dependency

    This removes golang.org/x/tools/cmd/stringer as a direct dependency of this module, instead using "go install" to install the required tool as part of go generate. I opted for pinning to a fixed version for reproducibility, but we could switch to @latest if there's no concerns for getting newer versions.

    With this patch:

    which stringer
    # (no output)
    
    go generate ./pkg/guid
    which stringer
    /Users/thajeztah/go/bin/stringer
    
  • pkg/fs: Add RemoveAll function

    pkg/fs: Add RemoveAll function

    New RemoveAll function intended to be a replacement for os.RemoveAll usage and be tailored to Windows scenarios.

    Most importantly, this function works with []uint16 instead of string. This allows it to properly delete Windows filesystem trees that contain files with invalid UTF-16 paths.

    Signed-off-by: Kevin Parsons [email protected]

dht is used by anacrolix/torrent, and is intended for use as a library in other projects both torrent related and otherwise

dht Installation Install the library package with go get github.com/anacrolix/dht, or the provided cmds with go get github.com/anacrolix/dht/cmd/....

Dec 28, 2022
An online book focusing on Go syntax/semantics and runtime related things

Go 101 is a book focusing on Go syntax/semantics and all kinds of runtime related things. It tries to help gophers gain a deep and thorough understanding of Go. This book also collects many details of Go and in Go programming. The book is expected to be helpful for both beginner and experienced Go programmers.

Dec 29, 2022
A small utility that aims to automate and simplify some tasks related to software release cycles.

Stork is a small utility that aims to automate and simplify some tasks related to software release cycles such as reading the current version from a f

Nov 9, 2022
A directory of hardware related libs, tools, and tutorials for Go

Go + hardware This repo is a directory of tools, packages and tutorials to let you introduce Go in your hardware projects. Why Go? Go can target platf

Dec 30, 2022
Nebula Operator manages NebulaGraph clusters on Kubernetes and automates tasks related to operating a NebulaGraph cluster

Nebula Operator manages NebulaGraph clusters on Kubernetes and automates tasks related to operating a NebulaGraph cluster. It evolved from NebulaGraph Cloud Service, makes NebulaGraph a truly cloud-native database.

Dec 31, 2022
Hammond is a self hosted vehicle management system to track fuel and other expenses related to all of your vehicles.
Hammond is a self hosted vehicle management system to track fuel and other expenses related to all of your vehicles.

Hammond is a self hosted vehicle management system to track fuel and other expenses related to all of your vehicles. It supports multiple users sharing multiple vehicles. It is the logical successor to Clarkson which has not been updated for quite some time now.

Jan 2, 2023
gophertunnel is composed of several packages that may be of use for creating Minecraft related tools
gophertunnel is composed of several packages that may be of use for creating Minecraft related tools

gophertunnel is composed of several packages that may be of use for creating Minecraft related tools. A brief overview of all packages may be found here.

Dec 31, 2022
Get related domains / subdomains by looking at Google Analytics IDs
Get related domains / subdomains by looking at Google Analytics IDs

AnalyticsRelationships This script try to get related domains / subdomains by looking at Google Analytics IDs from a URL. First search for ID of Googl

Jan 2, 2023
🎉 An awesome version control tool for protoc and its related plugins.
🎉 An awesome version control tool for protoc and its related plugins.

❤️ PowerProto is actively maintained! Any questions in use can be directly raised issue, I will respond to you as fast as possible. If you think the p

Dec 29, 2022
OpenAPI specification and related artifacts for HashiCorp Nomad

Overview This repository contains the HashiCorp Nomad OpenAPI specification and related artifacts. The OpenAPI specification defines a machine-readabl

Dec 14, 2022
A collection of authentication Go packages related to OIDC, JWKs and Distributed Claims.

cap (collection of authentication packages) provides a collection of related packages which enable support for OIDC, JWT Verification and Distributed Claims.

Dec 7, 2022
🌍 Package tcplisten provides a customizable TCP net.Listener with various performance-related options

Package tcplisten provides customizable TCP net.Listener with various performance-related options: SO_REUSEPORT. This option allows linear scaling ser

Nov 14, 2022
A program to create assembly 8086 strings to print without using any printing/strings related function but only mov-xchg-int and loops

Assembly String builder tool A program to create assembly 8086 strings to print without using any printing/strings related function but only mov-xchg-

Feb 1, 2022
The primary place where Optimism works on stuff related to Optimistic Ethereum
The primary place where Optimism works on stuff related to Optimistic Ethereum

The Optimism Monorepo TL;DR This is the primary place where Optimism works on stuff related to Optimistic Ethereum. Documentation Extensive documentat

Dec 16, 2022
A scanner for running security-related configuration checks such as CIS benchmarks

Localtoast Localtoast is a scanner for running security-related configuration checks such as CIS benchmarks in an easily configurable manner. The scan

Dec 15, 2022
Grpc bridge to various mediabank related systems

Mediabank bridge This internal tool enables authenticated gRPC based endpoint for securely communicating with systems like: Telestream Vantage Workflo

Jan 7, 2022
cluster-api-state-metrics (CASM) is a service that listens to the Kubernetes API server and generates metrics about the state of custom resource objects related of Kubernetes Cluster API.

Overview cluster-api-state-metrics (CASM) is a service that listens to the Kubernetes API server and generates metrics about the state of custom resou

Oct 27, 2022
Source code related to an on-site demonstration (for Ardan Labs) of packaging Go applications with Nix

Ardan Labs Nix Demo High-Level Overview We bumbled the scheduling of an earlier presentation about git worktree that a few co-workers attended. In eff

Oct 12, 2022
A go program that relies on back-end ffmpeg to process video-related content

Video Compress A go program that relies on back-end ffmpeg to process video-related content Installation v-go You can download the corresponding v-go

Dec 22, 2021
Labs, solutions and related materials from the MIT 6.824 Distributed Systems course.
Labs, solutions and related materials from the MIT 6.824 Distributed Systems course.

MIT 6.824 Distributed Systems Labs, solutions and related materials from the MIT 6.824 Distributed Systems course. Overview From the official website:

Nov 5, 2022