https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ce044cf80e6a45e0c3d4e…
commit ce044cf80e6a45e0c3d4eb1b695a8c8ccd3e58f7
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Fri Feb 2 21:48:18 2018 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Fri Feb 2 22:19:54 2018 +0100
[CONUTILS] Fix and improve the documentation for "outstream" and "utils", addendum to f982d77.
---
sdk/lib/conutils/outstream.c | 78 ++++++++++++++-----------
sdk/lib/conutils/utils.c | 135 ++++++++++++++++++++++++++++++++++++++-----
2 files changed, 165 insertions(+), 48 deletions(-)
diff --git a/sdk/lib/conutils/outstream.c b/sdk/lib/conutils/outstream.c
index ce25d51c1d..580269cf1e 100644
--- a/sdk/lib/conutils/outstream.c
+++ b/sdk/lib/conutils/outstream.c
@@ -795,10 +795,10 @@ ConResPrintf(
*
* @param[in] dwFlags
* The formatting options, and how to interpret the @p lpSource parameter.
- * See FormatMessage() for more details. The @b@c FORMAT_MESSAGE_ALLOCATE_BUFFER
- * and @b@c FORMAT_MESSAGE_ARGUMENT_ARRAY flags are always ignored.
- * The function implicitly uses the @b@c FORMAT_MESSAGE_IGNORE_INSERTS and
- * @b@c FORMAT_MESSAGE_MAX_WIDTH_MASK flags to implement its behaviour.
+ * See FormatMessage() for more details. The @b FORMAT_MESSAGE_ALLOCATE_BUFFER
+ * and @b FORMAT_MESSAGE_ARGUMENT_ARRAY flags are always ignored.
+ * The function implicitly uses the @b FORMAT_MESSAGE_IGNORE_INSERTS and
+ * @b FORMAT_MESSAGE_MAX_WIDTH_MASK flags to implement its behaviour.
*
* @param[in] lpSource
* The location of the message definition. The type of this parameter
@@ -806,11 +806,11 @@ ConResPrintf(
*
* @param[in] dwMessageId
* The message identifier for the requested message. This parameter
- * is ignored if @p dwFlags includes @b@c FORMAT_MESSAGE_FROM_STRING.
+ * is ignored if @p dwFlags includes @b FORMAT_MESSAGE_FROM_STRING.
*
* @param[in] dwLanguageId
* The language identifier for the requested message. This parameter
- * is ignored if @p dwFlags includes @b@c FORMAT_MESSAGE_FROM_STRING.
+ * is ignored if @p dwFlags includes @b FORMAT_MESSAGE_FROM_STRING.
*
* @return
* Numbers of characters successfully written to @p Stream.
@@ -819,7 +819,7 @@ ConResPrintf(
* Similarly to ConPuts(), no terminating new-line character is appended.
*
* @see ConPuts(), ConResPuts() and associated functions,
- * <a href="FormatMessage() (on MSDN)">https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).…</a>
+ * <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).…">FormatMessage() (on MSDN)</a>
**/
INT
ConMsgPuts(
@@ -976,9 +976,9 @@ ConMsgPrintf2V(
*
* @param[in] dwFlags
* The formatting options, and how to interpret the @p lpSource parameter.
- * See FormatMessage() for more details. The @b@c FORMAT_MESSAGE_ALLOCATE_BUFFER
+ * See FormatMessage() for more details. The @b FORMAT_MESSAGE_ALLOCATE_BUFFER
* flags is always ignored. The function implicitly uses the
- * @b@c FORMAT_MESSAGE_MAX_WIDTH_MASK flag to implement its behaviour.
+ * @b FORMAT_MESSAGE_MAX_WIDTH_MASK flag to implement its behaviour.
*
* @param[in] lpSource
* The location of the message definition. The type of this parameter
@@ -986,11 +986,11 @@ ConMsgPrintf2V(
*
* @param[in] dwMessageId
* The message identifier for the requested message. This parameter
- * is ignored if @p dwFlags includes @b@c FORMAT_MESSAGE_FROM_STRING.
+ * is ignored if @p dwFlags includes @b FORMAT_MESSAGE_FROM_STRING.
*
* @param[in] dwLanguageId
* The language identifier for the requested message. This parameter
- * is ignored if @p dwFlags includes @b@c FORMAT_MESSAGE_FROM_STRING.
+ * is ignored if @p dwFlags includes @b FORMAT_MESSAGE_FROM_STRING.
*
* @param[in] Arguments
* Optional pointer to an array of values describing a variable number of
@@ -1001,7 +1001,7 @@ ConMsgPrintf2V(
* return from the function. To use the @c va_list again, destroy the variable
* argument list pointer using va_end() and reinitialize it with va_start().
* If you do not have a pointer of type @c va_list*, then specify the
- * @b@c FORMAT_MESSAGE_ARGUMENT_ARRAY flag and pass a pointer to an array
+ * @b FORMAT_MESSAGE_ARGUMENT_ARRAY flag and pass a pointer to an array
* of @c DWORD_PTR values; those values are input to the message formatted
* as the insert values. Each insert must have a corresponding element in
* the array.
@@ -1017,7 +1017,7 @@ ConMsgPrintf2V(
* Numbers of characters successfully written to @p Stream.
*
* @see ConPrintf(), ConResPrintf() and associated functions, ConMsgPrintf(),
- * <a href="FormatMessage() (on MSDN)">https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).…</a>
+ * <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).…">FormatMessage() (on MSDN)</a>
**/
INT
ConMsgPrintfV(
@@ -1089,9 +1089,9 @@ ConMsgPrintfV(
*
* @param[in] dwFlags
* The formatting options, and how to interpret the @p lpSource parameter.
- * See FormatMessage() for more details. The @b@c FORMAT_MESSAGE_ALLOCATE_BUFFER
- * and @b@c FORMAT_MESSAGE_ARGUMENT_ARRAY flags are always ignored.
- * The function implicitly uses the @b@c FORMAT_MESSAGE_MAX_WIDTH_MASK flag
+ * See FormatMessage() for more details. The @b FORMAT_MESSAGE_ALLOCATE_BUFFER
+ * and @b FORMAT_MESSAGE_ARGUMENT_ARRAY flags are always ignored.
+ * The function implicitly uses the @b FORMAT_MESSAGE_MAX_WIDTH_MASK flag
* to implement its behaviour.
*
* @param[in] lpSource
@@ -1100,11 +1100,11 @@ ConMsgPrintfV(
*
* @param[in] dwMessageId
* The message identifier for the requested message. This parameter
- * is ignored if @p dwFlags includes @b@c FORMAT_MESSAGE_FROM_STRING.
+ * is ignored if @p dwFlags includes @b FORMAT_MESSAGE_FROM_STRING.
*
* @param[in] dwLanguageId
* The language identifier for the requested message. This parameter
- * is ignored if @p dwFlags includes @b@c FORMAT_MESSAGE_FROM_STRING.
+ * is ignored if @p dwFlags includes @b FORMAT_MESSAGE_FROM_STRING.
*
* @param[in] ...
* Additional arguments that can be expected by the function, depending
@@ -1122,7 +1122,7 @@ ConMsgPrintfV(
* Numbers of characters successfully written to @p Stream.
*
* @see ConPrintf(), ConResPrintf() and associated functions, ConMsgPrintfV(),
- * <a href="FormatMessage() (on MSDN)">https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).…</a>
+ * <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).…">FormatMessage() (on MSDN)</a>
**/
INT
__cdecl
@@ -1170,8 +1170,8 @@ ConMsgPrintf(
*
* @param[in] dwFlags
* The formatting options, see FormatMessage() for more details.
- * The only valid flags are @b@c FORMAT_MESSAGE_ARGUMENT_ARRAY and
- * @b@c FORMAT_MESSAGE_IGNORE_INSERTS. All the other flags are internally
+ * The only valid flags are @b FORMAT_MESSAGE_ARGUMENT_ARRAY and
+ * @b FORMAT_MESSAGE_IGNORE_INSERTS. All the other flags are internally
* overridden by the function to implement its behaviour.
*
* @param[in] uID
@@ -1185,11 +1185,19 @@ ConMsgPrintf(
* than the current language, use the @c MAKELANGID macro to create this
* parameter.
*
- * @param[in] args
- * Parameter describing a variable number of arguments, initialized
- * with va_start(), that can be expected by the function, depending
- * on the message string. Each argument is used to replace an
- * <em>insert sequence</em> in the message string.
+ * @param[in] Arguments
+ * Optional pointer to an array of values describing a variable number of
+ * arguments, depending on the message string. Each argument is used to
+ * replace an <em>insert sequence</em> in the message string.
+ * By default, the @p Arguments parameter is of type @c va_list*, initialized
+ * with va_start(). The state of the @c va_list argument is undefined upon
+ * return from the function. To use the @c va_list again, destroy the variable
+ * argument list pointer using va_end() and reinitialize it with va_start().
+ * If you do not have a pointer of type @c va_list*, then specify the
+ * @b FORMAT_MESSAGE_ARGUMENT_ARRAY flag and pass a pointer to an array
+ * of @c DWORD_PTR values; those values are input to the message formatted
+ * as the insert values. Each insert must have a corresponding element in
+ * the array.
*
* @remark
* Contrary to printf(), ConPrintf(), ConResPrintf() and associated functions,
@@ -1202,7 +1210,7 @@ ConMsgPrintf(
* Numbers of characters successfully written to @p Stream.
*
* @see ConPrintf(), ConResPrintf() and associated functions, ConMsgPrintf(),
- * <a href="FormatMessage() (on MSDN)">https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).…</a>
+ * <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).…">FormatMessage() (on MSDN)</a>
**/
INT
ConResMsgPrintfExV(
@@ -1283,8 +1291,8 @@ ConResMsgPrintfExV(
*
* @param[in] dwFlags
* The formatting options, see FormatMessage() for more details.
- * The only valid flags are @b@c FORMAT_MESSAGE_ARGUMENT_ARRAY and
- * @b@c FORMAT_MESSAGE_IGNORE_INSERTS. All the other flags are internally
+ * The only valid flags are @b FORMAT_MESSAGE_ARGUMENT_ARRAY and
+ * @b FORMAT_MESSAGE_IGNORE_INSERTS. All the other flags are internally
* overridden by the function to implement its behaviour.
*
* @param[in] uID
@@ -1300,7 +1308,7 @@ ConResMsgPrintfExV(
* return from the function. To use the @c va_list again, destroy the variable
* argument list pointer using va_end() and reinitialize it with va_start().
* If you do not have a pointer of type @c va_list*, then specify the
- * @b@c FORMAT_MESSAGE_ARGUMENT_ARRAY flag and pass a pointer to an array
+ * @b FORMAT_MESSAGE_ARGUMENT_ARRAY flag and pass a pointer to an array
* of @c DWORD_PTR values; those values are input to the message formatted
* as the insert values. Each insert must have a corresponding element in
* the array.
@@ -1316,7 +1324,7 @@ ConResMsgPrintfExV(
* Numbers of characters successfully written to @p Stream.
*
* @see ConPrintf(), ConResPrintf() and associated functions, ConMsgPrintf(),
- * <a href="FormatMessage() (on MSDN)">https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).…</a>
+ * <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).…">FormatMessage() (on MSDN)</a>
**/
INT
ConResMsgPrintfV(
@@ -1349,7 +1357,7 @@ ConResMsgPrintfV(
*
* @param[in] dwFlags
* The formatting options, see FormatMessage() for more details.
- * The only valid flag is @b@c FORMAT_MESSAGE_IGNORE_INSERTS.
+ * The only valid flag is @b FORMAT_MESSAGE_IGNORE_INSERTS.
* All the other flags are internally overridden by the function
* to implement its behaviour.
*
@@ -1380,7 +1388,7 @@ ConResMsgPrintfV(
* Numbers of characters successfully written to @p Stream.
*
* @see ConPrintf(), ConResPrintf() and associated functions, ConMsgPrintf(),
- * <a href="FormatMessage() (on MSDN)">https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).…</a>
+ * <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).…">FormatMessage() (on MSDN)</a>
**/
INT
__cdecl
@@ -1423,7 +1431,7 @@ ConResMsgPrintfEx(
*
* @param[in] dwFlags
* The formatting options, see FormatMessage() for more details.
- * The only valid flag is @b@c FORMAT_MESSAGE_IGNORE_INSERTS.
+ * The only valid flag is @b FORMAT_MESSAGE_IGNORE_INSERTS.
* All the other flags are internally overridden by the function
* to implement its behaviour.
*
@@ -1447,7 +1455,7 @@ ConResMsgPrintfEx(
* Numbers of characters successfully written to @p Stream.
*
* @see ConPrintf(), ConResPrintf() and associated functions, ConMsgPrintf(),
- * <a href="FormatMessage() (on MSDN)">https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).…</a>
+ * <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).…">FormatMessage() (on MSDN)</a>
**/
INT
__cdecl
diff --git a/sdk/lib/conutils/utils.c b/sdk/lib/conutils/utils.c
index e6e6fb8d24..8462be06f3 100644
--- a/sdk/lib/conutils/utils.c
+++ b/sdk/lib/conutils/utils.c
@@ -52,10 +52,48 @@ MultiByteToMultiByte(
#endif
-/*
- * 'LoadStringW' API ripped from user32.dll to remove
- * any dependency of this library from user32.dll
- */
+/**
+ * @name K32LoadStringExW
+ * Loads a string resource from the executable file associated with a
+ * specified module, copies the string into a buffer, and appends a
+ * terminating null character.
+ * This is basically the LoadString() API ripped from user32.dll to
+ * remove any dependency of ConUtils from user32.dll, and to add support
+ * for loading strings from other languages than the current one.
+ *
+ * @param[in] hInstance
+ * Optional handle to an instance of the module whose executable file
+ * contains the string resource. Can be set to NULL to get the handle
+ * to the application itself.
+ *
+ * @param[in] uID
+ * The identifier of the string to be loaded.
+ *
+ * @param[in] LanguageId
+ * The language identifier of the resource. If this parameter is
+ * <tt>MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)</tt>, the current language
+ * associated with the calling thread is used. To specify a language other
+ * than the current language, use the @c MAKELANGID macro to create this
+ * parameter.
+ *
+ * @param[out] lpBuffer
+ * The buffer that receives the string. Must be of sufficient length
+ * to hold a pointer (8 bytes).
+ *
+ * @param[in] nBufferMax
+ * The size of the buffer, in characters. The string is truncated and
+ * NULL-terminated if it is longer than the number of characters specified.
+ * If this parameter is 0, then @p lpBuffer receives a read-only pointer
+ * to the resource itself.
+ *
+ * @return
+ * If the function succeeds, the return value is the number of characters
+ * copied into the buffer, not including the terminating null character,
+ * or zero if the string resource does not exist. To get extended error
+ * information, call GetLastError().
+ *
+ * @see LoadString(), K32LoadStringW()
+ **/
INT
WINAPI
K32LoadStringExW(
@@ -121,6 +159,15 @@ K32LoadStringExW(
return i;
}
+/**
+ * @name K32LoadStringW
+ * Loads a string resource from the executable file associated with a
+ * specified module, copies the string into a buffer, and appends a
+ * terminating null character.
+ * This is a restricted version of K32LoadStringExW().
+ *
+ * @see LoadString(), K32LoadStringExW()
+ **/
INT
WINAPI
K32LoadStringW(
@@ -135,11 +182,73 @@ K32LoadStringW(
lpBuffer, nBufferMax);
}
-/*
- * "Safe" version of FormatMessageW, that does not crash if a malformed
- * source string is retrieved and then being used for formatting.
- * It basically wraps calls to FormatMessageW within SEH.
- */
+/**
+ * @name FormatMessageSafeW
+ * Loads and formats a message string. The function requires a message
+ * definition as input. The message definition can come from a buffer
+ * passed to the function. It can come from a message table resource in
+ * an already-loaded module, or the caller can ask the function to search
+ * the system's message table resource(s) for the message definition.
+ * Please refer to the Win32 FormatMessage() function for more details.
+ *
+ * @param[in] dwFlags
+ * The formatting options, and how to interpret the @p lpSource parameter.
+ * See FormatMessage() for more details.
+ *
+ * @param[in] lpSource
+ * The location of the message definition. The type of this parameter
+ * depends upon the settings in the @p dwFlags parameter.
+ *
+ * @param[in] dwMessageId
+ * The message identifier for the requested message. This parameter
+ * is ignored if @p dwFlags includes @b FORMAT_MESSAGE_FROM_STRING.
+ *
+ * @param[in] dwLanguageId
+ * The language identifier for the requested message. This parameter
+ * is ignored if @p dwFlags includes @b FORMAT_MESSAGE_FROM_STRING.
+ *
+ * @param[out] lpBuffer
+ * A pointer to a buffer that receives the null-terminated string that
+ * specifies the formatted message. If @p dwFlags includes
+ * @b FORMAT_MESSAGE_ALLOCATE_BUFFER, the function allocates a buffer
+ * using the LocalAlloc() function, and places the pointer to the buffer
+ * at the address specified in @p lpBuffer.
+ * This buffer cannot be larger than 64kB.
+ *
+ * @param[in] nSize
+ * If the @b FORMAT_MESSAGE_ALLOCATE_BUFFER flag is not set, this parameter
+ * specifies the size of the output buffer, in @b TCHARs.
+ * If @b FORMAT_MESSAGE_ALLOCATE_BUFFER is set, this parameter specifies
+ * the minimum number of @b TCHARs to allocate for an output buffer.
+ * The output buffer cannot be larger than 64kB.
+ *
+ * @param[in] Arguments
+ * Optional pointer to an array of values describing a variable number of
+ * arguments, depending on the message string. Each argument is used to
+ * replace an <em>insert sequence</em> in the message string.
+ * By default, the @p Arguments parameter is of type @c va_list*, initialized
+ * with va_start(). The state of the @c va_list argument is undefined upon
+ * return from the function. To use the @c va_list again, destroy the variable
+ * argument list pointer using va_end() and reinitialize it with va_start().
+ * If you do not have a pointer of type @c va_list*, then specify the
+ * @b FORMAT_MESSAGE_ARGUMENT_ARRAY flag and pass a pointer to an array
+ * of @c DWORD_PTR values; those values are input to the message formatted
+ * as the insert values. Each insert must have a corresponding element in
+ * the array.
+ *
+ * @return
+ * If the function succeeds, the return value is the number of characters
+ * copied into the buffer, not including the terminating null character,
+ * or zero if the string resource does not exist. To get extended error
+ * information, call GetLastError().
+ *
+ * @remark
+ * This function is a "safe" version of FormatMessage(), that does not
+ * crash if a malformed source string is retrieved and then being used
+ * for formatting. It basically wraps calls to FormatMessage() within SEH.
+ *
+ * @see <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).…">FormatMessage() (on MSDN)</a>
+ **/
DWORD
WINAPI
FormatMessageSafeW(
@@ -220,8 +329,8 @@ FormatMessageSafeW(
* Handle to the TTY object to check for.
*
* @return
- * @b@c TRUE when the handle refers to a valid TTY object,
- * @b@c FALSE if it does not.
+ * @b TRUE when the handle refers to a valid TTY object,
+ * @b FALSE if it does not.
*
* @remark
* This test is more general than IsConsoleHandle() as it is not limited
@@ -250,8 +359,8 @@ IsTTYHandle(IN HANDLE hHandle)
* console input buffer, console output buffer.
*
* @return
- * @b@c TRUE when the handle refers to a valid Win32 console object,
- * @b@c FALSE if it does not.
+ * @b TRUE when the handle refers to a valid Win32 console object,
+ * @b FALSE if it does not.
*
* @see IsTTYHandle()
**/
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f982d77b8a6bf04767e77…
commit f982d77b8a6bf04767e776098faec095e8e28029
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Fri Feb 2 00:35:08 2018 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Fri Feb 2 00:41:54 2018 +0100
[CONUTILS] Diverse improvements: start doxygenating and add some resource messsage helper functions.
- Start to doxygenate the library, focusing in great details on the
functions of the "outstream" module.
- Add a K32LoadStringEx function that expands (K32)LoadString by
allowing a LanguageId parameter to be able to load strings from other
languages than the current one.
- Add "ConResMsg*" helper functions to be able to (format and) print
message strings with inserts that come *NOT* from a message table (as
usual) *BUT* from resource string tables.
Will be helpful for CORE-14265 in particular.
[CMD] Fix the call to ConMsgPrintfV().
---
base/shell/cmd/console.c | 2 +-
sdk/lib/conutils/conutils.h | 15 +
sdk/lib/conutils/instream.c | 11 +-
sdk/lib/conutils/instream.h | 11 +-
sdk/lib/conutils/outstream.c | 808 +++++++++++++++++++++++++++++++++++++++++--
sdk/lib/conutils/outstream.h | 66 +++-
sdk/lib/conutils/pager.c | 7 +
sdk/lib/conutils/pager.h | 7 +
sdk/lib/conutils/screen.c | 7 +
sdk/lib/conutils/screen.h | 7 +
sdk/lib/conutils/stream.c | 11 +-
sdk/lib/conutils/stream.h | 11 +-
sdk/lib/conutils/utils.c | 77 ++++-
sdk/lib/conutils/utils.h | 20 +-
14 files changed, 981 insertions(+), 79 deletions(-)
diff --git a/base/shell/cmd/console.c b/base/shell/cmd/console.c
index 45e6257c9c..9d14d27301 100644
--- a/base/shell/cmd/console.c
+++ b/base/shell/cmd/console.c
@@ -141,7 +141,7 @@ VOID __cdecl ConFormatMessage(PCON_STREAM Stream, DWORD MessageId, ...)
NULL,
MessageId,
LANG_USER_DEFAULT,
- arg_ptr);
+ &arg_ptr);
va_end(arg_ptr);
if (Len <= 0)
diff --git a/sdk/lib/conutils/conutils.h b/sdk/lib/conutils/conutils.h
index 93d79e8848..3ad7849436 100644
--- a/sdk/lib/conutils/conutils.h
+++ b/sdk/lib/conutils/conutils.h
@@ -8,6 +8,21 @@
* Copyright 2017-2018 Hermes Belusca-Maito
*/
+/**
+ * @file conutils.h
+ * @ingroup ConUtils
+ *
+ * @defgroup ConUtils ReactOS Console Utilities Library
+ *
+ * @brief This library contains common functions used in many places inside
+ * the ReactOS console utilities and the ReactOS Command-Line Interpreter.
+ * Most of these functions are related with internationalisation and
+ * the problem of correctly displaying Unicode text on the console.
+ * Besides those, helpful functions for retrieving strings and messages
+ * from application resources are provided, together with printf-like
+ * functionality.
+ **/
+
#ifndef __CONUTILS_H__
#define __CONUTILS_H__
diff --git a/sdk/lib/conutils/instream.c b/sdk/lib/conutils/instream.c
index a9fa105766..73e40382ab 100644
--- a/sdk/lib/conutils/instream.c
+++ b/sdk/lib/conutils/instream.c
@@ -8,6 +8,13 @@
* Copyright 2017-2018 Hermes Belusca-Maito
*/
+/**
+ * @file instream.c
+ * @ingroup ConUtils
+ *
+ * @brief Console I/O utility API -- Input
+ **/
+
/*
* Enable this define if you want to only use CRT functions to output
* UNICODE stream to the console, as in the way explained by
@@ -42,8 +49,4 @@
#include "stream_private.h"
-/*
- * Console I/O utility API -- Input
- */
-
/* EOF */
diff --git a/sdk/lib/conutils/instream.h b/sdk/lib/conutils/instream.h
index d16a9c30de..087e163228 100644
--- a/sdk/lib/conutils/instream.h
+++ b/sdk/lib/conutils/instream.h
@@ -8,6 +8,13 @@
* Copyright 2017-2018 Hermes Belusca-Maito
*/
+/**
+ * @file instream.h
+ * @ingroup ConUtils
+ *
+ * @brief Console I/O utility API -- Input
+ **/
+
#ifndef __INSTREAM_H__
#define __INSTREAM_H__
@@ -32,10 +39,6 @@ extern "C" {
// Shadow type, implementation-specific
typedef struct _CON_STREAM CON_STREAM, *PCON_STREAM;
-/*
- * Console I/O utility API -- Input
- */
-
#ifdef __cplusplus
}
diff --git a/sdk/lib/conutils/outstream.c b/sdk/lib/conutils/outstream.c
index 63adaf3184..ce25d51c1d 100644
--- a/sdk/lib/conutils/outstream.c
+++ b/sdk/lib/conutils/outstream.c
@@ -8,6 +8,13 @@
* Copyright 2017-2018 Hermes Belusca-Maito
*/
+/**
+ * @file outstream.c
+ * @ingroup ConUtils
+ *
+ * @brief Console I/O utility API -- Output
+ **/
+
/*
* Enable this define if you want to only use CRT functions to output
* UNICODE stream to the console, as in the way explained by
@@ -51,17 +58,36 @@
// #define MAX_MESSAGE_SIZE 512 // See shutdown...
-/*
- * Console I/O utility API -- Output
- */
-
-// NOTE: Should be called with the stream locked.
+/**
+ * @name ConWrite
+ * Writes a counted string to a stream.
+ *
+ * @param[in] Stream
+ * Stream to which the write operation is issued.
+ *
+ * @param[in] szStr
+ * Pointer to the counted string to write.
+ *
+ * @param[in] len
+ * Length of the string pointed by @p szStr, specified
+ * in number of characters.
+ *
+ * @return
+ * Numbers of characters successfully written to @p Stream.
+ *
+ * @note
+ * This function is used as an internal function.
+ * Use the ConStreamWrite() function instead.
+ *
+ * @remark
+ * Should be called with the stream locked.
+ **/
INT
__stdcall
ConWrite(
IN PCON_STREAM Stream,
IN PTCHAR szStr,
- IN DWORD len)
+ IN DWORD len)
{
#ifndef USE_CRT
DWORD TotalLen = len, dwNumBytes = 0;
@@ -339,17 +365,52 @@ do { \
#endif
+/**
+ * @name ConStreamWrite
+ * Writes a counted string to a stream.
+ *
+ * @param[in] Stream
+ * Stream to which the write operation is issued.
+ *
+ * @param[in] szStr
+ * Pointer to the counted string to write.
+ *
+ * @param[in] len
+ * Length of the string pointed by @p szStr, specified
+ * in number of characters.
+ *
+ * @return
+ * Numbers of characters successfully written to @p Stream.
+ **/
INT
ConStreamWrite(
IN PCON_STREAM Stream,
IN PTCHAR szStr,
- IN DWORD len)
+ IN DWORD len)
{
INT Len;
CON_STREAM_WRITE2(Stream, szStr, len, Len);
return Len;
}
+/**
+ * @name ConPuts
+ * Writes a NULL-terminated string to a stream.
+ *
+ * @param[in] Stream
+ * Stream to which the write operation is issued.
+ *
+ * @param[in] szStr
+ * Pointer to the NULL-terminated string to write.
+ *
+ * @return
+ * Numbers of characters successfully written to @p Stream.
+ *
+ * @remark
+ * Contrary to the CRT puts() function, ConPuts() does not append
+ * a terminating new-line character. In this way it behaves more like
+ * the CRT fputs() function.
+ **/
INT
ConPuts(
IN PCON_STREAM Stream,
@@ -367,11 +428,33 @@ ConPuts(
return Len;
}
+/**
+ * @name ConPrintfV
+ * Formats and writes a NULL-terminated string to a stream.
+ *
+ * @param[in] Stream
+ * Stream to which the write operation is issued.
+ *
+ * @param[in] szStr
+ * Pointer to the NULL-terminated format string, that follows the same
+ * specifications as the @a szStr format string in ConPrintf().
+ *
+ * @param[in] args
+ * Parameter describing a variable number of arguments,
+ * initialized with va_start(), that can be expected by the function,
+ * depending on the @p szStr format string. Each argument is used to
+ * replace a <em>format specifier</em> in the format string.
+ *
+ * @return
+ * Numbers of characters successfully written to @p Stream.
+ *
+ * @see ConPrintf(), printf(), vprintf()
+ **/
INT
ConPrintfV(
IN PCON_STREAM Stream,
IN LPWSTR szStr,
- IN va_list args) // arg_ptr
+ IN va_list args)
{
INT Len;
WCHAR bufSrc[CON_RC_STRING_MAX_SIZE];
@@ -396,6 +479,30 @@ ConPrintfV(
return Len;
}
+/**
+ * @name ConPrintf
+ * Formats and writes a NULL-terminated string to a stream.
+ *
+ * @param[in] Stream
+ * Stream to which the write operation is issued.
+ *
+ * @param[in] szStr
+ * Pointer to the NULL-terminated format string, that follows the same
+ * specifications as the @a format string in printf(). This string can
+ * optionally contain embedded <em>format specifiers</em> that are
+ * replaced by the values specified in subsequent additional arguments
+ * and formatted as requested.
+ *
+ * @param[in] ...
+ * Additional arguments that can be expected by the function, depending
+ * on the @p szStr format string. Each argument is used to replace a
+ * <em>format specifier</em> in the format string.
+ *
+ * @return
+ * Numbers of characters successfully written to @p Stream.
+ *
+ * @see ConPrintfV(), printf(), vprintf()
+ **/
INT
__cdecl
ConPrintf(
@@ -416,16 +523,47 @@ ConPrintf(
return Len;
}
+/**
+ * @name ConResPutsEx
+ * Writes a string resource to a stream.
+ *
+ * @param[in] Stream
+ * Stream to which the write operation is issued.
+ *
+ * @param[in] hInstance
+ * Optional handle to an instance of the module whose executable file
+ * contains the string resource. Can be set to NULL to get the handle
+ * to the application itself.
+ *
+ * @param[in] uID
+ * The identifier of the string to be written.
+ *
+ * @param[in] LanguageId
+ * The language identifier of the resource. If this parameter is
+ * <tt>MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)</tt>, the current language
+ * associated with the calling thread is used. To specify a language other
+ * than the current language, use the @c MAKELANGID macro to create this
+ * parameter.
+ *
+ * @return
+ * Numbers of characters successfully written to @p Stream.
+ *
+ * @remark
+ * Similarly to ConPuts(), no terminating new-line character is appended.
+ *
+ * @see ConPuts(), ConResPuts()
+ **/
INT
ConResPutsEx(
IN PCON_STREAM Stream,
IN HINSTANCE hInstance OPTIONAL,
- IN UINT uID)
+ IN UINT uID,
+ IN LANGID LanguageId)
{
INT Len;
PWCHAR szStr = NULL;
- Len = K32LoadStringW(hInstance, uID, (PWSTR)&szStr, 0);
+ Len = K32LoadStringExW(hInstance, uID, LanguageId, (PWSTR)&szStr, 0);
if (szStr && Len)
// Len = ConPuts(Stream, szStr);
CON_STREAM_WRITE2(Stream, szStr, Len, Len);
@@ -437,59 +575,195 @@ ConResPutsEx(
return Len;
}
+/**
+ * @name ConResPuts
+ * Writes a string resource contained in the current application
+ * to a stream.
+ *
+ * @param[in] Stream
+ * Stream to which the write operation is issued.
+ *
+ * @param[in] uID
+ * The identifier of the string to be written.
+ *
+ * @return
+ * Numbers of characters successfully written to @p Stream.
+ *
+ * @remark
+ * Similarly to ConPuts(), no terminating new-line character is appended.
+ *
+ * @see ConPuts(), ConResPutsEx()
+ **/
INT
ConResPuts(
IN PCON_STREAM Stream,
IN UINT uID)
{
- return ConResPutsEx(Stream, NULL /*GetModuleHandleW(NULL)*/, uID);
+ return ConResPutsEx(Stream, NULL /*GetModuleHandleW(NULL)*/,
+ uID, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
}
+/**
+ * @name ConResPrintfExV
+ * Formats and writes a string resource to a stream.
+ *
+ * @param[in] Stream
+ * Stream to which the write operation is issued.
+ *
+ * @param[in] hInstance
+ * Optional handle to an instance of the module whose executable file
+ * contains the string resource. Can be set to NULL to get the handle
+ * to the application itself.
+ *
+ * @param[in] uID
+ * The identifier of the format string. The format string follows the
+ * same specifications as the @a szStr format string in ConPrintf().
+ *
+ * @param[in] LanguageId
+ * The language identifier of the resource. If this parameter is
+ * <tt>MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)</tt>, the current language
+ * associated with the calling thread is used. To specify a language other
+ * than the current language, use the @c MAKELANGID macro to create this
+ * parameter.
+ *
+ * @param[in] args
+ * Parameter describing a variable number of arguments,
+ * initialized with va_start(), that can be expected by the function,
+ * depending on the @p szStr format string. Each argument is used to
+ * replace a <em>format specifier</em> in the format string.
+ *
+ * @return
+ * Numbers of characters successfully written to @p Stream.
+ *
+ * @see ConPrintf(), ConResPrintfEx(), ConResPrintfV(), ConResPrintf()
+ **/
INT
ConResPrintfExV(
IN PCON_STREAM Stream,
IN HINSTANCE hInstance OPTIONAL,
IN UINT uID,
- IN va_list args) // arg_ptr
+ IN LANGID LanguageId,
+ IN va_list args)
{
INT Len;
WCHAR bufSrc[CON_RC_STRING_MAX_SIZE];
// NOTE: We may use the special behaviour where nBufMaxSize == 0
- Len = K32LoadStringW(hInstance, uID, bufSrc, ARRAYSIZE(bufSrc));
+ Len = K32LoadStringExW(hInstance, uID, LanguageId, bufSrc, ARRAYSIZE(bufSrc));
if (Len)
Len = ConPrintfV(Stream, bufSrc, args);
return Len;
}
+/**
+ * @name ConResPrintfV
+ * Formats and writes a string resource contained in the
+ * current application to a stream.
+ *
+ * @param[in] Stream
+ * Stream to which the write operation is issued.
+ *
+ * @param[in] uID
+ * The identifier of the format string. The format string follows the
+ * same specifications as the @a szStr format string in ConPrintf().
+ *
+ * @param[in] args
+ * Parameter describing a variable number of arguments,
+ * initialized with va_start(), that can be expected by the function,
+ * depending on the @p szStr format string. Each argument is used to
+ * replace a <em>format specifier</em> in the format string.
+ *
+ * @return
+ * Numbers of characters successfully written to @p Stream.
+ *
+ * @see ConPrintf(), ConResPrintfExV(), ConResPrintfEx(), ConResPrintf()
+ **/
INT
ConResPrintfV(
IN PCON_STREAM Stream,
IN UINT uID,
- IN va_list args) // arg_ptr
+ IN va_list args)
{
- return ConResPrintfExV(Stream, NULL /*GetModuleHandleW(NULL)*/, uID, args);
+ return ConResPrintfExV(Stream, NULL /*GetModuleHandleW(NULL)*/,
+ uID, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
+ args);
}
+/**
+ * @name ConResPrintfEx
+ * Formats and writes a string resource to a stream.
+ *
+ * @param[in] Stream
+ * Stream to which the write operation is issued.
+ *
+ * @param[in] hInstance
+ * Optional handle to an instance of the module whose executable file
+ * contains the string resource. Can be set to NULL to get the handle
+ * to the application itself.
+ *
+ * @param[in] uID
+ * The identifier of the format string. The format string follows the
+ * same specifications as the @a szStr format string in ConPrintf().
+ *
+ * @param[in] LanguageId
+ * The language identifier of the resource. If this parameter is
+ * <tt>MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)</tt>, the current language
+ * associated with the calling thread is used. To specify a language other
+ * than the current language, use the @c MAKELANGID macro to create this
+ * parameter.
+ *
+ * @param[in] ...
+ * Additional arguments that can be expected by the function, depending
+ * on the @p szStr format string. Each argument is used to replace a
+ * <em>format specifier</em> in the format string.
+ *
+ * @return
+ * Numbers of characters successfully written to @p Stream.
+ *
+ * @see ConPrintf(), ConResPrintfExV(), ConResPrintfV(), ConResPrintf()
+ **/
INT
__cdecl
ConResPrintfEx(
IN PCON_STREAM Stream,
IN HINSTANCE hInstance OPTIONAL,
- IN UINT uID,
+ IN UINT uID,
+ IN LANGID LanguageId,
...)
{
INT Len;
va_list args;
- va_start(args, uID);
- Len = ConResPrintfExV(Stream, hInstance, uID, args);
+ va_start(args, LanguageId);
+ Len = ConResPrintfExV(Stream, hInstance, uID, LanguageId, args);
va_end(args);
return Len;
}
+/**
+ * @name ConResPrintf
+ * Formats and writes a string resource contained in the
+ * current application to a stream.
+ *
+ * @param[in] Stream
+ * Stream to which the write operation is issued.
+ *
+ * @param[in] uID
+ * The identifier of the format string. The format string follows the
+ * same specifications as the @a szStr format string in ConPrintf().
+ *
+ * @param[in] ...
+ * Additional arguments that can be expected by the function, depending
+ * on the @p szStr format string. Each argument is used to replace a
+ * <em>format specifier</em> in the format string.
+ *
+ * @return
+ * Numbers of characters successfully written to @p Stream.
+ *
+ * @see ConPrintf(), ConResPrintfExV(), ConResPrintfEx(), ConResPrintfV()
+ **/
INT
__cdecl
ConResPrintf(
@@ -507,6 +781,46 @@ ConResPrintf(
return Len;
}
+/**
+ * @name ConMsgPuts
+ * Writes a message string to a stream without formatting. The function
+ * requires a message definition as input. The message definition can come
+ * from a buffer passed to the function. It can come from a message table
+ * resource in an already-loaded module, or the caller can ask the function
+ * to search the system's message table resource(s) for the message definition.
+ * Please refer to the Win32 FormatMessage() function for more details.
+ *
+ * @param[in] Stream
+ * Stream to which the write operation is issued.
+ *
+ * @param[in] dwFlags
+ * The formatting options, and how to interpret the @p lpSource parameter.
+ * See FormatMessage() for more details. The @b@c FORMAT_MESSAGE_ALLOCATE_BUFFER
+ * and @b@c FORMAT_MESSAGE_ARGUMENT_ARRAY flags are always ignored.
+ * The function implicitly uses the @b@c FORMAT_MESSAGE_IGNORE_INSERTS and
+ * @b@c FORMAT_MESSAGE_MAX_WIDTH_MASK flags to implement its behaviour.
+ *
+ * @param[in] lpSource
+ * The location of the message definition. The type of this parameter
+ * depends upon the settings in the @p dwFlags parameter.
+ *
+ * @param[in] dwMessageId
+ * The message identifier for the requested message. This parameter
+ * is ignored if @p dwFlags includes @b@c FORMAT_MESSAGE_FROM_STRING.
+ *
+ * @param[in] dwLanguageId
+ * The language identifier for the requested message. This parameter
+ * is ignored if @p dwFlags includes @b@c FORMAT_MESSAGE_FROM_STRING.
+ *
+ * @return
+ * Numbers of characters successfully written to @p Stream.
+ *
+ * @remark
+ * Similarly to ConPuts(), no terminating new-line character is appended.
+ *
+ * @see ConPuts(), ConResPuts() and associated functions,
+ * <a href="FormatMessage() (on MSDN)">https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).…</a>
+ **/
INT
ConMsgPuts(
IN PCON_STREAM Stream,
@@ -521,7 +835,7 @@ ConMsgPuts(
/*
* Sanitize dwFlags. This version always ignore explicitely the inserts
- * as we emulate the behaviour of the *puts function.
+ * as we emulate the behaviour of the (f)puts function.
*/
dwFlags |= FORMAT_MESSAGE_ALLOCATE_BUFFER; // Always allocate an internal buffer.
dwFlags |= FORMAT_MESSAGE_IGNORE_INSERTS; // Ignore inserts for FormatMessage.
@@ -540,7 +854,8 @@ ConMsgPuts(
dwMessageId,
dwLanguageId,
(LPWSTR)&lpMsgBuf,
- 0, NULL);
+ 0,
+ NULL);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@@ -572,6 +887,14 @@ ConMsgPuts(
return Len;
}
+/**
+ * @name ConMsgPrintf2V
+ * Formats and writes a message string to a stream.
+ *
+ * @remark For internal use only.
+ *
+ * @see ConMsgPrintfV()
+ **/
INT
ConMsgPrintf2V(
IN PCON_STREAM Stream,
@@ -579,7 +902,7 @@ ConMsgPrintf2V(
IN LPCVOID lpSource OPTIONAL,
IN DWORD dwMessageId,
IN DWORD dwLanguageId,
- IN va_list args) // arg_ptr
+ IN va_list args)
{
INT Len;
DWORD dwLength = 0;
@@ -606,7 +929,8 @@ ConMsgPrintf2V(
dwMessageId,
dwLanguageId,
(LPWSTR)&lpMsgBuf,
- 0, NULL);
+ 0,
+ NULL);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@@ -638,6 +962,63 @@ ConMsgPrintf2V(
return Len;
}
+/**
+ * @name ConMsgPrintfV
+ * Formats and writes a message string to a stream. The function requires
+ * a message definition as input. The message definition can come from a
+ * buffer passed to the function. It can come from a message table resource
+ * in an already-loaded module, or the caller can ask the function to search
+ * the system's message table resource(s) for the message definition.
+ * Please refer to the Win32 FormatMessage() function for more details.
+ *
+ * @param[in] Stream
+ * Stream to which the write operation is issued.
+ *
+ * @param[in] dwFlags
+ * The formatting options, and how to interpret the @p lpSource parameter.
+ * See FormatMessage() for more details. The @b@c FORMAT_MESSAGE_ALLOCATE_BUFFER
+ * flags is always ignored. The function implicitly uses the
+ * @b@c FORMAT_MESSAGE_MAX_WIDTH_MASK flag to implement its behaviour.
+ *
+ * @param[in] lpSource
+ * The location of the message definition. The type of this parameter
+ * depends upon the settings in the @p dwFlags parameter.
+ *
+ * @param[in] dwMessageId
+ * The message identifier for the requested message. This parameter
+ * is ignored if @p dwFlags includes @b@c FORMAT_MESSAGE_FROM_STRING.
+ *
+ * @param[in] dwLanguageId
+ * The language identifier for the requested message. This parameter
+ * is ignored if @p dwFlags includes @b@c FORMAT_MESSAGE_FROM_STRING.
+ *
+ * @param[in] Arguments
+ * Optional pointer to an array of values describing a variable number of
+ * arguments, depending on the message string. Each argument is used to
+ * replace an <em>insert sequence</em> in the message string.
+ * By default, the @p Arguments parameter is of type @c va_list*, initialized
+ * with va_start(). The state of the @c va_list argument is undefined upon
+ * return from the function. To use the @c va_list again, destroy the variable
+ * argument list pointer using va_end() and reinitialize it with va_start().
+ * If you do not have a pointer of type @c va_list*, then specify the
+ * @b@c FORMAT_MESSAGE_ARGUMENT_ARRAY flag and pass a pointer to an array
+ * of @c DWORD_PTR values; those values are input to the message formatted
+ * as the insert values. Each insert must have a corresponding element in
+ * the array.
+ *
+ * @remark
+ * Contrary to printf(), ConPrintf(), ConResPrintf() and associated functions,
+ * the ConMsg* functions work on format strings that contain <em>insert sequences</em>.
+ * These sequences extend the standard <em>format specifiers</em> as they
+ * allow to specify an <em>insert number</em> referring which precise value
+ * given in arguments to use.
+ *
+ * @return
+ * Numbers of characters successfully written to @p Stream.
+ *
+ * @see ConPrintf(), ConResPrintf() and associated functions, ConMsgPrintf(),
+ * <a href="FormatMessage() (on MSDN)">https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).…</a>
+ **/
INT
ConMsgPrintfV(
IN PCON_STREAM Stream,
@@ -645,7 +1026,7 @@ ConMsgPrintfV(
IN LPCVOID lpSource OPTIONAL,
IN DWORD dwMessageId,
IN DWORD dwLanguageId,
- IN va_list args) // arg_ptr
+ IN va_list *Arguments OPTIONAL)
{
INT Len;
DWORD dwLength = 0;
@@ -653,13 +1034,9 @@ ConMsgPrintfV(
/* Sanitize dwFlags */
dwFlags |= FORMAT_MESSAGE_ALLOCATE_BUFFER; // Always allocate an internal buffer.
-// dwFlags &= ~FORMAT_MESSAGE_IGNORE_INSERTS; // We always use arguments.
- dwFlags &= ~FORMAT_MESSAGE_ARGUMENT_ARRAY; // We always use arguments of type 'va_list'.
-
//
// NOTE: Technique taken from eventvwr.c!GetMessageStringFromDll()
//
-
dwFlags |= FORMAT_MESSAGE_MAX_WIDTH_MASK;
/*
@@ -672,7 +1049,8 @@ ConMsgPrintfV(
dwMessageId,
dwLanguageId,
(LPWSTR)&lpMsgBuf,
- 0, &args);
+ 0,
+ Arguments);
Len = (INT)dwLength;
@@ -684,7 +1062,6 @@ ConMsgPrintfV(
{
// ASSERT(dwLength != 0);
- // Len = ConPrintfV(Stream, lpMsgBuf, args);
CON_STREAM_WRITE2(Stream, lpMsgBuf, dwLength, Len);
/* Fixup returned length in case of errors */
@@ -698,6 +1075,55 @@ ConMsgPrintfV(
return Len;
}
+/**
+ * @name ConMsgPrintf
+ * Formats and writes a message string to a stream. The function requires
+ * a message definition as input. The message definition can come from a
+ * buffer passed to the function. It can come from a message table resource
+ * in an already-loaded module, or the caller can ask the function to search
+ * the system's message table resource(s) for the message definition.
+ * Please refer to the Win32 FormatMessage() function for more details.
+ *
+ * @param[in] Stream
+ * Stream to which the write operation is issued.
+ *
+ * @param[in] dwFlags
+ * The formatting options, and how to interpret the @p lpSource parameter.
+ * See FormatMessage() for more details. The @b@c FORMAT_MESSAGE_ALLOCATE_BUFFER
+ * and @b@c FORMAT_MESSAGE_ARGUMENT_ARRAY flags are always ignored.
+ * The function implicitly uses the @b@c FORMAT_MESSAGE_MAX_WIDTH_MASK flag
+ * to implement its behaviour.
+ *
+ * @param[in] lpSource
+ * The location of the message definition. The type of this parameter
+ * depends upon the settings in the @p dwFlags parameter.
+ *
+ * @param[in] dwMessageId
+ * The message identifier for the requested message. This parameter
+ * is ignored if @p dwFlags includes @b@c FORMAT_MESSAGE_FROM_STRING.
+ *
+ * @param[in] dwLanguageId
+ * The language identifier for the requested message. This parameter
+ * is ignored if @p dwFlags includes @b@c FORMAT_MESSAGE_FROM_STRING.
+ *
+ * @param[in] ...
+ * Additional arguments that can be expected by the function, depending
+ * on the message string. Each argument is used to replace an
+ * <em>insert sequence</em> in the message string.
+ *
+ * @remark
+ * Contrary to printf(), ConPrintf(), ConResPrintf() and associated functions,
+ * the ConMsg* functions work on format strings that contain <em>insert sequences</em>.
+ * These sequences extend the standard <em>format specifiers</em> as they
+ * allow to specify an <em>insert number</em> referring which precise value
+ * given in arguments to use.
+ *
+ * @return
+ * Numbers of characters successfully written to @p Stream.
+ *
+ * @see ConPrintf(), ConResPrintf() and associated functions, ConMsgPrintfV(),
+ * <a href="FormatMessage() (on MSDN)">https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).…</a>
+ **/
INT
__cdecl
ConMsgPrintf(
@@ -711,14 +1137,334 @@ ConMsgPrintf(
INT Len;
va_list args;
+ /* Sanitize dwFlags */
+ dwFlags &= ~FORMAT_MESSAGE_ARGUMENT_ARRAY;
+
va_start(args, dwLanguageId);
- // ConMsgPrintf2V
Len = ConMsgPrintfV(Stream,
dwFlags,
lpSource,
dwMessageId,
dwLanguageId,
- args);
+ &args);
+ va_end(args);
+
+ return Len;
+}
+
+/**
+ * @name ConResMsgPrintfExV
+ * Formats and writes a message string to a stream. The function requires
+ * a message definition as input. Contrary to the ConMsg* or the Win32
+ * FormatMessage() functions, the message definition comes from a resource
+ * string table, much like the strings for ConResPrintf(), but is formatted
+ * according to the rules of ConMsgPrintf().
+ *
+ * @param[in] Stream
+ * Stream to which the write operation is issued.
+ *
+ * @param[in] hInstance
+ * Optional handle to an instance of the module whose executable file
+ * contains the string resource. Can be set to NULL to get the handle
+ * to the application itself.
+ *
+ * @param[in] dwFlags
+ * The formatting options, see FormatMessage() for more details.
+ * The only valid flags are @b@c FORMAT_MESSAGE_ARGUMENT_ARRAY and
+ * @b@c FORMAT_MESSAGE_IGNORE_INSERTS. All the other flags are internally
+ * overridden by the function to implement its behaviour.
+ *
+ * @param[in] uID
+ * The identifier of the message string. The format string follows the
+ * same specifications as the @a lpSource format string in ConMsgPrintf().
+ *
+ * @param[in] LanguageId
+ * The language identifier of the resource. If this parameter is
+ * <tt>MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)</tt>, the current language
+ * associated with the calling thread is used. To specify a language other
+ * than the current language, use the @c MAKELANGID macro to create this
+ * parameter.
+ *
+ * @param[in] args
+ * Parameter describing a variable number of arguments, initialized
+ * with va_start(), that can be expected by the function, depending
+ * on the message string. Each argument is used to replace an
+ * <em>insert sequence</em> in the message string.
+ *
+ * @remark
+ * Contrary to printf(), ConPrintf(), ConResPrintf() and associated functions,
+ * the ConMsg* functions work on format strings that contain <em>insert sequences</em>.
+ * These sequences extend the standard <em>format specifiers</em> as they
+ * allow to specify an <em>insert number</em> referring which precise value
+ * given in arguments to use.
+ *
+ * @return
+ * Numbers of characters successfully written to @p Stream.
+ *
+ * @see ConPrintf(), ConResPrintf() and associated functions, ConMsgPrintf(),
+ * <a href="FormatMessage() (on MSDN)">https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).…</a>
+ **/
+INT
+ConResMsgPrintfExV(
+ IN PCON_STREAM Stream,
+ IN HINSTANCE hInstance OPTIONAL,
+ IN DWORD dwFlags,
+ IN UINT uID,
+ IN LANGID LanguageId,
+ IN va_list *Arguments OPTIONAL)
+{
+ INT Len;
+ DWORD dwLength = 0;
+ LPWSTR lpMsgBuf = NULL;
+ WCHAR bufSrc[CON_RC_STRING_MAX_SIZE];
+
+ /* Retrieve the string from the resource string table */
+ // NOTE: We may use the special behaviour where nBufMaxSize == 0
+ Len = K32LoadStringExW(hInstance, uID, LanguageId, bufSrc, ARRAYSIZE(bufSrc));
+ if (Len == 0)
+ return Len;
+
+ /* Sanitize dwFlags */
+ dwFlags |= FORMAT_MESSAGE_ALLOCATE_BUFFER; // Always allocate an internal buffer.
+ //
+ // NOTE: Technique taken from eventvwr.c!GetMessageStringFromDll()
+ //
+ dwFlags |= FORMAT_MESSAGE_MAX_WIDTH_MASK;
+
+ /* The string has already been manually loaded */
+ dwFlags &= ~(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM);
+ dwFlags |= FORMAT_MESSAGE_FROM_STRING;
+
+ /*
+ * Retrieve the message string without appending extra newlines.
+ * Use the "safe" FormatMessage version (SEH-protected) to protect
+ * from invalid string parameters.
+ */
+ dwLength = FormatMessageSafeW(dwFlags,
+ bufSrc,
+ 0, 0,
+ (LPWSTR)&lpMsgBuf,
+ 0,
+ Arguments);
+
+ Len = (INT)dwLength;
+
+ if (!lpMsgBuf)
+ {
+ // ASSERT(dwLength == 0);
+ }
+ else
+ {
+ // ASSERT(dwLength != 0);
+
+ CON_STREAM_WRITE2(Stream, lpMsgBuf, dwLength, Len);
+
+ /* Fixup returned length in case of errors */
+ if (Len < 0)
+ Len = 0;
+
+ /* Free the buffer allocated by FormatMessage */
+ LocalFree(lpMsgBuf);
+ }
+
+ return Len;
+}
+
+/**
+ * @name ConResMsgPrintfV
+ * Formats and writes a message string to a stream. The function requires
+ * a message definition as input. Contrary to the ConMsg* or the Win32
+ * FormatMessage() functions, the message definition comes from a resource
+ * string table, much like the strings for ConResPrintf(), but is formatted
+ * according to the rules of ConMsgPrintf().
+ *
+ * @param[in] Stream
+ * Stream to which the write operation is issued.
+ *
+ * @param[in] dwFlags
+ * The formatting options, see FormatMessage() for more details.
+ * The only valid flags are @b@c FORMAT_MESSAGE_ARGUMENT_ARRAY and
+ * @b@c FORMAT_MESSAGE_IGNORE_INSERTS. All the other flags are internally
+ * overridden by the function to implement its behaviour.
+ *
+ * @param[in] uID
+ * The identifier of the message string. The format string follows the
+ * same specifications as the @a lpSource format string in ConMsgPrintf().
+ *
+ * @param[in] Arguments
+ * Optional pointer to an array of values describing a variable number of
+ * arguments, depending on the message string. Each argument is used to
+ * replace an <em>insert sequence</em> in the message string.
+ * By default, the @p Arguments parameter is of type @c va_list*, initialized
+ * with va_start(). The state of the @c va_list argument is undefined upon
+ * return from the function. To use the @c va_list again, destroy the variable
+ * argument list pointer using va_end() and reinitialize it with va_start().
+ * If you do not have a pointer of type @c va_list*, then specify the
+ * @b@c FORMAT_MESSAGE_ARGUMENT_ARRAY flag and pass a pointer to an array
+ * of @c DWORD_PTR values; those values are input to the message formatted
+ * as the insert values. Each insert must have a corresponding element in
+ * the array.
+ *
+ * @remark
+ * Contrary to printf(), ConPrintf(), ConResPrintf() and associated functions,
+ * the ConMsg* functions work on format strings that contain <em>insert sequences</em>.
+ * These sequences extend the standard <em>format specifiers</em> as they
+ * allow to specify an <em>insert number</em> referring which precise value
+ * given in arguments to use.
+ *
+ * @return
+ * Numbers of characters successfully written to @p Stream.
+ *
+ * @see ConPrintf(), ConResPrintf() and associated functions, ConMsgPrintf(),
+ * <a href="FormatMessage() (on MSDN)">https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).…</a>
+ **/
+INT
+ConResMsgPrintfV(
+ IN PCON_STREAM Stream,
+ IN DWORD dwFlags,
+ IN UINT uID,
+ IN va_list *Arguments OPTIONAL)
+{
+ return ConResMsgPrintfExV(Stream, NULL /*GetModuleHandleW(NULL)*/,
+ dwFlags, uID,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
+ Arguments);
+}
+
+/**
+ * @name ConResMsgPrintfEx
+ * Formats and writes a message string to a stream. The function requires
+ * a message definition as input. Contrary to the ConMsg* or the Win32
+ * FormatMessage() functions, the message definition comes from a resource
+ * string table, much like the strings for ConResPrintf(), but is formatted
+ * according to the rules of ConMsgPrintf().
+ *
+ * @param[in] Stream
+ * Stream to which the write operation is issued.
+ *
+ * @param[in] hInstance
+ * Optional handle to an instance of the module whose executable file
+ * contains the string resource. Can be set to NULL to get the handle
+ * to the application itself.
+ *
+ * @param[in] dwFlags
+ * The formatting options, see FormatMessage() for more details.
+ * The only valid flag is @b@c FORMAT_MESSAGE_IGNORE_INSERTS.
+ * All the other flags are internally overridden by the function
+ * to implement its behaviour.
+ *
+ * @param[in] uID
+ * The identifier of the message string. The format string follows the
+ * same specifications as the @a lpSource format string in ConMsgPrintf().
+ *
+ * @param[in] LanguageId
+ * The language identifier of the resource. If this parameter is
+ * <tt>MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)</tt>, the current language
+ * associated with the calling thread is used. To specify a language other
+ * than the current language, use the @c MAKELANGID macro to create this
+ * parameter.
+ *
+ * @param[in] ...
+ * Additional arguments that can be expected by the function, depending
+ * on the message string. Each argument is used to replace an
+ * <em>insert sequence</em> in the message string.
+ *
+ * @remark
+ * Contrary to printf(), ConPrintf(), ConResPrintf() and associated functions,
+ * the ConMsg* functions work on format strings that contain <em>insert sequences</em>.
+ * These sequences extend the standard <em>format specifiers</em> as they
+ * allow to specify an <em>insert number</em> referring which precise value
+ * given in arguments to use.
+ *
+ * @return
+ * Numbers of characters successfully written to @p Stream.
+ *
+ * @see ConPrintf(), ConResPrintf() and associated functions, ConMsgPrintf(),
+ * <a href="FormatMessage() (on MSDN)">https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).…</a>
+ **/
+INT
+__cdecl
+ConResMsgPrintfEx(
+ IN PCON_STREAM Stream,
+ IN HINSTANCE hInstance OPTIONAL,
+ IN DWORD dwFlags,
+ IN UINT uID,
+ IN LANGID LanguageId,
+ ...)
+{
+ INT Len;
+ va_list args;
+
+ /* Sanitize dwFlags */
+ dwFlags &= ~FORMAT_MESSAGE_ARGUMENT_ARRAY;
+
+ va_start(args, LanguageId);
+ Len = ConResMsgPrintfExV(Stream,
+ hInstance,
+ dwFlags,
+ uID,
+ LanguageId,
+ &args);
+ va_end(args);
+
+ return Len;
+}
+
+/**
+ * @name ConResMsgPrintf
+ * Formats and writes a message string to a stream. The function requires
+ * a message definition as input. Contrary to the ConMsg* or the Win32
+ * FormatMessage() functions, the message definition comes from a resource
+ * string table, much like the strings for ConResPrintf(), but is formatted
+ * according to the rules of ConMsgPrintf().
+ *
+ * @param[in] Stream
+ * Stream to which the write operation is issued.
+ *
+ * @param[in] dwFlags
+ * The formatting options, see FormatMessage() for more details.
+ * The only valid flag is @b@c FORMAT_MESSAGE_IGNORE_INSERTS.
+ * All the other flags are internally overridden by the function
+ * to implement its behaviour.
+ *
+ * @param[in] uID
+ * The identifier of the message string. The format string follows the
+ * same specifications as the @a lpSource format string in ConMsgPrintf().
+ *
+ * @param[in] ...
+ * Additional arguments that can be expected by the function, depending
+ * on the message string. Each argument is used to replace an
+ * <em>insert sequence</em> in the message string.
+ *
+ * @remark
+ * Contrary to printf(), ConPrintf(), ConResPrintf() and associated functions,
+ * the ConMsg* functions work on format strings that contain <em>insert sequences</em>.
+ * These sequences extend the standard <em>format specifiers</em> as they
+ * allow to specify an <em>insert number</em> referring which precise value
+ * given in arguments to use.
+ *
+ * @return
+ * Numbers of characters successfully written to @p Stream.
+ *
+ * @see ConPrintf(), ConResPrintf() and associated functions, ConMsgPrintf(),
+ * <a href="FormatMessage() (on MSDN)">https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).…</a>
+ **/
+INT
+__cdecl
+ConResMsgPrintf(
+ IN PCON_STREAM Stream,
+ IN DWORD dwFlags,
+ IN UINT uID,
+ ...)
+{
+ INT Len;
+ va_list args;
+
+ /* Sanitize dwFlags */
+ dwFlags &= ~FORMAT_MESSAGE_ARGUMENT_ARRAY;
+
+ va_start(args, uID);
+ Len = ConResMsgPrintfV(Stream, dwFlags, uID, &args);
va_end(args);
return Len;
diff --git a/sdk/lib/conutils/outstream.h b/sdk/lib/conutils/outstream.h
index a4099e2e10..47a3e06ae4 100644
--- a/sdk/lib/conutils/outstream.h
+++ b/sdk/lib/conutils/outstream.h
@@ -8,6 +8,13 @@
* Copyright 2017-2018 Hermes Belusca-Maito
*/
+/**
+ * @file outstream.h
+ * @ingroup ConUtils
+ *
+ * @brief Console I/O utility API -- Output
+ **/
+
#ifndef __OUTSTREAM_H__
#define __OUTSTREAM_H__
@@ -37,22 +44,18 @@ typedef struct _CON_STREAM CON_STREAM, *PCON_STREAM;
typedef INT (__stdcall *CON_WRITE_FUNC)(IN PCON_STREAM, IN PTCHAR, IN DWORD);
-/*
- * Console I/O utility API -- Output
- */
-
INT
__stdcall
ConWrite(
IN PCON_STREAM Stream,
IN PTCHAR szStr,
- IN DWORD len);
+ IN DWORD len);
INT
ConStreamWrite(
IN PCON_STREAM Stream,
IN PTCHAR szStr,
- IN DWORD len);
+ IN DWORD len);
INT
ConPuts(
@@ -63,7 +66,7 @@ INT
ConPrintfV(
IN PCON_STREAM Stream,
IN LPWSTR szStr,
- IN va_list args); // arg_ptr
+ IN va_list args);
INT
__cdecl
@@ -76,7 +79,8 @@ INT
ConResPutsEx(
IN PCON_STREAM Stream,
IN HINSTANCE hInstance OPTIONAL,
- IN UINT uID);
+ IN UINT uID,
+ IN LANGID LanguageId);
INT
ConResPuts(
@@ -88,20 +92,22 @@ ConResPrintfExV(
IN PCON_STREAM Stream,
IN HINSTANCE hInstance OPTIONAL,
IN UINT uID,
- IN va_list args); // arg_ptr
+ IN LANGID LanguageId,
+ IN va_list args);
INT
ConResPrintfV(
IN PCON_STREAM Stream,
IN UINT uID,
- IN va_list args); // arg_ptr
+ IN va_list args);
INT
__cdecl
ConResPrintfEx(
IN PCON_STREAM Stream,
IN HINSTANCE hInstance OPTIONAL,
- IN UINT uID,
+ IN UINT uID,
+ IN LANGID LanguageId,
...);
INT
@@ -126,7 +132,7 @@ ConMsgPrintf2V(
IN LPCVOID lpSource OPTIONAL,
IN DWORD dwMessageId,
IN DWORD dwLanguageId,
- IN va_list args); // arg_ptr
+ IN va_list args);
INT
ConMsgPrintfV(
@@ -135,7 +141,7 @@ ConMsgPrintfV(
IN LPCVOID lpSource OPTIONAL,
IN DWORD dwMessageId,
IN DWORD dwLanguageId,
- IN va_list args); // arg_ptr
+ IN va_list *Arguments OPTIONAL);
INT
__cdecl
@@ -147,6 +153,40 @@ ConMsgPrintf(
IN DWORD dwLanguageId,
...);
+INT
+ConResMsgPrintfExV(
+ IN PCON_STREAM Stream,
+ IN HINSTANCE hInstance OPTIONAL,
+ IN DWORD dwFlags,
+ IN UINT uID,
+ IN LANGID LanguageId,
+ IN va_list *Arguments OPTIONAL);
+
+INT
+ConResMsgPrintfV(
+ IN PCON_STREAM Stream,
+ IN DWORD dwFlags,
+ IN UINT uID,
+ IN va_list *Arguments OPTIONAL);
+
+INT
+__cdecl
+ConResMsgPrintfEx(
+ IN PCON_STREAM Stream,
+ IN HINSTANCE hInstance OPTIONAL,
+ IN DWORD dwFlags,
+ IN UINT uID,
+ IN LANGID LanguageId,
+ ...);
+
+INT
+__cdecl
+ConResMsgPrintf(
+ IN PCON_STREAM Stream,
+ IN DWORD dwFlags,
+ IN UINT uID,
+ ...);
+
VOID
diff --git a/sdk/lib/conutils/pager.c b/sdk/lib/conutils/pager.c
index ac6bd3f0b5..27cbd72500 100644
--- a/sdk/lib/conutils/pager.c
+++ b/sdk/lib/conutils/pager.c
@@ -6,6 +6,13 @@
* Copyright 2017-2018 Hermes Belusca-Maito
*/
+/**
+ * @file pager.c
+ * @ingroup ConUtils
+ *
+ * @brief Console/terminal paging functionality.
+ **/
+
/* FIXME: Temporary HACK before we cleanly support UNICODE functions */
#define UNICODE
#define _UNICODE
diff --git a/sdk/lib/conutils/pager.h b/sdk/lib/conutils/pager.h
index 486b520d12..27737224a0 100644
--- a/sdk/lib/conutils/pager.h
+++ b/sdk/lib/conutils/pager.h
@@ -6,6 +6,13 @@
* Copyright 2017-2018 Hermes Belusca-Maito
*/
+/**
+ * @file pager.h
+ * @ingroup ConUtils
+ *
+ * @brief Console/terminal paging functionality.
+ **/
+
#ifndef __PAGER_H__
#define __PAGER_H__
diff --git a/sdk/lib/conutils/screen.c b/sdk/lib/conutils/screen.c
index 04f0b6e91d..b3d1c01b52 100644
--- a/sdk/lib/conutils/screen.c
+++ b/sdk/lib/conutils/screen.c
@@ -6,6 +6,13 @@
* Copyright 2017-2018 Hermes Belusca-Maito
*/
+/**
+ * @file screen.c
+ * @ingroup ConUtils
+ *
+ * @brief Console/terminal screen management.
+ **/
+
/* FIXME: Temporary HACK before we cleanly support UNICODE functions */
#define UNICODE
#define _UNICODE
diff --git a/sdk/lib/conutils/screen.h b/sdk/lib/conutils/screen.h
index 2ab11a7a65..f2e9714eff 100644
--- a/sdk/lib/conutils/screen.h
+++ b/sdk/lib/conutils/screen.h
@@ -6,6 +6,13 @@
* Copyright 2017-2018 Hermes Belusca-Maito
*/
+/**
+ * @file screen.h
+ * @ingroup ConUtils
+ *
+ * @brief Console/terminal screen management.
+ **/
+
#ifndef __SCREEN_H__
#define __SCREEN_H__
diff --git a/sdk/lib/conutils/stream.c b/sdk/lib/conutils/stream.c
index 5b843c183e..0b137ea2f7 100644
--- a/sdk/lib/conutils/stream.c
+++ b/sdk/lib/conutils/stream.c
@@ -8,6 +8,13 @@
* Copyright 2017-2018 Hermes Belusca-Maito
*/
+/**
+ * @file stream.c
+ * @ingroup ConUtils
+ *
+ * @brief Console I/O streams
+ **/
+
/*
* Enable this define if you want to only use CRT functions to output
* UNICODE stream to the console, as in the way explained by
@@ -37,10 +44,6 @@
#include "stream_private.h"
-/*
- * Console I/O streams
- */
-
/*
* Standard console streams, initialized by
* calls to ConStreamInit/ConInitStdStreams.
diff --git a/sdk/lib/conutils/stream.h b/sdk/lib/conutils/stream.h
index f3804b6103..8a2746af5c 100644
--- a/sdk/lib/conutils/stream.h
+++ b/sdk/lib/conutils/stream.h
@@ -8,6 +8,13 @@
* Copyright 2017-2018 Hermes Belusca-Maito
*/
+/**
+ * @file stream.h
+ * @ingroup ConUtils
+ *
+ * @brief Console I/O streams
+ **/
+
#ifndef __STREAM_H__
#define __STREAM_H__
@@ -29,10 +36,6 @@
extern "C" {
#endif
-/*
- * Console I/O streams
- */
-
/*
* See http://archives.miloush.net/michkap/archive/2009/08/14/9869928.html
* for more information.
diff --git a/sdk/lib/conutils/utils.c b/sdk/lib/conutils/utils.c
index b5dfdeefd1..e6e6fb8d24 100644
--- a/sdk/lib/conutils/utils.c
+++ b/sdk/lib/conutils/utils.c
@@ -7,6 +7,14 @@
* Copyright 2017-2018 Hermes Belusca-Maito
*/
+/**
+ * @file utils.c
+ * @ingroup ConUtils
+ *
+ * @brief General-purpose utility functions (wrappers around
+ * or reimplementations of Win32 APIs).
+ **/
+
/* FIXME: Temporary HACK before we cleanly support UNICODE functions */
#define UNICODE
#define _UNICODE
@@ -24,11 +32,6 @@
// #include "conutils.h"
#include "utils.h"
-/*
- * General-purpose utility functions (wrappers around,
- * or reimplementations of, Win32 APIs).
- */
-
#if 0 // The following function may be useful in the future...
// Performs MultiByteToWideChar then WideCharToMultiByte .
@@ -55,9 +58,10 @@ MultiByteToMultiByte(
*/
INT
WINAPI
-K32LoadStringW(
+K32LoadStringExW(
IN HINSTANCE hInstance OPTIONAL,
IN UINT uID,
+ IN LANGID LanguageId,
OUT LPWSTR lpBuffer,
IN INT nBufferMax)
{
@@ -71,11 +75,10 @@ K32LoadStringW(
/* Use LOWORD (incremented by 1) as ResourceID */
/* There are always blocks of 16 strings */
- // FindResourceExW(hInstance, RT_STRING, name, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
- // NOTE: Instead of using LANG_NEUTRAL, one might use LANG_USER_DEFAULT...
- hrsrc = FindResourceW(hInstance,
- MAKEINTRESOURCEW((LOWORD(uID) >> 4) + 1),
- (LPWSTR)RT_STRING);
+ hrsrc = FindResourceExW(hInstance,
+ (LPCWSTR)RT_STRING,
+ MAKEINTRESOURCEW((LOWORD(uID) >> 4) + 1),
+ LanguageId);
if (!hrsrc) return 0;
hmem = LoadResource(hInstance, hrsrc);
@@ -118,6 +121,20 @@ K32LoadStringW(
return i;
}
+INT
+WINAPI
+K32LoadStringW(
+ IN HINSTANCE hInstance OPTIONAL,
+ IN UINT uID,
+ OUT LPWSTR lpBuffer,
+ IN INT nBufferMax)
+{
+ // NOTE: Instead of using LANG_NEUTRAL, one might use LANG_USER_DEFAULT...
+ return K32LoadStringExW(hInstance, uID,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
+ lpBuffer, nBufferMax);
+}
+
/*
* "Safe" version of FormatMessageW, that does not crash if a malformed
* source string is retrieved and then being used for formatting.
@@ -194,18 +211,50 @@ FormatMessageSafeW(
return dwLength;
}
+/**
+ * @name IsTTYHandle
+ * Checks whether a handle refers to a valid TTY object.
+ * A TTY object may be a console or a "communications" (e.g. serial) port.
+ *
+ * @param[in] hHandle
+ * Handle to the TTY object to check for.
+ *
+ * @return
+ * @b@c TRUE when the handle refers to a valid TTY object,
+ * @b@c FALSE if it does not.
+ *
+ * @remark
+ * This test is more general than IsConsoleHandle() as it is not limited
+ * to Win32 console objects only.
+ *
+ * @see IsConsoleHandle()
+ **/
BOOL
IsTTYHandle(IN HANDLE hHandle)
{
/*
- * More general test than IsConsoleHandle. Consoles, as well as
- * serial ports, etc... verify this test, but only consoles verify
- * the IsConsoleHandle test: indeed the latter checks whether
+ * More general test than IsConsoleHandle(). Consoles, as well as serial
+ * (communications) ports, etc... verify this test, but only consoles
+ * verify the IsConsoleHandle() test: indeed the latter checks whether
* the handle is really handled by the console subsystem.
*/
return ((GetFileType(hHandle) & ~FILE_TYPE_REMOTE) == FILE_TYPE_CHAR);
}
+/**
+ * @name IsConsoleHandle
+ * Checks whether a handle refers to a valid Win32 console object.
+ *
+ * @param[in] hHandle
+ * Handle to the Win32 console object to check for:
+ * console input buffer, console output buffer.
+ *
+ * @return
+ * @b@c TRUE when the handle refers to a valid Win32 console object,
+ * @b@c FALSE if it does not.
+ *
+ * @see IsTTYHandle()
+ **/
BOOL
IsConsoleHandle(IN HANDLE hHandle)
{
diff --git a/sdk/lib/conutils/utils.h b/sdk/lib/conutils/utils.h
index 9f414ab0a8..798548056e 100644
--- a/sdk/lib/conutils/utils.h
+++ b/sdk/lib/conutils/utils.h
@@ -7,6 +7,14 @@
* Copyright 2017-2018 Hermes Belusca-Maito
*/
+/**
+ * @file utils.h
+ * @ingroup ConUtils
+ *
+ * @brief General-purpose utility functions (wrappers around
+ * or reimplementations of Win32 APIs).
+ **/
+
#ifndef __UTILS_H__
#define __UTILS_H__
@@ -20,10 +28,14 @@
extern "C" {
#endif
-/*
- * General-purpose utility functions (wrappers around,
- * or reimplementations of, Win32 APIs).
- */
+INT
+WINAPI
+K32LoadStringExW(
+ IN HINSTANCE hInstance OPTIONAL,
+ IN UINT uID,
+ IN LANGID LanguageId,
+ OUT LPWSTR lpBuffer,
+ IN INT nBufferMax);
INT
WINAPI