#include	<windows.h>
#include	<iostream.h>
#include	<iomanip.h>
#include	<fstream.h>
#include	<string.h>

ofstream	CERR("results.out", ios::app);
int	BUFLEN = 0x10000;

ostream	& operator << (ostream & os, SYSTEMTIME & r)
{
	static	const char	* const rgszDayNames[] =
		{
		"Sunday",
		"Monday",
		"Tuesday",
		"Wednesday",
		"Thursday",
		"Friday",
		"Saturday",
		0
		};
	char	chFill = os.fill();
	os.fill('0');
	os //--------------------------------- << rgszDayNames[r.wDayOfWeek] << ' '
		<< setw(2) << r.wMonth << '/'
		<< setw(2) << r.wDay << '/'
		<< setw(2) << r.wYear << ' '
		<< setw(2) << r.wHour << ':'
		<< setw(2) << r.wMinute << ':'
		//------------------- << setw(2) << r.wSecond
		;
	os.fill(chFill);
	return	os;
}

void	cat2(HANDLE h, HANDLE hOut)
{
	HANDLE	hMap = CreateFileMapping(h, 0, PAGE_READONLY, 0,0, 0);
	if (0 == hMap)
		{
		CERR << GetLastError() << ": error in CreateFileMapping." << endl;
		return;
		}
	LPVOID	pView = MapViewOfFile(hMap, FILE_MAP_READ, 0,0, 0);
	if (0 == pView)
		{
		CERR << GetLastError() << ": error in MapViewOfFile()." << endl;
		CloseHandle(hMap);
		return;
		}
	DWORD	dwNothing, dwFileSizeLo = GetFileSize(h, &dwNothing);
	const	char	*pOut = (char *)pView;
	while (dwFileSizeLo)
		{
		if (!WriteFile(hOut, (const void *)pOut, dwFileSizeLo, &dwNothing, 0))
			{
			CERR << GetLastError() << ": error in WriteFile()." << endl;
			break;
			}
		dwFileSizeLo -= dwNothing;
		pOut += dwNothing;
		}
	UnmapViewOfFile(pView);
	CloseHandle(hMap);
}
void cat(HANDLE h, HANDLE hOut)
{
	char	szBuf[8192];
	DWORD	nBytes;
	while (ReadFile(h, szBuf, sizeof(szBuf), &nBytes, 0) && nBytes)
		{
		DWORD	nWritten;
		if (!WriteFile(hOut, szBuf, nBytes, &nWritten, 0) )
			{
			CERR << GetLastError() << ": error in WriteFile. "
				<< nBytes << " read, " << nWritten << " written."
				<< endl;
			// return;
			}
		}
}

int main(int argc, char **argv)
{
	SYSTEMTIME	sNow;
	GetLocalTime(&sNow);
	CERR << sNow << "===> " << GetCommandLine() << endl;
	HANDLE	hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
	if (INVALID_HANDLE_VALUE == hStdout)
		{
		CERR << GetLastError() << ": error opening con for writing."
			<< endl;
		return	4;
		}
	if (argc < 2)
		{
		cat(GetStdHandle(STD_INPUT_HANDLE), hStdout);
		return	0;
		}
	DWORD	dwStart = GetTickCount();
	for (int iArg = 1; iArg < argc; iArg++)
		{
		HANDLE	fp = CreateFile(argv[iArg], GENERIC_READ,
			FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
			OPEN_EXISTING, 0, 0);
		if (INVALID_HANDLE_VALUE == fp)
			{
			CERR << GetLastError() << ": error opening file "
				<< argv[iArg] << " for reading." << endl;
			continue;
			}

		cat2(fp, hStdout);
		CloseHandle(fp);
		}
	dwStart = GetTickCount( ) - dwStart;
 	CERR << "**** Total time: " << (dwStart / 1000)
		<< '.' << (dwStart % 1000) << " seconds."
		<< endl;
	return	0;
}

