Merge branch 'master' into syscall-fix

This commit is contained in:
gingerBill
2024-07-19 11:43:56 +01:00
committed by GitHub
653 changed files with 66513 additions and 22262 deletions
+1 -1
View File
@@ -192,7 +192,7 @@ StringCopyToOdinString :: proc(
max := StringGetMaximumSizeForEncoding(length, StringEncoding(StringBuiltInEncodings.UTF8))
buf, err := make([]byte, max, allocator)
if err != nil do return
if err != nil { return }
raw_str := runtime.Raw_String {
data = raw_data(buf),
@@ -132,7 +132,7 @@ Application_nextEventMatchingMask :: proc "c" (self: ^Application, mask: EventMa
@(objc_type=Application, objc_name="sendEvent")
Application_sendEvent :: proc "c" (self: ^Application, event: ^Event) {
msgSend(Event, self, "sendEvent:", event)
msgSend(nil, self, "sendEvent:", event)
}
@(objc_type=Application, objc_name="updateWindows")
Application_updateWindows :: proc "c" (self: ^Application) {
+4
View File
@@ -712,3 +712,7 @@ Window_setDelegate :: proc "c" (self: ^Window, delegate: ^WindowDelegate) {
Window_backingScaleFactor :: proc "c" (self: ^Window) -> Float {
return msgSend(Float, self, "backingScaleFactor")
}
@(objc_type=Window, objc_name="setWantsLayer")
Window_setWantsLayer :: proc "c" (self: ^Window, ok: BOOL) {
msgSend(nil, self, "setWantsLayer:", ok)
}
+8 -14
View File
@@ -5,9 +5,9 @@ foreign import system "system:System.framework"
// #define OS_WAIT_ON_ADDR_AVAILABILITY \
// __API_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
when ODIN_OS == .Darwin {
when ODIN_PLATFORM_SUBTARGET == .iOS && ODIN_MINIMUM_OS_VERSION > 17_04_00 {
when ODIN_PLATFORM_SUBTARGET == .iOS && ODIN_MINIMUM_OS_VERSION >= 17_04_00 {
WAIT_ON_ADDRESS_AVAILABLE :: true
} else when ODIN_MINIMUM_OS_VERSION > 14_04_00 {
} else when ODIN_MINIMUM_OS_VERSION >= 14_04_00 {
WAIT_ON_ADDRESS_AVAILABLE :: true
} else {
WAIT_ON_ADDRESS_AVAILABLE :: false
@@ -17,9 +17,6 @@ when ODIN_OS == .Darwin {
}
os_sync_wait_on_address_flag :: enum u32 {
// This flag should be used as a default flag when no other flags listed below are required.
NONE,
// This flag should be used when synchronizing among multiple processes by
// placing the @addr passed to os_sync_wait_on_address and its variants
// in a shared memory region.
@@ -31,15 +28,12 @@ os_sync_wait_on_address_flag :: enum u32 {
// This flag should not be used when synchronizing among multiple threads of
// a single process. It allows the kernel to perform performance optimizations
// as the @addr is local to the calling process.
SHARED,
SHARED = 0,
}
os_sync_wait_on_address_flags :: bit_set[os_sync_wait_on_address_flag; u32]
os_sync_wait_on_address_flags :: distinct bit_set[os_sync_wait_on_address_flag; u32]
os_sync_wake_by_address_flag :: enum u32 {
// This flag should be used as a default flag when no other flags listed below are required.
NONE,
// This flag should be used when synchronizing among multiple processes by
// placing the @addr passed to os_sync_wake_by_address_any and its variants
// in a shared memory region.
@@ -51,10 +45,10 @@ os_sync_wake_by_address_flag :: enum u32 {
// This flag should not be used when synchronizing among multiple threads of
// a single process. It allows the kernel to perform performance optimizations
// as the @addr is local the calling process.
SHARED,
SHARED = 0,
}
os_sync_wake_by_address_flags :: bit_set[os_sync_wake_by_address_flag; u32]
os_sync_wake_by_address_flags :: distinct bit_set[os_sync_wake_by_address_flag; u32]
os_clockid :: enum u32 {
MACH_ABSOLUTE_TIME = 32,
@@ -283,7 +277,7 @@ foreign system {
// and the shared memory specification
// (See os_sync_wake_by_address_flags_t).
// ENOENT : No waiter(s) found waiting on the @addr.
os_sync_wake_by_address_any :: proc(addr: rawptr, size: uint, flags: os_sync_wait_on_address_flags) -> i32 ---
os_sync_wake_by_address_any :: proc(addr: rawptr, size: uint, flags: os_sync_wake_by_address_flags) -> i32 ---
// This function is a variant of os_sync_wake_by_address_any that wakes up all waiters
// blocked in os_sync_wait_on_address or its variants.
@@ -305,5 +299,5 @@ foreign system {
// In the event of an error, returns -1 with errno set to indicate the error.
//
// This function returns same error codes as returned by os_sync_wait_on_address.
os_sync_wake_by_address_all :: proc(addr: rawptr, size: uint, flags: os_sync_wait_on_address_flags) -> i32 ---
os_sync_wake_by_address_all :: proc(addr: rawptr, size: uint, flags: os_sync_wake_by_address_flags) -> i32 ---
}
@@ -3,6 +3,10 @@ package darwin
import "core:c"
import "base:runtime"
// IMPORTANT NOTE: direct syscall usage is not allowed by Apple's review process of apps and should
// be entirely avoided in the builtin Odin collections, these are here for users if they don't
// care about the Apple review process.
// this package uses the sys prefix for the proc names to indicate that these aren't native syscalls but directly call such
sys_write_string :: proc (fd: c.int, message: string) -> bool {
return syscall_write(fd, raw_data(message), cast(u64)len(message))
File diff suppressed because it is too large Load Diff
@@ -3,6 +3,10 @@ package darwin
import "core:c"
import "base:intrinsics"
// IMPORTANT NOTE: direct syscall usage is not allowed by Apple's review process of apps and should
// be entirely avoided in the builtin Odin collections, these are here for users if they don't
// care about the Apple review process.
/* flock */
LOCK_SH :: 1 /* shared lock */
LOCK_EX :: 2 /* exclusive lock */
@@ -337,7 +341,7 @@ syscall_ftruncate :: #force_inline proc "contextless" (fd: c.int, length: off_t)
return cast(c.int)intrinsics.syscall(unix_offset_syscall(.ftruncate), uintptr(fd), uintptr(length))
}
syscall_sysctl :: #force_inline proc "contextless" (name: ^c.int, namelen: c.uint, oldp: rawptr, oldlenp: ^i64, newp: ^i8, newlen: i64) -> c.int {
syscall_sysctl :: #force_inline proc "contextless" (name: [^]c.int, namelen: c.size_t, oldp: rawptr, oldlenp: ^c.size_t, newp: rawptr, newlen: c.size_t) -> c.int {
return cast(c.int)intrinsics.syscall(unix_offset_syscall(.sysctl), uintptr(name), uintptr(namelen), uintptr(oldp), uintptr(oldlenp), uintptr(newp), uintptr(newlen))
}
@@ -390,8 +394,8 @@ syscall_adjtime :: #force_inline proc "contextless" (delta: ^timeval, old_delta:
return cast(c.int)intrinsics.syscall(unix_offset_syscall(.adjtime), uintptr(delta), uintptr(old_delta))
}
syscall_sysctlbyname :: #force_inline proc "contextless" (name: cstring, oldp: rawptr, oldlenp: ^i64, newp: rawptr, newlen: i64) -> c.int {
return cast(c.int)intrinsics.syscall(unix_offset_syscall(.sysctlbyname), transmute(uintptr)name, uintptr(oldp), uintptr(oldlenp), uintptr(newp), uintptr(newlen))
syscall_sysctlbyname :: #force_inline proc "contextless" (name: string, oldp: rawptr, oldlenp: ^c.size_t, newp: rawptr, newlen: c.size_t) -> c.int {
return cast(c.int)intrinsics.syscall(unix_offset_syscall(.sysctlbyname), uintptr(raw_data(name)), uintptr(len(name)), uintptr(oldp), uintptr(oldlenp), uintptr(newp), uintptr(newlen))
}
syscall_proc_info :: #force_inline proc "contextless" (num: c.int, pid: u32, flavor: c.int, arg: u64, buffer: rawptr, buffer_size: c.int) -> c.int {
+59 -15
View File
@@ -1,26 +1,70 @@
//+build arm32, arm64
package sysinfo
// TODO: Set up an enum with the ARM equivalent of the above.
CPU_Feature :: enum u64 {}
import "core:sys/unix"
cpu_features: Maybe(CPU_Feature)
cpu_name: Maybe(string)
_ :: unix
@(init, private)
init_cpu_features :: proc "c" () {
CPU_Feature :: enum u64 {
// Advanced SIMD & floating-point capabilities:
asimd, // General support for Advanced SIMD instructions/neon.
floatingpoint, // General support for floating-point instructions.
asimdhp, // Advanced SIMD half-precision conversion instructions.
bf16, // Storage and arithmetic instructions of the Brain Floating Point (BFloat16) data type.
fcma, // Floating-point complex number instructions.
fhm, // Floating-point half-precision multiplication instructions.
fp16, // General half-precision floating-point data processing instructions.
frint, // Floating-point to integral valued floating-point number rounding instructions.
i8mm, // Advanced SIMD int8 matrix multiplication instructions.
jscvt, // JavaScript conversion instruction.
rdm, // Advanced SIMD rounding double multiply accumulate instructions.
flagm, // Condition flag manipulation instructions.
flagm2, // Enhancements to condition flag manipulation instructions.
crc32, // CRC32 instructions.
lse, // Atomic instructions to support large systems.
lse2, // Changes to single-copy atomicity and alignment requirements for loads and stores for large systems.
lrcpc, // Load-acquire Release Consistency processor consistent (RCpc) instructions.
lrcpc2, // Load-acquire Release Consistency processor consistent (RCpc) instructions version 2.
aes,
pmull,
sha1,
sha256,
sha512,
sha3,
sb, // Barrier instruction to control speculation.
ssbs, // Instructions to control speculation of loads and stores.
}
CPU_Features :: distinct bit_set[CPU_Feature; u64]
cpu_features: Maybe(CPU_Features)
cpu_name: Maybe(string)
@(private)
_cpu_name_buf: [72]u8
cpu_name_buf: [128]byte
@(init, private)
init_cpu_name :: proc "c" () {
when ODIN_ARCH == .arm32 {
copy(_cpu_name_buf[:], "ARM")
cpu_name = string(_cpu_name_buf[:3])
} else {
copy(_cpu_name_buf[:], "ARM64")
cpu_name = string(_cpu_name_buf[:5])
init_cpu_name :: proc "contextless" () {
generic := true
when ODIN_OS == .Darwin {
if unix.sysctlbyname("machdep.cpu.brand_string", &cpu_name_buf) {
cpu_name = string(cstring(rawptr(&cpu_name_buf)))
generic = false
}
}
}
if generic {
when ODIN_ARCH == .arm64 {
copy(cpu_name_buf[:], "ARM64")
cpu_name = string(cpu_name_buf[:len("ARM64")])
} else {
copy(cpu_name_buf[:], "ARM")
cpu_name = string(cpu_name_buf[:len("ARM")])
}
}
}
+98
View File
@@ -0,0 +1,98 @@
package sysinfo
import "core:sys/unix"
@(init, private)
init_cpu_features :: proc "contextless" () {
@(static) features: CPU_Features
defer cpu_features = features
try_set :: proc "contextless" (name: cstring, feature: CPU_Feature) -> (ok: bool) {
support: b32
if ok = unix.sysctlbyname(name, &support); ok && support {
features += { feature }
}
return
}
// Docs from Apple: https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics
// Features from there that do not have (or I didn't find) an equivalent on Linux are commented out below.
// Advanced SIMD & floating-point capabilities:
{
if !try_set("hw.optional.AdvSIMD", .asimd) {
try_set("hw.optional.neon", .asimd)
}
try_set("hw.optional.floatingpoint", .floatingpoint)
if !try_set("hw.optional.AdvSIMD_HPFPCvt", .asimdhp) {
try_set("hw.optional.neon_hpfp", .asimdhp)
}
try_set("hw.optional.arm.FEAT_BF16", .bf16)
// try_set("hw.optional.arm.FEAT_DotProd", .dotprod)
if !try_set("hw.optional.arm.FEAT_FCMA", .fcma) {
try_set("hw.optional.armv8_3_compnum", .fcma)
}
if !try_set("hw.optional.arm.FEAT_FHM", .fhm) {
try_set("hw.optional.armv8_2_fhm", .fhm)
}
if !try_set("hw.optional.arm.FEAT_FP16", .fp16) {
try_set("hw.optional.neon_fp16", .fp16)
}
try_set("hw.optional.arm.FEAT_FRINTTS", .frint)
try_set("hw.optional.arm.FEAT_I8MM", .i8mm)
try_set("hw.optional.arm.FEAT_JSCVT", .jscvt)
try_set("hw.optional.arm.FEAT_RDM", .rdm)
}
// Integer capabilities:
{
try_set("hw.optional.arm.FEAT_FlagM", .flagm)
try_set("hw.optional.arm.FEAT_FlagM2", .flagm2)
try_set("hw.optional.armv8_crc32", .crc32)
}
// Atomic and memory ordering instruction capabilities:
{
try_set("hw.optional.arm.FEAT_LRCPC", .lrcpc)
try_set("hw.optional.arm.FEAT_LRCPC2", .lrcpc2)
if !try_set("hw.optional.arm.FEAT_LSE", .lse) {
try_set("hw.optional.armv8_1_atomics", .lse)
}
// try_set("hw.optional.arm.FEAT_LSE2", .lse2)
}
// Encryption capabilities:
{
try_set("hw.optional.arm.FEAT_AES", .aes)
try_set("hw.optional.arm.FEAT_PMULL", .pmull)
try_set("hw.optional.arm.FEAT_SHA1", .sha1)
try_set("hw.optional.arm.FEAT_SHA256", .sha256)
if !try_set("hw.optional.arm.FEAT_SHA512", .sha512) {
try_set("hw.optional.armv8_2_sha512", .sha512)
}
if !try_set("hw.optional.arm.FEAT_SHA3", .sha3) {
try_set("hw.optional.armv8_2_sha3", .sha3)
}
}
// General capabilities:
{
// try_set("hw.optional.arm.FEAT_BTI", .bti)
// try_set("hw.optional.arm.FEAT_DPB", .dpb)
// try_set("hw.optional.arm.FEAT_DPB2", .dpb2)
// try_set("hw.optional.arm.FEAT_ECV", .ecv)
try_set("hw.optional.arm.FEAT_SB", .sb)
try_set("hw.optional.arm.FEAT_SSBS", .ssbs)
}
}
+4 -4
View File
@@ -67,8 +67,8 @@ init_cpu_features :: proc "c" () {
try_set(&set, .os_xsave, 27, ecx1)
try_set(&set, .rdrand, 30, ecx1)
when ODIN_OS == .FreeBSD || ODIN_OS == .OpenBSD {
// xgetbv is an illegal instruction under FreeBSD 13 & OpenBSD 7.1
when ODIN_OS == .FreeBSD || ODIN_OS == .OpenBSD || ODIN_OS == .NetBSD {
// xgetbv is an illegal instruction under FreeBSD 13, OpenBSD 7.1 and NetBSD 10
// return before probing further
cpu_features = set
return
@@ -117,7 +117,7 @@ init_cpu_name :: proc "c" () {
return
}
_buf := transmute(^[0x12]u32)&_cpu_name_buf
_buf := (^[0x12]u32)(&_cpu_name_buf)
_buf[ 0], _buf[ 1], _buf[ 2], _buf[ 3] = cpuid(0x8000_0002, 0)
_buf[ 4], _buf[ 5], _buf[ 6], _buf[ 7] = cpuid(0x8000_0003, 0)
_buf[ 8], _buf[ 9], _buf[10], _buf[11] = cpuid(0x8000_0004, 0)
@@ -133,4 +133,4 @@ init_cpu_name :: proc "c" () {
brand = brand[:len(brand) - 1]
}
cpu_name = brand
}
}
+65
View File
@@ -0,0 +1,65 @@
//+build arm32, arm64
//+build linux
package sysinfo
import "core:sys/linux"
import "core:strings"
@(init, private)
init_cpu_features :: proc() {
fd, err := linux.open("/proc/cpuinfo", {})
if err != .NONE { return }
defer linux.close(fd)
// This is probably enough right?
buf: [4096]byte
n, rerr := linux.read(fd, buf[:])
if rerr != .NONE || n == 0 { return }
features: CPU_Features
defer cpu_features = features
str := string(buf[:n])
for line in strings.split_lines_iterator(&str) {
key, _, value := strings.partition(line, ":")
key = strings.trim_space(key)
value = strings.trim_space(value)
if key != "Features" { continue }
for feature in strings.split_by_byte_iterator(&value, ' ') {
switch feature {
case "asimd", "neon": features += { .asimd }
case "fp": features += { .floatingpoint }
case "asimdhp": features += { .asimdhp }
case "asimdbf16": features += { .bf16 }
case "fcma": features += { .fcma }
case "asimdfhm": features += { .fhm }
case "fphp", "half": features += { .fp16 }
case "frint": features += { .frint }
case "i8mm": features += { .i8mm }
case "jscvt": features += { .jscvt }
case "asimdrdm": features += { .rdm }
case "flagm": features += { .flagm }
case "flagm2": features += { .flagm2 }
case "crc32": features += { .crc32 }
case "atomics": features += { .lse }
case "lrcpc": features += { .lrcpc }
case "ilrcpc": features += { .lrcpc2 }
case "aes": features += { .aes }
case "pmull": features += { .pmull }
case "sha1": features += { .sha1 }
case "sha2": features += { .sha256 }
case "sha3": features += { .sha3 }
case "sha512": features += { .sha512 }
case "sb": features += { .sb }
case "ssbs": features += { .ssbs }
}
}
break
}
}
+15 -12
View File
@@ -19,18 +19,21 @@ Example:
import si "core:sys/info"
main :: proc() {
fmt.printf("Odin: %v\n", ODIN_VERSION)
fmt.printf("OS: %v\n", si.os_version.as_string)
fmt.printf("OS: %#v\n", si.os_version)
fmt.printf("CPU: %v\n", si.cpu_name)
fmt.printf("RAM: %v MiB\n", si.ram.total_ram / 1024 / 1024)
fmt.printfln("Odin: %v", ODIN_VERSION)
fmt.printfln("OS: %v", si.os_version.as_string)
fmt.printfln("OS: %#v", si.os_version)
fmt.printfln("CPU: %v", si.cpu_name)
fmt.printfln("RAM: %#.1M", si.ram.total_ram)
// fmt.printfln("Features: %v", si.cpu_features)
// fmt.printfln("MacOS version: %v", si.macos_version)
fmt.println()
for gpu, i in si.gpus {
fmt.printf("GPU #%v:\n", i)
fmt.printf("\tVendor: %v\n", gpu.vendor_name)
fmt.printf("\tModel: %v\n", gpu.model_name)
fmt.printf("\tVRAM: %v MiB\n", gpu.total_ram / 1024 / 1024)
fmt.printfln("GPU #%v:", i)
fmt.printfln("\tVendor: %v", gpu.vendor_name)
fmt.printfln("\tModel: %v", gpu.model_name)
fmt.printfln("\tVRAM: %#.1M", gpu.total_ram)
}
}
@@ -51,11 +54,11 @@ Example:
as_string = "Windows 10 Professional (version: 20H2), build: 19042.1466",
}
CPU: AMD Ryzen 7 1800X Eight-Core Processor
RAM: 65469 MiB
RAM: 64.0 GiB
GPU #0:
Vendor: Advanced Micro Devices, Inc.
Model: Radeon RX Vega
VRAM: 8176 MiB
VRAM: 8.0 GiB
- Example macOS output:
@@ -73,6 +76,6 @@ Example:
as_string = "macOS Monterey 12.4 (build 21F79, kernel 21.5.0)",
}
CPU: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz
RAM: 8192 MiB
RAM: 8.0 GiB
*/
package sysinfo
@@ -1,4 +1,4 @@
// +build openbsd
//+build openbsd, netbsd
package sysinfo
import sys "core:sys/unix"
@@ -11,12 +11,16 @@ version_string_buf: [1024]u8
@(init, private)
init_os_version :: proc () {
os_version.platform = .OpenBSD
when ODIN_OS == .NetBSD {
os_version.platform = .NetBSD
} else {
os_version.platform = .OpenBSD
}
kernel_version_buf: [1024]u8
b := strings.builder_from_bytes(version_string_buf[:])
// Retrieve kernel info using `sysctl`, e.g. OpenBSD
// Retrieve kernel info using `sysctl`, e.g. OpenBSD and NetBSD
mib := []i32{sys.CTL_KERN, sys.KERN_OSTYPE}
if !sys.sysctl(mib, &kernel_version_buf) {
return
@@ -61,7 +65,7 @@ init_os_version :: proc () {
os_version.as_string = strings.to_string(b)
}
@(init)
@(init, private)
init_ram :: proc() {
// Retrieve RAM info using `sysctl`
mib := []i32{sys.CTL_HW, sys.HW_PHYSMEM64}
@@ -69,4 +73,4 @@ init_ram :: proc() {
if sys.sysctl(mib, &mem_size) {
ram.total_ram = int(mem_size)
}
}
}
+4 -2
View File
@@ -1,4 +1,3 @@
// +build darwin
package sysinfo
import sys "core:sys/unix"
@@ -76,6 +75,8 @@ init_os_version :: proc () {
os_version.minor = rel.darwin.y
os_version.patch = rel.darwin.z
macos_version = transmute(Version)rel.release.version
strings.write_string(&b, rel.os_name)
if match == .Exact || match == .Nearest {
strings.write_rune(&b, ' ')
@@ -113,7 +114,7 @@ init_os_version :: proc () {
os_version.as_string = strings.to_string(b)
}
@(init)
@(init, private)
init_ram :: proc() {
// Retrieve RAM info using `sysctl`
@@ -526,6 +527,7 @@ macos_release_map: map[string]Darwin_To_Release = {
"23D60" = {{23, 3, 0}, "macOS", {"Sonoma", {14, 3, 1}}},
"23E214" = {{23, 4, 0}, "macOS", {"Sonoma", {14, 4, 0}}},
"23E224" = {{23, 4, 0}, "macOS", {"Sonoma", {14, 4, 1}}},
"23F79" = {{23, 5, 0}, "macOS", {"Sonoma", {14, 5, 0}}},
}
@(private)
+2 -3
View File
@@ -1,4 +1,3 @@
// +build freebsd
package sysinfo
import sys "core:sys/unix"
@@ -13,7 +12,7 @@ version_string_buf: [1024]u8
init_os_version :: proc () {
os_version.platform = .FreeBSD
kernel_version_buf: [129]u8
kernel_version_buf: [1024]u8
b := strings.builder_from_bytes(version_string_buf[:])
// Retrieve kernel info using `sysctl`, e.g. FreeBSD 13.1-RELEASE-p2 GENERIC
@@ -68,7 +67,7 @@ init_os_version :: proc () {
}
}
@(init)
@(init, private)
init_ram :: proc() {
// Retrieve RAM info using `sysctl`
mib := []i32{sys.CTL_HW, sys.HW_PHYSMEM}
+58 -47
View File
@@ -1,11 +1,9 @@
// +build linux
package sysinfo
import "base:intrinsics"
import "base:runtime"
import "core:strings"
import "core:strconv"
import "core:strconv"
import "core:strings"
import "core:sys/linux"
@(private)
@@ -14,32 +12,37 @@ version_string_buf: [1024]u8
@(init, private)
init_os_version :: proc () {
os_version.platform = .Linux
// Try to parse `/etc/os-release` for `PRETTY_NAME="Ubuntu 20.04.3 LTS`
fd, errno := linux.open("/etc/os-release", {.RDONLY}, {})
assert(errno == .NONE, "Failed to read /etc/os-release")
defer {
cerrno := linux.close(fd)
assert(cerrno == .NONE, "Failed to close the file descriptor")
}
os_release_buf: [2048]u8
n, read_errno := linux.read(fd, os_release_buf[:])
assert(read_errno == .NONE, "Failed to read data from /etc/os-release")
release := string(os_release_buf[:n])
// Search the line in the file until we find "PRETTY_NAME="
NEEDLE :: "PRETTY_NAME=\""
pretty_start := strings.index(release, NEEDLE)
b := strings.builder_from_bytes(version_string_buf[:])
if pretty_start > 0 {
for r, i in release[pretty_start + len(NEEDLE):] {
if r == '"' {
strings.write_string(&b, release[pretty_start + len(NEEDLE):][:i])
break
} else if r == '\r' || r == '\n' {
strings.write_string(&b, "Unknown Linux Distro")
break
// Try to parse `/etc/os-release` for `PRETTY_NAME="Ubuntu 20.04.3 LTS`
{
fd, errno := linux.open("/etc/os-release", {})
assert(errno == .NONE, "Failed to read /etc/os-release")
defer {
cerrno := linux.close(fd)
assert(cerrno == .NONE, "Failed to close the file descriptor")
}
os_release_buf: [2048]u8
n, read_errno := linux.read(fd, os_release_buf[:])
assert(read_errno == .NONE, "Failed to read data from /etc/os-release")
release := string(os_release_buf[:n])
// Search the line in the file until we find "PRETTY_NAME="
NEEDLE :: "PRETTY_NAME=\""
_, _, post := strings.partition(release, NEEDLE)
if len(post) > 0 {
end := strings.index_any(post, "\"\n")
if end > -1 && post[end] == '"' {
strings.write_string(&b, post[:end])
}
}
if strings.builder_len(b) == 0 {
strings.write_string(&b, "Unknown Linux Distro")
}
}
// Grab kernel info using `uname()` syscall, https://linux.die.net/man/2/uname
uts: linux.UTS_Name
uname_errno := linux.uname(&uts)
@@ -48,31 +51,39 @@ init_os_version :: proc () {
strings.write_string(&b, ", ")
strings.write_string(&b, string(cstring(&uts.sysname[0])))
strings.write_rune(&b, ' ')
l := strings.builder_len(b)
release_i := strings.builder_len(b)
strings.write_string(&b, string(cstring(&uts.release[0])))
// Parse kernel version, as substrings of the version info in `version_string_buf`
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
version_bits := strings.split_n(strings.to_string(b)[l:], "-", 2, context.temp_allocator)
if len(version_bits) > 1 {
os_version.version = version_bits[1]
}
// Parse major, minor, patch from release info
triplet := strings.split(version_bits[0], ".", context.temp_allocator)
if len(triplet) == 3 {
major, major_ok := strconv.parse_int(triplet[0])
minor, minor_ok := strconv.parse_int(triplet[1])
patch, patch_ok := strconv.parse_int(triplet[2])
if major_ok && minor_ok && patch_ok {
os_version.major = major
os_version.minor = minor
os_version.patch = patch
release_str := string(b.buf[release_i:])
os_version.as_string = strings.to_string(b)
// Parse the Linux version out of the release string
{
version_num, _, version_suffix := strings.partition(release_str, "-")
os_version.version = version_suffix
i: int
for part in strings.split_iterator(&version_num, ".") {
defer i += 1
dst: ^int
switch i {
case 0: dst = &os_version.major
case 1: dst = &os_version.minor
case 2: dst = &os_version.patch
case: break
}
num, ok := strconv.parse_int(part)
if !ok { break }
dst^ = num
}
}
// Finish the string
os_version.as_string = strings.to_string(b)
}
@(init)
@(init, private)
init_ram :: proc() {
// Retrieve RAM info using `sysinfo`
sys_info: linux.Sys_Info
@@ -84,4 +95,4 @@ init_ram :: proc() {
total_swap = int(sys_info.totalswap) * int(sys_info.mem_unit),
free_swap = int(sys_info.freeswap) * int(sys_info.mem_unit),
}
}
}
+1 -2
View File
@@ -1,4 +1,3 @@
// +build windows
package sysinfo
import sys "core:sys/windows"
@@ -259,7 +258,7 @@ init_os_version :: proc () {
}
}
@(init)
@(init, private)
init_ram :: proc() {
state: sys.MEMORYSTATUSEX
+9 -4
View File
@@ -8,6 +8,9 @@ os_version: OS_Version
ram: RAM
gpus: []GPU
// Only on MacOS, contains the actual MacOS version, while the `os_version` contains the kernel version.
macos_version: Version
OS_Version_Platform :: enum {
Unknown,
Windows,
@@ -19,12 +22,14 @@ OS_Version_Platform :: enum {
NetBSD,
}
Version :: struct {
major, minor, patch: int,
}
OS_Version :: struct {
platform: OS_Version_Platform,
major: int,
minor: int,
patch: int,
using _: Version,
build: [2]int,
version: string,
@@ -42,4 +47,4 @@ GPU :: struct {
vendor_name: string,
model_name: string,
total_ram: int,
}
}
+91 -32
View File
@@ -48,6 +48,7 @@ Errno :: enum i32 {
ENOSYS = 38,
ENOTEMPTY = 39,
ELOOP = 40,
EUNKNOWN_41 = 41,
ENOMSG = 42,
EIDRM = 43,
ECHRNG = 44,
@@ -64,6 +65,7 @@ Errno :: enum i32 {
ENOANO = 55,
EBADRQC = 56,
EBADSLT = 57,
EUNKNOWN_58 = 58,
EBFONT = 59,
ENOSTR = 60,
ENODATA = 61,
@@ -145,26 +147,70 @@ Errno :: enum i32 {
}
/*
Bits for Open_Flags
Bits for Open_Flags.
RDONLY flag is not present, because it has the value of 0, i.e. it is the
default, unless WRONLY or RDWR is specified.
*/
Open_Flags_Bits :: enum {
RDONLY = 0,
WRONLY = 1,
RDWR = 2,
CREAT = 6,
EXCL = 7,
NOCTTY = 8,
TRUNC = 9,
APPEND = 10,
NONBLOCK = 11,
DSYNC = 12,
ASYNC = 13,
DIRECT = 14,
DIRECTORY = 16,
NOFOLLOW = 17,
NOATIME = 18,
CLOEXEC = 19,
PATH = 21,
when ODIN_ARCH != .arm64 && ODIN_ARCH != .arm32 {
Open_Flags_Bits :: enum {
WRONLY = 0,
RDWR = 1,
CREAT = 6,
EXCL = 7,
NOCTTY = 8,
TRUNC = 9,
APPEND = 10,
NONBLOCK = 11,
DSYNC = 12,
ASYNC = 13,
DIRECT = 14,
LARGEFILE = 15,
DIRECTORY = 16,
NOFOLLOW = 17,
NOATIME = 18,
CLOEXEC = 19,
PATH = 21,
}
// https://github.com/torvalds/linux/blob/7367539ad4b0f8f9b396baf02110962333719a48/include/uapi/asm-generic/fcntl.h#L19
#assert(1 << uint(Open_Flags_Bits.WRONLY) == 0o0000000_1)
#assert(1 << uint(Open_Flags_Bits.RDWR) == 0o0000000_2)
#assert(1 << uint(Open_Flags_Bits.CREAT) == 0o00000_100)
#assert(1 << uint(Open_Flags_Bits.EXCL) == 0o00000_200)
#assert(1 << uint(Open_Flags_Bits.NOCTTY) == 0o00000_400)
#assert(1 << uint(Open_Flags_Bits.TRUNC) == 0o0000_1000)
#assert(1 << uint(Open_Flags_Bits.APPEND) == 0o0000_2000)
#assert(1 << uint(Open_Flags_Bits.NONBLOCK) == 0o0000_4000)
#assert(1 << uint(Open_Flags_Bits.DSYNC) == 0o000_10000)
#assert(1 << uint(Open_Flags_Bits.ASYNC) == 0o000_20000)
#assert(1 << uint(Open_Flags_Bits.DIRECT) == 0o000_40000)
#assert(1 << uint(Open_Flags_Bits.LARGEFILE) == 0o00_100000)
#assert(1 << uint(Open_Flags_Bits.DIRECTORY) == 0o00_200000)
#assert(1 << uint(Open_Flags_Bits.NOFOLLOW) == 0o00_400000)
#assert(1 << uint(Open_Flags_Bits.NOATIME) == 0o0_1000000)
#assert(1 << uint(Open_Flags_Bits.CLOEXEC) == 0o0_2000000)
#assert(1 << uint(Open_Flags_Bits.PATH) == 0o_10000000)
} else {
Open_Flags_Bits :: enum {
WRONLY = 0,
RDWR = 1,
CREAT = 6,
EXCL = 7,
NOCTTY = 8,
TRUNC = 9,
APPEND = 10,
NONBLOCK = 11,
DSYNC = 12,
ASYNC = 13,
DIRECTORY = 14,
NOFOLLOW = 15,
DIRECT = 16,
LARGEFILE = 17,
NOATIME = 18,
CLOEXEC = 19,
PATH = 21,
}
}
/*
@@ -198,7 +244,7 @@ Mode_Bits :: enum {
ISVTX = 9, // 0o0001000
ISGID = 10, // 0o0002000
ISUID = 11, // 0o0004000
IFFIFO = 12, // 0o0010000
IFIFO = 12, // 0o0010000
IFCHR = 13, // 0o0020000
IFDIR = 14, // 0o0040000
IFREG = 15, // 0o0100000
@@ -845,7 +891,7 @@ Wait_Option :: enum {
WSTOPPED = 1,
WEXITED = 2,
WCONTINUED = 3,
WNOWAIT = 24,
WNOWAIT = 24,
// // For processes created using clone
__WNOTHREAD = 29,
__WALL = 30,
@@ -924,9 +970,22 @@ Sig_Stack_Flag :: enum i32 {
AUTODISARM = 31,
}
Sig_Action_Flag :: enum u32 {
NOCLDSTOP = 0,
NOCLDWAIT = 1,
SIGINFO = 2,
UNSUPPORTED = 10,
EXPOSE_TAGBITS = 11,
RESTORER = 26,
ONSTACK = 27,
RESTART = 28,
NODEFER = 30,
RESETHAND = 31,
}
/*
Type of socket to create
- For TCP you want to use SOCK_STREAM
- For TCP you want to use SOCK_STREAM
- For UDP you want to use SOCK_DGRAM
Also see `Protocol`
*/
@@ -1405,16 +1464,16 @@ Futex_Flags_Bits :: enum {
Kind of operation on futex, see FUTEX_WAKE_OP
*/
Futex_Arg_Op :: enum {
SET = 0, /* uaddr2 = oparg; */
ADD = 1, /* uaddr2 += oparg; */
OR = 2, /* uaddr2 |= oparg; */
ANDN = 3, /* uaddr2 &= ~oparg; */
XOR = 4, /* uaddr2 ^= oparg; */
PO2_SET = 0, /* uaddr2 = 1<<oparg; */
PO2_ADD = 1, /* uaddr2 += 1<<oparg; */
PO2_OR = 2, /* uaddr2 |= 1<<oparg; */
PO2_ANDN = 3, /* uaddr2 &= ~(1<<oparg); */
PO2_XOR = 4, /* uaddr2 ^= 1<<oparg; */
SET = 0, /* uaddr2 = oparg */
ADD = 1, /* uaddr2 += oparg */
OR = 2, /* uaddr2 |= oparg */
ANDN = 3, /* uaddr2 &= ~oparg */
XOR = 4, /* uaddr2 ^= oparg */
PO2_SET = 0, /* uaddr2 = 1<<oparg */
PO2_ADD = 1, /* uaddr2 += 1<<oparg */
PO2_OR = 2, /* uaddr2 |= 1<<oparg */
PO2_ANDN = 3, /* uaddr2 &~= 1<<oparg */
PO2_XOR = 4, /* uaddr2 ^= 1<<oparg */
}
/*
+3 -3
View File
@@ -39,11 +39,11 @@ PRIO_MIN :: -20
SIGRTMIN :: Signal(32)
SIGRTMAX :: Signal(64)
S_IFMT :: Mode{.IFREG, .IFDIR, .IFCHR, .IFFIFO}
S_IFMT :: Mode{.IFREG, .IFDIR, .IFCHR, .IFIFO}
S_IFSOCK :: Mode{.IFREG, .IFDIR}
S_IFLNK :: Mode{.IFREG, .IFCHR}
S_IFBLK :: Mode{.IFDIR, .IFCHR}
S_IFFIFO :: Mode{.IFFIFO}
S_IFIFO :: Mode{.IFIFO}
S_IFCHR :: Mode{.IFCHR}
S_IFDIR :: Mode{.IFDIR}
S_IFREG :: Mode{.IFREG}
@@ -51,7 +51,7 @@ S_IFREG :: Mode{.IFREG}
/*
Checks the Mode bits to see if the file is a named pipe (FIFO).
*/
S_ISFIFO :: #force_inline proc "contextless" (m: Mode) -> bool {return (S_IFFIFO == (m & S_IFMT))}
S_ISFIFO :: #force_inline proc "contextless" (m: Mode) -> bool {return (S_IFIFO == (m & S_IFMT))}
/*
Check the Mode bits to see if the file is a character device.
+15 -15
View File
@@ -26,7 +26,7 @@ where
@(private)
syscall2 :: #force_inline proc "contextless" (nr: uintptr,p1: $T1, p2: $T2) -> int
where
size_of(p1) <= size_of(uintptr) &&
size_of(p1) <= size_of(uintptr),
size_of(p2) <= size_of(uintptr)
{
return cast(int) intrinsics.syscall(nr,
@@ -36,8 +36,8 @@ where
@(private)
syscall3 :: #force_inline proc "contextless" (nr: uintptr, p1: $T1, p2: $T2, p3: $T3) -> int
where
size_of(p1) <= size_of(uintptr) &&
size_of(p2) <= size_of(uintptr) &&
size_of(p1) <= size_of(uintptr),
size_of(p2) <= size_of(uintptr),
size_of(p3) <= size_of(uintptr)
{
return cast(int) intrinsics.syscall(nr,
@@ -49,9 +49,9 @@ where
@(private)
syscall4 :: #force_inline proc "contextless" (nr: uintptr, p1: $T1, p2: $T2, p3: $T3, p4: $T4) -> int
where
size_of(p1) <= size_of(uintptr) &&
size_of(p2) <= size_of(uintptr) &&
size_of(p3) <= size_of(uintptr) &&
size_of(p1) <= size_of(uintptr),
size_of(p2) <= size_of(uintptr),
size_of(p3) <= size_of(uintptr),
size_of(p4) <= size_of(uintptr)
{
return cast(int) intrinsics.syscall(nr,
@@ -64,10 +64,10 @@ where
@(private)
syscall5 :: #force_inline proc "contextless" (nr: uintptr, p1: $T1, p2: $T2, p3: $T3, p4: $T4, p5: $T5) -> int
where
size_of(p1) <= size_of(uintptr) &&
size_of(p2) <= size_of(uintptr) &&
size_of(p3) <= size_of(uintptr) &&
size_of(p4) <= size_of(uintptr) &&
size_of(p1) <= size_of(uintptr),
size_of(p2) <= size_of(uintptr),
size_of(p3) <= size_of(uintptr),
size_of(p4) <= size_of(uintptr),
size_of(p5) <= size_of(uintptr)
{
return cast(int) intrinsics.syscall(nr,
@@ -81,11 +81,11 @@ where
@(private)
syscall6 :: #force_inline proc "contextless" (nr: uintptr, p1: $T1, p2: $T2, p3: $T3, p4: $T4, p5: $T5, p6: $T6) -> int
where
size_of(p1) <= size_of(uintptr) &&
size_of(p2) <= size_of(uintptr) &&
size_of(p3) <= size_of(uintptr) &&
size_of(p4) <= size_of(uintptr) &&
size_of(p5) <= size_of(uintptr) &&
size_of(p1) <= size_of(uintptr),
size_of(p2) <= size_of(uintptr),
size_of(p3) <= size_of(uintptr),
size_of(p4) <= size_of(uintptr),
size_of(p5) <= size_of(uintptr),
size_of(p6) <= size_of(uintptr)
{
return cast(int) intrinsics.syscall(nr,
+44 -29
View File
@@ -69,7 +69,7 @@ close :: proc "contextless" (fd: Fd) -> (Errno) {
stat :: proc "contextless" (filename: cstring, stat: ^Stat) -> (Errno) {
when size_of(int) == 8 {
when ODIN_ARCH == .arm64 {
ret := syscall(SYS_fstatat, AT_FDCWD, cast(rawptr) filename, stat)
ret := syscall(SYS_fstatat, AT_FDCWD, cast(rawptr) filename, stat, 0)
return Errno(-ret)
} else {
ret := syscall(SYS_stat, cast(rawptr) filename, stat)
@@ -200,10 +200,25 @@ brk :: proc "contextless" (addr: uintptr) -> (Errno) {
return Errno(-ret)
}
/*
Returns from signal handlers on some archs.
*/
rt_sigreturn :: proc "c" () -> ! {
intrinsics.syscall(uintptr(SYS_rt_sigreturn))
unreachable()
}
/*
Alter an action taken by a process.
*/
rt_sigaction :: proc "contextless" (sig: Signal, sigaction: ^Sig_Action, old_sigaction: ^Sig_Action) -> Errno {
rt_sigaction :: proc "contextless" (sig: Signal, sigaction: ^Sig_Action($T), old_sigaction: ^Sig_Action) -> Errno {
// NOTE(jason): It appears that the restorer is required for i386 and amd64
when ODIN_ARCH == .i386 || ODIN_ARCH == .amd64 {
sigaction.flags += {.RESTORER}
}
if sigaction != nil && sigaction.restorer == nil && .RESTORER in sigaction.flags {
sigaction.restorer = rt_sigreturn
}
ret := syscall(SYS_rt_sigaction, sig, sigaction, old_sigaction, size_of(Sig_Set))
return Errno(-ret)
}
@@ -487,6 +502,7 @@ connect :: proc "contextless" (sock: Fd, addr: ^$T) -> (Errno)
where
T == Sock_Addr_In ||
T == Sock_Addr_In6 ||
T == Sock_Addr_Un ||
T == Sock_Addr_Any
{
ret := syscall(SYS_connect, sock, addr, size_of(T))
@@ -502,6 +518,7 @@ accept :: proc "contextless" (sock: Fd, addr: ^$T, sockflags: Socket_FD_Flags =
where
T == Sock_Addr_In ||
T == Sock_Addr_In6 ||
T == Sock_Addr_Un ||
T == Sock_Addr_Any
{
addr_len: i32 = size_of(T)
@@ -514,6 +531,7 @@ recvfrom :: proc "contextless" (sock: Fd, buf: []u8, flags: Socket_Msg, addr: ^$
where
T == Sock_Addr_In ||
T == Sock_Addr_In6 ||
T == Sock_Addr_Un ||
T == Sock_Addr_Any
{
addr_len: i32 = size_of(T)
@@ -531,6 +549,7 @@ sendto :: proc "contextless" (sock: Fd, buf: []u8, flags: Socket_Msg, addr: ^$T)
where
T == Sock_Addr_In ||
T == Sock_Addr_In6 ||
T == Sock_Addr_Un ||
T == Sock_Addr_Any
{
ret := syscall(SYS_sendto, sock, raw_data(buf), len(buf), transmute(i32) flags, addr, size_of(T))
@@ -590,6 +609,7 @@ bind :: proc "contextless" (sock: Fd, addr: ^$T) -> (Errno)
where
T == Sock_Addr_In ||
T == Sock_Addr_In6 ||
T == Sock_Addr_Un ||
T == Sock_Addr_Any
{
ret := syscall(SYS_bind, sock, addr, size_of(T))
@@ -1114,7 +1134,7 @@ ftruncate :: proc "contextless" (fd: Fd, length: i64) -> (Errno) {
ret := syscall(SYS_ftruncate64, fd, compat64_arg_pair(length))
return Errno(-ret)
} else {
ret := syscall(SYS_truncate, fd, compat64_arg_pair(length))
ret := syscall(SYS_ftruncate, fd, compat64_arg_pair(length))
return Errno(-ret)
}
}
@@ -1222,7 +1242,7 @@ creat :: proc "contextless" (name: cstring, mode: Mode) -> (Fd, Errno) {
*/
link :: proc "contextless" (target: cstring, linkpath: cstring) -> (Errno) {
when ODIN_ARCH == .arm64 {
ret := syscall(SYS_linkat, AT_FDCWD, cast(rawptr) target, AT_FDCWD, cast(rawptr) linkpath)
ret := syscall(SYS_linkat, AT_FDCWD, cast(rawptr) target, AT_FDCWD, cast(rawptr) linkpath, 0)
return Errno(-ret)
} else {
ret := syscall(SYS_link, cast(rawptr) target, cast(rawptr) linkpath)
@@ -1252,7 +1272,7 @@ unlink :: proc "contextless" (name: cstring) -> (Errno) {
*/
symlink :: proc "contextless" (target: cstring, linkpath: cstring) -> (Errno) {
when ODIN_ARCH == .arm64 {
ret := syscall(SYS_symlinkat, AT_FDCWD, cast(rawptr) target, cast(rawptr) linkpath)
ret := syscall(SYS_symlinkat, cast(rawptr) target, AT_FDCWD, cast(rawptr) linkpath)
return Errno(-ret)
} else {
ret := syscall(SYS_symlink, cast(rawptr) target, cast(rawptr) linkpath)
@@ -1282,7 +1302,7 @@ readlink :: proc "contextless" (name: cstring, buf: []u8) -> (int, Errno) {
*/
chmod :: proc "contextless" (name: cstring, mode: Mode) -> (Errno) {
when ODIN_ARCH == .arm64 {
ret := syscall(SYS_fchmodat, cast(rawptr) name, transmute(u32) mode, 0)
ret := syscall(SYS_fchmodat, AT_FDCWD, cast(rawptr) name, transmute(u32) mode)
return Errno(-ret)
} else {
ret := syscall(SYS_chmod, cast(rawptr) name, transmute(u32) mode)
@@ -1709,9 +1729,9 @@ getpgrp :: proc "contextless" () -> (Pid, Errno) {
Create a session and set the process group ID.
Available since Linux 2.0.
*/
setsid :: proc "contextless" () -> (Errno) {
setsid :: proc "contextless" () -> (Pid, Errno) {
ret := syscall(SYS_setsid)
return Errno(-ret)
return errno_unwrap(ret, Pid)
}
/*
@@ -2217,8 +2237,7 @@ futex_wake :: proc "contextless" (futex: ^Futex, op: Futex_Wake_Type, flags: Fut
Returns the total number of waiters that have been woken up plus the number of waiters requeued.
*/
futex_cmp_requeue :: proc "contextless" (futex: ^Futex, op: Futex_Cmp_Requeue_Type, flags: Futex_Flags, requeue_threshold: u32,
requeue_max: i32, requeue_futex: ^Futex, val: i32) -> (int, Errno)
{
requeue_max: i32, requeue_futex: ^Futex, val: i32) -> (int, Errno) {
futex_flags := cast(u32) op + transmute(u32) flags
ret := syscall(SYS_futex, futex, futex_flags, requeue_threshold, requeue_max, requeue_futex, val)
return errno_unwrap(ret, int)
@@ -2229,8 +2248,7 @@ futex_cmp_requeue :: proc "contextless" (futex: ^Futex, op: Futex_Cmp_Requeue_Ty
Returns the total number of waiters that have been woken up.
*/
futex_requeue :: proc "contextless" (futex: ^Futex, op: Futex_Requeue_Type, flags: Futex_Flags, requeue_threshold: u32,
requeue_max: i32, requeue_futex: ^Futex) -> (int, Errno)
{
requeue_max: i32, requeue_futex: ^Futex) -> (int, Errno) {
futex_flags := cast(u32) op + transmute(u32) flags
ret := syscall(SYS_futex, futex, futex_flags, requeue_threshold, requeue_max, requeue_futex)
return errno_unwrap(ret, int)
@@ -2241,8 +2259,7 @@ futex_requeue :: proc "contextless" (futex: ^Futex, op: Futex_Requeue_Type, flag
purpose is to allow implementing conditional values sync primitive, it seems like.
*/
futex_wake_op :: proc "contextless" (futex: ^Futex, op: Futex_Wake_Op_Type, flags: Futex_Flags, wakeup: i32,
dst_wakeup, dst: ^Futex, futex_op: u32) -> (int, Errno)
{
dst_wakeup, dst: ^Futex, futex_op: u32) -> (int, Errno) {
futex_flags := cast(u32) op + transmute(u32) flags
ret := syscall(SYS_futex, futex, futex_flags, wakeup, dst_wakeup, dst, futex_op)
return errno_unwrap(ret, int)
@@ -2252,8 +2269,7 @@ futex_wake_op :: proc "contextless" (futex: ^Futex, op: Futex_Wake_Op_Type, flag
Same as wait, but mask specifies bits that must be equal for the mutex to wake up.
*/
futex_wait_bitset :: proc "contextless" (futex: ^Futex, op: Futex_Wait_Bitset_Type, flags: Futex_Flags, val: u32,
timeout: ^Time_Spec, mask: u32) -> (int, Errno)
{
timeout: ^Time_Spec, mask: u32) -> (int, Errno) {
futex_flags := cast(u32) op + transmute(u32) flags
ret := syscall(SYS_futex, futex, futex_flags, val, timeout, 0, mask)
return errno_unwrap(ret, int)
@@ -2262,8 +2278,7 @@ futex_wait_bitset :: proc "contextless" (futex: ^Futex, op: Futex_Wait_Bitset_Ty
/*
Wake up on bitset.
*/
futex_wake_bitset :: proc "contextless" (futex: ^Futex, op: Futex_Wake_Bitset_Type, flags: Futex_Flags, n_wakeup: u32, mask: u32) -> (int, Errno)
{
futex_wake_bitset :: proc "contextless" (futex: ^Futex, op: Futex_Wake_Bitset_Type, flags: Futex_Flags, n_wakeup: u32, mask: u32) -> (int, Errno) {
futex_flags := cast(u32) op + transmute(u32) flags
ret := syscall(SYS_futex, futex, futex_flags, n_wakeup, 0, 0, mask)
return errno_unwrap(ret, int)
@@ -2271,7 +2286,7 @@ futex_wake_bitset :: proc "contextless" (futex: ^Futex, op: Futex_Wake_Bitset_Ty
// TODO(flysand): Priority inheritance (PI) futicees
futex :: proc {
futex :: proc{
futex_wait,
futex_wake,
futex_cmp_requeue,
@@ -2310,7 +2325,7 @@ futex :: proc {
*/
epoll_create :: proc(size: i32 = 1) -> (Fd, Errno) {
when ODIN_ARCH != .arm64 {
ret := syscall(SYS_epoll_create)
ret := syscall(SYS_epoll_create, i32(1))
return errno_unwrap(ret, Fd)
} else {
ret := syscall(SYS_epoll_create1, i32(0))
@@ -2467,8 +2482,8 @@ tgkill :: proc "contextless" (tgid, tid: Pid, sig: Signal) -> (Errno) {
Wait on process, process group or pid file descriptor.
Available since Linux 2.6.10.
*/
waitid :: proc "contextless" (id_type: Id_Type, id: Id, sig_info: ^Sig_Info, options: Wait_Options) -> (Errno) {
ret := syscall(SYS_waitid, id_type, id, sig_info, transmute(i32) options)
waitid :: proc "contextless" (id_type: Id_Type, id: Id, sig_info: ^Sig_Info, options: Wait_Options, rusage: ^RUsage) -> (Errno) {
ret := syscall(SYS_waitid, id_type, id, sig_info, transmute(i32) options, rusage)
return Errno(-ret)
}
@@ -2495,7 +2510,7 @@ waitid :: proc "contextless" (id_type: Id_Type, id: Id, sig_info: ^Sig_Info, opt
Available since Linux 2.6.16.
*/
openat :: proc "contextless" (fd: Fd, name: cstring, flags: Open_Flags, mode: Mode = {}) -> (Fd, Errno) {
ret := syscall(SYS_openat, fd, AT_FDCWD, transmute(uintptr) name, transmute(u32) mode)
ret := syscall(SYS_openat, fd, transmute(uintptr) name, transmute(u32) flags, transmute(u32) mode)
return errno_unwrap(ret, Fd)
}
@@ -2574,8 +2589,8 @@ linkat :: proc "contextless" (target_dirfd: Fd, oldpath: cstring, link_dirfd: Fd
Create a symbolic link at specified dirfd.
Available since Linux 2.6.16.
*/
symlinkat :: proc "contextless" (dirfd: Fd, target: cstring, linkpath: cstring) -> (Errno) {
ret := syscall(SYS_symlinkat, dirfd, cast(rawptr) target, cast(rawptr) linkpath)
symlinkat :: proc "contextless" (target: cstring, dirfd: Fd, linkpath: cstring) -> (Errno) {
ret := syscall(SYS_symlinkat, cast(rawptr) target, dirfd, cast(rawptr) linkpath)
return Errno(-ret)
}
@@ -2610,13 +2625,13 @@ faccessat :: proc "contextless" (dirfd: Fd, name: cstring, mode: Mode = F_OK) ->
Wait for events on a file descriptor.
Available since Linux 2.6.16.
*/
ppoll :: proc "contextless" (fds: []Poll_Fd, timeout: ^Time_Spec, sigmask: ^Sig_Set) -> (Errno) {
ppoll :: proc "contextless" (fds: []Poll_Fd, timeout: ^Time_Spec, sigmask: ^Sig_Set) -> (i32, Errno) {
when size_of(int) == 8 {
ret := syscall(SYS_ppoll, raw_data(fds), len(fds), timeout, sigmask, size_of(Sig_Set))
return Errno(-ret)
return errno_unwrap(ret, i32)
} else {
ret := syscall(SYS_ppoll_time64, raw_data(fds), len(fds), timeout, sigmask, size_of(Sig_Set))
return Errno(-ret)
return errno_unwrap(ret, i32)
}
}
@@ -2799,7 +2814,7 @@ getrandom :: proc "contextless" (buf: []u8, flags: Get_Random_Flags) -> (int, Er
Execute program relative to a directory file descriptor.
Available since Linux 3.19.
*/
execveat :: proc "contextless" (dirfd: Fd, name: cstring, argv: [^]cstring, envp: [^]cstring, flags: Execveat_Flags) -> (Errno) {
execveat :: proc "contextless" (dirfd: Fd, name: cstring, argv: [^]cstring, envp: [^]cstring, flags: FD_Flags = {}) -> (Errno) {
ret := syscall(SYS_execveat, dirfd, cast(rawptr) name, cast(rawptr) argv, cast(rawptr) envp, transmute(i32) flags)
return Errno(-ret)
}
+85 -20
View File
@@ -18,7 +18,7 @@ Gid :: distinct u32
/*
Type for Process IDs, Thread IDs, Thread group ID.
*/
Pid :: distinct int
Pid :: distinct i32
/*
Type for any of: pid, pidfd, pgid.
@@ -89,11 +89,11 @@ FD_Flags :: bit_set[FD_Flags_Bits; i32]
Represents file's permission and status bits
**Example:**
When you're passing a value of this type the recommended usage is:
```
linux.Mode{.S_IXOTH, .S_IROTH} | linux.S_IRWXU | linux.S_IRWXG
```
This would generate a mode that has full permissions for the
file's owner and group, and only "read" and "execute" bits
for others.
@@ -151,9 +151,9 @@ when ODIN_ARCH == .amd64 {
size: i64,
blksize: uint,
blocks: u64,
atim: Time_Spec,
mtim: Time_Spec,
ctim: Time_Spec,
atime: Time_Spec,
mtime: Time_Spec,
ctime: Time_Spec,
ino: Inode,
}
}
@@ -495,16 +495,15 @@ Pid_FD_Flags :: bit_set[Pid_FD_Flags_Bits; i32]
// 1. Odin's bitfields start from 0, whereas signals start from 1
// 2. It's unclear how bitfields act in terms of ABI (are they an array of ints or an array of longs?).
// it makes a difference because ARM is big endian.
@private _SIGSET_NWORDS :: (1024 / (8 * size_of(uint)))
@private _SIGSET_NWORDS :: (8 / size_of(uint))
Sig_Set :: [_SIGSET_NWORDS]uint
@private SI_MAX_SIZE :: 128
@private SI_ARCH_PREAMBLE :: 3 * size_of(i32)
@private SI_PAD_SIZE :: (SI_MAX_SIZE - SI_ARCH_PREAMBLE) / size_of(i32)
@private SI_TIMER_PAD_SIZE :: size_of(Uid) - size_of(i32)
@private SI_ARCH_PREAMBLE :: 4 * size_of(i32)
@private SI_PAD_SIZE :: SI_MAX_SIZE - SI_ARCH_PREAMBLE
Sig_Handler_Fn :: #type proc "c" (sig: Signal)
Sig_Restore_Fn :: #type proc "c" ()
Sig_Restore_Fn :: #type proc "c" () -> !
Sig_Info :: struct #packed {
signo: Signal,
@@ -518,8 +517,9 @@ Sig_Info :: struct #packed {
uid: Uid, /* sender's uid */
},
using _timer: struct {
timerid: i32, /* timer id */
timerid: i32, /* timer id */
overrun: i32, /* overrun count */
value: Sig_Val, /* timer value */
},
/* POSIX.1b signals */
using _rt: struct {
@@ -528,8 +528,8 @@ Sig_Info :: struct #packed {
},
/* SIGCHLD */
using _sigchld: struct {
_pid1: Pid, /* which child */
_uid1: Uid, /* sender's uid */
_pid1: Pid, /* which child */
_uid1: Uid, /* sender's uid */
status: i32, /* exit code */
utime: uint,
stime: uint, //clock_t
@@ -537,7 +537,24 @@ Sig_Info :: struct #packed {
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
using _sigfault: struct {
addr: rawptr, /* faulting insn/memory ref. */
addr_lsb: i16, /* LSB of the reported address */
using _: struct #raw_union {
trapno: i32, /* Trap number that caused signal */
addr_lsb: i16, /* LSB of the reported address */
using _addr_bnd: struct {
_pad2: u64,
lower: rawptr, /* lower bound during fault */
upper: rawptr, /* upper bound during fault */
},
using _addr_pkey: struct {
_pad3: u64,
pkey: u32, /* protection key on PTE that faulted */
},
using _perf: struct {
perf_data: u64,
perf_type: u32,
perf_flags: u32,
},
},
},
/* SIGPOLL */
using _sigpoll: struct {
@@ -547,12 +564,43 @@ Sig_Info :: struct #packed {
/* SIGSYS */
using _sigsys: struct {
call_addr: rawptr, /* calling user insn */
syscall: i32, /* triggering system call number */
arch: u32, /* AUDIT_ARCH_* of syscall */
syscall: i32, /* triggering system call number */
arch: u32, /* AUDIT_ARCH_* of syscall */
},
},
}
#assert(size_of(Sig_Info) == 128)
when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm64 {
#assert(offset_of(Sig_Info, signo) == 0x00)
#assert(offset_of(Sig_Info, errno) == 0x04)
#assert(offset_of(Sig_Info, code) == 0x08)
#assert(offset_of(Sig_Info, pid) == 0x10)
#assert(offset_of(Sig_Info, uid) == 0x14)
#assert(offset_of(Sig_Info, timerid) == 0x10)
#assert(offset_of(Sig_Info, overrun) == 0x14)
#assert(offset_of(Sig_Info, value) == 0x18)
#assert(offset_of(Sig_Info, status) == 0x18)
#assert(offset_of(Sig_Info, utime) == 0x20)
#assert(offset_of(Sig_Info, stime) == 0x28)
#assert(offset_of(Sig_Info, addr) == 0x10)
#assert(offset_of(Sig_Info, addr_lsb) == 0x18)
#assert(offset_of(Sig_Info, trapno) == 0x18)
#assert(offset_of(Sig_Info, lower) == 0x20)
#assert(offset_of(Sig_Info, upper) == 0x28)
#assert(offset_of(Sig_Info, pkey) == 0x20)
#assert(offset_of(Sig_Info, perf_data) == 0x18)
#assert(offset_of(Sig_Info, perf_type) == 0x20)
#assert(offset_of(Sig_Info, perf_flags) == 0x24)
#assert(offset_of(Sig_Info, band) == 0x10)
#assert(offset_of(Sig_Info, fd) == 0x18)
#assert(offset_of(Sig_Info, call_addr) == 0x10)
#assert(offset_of(Sig_Info, syscall) == 0x18)
#assert(offset_of(Sig_Info, arch) == 0x1C)
} else {
// TODO
}
SIGEV_MAX_SIZE :: 64
SIGEV_PAD_SIZE :: ((SIGEV_MAX_SIZE-size_of(i32)*2+size_of(Sig_Val))/size_of(i32))
@@ -583,12 +631,20 @@ Sig_Stack :: struct {
size: uintptr,
}
Sig_Action_Special :: enum uint {
SIG_DFL = 0,
SIG_IGN = 1,
SIG_ERR = ~uint(0),
}
Sig_Action_Flags :: bit_set[Sig_Action_Flag; uint]
Sig_Action :: struct($T: typeid) {
using _u: struct #raw_union {
handler: Sig_Handler_Fn,
sigaction: #type proc "c" (sig: Signal, si: ^Sig_Info, ctx: ^T),
special: Sig_Action_Special,
},
flags: uint,
flags: Sig_Action_Flags,
restorer: Sig_Restore_Fn,
mask: Sig_Set,
}
@@ -631,6 +687,14 @@ Sock_Addr_In6 :: struct #packed {
sin6_scope_id: u32,
}
/*
Struct representing Unix Domain Socket address
*/
Sock_Addr_Un :: struct #packed {
sun_family: Address_Family,
sun_path: [108]u8,
}
/*
Struct representing an arbitrary socket address.
*/
@@ -641,6 +705,7 @@ Sock_Addr_Any :: struct #raw_union {
},
using ipv4: Sock_Addr_In,
using ipv6: Sock_Addr_In6,
using uds: Sock_Addr_Un,
}
/*
@@ -724,7 +789,7 @@ RLimit :: struct {
/*
Structure representing how much of each resource got used.
*/
*/
RUsage :: struct {
utime: Time_Val,
stime: Time_Val,
@@ -804,7 +869,7 @@ when size_of(int) == 8 || ODIN_ARCH == .i386 {
cpid: Pid,
lpid: Pid,
nattach: uint,
_: [2]uint,
_: [2]uint,
}
}
+4 -5
View File
@@ -48,7 +48,7 @@ WCOREDUMP :: #force_inline proc "contextless" (s: u32) -> bool {
return 1 << ((cast(uint)(sig) - 1) % (8*size_of(uint)))
}
@private _sigword :: proc "contextless" (sig: Signal) -> (uint) {
return (cast(uint)sig - 1) / (8*size_of(uint))
return (cast(uint)sig - 1) / (8*size_of(uint))
}
// TODO: sigaddset etc
@@ -85,13 +85,13 @@ dirent_iterate_buf :: proc "contextless" (buf: []u8, offs: ^int) -> (d: ^Dirent,
/// Obtain the name of dirent as a string
/// The lifetime of the string is bound to the lifetime of the provided dirent structure
dirent_name :: proc "contextless" (dirent: ^Dirent) -> string #no_bounds_check {
str := transmute([^]u8) &dirent.name
str := ([^]u8)(&dirent.name)
// Note(flysand): The string size calculated above applies only to the ideal case
// we subtract 1 byte from the string size, because a null terminator is guaranteed
// to be present. But! That said, the dirents are aligned to 8 bytes and the padding
// between the null terminator and the start of the next struct may be not initialized
// which means we also have to scan these garbage bytes.
str_size := (cast(int) dirent.reclen) - 1 - cast(int) offset_of(Dirent, name)
str_size := int(dirent.reclen) - 1 - cast(int)offset_of(Dirent, name)
// This skips *only* over the garbage, since if we're not garbage we're at nul terminator,
// which skips this loop
for str[str_size] != 0 {
@@ -115,7 +115,6 @@ futex_op :: proc "contextless" (arg_op: Futex_Arg_Op, cmp_op: Futex_Cmp_Op, op_a
/// Helper function for constructing the config for caches
perf_cache_config :: #force_inline proc "contextless" (id: Perf_Hardware_Cache_Id,
op: Perf_Hardware_Cache_Op_Id,
res: Perf_Hardware_Cache_Result_Id) -> u64
{
res: Perf_Hardware_Cache_Result_Id) -> u64 {
return u64(id) | (u64(op) << 8) | (u64(res) << 16)
}
+2 -2
View File
@@ -95,7 +95,7 @@ sem_t :: struct {
PTHREAD_CANCEL_ENABLE :: 0
PTHREAD_CANCEL_DISABLE :: 1
PTHREAD_CANCEL_DEFERRED :: 0
PTHREAD_CANCEL_ASYNCHRONOUS :: 1
PTHREAD_CANCEL_ASYNCHRONOUS :: 2
foreign import "system:pthread"
@@ -119,4 +119,4 @@ foreign pthread {
pthread_setcancelstate :: proc (state: c.int, old_state: ^c.int) -> c.int ---
pthread_setcanceltype :: proc (type: c.int, old_type: ^c.int) -> c.int ---
pthread_cancel :: proc (thread: pthread_t) -> c.int ---
}
}
+102
View File
@@ -0,0 +1,102 @@
package unix
import "core:c"
pthread_t :: distinct u64
SEM_T_SIZE :: 8
PTHREAD_CONDATTR_T_SIZE :: 16
PTHREAD_MUTEXATTR_T_SIZE :: 16
PTHREAD_RWLOCKATTR_T_SIZE :: 16
PTHREAD_BARRIERATTR_T_SIZE :: 16
PTHREAD_COND_T_SIZE :: 40
PTHREAD_MUTEX_T_SIZE :: 48
PTHREAD_RWLOCK_T_SIZE :: 64
PTHREAD_BARRIER_T_SIZE :: 48
PTHREAD_ATTR_T_SIZE :: 16
pthread_cond_t :: struct #align(8) {
_: [PTHREAD_COND_T_SIZE] c.char,
}
pthread_mutex_t :: struct #align(8) {
_: [PTHREAD_MUTEX_T_SIZE] c.char,
}
pthread_rwlock_t :: struct #align(8) {
_: [PTHREAD_RWLOCK_T_SIZE] c.char,
}
pthread_barrier_t :: struct #align(8) {
_: [PTHREAD_BARRIER_T_SIZE] c.char,
}
pthread_attr_t :: struct #align(8) {
_: [PTHREAD_ATTR_T_SIZE] c.char,
}
pthread_condattr_t :: struct #align(8) {
_: [PTHREAD_CONDATTR_T_SIZE] c.char,
}
pthread_mutexattr_t :: struct #align(8) {
_: [PTHREAD_MUTEXATTR_T_SIZE] c.char,
}
pthread_rwlockattr_t :: struct #align(8) {
_: [PTHREAD_RWLOCKATTR_T_SIZE] c.char,
}
pthread_barrierattr_t :: struct #align(8) {
_: [PTHREAD_BARRIERATTR_T_SIZE] c.char,
}
PTHREAD_MUTEX_NORMAL :: 0
PTHREAD_MUTEX_ERRORCHECK :: 1
PTHREAD_MUTEX_RECURSIVE :: 2
PTHREAD_CREATE_JOINABLE :: 0
PTHREAD_CREATE_DETACHED :: 1
PTHREAD_INHERIT_SCHED :: 0
PTHREAD_EXPLICIT_SCHED :: 1
PTHREAD_PROCESS_PRIVATE :: 0
PTHREAD_PROCESS_SHARED :: 1
SCHED_NONE :: -1
SCHED_OTHER :: 0
SCHED_FIFO :: 1
SCHED_RR :: 3
sched_param :: struct {
sched_priority: c.int,
}
sem_t :: struct #align(16) {
_: [SEM_T_SIZE] c.char,
}
PTHREAD_CANCEL_ENABLE :: 0
PTHREAD_CANCEL_DISABLE :: 1
PTHREAD_CANCEL_DEFERRED :: 0
PTHREAD_CANCEL_ASYNCHRONOUS :: 1
foreign import "system:pthread"
@(default_calling_convention="c")
foreign pthread {
sem_open :: proc(name: cstring, flags: c.int) -> ^sem_t ---
sem_init :: proc(sem: ^sem_t, pshared: c.int, initial_value: c.uint) -> c.int ---
sem_destroy :: proc(sem: ^sem_t) -> c.int ---
sem_post :: proc(sem: ^sem_t) -> c.int ---
sem_wait :: proc(sem: ^sem_t) -> c.int ---
sem_trywait :: proc(sem: ^sem_t) -> c.int ---
pthread_yield :: proc() ---
pthread_setcancelstate :: proc (state: c.int, old_state: ^c.int) -> c.int ---
pthread_setcanceltype :: proc (type: c.int, old_type: ^c.int) -> c.int ---
pthread_cancel :: proc (thread: pthread_t) -> c.int ---
}
+2 -2
View File
@@ -49,7 +49,7 @@ sem_t :: distinct rawptr
PTHREAD_CANCEL_ENABLE :: 0
PTHREAD_CANCEL_DISABLE :: 1
PTHREAD_CANCEL_DEFERRED :: 0
PTHREAD_CANCEL_ASYNCHRONOUS :: 1
PTHREAD_CANCEL_ASYNCHRONOUS :: 2
foreign import libc "system:c"
@@ -71,4 +71,4 @@ foreign libc {
pthread_setcancelstate :: proc (state: c.int, old_state: ^c.int) -> c.int ---
pthread_setcanceltype :: proc (type: c.int, old_type: ^c.int) -> c.int ---
pthread_cancel :: proc (thread: pthread_t) -> c.int ---
}
}
+2 -1
View File
@@ -1,4 +1,4 @@
//+build linux, darwin, freebsd, openbsd, haiku
//+build linux, darwin, freebsd, openbsd, netbsd, haiku
package unix
foreign import "system:pthread"
@@ -116,4 +116,5 @@ foreign pthread {
pthread_mutexattr_setpshared :: proc(attrs: ^pthread_mutexattr_t, value: c.int) -> c.int ---
pthread_mutexattr_getpshared :: proc(attrs: ^pthread_mutexattr_t, result: ^c.int) -> c.int ---
pthread_testcancel :: proc () ---
}
+3
View File
@@ -0,0 +1,3 @@
package unix
SYS___futex : uintptr : 166
+51 -11
View File
@@ -1,22 +1,62 @@
//+build darwin
package unix
import "core:sys/darwin"
import "base:intrinsics"
import "core:sys/darwin"
_ :: darwin
sysctl :: proc(mib: []i32, val: ^$T) -> (ok: bool) {
mib := mib
result_size := i64(size_of(T))
sysctl :: proc "contextless" (mib: []i32, val: ^$T) -> (ok: bool) {
result_size := uint(size_of(T))
when ODIN_NO_CRT {
res := darwin.syscall_sysctl(
raw_data(mib), len(mib),
val, &result_size,
nil, 0,
)
return res == 0
} else {
foreign {
@(link_name="sysctl") _sysctl :: proc(
name: [^]i32, namelen: u32,
oldp: rawptr, oldlenp: ^uint,
newp: rawptr, newlen: uint,
) -> i32 ---
}
res := _sysctl(
raw_data(mib), u32(len(mib)),
val, &result_size,
nil, 0,
)
return res == 0
}
}
res := intrinsics.syscall(
darwin.unix_offset_syscall(.sysctl),
uintptr(raw_data(mib)), uintptr(len(mib)),
uintptr(val), uintptr(&result_size),
uintptr(0), uintptr(0),
)
return res == 0
sysctlbyname :: proc "contextless" (name: cstring, val: ^$T) -> (ok: bool) {
result_size := uint(size_of(T))
when ODIN_NO_CRT {
res := darwin.syscall_sysctlbyname(
string(name),
val, &result_size,
nil, 0,
)
return res == 0
} else {
foreign {
@(link_name="sysctlbyname") _sysctlbyname :: proc(
name: cstring,
oldp: rawptr, oldlenp: ^uint,
newp: rawptr, newlen: uint,
) -> i32 ---
}
res := _sysctlbyname(
name,
val, &result_size,
nil, 0,
)
return res == 0
}
}
// See sysctl.h for darwin for details
+4 -3
View File
@@ -5,14 +5,15 @@ import "base:intrinsics"
sysctl :: proc(mib: []i32, val: ^$T) -> (ok: bool) {
mib := mib
result_size := i64(size_of(T))
result_size := u64(size_of(T))
res := intrinsics.syscall(SYS_sysctl,
res: uintptr
res, ok = intrinsics.syscall_bsd(SYS_sysctl,
uintptr(raw_data(mib)), uintptr(len(mib)),
uintptr(val), uintptr(&result_size),
uintptr(0), uintptr(0),
)
return res == 0
return
}
// See /usr/include/sys/sysctl.h for details
+44
View File
@@ -0,0 +1,44 @@
package unix
import "core:c"
foreign import libc "system:c"
@(default_calling_convention="c")
foreign libc {
@(link_name="sysctl") _unix_sysctl :: proc(name: [^]i32, namelen: u32, oldp: rawptr, oldlenp: ^c.size_t, newp: rawptr, newlen: c.size_t) -> i32 ---
}
sysctl :: proc(mib: []i32, val: ^$T) -> (ok: bool) {
mib := mib
result_size := c.size_t(size_of(T))
res := _unix_sysctl(raw_data(mib), u32(len(mib)), val, &result_size, nil, 0)
return res == 0
}
// See /usr/include/sys/sysctl.h for details
CTL_KERN :: 1
KERN_OSTYPE :: 1
KERN_OSRELEASE :: 2
KERN_OSREV :: 3
KERN_VERSION :: 4
CTL_VM :: 2
CTL_FS :: 3
CTL_NET :: 4
CTL_DEBUG :: 5
CTL_HW :: 6
HW_MACHINE :: 1
HW_MODEL :: 2
HW_NCPU :: 3
HW_BYTEORDER :: 4
HW_PHYSMEM :: 5
HW_USERMEM :: 6
HW_PAGESIZE :: 7
HW_DISKNAMES :: 8
HW_IOSTATS :: 9
HW_MACHINE_ARCH :: 10
HW_ALIGNBYTES :: 11
HW_CNMAGIC :: 12
HW_PHYSMEM64 :: 13
HW_USERMEM64 :: 14
HW_IOSTATNAMES :: 15
HW_NCPUONLINE :: 16
+15 -7
View File
@@ -1,4 +1,4 @@
//+build linux, darwin, freebsd, openbsd, haiku
//+build linux, darwin, freebsd, openbsd, netbsd, haiku
package unix
when ODIN_OS == .Darwin {
@@ -9,11 +9,20 @@ when ODIN_OS == .Darwin {
import "core:c"
@(default_calling_convention="c")
foreign libc {
clock_gettime :: proc(clock_id: u64, timespec: ^timespec) -> c.int ---
sleep :: proc(seconds: c.uint) -> c.int ---
nanosleep :: proc(requested, remaining: ^timespec) -> c.int ---
when ODIN_OS == .NetBSD {
@(default_calling_convention="c")
foreign libc {
@(link_name="__clock_gettime50") clock_gettime :: proc(clock_id: u64, timespec: ^timespec) -> c.int ---
@(link_name="__nanosleep50") nanosleep :: proc(requested, remaining: ^timespec) -> c.int ---
@(link_name="sleep") sleep :: proc(seconds: c.uint) -> c.int ---
}
} else {
@(default_calling_convention="c")
foreign libc {
clock_gettime :: proc(clock_id: u64, timespec: ^timespec) -> c.int ---
sleep :: proc(seconds: c.uint) -> c.int ---
nanosleep :: proc(requested, remaining: ^timespec) -> c.int ---
}
}
timespec :: struct {
@@ -65,7 +74,6 @@ seconds_since_boot :: proc "c" () -> f64 {
return f64(ts_boottime.tv_sec) + f64(ts_boottime.tv_nsec) / 1e9
}
inline_nanosleep :: proc "c" (nanoseconds: i64) -> (remaining: timespec, res: i32) {
s, ns := nanoseconds / 1e9, nanoseconds % 1e9
requested := timespec{tv_sec=s, tv_nsec=ns}
+2 -2
View File
@@ -962,7 +962,7 @@ prestat_dir_t :: struct {
}
prestat_t :: struct {
tag: u8,
tag: preopentype_t,
using u: struct {
dir: prestat_dir_t,
},
@@ -1158,7 +1158,7 @@ foreign wasi {
/**
* A buffer into which to write the preopened directory name.
*/
path: string,
path: []byte,
) -> errno_t ---
/**
* Create a directory.
+172 -1
View File
@@ -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,
}
+38
View File
@@ -228,6 +228,38 @@ MINIDUMP_TYPE :: enum u32 {
ValidTypeFlags = 0x01ffffff,
}
SYMBOL_INFOW :: struct {
SizeOfStruct: ULONG,
TypeIndex: ULONG,
Reserved: [2]ULONG64,
Index: ULONG,
Size: ULONG,
ModBase: ULONG64,
Flags: ULONG,
Value: ULONG64,
Address: ULONG64,
Register: ULONG,
Scope: ULONG,
Tag: ULONG,
NameLen: ULONG,
MaxNameLen: ULONG,
Name: [1]WCHAR,
}
IMAGEHLP_LINE64 :: struct {
SizeOfStruct: DWORD,
Key: PVOID,
LineNumber: DWORD,
FileName: PWSTR,
Address: DWORD64,
}
PSYMBOL_INFOW :: ^SYMBOL_INFOW
PIMAGEHLP_LINEW64 :: ^IMAGEHLP_LINE64
SYMOPT_LOAD_LINES :: 0x00000010
@(default_calling_convention = "system")
foreign Dbghelp {
MiniDumpWriteDump :: proc(
@@ -247,4 +279,10 @@ foreign Dbghelp {
StreamPointer: ^PVOID,
StreamSize: ^ULONG,
) -> BOOL ---
SymInitialize :: proc(hProcess: HANDLE, UserSearchPath: PCSTR, fInvadeProcess: BOOL) -> BOOL ---
SymCleanup :: proc(hProcess: HANDLE) -> BOOL ---
SymSetOptions :: proc(SymOptions: DWORD) -> DWORD ---
SymFromAddrW :: proc(hProcess: HANDLE, Address: DWORD64, Displacement: PDWORD64, Symbol: PSYMBOL_INFOW) -> BOOL ---
SymGetLineFromAddrW64 :: proc(hProcess: HANDLE, dwAddr: DWORD64, pdwDisplacement: PDWORD, Line: PIMAGEHLP_LINEW64) -> BOOL ---
}
+82 -3
View File
@@ -2,8 +2,20 @@
package sys_windows
import "core:c"
USAGE :: distinct USHORT
PUSAGE :: ^USAGE
HIDD_CONFIGURATION :: struct {
cookie: PVOID,
size: ULONG,
RingBufferSize: ULONG,
}
PHIDD_CONFIGURATION :: ^HIDD_CONFIGURATION
HIDD_ATTRIBUTES :: struct {
Size: ULONG,
VendorID: USHORT,
ProductID: USHORT,
VersionNumber: USHORT,
}
PHIDD_ATTRIBUTES :: ^HIDD_ATTRIBUTES
HIDP_CAPS :: struct {
Usage: USAGE,
@@ -113,7 +125,32 @@ HIDP_VALUE_CAPS :: struct {
}
PHIDP_VALUE_CAPS :: ^HIDP_VALUE_CAPS
PHIDP_PREPARSED_DATA :: rawptr
HIDP_DATA :: struct {
DataIndex: USHORT,
Reserved: USHORT,
using _ : struct #raw_union {
RawValue: ULONG,
On: BOOLEAN,
},
}
PHIDP_DATA :: ^HIDP_DATA
HIDP_LINK_COLLECTION_NODE :: struct {
LinkUsage: USAGE,
LinkUsagePage: USAGE,
Parent: USHORT,
NumberOfChildren: USHORT,
NextSibling: USHORT,
FirstChild: USHORT,
CollectionType: [8]ULONG,
IsAlias: [1]ULONG,
Reserved: [23]ULONG,
UserContext: PVOID,
}
PHIDP_LINK_COLLECTION_NODE :: ^HIDP_LINK_COLLECTION_NODE
HIDP_PREPARSED_DATA :: rawptr
PHIDP_PREPARSED_DATA :: ^HIDP_PREPARSED_DATA
HIDP_REPORT_TYPE :: enum c.int {
Input,
@@ -122,6 +159,26 @@ HIDP_REPORT_TYPE :: enum c.int {
}
HIDP_STATUS_SUCCESS : NTSTATUS : 0x110000
HIDP_STATUS_NULL : NTSTATUS : -2146369535 //0x80110001
HIDP_STATUS_INVALID_PREPARSED_DATA : NTSTATUS : -1072627711 //0xC0110001
HIDP_STATUS_INVALID_REPORT_TYPE : NTSTATUS : -1072627710 //0xC0110002
HIDP_STATUS_INVALID_REPORT_LENGTH : NTSTATUS : -1072627709 //0xC0110003
HIDP_STATUS_USAGE_NOT_FOUND : NTSTATUS : -1072627708 //0xC0110004
HIDP_STATUS_VALUE_OUT_OF_RANGE : NTSTATUS : -1072627707 //0xC0110005
HIDP_STATUS_BAD_LOG_PHY_VALUES : NTSTATUS : -1072627706 //0xC0100006
HIDP_STATUS_BUFFER_TOO_SMALL : NTSTATUS : -1072627705 //0xC0110007
HIDP_STATUS_INTERNAL_ERROR : NTSTATUS : -1072627704 //0xC0110008
HIDP_STATUS_I8042_TRANS_UNKNOWN : NTSTATUS : -1072627703 //0xC0110009
HIDP_STATUS_INCOMPATIBLE_REPORT_ID : NTSTATUS : -1072627702 //0xC011000A
HIDP_STATUS_NOT_VALUE_ARRAY : NTSTATUS : -1072627701 //0xC011000B
HIDP_STATUS_IS_VALUE_ARRAY : NTSTATUS : -1072627700 //0xC011000C
HIDP_STATUS_DATA_INDEX_NOT_FOUND : NTSTATUS : -1072627699 //0xC011000D
HIDP_STATUS_DATA_INDEX_OUT_OF_RANGE : NTSTATUS : -1072627698 //0xC011000E
HIDP_STATUS_BUTTON_NOT_PRESSED : NTSTATUS : -1072627697 //0xC011000F
HIDP_STATUS_REPORT_DOES_NOT_EXIST : NTSTATUS : -1072627696 //0xC0110010
HIDP_STATUS_NOT_IMPLEMENTED : NTSTATUS : -1072627680 //0xC0110020
HIDP_STATUS_NOT_BUTTON_ARRAY : NTSTATUS : -1072627679 //0xC0110021
HIDP_STATUS_I8242_TRANS_UNKNOWN :: HIDP_STATUS_I8042_TRANS_UNKNOWN
foreign import hid "system:hid.lib"
@(default_calling_convention="system")
@@ -131,4 +188,26 @@ foreign hid {
HidP_GetValueCaps :: proc(ReportType: HIDP_REPORT_TYPE, ValueCaps: PHIDP_VALUE_CAPS, ValueCapsLength: PUSHORT, PreparsedData: PHIDP_PREPARSED_DATA) -> NTSTATUS ---
HidP_GetUsages :: proc(ReportType: HIDP_REPORT_TYPE, UsagePage: USAGE, LinkCollection: USHORT, UsageList: PUSAGE, UsageLength: PULONG, PreparsedData: PHIDP_PREPARSED_DATA, Report: PCHAR, ReportLength: ULONG) -> NTSTATUS ---
HidP_GetUsageValue :: proc(ReportType: HIDP_REPORT_TYPE, UsagePage: USAGE, LinkCollection: USHORT, Usage: USAGE, UsageValue: PULONG, PreparsedData: PHIDP_PREPARSED_DATA, Report: PCHAR, ReportLength: ULONG) -> NTSTATUS ---
HidP_GetData :: proc(ReportType: HIDP_REPORT_TYPE, DataList: PHIDP_DATA, DataLength: PULONG, PreparsedData: PHIDP_PREPARSED_DATA, Report: PCHAR, ReportLength: ULONG) -> NTSTATUS ---
HidP_GetLinkCollectionNodes :: proc(LinkCollectionNodes: PHIDP_LINK_COLLECTION_NODE, LinkCollectionNodesLength: PULONG, PreparsedData: PHIDP_PREPARSED_DATA) -> NTSTATUS ---
HidD_GetAttributes :: proc(HidDeviceObject: HANDLE, Attributes: PHIDD_ATTRIBUTES) -> BOOLEAN ---
HidD_GetHidGuid :: proc(HidGuid: LPGUID) ---
HidD_GetPreparsedData :: proc(HidDeviceObject: HANDLE, PreparsedData: ^PHIDP_PREPARSED_DATA) -> BOOLEAN ---
HidD_FreePreparsedData :: proc(PreparsedData: PHIDP_PREPARSED_DATA) -> BOOLEAN ---
HidD_FlushQueue :: proc(HidDeviceObject: HANDLE) -> BOOLEAN ---
HidD_GetConfiguration :: proc(HidDeviceObject: HANDLE, Configuration: PHIDD_CONFIGURATION, ConfigurationLength: ULONG) -> BOOLEAN ---
HidD_SetConfiguration :: proc(HidDeviceObject: HANDLE, Configuration: PHIDD_CONFIGURATION, ConfigurationLength: ULONG) -> BOOLEAN ---
HidD_GetFeature :: proc(HidDeviceObject: HANDLE, ReportBuffer: PVOID, ReportBufferLength: ULONG) -> BOOLEAN ---
HidD_SetFeature :: proc(HidDeviceObject: HANDLE, ReportBuffer: PVOID, ReportBufferLength: ULONG) -> BOOLEAN ---
HidD_GetInputReport :: proc(HidDeviceObject: HANDLE, ReportBuffer: PVOID, ReportBufferLength: ULONG) -> BOOLEAN ---
HidD_SetOutputReport :: proc(HidDeviceObject: HANDLE, ReportBuffer: PVOID, ReportBufferLength: ULONG) -> BOOLEAN ---
HidD_GetNumInputBuffers :: proc(HidDeviceObject: HANDLE, NumberBuffers: PULONG) -> BOOLEAN ---
HidD_SetNumInputBuffers :: proc(HidDeviceObject: HANDLE, NumberBuffers: ULONG) -> BOOLEAN ---
HidD_GetPhysicalDescriptor :: proc(HidDeviceObject: HANDLE, Buffer: PVOID, BufferLength: ULONG) -> BOOLEAN ---
HidD_GetManufacturerString :: proc(HidDeviceObject: HANDLE, Buffer: PVOID, BufferLength: ULONG) -> BOOLEAN ---
HidD_GetProductString :: proc(HidDeviceObject: HANDLE, Buffer: PVOID, BufferLength: ULONG) -> BOOLEAN ---
HidD_GetIndexedString :: proc(HidDeviceObject: HANDLE, StringIndex: ULONG, Buffer: PVOID, BufferLength: ULONG) -> BOOLEAN ---
HidD_GetSerialNumberString :: proc(HidDeviceObject: HANDLE, Buffer: PVOID, BufferLength: ULONG) -> BOOLEAN ---
HidD_GetMsGenreDescriptor :: proc(HidDeviceObject: HANDLE, Buffer: PVOID, BufferLength: ULONG) -> BOOLEAN ---
}
+690
View File
@@ -0,0 +1,690 @@
// +build windows
package sys_windows
USAGE :: distinct USHORT
PUSAGE :: ^USAGE
HID_USAGE_PAGE_UNDEFINED :: 0x00
HID_USAGE_PAGE_GENERIC :: 0x01
HID_USAGE_PAGE_SIMULATION :: 0x02
HID_USAGE_PAGE_VR :: 0x03
HID_USAGE_PAGE_SPORT :: 0x04
HID_USAGE_PAGE_GAME :: 0x05
HID_USAGE_PAGE_GENERIC_DEVICE :: 0x06
HID_USAGE_PAGE_KEYBOARD :: 0x07
HID_USAGE_PAGE_LED :: 0x08
HID_USAGE_PAGE_BUTTON :: 0x09
HID_USAGE_PAGE_ORDINAL :: 0x0A
HID_USAGE_PAGE_TELEPHONY :: 0x0B
HID_USAGE_PAGE_CONSUMER :: 0x0C
HID_USAGE_PAGE_DIGITIZER :: 0x0D
HID_USAGE_PAGE_HAPTICS :: 0x0E
HID_USAGE_PAGE_PID :: 0x0F
HID_USAGE_PAGE_UNICODE :: 0x10
HID_USAGE_PAGE_ALPHANUMERIC :: 0x14
HID_USAGE_PAGE_SENSOR :: 0x20
HID_USAGE_PAGE_LIGHTING_ILLUMINATION :: 0x59
HID_USAGE_PAGE_BARCODE_SCANNER :: 0x8C
HID_USAGE_PAGE_WEIGHING_DEVICE :: 0x8D
HID_USAGE_PAGE_MAGNETIC_STRIPE_READER :: 0x8E
HID_USAGE_PAGE_CAMERA_CONTROL :: 0x90
HID_USAGE_PAGE_ARCADE :: 0x91
HID_USAGE_PAGE_MICROSOFT_BLUETOOTH_HANDSFREE :: 0xFFF3
HID_USAGE_PAGE_VENDOR_DEFINED_BEGIN :: 0xFF00
HID_USAGE_PAGE_VENDOR_DEFINED_END :: 0xFFFF
HID_USAGE_GENERIC_POINTER :: 0x01
HID_USAGE_GENERIC_MOUSE :: 0x02
HID_USAGE_GENERIC_JOYSTICK :: 0x04
HID_USAGE_GENERIC_GAMEPAD :: 0x05
HID_USAGE_GENERIC_KEYBOARD :: 0x06
HID_USAGE_GENERIC_KEYPAD :: 0x07
HID_USAGE_GENERIC_MULTI_AXIS_CONTROLLER :: 0x08
HID_USAGE_GENERIC_TABLET_PC_SYSTEM_CTL :: 0x09
HID_USAGE_GENERIC_PORTABLE_DEVICE_CONTROL :: 0x0D
HID_USAGE_GENERIC_INTERACTIVE_CONTROL :: 0x0E
HID_USAGE_GENERIC_SYSTEM_CTL :: 0x80
HID_USAGE_GENERIC_X :: 0x30
HID_USAGE_GENERIC_Y :: 0x31
HID_USAGE_GENERIC_Z :: 0x32
HID_USAGE_GENERIC_RX :: 0x33
HID_USAGE_GENERIC_RY :: 0x34
HID_USAGE_GENERIC_RZ :: 0x35
HID_USAGE_GENERIC_SLIDER :: 0x36
HID_USAGE_GENERIC_DIAL :: 0x37
HID_USAGE_GENERIC_WHEEL :: 0x38
HID_USAGE_GENERIC_HATSWITCH :: 0x39
HID_USAGE_GENERIC_COUNTED_BUFFER :: 0x3A
HID_USAGE_GENERIC_BYTE_COUNT :: 0x3B
HID_USAGE_GENERIC_MOTION_WAKEUP :: 0x3C
HID_USAGE_GENERIC_START :: 0x3D
HID_USAGE_GENERIC_SELECT :: 0x3E
HID_USAGE_GENERIC_VX :: 0x40
HID_USAGE_GENERIC_VY :: 0x41
HID_USAGE_GENERIC_VZ :: 0x42
HID_USAGE_GENERIC_VBRX :: 0x43
HID_USAGE_GENERIC_VBRY :: 0x44
HID_USAGE_GENERIC_VBRZ :: 0x45
HID_USAGE_GENERIC_VNO :: 0x46
HID_USAGE_GENERIC_FEATURE_NOTIFICATION :: 0x47
HID_USAGE_GENERIC_RESOLUTION_MULTIPLIER :: 0x48
HID_USAGE_GENERIC_SYSCTL_POWER :: 0x81
HID_USAGE_GENERIC_SYSCTL_SLEEP :: 0x82
HID_USAGE_GENERIC_SYSCTL_WAKE :: 0x83
HID_USAGE_GENERIC_SYSCTL_CONTEXT_MENU :: 0x84
HID_USAGE_GENERIC_SYSCTL_MAIN_MENU :: 0x85
HID_USAGE_GENERIC_SYSCTL_APP_MENU :: 0x86
HID_USAGE_GENERIC_SYSCTL_HELP_MENU :: 0x87
HID_USAGE_GENERIC_SYSCTL_MENU_EXIT :: 0x88
HID_USAGE_GENERIC_SYSCTL_MENU_SELECT :: 0x89
HID_USAGE_GENERIC_SYSCTL_MENU_RIGHT :: 0x8A
HID_USAGE_GENERIC_SYSCTL_MENU_LEFT :: 0x8B
HID_USAGE_GENERIC_SYSCTL_MENU_UP :: 0x8C
HID_USAGE_GENERIC_SYSCTL_MENU_DOWN :: 0x8D
HID_USAGE_GENERIC_SYSCTL_COLD_RESTART :: 0x8E
HID_USAGE_GENERIC_SYSCTL_WARM_RESTART :: 0x8F
HID_USAGE_GENERIC_DPAD_UP :: 0x90
HID_USAGE_GENERIC_DPAD_DOWN :: 0x91
HID_USAGE_GENERIC_DPAD_RIGHT :: 0x92
HID_USAGE_GENERIC_DPAD_LEFT :: 0x93
HID_USAGE_GENERIC_SYSCTL_FN :: 0x97
HID_USAGE_GENERIC_SYSCTL_FN_LOCK :: 0x98
HID_USAGE_GENERIC_SYSCTL_FN_LOCK_INDICATOR :: 0x99
HID_USAGE_GENERIC_SYSCTL_DISMISS_NOTIFICATION :: 0x9A
HID_USAGE_GENERIC_SYSCTL_DOCK :: 0xA0
HID_USAGE_GENERIC_SYSCTL_UNDOCK :: 0xA1
HID_USAGE_GENERIC_SYSCTL_SETUP :: 0xA2
HID_USAGE_GENERIC_SYSCTL_SYS_BREAK :: 0xA3
HID_USAGE_GENERIC_SYSCTL_SYS_DBG_BREAK :: 0xA4
HID_USAGE_GENERIC_SYSCTL_APP_BREAK :: 0xA5
HID_USAGE_GENERIC_SYSCTL_APP_DBG_BREAK :: 0xA6
HID_USAGE_GENERIC_SYSCTL_MUTE :: 0xA7
HID_USAGE_GENERIC_SYSCTL_HIBERNATE :: 0xA8
HID_USAGE_GENERIC_SYSCTL_DISP_INVERT :: 0xB0
HID_USAGE_GENERIC_SYSCTL_DISP_INTERNAL :: 0xB1
HID_USAGE_GENERIC_SYSCTL_DISP_EXTERNAL :: 0xB2
HID_USAGE_GENERIC_SYSCTL_DISP_BOTH :: 0xB3
HID_USAGE_GENERIC_SYSCTL_DISP_DUAL :: 0xB4
HID_USAGE_GENERIC_SYSCTL_DISP_TOGGLE :: 0xB5
HID_USAGE_GENERIC_SYSCTL_DISP_SWAP :: 0xB6
HID_USAGE_GENERIC_SYSCTL_DISP_AUTOSCALE :: 0xB7
HID_USAGE_GENERIC_SYSTEM_DISPLAY_ROTATION_LOCK_BUTTON :: 0xC9
HID_USAGE_GENERIC_SYSTEM_DISPLAY_ROTATION_LOCK_SLIDER_SWITCH :: 0xCA
HID_USAGE_GENERIC_CONTROL_ENABLE :: 0xCB
HID_USAGE_SIMULATION_FLIGHT_SIMULATION_DEVICE :: 0x01
HID_USAGE_SIMULATION_AUTOMOBILE_SIMULATION_DEVICE :: 0x02
HID_USAGE_SIMULATION_TANK_SIMULATION_DEVICE :: 0x03
HID_USAGE_SIMULATION_SPACESHIP_SIMULATION_DEVICE :: 0x04
HID_USAGE_SIMULATION_SUBMARINE_SIMULATION_DEVICE :: 0x05
HID_USAGE_SIMULATION_SAILING_SIMULATION_DEVICE :: 0x06
HID_USAGE_SIMULATION_MOTORCYCLE_SIMULATION_DEVICE :: 0x07
HID_USAGE_SIMULATION_SPORTS_SIMULATION_DEVICE :: 0x08
HID_USAGE_SIMULATION_AIRPLANE_SIMULATION_DEVICE :: 0x09
HID_USAGE_SIMULATION_HELICOPTER_SIMULATION_DEVICE :: 0x0A
HID_USAGE_SIMULATION_MAGIC_CARPET_SIMULATION_DEVICE :: 0x0B
HID_USAGE_SIMULATION_BICYCLE_SIMULATION_DEVICE :: 0x0C
HID_USAGE_SIMULATION_FLIGHT_CONTROL_STICK :: 0x20
HID_USAGE_SIMULATION_FLIGHT_STICK :: 0x21
HID_USAGE_SIMULATION_CYCLIC_CONTROL :: 0x22
HID_USAGE_SIMULATION_CYCLIC_TRIM :: 0x23
HID_USAGE_SIMULATION_FLIGHT_YOKE :: 0x24
HID_USAGE_SIMULATION_TRACK_CONTROL :: 0x25
HID_USAGE_SIMULATION_AILERON :: 0xB0
HID_USAGE_SIMULATION_AILERON_TRIM :: 0xB1
HID_USAGE_SIMULATION_ANTI_TORQUE_CONTROL :: 0xB2
HID_USAGE_SIMULATION_AUTOPIOLOT_ENABLE :: 0xB3
HID_USAGE_SIMULATION_CHAFF_RELEASE :: 0xB4
HID_USAGE_SIMULATION_COLLECTIVE_CONTROL :: 0xB5
HID_USAGE_SIMULATION_DIVE_BRAKE :: 0xB6
HID_USAGE_SIMULATION_ELECTRONIC_COUNTERMEASURES :: 0xB7
HID_USAGE_SIMULATION_ELEVATOR :: 0xB8
HID_USAGE_SIMULATION_ELEVATOR_TRIM :: 0xB9
HID_USAGE_SIMULATION_RUDDER :: 0xBA
HID_USAGE_SIMULATION_THROTTLE :: 0xBB
HID_USAGE_SIMULATION_FLIGHT_COMMUNICATIONS :: 0xBC
HID_USAGE_SIMULATION_FLARE_RELEASE :: 0xBD
HID_USAGE_SIMULATION_LANDING_GEAR :: 0xBE
HID_USAGE_SIMULATION_TOE_BRAKE :: 0xBF
HID_USAGE_SIMULATION_TRIGGER :: 0xC0
HID_USAGE_SIMULATION_WEAPONS_ARM :: 0xC1
HID_USAGE_SIMULATION_WEAPONS_SELECT :: 0xC2
HID_USAGE_SIMULATION_WING_FLAPS :: 0xC3
HID_USAGE_SIMULATION_ACCELLERATOR :: 0xC4
HID_USAGE_SIMULATION_BRAKE :: 0xC5
HID_USAGE_SIMULATION_CLUTCH :: 0xC6
HID_USAGE_SIMULATION_SHIFTER :: 0xC7
HID_USAGE_SIMULATION_STEERING :: 0xC8
HID_USAGE_SIMULATION_TURRET_DIRECTION :: 0xC9
HID_USAGE_SIMULATION_BARREL_ELEVATION :: 0xCA
HID_USAGE_SIMULATION_DIVE_PLANE :: 0xCB
HID_USAGE_SIMULATION_BALLAST :: 0xCC
HID_USAGE_SIMULATION_BICYCLE_CRANK :: 0xCD
HID_USAGE_SIMULATION_HANDLE_BARS :: 0xCE
HID_USAGE_SIMULATION_FRONT_BRAKE :: 0xCF
HID_USAGE_SIMULATION_REAR_BRAKE :: 0xD0
HID_USAGE_VR_BELT :: 0x01
HID_USAGE_VR_BODY_SUIT :: 0x02
HID_USAGE_VR_FLEXOR :: 0x03
HID_USAGE_VR_GLOVE :: 0x04
HID_USAGE_VR_HEAD_TRACKER :: 0x05
HID_USAGE_VR_HEAD_MOUNTED_DISPLAY :: 0x06
HID_USAGE_VR_HAND_TRACKER :: 0x07
HID_USAGE_VR_OCULOMETER :: 0x08
HID_USAGE_VR_VEST :: 0x09
HID_USAGE_VR_ANIMATRONIC_DEVICE :: 0x0A
HID_USAGE_VR_STEREO_ENABLE :: 0x20
HID_USAGE_VR_DISPLAY_ENABLE :: 0x21
HID_USAGE_SPORT_BASEBALL_BAT :: 0x01
HID_USAGE_SPORT_GOLF_CLUB :: 0x02
HID_USAGE_SPORT_ROWING_MACHINE :: 0x03
HID_USAGE_SPORT_TREADMILL :: 0x04
HID_USAGE_SPORT_STICK_TYPE :: 0x38
HID_USAGE_SPORT_OAR :: 0x30
HID_USAGE_SPORT_SLOPE :: 0x31
HID_USAGE_SPORT_RATE :: 0x32
HID_USAGE_SPORT_STICK_SPEED :: 0x33
HID_USAGE_SPORT_STICK_FACE_ANGLE :: 0x34
HID_USAGE_SPORT_HEEL_TOE :: 0x35
HID_USAGE_SPORT_FOLLOW_THROUGH :: 0x36
HID_USAGE_SPORT_TEMPO :: 0x37
HID_USAGE_SPORT_HEIGHT :: 0x39
HID_USAGE_SPORT_PUTTER :: 0x50
HID_USAGE_SPORT_1_IRON :: 0x51
HID_USAGE_SPORT_2_IRON :: 0x52
HID_USAGE_SPORT_3_IRON :: 0x53
HID_USAGE_SPORT_4_IRON :: 0x54
HID_USAGE_SPORT_5_IRON :: 0x55
HID_USAGE_SPORT_6_IRON :: 0x56
HID_USAGE_SPORT_7_IRON :: 0x57
HID_USAGE_SPORT_8_IRON :: 0x58
HID_USAGE_SPORT_9_IRON :: 0x59
HID_USAGE_SPORT_10_IRON :: 0x5A
HID_USAGE_SPORT_11_IRON :: 0x5B
HID_USAGE_SPORT_SAND_WEDGE :: 0x5C
HID_USAGE_SPORT_LOFT_WEDGE :: 0x5D
HID_USAGE_SPORT_POWER_WEDGE :: 0x5E
HID_USAGE_SPORT_1_WOOD :: 0x5F
HID_USAGE_SPORT_3_WOOD :: 0x60
HID_USAGE_SPORT_5_WOOD :: 0x61
HID_USAGE_SPORT_7_WOOD :: 0x62
HID_USAGE_SPORT_9_WOOD :: 0x63
HID_USAGE_GAME_3D_GAME_CONTROLLER :: 0x01
HID_USAGE_GAME_PINBALL_DEVICE :: 0x02
HID_USAGE_GAME_GUN_DEVICE :: 0x03
HID_USAGE_GAME_POINT_OF_VIEW :: 0x20
HID_USAGE_GAME_GUN_SELECTOR :: 0x32
HID_USAGE_GAME_GAMEPAD_FIRE_JUMP :: 0x37
HID_USAGE_GAME_GAMEPAD_TRIGGER :: 0x39
HID_USAGE_GAME_TURN_RIGHT_LEFT :: 0x21
HID_USAGE_GAME_PITCH_FORWARD_BACK :: 0x22
HID_USAGE_GAME_ROLL_RIGHT_LEFT :: 0x23
HID_USAGE_GAME_MOVE_RIGHT_LEFT :: 0x24
HID_USAGE_GAME_MOVE_FORWARD_BACK :: 0x25
HID_USAGE_GAME_MOVE_UP_DOWN :: 0x26
HID_USAGE_GAME_LEAN_RIGHT_LEFT :: 0x27
HID_USAGE_GAME_LEAN_FORWARD_BACK :: 0x28
HID_USAGE_GAME_POV_HEIGHT :: 0x29
HID_USAGE_GAME_FLIPPER :: 0x2A
HID_USAGE_GAME_SECONDARY_FLIPPER :: 0x2B
HID_USAGE_GAME_BUMP :: 0x2C
HID_USAGE_GAME_NEW_GAME :: 0x2D
HID_USAGE_GAME_SHOOT_BALL :: 0x2E
HID_USAGE_GAME_PLAYER :: 0x2F
HID_USAGE_GAME_GUN_BOLT :: 0x30
HID_USAGE_GAME_GUN_CLIP :: 0x31
HID_USAGE_GAME_GUN_SINGLE_SHOT :: 0x33
HID_USAGE_GAME_GUN_BURST :: 0x34
HID_USAGE_GAME_GUN_AUTOMATIC :: 0x35
HID_USAGE_GAME_GUN_SAFETY :: 0x36
HID_USAGE_GENERIC_DEVICE_BATTERY_STRENGTH :: 0x20
HID_USAGE_GENERIC_DEVICE_WIRELESS_CHANNEL :: 0x21
HID_USAGE_GENERIC_DEVICE_WIRELESS_ID :: 0x22
HID_USAGE_GENERIC_DEVICE_DISCOVER_WIRELESS_CONTROL :: 0x23
HID_USAGE_GENERIC_DEVICE_SECURITY_CODE_CHAR_ENTERED :: 0x24
HID_USAGE_GENERIC_DEVICE_SECURITY_CODE_CHAR_ERASED :: 0x25
HID_USAGE_GENERIC_DEVICE_SECURITY_CODE_CLEARED :: 0x26
// Error "keys"
HID_USAGE_KEYBOARD_NOEVENT :: 0x00
HID_USAGE_KEYBOARD_ROLLOVER :: 0x01
HID_USAGE_KEYBOARD_POSTFAIL :: 0x02
HID_USAGE_KEYBOARD_UNDEFINED :: 0x03
// Letters
HID_USAGE_KEYBOARD_aA :: 0x04
HID_USAGE_KEYBOARD_zZ :: 0x1D
// Numbers
HID_USAGE_KEYBOARD_ONE :: 0x1E
HID_USAGE_KEYBOARD_ZERO :: 0x27
// Modifier Keys
HID_USAGE_KEYBOARD_LCTRL :: 0xE0
HID_USAGE_KEYBOARD_LSHFT :: 0xE1
HID_USAGE_KEYBOARD_LALT :: 0xE2
HID_USAGE_KEYBOARD_LGUI :: 0xE3
HID_USAGE_KEYBOARD_RCTRL :: 0xE4
HID_USAGE_KEYBOARD_RSHFT :: 0xE5
HID_USAGE_KEYBOARD_RALT :: 0xE6
HID_USAGE_KEYBOARD_RGUI :: 0xE7
HID_USAGE_KEYBOARD_SCROLL_LOCK :: 0x47
HID_USAGE_KEYBOARD_NUM_LOCK :: 0x53
HID_USAGE_KEYBOARD_CAPS_LOCK :: 0x39
// Function keys
HID_USAGE_KEYBOARD_F1 :: 0x3A
HID_USAGE_KEYBOARD_F2 :: 0x3B
HID_USAGE_KEYBOARD_F3 :: 0x3C
HID_USAGE_KEYBOARD_F4 :: 0x3D
HID_USAGE_KEYBOARD_F5 :: 0x3E
HID_USAGE_KEYBOARD_F6 :: 0x3F
HID_USAGE_KEYBOARD_F7 :: 0x40
HID_USAGE_KEYBOARD_F8 :: 0x41
HID_USAGE_KEYBOARD_F9 :: 0x42
HID_USAGE_KEYBOARD_F10 :: 0x43
HID_USAGE_KEYBOARD_F11 :: 0x44
HID_USAGE_KEYBOARD_F12 :: 0x45
HID_USAGE_KEYBOARD_F13 :: 0x68
HID_USAGE_KEYBOARD_F14 :: 0x69
HID_USAGE_KEYBOARD_F15 :: 0x6A
HID_USAGE_KEYBOARD_F16 :: 0x6B
HID_USAGE_KEYBOARD_F17 :: 0x6C
HID_USAGE_KEYBOARD_F18 :: 0x6D
HID_USAGE_KEYBOARD_F19 :: 0x6E
HID_USAGE_KEYBOARD_F20 :: 0x6F
HID_USAGE_KEYBOARD_F21 :: 0x70
HID_USAGE_KEYBOARD_F22 :: 0x71
HID_USAGE_KEYBOARD_F23 :: 0x72
HID_USAGE_KEYBOARD_F24 :: 0x73
HID_USAGE_KEYBOARD_RETURN :: 0x28
HID_USAGE_KEYBOARD_ESCAPE :: 0x29
HID_USAGE_KEYBOARD_DELETE :: 0x2A
HID_USAGE_KEYBOARD_PRINT_SCREEN :: 0x46
HID_USAGE_KEYBOARD_DELETE_FORWARD :: 0x4C
// Numeric Keypad
HID_USAGE_KEYBOARD_KEYPAD_1_AND_END :: 0x59
HID_USAGE_KEYBOARD_KEYPAD_0_AND_INSERT :: 0x62
HID_USAGE_LED_NUM_LOCK :: 0x01
HID_USAGE_LED_CAPS_LOCK :: 0x02
HID_USAGE_LED_SCROLL_LOCK :: 0x03
HID_USAGE_LED_COMPOSE :: 0x04
HID_USAGE_LED_KANA :: 0x05
HID_USAGE_LED_POWER :: 0x06
HID_USAGE_LED_SHIFT :: 0x07
HID_USAGE_LED_DO_NOT_DISTURB :: 0x08
HID_USAGE_LED_MUTE :: 0x09
HID_USAGE_LED_TONE_ENABLE :: 0x0A
HID_USAGE_LED_HIGH_CUT_FILTER :: 0x0B
HID_USAGE_LED_LOW_CUT_FILTER :: 0x0C
HID_USAGE_LED_EQUALIZER_ENABLE :: 0x0D
HID_USAGE_LED_SOUND_FIELD_ON :: 0x0E
HID_USAGE_LED_SURROUND_FIELD_ON :: 0x0F
HID_USAGE_LED_REPEAT :: 0x10
HID_USAGE_LED_STEREO :: 0x11
HID_USAGE_LED_SAMPLING_RATE_DETECT :: 0x12
HID_USAGE_LED_SPINNING :: 0x13
HID_USAGE_LED_CAV :: 0x14
HID_USAGE_LED_CLV :: 0x15
HID_USAGE_LED_RECORDING_FORMAT_DET :: 0x16
HID_USAGE_LED_OFF_HOOK :: 0x17
HID_USAGE_LED_RING :: 0x18
HID_USAGE_LED_MESSAGE_WAITING :: 0x19
HID_USAGE_LED_DATA_MODE :: 0x1A
HID_USAGE_LED_BATTERY_OPERATION :: 0x1B
HID_USAGE_LED_BATTERY_OK :: 0x1C
HID_USAGE_LED_BATTERY_LOW :: 0x1D
HID_USAGE_LED_SPEAKER :: 0x1E
HID_USAGE_LED_HEAD_SET :: 0x1F
HID_USAGE_LED_HOLD :: 0x20
HID_USAGE_LED_MICROPHONE :: 0x21
HID_USAGE_LED_COVERAGE :: 0x22
HID_USAGE_LED_NIGHT_MODE :: 0x23
HID_USAGE_LED_SEND_CALLS :: 0x24
HID_USAGE_LED_CALL_PICKUP :: 0x25
HID_USAGE_LED_CONFERENCE :: 0x26
HID_USAGE_LED_STAND_BY :: 0x27
HID_USAGE_LED_CAMERA_ON :: 0x28
HID_USAGE_LED_CAMERA_OFF :: 0x29
HID_USAGE_LED_ON_LINE :: 0x2A
HID_USAGE_LED_OFF_LINE :: 0x2B
HID_USAGE_LED_BUSY :: 0x2C
HID_USAGE_LED_READY :: 0x2D
HID_USAGE_LED_PAPER_OUT :: 0x2E
HID_USAGE_LED_PAPER_JAM :: 0x2F
HID_USAGE_LED_REMOTE :: 0x30
HID_USAGE_LED_FORWARD :: 0x31
HID_USAGE_LED_REVERSE :: 0x32
HID_USAGE_LED_STOP :: 0x33
HID_USAGE_LED_REWIND :: 0x34
HID_USAGE_LED_FAST_FORWARD :: 0x35
HID_USAGE_LED_PLAY :: 0x36
HID_USAGE_LED_PAUSE :: 0x37
HID_USAGE_LED_RECORD :: 0x38
HID_USAGE_LED_ERROR :: 0x39
HID_USAGE_LED_SELECTED_INDICATOR :: 0x3A
HID_USAGE_LED_IN_USE_INDICATOR :: 0x3B
HID_USAGE_LED_MULTI_MODE_INDICATOR :: 0x3C
HID_USAGE_LED_INDICATOR_ON :: 0x3D
HID_USAGE_LED_INDICATOR_FLASH :: 0x3E
HID_USAGE_LED_INDICATOR_SLOW_BLINK :: 0x3F
HID_USAGE_LED_INDICATOR_FAST_BLINK :: 0x40
HID_USAGE_LED_INDICATOR_OFF :: 0x41
HID_USAGE_LED_FLASH_ON_TIME :: 0x42
HID_USAGE_LED_SLOW_BLINK_ON_TIME :: 0x43
HID_USAGE_LED_SLOW_BLINK_OFF_TIME :: 0x44
HID_USAGE_LED_FAST_BLINK_ON_TIME :: 0x45
HID_USAGE_LED_FAST_BLINK_OFF_TIME :: 0x46
HID_USAGE_LED_INDICATOR_COLOR :: 0x47
HID_USAGE_LED_RED :: 0x48
HID_USAGE_LED_GREEN :: 0x49
HID_USAGE_LED_AMBER :: 0x4A
HID_USAGE_LED_GENERIC_INDICATOR :: 0x4B
HID_USAGE_LED_SYSTEM_SUSPEND :: 0x4C
HID_USAGE_LED_EXTERNAL_POWER :: 0x4D
HID_USAGE_TELEPHONY_PHONE :: 0x01
HID_USAGE_TELEPHONY_ANSWERING_MACHINE :: 0x02
HID_USAGE_TELEPHONY_MESSAGE_CONTROLS :: 0x03
HID_USAGE_TELEPHONY_HANDSET :: 0x04
HID_USAGE_TELEPHONY_HEADSET :: 0x05
HID_USAGE_TELEPHONY_KEYPAD :: 0x06
HID_USAGE_TELEPHONY_PROGRAMMABLE_BUTTON :: 0x07
HID_USAGE_TELEPHONY_REDIAL :: 0x24
HID_USAGE_TELEPHONY_TRANSFER :: 0x25
HID_USAGE_TELEPHONY_DROP :: 0x26
HID_USAGE_TELEPHONY_LINE :: 0x2A
HID_USAGE_TELEPHONY_RING_ENABLE :: 0x2D
HID_USAGE_TELEPHONY_SEND :: 0x31
HID_USAGE_TELEPHONY_KEYPAD_0 :: 0xB0
HID_USAGE_TELEPHONY_KEYPAD_D :: 0xBF
HID_USAGE_TELEPHONY_HOST_AVAILABLE :: 0xF1
HID_USAGE_CONSUMERCTRL :: 0x01
// channel
HID_USAGE_CONSUMER_CHANNEL_INCREMENT :: 0x9C
HID_USAGE_CONSUMER_CHANNEL_DECREMENT :: 0x9D
// transport control
HID_USAGE_CONSUMER_PLAY :: 0xB0
HID_USAGE_CONSUMER_PAUSE :: 0xB1
HID_USAGE_CONSUMER_RECORD :: 0xB2
HID_USAGE_CONSUMER_FAST_FORWARD :: 0xB3
HID_USAGE_CONSUMER_REWIND :: 0xB4
HID_USAGE_CONSUMER_SCAN_NEXT_TRACK :: 0xB5
HID_USAGE_CONSUMER_SCAN_PREV_TRACK :: 0xB6
HID_USAGE_CONSUMER_STOP :: 0xB7
HID_USAGE_CONSUMER_PLAY_PAUSE :: 0xCD
// GameDVR
HID_USAGE_CONSUMER_GAMEDVR_OPEN_GAMEBAR :: 0xD0
HID_USAGE_CONSUMER_GAMEDVR_TOGGLE_RECORD :: 0xD1
HID_USAGE_CONSUMER_GAMEDVR_RECORD_CLIP :: 0xD2
HID_USAGE_CONSUMER_GAMEDVR_SCREENSHOT :: 0xD3
HID_USAGE_CONSUMER_GAMEDVR_TOGGLE_INDICATOR :: 0xD4
HID_USAGE_CONSUMER_GAMEDVR_TOGGLE_MICROPHONE :: 0xD5
HID_USAGE_CONSUMER_GAMEDVR_TOGGLE_CAMERA :: 0xD6
HID_USAGE_CONSUMER_GAMEDVR_TOGGLE_BROADCAST :: 0xD7
// audio
HID_USAGE_CONSUMER_VOLUME :: 0xE0
HID_USAGE_CONSUMER_BALANCE :: 0xE1
HID_USAGE_CONSUMER_MUTE :: 0xE2
HID_USAGE_CONSUMER_BASS :: 0xE3
HID_USAGE_CONSUMER_TREBLE :: 0xE4
HID_USAGE_CONSUMER_BASS_BOOST :: 0xE5
HID_USAGE_CONSUMER_SURROUND_MODE :: 0xE6
HID_USAGE_CONSUMER_LOUDNESS :: 0xE7
HID_USAGE_CONSUMER_MPX :: 0xE8
HID_USAGE_CONSUMER_VOLUME_INCREMENT :: 0xE9
HID_USAGE_CONSUMER_VOLUME_DECREMENT :: 0xEA
// supplementary audio
HID_USAGE_CONSUMER_BASS_INCREMENT :: 0x152
HID_USAGE_CONSUMER_BASS_DECREMENT :: 0x153
HID_USAGE_CONSUMER_TREBLE_INCREMENT :: 0x154
HID_USAGE_CONSUMER_TREBLE_DECREMENT :: 0x155
// Application Launch
HID_USAGE_CONSUMER_AL_CONFIGURATION :: 0x183
HID_USAGE_CONSUMER_AL_EMAIL :: 0x18A
HID_USAGE_CONSUMER_AL_CALCULATOR :: 0x192
HID_USAGE_CONSUMER_AL_BROWSER :: 0x194
HID_USAGE_CONSUMER_AL_SEARCH :: 0x1C6
// Application Control
HID_USAGE_CONSUMER_AC_SEARCH :: 0x221
HID_USAGE_CONSUMER_AC_GOTO :: 0x222
HID_USAGE_CONSUMER_AC_HOME :: 0x223
HID_USAGE_CONSUMER_AC_BACK :: 0x224
HID_USAGE_CONSUMER_AC_FORWARD :: 0x225
HID_USAGE_CONSUMER_AC_STOP :: 0x226
HID_USAGE_CONSUMER_AC_REFRESH :: 0x227
HID_USAGE_CONSUMER_AC_PREVIOUS :: 0x228
HID_USAGE_CONSUMER_AC_NEXT :: 0x229
HID_USAGE_CONSUMER_AC_BOOKMARKS :: 0x22A
HID_USAGE_CONSUMER_AC_PAN :: 0x238
// Keyboard Extended Attributes (defined on consumer page in HUTRR42)
HID_USAGE_CONSUMER_EXTENDED_KEYBOARD_ATTRIBUTES_COLLECTION :: 0x2C0
HID_USAGE_CONSUMER_KEYBOARD_FORM_FACTOR :: 0x2C1
HID_USAGE_CONSUMER_KEYBOARD_KEY_TYPE :: 0x2C2
HID_USAGE_CONSUMER_KEYBOARD_PHYSICAL_LAYOUT :: 0x2C3
HID_USAGE_CONSUMER_VENDOR_SPECIFIC_KEYBOARD_PHYSICAL_LAYOUT :: 0x2C4
HID_USAGE_CONSUMER_KEYBOARD_IETF_LANGUAGE_TAG_INDEX :: 0x2C5
HID_USAGE_CONSUMER_IMPLEMENTED_KEYBOARD_INPUT_ASSIST_CONTROLS :: 0x2C6
HID_USAGE_DIGITIZER_DIGITIZER :: 0x01
HID_USAGE_DIGITIZER_PEN :: 0x02
HID_USAGE_DIGITIZER_LIGHT_PEN :: 0x03
HID_USAGE_DIGITIZER_TOUCH_SCREEN :: 0x04
HID_USAGE_DIGITIZER_TOUCH_PAD :: 0x05
HID_USAGE_DIGITIZER_WHITE_BOARD :: 0x06
HID_USAGE_DIGITIZER_COORD_MEASURING :: 0x07
HID_USAGE_DIGITIZER_3D_DIGITIZER :: 0x08
HID_USAGE_DIGITIZER_STEREO_PLOTTER :: 0x09
HID_USAGE_DIGITIZER_ARTICULATED_ARM :: 0x0A
HID_USAGE_DIGITIZER_ARMATURE :: 0x0B
HID_USAGE_DIGITIZER_MULTI_POINT :: 0x0C
HID_USAGE_DIGITIZER_FREE_SPACE_WAND :: 0x0D
HID_USAGE_DIGITIZER_HEAT_MAP :: 0x0F
HID_USAGE_DIGITIZER_STYLUS :: 0x20
HID_USAGE_DIGITIZER_PUCK :: 0x21
HID_USAGE_DIGITIZER_FINGER :: 0x22
HID_USAGE_DIGITIZER_TABLET_FUNC_KEYS :: 0x39
HID_USAGE_DIGITIZER_PROG_CHANGE_KEYS :: 0x3A
HID_USAGE_DIGITIZER_TIP_PRESSURE :: 0x30
HID_USAGE_DIGITIZER_BARREL_PRESSURE :: 0x31
HID_USAGE_DIGITIZER_IN_RANGE :: 0x32
HID_USAGE_DIGITIZER_TOUCH :: 0x33
HID_USAGE_DIGITIZER_UNTOUCH :: 0x34
HID_USAGE_DIGITIZER_TAP :: 0x35
HID_USAGE_DIGITIZER_QUALITY :: 0x36
HID_USAGE_DIGITIZER_DATA_VALID :: 0x37
HID_USAGE_DIGITIZER_TRANSDUCER_INDEX :: 0x38
HID_USAGE_DIGITIZER_BATTERY_STRENGTH :: 0x3B
HID_USAGE_DIGITIZER_INVERT :: 0x3C
HID_USAGE_DIGITIZER_X_TILT :: 0x3D
HID_USAGE_DIGITIZER_Y_TILT :: 0x3E
HID_USAGE_DIGITIZER_AZIMUTH :: 0x3F
HID_USAGE_DIGITIZER_ALTITUDE :: 0x40
HID_USAGE_DIGITIZER_TWIST :: 0x41
HID_USAGE_DIGITIZER_TIP_SWITCH :: 0x42
HID_USAGE_DIGITIZER_SECONDARY_TIP_SWITCH :: 0x43
HID_USAGE_DIGITIZER_BARREL_SWITCH :: 0x44
HID_USAGE_DIGITIZER_ERASER :: 0x45
HID_USAGE_DIGITIZER_TABLET_PICK :: 0x46
HID_USAGE_DIGITIZER_TRANSDUCER_SERIAL :: 0x5B
HID_USAGE_DIGITIZER_HEAT_MAP_PROTOCOL_VENDOR_ID :: 0x6A
HID_USAGE_DIGITIZER_HEAT_MAP_PROTOCOL_VERSION :: 0x6B
HID_USAGE_DIGITIZER_HEAT_MAP_FRAME_DATA :: 0x6C
HID_USAGE_DIGITIZER_TRANSDUCER_SERIAL_PART2 :: 0x6E
HID_USAGE_DIGITIZER_TRANSDUCER_VENDOR :: 0x91
HID_USAGE_DIGITIZER_TRANSDUCER_PRODUCT :: 0x92
HID_USAGE_DIGITIZER_TRANSDUCER_CONNECTED :: 0xA2
HID_USAGE_HAPTICS_SIMPLE_CONTROLLER :: 0x01
HID_USAGE_HAPTICS_WAVEFORM_LIST :: 0x10
HID_USAGE_HAPTICS_DURATION_LIST :: 0x11
HID_USAGE_HAPTICS_AUTO_TRIGGER :: 0x20
HID_USAGE_HAPTICS_MANUAL_TRIGGER :: 0x21
HID_USAGE_HAPTICS_AUTO_ASSOCIATED_CONTROL :: 0x22
HID_USAGE_HAPTICS_INTENSITY :: 0x23
HID_USAGE_HAPTICS_REPEAT_COUNT :: 0x24
HID_USAGE_HAPTICS_RETRIGGER_PERIOD :: 0x25
HID_USAGE_HAPTICS_WAVEFORM_VENDOR_PAGE :: 0x26
HID_USAGE_HAPTICS_WAVEFORM_VENDOR_ID :: 0x27
HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME :: 0x28
// Waveform types
HID_USAGE_HAPTICS_WAVEFORM_BEGIN :: 0x1000
HID_USAGE_HAPTICS_WAVEFORM_STOP :: 0x1001
HID_USAGE_HAPTICS_WAVEFORM_NULL :: 0x1002
HID_USAGE_HAPTICS_WAVEFORM_CLICK :: 0x1003
HID_USAGE_HAPTICS_WAVEFORM_BUZZ :: 0x1004
HID_USAGE_HAPTICS_WAVEFORM_RUMBLE :: 0x1005
HID_USAGE_HAPTICS_WAVEFORM_PRESS :: 0x1006
HID_USAGE_HAPTICS_WAVEFORM_RELEASE :: 0x1007
HID_USAGE_HAPTICS_WAVEFORM_END :: 0x1FFF
HID_USAGE_HAPTICS_WAVEFORM_VENDOR_BEGIN :: 0x2000
HID_USAGE_HAPTICS_WAVEFORM_VENDOR_END :: 0x2FFF
HID_USAGE_ALPHANUMERIC_ALPHANUMERIC_DISPLAY :: 0x01
HID_USAGE_ALPHANUMERIC_BITMAPPED_DISPLAY :: 0x02
HID_USAGE_ALPHANUMERIC_DISPLAY_ATTRIBUTES_REPORT :: 0x20
HID_USAGE_ALPHANUMERIC_DISPLAY_CONTROL_REPORT :: 0x24
HID_USAGE_ALPHANUMERIC_CHARACTER_REPORT :: 0x2B
HID_USAGE_ALPHANUMERIC_DISPLAY_STATUS :: 0x2D
HID_USAGE_ALPHANUMERIC_CURSOR_POSITION_REPORT :: 0x32
HID_USAGE_ALPHANUMERIC_FONT_REPORT :: 0x3B
HID_USAGE_ALPHANUMERIC_FONT_DATA :: 0x3C
HID_USAGE_ALPHANUMERIC_CHARACTER_ATTRIBUTE :: 0x48
HID_USAGE_ALPHANUMERIC_PALETTE_REPORT :: 0x85
HID_USAGE_ALPHANUMERIC_PALETTE_DATA :: 0x88
HID_USAGE_ALPHANUMERIC_BLIT_REPORT :: 0x8A
HID_USAGE_ALPHANUMERIC_BLIT_DATA :: 0x8F
HID_USAGE_ALPHANUMERIC_SOFT_BUTTON :: 0x90
HID_USAGE_ALPHANUMERIC_ASCII_CHARACTER_SET :: 0x21
HID_USAGE_ALPHANUMERIC_DATA_READ_BACK :: 0x22
HID_USAGE_ALPHANUMERIC_FONT_READ_BACK :: 0x23
HID_USAGE_ALPHANUMERIC_CLEAR_DISPLAY :: 0x25
HID_USAGE_ALPHANUMERIC_DISPLAY_ENABLE :: 0x26
HID_USAGE_ALPHANUMERIC_SCREEN_SAVER_DELAY :: 0x27
HID_USAGE_ALPHANUMERIC_SCREEN_SAVER_ENABLE :: 0x28
HID_USAGE_ALPHANUMERIC_VERTICAL_SCROLL :: 0x29
HID_USAGE_ALPHANUMERIC_HORIZONTAL_SCROLL :: 0x2A
HID_USAGE_ALPHANUMERIC_DISPLAY_DATA :: 0x2C
HID_USAGE_ALPHANUMERIC_STATUS_NOT_READY :: 0x2E
HID_USAGE_ALPHANUMERIC_STATUS_READY :: 0x2F
HID_USAGE_ALPHANUMERIC_ERR_NOT_A_LOADABLE_CHARACTER :: 0x30
HID_USAGE_ALPHANUMERIC_ERR_FONT_DATA_CANNOT_BE_READ :: 0x31
HID_USAGE_ALPHANUMERIC_ROW :: 0x33
HID_USAGE_ALPHANUMERIC_COLUMN :: 0x34
HID_USAGE_ALPHANUMERIC_ROWS :: 0x35
HID_USAGE_ALPHANUMERIC_COLUMNS :: 0x36
HID_USAGE_ALPHANUMERIC_CURSOR_PIXEL_POSITIONING :: 0x37
HID_USAGE_ALPHANUMERIC_CURSOR_MODE :: 0x38
HID_USAGE_ALPHANUMERIC_CURSOR_ENABLE :: 0x39
HID_USAGE_ALPHANUMERIC_CURSOR_BLINK :: 0x3A
HID_USAGE_ALPHANUMERIC_CHAR_WIDTH :: 0x3D
HID_USAGE_ALPHANUMERIC_CHAR_HEIGHT :: 0x3E
HID_USAGE_ALPHANUMERIC_CHAR_SPACING_HORIZONTAL :: 0x3F
HID_USAGE_ALPHANUMERIC_CHAR_SPACING_VERTICAL :: 0x40
HID_USAGE_ALPHANUMERIC_UNICODE_CHAR_SET :: 0x41
HID_USAGE_ALPHANUMERIC_FONT_7_SEGMENT :: 0x42
HID_USAGE_ALPHANUMERIC_7_SEGMENT_DIRECT_MAP :: 0x43
HID_USAGE_ALPHANUMERIC_FONT_14_SEGMENT :: 0x44
HID_USAGE_ALPHANUMERIC_14_SEGMENT_DIRECT_MAP :: 0x45
HID_USAGE_ALPHANUMERIC_DISPLAY_BRIGHTNESS :: 0x46
HID_USAGE_ALPHANUMERIC_DISPLAY_CONTRAST :: 0x47
HID_USAGE_ALPHANUMERIC_ATTRIBUTE_READBACK :: 0x49
HID_USAGE_ALPHANUMERIC_ATTRIBUTE_DATA :: 0x4A
HID_USAGE_ALPHANUMERIC_CHAR_ATTR_ENHANCE :: 0x4B
HID_USAGE_ALPHANUMERIC_CHAR_ATTR_UNDERLINE :: 0x4C
HID_USAGE_ALPHANUMERIC_CHAR_ATTR_BLINK :: 0x4D
HID_USAGE_ALPHANUMERIC_BITMAP_SIZE_X :: 0x80
HID_USAGE_ALPHANUMERIC_BITMAP_SIZE_Y :: 0x81
HID_USAGE_ALPHANUMERIC_BIT_DEPTH_FORMAT :: 0x83
HID_USAGE_ALPHANUMERIC_DISPLAY_ORIENTATION :: 0x84
HID_USAGE_ALPHANUMERIC_PALETTE_DATA_SIZE :: 0x86
HID_USAGE_ALPHANUMERIC_PALETTE_DATA_OFFSET :: 0x87
HID_USAGE_ALPHANUMERIC_BLIT_RECTANGLE_X1 :: 0x8B
HID_USAGE_ALPHANUMERIC_BLIT_RECTANGLE_Y1 :: 0x8C
HID_USAGE_ALPHANUMERIC_BLIT_RECTANGLE_X2 :: 0x8D
HID_USAGE_ALPHANUMERIC_BLIT_RECTANGLE_Y2 :: 0x8E
HID_USAGE_ALPHANUMERIC_SOFT_BUTTON_ID :: 0x91
HID_USAGE_ALPHANUMERIC_SOFT_BUTTON_SIDE :: 0x92
HID_USAGE_ALPHANUMERIC_SOFT_BUTTON_OFFSET1 :: 0x93
HID_USAGE_ALPHANUMERIC_SOFT_BUTTON_OFFSET2 :: 0x94
HID_USAGE_ALPHANUMERIC_SOFT_BUTTON_REPORT :: 0x95
HID_USAGE_LAMPARRAY :: 0x01
HID_USAGE_LAMPARRAY_ATTRBIUTES_REPORT :: 0x02
HID_USAGE_LAMPARRAY_LAMP_COUNT :: 0x03
HID_USAGE_LAMPARRAY_BOUNDING_BOX_WIDTH_IN_MICROMETERS :: 0x04
HID_USAGE_LAMPARRAY_BOUNDING_BOX_HEIGHT_IN_MICROMETERS :: 0x05
HID_USAGE_LAMPARRAY_BOUNDING_BOX_DEPTH_IN_MICROMETERS :: 0x06
HID_USAGE_LAMPARRAY_KIND :: 0x07
HID_USAGE_LAMPARRAY_MIN_UPDATE_INTERVAL_IN_MICROSECONDS :: 0x08
// 0x09 - 0x1F Reserved
HID_USAGE_LAMPARRAY_LAMP_ATTRIBUTES_REQUEST_REPORT :: 0x20
HID_USAGE_LAMPARRAY_LAMP_ID :: 0x21
HID_USAGE_LAMPARRAY_LAMP_ATTRIBUTES_RESPONSE_REPORT :: 0x22
HID_USAGE_LAMPARRAY_POSITION_X_IN_MICROMETERS :: 0x23
HID_USAGE_LAMPARRAY_POSITION_Y_IN_MICROMETERS :: 0x24
HID_USAGE_LAMPARRAY_POSITION_Z_IN_MICROMETERS :: 0x25
HID_USAGE_LAMPARRAY_LAMP_PURPOSES :: 0x26
HID_USAGE_LAMPARRAY_UPDATE_LATENCY_IN_MICROSECONDS :: 0x27
HID_USAGE_LAMPARRAY_RED_LEVEL_COUNT :: 0x28
HID_USAGE_LAMPARRAY_GREEN_LEVEL_COUNT :: 0x29
HID_USAGE_LAMPARRAY_BLUE_LEVEL_COUNT :: 0x2A
HID_USAGE_LAMPARRAY_INTENSITY_LEVEL_COUNT :: 0x2B
HID_USAGE_LAMPARRAY_IS_PROGRAMMABLE :: 0x2C
HID_USAGE_LAMPARRAY_INPUT_BINDING :: 0x2D
// 0x2E - 0x4F Reserved
HID_USAGE_LAMPARRAY_LAMP_MULTI_UPDATE_REPORT :: 0x50
HID_USAGE_LAMPARRAY_LAMP_RED_UPDATE_CHANNEL :: 0x51
HID_USAGE_LAMPARRAY_LAMP_GREEN_UPDATE_CHANNEL :: 0x52
HID_USAGE_LAMPARRAY_LAMP_BLUE_UPDATE_CHANNEL :: 0x53
HID_USAGE_LAMPARRAY_LAMP_INTENSITY_UPDATE_CHANNEL :: 0x54
HID_USAGE_LAMPARRAY_LAMP_UPDATE_FLAGS :: 0x55
// 0x55 - 0x5F Reserved
HID_USAGE_LAMPARRAY_LAMP_RANGE_UPDATE_REPORT :: 0x60
HID_USAGE_LAMPARRAY_LAMP_ID_START :: 0x61
HID_USAGE_LAMPARRAY_LAMP_ID_END :: 0x62
// 0x63 - 0x6F Reserved
HID_USAGE_LAMPARRAY_CONTROL_REPORT :: 0x70
HID_USAGE_LAMPARRAY_AUTONOMOUS_MODE :: 0x71
HID_USAGE_CAMERA_AUTO_FOCUS :: 0x20
HID_USAGE_CAMERA_SHUTTER :: 0x21
HID_USAGE_MS_BTH_HF_DIALNUMBER :: 0x21
HID_USAGE_MS_BTH_HF_DIALMEMORY :: 0x22
Regular → Executable
+111 -149
View File
@@ -38,17 +38,36 @@ foreign kernel32 {
lpNumberOfCharsWritten: LPDWORD,
lpReserved: LPVOID) -> BOOL ---
PeekConsoleInputW :: proc(hConsoleInput: HANDLE,
lpBuffer: ^INPUT_RECORD,
nLength: DWORD,
lpNumberOfEventsRead: LPDWORD) -> BOOL ---
ReadConsoleInputW :: proc(hConsoleInput: HANDLE,
lpBuffer: ^INPUT_RECORD,
nLength: DWORD,
lpNumberOfEventsRead: LPDWORD) -> BOOL ---
// https://learn.microsoft.com/en-us/windows/console/getnumberofconsoleinputevents
GetNumberOfConsoleInputEvents :: proc(hConsoleInput: HANDLE, lpcNumberOfEvents: LPDWORD) -> BOOL ---
GetConsoleMode :: proc(hConsoleHandle: HANDLE,
lpMode: LPDWORD) -> BOOL ---
SetConsoleMode :: proc(hConsoleHandle: HANDLE,
dwMode: DWORD) -> BOOL ---
SetConsoleCursorPosition :: proc(hConsoleHandle: HANDLE,
dwCursorPosition: COORD) -> BOOL ---
dwCursorPosition: COORD) -> BOOL ---
SetConsoleTextAttribute :: proc(hConsoleOutput: HANDLE,
wAttributes: WORD) -> BOOL ---
wAttributes: WORD) -> BOOL ---
GetConsoleCP :: proc() -> UINT ---
SetConsoleCP :: proc(wCodePageID: UINT) -> BOOL ---
GetConsoleOutputCP :: proc() -> UINT ---
SetConsoleOutputCP :: proc(wCodePageID: UINT) -> BOOL ---
FlushConsoleInputBuffer :: proc(hConsoleInput: HANDLE) -> BOOL ---
GetFileInformationByHandle :: proc(hFile: HANDLE, lpFileInformation: LPBY_HANDLE_FILE_INFORMATION) -> BOOL ---
SetHandleInformation :: proc(hObject: HANDLE,
dwMask: DWORD,
dwFlags: DWORD) -> BOOL ---
@@ -64,6 +83,7 @@ foreign kernel32 {
RemoveVectoredContinueHandler :: proc(Handle: LPVOID) -> DWORD ---
RaiseException :: proc(dwExceptionCode, dwExceptionFlags, nNumberOfArguments: DWORD, lpArguments: ^ULONG_PTR) -> ! ---
SetUnhandledExceptionFilter :: proc(lpTopLevelExceptionFilter: LPTOP_LEVEL_EXCEPTION_FILTER) -> LPTOP_LEVEL_EXCEPTION_FILTER ---
CreateHardLinkW :: proc(lpSymlinkFileName: LPCWSTR,
lpTargetFileName: LPCWSTR,
@@ -84,6 +104,12 @@ foreign kernel32 {
RemoveDirectoryW :: proc(lpPathName: LPCWSTR) -> BOOL ---
SetFileAttributesW :: proc(lpFileName: LPCWSTR, dwFileAttributes: DWORD) -> BOOL ---
SetLastError :: proc(dwErrCode: DWORD) ---
GetCommTimeouts :: proc(handle: HANDLE, timeouts: ^COMMTIMEOUTS) -> BOOL ---
SetCommTimeouts :: proc(handle: HANDLE, timeouts: ^COMMTIMEOUTS) -> BOOL ---
ClearCommError :: proc(hFile: HANDLE, lpErrors: ^Com_Error, lpStat: ^COMSTAT) -> BOOL ---
GetCommState :: proc(handle: HANDLE, dcb: ^DCB) -> BOOL ---
SetCommState :: proc(handle: HANDLE, dcb: ^DCB) -> BOOL ---
GetCommPorts :: proc(lpPortNumbers: PULONG, uPortNumbersCount: ULONG, puPortNumbersFound: PULONG) -> ULONG ---
GetCommandLineW :: proc() -> LPCWSTR ---
GetTempPathW :: proc(nBufferLength: DWORD, lpBuffer: LPCWSTR) -> DWORD ---
GetCurrentProcess :: proc() -> HANDLE ---
@@ -207,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,
@@ -412,6 +444,7 @@ foreign kernel32 {
LoadLibraryW :: proc(c_str: LPCWSTR) -> HMODULE ---
FreeLibrary :: proc(h: HMODULE) -> BOOL ---
GetProcAddress :: proc(h: HMODULE, c_str: LPCSTR) -> rawptr ---
LoadLibraryExW :: proc(c_str: LPCWSTR, file: HANDLE, flags: LoadLibraryEx_Flags) -> HMODULE ---
GetFullPathNameW :: proc(filename: LPCWSTR, buffer_length: DWORD, buffer: LPCWSTR, file_part: ^LPCWSTR) -> DWORD ---
@@ -429,6 +462,8 @@ foreign kernel32 {
DisconnectNamedPipe :: proc(hNamedPipe: HANDLE) -> BOOL ---
WaitNamedPipeW :: proc(lpNamedPipeName: LPCWSTR, nTimeOut: DWORD) -> BOOL ---
AllocConsole :: proc() -> BOOL ---
AttachConsole :: proc(dwProcessId: DWORD) -> BOOL ---
SetConsoleCtrlHandler :: proc(HandlerRoutine: PHANDLER_ROUTINE, Add: BOOL) -> BOOL ---
GenerateConsoleCtrlEvent :: proc(dwCtrlEvent: DWORD, dwProcessGroupId: DWORD) -> BOOL ---
FreeConsole :: proc() -> BOOL ---
@@ -451,15 +486,19 @@ foreign kernel32 {
// [MS-Docs](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setfilecompletionnotificationmodes)
SetFileCompletionNotificationModes :: proc(FileHandle: HANDLE, Flags: u8) -> BOOL ---
// [MS-Docs](https://learn.microsoft.com/en-us/windows/win32/api/ioapiset/nf-ioapiset-createiocompletionport)
CreateIoCompletionPort :: proc(FileHandle: HANDLE, ExistingCompletionPort: HANDLE, CompletionKey: ^uintptr, NumberOfConcurrentThreads: DWORD) -> HANDLE ---
CreateIoCompletionPort :: proc(FileHandle: HANDLE, ExistingCompletionPort: HANDLE, CompletionKey: ULONG_PTR, NumberOfConcurrentThreads: DWORD) -> HANDLE ---
//[MS-Docs](https://learn.microsoft.com/en-us/windows/win32/api/ioapiset/nf-ioapiset-getqueuedcompletionstatus)
GetQueuedCompletionStatus :: proc(CompletionPort: HANDLE, lpNumberOfBytesTransferred: ^DWORD, lpCompletionKey: uintptr, lpOverlapped: ^^OVERLAPPED, dwMilliseconds: DWORD) -> BOOL ---
GetQueuedCompletionStatus :: proc(CompletionPort: HANDLE, lpNumberOfBytesTransferred: ^DWORD, lpCompletionKey: PULONG_PTR, lpOverlapped: ^^OVERLAPPED, dwMilliseconds: DWORD) -> BOOL ---
// [MS-Docs](https://learn.microsoft.com/en-us/windows/win32/api/ioapiset/nf-ioapiset-getqueuedcompletionstatusex)
GetQueuedCompletionStatusEx :: proc(CompletionPort: HANDLE, lpCompletionPortEntries: ^OVERLAPPED_ENTRY, ulCount: c_ulong, ulNumEntriesRemoved: ^c_ulong, dwMilliseconds: DWORD, fAlertable: BOOL) -> BOOL ---
// [MS-Docs](https://learn.microsoft.com/en-us/windows/win32/api/ioapiset/nf-ioapiset-postqueuedcompletionstatus)
PostQueuedCompletionStatus :: proc(CompletionPort: HANDLE, dwNumberOfBytesTransferred: DWORD, dwCompletionKey: c_ulong, lpOverlapped: ^OVERLAPPED) -> BOOL ---
// [MS-Docs](https://learn.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-gethandleinformation)
GetHandleInformation :: proc(hObject: HANDLE, lpdwFlags: ^DWORD) -> BOOL ---
RtlCaptureStackBackTrace :: proc(FramesToSkip: ULONG, FramesToCapture: ULONG, BackTrace: [^]PVOID, BackTraceHash: PULONG) -> USHORT ---
GetSystemPowerStatus :: proc(lpSystemPowerStatus: ^SYSTEM_POWER_STATUS) -> BOOL ---
}
DEBUG_PROCESS :: 0x00000001
@@ -510,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
@@ -1005,150 +1083,8 @@ foreign kernel32 {
HandlerRoutine :: proc "system" (dwCtrlType: DWORD) -> BOOL
PHANDLER_ROUTINE :: HandlerRoutine
DCB_Config :: struct {
fParity: bool,
fOutxCtsFlow: bool,
fOutxDsrFlow: bool,
fDtrControl: DTR_Control,
fDsrSensitivity: bool,
fTXContinueOnXoff: bool,
fOutX: bool,
fInX: bool,
fErrorChar: bool,
fNull: bool,
fRtsControl: RTS_Control,
fAbortOnError: bool,
BaudRate: DWORD,
ByteSize: BYTE,
Parity: Parity,
StopBits: Stop_Bits,
XonChar: byte,
XoffChar: byte,
ErrorChar: byte,
EvtChar: byte,
}
DTR_Control :: enum byte {
Disable = 0,
Enable = 1,
Handshake = 2,
}
RTS_Control :: enum byte {
Disable = 0,
Enable = 1,
Handshake = 2,
Toggle = 3,
}
Parity :: enum byte {
None = 0,
Odd = 1,
Even = 2,
Mark = 3,
Space = 4,
}
Stop_Bits :: enum byte {
One = 0,
One_And_A_Half = 1,
Two = 2,
}
// A helper procedure to set the values of a DCB structure.
init_dcb_with_config :: proc "contextless" (dcb: ^DCB, config: DCB_Config) {
out: u32
// NOTE(tetra, 2022-09-21): On both Clang 14 on Windows, and MSVC, the bits in the bitfield
// appear to be defined from LSB to MSB order.
// i.e: `fBinary` (the first bitfield in the C source) is the LSB in the `settings` u32.
out |= u32(1) << 0 // fBinary must always be true on Windows.
out |= u32(config.fParity) << 1
out |= u32(config.fOutxCtsFlow) << 2
out |= u32(config.fOutxDsrFlow) << 3
out |= u32(config.fDtrControl) << 4
out |= u32(config.fDsrSensitivity) << 6
out |= u32(config.fTXContinueOnXoff) << 7
out |= u32(config.fOutX) << 8
out |= u32(config.fInX) << 9
out |= u32(config.fErrorChar) << 10
out |= u32(config.fNull) << 11
out |= u32(config.fRtsControl) << 12
out |= u32(config.fAbortOnError) << 14
dcb.settings = out
dcb.BaudRate = config.BaudRate
dcb.ByteSize = config.ByteSize
dcb.Parity = config.Parity
dcb.StopBits = config.StopBits
dcb.XonChar = config.XonChar
dcb.XoffChar = config.XoffChar
dcb.ErrorChar = config.ErrorChar
dcb.EvtChar = config.EvtChar
dcb.DCBlength = size_of(DCB)
}
get_dcb_config :: proc "contextless" (dcb: DCB) -> (config: DCB_Config) {
config.fParity = bool((dcb.settings >> 1) & 0x01)
config.fOutxCtsFlow = bool((dcb.settings >> 2) & 0x01)
config.fOutxDsrFlow = bool((dcb.settings >> 3) & 0x01)
config.fDtrControl = DTR_Control((dcb.settings >> 4) & 0x02)
config.fDsrSensitivity = bool((dcb.settings >> 6) & 0x01)
config.fTXContinueOnXoff = bool((dcb.settings >> 7) & 0x01)
config.fOutX = bool((dcb.settings >> 8) & 0x01)
config.fInX = bool((dcb.settings >> 9) & 0x01)
config.fErrorChar = bool((dcb.settings >> 10) & 0x01)
config.fNull = bool((dcb.settings >> 11) & 0x01)
config.fRtsControl = RTS_Control((dcb.settings >> 12) & 0x02)
config.fAbortOnError = bool((dcb.settings >> 14) & 0x01)
config.BaudRate = dcb.BaudRate
config.ByteSize = dcb.ByteSize
config.Parity = dcb.Parity
config.StopBits = dcb.StopBits
config.XonChar = dcb.XonChar
config.XoffChar = dcb.XoffChar
config.ErrorChar = dcb.ErrorChar
config.EvtChar = dcb.EvtChar
return
}
// NOTE(tetra): See get_dcb_config() and init_dcb_with_config() for help with initializing this.
DCB :: struct {
DCBlength: DWORD, // NOTE(tetra): Must be set to size_of(DCB).
BaudRate: DWORD,
settings: u32, // NOTE(tetra): These are bitfields in the C struct.
wReserved: WORD,
XOnLim: WORD,
XOffLim: WORD,
ByteSize: BYTE,
Parity: Parity,
StopBits: Stop_Bits,
XonChar: byte,
XoffChar: byte,
ErrorChar: byte,
EofChar: byte,
EvtChar: byte,
wReserved1: WORD,
}
@(default_calling_convention="system")
foreign kernel32 {
GetCommState :: proc(handle: HANDLE, dcb: ^DCB) -> BOOL ---
SetCommState :: proc(handle: HANDLE, dcb: ^DCB) -> BOOL ---
}
// NOTE(Jeroen, 2024-06-13): As Odin now supports bit_fields, we no longer need
// a helper procedure. `init_dcb_with_config` and `get_dcb_config` have been removed.
LPFIBER_START_ROUTINE :: #type proc "system" (lpFiberParameter: LPVOID)
@@ -1206,6 +1142,30 @@ SYSTEM_LOGICAL_PROCESSOR_INFORMATION :: struct {
DummyUnion: DUMMYUNIONNAME_u,
}
SYSTEM_POWER_STATUS :: struct {
ACLineStatus: AC_Line_Status,
BatteryFlag: Battery_Flags,
BatteryLifePercent: BYTE,
SystemStatusFlag: BYTE,
BatteryLifeTime: DWORD,
BatteryFullLifeTime: DWORD,
}
AC_Line_Status :: enum BYTE {
Offline = 0,
Online = 1,
Unknown = 255,
}
Battery_Flag :: enum BYTE {
High = 0,
Low = 1,
Critical = 2,
Charging = 3,
No_Battery = 7,
}
Battery_Flags :: bit_set[Battery_Flag; BYTE]
/* Global Memory Flags */
GMEM_FIXED :: 0x0000
GMEM_MOVEABLE :: 0x0002
@@ -1224,3 +1184,5 @@ GMEM_INVALID_HANDLE :: 0x8000
GHND :: (GMEM_MOVEABLE | GMEM_ZEROINIT)
GPTR :: (GMEM_FIXED | GMEM_ZEROINIT)
LPTOP_LEVEL_EXCEPTION_FILTER :: PVECTORED_EXCEPTION_HANDLER
+106
View File
@@ -6,4 +6,110 @@ foreign import ntdll_lib "system:ntdll.lib"
@(default_calling_convention="system")
foreign ntdll_lib {
RtlGetVersion :: proc(lpVersionInformation: ^OSVERSIONINFOEXW) -> NTSTATUS ---
NtQueryInformationProcess :: proc(
ProcessHandle: HANDLE,
ProcessInformationClass: PROCESS_INFO_CLASS,
ProcessInformation: rawptr,
ProcessInformationLength: u32,
ReturnLength: ^u32,
) -> u32 ---
}
PROCESS_INFO_CLASS :: enum i32 {
ProcessBasicInformation = 0,
ProcessDebugPort = 7,
ProcessWow64Information = 26,
ProcessImageFileName = 27,
ProcessBreakOnTermination = 29,
ProcessTelemetryIdInformation = 64,
ProcessSubsystemInformation = 75,
}
PROCESS_BASIC_INFORMATION :: struct {
ExitStatus: NTSTATUS,
PebBaseAddress: ^PEB,
AffinityMask: ULONG_PTR,
BasePriority: KPRIORITY,
UniqueProcessId: ULONG_PTR,
InheritedFromUniqueProcessId: ULONG_PTR,
}
KPRIORITY :: rawptr
PPS_POST_PROCESS_INIT_ROUTINE :: proc "system" ()
PEB :: struct {
_: [2]u8,
BeingDebugged: u8,
_: [1]u8,
_: [2]rawptr,
Ldr: ^PEB_LDR_DATA,
ProcessParameters: ^RTL_USER_PROCESS_PARAMETERS,
_: [104]u8,
_: [52]rawptr,
PostProcessInitRoutine: PPS_POST_PROCESS_INIT_ROUTINE,
_: [128]u8,
_: [1]rawptr,
SessionId: u32,
}
PEB_LDR_DATA :: struct {
_: [8]u8,
_: [3]rawptr,
InMemoryOrderModuleList: LIST_ENTRY,
}
RTL_USER_PROCESS_PARAMETERS :: struct {
MaximumLength: u32,
Length: u32,
Flags: u32,
DebugFlags: u32,
ConsoleHandle: rawptr,
ConsoleFlags: u32,
StdInputHandle: rawptr,
StdOutputHandle: rawptr,
StdErrorHandle: rawptr,
CurrentDirectoryPath: UNICODE_STRING,
CurrentDirectoryHandle: rawptr,
DllPath: UNICODE_STRING,
ImagePathName: UNICODE_STRING,
CommandLine: UNICODE_STRING,
Environment: rawptr,
StartingPositionLeft: u32,
StartingPositionTop: u32,
Width: u32,
Height: u32,
CharWidth: u32,
CharHeight: u32,
ConsoleTextAttributes: u32,
WindowFlags: u32,
ShowWindowFlags: u32,
WindowTitle: UNICODE_STRING,
DesktopName: UNICODE_STRING,
ShellInfo: UNICODE_STRING,
RuntimeData: UNICODE_STRING,
DLCurrentDirectory: [32]RTL_DRIVE_LETTER_CURDIR,
EnvironmentSize: u32,
}
RTL_DRIVE_LETTER_CURDIR :: struct {
Flags: u16,
Length: u16,
TimeStamp: u32,
DosPath: UNICODE_STRING,
}
LIST_ENTRY :: struct {
Flink: ^LIST_ENTRY,
Blink: ^LIST_ENTRY,
}
+9 -7
View File
@@ -7,13 +7,13 @@ foreign import "system:Ole32.lib"
/*
typedef enum tagCOINIT
{
COINIT_APARTMENTTHREADED = 0x2, // Apartment model
COINIT_APARTMENTTHREADED = 0x2, // Apartment model
#if (_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM) // DCOM
// These constants are only valid on Windows NT 4.0
COINIT_MULTITHREADED = COINITBASE_MULTITHREADED,
COINIT_DISABLE_OLE1DDE = 0x4, // Don't use DDE for Ole1 support.
COINIT_SPEED_OVER_MEMORY = 0x8, // Trade memory for speed.
// These constants are only valid on Windows NT 4.0
COINIT_MULTITHREADED = COINITBASE_MULTITHREADED,
COINIT_DISABLE_OLE1DDE = 0x4, // Don't use DDE for Ole1 support.
COINIT_SPEED_OVER_MEMORY = 0x8, // Trade memory for speed.
#endif // DCOM
} COINIT;
*/
@@ -26,9 +26,11 @@ COINIT :: enum DWORD {
}
IUnknown :: struct {
using Vtbl: ^IUnknownVtbl,
using _iunknown_vtable: ^IUnknown_VTable,
}
IUnknownVtbl :: struct {
IUnknownVtbl :: IUnknown_VTable
IUnknown_VTable :: struct {
QueryInterface: proc "system" (This: ^IUnknown, riid: REFIID, ppvObject: ^rawptr) -> HRESULT,
AddRef: proc "system" (This: ^IUnknown) -> ULONG,
Release: proc "system" (This: ^IUnknown) -> ULONG,
+8 -1
View File
@@ -5,7 +5,7 @@ foreign import shell32 "system:Shell32.lib"
@(default_calling_convention="system")
foreign shell32 {
CommandLineToArgvW :: proc(cmd_list: wstring, num_args: ^c_int) -> ^wstring ---
CommandLineToArgvW :: proc(cmd_list: wstring, num_args: ^c_int) -> [^]wstring ---
ShellExecuteW :: proc(
hwnd: HWND,
lpOperation: LPCWSTR,
@@ -30,6 +30,11 @@ foreign shell32 {
SHGetKnownFolderIDList :: proc(rfid: REFKNOWNFOLDERID, dwFlags: /* KNOWN_FOLDER_FLAG */ DWORD, hToken: HANDLE, ppidl: rawptr) -> HRESULT ---
SHSetKnownFolderPath :: proc(rfid: REFKNOWNFOLDERID, dwFlags: /* KNOWN_FOLDER_FLAG */ DWORD, hToken: HANDLE, pszPath: PCWSTR ) -> HRESULT ---
SHGetKnownFolderPath :: proc(rfid: REFKNOWNFOLDERID, dwFlags: /* KNOWN_FOLDER_FLAG */ DWORD, hToken: HANDLE, ppszPath: ^LPWSTR) -> HRESULT ---
DragAcceptFiles :: proc(hWnd: HWND, fAccept: BOOL) ---
DragQueryPoint :: proc(hDrop: HDROP, ppt: ^POINT) -> BOOL ---
DragQueryFileW :: proc(hDrop: HDROP, iFile: UINT, lpszFile: LPWSTR, cch: UINT) -> UINT ---
DragFinish :: proc(hDrop: HDROP) --- // @New
}
APPBARDATA :: struct {
@@ -67,6 +72,8 @@ ABE_BOTTOM :: 3
KNOWNFOLDERID :: GUID
REFKNOWNFOLDERID :: ^KNOWNFOLDERID
HDROP :: HANDLE
KNOWN_FOLDER_FLAG :: enum u32 {
DEFAULT = 0x00000000,
+101
View File
@@ -0,0 +1,101 @@
//+build windows
package sys_windows
foreign import kernel32 "system:Kernel32.lib"
@(default_calling_convention="system")
foreign kernel32 {
CreateToolhelp32Snapshot :: proc (dwFlags: DWORD, th32ProcessID: DWORD) -> HANDLE ---
Process32FirstW :: proc (hSnapshot: HANDLE, lppe: LPPROCESSENTRY32W) -> BOOL ---
Process32NextW :: proc (hSnapshot: HANDLE, lppe: LPPROCESSENTRY32W) -> BOOL ---
Thread32First :: proc (hSnapshot: HANDLE, lpte: LPTHREADENTRY32) -> BOOL ---
Thread32Next :: proc (hSnapshot: HANDLE, lpte: LPTHREADENTRY32) -> BOOL ---
Module32FirstW :: proc (hSnapshot: HANDLE, lpme: LPMODULEENTRY32W) -> BOOL ---
Module32NextW :: proc (hSnapshot: HANDLE, lpme: LPMODULEENTRY32W) -> BOOL ---
Heap32ListFirst :: proc (hSnapshot: HANDLE, lphl: LPHEAPLIST32) -> BOOL ---
Heap32ListNext :: proc (hSnapshot: HANDLE, lphl: LPHEAPLIST32) -> BOOL ---
Heap32First :: proc (lphe: LPHEAPENTRY32, th32ProcessID: DWORD, th32HeapID: ULONG_PTR) -> BOOL ---
Heap32Next :: proc (lphe: LPHEAPENTRY32) -> BOOL ---
Toolhelp32ReadProcessMemory :: proc (
th32ProcessID: DWORD,
lpBaseAddress: LPCVOID,
lpBuffer: LPVOID,
cbRead: SIZE_T,
lpNumberOfBytesRead: ^SIZE_T,
) -> BOOL ---
}
MAX_MODULE_NAME32 :: 255
TH32CS_INHERIT :: 0x80000000
TH32CS_SNAPHEAPLIST :: 0x00000001
TH32CS_SNAPPROCESS :: 0x00000002
TH32CS_SNAPTHREAD :: 0x00000004
TH32CS_SNAPMODULE :: 0x00000008
TH32CS_SNAPMODULE32 :: 0x00000010
TH32CS_SNAPALL :: TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE
PROCESSENTRY32W :: struct {
dwSize: DWORD,
cntUsage: DWORD,
th32ProcessID: DWORD,
th32DefaultHeapID: ULONG_PTR,
th32ModuleID: DWORD,
cntThreads: DWORD,
th32ParentProcessID: DWORD,
pcPriClassBase: LONG,
dwFlags: DWORD,
szExeFile: [MAX_PATH]WCHAR,
}
LPPROCESSENTRY32W :: ^PROCESSENTRY32W
THREADENTRY32 :: struct {
dwSize: DWORD,
cntUsage: DWORD,
th32ThreadID: DWORD,
th32OwnerProcessID: DWORD,
tpBasePri: LONG,
tpDeltaPri: LONG,
dwFlags: DWORD,
}
LPTHREADENTRY32 :: ^THREADENTRY32
MODULEENTRY32W :: struct {
dwSize: DWORD,
th32ModuleID: DWORD,
th32ProcessID: DWORD,
GlblcntUsage: DWORD,
ProccntUsage: DWORD,
modBaseAddr: ^BYTE,
modBaseSize: DWORD,
hModule: HMODULE,
szModule: [MAX_MODULE_NAME32 + 1]WCHAR,
szExePath: [MAX_PATH]WCHAR,
}
LPMODULEENTRY32W :: ^MODULEENTRY32W
HEAPLIST32 :: struct {
dwSize: SIZE_T,
th32ProcessID: DWORD,
th32HeapID: ULONG_PTR,
dwFlags: DWORD,
}
LPHEAPLIST32 :: ^HEAPLIST32
HEAPENTRY32 :: struct {
dwSize: SIZE_T,
hHandle: HANDLE,
dwAddress: ULONG_PTR,
dwBlockSize: SIZE_T,
dwFlags: DWORD,
dwLockCount: DWORD,
dwResvd: DWORD,
th32ProcessID: DWORD,
th32HeapID: ULONG_PTR,
}
LPHEAPENTRY32 :: ^HEAPENTRY32
+320 -21
View File
@@ -34,6 +34,7 @@ HGDIOBJ :: distinct HANDLE
HBITMAP :: distinct HANDLE
HGLOBAL :: distinct HANDLE
HHOOK :: distinct HANDLE
HWINEVENTHOOK :: distinct HANDLE
HKEY :: distinct HANDLE
HDESK :: distinct HANDLE
HFONT :: distinct HANDLE
@@ -63,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
@@ -93,10 +95,14 @@ LONG32 :: i32
ULONG64 :: u64
LONG64 :: i64
DWORD64 :: u64
PDWORD64 :: ^DWORD64
PDWORD_PTR :: ^DWORD_PTR
ATOM :: distinct WORD
wstring :: [^]WCHAR
PWSTR :: [^]WCHAR
PBYTE :: ^BYTE
LPBYTE :: ^BYTE
@@ -699,6 +705,14 @@ WNDPROC :: #type proc "system" (HWND, UINT, WPARAM, LPARAM) -> LRESULT
HOOKPROC :: #type proc "system" (code: c_int, wParam: WPARAM, lParam: LPARAM) -> LRESULT
WINEVENTPROC :: #type proc "system" (
hWinEventHook: HWINEVENTHOOK,
event: DWORD,
hwnd: HWND,
idObject, idChild: LONG,
idEventThread, dwmsEventTime: DWORD,
)
CWPRETSTRUCT :: struct {
lResult: LRESULT,
lParam: LPARAM,
@@ -2132,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,
@@ -2480,9 +2495,9 @@ OBJECT_ATTRIBUTES :: struct {
}
UNICODE_STRING :: struct {
Length: u16,
MaximumLength: u16,
Buffer: ^u16,
Length: u16 `fmt:"-"`,
MaximumLength: u16 `fmt:"-"`,
Buffer: [^]u16 `fmt:"s,Length"`,
}
OVERLAPPED :: struct {
@@ -2557,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,
@@ -2661,6 +2808,22 @@ OSVERSIONINFOEXW :: struct {
wReserved: UCHAR,
}
LoadLibraryEx_Flag :: enum DWORD {
LOAD_LIBRARY_AS_DATAFILE = 1, // 1 << 1: 0x0002,
LOAD_WITH_ALTERED_SEARCH_PATH = 3, // 1 << 3: 0x0008,
LOAD_IGNORE_CODE_AUTHZ_LEVEL = 4, // 1 << 4: 0x0010,
LOAD_LIBRARY_AS_IMAGE_RESOURCE = 5, // 1 << 5: 0x0020,
LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 6, // 1 << 6: 0x0040,
LOAD_LIBRARY_REQUIRE_SIGNED_TARGET = 7, // 1 << 7: 0x0080,
LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR = 8, // 1 << 8: 0x0100,
LOAD_LIBRARY_SEARCH_APPLICATION_DIR = 9, // 1 << 9: 0x0200,
LOAD_LIBRARY_SEARCH_USER_DIRS = 10, // 1 << 10: 0x0400,
LOAD_LIBRARY_SEARCH_SYSTEM32 = 11, // 1 << 11: 0x0800,
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 12, // 1 << 12: 0x1000,
LOAD_LIBRARY_SAFE_CURRENT_DIRS = 13, // 1 << 13: 0x2000,
}
LoadLibraryEx_Flags :: distinct bit_set[LoadLibraryEx_Flag]
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-quota_limits
// Used in LogonUserExW
PQUOTA_LIMITS :: struct {
@@ -2704,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
@@ -3970,6 +4116,70 @@ CONSOLE_CURSOR_INFO :: struct {
PCONSOLE_SCREEN_BUFFER_INFO :: ^CONSOLE_SCREEN_BUFFER_INFO
PCONSOLE_CURSOR_INFO :: ^CONSOLE_CURSOR_INFO
Event_Type :: enum WORD {
KEY_EVENT = 0x0001,
MOUSE_EVENT = 0x0002,
WINDOW_BUFFER_SIZE_EVENT = 0x0004,
MENU_EVENT = 0x0008,
FOCUS_EVENT = 0x0010,
}
INPUT_RECORD :: struct {
EventType: Event_Type,
Event: struct #raw_union {
KeyEvent: KEY_EVENT_RECORD,
MouseEvent: MOUSE_EVENT_RECORD,
WindowBufferSizeEvent: WINDOW_BUFFER_SIZE_RECORD,
MenuEvent: MENU_EVENT_RECORD,
FocusEvent: FOCUS_EVENT_RECORD,
},
}
Control_Key_State_Bits :: enum {
RIGHT_ALT_PRESSED,
LEFT_ALT_PRESSED,
RIGHT_CTRL_PRESSED,
LEFT_CTRL_PRESSED,
SHIFT_PRESSED,
NUMLOCK_ON,
SCROLLLOCK_ON,
CAPSLOCK_ON,
ENHANCED_KEY,
}
Control_Key_State :: bit_set[Control_Key_State_Bits; DWORD]
KEY_EVENT_RECORD :: struct {
bKeyDown: BOOL,
wRepeatCount: WORD,
wVirtualKeyCode: WORD,
wVirtualScanCode: WORD,
uChar: struct #raw_union {
UnicodeChar: WCHAR,
AsciiChar: CHAR,
},
dwControlKeyState: Control_Key_State,
}
MOUSE_EVENT_RECORD :: struct {
dwMousePosition: COORD,
dwButtonState: DWORD,
dwControlKeyState: DWORD,
dwEventFlags: DWORD,
}
WINDOW_BUFFER_SIZE_RECORD :: struct {
dwSize: COORD,
}
MENU_EVENT_RECORD :: struct {
dwCommandId: UINT,
}
FOCUS_EVENT_RECORD :: struct {
bSetFocus: BOOL,
}
//
// Networking
//
@@ -4204,3 +4414,92 @@ SOCKADDR :: struct {
sa_family: ADDRESS_FAMILY,
sa_data: [14]CHAR,
}
DTR_Control :: enum byte {
Disable = 0,
Enable = 1,
Handshake = 2,
}
RTS_Control :: enum byte {
Disable = 0,
Enable = 1,
Handshake = 2,
Toggle = 3,
}
Parity :: enum byte {
None = 0,
Odd = 1,
Even = 2,
Mark = 3,
Space = 4,
}
Stop_Bits :: enum byte {
One = 0,
One_And_A_Half = 1,
Two = 2,
}
DCB :: struct {
DCBlength: DWORD,
BaudRate: DWORD,
using _: bit_field DWORD {
fBinary: bool | 1,
fParity: bool | 1,
fOutxCtsFlow: bool | 1,
fOutxDsrFlow: bool | 1,
fDtrControl: DTR_Control | 2,
fDsrSensitivity: bool | 1,
fTXContinueOnXoff: bool | 1,
fOutX: bool | 1,
fInX: bool | 1,
fErrorChar: bool | 1,
fNull: bool | 1,
fRtsControl: RTS_Control | 2,
fAbortOnError: bool | 1,
},
wReserved: WORD,
XOnLim: WORD,
XOffLim: WORD,
ByteSize: BYTE,
Parity: Parity,
StopBits: Stop_Bits,
XonChar: byte,
XoffChar: byte,
ErrorChar: byte,
EofChar: byte,
EvtChar: byte,
wReserved1: WORD,
}
COMMTIMEOUTS :: struct {
ReadIntervalTimeout: DWORD,
ReadTotalTimeoutMultiplier: DWORD,
ReadTotalTimeoutConstant: DWORD,
WriteTotalTimeoutMultiplier: DWORD,
WriteTotalTimeoutConstant: DWORD,
}
Com_Stat_Bits :: enum {
fCtsHold,
fDsrHold,
fRlsdHold,
fXoffHold,
fXoffSent,
fEof,
fTxim,
}
COMSTAT :: struct {
bits: bit_set[Com_Stat_Bits; DWORD],
cbInQue: DWORD,
cbOutQue: DWORD,
}
Com_Error_Bits :: enum {
RXOVER,
OVERRUN,
RXPARITY,
FRAME,
BREAK,
}
Com_Error :: bit_set[Com_Error_Bits; DWORD]
+41 -21
View File
@@ -17,6 +17,18 @@ foreign user32 {
GetClassNameW :: proc(hWnd: HWND, lpClassName: LPWSTR, nMaxCount: c_int) -> c_int ---
GetParent :: proc(hWnd: HWND) -> HWND ---
IsWindowVisible :: proc(hWnd: HWND) -> BOOL ---
SetWinEventHook :: proc(
eventMin, eventMax: DWORD,
hmodWinEventProc: HMODULE,
pfnWinEvenProc: WINEVENTPROC,
idProcess, idThread: DWORD,
dwFlags: WinEventFlags,
) -> HWINEVENTHOOK ---
IsChild :: proc(hWndParent, hWnd: HWND) -> BOOL ---
RegisterClassW :: proc(lpWndClass: ^WNDCLASSW) -> ATOM ---
RegisterClassExW :: proc(^WNDCLASSEXW) -> ATOM ---
UnregisterClassW :: proc(lpClassName: LPCWSTR, hInstance: HINSTANCE) -> BOOL ---
@@ -126,6 +138,7 @@ foreign user32 {
CreatePopupMenu :: proc() -> HMENU ---
DestroyMenu :: proc(hMenu: HMENU) -> BOOL ---
AppendMenuW :: proc(hMenu: HMENU, uFlags: UINT, uIDNewItem: UINT_PTR, lpNewItem: LPCWSTR) -> BOOL ---
SetMenu :: proc(hWnd: HWND, hMenu: HMENU) -> BOOL ---
TrackPopupMenu :: proc(hMenu: HMENU, uFlags: UINT, x: int, y: int, nReserved: int, hWnd: HWND, prcRect: ^RECT) -> i32 ---
RegisterWindowMessageW :: proc(lpString: LPCWSTR) -> UINT ---
@@ -355,9 +368,9 @@ RAWHID :: struct {
RAWMOUSE :: struct {
usFlags: USHORT,
DUMMYUNIONNAME: struct #raw_union {
using DUMMYUNIONNAME: struct #raw_union {
ulButtons: ULONG,
DUMMYSTRUCTNAME: struct {
using DUMMYSTRUCTNAME: struct {
usButtonFlags: USHORT,
usButtonData: USHORT,
},
@@ -433,7 +446,7 @@ RID_DEVICE_INFO_MOUSE :: struct {
RID_DEVICE_INFO :: struct {
cbSize: DWORD,
dwType: DWORD,
DUMMYUNIONNAME: struct #raw_union {
using DUMMYUNIONNAME: struct #raw_union {
mouse: RID_DEVICE_INFO_MOUSE,
keyboard: RID_DEVICE_INFO_KEYBOARD,
hid: RID_DEVICE_INFO_HID,
@@ -454,10 +467,21 @@ RIDEV_DEVNOTIFY :: 0x00002000
RID_HEADER :: 0x10000005
RID_INPUT :: 0x10000003
RIDI_PREPARSEDDATA :: 0x20000005
RIDI_DEVICENAME :: 0x20000007
RIDI_DEVICEINFO :: 0x2000000b
RIM_TYPEMOUSE :: 0
RIM_TYPEKEYBOARD :: 1
RIM_TYPEHID :: 2
RI_KEY_MAKE :: 0
RI_KEY_BREAK :: 1
RI_KEY_E0 :: 2
RI_KEY_E1 :: 4
RI_KEY_TERMSRV_SET_LED :: 8
RI_KEY_TERMSRV_SHADOW :: 0x10
MOUSE_MOVE_RELATIVE :: 0x00
MOUSE_MOVE_ABSOLUTE :: 0x01
MOUSE_VIRTUAL_DESKTOP :: 0x02
@@ -483,19 +507,6 @@ RI_MOUSE_BUTTON_5_UP :: 0x0200
RI_MOUSE_WHEEL :: 0x0400
RI_MOUSE_HWHEEL :: 0x0800
HID_USAGE_PAGE_GENERIC :: 0x01
HID_USAGE_PAGE_GAME :: 0x05
HID_USAGE_PAGE_LED :: 0x08
HID_USAGE_PAGE_BUTTON :: 0x09
HID_USAGE_GENERIC_POINTER :: 0x01
HID_USAGE_GENERIC_MOUSE :: 0x02
HID_USAGE_GENERIC_JOYSTICK :: 0x04
HID_USAGE_GENERIC_GAMEPAD :: 0x05
HID_USAGE_GENERIC_KEYBOARD :: 0x06
HID_USAGE_GENERIC_KEYPAD :: 0x07
HID_USAGE_GENERIC_MULTI_AXIS_CONTROLLER :: 0x08
WINDOWPLACEMENT :: struct {
length: UINT,
flags: UINT,
@@ -520,11 +531,11 @@ WINDOWINFO :: struct {
PWINDOWINFO :: ^WINDOWINFO
DRAWTEXTPARAMS :: struct {
cbSize : UINT ,
iTabLength: int ,
iLeftMargin: int ,
iRightMargin: int ,
uiLengthDrawn: UINT ,
cbSize: UINT,
iTabLength: int,
iLeftMargin: int,
iRightMargin: int,
uiLengthDrawn: UINT,
}
PDRAWTEXTPARAMS :: ^DRAWTEXTPARAMS
@@ -569,3 +580,12 @@ RedrawWindowFlags :: enum UINT {
RDW_FRAME = 0x0400,
RDW_NOFRAME = 0x0800,
}
// OUTOFCONTEXT is the zero value, use {}
WinEventFlags :: bit_set[WinEventFlag; DWORD]
WinEventFlag :: enum DWORD {
SKIPOWNTHREAD = 0,
SKIPOWNPROCESS = 1,
INCONTEXT = 2,
}
+4 -4
View File
@@ -53,8 +53,8 @@ utf8_to_utf16 :: proc(s: string, allocator := context.temp_allocator) -> []u16 {
return text[:n]
}
utf8_to_wstring :: proc(s: string, allocator := context.temp_allocator) -> wstring {
if res := utf8_to_utf16(s, allocator); res != nil {
return &res[0]
if res := utf8_to_utf16(s, allocator); len(res) > 0 {
return raw_data(res)
}
return nil
}
@@ -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
+1 -1
View File
@@ -47,7 +47,7 @@ ERROR_PIPE_BUSY : DWORD : 231
E_NOTIMPL :: HRESULT(-0x7fff_bfff) // 0x8000_4001
SUCCEEDED :: #force_inline proc(#any_int result: int) -> bool { return result >= 0 }
SUCCEEDED :: #force_inline proc "contextless" (#any_int result: int) -> bool { return result >= 0 }
System_Error :: enum DWORD {
+85
View File
@@ -0,0 +1,85 @@
//+build windows
package sys_windows
foreign import kernel32 "system:Kernel32.lib"
@(default_calling_convention="system")
foreign kernel32 {
GetSystemWow64Directory2W :: proc (lpBuffer: LPWSTR, uSize: UINT, ImageFileMachineTyp: WORD) -> UINT ---
GetSystemWow64DirectoryW :: proc (lpBuffer: LPWSTR, uSize: UINT) -> UINT ---
IsWow64GuestMachineSupported :: proc (WowGuestMachine: USHORT, MachineIsSupported: ^BOOL) -> HRESULT ---
IsWow64Process :: proc (hProcess: HANDLE, Wow64Process: PBOOL) -> BOOL ---
IsWow64Process2 :: proc (hProcess: HANDLE, pProcessMachine: ^USHORT, pNativeMachine: ^USHORT) -> BOOL ---
Wow64EnableWow64FsRedirection :: proc (Wow64FsEnableRedirection: BOOLEAN) -> BOOLEAN ---
Wow64DisableWow64FsRedirection :: proc (OldValue: ^PVOID) -> BOOL ---
Wow64RevertWow64FsRedirection :: proc (OlValue: PVOID) -> BOOL ---
Wow64GetThreadContext :: proc (hThread: HANDLE, lpContext: PWOW64_CONTEXT) -> BOOL ---
Wow64SetThreadContext :: proc(hThread: HANDLE, lpContext: ^WOW64_CONTEXT) -> BOOL ---
Wow64SetThreadDefaultGuestMachine :: proc(Machine: USHORT) -> USHORT ---
Wow64SuspendThread :: proc (hThread: HANDLE) -> DWORD ---
}
WOW64_CONTEXT_i386 :: 0x00010000
WOW64_CONTEXT_CONTROL :: (WOW64_CONTEXT_i386 | 0x00000001)
WOW64_CONTEXT_INTEGER :: (WOW64_CONTEXT_i386 | 0x00000002)
WOW64_CONTEXT_SEGMENTS :: (WOW64_CONTEXT_i386 | 0x00000004)
WOW64_CONTEXT_FLOATING_POINT :: (WOW64_CONTEXT_i386 | 0x00000008)
WOW64_CONTEXT_DEBUG_REGISTERS :: (WOW64_CONTEXT_i386 | 0x00000010)
WOW64_CONTEXT_EXTENDED_REGISTERS :: (WOW64_CONTEXT_i386 | 0x00000020)
WOW64_CONTEXT_FULL :: (WOW64_CONTEXT_CONTROL | WOW64_CONTEXT_INTEGER | WOW64_CONTEXT_SEGMENTS)
WOW64_CONTEXT_ALL :: (
WOW64_CONTEXT_CONTROL |
WOW64_CONTEXT_INTEGER |
WOW64_CONTEXT_SEGMENTS |
WOW64_CONTEXT_FLOATING_POINT |
WOW64_CONTEXT_DEBUG_REGISTERS |
WOW64_CONTEXT_EXTENDED_REGISTERS)
WOW64_SIZE_OF_80387_REGISTERS :: 80
WOW64_MAXIMUM_SUPPORTED_EXTENSION :: 512
WOW64_CONTEXT :: struct {
ContextFlags: DWORD,
Dr0: DWORD,
Dr1: DWORD,
Dr2: DWORD,
Dr3: DWORD,
Dr6: DWORD,
Dr7: DWORD,
FloatSave: WOW64_FLOATING_SAVE_AREA,
SegGs: DWORD,
SegFs: DWORD,
SegEs: DWORD,
SegDs: DWORD,
Edi: DWORD,
Esi: DWORD,
Ebx: DWORD,
Edx: DWORD,
Ecx: DWORD,
Eax: DWORD,
Ebp: DWORD,
Eip: DWORD,
SegCs: DWORD,
EFlags: DWORD,
Esp: DWORD,
SegSs: DWORD,
ExtendedRegisters: [WOW64_MAXIMUM_SUPPORTED_EXTENSION]BYTE,
}
PWOW64_CONTEXT :: ^WOW64_CONTEXT
WOW64_FLOATING_SAVE_AREA :: struct {
ControlWord: DWORD,
StatusWord: DWORD,
TagWord: DWORD,
ErrorOffset: DWORD,
ErrorSelector: DWORD,
DataOffset: DWORD,
DataSelector: DWORD,
RegisterArea: [WOW64_SIZE_OF_80387_REGISTERS]BYTE,
Cr0NpxState: DWORD,
}
PWOW64_FLOATING_SAVE_AREA :: ^WOW64_FLOATING_SAVE_AREA