Dynamically load WINMM, remove USER32
Prevent loading more libraries than necessary, so load WINMM the first time the bell is used and use the CRT printf functions to avoid loading USER32 at all. I was also going to remove MSVCRT, but that turned out to be more trouble than it's worth. However, a side-effect that I kept is replacing bsearch with a dedicated search routine.
This commit is contained in:
parent
2cb2af78c8
commit
852db64d91
41
ANSI.c
41
ANSI.c
@ -197,17 +197,24 @@
|
||||
v1.83, 16 February, 2018:
|
||||
create the flush thread on first use.
|
||||
|
||||
v1.84-wip, 17 February, 2018:
|
||||
close the flush handles on detach.
|
||||
v1.84-wip, 17 February, 26 to 30 April, 2018:
|
||||
close the flush handles on detach;
|
||||
dynamically load WINMM.DLL;
|
||||
use sprintf/_snprintf/_snwprintf instead of wsprintf, avoiding USER32.DLL;
|
||||
replace bsearch (in procrva.c) with specific code.
|
||||
*/
|
||||
|
||||
#include "ansicon.h"
|
||||
#include "version.h"
|
||||
#include <mmsystem.h>
|
||||
|
||||
#include <mmsystem.h>
|
||||
#ifndef SND_SENTRY
|
||||
#define SND_SENTRY 0x80000
|
||||
#endif
|
||||
#undef PlaySound
|
||||
typedef BOOL (WINAPI *FnPlaySound)( LPCWSTR, HMODULE, DWORD );
|
||||
FnPlaySound PlaySound;
|
||||
HMODULE winmm;
|
||||
|
||||
#define is_digit(c) ('0' <= (c) && (c) <= '9')
|
||||
|
||||
@ -483,7 +490,7 @@ void get_state( void )
|
||||
|
||||
valid_state = TRUE;
|
||||
|
||||
wsprintf( buf, L"ANSICON_State_%X", PtrToUint( hwnd ) );
|
||||
_snwprintf( buf, lenof(buf), L"ANSICON_State_%X", PtrToUint( hwnd ) );
|
||||
hMap = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
|
||||
0, sizeof(STATE), buf );
|
||||
init = (GetLastError() != ERROR_ALREADY_EXISTS);
|
||||
@ -552,7 +559,7 @@ void get_state( void )
|
||||
*a++ = '-';
|
||||
ATTR = ((ATTR >> 4) & 15) | ((ATTR & 15) << 4);
|
||||
}
|
||||
wsprintf( a, L"%X", ATTR & 255 );
|
||||
_snwprintf( a, 3, L"%X", ATTR & 255 );
|
||||
SetEnvironmentVariable( L"ANSICON_DEF", def );
|
||||
}
|
||||
set_ansicon( &Info );
|
||||
@ -1018,9 +1025,9 @@ void send_palette_sequence( COLORREF c )
|
||||
g = GetGValue( c );
|
||||
b = GetBValue( c );
|
||||
if ((c & 0x0F0F0F) == ((c >> 4) & 0x0F0F0F))
|
||||
wsprintf( buf, L"#%X%X%X", r & 0xF, g & 0xF, b & 0xF );
|
||||
_snwprintf( buf, lenof(buf), L"#%X%X%X", r & 0xF, g & 0xF, b & 0xF );
|
||||
else
|
||||
wsprintf( buf, L"#%02X%02X%02X", r, g, b );
|
||||
_snwprintf( buf, lenof(buf), L"#%02X%02X%02X", r, g, b );
|
||||
SendSequence( buf );
|
||||
}
|
||||
|
||||
@ -1765,7 +1772,7 @@ void InterpretEscSeq( void )
|
||||
case 6: // ESC[6n Report cursor position
|
||||
{
|
||||
TCHAR buf[32];
|
||||
wsprintf( buf, L"\33[%d;%d%sR",
|
||||
_snwprintf( buf, lenof(buf), L"\33[%d;%d%sR",
|
||||
CUR.Y - top + 1, CUR.X + 1,
|
||||
(suffix2 == '+') ? L"+" : L"" );
|
||||
SendSequence( buf );
|
||||
@ -2236,7 +2243,17 @@ ParseAndPrintString( HANDLE hDev,
|
||||
else if (pState->crm) PushBuffer( (WCHAR)c );
|
||||
else if (c == BEL)
|
||||
{
|
||||
if (hBell == NULL)
|
||||
if (PlaySound == NULL)
|
||||
{
|
||||
winmm = LoadLibraryEx( L"winmm.dll", NULL, 0 );
|
||||
if (winmm != NULL)
|
||||
PlaySound = (FnPlaySound)GetProcAddress( winmm, "PlaySoundW" );
|
||||
if (PlaySound == NULL)
|
||||
PlaySound = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
if (PlaySound == INVALID_HANDLE_VALUE)
|
||||
PushBuffer( (WCHAR)c );
|
||||
else if (hBell == NULL)
|
||||
hBell = CreateThread( NULL, 4096, BellThread, NULL, 0, NULL );
|
||||
}
|
||||
else if (c == SO) shifted = TRUE;
|
||||
@ -2975,7 +2992,7 @@ void Inject( DWORD dwCreationFlags, LPPROCESS_INFORMATION lpi,
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
wcscpy( DllNameType, L"CON.exe" );
|
||||
wsprintf( args, L"ansicon -P%ld", child_pi->dwProcessId );
|
||||
_snwprintf( args, lenof(args), L"ansicon -P%lu", child_pi->dwProcessId );
|
||||
ZeroMemory( &si, sizeof(si) );
|
||||
si.cb = sizeof(si);
|
||||
if (CreateProcess( DllName, args, NULL, NULL, FALSE, 0, NULL, NULL,
|
||||
@ -3689,7 +3706,7 @@ void set_ansicon( PCONSOLE_SCREEN_BUFFER_INFO pcsbi )
|
||||
pcsbi = &csbi;
|
||||
}
|
||||
|
||||
wsprintf( buf, L"%dx%d (%dx%d)",
|
||||
_snwprintf( buf, lenof(buf), L"%dx%d (%dx%d)",
|
||||
pcsbi->dwSize.X, pcsbi->dwSize.Y,
|
||||
pcsbi->srWindow.Right - pcsbi->srWindow.Left + 1,
|
||||
pcsbi->srWindow.Bottom - pcsbi->srWindow.Top + 1 );
|
||||
@ -3920,6 +3937,8 @@ BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved )
|
||||
{
|
||||
DEBUGSTR( 1, "Unloading" );
|
||||
HookAPIAllMod( Hooks, TRUE, FALSE );
|
||||
if (winmm != NULL)
|
||||
FreeLibrary( winmm );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -91,7 +91,7 @@
|
||||
use -pu to unload from the parent.
|
||||
*/
|
||||
|
||||
#define PDATE L"17 February, 2018"
|
||||
#define PDATE L"30 April, 2018"
|
||||
|
||||
#include "ansicon.h"
|
||||
#include "version.h"
|
||||
@ -199,7 +199,8 @@ BOOL Inject( LPPROCESS_INFORMATION ppi, BOOL* gui, LPCTSTR app )
|
||||
len = (DWORD)(prog - prog_path);
|
||||
memcpy( DllName, prog_path, TSIZE(len) );
|
||||
#ifdef _WIN64
|
||||
wsprintf( DllName + len, L"ANSI%d.dll", (type == 48) ? 64 : type );
|
||||
_snwprintf( DllName + len, MAX_PATH-1 - len,
|
||||
L"ANSI%d.dll", (type == 48) ? 64 : type );
|
||||
DllNameType = DllName + len + 4;
|
||||
set_ansi_dll();
|
||||
if (type == 64)
|
||||
@ -269,7 +270,7 @@ void RemoteLoad( LPPROCESS_INFORMATION ppi, LPCTSTR app, BOOL unload )
|
||||
memcpy( DllName, prog_path, TSIZE(len) );
|
||||
#ifdef _WIN64
|
||||
type = (IsWow64Process( ppi->hProcess, &WOW64 ) && WOW64) ? 32 : 64;
|
||||
wsprintf( DllName + len, L"ANSI%d.dll", type );
|
||||
_snwprintf( DllName + len, MAX_PATH-1 - len, L"ANSI%d.dll", type );
|
||||
#endif
|
||||
me.dwSize = sizeof(MODULEENTRY32);
|
||||
for (fOk = Module32First( hSnap, &me ); fOk; fOk = Module32Next( hSnap, &me ))
|
||||
|
@ -60,13 +60,14 @@ SHARE = /MD
|
||||
MT = mt.exe
|
||||
|
||||
CFLAGS = /nologo /W3 /O2 $(SHARE) /D_CRT_SECURE_NO_WARNINGS
|
||||
LIBS = advapi32.lib user32.lib winmm.lib $(LIBS64)
|
||||
LIBS = advapi32.lib $(LIBS64)
|
||||
|
||||
# Identify ansicon.exe using "ANSI" as a version number.
|
||||
LINK = /link /version:20033.18771
|
||||
|
||||
X86OBJS = x86\injdll.obj x86\proctype.obj x86\util.obj
|
||||
X64OBJS = x64\injdll.obj x64\proctype.obj x64\util.obj x64\procrva.obj
|
||||
X6432OBJS = x86\injdll.obj x64\proctype32.obj x86\util.obj
|
||||
|
||||
!IF !DEFINED(V)
|
||||
V = 0
|
||||
@ -118,7 +119,7 @@ x64\ANSI64.dll: x64\ANSI.obj $(X64OBJS) x64\ansi.res
|
||||
$(LDmsg)$(CC) /nologo $(SHARE) /LD /Fe$@ $** $(LIBS) /link \
|
||||
/base:0xAC000000
|
||||
|
||||
x64\ANSI32.dll: x64\ANSI32.obj x64\proctype32.obj x86\injdll.obj x86\util.obj x86\ansi.res
|
||||
x64\ANSI32.dll: x64\ANSI32.obj $(X6432OBJS) x86\ansi.res
|
||||
$(LDmsg)$(CC) /nologo $(SHARE) /LD /Fe$@ $** $(LIBS) /link \
|
||||
/base:0xAC0000 /filealign:512 /largeaddressaware
|
||||
!IF "$(_NMAKE_VER)" == "9.00.30729.01"
|
||||
|
34
procrva.c
34
procrva.c
@ -9,12 +9,6 @@
|
||||
static PIMAGE_DOS_HEADER pDosHeader;
|
||||
|
||||
|
||||
static int export_cmp( const void* a, const void* b )
|
||||
{
|
||||
return strcmp( (LPCSTR)a, MakeVA( LPCSTR, *(const PDWORD)b ) );
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN64
|
||||
DWORD GetProcRVA( LPCTSTR module, LPCSTR func, int bits )
|
||||
#else
|
||||
@ -28,8 +22,8 @@ DWORD GetProcRVA( LPCTSTR module, LPCSTR func )
|
||||
PIMAGE_EXPORT_DIRECTORY pExportDir;
|
||||
PDWORD fun_table, name_table;
|
||||
PWORD ord_table;
|
||||
PDWORD pFunc;
|
||||
DWORD rva;
|
||||
int lo, mid, hi, cmp;
|
||||
|
||||
#ifdef _WIN64
|
||||
if (bits == 32)
|
||||
@ -65,20 +59,30 @@ DWORD GetProcRVA( LPCTSTR module, LPCSTR func )
|
||||
name_table = MakeVA( PDWORD, pExportDir->AddressOfNames );
|
||||
ord_table = MakeVA( PWORD, pExportDir->AddressOfNameOrdinals );
|
||||
|
||||
pFunc = bsearch( func, name_table, pExportDir->NumberOfNames,
|
||||
sizeof(DWORD), export_cmp );
|
||||
if (pFunc == NULL)
|
||||
rva = 0;
|
||||
lo = 0;
|
||||
hi = pExportDir->NumberOfNames - 1;
|
||||
while (lo <= hi)
|
||||
{
|
||||
mid = (lo + hi) / 2;
|
||||
cmp = strcmp( func, MakeVA( LPCSTR, name_table[mid] ) );
|
||||
if (cmp == 0)
|
||||
{
|
||||
rva = fun_table[ord_table[mid]];
|
||||
break;
|
||||
}
|
||||
if (cmp < 0)
|
||||
hi = mid - 1;
|
||||
else
|
||||
lo = mid + 1;
|
||||
}
|
||||
if (rva == 0)
|
||||
{
|
||||
#ifdef _WIN64
|
||||
DEBUGSTR( 1, "Could not find %u-bit %s!", bits, func );
|
||||
#else
|
||||
DEBUGSTR( 1, "Could not find %s!", func );
|
||||
#endif
|
||||
rva = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rva = fun_table[ord_table[pFunc - name_table]];
|
||||
}
|
||||
FreeLibrary( hMod );
|
||||
return rva;
|
||||
|
@ -339,8 +339,9 @@ Version History
|
||||
|
||||
Legend: + added, - bug-fixed, * changed.
|
||||
|
||||
1.84-wip - 17 February, 2018:
|
||||
- close the flush handles on detach.
|
||||
1.84-wip - 30 April, 2018:
|
||||
- close the flush handles on detach;
|
||||
* remove dependency on USER32, dynamically load WINMM.
|
||||
|
||||
1.83 - 16 February, 2018:
|
||||
- create the flush thread on first use.
|
||||
@ -615,5 +616,5 @@ Distribution
|
||||
in LICENSE.txt.
|
||||
|
||||
|
||||
==============================
|
||||
Jason Hood, 17 February, 2018.
|
||||
===========================
|
||||
Jason Hood, 30 April, 2018.
|
||||
|
30
util.c
30
util.c
@ -107,14 +107,20 @@ static DWORD str_format( DWORD pos, BOOL wide, DWORD_PTR str, DWORD len )
|
||||
if (len == 0)
|
||||
{
|
||||
if (str == 0)
|
||||
pos += wsprintfA( buf + pos, "<null>" );
|
||||
{
|
||||
memcpy( buf + pos, "<null>", 6 );
|
||||
pos += 6;
|
||||
}
|
||||
else if (quote)
|
||||
{
|
||||
buf[pos++] = '"';
|
||||
buf[pos++] = '"';
|
||||
}
|
||||
else if (alt)
|
||||
pos += wsprintfA( buf + pos, "<empty>" );
|
||||
{
|
||||
memcpy( buf + pos, "<empty>", 7 );
|
||||
pos += 7;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
@ -165,7 +171,7 @@ static DWORD str_format( DWORD pos, BOOL wide, DWORD_PTR str, DWORD len )
|
||||
case '\r': buf[pos++] = 'r'; break;
|
||||
case 27 : buf[pos++] = 'e'; break;
|
||||
default:
|
||||
pos += wsprintfA( buf + pos, "x%.2X", ch );
|
||||
pos += sprintf( buf + pos, "x%.2X", ch );
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -194,7 +200,7 @@ static DWORD str_format( DWORD pos, BOOL wide, DWORD_PTR str, DWORD len )
|
||||
}
|
||||
}
|
||||
if (quote && start_trail)
|
||||
pos += wsprintfA( buf + pos, "\\x%.2X", ch );
|
||||
pos += sprintf( buf + pos, "\\x%.2X", ch );
|
||||
else
|
||||
buf[pos++] = ch;
|
||||
}
|
||||
@ -203,7 +209,7 @@ static DWORD str_format( DWORD pos, BOOL wide, DWORD_PTR str, DWORD len )
|
||||
int mb = WideCharToMultiByte( cp, flags, src.w - 1, 1, buf + pos, 12,
|
||||
NULL, pDef );
|
||||
if (def)
|
||||
mb = wsprintfA( buf + pos, ch < 0x100 ? "%cx%.2X" : "%cu%.4X",
|
||||
mb = sprintf( buf + pos, ch < 0x100 ? "%cx%.2X" : "%cu%.4X",
|
||||
(quote) ? '\\' : '^', ch );
|
||||
pos += mb;
|
||||
}
|
||||
@ -240,7 +246,7 @@ void DEBUGSTR( int level, LPCSTR szFormat, ... )
|
||||
}
|
||||
buf = HeapAlloc( hHeap, 0, 2048 );
|
||||
buf_len = (DWORD)HeapSize( hHeap, 0, buf );
|
||||
prefix_len = wsprintfA( buf, "%S (%lu): ", prog, GetCurrentProcessId() );
|
||||
prefix_len = sprintf( buf, "%S (%lu): ", prog, GetCurrentProcessId() );
|
||||
}
|
||||
if (WaitForSingleObject( mutex, 500 ) == WAIT_TIMEOUT)
|
||||
return;
|
||||
@ -274,7 +280,7 @@ void DEBUGSTR( int level, LPCSTR szFormat, ... )
|
||||
}
|
||||
|
||||
GetLocalTime( &now );
|
||||
len = wsprintfA( buf, "ANSICON (" BITSA "-bit) v" PVERSA " log (%d)"
|
||||
len = sprintf( buf, "ANSICON (" BITSA "-bit) v" PVERSA " log (%d)"
|
||||
" started %d-%.2d-%.2d %d:%.2d:%.2d\r\n",
|
||||
log_level,
|
||||
now.wYear, now.wMonth, now.wDay,
|
||||
@ -349,16 +355,16 @@ void DEBUGSTR( int level, LPCSTR szFormat, ... )
|
||||
num = va_arg( pArgList, DWORD_PTR );
|
||||
switch (*szFormat++)
|
||||
{
|
||||
case 'u': len += wsprintfA( buf + len, "%u", (DWORD)num ); break;
|
||||
case 'X': len += wsprintfA( buf + len, "%X", (DWORD)num ); break;
|
||||
case 'u': len += sprintf( buf + len, "%u", (DWORD)num ); break;
|
||||
case 'X': len += sprintf( buf + len, "%X", (DWORD)num ); break;
|
||||
case 'p':
|
||||
#ifdef _WIN64
|
||||
len += wsprintfA( buf + len, "%.8X_%.8X",
|
||||
len += sprintf( buf + len, "%.8X_%.8X",
|
||||
(DWORD)(num >> 32), (DWORD)num );
|
||||
break;
|
||||
#endif
|
||||
case 'q': len += wsprintfA( buf + len, "%.8X", (DWORD)num ); break;
|
||||
case 'P': len += wsprintfA( buf + len, "00000000_%.8X", (DWORD)num ); break;
|
||||
case 'q': len += sprintf( buf + len, "%.8X", (DWORD)num ); break;
|
||||
case 'P': len += sprintf( buf + len, "00000000_%.8X", (DWORD)num ); break;
|
||||
case 's': len = str_format( len, FALSE, num, slen ); break;
|
||||
case 'S': len = str_format( len, TRUE, num, slen ); break;
|
||||
default:
|
||||
|
Loading…
x
Reference in New Issue
Block a user