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"
|
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
COUNT get_free_hndl(VOID);
|
2002-01-23 23:29:41 +01:00
|
|
|
sft FAR * get_free_sft(COUNT *);
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2001-06-03 16:16:18 +02:00
|
|
|
f_node_ptr xlt_fd(COUNT);
|
2000-05-06 21:34:20 +02:00
|
|
|
|
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-01-23 23:29:41 +01:00
|
|
|
STATIC int share_open_check(char far * filename, /* far 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 */
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
drive = drive == 0 ? default_drive : drive - 1;
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2001-09-23 22:39:44 +02:00
|
|
|
if (drive >= lastdrive)
|
2001-11-18 15:01:12 +01:00
|
|
|
{
|
|
|
|
*rc = DE_INVLDDRV;
|
|
|
|
return 0;
|
|
|
|
}
|
2001-09-23 22:39:44 +02:00
|
|
|
|
2002-08-03 18:54:09 +02:00
|
|
|
dpb = CDSp[drive].cdsDpb;
|
|
|
|
if (dpb == 0 || CDSp[drive].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-01-23 23:29:41 +01:00
|
|
|
STATIC VOID DosGetFile(BYTE * lpszPath, BYTE FAR * lpszDosFileName)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
BYTE szLclName[FNAME_SIZE + 1];
|
|
|
|
BYTE szLclExt[FEXT_SIZE + 1];
|
|
|
|
|
|
|
|
ParseDosName(lpszPath, (COUNT *) 0, (BYTE *) 0,
|
|
|
|
szLclName, szLclExt, FALSE);
|
|
|
|
SpacePad(szLclName, FNAME_SIZE);
|
|
|
|
SpacePad(szLclExt, FEXT_SIZE);
|
2001-11-18 00:26:45 +01:00
|
|
|
fmemcpy(lpszDosFileName, (BYTE FAR *) szLclName, FNAME_SIZE);
|
|
|
|
fmemcpy(&lpszDosFileName[FNAME_SIZE], (BYTE FAR *) szLclExt, FEXT_SIZE);
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2002-01-23 23:29:41 +01:00
|
|
|
sft FAR * idx_to_sft(COUNT 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
|
|
|
|
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 */
|
2001-07-23 14:47:42 +02:00
|
|
|
return (sft FAR *) - 1;
|
|
|
|
}
|
|
|
|
|
2002-01-23 23:29:41 +01:00
|
|
|
COUNT get_sft_idx(UCOUNT hndl)
|
2001-07-23 14:47:42 +02:00
|
|
|
{
|
|
|
|
psp FAR *p = MK_FP(cu_psp, 0);
|
|
|
|
|
|
|
|
if (hndl >= p->ps_maxfiles)
|
|
|
|
return DE_INVLDHNDL;
|
|
|
|
|
|
|
|
return p->ps_filetab[hndl] == 0xff ? DE_INVLDHNDL : p->ps_filetab[hndl];
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The `force_binary' parameter is a hack to allow functions 0x01, 0x06, 0x07,
|
|
|
|
* and function 0x40 to use the same code for performing reads, even though the
|
|
|
|
* two classes of functions behave quite differently: 0x01 etc. always do
|
|
|
|
* binary reads, while for 0x40 the type of read (binary/text) depends on what
|
|
|
|
* the SFT says. -- ror4
|
|
|
|
*/
|
2001-11-18 15:01:12 +01:00
|
|
|
UCOUNT GenericReadSft(sft FAR * s, UCOUNT n, BYTE FAR * bp,
|
|
|
|
COUNT FAR * err, BOOL force_binary)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
UCOUNT ReadCount;
|
|
|
|
|
|
|
|
/* Get the SFT block that contains the SFT */
|
2001-11-04 20:47:39 +01:00
|
|
|
if (s == (sft FAR *) - 1)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
*err = DE_INVLDHNDL;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If not open or write permission - exit */
|
|
|
|
if (s->sft_count == 0 || (s->sft_mode & SFT_MWRITE))
|
|
|
|
{
|
|
|
|
*err = DE_INVLDACC;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
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)
|
|
|
|
{
|
2001-11-04 20:47:39 +01:00
|
|
|
COUNT rc;
|
|
|
|
BYTE FAR *save_dta;
|
|
|
|
|
|
|
|
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;
|
|
|
|
ReadCount = remote_read(s, n, &rc);
|
|
|
|
dta = save_dta;
|
|
|
|
*err = rc;
|
|
|
|
return rc == SUCCESS ? ReadCount : 0;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
/* Do a device read if device */
|
|
|
|
if (s->sft_flags & SFT_FDEVICE)
|
|
|
|
{
|
|
|
|
request rq;
|
|
|
|
|
|
|
|
/* First test for eof and exit */
|
|
|
|
/* immediately if it is */
|
|
|
|
if (!(s->sft_flags & SFT_FEOF) || (s->sft_flags & SFT_FNUL))
|
|
|
|
{
|
|
|
|
s->sft_flags &= ~SFT_FEOF;
|
|
|
|
*err = SUCCESS;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now handle raw and cooked modes */
|
|
|
|
if (force_binary || (s->sft_flags & SFT_FBINARY))
|
|
|
|
{
|
|
|
|
rq.r_length = sizeof(request);
|
|
|
|
rq.r_command = C_INPUT;
|
|
|
|
rq.r_count = n;
|
|
|
|
rq.r_trans = (BYTE FAR *) bp;
|
|
|
|
rq.r_status = 0;
|
|
|
|
execrh((request FAR *) & rq, s->sft_dev);
|
|
|
|
if (rq.r_status & S_ERROR)
|
|
|
|
{
|
|
|
|
char_error(&rq, s->sft_dev);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*err = SUCCESS;
|
|
|
|
return rq.r_count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (s->sft_flags & SFT_FCONIN)
|
|
|
|
{
|
|
|
|
kb_buf.kb_size = LINESIZE - 1;
|
2001-08-19 14:58:36 +02:00
|
|
|
ReadCount = sti(&kb_buf);
|
2001-04-22 00:32:53 +02:00
|
|
|
if (ReadCount < kb_buf.kb_count)
|
|
|
|
s->sft_flags &= ~SFT_FEOF;
|
2001-11-18 00:26:45 +01:00
|
|
|
fmemcpy(bp, (BYTE FAR *) kb_buf.kb_buf, kb_buf.kb_count);
|
2000-05-06 21:34:20 +02:00
|
|
|
*err = SUCCESS;
|
2001-04-22 00:32:53 +02:00
|
|
|
return ReadCount;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2001-08-19 14:58:36 +02:00
|
|
|
*bp = _sti(FALSE);
|
2000-05-06 21:34:20 +02:00
|
|
|
*err = SUCCESS;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
/* a block read */
|
|
|
|
{
|
2000-10-30 00:51:56 +01:00
|
|
|
/* /// Added for SHARE - Ron Cemer */
|
2001-11-18 15:01:12 +01:00
|
|
|
if (IsShareInstalled())
|
|
|
|
{
|
|
|
|
if (s->sft_shroff >= 0)
|
|
|
|
{
|
|
|
|
int share_result = share_access_check(cu_psp,
|
|
|
|
s->sft_shroff,
|
|
|
|
s->sft_posit,
|
|
|
|
(unsigned long)n,
|
|
|
|
1);
|
|
|
|
if (share_result != 0)
|
|
|
|
{
|
|
|
|
*err = share_result;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2000-10-30 00:51:56 +01:00
|
|
|
}
|
|
|
|
/* /// End of additions for SHARE - Ron Cemer */
|
|
|
|
|
2002-05-09 00:49:35 +02:00
|
|
|
ReadCount = rwblock(s->sft_status, bp, n, XFR_READ);
|
|
|
|
*err = SUCCESS;
|
|
|
|
return ReadCount;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
*err = SUCCESS;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2001-04-22 00:32:53 +02:00
|
|
|
#if 0
|
2000-05-06 21:34:20 +02:00
|
|
|
UCOUNT DosRead(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err)
|
|
|
|
{
|
|
|
|
return GenericRead(hndl, n, bp, err, FALSE);
|
|
|
|
}
|
2001-04-22 00:32:53 +02:00
|
|
|
#endif
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2002-02-16 20:20:20 +01:00
|
|
|
UCOUNT DosWriteSft(sft FAR * s, UCOUNT n, const BYTE FAR * bp, COUNT FAR * err)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2000-05-08 06:30:00 +02:00
|
|
|
UCOUNT WriteCount;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* Get the SFT block that contains the SFT */
|
2001-11-04 20:47:39 +01:00
|
|
|
if (s == (sft FAR *) - 1)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
*err = DE_INVLDHNDL;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If this is not opened and it's not a write */
|
|
|
|
/* another error */
|
|
|
|
if (s->sft_count == 0 ||
|
|
|
|
(!(s->sft_mode & SFT_MWRITE) && !(s->sft_mode & SFT_MRDWR)))
|
|
|
|
{
|
|
|
|
*err = DE_ACCESS;
|
|
|
|
return 0;
|
|
|
|
}
|
2000-05-26 21:25:19 +02:00
|
|
|
|
2000-05-06 21:34:20 +02:00
|
|
|
if (s->sft_flags & SFT_FSHARED)
|
|
|
|
{
|
2001-11-04 20:47:39 +01:00
|
|
|
COUNT rc;
|
|
|
|
BYTE FAR *save_dta;
|
|
|
|
|
|
|
|
save_dta = dta;
|
|
|
|
lpCurSft = s;
|
2001-11-18 15:01:12 +01:00
|
|
|
current_filepos = s->sft_posit; /* needed for MSCDEX */
|
2002-02-16 20:20:20 +01:00
|
|
|
dta = (BYTE FAR *)bp;
|
2001-11-04 20:47:39 +01:00
|
|
|
WriteCount = remote_write(s, n, &rc);
|
|
|
|
dta = save_dta;
|
|
|
|
*err = rc;
|
|
|
|
return rc == SUCCESS ? WriteCount : 0;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Do a device write if device */
|
|
|
|
if (s->sft_flags & SFT_FDEVICE)
|
|
|
|
{
|
|
|
|
request rq;
|
|
|
|
|
|
|
|
/* set to no EOF */
|
2001-04-22 00:32:53 +02:00
|
|
|
s->sft_flags |= SFT_FEOF;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* if null just report full transfer */
|
|
|
|
if (s->sft_flags & SFT_FNUL)
|
|
|
|
{
|
|
|
|
*err = SUCCESS;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now handle raw and cooked modes */
|
|
|
|
if (s->sft_flags & SFT_FBINARY)
|
|
|
|
{
|
|
|
|
rq.r_length = sizeof(request);
|
|
|
|
rq.r_command = C_OUTPUT;
|
|
|
|
rq.r_count = n;
|
|
|
|
rq.r_trans = (BYTE FAR *) bp;
|
|
|
|
rq.r_status = 0;
|
|
|
|
execrh((request FAR *) & rq, s->sft_dev);
|
|
|
|
if (rq.r_status & S_ERROR)
|
|
|
|
{
|
|
|
|
char_error(&rq, s->sft_dev);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (s->sft_flags & SFT_FCONOUT)
|
|
|
|
{
|
|
|
|
WORD cnt = rq.r_count;
|
|
|
|
while (cnt--)
|
|
|
|
{
|
|
|
|
switch (*bp++)
|
|
|
|
{
|
|
|
|
case CR:
|
|
|
|
scr_pos = 0;
|
|
|
|
break;
|
|
|
|
case LF:
|
|
|
|
case BELL:
|
|
|
|
break;
|
|
|
|
case BS:
|
|
|
|
--scr_pos;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
++scr_pos;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*err = SUCCESS;
|
|
|
|
return rq.r_count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2001-09-24 04:21:14 +02:00
|
|
|
REG WORD xfer;
|
2001-04-29 19:34:41 +02:00
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
for (xfer = 0; xfer < n && *bp != CTL_Z; bp++, xfer++)
|
2001-09-24 04:21:14 +02:00
|
|
|
{
|
2001-04-29 19:34:41 +02:00
|
|
|
if (s->sft_flags & SFT_FCONOUT)
|
2001-11-18 15:01:12 +01:00
|
|
|
{
|
|
|
|
cso(*bp);
|
2001-04-29 19:34:41 +02:00
|
|
|
}
|
2001-11-18 15:01:12 +01:00
|
|
|
else
|
|
|
|
FOREVER
|
2001-04-29 19:34:41 +02:00
|
|
|
{
|
|
|
|
rq.r_length = sizeof(request);
|
|
|
|
rq.r_command = C_OUTPUT;
|
|
|
|
rq.r_count = 1;
|
2002-02-16 20:20:20 +01:00
|
|
|
rq.r_trans = (BYTE FAR *)bp;
|
2001-04-29 19:34:41 +02:00
|
|
|
rq.r_status = 0;
|
|
|
|
execrh((request FAR *) & rq, s->sft_dev);
|
2001-09-24 04:21:14 +02:00
|
|
|
if (!(rq.r_status & S_ERROR))
|
2001-11-18 15:01:12 +01:00
|
|
|
break;
|
|
|
|
charloop:
|
|
|
|
switch (char_error(&rq, s->sft_dev))
|
|
|
|
{
|
|
|
|
case ABORT:
|
|
|
|
case FAIL:
|
|
|
|
*err = DE_INVLDACC;
|
|
|
|
return xfer;
|
|
|
|
case CONTINUE:
|
|
|
|
break;
|
|
|
|
case RETRY:
|
|
|
|
continue;
|
|
|
|
default:
|
|
|
|
goto charloop;
|
|
|
|
}
|
|
|
|
break;
|
2001-04-29 19:34:41 +02:00
|
|
|
}
|
2001-08-19 14:58:36 +02:00
|
|
|
if (control_break())
|
2001-04-29 19:34:41 +02:00
|
|
|
{
|
|
|
|
handle_break();
|
|
|
|
break;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
*err = SUCCESS;
|
|
|
|
return xfer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
/* a block write */
|
|
|
|
{
|
2000-10-30 00:51:56 +01:00
|
|
|
/* /// Added for SHARE - Ron Cemer */
|
2001-11-18 15:01:12 +01:00
|
|
|
if (IsShareInstalled())
|
|
|
|
{
|
|
|
|
if (s->sft_shroff >= 0)
|
|
|
|
{
|
|
|
|
int share_result = share_access_check(cu_psp,
|
|
|
|
s->sft_shroff,
|
|
|
|
s->sft_posit,
|
|
|
|
(unsigned long)n,
|
|
|
|
1);
|
|
|
|
if (share_result != 0)
|
|
|
|
{
|
|
|
|
*err = share_result;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2000-10-30 00:51:56 +01:00
|
|
|
}
|
|
|
|
/* /// End of additions for SHARE - Ron Cemer */
|
|
|
|
|
2002-05-09 00:49:35 +02:00
|
|
|
WriteCount = rwblock(s->sft_status, (BYTE FAR *)bp, n, XFR_WRITE);
|
2001-11-04 20:47:39 +01:00
|
|
|
s->sft_size = dos_getcufsize(s->sft_status);
|
2002-05-09 00:49:35 +02:00
|
|
|
*err = SUCCESS;
|
|
|
|
return WriteCount;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
*err = SUCCESS;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
COUNT SftSeek(sft FAR * s, LONG new_pos, COUNT mode)
|
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
|
|
|
}
|
|
|
|
|
|
|
|
COUNT DosSeek(COUNT hndl, LONG new_pos, COUNT mode, ULONG * set_pos)
|
|
|
|
{
|
2001-11-18 15:01:12 +01:00
|
|
|
sft FAR *s;
|
|
|
|
COUNT result;
|
|
|
|
|
|
|
|
/* Get the SFT block that contains the SFT */
|
|
|
|
if ((s = get_sft(hndl)) == (sft FAR *) - 1)
|
|
|
|
return DE_INVLDHNDL;
|
|
|
|
|
|
|
|
result = SftSeek(s, new_pos, mode);
|
|
|
|
if (result == SUCCESS)
|
|
|
|
{
|
|
|
|
*set_pos = s->sft_posit;
|
|
|
|
}
|
|
|
|
return result;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
STATIC COUNT get_free_hndl(void)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
psp FAR *p = MK_FP(cu_psp, 0);
|
|
|
|
WORD hndl;
|
|
|
|
|
|
|
|
for (hndl = 0; hndl < p->ps_maxfiles; hndl++)
|
|
|
|
{
|
|
|
|
if (p->ps_filetab[hndl] == 0xff)
|
|
|
|
return hndl;
|
|
|
|
}
|
2001-07-23 14:47:42 +02:00
|
|
|
return DE_TOOMANY;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2000-05-26 21:25:19 +02:00
|
|
|
BYTE FAR *get_root(BYTE FAR * fname)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
BYTE FAR *froot;
|
|
|
|
REG WORD length;
|
|
|
|
|
|
|
|
/* find the end */
|
|
|
|
for (length = 0, froot = fname; *froot != '\0'; ++froot)
|
|
|
|
++length;
|
|
|
|
/* now back up to first path seperator or start */
|
|
|
|
for (--froot; length > 0 && !(*froot == '/' || *froot == '\\'); --froot)
|
|
|
|
--length;
|
|
|
|
return ++froot;
|
|
|
|
}
|
|
|
|
|
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();
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
COUNT DosCreatSft(BYTE * fname, COUNT 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;
|
2001-07-23 14:47:42 +02:00
|
|
|
WORD result;
|
|
|
|
COUNT drive;
|
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));
|
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
sftp->sft_shroff = -1; /* /// Added for SHARE - Ron Cemer */
|
2001-07-23 14:47:42 +02:00
|
|
|
sftp->sft_psp = cu_psp;
|
|
|
|
sftp->sft_mode = SFT_MRDWR;
|
2001-11-04 20:47:39 +01:00
|
|
|
sftp->sft_attrib = attrib;
|
2002-01-23 23:29:41 +01:00
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
/* check for a device */
|
|
|
|
dhp = IsDevice(fname);
|
|
|
|
if (dhp)
|
|
|
|
{
|
2002-02-16 20:20:20 +01:00
|
|
|
DeviceOpenSft(dhp, sftp);
|
2001-11-18 15:01:12 +01:00
|
|
|
return sft_idx;
|
|
|
|
}
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
if (current_ldt->cdsFlags & CDSNETWDRV)
|
|
|
|
{
|
|
|
|
lpCurSft = sftp;
|
|
|
|
result = remote_creat(sftp, attrib);
|
|
|
|
if (result == SUCCESS)
|
|
|
|
{
|
|
|
|
sftp->sft_count += 1;
|
|
|
|
return sft_idx;
|
|
|
|
}
|
|
|
|
return result;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2001-09-23 22:39:44 +02:00
|
|
|
drive = get_verify_drive(fname);
|
2001-11-18 15:01:12 +01:00
|
|
|
if (drive < 0)
|
|
|
|
{
|
|
|
|
return drive;
|
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())
|
|
|
|
{
|
|
|
|
if ((sftp->sft_shroff = share_open_check((char far *)fname, cu_psp, 0x02, /* read-write */
|
|
|
|
0)) < 0) /* compatibility mode */
|
|
|
|
return sftp->sft_shroff;
|
2000-10-30 00:51:56 +01:00
|
|
|
}
|
|
|
|
/* /// End of additions for SHARE. - Ron Cemer */
|
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
sftp->sft_status = dos_creat(fname, attrib);
|
2000-05-06 21:34:20 +02:00
|
|
|
if (sftp->sft_status >= 0)
|
|
|
|
{
|
|
|
|
sftp->sft_count += 1;
|
2001-07-22 03:58:58 +02:00
|
|
|
sftp->sft_flags = drive;
|
2001-07-23 14:47:42 +02:00
|
|
|
DosGetFile(fname, 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);
|
2001-07-23 14:47:42 +02:00
|
|
|
return sft_idx;
|
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 */
|
2000-05-06 21:34:20 +02:00
|
|
|
return sftp->sft_status;
|
2000-10-30 00:51:56 +01:00
|
|
|
}
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
COUNT DosCreat(BYTE FAR * fname, COUNT attrib)
|
|
|
|
{
|
|
|
|
psp FAR *p = MK_FP(cu_psp, 0);
|
|
|
|
COUNT sft_idx, hndl, result;
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2002-02-16 20:20:20 +01:00
|
|
|
/* NEVER EVER allow directories to be created */
|
|
|
|
attrib = (BYTE) attrib;
|
|
|
|
if (attrib & ~(D_RDONLY | D_HIDDEN | D_SYSTEM | D_ARCHIVE))
|
|
|
|
{
|
|
|
|
return DE_ACCESS;
|
|
|
|
}
|
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
/* get a free handle */
|
|
|
|
if ((hndl = get_free_hndl()) < 0)
|
|
|
|
return hndl;
|
|
|
|
|
|
|
|
result = truename(fname, PriPathName, FALSE);
|
2001-11-18 15:01:12 +01:00
|
|
|
if (result != SUCCESS)
|
|
|
|
{
|
2001-07-23 14:47:42 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
sft_idx = DosCreatSft(PriPathName, attrib);
|
|
|
|
|
|
|
|
if (sft_idx < SUCCESS)
|
2001-11-18 15:01:12 +01:00
|
|
|
return sft_idx;
|
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
p->ps_filetab[hndl] = sft_idx;
|
|
|
|
return hndl;
|
|
|
|
}
|
|
|
|
|
2000-05-06 21:34:20 +02:00
|
|
|
COUNT CloneHandle(COUNT hndl)
|
|
|
|
{
|
|
|
|
sft FAR *sftp;
|
|
|
|
|
|
|
|
/* now get the system file table entry */
|
|
|
|
if ((sftp = get_sft(hndl)) == (sft FAR *) - 1)
|
|
|
|
return DE_INVLDHNDL;
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
COUNT DosDup(COUNT Handle)
|
|
|
|
{
|
|
|
|
psp FAR *p = MK_FP(cu_psp, 0);
|
|
|
|
COUNT NewHandle;
|
|
|
|
sft FAR *Sftp;
|
|
|
|
|
|
|
|
/* Get the SFT block that contains the SFT */
|
|
|
|
if ((Sftp = get_sft(Handle)) == (sft FAR *) - 1)
|
|
|
|
return DE_INVLDHNDL;
|
|
|
|
|
|
|
|
/* If not open - exit */
|
|
|
|
if (Sftp->sft_count <= 0)
|
|
|
|
return DE_INVLDHNDL;
|
|
|
|
|
|
|
|
/* now get a free handle */
|
2001-07-23 14:47:42 +02:00
|
|
|
if ((NewHandle = get_free_hndl()) < 0)
|
|
|
|
return NewHandle;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
/* 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[Handle];
|
|
|
|
Sftp->sft_count += 1;
|
|
|
|
return NewHandle;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return DE_INVLDHNDL;
|
|
|
|
}
|
|
|
|
|
|
|
|
COUNT DosForceDup(COUNT OldHandle, COUNT NewHandle)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
|
|
|
|
/* If not open - exit */
|
|
|
|
if (Sftp->sft_count <= 0)
|
|
|
|
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];
|
|
|
|
|
|
|
|
Sftp->sft_count += 1;
|
|
|
|
return NewHandle;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return DE_INVLDHNDL;
|
|
|
|
}
|
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
COUNT DosOpenSft(BYTE * fname, COUNT mode)
|
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;
|
2001-07-22 03:58:58 +02:00
|
|
|
COUNT drive, 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-22 03:58:58 +02:00
|
|
|
fmemset(sftp, 0, sizeof(sft));
|
2001-07-23 14:47:42 +02:00
|
|
|
sftp->sft_psp = cu_psp;
|
|
|
|
sftp->sft_mode = mode;
|
2002-02-09 16:39:35 +01:00
|
|
|
mode = OpenMode = (BYTE) mode;
|
2002-01-23 23:29:41 +01:00
|
|
|
|
2000-05-06 21:34:20 +02:00
|
|
|
/* check for a device */
|
2001-07-22 03:58:58 +02:00
|
|
|
dhp = IsDevice(fname);
|
2001-11-18 15:01:12 +01:00
|
|
|
if (dhp)
|
2001-07-22 03:58:58 +02:00
|
|
|
{
|
2002-02-16 20:20:20 +01:00
|
|
|
DeviceOpenSft(dhp, sftp);
|
2001-07-23 14:47:42 +02:00
|
|
|
return sft_idx;
|
2001-07-22 03:58:58 +02:00
|
|
|
}
|
2000-05-08 06:30:00 +02:00
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
if (current_ldt->cdsFlags & CDSNETWDRV)
|
|
|
|
{
|
|
|
|
lpCurSft = sftp;
|
|
|
|
result = remote_open(sftp, mode);
|
|
|
|
/* printf("open SFT %d = %p\n",sft_idx,sftp); */
|
|
|
|
if (result == SUCCESS)
|
|
|
|
{
|
|
|
|
sftp->sft_count += 1;
|
|
|
|
return sft_idx;
|
|
|
|
}
|
|
|
|
return result;
|
2001-07-22 03:58:58 +02:00
|
|
|
}
|
2001-09-23 22:39:44 +02:00
|
|
|
|
|
|
|
drive = get_verify_drive(fname);
|
2001-11-18 15:01:12 +01:00
|
|
|
if (drive < 0)
|
|
|
|
{
|
|
|
|
return drive;
|
2001-09-23 22:39:44 +02:00
|
|
|
}
|
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
sftp->sft_shroff = -1; /* /// Added for SHARE - Ron Cemer */
|
2001-07-22 03:58:58 +02:00
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
/* /// Added for SHARE. - Ron Cemer */
|
2001-11-18 15:01:12 +01:00
|
|
|
if (IsShareInstalled())
|
|
|
|
{
|
2000-10-30 00:51:56 +01:00
|
|
|
if ((sftp->sft_shroff = share_open_check
|
2001-11-18 15:01:12 +01:00
|
|
|
((char far *)fname,
|
|
|
|
(unsigned short)cu_psp, mode & 0x03, (mode >> 2) & 0x07)) < 0)
|
|
|
|
return sftp->sft_shroff;
|
2000-10-30 00:51:56 +01:00
|
|
|
}
|
|
|
|
/* /// End of additions for SHARE. - Ron Cemer */
|
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
sftp->sft_status = dos_open(fname, mode);
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
if (sftp->sft_status >= 0)
|
|
|
|
{
|
2001-06-03 16:16:18 +02:00
|
|
|
f_node_ptr fnp = xlt_fd(sftp->sft_status);
|
2000-05-06 21:34:20 +02:00
|
|
|
|
|
|
|
sftp->sft_attrib = fnp->f_dir.dir_attrib;
|
|
|
|
|
|
|
|
/* Check permissions. -- JPP */
|
|
|
|
if ((sftp->sft_attrib & (D_DIR | D_VOLID)) ||
|
|
|
|
((sftp->sft_attrib & D_RDONLY) && (mode != O_RDONLY)))
|
|
|
|
{
|
2001-11-18 15:01:12 +01:00
|
|
|
dos_close(sftp->sft_status);
|
2000-05-06 21:34:20 +02:00
|
|
|
return DE_ACCESS;
|
|
|
|
}
|
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
sftp->sft_size = dos_getfsize(sftp->sft_status);
|
|
|
|
dos_getftime(sftp->sft_status,
|
2001-11-18 15:01:12 +01:00
|
|
|
(date FAR *) & sftp->sft_date,
|
|
|
|
(time FAR *) & sftp->sft_time);
|
2000-05-06 21:34:20 +02:00
|
|
|
sftp->sft_count += 1;
|
|
|
|
sftp->sft_mode = mode;
|
2001-07-22 03:58:58 +02:00
|
|
|
sftp->sft_flags = drive;
|
2001-07-23 14:47:42 +02:00
|
|
|
DosGetFile(fname, sftp->sft_name);
|
|
|
|
return sft_idx;
|
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 */
|
2000-05-06 21:34:20 +02:00
|
|
|
return sftp->sft_status;
|
2000-10-30 00:51:56 +01:00
|
|
|
}
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
COUNT DosOpen(BYTE FAR * fname, COUNT mode)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
|
|
|
psp FAR *p = MK_FP(cu_psp, 0);
|
2001-07-23 14:47:42 +02:00
|
|
|
COUNT sft_idx, result, hndl;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2002-01-23 23:29:41 +01:00
|
|
|
/* test if mode is in range */
|
|
|
|
if ((mode & ~SFT_OMASK) != 0)
|
|
|
|
return DE_INVLDACC;
|
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
/* get a free handle */
|
|
|
|
if ((hndl = get_free_hndl()) < 0)
|
|
|
|
return hndl;
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
result = truename(fname, PriPathName, FALSE);
|
2001-11-18 15:01:12 +01:00
|
|
|
if (result != SUCCESS)
|
|
|
|
{
|
|
|
|
return result;
|
2001-07-23 14:47:42 +02:00
|
|
|
}
|
|
|
|
|
2002-01-23 23:29:41 +01:00
|
|
|
sft_idx = DosOpenSft(PriPathName, mode & 3);
|
2001-07-23 14:47:42 +02:00
|
|
|
|
|
|
|
if (sft_idx < SUCCESS)
|
2001-11-18 15:01:12 +01:00
|
|
|
return sft_idx;
|
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
p->ps_filetab[hndl] = sft_idx;
|
|
|
|
return hndl;
|
|
|
|
}
|
|
|
|
|
2002-01-23 23:29:41 +01:00
|
|
|
COUNT DosCloseSft(WORD 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
|
|
|
|
2001-11-04 20:47:39 +01:00
|
|
|
if (sftp == (sft FAR *) - 1)
|
2000-05-06 21:34:20 +02:00
|
|
|
return DE_INVLDHNDL;
|
|
|
|
|
|
|
|
/* If this is not opened another error */
|
2001-11-14 00:36:45 +01:00
|
|
|
if (sftp->sft_count == 0)
|
2000-05-06 21:34:20 +02:00
|
|
|
return DE_ACCESS;
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
BOOL DosGetFree(UBYTE drive, UCOUNT FAR * spc, UCOUNT FAR * navc,
|
|
|
|
UCOUNT FAR * bps, UCOUNT FAR * nc)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2001-11-18 15:01:12 +01:00
|
|
|
/* *nc==0xffff 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;
|
|
|
|
if (drive >= lastdrive)
|
2001-11-18 15:01:12 +01:00
|
|
|
return FALSE;
|
|
|
|
|
2002-08-03 18:54:09 +02:00
|
|
|
cdsp = &CDSp[drive];
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2001-04-15 05:21:50 +02:00
|
|
|
if (!(cdsp->cdsFlags & CDSVALID))
|
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 */
|
|
|
|
|
|
|
|
if (*nc != 0xffff)
|
|
|
|
{
|
|
|
|
*navc = (COUNT) rg[3];
|
|
|
|
rg[0] &= 0xff;
|
|
|
|
/* zero media ID (high part) */
|
|
|
|
}
|
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-03 18:54:09 +02:00
|
|
|
dpbp = CDSp[drive].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
|
|
|
|
|
|
|
if (*nc == 0xffff)
|
|
|
|
{
|
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 */
|
2000-05-06 21:34:20 +02:00
|
|
|
*spc = dpbp->dpb_clsmask + 1;
|
|
|
|
*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;
|
2001-11-18 15:01:12 +01:00
|
|
|
if (*nc != 0xffff)
|
|
|
|
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 */
|
2001-11-18 15:01:12 +01:00
|
|
|
*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;
|
2001-11-18 15:01:12 +01:00
|
|
|
*navc = (*navc < FAT_MAGIC16 / 2) ? (*navc << 1) : FAT_MAGIC16;
|
|
|
|
*nc = (*nc < FAT_MAGIC16 / 2) ? (*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;
|
|
|
|
UBYTE drive;
|
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
|
|
|
drive = DosUpFChar(*DriveString) - 'A';
|
2001-11-18 15:01:12 +01:00
|
|
|
if (drive >= lastdrive)
|
|
|
|
return DE_INVLDDRV;
|
2001-09-23 22:39:44 +02:00
|
|
|
|
2002-08-03 18:54:09 +02:00
|
|
|
cdsp = &CDSp[drive];
|
2001-09-23 22:39:44 +02:00
|
|
|
|
|
|
|
if (!(cdsp->cdsFlags & CDSVALID))
|
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-08-03 18:54:09 +02:00
|
|
|
dpbp = CDSp[drive].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
|
|
|
{
|
2001-07-28 20:13:06 +02:00
|
|
|
BYTE FAR *cp;
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2000-05-06 21:34:20 +02:00
|
|
|
/* next - "log" in the drive */
|
|
|
|
drive = (drive == 0 ? default_drive : drive - 1);
|
|
|
|
|
2001-04-15 05:21:50 +02:00
|
|
|
/* first check for valid drive */
|
2002-08-03 18:54:09 +02:00
|
|
|
if (drive >= lastdrive || !(CDSp[drive].cdsFlags & CDSVALID))
|
2001-11-18 15:01:12 +01:00
|
|
|
{
|
2001-04-15 05:21:50 +02:00
|
|
|
return DE_INVLDDRV;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2002-08-03 18:54:09 +02:00
|
|
|
current_ldt = &CDSp[drive];
|
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-05-09 00:49:35 +02:00
|
|
|
if ((current_ldt->cdsFlags & CDSNETWDRV) == 0)
|
|
|
|
{
|
|
|
|
if (current_ldt->cdsDpb == 0)
|
|
|
|
return DE_INVLDDRV;
|
|
|
|
|
|
|
|
if ((media_check(current_ldt->cdsDpb) < 0))
|
|
|
|
return DE_INVLDDRV;
|
|
|
|
}
|
|
|
|
|
2001-07-28 20:13:06 +02:00
|
|
|
cp = ¤t_ldt->cdsCurrentPath[current_ldt->cdsJoinOffset];
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
REG COUNT drive;
|
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;
|
|
|
|
|
|
|
|
drive = get_verify_drive(s);
|
|
|
|
if (drive < 0)
|
|
|
|
{
|
|
|
|
return drive;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = truename(s, PriPathName, FALSE);
|
|
|
|
if (result != SUCCESS)
|
|
|
|
{
|
|
|
|
return result;
|
|
|
|
}
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2002-08-03 18:54:09 +02:00
|
|
|
current_ldt = &CDSp[drive];
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
if (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 */
|
2001-11-04 20:47:39 +01:00
|
|
|
result = (current_ldt->cdsFlags & CDSNETWDRV) ? remote_chdir() :
|
|
|
|
dos_cd(current_ldt, 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);
|
2001-11-04 20:47:39 +01:00
|
|
|
if (PriPathName[7] == 0)
|
2001-11-18 15:01:12 +01:00
|
|
|
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)
|
|
|
|
{
|
2001-07-28 20:13:06 +02:00
|
|
|
COUNT rc;
|
2001-04-29 19:34:41 +02:00
|
|
|
REG dmatch FAR *dmp = (dmatch FAR *) dta;
|
2001-07-24 18:56:29 +02:00
|
|
|
BYTE FAR *p;
|
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
|
|
|
|
2001-07-24 18:56:29 +02:00
|
|
|
fmemset(dta, 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 */
|
2001-11-18 15:01:12 +01:00
|
|
|
((dmatch FAR *) dta)->dm_attr_fnd = D_DEVICE;
|
|
|
|
|
2001-07-24 18:56:29 +02:00
|
|
|
memset(&SearchDir, 0, sizeof(struct dirent));
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2001-07-24 18:56:29 +02:00
|
|
|
rc = truename(name, PriPathName, FALSE);
|
|
|
|
if (rc != SUCCESS)
|
2001-11-18 15:01:12 +01:00
|
|
|
return rc;
|
|
|
|
|
2001-07-24 18:56:29 +02:00
|
|
|
if (IsDevice(PriPathName))
|
2001-04-29 19:34:41 +02:00
|
|
|
{
|
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();
|
|
|
|
p = 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++;
|
|
|
|
if (*p == '.')
|
|
|
|
p++;
|
2001-07-24 18:56:29 +02:00
|
|
|
for (i = 0; i < FEXT_SIZE && *p && *p != '.'; i++)
|
2001-11-18 15:01:12 +01:00
|
|
|
SearchDir.dir_ext[i] = *p++;
|
2001-07-24 18:56:29 +02:00
|
|
|
pop_dmp(dmp);
|
2001-04-29 19:34:41 +02:00
|
|
|
return SUCCESS;
|
|
|
|
}
|
|
|
|
/* /// End of additions. - Ron Cemer ; heavily edited - Bart Oldeman */
|
2001-07-22 03:58:58 +02:00
|
|
|
|
|
|
|
SAttr = (BYTE) attr;
|
|
|
|
|
2001-07-24 18:56:29 +02:00
|
|
|
#if defined(FIND_DEBUG)
|
|
|
|
printf("Remote Find: n='%Fs\n", PriPathName);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
fmemcpy(TempBuffer, dta, 21);
|
|
|
|
p = dta;
|
2001-11-18 15:01:12 +01:00
|
|
|
dta = (BYTE FAR *) TempBuffer;
|
|
|
|
|
2001-07-24 18:56:29 +02:00
|
|
|
rc = current_ldt->cdsFlags & CDSNETWDRV ?
|
2001-11-18 15:01:12 +01:00
|
|
|
remote_findfirst((VOID FAR *) current_ldt) :
|
|
|
|
dos_findfirst(attr, PriPathName);
|
2001-07-24 18:56:29 +02:00
|
|
|
|
|
|
|
dta = p;
|
|
|
|
|
|
|
|
fmemcpy(dta, TempBuffer, 21);
|
2001-11-18 15:01:12 +01:00
|
|
|
pop_dmp((dmatch FAR *) dta);
|
|
|
|
if (rc != SUCCESS)
|
|
|
|
((dmatch FAR *) dta)->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;
|
|
|
|
BYTE FAR *p;
|
2001-04-29 19:34:41 +02:00
|
|
|
|
|
|
|
/* /// findnext will always fail on a device name. - Ron Cemer */
|
2001-11-18 15:01:12 +01:00
|
|
|
if (((dmatch FAR *) dta)->dm_attr_fnd == D_DEVICE)
|
|
|
|
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
|
2001-11-18 15:01:12 +01:00
|
|
|
printf("findnext: %d\n", ((dmatch FAR *) dta)->dm_drive);
|
2001-04-29 19:34:41 +02:00
|
|
|
#endif
|
2001-07-24 18:56:29 +02:00
|
|
|
fmemcpy(TempBuffer, dta, 21);
|
|
|
|
fmemset(dta, 0, sizeof(dmatch));
|
|
|
|
p = dta;
|
2001-11-18 15:01:12 +01:00
|
|
|
dta = (BYTE FAR *) TempBuffer;
|
2002-08-03 18:54:09 +02:00
|
|
|
current_ldt = &CDSp[((dmatch *) TempBuffer)->dm_drive];
|
2001-11-18 15:01:12 +01:00
|
|
|
rc = (((dmatch *) TempBuffer)->dm_drive & 0x80) ?
|
|
|
|
remote_findnext((VOID FAR *) current_ldt) : dos_findnext();
|
|
|
|
|
2001-07-24 18:56:29 +02:00
|
|
|
dta = p;
|
|
|
|
fmemcpy(dta, TempBuffer, 21);
|
2001-11-18 15:01:12 +01:00
|
|
|
pop_dmp((dmatch FAR *) dta);
|
2001-07-28 20:13:06 +02:00
|
|
|
return rc;
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
COUNT DosGetFtime(COUNT hndl, date FAR * dp, time FAR * tp)
|
|
|
|
{
|
|
|
|
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 */
|
|
|
|
if ((s = get_sft(hndl)) == (sft FAR *) - 1)
|
|
|
|
return DE_INVLDHNDL;
|
|
|
|
|
|
|
|
/* If this is not opened another error */
|
|
|
|
if (s->sft_count == 0)
|
|
|
|
return DE_ACCESS;
|
|
|
|
|
|
|
|
/* 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);
|
|
|
|
}
|
|
|
|
|
2001-08-19 14:58:36 +02:00
|
|
|
COUNT DosSetFtimeSft(WORD 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
|
|
|
|
2001-07-23 14:47:42 +02:00
|
|
|
if (s == (sft FAR *) - 1)
|
2000-05-06 21:34:20 +02:00
|
|
|
return DE_INVLDHNDL;
|
|
|
|
|
|
|
|
/* If this is not opened another error */
|
|
|
|
if (s->sft_count == 0)
|
|
|
|
return DE_ACCESS;
|
|
|
|
|
|
|
|
/* 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
|
|
|
{
|
2001-11-18 15:01:12 +01:00
|
|
|
COUNT result, drive;
|
2000-05-08 06:30:00 +02:00
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
if (IsDevice(name))
|
|
|
|
{
|
|
|
|
return DE_FILENOTFND;
|
|
|
|
}
|
2000-05-06 21:34:20 +02:00
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
drive = get_verify_drive(name);
|
|
|
|
if (drive < 0)
|
|
|
|
{
|
|
|
|
return drive;
|
|
|
|
}
|
2000-05-08 06:30:00 +02:00
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
result = truename(name, PriPathName, FALSE);
|
|
|
|
if (result != SUCCESS)
|
|
|
|
{
|
|
|
|
return result;
|
|
|
|
}
|
2000-05-08 06:30:00 +02:00
|
|
|
|
2000-08-06 07:50:17 +02:00
|
|
|
/* /// Added check for "d:\", which returns 0x10 (subdirectory) under DOS.
|
|
|
|
- Ron Cemer */
|
2001-11-18 15:01:12 +01:00
|
|
|
if ((PriPathName[0] != '\0')
|
|
|
|
&& (PriPathName[1] == ':')
|
|
|
|
&& ((PriPathName[2] == '/') || (PriPathName[2] == '\\'))
|
|
|
|
&& (PriPathName[3] == '\0'))
|
|
|
|
{
|
|
|
|
return 0x10;
|
|
|
|
}
|
2000-08-06 07:50:17 +02:00
|
|
|
|
2002-08-03 18:54:09 +02:00
|
|
|
current_ldt = &CDSp[drive];
|
2001-11-18 15:01:12 +01:00
|
|
|
if (current_ldt->cdsFlags & CDSNETWDRV)
|
|
|
|
{
|
|
|
|
return remote_getfattr();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
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
|
|
|
|
*/
|
|
|
|
return dos_getfattr(PriPathName);
|
|
|
|
|
|
|
|
}
|
2000-05-06 21:34:20 +02:00
|
|
|
}
|
|
|
|
|
2001-07-22 03:58:58 +02:00
|
|
|
COUNT DosSetFattr(BYTE FAR * name, UWORD attrp)
|
2000-05-06 21:34:20 +02:00
|
|
|
{
|
2001-11-18 15:01:12 +01:00
|
|
|
COUNT result, drive;
|
|
|
|
|
|
|
|
if (IsDevice(name))
|
|
|
|
{
|
|
|
|
return DE_FILENOTFND;
|
|
|
|
}
|
|
|
|
|
|
|
|
drive = get_verify_drive(name);
|
|
|
|
if (drive < 0)
|
|
|
|
{
|
|
|
|
return drive;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = truename(name, PriPathName, FALSE);
|
|
|
|
if (result != SUCCESS)
|
|
|
|
{
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2002-08-03 18:54:09 +02:00
|
|
|
current_ldt = &CDSp[drive];
|
2001-11-18 15:01:12 +01:00
|
|
|
if (current_ldt->cdsFlags & CDSNETWDRV)
|
|
|
|
{
|
|
|
|
return remote_setfattr(attrp);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
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
|
|
|
*/
|
|
|
|
return dos_setfattr(PriPathName, attrp);
|
2001-06-03 16:16:18 +02:00
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
}
|
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-08-03 18:54:09 +02:00
|
|
|
current_ldt = &CDSp[drv];
|
2001-11-18 15:01:12 +01:00
|
|
|
|
2001-11-04 20:47:39 +01:00
|
|
|
if ((drv < lastdrive) && (current_ldt->cdsFlags & CDSVALID))
|
2001-04-22 00:32:53 +02:00
|
|
|
/*
|
|
|
|
&&
|
2001-04-15 05:21:50 +02:00
|
|
|
((cdsp->cdsFlags & CDSNETWDRV) ||
|
|
|
|
(cdsp->cdsDpb!=NULL && media_check(cdsp->cdsDpb)==SUCCESS)))
|
2001-11-18 15:01:12 +01:00
|
|
|
*/
|
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
|
|
|
{
|
2001-11-18 15:01:12 +01:00
|
|
|
COUNT result, drive;
|
|
|
|
|
|
|
|
if (IsDevice(path))
|
|
|
|
{
|
|
|
|
return DE_FILENOTFND;
|
|
|
|
}
|
|
|
|
|
|
|
|
drive = get_verify_drive(path);
|
|
|
|
if (drive < 0)
|
|
|
|
{
|
|
|
|
return drive;
|
|
|
|
}
|
|
|
|
result = truename(path, PriPathName, FALSE);
|
|
|
|
if (result != SUCCESS)
|
|
|
|
{
|
|
|
|
return result;
|
|
|
|
}
|
2002-08-03 18:54:09 +02:00
|
|
|
current_ldt = &CDSp[drive];
|
2001-11-18 15:01:12 +01:00
|
|
|
if (current_ldt->cdsFlags & CDSNETWDRV)
|
|
|
|
{
|
|
|
|
return remote_delete();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2002-02-16 20:20:20 +01:00
|
|
|
return dos_delete(PriPathName, attrib);
|
2001-11-18 15:01:12 +01:00
|
|
|
}
|
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
|
|
|
{
|
2001-11-18 15:01:12 +01:00
|
|
|
COUNT drive1, drive2;
|
2000-05-26 21:25:19 +02:00
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
if (IsDevice(path1) || IsDevice(path2))
|
|
|
|
{
|
|
|
|
return DE_FILENOTFND;
|
|
|
|
}
|
2000-05-26 21:25:19 +02:00
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
drive1 = get_verify_drive(path1);
|
|
|
|
drive2 = get_verify_drive(path2);
|
|
|
|
if ((drive1 != drive2) || (drive1 < 0))
|
|
|
|
{
|
|
|
|
return DE_INVLDDRV;
|
|
|
|
}
|
2002-08-03 18:54:09 +02:00
|
|
|
current_ldt = &CDSp[drive1];
|
2001-11-18 15:01:12 +01:00
|
|
|
if (current_ldt->cdsFlags & CDSNETWDRV)
|
|
|
|
{
|
|
|
|
return remote_rename();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2002-02-16 20:20:20 +01:00
|
|
|
return dos_rename(PriPathName, SecPathName, attrib);
|
2001-11-18 15:01:12 +01:00
|
|
|
}
|
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
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
result = truename(path1, PriPathName, FALSE);
|
|
|
|
if (result != SUCCESS)
|
|
|
|
{
|
|
|
|
return result;
|
|
|
|
}
|
2001-07-23 14:47:42 +02:00
|
|
|
|
2001-11-18 15:01:12 +01:00
|
|
|
result = truename(path2, SecPathName, FALSE);
|
|
|
|
if (result != SUCCESS)
|
|
|
|
{
|
|
|
|
return result;
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
|
|
|
COUNT DosMkdir(BYTE FAR * dir)
|
|
|
|
{
|
2001-11-18 15:01:12 +01:00
|
|
|
COUNT result, drive;
|
|
|
|
|
|
|
|
if (IsDevice(dir))
|
|
|
|
{
|
|
|
|
return DE_PATHNOTFND;
|
|
|
|
}
|
|
|
|
|
|
|
|
drive = get_verify_drive(dir);
|
|
|
|
if (drive < 0)
|
|
|
|
{
|
|
|
|
return drive;
|
|
|
|
}
|
|
|
|
result = truename(dir, PriPathName, FALSE);
|
|
|
|
if (result != SUCCESS)
|
|
|
|
{
|
|
|
|
return result;
|
|
|
|
}
|
2002-08-03 18:54:09 +02:00
|
|
|
current_ldt = &CDSp[drive];
|
2001-11-18 15:01:12 +01:00
|
|
|
if (current_ldt->cdsFlags & CDSNETWDRV)
|
|
|
|
{
|
|
|
|
return remote_mkdir();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return dos_mkdir(PriPathName);
|
|
|
|
}
|
2000-05-08 06:30:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
COUNT DosRmdir(BYTE FAR * dir)
|
|
|
|
{
|
2001-11-18 15:01:12 +01:00
|
|
|
COUNT result, drive;
|
|
|
|
|
|
|
|
if (IsDevice(dir))
|
|
|
|
{
|
|
|
|
return DE_PATHNOTFND;
|
|
|
|
}
|
|
|
|
|
|
|
|
drive = get_verify_drive(dir);
|
|
|
|
if (drive < 0)
|
|
|
|
{
|
|
|
|
return drive;
|
|
|
|
}
|
|
|
|
result = truename(dir, PriPathName, FALSE);
|
|
|
|
if (result != SUCCESS)
|
|
|
|
{
|
|
|
|
return result;
|
|
|
|
}
|
2002-08-03 18:54:09 +02:00
|
|
|
current_ldt = &CDSp[drive];
|
|
|
|
if (CDSp[drive].cdsFlags & CDSNETWDRV)
|
2001-11-18 15:01:12 +01:00
|
|
|
{
|
|
|
|
return remote_rmdir();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
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 */
|
2001-11-18 15:01:12 +01:00
|
|
|
if ((s = get_sft(hndl)) == (sft FAR *) - 1)
|
|
|
|
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 */
|
2001-11-18 15:01:12 +01:00
|
|
|
struct dhdr FAR *IsDevice(BYTE FAR * fname)
|
2000-05-26 21:25:19 +02:00
|
|
|
{
|
|
|
|
struct dhdr FAR *dhp;
|
2002-02-16 20:20:20 +01:00
|
|
|
char FAR *froot = get_root(fname);
|
|
|
|
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
|
|
|
{
|
2002-02-16 20:20:20 +01:00
|
|
|
char c1 = froot[i];
|
|
|
|
if (c1 == '.' || c1 == '\0')
|
|
|
|
{
|
|
|
|
/* check if remainder of device name consists of spaces or nulls */
|
|
|
|
for (; i < FNAME_SIZE; i++)
|
|
|
|
{
|
|
|
|
char c2 = dhp->dh_name[i];
|
|
|
|
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-01-23 23:29:41 +01:00
|
|
|
STATIC int share_open_check(char far * filename, /* far 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);
|
|
|
|
}
|
|
|
|
|
2000-10-30 00:51:56 +01:00
|
|
|
|
2001-11-18 00:26:45 +01:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* /// Added SHARE support. 2000/09/04 Ron Cemer
|
|
|
|
*
|
|
|
|
* Log: dosfns.c,v - for newer log entries do a "cvs log dosfns.c"
|
|
|
|
*
|
|
|
|
* Revision 1.14 2000/04/02 05:01:08 jtabor
|
|
|
|
* Replaced ChgDir Code
|
|
|
|
*
|
|
|
|
* Revision 1.13 2000/04/02 04:53:56 jtabor
|
|
|
|
* Fix to DosChgDir
|
|
|
|
*
|
|
|
|
* Revision 1.12 2000/03/31 05:40:09 jtabor
|
|
|
|
* Added Eric W. Biederman Patches
|
|
|
|
*
|
|
|
|
* Revision 1.11 2000/03/09 06:07:11 kernel
|
|
|
|
* 2017f updates by James Tabor
|
|
|
|
*
|
|
|
|
* Revision 1.10 1999/09/23 04:40:46 jprice
|
|
|
|
* *** empty log message ***
|
|
|
|
*
|
|
|
|
* Revision 1.8 1999/09/14 01:01:53 jprice
|
|
|
|
* Fixed bug where you could write over directories.
|
|
|
|
*
|
|
|
|
* Revision 1.7 1999/08/25 03:18:07 jprice
|
|
|
|
* ror4 patches to allow TC 2.01 compile.
|
|
|
|
*
|
|
|
|
* Revision 1.6 1999/05/03 06:25:45 jprice
|
|
|
|
* Patches from ror4 and many changed of signed to unsigned variables.
|
|
|
|
*
|
|
|
|
* Revision 1.5 1999/04/16 12:21:22 jprice
|
|
|
|
* Steffen c-break handler changes
|
|
|
|
*
|
|
|
|
* Revision 1.4 1999/04/12 03:21:17 jprice
|
|
|
|
* more ror4 patches. Changes for multi-block IO
|
|
|
|
*
|
|
|
|
* Revision 1.3 1999/04/11 04:33:38 jprice
|
|
|
|
* ror4 patches
|
|
|
|
*
|
|
|
|
* Revision 1.2 1999/04/04 18:51:43 jprice
|
|
|
|
* no message
|
|
|
|
*
|
|
|
|
* Revision 1.1.1.1 1999/03/29 15:41:52 jprice
|
|
|
|
* New version without IPL.SYS
|
|
|
|
*
|
|
|
|
* Revision 1.4 1999/02/09 02:54:23 jprice
|
|
|
|
* Added Pat's 1937 kernel patches
|
|
|
|
*
|
|
|
|
* Revision 1.3 1999/02/01 01:43:28 jprice
|
|
|
|
* Fixed findfirst function to find volume label with Windows long filenames
|
|
|
|
*
|
|
|
|
* Revision 1.2 1999/01/22 04:15:28 jprice
|
|
|
|
* Formating
|
|
|
|
*
|
|
|
|
* Revision 1.1.1.1 1999/01/20 05:51:00 jprice
|
|
|
|
* Imported sources
|
|
|
|
*
|
|
|
|
* Rev 1.10 06 Dec 1998 8:44:42 patv
|
|
|
|
* Expanded dos functions due to new I/O subsystem.
|
|
|
|
*
|
|
|
|
* Rev 1.9 04 Jan 1998 23:14:38 patv
|
|
|
|
* Changed Log for strip utility
|
|
|
|
*
|
|
|
|
* Rev 1.8 03 Jan 1998 8:36:04 patv
|
|
|
|
* Converted data area to SDA format
|
|
|
|
*
|
|
|
|
* Rev 1.7 22 Jan 1997 12:59:56 patv
|
|
|
|
* pre-0.92 bug fixes
|
|
|
|
*
|
|
|
|
* Rev 1.6 16 Jan 1997 12:46:32 patv
|
|
|
|
* pre-Release 0.92 feature additions
|
|
|
|
*
|
|
|
|
* Rev 1.5 29 May 1996 21:15:20 patv
|
|
|
|
* bug fixes for v0.91a
|
|
|
|
*
|
|
|
|
* Rev 1.4 19 Feb 1996 3:20:08 patv
|
|
|
|
* Added NLS, int2f and config.sys processing
|
|
|
|
*
|
|
|
|
* Rev 1.2 01 Sep 1995 17:48:48 patv
|
|
|
|
* First GPL release.
|
|
|
|
*
|
|
|
|
* Rev 1.1 30 Jul 1995 20:50:24 patv
|
|
|
|
* Eliminated version strings in ipl
|
|
|
|
*
|
|
|
|
* Rev 1.0 02 Jul 1995 8:04:20 patv
|
|
|
|
* Initial revision.
|
|
|
|
*/
|