int main( int argc, char *argv[] ) { int in, out, i, rcparm = 0, pcnt; int Rflag = FALSE, nflag = FALSE; int uflag = FALSE; int dllflag = FALSE; char *wext = NULL; long tsize = 0; char drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME]; char ext[_MAX_EXT]; char rex[_MAX_PATH]; char exe[_MAX_PATH]; char dll[_MAX_PATH]; char res[_MAX_PATH]; char winext[_MAX_PATH]; char rc[256]; long totalsize; const char **arglist; char *path = NULL; int currarg,len; simple_header re; long exelen; char *desc = NULL; /* * get parms */ if( argc < 2 ) { doUsage( NULL ); } currarg=1; while( currarg < argc ) { #ifdef __UNIX__ if( argv[ currarg ][0] == '-' ) { #else if( argv[ currarg ][0] == '/' || argv[ currarg ][0] == '-' ) { #endif len = strlen( argv[ currarg ] ); for( i=1; i<len; i++ ) { switch( argv[ currarg ][i] ) { case '?': doUsage( NULL ); case 'D': currarg++; desc = argv[ currarg ]; break; case 's': currarg++; wext = argv[ currarg ]; break; case 'q': quietFlag = TRUE; break; case 'u': uflag = TRUE; break; case 'n': nflag = TRUE; break; case 'd': dllflag = TRUE; break; case 'R': case 'r': Rflag=TRUE; rcparm = currarg+1; if( rcparm == argc ) { doUsage("must specify resource compiler command line" ); } break; } } if( Rflag ) { break; } } else { if( path != NULL ) { doUsage( "Only one executable may be specified" ); } path = argv[ currarg ]; } currarg++; } if( path == NULL ) { doUsage( "No executable to bind" ); } doBanner(); /* * get files to use */ _splitpath( path, drive, dir, fname, ext ); _makepath( rex, drive, dir, fname, ".rex" ); if( dllflag ) { _makepath( dll, drive, dir, fname, ".dll" ); } _makepath( exe, drive, dir, fname, ".exe" ); _makepath( res, drive, dir, fname, "" ); /* * do the unbind */ if( uflag ) { if( ext[0] == 0 ) { path = exe; } in = open( path, O_RDONLY | O_BINARY ); if( in < 0 ) { doError( "Could not open %s", path ); } out = open( rex, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, PMODE_RWX ); if( out < 0 ) { doError( "Could not open %s", rex ); } lseek( in, MAGIC_OFFSET, SEEK_SET ); read( in, &exelen, sizeof( unsigned_32 ) ); lseek( in, exelen, SEEK_SET ); read( in, &re, sizeof( re ) ); if( re.signature != ('M' & ('Q' << 8)) ) { doError( "Not a bound Open Watcom 32-bit Windows application" ); } lseek( in, exelen, SEEK_SET ); CopyFile( in, out, path, rex ); close( in ); close( out ); myPrintf( ".rex file %s created", rex ); exit( 0 ); } if( wext == NULL ) { if( dllflag ) { FindExtender( "w386dll.ext", winext ); } else { FindExtender( "win386.ext", winext ); } } else { strcpy( winext, wext ); } if( dllflag ) { myPrintf("Loading 32-bit Windows DLL Supervisor \"%s\"\n",winext ); } else { myPrintf("Loading 32-bit Windows Supervisor \"%s\"\n",winext ); } /* * open files */ in = open( winext, O_RDONLY | O_BINARY ); if( in < 0 ) { doError( "Could not open %s", winext ); } out = open( exe, O_CREAT | O_TRUNC|O_WRONLY | O_BINARY, PMODE_RWX ); if( out < 0 ) { doError( "Could not open %s", exe ); } /* * copy extender over */ CopyFile( in, out, winext, exe ); close( in ); close( out ); /* * run the resource compiler */ if( !nflag ) { myPrintf( "Invoking the resource compiler...\n" ); if( Rflag ) { strcpy( rc, RC_STR ); arglist = myAlloc( sizeof(char *) *(argc-rcparm +3) ); pcnt = 1; for( i=rcparm;i<argc;i++ ) { arglist[pcnt++] = argv[i]; strcat( rc," " ); strcat( rc, argv[i] ); } } else { sprintf( rc, RC_STR " %s", res ); arglist = myAlloc( sizeof(char *) * 3 ); arglist[1] = res; pcnt = 2; } arglist[0] = RC_STR; arglist[pcnt] = NULL; myPrintf( "%s\n",rc ); i = spawnvp( P_WAIT, RC_STR, arglist ); if( i == -1 ) { remove( exe ); switch( errno ) { case E2BIG: doError( "Argument list too big. Resource compiler step failed." ); break; case ENOENT: doError( "Could not find " RC_STR ".exe." ); break; case ENOMEM: doError( "Not enough memory. Resource compiler step failed." ); break; } doError( "Unknown error %d, resource compiler step failed.", errno ); } if( i != 0 ) { remove( exe ); errPrintf( "Resource compiler failed, return code = %d\n", i ); exit( i ); } } /* * copy the rex file onto the end */ in = open( rex, O_RDONLY | O_BINARY ); if( in < 0 ) { doError( "Could not open %s", rex ); } out = open( exe, O_RDWR | O_BINARY ); if( out < 0 ) { doError( "Could not open %s", exe ); } lseek( out, 0, SEEK_END ); tsize = tell( out ); totalsize = CopyFile( in, out, rex, exe ); close( in ); /* * noodle the file: change name, and then * write the file size into the old exe header (for * use by the loader) */ lseek( out, MAGIC_OFFSET, SEEK_SET ); write( out, &tsize, sizeof( tsize ) ); len = strlen( fname ); memset( &fname[len],' ',8-len ); updateNHStuff( out, fname, desc ); close( out ); if( dllflag ) { remove( dll ); rename( exe,dll ); myPrintf("Created \"%s\" (%ld + %ld = %ld bytes)\n", dll, tsize,totalsize, tsize+totalsize ); } else { myPrintf("Created \"%s\" (%ld + %ld = %ld bytes)\n", exe, tsize,totalsize, tsize+totalsize ); } return( 0 ); } /* main */
const char *RemoteLink( const char *parms, bool server ) { #ifdef SERVER unsigned long link; #if defined(ACAD) { XVersion = 2; if( GetCS() & 3 ) { Meg1 = 0x37; } else { Meg1 = 0x60; } } #elif defined(PHARLAP) { CONFIG_INF config; static unsigned char buff[256]; _dx_config_inf(&config, buff ); XVersion = config.c_major; if( XVersion >= 3 ) { Meg1 = config.c_dos_sel; } else { Meg1 = 0x60; } } #elif defined(CAUSEWAY) Meg1 = GetZeroSel(); #endif parms = parms; link = GetDosLong( LINK_VECTOR * 4 ); if( link >= (1024UL * 1024UL) || GetDosLong( link ) != LINK_SIGNATURE ) { return( TRP_ERR_not_from_command ); } RMBuffPtr = RMLinToPM( GetDosLong( link + 4 ), 0 ); RMProcAddr = GetDosLong( link + 8 ); PutDosLong( LINK_VECTOR * 4, GetDosLong( link + 12 ) ); #else static char fullpath[256]; /* static because ss != ds */ static char buff[256]; static char *endname; char *name; char *buffp; char *endparm; void __far *link[4]; void __far * __far * link_ptr; unsigned len; #if defined(PHARLAP) const char *exe_name; #endif _DBG_EnterFunc( "RemoteLink()" ); BackFromFork = 0; link_ptr = (void __far *)(LINK_VECTOR * 4); link[ 3 ] = *link_ptr; link[ 2 ] = MK_FP( GetCS(), (unsigned )BackFromProtMode ); link[ 1 ] = (void __far *)MK_LINEAR( &Buff ); link[ 0 ] = (void __far *)LINK_SIGNATURE; *link_ptr = (void __far *)MK_LINEAR( &link ); // parms has following format // "trap parameters string"+"\0"+"command line string"+"\0" _DBG_Write( "Parms: " ); _DBG_NoTabWriteln( parms ); while( *parms == ' ' ) ++parms; if( *parms == '`' ) { ++parms; buffp = buff; while( *parms != '\0' ) { if( *parms == '`' ) { ++parms; break; } *buffp++ = *parms++; } *buffp = '\0'; } while( *parms == ' ' ) ++parms; if( setjmp( RealModeState ) == 0 ) { name = FindExtender( fullpath, &endname ); if( name == NULL ) { _DBG_ExitFunc( "RemoteLink(), unable to find extender" ); return( TRP_ERR_no_extender ); } _DBG_Write( "Extender name: " ); _DBG_NoTabWriteln( name ); while( *endname++ != '\0' ) {} // skip after extender name + '\0' #if defined(ACAD) buffp = buff; *buffp = '\0'; #else { static char *endhelp; const char *help_name; #if defined(PHARLAP) exe_name = parms; while( *exe_name++ != '\0' ) {} // skip to command line help_name = GetHelpName( exe_name ); #else help_name = HELPNAME; #endif buffp = SearchPath( DOSEnvFind( "PATH" ), help_name, buff, &endhelp ); if( *buffp == '\0' ) { _DBG_ExitFunc( "RemoteLink(), unable to find extender help file" ); return( TRP_ERR_no_extender ); } } #endif _DBG_Write( "Extender help name: " ); _DBG_NoTabWriteln( buffp ); endparm = CopyStr( parms, endname + 1 ); // reserve length byte endparm = CopyStr( buffp, CopyStr( " ", endparm ) ); #if defined(PHARLAP) endparm = CopyStr( " ", endparm ); endparm = CopyStr( exe_name, endparm ); // add extra executable name #endif len = endparm - ( endname + 1 ); if( len > 126 ) len = 126; *endname = len; // setup length byte endparm = endname + len + 1; endparm[0] = '\r'; endparm[1] = '\0'; _DBG_Write( "Extender Cmd line: " ); _DBG_NoTabWriteln( endname + 1 ); _DBG_Writeln( "calling _fork() to start extender/debugee" ); if( _fork( name, endname ) != 0 ) { _DBG_ExitFunc( "RemoteLink(), unable to start extender" ); return( TRP_ERR_cant_start_extender ); } } else if( BackFromFork || !BeenToProtMode ) { _DBG_ExitFunc( "RemoteLink(), extender could not start extender help file" ); return( TRP_ERR_cant_start_extender ); } #endif server = server; _DBG_ExitFunc( "RemoteLink()" ); return( NULL ); }