os_specific_windows.odin 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. //+build windows
  2. //+private
  3. package runtime
  4. foreign import kernel32 "system:Kernel32.lib"
  5. @(private="file")
  6. @(default_calling_convention="system")
  7. foreign kernel32 {
  8. // NOTE(bill): The types are not using the standard names (e.g. DWORD and LPVOID) to just minimizing the dependency
  9. // stderr_write
  10. GetStdHandle :: proc(which: u32) -> rawptr ---
  11. SetHandleInformation :: proc(hObject: rawptr, dwMask: u32, dwFlags: u32) -> b32 ---
  12. WriteFile :: proc(hFile: rawptr, lpBuffer: rawptr, nNumberOfBytesToWrite: u32, lpNumberOfBytesWritten: ^u32, lpOverlapped: rawptr) -> b32 ---
  13. GetLastError :: proc() -> u32 ---
  14. }
  15. _stderr_write :: proc "contextless" (data: []byte) -> (n: int, err: _OS_Errno) #no_bounds_check {
  16. if len(data) == 0 {
  17. return 0, 0
  18. }
  19. STD_ERROR_HANDLE :: ~u32(0) -12 + 1
  20. HANDLE_FLAG_INHERIT :: 0x00000001
  21. MAX_RW :: 1<<30
  22. h := GetStdHandle(STD_ERROR_HANDLE)
  23. when size_of(uintptr) == 8 {
  24. SetHandleInformation(h, HANDLE_FLAG_INHERIT, 0)
  25. }
  26. single_write_length: u32
  27. total_write: i64
  28. length := i64(len(data))
  29. for total_write < length {
  30. remaining := length - total_write
  31. to_write := u32(min(i32(remaining), MAX_RW))
  32. e := WriteFile(h, &data[total_write], to_write, &single_write_length, nil)
  33. if single_write_length <= 0 || !e {
  34. err = _OS_Errno(GetLastError())
  35. n = int(total_write)
  36. return
  37. }
  38. total_write += i64(single_write_length)
  39. }
  40. n = int(total_write)
  41. return
  42. }