Modificato il meccanismo di chiamata delle applicazioni
git-svn-id: svn://10.65.10.50/trunk@3031 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
28bf34a56a
commit
74035b375e
@ -6,6 +6,17 @@
|
|||||||
#include <utility.h>
|
#include <utility.h>
|
||||||
#include <mask.h>
|
#include <mask.h>
|
||||||
|
|
||||||
|
#if XVT_OS == XVT_OS_WIN
|
||||||
|
#include <windows.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#pragma hdrstop
|
||||||
|
#include "prochook.h"
|
||||||
|
#define MAX_PATH 260 // This really should be in WINDOWS.H, but is
|
||||||
|
// inexplicably hard-coded into the data structures
|
||||||
|
int MungeModuleHeader( HINSTANCE hInstance, BOOL fMunge );
|
||||||
|
#endif
|
||||||
|
|
||||||
#if XVT_OS == XVT_OS_SCOUNIX
|
#if XVT_OS == XVT_OS_SCOUNIX
|
||||||
extern "C" { long nap(long period); }
|
extern "C" { long nap(long period); }
|
||||||
#endif
|
#endif
|
||||||
@ -55,56 +66,156 @@ BOOLEAN CAMPI_SCAVATI = FALSE;
|
|||||||
const word WM_WAKEUP = RegisterWindowMessage("WAKEUP");
|
const word WM_WAKEUP = RegisterWindowMessage("WAKEUP");
|
||||||
|
|
||||||
// By Matt Pietrek
|
// By Matt Pietrek
|
||||||
bool allow_another_instance()
|
//########################################################################
|
||||||
|
// Code that does the real work
|
||||||
|
//########################################################################
|
||||||
|
|
||||||
|
//
|
||||||
|
// Central function that modifies a module table to trick the loader
|
||||||
|
// into letting a second instance of a multiple data segment program run.
|
||||||
|
//
|
||||||
|
int MungeModuleHeader( HINSTANCE hInstance, BOOL fMunge )
|
||||||
{
|
{
|
||||||
// Convert the HINSTANCE to an HMODULE
|
HMODULE hModuleSel;
|
||||||
HINSTANCE hInstance = (HINSTANCE)xvt_vobj_get_attr(NULL_WIN, ATTR_WIN_INSTANCE);
|
LPSTR lpszModName, lpszFileName;
|
||||||
LPCSTR sModuleName = (LPCSTR)MAKELP(0, hInstance);
|
BYTE cbModuleName;
|
||||||
HMODULE hModule = GetModuleHandle(sModuleName);
|
static BOOL fResidentNamesMunged = FALSE;
|
||||||
void FAR* mem_handle = GlobalLock(hModule);
|
|
||||||
HMODULE hModuleSel = (HMODULE)SELECTOROF(mem_handle);
|
|
||||||
if (hModuleSel == 0) // Make sure we succeeded.
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
// Make pointers to the resident names table and the OFSTRUCT
|
|
||||||
LPSTR moduleName = (LPSTR)MAKELP( hModuleSel, *(WORD FAR *)MAKELP(hModuleSel, 0x26));
|
|
||||||
LPSTR fileName = (LPSTR)MAKELP( hModuleSel, *(WORD FAR *)MAKELP(hModuleSel, 0x0A));
|
|
||||||
|
|
||||||
// Get the module name length, and advance to the actual string
|
|
||||||
BYTE cbModuleName = *moduleName++; // First byte is a length byte
|
|
||||||
|
|
||||||
// Convert the first uppercase letter of the modulename to lowercase
|
|
||||||
while ( cbModuleName )
|
|
||||||
{
|
|
||||||
if ( isupper(*moduleName) )
|
|
||||||
{
|
|
||||||
*moduleName = tolower(*moduleName); break;
|
|
||||||
}
|
|
||||||
cbModuleName--; moduleName++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( cbModuleName == 0 ) // Make sure we succeeded
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
// Position to the end of the filename. First byte is a length byte
|
|
||||||
fileName += *fileName - 1;
|
|
||||||
|
|
||||||
// Find the first uppercase letter in the filename. Convert to lowercase
|
|
||||||
while ( TRUE )
|
|
||||||
{
|
|
||||||
// Stop when we come to a directory separator or colon
|
|
||||||
if ( (*fileName=='\\') || (*fileName=='/') || (*fileName==':') )
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if ( isupper(*fileName) )
|
hModuleSel = SELECTOROF( // Convert the HINSTANCE to an HMODULE
|
||||||
|
GlobalLock(GetModuleHandle((LPSTR)MAKELP(0,hInstance))));
|
||||||
|
|
||||||
|
if ( hModuleSel == 0 ) // Make sure we succeeded.
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// First, we'll take care of the resident names table
|
||||||
|
//
|
||||||
|
if ( FALSE == fResidentNamesMunged )
|
||||||
{
|
{
|
||||||
*fileName = tolower(*fileName); break;
|
// Make pointers to the module name in the resident names table
|
||||||
|
lpszModName = (LPSTR)MAKELP(hModuleSel,
|
||||||
|
*(WORD FAR *)MAKELP(hModuleSel, 0x26) );
|
||||||
|
|
||||||
|
// Get the module name length, and advance to the actual string
|
||||||
|
cbModuleName = *lpszModName++; // First byte is a length byte
|
||||||
|
|
||||||
|
// Convert the first uppercase letter of the modulename to lowercase
|
||||||
|
while ( cbModuleName )
|
||||||
|
{
|
||||||
|
if ( isupper(*lpszModName) )
|
||||||
|
{
|
||||||
|
*lpszModName = tolower(*lpszModName); break;
|
||||||
|
}
|
||||||
|
cbModuleName--; lpszModName++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( cbModuleName == 0 ) // Make sure we succeeded
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Remember that we've done this, so that we don't bother doing
|
||||||
|
// it in the future.
|
||||||
|
fResidentNamesMunged = TRUE;
|
||||||
}
|
}
|
||||||
fileName--;
|
|
||||||
}
|
//
|
||||||
|
// Now, we'll turn our attention to the module file name in the OFSTRUCT
|
||||||
|
//
|
||||||
|
lpszFileName = (LPSTR)MAKELP(hModuleSel,
|
||||||
|
*(WORD FAR *)MAKELP(hModuleSel, 0x0A));
|
||||||
|
|
||||||
|
// Position to the end of the filename. First byte is a length byte
|
||||||
|
lpszFileName += *lpszFileName - 1;
|
||||||
|
|
||||||
|
// If we're munging, added 0x30 to the last character value, otherwise
|
||||||
|
// subtract 0x30. 0x30 is chosen completely at random.
|
||||||
|
if ( fMunge )
|
||||||
|
*lpszFileName += 0x30;
|
||||||
|
else
|
||||||
|
*lpszFileName -= 0x30;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//########################################################################
|
||||||
|
// This section watches calls to LoadModule and munges the EXE's module
|
||||||
|
// database as needed.
|
||||||
|
//########################################################################
|
||||||
|
|
||||||
|
HIDDEN NPHOOKCHILD npHookLoadModule = 0;
|
||||||
|
HIDDEN char szOurFileName[MAX_PATH];
|
||||||
|
HIDDEN HINSTANCE HInstance;
|
||||||
|
|
||||||
|
HINSTANCE
|
||||||
|
WINAPI
|
||||||
|
__export MultInst95LoadModule( LPCSTR lpszModuleName,
|
||||||
|
LPVOID lpvParameterBlock )
|
||||||
|
{
|
||||||
|
HINSTANCE retValue;
|
||||||
|
|
||||||
|
// Uppercase the name of the module name that was passed to LoadModule
|
||||||
|
char szNewFileName[MAX_PATH];
|
||||||
|
lstrcpy( szNewFileName, lpszModuleName );
|
||||||
|
strupr( szNewFileName );
|
||||||
|
|
||||||
|
// Compare the incoming filename to our EXE's module name. If they
|
||||||
|
// don't match, we don't need to bother munging the module database
|
||||||
|
BOOL fSecondInstance = strstr(szOurFileName, szNewFileName) ? TRUE:FALSE;
|
||||||
|
|
||||||
|
// Unhook our LoadModule hook so that we can call the real LoadModule
|
||||||
|
ProcUnhook( npHookLoadModule );
|
||||||
|
|
||||||
|
// Munge module database if needed
|
||||||
|
if ( fSecondInstance )
|
||||||
|
MungeModuleHeader( HInstance, TRUE );
|
||||||
|
|
||||||
|
// Call the original LoadModule code
|
||||||
|
retValue = LoadModule( lpszModuleName, lpvParameterBlock );
|
||||||
|
|
||||||
|
// Unmunge module database if needed
|
||||||
|
if ( fSecondInstance )
|
||||||
|
MungeModuleHeader( HInstance, FALSE );
|
||||||
|
|
||||||
|
// Reinstall our LoadModule hook so that we see future loads
|
||||||
|
ProcHook( npHookLoadModule );
|
||||||
|
|
||||||
|
return retValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL deny_another_instance()
|
||||||
|
{
|
||||||
|
if ( !npHookLoadModule )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
SetProcRelease( npHookLoadModule );
|
||||||
|
npHookLoadModule = 0;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL allow_another_instance()
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( npHookLoadModule )
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
// Get the EXE's filename into a global string variable and uppercase it
|
||||||
|
GetModuleFileName( HInstance, szOurFileName, sizeof(szOurFileName) );
|
||||||
|
strupr( szOurFileName );
|
||||||
|
|
||||||
|
// Create a MakeProcInstance thunk so that our callback function
|
||||||
|
// will always be using the correct DS selector
|
||||||
|
FARPROC lpfnMPI
|
||||||
|
= MakeProcInstance( (FARPROC)MultInst95LoadModule, HInstance );
|
||||||
|
|
||||||
|
if ( !lpfnMPI )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
// Call PROCHOOK.DLL to hook calls to LoadModule
|
||||||
|
npHookLoadModule = SetProcAddress( (FARPROC)LoadModule,
|
||||||
|
lpfnMPI, FALSE );
|
||||||
|
|
||||||
|
return (BOOL)npHookLoadModule;
|
||||||
|
}
|
||||||
|
|
||||||
static BOOLEAN event_hook(HWND hwnd,
|
static BOOLEAN event_hook(HWND hwnd,
|
||||||
UINT msg,
|
UINT msg,
|
||||||
UINT wparam,
|
UINT wparam,
|
||||||
@ -122,9 +233,10 @@ static BOOLEAN event_hook(HWND hwnd,
|
|||||||
WINDOW win = cur_win();
|
WINDOW win = cur_win();
|
||||||
if (win != NULL_WIN)
|
if (win != NULL_WIN)
|
||||||
{
|
{
|
||||||
TWindow* w = (TWindow*)xvt_vobj_get_data(win);
|
// TWindow* w = (TWindow*)xvt_vobj_get_data(win);
|
||||||
const KEY key = toupper(wparam)+K_CTRL;
|
const KEY key = toupper(wparam)+K_CTRL;
|
||||||
w->on_key(key);
|
// w->on_key(key);
|
||||||
|
dispatch_e_char(win, key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -502,11 +614,10 @@ void customize_controls(
|
|||||||
#if XVT_OS == XVT_OS_WIN
|
#if XVT_OS == XVT_OS_WIN
|
||||||
xvt_vobj_set_attr(NULL_WIN,ATTR_EVENT_HOOK, (long)event_hook);
|
xvt_vobj_set_attr(NULL_WIN,ATTR_EVENT_HOOK, (long)event_hook);
|
||||||
xvt_vobj_set_attr(NULL_WIN,ATTR_ERRMSG_HANDLER, (long)error_hook);
|
xvt_vobj_set_attr(NULL_WIN,ATTR_ERRMSG_HANDLER, (long)error_hook);
|
||||||
allow_another_instance();
|
HInstance = (HINSTANCE)xvt_vobj_get_attr(NULL_WIN, ATTR_WIN_INSTANCE);
|
||||||
|
|
||||||
HINSTANCE hInstance = (HINSTANCE)xvt_vobj_get_attr(NULL_WIN, ATTR_WIN_INSTANCE);
|
Ctl3dRegister(HInstance);
|
||||||
Ctl3dRegister(hInstance);
|
Ctl3dAutoSubclass(HInstance);
|
||||||
Ctl3dAutoSubclass(hInstance);
|
|
||||||
#endif
|
#endif
|
||||||
customize_colors();
|
customize_colors();
|
||||||
init_controls();
|
init_controls();
|
||||||
@ -514,8 +625,9 @@ void customize_controls(
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if XVT_OS == XVT_OS_WIN
|
#if XVT_OS == XVT_OS_WIN
|
||||||
HINSTANCE _hInstance = (HINSTANCE)xvt_vobj_get_attr(NULL_WIN, ATTR_WIN_INSTANCE);
|
// HINSTANCE _hInstance = (HINSTANCE)xvt_vobj_get_attr(NULL_WIN, ATTR_WIN_INSTANCE);
|
||||||
Ctl3dUnregister(_hInstance);
|
Ctl3dUnregister(HInstance);
|
||||||
|
deny_another_instance();
|
||||||
#endif
|
#endif
|
||||||
free_controls();
|
free_controls();
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,9 @@ WINDOW xvt_create_window
|
|||||||
long app_data
|
long app_data
|
||||||
);
|
);
|
||||||
|
|
||||||
|
int allow_another_instance();
|
||||||
|
int deny_another_instance();
|
||||||
|
|
||||||
WINDOW xvt_create_statbar();
|
WINDOW xvt_create_statbar();
|
||||||
void xvt_statbar_set(const char* text, bool def = FALSE);
|
void xvt_statbar_set(const char* text, bool def = FALSE);
|
||||||
void xvt_statbar_refresh();
|
void xvt_statbar_refresh();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user