The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: bomz on September 01, 2010, 05:24:29 PM

Title: Console IN
Post by: bomz on September 01, 2010, 05:24:29 PM
..............................................
   invoke GetStdHandle, STD_INPUT_HANDLE
   .IF eax!=INVALID_HANDLE_VALUE
   invoke ReadFile, eax, addr String, sizeof String, addr Lenth, NULL
   .IF Lenth!=0
   invoke OemToChar, addr String, addr Buffer
..............................................

Help me please.
TYPE MY.TXT | MYPROG.EXE
error occurs in invoke GetStdHandle, STD_INPUT_HANDLE, if size of MY.TXT more than about 3.5 kb.Why? (trying to write to unexisting chanel)

How to differ this event
echo off|MYPROG.EXE
and this
MYPROG.EXE


invoke CreateFile,CONIN$,GENERIC_READ,0,0,OPEN_EXISTING,0,0
How CONIN$ use in CreateFile?
Title: Re: Console IN
Post by: frktons on September 01, 2010, 07:04:10 PM
Quote from: bomz on September 01, 2010, 05:24:29 PM
..............................................
   invoke GetStdHandle, STD_INPUT_HANDLE
   .IF eax!=INVALID_HANDLE_VALUE
   invoke ReadFile, eax, addr String, sizeof String, addr Lenth, NULL
   .IF Lenth!=0
   invoke OemToChar, addr String, addr Buffer
..............................................

Help me please.
TYPE MY.TXT | MYPROG.EXE
error occurs in invoke GetStdHandle, STD_INPUT_HANDLE, if size of MY.TXT more than about 3.5 kb.Why? (trying to write to unexisting chanel)

How to differ this event
echo off|MYPROG.EXE
and this
MYPROG.EXE


invoke CreateFile,CONIN$,GENERIC_READ,0,0,OPEN_EXISTING,0,0
How CONIN$ use in CreateFile?

As far as I know GetStdHandle is used for the Console handle, for files maybe
you have to use another API call.
Not sure anyway, the handles can be used in many ways.
Title: Re: Console IN
Post by: bomz on September 01, 2010, 07:13:52 PM
readfile understand console handle too. code is working, but mistakes occurs for input biger than ~4,07 КБ (4 174 байт) bytes
http://msdn.microsoft.com/en-us/library/aa365467(VS.85).aspx
Quote
Parameters

hFile [in]

    A handle to the device (for example, a file, file stream, physical disk, volume, console buffer, tape drive, socket, communications resource, mailslot, or pipe).
Title: Re: Console IN
Post by: frktons on September 01, 2010, 07:17:00 PM
Quote from: bomz on September 01, 2010, 07:13:52 PM
readfile understand console handle too. code is working, but mistakes occurs for input biger that ~3700 bytes

Usually you:
1. get an handle
2. open the file
3. read the file
4. close the file

I'm not sure if you do all of the above, and in the correct order.
Title: Re: Console IN
Post by: bomz on September 01, 2010, 07:20:39 PM
it's working. put CONIN to clipboard
Quote
.386

.model flat, stdcall
option casemap :none

include \MASM32\INCLUDE\windows.inc
include \MASM32\INCLUDE\user32.inc
include \MASM32\INCLUDE\kernel32.inc
includelib \MASM32\LIB\user32.lib
includelib \MASM32\LIB\kernel32.lib

.data

.data?
Lenth dd ?
hMemory dd ?
pMemory dd ?
Buffer db 65536 dup(?)
String db 65536 dup(?)

;hStdIn dd ?
;evEvents word ?
;evBuffer INPUT_RECORD <>

.code
start:
   invoke GetStdHandle, STD_INPUT_HANDLE
   .IF eax!=INVALID_HANDLE_VALUE
   invoke ReadFile, eax, addr String, sizeof String, addr Lenth, NULL
   .IF (Lenth)   ;.IF Lenth!=0
   invoke OemToChar, addr String, addr Buffer
   dec Lenth
   invoke GlobalAlloc,LMEM_MOVEABLE,Lenth
   mov  hMemory,eax
   invoke GlobalLock,hMemory
   mov pMemory,eax
   invoke lstrcpy,pMemory,addr Buffer
   invoke GlobalUnlock,hMemory
   invoke OpenClipboard,NULL
   invoke EmptyClipboard
   invoke SetClipboardData,CF_TEXT,hMemory
   invoke CloseClipboard
   invoke GlobalFree,hMemory
   .ENDIF
   .ENDIF
   invoke ExitProcess,0
end start
Title: Re: Console IN
Post by: Vortex on September 01, 2010, 07:40:58 PM
Hi bomz,

Another one with C run-time functions :


include     scanf.inc

.data

string1     db 'What is your name?',13,10,13,10,0
string2     db 'Nice to meet you %s',13,10,0
f1          db '%s',0


.data?

szName      db 32 dup(?)

.code

start:

    invoke  crt_printf,ADDR string1
    invoke  crt_scanf,ADDR f1,ADDR szName
    invoke  crt_printf,ADDR string2,ADDR szName

    invoke  ExitProcess,0

END start
Title: Re: Console IN
Post by: bomz on September 01, 2010, 07:48:00 PM
thanks I try it, but I want do this using only windows api
Title: Re: Console IN
Post by: bomz on September 01, 2010, 07:52:27 PM
Quote
.386

.model flat, stdcall
option casemap :none

include \MASM32\INCLUDE\windows.inc
include \MASM32\INCLUDE\user32.inc
include \MASM32\INCLUDE\kernel32.inc
includelib \MASM32\LIB\user32.lib
includelib \MASM32\LIB\kernel32.lib
include     \MASM32\INCLUDE\msvcrt.inc
includelib \MASM32\LIB\msvcrt.lib
.data

string1     db 'What is your name?',13,10,13,10,0
string2     db 'Nice to meet you %s',13,10,0
f1          db '%s',0


.data?

szName      db 32 dup(?)

.code

start:

    invoke  crt_printf,ADDR string1
    invoke  crt_scanf,ADDR f1,ADDR szName
    invoke  crt_printf,ADDR string2,ADDR szName

    invoke  ExitProcess,0

END start
Title: Re: Console IN
Post by: bomz on September 02, 2010, 12:32:41 AM
Quote
BufferSize     COORD <>
...
mov BufferSize.x, 80
mov BufferSize.y, 10000
invoke SetConsoleScreenBufferSize, eax, addr BufferSize
this don't fix error. I am not shure that use this correct

using this construction
Quote
invoke  StdIn,ADDR String,sizeof String
mov Lenth,eax
cause the same error

and this too
    invoke  crt_scanf,ADDR f1,ADDR szName
Title: Re: Console IN
Post by: japheth on September 02, 2010, 07:04:10 AM

   invoke SetClipboardData,CF_TEXT,hMemory
   invoke CloseClipboard
   invoke GlobalFree,hMemory


I guess you shouldn't free the memory handle.

Here's a working clipboard sample:


CopyStringToClipboard proc public hWnd:HWND, pszText:LPSTR

local hGlobal:HGLOBAL
local pGlobal:ptr byte

invoke lstrlen, pszText
inc eax
invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_DDESHARE, eax
mov hGlobal,eax
.if (eax != 0)
invoke GlobalLock,hGlobal
.if (eax)
invoke lstrcpy, eax, pszText
invoke GlobalUnlock,hGlobal
invoke OpenClipboard, hWnd
invoke EmptyClipboard
invoke SetClipboardData,CF_TEXT,hGlobal
invoke CloseClipboard
.endif
.endif
ret
align 4

CopyStringToClipboard endp

Title: Re: Console IN
Post by: bomz on September 02, 2010, 07:12:00 AM
in your code memory free when your call invoke ExitProcess,0

PS or RET

the question is not how to use clipboard but how use CONIN$, you may use    invoke  StdOut,ADDR String to see what you read from CONIN$. I need it because invoke OemToChar, addr String, addr Buffer - my windows xp russian. In windows vista and windows 2008 server there is a utility CLIP.EXE, it's do the same but can put to clipboard more than 8 kb. and no error occurs

this code call the same error
Quote
.386

.model flat, stdcall
option casemap :none

include \MASM32\INCLUDE\windows.inc
include \MASM32\INCLUDE\user32.inc
include \MASM32\INCLUDE\kernel32.inc
includelib \MASM32\LIB\user32.lib
includelib \MASM32\LIB\kernel32.lib

.data

.code
start:
   invoke GetStdHandle, STD_INPUT_HANDLE
   invoke ExitProcess,0
end start

May be buffer may be resize hear???
Quote
ECHO OFF
COLOR 9F
CLS
C:\masm32\bin\ml.exe /c /coff current.asm
C:\masm32\bin\link.exe /subsystem:console current.obj
DEL current.obj
pause
or hear
Quote
.386

.model flat, stdcall
option casemap :none
Title: Re: Console IN
Post by: Yuri on September 02, 2010, 08:11:24 AM
"CONIN$" is a string, not a label. So, something like this should work:

.data

szConIn     DB "CONIN$",0

.code

invoke CreateFile,addr szConIn,GENERIC_READ,0,0,OPEN_EXISTING,0,0
Title: Re: Console IN
Post by: bomz on September 02, 2010, 08:15:01 AM
I try so no result

may be so - 2>CON   . ??????
Title: Re: Console IN
Post by: jj2007 on September 02, 2010, 08:42:36 AM
Be sure to use FILE_SHARE_READ when opening "CONIN$"

http://support.microsoft.com/kb/90088
Title: Re: Console IN
Post by: bomz on September 02, 2010, 08:44:42 AM
thanks
Title: Re: Console IN
Post by: bomz on September 02, 2010, 08:51:51 AM
szConIn     DB "CONIN$",0

invoke CreateFile,addr szConIn,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0
   .IF eax!=INVALID_HANDLE_VALUE


no INVALID_HANDLE_VALUE but no result - copy CONIN
Title: Re: Console IN
Post by: Yuri on September 02, 2010, 10:09:19 AM
CreateFile doesn't copy anything. It creates a handle to the console input buffer. This handle should be used with ReadConsole or ReadFile.

This code compiles and works OK for me:

.386

.model flat, stdcall
option casemap :none

include \MASM32\INCLUDE\windows.inc
include \MASM32\INCLUDE\kernel32.inc
includelib \MASM32\LIB\kernel32.lib

.data
    szConIn         DB "CONIN$",0
    szConOut        DB "CONOUT$",0
    szRequest       DB "Enter some text here: "
    szResult        DB "You entered: "
    hIn             DD 0
    hOut            DD 0
    BytesRead       DD 0
    BytesWritten    DD 0
    Buf             DB 100h DUP (0)

.code

start:
   invoke CreateFile, addr szConIn, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0
   mov hIn,eax
   invoke CreateFile, addr szConOut, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0
   mov hOut,eax
   invoke WriteConsole, hOut, addr szRequest, sizeof szRequest, addr BytesWritten, 0
   invoke ReadConsole, hIn, addr Buf, sizeof Buf, addr BytesRead, 0
   invoke WriteConsole, hOut, addr szResult, sizeof szResult, addr BytesWritten, 0
   invoke WriteConsole, hOut, addr Buf, BytesRead, addr BytesWritten, 0
   invoke ExitProcess,0
end start

Title: Re: Console IN
Post by: bomz on September 02, 2010, 10:12:48 AM
nobody say - copy
Title: Re: Console IN
Post by: bomz on September 02, 2010, 10:18:08 AM
not working - lenth=0
Quote
.386

.model flat, stdcall
option casemap :none

include \MASM32\INCLUDE\windows.inc
include \MASM32\INCLUDE\user32.inc
include \MASM32\INCLUDE\kernel32.inc
includelib \MASM32\LIB\user32.lib
includelib \MASM32\LIB\kernel32.lib

.data
szConIn     DB "CONIN$",0

.data?
Lenth dd ?
hMemory dd ?
pMemory dd ?
Buffer db 65536 dup(?)
String db 65536 dup(?)

hStdIn dd ?
;evEvents word ?
;evBuffer INPUT_RECORD <>

.code
start:

invoke CreateFile, addr szConIn, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0
mov hStdIn,eax
invoke ReadConsole, hStdIn, addr String, sizeof String, addr Lenth, 0
;   .IF Lenth!=0
   invoke OemToChar, addr String, addr Buffer
   dec Lenth
   invoke GlobalAlloc,LMEM_MOVEABLE,Lenth
   mov  hMemory,eax
   invoke GlobalLock,hMemory
   mov pMemory,eax
   invoke lstrcpy,pMemory,addr Buffer
   invoke GlobalUnlock,hMemory
   invoke OpenClipboard,NULL
   invoke EmptyClipboard
   invoke SetClipboardData,CF_TEXT,hMemory
   invoke CloseClipboard
   invoke GlobalFree,hMemory
;   .ENDIF
   invoke ExitProcess,0
end start
Title: Re: Console IN
Post by: bomz on September 02, 2010, 10:24:11 AM
it's mean that STD_INPUT_HANDLE and CONIN$ is different. But How change console buffer?
and differ echo off | MYPROG.EXE
Title: Re: Console IN
Post by: Yuri on September 02, 2010, 01:08:27 PM
Why do you want to change it? What for?
Title: Re: Console IN
Post by: bomz on September 02, 2010, 01:31:13 PM
to know how it's changed.

to get through STDIN more than 4 kb
Title: Re: Console IN
Post by: redskull on September 02, 2010, 02:00:04 PM
"CONIN$ gets a handle to the console input buffer, even if the SetStdHandle function redirects the standard input handle. To get the standard input handle, use the GetStdHandle function."

-r
Title: Re: Console IN
Post by: bomz on September 02, 2010, 02:05:25 PM
but how change buffer size before program starts?
Title: Re: Console IN
Post by: redskull on September 02, 2010, 02:49:00 PM
You don't; change the number of character you want to read.  Reduce the amount of events you are reading (from 65535 down to about 100), and then put it into a loop, ending when characters read != sizeof buffer.  If you want input piped to you, you must use ReadFile and not ReadConsole, and the STD_INPUT_HANDLE will work fine

-r
Title: Re: Console IN
Post by: Yuri on September 02, 2010, 03:05:33 PM
Here is an example of reading in a loop. Hope I didn't confuse MASM syntax.  ::)

.386

.model flat, stdcall
option casemap :none

include \MASM32\INCLUDE\windows.inc
include \MASM32\INCLUDE\kernel32.inc
includelib \MASM32\LIB\kernel32.lib

.data
    hIn             DD 0
    hOut            DD 0
    BytesRead       DD 0
    BytesWritten    DD 0
    Buf             DB 100h DUP (0)

.code

start:
    invoke GetStdHandle, STD_INPUT_HANDLE
    mov hIn,eax
    invoke GetStdHandle, STD_OUTPUT_HANDLE
    mov hOut,eax
    @@:
        invoke ReadFile, hIn, addr Buf, sizeof Buf, addr BytesRead, NULL
        test eax,eax
        jz @F
            invoke WriteFile, hOut, addr Buf, BytesRead, addr BytesWritten, NULL
    jmp @B
        @@:
    ret   
end start
Title: Re: Console IN
Post by: redskull on September 02, 2010, 03:09:20 PM
Depending on the goal, you can leave the buffer itself sized at FFFF, but read characters into it a few hundred at a time (adjusting a pointer after each read).  That way, after the loop, you still have one big contigious array of all the data to do with what you please.

-r
Title: Re: Console IN
Post by: bomz on September 02, 2010, 03:10:06 PM
yes it's works
Title: Re: Console IN
Post by: bomz on September 02, 2010, 03:20:50 PM
trying with 1.5 mb , and how to know the size of data in STDIN???
Title: Re: Console IN
Post by: redskull on September 02, 2010, 03:25:32 PM
GetNamedPipeInfo() will tell you the actual size; A quick test on my system shows that a console pipe buffer has a size of 00001000h (4K), for both the input and output buffers.  If you really want to be slick, use that function to get the size, and read that many bytes at a time in your loop for max effeciency.

-r
Title: Re: Console IN
Post by: bomz on September 02, 2010, 03:28:45 PM
thanks a lot. I trying this. (http://i012.radikal.ru/0811/fe/024c31290450.gif)
Title: Re: Console IN
Post by: bomz on September 02, 2010, 06:20:08 PM
how to differ
Quote
include \masm32\include\masm32rt.inc

.data

.data?
Lenth dd ?

.code
start:
   invoke GetStdHandle, STD_INPUT_HANDLE
   invoke GetFileSize,eax,addr Lenth
   MsgBox 0, str$(eax), 0, MB_OK
   invoke ExitProcess,0
end start


Quote
ECHO OFF
COLOR 9F
CLS
echo off | current.exe
pause

(http://s46.radikal.ru/i111/1009/64/6aa4d57193ba.png)
Quote
ECHO OFF
COLOR 9F
CLS
current.exe
pause
(http://s59.radikal.ru/i166/1009/32/23f005965f48.png)


Quote
ECHO OFF
COLOR 9F
CLS
type my.txt | current.exe
pause
(http://s58.radikal.ru/i162/1009/78/33e1c543ddce.png)
strange but buffer size not 4096 but 4176
Title: Re: Console IN
Post by: redskull on September 02, 2010, 06:28:52 PM
Use GetFileType() on the handle returned by GetStdHandle() to determine if it's a standard console or a pipe from another program. 

-r
Title: Re: Console IN
Post by: bomz on September 02, 2010, 06:31:37 PM
I think how to determine needed memorysize for clipboard.
allocate 10 mb and cut if need, or resize each 4176 byte
Title: Re: Console IN
Post by: bomz on September 03, 2010, 12:38:31 AM
Quote
.386

.model flat, stdcall
option casemap :none

include \MASM32\INCLUDE\windows.inc
include \MASM32\INCLUDE\user32.inc
include \MASM32\INCLUDE\kernel32.inc
includelib \MASM32\LIB\user32.lib
includelib \MASM32\LIB\kernel32.lib

.data

.data?
StdIn      dd ?
Lenth      dd ?
hMemory      dd ?
pMemory      dd ?
BytesRead   dd ?

.code
start:
   invoke GetStdHandle, STD_INPUT_HANDLE
   .IF eax!=INVALID_HANDLE_VALUE
   mov StdIn, eax
   invoke GetFileSize,eax,addr Lenth
   .IF eax!=-1

   invoke GlobalAlloc,LMEM_MOVEABLE,1048576
   mov  hMemory,eax
   invoke GlobalLock,hMemory
   mov pMemory,eax
Next:
   invoke ReadFile, StdIn, pMemory, 4096, addr BytesRead, NULL
   mov eax, BytesRead
   add pMemory, eax
   add Lenth, eax
   cmp BytesRead, 0
   jne Next

   invoke GlobalUnlock,hMemory
   inc Lenth
   invoke GlobalReAlloc,hMemory,Lenth,GMEM_MOVEABLE
   mov  hMemory,eax
   invoke OpenClipboard,NULL
   invoke EmptyClipboard
   invoke SetClipboardData,CF_TEXT,hMemory
   invoke CloseClipboard
   invoke GlobalFree,hMemory

   .ENDIF
   .ENDIF
   invoke ExitProcess,0
end start
Title: Re: Console IN
Post by: Yuri on September 03, 2010, 03:13:46 AM
GlobalFree is not needed here.

Quote from: SetClipboardData
If SetClipboardData succeeds, the system owns the object identified by the hMem parameter. The application may not write to or free the data once ownership has been transferred to the system
Title: Re: Console IN
Post by: bomz on September 03, 2010, 08:51:33 AM
ok

strange but I can't Reallock memory to biggersize, only cut it.
Title: Re: Console IN
Post by: Yuri on September 03, 2010, 10:45:34 AM
If you mean that the pointer changes, then it's normal. The next addresses are probably already allocated for other needs, so your block can't be extended in place.
As far as I know, you can reserve a large range of addresses through VirtualAlloc, then they won't be taken away and you will be able to commit more memory if needed to extend the initial block. Read about 'Virtual Memory Functions' on MSDN.
Quote
Reserving pages prevents needless consumption of physical storage, while enabling a process to reserve a range of its address space into which a dynamic data structure can grow. The process can allocate physical storage for this space, as needed.

This sounds promising, though I never used this technique myself.
Title: Re: Console IN
Post by: bomz on September 03, 2010, 11:09:11 AM
GlobalReAlloc  - hear any words about resizing to bigger size.
Thanks
Title: Re: Console IN
Post by: Yuri on September 03, 2010, 11:25:12 AM
Quote from: GlobalReAlloc
If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Call GetLastError and see what the error is.