ReactOS  0.4.14-dev-41-g31d7680
utils.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Console Utilities Library
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: Base set of functions for loading string resources
5  * and message strings, and handle type identification.
6  * COPYRIGHT: Copyright 2017-2018 ReactOS Team
7  * Copyright 2017-2018 Hermes Belusca-Maito
8  */
9 
18 /* FIXME: Temporary HACK before we cleanly support UNICODE functions */
19 #define UNICODE
20 #define _UNICODE
21 
22 #include <windef.h>
23 #include <winbase.h>
24 #include <winnls.h>
25 #include <winuser.h> // MAKEINTRESOURCEW, RT_STRING
26 #include <wincon.h> // Console APIs (only if kernel32 support included)
27 #include <strsafe.h>
28 
29 /* PSEH for SEH Support */
30 #include <pseh/pseh2.h>
31 
32 // #include "conutils.h"
33 #include "utils.h"
34 
35 #if 0 // The following function may be useful in the future...
36 
37 // Performs MultiByteToWideChar then WideCharToMultiByte .
38 // See https://github.com/pcman-bbs/pcman-windows/blob/master/Lite/StrUtils.h#l33
39 // and http://www.openfoundry.org/svn/pcman/branches/OpenPCMan_2009/Lite/StrUtils.cpp
40 // for the idea.
41 int
42 MultiByteToMultiByte(
43  // IN WORD wTranslations,
45  IN UINT SrcCodePage,
46  IN LPCSTR lpSrcString,
47  IN int cbSrcChar,
48  IN UINT DestCodePage,
49  OUT LPSTR wDestString OPTIONAL,
50  IN int cbDestChar
51 );
52 
53 #endif
54 
97 INT
98 WINAPI
101  IN UINT uID,
102  IN LANGID LanguageId,
104  IN INT nBufferMax)
105 {
106  HRSRC hrsrc;
107  HGLOBAL hmem;
108  WCHAR *p;
109  UINT i;
110 
111  if (!lpBuffer)
112  return 0;
113 
114  /* Use LOWORD (incremented by 1) as ResourceID */
115  /* There are always blocks of 16 strings */
116  hrsrc = FindResourceExW(hInstance,
118  MAKEINTRESOURCEW((LOWORD(uID) >> 4) + 1),
119  LanguageId);
120  if (!hrsrc) return 0;
121 
122  hmem = LoadResource(hInstance, hrsrc);
123  if (!hmem) return 0;
124 
125  p = LockResource(hmem);
126  // FreeResource(hmem);
127 
128  /* Find the string we're looking for */
129  uID &= 0x000F; /* Position in the block, same as % 16 */
130  for (i = 0; i < uID; i++)
131  p += *p + 1;
132 
133  /*
134  * If nBufferMax == 0, then return a read-only pointer
135  * to the resource itself in lpBuffer it is assumed that
136  * lpBuffer is actually a (LPWSTR *).
137  */
138  if (nBufferMax == 0)
139  {
140  *((LPWSTR*)lpBuffer) = p + 1;
141  return *p;
142  }
143 
144  i = min(nBufferMax - 1, *p);
145  if (i > 0)
146  {
147  memcpy(lpBuffer, p + 1, i * sizeof(WCHAR));
148  lpBuffer[i] = L'\0';
149  }
150  else
151  {
152  if (nBufferMax > 1)
153  {
154  lpBuffer[0] = L'\0';
155  return 0;
156  }
157  }
158 
159  return i;
160 }
161 
171 INT
172 WINAPI
175  IN UINT uID,
177  IN INT nBufferMax)
178 {
179  // NOTE: Instead of using LANG_NEUTRAL, one might use LANG_USER_DEFAULT...
180  return K32LoadStringExW(hInstance, uID,
182  lpBuffer, nBufferMax);
183 }
184 
252 DWORD
253 WINAPI
255  IN DWORD dwFlags,
256  IN LPCVOID lpSource OPTIONAL,
257  IN DWORD dwMessageId,
258  IN DWORD dwLanguageId,
260  IN DWORD nSize,
261  IN va_list *Arguments OPTIONAL)
262 {
263  DWORD dwLength = 0;
264 
265  _SEH2_TRY
266  {
267  /*
268  * Retrieve the message string. Wrap in SEH
269  * to protect from invalid string parameters.
270  */
271  _SEH2_TRY
272  {
274  lpSource,
275  dwMessageId,
276  dwLanguageId,
277  lpBuffer,
278  nSize,
279  Arguments);
280  }
282  {
283  dwLength = 0;
284 
285  /*
286  * An exception occurred while calling FormatMessage, this is usually
287  * the sign that a parameter was invalid, either 'lpBuffer' was NULL
288  * but we did not pass the flag FORMAT_MESSAGE_ALLOCATE_BUFFER, or the
289  * array pointer 'Arguments' was NULL or did not contain enough elements,
290  * and we did not pass the flag FORMAT_MESSAGE_IGNORE_INSERTS, and the
291  * message string expected too many inserts.
292  * In this last case only, we can call again FormatMessage but ignore
293  * explicitely the inserts. The string that we will return to the user
294  * will not be pre-formatted.
295  */
298  {
299  /* Remove any possible harmful flags and always ignore inserts */
302 
303  /* If this call also throws an exception, we are really dead */
305  lpSource,
306  dwMessageId,
307  dwLanguageId,
308  lpBuffer,
309  nSize,
310  NULL /* Arguments */);
311  }
312  }
313  _SEH2_END;
314  }
316  {
317  }
318  _SEH2_END;
319 
320  return dwLength;
321 }
322 
341 BOOL
343 {
344  /*
345  * More general test than IsConsoleHandle(). Consoles, as well as serial
346  * (communications) ports, etc... verify this test, but only consoles
347  * verify the IsConsoleHandle() test: indeed the latter checks whether
348  * the handle is really handled by the console subsystem.
349  */
350  return ((GetFileType(hHandle) & ~FILE_TYPE_REMOTE) == FILE_TYPE_CHAR);
351 }
352 
367 BOOL
369 {
370  DWORD dwMode;
371 
372  /* Check whether the handle may be that of a console... */
373  if ((GetFileType(hHandle) & ~FILE_TYPE_REMOTE) != FILE_TYPE_CHAR)
374  return FALSE;
375 
376  /*
377  * It may be. Perform another test. The idea comes from the
378  * MSDN description of the WriteConsole API:
379  *
380  * "WriteConsole fails if it is used with a standard handle
381  * that is redirected to a file. If an application processes
382  * multilingual output that can be redirected, determine whether
383  * the output handle is a console handle (one method is to call
384  * the GetConsoleMode function and check whether it succeeds).
385  * If the handle is a console handle, call WriteConsole. If the
386  * handle is not a console handle, the output is redirected and
387  * you should call WriteFile to perform the I/O."
388  */
389  return GetConsoleMode(hHandle, &dwMode);
390 }
391 
392 /* EOF */
#define IN
Definition: typedefs.h:38
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define FILE_TYPE_REMOTE
Definition: winbase.h:259
#define LANG_NEUTRAL
Definition: nls.h:22
#define FORMAT_MESSAGE_ARGUMENT_ARRAY
Definition: winbase.h:405
BOOL WINAPI GetConsoleMode(HANDLE hConsoleHandle, LPDWORD lpMode)
Definition: console.c:1571
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:2024
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
INT WINAPI K32LoadStringW(IN HINSTANCE hInstance OPTIONAL, IN UINT uID, OUT LPWSTR lpBuffer, IN INT nBufferMax)
Definition: utils.c:173
DWORD WINAPI GetFileType(HANDLE hFile)
Definition: fileinfo.c:419
WORD LANGID
Definition: typedefs.h:79
char * LPSTR
Definition: xmlstorage.h:182
DWORD WINAPI FormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, __ms_va_list *args)
Definition: format_msg.c:583
#define SUBLANG_NEUTRAL
Definition: nls.h:167
int32_t INT
Definition: typedefs.h:56
_SEH2_TRY
Definition: create.c:4250
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
HINSTANCE hInstance
Definition: charmap.c:20
unsigned int BOOL
Definition: ntddk_ex.h:94
#define FILE_TYPE_CHAR
Definition: winbase.h:257
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:173
#define FORMAT_MESSAGE_ALLOCATE_BUFFER
Definition: winbase.h:400
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
smooth NULL
Definition: ftsmooth.c:416
char * va_list
Definition: acmsvcex.h:78
const char * LPCSTR
Definition: xmlstorage.h:183
BOOL IsTTYHandle(IN HANDLE hHandle)
Definition: utils.c:342
__wchar_t WCHAR
Definition: xmlstorage.h:180
static DWORD DWORD * dwLength
Definition: fusion.c:83
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
HRSRC WINAPI FindResourceExW(HMODULE hModule, LPCWSTR type, LPCWSTR name, WORD lang)
Definition: res.c:164
static const WCHAR L[]
Definition: oid.c:1250
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define RT_STRING
Definition: pedump.c:368
BOOL IsConsoleHandle(IN HANDLE hHandle)
Definition: utils.c:368
#define FORMAT_MESSAGE_IGNORE_INSERTS
Definition: winbase.h:401
_SEH2_END
Definition: create.c:4424
_SEH2_FINALLY
Definition: create.c:4395
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
CONST void * LPCVOID
Definition: windef.h:191
#define OUT
Definition: typedefs.h:39
#define MAKELANGID(p, s)
Definition: nls.h:15
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR * LPWSTR
Definition: xmlstorage.h:184
DWORD WINAPI FormatMessageSafeW(IN DWORD dwFlags, IN LPCVOID lpSource OPTIONAL, IN DWORD dwMessageId, IN DWORD dwLanguageId, OUT LPWSTR lpBuffer, IN DWORD nSize, IN va_list *Arguments OPTIONAL)
Definition: utils.c:254
#define LOWORD(l)
Definition: pedump.c:82
INT WINAPI K32LoadStringExW(IN HINSTANCE hInstance OPTIONAL, IN UINT uID, IN LANGID LanguageId, OUT LPWSTR lpBuffer, IN INT nBufferMax)
Definition: utils.c:99
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68