Author: hbelusca Date: Sun Oct 1 16:30:39 2017 New Revision: 76023 URL: http://svn.reactos.org/svn/reactos?rev=76023&view=rev Log: [CMD]: Use the CONUTILS library (Part 1/x) for an uniform and consistent experience across command-line tools. - Make most of CMD use the conutils library. This means that now we explicitely use the CON_STREAM objects. In particular code handling STDIN/OUT/ERR redirection should be handled with care. - Factor out much of console-related support code into console.c. Code for console input is however not "CON_STREAM-enabled" yet. - Change ConOutPrintfPaging prototype to make it return TRUE/FALSE when it can continue paged-printing or not, respectively. CORE-13860
Modified: trunk/reactos/base/shell/cmd/CMakeLists.txt trunk/reactos/base/shell/cmd/beep.c trunk/reactos/base/shell/cmd/cls.c trunk/reactos/base/shell/cmd/cmd.c trunk/reactos/base/shell/cmd/cmd.h trunk/reactos/base/shell/cmd/color.c trunk/reactos/base/shell/cmd/console.c trunk/reactos/base/shell/cmd/console.h trunk/reactos/base/shell/cmd/dir.c trunk/reactos/base/shell/cmd/history.c trunk/reactos/base/shell/cmd/misc.c trunk/reactos/base/shell/cmd/precomp.h trunk/reactos/base/shell/cmd/redir.c trunk/reactos/base/shell/cmd/start.c Modified: trunk/reactos/base/shell/cmd/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/CMakeLists.txt?rev=76023&r1=76022&r2=76023&view=diff ============================================================================== --- trunk/reactos/base/shell/cmd/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/CMakeLists.txt [iso-8859-1] Sun Oct 1 16:30:39 2017 @@ -4,6 +4,7 @@ -D_DEBUG_MEM) include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) +include_directories(${REACTOS_SOURCE_DIR}/sdk/lib/conutils) list(APPEND SOURCE alias.c @@ -68,8 +69,9 @@ add_rc_deps(cmd.rc ${CMAKE_CURRENT_SOURCE_DIR}/res/terminal.ico) add_executable(cmd ${SOURCE} cmd.rc) +add_pch(cmd precomp.h SOURCE) +set_module_type(cmd win32cui UNICODE) target_link_libraries(cmd wine) -set_module_type(cmd win32cui UNICODE) +target_link_libraries(cmd conutils ${PSEH_LIB}) add_importlibs(cmd advapi32 user32 msvcrt kernel32 ntdll) -add_pch(cmd precomp.h SOURCE) add_cd_file(TARGET cmd DESTINATION reactos/system32 FOR all) Modified: trunk/reactos/base/shell/cmd/beep.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/beep.c?rev=76023&r1=76022&r2=76023&view=diff ============================================================================== --- trunk/reactos/base/shell/cmd/beep.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/beep.c [iso-8859-1] Sun Oct 1 16:30:39 2017 @@ -42,7 +42,7 @@ return 1; #endif - ConRingBell(GetStdHandle(STD_OUTPUT_HANDLE)); + ConRingBell(ConStreamGetOSHandle(StdOut)); return 0; } Modified: trunk/reactos/base/shell/cmd/cls.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/cls.c?rev=76023&r1=76022&r2=76023&view=diff ============================================================================== --- trunk/reactos/base/shell/cmd/cls.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/cls.c [iso-8859-1] Sun Oct 1 16:30:39 2017 @@ -38,7 +38,7 @@ return 0; } - ConClearScreen(GetStdHandle(STD_OUTPUT_HANDLE)); + ConClearScreen(&StdOutScreen); return 0; } Modified: trunk/reactos/base/shell/cmd/cmd.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/cmd.c?rev=76023&r1=76022&r2=76023&view=diff ============================================================================== --- trunk/reactos/base/shell/cmd/cmd.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/cmd.c [iso-8859-1] Sun Oct 1 16:30:39 2017 @@ -156,18 +156,22 @@ static BOOL bWaitForCommand = FALSE; /* When we are executing something passed on the commandline after /c or /k */ INT nErrorLevel = 0; /* Errorlevel of last launched external program */ CRITICAL_SECTION ChildProcessRunningLock; -BOOL bUnicodeOutput = FALSE; BOOL bDisableBatchEcho = FALSE; BOOL bEnableExtensions = TRUE; BOOL bDelayedExpansion = FALSE; BOOL bTitleSet = FALSE; DWORD dwChildProcessId = 0; -HANDLE hIn; LPTSTR lpOriginalEnvironment; HANDLE CMD_ModuleHandle; static NtQueryInformationProcessProc NtQueryInformationProcessPtr = NULL; static NtReadVirtualMemoryProc NtReadVirtualMemoryPtr = NULL; + +/* + * Default output file stream translation mode is UTF8, but CMD switches + * allow to change it to either UTF16 (/U) or ANSI (/A). + */ +CON_STREAM_MODE OutputStreamMode = UTF8Text; // AnsiText; #ifdef INCLUDE_CMD_COLOR WORD wDefColor = 0; /* Default color */ @@ -417,7 +421,7 @@ stui.wShowWindow = SW_SHOWDEFAULT; /* Set the console to standard mode */ - SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), + SetConsoleMode(ConStreamGetOSHandle(StdIn), ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT); if (CreateProcess(szFullName, @@ -468,15 +472,32 @@ } /* Restore our default console mode */ - SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), + SetConsoleMode(ConStreamGetOSHandle(StdIn), ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT); - SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), + SetConsoleMode(ConStreamGetOSHandle(StdOut), ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT); } - /* Get code page if it has been changed */ - InputCodePage= GetConsoleCP(); - OutputCodePage = GetConsoleOutputCP(); + /* Update our local codepage cache */ + { + UINT uNewInputCodePage = GetConsoleCP(); + UINT uNewOutputCodePage = GetConsoleOutputCP(); + + if ((InputCodePage != uNewInputCodePage) || + (OutputCodePage != uNewOutputCodePage)) + { + /* Update the locale as well */ + InitLocale(); + } + + InputCodePage = uNewInputCodePage; + OutputCodePage = uNewOutputCodePage; + + /* Update the streams codepage cache as well */ + ConStreamSetCacheCodePage(StdIn , InputCodePage ); + ConStreamSetCacheCodePage(StdOut, OutputCodePage); + ConStreamSetCacheCodePage(StdErr, OutputCodePage); + } /* Restore the original console title */ if (!bTitleSet) @@ -1472,7 +1493,7 @@ rec.Event.KeyEvent.uChar.UnicodeChar = _T('C'); rec.Event.KeyEvent.dwControlKeyState = RIGHT_CTRL_PRESSED; - WriteConsoleInput(hIn, + WriteConsoleInput(ConStreamGetOSHandle(StdIn), &rec, 1, &dwWritten); @@ -1779,7 +1800,7 @@ TCHAR ModuleName[_MAX_PATH + 1]; INT nExitCode; - HANDLE hOut; + HANDLE hIn, hOut; TCHAR *ptr, *cmdLine, option = 0; BOOL AlwaysStrip = FALSE; @@ -1805,10 +1826,6 @@ /* Initialize our locale */ InitLocale(); - /* Get default input and output console handles */ - hOut = GetStdHandle(STD_OUTPUT_HANDLE); - hIn = GetStdHandle(STD_INPUT_HANDLE); - /* Initialize prompt support */ InitPrompt(); @@ -1833,6 +1850,8 @@ AddBreakHandler(); /* Set our default console mode */ + hOut = ConStreamGetOSHandle(StdOut); + hIn = ConStreamGetOSHandle(StdIn); SetConsoleMode(hOut, 0); // Reinitialize the console output mode SetConsoleMode(hOut, ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT); SetConsoleMode(hIn , ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT); @@ -1871,7 +1890,7 @@ } else if (option == _T('A')) { - bUnicodeOutput = FALSE; + OutputStreamMode = AnsiText; } else if (option == _T('C') || option == _T('K') || option == _T('R')) { @@ -1899,7 +1918,7 @@ #endif else if (option == _T('U')) { - bUnicodeOutput = TRUE; + OutputStreamMode = UTF16Text; } else if (option == _T('V')) { @@ -1935,8 +1954,13 @@ } if (wDefColor != 0) - ConSetScreenColor(GetStdHandle(STD_OUTPUT_HANDLE), wDefColor, TRUE); + ConSetScreenColor(ConStreamGetOSHandle(StdOut), wDefColor, TRUE); #endif + + /* Reset the output Standard Streams translation modes and codepage caches */ + // ConStreamSetMode(StdIn , OutputStreamMode, InputCodePage ); + ConStreamSetMode(StdOut, OutputStreamMode, OutputCodePage); + ConStreamSetMode(StdErr, OutputStreamMode, OutputCodePage); if (!*ptr) { @@ -2000,9 +2024,9 @@ RemoveBreakHandler(); /* Restore the default console mode */ - SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), + SetConsoleMode(ConStreamGetOSHandle(StdIn), ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT); - SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), + SetConsoleMode(ConStreamGetOSHandle(StdOut), ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT); DeleteCriticalSection(&ChildProcessRunningLock); @@ -2022,8 +2046,13 @@ _tchdir(startPath); SetFileApisToOEM(); - InputCodePage = GetConsoleCP(); + InputCodePage = GetConsoleCP(); OutputCodePage = GetConsoleOutputCP(); + + /* Initialize the Console Standard Streams */ + ConStreamInit(StdIn , GetStdHandle(STD_INPUT_HANDLE) , /*OutputStreamMode*/ AnsiText, InputCodePage); + ConStreamInit(StdOut, GetStdHandle(STD_OUTPUT_HANDLE), OutputStreamMode, OutputCodePage); + ConStreamInit(StdErr, GetStdHandle(STD_ERROR_HANDLE) , OutputStreamMode, OutputCodePage); CMD_ModuleHandle = GetModuleHandle(NULL); Modified: trunk/reactos/base/shell/cmd/cmd.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/cmd.h?rev=76023&r1=76022&r2=76023&view=diff ============================================================================== --- trunk/reactos/base/shell/cmd/cmd.h [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/cmd.h [iso-8859-1] Sun Oct 1 16:30:39 2017 @@ -54,7 +54,6 @@ extern BOOL bEnableExtensions; extern BOOL bDelayedExpansion; extern INT nErrorLevel; -extern BOOL bUnicodeOutput; /* Prototypes for ALIAS.C */ @@ -282,7 +281,7 @@ #define PROMPT_ALL 2 #define PROMPT_BREAK 3 -INT PagePrompt (VOID); +BOOL __stdcall PagePrompt(PCON_PAGER Pager, DWORD Done, DWORD Total); INT FilePromptYN (UINT); INT FilePromptYNA (UINT); Modified: trunk/reactos/base/shell/cmd/color.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/color.c?rev=76023&r1=76022&r2=76023&view=diff ============================================================================== --- trunk/reactos/base/shell/cmd/color.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/color.c [iso-8859-1] Sun Oct 1 16:30:39 2017 @@ -46,7 +46,7 @@ /* No parameter: Set the default colors */ if (rest[0] == _T('\0')) { - ConSetScreenColor(GetStdHandle(STD_OUTPUT_HANDLE), wDefColor, TRUE); + ConSetScreenColor(ConStreamGetOSHandle(StdOut), wDefColor, TRUE); return 0; } @@ -87,7 +87,7 @@ * Set the chosen color. Use also the following advanced flag: * /-F to avoid changing already buffered foreground/background. */ - if (ConSetScreenColor(GetStdHandle(STD_OUTPUT_HANDLE), wColor, + if (ConSetScreenColor(ConStreamGetOSHandle(StdOut), wColor, !_tcsstr(rest, _T("/-F")) && !_tcsstr(rest, _T("/-f"))) == FALSE) { /* Failed because foreground and background colors were the same */ Modified: trunk/reactos/base/shell/cmd/console.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/console.c?rev=76023&r1=76022&r2=76023&view=diff ============================================================================== --- trunk/reactos/base/shell/cmd/console.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/console.c [iso-8859-1] Sun Oct 1 16:30:39 2017 @@ -25,30 +25,9 @@ UINT InputCodePage; UINT OutputCodePage; - -BOOL IsConsoleHandle(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); -} +/* Global console Screen and Pager */ +CON_SCREEN StdOutScreen = INIT_CON_SCREEN(StdOut); +CON_PAGER StdOutPager = INIT_CON_PAGER(&StdOutScreen); @@ -90,9 +69,11 @@ do { ReadConsoleInput(hInput, lpBuffer, 1, &dwRead); - if ((lpBuffer->EventType == KEY_EVENT) && - (lpBuffer->Event.KeyEvent.bKeyDown != FALSE)) + if (lpBuffer->EventType == KEY_EVENT && + lpBuffer->Event.KeyEvent.bKeyDown) + { break; + } } while (TRUE); } @@ -139,306 +120,68 @@ /******************** Console STREAM OUT utility functions ********************/ -static VOID ConWrite(DWORD nStdHandle, TCHAR *str, DWORD len) -{ - DWORD dwNumBytes = 0; - HANDLE hOutput = GetStdHandle(nStdHandle); - PVOID p; - - /* If we don't write anything, just return */ - if (!str || len == 0) - return; - - /* Check whether we are writing to a console and if so, write to it */ - if (IsConsoleHandle(hOutput)) - { - WriteConsole(hOutput, str, len, &dwNumBytes, NULL); - return; - } - - /* We're writing to a file or pipe instead of the console. Convert the - * string from TCHARs to the desired output format, if the two differ */ - if (bUnicodeOutput) - { -#ifndef _UNICODE - WCHAR *buffer = cmd_alloc(len * sizeof(WCHAR)); - if (!buffer) - { - error_out_of_memory(); - return; - } - len = (DWORD)MultiByteToWideChar(OutputCodePage, 0, str, (INT)len, buffer, (INT)len); - str = (PVOID)buffer; -#endif - /* - * Find any newline character in the buffer, - * write the part BEFORE the newline, then write - * a carriage-return + newline, and then write - * the remaining part of the buffer. - * - * This fixes output in files and serial console. - */ - while (len > 0) - { - /* Loop until we find a \r or \n character */ - // FIXME: What about the pair \r\n ? - p = str; - while (len > 0 && *(PWCHAR)p != L'\r' && *(PWCHAR)p != L'\n') - { - /* Advance one character */ - p = (PVOID)((PWCHAR)p + 1); - len--; - } - - /* Write everything up to \r or \n */ - dwNumBytes = ((PWCHAR)p - (PWCHAR)str) * sizeof(WCHAR); - WriteFile(hOutput, str, dwNumBytes, &dwNumBytes, NULL); - - /* If we hit \r or \n ... */ - if (len > 0 && (*(PWCHAR)p == L'\r' || *(PWCHAR)p == L'\n')) - { - /* ... send a carriage-return + newline sequence and skip \r or \n */ - WriteFile(hOutput, L"\r\n", 2 * sizeof(WCHAR), &dwNumBytes, NULL); - str = (PVOID)((PWCHAR)p + 1); - len--; - } - } - -#ifndef _UNICODE - cmd_free(buffer); -#endif - } - else - { -#ifdef _UNICODE - CHAR *buffer = cmd_alloc(len * MB_LEN_MAX * sizeof(CHAR)); - if (!buffer) - { - error_out_of_memory(); - return; - } - len = WideCharToMultiByte(OutputCodePage, 0, str, len, buffer, len * MB_LEN_MAX, NULL, NULL); - str = (PVOID)buffer; -#endif - /* - * Find any newline character in the buffer, - * write the part BEFORE the newline, then write - * a carriage-return + newline, and then write - * the remaining part of the buffer. - * - * This fixes output in files and serial console. - */ - while (len > 0) - { - /* Loop until we find a \r or \n character */ - // FIXME: What about the pair \r\n ? - p = str; - while (len > 0 && *(PCHAR)p != '\r' && *(PCHAR)p != '\n') - { - /* Advance one character */ - p = (PVOID)((PCHAR)p + 1); - len--; - } - - /* Write everything up to \r or \n */ - dwNumBytes = ((PCHAR)p - (PCHAR)str) * sizeof(CHAR); - WriteFile(hOutput, str, dwNumBytes, &dwNumBytes, NULL); - - /* If we hit \r or \n ... */ - if (len > 0 && (*(PCHAR)p == '\r' || *(PCHAR)p == '\n')) - { - /* ... send a carriage-return + newline sequence and skip \r or \n */ - WriteFile(hOutput, "\r\n", 2, &dwNumBytes, NULL); - str = (PVOID)((PCHAR)p + 1); - len--; - } - } - -#ifdef _UNICODE - cmd_free(buffer); -#endif - } -} - -VOID ConPuts(DWORD nStdHandle, LPTSTR szText) -{ - ConWrite(nStdHandle, szText, (DWORD)_tcslen(szText)); -} - -VOID ConResPuts(DWORD nStdHandle, UINT resID) -{ - TCHAR szMsg[RC_STRING_MAX_SIZE]; - LoadString(CMD_ModuleHandle, resID, szMsg, ARRAYSIZE(szMsg)); - ConPuts(nStdHandle, szMsg); -} - VOID ConOutChar(TCHAR c) { - ConWrite(STD_OUTPUT_HANDLE, &c, 1); + ConWrite(StdOut, &c, 1); } VOID ConErrChar(TCHAR c) { - ConWrite(STD_ERROR_HANDLE, &c, 1); -} - -VOID ConPrintfV(DWORD nStdHandle, LPTSTR szFormat, va_list arg_ptr) -{ - TCHAR szOut[OUTPUT_BUFFER_SIZE]; - DWORD len; - - len = (DWORD)_vstprintf(szOut, szFormat, arg_ptr); - ConWrite(nStdHandle, szOut, len); -} - -VOID ConPrintf(DWORD nStdHandle, LPTSTR szFormat, ...) -{ + ConWrite(StdErr, &c, 1); +} + +VOID __cdecl ConFormatMessage(PCON_STREAM Stream, DWORD MessageId, ...) +{ + INT Len; va_list arg_ptr; - va_start(arg_ptr, szFormat); - ConPrintfV(nStdHandle, szFormat, arg_ptr); - va_end(arg_ptr); -} - -VOID ConResPrintf(DWORD nStdHandle, UINT resID, ...) -{ - TCHAR szMsg[RC_STRING_MAX_SIZE]; - va_list arg_ptr; - - va_start(arg_ptr, resID); - LoadString(CMD_ModuleHandle, resID, szMsg, ARRAYSIZE(szMsg)); - ConPrintfV(nStdHandle, szMsg, arg_ptr); - va_end(arg_ptr); -} - -VOID ConFormatMessage(DWORD nStdHandle, DWORD MessageId, ...) -{ - DWORD ret; - LPTSTR text; - va_list arg_ptr; - va_start(arg_ptr, MessageId); - ret = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + Len = ConMsgPrintfV(Stream, + FORMAT_MESSAGE_FROM_SYSTEM, NULL, MessageId, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR)&text, - 0, - &arg_ptr); + LANG_USER_DEFAULT, + arg_ptr); va_end(arg_ptr); - if (ret > 0) - { - ConPuts(nStdHandle, text); - LocalFree(text); - } - else - { - ConResPrintf(nStdHandle, STRING_CONSOLE_ERROR, MessageId); - } + if (Len <= 0) + ConResPrintf(Stream, STRING_CONSOLE_ERROR, MessageId); } /************************** Console PAGER functions ***************************/ -BOOL ConPrintfVPaging(DWORD nStdHandle, BOOL NewPage, LPTSTR szFormat, va_list arg_ptr) -{ - INT len; - CONSOLE_SCREEN_BUFFER_INFO csbi; +BOOL ConPrintfVPaging(PCON_PAGER Pager, BOOL StartPaging, LPTSTR szFormat, va_list arg_ptr) +{ + // INT len; TCHAR szOut[OUTPUT_BUFFER_SIZE]; - DWORD dwWritten; - HANDLE hOutput = GetStdHandle(nStdHandle); - - /* Used to count number of lines since last pause */ - static int LineCount = 0; - - /* Used to see how big the screen is */ - int ScreenLines = 0; - - /* Chars since start of line */ - int CharSL; - - int from = 0, i = 0; - - if (NewPage != FALSE) - LineCount = 0; - - /* Reset LineCount and return if no string has been given */ + + /* Return if no string has been given */ if (szFormat == NULL) return TRUE; - /* Get the size of the visual screen that can be printed to */ - if (!IsConsoleHandle(hOutput) || !GetConsoleScreenBufferInfo(hOutput, &csbi)) - { - /* We assume it's a file handle */ - ConPrintfV(nStdHandle, szFormat, arg_ptr); - 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) - { - ConPrintfV(nStdHandle, szFormat, arg_ptr); - return TRUE; - } - - len = _vstprintf(szOut, szFormat, arg_ptr); - - while (i < len) - { - /* Search until the end of a line is reached */ - if (szOut[i++] != _T('\n') && ++CharSL < csbi.dwSize.X) - continue; - - LineCount++; - CharSL=0; - - if (LineCount >= ScreenLines) - { - WriteConsole(hOutput, &szOut[from], i-from, &dwWritten, NULL); - from = i; - - /* Prompt the user */ - if (PagePrompt() != PROMPT_YES) - return FALSE; - - // TODO: Recalculate 'ScreenLines' in case the user redimensions - // the window during the prompt. - - /* Reset the number of lines being printed */ - LineCount = 0; - } - } - - WriteConsole(hOutput, &szOut[from], i-from, &dwWritten, NULL); - - return TRUE; -} - -BOOL ConOutPrintfPaging(BOOL NewPage, LPTSTR szFormat, ...) + /*len =*/ _vstprintf(szOut, szFormat, arg_ptr); + + // return ConPutsPaging(Pager, PagePrompt, StartPaging, szOut); + return ConWritePaging(Pager, PagePrompt, StartPaging, + szOut, wcslen(szOut)); +} + +BOOL __cdecl ConOutPrintfPaging(BOOL StartPaging, LPTSTR szFormat, ...) { BOOL bRet; va_list arg_ptr; va_start(arg_ptr, szFormat); - bRet = ConPrintfVPaging(STD_OUTPUT_HANDLE, NewPage, szFormat, arg_ptr); + bRet = ConPrintfVPaging(&StdOutPager, StartPaging, szFormat, arg_ptr); va_end(arg_ptr); return bRet; } -VOID ConOutResPaging(BOOL NewPage, UINT resID) -{ - TCHAR szMsg[RC_STRING_MAX_SIZE]; - LoadString(CMD_ModuleHandle, resID, szMsg, ARRAYSIZE(szMsg)); - ConOutPrintfPaging(NewPage, szMsg); +VOID ConOutResPaging(BOOL StartPaging, UINT resID) +{ + ConResPaging(&StdOutPager, PagePrompt, StartPaging, resID); } @@ -451,7 +194,7 @@ coPos.X = x; coPos.Y = y; - SetConsoleCursorPosition(GetStdHandle (STD_OUTPUT_HANDLE), coPos); + SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coPos); } VOID GetCursorXY(PSHORT x, PSHORT y) @@ -487,7 +230,7 @@ cci.dwSize = bInsert ? 10 : 99; cci.bVisible = bVisible; - SetConsoleCursorInfo(GetStdHandle (STD_OUTPUT_HANDLE), &cci); + SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci); } VOID GetScreenSize(PSHORT maxx, PSHORT maxy) @@ -552,32 +295,6 @@ else #endif MessageBeep(-1); -} -#endif - -#ifdef INCLUDE_CMD_CLS -VOID ConClearScreen(HANDLE hOutput) -{ - CONSOLE_SCREEN_BUFFER_INFO csbi; - COORD coPos; - DWORD dwWritten; - - if (GetConsoleScreenBufferInfo(hOutput, &csbi)) - { - coPos.X = 0; - coPos.Y = 0; - FillConsoleOutputAttribute(hOutput, csbi.wAttributes, - csbi.dwSize.X * csbi.dwSize.Y, - coPos, &dwWritten); - FillConsoleOutputCharacter(hOutput, _T(' '), - csbi.dwSize.X * csbi.dwSize.Y, - coPos, &dwWritten); - SetConsoleCursorPosition(hOutput, coPos); - } - else - { - ConOutChar(_T('\f')); - } } #endif Modified: trunk/reactos/base/shell/cmd/console.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/console.h?rev=76023&r1=76022&r2=76023&view=diff ============================================================================== --- trunk/reactos/base/shell/cmd/console.h [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/console.h [iso-8859-1] Sun Oct 1 16:30:39 2017 @@ -1,9 +1,13 @@ #pragma once -/* Cache codepage */ +/* Cache codepage for text streams */ extern UINT InputCodePage; extern UINT OutputCodePage; + +/* Global console Screen and Pager */ +extern CON_SCREEN StdOutScreen; +extern CON_PAGER StdOutPager; // /* Global variables */ // extern BOOL bCtrlBreak; @@ -18,50 +22,45 @@ VOID ConInString (LPTSTR, DWORD); -VOID ConOutChar (TCHAR); -VOID ConErrChar (TCHAR); -VOID ConPrintfV(DWORD, LPTSTR, va_list); +VOID ConOutChar(TCHAR); +VOID ConErrChar(TCHAR); -VOID ConPuts(DWORD nStdHandle, LPTSTR szText); -VOID ConPrintf(DWORD nStdHandle, LPTSTR szFormat, ...); -VOID ConResPuts(DWORD nStdHandle, UINT resID); -VOID ConResPrintf(DWORD nStdHandle, UINT resID, ...); -VOID ConFormatMessage(DWORD nStdHandle, DWORD MessageId, ...); +VOID __cdecl ConFormatMessage(PCON_STREAM Stream, DWORD MessageId, ...); #define ConOutPuts(szStr) \ - ConPuts(STD_OUTPUT_HANDLE, (szStr)) + ConPuts(StdOut, (szStr)) #define ConErrPuts(szStr) \ - ConPuts(STD_ERROR_HANDLE, (szStr)) + ConPuts(StdErr, (szStr)) #define ConOutResPuts(uID) \ - ConResPuts(STD_OUTPUT_HANDLE, (uID)) + ConResPuts(StdOut, (uID)) #define ConErrResPuts(uID) \ - ConResPuts(STD_ERROR_HANDLE, (uID)) + ConResPuts(StdErr, (uID)) #define ConOutPrintf(szStr, ...) \ - ConPrintf(STD_OUTPUT_HANDLE, (szStr), ##__VA_ARGS__) + ConPrintf(StdOut, (szStr), ##__VA_ARGS__) #define ConErrPrintf(szStr, ...) \ - ConPrintf(STD_ERROR_HANDLE, (szStr), ##__VA_ARGS__) + ConPrintf(StdErr, (szStr), ##__VA_ARGS__) #define ConOutResPrintf(uID, ...) \ - ConResPrintf(STD_OUTPUT_HANDLE, (uID), ##__VA_ARGS__) + ConResPrintf(StdOut, (uID), ##__VA_ARGS__) #define ConErrResPrintf(uID, ...) \ - ConResPrintf(STD_ERROR_HANDLE, (uID), ##__VA_ARGS__) + ConResPrintf(StdErr, (uID), ##__VA_ARGS__) #define ConOutFormatMessage(MessageId, ...) \ - ConFormatMessage(STD_OUTPUT_HANDLE, (MessageId), ##__VA_ARGS__) + ConFormatMessage(StdOut, (MessageId), ##__VA_ARGS__) #define ConErrFormatMessage(MessageId, ...) \ - ConFormatMessage(STD_ERROR_HANDLE, (MessageId), ##__VA_ARGS__) + ConFormatMessage(StdErr, (MessageId), ##__VA_ARGS__) -BOOL ConPrintfVPaging(DWORD nStdHandle, BOOL, LPTSTR, va_list); -BOOL ConOutPrintfPaging (BOOL NewPage, LPTSTR, ...); -VOID ConOutResPaging(BOOL NewPage, UINT resID); +BOOL ConPrintfVPaging(PCON_PAGER Pager, BOOL StartPaging, LPTSTR szFormat, va_list arg_ptr); +BOOL __cdecl ConOutPrintfPaging(BOOL StartPaging, LPTSTR szFormat, ...); +VOID ConOutResPaging(BOOL StartPaging, UINT resID); SHORT GetCursorX (VOID); SHORT GetCursorY (VOID); @@ -83,10 +82,6 @@ VOID ConRingBell(HANDLE hOutput); #endif -#ifdef INCLUDE_CMD_CLS -VOID ConClearScreen(HANDLE hOutput); -#endif - #ifdef INCLUDE_CMD_COLOR BOOL ConSetScreenColor(HANDLE hOutput, WORD wColor, BOOL bFill); #endif @@ -99,6 +94,5 @@ // #define PROMPT_ALL 2 // #define PROMPT_BREAK 3 -// INT PagePrompt (VOID); // INT FilePromptYN (UINT); // INT FilePromptYNA (UINT); Modified: trunk/reactos/base/shell/cmd/dir.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/dir.c?rev=76023&r1=76022&r2=76023&view=diff ============================================================================== --- trunk/reactos/base/shell/cmd/dir.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/dir.c [iso-8859-1] Sun Oct 1 16:30:39 2017 @@ -557,9 +557,9 @@ va_list arg_ptr; va_start(arg_ptr, szFormat); if (lpFlags->bPause) - Done = ConPrintfVPaging(STD_OUTPUT_HANDLE, FALSE, szFormat, arg_ptr); + Done = ConPrintfVPaging(&StdOutPager, FALSE, szFormat, arg_ptr); else - ConPrintfV(STD_OUTPUT_HANDLE, szFormat, arg_ptr); + ConPrintfV(StdOut, szFormat, arg_ptr); va_end(arg_ptr); return Done; } Modified: trunk/reactos/base/shell/cmd/history.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/history.c?rev=76023&r1=76022&r2=76023&view=diff ============================================================================== --- trunk/reactos/base/shell/cmd/history.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/history.c [iso-8859-1] Sun Oct 1 16:30:39 2017 @@ -87,8 +87,6 @@ break; case _T('R'):/*read history from standard in*/ - //hIn=GetStdHandle (STD_INPUT_HANDLE); - for(;;) { ConInString(szBuffer,sizeof(szBuffer)/sizeof(TCHAR)); Modified: trunk/reactos/base/shell/cmd/misc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/misc.c?rev=76023&r1=76022&r2=76023&view=diff ============================================================================== --- trunk/reactos/base/shell/cmd/misc.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/misc.c [iso-8859-1] Sun Oct 1 16:30:39 2017 @@ -534,7 +534,8 @@ return TRUE; } -INT PagePrompt(VOID) +// See r874 +BOOL __stdcall PagePrompt(PCON_PAGER Pager, DWORD Done, DWORD Total) { SHORT iScreenWidth, iCursorY; INPUT_RECORD ir; @@ -574,10 +575,10 @@ ConOutChar(_T('\n')); bCtrlBreak = TRUE; - return PROMPT_BREAK; - } - - return PROMPT_YES; + return FALSE; + } + + return TRUE; } Modified: trunk/reactos/base/shell/cmd/precomp.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/precomp.h?rev=76023&r1=76022&r2=76023&view=diff ============================================================================== --- trunk/reactos/base/shell/cmd/precomp.h [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/precomp.h [iso-8859-1] Sun Oct 1 16:30:39 2017 @@ -22,6 +22,8 @@ #include <wincon.h> #include <shellapi.h> +#include <conutils.h> + #define NTOS_MODE_USER #include <ndk/rtlfuncs.h> Modified: trunk/reactos/base/shell/cmd/redir.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/redir.c?rev=76023&r1=76022&r2=76023&view=diff ============================================================================== --- trunk/reactos/base/shell/cmd/redir.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/redir.c [iso-8859-1] Sun Oct 1 16:30:39 2017 @@ -29,15 +29,18 @@ #ifdef FEATURE_REDIRECTION - -/* cmd allows redirection of handles numbered 3-9 even though these don't - * correspond to any STD_ constant. */ -static HANDLE ExtraHandles[10 - 3]; +/* + * CMD allows redirection of handles numbered 3-9 even though + * these don't correspond to any STD_ constant. + */ +static const PCON_STREAM StdStreams[] = { StdIn, StdOut, StdErr }; +static HANDLE ExtraHandles[10 - 3]; // 3 == ARRAYSIZE(StdStreams) static HANDLE GetHandle(UINT Number) { if (Number < 3) - return GetStdHandle(STD_INPUT_HANDLE - Number); + return ConStreamGetOSHandle(StdStreams[Number]); + // return GetStdHandle(STD_INPUT_HANDLE - Number); else return ExtraHandles[Number - 3]; } @@ -45,9 +48,15 @@ static VOID SetHandle(UINT Number, HANDLE Handle) { if (Number < 3) + { + ConStreamSetOSHandle(StdStreams[Number], Handle); + /* Synchronize the associated Win32 handle */ SetStdHandle(STD_INPUT_HANDLE - Number, Handle); + } else + { ExtraHandles[Number - 3] = Handle; + } } BOOL Modified: trunk/reactos/base/shell/cmd/start.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/start.c?rev=76023&r1=76022&r2=76023&view=diff ============================================================================== --- trunk/reactos/base/shell/cmd/start.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/start.c [iso-8859-1] Sun Oct 1 16:30:39 2017 @@ -304,9 +304,26 @@ } CloseHandle (prci.hProcess); - /* Get New code page if it has change */ - InputCodePage= GetConsoleCP(); - OutputCodePage = GetConsoleOutputCP(); + /* Update our local codepage cache */ + { + UINT uNewInputCodePage = GetConsoleCP(); + UINT uNewOutputCodePage = GetConsoleOutputCP(); + + if ((InputCodePage != uNewInputCodePage) || + (OutputCodePage != uNewOutputCodePage)) + { + /* Update the locale as well */ + InitLocale(); + } + + InputCodePage = uNewInputCodePage; + OutputCodePage = uNewOutputCodePage; + + /* Update the streams codepage cache as well */ + ConStreamSetCacheCodePage(StdIn , InputCodePage ); + ConStreamSetCacheCodePage(StdOut, OutputCodePage); + ConStreamSetCacheCodePage(StdErr, OutputCodePage); + } } else {