Last changes for kernel 2027 test.

git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@414 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
Bart Oldeman 2002-08-04 01:14:18 +00:00
parent 511bf63d16
commit dfeb595f8e
26 changed files with 2515 additions and 3175 deletions

View File

@ -14,6 +14,8 @@ James Tabor (jimtabor@infohwy.com)
Eric Biederman (ebiederm+eric@ccr.net)
Tom Ehlert (tom.ehlert@ginko.de)
Victor Vlasenko (victor_vlasenko@hotbox.ru)
Jeremy Davis (jeremyd@computer.org)
Martin Stromberg (ams@ludd.luth.se)
Bart Oldeman (bart@dosemu.org)
And last, but not least, a big thanx to Pasquale J. Villani

View File

@ -1,7 +1,7 @@
Begin3
Title: The FreeDOS Kernel
Version: 2.0.25.c
Entered-date: 17 Nov 2001
Version: 2.0.27
Entered-date: xx Aug 2002
Description: The FreeDOS Kernel.
Keywords: kernel freedos dos msdos
Author: (developers)

View File

@ -9,10 +9,31 @@
* 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
* removed unnecessary "BUFFERS" fields
* proper check for network/non-existing drive for int25/26.
* save more bytes on the stack at various places
* made the local registers for inthndlr.c "near" instead of "far".
* fix bug in strchr handling for fcbfns.c (FcbParseFname)
+ Changes Steffen (but changed a lot by Bart)
* new truename (Bart: but without mapPath() style struct)
* merge open/create functions into one extended open function
* also honor the sharing bits better for "open"
* use local 8+3 path names in fatfs.c; merge name+extension
into one array
* take care of filenames that start with ASCII 5: they should be
treated as starting with 0xe5
* exploit the fact that the filenames are already "truenames",
i.e., fully qualified in fatfs.c. This simplifies parsing a lot.
+ Changes Bart
* make "if exist c:\dir\nul" working
* honor "do not inherit handle on exec" flag for "open".
* improve the FCB functions so that they set the critical error code
properly
* next_cluster returns "1" instead of DE_xxx in case of failure.
* create one function to do binary character IO (used for CLOCK$
driver and character drivers such as CON)
* better handling of ABORT/FAIL
* merge all read and write functions
* patchobj makefile correction
* printf uses va_list etc.
* quicker and more robust Watcom build
@ -33,7 +54,6 @@
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

View File

@ -54,7 +54,8 @@ static BYTE *fat_hRcsId =
#define FEXT_SIZE 3
/* FAT deleted flag */
#define DELETED 0xe5 /* if first char, delete file */
#define DELETED '\x5' /* if first char, delete file */
#define EXT_DELETED '\xe5' /* external deleted flag */
/* FAT cluster to physical conversion macros */
#define clus_add(cl_no) ((ULONG) (((ULONG) cl_no - 2L) \
@ -81,8 +82,7 @@ static BYTE *fat_hRcsId =
/* FAT file system directory entry */
struct dirent {
UBYTE dir_name[FNAME_SIZE]; /* Filename */
UBYTE dir_ext[FEXT_SIZE]; /* Filename extension */
char dir_name[FNAME_SIZE + FEXT_SIZE]; /* Filename + extension in FCB format */
UBYTE dir_attrib; /* File Attribute */
UBYTE dir_case; /* File case */
UBYTE dir_crtimems; /* Milliseconds */

View File

@ -106,7 +106,7 @@ typedef struct _sfttbl {
#define SFT_MRDWR 0x0002 /* read/write bit */
#define SFT_MWRITE 0x0001 /* write bit */
#define SFT_MREAD 0x0000 /* ~ write bit */
#define SFT_OMASK 0x00f3 /* valid open mask */
#define SFT_OMASK 0xfff3 /* valid open mask */
/* flag bits */

View File

@ -117,13 +117,15 @@ irp_hi equ 26
; later
;
; assumption:
; we have never seen MSVC (our only I386 compiler) to use
; anything but eax,ecx, edx
; we have never seen MSVC to use anything but eax,ecx, edx
; so we only protect eax, ebx, ecx, edx to conserve stack space
;
; to save even more stack space, we save only HIGH part of regs
; at some expense of slower execution. it's easier anyway :-)
;
; WATCOM only uses FS: and GS: (using -zff and -zgf) and never
; any high part of the 386 registers
;
%IFNDEF I386
@ -141,6 +143,9 @@ irp_hi equ 26
%macro Protect386Registers 0
%ifdef WATCOM
push fs
push gs
%else
ror eax,16
push ax
ror eax,16
@ -153,9 +158,6 @@ irp_hi equ 26
ror edx,16
push dx
ror edx,16
%else
push fs
push gs
%endif
%endmacro
@ -163,6 +165,9 @@ irp_hi equ 26
%macro Restore386Registers 0
%ifdef WATCOM
pop gs
pop fs
%else
ror edx,16
pop dx
ror edx,16
@ -175,9 +180,6 @@ irp_hi equ 26
ror eax,16
pop ax
ror eax,16
%else
pop gs
pop fs
%endif
%endmacro

View File

@ -65,6 +65,40 @@ struct dhdr FAR *finddev(UWORD attr_mask)
}
#endif
UCOUNT BinaryCharIO(struct dhdr FAR * dev, UCOUNT n, void FAR * bp, unsigned command, COUNT *err)
{
*err = SUCCESS;
FOREVER
{
CharReqHdr.r_length = sizeof(request);
CharReqHdr.r_command = command;
CharReqHdr.r_count = n;
CharReqHdr.r_trans = bp;
CharReqHdr.r_status = 0;
execrh(&CharReqHdr, dev);
if (CharReqHdr.r_status & S_ERROR)
{
charloop:
switch (char_error(&CharReqHdr, dev))
{
case ABORT:
case FAIL:
*err = DE_INVLDACC;
return 0;
case CONTINUE:
break;
case RETRY:
continue;
default:
goto charloop;
}
}
break;
}
return CharReqHdr.r_count;
}
VOID _cso(COUNT c)
{
if (syscon->dh_attr & ATTR_FASTCON)
@ -72,7 +106,7 @@ VOID _cso(COUNT c)
#if defined(__TURBOC__)
_AL = c;
__int__(0x29);
#else
#elif defined(I86)
asm
{
mov al, byte ptr c;
@ -81,14 +115,7 @@ VOID _cso(COUNT c)
#endif
return;
}
CharReqHdr.r_length = sizeof(request);
CharReqHdr.r_command = C_OUTPUT;
CharReqHdr.r_count = 1;
CharReqHdr.r_trans = (BYTE FAR *) (&c);
CharReqHdr.r_status = 0;
execrh((request FAR *) & CharReqHdr, syscon);
if (CharReqHdr.r_status & S_ERROR)
char_error(&CharReqHdr, syscon);
BinaryCharIO(syscon, 1, &c, C_OUTPUT, &UnusedRetVal);
}
VOID cso(COUNT c)
@ -97,7 +124,7 @@ VOID cso(COUNT c)
con_hold();
if (PrinterEcho)
DosWrite(STDPRN, 1, (BYTE FAR *) & c, (COUNT FAR *) & UnusedRetVal);
DosWrite(STDPRN, 1, (BYTE FAR *) & c, & UnusedRetVal);
switch (c)
{
@ -125,7 +152,7 @@ VOID cso(COUNT c)
VOID sto(COUNT c)
{
DosWrite(STDOUT, 1, (BYTE FAR *) & c, (COUNT FAR *) & UnusedRetVal);
DosWrite(STDOUT, 1, (BYTE FAR *) & c, & UnusedRetVal);
}
VOID mod_cso(REG UCOUNT c)
@ -176,14 +203,7 @@ COUNT con_read(void)
{
BYTE c;
CharReqHdr.r_length = sizeof(request);
CharReqHdr.r_command = C_INPUT;
CharReqHdr.r_count = 1;
CharReqHdr.r_trans = (BYTE FAR *) & c;
CharReqHdr.r_status = 0;
execrh((request FAR *) & CharReqHdr, syscon);
if (CharReqHdr.r_status & S_ERROR)
char_error(&CharReqHdr, syscon);
BinaryCharIO(syscon, 1, &c, C_INPUT, &UnusedRetVal);
if (c == CTL_C)
handle_break();
return c;
@ -216,9 +236,8 @@ UCOUNT _sti(BOOL check_break)
Do_DosIdle_loop();
if (check_break)
con_hold();
while (GenericRead
(STDIN, 1, (BYTE FAR *) & c, (COUNT FAR *) & UnusedRetVal,
TRUE) != 1) ;
while (BinaryRead(STDIN, &c, & UnusedRetVal) != 1)
;
return c;
}

File diff suppressed because it is too large Load Diff

View File

@ -41,9 +41,12 @@ const char _DirWildNameChars[] = "*?./\\\"[]:|<>+=;,";
#define PathSep(c) ((c)=='/'||(c)=='\\')
#define DriveChar(c) (((c)>='A'&&(c)<='Z')||((c)>='a'&&(c)<='z'))
#define DirChar(c) (!strchr(_DirWildNameChars+5, (c)))
#define WildChar(c) (!strchr(_DirWildNameChars+2, (c)))
#define NameChar(c) (!strchr(_DirWildNameChars, (c)))
#define DirChar(c) (((unsigned char)(c)) >= ' ' && \
!strchr(_DirWildNameChars+5, (c)))
#define WildChar(c) (((unsigned char)(c)) >= ' ' && \
!strchr(_DirWildNameChars+2, (c)))
#define NameChar(c) (((unsigned char)(c)) >= ' ' && \
!strchr(_DirWildNameChars, (c)))
VOID XlateLcase(BYTE * szFname, COUNT nChars);
VOID DosTrimPath(BYTE * lpszPathNamep);
@ -61,14 +64,6 @@ VOID XlateLcase(BYTE * szFname, COUNT nChars)
}
#endif
VOID SpacePad(BYTE * szString, COUNT nChars)
{
REG COUNT i;
for (i = strlen(szString); i < nChars; i++)
szString[i] = ' ';
}
/*
MSD durring an FindFirst search string looks like this;
(*), & (.) == Current directory *.*
@ -76,90 +71,73 @@ VOID SpacePad(BYTE * szString, COUNT nChars)
(..) == Back one directory *.*
This always has a "truename" as input, so we may do some shortcuts
returns number of characters in the directory component (up to the
last backslash, including d:) or negative if error
*/
COUNT ParseDosName(BYTE * lpszFileName,
COUNT * pnDrive,
BYTE * pszDir,
BYTE * pszFile, BYTE * pszExt, BOOL bAllowWildcards)
int ParseDosName(const char *filename, char *fcbname, BOOL bAllowWildcards)
{
COUNT nDirCnt, nFileCnt, nExtCnt;
BYTE *lpszLclDir, *lpszLclFile, *lpszLclExt;
int nDirCnt, nFileCnt, nExtCnt;
const char *lpszLclDir, *lpszLclFile, *lpszLclExt;
/* Initialize the users data fields */
if (pszDir)
*pszDir = '\0';
if (pszFile)
*pszFile = '\0';
if (pszExt)
*pszExt = '\0';
lpszLclFile = lpszLclExt = lpszLclDir = 0;
nDirCnt = nFileCnt = nExtCnt = 0;
/* found a drive, fetch it and bump pointer past drive */
/* NB: this code assumes ASCII */
if (pnDrive)
*pnDrive = *lpszFileName - 'A';
lpszFileName += 2;
if (!pszDir && !pszFile && !pszExt)
return SUCCESS;
/* Now see how long a directory component we have. */
lpszLclDir = lpszLclFile = lpszFileName;
while (DirChar(*lpszFileName))
lpszLclDir = lpszLclFile = filename;
filename += 2;
while (DirChar(*filename))
{
if (*lpszFileName == '\\')
lpszLclFile = lpszFileName + 1;
++lpszFileName;
if (*filename == '\\')
lpszLclFile = filename + 1;
++filename;
}
nDirCnt = FP_OFF(lpszLclFile) - FP_OFF(lpszLclDir);
nDirCnt = lpszLclFile - lpszLclDir;
/* Fix lengths to maximums allowed by MS-DOS. */
if (nDirCnt > PARSE_MAX - 1)
nDirCnt = PARSE_MAX - 1;
/* Parse out the file name portion. */
lpszFileName = lpszLclFile;
while (bAllowWildcards ? WildChar(*lpszFileName) :
NameChar(*lpszFileName))
filename = lpszLclFile;
while (bAllowWildcards ? WildChar(*filename) :
NameChar(*filename))
{
++nFileCnt;
++lpszFileName;
++filename;
}
if (nFileCnt == 0)
{
/* Lixing Yuan Patch */
if (bAllowWildcards) /* for find first */
{
if (*lpszFileName != '\0')
if (*filename != '\0')
return DE_FILENOTFND;
if (nDirCnt == 1) /* for d:\ */
return DE_NFILES;
if (pszDir)
{
memcpy(pszDir, lpszLclDir, nDirCnt);
pszDir[nDirCnt] = '\0';
}
if (pszFile)
memcpy(pszFile, "????????", FNAME_SIZE + 1);
if (pszExt)
memcpy(pszExt, "???", FEXT_SIZE + 1);
return SUCCESS;
memset(fcbname, '?', FNAME_SIZE + FEXT_SIZE);
return nDirCnt;
}
else
return DE_FILENOTFND;
}
/* Now we have pointers set to the directory portion and the */
/* file portion. Now determine the existance of an extension. */
lpszLclExt = lpszFileName;
if ('.' == *lpszFileName)
lpszLclExt = filename;
if ('.' == *filename)
{
lpszLclExt = ++lpszFileName;
while (*lpszFileName)
lpszLclExt = ++filename;
while (*filename)
{
if (bAllowWildcards ? WildChar(*lpszFileName) :
NameChar(*lpszFileName))
if (bAllowWildcards ? WildChar(*filename) :
NameChar(*filename))
{
++nExtCnt;
++lpszFileName;
++filename;
}
else
{
@ -167,225 +145,20 @@ COUNT ParseDosName(BYTE * lpszFileName,
}
}
}
else if (*lpszFileName)
else if (*filename)
return DE_FILENOTFND;
/* Finally copy whatever the user wants extracted to the user's */
/* buffers. */
if (pszDir)
{
memcpy(pszDir, lpszLclDir, nDirCnt);
pszDir[nDirCnt] = '\0';
}
if (pszFile)
{
memcpy(pszFile, lpszLclFile, nFileCnt);
pszFile[nFileCnt] = '\0';
}
if (pszExt)
{
memcpy(pszExt, lpszLclExt, nExtCnt);
pszExt[nExtCnt] = '\0';
}
memset(fcbname, ' ', FNAME_SIZE + FEXT_SIZE);
memcpy(fcbname, lpszLclFile, nFileCnt);
memcpy(&fcbname[FNAME_SIZE], lpszLclExt, nExtCnt);
/* Clean up before leaving */
return SUCCESS;
return nDirCnt;
}
#if 0
/* not necessary anymore because of truename */
COUNT ParseDosPath(BYTE * lpszFileName,
COUNT * pnDrive, BYTE * pszDir, BYTE * pszCurPath)
{
COUNT nDirCnt, nPathCnt;
BYTE *lpszLclDir, *pszBase = pszDir;
/* Initialize the users data fields */
*pszDir = '\0';
lpszLclDir = 0;
nDirCnt = nPathCnt = 0;
/* Start by cheking for a drive specifier ... */
if (DriveChar(*lpszFileName) && ':' == lpszFileName[1])
{
/* found a drive, fetch it and bump pointer past drive */
/* NB: this code assumes ASCII */
if (pnDrive)
{
*pnDrive = *lpszFileName - 'A';
if (*pnDrive > 26)
*pnDrive -= ('a' - 'A');
}
lpszFileName += 2;
}
else
{
if (pnDrive)
{
*pnDrive = -1;
}
}
lpszLclDir = lpszFileName;
if (!PathSep(*lpszLclDir))
{
fstrncpy(pszDir, pszCurPath, PARSE_MAX - 1);
/*TE*/ nPathCnt = fstrlen(pszCurPath);
if (!PathSep(pszDir[nPathCnt - 1]) && nPathCnt < PARSE_MAX - 1)
/*TE*/ pszDir[nPathCnt++] = '\\';
if (nPathCnt > PARSE_MAX)
nPathCnt = PARSE_MAX;
pszDir += nPathCnt;
}
/* Now see how long a directory component we have. */
while (NameChar(*lpszFileName)
|| PathSep(*lpszFileName) || '.' == *lpszFileName)
{
++nDirCnt;
++lpszFileName;
}
/* Fix lengths to maximums allowed by MS-DOS. */
if ((nDirCnt + nPathCnt) > PARSE_MAX - 1)
/*TE*/ nDirCnt = PARSE_MAX - 1 - nPathCnt;
/* Finally copy whatever the user wants extracted to the user's */
/* buffers. */
if (pszDir)
{
memcpy(pszDir, lpszLclDir, nDirCnt);
pszDir[nDirCnt] = '\0';
}
/* Clean up before leaving */
DosTrimPath(pszBase);
/* Before returning to the user, eliminate any useless */
/* trailing "\\." since the path prior to this is sufficient. */
nPathCnt = strlen(pszBase);
if (2 == nPathCnt) /* Special case, root */
{
if (!strcmp(pszBase, "\\."))
pszBase[1] = '\0';
}
else if (2 < nPathCnt)
{
if (!strcmp(&pszBase[nPathCnt - 2], "\\."))
pszBase[nPathCnt - 2] = '\0';
}
return SUCCESS;
}
VOID DosTrimPath(BYTE * lpszPathNamep)
{
BYTE *lpszLast, *lpszNext, *lpszRoot = NULL;
COUNT nChars, flDotDot;
/* First, convert all '/' to '\'. Look for root as we scan */
if (*lpszPathNamep == '\\')
lpszRoot = lpszPathNamep;
for (lpszNext = lpszPathNamep; *lpszNext; ++lpszNext)
{
if (*lpszNext == '/')
*lpszNext = '\\';
if (!lpszRoot && *lpszNext == ':' && *(lpszNext + 1) == '\\')
lpszRoot = lpszNext + 1;
}
/* NAMEMAX + 2, must include C: TE */
for (lpszLast = lpszNext = lpszPathNamep, nChars = 0;
*lpszNext != '\0' && nChars < NAMEMAX + 2;)
{
/* Initialize flag for loop. */
flDotDot = FALSE;
/* If we are at a path seperator, check for extra path */
/* seperator, '.' and '..' to reduce. */
if (*lpszNext == '\\')
{
/* If it's '\', just move everything down one. */
if (*(lpszNext + 1) == '\\')
fstrncpy(lpszNext, lpszNext + 1, NAMEMAX);
/* also check for '.' and '..' and move down */
/* as appropriate. */
else if (*(lpszNext + 1) == '.')
{
if (*(lpszNext + 2) == '.' && !(*(lpszNext + 3)))
{
/* At the end, just truncate */
/* and exit. */
if (lpszLast == lpszRoot)
*(lpszLast + 1) = '\0';
else
*lpszLast = '\0';
return;
}
if (*(lpszNext + 2) == '.' && *(lpszNext + 3) == '\\')
{
fstrncpy(lpszLast, lpszNext + 3, NAMEMAX);
/* bump back to the last */
/* seperator. */
lpszNext = lpszLast;
/* set lpszLast to the last one */
if (lpszLast <= lpszPathNamep)
continue;
do
{
--lpszLast;
}
while (lpszLast != lpszPathNamep && *lpszLast != '\\');
flDotDot = TRUE;
}
/* Note: we skip strange stuff that */
/* starts with '.' */
else if (*(lpszNext + 2) == '\\')
{
fstrncpy(lpszNext, lpszNext + 2, NAMEMAX);
flDotDot = TRUE;
}
/* If we're at the end of a string, */
/* just exit. */
else if (*(lpszNext + 2) == NULL)
{
return;
}
/*
Added this "else" because otherwise we might not pass
any of the foregoing tests, as in the case where the
incoming string refers to a suffix only, like ".bat"
-SRM
*/
else
{
lpszLast = lpszNext++;
}
}
else
{
/* No '.' or '\' so mark it and bump */
/* past */
lpszLast = lpszNext++;
continue;
}
/* Done. Now set last to next to mark this */
/* instance of path seperator. */
if (!flDotDot)
lpszLast = lpszNext;
}
else
/* For all other cases, bump lpszNext for the */
/* next check */
++lpszNext;
}
}
#endif
/*
* Log: dosnames.c,v - for newer log entries do "cvs log dosnames.c"
*

View File

@ -376,7 +376,11 @@ int21_exit_nodec:
pop si
%IFDEF I386
sub bp,8
%ifdef WATCOM
sub bp, 4 ; for fs and gs only
%else
sub bp, 8 ; high parts of eax, ebx, ecx, edx
%endif
%endif
cli

View File

@ -68,14 +68,10 @@ VOID dir_init_fnode(f_node_ptr fnp, CLUSTER dirstart)
fnp->f_cluster = fnp->f_dirstart = dirstart;
}
f_node_ptr dir_open(BYTE * dirname)
f_node_ptr dir_open(register const char *dirname)
{
f_node_ptr fnp;
COUNT drive;
BYTE *p;
WORD i;
struct cds FAR *cdsp;
BYTE *pszPath = dirname + 2;
int i;
/* Allocate an fnode if possible - error return (0) if not. */
if ((fnp = get_f_node()) == (f_node_ptr) 0)
@ -86,57 +82,23 @@ f_node_ptr dir_open(BYTE * dirname)
/* Force the fnode into read-write mode */
fnp->f_mode = RDWR;
/* determine what drive we are using... */
if (ParseDosName
(dirname, &drive, (BYTE *) 0, (BYTE *) 0, (BYTE *) 0,
FALSE) != SUCCESS)
/* determine what drive and dpb we are using... */
fnp->f_dpb = CDSp[dirname[0]-'A'].cdsDpb;
if (fnp->f_dpb == 0)
{
release_f_node(fnp);
return NULL;
}
/* If the drive was specified, drive is non-negative and */
/* corresponds to the one passed in, i.e., 0 = A, 1 = B, etc. */
/* We use that and skip the "D:" part of the string. */
/* Otherwise, just use the default drive */
if (drive >= 0)
{
dirname += 2; /* Assume FAT style drive */
}
else
{
drive = default_drive;
}
if (drive >= lastdrive)
{
release_f_node(fnp);
return NULL;
}
cdsp = &CDSp[drive];
/* Generate full path name */
/* not necessary anymore, since truename did that already
i = cdsp->cdsJoinOffset;
ParseDosPath(dirname, (COUNT *) 0, pszPath, (BYTE FAR *) & cdsp->cdsCurrentPath[i]); */
/* for testing only for now */
#if 0
if ((cdsp->cdsFlags & CDSNETWDRV))
if ((CDSp[dirname[0]-'A'].cdsFlags & CDSNETWDRV))
{
printf("FailSafe %x \n", Int21AX);
return fnp;
}
#endif
if (cdsp->cdsDpb == 0)
{
release_f_node(fnp);
return NULL;
}
fnp->f_dpb = cdsp->cdsDpb;
/* Perform all directory common handling after all special */
/* handling has been performed. */
@ -150,15 +112,21 @@ f_node_ptr dir_open(BYTE * dirname)
/* */
/* Start from the root directory (dirstart = 0) */
/* The CDS's cdsStartCls may be used to shorten the search
beginning at the CWD, see mapPath() and CDS.H in order
to enable this behaviour there.
-- 2001/09/04 ska*/
dir_init_fnode(fnp, 0);
for (p = pszPath; *p != '\0';)
dirname += 2; /* Assume FAT style drive */
while(*dirname != '\0')
{
/* skip all path seperators */
while (*p == '\\')
++p;
while (*dirname == '\\')
++dirname;
/* don't continue if we're at the end */
if (*p == '\0')
if (*dirname == '\0')
break;
/* Convert the name into an absolute name for */
@ -169,20 +137,22 @@ f_node_ptr dir_open(BYTE * dirname)
for (i = 0; i < FNAME_SIZE; i++)
{
if (*p != '\0' && *p != '.' && *p != '/' && *p != '\\')
TempBuffer[i] = *p++;
if (*dirname != '\0' && *dirname != '.' && *dirname != '/' &&
*dirname != '\\')
TempBuffer[i] = *dirname++;
else
break;
}
/* and the extension (don't forget to */
/* add trailing spaces)... */
if (*p == '.')
++p;
if (*dirname == '.')
++dirname;
for (i = 0; i < FEXT_SIZE; i++)
{
if (*p != '\0' && *p != '.' && *p != '/' && *p != '\\')
TempBuffer[i + FNAME_SIZE] = *p++;
if (*dirname != '\0' && *dirname != '.' && *dirname != '/' &&
*dirname != '\\')
TempBuffer[i + FNAME_SIZE] = *dirname++;
else
break;
}
@ -191,27 +161,18 @@ f_node_ptr dir_open(BYTE * dirname)
/* find the entry... */
i = FALSE;
DosUpFMem((BYTE FAR *) TempBuffer, FNAME_SIZE + FEXT_SIZE);
while (dir_read(fnp) == 1)
{
if (fnp->f_dir.dir_name[0] != '\0'
&& fnp->f_dir.dir_name[0] != DELETED
&& !(fnp->f_dir.dir_attrib & D_VOLID))
if (!(fnp->f_dir.dir_attrib & D_VOLID) &&
fcbmatch(TempBuffer, fnp->f_dir.dir_name))
{
if (fcmp
(TempBuffer, (BYTE *) fnp->f_dir.dir_name,
FNAME_SIZE + FEXT_SIZE))
{
i = TRUE;
break;
}
i = TRUE;
break;
}
}
if (!i || !(fnp->f_dir.dir_attrib & D_DIR))
{
release_f_node(fnp);
return (f_node_ptr) 0;
}
@ -225,6 +186,15 @@ f_node_ptr dir_open(BYTE * dirname)
return fnp;
}
/* swap internal and external delete flags */
STATIC void swap_deleted(char *name)
{
if (name[0] == DELETED)
name[0] = EXT_DELETED;
else if (name[0] == EXT_DELETED)
name[0] = DELETED;
}
/* Description.
* Read next consequitive directory entry, pointed by fnp.
* If some error occures the other critical
@ -306,6 +276,8 @@ COUNT dir_read(REG f_node_ptr fnp)
b_buffer[((UWORD) new_diroff) % fnp->f_dpb->dpb_secsize],
(struct dirent FAR *)&fnp->f_dir);
swap_deleted(fnp->f_dir.dir_name);
/* Update the fnode's directory info */
fnp->f_flags.f_dmod = FALSE;
fnp->f_flags.f_dnew = FALSE;
@ -399,10 +371,15 @@ BOOL dir_write(REG f_node_ptr fnp)
if (fnp->f_flags.f_dnew && fnp->f_dir.dir_attrib != D_LFN)
fmemset(&fnp->f_dir.dir_case, 0, 8);
swap_deleted(fnp->f_dir.dir_name);
putdirent((struct dirent FAR *)&fnp->f_dir,
(VOID FAR *) & bp->b_buffer[(UWORD) fnp->f_diroff %
fnp->f_dpb->dpb_secsize]);
swap_deleted(fnp->f_dir.dir_name);
bp->b_flag &= ~(BFR_DATA | BFR_FAT);
bp->b_flag |= BFR_DIR | BFR_DIRTY | BFR_VALID;
}
@ -422,6 +399,7 @@ VOID dir_close(REG f_node_ptr fnp)
#endif
/* Clear buffers after release */
/* hazard: no error checking! */
flush_buffers(fnp->f_dpb->dpb_unit);
/* and release this instance of the fnode */
@ -434,10 +412,6 @@ COUNT dos_findfirst(UCOUNT attr, BYTE * name)
REG f_node_ptr fnp;
REG dmatch *dmp = (dmatch *) TempBuffer;
REG COUNT i;
COUNT nDrive;
BYTE *p;
BYTE local_name[FNAME_SIZE + 1], local_ext[FEXT_SIZE + 1];
/* printf("ff %Fs\n", name);*/
@ -449,63 +423,37 @@ COUNT dos_findfirst(UCOUNT attr, BYTE * name)
/* current directory, do a seek and read, then close the fnode. */
/* Parse out the drive, file name and file extension. */
i = ParseDosName(name, &nDrive, &szDirName[2], local_name, local_ext,
TRUE);
if (i != SUCCESS)
i = ParseDosName(name, SearchDir.dir_name, TRUE);
if (i < SUCCESS)
return i;
/*
printf("\nff %s", Tname);
printf("ff %s", local_name);
printf("ff %s\n", local_ext);
printf("ff %s", fcbname);
*/
/* Build the match pattern out of the passed string */
/* copy the part of the pattern which belongs to the filename and is fixed */
for (p = local_name, i = 0; i < FNAME_SIZE && *p; ++p, ++i)
SearchDir.dir_name[i] = *p;
for (; i < FNAME_SIZE; ++i)
SearchDir.dir_name[i] = ' ';
/* and the extension (don't forget to add trailing spaces)... */
for (p = local_ext, i = 0; i < FEXT_SIZE && *p; ++p, ++i)
SearchDir.dir_ext[i] = *p;
for (; i < FEXT_SIZE; ++i)
SearchDir.dir_ext[i] = ' ';
/* Convert everything to uppercase. */
DosUpFMem(SearchDir.dir_name, FNAME_SIZE + FEXT_SIZE);
/* Now search through the directory to find the entry... */
/* Complete building the directory from the passed in */
/* name */
szDirName[0] = 'A' + nDrive;
szDirName[1] = ':';
/* Special handling - the volume id is only in the root */
/* directory and only searched for once. So we need to open */
/* the root and return only the first entry that contains the */
/* volume id bit set. */
if (attr == D_VOLID)
{
szDirName[2] = '\\';
szDirName[3] = '\0';
}
i = 3;
/* Now open this directory so that we can read the */
/* fnode entry and do a match on it. */
/* printf("dir_open %s\n", szDirName);*/
if ((fnp = dir_open(szDirName)) == NULL)
return DE_PATHNOTFND;
{
char tmp = name[i];
name[i] = '\0';
if ((fnp = dir_open(name)) == NULL)
return DE_PATHNOTFND;
name[i] = tmp;
}
/* Now initialize the dirmatch structure. */
nDrive = get_verify_drive(name);
if (nDrive < 0)
return nDrive;
dmp->dm_drive = nDrive;
dmp->dm_drive = name[0] - 'A';
dmp->dm_attr_srch = attr;
/* Copy the raw pattern from our data segment to the DTA. */
@ -605,9 +553,7 @@ COUNT dos_findnext(void)
if (fnp->f_dir.dir_name[0] != '\0' && fnp->f_dir.dir_name[0] != DELETED
&& (fnp->f_dir.dir_attrib & D_VOLID) != D_VOLID)
{
if (fcmp_wild
((BYTE FAR *) dmp->dm_name_pat, (BYTE FAR *) fnp->f_dir.dir_name,
FNAME_SIZE + FEXT_SIZE))
if (fcmp_wild(dmp->dm_name_pat, fnp->f_dir.dir_name, FNAME_SIZE + FEXT_SIZE))
{
/*
MSD Command.com uses FCB FN 11 & 12 with attrib set to 0x16.
@ -694,6 +640,7 @@ void ConvertName83ToNameSZ(BYTE FAR * destSZ, BYTE FAR * srcFCBName)
*destSZ = '\0';
}
#if 0
/*
returns the asciiSZ length of a 8.3 filename
*/
@ -706,6 +653,7 @@ int FileName83Length(BYTE * filename83)
return strlen(buff);
}
#endif
/*
* Log: fatdir.c,v - for newer log entries do a "cvs log fatdir.c"

View File

@ -39,8 +39,8 @@ BYTE *RcsId = "$Id$";
/* */
f_node_ptr xlt_fd(COUNT);
COUNT xlt_fnp(f_node_ptr);
f_node_ptr split_path(BYTE *, BYTE *, BYTE *);
BOOL find_fname(f_node_ptr, BYTE *, BYTE *, int);
STATIC f_node_ptr split_path(char *, char *);
BOOL find_fname(f_node_ptr, char *, int);
/* /// Added - Ron Cemer */
STATIC void merge_file_changes(f_node_ptr fnp, int collect);
/* /// Added - Ron Cemer */
@ -77,63 +77,158 @@ ULONG clus2phys(CLUSTER cl_no, struct dpb FAR * dpbp)
/* Open a file given the path. Flags is 0 for read, 1 for write and 2 */
/* for update. */
/* Returns an integer file desriptor or a negative error code */
/* Returns an long where the high word is a status code and the low */
/* word is an integer file descriptor or a negative error code */
/* see DosOpenSft(), dosfns.c for an explanation of the flags bits */
/* directory opens are allowed here; these are not allowed by DosOpenSft*/
COUNT dos_open(BYTE * path, COUNT flag)
long dos_open(char *path, unsigned flags, unsigned attrib)
{
REG f_node_ptr fnp;
char fcbname[FNAME_SIZE + FEXT_SIZE];
int status = S_OPENED;
/* First test the flag to see if the user has passed a valid */
/* First test the flags to see if the user has passed a valid */
/* file mode... */
if (flag < 0 || flag > 2)
if ((flags & 3) > 2)
return DE_INVLDACC;
/* first split the passed dir into comopnents (i.e. - path to */
/* new directory and name of new directory. */
if ((fnp = split_path(path, szFileName, szFileExt)) == NULL)
{
if ((fnp = split_path(path, fcbname)) == NULL)
return DE_PATHNOTFND;
}
/* Look for the file. If we can't find it, just return a not */
/* found error. */
if (!find_fname(fnp, szFileName, szFileExt, D_ALL))
/* Check that we don't have a duplicate name, so if we */
/* find one, truncate it (O_CREAT). */
if (find_fname(fnp, fcbname, D_ALL | attrib))
{
if (flags & O_TRUNC)
{
/* The only permissable attribute is archive, */
/* check for any other bit set. If it is, give */
/* an access error. */
if ((fnp->f_dir.dir_attrib & (D_RDONLY | D_DIR | D_VOLID))
|| (fnp->f_dir.dir_attrib & ~D_ARCHIVE & ~attrib))
{
dir_close(fnp);
return DE_ACCESS;
}
/* Release the existing files FAT and set the */
/* length to zero, effectively truncating the */
/* file to zero. */
wipe_out(fnp);
status = S_REPLACED;
}
else if (!(flags & O_OPEN))
{
dir_close(fnp);
return DE_FILEEXISTS;
}
}
else if (flags & O_CREAT)
{
BOOL is_free;
/* Reset the directory by a close followed by */
/* an open */
fnp->f_flags.f_dmod = FALSE;
dir_close(fnp);
fnp = split_path(path, fcbname);
/* Get a free f_node pointer so that we can use */
/* it in building the new file. */
/* Note that if we're in the root and we don't */
/* find an empty slot, we need to abort. */
if (((is_free = find_free(fnp)) == 0) && (fnp->f_flags.f_droot))
{
fnp->f_flags.f_dmod = FALSE;
dir_close(fnp);
return DE_TOOMANY;
}
/* Otherwise just expand the directory */
else if (!is_free && !(fnp->f_flags.f_droot))
{
COUNT ret;
if ((ret = extend_dir(fnp)) != SUCCESS)
/* fnp already closed in extend_dir */
return ret;
}
/* put the fnode's name into the directory. */
memcpy(fnp->f_dir.dir_name, fcbname, FNAME_SIZE + FEXT_SIZE);
status = S_CREATED;
}
else
{
/* open: If we can't find the file, just return a not */
/* found error. */
dir_close(fnp);
return DE_FILENOTFND;
}
/* Set the fnode to the desired mode */
/* Updating the directory entry first. */
fnp->f_mode = flags & 3;
if (status != S_OPENED)
{
fnp->f_dir.dir_size = 0l;
setdstart(fnp->f_dir, FREE);
fnp->f_dir.dir_attrib = attrib;
fnp->f_dir.dir_time = dos_gettime();
fnp->f_dir.dir_date = dos_getdate();
fnp->f_flags.f_dmod = TRUE;
fnp->f_flags.f_ddate = FALSE;
fnp->f_flags.f_dnew = FALSE;
fnp->f_flags.f_ddir = TRUE;
if (!dir_write(fnp))
{
release_f_node(fnp);
return DE_ACCESS;
}
}
/* Set the fnode to the desired mode */
fnp->f_mode = flag;
/* force r/o open for FCBs if the file is read-only */
if ((flags & O_FCB) && (fnp->f_dir.dir_attrib & D_RDONLY))
fnp->f_mode = O_RDONLY;
/* Initialize the rest of the fnode. */
/* Check permissions. -- JPP */
if ((fnp->f_dir.dir_attrib & D_RDONLY) && (fnp->f_mode != O_RDONLY))
{
dir_close(fnp);
return DE_ACCESS;
}
/* Now change to file */
fnp->f_offset = 0l;
fnp->f_highwater = fnp->f_dir.dir_size;
fnp->f_back = LONG_LAST_CLUSTER;
fnp->f_flags.f_dmod = FALSE;
if (status != S_OPENED)
{
fnp->f_cluster = FREE;
setdstart(fnp->f_dir, FREE);
fnp->f_cluster_offset = 0l; /*JPP */
}
fnp->f_flags.f_dmod = (status != S_OPENED);
fnp->f_flags.f_ddate = FALSE;
fnp->f_flags.f_dnew = FALSE;
fnp->f_flags.f_ddir = FALSE;
merge_file_changes(fnp, TRUE); /* /// Added - Ron Cemer */
merge_file_changes(fnp, status == S_OPENED); /* /// Added - Ron Cemer */
/* /// Moved from above. - Ron Cemer */
fnp->f_cluster = getdstart(fnp->f_dir);
fnp->f_cluster_offset = 0l; /*JPP */
return xlt_fnp(fnp);
return xlt_fnp(fnp) | ((long)status << 16);
}
BOOL fcmp(BYTE * s1, BYTE * s2, COUNT n)
{
while (n--)
if (*s1++ != *s2++)
return FALSE;
return TRUE;
}
BOOL fcmp_wild(BYTE FAR * s1, BYTE FAR * s2, COUNT n)
BOOL fcmp_wild(const char * s1, const char * s2, unsigned n)
{
while (n--)
{
@ -203,31 +298,15 @@ COUNT dos_commit(COUNT fd)
/* */
/* split a path into it's component directory and file name */
/* */
f_node_ptr split_path(BYTE * path, BYTE * fname, BYTE * fext)
f_node_ptr split_path(char * path, char * fcbname)
{
REG f_node_ptr fnp;
COUNT nDrive;
struct cds FAR *cdsp;
/* Start off by parsing out the components. */
if (ParseDosName(path, &nDrive, &szDirName[2], fname, fext, FALSE)
!= SUCCESS)
/* Start off by parsing out the components. */
int dirlength = ParseDosName(path, fcbname, FALSE);
if (dirlength < SUCCESS)
return (f_node_ptr) 0;
if (nDrive < 0)
nDrive = default_drive;
szDirName[0] = 'A' + nDrive;
szDirName[1] = ':';
/* Add trailing spaces to the file name and extension */
SpacePad(fname, FNAME_SIZE);
SpacePad(fext, FEXT_SIZE);
if (nDrive >= lastdrive)
{
return (f_node_ptr) 0;
}
cdsp = &CDSp[nDrive];
/* 11/29/99 jt
* Networking and Cdroms. You can put in here a return.
@ -241,7 +320,7 @@ f_node_ptr split_path(BYTE * path, BYTE * fname, BYTE * fext)
*/
#ifdef DEBUG
if (cdsp->cdsFlags & CDSNETWDRV)
if (CDSp[path[0]-'A'].cdsFlags & CDSNETWDRV)
{
printf("split path called for redirected file: `%s.%s'\n",
fname, fext);
@ -250,7 +329,12 @@ f_node_ptr split_path(BYTE * path, BYTE * fname, BYTE * fext)
#endif
/* Translate the path into a useful pointer */
fnp = dir_open(szDirName);
{
char tmp = path[dirlength];
path[dirlength] = '\0';
fnp = dir_open(path);
path[dirlength] = tmp;
}
/* If the fd was invalid because it was out of range or the */
/* requested file was not open, tell the caller and exit... */
@ -261,21 +345,32 @@ f_node_ptr split_path(BYTE * path, BYTE * fname, BYTE * fext)
return (f_node_ptr) 0;
}
/* Convert the name into an absolute name for comparison... */
DosUpFString((BYTE FAR *) szDirName);
DosUpFMem((BYTE FAR *) fname, FNAME_SIZE);
DosUpFMem((BYTE FAR *) fext, FEXT_SIZE);
return fnp;
}
STATIC BOOL find_fname(f_node_ptr fnp, BYTE * fname, BYTE * fext, int attr)
/* checks whether directory part of path exists */
BOOL dir_exists(char * path)
{
REG f_node_ptr fnp;
char fcbname[FNAME_SIZE + FEXT_SIZE];
if ((fnp = split_path(path, fcbname)) == NULL)
return FALSE;
dir_close(fnp);
return TRUE;
}
BOOL fcbmatch(const char *fcbname1, const char *fcbname2)
{
return memcmp(fcbname1, fcbname2, FNAME_SIZE + FEXT_SIZE) == 0;
}
STATIC BOOL find_fname(f_node_ptr fnp, char *fcbname, int attr)
{
while (dir_read(fnp) == 1)
{
if (fnp->f_dir.dir_name[0] != DELETED
&& fcmp(fname, (BYTE *) fnp->f_dir.dir_name, FNAME_SIZE)
&& fcmp(fext, (BYTE *) fnp->f_dir.dir_ext, FEXT_SIZE)
if (fcbmatch(fnp->f_dir.dir_name, fcbname)
&& (fnp->f_dir.dir_attrib & ~(D_RDONLY | D_ARCHIVE | attr)) == 0)
{
return TRUE;
@ -375,12 +470,7 @@ STATIC int is_same_file(f_node_ptr fnp1, f_node_ptr fnp2)
return
(fnp1->f_dpb->dpb_unit == fnp2->f_dpb->dpb_unit)
&& (fnp1->f_dpb->dpb_subunit == fnp2->f_dpb->dpb_subunit)
&& (fcmp
((BYTE *) fnp1->f_dir.dir_name,
(BYTE *) fnp2->f_dir.dir_name, FNAME_SIZE))
&& (fcmp
((BYTE *) fnp1->f_dir.dir_ext,
(BYTE *) fnp2->f_dir.dir_ext, FEXT_SIZE))
&& (fcbmatch(fnp1->f_dir.dir_name, fnp2->f_dir.dir_name))
&& ((fnp1->f_dir.dir_attrib & D_VOLID) == 0)
&& ((fnp2->f_dir.dir_attrib & D_VOLID) == 0)
&& (fnp1->f_diroff == fnp2->f_diroff)
@ -401,108 +491,6 @@ STATIC void copy_file_changes(f_node_ptr src, f_node_ptr dst)
dst->f_dir.dir_time = src->f_dir.dir_time;
}
COUNT dos_creat(BYTE * path, int attrib)
{
REG f_node_ptr fnp;
/* first split the passed dir into components (i.e. - */
/* path to new directory and name of new directory */
if ((fnp = split_path(path, szFileName, szFileExt)) == NULL)
{
return DE_PATHNOTFND;
}
/* Check that we don't have a duplicate name, so if we */
/* find one, truncate it. */
if (find_fname(fnp, szFileName, szFileExt, D_ALL | attrib))
{
/* The only permissable attribute is archive, */
/* check for any other bit set. If it is, give */
/* an access error. */
if ((fnp->f_dir.dir_attrib & (D_RDONLY | D_DIR | D_VOLID))
|| (fnp->f_dir.dir_attrib & ~D_ARCHIVE & ~attrib))
{
dir_close(fnp);
return DE_ACCESS;
}
/* Release the existing files FAT and set the */
/* length to zero, effectively truncating the */
/* file to zero. */
wipe_out(fnp);
}
else
{
BOOL is_free;
/* Reset the directory by a close followed by */
/* an open */
fnp->f_flags.f_dmod = FALSE;
dir_close(fnp);
fnp = split_path(path, szFileName, szFileExt);
/* Get a free f_node pointer so that we can use */
/* it in building the new file. */
/* Note that if we're in the root and we don't */
/* find an empty slot, we need to abort. */
if (((is_free = find_free(fnp)) == 0) && (fnp->f_flags.f_droot))
{
fnp->f_flags.f_dmod = FALSE;
dir_close(fnp);
return DE_TOOMANY;
}
/* Otherwise just expand the directory */
else if (!is_free && !(fnp->f_flags.f_droot))
{
COUNT ret;
if ((ret = extend_dir(fnp)) != SUCCESS)
return ret;
}
/* put the fnode's name into the directory. */
memcpy(fnp->f_dir.dir_name, szFileName, FNAME_SIZE);
memcpy(fnp->f_dir.dir_ext, szFileExt, FEXT_SIZE);
}
/* Set the fnode to the desired mode */
/* Updating the directory entry first. */
fnp->f_mode = RDWR;
fnp->f_dir.dir_size = 0l;
setdstart(fnp->f_dir, FREE);
fnp->f_dir.dir_attrib = attrib | D_ARCHIVE;
fnp->f_dir.dir_time = dos_gettime();
fnp->f_dir.dir_date = dos_getdate();
fnp->f_flags.f_dmod = TRUE;
fnp->f_flags.f_ddate = FALSE;
fnp->f_flags.f_dnew = FALSE;
fnp->f_flags.f_ddir = TRUE;
if (!dir_write(fnp))
{
release_f_node(fnp);
return DE_ACCESS;
}
/* Now change to file */
fnp->f_offset = 0l;
fnp->f_highwater = 0l;
fnp->f_back = LONG_LAST_CLUSTER;
fnp->f_cluster = FREE;
setdstart(fnp->f_dir, FREE);
fnp->f_cluster_offset = 0l; /*JPP */
fnp->f_flags.f_dmod = TRUE;
fnp->f_flags.f_ddate = FALSE;
fnp->f_flags.f_dnew = FALSE;
fnp->f_flags.f_ddir = FALSE;
merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */
return xlt_fnp(fnp);
}
STATIC COUNT delete_dir_entry(f_node_ptr fnp)
{
COUNT rc;
@ -529,17 +517,18 @@ STATIC COUNT delete_dir_entry(f_node_ptr fnp)
COUNT dos_delete(BYTE * path, int attrib)
{
REG f_node_ptr fnp;
char fcbname[FNAME_SIZE + FEXT_SIZE];
/* first split the passed dir into components (i.e. - */
/* path to new directory and name of new directory */
if ((fnp = split_path(path, szFileName, szFileExt)) == NULL)
if ((fnp = split_path(path, fcbname)) == NULL)
{
return DE_PATHNOTFND;
}
/* Check that we don't have a duplicate name, so if we */
/* find one, it's an error. */
if (find_fname(fnp, szFileName, szFileExt, attrib))
if (find_fname(fnp, fcbname, attrib))
{
/* Do not delete directories or r/o files */
/* lfn entries and volume labels are only found */
@ -566,10 +555,11 @@ COUNT dos_rmdir(BYTE * path)
REG f_node_ptr fnp;
REG f_node_ptr fnp1;
BOOL found;
char fcbname[FNAME_SIZE + FEXT_SIZE];
/* first split the passed dir into comopnents (i.e. - */
/* path to new directory and name of new directory */
if ((fnp = split_path(path, szFileName, szFileExt)) == NULL)
if ((fnp = split_path(path, fcbname)) == NULL)
{
return DE_PATHNOTFND;
}
@ -583,7 +573,7 @@ COUNT dos_rmdir(BYTE * path)
/* Check that we don't have a duplicate name, so if we */
/* find one, it's an error. */
if (find_fname(fnp, szFileName, szFileExt, D_ALL))
if (find_fname(fnp, fcbname, D_ALL))
{
/* The only permissable attribute is directory, */
/* check for any other bit set. If it is, give */
@ -658,17 +648,18 @@ COUNT dos_rename(BYTE * path1, BYTE * path2, int attrib)
REG f_node_ptr fnp2;
BOOL is_free;
COUNT ret;
char fcbname[FNAME_SIZE + FEXT_SIZE];
/* first split the passed target into compnents (i.e. - path to */
/* new file name and name of new file name */
if ((fnp2 = split_path(path2, szFileName, szFileExt)) == NULL)
if ((fnp2 = split_path(path2, fcbname)) == NULL)
{
return DE_PATHNOTFND;
}
/* Check that we don't have a duplicate name, so if we find */
/* one, it's an error. */
if (find_fname(fnp2, szFileName, szFileExt, attrib))
if (find_fname(fnp2, fcbname, attrib))
{
dir_close(fnp2);
return DE_ACCESS;
@ -676,13 +667,13 @@ COUNT dos_rename(BYTE * path1, BYTE * path2, int attrib)
/* next split the passed source into compnents (i.e. - path to */
/* old file name and name of old file name */
if ((fnp1 = split_path(path1, szFileName, szFileExt)) == NULL)
if ((fnp1 = split_path(path1, fcbname)) == NULL)
{
dir_close(fnp2);
return DE_PATHNOTFND;
}
if (!find_fname(fnp1, szFileName, szFileExt, attrib))
if (!find_fname(fnp1, fcbname, attrib))
{
/* No such file, return the error */
dir_close(fnp1);
@ -693,7 +684,7 @@ COUNT dos_rename(BYTE * path1, BYTE * path2, int attrib)
/* Reset the directory by a close followed by an open */
fnp2->f_flags.f_dmod = FALSE;
dir_close(fnp2);
fnp2 = split_path(path2, szFileName, szFileExt);
fnp2 = split_path(path2, fcbname);
/* Now find a free slot to put the file into. */
/* If it's the root and we don't have room, return an error. */
@ -719,8 +710,7 @@ COUNT dos_rename(BYTE * path1, BYTE * path2, int attrib)
return ret;
/* put the fnode's name into the directory. */
memcpy(fnp2->f_dir.dir_name, szFileName, FNAME_SIZE);
memcpy(fnp2->f_dir.dir_ext, szFileExt, FEXT_SIZE);
memcpy(fnp2->f_dir.dir_name, fcbname, FNAME_SIZE + FEXT_SIZE);
/* Set the fnode to the desired mode */
fnp2->f_dir.dir_size = fnp1->f_dir.dir_size;
@ -766,7 +756,7 @@ STATIC VOID wipe_out_clusters(struct dpb FAR * dpbp, CLUSTER st)
next = next_cluster(dpbp, st);
/* just exit if a damaged file system exists */
if (next == FREE)
if (next == FREE || next == 1)
return;
/* zap the FAT pointed to */
@ -820,15 +810,13 @@ STATIC BOOL find_free(f_node_ptr fnp)
/* */
date dos_getdate()
{
BYTE WeekDay, Month, MonthDay;
COUNT Year;
UBYTE WeekDay, Month, MonthDay;
UWORD Year;
date Date;
/* First - get the system date set by either the user */
/* on start-up or the CMOS clock */
DosGetDate((BYTE FAR *) & WeekDay,
(BYTE FAR *) & Month,
(BYTE FAR *) & MonthDay, (COUNT FAR *) & Year);
DosGetDate(&WeekDay, &Month, &MonthDay, &Year);
Date = DT_ENCODE(Month, MonthDay, Year - EPOCH_YEAR);
return Date;
}
@ -838,13 +826,11 @@ date dos_getdate()
/* */
time dos_gettime()
{
BYTE Hour, Minute, Second, Hundredth;
UBYTE Hour, Minute, Second, Hundredth;
/* First - get the system time set by either the user */
/* on start-up or the CMOS clock */
DosGetTime((BYTE FAR *) & Hour,
(BYTE FAR *) & Minute,
(BYTE FAR *) & Second, (BYTE FAR *) & Hundredth);
DosGetTime(&Hour, &Minute, &Second, &Hundredth);
return TM_ENCODE(Hour, Minute, Second / 2);
}
@ -901,7 +887,7 @@ COUNT dos_setftime(COUNT fd, date dp, time tp)
/* */
/* dos_getfsize for the file time */
/* */
LONG dos_getcufsize(COUNT fd)
ULONG dos_getfsize(COUNT fd)
{
f_node_ptr fnp;
@ -913,33 +899,12 @@ LONG dos_getcufsize(COUNT fd)
/* requested file was not open, tell the caller and exit */
/* note: an invalid fd is indicated by a 0 return */
if (fnp == (f_node_ptr) 0 || fnp->f_count <= 0)
return -1l;
return (ULONG)-1l;
/* Return the file size */
return fnp->f_highwater;
}
/* */
/* dos_getfsize for the file time */
/* */
LONG dos_getfsize(COUNT fd)
{
f_node_ptr fnp;
/* Translate the fd into an fnode pointer, since all internal */
/* operations are achieved through fnodes. */
fnp = xlt_fd(fd);
/* If the fd was invalid because it was out of range or the */
/* requested file was not open, tell the caller and exit */
/* note: an invalid fd is indicated by a 0 return */
if (fnp == (f_node_ptr) 0 || fnp->f_count <= 0)
return -1l;
/* Return the file size */
return fnp->f_dir.dir_size;
}
/* */
/* dos_setfsize for the file time */
/* */
@ -1050,10 +1015,11 @@ COUNT dos_mkdir(BYTE * dir)
struct dpb FAR *dpbp;
CLUSTER free_fat, parent;
COUNT ret;
char fcbname[FNAME_SIZE + FEXT_SIZE];
/* first split the passed dir into comopnents (i.e. - */
/* path to new directory and name of new directory */
if ((fnp = split_path(dir, szFileName, szFileExt)) == NULL)
if ((fnp = split_path(dir, fcbname)) == NULL)
{
return DE_PATHNOTFND;
}
@ -1074,7 +1040,7 @@ COUNT dos_mkdir(BYTE * dir)
/* Check that we don't have a duplicate name, so if we */
/* find one, it's an error. */
if (find_fname(fnp, szFileName, szFileExt, D_ALL))
if (find_fname(fnp, fcbname, D_ALL))
{
dir_close(fnp);
return DE_ACCESS;
@ -1085,7 +1051,7 @@ COUNT dos_mkdir(BYTE * dir)
fnp->f_flags.f_dmod = FALSE;
parent = fnp->f_dirstart;
dir_close(fnp);
fnp = split_path(dir, szFileName, szFileExt);
fnp = split_path(dir, fcbname);
/* Get a free f_node pointer so that we can use */
/* it in building the new file. */
@ -1121,8 +1087,7 @@ COUNT dos_mkdir(BYTE * dir)
}
/* put the fnode's name into the directory. */
memcpy(fnp->f_dir.dir_name, szFileName, FNAME_SIZE);
memcpy(fnp->f_dir.dir_ext, szFileExt, FEXT_SIZE);
memcpy(fnp->f_dir.dir_name, fcbname, FNAME_SIZE + FEXT_SIZE);
/* Set the fnode to the desired mode */
fnp->f_mode = WRONLY;
@ -1160,8 +1125,8 @@ COUNT dos_mkdir(BYTE * dir)
}
/* Create the "." entry */
memcpy(DirEntBuffer.dir_name, ". ", FNAME_SIZE);
memcpy(DirEntBuffer.dir_ext, " ", FEXT_SIZE);
DirEntBuffer.dir_name[0] = '.';
memset(DirEntBuffer.dir_name + 1, ' ', FNAME_SIZE + FEXT_SIZE - 1);
DirEntBuffer.dir_attrib = D_DIR;
DirEntBuffer.dir_time = dos_gettime();
DirEntBuffer.dir_date = dos_getdate();
@ -1169,10 +1134,10 @@ COUNT dos_mkdir(BYTE * dir)
DirEntBuffer.dir_size = 0l;
/* And put it out */
putdirent((struct dirent FAR *)&DirEntBuffer, (BYTE FAR *) bp->b_buffer);
putdirent(&DirEntBuffer, bp->b_buffer);
/* create the ".." entry */
memcpy(DirEntBuffer.dir_name, ".. ", FNAME_SIZE);
DirEntBuffer.dir_name[1] = '.';
#ifdef WITHFAT32
if (ISFAT32(dpbp) && parent == dpbp->dpb_xrootclst)
{
@ -1182,8 +1147,7 @@ COUNT dos_mkdir(BYTE * dir)
setdstart(DirEntBuffer, parent);
/* and put it out */
putdirent((struct dirent FAR *)&DirEntBuffer,
(BYTE FAR *) & bp->b_buffer[DIRENT_SIZE]);
putdirent(&DirEntBuffer, &bp->b_buffer[DIRENT_SIZE]);
/* fill the rest of the block with zeros */
fmemset(&bp->b_buffer[2 * DIRENT_SIZE], 0, BUFFERSIZE - 2 * DIRENT_SIZE);
@ -1212,6 +1176,7 @@ COUNT dos_mkdir(BYTE * dir)
}
/* flush the drive buffers so that all info is written */
/* hazard: no error checking! */
flush_buffers((COUNT) (dpbp->dpb_unit));
/* Close the directory so that the entry is updated */
@ -1292,6 +1257,7 @@ STATIC COUNT extend_dir(f_node_ptr fnp)
}
/* flush the drive buffers so that all info is written */
/* hazard: no error checking! */
flush_buffers((COUNT) (fnp->f_dpb->dpb_unit));
return SUCCESS;
@ -1416,6 +1382,8 @@ COUNT map_cluster(REG f_node_ptr fnp, COUNT mode)
fnp->f_cluster = next_cluster(fnp->f_dpb, fnp->f_cluster);
fnp->f_cluster_offset += clssize;
idx -= clssize;
if (fnp->f_cluster == 1)
return DE_SEEK;
}
#ifdef DISPLAY_GETBLOCK
@ -1578,8 +1546,8 @@ UCOUNT rwblock(COUNT fd, VOID FAR * buffer, UCOUNT count, int mode)
REG struct buffer FAR *bp;
UCOUNT xfr_cnt = 0;
UCOUNT ret_cnt = 0;
UWORD secsize;
UCOUNT to_xfer = count;
unsigned secsize;
unsigned to_xfer = count;
ULONG currentblock;
#if 0 /*DSK_DEBUG*/
@ -1932,7 +1900,7 @@ COUNT dos_cd(struct cds FAR * cdsp, BYTE * PathName)
f_node_ptr get_f_node(void)
{
REG i;
REG int i;
for (i = 0; i < f_nodes_cnt; i++)
{
@ -1959,66 +1927,54 @@ VOID dos_setdta(BYTE FAR * newdta)
dta = newdta;
}
COUNT dos_getfattr(BYTE * name)
COUNT dos_getfattr_fd(COUNT fd)
{
f_node_ptr fnp;
COUNT fd, result;
/* Translate the fd into an fnode pointer, since all internal */
/* operations are achieved through fnodes. */
if ((fd = dos_open(name, O_RDONLY)) < SUCCESS)
return DE_FILENOTFND;
f_node_ptr fnp = xlt_fd(fd);
/* note: an invalid fd is indicated by a 0 return */
if ((fnp = xlt_fd(fd)) == (f_node_ptr) 0)
if (fnp == (f_node_ptr) 0)
return DE_TOOMANY;
/* If the fd was invalid because it was out of range or the */
/* requested file was not open, tell the caller and exit */
if (fnp->f_count <= 0)
{
dos_close(fd);
return DE_FILENOTFND;
}
/* Get the attribute from the fnode and return */
result = fnp->f_dir.dir_attrib;
return fnp->f_dir.dir_attrib;
}
COUNT dos_getfattr(BYTE * name)
{
COUNT result, fd;
fd = (short)dos_open(name, O_RDONLY | O_OPEN, 0);
if (fd < SUCCESS)
return fd;
result = dos_getfattr_fd(fd);
dos_close(fd);
return result;
}
COUNT dos_setfattr(BYTE * name, UWORD attrp)
{
f_node_ptr fnp;
COUNT fd;
f_node_ptr fnp;
/* Translate the fd into an fnode pointer, since all internal */
/* operations are achieved through fnodes. */
if ((fd = dos_open(name, O_RDONLY)) < SUCCESS)
return DE_FILENOTFND;
/* note: an invalid fd is indicated by a 0 return */
if ((fnp = xlt_fd(fd)) == (f_node_ptr) 0)
return DE_TOOMANY;
/* If the fd was invalid because it was out of range or the */
/* requested file was not open, tell the caller and exit */
if (fnp->f_count <= 0)
{
dos_close(fd);
return DE_FILENOTFND;
}
/* JPP-If user tries to set VOLID or DIR bits, return error */
if ((attrp & (D_VOLID | D_DIR | 0xC0)) != 0)
{
dos_close(fd);
return DE_ACCESS;
}
fd = (short)dos_open(name, O_RDONLY | O_OPEN, 0);
if (fd < SUCCESS)
return fd;
fnp = xlt_fd(fd);
/* Set the attribute from the fnode and return */
/* clear all attributes but DIR and VOLID */
fnp->f_dir.dir_attrib &= (D_VOLID | D_DIR); /* JPP */
/* set attributes that user requested */
fnp->f_dir.dir_attrib |= attrp; /* JPP */
fnp->f_flags.f_dmod = TRUE;
@ -2094,8 +2050,6 @@ VOID bpb_to_dpb(bpb FAR * bpbp, REG struct dpb FAR * dpbp)
COUNT media_check(REG struct dpb FAR * dpbp)
{
BYTE status;
/* First test if anyone has changed the removable media */
FOREVER
{
@ -2105,10 +2059,8 @@ COUNT media_check(REG struct dpb FAR * dpbp)
MediaReqHdr.r_mcmdesc = dpbp->dpb_mdb;
MediaReqHdr.r_status = 0;
execrh((request FAR *) & MediaReqHdr, dpbp->dpb_device);
if (!(MediaReqHdr.r_status & S_ERROR)
&& (MediaReqHdr.r_status & S_DONE))
break;
else
if ((MediaReqHdr.r_status & S_ERROR)
|| !(MediaReqHdr.r_status & S_DONE))
{
loop1:
switch (block_error(&MediaReqHdr, dpbp->dpb_unit, dpbp->dpb_device))
@ -2127,10 +2079,10 @@ COUNT media_check(REG struct dpb FAR * dpbp)
goto loop1;
}
}
break;
}
status = MediaReqHdr.r_mcretcode | dpbp->dpb_flags;
switch (status)
switch (MediaReqHdr.r_mcretcode | dpbp->dpb_flags)
{
case M_NOT_CHANGED:
/* It was definitely not changed, so ignore it */
@ -2139,6 +2091,7 @@ COUNT media_check(REG struct dpb FAR * dpbp)
/* If it is forced or the media may have changed, */
/* rebuild the bpb */
case M_DONT_KNOW:
/* hazard: no error checking! */
flush_buffers(dpbp->dpb_unit);
/* If it definitely changed, don't know (falls through) */
@ -2154,10 +2107,8 @@ COUNT media_check(REG struct dpb FAR * dpbp)
MediaReqHdr.r_mcmdesc = dpbp->dpb_mdb;
MediaReqHdr.r_status = 0;
execrh((request FAR *) & MediaReqHdr, dpbp->dpb_device);
if (!(MediaReqHdr.r_status & S_ERROR)
&& (MediaReqHdr.r_status & S_DONE))
break;
else
if ((MediaReqHdr.r_status & S_ERROR)
|| !(MediaReqHdr.r_status & S_DONE))
{
loop2:
switch (block_error
@ -2177,6 +2128,7 @@ COUNT media_check(REG struct dpb FAR * dpbp)
goto loop2;
}
}
break;
}
#ifdef WITHFAT32
/* extend dpb only for internal or FAT32 devices */
@ -2185,9 +2137,6 @@ COUNT media_check(REG struct dpb FAR * dpbp)
#else
bpb_to_dpb(MediaReqHdr.r_bpptr, dpbp);
#endif
/* need to change to root directory if changed */
if (status == M_CHANGED)
CDSp[dpbp->dpb_unit].cdsCurrentPath[3] = '\0';
return SUCCESS;
}
}
@ -2249,7 +2198,7 @@ STATIC VOID shrink_file(f_node_ptr fnp)
next = next_cluster(dpbp, st);
if (next == LONG_LAST_CLUSTER) /* last cluster found */
if (next == 1 || next == LONG_LAST_CLUSTER) /* error last cluster found */
goto done;
/* Loop from start until either a FREE entry is */

View File

@ -36,38 +36,30 @@ static BYTE *RcsId =
#define FCB_SUCCESS 0
#define FCB_ERR_NODATA 1
#define FCB_ERR_SEGMENT_WRAP 2
#define FCB_ERR_EOF 3
#define FCB_ERR_WRITE 1
#define FCB_ERROR 0xff
#ifdef PROTO
fcb FAR *ExtFcbToFcb(xfcb FAR * lpExtFcb);
fcb FAR *CommonFcbInit(xfcb FAR * lpExtFcb, BYTE * pszBuffer,
STATIC fcb FAR *ExtFcbToFcb(xfcb FAR * lpExtFcb);
STATIC fcb FAR *CommonFcbInit(xfcb FAR * lpExtFcb, BYTE * pszBuffer,
COUNT * pCurDrive);
void FcbNameInit(fcb FAR * lpFcb, BYTE * pszBuffer, COUNT * pCurDrive);
VOID FcbNextRecord(fcb FAR * lpFcb);
BOOL FcbCalcRec(xfcb FAR * lpXfcb);
#else
fcb FAR *ExtFcbToFcb();
fcb FAR *CommonFcbInit();
void FcbNameInit();
VOID FcbNextRecord();
BOOL FcbCalcRec();
#endif
STATIC int FcbNameInit(fcb FAR * lpFcb, BYTE * pszBuffer, COUNT * pCurDrive);
STATIC void FcbNextRecord(fcb FAR * lpFcb);
STATIC void FcbCalcRec(xfcb FAR * lpXfcb);
#define TestCmnSeps(lpFileName) (strchr(":<|>+=,", *lpFileName) != NULL)
#define TestFieldSeps(lpFileName) (*(lpFileName) <= ' ' || strchr("/\"[]<>|.", *lpFileName) != NULL)
#define TestCmnSeps(lpFileName) (*lpFileName && strchr(":<|>+=,", *lpFileName) != NULL)
#define TestFieldSeps(lpFileName) ((unsigned char)*lpFileName <= ' ' || strchr("/\"[]<>|.", *lpFileName) != NULL)
static dmatch Dmatch;
VOID FatGetDrvData(UCOUNT drive, UCOUNT FAR * spc, UCOUNT FAR * bps,
UCOUNT FAR * nc, BYTE FAR ** mdp)
BYTE FAR *FatGetDrvData(UBYTE drive, UWORD * spc, UWORD * bps, UWORD * nc)
{
static BYTE mdb;
UCOUNT navc;
UWORD navc;
/* get the data available from dpb */
*nc = 0xffff; /* pass 0xffff to skip free count */
if (DosGetFree((UBYTE) drive, spc, &navc, bps, nc))
if (DosGetFree(drive, spc, &navc, bps, nc))
{
struct cds FAR *cdsp =
&CDSp[(drive == 0 ? default_drive : drive - 1)];
@ -75,14 +67,15 @@ VOID FatGetDrvData(UCOUNT drive, UCOUNT FAR * spc, UCOUNT FAR * bps,
if (cdsp->cdsFlags & CDSNETWDRV)
{
mdb = *spc >> 8;
*mdp = &mdb;
*spc &= 0xff;
return &mdb;
}
else
{
*mdp = (BYTE FAR *) & (cdsp->cdsDpb->dpb_mdb);
return (BYTE FAR *) & (cdsp->cdsDpb->dpb_mdb);
}
}
return NULL;
}
#define PARSE_SEP_STOP 0x01
@ -95,78 +88,81 @@ VOID FatGetDrvData(UCOUNT drive, UCOUNT FAR * spc, UCOUNT FAR * bps,
#define PARSE_RET_BADDRIVE 0xff
#ifndef IPL
WORD FcbParseFname(int wTestMode, const BYTE FAR ** lpFileName, fcb FAR * lpFcb)
UWORD FcbParseFname(int *wTestMode, const BYTE FAR * lpFileName, fcb FAR * lpFcb)
{
COUNT nIndex;
WORD wRetCodeName = FALSE, wRetCodeExt = FALSE;
const BYTE FAR * lpFileName2 = lpFileName;
/* pjv -- ExtFcbToFcb? */
/* Start out with some simple stuff first. Check if we are */
/* going to use a default drive specificaton. */
if (!(wTestMode & PARSE_DFLT_DRIVE))
if (!(*wTestMode & PARSE_DFLT_DRIVE))
lpFcb->fcb_drive = FDFLT_DRIVE;
if (!(wTestMode & PARSE_BLNK_FNAME))
if (!(*wTestMode & PARSE_BLNK_FNAME))
{
for (nIndex = 0; nIndex < FNAME_SIZE; ++nIndex)
lpFcb->fcb_fname[nIndex] = ' ';
fmemset(lpFcb->fcb_fname, ' ', FNAME_SIZE);
}
if (!(wTestMode & PARSE_BLNK_FEXT))
if (!(*wTestMode & PARSE_BLNK_FEXT))
{
for (nIndex = 0; nIndex < FEXT_SIZE; ++nIndex)
lpFcb->fcb_fext[nIndex] = ' ';
fmemset(lpFcb->fcb_fext, ' ', FEXT_SIZE);
}
/* Undocumented behavior, set record number & record size to 0 */
lpFcb->fcb_cublock = lpFcb->fcb_recsiz = 0;
if (!(wTestMode & PARSE_SEP_STOP))
if (!(*wTestMode & PARSE_SEP_STOP))
{
*lpFileName = ParseSkipWh(*lpFileName);
if (TestCmnSeps(*lpFileName))
++ * lpFileName;
lpFileName2 = ParseSkipWh(lpFileName2);
if (TestCmnSeps(lpFileName2))
++lpFileName2;
}
/* Undocumented "feature," we skip white space anyway */
*lpFileName = ParseSkipWh(*lpFileName);
lpFileName2 = ParseSkipWh(lpFileName2);
/* Now check for drive specification */
if (*(*lpFileName + 1) == ':')
if (*(lpFileName2 + 1) == ':')
{
/* non-portable construct to be changed */
REG UBYTE Drive = DosUpFChar(**lpFileName) - 'A';
REG UBYTE Drive = DosUpFChar(*lpFileName2) - 'A';
if (Drive >= lastdrive)
return PARSE_RET_BADDRIVE;
{
*wTestMode = PARSE_RET_BADDRIVE;
return lpFileName2 - lpFileName;
}
lpFcb->fcb_drive = Drive + 1;
*lpFileName += 2;
lpFileName2 += 2;
}
/* special cases: '.' and '..' */
if (**lpFileName == '.')
if (*lpFileName2 == '.')
{
lpFcb->fcb_fname[0] = '.';
++*lpFileName;
if (**lpFileName == '.')
++lpFileName2;
if (*lpFileName2 == '.')
{
lpFcb->fcb_fname[1] = '.';
++*lpFileName;
++lpFileName2;
}
return PARSE_RET_NOWILD;
*wTestMode = PARSE_RET_NOWILD;
return lpFileName2 - lpFileName;
}
/* Now to format the file name into the string */
*lpFileName =
GetNameField(*lpFileName, (BYTE FAR *) lpFcb->fcb_fname, FNAME_SIZE,
lpFileName2 =
GetNameField(lpFileName2, (BYTE FAR *) lpFcb->fcb_fname, FNAME_SIZE,
(BOOL *) & wRetCodeName);
/* Do we have an extension? If do, format it else return */
if (**lpFileName == '.')
*lpFileName =
GetNameField(++*lpFileName, (BYTE FAR *) lpFcb->fcb_fext,
if (*lpFileName2 == '.')
lpFileName2 =
GetNameField(++lpFileName2, (BYTE FAR *) lpFcb->fcb_fext,
FEXT_SIZE, (BOOL *) & wRetCodeExt);
return (wRetCodeName | wRetCodeExt) ? PARSE_RET_WILD : PARSE_RET_NOWILD;
*wTestMode = (wRetCodeName | wRetCodeExt) ? PARSE_RET_WILD : PARSE_RET_NOWILD;
return lpFileName2 - lpFileName;
}
const BYTE FAR * ParseSkipWh(const BYTE FAR * lpFileName)
@ -229,8 +225,7 @@ const BYTE FAR * GetNameField(const BYTE FAR * lpFileName, BYTE FAR * lpDestFiel
}
/* Blank out remainder of field on exit */
for (; nIndex < nFieldSize; ++nIndex)
*lpDestField++ = cFill;
fmemset(lpDestField, cFill, nFieldSize - nIndex);
return lpFileName;
}
@ -248,109 +243,55 @@ STATIC ULONG FcbRec(VOID)
return ((ULONG) lpFcb->fcb_cublock * 128) + lpFcb->fcb_curec;
}
BOOL FcbRead(xfcb FAR * lpXfcb, COUNT * nErrorCode, UCOUNT recno)
UBYTE FcbReadWrite(xfcb FAR * lpXfcb, UCOUNT recno, int mode)
{
sft FAR *s;
ULONG lPosit;
COUNT nRead;
UCOUNT nTransfer;
BYTE far * FcbIoPtr = dta + recno * lpFcb->fcb_recsiz;
if ((ULONG)recno * lpFcb->fcb_recsiz >= 0x10000ul ||
FP_OFF(FcbIoPtr) < FP_OFF(dta))
return FCB_ERR_SEGMENT_WRAP;
/* Convert to fcb if necessary */
lpFcb = ExtFcbToFcb(lpXfcb);
/* Get the SFT block that contains the SFT */
if ((s = idx_to_sft(lpFcb->fcb_sftno)) == (sft FAR *) - 1)
return FALSE;
return FCB_ERR_NODATA;
/* If this is not opened another error */
if (s->sft_count == 0)
return FALSE;
return FCB_ERR_NODATA;
/* Now update the fcb and compute where we need to position */
/* to. */
lPosit = FcbRec() * lpFcb->fcb_recsiz;
if (SftSeek(s, lPosit, 0) != SUCCESS)
{
*nErrorCode = FCB_ERR_EOF;
return FALSE;
}
if ((CritErrCode = -SftSeek(s, lPosit, 0)) != SUCCESS)
return FCB_ERR_NODATA;
/* Do the read */
nRead = DosReadSft(s, lpFcb->fcb_recsiz, FcbIoPtr, nErrorCode);
nTransfer = DosRWSft(s, lpFcb->fcb_recsiz, FcbIoPtr, &CritErrCode, mode);
CritErrCode = -CritErrCode;
/* Now find out how we will return and do it. */
if (nRead == lpFcb->fcb_recsiz)
if (nTransfer == lpFcb->fcb_recsiz)
{
*nErrorCode = FCB_SUCCESS;
if (mode == XFR_WRITE) lpFcb->fcb_fsize = s->sft_size;
FcbNextRecord(lpFcb);
return TRUE;
return FCB_SUCCESS;
}
else if (nRead < 0)
if (mode == XFR_READ && nTransfer > 0)
{
*nErrorCode = FCB_ERR_EOF;
return TRUE;
}
else if (nRead == 0)
{
*nErrorCode = FCB_ERR_NODATA;
return FALSE;
}
else
{
fmemset(FcbIoPtr + nRead, 0, lpFcb->fcb_recsiz - nRead);
*nErrorCode = FCB_ERR_EOF;
fmemset(FcbIoPtr + nTransfer, 0, lpFcb->fcb_recsiz - nTransfer);
FcbNextRecord(lpFcb);
return FALSE;
return FCB_ERR_EOF;
}
return FCB_ERR_NODATA;
}
BOOL FcbWrite(xfcb FAR * lpXfcb, COUNT * nErrorCode, UCOUNT recno)
{
sft FAR *s;
ULONG lPosit;
COUNT nWritten;
BYTE far * FcbIoPtr = dta + recno * lpFcb->fcb_recsiz;
/* Convert to fcb if necessary */
lpFcb = ExtFcbToFcb(lpXfcb);
/* Get the SFT block that contains the SFT */
if ((s = idx_to_sft(lpFcb->fcb_sftno)) == (sft FAR *) - 1)
return FALSE;
/* If this is not opened another error */
if (s->sft_count == 0)
return FALSE;
/* Now update the fcb and compute where we need to position */
/* to. */
lPosit = FcbRec() * lpFcb->fcb_recsiz;
if (SftSeek(s, lPosit, 0) != SUCCESS)
{
*nErrorCode = FCB_ERR_EOF;
return FALSE;
}
nWritten = DosWriteSft(s, lpFcb->fcb_recsiz, FcbIoPtr, nErrorCode);
/* Now find out how we will return and do it. */
if (nWritten == lpFcb->fcb_recsiz)
{
lpFcb->fcb_fsize = s->sft_size;
FcbNextRecord(lpFcb);
*nErrorCode = FCB_SUCCESS;
return TRUE;
}
else if (nWritten <= 0)
{
*nErrorCode = FCB_ERR_WRITE;
return TRUE;
}
*nErrorCode = FCB_ERR_WRITE;
return FALSE;
}
BOOL FcbGetFileSize(xfcb FAR * lpXfcb)
UBYTE FcbGetFileSize(xfcb FAR * lpXfcb)
{
COUNT FcbDrive, hndl;
@ -358,11 +299,10 @@ BOOL FcbGetFileSize(xfcb FAR * lpXfcb)
lpFcb = CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
/* check for a device */
if (IsDevice(SecPathName) || (lpFcb->fcb_recsiz == 0))
{
return FALSE;
}
hndl = DosOpen(SecPathName, O_RDONLY);
if (!lpFcb || IsDevice(SecPathName) || (lpFcb->fcb_recsiz == 0))
return FCB_ERROR;
hndl = (short)DosOpen(SecPathName, O_LEGACY | O_RDONLY | O_OPEN, 0);
if (hndl >= 0)
{
ULONG fsize;
@ -376,13 +316,15 @@ BOOL FcbGetFileSize(xfcb FAR * lpXfcb)
++lpFcb->fcb_rndm;
/* close the file and leave */
return DosClose(hndl) == SUCCESS;
if ((CritErrCode = -DosClose(hndl)) == SUCCESS)
return FCB_SUCCESS;
}
else
return FALSE;
CritErrCode = -hndl;
return FCB_ERROR;
}
BOOL FcbSetRandom(xfcb FAR * lpXfcb)
void FcbSetRandom(xfcb FAR * lpXfcb)
{
/* Convert to fcb if necessary */
lpFcb = ExtFcbToFcb(lpXfcb);
@ -390,11 +332,9 @@ BOOL FcbSetRandom(xfcb FAR * lpXfcb)
/* Now update the fcb and compute where we need to position */
/* to. */
lpFcb->fcb_rndm = FcbRec();
return TRUE;
}
BOOL FcbCalcRec(xfcb FAR * lpXfcb)
void FcbCalcRec(xfcb FAR * lpXfcb)
{
/* Convert to fcb if necessary */
@ -404,14 +344,12 @@ BOOL FcbCalcRec(xfcb FAR * lpXfcb)
/* to. */
lpFcb->fcb_cublock = lpFcb->fcb_rndm / 128;
lpFcb->fcb_curec = lpFcb->fcb_rndm & 127;
return TRUE;
}
BOOL FcbRandomBlockRead(xfcb FAR * lpXfcb, COUNT nRecords,
COUNT * nErrorCode)
UBYTE FcbRandomBlockIO(xfcb FAR * lpXfcb, COUNT nRecords, int mode)
{
UCOUNT recno = 0;
UBYTE nErrorCode;
FcbCalcRec(lpXfcb);
@ -419,39 +357,20 @@ BOOL FcbRandomBlockRead(xfcb FAR * lpXfcb, COUNT nRecords,
lpFcb = ExtFcbToFcb(lpXfcb);
do
FcbRead(lpXfcb, nErrorCode, recno++);
while ((--nRecords > 0) && (*nErrorCode == 0));
nErrorCode = FcbReadWrite(lpXfcb, recno++, mode);
while ((--nRecords > 0) && (nErrorCode == 0));
/* Now update the fcb */
lpFcb->fcb_rndm = FcbRec();
return TRUE;
return nErrorCode;
}
BOOL FcbRandomBlockWrite(xfcb FAR * lpXfcb, COUNT nRecords,
COUNT * nErrorCode)
{
UCOUNT recno = 0;
FcbCalcRec(lpXfcb);
/* Convert to fcb if necessary */
lpFcb = ExtFcbToFcb(lpXfcb);
do
FcbWrite(lpXfcb, nErrorCode, recno++);
while ((--nRecords > 0) && (*nErrorCode == 0));
/* Now update the fcb */
lpFcb->fcb_rndm = FcbRec();
return TRUE;
}
BOOL FcbRandomIO(xfcb FAR * lpXfcb, COUNT * nErrorCode, FcbFunc_t *FcbFunc)
UBYTE FcbRandomIO(xfcb FAR * lpXfcb, int mode)
{
UWORD uwCurrentBlock;
UBYTE ucCurrentRecord;
UBYTE nErrorCode;
FcbCalcRec(lpXfcb);
@ -461,39 +380,35 @@ BOOL FcbRandomIO(xfcb FAR * lpXfcb, COUNT * nErrorCode, FcbFunc_t *FcbFunc)
uwCurrentBlock = lpFcb->fcb_cublock;
ucCurrentRecord = lpFcb->fcb_curec;
(*FcbFunc) (lpXfcb, nErrorCode, 0);
nErrorCode = FcbReadWrite(lpXfcb, 0, mode);
lpFcb->fcb_cublock = uwCurrentBlock;
lpFcb->fcb_curec = ucCurrentRecord;
return TRUE;
return nErrorCode;
}
/* merged fcbOpen and FcbCreate - saves ~200 byte */
BOOL FcbOpenCreate(xfcb FAR * lpXfcb, BOOL Create)
UBYTE FcbOpen(xfcb FAR * lpXfcb, unsigned flags)
{
sft FAR *sftp;
COUNT sft_idx, FcbDrive;
unsigned attr = 0;
/* Build a traditional DOS file name */
lpFcb = CommonFcbInit(lpXfcb, PriPathName, &FcbDrive);
lpFcb = CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
if (lpFcb == NULL)
return FCB_ERROR;
if (Create)
{
if ((flags & O_CREAT) && lpXfcb->xfcb_flag == 0xff)
/* pass attribute without constraints (dangerous for directories) */
int attr = (lpXfcb->xfcb_flag == 0xff ? lpXfcb->xfcb_attrib : 0);
sft_idx = DosCreatSft(PriPathName, attr);
}
else
{
sft_idx = DosOpenSft(PriPathName, O_RDWR | SFT_MFCB);
/* if file is RDONLY, try to open rdonly */
if (sft_idx == DE_ACCESS)
sft_idx = DosOpenSft(PriPathName, O_RDONLY | SFT_MFCB);
}
attr = lpXfcb->xfcb_attrib;
sft_idx = (short)DosOpenSft(SecPathName, flags, attr);
if (sft_idx < 0)
return FALSE;
{
CritErrCode = -sft_idx;
return FCB_ERROR;
}
sftp = idx_to_sft(sft_idx);
sftp->sft_mode |= SFT_MFCB;
@ -511,7 +426,7 @@ BOOL FcbOpenCreate(xfcb FAR * lpXfcb, BOOL Create)
lpFcb->fcb_fsize = sftp->sft_size;
lpFcb->fcb_date = sftp->sft_date;
lpFcb->fcb_time = sftp->sft_time;
return TRUE;
return FCB_SUCCESS;
}
@ -532,13 +447,14 @@ STATIC fcb FAR *CommonFcbInit(xfcb FAR * lpExtFcb, BYTE * pszBuffer,
lpFcb = ExtFcbToFcb(lpExtFcb);
/* Build a traditional DOS file name */
FcbNameInit(lpFcb, pszBuffer, pCurDrive);
if (FcbNameInit(lpFcb, pszBuffer, pCurDrive) < SUCCESS)
return NULL;
/* and return the fcb pointer */
return lpFcb;
}
void FcbNameInit(fcb FAR * lpFcb, BYTE * szBuffer, COUNT * pCurDrive)
int FcbNameInit(fcb FAR * lpFcb, BYTE * szBuffer, COUNT * pCurDrive)
{
BYTE loc_szBuffer[2 + FNAME_SIZE + 1 + FEXT_SIZE + 1]; /* 'A:' + '.' + '\0' */
BYTE *pszBuffer = loc_szBuffer;
@ -556,85 +472,83 @@ void FcbNameInit(fcb FAR * lpFcb, BYTE * szBuffer, COUNT * pCurDrive)
*pCurDrive = default_drive + 1;
}
ConvertName83ToNameSZ(pszBuffer, (BYTE FAR *) lpFcb->fcb_fname);
truename(loc_szBuffer, szBuffer, FALSE);
/* XXX fix truename error handling */
return truename(loc_szBuffer, szBuffer, CDS_MODE_CHECK_DEV_PATH);
}
BOOL FcbDelete(xfcb FAR * lpXfcb)
UBYTE FcbDelete(xfcb FAR * lpXfcb)
{
COUNT FcbDrive;
UBYTE result = FCB_SUCCESS;
BYTE FAR *lpOldDta = dta;
/* Build a traditional DOS file name */
CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
/* check for a device */
if (IsDevice(SecPathName))
if (lpFcb == NULL || IsDevice(SecPathName))
{
return FALSE;
result = FCB_ERROR;
}
else
{
int attr = (lpXfcb->xfcb_flag == 0xff ? lpXfcb->xfcb_attrib : D_ALL);
BYTE FAR *lpOldDta = dta;
int attr = (lpXfcb->xfcb_flag == 0xff ? lpXfcb->xfcb_attrib : D_ALL);
dmatch Dmatch;
dta = (BYTE FAR *) & Dmatch;
if (DosFindFirst(attr, SecPathName) != SUCCESS)
if ((CritErrCode = -DosFindFirst(attr, SecPathName)) != SUCCESS)
{
dta = lpOldDta;
return FALSE;
result = FCB_ERROR;
}
do
else do
{
SecPathName[0] = 'A' + FcbDrive - 1;
SecPathName[1] = ':';
strcpy(&SecPathName[2], Dmatch.dm_name);
if (DosDelete(SecPathName, attr) != SUCCESS)
{
dta = lpOldDta;
return FALSE;
result = FCB_ERROR;
break;
}
}
while (DosFindNext() == SUCCESS);
dta = lpOldDta;
return TRUE;
while ((CritErrCode = -DosFindNext()) == SUCCESS);
}
dta = lpOldDta;
return result;
}
BOOL FcbRename(xfcb FAR * lpXfcb)
UBYTE FcbRename(xfcb FAR * lpXfcb)
{
rfcb FAR *lpRenameFcb;
COUNT FcbDrive;
UBYTE result = FCB_SUCCESS;
BYTE FAR *lpOldDta = dta;
/* Build a traditional DOS file name */
lpRenameFcb = (rfcb FAR *) CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
wAttr = (lpXfcb->xfcb_flag == 0xff ? lpXfcb->xfcb_attrib : D_ALL);
/* check for a device */
if (IsDevice(SecPathName))
if (lpRenameFcb == NULL || IsDevice(SecPathName))
{
return FALSE;
result = FCB_ERROR;
}
else
{
BYTE FAR *lpOldDta = dta;
dmatch Dmatch;
COUNT result;
wAttr = (lpXfcb->xfcb_flag == 0xff ? lpXfcb->xfcb_attrib : D_ALL);
dta = (BYTE FAR *) & Dmatch;
if (DosFindFirst(wAttr, SecPathName) != SUCCESS)
if ((CritErrCode = -DosFindFirst(wAttr, SecPathName)) != SUCCESS)
{
dta = lpOldDta;
return FALSE;
result = FCB_ERROR;
}
do
else do
{
fcb LocalFcb;
BYTE *pToName;
const BYTE FAR *pFromPattern = Dmatch.dm_name;
int i;
int i = 0;
FcbParseFname(0, &pFromPattern, &LocalFcb);
FcbParseFname(&i, pFromPattern, &LocalFcb);
/* Overlay the pattern, skipping '?' */
/* I'm cheating because this assumes that the */
/* struct alignments are on byte boundaries */
@ -651,22 +565,32 @@ BOOL FcbRename(xfcb FAR * lpXfcb)
SecPathName[0] = 'A' + FcbDrive - 1;
SecPathName[1] = ':';
strcpy(&SecPathName[2], Dmatch.dm_name);
truename(SecPathName, PriPathName, FALSE);
result = truename(SecPathName, PriPathName, 0);
if (result < SUCCESS || (result & IS_DEVICE))
{
result = FCB_ERROR;
break;
}
/* now to build a dos name again */
LocalFcb.fcb_drive = FcbDrive;
FcbNameInit((fcb FAR *) & LocalFcb, SecPathName, &FcbDrive);
result = FcbNameInit((fcb FAR *) & LocalFcb, SecPathName, &FcbDrive);
if (result < SUCCESS || (!(result & IS_NETWORK) && (result & IS_DEVICE)))
{
result = FCB_ERROR;
break;
}
if (DosRenameTrue(PriPathName, SecPathName, wAttr) != SUCCESS)
{
dta = lpOldDta;
return FALSE;
result = FCB_ERROR;
break;
}
}
while (DosFindNext() == SUCCESS);
dta = lpOldDta;
return TRUE;
while ((CritErrCode = -DosFindNext()) == SUCCESS);
}
dta = lpOldDta;
return result;
}
/* TE:the MoveDirInfo() is now done by simply copying the dirEntry into the FCB
@ -674,7 +598,7 @@ BOOL FcbRename(xfcb FAR * lpXfcb)
BO:use global SearchDir, as produced by FindFirst/Next
*/
BOOL FcbClose(xfcb FAR * lpXfcb)
UBYTE FcbClose(xfcb FAR * lpXfcb)
{
sft FAR *s;
@ -683,23 +607,23 @@ BOOL FcbClose(xfcb FAR * lpXfcb)
/* An already closed FCB can be closed again without error */
if (lpFcb->fcb_sftno == (BYTE) 0xff)
return TRUE;
return FCB_SUCCESS;
/* Get the SFT block that contains the SFT */
if ((s = idx_to_sft(lpFcb->fcb_sftno)) == (sft FAR *) - 1)
return FALSE;
return FCB_ERROR;
/* change time and set file size */
s->sft_size = lpFcb->fcb_fsize;
if (!(s->sft_flags & SFT_FSHARED))
dos_setfsize(s->sft_status, lpFcb->fcb_fsize);
DosSetFtimeSft(lpFcb->fcb_sftno, lpFcb->fcb_date, lpFcb->fcb_time);
if (DosCloseSft(lpFcb->fcb_sftno, FALSE) == SUCCESS)
if ((CritErrCode = -DosCloseSft(lpFcb->fcb_sftno, FALSE)) == SUCCESS)
{
lpFcb->fcb_sftno = (BYTE) 0xff;
return TRUE;
return FCB_SUCCESS;
}
return FALSE;
return FCB_ERROR;
}
/* close all files the current process opened by FCBs */
@ -713,7 +637,7 @@ VOID FcbCloseAll()
DosCloseSft(idx, FALSE);
}
BOOL FcbFindFirst(xfcb FAR * lpXfcb)
UBYTE FcbFindFirstNext(xfcb FAR * lpXfcb, BOOL First)
{
BYTE FAR *lpDir;
COUNT FcbDrive;
@ -726,31 +650,45 @@ BOOL FcbFindFirst(xfcb FAR * lpXfcb)
/* Next initialze local variables by moving them from the fcb */
lpFcb = CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
if (lpXfcb->xfcb_flag == 0xff)
if (lpFcb == NULL)
return FCB_ERROR;
/* Reconstrct the dirmatch structure from the fcb - doesn't hurt for first */
Dmatch.dm_drive = lpFcb->fcb_sftno;
fmemcpy(Dmatch.dm_name_pat, lpFcb->fcb_fname, FNAME_SIZE + FEXT_SIZE);
DosUpFMem((BYTE FAR *) Dmatch.dm_name_pat, FNAME_SIZE + FEXT_SIZE);
Dmatch.dm_attr_srch = wAttr;
Dmatch.dm_entry = lpFcb->fcb_strtclst;
Dmatch.dm_dircluster = lpFcb->fcb_dirclst;
wAttr = D_ALL;
if ((xfcb FAR *) lpFcb != lpXfcb)
{
wAttr = lpXfcb->xfcb_attrib;
fmemcpy(lpDir, lpXfcb, 7);
lpDir += 7;
}
else
wAttr = D_ALL;
if (DosFindFirst(wAttr, SecPathName) != SUCCESS)
CritErrCode = -(First ? DosFindFirst(wAttr, SecPathName) : DosFindNext());
if (CritErrCode != SUCCESS)
{
dta = lpPsp->ps_dta;
return FALSE;
return FCB_ERROR;
}
*lpDir++ = FcbDrive;
fmemcpy(lpDir, &SearchDir, sizeof(struct dirent));
lpFcb->fcb_dirclst = (UWORD) Dmatch.dm_dircluster;
lpFcb->fcb_strtclst = Dmatch.dm_entry;
/*
This is undocumented and seen using Pcwatch and Ramview.
The First byte is the current directory count and the second seems
to be the attribute byte.
This is undocumented and seen using Pcwatch and Ramview.
The First byte is the current directory count and the second seems
to be the attribute byte.
*/
lpFcb->fcb_sftno = Dmatch.dm_drive; /* MSD seems to save this @ fcb_date. */
#if 0
@ -758,66 +696,8 @@ BOOL FcbFindFirst(xfcb FAR * lpXfcb)
lpFcb->fcb_cublock *= 0x100;
lpFcb->fcb_cublock += wAttr;
#endif
dta = lpPsp->ps_dta;
return TRUE;
}
BOOL FcbFindNext(xfcb FAR * lpXfcb)
{
BYTE FAR *lpDir;
COUNT FcbDrive;
psp FAR *lpPsp = MK_FP(cu_psp, 0);
/* First, move the dta to a local and change it around to match */
/* our functions. */
lpDir = (BYTE FAR *) dta;
dta = (BYTE FAR *) & Dmatch;
/* Next initialze local variables by moving them from the fcb */
lpFcb = CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
/* Reconstrct the dirmatch structure from the fcb */
Dmatch.dm_drive = lpFcb->fcb_sftno;
fmemcpy(Dmatch.dm_name_pat, lpFcb->fcb_fname, FNAME_SIZE + FEXT_SIZE);
DosUpFMem((BYTE FAR *) Dmatch.dm_name_pat, FNAME_SIZE + FEXT_SIZE);
Dmatch.dm_attr_srch = wAttr;
Dmatch.dm_entry = lpFcb->fcb_strtclst;
Dmatch.dm_dircluster = lpFcb->fcb_dirclst;
if ((xfcb FAR *) lpFcb != lpXfcb)
{
wAttr = lpXfcb->xfcb_attrib;
fmemcpy(lpDir, lpXfcb, 7);
lpDir += 7;
}
else
wAttr = D_ALL;
if (DosFindNext() != SUCCESS)
{
dta = lpPsp->ps_dta;
CritErrCode = 0x12;
return FALSE;
}
*lpDir++ = FcbDrive;
fmemcpy((struct dirent FAR *)lpDir, &SearchDir, sizeof(struct dirent));
lpFcb->fcb_dirclst = (UWORD) Dmatch.dm_dircluster;
lpFcb->fcb_strtclst = Dmatch.dm_entry;
lpFcb->fcb_sftno = Dmatch.dm_drive;
#if 0
lpFcb->fcb_cublock = Dmatch.dm_entry;
lpFcb->fcb_cublock *= 0x100;
lpFcb->fcb_cublock += wAttr;
#endif
dta = lpPsp->ps_dta;
return TRUE;
return FCB_SUCCESS;
}
#endif

View File

@ -307,15 +307,7 @@ extern struct /* Path name parsing buffer */
BYTE _PriPathName[128];
} ASM _PriPathBuffer;
extern struct {
BYTE _fname[FNAME_SIZE];
BYTE _fext[FEXT_SIZE + 1]; /* space for 0 */
} ASM szNames;
#define PriPathName _PriPathBuffer._PriPathName
#define szDirName TempCDS.cdsCurrentPath
#define szFileName szNames._fname
#define szFileExt szNames._fext
extern struct /* Alternate path name parsing buffer */
{
@ -440,25 +432,15 @@ COUNT con();
#define fputword(vp, w) (*(UWORD FAR *)(vp)=w)
#define fputbyte(vp, b) (*(UBYTE FAR *)(vp)=b)
#else
#ifdef PROTO
WORD getword(VOID *);
BYTE getbyte(VOID *);
LONG fgetlong(VOID FAR *);
WORD fgetword(VOID FAR *);
BYTE fgetbyte(VOID FAR *);
UDWORD getlong(VOID *);
UWORD getword(VOID *);
UBYTE getbyte(VOID *);
UDWORD fgetlong(VOID FAR *);
UWORD fgetword(VOID FAR *);
UBYTE fgetbyte(VOID FAR *);
VOID fputlong(VOID FAR *, UDWORD);
VOID fputword(VOID FAR *, UWORD);
VOID fputbyte(VOID FAR *, UBYTE);
#else
VOID getword();
VOID getbyte();
VOID fgetlong();
VOID fgetword();
VOID fgetbyte();
VOID fputlong();
VOID fputword();
VOID fputbyte();
#endif
#endif
#ifdef I86

View File

@ -20,7 +20,13 @@ extern __segment DosTextSeg;
#define DOSFAR FAR
#define DOSTEXTFAR FAR
#elif !defined(I86)
#define DOSFAR
#define DOSTEXTFAR
#else
#pragma error("unknown compiler - please adjust")
this should simply not compile ! !
#endif

View File

@ -106,7 +106,7 @@ IntDosCal:
; UWORD ip,cs,flags;
; UWORD callerARG1;
;};
Protect386Registers
Protect386Registers
push ax
push cx
push dx
@ -131,7 +131,7 @@ IntDosCal:
pop dx
pop cx
pop ax
Restore386Registers
Restore386Registers
iret
@ -255,6 +255,11 @@ _QRemote_Fn
global _remote_printredir
_remote_printredir:
mov al, 25h
jmp short call_int2f
global _remote_extopen
_remote_extopen:
mov al, 2eh
call_int2f:
mov ah, 11h
@ -263,7 +268,6 @@ call_int2f:
push es
push si
push di
push dx
push cx
push bx
@ -275,10 +279,6 @@ call_int2f:
je print_doredir
cmp al, 1fh
je print_doredir
cmp al, 21h ; 21h, Lseek from eof
je lseekeof
cmp al, 23h
je qremote_fn
cmp al, 25h
je remote_printredir
@ -289,22 +289,27 @@ call_int2f:
je remote_rw
cmp al, 0ch
je remote_getfree
cmp al, 21h ; 21h, Lseek from eof
je lseekeof
cmp al, 23h
je qremote_fn
int2f_call_push:
push word [bp+8] ; very fakey, HaHa ;)
int2f_call:
clc ; set to succeed
xor cx, cx ; set to succeed; clear carry and CX
int 2fh
pop bx
jc no_clear_ax
clear_ax:
xor ax,ax
mov ax, cx ; extended open -> status from CX in AX
; otherwise CX was set to zero above
jmp short no_neg_ax
no_clear_ax:
neg ax
no_neg_ax:
pop bx
pop cx
pop dx
pop di
pop si
pop es
@ -314,8 +319,8 @@ no_neg_ax:
lseekeof:
mov dx, [bp+8]
mov cx, [bp+10]
jmp int2f_call_push
; "fall through"
remote_getfattr:
clc ; set to succeed
int 2fh
@ -358,17 +363,20 @@ remote_printredir:
mov dx, [bp+4]
push word [bp+6]
jmp short int2f_call
remote_rw: jmp short remote_rw1
qremote_fn:
lds si,[bp+4]
les di,[bp+8]
qremote_fn:
push ds
lds si,[bp+8]
clc
int 2fh
pop ds
mov ax,0xffff
jc no_neg_ax
jmp short clear_ax
remote_rw: mov cx, [bp+8]
remote_rw1: mov cx, [bp+8]
clc ; set to succeed
int 2fh
jc int2f_carry
@ -377,7 +385,7 @@ int2f_carry: neg ax
mov di, [bp+10]
mov [di], ax
mov ax, cx
jmp short no_neg_ax
jmp no_neg_ax
global _remote_process_end
_remote_process_end: ; Terminate process

File diff suppressed because it is too large Load Diff

View File

@ -54,7 +54,7 @@ static BYTE *RcsId =
*/
COUNT DosDevIOctl(iregs FAR * r)
COUNT DosDevIOctl(lregs * r)
{
sft FAR *s;
struct dpb FAR *dpbp;
@ -78,10 +78,106 @@ COUNT DosDevIOctl(iregs FAR * r)
case 0x07:
case 0x0a:
case 0x0c:
case 0x10:
/* Get the SFT block that contains the SFT */
if ((s = get_sft(r->BX)) == (sft FAR *) - 1)
return DE_INVLDHNDL;
switch (r->AL)
{
case 0x00:
/* Get the flags from the SFT */
if (s->sft_flags & SFT_FDEVICE)
r->AX = (s->sft_dev->dh_attr & 0xff00) | s->sft_flags_lo;
else
r->AX = s->sft_flags;
/* Undocumented result, Ax = Dx seen using Pcwatch */
r->DX = r->AX;
break;
case 0x01:
/* sft_flags is a file, return an error because you */
/* can't set the status of a file. */
if (!(s->sft_flags & SFT_FDEVICE))
return DE_INVLDFUNC;
/* Set it to what we got in the DL register from the */
/* user. */
r->AL = s->sft_flags_lo = SFT_FDEVICE | r->DL;
break;
case 0x02:
nMode = C_IOCTLIN;
goto IoCharCommon;
case 0x03:
nMode = C_IOCTLOUT;
goto IoCharCommon;
case 0x06:
if (s->sft_flags & SFT_FDEVICE)
r->AL = s->sft_flags & SFT_FEOF ? 0xFF : 0;
else
r->AL = s->sft_posit >= s->sft_size ? 0xFF : 0;
break;
case 0x07:
if (s->sft_flags & SFT_FDEVICE)
{
nMode = C_OSTAT;
goto IoCharCommon;
}
r->AL = 0;
break;
case 0x0a:
r->DX = s->sft_flags;
r->AX = 0;
break;
case 0x0c:
nMode = C_GENIOCTL;
goto IoCharCommon;
case 0x10:
nMode = C_IOCTLQRY;
IoCharCommon:
if ((s->sft_flags & SFT_FDEVICE)
|| ((r->AL == 0x02) && (s->sft_dev->dh_attr & SFT_FIOCTL))
|| ((r->AL == 0x03) && (s->sft_dev->dh_attr & SFT_FIOCTL))
|| ((r->AL == 0x10) && (s->sft_dev->dh_attr & ATTR_QRYIOCTL))
|| ((r->AL == 0x0c) && (s->sft_dev->dh_attr & ATTR_GENIOCTL)))
{
CharReqHdr.r_unit = 0;
CharReqHdr.r_command = nMode;
execrh((request FAR *) & CharReqHdr, s->sft_dev);
if (CharReqHdr.r_status & S_ERROR)
{
CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13;
return DE_DEVICE;
}
if (r->AL == 0x07)
{
r->AL = CharReqHdr.r_status & S_BUSY ? 00 : 0xff;
}
else if (r->AL == 0x02 || r->AL == 0x03)
{
r->AX = CharReqHdr.r_count;
}
else if (r->AL == 0x0c || r->AL == 0x10)
{
r->AX = CharReqHdr.r_status;
}
break;
}
/* fall through */
default:
return DE_INVLDFUNC;
}
break;
case 0x04:
@ -91,7 +187,6 @@ COUNT DosDevIOctl(iregs FAR * r)
case 0x0d:
case 0x0e:
case 0x0f:
case 0x10:
case 0x11:
/*
@ -113,222 +208,125 @@ COUNT DosDevIOctl(iregs FAR * r)
/* cdsp = &CDSp[CharReqHdr.r_unit]; */
dpbp = CDSp[CharReqHdr.r_unit].cdsDpb;
}
break;
switch (r->AL)
{
case 0x04:
nMode = C_IOCTLIN;
goto IoBlockCommon;
case 0x05:
nMode = C_IOCTLOUT;
goto IoBlockCommon;
case 0x08:
if (!dpbp)
{
return DE_INVLDDRV;
}
if (dpbp->dpb_device->dh_attr & ATTR_EXCALLS)
{
nMode = C_REMMEDIA;
goto IoBlockCommon;
}
return DE_INVLDFUNC;
case 0x09:
if (CDSp[CharReqHdr.r_unit].cdsFlags & CDSNETWDRV)
{
r->DX = ATTR_REMOTE;
r->AX = S_DONE | S_BUSY;
}
else
{
if (!dpbp)
{
return DE_INVLDDRV;
}
/* Need to add subst bit 15 */
r->DX = dpbp->dpb_device->dh_attr;
r->AX = S_DONE | S_BUSY;
}
break;
case 0x0d:
nMode = C_GENIOCTL;
goto IoBlockCommon;
case 0x11:
nMode = C_IOCTLQRY;
IoBlockCommon:
if (!dpbp)
{
return DE_INVLDDRV;
}
if (((r->AL == 0x04) && !(dpbp->dpb_device->dh_attr & ATTR_IOCTL))
|| ((r->AL == 0x05) && !(dpbp->dpb_device->dh_attr & ATTR_IOCTL))
|| ((r->AL == 0x11)
&& !(dpbp->dpb_device->dh_attr & ATTR_QRYIOCTL))
|| ((r->AL == 0x0d)
&& !(dpbp->dpb_device->dh_attr & ATTR_GENIOCTL)))
{
return DE_INVLDFUNC;
}
CharReqHdr.r_command = nMode;
execrh((request FAR *) & CharReqHdr, dpbp->dpb_device);
if (CharReqHdr.r_status & S_ERROR)
{
CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13;
return DE_DEVICE;
}
if (r->AL == 0x08)
{
r->AX = (CharReqHdr.r_status & S_BUSY) ? 1 : 0;
}
else if (r->AL == 0x04 || r->AL == 0x05)
{
r->AX = CharReqHdr.r_count;
}
else if (r->AL == 0x0d || r->AL == 0x11)
{
r->AX = CharReqHdr.r_status;
}
break;
case 0x0e:
nMode = C_GETLDEV;
goto IoLogCommon;
case 0x0f:
nMode = C_SETLDEV;
IoLogCommon:
if (!dpbp)
{
return DE_INVLDDRV;
}
if ((dpbp->dpb_device->dh_attr & ATTR_GENIOCTL))
{
CharReqHdr.r_command = nMode;
execrh((request FAR *) & CharReqHdr, dpbp->dpb_device);
if (CharReqHdr.r_status & S_ERROR)
{
CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13;
return DE_ACCESS;
}
else
{
r->AL = CharReqHdr.r_unit;
return SUCCESS;
}
} /* fall through */
default:
return DE_INVLDFUNC;
}
break;
case 0x0b:
/* skip, it's a special case. */
NetDelay = r->CX;
if (!r->DX)
NetRetry = r->DX;
break;
default:
return DE_INVLDFUNC;
}
switch (r->AL)
{
case 0x00:
/* Get the flags from the SFT */
if (s->sft_flags & SFT_FDEVICE)
r->AX = (s->sft_dev->dh_attr & 0xff00) | s->sft_flags_lo;
else
r->AX = s->sft_flags;
/* Undocumented result, Ax = Dx seen using Pcwatch */
r->DX = r->AX;
break;
case 0x01:
/* sft_flags is a file, return an error because you */
/* can't set the status of a file. */
if (!(s->sft_flags & SFT_FDEVICE))
return DE_INVLDFUNC;
/* Set it to what we got in the DL register from the */
/* user. */
r->AL = s->sft_flags_lo = SFT_FDEVICE | r->DL;
break;
case 0x0c:
nMode = C_GENIOCTL;
goto IoCharCommon;
case 0x02:
nMode = C_IOCTLIN;
goto IoCharCommon;
case 0x10:
nMode = C_IOCTLQRY;
goto IoCharCommon;
case 0x03:
nMode = C_IOCTLOUT;
IoCharCommon:
if ((s->sft_flags & SFT_FDEVICE)
|| ((r->AL == 0x02) && (s->sft_dev->dh_attr & SFT_FIOCTL))
|| ((r->AL == 0x03) && (s->sft_dev->dh_attr & SFT_FIOCTL))
|| ((r->AL == 0x10) && (s->sft_dev->dh_attr & ATTR_QRYIOCTL))
|| ((r->AL == 0x0c) && (s->sft_dev->dh_attr & ATTR_GENIOCTL)))
{
CharReqHdr.r_unit = 0;
CharReqHdr.r_command = nMode;
execrh((request FAR *) & CharReqHdr, s->sft_dev);
if (CharReqHdr.r_status & S_ERROR)
{
CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13;
return DE_DEVICE;
}
if (r->AL == 0x07)
{
r->AL = CharReqHdr.r_status & S_BUSY ? 00 : 0xff;
}
else if (r->AL == 0x02 || r->AL == 0x03)
{
r->AX = CharReqHdr.r_count;
}
else if (r->AL == 0x0c || r->AL == 0x10)
{
r->AX = CharReqHdr.r_status;
}
break;
}
return DE_INVLDFUNC;
case 0x0d:
nMode = C_GENIOCTL;
goto IoBlockCommon;
case 0x04:
nMode = C_IOCTLIN;
goto IoBlockCommon;
case 0x11:
nMode = C_IOCTLQRY;
goto IoBlockCommon;
case 0x05:
nMode = C_IOCTLOUT;
IoBlockCommon:
if (!dpbp)
{
return DE_INVLDDRV;
}
if (((r->AL == 0x04) && !(dpbp->dpb_device->dh_attr & ATTR_IOCTL))
|| ((r->AL == 0x05) && !(dpbp->dpb_device->dh_attr & ATTR_IOCTL))
|| ((r->AL == 0x11)
&& !(dpbp->dpb_device->dh_attr & ATTR_QRYIOCTL))
|| ((r->AL == 0x0d)
&& !(dpbp->dpb_device->dh_attr & ATTR_GENIOCTL)))
{
return DE_INVLDFUNC;
}
CharReqHdr.r_command = nMode;
execrh((request FAR *) & CharReqHdr, dpbp->dpb_device);
if (CharReqHdr.r_status & S_ERROR)
{
CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13;
return DE_DEVICE;
}
if (r->AL == 0x08)
{
r->AX = (CharReqHdr.r_status & S_BUSY) ? 1 : 0;
}
else if (r->AL == 0x04 || r->AL == 0x05)
{
r->AX = CharReqHdr.r_count;
}
else if (r->AL == 0x0d || r->AL == 0x11)
{
r->AX = CharReqHdr.r_status;
}
break;
case 0x06:
if (s->sft_flags & SFT_FDEVICE)
{
r->AL = s->sft_flags & SFT_FEOF ? 0xFF : 0;
}
else
r->AL = s->sft_posit >= s->sft_size ? 0xFF : 0;
break;
case 0x07:
if (s->sft_flags & SFT_FDEVICE)
{
nMode = C_OSTAT;
goto IoCharCommon;
}
r->AL = 0;
break;
case 0x08:
if (!dpbp)
{
return DE_INVLDDRV;
}
if (dpbp->dpb_device->dh_attr & ATTR_EXCALLS)
{
nMode = C_REMMEDIA;
goto IoBlockCommon;
}
return DE_INVLDFUNC;
case 0x09:
if (CDSp[CharReqHdr.r_unit].cdsFlags & CDSNETWDRV)
{
r->DX = ATTR_REMOTE;
r->AX = S_DONE | S_BUSY;
}
else
{
if (!dpbp)
{
return DE_INVLDDRV;
}
/* Need to add subst bit 15 */
r->DX = dpbp->dpb_device->dh_attr;
r->AX = S_DONE | S_BUSY;
}
break;
case 0x0a:
r->DX = s->sft_flags;
r->AX = 0;
break;
case 0x0e:
nMode = C_GETLDEV;
goto IoLogCommon;
case 0x0f:
nMode = C_SETLDEV;
IoLogCommon:
if (!dpbp)
{
return DE_INVLDDRV;
}
if ((dpbp->dpb_device->dh_attr & ATTR_GENIOCTL))
{
CharReqHdr.r_command = nMode;
execrh((request FAR *) & CharReqHdr, dpbp->dpb_device);
if (CharReqHdr.r_status & S_ERROR)
{
CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13;
return DE_ACCESS;
}
else
{
r->AL = CharReqHdr.r_unit;
return SUCCESS;
}
}
return DE_INVLDFUNC;
default:
return DE_INVLDFUNC;
}

View File

@ -457,7 +457,6 @@ STATIC void kernel()
fmemcpy(p, insertString, 3);
Cmd.ctCount += 3;
printf("%d %s\n", Cmd.ctCount, Cmd.ctBuffer);
break;
}
}

View File

@ -74,13 +74,13 @@ int DosMkTmp(BYTE FAR * pathname, UWORD attr)
{
/* create filename from current date and time */
char FAR *ptmp = pathname;
BYTE wd, month, day;
BYTE h, m, s, hund;
WORD sh;
WORD year;
UBYTE wd, month, day;
UBYTE h, m, s, hund;
UWORD sh;
UWORD year;
int rc;
char name83[13];
int loop;
int loop = 0;
while (*ptmp)
ptmp++;
@ -88,52 +88,153 @@ int DosMkTmp(BYTE FAR * pathname, UWORD attr)
if (ptmp == pathname || (ptmp[-1] != '\\' && ptmp[-1] != '/'))
*ptmp++ = '\\';
DosGetDate(&wd, &month, &day, (COUNT FAR *) & year);
DosGetDate(&wd, &month, &day, &year);
DosGetTime(&h, &m, &s, &hund);
sh = s * 100 + hund;
for (loop = 0; loop < 0xfff; loop++)
{
do {
sprintf(name83, "%x%x%x%x%x%03x.%03x",
year & 0xf, month & 0xf, day & 0xf, h & 0xf, m & 0xf,
sh & 0xfff, loop & 0xfff);
fmemcpy(ptmp, name83, 13);
if ((rc = DosOpen(pathname, 0)) < 0 && rc != DE_ACCESS /* subdirectory ?? */
/* todo: sharing collision on
network drive
*/
)
break;
/* only create new file -- 2001/09/22 ska*/
rc = (short)DosOpen(pathname, O_LEGACY | O_CREAT | O_RDWR, attr);
} while (rc == DE_FILEEXISTS && loop++ < 0xfff);
if (rc >= 0)
DosClose(rc);
}
if (rc == DE_FILENOTFND)
{
rc = DosCreat(pathname, attr);
}
return rc;
}
COUNT get_verify_drive(char FAR * src)
#ifdef DEBUG
#define DEBUG_TRUENAME
#endif
#define drLetterToNr(dr) ((dr) - 'A')
/* Convert an uppercased drive letter into the drive index */
#define drNrToLetter(dr) ((dr) + 'A')
/* the other direction */
/* In DOS there are no free-standing UNC paths, therefore there
is always a logical drive letter associated with a path
spec. This letter is also the index into the CDS */
COUNT get_verify_drive(const char FAR * src)
{
UBYTE drive;
unsigned flags;
/* Do we have a drive? */
if (src[1] == ':')
drive = ((src[0] - 1) | 0x20) - ('a' - 1);
else
return default_drive;
if (drive < lastdrive && CDSp[drive].cdsFlags & CDSVALID)
return drive;
drive = drLetterToNr(DosUpFChar(src[0]));
else
drive = default_drive;
if (drive >= lastdrive)
return DE_INVLDDRV;
/* Entry is disabled or JOINed drives are accessable by the path only */
flags = CDSp[drive].cdsFlags;
if ((flags & CDSMODEMASK) == 0 || (flags & CDSJOINED) != 0)
return DE_INVLDDRV;
return drive;
}
/*
Definition of functions for the handling of the Current
Directory Structure.
MUX-11-23: Qualify Remote Filename
DOS-0x60 calls this MUX functions to let the Network Redirector
qualify the filename. According INTRSPY MS DOS 6 does not pre-
process the passed in filename in any way (see attached transcripts).
The DOS-60 interface TRUENAME looks like this:
DosTruename(src, dest) {
if (MUX-11-23(src, dest) != Error)
return SUCCESS
return local_truename(src, dest);
}
The CDS has the following entries:
char cdsPath[CDSPATHLEN];
The fully-qualified current working directory of this drive.
The format is DOS <dr>:\[<path>{\<path>}]
or UNC \<id>\[<path>{\<path>}].
The drive <dr> indicates the physical drive letter and is the
index into the blk_device[].
UWORD cdsFlags;
Indicates what kind this logical drive is:
NETWORK: drive is NOT local \ If both are set, drive is IFS
PHYSICAL: drive is local / If none is set, drive is non-existant
JOIN: drive is joined in as the path cdsPath. This Flag uses the
index into the CDS table to indicate the physical drive.
SUBST: drive substitutes the path cdsPath.
HIDDEN: drive is not included into the redirector's list.
struct dpb FAR *cdsDpb;
Pointer to the DPB driving the physical drive. In DOS-C, the physical
drive letter is the index into the DPB[]. But for compatibly reason
this field will be set correctly.
UWORD cdsStartCluster;
For local drives only: This holds the cluster number of
the start of the current working directory of this
logical drive. If 0000h, it's the root directory; if
0ffffh, the drive was never accessed and has to be read
again.
void FAR *cdsIFSrecord;
UWORD cdsIFSparameter;
For networked drives only: Holds pointer/parameters to/for IFS
driver. (Well, I don't know.)
UWORD cdsPathOff;
Number of characters of the cdsPath[], which are hidden. The
logical path is combined by the logical drive letter and the
cdsPath[] part, which is not hidden.
IFS FAR *cdsIFSdrv;
Will be zeroed for local drives.
Revision 1.2 1995/12/03 22:17:41 ska
bugfix: Scanning of file name in 8.3 failed on "." and on longer names.
Revision 1.1 1995/11/09 07:43:30 ska
#
*/
#define PATH_ERROR goto errRet
#define PATHLEN 128
/* Map a logical path into a physical one.
1) Uppercasing path.
2) Flipping '/' -> '\\'.
3) Removing empty directory components & ".".
4) Processing ".." components.
5) Convert path components into 8.3 convention.
6) Make it fully-qualified.
7) Map it to SUBST/UNC.
8) Map to JOIN.
Return:
*cdsItem will be point to the appropriate CDS entry. This will allow
the caller to aquire the DPB or the IFS informtion of this entry.
error number
Return value:
DE_FILENOTFND, or DE_PATHNOTFND (as described in RBIL)
If the output path pnfo->physPath exceeds the length MAX_PATH, the error
DE_FILENOTFND will be returned.
*/
/*
* Added support for external and internal calls.
* Clean buffer before use. Make the true path and expand file names.
@ -157,27 +258,127 @@ COUNT get_verify_drive(char FAR * src)
*/
COUNT truename(char FAR * src, char FAR * dest, COUNT t)
#ifdef DEBUG_TRUENAME
#define tn_printf(x) printf x
#else
#define tn_printf(x)
#endif
#define PNE_WILDCARD 1
#define PNE_DOT 2
#define addChar(c) \
{ \
if (p - dest >= SFTMAX) PATH_ERROR; /* path too long */ \
*p++ = c; \
}
/* helper for truename: parses either name or extension */
STATIC int parse_name_ext(int i, const char FAR **src, char **cp, char *dest)
{
static char buf[128] = "A:\\\0\0\0\0\0\0\0\0\0";
char *bufp = buf + 3;
COUNT i, rootEndPos = 2; /* renamed x to rootEndPos - Ron Cemer */
int retval = SUCCESS;
char *p = *cp;
char c;
while(1) switch(c=*(*src)++)
{
case '.':
retval |= PNE_DOT;
/* fall through */
case '/':
case '\\':
case '\0':
*cp = p;
return retval;
case '*':
retval |= PNE_WILDCARD;
/* register the wildcard, even if no '?' is appended */
if (i) do
{
addChar('?');
} while(--i);
/** Alternative implementation:
if (i)
{
if (dest + SFTMAX - *p < i)
PATH_ERROR;
fmemset(p, '?', i);
p += i;
} **/
break;
case '?':
retval |= PNE_WILDCARD;
/* fall through */
default:
if (i) { /* name length in limits */
--i;
addChar(c);
}
}
errRet:
return -1;
}
COUNT truename(const char FAR * src, char * dest, COUNT mode)
{
COUNT i;
struct dhdr FAR *dhp;
BYTE FAR *froot;
WORD d;
const char FAR *froot;
COUNT result;
int gotAnyWildcards = 0;
struct cds FAR *cdsEntry;
char *p = dest; /* dynamic pointer into dest */
char *rootPos;
enum { DONT_ADD, ADD, ADD_UNLESS_LAST } addSep;
dest[0] = '\0';
i = get_verify_drive(src);
if (i < 0)
return DE_INVLDDRV;
buf[0] = i + 'A';
buf[1] = ':'; /* Just to be sure */
tn_printf(("truename(%S)\n", src));
/* First, adjust the source pointer */
src = adjust_far(src);
/* In opposite of the TRUENAME shell command, an empty string is
rejected by MS DOS 6 */
if (src[0] == '\0')
return DE_FILENOTFND;
result = get_verify_drive(src);
if (result < SUCCESS)
return result;
cdsEntry = &CDSp[result];
tn_printf(("CDS entry: #%u @%p (%u) '%S'\n", result, cdsEntry,
cdsEntry->cdsBackslashOffset, cdsEntry->cdsCurrentPath));
/* is the current_ldt thing necessary for compatibly??
-- 2001/09/03 ska*/
current_ldt = cdsEntry;
if (cdsEntry->cdsFlags & CDSNETWDRV)
result |= IS_NETWORK;
dhp = IsDevice(src);
if (dhp)
result |= IS_DEVICE;
/* Try if the Network redirector wants to do it */
dest[0] = '\0'; /* better probable for sanity check below --
included by original truename() */
/* MUX succeeded and really something */
if (QRemote_Fn(dest, src) && dest[0] != '\0')
{
tn_printf(("QRemoteFn() returned: \"%S\"\n", dest));
#ifdef DEBUG_TRUENAME
if (strlen(dest) >= SFTMAX)
panic("Truename: QRemote_Fn() overflowed output buffer");
#endif
if (dest[2] == '/' && (result & IS_DEVICE))
result &= ~IS_NETWORK;
return result;
}
/* Redirector interface failed --> proceed with local mapper */
dest[0] = drNrToLetter(result & 0x1f);
dest[1] = ':';
/* Do we have a drive? */
if (src[1] == ':')
src += 2;
@ -188,344 +389,320 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
*/
/* check for a device */
if ((*src != '.') && (*src != '\\') && (*src != '/')
&& ((dhp = IsDevice(src)) != NULL))
dest[2] = '\\';
if (result & IS_DEVICE)
{
froot = get_root(src);
/* /// Bugfix: NUL.LST is the same as NUL. This is true for all
devices. On a device name, the extension is irrelevant
as long as the name matches.
- Ron Cemer */
buf[2] = '/';
/* /// Bug: should be only copying up to first space.
- Ron Cemer */
for (d = 0;
d < FNAME_SIZE && dhp->dh_name[d] != 0 && dhp->dh_name[d] != ' ';
d++)
*bufp++ = dhp->dh_name[d];
/* /// DOS will return C:/NUL.LST if you pass NUL.LST in.
DOS will also return C:/NUL.??? if you pass NUL.* in.
Code added here to support this.
- Ron Cemer */
while ((*froot != '.') && (*froot != '\0'))
froot++;
if (*froot)
froot++;
if (*froot)
if (froot == src || froot == src + 5)
{
*bufp++ = '.';
for (i = 0; i < FEXT_SIZE; i++)
if (froot == src + 5)
{
if ((*froot == '\0') || (*froot == '.'))
break;
if (*froot == '*')
{
for (; i < FEXT_SIZE; i++)
*bufp++ = '?';
break;
}
*bufp++ = *froot++;
fmemcpy(dest + 3, src, 5);
DosUpMem(dest + 3, 5);
if (dest[3] == '/') dest[3] = '\\';
if (dest[7] == '/') dest[7] = '\\';
}
if (froot == src || memcmp(dest + 3, "\\DEV\\", 5) == 0)
{
/* /// Bugfix: NUL.LST is the same as NUL. This is true for all
devices. On a device name, the extension is irrelevant
as long as the name matches.
- Ron Cemer */
dest[2] = '/';
result &= ~IS_NETWORK;
/* /// DOS will return C:/NUL.LST if you pass NUL.LST in.
DOS will also return C:/NUL.??? if you pass NUL.* in.
Code added here to support this.
- Ron Cemer */
src = froot;
}
}
/* /// End of code additions. - Ron Cemer */
goto exit_tn;
}
/* /// Added to adjust for filenames which begin with ".\"
* The problem was manifesting itself in the inability
* to run an program whose filename (without the extension)
* was longer than six characters and the PATH variable
* contained ".", unless you explicitly specified the full
* path to the executable file.
* Jun 11, 2000 - rbc */
/* /// Changed to "while" from "if". - Ron Cemer */
while ((src[0] == '.') && (src[1] == '\\'))
src += 2;
current_ldt = &CDSp[i];
/* Always give the redirector a chance to rewrite the filename */
fmemcpy(bufp - 1, src, sizeof(buf) - (bufp - buf));
if ((t == FALSE) && (QRemote_Fn(buf, dest) == SUCCESS)
&& (dest[0] != '\0'))
/* Make fully-qualified logical path */
/* register these two used characters and the \0 terminator byte */
/* we always append the current dir to stat the drive;
the only exceptions are devices without paths */
rootPos = p = dest + 2;
if (*p != '/') /* i.e., it's a backslash! */
{
return SUCCESS;
}
else
{
bufp[-1] = '\\';
}
if (t == FALSE)
{
fmemcpy(buf, current_ldt->cdsCurrentPath, current_ldt->cdsJoinOffset);
bufp = buf + current_ldt->cdsJoinOffset;
rootEndPos = current_ldt->cdsJoinOffset; /* renamed x to rootEndPos - Ron Cemer */
*bufp++ = '\\';
}
if (*src != '\\' && *src != '/') /* append current dir */
{
DosGetCuDir((UBYTE) (i + 1), bufp);
if (*bufp)
if (!(mode & CDS_MODE_SKIP_PHYSICAL))
{
while (*bufp)
bufp++;
*bufp++ = '\\';
}
}
else
src++;
tn_printf(("SUBSTing from: %S\n", cdsEntry->cdsCurrentPath));
/* What to do now: the logical drive letter will be replaced by the hidden
portion of the associated path. This is necessary for NETWORK and
SUBST drives. For local drives it should not harm.
This is actually the reverse mechanism of JOINED drives. */
/*move_name:*/
/* /// The block inside the "#if (0) ... #endif" is
seriously broken. New code added below to replace it.
This eliminates many serious bugs, specifically
with FreeCOM where truename is required to work
according to the DOS specification in order for
the COPY and other file-related commands to work
properly.
This should be a major improvement to all apps which
use truename.
- Ron Cemer */
#if (0)
/*
* The code here is brain dead. It works long as the calling
* function are operating with in normal parms.
* jt
*/
n = 9;
/* convert all forward slashes to backslashes, and uppercase all characters */
while (*src)
{
char c;
c = *src++;
if (!n)
return DE_PATHNOTFND; /* do this for now */
n--;
switch (c)
{
case '*':
if (*src == '.')
{
while (n--)
*bufp++ = '?';
break;
}
else
{
if (src[-2] == '.')
{
while (n--)
*bufp++ = '?';
break;
}
else
{
while (n--)
*bufp++ = '?';
break;
}
}
case '/': /* convert to backslash */
case '\\':
if (bufp[-1] != '\\')
{
*bufp++ = '\\';
n = 9;
}
break;
/* look for '.' and '..' dir entries */
case '.':
if (bufp[-1] == '\\')
{
if (*src == '.' && (src[1] == '/' || src[1] == '\\' || !src[1]))
{
/* '..' dir entry: rewind bufp to last backslash */
for (bufp -= 2; *bufp != '\\'; bufp--)
{
if (bufp < buf + rootEndPos) /* '..' illegal in root dir */
return DE_PATHNOTFND;
}
src++;
if (bufp[-1] == ':')
bufp++;
}
else if (*src == '/' || *src == '\\' || *src == 0)
break;
/* --bufp; */
else
return DE_PATHNOTFND;
}
else if (*src == '/' || *src == '\\' || *src == 0)
{
break;
}
else
{
n = 4;
*bufp++ = c;
}
break;
default:
*bufp++ = c;
break;
}
}
/* remove trailing backslashes */
while (bufp[-1] == '\\')
--bufp;
#endif
/* /// Beginning of new code. - Ron Cemer */
bufp--;
{
char c, *bufend = buf + (sizeof(buf) - 1);
int gotAnyWildcards = 0;
int seglen, copylen, state;
int error = DE_PATHNOTFND;
while ((*src) && (bufp < bufend))
{
/* Skip duplicated slashes. */
while ((*src == '/') || (*src == '\\'))
src++;
if (!(*src))
break;
/* Find the end of this segment in the source string. */
for (seglen = 0;; seglen++)
fmemcpy(dest, cdsEntry->cdsCurrentPath, cdsEntry->cdsBackslashOffset);
if (cdsEntry->cdsFlags & CDSSUBST)
{
c = src[seglen];
if (c == '\0')
{
error = DE_FILENOTFND;
break;
/* The drive had been changed --> update the CDS pointer */
if (dest[1] == ':')
{ /* sanity check if this really is a local drive still */
unsigned i = drLetterToNr(dest[0]);
if (i < lastdrive) /* sanity check #2 */
result = (result & 0xffe0) | i;
}
else if ((c == '/') || (c == '\\'))
break;
}
if (seglen > 0)
{
/* Ignore all ".\" or "\." path segments. */
if ((seglen != 1) || (*src != '.'))
{
/* Apply ".." to the path by removing
last path segment from buf. */
if ((seglen == 2) && (src[0] == '.') && (src[1] == '.'))
{
if (bufp > (buf + rootEndPos))
{
bufp--;
while ((bufp > (buf + rootEndPos))
&& (*bufp != '/') && (*bufp != '\\'))
bufp--;
}
else
{
/* .. in root dir illegal */
return error;
}
}
else
{
/* New segment. If any wildcards in previous
segment(s), this is an invalid path. */
if (gotAnyWildcards || src[0] == '.')
return error;
/* Append current path segment to result. */
*(bufp++) = '\\';
if (bufp >= bufend)
break;
copylen = state = 0;
for (i = 0; ((i < seglen) && (bufp < bufend)); i++)
{
c = src[i];
gotAnyWildcards |= ((c == '?') || (c == '*'));
switch (state)
{
case 0: /* Copying filename (excl. extension) */
if (c == '*')
{
while (copylen < FNAME_SIZE)
{
*(bufp++) = '?';
if (bufp >= bufend)
break;
copylen++;
}
break;
}
if (c == '.')
{
if (src[i + 1] != '.' && i + 1 < seglen)
*(bufp++) = '.';
copylen = 0;
state = 1; /* Copy extension next */
break;
}
if (copylen < FNAME_SIZE)
{
*(bufp++) = c;
copylen++;
break;
}
break;
case 1: /* Copying extension */
if (c == '*')
{
while (copylen < FEXT_SIZE)
{
*(bufp++) = '?';
if (bufp >= bufend)
break;
copylen++;
}
}
if (c == '.')
return error;
if (copylen < FEXT_SIZE)
{
*(bufp++) = c;
copylen++;
}
break;
}
}
}
}
} /* if (seglen > 0) */
src += seglen;
if (*src)
src++;
} /* while ( (*src) && (bufp < bufend) ) */
rootPos = p = dest + current_ldt->cdsBackslashOffset;
*p = '\\'; /* force backslash! */
}
p++;
DosGetCuDir((result & 0x1f) + 1, p);
if (*src != '\\' && *src != '/')
p += strlen(p);
else /* skip the absolute path marker */
src++;
/* remove trailing separator */
if (p[-1] == '\\') p--;
}
/* /// End of new code. - Ron Cemer */
if (bufp == buf + 2)
++bufp;
/* append the path specified in src */
addSep = ADD; /* add separator */
exit_tn:
while(*src)
{
/* New segment. If any wildcards in previous
segment(s), this is an invalid path. */
if (gotAnyWildcards)
return DE_PATHNOTFND;
switch(*src++)
{
case '/':
case '\\': /* skip multiple separators (duplicated slashes) */
addSep = ADD;
break;
case '.': /* special directory component */
switch(*src)
{
case '/':
case '\\':
case '\0':
/* current path -> ignore */
addSep = ADD_UNLESS_LAST;
/* If (/ or \) && no ++src
--> addSep = ADD next turn */
continue; /* next char */
case '.': /* maybe ".." entry */
switch(src[1])
{
case '/':
case '\\':
case '\0':
/* remove last path component */
while(*--p != '\\')
if (p <= rootPos) /* already on root */
return DE_PATHNOTFND;
/* the separator was removed -> add it again */
++src; /* skip the second dot */
/* If / or \, next turn will find them and
assign addSep = ADD */
addSep = ADD_UNLESS_LAST;
continue; /* next char */
}
}
/* ill-formed .* or ..* entries => return error */
errRet:
/* The error is either PATHNOTFND or FILENOTFND
depending on if it is not the last component */
return fstrchr(src, '/') == 0 && fstrchr(src, '\\') == 0
? DE_FILENOTFND
: DE_PATHNOTFND;
default: /* normal component */
if (addSep != DONT_ADD)
{ /* append backslash */
addChar(*rootPos);
addSep = DONT_ADD;
}
/* append component in 8.3 convention */
--src;
/* first character skipped in switch() */
i = parse_name_ext(FNAME_SIZE, &src, &p, dest);
if (i == -1)
PATH_ERROR;
if (i & PNE_WILDCARD)
gotAnyWildcards = TRUE;
/* strip trailing dot */
if ((i & PNE_DOT) && *src != '/' && *src != '\\' && *src != '\0')
{
/* we arrive here only when an extension-dot has been found */
addChar('.');
i = parse_name_ext(FEXT_SIZE, &src, &p, dest);
if (i == -1 || i & PNE_DOT) /* multiple dots are ill-formed */
PATH_ERROR;
if (i & PNE_WILDCARD)
gotAnyWildcards = TRUE;
}
--src; /* terminator or separator was skipped */
break;
}
}
if (addSep == ADD)
{
/* MS DOS preserves a trailing '\\', so an access to "C:\\DOS\\"
or "CDS.C\\" fails. */
/* But don't add the separator, if the last component was ".." */
addChar('\\');
}
*p = '\0'; /* add the string terminator */
DosUpFString(rootPos); /* upcase the file/path name */
/** Note:
Only the portions passed in by the user are upcased, because it is
assumed that the CDS is configured correctly and if it contains
lower case letters, it is required so **/
tn_printf(("Absolute logical path: \"%s\"\n", dest));
/* Now, all the steps 1) .. 7) are fullfilled. Join now */
/* search, if this path is a joined drive */
*bufp++ = 0;
/* finally, uppercase everything */
DosUpString(buf);
/* copy to user's buffer */
fmemcpy(dest, buf, bufp - buf);
return SUCCESS;
if (dest[2] != '/' && (!(mode & CDS_MODE_SKIP_PHYSICAL)) && njoined)
{
for(i = 0; i < lastdrive; ++i)
{
/* How many bytes must match */
size_t j = fstrlen(CDSp[i].cdsCurrentPath);
/* the last component must end before the backslash offset and */
/* the path the drive is joined to leads the logical path */
if ((CDSp[i].cdsFlags & CDSJOINED) && (dest[j] == '\\' || dest[j] == '\0')
&& fmemcmp(dest, CDSp[i].cdsCurrentPath, j) == 0)
{ /* JOINed drive found */
dest[0] = drNrToLetter(i); /* index is physical here */
dest[1] = ':';
if (dest[j] == '\0')
{ /* Reduce to root direc */
dest[2] = '\\';
dest[3] = 0;
/* move the relative path right behind the drive letter */
}
else if (j != 2)
{
strcpy(dest + 2, dest + j);
}
result = (result & 0xffe0) | i;
current_ldt = &CDSp[i];
result &= ~IS_NETWORK;
if (current_ldt->cdsFlags & CDSNETWDRV)
result |= IS_NETWORK;
tn_printf(("JOINed path: \"%S\"\n", dest));
return result;
}
}
/* nothing found => continue normally */
}
if ((mode & CDS_MODE_CHECK_DEV_PATH) && (result & IS_DEVICE) &&
!(result & IS_NETWORK) && dest[2] != '/' && !dir_exists(dest))
return DE_PATHNOTFND;
tn_printf(("Physical path: \"%s\"\n", dest));
return result;
}
#if 0
/**********************************************
Result of INTRSPY
Calling RBIL's INT.COM in MS DOS v6.22
=== Script: MUX.SCR
intercept 2fh
function 11h ; network redirector
subfunction 23h ; Qualify path and filename
on_entry
output "1123: IN: " (ds:SI->byte,asciiz,64)
on_exit
if (cflag == 1)
sameline " [FAIL " ax "]"
output "1123: OUT: " (es:dI->byte,asciiz,64)
output "1123: orig buffer: " (ds:sI->byte,asciiz,64)
function 12h
subfunction 21h
on_entry
output "1221: IN: " (ds:SI->byte,asciiz,64)
on_exit
if (cflag == 1)
sameline " [FAIL " ax "]"
output "1221: OUT: " (es:dI->byte,asciiz,64)
=== Batch file: SPY_INT.BAT
@echo off
if exist report.out del report.out
cmdspy stop
cmdspy flush
cmdspy restart
int ax=0x6000 -buf ds:si="abcöflkgsxkf\0" -buf es:di="%256s" -int 0x21 -d es:di:128 >spy_int.out
cmdspy stop
cmdspy report report.out
more report.out
=== Intspy report file: REPORT.OUT
1123: IN: C:\INTRSPY\SPY_INT.BAT [FAIL 0001]
1123: OUT: 
1123: orig buffer: C:\INTRSPY\SPY_INT.BAT
1123: IN: int.??? [FAIL 0001]
1123: OUT: C:\INTRSPY
1123: orig buffer: int.???
1123: IN: C:\TOOL\int.??? [FAIL 0001]
1123: OUT: C:\INTRSPY
1123: orig buffer: C:\TOOL\int.???
1123: IN: spy_int.out [FAIL 0001]
1123: OUT: C:\TOOL\INT.???
1123: orig buffer: spy_int.out
1123: IN: C:\TOOL\INT.COM [FAIL 0001]
1123: OUT: C:\INTRSPY\SPY_INT.OUT
1123: orig buffer: C:\TOOL\INT.COM
1123: IN: abcöflkgsxkf [FAIL 0001]
1123: OUT: C:\TOOL\INT.COM
1123: orig buffer: abcöflkgsxkf
1123: IN: C:\INTRSPY\SPY_INT.BAT [FAIL 0001]
1123: OUT: C:\INTRSPY\ABCÖFLKG
1123: orig buffer: C:\INTRSPY\SPY_INT.BAT
1123: IN: cmdspy.??? [FAIL 0001]
1123: OUT: C:\INTRSPY
1123: orig buffer: cmdspy.???
1123: IN: C:\INTRSPY\CMDSPY.EXE [FAIL 0001]
1123: OUT: C:\INTRSPY
1123: orig buffer: C:\INTRSPY\CMDSPY.EXE
=== INT.COM output: SPY_INT.OUT
000 CX=0000 DX=0000
SI=4A5E DI=4A76 BP=FF70 SP=FF64
CS=0000 DS=279D ES=279D SS=0000 CPU Flags: 0n00oditsz0a0p1c
INT: 0x21
AX=0059 BX=0000 CX=0000 DX=0000
SI=4A5E DI=4A76 BP=FF70 SP=FF64
CS=0000 DS=279D ES=279D SS=0000 CPU Flags: 0N11odItSz0A0P1c
DOSERR: 0000 (0)
*<es:di:128> {
43(C) 3A(:) 5C(\) 49(I) 4E(N) 54(T) 52(R) 53(S) 50(P) 59(Y) 5C(\) 41(A)
42(B) 43(C) 99(Ö) 46(F) 4C(L) 4B(K) 47(G) 00(.) 3D(=) 30(0) 30(0) 30(0)
30(0) 20( ) 20( ) 20( ) 43(C) 58(X) 3D(=) 30(0) 30(0) 30(0) 30(0) 28(()
30(0) 29()) 20( ) 32(2) 38(8) 28(() 28(() 29()) 20( ) 33(3) 30(0) 28(()
30(0) 29()) 20( ) 32(2) 39(9) 28(() 29()) 29()) 20( ) 32(2) 30(0) 28(()
20( ) 29()) 20( ) 33(3) 32(2) 28(() 32(2) 29()) 20( ) 33(3) 38(8) 28(()
38(8) 29()) 20( ) 32(2) 38(8) 28(() 28(() 29()) 20( ) 32(2) 38(8) 28(()
28(() 29()) 20( ) 32(2) 39(9) 28(() 29()) 29()) 20( ) 32(2) 30(0) 28(()
20( ) 29()) 20( ) 33(3) 33(3) 28(() 33(3) 29()) 20( ) 33(3) 30(0) 28(()
30(0) 29()) 20( ) 32(2) 38(8) 28(() 28(() 29()) 20( ) 33(3) 30(0) 28(()
30(0) 29()) 20( ) 32(2) 39(9) 28(() 29()) 29()) }
===
The actual interesting lines are the 6th "IN:" of the report file.
The DOS interface passed _exactly_ the same string to MUX-11-23 as
written on command line, the same applied to "con\0", a device driver.
***************************************/
#endif
/*
* Log: newstuff.c,v - for newer entries see "cvs log newstuff.c"
*

View File

@ -586,7 +586,7 @@ COUNT DosSetCountry(UWORD cntry)
/*
* Called for DOS-66-01 get CP
*/
COUNT DosGetCodepage(UWORD FAR * actCP, UWORD FAR * sysCP)
COUNT DosGetCodepage(UWORD * actCP, UWORD * sysCP)
{
*sysCP = nlsInfo.sysCodePage;
*actCP = nlsInfo.actPkg->cp;

View File

@ -50,6 +50,7 @@ UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks,
/* *** End of change */
/* chario.c */
UCOUNT BinaryCharIO(struct dhdr FAR * dev, UCOUNT n, void FAR * bp, unsigned command, COUNT *err);
VOID sto(COUNT c);
VOID cso(COUNT c);
VOID mod_cso(REG UCOUNT c);
@ -66,36 +67,33 @@ UCOUNT sti(keyboard * kp);
sft FAR *get_sft(UCOUNT);
/* dosfns.c */
BYTE FAR *get_root(BYTE FAR *);
const char FAR *get_root(const char FAR *);
BOOL check_break(void);
UCOUNT GenericReadSft(sft far * sftp, UCOUNT n, BYTE FAR * bp,
COUNT FAR * err, BOOL force_binary);
UCOUNT GenericReadSft(sft far * sftp, UCOUNT n, void FAR * bp,
COUNT * err, BOOL force_binary);
COUNT SftSeek(sft FAR * sftp, LONG new_pos, COUNT mode);
/*COUNT DosRead(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err); */
#define GenericRead(hndl, n, bp, err, t) GenericReadSft(get_sft(hndl), n, bp, err, t)
#define DosRead(hndl, n, bp, err) GenericRead(hndl, n, bp, err, FALSE)
#define DosReadSft(sftp, n, bp, err) GenericReadSft(sftp, n, bp, err, FALSE)
UCOUNT DosWriteSft(sft FAR * sftp, UCOUNT n, const BYTE FAR * bp,
COUNT FAR * err);
#define DosWrite(hndl, n, bp, err) DosWriteSft(get_sft(hndl), n, bp, err)
COUNT DosSeek(COUNT hndl, LONG new_pos, COUNT mode, ULONG * set_pos);
COUNT DosCreat(BYTE FAR * fname, COUNT attrib);
COUNT DosCreatSft(BYTE * fname, COUNT attrib);
COUNT CloneHandle(COUNT hndl);
COUNT DosDup(COUNT Handle);
COUNT DosForceDup(COUNT OldHandle, COUNT NewHandle);
COUNT DosOpen(BYTE FAR * fname, COUNT mode);
COUNT DosOpenSft(BYTE * fname, COUNT mode);
UCOUNT BinaryReadSft(sft FAR * s, void *bp, COUNT *err);
#define BinaryRead(hndl, bp, err) BinaryReadSft(get_sft(hndl), bp, err)
UCOUNT DosRWSft(sft FAR * s, UCOUNT n, void FAR * bp, COUNT *err, int mode);
#define DosRead(hndl, n, bp, err) DosRWSft(get_sft(hndl), n, bp, err, XFR_READ)
#define DosWrite(hndl, n, bp, err) DosRWSft(get_sft(hndl), n, bp, err, XFR_WRITE)
ULONG DosSeek(COUNT hndl, LONG new_pos, COUNT mode);
long DosOpen(char FAR * fname, unsigned flags, unsigned attrib);
COUNT CloneHandle(unsigned hndl);
long DosDup(unsigned Handle);
COUNT DosForceDup(unsigned OldHandle, unsigned NewHandle);
long DosOpenSft(char FAR * fname, unsigned flags, unsigned attrib);
COUNT DosClose(COUNT hndl);
COUNT DosCloseSft(WORD sft_idx, BOOL commitonly);
#define DosCommit(hndl) DosCloseSft(get_sft_idx(hndl), TRUE)
BOOL DosGetFree(UBYTE drive, UCOUNT FAR * spc, UCOUNT FAR * navc,
UCOUNT FAR * bps, UCOUNT FAR * nc);
BOOL DosGetFree(UBYTE drive, UWORD * spc, UWORD * navc,
UWORD * bps, UWORD * nc);
COUNT DosGetCuDir(UBYTE drive, BYTE FAR * s);
COUNT DosChangeDir(BYTE FAR * s);
COUNT DosFindFirst(UCOUNT attr, BYTE FAR * name);
COUNT DosFindNext(void);
COUNT DosGetFtime(COUNT hndl, date FAR * dp, time FAR * tp);
COUNT DosGetFtime(COUNT hndl, date * dp, time * tp);
COUNT DosSetFtimeSft(WORD sft_idx, date dp, time tp);
#define DosSetFtime(hndl, dp, tp) DosSetFtimeSft(get_sft_idx(hndl), (dp), (tp))
COUNT DosGetFattr(BYTE FAR * name);
@ -104,21 +102,20 @@ UBYTE DosSelectDrv(UBYTE drv);
COUNT DosDelete(BYTE FAR * path, int attrib);
COUNT DosRename(BYTE FAR * path1, BYTE FAR * path2);
COUNT DosRenameTrue(BYTE * path1, BYTE * path2, int attrib);
COUNT DosMkdir(BYTE FAR * dir);
COUNT DosRmdir(BYTE FAR * dir);
struct dhdr FAR *IsDevice(BYTE FAR * FileName);
COUNT DosMkdir(const char FAR * dir);
COUNT DosRmdir(const char FAR * dir);
struct dhdr FAR *IsDevice(const char FAR * FileName);
BOOL IsShareInstalled(void);
COUNT DosLockUnlock(COUNT hndl, LONG pos, LONG len, COUNT unlock);
sft FAR *idx_to_sft(COUNT SftIndex);
COUNT get_sft_idx(UCOUNT hndl);
COUNT DosTruename(const char FAR * src, char FAR * dest);
/*dosidle.asm */
VOID ASMCFUNC DosIdle_int(void);
/* dosnames.c */
VOID SpacePad(BYTE *, COUNT);
COUNT ParseDosName(BYTE *, COUNT *, BYTE *, BYTE *, BYTE *, BOOL);
/*COUNT ParseDosPath(BYTE *, COUNT *, BYTE *, BYTE FAR *); */
int ParseDosName(const char *, char *, BOOL);
/* error.c */
VOID dump(void);
@ -127,7 +124,7 @@ VOID fatal(BYTE * err_msg);
/* fatdir.c */
VOID dir_init_fnode(f_node_ptr fnp, CLUSTER dirstart);
f_node_ptr dir_open(BYTE * dirname);
f_node_ptr dir_open(const char *dirname);
COUNT dir_read(REG f_node_ptr fnp);
BOOL dir_write(REG f_node_ptr fnp);
VOID dir_close(REG f_node_ptr fnp);
@ -138,13 +135,12 @@ int FileName83Length(BYTE * filename83);
/* fatfs.c */
ULONG clus2phys(CLUSTER cl_no, struct dpb FAR * dpbp);
COUNT dos_open(BYTE * path, COUNT flag);
BOOL fcmp(BYTE * s1, BYTE * s2, COUNT n);
BOOL fcmp_wild(BYTE FAR * s1, BYTE FAR * s2, COUNT n);
long dos_open(char * path, unsigned flag, unsigned attrib);
BOOL fcbmatch(const char *fcbname1, const char *fcbname2);
BOOL fcmp_wild(const char * s1, const char * s2, unsigned n);
VOID touc(BYTE * s, COUNT n);
COUNT dos_close(COUNT fd);
COUNT dos_commit(COUNT fd);
COUNT dos_creat(BYTE * path, int attrib);
COUNT dos_delete(BYTE * path, int attrib);
COUNT dos_rmdir(BYTE * path);
COUNT dos_rename(BYTE * path1, BYTE * path2, int attrib);
@ -152,8 +148,7 @@ date dos_getdate(void);
time dos_gettime(void);
COUNT dos_getftime(COUNT fd, date FAR * dp, time FAR * tp);
COUNT dos_setftime(COUNT fd, date dp, time tp);
LONG dos_getcufsize(COUNT fd);
LONG dos_getfsize(COUNT fd);
ULONG dos_getfsize(COUNT fd);
BOOL dos_setfsize(COUNT fd, LONG size);
COUNT dos_mkdir(BYTE * dir);
BOOL last_link(f_node_ptr fnp);
@ -163,6 +158,7 @@ COUNT dos_read(COUNT fd, VOID FAR * buffer, UCOUNT count);
COUNT dos_write(COUNT fd, const VOID FAR * buffer, UCOUNT count);
LONG dos_lseek(COUNT fd, LONG foffset, COUNT origin);
CLUSTER dos_free(struct dpb FAR * dpbp);
BOOL dir_exists(char * path);
VOID trim_path(BYTE FAR * s);
@ -171,6 +167,7 @@ COUNT dos_cd(struct cds FAR * cdsp, BYTE * PathName);
f_node_ptr get_f_node(void);
VOID release_f_node(f_node_ptr fnp);
VOID dos_setdta(BYTE FAR * newdta);
COUNT dos_getfattr_fd(COUNT fd);
COUNT dos_getfattr(BYTE * name);
COUNT dos_setfattr(BYTE * name, UWORD attrp);
COUNT media_check(REG struct dpb FAR * dpbp);
@ -192,43 +189,35 @@ int DosCharInput(VOID);
VOID DosDirectConsoleIO(iregs FAR * r);
VOID DosCharOutput(COUNT c);
VOID DosDisplayOutput(COUNT c);
VOID FatGetDrvData(UCOUNT drive, UCOUNT FAR * spc, UCOUNT FAR * bps,
UCOUNT FAR * nc, BYTE FAR ** mdp);
WORD FcbParseFname(int wTestMode, const BYTE FAR ** lpFileName, fcb FAR * lpFcb);
BYTE FAR *FatGetDrvData(UBYTE drive, UWORD * spc, UWORD * bps,
UWORD * nc);
UWORD FcbParseFname(int *wTestMode, const BYTE FAR *lpFileName, fcb FAR * lpFcb);
const BYTE FAR *ParseSkipWh(const BYTE FAR * lpFileName);
BOOL TestCmnSeps(BYTE FAR * lpFileName);
BOOL TestFieldSeps(BYTE FAR * lpFileName);
const BYTE FAR *GetNameField(const BYTE FAR * lpFileName, BYTE FAR * lpDestField,
COUNT nFieldSize, BOOL * pbWildCard);
typedef BOOL FcbFunc_t (xfcb FAR *, COUNT *, UCOUNT);
FcbFunc_t FcbRead, FcbWrite;
BOOL FcbGetFileSize(xfcb FAR * lpXfcb);
BOOL FcbSetRandom(xfcb FAR * lpXfcb);
BOOL FcbCalcRec(xfcb FAR * lpXfcb);
BOOL FcbRandomBlockRead(xfcb FAR * lpXfcb, COUNT nRecords,
COUNT * nErrorCode);
BOOL FcbRandomBlockWrite(xfcb FAR * lpXfcb, COUNT nRecords,
COUNT * nErrorCode);
BOOL FcbRandomIO(xfcb FAR * lpXfcb, COUNT * nErrorCode, FcbFunc_t *FcbFunc);
BOOL FcbOpenCreate(xfcb FAR * lpXfcb, BOOL Create);
#define FcbOpen(fcb) FcbOpenCreate(fcb, FALSE)
#define FcbCreate(fcb) FcbOpenCreate(fcb, TRUE)
void FcbNameInit(fcb FAR * lpFcb, BYTE * pszBuffer, COUNT * pCurDrive);
BOOL FcbDelete(xfcb FAR * lpXfcb);
BOOL FcbRename(xfcb FAR * lpXfcb);
BOOL FcbClose(xfcb FAR * lpXfcb);
VOID FcbCloseAll(VOID);
BOOL FcbFindFirst(xfcb FAR * lpXfcb);
BOOL FcbFindNext(xfcb FAR * lpXfcb);
UBYTE FcbReadWrite(xfcb FAR *, UCOUNT, int);
UBYTE FcbGetFileSize(xfcb FAR * lpXfcb);
void FcbSetRandom(xfcb FAR * lpXfcb);
UBYTE FcbRandomBlockIO(xfcb FAR * lpXfcb, COUNT nRecords, int mode);
UBYTE FcbRandomIO(xfcb FAR * lpXfcb, int mode);
UBYTE FcbOpen(xfcb FAR * lpXfcb, unsigned flags);
int FcbNameInit(fcb FAR * lpFcb, BYTE * pszBuffer, COUNT * pCurDrive);
UBYTE FcbDelete(xfcb FAR * lpXfcb);
UBYTE FcbRename(xfcb FAR * lpXfcb);
UBYTE FcbClose(xfcb FAR * lpXfcb);
void FcbCloseAll(void);
UBYTE FcbFindFirstNext(xfcb FAR * lpXfcb, BOOL First);
/* ioctl.c */
COUNT DosDevIOctl(iregs FAR * r);
COUNT DosDevIOctl(lregs * r);
/* memmgr.c */
seg far2para(VOID FAR * p);
seg long2para(ULONG size);
VOID FAR *add_far(VOID FAR * fp, ULONG off);
void FAR *adjust_far(const 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);
@ -242,12 +231,16 @@ VOID DosUmbLink(BYTE n);
VOID mcb_print(mcb FAR * mcbp);
/* misc.c */
VOID ASMCFUNC strcpy(REG BYTE * d, REG const BYTE * s);
VOID ASMCFUNC fmemcpy(REG VOID FAR * d, REG const VOID FAR * s, REG COUNT n);
VOID ASMCFUNC fstrcpy(REG BYTE FAR * d, REG const BYTE FAR * s);
void ASMCFUNC memcpy(REG void *d, REG const VOID * s, REG COUNT n);
void ASMCFUNC fmemset(REG VOID FAR * s, REG int ch, REG COUNT n);
void ASMCFUNC memset(REG VOID * s, REG int ch, REG COUNT n);
char * ASMCFUNC strcpy(char * d, const char * s);
void ASMCFUNC fmemcpyBack(void FAR * d, const void FAR * s, size_t n);
void ASMCFUNC fmemcpy(void FAR * d, const void FAR * s, size_t n);
void ASMCFUNC fstrcpy(char FAR * d, const char FAR * s);
void * ASMCFUNC memcpy(void *d, const void * s, size_t n);
void ASMCFUNC fmemset(void FAR * s, int ch, size_t n);
void * ASMCFUNC memset(void * s, int ch, size_t n);
int ASMCFUNC memcmp(const void *m1, const void *m2, size_t n);
int ASMCFUNC fmemcmp(const void FAR *m1, const void FAR *m2, size_t n);
/* lfnapi.c */
COUNT lfn_allocate_inode(VOID);
@ -279,27 +272,29 @@ COUNT DosGetCountryInformation(UWORD cntry, VOID FAR * buf);
#ifndef DosSetCountry
COUNT DosSetCountry(UWORD cntry);
#endif
COUNT DosGetCodepage(UWORD FAR * actCP, UWORD FAR * sysCP);
COUNT DosGetCodepage(UWORD * actCP, UWORD * sysCP);
COUNT DosSetCodepage(UWORD actCP, UWORD sysCP);
UWORD ASMCFUNC syscall_MUX14(DIRECT_IREGS);
/* prf.c */
VOID put_console(COUNT c);
WORD CDECL printf(CONST BYTE * fmt, ...);
WORD CDECL sprintf(BYTE * buff, CONST BYTE * fmt, ...);
int CDECL printf(CONST BYTE * fmt, ...);
int CDECL sprintf(BYTE * buff, CONST BYTE * fmt, ...);
VOID hexd(char *title, VOID FAR * p, COUNT numBytes);
/* strings.c */
COUNT ASMCFUNC strlen(REG BYTE * s);
COUNT ASMCFUNC fstrlen(REG BYTE FAR * s);
VOID ASMCFUNC _fstrcpy(REG BYTE FAR * d, REG BYTE FAR * s);
VOID ASMCFUNC strncpy(REG BYTE * d, REG BYTE * s, COUNT l);
COUNT ASMCFUNC strcmp(REG BYTE * d, REG BYTE * s);
COUNT ASMCFUNC fstrcmp(REG BYTE FAR * d, REG BYTE FAR * s);
COUNT ASMCFUNC fstrncmp(REG BYTE FAR * d, REG BYTE FAR * s, COUNT l);
COUNT ASMCFUNC strncmp(REG BYTE * d, REG BYTE * s, COUNT l);
void ASMCFUNC fstrncpy(REG BYTE FAR * d, REG BYTE FAR * s, COUNT l);
BYTE * ASMCFUNC strchr(const BYTE * s, BYTE c);
size_t ASMCFUNC strlen(const char * s);
size_t ASMCFUNC fstrlen(const char FAR * s);
char FAR * ASMCFUNC _fstrcpy(char FAR * d, const char FAR * s);
char * ASMCFUNC strncpy(char * d, const char * s, size_t l);
int ASMCFUNC strcmp(const char * d, const char * s);
int ASMCFUNC fstrcmp(const char FAR * d, const char FAR * s);
int ASMCFUNC fstrncmp(const char FAR * d, const char FAR * s, size_t l);
int ASMCFUNC strncmp(const char * d, const char * s, size_t l);
void ASMCFUNC fstrncpy(char FAR * d, const char FAR * s, size_t l);
char * ASMCFUNC strchr(const char * s, int c);
char FAR * ASMCFUNC fstrchr(const char FAR * s, int c);
void FAR * ASMCFUNC fmemchr(const void FAR * s, int c, size_t n);
/* sysclk.c */
COUNT BcdToByte(COUNT x);
@ -309,19 +304,17 @@ LONG WordToBcd(BYTE * x, UWORD * mon, UWORD * day, UWORD * yr);
/* syspack.c */
#ifdef NONNATIVE
VOID getdirent(BYTE FAR * vp, struct dirent FAR * dp);
VOID putdirent(struct dirent FAR * dp, BYTE FAR * vp);
VOID getdirent(UBYTE FAR * vp, struct dirent FAR * dp);
VOID putdirent(struct dirent FAR * dp, UBYTE FAR * vp);
#else
#define getdirent(vp, dp) fmemcpy(dp, vp, sizeof(struct dirent))
#define putdirent(dp, vp) fmemcpy(vp, dp, sizeof(struct dirent))
#endif
/* systime.c */
VOID DosGetTime(BYTE FAR * hp, BYTE FAR * mp, BYTE FAR * sp,
BYTE FAR * hdp);
VOID DosGetTime(UBYTE * hp, UBYTE * mp, UBYTE * sp, UBYTE * hdp);
COUNT DosSetTime(BYTE h, BYTE m, BYTE s, BYTE hd);
VOID DosGetDate(BYTE FAR * wdp, BYTE FAR * mp, BYTE FAR * mdp,
COUNT FAR * yp);
VOID DosGetDate(UBYTE * wdp, UBYTE * mp, UBYTE * mdp, UWORD * yp);
COUNT DosSetDate(UWORD Month, UWORD DayOfMonth, UWORD Year);
const UWORD *is_leap_year_monthdays(UWORD year);
@ -337,8 +330,8 @@ VOID InitPSP(VOID);
/* newstuff.c */
int SetJFTSize(UWORD nHandles);
int DosMkTmp(BYTE FAR * pathname, UWORD attr);
COUNT get_verify_drive(char FAR * src);
COUNT truename(char FAR * src, char FAR * dest, COUNT t);
COUNT get_verify_drive(const char FAR * src);
COUNT truename(const char FAR * src, char * dest, COUNT t);
/* network.c */
COUNT ASMCFUNC remote_doredirect(UWORD b, UCOUNT n, UWORD d, VOID FAR * s,
@ -358,6 +351,7 @@ COUNT ASMCFUNC remote_findnext(VOID FAR * s);
COUNT ASMCFUNC remote_getfattr(VOID);
COUNT ASMCFUNC remote_getfree(VOID FAR * s, VOID * d);
COUNT ASMCFUNC remote_open(sft FAR * s, COUNT mode);
int ASMCFUNC remote_extopen(sft FAR * s, unsigned attr);
LONG ASMCFUNC remote_lseek(sft FAR * s, LONG new_pos);
UCOUNT ASMCFUNC remote_read(sft FAR * s, UCOUNT n, COUNT * err);
UCOUNT ASMCFUNC remote_write(sft FAR * s, UCOUNT n, COUNT * err);
@ -366,7 +360,7 @@ COUNT ASMCFUNC remote_setfattr(COUNT attr);
COUNT ASMCFUNC remote_printredir(UCOUNT dx, UCOUNT ax);
COUNT ASMCFUNC remote_commit(sft FAR * s);
COUNT ASMCFUNC remote_close(sft FAR * s);
COUNT ASMCFUNC QRemote_Fn(char FAR * s, char FAR * d);
COUNT ASMCFUNC QRemote_Fn(char FAR * d, const char FAR * s);
UWORD get_machine_name(BYTE FAR * netname);
VOID set_machine_name(BYTE FAR * netname, UWORD name_num);

View File

@ -74,16 +74,10 @@ UWORD DaysFromYearMonthDay(UWORD Year, UWORD Month, UWORD DayOfMonth)
/* common - call the clock driver */
void ExecuteClockDriverRequest(BYTE command)
{
ClkReqHdr.r_length = sizeof(request);
ClkReqHdr.r_command = command;
ClkReqHdr.r_count = sizeof(struct ClockRecord);
ClkReqHdr.r_trans = (BYTE FAR *) (&ClkRecord);
ClkReqHdr.r_status = 0;
execrh((request FAR *) & ClkReqHdr, (struct dhdr FAR *)clock);
BinaryCharIO(clock, sizeof(struct ClockRecord), &ClkRecord, command, &UnusedRetVal);
}
VOID DosGetTime(BYTE FAR * hp, BYTE FAR * mp, BYTE FAR * sp,
BYTE FAR * hdp)
VOID DosGetTime(UBYTE * hp, UBYTE * mp, UBYTE * sp, UBYTE * hdp)
{
ExecuteClockDriverRequest(C_INPUT);
@ -113,9 +107,7 @@ COUNT DosSetTime(BYTE h, BYTE m, BYTE s, BYTE hd)
return SUCCESS;
}
VOID DosGetDate(wdp, mp, mdp, yp)
BYTE FAR *wdp, FAR * mp, FAR * mdp;
COUNT FAR *yp;
VOID DosGetDate(UBYTE *wdp, UBYTE *mp, UBYTE *mdp, UWORD *yp)
{
UWORD c;
const UWORD *pdays;

View File

@ -461,7 +461,6 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
/* Now load the executable */
{
BYTE FAR *sp;
ULONG tmp;
if (mode == OVERLAY) /* memory already allocated */
sp = MK_FP(mem, 0);
@ -472,7 +471,7 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
-- 1999/04/21 ska */
/* rewind to start */
DosSeek(fd, 0, 0, &tmp);
DosSeek(fd, 0, 0);
/* read everything, but at most 64K - sizeof(PSP) */
DosRead(fd, 0xff00, sp, &UnusedRetVal);
DosClose(fd);
@ -552,7 +551,7 @@ VOID return_user(void)
COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
{
UWORD mem, env, start_seg, asize = 0;
ULONG exe_size, tmp;
ULONG exe_size;
{
ULONG image_size;
ULONG image_offset;
@ -646,8 +645,7 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
/* Now load the executable */
/* offset to start of image */
DosSeek(fd, image_offset, 0, &tmp);
if (tmp != image_offset)
if (DosSeek(fd, image_offset, 0) != image_offset)
{
if (mode != OVERLAY)
{
@ -696,9 +694,8 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
COUNT i;
UWORD reloc[2];
seg FAR *spot;
ULONG tmp;
DosSeek(fd, ExeHeader.exRelocTable, 0, &tmp);
DosSeek(fd, ExeHeader.exRelocTable, 0);
for (i = 0; i < ExeHeader.exRelocItems; i++)
{
if (DosRead
@ -765,11 +762,7 @@ COUNT DosExec(COUNT mode, exec_blk FAR * ep, BYTE FAR * lp)
/* If file not found - free ram and return error */
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;
}

View File

@ -20,7 +20,7 @@ SYS_EXE_dependencies = \
production: bin2c.com ..\bin\sys.com
bin2c.com: bin2c.c
$(CL) $(CFLAGST) $(TINY) bin2c.c
$(CL) $(CFLAGS) $(TINY) bin2c.c
..\bin\sys.com: sys.com
copy sys.com ..\bin

View File

@ -622,8 +622,7 @@ VOID put_boot(COUNT drive, BYTE * bsFile, BOOL both)
temp = bs32->sysFatSecMask + 1;
for (bs32->sysFatSecShift = 0; temp != 1;
bs32->sysFatSecShift++, temp >>= 1) ;
/* use fixed drive for A:, B: and DL otherwise */
/* put 0 for A: or B: (force booting from A:), otherwise use DL */
bs32->bsDriveNumber = drive < 2 ? 0 : 0xff;
}
#ifdef DEBUG
@ -659,9 +658,8 @@ VOID put_boot(COUNT drive, BYTE * bsFile, BOOL both)
/* sector data starts on */
temp = temp + bs->sysRootDirSecs;
bs->sysDataStart = temp;
/* use fixed BIOS drive 0 for A:, B: and DL otherwise */
bs32->bsDriveNumber = drive < 2 ? 0 : 0xff;
/* put 0 for A: or B: (force booting from A:), otherwise use DL */
bs->bsDriveNumber = drive < 2 ? 0 : 0xff;
}
#ifdef DEBUG