mirror of https://github.com/FDOS/kernel.git
Cleaned up task.c (merged much of DOSExe/ComLoader); transform the CDS into
a proper array. git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@413 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
parent
3b5e79890e
commit
511bf63d16
|
@ -1,10 +1,39 @@
|
|||
2002 Aug xx - Build 2027
|
||||
-------- Bart Oldeman (bart@dosemu.org)
|
||||
+ Changes Tom
|
||||
|
||||
* enable LBA FAT16 booting
|
||||
* workaround for redirectors that do/do not set the opencount
|
||||
* int25/26 should fail for redirectors
|
||||
* set the number of sectors per track in the INT 1E table when
|
||||
reading/writing floppies
|
||||
* disabled fatal() in error.c
|
||||
* Disable the A20 line upon exec (int21/ah=4B). This is necessary for some
|
||||
brain-dead exepacked programs.
|
||||
* removed unnecessary buffer fields
|
||||
* proper check for network/non-existing drive for int25/26.
|
||||
* save more bytes on the stack at various places
|
||||
+ Changes Bart
|
||||
* patchobj makefile correction
|
||||
* printf uses va_list etc.
|
||||
* quicker and more robust Watcom build
|
||||
* use FS: and GS: for Watcom 386.
|
||||
* workaround: don't use DL for floppy boots, but fixed A:
|
||||
* disable unused functions in floppy.asm
|
||||
* cleaner prototypes (thanks to gcc)
|
||||
* reorganized ioctl.c; there was an uninitialized variable.
|
||||
* inlined some functions of fattab.c
|
||||
* added (f)strcmp, (f)memcmp and (f)memchr to asmsupt.asm
|
||||
* initially suggested by Arkady: dsk.c FS_info copy optimization
|
||||
* initialize a VDISK signature in the HMA
|
||||
* sysclk.c: small size optimization
|
||||
* small UMB fixes
|
||||
* made the CDS into a proper array instead of a structure with
|
||||
one member
|
||||
* large task.c cleanups -
|
||||
merge as much as possible from DosExeLoader and DosComLoader
|
||||
(from Tom:) eliminate some structures in low memory
|
||||
* main.c: slightly cleanup "SHELL=" line parsing.
|
||||
|
||||
2002 May 9 - Build 2026b
|
||||
-------- Bart Oldeman (bart@dosemu.org)
|
||||
+ Changes Tom
|
||||
|
|
|
@ -72,7 +72,7 @@ fl_rst1: xor ax,ax ; FALSE on error
|
|||
; 2 Drive present, can detect disk change
|
||||
; 3 Fixed disk
|
||||
;
|
||||
|
||||
%if 0
|
||||
global _fl_readdasd
|
||||
_fl_readdasd:
|
||||
push bp
|
||||
|
@ -93,7 +93,7 @@ fl_rdasd1: mov ah,0 ; BIOS reset disketter & fixed disk
|
|||
mov ax,0FFh ; 0xFF on error
|
||||
pop bp ; C exit
|
||||
ret
|
||||
|
||||
%endif
|
||||
|
||||
;
|
||||
;
|
||||
|
@ -138,7 +138,7 @@ fl_dc_error: mov ax,0FFh ; 0xFF on error
|
|||
;
|
||||
; See Phoenix Bios Book for error code meanings
|
||||
;
|
||||
|
||||
%if 0
|
||||
global _fl_rd_status
|
||||
_fl_rd_status:
|
||||
push bp ; C entry
|
||||
|
@ -153,7 +153,7 @@ _fl_rd_status:
|
|||
|
||||
pop bp ; C exit
|
||||
ret
|
||||
|
||||
%endif
|
||||
|
||||
;
|
||||
; Format Sectors
|
||||
|
|
47
hdr/cds.h
47
hdr/cds.h
|
@ -37,20 +37,29 @@ static BYTE *Cds_hRcsId =
|
|||
|
||||
struct cds {
|
||||
BYTE cdsCurrentPath[MAX_CDSPATH];
|
||||
UWORD cdsFlags;
|
||||
struct dpb FAR *cdsDpb;
|
||||
UWORD cdsFlags; /* see below */
|
||||
struct dpb FAR *cdsDpb; /* if != 0, associated DPB */
|
||||
|
||||
union {
|
||||
BYTE FAR *_cdsRedirRec;
|
||||
BYTE FAR *_cdsRedirRec; /* IFS record */
|
||||
struct {
|
||||
UWORD _cdsStrtClst;
|
||||
UWORD _cdsStrtClst; /* if local path (Flags & CDSPHYSDRV):
|
||||
start cluster of CWD; root == 0,
|
||||
never access == 0xFFFF */
|
||||
UWORD _cdsParam;
|
||||
} _cdsRedir;
|
||||
} _cdsUnion;
|
||||
|
||||
UWORD cdsStoreUData;
|
||||
|
||||
WORD cdsJoinOffset;
|
||||
#define cdsJoinOffset cdsBackslashOffset
|
||||
WORD cdsBackslashOffset; /* Position of "root directory" backslash for
|
||||
this drive within CurrentPath[]
|
||||
prerequisites:
|
||||
+ ofs <= strlen(currentPath)
|
||||
+ if UNC: ofs > share component
|
||||
if local path: ofs > colon
|
||||
*/
|
||||
|
||||
BYTE cdsNetFlag1;
|
||||
BYTE FAR *cdsIfs;
|
||||
|
@ -62,17 +71,29 @@ struct cds {
|
|||
#define cdsRedirRec _cdsUnion._cdsRedirRec
|
||||
#define cdsParam _cdsUnion._cdsRedir._cdsParam
|
||||
|
||||
typedef struct _cdstbl {
|
||||
struct cds cds_table[26];
|
||||
} cdstbl;
|
||||
|
||||
/* Bits for cdsFlags */
|
||||
/* Bits for cdsFlags (OR combination) */
|
||||
#define CDSNETWDRV 0x8000
|
||||
#define CDSPHYSDRV 0x4000
|
||||
#define CDSJOINED 0x2000
|
||||
#define CDSSUBST 0x1000
|
||||
#define CDSVALID (CDSNETWDRV | CDSPHYSDRV)
|
||||
#define CDSJOINED 0x2000 /* not in combination with NETWDRV or SUBST */
|
||||
#define CDSSUBST 0x1000 /* not in combination with NETWDRV or JOINED */
|
||||
#define CDS_HIDDEN (1 << 7) /* hide drive from redirector's list */
|
||||
|
||||
/* NETWORK PHYSICAL meaning
|
||||
0 0 drive not accessable
|
||||
0 1 local file system
|
||||
1 0 networked file system (UNC naming convention)
|
||||
1 1 installable file system (IFS)
|
||||
*/
|
||||
#define CDSMODEMASK (CDSNETWDRV | CDSPHYSDRV)
|
||||
|
||||
/* #define CDSVALID (CDSNETWDRV | CDSPHYSDRV) */
|
||||
#define CDSVALID CDSMODEMASK
|
||||
|
||||
#define IS_DEVICE 0x20
|
||||
#define IS_NETWORK 0x40
|
||||
|
||||
#define CDS_MODE_SKIP_PHYSICAL 0x01 /* don't resolve SUBST, JOIN, NETW */
|
||||
#define CDS_MODE_CHECK_DEV_PATH 0x02 /* check for existence of device path */
|
||||
/*
|
||||
* Log: cds.h,v
|
||||
* Revision 1.2 2000/03/09 06:06:38 kernel
|
||||
|
|
|
@ -47,8 +47,8 @@ static BYTE *date_hRcsId =
|
|||
|
||||
#define REVISION_MAJOR 1
|
||||
#define REVISION_MINOR 1
|
||||
#define REVISION_SEQ 26
|
||||
#define BUILD "2026"
|
||||
#define SUB_BUILD "b"
|
||||
#define KERNEL_VERSION_STRING "1.1.26b" /*#REVISION_MAJOR "." #REVISION_MINOR "." #REVISION_SEQ */
|
||||
#define KERNEL_BUILD_STRING "2026b" /*#BUILD SUB_BUILD */
|
||||
#define REVISION_SEQ 27
|
||||
#define BUILD "2027"
|
||||
#define SUB_BUILD "test"
|
||||
#define KERNEL_VERSION_STRING "1.1.27" /*#REVISION_MAJOR "." #REVISION_MINOR "." #REVISION_SEQ */
|
||||
#define KERNEL_BUILD_STRING "2027test" /*#BUILD SUB_BUILD */
|
||||
|
|
|
@ -76,7 +76,7 @@ STATIC VOID setblkno(struct buffer FAR * bp, ULONG blkno)
|
|||
bp->b_blkno = blkno;
|
||||
/* bp->b_dpbp = &blk_devices[bp->b_unit]; */
|
||||
|
||||
bp->b_dpbp = CDSp->cds_table[bp->b_unit].cdsDpb;
|
||||
bp->b_dpbp = CDSp[bp->b_unit].cdsDpb;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -416,13 +416,13 @@ UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks,
|
|||
{
|
||||
/* REG struct dpb *dpbp = &blk_devices[dsk]; */
|
||||
|
||||
REG struct dpb FAR *dpbp = CDSp->cds_table[dsk].cdsDpb;
|
||||
REG struct dpb FAR *dpbp = CDSp[dsk].cdsDpb;
|
||||
|
||||
if ((UCOUNT) dsk >= lastdrive)
|
||||
{
|
||||
return 0x0201; /* illegal command */
|
||||
}
|
||||
if ((CDSp->cds_table[dsk].cdsFlags & (CDSPHYSDRV | CDSNETWDRV)) != CDSPHYSDRV)
|
||||
if ((CDSp[dsk].cdsFlags & (CDSPHYSDRV | CDSNETWDRV)) != CDSPHYSDRV)
|
||||
{
|
||||
return 0x0201; /* illegal command */
|
||||
}
|
||||
|
|
|
@ -107,8 +107,8 @@ struct dpb FAR * GetDriveDPB(UBYTE drive, COUNT * rc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
dpb = CDSp->cds_table[drive].cdsDpb;
|
||||
if (dpb == 0 || CDSp->cds_table[drive].cdsFlags & CDSNETWDRV)
|
||||
dpb = CDSp[drive].cdsDpb;
|
||||
if (dpb == 0 || CDSp[drive].cdsFlags & CDSNETWDRV)
|
||||
{
|
||||
*rc = DE_INVLDDRV;
|
||||
return 0;
|
||||
|
@ -1020,7 +1020,7 @@ BOOL DosGetFree(UBYTE drive, UCOUNT FAR * spc, UCOUNT FAR * navc,
|
|||
if (drive >= lastdrive)
|
||||
return FALSE;
|
||||
|
||||
cdsp = &CDSp->cds_table[drive];
|
||||
cdsp = &CDSp[drive];
|
||||
|
||||
if (!(cdsp->cdsFlags & CDSVALID))
|
||||
return FALSE;
|
||||
|
@ -1050,7 +1050,7 @@ BOOL DosGetFree(UBYTE drive, UCOUNT FAR * spc, UCOUNT FAR * navc,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
dpbp = CDSp->cds_table[drive].cdsDpb;
|
||||
dpbp = CDSp[drive].cdsDpb;
|
||||
if (dpbp == NULL)
|
||||
return FALSE;
|
||||
|
||||
|
@ -1127,7 +1127,7 @@ COUNT DosGetExtFree(BYTE FAR * DriveString, struct xfreespace FAR * xfsp)
|
|||
if (drive >= lastdrive)
|
||||
return DE_INVLDDRV;
|
||||
|
||||
cdsp = &CDSp->cds_table[drive];
|
||||
cdsp = &CDSp[drive];
|
||||
|
||||
if (!(cdsp->cdsFlags & CDSVALID))
|
||||
return DE_INVLDDRV;
|
||||
|
@ -1143,7 +1143,7 @@ COUNT DosGetExtFree(BYTE FAR * DriveString, struct xfreespace FAR * xfsp)
|
|||
}
|
||||
else
|
||||
{
|
||||
dpbp = CDSp->cds_table[drive].cdsDpb;
|
||||
dpbp = CDSp[drive].cdsDpb;
|
||||
if (dpbp == NULL || media_check(dpbp) < 0)
|
||||
return DE_INVLDDRV;
|
||||
xfsp->xfs_secsize = dpbp->dpb_secsize;
|
||||
|
@ -1172,12 +1172,12 @@ COUNT DosGetCuDir(UBYTE drive, BYTE FAR * s)
|
|||
drive = (drive == 0 ? default_drive : drive - 1);
|
||||
|
||||
/* first check for valid drive */
|
||||
if (drive >= lastdrive || !(CDSp->cds_table[drive].cdsFlags & CDSVALID))
|
||||
if (drive >= lastdrive || !(CDSp[drive].cdsFlags & CDSVALID))
|
||||
{
|
||||
return DE_INVLDDRV;
|
||||
}
|
||||
|
||||
current_ldt = &CDSp->cds_table[drive];
|
||||
current_ldt = &CDSp[drive];
|
||||
/* ensure termination of fstrcpy */
|
||||
cp[MAX_CDSPATH - 1] = '\0';
|
||||
|
||||
|
@ -1223,7 +1223,7 @@ COUNT DosChangeDir(BYTE FAR * s)
|
|||
return result;
|
||||
}
|
||||
|
||||
current_ldt = &CDSp->cds_table[drive];
|
||||
current_ldt = &CDSp[drive];
|
||||
|
||||
if (strlen(PriPathName) > sizeof(current_ldt->cdsCurrentPath) - 1)
|
||||
return DE_PATHNOTFND;
|
||||
|
@ -1364,7 +1364,7 @@ COUNT DosFindNext(void)
|
|||
fmemset(dta, 0, sizeof(dmatch));
|
||||
p = dta;
|
||||
dta = (BYTE FAR *) TempBuffer;
|
||||
current_ldt = &CDSp->cds_table[((dmatch *) TempBuffer)->dm_drive];
|
||||
current_ldt = &CDSp[((dmatch *) TempBuffer)->dm_drive];
|
||||
rc = (((dmatch *) TempBuffer)->dm_drive & 0x80) ?
|
||||
remote_findnext((VOID FAR *) current_ldt) : dos_findnext();
|
||||
|
||||
|
@ -1457,7 +1457,7 @@ COUNT DosGetFattr(BYTE FAR * name)
|
|||
return 0x10;
|
||||
}
|
||||
|
||||
current_ldt = &CDSp->cds_table[drive];
|
||||
current_ldt = &CDSp[drive];
|
||||
if (current_ldt->cdsFlags & CDSNETWDRV)
|
||||
{
|
||||
return remote_getfattr();
|
||||
|
@ -1518,7 +1518,7 @@ COUNT DosSetFattr(BYTE FAR * name, UWORD attrp)
|
|||
return result;
|
||||
}
|
||||
|
||||
current_ldt = &CDSp->cds_table[drive];
|
||||
current_ldt = &CDSp[drive];
|
||||
if (current_ldt->cdsFlags & CDSNETWDRV)
|
||||
{
|
||||
return remote_setfattr(attrp);
|
||||
|
@ -1543,7 +1543,7 @@ COUNT DosSetFattr(BYTE FAR * name, UWORD attrp)
|
|||
|
||||
UBYTE DosSelectDrv(UBYTE drv)
|
||||
{
|
||||
current_ldt = &CDSp->cds_table[drv];
|
||||
current_ldt = &CDSp[drv];
|
||||
|
||||
if ((drv < lastdrive) && (current_ldt->cdsFlags & CDSVALID))
|
||||
/*
|
||||
|
@ -1575,7 +1575,7 @@ COUNT DosDelete(BYTE FAR * path, int attrib)
|
|||
{
|
||||
return result;
|
||||
}
|
||||
current_ldt = &CDSp->cds_table[drive];
|
||||
current_ldt = &CDSp[drive];
|
||||
if (current_ldt->cdsFlags & CDSNETWDRV)
|
||||
{
|
||||
return remote_delete();
|
||||
|
@ -1601,7 +1601,7 @@ COUNT DosRenameTrue(BYTE * path1, BYTE * path2, int attrib)
|
|||
{
|
||||
return DE_INVLDDRV;
|
||||
}
|
||||
current_ldt = &CDSp->cds_table[drive1];
|
||||
current_ldt = &CDSp[drive1];
|
||||
if (current_ldt->cdsFlags & CDSNETWDRV)
|
||||
{
|
||||
return remote_rename();
|
||||
|
@ -1650,7 +1650,7 @@ COUNT DosMkdir(BYTE FAR * dir)
|
|||
{
|
||||
return result;
|
||||
}
|
||||
current_ldt = &CDSp->cds_table[drive];
|
||||
current_ldt = &CDSp[drive];
|
||||
if (current_ldt->cdsFlags & CDSNETWDRV)
|
||||
{
|
||||
return remote_mkdir();
|
||||
|
@ -1680,8 +1680,8 @@ COUNT DosRmdir(BYTE FAR * dir)
|
|||
{
|
||||
return result;
|
||||
}
|
||||
current_ldt = &CDSp->cds_table[drive];
|
||||
if (CDSp->cds_table[drive].cdsFlags & CDSNETWDRV)
|
||||
current_ldt = &CDSp[drive];
|
||||
if (CDSp[drive].cdsFlags & CDSNETWDRV)
|
||||
{
|
||||
return remote_rmdir();
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ f_node_ptr dir_open(BYTE * dirname)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
cdsp = &CDSp->cds_table[drive];
|
||||
cdsp = &CDSp[drive];
|
||||
|
||||
/* Generate full path name */
|
||||
/* not necessary anymore, since truename did that already
|
||||
|
@ -576,7 +576,7 @@ COUNT dos_findnext(void)
|
|||
|
||||
/* Select the default to help non-drive specified path */
|
||||
/* searches... */
|
||||
fnp->f_dpb = CDSp->cds_table[dmp->dm_drive].cdsDpb;
|
||||
fnp->f_dpb = CDSp[dmp->dm_drive].cdsDpb;
|
||||
if (media_check(fnp->f_dpb) < 0)
|
||||
{
|
||||
release_f_node(fnp);
|
||||
|
|
|
@ -227,7 +227,7 @@ f_node_ptr split_path(BYTE * path, BYTE * fname, BYTE * fext)
|
|||
{
|
||||
return (f_node_ptr) 0;
|
||||
}
|
||||
cdsp = &CDSp->cds_table[nDrive];
|
||||
cdsp = &CDSp[nDrive];
|
||||
|
||||
/* 11/29/99 jt
|
||||
* Networking and Cdroms. You can put in here a return.
|
||||
|
@ -2187,7 +2187,7 @@ COUNT media_check(REG struct dpb FAR * dpbp)
|
|||
#endif
|
||||
/* need to change to root directory if changed */
|
||||
if (status == M_CHANGED)
|
||||
CDSp->cds_table[dpbp->dpb_unit].cdsCurrentPath[3] = '\0';
|
||||
CDSp[dpbp->dpb_unit].cdsCurrentPath[3] = '\0';
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
|
@ -2210,7 +2210,7 @@ struct dhdr FAR *select_unit(COUNT drive)
|
|||
/* Just get the header from the dhdr array */
|
||||
/* return blk_devices[drive].dpb_device; */
|
||||
|
||||
return (struct dhdr FAR *)CDSp->cds_table[drive].cdsDpb;
|
||||
return (struct dhdr FAR *)CDSp[drive].cdsDpb;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -261,7 +261,7 @@ CLUSTER next_cluster(struct dpb FAR * dpbp, CLUSTER ClusterNum)
|
|||
bp = getFATblock(ClusterNum, dpbp);
|
||||
|
||||
if (bp == NULL)
|
||||
return DE_BLKINVLD;
|
||||
return 1; /* the only error code possible here */
|
||||
|
||||
if (ISFAT12(dpbp))
|
||||
{
|
||||
|
|
|
@ -70,7 +70,7 @@ VOID FatGetDrvData(UCOUNT drive, UCOUNT FAR * spc, UCOUNT FAR * bps,
|
|||
if (DosGetFree((UBYTE) drive, spc, &navc, bps, nc))
|
||||
{
|
||||
struct cds FAR *cdsp =
|
||||
&CDSp->cds_table[(drive == 0 ? default_drive : drive - 1)];
|
||||
&CDSp[(drive == 0 ? default_drive : drive - 1)];
|
||||
/* Point to the media desctriptor for this drive */
|
||||
if (cdsp->cdsFlags & CDSNETWDRV)
|
||||
{
|
||||
|
|
|
@ -267,7 +267,7 @@ FAR * ASM clock, /* CLOCK$ device */
|
|||
extern WORD ASM maxbksize; /* Number of Drives in system */
|
||||
extern struct buffer
|
||||
FAR *ASM firstbuf; /* head of buffers linked list */
|
||||
extern cdstbl FAR * ASM CDSp; /* Current Directory Structure */
|
||||
extern struct cds FAR * ASM CDSp; /* Current Directory Structure */
|
||||
extern
|
||||
struct cds FAR * ASM current_ldt;
|
||||
extern LONG ASM current_filepos; /* current file position */
|
||||
|
|
|
@ -655,8 +655,8 @@ dispatch:
|
|||
break;
|
||||
}
|
||||
|
||||
dpb = CDSp->cds_table[drv].cdsDpb;
|
||||
if (dpb == 0 || CDSp->cds_table[drv].cdsFlags & CDSNETWDRV)
|
||||
dpb = CDSp[drv].cdsDpb;
|
||||
if (dpb == 0 || CDSp[drv].cdsFlags & CDSNETWDRV)
|
||||
{
|
||||
r->AL = 0xFF;
|
||||
CritErrCode = 0x0f;
|
||||
|
@ -1264,14 +1264,14 @@ dispatch:
|
|||
case 0x07:
|
||||
if (r->DL < lastdrive)
|
||||
{
|
||||
CDSp->cds_table[r->DL].cdsFlags |= 0x100;
|
||||
CDSp[r->DL].cdsFlags |= 0x100;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x08:
|
||||
if (r->DL < lastdrive)
|
||||
{
|
||||
CDSp->cds_table[r->DL].cdsFlags &= ~0x100;
|
||||
CDSp[r->DL].cdsFlags &= ~0x100;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1432,7 +1432,7 @@ dispatch:
|
|||
if (rc < lastdrive)
|
||||
{
|
||||
UWORD saveCX = r->CX;
|
||||
if (CDSp->cds_table[rc].cdsFlags & CDSNETWDRV)
|
||||
if (CDSp[rc].cdsFlags & CDSNETWDRV)
|
||||
{
|
||||
goto error_invalid;
|
||||
}
|
||||
|
@ -1842,8 +1842,8 @@ VOID ASMCFUNC int2526_handler(WORD mode, struct int25regs FAR * r)
|
|||
}
|
||||
|
||||
#ifdef WITHFAT32
|
||||
if (!(CDSp->cds_table[drv].cdsFlags & CDSNETWDRV) &&
|
||||
ISFAT32(CDSp->cds_table[drv].cdsDpb))
|
||||
if (!(CDSp[drv].cdsFlags & CDSNETWDRV) &&
|
||||
ISFAT32(CDSp[drv].cdsDpb))
|
||||
{
|
||||
r->ax = 0x207;
|
||||
r->flags |= FLG_CARRY;
|
||||
|
@ -2017,7 +2017,7 @@ VOID ASMCFUNC int2F_12_handler(volatile struct int2f12regs r)
|
|||
else
|
||||
{
|
||||
r.ds = FP_SEG(CDSp);
|
||||
r.si = FP_OFF(&CDSp->cds_table[drv]);
|
||||
r.si = FP_OFF(&CDSp[drv]);
|
||||
r.flags &= ~FLG_CARRY;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -110,8 +110,8 @@ COUNT DosDevIOctl(iregs FAR * r)
|
|||
return DE_INVLDDRV;
|
||||
else
|
||||
{
|
||||
/* cdsp = &CDSp->cds_table[CharReqHdr.r_unit]; */
|
||||
dpbp = CDSp->cds_table[CharReqHdr.r_unit].cdsDpb;
|
||||
/* cdsp = &CDSp[CharReqHdr.r_unit]; */
|
||||
dpbp = CDSp[CharReqHdr.r_unit].cdsDpb;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -278,7 +278,7 @@ COUNT DosDevIOctl(iregs FAR * r)
|
|||
return DE_INVLDFUNC;
|
||||
|
||||
case 0x09:
|
||||
if (CDSp->cds_table[CharReqHdr.r_unit].cdsFlags & CDSNETWDRV)
|
||||
if (CDSp[CharReqHdr.r_unit].cdsFlags & CDSNETWDRV)
|
||||
{
|
||||
r->DX = ATTR_REMOTE;
|
||||
r->AX = S_DONE | S_BUSY;
|
||||
|
|
|
@ -64,7 +64,7 @@ COUNT lfn_allocate_inode(VOID)
|
|||
}
|
||||
|
||||
/* Check that default drive is a block device */
|
||||
cdsp = &CDSp->cds_table[default_drive];
|
||||
cdsp = &CDSp[default_drive];
|
||||
|
||||
if (cdsp->cdsDpb == 0)
|
||||
{
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "dyndata.h"
|
||||
#include "init-dat.h"
|
||||
|
||||
GLOBAL BYTE copyright[] =
|
||||
char copyright[] =
|
||||
"(C) Copyright 1995-2002 Pasquale J. Villani and The FreeDOS Project.\n"
|
||||
"All Rights Reserved. This is free software and comes with ABSOLUTELY NO\n"
|
||||
"WARRANTY; you can redistribute it and/or modify it under the terms of the\n"
|
||||
|
@ -58,7 +58,7 @@ GLOBAL BYTE DOSFAR os_release[];
|
|||
GLOBAL seg DOSFAR RootPsp; /* Root process -- do not abort */
|
||||
|
||||
extern struct dpb FAR *DOSFAR ASM DPBp; /* First drive Parameter Block */
|
||||
extern cdstbl FAR *DOSFAR ASM CDSp; /* Current Directory Structure */
|
||||
extern struct cds FAR *DOSFAR ASM CDSp; /* Current Directory Structure */
|
||||
|
||||
extern struct dhdr FAR *DOSFAR ASM clock, /* CLOCK$ device */
|
||||
FAR * DOSFAR ASM syscon; /* console device */
|
||||
|
@ -169,7 +169,7 @@ VOID ASMCFUNC FreeDOSmain(void)
|
|||
setvec(0, int0_handler); /* zero divide */
|
||||
setvec(1, empty_handler); /* single step */
|
||||
setvec(3, empty_handler); /* debug breakpoint */
|
||||
setvec(6, empty_handler); /* invalid opcode */
|
||||
setvec(6, int6_handler); /* invalid opcode */
|
||||
|
||||
/* clear the Init BSS area (what normally the RTL does */
|
||||
memset(_ib_start, 0, _ib_end - _ib_start);
|
||||
|
@ -315,7 +315,7 @@ STATIC VOID FsConfig(VOID)
|
|||
/* Initialize the current directory structures */
|
||||
for (i = 0; i < lastdrive; i++)
|
||||
{
|
||||
struct cds FAR *pcds_table = &CDSp->cds_table[i];
|
||||
struct cds FAR *pcds_table = &CDSp[i];
|
||||
|
||||
fmemcpy(pcds_table->cdsCurrentPath, "A:\\\0", 4);
|
||||
|
||||
|
@ -371,6 +371,8 @@ STATIC VOID signon()
|
|||
printf(" - MSC");
|
||||
#elif defined(__WATCOMC__)
|
||||
printf(" - WATCOMC");
|
||||
#elif defined(__GNUC__)
|
||||
printf(" - GNUC"); /* this is hypothetical only */
|
||||
#else
|
||||
generate some bullshit error here, as the compiler should be known
|
||||
#endif
|
||||
|
@ -443,20 +445,19 @@ STATIC void kernel()
|
|||
{
|
||||
|
||||
/* insert /D, /Y as first argument */
|
||||
int cmdEnd, i, slen = 3; /* strlen(insertString); */
|
||||
char *p, *q;
|
||||
|
||||
for (cmdEnd = 0; cmdEnd < sizeof(Cmd.ctBuffer); cmdEnd++)
|
||||
for (p = Cmd.ctBuffer; p < &Cmd.ctBuffer[Cmd.ctCount]; p++)
|
||||
{
|
||||
if (Cmd.ctBuffer[cmdEnd] == ' ' ||
|
||||
Cmd.ctBuffer[cmdEnd] == '\t' || Cmd.ctBuffer[cmdEnd] == '\r')
|
||||
if (*p == ' ' || *p == '\t' || *p == '\r')
|
||||
{
|
||||
for (i = sizeof(Cmd.ctBuffer) - slen - 1; i >= cmdEnd; i--)
|
||||
Cmd.ctBuffer[i + slen] = Cmd.ctBuffer[i];
|
||||
for (q = &Cmd.ctBuffer[Cmd.ctCount - 1]; q >= p; q--)
|
||||
q[3] = q[0];
|
||||
|
||||
fmemcpy(&Cmd.ctBuffer[cmdEnd], insertString, slen);
|
||||
|
||||
Cmd.ctCount += slen;
|
||||
fmemcpy(p, insertString, 3);
|
||||
|
||||
Cmd.ctCount += 3;
|
||||
printf("%d %s\n", Cmd.ctCount, Cmd.ctBuffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -529,8 +530,8 @@ STATIC VOID update_dcb(struct dhdr FAR * dhp)
|
|||
dpb->dpb_flags = M_CHANGED;
|
||||
if ((CDSp != 0) && (nblkdev < lastdrive))
|
||||
{
|
||||
CDSp->cds_table[nblkdev].cdsDpb = dpb;
|
||||
CDSp->cds_table[nblkdev].cdsFlags = CDSPHYSDRV;
|
||||
CDSp[nblkdev].cdsDpb = dpb;
|
||||
CDSp[nblkdev].cdsFlags = CDSPHYSDRV;
|
||||
}
|
||||
++dpb;
|
||||
++nblkdev;
|
||||
|
|
|
@ -34,10 +34,6 @@ static BYTE *memmgrRcsId =
|
|||
"$Id$";
|
||||
#endif
|
||||
|
||||
VOID mcb_init();
|
||||
VOID mcb_print();
|
||||
VOID show_chain();
|
||||
|
||||
/*#define nxtMCBsize(mcb,size) \
|
||||
MK_FP(far2para((VOID FAR *) (mcb)) + (size) + 1, 0) */
|
||||
|
||||
|
@ -102,6 +98,11 @@ VOID FAR * add_far(VOID FAR * fp, ULONG off)
|
|||
if (FP_SEG(fp) == 0xffff)
|
||||
return ((BYTE FAR *) fp) + FP_OFF(off);
|
||||
|
||||
#ifndef I86
|
||||
if (FP_SEG(fp) == 0)
|
||||
return ((BYTE FAR *) fp) + FP_OFF(off);
|
||||
#endif
|
||||
|
||||
off += FP_OFF(fp);
|
||||
off2 = ((off >> 16) << 12) + ((UWORD) off >> 4);
|
||||
|
||||
|
@ -111,13 +112,18 @@ VOID FAR * add_far(VOID FAR * fp, ULONG off)
|
|||
/*
|
||||
* Return a normalized far pointer
|
||||
*/
|
||||
VOID FAR * adjust_far(VOID FAR * fp)
|
||||
void FAR * adjust_far(const void FAR * fp)
|
||||
{
|
||||
/* and return an adddress adjusted to the nearest paragraph */
|
||||
/* boundary. */
|
||||
|
||||
if (FP_SEG(fp) == 0xffff)
|
||||
return fp;
|
||||
return (void FAR *)fp;
|
||||
|
||||
#ifndef I86
|
||||
if (FP_SEG(fp) == 0)
|
||||
return (void FAR *)fp;
|
||||
#endif
|
||||
|
||||
return MK_FP(FP_SEG(fp) + (FP_OFF(fp) >> 4), FP_OFF(fp) & 0xf);
|
||||
}
|
||||
|
@ -151,9 +157,13 @@ searchAgain:
|
|||
/*
|
||||
Hack to the Umb Region direct for now. Save time and program space.
|
||||
*/
|
||||
if ((mode != LARGEST) && (mode & (FIRST_FIT_UO | FIRST_FIT_U)) &&
|
||||
uppermem_link && uppermem_root != 0xffff)
|
||||
p = para2far(uppermem_root);
|
||||
if (uppermem_link && uppermem_root != 0xffff)
|
||||
{
|
||||
COUNT tmpmode = (mode == LARGEST ? mem_access_mode : mode);
|
||||
if ((mode != LARGEST || size == 0xffff) &&
|
||||
(tmpmode & (FIRST_FIT_UO | FIRST_FIT_U)))
|
||||
p = para2far(uppermem_root);
|
||||
}
|
||||
|
||||
/* Search through memory blocks */
|
||||
FOREVER
|
||||
|
@ -290,42 +300,6 @@ COUNT DosMemLargest(UWORD FAR * size)
|
|||
*size = 0;
|
||||
DosMemAlloc(0xffff, LARGEST, &dummy, size);
|
||||
return *size ? SUCCESS : DE_NOMEM;
|
||||
|
||||
#if 0
|
||||
REG mcb FAR *p;
|
||||
/* Initialize */
|
||||
p = ((mem_access_mode & (FIRST_FIT_UO | FIRST_FIT_U)) && uppermem_link
|
||||
&& uppermem_root != 0xffff) ? para2far(uppermem_root) : para2far(first_mcb);
|
||||
|
||||
/* Cycle through the whole MCB chain to find the largest unused
|
||||
area. Join all unused areas together. */
|
||||
*size = 0; /* nothing found */
|
||||
FOREVER
|
||||
{
|
||||
if (!mcbValid(p)) /* corrupted MCB chain */
|
||||
return DE_MCBDESTRY;
|
||||
|
||||
if (mcbFree(p))
|
||||
{ /* test if this is the largest block */
|
||||
/* first join this unused block with all following unused
|
||||
blocks */
|
||||
if (joinMCBs(p) != SUCCESS)
|
||||
return DE_MCBDESTRY;
|
||||
|
||||
/* Now test */
|
||||
if (*size < p->m_size)
|
||||
*size = p->m_size;
|
||||
}
|
||||
|
||||
if (p->m_type == MCB_LAST) /* that was last one in chain */
|
||||
break;
|
||||
p = nxtMCB(p);
|
||||
}
|
||||
|
||||
/* If *size is still zero, aka nothing had changed, either no unused
|
||||
block was found at all or a zero-length block only.
|
||||
Both is considered as a failure */
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -128,7 +128,7 @@ COUNT get_verify_drive(char FAR * src)
|
|||
drive = ((src[0] - 1) | 0x20) - ('a' - 1);
|
||||
else
|
||||
return default_drive;
|
||||
if (drive < lastdrive && CDSp->cds_table[drive].cdsFlags & CDSVALID)
|
||||
if (drive < lastdrive && CDSp[drive].cdsFlags & CDSVALID)
|
||||
return drive;
|
||||
else
|
||||
return DE_INVLDDRV;
|
||||
|
@ -246,7 +246,7 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
|
|||
while ((src[0] == '.') && (src[1] == '\\'))
|
||||
src += 2;
|
||||
|
||||
current_ldt = &CDSp->cds_table[i];
|
||||
current_ldt = &CDSp[i];
|
||||
|
||||
/* Always give the redirector a chance to rewrite the filename */
|
||||
fmemcpy(bufp - 1, src, sizeof(buf) - (bufp - buf));
|
||||
|
|
|
@ -228,7 +228,7 @@ COUNT DosDevIOctl(iregs FAR * r);
|
|||
seg far2para(VOID FAR * p);
|
||||
seg long2para(ULONG size);
|
||||
VOID FAR *add_far(VOID FAR * fp, ULONG off);
|
||||
VOID FAR *adjust_far(VOID FAR * fp);
|
||||
void FAR *adjust_far(const void FAR * fp);
|
||||
COUNT DosMemAlloc(UWORD size, COUNT mode, seg FAR * para,
|
||||
UWORD FAR * asize);
|
||||
COUNT DosMemLargest(UWORD FAR * size);
|
||||
|
@ -328,12 +328,10 @@ const UWORD *is_leap_year_monthdays(UWORD year);
|
|||
UWORD DaysFromYearMonthDay(UWORD Year, UWORD Month, UWORD DayOfMonth);
|
||||
|
||||
/* task.c */
|
||||
COUNT ChildEnv(exec_blk FAR * exp, UWORD * pChildEnvSeg,
|
||||
char far * pathname);
|
||||
VOID new_psp(psp FAR * p, int psize);
|
||||
VOID return_user(void);
|
||||
COUNT DosExec(COUNT mode, exec_blk FAR * ep, BYTE FAR * lp);
|
||||
LONG DosGetFsize(COUNT hndl);
|
||||
ULONG DosGetFsize(COUNT hndl);
|
||||
VOID InitPSP(VOID);
|
||||
|
||||
/* newstuff.c */
|
||||
|
|
734
kernel/task.c
734
kernel/task.c
|
@ -42,7 +42,12 @@ static BYTE *RcsId =
|
|||
|
||||
#define LOAD_HIGH 0x80
|
||||
|
||||
static exe_header header;
|
||||
/* static exe_header ExeHeader;
|
||||
to save some bytes, both static and on stack,
|
||||
we recycle SecPathBuffer TE */
|
||||
|
||||
#define ExeHeader (*(exe_header *)(SecPathName + 0))
|
||||
#define TempExeBlock (*(exec_blk *)(SecPathName + sizeof(exe_header)))
|
||||
|
||||
#define CHUNK 32256
|
||||
#define MAXENV 32768u
|
||||
|
@ -53,20 +58,7 @@ static exe_header header;
|
|||
+ 1 byte: '\0'
|
||||
-- 1999/04/21 ska */
|
||||
|
||||
#ifndef PROTO
|
||||
COUNT ChildEnv(exec_blk FAR *, UWORD *, char far *);
|
||||
#else
|
||||
COUNT ChildEnv();
|
||||
#endif
|
||||
|
||||
LONG doslseek(COUNT fd, LONG foffset, COUNT origin)
|
||||
{
|
||||
LONG set_pos;
|
||||
DosSeek(fd, foffset, origin, (ULONG *) & set_pos);
|
||||
return set_pos;
|
||||
}
|
||||
|
||||
LONG DosGetFsize(COUNT hndl)
|
||||
ULONG DosGetFsize(COUNT hndl)
|
||||
{
|
||||
sft FAR *s;
|
||||
/* sfttbl FAR *sp;*/
|
||||
|
@ -89,8 +81,7 @@ LONG DosGetFsize(COUNT hndl)
|
|||
return dos_getfsize(s->sft_status);
|
||||
}
|
||||
|
||||
COUNT ChildEnv(exec_blk FAR * exp, UWORD * pChildEnvSeg,
|
||||
char far * pathname)
|
||||
STATIC COUNT ChildEnv(exec_blk * exp, UWORD * pChildEnvSeg, char far * pathname)
|
||||
{
|
||||
BYTE FAR *pSrc;
|
||||
BYTE FAR *pDest;
|
||||
|
@ -157,10 +148,11 @@ COUNT ChildEnv(exec_blk FAR * exp, UWORD * pChildEnvSeg,
|
|||
pDest += sizeof(UWORD) / sizeof(BYTE);
|
||||
|
||||
/* copy complete pathname */
|
||||
if ((RetCode = truename(pathname, pDest, TRUE)) != SUCCESS)
|
||||
if ((RetCode = truename(pathname, PriPathName, CDS_MODE_SKIP_PHYSICAL)) < SUCCESS)
|
||||
{
|
||||
return RetCode;
|
||||
}
|
||||
fstrcpy(pDest, PriPathName);
|
||||
|
||||
/* Theoretically one could either:
|
||||
+ resize the already allocated block to best-fit behind the pathname, or
|
||||
|
@ -309,194 +301,209 @@ set_name:
|
|||
|
||||
/* return value: AX value to be passed based on FCB values */
|
||||
return ((psp->ps_fcb1.fcb_drive < lastdrive &&
|
||||
CDSp->cds_table[psp->ps_fcb1.fcb_drive].
|
||||
cdsFlags & CDSVALID) ? 0 : 0xff) + ((psp->ps_fcb2.fcb_drive <
|
||||
lastdrive
|
||||
&& CDSp->cds_table[psp->
|
||||
ps_fcb2.
|
||||
fcb_drive].
|
||||
cdsFlags & CDSVALID) ? 0 :
|
||||
0xff) * 0x100;
|
||||
CDSp[psp->ps_fcb1.fcb_drive].cdsFlags & CDSVALID) ? 0 : 0xff) +
|
||||
((psp->ps_fcb2.fcb_drive < lastdrive &&
|
||||
CDSp[psp->ps_fcb2.fcb_drive].cdsFlags & CDSVALID) ? 0 : 0xff) * 0x100;
|
||||
}
|
||||
|
||||
COUNT DosComLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
|
||||
int load_transfer(UWORD ds, exec_blk *exp, UWORD fcbcode, COUNT mode)
|
||||
{
|
||||
COUNT rc
|
||||
/* err */
|
||||
/*,env_size */ ;
|
||||
COUNT nread;
|
||||
UWORD mem;
|
||||
UWORD env, asize;
|
||||
BYTE FAR *sp;
|
||||
psp FAR *p;
|
||||
psp FAR *p = MK_FP(ds, 0);
|
||||
psp FAR *q = MK_FP(cu_psp, 0);
|
||||
iregs FAR *irp;
|
||||
LONG com_size;
|
||||
|
||||
int ModeLoadHigh = mode & 0x80;
|
||||
UBYTE UMBstate = uppermem_link;
|
||||
|
||||
mode &= 0x7f;
|
||||
|
||||
if (mode != OVERLAY)
|
||||
|
||||
/* Transfer control to the executable */
|
||||
p->ps_parent = cu_psp;
|
||||
p->ps_prevpsp = q;
|
||||
q->ps_stack = (BYTE FAR *)user_r;
|
||||
user_r->FLAGS &= ~FLG_CARRY;
|
||||
|
||||
cu_psp = ds;
|
||||
dta = p->ps_dta;
|
||||
|
||||
if (mode == LOADNGO)
|
||||
{
|
||||
iregs FAR *irp;
|
||||
|
||||
/* build the user area on the stack */
|
||||
irp = (iregs FAR *)(exp->exec.stack - sizeof(iregs));
|
||||
|
||||
/* start allocating REGs */
|
||||
irp->ES = irp->DS = ds;
|
||||
irp->CS = FP_SEG(exp->exec.start_addr);
|
||||
irp->IP = FP_OFF(exp->exec.start_addr);
|
||||
irp->AX = fcbcode;
|
||||
irp->BX = irp->CX = irp->DX = irp->SI = irp->DI = irp->BP = 0;
|
||||
irp->FLAGS = 0x200;
|
||||
|
||||
if (InDOS)
|
||||
--InDOS;
|
||||
exec_user(irp);
|
||||
|
||||
/* We should never be here
|
||||
fatal("KERNEL RETURNED!!!"); */
|
||||
}
|
||||
/* mode == LOAD */
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
if ((rc = ChildEnv(exp, &env, namep)) != SUCCESS)
|
||||
/* Now find out how many paragraphs are available
|
||||
considering a threshold, trying HIGH then LOW */
|
||||
STATIC int ExecMemLargest(UWORD *asize, UWORD threshold)
|
||||
{
|
||||
int rc = DosMemLargest(asize);
|
||||
/* less memory than the .COM/.EXE file has:
|
||||
try low memory first */
|
||||
if ((mem_access_mode & 0x80) &&
|
||||
(rc != SUCCESS || *asize < threshold))
|
||||
{
|
||||
mem_access_mode &= ~0x80;
|
||||
rc = DosMemLargest(asize);
|
||||
mem_access_mode |= 0x80;
|
||||
}
|
||||
return (*asize < threshold ? DE_NOMEM : rc);
|
||||
}
|
||||
|
||||
STATIC int ExecMemAlloc(UWORD size, seg *para, UWORD *asize)
|
||||
{
|
||||
/* We can still get an error on first fit if the above */
|
||||
/* returned size was a best fit case */
|
||||
/* ModeLoadHigh = 80 = try high, then low */
|
||||
int rc = DosMemAlloc(size, mem_access_mode, para, asize);
|
||||
|
||||
if (rc != SUCCESS)
|
||||
{
|
||||
if (rc == DE_NOMEM)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* COMFILES will always be loaded in largest area. is that true TE */
|
||||
|
||||
/* Now find out how many paragraphs are available */
|
||||
if ((rc = DosMemLargest((seg FAR *) & asize)) != SUCCESS)
|
||||
{
|
||||
DosMemFree(env);
|
||||
return rc;
|
||||
}
|
||||
com_size = asize;
|
||||
|
||||
if (ModeLoadHigh)
|
||||
{
|
||||
DosUmbLink(1); /* link in UMB's */
|
||||
}
|
||||
|
||||
/* Allocate our memory and pass back any errors */
|
||||
if ((rc =
|
||||
DosMemAlloc((seg) com_size, mem_access_mode, (seg FAR *) & mem,
|
||||
(UWORD FAR *) & asize)) < 0)
|
||||
{
|
||||
if (rc == DE_NOMEM)
|
||||
rc = DosMemAlloc(0, LARGEST, para, asize);
|
||||
if ((mem_access_mode & 0x80) && (rc != SUCCESS))
|
||||
{
|
||||
if ((rc =
|
||||
DosMemAlloc(0, LARGEST, (seg FAR *) & mem,
|
||||
(UWORD FAR *) & asize)) < 0)
|
||||
{
|
||||
DosMemFree(env);
|
||||
return rc;
|
||||
}
|
||||
/* This should never happen, but ... */
|
||||
if (asize < com_size)
|
||||
{
|
||||
DosMemFree(mem);
|
||||
DosMemFree(env);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DosMemFree(env); /* env may be 0 */
|
||||
return rc;
|
||||
mem_access_mode &= ~0x80;
|
||||
rc = DosMemAlloc(0, LARGEST, para, asize);
|
||||
mem_access_mode |= 0x80;
|
||||
}
|
||||
}
|
||||
++mem;
|
||||
}
|
||||
else
|
||||
mem = exp->load.load_seg;
|
||||
|
||||
if (ModeLoadHigh)
|
||||
{
|
||||
DosUmbLink(UMBstate); /* restore link state */
|
||||
/* with no error, we got exactly what we asked for */
|
||||
*asize = size;
|
||||
}
|
||||
|
||||
/* This should never happen, but ... */
|
||||
if (rc == SUCCESS && *asize < size)
|
||||
{
|
||||
DosMemFree(*para);
|
||||
return DE_NOMEM;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
COUNT DosComLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
|
||||
{
|
||||
UWORD mem;
|
||||
UWORD env, asize = 0;
|
||||
|
||||
{
|
||||
UWORD com_size;
|
||||
{
|
||||
ULONG com_size_long = DosGetFsize(fd);
|
||||
/* maximally 64k - 256 bytes stack -
|
||||
256 bytes psp */
|
||||
com_size = (min(com_size_long, 0xfe00u) >> 4) + 0x10;
|
||||
}
|
||||
|
||||
if ((mode & 0x7f) != OVERLAY)
|
||||
{
|
||||
COUNT rc;
|
||||
UBYTE UMBstate = uppermem_link;
|
||||
UBYTE orig_mem_access = mem_access_mode;
|
||||
|
||||
if (mode & 0x80)
|
||||
{
|
||||
mem_access_mode |= 0x80;
|
||||
DosUmbLink(1); /* link in UMB's */
|
||||
}
|
||||
|
||||
rc = ChildEnv(exp, &env, namep);
|
||||
|
||||
/* COMFILES will always be loaded in largest area. is that true TE */
|
||||
/* yes, see RBIL, int21/ah=48 -- Bart */
|
||||
|
||||
if (rc == SUCCESS)
|
||||
rc = ExecMemLargest(&asize, com_size);
|
||||
|
||||
if (rc == SUCCESS)
|
||||
/* Allocate our memory and pass back any errors */
|
||||
rc = ExecMemAlloc(asize, &mem, &asize);
|
||||
|
||||
if (rc != SUCCESS)
|
||||
DosMemFree(env);
|
||||
|
||||
if (mode & 0x80)
|
||||
{
|
||||
DosUmbLink(UMBstate); /* restore link state */
|
||||
mem_access_mode = orig_mem_access;
|
||||
mode &= 0x7f;
|
||||
}
|
||||
|
||||
if (rc != SUCCESS)
|
||||
return rc;
|
||||
|
||||
++mem;
|
||||
}
|
||||
else
|
||||
mem = exp->load.load_seg;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("DosComLoader. Loading '%S' at %04x\n", namep, mem);
|
||||
#endif
|
||||
/* Now load the executable */
|
||||
/* If file not found - error */
|
||||
/* NOTE - this is fatal because we lost it in transit */
|
||||
/* from DosExec! */
|
||||
if ((rc = DosOpen(namep, 0)) < 0)
|
||||
#if 0
|
||||
fatal("(DosComLoader) com file lost in transit")
|
||||
#endif
|
||||
;
|
||||
|
||||
/* do it in 32K chunks */
|
||||
if ((com_size = DosGetFsize(rc)) != 0)
|
||||
{
|
||||
if (mode == OVERLAY) /* memory already allocated */
|
||||
sp = MK_FP(mem, 0);
|
||||
else
|
||||
{ /* test the filesize against the allocated memory */
|
||||
BYTE FAR *sp;
|
||||
ULONG tmp;
|
||||
|
||||
if (mode == OVERLAY) /* memory already allocated */
|
||||
sp = MK_FP(mem, 0);
|
||||
else /* test the filesize against the allocated memory */
|
||||
sp = MK_FP(mem, sizeof(psp));
|
||||
|
||||
/* This is a potential problem, what to do with .COM files larger than
|
||||
the allocated memory?
|
||||
MS DOS always only loads the very first 64KB - sizeof(psp) bytes.
|
||||
-- 1999/04/21 ska */
|
||||
/* MS DOS always only loads the very first 64KB - sizeof(psp) bytes.
|
||||
-- 1999/04/21 ska */
|
||||
|
||||
/* BUG !! in case of LH, memory may be smaller then 64K TE */
|
||||
|
||||
if (com_size > ((LONG) asize << 4)) /* less memory than the .COM file has */
|
||||
com_size = (LONG) asize << 4;
|
||||
}
|
||||
do
|
||||
{
|
||||
nread = DosRead(rc, CHUNK, sp, &UnusedRetVal);
|
||||
sp = add_far((VOID FAR *) sp, (ULONG) nread);
|
||||
}
|
||||
while ((com_size -= nread) > 0 && nread == CHUNK);
|
||||
/* rewind to start */
|
||||
DosSeek(fd, 0, 0, &tmp);
|
||||
/* read everything, but at most 64K - sizeof(PSP) */
|
||||
DosRead(fd, 0xff00, sp, &UnusedRetVal);
|
||||
DosClose(fd);
|
||||
}
|
||||
DosClose(rc);
|
||||
|
||||
if (mode == OVERLAY)
|
||||
return SUCCESS;
|
||||
|
||||
/* point to the PSP so we can build it */
|
||||
p = MK_FP(mem, 0);
|
||||
setvec(0x22, MK_FP(user_r->CS, user_r->IP));
|
||||
new_psp(p, mem + asize);
|
||||
|
||||
asize = patchPSP(mem - 1, env, exp, namep); /* asize=fcbcode for ax */
|
||||
|
||||
/* Transfer control to the executable */
|
||||
p->ps_parent = cu_psp;
|
||||
p->ps_prevpsp = (BYTE FAR *) MK_FP(cu_psp, 0);
|
||||
q->ps_stack = (BYTE FAR *) user_r;
|
||||
user_r->FLAGS &= ~FLG_CARRY;
|
||||
cu_psp = mem;
|
||||
dta = p->ps_dta;
|
||||
|
||||
switch (mode)
|
||||
|
||||
{
|
||||
case LOADNGO:
|
||||
{
|
||||
/* BUG !!
|
||||
this works only, if COMSIZE >= 64K
|
||||
in case of LH, this is not necessarily true
|
||||
*/
|
||||
UWORD fcbcode;
|
||||
|
||||
/* point to the PSP so we can build it */
|
||||
setvec(0x22, MK_FP(user_r->CS, user_r->IP));
|
||||
new_psp(MK_FP(mem, 0), mem + asize);
|
||||
|
||||
fcbcode = patchPSP(mem - 1, env, exp, namep);
|
||||
/* set asize to end of segment */
|
||||
if (asize < 0x1000)
|
||||
asize = (asize << 4) - 2;
|
||||
else
|
||||
asize = 0xfffe;
|
||||
/* TODO: worry about PSP+6:
|
||||
CP/M compatibility--size of first segment for .COM files,
|
||||
while preserving the far call */
|
||||
|
||||
*((UWORD FAR *) MK_FP(mem, 0xfffe)) = (UWORD) 0;
|
||||
|
||||
/* build the user area on the stack */
|
||||
irp = MK_FP(mem, (0xfffe - sizeof(iregs)));
|
||||
|
||||
/* start allocating REGs */
|
||||
irp->ES = irp->DS = mem;
|
||||
irp->CS = mem;
|
||||
irp->IP = 0x100;
|
||||
irp->AX = asize; /* fcbcode */
|
||||
irp->BX = irp->CX = irp->DX = irp->SI = irp->DI = irp->BP = 0;
|
||||
irp->FLAGS = 0x200;
|
||||
|
||||
if (InDOS)
|
||||
--InDOS;
|
||||
exec_user(irp);
|
||||
|
||||
/* We should never be here
|
||||
fatal("KERNEL RETURNED!!!"); */
|
||||
break;
|
||||
}
|
||||
case LOAD:
|
||||
exp->exec.stack = MK_FP(mem, 0xfffe);
|
||||
*((UWORD FAR *) exp->exec.stack) = asize;
|
||||
exp->exec.start_addr = MK_FP(mem, 0x100);
|
||||
return SUCCESS;
|
||||
exp->exec.stack = MK_FP(mem, asize);
|
||||
exp->exec.start_addr = MK_FP(mem, 0x100);
|
||||
*((UWORD FAR *) MK_FP(mem, asize)) = (UWORD) 0;
|
||||
load_transfer(mem, exp, fcbcode, mode);
|
||||
}
|
||||
|
||||
return DE_INVLDFMT;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
VOID return_user(void)
|
||||
|
@ -542,191 +549,105 @@ VOID return_user(void)
|
|||
exec_user((iregs FAR *) q->ps_stack);
|
||||
}
|
||||
|
||||
COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
|
||||
COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
|
||||
{
|
||||
COUNT rc;
|
||||
/*err, */
|
||||
/*env_size, */
|
||||
|
||||
UWORD mem, env, asize, start_seg;
|
||||
|
||||
int ModeLoadHigh = mode & 0x80;
|
||||
UBYTE UMBstate = uppermem_link;
|
||||
|
||||
mode &= 0x7f;
|
||||
|
||||
/* Clone the environement and create a memory arena */
|
||||
if (mode != OVERLAY)
|
||||
{
|
||||
if ((rc = ChildEnv(exp, &env, namep)) != SUCCESS)
|
||||
return rc;
|
||||
}
|
||||
else
|
||||
mem = exp->load.load_seg;
|
||||
|
||||
UWORD mem, env, start_seg, asize = 0;
|
||||
ULONG exe_size, tmp;
|
||||
{
|
||||
ULONG image_size;
|
||||
ULONG image_offset;
|
||||
LONG exe_size;
|
||||
mcb FAR *mp;
|
||||
|
||||
/* compute image offset from the header */
|
||||
image_offset = (ULONG) header.exHeaderSize * 16;
|
||||
|
||||
/* compute image offset from the ExeHeader */
|
||||
image_offset = (ULONG) ExeHeader.exHeaderSize * 16;
|
||||
|
||||
/* compute image size by removing the offset from the */
|
||||
/* number pages scaled to bytes plus the remainder and */
|
||||
/* the psp */
|
||||
/* First scale the size */
|
||||
image_size = (ULONG) header.exPages * 512;
|
||||
image_size = (ULONG) ExeHeader.exPages * 512;
|
||||
/* remove the offset */
|
||||
image_size -= image_offset;
|
||||
|
||||
/* and finally add in the psp size */
|
||||
if (mode != OVERLAY)
|
||||
image_size += sizeof(psp); /*TE 03/20/01 */
|
||||
|
||||
if (mode != OVERLAY)
|
||||
|
||||
/* We should not attempt to allocate
|
||||
memory if we are overlaying the current process, because the new
|
||||
process will simply re-use the block we already have allocated.
|
||||
Jun 11, 2000 - rbc */
|
||||
|
||||
if ((mode & 0x7f) != OVERLAY)
|
||||
{
|
||||
if (ModeLoadHigh)
|
||||
UBYTE UMBstate = uppermem_link;
|
||||
UBYTE orig_mem_access = mem_access_mode;
|
||||
COUNT rc;
|
||||
|
||||
/* and finally add in the psp size */
|
||||
image_size += sizeof(psp); /*TE 03/20/01 */
|
||||
exe_size = (ULONG) long2para(image_size) + ExeHeader.exMinAlloc;
|
||||
|
||||
/* Clone the environement and create a memory arena */
|
||||
if ((mode & 0x7f) != OVERLAY && (mode & 0x80))
|
||||
{
|
||||
DosUmbLink(1); /* link in UMB's */
|
||||
mem_access_mode |= ModeLoadHigh;
|
||||
}
|
||||
|
||||
/* Now find out how many paragraphs are available */
|
||||
if ((rc = DosMemLargest((seg FAR *) & asize)) != SUCCESS)
|
||||
{
|
||||
DosMemFree(env);
|
||||
return rc;
|
||||
}
|
||||
|
||||
exe_size = (LONG) long2para(image_size) + header.exMinAlloc;
|
||||
|
||||
/* + long2para((LONG) sizeof(psp)); ?? see above
|
||||
image_size += sizeof(psp) -- 1999/04/21 ska */
|
||||
if (exe_size > asize && (mem_access_mode & 0x80))
|
||||
{
|
||||
/* First try low memory */
|
||||
mem_access_mode &= ~0x80;
|
||||
rc = DosMemLargest((seg FAR *) & asize);
|
||||
mem_access_mode |= 0x80;
|
||||
if (rc != SUCCESS)
|
||||
{
|
||||
DosMemFree(env);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
if (exe_size > asize)
|
||||
{
|
||||
DosMemFree(env);
|
||||
return DE_NOMEM;
|
||||
}
|
||||
exe_size = (LONG) long2para(image_size) + header.exMaxAlloc;
|
||||
/* + long2para((LONG) sizeof(psp)); ?? -- 1999/04/21 ska */
|
||||
|
||||
rc = ChildEnv(exp, &env, namep);
|
||||
|
||||
if (rc == SUCCESS)
|
||||
/* Now find out how many paragraphs are available */
|
||||
rc = ExecMemLargest(&asize, (UWORD)exe_size);
|
||||
|
||||
exe_size = (ULONG) long2para(image_size) + ExeHeader.exMaxAlloc;
|
||||
if (exe_size > asize)
|
||||
exe_size = asize;
|
||||
|
||||
/* TE if header.exMinAlloc == header.exMaxAlloc == 0,
|
||||
|
||||
/* TE if ExeHeader.exMinAlloc == ExeHeader.exMaxAlloc == 0,
|
||||
DOS will allocate the largest possible memory area
|
||||
and load the image as high as possible into it.
|
||||
discovered (and after that found in RBIL), when testing NET */
|
||||
|
||||
if ((header.exMinAlloc | header.exMaxAlloc) == 0)
|
||||
|
||||
if ((ExeHeader.exMinAlloc | ExeHeader.exMaxAlloc) == 0)
|
||||
exe_size = asize;
|
||||
|
||||
/* /// Removed closing curly brace. We should not attempt to allocate
|
||||
memory if we are overlaying the current process, because the new
|
||||
process will simply re-use the block we already have allocated.
|
||||
This was causing execl() to fail in applications which use it to
|
||||
overlay (replace) the current exe file with a new one.
|
||||
Jun 11, 2000 - rbc
|
||||
} */
|
||||
|
||||
|
||||
/* Allocate our memory and pass back any errors */
|
||||
/* We can still get an error on first fit if the above */
|
||||
/* returned size was a bet fit case */
|
||||
/* ModeLoadHigh = 80 = try high, then low */
|
||||
if ((rc =
|
||||
DosMemAlloc((seg) exe_size, mem_access_mode | ModeLoadHigh,
|
||||
(seg FAR *) & mem, (UWORD FAR *) & asize)) < 0)
|
||||
if (rc == SUCCESS)
|
||||
rc = ExecMemAlloc((UWORD)exe_size, &mem, &asize);
|
||||
|
||||
if (rc != SUCCESS)
|
||||
DosMemFree(env);
|
||||
|
||||
if (mode & 0x80)
|
||||
{
|
||||
if (rc == DE_NOMEM)
|
||||
{
|
||||
if ((rc =
|
||||
DosMemAlloc(0, LARGEST, (seg FAR *) & mem,
|
||||
(UWORD FAR *) & asize)) < 0)
|
||||
{
|
||||
DosMemFree(env);
|
||||
return rc;
|
||||
}
|
||||
/* This should never happen, but ... */
|
||||
if (asize < exe_size)
|
||||
{
|
||||
DosMemFree(mem);
|
||||
DosMemFree(env);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DosMemFree(env);
|
||||
return rc;
|
||||
}
|
||||
mem_access_mode = orig_mem_access; /* restore old situation */
|
||||
DosUmbLink(UMBstate); /* restore link state */
|
||||
}
|
||||
else
|
||||
/* with no error, we got exactly what we asked for */
|
||||
asize = exe_size;
|
||||
|
||||
if (rc != SUCCESS)
|
||||
return rc;
|
||||
|
||||
mode &= 0x7f; /* forget about high loading from now on */
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("DosExeLoader. Loading '%S' at %04x\n", namep, mem);
|
||||
#endif
|
||||
|
||||
/* /// Added open curly brace and "else" clause. We should not attempt
|
||||
to allocate memory if we are overlaying the current process, because
|
||||
the new process will simply re-use the block we already have allocated.
|
||||
This was causing execl() to fail in applications which use it to
|
||||
overlay (replace) the current exe file with a new one.
|
||||
Jun 11, 2000 - rbc */
|
||||
}
|
||||
else
|
||||
asize = exe_size;
|
||||
/* /// End of additions. Jun 11, 2000 - rbc */
|
||||
|
||||
if (ModeLoadHigh)
|
||||
{
|
||||
mem_access_mode &= ~ModeLoadHigh; /* restore old situation */
|
||||
DosUmbLink(UMBstate); /* restore link state */
|
||||
}
|
||||
|
||||
if (mode != OVERLAY)
|
||||
{
|
||||
|
||||
/* memory found large enough - continue processing */
|
||||
mp = MK_FP(mem, 0);
|
||||
++mem;
|
||||
|
||||
/* /// Added open curly brace and "else" clause. We should not attempt
|
||||
to allocate memory if we are overlaying the current process, because
|
||||
the new process will simply re-use the block we already have allocated.
|
||||
This was causing execl() to fail in applications which use it to
|
||||
overlay (replace) the current exe file with a new one.
|
||||
Jun 11, 2000 - rbc */
|
||||
}
|
||||
else
|
||||
mem = exp->load.load_seg;
|
||||
|
||||
/* create the start seg for later computations */
|
||||
if (mode == OVERLAY)
|
||||
start_seg = mem;
|
||||
else
|
||||
else /* !!OVERLAY */
|
||||
{
|
||||
start_seg = mem + long2para((LONG) sizeof(psp));
|
||||
mem = exp->load.load_seg;
|
||||
}
|
||||
|
||||
/* Now load the executable */
|
||||
/* If file not found - error */
|
||||
/* NOTE - this is fatal because we lost it in transit */
|
||||
/* from DosExec! */
|
||||
if ((rc = DosOpen(namep, 0)) < 0)
|
||||
{
|
||||
#if 0
|
||||
fatal("(DosExeLoader) exe file lost in transit");
|
||||
#endif
|
||||
}
|
||||
/* offset to start of image */
|
||||
if (doslseek(rc, image_offset, 0) != image_offset)
|
||||
DosSeek(fd, image_offset, 0, &tmp);
|
||||
if (tmp != image_offset)
|
||||
{
|
||||
if (mode != OVERLAY)
|
||||
{
|
||||
|
@ -735,41 +656,39 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
|
|||
}
|
||||
return DE_INVLDDATA;
|
||||
}
|
||||
|
||||
/* read in the image in 32K chunks */
|
||||
|
||||
/* create the start seg for later computations */
|
||||
start_seg = mem;
|
||||
exe_size = image_size;
|
||||
if (mode != OVERLAY)
|
||||
{
|
||||
exe_size = image_size - sizeof(psp);
|
||||
exe_size -= sizeof(psp);
|
||||
start_seg += long2para(sizeof(psp));
|
||||
if (exe_size > 0 && (ExeHeader.exMinAlloc == 0) && (ExeHeader.exMaxAlloc == 0))
|
||||
{
|
||||
mcb FAR *mp = MK_FP(mem - 1, 0);
|
||||
|
||||
/* then the image should be placed as high as possible */
|
||||
start_seg = start_seg + mp->m_size - (image_size + 15) / 16;
|
||||
}
|
||||
}
|
||||
else
|
||||
exe_size = image_size;
|
||||
}
|
||||
|
||||
if (exe_size > 0)
|
||||
/* read in the image in 32K chunks */
|
||||
{
|
||||
UCOUNT nBytesRead;
|
||||
BYTE FAR *sp = MK_FP(start_seg, 0x0);
|
||||
|
||||
while (exe_size > 0)
|
||||
{
|
||||
UCOUNT nBytesRead;
|
||||
BYTE FAR *sp;
|
||||
|
||||
if (mode != OVERLAY)
|
||||
{
|
||||
if ((header.exMinAlloc == 0) && (header.exMaxAlloc == 0))
|
||||
{
|
||||
/* then the image should be placed as high as possible */
|
||||
start_seg = start_seg + mp->m_size - (image_size + 15) / 16;
|
||||
}
|
||||
}
|
||||
|
||||
sp = MK_FP(start_seg, 0x0);
|
||||
|
||||
do
|
||||
{
|
||||
nBytesRead =
|
||||
DosRead((COUNT) rc,
|
||||
(COUNT) (exe_size < CHUNK ? exe_size : CHUNK),
|
||||
(VOID FAR *) sp, &UnusedRetVal);
|
||||
sp = add_far((VOID FAR *) sp, (ULONG) nBytesRead);
|
||||
exe_size -= nBytesRead;
|
||||
}
|
||||
while (nBytesRead && exe_size > 0);
|
||||
nBytesRead =
|
||||
DosRead(fd,
|
||||
(COUNT) (exe_size < CHUNK ? exe_size : CHUNK),
|
||||
(VOID FAR *) sp, &UnusedRetVal);
|
||||
if (nBytesRead == 0)
|
||||
break;
|
||||
sp = add_far((VOID FAR *) sp, nBytesRead);
|
||||
exe_size -= nBytesRead;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -777,12 +696,13 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
|
|||
COUNT i;
|
||||
UWORD reloc[2];
|
||||
seg FAR *spot;
|
||||
ULONG tmp;
|
||||
|
||||
doslseek(rc, (LONG) header.exRelocTable, 0);
|
||||
for (i = 0; i < header.exRelocItems; i++)
|
||||
DosSeek(fd, ExeHeader.exRelocTable, 0, &tmp);
|
||||
for (i = 0; i < ExeHeader.exRelocItems; i++)
|
||||
{
|
||||
if (DosRead
|
||||
(rc, sizeof(reloc), (VOID FAR *) & reloc[0],
|
||||
(fd, sizeof(reloc), (VOID FAR *) & reloc[0],
|
||||
&UnusedRetVal) != sizeof(reloc))
|
||||
{
|
||||
return DE_INVLDDATA;
|
||||
|
@ -802,69 +722,29 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
|
|||
}
|
||||
|
||||
/* and finally close the file */
|
||||
DosClose(rc);
|
||||
DosClose(fd);
|
||||
|
||||
/* exit here for overlay */
|
||||
if (mode == OVERLAY)
|
||||
return SUCCESS;
|
||||
|
||||
{
|
||||
psp FAR *p;
|
||||
psp FAR *q = MK_FP(cu_psp, 0);
|
||||
UWORD fcbcode;
|
||||
|
||||
/* point to the PSP so we can build it */
|
||||
p = MK_FP(mem, 0);
|
||||
setvec(0x22, MK_FP(user_r->CS, user_r->IP));
|
||||
new_psp(p, mem + asize);
|
||||
new_psp(MK_FP(mem, 0), mem + asize);
|
||||
|
||||
asize = patchPSP(mem - 1, env, exp, namep); /* asize = fcbcode */
|
||||
fcbcode = patchPSP(mem - 1, env, exp, namep);
|
||||
exp->exec.stack =
|
||||
MK_FP(ExeHeader.exInitSS + start_seg, ExeHeader.exInitSP);
|
||||
exp->exec.start_addr =
|
||||
MK_FP(ExeHeader.exInitCS + start_seg, ExeHeader.exInitIP);
|
||||
|
||||
/* Transfer control to the executable */
|
||||
p->ps_parent = cu_psp;
|
||||
p->ps_prevpsp = (BYTE FAR *) MK_FP(cu_psp, 0);
|
||||
q->ps_stack = (BYTE FAR *) user_r;
|
||||
user_r->FLAGS &= ~FLG_CARRY;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case LOADNGO:
|
||||
{
|
||||
/* build the user area on the stack */
|
||||
iregs FAR *irp = MK_FP(header.exInitSS + start_seg,
|
||||
((header.exInitSP -
|
||||
sizeof(iregs)) & 0xffff));
|
||||
|
||||
/* start allocating REGs */
|
||||
/* Note: must match es & ds memory segment */
|
||||
irp->ES = irp->DS = mem;
|
||||
irp->CS = header.exInitCS + start_seg;
|
||||
irp->IP = header.exInitIP;
|
||||
irp->AX = asize; /* asize = fcbcode */
|
||||
irp->BX = irp->CX = irp->DX = irp->SI = irp->DI = irp->BP = 0;
|
||||
irp->FLAGS = 0x200;
|
||||
|
||||
cu_psp = mem;
|
||||
dta = p->ps_dta;
|
||||
|
||||
if (InDOS)
|
||||
--InDOS;
|
||||
exec_user(irp);
|
||||
/* We should never be here
|
||||
fatal("KERNEL RETURNED!!!"); */
|
||||
break;
|
||||
}
|
||||
|
||||
case LOAD:
|
||||
cu_psp = mem;
|
||||
exp->exec.stack =
|
||||
MK_FP(header.exInitSS + start_seg, header.exInitSP);
|
||||
*((UWORD FAR *) exp->exec.stack) = asize; /* fcbcode */
|
||||
exp->exec.start_addr =
|
||||
MK_FP(header.exInitCS + start_seg, header.exInitIP);
|
||||
return SUCCESS;
|
||||
}
|
||||
load_transfer(mem, exp, fcbcode, mode);
|
||||
}
|
||||
return DE_INVLDFMT;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* mode = LOAD or EXECUTE
|
||||
|
@ -876,36 +756,40 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk FAR * exp, COUNT mode)
|
|||
COUNT DosExec(COUNT mode, exec_blk FAR * ep, BYTE FAR * lp)
|
||||
{
|
||||
COUNT rc;
|
||||
exec_blk leb;
|
||||
COUNT fd;
|
||||
|
||||
/* BYTE FAR *cp;*/
|
||||
BOOL bIsCom = FALSE;
|
||||
if ((mode & 0x7f) > 3 || (mode & 0x7f) == 2)
|
||||
return DE_INVLDFMT;
|
||||
|
||||
fmemcpy(&leb, ep, sizeof(exec_blk));
|
||||
fmemcpy(&TempExeBlock, ep, sizeof(exec_blk));
|
||||
/* If file not found - free ram and return error */
|
||||
|
||||
if ((rc = DosOpen(lp, 0)) < 0)
|
||||
if (IsDevice(lp) || /* we don't want to execute C:>NUL */
|
||||
#if 0
|
||||
(fd = (short)DosOpen(lp, O_LEGACY | O_OPEN | O_RDONLY, 0)) < 0)
|
||||
#else
|
||||
(fd = (short)DosOpen(lp, 0)) < 0)
|
||||
#endif
|
||||
{
|
||||
return DE_FILENOTFND;
|
||||
}
|
||||
|
||||
rc = DosRead(fd, sizeof(exe_header), (BYTE FAR *)&ExeHeader, &UnusedRetVal);
|
||||
|
||||
if (DosRead(rc, sizeof(exe_header), (VOID FAR *) & header, &UnusedRetVal)
|
||||
!= sizeof(exe_header))
|
||||
if (rc == sizeof(exe_header) &&
|
||||
(ExeHeader.exSignature == MAGIC || ExeHeader.exSignature == OLD_MAGIC))
|
||||
{
|
||||
bIsCom = TRUE;
|
||||
rc = DosExeLoader(lp, &TempExeBlock, mode, fd);
|
||||
}
|
||||
else if (rc != 0)
|
||||
{
|
||||
rc = DosComLoader(lp, &TempExeBlock, mode, fd);
|
||||
}
|
||||
DosClose(rc);
|
||||
|
||||
if (bIsCom || header.exSignature != MAGIC)
|
||||
{
|
||||
rc = DosComLoader(lp, &leb, mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = DosExeLoader(lp, &leb, mode);
|
||||
}
|
||||
DosClose(fd);
|
||||
|
||||
if (mode == LOAD && rc == SUCCESS)
|
||||
fmemcpy(ep, &leb, sizeof(exec_blk));
|
||||
fmemcpy(ep, &TempExeBlock, sizeof(exec_blk));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue