2010-11-08 15:31:01 +10:00
|
|
|
/*
|
|
|
|
ANSI.c - ANSI escape sequence console driver.
|
|
|
|
|
|
|
|
Jason Hood, 21 & 22 October, 2005.
|
|
|
|
|
|
|
|
Derived from ANSI.xs by Jean-Louis Morel, from his Perl package
|
|
|
|
Win32::Console::ANSI. I removed the codepage conversion ("\e(") and added
|
|
|
|
WriteConsole hooking.
|
|
|
|
|
|
|
|
v1.01, 11 & 12 March, 2006:
|
|
|
|
disable when console has disabled processed output;
|
|
|
|
\e[5m (blink) is the same as \e[4m (underline);
|
|
|
|
do not conceal control characters (0 to 31);
|
|
|
|
\e[m will restore original color.
|
|
|
|
|
|
|
|
v1.10, 22 February, 2009:
|
|
|
|
fix MyWriteConsoleW for strings longer than the buffer;
|
|
|
|
initialise attributes to current;
|
|
|
|
hook into child processes.
|
|
|
|
|
|
|
|
v1.11, 28 February, 2009:
|
|
|
|
fix hooking into child processes (only do console executables).
|
|
|
|
|
|
|
|
v1.12, 9 March, 2009:
|
|
|
|
really fix hooking (I didn't realise MinGW didn't generate relocations).
|
|
|
|
|
|
|
|
v1.13, 21 & 27 March, 2009:
|
|
|
|
alternate injection method, to work with DEP;
|
|
|
|
use Unicode and the current output code page (not OEMCP).
|
|
|
|
|
|
|
|
v1.14, 3 April, 2009:
|
|
|
|
fix test for empty import section.
|
|
|
|
|
|
|
|
v1.15, 17 May, 2009:
|
|
|
|
properly update lpNumberOfCharsWritten in MyWriteConsoleA.
|
|
|
|
|
|
|
|
v1.20, 26 & 29 May, 17 to 21 June, 2009:
|
|
|
|
create an ANSICON environment variable;
|
|
|
|
hook GetEnvironmentVariable to create ANSICON dynamically;
|
|
|
|
use another injection method.
|
|
|
|
|
|
|
|
v1.22, 5 October, 2009:
|
|
|
|
hook LoadLibrary to intercept the newly loaded functions.
|
|
|
|
|
|
|
|
v1.23, 11 November, 2009:
|
|
|
|
unload gracefully;
|
|
|
|
conceal characters by making foreground same as background;
|
|
|
|
reverse the bold/underline attributes, too.
|
|
|
|
|
|
|
|
v1.25, 15, 20 & 21 July, 2010:
|
|
|
|
hook LoadLibraryEx (now cscript works);
|
|
|
|
Win7 support.
|
|
|
|
|
|
|
|
v1.30, 3 August to 7 September, 2010:
|
|
|
|
x64 support.
|
2010-11-13 14:49:27 +10:00
|
|
|
|
2010-11-19 15:50:10 +10:00
|
|
|
v1.31, 13 & 19 November, 2010:
|
2010-11-13 14:49:27 +10:00
|
|
|
fix multibyte conversion problems.
|
2010-12-04 15:19:36 +10:00
|
|
|
|
2010-12-22 18:47:45 +10:00
|
|
|
v1.32, 4 to 22 December, 2010:
|
2010-12-12 21:58:35 +10:00
|
|
|
test for lpNumberOfCharsWritten/lpNumberOfBytesWritten being NULL;
|
|
|
|
recognise DSR and xterm window title;
|
2010-12-16 16:00:56 +10:00
|
|
|
ignore sequences starting with \e[? & \e[>;
|
|
|
|
close the handles opened by CreateProcess.
|
2011-02-26 01:12:35 +10:00
|
|
|
|
2011-03-01 21:01:37 +10:00
|
|
|
v1.40, 25 & 26 February, 1 March, 2011:
|
2011-02-26 17:14:21 +10:00
|
|
|
hook GetProcAddress, addresses issues with .NET (work with PowerShell);
|
|
|
|
implement SO & SI to use the DEC Special Graphics Character Set (enables
|
2011-03-01 21:01:37 +10:00
|
|
|
line drawing via ASCII); ignore \e(X & \e)X (where X is any character);
|
|
|
|
add \e[?25h & \e[?25l to show/hide the cursor (DECTCEM).
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
|
|
|
|
v1.50, 7 to 14 December, 2011:
|
|
|
|
added dynamic environment variable ANSICON_VER to return version;
|
|
|
|
read ANSICON_EXC environment variable to exclude selected modules;
|
|
|
|
read ANSICON_GUI environment variable to hook selected GUI programs;
|
|
|
|
read ANSICON_DEF environment variable to set the default GR;
|
|
|
|
transfer current GR to child, read it on exit.
|
2012-02-24 12:53:07 +10:00
|
|
|
|
|
|
|
v1.51, 15 January, 5, 22 & 24 February, 2012:
|
|
|
|
added log mask 16 to log all the imported modules of imported modules;
|
|
|
|
ignore the version within the core API DLL names;
|
|
|
|
fix 32-bit process trying to identify 64-bit process;
|
|
|
|
hook _lwrite & _hwrite.
|
2012-04-10 15:39:58 +10:00
|
|
|
|
2012-06-02 17:20:21 +10:00
|
|
|
v1.52, 10 April, 1 & 2 June, 2012:
|
2012-06-01 23:42:58 +10:00
|
|
|
use ansicon.exe to enable 32-bit to inject into 64-bit;
|
2012-06-02 17:20:21 +10:00
|
|
|
implement \e[39m & \e[49m (only setting color, nothing else);
|
|
|
|
added the character/line equivalents (keaj`) of the cursor movement
|
|
|
|
sequences (ABCDG), as well as vertical absolute (d) and erase characters
|
|
|
|
(X).
|
2012-06-12 14:38:00 +10:00
|
|
|
|
|
|
|
v1.53, 12 June, 2012:
|
|
|
|
fixed Update_GRM when running multiple processes (e.g. "cl /MP").
|
2012-11-24 23:41:29 +10:00
|
|
|
|
|
|
|
v1.60, 22 to 24 November, 2012:
|
|
|
|
alternative method to obtain LLW for 64->32 injection;
|
|
|
|
support for VC6 (remove section pragma, rename isdigit to is_digit).
|
2013-02-14 18:12:13 +10:00
|
|
|
|
|
|
|
v1.61, 14 February, 2013:
|
|
|
|
go back to using ANSI-LLW.exe for 64->32 injection.
|
2013-07-19 00:14:54 +10:00
|
|
|
|
|
|
|
v1.62, 17 & 18 July, 2013:
|
|
|
|
another method to obtain LLW for 64->32 injection.
|
2013-08-02 23:21:07 +10:00
|
|
|
|
|
|
|
v1.64, 2 August, 2013:
|
|
|
|
better method of determining a console handle (see IsConsoleHandle).
|
2013-09-04 19:37:55 +10:00
|
|
|
|
|
|
|
v1.65, 28 August, 2013:
|
|
|
|
fix \e[K (was using window, not buffer).
|
2014-01-25 23:43:41 +10:00
|
|
|
|
|
|
|
v.166, 20 & 21 September, 2013:
|
|
|
|
fix 32-bit process trying to detect 64-bit process.
|
|
|
|
|
2014-01-27 14:03:53 +10:00
|
|
|
v1.67, 25 to 27 January, 2014:
|
2014-01-25 23:43:41 +10:00
|
|
|
don't hook ourself from LoadLibrary or LoadLibraryEx;
|
2014-01-27 14:03:53 +10:00
|
|
|
update the LoadLibraryEx flags that should not cause hooking;
|
|
|
|
always find the base address of kernel32.dll.
|
2010-11-08 15:31:01 +10:00
|
|
|
*/
|
|
|
|
|
2010-12-12 21:58:35 +10:00
|
|
|
#include "ansicon.h"
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
#include "version.h"
|
2010-11-08 15:31:01 +10:00
|
|
|
#include <tlhelp32.h>
|
2010-11-15 21:51:38 +10:00
|
|
|
|
2012-11-24 23:41:29 +10:00
|
|
|
#define is_digit(c) ('0' <= (c) && (c) <= '9')
|
2010-11-08 15:31:01 +10:00
|
|
|
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
#ifdef __GNUC__
|
2012-11-24 23:41:29 +10:00
|
|
|
#define SHARED __attribute__((shared, section(".shared")))
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
#else
|
2012-11-24 23:41:29 +10:00
|
|
|
#pragma data_seg(".shared", "read,write,shared")
|
|
|
|
#pragma data_seg()
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
#define SHARED __declspec(allocate(".shared"))
|
|
|
|
#endif
|
2010-12-12 21:58:35 +10:00
|
|
|
|
2010-11-08 15:31:01 +10:00
|
|
|
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
// ========== Global variables and constants
|
2010-11-08 15:31:01 +10:00
|
|
|
|
|
|
|
HANDLE hConOut; // handle to CONOUT$
|
|
|
|
|
2010-12-12 21:58:35 +10:00
|
|
|
#define ESC '\x1B' // ESCape character
|
|
|
|
#define BEL '\x07'
|
2011-02-26 17:14:21 +10:00
|
|
|
#define SO '\x0E' // Shift Out
|
|
|
|
#define SI '\x0F' // Shift In
|
2010-11-08 15:31:01 +10:00
|
|
|
|
|
|
|
#define MAX_ARG 16 // max number of args in an escape sequence
|
|
|
|
int state; // automata state
|
2010-12-12 21:58:35 +10:00
|
|
|
TCHAR prefix; // escape sequence prefix ( '[', ']' or '(' );
|
|
|
|
TCHAR prefix2; // secondary prefix ( '?' or '>' );
|
2010-11-08 15:31:01 +10:00
|
|
|
TCHAR suffix; // escape sequence suffix
|
|
|
|
int es_argc; // escape sequence args count
|
|
|
|
int es_argv[MAX_ARG]; // escape sequence args
|
2010-12-12 21:58:35 +10:00
|
|
|
TCHAR Pt_arg[MAX_PATH*2]; // text parameter for Operating System Command
|
|
|
|
int Pt_len;
|
2011-02-26 17:14:21 +10:00
|
|
|
BOOL shifted;
|
|
|
|
|
|
|
|
|
|
|
|
// DEC Special Graphics Character Set from
|
|
|
|
// http://vt100.net/docs/vt220-rm/table2-4.html
|
|
|
|
// Some of these may not look right, depending on the font and code page (in
|
|
|
|
// particular, the Control Pictures probably won't work at all).
|
|
|
|
const WCHAR G1[] =
|
|
|
|
{
|
|
|
|
' ', // _ - blank
|
|
|
|
L'\x2666', // ` - Black Diamond Suit
|
|
|
|
L'\x2592', // a - Medium Shade
|
|
|
|
L'\x2409', // b - HT
|
|
|
|
L'\x240c', // c - FF
|
|
|
|
L'\x240d', // d - CR
|
|
|
|
L'\x240a', // e - LF
|
|
|
|
L'\x00b0', // f - Degree Sign
|
|
|
|
L'\x00b1', // g - Plus-Minus Sign
|
|
|
|
L'\x2424', // h - NL
|
|
|
|
L'\x240b', // i - VT
|
|
|
|
L'\x2518', // j - Box Drawings Light Up And Left
|
|
|
|
L'\x2510', // k - Box Drawings Light Down And Left
|
|
|
|
L'\x250c', // l - Box Drawings Light Down And Right
|
|
|
|
L'\x2514', // m - Box Drawings Light Up And Right
|
|
|
|
L'\x253c', // n - Box Drawings Light Vertical And Horizontal
|
|
|
|
L'\x00af', // o - SCAN 1 - Macron
|
|
|
|
L'\x25ac', // p - SCAN 3 - Black Rectangle
|
|
|
|
L'\x2500', // q - SCAN 5 - Box Drawings Light Horizontal
|
|
|
|
L'_', // r - SCAN 7 - Low Line
|
|
|
|
L'_', // s - SCAN 9 - Low Line
|
|
|
|
L'\x251c', // t - Box Drawings Light Vertical And Right
|
|
|
|
L'\x2524', // u - Box Drawings Light Vertical And Left
|
|
|
|
L'\x2534', // v - Box Drawings Light Up And Horizontal
|
|
|
|
L'\x252c', // w - Box Drawings Light Down And Horizontal
|
|
|
|
L'\x2502', // x - Box Drawings Light Vertical
|
|
|
|
L'\x2264', // y - Less-Than Or Equal To
|
|
|
|
L'\x2265', // z - Greater-Than Or Equal To
|
|
|
|
L'\x03c0', // { - Greek Small Letter Pi
|
|
|
|
L'\x2260', // | - Not Equal To
|
|
|
|
L'\x00a3', // } - Pound Sign
|
|
|
|
L'\x00b7', // ~ - Middle Dot
|
|
|
|
};
|
|
|
|
|
|
|
|
#define FIRST_G1 '_'
|
|
|
|
#define LAST_G1 '~'
|
|
|
|
|
2010-11-08 15:31:01 +10:00
|
|
|
|
|
|
|
// color constants
|
|
|
|
|
|
|
|
#define FOREGROUND_BLACK 0
|
|
|
|
#define FOREGROUND_WHITE FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE
|
|
|
|
|
|
|
|
#define BACKGROUND_BLACK 0
|
|
|
|
#define BACKGROUND_WHITE BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE
|
|
|
|
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
const BYTE foregroundcolor[8] =
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
|
|
|
FOREGROUND_BLACK, // black foreground
|
|
|
|
FOREGROUND_RED, // red foreground
|
|
|
|
FOREGROUND_GREEN, // green foreground
|
|
|
|
FOREGROUND_RED | FOREGROUND_GREEN, // yellow foreground
|
|
|
|
FOREGROUND_BLUE, // blue foreground
|
|
|
|
FOREGROUND_BLUE | FOREGROUND_RED, // magenta foreground
|
|
|
|
FOREGROUND_BLUE | FOREGROUND_GREEN, // cyan foreground
|
|
|
|
FOREGROUND_WHITE // white foreground
|
|
|
|
};
|
|
|
|
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
const BYTE backgroundcolor[8] =
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
|
|
|
BACKGROUND_BLACK, // black background
|
|
|
|
BACKGROUND_RED, // red background
|
|
|
|
BACKGROUND_GREEN, // green background
|
|
|
|
BACKGROUND_RED | BACKGROUND_GREEN, // yellow background
|
|
|
|
BACKGROUND_BLUE, // blue background
|
|
|
|
BACKGROUND_BLUE | BACKGROUND_RED, // magenta background
|
|
|
|
BACKGROUND_BLUE | BACKGROUND_GREEN, // cyan background
|
|
|
|
BACKGROUND_WHITE, // white background
|
|
|
|
};
|
|
|
|
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
const BYTE attr2ansi[8] = // map console attribute to ANSI number
|
|
|
|
{
|
|
|
|
0, // black
|
|
|
|
4, // blue
|
|
|
|
2, // green
|
|
|
|
6, // cyan
|
|
|
|
1, // red
|
|
|
|
5, // magenta
|
|
|
|
3, // yellow
|
|
|
|
7 // white
|
|
|
|
};
|
2010-11-08 15:31:01 +10:00
|
|
|
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
GRM grm;
|
2010-11-08 15:31:01 +10:00
|
|
|
|
|
|
|
// saved cursor position
|
2010-11-15 21:51:38 +10:00
|
|
|
COORD SavePos;
|
2010-11-08 15:31:01 +10:00
|
|
|
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
// Variables to enable copying attributes between processes.
|
|
|
|
SHARED DWORD s_pid;
|
|
|
|
SHARED GRM s_grm;
|
|
|
|
SHARED DWORD s_flag;
|
|
|
|
#define GRM_INIT 1
|
|
|
|
#define GRM_EXIT 2
|
2010-11-08 15:31:01 +10:00
|
|
|
|
2014-01-27 14:03:53 +10:00
|
|
|
SHARED DWORD LLW32r;
|
2012-11-24 23:41:29 +10:00
|
|
|
#ifdef _WIN64
|
2014-01-27 14:03:53 +10:00
|
|
|
SHARED DWORD LLW64r;
|
2012-11-24 23:41:29 +10:00
|
|
|
#endif
|
2010-11-08 15:31:01 +10:00
|
|
|
|
|
|
|
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
// Wait for the child process to finish, then update our GRM to the child's.
|
2012-06-12 14:38:00 +10:00
|
|
|
DWORD WINAPI UpdateGRM( LPVOID child_pi )
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
2012-06-12 14:38:00 +10:00
|
|
|
DWORD pid = ((LPPROCESS_INFORMATION)child_pi)->dwProcessId;
|
|
|
|
HANDLE proc = ((LPPROCESS_INFORMATION)child_pi)->hProcess;
|
|
|
|
free( child_pi );
|
|
|
|
|
|
|
|
WaitForSingleObject( proc, INFINITE );
|
|
|
|
CloseHandle( proc );
|
|
|
|
|
|
|
|
if (s_flag == GRM_EXIT && s_pid == pid)
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
s_flag = 0;
|
|
|
|
grm = s_grm;
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
|
|
|
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
return 0;
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
// Search an environment variable for a string.
|
|
|
|
BOOL search_env( LPCTSTR var, LPCTSTR val )
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
static LPTSTR env;
|
|
|
|
static DWORD env_len;
|
|
|
|
DWORD len;
|
|
|
|
BOOL not;
|
2010-11-08 15:31:01 +10:00
|
|
|
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
len = GetEnvironmentVariable( var, env, env_len );
|
|
|
|
if (len == 0)
|
|
|
|
return FALSE;
|
2010-11-08 15:31:01 +10:00
|
|
|
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
if (len > env_len)
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
LPTSTR tmp = realloc( env, TSIZE(len) );
|
|
|
|
if (tmp == NULL)
|
|
|
|
return FALSE;
|
|
|
|
env = tmp;
|
|
|
|
env_len = len;
|
|
|
|
GetEnvironmentVariable( var, env, env_len );
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
|
|
|
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
not = (*env == '!');
|
|
|
|
if (not && env[1] == '\0')
|
|
|
|
return TRUE;
|
2010-11-08 15:31:01 +10:00
|
|
|
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
for (var = wcstok( env + not, L";" ); var; var = wcstok( NULL, L";" ))
|
|
|
|
if (_wcsicmp( val, var ) == 0)
|
|
|
|
return !not;
|
|
|
|
|
|
|
|
return not;
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
|
|
|
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
|
2010-11-08 15:31:01 +10:00
|
|
|
// ========== Print Buffer functions
|
|
|
|
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
#define BUFFER_SIZE 2048
|
2011-02-26 17:14:21 +10:00
|
|
|
|
|
|
|
int nCharInBuffer;
|
|
|
|
WCHAR ChBuffer[BUFFER_SIZE];
|
2010-11-08 15:31:01 +10:00
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// FlushBuffer()
|
|
|
|
// Writes the buffer to the console and empties it.
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void FlushBuffer( void )
|
|
|
|
{
|
|
|
|
DWORD nWritten;
|
|
|
|
if (nCharInBuffer <= 0) return;
|
|
|
|
WriteConsole( hConOut, ChBuffer, nCharInBuffer, &nWritten, NULL );
|
|
|
|
nCharInBuffer = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2011-02-26 17:14:21 +10:00
|
|
|
// PushBuffer( WCHAR c )
|
|
|
|
// Adds a character in the buffer.
|
2010-11-08 15:31:01 +10:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
2011-02-26 17:14:21 +10:00
|
|
|
void PushBuffer( WCHAR c )
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
2011-02-26 17:14:21 +10:00
|
|
|
if (shifted && c >= FIRST_G1 && c <= LAST_G1)
|
|
|
|
c = G1[c-FIRST_G1];
|
|
|
|
ChBuffer[nCharInBuffer] = c;
|
|
|
|
if (++nCharInBuffer == BUFFER_SIZE)
|
|
|
|
FlushBuffer();
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
|
|
|
|
2010-12-12 21:58:35 +10:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// SendSequence( LPTSTR seq )
|
|
|
|
// Send the string to the input buffer.
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void SendSequence( LPTSTR seq )
|
|
|
|
{
|
|
|
|
DWORD out;
|
|
|
|
INPUT_RECORD in;
|
|
|
|
HANDLE hStdIn = GetStdHandle( STD_INPUT_HANDLE );
|
|
|
|
|
2010-12-12 23:32:22 +10:00
|
|
|
in.EventType = KEY_EVENT;
|
|
|
|
in.Event.KeyEvent.bKeyDown = TRUE;
|
|
|
|
in.Event.KeyEvent.wRepeatCount = 1;
|
|
|
|
in.Event.KeyEvent.wVirtualKeyCode = 0;
|
|
|
|
in.Event.KeyEvent.wVirtualScanCode = 0;
|
|
|
|
in.Event.KeyEvent.dwControlKeyState = 0;
|
2010-12-12 21:58:35 +10:00
|
|
|
for (; *seq; ++seq)
|
|
|
|
{
|
|
|
|
in.Event.KeyEvent.uChar.UnicodeChar = *seq;
|
|
|
|
WriteConsoleInput( hStdIn, &in, 1, &out );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-08 15:31:01 +10:00
|
|
|
// ========== Print functions
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// InterpretEscSeq()
|
|
|
|
// Interprets the last escape sequence scanned by ParseAndPrintString
|
|
|
|
// prefix escape sequence prefix
|
|
|
|
// es_argc escape sequence args count
|
|
|
|
// es_argv[] escape sequence args array
|
|
|
|
// suffix escape sequence suffix
|
|
|
|
//
|
|
|
|
// for instance, with \e[33;45;1m we have
|
|
|
|
// prefix = '[',
|
|
|
|
// es_argc = 3, es_argv[0] = 33, es_argv[1] = 45, es_argv[2] = 1
|
|
|
|
// suffix = 'm'
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void InterpretEscSeq( void )
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
WORD attribut;
|
|
|
|
CONSOLE_SCREEN_BUFFER_INFO Info;
|
2011-03-01 21:01:37 +10:00
|
|
|
CONSOLE_CURSOR_INFO CursInfo;
|
2010-11-08 15:31:01 +10:00
|
|
|
DWORD len, NumberOfCharsWritten;
|
|
|
|
COORD Pos;
|
|
|
|
SMALL_RECT Rect;
|
|
|
|
CHAR_INFO CharInfo;
|
|
|
|
|
2010-12-12 21:58:35 +10:00
|
|
|
if (prefix == '[')
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
2011-03-01 21:01:37 +10:00
|
|
|
if (prefix2 == '?' && (suffix == 'h' || suffix == 'l'))
|
|
|
|
{
|
|
|
|
if (es_argc == 1 && es_argv[0] == 25)
|
|
|
|
{
|
|
|
|
GetConsoleCursorInfo( hConOut, &CursInfo );
|
|
|
|
CursInfo.bVisible = (suffix == 'h');
|
|
|
|
SetConsoleCursorInfo( hConOut, &CursInfo );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Ignore any other \e[? or \e[> sequences.
|
|
|
|
if (prefix2 != 0)
|
|
|
|
return;
|
|
|
|
|
2010-11-08 15:31:01 +10:00
|
|
|
GetConsoleScreenBufferInfo( hConOut, &Info );
|
|
|
|
switch (suffix)
|
|
|
|
{
|
|
|
|
case 'm':
|
|
|
|
if (es_argc == 0) es_argv[es_argc++] = 0;
|
|
|
|
for (i = 0; i < es_argc; i++)
|
|
|
|
{
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
if (30 <= es_argv[i] && es_argv[i] <= 37)
|
|
|
|
grm.foreground = es_argv[i] - 30;
|
|
|
|
else if (40 <= es_argv[i] && es_argv[i] <= 47)
|
|
|
|
grm.background = es_argv[i] - 40;
|
|
|
|
else switch (es_argv[i])
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
|
|
|
case 0:
|
2012-06-01 23:42:58 +10:00
|
|
|
case 39:
|
|
|
|
case 49:
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
{
|
|
|
|
TCHAR def[4];
|
|
|
|
int a;
|
|
|
|
*def = '7'; def[1] = '\0';
|
|
|
|
GetEnvironmentVariable( L"ANSICON_DEF", def, lenof(def) );
|
|
|
|
a = wcstol( def, NULL, 16 );
|
|
|
|
grm.reverse = FALSE;
|
|
|
|
if (a < 0)
|
|
|
|
{
|
|
|
|
grm.reverse = TRUE;
|
|
|
|
a = -a;
|
|
|
|
}
|
2012-06-01 23:42:58 +10:00
|
|
|
if (es_argv[i] != 49)
|
|
|
|
grm.foreground = attr2ansi[a & 7];
|
|
|
|
if (es_argv[i] != 39)
|
|
|
|
grm.background = attr2ansi[(a >> 4) & 7];
|
|
|
|
if (es_argv[i] == 0)
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
{
|
2012-06-01 23:42:58 +10:00
|
|
|
if (es_argc == 1)
|
|
|
|
{
|
|
|
|
grm.bold = a & FOREGROUND_INTENSITY;
|
|
|
|
grm.underline = a & BACKGROUND_INTENSITY;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
grm.bold = 0;
|
|
|
|
grm.underline = 0;
|
|
|
|
}
|
|
|
|
grm.rvideo = 0;
|
|
|
|
grm.concealed = 0;
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
}
|
|
|
|
}
|
2010-11-08 15:31:01 +10:00
|
|
|
break;
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
|
|
|
|
case 1: grm.bold = FOREGROUND_INTENSITY; break;
|
|
|
|
case 5: // blink
|
|
|
|
case 4: grm.underline = BACKGROUND_INTENSITY; break;
|
|
|
|
case 7: grm.rvideo = 1; break;
|
|
|
|
case 8: grm.concealed = 1; break;
|
|
|
|
case 21: // oops, this actually turns on double underline
|
|
|
|
case 22: grm.bold = 0; break;
|
2010-11-08 15:31:01 +10:00
|
|
|
case 25:
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
case 24: grm.underline = 0; break;
|
|
|
|
case 27: grm.rvideo = 0; break;
|
|
|
|
case 28: grm.concealed = 0; break;
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
|
|
|
}
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
if (grm.concealed)
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
if (grm.rvideo)
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
attribut = foregroundcolor[grm.foreground]
|
|
|
|
| backgroundcolor[grm.foreground];
|
|
|
|
if (grm.bold)
|
2010-11-08 15:31:01 +10:00
|
|
|
attribut |= FOREGROUND_INTENSITY | BACKGROUND_INTENSITY;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
attribut = foregroundcolor[grm.background]
|
|
|
|
| backgroundcolor[grm.background];
|
|
|
|
if (grm.underline)
|
2010-11-08 15:31:01 +10:00
|
|
|
attribut |= FOREGROUND_INTENSITY | BACKGROUND_INTENSITY;
|
|
|
|
}
|
|
|
|
}
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
else if (grm.rvideo)
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
attribut = foregroundcolor[grm.background]
|
|
|
|
| backgroundcolor[grm.foreground];
|
|
|
|
if (grm.bold)
|
2010-11-08 15:31:01 +10:00
|
|
|
attribut |= BACKGROUND_INTENSITY;
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
if (grm.underline)
|
2010-11-08 15:31:01 +10:00
|
|
|
attribut |= FOREGROUND_INTENSITY;
|
|
|
|
}
|
|
|
|
else
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
attribut = foregroundcolor[grm.foreground] | grm.bold
|
|
|
|
| backgroundcolor[grm.background] | grm.underline;
|
|
|
|
if (grm.reverse)
|
|
|
|
attribut = ((attribut >> 4) & 15) | ((attribut & 15) << 4);
|
2010-11-08 15:31:01 +10:00
|
|
|
SetConsoleTextAttribute( hConOut, attribut );
|
|
|
|
return;
|
|
|
|
|
|
|
|
case 'J':
|
|
|
|
if (es_argc == 0) es_argv[es_argc++] = 0; // ESC[J == ESC[0J
|
|
|
|
if (es_argc != 1) return;
|
|
|
|
switch (es_argv[0])
|
|
|
|
{
|
|
|
|
case 0: // ESC[0J erase from cursor to end of display
|
|
|
|
len = (Info.dwSize.Y - Info.dwCursorPosition.Y - 1) * Info.dwSize.X
|
|
|
|
+ Info.dwSize.X - Info.dwCursorPosition.X - 1;
|
|
|
|
FillConsoleOutputCharacter( hConOut, ' ', len,
|
|
|
|
Info.dwCursorPosition,
|
|
|
|
&NumberOfCharsWritten );
|
|
|
|
FillConsoleOutputAttribute( hConOut, Info.wAttributes, len,
|
|
|
|
Info.dwCursorPosition,
|
|
|
|
&NumberOfCharsWritten );
|
|
|
|
return;
|
|
|
|
|
|
|
|
case 1: // ESC[1J erase from start to cursor.
|
|
|
|
Pos.X = 0;
|
|
|
|
Pos.Y = 0;
|
|
|
|
len = Info.dwCursorPosition.Y * Info.dwSize.X
|
|
|
|
+ Info.dwCursorPosition.X + 1;
|
|
|
|
FillConsoleOutputCharacter( hConOut, ' ', len, Pos,
|
|
|
|
&NumberOfCharsWritten );
|
|
|
|
FillConsoleOutputAttribute( hConOut, Info.wAttributes, len, Pos,
|
|
|
|
&NumberOfCharsWritten );
|
|
|
|
return;
|
|
|
|
|
|
|
|
case 2: // ESC[2J Clear screen and home cursor
|
|
|
|
Pos.X = 0;
|
|
|
|
Pos.Y = 0;
|
|
|
|
len = Info.dwSize.X * Info.dwSize.Y;
|
|
|
|
FillConsoleOutputCharacter( hConOut, ' ', len, Pos,
|
|
|
|
&NumberOfCharsWritten );
|
|
|
|
FillConsoleOutputAttribute( hConOut, Info.wAttributes, len, Pos,
|
|
|
|
&NumberOfCharsWritten );
|
|
|
|
SetConsoleCursorPosition( hConOut, Pos );
|
|
|
|
return;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
case 'K':
|
|
|
|
if (es_argc == 0) es_argv[es_argc++] = 0; // ESC[K == ESC[0K
|
|
|
|
if (es_argc != 1) return;
|
|
|
|
switch (es_argv[0])
|
|
|
|
{
|
|
|
|
case 0: // ESC[0K Clear to end of line
|
2013-09-04 19:37:55 +10:00
|
|
|
len = Info.dwSize.X - Info.dwCursorPosition.X + 1;
|
2010-11-08 15:31:01 +10:00
|
|
|
FillConsoleOutputCharacter( hConOut, ' ', len,
|
|
|
|
Info.dwCursorPosition,
|
|
|
|
&NumberOfCharsWritten );
|
|
|
|
FillConsoleOutputAttribute( hConOut, Info.wAttributes, len,
|
|
|
|
Info.dwCursorPosition,
|
|
|
|
&NumberOfCharsWritten );
|
|
|
|
return;
|
|
|
|
|
|
|
|
case 1: // ESC[1K Clear from start of line to cursor
|
|
|
|
Pos.X = 0;
|
|
|
|
Pos.Y = Info.dwCursorPosition.Y;
|
|
|
|
FillConsoleOutputCharacter( hConOut, ' ',
|
|
|
|
Info.dwCursorPosition.X + 1, Pos,
|
|
|
|
&NumberOfCharsWritten );
|
|
|
|
FillConsoleOutputAttribute( hConOut, Info.wAttributes,
|
|
|
|
Info.dwCursorPosition.X + 1, Pos,
|
|
|
|
&NumberOfCharsWritten );
|
|
|
|
return;
|
|
|
|
|
|
|
|
case 2: // ESC[2K Clear whole line.
|
|
|
|
Pos.X = 0;
|
|
|
|
Pos.Y = Info.dwCursorPosition.Y;
|
|
|
|
FillConsoleOutputCharacter( hConOut, ' ', Info.dwSize.X, Pos,
|
|
|
|
&NumberOfCharsWritten );
|
|
|
|
FillConsoleOutputAttribute( hConOut, Info.wAttributes,
|
|
|
|
Info.dwSize.X, Pos,
|
|
|
|
&NumberOfCharsWritten );
|
|
|
|
return;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-06-02 17:20:21 +10:00
|
|
|
case 'X': // ESC[#X Erase # characters.
|
|
|
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[X == ESC[1X
|
|
|
|
if (es_argc != 1) return;
|
|
|
|
FillConsoleOutputCharacter( hConOut, ' ', es_argv[0],
|
|
|
|
Info.dwCursorPosition,
|
|
|
|
&NumberOfCharsWritten );
|
|
|
|
FillConsoleOutputAttribute( hConOut, Info.wAttributes, es_argv[0],
|
|
|
|
Info.dwCursorPosition,
|
|
|
|
&NumberOfCharsWritten );
|
|
|
|
return;
|
|
|
|
|
2010-11-08 15:31:01 +10:00
|
|
|
case 'L': // ESC[#L Insert # blank lines.
|
|
|
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[L == ESC[1L
|
|
|
|
if (es_argc != 1) return;
|
|
|
|
Rect.Left = 0;
|
|
|
|
Rect.Top = Info.dwCursorPosition.Y;
|
|
|
|
Rect.Right = Info.dwSize.X - 1;
|
|
|
|
Rect.Bottom = Info.dwSize.Y - 1;
|
|
|
|
Pos.X = 0;
|
|
|
|
Pos.Y = Info.dwCursorPosition.Y + es_argv[0];
|
|
|
|
CharInfo.Char.UnicodeChar = ' ';
|
|
|
|
CharInfo.Attributes = Info.wAttributes;
|
|
|
|
ScrollConsoleScreenBuffer( hConOut, &Rect, NULL, Pos, &CharInfo );
|
|
|
|
return;
|
|
|
|
|
|
|
|
case 'M': // ESC[#M Delete # lines.
|
|
|
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[M == ESC[1M
|
|
|
|
if (es_argc != 1) return;
|
|
|
|
if (es_argv[0] > Info.dwSize.Y - Info.dwCursorPosition.Y)
|
|
|
|
es_argv[0] = Info.dwSize.Y - Info.dwCursorPosition.Y;
|
|
|
|
Rect.Left = 0;
|
|
|
|
Rect.Top = Info.dwCursorPosition.Y + es_argv[0];
|
|
|
|
Rect.Right = Info.dwSize.X - 1;
|
|
|
|
Rect.Bottom = Info.dwSize.Y - 1;
|
|
|
|
Pos.X = 0;
|
|
|
|
Pos.Y = Info.dwCursorPosition.Y;
|
|
|
|
CharInfo.Char.UnicodeChar = ' ';
|
|
|
|
CharInfo.Attributes = Info.wAttributes;
|
|
|
|
ScrollConsoleScreenBuffer( hConOut, &Rect, NULL, Pos, &CharInfo );
|
|
|
|
return;
|
|
|
|
|
|
|
|
case 'P': // ESC[#P Delete # characters.
|
|
|
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[P == ESC[1P
|
|
|
|
if (es_argc != 1) return;
|
|
|
|
if (Info.dwCursorPosition.X + es_argv[0] > Info.dwSize.X - 1)
|
|
|
|
es_argv[0] = Info.dwSize.X - Info.dwCursorPosition.X;
|
|
|
|
Rect.Left = Info.dwCursorPosition.X + es_argv[0];
|
|
|
|
Rect.Top = Info.dwCursorPosition.Y;
|
|
|
|
Rect.Right = Info.dwSize.X - 1;
|
|
|
|
Rect.Bottom = Info.dwCursorPosition.Y;
|
|
|
|
CharInfo.Char.UnicodeChar = ' ';
|
|
|
|
CharInfo.Attributes = Info.wAttributes;
|
|
|
|
ScrollConsoleScreenBuffer( hConOut, &Rect, NULL, Info.dwCursorPosition,
|
|
|
|
&CharInfo );
|
|
|
|
return;
|
|
|
|
|
|
|
|
case '@': // ESC[#@ Insert # blank characters.
|
|
|
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[@ == ESC[1@
|
|
|
|
if (es_argc != 1) return;
|
|
|
|
if (Info.dwCursorPosition.X + es_argv[0] > Info.dwSize.X - 1)
|
|
|
|
es_argv[0] = Info.dwSize.X - Info.dwCursorPosition.X;
|
|
|
|
Rect.Left = Info.dwCursorPosition.X;
|
|
|
|
Rect.Top = Info.dwCursorPosition.Y;
|
|
|
|
Rect.Right = Info.dwSize.X - 1 - es_argv[0];
|
|
|
|
Rect.Bottom = Info.dwCursorPosition.Y;
|
|
|
|
Pos.X = Info.dwCursorPosition.X + es_argv[0];
|
|
|
|
Pos.Y = Info.dwCursorPosition.Y;
|
|
|
|
CharInfo.Char.UnicodeChar = ' ';
|
|
|
|
CharInfo.Attributes = Info.wAttributes;
|
|
|
|
ScrollConsoleScreenBuffer( hConOut, &Rect, NULL, Pos, &CharInfo );
|
|
|
|
return;
|
|
|
|
|
2012-06-02 17:20:21 +10:00
|
|
|
case 'k': // ESC[#k
|
2010-11-08 15:31:01 +10:00
|
|
|
case 'A': // ESC[#A Moves cursor up # lines
|
|
|
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[A == ESC[1A
|
|
|
|
if (es_argc != 1) return;
|
|
|
|
Pos.Y = Info.dwCursorPosition.Y - es_argv[0];
|
|
|
|
if (Pos.Y < 0) Pos.Y = 0;
|
|
|
|
Pos.X = Info.dwCursorPosition.X;
|
|
|
|
SetConsoleCursorPosition( hConOut, Pos );
|
|
|
|
return;
|
|
|
|
|
2012-06-02 17:20:21 +10:00
|
|
|
case 'e': // ESC[#e
|
2010-11-08 15:31:01 +10:00
|
|
|
case 'B': // ESC[#B Moves cursor down # lines
|
|
|
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[B == ESC[1B
|
|
|
|
if (es_argc != 1) return;
|
|
|
|
Pos.Y = Info.dwCursorPosition.Y + es_argv[0];
|
|
|
|
if (Pos.Y >= Info.dwSize.Y) Pos.Y = Info.dwSize.Y - 1;
|
|
|
|
Pos.X = Info.dwCursorPosition.X;
|
|
|
|
SetConsoleCursorPosition( hConOut, Pos );
|
|
|
|
return;
|
|
|
|
|
2012-06-02 17:20:21 +10:00
|
|
|
case 'a': // ESC[#a
|
2010-11-08 15:31:01 +10:00
|
|
|
case 'C': // ESC[#C Moves cursor forward # spaces
|
|
|
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[C == ESC[1C
|
|
|
|
if (es_argc != 1) return;
|
|
|
|
Pos.X = Info.dwCursorPosition.X + es_argv[0];
|
|
|
|
if (Pos.X >= Info.dwSize.X) Pos.X = Info.dwSize.X - 1;
|
|
|
|
Pos.Y = Info.dwCursorPosition.Y;
|
|
|
|
SetConsoleCursorPosition( hConOut, Pos );
|
|
|
|
return;
|
|
|
|
|
2012-06-02 17:20:21 +10:00
|
|
|
case 'j': // ESC[#j
|
2010-11-08 15:31:01 +10:00
|
|
|
case 'D': // ESC[#D Moves cursor back # spaces
|
|
|
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[D == ESC[1D
|
|
|
|
if (es_argc != 1) return;
|
|
|
|
Pos.X = Info.dwCursorPosition.X - es_argv[0];
|
|
|
|
if (Pos.X < 0) Pos.X = 0;
|
|
|
|
Pos.Y = Info.dwCursorPosition.Y;
|
|
|
|
SetConsoleCursorPosition( hConOut, Pos );
|
|
|
|
return;
|
|
|
|
|
|
|
|
case 'E': // ESC[#E Moves cursor down # lines, column 1.
|
|
|
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[E == ESC[1E
|
|
|
|
if (es_argc != 1) return;
|
|
|
|
Pos.Y = Info.dwCursorPosition.Y + es_argv[0];
|
|
|
|
if (Pos.Y >= Info.dwSize.Y) Pos.Y = Info.dwSize.Y - 1;
|
|
|
|
Pos.X = 0;
|
|
|
|
SetConsoleCursorPosition( hConOut, Pos );
|
|
|
|
return;
|
|
|
|
|
|
|
|
case 'F': // ESC[#F Moves cursor up # lines, column 1.
|
|
|
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[F == ESC[1F
|
|
|
|
if (es_argc != 1) return;
|
|
|
|
Pos.Y = Info.dwCursorPosition.Y - es_argv[0];
|
|
|
|
if (Pos.Y < 0) Pos.Y = 0;
|
|
|
|
Pos.X = 0;
|
|
|
|
SetConsoleCursorPosition( hConOut, Pos );
|
|
|
|
return;
|
|
|
|
|
2012-06-02 17:20:21 +10:00
|
|
|
case '`': // ESC[#`
|
2010-11-08 15:31:01 +10:00
|
|
|
case 'G': // ESC[#G Moves cursor column # in current row.
|
|
|
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[G == ESC[1G
|
|
|
|
if (es_argc != 1) return;
|
|
|
|
Pos.X = es_argv[0] - 1;
|
|
|
|
if (Pos.X >= Info.dwSize.X) Pos.X = Info.dwSize.X - 1;
|
|
|
|
if (Pos.X < 0) Pos.X = 0;
|
|
|
|
Pos.Y = Info.dwCursorPosition.Y;
|
|
|
|
SetConsoleCursorPosition( hConOut, Pos );
|
|
|
|
return;
|
|
|
|
|
2012-06-02 17:20:21 +10:00
|
|
|
case 'd': // ESC[#d Moves cursor row #, current column.
|
|
|
|
if (es_argc == 0) es_argv[es_argc++] = 1; // ESC[d == ESC[1d
|
|
|
|
if (es_argc != 1) return;
|
|
|
|
Pos.Y = es_argv[0] - 1;
|
|
|
|
if (Pos.Y < 0) Pos.Y = 0;
|
|
|
|
if (Pos.Y >= Info.dwSize.Y) Pos.Y = Info.dwSize.Y - 1;
|
|
|
|
SetConsoleCursorPosition( hConOut, Pos );
|
|
|
|
return;
|
|
|
|
|
2010-11-08 15:31:01 +10:00
|
|
|
case 'f': // ESC[#;#f
|
|
|
|
case 'H': // ESC[#;#H Moves cursor to line #, column #
|
|
|
|
if (es_argc == 0)
|
|
|
|
es_argv[es_argc++] = 1; // ESC[H == ESC[1;1H
|
|
|
|
if (es_argc == 1)
|
|
|
|
es_argv[es_argc++] = 1; // ESC[#H == ESC[#;1H
|
|
|
|
if (es_argc > 2) return;
|
|
|
|
Pos.X = es_argv[1] - 1;
|
|
|
|
if (Pos.X < 0) Pos.X = 0;
|
|
|
|
if (Pos.X >= Info.dwSize.X) Pos.X = Info.dwSize.X - 1;
|
|
|
|
Pos.Y = es_argv[0] - 1;
|
|
|
|
if (Pos.Y < 0) Pos.Y = 0;
|
|
|
|
if (Pos.Y >= Info.dwSize.Y) Pos.Y = Info.dwSize.Y - 1;
|
|
|
|
SetConsoleCursorPosition( hConOut, Pos );
|
|
|
|
return;
|
|
|
|
|
|
|
|
case 's': // ESC[s Saves cursor position for recall later
|
|
|
|
if (es_argc != 0) return;
|
|
|
|
SavePos = Info.dwCursorPosition;
|
|
|
|
return;
|
|
|
|
|
|
|
|
case 'u': // ESC[u Return to saved cursor position
|
|
|
|
if (es_argc != 0) return;
|
|
|
|
SetConsoleCursorPosition( hConOut, SavePos );
|
|
|
|
return;
|
|
|
|
|
2010-12-12 21:58:35 +10:00
|
|
|
case 'n': // ESC[#n Device status report
|
|
|
|
if (es_argc != 1) return; // ESC[n == ESC[0n -> ignored
|
2010-12-12 23:32:22 +10:00
|
|
|
switch (es_argv[0])
|
2010-12-12 21:58:35 +10:00
|
|
|
{
|
2010-12-12 23:32:22 +10:00
|
|
|
case 5: // ESC[5n Report status
|
|
|
|
SendSequence( L"\33[0n" ); // "OK"
|
|
|
|
return;
|
|
|
|
|
|
|
|
case 6: // ESC[6n Report cursor position
|
|
|
|
{
|
|
|
|
TCHAR buf[32];
|
|
|
|
wsprintf( buf, L"\33[%d;%dR", Info.dwCursorPosition.Y + 1,
|
|
|
|
Info.dwCursorPosition.X + 1 );
|
|
|
|
SendSequence( buf );
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return;
|
2010-12-12 21:58:35 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
case 't': // ESC[#t Window manipulation
|
|
|
|
if (es_argc != 1) return;
|
|
|
|
if (es_argv[0] == 21) // ESC[21t Report xterm window's title
|
|
|
|
{
|
|
|
|
TCHAR buf[MAX_PATH*2];
|
|
|
|
DWORD len = GetConsoleTitle( buf+3, lenof(buf)-3-2 );
|
|
|
|
// Too bad if it's too big or fails.
|
|
|
|
buf[0] = ESC;
|
|
|
|
buf[1] = ']';
|
|
|
|
buf[2] = 'l';
|
|
|
|
buf[3+len] = ESC;
|
|
|
|
buf[3+len+1] = '\\';
|
|
|
|
buf[3+len+2] = '\0';
|
|
|
|
SendSequence( buf );
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
|
2010-11-08 15:31:01 +10:00
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2010-12-12 21:58:35 +10:00
|
|
|
else // (prefix == ']')
|
|
|
|
{
|
2011-03-01 21:01:37 +10:00
|
|
|
// Ignore any \e]? or \e]> sequences.
|
|
|
|
if (prefix2 != 0)
|
|
|
|
return;
|
|
|
|
|
2010-12-12 21:58:35 +10:00
|
|
|
if (es_argc == 1 && es_argv[0] == 0) // ESC]0;titleST
|
|
|
|
{
|
2010-12-12 23:32:22 +10:00
|
|
|
SetConsoleTitle( Pt_arg );
|
2010-12-12 21:58:35 +10:00
|
|
|
}
|
|
|
|
}
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// ParseAndPrintString(hDev, lpBuffer, nNumberOfBytesToWrite)
|
|
|
|
// Parses the string lpBuffer, interprets the escapes sequences and prints the
|
|
|
|
// characters in the device hDev (console).
|
|
|
|
// The lexer is a three states automata.
|
|
|
|
// If the number of arguments es_argc > MAX_ARG, only the MAX_ARG-1 firsts and
|
|
|
|
// the last arguments are processed (no es_argv[] overflow).
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
BOOL
|
|
|
|
ParseAndPrintString( HANDLE hDev,
|
|
|
|
LPCVOID lpBuffer,
|
|
|
|
DWORD nNumberOfBytesToWrite,
|
|
|
|
LPDWORD lpNumberOfBytesWritten
|
|
|
|
)
|
|
|
|
{
|
2010-12-16 16:00:56 +10:00
|
|
|
DWORD i;
|
|
|
|
LPCTSTR s;
|
2010-11-08 15:31:01 +10:00
|
|
|
|
|
|
|
if (hDev != hConOut) // reinit if device has changed
|
|
|
|
{
|
|
|
|
hConOut = hDev;
|
|
|
|
state = 1;
|
2011-02-26 17:14:21 +10:00
|
|
|
shifted = FALSE;
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
2010-12-16 16:00:56 +10:00
|
|
|
for (i = nNumberOfBytesToWrite, s = (LPCTSTR)lpBuffer; i > 0; i--, s++)
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
|
|
|
if (state == 1)
|
|
|
|
{
|
|
|
|
if (*s == ESC) state = 2;
|
2011-02-26 17:14:21 +10:00
|
|
|
else if (*s == SO) shifted = TRUE;
|
|
|
|
else if (*s == SI) shifted = FALSE;
|
|
|
|
else PushBuffer( *s );
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
|
|
|
else if (state == 2)
|
|
|
|
{
|
|
|
|
if (*s == ESC) ; // \e\e...\e == \e
|
2011-02-26 17:14:21 +10:00
|
|
|
else if ((*s == '[') || (*s == ']'))
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
|
|
|
FlushBuffer();
|
2010-12-12 21:58:35 +10:00
|
|
|
prefix = *s;
|
|
|
|
prefix2 = 0;
|
2010-11-08 15:31:01 +10:00
|
|
|
state = 3;
|
2010-12-12 21:58:35 +10:00
|
|
|
Pt_len = 0;
|
|
|
|
*Pt_arg = '\0';
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
2011-02-26 17:14:21 +10:00
|
|
|
else if (*s == ')' || *s == '(') state = 6;
|
2010-11-08 15:31:01 +10:00
|
|
|
else state = 1;
|
|
|
|
}
|
|
|
|
else if (state == 3)
|
|
|
|
{
|
2012-11-24 23:41:29 +10:00
|
|
|
if (is_digit( *s ))
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
|
|
|
es_argc = 0;
|
|
|
|
es_argv[0] = *s - '0';
|
|
|
|
state = 4;
|
|
|
|
}
|
|
|
|
else if (*s == ';')
|
|
|
|
{
|
|
|
|
es_argc = 1;
|
|
|
|
es_argv[0] = 0;
|
|
|
|
es_argv[1] = 0;
|
|
|
|
state = 4;
|
|
|
|
}
|
2010-12-12 21:58:35 +10:00
|
|
|
else if (*s == '?' || *s == '>')
|
|
|
|
{
|
|
|
|
prefix2 = *s;
|
|
|
|
}
|
2010-11-08 15:31:01 +10:00
|
|
|
else
|
|
|
|
{
|
|
|
|
es_argc = 0;
|
|
|
|
suffix = *s;
|
|
|
|
InterpretEscSeq();
|
|
|
|
state = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (state == 4)
|
|
|
|
{
|
2012-11-24 23:41:29 +10:00
|
|
|
if (is_digit( *s ))
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
|
|
|
es_argv[es_argc] = 10 * es_argv[es_argc] + (*s - '0');
|
|
|
|
}
|
|
|
|
else if (*s == ';')
|
|
|
|
{
|
|
|
|
if (es_argc < MAX_ARG-1) es_argc++;
|
2010-12-12 21:58:35 +10:00
|
|
|
es_argv[es_argc] = 0;
|
|
|
|
if (prefix == ']')
|
|
|
|
state = 5;
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
es_argc++;
|
|
|
|
suffix = *s;
|
|
|
|
InterpretEscSeq();
|
|
|
|
state = 1;
|
|
|
|
}
|
|
|
|
}
|
2010-12-12 21:58:35 +10:00
|
|
|
else if (state == 5)
|
|
|
|
{
|
|
|
|
if (*s == BEL)
|
|
|
|
{
|
|
|
|
Pt_arg[Pt_len] = '\0';
|
|
|
|
InterpretEscSeq();
|
|
|
|
state = 1;
|
|
|
|
}
|
|
|
|
else if (*s == '\\' && Pt_len > 0 && Pt_arg[Pt_len-1] == ESC)
|
|
|
|
{
|
|
|
|
Pt_arg[--Pt_len] = '\0';
|
|
|
|
InterpretEscSeq();
|
|
|
|
state = 1;
|
|
|
|
}
|
|
|
|
else if (Pt_len < lenof(Pt_arg)-1)
|
|
|
|
Pt_arg[Pt_len++] = *s;
|
|
|
|
}
|
2011-02-26 17:14:21 +10:00
|
|
|
else if (state == 6)
|
|
|
|
{
|
|
|
|
// Ignore it (ESC ) 0 is implicit; nothing else is supported).
|
|
|
|
state = 1;
|
|
|
|
}
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
|
|
|
FlushBuffer();
|
2010-12-04 15:19:36 +10:00
|
|
|
if (lpNumberOfBytesWritten != NULL)
|
|
|
|
*lpNumberOfBytesWritten = nNumberOfBytesToWrite - i;
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
return (i == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ========== Hooking API functions
|
|
|
|
//
|
|
|
|
// References about API hooking (and dll injection):
|
|
|
|
// - Matt Pietrek ~ Windows 95 System Programming Secrets.
|
|
|
|
// - Jeffrey Richter ~ Programming Applications for Microsoft Windows 4th ed.
|
|
|
|
|
|
|
|
// Macro for adding pointers/DWORDs together without C arithmetic interfering
|
|
|
|
#define MakeVA( cast, offset ) (cast)((DWORD_PTR)(pDosHeader)+(DWORD)(offset))
|
|
|
|
|
|
|
|
|
|
|
|
const char APIKernel[] = "kernel32.dll";
|
2012-01-15 15:24:01 +10:00
|
|
|
const char APIConsole[] = "API-MS-Win-Core-Console-";
|
|
|
|
const char APIProcessThreads[] = "API-MS-Win-Core-ProcessThreads-";
|
|
|
|
const char APIProcessEnvironment[] = "API-MS-Win-Core-ProcessEnvironment-";
|
|
|
|
const char APILibraryLoader[] = "API-MS-Win-Core-LibraryLoader-";
|
|
|
|
const char APIFile[] = "API-MS-Win-Core-File-";
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
|
2012-01-15 15:24:01 +10:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
PCSTR name;
|
|
|
|
DWORD len;
|
|
|
|
HMODULE base;
|
|
|
|
} API_DATA, *PAPI_DATA;
|
|
|
|
|
|
|
|
API_DATA APIs[] =
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
{
|
2012-01-15 15:24:01 +10:00
|
|
|
{ APIConsole, sizeof(APIConsole) - 1, NULL },
|
|
|
|
{ APIProcessThreads, sizeof(APIProcessThreads) - 1, NULL },
|
|
|
|
{ APIProcessEnvironment, sizeof(APIProcessEnvironment) - 1, NULL },
|
|
|
|
{ APILibraryLoader, sizeof(APILibraryLoader) - 1, NULL },
|
|
|
|
{ APIFile, sizeof(APIFile) - 1, NULL },
|
|
|
|
{ NULL, 0, NULL }
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
HMODULE hKernel; // Kernel32 module handle
|
|
|
|
HINSTANCE hDllInstance; // Dll instance handle
|
|
|
|
TCHAR hDllName[MAX_PATH]; // Dll file name
|
2012-04-10 15:39:58 +10:00
|
|
|
#if defined(_WIN64) || defined(W32ON64)
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
LPTSTR hDllNameType; // pointer to process type within above
|
|
|
|
#endif
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
PCSTR lib;
|
|
|
|
PSTR name;
|
|
|
|
PROC newfunc;
|
|
|
|
PROC oldfunc;
|
|
|
|
PROC apifunc;
|
|
|
|
} HookFn, *PHookFn;
|
|
|
|
|
|
|
|
HookFn Hooks[];
|
|
|
|
|
|
|
|
const WCHAR zIgnoring[] = L"Ignoring";
|
|
|
|
const WCHAR zHooking[] = L"Hooking";
|
|
|
|
const WCHAR zUnhooking[] = L"Unhooking";
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// HookAPIOneMod
|
|
|
|
// Substitute a new function in the Import Address Table (IAT) of the
|
|
|
|
// specified module.
|
|
|
|
// Return FALSE on error and TRUE on success.
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
BOOL HookAPIOneMod(
|
|
|
|
HMODULE hFromModule, // Handle of the module to intercept calls from
|
|
|
|
PHookFn Hooks, // Functions to replace
|
|
|
|
BOOL restore // Restore the original functions
|
|
|
|
)
|
|
|
|
{
|
|
|
|
PIMAGE_DOS_HEADER pDosHeader;
|
|
|
|
PIMAGE_NT_HEADERS pNTHeader;
|
|
|
|
PIMAGE_IMPORT_DESCRIPTOR pImportDesc;
|
|
|
|
PIMAGE_THUNK_DATA pThunk;
|
|
|
|
PHookFn hook;
|
|
|
|
|
|
|
|
// Tests to make sure we're looking at a module image (the 'MZ' header)
|
|
|
|
pDosHeader = (PIMAGE_DOS_HEADER)hFromModule;
|
|
|
|
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
|
|
|
|
{
|
|
|
|
DEBUGSTR( 1, L"Image has no DOS header!" );
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The MZ header has a pointer to the PE header
|
|
|
|
pNTHeader = MakeVA( PIMAGE_NT_HEADERS, pDosHeader->e_lfanew );
|
|
|
|
|
|
|
|
// One more test to make sure we're looking at a "PE" image
|
|
|
|
if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
|
|
|
|
{
|
|
|
|
DEBUGSTR( 1, L"Image has no NT header!" );
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// We now have a valid pointer to the module's PE header.
|
|
|
|
// Get a pointer to its imports section.
|
|
|
|
pImportDesc = MakeVA( PIMAGE_IMPORT_DESCRIPTOR,
|
|
|
|
pNTHeader->OptionalHeader.
|
|
|
|
DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].
|
|
|
|
VirtualAddress );
|
|
|
|
|
|
|
|
// Bail out if the RVA of the imports section is 0 (it doesn't exist)
|
|
|
|
if (pImportDesc == (PIMAGE_IMPORT_DESCRIPTOR)pDosHeader)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
// Iterate through the array of imported module descriptors, looking
|
|
|
|
// for the module whose name matches the pszFunctionModule parameter.
|
|
|
|
for (; pImportDesc->Name; pImportDesc++)
|
|
|
|
{
|
2012-01-15 15:24:01 +10:00
|
|
|
BOOL kernel = TRUE;
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
PSTR pszModName = MakeVA( PSTR, pImportDesc->Name );
|
2012-01-15 15:24:01 +10:00
|
|
|
if (_stricmp( pszModName, APIKernel ) != 0)
|
|
|
|
{
|
|
|
|
PAPI_DATA lib;
|
|
|
|
for (lib = APIs; lib->name; ++lib)
|
|
|
|
{
|
|
|
|
if (_strnicmp( pszModName, lib->name, lib->len ) == 0)
|
|
|
|
{
|
|
|
|
if (lib->base == NULL)
|
|
|
|
{
|
|
|
|
lib->base = GetModuleHandleA( pszModName );
|
|
|
|
for (hook = Hooks; hook->name; ++hook)
|
|
|
|
if (hook->lib == lib->name)
|
|
|
|
hook->apifunc = GetProcAddress( lib->base, hook->name );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (lib->name == NULL)
|
|
|
|
{
|
|
|
|
if (log_level & 16)
|
|
|
|
DEBUGSTR( 2, L" %s %S", zIgnoring, pszModName );
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
kernel = FALSE;
|
|
|
|
}
|
|
|
|
if (log_level & 16)
|
|
|
|
DEBUGSTR( 2, L" Scanning %S", pszModName );
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
|
|
|
|
// Get a pointer to the found module's import address table (IAT).
|
|
|
|
pThunk = MakeVA( PIMAGE_THUNK_DATA, pImportDesc->FirstThunk );
|
|
|
|
|
|
|
|
// Blast through the table of import addresses, looking for the ones
|
|
|
|
// that match the original addresses.
|
|
|
|
while (pThunk->u1.Function)
|
|
|
|
{
|
|
|
|
for (hook = Hooks; hook->name; ++hook)
|
|
|
|
{
|
|
|
|
PROC patch = 0;
|
|
|
|
if (restore)
|
|
|
|
{
|
|
|
|
if ((PROC)pThunk->u1.Function == hook->newfunc)
|
2012-01-15 15:24:01 +10:00
|
|
|
patch = (kernel) ? hook->oldfunc : hook->apifunc;
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
}
|
|
|
|
else if ((PROC)pThunk->u1.Function == hook->oldfunc ||
|
|
|
|
(PROC)pThunk->u1.Function == hook->apifunc)
|
|
|
|
{
|
|
|
|
patch = hook->newfunc;
|
|
|
|
}
|
|
|
|
if (patch)
|
|
|
|
{
|
|
|
|
DWORD flOldProtect, flNewProtect, flDummy;
|
|
|
|
MEMORY_BASIC_INFORMATION mbi;
|
|
|
|
|
|
|
|
DEBUGSTR( 3, L" %S", hook->name );
|
|
|
|
// Get the current protection attributes.
|
|
|
|
VirtualQuery( &pThunk->u1.Function, &mbi, sizeof(mbi) );
|
|
|
|
// Take the access protection flags.
|
|
|
|
flNewProtect = mbi.Protect;
|
|
|
|
// Remove ReadOnly and ExecuteRead flags.
|
|
|
|
flNewProtect &= ~(PAGE_READONLY | PAGE_EXECUTE_READ);
|
|
|
|
// Add on ReadWrite flag
|
|
|
|
flNewProtect |= (PAGE_READWRITE);
|
|
|
|
// Change the access protection on the region of committed pages in the
|
|
|
|
// virtual address space of the current process.
|
|
|
|
VirtualProtect( &pThunk->u1.Function, sizeof(PVOID),
|
|
|
|
flNewProtect, &flOldProtect );
|
|
|
|
|
|
|
|
// Overwrite the original address with the address of the new function.
|
|
|
|
if (!WriteProcessMemory( GetCurrentProcess(),
|
|
|
|
&pThunk->u1.Function,
|
|
|
|
&patch, sizeof(patch), NULL ))
|
|
|
|
{
|
|
|
|
DEBUGSTR( 1, L"Could not patch!" );
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Put the page attributes back the way they were.
|
|
|
|
VirtualProtect( &pThunk->u1.Function, sizeof(PVOID),
|
|
|
|
flOldProtect, &flDummy );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pThunk++; // Advance to next imported function address
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE; // Function not found
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// HookAPIAllMod
|
|
|
|
// Substitute a new function in the Import Address Table (IAT) of all
|
|
|
|
// the modules in the current process.
|
|
|
|
// Return FALSE on error and TRUE on success.
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
BOOL HookAPIAllMod( PHookFn Hooks, BOOL restore )
|
|
|
|
{
|
|
|
|
HANDLE hModuleSnap;
|
|
|
|
MODULEENTRY32 me;
|
|
|
|
BOOL fOk;
|
|
|
|
|
|
|
|
// Take a snapshot of all modules in the current process.
|
|
|
|
hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE,
|
|
|
|
GetCurrentProcessId() );
|
|
|
|
|
|
|
|
if (hModuleSnap == INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
DEBUGSTR( 1, L"Failed to create snapshot!" );
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fill the size of the structure before using it.
|
|
|
|
me.dwSize = sizeof(MODULEENTRY32);
|
|
|
|
|
|
|
|
// Walk the module list of the modules.
|
|
|
|
for (fOk = Module32First( hModuleSnap, &me ); fOk;
|
|
|
|
fOk = Module32Next( hModuleSnap, &me ))
|
|
|
|
{
|
|
|
|
// We don't hook functions in our own module.
|
|
|
|
if (me.hModule != hDllInstance && me.hModule != hKernel)
|
|
|
|
{
|
|
|
|
if (search_env( L"ANSICON_EXC", me.szModule ))
|
|
|
|
{
|
|
|
|
DEBUGSTR( 2, L"%s %s", zIgnoring, me.szModule );
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
DEBUGSTR( 2, L"%s %s", (restore) ? zUnhooking : zHooking, me.szModule );
|
|
|
|
// Hook this function in this module.
|
|
|
|
if (!HookAPIOneMod( me.hModule, Hooks, restore ))
|
|
|
|
{
|
|
|
|
CloseHandle( hModuleSnap );
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CloseHandle( hModuleSnap );
|
2012-01-07 15:34:43 +10:00
|
|
|
DEBUGSTR( 2, L"%s completed", (restore) ? zUnhooking : zHooking );
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
return TRUE;
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ========== Child process injection
|
|
|
|
|
|
|
|
// Inject code into the target process to load our DLL.
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
void Inject( DWORD dwCreationFlags, LPPROCESS_INFORMATION lpi,
|
2012-06-12 14:38:00 +10:00
|
|
|
LPPROCESS_INFORMATION child_pi,
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
BOOL wide, LPCVOID lpApp, LPCVOID lpCmd )
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
int type;
|
|
|
|
BOOL gui;
|
|
|
|
|
2012-06-12 14:38:00 +10:00
|
|
|
type = ProcessType( child_pi, &gui );
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
if (gui)
|
|
|
|
{
|
|
|
|
TCHAR app[MAX_PATH];
|
|
|
|
LPTSTR name;
|
|
|
|
LPCTSTR term = L" \t";
|
|
|
|
|
|
|
|
app[MAX_PATH-1] = '\0';
|
|
|
|
if (lpApp == NULL)
|
|
|
|
{
|
|
|
|
// Extract the program from the command line. I would use
|
|
|
|
// GetModuleFileNameEx, but it doesn't work when a process is created
|
|
|
|
// suspended and setting up a delay until it does work sometimes
|
|
|
|
// prevents the process running at all. GetProcessImageFileName works,
|
|
|
|
// but it's not supported in 2K.
|
|
|
|
if (wide)
|
|
|
|
{
|
|
|
|
LPCTSTR pos;
|
|
|
|
for (pos = lpCmd; *pos == ' ' || *pos == '\t'; ++pos) ;
|
|
|
|
if (*pos == '"')
|
|
|
|
{
|
|
|
|
term = L"\"";
|
|
|
|
++pos;
|
|
|
|
}
|
|
|
|
wcsncpy( app, pos, MAX_PATH-1 );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LPCSTR pos;
|
|
|
|
for (pos = lpCmd; *pos == ' ' || *pos == '\t'; ++pos) ;
|
|
|
|
if (*pos == '"')
|
|
|
|
{
|
|
|
|
term = L"\"";
|
|
|
|
++pos;
|
|
|
|
}
|
|
|
|
MultiByteToWideChar( CP_ACP, 0, pos, -1, app, MAX_PATH );
|
|
|
|
}
|
|
|
|
// CreateProcess only works with surrounding quotes ('"a name"' works, but
|
|
|
|
// 'a" "name' fails), so that's all I'll test, too. However, it also
|
|
|
|
// tests for a file at each separator ('a name' tries "a.exe" before
|
|
|
|
// "a name.exe") which I won't do.
|
|
|
|
name = wcspbrk( app, term );
|
|
|
|
if (name)
|
|
|
|
*name = '\0';
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (wide)
|
|
|
|
wcsncpy( app, lpApp, MAX_PATH-1 );
|
|
|
|
else
|
|
|
|
MultiByteToWideChar( CP_ACP, 0, lpApp, -1, app, MAX_PATH );
|
|
|
|
}
|
|
|
|
name = get_program_name( app );
|
|
|
|
if (!search_env( L"ANSICON_GUI", name ))
|
|
|
|
{
|
|
|
|
DEBUGSTR( 1, L" %s", zIgnoring );
|
|
|
|
type = 0;
|
|
|
|
}
|
|
|
|
}
|
2010-12-04 15:19:36 +10:00
|
|
|
if (type != 0)
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
|
|
|
#ifdef _WIN64
|
2010-12-22 18:47:45 +10:00
|
|
|
if (type == 32)
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
hDllNameType[0] = '3';
|
|
|
|
hDllNameType[1] = '2';
|
2012-06-12 14:38:00 +10:00
|
|
|
InjectDLL32( child_pi, hDllName );
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
hDllNameType[0] = '6';
|
|
|
|
hDllNameType[1] = '4';
|
2012-06-12 14:38:00 +10:00
|
|
|
InjectDLL64( child_pi, hDllName );
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
|
|
|
#else
|
2012-04-10 15:39:58 +10:00
|
|
|
#ifdef W32ON64
|
|
|
|
if (type == 64)
|
|
|
|
{
|
|
|
|
TCHAR args[64];
|
|
|
|
STARTUPINFO si;
|
|
|
|
PROCESS_INFORMATION pi;
|
|
|
|
wcscpy( hDllNameType, L"CON.exe" );
|
|
|
|
wsprintf( args, L"ansicon -P%lu:%lu",
|
2012-06-12 14:38:00 +10:00
|
|
|
child_pi->dwProcessId, child_pi->dwThreadId );
|
2012-04-10 15:39:58 +10:00
|
|
|
ZeroMemory( &si, sizeof(si) );
|
|
|
|
si.cb = sizeof(si);
|
|
|
|
if (CreateProcess( hDllName, args, NULL, NULL, FALSE, 0, NULL, NULL,
|
|
|
|
&si, &pi ))
|
|
|
|
{
|
|
|
|
WaitForSingleObject( pi.hProcess, INFINITE );
|
|
|
|
CloseHandle( pi.hProcess );
|
|
|
|
CloseHandle( pi.hThread );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
DEBUGSTR( 1, L"Could not execute \"%s\"", hDllName );
|
|
|
|
wcscpy( hDllNameType, L"32.dll" );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
2012-06-12 14:38:00 +10:00
|
|
|
InjectDLL32( child_pi, hDllName );
|
2010-11-08 15:31:01 +10:00
|
|
|
#endif
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
if (!gui && !(dwCreationFlags & (CREATE_NEW_CONSOLE | DETACHED_PROCESS)))
|
|
|
|
{
|
2012-06-12 14:38:00 +10:00
|
|
|
LPPROCESS_INFORMATION cpi;
|
|
|
|
s_pid = child_pi->dwProcessId;
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
s_grm = grm;
|
|
|
|
s_flag = GRM_INIT;
|
2012-06-12 14:38:00 +10:00
|
|
|
cpi = malloc( sizeof(*cpi) );
|
|
|
|
cpi->dwProcessId = child_pi->dwProcessId;
|
|
|
|
DuplicateHandle( GetCurrentProcess(), child_pi->hProcess,
|
|
|
|
GetCurrentProcess(), &cpi->hProcess, 0, FALSE,
|
|
|
|
DUPLICATE_SAME_ACCESS );
|
|
|
|
CloseHandle( CreateThread( NULL, 4096, UpdateGRM, cpi, 0, NULL ) );
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
}
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!(dwCreationFlags & CREATE_SUSPENDED))
|
2012-06-12 14:38:00 +10:00
|
|
|
ResumeThread( child_pi->hThread );
|
2010-12-16 16:00:56 +10:00
|
|
|
|
|
|
|
if (lpi)
|
|
|
|
{
|
2012-06-12 14:38:00 +10:00
|
|
|
memcpy( lpi, child_pi, sizeof(PROCESS_INFORMATION) );
|
2010-12-16 16:00:56 +10:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-06-12 14:38:00 +10:00
|
|
|
CloseHandle( child_pi->hThread );
|
|
|
|
CloseHandle( child_pi->hProcess );
|
2010-12-16 16:00:56 +10:00
|
|
|
}
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOL WINAPI MyCreateProcessA( LPCSTR lpApplicationName,
|
|
|
|
LPSTR lpCommandLine,
|
|
|
|
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
|
|
|
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
|
|
|
BOOL bInheritHandles,
|
|
|
|
DWORD dwCreationFlags,
|
|
|
|
LPVOID lpEnvironment,
|
|
|
|
LPCSTR lpCurrentDirectory,
|
|
|
|
LPSTARTUPINFOA lpStartupInfo,
|
|
|
|
LPPROCESS_INFORMATION lpProcessInformation )
|
|
|
|
{
|
2012-06-12 14:38:00 +10:00
|
|
|
PROCESS_INFORMATION child_pi;
|
|
|
|
|
2010-11-08 15:31:01 +10:00
|
|
|
if (!CreateProcessA( lpApplicationName,
|
|
|
|
lpCommandLine,
|
|
|
|
lpThreadAttributes,
|
|
|
|
lpProcessAttributes,
|
|
|
|
bInheritHandles,
|
|
|
|
dwCreationFlags | CREATE_SUSPENDED,
|
|
|
|
lpEnvironment,
|
|
|
|
lpCurrentDirectory,
|
|
|
|
lpStartupInfo,
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
&child_pi ))
|
2010-11-08 15:31:01 +10:00
|
|
|
return FALSE;
|
|
|
|
|
2012-06-12 14:38:00 +10:00
|
|
|
DEBUGSTR( 1, L"CreateProcessA: (%lu) \"%S\", \"%S\"",
|
|
|
|
child_pi.dwProcessId,
|
2010-11-08 15:31:01 +10:00
|
|
|
(lpApplicationName == NULL) ? "" : lpApplicationName,
|
|
|
|
(lpCommandLine == NULL) ? "" : lpCommandLine );
|
2012-06-12 14:38:00 +10:00
|
|
|
Inject( dwCreationFlags, lpProcessInformation, &child_pi,
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
FALSE, lpApplicationName, lpCommandLine );
|
2010-11-08 15:31:01 +10:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOL WINAPI MyCreateProcessW( LPCWSTR lpApplicationName,
|
|
|
|
LPWSTR lpCommandLine,
|
|
|
|
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
|
|
|
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
|
|
|
BOOL bInheritHandles,
|
|
|
|
DWORD dwCreationFlags,
|
|
|
|
LPVOID lpEnvironment,
|
|
|
|
LPCWSTR lpCurrentDirectory,
|
|
|
|
LPSTARTUPINFOW lpStartupInfo,
|
|
|
|
LPPROCESS_INFORMATION lpProcessInformation )
|
|
|
|
{
|
2012-06-12 14:38:00 +10:00
|
|
|
PROCESS_INFORMATION child_pi;
|
|
|
|
|
2010-11-08 15:31:01 +10:00
|
|
|
if (!CreateProcessW( lpApplicationName,
|
|
|
|
lpCommandLine,
|
|
|
|
lpThreadAttributes,
|
|
|
|
lpProcessAttributes,
|
|
|
|
bInheritHandles,
|
|
|
|
dwCreationFlags | CREATE_SUSPENDED,
|
|
|
|
lpEnvironment,
|
|
|
|
lpCurrentDirectory,
|
|
|
|
lpStartupInfo,
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
&child_pi ))
|
2010-11-08 15:31:01 +10:00
|
|
|
return FALSE;
|
|
|
|
|
2012-06-12 14:38:00 +10:00
|
|
|
DEBUGSTR( 1, L"CreateProcessW: (%lu) \"%s\", \"%s\"",
|
|
|
|
child_pi.dwProcessId,
|
2010-11-08 15:31:01 +10:00
|
|
|
(lpApplicationName == NULL) ? L"" : lpApplicationName,
|
|
|
|
(lpCommandLine == NULL) ? L"" : lpCommandLine );
|
2012-06-12 14:38:00 +10:00
|
|
|
Inject( dwCreationFlags, lpProcessInformation, &child_pi,
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
TRUE, lpApplicationName, lpCommandLine );
|
2010-11-08 15:31:01 +10:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-02-26 01:12:35 +10:00
|
|
|
FARPROC WINAPI MyGetProcAddress( HMODULE hModule, LPCSTR lpProcName )
|
|
|
|
{
|
|
|
|
PHookFn hook;
|
|
|
|
FARPROC proc;
|
|
|
|
|
|
|
|
proc = GetProcAddress( hModule, lpProcName );
|
|
|
|
|
|
|
|
if (proc)
|
|
|
|
{
|
|
|
|
if (hModule == hKernel)
|
|
|
|
{
|
|
|
|
// Ignore LoadLibrary so other hooks continue to work (our version
|
|
|
|
// might end up at a different address).
|
|
|
|
if (proc == Hooks[0].oldfunc || proc == Hooks[1].oldfunc)
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
{
|
|
|
|
DEBUGSTR( 3, L"GetProcAddress: %S (ignoring)", lpProcName );
|
2011-02-26 01:12:35 +10:00
|
|
|
return proc;
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
}
|
2012-01-15 15:24:01 +10:00
|
|
|
for (hook = Hooks + 2; hook->name; ++hook)
|
2011-02-26 01:12:35 +10:00
|
|
|
{
|
|
|
|
if (proc == hook->oldfunc)
|
|
|
|
{
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
DEBUGSTR( 3, L"GetProcAddress: %S", lpProcName );
|
2011-02-26 01:12:35 +10:00
|
|
|
return hook->newfunc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-01-15 15:24:01 +10:00
|
|
|
else
|
2011-02-26 01:12:35 +10:00
|
|
|
{
|
2012-01-15 15:24:01 +10:00
|
|
|
PAPI_DATA api;
|
|
|
|
for (api = APIs; api->name; ++api)
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
{
|
2012-01-15 15:24:01 +10:00
|
|
|
if (hModule == api->base)
|
2011-02-26 01:12:35 +10:00
|
|
|
{
|
2012-01-15 15:24:01 +10:00
|
|
|
if (proc == Hooks[0].apifunc || proc == Hooks[1].apifunc)
|
|
|
|
{
|
|
|
|
DEBUGSTR( 3, L"GetProcAddress: %S (ignoring)", lpProcName );
|
|
|
|
return proc;
|
|
|
|
}
|
|
|
|
for (hook = Hooks + 2; hook->name; ++hook)
|
|
|
|
{
|
|
|
|
if (proc == hook->apifunc)
|
|
|
|
{
|
|
|
|
DEBUGSTR( 3, L"GetProcAddress: %S", lpProcName );
|
|
|
|
return hook->newfunc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2011-02-26 01:12:35 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return proc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
void HookLibrary( HMODULE hMod, LPCVOID lpFileName, BOOL wide, LPCSTR funcName )
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
LPCWSTR name;
|
|
|
|
WCHAR wname[MAX_PATH];
|
|
|
|
|
2014-01-25 23:43:41 +10:00
|
|
|
if (hMod && hMod != hKernel && hMod != hDllInstance)
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
if (!wide)
|
|
|
|
{
|
|
|
|
MultiByteToWideChar( AreFileApisANSI() ? CP_ACP : CP_OEMCP, 0,
|
|
|
|
lpFileName, -1, wname, MAX_PATH );
|
|
|
|
lpFileName = wname;
|
|
|
|
}
|
|
|
|
name = wcsrchr( lpFileName, '\\' );
|
|
|
|
if (name == NULL)
|
|
|
|
name = lpFileName;
|
|
|
|
else
|
|
|
|
++name;
|
|
|
|
if (search_env( L"ANSICON_EXC", name ))
|
|
|
|
DEBUGSTR( 2, L"%s %s (%S)", zIgnoring, lpFileName, funcName );
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DEBUGSTR( 2, L"%s %s (%S)", zHooking, lpFileName, funcName );
|
|
|
|
HookAPIOneMod( hMod, Hooks, FALSE );
|
|
|
|
}
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HMODULE WINAPI MyLoadLibraryA( LPCSTR lpFileName )
|
|
|
|
{
|
|
|
|
HMODULE hMod = LoadLibraryA( lpFileName );
|
|
|
|
HookLibrary( hMod, lpFileName, FALSE, "LoadLibraryA" );
|
2010-11-08 15:31:01 +10:00
|
|
|
return hMod;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HMODULE WINAPI MyLoadLibraryW( LPCWSTR lpFileName )
|
|
|
|
{
|
|
|
|
HMODULE hMod = LoadLibraryW( lpFileName );
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
HookLibrary( hMod, lpFileName, TRUE, "LoadLibraryW" );
|
2010-11-08 15:31:01 +10:00
|
|
|
return hMod;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HMODULE WINAPI MyLoadLibraryExA( LPCSTR lpFileName, HANDLE hFile,
|
|
|
|
DWORD dwFlags )
|
|
|
|
{
|
|
|
|
HMODULE hMod = LoadLibraryExA( lpFileName, hFile, dwFlags );
|
2014-01-25 23:43:41 +10:00
|
|
|
if (!(dwFlags & (LOAD_LIBRARY_AS_DATAFILE |
|
|
|
|
LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE |
|
|
|
|
LOAD_LIBRARY_AS_IMAGE_RESOURCE)))
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
HookLibrary( hMod, lpFileName, FALSE, "LoadLibraryExA" );
|
2010-11-08 15:31:01 +10:00
|
|
|
return hMod;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HMODULE WINAPI MyLoadLibraryExW( LPCWSTR lpFileName, HANDLE hFile,
|
|
|
|
DWORD dwFlags )
|
|
|
|
{
|
|
|
|
HMODULE hMod = LoadLibraryExW( lpFileName, hFile, dwFlags );
|
2014-01-25 23:43:41 +10:00
|
|
|
if (!(dwFlags & (LOAD_LIBRARY_AS_DATAFILE |
|
|
|
|
LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE |
|
|
|
|
LOAD_LIBRARY_AS_IMAGE_RESOURCE)))
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
HookLibrary( hMod, lpFileName, TRUE, "LoadLibraryExW" );
|
2010-11-08 15:31:01 +10:00
|
|
|
return hMod;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-08-02 23:21:07 +10:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// IsConsoleHandle
|
|
|
|
// Determine if the handle is writing to the console, with processed output.
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
BOOL IsConsoleHandle( HANDLE h )
|
|
|
|
{
|
|
|
|
DWORD mode;
|
|
|
|
|
|
|
|
if (!GetConsoleMode( h, &mode ))
|
|
|
|
{
|
|
|
|
// This fails if the handle isn't opened for reading. Fortunately, it
|
|
|
|
// seems WriteConsole tests the handle before it tests the length.
|
|
|
|
return WriteConsole( h, NULL, 0, &mode, NULL );
|
|
|
|
}
|
|
|
|
|
|
|
|
return (mode & ENABLE_PROCESSED_OUTPUT);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-08 15:31:01 +10:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// MyWrite...
|
2013-08-02 23:21:07 +10:00
|
|
|
// The new functions that must replace the original Write... functions. These
|
|
|
|
// functions have exactly the same signature as the original ones. This
|
|
|
|
// module is not hooked, so we can still call the original functions ourselves.
|
2010-11-08 15:31:01 +10:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
BOOL
|
|
|
|
WINAPI MyWriteConsoleA( HANDLE hCon, LPCVOID lpBuffer,
|
|
|
|
DWORD nNumberOfCharsToWrite,
|
|
|
|
LPDWORD lpNumberOfCharsWritten, LPVOID lpReserved )
|
|
|
|
{
|
2010-11-13 14:49:27 +10:00
|
|
|
LPWSTR buf;
|
|
|
|
DWORD len;
|
|
|
|
BOOL rc = TRUE;
|
2010-11-08 15:31:01 +10:00
|
|
|
|
2013-08-02 23:21:07 +10:00
|
|
|
if (IsConsoleHandle( hCon ))
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
|
|
|
UINT cp = GetConsoleOutputCP();
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
DEBUGSTR( 4, L"\33WriteConsoleA: %lu \"%.*S\"",
|
2010-12-12 23:32:22 +10:00
|
|
|
nNumberOfCharsToWrite, nNumberOfCharsToWrite, lpBuffer );
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
len = MultiByteToWideChar( cp, 0, lpBuffer, nNumberOfCharsToWrite, NULL,0 );
|
|
|
|
buf = malloc( TSIZE(len) );
|
2010-11-13 14:49:27 +10:00
|
|
|
if (buf == NULL)
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
2010-12-04 15:19:36 +10:00
|
|
|
if (lpNumberOfCharsWritten != NULL)
|
|
|
|
*lpNumberOfCharsWritten = 0;
|
2010-11-13 14:49:27 +10:00
|
|
|
return (nNumberOfCharsToWrite == 0);
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
2010-11-13 14:49:27 +10:00
|
|
|
MultiByteToWideChar( cp, 0, lpBuffer, nNumberOfCharsToWrite, buf, len );
|
|
|
|
rc = ParseAndPrintString( hCon, buf, len, lpNumberOfCharsWritten );
|
|
|
|
free( buf );
|
2010-12-12 23:32:22 +10:00
|
|
|
if (rc && lpNumberOfCharsWritten != NULL &&
|
|
|
|
*lpNumberOfCharsWritten != nNumberOfCharsToWrite)
|
2010-11-15 22:14:17 +10:00
|
|
|
{
|
|
|
|
// Converting a multibyte character to Unicode results in a different
|
|
|
|
// "character" count. This causes some programs to think not everything
|
|
|
|
// was written, so the difference is sent again. Fudge the (presumably)
|
|
|
|
// correct count.
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
if (search_env( L"ANSICON_API", prog ))
|
|
|
|
*lpNumberOfCharsWritten = nNumberOfCharsToWrite;
|
2010-11-15 22:14:17 +10:00
|
|
|
}
|
2010-11-08 15:31:01 +10:00
|
|
|
return rc;
|
|
|
|
}
|
2012-02-24 12:53:07 +10:00
|
|
|
|
|
|
|
return WriteConsoleA( hCon, lpBuffer, nNumberOfCharsToWrite,
|
|
|
|
lpNumberOfCharsWritten, lpReserved );
|
|
|
|
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
|
|
WINAPI MyWriteConsoleW( HANDLE hCon, LPCVOID lpBuffer,
|
|
|
|
DWORD nNumberOfCharsToWrite,
|
|
|
|
LPDWORD lpNumberOfCharsWritten, LPVOID lpReserved )
|
|
|
|
{
|
2013-08-02 23:21:07 +10:00
|
|
|
if (IsConsoleHandle( hCon ))
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
DEBUGSTR( 4, L"\33WriteConsoleW: %lu \"%.*s\"",
|
2010-12-12 23:32:22 +10:00
|
|
|
nNumberOfCharsToWrite, nNumberOfCharsToWrite, lpBuffer );
|
2010-11-08 15:31:01 +10:00
|
|
|
return ParseAndPrintString( hCon, lpBuffer,
|
|
|
|
nNumberOfCharsToWrite,
|
|
|
|
lpNumberOfCharsWritten );
|
|
|
|
}
|
2012-02-24 12:53:07 +10:00
|
|
|
|
|
|
|
return WriteConsoleW( hCon, lpBuffer, nNumberOfCharsToWrite,
|
|
|
|
lpNumberOfCharsWritten, lpReserved );
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
|
|
WINAPI MyWriteFile( HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
|
|
|
|
LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped )
|
|
|
|
{
|
2013-08-02 23:21:07 +10:00
|
|
|
if (IsConsoleHandle( hFile ))
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
DEBUGSTR( 4, L"WriteFile->" );
|
2010-11-08 15:31:01 +10:00
|
|
|
return MyWriteConsoleA( hFile, lpBuffer,
|
|
|
|
nNumberOfBytesToWrite,
|
|
|
|
lpNumberOfBytesWritten,
|
|
|
|
lpOverlapped );
|
|
|
|
}
|
2012-02-24 12:53:07 +10:00
|
|
|
|
|
|
|
return WriteFile( hFile, lpBuffer, nNumberOfBytesToWrite,
|
|
|
|
lpNumberOfBytesWritten, lpOverlapped );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#define HHFILE (HANDLE)(DWORD_PTR)
|
|
|
|
|
|
|
|
UINT
|
|
|
|
WINAPI My_lwrite( HFILE hFile, LPCSTR lpBuffer, UINT uBytes )
|
|
|
|
{
|
2013-08-02 23:21:07 +10:00
|
|
|
if (IsConsoleHandle( HHFILE hFile ))
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
2013-08-02 23:21:07 +10:00
|
|
|
DWORD written;
|
2012-02-24 12:53:07 +10:00
|
|
|
DEBUGSTR( 4, L"_lwrite->" );
|
|
|
|
MyWriteConsoleA( HHFILE hFile, lpBuffer, uBytes, &written, NULL );
|
|
|
|
return written;
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
2012-02-24 12:53:07 +10:00
|
|
|
|
|
|
|
return _lwrite( hFile, lpBuffer, uBytes );
|
|
|
|
}
|
|
|
|
|
|
|
|
long
|
|
|
|
WINAPI My_hwrite( HFILE hFile, LPCSTR lpBuffer, long lBytes )
|
|
|
|
{
|
2013-08-02 23:21:07 +10:00
|
|
|
if (IsConsoleHandle( HHFILE hFile ))
|
2012-02-24 12:53:07 +10:00
|
|
|
{
|
2013-08-02 23:21:07 +10:00
|
|
|
DWORD written;
|
2012-02-24 12:53:07 +10:00
|
|
|
DEBUGSTR( 4, L"_hwrite->" );
|
|
|
|
MyWriteConsoleA( HHFILE hFile, lpBuffer, lBytes, &written, NULL );
|
|
|
|
return written;
|
|
|
|
}
|
|
|
|
|
|
|
|
return _hwrite( hFile, lpBuffer, lBytes );
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ========== Environment variable
|
|
|
|
|
|
|
|
void set_ansicon( PCONSOLE_SCREEN_BUFFER_INFO pcsbi )
|
|
|
|
{
|
|
|
|
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
2010-11-15 21:51:38 +10:00
|
|
|
TCHAR buf[64];
|
2010-11-08 15:31:01 +10:00
|
|
|
|
|
|
|
if (pcsbi == NULL)
|
|
|
|
{
|
|
|
|
HANDLE hConOut;
|
2010-11-15 21:51:38 +10:00
|
|
|
hConOut = CreateFile( L"CONOUT$", GENERIC_READ | GENERIC_WRITE,
|
|
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
|
|
NULL, OPEN_EXISTING, 0, 0 );
|
2010-11-08 15:31:01 +10:00
|
|
|
GetConsoleScreenBufferInfo( hConOut, &csbi );
|
|
|
|
CloseHandle( hConOut );
|
|
|
|
pcsbi = &csbi;
|
|
|
|
}
|
|
|
|
|
2010-11-15 21:51:38 +10:00
|
|
|
wsprintf( buf, L"%dx%d (%dx%d)",
|
2010-11-08 15:31:01 +10:00
|
|
|
pcsbi->dwSize.X, pcsbi->dwSize.Y,
|
|
|
|
pcsbi->srWindow.Right - pcsbi->srWindow.Left + 1,
|
|
|
|
pcsbi->srWindow.Bottom - pcsbi->srWindow.Top + 1 );
|
2010-11-15 21:51:38 +10:00
|
|
|
SetEnvironmentVariable( L"ANSICON", buf );
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
DWORD
|
|
|
|
WINAPI MyGetEnvironmentVariableA( LPCSTR lpName, LPSTR lpBuffer, DWORD nSize )
|
|
|
|
{
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
if (lstrcmpiA( lpName, "ANSICON_VER" ) == 0)
|
|
|
|
{
|
|
|
|
if (nSize < sizeof(PVEREA))
|
|
|
|
return sizeof(PVEREA);
|
|
|
|
memcpy( lpBuffer, PVEREA, sizeof(PVEREA) );
|
|
|
|
return sizeof(PVEREA) - 1;
|
|
|
|
}
|
2012-02-24 12:53:07 +10:00
|
|
|
|
2010-11-08 15:31:01 +10:00
|
|
|
if (lstrcmpiA( lpName, "ANSICON" ) == 0)
|
|
|
|
set_ansicon( NULL );
|
2012-02-24 12:53:07 +10:00
|
|
|
|
2010-11-08 15:31:01 +10:00
|
|
|
return GetEnvironmentVariableA( lpName, lpBuffer, nSize );
|
|
|
|
}
|
|
|
|
|
|
|
|
DWORD
|
|
|
|
WINAPI MyGetEnvironmentVariableW( LPCWSTR lpName, LPWSTR lpBuffer, DWORD nSize )
|
|
|
|
{
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
if (lstrcmpi( lpName, L"ANSICON_VER" ) == 0)
|
|
|
|
{
|
|
|
|
if (nSize < lenof(PVERE))
|
|
|
|
return lenof(PVERE);
|
|
|
|
memcpy( lpBuffer, PVERE, sizeof(PVERE) );
|
|
|
|
return lenof(PVERE) - 1;
|
|
|
|
}
|
2012-02-24 12:53:07 +10:00
|
|
|
|
2010-11-15 21:51:38 +10:00
|
|
|
if (lstrcmpi( lpName, L"ANSICON" ) == 0)
|
2010-11-08 15:31:01 +10:00
|
|
|
set_ansicon( NULL );
|
2012-02-24 12:53:07 +10:00
|
|
|
|
2010-11-08 15:31:01 +10:00
|
|
|
return GetEnvironmentVariableW( lpName, lpBuffer, nSize );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ========== Initialisation
|
|
|
|
|
|
|
|
HookFn Hooks[] = {
|
2011-02-26 01:12:35 +10:00
|
|
|
// These two are expected first!
|
|
|
|
{ APILibraryLoader, "LoadLibraryA", (PROC)MyLoadLibraryA, NULL, NULL },
|
|
|
|
{ APILibraryLoader, "LoadLibraryW", (PROC)MyLoadLibraryW, NULL, NULL },
|
2010-11-08 15:31:01 +10:00
|
|
|
{ APIProcessThreads, "CreateProcessA", (PROC)MyCreateProcessA, NULL, NULL },
|
|
|
|
{ APIProcessThreads, "CreateProcessW", (PROC)MyCreateProcessW, NULL, NULL },
|
|
|
|
{ APIProcessEnvironment, "GetEnvironmentVariableA", (PROC)MyGetEnvironmentVariableA, NULL, NULL },
|
|
|
|
{ APIProcessEnvironment, "GetEnvironmentVariableW", (PROC)MyGetEnvironmentVariableW, NULL, NULL },
|
2011-02-26 01:12:35 +10:00
|
|
|
{ APILibraryLoader, "GetProcAddress", (PROC)MyGetProcAddress, NULL, NULL },
|
2010-11-08 15:31:01 +10:00
|
|
|
{ APILibraryLoader, "LoadLibraryExA", (PROC)MyLoadLibraryExA, NULL, NULL },
|
|
|
|
{ APILibraryLoader, "LoadLibraryExW", (PROC)MyLoadLibraryExW, NULL, NULL },
|
|
|
|
{ APIConsole, "WriteConsoleA", (PROC)MyWriteConsoleA, NULL, NULL },
|
|
|
|
{ APIConsole, "WriteConsoleW", (PROC)MyWriteConsoleW, NULL, NULL },
|
|
|
|
{ APIFile, "WriteFile", (PROC)MyWriteFile, NULL, NULL },
|
2012-02-24 12:53:07 +10:00
|
|
|
{ APIKernel, "_lwrite", (PROC)My_lwrite, NULL, NULL },
|
|
|
|
{ APIKernel, "_hwrite", (PROC)My_hwrite, NULL, NULL },
|
2012-01-15 15:24:01 +10:00
|
|
|
{ NULL, NULL, NULL, NULL, NULL }
|
2010-11-08 15:31:01 +10:00
|
|
|
};
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// OriginalAttr()
|
|
|
|
// Determine the original attributes for use by \e[m.
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void OriginalAttr( void )
|
|
|
|
{
|
|
|
|
HANDLE hConOut;
|
|
|
|
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
|
|
|
|
2010-11-15 21:51:38 +10:00
|
|
|
hConOut = CreateFile( L"CONOUT$", GENERIC_READ | GENERIC_WRITE,
|
|
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
|
|
NULL, OPEN_EXISTING, 0, 0 );
|
2010-11-08 15:31:01 +10:00
|
|
|
if (!GetConsoleScreenBufferInfo( hConOut, &csbi ))
|
|
|
|
csbi.wAttributes = 7;
|
|
|
|
CloseHandle( hConOut );
|
|
|
|
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
if (s_flag == GRM_INIT && s_pid == GetCurrentProcessId())
|
|
|
|
{
|
|
|
|
s_flag = 0;
|
|
|
|
grm = s_grm;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (GetEnvironmentVariable( L"ANSICON_REVERSE", NULL, 0 ))
|
|
|
|
{
|
|
|
|
SetEnvironmentVariable( L"ANSICON_REVERSE", NULL );
|
|
|
|
grm.reverse = TRUE;
|
|
|
|
grm.foreground = attr2ansi[(csbi.wAttributes >> 4) & 7];
|
|
|
|
grm.background = attr2ansi[csbi.wAttributes & 7];
|
|
|
|
grm.bold = (csbi.wAttributes & BACKGROUND_INTENSITY) >> 4;
|
|
|
|
grm.underline = (csbi.wAttributes & FOREGROUND_INTENSITY) << 4;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
grm.foreground = attr2ansi[csbi.wAttributes & 7];
|
|
|
|
grm.background = attr2ansi[(csbi.wAttributes >> 4) & 7];
|
|
|
|
grm.bold = csbi.wAttributes & FOREGROUND_INTENSITY;
|
|
|
|
grm.underline = csbi.wAttributes & BACKGROUND_INTENSITY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!GetEnvironmentVariable( L"ANSICON_DEF", NULL, 0 ))
|
|
|
|
{
|
|
|
|
TCHAR def[4];
|
|
|
|
LPTSTR a = def;
|
|
|
|
if (grm.reverse)
|
|
|
|
{
|
|
|
|
*a++ = '-';
|
|
|
|
csbi.wAttributes = ((csbi.wAttributes >> 4) & 15)
|
|
|
|
| ((csbi.wAttributes & 15) << 4);
|
|
|
|
}
|
|
|
|
wsprintf( a, L"%X", csbi.wAttributes & 255 );
|
|
|
|
SetEnvironmentVariable( L"ANSICON_DEF", def );
|
|
|
|
}
|
2010-11-08 15:31:01 +10:00
|
|
|
set_ansicon( &csbi );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// DllMain()
|
|
|
|
// Function called by the system when processes and threads are initialized
|
|
|
|
// and terminated.
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
2012-11-24 23:41:29 +10:00
|
|
|
__declspec(dllexport) // just to stop MinGW exporting everything
|
2010-11-08 15:31:01 +10:00
|
|
|
BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved )
|
|
|
|
{
|
|
|
|
BOOL bResult = TRUE;
|
|
|
|
PHookFn hook;
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
TCHAR logstr[4];
|
2010-11-08 15:31:01 +10:00
|
|
|
|
|
|
|
if (dwReason == DLL_PROCESS_ATTACH)
|
|
|
|
{
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
*logstr = '\0';
|
|
|
|
GetEnvironmentVariable( L"ANSICON_LOG", logstr, lenof(logstr) );
|
|
|
|
log_level = _wtoi( logstr );
|
|
|
|
prog = get_program_name( NULL );
|
2012-04-10 15:39:58 +10:00
|
|
|
#if defined(_WIN64) || defined(W32ON64)
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
hDllNameType = hDllName - 6 +
|
|
|
|
#endif
|
|
|
|
GetModuleFileName( hInstance, hDllName, lenof(hDllName) );
|
|
|
|
|
2010-11-08 15:31:01 +10:00
|
|
|
hDllInstance = hInstance; // save Dll instance handle
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
DEBUGSTR( 1, L"hDllInstance = %p", hDllInstance );
|
2010-11-08 15:31:01 +10:00
|
|
|
|
2014-01-27 14:03:53 +10:00
|
|
|
if (LLW32r == 0)
|
|
|
|
{
|
|
|
|
if (!get_LLW32r())
|
|
|
|
return FALSE;
|
|
|
|
#ifdef _WIN64
|
|
|
|
if (!get_LLW64r())
|
|
|
|
return FALSE;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2010-11-08 15:31:01 +10:00
|
|
|
// Get the entry points to the original functions.
|
|
|
|
hKernel = GetModuleHandleA( APIKernel );
|
|
|
|
for (hook = Hooks; hook->name; ++hook)
|
|
|
|
hook->oldfunc = GetProcAddress( hKernel, hook->name );
|
|
|
|
|
|
|
|
bResult = HookAPIAllMod( Hooks, FALSE );
|
|
|
|
OriginalAttr();
|
|
|
|
DisableThreadLibraryCalls( hInstance );
|
|
|
|
}
|
2010-12-16 16:00:56 +10:00
|
|
|
else if (dwReason == DLL_PROCESS_DETACH)
|
2010-11-08 15:31:01 +10:00
|
|
|
{
|
2010-12-16 16:00:56 +10:00
|
|
|
if (lpReserved == NULL)
|
|
|
|
{
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
DEBUGSTR( 1, L"Unloading" );
|
2010-12-16 16:00:56 +10:00
|
|
|
HookAPIAllMod( Hooks, TRUE );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
DEBUGSTR( 1, L"Terminating" );
|
|
|
|
s_pid = GetCurrentProcessId();
|
|
|
|
s_grm = grm;
|
|
|
|
s_flag = GRM_EXIT;
|
2010-12-16 16:00:56 +10:00
|
|
|
}
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|
|
|
|
|
Exclude modules from being hooked; hook only selected GUI programs.
Added environment variable ANSICON_EXC to specify modules that should not be
hooked. This should work around the nvd3d9wrap.dll issue. Since it helps to
know what the modules are, logging is now always available, controlled by -l
or ANSICON_LOG. A side-effect caused debugstr.c to move to util.c.
GUI programs are once again not hooked, unless run by "ansicon" directly or in
the ANSICON_GUI environment variable. Since not hooking still leaves ANSICON in
the environment, created ANSICON_VER as a dynamic-only variable, which can also
serve as a version check.
Due to an email requesting a reverse video option, realised I always take the
current attributes as default. This means if you turned on reverse and ran a
program, it would take the reverse as its default. Created ANSICON_DEF variable
to explicitly set the default attribute, using the current if it doesn't exist.
The reverse video option is done via a "negative" attribute (e.g. "-m-f0" is
reversed black on white, meaning you'll get white on black, with foreground
sequences changing the background). (The difference from "\e[7m" is that it
won't be reset on "\e[m".)
A child program will inherit the parent's modes (but not shift); the parent will
read the child's modes on exit (but not unload). The exception is "ansicon",
which will always start with the default modes and leave the parent unchanged.
Improved the AutoRun entry, only running "ansicon" if ANSICON_VER doesn't exist.
The "ansicon" command is always first.
Stopped -u implying -p; return the program's exit code; don't restore the
original color when just using -p; output error messages to stderr.
2011-12-14 20:53:51 +10:00
|
|
|
return bResult;
|
2010-11-08 15:31:01 +10:00
|
|
|
}
|