⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 driveio.c

📁 format命令的源代码
💻 C
字号:
/*
// Program:  Format
// Version:  0.90
// Written By:  Brian E. Reifsnyder
// Copyright:  2002 under the terms of the GNU GPL, Version 2
// Module Name:  driveio.c
// Module Description:  Functions specific to accessing a disk.
*/

#define DIO

#include "driveio.h"
#include "format.h"



/* Clear Huge Sector Buffer */
void Clear_Huge_Sector_Buffer()
{
  memset(huge_sector_buffer, 0, sizeof(huge_sector_buffer));
}

/* Clear Sector Buffer */
void Clear_Sector_Buffer()
{
  memset(sector_buffer, 0, 512);
}


int Drive_IO(int command,unsigned long sector_number,int number_of_sectors)
{
  unsigned int return_code;
  int error_counter = 0;

  retry:

  if(param.fat_type != FAT32)
    {
    return_code =
       TE_AbsReadWrite(param.drive_number,number_of_sectors,sector_number,
	   number_of_sectors==1 ?sector_buffer : huge_sector_buffer,
	   command);
    }
  else
    {
    return_code =
       FAT32_AbsReadWrite(param.drive_number,number_of_sectors,sector_number,
	   number_of_sectors==1 ?sector_buffer : huge_sector_buffer,
	   command);
    }

  if(return_code==0x0408)
    {
    /* As per RBIL, if 0x0408 is returned, retry with high bit of AL set. */
    param.drive_number = param.drive_number + 0x80; /* set high bit. */
    error_counter++;
    if(debug_prog==TRUE) printf("[DEBUG]  Retrying drive access.  High bit of AL is set.\n");
    goto retry;
    }

  if( (return_code!=0) && (error_counter<3) )
    {
    error_counter++;
    if(debug_prog==TRUE) printf("[DEBUG]  Retrying drive access.  Retry number->  %2d\n",error_counter);
    goto retry;
    }

  if(return_code!=0) Critical_Error_Handler(DOS,return_code);

  param.drive_number = param.drive_number & 0x7f; /* unset high bit. */
  return (return_code);
}


void Enable_Disk_Access()
{
  unsigned char category_code;
  unsigned long error_code=0;

  if(param.fat_type!=FAT32) category_code = 0x08;
  else                      category_code = 0x48;

  if(debug_prog==TRUE)
    {
    printf("[DEBUG]  Enable_Disk_Access() function\n");
    }

  /* Get the device parameters for the logical drive */

  regs.h.ah=0x44;                     /* IOCTL Block Device Request      */
  regs.h.al=0x0d;
  regs.h.bl=param.drive_number + 1;
  regs.h.ch=category_code;            /* 0x08 if !FAT32, 0x48 if FAT32   */
  regs.h.cl=0x67;                     /* Get Access Flags                */
  regs.x.dx=FP_OFF(&access_flags);
  sregs.ds =FP_SEG(&access_flags);

  intdosx(&regs, &regs, &sregs);

  error_code = regs.h.al;

  if (regs.x.cflag)
    {
    /* BO: if invalid function: try to format anyway maybe access
	   flags do not work this way in this DOS (e.g. DRDOS 7.03) */
    if (error_code == 0x1 || error_code == 0x16)
	return;

    /* Add error trapping here */
    printf("\nFatal error obtaining disk access flags...format terminated.\n", error_code);
    printf("Error Code:  %02x\n",error_code);
    exit(1);
    }

  if(access_flags.disk_access==0)
    {
    access_flags.disk_access++;

    regs.h.ah = 0x44;                     /* IOCTL Block Device Request          */
    regs.h.al = 0x0d;
    regs.h.bl = param.drive_number + 1;
    regs.h.ch = category_code;            /* 0x08 if !FAT32, 0x48 if FAT32       */
    regs.h.cl = 0x47;                     /* Set device parameters               */
    regs.x.dx = FP_OFF(&access_flags);
    sregs.ds  = FP_SEG(&access_flags);
    intdosx( &regs, &regs, &sregs);

    error_code = regs.h.al;

    if (regs.x.cflag)
	{
      /* Add error trapping here */
	printf("\nFatal error writing setting disk access flags...format terminated.\n", error_code);
	printf("Error Code:  %02x\n",error_code);
	exit(1);
	}
    }

  if(debug_prog==TRUE)
    {
    printf("[DEBUG]  Exit Exit_Enable_Disk_Access() function\n");
    }
}

/* FAT32_AbsReadWrite() is modified from TE_AbsReadWrite(). */
unsigned int FAT32_AbsReadWrite(char DosDrive, int count, ULONG sector, void *buffer, unsigned ReadOrWrite)
{
    unsigned diskReadPacket_seg;
    unsigned diskReadPacket_off;

    unsigned char return_code;

    void far * diskReadPacket_p;

    struct {
	unsigned long  sectorNumber;
	unsigned short count;
	void far *address;
	} diskReadPacket;
    union REGS regs;

    struct {
	unsigned direction  : 1 ;
	unsigned reserved_1 : 12;
	unsigned write_type : 2 ;
	unsigned reserved_2 : 1 ;
	} mode_flags;

    diskReadPacket.sectorNumber = sector;
    diskReadPacket.count        = count;
    diskReadPacket.address      = buffer;

    diskReadPacket_p =& diskReadPacket;

    diskReadPacket_seg = FP_SEG(diskReadPacket_p);
    diskReadPacket_off = FP_OFF(diskReadPacket_p);

    mode_flags.reserved_1 = 0;
    mode_flags.write_type = 0;
    mode_flags.direction  = ReadOrWrite == READ ?0 : 1;
    mode_flags.reserved_2 = 0;

    DosDrive++;

    asm{
      mov ax,0x7305
      mov bx,WORD PTR diskReadPacket_off
      mov cx,0xffff
      mov dl,BYTE PTR DosDrive
      mov ds,WORD PTR diskReadPacket_seg
      mov si,WORD PTR mode_flags
      int 0x21

      mov BYTE PTR return_code,ah
      jc carry_set
      }

//    return regs.x.cflag ? regs.x.ax : 0;
    return 0;

carry_set:
    return return_code;
}

/* TE_AbsReadWrite() is written by Tom Ehlert. */
unsigned int TE_AbsReadWrite(char DosDrive, int count, ULONG sector, void *buffer, unsigned ReadOrWrite)
{
    struct {
	unsigned long  sectorNumber;
	unsigned short count;
	void far *address;
	} diskReadPacket;
    union REGS regs;


    diskReadPacket.sectorNumber = sector;
    diskReadPacket.count        = count;
    diskReadPacket.address      = buffer;

    regs.h.al = DosDrive;
    regs.x.bx = (short)&diskReadPacket;
    regs.x.cx = 0xffff;

    switch(ReadOrWrite)
	{
	    case READ:  int86(0x25,&regs,&regs); break;
	    case WRITE: int86(0x26,&regs,&regs); break;
	    default:
		printf("TE_AbsReadWrite wrong called %02x\n", ReadOrWrite);
		exit(1);
	 }

    return regs.x.cflag ? regs.x.ax : 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -