📄 handler.c
字号:
// Build response packet
packet.build_bpb_a.bba_status = rhp.s.rhp_status;
if ( !(rhp.s.rhp_status & STATUS_ERROR) ) { // No error building BPB
packet.build_bpb_a.bba_bpb = *rhp.build_bpb_ans.bpb_bpb;
devices[device].bytes_per_sector =
rhp.build_bpb_ans.bpb_bpb->bytes_per_sector;
length = sizeof(struct build_bpb_a);
// If media is removeable, read the volume label
if (devices[device].non_removable == FALSE) {
reset_disk();
read_volume_label(device);
}
}
else { // Else error getting BPB
length = (char *) &packet.build_bpb_a.bba_bpb - (char *) &packet;
}
// Send Response Packet
if ( !FxSend(&packet, length) ) {
return FALSE;
}
devices[device].invalid = FALSE; // Clear invalid flag after we've
// successfully build a BPB
return TRUE;
}
/* Read request Handler. This routine handles a read request for a given
device driver and drive.
If this is DOS 3.0+ and error ERR_DISK_CHANGE (0FH) is returned, the driver
will (should) return the volume label.
*/
int read_handler(word count)
{
word volume_length;
int device;
count;
device = (int) packet.io_r.ior_unit;
if (device >= slave_block_devices) {
rhp.s.rhp_status = STATUS_ERROR | STATUS_DONE | ERR_UNK_UNIT;
}
else {
rhp.io_req.s.rhp_length = 22;
rhp.io_req.s.rhp_unit = devices[device].unit;
rhp.io_req.s.rhp_command = READ;
rhp.io_req.media_id = packet.io_r.ior_media_id;
rhp.io_req.io_data = buffer;
rhp.io_req.io_requested = packet.io_r.ior_requested;
if (slave_dos_version != DOS_VERSION(3, 31)) {
rhp.io_req.io_start = packet.io_r.ior_start;
rhp.io_req.io_huge_start = packet.io_r.ior_huge_start;
}
else { // else MS-DOS 3.31
rhp.io_req.s.rhp_length =
(byte) ((byte *) &rhp.io_req.reserved - (byte *) &rhp);
*((dword *) &rhp.io_req.io_start) = packet.io_r.ior_huge_start;
}
call_driver((void far *) &rhp, devices[device].header);
}
// build response packet
packet.io_a.ioa_status = rhp.s.rhp_status;
if (rhp.s.rhp_status & STATUS_ERROR)
packet.io_a.ioa_transfered = 0;
else
packet.io_a.ioa_transfered = rhp.io_ans.io_transfered;
packet.io_a.ioa_volume[0] = '\0';
packet.io_a.ioa_serial_number = 0;
volume_length = 0;
if ((rhp.s.rhp_status & 0xff) == ERR_DISK_CHANGE && _osmajor >= 3) {
memcpyf(packet.io_a.ioa_volume, rhp.io_ans.io_label, MAX_VOLUME);
volume_length = MAX_VOLUME + 4;
}
// send response packet
if ( !FxSend(&packet, (packet.io_a.ioa_volume
- (char *) &packet) + volume_length) ) {
return FALSE;
}
// send data
if (rhp.io_ans.io_transfered) {
if ( !FxSend(buffer, rhp.io_ans.io_transfered *
devices[device].bytes_per_sector) ) {
return FALSE;
}
}
return TRUE;
}
/* Write request Handler. This routine handles a write request for a given
device driver and drive.
If this is DOS 3.0+ and error ERR_DISK_CHANGE (0FH) is returned, the driver
will (should) return the volume label.
*/
int write_handler(word count)
{
int device;
word bufsiz;
word volume_length;
byte command;
count;
if (packet.packet_type == WRITE_REQ) {
command = WRITE;
}
else {
command = WRITE_VERIFY;
}
// get data to be written
bufsiz = FxReceive(buffer, (word) sizeof(buffer));
if (fx_errno) { // NOTE: have to check fx_errno because bufsize can be zero
return FALSE;
}
device = (int) packet.io_r.ior_unit;
if (device >= slave_block_devices) {
rhp.s.rhp_status = STATUS_ERROR | STATUS_DONE | ERR_UNK_UNIT;
rhp.io_ans.io_transfered = 0;
}
else if (bufsiz != packet.io_r.ior_requested *
devices[device].bytes_per_sector) {
rhp.s.rhp_status = STATUS_ERROR | STATUS_DONE | ERR_WRITE_FAULT;
rhp.io_ans.io_transfered = 0;
}
else {
rhp.io_req.s.rhp_length = 22;
rhp.io_req.s.rhp_unit = devices[device].unit;
rhp.io_req.s.rhp_command = command;
rhp.io_req.media_id = packet.io_r.ior_media_id;
rhp.io_req.io_data = buffer;
rhp.io_req.io_requested = packet.io_r.ior_requested;
rhp.io_req.io_start = packet.io_r.ior_start;
rhp.io_req.io_huge_start = packet.io_r.ior_huge_start;
if (slave_dos_version == DOS_VERSION(3, 31)) {
rhp.io_req.s.rhp_length =
(byte) ((byte *) &rhp.io_req.reserved - (byte *) &rhp);
*((dword *) &rhp.io_req.io_start) = packet.io_r.ior_huge_start;
}
call_driver((void far *) &rhp, devices[device].header);
}
// build response packet
packet.io_a.ioa_status = rhp.s.rhp_status;
packet.io_a.ioa_transfered = rhp.io_ans.io_transfered;
packet.io_a.ioa_volume[0] = '\0';
packet.io_a.ioa_serial_number = 0;
volume_length = 0;
if ((rhp.s.rhp_status & 0xff) == ERR_DISK_CHANGE && _osmajor >= 3) {
memcpyf(packet.io_a.ioa_volume, rhp.io_ans.io_label, MAX_VOLUME);
volume_length = MAX_VOLUME + 4;
}
return FxSend(&packet, (packet.io_a.ioa_volume
- (char *) &packet) + volume_length);
}
/* Error Handler. No longer used. */
int error_handler(word count)
{
return TRUE;
}
int ocrm_handler(word count)
{
int device;
byte command;
count;
if (packet.packet_type == DEV_OPEN_REQ) {
command = DEVICE_OPEN;
}
else {
command = DEVICE_CLOSE;
}
device = (int) packet.ocrm_r.ocr_unit;
if (device >= slave_block_devices) {
rhp.s.rhp_status = STATUS_ERROR | STATUS_DONE | ERR_UNK_UNIT;
}
else {
rhp.s.rhp_length = sizeof(struct static_rhp);
rhp.s.rhp_unit = (byte) device;
rhp.s.rhp_command = command;
call_driver((void far *) &rhp, devices[device].header);
}
// build response packet
packet.ocrm_a.oca_status = rhp.s.rhp_status;
// 4) send response packet
return FxSend(&packet, sizeof(struct ocrm_a));
}
int gen_ioctl_handler(word count)
{
int device;
struct media_id_buffer media_id_buffer;
byte function = 0;
device = (int) packet.gen_ioctl_r.gir_unit;
if (device >= slave_block_devices) {
rhp.s.rhp_status = STATUS_ERROR | STATUS_DONE | ERR_UNK_UNIT;
}
else {
function = packet.gen_ioctl_r.gir_function;
if (function == 0x46) {
if ( !FxReceive(&media_id_buffer, sizeof(media_id_buffer)) ) {
return FALSE;
}
}
rhp.s.rhp_length = sizeof(struct gen_ioctl_req);
rhp.s.rhp_unit = (byte) device;
rhp.s.rhp_command = GENERIC_IOCTL;
rhp.gen_ioctl_req.gen_category = packet.gen_ioctl_r.gir_category;
rhp.gen_ioctl_req.gen_function = packet.gen_ioctl_r.gir_function;
rhp.gen_ioctl_req.gen_data = &media_id_buffer;
call_driver((void far *) &rhp, devices[device].header);
}
// build response packet
packet.gen_ioctl_a.gia_status = rhp.s.rhp_status;
// 4) send response packet
if ( !FxSend(&packet, sizeof(struct gen_ioctl_a)) ) {
return FALSE;
}
if ( (rhp.s.rhp_status & STATUS_ERROR) == 0 ) {
if (function == 0x66)
return FxSend(&media_id_buffer, sizeof(media_id_buffer));
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -