From ef587f0dee213747dd53f39cebd0950fe250f979 Mon Sep 17 00:00:00 2001
From: Jason Hood <jadoxa@yahoo.com.au>
Date: Tue, 12 Jun 2012 14:38:00 +1000
Subject: [PATCH] Fixed multiple simultaneous process creation.

---
 ANSI.c      | 59 ++++++++++++++++++++++++++++++++++++-----------------
 ansicon.c   |  4 ++--
 makefile    |  2 ++
 makefile.vc |  2 +-
 proctype.c  |  6 ++++--
 readme.txt  |  9 +++++---
 util.c      |  5 ++++-
 version.h   | 10 ++++-----
 8 files changed, 64 insertions(+), 33 deletions(-)

diff --git a/ANSI.c b/ANSI.c
index 9444365..3907252 100644
--- a/ANSI.c
+++ b/ANSI.c
@@ -88,6 +88,9 @@
     added the character/line equivalents (keaj`) of the cursor movement
      sequences (ABCDG), as well as vertical absolute (d) and erase characters
      (X).
+
+  v1.53, 12 June, 2012:
+    fixed Update_GRM when running multiple processes (e.g. "cl /MP").
 */
 
 #include "ansicon.h"
@@ -225,14 +228,19 @@ SHARED DWORD s_flag;
 #define GRM_INIT 1
 #define GRM_EXIT 2
 
-PROCESS_INFORMATION child_pi;
 
 
 // Wait for the child process to finish, then update our GRM to the child's.
-DWORD WINAPI UpdateGRM( LPVOID lpParameter )
+DWORD WINAPI UpdateGRM( LPVOID child_pi )
 {
-  WaitForSingleObject( child_pi.hProcess, INFINITE );
-  if (s_flag == GRM_EXIT && s_pid == child_pi.dwProcessId)
+  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)
   {
     s_flag = 0;
     grm = s_grm;
@@ -1171,12 +1179,13 @@ BOOL HookAPIAllMod( PHookFn Hooks, BOOL restore )
 
 // Inject code into the target process to load our DLL.
 void Inject( DWORD dwCreationFlags, LPPROCESS_INFORMATION lpi,
+	     LPPROCESS_INFORMATION child_pi,
 	     BOOL wide, LPCVOID lpApp, LPCVOID lpCmd )
 {
   int	 type;
   BOOL	 gui;
 
-  type = ProcessType( &child_pi, &gui );
+  type = ProcessType( child_pi, &gui );
   if (gui)
   {
     TCHAR   app[MAX_PATH];
@@ -1242,13 +1251,13 @@ void Inject( DWORD dwCreationFlags, LPPROCESS_INFORMATION lpi,
     {
       hDllNameType[0] = '3';
       hDllNameType[1] = '2';
-      InjectDLL32( &child_pi, hDllName );
+      InjectDLL32( child_pi, hDllName );
     }
     else
     {
       hDllNameType[0] = '6';
       hDllNameType[1] = '4';
-      InjectDLL64( &child_pi, hDllName );
+      InjectDLL64( child_pi, hDllName );
     }
 #else
 #ifdef W32ON64
@@ -1259,7 +1268,7 @@ void Inject( DWORD dwCreationFlags, LPPROCESS_INFORMATION lpi,
       PROCESS_INFORMATION pi;
       wcscpy( hDllNameType, L"CON.exe" );
       wsprintf( args, L"ansicon -P%lu:%lu",
-		      child_pi.dwProcessId, child_pi.dwThreadId );
+		      child_pi->dwProcessId, child_pi->dwThreadId );
       ZeroMemory( &si, sizeof(si) );
       si.cb = sizeof(si);
       if (CreateProcess( hDllName, args, NULL, NULL, FALSE, 0, NULL, NULL,
@@ -1275,28 +1284,34 @@ void Inject( DWORD dwCreationFlags, LPPROCESS_INFORMATION lpi,
     }
     else
 #endif
-    InjectDLL32( &child_pi, hDllName );
+    InjectDLL32( child_pi, hDllName );
 #endif
     if (!gui && !(dwCreationFlags & (CREATE_NEW_CONSOLE | DETACHED_PROCESS)))
     {
-      s_pid = child_pi.dwProcessId;
+      LPPROCESS_INFORMATION cpi;
+      s_pid = child_pi->dwProcessId;
       s_grm = grm;
       s_flag = GRM_INIT;
-      CloseHandle( CreateThread( NULL, 4096, UpdateGRM, NULL, 0, NULL ) );
+      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 ) );
     }
   }
 
   if (!(dwCreationFlags & CREATE_SUSPENDED))
-    ResumeThread( child_pi.hThread );
+    ResumeThread( child_pi->hThread );
 
   if (lpi)
   {
-    memcpy( lpi, &child_pi, sizeof(PROCESS_INFORMATION) );
+    memcpy( lpi, child_pi, sizeof(PROCESS_INFORMATION) );
   }
   else
   {
-    CloseHandle( child_pi.hThread );
-    CloseHandle( child_pi.hProcess );
+    CloseHandle( child_pi->hThread );
+    CloseHandle( child_pi->hProcess );
   }
 }
 
@@ -1312,6 +1327,8 @@ BOOL WINAPI MyCreateProcessA( LPCSTR lpApplicationName,
 			      LPSTARTUPINFOA lpStartupInfo,
 			      LPPROCESS_INFORMATION lpProcessInformation )
 {
+  PROCESS_INFORMATION child_pi;
+
   if (!CreateProcessA( lpApplicationName,
 		       lpCommandLine,
 		       lpThreadAttributes,
@@ -1324,10 +1341,11 @@ BOOL WINAPI MyCreateProcessA( LPCSTR lpApplicationName,
 		       &child_pi ))
     return FALSE;
 
-  DEBUGSTR( 1, L"CreateProcessA: \"%S\", \"%S\"",
+  DEBUGSTR( 1, L"CreateProcessA: (%lu) \"%S\", \"%S\"",
+	    child_pi.dwProcessId,
 	    (lpApplicationName == NULL) ? "" : lpApplicationName,
 	    (lpCommandLine == NULL) ? "" : lpCommandLine );
-  Inject( dwCreationFlags, lpProcessInformation,
+  Inject( dwCreationFlags, lpProcessInformation, &child_pi,
 	  FALSE, lpApplicationName, lpCommandLine );
 
   return TRUE;
@@ -1345,6 +1363,8 @@ BOOL WINAPI MyCreateProcessW( LPCWSTR lpApplicationName,
 			      LPSTARTUPINFOW lpStartupInfo,
 			      LPPROCESS_INFORMATION lpProcessInformation )
 {
+  PROCESS_INFORMATION child_pi;
+
   if (!CreateProcessW( lpApplicationName,
 		       lpCommandLine,
 		       lpThreadAttributes,
@@ -1357,10 +1377,11 @@ BOOL WINAPI MyCreateProcessW( LPCWSTR lpApplicationName,
 		       &child_pi ))
     return FALSE;
 
-  DEBUGSTR( 1, L"CreateProcessW: \"%s\", \"%s\"",
+  DEBUGSTR( 1, L"CreateProcessW: (%lu) \"%s\", \"%s\"",
+	    child_pi.dwProcessId,
 	    (lpApplicationName == NULL) ? L"" : lpApplicationName,
 	    (lpCommandLine == NULL) ? L"" : lpCommandLine );
-  Inject( dwCreationFlags, lpProcessInformation,
+  Inject( dwCreationFlags, lpProcessInformation, &child_pi,
 	  TRUE, lpApplicationName, lpCommandLine );
 
   return TRUE;
diff --git a/ansicon.c b/ansicon.c
index 59a3e7c..2b87abe 100644
--- a/ansicon.c
+++ b/ansicon.c
@@ -66,7 +66,7 @@
     pass process & thread identifiers on the command line (for x86->x64).
 */
 
-#define PDATE L"2 June, 2012"
+#define PDATE L"12 June, 2012"
 
 #include "ansicon.h"
 #include "version.h"
@@ -110,7 +110,7 @@ BOOL Inject( LPPROCESS_INFORMATION ppi, BOOL* gui, LPCTSTR app )
   WCHAR dll[MAX_PATH];
   int	type;
 
-  DEBUGSTR( 1, L"%s", app );
+  DEBUGSTR( 1, L"%s (%lu)", app, ppi->dwProcessId );
   type = ProcessType( ppi, gui );
   if (type == 0)
   {
diff --git a/makefile b/makefile
index 1ab6753..0007bee 100644
--- a/makefile
+++ b/makefile
@@ -63,6 +63,8 @@ x86/ansicon.o:	version.h
 x86/ANSI.o:	version.h
 x64/ansicon.o:	version.h
 x64/ANSI.o:	version.h
+x86/util.o:	version.h
+x64/util.o:	version.h
 x86/ansiconv.o: ansicon.rc
 x86/ansiv.o:	ansi.rc
 x64/ansiconv.o: ansicon.rc
diff --git a/makefile.vc b/makefile.vc
index 00a9019..da71872 100644
--- a/makefile.vc
+++ b/makefile.vc
@@ -74,7 +74,7 @@ ansicon.c:  ansicon.h version.h
 ansicon.rc: version.h
 ANSI.c:     ansicon.h version.h
 ANSI.rc:    version.h
-util.c:     ansicon.h
+util.c:     ansicon.h version.h
 injdll32.c: ansicon.h
 injdll64.c: ansicon.h
 proctype.c: ansicon.h
diff --git a/proctype.c b/proctype.c
index f6a6e60..27399cd 100644
--- a/proctype.c
+++ b/proctype.c
@@ -50,8 +50,10 @@ int ProcessType( LPPROCESS_INFORMATION pinfo, BOOL* gui )
 	    {
 	      if (nt_header.FileHeader.Machine == IMAGE_FILE_MACHINE_I386)
 	      {
-		DEBUGSTR( 1, L"  32-bit %s (base = %.8p)",
-			  (*gui) ? L"GUI" : L"console", minfo.AllocationBase );
+		// Microsoft ignores precision on %p.
+		DEBUGSTR( 1, L"  32-bit %s (base = %.8X)",
+			  (*gui) ? L"GUI" : L"console",
+			  (DWORD)(DWORD_PTR)minfo.AllocationBase );
 		return 32;
 	      }
 #ifdef _WIN64
diff --git a/readme.txt b/readme.txt
index a125b7c..78f00eb 100644
--- a/readme.txt
+++ b/readme.txt
@@ -3,7 +3,7 @@
 
 			 Copyright 2005-2012 Jason Hood
 
-			    Version 1.52.  Freeware
+			    Version 1.53.  Freeware
 
 
     ===========
@@ -274,6 +274,9 @@
 
     Legend: + added, - bug-fixed, * changed.
 
+    1.53 - 12 June, 2012:
+    - fix for multiple simultaneous process creation (e.g. "cl /MP ...").
+
     1.52 - 2 June, 2012:
     + 32-bit processes can inject into 64-bit processes;
     + implemented \e[39m & \e[49m (set default foreground/background color);
@@ -432,5 +435,5 @@
     in the version text and a source diff is included.
 
 
-    =========================
-    Jason Hood, 2 June, 2012.
+    ==========================
+    Jason Hood, 12 June, 2012.
diff --git a/util.c b/util.c
index 0867ddb..461b7b6 100644
--- a/util.c
+++ b/util.c
@@ -3,6 +3,7 @@
 */
 
 #include "ansicon.h"
+#include "version.h"
 
 
 TCHAR	prog_path[MAX_PATH];
@@ -59,7 +60,9 @@ void DEBUGSTR( int level, LPTSTR szFormat, ... )
     {
       SYSTEMTIME now;
       GetLocalTime( &now );
-      fprintf( file, "Logging started %d-%.2d-%.2d %d:%.2d:%.2d\n",
+      fprintf( file, "ANSICON v" PVERSA " log (%d) started "
+		      "%d-%.2d-%.2d %d:%.2d:%.2d\n",
+		     log_level,
 		     now.wYear, now.wMonth, now.wDay,
 		     now.wHour, now.wMinute, now.wSecond );
       fclose( file );
diff --git a/version.h b/version.h
index a66bdcd..ff76004 100644
--- a/version.h
+++ b/version.h
@@ -2,8 +2,8 @@
   version.h - Version defines.
 */
 
-#define PVERS	L"1.52"         // wide string
-#define PVERSA	 "1.52"         // ANSI string (windres 2.16.91 didn't like L)
-#define PVERE	L"152"          // wide environment string
-#define PVEREA	 "152"          // ANSI environment string
-#define PVERB	1,5,2,0 	// binary (resource)
+#define PVERS	L"1.53"         // wide string
+#define PVERSA	 "1.53"         // ANSI string (windres 2.16.91 didn't like L)
+#define PVERE	L"153"          // wide environment string
+#define PVEREA	 "153"          // ANSI environment string
+#define PVERB	1,5,3,0 	// binary (resource)