/* Write the messages to the output handle. Frequently hOut
will be standard out or error, but this is not required.
Use WriteConsole (to handle Unicode) first, as the
output will normally be the console. If that fails, use WriteFile.
hOut: Handle for output file.
... : Variable argument list containing TCHAR strings.
The list must be terminated with NULL. */
{
DWORD MsgLen, Count;
LPCTSTR pMsg;
va_list pMsgList; /* Current message string. */
va_start (pMsgList, hOut); /* Start processing msgs. */
while ((pMsg = va_arg (pMsgList, LPCTSTR)) != NULL) {
MsgLen = lstrlen (pMsg);
if (!WriteConsole (hOut, pMsg, MsgLen, &Count, NULL)
&& !WriteFile (hOut, pMsg, MsgLen * sizeof (TCHAR),
&Count, NULL))
return FALSE;
}
va_end (pMsgList);
return TRUE;
}
BOOL PrintMsg (HANDLE hOut, LPCTSTR pMsg)
/* For convenience only - Single message version of PrintStrings so that
you do not have to remember the NULL arg list terminator.
hOut: Handle of output file
pMsg: Single message to output. */
{
return PrintStrings (hOut, pMsg, NULL);
}
/* Prompt the user at the console and get a response
which can be up to MaxTchar generic characters.
pPromptMessage: Message displayed to user.
pResponse: Programmer-supplied buffer that receives the response.
MaxTchar: Maximum size of the user buffer, measured as generic characters.
Echo: Do not display the user's response if this flag is FALSE. */
{
HANDLE hStdIn, hStdOut;
DWORD TcharIn, EchoFlag;
BOOL Success;
hStdIn = CreateFile (TEXT ("CONIN$"), GENERIC_READ | GENERIC_WRITE, 0,
NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
hStdOut = CreateFile (TEXT ("CONOUT$"), GENERIC_WRITE, 0,
NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
/* Should the input be echoed? */
EchoFlag = Echo ? ENABLE_ECHO_INPUT : 0;
/* API "and" chain. If any test or system call fails, the
rest of the expression is not evaluated, and the
subsequent functions are not called. GetStdError ()
will return the result of the failed call. */
/* General-purpose function for reporting system errors.
Obtain the error number and turn it into the system error message.
Display this information and the user-specified message to the standard error device.
UserMessage: Message to be displayed to standard error device.
ExitCode: 0 - Return.
\x11> 0 - ExitProcess with this code.
PrintErrorMessage: Display the last system error message if this flag is set. */
{
DWORD eMsgLen, ErrNum = GetLastError ();
LPTSTR lpvSysMsg;
HANDLE hStdErr;
hStdErr = GetStdHandle (STD_ERROR_HANDLE);
PrintMsg (hStdErr, UserMessage);
if (PrintErrorMsg) {
eMsgLen = FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM, NULL,
ErrNum, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpvSysMsg, 0, NULL);
PrintStrings (hStdErr, TEXT ("\n"), lpvSysMsg, TEXT ("\n"), NULL);
HeapFree (GetProcessHeap (), 0, lpvSysMsg);
/* Explained in Chapter 5. */
}
if (ExitCode > 0)
ExitProcess (ExitCode);
else
return;
}