News:

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

odd redirect response from stdout to console

Started by thomas_remkus, October 07, 2008, 08:11:50 PM

Previous topic - Next topic

thomas_remkus

I would like to output text to the console and/or output the same text to a file via redirection (">" or ">>"). When I use the below code with the console it works perfectly. When I use it with a redirection it gives debug errors and pulls up the system debugger. I presume this is because the redirection is offering a file handle and not stdout. What can I do to make this compatible with both needs:

.686
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\msvcrt.inc
include \masm32\include\masm32.inc
include \masm32\macros\macros.asm

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\msvcrt.lib

.const
ccBlack          EQU 0
ccDarkBlue       EQU 1
ccDarkGreen      EQU 2
ccSoftBlue       EQU 3
ccDarkRed        EQU 4
ccDarkPurple     EQU 5
ccTan            EQU 6
ccLightGrey      EQU 7
ccGrey           EQU 8
ccBrightBlue     EQU (1 or ccGrey)
ccBrightGreen    EQU (2 or ccGrey)
ccBabyBlue       EQU (3 or ccGrey)
ccBrightRed      EQU (4 or ccGrey)
ccBrightPurple   EQU (5 or ccGrey)
ccYellow         EQU (6 or ccGrey)
ccWhite          EQU (7 or ccGrey)

.data
hStdOut HANDLE 0
csbi CONSOLE_SCREEN_BUFFER_INFO <>
szHead db "ÚÄÄÄÄÄ¿", 13, 10, "³", 0
szHello db "hello", 0
szFoot db "³", 13, 10, "ÀÄÄÄÄÄÙ", 13, 10, 0

.code
start:
invoke GetStdHandle, STD_OUTPUT_HANDLE
mov hStdOut, eax

invoke GetConsoleScreenBufferInfo, hStdOut, addr csbi

invoke SetConsoleTextAttribute, hStdOut, ccBrightBlue
invoke lstrlen, addr szHead
invoke WriteFile, hStdOut, addr szHead, eax, NULL, NULL
invoke SetConsoleTextAttribute, hStdOut, ccBrightGreen
invoke lstrlen, addr szHello
invoke WriteFile, hStdOut, addr szHello, eax, NULL, NULL
invoke SetConsoleTextAttribute, hStdOut, ccBrightBlue
invoke lstrlen, addr szFoot
invoke WriteFile, hStdOut, addr szFoot, eax, NULL, NULL

movzx eax, csbi.wAttributes
invoke SetConsoleTextAttribute, hStdOut, eax

xor eax, eax
invoke ExitProcess, eax
end start

MichaelW

It triggers an access violation exception, and the problem is with the lpNumberOfBytesWritten parameter of WriteFile:

Quote
If lpOverlapped is NULL, lpNumberOfBytesWritten cannot be NULL.
eschew obfuscation

Tedd

You do need to supply lpNumberOfBytesWritten if you expect to redirect the output to a file (it seems to work okay when going to console, but not if you redirect to a file - so just always provide it.)

Also, there's a slight annoyance if you try to write Unicode characters - WriteConsole handles it, but WriteFile (directed to a console) doesn't. So you have to call GetConsole mode to check whether you have a real console (it fails if not) and then use the appropriate functions (and add WideCharToMultiByte for WriteFile; you can also use that to skip the console attribute stuff.)
No snowflake in an avalanche feels responsible.