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) Eric Biederman (ebiederm+eric@ccr.net)
Tom Ehlert (tom.ehlert@ginko.de) Tom Ehlert (tom.ehlert@ginko.de)
Victor Vlasenko (victor_vlasenko@hotbox.ru) Victor Vlasenko (victor_vlasenko@hotbox.ru)
Jeremy Davis (jeremyd@computer.org)
Martin Stromberg (ams@ludd.luth.se)
Bart Oldeman (bart@dosemu.org) Bart Oldeman (bart@dosemu.org)
And last, but not least, a big thanx to Pasquale J. Villani And last, but not least, a big thanx to Pasquale J. Villani

View File

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

View File

@ -9,10 +9,31 @@
* disabled fatal() in error.c * disabled fatal() in error.c
* Disable the A20 line upon exec (int21/ah=4B). This is necessary for some * Disable the A20 line upon exec (int21/ah=4B). This is necessary for some
brain-dead exepacked programs. brain-dead exepacked programs.
* removed unnecessary buffer fields * removed unnecessary "BUFFERS" fields
* proper check for network/non-existing drive for int25/26. * proper check for network/non-existing drive for int25/26.
* save more bytes on the stack at various places * 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 + 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 * patchobj makefile correction
* printf uses va_list etc. * printf uses va_list etc.
* quicker and more robust Watcom build * quicker and more robust Watcom build
@ -33,7 +54,6 @@
merge as much as possible from DosExeLoader and DosComLoader merge as much as possible from DosExeLoader and DosComLoader
(from Tom:) eliminate some structures in low memory (from Tom:) eliminate some structures in low memory
* main.c: slightly cleanup "SHELL=" line parsing. * main.c: slightly cleanup "SHELL=" line parsing.
2002 May 9 - Build 2026b 2002 May 9 - Build 2026b
-------- Bart Oldeman (bart@dosemu.org) -------- Bart Oldeman (bart@dosemu.org)
+ Changes Tom + Changes Tom

View File

@ -54,7 +54,8 @@ static BYTE *fat_hRcsId =
#define FEXT_SIZE 3 #define FEXT_SIZE 3
/* FAT deleted flag */ /* 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 */ /* FAT cluster to physical conversion macros */
#define clus_add(cl_no) ((ULONG) (((ULONG) cl_no - 2L) \ #define clus_add(cl_no) ((ULONG) (((ULONG) cl_no - 2L) \
@ -81,8 +82,7 @@ static BYTE *fat_hRcsId =
/* FAT file system directory entry */ /* FAT file system directory entry */
struct dirent { struct dirent {
UBYTE dir_name[FNAME_SIZE]; /* Filename */ char dir_name[FNAME_SIZE + FEXT_SIZE]; /* Filename + extension in FCB format */
UBYTE dir_ext[FEXT_SIZE]; /* Filename extension */
UBYTE dir_attrib; /* File Attribute */ UBYTE dir_attrib; /* File Attribute */
UBYTE dir_case; /* File case */ UBYTE dir_case; /* File case */
UBYTE dir_crtimems; /* Milliseconds */ UBYTE dir_crtimems; /* Milliseconds */

View File

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

View File

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

View File

@ -65,6 +65,40 @@ struct dhdr FAR *finddev(UWORD attr_mask)
} }
#endif #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) VOID _cso(COUNT c)
{ {
if (syscon->dh_attr & ATTR_FASTCON) if (syscon->dh_attr & ATTR_FASTCON)
@ -72,7 +106,7 @@ VOID _cso(COUNT c)
#if defined(__TURBOC__) #if defined(__TURBOC__)
_AL = c; _AL = c;
__int__(0x29); __int__(0x29);
#else #elif defined(I86)
asm asm
{ {
mov al, byte ptr c; mov al, byte ptr c;
@ -81,14 +115,7 @@ VOID _cso(COUNT c)
#endif #endif
return; return;
} }
CharReqHdr.r_length = sizeof(request); BinaryCharIO(syscon, 1, &c, C_OUTPUT, &UnusedRetVal);
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);
} }
VOID cso(COUNT c) VOID cso(COUNT c)
@ -97,7 +124,7 @@ VOID cso(COUNT c)
con_hold(); con_hold();
if (PrinterEcho) if (PrinterEcho)
DosWrite(STDPRN, 1, (BYTE FAR *) & c, (COUNT FAR *) & UnusedRetVal); DosWrite(STDPRN, 1, (BYTE FAR *) & c, & UnusedRetVal);
switch (c) switch (c)
{ {
@ -125,7 +152,7 @@ VOID cso(COUNT c)
VOID sto(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) VOID mod_cso(REG UCOUNT c)
@ -176,14 +203,7 @@ COUNT con_read(void)
{ {
BYTE c; BYTE c;
CharReqHdr.r_length = sizeof(request); BinaryCharIO(syscon, 1, &c, C_INPUT, &UnusedRetVal);
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);
if (c == CTL_C) if (c == CTL_C)
handle_break(); handle_break();
return c; return c;
@ -216,9 +236,8 @@ UCOUNT _sti(BOOL check_break)
Do_DosIdle_loop(); Do_DosIdle_loop();
if (check_break) if (check_break)
con_hold(); con_hold();
while (GenericRead while (BinaryRead(STDIN, &c, & UnusedRetVal) != 1)
(STDIN, 1, (BYTE FAR *) & c, (COUNT FAR *) & UnusedRetVal, ;
TRUE) != 1) ;
return c; 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 PathSep(c) ((c)=='/'||(c)=='\\')
#define DriveChar(c) (((c)>='A'&&(c)<='Z')||((c)>='a'&&(c)<='z')) #define DriveChar(c) (((c)>='A'&&(c)<='Z')||((c)>='a'&&(c)<='z'))
#define DirChar(c) (!strchr(_DirWildNameChars+5, (c))) #define DirChar(c) (((unsigned char)(c)) >= ' ' && \
#define WildChar(c) (!strchr(_DirWildNameChars+2, (c))) !strchr(_DirWildNameChars+5, (c)))
#define NameChar(c) (!strchr(_DirWildNameChars, (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 XlateLcase(BYTE * szFname, COUNT nChars);
VOID DosTrimPath(BYTE * lpszPathNamep); VOID DosTrimPath(BYTE * lpszPathNamep);
@ -61,14 +64,6 @@ VOID XlateLcase(BYTE * szFname, COUNT nChars)
} }
#endif #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; MSD durring an FindFirst search string looks like this;
(*), & (.) == Current directory *.* (*), & (.) == Current directory *.*
@ -76,90 +71,73 @@ VOID SpacePad(BYTE * szString, COUNT nChars)
(..) == Back one directory *.* (..) == Back one directory *.*
This always has a "truename" as input, so we may do some shortcuts 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, int ParseDosName(const char *filename, char *fcbname, BOOL bAllowWildcards)
COUNT * pnDrive,
BYTE * pszDir,
BYTE * pszFile, BYTE * pszExt, BOOL bAllowWildcards)
{ {
COUNT nDirCnt, nFileCnt, nExtCnt; int nDirCnt, nFileCnt, nExtCnt;
BYTE *lpszLclDir, *lpszLclFile, *lpszLclExt; const char *lpszLclDir, *lpszLclFile, *lpszLclExt;
/* Initialize the users data fields */ /* 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; nDirCnt = nFileCnt = nExtCnt = 0;
/* found a drive, fetch it and bump pointer past drive */
/* NB: this code assumes ASCII */ /* 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. */ /* Now see how long a directory component we have. */
lpszLclDir = lpszLclFile = lpszFileName; lpszLclDir = lpszLclFile = filename;
while (DirChar(*lpszFileName)) filename += 2;
while (DirChar(*filename))
{ {
if (*lpszFileName == '\\') if (*filename == '\\')
lpszLclFile = lpszFileName + 1; lpszLclFile = filename + 1;
++lpszFileName; ++filename;
} }
nDirCnt = FP_OFF(lpszLclFile) - FP_OFF(lpszLclDir); nDirCnt = lpszLclFile - lpszLclDir;
/* Fix lengths to maximums allowed by MS-DOS. */ /* Fix lengths to maximums allowed by MS-DOS. */
if (nDirCnt > PARSE_MAX - 1) if (nDirCnt > PARSE_MAX - 1)
nDirCnt = PARSE_MAX - 1; nDirCnt = PARSE_MAX - 1;
/* Parse out the file name portion. */ /* Parse out the file name portion. */
lpszFileName = lpszLclFile; filename = lpszLclFile;
while (bAllowWildcards ? WildChar(*lpszFileName) : while (bAllowWildcards ? WildChar(*filename) :
NameChar(*lpszFileName)) NameChar(*filename))
{ {
++nFileCnt; ++nFileCnt;
++lpszFileName; ++filename;
} }
if (nFileCnt == 0) if (nFileCnt == 0)
{
/* Lixing Yuan Patch */ /* Lixing Yuan Patch */
if (bAllowWildcards) /* for find first */ if (bAllowWildcards) /* for find first */
{ {
if (*lpszFileName != '\0') if (*filename != '\0')
return DE_FILENOTFND; return DE_FILENOTFND;
if (nDirCnt == 1) /* for d:\ */ if (nDirCnt == 1) /* for d:\ */
return DE_NFILES; return DE_NFILES;
if (pszDir) memset(fcbname, '?', FNAME_SIZE + FEXT_SIZE);
{ return nDirCnt;
memcpy(pszDir, lpszLclDir, nDirCnt);
pszDir[nDirCnt] = '\0';
}
if (pszFile)
memcpy(pszFile, "????????", FNAME_SIZE + 1);
if (pszExt)
memcpy(pszExt, "???", FEXT_SIZE + 1);
return SUCCESS;
} }
else else
return DE_FILENOTFND; return DE_FILENOTFND;
}
/* Now we have pointers set to the directory portion and the */ /* Now we have pointers set to the directory portion and the */
/* file portion. Now determine the existance of an extension. */ /* file portion. Now determine the existance of an extension. */
lpszLclExt = lpszFileName; lpszLclExt = filename;
if ('.' == *lpszFileName) if ('.' == *filename)
{ {
lpszLclExt = ++lpszFileName; lpszLclExt = ++filename;
while (*lpszFileName) while (*filename)
{ {
if (bAllowWildcards ? WildChar(*lpszFileName) : if (bAllowWildcards ? WildChar(*filename) :
NameChar(*lpszFileName)) NameChar(*filename))
{ {
++nExtCnt; ++nExtCnt;
++lpszFileName; ++filename;
} }
else else
{ {
@ -167,225 +145,20 @@ COUNT ParseDosName(BYTE * lpszFileName,
} }
} }
} }
else if (*lpszFileName) else if (*filename)
return DE_FILENOTFND; return DE_FILENOTFND;
/* Finally copy whatever the user wants extracted to the user's */ /* Finally copy whatever the user wants extracted to the user's */
/* buffers. */ /* buffers. */
if (pszDir) memset(fcbname, ' ', FNAME_SIZE + FEXT_SIZE);
{ memcpy(fcbname, lpszLclFile, nFileCnt);
memcpy(pszDir, lpszLclDir, nDirCnt); memcpy(&fcbname[FNAME_SIZE], lpszLclExt, nExtCnt);
pszDir[nDirCnt] = '\0';
}
if (pszFile)
{
memcpy(pszFile, lpszLclFile, nFileCnt);
pszFile[nFileCnt] = '\0';
}
if (pszExt)
{
memcpy(pszExt, lpszLclExt, nExtCnt);
pszExt[nExtCnt] = '\0';
}
/* Clean up before leaving */ /* 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" * Log: dosnames.c,v - for newer log entries do "cvs log dosnames.c"
* *

View File

@ -376,7 +376,11 @@ int21_exit_nodec:
pop si pop si
%IFDEF I386 %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 %endif
cli cli

View File

@ -68,14 +68,10 @@ VOID dir_init_fnode(f_node_ptr fnp, CLUSTER dirstart)
fnp->f_cluster = fnp->f_dirstart = 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; f_node_ptr fnp;
COUNT drive; int i;
BYTE *p;
WORD i;
struct cds FAR *cdsp;
BYTE *pszPath = dirname + 2;
/* Allocate an fnode if possible - error return (0) if not. */ /* Allocate an fnode if possible - error return (0) if not. */
if ((fnp = get_f_node()) == (f_node_ptr) 0) 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 */ /* Force the fnode into read-write mode */
fnp->f_mode = RDWR; fnp->f_mode = RDWR;
/* determine what drive we are using... */ /* determine what drive and dpb we are using... */
if (ParseDosName fnp->f_dpb = CDSp[dirname[0]-'A'].cdsDpb;
(dirname, &drive, (BYTE *) 0, (BYTE *) 0, (BYTE *) 0, if (fnp->f_dpb == 0)
FALSE) != SUCCESS)
{ {
release_f_node(fnp); release_f_node(fnp);
return NULL; 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 */ /* for testing only for now */
#if 0 #if 0
if ((cdsp->cdsFlags & CDSNETWDRV)) if ((CDSp[dirname[0]-'A'].cdsFlags & CDSNETWDRV))
{ {
printf("FailSafe %x \n", Int21AX); printf("FailSafe %x \n", Int21AX);
return fnp; return fnp;
} }
#endif #endif
if (cdsp->cdsDpb == 0)
{
release_f_node(fnp);
return NULL;
}
fnp->f_dpb = cdsp->cdsDpb;
/* Perform all directory common handling after all special */ /* Perform all directory common handling after all special */
/* handling has been performed. */ /* handling has been performed. */
@ -150,15 +112,21 @@ f_node_ptr dir_open(BYTE * dirname)
/* */ /* */
/* Start from the root directory (dirstart = 0) */ /* 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); dir_init_fnode(fnp, 0);
for (p = pszPath; *p != '\0';) dirname += 2; /* Assume FAT style drive */
while(*dirname != '\0')
{ {
/* skip all path seperators */ /* skip all path seperators */
while (*p == '\\') while (*dirname == '\\')
++p; ++dirname;
/* don't continue if we're at the end */ /* don't continue if we're at the end */
if (*p == '\0') if (*dirname == '\0')
break; break;
/* Convert the name into an absolute name for */ /* 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++) for (i = 0; i < FNAME_SIZE; i++)
{ {
if (*p != '\0' && *p != '.' && *p != '/' && *p != '\\') if (*dirname != '\0' && *dirname != '.' && *dirname != '/' &&
TempBuffer[i] = *p++; *dirname != '\\')
TempBuffer[i] = *dirname++;
else else
break; break;
} }
/* and the extension (don't forget to */ /* and the extension (don't forget to */
/* add trailing spaces)... */ /* add trailing spaces)... */
if (*p == '.') if (*dirname == '.')
++p; ++dirname;
for (i = 0; i < FEXT_SIZE; i++) for (i = 0; i < FEXT_SIZE; i++)
{ {
if (*p != '\0' && *p != '.' && *p != '/' && *p != '\\') if (*dirname != '\0' && *dirname != '.' && *dirname != '/' &&
TempBuffer[i + FNAME_SIZE] = *p++; *dirname != '\\')
TempBuffer[i + FNAME_SIZE] = *dirname++;
else else
break; break;
} }
@ -191,27 +161,18 @@ f_node_ptr dir_open(BYTE * dirname)
/* find the entry... */ /* find the entry... */
i = FALSE; i = FALSE;
DosUpFMem((BYTE FAR *) TempBuffer, FNAME_SIZE + FEXT_SIZE);
while (dir_read(fnp) == 1) while (dir_read(fnp) == 1)
{ {
if (fnp->f_dir.dir_name[0] != '\0' if (!(fnp->f_dir.dir_attrib & D_VOLID) &&
&& fnp->f_dir.dir_name[0] != DELETED fcbmatch(TempBuffer, fnp->f_dir.dir_name))
&& !(fnp->f_dir.dir_attrib & D_VOLID))
{
if (fcmp
(TempBuffer, (BYTE *) fnp->f_dir.dir_name,
FNAME_SIZE + FEXT_SIZE))
{ {
i = TRUE; i = TRUE;
break; break;
} }
} }
}
if (!i || !(fnp->f_dir.dir_attrib & D_DIR)) if (!i || !(fnp->f_dir.dir_attrib & D_DIR))
{ {
release_f_node(fnp); release_f_node(fnp);
return (f_node_ptr) 0; return (f_node_ptr) 0;
} }
@ -225,6 +186,15 @@ f_node_ptr dir_open(BYTE * dirname)
return fnp; 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. /* Description.
* Read next consequitive directory entry, pointed by fnp. * Read next consequitive directory entry, pointed by fnp.
* If some error occures the other critical * 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], b_buffer[((UWORD) new_diroff) % fnp->f_dpb->dpb_secsize],
(struct dirent FAR *)&fnp->f_dir); (struct dirent FAR *)&fnp->f_dir);
swap_deleted(fnp->f_dir.dir_name);
/* Update the fnode's directory info */ /* Update the fnode's directory info */
fnp->f_flags.f_dmod = FALSE; fnp->f_flags.f_dmod = FALSE;
fnp->f_flags.f_dnew = 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) if (fnp->f_flags.f_dnew && fnp->f_dir.dir_attrib != D_LFN)
fmemset(&fnp->f_dir.dir_case, 0, 8); fmemset(&fnp->f_dir.dir_case, 0, 8);
swap_deleted(fnp->f_dir.dir_name);
putdirent((struct dirent FAR *)&fnp->f_dir, putdirent((struct dirent FAR *)&fnp->f_dir,
(VOID FAR *) & bp->b_buffer[(UWORD) fnp->f_diroff % (VOID FAR *) & bp->b_buffer[(UWORD) fnp->f_diroff %
fnp->f_dpb->dpb_secsize]); fnp->f_dpb->dpb_secsize]);
swap_deleted(fnp->f_dir.dir_name);
bp->b_flag &= ~(BFR_DATA | BFR_FAT); bp->b_flag &= ~(BFR_DATA | BFR_FAT);
bp->b_flag |= BFR_DIR | BFR_DIRTY | BFR_VALID; bp->b_flag |= BFR_DIR | BFR_DIRTY | BFR_VALID;
} }
@ -422,6 +399,7 @@ VOID dir_close(REG f_node_ptr fnp)
#endif #endif
/* Clear buffers after release */ /* Clear buffers after release */
/* hazard: no error checking! */
flush_buffers(fnp->f_dpb->dpb_unit); flush_buffers(fnp->f_dpb->dpb_unit);
/* and release this instance of the fnode */ /* and release this instance of the fnode */
@ -434,10 +412,6 @@ COUNT dos_findfirst(UCOUNT attr, BYTE * name)
REG f_node_ptr fnp; REG f_node_ptr fnp;
REG dmatch *dmp = (dmatch *) TempBuffer; REG dmatch *dmp = (dmatch *) TempBuffer;
REG COUNT i; REG COUNT i;
COUNT nDrive;
BYTE *p;
BYTE local_name[FNAME_SIZE + 1], local_ext[FEXT_SIZE + 1];
/* printf("ff %Fs\n", name);*/ /* 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. */ /* current directory, do a seek and read, then close the fnode. */
/* Parse out the drive, file name and file extension. */ /* Parse out the drive, file name and file extension. */
i = ParseDosName(name, &nDrive, &szDirName[2], local_name, local_ext, i = ParseDosName(name, SearchDir.dir_name, TRUE);
TRUE); if (i < SUCCESS)
if (i != SUCCESS)
return i; return i;
/* /*
printf("\nff %s", Tname); printf("\nff %s", Tname);
printf("ff %s", local_name); printf("ff %s", fcbname);
printf("ff %s\n", local_ext);
*/ */
/* 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... */ /* 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 */ /* Special handling - the volume id is only in the root */
/* directory and only searched for once. So we need to open */ /* directory and only searched for once. So we need to open */
/* the root and return only the first entry that contains the */ /* the root and return only the first entry that contains the */
/* volume id bit set. */ /* volume id bit set. */
if (attr == D_VOLID) if (attr == D_VOLID)
{ i = 3;
szDirName[2] = '\\';
szDirName[3] = '\0';
}
/* Now open this directory so that we can read the */ /* Now open this directory so that we can read the */
/* fnode entry and do a match on it. */ /* fnode entry and do a match on it. */
/* printf("dir_open %s\n", szDirName);*/ /* printf("dir_open %s\n", szDirName);*/
if ((fnp = dir_open(szDirName)) == NULL) {
char tmp = name[i];
name[i] = '\0';
if ((fnp = dir_open(name)) == NULL)
return DE_PATHNOTFND; return DE_PATHNOTFND;
name[i] = tmp;
}
/* Now initialize the dirmatch structure. */ /* Now initialize the dirmatch structure. */
nDrive = get_verify_drive(name); dmp->dm_drive = name[0] - 'A';
if (nDrive < 0)
return nDrive;
dmp->dm_drive = nDrive;
dmp->dm_attr_srch = attr; dmp->dm_attr_srch = attr;
/* Copy the raw pattern from our data segment to the DTA. */ /* 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 if (fnp->f_dir.dir_name[0] != '\0' && fnp->f_dir.dir_name[0] != DELETED
&& (fnp->f_dir.dir_attrib & D_VOLID) != D_VOLID) && (fnp->f_dir.dir_attrib & D_VOLID) != D_VOLID)
{ {
if (fcmp_wild if (fcmp_wild(dmp->dm_name_pat, fnp->f_dir.dir_name, FNAME_SIZE + FEXT_SIZE))
((BYTE FAR *) dmp->dm_name_pat, (BYTE FAR *) fnp->f_dir.dir_name,
FNAME_SIZE + FEXT_SIZE))
{ {
/* /*
MSD Command.com uses FCB FN 11 & 12 with attrib set to 0x16. 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'; *destSZ = '\0';
} }
#if 0
/* /*
returns the asciiSZ length of a 8.3 filename returns the asciiSZ length of a 8.3 filename
*/ */
@ -706,6 +653,7 @@ int FileName83Length(BYTE * filename83)
return strlen(buff); return strlen(buff);
} }
#endif
/* /*
* Log: fatdir.c,v - for newer log entries do a "cvs log fatdir.c" * 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); f_node_ptr xlt_fd(COUNT);
COUNT xlt_fnp(f_node_ptr); COUNT xlt_fnp(f_node_ptr);
f_node_ptr split_path(BYTE *, BYTE *, BYTE *); STATIC f_node_ptr split_path(char *, char *);
BOOL find_fname(f_node_ptr, BYTE *, BYTE *, int); BOOL find_fname(f_node_ptr, char *, int);
/* /// Added - Ron Cemer */ /* /// Added - Ron Cemer */
STATIC void merge_file_changes(f_node_ptr fnp, int collect); STATIC void merge_file_changes(f_node_ptr fnp, int collect);
/* /// Added - Ron Cemer */ /* /// 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 */ /* Open a file given the path. Flags is 0 for read, 1 for write and 2 */
/* for update. */ /* 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; 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... */ /* file mode... */
if (flag < 0 || flag > 2) if ((flags & 3) > 2)
return DE_INVLDACC; return DE_INVLDACC;
/* first split the passed dir into comopnents (i.e. - path to */ /* first split the passed dir into comopnents (i.e. - path to */
/* new directory and name of new directory. */ /* 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; return DE_PATHNOTFND;
/* 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;
} }
/* Look for the file. If we can't find it, just return a not */ /* Release the existing files FAT and set the */
/* found error. */ /* length to zero, effectively truncating the */
if (!find_fname(fnp, szFileName, szFileExt, D_ALL)) /* 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); dir_close(fnp);
return DE_FILENOTFND; return DE_FILENOTFND;
} }
/* Set the fnode to the desired mode */ /* Set the fnode to the desired mode */
fnp->f_mode = flag; /* Updating the directory entry first. */
fnp->f_mode = flags & 3;
/* Initialize the rest of the fnode. */ 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;
}
}
/* 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;
/* 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_offset = 0l;
fnp->f_highwater = fnp->f_dir.dir_size; fnp->f_highwater = fnp->f_dir.dir_size;
fnp->f_back = LONG_LAST_CLUSTER; fnp->f_back = LONG_LAST_CLUSTER;
if (status != S_OPENED)
{
fnp->f_cluster = FREE;
setdstart(fnp->f_dir, FREE);
fnp->f_cluster_offset = 0l; /*JPP */
}
fnp->f_flags.f_dmod = FALSE; fnp->f_flags.f_dmod = (status != S_OPENED);
fnp->f_flags.f_ddate = FALSE;
fnp->f_flags.f_dnew = FALSE; fnp->f_flags.f_dnew = FALSE;
fnp->f_flags.f_ddir = 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 */ /* /// Moved from above. - Ron Cemer */
fnp->f_cluster = getdstart(fnp->f_dir); fnp->f_cluster = getdstart(fnp->f_dir);
fnp->f_cluster_offset = 0l; /*JPP */ 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) BOOL fcmp_wild(const char * s1, const char * s2, unsigned n)
{
while (n--)
if (*s1++ != *s2++)
return FALSE;
return TRUE;
}
BOOL fcmp_wild(BYTE FAR * s1, BYTE FAR * s2, COUNT n)
{ {
while (n--) while (n--)
{ {
@ -203,31 +298,15 @@ COUNT dos_commit(COUNT fd)
/* */ /* */
/* split a path into it's component directory and file name */ /* 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; REG f_node_ptr fnp;
COUNT nDrive;
struct cds FAR *cdsp;
/* Start off by parsing out the components. */ /* Start off by parsing out the components. */
if (ParseDosName(path, &nDrive, &szDirName[2], fname, fext, FALSE) int dirlength = ParseDosName(path, fcbname, FALSE);
!= SUCCESS)
if (dirlength < SUCCESS)
return (f_node_ptr) 0; 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 /* 11/29/99 jt
* Networking and Cdroms. You can put in here a return. * 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 #ifdef DEBUG
if (cdsp->cdsFlags & CDSNETWDRV) if (CDSp[path[0]-'A'].cdsFlags & CDSNETWDRV)
{ {
printf("split path called for redirected file: `%s.%s'\n", printf("split path called for redirected file: `%s.%s'\n",
fname, fext); fname, fext);
@ -250,7 +329,12 @@ f_node_ptr split_path(BYTE * path, BYTE * fname, BYTE * fext)
#endif #endif
/* Translate the path into a useful pointer */ /* 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 */ /* If the fd was invalid because it was out of range or the */
/* requested file was not open, tell the caller and exit... */ /* 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; 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; 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) while (dir_read(fnp) == 1)
{ {
if (fnp->f_dir.dir_name[0] != DELETED if (fcbmatch(fnp->f_dir.dir_name, fcbname)
&& fcmp(fname, (BYTE *) fnp->f_dir.dir_name, FNAME_SIZE)
&& fcmp(fext, (BYTE *) fnp->f_dir.dir_ext, FEXT_SIZE)
&& (fnp->f_dir.dir_attrib & ~(D_RDONLY | D_ARCHIVE | attr)) == 0) && (fnp->f_dir.dir_attrib & ~(D_RDONLY | D_ARCHIVE | attr)) == 0)
{ {
return TRUE; return TRUE;
@ -375,12 +470,7 @@ STATIC int is_same_file(f_node_ptr fnp1, f_node_ptr fnp2)
return return
(fnp1->f_dpb->dpb_unit == fnp2->f_dpb->dpb_unit) (fnp1->f_dpb->dpb_unit == fnp2->f_dpb->dpb_unit)
&& (fnp1->f_dpb->dpb_subunit == fnp2->f_dpb->dpb_subunit) && (fnp1->f_dpb->dpb_subunit == fnp2->f_dpb->dpb_subunit)
&& (fcmp && (fcbmatch(fnp1->f_dir.dir_name, fnp2->f_dir.dir_name))
((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))
&& ((fnp1->f_dir.dir_attrib & D_VOLID) == 0) && ((fnp1->f_dir.dir_attrib & D_VOLID) == 0)
&& ((fnp2->f_dir.dir_attrib & D_VOLID) == 0) && ((fnp2->f_dir.dir_attrib & D_VOLID) == 0)
&& (fnp1->f_diroff == fnp2->f_diroff) && (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; 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) STATIC COUNT delete_dir_entry(f_node_ptr fnp)
{ {
COUNT rc; COUNT rc;
@ -529,17 +517,18 @@ STATIC COUNT delete_dir_entry(f_node_ptr fnp)
COUNT dos_delete(BYTE * path, int attrib) COUNT dos_delete(BYTE * path, int attrib)
{ {
REG f_node_ptr fnp; REG f_node_ptr fnp;
char fcbname[FNAME_SIZE + FEXT_SIZE];
/* first split the passed dir into components (i.e. - */ /* first split the passed dir into components (i.e. - */
/* path to new directory and name of new directory */ /* 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; return DE_PATHNOTFND;
} }
/* Check that we don't have a duplicate name, so if we */ /* Check that we don't have a duplicate name, so if we */
/* find one, it's an error. */ /* 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 */ /* Do not delete directories or r/o files */
/* lfn entries and volume labels are only found */ /* 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 fnp;
REG f_node_ptr fnp1; REG f_node_ptr fnp1;
BOOL found; BOOL found;
char fcbname[FNAME_SIZE + FEXT_SIZE];
/* first split the passed dir into comopnents (i.e. - */ /* first split the passed dir into comopnents (i.e. - */
/* path to new directory and name of new directory */ /* 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; return DE_PATHNOTFND;
} }
@ -583,7 +573,7 @@ COUNT dos_rmdir(BYTE * path)
/* Check that we don't have a duplicate name, so if we */ /* Check that we don't have a duplicate name, so if we */
/* find one, it's an error. */ /* 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, */ /* The only permissable attribute is directory, */
/* check for any other bit set. If it is, give */ /* 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; REG f_node_ptr fnp2;
BOOL is_free; BOOL is_free;
COUNT ret; COUNT ret;
char fcbname[FNAME_SIZE + FEXT_SIZE];
/* first split the passed target into compnents (i.e. - path to */ /* first split the passed target into compnents (i.e. - path to */
/* new file name and name of new file name */ /* 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; return DE_PATHNOTFND;
} }
/* Check that we don't have a duplicate name, so if we find */ /* Check that we don't have a duplicate name, so if we find */
/* one, it's an error. */ /* one, it's an error. */
if (find_fname(fnp2, szFileName, szFileExt, attrib)) if (find_fname(fnp2, fcbname, attrib))
{ {
dir_close(fnp2); dir_close(fnp2);
return DE_ACCESS; 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 */ /* next split the passed source into compnents (i.e. - path to */
/* old file name and name of old file name */ /* 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); dir_close(fnp2);
return DE_PATHNOTFND; return DE_PATHNOTFND;
} }
if (!find_fname(fnp1, szFileName, szFileExt, attrib)) if (!find_fname(fnp1, fcbname, attrib))
{ {
/* No such file, return the error */ /* No such file, return the error */
dir_close(fnp1); 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 */ /* Reset the directory by a close followed by an open */
fnp2->f_flags.f_dmod = FALSE; fnp2->f_flags.f_dmod = FALSE;
dir_close(fnp2); dir_close(fnp2);
fnp2 = split_path(path2, szFileName, szFileExt); fnp2 = split_path(path2, fcbname);
/* Now find a free slot to put the file into. */ /* Now find a free slot to put the file into. */
/* If it's the root and we don't have room, return an error. */ /* 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; return ret;
/* put the fnode's name into the directory. */ /* put the fnode's name into the directory. */
memcpy(fnp2->f_dir.dir_name, szFileName, FNAME_SIZE); memcpy(fnp2->f_dir.dir_name, fcbname, FNAME_SIZE + FEXT_SIZE);
memcpy(fnp2->f_dir.dir_ext, szFileExt, FEXT_SIZE);
/* Set the fnode to the desired mode */ /* Set the fnode to the desired mode */
fnp2->f_dir.dir_size = fnp1->f_dir.dir_size; 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); next = next_cluster(dpbp, st);
/* just exit if a damaged file system exists */ /* just exit if a damaged file system exists */
if (next == FREE) if (next == FREE || next == 1)
return; return;
/* zap the FAT pointed to */ /* zap the FAT pointed to */
@ -820,15 +810,13 @@ STATIC BOOL find_free(f_node_ptr fnp)
/* */ /* */
date dos_getdate() date dos_getdate()
{ {
BYTE WeekDay, Month, MonthDay; UBYTE WeekDay, Month, MonthDay;
COUNT Year; UWORD Year;
date Date; date Date;
/* First - get the system date set by either the user */ /* First - get the system date set by either the user */
/* on start-up or the CMOS clock */ /* on start-up or the CMOS clock */
DosGetDate((BYTE FAR *) & WeekDay, DosGetDate(&WeekDay, &Month, &MonthDay, &Year);
(BYTE FAR *) & Month,
(BYTE FAR *) & MonthDay, (COUNT FAR *) & Year);
Date = DT_ENCODE(Month, MonthDay, Year - EPOCH_YEAR); Date = DT_ENCODE(Month, MonthDay, Year - EPOCH_YEAR);
return Date; return Date;
} }
@ -838,13 +826,11 @@ date dos_getdate()
/* */ /* */
time dos_gettime() time dos_gettime()
{ {
BYTE Hour, Minute, Second, Hundredth; UBYTE Hour, Minute, Second, Hundredth;
/* First - get the system time set by either the user */ /* First - get the system time set by either the user */
/* on start-up or the CMOS clock */ /* on start-up or the CMOS clock */
DosGetTime((BYTE FAR *) & Hour, DosGetTime(&Hour, &Minute, &Second, &Hundredth);
(BYTE FAR *) & Minute,
(BYTE FAR *) & Second, (BYTE FAR *) & Hundredth);
return TM_ENCODE(Hour, Minute, Second / 2); 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 */ /* dos_getfsize for the file time */
/* */ /* */
LONG dos_getcufsize(COUNT fd) ULONG dos_getfsize(COUNT fd)
{ {
f_node_ptr fnp; f_node_ptr fnp;
@ -913,33 +899,12 @@ LONG dos_getcufsize(COUNT fd)
/* requested file was not open, tell the caller and exit */ /* requested file was not open, tell the caller and exit */
/* note: an invalid fd is indicated by a 0 return */ /* note: an invalid fd is indicated by a 0 return */
if (fnp == (f_node_ptr) 0 || fnp->f_count <= 0) if (fnp == (f_node_ptr) 0 || fnp->f_count <= 0)
return -1l; return (ULONG)-1l;
/* Return the file size */ /* Return the file size */
return fnp->f_highwater; 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 */ /* dos_setfsize for the file time */
/* */ /* */
@ -1050,10 +1015,11 @@ COUNT dos_mkdir(BYTE * dir)
struct dpb FAR *dpbp; struct dpb FAR *dpbp;
CLUSTER free_fat, parent; CLUSTER free_fat, parent;
COUNT ret; COUNT ret;
char fcbname[FNAME_SIZE + FEXT_SIZE];
/* first split the passed dir into comopnents (i.e. - */ /* first split the passed dir into comopnents (i.e. - */
/* path to new directory and name of new directory */ /* 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; return DE_PATHNOTFND;
} }
@ -1074,7 +1040,7 @@ COUNT dos_mkdir(BYTE * dir)
/* Check that we don't have a duplicate name, so if we */ /* Check that we don't have a duplicate name, so if we */
/* find one, it's an error. */ /* find one, it's an error. */
if (find_fname(fnp, szFileName, szFileExt, D_ALL)) if (find_fname(fnp, fcbname, D_ALL))
{ {
dir_close(fnp); dir_close(fnp);
return DE_ACCESS; return DE_ACCESS;
@ -1085,7 +1051,7 @@ COUNT dos_mkdir(BYTE * dir)
fnp->f_flags.f_dmod = FALSE; fnp->f_flags.f_dmod = FALSE;
parent = fnp->f_dirstart; parent = fnp->f_dirstart;
dir_close(fnp); 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 */ /* Get a free f_node pointer so that we can use */
/* it in building the new file. */ /* it in building the new file. */
@ -1121,8 +1087,7 @@ COUNT dos_mkdir(BYTE * dir)
} }
/* put the fnode's name into the directory. */ /* put the fnode's name into the directory. */
memcpy(fnp->f_dir.dir_name, szFileName, FNAME_SIZE); memcpy(fnp->f_dir.dir_name, fcbname, FNAME_SIZE + FEXT_SIZE);
memcpy(fnp->f_dir.dir_ext, szFileExt, FEXT_SIZE);
/* Set the fnode to the desired mode */ /* Set the fnode to the desired mode */
fnp->f_mode = WRONLY; fnp->f_mode = WRONLY;
@ -1160,8 +1125,8 @@ COUNT dos_mkdir(BYTE * dir)
} }
/* Create the "." entry */ /* Create the "." entry */
memcpy(DirEntBuffer.dir_name, ". ", FNAME_SIZE); DirEntBuffer.dir_name[0] = '.';
memcpy(DirEntBuffer.dir_ext, " ", FEXT_SIZE); memset(DirEntBuffer.dir_name + 1, ' ', FNAME_SIZE + FEXT_SIZE - 1);
DirEntBuffer.dir_attrib = D_DIR; DirEntBuffer.dir_attrib = D_DIR;
DirEntBuffer.dir_time = dos_gettime(); DirEntBuffer.dir_time = dos_gettime();
DirEntBuffer.dir_date = dos_getdate(); DirEntBuffer.dir_date = dos_getdate();
@ -1169,10 +1134,10 @@ COUNT dos_mkdir(BYTE * dir)
DirEntBuffer.dir_size = 0l; DirEntBuffer.dir_size = 0l;
/* And put it out */ /* And put it out */
putdirent((struct dirent FAR *)&DirEntBuffer, (BYTE FAR *) bp->b_buffer); putdirent(&DirEntBuffer, bp->b_buffer);
/* create the ".." entry */ /* create the ".." entry */
memcpy(DirEntBuffer.dir_name, ".. ", FNAME_SIZE); DirEntBuffer.dir_name[1] = '.';
#ifdef WITHFAT32 #ifdef WITHFAT32
if (ISFAT32(dpbp) && parent == dpbp->dpb_xrootclst) if (ISFAT32(dpbp) && parent == dpbp->dpb_xrootclst)
{ {
@ -1182,8 +1147,7 @@ COUNT dos_mkdir(BYTE * dir)
setdstart(DirEntBuffer, parent); setdstart(DirEntBuffer, parent);
/* and put it out */ /* and put it out */
putdirent((struct dirent FAR *)&DirEntBuffer, putdirent(&DirEntBuffer, &bp->b_buffer[DIRENT_SIZE]);
(BYTE FAR *) & bp->b_buffer[DIRENT_SIZE]);
/* fill the rest of the block with zeros */ /* fill the rest of the block with zeros */
fmemset(&bp->b_buffer[2 * DIRENT_SIZE], 0, BUFFERSIZE - 2 * DIRENT_SIZE); 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 */ /* flush the drive buffers so that all info is written */
/* hazard: no error checking! */
flush_buffers((COUNT) (dpbp->dpb_unit)); flush_buffers((COUNT) (dpbp->dpb_unit));
/* Close the directory so that the entry is updated */ /* 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 */ /* flush the drive buffers so that all info is written */
/* hazard: no error checking! */
flush_buffers((COUNT) (fnp->f_dpb->dpb_unit)); flush_buffers((COUNT) (fnp->f_dpb->dpb_unit));
return SUCCESS; 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 = next_cluster(fnp->f_dpb, fnp->f_cluster);
fnp->f_cluster_offset += clssize; fnp->f_cluster_offset += clssize;
idx -= clssize; idx -= clssize;
if (fnp->f_cluster == 1)
return DE_SEEK;
} }
#ifdef DISPLAY_GETBLOCK #ifdef DISPLAY_GETBLOCK
@ -1578,8 +1546,8 @@ UCOUNT rwblock(COUNT fd, VOID FAR * buffer, UCOUNT count, int mode)
REG struct buffer FAR *bp; REG struct buffer FAR *bp;
UCOUNT xfr_cnt = 0; UCOUNT xfr_cnt = 0;
UCOUNT ret_cnt = 0; UCOUNT ret_cnt = 0;
UWORD secsize; unsigned secsize;
UCOUNT to_xfer = count; unsigned to_xfer = count;
ULONG currentblock; ULONG currentblock;
#if 0 /*DSK_DEBUG*/ #if 0 /*DSK_DEBUG*/
@ -1932,7 +1900,7 @@ COUNT dos_cd(struct cds FAR * cdsp, BYTE * PathName)
f_node_ptr get_f_node(void) f_node_ptr get_f_node(void)
{ {
REG i; REG int i;
for (i = 0; i < f_nodes_cnt; i++) for (i = 0; i < f_nodes_cnt; i++)
{ {
@ -1959,61 +1927,49 @@ VOID dos_setdta(BYTE FAR * newdta)
dta = newdta; dta = newdta;
} }
COUNT dos_getfattr(BYTE * name) COUNT dos_getfattr_fd(COUNT fd)
{ {
f_node_ptr fnp; f_node_ptr fnp = xlt_fd(fd);
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;
/* note: an invalid fd is indicated by a 0 return */ /* 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; return DE_TOOMANY;
/* If the fd was invalid because it was out of range or the */ /* If the fd was invalid because it was out of range or the */
/* requested file was not open, tell the caller and exit */ /* requested file was not open, tell the caller and exit */
if (fnp->f_count <= 0) if (fnp->f_count <= 0)
{
dos_close(fd);
return DE_FILENOTFND; return DE_FILENOTFND;
}
/* Get the attribute from the fnode and return */ return fnp->f_dir.dir_attrib;
result = 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); dos_close(fd);
return result; return result;
} }
COUNT dos_setfattr(BYTE * name, UWORD attrp) COUNT dos_setfattr(BYTE * name, UWORD attrp)
{ {
f_node_ptr fnp;
COUNT fd; 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 */ /* JPP-If user tries to set VOLID or DIR bits, return error */
if ((attrp & (D_VOLID | D_DIR | 0xC0)) != 0) if ((attrp & (D_VOLID | D_DIR | 0xC0)) != 0)
{
dos_close(fd);
return DE_ACCESS; 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 */ /* Set the attribute from the fnode and return */
/* clear all attributes but DIR and VOLID */ /* clear all attributes but DIR and VOLID */
@ -2094,8 +2050,6 @@ VOID bpb_to_dpb(bpb FAR * bpbp, REG struct dpb FAR * dpbp)
COUNT media_check(REG struct dpb FAR * dpbp) COUNT media_check(REG struct dpb FAR * dpbp)
{ {
BYTE status;
/* First test if anyone has changed the removable media */ /* First test if anyone has changed the removable media */
FOREVER FOREVER
{ {
@ -2105,10 +2059,8 @@ COUNT media_check(REG struct dpb FAR * dpbp)
MediaReqHdr.r_mcmdesc = dpbp->dpb_mdb; MediaReqHdr.r_mcmdesc = dpbp->dpb_mdb;
MediaReqHdr.r_status = 0; MediaReqHdr.r_status = 0;
execrh((request FAR *) & MediaReqHdr, dpbp->dpb_device); execrh((request FAR *) & MediaReqHdr, dpbp->dpb_device);
if (!(MediaReqHdr.r_status & S_ERROR) if ((MediaReqHdr.r_status & S_ERROR)
&& (MediaReqHdr.r_status & S_DONE)) || !(MediaReqHdr.r_status & S_DONE))
break;
else
{ {
loop1: loop1:
switch (block_error(&MediaReqHdr, dpbp->dpb_unit, dpbp->dpb_device)) switch (block_error(&MediaReqHdr, dpbp->dpb_unit, dpbp->dpb_device))
@ -2127,10 +2079,10 @@ COUNT media_check(REG struct dpb FAR * dpbp)
goto loop1; goto loop1;
} }
} }
break;
} }
status = MediaReqHdr.r_mcretcode | dpbp->dpb_flags; switch (MediaReqHdr.r_mcretcode | dpbp->dpb_flags)
switch (status)
{ {
case M_NOT_CHANGED: case M_NOT_CHANGED:
/* It was definitely not changed, so ignore it */ /* 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, */ /* If it is forced or the media may have changed, */
/* rebuild the bpb */ /* rebuild the bpb */
case M_DONT_KNOW: case M_DONT_KNOW:
/* hazard: no error checking! */
flush_buffers(dpbp->dpb_unit); flush_buffers(dpbp->dpb_unit);
/* If it definitely changed, don't know (falls through) */ /* 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_mcmdesc = dpbp->dpb_mdb;
MediaReqHdr.r_status = 0; MediaReqHdr.r_status = 0;
execrh((request FAR *) & MediaReqHdr, dpbp->dpb_device); execrh((request FAR *) & MediaReqHdr, dpbp->dpb_device);
if (!(MediaReqHdr.r_status & S_ERROR) if ((MediaReqHdr.r_status & S_ERROR)
&& (MediaReqHdr.r_status & S_DONE)) || !(MediaReqHdr.r_status & S_DONE))
break;
else
{ {
loop2: loop2:
switch (block_error switch (block_error
@ -2177,6 +2128,7 @@ COUNT media_check(REG struct dpb FAR * dpbp)
goto loop2; goto loop2;
} }
} }
break;
} }
#ifdef WITHFAT32 #ifdef WITHFAT32
/* extend dpb only for internal or FAT32 devices */ /* extend dpb only for internal or FAT32 devices */
@ -2185,9 +2137,6 @@ COUNT media_check(REG struct dpb FAR * dpbp)
#else #else
bpb_to_dpb(MediaReqHdr.r_bpptr, dpbp); bpb_to_dpb(MediaReqHdr.r_bpptr, dpbp);
#endif #endif
/* need to change to root directory if changed */
if (status == M_CHANGED)
CDSp[dpbp->dpb_unit].cdsCurrentPath[3] = '\0';
return SUCCESS; return SUCCESS;
} }
} }
@ -2249,7 +2198,7 @@ STATIC VOID shrink_file(f_node_ptr fnp)
next = next_cluster(dpbp, st); 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; goto done;
/* Loop from start until either a FREE entry is */ /* Loop from start until either a FREE entry is */

View File

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

View File

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

View File

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

View File

@ -255,6 +255,11 @@ _QRemote_Fn
global _remote_printredir global _remote_printredir
_remote_printredir: _remote_printredir:
mov al, 25h mov al, 25h
jmp short call_int2f
global _remote_extopen
_remote_extopen:
mov al, 2eh
call_int2f: call_int2f:
mov ah, 11h mov ah, 11h
@ -263,7 +268,6 @@ call_int2f:
push es push es
push si push si
push di push di
push dx
push cx push cx
push bx push bx
@ -275,10 +279,6 @@ call_int2f:
je print_doredir je print_doredir
cmp al, 1fh cmp al, 1fh
je print_doredir je print_doredir
cmp al, 21h ; 21h, Lseek from eof
je lseekeof
cmp al, 23h
je qremote_fn
cmp al, 25h cmp al, 25h
je remote_printredir je remote_printredir
@ -289,22 +289,27 @@ call_int2f:
je remote_rw je remote_rw
cmp al, 0ch cmp al, 0ch
je remote_getfree je remote_getfree
cmp al, 21h ; 21h, Lseek from eof
je lseekeof
cmp al, 23h
je qremote_fn
int2f_call_push: int2f_call_push:
push word [bp+8] ; very fakey, HaHa ;) push word [bp+8] ; very fakey, HaHa ;)
int2f_call: int2f_call:
clc ; set to succeed xor cx, cx ; set to succeed; clear carry and CX
int 2fh int 2fh
pop bx pop bx
jc no_clear_ax jc no_clear_ax
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: no_clear_ax:
neg ax neg ax
no_neg_ax: no_neg_ax:
pop bx pop bx
pop cx pop cx
pop dx
pop di pop di
pop si pop si
pop es pop es
@ -314,7 +319,7 @@ no_neg_ax:
lseekeof: lseekeof:
mov dx, [bp+8] mov dx, [bp+8]
mov cx, [bp+10] mov cx, [bp+10]
jmp int2f_call_push ; "fall through"
remote_getfattr: remote_getfattr:
clc ; set to succeed clc ; set to succeed
@ -359,16 +364,19 @@ remote_printredir:
push word [bp+6] push word [bp+6]
jmp short int2f_call jmp short int2f_call
remote_rw: jmp short remote_rw1
qremote_fn: qremote_fn:
lds si,[bp+4] push ds
les di,[bp+8] lds si,[bp+8]
clc clc
int 2fh int 2fh
pop ds
mov ax,0xffff mov ax,0xffff
jc no_neg_ax jc no_neg_ax
jmp short clear_ax jmp short clear_ax
remote_rw: mov cx, [bp+8] remote_rw1: mov cx, [bp+8]
clc ; set to succeed clc ; set to succeed
int 2fh int 2fh
jc int2f_carry jc int2f_carry
@ -377,7 +385,7 @@ int2f_carry: neg ax
mov di, [bp+10] mov di, [bp+10]
mov [di], ax mov [di], ax
mov ax, cx mov ax, cx
jmp short no_neg_ax jmp no_neg_ax
global _remote_process_end global _remote_process_end
_remote_process_end: ; Terminate process _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; sft FAR *s;
struct dpb FAR *dpbp; struct dpb FAR *dpbp;
@ -78,10 +78,106 @@ COUNT DosDevIOctl(iregs FAR * r)
case 0x07: case 0x07:
case 0x0a: case 0x0a:
case 0x0c: case 0x0c:
case 0x10:
/* Get the SFT block that contains the SFT */ /* Get the SFT block that contains the SFT */
if ((s = get_sft(r->BX)) == (sft FAR *) - 1) if ((s = get_sft(r->BX)) == (sft FAR *) - 1)
return DE_INVLDHNDL; 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; break;
case 0x04: case 0x04:
@ -91,7 +187,6 @@ COUNT DosDevIOctl(iregs FAR * r)
case 0x0d: case 0x0d:
case 0x0e: case 0x0e:
case 0x0f: case 0x0f:
case 0x10:
case 0x11: case 0x11:
/* /*
@ -113,100 +208,48 @@ COUNT DosDevIOctl(iregs FAR * r)
/* cdsp = &CDSp[CharReqHdr.r_unit]; */ /* cdsp = &CDSp[CharReqHdr.r_unit]; */
dpbp = CDSp[CharReqHdr.r_unit].cdsDpb; dpbp = CDSp[CharReqHdr.r_unit].cdsDpb;
} }
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) 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: case 0x04:
nMode = C_IOCTLIN; nMode = C_IOCTLIN;
goto IoBlockCommon; goto IoBlockCommon;
case 0x11:
nMode = C_IOCTLQRY;
goto IoBlockCommon;
case 0x05: case 0x05:
nMode = C_IOCTLOUT; 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: IoBlockCommon:
if (!dpbp) if (!dpbp)
{ {
@ -233,13 +276,11 @@ COUNT DosDevIOctl(iregs FAR * r)
if (r->AL == 0x08) if (r->AL == 0x08)
{ {
r->AX = (CharReqHdr.r_status & S_BUSY) ? 1 : 0; r->AX = (CharReqHdr.r_status & S_BUSY) ? 1 : 0;
} }
else if (r->AL == 0x04 || r->AL == 0x05) else if (r->AL == 0x04 || r->AL == 0x05)
{ {
r->AX = CharReqHdr.r_count; r->AX = CharReqHdr.r_count;
} }
else if (r->AL == 0x0d || r->AL == 0x11) else if (r->AL == 0x0d || r->AL == 0x11)
{ {
@ -247,59 +288,6 @@ COUNT DosDevIOctl(iregs FAR * r)
} }
break; 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: case 0x0e:
nMode = C_GETLDEV; nMode = C_GETLDEV;
goto IoLogCommon; goto IoLogCommon;
@ -326,8 +314,18 @@ COUNT DosDevIOctl(iregs FAR * r)
r->AL = CharReqHdr.r_unit; r->AL = CharReqHdr.r_unit;
return SUCCESS; return SUCCESS;
} }
} } /* fall through */
default:
return DE_INVLDFUNC; return DE_INVLDFUNC;
}
break;
case 0x0b:
/* skip, it's a special case. */
NetDelay = r->CX;
if (!r->DX)
NetRetry = r->DX;
break;
default: default:
return DE_INVLDFUNC; return DE_INVLDFUNC;

View File

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

View File

@ -74,13 +74,13 @@ int DosMkTmp(BYTE FAR * pathname, UWORD attr)
{ {
/* create filename from current date and time */ /* create filename from current date and time */
char FAR *ptmp = pathname; char FAR *ptmp = pathname;
BYTE wd, month, day; UBYTE wd, month, day;
BYTE h, m, s, hund; UBYTE h, m, s, hund;
WORD sh; UWORD sh;
WORD year; UWORD year;
int rc; int rc;
char name83[13]; char name83[13];
int loop; int loop = 0;
while (*ptmp) while (*ptmp)
ptmp++; ptmp++;
@ -88,52 +88,153 @@ int DosMkTmp(BYTE FAR * pathname, UWORD attr)
if (ptmp == pathname || (ptmp[-1] != '\\' && ptmp[-1] != '/')) if (ptmp == pathname || (ptmp[-1] != '\\' && ptmp[-1] != '/'))
*ptmp++ = '\\'; *ptmp++ = '\\';
DosGetDate(&wd, &month, &day, (COUNT FAR *) & year); DosGetDate(&wd, &month, &day, &year);
DosGetTime(&h, &m, &s, &hund); DosGetTime(&h, &m, &s, &hund);
sh = s * 100 + hund; sh = s * 100 + hund;
for (loop = 0; loop < 0xfff; loop++) do {
{
sprintf(name83, "%x%x%x%x%x%03x.%03x", sprintf(name83, "%x%x%x%x%x%03x.%03x",
year & 0xf, month & 0xf, day & 0xf, h & 0xf, m & 0xf, year & 0xf, month & 0xf, day & 0xf, h & 0xf, m & 0xf,
sh & 0xfff, loop & 0xfff); sh & 0xfff, loop & 0xfff);
fmemcpy(ptmp, name83, 13); fmemcpy(ptmp, name83, 13);
if ((rc = DosOpen(pathname, 0)) < 0 && rc != DE_ACCESS /* subdirectory ?? */ /* only create new file -- 2001/09/22 ska*/
/* todo: sharing collision on rc = (short)DosOpen(pathname, O_LEGACY | O_CREAT | O_RDWR, attr);
network drive } while (rc == DE_FILEEXISTS && loop++ < 0xfff);
*/
)
break;
if (rc >= 0)
DosClose(rc);
}
if (rc == DE_FILENOTFND)
{
rc = DosCreat(pathname, attr);
}
return rc; 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; UBYTE drive;
unsigned flags;
/* Do we have a drive? */ /* Do we have a drive? */
if (src[1] == ':') if (src[1] == ':')
drive = ((src[0] - 1) | 0x20) - ('a' - 1); drive = drLetterToNr(DosUpFChar(src[0]));
else
return default_drive;
if (drive < lastdrive && CDSp[drive].cdsFlags & CDSVALID)
return drive;
else else
drive = default_drive;
if (drive >= lastdrive)
return DE_INVLDDRV; 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. * Added support for external and internal calls.
* Clean buffer before use. Make the true path and expand file names. * 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"; int retval = SUCCESS;
char *bufp = buf + 3; char *p = *cp;
COUNT i, rootEndPos = 2; /* renamed x to rootEndPos - Ron Cemer */ 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; struct dhdr FAR *dhp;
BYTE FAR *froot; const char FAR *froot;
WORD d; 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'; tn_printf(("truename(%S)\n", src));
i = get_verify_drive(src);
if (i < 0)
return DE_INVLDDRV;
buf[0] = i + 'A';
buf[1] = ':'; /* Just to be sure */
/* First, adjust the source pointer */ /* First, adjust the source pointer */
src = adjust_far(src); 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? */ /* Do we have a drive? */
if (src[1] == ':') if (src[1] == ':')
src += 2; src += 2;
@ -188,344 +389,320 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
*/ */
/* check for a device */ /* check for a device */
if ((*src != '.') && (*src != '\\') && (*src != '/') dest[2] = '\\';
&& ((dhp = IsDevice(src)) != NULL)) if (result & IS_DEVICE)
{ {
froot = get_root(src); froot = get_root(src);
if (froot == src || froot == src + 5)
{
if (froot == src + 5)
{
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 /* /// Bugfix: NUL.LST is the same as NUL. This is true for all
devices. On a device name, the extension is irrelevant devices. On a device name, the extension is irrelevant
as long as the name matches. as long as the name matches.
- Ron Cemer */ - Ron Cemer */
dest[2] = '/';
buf[2] = '/'; result &= ~IS_NETWORK;
/* /// 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 return C:/NUL.LST if you pass NUL.LST in.
DOS will also return C:/NUL.??? if you pass NUL.* in. DOS will also return C:/NUL.??? if you pass NUL.* in.
Code added here to support this. Code added here to support this.
- Ron Cemer */ - Ron Cemer */
while ((*froot != '.') && (*froot != '\0')) src = froot;
froot++;
if (*froot)
froot++;
if (*froot)
{
*bufp++ = '.';
for (i = 0; i < FEXT_SIZE; i++)
{
if ((*froot == '\0') || (*froot == '.'))
break;
if (*froot == '*')
{
for (; i < FEXT_SIZE; i++)
*bufp++ = '?';
break;
}
*bufp++ = *froot++;
} }
} }
/* /// End of code additions. - Ron Cemer */
goto exit_tn;
} }
/* /// Added to adjust for filenames which begin with ".\" /* Make fully-qualified logical path */
* The problem was manifesting itself in the inability /* register these two used characters and the \0 terminator byte */
* to run an program whose filename (without the extension) /* we always append the current dir to stat the drive;
* was longer than six characters and the PATH variable the only exceptions are devices without paths */
* contained ".", unless you explicitly specified the full rootPos = p = dest + 2;
* path to the executable file. if (*p != '/') /* i.e., it's a backslash! */
* Jun 11, 2000 - rbc */ {
/* /// Changed to "while" from "if". - Ron Cemer */ if (!(mode & CDS_MODE_SKIP_PHYSICAL))
while ((src[0] == '.') && (src[1] == '\\')) {
src += 2; 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. */
current_ldt = &CDSp[i]; fmemcpy(dest, cdsEntry->cdsCurrentPath, cdsEntry->cdsBackslashOffset);
if (cdsEntry->cdsFlags & CDSSUBST)
{
/* 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]);
/* Always give the redirector a chance to rewrite the filename */ if (i < lastdrive) /* sanity check #2 */
fmemcpy(bufp - 1, src, sizeof(buf) - (bufp - buf)); result = (result & 0xffe0) | i;
if ((t == FALSE) && (QRemote_Fn(buf, dest) == SUCCESS)
&& (dest[0] != '\0'))
{
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)
{
while (*bufp)
bufp++;
*bufp++ = '\\';
} }
} }
else 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++; src++;
/* remove trailing separator */
/*move_name:*/ if (p[-1] == '\\') p--;
/* /// 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 */ /* append the path specified in src */
while (bufp[-1] == '\\') addSep = ADD; /* add separator */
--bufp;
#endif
/* /// Beginning of new code. - Ron Cemer */ while(*src)
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++)
{
c = src[seglen];
if (c == '\0')
{
error = DE_FILENOTFND;
break;
}
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 /* New segment. If any wildcards in previous
segment(s), this is an invalid path. */ segment(s), this is an invalid path. */
if (gotAnyWildcards || src[0] == '.') if (gotAnyWildcards)
return error; return DE_PATHNOTFND;
/* Append current path segment to result. */ switch(*src++)
*(bufp++) = '\\'; {
if (bufp >= bufend) case '/':
case '\\': /* skip multiple separators (duplicated slashes) */
addSep = ADD;
break; break;
copylen = state = 0; case '.': /* special directory component */
for (i = 0; ((i < seglen) && (bufp < bufend)); i++) switch(*src)
{ {
c = src[i]; case '/':
gotAnyWildcards |= ((c == '?') || (c == '*')); case '\\':
switch (state) 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 0: /* Copying filename (excl. extension) */ case '/':
if (c == '*') case '\\':
{ case '\0':
while (copylen < FNAME_SIZE) /* remove last path component */
{ while(*--p != '\\')
*(bufp++) = '?'; if (p <= rootPos) /* already on root */
if (bufp >= bufend) return DE_PATHNOTFND;
break; /* the separator was removed -> add it again */
copylen++; ++src; /* skip the second dot */
} /* If / or \, next turn will find them and
break; assign addSep = ADD */
} addSep = ADD_UNLESS_LAST;
if (c == '.') continue; /* next char */
{
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) ) */
}
/* /// End of new code. - Ron Cemer */
if (bufp == buf + 2) /* ill-formed .* or ..* entries => return error */
++bufp; 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;
}
exit_tn: /* 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('\\');
}
*bufp++ = 0; *p = '\0'; /* add the string terminator */
DosUpFString(rootPos); /* upcase the file/path name */
/* finally, uppercase everything */ /** Note:
DosUpString(buf); 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 **/
/* copy to user's buffer */ tn_printf(("Absolute logical path: \"%s\"\n", dest));
fmemcpy(dest, buf, bufp - buf);
return SUCCESS; /* Now, all the steps 1) .. 7) are fullfilled. Join now */
/* search, if this path is a joined drive */
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" * 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 * Called for DOS-66-01 get CP
*/ */
COUNT DosGetCodepage(UWORD FAR * actCP, UWORD FAR * sysCP) COUNT DosGetCodepage(UWORD * actCP, UWORD * sysCP)
{ {
*sysCP = nlsInfo.sysCodePage; *sysCP = nlsInfo.sysCodePage;
*actCP = nlsInfo.actPkg->cp; *actCP = nlsInfo.actPkg->cp;

View File

@ -50,6 +50,7 @@ UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks,
/* *** End of change */ /* *** End of change */
/* chario.c */ /* chario.c */
UCOUNT BinaryCharIO(struct dhdr FAR * dev, UCOUNT n, void FAR * bp, unsigned command, COUNT *err);
VOID sto(COUNT c); VOID sto(COUNT c);
VOID cso(COUNT c); VOID cso(COUNT c);
VOID mod_cso(REG UCOUNT c); VOID mod_cso(REG UCOUNT c);
@ -66,36 +67,33 @@ UCOUNT sti(keyboard * kp);
sft FAR *get_sft(UCOUNT); sft FAR *get_sft(UCOUNT);
/* dosfns.c */ /* dosfns.c */
BYTE FAR *get_root(BYTE FAR *); const char FAR *get_root(const char FAR *);
BOOL check_break(void); BOOL check_break(void);
UCOUNT GenericReadSft(sft far * sftp, UCOUNT n, BYTE FAR * bp, UCOUNT GenericReadSft(sft far * sftp, UCOUNT n, void FAR * bp,
COUNT FAR * err, BOOL force_binary); COUNT * err, BOOL force_binary);
COUNT SftSeek(sft FAR * sftp, LONG new_pos, COUNT mode); COUNT SftSeek(sft FAR * sftp, LONG new_pos, COUNT mode);
/*COUNT DosRead(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err); */ /*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) UCOUNT BinaryReadSft(sft FAR * s, void *bp, COUNT *err);
#define DosRead(hndl, n, bp, err) GenericRead(hndl, n, bp, err, FALSE) #define BinaryRead(hndl, bp, err) BinaryReadSft(get_sft(hndl), bp, err)
#define DosReadSft(sftp, n, bp, err) GenericReadSft(sftp, n, bp, err, FALSE) UCOUNT DosRWSft(sft FAR * s, UCOUNT n, void FAR * bp, COUNT *err, int mode);
UCOUNT DosWriteSft(sft FAR * sftp, UCOUNT n, const BYTE FAR * bp, #define DosRead(hndl, n, bp, err) DosRWSft(get_sft(hndl), n, bp, err, XFR_READ)
COUNT FAR * err); #define DosWrite(hndl, n, bp, err) DosRWSft(get_sft(hndl), n, bp, err, XFR_WRITE)
#define DosWrite(hndl, n, bp, err) DosWriteSft(get_sft(hndl), n, bp, err) ULONG DosSeek(COUNT hndl, LONG new_pos, COUNT mode);
COUNT DosSeek(COUNT hndl, LONG new_pos, COUNT mode, ULONG * set_pos); long DosOpen(char FAR * fname, unsigned flags, unsigned attrib);
COUNT DosCreat(BYTE FAR * fname, COUNT attrib); COUNT CloneHandle(unsigned hndl);
COUNT DosCreatSft(BYTE * fname, COUNT attrib); long DosDup(unsigned Handle);
COUNT CloneHandle(COUNT hndl); COUNT DosForceDup(unsigned OldHandle, unsigned NewHandle);
COUNT DosDup(COUNT Handle); long DosOpenSft(char FAR * fname, unsigned flags, unsigned attrib);
COUNT DosForceDup(COUNT OldHandle, COUNT NewHandle);
COUNT DosOpen(BYTE FAR * fname, COUNT mode);
COUNT DosOpenSft(BYTE * fname, COUNT mode);
COUNT DosClose(COUNT hndl); COUNT DosClose(COUNT hndl);
COUNT DosCloseSft(WORD sft_idx, BOOL commitonly); COUNT DosCloseSft(WORD sft_idx, BOOL commitonly);
#define DosCommit(hndl) DosCloseSft(get_sft_idx(hndl), TRUE) #define DosCommit(hndl) DosCloseSft(get_sft_idx(hndl), TRUE)
BOOL DosGetFree(UBYTE drive, UCOUNT FAR * spc, UCOUNT FAR * navc, BOOL DosGetFree(UBYTE drive, UWORD * spc, UWORD * navc,
UCOUNT FAR * bps, UCOUNT FAR * nc); UWORD * bps, UWORD * nc);
COUNT DosGetCuDir(UBYTE drive, BYTE FAR * s); COUNT DosGetCuDir(UBYTE drive, BYTE FAR * s);
COUNT DosChangeDir(BYTE FAR * s); COUNT DosChangeDir(BYTE FAR * s);
COUNT DosFindFirst(UCOUNT attr, BYTE FAR * name); COUNT DosFindFirst(UCOUNT attr, BYTE FAR * name);
COUNT DosFindNext(void); 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); COUNT DosSetFtimeSft(WORD sft_idx, date dp, time tp);
#define DosSetFtime(hndl, dp, tp) DosSetFtimeSft(get_sft_idx(hndl), (dp), (tp)) #define DosSetFtime(hndl, dp, tp) DosSetFtimeSft(get_sft_idx(hndl), (dp), (tp))
COUNT DosGetFattr(BYTE FAR * name); COUNT DosGetFattr(BYTE FAR * name);
@ -104,21 +102,20 @@ UBYTE DosSelectDrv(UBYTE drv);
COUNT DosDelete(BYTE FAR * path, int attrib); COUNT DosDelete(BYTE FAR * path, int attrib);
COUNT DosRename(BYTE FAR * path1, BYTE FAR * path2); COUNT DosRename(BYTE FAR * path1, BYTE FAR * path2);
COUNT DosRenameTrue(BYTE * path1, BYTE * path2, int attrib); COUNT DosRenameTrue(BYTE * path1, BYTE * path2, int attrib);
COUNT DosMkdir(BYTE FAR * dir); COUNT DosMkdir(const char FAR * dir);
COUNT DosRmdir(BYTE FAR * dir); COUNT DosRmdir(const char FAR * dir);
struct dhdr FAR *IsDevice(BYTE FAR * FileName); struct dhdr FAR *IsDevice(const char FAR * FileName);
BOOL IsShareInstalled(void); BOOL IsShareInstalled(void);
COUNT DosLockUnlock(COUNT hndl, LONG pos, LONG len, COUNT unlock); COUNT DosLockUnlock(COUNT hndl, LONG pos, LONG len, COUNT unlock);
sft FAR *idx_to_sft(COUNT SftIndex); sft FAR *idx_to_sft(COUNT SftIndex);
COUNT get_sft_idx(UCOUNT hndl); COUNT get_sft_idx(UCOUNT hndl);
COUNT DosTruename(const char FAR * src, char FAR * dest);
/*dosidle.asm */ /*dosidle.asm */
VOID ASMCFUNC DosIdle_int(void); VOID ASMCFUNC DosIdle_int(void);
/* dosnames.c */ /* dosnames.c */
VOID SpacePad(BYTE *, COUNT); int ParseDosName(const char *, char *, BOOL);
COUNT ParseDosName(BYTE *, COUNT *, BYTE *, BYTE *, BYTE *, BOOL);
/*COUNT ParseDosPath(BYTE *, COUNT *, BYTE *, BYTE FAR *); */
/* error.c */ /* error.c */
VOID dump(void); VOID dump(void);
@ -127,7 +124,7 @@ VOID fatal(BYTE * err_msg);
/* fatdir.c */ /* fatdir.c */
VOID dir_init_fnode(f_node_ptr fnp, CLUSTER dirstart); 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); COUNT dir_read(REG f_node_ptr fnp);
BOOL dir_write(REG f_node_ptr fnp); BOOL dir_write(REG f_node_ptr fnp);
VOID dir_close(REG f_node_ptr fnp); VOID dir_close(REG f_node_ptr fnp);
@ -138,13 +135,12 @@ int FileName83Length(BYTE * filename83);
/* fatfs.c */ /* fatfs.c */
ULONG clus2phys(CLUSTER cl_no, struct dpb FAR * dpbp); ULONG clus2phys(CLUSTER cl_no, struct dpb FAR * dpbp);
COUNT dos_open(BYTE * path, COUNT flag); long dos_open(char * path, unsigned flag, unsigned attrib);
BOOL fcmp(BYTE * s1, BYTE * s2, COUNT n); BOOL fcbmatch(const char *fcbname1, const char *fcbname2);
BOOL fcmp_wild(BYTE FAR * s1, BYTE FAR * s2, COUNT n); BOOL fcmp_wild(const char * s1, const char * s2, unsigned n);
VOID touc(BYTE * s, COUNT n); VOID touc(BYTE * s, COUNT n);
COUNT dos_close(COUNT fd); COUNT dos_close(COUNT fd);
COUNT dos_commit(COUNT fd); COUNT dos_commit(COUNT fd);
COUNT dos_creat(BYTE * path, int attrib);
COUNT dos_delete(BYTE * path, int attrib); COUNT dos_delete(BYTE * path, int attrib);
COUNT dos_rmdir(BYTE * path); COUNT dos_rmdir(BYTE * path);
COUNT dos_rename(BYTE * path1, BYTE * path2, int attrib); COUNT dos_rename(BYTE * path1, BYTE * path2, int attrib);
@ -152,8 +148,7 @@ date dos_getdate(void);
time dos_gettime(void); time dos_gettime(void);
COUNT dos_getftime(COUNT fd, date FAR * dp, time FAR * tp); COUNT dos_getftime(COUNT fd, date FAR * dp, time FAR * tp);
COUNT dos_setftime(COUNT fd, date dp, time tp); COUNT dos_setftime(COUNT fd, date dp, time tp);
LONG dos_getcufsize(COUNT fd); ULONG dos_getfsize(COUNT fd);
LONG dos_getfsize(COUNT fd);
BOOL dos_setfsize(COUNT fd, LONG size); BOOL dos_setfsize(COUNT fd, LONG size);
COUNT dos_mkdir(BYTE * dir); COUNT dos_mkdir(BYTE * dir);
BOOL last_link(f_node_ptr fnp); 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); COUNT dos_write(COUNT fd, const VOID FAR * buffer, UCOUNT count);
LONG dos_lseek(COUNT fd, LONG foffset, COUNT origin); LONG dos_lseek(COUNT fd, LONG foffset, COUNT origin);
CLUSTER dos_free(struct dpb FAR * dpbp); CLUSTER dos_free(struct dpb FAR * dpbp);
BOOL dir_exists(char * path);
VOID trim_path(BYTE FAR * s); 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); f_node_ptr get_f_node(void);
VOID release_f_node(f_node_ptr fnp); VOID release_f_node(f_node_ptr fnp);
VOID dos_setdta(BYTE FAR * newdta); VOID dos_setdta(BYTE FAR * newdta);
COUNT dos_getfattr_fd(COUNT fd);
COUNT dos_getfattr(BYTE * name); COUNT dos_getfattr(BYTE * name);
COUNT dos_setfattr(BYTE * name, UWORD attrp); COUNT dos_setfattr(BYTE * name, UWORD attrp);
COUNT media_check(REG struct dpb FAR * dpbp); COUNT media_check(REG struct dpb FAR * dpbp);
@ -192,43 +189,35 @@ int DosCharInput(VOID);
VOID DosDirectConsoleIO(iregs FAR * r); VOID DosDirectConsoleIO(iregs FAR * r);
VOID DosCharOutput(COUNT c); VOID DosCharOutput(COUNT c);
VOID DosDisplayOutput(COUNT c); VOID DosDisplayOutput(COUNT c);
VOID FatGetDrvData(UCOUNT drive, UCOUNT FAR * spc, UCOUNT FAR * bps, BYTE FAR *FatGetDrvData(UBYTE drive, UWORD * spc, UWORD * bps,
UCOUNT FAR * nc, BYTE FAR ** mdp); UWORD * nc);
WORD FcbParseFname(int wTestMode, const BYTE FAR ** lpFileName, fcb FAR * lpFcb); UWORD FcbParseFname(int *wTestMode, const BYTE FAR *lpFileName, fcb FAR * lpFcb);
const BYTE FAR *ParseSkipWh(const BYTE FAR * lpFileName); const BYTE FAR *ParseSkipWh(const BYTE FAR * lpFileName);
BOOL TestCmnSeps(BYTE FAR * lpFileName); BOOL TestCmnSeps(BYTE FAR * lpFileName);
BOOL TestFieldSeps(BYTE FAR * lpFileName); BOOL TestFieldSeps(BYTE FAR * lpFileName);
const BYTE FAR *GetNameField(const BYTE FAR * lpFileName, BYTE FAR * lpDestField, const BYTE FAR *GetNameField(const BYTE FAR * lpFileName, BYTE FAR * lpDestField,
COUNT nFieldSize, BOOL * pbWildCard); COUNT nFieldSize, BOOL * pbWildCard);
typedef BOOL FcbFunc_t (xfcb FAR *, COUNT *, UCOUNT); UBYTE FcbReadWrite(xfcb FAR *, UCOUNT, int);
FcbFunc_t FcbRead, FcbWrite; UBYTE FcbGetFileSize(xfcb FAR * lpXfcb);
BOOL FcbGetFileSize(xfcb FAR * lpXfcb); void FcbSetRandom(xfcb FAR * lpXfcb);
BOOL FcbSetRandom(xfcb FAR * lpXfcb); UBYTE FcbRandomBlockIO(xfcb FAR * lpXfcb, COUNT nRecords, int mode);
BOOL FcbCalcRec(xfcb FAR * lpXfcb); UBYTE FcbRandomIO(xfcb FAR * lpXfcb, int mode);
BOOL FcbRandomBlockRead(xfcb FAR * lpXfcb, COUNT nRecords, UBYTE FcbOpen(xfcb FAR * lpXfcb, unsigned flags);
COUNT * nErrorCode); int FcbNameInit(fcb FAR * lpFcb, BYTE * pszBuffer, COUNT * pCurDrive);
BOOL FcbRandomBlockWrite(xfcb FAR * lpXfcb, COUNT nRecords, UBYTE FcbDelete(xfcb FAR * lpXfcb);
COUNT * nErrorCode); UBYTE FcbRename(xfcb FAR * lpXfcb);
BOOL FcbRandomIO(xfcb FAR * lpXfcb, COUNT * nErrorCode, FcbFunc_t *FcbFunc); UBYTE FcbClose(xfcb FAR * lpXfcb);
BOOL FcbOpenCreate(xfcb FAR * lpXfcb, BOOL Create); void FcbCloseAll(void);
#define FcbOpen(fcb) FcbOpenCreate(fcb, FALSE) UBYTE FcbFindFirstNext(xfcb FAR * lpXfcb, BOOL First);
#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);
/* ioctl.c */ /* ioctl.c */
COUNT DosDevIOctl(iregs FAR * r); COUNT DosDevIOctl(lregs * r);
/* memmgr.c */ /* memmgr.c */
seg far2para(VOID FAR * p); seg far2para(VOID FAR * p);
seg long2para(ULONG size); seg long2para(ULONG size);
VOID FAR *add_far(VOID FAR * fp, ULONG off); 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, COUNT DosMemAlloc(UWORD size, COUNT mode, seg FAR * para,
UWORD FAR * asize); UWORD FAR * asize);
COUNT DosMemLargest(UWORD FAR * size); COUNT DosMemLargest(UWORD FAR * size);
@ -242,12 +231,16 @@ VOID DosUmbLink(BYTE n);
VOID mcb_print(mcb FAR * mcbp); VOID mcb_print(mcb FAR * mcbp);
/* misc.c */ /* misc.c */
VOID ASMCFUNC strcpy(REG BYTE * d, REG const BYTE * s); char * ASMCFUNC strcpy(char * d, const char * s);
VOID ASMCFUNC fmemcpy(REG VOID FAR * d, REG const VOID FAR * s, REG COUNT n); void ASMCFUNC fmemcpyBack(void FAR * d, const void FAR * s, size_t n);
VOID ASMCFUNC fstrcpy(REG BYTE FAR * d, REG const BYTE FAR * s); void ASMCFUNC fmemcpy(void FAR * d, const void FAR * s, size_t n);
void ASMCFUNC memcpy(REG void *d, REG const VOID * s, REG COUNT n); void ASMCFUNC fstrcpy(char FAR * d, const char FAR * s);
void ASMCFUNC fmemset(REG VOID FAR * s, REG int ch, REG COUNT n); void * ASMCFUNC memcpy(void *d, const void * s, size_t n);
void ASMCFUNC memset(REG VOID * s, REG int ch, REG COUNT 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 */ /* lfnapi.c */
COUNT lfn_allocate_inode(VOID); COUNT lfn_allocate_inode(VOID);
@ -279,27 +272,29 @@ COUNT DosGetCountryInformation(UWORD cntry, VOID FAR * buf);
#ifndef DosSetCountry #ifndef DosSetCountry
COUNT DosSetCountry(UWORD cntry); COUNT DosSetCountry(UWORD cntry);
#endif #endif
COUNT DosGetCodepage(UWORD FAR * actCP, UWORD FAR * sysCP); COUNT DosGetCodepage(UWORD * actCP, UWORD * sysCP);
COUNT DosSetCodepage(UWORD actCP, UWORD sysCP); COUNT DosSetCodepage(UWORD actCP, UWORD sysCP);
UWORD ASMCFUNC syscall_MUX14(DIRECT_IREGS); UWORD ASMCFUNC syscall_MUX14(DIRECT_IREGS);
/* prf.c */ /* prf.c */
VOID put_console(COUNT c); VOID put_console(COUNT c);
WORD CDECL printf(CONST BYTE * fmt, ...); int CDECL printf(CONST BYTE * fmt, ...);
WORD CDECL sprintf(BYTE * buff, CONST BYTE * fmt, ...); int CDECL sprintf(BYTE * buff, CONST BYTE * fmt, ...);
VOID hexd(char *title, VOID FAR * p, COUNT numBytes); VOID hexd(char *title, VOID FAR * p, COUNT numBytes);
/* strings.c */ /* strings.c */
COUNT ASMCFUNC strlen(REG BYTE * s); size_t ASMCFUNC strlen(const char * s);
COUNT ASMCFUNC fstrlen(REG BYTE FAR * s); size_t ASMCFUNC fstrlen(const char FAR * s);
VOID ASMCFUNC _fstrcpy(REG BYTE FAR * d, REG BYTE FAR * s); char FAR * ASMCFUNC _fstrcpy(char FAR * d, const char FAR * s);
VOID ASMCFUNC strncpy(REG BYTE * d, REG BYTE * s, COUNT l); char * ASMCFUNC strncpy(char * d, const char * s, size_t l);
COUNT ASMCFUNC strcmp(REG BYTE * d, REG BYTE * s); int ASMCFUNC strcmp(const char * d, const char * s);
COUNT ASMCFUNC fstrcmp(REG BYTE FAR * d, REG BYTE FAR * s); int ASMCFUNC fstrcmp(const char FAR * d, const char FAR * s);
COUNT ASMCFUNC fstrncmp(REG BYTE FAR * d, REG BYTE FAR * s, COUNT l); int ASMCFUNC fstrncmp(const char FAR * d, const char FAR * s, size_t l);
COUNT ASMCFUNC strncmp(REG BYTE * d, REG BYTE * s, COUNT l); int ASMCFUNC strncmp(const char * d, const char * s, size_t l);
void ASMCFUNC fstrncpy(REG BYTE FAR * d, REG BYTE FAR * s, COUNT l); void ASMCFUNC fstrncpy(char FAR * d, const char FAR * s, size_t l);
BYTE * ASMCFUNC strchr(const BYTE * s, BYTE c); 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 */ /* sysclk.c */
COUNT BcdToByte(COUNT x); COUNT BcdToByte(COUNT x);
@ -309,19 +304,17 @@ LONG WordToBcd(BYTE * x, UWORD * mon, UWORD * day, UWORD * yr);
/* syspack.c */ /* syspack.c */
#ifdef NONNATIVE #ifdef NONNATIVE
VOID getdirent(BYTE FAR * vp, struct dirent FAR * dp); VOID getdirent(UBYTE FAR * vp, struct dirent FAR * dp);
VOID putdirent(struct dirent FAR * dp, BYTE FAR * vp); VOID putdirent(struct dirent FAR * dp, UBYTE FAR * vp);
#else #else
#define getdirent(vp, dp) fmemcpy(dp, vp, sizeof(struct dirent)) #define getdirent(vp, dp) fmemcpy(dp, vp, sizeof(struct dirent))
#define putdirent(dp, vp) fmemcpy(vp, dp, sizeof(struct dirent)) #define putdirent(dp, vp) fmemcpy(vp, dp, sizeof(struct dirent))
#endif #endif
/* systime.c */ /* systime.c */
VOID DosGetTime(BYTE FAR * hp, BYTE FAR * mp, BYTE FAR * sp, VOID DosGetTime(UBYTE * hp, UBYTE * mp, UBYTE * sp, UBYTE * hdp);
BYTE FAR * hdp);
COUNT DosSetTime(BYTE h, BYTE m, BYTE s, BYTE hd); COUNT DosSetTime(BYTE h, BYTE m, BYTE s, BYTE hd);
VOID DosGetDate(BYTE FAR * wdp, BYTE FAR * mp, BYTE FAR * mdp, VOID DosGetDate(UBYTE * wdp, UBYTE * mp, UBYTE * mdp, UWORD * yp);
COUNT FAR * yp);
COUNT DosSetDate(UWORD Month, UWORD DayOfMonth, UWORD Year); COUNT DosSetDate(UWORD Month, UWORD DayOfMonth, UWORD Year);
const UWORD *is_leap_year_monthdays(UWORD year); const UWORD *is_leap_year_monthdays(UWORD year);
@ -337,8 +330,8 @@ VOID InitPSP(VOID);
/* newstuff.c */ /* newstuff.c */
int SetJFTSize(UWORD nHandles); int SetJFTSize(UWORD nHandles);
int DosMkTmp(BYTE FAR * pathname, UWORD attr); int DosMkTmp(BYTE FAR * pathname, UWORD attr);
COUNT get_verify_drive(char FAR * src); COUNT get_verify_drive(const char FAR * src);
COUNT truename(char FAR * src, char FAR * dest, COUNT t); COUNT truename(const char FAR * src, char * dest, COUNT t);
/* network.c */ /* network.c */
COUNT ASMCFUNC remote_doredirect(UWORD b, UCOUNT n, UWORD d, VOID FAR * s, 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_getfattr(VOID);
COUNT ASMCFUNC remote_getfree(VOID FAR * s, VOID * d); COUNT ASMCFUNC remote_getfree(VOID FAR * s, VOID * d);
COUNT ASMCFUNC remote_open(sft FAR * s, COUNT mode); 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); LONG ASMCFUNC remote_lseek(sft FAR * s, LONG new_pos);
UCOUNT ASMCFUNC remote_read(sft FAR * s, UCOUNT n, COUNT * err); UCOUNT ASMCFUNC remote_read(sft FAR * s, UCOUNT n, COUNT * err);
UCOUNT ASMCFUNC remote_write(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_printredir(UCOUNT dx, UCOUNT ax);
COUNT ASMCFUNC remote_commit(sft FAR * s); COUNT ASMCFUNC remote_commit(sft FAR * s);
COUNT ASMCFUNC remote_close(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); UWORD get_machine_name(BYTE FAR * netname);
VOID set_machine_name(BYTE FAR * netname, UWORD name_num); 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 */ /* common - call the clock driver */
void ExecuteClockDriverRequest(BYTE command) void ExecuteClockDriverRequest(BYTE command)
{ {
ClkReqHdr.r_length = sizeof(request); BinaryCharIO(clock, sizeof(struct ClockRecord), &ClkRecord, command, &UnusedRetVal);
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);
} }
VOID DosGetTime(BYTE FAR * hp, BYTE FAR * mp, BYTE FAR * sp, VOID DosGetTime(UBYTE * hp, UBYTE * mp, UBYTE * sp, UBYTE * hdp)
BYTE FAR * hdp)
{ {
ExecuteClockDriverRequest(C_INPUT); ExecuteClockDriverRequest(C_INPUT);
@ -113,9 +107,7 @@ COUNT DosSetTime(BYTE h, BYTE m, BYTE s, BYTE hd)
return SUCCESS; return SUCCESS;
} }
VOID DosGetDate(wdp, mp, mdp, yp) VOID DosGetDate(UBYTE *wdp, UBYTE *mp, UBYTE *mdp, UWORD *yp)
BYTE FAR *wdp, FAR * mp, FAR * mdp;
COUNT FAR *yp;
{ {
UWORD c; UWORD c;
const UWORD *pdays; 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 */ /* Now load the executable */
{ {
BYTE FAR *sp; BYTE FAR *sp;
ULONG tmp;
if (mode == OVERLAY) /* memory already allocated */ if (mode == OVERLAY) /* memory already allocated */
sp = MK_FP(mem, 0); 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 */ -- 1999/04/21 ska */
/* rewind to start */ /* rewind to start */
DosSeek(fd, 0, 0, &tmp); DosSeek(fd, 0, 0);
/* read everything, but at most 64K - sizeof(PSP) */ /* read everything, but at most 64K - sizeof(PSP) */
DosRead(fd, 0xff00, sp, &UnusedRetVal); DosRead(fd, 0xff00, sp, &UnusedRetVal);
DosClose(fd); DosClose(fd);
@ -552,7 +551,7 @@ VOID return_user(void)
COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd) COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
{ {
UWORD mem, env, start_seg, asize = 0; UWORD mem, env, start_seg, asize = 0;
ULONG exe_size, tmp; ULONG exe_size;
{ {
ULONG image_size; ULONG image_size;
ULONG image_offset; ULONG image_offset;
@ -646,8 +645,7 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
/* Now load the executable */ /* Now load the executable */
/* offset to start of image */ /* offset to start of image */
DosSeek(fd, image_offset, 0, &tmp); if (DosSeek(fd, image_offset, 0) != image_offset)
if (tmp != image_offset)
{ {
if (mode != OVERLAY) if (mode != OVERLAY)
{ {
@ -696,9 +694,8 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
COUNT i; COUNT i;
UWORD reloc[2]; UWORD reloc[2];
seg FAR *spot; seg FAR *spot;
ULONG tmp;
DosSeek(fd, ExeHeader.exRelocTable, 0, &tmp); DosSeek(fd, ExeHeader.exRelocTable, 0);
for (i = 0; i < ExeHeader.exRelocItems; i++) for (i = 0; i < ExeHeader.exRelocItems; i++)
{ {
if (DosRead 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 file not found - free ram and return error */
if (IsDevice(lp) || /* we don't want to execute C:>NUL */ 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) (fd = (short)DosOpen(lp, O_LEGACY | O_OPEN | O_RDONLY, 0)) < 0)
#else
(fd = (short)DosOpen(lp, 0)) < 0)
#endif
{ {
return DE_FILENOTFND; return DE_FILENOTFND;
} }

View File

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

View File

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