📄 format.c
字号:
/* Load the starting LBA */
fr_DWORD((byte *)&(part.ents[partition_number].r_sec), starting_lba);
}
else
{
/* 10-24-2000 - This was the original code */
part.ents[partition_number].s_head = 1; /* Start at head 1 */
fr_WORD((byte *) &(part.ents[partition_number].s_cyl), (word)starting_cylinder);
}
if (partition_size > (dword) 0xffff)
{
if (nibs_per_entry == 8)
{
/* 10-24-2000 - New code to support lba formatting */
if (pgeometry->dev_geometry_lbas)
part.ents[partition_number].p_typ = 0x0c; /* DOS 32 bit LBA mode (was: 0x0b) */
else
/* 10-24-2000 - This was the original code */
part.ents[partition_number].p_typ = 0x0b; /* DOS 32 bit */
}
else
part.ents[partition_number].p_typ = 6; /* Huge */
}
else
{
if (nibs_per_entry == 4)
part.ents[partition_number].p_typ = 4; /* DOS 16 bit */
else
part.ents[partition_number].p_typ = 1; /* DOS 12 bit */
}
if (pgeometry->dev_geometry_lbas)
{
/* 10-24-2000 - New code to support lba formatting */
/* Load the LBA size of the partition */
fr_DWORD((byte *)&(part.ents[partition_number].p_size), partition_size);
/* Advance the starting_lba */
starting_lba += partition_size;
/* Do CHS */
/* SECTOR */
dwTemp = ((starting_lba-1) % pgeometry->dev_geometry_secptrack) + 1;
sec = (byte) dwTemp;
/* HEAD */
dwTemp = (starting_lba-1) / pgeometry->dev_geometry_secptrack;
dwTemp = dwTemp % pgeometry->dev_geometry_heads;
head = (byte) dwTemp;
/* CYLINDER */
dwTemp = (starting_lba-1) / pgeometry->dev_geometry_secptrack;
dwTemp = dwTemp / pgeometry->dev_geometry_heads;
if (dwTemp > 1023)
dwTemp = 1023;
cyl = (word) dwTemp;
/* Load the ending CHS */
part.ents[partition_number].e_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].e_cyl), utemp);
}
else
{
/* 10-24-2000 - This was the original code */
/* Ending head is NHEADS-1 since heads go from 0 to n */
part.ents[partition_number].e_head = (byte) (pgeometry->dev_geometry_heads-1);
/* Ending cylinder is in the top ten bits, secptrack in lower 6 ?? */
/* Relative sector starting */
fr_DWORD((byte *)&(part.ents[partition_number].r_sec), (dword) pgeometry->dev_geometry_secptrack*starting_cylinder);
/* Set up for the next partition and use new value to calculate ending cyl */
starting_cylinder += (word) *(partition_list+partition_number);
utemp = (word)(((starting_cylinder-1) & 0xff) << 8); /* Low 8 bit to hi bite */
utemp2 = (word)(((starting_cylinder-1) >> 2) & 0xc0); /* Hi 2 bits to bits 6 + 7 */
utemp |= utemp2;
utemp |= (word) pgeometry->dev_geometry_secptrack;
fr_WORD((byte *)&(part.ents[partition_number].e_cyl), utemp);
/* And partition size */
fr_DWORD((byte *)&(part.ents[partition_number].p_size), partition_size);
}
} /* for (partition_number = 0; partition_number < 4;.. */
/* Now for the signature */
fr_WORD((byte *)&(part.signature), 0xAA55);
/* Grab some working space */
buf = pc_scratch_blk();
if (!buf)
{
set_errno(PENOSPC);
return(ret_val);
}
pbuf = buf->data;
pc_memfill(pbuf, 512, (byte) 0);
/* Copy in the boot code */
copybuff((PFVOID)pbuf, (PFVOID)&part_boot[0], sizeof(part_boot));
/* Now copy the partition into a block */
/* The info starts at buf[1be] */
copybuff((pbuf + 0x1be), &part, sizeof(PTABLE));
/* try the write */
if (!devio_write(driveno, 0, pbuf, 1, TRUE))
{
set_errno(PENOSPC);
}
else
ret_val = TRUE;
pc_free_buf(buf, TRUE);
return(ret_val);
}
/***************************************************************************
PC_FORMAT_VOLUME - Format a volume
Description
This routine formats the volume referred to by drive letter.
drive structure is queried to determine if the device is parttioned
or not. If the device is partitioned then the partition table is read
and the volume within the partition is formatted. If it is a non
partitioned device the device is formatted according to the supplied
pgeometry parameters. The pgeometry parameter contains the the media
size in HCN format. It also contains a
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 failed or memory alloc fail
PEINVAL - One ore more arguments were invalid
****************************************************************************/
BOOLEAN pc_format_volume(char *path, PDEV_GEOMETRY pgeometry)
{
DDRIVE *pdr;
BOOLEAN raw_mode_io;
FMTPARMS fmt;
int driveno;
dword partition_size;
dword ltemp;
word n_cyls;
int i;
int root_entries;
byte secpalloc;
word secpfat;
int root_sectors;
int nibs_per_entry;
CHECK_MEM(BOOLEAN, 0)
set_errno(PEINVAL);
/* Make sure it's a valid drive number */
driveno = pc_parse_raw_drive(path);
if (driveno == -1 || !pgeometry)
{
return(FALSE);
}
/* Make sure all is flushed */
pc_dskfree(driveno);
pdr = pc_drno_to_drive_struct(driveno);
/* Check the drive structure for format strategy */
if (!pdr || !(pdr->drive_flags&DRIVE_FLAGS_VALID))
{
return(FALSE);
}
/* If the format parms were provided by the driver format now */
if (pgeometry->fmt_parms_valid)
{
return(pc_mkfs(driveno, &pgeometry->fmt, TRUE)); // TRUE == RAW IO
}
/* If the device is partitioned read the partition table into the
drive structure.
*/
if (pdr->drive_flags & DRIVE_FLAGS_PARTITIONED)
{
if (pc_read_partition_table(driveno, pdr) != READ_PARTION_OK)
{
set_errno(PENOSPC);
return(FALSE);
}
partition_size = pdr->partition_size;
ltemp = partition_size /
(dword)(pgeometry->dev_geometry_heads * pgeometry->dev_geometry_secptrack);
n_cyls = (word) ltemp;
raw_mode_io = FALSE;
}
else
{
partition_size = (dword) pgeometry->dev_geometry_cylinders;
partition_size = partition_size * (dword) pgeometry->dev_geometry_heads;
partition_size = partition_size * (dword) pgeometry->dev_geometry_secptrack;
n_cyls = (word) pgeometry->dev_geometry_cylinders;
raw_mode_io = TRUE;
}
/* 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);
tc_strcpy(&fmt.oemname[0], "EBSNET");
fmt.physical_drive_no = (unsigned char) driveno;
fmt.binary_volume_label = BIN_VOL_LABEL;
tc_strcpy(fmt.text_volume_label, STR_VOL_LABEL);
fmt.secpalloc = (unsigned char) secpalloc;
fmt.numfats = (unsigned char) 2;
fmt.secptrk = (unsigned short) pgeometry->dev_geometry_secptrack;
fmt.numhead = (unsigned short) pgeometry->dev_geometry_heads;
fmt.numcyl = (unsigned short) n_cyls;
fmt.mediadesc = (unsigned char) 0xF8;
if (nibs_per_entry == 8) /* FAT32 Format */
{
fmt.secreserved = (unsigned short) 32;
fmt.fmttype = FMT_FAT32;
if (pgeometry->dev_geometry_lbas)
/* 10-24-2000 - New code to support lba formatting */
fmt.numhide = (unsigned long) 0; /*PS Doesn't work as "fmt.secptrk" here */
else
/* 10-24-2000 - This was the original code */
fmt.numhide = (unsigned long) fmt.secptrk;
fmt.secpfat = (unsigned short) 0;
fmt.numroot = (unsigned short) 0;
fmt.mediadesc = (unsigned char) 0xF8;
}
else
{
fmt.secreserved = (unsigned short) 1;
fmt.fmttype = FMT_DOS;
fmt.numhide = 0;
fmt.secpfat = (unsigned short) secpfat;
fmt.numroot = (unsigned short) root_entries;
fmt.mediadesc = (unsigned char) 0xF8;
}
return(pc_mkfs(driveno, &fmt, raw_mode_io));
}
/*****************************************************************************
PC_MKFS - Make a file system on a disk MS-DOS 4.0 version
Description
Given a drive number and a format parameter block. Put an MS-DOS
file system on the drive:
The disk MUST already have a low level format. All blocks on the drive
should be intitialize with E5's or zeros.
see pcmkfs in the samples directory.
Some common parameters. Note: For other drive types use debug to get the
parameters from block zero after FORMAT has been run.
360 720 20M 80M (DRIVE SIZE)
oemname ===== UP TO YOU. ONLY 8 Chars matter. Right filled with ' '
secpalloc 2 2 4 8
secreserved 1 1 1 1
numfats 2 2 2 2
numroot 0x70 0x70 0x200 0x200
mediadesc 0xFD 0xF9 0xF8 0xF8
secpfat 2 3 44 88
secptrk 9 9 0x11 0x11
numhead 2 2 4 8
numcyl 40 80 612 1224
Note: If pc_mkfs is called secpfat equal zero, secpfat will be calculated
internally.
Returns
Returns TRUE if the filesystem disk was successfully initialized.
See Also:
pcmkfs.c format utility program
****************************************************************************/
BOOLEAN pc_mkfs(int driveno, FMTPARMS *pfmt, BOOLEAN use_raw) /*__fn__*/
{
byte *b;
BLKBUFF *buf;
dword ltotsecs;
word totsecs;
word nclusters;
dword lnclusters;
dword ldata_area;
int fausize;
word i,j;
#if (FAT32)
word k;
#endif
BLOCKT blockno;
BOOLEAN ret_val;
/* If raw IO we call check media. This will clear a change condition
so it doesn't cause MKFS to fail. */
/* Don't automount, don't use partition table, don't print errors */
if (use_raw)
check_media(driveno, FALSE, TRUE, FALSE);
ret_val = FALSE;
buf = pc_scratch_blk();
if (!buf)
{
set_errno(PENOSPC);
return(FALSE);
}
b = buf->data;
set_errno(PENOSPC);
/* Build up a block 0 */
pc_memfill(&b[0], 512, '\0');
#if (FAT32)
if (pfmt->fmttype == FMT_FAT32)
{
for (i=0;i<pfmt->secreserved;i++)
{
/* WRITE */
if (!devio_write_format(driveno, (dword) i, &(b[0]), 1, use_raw) )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -