2000-05-06 21:34:20 +02:00
|
|
|
/****************************************************************/
|
|
|
|
/* */
|
|
|
|
/* fcbfns.c */
|
|
|
|
/* */
|
|
|
|
/* Old CP/M Style Function Handlers for Kernel */
|
|
|
|
/* */
|
|
|
|
/* Copyright (c) 1995 */
|
|
|
|
/* Pasquale J. Villani */
|
|
|
|
/* All Rights Reserved */
|
|
|
|
/* */
|
|
|
|
/* This file is part of DOS-C. */
|
|
|
|
/* */
|
|
|
|
/* DOS-C is free software; you can redistribute it and/or */
|
|
|
|
/* modify it under the terms of the GNU General Public License */
|
|
|
|
/* as published by the Free Software Foundation; either version */
|
|
|
|
/* 2, or (at your option) any later version. */
|
|
|
|
/* */
|
|
|
|
/* DOS-C is distributed in the hope that it will be useful, but */
|
|
|
|
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
|
|
|
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
|
|
|
|
/* the GNU General Public License for more details. */
|
|
|
|
/* */
|
|
|
|
/* You should have received a copy of the GNU General Public */
|
|
|
|
/* License along with DOS-C; see the file COPYING. If not, */
|
|
|
|
/* write to the Free Software Foundation, 675 Mass Ave, */
|
|
|
|
/* Cambridge, MA 02139, USA. */
|
|
|
|
/****************************************************************/
|
|
|
|
|
|
|
|
#include "portab.h"
|
|
|
|
#include "globals.h"
|
|
|
|
|
|
|
|
#ifdef VERSION_STRINGS
|
2001-11-18 15:01:12 +01:00
|
|
|
static BYTE *RcsId =
|
|
|
|
"$Id$";
|
2000-05-06 21:34:20 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#define FCB_SUCCESS 0
|
|
|
|
#define FCB_ERR_NODATA 1
|
2002-08-04 03:14:18 +02:00
|
|
|
#define FCB_ERR_SEGMENT_WRAP 2
|
2000-05-06 21:34:20 +02:00
|
|
|
#define FCB_ERR_EOF 3
|
2002-08-04 03:14:18 +02:00
|
|
|
#define FCB_ERROR 0xff
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
STATIC fcb FAR *ExtFcbToFcb(xfcb FAR * lpExtFcb);
|
|
|
|
STATIC fcb FAR *CommonFcbInit(xfcb FAR * lpExtFcb, BYTE * pszBuffer,
|
2001-11-18 15:01:12 +01:00
|
|
|
COUNT * pCurDrive);
|
2004-02-09 20:32:22 +01:00
|
|
|
STATIC void FcbNameInit(fcb FAR * lpFcb, BYTE * pszBuffer, COUNT * pCurDrive);
|
2002-08-04 03:14:18 +02:00
|
|
|
STATIC void FcbNextRecord(fcb FAR * lpFcb);
|
|
|
|
STATIC void FcbCalcRec(xfcb FAR * lpXfcb);
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
#define TestCmnSeps(lpFileName) (*lpFileName && strchr(":<|>+=,", *lpFileName) != NULL)
|
|
|
|
#define TestFieldSeps(lpFileName) ((unsigned char)*lpFileName <= ' ' || strchr("/\"[]<>|.", *lpFileName) != NULL)
|
2001-04-22 00:32:53 +02:00
|
|
|
|
2000-05-06 21:34:20 +02:00
|
|
|
static dmatch Dmatch;
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
BYTE FAR *FatGetDrvData(UBYTE drive, UWORD * spc, UWORD * bps, UWORD * nc)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-05-09 00:49:35 +02:00
|
|
|
static BYTE mdb;
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2001-11-04 20:47:39 +01:00
|
|
|
/* get the data available from dpb */
|
2002-10-22 04:40:19 +02:00
|
|
|
if (DosGetFree(drive, spc, NULL, bps, nc))
|
2002-05-09 00:49:35 +02:00
|
|
|
{
|
2002-10-22 04:40:19 +02:00
|
|
|
struct dpb FAR *dpbp = get_dpb(drive == 0 ? default_drive : drive - 1);
|
2001-11-18 15:01:12 +01:00
|
|
|
/* Point to the media desctriptor for this drive */
|
2002-10-22 04:40:19 +02:00
|
|
|
if (dpbp == NULL)
|
2002-05-09 00:49:35 +02:00
|
|
|
{
|
|
|
|
mdb = *spc >> 8;
|
|
|
|
*spc &= 0xff;
|
2002-08-04 03:14:18 +02:00
|
|
|
return &mdb;
|
2002-05-09 00:49:35 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2002-10-22 04:40:19 +02:00
|
|
|
return (BYTE FAR *) & (dpbp->dpb_mdb);
|
2002-05-09 00:49:35 +02:00
|
|
|
}
|
|
|
|
}
|
2002-08-04 03:14:18 +02:00
|
|
|
return NULL;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#define PARSE_SEP_STOP 0x01
|
|
|
|
#define PARSE_DFLT_DRIVE 0x02
|
|
|
|
#define PARSE_BLNK_FNAME 0x04
|
|
|
|
#define PARSE_BLNK_FEXT 0x08
|
|
|
|
|
|
|
|
#define PARSE_RET_NOWILD 0
|
|
|
|
#define PARSE_RET_WILD 1
|
|
|
|
#define PARSE_RET_BADDRIVE 0xff
|
|
|
|
|
|
|
|
#ifndef IPL
|
2002-08-04 03:14:18 +02:00
|
|
|
UWORD FcbParseFname(int *wTestMode, const BYTE FAR * lpFileName, fcb FAR * lpFcb)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-01-23 23:29:41 +01:00
|
|
|
WORD wRetCodeName = FALSE, wRetCodeExt = FALSE;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* pjv -- ExtFcbToFcb? */
|
|
|
|
/* Start out with some simple stuff first. Check if we are */
|
|
|
|
/* going to use a default drive specificaton. */
|
2002-08-04 03:14:18 +02:00
|
|
|
if (!(*wTestMode & PARSE_DFLT_DRIVE))
|
2000-05-06 21:34:20 +02:00
|
|
|
lpFcb->fcb_drive = FDFLT_DRIVE;
|
2002-08-04 03:14:18 +02:00
|
|
|
if (!(*wTestMode & PARSE_BLNK_FNAME))
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
fmemset(lpFcb->fcb_fname, ' ', FNAME_SIZE);
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
2002-08-04 03:14:18 +02:00
|
|
|
if (!(*wTestMode & PARSE_BLNK_FEXT))
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
fmemset(lpFcb->fcb_fext, ' ', FEXT_SIZE);
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Undocumented behavior, set record number & record size to 0 */
|
|
|
|
lpFcb->fcb_cublock = lpFcb->fcb_recsiz = 0;
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
if (!(*wTestMode & PARSE_SEP_STOP))
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2004-02-07 19:04:50 +01:00
|
|
|
lpFileName = ParseSkipWh(lpFileName);
|
|
|
|
if (TestCmnSeps(lpFileName))
|
|
|
|
++lpFileName;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Undocumented "feature," we skip white space anyway */
|
2004-02-07 19:04:50 +01:00
|
|
|
lpFileName = ParseSkipWh(lpFileName);
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* Now check for drive specification */
|
2004-02-07 19:04:50 +01:00
|
|
|
if (*(lpFileName + 1) == ':')
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
/* non-portable construct to be changed */
|
2004-02-07 19:04:50 +01:00
|
|
|
REG UBYTE Drive = DosUpFChar(*lpFileName) - 'A';
|
2001-07-10 00:19:33 +02:00
|
|
|
|
2001-03-31 00:27:42 +02:00
|
|
|
if (Drive >= lastdrive)
|
2002-08-04 03:14:18 +02:00
|
|
|
{
|
|
|
|
*wTestMode = PARSE_RET_BADDRIVE;
|
2004-02-07 19:04:50 +01:00
|
|
|
return FP_OFF(lpFileName);
|
2002-08-04 03:14:18 +02:00
|
|
|
}
|
2001-07-10 00:19:33 +02:00
|
|
|
|
2001-09-23 22:39:44 +02:00
|
|
|
lpFcb->fcb_drive = Drive + 1;
|
2004-02-07 19:04:50 +01:00
|
|
|
lpFileName += 2;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
/* special cases: '.' and '..' */
|
2004-02-07 19:04:50 +01:00
|
|
|
if (*lpFileName == '.')
|
2001-07-23 14:47:42 +02:00
|
|
|
{
|
2001-11-18 15:01:12 +01:00
|
|
|
lpFcb->fcb_fname[0] = '.';
|
2004-02-07 19:04:50 +01:00
|
|
|
++lpFileName;
|
|
|
|
if (*lpFileName == '.')
|
2001-11-18 15:01:12 +01:00
|
|
|
{
|
|
|
|
lpFcb->fcb_fname[1] = '.';
|
2004-02-07 19:04:50 +01:00
|
|
|
++lpFileName;
|
2001-11-18 15:01:12 +01:00
|
|
|
}
|
2002-08-04 03:14:18 +02:00
|
|
|
*wTestMode = PARSE_RET_NOWILD;
|
2004-02-07 19:04:50 +01:00
|
|
|
return FP_OFF(lpFileName);
|
2001-07-23 14:47:42 +02:00
|
|
|
}
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2000-05-06 21:34:20 +02:00
|
|
|
/* Now to format the file name into the string */
|
2004-02-07 19:04:50 +01:00
|
|
|
lpFileName =
|
|
|
|
GetNameField(lpFileName, (BYTE FAR *) lpFcb->fcb_fname, FNAME_SIZE,
|
2001-11-18 15:01:12 +01:00
|
|
|
(BOOL *) & wRetCodeName);
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* Do we have an extension? If do, format it else return */
|
2004-02-07 19:04:50 +01:00
|
|
|
if (*lpFileName == '.')
|
|
|
|
lpFileName =
|
|
|
|
GetNameField(++lpFileName, (BYTE FAR *) lpFcb->fcb_fext,
|
2001-11-18 15:01:12 +01:00
|
|
|
FEXT_SIZE, (BOOL *) & wRetCodeExt);
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
*wTestMode = (wRetCodeName | wRetCodeExt) ? PARSE_RET_WILD : PARSE_RET_NOWILD;
|
2004-02-07 19:04:50 +01:00
|
|
|
return FP_OFF(lpFileName);
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2002-02-16 20:20:20 +01:00
|
|
|
const BYTE FAR * ParseSkipWh(const BYTE FAR * lpFileName)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
while (*lpFileName == ' ' || *lpFileName == '\t')
|
|
|
|
++lpFileName;
|
|
|
|
return lpFileName;
|
|
|
|
}
|
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
#if 0 /* defined above */
|
2000-05-06 21:34:20 +02:00
|
|
|
BOOL TestCmnSeps(BYTE FAR * lpFileName)
|
|
|
|
{
|
2001-11-18 15:01:12 +01:00
|
|
|
BYTE *pszTest, *pszCmnSeps = ":<|>+=,";
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
for (pszTest = pszCmnSeps; *pszTest != '\0'; ++pszTest)
|
|
|
|
if (*lpFileName == *pszTest)
|
|
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
|
|
}
|
2001-11-18 15:01:12 +01:00
|
|
|
#endif
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2001-04-22 00:32:53 +02:00
|
|
|
#if 0
|
2000-05-06 21:34:20 +02:00
|
|
|
BOOL TestFieldSeps(BYTE FAR * lpFileName)
|
|
|
|
{
|
2001-11-18 15:01:12 +01:00
|
|
|
BYTE *pszTest, *pszCmnSeps = "/\"[]<>|.";
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* Another non-portable construct */
|
|
|
|
if (*lpFileName <= ' ')
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
for (pszTest = pszCmnSeps; *pszTest != '\0'; ++pszTest)
|
|
|
|
if (*lpFileName == *pszTest)
|
|
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
|
|
}
|
2001-04-22 00:32:53 +02:00
|
|
|
#endif
|
|
|
|
|
2002-02-16 20:20:20 +01:00
|
|
|
const BYTE FAR * GetNameField(const BYTE FAR * lpFileName, BYTE FAR * lpDestField,
|
2000-05-06 21:34:20 +02:00
|
|
|
COUNT nFieldSize, BOOL * pbWildCard)
|
|
|
|
{
|
|
|
|
COUNT nIndex = 0;
|
|
|
|
BYTE cFill = ' ';
|
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
while (*lpFileName != '\0' && !TestFieldSeps(lpFileName)
|
|
|
|
&& nIndex < nFieldSize)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
if (*lpFileName == ' ')
|
|
|
|
break;
|
|
|
|
if (*lpFileName == '*')
|
|
|
|
{
|
|
|
|
*pbWildCard = TRUE;
|
|
|
|
cFill = '?';
|
|
|
|
++lpFileName;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (*lpFileName == '?')
|
|
|
|
*pbWildCard = TRUE;
|
2000-08-06 07:50:17 +02:00
|
|
|
*lpDestField++ = DosUpFChar(*lpFileName++);
|
2000-05-06 21:34:20 +02:00
|
|
|
++nIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Blank out remainder of field on exit */
|
2002-08-04 03:14:18 +02:00
|
|
|
fmemset(lpDestField, cFill, nFieldSize - nIndex);
|
2000-05-06 21:34:20 +02:00
|
|
|
return lpFileName;
|
|
|
|
}
|
|
|
|
|
2002-01-23 23:29:41 +01:00
|
|
|
STATIC VOID FcbNextRecord(fcb FAR * lpFcb)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-10-22 04:40:19 +02:00
|
|
|
if (++lpFcb->fcb_curec >= 128)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
lpFcb->fcb_curec = 0;
|
|
|
|
++lpFcb->fcb_cublock;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-10-16 15:01:55 +02:00
|
|
|
STATIC ULONG FcbRec(fcb FAR *lpFcb)
|
2001-04-15 05:21:50 +02:00
|
|
|
{
|
2002-01-23 23:29:41 +01:00
|
|
|
return ((ULONG) lpFcb->fcb_cublock * 128) + lpFcb->fcb_curec;
|
2001-04-15 05:21:50 +02:00
|
|
|
}
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
UBYTE FcbReadWrite(xfcb FAR * lpXfcb, UCOUNT recno, int mode)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-01-23 23:29:41 +01:00
|
|
|
ULONG lPosit;
|
2002-10-22 04:40:19 +02:00
|
|
|
long nTransfer;
|
2003-10-16 15:01:55 +02:00
|
|
|
fcb FAR *lpFcb;
|
2003-10-16 17:03:16 +02:00
|
|
|
unsigned size;
|
|
|
|
unsigned long bigsize;
|
|
|
|
unsigned recsiz;
|
2002-08-04 03:14:18 +02:00
|
|
|
|
2000-05-06 21:34:20 +02:00
|
|
|
/* Convert to fcb if necessary */
|
|
|
|
lpFcb = ExtFcbToFcb(lpXfcb);
|
2003-10-16 17:03:16 +02:00
|
|
|
recsiz = lpFcb->fcb_recsiz;
|
|
|
|
bigsize = (ULONG)recsiz * recno;
|
|
|
|
if (bigsize > 0xffff)
|
|
|
|
return FCB_ERR_SEGMENT_WRAP;
|
|
|
|
size = (unsigned)bigsize;
|
|
|
|
|
|
|
|
if (FP_OFF(dta) + size < FP_OFF(dta))
|
|
|
|
return FCB_ERR_SEGMENT_WRAP;
|
2003-10-16 16:25:15 +02:00
|
|
|
|
2000-05-06 21:34:20 +02:00
|
|
|
/* Now update the fcb and compute where we need to position */
|
|
|
|
/* to. */
|
2003-10-16 17:03:16 +02:00
|
|
|
lPosit = FcbRec(lpFcb) * recsiz;
|
2002-10-22 04:40:19 +02:00
|
|
|
if ((CritErrCode = -SftSeek(lpFcb->fcb_sftno, lPosit, 0)) != SUCCESS)
|
2002-08-04 03:14:18 +02:00
|
|
|
return FCB_ERR_NODATA;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2001-11-04 20:47:39 +01:00
|
|
|
/* Do the read */
|
2003-10-16 17:03:16 +02:00
|
|
|
nTransfer = DosRWSft(lpFcb->fcb_sftno, size, dta, mode & ~XFR_FCB_RANDOM);
|
2002-10-22 04:40:19 +02:00
|
|
|
if (nTransfer < 0)
|
|
|
|
CritErrCode = -(int)nTransfer;
|
2003-10-16 16:25:15 +02:00
|
|
|
|
2000-05-06 21:34:20 +02:00
|
|
|
/* Now find out how we will return and do it. */
|
2003-10-16 17:03:16 +02:00
|
|
|
if (mode & XFR_WRITE)
|
|
|
|
lpFcb->fcb_fsize = SftGetFsize(lpFcb->fcb_sftno);
|
|
|
|
|
|
|
|
/* if end-of-file, then partial read should count last record */
|
|
|
|
if (mode & XFR_FCB_RANDOM && recsiz > 0)
|
|
|
|
lpFcb->fcb_rndm += ((unsigned)nTransfer + recsiz - 1) / recsiz;
|
|
|
|
size -= (unsigned)nTransfer;
|
|
|
|
if (size == 0)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
FcbNextRecord(lpFcb);
|
2002-08-04 03:14:18 +02:00
|
|
|
return FCB_SUCCESS;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
2003-10-16 17:03:16 +02:00
|
|
|
size %= lpFcb->fcb_recsiz;
|
|
|
|
if (mode & XFR_READ && size > 0)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2003-10-16 17:03:16 +02:00
|
|
|
fmemset((char FAR *)dta + (unsigned)nTransfer, 0, size);
|
2000-05-06 21:34:20 +02:00
|
|
|
FcbNextRecord(lpFcb);
|
2002-08-04 03:14:18 +02:00
|
|
|
return FCB_ERR_EOF;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
2002-08-04 03:14:18 +02:00
|
|
|
return FCB_ERR_NODATA;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
UBYTE FcbGetFileSize(xfcb FAR * lpXfcb)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-10-22 04:40:19 +02:00
|
|
|
int FcbDrive, sft_idx;
|
2003-10-16 16:25:15 +02:00
|
|
|
unsigned recsiz;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* Build a traditional DOS file name */
|
2003-10-16 15:01:55 +02:00
|
|
|
fcb FAR *lpFcb = CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
|
2003-10-16 16:25:15 +02:00
|
|
|
recsiz = lpFcb->fcb_recsiz;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* check for a device */
|
2003-10-16 16:25:15 +02:00
|
|
|
if (!lpFcb || IsDevice(SecPathName) || (recsiz == 0))
|
2002-08-04 03:14:18 +02:00
|
|
|
return FCB_ERROR;
|
|
|
|
|
2002-10-22 04:40:19 +02:00
|
|
|
sft_idx = (short)DosOpenSft(SecPathName, O_LEGACY | O_RDONLY | O_OPEN, 0);
|
|
|
|
if (sft_idx >= 0)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-01-23 23:29:41 +01:00
|
|
|
ULONG fsize;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* Get the size */
|
2002-10-22 04:40:19 +02:00
|
|
|
fsize = SftGetFsize(sft_idx);
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* compute the size and update the fcb */
|
2003-10-16 16:25:15 +02:00
|
|
|
lpFcb->fcb_rndm = (fsize + (recsiz - 1)) / recsiz;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* close the file and leave */
|
2002-10-22 04:40:19 +02:00
|
|
|
if ((CritErrCode = -DosCloseSft(sft_idx, FALSE)) == SUCCESS)
|
2002-08-04 03:14:18 +02:00
|
|
|
return FCB_SUCCESS;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
else
|
2002-10-22 04:40:19 +02:00
|
|
|
CritErrCode = -sft_idx;
|
2002-08-04 03:14:18 +02:00
|
|
|
return FCB_ERROR;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
void FcbSetRandom(xfcb FAR * lpXfcb)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
/* Convert to fcb if necessary */
|
2003-10-16 15:01:55 +02:00
|
|
|
fcb FAR *lpFcb = ExtFcbToFcb(lpXfcb);
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* Now update the fcb and compute where we need to position */
|
2001-04-15 05:21:50 +02:00
|
|
|
/* to. */
|
2003-10-16 15:01:55 +02:00
|
|
|
lpFcb->fcb_rndm = FcbRec(lpFcb);
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
void FcbCalcRec(xfcb FAR * lpXfcb)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2001-11-04 20:47:39 +01:00
|
|
|
|
2000-05-06 21:34:20 +02:00
|
|
|
/* Convert to fcb if necessary */
|
2003-10-16 15:01:55 +02:00
|
|
|
fcb FAR *lpFcb = ExtFcbToFcb(lpXfcb);
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* Now update the fcb and compute where we need to position */
|
|
|
|
/* to. */
|
2004-02-07 19:04:50 +01:00
|
|
|
lpFcb->fcb_cublock = (UWORD)(lpFcb->fcb_rndm / 128);
|
|
|
|
lpFcb->fcb_curec = (UBYTE)lpFcb->fcb_rndm & 127;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2003-10-12 01:58:51 +02:00
|
|
|
UBYTE FcbRandomBlockIO(xfcb FAR * lpXfcb, UWORD *nRecords, int mode)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2003-10-16 17:03:16 +02:00
|
|
|
UBYTE nErrorCode;
|
2003-10-16 15:01:55 +02:00
|
|
|
fcb FAR *lpFcb;
|
2003-10-16 17:03:16 +02:00
|
|
|
unsigned long old;
|
2002-01-23 23:29:41 +01:00
|
|
|
|
2000-05-06 21:34:20 +02:00
|
|
|
FcbCalcRec(lpXfcb);
|
|
|
|
|
|
|
|
/* Convert to fcb if necessary */
|
|
|
|
lpFcb = ExtFcbToFcb(lpXfcb);
|
|
|
|
|
2003-10-16 17:03:16 +02:00
|
|
|
old = lpFcb->fcb_rndm;
|
|
|
|
nErrorCode = FcbReadWrite(lpXfcb, *nRecords, mode);
|
2004-02-07 19:04:50 +01:00
|
|
|
*nRecords = (UWORD)(lpFcb->fcb_rndm - old);
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* Now update the fcb */
|
2003-10-16 17:03:16 +02:00
|
|
|
FcbCalcRec(lpXfcb);
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
return nErrorCode;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
UBYTE FcbRandomIO(xfcb FAR * lpXfcb, int mode)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
UWORD uwCurrentBlock;
|
|
|
|
UBYTE ucCurrentRecord;
|
2002-08-04 03:14:18 +02:00
|
|
|
UBYTE nErrorCode;
|
2003-10-16 15:01:55 +02:00
|
|
|
fcb FAR *lpFcb;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
FcbCalcRec(lpXfcb);
|
|
|
|
|
|
|
|
/* Convert to fcb if necessary */
|
|
|
|
lpFcb = ExtFcbToFcb(lpXfcb);
|
|
|
|
|
|
|
|
uwCurrentBlock = lpFcb->fcb_cublock;
|
|
|
|
ucCurrentRecord = lpFcb->fcb_curec;
|
|
|
|
|
2003-10-16 17:03:16 +02:00
|
|
|
nErrorCode = FcbReadWrite(lpXfcb, 1, mode);
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
lpFcb->fcb_cublock = uwCurrentBlock;
|
|
|
|
lpFcb->fcb_curec = ucCurrentRecord;
|
2002-08-04 03:14:18 +02:00
|
|
|
return nErrorCode;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2002-01-23 23:29:41 +01:00
|
|
|
/* merged fcbOpen and FcbCreate - saves ~200 byte */
|
2002-08-04 03:14:18 +02:00
|
|
|
UBYTE FcbOpen(xfcb FAR * lpXfcb, unsigned flags)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2001-11-14 00:36:45 +01:00
|
|
|
sft FAR *sftp;
|
2001-07-23 14:47:42 +02:00
|
|
|
COUNT sft_idx, FcbDrive;
|
2002-08-04 03:14:18 +02:00
|
|
|
unsigned attr = 0;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* Build a traditional DOS file name */
|
2003-10-16 15:01:55 +02:00
|
|
|
fcb FAR *lpFcb = CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
|
2002-08-04 03:14:18 +02:00
|
|
|
if ((flags & O_CREAT) && lpXfcb->xfcb_flag == 0xff)
|
2002-02-16 20:20:20 +01:00
|
|
|
/* pass attribute without constraints (dangerous for directories) */
|
2002-08-04 03:14:18 +02:00
|
|
|
attr = lpXfcb->xfcb_attrib;
|
2002-01-23 23:29:41 +01:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
sft_idx = (short)DosOpenSft(SecPathName, flags, attr);
|
2001-07-23 14:47:42 +02:00
|
|
|
if (sft_idx < 0)
|
2002-08-04 03:14:18 +02:00
|
|
|
{
|
|
|
|
CritErrCode = -sft_idx;
|
|
|
|
return FCB_ERROR;
|
|
|
|
}
|
2001-07-23 14:47:42 +02:00
|
|
|
|
2001-11-14 00:36:45 +01:00
|
|
|
sftp = idx_to_sft(sft_idx);
|
2004-03-27 01:23:06 +01:00
|
|
|
sftp->sft_mode |= O_FCB;
|
2001-11-14 00:36:45 +01:00
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
lpFcb->fcb_sftno = sft_idx;
|
|
|
|
lpFcb->fcb_curec = 0;
|
|
|
|
lpFcb->fcb_rndm = 0;
|
2002-01-23 23:29:41 +01:00
|
|
|
|
|
|
|
lpFcb->fcb_recsiz = 0; /* true for devices */
|
2002-02-09 16:39:35 +01:00
|
|
|
if (!(sftp->sft_flags & SFT_FDEVICE)) /* check for a device */
|
2002-01-23 23:29:41 +01:00
|
|
|
{
|
|
|
|
lpFcb->fcb_drive = FcbDrive;
|
|
|
|
lpFcb->fcb_recsiz = 128;
|
|
|
|
}
|
|
|
|
lpFcb->fcb_fsize = sftp->sft_size;
|
|
|
|
lpFcb->fcb_date = sftp->sft_date;
|
|
|
|
lpFcb->fcb_time = sftp->sft_time;
|
2002-08-04 03:14:18 +02:00
|
|
|
return FCB_SUCCESS;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2002-01-23 23:29:41 +01:00
|
|
|
|
2001-07-10 00:19:33 +02:00
|
|
|
STATIC fcb FAR *ExtFcbToFcb(xfcb FAR * lpExtFcb)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
if (*((UBYTE FAR *) lpExtFcb) == 0xff)
|
2003-10-16 15:01:55 +02:00
|
|
|
sda_lpFcb = &lpExtFcb->xfcb_fcb;
|
2000-05-06 21:34:20 +02:00
|
|
|
else
|
2003-10-16 15:01:55 +02:00
|
|
|
sda_lpFcb = (fcb FAR *) lpExtFcb;
|
|
|
|
return sda_lpFcb;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2001-07-10 00:19:33 +02:00
|
|
|
STATIC fcb FAR *CommonFcbInit(xfcb FAR * lpExtFcb, BYTE * pszBuffer,
|
2000-05-06 21:34:20 +02:00
|
|
|
COUNT * pCurDrive)
|
|
|
|
{
|
|
|
|
fcb FAR *lpFcb;
|
|
|
|
|
|
|
|
/* convert to fcb if needed first */
|
2003-10-16 15:01:55 +02:00
|
|
|
sda_lpFcb = lpFcb = ExtFcbToFcb(lpExtFcb);
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* Build a traditional DOS file name */
|
2004-02-09 20:32:22 +01:00
|
|
|
FcbNameInit(lpFcb, pszBuffer, pCurDrive);
|
2000-05-06 21:34:20 +02:00
|
|
|
/* and return the fcb pointer */
|
|
|
|
return lpFcb;
|
|
|
|
}
|
|
|
|
|
2004-02-09 20:32:22 +01:00
|
|
|
STATIC void FcbNameInit(fcb FAR * lpFcb, BYTE * szBuffer, COUNT * pCurDrive)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2004-02-09 20:32:22 +01:00
|
|
|
BYTE *pszBuffer = szBuffer;
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2000-05-06 21:34:20 +02:00
|
|
|
/* Build a traditional DOS file name */
|
2003-06-15 21:00:39 +02:00
|
|
|
*pCurDrive = default_drive + 1;
|
2000-05-06 21:34:20 +02:00
|
|
|
if (lpFcb->fcb_drive != 0)
|
|
|
|
{
|
|
|
|
*pCurDrive = lpFcb->fcb_drive;
|
|
|
|
pszBuffer[0] = 'A' + lpFcb->fcb_drive - 1;
|
|
|
|
pszBuffer[1] = ':';
|
2001-03-21 03:56:26 +01:00
|
|
|
pszBuffer += 2;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
2002-10-22 04:40:19 +02:00
|
|
|
ConvertName83ToNameSZ(pszBuffer, lpFcb->fcb_fname);
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
UBYTE FcbDelete(xfcb FAR * lpXfcb)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
COUNT FcbDrive;
|
2002-08-04 03:14:18 +02:00
|
|
|
UBYTE result = FCB_SUCCESS;
|
2002-10-22 04:40:19 +02:00
|
|
|
void FAR *lpOldDta = dta;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* Build a traditional DOS file name */
|
2004-02-09 20:35:50 +01:00
|
|
|
CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
|
2000-05-06 21:34:20 +02:00
|
|
|
/* check for a device */
|
2004-02-09 20:32:22 +01:00
|
|
|
if (IsDevice(SecPathName))
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
result = FCB_ERROR;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
int attr = (lpXfcb->xfcb_flag == 0xff ? lpXfcb->xfcb_attrib : D_ALL);
|
2000-05-06 21:34:20 +02:00
|
|
|
dmatch Dmatch;
|
|
|
|
|
2002-10-22 04:40:19 +02:00
|
|
|
dta = &Dmatch;
|
2002-08-04 03:14:18 +02:00
|
|
|
if ((CritErrCode = -DosFindFirst(attr, SecPathName)) != SUCCESS)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
result = FCB_ERROR;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
2002-08-04 03:14:18 +02:00
|
|
|
else do
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-02-16 20:20:20 +01:00
|
|
|
SecPathName[0] = 'A' + FcbDrive - 1;
|
|
|
|
SecPathName[1] = ':';
|
|
|
|
strcpy(&SecPathName[2], Dmatch.dm_name);
|
|
|
|
if (DosDelete(SecPathName, attr) != SUCCESS)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
result = FCB_ERROR;
|
|
|
|
break;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
}
|
2002-08-04 03:14:18 +02:00
|
|
|
while ((CritErrCode = -DosFindNext()) == SUCCESS);
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
2002-08-04 03:14:18 +02:00
|
|
|
dta = lpOldDta;
|
|
|
|
return result;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
UBYTE FcbRename(xfcb FAR * lpXfcb)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
rfcb FAR *lpRenameFcb;
|
|
|
|
COUNT FcbDrive;
|
2002-08-04 03:14:18 +02:00
|
|
|
UBYTE result = FCB_SUCCESS;
|
2002-10-22 04:40:19 +02:00
|
|
|
void FAR *lpOldDta = dta;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* Build a traditional DOS file name */
|
2001-07-23 14:47:42 +02:00
|
|
|
lpRenameFcb = (rfcb FAR *) CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
|
2002-08-04 03:14:18 +02:00
|
|
|
|
2000-05-06 21:34:20 +02:00
|
|
|
/* check for a device */
|
2004-02-09 20:32:22 +01:00
|
|
|
if (IsDevice(SecPathName))
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
result = FCB_ERROR;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
dmatch Dmatch;
|
2002-08-04 03:14:18 +02:00
|
|
|
COUNT result;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
wAttr = (lpXfcb->xfcb_flag == 0xff ? lpXfcb->xfcb_attrib : D_ALL);
|
2002-10-22 04:40:19 +02:00
|
|
|
dta = &Dmatch;
|
2002-08-04 03:14:18 +02:00
|
|
|
if ((CritErrCode = -DosFindFirst(wAttr, SecPathName)) != SUCCESS)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
result = FCB_ERROR;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
2002-08-04 03:14:18 +02:00
|
|
|
else do
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2004-02-09 20:32:22 +01:00
|
|
|
/* 'A:' + '.' + '\0' */
|
|
|
|
BYTE loc_szBuffer[2 + FNAME_SIZE + 1 + FEXT_SIZE + 1];
|
2000-05-06 21:34:20 +02:00
|
|
|
fcb LocalFcb;
|
2002-02-16 20:20:20 +01:00
|
|
|
BYTE *pToName;
|
|
|
|
const BYTE FAR *pFromPattern = Dmatch.dm_name;
|
2002-08-04 03:14:18 +02:00
|
|
|
int i = 0;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
FcbParseFname(&i, pFromPattern, &LocalFcb);
|
2000-05-06 21:34:20 +02:00
|
|
|
/* Overlay the pattern, skipping '?' */
|
|
|
|
/* I'm cheating because this assumes that the */
|
|
|
|
/* struct alignments are on byte boundaries */
|
|
|
|
pToName = LocalFcb.fcb_fname;
|
2002-02-16 20:20:20 +01:00
|
|
|
pFromPattern = lpRenameFcb->renNewName;
|
|
|
|
for (i = 0; i < FNAME_SIZE + FEXT_SIZE; i++)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
if (*pFromPattern != '?')
|
2002-02-16 20:20:20 +01:00
|
|
|
*pToName = *pFromPattern;
|
|
|
|
pToName++;
|
|
|
|
pFromPattern++;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2002-02-16 20:20:20 +01:00
|
|
|
SecPathName[0] = 'A' + FcbDrive - 1;
|
|
|
|
SecPathName[1] = ':';
|
|
|
|
strcpy(&SecPathName[2], Dmatch.dm_name);
|
2002-08-04 03:14:18 +02:00
|
|
|
result = truename(SecPathName, PriPathName, 0);
|
2002-02-16 20:20:20 +01:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
if (result < SUCCESS || (result & IS_DEVICE))
|
|
|
|
{
|
|
|
|
result = FCB_ERROR;
|
|
|
|
break;
|
|
|
|
}
|
2000-05-06 21:34:20 +02:00
|
|
|
/* now to build a dos name again */
|
2002-02-16 20:20:20 +01:00
|
|
|
LocalFcb.fcb_drive = FcbDrive;
|
2004-02-09 20:32:22 +01:00
|
|
|
FcbNameInit(&LocalFcb, loc_szBuffer, &FcbDrive);
|
|
|
|
result = truename(loc_szBuffer, SecPathName, 0);
|
2004-05-24 13:42:28 +02:00
|
|
|
if (result < SUCCESS || (result & (IS_NETWORK|IS_DEVICE)) == IS_DEVICE
|
2004-05-23 20:28:18 +02:00
|
|
|
|| DosRenameTrue(PriPathName, SecPathName, wAttr) != SUCCESS)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
result = FCB_ERROR;
|
|
|
|
break;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
}
|
2002-08-04 03:14:18 +02:00
|
|
|
while ((CritErrCode = -DosFindNext()) == SUCCESS);
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
2002-08-04 03:14:18 +02:00
|
|
|
dta = lpOldDta;
|
|
|
|
return result;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2001-07-10 00:19:33 +02:00
|
|
|
/* TE:the MoveDirInfo() is now done by simply copying the dirEntry into the FCB
|
|
|
|
this prevents problems with ".", ".." and saves code
|
2001-07-24 18:56:29 +02:00
|
|
|
BO:use global SearchDir, as produced by FindFirst/Next
|
2001-07-10 00:19:33 +02:00
|
|
|
*/
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
UBYTE FcbClose(xfcb FAR * lpXfcb)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
sft FAR *s;
|
|
|
|
|
|
|
|
/* Convert to fcb if necessary */
|
2003-10-16 15:01:55 +02:00
|
|
|
fcb FAR *lpFcb = ExtFcbToFcb(lpXfcb);
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2001-08-19 14:58:36 +02:00
|
|
|
/* An already closed FCB can be closed again without error */
|
2001-11-18 15:01:12 +01:00
|
|
|
if (lpFcb->fcb_sftno == (BYTE) 0xff)
|
2002-08-04 03:14:18 +02:00
|
|
|
return FCB_SUCCESS;
|
2001-08-19 14:58:36 +02:00
|
|
|
|
2000-05-06 21:34:20 +02:00
|
|
|
/* Get the SFT block that contains the SFT */
|
2001-07-23 14:47:42 +02:00
|
|
|
if ((s = idx_to_sft(lpFcb->fcb_sftno)) == (sft FAR *) - 1)
|
2002-08-04 03:14:18 +02:00
|
|
|
return FCB_ERROR;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
/* 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);
|
2001-08-19 14:58:36 +02:00
|
|
|
DosSetFtimeSft(lpFcb->fcb_sftno, lpFcb->fcb_date, lpFcb->fcb_time);
|
2002-08-04 03:14:18 +02:00
|
|
|
if ((CritErrCode = -DosCloseSft(lpFcb->fcb_sftno, FALSE)) == SUCCESS)
|
2001-11-18 15:01:12 +01:00
|
|
|
{
|
|
|
|
lpFcb->fcb_sftno = (BYTE) 0xff;
|
2002-08-04 03:14:18 +02:00
|
|
|
return FCB_SUCCESS;
|
2001-08-19 14:58:36 +02:00
|
|
|
}
|
2002-08-04 03:14:18 +02:00
|
|
|
return FCB_ERROR;
|
2001-07-23 14:47:42 +02:00
|
|
|
}
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2001-11-14 00:36:45 +01:00
|
|
|
/* close all files the current process opened by FCBs */
|
2001-07-23 14:47:42 +02:00
|
|
|
VOID FcbCloseAll()
|
|
|
|
{
|
|
|
|
COUNT idx = 0;
|
2001-11-14 00:36:45 +01:00
|
|
|
sft FAR *sftp;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
for (idx = 0; (sftp = idx_to_sft(idx)) != (sft FAR *) - 1; idx++)
|
2004-03-27 01:23:06 +01:00
|
|
|
if ((sftp->sft_mode & O_FCB) && sftp->sft_psp == cu_psp)
|
2002-01-23 23:29:41 +01:00
|
|
|
DosCloseSft(idx, FALSE);
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
UBYTE FcbFindFirstNext(xfcb FAR * lpXfcb, BOOL First)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-10-22 04:40:19 +02:00
|
|
|
void FAR *orig_dta = dta;
|
2001-07-24 18:56:29 +02:00
|
|
|
BYTE FAR *lpDir;
|
2001-04-15 05:21:50 +02:00
|
|
|
COUNT FcbDrive;
|
2003-10-16 15:01:55 +02:00
|
|
|
fcb FAR *lpFcb;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* First, move the dta to a local and change it around to match */
|
|
|
|
/* our functions. */
|
2002-10-22 04:40:19 +02:00
|
|
|
lpDir = dta;
|
|
|
|
dta = &Dmatch;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* Next initialze local variables by moving them from the fcb */
|
2000-08-06 07:50:17 +02:00
|
|
|
lpFcb = CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);
|
2002-08-04 03:14:18 +02:00
|
|
|
/* Reconstrct the dirmatch structure from the fcb - doesn't hurt for first */
|
2000-08-06 07:50:17 +02:00
|
|
|
Dmatch.dm_drive = lpFcb->fcb_sftno;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2001-11-18 00:26:45 +01:00
|
|
|
fmemcpy(Dmatch.dm_name_pat, lpFcb->fcb_fname, FNAME_SIZE + FEXT_SIZE);
|
2000-08-06 07:50:17 +02:00
|
|
|
DosUpFMem((BYTE FAR *) Dmatch.dm_name_pat, FNAME_SIZE + FEXT_SIZE);
|
2002-08-04 03:14:18 +02:00
|
|
|
|
2000-05-06 21:34:20 +02:00
|
|
|
Dmatch.dm_attr_srch = wAttr;
|
2001-07-10 00:19:33 +02:00
|
|
|
Dmatch.dm_entry = lpFcb->fcb_strtclst;
|
2001-09-23 22:39:44 +02:00
|
|
|
Dmatch.dm_dircluster = lpFcb->fcb_dirclst;
|
2001-07-10 00:19:33 +02:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
wAttr = D_ALL;
|
|
|
|
|
2001-07-24 18:56:29 +02:00
|
|
|
if ((xfcb FAR *) lpFcb != lpXfcb)
|
|
|
|
{
|
|
|
|
wAttr = lpXfcb->xfcb_attrib;
|
2001-11-18 00:26:45 +01:00
|
|
|
fmemcpy(lpDir, lpXfcb, 7);
|
2001-07-24 18:56:29 +02:00
|
|
|
lpDir += 7;
|
|
|
|
}
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
CritErrCode = -(First ? DosFindFirst(wAttr, SecPathName) : DosFindNext());
|
|
|
|
if (CritErrCode != SUCCESS)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-10-22 04:40:19 +02:00
|
|
|
dta = orig_dta;
|
2002-08-04 03:14:18 +02:00
|
|
|
return FCB_ERROR;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
*lpDir++ = FcbDrive;
|
2002-08-04 03:14:18 +02:00
|
|
|
fmemcpy(lpDir, &SearchDir, sizeof(struct dirent));
|
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
lpFcb->fcb_dirclst = (UWORD) Dmatch.dm_dircluster;
|
2001-07-10 00:19:33 +02:00
|
|
|
lpFcb->fcb_strtclst = Dmatch.dm_entry;
|
2002-08-04 03:14:18 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
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. */
|
2000-06-21 20:16:46 +02:00
|
|
|
#if 0
|
|
|
|
lpFcb->fcb_cublock = Dmatch.dm_entry;
|
|
|
|
lpFcb->fcb_cublock *= 0x100;
|
|
|
|
lpFcb->fcb_cublock += wAttr;
|
|
|
|
#endif
|
2002-10-22 04:40:19 +02:00
|
|
|
dta = orig_dta;
|
2002-08-04 03:14:18 +02:00
|
|
|
return FCB_SUCCESS;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|