| /* A part of the Native C Library for Windows NT |
| Copyright 2007-2015 PC GO Ld. |
| |
| This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
| */ |
| |
| #include <unistd.h> |
| #include <errno.h> |
| #include <windows.h> |
| #include <nt.h> |
| |
| #include <stdio.h> |
| |
| static void *keyboard_fh; |
| static int stdin_fd = TTY_FD_DEFAULT; |
| static int stdout_fd = TTY_FD_DEFAULT; |
| static int stderr_fd = TTY_FD_DEFAULT; |
| |
| int __init_keyboard() { |
| UNICODE_STRING keyboard_path = { .Buffer = L"\\Device\\KeyboardClass0" }; |
| keyboard_path.MaximumLength = sizeof L"\\Device\\KeyboardClass0"; |
| keyboard_path.Length = keyboard_path.MaximumLength - sizeof(wchar_t); |
| OBJECT_ATTRIBUTES object_attrib = { sizeof(OBJECT_ATTRIBUTES), NULL, &keyboard_path, 0, NULL, NULL }; |
| unsigned long int access_mask = GENERIC_READ | SYNCHRONIZE; |
| IO_STATUS_BLOCK io_status; |
| long int status = NtOpenFile(&keyboard_fh, access_mask, &object_attrib, &io_status, 0, FILE_DIRECTORY_FILE); |
| printf("nativelibc debug: __init_keyboard: status = 0x%lx\n", status); |
| if(status < 0) { |
| __set_errno_from_ntstatus(status); |
| return -1; |
| } |
| return 0; |
| } |
| |
| int _get_stdin_fd(void **keyboard) { |
| if(keyboard && stdin_fd == TTY_FD_DEFAULT) *keyboard = keyboard_fh; |
| return stdin_fd; |
| } |
| |
| int _get_stdout_fd() { |
| return stdout_fd; |
| } |
| |
| int _get_stderr_fd() { |
| return stderr_fd; |
| } |
| |
| int _set_stdin_fd(int fd) { |
| if(fd == 0 || fd == 1 || fd == 2) { |
| errno = EBADF; |
| return -1; |
| } |
| stdin_fd = fd; |
| return 0; |
| } |
| |
| int _set_stdout_fd(int fd) { |
| if(fd == 0 || fd == 1 || fd == 2) { |
| errno = EBADF; |
| return -1; |
| } |
| stdout_fd = fd; |
| return 0; |
| } |
| |
| int _set_stderr_fd(int fd) { |
| if(fd == 0 || fd == 1 || fd == 2) { |
| errno = EBADF; |
| return -1; |
| } |
| stderr_fd = fd; |
| return 0; |
| } |
| |
| int _get_std_fd(int pseudo_fd) { |
| switch(pseudo_fd) { |
| case STDIN_FILENO: |
| return stdin_fd; |
| case STDOUT_FILENO: |
| return stdout_fd; |
| case STDERR_FILENO: |
| return stderr_fd; |
| default: |
| errno = EINVAL; |
| return -1; |
| } |
| } |
| |
| int _set_std_fd(int pseudo_fd, int real_fd) { |
| if(real_fd == STDIN_FILENO || real_fd == STDOUT_FILENO || real_fd == STDERR_FILENO) { |
| errno = EBADF; |
| return -1; |
| } |
| switch(pseudo_fd) { |
| case STDIN_FILENO: |
| stdin_fd = real_fd; |
| break; |
| case STDOUT_FILENO: |
| stdout_fd = real_fd; |
| break; |
| case STDERR_FILENO: |
| stderr_fd = real_fd; |
| break; |
| default: |
| errno = EINVAL; |
| return -1; |
| } |
| return 0; |
| } |