mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 21:36:11 +00:00
Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.
This commit is contained in:
parent
b94e2d8ca0
commit
c2c66aff7d
24198 changed files with 0 additions and 37285 deletions
14
sdk/lib/conutils/CMakeLists.txt
Normal file
14
sdk/lib/conutils/CMakeLists.txt
Normal file
|
@ -0,0 +1,14 @@
|
|||
|
||||
list(APPEND SOURCE
|
||||
pager.c
|
||||
screen.c
|
||||
stream.c
|
||||
utils.c
|
||||
# conutils.h
|
||||
)
|
||||
|
||||
add_library(conutils ${SOURCE})
|
||||
# add_pch(conutils conutils.h SOURCE)
|
||||
add_dependencies(conutils xdk)
|
||||
target_link_libraries(conutils ${PSEH_LIB})
|
||||
add_importlibs(conutils msvcrt kernel32)
|
43
sdk/lib/conutils/README.txt
Normal file
43
sdk/lib/conutils/README.txt
Normal file
|
@ -0,0 +1,43 @@
|
|||
The ReactOS Console Utilities Library v0.1
|
||||
==========================================
|
||||
|
||||
COPYRIGHT: Under GPLv2, see COPYING in the top level directory.
|
||||
CREDITS: Thanks to the many people who originally wrote the code that finally
|
||||
ended up inside this library, with more or less refactoring, or
|
||||
whose code served as a basis for some functions of the library.
|
||||
|
||||
|
||||
INTRODUCTION
|
||||
~-~-~-~-~-~-
|
||||
|
||||
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.
|
||||
|
||||
|
||||
CONTENTS
|
||||
~-~-~-~-
|
||||
|
||||
0. 'conutils_base' (utils.c and utils.h): Base set of functions for loading
|
||||
string resources and message strings, and handle type identification.
|
||||
|
||||
1. 'conutils_stream' (stream.c and stream.h): Console Stream API (CON_STREAM):
|
||||
Stream initialization, basic ConStreamRead/Write. Stream utility functions:
|
||||
ConPuts/Printf, ConResPuts/Printf, ConMsgPuts/Printf.
|
||||
Depends on 'conutils_base'.
|
||||
|
||||
2. 'conutils_screen' (screen.c and screen.h): Console Screen API (CON_SCREEN):
|
||||
Introduces the notion of console/terminal screen around the streams. Manages
|
||||
console/terminal screen metrics for Win32 consoles and TTYs (serial...).
|
||||
Additional Screen utility functions.
|
||||
Depends on 'conutils_stream', and indirectly on 'conutils_base'.
|
||||
|
||||
3. 'conutils_pager' (pager.c and pager.h): Console Pager API (CON_PAGER):
|
||||
Implements core console/terminal paging functionality around console screens.
|
||||
Depends on 'conutils_screen' and indirectly on 'conutils_stream' and
|
||||
'conutils_base'.
|
||||
|
||||
4. More to come!
|
25
sdk/lib/conutils/conutils.h
Normal file
25
sdk/lib/conutils/conutils.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Console Utilities Library
|
||||
* FILE: sdk/lib/conutils/conutils.h
|
||||
* PURPOSE: Provides simple abstraction wrappers around CRT streams or
|
||||
* Win32 console API I/O functions, to deal with i18n + Unicode
|
||||
* related problems.
|
||||
* PROGRAMMERS: - Hermes Belusca-Maito (for the library);
|
||||
* - All programmers who wrote the different console applications
|
||||
* from which I took those functions and improved them.
|
||||
*/
|
||||
|
||||
#ifndef __CONUTILS_H__
|
||||
#define __CONUTILS_H__
|
||||
|
||||
#ifndef _UNICODE
|
||||
#error The ConUtils library only supports compilation with _UNICODE defined, at the moment!
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
#include "stream.h"
|
||||
#include "screen.h"
|
||||
#include "pager.h"
|
||||
|
||||
#endif /* __CONUTILS_H__ */
|
160
sdk/lib/conutils/pager.c
Normal file
160
sdk/lib/conutils/pager.c
Normal file
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Console Utilities Library
|
||||
* FILE: sdk/lib/conutils/pager.c
|
||||
* PURPOSE: Console/terminal paging functionality.
|
||||
* PROGRAMMERS: - Hermes Belusca-Maito (for the library);
|
||||
* - All programmers who wrote the different console applications
|
||||
* from which I took those functions and improved them.
|
||||
*/
|
||||
|
||||
/* FIXME: Temporary HACK before we cleanly support UNICODE functions */
|
||||
#define UNICODE
|
||||
#define _UNICODE
|
||||
|
||||
#include <stdlib.h> // limits.h // For MB_LEN_MAX
|
||||
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
// #include <winnls.h>
|
||||
#include <wincon.h> // Console APIs (only if kernel32 support included)
|
||||
#include <strsafe.h>
|
||||
|
||||
#include "conutils.h"
|
||||
#include "stream.h"
|
||||
#include "screen.h"
|
||||
#include "pager.h"
|
||||
|
||||
// Temporary HACK
|
||||
#define CON_STREAM_WRITE ConStreamWrite
|
||||
|
||||
|
||||
|
||||
/* Returns TRUE when all the text is displayed, and FALSE if display is stopped */
|
||||
BOOL
|
||||
ConWritePaging(
|
||||
IN PCON_PAGER Pager,
|
||||
IN PAGE_PROMPT PagePrompt,
|
||||
IN BOOL StartPaging,
|
||||
IN PTCHAR szStr,
|
||||
IN DWORD len)
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
|
||||
/* Used to see how big the screen is */
|
||||
DWORD ScreenLines = 0;
|
||||
|
||||
/* Chars since start of line */
|
||||
DWORD CharSL;
|
||||
|
||||
DWORD from = 0, i = 0;
|
||||
|
||||
/* Parameters validation */
|
||||
if (!Pager)
|
||||
return FALSE;
|
||||
|
||||
/* Reset LineCount and return if no string has been given */
|
||||
if (StartPaging == TRUE)
|
||||
Pager->LineCount = 0;
|
||||
if (szStr == NULL)
|
||||
return TRUE;
|
||||
|
||||
/* Get the size of the visual screen that can be printed to */
|
||||
if (!ConGetScreenInfo(Pager->Screen, &csbi))
|
||||
{
|
||||
/* We assume it's a file handle */
|
||||
CON_STREAM_WRITE(Pager->Screen->Stream, szStr, len);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the number of lines currently displayed on screen, minus 1
|
||||
* to account for the "press any key..." prompt from PagePrompt().
|
||||
*/
|
||||
ScreenLines = (csbi.srWindow.Bottom - csbi.srWindow.Top);
|
||||
CharSL = csbi.dwCursorPosition.X;
|
||||
|
||||
/* Make sure the user doesn't have the screen too small */
|
||||
if (ScreenLines < 4)
|
||||
{
|
||||
CON_STREAM_WRITE(Pager->Screen->Stream, szStr, len);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
while (i < len)
|
||||
{
|
||||
/* Search until the end of a line is reached */
|
||||
if (szStr[i++] != TEXT('\n') && ++CharSL < csbi.dwSize.X)
|
||||
continue;
|
||||
|
||||
Pager->LineCount++;
|
||||
CharSL = 0;
|
||||
|
||||
if (Pager->LineCount >= ScreenLines)
|
||||
{
|
||||
CON_STREAM_WRITE(Pager->Screen->Stream, &szStr[from], i-from);
|
||||
from = i;
|
||||
|
||||
/* Prompt the user; give him some values for statistics */
|
||||
// FIXME TODO: The prompt proc can also take ScreenLines ??
|
||||
if (!PagePrompt(Pager, from, len))
|
||||
return FALSE;
|
||||
|
||||
// TODO: Recalculate 'ScreenLines' in case the user redimensions
|
||||
// the window during the prompt.
|
||||
|
||||
/* Reset the number of lines being printed */
|
||||
Pager->LineCount = 0;
|
||||
}
|
||||
}
|
||||
if (i > from)
|
||||
CON_STREAM_WRITE(Pager->Screen->Stream, &szStr[from], i-from);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL
|
||||
ConPutsPaging(
|
||||
IN PCON_PAGER Pager,
|
||||
IN PAGE_PROMPT PagePrompt,
|
||||
IN BOOL StartPaging,
|
||||
IN LPTSTR szStr)
|
||||
{
|
||||
DWORD len;
|
||||
|
||||
/* Return if no string has been given */
|
||||
if (szStr == NULL)
|
||||
return TRUE;
|
||||
|
||||
len = wcslen(szStr);
|
||||
return ConWritePaging(Pager, PagePrompt, StartPaging, szStr, len);
|
||||
}
|
||||
|
||||
BOOL
|
||||
ConResPagingEx(
|
||||
IN PCON_PAGER Pager,
|
||||
IN PAGE_PROMPT PagePrompt,
|
||||
IN BOOL StartPaging,
|
||||
IN HINSTANCE hInstance OPTIONAL,
|
||||
IN UINT uID)
|
||||
{
|
||||
INT Len;
|
||||
PWCHAR szStr = NULL;
|
||||
|
||||
Len = K32LoadStringW(hInstance, uID, (PWSTR)&szStr, 0);
|
||||
if (szStr && Len)
|
||||
return ConWritePaging(Pager, PagePrompt, StartPaging, szStr, Len);
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL
|
||||
ConResPaging(
|
||||
IN PCON_PAGER Pager,
|
||||
IN PAGE_PROMPT PagePrompt,
|
||||
IN BOOL StartPaging,
|
||||
IN UINT uID)
|
||||
{
|
||||
return ConResPagingEx(Pager, PagePrompt, StartPaging,
|
||||
NULL /*GetModuleHandleW(NULL)*/, uID);
|
||||
}
|
74
sdk/lib/conutils/pager.h
Normal file
74
sdk/lib/conutils/pager.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Console Utilities Library
|
||||
* FILE: sdk/lib/conutils/pager.h
|
||||
* PURPOSE: Console/terminal paging functionality.
|
||||
* PROGRAMMERS: - Hermes Belusca-Maito (for the library);
|
||||
* - All programmers who wrote the different console applications
|
||||
* from which I took those functions and improved them.
|
||||
*/
|
||||
|
||||
#ifndef __PAGER_H__
|
||||
#define __PAGER_H__
|
||||
|
||||
#ifndef _UNICODE
|
||||
#error The ConUtils library at the moment only supports compilation with _UNICODE defined!
|
||||
#endif
|
||||
|
||||
|
||||
// #include <wincon.h>
|
||||
|
||||
|
||||
typedef struct _CON_PAGER
|
||||
{
|
||||
PCON_SCREEN Screen;
|
||||
|
||||
// TODO: Add more properties. Maybe those extra parameters
|
||||
// of PAGE_PROMPT could go there?
|
||||
|
||||
/* Used to count number of lines since last pause */
|
||||
DWORD LineCount;
|
||||
} CON_PAGER, *PCON_PAGER;
|
||||
|
||||
#define INIT_CON_PAGER(pScreen) {(pScreen), 0}
|
||||
|
||||
#define InitializeConPager(pPager, pScreen) \
|
||||
do { \
|
||||
(pPager)->Screen = (pScreen); \
|
||||
(pPager)->LineCount = 0; \
|
||||
} while (0)
|
||||
|
||||
// Pager, Done, Total
|
||||
typedef BOOL (__stdcall *PAGE_PROMPT)(IN PCON_PAGER, IN DWORD, IN DWORD);
|
||||
|
||||
BOOL
|
||||
ConWritePaging(
|
||||
IN PCON_PAGER Pager,
|
||||
IN PAGE_PROMPT PagePrompt,
|
||||
IN BOOL StartPaging,
|
||||
IN PTCHAR szStr,
|
||||
IN DWORD len);
|
||||
|
||||
BOOL
|
||||
ConPutsPaging(
|
||||
IN PCON_PAGER Pager,
|
||||
IN PAGE_PROMPT PagePrompt,
|
||||
IN BOOL StartPaging,
|
||||
IN LPTSTR szStr);
|
||||
|
||||
BOOL
|
||||
ConResPagingEx(
|
||||
IN PCON_PAGER Pager,
|
||||
IN PAGE_PROMPT PagePrompt,
|
||||
IN BOOL StartPaging,
|
||||
IN HINSTANCE hInstance OPTIONAL,
|
||||
IN UINT uID);
|
||||
|
||||
BOOL
|
||||
ConResPaging(
|
||||
IN PCON_PAGER Pager,
|
||||
IN PAGE_PROMPT PagePrompt,
|
||||
IN BOOL StartPaging,
|
||||
IN UINT uID);
|
||||
|
||||
#endif /* __PAGER_H__ */
|
175
sdk/lib/conutils/screen.c
Normal file
175
sdk/lib/conutils/screen.c
Normal file
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Console Utilities Library
|
||||
* FILE: sdk/lib/conutils/screen.c
|
||||
* PURPOSE: Console/terminal screen management.
|
||||
* PROGRAMMERS: - Hermes Belusca-Maito (for the library);
|
||||
* - All programmers who wrote the different console applications
|
||||
* from which I took those functions and improved them.
|
||||
*/
|
||||
|
||||
/* FIXME: Temporary HACK before we cleanly support UNICODE functions */
|
||||
#define UNICODE
|
||||
#define _UNICODE
|
||||
|
||||
#include <stdlib.h> // limits.h // For MB_LEN_MAX
|
||||
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
// #include <winnls.h>
|
||||
#include <wincon.h> // Console APIs (only if kernel32 support included)
|
||||
#include <strsafe.h>
|
||||
|
||||
#include "conutils.h"
|
||||
#include "stream.h"
|
||||
#include "screen.h"
|
||||
|
||||
// Temporary HACK
|
||||
#define CON_STREAM_WRITE ConStreamWrite
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
VOID
|
||||
ConClearLine(IN PCON_STREAM Stream)
|
||||
{
|
||||
HANDLE hOutput = ConStreamGetOSHandle(Stream);
|
||||
|
||||
/*
|
||||
* Erase the full line where the cursor is, and move
|
||||
* the cursor back to the beginning of the line.
|
||||
*/
|
||||
|
||||
if (IsConsoleHandle(hOutput))
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
DWORD dwWritten;
|
||||
|
||||
GetConsoleScreenBufferInfo(hOutput, &csbi);
|
||||
|
||||
csbi.dwCursorPosition.X = 0;
|
||||
// csbi.dwCursorPosition.Y;
|
||||
|
||||
FillConsoleOutputCharacterW(hOutput, L' ',
|
||||
csbi.dwSize.X,
|
||||
csbi.dwCursorPosition,
|
||||
&dwWritten);
|
||||
SetConsoleCursorPosition(hOutput, csbi.dwCursorPosition);
|
||||
}
|
||||
else if (IsTTYHandle(hOutput))
|
||||
{
|
||||
ConPuts(Stream, L"\x1B[2K\x1B[1G"); // FIXME: Just use WriteFile
|
||||
}
|
||||
// else, do nothing for files
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
BOOL
|
||||
ConGetScreenInfo(
|
||||
IN PCON_SCREEN Screen,
|
||||
OUT PCONSOLE_SCREEN_BUFFER_INFO pcsbi)
|
||||
{
|
||||
BOOL Success;
|
||||
HANDLE hOutput;
|
||||
|
||||
/* Parameters validation */
|
||||
if (!Screen || !pcsbi)
|
||||
return FALSE;
|
||||
|
||||
hOutput = ConStreamGetOSHandle(Screen->Stream);
|
||||
|
||||
/* Screen handle must be of TTY type (console or TTY) */
|
||||
if (!IsTTYHandle(hOutput))
|
||||
return FALSE;
|
||||
|
||||
/* Update cached screen information */
|
||||
if (IsConsoleHandle(hOutput))
|
||||
{
|
||||
Success = GetConsoleScreenBufferInfo(hOutput, &Screen->csbi);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
/* TODO: Do something adequate for TTYs */
|
||||
// FIXME: At the moment we return hardcoded info.
|
||||
Screen->csbi.dwSize.X = 80;
|
||||
Screen->csbi.dwSize.Y = 25;
|
||||
|
||||
// Screen->csbi.dwCursorPosition;
|
||||
// Screen->csbi.wAttributes;
|
||||
// Screen->csbi.srWindow;
|
||||
Screen->csbi.dwMaximumWindowSize = Screen->csbi.dwSize;
|
||||
#else
|
||||
hOutput = CreateFileW(L"CONOUT$", GENERIC_READ|GENERIC_WRITE,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
|
||||
OPEN_EXISTING, 0, NULL);
|
||||
|
||||
Success = IsConsoleHandle(hOutput) &&
|
||||
GetConsoleScreenBufferInfo(hOutput, &Screen->csbi);
|
||||
|
||||
CloseHandle(hOutput);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (Success)
|
||||
{
|
||||
/* Return it to the caller */
|
||||
*pcsbi = Screen->csbi;
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
// For real consoles, erase everything, otherwise (TTY) erase just the "screen".
|
||||
// FIXME: Or we can add a BOOL flag?
|
||||
VOID
|
||||
ConClearScreen(IN PCON_SCREEN Screen)
|
||||
{
|
||||
HANDLE hOutput;
|
||||
|
||||
/* Parameters validation */
|
||||
if (!Screen) return;
|
||||
|
||||
#if 0
|
||||
/* Get the size of the visual screen */
|
||||
if (!ConGetScreenInfo(Screen, &csbi))
|
||||
{
|
||||
/* We assume it's a file handle */
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
hOutput = ConStreamGetOSHandle(Screen->Stream);
|
||||
|
||||
if (IsConsoleHandle(hOutput))
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
COORD coPos;
|
||||
DWORD dwWritten;
|
||||
|
||||
GetConsoleScreenBufferInfo(hOutput, &csbi);
|
||||
|
||||
coPos.X = 0;
|
||||
coPos.Y = 0;
|
||||
FillConsoleOutputAttribute(hOutput, csbi.wAttributes,
|
||||
csbi.dwSize.X * csbi.dwSize.Y,
|
||||
coPos, &dwWritten);
|
||||
FillConsoleOutputCharacterW(hOutput, L' ',
|
||||
csbi.dwSize.X * csbi.dwSize.Y,
|
||||
coPos, &dwWritten);
|
||||
SetConsoleCursorPosition(hOutput, coPos);
|
||||
}
|
||||
else if (IsTTYHandle(hOutput))
|
||||
{
|
||||
/* Clear the full screen and move the cursor to (0,0) */
|
||||
ConPuts(Screen->Stream, L"\x1B[2J\x1B[1;1H");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Issue a Form-Feed control */
|
||||
WCHAR ch = L'\f';
|
||||
CON_STREAM_WRITE(Screen->Stream, &ch, 1);
|
||||
}
|
||||
}
|
56
sdk/lib/conutils/screen.h
Normal file
56
sdk/lib/conutils/screen.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Console Utilities Library
|
||||
* FILE: sdk/lib/conutils/screen.h
|
||||
* PURPOSE: Console/terminal screen management.
|
||||
* PROGRAMMERS: - Hermes Belusca-Maito (for the library);
|
||||
* - All programmers who wrote the different console applications
|
||||
* from which I took those functions and improved them.
|
||||
*/
|
||||
|
||||
#ifndef __SCREEN_H__
|
||||
#define __SCREEN_H__
|
||||
|
||||
#ifndef _UNICODE
|
||||
#error The ConUtils library at the moment only supports compilation with _UNICODE defined!
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
VOID
|
||||
ConClearLine(IN PCON_STREAM Stream);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#include <wincon.h>
|
||||
|
||||
typedef struct _CON_SCREEN
|
||||
{
|
||||
PCON_STREAM Stream; // Out
|
||||
// PCON_STREAM In;
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
CONSOLE_CURSOR_INFO cci;
|
||||
} CON_SCREEN, *PCON_SCREEN;
|
||||
|
||||
#define INIT_CON_SCREEN(pStream) {(pStream)} /* {(pStream), {{}}, {{}}} */
|
||||
|
||||
#define InitializeConScreen(pScreen, pStream) \
|
||||
do { \
|
||||
(pScreen)->Stream = (pStream); \
|
||||
RtlZeroMemory(&(pScreen)->csbi, sizeof((pScreen)->csbi)); \
|
||||
RtlZeroMemory(&(pScreen)->cci , sizeof((pScreen)->cci )); \
|
||||
} while (0)
|
||||
|
||||
BOOL
|
||||
ConGetScreenInfo(
|
||||
IN PCON_SCREEN Screen,
|
||||
OUT PCONSOLE_SCREEN_BUFFER_INFO pcsbi);
|
||||
|
||||
VOID
|
||||
ConClearScreen(IN PCON_SCREEN Screen);
|
||||
|
||||
|
||||
#endif /* __SCREEN_H__ */
|
1051
sdk/lib/conutils/stream.c
Normal file
1051
sdk/lib/conutils/stream.c
Normal file
File diff suppressed because it is too large
Load diff
267
sdk/lib/conutils/stream.h
Normal file
267
sdk/lib/conutils/stream.h
Normal file
|
@ -0,0 +1,267 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Console Utilities Library
|
||||
* FILE: sdk/lib/conutils/stream.h
|
||||
* PURPOSE: Provides basic abstraction wrappers around CRT streams or
|
||||
* Win32 console API I/O functions, to deal with i18n + Unicode
|
||||
* related problems.
|
||||
* PROGRAMMERS: - Hermes Belusca-Maito (for the library);
|
||||
* - All programmers who wrote the different console applications
|
||||
* from which I took those functions and improved them.
|
||||
*/
|
||||
|
||||
#ifndef __STREAM_H__
|
||||
#define __STREAM_H__
|
||||
|
||||
/*
|
||||
* Enable this define if you want to only use CRT functions to output
|
||||
* UNICODE stream to the console, as in the way explained by
|
||||
* http://archives.miloush.net/michkap/archive/2008/03/18/8306597.html
|
||||
*/
|
||||
/** NOTE: Experimental! Don't use USE_CRT yet because output to console is a bit broken **/
|
||||
// #define USE_CRT
|
||||
|
||||
#ifndef _UNICODE
|
||||
#error The ConUtils library at the moment only supports compilation with _UNICODE defined!
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Console I/O streams
|
||||
*/
|
||||
|
||||
/*
|
||||
* See http://archives.miloush.net/michkap/archive/2009/08/14/9869928.html
|
||||
* for more information.
|
||||
*/
|
||||
typedef enum _CON_STREAM_MODE
|
||||
{
|
||||
Binary = 0, // #define _O_BINARY 0x8000 // file mode is binary (untranslated)
|
||||
// #define _O_RAW _O_BINARY
|
||||
AnsiText, // #define _O_TEXT 0x4000 // file mode is text (translated) -- "ANSI"
|
||||
WideText, // #define _O_WTEXT 0x10000 // file mode is UTF16 with BOM (translated) -- "Unicode" of Windows
|
||||
UTF16Text, // #define _O_U16TEXT 0x20000 // file mode is UTF16 no BOM (translated) -- "" ""
|
||||
UTF8Text, // #define _O_U8TEXT 0x40000 // file mode is UTF8 no BOM (translated)
|
||||
} CON_STREAM_MODE, *PCON_STREAM_MODE;
|
||||
|
||||
#define INVALID_CP ((UINT)-1)
|
||||
|
||||
// Shadow type, implementation-specific
|
||||
typedef struct _CON_STREAM CON_STREAM, *PCON_STREAM;
|
||||
|
||||
// typedef INT (__stdcall *CON_READ_FUNC)(IN PCON_STREAM, IN PTCHAR, IN DWORD);
|
||||
// Stream, szStr, len
|
||||
typedef INT (__stdcall *CON_WRITE_FUNC)(IN PCON_STREAM, IN PTCHAR, IN DWORD);
|
||||
|
||||
/*
|
||||
* Standard console streams, initialized by
|
||||
* calls to ConStreamInit/ConInitStdStreams.
|
||||
*/
|
||||
#if 0 // FIXME!
|
||||
extern CON_STREAM StdStreams[3];
|
||||
#define StdIn (&StdStreams[0])
|
||||
#define StdOut (&StdStreams[1])
|
||||
#define StdErr (&StdStreams[2])
|
||||
#else
|
||||
extern CON_STREAM csStdIn;
|
||||
extern CON_STREAM csStdOut;
|
||||
extern CON_STREAM csStdErr;
|
||||
#define StdIn (&csStdIn )
|
||||
#define StdOut (&csStdOut)
|
||||
#define StdErr (&csStdErr)
|
||||
#endif
|
||||
|
||||
BOOL
|
||||
ConStreamInitEx(
|
||||
OUT PCON_STREAM Stream,
|
||||
IN PVOID Handle,
|
||||
IN CON_STREAM_MODE Mode,
|
||||
IN UINT CacheCodePage OPTIONAL,
|
||||
// IN ReadWriteMode ????
|
||||
// IN CON_READ_FUNC ReadFunc OPTIONAL,
|
||||
IN CON_WRITE_FUNC WriteFunc OPTIONAL);
|
||||
|
||||
BOOL
|
||||
ConStreamInit(
|
||||
OUT PCON_STREAM Stream,
|
||||
IN PVOID Handle,
|
||||
// IN ReadWriteMode ????
|
||||
IN CON_STREAM_MODE Mode,
|
||||
IN UINT CacheCodePage OPTIONAL);
|
||||
|
||||
|
||||
/* Console Standard Streams initialization helpers */
|
||||
#ifdef USE_CRT
|
||||
#define ConInitStdStreamsAndMode(Mode, CacheCodePage) \
|
||||
do { \
|
||||
ConStreamInit(StdIn , stdin , (Mode), (CacheCodePage)); \
|
||||
ConStreamInit(StdOut, stdout, (Mode), (CacheCodePage)); \
|
||||
ConStreamInit(StdErr, stderr, (Mode), (CacheCodePage)); \
|
||||
} while(0)
|
||||
#else
|
||||
#define ConInitStdStreamsAndMode(Mode, CacheCodePage) \
|
||||
do { \
|
||||
ConStreamInit(StdIn , GetStdHandle(STD_INPUT_HANDLE) , (Mode), (CacheCodePage)); \
|
||||
ConStreamInit(StdOut, GetStdHandle(STD_OUTPUT_HANDLE), (Mode), (CacheCodePage)); \
|
||||
ConStreamInit(StdErr, GetStdHandle(STD_ERROR_HANDLE) , (Mode), (CacheCodePage)); \
|
||||
} while(0)
|
||||
#endif /* defined(USE_CRT) */
|
||||
|
||||
#ifdef _UNICODE
|
||||
/*
|
||||
* Use UTF8 by default for file output, because this mode is back-compatible
|
||||
* with ANSI, and it displays nice on terminals that support UTF8 by default
|
||||
* (not many terminals support UTF16 on the contrary).
|
||||
*/
|
||||
#define ConInitStdStreams() \
|
||||
ConInitStdStreamsAndMode(UTF8Text, INVALID_CP); // Cache code page unused
|
||||
#else
|
||||
/* Use ANSI by default for file output */
|
||||
#define ConInitStdStreams() \
|
||||
ConInitStdStreamsAndMode(AnsiText, INVALID_CP);
|
||||
#endif /* defined(_UNICODE) */
|
||||
|
||||
/* Stream translation modes */
|
||||
BOOL
|
||||
ConStreamSetMode(
|
||||
IN PCON_STREAM Stream,
|
||||
IN CON_STREAM_MODE Mode,
|
||||
IN UINT CacheCodePage OPTIONAL);
|
||||
|
||||
#ifdef USE_CRT
|
||||
// FIXME!
|
||||
#warning The ConStreamSetCacheCodePage function does not make much sense with the CRT!
|
||||
#else
|
||||
BOOL
|
||||
ConStreamSetCacheCodePage(
|
||||
IN PCON_STREAM Stream,
|
||||
IN UINT CacheCodePage);
|
||||
#endif
|
||||
|
||||
HANDLE
|
||||
ConStreamGetOSHandle(
|
||||
IN PCON_STREAM Stream);
|
||||
|
||||
BOOL
|
||||
ConStreamSetOSHandle(
|
||||
IN PCON_STREAM Stream,
|
||||
IN HANDLE Handle);
|
||||
|
||||
|
||||
/*
|
||||
* Console I/O utility API
|
||||
* (for the moment, only Output)
|
||||
*/
|
||||
|
||||
INT
|
||||
__stdcall
|
||||
ConWrite(
|
||||
IN PCON_STREAM Stream,
|
||||
IN PTCHAR szStr,
|
||||
IN DWORD len);
|
||||
|
||||
INT
|
||||
ConStreamWrite(
|
||||
IN PCON_STREAM Stream,
|
||||
IN PTCHAR szStr,
|
||||
IN DWORD len);
|
||||
|
||||
INT
|
||||
ConPuts(
|
||||
IN PCON_STREAM Stream,
|
||||
IN LPWSTR szStr);
|
||||
|
||||
INT
|
||||
ConPrintfV(
|
||||
IN PCON_STREAM Stream,
|
||||
IN LPWSTR szStr,
|
||||
IN va_list args); // arg_ptr
|
||||
|
||||
INT
|
||||
__cdecl
|
||||
ConPrintf(
|
||||
IN PCON_STREAM Stream,
|
||||
IN LPWSTR szStr,
|
||||
...);
|
||||
|
||||
INT
|
||||
ConResPutsEx(
|
||||
IN PCON_STREAM Stream,
|
||||
IN HINSTANCE hInstance OPTIONAL,
|
||||
IN UINT uID);
|
||||
|
||||
INT
|
||||
ConResPuts(
|
||||
IN PCON_STREAM Stream,
|
||||
IN UINT uID);
|
||||
|
||||
INT
|
||||
ConResPrintfExV(
|
||||
IN PCON_STREAM Stream,
|
||||
IN HINSTANCE hInstance OPTIONAL,
|
||||
IN UINT uID,
|
||||
IN va_list args); // arg_ptr
|
||||
|
||||
INT
|
||||
ConResPrintfV(
|
||||
IN PCON_STREAM Stream,
|
||||
IN UINT uID,
|
||||
IN va_list args); // arg_ptr
|
||||
|
||||
INT
|
||||
__cdecl
|
||||
ConResPrintfEx(
|
||||
IN PCON_STREAM Stream,
|
||||
IN HINSTANCE hInstance OPTIONAL,
|
||||
IN UINT uID,
|
||||
...);
|
||||
|
||||
INT
|
||||
__cdecl
|
||||
ConResPrintf(
|
||||
IN PCON_STREAM Stream,
|
||||
IN UINT uID,
|
||||
...);
|
||||
|
||||
INT
|
||||
ConMsgPuts(
|
||||
IN PCON_STREAM Stream,
|
||||
IN DWORD dwFlags,
|
||||
IN LPCVOID lpSource OPTIONAL,
|
||||
IN DWORD dwMessageId,
|
||||
IN DWORD dwLanguageId);
|
||||
|
||||
INT
|
||||
ConMsgPrintf2V(
|
||||
IN PCON_STREAM Stream,
|
||||
IN DWORD dwFlags,
|
||||
IN LPCVOID lpSource OPTIONAL,
|
||||
IN DWORD dwMessageId,
|
||||
IN DWORD dwLanguageId,
|
||||
IN va_list args); // arg_ptr
|
||||
|
||||
INT
|
||||
ConMsgPrintfV(
|
||||
IN PCON_STREAM Stream,
|
||||
IN DWORD dwFlags,
|
||||
IN LPCVOID lpSource OPTIONAL,
|
||||
IN DWORD dwMessageId,
|
||||
IN DWORD dwLanguageId,
|
||||
IN va_list args); // arg_ptr
|
||||
|
||||
INT
|
||||
__cdecl
|
||||
ConMsgPrintf(
|
||||
IN PCON_STREAM Stream,
|
||||
IN DWORD dwFlags,
|
||||
IN LPCVOID lpSource OPTIONAL,
|
||||
IN DWORD dwMessageId,
|
||||
IN DWORD dwLanguageId,
|
||||
...);
|
||||
|
||||
|
||||
|
||||
VOID
|
||||
ConClearLine(IN PCON_STREAM Stream);
|
||||
|
||||
|
||||
#endif /* __STREAM_H__ */
|
234
sdk/lib/conutils/utils.c
Normal file
234
sdk/lib/conutils/utils.c
Normal file
|
@ -0,0 +1,234 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Console Utilities Library
|
||||
* FILE: sdk/lib/conutils/utils.c
|
||||
* PURPOSE: Base set of functions for loading string resources
|
||||
* and message strings, and handle type identification.
|
||||
* PROGRAMMERS: - Hermes Belusca-Maito (for the library);
|
||||
* - All programmers who wrote the different console applications
|
||||
* from which I took those functions and improved them.
|
||||
*/
|
||||
|
||||
/* FIXME: Temporary HACK before we cleanly support UNICODE functions */
|
||||
#define UNICODE
|
||||
#define _UNICODE
|
||||
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <winnls.h>
|
||||
#include <winuser.h> // MAKEINTRESOURCEW, RT_STRING
|
||||
#include <wincon.h> // Console APIs (only if kernel32 support included)
|
||||
#include <strsafe.h>
|
||||
|
||||
/* PSEH for SEH Support */
|
||||
#include <pseh/pseh2.h>
|
||||
|
||||
// #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 .
|
||||
// See https://github.com/pcman-bbs/pcman-windows/blob/master/Lite/StrUtils.h#l33
|
||||
// and http://www.openfoundry.org/svn/pcman/branches/OpenPCMan_2009/Lite/StrUtils.cpp
|
||||
// for the idea.
|
||||
int
|
||||
MultiByteToMultiByte(
|
||||
// IN WORD wTranslations,
|
||||
IN DWORD dwFlags,
|
||||
IN UINT SrcCodePage,
|
||||
IN LPCSTR lpSrcString,
|
||||
IN int cbSrcChar,
|
||||
IN UINT DestCodePage,
|
||||
OUT LPSTR wDestString OPTIONAL,
|
||||
IN int cbDestChar
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 'LoadStringW' API ripped from user32.dll to remove
|
||||
* any dependency of this library from user32.dll
|
||||
*/
|
||||
INT
|
||||
WINAPI
|
||||
K32LoadStringW(
|
||||
IN HINSTANCE hInstance OPTIONAL,
|
||||
IN UINT uID,
|
||||
OUT LPWSTR lpBuffer,
|
||||
IN INT nBufferMax)
|
||||
{
|
||||
HRSRC hrsrc;
|
||||
HGLOBAL hmem;
|
||||
WCHAR *p;
|
||||
UINT i;
|
||||
|
||||
if (!lpBuffer)
|
||||
return 0;
|
||||
|
||||
/* 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);
|
||||
if (!hrsrc) return 0;
|
||||
|
||||
hmem = LoadResource(hInstance, hrsrc);
|
||||
if (!hmem) return 0;
|
||||
|
||||
p = LockResource(hmem);
|
||||
// FreeResource(hmem);
|
||||
|
||||
/* Find the string we're looking for */
|
||||
uID &= 0x000F; /* Position in the block, same as % 16 */
|
||||
for (i = 0; i < uID; i++)
|
||||
p += *p + 1;
|
||||
|
||||
/*
|
||||
* If nBufferMax == 0, then return a read-only pointer
|
||||
* to the resource itself in lpBuffer it is assumed that
|
||||
* lpBuffer is actually a (LPWSTR *).
|
||||
*/
|
||||
if (nBufferMax == 0)
|
||||
{
|
||||
*((LPWSTR*)lpBuffer) = p + 1;
|
||||
return *p;
|
||||
}
|
||||
|
||||
i = min(nBufferMax - 1, *p);
|
||||
if (i > 0)
|
||||
{
|
||||
memcpy(lpBuffer, p + 1, i * sizeof(WCHAR));
|
||||
lpBuffer[i] = L'\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nBufferMax > 1)
|
||||
{
|
||||
lpBuffer[0] = L'\0';
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* "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.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
DWORD dwLength = 0;
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
/*
|
||||
* Retrieve the message string. Wrap in SEH
|
||||
* to protect from invalid string parameters.
|
||||
*/
|
||||
_SEH2_TRY
|
||||
{
|
||||
dwLength = FormatMessageW(dwFlags,
|
||||
lpSource,
|
||||
dwMessageId,
|
||||
dwLanguageId,
|
||||
lpBuffer,
|
||||
nSize,
|
||||
Arguments);
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
dwLength = 0;
|
||||
|
||||
/*
|
||||
* An exception occurred while calling FormatMessage, this is usually
|
||||
* the sign that a parameter was invalid, either 'lpBuffer' was NULL
|
||||
* but we did not pass the flag FORMAT_MESSAGE_ALLOCATE_BUFFER, or the
|
||||
* array pointer 'Arguments' was NULL or did not contain enough elements,
|
||||
* and we did not pass the flag FORMAT_MESSAGE_IGNORE_INSERTS, and the
|
||||
* message string expected too many inserts.
|
||||
* In this last case only, we can call again FormatMessage but ignore
|
||||
* explicitely the inserts. The string that we will return to the user
|
||||
* will not be pre-formatted.
|
||||
*/
|
||||
if (((dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) || lpBuffer) &&
|
||||
!(dwFlags & FORMAT_MESSAGE_IGNORE_INSERTS))
|
||||
{
|
||||
/* Remove any possible harmful flags and always ignore inserts */
|
||||
dwFlags &= ~FORMAT_MESSAGE_ARGUMENT_ARRAY;
|
||||
dwFlags |= FORMAT_MESSAGE_IGNORE_INSERTS;
|
||||
|
||||
/* If this call also throws an exception, we are really dead */
|
||||
dwLength = FormatMessageW(dwFlags,
|
||||
lpSource,
|
||||
dwMessageId,
|
||||
dwLanguageId,
|
||||
lpBuffer,
|
||||
nSize,
|
||||
NULL /* Arguments */);
|
||||
}
|
||||
}
|
||||
_SEH2_END;
|
||||
}
|
||||
_SEH2_FINALLY
|
||||
{
|
||||
}
|
||||
_SEH2_END;
|
||||
|
||||
return dwLength;
|
||||
}
|
||||
|
||||
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
|
||||
* the handle is really handled by the console subsystem.
|
||||
*/
|
||||
return ((GetFileType(hHandle) & ~FILE_TYPE_REMOTE) == FILE_TYPE_CHAR);
|
||||
}
|
||||
|
||||
BOOL
|
||||
IsConsoleHandle(IN HANDLE hHandle)
|
||||
{
|
||||
DWORD dwMode;
|
||||
|
||||
/* Check whether the handle may be that of a console... */
|
||||
if ((GetFileType(hHandle) & ~FILE_TYPE_REMOTE) != FILE_TYPE_CHAR)
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* It may be. Perform another test. The idea comes from the
|
||||
* MSDN description of the WriteConsole API:
|
||||
*
|
||||
* "WriteConsole fails if it is used with a standard handle
|
||||
* that is redirected to a file. If an application processes
|
||||
* multilingual output that can be redirected, determine whether
|
||||
* the output handle is a console handle (one method is to call
|
||||
* the GetConsoleMode function and check whether it succeeds).
|
||||
* If the handle is a console handle, call WriteConsole. If the
|
||||
* handle is not a console handle, the output is redirected and
|
||||
* you should call WriteFile to perform the I/O."
|
||||
*/
|
||||
return GetConsoleMode(hHandle, &dwMode);
|
||||
}
|
53
sdk/lib/conutils/utils.h
Normal file
53
sdk/lib/conutils/utils.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Console Utilities Library
|
||||
* FILE: sdk/lib/conutils/utils.h
|
||||
* PURPOSE: Base set of functions for loading string resources
|
||||
* and message strings, and handle type identification.
|
||||
* PROGRAMMERS: - Hermes Belusca-Maito (for the library);
|
||||
* - All programmers who wrote the different console applications
|
||||
* from which I took those functions and improved them.
|
||||
*/
|
||||
|
||||
#ifndef __UTILS_H__
|
||||
#define __UTILS_H__
|
||||
|
||||
#ifndef _UNICODE
|
||||
#error The ConUtils library at the moment only supports compilation with _UNICODE defined!
|
||||
#endif
|
||||
|
||||
/*
|
||||
* General-purpose utility functions (wrappers around,
|
||||
* or reimplementations of, Win32 APIs).
|
||||
*/
|
||||
|
||||
INT
|
||||
WINAPI
|
||||
K32LoadStringW(
|
||||
IN HINSTANCE hInstance OPTIONAL,
|
||||
IN UINT uID,
|
||||
OUT LPWSTR lpBuffer,
|
||||
IN INT nBufferMax);
|
||||
|
||||
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);
|
||||
|
||||
BOOL
|
||||
IsTTYHandle(IN HANDLE hHandle);
|
||||
|
||||
BOOL
|
||||
IsConsoleHandle(IN HANDLE hHandle);
|
||||
|
||||
|
||||
// #include <wincon.h>
|
||||
|
||||
|
||||
#endif /* __UTILS_H__ */
|
Loading…
Add table
Add a link
Reference in a new issue