unsigned LocalWrite( sys_handle filehndl, void *ptr, unsigned len ) { tiny_ret_t ret; ret = TinyWrite( filehndl, ptr, len ); if( TINY_ERROR( ret ) ) { StashErrCode( TINY_INFO( ret ), OP_LOCAL ); return( ERR_RETURN ); } return( TINY_INFO( ret ) ); }
trap_retval ReqFile_close( void ) { tiny_ret_t rc; file_close_req *acc; file_close_ret *ret; acc = GetInPtr( 0 ); ret = GetOutPtr( 0 ); rc = TinyClose( acc->handle ); ret->err = TINY_ERROR( rc ) ? TINY_INFO( rc ) : 0; return( sizeof( *ret ) ); }
unsigned long QFileSize( f_handle file ) /*********************************************/ { unsigned long curpos; unsigned long size; curpos = QPos( file ); if( TINY_ERROR( TinyLSeek( file, 0L, TIO_SEEK_END, (void __near *)&size ) ) ) size = 0; TinySeek( file, curpos, TIO_SEEK_START ); return( size ); }
unsigned long LocalSeek( sys_handle hdl, unsigned long npos, seek_method method ) { tiny_ret_t ret; unsigned long pos; ret = TinyLSeek( hdl, npos, method, (u32_stk_ptr)&pos ); if( TINY_ERROR( ret ) ) { StashErrCode( TINY_INFO( ret ), OP_LOCAL ); return( -1UL ); } return( pos ); }
trap_retval ReqFile_write_console( void ) { tiny_ret_t rc; file_write_console_ret *ret; ret = GetOutPtr( 0 ); rc = TinyWrite( TINY_ERR, GetInPtr( sizeof( file_write_console_req ) ), ( GetTotalSize() - sizeof( file_write_console_req ) ) ); ret->len = TINY_INFO( rc ); ret->err = TINY_ERROR( rc ) ? TINY_INFO( rc ) : 0; return( sizeof( *ret ) ); }
unsigned long LocalSeek( sys_handle hdl, unsigned long len, unsigned method ) { tiny_ret_t ret; unsigned long pos; ret = TinyLSeek( hdl, len, method, &pos ); if( TINY_ERROR( ret ) ) { StashErrCode( TINY_INFO( ret ), OP_LOCAL ); return( -1UL ); } return( pos ); }
int __qread( int handle, void *buffer, unsigned len ) { #if defined( __NT__ ) DWORD amount_read; #elif defined(__OS2__) OS_UINT amount_read; APIRET rc; #else unsigned amount_read; tiny_ret_t rc; #endif __handle_check( handle, -1 ); #ifdef DEFAULT_WINDOWING if( _WindowsStdin != NULL ) { LPWDATA res; res = _WindowsIsWindowedHandle( handle ); if( res ) { int rt; rt = _WindowsStdin( res, buffer, len ); return( rt ); } } #endif #if defined(__NT__) if( !ReadFile( __getOSHandle( handle ), buffer, len, &amount_read, NULL ) ) { DWORD err; err = GetLastError(); __set_errno_dos( err ); if( err != ERROR_BROKEN_PIPE || amount_read != 0 ) { return( -1 ); } } #elif defined(__OS2__) rc = DosRead( handle, buffer, len, &amount_read ); if( rc ) { return( __set_errno_dos( rc ) ); } #else #if defined( __WINDOWS_386__ ) rc = __TinyRead( handle, buffer, len ); #else rc = TinyRead( handle, buffer, len ); #endif if( TINY_ERROR( rc ) ) { return( __set_errno_dos( TINY_INFO( rc ) ) ); } amount_read = TINY_LINFO( rc ); #endif return( amount_read ); }
void QDelete( char *name ) /*******************************/ { tiny_ret_t h; if( name == NULL ) return; h = TinyDelete( name ); if( TINY_ERROR( h ) ) { if( TINY_INFO( h ) != 2 ) { /* file not found is OK */ LnkMsg( ERR+MSG_IO_PROBLEM, "12", name, QErrMsg( TINY_INFO( h ) ) ); } } }
trap_retval ReqFile_write( void ) { tiny_ret_t rc; file_write_req *acc; file_write_ret *ret; acc = GetInPtr( 0 ); ret = GetOutPtr( 0 ); rc = TinyWrite( TRPH2LH( acc ), GetInPtr( sizeof( *acc ) ), ( GetTotalSize() - sizeof( *acc ) ) ); ret->len = TINY_INFO( rc ); ret->err = TINY_ERROR( rc ) ? TINY_INFO( rc ) : 0; return( sizeof( *ret ) ); }
static unsigned dosalloc( unsigned min ) { tiny_ret_t rc; unsigned block; rc = TinyAllocBlock( min ); if( TINY_ERROR( rc ) ) { return( 0 ); } block = TINY_INFO( rc ); dosexpand( block ); return( block ); }
trap_retval ReqFile_seek( void ) { tiny_ret_t rc; file_seek_req *acc; file_seek_ret *ret; unsigned long pos; acc = GetInPtr( 0 ); ret = GetOutPtr( 0 ); rc = TinyLSeek( acc->handle, acc->pos, acc->mode, (u32_stk_ptr)&pos ); ret->pos = pos; ret->err = TINY_ERROR( rc ) ? TINY_INFO( rc ) : 0; return( sizeof( *ret ) ); }
long QLSeek( f_handle file, long position, int start, char *name ) /***********************************************************************/ { tiny_ret_t rc; unsigned long pos; CheckBreak(); rc = TinyLSeek( file, position, start, (void __near *)&pos ); if( TINY_ERROR( rc ) ) { if( name != NULL ) LnkMsg( ERR+MSG_IO_PROBLEM, "12", name, QErrMsg( TINY_INFO( rc ) ) ); return( -1L ); /* for xmem checking */ } return( pos ); }
static const char *GetHelpName( const char *exe_name ) { /* if executable is: PE format, subsystem PE_SS_PL_DOSSTYLE (0x42) then PEDHELP.EXP or: PE format, other subsystems then PENHELP.EXP otherwise: PLSHELP.EXP */ tiny_ret_t rc; tiny_handle_t handle; unsigned_32 off; union { dos_exe_header dos; pe_header pe; } head; handle = -1; rc = TinyOpen( exe_name, 0 ); if( TINY_ERROR( rc ) ) goto exp; handle = TINY_INFO( rc ); TinyRead( handle, &head.dos, sizeof( head.dos ) ); if( head.dos.signature != DOS_SIGNATURE ) goto exp; TinySeek( handle, OS2_NE_OFFSET, SEEK_SET ); TinyRead( handle, &off, sizeof( off ) ); TinySeek( handle, off, SEEK_SET ); TinyRead( handle, &head.pe, sizeof( head.pe ) ); TinyClose( handle ); handle = -1; switch( head.pe.signature ) { case PE_SIGNATURE: case PL_SIGNATURE: if( head.pe.subsystem == PE_SS_PL_DOSSTYLE ) { _DBG_Writeln( "Want PEDHELP" ); return( HELPNAME_DS ); } _DBG_Writeln( "Want PENHELP" ); return( HELPNAME_NS ); } exp: if( handle != -1 ) TinyClose( handle ); _DBG_Writeln( "Want PLSHELP" ); return( HELPNAME ); }
static int os_write( int handle, const void *buffer, unsigned len, unsigned *amt ) /********************************************************************************/ { #ifdef DEFAULT_WINDOWING LPWDATA res; #endif #if defined(__NT__) HANDLE h; int rc; #else tiny_ret_t rc; #endif rc = 0; #ifdef DEFAULT_WINDOWING if( _WindowsStdout != 0 && (res = _WindowsIsWindowedHandle( handle )) != 0 ) { *amt = _WindowsStdout( res, buffer, len ); } else #endif { #if defined(__NT__) h = __getOSHandle( handle ); if( !WriteFile( h, (LPCVOID)buffer, (DWORD)len, (LPDWORD)amt, NULL ) ) { rc = __set_errno_nt(); } #elif defined(__OS2_286__) rc = DosWrite( handle, (PVOID)buffer, (USHORT)len, (PUSHORT)amt ); #elif defined(__OS2__) rc = DosWrite( handle, (PVOID)buffer, (ULONG)len, (PULONG)amt ); #else rc = TinyWrite( handle, buffer, len ); *amt = TINY_LINFO( rc ); if( TINY_OK( rc ) ) { rc = 0; } #endif } #if !defined(__NT__) if( TINY_ERROR( rc ) ) { rc = __set_errno_dos( TINY_INFO( rc ) ); } #endif if( *amt != len ) { rc = ENOSPC; __set_errno( rc ); } return( rc ); }
_WCRTLINK int dup2( int handle1, int handle2 ) { tiny_ret_t rc; __handle_check( handle1, -1 ); if( handle1 == handle2 ) { return( handle2 ); } rc = TinyDup2( handle1, handle2 ); if( TINY_ERROR(rc) ) { return( __set_errno_dos( TINY_INFO(rc) ) ); } __SetIOMode( handle2, __GetIOMode( handle1 ) ); return( 0 ); /* indicate success */ }
dig_fhandle DIGPathOpen( const char *name, unsigned name_len, const char *exts, char *result, unsigned max_result ) { bool has_ext; bool has_path; const char *src; char *dst; char trpfile[256]; tiny_ret_t rc; char c; result = result; max_result = max_result; has_ext = FALSE; has_path = FALSE; src = name; dst = trpfile; while( name_len-- > 0 ) { c = *src++; *dst++ = c; switch( c ) { case '.': has_ext = TRUE; break; case '/': case '\\': has_ext = FALSE; /* fall through */ case ':': has_path = TRUE; break; } } if( !has_ext ) { *dst++ = '.'; name_len = strlen( exts ); memcpy( dst, exts, name_len ); dst += name_len; } *dst = '\0'; if( has_path ) { rc = TinyOpen( trpfile, TIO_READ ); } else { _searchenv( trpfile, "PATH", RWBuff ); rc = TinyOpen( RWBuff, TIO_READ ); } return( TINY_ERROR( rc ) ? DIG_NIL_HANDLE : TINY_INFO( rc ) ); }
static int os_write( int handle, const void *buffer, unsigned len, unsigned *amt ) /********************************************************************************/ { int rc; #ifdef DEFAULT_WINDOWING LPWDATA res; #endif #if defined(__NT__) HANDLE h; #elif defined(__OS2__) APIRET rc1; #else tiny_ret_t rc1; #endif rc = 0; #ifdef DEFAULT_WINDOWING if( _WindowsStdout != NULL && (res = _WindowsIsWindowedHandle( handle )) != NULL ) { *amt = _WindowsStdout( res, buffer, len ); } else #endif { #if defined(__NT__) h = __getOSHandle( handle ); if( !WriteFile( h, (LPCVOID)buffer, (DWORD)len, (LPDWORD)amt, NULL ) ) { return( __set_errno_nt() ); } #elif defined(__OS2__) rc1 = DosWrite( handle, (PVOID)buffer, (OS_UINT)len, (OS_PUINT)amt ); if( rc1 ) { return( __set_errno_dos( rc1 ) ); } #else rc1 = TinyWrite( handle, buffer, len ); if( TINY_ERROR( rc1 ) ) { return( __set_errno_dos( TINY_INFO( rc1 ) ) ); } *amt = TINY_LINFO( rc1 ); #endif } if( *amt != len ) { rc = ENOSPC; _RWD_errno = rc; } return( rc ); }
unsigned QRead( f_handle file, void *buffer, unsigned len, char *name ) /****************************************************************************/ /* read into far memory */ { tiny_ret_t h; CheckBreak(); h = TinyRead( file, buffer, len ); if( TINY_ERROR( h ) ) { if( name != NULL ) { LnkMsg( ERR+MSG_IO_PROBLEM, "12", name, QErrMsg( TINY_INFO( h ) ) ); } else { return( -1 ); } } return( TINY_INFO(h) ); }
void CheckPointRestore( void ) { dos_mem_block *chk; tiny_ret_t rc; tiny_handle_t hdl; rc = TinyOpen( ChkFile, TIO_READ ); if( TINY_ERROR( rc ) ) return; hdl = TINY_INFO( rc ); TinyRead( hdl, &chk, sizeof( chk ) ); TinyRead( hdl, chk, sizeof( *chk ) ); TinyRead( hdl, &chk, sizeof( chk ) ); while( TinyRead( hdl, chk, 0x8000 ) == 0x8000 ) { chk = MK_FP( FP_SEG( chk ) + 0x800, 0 ); } TinyClose( hdl ); Cleanup(); }
trap_retval ReqFile_read( void ) { tiny_ret_t rc; file_read_req *acc; file_read_ret *ret; char *buff; unsigned len; acc = GetInPtr( 0 ); ret = GetOutPtr( 0 ); buff = GetOutPtr( sizeof( *ret ) ); rc = TinyRead( acc->handle, buff, acc->len ); if( TINY_ERROR( rc ) ) { ret->err = TINY_INFO( rc ); len = 0; } else { ret->err = 0; len = TINY_INFO( rc ); } return( sizeof( *ret ) + len ); }
_WCRTLINK unsigned _dos_findfirst( const char *path, unsigned attr, struct find_t *buf ) { /******************************************************/ #if defined(__OS2_286__) if( _RWD_osmode == OS2_MODE ) { #endif APIRET rc; FF_BUFFER dir_buff; HDIR handle = BAD_HANDLE; OS_UINT searchcount; searchcount = 1; /* only one at a time */ rc = DosFindFirst( (PSZ)path, (PHFILE)&handle, attr, (PVOID)&dir_buff, sizeof( dir_buff ), &searchcount, FF_LEVEL ); if( rc != 0 && rc != ERROR_EAS_DIDNT_FIT ) { FIND_HANDLE_OF( buf ) = BAD_HANDLE; return( __set_errno_dos_reterr( rc ) ); } FIND_HANDLE_OF( buf ) = handle; copydir( buf, &dir_buff ); /* copy in other fields */ #if defined(__OS2_286__) } else { /* real mode */ tiny_ret_t rc; void __far * old_dta; old_dta = TinyFarChangeDTA( buf ); /* set our DTA */ rc = TinyFindFirst( path, attr ); TinyFarSetDTA( old_dta ); /* restore DTA */ if( TINY_ERROR( rc ) ) { return( __set_errno_dos_reterr( TINY_INFO( rc ) ) ); } } #endif return( 0 ); }
trap_retval ReqFile_open( void ) { tiny_ret_t rc; int mode; char *filename; file_open_req *acc; file_open_ret *ret; static int MapAcc[] = { TIO_READ, TIO_WRITE, TIO_READ_WRITE }; acc = GetInPtr( 0 ); filename = GetInPtr( sizeof( *acc ) ); ret = GetOutPtr( 0 ); if( acc->mode & TF_CREATE ) { rc = TinyCreate( filename, TIO_NORMAL ); } else { mode = MapAcc[ acc->mode - 1 ]; if( IsDOS3 ) mode |= 0x80; /* set no inheritance */ rc = TinyOpen( filename, mode ); } ret->handle = TINY_INFO( rc ); ret->err = TINY_ERROR( rc ) ? TINY_INFO( rc ) : 0; return( sizeof( *ret ) ); }
static unsigned TestWrite( f_handle file, void *buffer, unsigned len, char *name ) /*****************************************************************************/ { tiny_ret_t h; char rc_buff[RESOURCE_MAX_SIZE]; CheckBreak(); if( len == 0 ) return( 0 ); h = TinyWrite( file, buffer, len ); if( name != NULL ) { if( TINY_ERROR( h ) ) { LnkMsg( ERR+MSG_IO_PROBLEM, "12", name, QErrMsg( TINY_INFO( h ) ) ); return( ~0 ); } else if( TINY_INFO( h ) != len ) { if( name != NULL ) { Msg_Get( MSG_IOERRLIST_7, rc_buff ); LnkMsg( (FTL+MSG_IO_PROBLEM) & ~OUT_MAP, "12", name, rc_buff ); } } } return( TINY_INFO(h) ); }
int __FreeSeg( __segment seg ) { #if defined(__QNX__) if( qnx_segment_free( seg ) == -1 ) { return( -1 ); } #elif defined(__WINDOWS_286__) if( __DoFreeSeg( seg ) ) { return( -1 ); } #else tiny_ret_t rc; #if defined(__OS2__) rc = __DoFreeSeg( seg ); #else rc = TinyFreeBlock( seg ); #endif if( TINY_ERROR( rc ) ) { return( __set_errno_dos( TINY_INFO( rc ) ) ); } #endif return( 0 ); }
sys_handle LocalOpen( char *name, open_access access ) { tiny_ret_t ret; unsigned mode; if( access & OP_CREATE ) { ret = TinyCreate( name, TIO_NORMAL ); } else { if( (access & OP_WRITE) == 0 ) { mode = TIO_READ; } else if( access & OP_READ ) { mode = TIO_READ_WRITE; } else { mode = TIO_WRITE; } if( _osmajor >= 3 ) mode |= 0x80; /* set no inheritance */ ret = TinyOpen( name, mode ); } if( TINY_ERROR( ret ) ) { StashErrCode( TINY_INFO( ret ), OP_LOCAL ); return( NIL_SYS_HANDLE ); } return( TINY_INFO( ret ) ); }
_WCRTLINK int write( int handle, const void *buffer, unsigned len ) #endif /**********************************************************************/ { unsigned iomode_flags; char *buf; unsigned buf_size; unsigned len_written, i, j; #if defined(__NT__) HANDLE h; LONG cur_ptr_low; LONG cur_ptr_high; DWORD rc1; #else tiny_ret_t rc1; #endif int rc2; __handle_check( handle, -1 ); iomode_flags = __GetIOMode( handle ); if( iomode_flags == 0 ) { #if defined(__WINDOWS__) || defined(__WINDOWS_386__) // How can we write to the handle if we never opened it? JBS return( _lwrite( handle, buffer, len ) ); #else __set_errno( EBADF ); return( -1 ); #endif } if( !(iomode_flags & _WRITE) ) { __set_errno( EACCES ); /* changed from EBADF to EACCES 23-feb-89 */ return( -1 ); } #if defined(__NT__) h = __getOSHandle( handle ); #endif // put a semaphore around our writes _AccessFileH( handle ); if( (iomode_flags & _APPEND) && !(iomode_flags & _ISTTY) ) { #if defined(__NT__) if( GetFileType( h ) == FILE_TYPE_DISK ) { cur_ptr_low = 0; cur_ptr_high = 0; rc1 = SetFilePointer( h, cur_ptr_low, &cur_ptr_high, FILE_END ); if( rc1 == INVALID_SET_FILE_POINTER ) { // this might be OK so if( GetLastError() != NO_ERROR ) { _ReleaseFileH( handle ); return( __set_errno_nt() ); } } } #elif defined(__OS2__) { unsigned long dummy; rc1 = DosChgFilePtr( handle, 0L, SEEK_END, &dummy ); // should we explicitly ignore ERROR_SEEK_ON_DEVICE here? } #else rc1 = TinySeek( handle, 0L, SEEK_END ); #endif #if !defined(__NT__) if( TINY_ERROR( rc1 ) ) { _ReleaseFileH( handle ); return( __set_errno_dos( TINY_INFO( rc1 ) ) ); } #endif } len_written = 0; rc2 = 0; // Pad the file with zeros if necessary if( iomode_flags & _FILEEXT ) { // turn off file extended flag __SetIOMode_nogrow( handle, iomode_flags&(~_FILEEXT) ); // It is not required to pad a file with zeroes on an NTFS file system; // unfortunately it is required on FAT (and probably FAT32). (JBS) rc2 = zero_pad( handle ); } if( rc2 == 0 ) { if( iomode_flags & _BINARY ) { /* if binary mode */ rc2 = os_write( handle, buffer, len, &len_written ); /* end of binary mode part */ } else { /* text mode */ i = stackavail(); if( i < 0x00b0 ) { __STKOVERFLOW(); /* not enough stack space */ } buf_size = 512; if( i < (512 + 48) ) { buf_size = 128; } #if defined(__AXP__) || defined(__PPC__) buf = alloca( buf_size ); #else buf = __alloca( buf_size ); #endif j = 0; for( i = 0; i < len; ) { if( ((const char*)buffer)[i] == '\n' ) { buf[j] = '\r'; ++j; if( j == buf_size ) { rc2 = os_write( handle, buf, buf_size, &j ); if( rc2 == -1 ) break; len_written += j; if( rc2 == ENOSPC ) break; len_written = i; j = 0; } } buf[j] = ((const char*)buffer)[i]; ++i; ++j; if( j == buf_size ) { rc2 = os_write( handle, buf, buf_size, &j ); if( rc2 == -1 ) break; len_written += j; if( rc2 == ENOSPC ) break; len_written = i; j = 0; } } if( j ) { rc2 = os_write( handle, buf, j, &i ); if( rc2 == ENOSPC ) { len_written += i; } else { len_written = len; } } /* end of text mode part */ } } _ReleaseFileH( handle ); if( rc2 == -1 ) { return( rc2 ); } else { return( len_written ); } }
static void ioSuppTempOpen( // OPEN TEMPORARY FILE void ) { int mode; auto char fname[ _MAX_PATH ]; mode = O_RDWR | O_CREAT | O_EXCL; #ifdef __UNIX__ #ifndef O_TEMP #define O_TEMP 0 /* Not a standard flag */ #endif // Unix files are always binary mode |= O_TEMP; #else mode |= O_BINARY; #endif for(;;) { tempFname( fname ); #if defined(__DOS__) { tiny_ret_t rc; rc = TinyCreateNew( fname, 0 ); if( TINY_ERROR( rc ) ) { temphandle = -1; } else { temphandle = TINY_INFO( rc ); __SetIOMode( temphandle, _READ | _WRITE | _BINARY ); } } #else temphandle = open( fname, mode, S_IRUSR | S_IWUSR ); #endif if( temphandle != -1 ) break; if( workFile[5] == 'Z' ) { temphandle = -1; break; } switch( workFile[5] ) { case '9': workFile[5] = 'A'; break; case 'I': workFile[5] = 'J'; /* file-system may be EBCDIC */ break; case 'R': workFile[5] = 'S'; /* file-system may be EBCDIC */ break; default: ++workFile[5]; break; } } #if defined(__UNIX__) /* Under POSIX it's legal to remove a file that's open. The file space will be reclaimed when the handle is closed. This makes sure that the work file always gets removed. */ remove( fname ); tempname = NULL; #else tempname = FNameAdd( fname ); #endif if( temphandle == -1 ) { ioSuppError( ERR_UNABLE_TO_OPEN_WORK_FILE ); } }
static void AddModHandle( char *name, epsp_t *epsp ) /**************************************************/ { mod_t *mod; tiny_ret_t rc; int handle; object_record obj; unsigned_32 off; os2_flat_header os2_hdr; addr_off new_base; unsigned i; if( ModHandles == NULL ) { ModHandles = malloc( sizeof( mod_t ) ); } else { ModHandles = realloc( ModHandles, ( NumModHandles + 1 ) * sizeof( mod_t ) ); } mod = &ModHandles[NumModHandles]; ++NumModHandles; mod->epsp = epsp; mod->loaded = TRUE; mod->SegCount = 0; mod->ObjInfo = NULL; if( XVersion >= 0x404 ) { name = epsp->FileName; } rc = TinyOpen( name, TIO_READ ); if( TINY_ERROR( rc ) ) { return; } handle = TINY_INFO( rc ); TinySeek( handle, OS2_NE_OFFSET, SEEK_SET ); TinyRead( handle, &off, sizeof( off ) ); TinySeek( handle, off, SEEK_SET ); TinyRead( handle, &os2_hdr, sizeof( os2_hdr ) ); TinySeek( handle, os2_hdr.objtab_off + off, SEEK_SET ); mod->SegCount = os2_hdr.num_objects; mod->ObjInfo = malloc( os2_hdr.num_objects * sizeof( seg_t ) ); new_base = 0; for( i = 0; i < os2_hdr.num_objects; ++i ) { TinyRead( handle, &obj, sizeof( obj ) ); mod->ObjInfo[i].flags = obj.flags; mod->ObjInfo[i].base = obj.addr; mod->ObjInfo[i].size = obj.size; mod->ObjInfo[i].new_base = new_base; new_base += ALIGN4K( obj.size ); if( NumModHandles == 1 ) { // main executable if( obj.flags & OBJ_BIG ) { if( obj.flags & OBJ_EXECUTABLE ) { if( flatCode == FLAT_SEL ) { flatCode = ( mod->epsp->SegBase + i * 8 ) | 3; } } else { if( flatData == FLAT_SEL ) { flatData = ( mod->epsp->SegBase + i * 8 ) | 3; } } } } } TinyClose( handle ); }
trap_retval ReqProg_load( void ) { addr_seg psp; pblock parmblock; tiny_ret_t rc; char *parm; char *name; char __far *dst; char exe_name[128]; char ch; EXE_TYPE exe; prog_load_ret *ret; unsigned len; ExceptNum = -1; ret = GetOutPtr( 0 ); memset( &TaskRegs, 0, sizeof( TaskRegs ) ); TaskRegs.EFL = MyFlags() & ~USR_FLAGS; /* build a DOS command line parameter in our PSP command area */ Flags.BoundApp = FALSE; psp = DbgPSP(); parm = name = GetInPtr( sizeof( prog_load_req ) ); if( TINY_ERROR( FindFilePath( name, exe_name, DosExtList ) ) ) { exe_name[0] = '\0'; } while( *parm++ != '\0' ) {} // skip program name len = GetTotalSize() - ( parm - name ) - sizeof( prog_load_req ); if( len > 126 ) len = 126; dst = MK_FP( psp, CMD_OFFSET + 1 ); for( ; len > 0; --len ) { ch = *parm++; if( ch == '\0' ) { if( len == 1 ) break; ch = ' '; } *dst++ = ch; } *dst = '\r'; *(byte __far *)MK_FP( psp, CMD_OFFSET ) = FP_OFF( dst ) - ( CMD_OFFSET + 1 ); parmblock.envstring = 0; parmblock.commandln.segment = psp; parmblock.commandln.offset = CMD_OFFSET; parmblock.fcb01.segment = psp; parmblock.fcb02.segment = psp; parmblock.fcb01.offset = 0x5C; parmblock.fcb02.offset = 0x6C; exe = CheckEXEType( exe_name ); if( EXEhandle != 0 ) { TinyClose( EXEhandle ); EXEhandle = 0; } switch( exe ) { case EXE_RATIONAL_386: ret->err = ERR_RATIONAL_EXE; return( sizeof( *ret ) ); case EXE_PHARLAP_SIMPLE: ret->err = ERR_PHARLAP_EXE; return( sizeof( *ret ) ); } SegmentChain = 0; BoundAppLoading = FALSE; rc = DOSLoadProg( exe_name, &parmblock ); if( TINY_OK( rc ) ) { TaskRegs.SS = parmblock.startsssp.segment; /* for some insane reason DOS returns a starting SP two less then normal */ TaskRegs.ESP = parmblock.startsssp.offset + 2; TaskRegs.CS = parmblock.startcsip.segment; TaskRegs.EIP = parmblock.startcsip.offset; psp = DOSTaskPSP(); } else { psp = TinyAllocBlock( TinyAllocBlock( 0xffff ) ); TinyFreeBlock( psp ); TaskRegs.SS = psp + 0x10; TaskRegs.ESP = 0xfffe; TaskRegs.CS = psp + 0x10; TaskRegs.EIP = 0x100; } TaskRegs.DS = psp; TaskRegs.ES = psp; if( TINY_OK( rc ) ) { if( Flags.NoOvlMgr || !CheckOvl( parmblock.startcsip ) ) { if( exe == EXE_OS2 ) { opcode_type __far *loc_brk_opcode; BoundAppLoading = TRUE; RunProg( &TaskRegs, &TaskRegs ); loc_brk_opcode = MK_FP(TaskRegs.CS, TaskRegs.EIP); if( *loc_brk_opcode == BRKPOINT ) { *loc_brk_opcode = saved_opcode; } BoundAppLoading = FALSE; rc = TinyOpen( exe_name, TIO_READ_WRITE ); if( TINY_OK( rc ) ) { EXEhandle = TINY_INFO( rc ); SeekEXEset( StartByte ); WriteEXE( saved_opcode ); TinySetFileStamp( EXEhandle, EXETime, EXEDate ); TinyClose( EXEhandle ); EXEhandle = 0; Flags.BoundApp = TRUE; } } } } ret->err = TINY_ERROR( rc ) ? TINY_INFO( rc ) : 0; ret->task_id = psp; ret->flags = 0; ret->mod_handle = 0; return( sizeof( *ret ) ); }
unsigned __GrowSeg( unsigned short seg, unsigned int amount ) { unsigned n; /* number of paragraphs desired */ unsigned int old_heaplen; unsigned int old_heap_paras; struct heapblk __far *p; struct freelist __far *pfree; struct freelist __far *pnew; tag __far *last_tag; p = (struct heapblk __far *)MK_FP( seg, 0 ); old_heaplen = p->heaplen; if( old_heaplen != 0 ) { /* if not already 64K */ amount += sizeof(tag); /* 25-feb-91 */ if( amount < sizeof(tag) ) amount = ~0; if( amount < _amblksiz ) amount = _amblksiz; n = ( amount + 0x0f ) >> 4; if( n == 0 ) n = PARAS_IN_64K; /* 23-may-89 */ old_heap_paras = old_heaplen >> 4; n += old_heap_paras; /* We shouldn't extend segments to 64k if we are not going to use the space for this allocation. In protected-mode environments, it should be possible to extend segments later on when we know we can use the space. */ if( n > PARAS_IN_64K ) n = PARAS_IN_64K; if( LastSeg != MK_FP( seg, 0 ) ) { if( seg <= FP_SEG( SyMemEnd ) && seg >= FP_SEG( SyMemBeg ) ) { return( 0 ); } else if ( _IsOn( SW_REMOTE_LINK ) ) { if( TINY_ERROR( TinySetBlock( n, seg ) ) ) return( 0 ); } } else if( FP_SEG( LastSeg ) + n < FP_SEG( LastSeg ) || FP_SEG( LastSeg ) + n > FP_SEG( SyMemEnd ) ) { return( 0 ); } p->heaplen = n << 4; /* put in new heap length */ pfree = MK_FP( seg, p->freehead.prev ); if( FP_OFF(pfree) + pfree->len != old_heaplen - sizeof(tag)*2 ) { /* last free entry not at end of the heap */ /* add a new free entry to end of list */ pnew = MK_FP( seg, old_heaplen - sizeof(tag)*2 ); pnew->prev = FP_OFF(pfree); pnew->next = pfree->next; pfree->next = FP_OFF(pnew); p->freehead.prev = FP_OFF(pnew); p->numfree++; pfree = pnew; } pfree->len = p->heaplen - FP_OFF(pfree) - sizeof(tag)*2; if( pfree->len > p->largest_blk ) p->largest_blk = pfree->len; last_tag = MK_FP( seg, p->heaplen - sizeof(tag)*2 ); *last_tag = END_TAG; last_tag[1] = 0; /* link to next piece of near heap */ return( 1 ); /* indicate segment was grown */ }