Consoles and win32

We can perform console I/O with the ReadFile() and WriteFile() functions, but it’s easier to use the specific console I/O functions, ReadConsole() and WriteConsole(). The ReadConsole() and WriteConsole() functions both accept TCHAR, or generic characters. TCHAR characters can be used to describe either ANSI single byte characters or wide double byte Unicode characters; thus, the TCHAR type allows us to be narrow/wide neutral.

The GetStdHandle() function gives us a mechanism for retrieving the standard input, STDIN, the Standard Output, STDOUT, and the standard error handles, STDERR. The GetStdHandle() function takes a single parameter that can be one of three values, STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, and STD_ERROR_HANDLE.

#include "stdafx.h"
#include <Windows.h>

int main()
{
 HANDLE hStdin, hStdout, hStderr;

 hStdin = GetStdHandle(STD_INPUT_HANDLE);
 if (hStdin != INVALID_HANDLE_VALUE) {
 printf("Handle to standard input acquired.\n");
 }
 //combine the steps
 if ((hStdout = GetStdHandle(STD_OUTPUT_HANDLE)) != INVALID_HANDLE_VALUE) {
 printf("Handle to standard output acquired.\n");
 }

 if ((hStderr = GetStdHandle(STD_ERROR_HANDLE)) != INVALID_HANDLE_VALUE){
 printf("Handle to standard error acquired.\n");
 }

 return 0;
}

The SetConsoleMode() and GetConsoleMode() functions allow us to modify and view the console mode for the input or screen buffer. The console mode describes how characters are processed via flags; five commonly used flags, which are enabled by default, are ENABLE_LINE_INPUT, ENABLE_ECHO_INPUT, ENABLE_PROCESSED_INPUT, ENABLE_PROCESSED_OUTPUT, and ENABLE_WRAP_AT_EOL_OUTPUT. Both the SetConsoleMode() and GetConsoleMode() functions return a Boolean value indicating success or failure.

 #include "stdafx.h"
#include <Windows.h>

void PrintConsoleInputFlags(DWORD dwFlags);
void PrintConsoleOutputFlags(DWORD dwFlags);

int main()
{
 HANDLE hStdin, hStdout;
 DWORD dwStdinFlags, dwStdoutFlags;
 //get handles to stdin and stdout
 hStdin = GetStdHandle(STD_INPUT_HANDLE);
 hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

 if (hStdin == INVALID_HANDLE_VALUE || hStdout == INVALID_HANDLE_VALUE) {
 printf("Error getting stdin or stdout.\n");
 exit(EXIT_FAILURE);
 }

 //GetConsoleMode returns Boolean value indicating success
 if (GetConsoleMode(hStdin, &dwStdinFlags)) {
 printf("Console mode for stdin acquired.\n");
 }

 if (GetConsoleMode(hStdout, &dwStdoutFlags)) {
 printf("Console mode for stdout acquired.\n");
 }

 printf("\nFor stdin: \n");
 PrintConsoleInputFlags(dwStdinFlags);
 

 printf("\nFot stdout: \n");
 PrintConsoleOutputFlags(dwStdoutFlags);

 return 0;
}

void PrintConsoleInputFlags(DWORD dwFlags) {
 if (dwFlags & ENABLE_ECHO_INPUT) {
 printf("Echo input enabled.\n");
 }
 if (dwFlags & ENABLE_INSERT_MODE) {
 printf("Insert mode enabled.\n");
 }
 if (dwFlags & ENABLE_LINE_INPUT) {
 printf("Line input enabled.\n");
 }
 if (dwFlags & ENABLE_MOUSE_INPUT) {
 printf("Mouse input enabled.\n");
 }
 if (dwFlags & ENABLE_PROCESSED_INPUT) {
 printf("Processed input enabled.\n");
 }
}

void PrintConsoleOutputFlags(DWORD dwFlags) {
 if (dwFlags & ENABLE_PROCESSED_OUTPUT) {
 printf("Processed output enabled.\n");
 }
}

The ReadConsole() and WriteConsole() functions both return TRUE if and only if the action succeeds. The ReadConsole() function takes a handle to the input buffer, and then two length parameters indicating lengths in generic characters, not bytes. The WriteConsole() function is essentially the same, except the buffer is a pointer to a constant.

#include "stdafx.h"
#include <Windows.h>


int main()
{
 const int Buffer_Length = 2056;

 HANDLE hStdin, hStdout;
 DWORD dwCharsRead, dwCharsWritten;
 TCHAR tszBuffer[Buffer_Length];

 BOOL bSuccess;

 //get handles for standard input
 //and standard output
 hStdin = GetStdHandle(STD_INPUT_HANDLE);
 hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

 if (hStdin == INVALID_HANDLE_VALUE) {
 exit(EXIT_FAILURE);
 }
 else {
 printf("Handle to stdin acquired.\n");
 }

 if (hStdout == INVALID_HANDLE_VALUE) {
 exit(EXIT_FAILURE);
 }
 else {
 printf("Handle to stdout acquired.\n");
 }

 printf("Please enter in some text!\n");

 bSuccess = ReadConsole(hStdin, tszBuffer, Buffer_Length - 2, &dwCharsRead, NULL);

 //replace the enter with the null character
 if (bSuccess) {
 printf("Successfully read from console.\n");
 printf("%d chars read.\n", dwCharsRead);
 tszBuffer[dwCharsRead - 2] = '';
 }

 bSuccess = WriteConsole(hStdout, tszBuffer, _tcslen(tszBuffer), &dwCharsWritten, NULL);

 if (bSuccess) {
 printf("\nSuccessfully wrote to console.\n");
 printf("%d chars written.\n", dwCharsWritten);
 }


 //close the handles!
 CloseHandle(hStdin);
 CloseHandle(hStdout);

 return 0;
}

Note that a Windows process can only have one console.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s