Jump to content
Tuts 4 You

[Native/C] Reading keyboard input


Saduff

Recommended Posts

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 by Saduff
Link to comment

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...