Input from keyboard using Native NT API - how to?
От: kpoxman  
Дата: 09.05.06 10:27
Оценка:
Добрый день!

Мое приложение использует Native NT API, для того, чтобы работать при загрузке
ОС в blue screen, как autochk.exe.

Как прочитать char с клавиатуры?

Я попробовал нижепреведенный кусок кода, однако, не помогло. При открытии файла
возвращается код ошибки Invalid Parameter.

UNICODE_STRING KeyboardName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status;
InitializeObjectAttributes(&ObjectAttributes, &KeyboardName, 0, NULL, NULL);
Status = NtOpenFile(&StdInput, FILE_READ_ACCESS, &ObjectAttributes, &IoStatusBlock, 0, FILE_SYNCHRONOUS_IO_NONALERT);
{
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
KEYBOARD_INPUT_DATA InputData;
Status = NtReadFile(StdInput, NULL, NULL, NULL, &Iosb, &InputData, sizeof(KEYBOARD_INPUT_DATA), NULL, 0);
}
Re: Input from keyboard using Native NT API - how to?
От: MShura  
Дата: 10.05.06 08:36
Оценка: 23 (4)
K>Мое приложение использует Native NT API, для того, чтобы работать при загрузке
K>ОС в blue screen, как autochk.exe.

Всех проще посмотреть с помощью IDA как это делает autochk.exe.
Одно могу сказать, что autochk перед тем как показать обратный отсчет открывает 100 клавиатур и ждет "any key" от какой-нибудь.
Причем функции NtReadFile передают Event, его и ждут.

P.S.
Открывают keyboard (NtCreateFile) со следующими ключами

DesiredAccess = GENERIC_READ|SYNCHRONIZE|FILE_READ_ATTRIBUTES, // 0x80100080,
FileAttributes = FILE_ATTRIBUTE_NORMAL
ShareAccess = 0
CreateDisposition = FILE_OPEN; // 1
CreateOptions = FILE_DIRECTORY_FILE; // 1

да и ObjectAttributes инициализируют с Attributes = OBJ_CASE_INSENSITIVE

P.P.S.
Я в своё время делал полноценную работу с клавиатурой. Могу подсказать.
Re[2]: Input from keyboard using Native NT API - solved!
От: kpoxman  
Дата: 10.05.06 21:01
Оценка: 6 (1)
MSura, спасибо большое! Вы мне очень помогли!
Кстати, я послал вопрос на несколько форумов, и только здесь мне ответили по существу
Вот кусок кода, который получает один char, может кому пригодится:

USHORT ProcessInput() {
UNICODE_STRING KeyboardName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status;
USHORT Res;

InitializeObjectAttributes(&ObjectAttributes, &KeyboardName, OBJ_CASE_INSENSITIVE, NULL, NULL);
Status = NtCreateFile(&StdInput, GENERIC_READ | SYNCHRONIZE | FILE_READ_ATTRIBUTES,
&ObjectAttributes, &IoStatusBlock, 0, FILE_ATTRIBUTE_NORMAL, 0,
FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, 0, 0);
{
KEYBOARD_INPUT_DATA InputData;
Status = NtReadFile(StdInput, NULL, NULL, NULL, &IoStatusBlock, &InputData, sizeof(KEYBOARD_INPUT_DATA), NULL, 0);
Res = InputData.MakeCode;
}

NtClose(StdInput);

return Res;
}
Re[3]: Input from keyboard using Native NT API - solved!
От: MShura  
Дата: 11.05.06 11:10
Оценка: 2 (1)
K>Кстати, я послал вопрос на несколько форумов, и только здесь мне ответили по существу
K>Вот кусок кода, который получает один char, может кому пригодится:

K>USHORT ProcessInput() {

K> UNICODE_STRING KeyboardName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
...
Я не зря говорил про 100 клавиатур.
В NT варианте autochk действительно использовалась только клавиатура 0, но начиная с Win2K autochk стала открывать 100 клавиатур.
Я за свою практику встречал один случай, когда клавиатура 0 не работала, а работала номер 2. Как такое получилось и как это воспроизвести я не знаю, но это именно этот случай заставил меня сканировать 100 клавиатур. Но сканирование я делал только до первого символа, далее работал только с определенной клавиатурой. Я думаю маловероятно, что будут подключены сразу две клавиатуры и ввод будет с обоих.
Re[4]: Input from keyboard using Native NT API - solved!
От: MShura  
Дата: 11.05.06 11:30
Оценка:
MS>В NT варианте autochk действительно использовалась только клавиатура 0, но начиная с Win2K autochk стала открывать 100 клавиатур.
Уточнение: Сканирование 100 клавиатур началось с WinXP.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.