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

📄 pdiskio.c

📁 Fdisk 1.2.1 Freedos下硬盘分区软件
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
// Module:  PDISKIO.C
// Module Description:  Disk Input/Output Code Module
//                      All functions that access the hard disk via
//                      interrupt 0x13 are here, including LBA support.
// Written By:  Brian E. Reifsnyder
// Module Version:  3.0
// Copyright:  2001 under the terms of the GNU GPL, Version 2
*/

/*
/////////////////////////////////////////////////////////////////////////////
//  SPECIAL
/////////////////////////////////////////////////////////////////////////////
*/

#define PDISKIO
#include "main.h"

/*
/////////////////////////////////////////////////////////////////////////////
//  INCLUDES
/////////////////////////////////////////////////////////////////////////////
*/

#include <conio.h>
#include <bios.h>
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "pdiskio.h"

extern void Pause(void);

/*
/////////////////////////////////////////////////////////////////////////////
//  PROTOTYPES
/////////////////////////////////////////////////////////////////////////////
*/

/* Module Prototype Declarations */
/* ***************************** */
int Get_Hard_Drive_Parameters(int physical_drive);
int Read_Physical_Sectors_CHS(int drive,long cylinder, long head, long sector, int number_of_sectors);
int Read_Physical_Sectors_LBA(int drive,long cylinder, long head, long sector, int number_of_sectors);
int Write_Physical_Sectors_CHS(int drive, long cylinder, long head, long sector, int number_of_sectors);
int Write_Physical_Sectors_LBA(int drive, long cylinder, long head, long sector, int number_of_sectors);

long Translate_CHS_To_LBA(unsigned long cylinder,unsigned long head
 ,unsigned long sector,unsigned long total_heads,unsigned long total_sectors);

void Clear_Partition_Table_Area_Of_Sector_Buffer(void);
void Check_For_INT13_Extensions();
void Convert_Logical_To_Physical(unsigned long sector
 ,unsigned long total_heads,unsigned long total_sectors);
void Get_Partition_Information(void);

int Determine_Drive_Letters();
int Read_Partition_Tables();
int Read_Physical_Sectors(int drive, long cylinder, long head, long sector, int number_of_sectors);
int Write_Logical_Sectors(unsigned char drive_letter[2]
 , unsigned long logical_sector_number, int number_of_sectors);
int Write_Partition_Tables();
int Write_Physical_Sectors(int drive, long cylinder, long head, long sector, int number_of_sectors);

unsigned long Decimal_Number(unsigned long hex1, unsigned long hex2, unsigned long hex3, unsigned long hex4);

void StorePartitionInSectorBuffer( char *sector_buffer,struct Partition *pPart);


void Check_For_INT13_Extensions();
void Clear_Sector_Buffer();
void Initialize_LBA_Structures();
void Load_Brief_Partition_Table();

  /* External Prototype Declarations */
  /* ******************************* */
  extern void Clear_Extended_Partition_Table(int drive);
  extern void Clear_Screen(int type);
/*  extern void Convert_Long_To_Integer(long number);*/
  extern void Pause();
  extern void Print_Centered(int y,char *text,int style);
  extern void Position_Cursor(int row,int column);

/*
/////////////////////////////////////////////////////////////////////////////
//  FUNCTIONS
/////////////////////////////////////////////////////////////////////////////
*/

/* Check for interrupt 0x13 extensions */
void Check_For_INT13_Extensions()
{
  int carry;
  int drive_number=0x80;

  unsigned int ah_register;
  unsigned int bx_register;
  unsigned int cx_register;

#ifdef DEBUG
  if(debug.lba==TRUE)
    {
    Clear_Screen(NULL);
    Print_Centered(0,"void Check_For_INT13_Extensions() debugging screen",BOLD);
    printf("\n\n    drive     int 0x13 ext?     access w/packet\n\n");
    }
#endif

  do
    {
    carry=99;

    asm{
      mov ah,0x41
      mov bx,0x55aa
      mov dl,BYTE PTR drive_number
      int 0x13

      mov BYTE PTR ah_register,ah
      mov WORD PTR bx_register,bx
      mov WORD PTR cx_register,cx

      jnc carry_flag_not_set    /* Jump if the carry flag is clear  */
      }                         /* If the carry flag is clear, then */
                                /* the extensions exist.            */
    carry=1;
    part_table[(drive_number-128)].ext_int_13=FALSE;

    carry_flag_not_set:
    if( (carry==99) && (bx_register==0xaa55) )
      {
      flags.use_extended_int_13=TRUE;
      part_table[(drive_number-128)].ext_int_13=TRUE;

      if((cx_register&0x0001)==1) part_table[(drive_number-128)].device_access_using_packet_structure=TRUE;
      else part_table[(drive_number-128)].device_access_using_packet_structure=FALSE;

      part_table[(drive_number-128)].ext_int_13_version=ah_register;

#ifdef DEBUG
      if(debug.lba==TRUE)
        {
        printf("     0x%2x          yes",drive_number);

        if((cx_register&0x0001)==1) printf("                 yes");
        else printf("                  no");

        printf("\n");
        }
#endif

      }
#ifdef DEBUG
    else if(debug.lba==TRUE) printf("     0x%2x           no\n",drive_number);
#endif

    drive_number++;
    }while(drive_number<0x88);

#ifdef DEBUG
  if(debug.lba==TRUE)
    {
    printf("\n\n\n");
    Pause();
    }
#endif

}

/* Clear the Boot Sector of a partition */
void Clear_Boot_Sector(int drive,long cylinder,long head,long sector)
{
  unsigned char stored_sector_buffer[512];
  long index;

  /* Save sector_buffer[512] into stored_sector_buffer[512] */
  memcpy(stored_sector_buffer,sector_buffer,512);

  /* Write all 0xf6 values to sector_buffer[index] */
  memset(sector_buffer,0xf6,512);

  for (index=0; index < 16; index++)
    {
    Write_Physical_Sectors(drive,cylinder,head,(sector+index),1);
    }

  /* Restore sector_buffer[512] to its original contents */
  memcpy(sector_buffer,stored_sector_buffer,512);
}

/* Clear The Partition Table Area Of sector_buffer only. */
void Clear_Partition_Table_Area_Of_Sector_Buffer()
{
    memset(sector_buffer+0x1be,0,4*16);
}

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

/* Combine Cylinder and Sector Values */
unsigned long Combine_Cylinder_and_Sector(unsigned long cylinder, unsigned long sector)
{
  long value = 0;

  asm{
    mov ax,WORD PTR cylinder
    mov bx,WORD PTR sector

    mov dl,ah
    shl dl,1
    shl dl,1
    shl dl,1
    shl dl,1
    shl dl,1
    shl dl,1

    mov dh,al

    add dx,bx

    mov WORD PTR value,dx
    }

  return(value);
}

/* Determine drive letters */
int Determine_Drive_Letters()
/* Returns last used drive letter as ASCII number. */
{
//  int active_found=FALSE;
  int current_letter='C';
//  int drive_found=FALSE;
  int index=0;
  int non_dos_partition;
  int non_dos_partition_counter;
  int sub_index=0;

  int active_part_found[8];

  Load_Brief_Partition_Table();

  /* Clear drive_lettering_buffer[8] [27] */
  index=0;
  do
    {
    sub_index=0;
    do
      {
      drive_lettering_buffer[index] [sub_index]=0;

      sub_index++;
      }while(sub_index<27);

    index++;
    }while(index<8);

  /* Set all active_part_found[] values to 0. */
  index=0;
  do
    {
    active_part_found[index]=0;
    index++;
    }while(index<8);

  /* Begin placement of drive letters */

  /* First, look for and assign drive letters to all active */
  /* primary partitions. */

  index=0;
  do
    {
    Partition_Table *pDrive = &part_table[index];

    sub_index=0;
    do
      {
      if( (IsRecognizedFatPartition(brief_partition_table[index] [sub_index]))
       && (pDrive->pri_part[sub_index].active_status==0x80) )
	{
	drive_lettering_buffer[index] [sub_index]=current_letter;
	active_part_found[index]=1;
	sub_index=5;                   /* get out of loop */
	current_letter++;
	}

      sub_index++;
      }while(sub_index<4);


    index++;
    }while(index<8);


  /* Next, assign one drive letter for one existing primary partition   */
  /* if an active partition does not exist on that hard disk.           */

  index=0;
  do
    {
    if(active_part_found[index]==0)
      {
      sub_index=0;
      do
	{
	if(IsRecognizedFatPartition(brief_partition_table[index] [sub_index]))
	  {
	  drive_lettering_buffer[index] [sub_index]=current_letter;
	  current_letter++;
	  sub_index=5;  /* Set sub_index = 5 to break out of loop early. */
	  }

	sub_index++;
	}while(sub_index<4);
      }

    index++;
    }while(index<8);

  /* Next assign drive letters to applicable extended partitions... */
  index=0;
  do
    {
    sub_index=4;
    do
      {
      if(IsRecognizedFatPartition (brief_partition_table[index] [sub_index]))
	{
	drive_lettering_buffer[index] [sub_index]=current_letter;
	current_letter++;
	}

      sub_index++;
      }while(sub_index<27);

    index++;
    }while(index<8);

  /* Return to the primary partitions... */
  index=0;
  do
    {
    sub_index=0;

    do
      {
      if( drive_lettering_buffer[index] [sub_index]==0)
	{
	if (IsRecognizedFatPartition(brief_partition_table[index] [sub_index]))
	  {
	  drive_lettering_buffer[index] [sub_index]=current_letter;
	  current_letter++;
	  }
	}
      sub_index++;
      }while(sub_index<4);

    index++;
    }while(index<8);

  /* Find the Non-DOS Logical Drives in the Extended Partition Table */
  non_dos_partition_counter='1';
  index=0;
  do
    {
    Partition_Table *pDrive = &part_table[index];

    pDrive->num_of_non_dos_log_drives=0;
    sub_index=4;

    do
      {
      if(brief_partition_table[index] [sub_index]>0)
	{
	non_dos_partition=TRUE;

	if( IsRecognizedFatPartition(brief_partition_table[index] [sub_index]))
	  {
	  non_dos_partition=FALSE;
	  }

	if( (non_dos_partition==TRUE) && (non_dos_partition_counter<='9') )
	  {
	  drive_lettering_buffer[index] [sub_index]=non_dos_partition_counter;
	  pDrive->num_of_non_dos_log_drives++;
	  non_dos_partition_counter++;
	  }
	}
      sub_index++;
      }while(sub_index<27);

    non_dos_partition_counter='1';
    index++;
    }while(index<8);

  return(current_letter-1);
}


/* Extract Cylinder */
unsigned long Extract_Cylinder(unsigned long hex1, unsigned long hex2)
{
  unsigned long cylinder_and_sector = ( (256*hex2) + hex1 );
  unsigned long extracted_cylinder = ( ( (cylinder_and_sector*4) & 768) + (cylinder_and_sector /256) );

  return(extracted_cylinder);
}

/* Extract the Cylinder from an LBA Value */
unsigned long Extract_Cylinder_From_LBA_Value(long lba_value
 ,long head,long sector,long total_heads
 ,long total_sectors)
{
  return( ( ( ( (lba_value-(sector-1))/total_sectors)-head)/(total_heads+1) ) );
}

/* Extract Sector */
unsigned long Extract_Sector(unsigned long hex1, unsigned long hex2)
{
  unsigned long cylinder_and_sector = ( (256*hex2) + hex1 );
  unsigned long extracted_sector = cylinder_and_sector % 64;

  return(extracted_sector);
}

/* Get the parameters of the hard disk */
int Get_Hard_Drive_Parameters(int physical_drive)
{
  int error_code=0;

  unsigned int total_number_hard_disks=0;

  unsigned long total_cylinders=0;
  unsigned long total_heads=0;
  unsigned long total_sectors=0;
  Partition_Table *pDrive = &part_table[physical_drive-0x80];


  if( (physical_drive-0x80)>=flags.total_number_hard_disks) return(255);

  if(user_defined_chs_settings[(physical_drive-128)].defined==TRUE)
    {
    pDrive->total_cyl
     =user_defined_chs_settings[(physical_drive-0x80)].total_cylinders;
    pDrive->total_head
     =user_defined_chs_settings[(physical_drive-0x80)].total_heads;
    pDrive->total_sect
     =user_defined_chs_settings[(physical_drive-0x80)].total_sectors;
    pDrive->num_of_log_drives=0;

    return(0);
    }

  /* Get the hard drive parameters with normal int 0x13 calls. */
  asm{
    mov ah, 0x08
    mov dl, BYTE PTR physical_drive
    int 0x13

    mov bl,cl
    and bl,00111111B

    mov BYTE PTR error_code, ah
    mov BYTE PTR total_sectors, bl
    mov BYTE PTR total_number_hard_disks,dl

    mov bl,cl
    mov cl,ch
    shr bl,1
    shr bl,1
    shr bl,1
    shr bl,1
    shr bl,1
    shr bl,1

    mov ch,bl

    mov WORD PTR total_cylinders, cx
    mov BYTE PTR total_heads, dh
    }

  if(flags.total_number_hard_disks==255)
   flags.total_number_hard_disks = total_number_hard_disks;
  if(total_number_hard_disks==0) return(255);


  if(error_code>0) return(error_code);

  pDrive->total_head=total_heads;
  pDrive->total_sect=total_sectors;
  pDrive->num_of_log_drives=0;

  if(pDrive->ext_int_13==TRUE)
    {
    /* Get the hard drive parameters with extended int 0x13 calls. */

    /* Note:  Supported interrupt 0x13 extensions have already been        */
    /* checked for in the function Check_For_INT13_Extensions().           */

    unsigned int result_buffer_segment=FP_SEG(result_buffer);
    unsigned int result_buffer_offset=FP_OFF(result_buffer);

    unsigned long legacy_total_cylinders=total_cylinders;
    unsigned long number_of_physical_sectors;

    asm {
      mov ah,0x48
      mov dl,BYTE PTR physical_drive
      mov ds,result_buffer_segment
      mov si,result_buffer_offset
      int 0x13

      mov BYTE PTR error_code,ah
      }

    if(error_code>0) return(error_code);

    /* Compute the total number of logical cylinders based upon the number */

⌨️ 快捷键说明

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