Author Topic: WriteConsoleInput  (Read 20895 times)

jj2007

  • Member
  • *****
  • Posts: 13957
  • Assembly is fun ;-)
    • MasmBasic
WriteConsoleInput
« on: January 03, 2013, 09:04:53 AM »
A while ago we played with console I/O here.

The core code is this, and it works fine to prefill the console buffer:

@@:        dec ebx        ; write the prefill string to the console input buffer
        js @F
        movzx eax, byte ptr [ecx+ebx]        ; read backwards, start with Len-1
        inc edi        ; count the records
       
push 0        ; dwControlKeyState
       
push ax        ; UnicodeChar
        push ax        ; wVirtualKeyCode
        push 0        ; looks unprofessional but it works better without MapVirtualKey
        push 1        ; bKeyDown
        push KEY_EVENT
        jmp @B
@@:        invoke GetStdHandle, STD_INPUT_HANDLE        ; Google GetStdHandle WriteConsoleInput FILE_TYPE_PIPE
        xchg eax, ebx
        invoke SetLastError, 1
        mov ebx, hConin                ; Conin$ throws no errors for WriteConsoleInputA but no effect...
;        call GetStInfo
;        xchg eax, ebx
        mov edx, esp                ; buffer start
        push edx                ; create a slot for chars written
        invoke WriteConsoleInputA, ebx, edx, edi, esp        ; ml chokes without the A

Except for pipes... no effect. Googling didn't help, it seems most people use STD_INPUT_HANDLE successfully, but in my code it says invalid handle. Using CONIN$ does not throw an error, but it doesn't fill the buffer either. Any ideas?

Thanks, jj

qWord

  • Member
  • *****
  • Posts: 1475
  • The base type of a type is the type itself
    • SmplMath macros
Re: WriteConsoleInput
« Reply #1 on: January 03, 2013, 09:27:16 AM »
maybe the problem is that you only push the keys (bKeyDown=1), but never release them?
MREAL macros - when you need floating point arithmetic while assembling!

nidud

  • Member
  • *****
  • Posts: 2388
    • https://github.com/nidud/asmc
Re: WriteConsoleInput
« Reply #2 on: January 03, 2013, 09:35:55 AM »
deleted
« Last Edit: February 25, 2022, 05:52:54 AM by nidud »

jj2007

  • Member
  • *****
  • Posts: 13957
  • Assembly is fun ;-)
    • MasmBasic
Re: WriteConsoleInput
« Reply #3 on: January 03, 2013, 09:43:28 AM »
Thanks, qWord. However, it seems not important. The code works perfectly in non-pipe mode.

WriteConsoleInputA returns invalid handle when used with GetStdHandle(STD_INPUT_HANDLE), but only in piped mode. The other console functions work just fine.

WriteConsoleInputA returns no error when used with CreateFile(CONIN$), and it works fine in non-pipe mode with that handle (which is different from std input handle). But the console input buffer doesn't get filled in pipe mode.

@nidud: No, the order is correct. hConin is obtained through CreateFile, not shown here. If I comment it out, WriteConsoleInputA uses std input handle and throws invalid handle error. Both work fine in non-pipe mode.

I attach the code and executables. Latest MasmBasic of today required if you want to assemble it.

qWord

  • Member
  • *****
  • Posts: 1475
  • The base type of a type is the type itself
    • SmplMath macros
Re: WriteConsoleInput
« Reply #4 on: January 03, 2013, 09:47:11 AM »
Are you using named pipes?
MREAL macros - when you need floating point arithmetic while assembling!

jj2007

  • Member
  • *****
  • Posts: 13957
  • Assembly is fun ;-)
    • MasmBasic
Re: WriteConsoleInput
« Reply #5 on: January 03, 2013, 09:48:43 AM »
No, just CreatePipe. The normal case for passing handles to child processes.

qWord

  • Member
  • *****
  • Posts: 1475
  • The base type of a type is the type itself
    • SmplMath macros
Re: WriteConsoleInput
« Reply #6 on: January 03, 2013, 09:50:09 AM »
Just for testing purpose, I would try it with releasing the keys...
MREAL macros - when you need floating point arithmetic while assembling!

jj2007

  • Member
  • *****
  • Posts: 13957
  • Assembly is fun ;-)
    • MasmBasic
Re: WriteConsoleInput
« Reply #7 on: January 03, 2013, 10:01:53 AM »
No change, exactly as before...

Line 37ff of SendStringsOnDemand.asc:
@@:        dec ebx        ; write the prefill string to the console input buffer
        js @F
        movzx eax, byte ptr [ecx+ebx]        ; read backwards, start with Len-1

        inc edi        ; count the records
       
push 0        ; dwControlKeyState
       
push ax        ; UnicodeChar
        push ax        ; wVirtualKeyCode
        push 0        ; looks unprofessional but it works better without MapVirtualKey
        push 0        ; bKeyUp
        push KEY_EVENT

        inc edi        ; count the records
       
push 0        ; dwControlKeyState
       
push ax        ; UnicodeChar
        push ax        ; wVirtualKeyCode
        push 0        ; looks unprofessional but it works better without MapVirtualKey
        push 1        ; bKeyDown
        push KEY_EVENT
        jmp @B

qWord

  • Member
  • *****
  • Posts: 1475
  • The base type of a type is the type itself
    • SmplMath macros
Re: WriteConsoleInput
« Reply #8 on: January 03, 2013, 10:09:37 AM »
can you make a short description how I can reproduce the described bug with the two EXEs you've upload.
MREAL macros - when you need floating point arithmetic while assembling!

jj2007

  • Member
  • *****
  • Posts: 13957
  • Assembly is fun ;-)
    • MasmBasic
Re: WriteConsoleInput
« Reply #9 on: January 03, 2013, 10:22:30 AM »
SendStringsOnDemand.exe "standalone" shows
Enter x, Date or Time: >date
(the stuff before is debug info that I forgot to take out - new attachment below has switched that off)

When launched from CmdGUI_full.exe, it shows

D:\Masm32\CmdGUI>SendStringsOnDemand
..
Ready
Enter x, Date or Time: >[NO DATE HERE...]

The attachment above lacked the *.dat files, here is a complete one.

qWord

  • Member
  • *****
  • Posts: 1475
  • The base type of a type is the type itself
    • SmplMath macros
Re: WriteConsoleInput
« Reply #10 on: January 03, 2013, 10:47:14 AM »
did you try it with SetConsoleMode->ENABLE_ECHO_INPUT for the pipe handle?
MREAL macros - when you need floating point arithmetic while assembling!

jj2007

  • Member
  • *****
  • Posts: 13957
  • Assembly is fun ;-)
    • MasmBasic
Re: WriteConsoleInput
« Reply #11 on: January 03, 2013, 05:16:55 PM »
Good idea, I tried in various places but the answer is always "invalid handle"...

        invoke SetHandleInformation, hWriteOut, hflags, hflags         ; we need only hWriteOut
        invoke SetHandleInformation, hReadIn, hflags, hflags         ; and hReadIn
        invoke SetConsoleMode, hWriteOut, ENABLE_ECHO_INPUT
        deb 4, "SW2", eax, $Err$()
        invoke SetConsoleMode, hReadIn, ENABLE_ECHO_INPUT
        deb 4, "SW2", eax, $Err$()

qWord

  • Member
  • *****
  • Posts: 1475
  • The base type of a type is the type itself
    • SmplMath macros
Re: WriteConsoleInput
« Reply #12 on: January 03, 2013, 09:02:13 PM »
Well, I can't compile your source (SendStringsOnDemand) with MASM. Also, when using jWasm, I get an executable that behaviors differently than the EXE you supplied - I get directly an error "invalid handle".
Also, I've seen some "strange" comments in your code:
Code: [Select]
LOCAL PipeBytes, buffer[8000]:BYTE ; 8102 works, 8104 crashes, slow for small buffers (e.g. 100 bytes) How should one interpret that?
MREAL macros - when you need floating point arithmetic while assembling!

sinsi

  • Guest
Re: WriteConsoleInput
« Reply #13 on: January 03, 2013, 09:16:41 PM »
"push KEY_EVENT" is that pushing a word?

WORD  EventType;

qWord

  • Member
  • *****
  • Posts: 1475
  • The base type of a type is the type itself
    • SmplMath macros
Re: WriteConsoleInput
« Reply #14 on: January 03, 2013, 09:21:30 PM »
"push KEY_EVENT" is that pushing a word?

WORD  EventType;
the union must be aligned to 4 (size of the greatest member that is not lager than 8 ) so it should be right.
MREAL macros - when you need floating point arithmetic while assembling!