/* Copies one file to another (both specified by path). Dynamically * allocates memory for the file buffer. Returns TRUE if successful, * or FALSE if unsuccessful. This function uses _dos_ functions only; * standard C functions are not used. */ BOOL fastcopy( HANDLE hfSrcParm, HANDLE hfDstParm ) { char _far *buf = NULL; unsigned segbuf, count; /* Attempt to dynamically allocate all of memory (0xffff paragraphs). * This will fail, but will return the amount actually available * in segbuf. Then allocate this amount. */ if (_dos_allocmem( 0xffff, &segbuf ) ) { count = segbuf; if(_dos_allocmem( count, &segbuf ) ) return FALSE; } FP_SEG( buf ) = segbuf; /* Read and write until there is nothing left. */ while( count ) { /* Read and write input. */ if( (_dos_read( hfSrcParm, buf, count, &count )) ){ _dos_freemem( segbuf ); return FALSE; } if( (_dos_write( hfDstParm, buf, count, &count )) ){ _dos_freemem( segbuf ); return FALSE; } } /* Free memory. */ _dos_freemem( segbuf ); return TRUE; }
void init_floppyio(void) { int status; ticktimer = 0x00; intflag = 0x00; time_tick_count = 0x00; memset(§or_buf,0,512); status = chs_biosdisk(_DISK_RESET,0, 0, 255,0, 1, §or_buf); if(status) hxc_printf(0,"FDC Reset error : Return value %d\n",status); prev_floppy_int = _dos_getvect( 8+0x6 ); _dos_setvect( 8+0x6, floppy_interrupt_handler ); prev_timer_int = _dos_getvect( 8+0x0 ); _dos_setvect( 8+0x0, timer_interrupt_handler ); if(_dos_allocmem( 32768/16, &dmabuf_seg_rd )) { hxc_printf(0,"Alloc Error !\n"); for(;;); } bufrd = (unsigned char *)MK_FP(dmabuf_seg_rd, 0); if(_dos_allocmem( 32768/16, &dmabuf_seg_wr )) { hxc_printf(0,"Alloc Error !\n"); for(;;); } bufwr = (unsigned char *)MK_FP(dmabuf_seg_wr, 0); reset_drive(0); }
void main( void ) { #if defined(__NT__) || \ ( defined(__OS2__) && \ (defined(__386__) || defined(__PPC__)) ) void *segment; #else unsigned segment; #endif /* Try to allocate 100 paragraphs, then free them */ if( _dos_allocmem( 100, &segment ) != 0 ) { printf( "_dos_allocmem failed\n" ); printf( "Only %u paragraphs available\n", segment ); } else { printf( "_dos_allocmem succeeded\n" ); if( _dos_freemem( segment ) != 0 ) { printf( "_dos_freemem failed\n" ); } else { printf( "_dos_freemem succeeded\n" ); } } }
_WCRTLINK int __F_NAME(spawnve,_wspawnve)( int mode, const CHAR_TYPE * path, const CHAR_TYPE * const argv[], const CHAR_TYPE * const in_envp[] ) { const CHAR_TYPE * const *envp = (const CHAR_TYPE * const *)in_envp; CHAR_TYPE *envmem; CHAR_TYPE *envstrings; unsigned envseg; int len; CHAR_TYPE SPVE_NEAR *np; CHAR_TYPE SPVE_NEAR *p; CHAR_TYPE SPVE_NEAR *end_of_p; int retval; int num_of_paras; /* for environment */ size_t cmdline_len; CHAR_TYPE SPVE_NEAR *cmdline_mem; CHAR_TYPE SPVE_NEAR *cmdline; CHAR_TYPE switch_c[4]; CHAR_TYPE prot_mode286; #if defined( __DOS__ ) auto _87state _87save; #endif CHAR_TYPE *drive; CHAR_TYPE *dir; CHAR_TYPE *fname; CHAR_TYPE *ext; int rc; #if defined( __DOS__ ) && defined( _M_I86 ) #define ENVPARM envseg #else #define ENVPARM envmem #endif #ifdef __USE_POSIX_HANDLE_STRINGS CHAR_TYPE **newEnvp; int count; CHAR_TYPE *fileinfo; int doFreeFlag = 0; if( _fileinfo != 0 ) { fileinfo = __F_NAME(__FormPosixHandleStr,__wFormPosixHandleStr)(); if( fileinfo != NULL ) { count = 1; if( envp != NULL ) { newEnvp = (CHAR_TYPE **)envp; while( *newEnvp != NULL ) { /* count 'em, including NULL */ newEnvp++; count++; } } count++; /* one more for the new entry */ newEnvp = lib_malloc( count * sizeof(CHAR_TYPE*) ); if( newEnvp != NULL ) { if( envp != NULL ) { memcpy( newEnvp, envp, (count-1)*sizeof(CHAR_TYPE*) ); } newEnvp[count-2] = fileinfo;/* add C_FILE_INFO entry */ newEnvp[count-1] = NULL; /* terminate pointer list */ envp = (const CHAR_TYPE **)newEnvp;/* use new environment */ doFreeFlag = 1; /* do cleanup on exit */ } else { lib_free( fileinfo ); } } } #endif #if defined(__386__) || defined(__AXP__) || defined(__PPC__) prot_mode286 = FALSE; #if defined(__OS2__) || defined(__NT__) if( mode == OLD_P_OVERLAY ) { rc = __F_NAME(execve,_wexecve)(path, argv, envp); _POSIX_HANDLE_CLEANUP; return( rc ); } #endif #if defined( __DOS__ ) if( mode >= OLD_P_OVERLAY ) { __set_errno( EINVAL ); rc = -1; _POSIX_HANDLE_CLEANUP; return( rc ); } #endif #else #if defined( __OS2__ ) prot_mode286 = _RWD_osmode; if( mode == OLD_P_OVERLAY ) { rc = execve(path, argv, envp); _POSIX_HANDLE_CLEANUP; return( rc ); } #else prot_mode286 = FALSE; if( mode == OLD_P_OVERLAY ) { execveaddr_type execve; execve = __execaddr(); if( execve != NULL ) { rc = (*execve)( path, argv, envp ); _POSIX_HANDLE_CLEANUP; return( rc ); } __set_errno( EINVAL ); _POSIX_HANDLE_CLEANUP; return( -1 ); } #endif #endif retval = __F_NAME(__cenvarg,__wcenvarg)( argv, envp, &envmem, &envstrings, &envseg, &cmdline_len, FALSE ); if( retval == -1 ) { _POSIX_HANDLE_CLEANUP; return( -1 ); } num_of_paras = retval; len = __F_NAME(strlen,wcslen)( path ) + 7 + _MAX_PATH2; np = LIB_ALLOC( len * sizeof( CHAR_TYPE ) ); if( np == NULL ) { p = (CHAR_TYPE SPVE_NEAR *)alloca( len*sizeof(CHAR_TYPE) ); if( p == NULL ) { lib_free( envmem ); _POSIX_HANDLE_CLEANUP; return( -1 ); } } else { p = np; } __F_NAME(_splitpath2,_wsplitpath2)( path, p + (len-_MAX_PATH2), &drive, &dir, &fname, &ext ); #if defined( __DOS__ ) _RWD_Save8087( &_87save ); #endif #if defined( __DOS__ ) && defined( _M_I86 ) if( _osmode != DOS_MODE ) { /* if protect-mode e.g. DOS/16M */ unsigned segment; if( _dos_allocmem( num_of_paras, &segment ) != 0 ) { lib_nfree( np ); lib_free( envmem ); _POSIX_HANDLE_CLEANUP; return( -1 ); } envseg = segment; _fmemcpy( MK_FP( segment, 0 ), envstrings, num_of_paras * 16 ); } #endif /* allocate the cmdline buffer */ cmdline_mem = LIB_ALLOC( cmdline_len * sizeof( CHAR_TYPE ) ); if( cmdline_mem == NULL ) { cmdline = (CHAR_TYPE SPVE_NEAR *)alloca( cmdline_len*sizeof(CHAR_TYPE) ); if( cmdline == NULL ) { retval = -1; __set_errno( E2BIG ); __set_doserrno( E_badenv ); goto cleanup; } } else { cmdline = cmdline_mem; } #if !defined( __OS2__ ) && !defined(__NT__) if( _RWD_osmajor >= 3 ) { /* 17-oct-88, check version # * 'append' program in DOS has a bug, so we avoid it by putting '.\' * on the front of a filename that doesn't have a path or drive */ if( drive[0] == 0 && dir[0] == 0 ) { dir = ".\\"; } } #endif __F_NAME(_makepath,_wmakepath)( p, drive, dir, fname, ext ); __set_errno( ENOENT ); if( ext[0] != '\0' ) { #if defined( __OS2__ ) if( stricmp( ext, ".cmd" ) == 0 || stricmp( ext, ".bat" ) == 0 ) #else if( __F_NAME(stricmp,wcscmp)( ext, __F_NAME(".bat",L".bat") ) == 0 ) #endif { retval = -1; /* assume file doesn't exist */ if( file_exists( p ) ) goto spawn_command_com; } else { __set_errno( 0 ); /* user specified an extension, so try it */ retval = x_dospawn( mode, p, cmdline, ENVPARM, argv ); } } #if defined( __OS2__ ) || defined( __NT__ ) /* * consider the following valid executable filenames: * a.b.exe a.cmd.exe a.exe.cmd a.cmd * we must always try to add .exe, etc. */ if( _RWD_errno == ENOENT || _RWD_errno == EINVAL ) { #else else { #endif end_of_p = p + __F_NAME(strlen,wcslen)( p ); if( prot_mode286 ) { __set_errno( ENOENT ); } else { __F_NAME(strcpy,wcscpy)( end_of_p, __F_NAME(".com",L".com") ); __set_errno( 0 ); retval = x_dospawn( mode, p, cmdline, ENVPARM, argv ); } if( _RWD_errno == ENOENT || _RWD_errno == EINVAL ) { __set_errno( 0 ); __F_NAME(strcpy,wcscpy)( end_of_p, __F_NAME(".exe",L".exe") ); retval = x_dospawn( mode, p, cmdline, ENVPARM, argv ); if( _RWD_errno == ENOENT || _RWD_errno == EINVAL ) { /* try for a .BAT file */ __set_errno( 0 ); #if defined( __OS2__ ) strcpy( end_of_p, ".cmd" ); if( !file_exists( p ) ) strcpy( end_of_p, ".bat" ); #else __F_NAME(strcpy,wcscpy)( end_of_p, __F_NAME(".bat",L".bat") ); #endif if( file_exists( p ) ) { spawn_command_com: /* the environment will have to be reconstructed */ lib_free( envmem ); envmem = NULL; __F_NAME(__ccmdline,__wccmdline)( p, argv, cmdline, 1 ); #ifdef __WIDECHAR__ retval = _wspawnl( mode, _wgetenv(L"COMSPEC"), prot_mode286 ? L"CMD" : L"COMMAND", __wSlash_C( switch_c, prot_mode286 ), p, cmdline, NULL ); #else retval = spawnl( mode, getenv("COMSPEC"), prot_mode286 ? "CMD" : "COMMAND", __Slash_C( switch_c, prot_mode286 ), p, cmdline, NULL ); #endif } } } } cleanup: _POSIX_HANDLE_CLEANUP; LIB_FREE( cmdline_mem ); LIB_FREE( np ); lib_free( envmem ); #if !defined(__OS2__) && defined( _M_I86 ) if( _osmode != DOS_MODE ) { /* if protect-mode e.g. DOS/16M */ _dos_freemem( envseg ); } #endif #if defined( __DOS__ ) _RWD_Rest8087( &_87save ); #endif return( retval ); }
static void _dos_freemem_wrap(void far *x) { if (x != NULL) _dos_freemem(FP_SEG(x)); } static void far *_dos_allocmem_wrap(unsigned long sz) { unsigned segs,res,err; if (sz >= 0xBFFFFUL) return NULL; if (sz != 0) segs = (unsigned)((sz + 0xFUL) >> 4UL); else segs = 1; err = _dos_allocmem(segs,&res); if (err != 0) return NULL; return MK_FP(res,0); } #endif /* one bit per channel that is 16-bit AND requires address shift (lower 16 bits >> 1) AND the counter is # of WORDs */ /* in the original implementation we take the lower 16 bits and shift right by 1 for WORD transfers, * the later Intel chipsets allow for 8, 16 & 32-bit transfers on any channel with or without * the 16-bit address shift, which is why this is a variable not a const */ unsigned char d8237_16bit_ashift = 0xF0; static int d8237_readwrite_test4(unsigned int bch) { int j,i;
int exeload_load_fd(struct exeload_ctx *exe,const int fd/*must be open, you must lseek to EXE header*/) { struct exe_dos_header *header; unsigned char *hdr=NULL; unsigned long img_sz=0; unsigned long hdr_sz=0; unsigned long add_sz=0; // BSS segment if (exe == NULL) return 0; exeload_free(exe); if (fd < 0) return 0; // keep a local copy so the C compiler doesn't have to keep dereferencing exe->header header = exe->header = malloc(sizeof(*header)); if (header == NULL) goto fail; { if (read(fd,header,sizeof(*header)) < sizeof(*header)) goto fail; if (header->magic != 0x5A4D) goto fail; /* img_sz = number of blocks part of EXE file */ img_sz = exe_dos_header_file_resident_size(header); /* EXE header size */ hdr_sz = exe_dos_header_file_header_size(header); if (hdr_sz < 0x20UL) goto fail; /* header must be at least 32 bytes */ if (hdr_sz > 0x8000UL) goto fail; /* header up to 32KB supported */ if (hdr_sz >= img_sz) goto fail; /* header cannot completely consume EXE file */ /* additional resident set (BSS segment) */ add_sz = exe_dos_header_bss_size(header); if (add_sz > 0xA0000UL) goto fail; /* 640KB limit */ /* this loader only supports EXE images (resident part) up to 640KB */ if ((img_sz+add_sz-hdr_sz) >= 0xA0000UL) goto fail; /* finish loading EXE header */ hdr = malloc((unsigned short)hdr_sz); if (hdr == NULL) goto fail; memcpy(hdr,header,sizeof(*header)); /* this is why header must be 20 bytes, also to make valid structure */ } /* finish loading EXE header */ { unsigned short more = (unsigned short)(hdr_sz - sizeof(*header)); /* hdr_sz >= 0x20 therefore this cannot be zero */ if (read(fd,hdr+sizeof(*header),more) < more) goto fail; } /* allocate resident section. * resident section is resident part of EXE on disk plus BSS segment in memory (additional paragraphs) */ { unsigned short paras = (unsigned short)((img_sz+add_sz+0xFUL/*round up*/-hdr_sz) >> 4UL); /* NTS: should never exceed 640KB */ if (_dos_allocmem(paras,&exe->base_seg) != 0) goto fail; exe->len_seg = paras; } /* file pointer is just past EXE header, load contents */ { const unsigned int maxload = 0x8000U; // 32KB (must be multiple of 16) unsigned int load_seg = exe->base_seg; unsigned long rem = img_sz - hdr_sz; unsigned int doload; while (rem > 0UL) { if (rem > (unsigned long)maxload) doload = maxload; else doload = (unsigned int)rem; if (_dos_xread(fd,(void far*)MK_FP(load_seg,0),doload) != doload) goto fail; load_seg += doload >> 4UL; rem -= doload; } } /* need to zero additional size */ if (add_sz != 0) { unsigned long rem = add_sz; unsigned long ao = img_sz-hdr_sz; unsigned int zero_seg = exe->base_seg+(ao>>4UL); const unsigned int maxz = 0x8000U; unsigned int doz; while (rem > 0UL) { if (rem > (unsigned long)maxz) doz = maxz; else doz = (unsigned int)rem; _fmemset(MK_FP(zero_seg,(unsigned int)ao&0xFU),0,doz); zero_seg += doz >> 4UL; rem -= doz; } }
uint32_t _memmax(void) { uint16_t max; _dos_allocmem(0xffff, &max); return (uint32_t)max << 4; }