github.com/iDigitalFlame/xmt@v0.5.4/device/winapi/structs.go (about)

     1  //go:build windows
     2  // +build windows
     3  
     4  // Copyright (C) 2020 - 2023 iDigitalFlame
     5  //
     6  // This program is free software: you can redistribute it and/or modify
     7  // it under the terms of the GNU General Public License as published by
     8  // the Free Software Foundation, either version 3 of the License, or
     9  // any later version.
    10  //
    11  // This program is distributed in the hope that it will be useful,
    12  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  // GNU General Public License for more details.
    15  //
    16  // You should have received a copy of the GNU General Public License
    17  // along with this program.  If not, see <https://www.gnu.org/licenses/>.
    18  //
    19  
    20  package winapi
    21  
    22  import (
    23  	"sync"
    24  	"unsafe"
    25  )
    26  
    27  // SID matches the SID struct
    28  //
    29  //	https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-sid
    30  type SID struct{}
    31  
    32  // ACL matches the ACL struct
    33  //
    34  //	https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-acl
    35  //
    36  //	typedef struct _ACL {
    37  //	  BYTE AclRevision;
    38  //	  BYTE Sbz1;
    39  //	  WORD AclSize;
    40  //	  WORD AceCount;
    41  //	  WORD Sbz2;
    42  //	} ACL;
    43  //
    44  // DO NOT REORDER
    45  type ACL struct {
    46  	_, _    byte
    47  	_, _, _ uint16
    48  }
    49  
    50  // LUID matches the LUID struct
    51  //
    52  //	https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-luid
    53  //
    54  //	typedef struct _LUID {
    55  //	  DWORD LowPart;
    56  //	  LONG  HighPart;
    57  //	} LUID, *PLUID;
    58  //
    59  // DO NOT REORDER
    60  type LUID struct {
    61  	Low  uint32
    62  	High int32
    63  }
    64  type curDir struct {
    65  	// DO NOT REORDER
    66  	DosPath lsaString
    67  	Handle  uintptr
    68  }
    69  type modInfo struct {
    70  	// DO NOT REORDER
    71  	Base  uintptr
    72  	Size  uint32
    73  	Entry uintptr
    74  }
    75  type clientID struct {
    76  	// DO NOT REORDER
    77  	Process uintptr
    78  	Thread  uintptr
    79  }
    80  type objAttrs struct {
    81  	// DO NOT REORDER
    82  	Length                   uint32
    83  	RootDirectory            uintptr
    84  	ObjectName               *lsaString
    85  	Attributes               uint32
    86  	SecurityDescriptor       *SecurityDescriptor
    87  	SecurityQualityOfService *SecurityQualityOfService
    88  }
    89  type certBlob struct {
    90  	// DO NOT REORDER
    91  	_ uint32
    92  	_ uintptr
    93  }
    94  type certAlgo struct {
    95  	// DO NOT REORDER
    96  	_ *uint16
    97  	_ certBlob
    98  }
    99  type certInfo struct {
   100  	// DO NOT REORDER
   101  	_       uint32
   102  	Serial  certBlob
   103  	_       certAlgo
   104  	Issuer  certBlob
   105  	_, _    uint64
   106  	Subject certBlob
   107  	_       certAlgo
   108  	_, _, _ certBlob
   109  	_       uint32
   110  	_       uintptr
   111  	// NOTE(dij): This is here as go1.10 has a bug with this.
   112  	//            It tries to compare certInfo structs for some reason?
   113  	_ [0]func()
   114  }
   115  type lsaString struct {
   116  	// DO NOT REORDER
   117  	Length        uint16
   118  	MaximumLength uint16
   119  	Buffer        *uint16
   120  }
   121  type dumpParam struct {
   122  	_ [0]func()
   123  	sync.Mutex
   124  	h, b uintptr
   125  	s, w uint64
   126  }
   127  
   128  // TokenUser matches the TOKEN_USER struct.
   129  //
   130  //	https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-token_user
   131  //
   132  //	typedef struct _TOKEN_USER {
   133  //	  SID_AND_ATTRIBUTES User;
   134  //	} TOKEN_USER, *PTOKEN_USER
   135  //
   136  // DO NOT REORDER
   137  type TokenUser struct {
   138  	User SIDAndAttributes
   139  }
   140  
   141  // ProxyInfo matches the WINHTTP_PROXY_INFO struct
   142  //
   143  //	https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_proxy_info
   144  //
   145  //	typedef struct _WINHTTP_PROXY_INFO {
   146  //	  DWORD  dwAccessType;
   147  //	  LPWSTR lpszProxy;
   148  //	  LPWSTR lpszProxyBypass;
   149  //	} WINHTTP_PROXY_INFO, *LPWINHTTP_PROXY_INFO, *PWINHTTP_PROXY_INFO;
   150  //
   151  // DO NOT REORDER
   152  type ProxyInfo struct {
   153  	AccessType  uint32
   154  	Proxy       *uint16
   155  	ProxyBypass *uint16
   156  }
   157  type certSigner struct {
   158  	// DO NOT REORDER
   159  	_       uint32
   160  	Issuer  certBlob
   161  	Serial  certBlob
   162  	_, _    certAlgo
   163  	_, _, _ certBlob
   164  	// NOTE(dij): This is here as go1.10 has a bug with this.
   165  	//            It tries to compare certSigner structs for some reason?
   166  	_ [0]func()
   167  }
   168  type dumpOutput struct {
   169  	Status int32
   170  }
   171  type privileges struct {
   172  	// DO NOT REORDER
   173  	PrivilegeCount uint32
   174  	Privileges     [5]LUIDAndAttributes
   175  }
   176  type processPeb struct {
   177  	// DO NOT REORDER
   178  	_                      [2]byte
   179  	BeingDebugged          byte
   180  	_                      [1]byte
   181  	_                      [2]uintptr
   182  	Ldr                    uintptr
   183  	ProcessParameters      *processParams
   184  	_                      [3]uintptr
   185  	AtlThunkSListPtr       uintptr
   186  	_                      uintptr
   187  	_                      uint32
   188  	_                      uintptr
   189  	_                      uint32
   190  	AtlThunkSListPtr32     uint32
   191  	_                      [9]uintptr
   192  	_                      [10]byte
   193  	NtGlobalFlag           uint32
   194  	_                      [35]uintptr
   195  	_                      [84]byte
   196  	PostProcessInitRoutine uintptr
   197  	_                      [128]byte
   198  	_                      [1]uintptr
   199  	SessionID              uint32
   200  }
   201  
   202  // Overlapped matches the OVERLAPPED struct
   203  //
   204  //	https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-overlapped
   205  //
   206  //	typedef struct _OVERLAPPED {
   207  //	  ULONG_PTR Internal;
   208  //	  ULONG_PTR InternalHigh;
   209  //	  DWORD Offset;
   210  //	  DWORD OffsetHigh;
   211  //	  HANDLE    hEvent;
   212  //	} OVERLAPPED, *LPOVERLAPPED;
   213  //
   214  // DO NOT REORDER
   215  type Overlapped struct {
   216  	Internal     uintptr
   217  	InternalHigh uintptr
   218  	Offset       uint32
   219  	OffsetHigh   uint32
   220  	Event        uintptr
   221  }
   222  
   223  // StartupInfo matches the STARTUPINFOW struct
   224  //
   225  //	https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfow
   226  //
   227  //	typedef struct _STARTUPINFOW {
   228  //	  DWORD  cb;
   229  //	  LPWSTR lpReserved;
   230  //	  LPWSTR lpDesktop;
   231  //	  LPWSTR lpTitle;
   232  //	  DWORD  dwX;
   233  //	  DWORD  dwY;
   234  //	  DWORD  dwXSize;
   235  //	  DWORD  dwYSize;
   236  //	  DWORD  dwXCountChars;
   237  //	  DWORD  dwYCountChars;
   238  //	  DWORD  dwFillAttribute;
   239  //	  DWORD  dwFlags;
   240  //	  WORD   wShowWindow;
   241  //	  WORD   cbReserved2;
   242  //	  LPBYTE lpReserved2;
   243  //	  HANDLE hStdInput;
   244  //	  HANDLE hStdOutput;
   245  //	  HANDLE hStdError;
   246  //	} STARTUPINFOW, *LPSTARTUPINFOW;
   247  //
   248  // DO NOT REORDER
   249  type StartupInfo struct {
   250  	Cb            uint32
   251  	_             *uint16
   252  	Desktop       *uint16
   253  	Title         *uint16
   254  	X             uint32
   255  	Y             uint32
   256  	XSize         uint32
   257  	YSize         uint32
   258  	XCountChars   uint32
   259  	YCountChars   uint32
   260  	FillAttribute uint32
   261  	Flags         uint32
   262  	ShowWindow    uint16
   263  	_             uint16
   264  	_             *byte
   265  	StdInput      uintptr
   266  	StdOutput     uintptr
   267  	StdErr        uintptr
   268  }
   269  type timeZoneInfo struct {
   270  	// DO NOT REORDER
   271  	Bias         uint32
   272  	_            [80]byte
   273  	StdBias      uint32
   274  	_            [80]byte
   275  	DaylightBias uint32
   276  }
   277  type highContrast struct {
   278  	// DO NOT REORDER
   279  	Size  uint32
   280  	Flags uint32
   281  	_     *uint16
   282  }
   283  
   284  // StartupInfoEx matches the STARTUPINFOEXW struct
   285  //
   286  //	https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-startupinfoexw
   287  //
   288  //	typedef struct _STARTUPINFOEXW {
   289  //	  STARTUPINFOW                 StartupInfo;
   290  //	  LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList;
   291  //	} STARTUPINFOEXW, *LPSTARTUPINFOEXW;
   292  //
   293  // DO NOT REORDER
   294  type StartupInfoEx struct {
   295  	StartupInfo   StartupInfo
   296  	AttributeList *StartupAttributes
   297  }
   298  type lsaAttributes struct {
   299  	// DO NOT REORDER
   300  	Length     uint32
   301  	_          uintptr
   302  	_          *lsaString
   303  	Attributes uint32
   304  	_, _       unsafe.Pointer
   305  }
   306  type processParams struct {
   307  	// DO NOT REORDER
   308  	_                [16]byte
   309  	Console          uintptr
   310  	_                uint32
   311  	StandardInput    uintptr
   312  	StandardOutput   uintptr
   313  	StandardError    uintptr
   314  	CurrentDirectory curDir
   315  	DllPath          lsaString
   316  	ImagePathName    lsaString
   317  	CommandLine      lsaString
   318  	Environment      uintptr
   319  }
   320  
   321  // ServiceStatus matches the SERVICE_STATUS struct
   322  //
   323  //	https://docs.microsoft.com/en-us/windows/win32/api/winsvc/ns-winsvc-service_status
   324  //
   325  //	typedef struct _SERVICE_STATUS {
   326  //	 DWORD dwServiceType;
   327  //	 DWORD dwCurrentState;
   328  //	 DWORD dwControlsAccepted;
   329  //	 DWORD dwWin32ExitCode;
   330  //	 DWORD dwServiceSpecificExitCode;
   331  //	 DWORD dwCheckPoint;
   332  //	 DWORD dwWaitHint;
   333  //	} SERVICE_STATUS, *LPSERVICE_STATUS;
   334  type ServiceStatus struct {
   335  	ServiceType             uint32
   336  	CurrentState            uint32
   337  	ControlsAccepted        uint32
   338  	Win32ExitCode           uint32
   339  	ServiceSpecificExitCode uint32
   340  	CheckPoint              uint32
   341  	WaitHint                uint32
   342  }
   343  type diskGeometryEx struct {
   344  	// DO NOT REORDER
   345  	_    [24]byte
   346  	Size uint64
   347  	_    uintptr
   348  }
   349  type threadBasicInfo struct {
   350  	// DO NOT REORDER
   351  	ExitStatus     uint32
   352  	TebBaseAddress uintptr
   353  	ClientID       clientID
   354  	_              uint64
   355  	_              uint32
   356  }
   357  type ntUnicodeString struct {
   358  	// DO NOT REORDER
   359  	Length        uint16
   360  	MaximumLength uint16
   361  	_, _          uint16
   362  	Buffer        [260]uint16
   363  }
   364  type systemBasicInfo struct {
   365  	// DO NOT REORDER
   366  	_             [8]byte
   367  	PageSize      uint32
   368  	PhysicalPages uint32
   369  	LowPage       uint32
   370  	HighPage      uint32
   371  	_             uint32
   372  	_             [3]uintptr
   373  	NumProc       uint8
   374  }
   375  
   376  // SIDAndAttributes matches the SID_AND_ATTRIBUTES struct
   377  //
   378  //	https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-sid_and_attributes
   379  //
   380  //	typedef struct _SID_AND_ATTRIBUTES {
   381  //	  PSID  Sid;
   382  //	  DWORD Attributes;
   383  //	} SID_AND_ATTRIBUTES, *PSID_AND_ATTRIBUTES;
   384  //
   385  // DO NOT REORDER
   386  type SIDAndAttributes struct {
   387  	Sid        *SID
   388  	Attributes uint32
   389  }
   390  type processBasicInfo struct {
   391  	// DO NOT REORDER
   392  	ExitStatus                   uint32
   393  	PebBaseAddress               uintptr
   394  	_                            *uintptr
   395  	_                            uint32
   396  	UniqueProcessID              uintptr
   397  	InheritedFromUniqueProcessID uintptr
   398  }
   399  
   400  // ServiceTableEntry matches the SERVICE_TABLE_ENTRYW struct
   401  //
   402  //	https://docs.microsoft.com/en-us/windows/win32/api/winsvc/ns-winsvc-service_table_entryw
   403  //
   404  //	typedef struct _SERVICE_TABLE_ENTRYW {
   405  //	 LPWSTR                   lpServiceName;
   406  //	 LPSERVICE_MAIN_FUNCTIONW lpServiceProc;
   407  //	} SERVICE_TABLE_ENTRYW, *LPSERVICE_TABLE_ENTRYW;
   408  type ServiceTableEntry struct {
   409  	Name *uint16
   410  	Proc uintptr
   411  }
   412  
   413  // StartupAttributes matches the LPPROC_THREAD_ATTRIBUTE_LIST opaque struct
   414  //
   415  //	https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-initializeprocthreadattributelist
   416  //
   417  // There's not much documentation for this *shrug*
   418  type StartupAttributes struct {
   419  	_     [4]byte
   420  	Count uint32
   421  	_     [64]byte
   422  }
   423  
   424  // LUIDAndAttributes matches the LUIDAndAttributes struct
   425  //
   426  //	https://docs.microsoft.com/en-us/previous-versions/windows/desktop/wmipjobobjprov/win32-luidandattributes
   427  //
   428  //	typedef struct LUIDAndAttributes {
   429  //	  LUID  Luid;
   430  //	  DWORD dwSize;
   431  //	} PLUIDANDATTRIBUTES;
   432  //
   433  // DO NOT REORDER
   434  type LUIDAndAttributes struct {
   435  	Luid       LUID
   436  	Attributes uint32
   437  }
   438  
   439  // ProcessInformation matches the PROCESS_INFORMATION struct
   440  //
   441  //	https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-process_information
   442  //
   443  //	typedef struct _PROCESS_INFORMATION {
   444  //	  HANDLE hProcess;
   445  //	  HANDLE hThread;
   446  //	  DWORD  dwProcessId;
   447  //	  DWORD  dwThreadId;
   448  //	} PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;
   449  //
   450  // DO NOT REORDER
   451  type ProcessInformation struct {
   452  	Process   uintptr
   453  	Thread    uintptr
   454  	ProcessID uint32
   455  	ThreadID  uint32
   456  }
   457  
   458  // SecurityDescriptor matches the SECURITY_DESCRIPTOR struct
   459  //
   460  //	https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-security_descriptor
   461  //
   462  //	typedef struct _SECURITY_DESCRIPTOR {
   463  //	  BYTE                        Revision;
   464  //	  BYTE                        Sbz1;
   465  //	  SECURITY_DESCRIPTOR_CONTROL Control;
   466  //	  PSID                        Owner;
   467  //	  PSID                        Group;
   468  //	  PACL                        Sacl;
   469  //	  PACL                        Dacl;
   470  //	} SECURITY_DESCRIPTOR, *PISECURITY_DESCRIPTOR;
   471  //
   472  // DO NOT REORDER
   473  type SecurityDescriptor struct {
   474  	_, _ byte
   475  	_    SecurityDescriptorControl
   476  	_, _ SID
   477  	_, _ *ACL
   478  }
   479  
   480  // SecurityAttributes matches the SECURITY_ATTRIBUTES struct
   481  //
   482  //	https://docs.microsoft.com/en-us/windows/win32/api/wtypesbase/ns-wtypesbase-security_attributes
   483  //
   484  //	typedef struct _SECURITY_ATTRIBUTES {
   485  //	  DWORD  nLength;
   486  //	  LPVOID lpSecurityDescriptor;
   487  //	  BOOL   bInheritHandle;
   488  //	} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
   489  //
   490  // DO NOT REORDER
   491  type SecurityAttributes struct {
   492  	Length             uint32
   493  	SecurityDescriptor *SecurityDescriptor
   494  	InheritHandle      uint32
   495  }
   496  type lsaAccountDomainInfo struct {
   497  	// DO NOT REORDER
   498  	_   lsaString
   499  	SID *SID
   500  }
   501  
   502  // SecurityQualityOfService matches the SECURITY_QUALITY_OF_SERVICE struct
   503  //
   504  //	https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-security_quality_of_service
   505  //
   506  //	typedef struct _SECURITY_QUALITY_OF_SERVICE {
   507  //	  DWORD                          Length;
   508  //	  SECURITY_IMPERSONATION_LEVEL   ImpersonationLevel;
   509  //	  SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode;
   510  //	  BOOLEAN                        EffectiveOnly;
   511  //	} SECURITY_QUALITY_OF_SERVICE, *PSECURITY_QUALITY_OF_SERVICE;
   512  type SecurityQualityOfService struct {
   513  	Length              uint32
   514  	ImpersonationLevel  uint32
   515  	ContextTrackingMode bool
   516  	EffectiveOnly       bool
   517  }
   518  
   519  // SecurityDescriptorControl matches the SECURITY_DESCRIPTOR_CONTROL bitflag.
   520  //
   521  //	https://docs.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-control
   522  //
   523  // typedef WORD SECURITY_DESCRIPTOR_CONTROL, *PSECURITY_DESCRIPTOR_CONTROL;
   524  type SecurityDescriptorControl uint16
   525  
   526  // String returns the string representation of this SID.
   527  func (s *SID) String() string {
   528  	var o *uint16
   529  	if err := convertSIDToStringSID(s, &o); err != nil {
   530  		return ""
   531  	}
   532  	v := UTF16ToString((*[256]uint16)(unsafe.Pointer(o))[:])
   533  	localFree(uintptr(unsafe.Pointer(o)))
   534  	return v
   535  }
   536  
   537  // UserName attempts to return a Domain\User string from the SID.
   538  func (s *SID) UserName() (string, error) {
   539  	var c, x, t uint32 = 64, 64, 0
   540  	for {
   541  		var (
   542  			n, d      = make([]uint16, c), make([]uint16, x)
   543  			r, _, err = syscallN(funcLookupAccountSid.address(),
   544  				0, uintptr(unsafe.Pointer(s)), uintptr(unsafe.Pointer(&n[0])),
   545  				uintptr(unsafe.Pointer(&c)), uintptr(unsafe.Pointer(&d[0])),
   546  				uintptr(unsafe.Pointer(&x)), uintptr(unsafe.Pointer(&t)),
   547  			)
   548  		)
   549  		if r > 0 {
   550  			u, q := UTF16ToString(n), UTF16ToString(d)
   551  			if n, d = nil, nil; len(q) == 0 {
   552  				return u, nil
   553  			}
   554  			return q + "\\" + u, nil
   555  		}
   556  		if err != ErrInsufficientBuffer || c <= uint32(len(n)) {
   557  			return "", unboxError(err)
   558  		}
   559  	}
   560  }
   561  
   562  // IsWellKnown returns true if this SID matches the well known SID type index.
   563  func (s *SID) IsWellKnown(t uint32) bool {
   564  	r, _, _ := syscallN(funcIsWellKnownSID.address(), uintptr(unsafe.Pointer(s)), uintptr(t))
   565  	return r > 0
   566  }
   567  func (s *SecurityDescriptor) len() uint32 {
   568  	r, _, _ := syscallN(funcRtlLengthSecurityDescriptor.address(), uintptr(unsafe.Pointer(s)))
   569  	return uint32(r)
   570  }
   571  func localFree(h uintptr) (uintptr, error) {
   572  	r, _, err := syscallN(funcLocalFree.address(), h)
   573  	if r != 0 {
   574  		return r, unboxError(err)
   575  	}
   576  	return r, nil
   577  }
   578  func convertSIDToStringSID(i *SID, s **uint16) error {
   579  	r, _, err := syscallN(funcConvertSIDToStringSID.address(), uintptr(unsafe.Pointer(i)), uintptr(unsafe.Pointer(s)))
   580  	if r == 0 {
   581  		return unboxError(err)
   582  	}
   583  	return nil
   584  }
   585  func (s *SecurityDescriptor) copyRelative() *SecurityDescriptor {
   586  	var (
   587  		n = int(s.len())
   588  		m = int(unsafe.Sizeof(SecurityDescriptor{}))
   589  	)
   590  	if n < m {
   591  		n = m
   592  	}
   593  	var (
   594  		b []byte
   595  		h = (*SliceHeader)(unsafe.Pointer(&b))
   596  	)
   597  	h.Data = unsafe.Pointer(s)
   598  	h.Len, h.Cap = n, n
   599  	var (
   600  		d []byte
   601  		x = (*SliceHeader)(unsafe.Pointer(&d))
   602  		a = make([]uintptr, (n+int(ptrSize)-1)/int(ptrSize))
   603  	)
   604  	x.Data = (*SliceHeader)(unsafe.Pointer(&a)).Data
   605  	x.Len, x.Cap = n, n
   606  	copy(d, b)
   607  	return (*SecurityDescriptor)(unsafe.Pointer(&d[0]))
   608  }