patch: ioctl.c Hi! - 3 nested switches splitted by two separate swicth: one prepares parameters (attr, flags), other calls execrh(). - CharReqHdr.r_command computed through table lookup. - remained only one goto.
Result: DGROUP increased from 1646h to 1658h (18 bytes), TGROUP decreased from de6eh to ddceh (160 bytes). _DATA segment increased from 248h to 25ah, HMA_TEXT segment decreased from a482h to a3e5h.
--- Begin Message ---diff -ruNp old/kernel/ioctl.c new/kernel/ioctl.c --- old/kernel/ioctl.c 2004-05-29 02:51:30.000000000 +0000 +++ new/kernel/ioctl.c 2004-05-31 20:58:14.000000000 +0000 @@ -56,38 +56,38 @@ static BYTE *RcsId = COUNT DosDevIOctl(lregs * r) { + static UBYTE cmd [] = { + 0, 0, + /* 0x02 */ C_IOCTLIN, + /* 0x03 */ C_IOCTLOUT, + /* 0x04 */ C_IOCTLIN, + /* 0x05 */ C_IOCTLOUT, + /* 0x06 */ C_ISTAT, + /* 0x07 */ C_OSTAT, + /* 0x08 */ C_REMMEDIA, + 0, 0, 0, + /* 0x0c */ C_GENIOCTL, + /* 0x0d */ C_GENIOCTL, + /* 0x0e */ C_GETLDEV, + /* 0x0f */ C_SETLDEV, + /* 0x10 */ C_IOCTLQRY, + /* 0x11 */ C_IOCTLQRY, + }; + sft FAR *s; struct dpb FAR *dpbp; - COUNT nMode; - unsigned attr; - unsigned char al = r->AL; - - if (al > 0x11) - return DE_INVLDFUNC; - - /* commonly used, shouldn't harm to do front up */ - if (al == 0x0C || al == 0x0D || al >= 0x10) /* generic or query */ - { - CharReqHdr.r_cat = r->CH; /* category (major) code */ - CharReqHdr.r_fun = r->CL; /* function (minor) code */ - CharReqHdr.r_io = MK_FP(r->DS, r->DX); /* parameter block */ - } - else - { - CharReqHdr.r_count = r->CX; - CharReqHdr.r_trans = MK_FP(r->DS, r->DX); - } - CharReqHdr.r_length = sizeof(request); - CharReqHdr.r_status = 0; + unsigned attr, flags; switch (r->AL) { + default: /* 0x12+ */ + return DE_INVLDFUNC; + case 0x0b: - /* skip, it's a special case. */ - NetDelay = r->CX; - if (r->DX) + if (r->DX) /* skip, it's a special case */ NetRetry = r->DX; - break; + NetDelay = r->CX; + return SUCCESS; case 0x00: case 0x01: @@ -98,30 +98,79 @@ COUNT DosDevIOctl(lregs * r) case 0x0a: case 0x0c: case 0x10: - { - unsigned flags; - /* Test that the handle is valid and */ /* get the SFT block that contains the SFT */ - if ((s = get_sft(r->BX)) == (sft FAR *) - 1) + if ((s = get_sft(r->BX)) == (sft FAR *)-1) return DE_INVLDHNDL; - attr = s->sft_dev->dh_attr; flags = s->sft_flags; + break; - switch (r->AL) + case 0x04: + case 0x05: + case 0x08: + case 0x09: + case 0x0d: + case 0x0e: + case 0x0f: + case 0x11: +/* + This line previously returned the deviceheader at r->bl. But, + DOS numbers its drives starting at 1, not 0. A=1, B=2, and so + on. Changed this line so it is now zero-based. + + -SRM + */ +/* JPP - changed to use default drive if drive=0 */ +/* JT Fixed it */ + +#define NDN_HACK +/* NDN feeds the actual ASCII drive letter to this function */ +#ifdef NDN_HACK + CharReqHdr.r_unit = ((r->BL & 0x1f) == 0 ? default_drive : + (r->BL & 0x1f) - 1); +#else + CharReqHdr.r_unit = (r->BL == 0 ? default_drive : r->BL - 1); +#endif + + if ((dpbp = get_dpb(CharReqHdr.r_unit)) != NULL) + attr = dpbp->dpb_device->dh_attr; + else { - case 0x00: + if (r->AL != 0x09) + return DE_INVLDDRV; + attr = ATTR_REMOTE; + } + } /* switch */ + + /* commonly used, shouldn't harm to do front up */ + if (r->AL == 0x0C || r->AL == 0x0D || r->AL >= 0x10) /* generic or query */ + { + CharReqHdr.r_cat = r->CH; /* category (major) code */ + CharReqHdr.r_fun = r->CL; /* function (minor) code */ + CharReqHdr.r_io = MK_FP(r->DS, r->DX); /* parameter block */ + } + else + { + CharReqHdr.r_count = r->CX; + CharReqHdr.r_trans = MK_FP(r->DS, r->DX); + } + CharReqHdr.r_length = sizeof(request); + CharReqHdr.r_status = 0; + CharReqHdr.r_command = cmd [r->AL]; + + switch (r->AL) + { + case 0x00: /* Get the flags from the SFT */ + r->DX = flags; if (flags & SFT_FDEVICE) - r->AX = (attr & 0xff00) | (flags & 0xff); - else - r->AX = flags; + r->DH = attr >> 8; /* Undocumented result, Ax = Dx seen using Pcwatch */ - r->DX = r->AX; + r->AX = r->DX; break; - case 0x01: + case 0x01: /* sft_flags is a file, return an error because you */ /* can't set the status of a file. */ if (!(flags & SFT_FDEVICE)) @@ -139,198 +188,104 @@ COUNT DosDevIOctl(lregs * r) s->sft_flags_lo = SFT_FDEVICE | r->DL; break; - case 0x02: - nMode = C_IOCTLIN; - goto IoCharCommon; - - case 0x03: - nMode = C_IOCTLOUT; - goto IoCharCommon; - - case 0x06: - if (flags & SFT_FDEVICE) - { - nMode = C_ISTAT; - goto IoCharCommon; - } - r->AL = s->sft_posit >= s->sft_size ? 0 : 0xFF; - break; - - case 0x07: - if (flags & SFT_FDEVICE) - { - nMode = C_OSTAT; - goto IoCharCommon; - } - r->AL = 0; - break; - - case 0x0a: + case 0x0a: r->DX = flags; r->AX = 0; break; - case 0x0c: - nMode = C_GENIOCTL; - goto IoCharCommon; - - default: /* 0x10 */ - nMode = C_IOCTLQRY; - IoCharCommon: - if ((flags & SFT_FDEVICE) && - ( (r->AL <= 0x03 && (attr & ATTR_IOCTL)) - || r->AL == 0x06 || r->AL == 0x07 - || (r->AL == 0x10 && (attr & ATTR_QRYIOCTL)) - || (r->AL == 0x0c && (attr & ATTR_GENIOCTL)))) + case 0x06: + if (!(flags & SFT_FDEVICE)) { - CharReqHdr.r_unit = 0; - CharReqHdr.r_command = nMode; - execrh((request FAR *) & CharReqHdr, s->sft_dev); - - if (CharReqHdr.r_status & S_ERROR) - { - CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13; - return DE_DEVICE; - } - - if (r->AL <= 0x03) - r->AX = CharReqHdr.r_count; - else if (r->AL <= 0x07) - r->AX = CharReqHdr.r_status & S_BUSY ? 0000 : 0x00ff; - else /* 0x0c or 0x10 */ - r->AX = CharReqHdr.r_status; + r->AL = s->sft_posit >= s->sft_size ? 0 : 0xFF; break; } - return DE_INVLDFUNC; - } - break; - } - - default: /* block IOCTL: 4, 5, 8, 9, d, e, f, 11 */ - -/* - This line previously returned the deviceheader at r->bl. But, - DOS numbers its drives starting at 1, not 0. A=1, B=2, and so - on. Changed this line so it is now zero-based. + /* fall through */ - -SRM - */ -/* JPP - changed to use default drive if drive=0 */ -/* JT Fixed it */ + case 0x07: + if (!(flags & SFT_FDEVICE)) + { + r->AL = 0; + break; + } + /* fall through */ -#define NDN_HACK -/* NDN feeds the actual ASCII drive letter to this function */ -#ifdef NDN_HACK - CharReqHdr.r_unit = ((r->BL & 0x1f) == 0 ? default_drive : - (r->BL & 0x1f) - 1); -#else - CharReqHdr.r_unit = (r->BL == 0 ? default_drive : r->BL - 1); -#endif + case 0x02: + case 0x03: + case 0x0c: + case 0x10: + if (!(flags & SFT_FDEVICE) || + r->AL <= 0x03 && !(attr & ATTR_IOCTL) || + r->AL == 0x0c && !(attr & ATTR_GENIOCTL) || + r->AL == 0x10 && !(attr & ATTR_QRYIOCTL)) + return DE_INVLDFUNC; - dpbp = get_dpb(CharReqHdr.r_unit); - if (dpbp) - attr = dpbp->dpb_device->dh_attr; - else if (r->AL != 9) - return DE_INVLDDRV; + CharReqHdr.r_unit = 0; + execrh((request FAR *) & CharReqHdr, s->sft_dev); + goto commoncheck; - switch (r->AL) - { - case 0x04: - nMode = C_IOCTLIN; - goto IoBlockCommon; - case 0x05: - nMode = C_IOCTLOUT; - goto IoBlockCommon; - case 0x08: - if (attr & ATTR_EXCALLS) - { - nMode = C_REMMEDIA; - goto IoBlockCommon; - } - return DE_INVLDFUNC; - case 0x09: + case 0x09: { - struct cds FAR *cdsp = get_cds(CharReqHdr.r_unit); + const struct cds FAR *cdsp = get_cds(CharReqHdr.r_unit); r->AX = S_DONE | S_BUSY; - if (cdsp != NULL && dpbp == NULL) - { - r->DX = ATTR_REMOTE; - } - else - { - if (!dpbp) - { - return DE_INVLDDRV; - } - r->DX = attr; - } + if (cdsp == NULL) + return DE_INVLDDRV; if (cdsp->cdsFlags & CDSSUBST) - { - r->DX |= ATTR_SUBST; - } + attr |= ATTR_SUBST; + r->DX = attr; break; } - case 0x0d: - nMode = C_GENIOCTL; - goto IoBlockCommon; - case 0x11: - nMode = C_IOCTLQRY; - IoBlockCommon: + + case 0x08: + if (!(attr & ATTR_EXCALLS)) + return DE_INVLDFUNC; + /* fall through */ + + case 0x0d: if (r->AL == 0x0D && (r->CX & ~(0x486B-0x084A)) == 0x084A) { /* 084A/484A, 084B/484B, 086A/486A, 086B/486B */ r->AX = 0; /* (lock/unlock logical/physical volume) */ break; /* simulate success for MS-DOS 7+ SCANDISK etc. --LG */ } - if ((r->AL <= 0x05 && !(attr & ATTR_IOCTL)) - || (r->AL == 0x11 && !(attr & ATTR_QRYIOCTL)) - || (r->AL == 0x0d && !(attr & ATTR_GENIOCTL))) - { + /* fall through */ + + case 0x04: + case 0x05: + case 0x11: + if (r->AL <= 0x05 && !(attr & ATTR_IOCTL) || + r->AL == 0x0d && !(attr & ATTR_GENIOCTL) || + r->AL == 0x11 && !(attr & ATTR_QRYIOCTL)) return DE_INVLDFUNC; - } - CharReqHdr.r_command = nMode; execrh((request FAR *) & CharReqHdr, dpbp->dpb_device); - + commoncheck: if (CharReqHdr.r_status & S_ERROR) { CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13; return DE_DEVICE; } - if (r->AL <= 0x05) + + if (r->AL <= 0x05) /* 0x02, 0x03, 0x04, 0x05 */ r->AX = CharReqHdr.r_count; - else if (r->AL == 0x08) + else if (r->AL <= 0x07) /* 0x06, 0x07 */ + r->AX = CharReqHdr.r_status & S_BUSY ? 0000 : 0x00ff; + else if (r->AL == 0x08) /* 0x08 */ r->AX = (CharReqHdr.r_status & S_BUSY) ? 1 : 0; - else /* 0x0d or 0x11 */ + else /* 0x0c, 0x0d, 0x10, 0x11 */ r->AX = CharReqHdr.r_status; break; - case 0x0e: - nMode = C_GETLDEV; - goto IoLogCommon; - default: /* 0x0f */ - nMode = C_SETLDEV; - IoLogCommon: - if (attr & ATTR_GENIOCTL) + case 0x0e: + default: /* 0x0f */ + if (!(attr & ATTR_GENIOCTL)) + return DE_INVLDFUNC; + + execrh((request FAR *) & CharReqHdr, dpbp->dpb_device); + if (CharReqHdr.r_status & S_ERROR) { - - CharReqHdr.r_command = nMode; - execrh((request FAR *) & CharReqHdr, dpbp->dpb_device); - - if (CharReqHdr.r_status & S_ERROR) - { - CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13; - return DE_ACCESS; - } - else - { - r->AL = CharReqHdr.r_unit; - return SUCCESS; - } + CritErrCode = (CharReqHdr.r_status & S_MASK) + 0x13; + return DE_ACCESS; } - return DE_INVLDFUNC; - } - break; - } + r->AL = CharReqHdr.r_unit; + } /* switch */ return SUCCESS; } -
--- End Message ---
