diff --git a/hdr/network.h b/hdr/network.h index dcb66f0..7e33e5c 100644 --- a/hdr/network.h +++ b/hdr/network.h @@ -59,6 +59,9 @@ #define REM_PRINTREDIR 0x1125 #define REM_EXTOC 0x112e +/* Redirector extensions */ +#define REM_GETLARGESPACE 0x11a3 + struct rgds { UWORD r_spc; UWORD r_navc; diff --git a/kernel/dosfns.c b/kernel/dosfns.c index f9655f8..3a8451f 100644 --- a/kernel/dosfns.c +++ b/kernel/dosfns.c @@ -771,7 +771,7 @@ UWORD DosGetFree(UBYTE drive, UWORD * navc, UWORD * bps, UWORD * nc) /* navc==NULL means: called from FatGetDrvData, fcbfns.c */ struct dpb FAR *dpbp; struct cds FAR *cdsp; - COUNT rg[4]; + COUNT rg[5]; /* add space for SI, although it's unused here */ UWORD spc; /* first check for valid drive */ @@ -876,7 +876,7 @@ COUNT DosGetExtFree(BYTE FAR * DriveString, struct xfreespace FAR * xfsp) { struct dpb FAR *dpbp; struct cds FAR *cdsp; - UCOUNT rg[4]; + UCOUNT rg[5]; /* ensure all fields known value - clear reserved bytes & set xfs_version.actual to 0 */ fmemset(xfsp, 0, sizeof(struct xfreespace)); @@ -899,13 +899,44 @@ COUNT DosGetExtFree(BYTE FAR * DriveString, struct xfreespace FAR * xfsp) if (cdsp->cdsFlags & CDSNETWDRV) { - if (remote_getfree(cdsp, rg) != SUCCESS) - return DE_INVLDDRV; + /* Try redirector extension */ + if (remote_getfree_11a3(cdsp, rg) != SUCCESS) + { + /* Fallback */ + if (remote_getfree(cdsp, rg) != SUCCESS) + return DE_INVLDDRV; - xfsp->xfs_clussize = rg[0]; - xfsp->xfs_totalclusters = rg[1]; - xfsp->xfs_secsize = rg[2]; - xfsp->xfs_freeclusters = rg[3]; + xfsp->xfs_clussize = rg[0]; + xfsp->xfs_totalclusters = rg[1]; + xfsp->xfs_secsize = rg[2]; + xfsp->xfs_freeclusters = rg[3]; + } + else /* Supports extension */ + { + UDWORD total, avail; + UDWORD bps, spc; + + bps = rg[4]; + spc = 1; + total = (((UDWORD)rg[0] << 16UL) | rg[1]); + avail = (((UDWORD)rg[2] << 16UL) | rg[3]); + + while (total > 0x00ffffff && spc < 128) { + spc *= 2; + avail /= 2; + total /= 2; + } + while (total > 0x00ffffff && bps < 32768) { + bps *= 2; + avail /= 2; + total /= 2; + } + + xfsp->xfs_secsize = bps; + xfsp->xfs_clussize = spc; + xfsp->xfs_totalclusters = total; + xfsp->xfs_freeclusters = avail; + } } else { diff --git a/kernel/int2f.asm b/kernel/int2f.asm index 70f1bca..8ab31fc 100644 --- a/kernel/int2f.asm +++ b/kernel/int2f.asm @@ -428,6 +428,8 @@ call_int2f: push cx ; arg cmp al, 0ch je remote_getfree + cmp al, 0xa3 + je remote_getfree cmp al, 1eh je remote_print_doredir cmp al, 1fh @@ -478,6 +480,7 @@ remote_getfree: mov [di+2],bx mov [di+4],cx mov [di+6],dx + mov [di+8],si ; for REM_GETLARGEFREE, unused on REM_GETFREE jmp short ret_set_ax_to_carry remote_rw: diff --git a/kernel/proto.h b/kernel/proto.h index f8fa240..551d03b 100644 --- a/kernel/proto.h +++ b/kernel/proto.h @@ -377,6 +377,7 @@ int network_redirector_fp(unsigned cmd, void far *s); long ASMPASCAL network_redirector_mx(unsigned cmd, void far *s, void *arg); #define remote_rw(cmd,s,arg) network_redirector_mx(cmd, s, (void *)arg) #define remote_getfree(s,d) (int)network_redirector_mx(REM_GETSPACE, s, d) +#define remote_getfree_11a3(s,d) (int)network_redirector_mx(REM_GETLARGESPACE, s, d) #define remote_lseek(s,new_pos) network_redirector_mx(REM_LSEEK, s, &new_pos) #define remote_setfattr(attr) (int)network_redirector_mx(REM_SETATTR, NULL, (void *)attr) #define remote_printredir(dx,ax) (int)network_redirector_mx(REM_PRINTREDIR, MK_FP(0,dx),(void *)ax)