News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

CRT redirect of stdin/out/err

Started by qWord, January 28, 2011, 03:13:06 PM

Previous topic - Next topic

qWord

hi,

reasoned the fact that you can't use CRT i/o function with consoles that are created using AllocConsole(), I've written some macros that allow reassignment of CRT's stdin/out/err.
The code is base on this Knowledge Base entry: Calling CRT Output Routines from a GUI Application
IMO such macros should be included in the masm32 package.

Here the macros and an example (create it as an GUI Application):
include masm32rt.inc

IFNDEF FILE
FILE struct
_ptr PCHAR ?
_cnt SDWORD ?
_base PCHAR ?
_flag SDWORD ?
_file SDWORD ?
_charbuf SDWORD ?
_bufsiz SDWORD ?
_tmpfname PCHAR ?
FILE ends
PFILE typedef ptr FILE
ENDIF

crt_assign_stdin macro hFile
crt_assign_stdxxx hFile,0
endm
crt_assign_stdout macro hFile
crt_assign_stdxxx hFile,1
endm
crt_assign_stderr macro hFile
crt_assign_stdxxx hFile,2
endm

crt_assign_stdxxx macro hFile,_type

IFNB <hFile>
?casx_txt TEXTEQU <&hFile>
ELSE
?casx_txt SUBSTR <STD_INPUT_HANDLE  STD_OUTPUT_HANDLE STD_ERROR_HANDLE  >,_type*18+1,18
?casx_txt CATSTR <rv(GetStdHandle,>,?casx_txt,<)>
ENDIF
?casx_file    SUBSTR <_stdin  _stdout _stderr>,_type*8+1,7

IFNDEF _stdout
.data?
align 4
_stdin PFILE ?
_stdout PFILE ?
_stderr PFILE ?
__tmphandle HANDLE ?
.code
ENDIF

push DUPLICATE_SAME_ACCESS
push 0
push 0
push OFFSET __tmphandle
push rv(GetCurrentProcess)
push ?casx_txt
push rv(GetCurrentProcess)
call DuplicateHandle
.if eax
.if ?casx_file
invoke crt_fclose,?casx_file
.endif
.if rv(crt__open_osfhandle,__tmphandle,4000h) != -1
mov __tmphandle,eax
.if rv(crt__fdopen,eax,@CatStr(<!">,@SubStr(<rww>,_type+1,1),<!">))
mov ?casx_file,eax
invoke crt___p__iob
push eax
invoke MemCopy,?casx_file,ADDR [eax+_type*sizeof(FILE)],SIZEOF FILE
pop eax
invoke crt_setvbuf,ADDR [eax+_type*sizeof(FILE)],NULL,4,0 ; _IONBF
.else
invoke crt__close,__tmphandle
mov ?casx_file,0
.endif
.else
mov ?casx_file,0
.endif
.endif
endm


.code
main proc
LOCAL sz[256]:CHAR

.data?
hLogFile HANDLE ?
.code

invoke AllocConsole
crt_assign_stdout
crt_assign_stdin

; test crt console functions
fn crt_printf,chr$("Hallo welt ",13,10)
fn crt_scanf,"%s",ADDR sz
fn crt_printf,chr$("%s",13,10),ADDR sz

mov hLogFile,fcreate("log.txt")

; redirect stdout to logfile
crt_assign_stdout hLogFile

fn crt_printf,chr$("redirected text .... ;-)",13,10)

fclose hLogFile

; set stdout to console
crt_assign_stdout

fn crt_printf,chr$("read string from file:",13,10)

; input from file
mov hLogFile,fopen("log.txt")
crt_assign_stdin hLogFile

fn crt_scanf,chr$("%[^",13,10,"]"),ADDR sz
fn crt_printf,chr$("%s",13,10),ADDR sz

fclose hLogFile


inkey
ret

main endp
end main


regards, qWord

EDIT: new code with handle-management
FPU in a trice: SmplMath
It's that simple!