Re: Scanf-like function for native application

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance

From: Doron Holan [MS] (doronh_at_nospam.microsoft.com)
Date: 03/10/04


Date: Tue, 9 Mar 2004 22:05:38 -0800

i bet you are reading from the terminal services keyboard. you need to get
all of the instances of the keyboard interface (IoGetDeviceInterfaces, see
ntddkbd.h for the interface guid) and read from all the keyboards
simultaneously.

d

-- 
This posting is provided "AS IS" with no warranties, and confers no rights.
Please reply to newsgroups only.
"Gsw.Zero" <gswzero@hotmail.com> wrote in message
news:uwpsB$eBEHA.2360@TK2MSFTNGP10.phx.gbl...
> > Was the read length an integral sizeof(KEYBOARD_INPUT_DATA) ?
> I suppose it is, the code sequence is allocating this size:
>
>      kidLen = sizeof(KEYBOARD_INPUT_DATA);    //    KEYBOARD_INPUT_DATA
*kid
>      kid = RtlAllocateHeap(Heap, 0, kidLen);
>     ...
>       offset.QuadPart = 0;    //    LARGE_INTEGER offset;
>       kid->UnitId    = 0;
>       kid->MakeCode   = 0;
>       kid->Flags    = 0;
>       kid->Reserved   = 0;
>       kid->ExtraInformation = 0;
>       ...
>       readStatus = ZwReadFile(ConsoleHandle, NULL, NULL,
>            NULL, &ioStatus, (PVOID)kid, kidLen, &offset, NULL);
>     ...
> I press a key but I don't get nothing. After ZwReadFile I have some delays
and
> strings displayed with NtDisplayString, including the character supposed
to be
> read by ZwReadFile.
> I see all the messages printed on the blue screen until ZwReadFile, but no
other
> thing after, and the GUI starts.
>
> This is the whole function (don't laugh, remember I'm a newbie):
>
> NTSTATUS
> NtBk_DisplayMenu(
>  HANDLE   Heap,
>  PWCHAR   *ppwBuffer
> ) {
>  PWCHAR     pwBuffer   = NULL;
>  UNICODE_STRING   menuString   = {0, 0, NULL};
>  NTSTATUS    writeStatus   = STATUS_SUCCESS;
>  NTSTATUS    readStatus   = STATUS_SUCCESS;
>  HANDLE     ConsoleHandle  = NULL;
>  IO_STATUS_BLOCK   ioStatus   = {0};
>  OBJECT_ATTRIBUTES  ObjectAttributes = {0};
>  UNICODE_STRING   consoleName   = {0};
>  PVOID     pvOption   = NULL;
>  ULONG     optionLength  = 0;
>  WCHAR     wOption    = L'\0';
>  WCHAR     pwOption2[2]  = L"";
>  WCHAR     pwError[128]  = L"";
>  PKEYBOARD_INPUT_DATA kid     = NULL;
>  ULONG     kidLen;
>  LARGE_INTEGER   offset;
>
>  if(ppwBuffer != NULL) {
>   *ppwBuffer = NULL;
>
>   pwBuffer = RtlAllocateHeap(Heap, 0, 512);
>   if(pwBuffer == NULL) {
>    return STATUS_NO_MEMORY;
>   }
>   else {
>    NtBk_FormatInput(pwBuffer);
>    *ppwBuffer = pwBuffer;
>
>    NtBk_UnicodeStringFromWChar(&menuString, pwBuffer);
>    writeStatus = NtDisplayString(&menuString);
>
>    // read user option
>    __try {
>     NtBk_Print(L"\n");
>     NtBk_Print(L"Preparing console name buffer...\n");
>     NtBk_Sleep(0);
>
>     RtlInitUnicodeString(&consoleName, L"\\Device\\KeyboardPort0");
>     NtBk_Print(L"Initializing console attributes...\n");
>     NtBk_Sleep(0);
>
>     InitializeObjectAttributes(&ObjectAttributes,
>      &consoleName, 0, NULL, NULL);
>
>     NtBk_Print(L"Opening console \"");
>     NtBk_Print(consoleName.Buffer);
>     NtBk_Print(L"\"...\n");
>     NtBk_Sleep(0);
>
>     readStatus = ZwCreateFile(
>      &ConsoleHandle,
>      FILE_READ_DATA,
>      &ObjectAttributes,
>      &ioStatus,
>      NULL,
>      FILE_ATTRIBUTE_NORMAL,
>      FILE_SHARE_READ | FILE_SHARE_WRITE,
>      FILE_OPEN,
>      FILE_NON_DIRECTORY_FILE,
>      NULL,
>      0);
>     if(NT_SUCCESS(readStatus)) {
>      NtBk_Print(L"Console open SUCCESS\n");
>      NtBk_Sleep(0);
>
>      kidLen = sizeof(KEYBOARD_INPUT_DATA);
>      kid = RtlAllocateHeap(Heap, 0, kidLen);
>      if(kid == NULL) {
>       NtBk_Print(L"kid = RtlAllocateHeap FAILED\n");
>       NtBk_Sleep(0);
>      }
>      else {
>       NtBk_Print(L"kid = RtlAllocateHeap SUCCEEDED\n");
>       NtBk_Sleep(0);
>
>       offset.QuadPart = 0;
>       kid->UnitId    = 0;
>       kid->MakeCode   = 0;
>       kid->Flags    = 0;
>       kid->Reserved   = 0;
>       kid->ExtraInformation = 0;
>
>       NtBk_Print(L"kid = RtlAllocateHeap SUCCEEDED\n");
>       NtBk_Sleep(0);
>       NtBk_Print(L"Preparing to character read:\n");
>       NtBk_Sleep(0);
>
>       readStatus = ZwReadFile(ConsoleHandle, NULL, NULL,
>        NULL, &ioStatus, (PVOID)kid, kidLen, &offset, NULL);
>       if(NT_SUCCESS(readStatus)) {
>        NtBk_Print(L"NtReadFile SUCCESS: character read: ");
>        NtBk_Sleep(0);
>        //pwOption2[0] = wOption;
>        pwOption2[0] = (WCHAR)kid->MakeCode;
>        pwOption2[1] = L'\0';
>
>        NtBk_Print(pwOption2);
>        NtBk_Print(L"\n");
>        NtBk_Sleep(0);
>       }
>       else {
>        swprintf(pwError, L"readStatus=0x%8.8x ioStatus.Status=%ld\n",
>         readStatus, ioStatus.Status);
>        NtBk_Print(L"NtReadFile FAILED: ");
>        NtBk_Sleep(0);
>        NtBk_Print(pwError);
>        NtBk_Sleep(0);
>       }
>       RtlFreeHeap(Heap, 0, kid);
>      }
>
>      ZwClose(ConsoleHandle);
>     }
>     else {
>      NtBk_Print(L"Console open FAILURE\n");
>      NtBk_Sleep(0);
>     }
>    }
>    __finally {
>     NtBk_Print(L"Free console name buffer...\n");
>     NtBk_Sleep(0);
>
>     RtlFreeUnicodeString(&consoleName);
>    }
>
>    NtBk_Print(L"returning read status...\n");
>    NtBk_Sleep(0);
>
>    return readStatus;
>   }
>  }
>  else {
>   return STATUS_SUCCESS;
>  }
> }
>
> VOID
> NtBk_Print(
>  PWCHAR pwString
> ) {
>  UNICODE_STRING unicodeString = {0, 0, NULL};
>
>  if(pwString != NULL) {
>   NtBk_UnicodeStringFromWChar(&unicodeString, pwString);
>   NtDisplayString(&unicodeString);
>  }
> }
>
>
> VOID
> NTAPI
> NtBk_Sleep(int howMany) {
>  LARGE_INTEGER oneSecond;
>  oneSecond.QuadPart = 1*10*1000*1000;
>  KeDelayExecutionThread(KernelMode, FALSE, &oneSecond);
> }
>
>
>
> "Doron Holan [MS]" <doronh@nospam.microsoft.com> wrote in message
> news:%23H4YNEHBEHA.1140@TK2MSFTNGP10.phx.gbl...
> > UnitId is ignored completely.  Was the read length an integral
> > sizeof(KEYBOARD_INPUT_DATA) ?  Your best bet is to look at the kbdclass
> > sources in the DDK and look at the read dispatch function.  it should be
> > clear why the read is failing.
> >
> > d
> >
> > -- 
> > This posting is provided "AS IS" with no warranties, and confers no
rights.
> > Please reply to newsgroups only.
> >
> > "Gsw.Zero" <gswzero@hotmail.com> wrote in message
> > news:um8R99CBEHA.2796@TK2MSFTNGP09.phx.gbl...
> > > I have tried also by passing a KEYBOARD_INPUT_DATA, zero-initialized -
so
> > > the UnitId is 0, as in the hardcoded example with KeyboardPort0 -,
> > > dynamically allocated or not... no chance. STATUS_INVALID_PARAMETER.
> > >
> > > Any ideas or working source sample?
> > >
> > > Cristian Amarie
> > >
> > > "Maxim S. Shatskih" <maxim@storagecraft.com> wrote in message
> > > news:eOTm696AEHA.916@tk2msftngp13.phx.gbl...
> > > > > validates the option with enter. How a native application can read
a
> > key
> > > > > pressed ? (of course you realize I'm a DDK newbie...)
> > > > >
> > > > > I have tried ZwCreateFile to open \\Device\\KeyboardPort0
> > > >
> > > > Correct.
> > > >
> > > > > ZwReadFile to read a WCHAR.
> > > >
> > > > Sorry, you will have no WCHARs. Only KEYBOARD_INPUT_DATA structures
can
> > be
> > > read
> > > > from \\Device\\KeyboardPort0. This structure contains the _scancode_
of
> > > the
> > > > key, translate it to character by yourself.
> > > >
> > > > The code used by Windows to input keyboard characters is
> > > > user32!TranslateMessage, which converts the scancode to Unicode
> > character
> > > code
> > > > and emits WM_CHAR message. This is done in window manager, by using
the
> > > current
> > > > keyboard layout table, and by far not in keyboard driver stack.
> > > >
> > > > Keyboard driver stack works with scancodes only.
> > > >
> > > > Maxim Shatskih, Windows DDK MVP
> > > > StorageCraft Corporation
> > > > maxim@storagecraft.com
> > > > http://www.storagecraft.com
> > > >
> > > >
> > >
> > >
> >
> >
>
>


Relevant Pages