### Author Topic: Control in console input?  (Read 1084 times)

#### felipe

• Member
• Posts: 378
• assemble the unassembled.
##### Control in console input?
« on: June 10, 2017, 11:02:16 AM »
Is there a way to limit input in the console to a maximum of keys?

Code: [Select]
`.386.model  flat,stdcalloption  casemap:noneinclude \masm32\include\windows.incinclude \masm32\include\kernel32.incincludelib \masm32\lib\kernel32.lib.data?hconsoleinput   dd  ?hconsoleoutput  dd  ?charswritten    dd  ?charsread       dd  ?charsattset     dd  ?.dataprogramname db  "THE CONSOLE WAY!",0welcome     db  "Hi, welcome to this program!",0ah,0dhtext        db  " ".codemain    proc        invoke  GetStdHandle,STD_INPUT_HANDLE        mov     hconsoleinput,eax        invoke  GetStdHandle,STD_OUTPUT_HANDLE        mov     hconsoleoutput,eax        invoke  SetConsoleTitle,offset programname           call    paintb        invoke  SetConsoleTextAttribute,hconsoleoutput,\                            ; Set the text and background                FOREGROUND_BLUE or FOREGROUND_GREEN or FOREGROUND_INTENSITY or\     ;  colors.                BACKGROUND_GREEN             invoke  WriteConsole,hconsoleoutput,offset welcome,sizeof welcome,\                offset charswritten,NULL           invoke  ReadConsole,hconsoleinput,offset text,sizeof text,\                offset charsread,NULL        invoke  ExitProcess,0main    endppaintb  proc                                                                        ; Fill into green.        local   cc:COORD        mov     cc.x,0        mov     cc.y,0        mov     eax,cc                invoke  FillConsoleOutputAttribute,hconsoleoutput,BACKGROUND_GREEN,\                30000,eax,offset charsattset        retpaintb  endp                          end     main    `
Here you can enter until 255 chars from the keyboard (including the enter key) But that's crap, how to limit this?
Felipe.

#### jj2007

• Member
• Posts: 7764
• Assembler is fun ;-)
##### Re: Control in console input?
« Reply #1 on: June 10, 2017, 05:02:55 PM »
Is there a way to limit input in the console to a maximum of keys?
...
Here you can enter until 255 chars from the keyboard (including the enter key) But that's crap, how to limit this?

Does MASM32 include a Console string input function which can do the following:

1. Allows me to specify a maximum input length of the string

2. Handles input editing keys, such as arrow keys, backspace, and delete?

#### felipe

• Member
• Posts: 378
• assemble the unassembled.
##### Re: Control in console input?
« Reply #2 on: June 11, 2017, 01:16:48 AM »
Thanks jj. I'm starting to think that if i want to play with a console program,  it would better to "emulate" a console by creating a window and writing text there...
Felipe.

#### jj2007

• Member
• Posts: 7764
• Assembler is fun ;-)
##### Re: Control in console input?
« Reply #3 on: June 11, 2017, 10:34:14 AM »
It is perhaps not totally impossible (GetNumberOfConsoleInputEvents+timer), but I am pessimistic. There are many thousands of absolutely useless functions in the Windows API, but the one function that could prevent buffer overflows doesn't exist. Strange, isn't it?

#### felipe

• Member
• Posts: 378
• assemble the unassembled.
##### Re: Control in console input?
« Reply #4 on: June 11, 2017, 12:09:27 PM »

Felipe.

#### Vortex

• Member
• Posts: 1734
##### Re: Control in console input?
« Reply #5 on: June 11, 2017, 08:02:58 PM »
Hi felipe,

The code below does not replace the traditional input functions and you will have to implement the functionality of the DEL key :

Code: [Select]
`.386.model flat,stdcalloption casemap:noneinclude     \masm32\include\windows.incinclude     \masm32\include\kernel32.incinclude     \masm32\include\msvcrt.incincludelib  \masm32\lib\kernel32.libincludelib  \masm32\lib\msvcrt.lib.datamsg1        db 'You can type 10 characters. Hit RETURN to terminate the keyboard input',13,10,0msg2        db '%c',0msg3        db 13,10,'You typed : %s',13,10,0.data?buffer      db 10 dup(?).codestart:    call    main    invoke  ExitProcess,0main PROC uses esi ebx    invoke  crt_printf,ADDR msg1    mov     esi,OFFSET buffer    xor     ebx,ebx@@:    invoke  crt__getch    cmp     eax,13    je      finish        push    eax    invoke  crt_printf,ADDR msg2,eax    pop     eax        mov     BYTE PTR [esi+ebx],al    inc     ebx    cmp     ebx,10    jne     @bfinish:    invoke  crt_printf,ADDR msg3,esi    retmain ENDPEND start`
Reference :

https://msdn.microsoft.com/en-us/library/078sfkak%28v=vs.100%29.aspx

Don't forget to check the StdIn function from masm32.lib

#### felipe

• Member
• Posts: 378
• assemble the unassembled.
##### Re: Control in console input?
« Reply #6 on: June 12, 2017, 06:34:57 AM »
Thanks Vortex, i will check this.
Felipe.

#### jj2007

• Member
• Posts: 7764
• Assembler is fun ;-)
##### Re: Control in console input?
« Reply #7 on: June 12, 2017, 09:27:28 AM »
Attached a test, let me know if that is what you wanted.

Seems to run OK on Win XP, 7-64 and the latest 10-64.
It's still a beta, and required some acrobatic workarounds

#### qWord

• Member
• Posts: 1471
• The base type of a type is the type itself
##### Re: Control in console input?
« Reply #8 on: June 12, 2017, 10:10:08 AM »
This kind of question did come up several times in the past IIRC, e.g. here:
MREAL macros - when you need floating point arithmetic while assembling!

#### felipe

• Member
• Posts: 378
• assemble the unassembled.
##### Re: Control in console input?
« Reply #9 on: June 12, 2017, 12:54:53 PM »
Attached a test, let me know if that is what you wanted.

Seems to run OK on Win XP, 7-64 and the latest 10-64.
It's still a beta, and required some acrobatic workarounds

Actually yes.
But what kind of file is the no exe file?
Felipe.

#### felipe

• Member
• Posts: 378
• assemble the unassembled.
##### Re: Control in console input?
« Reply #10 on: June 12, 2017, 12:59:52 PM »
This kind of question did come up several times in the past IIRC, e.g. here:
Thanks qword i will see it tomorrow. (Now i have to go to the bed..   ).

Felipe.

#### jj2007

• Member
• Posts: 7764
• Assembler is fun ;-)
##### Re: Control in console input?
« Reply #11 on: June 12, 2017, 05:22:01 PM »
But what kind of file is the no exe file?

In case you mean the *.asc file: the source. If you don't yet have RichMasm, you can open it in WordPad. Here is the main loop:

.Repeat
Print At(5, Locate(y)) " "
Let esi=Input\$("Go ahead, edit that string: ", "123456789012345678", max20)
PrintLine "                       you typed [", esi, "]"
.Until Len(esi)<5

#### felipe

• Member
• Posts: 378
• assemble the unassembled.
##### Re: Control in console input?
« Reply #12 on: June 13, 2017, 02:55:58 AM »
Well, seems like: "ReadConsole always wants a 256 buffer", (yes, dedndave is right  ), but maybe is not the end of the world (certainly  ). So in this program the way to control the input will be allocating a buffer size of 256 bytes for each input (if this size is less and the user writes more chars the program terminates  ).  Doing a clear screen and locating the cursor position will help it the control of the output. Now i have to control the input for just the CR key (probably using SetConsoleMode).

Code: [Select]
`.386.model  flat,stdcalloption  casemap:noneinclude \masm32\include\windows.incinclude \masm32\include\kernel32.incincludelib \masm32\lib\kernel32.lib.data?hconsoleinput   dd  ?hconsoleoutput  dd  ?charswritten    dd  ?charsread       dd  ?charsattset     dd  ?.dataprogramname db  "THE CONSOLE WAY!",0welcome     db  "Hi, welcome to this program!",0ah,0dhtext        db  256 dup(" "),0promptname  db  "Enter your name: "saveit      db  0ah,0ah,"Exit program?(Y/N): "usernbuff   db  256 dup(" "),0username    db  256 dup(" "),0inerror     db  "Error! names allowed of 20 chars max. only...",0cursorp proto   :word,:wordpaintb  proto   :word,:word.codemain    proc        invoke  GetStdHandle,STD_INPUT_HANDLE        mov     hconsoleinput,eax        invoke  GetStdHandle,STD_OUTPUT_HANDLE        mov     hconsoleoutput,eax        invoke  SetConsoleTitle,offset programname   again:        invoke  cursorp,0,0                                                         ; Locates the cursor.        invoke  paintb,0,0                                                          ; Clears the screen.        invoke  SetConsoleTextAttribute,hconsoleoutput,\                            ; Set the text and background                FOREGROUND_BLUE or FOREGROUND_GREEN or FOREGROUND_INTENSITY or\     ;  colors for the console.                BACKGROUND_GREEN             invoke  WriteConsole,hconsoleoutput,offset welcome,sizeof welcome,\         ; Welcome message in screen.                offset charswritten,NULL                 invoke  WriteConsole,hconsoleoutput,offset promptname,sizeof promptname,\   ; Prompt for the user's name.                offset charswritten,NULL        invoke  ReadConsole,hconsoleinput,offset usernbuff,sizeof usernbuff,\                offset charsread,NULL        cmp     charsread,23                                                        ; More chars than allowed?:                                   jb      all_ok                                                              ;  -no, so continue in all_ok.        invoke  cursorp,0,0                                                         ;  -yes, so:        invoke  paintb,0,0                                                          ;    *locate cursor and clears the screen.        invoke  WriteConsole,hconsoleoutput,offset inerror,sizeof inerror,\         ;    *show error message.                offset charswritten,NULL        invoke  ReadConsole,hconsoleinput,offset text,sizeof text,\                 ;*****(*Waits for the CR key.)*****                offset charsread,NULL                                                      jmp     again                                                                                     all_ok:                invoke  WriteConsole,hconsoleoutput,offset saveit,sizeof saveit,\                offset charswritten,NULL         invoke  ReadConsole,hconsoleinput,offset text,sizeof text,\                offset charsread,NULL        invoke  ExitProcess,0main    endppaintb  proc    colx:word,rowy:word                                                 ; Fill into green all the screen,        local   cc:COORD                                                            ;   (background and foreground).        mov     ax,colx        mov     cc.x,ax        mov     ax,rowy        mov     cc.y,ax        mov     eax,cc                invoke  FillConsoleOutputAttribute,hconsoleoutput,BACKGROUND_GREEN or\                FOREGROUND_GREEN,30000,eax,offset charsread        retpaintb  endpcursorp proc    col:word,row:word                                                   ; Sets the cursor location.        local   cc:COORD        mov     ax,col        mov     cc.x,ax        mov     ax,row        mov     cc.y,ax        mov     eax,cc        invoke  SetConsoleCursorPosition,hconsoleoutput,eax        ret cursorp endp                         end     main`
Felipe.

#### felipe

• Member
• Posts: 378
• assemble the unassembled.
##### Re: Control in console input?
« Reply #13 on: June 13, 2017, 05:13:00 AM »
Yeah, i added the SetConsoleMode function, first to allow just the CR key, and then for all the others (256 chars in the input buffer    ). I guess this would be the most basic 'algo' for some text mode programs. Thanks for all your help!

Code: [Select]
`.386.model  flat,stdcalloption  casemap:noneinclude \masm32\include\windows.incinclude \masm32\include\kernel32.incincludelib \masm32\lib\kernel32.lib.data?hconsoleinput   dd  ?hconsoleoutput  dd  ?charswritten    dd  ?charsread       dd  ?charsattset     dd  ?.dataprogramname db  "THE CONSOLE WAY!",0welcome     db  "Hi, welcome to this program!",0ah,0dhtext        db  256 dup(" "),0promptname  db  "Enter your name: "saveit      db  0ah,0ah,"Exit program?(Y/N): "usernbuff   db  256 dup(" "),0username    db  256 dup(" "),0inerror     db  "Error! names allowed of 20 chars max. only...",0cursorp proto   :word,:wordpaintb  proto   :word,:word.codemain    proc        invoke  GetStdHandle,STD_INPUT_HANDLE        mov     hconsoleinput,eax        invoke  GetStdHandle,STD_OUTPUT_HANDLE        mov     hconsoleoutput,eax        invoke  SetConsoleTitle,offset programname   again:        invoke  cursorp,0,0                                                         ; Locates the cursor.        invoke  paintb,0,0                                                          ; Clears the screen.        invoke  SetConsoleTextAttribute,hconsoleoutput,\                            ; Set the text and background                FOREGROUND_BLUE or FOREGROUND_GREEN or FOREGROUND_INTENSITY or\     ;  colors for the console.                BACKGROUND_GREEN             invoke  WriteConsole,hconsoleoutput,offset welcome,sizeof welcome,\         ; Welcome message in screen.                offset charswritten,NULL                 invoke  WriteConsole,hconsoleoutput,offset promptname,sizeof promptname,\   ; Prompt for the user's name.                offset charswritten,NULL        invoke  ReadConsole,hconsoleinput,offset usernbuff,sizeof usernbuff,\                offset charsread,NULL        cmp     charsread,23                                                        ; More chars than allowed?:                                   jb      all_ok                                                              ;  -no, so continue in all_ok.        invoke  cursorp,0,0                                                         ;  -yes, so:        invoke  paintb,0,0                                                          ;    *sets the cursor location and clears the screen.        invoke  WriteConsole,hconsoleoutput,offset inerror,sizeof inerror,\         ;    *show error message.                offset charswritten,NULL        invoke  SetConsoleMode,hconsoleinput,ENABLE_LINE_INPUT        invoke  ReadConsole,hconsoleinput,offset text,sizeof text,\                 ;    *Waits for the CR key.                offset charsread,NULL             invoke  SetConsoleMode,hconsoleinput,ENABLE_ECHO_INPUT or\                  ; Allow inputs again (256 chars).                ENABLE_LINE_INPUT                                                 jmp     again                                                                                     all_ok:                invoke  WriteConsole,hconsoleoutput,offset saveit,sizeof saveit,\                offset charswritten,NULL         invoke  ReadConsole,hconsoleinput,offset text,sizeof text,\                offset charsread,NULL        invoke  ExitProcess,0main    endppaintb  proc    colx:word,rowy:word                                                 ; Fill into green all the screen,        local   cc:COORD                                                            ;   (background and foreground).        mov     ax,colx        mov     cc.x,ax        mov     ax,rowy        mov     cc.y,ax        mov     eax,cc                invoke  FillConsoleOutputAttribute,hconsoleoutput,BACKGROUND_GREEN or\                FOREGROUND_GREEN,30000,eax,offset charsread        retpaintb  endpcursorp proc    col:word,row:word                                                   ; Sets the cursor location.        local   cc:COORD        mov     ax,col        mov     cc.x,ax        mov     ax,row        mov     cc.y,ax        mov     eax,cc        invoke  SetConsoleCursorPosition,hconsoleoutput,eax        ret cursorp endp                         end     main`
Felipe.

#### felipe

• Member
• Posts: 378
• assemble the unassembled.
##### Re: Control in console input?
« Reply #14 on: June 13, 2017, 06:32:20 AM »
Here one little more addition to this and a fix of some usless buffer: Now checks if you didn't enter any char (only CR key), only accept 2 chars as minimum for the name and a maximum of 20. The username buffer was useless (i think i forget it there... ) so i deleted.

Code: [Select]
`.386.model  flat,stdcalloption  casemap:noneinclude \masm32\include\windows.incinclude \masm32\include\kernel32.incincludelib \masm32\lib\kernel32.lib.data?hconsoleinput   dd  ?hconsoleoutput  dd  ?charswritten    dd  ?charsread       dd  ?charsattset     dd  ?.dataprogramname db  "THE CONSOLE WAY!",0welcome     db  "Hi, welcome to this program!",0ah,0dhtext        db  256 dup(" "),0promptname  db  "Enter your name: "saveit      db  0ah,0ah,"Exit program?(Y/N): "usernbuff   db  256 dup(" "),0inerror     db  "Error! names allowed of 20 chars as maximun only...",0inerror2    db  "Error! you must put a name here of 2 chars as minimum...",0cursorp proto   :word,:wordpaintb  proto   :word,:word.codemain    proc        invoke  GetStdHandle,STD_INPUT_HANDLE        mov     hconsoleinput,eax        invoke  GetStdHandle,STD_OUTPUT_HANDLE        mov     hconsoleoutput,eax        invoke  SetConsoleTitle,offset programname   again:        invoke  cursorp,0,0                                                         ; Locates the cursor.        invoke  paintb,0,0                                                          ; Clears the screen.        invoke  SetConsoleTextAttribute,hconsoleoutput,\                            ; Set the text and background                FOREGROUND_BLUE or FOREGROUND_GREEN or FOREGROUND_INTENSITY or\     ;  colors for the console.                BACKGROUND_GREEN             invoke  WriteConsole,hconsoleoutput,offset welcome,sizeof welcome,\         ; Welcome message in screen.                offset charswritten,NULL                 invoke  WriteConsole,hconsoleoutput,offset promptname,sizeof promptname,\   ; Prompt for the user's name.                offset charswritten,NULL        invoke  ReadConsole,hconsoleinput,offset usernbuff,sizeof usernbuff,\                offset charsread,NULL        cmp     charsread,23                                                        ; More chars than allowed?:                                   jb      all_ok                                                              ;  -no, so continue in all_ok.        invoke  cursorp,0,0                                                         ;  -yes, so:        invoke  paintb,0,0                                                          ;    *clears the screen.        invoke  WriteConsole,hconsoleoutput,offset inerror,sizeof inerror,\         ;    *show error message.                offset charswritten,NULL        invoke  SetConsoleMode,hconsoleinput,ENABLE_LINE_INPUT        invoke  ReadConsole,hconsoleinput,offset text,sizeof text,\                 ;    *Waits for the CR key.                offset charsread,NULL             invoke  SetConsoleMode,hconsoleinput,ENABLE_ECHO_INPUT or\                  ; Allows inputs again (256 chars).                ENABLE_LINE_INPUT                                                 jmp     again                                                                                     all_ok:            cmp     charsread,2            ja      all_ok2                                                             ; No input at all (just CR)?               invoke  cursorp,0,0                                                         ;  if so, set cursor location (0,0)        invoke  paintb,0,0                                                          ;   clears the screen        invoke  WriteConsole,hconsoleoutput,offset inerror2,sizeof inerror2,\       ;     show error message.                offset charswritten,NULL        invoke  SetConsoleMode,hconsoleinput,ENABLE_LINE_INPUT                      ; Just CR accepted.        invoke  ReadConsole,hconsoleinput,offset text,sizeof text,\                offset charsread,NULL        invoke  SetConsoleMode,hconsoleinput,ENABLE_ECHO_INPUT or\                  ; All keys accepted from now                ENABLE_LINE_INPUT                                                   ;   again.        jmp     againall_ok2:                                                                            ; Correct name format until here.        invoke  WriteConsole,hconsoleoutput,offset saveit,sizeof saveit,\                offset charswritten,NULL         invoke  ReadConsole,hconsoleinput,offset text,sizeof text,\                offset charsread,NULL        invoke  ExitProcess,0main    endppaintb  proc    colx:word,rowy:word                                                 ; Fill into green all the screen,        local   cc:COORD                                                            ;   (background and foreground).        mov     ax,colx        mov     cc.x,ax        mov     ax,rowy        mov     cc.y,ax        mov     eax,cc                invoke  FillConsoleOutputAttribute,hconsoleoutput,BACKGROUND_GREEN or\                FOREGROUND_GREEN,30000,eax,offset charsread        retpaintb  endpcursorp proc    col:word,row:word                                                   ; Sets the cursor location.        local   cc:COORD        mov     ax,col        mov     cc.x,ax        mov     ax,row        mov     cc.y,ax        mov     eax,cc        invoke  SetConsoleCursorPosition,hconsoleoutput,eax        ret cursorp endp                         end     main    `
Felipe.