https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f982d77b8a6bf04767e776...
commit f982d77b8a6bf04767e776098faec095e8e28029 Author: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org AuthorDate: Fri Feb 2 00:35:08 2018 +0100 Commit: Hermès Bélusca-Maïto hermes.belusca-maito@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).aspx</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).aspx</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).aspx</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).aspx</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).aspx</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).aspx</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).aspx</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