Source file src/internal/syscall/windows/syscall_windows.go

     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_FILE_IS_A_DIRECTORY       NTStatus = 0xC00000BA
   552  	STATUS_DIRECTORY_NOT_EMPTY       NTStatus = 0xC0000101
   553  	STATUS_NOT_A_DIRECTORY           NTStatus = 0xC0000103
   554  	STATUS_CANNOT_DELETE             NTStatus = 0xC0000121
   555  	STATUS_REPARSE_POINT_ENCOUNTERED NTStatus = 0xC000050B
   556  )
   557  
   558  const (
   559  	FileModeInformation = 16
   560  )
   561  
   562  // https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_file_mode_information
   563  type FILE_MODE_INFORMATION struct {
   564  	Mode uint32
   565  }
   566  
   567  // NT Native APIs
   568  //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
   569  //sys   NtOpenFile(handle *syscall.Handle, access uint32, oa *OBJECT_ATTRIBUTES, iosb *IO_STATUS_BLOCK, share uint32, options uint32) (ntstatus error) = ntdll.NtOpenFile
   570  //sys   rtlNtStatusToDosErrorNoTeb(ntstatus NTStatus) (ret syscall.Errno) = ntdll.RtlNtStatusToDosErrorNoTeb
   571  //sys   NtSetInformationFile(handle syscall.Handle, iosb *IO_STATUS_BLOCK, inBuffer unsafe.Pointer, inBufferLen uint32, class uint32) (ntstatus error) = ntdll.NtSetInformationFile
   572  //sys	RtlIsDosDeviceName_U(name *uint16) (ret uint32) = ntdll.RtlIsDosDeviceName_U
   573  //sys   NtQueryInformationFile(handle syscall.Handle, iosb *IO_STATUS_BLOCK, inBuffer unsafe.Pointer, inBufferLen uint32, class uint32) (ntstatus error) = ntdll.NtQueryInformationFile
   574  

View as plain text