mirror of
https://github.com/FDOS/kernel.git
synced 2025-07-25 14:54:28 +02:00
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:
parent
511bf63d16
commit
dfeb595f8e
@ -14,6 +14,8 @@ James Tabor (jimtabor@infohwy.com)
|
||||
Eric Biederman (ebiederm+eric@ccr.net)
|
||||
Tom Ehlert (tom.ehlert@ginko.de)
|
||||
Victor Vlasenko (victor_vlasenko@hotbox.ru)
|
||||
Jeremy Davis (jeremyd@computer.org)
|
||||
Martin Stromberg (ams@ludd.luth.se)
|
||||
Bart Oldeman (bart@dosemu.org)
|
||||
|
||||
And last, but not least, a big thanx to Pasquale J. Villani
|
||||
|
@ -1,7 +1,7 @@
|
||||
Begin3
|
||||
Title: The FreeDOS Kernel
|
||||
Version: 2.0.25.c
|
||||
Entered-date: 17 Nov 2001
|
||||
Version: 2.0.27
|
||||
Entered-date: xx Aug 2002
|
||||
Description: The FreeDOS Kernel.
|
||||
Keywords: kernel freedos dos msdos
|
||||
Author: (developers)
|
||||
|
@ -9,10 +9,31 @@
|
||||
* disabled fatal() in error.c
|
||||
* Disable the A20 line upon exec (int21/ah=4B). This is necessary for some
|
||||
brain-dead exepacked programs.
|
||||
* removed unnecessary buffer fields
|
||||
* removed unnecessary "BUFFERS" fields
|
||||
* proper check for network/non-existing drive for int25/26.
|
||||
* save more bytes on the stack at various places
|
||||
* made the local registers for inthndlr.c "near" instead of "far".
|
||||
* fix bug in strchr handling for fcbfns.c (FcbParseFname)
|
||||
+ Changes Steffen (but changed a lot by Bart)
|
||||
* new truename (Bart: but without mapPath() style struct)
|
||||
* merge open/create functions into one extended open function
|
||||
* also honor the sharing bits better for "open"
|
||||
* use local 8+3 path names in fatfs.c; merge name+extension
|
||||
into one array
|
||||
* take care of filenames that start with ASCII 5: they should be
|
||||
treated as starting with 0xe5
|
||||
* exploit the fact that the filenames are already "truenames",
|
||||
i.e., fully qualified in fatfs.c. This simplifies parsing a lot.
|
||||
+ Changes Bart
|
||||
* make "if exist c:\dir\nul" working
|
||||
* honor "do not inherit handle on exec" flag for "open".
|
||||
* improve the FCB functions so that they set the critical error code
|
||||
properly
|
||||
* next_cluster returns "1" instead of DE_xxx in case of failure.
|
||||
* create one function to do binary character IO (used for CLOCK$
|
||||
driver and character drivers such as CON)
|
||||
* better handling of ABORT/FAIL
|
||||
* merge all read and write functions
|
||||
* patchobj makefile correction
|
||||
* printf uses va_list etc.
|
||||
* quicker and more robust Watcom build
|
||||
@ -33,7 +54,6 @@
|
||||
merge as much as possible from DosExeLoader and DosComLoader
|
||||
(from Tom:) eliminate some structures in low memory
|
||||
* main.c: slightly cleanup "SHELL=" line parsing.
|
||||
|
||||
2002 May 9 - Build 2026b
|
||||
-------- Bart Oldeman (bart@dosemu.org)
|
||||
+ Changes Tom
|
||||
|
@ -54,7 +54,8 @@ static BYTE *fat_hRcsId =
|
||||
#define FEXT_SIZE 3
|
||||
|
||||
/* FAT deleted flag */
|
||||
#define DELETED 0xe5 /* if first char, delete file */
|
||||
#define DELETED '\x5' /* if first char, delete file */
|
||||
#define EXT_DELETED '\xe5' /* external deleted flag */
|
||||
|
||||
/* FAT cluster to physical conversion macros */
|
||||
#define clus_add(cl_no) ((ULONG) (((ULONG) cl_no - 2L) \
|
||||
@ -81,8 +82,7 @@ static BYTE *fat_hRcsId =
|
||||
|
||||
/* FAT file system directory entry */
|
||||
struct dirent {
|
||||
UBYTE dir_name[FNAME_SIZE]; /* Filename */
|
||||
UBYTE dir_ext[FEXT_SIZE]; /* Filename extension */
|
||||
char dir_name[FNAME_SIZE + FEXT_SIZE]; /* Filename + extension in FCB format */
|
||||
UBYTE dir_attrib; /* File Attribute */
|
||||
UBYTE dir_case; /* File case */
|
||||
UBYTE dir_crtimems; /* Milliseconds */
|
||||
|
@ -106,7 +106,7 @@ typedef struct _sfttbl {
|
||||
#define SFT_MRDWR 0x0002 /* read/write bit */
|
||||
#define SFT_MWRITE 0x0001 /* write bit */
|
||||
#define SFT_MREAD 0x0000 /* ~ write bit */
|
||||
#define SFT_OMASK 0x00f3 /* valid open mask */
|
||||
#define SFT_OMASK 0xfff3 /* valid open mask */
|
||||
|
||||
/* flag bits */
|
||||
|
||||
|
@ -117,13 +117,15 @@ irp_hi equ 26
|
||||
; later
|
||||
;
|
||||
; assumption:
|
||||
; we have never seen MSVC (our only I386 compiler) to use
|
||||
; anything but eax,ecx, edx
|
||||
; we have never seen MSVC to use anything but eax,ecx, edx
|
||||
; so we only protect eax, ebx, ecx, edx to conserve stack space
|
||||
;
|
||||
; to save even more stack space, we save only HIGH part of regs
|
||||
; at some expense of slower execution. it's easier anyway :-)
|
||||
;
|
||||
; WATCOM only uses FS: and GS: (using -zff and -zgf) and never
|
||||
; any high part of the 386 registers
|
||||
;
|
||||
|
||||
|
||||
%IFNDEF I386
|
||||
@ -141,6 +143,9 @@ irp_hi equ 26
|
||||
%macro Protect386Registers 0
|
||||
|
||||
%ifdef WATCOM
|
||||
push fs
|
||||
push gs
|
||||
%else
|
||||
ror eax,16
|
||||
push ax
|
||||
ror eax,16
|
||||
@ -153,9 +158,6 @@ irp_hi equ 26
|
||||
ror edx,16
|
||||
push dx
|
||||
ror edx,16
|
||||
%else
|
||||
push fs
|
||||
push gs
|
||||
%endif
|
||||
|
||||
%endmacro
|
||||
@ -163,6 +165,9 @@ irp_hi equ 26
|
||||
%macro Restore386Registers 0
|
||||
|
||||
%ifdef WATCOM
|
||||
pop gs
|
||||
pop fs
|
||||
%else
|
||||
ror edx,16
|
||||
pop dx
|
||||
ror edx,16
|
||||
@ -175,9 +180,6 @@ irp_hi equ 26
|
||||
ror eax,16
|
||||
pop ax
|
||||
ror eax,16
|
||||
%else
|
||||
pop gs
|
||||
pop fs
|
||||
%endif
|
||||
|
||||
%endmacro
|
||||
|
@ -65,6 +65,40 @@ struct dhdr FAR *finddev(UWORD attr_mask)
|
||||
}
|
||||
#endif
|
||||
|
||||
UCOUNT BinaryCharIO(struct dhdr FAR * dev, UCOUNT n, void FAR * bp, unsigned command, COUNT *err)
|
||||
{
|
||||
*err = SUCCESS;
|
||||
|
||||
FOREVER
|
||||
{
|
||||
CharReqHdr.r_length = sizeof(request);
|
||||
CharReqHdr.r_command = command;
|
||||
CharReqHdr.r_count = n;
|
||||
CharReqHdr.r_trans = bp;
|
||||
CharReqHdr.r_status = 0;
|
||||
execrh(&CharReqHdr, dev);
|
||||
if (CharReqHdr.r_status & S_ERROR)
|
||||
{
|
||||
charloop:
|
||||
switch (char_error(&CharReqHdr, dev))
|
||||
{
|
||||
case ABORT:
|
||||
case FAIL:
|
||||
*err = DE_INVLDACC;
|
||||
return 0;
|
||||
case CONTINUE:
|
||||
break;
|
||||
case RETRY:
|
||||
continue;
|
||||
default:
|
||||
goto charloop;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return CharReqHdr.r_count;
|
||||
}
|
||||
|
||||
VOID _cso(COUNT c)
|
||||
{
|
||||
if (syscon->dh_attr & ATTR_FASTCON)
|
||||
@ -72,7 +106,7 @@ VOID _cso(COUNT c)
|
||||
#if defined(__TURBOC__)
|
||||
_AL = c;
|
||||
__int__(0x29);
|
||||
#else
|
||||
#elif defined(I86)
|
||||
asm
|
||||
{
|
||||
mov al, byte ptr c;
|
||||
@ -81,14 +115,7 @@ VOID _cso(COUNT c)
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
CharReqHdr.r_length = sizeof(request);
|
||||
CharReqHdr.r_command = C_OUTPUT;
|
||||
CharReqHdr.r_count = 1;
|
||||
CharReqHdr.r_trans = (BYTE FAR *) (&c);
|
||||
CharReqHdr.r_status = 0;
|
||||
execrh((request FAR *) & CharReqHdr, syscon);
|
||||
if (CharReqHdr.r_status & S_ERROR)
|
||||
char_error(&CharReqHdr, syscon);
|
||||
BinaryCharIO(syscon, 1, &c, C_OUTPUT, &UnusedRetVal);
|
||||
}
|
||||
|
||||
VOID cso(COUNT c)
|
||||
@ -97,7 +124,7 @@ VOID cso(COUNT c)
|
||||
con_hold();
|
||||
|
||||
if (PrinterEcho)
|
||||
DosWrite(STDPRN, 1, (BYTE FAR *) & c, (COUNT FAR *) & UnusedRetVal);
|
||||
DosWrite(STDPRN, 1, (BYTE FAR *) & c, & UnusedRetVal);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
@ -125,7 +152,7 @@ VOID cso(COUNT c)
|
||||
|
||||
VOID sto(COUNT c)
|
||||
{
|
||||
DosWrite(STDOUT, 1, (BYTE FAR *) & c, (COUNT FAR *) & UnusedRetVal);
|
||||
DosWrite(STDOUT, 1, (BYTE FAR *) & c, & UnusedRetVal);
|
||||
}
|
||||
|
||||
VOID mod_cso(REG UCOUNT c)
|
||||
@ -176,14 +203,7 @@ COUNT con_read(void)
|
||||
{
|
||||
BYTE c;
|
||||
|
||||
CharReqHdr.r_length = sizeof(request);
|
||||
CharReqHdr.r_command = C_INPUT;
|
||||
CharReqHdr.r_count = 1;
|
||||
CharReqHdr.r_trans = (BYTE FAR *) & c;
|
||||
CharReqHdr.r_status = 0;
|
||||
execrh((request FAR *) & CharReqHdr, syscon);
|
||||
if (CharReqHdr.r_status & S_ERROR)
|
||||
char_error(&CharReqHdr, syscon);
|
||||
BinaryCharIO(syscon, 1, &c, C_INPUT, &UnusedRetVal);
|
||||
if (c == CTL_C)
|
||||
handle_break();
|
||||
return c;
|
||||
@ -216,9 +236,8 @@ UCOUNT _sti(BOOL check_break)
|
||||
Do_DosIdle_loop();
|
||||
if (check_break)
|
||||
con_hold();
|
||||
while (GenericRead
|
||||
(STDIN, 1, (BYTE FAR *) & c, (COUNT FAR *) & UnusedRetVal,
|
||||
TRUE) != 1) ;
|
||||
while (BinaryRead(STDIN, &c, & UnusedRetVal) != 1)
|
||||
;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
1197
kernel/dosfns.c
1197
kernel/dosfns.c
File diff suppressed because it is too large
Load Diff
@ -41,9 +41,12 @@ const char _DirWildNameChars[] = "*?./\\\"[]:|<>+=;,";
|
||||
|
||||
#define PathSep(c) ((c)=='/'||(c)=='\\')
|
||||
#define DriveChar(c) (((c)>='A'&&(c)<='Z')||((c)>='a'&&(c)<='z'))
|
||||
#define DirChar(c) (!strchr(_DirWildNameChars+5, (c)))
|
||||
#define WildChar(c) (!strchr(_DirWildNameChars+2, (c)))
|
||||
#define NameChar(c) (!strchr(_DirWildNameChars, (c)))
|
||||
#define DirChar(c) (((unsigned char)(c)) >= ' ' && \
|
||||
!strchr(_DirWildNameChars+5, (c)))
|
||||
#define WildChar(c) (((unsigned char)(c)) >= ' ' && \
|
||||
!strchr(_DirWildNameChars+2, (c)))
|
||||
#define NameChar(c) (((unsigned char)(c)) >= ' ' && \
|
||||
!strchr(_DirWildNameChars, (c)))
|
||||
|
||||
VOID XlateLcase(BYTE * szFname, COUNT nChars);
|
||||
VOID DosTrimPath(BYTE * lpszPathNamep);
|
||||
@ -61,14 +64,6 @@ VOID XlateLcase(BYTE * szFname, COUNT nChars)
|
||||
}
|
||||
#endif
|
||||
|
||||
VOID SpacePad(BYTE * szString, COUNT nChars)
|
||||
{
|
||||
REG COUNT i;
|
||||
|
||||
for (i = strlen(szString); i < nChars; i++)
|
||||
szString[i] = ' ';
|
||||
}
|
||||
|
||||
/*
|
||||
MSD durring an FindFirst search string looks like this;
|
||||
(*), & (.) == Current directory *.*
|
||||
@ -76,90 +71,73 @@ VOID SpacePad(BYTE * szString, COUNT nChars)
|
||||
(..) == Back one directory *.*
|
||||
|
||||
This always has a "truename" as input, so we may do some shortcuts
|
||||
|
||||
returns number of characters in the directory component (up to the
|
||||
last backslash, including d:) or negative if error
|
||||
*/
|
||||
COUNT ParseDosName(BYTE * lpszFileName,
|
||||
COUNT * pnDrive,
|
||||
BYTE * pszDir,
|
||||
BYTE * pszFile, BYTE * pszExt, BOOL bAllowWildcards)
|
||||
int ParseDosName(const char *filename, char *fcbname, BOOL bAllowWildcards)
|
||||
{
|
||||
COUNT nDirCnt, nFileCnt, nExtCnt;
|
||||
BYTE *lpszLclDir, *lpszLclFile, *lpszLclExt;
|
||||
int nDirCnt, nFileCnt, nExtCnt;
|
||||
const char *lpszLclDir, *lpszLclFile, *lpszLclExt;
|
||||
|
||||
/* Initialize the users data fields */
|
||||
if (pszDir)
|
||||
*pszDir = '\0';
|
||||
if (pszFile)
|
||||
*pszFile = '\0';
|
||||
if (pszExt)
|
||||
*pszExt = '\0';
|
||||
lpszLclFile = lpszLclExt = lpszLclDir = 0;
|
||||
nDirCnt = nFileCnt = nExtCnt = 0;
|
||||
|
||||
/* found a drive, fetch it and bump pointer past drive */
|
||||
/* NB: this code assumes ASCII */
|
||||
if (pnDrive)
|
||||
*pnDrive = *lpszFileName - 'A';
|
||||
lpszFileName += 2;
|
||||
if (!pszDir && !pszFile && !pszExt)
|
||||
return SUCCESS;
|
||||
|
||||
/* Now see how long a directory component we have. */
|
||||
lpszLclDir = lpszLclFile = lpszFileName;
|
||||
while (DirChar(*lpszFileName))
|
||||
lpszLclDir = lpszLclFile = filename;
|
||||
filename += 2;
|
||||
|
||||
while (DirChar(*filename))
|
||||
{
|
||||
if (*lpszFileName == '\\')
|
||||
lpszLclFile = lpszFileName + 1;
|
||||
++lpszFileName;
|
||||
if (*filename == '\\')
|
||||
lpszLclFile = filename + 1;
|
||||
++filename;
|
||||
}
|
||||
nDirCnt = FP_OFF(lpszLclFile) - FP_OFF(lpszLclDir);
|
||||
nDirCnt = lpszLclFile - lpszLclDir;
|
||||
/* Fix lengths to maximums allowed by MS-DOS. */
|
||||
if (nDirCnt > PARSE_MAX - 1)
|
||||
nDirCnt = PARSE_MAX - 1;
|
||||
|
||||
/* Parse out the file name portion. */
|
||||
lpszFileName = lpszLclFile;
|
||||
while (bAllowWildcards ? WildChar(*lpszFileName) :
|
||||
NameChar(*lpszFileName))
|
||||
filename = lpszLclFile;
|
||||
while (bAllowWildcards ? WildChar(*filename) :
|
||||
NameChar(*filename))
|
||||
{
|
||||
++nFileCnt;
|
||||
++lpszFileName;
|
||||
++filename;
|
||||
}
|
||||
|
||||
if (nFileCnt == 0)
|
||||
{
|
||||
/* Lixing Yuan Patch */
|
||||
if (bAllowWildcards) /* for find first */
|
||||
{
|
||||
if (*lpszFileName != '\0')
|
||||
if (*filename != '\0')
|
||||
return DE_FILENOTFND;
|
||||
if (nDirCnt == 1) /* for d:\ */
|
||||
return DE_NFILES;
|
||||
if (pszDir)
|
||||
{
|
||||
memcpy(pszDir, lpszLclDir, nDirCnt);
|
||||
pszDir[nDirCnt] = '\0';
|
||||
}
|
||||
if (pszFile)
|
||||
memcpy(pszFile, "????????", FNAME_SIZE + 1);
|
||||
if (pszExt)
|
||||
memcpy(pszExt, "???", FEXT_SIZE + 1);
|
||||
return SUCCESS;
|
||||
memset(fcbname, '?', FNAME_SIZE + FEXT_SIZE);
|
||||
return nDirCnt;
|
||||
}
|
||||
else
|
||||
return DE_FILENOTFND;
|
||||
|
||||
}
|
||||
|
||||
/* Now we have pointers set to the directory portion and the */
|
||||
/* file portion. Now determine the existance of an extension. */
|
||||
lpszLclExt = lpszFileName;
|
||||
if ('.' == *lpszFileName)
|
||||
lpszLclExt = filename;
|
||||
if ('.' == *filename)
|
||||
{
|
||||
lpszLclExt = ++lpszFileName;
|
||||
while (*lpszFileName)
|
||||
lpszLclExt = ++filename;
|
||||
while (*filename)
|
||||
{
|
||||
if (bAllowWildcards ? WildChar(*lpszFileName) :
|
||||
NameChar(*lpszFileName))
|
||||
if (bAllowWildcards ? WildChar(*filename) :
|
||||
NameChar(*filename))
|
||||
{
|
||||
++nExtCnt;
|
||||
++lpszFileName;
|
||||
++filename;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -167,225 +145,20 @@ COUNT ParseDosName(BYTE * lpszFileName,
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (*lpszFileName)
|
||||
else if (*filename)
|
||||
return DE_FILENOTFND;
|
||||
|
||||
/* Finally copy whatever the user wants extracted to the user's */
|
||||
/* buffers. */
|
||||
if (pszDir)
|
||||
{
|
||||
memcpy(pszDir, lpszLclDir, nDirCnt);
|
||||
pszDir[nDirCnt] = '\0';
|
||||
}
|
||||
if (pszFile)
|
||||
{
|
||||
memcpy(pszFile, lpszLclFile, nFileCnt);
|
||||
pszFile[nFileCnt] = '\0';
|
||||
}
|
||||
if (pszExt)
|
||||
{
|
||||
memcpy(pszExt, lpszLclExt, nExtCnt);
|
||||
pszExt[nExtCnt] = '\0';
|
||||
}
|
||||
memset(fcbname, ' ', FNAME_SIZE + FEXT_SIZE);
|
||||
memcpy(fcbname, lpszLclFile, nFileCnt);
|
||||
memcpy(&fcbname[FNAME_SIZE], lpszLclExt, nExtCnt);
|
||||
|
||||
/* Clean up before leaving */
|
||||
|
||||
return SUCCESS;
|
||||
return nDirCnt;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* not necessary anymore because of truename */
|
||||
COUNT ParseDosPath(BYTE * lpszFileName,
|
||||
COUNT * pnDrive, BYTE * pszDir, BYTE * pszCurPath)
|
||||
{
|
||||
COUNT nDirCnt, nPathCnt;
|
||||
BYTE *lpszLclDir, *pszBase = pszDir;
|
||||
|
||||
/* Initialize the users data fields */
|
||||
*pszDir = '\0';
|
||||
lpszLclDir = 0;
|
||||
nDirCnt = nPathCnt = 0;
|
||||
|
||||
/* Start by cheking for a drive specifier ... */
|
||||
if (DriveChar(*lpszFileName) && ':' == lpszFileName[1])
|
||||
{
|
||||
/* found a drive, fetch it and bump pointer past drive */
|
||||
/* NB: this code assumes ASCII */
|
||||
if (pnDrive)
|
||||
{
|
||||
*pnDrive = *lpszFileName - 'A';
|
||||
if (*pnDrive > 26)
|
||||
*pnDrive -= ('a' - 'A');
|
||||
}
|
||||
lpszFileName += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pnDrive)
|
||||
{
|
||||
*pnDrive = -1;
|
||||
}
|
||||
}
|
||||
|
||||
lpszLclDir = lpszFileName;
|
||||
if (!PathSep(*lpszLclDir))
|
||||
{
|
||||
fstrncpy(pszDir, pszCurPath, PARSE_MAX - 1);
|
||||
/*TE*/ nPathCnt = fstrlen(pszCurPath);
|
||||
if (!PathSep(pszDir[nPathCnt - 1]) && nPathCnt < PARSE_MAX - 1)
|
||||
/*TE*/ pszDir[nPathCnt++] = '\\';
|
||||
if (nPathCnt > PARSE_MAX)
|
||||
nPathCnt = PARSE_MAX;
|
||||
pszDir += nPathCnt;
|
||||
}
|
||||
|
||||
/* Now see how long a directory component we have. */
|
||||
while (NameChar(*lpszFileName)
|
||||
|| PathSep(*lpszFileName) || '.' == *lpszFileName)
|
||||
{
|
||||
++nDirCnt;
|
||||
++lpszFileName;
|
||||
}
|
||||
|
||||
/* Fix lengths to maximums allowed by MS-DOS. */
|
||||
if ((nDirCnt + nPathCnt) > PARSE_MAX - 1)
|
||||
/*TE*/ nDirCnt = PARSE_MAX - 1 - nPathCnt;
|
||||
|
||||
/* Finally copy whatever the user wants extracted to the user's */
|
||||
/* buffers. */
|
||||
if (pszDir)
|
||||
{
|
||||
memcpy(pszDir, lpszLclDir, nDirCnt);
|
||||
pszDir[nDirCnt] = '\0';
|
||||
}
|
||||
|
||||
/* Clean up before leaving */
|
||||
DosTrimPath(pszBase);
|
||||
|
||||
/* Before returning to the user, eliminate any useless */
|
||||
/* trailing "\\." since the path prior to this is sufficient. */
|
||||
nPathCnt = strlen(pszBase);
|
||||
if (2 == nPathCnt) /* Special case, root */
|
||||
{
|
||||
if (!strcmp(pszBase, "\\."))
|
||||
pszBase[1] = '\0';
|
||||
}
|
||||
else if (2 < nPathCnt)
|
||||
{
|
||||
if (!strcmp(&pszBase[nPathCnt - 2], "\\."))
|
||||
pszBase[nPathCnt - 2] = '\0';
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
VOID DosTrimPath(BYTE * lpszPathNamep)
|
||||
{
|
||||
BYTE *lpszLast, *lpszNext, *lpszRoot = NULL;
|
||||
COUNT nChars, flDotDot;
|
||||
|
||||
/* First, convert all '/' to '\'. Look for root as we scan */
|
||||
if (*lpszPathNamep == '\\')
|
||||
lpszRoot = lpszPathNamep;
|
||||
for (lpszNext = lpszPathNamep; *lpszNext; ++lpszNext)
|
||||
{
|
||||
if (*lpszNext == '/')
|
||||
*lpszNext = '\\';
|
||||
if (!lpszRoot && *lpszNext == ':' && *(lpszNext + 1) == '\\')
|
||||
lpszRoot = lpszNext + 1;
|
||||
}
|
||||
|
||||
/* NAMEMAX + 2, must include C: TE */
|
||||
for (lpszLast = lpszNext = lpszPathNamep, nChars = 0;
|
||||
*lpszNext != '\0' && nChars < NAMEMAX + 2;)
|
||||
{
|
||||
/* Initialize flag for loop. */
|
||||
flDotDot = FALSE;
|
||||
|
||||
/* If we are at a path seperator, check for extra path */
|
||||
/* seperator, '.' and '..' to reduce. */
|
||||
if (*lpszNext == '\\')
|
||||
{
|
||||
/* If it's '\', just move everything down one. */
|
||||
if (*(lpszNext + 1) == '\\')
|
||||
fstrncpy(lpszNext, lpszNext + 1, NAMEMAX);
|
||||
/* also check for '.' and '..' and move down */
|
||||
/* as appropriate. */
|
||||
else if (*(lpszNext + 1) == '.')
|
||||
{
|
||||
if (*(lpszNext + 2) == '.' && !(*(lpszNext + 3)))
|
||||
{
|
||||
/* At the end, just truncate */
|
||||
/* and exit. */
|
||||
if (lpszLast == lpszRoot)
|
||||
*(lpszLast + 1) = '\0';
|
||||
else
|
||||
*lpszLast = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
if (*(lpszNext + 2) == '.' && *(lpszNext + 3) == '\\')
|
||||
{
|
||||
fstrncpy(lpszLast, lpszNext + 3, NAMEMAX);
|
||||
/* bump back to the last */
|
||||
/* seperator. */
|
||||
lpszNext = lpszLast;
|
||||
/* set lpszLast to the last one */
|
||||
if (lpszLast <= lpszPathNamep)
|
||||
continue;
|
||||
do
|
||||
{
|
||||
--lpszLast;
|
||||
}
|
||||
while (lpszLast != lpszPathNamep && *lpszLast != '\\');
|
||||
flDotDot = TRUE;
|
||||
}
|
||||
/* Note: we skip strange stuff that */
|
||||
/* starts with '.' */
|
||||
else if (*(lpszNext + 2) == '\\')
|
||||
{
|
||||
fstrncpy(lpszNext, lpszNext + 2, NAMEMAX);
|
||||
flDotDot = TRUE;
|
||||
}
|
||||
/* If we're at the end of a string, */
|
||||
/* just exit. */
|
||||
else if (*(lpszNext + 2) == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
/*
|
||||
Added this "else" because otherwise we might not pass
|
||||
any of the foregoing tests, as in the case where the
|
||||
incoming string refers to a suffix only, like ".bat"
|
||||
|
||||
-SRM
|
||||
*/
|
||||
else
|
||||
{
|
||||
lpszLast = lpszNext++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No '.' or '\' so mark it and bump */
|
||||
/* past */
|
||||
lpszLast = lpszNext++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Done. Now set last to next to mark this */
|
||||
/* instance of path seperator. */
|
||||
if (!flDotDot)
|
||||
lpszLast = lpszNext;
|
||||
}
|
||||
else
|
||||
/* For all other cases, bump lpszNext for the */
|
||||
/* next check */
|
||||
++lpszNext;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Log: dosnames.c,v - for newer log entries do "cvs log dosnames.c"
|
||||
*
|
||||
|
@ -376,7 +376,11 @@ int21_exit_nodec:
|
||||
pop si
|
||||
|
||||
%IFDEF I386
|
||||
sub bp,8
|
||||
%ifdef WATCOM
|
||||
sub bp, 4 ; for fs and gs only
|
||||
%else
|
||||
sub bp, 8 ; high parts of eax, ebx, ecx, edx
|
||||
%endif
|
||||
%endif
|
||||
|
||||
cli
|
||||
|
172
kernel/fatdir.c
172
kernel/fatdir.c
@ -68,14 +68,10 @@ VOID dir_init_fnode(f_node_ptr fnp, CLUSTER dirstart)
|
||||
fnp->f_cluster = fnp->f_dirstart = dirstart;
|
||||
}
|
||||
|
||||
f_node_ptr dir_open(BYTE * dirname)
|
||||
f_node_ptr dir_open(register const char *dirname)
|
||||
{
|
||||
f_node_ptr fnp;
|
||||
COUNT drive;
|
||||
BYTE *p;
|
||||
WORD i;
|
||||
struct cds FAR *cdsp;
|
||||
BYTE *pszPath = dirname + 2;
|
||||
int i;
|
||||
|
||||
/* Allocate an fnode if possible - error return (0) if not. */
|
||||
if ((fnp = get_f_node()) == (f_node_ptr) 0)
|
||||
@ -86,57 +82,23 @@ f_node_ptr dir_open(BYTE * dirname)
|
||||
/* Force the fnode into read-write mode */
|
||||
fnp->f_mode = RDWR;
|
||||
|
||||
/* determine what drive we are using... */
|
||||
if (ParseDosName
|
||||
(dirname, &drive, (BYTE *) 0, (BYTE *) 0, (BYTE *) 0,
|
||||
FALSE) != SUCCESS)
|
||||
/* determine what drive and dpb we are using... */
|
||||
fnp->f_dpb = CDSp[dirname[0]-'A'].cdsDpb;
|
||||
if (fnp->f_dpb == 0)
|
||||
{
|
||||
release_f_node(fnp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* If the drive was specified, drive is non-negative and */
|
||||
/* corresponds to the one passed in, i.e., 0 = A, 1 = B, etc. */
|
||||
/* We use that and skip the "D:" part of the string. */
|
||||
/* Otherwise, just use the default drive */
|
||||
if (drive >= 0)
|
||||
{
|
||||
dirname += 2; /* Assume FAT style drive */
|
||||
}
|
||||
else
|
||||
{
|
||||
drive = default_drive;
|
||||
}
|
||||
if (drive >= lastdrive)
|
||||
{
|
||||
release_f_node(fnp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cdsp = &CDSp[drive];
|
||||
|
||||
/* Generate full path name */
|
||||
/* not necessary anymore, since truename did that already
|
||||
i = cdsp->cdsJoinOffset;
|
||||
ParseDosPath(dirname, (COUNT *) 0, pszPath, (BYTE FAR *) & cdsp->cdsCurrentPath[i]); */
|
||||
|
||||
/* for testing only for now */
|
||||
#if 0
|
||||
if ((cdsp->cdsFlags & CDSNETWDRV))
|
||||
if ((CDSp[dirname[0]-'A'].cdsFlags & CDSNETWDRV))
|
||||
{
|
||||
printf("FailSafe %x \n", Int21AX);
|
||||
return fnp;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cdsp->cdsDpb == 0)
|
||||
{
|
||||
release_f_node(fnp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fnp->f_dpb = cdsp->cdsDpb;
|
||||
|
||||
/* Perform all directory common handling after all special */
|
||||
/* handling has been performed. */
|
||||
|
||||
@ -150,15 +112,21 @@ f_node_ptr dir_open(BYTE * dirname)
|
||||
/* */
|
||||
/* Start from the root directory (dirstart = 0) */
|
||||
|
||||
/* The CDS's cdsStartCls may be used to shorten the search
|
||||
beginning at the CWD, see mapPath() and CDS.H in order
|
||||
to enable this behaviour there.
|
||||
-- 2001/09/04 ska*/
|
||||
|
||||
dir_init_fnode(fnp, 0);
|
||||
|
||||
for (p = pszPath; *p != '\0';)
|
||||
dirname += 2; /* Assume FAT style drive */
|
||||
while(*dirname != '\0')
|
||||
{
|
||||
/* skip all path seperators */
|
||||
while (*p == '\\')
|
||||
++p;
|
||||
while (*dirname == '\\')
|
||||
++dirname;
|
||||
/* don't continue if we're at the end */
|
||||
if (*p == '\0')
|
||||
if (*dirname == '\0')
|
||||
break;
|
||||
|
||||
/* Convert the name into an absolute name for */
|
||||
@ -169,20 +137,22 @@ f_node_ptr dir_open(BYTE * dirname)
|
||||
|
||||
for (i = 0; i < FNAME_SIZE; i++)
|
||||
{
|
||||
if (*p != '\0' && *p != '.' && *p != '/' && *p != '\\')
|
||||
TempBuffer[i] = *p++;
|
||||
if (*dirname != '\0' && *dirname != '.' && *dirname != '/' &&
|
||||
*dirname != '\\')
|
||||
TempBuffer[i] = *dirname++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
/* and the extension (don't forget to */
|
||||
/* add trailing spaces)... */
|
||||
if (*p == '.')
|
||||
++p;
|
||||
if (*dirname == '.')
|
||||
++dirname;
|
||||
for (i = 0; i < FEXT_SIZE; i++)
|
||||
{
|
||||
if (*p != '\0' && *p != '.' && *p != '/' && *p != '\\')
|
||||
TempBuffer[i + FNAME_SIZE] = *p++;
|
||||
if (*dirname != '\0' && *dirname != '.' && *dirname != '/' &&
|
||||
*dirname != '\\')
|
||||
TempBuffer[i + FNAME_SIZE] = *dirname++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
@ -191,27 +161,18 @@ f_node_ptr dir_open(BYTE * dirname)
|
||||
/* find the entry... */
|
||||
i = FALSE;
|
||||
|
||||
DosUpFMem((BYTE FAR *) TempBuffer, FNAME_SIZE + FEXT_SIZE);
|
||||
|
||||
while (dir_read(fnp) == 1)
|
||||
{
|
||||
if (fnp->f_dir.dir_name[0] != '\0'
|
||||
&& fnp->f_dir.dir_name[0] != DELETED
|
||||
&& !(fnp->f_dir.dir_attrib & D_VOLID))
|
||||
if (!(fnp->f_dir.dir_attrib & D_VOLID) &&
|
||||
fcbmatch(TempBuffer, fnp->f_dir.dir_name))
|
||||
{
|
||||
if (fcmp
|
||||
(TempBuffer, (BYTE *) fnp->f_dir.dir_name,
|
||||
FNAME_SIZE + FEXT_SIZE))
|
||||
{
|
||||
i = TRUE;
|
||||
break;
|
||||
}
|
||||
i = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!i || !(fnp->f_dir.dir_attrib & D_DIR))
|
||||
{
|
||||
|
||||
release_f_node(fnp);
|
||||
return (f_node_ptr) 0;
|
||||
}
|
||||
@ -225,6 +186,15 @@ f_node_ptr dir_open(BYTE * dirname)
|
||||
return fnp;
|
||||
}
|
||||
|
||||
/* swap internal and external delete flags */
|
||||
STATIC void swap_deleted(char *name)
|
||||
{
|
||||
if (name[0] == DELETED)
|
||||
name[0] = EXT_DELETED;
|
||||
else if (name[0] == EXT_DELETED)
|
||||
name[0] = DELETED;
|
||||
}
|
||||
|
||||
/* Description.
|
||||
* Read next consequitive directory entry, pointed by fnp.
|
||||
* If some error occures the other critical
|
||||
@ -306,6 +276,8 @@ COUNT dir_read(REG f_node_ptr fnp)
|
||||
b_buffer[((UWORD) new_diroff) % fnp->f_dpb->dpb_secsize],
|
||||
(struct dirent FAR *)&fnp->f_dir);
|
||||
|
||||
swap_deleted(fnp->f_dir.dir_name);
|
||||
|
||||
/* Update the fnode's directory info */
|
||||
fnp->f_flags.f_dmod = FALSE;
|
||||
fnp->f_flags.f_dnew = FALSE;
|
||||
@ -399,10 +371,15 @@ BOOL dir_write(REG f_node_ptr fnp)
|
||||
|
||||
if (fnp->f_flags.f_dnew && fnp->f_dir.dir_attrib != D_LFN)
|
||||
fmemset(&fnp->f_dir.dir_case, 0, 8);
|
||||
|
||||
swap_deleted(fnp->f_dir.dir_name);
|
||||
|
||||
putdirent((struct dirent FAR *)&fnp->f_dir,
|
||||
(VOID FAR *) & bp->b_buffer[(UWORD) fnp->f_diroff %
|
||||
fnp->f_dpb->dpb_secsize]);
|
||||
|
||||
swap_deleted(fnp->f_dir.dir_name);
|
||||
|
||||
bp->b_flag &= ~(BFR_DATA | BFR_FAT);
|
||||
bp->b_flag |= BFR_DIR | BFR_DIRTY | BFR_VALID;
|
||||
}
|
||||
@ -422,6 +399,7 @@ VOID dir_close(REG f_node_ptr fnp)
|
||||
|
||||
#endif
|
||||
/* Clear buffers after release */
|
||||
/* hazard: no error checking! */
|
||||
flush_buffers(fnp->f_dpb->dpb_unit);
|
||||
|
||||
/* and release this instance of the fnode */
|
||||
@ -434,10 +412,6 @@ COUNT dos_findfirst(UCOUNT attr, BYTE * name)
|
||||
REG f_node_ptr fnp;
|
||||
REG dmatch *dmp = (dmatch *) TempBuffer;
|
||||
REG COUNT i;
|
||||
COUNT nDrive;
|
||||
BYTE *p;
|
||||
|
||||
BYTE local_name[FNAME_SIZE + 1], local_ext[FEXT_SIZE + 1];
|
||||
|
||||
/* printf("ff %Fs\n", name);*/
|
||||
|
||||
@ -449,63 +423,37 @@ COUNT dos_findfirst(UCOUNT attr, BYTE * name)
|
||||
/* current directory, do a seek and read, then close the fnode. */
|
||||
|
||||
/* Parse out the drive, file name and file extension. */
|
||||
i = ParseDosName(name, &nDrive, &szDirName[2], local_name, local_ext,
|
||||
TRUE);
|
||||
if (i != SUCCESS)
|
||||
i = ParseDosName(name, SearchDir.dir_name, TRUE);
|
||||
if (i < SUCCESS)
|
||||
return i;
|
||||
/*
|
||||
printf("\nff %s", Tname);
|
||||
printf("ff %s", local_name);
|
||||
printf("ff %s\n", local_ext);
|
||||
printf("ff %s", fcbname);
|
||||
*/
|
||||
|
||||
/* Build the match pattern out of the passed string */
|
||||
/* copy the part of the pattern which belongs to the filename and is fixed */
|
||||
for (p = local_name, i = 0; i < FNAME_SIZE && *p; ++p, ++i)
|
||||
SearchDir.dir_name[i] = *p;
|
||||
|
||||
for (; i < FNAME_SIZE; ++i)
|
||||
SearchDir.dir_name[i] = ' ';
|
||||
|
||||
/* and the extension (don't forget to add trailing spaces)... */
|
||||
for (p = local_ext, i = 0; i < FEXT_SIZE && *p; ++p, ++i)
|
||||
SearchDir.dir_ext[i] = *p;
|
||||
|
||||
for (; i < FEXT_SIZE; ++i)
|
||||
SearchDir.dir_ext[i] = ' ';
|
||||
|
||||
/* Convert everything to uppercase. */
|
||||
DosUpFMem(SearchDir.dir_name, FNAME_SIZE + FEXT_SIZE);
|
||||
|
||||
/* Now search through the directory to find the entry... */
|
||||
|
||||
/* Complete building the directory from the passed in */
|
||||
/* name */
|
||||
szDirName[0] = 'A' + nDrive;
|
||||
szDirName[1] = ':';
|
||||
|
||||
/* Special handling - the volume id is only in the root */
|
||||
/* directory and only searched for once. So we need to open */
|
||||
/* the root and return only the first entry that contains the */
|
||||
/* volume id bit set. */
|
||||
if (attr == D_VOLID)
|
||||
{
|
||||
szDirName[2] = '\\';
|
||||
szDirName[3] = '\0';
|
||||
}
|
||||
i = 3;
|
||||
/* Now open this directory so that we can read the */
|
||||
/* fnode entry and do a match on it. */
|
||||
|
||||
/* printf("dir_open %s\n", szDirName);*/
|
||||
if ((fnp = dir_open(szDirName)) == NULL)
|
||||
return DE_PATHNOTFND;
|
||||
{
|
||||
char tmp = name[i];
|
||||
name[i] = '\0';
|
||||
if ((fnp = dir_open(name)) == NULL)
|
||||
return DE_PATHNOTFND;
|
||||
name[i] = tmp;
|
||||
}
|
||||
|
||||
/* Now initialize the dirmatch structure. */
|
||||
|
||||
nDrive = get_verify_drive(name);
|
||||
if (nDrive < 0)
|
||||
return nDrive;
|
||||
dmp->dm_drive = nDrive;
|
||||
dmp->dm_drive = name[0] - 'A';
|
||||
dmp->dm_attr_srch = attr;
|
||||
|
||||
/* Copy the raw pattern from our data segment to the DTA. */
|
||||
@ -605,9 +553,7 @@ COUNT dos_findnext(void)
|
||||
if (fnp->f_dir.dir_name[0] != '\0' && fnp->f_dir.dir_name[0] != DELETED
|
||||
&& (fnp->f_dir.dir_attrib & D_VOLID) != D_VOLID)
|
||||
{
|
||||
if (fcmp_wild
|
||||
((BYTE FAR *) dmp->dm_name_pat, (BYTE FAR *) fnp->f_dir.dir_name,
|
||||
FNAME_SIZE + FEXT_SIZE))
|
||||
if (fcmp_wild(dmp->dm_name_pat, fnp->f_dir.dir_name, FNAME_SIZE + FEXT_SIZE))
|
||||
{
|
||||
/*
|
||||
MSD Command.com uses FCB FN 11 & 12 with attrib set to 0x16.
|
||||
@ -694,6 +640,7 @@ void ConvertName83ToNameSZ(BYTE FAR * destSZ, BYTE FAR * srcFCBName)
|
||||
*destSZ = '\0';
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
returns the asciiSZ length of a 8.3 filename
|
||||
*/
|
||||
@ -706,6 +653,7 @@ int FileName83Length(BYTE * filename83)
|
||||
|
||||
return strlen(buff);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Log: fatdir.c,v - for newer log entries do a "cvs log fatdir.c"
|
||||
|
511
kernel/fatfs.c
511
kernel/fatfs.c
@ -39,8 +39,8 @@ BYTE *RcsId = "$Id$";
|
||||
/* */
|
||||
f_node_ptr xlt_fd(COUNT);
|
||||
COUNT xlt_fnp(f_node_ptr);
|
||||
f_node_ptr split_path(BYTE *, BYTE *, BYTE *);
|
||||
BOOL find_fname(f_node_ptr, BYTE *, BYTE *, int);
|
||||
STATIC f_node_ptr split_path(char *, char *);
|
||||
BOOL find_fname(f_node_ptr, char *, int);
|
||||
/* /// Added - Ron Cemer */
|
||||
STATIC void merge_file_changes(f_node_ptr fnp, int collect);
|
||||
/* /// Added - Ron Cemer */
|
||||
@ -77,63 +77,158 @@ ULONG clus2phys(CLUSTER cl_no, struct dpb FAR * dpbp)
|
||||
|
||||
/* Open a file given the path. Flags is 0 for read, 1 for write and 2 */
|
||||
/* for update. */
|
||||
/* Returns an integer file desriptor or a negative error code */
|
||||
/* Returns an long where the high word is a status code and the low */
|
||||
/* word is an integer file descriptor or a negative error code */
|
||||
/* see DosOpenSft(), dosfns.c for an explanation of the flags bits */
|
||||
/* directory opens are allowed here; these are not allowed by DosOpenSft*/
|
||||
|
||||
COUNT dos_open(BYTE * path, COUNT flag)
|
||||
long dos_open(char *path, unsigned flags, unsigned attrib)
|
||||
{
|
||||
REG f_node_ptr fnp;
|
||||
char fcbname[FNAME_SIZE + FEXT_SIZE];
|
||||
int status = S_OPENED;
|
||||
|
||||
/* First test the flag to see if the user has passed a valid */
|
||||
/* First test the flags to see if the user has passed a valid */
|
||||
/* file mode... */
|
||||
if (flag < 0 || flag > 2)
|
||||
if ((flags & 3) > 2)
|
||||
return DE_INVLDACC;
|
||||
|
||||
/* first split the passed dir into comopnents (i.e. - path to */
|
||||
/* new directory and name of new directory. */
|
||||
if ((fnp = split_path(path, szFileName, szFileExt)) == NULL)
|
||||
{
|
||||
if ((fnp = split_path(path, fcbname)) == NULL)
|
||||
return DE_PATHNOTFND;
|
||||
}
|
||||
|
||||
/* Look for the file. If we can't find it, just return a not */
|
||||
/* found error. */
|
||||
if (!find_fname(fnp, szFileName, szFileExt, D_ALL))
|
||||
/* Check that we don't have a duplicate name, so if we */
|
||||
/* find one, truncate it (O_CREAT). */
|
||||
if (find_fname(fnp, fcbname, D_ALL | attrib))
|
||||
{
|
||||
if (flags & O_TRUNC)
|
||||
{
|
||||
/* The only permissable attribute is archive, */
|
||||
/* check for any other bit set. If it is, give */
|
||||
/* an access error. */
|
||||
if ((fnp->f_dir.dir_attrib & (D_RDONLY | D_DIR | D_VOLID))
|
||||
|| (fnp->f_dir.dir_attrib & ~D_ARCHIVE & ~attrib))
|
||||
{
|
||||
dir_close(fnp);
|
||||
return DE_ACCESS;
|
||||
}
|
||||
|
||||
/* Release the existing files FAT and set the */
|
||||
/* length to zero, effectively truncating the */
|
||||
/* file to zero. */
|
||||
wipe_out(fnp);
|
||||
status = S_REPLACED;
|
||||
}
|
||||
else if (!(flags & O_OPEN))
|
||||
{
|
||||
dir_close(fnp);
|
||||
return DE_FILEEXISTS;
|
||||
}
|
||||
}
|
||||
else if (flags & O_CREAT)
|
||||
{
|
||||
BOOL is_free;
|
||||
|
||||
/* Reset the directory by a close followed by */
|
||||
/* an open */
|
||||
fnp->f_flags.f_dmod = FALSE;
|
||||
dir_close(fnp);
|
||||
fnp = split_path(path, fcbname);
|
||||
|
||||
/* Get a free f_node pointer so that we can use */
|
||||
/* it in building the new file. */
|
||||
/* Note that if we're in the root and we don't */
|
||||
/* find an empty slot, we need to abort. */
|
||||
if (((is_free = find_free(fnp)) == 0) && (fnp->f_flags.f_droot))
|
||||
{
|
||||
fnp->f_flags.f_dmod = FALSE;
|
||||
dir_close(fnp);
|
||||
return DE_TOOMANY;
|
||||
}
|
||||
|
||||
/* Otherwise just expand the directory */
|
||||
else if (!is_free && !(fnp->f_flags.f_droot))
|
||||
{
|
||||
COUNT ret;
|
||||
|
||||
if ((ret = extend_dir(fnp)) != SUCCESS)
|
||||
/* fnp already closed in extend_dir */
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* put the fnode's name into the directory. */
|
||||
memcpy(fnp->f_dir.dir_name, fcbname, FNAME_SIZE + FEXT_SIZE);
|
||||
status = S_CREATED;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* open: If we can't find the file, just return a not */
|
||||
/* found error. */
|
||||
dir_close(fnp);
|
||||
return DE_FILENOTFND;
|
||||
}
|
||||
|
||||
/* Set the fnode to the desired mode */
|
||||
/* Updating the directory entry first. */
|
||||
fnp->f_mode = flags & 3;
|
||||
|
||||
if (status != S_OPENED)
|
||||
{
|
||||
fnp->f_dir.dir_size = 0l;
|
||||
setdstart(fnp->f_dir, FREE);
|
||||
fnp->f_dir.dir_attrib = attrib;
|
||||
fnp->f_dir.dir_time = dos_gettime();
|
||||
fnp->f_dir.dir_date = dos_getdate();
|
||||
|
||||
fnp->f_flags.f_dmod = TRUE;
|
||||
fnp->f_flags.f_ddate = FALSE;
|
||||
fnp->f_flags.f_dnew = FALSE;
|
||||
fnp->f_flags.f_ddir = TRUE;
|
||||
if (!dir_write(fnp))
|
||||
{
|
||||
release_f_node(fnp);
|
||||
return DE_ACCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the fnode to the desired mode */
|
||||
fnp->f_mode = flag;
|
||||
/* force r/o open for FCBs if the file is read-only */
|
||||
if ((flags & O_FCB) && (fnp->f_dir.dir_attrib & D_RDONLY))
|
||||
fnp->f_mode = O_RDONLY;
|
||||
|
||||
/* Initialize the rest of the fnode. */
|
||||
/* Check permissions. -- JPP */
|
||||
if ((fnp->f_dir.dir_attrib & D_RDONLY) && (fnp->f_mode != O_RDONLY))
|
||||
{
|
||||
dir_close(fnp);
|
||||
return DE_ACCESS;
|
||||
}
|
||||
|
||||
/* Now change to file */
|
||||
fnp->f_offset = 0l;
|
||||
fnp->f_highwater = fnp->f_dir.dir_size;
|
||||
|
||||
|
||||
fnp->f_back = LONG_LAST_CLUSTER;
|
||||
|
||||
fnp->f_flags.f_dmod = FALSE;
|
||||
if (status != S_OPENED)
|
||||
{
|
||||
fnp->f_cluster = FREE;
|
||||
setdstart(fnp->f_dir, FREE);
|
||||
fnp->f_cluster_offset = 0l; /*JPP */
|
||||
}
|
||||
|
||||
fnp->f_flags.f_dmod = (status != S_OPENED);
|
||||
fnp->f_flags.f_ddate = FALSE;
|
||||
fnp->f_flags.f_dnew = FALSE;
|
||||
fnp->f_flags.f_ddir = FALSE;
|
||||
|
||||
merge_file_changes(fnp, TRUE); /* /// Added - Ron Cemer */
|
||||
|
||||
|
||||
merge_file_changes(fnp, status == S_OPENED); /* /// Added - Ron Cemer */
|
||||
/* /// Moved from above. - Ron Cemer */
|
||||
fnp->f_cluster = getdstart(fnp->f_dir);
|
||||
fnp->f_cluster_offset = 0l; /*JPP */
|
||||
|
||||
return xlt_fnp(fnp);
|
||||
return xlt_fnp(fnp) | ((long)status << 16);
|
||||
}
|
||||
|
||||
BOOL fcmp(BYTE * s1, BYTE * s2, COUNT n)
|
||||
{
|
||||
while (n--)
|
||||
if (*s1++ != *s2++)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL fcmp_wild(BYTE FAR * s1, BYTE FAR * s2, COUNT n)
|
||||
BOOL fcmp_wild(const char * s1, const char * s2, unsigned n)
|
||||
{
|
||||
while (n--)
|
||||
{
|
||||
@ -203,31 +298,15 @@ COUNT dos_commit(COUNT fd)
|
||||
/* */
|
||||
/* split a path into it's component directory and file name */
|
||||
/* */
|
||||
f_node_ptr split_path(BYTE * path, BYTE * fname, BYTE * fext)
|
||||
f_node_ptr split_path(char * path, char * fcbname)
|
||||
{
|
||||
REG f_node_ptr fnp;
|
||||
COUNT nDrive;
|
||||
struct cds FAR *cdsp;
|
||||
|
||||
/* Start off by parsing out the components. */
|
||||
if (ParseDosName(path, &nDrive, &szDirName[2], fname, fext, FALSE)
|
||||
!= SUCCESS)
|
||||
/* Start off by parsing out the components. */
|
||||
int dirlength = ParseDosName(path, fcbname, FALSE);
|
||||
|
||||
if (dirlength < SUCCESS)
|
||||
return (f_node_ptr) 0;
|
||||
if (nDrive < 0)
|
||||
nDrive = default_drive;
|
||||
|
||||
szDirName[0] = 'A' + nDrive;
|
||||
szDirName[1] = ':';
|
||||
|
||||
/* Add trailing spaces to the file name and extension */
|
||||
SpacePad(fname, FNAME_SIZE);
|
||||
SpacePad(fext, FEXT_SIZE);
|
||||
|
||||
if (nDrive >= lastdrive)
|
||||
{
|
||||
return (f_node_ptr) 0;
|
||||
}
|
||||
cdsp = &CDSp[nDrive];
|
||||
|
||||
/* 11/29/99 jt
|
||||
* Networking and Cdroms. You can put in here a return.
|
||||
@ -241,7 +320,7 @@ f_node_ptr split_path(BYTE * path, BYTE * fname, BYTE * fext)
|
||||
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
if (cdsp->cdsFlags & CDSNETWDRV)
|
||||
if (CDSp[path[0]-'A'].cdsFlags & CDSNETWDRV)
|
||||
{
|
||||
printf("split path called for redirected file: `%s.%s'\n",
|
||||
fname, fext);
|
||||
@ -250,7 +329,12 @@ f_node_ptr split_path(BYTE * path, BYTE * fname, BYTE * fext)
|
||||
#endif
|
||||
|
||||
/* Translate the path into a useful pointer */
|
||||
fnp = dir_open(szDirName);
|
||||
{
|
||||
char tmp = path[dirlength];
|
||||
path[dirlength] = '\0';
|
||||
fnp = dir_open(path);
|
||||
path[dirlength] = tmp;
|
||||
}
|
||||
|
||||
/* If the fd was invalid because it was out of range or the */
|
||||
/* requested file was not open, tell the caller and exit... */
|
||||
@ -261,21 +345,32 @@ f_node_ptr split_path(BYTE * path, BYTE * fname, BYTE * fext)
|
||||
return (f_node_ptr) 0;
|
||||
}
|
||||
|
||||
/* Convert the name into an absolute name for comparison... */
|
||||
DosUpFString((BYTE FAR *) szDirName);
|
||||
DosUpFMem((BYTE FAR *) fname, FNAME_SIZE);
|
||||
DosUpFMem((BYTE FAR *) fext, FEXT_SIZE);
|
||||
|
||||
return fnp;
|
||||
}
|
||||
|
||||
STATIC BOOL find_fname(f_node_ptr fnp, BYTE * fname, BYTE * fext, int attr)
|
||||
/* checks whether directory part of path exists */
|
||||
BOOL dir_exists(char * path)
|
||||
{
|
||||
REG f_node_ptr fnp;
|
||||
char fcbname[FNAME_SIZE + FEXT_SIZE];
|
||||
|
||||
if ((fnp = split_path(path, fcbname)) == NULL)
|
||||
return FALSE;
|
||||
|
||||
dir_close(fnp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL fcbmatch(const char *fcbname1, const char *fcbname2)
|
||||
{
|
||||
return memcmp(fcbname1, fcbname2, FNAME_SIZE + FEXT_SIZE) == 0;
|
||||
}
|
||||
|
||||
STATIC BOOL find_fname(f_node_ptr fnp, char *fcbname, int attr)
|
||||
{
|
||||
while (dir_read(fnp) == 1)
|
||||
{
|
||||
if (fnp->f_dir.dir_name[0] != DELETED
|
||||
&& fcmp(fname, (BYTE *) fnp->f_dir.dir_name, FNAME_SIZE)
|
||||
&& fcmp(fext, (BYTE *) fnp->f_dir.dir_ext, FEXT_SIZE)
|
||||
if (fcbmatch(fnp->f_dir.dir_name, fcbname)
|
||||
&& (fnp->f_dir.dir_attrib & ~(D_RDONLY | D_ARCHIVE | attr)) == 0)
|
||||
{
|
||||
return TRUE;
|
||||
@ -375,12 +470,7 @@ STATIC int is_same_file(f_node_ptr fnp1, f_node_ptr fnp2)
|
||||
return
|
||||
(fnp1->f_dpb->dpb_unit == fnp2->f_dpb->dpb_unit)
|
||||
&& (fnp1->f_dpb->dpb_subunit == fnp2->f_dpb->dpb_subunit)
|
||||
&& (fcmp
|
||||
((BYTE *) fnp1->f_dir.dir_name,
|
||||
(BYTE *) fnp2->f_dir.dir_name, FNAME_SIZE))
|
||||
&& (fcmp
|
||||
((BYTE *) fnp1->f_dir.dir_ext,
|
||||
(BYTE *) fnp2->f_dir.dir_ext, FEXT_SIZE))
|
||||
&& (fcbmatch(fnp1->f_dir.dir_name, fnp2->f_dir.dir_name))
|
||||
&& ((fnp1->f_dir.dir_attrib & D_VOLID) == 0)
|
||||
&& ((fnp2->f_dir.dir_attrib & D_VOLID) == 0)
|
||||
&& (fnp1->f_diroff == fnp2->f_diroff)
|
||||
@ -401,108 +491,6 @@ STATIC void copy_file_changes(f_node_ptr src, f_node_ptr dst)
|
||||
dst->f_dir.dir_time = src->f_dir.dir_time;
|
||||
}
|
||||
|
||||
COUNT dos_creat(BYTE * path, int attrib)
|
||||
{
|
||||
REG f_node_ptr fnp;
|
||||
|
||||
/* first split the passed dir into components (i.e. - */
|
||||
/* path to new directory and name of new directory */
|
||||
if ((fnp = split_path(path, szFileName, szFileExt)) == NULL)
|
||||
{
|
||||
return DE_PATHNOTFND;
|
||||
}
|
||||
|
||||
/* Check that we don't have a duplicate name, so if we */
|
||||
/* find one, truncate it. */
|
||||
if (find_fname(fnp, szFileName, szFileExt, D_ALL | attrib))
|
||||
{
|
||||
/* The only permissable attribute is archive, */
|
||||
/* check for any other bit set. If it is, give */
|
||||
/* an access error. */
|
||||
if ((fnp->f_dir.dir_attrib & (D_RDONLY | D_DIR | D_VOLID))
|
||||
|| (fnp->f_dir.dir_attrib & ~D_ARCHIVE & ~attrib))
|
||||
{
|
||||
dir_close(fnp);
|
||||
return DE_ACCESS;
|
||||
}
|
||||
|
||||
/* Release the existing files FAT and set the */
|
||||
/* length to zero, effectively truncating the */
|
||||
/* file to zero. */
|
||||
wipe_out(fnp);
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOL is_free;
|
||||
|
||||
/* Reset the directory by a close followed by */
|
||||
/* an open */
|
||||
fnp->f_flags.f_dmod = FALSE;
|
||||
dir_close(fnp);
|
||||
fnp = split_path(path, szFileName, szFileExt);
|
||||
|
||||
/* Get a free f_node pointer so that we can use */
|
||||
/* it in building the new file. */
|
||||
/* Note that if we're in the root and we don't */
|
||||
/* find an empty slot, we need to abort. */
|
||||
if (((is_free = find_free(fnp)) == 0) && (fnp->f_flags.f_droot))
|
||||
{
|
||||
fnp->f_flags.f_dmod = FALSE;
|
||||
dir_close(fnp);
|
||||
return DE_TOOMANY;
|
||||
}
|
||||
|
||||
/* Otherwise just expand the directory */
|
||||
else if (!is_free && !(fnp->f_flags.f_droot))
|
||||
{
|
||||
COUNT ret;
|
||||
|
||||
if ((ret = extend_dir(fnp)) != SUCCESS)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* put the fnode's name into the directory. */
|
||||
memcpy(fnp->f_dir.dir_name, szFileName, FNAME_SIZE);
|
||||
memcpy(fnp->f_dir.dir_ext, szFileExt, FEXT_SIZE);
|
||||
}
|
||||
/* Set the fnode to the desired mode */
|
||||
/* Updating the directory entry first. */
|
||||
fnp->f_mode = RDWR;
|
||||
|
||||
fnp->f_dir.dir_size = 0l;
|
||||
setdstart(fnp->f_dir, FREE);
|
||||
fnp->f_dir.dir_attrib = attrib | D_ARCHIVE;
|
||||
fnp->f_dir.dir_time = dos_gettime();
|
||||
fnp->f_dir.dir_date = dos_getdate();
|
||||
|
||||
fnp->f_flags.f_dmod = TRUE;
|
||||
fnp->f_flags.f_ddate = FALSE;
|
||||
fnp->f_flags.f_dnew = FALSE;
|
||||
fnp->f_flags.f_ddir = TRUE;
|
||||
if (!dir_write(fnp))
|
||||
{
|
||||
release_f_node(fnp);
|
||||
return DE_ACCESS;
|
||||
}
|
||||
|
||||
/* Now change to file */
|
||||
fnp->f_offset = 0l;
|
||||
fnp->f_highwater = 0l;
|
||||
|
||||
fnp->f_back = LONG_LAST_CLUSTER;
|
||||
fnp->f_cluster = FREE;
|
||||
setdstart(fnp->f_dir, FREE);
|
||||
fnp->f_cluster_offset = 0l; /*JPP */
|
||||
fnp->f_flags.f_dmod = TRUE;
|
||||
fnp->f_flags.f_ddate = FALSE;
|
||||
fnp->f_flags.f_dnew = FALSE;
|
||||
fnp->f_flags.f_ddir = FALSE;
|
||||
|
||||
merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */
|
||||
|
||||
return xlt_fnp(fnp);
|
||||
}
|
||||
|
||||
STATIC COUNT delete_dir_entry(f_node_ptr fnp)
|
||||
{
|
||||
COUNT rc;
|
||||
@ -529,17 +517,18 @@ STATIC COUNT delete_dir_entry(f_node_ptr fnp)
|
||||
COUNT dos_delete(BYTE * path, int attrib)
|
||||
{
|
||||
REG f_node_ptr fnp;
|
||||
char fcbname[FNAME_SIZE + FEXT_SIZE];
|
||||
|
||||
/* first split the passed dir into components (i.e. - */
|
||||
/* path to new directory and name of new directory */
|
||||
if ((fnp = split_path(path, szFileName, szFileExt)) == NULL)
|
||||
if ((fnp = split_path(path, fcbname)) == NULL)
|
||||
{
|
||||
return DE_PATHNOTFND;
|
||||
}
|
||||
|
||||
/* Check that we don't have a duplicate name, so if we */
|
||||
/* find one, it's an error. */
|
||||
if (find_fname(fnp, szFileName, szFileExt, attrib))
|
||||
if (find_fname(fnp, fcbname, attrib))
|
||||
{
|
||||
/* Do not delete directories or r/o files */
|
||||
/* lfn entries and volume labels are only found */
|
||||
@ -566,10 +555,11 @@ COUNT dos_rmdir(BYTE * path)
|
||||
REG f_node_ptr fnp;
|
||||
REG f_node_ptr fnp1;
|
||||
BOOL found;
|
||||
char fcbname[FNAME_SIZE + FEXT_SIZE];
|
||||
|
||||
/* first split the passed dir into comopnents (i.e. - */
|
||||
/* path to new directory and name of new directory */
|
||||
if ((fnp = split_path(path, szFileName, szFileExt)) == NULL)
|
||||
if ((fnp = split_path(path, fcbname)) == NULL)
|
||||
{
|
||||
return DE_PATHNOTFND;
|
||||
}
|
||||
@ -583,7 +573,7 @@ COUNT dos_rmdir(BYTE * path)
|
||||
|
||||
/* Check that we don't have a duplicate name, so if we */
|
||||
/* find one, it's an error. */
|
||||
if (find_fname(fnp, szFileName, szFileExt, D_ALL))
|
||||
if (find_fname(fnp, fcbname, D_ALL))
|
||||
{
|
||||
/* The only permissable attribute is directory, */
|
||||
/* check for any other bit set. If it is, give */
|
||||
@ -658,17 +648,18 @@ COUNT dos_rename(BYTE * path1, BYTE * path2, int attrib)
|
||||
REG f_node_ptr fnp2;
|
||||
BOOL is_free;
|
||||
COUNT ret;
|
||||
char fcbname[FNAME_SIZE + FEXT_SIZE];
|
||||
|
||||
/* first split the passed target into compnents (i.e. - path to */
|
||||
/* new file name and name of new file name */
|
||||
if ((fnp2 = split_path(path2, szFileName, szFileExt)) == NULL)
|
||||
if ((fnp2 = split_path(path2, fcbname)) == NULL)
|
||||
{
|
||||
return DE_PATHNOTFND;
|
||||
}
|
||||
|
||||
/* Check that we don't have a duplicate name, so if we find */
|
||||
/* one, it's an error. */
|
||||
if (find_fname(fnp2, szFileName, szFileExt, attrib))
|
||||
if (find_fname(fnp2, fcbname, attrib))
|
||||
{
|
||||
dir_close(fnp2);
|
||||
return DE_ACCESS;
|
||||
@ -676,13 +667,13 @@ COUNT dos_rename(BYTE * path1, BYTE * path2, int attrib)
|
||||
|
||||
/* next split the passed source into compnents (i.e. - path to */
|
||||
/* old file name and name of old file name */
|
||||
if ((fnp1 = split_path(path1, szFileName, szFileExt)) == NULL)
|
||||
if ((fnp1 = split_path(path1, fcbname)) == NULL)
|
||||
{
|
||||
dir_close(fnp2);
|
||||
return DE_PATHNOTFND;
|
||||
}
|
||||
|
||||
if (!find_fname(fnp1, szFileName, szFileExt, attrib))
|
||||
if (!find_fname(fnp1, fcbname, attrib))
|
||||
{
|
||||
/* No such file, return the error */
|
||||
dir_close(fnp1);
|
||||
@ -693,7 +684,7 @@ COUNT dos_rename(BYTE * path1, BYTE * path2, int attrib)
|
||||
/* Reset the directory by a close followed by an open */
|
||||
fnp2->f_flags.f_dmod = FALSE;
|
||||
dir_close(fnp2);
|
||||
fnp2 = split_path(path2, szFileName, szFileExt);
|
||||
fnp2 = split_path(path2, fcbname);
|
||||
|
||||
/* Now find a free slot to put the file into. */
|
||||
/* If it's the root and we don't have room, return an error. */
|
||||
@ -719,8 +710,7 @@ COUNT dos_rename(BYTE * path1, BYTE * path2, int attrib)
|
||||
return ret;
|
||||
|
||||
/* put the fnode's name into the directory. */
|
||||
memcpy(fnp2->f_dir.dir_name, szFileName, FNAME_SIZE);
|
||||
memcpy(fnp2->f_dir.dir_ext, szFileExt, FEXT_SIZE);
|
||||
memcpy(fnp2->f_dir.dir_name, fcbname, FNAME_SIZE + FEXT_SIZE);
|
||||
|
||||
/* Set the fnode to the desired mode */
|
||||
fnp2->f_dir.dir_size = fnp1->f_dir.dir_size;
|
||||
@ -766,7 +756,7 @@ STATIC VOID wipe_out_clusters(struct dpb FAR * dpbp, CLUSTER st)
|
||||
next = next_cluster(dpbp, st);
|
||||
|
||||
/* just exit if a damaged file system exists */
|
||||
if (next == FREE)
|
||||
if (next == FREE || next == 1)
|
||||
return;
|
||||
|
||||
/* zap the FAT pointed to */
|
||||
@ -820,15 +810,13 @@ STATIC BOOL find_free(f_node_ptr fnp)
|
||||
/* */
|
||||
date dos_getdate()
|
||||
{
|
||||
BYTE WeekDay, Month, MonthDay;
|
||||
COUNT Year;
|
||||
UBYTE WeekDay, Month, MonthDay;
|
||||
UWORD Year;
|
||||
date Date;
|
||||
|
||||
/* First - get the system date set by either the user */
|
||||
/* on start-up or the CMOS clock */
|
||||
DosGetDate((BYTE FAR *) & WeekDay,
|
||||
(BYTE FAR *) & Month,
|
||||
(BYTE FAR *) & MonthDay, (COUNT FAR *) & Year);
|
||||
DosGetDate(&WeekDay, &Month, &MonthDay, &Year);
|
||||
Date = DT_ENCODE(Month, MonthDay, Year - EPOCH_YEAR);
|
||||
return Date;
|
||||
}
|
||||
@ -838,13 +826,11 @@ date dos_getdate()
|
||||
/* */
|
||||
time dos_gettime()
|
||||
{
|
||||
BYTE Hour, Minute, Second, Hundredth;
|
||||
UBYTE Hour, Minute, Second, Hundredth;
|
||||
|
||||
/* First - get the system time set by either the user */
|
||||
/* on start-up or the CMOS clock */
|
||||
DosGetTime((BYTE FAR *) & Hour,
|
||||
(BYTE FAR *) & Minute,
|
||||
(BYTE FAR *) & Second, (BYTE FAR *) & Hundredth);
|
||||
DosGetTime(&Hour, &Minute, &Second, &Hundredth);
|
||||
return TM_ENCODE(Hour, Minute, Second / 2);
|
||||
}
|
||||
|
||||
@ -901,7 +887,7 @@ COUNT dos_setftime(COUNT fd, date dp, time tp)
|
||||
/* */
|
||||
/* dos_getfsize for the file time */
|
||||
/* */
|
||||
LONG dos_getcufsize(COUNT fd)
|
||||
ULONG dos_getfsize(COUNT fd)
|
||||
{
|
||||
f_node_ptr fnp;
|
||||
|
||||
@ -913,33 +899,12 @@ LONG dos_getcufsize(COUNT fd)
|
||||
/* requested file was not open, tell the caller and exit */
|
||||
/* note: an invalid fd is indicated by a 0 return */
|
||||
if (fnp == (f_node_ptr) 0 || fnp->f_count <= 0)
|
||||
return -1l;
|
||||
return (ULONG)-1l;
|
||||
|
||||
/* Return the file size */
|
||||
return fnp->f_highwater;
|
||||
}
|
||||
|
||||
/* */
|
||||
/* dos_getfsize for the file time */
|
||||
/* */
|
||||
LONG dos_getfsize(COUNT fd)
|
||||
{
|
||||
f_node_ptr fnp;
|
||||
|
||||
/* Translate the fd into an fnode pointer, since all internal */
|
||||
/* operations are achieved through fnodes. */
|
||||
fnp = xlt_fd(fd);
|
||||
|
||||
/* If the fd was invalid because it was out of range or the */
|
||||
/* requested file was not open, tell the caller and exit */
|
||||
/* note: an invalid fd is indicated by a 0 return */
|
||||
if (fnp == (f_node_ptr) 0 || fnp->f_count <= 0)
|
||||
return -1l;
|
||||
|
||||
/* Return the file size */
|
||||
return fnp->f_dir.dir_size;
|
||||
}
|
||||
|
||||
/* */
|
||||
/* dos_setfsize for the file time */
|
||||
/* */
|
||||
@ -1050,10 +1015,11 @@ COUNT dos_mkdir(BYTE * dir)
|
||||
struct dpb FAR *dpbp;
|
||||
CLUSTER free_fat, parent;
|
||||
COUNT ret;
|
||||
|
||||
char fcbname[FNAME_SIZE + FEXT_SIZE];
|
||||
|
||||
/* first split the passed dir into comopnents (i.e. - */
|
||||
/* path to new directory and name of new directory */
|
||||
if ((fnp = split_path(dir, szFileName, szFileExt)) == NULL)
|
||||
if ((fnp = split_path(dir, fcbname)) == NULL)
|
||||
{
|
||||
return DE_PATHNOTFND;
|
||||
}
|
||||
@ -1074,7 +1040,7 @@ COUNT dos_mkdir(BYTE * dir)
|
||||
|
||||
/* Check that we don't have a duplicate name, so if we */
|
||||
/* find one, it's an error. */
|
||||
if (find_fname(fnp, szFileName, szFileExt, D_ALL))
|
||||
if (find_fname(fnp, fcbname, D_ALL))
|
||||
{
|
||||
dir_close(fnp);
|
||||
return DE_ACCESS;
|
||||
@ -1085,7 +1051,7 @@ COUNT dos_mkdir(BYTE * dir)
|
||||
fnp->f_flags.f_dmod = FALSE;
|
||||
parent = fnp->f_dirstart;
|
||||
dir_close(fnp);
|
||||
fnp = split_path(dir, szFileName, szFileExt);
|
||||
fnp = split_path(dir, fcbname);
|
||||
|
||||
/* Get a free f_node pointer so that we can use */
|
||||
/* it in building the new file. */
|
||||
@ -1121,8 +1087,7 @@ COUNT dos_mkdir(BYTE * dir)
|
||||
}
|
||||
|
||||
/* put the fnode's name into the directory. */
|
||||
memcpy(fnp->f_dir.dir_name, szFileName, FNAME_SIZE);
|
||||
memcpy(fnp->f_dir.dir_ext, szFileExt, FEXT_SIZE);
|
||||
memcpy(fnp->f_dir.dir_name, fcbname, FNAME_SIZE + FEXT_SIZE);
|
||||
|
||||
/* Set the fnode to the desired mode */
|
||||
fnp->f_mode = WRONLY;
|
||||
@ -1160,8 +1125,8 @@ COUNT dos_mkdir(BYTE * dir)
|
||||
}
|
||||
|
||||
/* Create the "." entry */
|
||||
memcpy(DirEntBuffer.dir_name, ". ", FNAME_SIZE);
|
||||
memcpy(DirEntBuffer.dir_ext, " ", FEXT_SIZE);
|
||||
DirEntBuffer.dir_name[0] = '.';
|
||||
memset(DirEntBuffer.dir_name + 1, ' ', FNAME_SIZE + FEXT_SIZE - 1);
|
||||
DirEntBuffer.dir_attrib = D_DIR;
|
||||
DirEntBuffer.dir_time = dos_gettime();
|
||||
DirEntBuffer.dir_date = dos_getdate();
|
||||
@ -1169,10 +1134,10 @@ COUNT dos_mkdir(BYTE * dir)
|
||||
DirEntBuffer.dir_size = 0l;
|
||||
|
||||
/* And put it out */
|
||||
putdirent((struct dirent FAR *)&DirEntBuffer, (BYTE FAR *) bp->b_buffer);
|
||||
putdirent(&DirEntBuffer, bp->b_buffer);
|
||||
|
||||
/* create the ".." entry */
|
||||
memcpy(DirEntBuffer.dir_name, ".. ", FNAME_SIZE);
|
||||
DirEntBuffer.dir_name[1] = '.';
|
||||
#ifdef WITHFAT32
|
||||
if (ISFAT32(dpbp) && parent == dpbp->dpb_xrootclst)
|
||||
{
|
||||
@ -1182,8 +1147,7 @@ COUNT dos_mkdir(BYTE * dir)
|
||||
setdstart(DirEntBuffer, parent);
|
||||
|
||||
/* and put it out */
|
||||
putdirent((struct dirent FAR *)&DirEntBuffer,
|
||||
(BYTE FAR *) & bp->b_buffer[DIRENT_SIZE]);
|
||||
putdirent(&DirEntBuffer, &bp->b_buffer[DIRENT_SIZE]);
|
||||
|
||||
/* fill the rest of the block with zeros */
|
||||
fmemset(&bp->b_buffer[2 * DIRENT_SIZE], 0, BUFFERSIZE - 2 * DIRENT_SIZE);
|
||||
@ -1212,6 +1176,7 @@ COUNT dos_mkdir(BYTE * dir)
|
||||
}
|
||||
|
||||
/* flush the drive buffers so that all info is written */
|
||||
/* hazard: no error checking! */
|
||||
flush_buffers((COUNT) (dpbp->dpb_unit));
|
||||
|
||||
/* Close the directory so that the entry is updated */
|
||||
@ -1292,6 +1257,7 @@ STATIC COUNT extend_dir(f_node_ptr fnp)
|
||||
}
|
||||
|
||||
/* flush the drive buffers so that all info is written */
|
||||
/* hazard: no error checking! */
|
||||
flush_buffers((COUNT) (fnp->f_dpb->dpb_unit));
|
||||
|
||||
return SUCCESS;
|
||||
@ -1416,6 +1382,8 @@ COUNT map_cluster(REG f_node_ptr fnp, COUNT mode)
|
||||
fnp->f_cluster = next_cluster(fnp->f_dpb, fnp->f_cluster);
|
||||
fnp->f_cluster_offset += clssize;
|
||||
idx -= clssize;
|
||||
if (fnp->f_cluster == 1)
|
||||
return DE_SEEK;
|
||||
}
|
||||
|
||||
#ifdef DISPLAY_GETBLOCK
|
||||
@ -1578,8 +1546,8 @@ UCOUNT rwblock(COUNT fd, VOID FAR * buffer, UCOUNT count, int mode)
|
||||
REG struct buffer FAR *bp;
|
||||
UCOUNT xfr_cnt = 0;
|
||||
UCOUNT ret_cnt = 0;
|
||||
UWORD secsize;
|
||||
UCOUNT to_xfer = count;
|
||||
unsigned secsize;
|
||||
unsigned to_xfer = count;
|
||||
ULONG currentblock;
|
||||
|
||||
#if 0 /*DSK_DEBUG*/
|
||||
@ -1932,7 +1900,7 @@ COUNT dos_cd(struct cds FAR * cdsp, BYTE * PathName)
|
||||
|
||||
f_node_ptr get_f_node(void)
|
||||
{
|
||||
REG i;
|
||||
REG int i;
|
||||
|
||||
for (i = 0; i < f_nodes_cnt; i++)
|
||||
{
|
||||
@ -1959,66 +1927,54 @@ VOID dos_setdta(BYTE FAR * newdta)
|
||||
dta = newdta;
|
||||
}
|
||||
|
||||
COUNT dos_getfattr(BYTE * name)
|
||||
COUNT dos_getfattr_fd(COUNT fd)
|
||||
{
|
||||
f_node_ptr fnp;
|
||||
COUNT fd, result;
|
||||
|
||||
/* Translate the fd into an fnode pointer, since all internal */
|
||||
/* operations are achieved through fnodes. */
|
||||
if ((fd = dos_open(name, O_RDONLY)) < SUCCESS)
|
||||
return DE_FILENOTFND;
|
||||
f_node_ptr fnp = xlt_fd(fd);
|
||||
|
||||
/* note: an invalid fd is indicated by a 0 return */
|
||||
if ((fnp = xlt_fd(fd)) == (f_node_ptr) 0)
|
||||
if (fnp == (f_node_ptr) 0)
|
||||
return DE_TOOMANY;
|
||||
|
||||
/* If the fd was invalid because it was out of range or the */
|
||||
/* requested file was not open, tell the caller and exit */
|
||||
if (fnp->f_count <= 0)
|
||||
{
|
||||
dos_close(fd);
|
||||
return DE_FILENOTFND;
|
||||
}
|
||||
|
||||
/* Get the attribute from the fnode and return */
|
||||
result = fnp->f_dir.dir_attrib;
|
||||
return fnp->f_dir.dir_attrib;
|
||||
}
|
||||
|
||||
COUNT dos_getfattr(BYTE * name)
|
||||
{
|
||||
COUNT result, fd;
|
||||
|
||||
fd = (short)dos_open(name, O_RDONLY | O_OPEN, 0);
|
||||
if (fd < SUCCESS)
|
||||
return fd;
|
||||
|
||||
result = dos_getfattr_fd(fd);
|
||||
dos_close(fd);
|
||||
return result;
|
||||
}
|
||||
|
||||
COUNT dos_setfattr(BYTE * name, UWORD attrp)
|
||||
{
|
||||
f_node_ptr fnp;
|
||||
COUNT fd;
|
||||
f_node_ptr fnp;
|
||||
|
||||
/* Translate the fd into an fnode pointer, since all internal */
|
||||
/* operations are achieved through fnodes. */
|
||||
if ((fd = dos_open(name, O_RDONLY)) < SUCCESS)
|
||||
return DE_FILENOTFND;
|
||||
|
||||
/* note: an invalid fd is indicated by a 0 return */
|
||||
if ((fnp = xlt_fd(fd)) == (f_node_ptr) 0)
|
||||
return DE_TOOMANY;
|
||||
|
||||
/* If the fd was invalid because it was out of range or the */
|
||||
/* requested file was not open, tell the caller and exit */
|
||||
if (fnp->f_count <= 0)
|
||||
{
|
||||
dos_close(fd);
|
||||
return DE_FILENOTFND;
|
||||
}
|
||||
/* JPP-If user tries to set VOLID or DIR bits, return error */
|
||||
if ((attrp & (D_VOLID | D_DIR | 0xC0)) != 0)
|
||||
{
|
||||
dos_close(fd);
|
||||
return DE_ACCESS;
|
||||
}
|
||||
|
||||
fd = (short)dos_open(name, O_RDONLY | O_OPEN, 0);
|
||||
if (fd < SUCCESS)
|
||||
return fd;
|
||||
|
||||
fnp = xlt_fd(fd);
|
||||
|
||||
/* Set the attribute from the fnode and return */
|
||||
/* clear all attributes but DIR and VOLID */
|
||||
fnp->f_dir.dir_attrib &= (D_VOLID | D_DIR); /* JPP */
|
||||
|
||||
|
||||
/* set attributes that user requested */
|
||||
fnp->f_dir.dir_attrib |= attrp; /* JPP */
|
||||
fnp->f_flags.f_dmod = TRUE;
|
||||
@ -2094,8 +2050,6 @@ VOID bpb_to_dpb(bpb FAR * bpbp, REG struct dpb FAR * dpbp)
|
||||
|
||||
COUNT media_check(REG struct dpb FAR * dpbp)
|
||||
{
|
||||
BYTE status;
|
||||
|
||||
/* First test if anyone has changed the removable media */
|
||||
FOREVER
|
||||
{
|
||||
@ -2105,10 +2059,8 @@ COUNT media_check(REG struct dpb FAR * dpbp)
|
||||
MediaReqHdr.r_mcmdesc = dpbp->dpb_mdb;
|
||||
MediaReqHdr.r_status = 0;
|
||||
execrh((request FAR *) & MediaReqHdr, dpbp->dpb_device);
|
||||
if (!(MediaReqHdr.r_status & S_ERROR)
|
||||
&& (MediaReqHdr.r_status & S_DONE))
|
||||
break;
|
||||
else
|
||||
if ((MediaReqHdr.r_status & S_ERROR)
|
||||
|| !(MediaReqHdr.r_status & S_DONE))
|
||||
{
|
||||
loop1:
|
||||
switch (block_error(&MediaReqHdr, dpbp->dpb_unit, dpbp->dpb_device))
|
||||
@ -2127,10 +2079,10 @@ COUNT media_check(REG struct dpb FAR * dpbp)
|
||||
goto loop1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
status = MediaReqHdr.r_mcretcode | dpbp->dpb_flags;
|
||||
switch (status)
|
||||
switch (MediaReqHdr.r_mcretcode | dpbp->dpb_flags)
|
||||
{
|
||||
case M_NOT_CHANGED:
|
||||
/* It was definitely not changed, so ignore it */
|
||||
@ -2139,6 +2091,7 @@ COUNT media_check(REG struct dpb FAR * dpbp)
|
||||
/* If it is forced or the media may have changed, */
|
||||
/* rebuild the bpb */
|
||||
case M_DONT_KNOW:
|
||||
/* hazard: no error checking! */
|
||||
flush_buffers(dpbp->dpb_unit);
|
||||
|
||||
/* If it definitely changed, don't know (falls through) */
|
||||
@ -2154,10 +2107,8 @@ COUNT media_check(REG struct dpb FAR * dpbp)
|
||||
MediaReqHdr.r_mcmdesc = dpbp->dpb_mdb;
|
||||
MediaReqHdr.r_status = 0;
|
||||
execrh((request FAR *) & MediaReqHdr, dpbp->dpb_device);
|
||||
if (!(MediaReqHdr.r_status & S_ERROR)
|
||||
&& (MediaReqHdr.r_status & S_DONE))
|
||||
break;
|
||||
else
|
||||
if ((MediaReqHdr.r_status & S_ERROR)
|
||||
|| !(MediaReqHdr.r_status & S_DONE))
|
||||
{
|
||||
loop2:
|
||||
switch (block_error
|
||||
@ -2177,6 +2128,7 @@ COUNT media_check(REG struct dpb FAR * dpbp)
|
||||
goto loop2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
#ifdef WITHFAT32
|
||||
/* extend dpb only for internal or FAT32 devices */
|
||||
@ -2185,9 +2137,6 @@ COUNT media_check(REG struct dpb FAR * dpbp)
|
||||
#else
|
||||
bpb_to_dpb(MediaReqHdr.r_bpptr, dpbp);
|
||||
#endif
|
||||
/* need to change to root directory if changed */
|
||||
if (status == M_CHANGED)
|
||||
CDSp[dpbp->dpb_unit].cdsCurrentPath[3] = '\0';
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
@ -2249,7 +2198,7 @@ STATIC VOID shrink_file(f_node_ptr fnp)
|
||||
|
||||
next = next_cluster(dpbp, st);
|
||||
|
||||
if (next == LONG_LAST_CLUSTER) /* last cluster found */
|
||||
if (next == 1 || next == LONG_LAST_CLUSTER) /* error last cluster found */
|
||||
goto done;
|
||||
|
||||
/* Loop from start until either a FREE entry is */
|
||||
|
486
kernel/fcbfns.c
486
kernel/fcbfns.c
@ -36,38 +36,30 @@ static BYTE *RcsId =
|
||||
|
||||
#define FCB_SUCCESS 0
|
||||
#define FCB_ERR_NODATA 1
|
||||
#define FCB_ERR_SEGMENT_WRAP 2
|
||||
#define FCB_ERR_EOF 3
|
||||
#define FCB_ERR_WRITE 1
|
||||
#define FCB_ERROR 0xff
|
||||
|
||||
#ifdef PROTO
|
||||
fcb FAR *ExtFcbToFcb(xfcb FAR * lpExtFcb);
|
||||
fcb FAR *CommonFcbInit(xfcb FAR * lpExtFcb, BYTE * pszBuffer,
|
||||
STATIC fcb FAR *ExtFcbToFcb(xfcb FAR * lpExtFcb);
|
||||
STATIC fcb FAR *CommonFcbInit(xfcb FAR * lpExtFcb, BYTE * pszBuffer,
|
||||
COUNT * pCurDrive);
|
||||
void FcbNameInit(fcb FAR * lpFcb, BYTE * pszBuffer, COUNT * pCurDrive);
|
||||
VOID FcbNextRecord(fcb FAR * lpFcb);
|
||||
BOOL FcbCalcRec(xfcb FAR * lpXfcb);
|
||||
#else
|
||||
fcb FAR *ExtFcbToFcb();
|
||||
fcb FAR *CommonFcbInit();
|
||||
void FcbNameInit();
|
||||
VOID FcbNextRecord();
|
||||
BOOL FcbCalcRec();
|
||||
#endif
|
||||
STATIC int FcbNameInit(fcb FAR * lpFcb, BYTE * pszBuffer, COUNT * pCurDrive);
|
||||
STATIC void FcbNextRecord(fcb FAR * lpFcb);
|
||||
STATIC void FcbCalcRec(xfcb FAR * lpXfcb);
|
||||
|
||||
#define TestCmnSeps(lpFileName) (strchr(":<|>+=,", *lpFileName) != NULL)
|
||||
#define TestFieldSeps(lpFileName) (*(lpFileName) <= ' ' || strchr("/\"[]<>|.", *lpFileName) != NULL)
|
||||
#define TestCmnSeps(lpFileName) (*lpFileName && strchr(":<|>+=,", *lpFileName) != NULL)
|
||||
#define TestFieldSeps(lpFileName) ((unsigned char)*lpFileName <= ' ' || strchr("/\"[]<>|.", *lpFileName) != NULL)
|
||||
|
||||
static dmatch Dmatch;
|
||||
|
||||
VOID FatGetDrvData(UCOUNT drive, UCOUNT FAR * spc, UCOUNT FAR * bps,
|
||||
UCOUNT FAR * nc, BYTE FAR ** mdp)
|
||||
BYTE FAR *FatGetDrvData(UBYTE drive, UWORD * spc, UWORD * bps, UWORD * nc)
|
||||
{
|
||||
static BYTE mdb;
|
||||
UCOUNT navc;
|
||||
UWORD navc;
|
||||
|
||||
/* get the data available from dpb */
|
||||
*nc = 0xffff; /* pass 0xffff to skip free count */
|
||||
if (DosGetFree((UBYTE) drive, spc, &navc, bps, nc))
|
||||
if (DosGetFree(drive, spc, &navc, bps, nc))
|
||||
{
|
||||
struct cds FAR *cdsp =
|
||||
&CDSp[(drive == 0 ? default_drive : drive - 1)];
|
||||
@ -75,14 +67,15 @@ VOID FatGetDrvData(UCOUNT drive, UCOUNT FAR * spc, UCOUNT FAR * bps,
|
||||
if (cdsp->cdsFlags & CDSNETWDRV)
|
||||
{
|
||||
mdb = *spc >> 8;
|
||||
*mdp = &mdb;
|
||||
*spc &= 0xff;
|
||||
return &mdb;
|
||||
}
|
||||
else
|
||||
{
|
||||
*mdp = (BYTE FAR *) & (cdsp->cdsDpb->dpb_mdb);
|
||||
return (BYTE FAR *) & (cdsp->cdsDpb->dpb_mdb);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define PARSE_SEP_STOP 0x01
|
||||
@ -95,78 +88,81 @@ VOID FatGetDrvData(UCOUNT drive, UCOUNT FAR * spc, UCOUNT FAR * bps,
|
||||
#define PARSE_RET_BADDRIVE 0xff
|
||||
|
||||
#ifndef IPL
|
||||
WORD FcbParseFname(int wTestMode, const BYTE FAR ** lpFileName, fcb FAR * lpFcb)
|
||||
UWORD FcbParseFname(int *wTestMode, const BYTE FAR * lpFileName, fcb FAR * lpFcb)
|
||||
{
|
||||
COUNT nIndex;
|
||||
WORD wRetCodeName = FALSE, wRetCodeExt = FALSE;
|
||||
const BYTE FAR * lpFileName2 = lpFileName;
|
||||
|
||||
/* pjv -- ExtFcbToFcb? */
|
||||
/* Start out with some simple stuff first. Check if we are */
|
||||
/* going to use a default drive specificaton. */
|
||||
if (!(wTestMode & PARSE_DFLT_DRIVE))
|
||||
if (!(*wTestMode & PARSE_DFLT_DRIVE))
|
||||
lpFcb->fcb_drive = FDFLT_DRIVE;
|
||||
if (!(wTestMode & PARSE_BLNK_FNAME))
|
||||
if (!(*wTestMode & PARSE_BLNK_FNAME))
|
||||
{
|
||||
for (nIndex = 0; nIndex < FNAME_SIZE; ++nIndex)
|
||||
lpFcb->fcb_fname[nIndex] = ' ';
|
||||
fmemset(lpFcb->fcb_fname, ' ', FNAME_SIZE);
|
||||
}
|
||||
if (!(wTestMode & PARSE_BLNK_FEXT))
|
||||
if (!(*wTestMode & PARSE_BLNK_FEXT))
|
||||
{
|
||||
for (nIndex = 0; nIndex < FEXT_SIZE; ++nIndex)
|
||||
lpFcb->fcb_fext[nIndex] = ' ';
|
||||
fmemset(lpFcb->fcb_fext, ' ', FEXT_SIZE);
|
||||
}
|
||||
|
||||
/* Undocumented behavior, set record number & record size to 0 */
|
||||
lpFcb->fcb_cublock = lpFcb->fcb_recsiz = 0;
|
||||
|
||||
if (!(wTestMode & PARSE_SEP_STOP))
|
||||
if (!(*wTestMode & PARSE_SEP_STOP))
|
||||
{
|
||||
*lpFileName = ParseSkipWh(*lpFileName);
|
||||
if (TestCmnSeps(*lpFileName))
|
||||
++ * lpFileName;
|
||||
lpFileName2 = ParseSkipWh(lpFileName2);
|
||||
if (TestCmnSeps(lpFileName2))
|
||||
++lpFileName2;
|
||||
}
|
||||
|
||||
/* Undocumented "feature," we skip white space anyway */
|
||||
*lpFileName = ParseSkipWh(*lpFileName);
|
||||
lpFileName2 = ParseSkipWh(lpFileName2);
|
||||
|
||||
/* Now check for drive specification */
|
||||
if (*(*lpFileName + 1) == ':')
|
||||
if (*(lpFileName2 + 1) == ':')
|
||||
{
|
||||
/* non-portable construct to be changed */
|
||||
REG UBYTE Drive = DosUpFChar(**lpFileName) - 'A';
|
||||
REG UBYTE Drive = DosUpFChar(*lpFileName2) - 'A';
|
||||
|
||||
if (Drive >= lastdrive)
|
||||
return PARSE_RET_BADDRIVE;
|
||||
{
|
||||
*wTestMode = PARSE_RET_BADDRIVE;
|
||||
return lpFileName2 - lpFileName;
|
||||
}
|
||||
|
||||
lpFcb->fcb_drive = Drive + 1;
|
||||
*lpFileName += 2;
|
||||
lpFileName2 += 2;
|
||||
}
|
||||
|
||||
/* special cases: '.' and '..' */
|
||||
if (**lpFileName == '.')
|
||||
if (*lpFileName2 == '.')
|
||||
{
|
||||
lpFcb->fcb_fname[0] = '.';
|
||||
++*lpFileName;
|
||||
if (**lpFileName == '.')
|
||||
++lpFileName2;
|
||||
if (*lpFileName2 == '.')
|
||||
{
|
||||
lpFcb->fcb_fname[1] = '.';
|
||||
++*lpFileName;
|
||||
++lpFileName2;
|
||||
}
|
||||
return PARSE_RET_NOWILD;
|
||||
*wTestMode = PARSE_RET_NOWILD;
|
||||
return lpFileName2 - lpFileName;
|
||||
}
|
||||
|
||||
/* Now to format the file name into the string */
|
||||
*lpFileName =
|
||||
GetNameField(*lpFileName, (BYTE FAR *) lpFcb->fcb_fname, FNAME_SIZE,
|
||||
lpFileName2 =
|
||||
GetNameField(lpFileName2, (BYTE FAR *) lpFcb->fcb_fname, FNAME_SIZE,
|
||||
(BOOL *) & wRetCodeName);
|
||||
|
||||
/* Do we have an extension? If do, format it else return */
|
||||
if (**lpFileName == '.')
|
||||
*lpFileName =
|
||||
GetNameField(++*lpFileName, (BYTE FAR *) lpFcb->fcb_fext,
|
||||
if (*lpFileName2 == '.')
|
||||
lpFileName2 =
|
||||
GetNameField(++lpFileName2, (BYTE FAR *) lpFcb->fcb_fext,
|
||||
FEXT_SIZE, (BOOL *) & wRetCodeExt);
|
||||
|
||||
return (wRetCodeName | wRetCodeExt) ? PARSE_RET_WILD : PARSE_RET_NOWILD;
|
||||
*wTestMode = (wRetCodeName | wRetCodeExt) ? PARSE_RET_WILD : PARSE_RET_NOWILD;
|
||||
return lpFileName2 - lpFileName;
|
||||
}
|
||||
|
||||
const BYTE FAR * ParseSkipWh(const BYTE FAR * lpFileName)
|
||||
@ -229,8 +225,7 @@ const BYTE FAR * GetNameField(const BYTE FAR * lpFileName, BYTE FAR * lpDestFiel
|
||||
}
|
||||
|
||||
/* Blank out remainder of field on exit */
|
||||
for (; nIndex < nFieldSize; ++nIndex)
|
||||
*lpDestField++ = cFill;
|
||||
fmemset(lpDestField, cFill, nFieldSize - nIndex);
|
||||
return lpFileName;
|
||||
}
|
||||
|
||||
@ -248,109 +243,55 @@ STATIC ULONG FcbRec(VOID)
|
||||
return ((ULONG) lpFcb->fcb_cublock * 128) + lpFcb->fcb_curec;
|
||||
}
|
||||
|
||||
BOOL FcbRead(xfcb FAR * lpXfcb, COUNT * nErrorCode, UCOUNT recno)
|
||||
UBYTE FcbReadWrite(xfcb FAR * lpXfcb, UCOUNT recno, int mode)
|
||||
{
|
||||
sft FAR *s;
|
||||
ULONG lPosit;
|
||||
COUNT nRead;
|
||||
UCOUNT nTransfer;
|
||||
BYTE far * FcbIoPtr = dta + recno * lpFcb->fcb_recsiz;
|
||||
|
||||
if ((ULONG)recno * lpFcb->fcb_recsiz >= 0x10000ul ||
|
||||
FP_OFF(FcbIoPtr) < FP_OFF(dta))
|
||||
return FCB_ERR_SEGMENT_WRAP;
|
||||
|
||||
/* Convert to fcb if necessary */
|
||||
lpFcb = ExtFcbToFcb(lpXfcb);
|
||||
|
||||
|
||||
/* Get the SFT block that contains the SFT */
|
||||
if ((s = idx_to_sft(lpFcb->fcb_sftno)) == (sft FAR *) - 1)
|
||||
return FALSE;
|
||||
return FCB_ERR_NODATA;
|
||||
|
||||
/* If this is not opened another error */
|
||||
if (s->sft_count == 0)
|
||||
return FALSE;
|
||||
|
||||
return FCB_ERR_NODATA;
|
||||
|
||||
/* Now update the fcb and compute where we need to position */
|
||||
/* to. */
|
||||
lPosit = FcbRec() * lpFcb->fcb_recsiz;
|
||||
if (SftSeek(s, lPosit, 0) != SUCCESS)
|
||||
{
|
||||
*nErrorCode = FCB_ERR_EOF;
|
||||
return FALSE;
|
||||
}
|
||||
if ((CritErrCode = -SftSeek(s, lPosit, 0)) != SUCCESS)
|
||||
return FCB_ERR_NODATA;
|
||||
|
||||
/* Do the read */
|
||||
nRead = DosReadSft(s, lpFcb->fcb_recsiz, FcbIoPtr, nErrorCode);
|
||||
|
||||
nTransfer = DosRWSft(s, lpFcb->fcb_recsiz, FcbIoPtr, &CritErrCode, mode);
|
||||
CritErrCode = -CritErrCode;
|
||||
|
||||
/* Now find out how we will return and do it. */
|
||||
if (nRead == lpFcb->fcb_recsiz)
|
||||
if (nTransfer == lpFcb->fcb_recsiz)
|
||||
{
|
||||
*nErrorCode = FCB_SUCCESS;
|
||||
if (mode == XFR_WRITE) lpFcb->fcb_fsize = s->sft_size;
|
||||
FcbNextRecord(lpFcb);
|
||||
return TRUE;
|
||||
return FCB_SUCCESS;
|
||||
}
|
||||
else if (nRead < 0)
|
||||
if (mode == XFR_READ && nTransfer > 0)
|
||||
{
|
||||
*nErrorCode = FCB_ERR_EOF;
|
||||
return TRUE;
|
||||
}
|
||||
else if (nRead == 0)
|
||||
{
|
||||
*nErrorCode = FCB_ERR_NODATA;
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
fmemset(FcbIoPtr + nRead, 0, lpFcb->fcb_recsiz - nRead);
|
||||
*nErrorCode = FCB_ERR_EOF;
|
||||
fmemset(FcbIoPtr + nTransfer, 0, lpFcb->fcb_recsiz - nTransfer);
|
||||
FcbNextRecord(lpFcb);
|
||||
return FALSE;
|
||||
return FCB_ERR_EOF;
|
||||
}
|
||||
return FCB_ERR_NODATA;
|
||||
}
|
||||
|
||||
BOOL FcbWrite(xfcb FAR * lpXfcb, COUNT * nErrorCode, UCOUNT recno)
|
||||
{
|
||||
sft FAR *s;
|
||||
ULONG lPosit;
|
||||
COUNT nWritten;
|
||||
BYTE far * FcbIoPtr = dta + recno * lpFcb->fcb_recsiz;
|
||||
|
||||
/* Convert to fcb if necessary */
|
||||
lpFcb = ExtFcbToFcb(lpXfcb);
|
||||
|
||||
/* Get the SFT block that contains the SFT */
|
||||
if ((s = idx_to_sft(lpFcb->fcb_sftno)) == (sft FAR *) - 1)
|
||||
return FALSE;
|
||||
|
||||
/* If this is not opened another error */
|
||||
if (s->sft_count == 0)
|
||||
return FALSE;
|
||||
|
||||
/* Now update the fcb and compute where we need to position */
|
||||
/* to. */
|
||||
lPosit = FcbRec() * lpFcb->fcb_recsiz;
|
||||
if (SftSeek(s, lPosit, 0) != SUCCESS)
|
||||
{
|
||||
*nErrorCode = FCB_ERR_EOF;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
nWritten = DosWriteSft(s, lpFcb->fcb_recsiz, FcbIoPtr, nErrorCode);
|
||||
|
||||
/* Now find out how we will return and do it. */
|
||||
if (nWritten == lpFcb->fcb_recsiz)
|
||||
{
|
||||
lpFcb->fcb_fsize = s->sft_size;
|
||||
FcbNextRecord(lpFcb);
|
||||
*nErrorCode = FCB_SUCCESS;
|
||||
return TRUE;
|
||||
}
|
||||
else if (nWritten <= 0)
|
||||
{
|
||||
*nErrorCode = FCB_ERR_WRITE;
|
||||
return TRUE;
|
||||
}
|
||||
*nErrorCode = FCB_ERR_WRITE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL FcbGetFileSize(xfcb FAR * lpXfcb)
|
||||
UBYTE FcbGetFileSize(xfcb FAR * lpXfcb)
|
||||
{
|
||||
COUNT FcbDrive, hndl;
|
||||
|
||||
@ -358,11 +299,10 @@ BOOL FcbGetFileSize(xfcb FAR * lpXfcb)
|
||||
lpFcb = CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
|
||||
|
||||
/* check for a device */
|
||||
if (IsDevice(SecPathName) || (lpFcb->fcb_recsiz == 0))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
hndl = DosOpen(SecPathName, O_RDONLY);
|
||||
if (!lpFcb || IsDevice(SecPathName) || (lpFcb->fcb_recsiz == 0))
|
||||
return FCB_ERROR;
|
||||
|
||||
hndl = (short)DosOpen(SecPathName, O_LEGACY | O_RDONLY | O_OPEN, 0);
|
||||
if (hndl >= 0)
|
||||
{
|
||||
ULONG fsize;
|
||||
@ -376,13 +316,15 @@ BOOL FcbGetFileSize(xfcb FAR * lpXfcb)
|
||||
++lpFcb->fcb_rndm;
|
||||
|
||||
/* close the file and leave */
|
||||
return DosClose(hndl) == SUCCESS;
|
||||
if ((CritErrCode = -DosClose(hndl)) == SUCCESS)
|
||||
return FCB_SUCCESS;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
CritErrCode = -hndl;
|
||||
return FCB_ERROR;
|
||||
}
|
||||
|
||||
BOOL FcbSetRandom(xfcb FAR * lpXfcb)
|
||||
void FcbSetRandom(xfcb FAR * lpXfcb)
|
||||
{
|
||||
/* Convert to fcb if necessary */
|
||||
lpFcb = ExtFcbToFcb(lpXfcb);
|
||||
@ -390,11 +332,9 @@ BOOL FcbSetRandom(xfcb FAR * lpXfcb)
|
||||
/* Now update the fcb and compute where we need to position */
|
||||
/* to. */
|
||||
lpFcb->fcb_rndm = FcbRec();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL FcbCalcRec(xfcb FAR * lpXfcb)
|
||||
void FcbCalcRec(xfcb FAR * lpXfcb)
|
||||
{
|
||||
|
||||
/* Convert to fcb if necessary */
|
||||
@ -404,14 +344,12 @@ BOOL FcbCalcRec(xfcb FAR * lpXfcb)
|
||||
/* to. */
|
||||
lpFcb->fcb_cublock = lpFcb->fcb_rndm / 128;
|
||||
lpFcb->fcb_curec = lpFcb->fcb_rndm & 127;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL FcbRandomBlockRead(xfcb FAR * lpXfcb, COUNT nRecords,
|
||||
COUNT * nErrorCode)
|
||||
UBYTE FcbRandomBlockIO(xfcb FAR * lpXfcb, COUNT nRecords, int mode)
|
||||
{
|
||||
UCOUNT recno = 0;
|
||||
UBYTE nErrorCode;
|
||||
|
||||
FcbCalcRec(lpXfcb);
|
||||
|
||||
@ -419,39 +357,20 @@ BOOL FcbRandomBlockRead(xfcb FAR * lpXfcb, COUNT nRecords,
|
||||
lpFcb = ExtFcbToFcb(lpXfcb);
|
||||
|
||||
do
|
||||
FcbRead(lpXfcb, nErrorCode, recno++);
|
||||
while ((--nRecords > 0) && (*nErrorCode == 0));
|
||||
nErrorCode = FcbReadWrite(lpXfcb, recno++, mode);
|
||||
while ((--nRecords > 0) && (nErrorCode == 0));
|
||||
|
||||
/* Now update the fcb */
|
||||
lpFcb->fcb_rndm = FcbRec();
|
||||
|
||||
return TRUE;
|
||||
return nErrorCode;
|
||||
}
|
||||
|
||||
BOOL FcbRandomBlockWrite(xfcb FAR * lpXfcb, COUNT nRecords,
|
||||
COUNT * nErrorCode)
|
||||
{
|
||||
UCOUNT recno = 0;
|
||||
|
||||
FcbCalcRec(lpXfcb);
|
||||
|
||||
/* Convert to fcb if necessary */
|
||||
lpFcb = ExtFcbToFcb(lpXfcb);
|
||||
|
||||
do
|
||||
FcbWrite(lpXfcb, nErrorCode, recno++);
|
||||
while ((--nRecords > 0) && (*nErrorCode == 0));
|
||||
|
||||
/* Now update the fcb */
|
||||
lpFcb->fcb_rndm = FcbRec();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL FcbRandomIO(xfcb FAR * lpXfcb, COUNT * nErrorCode, FcbFunc_t *FcbFunc)
|
||||
UBYTE FcbRandomIO(xfcb FAR * lpXfcb, int mode)
|
||||
{
|
||||
UWORD uwCurrentBlock;
|
||||
UBYTE ucCurrentRecord;
|
||||
UBYTE nErrorCode;
|
||||
|
||||
FcbCalcRec(lpXfcb);
|
||||
|
||||
@ -461,39 +380,35 @@ BOOL FcbRandomIO(xfcb FAR * lpXfcb, COUNT * nErrorCode, FcbFunc_t *FcbFunc)
|
||||
uwCurrentBlock = lpFcb->fcb_cublock;
|
||||
ucCurrentRecord = lpFcb->fcb_curec;
|
||||
|
||||
(*FcbFunc) (lpXfcb, nErrorCode, 0);
|
||||
nErrorCode = FcbReadWrite(lpXfcb, 0, mode);
|
||||
|
||||
lpFcb->fcb_cublock = uwCurrentBlock;
|
||||
lpFcb->fcb_curec = ucCurrentRecord;
|
||||
return TRUE;
|
||||
return nErrorCode;
|
||||
}
|
||||
|
||||
/* merged fcbOpen and FcbCreate - saves ~200 byte */
|
||||
BOOL FcbOpenCreate(xfcb FAR * lpXfcb, BOOL Create)
|
||||
UBYTE FcbOpen(xfcb FAR * lpXfcb, unsigned flags)
|
||||
{
|
||||
sft FAR *sftp;
|
||||
COUNT sft_idx, FcbDrive;
|
||||
unsigned attr = 0;
|
||||
|
||||
/* Build a traditional DOS file name */
|
||||
lpFcb = CommonFcbInit(lpXfcb, PriPathName, &FcbDrive);
|
||||
lpFcb = CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
|
||||
if (lpFcb == NULL)
|
||||
return FCB_ERROR;
|
||||
|
||||
if (Create)
|
||||
{
|
||||
if ((flags & O_CREAT) && lpXfcb->xfcb_flag == 0xff)
|
||||
/* pass attribute without constraints (dangerous for directories) */
|
||||
int attr = (lpXfcb->xfcb_flag == 0xff ? lpXfcb->xfcb_attrib : 0);
|
||||
sft_idx = DosCreatSft(PriPathName, attr);
|
||||
}
|
||||
else
|
||||
{
|
||||
sft_idx = DosOpenSft(PriPathName, O_RDWR | SFT_MFCB);
|
||||
|
||||
/* if file is RDONLY, try to open rdonly */
|
||||
if (sft_idx == DE_ACCESS)
|
||||
sft_idx = DosOpenSft(PriPathName, O_RDONLY | SFT_MFCB);
|
||||
}
|
||||
attr = lpXfcb->xfcb_attrib;
|
||||
|
||||
sft_idx = (short)DosOpenSft(SecPathName, flags, attr);
|
||||
if (sft_idx < 0)
|
||||
return FALSE;
|
||||
{
|
||||
CritErrCode = -sft_idx;
|
||||
return FCB_ERROR;
|
||||
}
|
||||
|
||||
sftp = idx_to_sft(sft_idx);
|
||||
sftp->sft_mode |= SFT_MFCB;
|
||||
@ -511,7 +426,7 @@ BOOL FcbOpenCreate(xfcb FAR * lpXfcb, BOOL Create)
|
||||
lpFcb->fcb_fsize = sftp->sft_size;
|
||||
lpFcb->fcb_date = sftp->sft_date;
|
||||
lpFcb->fcb_time = sftp->sft_time;
|
||||
return TRUE;
|
||||
return FCB_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@ -532,13 +447,14 @@ STATIC fcb FAR *CommonFcbInit(xfcb FAR * lpExtFcb, BYTE * pszBuffer,
|
||||
lpFcb = ExtFcbToFcb(lpExtFcb);
|
||||
|
||||
/* Build a traditional DOS file name */
|
||||
FcbNameInit(lpFcb, pszBuffer, pCurDrive);
|
||||
if (FcbNameInit(lpFcb, pszBuffer, pCurDrive) < SUCCESS)
|
||||
return NULL;
|
||||
|
||||
/* and return the fcb pointer */
|
||||
return lpFcb;
|
||||
}
|
||||
|
||||
void FcbNameInit(fcb FAR * lpFcb, BYTE * szBuffer, COUNT * pCurDrive)
|
||||
int FcbNameInit(fcb FAR * lpFcb, BYTE * szBuffer, COUNT * pCurDrive)
|
||||
{
|
||||
BYTE loc_szBuffer[2 + FNAME_SIZE + 1 + FEXT_SIZE + 1]; /* 'A:' + '.' + '\0' */
|
||||
BYTE *pszBuffer = loc_szBuffer;
|
||||
@ -556,85 +472,83 @@ void FcbNameInit(fcb FAR * lpFcb, BYTE * szBuffer, COUNT * pCurDrive)
|
||||
*pCurDrive = default_drive + 1;
|
||||
}
|
||||
ConvertName83ToNameSZ(pszBuffer, (BYTE FAR *) lpFcb->fcb_fname);
|
||||
truename(loc_szBuffer, szBuffer, FALSE);
|
||||
/* XXX fix truename error handling */
|
||||
return truename(loc_szBuffer, szBuffer, CDS_MODE_CHECK_DEV_PATH);
|
||||
}
|
||||
|
||||
BOOL FcbDelete(xfcb FAR * lpXfcb)
|
||||
UBYTE FcbDelete(xfcb FAR * lpXfcb)
|
||||
{
|
||||
COUNT FcbDrive;
|
||||
UBYTE result = FCB_SUCCESS;
|
||||
BYTE FAR *lpOldDta = dta;
|
||||
|
||||
/* Build a traditional DOS file name */
|
||||
CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
|
||||
|
||||
/* check for a device */
|
||||
if (IsDevice(SecPathName))
|
||||
if (lpFcb == NULL || IsDevice(SecPathName))
|
||||
{
|
||||
return FALSE;
|
||||
result = FCB_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
int attr = (lpXfcb->xfcb_flag == 0xff ? lpXfcb->xfcb_attrib : D_ALL);
|
||||
BYTE FAR *lpOldDta = dta;
|
||||
int attr = (lpXfcb->xfcb_flag == 0xff ? lpXfcb->xfcb_attrib : D_ALL);
|
||||
dmatch Dmatch;
|
||||
|
||||
dta = (BYTE FAR *) & Dmatch;
|
||||
if (DosFindFirst(attr, SecPathName) != SUCCESS)
|
||||
if ((CritErrCode = -DosFindFirst(attr, SecPathName)) != SUCCESS)
|
||||
{
|
||||
dta = lpOldDta;
|
||||
return FALSE;
|
||||
result = FCB_ERROR;
|
||||
}
|
||||
do
|
||||
else do
|
||||
{
|
||||
SecPathName[0] = 'A' + FcbDrive - 1;
|
||||
SecPathName[1] = ':';
|
||||
strcpy(&SecPathName[2], Dmatch.dm_name);
|
||||
if (DosDelete(SecPathName, attr) != SUCCESS)
|
||||
{
|
||||
dta = lpOldDta;
|
||||
return FALSE;
|
||||
result = FCB_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (DosFindNext() == SUCCESS);
|
||||
dta = lpOldDta;
|
||||
return TRUE;
|
||||
while ((CritErrCode = -DosFindNext()) == SUCCESS);
|
||||
}
|
||||
dta = lpOldDta;
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL FcbRename(xfcb FAR * lpXfcb)
|
||||
UBYTE FcbRename(xfcb FAR * lpXfcb)
|
||||
{
|
||||
rfcb FAR *lpRenameFcb;
|
||||
COUNT FcbDrive;
|
||||
UBYTE result = FCB_SUCCESS;
|
||||
BYTE FAR *lpOldDta = dta;
|
||||
|
||||
/* Build a traditional DOS file name */
|
||||
lpRenameFcb = (rfcb FAR *) CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
|
||||
wAttr = (lpXfcb->xfcb_flag == 0xff ? lpXfcb->xfcb_attrib : D_ALL);
|
||||
|
||||
|
||||
/* check for a device */
|
||||
if (IsDevice(SecPathName))
|
||||
if (lpRenameFcb == NULL || IsDevice(SecPathName))
|
||||
{
|
||||
return FALSE;
|
||||
result = FCB_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
BYTE FAR *lpOldDta = dta;
|
||||
dmatch Dmatch;
|
||||
COUNT result;
|
||||
|
||||
wAttr = (lpXfcb->xfcb_flag == 0xff ? lpXfcb->xfcb_attrib : D_ALL);
|
||||
dta = (BYTE FAR *) & Dmatch;
|
||||
if (DosFindFirst(wAttr, SecPathName) != SUCCESS)
|
||||
if ((CritErrCode = -DosFindFirst(wAttr, SecPathName)) != SUCCESS)
|
||||
{
|
||||
dta = lpOldDta;
|
||||
return FALSE;
|
||||
result = FCB_ERROR;
|
||||
}
|
||||
|
||||
do
|
||||
else do
|
||||
{
|
||||
fcb LocalFcb;
|
||||
BYTE *pToName;
|
||||
const BYTE FAR *pFromPattern = Dmatch.dm_name;
|
||||
int i;
|
||||
int i = 0;
|
||||
|
||||
FcbParseFname(0, &pFromPattern, &LocalFcb);
|
||||
FcbParseFname(&i, pFromPattern, &LocalFcb);
|
||||
/* Overlay the pattern, skipping '?' */
|
||||
/* I'm cheating because this assumes that the */
|
||||
/* struct alignments are on byte boundaries */
|
||||
@ -651,22 +565,32 @@ BOOL FcbRename(xfcb FAR * lpXfcb)
|
||||
SecPathName[0] = 'A' + FcbDrive - 1;
|
||||
SecPathName[1] = ':';
|
||||
strcpy(&SecPathName[2], Dmatch.dm_name);
|
||||
truename(SecPathName, PriPathName, FALSE);
|
||||
result = truename(SecPathName, PriPathName, 0);
|
||||
|
||||
if (result < SUCCESS || (result & IS_DEVICE))
|
||||
{
|
||||
result = FCB_ERROR;
|
||||
break;
|
||||
}
|
||||
/* now to build a dos name again */
|
||||
LocalFcb.fcb_drive = FcbDrive;
|
||||
FcbNameInit((fcb FAR *) & LocalFcb, SecPathName, &FcbDrive);
|
||||
result = FcbNameInit((fcb FAR *) & LocalFcb, SecPathName, &FcbDrive);
|
||||
if (result < SUCCESS || (!(result & IS_NETWORK) && (result & IS_DEVICE)))
|
||||
{
|
||||
result = FCB_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (DosRenameTrue(PriPathName, SecPathName, wAttr) != SUCCESS)
|
||||
{
|
||||
dta = lpOldDta;
|
||||
return FALSE;
|
||||
result = FCB_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (DosFindNext() == SUCCESS);
|
||||
dta = lpOldDta;
|
||||
return TRUE;
|
||||
while ((CritErrCode = -DosFindNext()) == SUCCESS);
|
||||
}
|
||||
dta = lpOldDta;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* TE:the MoveDirInfo() is now done by simply copying the dirEntry into the FCB
|
||||
@ -674,7 +598,7 @@ BOOL FcbRename(xfcb FAR * lpXfcb)
|
||||
BO:use global SearchDir, as produced by FindFirst/Next
|
||||
*/
|
||||
|
||||
BOOL FcbClose(xfcb FAR * lpXfcb)
|
||||
UBYTE FcbClose(xfcb FAR * lpXfcb)
|
||||
{
|
||||
sft FAR *s;
|
||||
|
||||
@ -683,23 +607,23 @@ BOOL FcbClose(xfcb FAR * lpXfcb)
|
||||
|
||||
/* An already closed FCB can be closed again without error */
|
||||
if (lpFcb->fcb_sftno == (BYTE) 0xff)
|
||||
return TRUE;
|
||||
return FCB_SUCCESS;
|
||||
|
||||
/* Get the SFT block that contains the SFT */
|
||||
if ((s = idx_to_sft(lpFcb->fcb_sftno)) == (sft FAR *) - 1)
|
||||
return FALSE;
|
||||
return FCB_ERROR;
|
||||
|
||||
/* change time and set file size */
|
||||
s->sft_size = lpFcb->fcb_fsize;
|
||||
if (!(s->sft_flags & SFT_FSHARED))
|
||||
dos_setfsize(s->sft_status, lpFcb->fcb_fsize);
|
||||
DosSetFtimeSft(lpFcb->fcb_sftno, lpFcb->fcb_date, lpFcb->fcb_time);
|
||||
if (DosCloseSft(lpFcb->fcb_sftno, FALSE) == SUCCESS)
|
||||
if ((CritErrCode = -DosCloseSft(lpFcb->fcb_sftno, FALSE)) == SUCCESS)
|
||||
{
|
||||
lpFcb->fcb_sftno = (BYTE) 0xff;
|
||||
return TRUE;
|
||||
return FCB_SUCCESS;
|
||||
}
|
||||
return FALSE;
|
||||
return FCB_ERROR;
|
||||
}
|
||||
|
||||
/* close all files the current process opened by FCBs */
|
||||
@ -713,7 +637,7 @@ VOID FcbCloseAll()
|
||||
DosCloseSft(idx, FALSE);
|
||||
}
|
||||
|
||||
BOOL FcbFindFirst(xfcb FAR * lpXfcb)
|
||||
UBYTE FcbFindFirstNext(xfcb FAR * lpXfcb, BOOL First)
|
||||
{
|
||||
BYTE FAR *lpDir;
|
||||
COUNT FcbDrive;
|
||||
@ -726,31 +650,45 @@ BOOL FcbFindFirst(xfcb FAR * lpXfcb)
|
||||
|
||||
/* Next initialze local variables by moving them from the fcb */
|
||||
lpFcb = CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
|
||||
if (lpXfcb->xfcb_flag == 0xff)
|
||||
if (lpFcb == NULL)
|
||||
return FCB_ERROR;
|
||||
|
||||
/* Reconstrct the dirmatch structure from the fcb - doesn't hurt for first */
|
||||
Dmatch.dm_drive = lpFcb->fcb_sftno;
|
||||
|
||||
fmemcpy(Dmatch.dm_name_pat, lpFcb->fcb_fname, FNAME_SIZE + FEXT_SIZE);
|
||||
DosUpFMem((BYTE FAR *) Dmatch.dm_name_pat, FNAME_SIZE + FEXT_SIZE);
|
||||
|
||||
Dmatch.dm_attr_srch = wAttr;
|
||||
Dmatch.dm_entry = lpFcb->fcb_strtclst;
|
||||
Dmatch.dm_dircluster = lpFcb->fcb_dirclst;
|
||||
|
||||
wAttr = D_ALL;
|
||||
|
||||
if ((xfcb FAR *) lpFcb != lpXfcb)
|
||||
{
|
||||
wAttr = lpXfcb->xfcb_attrib;
|
||||
fmemcpy(lpDir, lpXfcb, 7);
|
||||
lpDir += 7;
|
||||
}
|
||||
else
|
||||
wAttr = D_ALL;
|
||||
|
||||
if (DosFindFirst(wAttr, SecPathName) != SUCCESS)
|
||||
CritErrCode = -(First ? DosFindFirst(wAttr, SecPathName) : DosFindNext());
|
||||
if (CritErrCode != SUCCESS)
|
||||
{
|
||||
dta = lpPsp->ps_dta;
|
||||
return FALSE;
|
||||
return FCB_ERROR;
|
||||
}
|
||||
|
||||
*lpDir++ = FcbDrive;
|
||||
fmemcpy(lpDir, &SearchDir, sizeof(struct dirent));
|
||||
|
||||
|
||||
lpFcb->fcb_dirclst = (UWORD) Dmatch.dm_dircluster;
|
||||
lpFcb->fcb_strtclst = Dmatch.dm_entry;
|
||||
|
||||
|
||||
/*
|
||||
This is undocumented and seen using Pcwatch and Ramview.
|
||||
The First byte is the current directory count and the second seems
|
||||
to be the attribute byte.
|
||||
This is undocumented and seen using Pcwatch and Ramview.
|
||||
The First byte is the current directory count and the second seems
|
||||
to be the attribute byte.
|
||||
*/
|
||||
lpFcb->fcb_sftno = Dmatch.dm_drive; /* MSD seems to save this @ fcb_date. */
|
||||
#if 0
|
||||
@ -758,66 +696,8 @@ BOOL FcbFindFirst(xfcb FAR * lpXfcb)
|
||||
lpFcb->fcb_cublock *= 0x100;
|
||||
lpFcb->fcb_cublock += wAttr;
|
||||
#endif
|
||||
|
||||
dta = lpPsp->ps_dta;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL FcbFindNext(xfcb FAR * lpXfcb)
|
||||
{
|
||||
BYTE FAR *lpDir;
|
||||
COUNT FcbDrive;
|
||||
psp FAR *lpPsp = MK_FP(cu_psp, 0);
|
||||
|
||||
/* First, move the dta to a local and change it around to match */
|
||||
/* our functions. */
|
||||
lpDir = (BYTE FAR *) dta;
|
||||
dta = (BYTE FAR *) & Dmatch;
|
||||
|
||||
/* Next initialze local variables by moving them from the fcb */
|
||||
lpFcb = CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
|
||||
|
||||
/* Reconstrct the dirmatch structure from the fcb */
|
||||
Dmatch.dm_drive = lpFcb->fcb_sftno;
|
||||
|
||||
fmemcpy(Dmatch.dm_name_pat, lpFcb->fcb_fname, FNAME_SIZE + FEXT_SIZE);
|
||||
DosUpFMem((BYTE FAR *) Dmatch.dm_name_pat, FNAME_SIZE + FEXT_SIZE);
|
||||
|
||||
Dmatch.dm_attr_srch = wAttr;
|
||||
Dmatch.dm_entry = lpFcb->fcb_strtclst;
|
||||
Dmatch.dm_dircluster = lpFcb->fcb_dirclst;
|
||||
|
||||
if ((xfcb FAR *) lpFcb != lpXfcb)
|
||||
{
|
||||
wAttr = lpXfcb->xfcb_attrib;
|
||||
fmemcpy(lpDir, lpXfcb, 7);
|
||||
lpDir += 7;
|
||||
}
|
||||
else
|
||||
wAttr = D_ALL;
|
||||
|
||||
if (DosFindNext() != SUCCESS)
|
||||
{
|
||||
dta = lpPsp->ps_dta;
|
||||
CritErrCode = 0x12;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*lpDir++ = FcbDrive;
|
||||
fmemcpy((struct dirent FAR *)lpDir, &SearchDir, sizeof(struct dirent));
|
||||
|
||||
lpFcb->fcb_dirclst = (UWORD) Dmatch.dm_dircluster;
|
||||
lpFcb->fcb_strtclst = Dmatch.dm_entry;
|
||||
|
||||
lpFcb->fcb_sftno = Dmatch.dm_drive;
|
||||
#if 0
|
||||
lpFcb->fcb_cublock = Dmatch.dm_entry;
|
||||
lpFcb->fcb_cublock *= 0x100;
|
||||
lpFcb->fcb_cublock += wAttr;
|
||||
#endif
|
||||
|
||||
dta = lpPsp->ps_dta;
|
||||
return TRUE;
|
||||
return FCB_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -307,15 +307,7 @@ extern struct /* Path name parsing buffer */
|
||||
BYTE _PriPathName[128];
|
||||
} ASM _PriPathBuffer;
|
||||
|
||||
extern struct {
|
||||
BYTE _fname[FNAME_SIZE];
|
||||
BYTE _fext[FEXT_SIZE + 1]; /* space for 0 */
|
||||
} ASM szNames;
|
||||
|
||||
#define PriPathName _PriPathBuffer._PriPathName
|
||||
#define szDirName TempCDS.cdsCurrentPath
|
||||
#define szFileName szNames._fname
|
||||
#define szFileExt szNames._fext
|
||||
|
||||
extern struct /* Alternate path name parsing buffer */
|
||||
{
|
||||
@ -440,25 +432,15 @@ COUNT con();
|
||||
#define fputword(vp, w) (*(UWORD FAR *)(vp)=w)
|
||||
#define fputbyte(vp, b) (*(UBYTE FAR *)(vp)=b)
|
||||
#else
|
||||
#ifdef PROTO
|
||||
WORD getword(VOID *);
|
||||
BYTE getbyte(VOID *);
|
||||
LONG fgetlong(VOID FAR *);
|
||||
WORD fgetword(VOID FAR *);
|
||||
BYTE fgetbyte(VOID FAR *);
|
||||
UDWORD getlong(VOID *);
|
||||
UWORD getword(VOID *);
|
||||
UBYTE getbyte(VOID *);
|
||||
UDWORD fgetlong(VOID FAR *);
|
||||
UWORD fgetword(VOID FAR *);
|
||||
UBYTE fgetbyte(VOID FAR *);
|
||||
VOID fputlong(VOID FAR *, UDWORD);
|
||||
VOID fputword(VOID FAR *, UWORD);
|
||||
VOID fputbyte(VOID FAR *, UBYTE);
|
||||
#else
|
||||
VOID getword();
|
||||
VOID getbyte();
|
||||
VOID fgetlong();
|
||||
VOID fgetword();
|
||||
VOID fgetbyte();
|
||||
VOID fputlong();
|
||||
VOID fputword();
|
||||
VOID fputbyte();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef I86
|
||||
|
@ -20,7 +20,13 @@ extern __segment DosTextSeg;
|
||||
#define DOSFAR FAR
|
||||
#define DOSTEXTFAR FAR
|
||||
|
||||
#elif !defined(I86)
|
||||
|
||||
#define DOSFAR
|
||||
#define DOSTEXTFAR
|
||||
|
||||
#else
|
||||
|
||||
#pragma error("unknown compiler - please adjust")
|
||||
this should simply not compile ! !
|
||||
#endif
|
||||
|
@ -106,7 +106,7 @@ IntDosCal:
|
||||
; UWORD ip,cs,flags;
|
||||
; UWORD callerARG1;
|
||||
;};
|
||||
Protect386Registers
|
||||
Protect386Registers
|
||||
push ax
|
||||
push cx
|
||||
push dx
|
||||
@ -131,7 +131,7 @@ IntDosCal:
|
||||
pop dx
|
||||
pop cx
|
||||
pop ax
|
||||
Restore386Registers
|
||||
Restore386Registers
|
||||
|
||||
iret
|
||||
|
||||
@ -255,6 +255,11 @@ _QRemote_Fn
|
||||
global _remote_printredir
|
||||
_remote_printredir:
|
||||
mov al, 25h
|
||||
jmp short call_int2f
|
||||
|
||||
global _remote_extopen
|
||||
_remote_extopen:
|
||||
mov al, 2eh
|
||||
|
||||
call_int2f:
|
||||
mov ah, 11h
|
||||
@ -263,7 +268,6 @@ call_int2f:
|
||||
push es
|
||||
push si
|
||||
push di
|
||||
push dx
|
||||
push cx
|
||||
push bx
|
||||
|
||||
@ -275,10 +279,6 @@ call_int2f:
|
||||
je print_doredir
|
||||
cmp al, 1fh
|
||||
je print_doredir
|
||||
cmp al, 21h ; 21h, Lseek from eof
|
||||
je lseekeof
|
||||
cmp al, 23h
|
||||
je qremote_fn
|
||||
cmp al, 25h
|
||||
je remote_printredir
|
||||
|
||||
@ -289,22 +289,27 @@ call_int2f:
|
||||
je remote_rw
|
||||
cmp al, 0ch
|
||||
je remote_getfree
|
||||
cmp al, 21h ; 21h, Lseek from eof
|
||||
je lseekeof
|
||||
cmp al, 23h
|
||||
je qremote_fn
|
||||
|
||||
int2f_call_push:
|
||||
push word [bp+8] ; very fakey, HaHa ;)
|
||||
int2f_call:
|
||||
clc ; set to succeed
|
||||
xor cx, cx ; set to succeed; clear carry and CX
|
||||
int 2fh
|
||||
pop bx
|
||||
jc no_clear_ax
|
||||
clear_ax:
|
||||
xor ax,ax
|
||||
mov ax, cx ; extended open -> status from CX in AX
|
||||
; otherwise CX was set to zero above
|
||||
jmp short no_neg_ax
|
||||
no_clear_ax:
|
||||
neg ax
|
||||
no_neg_ax:
|
||||
pop bx
|
||||
pop cx
|
||||
pop dx
|
||||
pop di
|
||||
pop si
|
||||
pop es
|
||||
@ -314,8 +319,8 @@ no_neg_ax:
|
||||
lseekeof:
|
||||
mov dx, [bp+8]
|
||||
mov cx, [bp+10]
|
||||
jmp int2f_call_push
|
||||
|
||||
; "fall through"
|
||||
|
||||
remote_getfattr:
|
||||
clc ; set to succeed
|
||||
int 2fh
|
||||
@ -358,17 +363,20 @@ remote_printredir:
|
||||
mov dx, [bp+4]
|
||||
push word [bp+6]
|
||||
jmp short int2f_call
|
||||
|
||||
remote_rw: jmp short remote_rw1
|
||||
|
||||
qremote_fn:
|
||||
lds si,[bp+4]
|
||||
les di,[bp+8]
|
||||
qremote_fn:
|
||||
push ds
|
||||
lds si,[bp+8]
|
||||
clc
|
||||
int 2fh
|
||||
pop ds
|
||||
mov ax,0xffff
|
||||
jc no_neg_ax
|
||||
jmp short clear_ax
|
||||
|
||||
remote_rw: mov cx, [bp+8]
|
||||
remote_rw1: mov cx, [bp+8]
|
||||
clc ; set to succeed
|
||||
int 2fh
|
||||
jc int2f_carry
|
||||
@ -377,7 +385,7 @@ int2f_carry: neg ax
|
||||
mov di, [bp+10]
|
||||
mov [di], ax
|
||||
mov ax, cx
|
||||
jmp short no_neg_ax
|
||||
jmp no_neg_ax
|
||||
|
||||
global _remote_process_end
|
||||
_remote_process_end: ; Terminate process
|
||||
|
1283
kernel/inthndlr.c
1283
kernel/inthndlr.c
File diff suppressed because it is too large
Load Diff
420
kernel/ioctl.c
420
kernel/ioctl.c
@ -54,7 +54,7 @@ static BYTE *RcsId =
|
||||
|
||||
*/
|
||||
|
||||
COUNT DosDevIOctl(iregs FAR * r)
|
||||
COUNT DosDevIOctl(lregs * r)
|
||||
{
|
||||
sft FAR *s;
|
||||
struct dpb FAR *dpbp;
|
||||
@ -78,10 +78,106 @@ COUNT DosDevIOctl(iregs FAR * r)
|
||||
case 0x07:
|
||||
case 0x0a:
|
||||
case 0x0c:
|
||||
case 0x10:
|
||||
|
||||
/* Get the SFT block that contains the SFT */
|
||||
if ((s = get_sft(r->BX)) == (sft FAR *) - 1)
|
||||
return DE_INVLDHNDL;
|
||||
|
||||
switch (r->AL)
|
||||
{
|
||||
case 0x00:
|
||||
/* Get the flags from the SFT */
|
||||
if (s->sft_flags & SFT_FDEVICE)
|
||||
r->AX = (s->sft_dev->dh_attr & 0xff00) | s->sft_flags_lo;
|
||||
else
|
||||
r->AX = s->sft_flags;
|
||||
/* Undocumented result, Ax = Dx seen using Pcwatch */
|
||||
r->DX = r->AX;
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
/* sft_flags is a file, return an error because you */
|
||||
/* can't set the status of a file. */
|
||||
if (!(s->sft_flags & SFT_FDEVICE))
|
||||
return DE_INVLDFUNC;
|
||||
|
||||
/* Set it to what we got in the DL register from the */
|
||||
/* user. */
|
||||
r->AL = s->sft_flags_lo = SFT_FDEVICE | r->DL;
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
nMode = C_IOCTLIN;
|
||||
goto IoCharCommon;
|
||||
|
||||
case 0x03:
|
||||
nMode = C_IOCTLOUT;
|
||||
goto IoCharCommon;
|
||||
|
||||
case 0x06:
|
||||
if (s->sft_flags & SFT_FDEVICE)
|
||||
r->AL = s->sft_flags & SFT_FEOF ? 0xFF : 0;
|
||||
else
|
||||
r->AL = s->sft_posit >= s->sft_size ? 0xFF : 0;
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
if (s->sft_flags & SFT_FDEVICE)
|
||||
{
|
||||
nMode = C_OSTAT;
|
||||
goto IoCharCommon;
|
||||
}
|
||||
r->AL = 0;
|
||||
break;
|
||||
|
||||
case 0x0a:
|
||||
r->DX = s->sft_flags;
|
||||
r->AX = 0;
|
||||
break;
|
||||
|
||||
case 0x0c:
|
||||
nMode = C_GENIOCTL;
|
||||
goto IoCharCommon;
|
||||
|
||||
case 0x10:
|
||||
nMode = C_IOCTLQRY;
|
||||
IoCharCommon:
|
||||
if ((s->sft_flags & SFT_FDEVICE)
|
||||
|| ((r->AL == 0x02) && (s->sft_dev->dh_attr & SFT_FIOCTL))
|
||||
|| ((r->AL == 0x03) && (s->sft_dev->dh_attr & SFT_FIOCTL))
|
||||
|| ((r->AL == 0x10) && (s->sft_dev->dh_attr & ATTR_QRYIOCTL))
|
||||
|| ((r->AL == 0x0c) && (s->sft_dev->dh_attr & ATTR_GENIOCTL)))
|
||||
{
|
||||
CharReqHdr.r_unit = 0;
|
||||
CharReqHdr.r_command = nMode;
|
||||
execrh((request FAR *) & CharReqHdr, s->sft_dev);
|
||||
|
||||
if (CharReqHdr.r_status & S_ERROR)
|
||||
{
|
||||
CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13;
|
||||
return DE_DEVICE;
|
||||
}
|
||||
|
||||
if (r->AL == 0x07)
|
||||
{
|
||||
r->AL = CharReqHdr.r_status & S_BUSY ? 00 : 0xff;
|
||||
}
|
||||
else if (r->AL == 0x02 || r->AL == 0x03)
|
||||
{
|
||||
r->AX = CharReqHdr.r_count;
|
||||
}
|
||||
|
||||
else if (r->AL == 0x0c || r->AL == 0x10)
|
||||
{
|
||||
r->AX = CharReqHdr.r_status;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
default:
|
||||
return DE_INVLDFUNC;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
@ -91,7 +187,6 @@ COUNT DosDevIOctl(iregs FAR * r)
|
||||
case 0x0d:
|
||||
case 0x0e:
|
||||
case 0x0f:
|
||||
case 0x10:
|
||||
case 0x11:
|
||||
|
||||
/*
|
||||
@ -113,222 +208,125 @@ COUNT DosDevIOctl(iregs FAR * r)
|
||||
/* cdsp = &CDSp[CharReqHdr.r_unit]; */
|
||||
dpbp = CDSp[CharReqHdr.r_unit].cdsDpb;
|
||||
}
|
||||
break;
|
||||
|
||||
switch (r->AL)
|
||||
{
|
||||
case 0x04:
|
||||
nMode = C_IOCTLIN;
|
||||
goto IoBlockCommon;
|
||||
case 0x05:
|
||||
nMode = C_IOCTLOUT;
|
||||
goto IoBlockCommon;
|
||||
case 0x08:
|
||||
if (!dpbp)
|
||||
{
|
||||
return DE_INVLDDRV;
|
||||
}
|
||||
if (dpbp->dpb_device->dh_attr & ATTR_EXCALLS)
|
||||
{
|
||||
nMode = C_REMMEDIA;
|
||||
goto IoBlockCommon;
|
||||
}
|
||||
return DE_INVLDFUNC;
|
||||
case 0x09:
|
||||
if (CDSp[CharReqHdr.r_unit].cdsFlags & CDSNETWDRV)
|
||||
{
|
||||
r->DX = ATTR_REMOTE;
|
||||
r->AX = S_DONE | S_BUSY;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!dpbp)
|
||||
{
|
||||
return DE_INVLDDRV;
|
||||
}
|
||||
/* Need to add subst bit 15 */
|
||||
r->DX = dpbp->dpb_device->dh_attr;
|
||||
r->AX = S_DONE | S_BUSY;
|
||||
}
|
||||
break;
|
||||
case 0x0d:
|
||||
nMode = C_GENIOCTL;
|
||||
goto IoBlockCommon;
|
||||
case 0x11:
|
||||
nMode = C_IOCTLQRY;
|
||||
IoBlockCommon:
|
||||
if (!dpbp)
|
||||
{
|
||||
return DE_INVLDDRV;
|
||||
}
|
||||
if (((r->AL == 0x04) && !(dpbp->dpb_device->dh_attr & ATTR_IOCTL))
|
||||
|| ((r->AL == 0x05) && !(dpbp->dpb_device->dh_attr & ATTR_IOCTL))
|
||||
|| ((r->AL == 0x11)
|
||||
&& !(dpbp->dpb_device->dh_attr & ATTR_QRYIOCTL))
|
||||
|| ((r->AL == 0x0d)
|
||||
&& !(dpbp->dpb_device->dh_attr & ATTR_GENIOCTL)))
|
||||
{
|
||||
return DE_INVLDFUNC;
|
||||
}
|
||||
|
||||
CharReqHdr.r_command = nMode;
|
||||
execrh((request FAR *) & CharReqHdr, dpbp->dpb_device);
|
||||
|
||||
if (CharReqHdr.r_status & S_ERROR)
|
||||
{
|
||||
CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13;
|
||||
return DE_DEVICE;
|
||||
}
|
||||
if (r->AL == 0x08)
|
||||
{
|
||||
r->AX = (CharReqHdr.r_status & S_BUSY) ? 1 : 0;
|
||||
}
|
||||
|
||||
else if (r->AL == 0x04 || r->AL == 0x05)
|
||||
{
|
||||
r->AX = CharReqHdr.r_count;
|
||||
}
|
||||
else if (r->AL == 0x0d || r->AL == 0x11)
|
||||
{
|
||||
r->AX = CharReqHdr.r_status;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0e:
|
||||
nMode = C_GETLDEV;
|
||||
goto IoLogCommon;
|
||||
case 0x0f:
|
||||
nMode = C_SETLDEV;
|
||||
IoLogCommon:
|
||||
if (!dpbp)
|
||||
{
|
||||
return DE_INVLDDRV;
|
||||
}
|
||||
if ((dpbp->dpb_device->dh_attr & ATTR_GENIOCTL))
|
||||
{
|
||||
|
||||
CharReqHdr.r_command = nMode;
|
||||
execrh((request FAR *) & CharReqHdr, dpbp->dpb_device);
|
||||
|
||||
if (CharReqHdr.r_status & S_ERROR)
|
||||
{
|
||||
CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13;
|
||||
return DE_ACCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
r->AL = CharReqHdr.r_unit;
|
||||
return SUCCESS;
|
||||
}
|
||||
} /* fall through */
|
||||
default:
|
||||
return DE_INVLDFUNC;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0b:
|
||||
/* skip, it's a special case. */
|
||||
|
||||
NetDelay = r->CX;
|
||||
if (!r->DX)
|
||||
NetRetry = r->DX;
|
||||
break;
|
||||
|
||||
default:
|
||||
return DE_INVLDFUNC;
|
||||
}
|
||||
|
||||
switch (r->AL)
|
||||
{
|
||||
case 0x00:
|
||||
/* Get the flags from the SFT */
|
||||
if (s->sft_flags & SFT_FDEVICE)
|
||||
r->AX = (s->sft_dev->dh_attr & 0xff00) | s->sft_flags_lo;
|
||||
else
|
||||
r->AX = s->sft_flags;
|
||||
/* Undocumented result, Ax = Dx seen using Pcwatch */
|
||||
r->DX = r->AX;
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
/* sft_flags is a file, return an error because you */
|
||||
/* can't set the status of a file. */
|
||||
if (!(s->sft_flags & SFT_FDEVICE))
|
||||
return DE_INVLDFUNC;
|
||||
|
||||
/* Set it to what we got in the DL register from the */
|
||||
/* user. */
|
||||
r->AL = s->sft_flags_lo = SFT_FDEVICE | r->DL;
|
||||
break;
|
||||
|
||||
case 0x0c:
|
||||
nMode = C_GENIOCTL;
|
||||
goto IoCharCommon;
|
||||
case 0x02:
|
||||
nMode = C_IOCTLIN;
|
||||
goto IoCharCommon;
|
||||
case 0x10:
|
||||
nMode = C_IOCTLQRY;
|
||||
goto IoCharCommon;
|
||||
case 0x03:
|
||||
nMode = C_IOCTLOUT;
|
||||
IoCharCommon:
|
||||
if ((s->sft_flags & SFT_FDEVICE)
|
||||
|| ((r->AL == 0x02) && (s->sft_dev->dh_attr & SFT_FIOCTL))
|
||||
|| ((r->AL == 0x03) && (s->sft_dev->dh_attr & SFT_FIOCTL))
|
||||
|| ((r->AL == 0x10) && (s->sft_dev->dh_attr & ATTR_QRYIOCTL))
|
||||
|| ((r->AL == 0x0c) && (s->sft_dev->dh_attr & ATTR_GENIOCTL)))
|
||||
{
|
||||
CharReqHdr.r_unit = 0;
|
||||
CharReqHdr.r_command = nMode;
|
||||
execrh((request FAR *) & CharReqHdr, s->sft_dev);
|
||||
|
||||
if (CharReqHdr.r_status & S_ERROR)
|
||||
{
|
||||
CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13;
|
||||
return DE_DEVICE;
|
||||
}
|
||||
|
||||
if (r->AL == 0x07)
|
||||
{
|
||||
r->AL = CharReqHdr.r_status & S_BUSY ? 00 : 0xff;
|
||||
|
||||
}
|
||||
else if (r->AL == 0x02 || r->AL == 0x03)
|
||||
{
|
||||
r->AX = CharReqHdr.r_count;
|
||||
}
|
||||
|
||||
else if (r->AL == 0x0c || r->AL == 0x10)
|
||||
{
|
||||
r->AX = CharReqHdr.r_status;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return DE_INVLDFUNC;
|
||||
|
||||
case 0x0d:
|
||||
nMode = C_GENIOCTL;
|
||||
goto IoBlockCommon;
|
||||
case 0x04:
|
||||
nMode = C_IOCTLIN;
|
||||
goto IoBlockCommon;
|
||||
case 0x11:
|
||||
nMode = C_IOCTLQRY;
|
||||
goto IoBlockCommon;
|
||||
case 0x05:
|
||||
nMode = C_IOCTLOUT;
|
||||
IoBlockCommon:
|
||||
if (!dpbp)
|
||||
{
|
||||
return DE_INVLDDRV;
|
||||
}
|
||||
if (((r->AL == 0x04) && !(dpbp->dpb_device->dh_attr & ATTR_IOCTL))
|
||||
|| ((r->AL == 0x05) && !(dpbp->dpb_device->dh_attr & ATTR_IOCTL))
|
||||
|| ((r->AL == 0x11)
|
||||
&& !(dpbp->dpb_device->dh_attr & ATTR_QRYIOCTL))
|
||||
|| ((r->AL == 0x0d)
|
||||
&& !(dpbp->dpb_device->dh_attr & ATTR_GENIOCTL)))
|
||||
{
|
||||
return DE_INVLDFUNC;
|
||||
}
|
||||
|
||||
CharReqHdr.r_command = nMode;
|
||||
execrh((request FAR *) & CharReqHdr, dpbp->dpb_device);
|
||||
|
||||
if (CharReqHdr.r_status & S_ERROR)
|
||||
{
|
||||
CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13;
|
||||
return DE_DEVICE;
|
||||
}
|
||||
if (r->AL == 0x08)
|
||||
{
|
||||
r->AX = (CharReqHdr.r_status & S_BUSY) ? 1 : 0;
|
||||
|
||||
}
|
||||
|
||||
else if (r->AL == 0x04 || r->AL == 0x05)
|
||||
{
|
||||
r->AX = CharReqHdr.r_count;
|
||||
|
||||
}
|
||||
else if (r->AL == 0x0d || r->AL == 0x11)
|
||||
{
|
||||
r->AX = CharReqHdr.r_status;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x06:
|
||||
if (s->sft_flags & SFT_FDEVICE)
|
||||
{
|
||||
r->AL = s->sft_flags & SFT_FEOF ? 0xFF : 0;
|
||||
}
|
||||
else
|
||||
r->AL = s->sft_posit >= s->sft_size ? 0xFF : 0;
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
if (s->sft_flags & SFT_FDEVICE)
|
||||
{
|
||||
nMode = C_OSTAT;
|
||||
goto IoCharCommon;
|
||||
}
|
||||
r->AL = 0;
|
||||
break;
|
||||
|
||||
case 0x08:
|
||||
if (!dpbp)
|
||||
{
|
||||
return DE_INVLDDRV;
|
||||
}
|
||||
if (dpbp->dpb_device->dh_attr & ATTR_EXCALLS)
|
||||
{
|
||||
nMode = C_REMMEDIA;
|
||||
goto IoBlockCommon;
|
||||
}
|
||||
return DE_INVLDFUNC;
|
||||
|
||||
case 0x09:
|
||||
if (CDSp[CharReqHdr.r_unit].cdsFlags & CDSNETWDRV)
|
||||
{
|
||||
r->DX = ATTR_REMOTE;
|
||||
r->AX = S_DONE | S_BUSY;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!dpbp)
|
||||
{
|
||||
return DE_INVLDDRV;
|
||||
}
|
||||
/* Need to add subst bit 15 */
|
||||
r->DX = dpbp->dpb_device->dh_attr;
|
||||
r->AX = S_DONE | S_BUSY;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0a:
|
||||
r->DX = s->sft_flags;
|
||||
r->AX = 0;
|
||||
break;
|
||||
|
||||
case 0x0e:
|
||||
nMode = C_GETLDEV;
|
||||
goto IoLogCommon;
|
||||
case 0x0f:
|
||||
nMode = C_SETLDEV;
|
||||
IoLogCommon:
|
||||
if (!dpbp)
|
||||
{
|
||||
return DE_INVLDDRV;
|
||||
}
|
||||
if ((dpbp->dpb_device->dh_attr & ATTR_GENIOCTL))
|
||||
{
|
||||
|
||||
CharReqHdr.r_command = nMode;
|
||||
execrh((request FAR *) & CharReqHdr, dpbp->dpb_device);
|
||||
|
||||
if (CharReqHdr.r_status & S_ERROR)
|
||||
{
|
||||
CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13;
|
||||
return DE_ACCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
r->AL = CharReqHdr.r_unit;
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
return DE_INVLDFUNC;
|
||||
|
||||
|
||||
default:
|
||||
return DE_INVLDFUNC;
|
||||
}
|
||||
|
@ -457,7 +457,6 @@ STATIC void kernel()
|
||||
fmemcpy(p, insertString, 3);
|
||||
|
||||
Cmd.ctCount += 3;
|
||||
printf("%d %s\n", Cmd.ctCount, Cmd.ctBuffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -74,13 +74,13 @@ int DosMkTmp(BYTE FAR * pathname, UWORD attr)
|
||||
{
|
||||
/* create filename from current date and time */
|
||||
char FAR *ptmp = pathname;
|
||||
BYTE wd, month, day;
|
||||
BYTE h, m, s, hund;
|
||||
WORD sh;
|
||||
WORD year;
|
||||
UBYTE wd, month, day;
|
||||
UBYTE h, m, s, hund;
|
||||
UWORD sh;
|
||||
UWORD year;
|
||||
int rc;
|
||||
char name83[13];
|
||||
int loop;
|
||||
int loop = 0;
|
||||
|
||||
while (*ptmp)
|
||||
ptmp++;
|
||||
@ -88,52 +88,153 @@ int DosMkTmp(BYTE FAR * pathname, UWORD attr)
|
||||
if (ptmp == pathname || (ptmp[-1] != '\\' && ptmp[-1] != '/'))
|
||||
*ptmp++ = '\\';
|
||||
|
||||
DosGetDate(&wd, &month, &day, (COUNT FAR *) & year);
|
||||
DosGetDate(&wd, &month, &day, &year);
|
||||
DosGetTime(&h, &m, &s, &hund);
|
||||
|
||||
sh = s * 100 + hund;
|
||||
|
||||
for (loop = 0; loop < 0xfff; loop++)
|
||||
{
|
||||
do {
|
||||
sprintf(name83, "%x%x%x%x%x%03x.%03x",
|
||||
year & 0xf, month & 0xf, day & 0xf, h & 0xf, m & 0xf,
|
||||
sh & 0xfff, loop & 0xfff);
|
||||
|
||||
fmemcpy(ptmp, name83, 13);
|
||||
|
||||
if ((rc = DosOpen(pathname, 0)) < 0 && rc != DE_ACCESS /* subdirectory ?? */
|
||||
/* todo: sharing collision on
|
||||
network drive
|
||||
*/
|
||||
)
|
||||
break;
|
||||
/* only create new file -- 2001/09/22 ska*/
|
||||
rc = (short)DosOpen(pathname, O_LEGACY | O_CREAT | O_RDWR, attr);
|
||||
} while (rc == DE_FILEEXISTS && loop++ < 0xfff);
|
||||
|
||||
if (rc >= 0)
|
||||
DosClose(rc);
|
||||
}
|
||||
|
||||
if (rc == DE_FILENOTFND)
|
||||
{
|
||||
rc = DosCreat(pathname, attr);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
COUNT get_verify_drive(char FAR * src)
|
||||
#ifdef DEBUG
|
||||
#define DEBUG_TRUENAME
|
||||
#endif
|
||||
|
||||
#define drLetterToNr(dr) ((dr) - 'A')
|
||||
/* Convert an uppercased drive letter into the drive index */
|
||||
#define drNrToLetter(dr) ((dr) + 'A')
|
||||
/* the other direction */
|
||||
|
||||
/* In DOS there are no free-standing UNC paths, therefore there
|
||||
is always a logical drive letter associated with a path
|
||||
spec. This letter is also the index into the CDS */
|
||||
|
||||
COUNT get_verify_drive(const char FAR * src)
|
||||
{
|
||||
UBYTE drive;
|
||||
unsigned flags;
|
||||
|
||||
/* Do we have a drive? */
|
||||
if (src[1] == ':')
|
||||
drive = ((src[0] - 1) | 0x20) - ('a' - 1);
|
||||
else
|
||||
return default_drive;
|
||||
if (drive < lastdrive && CDSp[drive].cdsFlags & CDSVALID)
|
||||
return drive;
|
||||
drive = drLetterToNr(DosUpFChar(src[0]));
|
||||
else
|
||||
drive = default_drive;
|
||||
|
||||
if (drive >= lastdrive)
|
||||
return DE_INVLDDRV;
|
||||
|
||||
/* Entry is disabled or JOINed drives are accessable by the path only */
|
||||
flags = CDSp[drive].cdsFlags;
|
||||
if ((flags & CDSMODEMASK) == 0 || (flags & CDSJOINED) != 0)
|
||||
return DE_INVLDDRV;
|
||||
|
||||
return drive;
|
||||
}
|
||||
|
||||
/*
|
||||
Definition of functions for the handling of the Current
|
||||
Directory Structure.
|
||||
|
||||
MUX-11-23: Qualify Remote Filename
|
||||
DOS-0x60 calls this MUX functions to let the Network Redirector
|
||||
qualify the filename. According INTRSPY MS DOS 6 does not pre-
|
||||
process the passed in filename in any way (see attached transcripts).
|
||||
|
||||
The DOS-60 interface TRUENAME looks like this:
|
||||
|
||||
DosTruename(src, dest) {
|
||||
if (MUX-11-23(src, dest) != Error)
|
||||
return SUCCESS
|
||||
return local_truename(src, dest);
|
||||
}
|
||||
|
||||
The CDS has the following entries:
|
||||
|
||||
char cdsPath[CDSPATHLEN];
|
||||
The fully-qualified current working directory of this drive.
|
||||
The format is DOS <dr>:\[<path>{\<path>}]
|
||||
or UNC \<id>\[<path>{\<path>}].
|
||||
The drive <dr> indicates the physical drive letter and is the
|
||||
index into the blk_device[].
|
||||
|
||||
UWORD cdsFlags;
|
||||
Indicates what kind this logical drive is:
|
||||
NETWORK: drive is NOT local \ If both are set, drive is IFS
|
||||
PHYSICAL: drive is local / If none is set, drive is non-existant
|
||||
JOIN: drive is joined in as the path cdsPath. This Flag uses the
|
||||
index into the CDS table to indicate the physical drive.
|
||||
SUBST: drive substitutes the path cdsPath.
|
||||
HIDDEN: drive is not included into the redirector's list.
|
||||
|
||||
struct dpb FAR *cdsDpb;
|
||||
Pointer to the DPB driving the physical drive. In DOS-C, the physical
|
||||
drive letter is the index into the DPB[]. But for compatibly reason
|
||||
this field will be set correctly.
|
||||
|
||||
UWORD cdsStartCluster;
|
||||
For local drives only: This holds the cluster number of
|
||||
the start of the current working directory of this
|
||||
logical drive. If 0000h, it's the root directory; if
|
||||
0ffffh, the drive was never accessed and has to be read
|
||||
again.
|
||||
|
||||
void FAR *cdsIFSrecord;
|
||||
UWORD cdsIFSparameter;
|
||||
For networked drives only: Holds pointer/parameters to/for IFS
|
||||
driver. (Well, I don't know.)
|
||||
|
||||
UWORD cdsPathOff;
|
||||
Number of characters of the cdsPath[], which are hidden. The
|
||||
logical path is combined by the logical drive letter and the
|
||||
cdsPath[] part, which is not hidden.
|
||||
|
||||
IFS FAR *cdsIFSdrv;
|
||||
Will be zeroed for local drives.
|
||||
|
||||
Revision 1.2 1995/12/03 22:17:41 ska
|
||||
bugfix: Scanning of file name in 8.3 failed on "." and on longer names.
|
||||
|
||||
Revision 1.1 1995/11/09 07:43:30 ska
|
||||
#
|
||||
|
||||
*/
|
||||
|
||||
#define PATH_ERROR goto errRet
|
||||
#define PATHLEN 128
|
||||
|
||||
|
||||
/* Map a logical path into a physical one.
|
||||
|
||||
1) Uppercasing path.
|
||||
2) Flipping '/' -> '\\'.
|
||||
3) Removing empty directory components & ".".
|
||||
4) Processing ".." components.
|
||||
5) Convert path components into 8.3 convention.
|
||||
6) Make it fully-qualified.
|
||||
7) Map it to SUBST/UNC.
|
||||
8) Map to JOIN.
|
||||
|
||||
Return:
|
||||
*cdsItem will be point to the appropriate CDS entry. This will allow
|
||||
the caller to aquire the DPB or the IFS informtion of this entry.
|
||||
error number
|
||||
Return value:
|
||||
DE_FILENOTFND, or DE_PATHNOTFND (as described in RBIL)
|
||||
If the output path pnfo->physPath exceeds the length MAX_PATH, the error
|
||||
DE_FILENOTFND will be returned.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Added support for external and internal calls.
|
||||
* Clean buffer before use. Make the true path and expand file names.
|
||||
@ -157,27 +258,127 @@ COUNT get_verify_drive(char FAR * src)
|
||||
|
||||
*/
|
||||
|
||||
COUNT truename(char FAR * src, char FAR * dest, COUNT t)
|
||||
#ifdef DEBUG_TRUENAME
|
||||
#define tn_printf(x) printf x
|
||||
#else
|
||||
#define tn_printf(x)
|
||||
#endif
|
||||
|
||||
#define PNE_WILDCARD 1
|
||||
#define PNE_DOT 2
|
||||
|
||||
#define addChar(c) \
|
||||
{ \
|
||||
if (p - dest >= SFTMAX) PATH_ERROR; /* path too long */ \
|
||||
*p++ = c; \
|
||||
}
|
||||
|
||||
/* helper for truename: parses either name or extension */
|
||||
STATIC int parse_name_ext(int i, const char FAR **src, char **cp, char *dest)
|
||||
{
|
||||
static char buf[128] = "A:\\\0\0\0\0\0\0\0\0\0";
|
||||
char *bufp = buf + 3;
|
||||
COUNT i, rootEndPos = 2; /* renamed x to rootEndPos - Ron Cemer */
|
||||
int retval = SUCCESS;
|
||||
char *p = *cp;
|
||||
char c;
|
||||
|
||||
while(1) switch(c=*(*src)++)
|
||||
{
|
||||
case '.':
|
||||
retval |= PNE_DOT;
|
||||
/* fall through */
|
||||
case '/':
|
||||
case '\\':
|
||||
case '\0':
|
||||
*cp = p;
|
||||
return retval;
|
||||
case '*':
|
||||
retval |= PNE_WILDCARD;
|
||||
/* register the wildcard, even if no '?' is appended */
|
||||
if (i) do
|
||||
{
|
||||
addChar('?');
|
||||
} while(--i);
|
||||
/** Alternative implementation:
|
||||
if (i)
|
||||
{
|
||||
if (dest + SFTMAX - *p < i)
|
||||
PATH_ERROR;
|
||||
fmemset(p, '?', i);
|
||||
p += i;
|
||||
} **/
|
||||
break;
|
||||
case '?':
|
||||
retval |= PNE_WILDCARD;
|
||||
/* fall through */
|
||||
default:
|
||||
if (i) { /* name length in limits */
|
||||
--i;
|
||||
addChar(c);
|
||||
}
|
||||
}
|
||||
|
||||
errRet:
|
||||
return -1;
|
||||
}
|
||||
|
||||
COUNT truename(const char FAR * src, char * dest, COUNT mode)
|
||||
{
|
||||
COUNT i;
|
||||
struct dhdr FAR *dhp;
|
||||
BYTE FAR *froot;
|
||||
WORD d;
|
||||
const char FAR *froot;
|
||||
COUNT result;
|
||||
int gotAnyWildcards = 0;
|
||||
struct cds FAR *cdsEntry;
|
||||
char *p = dest; /* dynamic pointer into dest */
|
||||
char *rootPos;
|
||||
enum { DONT_ADD, ADD, ADD_UNLESS_LAST } addSep;
|
||||
|
||||
dest[0] = '\0';
|
||||
|
||||
i = get_verify_drive(src);
|
||||
if (i < 0)
|
||||
return DE_INVLDDRV;
|
||||
|
||||
buf[0] = i + 'A';
|
||||
buf[1] = ':'; /* Just to be sure */
|
||||
tn_printf(("truename(%S)\n", src));
|
||||
|
||||
/* First, adjust the source pointer */
|
||||
src = adjust_far(src);
|
||||
|
||||
/* In opposite of the TRUENAME shell command, an empty string is
|
||||
rejected by MS DOS 6 */
|
||||
if (src[0] == '\0')
|
||||
return DE_FILENOTFND;
|
||||
|
||||
result = get_verify_drive(src);
|
||||
if (result < SUCCESS)
|
||||
return result;
|
||||
|
||||
cdsEntry = &CDSp[result];
|
||||
tn_printf(("CDS entry: #%u @%p (%u) '%S'\n", result, cdsEntry,
|
||||
cdsEntry->cdsBackslashOffset, cdsEntry->cdsCurrentPath));
|
||||
/* is the current_ldt thing necessary for compatibly??
|
||||
-- 2001/09/03 ska*/
|
||||
current_ldt = cdsEntry;
|
||||
if (cdsEntry->cdsFlags & CDSNETWDRV)
|
||||
result |= IS_NETWORK;
|
||||
|
||||
dhp = IsDevice(src);
|
||||
if (dhp)
|
||||
result |= IS_DEVICE;
|
||||
|
||||
/* Try if the Network redirector wants to do it */
|
||||
dest[0] = '\0'; /* better probable for sanity check below --
|
||||
included by original truename() */
|
||||
/* MUX succeeded and really something */
|
||||
if (QRemote_Fn(dest, src) && dest[0] != '\0')
|
||||
{
|
||||
tn_printf(("QRemoteFn() returned: \"%S\"\n", dest));
|
||||
#ifdef DEBUG_TRUENAME
|
||||
if (strlen(dest) >= SFTMAX)
|
||||
panic("Truename: QRemote_Fn() overflowed output buffer");
|
||||
#endif
|
||||
if (dest[2] == '/' && (result & IS_DEVICE))
|
||||
result &= ~IS_NETWORK;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Redirector interface failed --> proceed with local mapper */
|
||||
dest[0] = drNrToLetter(result & 0x1f);
|
||||
dest[1] = ':';
|
||||
|
||||
/* Do we have a drive? */
|
||||
if (src[1] == ':')
|
||||
src += 2;
|
||||
@ -188,344 +389,320 @@ COUNT truename(char FAR * src, char FAR * dest, COUNT t)
|
||||
*/
|
||||
/* check for a device */
|
||||
|
||||
if ((*src != '.') && (*src != '\\') && (*src != '/')
|
||||
&& ((dhp = IsDevice(src)) != NULL))
|
||||
dest[2] = '\\';
|
||||
if (result & IS_DEVICE)
|
||||
{
|
||||
|
||||
froot = get_root(src);
|
||||
|
||||
/* /// Bugfix: NUL.LST is the same as NUL. This is true for all
|
||||
devices. On a device name, the extension is irrelevant
|
||||
as long as the name matches.
|
||||
- Ron Cemer */
|
||||
|
||||
buf[2] = '/';
|
||||
/* /// Bug: should be only copying up to first space.
|
||||
- Ron Cemer */
|
||||
|
||||
for (d = 0;
|
||||
d < FNAME_SIZE && dhp->dh_name[d] != 0 && dhp->dh_name[d] != ' ';
|
||||
d++)
|
||||
*bufp++ = dhp->dh_name[d];
|
||||
/* /// DOS will return C:/NUL.LST if you pass NUL.LST in.
|
||||
DOS will also return C:/NUL.??? if you pass NUL.* in.
|
||||
Code added here to support this.
|
||||
- Ron Cemer */
|
||||
while ((*froot != '.') && (*froot != '\0'))
|
||||
froot++;
|
||||
if (*froot)
|
||||
froot++;
|
||||
if (*froot)
|
||||
if (froot == src || froot == src + 5)
|
||||
{
|
||||
*bufp++ = '.';
|
||||
for (i = 0; i < FEXT_SIZE; i++)
|
||||
if (froot == src + 5)
|
||||
{
|
||||
if ((*froot == '\0') || (*froot == '.'))
|
||||
break;
|
||||
if (*froot == '*')
|
||||
{
|
||||
for (; i < FEXT_SIZE; i++)
|
||||
*bufp++ = '?';
|
||||
break;
|
||||
}
|
||||
*bufp++ = *froot++;
|
||||
fmemcpy(dest + 3, src, 5);
|
||||
DosUpMem(dest + 3, 5);
|
||||
if (dest[3] == '/') dest[3] = '\\';
|
||||
if (dest[7] == '/') dest[7] = '\\';
|
||||
}
|
||||
if (froot == src || memcmp(dest + 3, "\\DEV\\", 5) == 0)
|
||||
{
|
||||
/* /// Bugfix: NUL.LST is the same as NUL. This is true for all
|
||||
devices. On a device name, the extension is irrelevant
|
||||
as long as the name matches.
|
||||
- Ron Cemer */
|
||||
dest[2] = '/';
|
||||
result &= ~IS_NETWORK;
|
||||
/* /// DOS will return C:/NUL.LST if you pass NUL.LST in.
|
||||
DOS will also return C:/NUL.??? if you pass NUL.* in.
|
||||
Code added here to support this.
|
||||
- Ron Cemer */
|
||||
src = froot;
|
||||
}
|
||||
}
|
||||
/* /// End of code additions. - Ron Cemer */
|
||||
goto exit_tn;
|
||||
}
|
||||
|
||||
/* /// Added to adjust for filenames which begin with ".\"
|
||||
* The problem was manifesting itself in the inability
|
||||
* to run an program whose filename (without the extension)
|
||||
* was longer than six characters and the PATH variable
|
||||
* contained ".", unless you explicitly specified the full
|
||||
* path to the executable file.
|
||||
* Jun 11, 2000 - rbc */
|
||||
/* /// Changed to "while" from "if". - Ron Cemer */
|
||||
while ((src[0] == '.') && (src[1] == '\\'))
|
||||
src += 2;
|
||||
|
||||
current_ldt = &CDSp[i];
|
||||
|
||||
/* Always give the redirector a chance to rewrite the filename */
|
||||
fmemcpy(bufp - 1, src, sizeof(buf) - (bufp - buf));
|
||||
if ((t == FALSE) && (QRemote_Fn(buf, dest) == SUCCESS)
|
||||
&& (dest[0] != '\0'))
|
||||
|
||||
/* Make fully-qualified logical path */
|
||||
/* register these two used characters and the \0 terminator byte */
|
||||
/* we always append the current dir to stat the drive;
|
||||
the only exceptions are devices without paths */
|
||||
rootPos = p = dest + 2;
|
||||
if (*p != '/') /* i.e., it's a backslash! */
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
bufp[-1] = '\\';
|
||||
}
|
||||
if (t == FALSE)
|
||||
{
|
||||
fmemcpy(buf, current_ldt->cdsCurrentPath, current_ldt->cdsJoinOffset);
|
||||
bufp = buf + current_ldt->cdsJoinOffset;
|
||||
rootEndPos = current_ldt->cdsJoinOffset; /* renamed x to rootEndPos - Ron Cemer */
|
||||
*bufp++ = '\\';
|
||||
}
|
||||
|
||||
if (*src != '\\' && *src != '/') /* append current dir */
|
||||
{
|
||||
DosGetCuDir((UBYTE) (i + 1), bufp);
|
||||
if (*bufp)
|
||||
if (!(mode & CDS_MODE_SKIP_PHYSICAL))
|
||||
{
|
||||
while (*bufp)
|
||||
bufp++;
|
||||
*bufp++ = '\\';
|
||||
}
|
||||
}
|
||||
else
|
||||
src++;
|
||||
tn_printf(("SUBSTing from: %S\n", cdsEntry->cdsCurrentPath));
|
||||
/* What to do now: the logical drive letter will be replaced by the hidden
|
||||
portion of the associated path. This is necessary for NETWORK and
|
||||
SUBST drives. For local drives it should not harm.
|
||||
This is actually the reverse mechanism of JOINED drives. */
|
||||
|
||||
/*move_name:*/
|
||||
|
||||
/* /// The block inside the "#if (0) ... #endif" is
|
||||
seriously broken. New code added below to replace it.
|
||||
This eliminates many serious bugs, specifically
|
||||
with FreeCOM where truename is required to work
|
||||
according to the DOS specification in order for
|
||||
the COPY and other file-related commands to work
|
||||
properly.
|
||||
This should be a major improvement to all apps which
|
||||
use truename.
|
||||
- Ron Cemer */
|
||||
|
||||
#if (0)
|
||||
/*
|
||||
* The code here is brain dead. It works long as the calling
|
||||
* function are operating with in normal parms.
|
||||
* jt
|
||||
*/
|
||||
n = 9;
|
||||
/* convert all forward slashes to backslashes, and uppercase all characters */
|
||||
while (*src)
|
||||
{
|
||||
char c;
|
||||
c = *src++;
|
||||
if (!n)
|
||||
return DE_PATHNOTFND; /* do this for now */
|
||||
n--;
|
||||
switch (c)
|
||||
{
|
||||
case '*':
|
||||
if (*src == '.')
|
||||
{
|
||||
while (n--)
|
||||
*bufp++ = '?';
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (src[-2] == '.')
|
||||
{
|
||||
while (n--)
|
||||
*bufp++ = '?';
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (n--)
|
||||
*bufp++ = '?';
|
||||
break;
|
||||
}
|
||||
}
|
||||
case '/': /* convert to backslash */
|
||||
case '\\':
|
||||
|
||||
if (bufp[-1] != '\\')
|
||||
{
|
||||
*bufp++ = '\\';
|
||||
n = 9;
|
||||
}
|
||||
break;
|
||||
|
||||
/* look for '.' and '..' dir entries */
|
||||
case '.':
|
||||
if (bufp[-1] == '\\')
|
||||
{
|
||||
if (*src == '.' && (src[1] == '/' || src[1] == '\\' || !src[1]))
|
||||
{
|
||||
/* '..' dir entry: rewind bufp to last backslash */
|
||||
|
||||
for (bufp -= 2; *bufp != '\\'; bufp--)
|
||||
{
|
||||
if (bufp < buf + rootEndPos) /* '..' illegal in root dir */
|
||||
return DE_PATHNOTFND;
|
||||
}
|
||||
src++;
|
||||
if (bufp[-1] == ':')
|
||||
bufp++;
|
||||
}
|
||||
else if (*src == '/' || *src == '\\' || *src == 0)
|
||||
break;
|
||||
/* --bufp; */
|
||||
else
|
||||
return DE_PATHNOTFND;
|
||||
}
|
||||
else if (*src == '/' || *src == '\\' || *src == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
n = 4;
|
||||
*bufp++ = c;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
*bufp++ = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* remove trailing backslashes */
|
||||
while (bufp[-1] == '\\')
|
||||
--bufp;
|
||||
#endif
|
||||
|
||||
/* /// Beginning of new code. - Ron Cemer */
|
||||
bufp--;
|
||||
{
|
||||
char c, *bufend = buf + (sizeof(buf) - 1);
|
||||
int gotAnyWildcards = 0;
|
||||
int seglen, copylen, state;
|
||||
int error = DE_PATHNOTFND;
|
||||
while ((*src) && (bufp < bufend))
|
||||
{
|
||||
/* Skip duplicated slashes. */
|
||||
while ((*src == '/') || (*src == '\\'))
|
||||
src++;
|
||||
if (!(*src))
|
||||
break;
|
||||
/* Find the end of this segment in the source string. */
|
||||
for (seglen = 0;; seglen++)
|
||||
fmemcpy(dest, cdsEntry->cdsCurrentPath, cdsEntry->cdsBackslashOffset);
|
||||
if (cdsEntry->cdsFlags & CDSSUBST)
|
||||
{
|
||||
c = src[seglen];
|
||||
if (c == '\0')
|
||||
{
|
||||
error = DE_FILENOTFND;
|
||||
break;
|
||||
/* The drive had been changed --> update the CDS pointer */
|
||||
if (dest[1] == ':')
|
||||
{ /* sanity check if this really is a local drive still */
|
||||
unsigned i = drLetterToNr(dest[0]);
|
||||
|
||||
if (i < lastdrive) /* sanity check #2 */
|
||||
result = (result & 0xffe0) | i;
|
||||
}
|
||||
else if ((c == '/') || (c == '\\'))
|
||||
break;
|
||||
}
|
||||
if (seglen > 0)
|
||||
{
|
||||
/* Ignore all ".\" or "\." path segments. */
|
||||
if ((seglen != 1) || (*src != '.'))
|
||||
{
|
||||
/* Apply ".." to the path by removing
|
||||
last path segment from buf. */
|
||||
if ((seglen == 2) && (src[0] == '.') && (src[1] == '.'))
|
||||
{
|
||||
if (bufp > (buf + rootEndPos))
|
||||
{
|
||||
bufp--;
|
||||
while ((bufp > (buf + rootEndPos))
|
||||
&& (*bufp != '/') && (*bufp != '\\'))
|
||||
bufp--;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* .. in root dir illegal */
|
||||
return error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* New segment. If any wildcards in previous
|
||||
segment(s), this is an invalid path. */
|
||||
if (gotAnyWildcards || src[0] == '.')
|
||||
return error;
|
||||
/* Append current path segment to result. */
|
||||
*(bufp++) = '\\';
|
||||
if (bufp >= bufend)
|
||||
break;
|
||||
copylen = state = 0;
|
||||
for (i = 0; ((i < seglen) && (bufp < bufend)); i++)
|
||||
{
|
||||
c = src[i];
|
||||
gotAnyWildcards |= ((c == '?') || (c == '*'));
|
||||
switch (state)
|
||||
{
|
||||
case 0: /* Copying filename (excl. extension) */
|
||||
if (c == '*')
|
||||
{
|
||||
while (copylen < FNAME_SIZE)
|
||||
{
|
||||
*(bufp++) = '?';
|
||||
if (bufp >= bufend)
|
||||
break;
|
||||
copylen++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (c == '.')
|
||||
{
|
||||
if (src[i + 1] != '.' && i + 1 < seglen)
|
||||
*(bufp++) = '.';
|
||||
copylen = 0;
|
||||
state = 1; /* Copy extension next */
|
||||
break;
|
||||
}
|
||||
if (copylen < FNAME_SIZE)
|
||||
{
|
||||
*(bufp++) = c;
|
||||
copylen++;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 1: /* Copying extension */
|
||||
if (c == '*')
|
||||
{
|
||||
while (copylen < FEXT_SIZE)
|
||||
{
|
||||
*(bufp++) = '?';
|
||||
if (bufp >= bufend)
|
||||
break;
|
||||
copylen++;
|
||||
}
|
||||
}
|
||||
if (c == '.')
|
||||
return error;
|
||||
if (copylen < FEXT_SIZE)
|
||||
{
|
||||
*(bufp++) = c;
|
||||
copylen++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* if (seglen > 0) */
|
||||
src += seglen;
|
||||
if (*src)
|
||||
src++;
|
||||
} /* while ( (*src) && (bufp < bufend) ) */
|
||||
rootPos = p = dest + current_ldt->cdsBackslashOffset;
|
||||
*p = '\\'; /* force backslash! */
|
||||
}
|
||||
p++;
|
||||
DosGetCuDir((result & 0x1f) + 1, p);
|
||||
if (*src != '\\' && *src != '/')
|
||||
p += strlen(p);
|
||||
else /* skip the absolute path marker */
|
||||
src++;
|
||||
/* remove trailing separator */
|
||||
if (p[-1] == '\\') p--;
|
||||
}
|
||||
/* /// End of new code. - Ron Cemer */
|
||||
|
||||
if (bufp == buf + 2)
|
||||
++bufp;
|
||||
/* append the path specified in src */
|
||||
addSep = ADD; /* add separator */
|
||||
|
||||
exit_tn:
|
||||
while(*src)
|
||||
{
|
||||
/* New segment. If any wildcards in previous
|
||||
segment(s), this is an invalid path. */
|
||||
if (gotAnyWildcards)
|
||||
return DE_PATHNOTFND;
|
||||
switch(*src++)
|
||||
{
|
||||
case '/':
|
||||
case '\\': /* skip multiple separators (duplicated slashes) */
|
||||
addSep = ADD;
|
||||
break;
|
||||
case '.': /* special directory component */
|
||||
switch(*src)
|
||||
{
|
||||
case '/':
|
||||
case '\\':
|
||||
case '\0':
|
||||
/* current path -> ignore */
|
||||
addSep = ADD_UNLESS_LAST;
|
||||
/* If (/ or \) && no ++src
|
||||
--> addSep = ADD next turn */
|
||||
continue; /* next char */
|
||||
case '.': /* maybe ".." entry */
|
||||
switch(src[1])
|
||||
{
|
||||
case '/':
|
||||
case '\\':
|
||||
case '\0':
|
||||
/* remove last path component */
|
||||
while(*--p != '\\')
|
||||
if (p <= rootPos) /* already on root */
|
||||
return DE_PATHNOTFND;
|
||||
/* the separator was removed -> add it again */
|
||||
++src; /* skip the second dot */
|
||||
/* If / or \, next turn will find them and
|
||||
assign addSep = ADD */
|
||||
addSep = ADD_UNLESS_LAST;
|
||||
continue; /* next char */
|
||||
}
|
||||
}
|
||||
|
||||
/* ill-formed .* or ..* entries => return error */
|
||||
errRet:
|
||||
/* The error is either PATHNOTFND or FILENOTFND
|
||||
depending on if it is not the last component */
|
||||
return fstrchr(src, '/') == 0 && fstrchr(src, '\\') == 0
|
||||
? DE_FILENOTFND
|
||||
: DE_PATHNOTFND;
|
||||
default: /* normal component */
|
||||
if (addSep != DONT_ADD)
|
||||
{ /* append backslash */
|
||||
addChar(*rootPos);
|
||||
addSep = DONT_ADD;
|
||||
}
|
||||
|
||||
/* append component in 8.3 convention */
|
||||
--src;
|
||||
/* first character skipped in switch() */
|
||||
i = parse_name_ext(FNAME_SIZE, &src, &p, dest);
|
||||
if (i == -1)
|
||||
PATH_ERROR;
|
||||
if (i & PNE_WILDCARD)
|
||||
gotAnyWildcards = TRUE;
|
||||
/* strip trailing dot */
|
||||
if ((i & PNE_DOT) && *src != '/' && *src != '\\' && *src != '\0')
|
||||
{
|
||||
/* we arrive here only when an extension-dot has been found */
|
||||
addChar('.');
|
||||
i = parse_name_ext(FEXT_SIZE, &src, &p, dest);
|
||||
if (i == -1 || i & PNE_DOT) /* multiple dots are ill-formed */
|
||||
PATH_ERROR;
|
||||
if (i & PNE_WILDCARD)
|
||||
gotAnyWildcards = TRUE;
|
||||
}
|
||||
--src; /* terminator or separator was skipped */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (addSep == ADD)
|
||||
{
|
||||
/* MS DOS preserves a trailing '\\', so an access to "C:\\DOS\\"
|
||||
or "CDS.C\\" fails. */
|
||||
/* But don't add the separator, if the last component was ".." */
|
||||
addChar('\\');
|
||||
}
|
||||
|
||||
*p = '\0'; /* add the string terminator */
|
||||
DosUpFString(rootPos); /* upcase the file/path name */
|
||||
|
||||
/** Note:
|
||||
Only the portions passed in by the user are upcased, because it is
|
||||
assumed that the CDS is configured correctly and if it contains
|
||||
lower case letters, it is required so **/
|
||||
|
||||
tn_printf(("Absolute logical path: \"%s\"\n", dest));
|
||||
|
||||
/* Now, all the steps 1) .. 7) are fullfilled. Join now */
|
||||
/* search, if this path is a joined drive */
|
||||
|
||||
*bufp++ = 0;
|
||||
|
||||
/* finally, uppercase everything */
|
||||
DosUpString(buf);
|
||||
|
||||
/* copy to user's buffer */
|
||||
fmemcpy(dest, buf, bufp - buf);
|
||||
|
||||
return SUCCESS;
|
||||
if (dest[2] != '/' && (!(mode & CDS_MODE_SKIP_PHYSICAL)) && njoined)
|
||||
{
|
||||
for(i = 0; i < lastdrive; ++i)
|
||||
{
|
||||
/* How many bytes must match */
|
||||
size_t j = fstrlen(CDSp[i].cdsCurrentPath);
|
||||
/* the last component must end before the backslash offset and */
|
||||
/* the path the drive is joined to leads the logical path */
|
||||
if ((CDSp[i].cdsFlags & CDSJOINED) && (dest[j] == '\\' || dest[j] == '\0')
|
||||
&& fmemcmp(dest, CDSp[i].cdsCurrentPath, j) == 0)
|
||||
{ /* JOINed drive found */
|
||||
dest[0] = drNrToLetter(i); /* index is physical here */
|
||||
dest[1] = ':';
|
||||
if (dest[j] == '\0')
|
||||
{ /* Reduce to root direc */
|
||||
dest[2] = '\\';
|
||||
dest[3] = 0;
|
||||
/* move the relative path right behind the drive letter */
|
||||
}
|
||||
else if (j != 2)
|
||||
{
|
||||
strcpy(dest + 2, dest + j);
|
||||
}
|
||||
result = (result & 0xffe0) | i;
|
||||
current_ldt = &CDSp[i];
|
||||
result &= ~IS_NETWORK;
|
||||
if (current_ldt->cdsFlags & CDSNETWDRV)
|
||||
result |= IS_NETWORK;
|
||||
tn_printf(("JOINed path: \"%S\"\n", dest));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
/* nothing found => continue normally */
|
||||
}
|
||||
if ((mode & CDS_MODE_CHECK_DEV_PATH) && (result & IS_DEVICE) &&
|
||||
!(result & IS_NETWORK) && dest[2] != '/' && !dir_exists(dest))
|
||||
return DE_PATHNOTFND;
|
||||
|
||||
tn_printf(("Physical path: \"%s\"\n", dest));
|
||||
return result;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**********************************************
|
||||
Result of INTRSPY
|
||||
|
||||
Calling RBIL's INT.COM in MS DOS v6.22
|
||||
|
||||
=== Script: MUX.SCR
|
||||
|
||||
intercept 2fh
|
||||
function 11h ; network redirector
|
||||
subfunction 23h ; Qualify path and filename
|
||||
on_entry
|
||||
output "1123: IN: " (ds:SI->byte,asciiz,64)
|
||||
on_exit
|
||||
if (cflag == 1)
|
||||
sameline " [FAIL " ax "]"
|
||||
output "1123: OUT: " (es:dI->byte,asciiz,64)
|
||||
output "1123: orig buffer: " (ds:sI->byte,asciiz,64)
|
||||
function 12h
|
||||
subfunction 21h
|
||||
on_entry
|
||||
output "1221: IN: " (ds:SI->byte,asciiz,64)
|
||||
on_exit
|
||||
if (cflag == 1)
|
||||
sameline " [FAIL " ax "]"
|
||||
output "1221: OUT: " (es:dI->byte,asciiz,64)
|
||||
|
||||
=== Batch file: SPY_INT.BAT
|
||||
@echo off
|
||||
if exist report.out del report.out
|
||||
cmdspy stop
|
||||
cmdspy flush
|
||||
cmdspy restart
|
||||
int ax=0x6000 -buf ds:si="abcöflkgsxkf\0" -buf es:di="%256s" -int 0x21 -d es:di:128 >spy_int.out
|
||||
cmdspy stop
|
||||
cmdspy report report.out
|
||||
more report.out
|
||||
=== Intspy report file: REPORT.OUT
|
||||
1123: IN: C:\INTRSPY\SPY_INT.BAT [FAIL 0001]
|
||||
1123: OUT:
|
||||
1123: orig buffer: C:\INTRSPY\SPY_INT.BAT
|
||||
1123: IN: int.??? [FAIL 0001]
|
||||
1123: OUT: C:\INTRSPY
|
||||
1123: orig buffer: int.???
|
||||
1123: IN: C:\TOOL\int.??? [FAIL 0001]
|
||||
1123: OUT: C:\INTRSPY
|
||||
1123: orig buffer: C:\TOOL\int.???
|
||||
1123: IN: spy_int.out [FAIL 0001]
|
||||
1123: OUT: C:\TOOL\INT.???
|
||||
1123: orig buffer: spy_int.out
|
||||
1123: IN: C:\TOOL\INT.COM [FAIL 0001]
|
||||
1123: OUT: C:\INTRSPY\SPY_INT.OUT
|
||||
1123: orig buffer: C:\TOOL\INT.COM
|
||||
1123: IN: abcöflkgsxkf [FAIL 0001]
|
||||
1123: OUT: C:\TOOL\INT.COM
|
||||
1123: orig buffer: abcöflkgsxkf
|
||||
1123: IN: C:\INTRSPY\SPY_INT.BAT [FAIL 0001]
|
||||
1123: OUT: C:\INTRSPY\ABCÖFLKG
|
||||
1123: orig buffer: C:\INTRSPY\SPY_INT.BAT
|
||||
1123: IN: cmdspy.??? [FAIL 0001]
|
||||
1123: OUT: C:\INTRSPY
|
||||
1123: orig buffer: cmdspy.???
|
||||
1123: IN: C:\INTRSPY\CMDSPY.EXE [FAIL 0001]
|
||||
1123: OUT: C:\INTRSPY
|
||||
1123: orig buffer: C:\INTRSPY\CMDSPY.EXE
|
||||
=== INT.COM output: SPY_INT.OUT
|
||||
000 CX=0000 DX=0000
|
||||
SI=4A5E DI=4A76 BP=FF70 SP=FF64
|
||||
CS=0000 DS=279D ES=279D SS=0000 CPU Flags: 0n00oditsz0a0p1c
|
||||
|
||||
INT: 0x21
|
||||
|
||||
AX=0059 BX=0000 CX=0000 DX=0000
|
||||
SI=4A5E DI=4A76 BP=FF70 SP=FF64
|
||||
CS=0000 DS=279D ES=279D SS=0000 CPU Flags: 0N11odItSz0A0P1c
|
||||
DOSERR: 0000 (0)
|
||||
|
||||
*<es:di:128> {
|
||||
43(C) 3A(:) 5C(\) 49(I) 4E(N) 54(T) 52(R) 53(S) 50(P) 59(Y) 5C(\) 41(A)
|
||||
42(B) 43(C) 99(Ö) 46(F) 4C(L) 4B(K) 47(G) 00(.) 3D(=) 30(0) 30(0) 30(0)
|
||||
30(0) 20( ) 20( ) 20( ) 43(C) 58(X) 3D(=) 30(0) 30(0) 30(0) 30(0) 28(()
|
||||
30(0) 29()) 20( ) 32(2) 38(8) 28(() 28(() 29()) 20( ) 33(3) 30(0) 28(()
|
||||
30(0) 29()) 20( ) 32(2) 39(9) 28(() 29()) 29()) 20( ) 32(2) 30(0) 28(()
|
||||
20( ) 29()) 20( ) 33(3) 32(2) 28(() 32(2) 29()) 20( ) 33(3) 38(8) 28(()
|
||||
38(8) 29()) 20( ) 32(2) 38(8) 28(() 28(() 29()) 20( ) 32(2) 38(8) 28(()
|
||||
28(() 29()) 20( ) 32(2) 39(9) 28(() 29()) 29()) 20( ) 32(2) 30(0) 28(()
|
||||
20( ) 29()) 20( ) 33(3) 33(3) 28(() 33(3) 29()) 20( ) 33(3) 30(0) 28(()
|
||||
30(0) 29()) 20( ) 32(2) 38(8) 28(() 28(() 29()) 20( ) 33(3) 30(0) 28(()
|
||||
30(0) 29()) 20( ) 32(2) 39(9) 28(() 29()) 29()) }
|
||||
===
|
||||
|
||||
The actual interesting lines are the 6th "IN:" of the report file.
|
||||
The DOS interface passed _exactly_ the same string to MUX-11-23 as
|
||||
written on command line, the same applied to "con\0", a device driver.
|
||||
|
||||
***************************************/
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Log: newstuff.c,v - for newer entries see "cvs log newstuff.c"
|
||||
*
|
||||
|
@ -586,7 +586,7 @@ COUNT DosSetCountry(UWORD cntry)
|
||||
/*
|
||||
* Called for DOS-66-01 get CP
|
||||
*/
|
||||
COUNT DosGetCodepage(UWORD FAR * actCP, UWORD FAR * sysCP)
|
||||
COUNT DosGetCodepage(UWORD * actCP, UWORD * sysCP)
|
||||
{
|
||||
*sysCP = nlsInfo.sysCodePage;
|
||||
*actCP = nlsInfo.actPkg->cp;
|
||||
|
166
kernel/proto.h
166
kernel/proto.h
@ -50,6 +50,7 @@ UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks,
|
||||
/* *** End of change */
|
||||
|
||||
/* chario.c */
|
||||
UCOUNT BinaryCharIO(struct dhdr FAR * dev, UCOUNT n, void FAR * bp, unsigned command, COUNT *err);
|
||||
VOID sto(COUNT c);
|
||||
VOID cso(COUNT c);
|
||||
VOID mod_cso(REG UCOUNT c);
|
||||
@ -66,36 +67,33 @@ UCOUNT sti(keyboard * kp);
|
||||
sft FAR *get_sft(UCOUNT);
|
||||
|
||||
/* dosfns.c */
|
||||
BYTE FAR *get_root(BYTE FAR *);
|
||||
const char FAR *get_root(const char FAR *);
|
||||
BOOL check_break(void);
|
||||
UCOUNT GenericReadSft(sft far * sftp, UCOUNT n, BYTE FAR * bp,
|
||||
COUNT FAR * err, BOOL force_binary);
|
||||
UCOUNT GenericReadSft(sft far * sftp, UCOUNT n, void FAR * bp,
|
||||
COUNT * err, BOOL force_binary);
|
||||
COUNT SftSeek(sft FAR * sftp, LONG new_pos, COUNT mode);
|
||||
/*COUNT DosRead(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err); */
|
||||
#define GenericRead(hndl, n, bp, err, t) GenericReadSft(get_sft(hndl), n, bp, err, t)
|
||||
#define DosRead(hndl, n, bp, err) GenericRead(hndl, n, bp, err, FALSE)
|
||||
#define DosReadSft(sftp, n, bp, err) GenericReadSft(sftp, n, bp, err, FALSE)
|
||||
UCOUNT DosWriteSft(sft FAR * sftp, UCOUNT n, const BYTE FAR * bp,
|
||||
COUNT FAR * err);
|
||||
#define DosWrite(hndl, n, bp, err) DosWriteSft(get_sft(hndl), n, bp, err)
|
||||
COUNT DosSeek(COUNT hndl, LONG new_pos, COUNT mode, ULONG * set_pos);
|
||||
COUNT DosCreat(BYTE FAR * fname, COUNT attrib);
|
||||
COUNT DosCreatSft(BYTE * fname, COUNT attrib);
|
||||
COUNT CloneHandle(COUNT hndl);
|
||||
COUNT DosDup(COUNT Handle);
|
||||
COUNT DosForceDup(COUNT OldHandle, COUNT NewHandle);
|
||||
COUNT DosOpen(BYTE FAR * fname, COUNT mode);
|
||||
COUNT DosOpenSft(BYTE * fname, COUNT mode);
|
||||
UCOUNT BinaryReadSft(sft FAR * s, void *bp, COUNT *err);
|
||||
#define BinaryRead(hndl, bp, err) BinaryReadSft(get_sft(hndl), bp, err)
|
||||
UCOUNT DosRWSft(sft FAR * s, UCOUNT n, void FAR * bp, COUNT *err, int mode);
|
||||
#define DosRead(hndl, n, bp, err) DosRWSft(get_sft(hndl), n, bp, err, XFR_READ)
|
||||
#define DosWrite(hndl, n, bp, err) DosRWSft(get_sft(hndl), n, bp, err, XFR_WRITE)
|
||||
ULONG DosSeek(COUNT hndl, LONG new_pos, COUNT mode);
|
||||
long DosOpen(char FAR * fname, unsigned flags, unsigned attrib);
|
||||
COUNT CloneHandle(unsigned hndl);
|
||||
long DosDup(unsigned Handle);
|
||||
COUNT DosForceDup(unsigned OldHandle, unsigned NewHandle);
|
||||
long DosOpenSft(char FAR * fname, unsigned flags, unsigned attrib);
|
||||
COUNT DosClose(COUNT hndl);
|
||||
COUNT DosCloseSft(WORD sft_idx, BOOL commitonly);
|
||||
#define DosCommit(hndl) DosCloseSft(get_sft_idx(hndl), TRUE)
|
||||
BOOL DosGetFree(UBYTE drive, UCOUNT FAR * spc, UCOUNT FAR * navc,
|
||||
UCOUNT FAR * bps, UCOUNT FAR * nc);
|
||||
BOOL DosGetFree(UBYTE drive, UWORD * spc, UWORD * navc,
|
||||
UWORD * bps, UWORD * nc);
|
||||
COUNT DosGetCuDir(UBYTE drive, BYTE FAR * s);
|
||||
COUNT DosChangeDir(BYTE FAR * s);
|
||||
COUNT DosFindFirst(UCOUNT attr, BYTE FAR * name);
|
||||
COUNT DosFindNext(void);
|
||||
COUNT DosGetFtime(COUNT hndl, date FAR * dp, time FAR * tp);
|
||||
COUNT DosGetFtime(COUNT hndl, date * dp, time * tp);
|
||||
COUNT DosSetFtimeSft(WORD sft_idx, date dp, time tp);
|
||||
#define DosSetFtime(hndl, dp, tp) DosSetFtimeSft(get_sft_idx(hndl), (dp), (tp))
|
||||
COUNT DosGetFattr(BYTE FAR * name);
|
||||
@ -104,21 +102,20 @@ UBYTE DosSelectDrv(UBYTE drv);
|
||||
COUNT DosDelete(BYTE FAR * path, int attrib);
|
||||
COUNT DosRename(BYTE FAR * path1, BYTE FAR * path2);
|
||||
COUNT DosRenameTrue(BYTE * path1, BYTE * path2, int attrib);
|
||||
COUNT DosMkdir(BYTE FAR * dir);
|
||||
COUNT DosRmdir(BYTE FAR * dir);
|
||||
struct dhdr FAR *IsDevice(BYTE FAR * FileName);
|
||||
COUNT DosMkdir(const char FAR * dir);
|
||||
COUNT DosRmdir(const char FAR * dir);
|
||||
struct dhdr FAR *IsDevice(const char FAR * FileName);
|
||||
BOOL IsShareInstalled(void);
|
||||
COUNT DosLockUnlock(COUNT hndl, LONG pos, LONG len, COUNT unlock);
|
||||
sft FAR *idx_to_sft(COUNT SftIndex);
|
||||
COUNT get_sft_idx(UCOUNT hndl);
|
||||
COUNT DosTruename(const char FAR * src, char FAR * dest);
|
||||
|
||||
/*dosidle.asm */
|
||||
VOID ASMCFUNC DosIdle_int(void);
|
||||
|
||||
/* dosnames.c */
|
||||
VOID SpacePad(BYTE *, COUNT);
|
||||
COUNT ParseDosName(BYTE *, COUNT *, BYTE *, BYTE *, BYTE *, BOOL);
|
||||
/*COUNT ParseDosPath(BYTE *, COUNT *, BYTE *, BYTE FAR *); */
|
||||
int ParseDosName(const char *, char *, BOOL);
|
||||
|
||||
/* error.c */
|
||||
VOID dump(void);
|
||||
@ -127,7 +124,7 @@ VOID fatal(BYTE * err_msg);
|
||||
|
||||
/* fatdir.c */
|
||||
VOID dir_init_fnode(f_node_ptr fnp, CLUSTER dirstart);
|
||||
f_node_ptr dir_open(BYTE * dirname);
|
||||
f_node_ptr dir_open(const char *dirname);
|
||||
COUNT dir_read(REG f_node_ptr fnp);
|
||||
BOOL dir_write(REG f_node_ptr fnp);
|
||||
VOID dir_close(REG f_node_ptr fnp);
|
||||
@ -138,13 +135,12 @@ int FileName83Length(BYTE * filename83);
|
||||
|
||||
/* fatfs.c */
|
||||
ULONG clus2phys(CLUSTER cl_no, struct dpb FAR * dpbp);
|
||||
COUNT dos_open(BYTE * path, COUNT flag);
|
||||
BOOL fcmp(BYTE * s1, BYTE * s2, COUNT n);
|
||||
BOOL fcmp_wild(BYTE FAR * s1, BYTE FAR * s2, COUNT n);
|
||||
long dos_open(char * path, unsigned flag, unsigned attrib);
|
||||
BOOL fcbmatch(const char *fcbname1, const char *fcbname2);
|
||||
BOOL fcmp_wild(const char * s1, const char * s2, unsigned n);
|
||||
VOID touc(BYTE * s, COUNT n);
|
||||
COUNT dos_close(COUNT fd);
|
||||
COUNT dos_commit(COUNT fd);
|
||||
COUNT dos_creat(BYTE * path, int attrib);
|
||||
COUNT dos_delete(BYTE * path, int attrib);
|
||||
COUNT dos_rmdir(BYTE * path);
|
||||
COUNT dos_rename(BYTE * path1, BYTE * path2, int attrib);
|
||||
@ -152,8 +148,7 @@ date dos_getdate(void);
|
||||
time dos_gettime(void);
|
||||
COUNT dos_getftime(COUNT fd, date FAR * dp, time FAR * tp);
|
||||
COUNT dos_setftime(COUNT fd, date dp, time tp);
|
||||
LONG dos_getcufsize(COUNT fd);
|
||||
LONG dos_getfsize(COUNT fd);
|
||||
ULONG dos_getfsize(COUNT fd);
|
||||
BOOL dos_setfsize(COUNT fd, LONG size);
|
||||
COUNT dos_mkdir(BYTE * dir);
|
||||
BOOL last_link(f_node_ptr fnp);
|
||||
@ -163,6 +158,7 @@ COUNT dos_read(COUNT fd, VOID FAR * buffer, UCOUNT count);
|
||||
COUNT dos_write(COUNT fd, const VOID FAR * buffer, UCOUNT count);
|
||||
LONG dos_lseek(COUNT fd, LONG foffset, COUNT origin);
|
||||
CLUSTER dos_free(struct dpb FAR * dpbp);
|
||||
BOOL dir_exists(char * path);
|
||||
|
||||
VOID trim_path(BYTE FAR * s);
|
||||
|
||||
@ -171,6 +167,7 @@ COUNT dos_cd(struct cds FAR * cdsp, BYTE * PathName);
|
||||
f_node_ptr get_f_node(void);
|
||||
VOID release_f_node(f_node_ptr fnp);
|
||||
VOID dos_setdta(BYTE FAR * newdta);
|
||||
COUNT dos_getfattr_fd(COUNT fd);
|
||||
COUNT dos_getfattr(BYTE * name);
|
||||
COUNT dos_setfattr(BYTE * name, UWORD attrp);
|
||||
COUNT media_check(REG struct dpb FAR * dpbp);
|
||||
@ -192,43 +189,35 @@ int DosCharInput(VOID);
|
||||
VOID DosDirectConsoleIO(iregs FAR * r);
|
||||
VOID DosCharOutput(COUNT c);
|
||||
VOID DosDisplayOutput(COUNT c);
|
||||
VOID FatGetDrvData(UCOUNT drive, UCOUNT FAR * spc, UCOUNT FAR * bps,
|
||||
UCOUNT FAR * nc, BYTE FAR ** mdp);
|
||||
WORD FcbParseFname(int wTestMode, const BYTE FAR ** lpFileName, fcb FAR * lpFcb);
|
||||
BYTE FAR *FatGetDrvData(UBYTE drive, UWORD * spc, UWORD * bps,
|
||||
UWORD * nc);
|
||||
UWORD FcbParseFname(int *wTestMode, const BYTE FAR *lpFileName, fcb FAR * lpFcb);
|
||||
const BYTE FAR *ParseSkipWh(const BYTE FAR * lpFileName);
|
||||
BOOL TestCmnSeps(BYTE FAR * lpFileName);
|
||||
BOOL TestFieldSeps(BYTE FAR * lpFileName);
|
||||
const BYTE FAR *GetNameField(const BYTE FAR * lpFileName, BYTE FAR * lpDestField,
|
||||
COUNT nFieldSize, BOOL * pbWildCard);
|
||||
typedef BOOL FcbFunc_t (xfcb FAR *, COUNT *, UCOUNT);
|
||||
FcbFunc_t FcbRead, FcbWrite;
|
||||
BOOL FcbGetFileSize(xfcb FAR * lpXfcb);
|
||||
BOOL FcbSetRandom(xfcb FAR * lpXfcb);
|
||||
BOOL FcbCalcRec(xfcb FAR * lpXfcb);
|
||||
BOOL FcbRandomBlockRead(xfcb FAR * lpXfcb, COUNT nRecords,
|
||||
COUNT * nErrorCode);
|
||||
BOOL FcbRandomBlockWrite(xfcb FAR * lpXfcb, COUNT nRecords,
|
||||
COUNT * nErrorCode);
|
||||
BOOL FcbRandomIO(xfcb FAR * lpXfcb, COUNT * nErrorCode, FcbFunc_t *FcbFunc);
|
||||
BOOL FcbOpenCreate(xfcb FAR * lpXfcb, BOOL Create);
|
||||
#define FcbOpen(fcb) FcbOpenCreate(fcb, FALSE)
|
||||
#define FcbCreate(fcb) FcbOpenCreate(fcb, TRUE)
|
||||
void FcbNameInit(fcb FAR * lpFcb, BYTE * pszBuffer, COUNT * pCurDrive);
|
||||
BOOL FcbDelete(xfcb FAR * lpXfcb);
|
||||
BOOL FcbRename(xfcb FAR * lpXfcb);
|
||||
BOOL FcbClose(xfcb FAR * lpXfcb);
|
||||
VOID FcbCloseAll(VOID);
|
||||
BOOL FcbFindFirst(xfcb FAR * lpXfcb);
|
||||
BOOL FcbFindNext(xfcb FAR * lpXfcb);
|
||||
UBYTE FcbReadWrite(xfcb FAR *, UCOUNT, int);
|
||||
UBYTE FcbGetFileSize(xfcb FAR * lpXfcb);
|
||||
void FcbSetRandom(xfcb FAR * lpXfcb);
|
||||
UBYTE FcbRandomBlockIO(xfcb FAR * lpXfcb, COUNT nRecords, int mode);
|
||||
UBYTE FcbRandomIO(xfcb FAR * lpXfcb, int mode);
|
||||
UBYTE FcbOpen(xfcb FAR * lpXfcb, unsigned flags);
|
||||
int FcbNameInit(fcb FAR * lpFcb, BYTE * pszBuffer, COUNT * pCurDrive);
|
||||
UBYTE FcbDelete(xfcb FAR * lpXfcb);
|
||||
UBYTE FcbRename(xfcb FAR * lpXfcb);
|
||||
UBYTE FcbClose(xfcb FAR * lpXfcb);
|
||||
void FcbCloseAll(void);
|
||||
UBYTE FcbFindFirstNext(xfcb FAR * lpXfcb, BOOL First);
|
||||
|
||||
/* ioctl.c */
|
||||
COUNT DosDevIOctl(iregs FAR * r);
|
||||
COUNT DosDevIOctl(lregs * r);
|
||||
|
||||
/* memmgr.c */
|
||||
seg far2para(VOID FAR * p);
|
||||
seg long2para(ULONG size);
|
||||
VOID FAR *add_far(VOID FAR * fp, ULONG off);
|
||||
void FAR *adjust_far(const void FAR * fp);
|
||||
VOID FAR *adjust_far(const void FAR * fp);
|
||||
COUNT DosMemAlloc(UWORD size, COUNT mode, seg FAR * para,
|
||||
UWORD FAR * asize);
|
||||
COUNT DosMemLargest(UWORD FAR * size);
|
||||
@ -242,12 +231,16 @@ VOID DosUmbLink(BYTE n);
|
||||
VOID mcb_print(mcb FAR * mcbp);
|
||||
|
||||
/* misc.c */
|
||||
VOID ASMCFUNC strcpy(REG BYTE * d, REG const BYTE * s);
|
||||
VOID ASMCFUNC fmemcpy(REG VOID FAR * d, REG const VOID FAR * s, REG COUNT n);
|
||||
VOID ASMCFUNC fstrcpy(REG BYTE FAR * d, REG const BYTE FAR * s);
|
||||
void ASMCFUNC memcpy(REG void *d, REG const VOID * s, REG COUNT n);
|
||||
void ASMCFUNC fmemset(REG VOID FAR * s, REG int ch, REG COUNT n);
|
||||
void ASMCFUNC memset(REG VOID * s, REG int ch, REG COUNT n);
|
||||
char * ASMCFUNC strcpy(char * d, const char * s);
|
||||
void ASMCFUNC fmemcpyBack(void FAR * d, const void FAR * s, size_t n);
|
||||
void ASMCFUNC fmemcpy(void FAR * d, const void FAR * s, size_t n);
|
||||
void ASMCFUNC fstrcpy(char FAR * d, const char FAR * s);
|
||||
void * ASMCFUNC memcpy(void *d, const void * s, size_t n);
|
||||
void ASMCFUNC fmemset(void FAR * s, int ch, size_t n);
|
||||
void * ASMCFUNC memset(void * s, int ch, size_t n);
|
||||
|
||||
int ASMCFUNC memcmp(const void *m1, const void *m2, size_t n);
|
||||
int ASMCFUNC fmemcmp(const void FAR *m1, const void FAR *m2, size_t n);
|
||||
|
||||
/* lfnapi.c */
|
||||
COUNT lfn_allocate_inode(VOID);
|
||||
@ -279,27 +272,29 @@ COUNT DosGetCountryInformation(UWORD cntry, VOID FAR * buf);
|
||||
#ifndef DosSetCountry
|
||||
COUNT DosSetCountry(UWORD cntry);
|
||||
#endif
|
||||
COUNT DosGetCodepage(UWORD FAR * actCP, UWORD FAR * sysCP);
|
||||
COUNT DosGetCodepage(UWORD * actCP, UWORD * sysCP);
|
||||
COUNT DosSetCodepage(UWORD actCP, UWORD sysCP);
|
||||
UWORD ASMCFUNC syscall_MUX14(DIRECT_IREGS);
|
||||
|
||||
/* prf.c */
|
||||
VOID put_console(COUNT c);
|
||||
WORD CDECL printf(CONST BYTE * fmt, ...);
|
||||
WORD CDECL sprintf(BYTE * buff, CONST BYTE * fmt, ...);
|
||||
int CDECL printf(CONST BYTE * fmt, ...);
|
||||
int CDECL sprintf(BYTE * buff, CONST BYTE * fmt, ...);
|
||||
VOID hexd(char *title, VOID FAR * p, COUNT numBytes);
|
||||
|
||||
/* strings.c */
|
||||
COUNT ASMCFUNC strlen(REG BYTE * s);
|
||||
COUNT ASMCFUNC fstrlen(REG BYTE FAR * s);
|
||||
VOID ASMCFUNC _fstrcpy(REG BYTE FAR * d, REG BYTE FAR * s);
|
||||
VOID ASMCFUNC strncpy(REG BYTE * d, REG BYTE * s, COUNT l);
|
||||
COUNT ASMCFUNC strcmp(REG BYTE * d, REG BYTE * s);
|
||||
COUNT ASMCFUNC fstrcmp(REG BYTE FAR * d, REG BYTE FAR * s);
|
||||
COUNT ASMCFUNC fstrncmp(REG BYTE FAR * d, REG BYTE FAR * s, COUNT l);
|
||||
COUNT ASMCFUNC strncmp(REG BYTE * d, REG BYTE * s, COUNT l);
|
||||
void ASMCFUNC fstrncpy(REG BYTE FAR * d, REG BYTE FAR * s, COUNT l);
|
||||
BYTE * ASMCFUNC strchr(const BYTE * s, BYTE c);
|
||||
size_t ASMCFUNC strlen(const char * s);
|
||||
size_t ASMCFUNC fstrlen(const char FAR * s);
|
||||
char FAR * ASMCFUNC _fstrcpy(char FAR * d, const char FAR * s);
|
||||
char * ASMCFUNC strncpy(char * d, const char * s, size_t l);
|
||||
int ASMCFUNC strcmp(const char * d, const char * s);
|
||||
int ASMCFUNC fstrcmp(const char FAR * d, const char FAR * s);
|
||||
int ASMCFUNC fstrncmp(const char FAR * d, const char FAR * s, size_t l);
|
||||
int ASMCFUNC strncmp(const char * d, const char * s, size_t l);
|
||||
void ASMCFUNC fstrncpy(char FAR * d, const char FAR * s, size_t l);
|
||||
char * ASMCFUNC strchr(const char * s, int c);
|
||||
char FAR * ASMCFUNC fstrchr(const char FAR * s, int c);
|
||||
void FAR * ASMCFUNC fmemchr(const void FAR * s, int c, size_t n);
|
||||
|
||||
/* sysclk.c */
|
||||
COUNT BcdToByte(COUNT x);
|
||||
@ -309,19 +304,17 @@ LONG WordToBcd(BYTE * x, UWORD * mon, UWORD * day, UWORD * yr);
|
||||
|
||||
/* syspack.c */
|
||||
#ifdef NONNATIVE
|
||||
VOID getdirent(BYTE FAR * vp, struct dirent FAR * dp);
|
||||
VOID putdirent(struct dirent FAR * dp, BYTE FAR * vp);
|
||||
VOID getdirent(UBYTE FAR * vp, struct dirent FAR * dp);
|
||||
VOID putdirent(struct dirent FAR * dp, UBYTE FAR * vp);
|
||||
#else
|
||||
#define getdirent(vp, dp) fmemcpy(dp, vp, sizeof(struct dirent))
|
||||
#define putdirent(dp, vp) fmemcpy(vp, dp, sizeof(struct dirent))
|
||||
#endif
|
||||
|
||||
/* systime.c */
|
||||
VOID DosGetTime(BYTE FAR * hp, BYTE FAR * mp, BYTE FAR * sp,
|
||||
BYTE FAR * hdp);
|
||||
VOID DosGetTime(UBYTE * hp, UBYTE * mp, UBYTE * sp, UBYTE * hdp);
|
||||
COUNT DosSetTime(BYTE h, BYTE m, BYTE s, BYTE hd);
|
||||
VOID DosGetDate(BYTE FAR * wdp, BYTE FAR * mp, BYTE FAR * mdp,
|
||||
COUNT FAR * yp);
|
||||
VOID DosGetDate(UBYTE * wdp, UBYTE * mp, UBYTE * mdp, UWORD * yp);
|
||||
COUNT DosSetDate(UWORD Month, UWORD DayOfMonth, UWORD Year);
|
||||
|
||||
const UWORD *is_leap_year_monthdays(UWORD year);
|
||||
@ -337,8 +330,8 @@ VOID InitPSP(VOID);
|
||||
/* newstuff.c */
|
||||
int SetJFTSize(UWORD nHandles);
|
||||
int DosMkTmp(BYTE FAR * pathname, UWORD attr);
|
||||
COUNT get_verify_drive(char FAR * src);
|
||||
COUNT truename(char FAR * src, char FAR * dest, COUNT t);
|
||||
COUNT get_verify_drive(const char FAR * src);
|
||||
COUNT truename(const char FAR * src, char * dest, COUNT t);
|
||||
|
||||
/* network.c */
|
||||
COUNT ASMCFUNC remote_doredirect(UWORD b, UCOUNT n, UWORD d, VOID FAR * s,
|
||||
@ -358,6 +351,7 @@ COUNT ASMCFUNC remote_findnext(VOID FAR * s);
|
||||
COUNT ASMCFUNC remote_getfattr(VOID);
|
||||
COUNT ASMCFUNC remote_getfree(VOID FAR * s, VOID * d);
|
||||
COUNT ASMCFUNC remote_open(sft FAR * s, COUNT mode);
|
||||
int ASMCFUNC remote_extopen(sft FAR * s, unsigned attr);
|
||||
LONG ASMCFUNC remote_lseek(sft FAR * s, LONG new_pos);
|
||||
UCOUNT ASMCFUNC remote_read(sft FAR * s, UCOUNT n, COUNT * err);
|
||||
UCOUNT ASMCFUNC remote_write(sft FAR * s, UCOUNT n, COUNT * err);
|
||||
@ -366,7 +360,7 @@ COUNT ASMCFUNC remote_setfattr(COUNT attr);
|
||||
COUNT ASMCFUNC remote_printredir(UCOUNT dx, UCOUNT ax);
|
||||
COUNT ASMCFUNC remote_commit(sft FAR * s);
|
||||
COUNT ASMCFUNC remote_close(sft FAR * s);
|
||||
COUNT ASMCFUNC QRemote_Fn(char FAR * s, char FAR * d);
|
||||
COUNT ASMCFUNC QRemote_Fn(char FAR * d, const char FAR * s);
|
||||
|
||||
UWORD get_machine_name(BYTE FAR * netname);
|
||||
VOID set_machine_name(BYTE FAR * netname, UWORD name_num);
|
||||
|
@ -74,16 +74,10 @@ UWORD DaysFromYearMonthDay(UWORD Year, UWORD Month, UWORD DayOfMonth)
|
||||
/* common - call the clock driver */
|
||||
void ExecuteClockDriverRequest(BYTE command)
|
||||
{
|
||||
ClkReqHdr.r_length = sizeof(request);
|
||||
ClkReqHdr.r_command = command;
|
||||
ClkReqHdr.r_count = sizeof(struct ClockRecord);
|
||||
ClkReqHdr.r_trans = (BYTE FAR *) (&ClkRecord);
|
||||
ClkReqHdr.r_status = 0;
|
||||
execrh((request FAR *) & ClkReqHdr, (struct dhdr FAR *)clock);
|
||||
BinaryCharIO(clock, sizeof(struct ClockRecord), &ClkRecord, command, &UnusedRetVal);
|
||||
}
|
||||
|
||||
VOID DosGetTime(BYTE FAR * hp, BYTE FAR * mp, BYTE FAR * sp,
|
||||
BYTE FAR * hdp)
|
||||
VOID DosGetTime(UBYTE * hp, UBYTE * mp, UBYTE * sp, UBYTE * hdp)
|
||||
{
|
||||
ExecuteClockDriverRequest(C_INPUT);
|
||||
|
||||
@ -113,9 +107,7 @@ COUNT DosSetTime(BYTE h, BYTE m, BYTE s, BYTE hd)
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
VOID DosGetDate(wdp, mp, mdp, yp)
|
||||
BYTE FAR *wdp, FAR * mp, FAR * mdp;
|
||||
COUNT FAR *yp;
|
||||
VOID DosGetDate(UBYTE *wdp, UBYTE *mp, UBYTE *mdp, UWORD *yp)
|
||||
{
|
||||
UWORD c;
|
||||
const UWORD *pdays;
|
||||
|
@ -461,7 +461,6 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
|
||||
/* Now load the executable */
|
||||
{
|
||||
BYTE FAR *sp;
|
||||
ULONG tmp;
|
||||
|
||||
if (mode == OVERLAY) /* memory already allocated */
|
||||
sp = MK_FP(mem, 0);
|
||||
@ -472,7 +471,7 @@ COUNT DosComLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
|
||||
-- 1999/04/21 ska */
|
||||
|
||||
/* rewind to start */
|
||||
DosSeek(fd, 0, 0, &tmp);
|
||||
DosSeek(fd, 0, 0);
|
||||
/* read everything, but at most 64K - sizeof(PSP) */
|
||||
DosRead(fd, 0xff00, sp, &UnusedRetVal);
|
||||
DosClose(fd);
|
||||
@ -552,7 +551,7 @@ VOID return_user(void)
|
||||
COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
|
||||
{
|
||||
UWORD mem, env, start_seg, asize = 0;
|
||||
ULONG exe_size, tmp;
|
||||
ULONG exe_size;
|
||||
{
|
||||
ULONG image_size;
|
||||
ULONG image_offset;
|
||||
@ -646,8 +645,7 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
|
||||
|
||||
/* Now load the executable */
|
||||
/* offset to start of image */
|
||||
DosSeek(fd, image_offset, 0, &tmp);
|
||||
if (tmp != image_offset)
|
||||
if (DosSeek(fd, image_offset, 0) != image_offset)
|
||||
{
|
||||
if (mode != OVERLAY)
|
||||
{
|
||||
@ -696,9 +694,8 @@ COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd)
|
||||
COUNT i;
|
||||
UWORD reloc[2];
|
||||
seg FAR *spot;
|
||||
ULONG tmp;
|
||||
|
||||
DosSeek(fd, ExeHeader.exRelocTable, 0, &tmp);
|
||||
DosSeek(fd, ExeHeader.exRelocTable, 0);
|
||||
for (i = 0; i < ExeHeader.exRelocItems; i++)
|
||||
{
|
||||
if (DosRead
|
||||
@ -765,11 +762,7 @@ COUNT DosExec(COUNT mode, exec_blk FAR * ep, BYTE FAR * lp)
|
||||
/* If file not found - free ram and return error */
|
||||
|
||||
if (IsDevice(lp) || /* we don't want to execute C:>NUL */
|
||||
#if 0
|
||||
(fd = (short)DosOpen(lp, O_LEGACY | O_OPEN | O_RDONLY, 0)) < 0)
|
||||
#else
|
||||
(fd = (short)DosOpen(lp, 0)) < 0)
|
||||
#endif
|
||||
{
|
||||
return DE_FILENOTFND;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ SYS_EXE_dependencies = \
|
||||
production: bin2c.com ..\bin\sys.com
|
||||
|
||||
bin2c.com: bin2c.c
|
||||
$(CL) $(CFLAGST) $(TINY) bin2c.c
|
||||
$(CL) $(CFLAGS) $(TINY) bin2c.c
|
||||
|
||||
..\bin\sys.com: sys.com
|
||||
copy sys.com ..\bin
|
||||
|
@ -622,8 +622,7 @@ VOID put_boot(COUNT drive, BYTE * bsFile, BOOL both)
|
||||
temp = bs32->sysFatSecMask + 1;
|
||||
for (bs32->sysFatSecShift = 0; temp != 1;
|
||||
bs32->sysFatSecShift++, temp >>= 1) ;
|
||||
|
||||
/* use fixed drive for A:, B: and DL otherwise */
|
||||
/* put 0 for A: or B: (force booting from A:), otherwise use DL */
|
||||
bs32->bsDriveNumber = drive < 2 ? 0 : 0xff;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
@ -659,9 +658,8 @@ VOID put_boot(COUNT drive, BYTE * bsFile, BOOL both)
|
||||
/* sector data starts on */
|
||||
temp = temp + bs->sysRootDirSecs;
|
||||
bs->sysDataStart = temp;
|
||||
|
||||
/* use fixed BIOS drive 0 for A:, B: and DL otherwise */
|
||||
bs32->bsDriveNumber = drive < 2 ? 0 : 0xff;
|
||||
/* put 0 for A: or B: (force booting from A:), otherwise use DL */
|
||||
bs->bsDriveNumber = drive < 2 ? 0 : 0xff;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
Loading…
x
Reference in New Issue
Block a user