From 6fc87e3a068493c7bff30d3e3b0dd1099a175aae Mon Sep 17 00:00:00 2001
From: Jason Hood <jadoxa@yahoo.com.au>
Date: Fri, 24 Feb 2012 12:53:07 +1000
Subject: [PATCH] Hook _lwrite & _hwrite; release v1.51.

---
 ANSI.c     | 71 +++++++++++++++++++++++++++++++++++++++---------------
 ansicon.c  |  6 ++++-
 readme.txt | 15 +++++++++---
 version.h  | 10 ++++----
 4 files changed, 73 insertions(+), 29 deletions(-)

diff --git a/ANSI.c b/ANSI.c
index 0222bee..6c09260 100644
--- a/ANSI.c
+++ b/ANSI.c
@@ -75,6 +75,12 @@
     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.
+
+  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.
 */
 
 #include "ansicon.h"
@@ -1465,13 +1471,10 @@ WINAPI MyWriteConsoleA( HANDLE hCon, LPCVOID lpBuffer,
     }
     return rc;
   }
-  else
-  {
-    return WriteConsoleA( hCon, lpBuffer,
-			  nNumberOfCharsToWrite,
-			  lpNumberOfCharsWritten,
-			  lpReserved );
-  }
+
+  return WriteConsoleA( hCon, lpBuffer, nNumberOfCharsToWrite,
+			lpNumberOfCharsWritten, lpReserved );
+
 }
 
 BOOL
@@ -1488,13 +1491,9 @@ WINAPI MyWriteConsoleW( HANDLE hCon, LPCVOID lpBuffer,
 				nNumberOfCharsToWrite,
 				lpNumberOfCharsWritten );
   }
-  else
-  {
-    return WriteConsoleW( hCon, lpBuffer,
-			  nNumberOfCharsToWrite,
-			  lpNumberOfCharsWritten,
-			  lpReserved );
-  }
+
+  return WriteConsoleW( hCon, lpBuffer, nNumberOfCharsToWrite,
+			lpNumberOfCharsWritten, lpReserved );
 }
 
 BOOL
@@ -1510,13 +1509,41 @@ WINAPI MyWriteFile( HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
 			    lpNumberOfBytesWritten,
 			    lpOverlapped );
   }
-  else	    // here, WriteFile is the old function (this module is not hooked)
+
+  // here, WriteFile is the old function (this module is not hooked)
+  return WriteFile( hFile, lpBuffer, nNumberOfBytesToWrite,
+		    lpNumberOfBytesWritten, lpOverlapped );
+}
+
+
+#define HHFILE (HANDLE)(DWORD_PTR)
+
+UINT
+WINAPI My_lwrite( HFILE hFile, LPCSTR lpBuffer, UINT uBytes )
+{
+  DWORD Mode, written;
+  if (GetConsoleMode( HHFILE hFile, &Mode ) && (Mode & ENABLE_PROCESSED_OUTPUT))
   {
-    return WriteFile( hFile, lpBuffer,
-		      nNumberOfBytesToWrite,
-		      lpNumberOfBytesWritten,
-		      lpOverlapped );
+    DEBUGSTR( 4, L"_lwrite->" );
+    MyWriteConsoleA( HHFILE hFile, lpBuffer, uBytes, &written, NULL );
+    return written;
   }
+
+  return _lwrite( hFile, lpBuffer, uBytes );
+}
+
+long
+WINAPI My_hwrite( HFILE hFile, LPCSTR lpBuffer, long lBytes )
+{
+  DWORD Mode, written;
+  if (GetConsoleMode( HHFILE hFile, &Mode ) && (Mode & ENABLE_PROCESSED_OUTPUT))
+  {
+    DEBUGSTR( 4, L"_hwrite->" );
+    MyWriteConsoleA( HHFILE hFile, lpBuffer, lBytes, &written, NULL );
+    return written;
+  }
+
+  return _hwrite( hFile, lpBuffer, lBytes );
 }
 
 
@@ -1555,8 +1582,10 @@ WINAPI MyGetEnvironmentVariableA( LPCSTR lpName, LPSTR lpBuffer, DWORD nSize )
     memcpy( lpBuffer, PVEREA, sizeof(PVEREA) );
     return sizeof(PVEREA) - 1;
   }
+
   if (lstrcmpiA( lpName, "ANSICON" ) == 0)
     set_ansicon( NULL );
+
   return GetEnvironmentVariableA( lpName, lpBuffer, nSize );
 }
 
@@ -1570,8 +1599,10 @@ WINAPI MyGetEnvironmentVariableW( LPCWSTR lpName, LPWSTR lpBuffer, DWORD nSize )
     memcpy( lpBuffer, PVERE, sizeof(PVERE) );
     return lenof(PVERE) - 1;
   }
+
   if (lstrcmpi( lpName, L"ANSICON" ) == 0)
     set_ansicon( NULL );
+
   return GetEnvironmentVariableW( lpName, lpBuffer, nSize );
 }
 
@@ -1592,6 +1623,8 @@ HookFn Hooks[] = {
   { APIConsole, 	   "WriteConsoleA",           (PROC)MyWriteConsoleA,           NULL, NULL },
   { APIConsole, 	   "WriteConsoleW",           (PROC)MyWriteConsoleW,           NULL, NULL },
   { APIFile,		   "WriteFile",               (PROC)MyWriteFile,               NULL, NULL },
+  { APIKernel,		   "_lwrite",                 (PROC)My_lwrite,                 NULL, NULL },
+  { APIKernel,		   "_hwrite",                 (PROC)My_hwrite,                 NULL, NULL },
   { NULL, NULL, NULL, NULL, NULL }
 };
 
diff --git a/ansicon.c b/ansicon.c
index 23267b7..7196933 100644
--- a/ansicon.c
+++ b/ansicon.c
@@ -56,9 +56,13 @@
     logging is always available, controlled by ANSICON_LOG environment variable;
     only restore the original color after program/echo/type;
     return program's exit code.
+
+  7 January, 2012:
+    fixed installing into a piped CMD.EXE;
+    added a log message indicating all imports have been processed.
 */
 
-#define PDATE L"14 December, 2011"
+#define PDATE L"24 February, 2012"
 
 #include "ansicon.h"
 #include "version.h"
diff --git a/readme.txt b/readme.txt
index 847e01f..fcd936a 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,9 +1,9 @@
 
 				    ANSICON
 
-			 Copyright 2005-2011 Jason Hood
+			 Copyright 2005-2012 Jason Hood
 
-			    Version 1.50.  Freeware
+			    Version 1.51.  Freeware
 
 
     ===========
@@ -40,7 +40,7 @@
 
     Delete ANSI.dll, it has been replaced with ANSI32.dll.
     Delete ANSI-LLA.dll, it has been replaced with ANSI-LLW.dll.
-    Uninstall with your current version and install with this version.
+    Uninstall a pre-1.50 version and reinstall with this version.
 
 
     =====
@@ -92,6 +92,7 @@
 	3	Above, plus log functions that are hooked
 	4	Log console output (add to any of the above)
 	8	Append to the existing file (add to any of the above)
+       16	Log all imported modules (add to any of the above)
 
     The log option will not work with `-p'; set the environment variable
     ANSICON_LOG instead.  The variable is only read once when a new process
@@ -269,6 +270,12 @@
 
     Legend: + added, - bug-fixed, * changed.
 
+    1.51 - 24 February, 2012:
+    - fixed installing into a piped/redirected CMD.EXE;
+    - fixed 32-bit process trying to identify a 64-bit process;
+    - ignore version within core API DLL names (now Win8 works);
+    + hook _lwrite & _hwrite (now Silverfrost FTN95 v6.20 works).
+
     1.50 - 14 December, 2011:
     - -u does not imply -p;
     - return the program's exit code;
@@ -416,4 +423,4 @@
 
 
     ==============================
-    Jason Hood, 14 December, 2011.
+    Jason Hood, 24 February, 2012.
diff --git a/version.h b/version.h
index c6ec754..b834aa6 100644
--- a/version.h
+++ b/version.h
@@ -2,8 +2,8 @@
   version.h - Version defines.
 */
 
-#define PVERS	L"1.50"         // wide string
-#define PVERSA	 "1.50"         // ANSI string (windres 2.16.91 didn't like L)
-#define PVERE	L"150"          // wide environment string
-#define PVEREA	 "150"          // ANSI environment string
-#define PVERB	1,5,0,0 	// binary (resource)
+#define PVERS	L"1.51"         // wide string
+#define PVERSA	 "1.51"         // ANSI string (windres 2.16.91 didn't like L)
+#define PVERE	L"151"          // wide environment string
+#define PVEREA	 "151"          // ANSI environment string
+#define PVERB	1,5,1,0 	// binary (resource)