Browse code

vendor: Update go-winio to v0.4.20

Updates go-winio to the latest v0.4.x version. The main important fix
here is to go-winio's backuptar package. This is needed to fix a bug in
sparse file handling in container layers, which was exposed by a recent
change in Windows.

go-winio v0.4.20: https://github.com/microsoft/go-winio/releases/tag/v0.4.20

Signed-off-by: Kevin Parsons <kevpar@microsoft.com>

Kevin Parsons authored on 2021/10/16 07:15:28
Showing 27 changed files
... ...
@@ -1,6 +1,6 @@
1 1
 github.com/Azure/go-ansiterm                        d6e3b3328b783f23731bc4d058875b0371ff8109
2 2
 github.com/Microsoft/hcsshim                        64a2b71405dacf76c95600f4c756a991ad09cf7c # moby branch
3
-github.com/Microsoft/go-winio                       5b44b70ab3ab4d291a7c1d28afe7b4afeced0ed4 # v0.4.15
3
+github.com/Microsoft/go-winio                       7e149e8c70409f36773c1b2cf3447a7ab7697368 # v0.4.20
4 4
 github.com/docker/libtrust                          9cbd2a1374f46905c68a4eb3694a130610adc62a
5 5
 github.com/golang/gddo                              72a348e765d293ed6d1ded7b699591f14d6cd921
6 6
 github.com/google/uuid                              0cd6bf5da1e1c83f8b45653022c74f71af0538a4 # v1.1.1
... ...
@@ -1,4 +1,4 @@
1
-# go-winio
1
+# go-winio [![Build Status](https://github.com/microsoft/go-winio/actions/workflows/ci.yml/badge.svg)](https://github.com/microsoft/go-winio/actions/workflows/ci.yml)
2 2
 
3 3
 This repository contains utilities for efficiently performing Win32 IO operations in
4 4
 Go. Currently, this is focused on accessing named pipes and other file handles, and
... ...
@@ -5,7 +5,6 @@ package backuptar
5 5
 import (
6 6
 	"archive/tar"
7 7
 	"encoding/base64"
8
-	"errors"
9 8
 	"fmt"
10 9
 	"io"
11 10
 	"io/ioutil"
... ...
@@ -41,19 +40,14 @@ const (
41 41
 	hdrCreationTime = "LIBARCHIVE.creationtime"
42 42
 )
43 43
 
44
-func writeZeroes(w io.Writer, count int64) error {
45
-	buf := make([]byte, 8192)
46
-	c := len(buf)
47
-	for i := int64(0); i < count; i += int64(c) {
48
-		if int64(c) > count-i {
49
-			c = int(count - i)
50
-		}
51
-		_, err := w.Write(buf[:c])
52
-		if err != nil {
53
-			return err
54
-		}
44
+// zeroReader is an io.Reader that always returns 0s.
45
+type zeroReader struct{}
46
+
47
+func (zr zeroReader) Read(b []byte) (int, error) {
48
+	for i := range b {
49
+		b[i] = 0
55 50
 	}
56
-	return nil
51
+	return len(b), nil
57 52
 }
58 53
 
59 54
 func copySparse(t *tar.Writer, br *winio.BackupStreamReader) error {
... ...
@@ -70,16 +64,26 @@ func copySparse(t *tar.Writer, br *winio.BackupStreamReader) error {
70 70
 			return fmt.Errorf("unexpected stream %d", bhdr.Id)
71 71
 		}
72 72
 
73
+		// We can't seek backwards, since we have already written that data to the tar.Writer.
74
+		if bhdr.Offset < curOffset {
75
+			return fmt.Errorf("cannot seek back from %d to %d", curOffset, bhdr.Offset)
76
+		}
73 77
 		// archive/tar does not support writing sparse files
74 78
 		// so just write zeroes to catch up to the current offset.
75
-		err = writeZeroes(t, bhdr.Offset-curOffset)
79
+		if _, err := io.CopyN(t, zeroReader{}, bhdr.Offset-curOffset); err != nil {
80
+			return fmt.Errorf("seek to offset %d: %s", bhdr.Offset, err)
81
+		}
76 82
 		if bhdr.Size == 0 {
83
+			// A sparse block with size = 0 is used to mark the end of the sparse blocks.
77 84
 			break
78 85
 		}
79 86
 		n, err := io.Copy(t, br)
80 87
 		if err != nil {
81 88
 			return err
82 89
 		}
90
+		if n != bhdr.Size {
91
+			return fmt.Errorf("copied %d bytes instead of %d at offset %d", n, bhdr.Size, bhdr.Offset)
92
+		}
83 93
 		curOffset = bhdr.Offset + n
84 94
 	}
85 95
 	return nil
... ...
@@ -220,20 +224,44 @@ func WriteTarFileFromBackupStream(t *tar.Writer, r io.Reader, name string, size
220 220
 		}
221 221
 	}
222 222
 
223
+	// The logic for copying file contents is fairly complicated due to the need for handling sparse files,
224
+	// and the weird ways they are represented by BackupRead. A normal file will always either have a data stream
225
+	// with size and content, or no data stream at all (if empty). However, for a sparse file, the content can also
226
+	// be represented using a series of sparse block streams following the data stream. Additionally, the way sparse
227
+	// files are handled by BackupRead has changed in the OS recently. The specifics of the representation are described
228
+	// in the list at the bottom of this block comment.
229
+	//
230
+	// Sparse files can be represented in four different ways, based on the specifics of the file.
231
+	// - Size = 0:
232
+	//     Previously: BackupRead yields no data stream and no sparse block streams.
233
+	//     Recently: BackupRead yields a data stream with size = 0. There are no following sparse block streams.
234
+	// - Size > 0, no allocated ranges:
235
+	//     BackupRead yields a data stream with size = 0. Following is a single sparse block stream with
236
+	//     size = 0 and offset = <file size>.
237
+	// - Size > 0, one allocated range:
238
+	//     BackupRead yields a data stream with size = <file size> containing the file contents. There are no
239
+	//     sparse block streams. This is the case if you take a normal file with contents and simply set the
240
+	//     sparse flag on it.
241
+	// - Size > 0, multiple allocated ranges:
242
+	//     BackupRead yields a data stream with size = 0. Following are sparse block streams for each allocated
243
+	//     range of the file containing the range contents. Finally there is a sparse block stream with
244
+	//     size = 0 and offset = <file size>.
245
+
223 246
 	if dataHdr != nil {
224 247
 		// A data stream was found. Copy the data.
225
-		if (dataHdr.Attributes & winio.StreamSparseAttributes) == 0 {
248
+		// We assume that we will either have a data stream size > 0 XOR have sparse block streams.
249
+		if dataHdr.Size > 0 || (dataHdr.Attributes&winio.StreamSparseAttributes) == 0 {
226 250
 			if size != dataHdr.Size {
227 251
 				return fmt.Errorf("%s: mismatch between file size %d and header size %d", name, size, dataHdr.Size)
228 252
 			}
229
-			_, err = io.Copy(t, br)
230
-			if err != nil {
231
-				return err
253
+			if _, err = io.Copy(t, br); err != nil {
254
+				return fmt.Errorf("%s: copying contents from data stream: %s", name, err)
232 255
 			}
233
-		} else {
234
-			err = copySparse(t, br)
235
-			if err != nil {
236
-				return err
256
+		} else if size > 0 {
257
+			// As of a recent OS change, BackupRead now returns a data stream for empty sparse files.
258
+			// These files have no sparse block streams, so skip the copySparse call if file size = 0.
259
+			if err = copySparse(t, br); err != nil {
260
+				return fmt.Errorf("%s: copying contents from sparse block stream: %s", name, err)
237 261
 			}
238 262
 		}
239 263
 	}
... ...
@@ -278,7 +306,7 @@ func WriteTarFileFromBackupStream(t *tar.Writer, r io.Reader, name string, size
278 278
 			} else {
279 279
 				// Unsupported for now, since the size of the alternate stream is not present
280 280
 				// in the backup stream until after the data has been read.
281
-				return errors.New("tar of sparse alternate data streams is unsupported")
281
+				return fmt.Errorf("%s: tar of sparse alternate data streams is unsupported", name)
282 282
 			}
283 283
 		case winio.BackupEaData, winio.BackupLink, winio.BackupPropertyData, winio.BackupObjectId, winio.BackupTxfsData:
284 284
 			// ignore these streams
... ...
@@ -3,7 +3,7 @@ module github.com/Microsoft/go-winio
3 3
 go 1.12
4 4
 
5 5
 require (
6
-	github.com/pkg/errors v0.8.1
7
-	github.com/sirupsen/logrus v1.4.1
8
-	golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3
6
+	github.com/pkg/errors v0.9.1
7
+	github.com/sirupsen/logrus v1.7.0
8
+	golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c
9 9
 )
... ...
@@ -1,3 +1,5 @@
1
+// +build windows
2
+
1 3
 package winio
2 4
 
3 5
 import (
... ...
@@ -429,10 +429,10 @@ type PipeConfig struct {
429 429
 	// when the pipe is in message mode.
430 430
 	MessageMode bool
431 431
 
432
-	// InputBufferSize specifies the size the input buffer, in bytes.
432
+	// InputBufferSize specifies the size of the input buffer, in bytes.
433 433
 	InputBufferSize int32
434 434
 
435
-	// OutputBufferSize specifies the size the input buffer, in bytes.
435
+	// OutputBufferSize specifies the size of the output buffer, in bytes.
436 436
 	OutputBufferSize int32
437 437
 }
438 438
 
... ...
@@ -1,3 +1,5 @@
1
+// +build windows
2
+
1 3
 package etw
2 4
 
3 5
 import (
... ...
@@ -1,3 +1,5 @@
1
+// +build windows
2
+
1 3
 package etw
2 4
 
3 5
 import (
... ...
@@ -1,3 +1,5 @@
1
+// +build windows
2
+
1 3
 package etw
2 4
 
3 5
 import (
... ...
@@ -1,3 +1,4 @@
1
+// +build windows
1 2
 // +build amd64 arm64 386
2 3
 
3 4
 package etw
... ...
@@ -11,11 +12,20 @@ import (
11 11
 	"golang.org/x/sys/windows"
12 12
 )
13 13
 
14
-// NewProviderWithID creates and registers a new ETW provider, allowing the
15
-// provider ID to be manually specified. This is most useful when there is an
16
-// existing provider ID that must be used to conform to existing diagnostic
17
-// infrastructure.
18
-func NewProviderWithID(name string, id guid.GUID, callback EnableCallback) (provider *Provider, err error) {
14
+// NewProviderWithOptions creates and registers a new ETW provider, allowing
15
+// the provider ID and Group to be manually specified. This is most useful when
16
+// there is an existing provider ID that must be used to conform to existing
17
+// diagnostic infrastructure.
18
+func NewProviderWithOptions(name string, options ...ProviderOpt) (provider *Provider, err error) {
19
+	var opts providerOpts
20
+	for _, opt := range options {
21
+		opt(&opts)
22
+	}
23
+
24
+	if opts.id == (guid.GUID{}) {
25
+		opts.id = providerIDFromName(name)
26
+	}
27
+
19 28
 	providerCallbackOnce.Do(func() {
20 29
 		globalProviderCallback = windows.NewCallback(providerCallbackAdapter)
21 30
 	})
... ...
@@ -26,17 +36,27 @@ func NewProviderWithID(name string, id guid.GUID, callback EnableCallback) (prov
26 26
 			providers.removeProvider(provider)
27 27
 		}
28 28
 	}(provider)
29
-	provider.ID = id
30
-	provider.callback = callback
29
+	provider.ID = opts.id
30
+	provider.callback = opts.callback
31 31
 
32 32
 	if err := eventRegister((*windows.GUID)(&provider.ID), globalProviderCallback, uintptr(provider.index), &provider.handle); err != nil {
33 33
 		return nil, err
34 34
 	}
35 35
 
36
+	trait := &bytes.Buffer{}
37
+	if opts.group != (guid.GUID{}) {
38
+		binary.Write(trait, binary.LittleEndian, uint16(0)) // Write empty size for buffer (update later)
39
+		binary.Write(trait, binary.LittleEndian, uint8(1))  // EtwProviderTraitTypeGroup
40
+		traitArray := opts.group.ToWindowsArray()           // Append group guid
41
+		trait.Write(traitArray[:])
42
+		binary.LittleEndian.PutUint16(trait.Bytes(), uint16(trait.Len())) // Update size
43
+	}
44
+
36 45
 	metadata := &bytes.Buffer{}
37 46
 	binary.Write(metadata, binary.LittleEndian, uint16(0)) // Write empty size for buffer (to update later)
38 47
 	metadata.WriteString(name)
39 48
 	metadata.WriteByte(0)                                                   // Null terminator for name
49
+	trait.WriteTo(metadata)                                                 // Add traits if applicable
40 50
 	binary.LittleEndian.PutUint16(metadata.Bytes(), uint16(metadata.Len())) // Update the size at the beginning of the buffer
41 51
 	provider.metadata = metadata.Bytes()
42 52
 
... ...
@@ -1,12 +1,9 @@
1
+// +build windows
1 2
 // +build arm
2 3
 
3 4
 package etw
4 5
 
5
-import (
6
-	"github.com/Microsoft/go-winio/pkg/guid"
7
-)
8
-
9 6
 // NewProviderWithID returns a nil provider on unsupported platforms.
10
-func NewProviderWithID(name string, id guid.GUID, callback EnableCallback) (provider *Provider, err error) {
7
+func NewProviderWithOptions(name string, options ...ProviderOpt) (provider *Provider, err error) {
11 8
 	return nil, nil
12 9
 }
... ...
@@ -1,3 +1,5 @@
1
+// +build windows
2
+
1 3
 package etw
2 4
 
3 5
 import (
... ...
@@ -81,15 +83,6 @@ func providerCallback(sourceID guid.GUID, state ProviderState, level Level, matc
81 81
 	}
82 82
 }
83 83
 
84
-// providerCallbackAdapter acts as the first-level callback from the C/ETW side
85
-// for provider notifications. Because Go has trouble with callback arguments of
86
-// different size, it has only pointer-sized arguments, which are then cast to
87
-// the appropriate types when calling providerCallback.
88
-func providerCallbackAdapter(sourceID *guid.GUID, state uintptr, level uintptr, matchAnyKeyword uintptr, matchAllKeyword uintptr, filterData uintptr, i uintptr) uintptr {
89
-	providerCallback(*sourceID, ProviderState(state), Level(level), uint64(matchAnyKeyword), uint64(matchAllKeyword), filterData, i)
90
-	return 0
91
-}
92
-
93 84
 // providerIDFromName generates a provider ID based on the provider name. It
94 85
 // uses the same algorithm as used by .NET's EventSource class, which is based
95 86
 // on RFC 4122. More information on the algorithm can be found here:
... ...
@@ -117,10 +110,50 @@ func providerIDFromName(name string) guid.GUID {
117 117
 	return guid.FromWindowsArray(a)
118 118
 }
119 119
 
120
+type providerOpts struct {
121
+	callback EnableCallback
122
+	id       guid.GUID
123
+	group    guid.GUID
124
+}
125
+
126
+// ProviderOpt allows the caller to specify provider options to
127
+// NewProviderWithOptions
128
+type ProviderOpt func(*providerOpts)
129
+
130
+// WithCallback is used to provide a callback option to NewProviderWithOptions
131
+func WithCallback(callback EnableCallback) ProviderOpt {
132
+	return func(opts *providerOpts) {
133
+		opts.callback = callback
134
+	}
135
+}
136
+
137
+// WithID is used to provide a provider ID option to NewProviderWithOptions
138
+func WithID(id guid.GUID) ProviderOpt {
139
+	return func(opts *providerOpts) {
140
+		opts.id = id
141
+	}
142
+}
143
+
144
+// WithGroup is used to provide a provider group option to
145
+// NewProviderWithOptions
146
+func WithGroup(group guid.GUID) ProviderOpt {
147
+	return func(opts *providerOpts) {
148
+		opts.group = group
149
+	}
150
+}
151
+
152
+// NewProviderWithID creates and registers a new ETW provider, allowing the
153
+// provider ID to be manually specified. This is most useful when there is an
154
+// existing provider ID that must be used to conform to existing diagnostic
155
+// infrastructure.
156
+func NewProviderWithID(name string, id guid.GUID, callback EnableCallback) (provider *Provider, err error) {
157
+	return NewProviderWithOptions(name, WithID(id), WithCallback(callback))
158
+}
159
+
120 160
 // NewProvider creates and registers a new ETW provider. The provider ID is
121 161
 // generated based on the provider name.
122 162
 func NewProvider(name string, callback EnableCallback) (provider *Provider, err error) {
123
-	return NewProviderWithID(name, providerIDFromName(name), callback)
163
+	return NewProviderWithOptions(name, WithCallback(callback))
124 164
 }
125 165
 
126 166
 // Close unregisters the provider.
... ...
@@ -1,3 +1,5 @@
1
+// +build windows
2
+
1 3
 package etw
2 4
 
3 5
 import (
... ...
@@ -1,8 +1,10 @@
1
+// +build windows
1 2
 // +build 386 arm
2 3
 
3 4
 package etw
4 5
 
5 6
 import (
7
+	"github.com/Microsoft/go-winio/pkg/guid"
6 8
 	"golang.org/x/sys/windows"
7 9
 )
8 10
 
... ...
@@ -49,3 +51,17 @@ func eventSetInformation(
49 49
 		information,
50 50
 		length)
51 51
 }
52
+
53
+// providerCallbackAdapter acts as the first-level callback from the C/ETW side
54
+// for provider notifications. Because Go has trouble with callback arguments of
55
+// different size, it has only pointer-sized arguments, which are then cast to
56
+// the appropriate types when calling providerCallback.
57
+// For x86, the matchAny and matchAll keywords need to be assembled from two
58
+// 32-bit integers, because the max size of an argument is uintptr, but those
59
+// two arguments are actually 64-bit integers.
60
+func providerCallbackAdapter(sourceID *guid.GUID, state uint32, level uint32, matchAnyKeyword_low uint32, matchAnyKeyword_high uint32, matchAllKeyword_low uint32, matchAllKeyword_high uint32, filterData uintptr, i uintptr) uintptr {
61
+	matchAnyKeyword := uint64(matchAnyKeyword_high)<<32 | uint64(matchAnyKeyword_low)
62
+	matchAllKeyword := uint64(matchAllKeyword_high)<<32 | uint64(matchAllKeyword_low)
63
+	providerCallback(*sourceID, ProviderState(state), Level(level), uint64(matchAnyKeyword), uint64(matchAllKeyword), filterData, i)
64
+	return 0
65
+}
... ...
@@ -1,8 +1,10 @@
1
+// +build windows
1 2
 // +build amd64 arm64
2 3
 
3 4
 package etw
4 5
 
5 6
 import (
7
+	"github.com/Microsoft/go-winio/pkg/guid"
6 8
 	"golang.org/x/sys/windows"
7 9
 )
8 10
 
... ...
@@ -39,3 +41,12 @@ func eventSetInformation(
39 39
 		information,
40 40
 		length)
41 41
 }
42
+
43
+// providerCallbackAdapter acts as the first-level callback from the C/ETW side
44
+// for provider notifications. Because Go has trouble with callback arguments of
45
+// different size, it has only pointer-sized arguments, which are then cast to
46
+// the appropriate types when calling providerCallback.
47
+func providerCallbackAdapter(sourceID *guid.GUID, state uintptr, level uintptr, matchAnyKeyword uintptr, matchAllKeyword uintptr, filterData uintptr, i uintptr) uintptr {
48
+	providerCallback(*sourceID, ProviderState(state), Level(level), uint64(matchAnyKeyword), uint64(matchAllKeyword), filterData, i)
49
+	return 0
50
+}
... ...
@@ -19,6 +19,7 @@ const (
19 19
 
20 20
 var (
21 21
 	errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
22
+	errERROR_EINVAL     error = syscall.EINVAL
22 23
 )
23 24
 
24 25
 // errnoErr returns common boxed Errno values, to prevent
... ...
@@ -26,7 +27,7 @@ var (
26 26
 func errnoErr(e syscall.Errno) error {
27 27
 	switch e {
28 28
 	case 0:
29
-		return nil
29
+		return errERROR_EINVAL
30 30
 	case errnoERROR_IO_PENDING:
31 31
 		return errERROR_IO_PENDING
32 32
 	}
... ...
@@ -40,9 +41,9 @@ var (
40 40
 	modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
41 41
 
42 42
 	procEventRegister       = modadvapi32.NewProc("EventRegister")
43
+	procEventSetInformation = modadvapi32.NewProc("EventSetInformation")
43 44
 	procEventUnregister     = modadvapi32.NewProc("EventUnregister")
44 45
 	procEventWriteTransfer  = modadvapi32.NewProc("EventWriteTransfer")
45
-	procEventSetInformation = modadvapi32.NewProc("EventSetInformation")
46 46
 )
47 47
 
48 48
 func eventRegister(providerId *windows.GUID, callback uintptr, callbackContext uintptr, providerHandle *providerHandle) (win32err error) {
... ...
@@ -53,24 +54,24 @@ func eventRegister(providerId *windows.GUID, callback uintptr, callbackContext u
53 53
 	return
54 54
 }
55 55
 
56
-func eventUnregister_64(providerHandle providerHandle) (win32err error) {
57
-	r0, _, _ := syscall.Syscall(procEventUnregister.Addr(), 1, uintptr(providerHandle), 0, 0)
56
+func eventSetInformation_64(providerHandle providerHandle, class eventInfoClass, information uintptr, length uint32) (win32err error) {
57
+	r0, _, _ := syscall.Syscall6(procEventSetInformation.Addr(), 4, uintptr(providerHandle), uintptr(class), uintptr(information), uintptr(length), 0, 0)
58 58
 	if r0 != 0 {
59 59
 		win32err = syscall.Errno(r0)
60 60
 	}
61 61
 	return
62 62
 }
63 63
 
64
-func eventWriteTransfer_64(providerHandle providerHandle, descriptor *eventDescriptor, activityID *windows.GUID, relatedActivityID *windows.GUID, dataDescriptorCount uint32, dataDescriptors *eventDataDescriptor) (win32err error) {
65
-	r0, _, _ := syscall.Syscall6(procEventWriteTransfer.Addr(), 6, uintptr(providerHandle), uintptr(unsafe.Pointer(descriptor)), uintptr(unsafe.Pointer(activityID)), uintptr(unsafe.Pointer(relatedActivityID)), uintptr(dataDescriptorCount), uintptr(unsafe.Pointer(dataDescriptors)))
64
+func eventSetInformation_32(providerHandle_low uint32, providerHandle_high uint32, class eventInfoClass, information uintptr, length uint32) (win32err error) {
65
+	r0, _, _ := syscall.Syscall6(procEventSetInformation.Addr(), 5, uintptr(providerHandle_low), uintptr(providerHandle_high), uintptr(class), uintptr(information), uintptr(length), 0)
66 66
 	if r0 != 0 {
67 67
 		win32err = syscall.Errno(r0)
68 68
 	}
69 69
 	return
70 70
 }
71 71
 
72
-func eventSetInformation_64(providerHandle providerHandle, class eventInfoClass, information uintptr, length uint32) (win32err error) {
73
-	r0, _, _ := syscall.Syscall6(procEventSetInformation.Addr(), 4, uintptr(providerHandle), uintptr(class), uintptr(information), uintptr(length), 0, 0)
72
+func eventUnregister_64(providerHandle providerHandle) (win32err error) {
73
+	r0, _, _ := syscall.Syscall(procEventUnregister.Addr(), 1, uintptr(providerHandle), 0, 0)
74 74
 	if r0 != 0 {
75 75
 		win32err = syscall.Errno(r0)
76 76
 	}
... ...
@@ -85,16 +86,16 @@ func eventUnregister_32(providerHandle_low uint32, providerHandle_high uint32) (
85 85
 	return
86 86
 }
87 87
 
88
-func eventWriteTransfer_32(providerHandle_low uint32, providerHandle_high uint32, descriptor *eventDescriptor, activityID *windows.GUID, relatedActivityID *windows.GUID, dataDescriptorCount uint32, dataDescriptors *eventDataDescriptor) (win32err error) {
89
-	r0, _, _ := syscall.Syscall9(procEventWriteTransfer.Addr(), 7, uintptr(providerHandle_low), uintptr(providerHandle_high), uintptr(unsafe.Pointer(descriptor)), uintptr(unsafe.Pointer(activityID)), uintptr(unsafe.Pointer(relatedActivityID)), uintptr(dataDescriptorCount), uintptr(unsafe.Pointer(dataDescriptors)), 0, 0)
88
+func eventWriteTransfer_64(providerHandle providerHandle, descriptor *eventDescriptor, activityID *windows.GUID, relatedActivityID *windows.GUID, dataDescriptorCount uint32, dataDescriptors *eventDataDescriptor) (win32err error) {
89
+	r0, _, _ := syscall.Syscall6(procEventWriteTransfer.Addr(), 6, uintptr(providerHandle), uintptr(unsafe.Pointer(descriptor)), uintptr(unsafe.Pointer(activityID)), uintptr(unsafe.Pointer(relatedActivityID)), uintptr(dataDescriptorCount), uintptr(unsafe.Pointer(dataDescriptors)))
90 90
 	if r0 != 0 {
91 91
 		win32err = syscall.Errno(r0)
92 92
 	}
93 93
 	return
94 94
 }
95 95
 
96
-func eventSetInformation_32(providerHandle_low uint32, providerHandle_high uint32, class eventInfoClass, information uintptr, length uint32) (win32err error) {
97
-	r0, _, _ := syscall.Syscall6(procEventSetInformation.Addr(), 5, uintptr(providerHandle_low), uintptr(providerHandle_high), uintptr(class), uintptr(information), uintptr(length), 0)
96
+func eventWriteTransfer_32(providerHandle_low uint32, providerHandle_high uint32, descriptor *eventDescriptor, activityID *windows.GUID, relatedActivityID *windows.GUID, dataDescriptorCount uint32, dataDescriptors *eventDataDescriptor) (win32err error) {
97
+	r0, _, _ := syscall.Syscall9(procEventWriteTransfer.Addr(), 7, uintptr(providerHandle_low), uintptr(providerHandle_high), uintptr(unsafe.Pointer(descriptor)), uintptr(unsafe.Pointer(activityID)), uintptr(unsafe.Pointer(relatedActivityID)), uintptr(dataDescriptorCount), uintptr(unsafe.Pointer(dataDescriptors)), 0, 0)
98 98
 	if r0 != 0 {
99 99
 		win32err = syscall.Errno(r0)
100 100
 	}
... ...
@@ -1,3 +1,5 @@
1
+// +build windows
2
+
1 3
 package etwlogrus
2 4
 
3 5
 import (
... ...
@@ -1,3 +1,5 @@
1
+// +build windows
2
+
1 3
 // Package guid provides a GUID type. The backing structure for a GUID is
2 4
 // identical to that used by the golang.org/x/sys/windows GUID type.
3 5
 // There are two main binary encodings used for a GUID, the big-endian encoding,
... ...
@@ -1,3 +1,5 @@
1
+// +build windows
2
+
1 3
 package security
2 4
 
3 5
 import (
... ...
@@ -2,6 +2,6 @@ package security
2 2
 
3 3
 //go:generate go run mksyscall_windows.go -output zsyscall_windows.go syscall_windows.go
4 4
 
5
-//sys getSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, ppsidOwner **uintptr, ppsidGroup **uintptr, ppDacl *uintptr, ppSacl *uintptr, ppSecurityDescriptor *uintptr) (err error) [failretval!=0] = advapi32.GetSecurityInfo
6
-//sys setSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, psidOwner uintptr, psidGroup uintptr, pDacl uintptr, pSacl uintptr) (err error) [failretval!=0] = advapi32.SetSecurityInfo
7
-//sys setEntriesInAcl(count uintptr, pListOfEEs uintptr, oldAcl uintptr, newAcl *uintptr) (err error) [failretval!=0] = advapi32.SetEntriesInAclW
5
+//sys getSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, ppsidOwner **uintptr, ppsidGroup **uintptr, ppDacl *uintptr, ppSacl *uintptr, ppSecurityDescriptor *uintptr) (win32err error) = advapi32.GetSecurityInfo
6
+//sys setSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, psidOwner uintptr, psidGroup uintptr, pDacl uintptr, pSacl uintptr) (win32err error) = advapi32.SetSecurityInfo
7
+//sys setEntriesInAcl(count uintptr, pListOfEEs uintptr, oldAcl uintptr, newAcl *uintptr) (win32err error) = advapi32.SetEntriesInAclW
... ...
@@ -1,4 +1,4 @@
1
-// Code generated mksyscall_windows.exe DO NOT EDIT
1
+// Code generated by 'go generate'; DO NOT EDIT.
2 2
 
3 3
 package security
4 4
 
... ...
@@ -19,6 +19,7 @@ const (
19 19
 
20 20
 var (
21 21
 	errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
22
+	errERROR_EINVAL     error = syscall.EINVAL
22 23
 )
23 24
 
24 25
 // errnoErr returns common boxed Errno values, to prevent
... ...
@@ -26,7 +27,7 @@ var (
26 26
 func errnoErr(e syscall.Errno) error {
27 27
 	switch e {
28 28
 	case 0:
29
-		return nil
29
+		return errERROR_EINVAL
30 30
 	case errnoERROR_IO_PENDING:
31 31
 		return errERROR_IO_PENDING
32 32
 	}
... ...
@@ -40,42 +41,30 @@ var (
40 40
 	modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
41 41
 
42 42
 	procGetSecurityInfo  = modadvapi32.NewProc("GetSecurityInfo")
43
-	procSetSecurityInfo  = modadvapi32.NewProc("SetSecurityInfo")
44 43
 	procSetEntriesInAclW = modadvapi32.NewProc("SetEntriesInAclW")
44
+	procSetSecurityInfo  = modadvapi32.NewProc("SetSecurityInfo")
45 45
 )
46 46
 
47
-func getSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, ppsidOwner **uintptr, ppsidGroup **uintptr, ppDacl *uintptr, ppSacl *uintptr, ppSecurityDescriptor *uintptr) (err error) {
48
-	r1, _, e1 := syscall.Syscall9(procGetSecurityInfo.Addr(), 8, uintptr(handle), uintptr(objectType), uintptr(si), uintptr(unsafe.Pointer(ppsidOwner)), uintptr(unsafe.Pointer(ppsidGroup)), uintptr(unsafe.Pointer(ppDacl)), uintptr(unsafe.Pointer(ppSacl)), uintptr(unsafe.Pointer(ppSecurityDescriptor)), 0)
49
-	if r1 != 0 {
50
-		if e1 != 0 {
51
-			err = errnoErr(e1)
52
-		} else {
53
-			err = syscall.EINVAL
54
-		}
47
+func getSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, ppsidOwner **uintptr, ppsidGroup **uintptr, ppDacl *uintptr, ppSacl *uintptr, ppSecurityDescriptor *uintptr) (win32err error) {
48
+	r0, _, _ := syscall.Syscall9(procGetSecurityInfo.Addr(), 8, uintptr(handle), uintptr(objectType), uintptr(si), uintptr(unsafe.Pointer(ppsidOwner)), uintptr(unsafe.Pointer(ppsidGroup)), uintptr(unsafe.Pointer(ppDacl)), uintptr(unsafe.Pointer(ppSacl)), uintptr(unsafe.Pointer(ppSecurityDescriptor)), 0)
49
+	if r0 != 0 {
50
+		win32err = syscall.Errno(r0)
55 51
 	}
56 52
 	return
57 53
 }
58 54
 
59
-func setSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, psidOwner uintptr, psidGroup uintptr, pDacl uintptr, pSacl uintptr) (err error) {
60
-	r1, _, e1 := syscall.Syscall9(procSetSecurityInfo.Addr(), 7, uintptr(handle), uintptr(objectType), uintptr(si), uintptr(psidOwner), uintptr(psidGroup), uintptr(pDacl), uintptr(pSacl), 0, 0)
61
-	if r1 != 0 {
62
-		if e1 != 0 {
63
-			err = errnoErr(e1)
64
-		} else {
65
-			err = syscall.EINVAL
66
-		}
55
+func setEntriesInAcl(count uintptr, pListOfEEs uintptr, oldAcl uintptr, newAcl *uintptr) (win32err error) {
56
+	r0, _, _ := syscall.Syscall6(procSetEntriesInAclW.Addr(), 4, uintptr(count), uintptr(pListOfEEs), uintptr(oldAcl), uintptr(unsafe.Pointer(newAcl)), 0, 0)
57
+	if r0 != 0 {
58
+		win32err = syscall.Errno(r0)
67 59
 	}
68 60
 	return
69 61
 }
70 62
 
71
-func setEntriesInAcl(count uintptr, pListOfEEs uintptr, oldAcl uintptr, newAcl *uintptr) (err error) {
72
-	r1, _, e1 := syscall.Syscall6(procSetEntriesInAclW.Addr(), 4, uintptr(count), uintptr(pListOfEEs), uintptr(oldAcl), uintptr(unsafe.Pointer(newAcl)), 0, 0)
73
-	if r1 != 0 {
74
-		if e1 != 0 {
75
-			err = errnoErr(e1)
76
-		} else {
77
-			err = syscall.EINVAL
78
-		}
63
+func setSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, psidOwner uintptr, psidGroup uintptr, pDacl uintptr, pSacl uintptr) (win32err error) {
64
+	r0, _, _ := syscall.Syscall9(procSetSecurityInfo.Addr(), 7, uintptr(handle), uintptr(objectType), uintptr(si), uintptr(psidOwner), uintptr(psidGroup), uintptr(pDacl), uintptr(pSacl), 0, 0)
65
+	if r0 != 0 {
66
+		win32err = syscall.Errno(r0)
79 67
 	}
80 68
 	return
81 69
 }
... ...
@@ -28,8 +28,9 @@ const (
28 28
 
29 29
 	ERROR_NOT_ALL_ASSIGNED syscall.Errno = 1300
30 30
 
31
-	SeBackupPrivilege  = "SeBackupPrivilege"
32
-	SeRestorePrivilege = "SeRestorePrivilege"
31
+	SeBackupPrivilege   = "SeBackupPrivilege"
32
+	SeRestorePrivilege  = "SeRestorePrivilege"
33
+	SeSecurityPrivilege = "SeSecurityPrivilege"
33 34
 )
34 35
 
35 36
 const (
... ...
@@ -1,3 +1,3 @@
1 1
 package winio
2 2
 
3
-//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go file.go pipe.go sd.go fileinfo.go privilege.go backup.go hvsock.go
3
+//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go file.go pipe.go sd.go fileinfo.go privilege.go backup.go hvsock.go
... ...
@@ -2,150 +2,322 @@
2 2
 
3 3
 package vhd
4 4
 
5
-import "syscall"
5
+import (
6
+	"fmt"
7
+	"syscall"
6 8
 
7
-//go:generate go run mksyscall_windows.go -output zvhd.go vhd.go
9
+	"github.com/Microsoft/go-winio/pkg/guid"
10
+	"github.com/pkg/errors"
11
+	"golang.org/x/sys/windows"
12
+)
8 13
 
9
-//sys createVirtualDisk(virtualStorageType *virtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, flags uint32, providerSpecificFlags uint32, parameters *createVirtualDiskParameters, o *syscall.Overlapped, handle *syscall.Handle) (err error) [failretval != 0] = VirtDisk.CreateVirtualDisk
10
-//sys openVirtualDisk(virtualStorageType *virtualStorageType, path string, virtualDiskAccessMask uint32, flags uint32, parameters *openVirtualDiskParameters, handle *syscall.Handle) (err error) [failretval != 0] = VirtDisk.OpenVirtualDisk
11
-//sys detachVirtualDisk(handle syscall.Handle, flags uint32, providerSpecificFlags uint32) (err error) [failretval != 0] = VirtDisk.DetachVirtualDisk
14
+//go:generate go run mksyscall_windows.go -output zvhd_windows.go vhd.go
12 15
 
13
-type virtualStorageType struct {
14
-	DeviceID uint32
15
-	VendorID [16]byte
16
-}
16
+//sys createVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, createVirtualDiskFlags uint32, providerSpecificFlags uint32, parameters *CreateVirtualDiskParameters, overlapped *syscall.Overlapped, handle *syscall.Handle) (win32err error) = virtdisk.CreateVirtualDisk
17
+//sys openVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *OpenVirtualDiskParameters, handle *syscall.Handle) (win32err error) = virtdisk.OpenVirtualDisk
18
+//sys attachVirtualDisk(handle syscall.Handle, securityDescriptor *uintptr, attachVirtualDiskFlag uint32, providerSpecificFlags uint32, parameters *AttachVirtualDiskParameters, overlapped *syscall.Overlapped) (win32err error) = virtdisk.AttachVirtualDisk
19
+//sys detachVirtualDisk(handle syscall.Handle, detachVirtualDiskFlags uint32, providerSpecificFlags uint32) (win32err error) = virtdisk.DetachVirtualDisk
20
+//sys getVirtualDiskPhysicalPath(handle syscall.Handle, diskPathSizeInBytes *uint32, buffer *uint16) (win32err error) = virtdisk.GetVirtualDiskPhysicalPath
17 21
 
18 22
 type (
19
-	createVirtualDiskFlag uint32
20
-	VirtualDiskAccessMask uint32
23
+	CreateVirtualDiskFlag uint32
21 24
 	VirtualDiskFlag       uint32
25
+	AttachVirtualDiskFlag uint32
26
+	DetachVirtualDiskFlag uint32
27
+	VirtualDiskAccessMask uint32
22 28
 )
23 29
 
24
-const (
25
-	// Flags for creating a VHD (not exported)
26
-	createVirtualDiskFlagNone                        createVirtualDiskFlag = 0
27
-	createVirtualDiskFlagFullPhysicalAllocation      createVirtualDiskFlag = 1
28
-	createVirtualDiskFlagPreventWritesToSourceDisk   createVirtualDiskFlag = 2
29
-	createVirtualDiskFlagDoNotCopyMetadataFromParent createVirtualDiskFlag = 4
30
-
31
-	// Access Mask for opening a VHD
32
-	VirtualDiskAccessNone     VirtualDiskAccessMask = 0
33
-	VirtualDiskAccessAttachRO VirtualDiskAccessMask = 65536
34
-	VirtualDiskAccessAttachRW VirtualDiskAccessMask = 131072
35
-	VirtualDiskAccessDetach   VirtualDiskAccessMask = 262144
36
-	VirtualDiskAccessGetInfo  VirtualDiskAccessMask = 524288
37
-	VirtualDiskAccessCreate   VirtualDiskAccessMask = 1048576
38
-	VirtualDiskAccessMetaOps  VirtualDiskAccessMask = 2097152
39
-	VirtualDiskAccessRead     VirtualDiskAccessMask = 851968
40
-	VirtualDiskAccessAll      VirtualDiskAccessMask = 4128768
41
-	VirtualDiskAccessWritable VirtualDiskAccessMask = 3276800
42
-
43
-	// Flags for opening a VHD
44
-	OpenVirtualDiskFlagNone                        VirtualDiskFlag = 0
45
-	OpenVirtualDiskFlagNoParents                   VirtualDiskFlag = 0x1
46
-	OpenVirtualDiskFlagBlankFile                   VirtualDiskFlag = 0x2
47
-	OpenVirtualDiskFlagBootDrive                   VirtualDiskFlag = 0x4
48
-	OpenVirtualDiskFlagCachedIO                    VirtualDiskFlag = 0x8
49
-	OpenVirtualDiskFlagCustomDiffChain             VirtualDiskFlag = 0x10
50
-	OpenVirtualDiskFlagParentCachedIO              VirtualDiskFlag = 0x20
51
-	OpenVirtualDiskFlagVhdSetFileOnly              VirtualDiskFlag = 0x40
52
-	OpenVirtualDiskFlagIgnoreRelativeParentLocator VirtualDiskFlag = 0x80
53
-	OpenVirtualDiskFlagNoWriteHardening            VirtualDiskFlag = 0x100
54
-)
30
+type VirtualStorageType struct {
31
+	DeviceID uint32
32
+	VendorID guid.GUID
33
+}
55 34
 
56
-type createVersion2 struct {
57
-	UniqueID                 [16]byte // GUID
35
+type CreateVersion2 struct {
36
+	UniqueID                 guid.GUID
58 37
 	MaximumSize              uint64
59 38
 	BlockSizeInBytes         uint32
60 39
 	SectorSizeInBytes        uint32
40
+	PhysicalSectorSizeInByte uint32
61 41
 	ParentPath               *uint16 // string
62 42
 	SourcePath               *uint16 // string
63 43
 	OpenFlags                uint32
64
-	ParentVirtualStorageType virtualStorageType
65
-	SourceVirtualStorageType virtualStorageType
66
-	ResiliencyGUID           [16]byte // GUID
44
+	ParentVirtualStorageType VirtualStorageType
45
+	SourceVirtualStorageType VirtualStorageType
46
+	ResiliencyGUID           guid.GUID
67 47
 }
68 48
 
69
-type createVirtualDiskParameters struct {
49
+type CreateVirtualDiskParameters struct {
70 50
 	Version  uint32 // Must always be set to 2
71
-	Version2 createVersion2
51
+	Version2 CreateVersion2
72 52
 }
73 53
 
74
-type openVersion2 struct {
75
-	GetInfoOnly    int32    // bool but 4-byte aligned
76
-	ReadOnly       int32    // bool but 4-byte aligned
77
-	ResiliencyGUID [16]byte // GUID
54
+type OpenVersion2 struct {
55
+	GetInfoOnly    bool
56
+	ReadOnly       bool
57
+	ResiliencyGUID guid.GUID
78 58
 }
79 59
 
80
-type openVirtualDiskParameters struct {
60
+type OpenVirtualDiskParameters struct {
81 61
 	Version  uint32 // Must always be set to 2
82
-	Version2 openVersion2
62
+	Version2 OpenVersion2
83 63
 }
84 64
 
85
-// CreateVhdx will create a simple vhdx file at the given path using default values.
86
-func CreateVhdx(path string, maxSizeInGb, blockSizeInMb uint32) error {
87
-	var (
88
-		defaultType virtualStorageType
89
-		handle      syscall.Handle
90
-	)
65
+type AttachVersion2 struct {
66
+	RestrictedOffset uint64
67
+	RestrictedLength uint64
68
+}
69
+
70
+type AttachVirtualDiskParameters struct {
71
+	Version  uint32 // Must always be set to 2
72
+	Version2 AttachVersion2
73
+}
91 74
 
92
-	parameters := createVirtualDiskParameters{
75
+const (
76
+	VIRTUAL_STORAGE_TYPE_DEVICE_VHDX = 0x3
77
+
78
+	// Access Mask for opening a VHD
79
+	VirtualDiskAccessNone     VirtualDiskAccessMask = 0x00000000
80
+	VirtualDiskAccessAttachRO VirtualDiskAccessMask = 0x00010000
81
+	VirtualDiskAccessAttachRW VirtualDiskAccessMask = 0x00020000
82
+	VirtualDiskAccessDetach   VirtualDiskAccessMask = 0x00040000
83
+	VirtualDiskAccessGetInfo  VirtualDiskAccessMask = 0x00080000
84
+	VirtualDiskAccessCreate   VirtualDiskAccessMask = 0x00100000
85
+	VirtualDiskAccessMetaOps  VirtualDiskAccessMask = 0x00200000
86
+	VirtualDiskAccessRead     VirtualDiskAccessMask = 0x000d0000
87
+	VirtualDiskAccessAll      VirtualDiskAccessMask = 0x003f0000
88
+	VirtualDiskAccessWritable VirtualDiskAccessMask = 0x00320000
89
+
90
+	// Flags for creating a VHD
91
+	CreateVirtualDiskFlagNone                              CreateVirtualDiskFlag = 0x0
92
+	CreateVirtualDiskFlagFullPhysicalAllocation            CreateVirtualDiskFlag = 0x1
93
+	CreateVirtualDiskFlagPreventWritesToSourceDisk         CreateVirtualDiskFlag = 0x2
94
+	CreateVirtualDiskFlagDoNotCopyMetadataFromParent       CreateVirtualDiskFlag = 0x4
95
+	CreateVirtualDiskFlagCreateBackingStorage              CreateVirtualDiskFlag = 0x8
96
+	CreateVirtualDiskFlagUseChangeTrackingSourceLimit      CreateVirtualDiskFlag = 0x10
97
+	CreateVirtualDiskFlagPreserveParentChangeTrackingState CreateVirtualDiskFlag = 0x20
98
+	CreateVirtualDiskFlagVhdSetUseOriginalBackingStorage   CreateVirtualDiskFlag = 0x40
99
+	CreateVirtualDiskFlagSparseFile                        CreateVirtualDiskFlag = 0x80
100
+	CreateVirtualDiskFlagPmemCompatible                    CreateVirtualDiskFlag = 0x100
101
+	CreateVirtualDiskFlagSupportCompressedVolumes          CreateVirtualDiskFlag = 0x200
102
+
103
+	// Flags for opening a VHD
104
+	OpenVirtualDiskFlagNone                        VirtualDiskFlag = 0x00000000
105
+	OpenVirtualDiskFlagNoParents                   VirtualDiskFlag = 0x00000001
106
+	OpenVirtualDiskFlagBlankFile                   VirtualDiskFlag = 0x00000002
107
+	OpenVirtualDiskFlagBootDrive                   VirtualDiskFlag = 0x00000004
108
+	OpenVirtualDiskFlagCachedIO                    VirtualDiskFlag = 0x00000008
109
+	OpenVirtualDiskFlagCustomDiffChain             VirtualDiskFlag = 0x00000010
110
+	OpenVirtualDiskFlagParentCachedIO              VirtualDiskFlag = 0x00000020
111
+	OpenVirtualDiskFlagVhdsetFileOnly              VirtualDiskFlag = 0x00000040
112
+	OpenVirtualDiskFlagIgnoreRelativeParentLocator VirtualDiskFlag = 0x00000080
113
+	OpenVirtualDiskFlagNoWriteHardening            VirtualDiskFlag = 0x00000100
114
+	OpenVirtualDiskFlagSupportCompressedVolumes    VirtualDiskFlag = 0x00000200
115
+
116
+	// Flags for attaching a VHD
117
+	AttachVirtualDiskFlagNone                          AttachVirtualDiskFlag = 0x00000000
118
+	AttachVirtualDiskFlagReadOnly                      AttachVirtualDiskFlag = 0x00000001
119
+	AttachVirtualDiskFlagNoDriveLetter                 AttachVirtualDiskFlag = 0x00000002
120
+	AttachVirtualDiskFlagPermanentLifetime             AttachVirtualDiskFlag = 0x00000004
121
+	AttachVirtualDiskFlagNoLocalHost                   AttachVirtualDiskFlag = 0x00000008
122
+	AttachVirtualDiskFlagNoSecurityDescriptor          AttachVirtualDiskFlag = 0x00000010
123
+	AttachVirtualDiskFlagBypassDefaultEncryptionPolicy AttachVirtualDiskFlag = 0x00000020
124
+	AttachVirtualDiskFlagNonPnp                        AttachVirtualDiskFlag = 0x00000040
125
+	AttachVirtualDiskFlagRestrictedRange               AttachVirtualDiskFlag = 0x00000080
126
+	AttachVirtualDiskFlagSinglePartition               AttachVirtualDiskFlag = 0x00000100
127
+	AttachVirtualDiskFlagRegisterVolume                AttachVirtualDiskFlag = 0x00000200
128
+
129
+	// Flags for detaching a VHD
130
+	DetachVirtualDiskFlagNone DetachVirtualDiskFlag = 0x0
131
+)
132
+
133
+// CreateVhdx is a helper function to create a simple vhdx file at the given path using
134
+// default values.
135
+func CreateVhdx(path string, maxSizeInGb, blockSizeInMb uint32) error {
136
+	params := CreateVirtualDiskParameters{
93 137
 		Version: 2,
94
-		Version2: createVersion2{
138
+		Version2: CreateVersion2{
95 139
 			MaximumSize:      uint64(maxSizeInGb) * 1024 * 1024 * 1024,
96 140
 			BlockSizeInBytes: blockSizeInMb * 1024 * 1024,
97 141
 		},
98 142
 	}
99 143
 
100
-	if err := createVirtualDisk(
101
-		&defaultType,
102
-		path,
103
-		uint32(VirtualDiskAccessNone),
104
-		nil,
105
-		uint32(createVirtualDiskFlagNone),
106
-		0,
107
-		&parameters,
108
-		nil,
109
-		&handle); err != nil {
144
+	handle, err := CreateVirtualDisk(path, VirtualDiskAccessNone, CreateVirtualDiskFlagNone, &params)
145
+	if err != nil {
110 146
 		return err
111 147
 	}
112 148
 
113 149
 	if err := syscall.CloseHandle(handle); err != nil {
114 150
 		return err
115 151
 	}
152
+	return nil
153
+}
116 154
 
155
+// DetachVirtualDisk detaches a virtual hard disk by handle.
156
+func DetachVirtualDisk(handle syscall.Handle) (err error) {
157
+	if err := detachVirtualDisk(handle, 0, 0); err != nil {
158
+		return errors.Wrap(err, "failed to detach virtual disk")
159
+	}
117 160
 	return nil
118 161
 }
119 162
 
120
-// DetachVhd detaches a mounted container layer vhd found at `path`.
163
+// DetachVhd detaches a vhd found at `path`.
121 164
 func DetachVhd(path string) error {
122 165
 	handle, err := OpenVirtualDisk(
123 166
 		path,
124 167
 		VirtualDiskAccessNone,
125
-		OpenVirtualDiskFlagCachedIO|OpenVirtualDiskFlagIgnoreRelativeParentLocator)
168
+		OpenVirtualDiskFlagCachedIO|OpenVirtualDiskFlagIgnoreRelativeParentLocator,
169
+	)
170
+	if err != nil {
171
+		return err
172
+	}
173
+	defer syscall.CloseHandle(handle)
174
+	return DetachVirtualDisk(handle)
175
+}
126 176
 
177
+// AttachVirtualDisk attaches a virtual hard disk for use.
178
+func AttachVirtualDisk(handle syscall.Handle, attachVirtualDiskFlag AttachVirtualDiskFlag, parameters *AttachVirtualDiskParameters) (err error) {
179
+	// Supports both version 1 and 2 of the attach parameters as version 2 wasn't present in RS5.
180
+	if err := attachVirtualDisk(
181
+		handle,
182
+		nil,
183
+		uint32(attachVirtualDiskFlag),
184
+		0,
185
+		parameters,
186
+		nil,
187
+	); err != nil {
188
+		return errors.Wrap(err, "failed to attach virtual disk")
189
+	}
190
+	return nil
191
+}
192
+
193
+// AttachVhd attaches a virtual hard disk at `path` for use. Attaches using version 2
194
+// of the ATTACH_VIRTUAL_DISK_PARAMETERS.
195
+func AttachVhd(path string) (err error) {
196
+	handle, err := OpenVirtualDisk(
197
+		path,
198
+		VirtualDiskAccessNone,
199
+		OpenVirtualDiskFlagCachedIO|OpenVirtualDiskFlagIgnoreRelativeParentLocator,
200
+	)
127 201
 	if err != nil {
128 202
 		return err
129 203
 	}
204
+
130 205
 	defer syscall.CloseHandle(handle)
131
-	return detachVirtualDisk(handle, 0, 0)
206
+	params := AttachVirtualDiskParameters{Version: 2}
207
+	if err := AttachVirtualDisk(
208
+		handle,
209
+		AttachVirtualDiskFlagNone,
210
+		&params,
211
+	); err != nil {
212
+		return errors.Wrap(err, "failed to attach virtual disk")
213
+	}
214
+	return nil
132 215
 }
133 216
 
134 217
 // OpenVirtualDisk obtains a handle to a VHD opened with supplied access mask and flags.
135
-func OpenVirtualDisk(path string, accessMask VirtualDiskAccessMask, flag VirtualDiskFlag) (syscall.Handle, error) {
218
+func OpenVirtualDisk(vhdPath string, virtualDiskAccessMask VirtualDiskAccessMask, openVirtualDiskFlags VirtualDiskFlag) (syscall.Handle, error) {
219
+	parameters := OpenVirtualDiskParameters{Version: 2}
220
+	handle, err := OpenVirtualDiskWithParameters(
221
+		vhdPath,
222
+		virtualDiskAccessMask,
223
+		openVirtualDiskFlags,
224
+		&parameters,
225
+	)
226
+	if err != nil {
227
+		return 0, err
228
+	}
229
+	return handle, nil
230
+}
231
+
232
+// OpenVirtualDiskWithParameters obtains a handle to a VHD opened with supplied access mask, flags and parameters.
233
+func OpenVirtualDiskWithParameters(vhdPath string, virtualDiskAccessMask VirtualDiskAccessMask, openVirtualDiskFlags VirtualDiskFlag, parameters *OpenVirtualDiskParameters) (syscall.Handle, error) {
136 234
 	var (
137
-		defaultType virtualStorageType
138 235
 		handle      syscall.Handle
236
+		defaultType VirtualStorageType
139 237
 	)
140
-	parameters := openVirtualDiskParameters{Version: 2}
238
+	if parameters.Version != 2 {
239
+		return handle, fmt.Errorf("only version 2 VHDs are supported, found version: %d", parameters.Version)
240
+	}
141 241
 	if err := openVirtualDisk(
142 242
 		&defaultType,
243
+		vhdPath,
244
+		uint32(virtualDiskAccessMask),
245
+		uint32(openVirtualDiskFlags),
246
+		parameters,
247
+		&handle,
248
+	); err != nil {
249
+		return 0, errors.Wrap(err, "failed to open virtual disk")
250
+	}
251
+	return handle, nil
252
+}
253
+
254
+// CreateVirtualDisk creates a virtual harddisk and returns a handle to the disk.
255
+func CreateVirtualDisk(path string, virtualDiskAccessMask VirtualDiskAccessMask, createVirtualDiskFlags CreateVirtualDiskFlag, parameters *CreateVirtualDiskParameters) (syscall.Handle, error) {
256
+	var (
257
+		handle      syscall.Handle
258
+		defaultType VirtualStorageType
259
+	)
260
+	if parameters.Version != 2 {
261
+		return handle, fmt.Errorf("only version 2 VHDs are supported, found version: %d", parameters.Version)
262
+	}
263
+
264
+	if err := createVirtualDisk(
265
+		&defaultType,
143 266
 		path,
144
-		uint32(accessMask),
145
-		uint32(flag),
146
-		&parameters,
147
-		&handle); err != nil {
148
-		return 0, err
267
+		uint32(virtualDiskAccessMask),
268
+		nil,
269
+		uint32(createVirtualDiskFlags),
270
+		0,
271
+		parameters,
272
+		nil,
273
+		&handle,
274
+	); err != nil {
275
+		return handle, errors.Wrap(err, "failed to create virtual disk")
149 276
 	}
150 277
 	return handle, nil
151 278
 }
279
+
280
+// GetVirtualDiskPhysicalPath takes a handle to a virtual hard disk and returns the physical
281
+// path of the disk on the machine. This path is in the form \\.\PhysicalDriveX where X is an integer
282
+// that represents the particular enumeration of the physical disk on the caller's system.
283
+func GetVirtualDiskPhysicalPath(handle syscall.Handle) (_ string, err error) {
284
+	var (
285
+		diskPathSizeInBytes uint32 = 256 * 2 // max path length 256 wide chars
286
+		diskPhysicalPathBuf [256]uint16
287
+	)
288
+	if err := getVirtualDiskPhysicalPath(
289
+		handle,
290
+		&diskPathSizeInBytes,
291
+		&diskPhysicalPathBuf[0],
292
+	); err != nil {
293
+		return "", errors.Wrap(err, "failed to get disk physical path")
294
+	}
295
+	return windows.UTF16ToString(diskPhysicalPathBuf[:]), nil
296
+}
297
+
298
+// CreateDiffVhd is a helper function to create a differencing virtual disk.
299
+func CreateDiffVhd(diffVhdPath, baseVhdPath string, blockSizeInMB uint32) error {
300
+	// Setting `ParentPath` is how to signal to create a differencing disk.
301
+	createParams := &CreateVirtualDiskParameters{
302
+		Version: 2,
303
+		Version2: CreateVersion2{
304
+			ParentPath:       windows.StringToUTF16Ptr(baseVhdPath),
305
+			BlockSizeInBytes: blockSizeInMB * 1024 * 1024,
306
+			OpenFlags:        uint32(OpenVirtualDiskFlagCachedIO),
307
+		},
308
+	}
309
+
310
+	vhdHandle, err := CreateVirtualDisk(
311
+		diffVhdPath,
312
+		VirtualDiskAccessNone,
313
+		CreateVirtualDiskFlagNone,
314
+		createParams,
315
+	)
316
+	if err != nil {
317
+		return fmt.Errorf("failed to create differencing vhd: %s", err)
318
+	}
319
+	if err := syscall.CloseHandle(vhdHandle); err != nil {
320
+		return fmt.Errorf("failed to close differencing vhd handle: %s", err)
321
+	}
322
+	return nil
323
+}
152 324
deleted file mode 100644
... ...
@@ -1,99 +0,0 @@
1
-// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
2
-
3
-package vhd
4
-
5
-import (
6
-	"syscall"
7
-	"unsafe"
8
-
9
-	"golang.org/x/sys/windows"
10
-)
11
-
12
-var _ unsafe.Pointer
13
-
14
-// Do the interface allocations only once for common
15
-// Errno values.
16
-const (
17
-	errnoERROR_IO_PENDING = 997
18
-)
19
-
20
-var (
21
-	errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
22
-)
23
-
24
-// errnoErr returns common boxed Errno values, to prevent
25
-// allocations at runtime.
26
-func errnoErr(e syscall.Errno) error {
27
-	switch e {
28
-	case 0:
29
-		return nil
30
-	case errnoERROR_IO_PENDING:
31
-		return errERROR_IO_PENDING
32
-	}
33
-	// TODO: add more here, after collecting data on the common
34
-	// error values see on Windows. (perhaps when running
35
-	// all.bat?)
36
-	return e
37
-}
38
-
39
-var (
40
-	modVirtDisk = windows.NewLazySystemDLL("VirtDisk.dll")
41
-
42
-	procCreateVirtualDisk = modVirtDisk.NewProc("CreateVirtualDisk")
43
-	procOpenVirtualDisk   = modVirtDisk.NewProc("OpenVirtualDisk")
44
-	procDetachVirtualDisk = modVirtDisk.NewProc("DetachVirtualDisk")
45
-)
46
-
47
-func createVirtualDisk(virtualStorageType *virtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, flags uint32, providerSpecificFlags uint32, parameters *createVirtualDiskParameters, o *syscall.Overlapped, handle *syscall.Handle) (err error) {
48
-	var _p0 *uint16
49
-	_p0, err = syscall.UTF16PtrFromString(path)
50
-	if err != nil {
51
-		return
52
-	}
53
-	return _createVirtualDisk(virtualStorageType, _p0, virtualDiskAccessMask, securityDescriptor, flags, providerSpecificFlags, parameters, o, handle)
54
-}
55
-
56
-func _createVirtualDisk(virtualStorageType *virtualStorageType, path *uint16, virtualDiskAccessMask uint32, securityDescriptor *uintptr, flags uint32, providerSpecificFlags uint32, parameters *createVirtualDiskParameters, o *syscall.Overlapped, handle *syscall.Handle) (err error) {
57
-	r1, _, e1 := syscall.Syscall9(procCreateVirtualDisk.Addr(), 9, uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(unsafe.Pointer(securityDescriptor)), uintptr(flags), uintptr(providerSpecificFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(handle)))
58
-	if r1 != 0 {
59
-		if e1 != 0 {
60
-			err = errnoErr(e1)
61
-		} else {
62
-			err = syscall.EINVAL
63
-		}
64
-	}
65
-	return
66
-}
67
-
68
-func openVirtualDisk(virtualStorageType *virtualStorageType, path string, virtualDiskAccessMask uint32, flags uint32, parameters *openVirtualDiskParameters, handle *syscall.Handle) (err error) {
69
-	var _p0 *uint16
70
-	_p0, err = syscall.UTF16PtrFromString(path)
71
-	if err != nil {
72
-		return
73
-	}
74
-	return _openVirtualDisk(virtualStorageType, _p0, virtualDiskAccessMask, flags, parameters, handle)
75
-}
76
-
77
-func _openVirtualDisk(virtualStorageType *virtualStorageType, path *uint16, virtualDiskAccessMask uint32, flags uint32, parameters *openVirtualDiskParameters, handle *syscall.Handle) (err error) {
78
-	r1, _, e1 := syscall.Syscall6(procOpenVirtualDisk.Addr(), 6, uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(flags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(handle)))
79
-	if r1 != 0 {
80
-		if e1 != 0 {
81
-			err = errnoErr(e1)
82
-		} else {
83
-			err = syscall.EINVAL
84
-		}
85
-	}
86
-	return
87
-}
88
-
89
-func detachVirtualDisk(handle syscall.Handle, flags uint32, providerSpecificFlags uint32) (err error) {
90
-	r1, _, e1 := syscall.Syscall(procDetachVirtualDisk.Addr(), 3, uintptr(handle), uintptr(flags), uintptr(providerSpecificFlags))
91
-	if r1 != 0 {
92
-		if e1 != 0 {
93
-			err = errnoErr(e1)
94
-		} else {
95
-			err = syscall.EINVAL
96
-		}
97
-	}
98
-	return
99
-}
100 1
new file mode 100644
... ...
@@ -0,0 +1,106 @@
0
+// Code generated by 'go generate'; DO NOT EDIT.
1
+
2
+package vhd
3
+
4
+import (
5
+	"syscall"
6
+	"unsafe"
7
+
8
+	"golang.org/x/sys/windows"
9
+)
10
+
11
+var _ unsafe.Pointer
12
+
13
+// Do the interface allocations only once for common
14
+// Errno values.
15
+const (
16
+	errnoERROR_IO_PENDING = 997
17
+)
18
+
19
+var (
20
+	errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
21
+	errERROR_EINVAL     error = syscall.EINVAL
22
+)
23
+
24
+// errnoErr returns common boxed Errno values, to prevent
25
+// allocations at runtime.
26
+func errnoErr(e syscall.Errno) error {
27
+	switch e {
28
+	case 0:
29
+		return errERROR_EINVAL
30
+	case errnoERROR_IO_PENDING:
31
+		return errERROR_IO_PENDING
32
+	}
33
+	// TODO: add more here, after collecting data on the common
34
+	// error values see on Windows. (perhaps when running
35
+	// all.bat?)
36
+	return e
37
+}
38
+
39
+var (
40
+	modvirtdisk = windows.NewLazySystemDLL("virtdisk.dll")
41
+
42
+	procAttachVirtualDisk          = modvirtdisk.NewProc("AttachVirtualDisk")
43
+	procCreateVirtualDisk          = modvirtdisk.NewProc("CreateVirtualDisk")
44
+	procDetachVirtualDisk          = modvirtdisk.NewProc("DetachVirtualDisk")
45
+	procGetVirtualDiskPhysicalPath = modvirtdisk.NewProc("GetVirtualDiskPhysicalPath")
46
+	procOpenVirtualDisk            = modvirtdisk.NewProc("OpenVirtualDisk")
47
+)
48
+
49
+func attachVirtualDisk(handle syscall.Handle, securityDescriptor *uintptr, attachVirtualDiskFlag uint32, providerSpecificFlags uint32, parameters *AttachVirtualDiskParameters, overlapped *syscall.Overlapped) (win32err error) {
50
+	r0, _, _ := syscall.Syscall6(procAttachVirtualDisk.Addr(), 6, uintptr(handle), uintptr(unsafe.Pointer(securityDescriptor)), uintptr(attachVirtualDiskFlag), uintptr(providerSpecificFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(overlapped)))
51
+	if r0 != 0 {
52
+		win32err = syscall.Errno(r0)
53
+	}
54
+	return
55
+}
56
+
57
+func createVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, createVirtualDiskFlags uint32, providerSpecificFlags uint32, parameters *CreateVirtualDiskParameters, overlapped *syscall.Overlapped, handle *syscall.Handle) (win32err error) {
58
+	var _p0 *uint16
59
+	_p0, win32err = syscall.UTF16PtrFromString(path)
60
+	if win32err != nil {
61
+		return
62
+	}
63
+	return _createVirtualDisk(virtualStorageType, _p0, virtualDiskAccessMask, securityDescriptor, createVirtualDiskFlags, providerSpecificFlags, parameters, overlapped, handle)
64
+}
65
+
66
+func _createVirtualDisk(virtualStorageType *VirtualStorageType, path *uint16, virtualDiskAccessMask uint32, securityDescriptor *uintptr, createVirtualDiskFlags uint32, providerSpecificFlags uint32, parameters *CreateVirtualDiskParameters, overlapped *syscall.Overlapped, handle *syscall.Handle) (win32err error) {
67
+	r0, _, _ := syscall.Syscall9(procCreateVirtualDisk.Addr(), 9, uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(unsafe.Pointer(securityDescriptor)), uintptr(createVirtualDiskFlags), uintptr(providerSpecificFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(handle)))
68
+	if r0 != 0 {
69
+		win32err = syscall.Errno(r0)
70
+	}
71
+	return
72
+}
73
+
74
+func detachVirtualDisk(handle syscall.Handle, detachVirtualDiskFlags uint32, providerSpecificFlags uint32) (win32err error) {
75
+	r0, _, _ := syscall.Syscall(procDetachVirtualDisk.Addr(), 3, uintptr(handle), uintptr(detachVirtualDiskFlags), uintptr(providerSpecificFlags))
76
+	if r0 != 0 {
77
+		win32err = syscall.Errno(r0)
78
+	}
79
+	return
80
+}
81
+
82
+func getVirtualDiskPhysicalPath(handle syscall.Handle, diskPathSizeInBytes *uint32, buffer *uint16) (win32err error) {
83
+	r0, _, _ := syscall.Syscall(procGetVirtualDiskPhysicalPath.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(diskPathSizeInBytes)), uintptr(unsafe.Pointer(buffer)))
84
+	if r0 != 0 {
85
+		win32err = syscall.Errno(r0)
86
+	}
87
+	return
88
+}
89
+
90
+func openVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *OpenVirtualDiskParameters, handle *syscall.Handle) (win32err error) {
91
+	var _p0 *uint16
92
+	_p0, win32err = syscall.UTF16PtrFromString(path)
93
+	if win32err != nil {
94
+		return
95
+	}
96
+	return _openVirtualDisk(virtualStorageType, _p0, virtualDiskAccessMask, openVirtualDiskFlags, parameters, handle)
97
+}
98
+
99
+func _openVirtualDisk(virtualStorageType *VirtualStorageType, path *uint16, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *OpenVirtualDiskParameters, handle *syscall.Handle) (win32err error) {
100
+	r0, _, _ := syscall.Syscall6(procOpenVirtualDisk.Addr(), 6, uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(openVirtualDiskFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(handle)))
101
+	if r0 != 0 {
102
+		win32err = syscall.Errno(r0)
103
+	}
104
+	return
105
+}
... ...
@@ -19,6 +19,7 @@ const (
19 19
 
20 20
 var (
21 21
 	errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
22
+	errERROR_EINVAL     error = syscall.EINVAL
22 23
 )
23 24
 
24 25
 // errnoErr returns common boxed Errno values, to prevent
... ...
@@ -26,7 +27,7 @@ var (
26 26
 func errnoErr(e syscall.Errno) error {
27 27
 	switch e {
28 28
 	case 0:
29
-		return nil
29
+		return errERROR_EINVAL
30 30
 	case errnoERROR_IO_PENDING:
31 31
 		return errERROR_IO_PENDING
32 32
 	}
... ...
@@ -37,514 +38,400 @@ func errnoErr(e syscall.Errno) error {
37 37
 }
38 38
 
39 39
 var (
40
+	modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
40 41
 	modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
41
-	modws2_32   = windows.NewLazySystemDLL("ws2_32.dll")
42 42
 	modntdll    = windows.NewLazySystemDLL("ntdll.dll")
43
-	modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
43
+	modws2_32   = windows.NewLazySystemDLL("ws2_32.dll")
44 44
 
45
-	procCancelIoEx                                           = modkernel32.NewProc("CancelIoEx")
46
-	procCreateIoCompletionPort                               = modkernel32.NewProc("CreateIoCompletionPort")
47
-	procGetQueuedCompletionStatus                            = modkernel32.NewProc("GetQueuedCompletionStatus")
48
-	procSetFileCompletionNotificationModes                   = modkernel32.NewProc("SetFileCompletionNotificationModes")
49
-	procWSAGetOverlappedResult                               = modws2_32.NewProc("WSAGetOverlappedResult")
50
-	procConnectNamedPipe                                     = modkernel32.NewProc("ConnectNamedPipe")
51
-	procCreateNamedPipeW                                     = modkernel32.NewProc("CreateNamedPipeW")
52
-	procCreateFileW                                          = modkernel32.NewProc("CreateFileW")
53
-	procGetNamedPipeInfo                                     = modkernel32.NewProc("GetNamedPipeInfo")
54
-	procGetNamedPipeHandleStateW                             = modkernel32.NewProc("GetNamedPipeHandleStateW")
55
-	procLocalAlloc                                           = modkernel32.NewProc("LocalAlloc")
56
-	procNtCreateNamedPipeFile                                = modntdll.NewProc("NtCreateNamedPipeFile")
57
-	procRtlNtStatusToDosErrorNoTeb                           = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb")
58
-	procRtlDosPathNameToNtPathName_U                         = modntdll.NewProc("RtlDosPathNameToNtPathName_U")
59
-	procRtlDefaultNpAcl                                      = modntdll.NewProc("RtlDefaultNpAcl")
60
-	procLookupAccountNameW                                   = modadvapi32.NewProc("LookupAccountNameW")
45
+	procAdjustTokenPrivileges                                = modadvapi32.NewProc("AdjustTokenPrivileges")
46
+	procConvertSecurityDescriptorToStringSecurityDescriptorW = modadvapi32.NewProc("ConvertSecurityDescriptorToStringSecurityDescriptorW")
61 47
 	procConvertSidToStringSidW                               = modadvapi32.NewProc("ConvertSidToStringSidW")
62 48
 	procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW")
63
-	procConvertSecurityDescriptorToStringSecurityDescriptorW = modadvapi32.NewProc("ConvertSecurityDescriptorToStringSecurityDescriptorW")
64
-	procLocalFree                                            = modkernel32.NewProc("LocalFree")
65 49
 	procGetSecurityDescriptorLength                          = modadvapi32.NewProc("GetSecurityDescriptorLength")
66
-	procGetFileInformationByHandleEx                         = modkernel32.NewProc("GetFileInformationByHandleEx")
67
-	procSetFileInformationByHandle                           = modkernel32.NewProc("SetFileInformationByHandle")
68
-	procAdjustTokenPrivileges                                = modadvapi32.NewProc("AdjustTokenPrivileges")
69 50
 	procImpersonateSelf                                      = modadvapi32.NewProc("ImpersonateSelf")
70
-	procRevertToSelf                                         = modadvapi32.NewProc("RevertToSelf")
71
-	procOpenThreadToken                                      = modadvapi32.NewProc("OpenThreadToken")
72
-	procGetCurrentThread                                     = modkernel32.NewProc("GetCurrentThread")
73
-	procLookupPrivilegeValueW                                = modadvapi32.NewProc("LookupPrivilegeValueW")
74
-	procLookupPrivilegeNameW                                 = modadvapi32.NewProc("LookupPrivilegeNameW")
51
+	procLookupAccountNameW                                   = modadvapi32.NewProc("LookupAccountNameW")
75 52
 	procLookupPrivilegeDisplayNameW                          = modadvapi32.NewProc("LookupPrivilegeDisplayNameW")
53
+	procLookupPrivilegeNameW                                 = modadvapi32.NewProc("LookupPrivilegeNameW")
54
+	procLookupPrivilegeValueW                                = modadvapi32.NewProc("LookupPrivilegeValueW")
55
+	procOpenThreadToken                                      = modadvapi32.NewProc("OpenThreadToken")
56
+	procRevertToSelf                                         = modadvapi32.NewProc("RevertToSelf")
76 57
 	procBackupRead                                           = modkernel32.NewProc("BackupRead")
77 58
 	procBackupWrite                                          = modkernel32.NewProc("BackupWrite")
59
+	procCancelIoEx                                           = modkernel32.NewProc("CancelIoEx")
60
+	procConnectNamedPipe                                     = modkernel32.NewProc("ConnectNamedPipe")
61
+	procCreateFileW                                          = modkernel32.NewProc("CreateFileW")
62
+	procCreateIoCompletionPort                               = modkernel32.NewProc("CreateIoCompletionPort")
63
+	procCreateNamedPipeW                                     = modkernel32.NewProc("CreateNamedPipeW")
64
+	procGetCurrentThread                                     = modkernel32.NewProc("GetCurrentThread")
65
+	procGetFileInformationByHandleEx                         = modkernel32.NewProc("GetFileInformationByHandleEx")
66
+	procGetNamedPipeHandleStateW                             = modkernel32.NewProc("GetNamedPipeHandleStateW")
67
+	procGetNamedPipeInfo                                     = modkernel32.NewProc("GetNamedPipeInfo")
68
+	procGetQueuedCompletionStatus                            = modkernel32.NewProc("GetQueuedCompletionStatus")
69
+	procLocalAlloc                                           = modkernel32.NewProc("LocalAlloc")
70
+	procLocalFree                                            = modkernel32.NewProc("LocalFree")
71
+	procSetFileCompletionNotificationModes                   = modkernel32.NewProc("SetFileCompletionNotificationModes")
72
+	procSetFileInformationByHandle                           = modkernel32.NewProc("SetFileInformationByHandle")
73
+	procNtCreateNamedPipeFile                                = modntdll.NewProc("NtCreateNamedPipeFile")
74
+	procRtlDefaultNpAcl                                      = modntdll.NewProc("RtlDefaultNpAcl")
75
+	procRtlDosPathNameToNtPathName_U                         = modntdll.NewProc("RtlDosPathNameToNtPathName_U")
76
+	procRtlNtStatusToDosErrorNoTeb                           = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb")
77
+	procWSAGetOverlappedResult                               = modws2_32.NewProc("WSAGetOverlappedResult")
78 78
 	procbind                                                 = modws2_32.NewProc("bind")
79 79
 )
80 80
 
81
-func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) {
82
-	r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0)
83
-	if r1 == 0 {
84
-		if e1 != 0 {
85
-			err = errnoErr(e1)
86
-		} else {
87
-			err = syscall.EINVAL
88
-		}
81
+func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) {
82
+	var _p0 uint32
83
+	if releaseAll {
84
+		_p0 = 1
89 85
 	}
90
-	return
91
-}
92
-
93
-func createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) {
94
-	r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount), 0, 0)
95
-	newport = syscall.Handle(r0)
96
-	if newport == 0 {
97
-		if e1 != 0 {
98
-			err = errnoErr(e1)
99
-		} else {
100
-			err = syscall.EINVAL
101
-		}
86
+	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)))
87
+	success = r0 != 0
88
+	if true {
89
+		err = errnoErr(e1)
102 90
 	}
103 91
 	return
104 92
 }
105 93
 
106
-func getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) {
107
-	r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0)
94
+func convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) {
95
+	r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(secInfo), uintptr(unsafe.Pointer(sddl)), uintptr(unsafe.Pointer(sddlSize)), 0)
108 96
 	if r1 == 0 {
109
-		if e1 != 0 {
110
-			err = errnoErr(e1)
111
-		} else {
112
-			err = syscall.EINVAL
113
-		}
97
+		err = errnoErr(e1)
114 98
 	}
115 99
 	return
116 100
 }
117 101
 
118
-func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) {
119
-	r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0)
102
+func convertSidToStringSid(sid *byte, str **uint16) (err error) {
103
+	r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)), 0)
120 104
 	if r1 == 0 {
121
-		if e1 != 0 {
122
-			err = errnoErr(e1)
123
-		} else {
124
-			err = syscall.EINVAL
125
-		}
105
+		err = errnoErr(e1)
126 106
 	}
127 107
 	return
128 108
 }
129 109
 
130
-func wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) {
131
-	var _p0 uint32
132
-	if wait {
133
-		_p0 = 1
134
-	} else {
135
-		_p0 = 0
110
+func convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) {
111
+	var _p0 *uint16
112
+	_p0, err = syscall.UTF16PtrFromString(str)
113
+	if err != nil {
114
+		return
136 115
 	}
137
-	r1, _, e1 := syscall.Syscall6(procWSAGetOverlappedResult.Addr(), 5, uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags)), 0)
116
+	return _convertStringSecurityDescriptorToSecurityDescriptor(_p0, revision, sd, size)
117
+}
118
+
119
+func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision uint32, sd *uintptr, size *uint32) (err error) {
120
+	r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0)
138 121
 	if r1 == 0 {
139
-		if e1 != 0 {
140
-			err = errnoErr(e1)
141
-		} else {
142
-			err = syscall.EINVAL
143
-		}
122
+		err = errnoErr(e1)
144 123
 	}
145 124
 	return
146 125
 }
147 126
 
148
-func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) {
149
-	r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0)
127
+func getSecurityDescriptorLength(sd uintptr) (len uint32) {
128
+	r0, _, _ := syscall.Syscall(procGetSecurityDescriptorLength.Addr(), 1, uintptr(sd), 0, 0)
129
+	len = uint32(r0)
130
+	return
131
+}
132
+
133
+func impersonateSelf(level uint32) (err error) {
134
+	r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(level), 0, 0)
150 135
 	if r1 == 0 {
151
-		if e1 != 0 {
152
-			err = errnoErr(e1)
153
-		} else {
154
-			err = syscall.EINVAL
155
-		}
136
+		err = errnoErr(e1)
156 137
 	}
157 138
 	return
158 139
 }
159 140
 
160
-func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) {
141
+func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
161 142
 	var _p0 *uint16
162
-	_p0, err = syscall.UTF16PtrFromString(name)
143
+	_p0, err = syscall.UTF16PtrFromString(accountName)
163 144
 	if err != nil {
164 145
 		return
165 146
 	}
166
-	return _createNamedPipe(_p0, flags, pipeMode, maxInstances, outSize, inSize, defaultTimeout, sa)
147
+	return _lookupAccountName(systemName, _p0, sid, sidSize, refDomain, refDomainSize, sidNameUse)
167 148
 }
168 149
 
169
-func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) {
170
-	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)
171
-	handle = syscall.Handle(r0)
172
-	if handle == syscall.InvalidHandle {
173
-		if e1 != 0 {
174
-			err = errnoErr(e1)
175
-		} else {
176
-			err = syscall.EINVAL
177
-		}
150
+func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
151
+	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)
152
+	if r1 == 0 {
153
+		err = errnoErr(e1)
178 154
 	}
179 155
 	return
180 156
 }
181 157
 
182
-func createFile(name string, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
158
+func lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
183 159
 	var _p0 *uint16
184
-	_p0, err = syscall.UTF16PtrFromString(name)
160
+	_p0, err = syscall.UTF16PtrFromString(systemName)
185 161
 	if err != nil {
186 162
 		return
187 163
 	}
188
-	return _createFile(_p0, access, mode, sa, createmode, attrs, templatefile)
164
+	return _lookupPrivilegeDisplayName(_p0, name, buffer, size, languageId)
189 165
 }
190 166
 
191
-func _createFile(name *uint16, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
192
-	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)
193
-	handle = syscall.Handle(r0)
194
-	if handle == syscall.InvalidHandle {
195
-		if e1 != 0 {
196
-			err = errnoErr(e1)
197
-		} else {
198
-			err = syscall.EINVAL
199
-		}
167
+func _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
168
+	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)
169
+	if r1 == 0 {
170
+		err = errnoErr(e1)
200 171
 	}
201 172
 	return
202 173
 }
203 174
 
204
-func getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) {
205
-	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)
206
-	if r1 == 0 {
207
-		if e1 != 0 {
208
-			err = errnoErr(e1)
209
-		} else {
210
-			err = syscall.EINVAL
211
-		}
175
+func lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) {
176
+	var _p0 *uint16
177
+	_p0, err = syscall.UTF16PtrFromString(systemName)
178
+	if err != nil {
179
+		return
212 180
 	}
213
-	return
181
+	return _lookupPrivilegeName(_p0, luid, buffer, size)
214 182
 }
215 183
 
216
-func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) {
217
-	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)
184
+func _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size *uint32) (err error) {
185
+	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)
218 186
 	if r1 == 0 {
219
-		if e1 != 0 {
220
-			err = errnoErr(e1)
221
-		} else {
222
-			err = syscall.EINVAL
223
-		}
187
+		err = errnoErr(e1)
224 188
 	}
225 189
 	return
226 190
 }
227 191
 
228
-func localAlloc(uFlags uint32, length uint32) (ptr uintptr) {
229
-	r0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(uFlags), uintptr(length), 0)
230
-	ptr = uintptr(r0)
231
-	return
192
+func lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) {
193
+	var _p0 *uint16
194
+	_p0, err = syscall.UTF16PtrFromString(systemName)
195
+	if err != nil {
196
+		return
197
+	}
198
+	var _p1 *uint16
199
+	_p1, err = syscall.UTF16PtrFromString(name)
200
+	if err != nil {
201
+		return
202
+	}
203
+	return _lookupPrivilegeValue(_p0, _p1, luid)
232 204
 }
233 205
 
234
-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) {
235
-	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)
236
-	status = ntstatus(r0)
206
+func _lookupPrivilegeValue(systemName *uint16, name *uint16, luid *uint64) (err error) {
207
+	r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid)))
208
+	if r1 == 0 {
209
+		err = errnoErr(e1)
210
+	}
237 211
 	return
238 212
 }
239 213
 
240
-func rtlNtStatusToDosError(status ntstatus) (winerr error) {
241
-	r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(status), 0, 0)
242
-	if r0 != 0 {
243
-		winerr = syscall.Errno(r0)
214
+func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) {
215
+	var _p0 uint32
216
+	if openAsSelf {
217
+		_p0 = 1
218
+	}
219
+	r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0)
220
+	if r1 == 0 {
221
+		err = errnoErr(e1)
244 222
 	}
245 223
 	return
246 224
 }
247 225
 
248
-func rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntstatus) {
249
-	r0, _, _ := syscall.Syscall6(procRtlDosPathNameToNtPathName_U.Addr(), 4, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(ntName)), uintptr(filePart), uintptr(reserved), 0, 0)
250
-	status = ntstatus(r0)
226
+func revertToSelf() (err error) {
227
+	r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0)
228
+	if r1 == 0 {
229
+		err = errnoErr(e1)
230
+	}
251 231
 	return
252 232
 }
253 233
 
254
-func rtlDefaultNpAcl(dacl *uintptr) (status ntstatus) {
255
-	r0, _, _ := syscall.Syscall(procRtlDefaultNpAcl.Addr(), 1, uintptr(unsafe.Pointer(dacl)), 0, 0)
256
-	status = ntstatus(r0)
234
+func backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) {
235
+	var _p0 *byte
236
+	if len(b) > 0 {
237
+		_p0 = &b[0]
238
+	}
239
+	var _p1 uint32
240
+	if abort {
241
+		_p1 = 1
242
+	}
243
+	var _p2 uint32
244
+	if processSecurity {
245
+		_p2 = 1
246
+	}
247
+	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)
248
+	if r1 == 0 {
249
+		err = errnoErr(e1)
250
+	}
257 251
 	return
258 252
 }
259 253
 
260
-func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
261
-	var _p0 *uint16
262
-	_p0, err = syscall.UTF16PtrFromString(accountName)
263
-	if err != nil {
264
-		return
254
+func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) {
255
+	var _p0 *byte
256
+	if len(b) > 0 {
257
+		_p0 = &b[0]
265 258
 	}
266
-	return _lookupAccountName(systemName, _p0, sid, sidSize, refDomain, refDomainSize, sidNameUse)
259
+	var _p1 uint32
260
+	if abort {
261
+		_p1 = 1
262
+	}
263
+	var _p2 uint32
264
+	if processSecurity {
265
+		_p2 = 1
266
+	}
267
+	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)
268
+	if r1 == 0 {
269
+		err = errnoErr(e1)
270
+	}
271
+	return
267 272
 }
268 273
 
269
-func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
270
-	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)
274
+func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) {
275
+	r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0)
271 276
 	if r1 == 0 {
272
-		if e1 != 0 {
273
-			err = errnoErr(e1)
274
-		} else {
275
-			err = syscall.EINVAL
276
-		}
277
+		err = errnoErr(e1)
277 278
 	}
278 279
 	return
279 280
 }
280 281
 
281
-func convertSidToStringSid(sid *byte, str **uint16) (err error) {
282
-	r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)), 0)
282
+func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) {
283
+	r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0)
283 284
 	if r1 == 0 {
284
-		if e1 != 0 {
285
-			err = errnoErr(e1)
286
-		} else {
287
-			err = syscall.EINVAL
288
-		}
285
+		err = errnoErr(e1)
289 286
 	}
290 287
 	return
291 288
 }
292 289
 
293
-func convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) {
290
+func createFile(name string, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
294 291
 	var _p0 *uint16
295
-	_p0, err = syscall.UTF16PtrFromString(str)
292
+	_p0, err = syscall.UTF16PtrFromString(name)
296 293
 	if err != nil {
297 294
 		return
298 295
 	}
299
-	return _convertStringSecurityDescriptorToSecurityDescriptor(_p0, revision, sd, size)
296
+	return _createFile(_p0, access, mode, sa, createmode, attrs, templatefile)
300 297
 }
301 298
 
302
-func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision uint32, sd *uintptr, size *uint32) (err error) {
303
-	r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0)
304
-	if r1 == 0 {
305
-		if e1 != 0 {
306
-			err = errnoErr(e1)
307
-		} else {
308
-			err = syscall.EINVAL
309
-		}
299
+func _createFile(name *uint16, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
300
+	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)
301
+	handle = syscall.Handle(r0)
302
+	if handle == syscall.InvalidHandle {
303
+		err = errnoErr(e1)
310 304
 	}
311 305
 	return
312 306
 }
313 307
 
314
-func convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) {
315
-	r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(secInfo), uintptr(unsafe.Pointer(sddl)), uintptr(unsafe.Pointer(sddlSize)), 0)
316
-	if r1 == 0 {
317
-		if e1 != 0 {
318
-			err = errnoErr(e1)
319
-		} else {
320
-			err = syscall.EINVAL
321
-		}
308
+func createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) {
309
+	r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount), 0, 0)
310
+	newport = syscall.Handle(r0)
311
+	if newport == 0 {
312
+		err = errnoErr(e1)
322 313
 	}
323 314
 	return
324 315
 }
325 316
 
326
-func localFree(mem uintptr) {
327
-	syscall.Syscall(procLocalFree.Addr(), 1, uintptr(mem), 0, 0)
317
+func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) {
318
+	var _p0 *uint16
319
+	_p0, err = syscall.UTF16PtrFromString(name)
320
+	if err != nil {
321
+		return
322
+	}
323
+	return _createNamedPipe(_p0, flags, pipeMode, maxInstances, outSize, inSize, defaultTimeout, sa)
324
+}
325
+
326
+func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) {
327
+	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)
328
+	handle = syscall.Handle(r0)
329
+	if handle == syscall.InvalidHandle {
330
+		err = errnoErr(e1)
331
+	}
328 332
 	return
329 333
 }
330 334
 
331
-func getSecurityDescriptorLength(sd uintptr) (len uint32) {
332
-	r0, _, _ := syscall.Syscall(procGetSecurityDescriptorLength.Addr(), 1, uintptr(sd), 0, 0)
333
-	len = uint32(r0)
335
+func getCurrentThread() (h syscall.Handle) {
336
+	r0, _, _ := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0)
337
+	h = syscall.Handle(r0)
334 338
 	return
335 339
 }
336 340
 
337 341
 func getFileInformationByHandleEx(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) {
338 342
 	r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0)
339 343
 	if r1 == 0 {
340
-		if e1 != 0 {
341
-			err = errnoErr(e1)
342
-		} else {
343
-			err = syscall.EINVAL
344
-		}
344
+		err = errnoErr(e1)
345 345
 	}
346 346
 	return
347 347
 }
348 348
 
349
-func setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) {
350
-	r1, _, e1 := syscall.Syscall6(procSetFileInformationByHandle.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0)
349
+func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) {
350
+	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)
351 351
 	if r1 == 0 {
352
-		if e1 != 0 {
353
-			err = errnoErr(e1)
354
-		} else {
355
-			err = syscall.EINVAL
356
-		}
357
-	}
358
-	return
359
-}
360
-
361
-func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) {
362
-	var _p0 uint32
363
-	if releaseAll {
364
-		_p0 = 1
365
-	} else {
366
-		_p0 = 0
367
-	}
368
-	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)))
369
-	success = r0 != 0
370
-	if true {
371
-		if e1 != 0 {
372
-			err = errnoErr(e1)
373
-		} else {
374
-			err = syscall.EINVAL
375
-		}
352
+		err = errnoErr(e1)
376 353
 	}
377 354
 	return
378 355
 }
379 356
 
380
-func impersonateSelf(level uint32) (err error) {
381
-	r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(level), 0, 0)
357
+func getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) {
358
+	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)
382 359
 	if r1 == 0 {
383
-		if e1 != 0 {
384
-			err = errnoErr(e1)
385
-		} else {
386
-			err = syscall.EINVAL
387
-		}
360
+		err = errnoErr(e1)
388 361
 	}
389 362
 	return
390 363
 }
391 364
 
392
-func revertToSelf() (err error) {
393
-	r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0)
365
+func getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) {
366
+	r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0)
394 367
 	if r1 == 0 {
395
-		if e1 != 0 {
396
-			err = errnoErr(e1)
397
-		} else {
398
-			err = syscall.EINVAL
399
-		}
368
+		err = errnoErr(e1)
400 369
 	}
401 370
 	return
402 371
 }
403 372
 
404
-func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) {
405
-	var _p0 uint32
406
-	if openAsSelf {
407
-		_p0 = 1
408
-	} else {
409
-		_p0 = 0
410
-	}
411
-	r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0)
412
-	if r1 == 0 {
413
-		if e1 != 0 {
414
-			err = errnoErr(e1)
415
-		} else {
416
-			err = syscall.EINVAL
417
-		}
418
-	}
373
+func localAlloc(uFlags uint32, length uint32) (ptr uintptr) {
374
+	r0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(uFlags), uintptr(length), 0)
375
+	ptr = uintptr(r0)
419 376
 	return
420 377
 }
421 378
 
422
-func getCurrentThread() (h syscall.Handle) {
423
-	r0, _, _ := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0)
424
-	h = syscall.Handle(r0)
379
+func localFree(mem uintptr) {
380
+	syscall.Syscall(procLocalFree.Addr(), 1, uintptr(mem), 0, 0)
425 381
 	return
426 382
 }
427 383
 
428
-func lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) {
429
-	var _p0 *uint16
430
-	_p0, err = syscall.UTF16PtrFromString(systemName)
431
-	if err != nil {
432
-		return
433
-	}
434
-	var _p1 *uint16
435
-	_p1, err = syscall.UTF16PtrFromString(name)
436
-	if err != nil {
437
-		return
438
-	}
439
-	return _lookupPrivilegeValue(_p0, _p1, luid)
440
-}
441
-
442
-func _lookupPrivilegeValue(systemName *uint16, name *uint16, luid *uint64) (err error) {
443
-	r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid)))
384
+func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) {
385
+	r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0)
444 386
 	if r1 == 0 {
445
-		if e1 != 0 {
446
-			err = errnoErr(e1)
447
-		} else {
448
-			err = syscall.EINVAL
449
-		}
387
+		err = errnoErr(e1)
450 388
 	}
451 389
 	return
452 390
 }
453 391
 
454
-func lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) {
455
-	var _p0 *uint16
456
-	_p0, err = syscall.UTF16PtrFromString(systemName)
457
-	if err != nil {
458
-		return
392
+func setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) {
393
+	r1, _, e1 := syscall.Syscall6(procSetFileInformationByHandle.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0)
394
+	if r1 == 0 {
395
+		err = errnoErr(e1)
459 396
 	}
460
-	return _lookupPrivilegeName(_p0, luid, buffer, size)
397
+	return
461 398
 }
462 399
 
463
-func _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size *uint32) (err error) {
464
-	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)
465
-	if r1 == 0 {
466
-		if e1 != 0 {
467
-			err = errnoErr(e1)
468
-		} else {
469
-			err = syscall.EINVAL
470
-		}
471
-	}
400
+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) {
401
+	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)
402
+	status = ntstatus(r0)
472 403
 	return
473 404
 }
474 405
 
475
-func lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
476
-	var _p0 *uint16
477
-	_p0, err = syscall.UTF16PtrFromString(systemName)
478
-	if err != nil {
479
-		return
480
-	}
481
-	return _lookupPrivilegeDisplayName(_p0, name, buffer, size, languageId)
406
+func rtlDefaultNpAcl(dacl *uintptr) (status ntstatus) {
407
+	r0, _, _ := syscall.Syscall(procRtlDefaultNpAcl.Addr(), 1, uintptr(unsafe.Pointer(dacl)), 0, 0)
408
+	status = ntstatus(r0)
409
+	return
482 410
 }
483 411
 
484
-func _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
485
-	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)
486
-	if r1 == 0 {
487
-		if e1 != 0 {
488
-			err = errnoErr(e1)
489
-		} else {
490
-			err = syscall.EINVAL
491
-		}
492
-	}
412
+func rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntstatus) {
413
+	r0, _, _ := syscall.Syscall6(procRtlDosPathNameToNtPathName_U.Addr(), 4, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(ntName)), uintptr(filePart), uintptr(reserved), 0, 0)
414
+	status = ntstatus(r0)
493 415
 	return
494 416
 }
495 417
 
496
-func backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) {
497
-	var _p0 *byte
498
-	if len(b) > 0 {
499
-		_p0 = &b[0]
500
-	}
501
-	var _p1 uint32
502
-	if abort {
503
-		_p1 = 1
504
-	} else {
505
-		_p1 = 0
506
-	}
507
-	var _p2 uint32
508
-	if processSecurity {
509
-		_p2 = 1
510
-	} else {
511
-		_p2 = 0
512
-	}
513
-	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)
514
-	if r1 == 0 {
515
-		if e1 != 0 {
516
-			err = errnoErr(e1)
517
-		} else {
518
-			err = syscall.EINVAL
519
-		}
418
+func rtlNtStatusToDosError(status ntstatus) (winerr error) {
419
+	r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(status), 0, 0)
420
+	if r0 != 0 {
421
+		winerr = syscall.Errno(r0)
520 422
 	}
521 423
 	return
522 424
 }
523 425
 
524
-func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) {
525
-	var _p0 *byte
526
-	if len(b) > 0 {
527
-		_p0 = &b[0]
528
-	}
529
-	var _p1 uint32
530
-	if abort {
531
-		_p1 = 1
532
-	} else {
533
-		_p1 = 0
534
-	}
535
-	var _p2 uint32
536
-	if processSecurity {
537
-		_p2 = 1
538
-	} else {
539
-		_p2 = 0
426
+func wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) {
427
+	var _p0 uint32
428
+	if wait {
429
+		_p0 = 1
540 430
 	}
541
-	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)
431
+	r1, _, e1 := syscall.Syscall6(procWSAGetOverlappedResult.Addr(), 5, uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags)), 0)
542 432
 	if r1 == 0 {
543
-		if e1 != 0 {
544
-			err = errnoErr(e1)
545
-		} else {
546
-			err = syscall.EINVAL
547
-		}
433
+		err = errnoErr(e1)
548 434
 	}
549 435
 	return
550 436
 }
... ...
@@ -552,11 +439,7 @@ func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, p
552 552
 func bind(s syscall.Handle, name unsafe.Pointer, namelen int32) (err error) {
553 553
 	r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
554 554
 	if r1 == socketError {
555
-		if e1 != 0 {
556
-			err = errnoErr(e1)
557
-		} else {
558
-			err = syscall.EINVAL
559
-		}
555
+		err = errnoErr(e1)
560 556
 	}
561 557
 	return
562 558
 }