📄 format.c
字号:
/*
* EBS - RTFS (Real Time File Manager)
*
* Copyright EBS Inc. 2000
* All rights reserved.
* This code may not be redistributed in source or linkable object form
* without the consent of its author.
*/
#include <pcdisk.h>
//
// New format logic
//
//
//
extern KS_CONSTANT FORMAT_DEC_TREE f_d_c[7];
extern KS_CONSTANT byte bootcode[0x1E5];
extern KS_CONSTANT byte part_boot[218];
word pc_fat_size(word nreserved, word cluster_size, word n_fat_copies,
word root_sectors, dword volume_size,
int *nibs_per_entry);
//
//1. Floppy driver must return partition info. Must format
//2. other drivers must return info. must format. See ATAPI
BOOLEAN pc_mkfs(int driveno, FMTPARMS *pfmt, BOOLEAN use_raw);
BOOLEAN devio_write_format(int driveno, dword blockno, byte * buf, word n_to_write, BOOLEAN raw);
// 10-24-2000 added LBA formatting. Submit to main tree
/***************************************************************************
PC_GET_MEDIA_PARMS - Get media parameters.
Description
Queries the drive's associated device driver for a description of the
installed media. This information is used by the pc_format_media,
pc_partition_media and pc_format_volume routines. The application may
use the results of this call to calculate how it wishes the media to
be partitioned.
Note that the floppy device driver uses a "back door" to communicate
with the format routine through the geometry structure. This allows us
to not have floppy specific code in the format routine but still use the
exact format parameters that DOS uses when it formats a floppy.
See the following definition of the pgeometry structure:
typedef struct dev_geometry {
int dev_geometry_heads; -- - Must be < 256
int dev_geometry_cylinders; -- - Must be < 1024
int dev_geometry_secptrack; -- - Must be < 64
BOOLEAN fmt_parms_valid; -- If the device io control call sets this
-- TRUE then it it telling the applications
-- layer that these format parameters should
-- be used. This is a way to format floppy
-- disks exactly as they are fromatted by dos.
FMTPARMS fmt;
} DEV_GEOMETRY;
typedef struct dev_geometry KS_FAR *PDEV_GEOMETRY;
Returns
Returns TRUE if it was able to get the parameters otherwise
it returns FALSE.
If the return value is FALSE xn_getlasterror() will be set with one of the following:
PENOSPC - Device driver query failed
PEINVAL - Invalid Drive Argument
****************************************************************************/
BOOLEAN pc_get_media_parms(char *path, PDEV_GEOMETRY pgeometry)
{
int driveno;
DDRIVE *pdr;
BOOLEAN ret_val;
CHECK_MEM(BOOLEAN, 0)
/* Make sure it's a valid drive number */
driveno = pc_parse_raw_drive(path);
if (driveno == -1)
{
inval:
set_errno(PEINVAL);
return(FALSE);
}
pdr = pc_drno_to_drive_struct(driveno);
if (!pdr || !(pdr->drive_flags&DRIVE_FLAGS_VALID) )
goto inval;
/* Ask - for device geometry */
OS_CLAIM_DRIVE_IO(pdr->lock_unit)
if (pdr->dev_table_perform_device_ioctl(driveno, DEVCTL_GET_GEOMETRY, (PFVOID) pgeometry))
{
set_errno(PENOSPC);
ret_val = FALSE;
}
else
ret_val = TRUE;
OS_RELEASE_DRIVE_IO(pdr->lock_unit)
/* Now fix up geometry structure such that
int dev_geometry_heads; -- - Must be < ??? 128
int dev_geometry_cylinders; -- - Must be < 1024
int dev_geometry_secptrack; -- - Must be < 64
*/
while (pgeometry->dev_geometry_cylinders > 1023)
{
pgeometry->dev_geometry_cylinders /= 2;
if (pgeometry->dev_geometry_heads < 128)
pgeometry->dev_geometry_heads *= 2;
else if (pgeometry->dev_geometry_secptrack < 32)
pgeometry->dev_geometry_secptrack *= 2;
else
{
break; /* nothing more we can do. */
}
}
return(ret_val);
}
/***************************************************************************
PC_FORMAT_MEDIA - Device level format
Description
This routine performs a device level format on the specified
drive.
Returns
Returns TRUE if it was able to perform the operation otherwise
it returns FALSE.
If the return value is FALSE xn_getlasterror() will be set with one of the following:
PENOSPC - Device driver format failed
PEINVAL - One or more arguments were invalid
****************************************************************************/
BOOLEAN pc_format_media(char *path, PDEV_GEOMETRY pgeometry)
{
int driveno;
DDRIVE *pdr;
BOOLEAN ret_val;
CHECK_MEM(BOOLEAN, 0)
/* Make sure it's a valid drive number */
driveno = pc_parse_raw_drive(path);
if (driveno == -1)
{
inval:
set_errno(PEINVAL);
return(FALSE);
}
pdr = pc_drno_to_drive_struct(driveno);
if (!pdr || !(pdr->drive_flags&DRIVE_FLAGS_VALID) )
goto inval;
/* Make sure that is it closed up */
pc_dskfree(driveno);
/* Format the device geometry */
OS_CLAIM_DRIVE_IO(pdr->lock_unit)
if (pdr->dev_table_perform_device_ioctl(driveno, DEVCTL_FORMAT, (PFVOID) pgeometry))
{
set_errno(PENOSPC);
ret_val = FALSE;
}
else
{
ret_val = TRUE;
}
OS_RELEASE_DRIVE_IO(pdr->lock_unit)
return(ret_val);
}
/***************************************************************************
PC_PARTITION_MEDIA - Write partition table
Description
A partition list is provided (a list of partition sizes
in units of LBA's) by the user.
Returns
Returns TRUE if it was able to perform the operation otherwise
it returns FALSE.
If the return value is FALSE xn_getlasterror() will be set with one of the following:
PENOSPC - Device driver write failed or memory alloc fail
PEINVAL - One ore more arguments were invalid
****************************************************************************/
BOOLEAN pc_partition_media(char *path, PDEV_GEOMETRY pgeometry, PFDWORD partition_list)
{
int driveno;
BOOLEAN ret_val;
BLKBUFF *buf;
PFBYTE pbuf;
dword partition_size;
int partition_number;
int i;
int nibs_per_entry;
PTABLE part;
DDRIVE *pdr;
int root_entries;
byte secpalloc;
word secpfat;
int root_sectors;
word utemp;
word utemp2;
dword dwTemp;
dword starting_lba;
word cyl;
byte head,sec;
dword disk_size;
word starting_cylinder;
CHECK_MEM(BOOLEAN, 0)
ret_val = FALSE;
set_errno(PEINVAL);
/* Make sure it's a valid drive number */
driveno = pc_parse_raw_drive(path);
if (driveno == -1 || !pgeometry || !partition_list || !*partition_list)
{
inval:
return(ret_val);
}
pdr = pc_drno_to_drive_struct(driveno);
if (!pdr)
goto inval;
/* Zero the partition table to start */
pc_memfill(&part, sizeof(part), (byte) 0);
/* 10-24-2000 - New code to support lba formatting */
/* The first partition starts at cylinder=0, head=1, sector=1 */
if (pgeometry->dev_geometry_lbas)
starting_lba = (dword) pgeometry->dev_geometry_secptrack;
else
{
/* 10-24-2000 - This was the original code */
disk_size = (dword) pgeometry->dev_geometry_cylinders;
disk_size = disk_size * (dword) pgeometry->dev_geometry_heads;
disk_size = disk_size * (dword) pgeometry->dev_geometry_secptrack;
/* The first partition starts at 1 */
starting_cylinder = 1;
}
for (partition_number = 0; partition_number < 4; partition_number++)
{
partition_size = (dword) *(partition_list+partition_number);
if (!partition_size)
break; /* End of list */
if (pgeometry->dev_geometry_lbas)
{
/* 10-24-2000 - New code to support lba formatting */
/* Apparently, we must still align to cylinders even in LBA mode */
dwTemp = (dword) pgeometry->dev_geometry_heads;
dwTemp *= (dword) pgeometry->dev_geometry_secptrack;
partition_size = ((partition_size / dwTemp) * dwTemp) - (starting_lba % dwTemp);
}
else
{
/* 10-24-2000 - This was the original code */
/* Multiply time # heads and secptrack */
partition_size = partition_size * (dword) pgeometry->dev_geometry_heads;
partition_size = partition_size * (dword) pgeometry->dev_geometry_secptrack;
}
/* Look up root_entries and cluster size */
for(i = 0;;i++)
{
if (!f_d_c[i].n_blocks || partition_size <= f_d_c[i].n_blocks)
{
root_entries = f_d_c[i].ents_p_root;
secpalloc = (byte) f_d_c[i].sec_p_alloc;
break;
}
}
root_sectors = (int) (root_entries/16);
/* Calculate sectors per fat */
secpfat = pc_fat_size( (word)1 /* reserved */, (word)secpalloc,
(word)2 /*numfats*/, (word)root_sectors /* root sectors */,
partition_size, &nibs_per_entry);
/* Now fill in the partition entry 0 */
part.ents[partition_number].boot = 0x80; /* Set this to 0x80 for bootable */
if (pgeometry->dev_geometry_lbas)
{
/* 10-24-2000 - New code to support lba formatting */
/* Do CHS */
/* SECTOR */
dwTemp = (starting_lba % pgeometry->dev_geometry_secptrack) + 1;
sec = (byte) dwTemp;
/* HEAD */
dwTemp = starting_lba / pgeometry->dev_geometry_secptrack;
dwTemp = dwTemp % pgeometry->dev_geometry_heads;
head = (byte) dwTemp;
/* CYLINDER */
dwTemp = starting_lba / pgeometry->dev_geometry_secptrack;
dwTemp = dwTemp / pgeometry->dev_geometry_heads;
if (dwTemp > 1023)
dwTemp = 1023;
cyl = (word) dwTemp;
/* Load the starting CHS */
part.ents[partition_number].s_head = head;
utemp = (word)((cyl & 0xff) << 8); /* Low 8 bit to hi bite */
utemp2 = (word)((cyl >> 2) & 0xc0); /* Hi 2 bits to bits 6 + 7 */
utemp |= utemp2;
utemp |= sec;
fr_WORD((byte *)&(part.ents[partition_number].s_cyl), utemp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -