2000-05-06 21:34:20 +02:00
|
|
|
/****************************************************************/
|
|
|
|
/* */
|
|
|
|
/* dosfns.c */
|
|
|
|
/* */
|
|
|
|
/* DOS functions */
|
|
|
|
/* */
|
|
|
|
/* 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"
|
|
|
|
|
|
|
|
#ifdef VERSION_STRINGS
|
2001-11-18 15:01:12 +01:00
|
|
|
static BYTE *dosfnsRcsId =
|
|
|
|
"$Id$";
|
2000-05-06 21:34:20 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "globals.h"
|
|
|
|
|
2000-10-30 00:51:56 +01:00
|
|
|
/* /// Added for SHARE. - Ron Cemer */
|
|
|
|
|
2001-11-04 20:47:39 +01:00
|
|
|
BYTE share_installed = 0;
|
2000-10-30 00:51:56 +01:00
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
/* DOS calls this to see if it's okay to open the file.
|
|
|
|
Returns a file_table entry number to use (>= 0) if okay
|
|
|
|
to open. Otherwise returns < 0 and may generate a critical
|
|
|
|
error. If < 0 is returned, it is the negated error return
|
|
|
|
code, so DOS simply negates this value and returns it in
|
|
|
|
AX. */
|
2002-08-04 03:14:18 +02:00
|
|
|
STATIC int share_open_check(char * filename, /* pointer to fully qualified filename */
|
2001-11-18 15:01:12 +01:00
|
|
|
unsigned short pspseg, /* psp segment address of owner process */
|
|
|
|
int openmode, /* 0=read-only, 1=write-only, 2=read-write */
|
|
|
|
int sharemode); /* SHARE_COMPAT, etc... */
|
|
|
|
|
|
|
|
/* DOS calls this to record the fact that it has successfully
|
|
|
|
closed a file, or the fact that the open for this file failed. */
|
2002-01-23 23:29:41 +01:00
|
|
|
STATIC void share_close_file(int fileno); /* file_table entry number */
|
2001-11-18 15:01:12 +01:00
|
|
|
|
|
|
|
/* DOS calls this to determine whether it can access (read or
|
|
|
|
write) a specific section of a file. We call it internally
|
|
|
|
from lock_unlock (only when locking) to see if any portion
|
|
|
|
of the requested region is already locked. If pspseg is zero,
|
|
|
|
then it matches any pspseg in the lock table. Otherwise, only
|
|
|
|
locks which DO NOT belong to pspseg will be considered.
|
|
|
|
Returns zero if okay to access or lock (no portion of the
|
|
|
|
region is already locked). Otherwise returns non-zero and
|
|
|
|
generates a critical error (if allowcriter is non-zero).
|
|
|
|
If non-zero is returned, it is the negated return value for
|
|
|
|
the DOS call. */
|
2002-01-23 23:29:41 +01:00
|
|
|
STATIC int share_access_check(unsigned short pspseg, /* psp segment address of owner process */
|
2001-11-18 15:01:12 +01:00
|
|
|
int fileno, /* file_table entry number */
|
|
|
|
unsigned long ofs, /* offset into file */
|
|
|
|
unsigned long len, /* length (in bytes) of region to access */
|
|
|
|
int allowcriter); /* allow a critical error to be generated */
|
|
|
|
|
|
|
|
/* DOS calls this to lock or unlock a specific section of a file.
|
|
|
|
Returns zero if successfully locked or unlocked. Otherwise
|
|
|
|
returns non-zero.
|
|
|
|
If the return value is non-zero, it is the negated error
|
|
|
|
return code for the DOS 0x5c call. */
|
2002-01-23 23:29:41 +01:00
|
|
|
STATIC int share_lock_unlock(unsigned short pspseg, /* psp segment address of owner process */
|
2001-11-18 15:01:12 +01:00
|
|
|
int fileno, /* file_table entry number */
|
|
|
|
unsigned long ofs, /* offset into file */
|
|
|
|
unsigned long len, /* length (in bytes) of region to lock or unlock */
|
|
|
|
int unlock); /* non-zero to unlock; zero to lock */
|
2000-10-30 00:51:56 +01:00
|
|
|
|
|
|
|
/* /// End of additions for SHARE. - Ron Cemer */
|
|
|
|
|
2002-01-23 23:29:41 +01:00
|
|
|
STATIC int remote_lock_unlock(sft FAR *sftp, /* SFT for file */
|
|
|
|
unsigned long ofs, /* offset into file */
|
|
|
|
unsigned long len, /* length (in bytes) of region to lock or unlock */
|
|
|
|
int unlock); /* non-zero to unlock; zero to lock */
|
|
|
|
|
2002-10-22 04:40:19 +02:00
|
|
|
/* get current directory structure for drive
|
|
|
|
return NULL if the CDS is not valid or the
|
|
|
|
drive is not within range */
|
2003-06-16 00:06:03 +02:00
|
|
|
struct cds FAR *get_cds(unsigned drive)
|
2002-10-22 04:40:19 +02:00
|
|
|
{
|
|
|
|
struct cds FAR *cdsp;
|
|
|
|
unsigned flags;
|
|
|
|
|
|
|
|
if (drive >= lastdrive)
|
|
|
|
return NULL;
|
|
|
|
cdsp = &CDSp[drive];
|
|
|
|
flags = cdsp->cdsFlags;
|
|
|
|
/* Entry is disabled or JOINed drives are accessable by the path only */
|
|
|
|
if (!(flags & CDSVALID) || (flags & CDSJOINED) != 0)
|
|
|
|
return NULL;
|
|
|
|
if (!(flags & CDSNETWDRV) && cdsp->cdsDpb == NULL)
|
|
|
|
return NULL;
|
|
|
|
return cdsp;
|
|
|
|
}
|
2002-01-23 23:29:41 +01:00
|
|
|
|
2001-09-23 22:39:44 +02:00
|
|
|
#ifdef WITHFAT32
|
2002-01-23 23:29:41 +01:00
|
|
|
struct dpb FAR * GetDriveDPB(UBYTE drive, COUNT * rc)
|
2001-09-23 22:39:44 +02:00
|
|
|
{
|
|
|
|
struct dpb FAR *dpb;
|
2002-10-22 04:40:19 +02:00
|
|
|
struct cds FAR *cdsp;
|
|
|
|
|
|
|
|
cdsp = get_cds(drive == 0 ? default_drive : drive - 1);
|
|
|
|
|
|
|
|
if (cdsp == NULL)
|
2001-11-18 15:01:12 +01:00
|
|
|
{
|
|
|
|
*rc = DE_INVLDDRV;
|
|
|
|
return 0;
|
|
|
|
}
|
2002-10-22 04:40:19 +02:00
|
|
|
dpb = cdsp->cdsDpb;
|
|
|
|
if (dpb == 0 || cdsp->cdsFlags & CDSNETWDRV)
|
2001-11-18 15:01:12 +01:00
|
|
|
{
|
|
|
|
*rc = DE_INVLDDRV;
|
|
|
|
return 0;
|
|
|
|
}
|
2001-09-23 22:39:44 +02:00
|
|
|
|
|
|
|
*rc = SUCCESS;
|
|
|
|
return dpb;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
/* Construct dir-style filename for ASCIIZ 8.3 name */
|
2002-01-23 23:29:41 +01:00
|
|
|
STATIC VOID DosGetFile(BYTE * lpszPath, BYTE FAR * lpszDosFileName)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
char fcbname[FNAME_SIZE + FEXT_SIZE];
|
|
|
|
|
|
|
|
ParseDosName(lpszPath, fcbname, FALSE);
|
|
|
|
fmemcpy(lpszDosFileName, fcbname, FNAME_SIZE + FEXT_SIZE);
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2002-10-22 04:40:19 +02:00
|
|
|
sft FAR * idx_to_sft(int SftIndex)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
sfttbl FAR *sp;
|
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
if (SftIndex < 0)
|
2000-05-06 21:34:20 +02:00
|
|
|
return (sft FAR *) - 1;
|
|
|
|
|
|
|
|
/* Get the SFT block that contains the SFT */
|
2001-11-18 15:01:12 +01:00
|
|
|
for (sp = sfthead; sp != (sfttbl FAR *) - 1; sp = sp->sftt_next)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2001-11-18 15:01:12 +01:00
|
|
|
if (SftIndex < sp->sftt_count)
|
2001-11-04 20:47:39 +01:00
|
|
|
{
|
|
|
|
lpCurSft = (sft FAR *) & (sp->sftt_table[SftIndex]);
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
/* if not opened, the SFT is useless */
|
|
|
|
if (lpCurSft->sft_count == 0)
|
|
|
|
return (sft FAR *) - 1;
|
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
/* finally, point to the right entry */
|
2001-11-04 20:47:39 +01:00
|
|
|
return lpCurSft;
|
2001-11-18 15:01:12 +01:00
|
|
|
}
|
2000-05-06 21:34:20 +02:00
|
|
|
else
|
2001-07-23 14:47:42 +02:00
|
|
|
SftIndex -= sp->sftt_count;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
/* If not found, return an error */
|
2002-08-04 03:14:18 +02:00
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
return (sft FAR *) - 1;
|
|
|
|
}
|
|
|
|
|
2002-10-22 04:40:19 +02:00
|
|
|
int get_sft_idx(unsigned hndl)
|
2001-07-23 14:47:42 +02:00
|
|
|
{
|
|
|
|
psp FAR *p = MK_FP(cu_psp, 0);
|
2002-10-22 04:40:19 +02:00
|
|
|
int idx;
|
2001-07-23 14:47:42 +02:00
|
|
|
|
|
|
|
if (hndl >= p->ps_maxfiles)
|
|
|
|
return DE_INVLDHNDL;
|
|
|
|
|
2002-10-22 04:40:19 +02:00
|
|
|
idx = p->ps_filetab[hndl];
|
|
|
|
return idx == 0xff ? DE_INVLDHNDL : idx;
|
2001-07-23 14:47:42 +02:00
|
|
|
}
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
sft FAR *get_sft(UCOUNT hndl)
|
|
|
|
{
|
|
|
|
/* Get the SFT block that contains the SFT */
|
|
|
|
return idx_to_sft(get_sft_idx(hndl));
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2002-10-22 04:40:19 +02:00
|
|
|
long DosRWSft(int sft_idx, size_t n, void FAR * bp, int mode)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-10-22 04:40:19 +02:00
|
|
|
/* Get the SFT block that contains the SFT */
|
|
|
|
sft FAR *s = idx_to_sft(sft_idx);
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
if (FP_OFF(s) == (size_t) - 1)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-10-22 04:40:19 +02:00
|
|
|
return DE_INVLDHNDL;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
2002-08-04 03:14:18 +02:00
|
|
|
/* If for read and write-only or for write and read-only then exit */
|
|
|
|
if((mode == XFR_READ && (s->sft_mode & SFT_MWRITE)) ||
|
|
|
|
(mode == XFR_WRITE && !(s->sft_mode & (SFT_MWRITE | SFT_MRDWR))))
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-10-22 04:40:19 +02:00
|
|
|
return DE_ACCESS;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
2002-10-22 04:40:19 +02:00
|
|
|
if (mode == XFR_FORCE_WRITE)
|
|
|
|
mode = XFR_WRITE;
|
2002-08-04 03:14:18 +02:00
|
|
|
|
2000-05-06 21:34:20 +02:00
|
|
|
/*
|
2000-05-26 21:25:19 +02:00
|
|
|
* Do remote first or return error.
|
|
|
|
* must have been opened from remote.
|
2000-05-06 21:34:20 +02:00
|
|
|
*/
|
|
|
|
if (s->sft_flags & SFT_FSHARED)
|
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
UCOUNT XferCount;
|
2002-10-22 04:40:19 +02:00
|
|
|
VOID FAR *save_dta;
|
|
|
|
int err;
|
2001-11-04 20:47:39 +01:00
|
|
|
|
|
|
|
save_dta = dta;
|
|
|
|
lpCurSft = s;
|
2001-11-18 15:01:12 +01:00
|
|
|
current_filepos = s->sft_posit; /* needed for MSCDEX */
|
2001-11-04 20:47:39 +01:00
|
|
|
dta = bp;
|
2002-10-22 04:40:19 +02:00
|
|
|
XferCount = (mode == XFR_READ ? remote_read : remote_write)(s, n, &err);
|
2001-11-04 20:47:39 +01:00
|
|
|
dta = save_dta;
|
2003-09-04 21:05:27 +02:00
|
|
|
return err == SUCCESS ? (long)XferCount : err;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
2002-08-04 03:14:18 +02:00
|
|
|
|
|
|
|
/* Do a device transfer if device */
|
2000-05-06 21:34:20 +02:00
|
|
|
if (s->sft_flags & SFT_FDEVICE)
|
|
|
|
{
|
2003-09-09 19:43:43 +02:00
|
|
|
struct dhdr FAR *dev = s->sft_dev;
|
|
|
|
|
2002-10-22 04:40:19 +02:00
|
|
|
/* Now handle raw and cooked modes */
|
|
|
|
if (s->sft_flags & SFT_FBINARY)
|
|
|
|
{
|
2003-09-09 19:43:43 +02:00
|
|
|
long rc = BinaryCharIO(&dev, n, bp,
|
2002-10-22 04:40:19 +02:00
|
|
|
mode == XFR_READ ? C_INPUT : C_OUTPUT);
|
|
|
|
if (mode == XFR_WRITE && rc > 0 && (s->sft_flags & SFT_FCONOUT))
|
|
|
|
{
|
|
|
|
size_t cnt = (size_t)rc;
|
|
|
|
const char FAR *p = bp;
|
2003-06-15 16:21:49 +02:00
|
|
|
unsigned char scrpos = scr_pos;
|
2002-10-22 04:40:19 +02:00
|
|
|
while (cnt--)
|
|
|
|
{
|
|
|
|
switch (*p++)
|
|
|
|
{
|
|
|
|
case CR:
|
2003-06-15 16:21:49 +02:00
|
|
|
scrpos = 0;
|
2002-10-22 04:40:19 +02:00
|
|
|
break;
|
|
|
|
case LF:
|
|
|
|
case BELL:
|
|
|
|
break;
|
|
|
|
case BS:
|
2003-06-15 16:21:49 +02:00
|
|
|
--scrpos;
|
2002-10-22 04:40:19 +02:00
|
|
|
break;
|
|
|
|
default:
|
2003-06-15 16:21:49 +02:00
|
|
|
++scrpos;
|
2002-10-22 04:40:19 +02:00
|
|
|
}
|
|
|
|
}
|
2003-06-15 16:21:49 +02:00
|
|
|
scr_pos = scrpos;
|
2002-10-22 04:40:19 +02:00
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* cooked mode */
|
2002-08-04 03:14:18 +02:00
|
|
|
if (mode==XFR_READ)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-10-22 04:40:19 +02:00
|
|
|
long rc;
|
2003-09-09 19:43:43 +02:00
|
|
|
|
2002-10-22 04:40:19 +02:00
|
|
|
/* Test for eof and exit */
|
2002-08-04 03:14:18 +02:00
|
|
|
/* immediately if it is */
|
|
|
|
if (!(s->sft_flags & SFT_FEOF) || (s->sft_flags & SFT_FNUL))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (s->sft_flags & SFT_FCONIN)
|
2002-10-22 04:40:19 +02:00
|
|
|
rc = read_line_handle(sft_idx, n, bp);
|
2002-08-05 21:56:38 +02:00
|
|
|
else
|
2003-09-09 19:43:43 +02:00
|
|
|
rc = cooked_read(&dev, n, bp);
|
2002-10-22 04:40:19 +02:00
|
|
|
if (*(char *)bp == CTL_Z)
|
2002-08-05 21:56:38 +02:00
|
|
|
s->sft_flags &= ~SFT_FEOF;
|
2002-10-22 04:40:19 +02:00
|
|
|
return rc;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
2002-08-04 03:14:18 +02:00
|
|
|
else
|
2001-11-18 15:01:12 +01:00
|
|
|
{
|
2003-09-09 19:43:43 +02:00
|
|
|
/* reset EOF state (set to no EOF) */
|
2002-08-04 03:14:18 +02:00
|
|
|
s->sft_flags |= SFT_FEOF;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
/* if null just report full transfer */
|
|
|
|
if (s->sft_flags & SFT_FNUL)
|
|
|
|
return n;
|
|
|
|
else
|
2003-09-09 19:43:43 +02:00
|
|
|
return cooked_write(&dev, n, bp);
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
}
|
2002-08-04 03:14:18 +02:00
|
|
|
|
|
|
|
/* a block transfer */
|
|
|
|
/* /// Added for SHARE - Ron Cemer */
|
|
|
|
if (IsShareInstalled() && (s->sft_shroff >= 0))
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-10-22 04:40:19 +02:00
|
|
|
int rc = share_access_check(cu_psp, s->sft_shroff, s->sft_posit,
|
|
|
|
(unsigned long)n, 1);
|
|
|
|
if (rc != SUCCESS)
|
|
|
|
return rc;
|
2002-08-04 03:14:18 +02:00
|
|
|
}
|
|
|
|
/* /// End of additions for SHARE - Ron Cemer */
|
|
|
|
{
|
2003-09-24 21:34:11 +02:00
|
|
|
long XferCount = rwblock(s->sft_status, bp, n, mode);
|
|
|
|
if (XferCount < 0)
|
|
|
|
return XferCount;
|
2002-08-04 03:14:18 +02:00
|
|
|
if (mode == XFR_WRITE)
|
|
|
|
s->sft_size = dos_getfsize(s->sft_status);
|
2002-10-22 04:40:19 +02:00
|
|
|
s->sft_posit += XferCount;
|
2002-08-04 03:14:18 +02:00
|
|
|
return XferCount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-10-22 04:40:19 +02:00
|
|
|
COUNT SftSeek(int sft_idx, LONG new_pos, COUNT mode)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-10-22 04:40:19 +02:00
|
|
|
sft FAR *s = idx_to_sft(sft_idx);
|
|
|
|
if (FP_OFF(s) == (size_t) -1)
|
|
|
|
return DE_INVLDHNDL;
|
|
|
|
|
2000-05-06 21:34:20 +02:00
|
|
|
/* Test for invalid mode */
|
|
|
|
if (mode < 0 || mode > 2)
|
|
|
|
return DE_INVLDFUNC;
|
|
|
|
|
2001-11-04 20:47:39 +01:00
|
|
|
lpCurSft = s;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
if (s->sft_flags & SFT_FSHARED)
|
|
|
|
{
|
2000-05-26 21:25:19 +02:00
|
|
|
/* seek from end of file */
|
2001-11-18 15:01:12 +01:00
|
|
|
if (mode == 2)
|
|
|
|
{
|
2000-05-26 21:25:19 +02:00
|
|
|
/*
|
|
|
|
* RB list has it as Note:
|
|
|
|
* this function is called by the DOS 3.1+ kernel, but only when seeking
|
|
|
|
* from the end of a file opened with sharing modes set in such a manner
|
|
|
|
* that another process is able to change the size of the file while it
|
|
|
|
* is already open
|
|
|
|
* Tested this with Shsucdx ver 0.06 and 1.0. Both now work.
|
|
|
|
* Lredir via mfs.c from DosEMU works when writing appended files.
|
|
|
|
* Mfs.c looks for these mode bits set, so here is my best guess.;^)
|
|
|
|
*/
|
2001-11-18 15:01:12 +01:00
|
|
|
if ((s->sft_mode & SFT_MDENYREAD) || (s->sft_mode & SFT_MDENYNONE))
|
|
|
|
{
|
|
|
|
s->sft_posit = remote_lseek(s, new_pos);
|
2000-05-26 21:25:19 +02:00
|
|
|
return SUCCESS;
|
2001-11-18 15:01:12 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
s->sft_posit = s->sft_size + new_pos;
|
2000-05-26 21:25:19 +02:00
|
|
|
return SUCCESS;
|
2001-11-18 15:01:12 +01:00
|
|
|
}
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
2001-11-18 15:01:12 +01:00
|
|
|
if (mode == 0)
|
|
|
|
{
|
|
|
|
s->sft_posit = new_pos;
|
|
|
|
return SUCCESS;
|
2000-05-26 21:25:19 +02:00
|
|
|
}
|
2001-11-18 15:01:12 +01:00
|
|
|
if (mode == 1)
|
2000-05-26 21:25:19 +02:00
|
|
|
{
|
2001-11-18 15:01:12 +01:00
|
|
|
s->sft_posit += new_pos;
|
|
|
|
return SUCCESS;
|
2000-05-26 21:25:19 +02:00
|
|
|
}
|
2001-11-18 15:01:12 +01:00
|
|
|
return DE_INVLDFUNC;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Do special return for character devices */
|
|
|
|
if (s->sft_flags & SFT_FDEVICE)
|
|
|
|
{
|
|
|
|
s->sft_posit = 0l;
|
|
|
|
return SUCCESS;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LONG result = dos_lseek(s->sft_status, new_pos, mode);
|
|
|
|
if (result < 0l)
|
|
|
|
return (int)result;
|
2000-05-26 21:25:19 +02:00
|
|
|
else
|
|
|
|
{
|
2001-11-18 15:01:12 +01:00
|
|
|
s->sft_posit = result;
|
|
|
|
return SUCCESS;
|
2000-05-26 21:25:19 +02:00
|
|
|
}
|
2001-11-18 15:01:12 +01:00
|
|
|
}
|
2000-05-08 06:30:00 +02:00
|
|
|
}
|
|
|
|
|
2002-10-22 04:40:19 +02:00
|
|
|
ULONG DosSeek(unsigned hndl, LONG new_pos, COUNT mode)
|
2000-05-08 06:30:00 +02:00
|
|
|
{
|
2002-10-22 04:40:19 +02:00
|
|
|
int sft_idx = get_sft_idx(hndl);
|
2001-11-18 15:01:12 +01:00
|
|
|
COUNT result;
|
|
|
|
|
|
|
|
/* Get the SFT block that contains the SFT */
|
2002-10-22 04:40:19 +02:00
|
|
|
result = SftSeek(sft_idx, new_pos, mode);
|
2001-11-18 15:01:12 +01:00
|
|
|
if (result == SUCCESS)
|
|
|
|
{
|
2002-10-22 04:40:19 +02:00
|
|
|
return idx_to_sft(sft_idx)->sft_posit;
|
2001-11-18 15:01:12 +01:00
|
|
|
}
|
2002-08-04 03:14:18 +02:00
|
|
|
return (ULONG)-1;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
STATIC long get_free_hndl(void)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
psp FAR *p = MK_FP(cu_psp, 0);
|
2003-06-15 16:21:49 +02:00
|
|
|
UBYTE FAR *q = p->ps_filetab;
|
|
|
|
UBYTE FAR *r = fmemchr(q, 0xff, p->ps_maxfiles);
|
|
|
|
return FP_OFF(r) == 0 ? DE_TOOMANY : r - q;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2002-10-22 04:40:19 +02:00
|
|
|
STATIC sft FAR *get_free_sft(COUNT * sft_idx)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2001-07-23 14:47:42 +02:00
|
|
|
COUNT sys_idx = 0;
|
2000-05-06 21:34:20 +02:00
|
|
|
sfttbl FAR *sp;
|
|
|
|
|
|
|
|
/* Get the SFT block that contains the SFT */
|
|
|
|
for (sp = sfthead; sp != (sfttbl FAR *) - 1; sp = sp->sftt_next)
|
|
|
|
{
|
2001-04-29 19:34:41 +02:00
|
|
|
REG COUNT i = sp->sftt_count;
|
|
|
|
sft FAR *sfti = sp->sftt_table;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
for (; --i >= 0; sys_idx++, sfti++)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2001-04-29 19:34:41 +02:00
|
|
|
if (sfti->sft_count == 0)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2001-11-18 15:01:12 +01:00
|
|
|
*sft_idx = sys_idx;
|
2001-11-04 20:47:39 +01:00
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
/* MS NET uses this on open/creat TE */
|
|
|
|
{
|
2002-01-23 23:29:41 +01:00
|
|
|
extern WORD ASM current_sft_idx;
|
2001-11-04 20:47:39 +01:00
|
|
|
current_sft_idx = sys_idx;
|
2001-11-18 15:01:12 +01:00
|
|
|
}
|
2001-11-04 20:47:39 +01:00
|
|
|
|
2001-04-29 19:34:41 +02:00
|
|
|
return sfti;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* If not found, return an error */
|
|
|
|
return (sft FAR *) - 1;
|
|
|
|
}
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
const char FAR *get_root(const char FAR * fname)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
/* find the end */
|
2003-06-15 16:21:49 +02:00
|
|
|
register unsigned length = fstrlen(fname);
|
2002-08-04 03:14:18 +02:00
|
|
|
char c;
|
|
|
|
|
2000-05-06 21:34:20 +02:00
|
|
|
/* now back up to first path seperator or start */
|
2003-06-15 16:21:49 +02:00
|
|
|
fname += length;
|
|
|
|
while (length)
|
2002-08-04 03:14:18 +02:00
|
|
|
{
|
2003-06-15 16:21:49 +02:00
|
|
|
length--;
|
|
|
|
c = *--fname;
|
2003-06-17 13:55:44 +02:00
|
|
|
if (c == '/' || c == '\\' || c == ':') {
|
|
|
|
fname++;
|
2002-08-04 03:14:18 +02:00
|
|
|
break;
|
2003-06-17 13:55:44 +02:00
|
|
|
}
|
2002-08-04 03:14:18 +02:00
|
|
|
}
|
2003-06-15 16:21:49 +02:00
|
|
|
return fname;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2002-02-16 20:20:20 +01:00
|
|
|
/* initialize SFT fields (for open/creat) for character devices */
|
|
|
|
STATIC void DeviceOpenSft(struct dhdr FAR *dhp, sft FAR *sftp)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-02-16 20:20:20 +01:00
|
|
|
int i;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2002-02-16 20:20:20 +01:00
|
|
|
sftp->sft_shroff = -1; /* /// Added for SHARE - Ron Cemer */
|
|
|
|
sftp->sft_count += 1;
|
|
|
|
sftp->sft_flags =
|
|
|
|
((dhp->
|
|
|
|
dh_attr & ~SFT_MASK) & ~SFT_FSHARED) | SFT_FDEVICE | SFT_FEOF;
|
|
|
|
fmemcpy(sftp->sft_name, dhp->dh_name, FNAME_SIZE);
|
|
|
|
|
|
|
|
/* pad with spaces */
|
|
|
|
for (i = FNAME_SIZE + FEXT_SIZE - 1; sftp->sft_name[i] == '\0'; i--)
|
|
|
|
sftp->sft_name[i] = ' ';
|
|
|
|
/* and uppercase */
|
|
|
|
DosUpFMem(sftp->sft_name, FNAME_SIZE + FEXT_SIZE);
|
|
|
|
|
|
|
|
sftp->sft_dev = dhp;
|
|
|
|
sftp->sft_date = dos_getdate();
|
|
|
|
sftp->sft_time = dos_gettime();
|
2002-08-04 03:14:18 +02:00
|
|
|
sftp->sft_attrib = D_DEVICE;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
/*
|
|
|
|
extended open codes
|
|
|
|
0000 0000 always fail
|
|
|
|
0000 0001 open O_OPEN
|
|
|
|
0000 0010 replace O_TRUNC
|
|
|
|
|
|
|
|
0001 0000 create new file O_CREAT
|
|
|
|
0001 0001 create if not exists, open if exists O_CREAT | O_OPEN
|
|
|
|
0001 0010 create O_CREAT | O_TRUNC
|
|
|
|
|
|
|
|
bits for flags (bits 11-8 are internal FreeDOS bits only)
|
|
|
|
15 O_FCB called from FCB open
|
|
|
|
14 O_SYNC commit for each write (not implemented yet)
|
|
|
|
13 O_NOCRIT do not invoke int23 (not implemented yet)
|
|
|
|
12 O_LARGEFILE allow files >= 2gb but < 4gb (not implemented yet)
|
|
|
|
11 O_LEGACY not called from int21/ah=6c: find right fn for redirector
|
|
|
|
10 O_CREAT if file does not exist, create it
|
|
|
|
9 O_TRUNC if file exists, truncate and open it \ not both
|
|
|
|
8 O_OPEN if file exists, open it /
|
|
|
|
7 O_NOINHERIT do not inherit handle on exec
|
|
|
|
6 \
|
|
|
|
5 - sharing modes
|
|
|
|
4 /
|
|
|
|
3 reserved
|
|
|
|
2 bits 2,1,0 = 100: RDONLY and do not modify file's last access time
|
|
|
|
(not implemented yet)
|
|
|
|
1 \ 0=O_RDONLY, 1=O_WRONLY,
|
|
|
|
0 / 2=O_RDWR, 3=O_EXECCASE (preserve case for redirector EXEC,
|
|
|
|
(not implemented yet))
|
|
|
|
*/
|
|
|
|
|
|
|
|
long DosOpenSft(char FAR * fname, unsigned flags, unsigned attrib)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2001-07-23 14:47:42 +02:00
|
|
|
COUNT sft_idx;
|
2000-05-06 21:34:20 +02:00
|
|
|
sft FAR *sftp;
|
|
|
|
struct dhdr FAR *dhp;
|
2002-08-04 03:14:18 +02:00
|
|
|
long result;
|
|
|
|
|
|
|
|
result = truename(fname, PriPathName, CDS_MODE_CHECK_DEV_PATH);
|
|
|
|
if (result < SUCCESS)
|
|
|
|
return result;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* now get a free system file table entry */
|
2001-07-23 14:47:42 +02:00
|
|
|
if ((sftp = get_free_sft(&sft_idx)) == (sft FAR *) - 1)
|
2000-05-06 21:34:20 +02:00
|
|
|
return DE_TOOMANY;
|
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
fmemset(sftp, 0, sizeof(sft));
|
|
|
|
|
|
|
|
sftp->sft_psp = cu_psp;
|
2002-08-04 03:14:18 +02:00
|
|
|
sftp->sft_mode = flags & 0xf0ff;
|
|
|
|
OpenMode = (BYTE) flags;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
sftp->sft_shroff = -1; /* /// Added for SHARE - Ron Cemer */
|
|
|
|
sftp->sft_attrib = attrib = attrib | D_ARCHIVE;
|
|
|
|
|
|
|
|
if (result & IS_NETWORK)
|
2001-11-18 15:01:12 +01:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
int status;
|
|
|
|
if ((flags & (O_TRUNC | O_CREAT)) == O_CREAT)
|
|
|
|
attrib |= 0x100;
|
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
lpCurSft = sftp;
|
2002-08-04 03:14:18 +02:00
|
|
|
if (!(flags & O_LEGACY))
|
2001-11-18 15:01:12 +01:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
extern UWORD ASM ext_open_mode, ASM ext_open_attrib, ASM ext_open_action;
|
|
|
|
ext_open_mode = flags & 0x70ff;
|
|
|
|
ext_open_attrib = attrib & 0xff;
|
|
|
|
ext_open_action = ((flags & 0x0300) >> 8) | ((flags & O_CREAT) >> 6);
|
|
|
|
status = remote_extopen(sftp, attrib);
|
2001-11-18 15:01:12 +01:00
|
|
|
}
|
2002-08-04 03:14:18 +02:00
|
|
|
else if (flags & O_CREAT)
|
|
|
|
status = remote_creat(sftp, attrib);
|
|
|
|
else
|
|
|
|
status = remote_open(sftp, (BYTE)flags);
|
|
|
|
if (status >= SUCCESS)
|
|
|
|
{
|
|
|
|
if (sftp->sft_count == 0)
|
|
|
|
sftp->sft_count++;
|
|
|
|
return sft_idx | ((long)status << 16);
|
|
|
|
}
|
|
|
|
return status;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
/* check for a device */
|
|
|
|
if ((result & IS_DEVICE) && (dhp = IsDevice(fname)) != NULL)
|
2001-11-18 15:01:12 +01:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
DeviceOpenSft(dhp, sftp);
|
|
|
|
return sft_idx;
|
2001-09-23 22:39:44 +02:00
|
|
|
}
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2000-10-30 00:51:56 +01:00
|
|
|
/* /// Added for SHARE. - Ron Cemer */
|
2001-11-18 15:01:12 +01:00
|
|
|
if (IsShareInstalled())
|
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
if ((sftp->sft_shroff =
|
|
|
|
share_open_check(PriPathName, cu_psp,
|
2002-11-09 20:11:26 +01:00
|
|
|
flags & 0x03, (flags >> 4) & 0x07)) < 0)
|
2001-11-18 15:01:12 +01:00
|
|
|
return sftp->sft_shroff;
|
2000-10-30 00:51:56 +01:00
|
|
|
}
|
2002-08-04 03:14:18 +02:00
|
|
|
|
2000-10-30 00:51:56 +01:00
|
|
|
/* /// End of additions for SHARE. - Ron Cemer */
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
/* NEVER EVER allow directories to be created */
|
|
|
|
/* ... though FCB's are weird :) */
|
|
|
|
if (!(flags & O_FCB) &&
|
|
|
|
(attrib & ~(D_RDONLY | D_HIDDEN | D_SYSTEM | D_ARCHIVE | D_VOLID)))
|
|
|
|
return DE_ACCESS;
|
|
|
|
|
|
|
|
result = dos_open(PriPathName, flags, attrib);
|
|
|
|
if (result >= 0)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
int status = (int)(result >> 16);
|
|
|
|
if (status == S_OPENED)
|
|
|
|
{
|
|
|
|
sftp->sft_attrib = dos_getfattr_fd((COUNT)result);
|
|
|
|
/* Check permissions. -- JPP
|
|
|
|
(do not allow to open volume labels/directories) */
|
|
|
|
if (sftp->sft_attrib & (D_DIR | D_VOLID))
|
|
|
|
{
|
|
|
|
dos_close((COUNT)result);
|
|
|
|
return DE_ACCESS;
|
|
|
|
}
|
|
|
|
sftp->sft_size = dos_getfsize((COUNT)result);
|
|
|
|
}
|
|
|
|
sftp->sft_status = (COUNT)result;
|
|
|
|
sftp->sft_flags = PriPathName[0] - 'A';
|
2000-05-06 21:34:20 +02:00
|
|
|
sftp->sft_count += 1;
|
2002-08-04 03:14:18 +02:00
|
|
|
DosGetFile(PriPathName, sftp->sft_name);
|
2002-01-23 23:29:41 +01:00
|
|
|
dos_getftime(sftp->sft_status,
|
|
|
|
(date FAR *) & sftp->sft_date,
|
2002-02-16 20:20:20 +01:00
|
|
|
(time FAR *) & sftp->sft_time);
|
2002-08-04 03:14:18 +02:00
|
|
|
return sft_idx | ((long)status << 16);
|
2001-11-18 15:01:12 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2000-10-30 00:51:56 +01:00
|
|
|
/* /// Added for SHARE *** CURLY BRACES ADDED ALSO!!! ***. - Ron Cemer */
|
2001-11-18 15:01:12 +01:00
|
|
|
if (IsShareInstalled())
|
|
|
|
{
|
|
|
|
share_close_file(sftp->sft_shroff);
|
|
|
|
sftp->sft_shroff = -1;
|
2000-10-30 00:51:56 +01:00
|
|
|
}
|
|
|
|
/* /// End of additions for SHARE. - Ron Cemer */
|
2002-08-04 03:14:18 +02:00
|
|
|
return result;
|
|
|
|
}
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
long DosOpen(char FAR * fname, unsigned mode, unsigned attrib)
|
2001-07-23 14:47:42 +02:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
long result;
|
|
|
|
unsigned hndl;
|
|
|
|
|
|
|
|
/* test if mode is in range */
|
|
|
|
if ((mode & ~SFT_OMASK) != 0)
|
|
|
|
return DE_INVLDACC;
|
2002-02-16 20:20:20 +01:00
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
/* get a free handle */
|
2002-08-04 03:14:18 +02:00
|
|
|
if ((result = get_free_hndl()) < 0)
|
2001-07-23 14:47:42 +02:00
|
|
|
return result;
|
2002-08-04 03:14:18 +02:00
|
|
|
hndl = (unsigned)result;
|
2001-07-23 14:47:42 +02:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
result = DosOpenSft(fname, mode, attrib);
|
|
|
|
if (result < SUCCESS)
|
|
|
|
return result;
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
((psp FAR *)MK_FP(cu_psp, 0))->ps_filetab[hndl] = (UBYTE)result;
|
|
|
|
return hndl | (result & 0xffff0000l);
|
2001-07-23 14:47:42 +02:00
|
|
|
}
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
COUNT CloneHandle(unsigned hndl)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
/* now get the system file table entry */
|
2002-08-04 03:14:18 +02:00
|
|
|
sft FAR *sftp = get_sft(hndl);
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
if (sftp == (sft FAR *) -1 || (sftp->sft_mode & O_NOINHERIT))
|
|
|
|
return DE_INVLDHNDL;
|
|
|
|
|
2000-05-06 21:34:20 +02:00
|
|
|
/* now that we have the system file table entry, get the fnode */
|
|
|
|
/* index, and increment the count, so that we've effectively */
|
|
|
|
/* cloned the file. */
|
|
|
|
sftp->sft_count += 1;
|
|
|
|
return SUCCESS;
|
|
|
|
}
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
long DosDup(unsigned Handle)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
long NewHandle;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
if ((NewHandle = get_free_hndl()) < 0)
|
|
|
|
return NewHandle;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
if (DosForceDup(Handle, (unsigned)NewHandle) < 0)
|
2000-05-06 21:34:20 +02:00
|
|
|
return DE_INVLDHNDL;
|
2002-08-04 03:14:18 +02:00
|
|
|
else
|
|
|
|
return NewHandle;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
COUNT DosForceDup(unsigned OldHandle, unsigned NewHandle)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
psp FAR *p = MK_FP(cu_psp, 0);
|
|
|
|
sft FAR *Sftp;
|
|
|
|
|
|
|
|
/* Get the SFT block that contains the SFT */
|
|
|
|
if ((Sftp = get_sft(OldHandle)) == (sft FAR *) - 1)
|
|
|
|
return DE_INVLDHNDL;
|
|
|
|
|
|
|
|
/* now close the new handle if it's open */
|
|
|
|
if ((UBYTE) p->ps_filetab[NewHandle] != 0xff)
|
|
|
|
{
|
|
|
|
COUNT ret;
|
|
|
|
|
|
|
|
if ((ret = DosClose(NewHandle)) != SUCCESS)
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If everything looks ok, bump it up. */
|
2001-11-18 15:01:12 +01:00
|
|
|
if ((Sftp->sft_flags & (SFT_FDEVICE | SFT_FSHARED))
|
|
|
|
|| (Sftp->sft_status >= 0))
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
p->ps_filetab[NewHandle] = p->ps_filetab[OldHandle];
|
2002-08-04 03:14:18 +02:00
|
|
|
/* possible hazard: integer overflow ska*/
|
2000-05-06 21:34:20 +02:00
|
|
|
Sftp->sft_count += 1;
|
2002-08-04 03:14:18 +02:00
|
|
|
return SUCCESS;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
return DE_INVLDHNDL;
|
|
|
|
}
|
|
|
|
|
2002-10-22 04:40:19 +02:00
|
|
|
COUNT DosCloseSft(int sft_idx, BOOL commitonly)
|
2001-07-23 14:47:42 +02:00
|
|
|
{
|
2001-11-04 20:47:39 +01:00
|
|
|
sft FAR *sftp = idx_to_sft(sft_idx);
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
if (FP_OFF(sftp) == (size_t) - 1)
|
2000-05-06 21:34:20 +02:00
|
|
|
return DE_INVLDHNDL;
|
|
|
|
|
2001-11-04 20:47:39 +01:00
|
|
|
lpCurSft = sftp;
|
2000-05-06 21:34:20 +02:00
|
|
|
/*
|
|
|
|
remote sub sft_count.
|
|
|
|
*/
|
2001-11-04 20:47:39 +01:00
|
|
|
if (sftp->sft_flags & SFT_FSHARED)
|
2001-11-18 15:01:12 +01:00
|
|
|
{
|
2001-11-04 20:47:39 +01:00
|
|
|
/* printf("closing SFT %d = %p\n",sft_idx,sftp); */
|
2002-01-23 23:29:41 +01:00
|
|
|
return (commitonly ? remote_commit(sftp) : remote_close(sftp));
|
2001-11-18 15:01:12 +01:00
|
|
|
}
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* now just drop the count if a device, else */
|
|
|
|
/* call file system handler */
|
2002-01-23 23:29:41 +01:00
|
|
|
if (!commitonly)
|
|
|
|
sftp->sft_count -= 1;
|
|
|
|
|
2001-11-04 20:47:39 +01:00
|
|
|
if (sftp->sft_flags & SFT_FDEVICE)
|
2000-05-06 21:34:20 +02:00
|
|
|
return SUCCESS;
|
2002-01-23 23:29:41 +01:00
|
|
|
|
|
|
|
if (commitonly)
|
|
|
|
return dos_commit(sftp->sft_status);
|
|
|
|
|
|
|
|
if (sftp->sft_count > 0)
|
|
|
|
return SUCCESS;
|
|
|
|
|
2000-10-30 00:51:56 +01:00
|
|
|
/* /// Added for SHARE *** CURLY BRACES ADDED ALSO!!! ***. - Ron Cemer */
|
2002-01-23 23:29:41 +01:00
|
|
|
if (IsShareInstalled())
|
|
|
|
{
|
|
|
|
if (sftp->sft_shroff >= 0)
|
|
|
|
share_close_file(sftp->sft_shroff);
|
|
|
|
sftp->sft_shroff = -1;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
2002-01-23 23:29:41 +01:00
|
|
|
/* /// End of additions for SHARE. - Ron Cemer */
|
|
|
|
return dos_close(sftp->sft_status);
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
COUNT DosClose(COUNT hndl)
|
|
|
|
{
|
|
|
|
psp FAR *p = MK_FP(cu_psp, 0);
|
|
|
|
COUNT ret;
|
|
|
|
|
|
|
|
/* Get the SFT block that contains the SFT */
|
2002-01-23 23:29:41 +01:00
|
|
|
ret = DosCloseSft(get_sft_idx(hndl), FALSE);
|
2001-07-23 14:47:42 +02:00
|
|
|
if (ret != DE_INVLDHNDL && ret != DE_ACCESS)
|
|
|
|
p->ps_filetab[hndl] = 0xff;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
BOOL DosGetFree(UBYTE drive, UWORD * spc, UWORD * navc,
|
|
|
|
UWORD * bps, UWORD * nc)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-10-22 04:40:19 +02:00
|
|
|
/* navc==NULL means: called from FatGetDrvData, fcbfns.c */
|
2001-04-15 05:21:50 +02:00
|
|
|
struct dpb FAR *dpbp;
|
2000-05-06 21:34:20 +02:00
|
|
|
struct cds FAR *cdsp;
|
2001-11-18 15:01:12 +01:00
|
|
|
COUNT rg[4];
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* next - "log" in the drive */
|
|
|
|
drive = (drive == 0 ? default_drive : drive - 1);
|
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
/* first check for valid drive */
|
2001-04-15 05:21:50 +02:00
|
|
|
*spc = -1;
|
2002-10-22 04:40:19 +02:00
|
|
|
cdsp = get_cds(drive);
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2002-10-22 04:40:19 +02:00
|
|
|
if (cdsp == NULL)
|
2001-11-18 15:01:12 +01:00
|
|
|
return FALSE;
|
|
|
|
|
2001-04-15 05:21:50 +02:00
|
|
|
if (cdsp->cdsFlags & CDSNETWDRV)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-05-09 00:49:35 +02:00
|
|
|
if (remote_getfree(cdsp, rg) != SUCCESS)
|
2001-11-18 15:01:12 +01:00
|
|
|
return FALSE;
|
|
|
|
|
2002-05-09 00:49:35 +02:00
|
|
|
/* for int21/ah=1c:
|
|
|
|
Undoc DOS says, its not supported for
|
|
|
|
network drives. so it's probably OK */
|
|
|
|
/* some programs such as RHIDE want it though and
|
|
|
|
the redirector can provide all info
|
|
|
|
- Bart, 2002 Apr 1 */
|
|
|
|
|
2002-10-22 04:40:19 +02:00
|
|
|
if (navc != NULL)
|
2002-05-09 00:49:35 +02:00
|
|
|
{
|
|
|
|
*navc = (COUNT) rg[3];
|
2002-10-22 04:40:19 +02:00
|
|
|
*spc &= 0xff; /* zero out media ID byte */
|
2002-05-09 00:49:35 +02:00
|
|
|
}
|
2001-11-18 15:01:12 +01:00
|
|
|
|
|
|
|
*spc = (COUNT) rg[0];
|
|
|
|
*nc = (COUNT) rg[1];
|
|
|
|
*bps = (COUNT) rg[2];
|
|
|
|
return TRUE;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
dpbp = cdsp->cdsDpb;
|
2001-11-14 00:36:45 +01:00
|
|
|
if (dpbp == NULL)
|
2001-11-18 15:01:12 +01:00
|
|
|
return FALSE;
|
2001-11-14 00:36:45 +01:00
|
|
|
|
2002-10-22 04:40:19 +02:00
|
|
|
if (navc == NULL)
|
2001-11-14 00:36:45 +01:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
/* hazard: no error checking! */
|
2001-11-18 15:01:12 +01:00
|
|
|
flush_buffers(dpbp->dpb_unit);
|
|
|
|
dpbp->dpb_flags = M_CHANGED;
|
2001-11-14 00:36:45 +01:00
|
|
|
}
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2001-11-14 00:36:45 +01:00
|
|
|
if (media_check(dpbp) < 0)
|
2001-11-18 15:01:12 +01:00
|
|
|
return FALSE;
|
2001-09-23 22:39:44 +02:00
|
|
|
/* get the data available from dpb */
|
2002-10-22 04:40:19 +02:00
|
|
|
*spc = (dpbp->dpb_clsmask + 1);
|
2000-05-06 21:34:20 +02:00
|
|
|
*bps = dpbp->dpb_secsize;
|
|
|
|
|
|
|
|
/* now tell fs to give us free cluster */
|
|
|
|
/* count */
|
2001-11-04 20:47:39 +01:00
|
|
|
#ifdef WITHFAT32
|
|
|
|
if (ISFAT32(dpbp))
|
|
|
|
{
|
|
|
|
ULONG cluster_size, ntotal, nfree;
|
|
|
|
|
|
|
|
/* we shift ntotal until it is equal to or below 0xfff6 */
|
2001-11-18 15:01:12 +01:00
|
|
|
cluster_size = (ULONG) dpbp->dpb_secsize << dpbp->dpb_shftcnt;
|
2001-11-04 20:47:39 +01:00
|
|
|
ntotal = dpbp->dpb_xsize - 1;
|
2002-10-22 04:40:19 +02:00
|
|
|
if (navc != NULL)
|
2001-11-18 15:01:12 +01:00
|
|
|
nfree = dos_free(dpbp);
|
2001-11-04 20:47:39 +01:00
|
|
|
while (ntotal > FAT_MAGIC16 && cluster_size < 0x8000)
|
|
|
|
{
|
|
|
|
cluster_size <<= 1;
|
|
|
|
*spc <<= 1;
|
|
|
|
ntotal >>= 1;
|
|
|
|
nfree >>= 1;
|
|
|
|
}
|
|
|
|
/* get the data available from dpb */
|
2001-11-18 15:01:12 +01:00
|
|
|
*nc = ntotal > FAT_MAGIC16 ? FAT_MAGIC16 : (UCOUNT) ntotal;
|
2001-11-04 20:47:39 +01:00
|
|
|
|
|
|
|
/* now tell fs to give us free cluster */
|
|
|
|
/* count */
|
2002-10-22 04:40:19 +02:00
|
|
|
if (navc != NULL)
|
|
|
|
*navc = nfree > FAT_MAGIC16 ? FAT_MAGIC16 : (UCOUNT) nfree;
|
2001-11-14 00:36:45 +01:00
|
|
|
return TRUE;
|
2001-11-04 20:47:39 +01:00
|
|
|
}
|
2001-09-23 22:39:44 +02:00
|
|
|
#endif
|
2001-11-14 00:36:45 +01:00
|
|
|
/* a passed nc of 0xffff means: skip free; see FatGetDrvData
|
|
|
|
fcbfns.c */
|
2001-11-18 15:01:12 +01:00
|
|
|
if (*nc != 0xffff)
|
|
|
|
*navc = (COUNT) dos_free(dpbp);
|
2001-11-14 00:36:45 +01:00
|
|
|
*nc = dpbp->dpb_size - 1;
|
2001-11-18 15:01:12 +01:00
|
|
|
if (*spc > 64)
|
|
|
|
{
|
|
|
|
/* fake for 64k clusters do confuse some DOS programs, but let
|
|
|
|
others work without overflowing */
|
2001-11-14 00:36:45 +01:00
|
|
|
*spc >>= 1;
|
2002-08-04 03:14:18 +02:00
|
|
|
*navc = ((unsigned)*navc < FAT_MAGIC16 / 2) ? ((unsigned)*navc << 1) : FAT_MAGIC16;
|
|
|
|
*nc = ((unsigned)*nc < FAT_MAGIC16 / 2) ? ((unsigned)*nc << 1) : FAT_MAGIC16;
|
2001-11-14 00:36:45 +01:00
|
|
|
}
|
|
|
|
return TRUE;
|
2001-09-23 22:39:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef WITHFAT32
|
|
|
|
/* network names like \\SERVER\C aren't supported yet */
|
|
|
|
#define IS_SLASH(ch) (ch == '\\' || ch == '/')
|
2001-11-18 15:01:12 +01:00
|
|
|
COUNT DosGetExtFree(BYTE FAR * DriveString, struct xfreespace FAR * xfsp)
|
2001-09-23 22:39:44 +02:00
|
|
|
{
|
|
|
|
struct dpb FAR *dpbp;
|
|
|
|
struct cds FAR *cdsp;
|
2001-11-18 15:01:12 +01:00
|
|
|
UCOUNT rg[4];
|
2001-09-23 22:39:44 +02:00
|
|
|
|
|
|
|
if (IS_SLASH(DriveString[0]) || !IS_SLASH(DriveString[2])
|
2001-11-18 15:01:12 +01:00
|
|
|
|| DriveString[1] != ':')
|
|
|
|
return DE_INVLDDRV;
|
2001-09-23 22:39:44 +02:00
|
|
|
|
2002-10-22 04:40:19 +02:00
|
|
|
cdsp = get_cds(DosUpFChar(*DriveString) - 'A');
|
2001-09-23 22:39:44 +02:00
|
|
|
|
2002-10-22 04:40:19 +02:00
|
|
|
if (cdsp == NULL)
|
2001-11-18 15:01:12 +01:00
|
|
|
return DE_INVLDDRV;
|
|
|
|
|
2001-09-23 22:39:44 +02:00
|
|
|
if (cdsp->cdsFlags & CDSNETWDRV)
|
|
|
|
{
|
2001-11-18 15:01:12 +01:00
|
|
|
remote_getfree(cdsp, rg);
|
|
|
|
|
|
|
|
xfsp->xfs_clussize = rg[0];
|
|
|
|
xfsp->xfs_totalclusters = rg[1];
|
|
|
|
xfsp->xfs_secsize = rg[2];
|
|
|
|
xfsp->xfs_freeclusters = rg[3];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2002-10-22 04:40:19 +02:00
|
|
|
dpbp = cdsp->cdsDpb;
|
2001-11-18 15:01:12 +01:00
|
|
|
if (dpbp == NULL || media_check(dpbp) < 0)
|
2001-09-23 22:39:44 +02:00
|
|
|
return DE_INVLDDRV;
|
2001-11-18 15:01:12 +01:00
|
|
|
xfsp->xfs_secsize = dpbp->dpb_secsize;
|
|
|
|
xfsp->xfs_totalclusters =
|
|
|
|
(ISFAT32(dpbp) ? dpbp->dpb_xsize : dpbp->dpb_size);
|
|
|
|
xfsp->xfs_freeclusters = dos_free(dpbp);
|
|
|
|
xfsp->xfs_clussize = dpbp->dpb_clsmask + 1;
|
|
|
|
}
|
|
|
|
xfsp->xfs_totalunits = xfsp->xfs_totalclusters;
|
|
|
|
xfsp->xfs_freeunits = xfsp->xfs_freeclusters;
|
|
|
|
xfsp->xfs_totalsectors = xfsp->xfs_totalclusters * xfsp->xfs_clussize;
|
|
|
|
xfsp->xfs_freesectors = xfsp->xfs_freeclusters * xfsp->xfs_clussize;
|
|
|
|
xfsp->xfs_datasize = sizeof(struct xfreespace);
|
|
|
|
|
|
|
|
fmemset(xfsp->xfs_reserved, 0, 8);
|
2001-09-23 22:39:44 +02:00
|
|
|
|
|
|
|
return SUCCESS;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
2001-09-23 22:39:44 +02:00
|
|
|
#endif
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2001-04-15 05:21:50 +02:00
|
|
|
COUNT DosGetCuDir(UBYTE drive, BYTE FAR * s)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
BYTE *cp;
|
|
|
|
struct cds FAR *cdsp;
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2000-05-06 21:34:20 +02:00
|
|
|
/* next - "log" in the drive */
|
2001-04-15 05:21:50 +02:00
|
|
|
/* first check for valid drive */
|
2002-10-22 04:40:19 +02:00
|
|
|
cdsp = get_cds(drive == 0 ? default_drive : drive - 1);
|
|
|
|
if (cdsp == NULL)
|
2002-08-04 03:14:18 +02:00
|
|
|
return DE_INVLDDRV;
|
|
|
|
|
|
|
|
fmemcpy(&TempCDS, cdsp, sizeof(TempCDS));
|
|
|
|
cp = TempCDS.cdsCurrentPath;
|
2002-08-03 03:48:49 +02:00
|
|
|
/* ensure termination of fstrcpy */
|
|
|
|
cp[MAX_CDSPATH - 1] = '\0';
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
if ((TempCDS.cdsFlags & CDSNETWDRV) == 0)
|
2002-05-09 00:49:35 +02:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
/* dos_cd ensures that the path exists; if not, we
|
|
|
|
need to change to the root directory */
|
2002-10-22 04:40:19 +02:00
|
|
|
int result = dos_cd(cp);
|
2002-08-04 03:14:18 +02:00
|
|
|
if (result == DE_PATHNOTFND)
|
|
|
|
cp[TempCDS.cdsBackslashOffset + 1] =
|
|
|
|
cdsp->cdsCurrentPath[TempCDS.cdsBackslashOffset + 1] = '\0';
|
|
|
|
else if (result < SUCCESS)
|
|
|
|
return result;
|
2002-05-09 00:49:35 +02:00
|
|
|
}
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
cp += TempCDS.cdsBackslashOffset;
|
2001-07-28 20:13:06 +02:00
|
|
|
if (*cp == '\0')
|
2001-11-18 15:01:12 +01:00
|
|
|
s[0] = '\0';
|
2001-07-28 20:13:06 +02:00
|
|
|
else
|
2002-08-03 03:51:15 +02:00
|
|
|
fstrcpy(s, cp + 1);
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
return SUCCESS;
|
|
|
|
}
|
|
|
|
|
2000-05-08 06:30:00 +02:00
|
|
|
#undef CHDIR_DEBUG
|
2000-05-06 21:34:20 +02:00
|
|
|
COUNT DosChangeDir(BYTE FAR * s)
|
|
|
|
{
|
2001-11-18 15:01:12 +01:00
|
|
|
COUNT result;
|
|
|
|
BYTE FAR *p;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
/* don't do wildcard CHDIR --TE */
|
|
|
|
for (p = s; *p; p++)
|
|
|
|
if (*p == '*' || *p == '?')
|
|
|
|
return DE_PATHNOTFND;
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
result = truename(s, PriPathName, CDS_MODE_CHECK_DEV_PATH);
|
|
|
|
if (result < SUCCESS)
|
2001-11-18 15:01:12 +01:00
|
|
|
{
|
|
|
|
return result;
|
|
|
|
}
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2003-06-16 00:06:03 +02:00
|
|
|
if ((FP_OFF(current_ldt) != 0xFFFF) &&
|
|
|
|
(strlen(PriPathName) > sizeof(current_ldt->cdsCurrentPath) - 1))
|
2001-09-26 03:06:05 +02:00
|
|
|
return DE_PATHNOTFND;
|
|
|
|
|
2000-05-08 06:30:00 +02:00
|
|
|
#if defined(CHDIR_DEBUG)
|
2001-11-18 15:01:12 +01:00
|
|
|
printf("Remote Chdir: n='%Fs' p='%Fs\n", s, PriPathName);
|
2000-05-08 06:30:00 +02:00
|
|
|
#endif
|
2001-11-04 20:47:39 +01:00
|
|
|
/* now get fs to change to new */
|
2001-11-18 15:01:12 +01:00
|
|
|
/* directory */
|
2002-10-22 04:40:19 +02:00
|
|
|
result = (result & IS_NETWORK ? remote_chdir() : dos_cd(PriPathName));
|
2000-05-08 06:30:00 +02:00
|
|
|
#if defined(CHDIR_DEBUG)
|
2001-11-04 20:47:39 +01:00
|
|
|
printf("status = %04x, new_path='%Fs'\n", result, cdsd->cdsCurrentPath);
|
2000-05-08 06:30:00 +02:00
|
|
|
#endif
|
2001-11-04 20:47:39 +01:00
|
|
|
if (result != SUCCESS)
|
2001-11-18 15:01:12 +01:00
|
|
|
return result;
|
2000-05-08 06:30:00 +02:00
|
|
|
/*
|
2001-11-04 20:47:39 +01:00
|
|
|
Copy the path to the current directory
|
|
|
|
structure.
|
|
|
|
|
2002-02-16 20:20:20 +01:00
|
|
|
Some redirectors do not write back to the CDS.
|
|
|
|
SHSUCdX needs this. jt
|
2000-05-08 06:30:00 +02:00
|
|
|
*/
|
2001-11-18 15:01:12 +01:00
|
|
|
fstrcpy(current_ldt->cdsCurrentPath, PriPathName);
|
2003-06-16 00:06:03 +02:00
|
|
|
if (FP_OFF(current_ldt) != 0xFFFF)
|
|
|
|
{
|
|
|
|
fstrcpy(current_ldt->cdsCurrentPath, PriPathName);
|
|
|
|
if (PriPathName[7] == 0)
|
|
|
|
current_ldt->cdsCurrentPath[8] = 0; /* Need two Zeros at the end */
|
|
|
|
}
|
2001-11-04 20:47:39 +01:00
|
|
|
return SUCCESS;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2001-07-24 18:56:29 +02:00
|
|
|
STATIC VOID pop_dmp(dmatch FAR * dmp)
|
|
|
|
{
|
|
|
|
dmp->dm_attr_fnd = (BYTE) SearchDir.dir_attrib;
|
|
|
|
dmp->dm_time = SearchDir.dir_time;
|
|
|
|
dmp->dm_date = SearchDir.dir_date;
|
|
|
|
dmp->dm_size = (LONG) SearchDir.dir_size;
|
2001-11-18 15:01:12 +01:00
|
|
|
ConvertName83ToNameSZ(dmp->dm_name, (BYTE FAR *) SearchDir.dir_name);
|
2001-07-24 18:56:29 +02:00
|
|
|
}
|
|
|
|
|
2000-05-06 21:34:20 +02:00
|
|
|
COUNT DosFindFirst(UCOUNT attr, BYTE FAR * name)
|
|
|
|
{
|
2002-10-22 04:40:19 +02:00
|
|
|
int rc;
|
|
|
|
register dmatch FAR *dmp = dta;
|
2002-08-04 03:14:18 +02:00
|
|
|
|
2003-03-12 07:50:33 +01:00
|
|
|
rc = truename(name, PriPathName,
|
|
|
|
CDS_MODE_CHECK_DEV_PATH | CDS_MODE_ALLOW_WILDCARDS);
|
2002-08-04 03:14:18 +02:00
|
|
|
if (rc < SUCCESS)
|
|
|
|
return rc;
|
2001-04-29 19:34:41 +02:00
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
/* /// Added code here to do matching against device names.
|
|
|
|
DOS findfirst will match exact device names if the
|
|
|
|
filename portion (excluding the extension) contains
|
|
|
|
a valid device name.
|
|
|
|
Credits: some of this code was ripped off from truename()
|
|
|
|
in newstuff.c.
|
|
|
|
- Ron Cemer */
|
2001-04-29 19:34:41 +02:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
fmemset(dmp, 0, sizeof(dmatch));
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2001-07-28 20:13:06 +02:00
|
|
|
/* initially mark the dta as invalid for further findnexts */
|
2002-08-04 03:14:18 +02:00
|
|
|
dmp->dm_attr_fnd = D_DEVICE;
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2001-07-24 18:56:29 +02:00
|
|
|
memset(&SearchDir, 0, sizeof(struct dirent));
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
SAttr = (BYTE) attr;
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
#if defined(FIND_DEBUG)
|
|
|
|
printf("Remote Find: n='%Fs\n", PriPathName);
|
|
|
|
#endif
|
|
|
|
|
2002-10-22 04:40:19 +02:00
|
|
|
fmemcpy(&sda_tmp_dm, dta, 21);
|
|
|
|
dta = &sda_tmp_dm;
|
2002-08-04 03:14:18 +02:00
|
|
|
|
|
|
|
if (rc & IS_NETWORK)
|
|
|
|
rc = remote_findfirst(current_ldt);
|
|
|
|
else if (rc & IS_DEVICE)
|
2001-04-29 19:34:41 +02:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
const char *p;
|
2001-07-24 18:56:29 +02:00
|
|
|
COUNT i;
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2001-04-29 19:34:41 +02:00
|
|
|
/* Found a matching device. Hence there cannot be wildcards. */
|
2001-07-24 18:56:29 +02:00
|
|
|
SearchDir.dir_attrib = D_DEVICE;
|
|
|
|
SearchDir.dir_time = dos_gettime();
|
|
|
|
SearchDir.dir_date = dos_getdate();
|
2002-08-04 03:14:18 +02:00
|
|
|
p = (char *)FP_OFF(get_root(PriPathName));
|
2001-11-18 15:01:12 +01:00
|
|
|
memset(SearchDir.dir_name, ' ', FNAME_SIZE + FEXT_SIZE);
|
2001-07-24 18:56:29 +02:00
|
|
|
for (i = 0; i < FNAME_SIZE && *p && *p != '.'; i++)
|
2001-11-18 15:01:12 +01:00
|
|
|
SearchDir.dir_name[i] = *p++;
|
2002-08-04 03:14:18 +02:00
|
|
|
rc = SUCCESS;
|
|
|
|
/* /// End of additions. - Ron Cemer ; heavily edited - Bart Oldeman */
|
2001-04-29 19:34:41 +02:00
|
|
|
}
|
2002-08-04 03:14:18 +02:00
|
|
|
else
|
|
|
|
rc = dos_findfirst(attr, PriPathName);
|
2001-07-24 18:56:29 +02:00
|
|
|
|
2002-10-22 04:40:19 +02:00
|
|
|
dta = dmp;
|
|
|
|
fmemcpy(dta, &sda_tmp_dm, 21);
|
2002-08-04 03:14:18 +02:00
|
|
|
pop_dmp(dmp);
|
2001-11-18 15:01:12 +01:00
|
|
|
if (rc != SUCCESS)
|
2002-08-04 03:14:18 +02:00
|
|
|
dmp->dm_attr_fnd = D_DEVICE; /* mark invalid */
|
2001-07-28 20:13:06 +02:00
|
|
|
return rc;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
COUNT DosFindNext(void)
|
|
|
|
{
|
2001-07-24 18:56:29 +02:00
|
|
|
COUNT rc;
|
2002-10-22 04:40:19 +02:00
|
|
|
register dmatch FAR *dmp = dta;
|
2001-04-29 19:34:41 +02:00
|
|
|
|
2003-03-13 00:29:08 +01:00
|
|
|
/* /// findnext will always fail on a device name device name or volume id */
|
|
|
|
if (dmp->dm_attr_fnd == D_DEVICE || dmp->dm_attr_fnd & D_VOLID)
|
2001-11-18 15:01:12 +01:00
|
|
|
return DE_NFILES;
|
2001-04-29 19:34:41 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The new version of SHSUCDX 1.0 looks at the dm_drive byte to
|
|
|
|
* test 40h. I used RamView to see location MSD 116:04be and
|
|
|
|
* FD f??:04be, the byte set with 0xc4 = Remote/Network drive 4.
|
|
|
|
* Ralf Brown docs for dos 4eh say bit 7 set == remote so what is
|
|
|
|
* bit 6 for?
|
|
|
|
* SHSUCDX Mod info say "test redir not network bit".
|
|
|
|
* Just to confuse the rest, MSCDEX sets bit 5 too.
|
|
|
|
*
|
|
|
|
* So, assume bit 6 is redirector and bit 7 is network.
|
|
|
|
* jt
|
|
|
|
* Bart: dm_drive can be the drive _letter_.
|
|
|
|
* but better just stay independent of it: we only use
|
|
|
|
* bit 7 to detect a network drive; the rest untouched.
|
|
|
|
* RBIL says that findnext can only return one error type anyway
|
|
|
|
* (12h, DE_NFILES)
|
|
|
|
*/
|
|
|
|
#if 0
|
2002-10-22 04:40:19 +02:00
|
|
|
printf("findnext: %d\n", dmp->dm_drive);
|
2001-04-29 19:34:41 +02:00
|
|
|
#endif
|
2002-10-22 04:40:19 +02:00
|
|
|
fmemcpy(&sda_tmp_dm, dmp, 21);
|
|
|
|
fmemset(dmp, 0, sizeof(*dmp));
|
|
|
|
dta = &sda_tmp_dm;
|
|
|
|
rc = (sda_tmp_dm.dm_drive & 0x80) ?
|
|
|
|
remote_findnext(&sda_tmp_dm) : dos_findnext();
|
|
|
|
|
|
|
|
dta = dmp;
|
|
|
|
fmemcpy(dmp, &sda_tmp_dm, 21);
|
|
|
|
pop_dmp(dmp);
|
2001-07-28 20:13:06 +02:00
|
|
|
return rc;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
COUNT DosGetFtime(COUNT hndl, date * dp, time * tp)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
sft FAR *s;
|
2001-04-03 01:18:30 +02:00
|
|
|
/*sfttbl FAR *sp;*/
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* Get the SFT block that contains the SFT */
|
2002-08-04 03:14:18 +02:00
|
|
|
if (FP_OFF(s = get_sft(hndl)) == (size_t) - 1)
|
2000-05-06 21:34:20 +02:00
|
|
|
return DE_INVLDHNDL;
|
|
|
|
|
|
|
|
/* If SFT entry refers to a device, return the date and time of opening */
|
|
|
|
if (s->sft_flags & (SFT_FDEVICE | SFT_FSHARED))
|
|
|
|
{
|
|
|
|
*dp = s->sft_date;
|
|
|
|
*tp = s->sft_time;
|
|
|
|
return SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* call file system handler */
|
|
|
|
return dos_getftime(s->sft_status, dp, tp);
|
|
|
|
}
|
|
|
|
|
2002-10-22 04:40:19 +02:00
|
|
|
COUNT DosSetFtimeSft(int sft_idx, date dp, time tp)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
/* Get the SFT block that contains the SFT */
|
2001-07-23 14:47:42 +02:00
|
|
|
sft FAR *s = idx_to_sft(sft_idx);
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
if (FP_OFF(s) == (size_t) - 1)
|
2000-05-06 21:34:20 +02:00
|
|
|
return DE_INVLDHNDL;
|
|
|
|
|
|
|
|
/* If SFT entry refers to a device, do nothing */
|
|
|
|
if (s->sft_flags & SFT_FDEVICE)
|
|
|
|
return SUCCESS;
|
|
|
|
|
2001-08-19 14:58:36 +02:00
|
|
|
s->sft_flags |= SFT_FDATE;
|
|
|
|
s->sft_date = dp;
|
|
|
|
s->sft_time = tp;
|
|
|
|
|
2000-05-06 21:34:20 +02:00
|
|
|
if (s->sft_flags & SFT_FSHARED)
|
|
|
|
return SUCCESS;
|
|
|
|
|
|
|
|
/* call file system handler */
|
|
|
|
return dos_setftime(s->sft_status, dp, tp);
|
|
|
|
}
|
|
|
|
|
2001-07-22 03:58:58 +02:00
|
|
|
COUNT DosGetFattr(BYTE FAR * name)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
COUNT result;
|
2000-05-08 06:30:00 +02:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
result = truename(name, PriPathName, CDS_MODE_CHECK_DEV_PATH);
|
|
|
|
if (result < SUCCESS)
|
2001-11-18 15:01:12 +01:00
|
|
|
return result;
|
2002-08-04 03:14:18 +02:00
|
|
|
|
2000-08-06 07:50:17 +02:00
|
|
|
/* /// Added check for "d:\", which returns 0x10 (subdirectory) under DOS.
|
|
|
|
- Ron Cemer */
|
2002-08-04 03:14:18 +02:00
|
|
|
/* Theoretically: If the redirectory's qualify function
|
|
|
|
doesn't return nonsense this check can be reduced to
|
|
|
|
PriPathname[3] == 0, because local path names always
|
|
|
|
have the three-byte string ?:\ and UNC path shouldn't
|
|
|
|
validy consist of just two slashes.
|
|
|
|
-- 2001/09/03 ska*/
|
|
|
|
|
|
|
|
if (PriPathName[3] == '\0')
|
2001-11-18 15:01:12 +01:00
|
|
|
return 0x10;
|
2000-08-06 07:50:17 +02:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
if (result & IS_NETWORK)
|
2001-11-18 15:01:12 +01:00
|
|
|
return remote_getfattr();
|
2002-08-04 03:14:18 +02:00
|
|
|
|
|
|
|
if (result & IS_DEVICE)
|
|
|
|
return DE_FILENOTFND;
|
|
|
|
|
2000-08-06 07:50:17 +02:00
|
|
|
/* /// Use truename()'s result, which we already have in PriPathName.
|
|
|
|
I copy it to tmp_name because PriPathName is global and seems
|
|
|
|
to get trashed somewhere in transit.
|
|
|
|
The reason for using truename()'s result is that dos_?etfattr()
|
|
|
|
are very low-level functions and don't handle full path expansion
|
|
|
|
or cleanup, such as converting "c:\a\b\.\c\.." to "C:\A\B".
|
|
|
|
- Ron Cemer
|
|
|
|
*/
|
2001-06-03 16:16:18 +02:00
|
|
|
/*
|
2001-04-22 00:32:53 +02:00
|
|
|
memcpy(SecPathName,PriPathName,sizeof(SecPathName));
|
|
|
|
return dos_getfattr(SecPathName, attrp);
|
2001-06-03 16:16:18 +02:00
|
|
|
*/
|
|
|
|
/* no longer true. dos_getfattr() is
|
|
|
|
A) intelligent (uses dos_open) anyway
|
|
|
|
B) there are some problems with MAX_PARSE, i.e. if PATH ~= 64
|
2001-11-18 15:01:12 +01:00
|
|
|
and TRUENAME adds a C:, which leeds to trouble.
|
|
|
|
|
2001-06-03 16:16:18 +02:00
|
|
|
the problem was discovered, when VC did something like
|
2001-11-18 15:01:12 +01:00
|
|
|
|
|
|
|
fd = DosOpen(filename,...)
|
|
|
|
jc can't_copy_dialog;
|
|
|
|
|
|
|
|
attr = DosGetAttrib(filename);
|
|
|
|
jc can't_copy_dialog;
|
|
|
|
and suddenly, the filehandle stays open
|
|
|
|
shit.
|
|
|
|
tom
|
|
|
|
*/
|
2002-08-04 03:14:18 +02:00
|
|
|
return dos_getfattr(PriPathName);
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
/* This function is almost identical to DosGetFattr().
|
|
|
|
Maybe it is nice to join both functions.
|
|
|
|
-- 2001/09/03 ska*/
|
2001-07-22 03:58:58 +02:00
|
|
|
COUNT DosSetFattr(BYTE FAR * name, UWORD attrp)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
COUNT result;
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
result = truename(name, PriPathName, CDS_MODE_CHECK_DEV_PATH);
|
|
|
|
if (result < SUCCESS)
|
2001-11-18 15:01:12 +01:00
|
|
|
return result;
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
if (result & IS_NETWORK)
|
2001-11-18 15:01:12 +01:00
|
|
|
return remote_setfattr(attrp);
|
2002-08-04 03:14:18 +02:00
|
|
|
|
|
|
|
if (result & IS_DEVICE)
|
|
|
|
return DE_FILENOTFND;
|
|
|
|
|
2000-08-06 07:50:17 +02:00
|
|
|
/* /// Use truename()'s result, which we already have in PriPathName.
|
|
|
|
I copy it to tmp_name because PriPathName is global and seems
|
|
|
|
to get trashed somewhere in transit.
|
|
|
|
- Ron Cemer
|
|
|
|
*/
|
2001-06-03 16:16:18 +02:00
|
|
|
/*
|
2001-04-22 00:32:53 +02:00
|
|
|
memcpy(SecPathName,PriPathName,sizeof(SecPathName));
|
|
|
|
return dos_setfattr(SecPathName, attrp);
|
2001-06-03 16:16:18 +02:00
|
|
|
|
|
|
|
see DosGetAttr()
|
2001-11-18 15:01:12 +01:00
|
|
|
*/
|
2002-08-04 03:14:18 +02:00
|
|
|
return dos_setfattr(PriPathName, attrp);
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2001-04-15 05:21:50 +02:00
|
|
|
UBYTE DosSelectDrv(UBYTE drv)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2002-10-22 04:40:19 +02:00
|
|
|
current_ldt = get_cds(drv);
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2002-10-22 04:40:19 +02:00
|
|
|
if (current_ldt != NULL)
|
2000-05-06 21:34:20 +02:00
|
|
|
default_drive = drv;
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2000-05-06 21:34:20 +02:00
|
|
|
return lastdrive;
|
|
|
|
}
|
|
|
|
|
2002-02-16 20:20:20 +01:00
|
|
|
COUNT DosDelete(BYTE FAR * path, int attrib)
|
2000-05-08 06:30:00 +02:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
COUNT result;
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
result = truename(path, PriPathName, CDS_MODE_CHECK_DEV_PATH);
|
|
|
|
if (result < SUCCESS)
|
2001-11-18 15:01:12 +01:00
|
|
|
return result;
|
2002-08-04 03:14:18 +02:00
|
|
|
|
|
|
|
if (result & IS_NETWORK)
|
2001-11-18 15:01:12 +01:00
|
|
|
return remote_delete();
|
2002-08-04 03:14:18 +02:00
|
|
|
|
|
|
|
if (result & IS_DEVICE)
|
|
|
|
return DE_FILENOTFND;
|
|
|
|
|
|
|
|
return dos_delete(PriPathName, attrib);
|
2000-05-08 06:30:00 +02:00
|
|
|
}
|
|
|
|
|
2002-02-16 20:20:20 +01:00
|
|
|
COUNT DosRenameTrue(BYTE * path1, BYTE * path2, int attrib)
|
2000-05-08 06:30:00 +02:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
if (path1[0] != path2[0])
|
2001-11-18 15:01:12 +01:00
|
|
|
{
|
2003-03-23 19:41:36 +01:00
|
|
|
return DE_DEVICE; /* not same device */
|
2001-11-18 15:01:12 +01:00
|
|
|
}
|
2003-06-16 00:06:03 +02:00
|
|
|
if (FP_OFF(current_ldt) == 0xFFFF || (current_ldt->cdsFlags & CDSNETWDRV))
|
2001-11-18 15:01:12 +01:00
|
|
|
return remote_rename();
|
2002-08-04 03:14:18 +02:00
|
|
|
|
|
|
|
return dos_rename(path1, path2, attrib);
|
2001-07-23 14:47:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
COUNT DosRename(BYTE FAR * path1, BYTE FAR * path2)
|
|
|
|
{
|
2001-11-18 15:01:12 +01:00
|
|
|
COUNT result;
|
2001-07-23 14:47:42 +02:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
result = truename(path2, SecPathName, CDS_MODE_CHECK_DEV_PATH);
|
|
|
|
if (result < SUCCESS)
|
2001-11-18 15:01:12 +01:00
|
|
|
return result;
|
2001-07-23 14:47:42 +02:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
if (!(result & IS_NETWORK) && (result & IS_DEVICE))
|
|
|
|
return DE_FILENOTFND;
|
|
|
|
|
|
|
|
result = truename(path1, PriPathName, CDS_MODE_CHECK_DEV_PATH);
|
|
|
|
if (result < SUCCESS)
|
2001-11-18 15:01:12 +01:00
|
|
|
return result;
|
2002-08-04 03:14:18 +02:00
|
|
|
|
|
|
|
if (!(result & IS_NETWORK) && (result & IS_DEVICE))
|
|
|
|
return DE_FILENOTFND;
|
2001-07-23 14:47:42 +02:00
|
|
|
|
2002-02-16 20:20:20 +01:00
|
|
|
return DosRenameTrue(PriPathName, SecPathName, D_ALL);
|
2000-05-08 06:30:00 +02:00
|
|
|
}
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
COUNT DosMkdir(const char FAR * dir)
|
2000-05-08 06:30:00 +02:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
COUNT result;
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
result = truename(dir, PriPathName, CDS_MODE_CHECK_DEV_PATH);
|
|
|
|
if (result < SUCCESS)
|
2001-11-18 15:01:12 +01:00
|
|
|
return result;
|
2002-08-04 03:14:18 +02:00
|
|
|
|
|
|
|
if (result & IS_NETWORK)
|
2001-11-18 15:01:12 +01:00
|
|
|
return remote_mkdir();
|
2002-08-04 03:14:18 +02:00
|
|
|
|
|
|
|
if (result & IS_DEVICE)
|
|
|
|
return DE_ACCESS;
|
|
|
|
|
|
|
|
return dos_mkdir(PriPathName);
|
2000-05-08 06:30:00 +02:00
|
|
|
}
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
/* This function is almost identical to DosMkdir().
|
|
|
|
Maybe it would be nice to merge both functions.
|
|
|
|
-- 2001/09/03 ska*/
|
|
|
|
COUNT DosRmdir(const char FAR * dir)
|
2000-05-08 06:30:00 +02:00
|
|
|
{
|
2002-08-04 03:14:18 +02:00
|
|
|
COUNT result;
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
result = truename(dir, PriPathName, CDS_MODE_CHECK_DEV_PATH);
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
if (result < SUCCESS)
|
2001-11-18 15:01:12 +01:00
|
|
|
return result;
|
2002-08-04 03:14:18 +02:00
|
|
|
|
|
|
|
if (result & IS_NETWORK)
|
2001-11-18 15:01:12 +01:00
|
|
|
return remote_rmdir();
|
2002-08-04 03:14:18 +02:00
|
|
|
|
|
|
|
if (result & IS_DEVICE)
|
|
|
|
return DE_ACCESS;
|
|
|
|
|
|
|
|
return dos_rmdir(PriPathName);
|
2000-05-08 06:30:00 +02:00
|
|
|
}
|
2000-05-26 21:25:19 +02:00
|
|
|
|
2000-10-30 00:51:56 +01:00
|
|
|
/* /// Added for SHARE. - Ron Cemer */
|
|
|
|
|
|
|
|
COUNT DosLockUnlock(COUNT hndl, LONG pos, LONG len, COUNT unlock)
|
|
|
|
{
|
|
|
|
sft FAR *s;
|
|
|
|
|
|
|
|
/* Get the SFT block that contains the SFT */
|
2002-08-04 03:14:18 +02:00
|
|
|
if (FP_OFF(s = get_sft(hndl)) == (size_t) - 1)
|
2001-11-18 15:01:12 +01:00
|
|
|
return DE_INVLDHNDL;
|
2000-10-30 00:51:56 +01:00
|
|
|
|
2002-01-23 23:29:41 +01:00
|
|
|
if (s->sft_flags & SFT_FSHARED)
|
|
|
|
return remote_lock_unlock(s, pos, len, unlock);
|
|
|
|
|
|
|
|
/* Invalid function unless SHARE is installed or remote. */
|
|
|
|
if (!IsShareInstalled())
|
|
|
|
return DE_INVLDFUNC;
|
|
|
|
|
2000-10-30 00:51:56 +01:00
|
|
|
/* Lock violation if this SFT entry does not support locking. */
|
2001-11-18 15:01:12 +01:00
|
|
|
if (s->sft_shroff < 0)
|
|
|
|
return DE_LOCK;
|
2000-10-30 00:51:56 +01:00
|
|
|
|
|
|
|
/* Let SHARE do the work. */
|
|
|
|
return share_lock_unlock(cu_psp, s->sft_shroff, pos, len, unlock);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* /// End of additions for SHARE. - Ron Cemer */
|
|
|
|
|
2000-05-26 21:25:19 +02:00
|
|
|
/*
|
|
|
|
* This seems to work well.
|
|
|
|
*/
|
|
|
|
|
2002-02-16 20:20:20 +01:00
|
|
|
/* check for a device */
|
2002-08-04 03:14:18 +02:00
|
|
|
struct dhdr FAR *IsDevice(const char FAR * fname)
|
2000-05-26 21:25:19 +02:00
|
|
|
{
|
|
|
|
struct dhdr FAR *dhp;
|
2002-08-04 03:14:18 +02:00
|
|
|
const char FAR *froot = get_root(fname);
|
2002-02-16 20:20:20 +01:00
|
|
|
int i;
|
2000-08-06 07:50:17 +02:00
|
|
|
|
|
|
|
/* /// BUG!!! This is absolutely wrong. A filename of "NUL.LST" must be
|
|
|
|
treated EXACTLY the same as a filename of "NUL". The existence or
|
|
|
|
content of the extension is irrelevent in determining whether a
|
|
|
|
filename refers to a device.
|
|
|
|
- Ron Cemer
|
|
|
|
// if we have an extension, can't be a device <--- WRONG.
|
2000-05-26 21:25:19 +02:00
|
|
|
if (*froot != '.')
|
|
|
|
{
|
2000-08-06 07:50:17 +02:00
|
|
|
*/
|
2001-04-03 01:18:30 +02:00
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
for (dhp = (struct dhdr FAR *)&nul_dev; dhp != (struct dhdr FAR *)-1;
|
|
|
|
dhp = dhp->dh_next)
|
|
|
|
{
|
2001-04-03 01:18:30 +02:00
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
/* BUGFIX: MSCD000<00> should be handled like MSCD000<20> TE */
|
2001-04-03 01:18:30 +02:00
|
|
|
|
2002-02-16 20:20:20 +01:00
|
|
|
for (i = 0; i < FNAME_SIZE; i++)
|
2001-11-18 15:01:12 +01:00
|
|
|
{
|
2003-09-09 19:43:43 +02:00
|
|
|
unsigned char c1 = (unsigned char)froot[i];
|
2002-02-16 20:20:20 +01:00
|
|
|
if (c1 == '.' || c1 == '\0')
|
|
|
|
{
|
|
|
|
/* check if remainder of device name consists of spaces or nulls */
|
|
|
|
for (; i < FNAME_SIZE; i++)
|
|
|
|
{
|
2003-09-09 19:43:43 +02:00
|
|
|
unsigned char c2 = dhp->dh_name[i];
|
2002-02-16 20:20:20 +01:00
|
|
|
if (c2 != ' ' && c2 != '\0')
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (DosUpFChar(c1) != DosUpFChar(dhp->dh_name[i]))
|
|
|
|
break;
|
2000-05-26 21:25:19 +02:00
|
|
|
}
|
2002-02-16 20:20:20 +01:00
|
|
|
if (i == FNAME_SIZE)
|
|
|
|
return dhp;
|
2001-11-18 15:01:12 +01:00
|
|
|
}
|
2000-08-06 07:50:17 +02:00
|
|
|
|
2002-02-16 20:20:20 +01:00
|
|
|
return NULL;
|
2000-05-26 21:25:19 +02:00
|
|
|
}
|
|
|
|
|
2000-10-30 00:51:56 +01:00
|
|
|
/* /// Added for SHARE. - Ron Cemer */
|
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
BOOL IsShareInstalled(void)
|
|
|
|
{
|
|
|
|
if (!share_installed)
|
|
|
|
{
|
2000-10-30 00:51:56 +01:00
|
|
|
iregs regs;
|
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
regs.a.x = 0x1000;
|
2000-10-30 00:51:56 +01:00
|
|
|
intr(0x2f, ®s);
|
2001-11-18 15:01:12 +01:00
|
|
|
share_installed = ((regs.a.x & 0xff) == 0xff);
|
|
|
|
}
|
|
|
|
return share_installed;
|
2000-10-30 00:51:56 +01:00
|
|
|
}
|
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
/* DOS calls this to see if it's okay to open the file.
|
|
|
|
Returns a file_table entry number to use (>= 0) if okay
|
|
|
|
to open. Otherwise returns < 0 and may generate a critical
|
|
|
|
error. If < 0 is returned, it is the negated error return
|
|
|
|
code, so DOS simply negates this value and returns it in
|
|
|
|
AX. */
|
2002-08-04 03:14:18 +02:00
|
|
|
STATIC int share_open_check(char * filename, /* pointer to fully qualified filename */
|
2001-11-18 15:01:12 +01:00
|
|
|
unsigned short pspseg, /* psp segment address of owner process */
|
|
|
|
int openmode, /* 0=read-only, 1=write-only, 2=read-write */
|
|
|
|
int sharemode)
|
|
|
|
{ /* SHARE_COMPAT, etc... */
|
|
|
|
iregs regs;
|
|
|
|
|
|
|
|
regs.a.x = 0x10a0;
|
|
|
|
regs.ds = FP_SEG(filename);
|
|
|
|
regs.si = FP_OFF(filename);
|
|
|
|
regs.b.x = pspseg;
|
|
|
|
regs.c.x = openmode;
|
|
|
|
regs.d.x = sharemode;
|
|
|
|
intr(0x2f, ®s);
|
|
|
|
return (int)regs.a.x;
|
2000-10-30 00:51:56 +01:00
|
|
|
}
|
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
/* DOS calls this to record the fact that it has successfully
|
|
|
|
closed a file, or the fact that the open for this file failed. */
|
2002-01-23 23:29:41 +01:00
|
|
|
STATIC void share_close_file(int fileno)
|
2001-11-18 15:01:12 +01:00
|
|
|
{ /* file_table entry number */
|
|
|
|
iregs regs;
|
2000-10-30 00:51:56 +01:00
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
regs.a.x = 0x10a1;
|
|
|
|
regs.b.x = fileno;
|
|
|
|
intr(0x2f, ®s);
|
2000-10-30 00:51:56 +01:00
|
|
|
}
|
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
/* DOS calls this to determine whether it can access (read or
|
|
|
|
write) a specific section of a file. We call it internally
|
|
|
|
from lock_unlock (only when locking) to see if any portion
|
|
|
|
of the requested region is already locked. If pspseg is zero,
|
|
|
|
then it matches any pspseg in the lock table. Otherwise, only
|
|
|
|
locks which DO NOT belong to pspseg will be considered.
|
|
|
|
Returns zero if okay to access or lock (no portion of the
|
|
|
|
region is already locked). Otherwise returns non-zero and
|
|
|
|
generates a critical error (if allowcriter is non-zero).
|
|
|
|
If non-zero is returned, it is the negated return value for
|
|
|
|
the DOS call. */
|
2002-01-23 23:29:41 +01:00
|
|
|
STATIC int share_access_check(unsigned short pspseg, /* psp segment address of owner process */
|
2001-11-18 15:01:12 +01:00
|
|
|
int fileno, /* file_table entry number */
|
|
|
|
unsigned long ofs, /* offset into file */
|
|
|
|
unsigned long len, /* length (in bytes) of region to access */
|
|
|
|
int allowcriter)
|
|
|
|
{ /* allow a critical error to be generated */
|
|
|
|
iregs regs;
|
|
|
|
|
|
|
|
regs.a.x = 0x10a2 | (allowcriter ? 0x01 : 0x00);
|
|
|
|
regs.b.x = pspseg;
|
|
|
|
regs.c.x = fileno;
|
|
|
|
regs.si = (unsigned short)((ofs >> 16) & 0xffffL);
|
|
|
|
regs.di = (unsigned short)(ofs & 0xffffL);
|
|
|
|
regs.es = (unsigned short)((len >> 16) & 0xffffL);
|
|
|
|
regs.d.x = (unsigned short)(len & 0xffffL);
|
|
|
|
intr(0x2f, ®s);
|
|
|
|
return (int)regs.a.x;
|
|
|
|
}
|
2000-10-30 00:51:56 +01:00
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
/* DOS calls this to lock or unlock a specific section of a file.
|
|
|
|
Returns zero if successfully locked or unlocked. Otherwise
|
|
|
|
returns non-zero.
|
|
|
|
If the return value is non-zero, it is the negated error
|
|
|
|
return code for the DOS 0x5c call. */
|
2002-01-23 23:29:41 +01:00
|
|
|
STATIC int share_lock_unlock(unsigned short pspseg, /* psp segment address of owner process */
|
2001-11-18 15:01:12 +01:00
|
|
|
int fileno, /* file_table entry number */
|
|
|
|
unsigned long ofs, /* offset into file */
|
|
|
|
unsigned long len, /* length (in bytes) of region to lock or unlock */
|
|
|
|
int unlock)
|
|
|
|
{ /* non-zero to unlock; zero to lock */
|
|
|
|
iregs regs;
|
|
|
|
|
|
|
|
regs.a.x = 0x10a4 | (unlock ? 0x01 : 0x00);
|
|
|
|
regs.b.x = pspseg;
|
|
|
|
regs.c.x = fileno;
|
|
|
|
regs.si = (unsigned short)((ofs >> 16) & 0xffffL);
|
|
|
|
regs.di = (unsigned short)(ofs & 0xffffL);
|
|
|
|
regs.es = (unsigned short)((len >> 16) & 0xffffL);
|
|
|
|
regs.d.x = (unsigned short)(len & 0xffffL);
|
|
|
|
intr(0x2f, ®s);
|
|
|
|
return (int)regs.a.x;
|
2000-10-30 00:51:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* /// End of additions for SHARE. - Ron Cemer */
|
2002-01-23 23:29:41 +01:00
|
|
|
STATIC int remote_lock_unlock(sft FAR *sftp, /* SFT for file */
|
|
|
|
unsigned long ofs, /* offset into file */
|
|
|
|
unsigned long len, /* length (in bytes) of region to lock or unlock */
|
|
|
|
int unlock)
|
|
|
|
{ /* non-zero to unlock; zero to lock */
|
|
|
|
iregs regs;
|
|
|
|
unsigned long param_block[2];
|
|
|
|
param_block[0] = ofs;
|
|
|
|
param_block[1] = len;
|
|
|
|
|
|
|
|
regs.a.x = 0x110a;
|
|
|
|
regs.b.b.l = (unlock ? 0x01 : 0x00);
|
|
|
|
regs.c.x = 1;
|
|
|
|
regs.ds = FP_SEG(param_block);
|
|
|
|
regs.d.x = FP_OFF(param_block);
|
|
|
|
regs.es = FP_SEG(sftp);
|
|
|
|
regs.di = FP_OFF(sftp);
|
|
|
|
intr(0x2f, ®s);
|
|
|
|
return ((regs.flags & 1) ? -(int)regs.a.b.l : 0);
|
|
|
|
}
|
|
|
|
|
2002-08-04 03:14:18 +02:00
|
|
|
COUNT DosTruename(const char FAR *src, char FAR *dest)
|
|
|
|
{
|
|
|
|
/* RBIL: The buffer has be unchanged, if the call fails.
|
|
|
|
Therefore, the name is created in an internal buffer
|
|
|
|
and copied into the user buffer only on success.
|
|
|
|
*/
|
2003-03-12 07:50:33 +01:00
|
|
|
COUNT rc = truename(src, PriPathName, CDS_MODE_ALLOW_WILDCARDS);
|
2002-08-04 03:14:18 +02:00
|
|
|
if (rc >= SUCCESS)
|
|
|
|
fstrcpy(dest, PriPathName);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|