274 lines
9.6 KiB
C
274 lines
9.6 KiB
C
#include "loader.h"
|
|
#include "context.h"
|
|
|
|
AGENT_CTX AgentContext = {0};
|
|
|
|
/*
|
|
*
|
|
*/
|
|
VOID context_init( VOID )
|
|
{
|
|
memset( &AgentContext, 0, sizeof(AGENT_CTX) );
|
|
|
|
AgentContext.bDisableCourtesyShell = FALSE;
|
|
AgentContext.bInit = TRUE;
|
|
AgentContext.hCloseEvent = NULL;
|
|
AgentContext.dwEncoding = 0;
|
|
AgentContext.dwCompressLevel = 6;
|
|
AgentContext.dwQualityLevel = -1;
|
|
AgentContext.bUseCopyRect = FALSE;
|
|
AgentContext.bEncodingRichCursor = FALSE;
|
|
AgentContext.bEncodingPointerPos = FALSE;
|
|
AgentContext.bEncodingLastRect = FALSE;
|
|
AgentContext.bEncodingNewfbSize = FALSE;
|
|
AgentContext.bEncodingXCursor = FALSE;
|
|
|
|
/*AgentContext.dictionaries[0] = NULL;
|
|
AgentContext.dictionaries[1] = NULL;
|
|
AgentContext.dictionaries[2] = NULL;
|
|
AgentContext.dictionaries[3] = NULL;*/
|
|
|
|
AgentContext.dwPipeName = ( GetTickCount() ^ (DWORD)&AgentContext );
|
|
}
|
|
|
|
/*
|
|
* Try to read an exact ammount of data from a pipe and return
|
|
* when either the data has been read or a failure occurs.
|
|
*/
|
|
DWORD _readexact( HANDLE hPipe, DWORD dwLength, BYTE * pBuffer )
|
|
{
|
|
DWORD dwTotal = 0;
|
|
DWORD dwRead = 0;
|
|
|
|
do
|
|
{
|
|
while( dwTotal < dwLength )
|
|
{
|
|
if( !PeekNamedPipe( hPipe, NULL, 0, NULL, &dwRead, NULL ) )
|
|
break;
|
|
|
|
if( !dwRead )
|
|
{
|
|
Sleep( 50 );
|
|
continue;
|
|
}
|
|
|
|
if( ReadFile( hPipe, (LPVOID)((LPBYTE)pBuffer + dwTotal), (dwLength - dwTotal), &dwRead, NULL ) )
|
|
dwTotal += dwRead;
|
|
}
|
|
|
|
} while( 0 );
|
|
|
|
return dwTotal;
|
|
}
|
|
|
|
/*
|
|
* A thread to pick up any messages being posted back to the loader (such as an encoder change in the stream)
|
|
*/
|
|
DWORD WINAPI context_message_thread( LPVOID lpParameter )
|
|
{
|
|
DWORD dwResult = ERROR_SUCCESS;
|
|
HANDLE hServerPipe = NULL;
|
|
BYTE * pBuffer = NULL;
|
|
char cNamedPipe[MAX_PATH] = {0};
|
|
|
|
__try
|
|
{
|
|
do
|
|
{
|
|
_snprintf( cNamedPipe, MAX_PATH, "\\\\.\\pipe\\%08X", AgentContext.dwPipeName );
|
|
|
|
dprintf("[LOADER] loader_message_thread. cNamedPipe=%s", cNamedPipe );
|
|
|
|
hServerPipe = CreateNamedPipe( cNamedPipe, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE|PIPE_READMODE_BYTE|PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 0, 0, 0, NULL );
|
|
if( !hServerPipe )
|
|
BREAK_ON_ERROR( "[LOADER] loader_message_thread. CreateNamedPipe failed" );
|
|
|
|
while( TRUE )
|
|
{
|
|
struct _hdr {
|
|
DWORD dwMessage;
|
|
DWORD dwLength;
|
|
} header = {0};
|
|
DWORD dwTotal = 0;
|
|
|
|
if( !ConnectNamedPipe( hServerPipe, NULL ) )
|
|
{
|
|
if( GetLastError() != ERROR_PIPE_CONNECTED )
|
|
continue;
|
|
}
|
|
|
|
dwTotal = _readexact( hServerPipe, 8, (BYTE *)&header );
|
|
if( dwTotal != sizeof( struct _hdr ) )
|
|
BREAK_WITH_ERROR( "[LOADER] loader_message_thread. _readexact header failed", ERROR_INVALID_HANDLE );
|
|
|
|
pBuffer = (BYTE *)malloc( header.dwLength );
|
|
if( !pBuffer )
|
|
BREAK_WITH_ERROR( "[LOADER] loader_message_thread. pBuffer malloc failed", ERROR_INVALID_HANDLE );
|
|
|
|
dwTotal = _readexact( hServerPipe, header.dwLength, pBuffer );
|
|
if( dwTotal != header.dwLength )
|
|
BREAK_WITH_ERROR( "[LOADER] loader_message_thread. _readexact pBuffer failed", ERROR_INVALID_HANDLE );
|
|
|
|
DisconnectNamedPipe( hServerPipe );
|
|
|
|
switch( header.dwMessage )
|
|
{
|
|
case MESSAGE_SETENCODING:
|
|
if( header.dwLength != sizeof(DWORD) )
|
|
{
|
|
dprintf("[LOADER] loader_message_thread. MESSAGE_SETENCODING, not enought data (got %d bytes)", header.dwLength );
|
|
break;
|
|
}
|
|
AgentContext.dwEncoding = *(DWORD *)pBuffer;
|
|
dprintf("[LOADER] loader_message_thread. MESSAGE_SETENCODING, new encoding is %d", AgentContext.dwEncoding );
|
|
break;
|
|
case MESSAGE_SETPIXELFORMAT:
|
|
if( header.dwLength != sizeof(PIXELFORMAT) )
|
|
{
|
|
dprintf("[LOADER] loader_message_thread. MESSAGE_SETPIXELFORMAT, not enought data (got %d bytes)", header.dwLength );
|
|
break;
|
|
}
|
|
memcpy( &AgentContext.PixelFormat, pBuffer, sizeof(PIXELFORMAT) );
|
|
dprintf("[LOADER] loader_message_thread. MESSAGE_SETPIXELFORMAT" );
|
|
break;
|
|
case MESSAGE_SETCOMPRESSLEVEL:
|
|
if( header.dwLength != sizeof(DWORD) )
|
|
{
|
|
dprintf("[LOADER] loader_message_thread. MESSAGE_SETCOMPRESSLEVEL, not enought data (got %d bytes)", header.dwLength );
|
|
break;
|
|
}
|
|
AgentContext.dwCompressLevel = *(DWORD *)pBuffer;
|
|
dprintf("[LOADER] loader_message_thread. MESSAGE_SETCOMPRESSLEVEL, new compress level is %d", AgentContext.dwCompressLevel );
|
|
break;
|
|
case MESSAGE_SETQUALITYLEVEL:
|
|
if( header.dwLength != sizeof(DWORD) )
|
|
{
|
|
dprintf("[LOADER] loader_message_thread. MESSAGE_SETQUALITYLEVEL, not enought data (got %d bytes)", header.dwLength );
|
|
break;
|
|
}
|
|
AgentContext.dwQualityLevel = *(DWORD *)pBuffer;
|
|
dprintf("[LOADER] loader_message_thread. MESSAGE_SETQUALITYLEVEL, new quality level is %d", AgentContext.dwQualityLevel );
|
|
break;
|
|
case MESSAGE_SETCOPYRECTUSE:
|
|
if( header.dwLength != sizeof(BOOL) )
|
|
{
|
|
dprintf("[LOADER] loader_message_thread. MESSAGE_SETCOPYRECTUSE, not enought data (got %d bytes)", header.dwLength );
|
|
break;
|
|
}
|
|
AgentContext.bUseCopyRect = *(BOOL *)pBuffer;
|
|
dprintf("[LOADER] loader_message_thread. MESSAGE_SETCOPYRECTUSE, new bUseCopyRect is %d", AgentContext.bUseCopyRect );
|
|
break;
|
|
case MESSAGE_SETENCODINGRICHCURSOR:
|
|
if( header.dwLength != sizeof(BOOL) )
|
|
{
|
|
dprintf("[LOADER] loader_message_thread. MESSAGE_SETENCODINGRICHCURSOR, not enought data (got %d bytes)", header.dwLength );
|
|
break;
|
|
}
|
|
AgentContext.bEncodingRichCursor = *(BOOL *)pBuffer;
|
|
dprintf("[LOADER] loader_message_thread. MESSAGE_SETENCODINGRICHCURSOR, new dwEncodingRichCursor is %d", AgentContext.bEncodingRichCursor );
|
|
break;
|
|
case MESSAGE_SETENCODINGPOINTERPOS:
|
|
if( header.dwLength != sizeof(BOOL) )
|
|
{
|
|
dprintf("[LOADER] loader_message_thread. MESSAGE_SETENCODINGPOINTERPOS, not enought data (got %d bytes)", header.dwLength );
|
|
break;
|
|
}
|
|
AgentContext.bEncodingPointerPos = *(BOOL *)pBuffer;
|
|
dprintf("[LOADER] loader_message_thread. MESSAGE_SETENCODINGPOINTERPOS, new dwEncodingPointerPos is %d", AgentContext.bEncodingPointerPos );
|
|
break;
|
|
case MESSAGE_SETENCODINGLASTRECT:
|
|
if( header.dwLength != sizeof(BOOL) )
|
|
{
|
|
dprintf("[LOADER] loader_message_thread. MESSAGE_SETENCODINGLASTRECT, not enought data (got %d bytes)", header.dwLength );
|
|
break;
|
|
}
|
|
AgentContext.bEncodingLastRect = *(BOOL *)pBuffer;
|
|
dprintf("[LOADER] loader_message_thread. MESSAGE_SETENCODINGLASTRECT, new dwEncodingLastRect is %d", AgentContext.bEncodingLastRect );
|
|
break;
|
|
case MESSAGE_SETENCODINGNEWFBSIZE:
|
|
if( header.dwLength != sizeof(BOOL) )
|
|
{
|
|
dprintf("[LOADER] loader_message_thread. MESSAGE_SETENCODINGNEWFBSIZE, not enought data (got %d bytes)", header.dwLength );
|
|
break;
|
|
}
|
|
AgentContext.bEncodingNewfbSize = *(BOOL *)pBuffer;
|
|
dprintf("[LOADER] loader_message_thread. MESSAGE_SETENCODINGNEWFBSIZE, new bEncodingNewfbSize is %d", AgentContext.bEncodingNewfbSize );
|
|
break;
|
|
case MESSAGE_SETENCODINGXCURSOR:
|
|
if( header.dwLength != sizeof(BOOL) )
|
|
{
|
|
dprintf("[LOADER] loader_message_thread. MESSAGE_SETENCODINGXCURSOR, not enought data (got %d bytes)", header.dwLength );
|
|
break;
|
|
}
|
|
AgentContext.bEncodingXCursor = *(BOOL *)pBuffer;
|
|
dprintf("[LOADER] loader_message_thread. MESSAGE_SETENCODINGXCURSOR, new bEncodingXCursor is %d", AgentContext.bEncodingXCursor );
|
|
break;
|
|
/*
|
|
case MESSAGE_SETZLIBDICTIONARY:
|
|
if( header.dwLength < sizeof(DICTMSG) )
|
|
{
|
|
dprintf("[LOADER] loader_message_thread. MESSAGE_SETZLIBDICTIONARY, not enought data (got %d bytes)", header.dwLength );
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
DICTMSG * dmsg = (DICTMSG *)pBuffer;
|
|
if( dmsg->dwId > 4 )
|
|
{
|
|
dprintf("[LOADER] loader_message_thread. MESSAGE_SETZLIBDICTIONARY, invalid id (got %d)", dmsg->dwId );
|
|
break;
|
|
}
|
|
|
|
if( AgentContext.dictionaries[dmsg->dwId] )
|
|
free( AgentContext.dictionaries[dmsg->dwId] );
|
|
|
|
AgentContext.dictionaries[dmsg->dwId] = (DICTMSG *)malloc( sizeof(DICTMSG) + dmsg->dwDictLength );
|
|
if( !AgentContext.dictionaries[dmsg->dwId] )
|
|
{
|
|
dprintf("[LOADER] loader_message_thread. MESSAGE_SETZLIBDICTIONARY, malloc failed" );
|
|
break;
|
|
}
|
|
|
|
AgentContext.dictionaries[dmsg->dwId]->dwId = dmsg->dwId;
|
|
AgentContext.dictionaries[dmsg->dwId]->dwDictLength = dmsg->dwDictLength;
|
|
|
|
memcpy( &AgentContext.dictionaries[dmsg->dwId]->bDictBuffer, &dmsg->bDictBuffer, dmsg->dwDictLength );
|
|
|
|
dprintf("[LOADER] loader_message_thread. MESSAGE_SETZLIBDICTIONARY, id=%d, length=%d", dmsg->dwId, dmsg->dwDictLength );
|
|
}
|
|
break;
|
|
*/
|
|
default:
|
|
dprintf("[LOADER] loader_message_thread. Unknown message 0x%08X", header.dwMessage );
|
|
break;
|
|
}
|
|
|
|
if( pBuffer )
|
|
{
|
|
free( pBuffer );
|
|
pBuffer = NULL;
|
|
}
|
|
}
|
|
|
|
} while( 0 );
|
|
}
|
|
__except( EXCEPTION_EXECUTE_HANDLER )
|
|
{
|
|
dprintf( "[LOADER] loader_message_thread. EXCEPTION_EXECUTE_HANDLER\n\n" );
|
|
}
|
|
|
|
dprintf("[LOADER] loader_message_thread. thread finishing...");
|
|
|
|
if( hServerPipe )
|
|
{
|
|
DisconnectNamedPipe( hServerPipe );
|
|
CLOSE_HANDLE( hServerPipe );
|
|
}
|
|
|
|
if( pBuffer )
|
|
free( pBuffer );
|
|
|
|
return dwResult;
|
|
}
|