syscall_windows.mx raw

   1  // Copyright 2014 The Go Authors. All rights reserved.
   2  // Use of this source code is governed by a BSD-style
   3  // license that can be found in the LICENSE file.
   4  
   5  package windows
   6  
   7  import (
   8  	"sync"
   9  	"syscall"
  10  	"unsafe"
  11  )
  12  
  13  // CanUseLongPaths is true when the OS supports opting into
  14  // proper long path handling without the need for fixups.
  15  //
  16  //go:linkname CanUseLongPaths
  17  var CanUseLongPaths bool
  18  
  19  // UTF16PtrToString is like UTF16ToString, but takes *uint16
  20  // as a parameter instead of []uint16.
  21  func UTF16PtrToString(p *uint16) string {
  22  	if p == nil {
  23  		return ""
  24  	}
  25  	end := unsafe.Pointer(p)
  26  	n := 0
  27  	for *(*uint16)(end) != 0 {
  28  		end = unsafe.Pointer(uintptr(end) + unsafe.Sizeof(*p))
  29  		n++
  30  	}
  31  	return syscall.UTF16ToString(unsafe.Slice(p, n))
  32  }
  33  
  34  const (
  35  	ERROR_INVALID_HANDLE         syscall.Errno = 6
  36  	ERROR_BAD_LENGTH             syscall.Errno = 24
  37  	ERROR_SHARING_VIOLATION      syscall.Errno = 32
  38  	ERROR_LOCK_VIOLATION         syscall.Errno = 33
  39  	ERROR_NOT_SUPPORTED          syscall.Errno = 50
  40  	ERROR_CALL_NOT_IMPLEMENTED   syscall.Errno = 120
  41  	ERROR_INVALID_NAME           syscall.Errno = 123
  42  	ERROR_LOCK_FAILED            syscall.Errno = 167
  43  	ERROR_IO_INCOMPLETE          syscall.Errno = 996
  44  	ERROR_NO_TOKEN               syscall.Errno = 1008
  45  	ERROR_NO_UNICODE_TRANSLATION syscall.Errno = 1113
  46  	ERROR_CANT_ACCESS_FILE       syscall.Errno = 1920
  47  )
  48  
  49  const (
  50  	GAA_FLAG_INCLUDE_PREFIX   = 0x00000010
  51  	GAA_FLAG_INCLUDE_GATEWAYS = 0x0080
  52  )
  53  
  54  const (
  55  	IF_TYPE_OTHER              = 1
  56  	IF_TYPE_ETHERNET_CSMACD    = 6
  57  	IF_TYPE_ISO88025_TOKENRING = 9
  58  	IF_TYPE_PPP                = 23
  59  	IF_TYPE_SOFTWARE_LOOPBACK  = 24
  60  	IF_TYPE_ATM                = 37
  61  	IF_TYPE_IEEE80211          = 71
  62  	IF_TYPE_TUNNEL             = 131
  63  	IF_TYPE_IEEE1394           = 144
  64  )
  65  
  66  type SocketAddress struct {
  67  	Sockaddr       *syscall.RawSockaddrAny
  68  	SockaddrLength int32
  69  }
  70  
  71  type IpAdapterUnicastAddress struct {
  72  	Length             uint32
  73  	Flags              uint32
  74  	Next               *IpAdapterUnicastAddress
  75  	Address            SocketAddress
  76  	PrefixOrigin       int32
  77  	SuffixOrigin       int32
  78  	DadState           int32
  79  	ValidLifetime      uint32
  80  	PreferredLifetime  uint32
  81  	LeaseLifetime      uint32
  82  	OnLinkPrefixLength uint8
  83  }
  84  
  85  type IpAdapterAnycastAddress struct {
  86  	Length  uint32
  87  	Flags   uint32
  88  	Next    *IpAdapterAnycastAddress
  89  	Address SocketAddress
  90  }
  91  
  92  type IpAdapterMulticastAddress struct {
  93  	Length  uint32
  94  	Flags   uint32
  95  	Next    *IpAdapterMulticastAddress
  96  	Address SocketAddress
  97  }
  98  
  99  type IpAdapterDnsServerAdapter struct {
 100  	Length   uint32
 101  	Reserved uint32
 102  	Next     *IpAdapterDnsServerAdapter
 103  	Address  SocketAddress
 104  }
 105  
 106  type IpAdapterPrefix struct {
 107  	Length       uint32
 108  	Flags        uint32
 109  	Next         *IpAdapterPrefix
 110  	Address      SocketAddress
 111  	PrefixLength uint32
 112  }
 113  
 114  type IpAdapterWinsServerAddress struct {
 115  	Length   uint32
 116  	Reserved uint32
 117  	Next     *IpAdapterWinsServerAddress
 118  	Address  SocketAddress
 119  }
 120  
 121  type IpAdapterGatewayAddress struct {
 122  	Length   uint32
 123  	Reserved uint32
 124  	Next     *IpAdapterGatewayAddress
 125  	Address  SocketAddress
 126  }
 127  
 128  type IpAdapterAddresses struct {
 129  	Length                 uint32
 130  	IfIndex                uint32
 131  	Next                   *IpAdapterAddresses
 132  	AdapterName            *byte
 133  	FirstUnicastAddress    *IpAdapterUnicastAddress
 134  	FirstAnycastAddress    *IpAdapterAnycastAddress
 135  	FirstMulticastAddress  *IpAdapterMulticastAddress
 136  	FirstDnsServerAddress  *IpAdapterDnsServerAdapter
 137  	DnsSuffix              *uint16
 138  	Description            *uint16
 139  	FriendlyName           *uint16
 140  	PhysicalAddress        [syscall.MAX_ADAPTER_ADDRESS_LENGTH]byte
 141  	PhysicalAddressLength  uint32
 142  	Flags                  uint32
 143  	Mtu                    uint32
 144  	IfType                 uint32
 145  	OperStatus             uint32
 146  	Ipv6IfIndex            uint32
 147  	ZoneIndices            [16]uint32
 148  	FirstPrefix            *IpAdapterPrefix
 149  	TransmitLinkSpeed      uint64
 150  	ReceiveLinkSpeed       uint64
 151  	FirstWinsServerAddress *IpAdapterWinsServerAddress
 152  	FirstGatewayAddress    *IpAdapterGatewayAddress
 153  	/* more fields might be present here. */
 154  }
 155  
 156  type SecurityAttributes struct {
 157  	Length             uint16
 158  	SecurityDescriptor uintptr
 159  	InheritHandle      bool
 160  }
 161  
 162  type FILE_BASIC_INFO struct {
 163  	CreationTime   int64
 164  	LastAccessTime int64
 165  	LastWriteTime  int64
 166  	ChangedTime    int64
 167  	FileAttributes uint32
 168  
 169  	// Pad out to 8-byte alignment.
 170  	//
 171  	// Without this padding, TestChmod fails due to an argument validation error
 172  	// in SetFileInformationByHandle on windows/386.
 173  	//
 174  	// https://learn.microsoft.com/en-us/cpp/build/reference/zp-struct-member-alignment?view=msvc-170
 175  	// says that “The C/C++ headers in the Windows SDK assume the platform's
 176  	// default alignment is used.” What we see here is padding rather than
 177  	// alignment, but maybe it is related.
 178  	_ uint32
 179  }
 180  
 181  const (
 182  	IfOperStatusUp             = 1
 183  	IfOperStatusDown           = 2
 184  	IfOperStatusTesting        = 3
 185  	IfOperStatusUnknown        = 4
 186  	IfOperStatusDormant        = 5
 187  	IfOperStatusNotPresent     = 6
 188  	IfOperStatusLowerLayerDown = 7
 189  )
 190  
 191  //sys	GetAdaptersAddresses(family uint32, flags uint32, reserved unsafe.Pointer, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) = iphlpapi.GetAdaptersAddresses
 192  //sys	GetComputerNameEx(nameformat uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW
 193  //sys	MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) = MoveFileExW
 194  //sys	GetModuleFileName(module syscall.Handle, fn *uint16, len uint32) (n uint32, err error) = kernel32.GetModuleFileNameW
 195  //sys	SetFileInformationByHandle(handle syscall.Handle, fileInformationClass uint32, buf unsafe.Pointer, bufsize uint32) (err error) = kernel32.SetFileInformationByHandle
 196  //sys	VirtualQuery(address uintptr, buffer *MemoryBasicInformation, length uintptr) (err error) = kernel32.VirtualQuery
 197  //sys	GetTempPath2(buflen uint32, buf *uint16) (n uint32, err error) = GetTempPath2W
 198  
 199  const (
 200  	// flags for CreateToolhelp32Snapshot
 201  	TH32CS_SNAPMODULE   = 0x08
 202  	TH32CS_SNAPMODULE32 = 0x10
 203  )
 204  
 205  const MAX_MODULE_NAME32 = 255
 206  
 207  type ModuleEntry32 struct {
 208  	Size         uint32
 209  	ModuleID     uint32
 210  	ProcessID    uint32
 211  	GlblcntUsage uint32
 212  	ProccntUsage uint32
 213  	ModBaseAddr  uintptr
 214  	ModBaseSize  uint32
 215  	ModuleHandle syscall.Handle
 216  	Module       [MAX_MODULE_NAME32 + 1]uint16
 217  	ExePath      [syscall.MAX_PATH]uint16
 218  }
 219  
 220  const SizeofModuleEntry32 = unsafe.Sizeof(ModuleEntry32{})
 221  
 222  //sys	Module32First(snapshot syscall.Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32FirstW
 223  //sys	Module32Next(snapshot syscall.Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32NextW
 224  
 225  const (
 226  	WSA_FLAG_OVERLAPPED        = 0x01
 227  	WSA_FLAG_NO_HANDLE_INHERIT = 0x80
 228  
 229  	WSAEINVAL       syscall.Errno = 10022
 230  	WSAEMSGSIZE     syscall.Errno = 10040
 231  	WSAEAFNOSUPPORT syscall.Errno = 10047
 232  
 233  	MSG_PEEK   = 0x2
 234  	MSG_TRUNC  = 0x0100
 235  	MSG_CTRUNC = 0x0200
 236  
 237  	socket_error = uintptr(^uint32(0))
 238  )
 239  
 240  var WSAID_WSASENDMSG = syscall.GUID{
 241  	Data1: 0xa441e712,
 242  	Data2: 0x754f,
 243  	Data3: 0x43ca,
 244  	Data4: [8]byte{0x84, 0xa7, 0x0d, 0xee, 0x44, 0xcf, 0x60, 0x6d},
 245  }
 246  
 247  var WSAID_WSARECVMSG = syscall.GUID{
 248  	Data1: 0xf689d7c8,
 249  	Data2: 0x6f1f,
 250  	Data3: 0x436b,
 251  	Data4: [8]byte{0x8a, 0x53, 0xe5, 0x4f, 0xe3, 0x51, 0xc3, 0x22},
 252  }
 253  
 254  var sendRecvMsgFunc struct {
 255  	once     sync.Once
 256  	sendAddr uintptr
 257  	recvAddr uintptr
 258  	err      error
 259  }
 260  
 261  type WSAMsg struct {
 262  	Name        syscall.Pointer
 263  	Namelen     int32
 264  	Buffers     *syscall.WSABuf
 265  	BufferCount uint32
 266  	Control     syscall.WSABuf
 267  	Flags       uint32
 268  }
 269  
 270  //sys	WSASocket(af int32, typ int32, protocol int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = ws2_32.WSASocketW
 271  //sys	WSADuplicateSocket(s syscall.Handle, processID uint32, info *syscall.WSAProtocolInfo) (err error) [failretval!=0] = ws2_32.WSADuplicateSocketW
 272  //sys	WSAGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) = ws2_32.WSAGetOverlappedResult
 273  
 274  func loadWSASendRecvMsg() error {
 275  	sendRecvMsgFunc.once.Do(func() {
 276  		var s syscall.Handle
 277  		s, sendRecvMsgFunc.err = syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
 278  		if sendRecvMsgFunc.err != nil {
 279  			return
 280  		}
 281  		defer syscall.CloseHandle(s)
 282  		var n uint32
 283  		sendRecvMsgFunc.err = syscall.WSAIoctl(s,
 284  			syscall.SIO_GET_EXTENSION_FUNCTION_POINTER,
 285  			(*byte)(unsafe.Pointer(&WSAID_WSARECVMSG)),
 286  			uint32(unsafe.Sizeof(WSAID_WSARECVMSG)),
 287  			(*byte)(unsafe.Pointer(&sendRecvMsgFunc.recvAddr)),
 288  			uint32(unsafe.Sizeof(sendRecvMsgFunc.recvAddr)),
 289  			&n, nil, 0)
 290  		if sendRecvMsgFunc.err != nil {
 291  			return
 292  		}
 293  		sendRecvMsgFunc.err = syscall.WSAIoctl(s,
 294  			syscall.SIO_GET_EXTENSION_FUNCTION_POINTER,
 295  			(*byte)(unsafe.Pointer(&WSAID_WSASENDMSG)),
 296  			uint32(unsafe.Sizeof(WSAID_WSASENDMSG)),
 297  			(*byte)(unsafe.Pointer(&sendRecvMsgFunc.sendAddr)),
 298  			uint32(unsafe.Sizeof(sendRecvMsgFunc.sendAddr)),
 299  			&n, nil, 0)
 300  	})
 301  	return sendRecvMsgFunc.err
 302  }
 303  
 304  func WSASendMsg(fd syscall.Handle, msg *WSAMsg, flags uint32, bytesSent *uint32, overlapped *syscall.Overlapped, croutine *byte) error {
 305  	err := loadWSASendRecvMsg()
 306  	if err != nil {
 307  		return err
 308  	}
 309  	r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.sendAddr, 6, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(flags), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
 310  	if r1 == socket_error {
 311  		if e1 != 0 {
 312  			err = errnoErr(e1)
 313  		} else {
 314  			err = syscall.EINVAL
 315  		}
 316  	}
 317  	return err
 318  }
 319  
 320  func WSARecvMsg(fd syscall.Handle, msg *WSAMsg, bytesReceived *uint32, overlapped *syscall.Overlapped, croutine *byte) error {
 321  	err := loadWSASendRecvMsg()
 322  	if err != nil {
 323  		return err
 324  	}
 325  	r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.recvAddr, 5, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(bytesReceived)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0)
 326  	if r1 == socket_error {
 327  		if e1 != 0 {
 328  			err = errnoErr(e1)
 329  		} else {
 330  			err = syscall.EINVAL
 331  		}
 332  	}
 333  	return err
 334  }
 335  
 336  const (
 337  	ComputerNameNetBIOS                   = 0
 338  	ComputerNameDnsHostname               = 1
 339  	ComputerNameDnsDomain                 = 2
 340  	ComputerNameDnsFullyQualified         = 3
 341  	ComputerNamePhysicalNetBIOS           = 4
 342  	ComputerNamePhysicalDnsHostname       = 5
 343  	ComputerNamePhysicalDnsDomain         = 6
 344  	ComputerNamePhysicalDnsFullyQualified = 7
 345  	ComputerNameMax                       = 8
 346  
 347  	MOVEFILE_REPLACE_EXISTING      = 0x1
 348  	MOVEFILE_COPY_ALLOWED          = 0x2
 349  	MOVEFILE_DELAY_UNTIL_REBOOT    = 0x4
 350  	MOVEFILE_WRITE_THROUGH         = 0x8
 351  	MOVEFILE_CREATE_HARDLINK       = 0x10
 352  	MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20
 353  )
 354  
 355  func Rename(oldpath, newpath string) error {
 356  	from, err := syscall.UTF16PtrFromString(oldpath)
 357  	if err != nil {
 358  		return err
 359  	}
 360  	to, err := syscall.UTF16PtrFromString(newpath)
 361  	if err != nil {
 362  		return err
 363  	}
 364  	return MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING)
 365  }
 366  
 367  //sys LockFileEx(file syscall.Handle, flags uint32, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *syscall.Overlapped) (err error) = kernel32.LockFileEx
 368  //sys UnlockFileEx(file syscall.Handle, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *syscall.Overlapped) (err error) = kernel32.UnlockFileEx
 369  
 370  const (
 371  	LOCKFILE_FAIL_IMMEDIATELY = 0x00000001
 372  	LOCKFILE_EXCLUSIVE_LOCK   = 0x00000002
 373  )
 374  
 375  const MB_ERR_INVALID_CHARS = 8
 376  
 377  //sys	GetACP() (acp uint32) = kernel32.GetACP
 378  //sys	GetConsoleCP() (ccp uint32) = kernel32.GetConsoleCP
 379  //sys	MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar
 380  //sys	GetCurrentThread() (pseudoHandle syscall.Handle, err error) = kernel32.GetCurrentThread
 381  
 382  // Constants from lmshare.h
 383  const (
 384  	STYPE_DISKTREE  = 0x00
 385  	STYPE_TEMPORARY = 0x40000000
 386  )
 387  
 388  type SHARE_INFO_2 struct {
 389  	Netname     *uint16
 390  	Type        uint32
 391  	Remark      *uint16
 392  	Permissions uint32
 393  	MaxUses     uint32
 394  	CurrentUses uint32
 395  	Path        *uint16
 396  	Passwd      *uint16
 397  }
 398  
 399  //sys  NetShareAdd(serverName *uint16, level uint32, buf *byte, parmErr *uint16) (neterr error) = netapi32.NetShareAdd
 400  //sys  NetShareDel(serverName *uint16, netName *uint16, reserved uint32) (neterr error) = netapi32.NetShareDel
 401  
 402  const (
 403  	FILE_NAME_NORMALIZED = 0x0
 404  	FILE_NAME_OPENED     = 0x8
 405  
 406  	VOLUME_NAME_DOS  = 0x0
 407  	VOLUME_NAME_GUID = 0x1
 408  	VOLUME_NAME_NONE = 0x4
 409  	VOLUME_NAME_NT   = 0x2
 410  )
 411  
 412  //sys	GetFinalPathNameByHandle(file syscall.Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) = kernel32.GetFinalPathNameByHandleW
 413  
 414  func ErrorLoadingGetTempPath2() error {
 415  	return procGetTempPath2W.Find()
 416  }
 417  
 418  //sys	CreateEnvironmentBlock(block **uint16, token syscall.Token, inheritExisting bool) (err error) = userenv.CreateEnvironmentBlock
 419  //sys	DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock
 420  //sys	CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle syscall.Handle, err error) = kernel32.CreateEventW
 421  
 422  //sys	ProcessPrng(buf []byte) (err error) = bcryptprimitives.ProcessPrng
 423  
 424  type FILE_ID_BOTH_DIR_INFO struct {
 425  	NextEntryOffset uint32
 426  	FileIndex       uint32
 427  	CreationTime    syscall.Filetime
 428  	LastAccessTime  syscall.Filetime
 429  	LastWriteTime   syscall.Filetime
 430  	ChangeTime      syscall.Filetime
 431  	EndOfFile       uint64
 432  	AllocationSize  uint64
 433  	FileAttributes  uint32
 434  	FileNameLength  uint32
 435  	EaSize          uint32
 436  	ShortNameLength uint32
 437  	ShortName       [12]uint16
 438  	FileID          uint64
 439  	FileName        [1]uint16
 440  }
 441  
 442  type FILE_FULL_DIR_INFO struct {
 443  	NextEntryOffset uint32
 444  	FileIndex       uint32
 445  	CreationTime    syscall.Filetime
 446  	LastAccessTime  syscall.Filetime
 447  	LastWriteTime   syscall.Filetime
 448  	ChangeTime      syscall.Filetime
 449  	EndOfFile       uint64
 450  	AllocationSize  uint64
 451  	FileAttributes  uint32
 452  	FileNameLength  uint32
 453  	EaSize          uint32
 454  	FileName        [1]uint16
 455  }
 456  
 457  //sys	GetVolumeInformationByHandle(file syscall.Handle, volumeNameBuffer *uint16, volumeNameSize uint32, volumeNameSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemNameBuffer *uint16, fileSystemNameSize uint32) (err error) = GetVolumeInformationByHandleW
 458  //sys	GetVolumeNameForVolumeMountPoint(volumeMountPoint *uint16, volumeName *uint16, bufferlength uint32) (err error) = GetVolumeNameForVolumeMountPointW
 459  
 460  type RUNTIME_FUNCTION struct {
 461  	BeginAddress uint32
 462  	EndAddress   uint32
 463  	UnwindData   uint32
 464  }
 465  
 466  //sys	RtlLookupFunctionEntry(pc uintptr, baseAddress *uintptr, table unsafe.Pointer) (ret *RUNTIME_FUNCTION) = kernel32.RtlLookupFunctionEntry
 467  //sys	RtlVirtualUnwind(handlerType uint32, baseAddress uintptr, pc uintptr, entry *RUNTIME_FUNCTION, ctxt unsafe.Pointer, data unsafe.Pointer, frame *uintptr, ctxptrs unsafe.Pointer) (ret uintptr) = kernel32.RtlVirtualUnwind
 468  
 469  type SERVICE_STATUS struct {
 470  	ServiceType             uint32
 471  	CurrentState            uint32
 472  	ControlsAccepted        uint32
 473  	Win32ExitCode           uint32
 474  	ServiceSpecificExitCode uint32
 475  	CheckPoint              uint32
 476  	WaitHint                uint32
 477  }
 478  
 479  const (
 480  	SERVICE_RUNNING      = 4
 481  	SERVICE_QUERY_STATUS = 4
 482  )
 483  
 484  //sys    OpenService(mgr syscall.Handle, serviceName *uint16, access uint32) (handle syscall.Handle, err error) = advapi32.OpenServiceW
 485  //sys	QueryServiceStatus(hService syscall.Handle, lpServiceStatus *SERVICE_STATUS) (err error)  = advapi32.QueryServiceStatus
 486  //sys    OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle syscall.Handle, err error)  [failretval==0] = advapi32.OpenSCManagerW
 487  
 488  func FinalPath(h syscall.Handle, flags uint32) (string, error) {
 489  	buf := make([]uint16, 100)
 490  	for {
 491  		n, err := GetFinalPathNameByHandle(h, &buf[0], uint32(len(buf)), flags)
 492  		if err != nil {
 493  			return "", err
 494  		}
 495  		if n < uint32(len(buf)) {
 496  			break
 497  		}
 498  		buf = make([]uint16, n)
 499  	}
 500  	return syscall.UTF16ToString(buf), nil
 501  }
 502  
 503  // QueryPerformanceCounter retrieves the current value of performance counter.
 504  //
 505  //go:linkname QueryPerformanceCounter
 506  func QueryPerformanceCounter() int64 // Implemented in runtime package.
 507  
 508  // QueryPerformanceFrequency retrieves the frequency of the performance counter.
 509  // The returned value is represented as counts per second.
 510  //
 511  //go:linkname QueryPerformanceFrequency
 512  func QueryPerformanceFrequency() int64 // Implemented in runtime package.
 513  
 514  //sys   GetModuleHandle(modulename *uint16) (handle syscall.Handle, err error) = kernel32.GetModuleHandleW
 515  
 516  const (
 517  	PIPE_ACCESS_INBOUND  = 0x00000001
 518  	PIPE_ACCESS_OUTBOUND = 0x00000002
 519  	PIPE_ACCESS_DUPLEX   = 0x00000003
 520  
 521  	PIPE_TYPE_BYTE    = 0x00000000
 522  	PIPE_TYPE_MESSAGE = 0x00000004
 523  
 524  	PIPE_READMODE_BYTE    = 0x00000000
 525  	PIPE_READMODE_MESSAGE = 0x00000002
 526  )
 527  
 528  //sys	CreateIoCompletionPort(filehandle syscall.Handle, cphandle syscall.Handle, key uintptr, threadcnt uint32) (handle syscall.Handle, err error)
 529  //sys	GetOverlappedResult(handle syscall.Handle, overlapped *syscall.Overlapped, done *uint32, wait bool) (err error)
 530  //sys	CreateNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error)  [failretval==syscall.InvalidHandle] = CreateNamedPipeW
 531  
 532  // NTStatus corresponds with NTSTATUS, error values returned by ntdll.dll and
 533  // other native functions.
 534  type NTStatus uint32
 535  
 536  func (s NTStatus) Errno() syscall.Errno {
 537  	return rtlNtStatusToDosErrorNoTeb(s)
 538  }
 539  
 540  func langID(pri, sub uint16) uint32 { return uint32(sub)<<10 | uint32(pri) }
 541  
 542  func (s NTStatus) Error() string {
 543  	return s.Errno().Error()
 544  }
 545  
 546  // x/sys/windows/mkerrors.bash can generate a complete list of NTStatus codes.
 547  //
 548  // At the moment, we only need a couple, so just put them here manually.
 549  // If this list starts getting long, we should consider generating the full set.
 550  const (
 551  	STATUS_OBJECT_NAME_COLLISION     NTStatus = 0xC0000035
 552  	STATUS_FILE_IS_A_DIRECTORY       NTStatus = 0xC00000BA
 553  	STATUS_DIRECTORY_NOT_EMPTY       NTStatus = 0xC0000101
 554  	STATUS_NOT_A_DIRECTORY           NTStatus = 0xC0000103
 555  	STATUS_CANNOT_DELETE             NTStatus = 0xC0000121
 556  	STATUS_REPARSE_POINT_ENCOUNTERED NTStatus = 0xC000050B
 557  )
 558  
 559  const (
 560  	FileModeInformation = 16
 561  )
 562  
 563  // https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_file_mode_information
 564  type FILE_MODE_INFORMATION struct {
 565  	Mode uint32
 566  }
 567  
 568  // NT Native APIs
 569  //sys   NtCreateFile(handle *syscall.Handle, access uint32, oa *OBJECT_ATTRIBUTES, iosb *IO_STATUS_BLOCK, allocationSize *int64, attributes uint32, share uint32, disposition uint32, options uint32, eabuffer unsafe.Pointer, ealength uint32) (ntstatus error) = ntdll.NtCreateFile
 570  //sys   NtOpenFile(handle *syscall.Handle, access uint32, oa *OBJECT_ATTRIBUTES, iosb *IO_STATUS_BLOCK, share uint32, options uint32) (ntstatus error) = ntdll.NtOpenFile
 571  //sys   rtlNtStatusToDosErrorNoTeb(ntstatus NTStatus) (ret syscall.Errno) = ntdll.RtlNtStatusToDosErrorNoTeb
 572  //sys   NtSetInformationFile(handle syscall.Handle, iosb *IO_STATUS_BLOCK, inBuffer unsafe.Pointer, inBufferLen uint32, class uint32) (ntstatus error) = ntdll.NtSetInformationFile
 573  //sys	RtlIsDosDeviceName_U(name *uint16) (ret uint32) = ntdll.RtlIsDosDeviceName_U
 574  //sys   NtQueryInformationFile(handle syscall.Handle, iosb *IO_STATUS_BLOCK, inBuffer unsafe.Pointer, inBufferLen uint32, class uint32) (ntstatus error) = ntdll.NtQueryInformationFile
 575