2010-04-13 15:25:33 +00:00
// System.cpp : Defines the entry point for the DLL application.
//
// Unicode support by Jim Park & Olivier Marcoux
# include "stdafx.h"
# include "Plugin.h"
# include "Buffers.h"
# include "System.h"
# ifndef __GNUC__
# define _DECL_DLLMAIN /* enable prototypes for DllMain and _CRT_INIT */
# include <process.h>
# include <crtdbg.h>
# else
# define _RPT0(type, msg)
# define _CRT_WARN 0
# endif /* __GNUC__ */
# include <objbase.h>
2012-03-06 23:09:23 +00:00
2010-04-13 15:25:33 +00:00
// Parse Section Type
# define PST_PROC 0
# define PST_PARAMS 1
# define PST_RETURN 2
# define PST_OPTIONS 3
# define PCD_NONE 0
# define PCD_PROC 1
# define PCD_PARAMS 2
# define PCD_DONE 3 // Just Continue
2013-09-06 23:48:59 +00:00
const int PARAMSIZEBYTYPE_PTR = ( 4 = = sizeof ( void * ) ) ? 1 : 2 ;
2014-06-28 19:54:51 +00:00
const int ParamSizeByType [ 8 ] = {
2013-09-06 23:48:59 +00:00
0 , // PAT_VOID (Size will be equal to 1) //BUGBUG64?
2010-04-13 15:25:33 +00:00
1 , // PAT_INT
2 , // PAT_LONG
2013-09-06 23:48:59 +00:00
sizeof ( void * ) / 4 , // PAT_STRING //BUGBUG64?
sizeof ( void * ) / 4 , // PAT_WSTRING //BUGBUG64?
sizeof ( void * ) / 4 , // PAT_GUID //BUGBUG64?
2014-06-27 14:27:32 +00:00
0 , // PAT_CALLBACK (Size will be equal to 1) //BUGBUG64?
2014-07-01 22:09:38 +00:00
0 // PAT_REGMEM //BUGBUG64?
2014-06-27 14:27:32 +00:00
} ;
2010-04-13 15:25:33 +00:00
2017-12-03 18:04:02 +00:00
// The size of the base type when used in a struct with the '&' syntax (multiply by (Option - PAO_ARRBASE) to get the real size)
2014-06-27 14:27:32 +00:00
static const int ByteSizeByType [ 8 ] = {
2010-04-13 15:25:33 +00:00
1 , // PAT_VOID
1 , // PAT_INT
1 , // PAT_LONG
1 , // PAT_STRING
2017-10-07 18:56:03 +00:00
2 , // PAT_WSTRING (Special case for &wN notation: N is a number of WCHAR, not a number of bytes)
1 , // PAT_GUID (Must stay 1 for compatibility with the old '*(&g16,i)i.s' syntax)
2014-06-27 14:27:32 +00:00
1 , // PAT_CALLBACK
1 // PAT_REGMEM
} ;
2012-09-10 22:56:41 +00:00
2010-04-13 15:25:33 +00:00
int LastStackPlace ;
int LastStackReal ;
DWORD LastError ;
volatile SystemProc * LastProc ;
int CallbackIndex ;
2013-09-06 23:48:59 +00:00
CallbackThunk * g_CallbackThunkListHead ;
2010-04-13 15:25:33 +00:00
HINSTANCE g_hInstance ;
// Return to callback caller with stack restore
2012-09-10 22:56:41 +00:00
char retexpr [ 4 ] ; //BUGBUG64?
2010-04-13 15:25:33 +00:00
HANDLE retaddr ;
2017-12-03 18:04:02 +00:00
static TCHAR * MakeResultStr ( SystemProc * proc , TCHAR * buf )
2010-04-13 15:25:33 +00:00
{
2017-12-03 18:04:02 +00:00
if ( proc - > ProcResult = = PR_OK )
lstrcpy ( buf , _T ( " ok " ) ) ;
else if ( proc - > ProcResult = = PR_ERROR )
lstrcpy ( buf , _T ( " error " ) ) ;
else if ( proc - > ProcResult = = PR_CALLBACK )
{
INT_PTR id = proc - > CallbackIndex ;
# ifdef POPT_SYNTAX2
if ( proc - > Options & POPT_SYNTAX2 )
id = ( INT_PTR ) GetAssociatedSysProcFromCallbackThunkPtr ( proc - > Proc ) ;
# endif
wsprintf ( buf , sizeof ( void * ) > 4 ? _T ( " callback%Id " ) : _T ( " callback%d " ) , id ) ; // "%d" must match format used by system_pushintptr() in Get() because script will StrCmp!
}
2010-04-13 15:25:33 +00:00
return buf ;
}
2017-12-03 18:04:02 +00:00
TCHAR * AllocResultStr ( SystemProc * proc )
{
return MakeResultStr ( proc , AllocString ( ) ) ;
}
2010-04-13 15:25:33 +00:00
# ifdef SYSTEM_LOG_DEBUG
2010-11-15 18:02:29 +00:00
# ifndef COUNTOF
2010-11-15 18:17:41 +00:00
# define COUNTOF(a) ( sizeof(a) / sizeof(a[0]) )
2010-11-15 18:02:29 +00:00
# endif
2010-04-13 15:25:33 +00:00
// System log debugging turned on
2010-11-15 18:02:29 +00:00
# define SYSTEM_LOG_ADD(a) do{ register int _len = lstrlen(syslogbuf); lstrcpyn(syslogbuf + _len, a, COUNTOF(syslogbuf) - _len); }while(0)
# define SYSTEM_LOG_POST do{ SYSTEM_LOG_ADD(_T("\n")); WriteToLog(syslogbuf); *syslogbuf = 0; }while(0)
2010-04-13 15:25:33 +00:00
HANDLE logfile = NULL ;
TCHAR syslogbuf [ 4096 ] = _T ( " " ) ;
int logop = 0 ;
void WriteToLog ( TCHAR * buffer )
{
DWORD written ;
TCHAR timebuffer [ 128 ] ;
GetTickCount ( ) ;
if ( logfile = = NULL ) return ;
SetFilePointer ( logfile , 0 , 0 , FILE_END ) ;
2011-12-13 21:16:24 +00:00
if ( - 1 ! = logop )
{
wsprintf ( timebuffer , _T ( " %04d %04d.%03d " ) , ( + + logop ) % 10000 ,
( GetTickCount ( ) / 1000 ) % 10000 , GetTickCount ( ) % 1000 ) ;
2010-04-13 15:25:33 +00:00
# ifdef _UNICODE
# ifdef _RPTW0
2011-12-13 21:16:24 +00:00
_RPTW0 ( _CRT_WARN , timebuffer ) ;
_RPTW0 ( _CRT_WARN , buffer ) ;
2010-04-13 15:25:33 +00:00
# endif
# else
2011-12-13 21:16:24 +00:00
_RPT0 ( _CRT_WARN , timebuffer ) ;
_RPT0 ( _CRT_WARN , buffer ) ;
2010-04-13 15:25:33 +00:00
# endif
2011-12-13 21:16:24 +00:00
WriteFile ( logfile , timebuffer , lstrlen ( timebuffer ) * sizeof ( TCHAR ) , & written , NULL ) ;
}
2010-04-13 15:25:33 +00:00
WriteFile ( logfile , buffer , lstrlen ( buffer ) * sizeof ( TCHAR ) , & written , NULL ) ;
// FlushFileBuffers(logfile);
}
PLUGINFUNCTION ( Debug )
{
TCHAR * o1 ;
o1 = system_popstring ( ) ;
if ( logfile = = NULL )
if ( lstrlen ( o1 ) > 0 )
{
SYSTEMTIME t ;
TCHAR buffer [ 1024 ] , buftime [ 1024 ] , bufdate [ 1024 ] ;
// Init debugging
logfile = CreateFile ( o1 , GENERIC_READ | GENERIC_WRITE , FILE_SHARE_READ | FILE_SHARE_WRITE , NULL ,
OPEN_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL ) ;
SetFilePointer ( logfile , 0 , 0 , FILE_END ) ;
logop = 0 ;
# ifdef _UNICODE
{ // write Unicode Byte-Order Mark
DWORD written ;
unsigned short bom = 0xfeff ;
WriteFile ( logfile , & bom , 2 , & written , NULL ) ;
}
# endif
GetLocalTime ( & t ) ;
GetTimeFormat ( LOCALE_SYSTEM_DEFAULT , LOCALE_NOUSEROVERRIDE , & t , NULL , buftime , 1024 ) ;
GetDateFormat ( LOCALE_SYSTEM_DEFAULT , LOCALE_NOUSEROVERRIDE , & t , NULL , bufdate , 1024 ) ;
2013-09-06 23:48:59 +00:00
wsprintf ( buffer , _T ( " System, %s %s [build %hs %hs] \n " ) , buftime , bufdate , __TIME__ , __DATE__ ) ;
2010-04-13 15:25:33 +00:00
WriteToLog ( buffer ) ;
} else ;
else
if ( lstrlen ( o1 ) > 0 )
{
// Log in to log file
2011-12-13 21:16:24 +00:00
int orglogop ;
2010-04-13 15:25:33 +00:00
WriteToLog ( o1 ) ;
2011-12-13 21:16:24 +00:00
orglogop = logop , logop = - 1 ;
WriteToLog ( _T ( " \n " ) ) ;
logop = orglogop ;
2010-04-13 15:25:33 +00:00
} else
{
// Stop debugging
WriteToLog ( _T ( " Debug stopped. \n \n \n " ) ) ;
CloseHandle ( logfile ) ;
logfile = NULL ;
}
2014-05-20 20:13:54 +00:00
if ( o1 ) GlobalFree ( o1 ) ;
2010-04-13 15:25:33 +00:00
} PLUGINFUNCTIONEND
# else
// System log debugging turned off
# define SYSTEM_EVENT(a)
# define SYSTEM_LOG_ADD(a)
# define SYSTEM_LOG_POST
# endif
/**
* This function is useful for Unicode support . Since the Windows
* GetProcAddress function always takes a char * , this function wraps
* the windows call and does the appropriate translation when
* appropriate .
*
* @ param dllHandle Handle to the DLL loaded by LoadLibraryEx .
* @ param funcName The name of the function to get the address of .
* @ return The pointer to the function . Null if failure .
*/
void * NSISGetProcAddress ( HMODULE dllHandle , TCHAR * funcName )
{
# ifdef _UNICODE
char * ansiName = NULL ;
int len ;
2012-09-10 22:56:41 +00:00
void * funcPtr ;
2010-04-13 15:25:33 +00:00
len = WideCharToMultiByte ( CP_ACP , 0 , funcName , - 1 , ansiName , 0 , NULL , NULL ) ;
ansiName = ( char * ) GlobalAlloc ( GPTR , len ) ;
WideCharToMultiByte ( CP_ACP , 0 , funcName , - 1 , ansiName , len , NULL , NULL ) ;
funcPtr = GetProcAddress ( dllHandle , ansiName ) ;
GlobalFree ( ansiName ) ;
return funcPtr ;
# else
return GetProcAddress ( dllHandle , funcName ) ;
# endif
}
PLUGINFUNCTIONSHORT ( Free )
{
2012-03-06 23:09:23 +00:00
HANDLE memtofree = ( HANDLE ) popintptr ( ) ;
2010-04-13 15:25:33 +00:00
2013-09-06 23:48:59 +00:00
if ( g_CallbackThunkListHead )
2010-04-13 15:25:33 +00:00
{
2013-09-06 23:48:59 +00:00
CallbackThunk * pCb = g_CallbackThunkListHead , * pPrev = NULL ;
2010-04-13 15:25:33 +00:00
do
{
if ( GetAssociatedSysProcFromCallbackThunkPtr ( pCb ) = = ( SystemProc * ) memtofree )
{
if ( pPrev )
pPrev - > pNext = pCb - > pNext ;
else
2013-09-06 23:48:59 +00:00
g_CallbackThunkListHead = pCb - > pNext ;
2010-04-13 15:25:33 +00:00
- - ( CallbackIndex ) ;
VirtualFree ( pCb , 0 , MEM_RELEASE ) ;
break ;
}
pPrev = pCb ;
pCb = pCb - > pNext ;
}
while ( pCb ! = NULL ) ;
}
GlobalFree ( memtofree ) ;
}
PLUGINFUNCTIONEND
PLUGINFUNCTION ( Get )
{
SystemProc * proc = PrepareProc ( FALSE ) ;
if ( proc = = NULL )
{
system_pushstring ( _T ( " error " ) ) ;
return ;
}
SYSTEM_LOG_ADD ( _T ( " Get " ) ) ;
SYSTEM_LOG_ADD ( proc - > DllName ) ;
SYSTEM_LOG_ADD ( _T ( " :: " ) ) ;
SYSTEM_LOG_ADD ( proc - > ProcName ) ;
2011-12-13 21:16:24 +00:00
//SYSTEM_LOG_ADD(_T("\n"));
2010-04-13 15:25:33 +00:00
SYSTEM_LOG_POST ;
2017-12-03 18:04:02 +00:00
if ( proc - > Options & POPT_ALWRETURN )
2010-04-13 15:25:33 +00:00
{
// Always return flag set -> return separate proc and result
2012-03-06 23:09:23 +00:00
system_pushintptr ( ( INT_PTR ) proc ) ;
2017-12-03 18:04:02 +00:00
GlobalFree ( system_pushstring ( AllocResultStr ( proc ) ) ) ;
}
else
2010-04-13 15:25:33 +00:00
{
if ( proc - > ProcResult ! = PR_OK )
{
// No always return flag and error result - return result
2017-12-03 18:04:02 +00:00
GlobalFree ( system_pushstring ( AllocResultStr ( proc ) ) ) ;
2010-04-13 15:25:33 +00:00
// If proc is permanent?
2017-12-03 18:04:02 +00:00
if ( ! ( proc - > Options & POPT_PERMANENT ) )
2014-07-01 22:09:38 +00:00
GlobalFree ( ( HGLOBAL ) proc ) ; // No, free it
2010-04-13 15:25:33 +00:00
}
else // Ok result, return proc
2012-03-06 23:09:23 +00:00
system_pushintptr ( ( INT_PTR ) proc ) ;
2010-04-13 15:25:33 +00:00
}
} PLUGINFUNCTIONEND
2013-09-06 23:48:59 +00:00
2018-06-03 21:00:53 +00:00
# ifdef SYSTEM_ARM64
/*
TODO : CallProc not implemeted .
Fake the behavior of the System plugin for the LoadImage API function so MUI works .
BUGBUG : MUI is leaking DeleteObject and failing GetClientRect
*/
SystemProc * CallProc ( SystemProc * proc )
{
INT_PTR ret , * place ;
int cmp = lstrcmp ( proc - > ProcName , sizeof ( TCHAR ) > 1 ? _T ( " LoadImageW " ) : _T ( " LoadImageA " ) ) ;
if ( ! cmp )
{
ret = ( INT_PTR ) LoadImage ( ( HINSTANCE ) proc - > Params [ 1 ] . Value ,
( LPCTSTR ) proc - > Params [ 2 ] . Value , ( UINT ) proc - > Params [ 3 ] . Value ,
( int ) proc - > Params [ 4 ] . Value , ( int ) proc - > Params [ 5 ] . Value ,
( UINT ) proc - > Params [ 6 ] . Value ) ;
LastError = GetLastError ( ) ;
}
else
proc - > ProcResult = PR_ERROR , ret = 0 , LastError = ERROR_INVALID_FUNCTION ;
place = ( INT_PTR * ) proc - > Params [ 0 ] . Value ;
if ( proc - > Params [ 0 ] . Option ! = - 1 ) place = ( INT_PTR * ) & ( proc - > Params [ 0 ] . Value ) ;
if ( place ) * place = ret ;
return proc ;
}
# endif //~ SYSTEM_ARM64
2013-09-06 23:48:59 +00:00
# ifdef _WIN64
/*
2015-09-17 14:30:07 +00:00
BUGBUG : TODO : CallBack support not implemeted !
2013-09-06 23:48:59 +00:00
*/
2014-02-08 00:13:52 +00:00
SystemProc * CallBack ( SystemProc * proc )
2013-09-06 23:48:59 +00:00
{
proc - > ProcResult = PR_ERROR ;
return proc ;
}
2017-11-30 21:38:49 +00:00
# endif //~ _WIN64
2013-09-06 23:48:59 +00:00
2010-04-13 15:25:33 +00:00
PLUGINFUNCTION ( Call )
{
// Prepare input
SystemProc * proc = PrepareProc ( TRUE ) ;
2013-09-06 23:48:59 +00:00
if ( proc = = NULL ) return ;
2010-04-13 15:25:33 +00:00
SYSTEM_LOG_ADD ( _T ( " Call " ) ) ;
SYSTEM_LOG_ADD ( proc - > DllName ) ;
SYSTEM_LOG_ADD ( _T ( " :: " ) ) ;
SYSTEM_LOG_ADD ( proc - > ProcName ) ;
2011-12-13 21:16:24 +00:00
//SYSTEM_LOG_ADD(_T("\n"));
SYSTEM_LOG_POST ;
2013-09-06 23:48:59 +00:00
if ( proc - > ProcResult ! = PR_CALLBACK ) ParamAllocate ( proc ) ;
2010-04-13 15:25:33 +00:00
ParamsIn ( proc ) ;
// Make the call
if ( proc - > ProcResult ! = PR_ERROR )
{
switch ( proc - > ProcType )
{
case PT_NOTHING :
if ( proc - > ProcResult = = PR_CALLBACK )
proc = CallBack ( proc ) ;
break ;
case PT_PROC :
case PT_VTABLEPROC :
proc = CallProc ( proc ) ; break ;
case PT_STRUCT :
CallStruct ( proc ) ; break ;
}
}
// Process output
2017-12-03 18:04:02 +00:00
if ( proc - > Options & POPT_ALWRETURN )
2010-04-13 15:25:33 +00:00
{
// Always return flag set - return separate return and result
ParamsOut ( proc ) ;
2017-12-03 18:04:02 +00:00
GlobalFree ( system_pushstring ( AllocResultStr ( proc ) ) ) ;
2013-09-06 23:48:59 +00:00
}
else
2010-04-13 15:25:33 +00:00
{
if ( proc - > ProcResult ! = PR_OK )
{
2013-09-06 23:48:59 +00:00
ProcParameter pp = proc - > Params [ 0 ] ; // Save old return param
2010-04-13 15:25:33 +00:00
// Return result instead of return value
2017-12-03 18:04:02 +00:00
TCHAR resstr [ 50 ] ;
proc - > Params [ 0 ] . Value = ( INT_PTR ) MakeResultStr ( proc , resstr ) ;
2010-04-13 15:25:33 +00:00
proc - > Params [ 0 ] . Type = PAT_TSTRING ;
2017-12-03 18:04:02 +00:00
proc - > Params [ 0 ] . allocatedBlock = NULL ;
2010-04-13 15:25:33 +00:00
2013-09-06 23:48:59 +00:00
ParamsOut ( proc ) ; // Return all params
proc - > Params [ 0 ] = pp ; // Restore old return param
}
else
2014-03-03 18:10:53 +00:00
ParamsOut ( proc ) ;
2010-04-13 15:25:33 +00:00
}
if ( proc - > ProcResult ! = PR_CALLBACK )
{
ParamsDeAllocate ( proc ) ;
// if not callback - check for unload library option
2013-09-06 23:48:59 +00:00
if ( ( proc - > Options & POPT_UNLOAD ) & & proc - > ProcType = = PT_PROC & & proc - > Dll )
2010-04-13 15:25:33 +00:00
FreeLibrary ( proc - > Dll ) ; // and unload it :)
// In case of POPT_ERROR - first pop will be proc error
if ( ( proc - > Options & POPT_ERROR ) ! = 0 ) system_pushint ( LastError ) ;
}
// If proc is permanent?
2017-12-03 18:04:02 +00:00
if ( ! ( proc - > Options & POPT_PERMANENT ) ) GlobalFree ( ( HGLOBAL ) proc ) ; // No, free it
2010-04-13 15:25:33 +00:00
} PLUGINFUNCTIONEND
PLUGINFUNCTIONSHORT ( Int64Op )
{
__int64 i1 , i2 = 0 , i3 , i4 ;
2014-05-19 22:03:09 +00:00
TCHAR * op ;
# ifndef _WIN64
TCHAR buf [ 25 ] , * o1 , * o2 ;
# endif
2010-04-13 15:25:33 +00:00
2014-05-19 22:03:09 +00:00
// Get parameters: <num1> <op> [num2]
# ifdef _WIN64
i1 = system_popintptr ( ) ;
# else
o1 = system_popstring ( ) , i1 = myatoi64 ( o1 ) ;
# endif
op = system_popstring ( ) ;
2010-04-13 15:25:33 +00:00
if ( ( * op ! = _T ( ' ~ ' ) ) & & ( * op ! = _T ( ' ! ' ) ) )
{
2014-05-19 22:03:09 +00:00
# ifdef _WIN64
i2 = system_popintptr ( ) ;
# else
o2 = system_popstring ( ) , i2 = myatoi64 ( o2 ) , GlobalFree ( o2 ) ;
# endif
2010-04-13 15:25:33 +00:00
}
2015-05-14 20:17:14 +00:00
// Operation
2010-04-13 15:25:33 +00:00
switch ( * op )
{
case _T ( ' + ' ) : i1 + = i2 ; break ;
case _T ( ' - ' ) : i1 - = i2 ; break ;
case _T ( ' * ' ) : i1 * = i2 ; break ;
case _T ( ' / ' ) :
case _T ( ' % ' ) :
// It's unclear, but in this case compiler will use DivMod rountine
// instead of two separate Div and Mod rountines.
if ( i2 = = 0 ) { i3 = 0 ; i4 = i1 ; }
else { i3 = i1 / i2 ; i4 = i1 % i2 ; }
if ( * op = = _T ( ' / ' ) ) i1 = i3 ; else i1 = i4 ;
break ;
case _T ( ' | ' ) : if ( op [ 1 ] = = _T ( ' | ' ) ) i1 = i1 | | i2 ; else i1 | = i2 ; break ;
case _T ( ' & ' ) : if ( op [ 1 ] = = _T ( ' & ' ) ) i1 = i1 & & i2 ; else i1 & = i2 ; break ;
case _T ( ' ^ ' ) : i1 ^ = i2 ; break ;
case _T ( ' ~ ' ) : i1 = ~ i1 ; break ;
case _T ( ' ! ' ) : i1 = ! i1 ; break ;
case _T ( ' < ' ) : if ( op [ 1 ] = = _T ( ' < ' ) ) i1 = i1 < < i2 ; else i1 = i1 < i2 ; break ;
2017-10-08 15:26:54 +00:00
case _T ( ' > ' ) : if ( op [ 1 ] = = _T ( ' > ' ) ) i1 = op [ 2 ] = = _T ( ' > ' ) ? ( UINT64 ) i1 > > ( UINT64 ) i2 : i1 > > i2 ; else i1 = i1 > i2 ; break ;
2010-04-13 15:25:33 +00:00
case _T ( ' = ' ) : i1 = ( i1 = = i2 ) ; break ;
}
// Output and freedom
2014-05-19 22:03:09 +00:00
# ifdef _WIN64
system_pushintptr ( i1 ) ;
# else
myitoa64 ( i1 , buf ) , system_pushstring ( buf ) , GlobalFree ( o1 ) ;
# endif
GlobalFree ( op ) ;
2010-04-13 15:25:33 +00:00
} PLUGINFUNCTIONEND
__int64 GetIntFromString ( TCHAR * * p )
{
TCHAR buffer [ 128 ] , * b = buffer ;
( * p ) + + ; // First character should be skipped
while ( ( ( * * p > = _T ( ' a ' ) ) & & ( * * p < = _T ( ' f ' ) ) ) | | ( ( * * p > = _T ( ' A ' ) ) & & ( * * p < = _T ( ' F ' ) ) ) | | ( ( * * p > = _T ( ' 0 ' ) ) & & ( * * p < = _T ( ' 9 ' ) ) ) | | ( * * p = = _T ( ' X ' ) ) | | ( * * p = = _T ( ' - ' ) ) | | ( * * p = = _T ( ' x ' ) ) | | ( * * p = = _T ( ' | ' ) ) ) * ( b + + ) = * ( ( * p ) + + ) ;
* b = 0 ;
( * p ) - - ; // We should point at last digit
return myatoi64 ( buffer ) ;
}
SystemProc * PrepareProc ( BOOL NeedForCall )
{
int SectionType = PST_PROC , // First section is always proc spec
ProcType = PT_NOTHING , // Default proc spec
ChangesDone = 0 ,
ParamIndex = 0 ,
2012-09-10 22:56:41 +00:00
temp = 0 , temp2 , temp3 ;
INT_PTR temp4 ;
2010-04-13 15:25:33 +00:00
BOOL param_defined = FALSE ;
SystemProc * proc = NULL ;
TCHAR * ibuf , * ib , * sbuf , * cbuf , * cb ;
2017-12-03 18:04:02 +00:00
unsigned int UsedTString = 0 , aligntype ;
# ifdef POPT_SYNTAX2
const UINT alignflag = PAT_ALIGNFLAG ;
# else
const UINT alignflag = 0 ;
# endif
2010-04-13 15:25:33 +00:00
2015-09-17 14:30:07 +00:00
# ifdef __GNUC__
2014-07-19 19:21:43 +00:00
temp3 = 0 ; // "warning: 'temp3' may be used uninitialized in this function": temp3 is set to 0 when we start parsing a new parameter
# endif
2010-04-13 15:25:33 +00:00
// Retrieve proc specs
cb = ( cbuf = AllocString ( ) ) ; // Current String buffer
sbuf = AllocString ( ) ; // Safe String buffer
ib = ibuf = system_popstring ( ) ; // Input string
// Parse the string
while ( SectionType ! = - 1 )
{
// Check for Section Change
BOOL changed = TRUE ;
ChangesDone = SectionType ;
if ( SectionType ! = PST_PROC & & proc = = NULL )
// no proc after PST_PROC is done means something is wrong with
// the call syntax and we'll get a crash because everything needs
// proc from here on.
break ;
switch ( * ib )
{
case 0x0 : SectionType = - 1 ; break ;
2013-12-09 01:17:55 +00:00
case _T ( ' # ' ) : // "...#" redefines proc unless preceded by ":", then it's an ordinal (dll::#123)
if ( ib < = ibuf | | * ( ib - 1 ) ! = _T ( ' : ' ) | | PST_PROC ! = SectionType )
SectionType = PST_PROC , ProcType = PT_NOTHING ;
else
changed = FALSE ;
break ;
2010-04-13 15:25:33 +00:00
case _T ( ' ( ' ) :
SectionType = PST_PARAMS ;
// fake-real parameter: for COM interfaces first param is Interface Pointer
2017-12-03 18:04:02 +00:00
ParamIndex = ( ( ProcType = = PT_VTABLEPROC ) ? ( 2 ) : ( 1 ) ) ;
2010-04-13 15:25:33 +00:00
temp3 = temp = 0 ;
param_defined = FALSE ;
break ;
case _T ( ' ) ' ) : SectionType = PST_RETURN ; temp3 = temp = 0 ; break ;
case _T ( ' ? ' ) : SectionType = PST_OPTIONS ; temp = 1 ; break ;
default :
changed = FALSE ;
}
// Check for changes
if ( changed )
{
switch ( ChangesDone )
{
case PST_PROC :
* cb = 0 ;
// Adopt proc
if ( proc = = NULL )
{
proc = ( SystemProc * ) GlobalAlloc ( GPTR , sizeof ( SystemProc ) ) ;
proc - > Options = 0 ;
proc - > ParamCount = 0 ;
}
// Default parameters
* proc - > DllName = 0 ;
* proc - > ProcName = 0 ;
proc - > Dll = NULL ;
proc - > Proc = NULL ;
proc - > ProcType = ProcType ;
proc - > ProcResult = PR_OK ;
// Section changed and previos section was Proc
switch ( ProcType )
{
case PT_NOTHING :
// Is it previous proc or just unknown proc?
if ( cb ! = cbuf )
{
// Previous proc (for clear up)
SystemProc * pr = NULL ;
if ( proc ! = NULL ) GlobalFree ( proc ) ;
// Get already defined proc
2012-03-06 23:09:23 +00:00
proc = ( SystemProc * ) StrToIntPtr ( cbuf ) ;
2010-04-13 15:25:33 +00:00
if ( ! proc ) break ;
// Find the last clone at proc queue
while ( proc & & ( proc - > Clone ! = NULL ) ) proc = ( pr = proc ) - > Clone ;
// Clear parents record for child callback proc
if ( pr ! = NULL ) pr - > Clone = NULL ;
// Never Redefine?
2017-12-03 18:04:02 +00:00
if ( proc - > Options & POPT_NEVERREDEF )
2010-04-13 15:25:33 +00:00
{
2017-12-03 18:04:02 +00:00
proc = GlobalCopy ( proc ) ; // Create new proc as copy
proc - > Options & = ~ ( POPT_NEVERREDEF | POPT_PERMANENT ) ; // NeverRedef options is never inherited
}
else
proc - > Options | = POPT_PERMANENT ; // Proc is old -> permanent
2010-04-13 15:25:33 +00:00
}
break ;
case PT_PROC :
case PT_VTABLEPROC :
lstrcpy ( proc - > DllName , sbuf ) ;
case PT_STRUCT :
lstrcpy ( proc - > ProcName , cbuf ) ;
break ;
}
break ;
case PST_PARAMS :
if ( param_defined )
proc - > ParamCount = ParamIndex ;
else
// not simply zero because of vtable calls
proc - > ParamCount = ParamIndex - 1 ;
case PST_RETURN :
case PST_OPTIONS :
break ;
2011-12-13 21:16:24 +00:00
}
2010-04-13 15:25:33 +00:00
ib + + ;
cb = cbuf ;
continue ;
}
// Parse the section
ChangesDone = PCD_NONE ;
switch ( SectionType )
{
// Proc sections parser
case PST_PROC :
switch ( * ib )
{
case _T ( ' : ' ) :
case _T ( ' - ' ) :
// Is it '::'
if ( ( * ( ib ) = = _T ( ' - ' ) ) & & ( * ( ib + 1 ) = = _T ( ' > ' ) ) )
{
2017-10-07 18:56:03 +00:00
ProcType = PT_VTABLEPROC ;
2010-04-13 15:25:33 +00:00
} else
{
if ( ( * ( ib + 1 ) ! = _T ( ' : ' ) ) | | ( * ( ib ) = = _T ( ' - ' ) ) ) break ;
ProcType = PT_PROC ;
}
ib + + ; // Skip next ':'
if ( cb > cbuf )
{
* cb = 0 ;
lstrcpy ( sbuf , cbuf ) ;
} else * sbuf = 0 ; // No dll - system proc
// Ok
ChangesDone = PCD_DONE ;
break ;
case _T ( ' * ' ) :
// Structure defenition
ProcType = PT_STRUCT ;
ChangesDone = PCD_DONE ;
break ;
2011-12-13 21:16:24 +00:00
}
2010-04-13 15:25:33 +00:00
break ;
// Params and return sections parser
case PST_RETURN :
ParamIndex = 0 ; // Uses the same logic as PST_PARAMS section
case PST_PARAMS :
temp2 = - 1 ; temp4 = 0 ; // Our type placeholder
2017-12-03 18:04:02 +00:00
aligntype = FALSE ;
2010-04-13 15:25:33 +00:00
switch ( * ib )
{
case _T ( ' ' ) :
break ;
case _T ( ' _ ' ) : // No param cutting specifier
if ( proc - > ParamCount > ParamIndex ) ParamIndex = proc - > ParamCount ;
temp3 = temp = 0 ; // Clear parameter options
if ( proc - > ParamCount ! = ( ( ProcType = = PT_VTABLEPROC ) ? 1 : 0 ) )
{
// only define params if the last count wasn't zero
// this prevents errornous param count for:
// 'user32::CloseClipboard()(_)'
// for vtable calls, param count should not be one
param_defined = TRUE ;
}
break ;
case _T ( ' , ' ) : // Next param
temp3 = temp = 0 ; // Clear parameter options
ParamIndex + + ;
param_defined = TRUE ;
break ;
case _T ( ' & ' ) :
2017-12-03 18:04:02 +00:00
temp = PAO_ARRBASE ; break ; // Special parameter option
2010-04-13 15:25:33 +00:00
case _T ( ' * ' ) :
2017-12-03 18:04:02 +00:00
temp = PAO_PTRFLAG ; break ; // Pointer parameter option
2010-04-13 15:25:33 +00:00
// Types
2014-06-27 14:27:32 +00:00
case _T ( ' @ ' ) : temp2 = PAT_REGMEM ; break ;
2017-12-03 18:04:02 +00:00
case _T ( ' V ' ) : // No extra alignment for void padding
case _T ( ' v ' ) : temp2 = PAT_VOID ; break ;
case ' B ' : aligntype + = alignflag ? 1 : 0 ;
case ' b ' : temp2 = PAT_INT , temp = sizeof ( BYTE ) + 1 ; break ; // INT8/BYTE/BOOLEAN alias for &1
case ' H ' : aligntype + = alignflag ? 1 : 0 ;
case ' h ' : temp2 = PAT_INT , temp = sizeof ( WORD ) + 1 ; break ; // INT16/WORD/SHORT alias for &2 with 'h' AKA printf type length specifier
# ifndef _WIN64
case _T ( ' P ' ) :
# endif
case _T ( ' I ' ) : aligntype + = alignflag ? 1 : 0 ;
2013-09-06 23:48:59 +00:00
# ifndef _WIN64
case _T ( ' p ' ) :
# endif
2017-12-03 18:04:02 +00:00
case _T ( ' i ' ) : temp2 = PAT_INT ; break ; // INT32
# ifdef _WIN64
case _T ( ' P ' ) :
# endif
case _T ( ' L ' ) : aligntype + = alignflag ? 1 : 0 ;
2013-09-06 23:48:59 +00:00
# ifdef _WIN64
case _T ( ' p ' ) :
# endif
2017-12-03 18:04:02 +00:00
case _T ( ' l ' ) : temp2 = PAT_LONG ; break ; // INT64
case _T ( ' M ' ) : // 1 byte, no extra alignment
case _T ( ' m ' ) : temp2 = PAT_STRING ; break ;
case _T ( ' T ' ) : aligntype + = ( alignflag & & sizeof ( TCHAR ) > 1 ) ? 1 : 0 ;
case _T ( ' t ' ) : temp2 = PAT_TSTRING , + + UsedTString ; break ;
case _T ( ' G ' ) : aligntype + = alignflag ? 1 : 0 ;
case _T ( ' g ' ) : temp2 = PAT_GUID ; break ;
case _T ( ' W ' ) : aligntype + = alignflag ? 1 : 0 ;
case _T ( ' w ' ) : temp2 = PAT_WSTRING ; break ;
case _T ( ' K ' ) : aligntype + = alignflag ? 1 : 0 ;
case _T ( ' k ' ) : temp2 = PAT_CALLBACK ; break ;
2010-04-13 15:25:33 +00:00
// Input output specifiers
case _T ( ' . ' ) : temp3 + + ; break ; // skip specifier
case _T ( ' R ' ) :
2012-09-10 22:56:41 +00:00
temp4 = ( ( INT_PTR ) GetIntFromString ( & ib ) ) + 1 ;
2010-04-13 15:25:33 +00:00
if ( temp4 < 11 ) temp4 + = 10 ;
break ;
2012-09-10 22:56:41 +00:00
case _T ( ' r ' ) : temp4 = ( ( INT_PTR ) GetIntFromString ( & ib ) ) + 1 ; break ; // Register
2010-04-13 15:25:33 +00:00
case _T ( ' - ' ) :
case _T ( ' 0 ' ) : case _T ( ' 1 ' ) : case _T ( ' 2 ' ) : case _T ( ' 3 ' ) : case _T ( ' 4 ' ) :
case _T ( ' 5 ' ) : case _T ( ' 6 ' ) : case _T ( ' 7 ' ) : case _T ( ' 8 ' ) : case _T ( ' 9 ' ) :
// Numeric inline
if ( temp3 = = 0 )
{
ib - - ;
2012-03-06 23:09:23 +00:00
// It's stupid, I know, but I'm too lazy to do another thing
2012-09-10 22:56:41 +00:00
myitoa64 ( GetIntFromString ( & ( ib ) ) , ( TCHAR * ) ( temp4 = ( INT_PTR ) AllocString ( ) ) ) ;
2010-04-13 15:25:33 +00:00
}
break ;
case _T ( ' \" ' ) : case _T ( ' \' ' ) : case _T ( ' ` ' ) :
// Character inline
{
TCHAR start = * ib ;
cb = cbuf ;
// copy inline
while ( ! ( ( * ( + + ib ) = = start ) & & ( * ( ib + 1 ) ! = start ) ) & & ( * ib ) )
{
if ( ( * ib ) = = start ) + + ib ;
* ( cb + + ) = * ( ib ) ;
}
// finish and save
* cb = 0 ;
2012-09-10 22:56:41 +00:00
temp4 = ( INT_PTR ) AllocStr ( cbuf ) ;
2010-04-13 15:25:33 +00:00
}
break ;
case _T ( ' s ' ) :
2017-10-07 18:56:03 +00:00
case _T ( ' S ' ) : temp4 = - 1 ; break ; // Stack
2010-04-13 15:25:33 +00:00
case _T ( ' c ' ) :
case _T ( ' C ' ) : temp4 = INST_CMDLINE + 1 ; break ;
case _T ( ' d ' ) :
case _T ( ' D ' ) : temp4 = INST_INSTDIR + 1 ; break ;
case _T ( ' o ' ) :
case _T ( ' O ' ) : temp4 = INST_OUTDIR + 1 ; break ;
case _T ( ' e ' ) :
case _T ( ' E ' ) : temp4 = INST_EXEDIR + 1 ; break ;
case _T ( ' a ' ) :
case _T ( ' A ' ) : temp4 = INST_LANG + 1 ; break ;
}
// Param type changed?
if ( temp2 ! = - 1 )
{
2012-09-10 22:56:41 +00:00
const int psbt = ParamSizeByType [ temp2 ] ;
2010-04-13 15:25:33 +00:00
param_defined = TRUE ;
2017-12-03 18:04:02 +00:00
proc - > Params [ ParamIndex ] . Type = temp2 | ( alignflag & & aligntype ? alignflag : 0 ) ;
2012-09-10 22:56:41 +00:00
proc - > Params [ ParamIndex ] . Size = // Pointer sized or from type
2017-12-03 18:04:02 +00:00
ParamOptionIsPointer ( temp ) ? ( PARAMSIZEBYTYPE_PTR ) : ( ( psbt > 0 ) ? ( psbt ) : ( 1 ) ) ; //BUGBUG64: Is it safe to fallback to 1 for CALLBACK?
if ( temp = = PAO_ARRBASE ) temp =
PAO_ARRBASE + ( ( int ) GetIntFromString ( & ib ) ) ; // Read '&' array count specification
2010-04-13 15:25:33 +00:00
proc - > Params [ ParamIndex ] . Option = temp ;
proc - > Params [ ParamIndex ] . Value = 0 ;
proc - > Params [ ParamIndex ] . Input = IOT_NONE ;
proc - > Params [ ParamIndex ] . Output = IOT_NONE ;
}
// Param source/dest changed?
if ( temp4 ! = 0 )
{
param_defined = TRUE ;
if ( temp3 = = 0 )
{
// it may contain previous inline input
if ( ! ( ( proc - > Params [ ParamIndex ] . Input > - 1 ) & & ( proc - > Params [ ParamIndex ] . Input < = __INST_LAST ) ) )
2014-07-01 22:09:38 +00:00
GlobalFree ( ( HGLOBAL ) proc - > Params [ ParamIndex ] . Input ) ;
proc - > Params [ ParamIndex ] . Input = temp4 ;
2010-04-13 15:25:33 +00:00
}
if ( temp3 = = 1 )
2014-07-01 22:09:38 +00:00
proc - > Params [ ParamIndex ] . Output = ( int ) temp4 ; // Note: As long as we never assign a pointer to temp4 when parsing a destination the cast to int is OK.
2010-04-13 15:25:33 +00:00
// Next parameter is output or something else
temp3 + + ;
}
ChangesDone = PCD_DONE ;
break ;
// Options sections parser
case PST_OPTIONS :
temp2 = 0 ;
switch ( * ib )
{
2017-12-03 18:04:02 +00:00
case _T ( ' ' ) : break ;
2010-04-13 15:25:33 +00:00
case _T ( ' ! ' ) : temp = - temp ; break ;
case _T ( ' c ' ) :
2014-03-03 18:10:53 +00:00
# ifndef _WIN64
2017-12-03 18:04:02 +00:00
temp2 = POPT_CDECL ; // Only x86 cares, just eat the option for everything else
2014-03-03 18:10:53 +00:00
# endif
2010-04-13 15:25:33 +00:00
break ;
2017-12-03 18:04:02 +00:00
case _T ( ' r ' ) : temp2 = POPT_ALWRETURN ; break ;
case _T ( ' n ' ) : temp2 = POPT_NEVERREDEF ; break ;
case _T ( ' s ' ) : temp2 = POPT_GENSTACK ; break ;
case _T ( ' e ' ) : temp2 = POPT_ERROR ; break ;
case _T ( ' u ' ) : temp2 = POPT_UNLOAD ; break ;
# ifdef POPT_SYNTAX2
case _T ( ' 2 ' ) : temp2 = POPT_SYNTAX2 ; break ;
# endif
2010-04-13 15:25:33 +00:00
}
// New Options
if ( temp2 ! = 0 )
{
2017-12-03 18:04:02 +00:00
if ( temp = = 1 ) proc - > Options | = temp2 ; else proc - > Options & = ~ temp2 ;
2010-04-13 15:25:33 +00:00
// Back to default (turn on nothing) state
temp = 1 ; temp2 = 0 ;
}
ChangesDone = PCD_DONE ;
break ;
}
// Nothing done, just copy char to buffer
if ( ChangesDone = = PCD_NONE ) * ( cb + + ) = * ( ib ) ;
// Something done, buffer = ""
else cb = cbuf ;
// Increase input pointer
ib + + ;
}
GlobalFree ( ibuf ) ;
GlobalFree ( cbuf ) ;
GlobalFree ( sbuf ) ;
// Ok, the final step: check proc for existance
if ( proc ! = NULL & & proc - > Proc = = NULL )
{
switch ( proc - > ProcType )
{
case PT_NOTHING : break ;
case PT_VTABLEPROC :
{
// Use direct system proc address
2012-09-10 22:56:41 +00:00
INT_PTR addr ;
2010-04-13 15:25:33 +00:00
2012-03-06 23:09:23 +00:00
proc - > Dll = ( HMODULE ) StrToIntPtr ( proc - > DllName ) ;
2010-04-13 15:25:33 +00:00
if ( proc - > Dll = = 0 )
{
proc - > ProcResult = PR_ERROR ;
break ;
}
2012-09-10 22:56:41 +00:00
addr = ( INT_PTR ) proc - > Dll ;
2010-04-13 15:25:33 +00:00
// fake-real parameter: for COM interfaces first param is Interface Pointer
proc - > Params [ 1 ] . Output = IOT_NONE ;
2014-07-01 22:09:38 +00:00
proc - > Params [ 1 ] . Input = ( INT_PTR ) AllocStr ( proc - > DllName ) ;
2012-09-10 22:56:41 +00:00
proc - > Params [ 1 ] . Size = PARAMSIZEBYTYPE_PTR ;
proc - > Params [ 1 ] . Type = PAT_PTR ;
2010-04-13 15:25:33 +00:00
proc - > Params [ 1 ] . Option = 0 ;
// addr - pointer to interface vtable
2012-09-10 22:56:41 +00:00
addr = * ( ( INT_PTR * ) addr ) ;
2010-04-13 15:25:33 +00:00
// now addr contains the pointer to first item at VTABLE
// add the index of proc
2012-09-10 22:56:41 +00:00
addr = addr + ( INT_PTR ) ( myatoi64 ( proc - > ProcName ) * sizeof ( void * ) ) ;
2010-04-13 15:25:33 +00:00
proc - > Proc = * ( ( HANDLE * ) addr ) ;
}
break ;
case PT_PROC :
if ( * proc - > DllName = = 0 )
{
// Use direct system proc address
2012-03-06 23:09:23 +00:00
if ( ( proc - > Proc = ( HANDLE ) StrToIntPtr ( proc - > ProcName ) ) = = 0 )
2010-04-13 15:25:33 +00:00
proc - > ProcResult = PR_ERROR ;
} else
{
// Get DLL address
if ( ( proc - > Dll = GetModuleHandle ( proc - > DllName ) ) = = NULL )
if ( ( proc - > Dll = LoadLibrary ( proc - > DllName ) ) = = NULL )
{
proc - > ProcResult = PR_ERROR ;
break ;
}
// Get proc address
2010-05-28 14:09:08 +00:00
proc - > Proc = NSISGetProcAddress ( proc - > Dll , proc - > ProcName ) ;
2013-12-09 01:17:55 +00:00
if ( ! proc - > Proc & & * proc - > ProcName = = _T ( ' # ' ) )
{
int ordinal = myatoi ( proc - > ProcName + 1 ) ;
if ( ordinal & & IS_INTRESOURCE ( ordinal ) )
proc - > Proc = GetProcAddress ( proc - > Dll , MAKEINTRESOURCEA ( ordinal ) ) ;
}
2012-06-21 23:13:05 +00:00
if ( UsedTString | | ! proc - > Proc )
2010-04-13 15:25:33 +00:00
{
2012-03-06 00:26:12 +00:00
FARPROC tproc ;
TCHAR * ProcName = proc - > ProcName ; // This buffer has room for us to party on
unsigned int cch = lstrlen ( ProcName ) ;
2010-04-13 15:25:33 +00:00
# ifdef _UNICODE
2012-03-06 00:26:12 +00:00
STRSET2CH ( ProcName + cch , _T ( ' W ' ) , _T ( ' \0 ' ) ) ;
2010-04-13 15:25:33 +00:00
# else
2012-03-06 00:26:12 +00:00
STRSET2CH ( ProcName + cch , _T ( ' A ' ) , _T ( ' \0 ' ) ) ;
2010-04-13 15:25:33 +00:00
# endif
2012-03-06 00:26:12 +00:00
tproc = NSISGetProcAddress ( proc - > Dll , ProcName ) ;
2012-06-21 23:13:05 +00:00
if ( tproc )
proc - > Proc = tproc ;
else
2013-12-09 01:17:55 +00:00
if ( ! proc - > Proc ) proc - > ProcResult = PR_ERROR ;
2012-03-06 00:26:12 +00:00
}
2010-04-13 15:25:33 +00:00
}
break ;
case PT_STRUCT :
2012-03-06 23:09:23 +00:00
if ( * ( proc - > ProcName ) ! = 0 ) proc - > Proc = ( HANDLE ) StrToIntPtr ( proc - > ProcName ) ;
2010-04-13 15:25:33 +00:00
break ;
}
}
return proc ;
}
void ParamAllocate ( SystemProc * proc )
{
2017-12-03 18:04:02 +00:00
UINT i , c ;
for ( i = 0 , c = proc - > ParamCount ; i < = c ; i + + )
if ( ! proc - > Params [ i ] . Value & & ParamIsPointer ( proc - > Params [ i ] ) )
proc - > Params [ i ] . Value = ( INT_PTR ) GlobalAlloc ( GPTR , ParamSizeByType [ GetParamType ( proc - > Params [ i ] ) ] * 4 ) ;
2010-04-13 15:25:33 +00:00
}
void ParamsIn ( SystemProc * proc )
{
int i ;
HGLOBAL * place ;
TCHAR * realbuf ;
2012-03-06 00:26:12 +00:00
# ifndef _UNICODE
2010-04-13 15:25:33 +00:00
LPWSTR wstr ;
2012-03-06 00:26:12 +00:00
# endif
2017-10-07 18:56:03 +00:00
# if !defined(_WIN64) && defined(C_ASSERT)
C_ASSERT ( FIELD_OFFSET ( ProcParameter , Value ) + sizeof ( int ) = = FIELD_OFFSET ( ProcParameter , _value ) ) ; // Make sure PAT_LONG writes to the correct places
# endif
2010-04-13 15:25:33 +00:00
i = ( proc - > ParamCount > 0 ) ? ( 1 ) : ( 0 ) ;
while ( TRUE )
{
ProcParameter * par = & proc - > Params [ i ] ;
2017-12-03 18:04:02 +00:00
UINT partype ;
2010-04-13 15:25:33 +00:00
// Step 1: retrive value
if ( ( par - > Input = = IOT_NONE ) | | ( par - > Input = = IOT_INLINE ) )
realbuf = AllocStr ( _T ( " " ) ) ;
else if ( par - > Input = = IOT_STACK ) realbuf = system_popstring ( ) ;
else if ( ( par - > Input > 0 ) & & ( par - > Input < = __INST_LAST ) )
2014-07-01 22:09:38 +00:00
realbuf = system_getuservariable ( ( int ) par - > Input - 1 ) ;
2010-04-13 15:25:33 +00:00
else
{
// Inline input, will be freed as realbuf
realbuf = ( TCHAR * ) par - > Input ;
par - > Input = IOT_INLINE ;
}
// Retreive pointer to place
2017-12-03 18:04:02 +00:00
place = ParamIsPointer ( * par ) ? ( HGLOBAL * ) par - > Value : ( HGLOBAL * ) & ( par - > Value ) ;
2010-04-13 15:25:33 +00:00
// by default no blocks are allocated
par - > allocatedBlock = NULL ;
// Step 2: place it
2017-12-03 18:04:02 +00:00
switch ( partype = GetParamType ( * par ) )
2010-04-13 15:25:33 +00:00
{
case PAT_VOID :
par - > Value = 0 ;
break ;
case PAT_INT :
2012-03-06 23:09:23 +00:00
* ( int * ) place = myatoi ( realbuf ) ;
2010-04-13 15:25:33 +00:00
break ;
case PAT_LONG :
* ( __int64 * ) place = myatoi64 ( realbuf ) ;
break ;
case PAT_TSTRING :
/* if (par->Input == IOT_NONE)
* ( ( int * ) place ) = ( int ) NULL ;
else */
* place = par - > allocatedBlock = AllocStr ( realbuf ) ;
break ;
# ifdef _UNICODE
case PAT_STRING :
* place = par - > allocatedBlock = GlobalAlloc ( GPTR , g_stringsize ) ;
WideCharToMultiByte ( CP_ACP , 0 , realbuf , g_stringsize , * ( LPSTR * ) place , g_stringsize , NULL , NULL ) ;
break ;
case PAT_GUID :
* place = par - > allocatedBlock = GlobalAlloc ( GPTR , 16 ) ;
CLSIDFromString ( realbuf , * ( LPCLSID * ) place ) ;
break ;
# else
case PAT_WSTRING :
case PAT_GUID :
wstr = ( LPWSTR ) GlobalAlloc ( GPTR , g_stringsize * sizeof ( WCHAR ) ) ;
MultiByteToWideChar ( CP_ACP , 0 , realbuf , g_stringsize , wstr , g_stringsize ) ;
2017-12-03 18:04:02 +00:00
if ( partype = = PAT_GUID )
2010-04-13 15:25:33 +00:00
{
* place = par - > allocatedBlock = GlobalAlloc ( GPTR , 16 ) ;
CLSIDFromString ( wstr , * ( LPCLSID * ) place ) ;
GlobalFree ( ( HGLOBAL ) wstr ) ;
} else
* place = par - > allocatedBlock = ( HGLOBAL ) wstr ;
break ;
# endif
case PAT_CALLBACK :
// Generate new or use old callback
2017-06-06 19:51:43 +00:00
if ( realbuf [ 0 ] )
2014-02-08 00:13:52 +00:00
par - > Value = ( INT_PTR ) CreateCallback ( ( SystemProc * ) StrToIntPtr ( realbuf ) ) ;
2010-04-13 15:25:33 +00:00
break ;
2014-06-27 14:27:32 +00:00
case PAT_REGMEM :
2014-06-28 19:54:51 +00:00
{
LPTSTR straddr = system_getuservariableptr ( par - > Input - 1 ) ;
par - > Value = ( INT_PTR ) straddr ;
par - > Value + = sizeof ( void * ) > 4 ? sizeof ( _T ( " -9223372036854775807 " ) ) : sizeof ( _T ( " -2147483647 " ) ) ;
IntPtrToStr ( par - > Value , straddr ) ;
}
2014-06-27 14:27:32 +00:00
break ;
2010-04-13 15:25:33 +00:00
}
GlobalFree ( realbuf ) ;
# ifdef SYSTEM_LOG_DEBUG
{
2012-03-06 23:09:23 +00:00
TCHAR buf [ 666 ] ;
2014-03-03 18:10:53 +00:00
UINT32 hi32 = 0 ;
# ifndef _WIN64
hi32 = par - > _value ;
# endif
2017-12-03 18:04:02 +00:00
wsprintf ( buf , _T ( " \t \t \t Param In %d: \t Type=%#x Value= " ) SYSFMT_HEXPTR _T ( " hi32=0x%08X " ) , i ,
2014-03-03 18:10:53 +00:00
par - > Type , par - > Value , hi32 ) ;
2010-04-13 15:25:33 +00:00
SYSTEM_LOG_ADD ( buf ) ;
2011-12-13 21:16:24 +00:00
SYSTEM_LOG_POST ;
2010-04-13 15:25:33 +00:00
}
# endif
if ( i = = 0 ) break ;
2014-03-03 18:10:53 +00:00
if ( i = = proc - > ParamCount ) i = 0 ; else i + + ;
2011-12-13 21:16:24 +00:00
}
2010-04-13 15:25:33 +00:00
}
void ParamsDeAllocate ( SystemProc * proc )
{
int i ;
for ( i = proc - > ParamCount ; i > = 0 ; i - - )
2017-12-03 18:04:02 +00:00
if ( proc - > Params [ i ] . Value & & ParamIsPointer ( proc - > Params [ i ] ) )
2010-04-13 15:25:33 +00:00
{
2014-07-01 22:09:38 +00:00
GlobalFree ( ( HGLOBAL ) ( proc - > Params [ i ] . Value ) ) ;
2013-09-06 23:48:59 +00:00
proc - > Params [ i ] . Value = 0 ;
2010-04-13 15:25:33 +00:00
}
}
2017-12-03 18:04:02 +00:00
# define GetSpecialParamTypeSize(par) ( (((par).Option)-PAO_ARRBASE) * ByteSizeByType[GetParamType(par)] ) // Option must be > PAO_ARRBASE!
2017-11-30 21:38:49 +00:00
static const int g_intmask [ 4 ] = { 0xFFFFFFFF , 0x000000FF , 0x0000FFFF , 0x00FFFFFF } ;
2017-12-03 18:04:02 +00:00
# define GetMaskedInt32Value(val, size) ( (val) & g_intmask[((UINT)(size) < 4) ? (size) : (0)] )
# define GetSpecialParamInt32Value(par, size) GetMaskedInt32Value((par).Value, (size))
2017-11-30 21:38:49 +00:00
2010-04-13 15:25:33 +00:00
void ParamsOut ( SystemProc * proc )
{
2013-09-06 23:48:59 +00:00
INT_PTR * place ;
2010-04-13 15:25:33 +00:00
LPWSTR wstr ;
2017-12-03 18:04:02 +00:00
int i , partype , intval , typsiz ;
2014-07-01 22:09:38 +00:00
TCHAR * realbuf = AllocString ( ) ;
2010-04-13 15:25:33 +00:00
i = proc - > ParamCount ;
do
{
// Retreive pointer to place
2017-12-03 18:04:02 +00:00
if ( ParamIsPointer ( proc - > Params [ i ] ) )
2014-07-01 22:09:38 +00:00
place = ( INT_PTR * ) proc - > Params [ i ] . Value ;
else
place = ( INT_PTR * ) & ( proc - > Params [ i ] . Value ) ;
2010-04-13 15:25:33 +00:00
// Step 1: retrive value
2017-12-03 18:04:02 +00:00
switch ( partype = GetParamType ( proc - > Params [ i ] ) )
2010-04-13 15:25:33 +00:00
{
case PAT_VOID :
2014-03-06 17:26:49 +00:00
* realbuf = _T ( ' \0 ' ) ;
2010-04-13 15:25:33 +00:00
break ;
2014-06-27 14:27:32 +00:00
# ifndef _WIN64
case PAT_REGMEM :
# endif
2010-04-13 15:25:33 +00:00
case PAT_INT :
2017-11-30 21:38:49 +00:00
intval = ( int ) ( * ( ( INT_PTR * ) place ) ) ;
if ( proc - > Params [ i ] . Option > 0 ) // Note: We don't handle '*' pointers, "*h" and "*b" are not supported, use "*i" even on smaller types
{
2017-12-03 18:04:02 +00:00
typsiz = GetSpecialParamTypeSize ( proc - > Params [ i ] ) ;
2017-11-30 21:38:49 +00:00
intval = GetMaskedInt32Value ( intval , typsiz ) ;
}
wsprintf ( realbuf , _T ( " %d " ) , intval ) ;
2010-04-13 15:25:33 +00:00
break ;
2014-06-27 14:27:32 +00:00
# ifdef _WIN64
case PAT_REGMEM :
# endif
2010-04-13 15:25:33 +00:00
case PAT_LONG :
myitoa64 ( * ( ( __int64 * ) place ) , realbuf ) ;
break ;
case PAT_STRING :
# ifdef _UNICODE
MultiByteToWideChar ( CP_ACP , 0 , * ( ( char * * ) place ) , g_stringsize , realbuf , g_stringsize - 1 ) ;
realbuf [ g_stringsize - 1 ] = _T ( ' \0 ' ) ; // make sure we have a null terminator
# else
2017-11-30 21:38:49 +00:00
lstrcpyn ( realbuf , * ( ( TCHAR * * ) place ) , g_stringsize ) ; // note: lstrcpyn always includes a null terminator (unlike strncpy)
2010-04-13 15:25:33 +00:00
# endif
break ;
case PAT_GUID :
# ifdef _UNICODE
StringFromGUID2 ( * ( ( REFGUID * ) place ) , realbuf , g_stringsize ) ;
# else
2014-07-01 22:09:38 +00:00
{
WCHAR guidstrbuf [ 39 ] ;
2015-10-16 20:50:06 +00:00
int guidcch = StringFromGUID2 ( * ( ( REFGUID * ) place ) , guidstrbuf , 39 ) ;
2014-07-01 22:09:38 +00:00
WideCharToMultiByte ( CP_ACP , 0 , guidstrbuf , guidcch , realbuf , g_stringsize , NULL , NULL ) ;
}
2010-04-13 15:25:33 +00:00
# endif
break ;
case PAT_WSTRING :
wstr = * ( ( LPWSTR * ) place ) ;
# ifdef _UNICODE
lstrcpyn ( realbuf , wstr , g_stringsize ) ; // note: lstrcpyn always include a null terminator (unlike strncpy)
# else
WideCharToMultiByte ( CP_ACP , 0 , wstr , g_stringsize , realbuf , g_stringsize - 1 , NULL , NULL ) ;
realbuf [ g_stringsize - 1 ] = _T ( ' \0 ' ) ; // make sure we have a null terminator
# endif
break ;
case PAT_CALLBACK :
2017-10-07 18:56:03 +00:00
wsprintf ( realbuf , sizeof ( void * ) > 4 ? _T ( " %Id " ) : _T ( " %d " ) , proc - > Params [ i ] . Value ) ;
2010-04-13 15:25:33 +00:00
break ;
}
// memory cleanup
2017-12-03 18:04:02 +00:00
if ( ( proc - > Params [ i ] . allocatedBlock ! = NULL )
2018-01-06 17:51:06 +00:00
& & ( ( proc - > ProcType ! = PT_STRUCT ) | | ParamIsArray ( proc - > Params [ i ] ) )
2017-12-03 18:04:02 +00:00
)
2010-04-13 15:25:33 +00:00
GlobalFree ( proc - > Params [ i ] . allocatedBlock ) ;
2011-12-13 21:16:24 +00:00
SYSTEM_LOG_ADD ( _T ( " \t \t \t Param Out( " ) ) ;
2010-04-13 15:25:33 +00:00
// Step 2: place it
2014-07-01 22:09:38 +00:00
if ( proc - > Params [ i ] . Output = = IOT_NONE )
SYSTEM_LOG_ADD ( _T ( " none " ) ) ;
2011-12-13 21:16:24 +00:00
else if ( proc - > Params [ i ] . Output = = IOT_STACK )
{
SYSTEM_LOG_ADD ( _T ( " stack " ) ) ;
system_pushstring ( realbuf ) ;
}
else if ( proc - > Params [ i ] . Output > 0 )
{
SYSTEM_LOG_ADD ( _T ( " var " ) ) ;
system_setuservariable ( proc - > Params [ i ] . Output - 1 , realbuf ) ;
}
else
SYSTEM_LOG_ADD ( _T ( " ?BUG? " ) ) ;
# ifdef SYSTEM_LOG_DEBUG
{
TCHAR dbgbuf [ 99 ] ;
2017-12-03 18:04:02 +00:00
wsprintf ( dbgbuf , _T ( " ) \t %d: \t Type=%#x Optn=%d Size=%d Data= " ) ,
2011-12-13 21:16:24 +00:00
i , proc - > Params [ i ] . Type , proc - > Params [ i ] . Option , proc - > Params [ i ] . Size ) ;
SYSTEM_LOG_ADD ( dbgbuf ) ;
SYSTEM_LOG_ADD ( realbuf ) ;
SYSTEM_LOG_POST ;
}
# endif
2010-04-13 15:25:33 +00:00
i - - ;
}
while ( i > = 0 ) ;
2014-07-01 22:09:38 +00:00
GlobalFree ( realbuf ) ;
2010-04-13 15:25:33 +00:00
}
HANDLE CreateCallback ( SystemProc * cbproc )
{
2018-06-03 21:00:53 +00:00
# if defined(SYSTEM_AMD64) || defined(SYSTEM_ARM64)
2013-09-06 23:48:59 +00:00
return BUGBUG64 ( HANDLE ) NULL ;
# else
2010-04-13 15:25:33 +00:00
char * mem ;
if ( cbproc - > Proc = = NULL )
{
// Set callback index
cbproc - > CallbackIndex = + + ( CallbackIndex ) ;
cbproc - > Options | = POPT_PERMANENT ;
mem = ( char * ) ( cbproc - > Proc = VirtualAlloc ( NULL , sizeof ( CallbackThunk ) , MEM_COMMIT , PAGE_EXECUTE_READWRITE ) ) ;
2013-09-06 23:48:59 +00:00
( ( CallbackThunk * ) mem ) - > pNext = g_CallbackThunkListHead ;
g_CallbackThunkListHead = ( CallbackThunk * ) mem ;
2010-04-13 15:25:33 +00:00
# ifdef SYSTEM_X86
* ( mem + + ) = ( char ) 0xB8 ; // Mov eax, const
* ( ( int * ) mem ) = ( int ) cbproc ;
mem + = sizeof ( int ) ;
* ( mem + + ) = ( char ) 0xe9 ; // Jmp relative
* ( ( int * ) mem ) = ( int ) RealCallBack ;
* ( ( int * ) mem ) - = ( ( int ) mem ) + 4 ;
# else
# error "Asm thunk not implemeted for this architecture!"
# endif
}
// Return proc address
return cbproc - > Proc ;
2013-09-06 23:48:59 +00:00
# endif
2010-04-13 15:25:33 +00:00
}
2017-12-03 18:04:02 +00:00
# ifdef POPT_SYNTAX2
static UINT GetStructParamAlignment ( const ProcParameter * par )
{
2018-01-06 17:51:06 +00:00
int partype = GetParamType ( * par ) , isarr = ParamIsArray ( * par ) ;
2017-12-03 18:04:02 +00:00
// &l is used to get the final struct size "*(p, &l.r0)"
// but it also allows you to write the struct size to the struct as a int<8|16|32|64> "*(p, &l4)"
2018-01-06 17:51:06 +00:00
// so we can't stop that with: "if ((par->Type & PAT_ALIGNFLAG) && (!isarr || partype != PAT_LONG))"
2017-12-03 18:04:02 +00:00
if ( par - > Type & PAT_ALIGNFLAG )
{
if ( ( partype = = PAT_STRING ) | ( partype = = PAT_WSTRING ) ) return ByteSizeByType [ partype ] ;
if ( partype = = PAT_GUID ) return 16 ;
return ! isarr ? ( par - > Size * 4 ) : GetSpecialParamTypeSize ( * par ) ;
}
return 0 ;
}
# endif
2010-04-13 15:25:33 +00:00
void CallStruct ( SystemProc * proc )
{
2017-10-07 18:56:03 +00:00
BOOL ssflag ; // "&l" struct size syntax
2017-12-03 18:04:02 +00:00
UINT i , paramcount = proc - > ParamCount , structsize = 0 , size = 0 , partype ;
2010-04-13 15:25:33 +00:00
char * st , * ptr ;
2017-12-03 18:04:02 +00:00
# ifdef POPT_SYNTAX2
BOOL tryalign = proc - > Options & POPT_SYNTAX2 ;
# endif
2010-04-13 15:25:33 +00:00
SYSTEM_LOG_ADD ( _T ( " \t \t Struct... " ) ) ;
// Calculate the structure size
2017-12-03 18:04:02 +00:00
for ( i = 1 ; i < = paramcount ; i + + )
2011-12-13 21:16:24 +00:00
{
2017-12-03 18:04:02 +00:00
partype = GetParamType ( proc - > Params [ i ] ) ;
2011-12-13 21:20:56 +00:00
// Emulate g as &g16
// (Changing ByteSizeByType would break compatibility with '*(&g16,i)i.s')
2017-12-03 18:04:02 +00:00
if ( PAT_GUID = = partype & & ParamIsSimple ( proc - > Params [ i ] ) )
proc - > Params [ i ] . Option = PAO_ARRBASE + 16 ;
2011-12-13 21:20:56 +00:00
2017-12-03 18:04:02 +00:00
if ( ! ParamIsArray ( proc - > Params [ i ] ) )
size = proc - > Params [ i ] . Size * 4 ;
2010-04-13 15:25:33 +00:00
else
2017-12-03 18:04:02 +00:00
size = GetParamArrayTypeSize ( proc - > Params [ i ] ) ;
# ifdef POPT_SYNTAX2
if ( tryalign )
structsize = SYS_ALIGNON ( structsize , GetStructParamAlignment ( & proc - > Params [ i ] ) ) ;
# endif
structsize + = size ;
2011-12-13 21:16:24 +00:00
}
2017-12-03 18:04:02 +00:00
2010-04-13 15:25:33 +00:00
// Struct exists?
2017-12-03 18:04:02 +00:00
if ( proc - > Proc = = NULL ) // No. Allocate struct memory
2010-04-13 15:25:33 +00:00
proc - > Proc = ( HANDLE ) GlobalAlloc ( GPTR , structsize ) ;
2017-12-03 18:04:02 +00:00
else if ( structsize = = 0 ) // In case of zero size defined structure use mapped size
structsize = ( int ) GlobalSize ( ( HGLOBAL ) proc - > Proc ) ;
2011-12-13 21:16:24 +00:00
# ifdef SYSTEM_LOG_DEBUG
{
TCHAR dbgbuf [ 99 ] ;
wsprintf ( dbgbuf , _T ( " \t (%u bytes) " ) , structsize ) ;
SYSTEM_LOG_ADD ( dbgbuf ) ;
}
# endif
2010-04-13 15:25:33 +00:00
// Pointer to current data
st = ( char * ) proc - > Proc ;
2017-12-03 18:04:02 +00:00
for ( i = 1 ; i < = paramcount ; i + + )
2010-04-13 15:25:33 +00:00
{
ssflag = FALSE ;
2017-12-03 18:04:02 +00:00
partype = GetParamType ( proc - > Params [ i ] ) ;
2010-04-13 15:25:33 +00:00
// Normal or special block?
2017-12-03 18:04:02 +00:00
if ( ! ParamIsArray ( proc - > Params [ i ] ) )
2010-04-13 15:25:33 +00:00
{
// Normal
2017-12-03 18:04:02 +00:00
size = proc - > Params [ i ] . Size * 4 ;
2010-04-13 15:25:33 +00:00
ptr = ( char * ) & ( proc - > Params [ i ] . Value ) ;
}
else
{
// Special
2017-12-03 18:04:02 +00:00
size = GetParamArrayTypeSize ( proc - > Params [ i ] ) ;
2012-09-08 02:50:09 +00:00
ptr = NULL ;
2017-12-03 18:04:02 +00:00
switch ( partype )
2010-04-13 15:25:33 +00:00
{
2017-12-03 18:04:02 +00:00
case PAT_VOID :
break ;
case PAT_LONG :
2010-04-13 15:25:33 +00:00
// real structure size
proc - > Params [ i ] . Value = structsize ;
2014-07-01 22:09:38 +00:00
# ifndef _WIN64
2010-04-13 15:25:33 +00:00
proc - > Params [ i ] . _value = 0 ;
2014-07-01 22:09:38 +00:00
# endif
ssflag = TRUE ; // System::Call '*(...,&l.r0)'
2017-12-03 18:04:02 +00:00
// [[fallthrough]]
2010-04-13 15:25:33 +00:00
case PAT_INT :
2017-12-03 18:04:02 +00:00
proc - > Params [ i ] . Value = GetSpecialParamInt32Value ( proc - > Params [ i ] , size ) ; // clears unused value bits
2010-04-13 15:25:33 +00:00
// pointer
ptr = ( char * ) & ( proc - > Params [ i ] . Value ) ;
break ;
2017-12-03 18:04:02 +00:00
case PAT_STRING :
case PAT_WSTRING :
case PAT_GUID :
2010-04-13 15:25:33 +00:00
// Jim Park: Pointer for memcopy, so keep as char*
2017-12-03 18:04:02 +00:00
ptr = ( char * ) proc - > Params [ i ] . Value ;
break ;
2010-04-13 15:25:33 +00:00
}
}
// Process them!
if ( ptr ! = NULL )
{
2017-12-03 18:04:02 +00:00
# ifdef POPT_SYNTAX2
if ( tryalign )
st = ( char * ) SYS_ALIGNON ( ( INT_PTR ) st , GetStructParamAlignment ( & proc - > Params [ i ] ) ) ;
# endif
2010-04-13 15:25:33 +00:00
// Input
if ( ( proc - > Params [ i ] . Input ! = IOT_NONE ) | | ( ssflag ) )
copymem ( st , ptr , size ) ;
// Output
if ( proc - > Params [ i ] . Output ! = IOT_NONE )
copymem ( ptr , st , size ) ;
}
// Skip to next data block
st + = size ;
}
SYSTEM_LOG_POST ;
// Proc virtual return - pointer to memory struct
2014-02-08 00:13:52 +00:00
proc - > Params [ 0 ] . Value = ( INT_PTR ) proc - > Proc ;
2010-04-13 15:25:33 +00:00
}
/*
Use of system _DllMainCRTStartup to avoid endless recursion for the debug
report macro _RPT0 .
The system _DllMainCRTStartup initializes the C runtime environment .
In particular the value for _osplatform is initialized . In the function
_get_winmajor called in the execution of the _RPT0 macro an assertion
failure is raised if _osplatform is not set . The assertion is reported by
the same means as used for the _RPT0 macro . This leads to an endless recursion .
*/
2012-10-13 01:47:50 +00:00
BOOL WINAPI DllMain ( HINSTANCE hInst , DWORD fdwReason , LPVOID lpReserved )
2010-04-13 15:25:33 +00:00
{
2013-09-06 23:48:59 +00:00
g_hInstance = hInst ;
2010-04-13 15:25:33 +00:00
2013-09-06 23:48:59 +00:00
if ( DLL_PROCESS_ATTACH = = fdwReason )
{
// change the protection of return command
VirtualProtect ( & retexpr , sizeof ( retexpr ) , PAGE_EXECUTE_READWRITE , ( PDWORD ) & LastStackPlace ) ;
// initialize some variables
LastStackPlace = 0 , LastStackReal = 0 ;
LastError = 0 ;
LastProc = NULL ;
CallbackIndex = 0 , g_CallbackThunkListHead = NULL ;
# ifdef SYSTEM_X86
retexpr [ 0 ] = ( char ) 0xC2 ;
retexpr [ 2 ] = 0x00 ;
2018-06-03 21:00:53 +00:00
# elif defined(SYSTEM_AMD64) || defined(SYSTEM_ARM64)
2013-09-06 23:48:59 +00:00
retexpr [ 0 ] = BUGBUG64 ( 0 ) ;
# else
# error TODO
# endif
}
return TRUE ;
2010-04-13 15:25:33 +00:00
}
/*
Returns size by which the stack should be expanded
*/
unsigned int GetNewStackSize ( void )
{
2014-07-02 20:03:18 +00:00
return NEW_STACK_SIZE ;
2010-04-13 15:25:33 +00:00
}
/*
Returns non - zero value if GENSTACK option is set
*/
unsigned int GetGenStackOption ( SystemProc * proc )
{
2014-07-02 20:03:18 +00:00
return ( proc - > Options & POPT_GENSTACK ) ;
2010-04-13 15:25:33 +00:00
}
/*
Returns non - zero value if CDECL option is set
*/
unsigned int GetCDeclOption ( SystemProc * proc )
{
2014-07-02 20:03:18 +00:00
return ( proc - > Options & POPT_CDECL ) ;
2010-04-13 15:25:33 +00:00
}
/*
Returns non - zero value if Error option is set
*/
unsigned int GetErrorOption ( SystemProc * proc )
{
2014-07-02 20:03:18 +00:00
return ( proc - > Options & POPT_ERROR ) ;
2010-04-13 15:25:33 +00:00
}
/*
Returns offset for element Proc of SystemProc structure
*/
2014-03-03 18:10:53 +00:00
UINT_PTR GetProcOffset ( void )
2010-04-13 15:25:33 +00:00
{
2014-07-02 20:03:18 +00:00
return ( UINT_PTR ) ( & ( ( ( SystemProc * ) 0 ) - > Proc ) ) ;
2010-04-13 15:25:33 +00:00
}
/*
Returns offset for element Clone of SystemProc structure
*/
unsigned int GetCloneOffset ( void )
{
2015-09-17 14:30:07 +00:00
return ( unsigned int ) ( UINT_PTR ) ( & ( ( ( SystemProc * ) 0 ) - > Clone ) ) ;
2010-04-13 15:25:33 +00:00
}
/*
Returns offset for element ProcName of SystemProc structure
*/
unsigned int GetProcNameOffset ( void )
{
2015-09-17 14:30:07 +00:00
return ( unsigned int ) ( UINT_PTR ) ( & ( ( ( SystemProc * ) 0 ) - > ProcName ) ) ;
2010-04-13 15:25:33 +00:00
}
/*
Returns offset for element ArgsSize of SystemProc structure
*/
unsigned int GetArgsSizeOffset ( void )
{
2015-09-17 14:30:07 +00:00
return ( unsigned int ) ( UINT_PTR ) ( & ( ( ( SystemProc * ) 0 ) - > ArgsSize ) ) ;
2010-04-13 15:25:33 +00:00
}
/*
Returns number of parameters
*/
unsigned int GetParamCount ( SystemProc * proc )
{
2014-07-02 20:03:18 +00:00
return proc - > ParamCount ;
2010-04-13 15:25:33 +00:00
}
/*
Returns offset for element Params of SystemProc structure
*/
2014-03-03 18:10:53 +00:00
UINT_PTR GetParamsOffset ( void )
2010-04-13 15:25:33 +00:00
{
2014-07-02 20:03:18 +00:00
return ( UINT_PTR ) ( & ( ( ( SystemProc * ) 0 ) - > Params ) ) ;
2010-04-13 15:25:33 +00:00
}
/*
Returns size of ProcParameter structure
*/
2014-03-03 18:10:53 +00:00
UINT_PTR GetSizeOfProcParam ( void )
2010-04-13 15:25:33 +00:00
{
2014-07-02 20:03:18 +00:00
return ( sizeof ( ProcParameter ) ) ;
2010-04-13 15:25:33 +00:00
}
/*
Returns offset for element Size of ProcParameter structure
*/
unsigned int GetSizeOffsetParam ( void )
{
2015-09-17 14:30:07 +00:00
return ( unsigned int ) ( UINT_PTR ) ( & ( ( ( ProcParameter * ) 0 ) - > Size ) ) ;
2010-04-13 15:25:33 +00:00
}
/*
Returns offset for element Value of ProcParameter structure
*/
2014-03-03 18:10:53 +00:00
UINT_PTR GetValueOffsetParam ( void )
2010-04-13 15:25:33 +00:00
{
2014-07-02 20:03:18 +00:00
return ( UINT_PTR ) ( & ( ( ( ProcParameter * ) 0 ) - > Value ) ) ;
2010-04-13 15:25:33 +00:00
}
2014-03-03 18:10:53 +00:00
# ifndef _WIN64
2010-04-13 15:25:33 +00:00
/*
Returns offset for element _value of ProcParameter structure
*/
unsigned int Get_valueOffsetParam ( void )
{
2014-07-02 20:03:18 +00:00
return ( unsigned int ) ( & ( ( ( ProcParameter * ) 0 ) - > _value ) ) ;
2010-04-13 15:25:33 +00:00
}
2014-03-03 18:10:53 +00:00
# endif
2010-04-13 15:25:33 +00:00
/*
Sets " CLONE " option
*/
void SetCloneOption ( SystemProc * proc )
{
2014-07-02 20:03:18 +00:00
proc - > Options | = POPT_CLONE ;
2010-04-13 15:25:33 +00:00
}
/*
Sets Result of procedure call to be " OK "
*/
void SetProcResultOk ( SystemProc * proc )
{
2014-07-02 20:03:18 +00:00
proc - > ProcResult = PR_OK ;
2010-04-13 15:25:33 +00:00
}
/*
Sets Result of procedure call to be " CALLBACK "
*/
void SetProcResultCallback ( SystemProc * proc )
{
2014-07-02 20:03:18 +00:00
proc - > ProcResult = PR_CALLBACK ;
2010-04-13 15:25:33 +00:00
}