Saduff Posted August 6, 2011 Posted August 6, 2011 (edited) I'm writing a native application in C (/SUBSYSTEM:NATIVE) and need to check if a key combination was pressed. It works, but it only captures the first packet of keyboard input data (i.e only first key pressed), however I need to check 4 keys simultaneously. Here's the code I used for testing: UNICODE_STRING NtReadKeyboardInput(){ LARGE_INTEGER Interval; UNICODE_STRING input; UNICODE_STRING keyboardDeviceName; OBJECT_ATTRIBUTES objectAttributes; IO_STATUS_BLOCK ioStatusBlock; WCHAR show[200]; NTSTATUS status; HANDLE keyboardHandle; UNICODE_STRING message; KEYBOARD_INPUT_DATA inputData[3]; USHORT usMakeCode; USHORT usFlags;//----------------- "\\Device\\KeyboardClass0" ------------------------ NtPrint(L"\nReadKeyboardInput Start"); NtSleep2();//-------------------------------------------------------------------- RtlInitUnicodeString(&keyboardDeviceName, L"\\Device\\KeyboardClass0"); InitializeObjectAttributes(&objectAttributes, &keyboardDeviceName, OBJ_CASE_INSENSITIVE, NULL, NULL); memset(&ioStatusBlock, 0, sizeof(ioStatusBlock));//----------------------------- NtCreateFile --------------------------------- status = NtCreateFile(&keyboardHandle, GENERIC_READ|FILE_READ_ATTRIBUTES, &objectAttributes, &ioStatusBlock, 0, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, FILE_DIRECTORY_FILE, 0, 0); if (status == STATUS_SUCCESS) { HANDLE hEvent; NtPrint(L"\nKeyboard created"); NtSleep2();//------------------------------------------------------------------------------- InitializeObjectAttributes(&objectAttributes, NULL, 0, NULL, NULL); status = NtCreateEvent(&hEvent, STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x03, &objectAttributes, NotificationEvent, FALSE); if (status == STATUS_SUCCESS) { static char buffer[0x78]; int i; static LARGE_INTEGER byteOffset; byteOffset.LowPart = 0; byteOffset.HighPart = 0; memset(&ioStatusBlock, 0, sizeof(ioStatusBlock)); NtPrint(L"\nEvent created"); NtSleep2();//------------------------------------------------------------------------------ status = NtReadFile(keyboardHandle, hEvent, NULL, NULL, &ioStatusBlock, &inputData, sizeof(KEYBOARD_INPUT_DATA)*4, &byteOffset, NULL); if (status == STATUS_PENDING) { int i; NtPrint(L"\nPlease Press any key..."); for (i=0; i<6; i++) { // NtDisplayString(&message);//************************** Interval.QuadPart = 2 * 10000 * 1000; Interval.QuadPart = -Interval.QuadPart; NtDelayExecution(FALSE, &Interval); status = NtWaitForSingleObject(hEvent, TRUE, &Interval); if (status == STATUS_SUCCESS) { NtPrint(L"Success\n"); NtSleep2(); usMakeCode = inputData[0].MakeCode; usFlags = inputData[0].Flags; swprintf(show, L"Key 0 MakeCode : %x, Flags : %x\n", usMakeCode, usFlags); NtPrint(show); NtSleep2(); usMakeCode = inputData[1].MakeCode; usFlags = inputData[1].Flags; swprintf(show, L"Key 1 MakeCode : %x, Flags : %x\n", usMakeCode, usFlags); NtPrint(show); NtSleep2(); usMakeCode = inputData[2].MakeCode; usFlags = inputData[2].Flags; swprintf(show, L"Key 2 MakeCode : %x, Flags : %x\n", usMakeCode, usFlags); NtPrint(show); NtSleep2(); usMakeCode = inputData[3].MakeCode; usFlags = inputData[3].Flags; swprintf(show, L"Key 3 MakeCode : %x, Flags : %x\n", usMakeCode, usFlags); NtPrint(show); NtSleep2(); break; } else if (status == STATUS_TIMEOUT) { swprintf(show,L"\nAttempt %d to get keyboard input, please press a key...\n",i+1); NtPrint(show); NtSleep2(); NtPrint(L"STATUS_TIMEOUT\n"); NtSleep2(); if (i == 5) { RtlInitUnicodeString(&message, L"\n\nFailed! You did not press any key.\n"); input = message; } } } if (status != STATUS_SUCCESS) { NtPrint(L"STATUS_UNSUCCESS"); NtSleep2(); } else { RtlInitUnicodeString(&message, L"\n\nKey was pressed!!!\n"); input = message; } } else {//-------------------------------------------------- NtPrint(L"\nRead failed:"); NtSleep2();///////////////////////////////////////////////// } NtClose(hEvent); } else { NtPrint(L"\nCreate Event failed:"); } NtClose(keyboardHandle); } else {//------------------------------------------------------------------- NtPrint(L"\nUnable to open keyboard device:"); NtSleep2();//------------------------------------------------------------------------- } return input;} Key 1,2 and 3 MakeCode is always zero and flags is some strange value. NtPrint is a function I made that initializes the unicode string and calls NtDisplayString. NtSleep2 calls NtDelayExecution with Interval of 2 seconds. Anyway, this is irrelevant. What is important is why NtReadFile only reads the first pressed key? It's a PS/2 keyboard it reads from. Edited August 6, 2011 by Saduff
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now