STATIC int CharRequest(struct dhdr FAR **pdev, unsigned command) { struct dhdr FAR *dev = *pdev; CharReqHdr.r_command = command; CharReqHdr.r_unit = 0; CharReqHdr.r_status = 0; CharReqHdr.r_length = sizeof(request); execrh(&CharReqHdr, dev); if (CharReqHdr.r_status & S_ERROR) { for (;;) { switch (char_error(&CharReqHdr, dev)) { case ABORT: case FAIL: return DE_INVLDACC; case CONTINUE: CharReqHdr.r_count = 0; return 0; case RETRY: return 1; } } } return SUCCESS; }
COUNT DosSetTime(BYTE FAR * hp, BYTE FAR * mp, BYTE FAR * sp, BYTE FAR * hdp) { DosGetDate((BYTE FAR *) & DayOfWeek, (BYTE FAR *) & Month, (BYTE FAR *) & DayOfMonth, (COUNT FAR *) & Year); ClkRecord.clkHours = *hp; ClkRecord.clkMinutes = *mp; ClkRecord.clkSeconds = *sp; ClkRecord.clkHundredths = *hdp; YearsSince1980 = Year - 1980; ClkRecord.clkDays = DayOfMonth - 1 + days[is_leap_year(Year)][Month - 1] + ((YearsSince1980) * 365) + ((YearsSince1980 + 3) / 4); ClkReqHdr.r_length = sizeof(request); ClkReqHdr.r_command = C_OUTPUT; ClkReqHdr.r_count = sizeof(struct ClockRecord); ClkReqHdr.r_trans = (BYTE FAR *) (&ClkRecord); ClkReqHdr.r_status = 0; execrh((request FAR *) & ClkReqHdr, (struct dhdr FAR *)clock); if (ClkReqHdr.r_status & S_ERROR) return char_error(&ClkReqHdr, (struct dhdr FAR *)clock); return SUCCESS; }
UCOUNT BinaryCharIO(struct dhdr FAR * dev, UCOUNT n, void FAR * bp, unsigned command, COUNT *err) { *err = SUCCESS; FOREVER { CharReqHdr.r_length = sizeof(request); CharReqHdr.r_command = command; CharReqHdr.r_count = n; CharReqHdr.r_trans = bp; CharReqHdr.r_status = 0; execrh(&CharReqHdr, dev); if (CharReqHdr.r_status & S_ERROR) { charloop: switch (char_error(&CharReqHdr, dev)) { case ABORT: case FAIL: *err = DE_INVLDACC; return 0; case CONTINUE: break; case RETRY: continue; default: goto charloop; } } break; } return CharReqHdr.r_count; }
COUNT DosSetTime(BYTE h, BYTE m, BYTE s, BYTE hd) { /* for ClkRecord.clkDays */ ExecuteClockDriverRequest(C_INPUT); ClkRecord.clkHours = h; ClkRecord.clkMinutes = m; ClkRecord.clkSeconds = s; ClkRecord.clkHundredths = hd; ExecuteClockDriverRequest(C_OUTPUT); if (ClkReqHdr.r_status & S_ERROR) return char_error(&ClkReqHdr, (struct dhdr FAR *)clock); return SUCCESS; }
UCOUNT DosWrite(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err) { sft FAR *s; WORD sys_idx; sfttbl FAR *sp; UCOUNT ReadCount; /* Test that the handle is valid */ if (hndl < 0) { *err = DE_INVLDHNDL; return 0; } /* Get the SFT block that contains the SFT */ if ((s = get_sft(hndl)) == (sft FAR *) - 1) { *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; } if (s->sft_flags & SFT_FSHARED) { ReadCount = Remote_RW(REM_WRITE, n, bp, s, err); if (err) { return ReadCount; } else return 0; } /* Do a device write if device */ if (s->sft_flags & SFT_FDEVICE) { request rq; /* set to no EOF */ s->sft_flags &= ~SFT_FEOF; /* 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 { REG WORD c, cnt = n, spaces_left = 0, next_pos, xfer = 0; static BYTE space = ' '; start: if (cnt-- == 0) goto end; if (*bp == CTL_Z) goto end; if (s->sft_flags & SFT_FCONOUT) { switch (*bp) { case CR: next_pos = 0; break; case LF: case BELL: next_pos = scr_pos; break; case BS: next_pos = scr_pos ? scr_pos - 1 : 0; break; case HT: spaces_left = 8 - (scr_pos & 7); next_pos = scr_pos + spaces_left; goto output_space; default: next_pos = scr_pos + 1; } } rq.r_length = sizeof(request); rq.r_command = C_OUTPUT; rq.r_count = 1; rq.r_trans = bp; rq.r_status = 0; execrh((request FAR *) & rq, s->sft_dev); if (rq.r_status & S_ERROR) char_error(&rq, s->sft_dev); goto post; output_space: rq.r_length = sizeof(request); rq.r_command = C_OUTPUT; rq.r_count = 1; rq.r_trans = &space; rq.r_status = 0; execrh((request FAR *) & rq, s->sft_dev); if (rq.r_status & S_ERROR) char_error(&rq, s->sft_dev); --spaces_left; post: if (spaces_left) goto output_space; ++bp; ++xfer; if (s->sft_flags & SFT_FCONOUT) scr_pos = next_pos; if (break_ena && control_break()) { handle_break(); goto end; } goto start; end: *err = SUCCESS; return xfer; } } else /* a block write */ { COUNT rc; ReadCount = writeblock(s->sft_status, bp, n, &rc); if (rc < SUCCESS) { *err = rc; return 0; } else { *err = SUCCESS; return ReadCount; } } *err = SUCCESS; return 0; }
/* * 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 */ UCOUNT GenericRead(COUNT hndl, UCOUNT n, BYTE FAR * bp, COUNT FAR * err, BOOL force_binary) { sft FAR *s; WORD sys_idx; sfttbl FAR *sp; UCOUNT ReadCount; /* Test that the handle is valid */ if (hndl < 0) { *err = DE_INVLDHNDL; return 0; } /* Get the SFT block that contains the SFT */ if ((s = get_sft(hndl)) == (sft FAR *) - 1) { *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; } /* * Do remote first or return error. * must have been opened from remote. */ if (s->sft_flags & SFT_FSHARED) { ReadCount = Remote_RW(REM_READ, n, bp, s, err); if (err) { *err = SUCCESS; return ReadCount; } else return 0; } /* 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; kb_buf.kb_count = 0; sti((keyboard FAR *) & kb_buf); fbcopy((BYTE FAR *) kb_buf.kb_buf, bp, kb_buf.kb_count); *err = SUCCESS; return kb_buf.kb_count; } else { *bp = _sti(); *err = SUCCESS; return 1; } } else /* a block read */ { COUNT rc; ReadCount = readblock(s->sft_status, bp, n, &rc); if (rc != SUCCESS) { *err = rc; return 0; } else { *err = SUCCESS; return ReadCount; } } *err = SUCCESS; return 0; }
COUNT DosDevIOctl(iregs FAR * r, COUNT FAR * err) { sft FAR *s; struct dpb FAR *dpbp; BYTE FAR *pBuffer = MK_FP(r->DS, r->DX); COUNT nMode; /* Test that the handle is valid */ switch (r->AL) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x06: case 0x07: case 0x0a: case 0x0c: /* Get the SFT block that contains the SFT */ if ((s = get_sft(r->BX)) == (sft FAR *) - 1) { *err = DE_INVLDHNDL; return 0; } break; case 0x04: case 0x05: case 0x08: case 0x09: case 0x0d: case 0x0e: case 0x0f: case 0x10: case 0x11: if (r->BL > nblkdev) { *err = DE_INVLDDRV; return 0; } else { /* 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 */ if (r->BL == 0) dpbp = &blk_devices[default_drive]; else dpbp = &blk_devices[r->BL - 1]; } break; case 0x0b: /* skip, it's a special case. */ NetDelay = r->CX; if (!r->DX) NetRetry = r->DX; break; default: *err = DE_INVLDFUNC; return 0; } switch (r->AL) { case 0x00: /* Get the flags from the SFT */ r->DX = r->AX = s->sft_flags; /* Test for file and network SFT. These return a 0 in */ /* the AH register. */ if ((s->sft_flags & SFT_FSHARED) || !(s->sft_flags & SFT_FDEVICE)) { r->AH = 0; } break; case 0x01: /* sft_flags is a file, return an error because you */ /* can't set the status of a file. */ if (!(s->sft_flags & SFT_FDEVICE)) { *err = DE_INVLDFUNC; return 0; } /* Set it to what we got in the DL register from the */ /* user. */ r->AL = s->sft_flags_lo = SFT_FDEVICE | r->DL; break; case 0x0c: nMode = C_GENIOCTL; goto IoCharCommon; case 0x02: nMode = C_IOCTLIN; goto IoCharCommon; case 0x10: nMode = C_IOCTLQRY; goto IoCharCommon; case 0x03: nMode = C_IOCTLOUT; IoCharCommon: if ((s->sft_flags & SFT_FDEVICE) || ((r->AL == 0x10) && !(s->sft_dev->dh_attr & ATTR_QRYIOCTL)) || ((r->AL == 0x0c) && !(s->sft_dev->dh_attr & ATTR_GENIOCTL))) { if (s->sft_dev->dh_attr & SFT_FIOCTL) { CharReqHdr.r_unit = 0; CharReqHdr.r_length = sizeof(request); CharReqHdr.r_command = nMode; CharReqHdr.r_count = r->CX; CharReqHdr.r_trans = pBuffer; CharReqHdr.r_status = 0; execrh((request FAR *) & CharReqHdr, s->sft_dev); if (CharReqHdr.r_status & S_ERROR) return char_error(&CharReqHdr, s->sft_dev); if (r->AL == 0x07) { r->AL = CharReqHdr.r_status & S_BUSY ? 00 : 0xff; } break; } } *err = DE_INVLDFUNC; return 0; case 0x0d: nMode = C_GENIOCTL; goto IoBlockCommon; case 0x04: nMode = C_IOCTLIN; goto IoBlockCommon; case 0x11: nMode = C_IOCTLQRY; goto IoBlockCommon; case 0x05: nMode = C_IOCTLOUT; IoBlockCommon: if ((dpbp->dpb_device->dh_attr & ATTR_IOCTL) || ((r->AL == 0x11) && !(dpbp->dpb_device->dh_attr & ATTR_QRYIOCTL)) || ((r->AL == 0x0d) && !(dpbp->dpb_device->dh_attr & ATTR_GENIOCTL))) { *err = DE_INVLDFUNC; return 0; } CharReqHdr.r_unit = r->BL; CharReqHdr.r_length = sizeof(request); CharReqHdr.r_command = nMode; CharReqHdr.r_count = r->CX; CharReqHdr.r_trans = pBuffer; CharReqHdr.r_status = 0; execrh((request FAR *) & CharReqHdr, dpbp->dpb_device); if (r->AL == 0x08) { if (CharReqHdr.r_status & S_ERROR) { *err = DE_DEVICE; return 0; } r->AX = (CharReqHdr.r_status & S_BUSY) ? 1 : 0; } else { if (CharReqHdr.r_status & S_ERROR) { *err = DE_DEVICE; return 0; } } break; case 0x06: if (s->sft_flags & SFT_FDEVICE) { r->AL = s->sft_flags & SFT_FEOF ? 0 : 0xFF; } else r->AL = s->sft_posit >= s->sft_size ? 0xFF : 0; break; case 0x07: if (s->sft_flags & SFT_FDEVICE) { goto IoCharCommon; } r->AL = 0; break; case 0x08: if (dpbp->dpb_device->dh_attr & ATTR_EXCALLS) { nMode = C_REMMEDIA; goto IoBlockCommon; } *err = DE_INVLDFUNC; return 0; case 0x09: r->DX = dpbp->dpb_device->dh_attr; break; case 0x0a: r->DX = s->sft_dcb->dpb_device->dh_attr; break; case 0x0e: nMode = C_GETLDEV; goto IoLogCommon; case 0x0f: nMode = C_SETLDEV; IoLogCommon: if ((dpbp->dpb_device->dh_attr & ATTR_GENIOCTL)) { if (r->BL == 0) r->BL = default_drive; CharReqHdr.r_unit = r->BL; CharReqHdr.r_length = sizeof(request); CharReqHdr.r_command = nMode; CharReqHdr.r_count = r->CX; CharReqHdr.r_trans = pBuffer; CharReqHdr.r_status = 0; execrh((request FAR *) & CharReqHdr, dpbp->dpb_device); if (CharReqHdr.r_status & S_ERROR) *err = DE_ACCESS; else *err = SUCCESS; return 0; } *err = DE_INVLDFUNC; return 0; default: *err = DE_INVLDFUNC; return 0; } *err = SUCCESS; return 0; }
COUNT DosDevIOctl(iregs FAR * r, COUNT FAR * err) { sft FAR *s; struct dpb FAR *dpbp; BYTE FAR *pBuffer = MK_FP(r->DS, r->DX); COUNT nMode; switch (r->AL) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x06: case 0x07: case 0x0a: case 0x0c: if ((s = get_sft(r->BX)) == (sft FAR *) - 1) { *err = DE_INVLDHNDL; return 0; } break; case 0x04: case 0x05: case 0x08: case 0x09: case 0x0d: case 0x0e: case 0x0f: case 0x10: case 0x11: if (r->BL > nblkdev) { *err = DE_INVLDDRV; return 0; } else { if (r->BL == 0) dpbp = &blk_devices[default_drive]; else dpbp = &blk_devices[r->BL - 1]; } break; case 0x0b: break; default: *err = DE_INVLDFUNC; return 0; } switch (r->AL) { case 0x00: r->DX = r->AX = s->sft_flags; if ((s->sft_flags & SFT_FSHARED) || !(s->sft_flags & SFT_FDEVICE)) { r->AH = 0; } break; case 0x01: if (!(s->sft_flags & SFT_FDEVICE)) { *err = DE_INVLDFUNC; return 0; } r->AL = s->sft_flags_lo = SFT_FDEVICE | r->DL; break; case 0x0c: nMode = C_GENIOCTL; goto IoCharCommon; case 0x02: nMode = C_IOCTLIN; goto IoCharCommon; case 0x10: nMode = C_IOCTLQRY; goto IoCharCommon; case 0x03: nMode = C_IOCTLOUT; IoCharCommon: if (!(s->sft_flags & SFT_FDEVICE) || ((r->AL == 0x10) && !(s->sft_dev->dh_attr & ATTR_QRYIOCTL)) || ((r->AL == 0x0c) && !(s->sft_dev->dh_attr & ATTR_GENIOCTL))) { if (s->sft_dev->dh_attr & SFT_FIOCTL) { CharReqHdr.r_unit = 0; CharReqHdr.r_length = sizeof(request); CharReqHdr.r_command = nMode; CharReqHdr.r_count = r->CX; CharReqHdr.r_trans = pBuffer; CharReqHdr.r_status = 0; execrh((request FAR *) & CharReqHdr, s->sft_dev); if (CharReqHdr.r_status & S_ERROR) return char_error(&CharReqHdr, s->sft_dev); if (r->AL == 0x07) { r->AL = CharReqHdr.r_status & S_BUSY ? 00 : 0xff; } break; } } *err = DE_INVLDFUNC; return 0; case 0x0d: nMode = C_GENIOCTL; goto IoBlockCommon; case 0x04: nMode = C_IOCTLIN; goto IoBlockCommon; case 0x11: nMode = C_IOCTLQRY; goto IoBlockCommon; case 0x05: nMode = C_IOCTLOUT; IoBlockCommon: if (!(dpbp->dpb_device->dh_attr & ATTR_IOCTL) || ((r->AL == 0x11) && !(dpbp->dpb_device->dh_attr & ATTR_QRYIOCTL)) || ((r->AL == 0x0d) && !(dpbp->dpb_device->dh_attr & ATTR_GENIOCTL))) { *err = DE_INVLDFUNC; return 0; } CharReqHdr.r_unit = r->BL; CharReqHdr.r_length = sizeof(request); CharReqHdr.r_command = nMode; CharReqHdr.r_count = r->CX; CharReqHdr.r_trans = pBuffer; CharReqHdr.r_status = 0; execrh((request FAR *) & CharReqHdr, dpbp->dpb_device); if (r->AL == 0x08) { if (CharReqHdr.r_status & S_ERROR) { *err = DE_DEVICE; return 0; } r->AX = (CharReqHdr.r_status & S_BUSY) ? 1 : 0; } else { if (CharReqHdr.r_status & S_ERROR) { *err = DE_DEVICE; return 0; } } break; case 0x06: if (s->sft_flags & SFT_FDEVICE) { r->AL = s->sft_flags & SFT_FEOF ? 0 : 0xFF; } else r->AL = s->sft_posit >= s->sft_size ? 0xFF : 0; break; case 0x07: if (s->sft_flags & SFT_FDEVICE) { goto IoCharCommon; } r->AL = 0; break; case 0x08: if (dpbp->dpb_device->dh_attr & ATTR_EXCALLS) { nMode = C_REMMEDIA; goto IoBlockCommon; } *err = DE_INVLDFUNC; return 0; case 0x09: r->DX = dpbp->dpb_device->dh_attr; break; case 0x0a: r->DX = s->sft_dcb->dpb_device->dh_attr; break; case 0x0e: nMode = C_GETLDEV; goto IoLogCommon; case 0x0f: nMode = C_SETLDEV; IoLogCommon: if (!(dpbp->dpb_device->dh_attr & ATTR_GENIOCTL)) { if (r->BL == 0) r->BL = default_drive; CharReqHdr.r_unit = r->BL; CharReqHdr.r_length = sizeof(request); CharReqHdr.r_command = nMode; CharReqHdr.r_count = r->CX; CharReqHdr.r_trans = pBuffer; CharReqHdr.r_status = 0; execrh((request FAR *) & CharReqHdr, dpbp->dpb_device); if (CharReqHdr.r_status & S_ERROR) *err = DE_ACCESS; else *err = SUCCESS; return 0; } *err = DE_INVLDFUNC; return 0; default: *err = DE_INVLDFUNC; return 0; } *err = SUCCESS; return 0; }