Adding Share Support by Ron Cemer

git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@77 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
Jim Tabor 2000-10-29 23:51:56 +00:00
parent d53d9f4445
commit 584d442959
3 changed files with 391 additions and 9 deletions

View File

@ -33,7 +33,13 @@ static BYTE *dosfnsRcsId = "$Id$";
#endif
/*
*
* /// Added SHARE support. 2000/09/04 Ron Cemer
*
* $Log$
* Revision 1.9 2000/10/29 23:51:56 jimtabor
* Adding Share Support by Ron Cemer
*
* Revision 1.8 2000/08/06 05:50:17 jimtabor
* Add new files and update cvs with patches and changes
*
@ -150,6 +156,61 @@ BOOL cmatch(COUNT, COUNT, COUNT);
struct f_node FAR *xlt_fd(COUNT);
/* /// Added for SHARE. - Ron Cemer */
int share_installed = 0;
/* 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. */
static int share_open_check
(char far *filename, /* far pointer to fully qualified filename */
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. */
static void share_close_file
(int fileno); /* file_table entry number */
/* 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. */
static int share_access_check
(unsigned short pspseg,/* psp segment address of owner process */
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. */
static int share_lock_unlock
(unsigned short pspseg,/* psp segment address of owner process */
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 */
/* /// End of additions for SHARE. - Ron Cemer */
static VOID DosGetFile(BYTE FAR * lpszPath, BYTE FAR * lpszDosFileName)
{
BYTE szLclName[FNAME_SIZE + 1];
@ -292,6 +353,23 @@ UCOUNT GenericRead(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err,
{
COUNT rc;
/* /// Added for SHARE - Ron Cemer */
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;
}
}
}
/* /// End of additions for SHARE - Ron Cemer */
ReadCount = readblock(s->sft_status, bp, n, &rc);
if (rc != SUCCESS)
{
@ -482,6 +560,23 @@ UCOUNT DosWrite(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err)
{
COUNT rc;
/* /// Added for SHARE - Ron Cemer */
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;
}
}
}
/* /// End of additions for SHARE - Ron Cemer */
WriteCount = writeblock(s->sft_status, bp, n, &rc);
if (rc < SUCCESS)
{
@ -674,6 +769,8 @@ COUNT DosCreat(BYTE FAR * fname, COUNT attrib)
if ((sftp = get_free_sft((WORD FAR *) & sft_idx)) == (sft FAR *) - 1)
return DE_TOOMANY;
sftp->sft_shroff = -1; /* /// Added for SHARE - Ron Cemer */
/* check for a device */
dhp = IsDevice(fname);
if ( dhp )
@ -712,6 +809,17 @@ COUNT DosCreat(BYTE FAR * fname, COUNT attrib)
return result;
}
/* /// Added for SHARE. - Ron Cemer */
if (IsShareInstalled()) {
if ((sftp->sft_shroff = share_open_check
((char far *)PriPathName,
cu_psp,
0x02, /* read-write */
0)) < 0) /* compatibility mode */
return sftp->sft_shroff;
}
/* /// End of additions for SHARE. - Ron Cemer */
sftp->sft_status = dos_creat(fname, attrib);
if (sftp->sft_status >= 0)
{
@ -723,9 +831,15 @@ COUNT DosCreat(BYTE FAR * fname, COUNT attrib)
sftp->sft_psp = cu_psp;
DosGetFile(fname, sftp->sft_name);
return hndl;
}
else
} else {
/* /// Added for SHARE *** CURLY BRACES ADDED ALSO!!! ***. - Ron Cemer */
if (IsShareInstalled()) {
share_close_file(sftp->sft_shroff);
sftp->sft_shroff = -1;
}
/* /// End of additions for SHARE. - Ron Cemer */
return sftp->sft_status;
}
}
COUNT CloneHandle(COUNT hndl)
@ -841,6 +955,8 @@ COUNT DosOpen(BYTE FAR * fname, COUNT mode)
if ((sftp = get_free_sft((WORD FAR *) & sft_idx)) == (sft FAR *) - 1)
return DE_TOOMANY;
sftp->sft_shroff = -1; /* /// Added for SHARE - Ron Cemer */
/* check for a device */
dhp = IsDevice(fname);
if ( dhp )
@ -880,6 +996,18 @@ COUNT DosOpen(BYTE FAR * fname, COUNT mode)
}
return result;
}
/* /// Added for SHARE. - Ron Cemer */
if (IsShareInstalled()) {
if ((sftp->sft_shroff = share_open_check
((char far *)PriPathName,
(unsigned short)cu_psp,
mode & 0x03,
(mode >> 2) & 0x07)) < 0)
return sftp->sft_shroff;
}
/* /// End of additions for SHARE. - Ron Cemer */
sftp->sft_status = dos_open(fname, mode);
if (sftp->sft_status >= 0)
@ -903,9 +1031,15 @@ COUNT DosOpen(BYTE FAR * fname, COUNT mode)
sftp->sft_psp = cu_psp;
DosGetFile(fname, sftp->sft_name);
return hndl;
}
else
} else {
/* /// Added for SHARE *** CURLY BRACES ADDED ALSO!!! ***. - Ron Cemer */
if (IsShareInstalled()) {
share_close_file(sftp->sft_shroff);
sftp->sft_shroff = -1;
}
/* /// End of additions for SHARE. - Ron Cemer */
return sftp->sft_status;
}
}
COUNT DosClose(COUNT hndl)
@ -951,8 +1085,15 @@ COUNT DosClose(COUNT hndl)
s->sft_count -= 1;
if (s->sft_count > 0)
return SUCCESS;
else
else {
/* /// Added for SHARE *** CURLY BRACES ADDED ALSO!!! ***. - Ron Cemer */
if (IsShareInstalled()) {
if (s->sft_shroff >= 0) share_close_file(s->sft_shroff);
s->sft_shroff = -1;
}
/* /// End of additions for SHARE. - Ron Cemer */
return dos_close(s->sft_status);
}
}
}
@ -1382,6 +1523,30 @@ COUNT DosRmdir(BYTE FAR * dir)
return result;
}
/* /// Added for SHARE. - Ron Cemer */
COUNT DosLockUnlock(COUNT hndl, LONG pos, LONG len, COUNT unlock)
{
sft FAR *s;
/* Invalid function unless SHARE is installed. */
if (!IsShareInstalled()) return DE_INVLDFUNC;
/* Test that the handle is valid */
if (hndl < 0) return DE_INVLDHNDL;
/* Get the SFT block that contains the SFT */
if ((s = get_sft(hndl)) == (sft FAR *) -1) return DE_INVLDHNDL;
/* Lock violation if this SFT entry does not support locking. */
if (s->sft_shroff < 0) return DE_LOCK;
/* Let SHARE do the work. */
return share_lock_unlock(cu_psp, s->sft_shroff, pos, len, unlock);
}
/* /// End of additions for SHARE. - Ron Cemer */
/*
* This seems to work well.
*/
@ -1427,3 +1592,107 @@ struct dhdr FAR * IsDevice(BYTE FAR * fname)
return (struct dhdr FAR *)0;
}
/* /// Added for SHARE. - Ron Cemer */
BOOL IsShareInstalled(void) {
if (!share_installed) {
iregs regs;
regs.a.x = 0x1000;
intr(0x2f, &regs);
share_installed = ((regs.a.x & 0xff) == 0xff);
}
return share_installed;
}
/* 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. */
static int share_open_check
(char far *filename, /* far pointer to fully qualified filename */
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, &regs);
return (int)regs.a.x;
}
/* DOS calls this to record the fact that it has successfully
closed a file, or the fact that the open for this file failed. */
static void share_close_file
(int fileno) { /* file_table entry number */
iregs regs;
regs.a.x = 0x10a1;
regs.b.x = fileno;
intr(0x2f, &regs);
}
/* 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. */
static int share_access_check
(unsigned short pspseg,/* psp segment address of owner process */
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, &regs);
return (int)regs.a.x;
}
/* 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. */
static int share_lock_unlock
(unsigned short pspseg,/* psp segment address of owner process */
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, &regs);
return (int)regs.a.x;
}
/* /// End of additions for SHARE. - Ron Cemer */

View File

@ -36,6 +36,9 @@ BYTE *RcsId = "$Id$";
/*
* $Log$
* Revision 1.8 2000/10/29 23:51:56 jimtabor
* Adding Share Support by Ron Cemer
*
* Revision 1.7 2000/09/05 00:56:50 jimtabor
* *** empty log message ***
*
@ -199,6 +202,12 @@ struct f_node FAR *xlt_fd(COUNT);
COUNT xlt_fnp(struct f_node FAR *);
struct f_node FAR *split_path(BYTE FAR *, BYTE *, BYTE *, BYTE *);
BOOL find_fname(struct f_node FAR *, BYTE *, BYTE *);
/* /// Added - Ron Cemer */
static void merge_file_changes(struct f_node FAR *fnp, int collect);
/* /// Added - Ron Cemer */
static int is_same_file(struct f_node FAR *fnp1, struct f_node FAR *fnp2);
/* /// Added - Ron Cemer */
static int copy_file_changes(struct f_node FAR *src, struct f_node FAR *dst);
date dos_getdate(VOID);
time dos_gettime(VOID);
BOOL find_free(struct f_node FAR *);
@ -255,13 +264,20 @@ COUNT dos_open(BYTE FAR * path, COUNT flag)
fnp->f_highwater = fnp->f_dir.dir_size;
fnp->f_back = LONG_LAST_CLUSTER;
/* /// Moved to below. - Ron Cemer
fnp->f_cluster = fnp->f_dir.dir_start;
fnp->f_cluster_offset = 0l; /*JPP */
fnp->f_cluster_offset = 0l; */ /*JPP */
fnp->f_flags.f_dmod = FALSE;
fnp->f_flags.f_dnew = FALSE;
fnp->f_flags.f_ddir = FALSE;
merge_file_changes(fnp, TRUE); /* /// Added - Ron Cemer */
/* /// Moved from above. - Ron Cemer */
fnp->f_cluster = fnp->f_dir.dir_start;
fnp->f_cluster_offset = 0l; /*JPP */
return xlt_fnp(fnp);
}
@ -310,6 +326,7 @@ COUNT dos_close(COUNT fd)
{
fnp->f_dir.dir_size = fnp->f_highwater;
fnp->f_flags.f_dmod = TRUE;
merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */
}
fnp->f_flags.f_ddir = TRUE;
@ -421,6 +438,74 @@ static BOOL find_fname(struct f_node FAR * fnp, BYTE * fname, BYTE * fext)
return found;
}
/* /// Added - Ron Cemer */
/* If more than one f_node has a file open, and a write
occurs, this function must be called to propagate the
results of that write to the other f_nodes which have
that file open. Note that this function only has an
effect if SHARE is installed. This is for compatibility
reasons, since DOS without SHARE does not share changes
between two or more open instances of the same file
unless these instances were generated by dup() or dup2(). */
static void merge_file_changes(struct f_node FAR *fnp, int collect) {
struct f_node FAR *fnp2;
int i;
if (!IsShareInstalled()) return;
for (i = 0; i < NFILES; i++) {
fnp2 = &f_nodes[i];
if ( (fnp != (struct f_node FAR *)0)
&& (fnp != fnp2)
&& (fnp->f_count > 0)
&& (is_same_file(fnp, fnp2)) ) {
if (collect) {
/* We're collecting file changes from any other
f_node which refers to this file. */
if (fnp2->f_mode != RDONLY) {
fnp2->f_dir.dir_size = fnp2->f_highwater;
copy_file_changes(fnp2, fnp);
break;
}
} else {
/* We just made changes to this file, so we are
distributing these changes to the other f_nodes
which refer to this file. */
if (fnp->f_mode != RDONLY)
fnp->f_dir.dir_size = fnp->f_highwater;
copy_file_changes(fnp, fnp2);
}
}
}
}
/* /// Added - Ron Cemer */
static int is_same_file(struct f_node FAR *fnp1, struct f_node FAR *fnp2) {
return
(fnp1->f_dpb->dpb_unit == fnp2->f_dpb->dpb_unit)
&& (fnp1->f_dpb->dpb_subunit == fnp2->f_dpb->dpb_subunit)
&& (fcmp
((BYTE FAR *)fnp1->f_dir.dir_name,
(BYTE FAR *)fnp2->f_dir.dir_name, FNAME_SIZE))
&& (fcmp
((BYTE FAR *)fnp1->f_dir.dir_ext,
(BYTE FAR *)fnp2->f_dir.dir_ext, FEXT_SIZE))
&& ((fnp1->f_dir.dir_attrib & D_VOLID) == 0)
&& ((fnp2->f_dir.dir_attrib & D_VOLID) == 0)
&& (fnp1->f_flags.f_dremote == fnp2->f_flags.f_dremote)
&& (fnp1->f_diroff == fnp2->f_diroff)
&& (fnp1->f_dirstart == fnp2->f_dirstart)
&& (fnp1->f_dpb == fnp2->f_dpb);
}
/* /// Added - Ron Cemer */
static int copy_file_changes(struct f_node FAR *src, struct f_node FAR *dst) {
dst->f_highwater = src->f_highwater;
dst->f_dir.dir_start = src->f_dir.dir_start;
dst->f_dir.dir_size = src->f_dir.dir_size;
dst->f_dir.dir_date = src->f_dir.dir_date;
dst->f_dir.dir_time = src->f_dir.dir_time;
}
COUNT dos_creat(BYTE FAR * path, COUNT attrib)
{
REG struct f_node FAR *fnp;
@ -521,6 +606,8 @@ COUNT dos_creat(BYTE FAR * path, COUNT attrib)
fnp->f_flags.f_dnew = FALSE;
fnp->f_flags.f_ddir = FALSE;
merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */
return xlt_fnp(fnp);
}
@ -999,6 +1086,9 @@ BOOL dos_setfsize(COUNT fd, LONG size)
/* Change the file size */
fnp->f_dir.dir_size = size;
fnp->f_highwater = size;
merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */
return TRUE;
}
@ -1633,13 +1723,13 @@ UCOUNT writeblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err)
if (count == 0)
{
fnp->f_highwater = fnp->f_offset;
merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */
*err = SUCCESS;
return 0;
}
/* /// BUG!!! Moved to above previous block because we should NOT be able
to truncate the file if we can't write to it. - Ron Cemer
to truncate the file if we can't write to it. - Ron Cemer */
/* test that we have a valid mode for this fnode */
/*
if (fnp->f_mode != WRONLY && fnp->f_mode != RDWR)
@ -1686,6 +1776,7 @@ UCOUNT writeblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err)
fnp->f_back = LONG_LAST_CLUSTER;
fnp->f_sector = 0;
fnp->f_boff = 0;
merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */
}
/* The more difficult scenario is the (more common) */
@ -1723,19 +1814,22 @@ UCOUNT writeblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err)
return ret_cnt;
case SUCCESS:
merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */
break;
}
}
/* XFR_WRITE case only - if we're at the end, the next */
/* FAT is an EOF marker, so just extend the file length */
if (last_link(fnp))
if (last_link(fnp)) {
if (!extend(fnp))
{
dir_close(fnp);
*err = DE_HNDLDSKFULL;
return ret_cnt;
}
merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */
}
/* Compute the block within the cluster and the offset */
/* within the block. */
@ -1809,6 +1903,7 @@ UCOUNT writeblock(COUNT fd, VOID FAR * buffer, UCOUNT count, COUNT * err)
fnp->f_highwater = fnp->f_offset;
fnp->f_dir.dir_size = fnp->f_highwater;
}
merge_file_changes(fnp, FALSE); /* /// Added - Ron Cemer */
}
*err = SUCCESS;
return ret_cnt;

View File

@ -36,6 +36,9 @@ BYTE *RcsId = "$Id$";
/*
* $Log$
* Revision 1.10 2000/10/29 23:51:56 jimtabor
* Adding Share Support by Ron Cemer
*
* Revision 1.9 2000/08/06 05:50:17 jimtabor
* Add new files and update cvs with patches and changes
*
@ -1348,6 +1351,21 @@ dispatch:
}
break;
/* /// Added for SHARE. - Ron Cemer */
/* Lock/unlock file access */
case 0x5c:
if ((rc = DosLockUnlock
(r->BX,
(((unsigned long)r->CX)<<16)|(((unsigned long)r->DX)&0xffffL),
(((unsigned long)r->SI)<<16)|(((unsigned long)r->DI)&0xffffL),
((r->AX & 0xff) != 0))) != 0)
r->FLAGS |= FLG_CARRY;
else
r->FLAGS &= ~FLG_CARRY;
r->AX = -rc;
break;
/* /// End of additions for SHARE. - Ron Cemer */
/* UNDOCUMENTED: server, share.exe and sda function */
case 0x5d:
switch (r->AL)