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

View as plain text