Review of Console I/O with win32 functions

The SetConsoleMode() function can be used to set the input and output modes of the console’s input and output buffers. The function takes two arguments; the first argument is the handle to the console, which can be acquired via the GetStdHandle() function.

#include <Windows.h>
#include <stdlib.h>
#include <stdio.h>


int _tmain(int argc, _TCHAR* argv[])
{
	HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
	HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

	//check to see we got the input handle
	if(hInput == INVALID_HANDLE_VALUE){
		printf("Error getting input handle.\n");
		exit(EXIT_FAILURE);
	} else {
		printf("Input handle acquired.\n");
	}

	//check to see we got the output handle
	if(hOutput == INVALID_HANDLE_VALUE){
		printf("Error getting output handle.\n");
		exit(EXIT_FAILURE);
	} else {
		printf("Output handle acquired.\n");
	}

	return 0;
}

The second argument to the SetConsoleMode() function is a DWORD value that specifies how the characters are processed. There are five commonly used flags that are in fact enabled by default; ENABLE_LINE_INPUT, which specifies that the ReadConsole() function returns when it encounters a carriage return characters; ENABLE_ECHO_INPUT, which echoes characters to the screen as they are read; ENABLE_PROCESSED_INPUT, which processes backspace, carriage return, and line feed characters; ENABLE_PROCESSED_OUTPUT, which processes backspace, carriage return, and line feed characters; and ENABLE_WRAP_AT_EOL_OUTPUT, which enables line wrap for both normal and echoed output.

#include <Windows.h>
#include <stdio.h>

int _tmain(int argc, _TCHAR* argv[])
{
	printf("ENABLE_LINE_INPUT %u\n", ENABLE_LINE_INPUT);
	printf("ENABLE_ECHO_INPUT %u\n", ENABLE_ECHO_INPUT);
	printf("ENABLE_PROCESSED_INPUT %u\n", ENABLE_PROCESSED_INPUT);
	printf("ENABLE_PROCESSED_OUTPUT %u\n", ENABLE_PROCESSED_OUTPUT);
	printf("ENABLE_WRAP_AT_EOL_OUTPUT %u\n", ENABLE_WRAP_AT_EOL_OUTPUT);

	return 0;
}

The SetConsoleMode() function returns True if the function succeeds and False, otherwise.

It is possible to perform console I/O using ReadFile() and WriteFile(), but it is somewhat easier just to use the console I/O functions ReadConsole() and WriteConsole(). The ReadConsole() and WriteConsole() functions process TCHAR values, rather than bytes, and operates according to the console mode.

The ReadConsole() function has five parameters. While the fifth parameter can be set to NULL, the rest must be filled out. The first parameter is a handle to the console input buffer that has GENERIC_READ access. The second parameter is a pointer to a buffer that stores the data read from the console input buffer. The third argument is the number of characters to be read. The fourth argument is a pointer to a DWORD value that stores the number of characters actually read. The ReadConsole() function returns True if the read action succeeds.

#include <Windows.h>
#include <stdlib.h>
#include <stdio.h>

int _tmain(int argc, _TCHAR* argv[])
{
	const int Buffer_Length = 1024;
	TCHAR szBuffer[Buffer_Length];
	DWORD dwLength, dwRead;
	HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
	
	if(hIn==INVALID_HANDLE_VALUE){
		printf("Invalid handle value.\n");
		exit(EXIT_FAILURE);
	}

	//get length of buffer
	dwLength = _tcslen(szBuffer);

	printf("Please enter the text: ");

	if(ReadConsole(hIn, szBuffer, dwLength, &dwRead, NULL)){
		printf("Read from console.\n");
		printf("%d characters read (includes carriage return / line feed).\n", dwRead);
	} else {
		printf("Failed to read from console.\n");
		exit(EXIT_FAILURE);
	}

        CloseHandle(hIn);

	return 0;
}

Please note that a process can only have one console at a time.

The WriteConsole() function is essentially the same as the ReadConsole() function. The first parameter passed to WriteConsole() is a handle to the console screen buffer. The second parameter is the buffer storing the TCHAR values we wish to write to the console. The third parameter indicates the number of characters we want to write. The fourth parameter is a pointer to a DWORD value that stores the number of characters actually written. We will again pass NULL for the fifth parameter.

#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>

int _tmain(int argc, _TCHAR* argv[])
{
	DWORD dwCount, dwMsgLen;
	HANDLE hIn, hOut;
	BOOL bSuccess;
	TCHAR szBuffer[2056], szWriteBuffer[2112];

	hIn = GetStdHandle(STD_INPUT_HANDLE);
	hOut = GetStdHandle(STD_OUTPUT_HANDLE);

	if(hIn == INVALID_HANDLE_VALUE || hOut == INVALID_HANDLE_VALUE){
		printf("Error getting the handles to the console.\n");
		exit(EXIT_FAILURE);
	}

	//read the text
	printf("Please enter some text: ");

	bSuccess = ReadConsole(hIn, szBuffer, _tcslen(szBuffer), &dwCount, NULL);

	if(!bSuccess){
		printf("Error reading from the console.\n");
		exit(EXIT_FAILURE);
	}

	
	dwMsgLen = dwCount - 2;
	

	szBuffer[dwMsgLen] = '';

	//TCHAR mapping to sprintf()
	swprintf_s(szWriteBuffer, _T("You wrote: '%s' [%d TCHAR written.]\n"), szBuffer, dwMsgLen);

	WriteConsole(hOut, szWriteBuffer, _tcslen(szWriteBuffer), &dwCount, NULL);

	//close the handles!
	CloseHandle(hIn);
	CloseHandle(hOut);

	return 0;
}

If you have any interest in learning standard C, take a look at my book http://www.amazon.com/Big-Als-C-Standard-ebook/dp/B00A4JGE0M/

Advertisements

Directory Management in win32

Creating and deleting directories involves a pair of thankfully simple functions, CreateDirectory() and RemoveDirectory(). The CreateDirectory() function takes two arguments, the first is the pathname to the directory to create, and the second is a pointer to a SECURITY_ATTRIBUTES structure. For the second argument, we can simply put NULL.  The RemoveDirectory() function has only one parameter, the name of the directory to be removed. Both functions return a Boolean value stating the success or failure of the function call.

#include <Windows.h>
#include <stdlib.h>
#include <stdio.h>

int _tmain(int argc, char argv[]){

	if((CreateDirectory("exampleDir", NULL))==FALSE){
		printf("Error creating directory.\n");
		exit(EXIT_FAILURE);
	} else {
		printf("Directory created.\n");
	}

	if((RemoveDirectory("exampleDir"))==FALSE){
		printf("Error removing directory.\n");
		exit(EXIT_FAILURE);
	} else {
		printf("Directory deleted.\n");
	}

	return 0;

}

A process has a working directory. We can both get and set the working directory. The GetCurrentDirectory() function takes two arguments, the size of the buffer in characters, and the buffer to write the full pathname of the directory to. The SetCurrentDirectory() function has one parameter, the name of the directory we wish to set as the current working directory.

#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>

int _tmain(int argc, char argv[]){

	TCHAR szBuffer[MAX_PATH + 1];
	TCHAR szNewDir[] = _T("testdir");
	DWORD dwRValue = 0;
	CreateDirectory(szNewDir, NULL);

	dwRValue = GetCurrentDirectory(MAX_PATH, szBuffer);

	if(dwRValue != 0){
		_tprintf(_T("Current directory is %s\n"), szBuffer);
	} else {
		printf("Error getting current directory.\n");
		exit(EXIT_FAILURE);
	}

	if(!(SetCurrentDirectory(szNewDir))){
		printf("Could not change directory.\n");
		exit(EXIT_FAILURE);
	} else {
		printf("Directory changed.\n");
	}

	if(!(GetCurrentDirectory(MAX_PATH, szBuffer))){
		printf("Could not get working directory.\n");
		exit(EXIT_FAILURE);
	} else {
		_tprintf(_T("Current directory is %s\n"), szBuffer);
	}

	return 0;

}

The ReadConsole() and WriteConsole() functions are used to read and write from the console. Both the ReadConsole() and WriteConsole() functions take five arguments; the first argument is a HANDLE to standard input or standard output.  We get a standard handle using the GetStdHandle() function, which takes a single parameter that can be one of three DWORD values, STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, and STD_ERROR_HANDLE .

#include <Window.h>
#include <stdlib.h>
#include <stdio.h>

int _tmain(int argc, char argv[]){

	//create a handle to standard output
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	TCHAR *szMsg = "Nice boat!";
	DWORD dwCount;
	BOOLEAN bRValue;

	if(hOut==INVALID_HANDLE_VALUE){
		printf("Could not open a file handle to standard output.\n");
		exit(EXIT_FAILURE);
	}

	WriteConsole(hOut, szMsg, _tcslen(szMsg),  &dwCount, NULL);

	if(dwCount == _tcslen(szMsg)){
		printf("\nThe full message has been printed.\n");
	} else {
		printf("\nError! The full message has not printed.\n");
	}

	CloseHandle(hOut);

	return 0;

}

Note that a process can only have one console at a time.