Browse Source

Merge pull request #3905 from flysand7/winapi-process-procs

[sys/windows]: Advapi bindings, process-related functions and thread context
gingerBill 1 year ago
parent
commit
9e0c4098be
4 changed files with 354 additions and 21 deletions
  1. 172 1
      core/sys/windows/advapi32.odin
  2. 45 0
      core/sys/windows/kernel32.odin
  3. 135 18
      core/sys/windows/types.odin
  4. 2 2
      core/sys/windows/util.odin

+ 172 - 1
core/sys/windows/advapi32.odin

@@ -18,6 +18,14 @@ foreign advapi32 {
 	                        OpenAsSelf:    BOOL,
 	                        TokenHandle:   ^HANDLE) -> BOOL ---
 
+	GetTokenInformation :: proc (
+		TokenHandle: HANDLE,
+		TokenInformationClass: TOKEN_INFORMATION_CLASS,
+		TokenInformation: LPVOID,
+		TokenInformationLength: DWORD,
+		ReturnLength: PDWORD,
+	) -> BOOL ---
+
 	CryptAcquireContextW :: proc(hProv: ^HCRYPTPROV, szContainer, szProvider: wstring, dwProvType, dwFlags: DWORD) -> DWORD ---
 	CryptGenRandom       :: proc(hProv: HCRYPTPROV, dwLen: DWORD, buf: LPVOID) -> DWORD ---
 	CryptReleaseContext  :: proc(hProv: HCRYPTPROV, dwFlags: DWORD) -> DWORD ---
@@ -44,7 +52,17 @@ foreign advapi32 {
 		cbSid: ^DWORD,
 		ReferencedDomainName: wstring,
 		cchReferencedDomainName: ^DWORD,
-		peUse: ^SID_TYPE,
+		peUse: PSID_NAME_USE,
+	) -> BOOL ---
+
+	LookupAccountSidW :: proc (
+		lpSystemName: LPCWSTR,
+		Sid: PSID,
+		Name: LPWSTR,
+		cchName: LPDWORD,
+		ReferencedDomainName: LPWSTR,
+		cchReferencedDomainName: LPDWORD,
+		peUse: PSID_NAME_USE,
 	) -> BOOL ---
 
 	CreateProcessWithLogonW :: proc(
@@ -164,3 +182,156 @@ foreign advapi32 {
 		AccessStatus: LPBOOL,
 	) -> BOOL ---
 }
+
+PTOKEN_INFORMATION_CLASS :: ^TOKEN_INFORMATION_CLASS
+TOKEN_INFORMATION_CLASS :: enum i32 {
+	TokenUser = 1,
+	TokenGroups,
+	TokenPrivileges,
+	TokenOwner,
+	TokenPrimaryGroup,
+	TokenDefaultDacl,
+	TokenSource,
+	TokenType,
+	TokenImpersonationLevel,
+	TokenStatistics,
+	TokenRestrictedSids,
+	TokenSessionId,
+	TokenGroupsAndPrivileges,
+	TokenSessionReference,
+	TokenSandBoxInert,
+	TokenAuditPolicy,
+	TokenOrigin,
+	TokenElevationType,
+	TokenLinkedToken,
+	TokenElevation,
+	TokenHasRestrictions,
+	TokenAccessInformation,
+	TokenVirtualizationAllowed,
+	TokenVirtualizationEnabled,
+	TokenIntegrityLevel,
+	TokenUIAccess,
+	TokenMandatoryPolicy,
+	TokenLogonSid,
+	TokenIsAppContainer,
+	TokenCapabilities,
+	TokenAppContainerSid,
+	TokenAppContainerNumber,
+	TokenUserClaimAttributes,
+	TokenDeviceClaimAttributes,
+	TokenRestrictedUserClaimAttributes,
+	TokenRestrictedDeviceClaimAttributes,
+	TokenDeviceGroups,
+	TokenRestrictedDeviceGroups,
+	TokenSecurityAttributes,
+	TokenIsRestricted,
+	TokenProcessTrustLevel,
+	TokenPrivateNameSpace,
+	TokenSingletonAttributes,
+	TokenBnoIsolation,
+	TokenChildProcessFlags,
+	TokenIsLessPrivilegedAppContainer,
+	TokenIsSandboxed,
+	TokenIsAppSilo,
+	TokenLoggingInformation,
+	MaxTokenInfoClass,
+}
+
+PSID_NAME_USE :: ^SID_NAME_USE
+SID_NAME_USE :: enum i32 {
+	SidTypeUser = 1,
+	SidTypeGroup,
+	SidTypeDomain,
+	SidTypeAlias,
+	SidTypeWellKnownGroup,
+	SidTypeDeletedAccount,
+	SidTypeInvalid,
+	SidTypeUnknown,
+	SidTypeComputer,
+	SidTypeLabel,
+	SidTypeLogonSession,
+}
+
+PTOKEN_USER :: ^TOKEN_USER
+TOKEN_USER :: struct {
+	User: SID_AND_ATTRIBUTES,
+}
+
+PSID_AND_ATTRIBUTES :: ^SID_AND_ATTRIBUTES
+SID_AND_ATTRIBUTES :: struct {
+	Sid: rawptr,
+	Attributes: ULONG,
+}
+
+PTOKEN_TYPE :: ^TOKEN_TYPE
+TOKEN_TYPE :: enum {
+	TokenPrimary = 1,
+	TokenImpersonation = 2,
+}
+
+PTOKEN_STATISTICS :: ^TOKEN_STATISTICS
+TOKEN_STATISTICS :: struct {
+	TokenId: LUID,
+	AuthenticationId: LUID,
+	ExpirationTime: LARGE_INTEGER,
+	TokenType: TOKEN_TYPE,
+	ImpersonationLevel: SECURITY_IMPERSONATION_LEVEL,
+	DynamicCharged: DWORD,
+	DynamicAvailable: DWORD,
+	GroupCount: DWORD,
+	PrivilegeCount: DWORD,
+	ModifiedId: LUID,
+}
+
+
+TOKEN_SOURCE_LENGTH :: 8
+PTOKEN_SOURCE :: ^TOKEN_SOURCE
+TOKEN_SOURCE :: struct {
+	SourceName: [TOKEN_SOURCE_LENGTH]CHAR,
+	SourceIdentifier: LUID,
+}
+
+
+PTOKEN_PRIVILEGES :: ^TOKEN_PRIVILEGES
+TOKEN_PRIVILEGES :: struct {
+	PrivilegeCount: DWORD,
+	Privileges: [0]LUID_AND_ATTRIBUTES,
+}
+
+PTOKEN_PRIMARY_GROUP :: ^TOKEN_PRIMARY_GROUP
+TOKEN_PRIMARY_GROUP :: struct {
+	PrimaryGroup: PSID,
+}
+
+PTOKEN_OWNER :: ^TOKEN_OWNER
+TOKEN_OWNER :: struct {
+	Owner: PSID,
+}
+
+PTOKEN_GROUPS_AND_PRIVILEGES :: ^TOKEN_GROUPS_AND_PRIVILEGES
+TOKEN_GROUPS_AND_PRIVILEGES :: struct {
+	SidCount: DWORD,
+	SidLength: DWORD,
+	Sids: PSID_AND_ATTRIBUTES,
+	RestrictedSidCount: DWORD,
+	RestrictedSidLength: DWORD,
+	RestrictedSids: PSID_AND_ATTRIBUTES,
+	PrivilegeCount: DWORD,
+	PrivilegeLength: DWORD,
+	Privileges: PLUID_AND_ATTRIBUTES,
+	AuthenticationId: LUID,
+}
+
+PTOKEN_DEFAULT_DACL :: ^TOKEN_DEFAULT_DACL
+TOKEN_DEFAULT_DACL :: struct {
+	DefaultDacl: PACL,
+}
+
+PACL :: ^ACL
+ACL :: struct {
+	AclRevision: BYTE,
+	Sbz1: BYTE,
+	AclSize: WORD,
+	AceCount: WORD,
+	Sbz2: WORD,
+}

+ 45 - 0
core/sys/windows/kernel32.odin

@@ -233,6 +233,12 @@ foreign kernel32 {
 	QueryPerformanceCounter :: proc(lpPerformanceCount: ^LARGE_INTEGER) -> BOOL ---
 	GetExitCodeProcess :: proc(hProcess: HANDLE, lpExitCode: LPDWORD) -> BOOL ---
 	TerminateProcess :: proc(hProcess: HANDLE, uExitCode: UINT) -> BOOL ---
+	OpenProcess :: proc(dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwProcessId: DWORD) -> HANDLE ---
+	OpenThread :: proc(dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwThreadId: DWORD) -> HANDLE ---
+	GetThreadContext :: proc(
+		hThread: HANDLE,
+		lpContext: LPCONTEXT,
+	) -> BOOL ---
 	CreateProcessW :: proc(
 		lpApplicationName: LPCWSTR,
 		lpCommandLine: LPWSTR,
@@ -543,6 +549,45 @@ THREAD_PRIORITY_IDLE          :: THREAD_BASE_PRIORITY_IDLE
 THREAD_MODE_BACKGROUND_BEGIN  :: 0x00010000
 THREAD_MODE_BACKGROUND_END    :: 0x00020000
 
+PROCESS_ALL_ACCESS :: 0x000F0000 | SYNCHRONIZE | 0xFFFF
+PROCESS_CREATE_PROCESS :: 0x0080
+PROCESS_CREATE_THREAD :: 0x0002
+PROCESS_DUP_HANDLE :: 0x0040
+PROCESS_QUERY_INFORMATION :: 0x0400
+PROCESS_QUERY_LIMITED_INFORMATION :: 0x1000
+PROCESS_SET_INFORMATION :: 0x0200
+PROCESS_SET_QUOTA :: 0x0100
+PROCESS_SUSPEND_RESUME :: 0x0800
+PROCESS_TERMINATE :: 0x0001
+PROCESS_VM_OPERATION :: 0x0008
+PROCESS_VM_READ :: 0x0010
+PROCESS_VM_WRITE :: 0x0020
+
+THREAD_ALL_ACCESS :: \
+	THREAD_DIRECT_IMPERSONATION |
+	THREAD_GET_CONTEXT |
+	THREAD_IMPERSONATE |
+	THREAD_QUERY_INFORMATION |
+	THREAD_QUERY_LIMITED_INFORMATION |
+	THREAD_SET_CONTEXT |
+	THREAD_SET_INFORMATION |
+	THREAD_SET_LIMITED_INFORMATION |
+	THREAD_SET_THREAD_TOKEN |
+	THREAD_SUSPEND_RESUME |
+	THREAD_TERMINATE |
+	SYNCHRONIZE
+THREAD_DIRECT_IMPERSONATION :: 0x0200
+THREAD_GET_CONTEXT :: 0x0008
+THREAD_IMPERSONATE :: 0x0100
+THREAD_QUERY_INFORMATION :: 0x0040
+THREAD_QUERY_LIMITED_INFORMATION :: 0x0800
+THREAD_SET_CONTEXT :: 0x0010
+THREAD_SET_INFORMATION :: 0x0020
+THREAD_SET_LIMITED_INFORMATION :: 0x0400
+THREAD_SET_THREAD_TOKEN :: 0x0080
+THREAD_SUSPEND_RESUME :: 0x0002
+THREAD_TERMINATE :: 0x0001
+
 COPY_FILE_FAIL_IF_EXISTS              :: 0x00000001
 COPY_FILE_RESTARTABLE                 :: 0x00000002
 COPY_FILE_OPEN_SOURCE_FOR_WRITE       :: 0x00000004

+ 135 - 18
core/sys/windows/types.odin

@@ -64,6 +64,7 @@ LONG_PTR :: int
 UINT_PTR :: uintptr
 ULONG :: c_ulong
 ULONGLONG :: c_ulonglong
+LONGLONG :: c_longlong
 UCHAR :: BYTE
 NTSTATUS :: c.long
 COLORREF :: DWORD
@@ -2145,6 +2146,7 @@ SECURITY_IMPERSONATION_LEVEL :: enum {
 SECURITY_INFORMATION :: DWORD
 ANYSIZE_ARRAY :: 1
 
+PLUID_AND_ATTRIBUTES :: ^LUID_AND_ATTRIBUTES
 LUID_AND_ATTRIBUTES :: struct {
 	Luid: LUID,
 	Attributes: DWORD,
@@ -2570,7 +2572,139 @@ EXCEPTION_RECORD :: struct {
 	ExceptionInformation: [EXCEPTION_MAXIMUM_PARAMETERS]LPVOID,
 }
 
-CONTEXT :: struct{} // TODO(bill)
+
+CONTEXT :: struct {
+	P1Home: DWORD64,
+	P2Home: DWORD64,
+	P3Home: DWORD64,
+	P4Home: DWORD64,
+	P5Home: DWORD64,
+	P6Home: DWORD64,
+	ContextFlags: DWORD,
+	MxCsr: DWORD,
+	SegCs: WORD,
+	SegDs: WORD,
+	SegEs: WORD,
+	SegFs: WORD,
+	SegGs: WORD,
+	SegSs: WORD,
+	EFlags: DWORD,
+	Dr0: DWORD64,
+	Dr1: DWORD64,
+	Dr2: DWORD64,
+	Dr3: DWORD64,
+	Dr6: DWORD64,
+	Dr7: DWORD64,
+	Rax: DWORD64,
+	Rcx: DWORD64,
+	Rdx: DWORD64,
+	Rbx: DWORD64,
+	Rsp: DWORD64,
+	Rbp: DWORD64,
+	Rsi: DWORD64,
+	Rdi: DWORD64,
+	R8: DWORD64,
+	R9: DWORD64,
+	R10: DWORD64,
+	R11: DWORD64,
+	R12: DWORD64,
+	R13: DWORD64,
+	R14: DWORD64,
+	R15: DWORD64,
+	Rip: DWORD64,
+	_: struct #raw_union {
+		FltSave: XMM_SAVE_AREA32,
+		Q: [16]NEON128,
+		D: [32]ULONGLONG,
+		_: struct {
+			Header: [2]M128A,
+			Legacy: [8]M128A,
+			Xmm0: M128A,
+			Xmm1: M128A,
+			Xmm2: M128A,
+			Xmm3: M128A,
+			Xmm4: M128A,
+			Xmm5: M128A,
+			Xmm6: M128A,
+			Xmm7: M128A,
+			Xmm8: M128A,
+			Xmm9: M128A,
+			Xmm10: M128A,
+			Xmm11: M128A,
+			Xmm12: M128A,
+			Xmm13: M128A,
+			Xmm14: M128A,
+			Xmm15: M128A,
+		},
+		S: [32]DWORD,
+	},
+	VectorRegister: [26]M128A,
+	VectorControl: DWORD64,
+	DebugControl: DWORD64,
+	LastBranchToRip: DWORD64,
+	LastBranchFromRip: DWORD64,
+	LastExceptionToRip: DWORD64,
+	LastExceptionFromRip: DWORD64,
+}
+
+PCONTEXT :: ^CONTEXT
+LPCONTEXT :: ^CONTEXT
+
+when size_of(uintptr) == 32 { 
+	XSAVE_FORMAT :: struct #align(16) {
+		ControlWord: WORD,
+		StatusWord: WORD,
+		TagWord: BYTE,
+		Reserved1: BYTE,
+		ErrorOpcode: WORD,
+		ErrorOffset: DWORD,
+		ErrorSelector: WORD,
+		Reserved2: WORD,
+		DataOffset: DWORD,
+		DataSelector: WORD,
+		Reserved3: WORD,
+		MxCsr: DWORD,
+		MxCsr_Mask: DWORD,
+		FloatRegisters: [8]M128A,
+		// 32-bit specific
+		XmmRegisters: [8]M128A,
+		Reserved4: [192]BYTE,
+		StackControl: [7]DWORD,
+		Cr0NpxState: DWORD,
+	}
+} else {
+	XSAVE_FORMAT :: struct #align(16) {
+		ControlWord: WORD,
+		StatusWord: WORD,
+		TagWord: BYTE,
+		Reserved1: BYTE,
+		ErrorOpcode: WORD,
+		ErrorOffset: DWORD,
+		ErrorSelector: WORD,
+		Reserved2: WORD,
+		DataOffset: DWORD,
+		DataSelector: WORD,
+		Reserved3: WORD,
+		MxCsr: DWORD,
+		MxCsr_Mask: DWORD,
+		FloatRegisters: [8]M128A,
+		// 64-bit specific
+		XmmRegisters: [16]M128A,
+		Reserved4: [96]BYTE,
+	}
+}
+
+XMM_SAVE_AREA32 :: XSAVE_FORMAT
+
+M128A :: struct {
+	Low: ULONGLONG,
+	High: LONGLONG,
+}
+
+NEON128 :: struct {
+	Low: ULONGLONG,
+	High: LONGLONG,
+}
 
 EXCEPTION_POINTERS :: struct {
 	ExceptionRecord: ^EXCEPTION_RECORD,
@@ -2733,23 +2867,6 @@ PROFILEINFOW :: struct {
 	hProfile: HANDLE,
 }
 
-// Used in LookupAccountNameW
-SID_NAME_USE :: distinct DWORD
-
-SID_TYPE :: enum SID_NAME_USE {
-	User = 1,
-	Group,
-	Domain,
-	Alias,
-	WellKnownGroup,
-	DeletedAccount,
-	Invalid,
-	Unknown,
-	Computer,
-	Label,
-	LogonSession,
-}
-
 SECURITY_MAX_SID_SIZE :: 68
 
 // https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-sid

+ 2 - 2
core/sys/windows/util.odin

@@ -202,7 +202,7 @@ get_computer_name_and_account_sid :: proc(username: string) -> (computer_name: s
 	username_w := utf8_to_utf16(username, context.temp_allocator)
 	cbsid: DWORD
 	computer_name_size: DWORD
-	pe_use := SID_TYPE.User
+	pe_use := SID_NAME_USE.SidTypeUser
 
 	res := LookupAccountNameW(
 		nil, // Look on this computer first
@@ -244,7 +244,7 @@ get_sid :: proc(username: string, sid: ^SID) -> (ok: bool) {
 	username_w := utf8_to_utf16(username, context.temp_allocator)
 	cbsid: DWORD
 	computer_name_size: DWORD
-	pe_use := SID_TYPE.User
+	pe_use := SID_NAME_USE.SidTypeUser
 
 	res := LookupAccountNameW(
 		nil, // Look on this computer first