avoid linking against libbe.so
style cleanup allows to use a disk image in case ioctl calls fail git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18586 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
SubDir HAIKU_TOP src bin mkdos ;
|
SubDir HAIKU_TOP src bin mkdos ;
|
||||||
|
|
||||||
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
|
||||||
BinCommand mkdos :
|
BinCommand mkdos :
|
||||||
mkdos.cpp
|
mkdos.cpp
|
||||||
: be
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
+159
-159
@@ -25,15 +25,14 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
#include <OS.h>
|
#include <ByteOrder.h>
|
||||||
#include <Drivers.h>
|
#include <Drivers.h>
|
||||||
|
#include <OS.h>
|
||||||
|
#include <getopt.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <File.h>
|
#include <unistd.h>
|
||||||
#include <ByteOrder.h>
|
|
||||||
#include <getopt.h>
|
|
||||||
#include "fat.h"
|
#include "fat.h"
|
||||||
|
|
||||||
#define WITH_FLOPPY_SUPPORT
|
#define WITH_FLOPPY_SUPPORT
|
||||||
@@ -42,7 +41,8 @@ void PrintUsage();
|
|||||||
void CreateVolumeLabel(void *sector, const char *label);
|
void CreateVolumeLabel(void *sector, const char *label);
|
||||||
status_t Initialize(int fatbits, const char *device, const char *label, bool noprompt, bool testmode);
|
status_t Initialize(int fatbits, const char *device, const char *label, bool noprompt, bool testmode);
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
if (sizeof(bootsector1216) != 512 || sizeof(bootsector32) != 512 || sizeof(fsinfosector32) != 512) {
|
if (sizeof(bootsector1216) != 512 || sizeof(bootsector32) != 512 || sizeof(fsinfosector32) != 512) {
|
||||||
printf("compilation error: struct alignment wrong\n");
|
printf("compilation error: struct alignment wrong\n");
|
||||||
@@ -66,7 +66,7 @@ int main(int argc, char *argv[])
|
|||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
c = getopt_long (argc, argv, "ntf:",long_options, &option_index);
|
c = getopt_long (argc, argv, "ntf:", long_options, &option_index);
|
||||||
if (c == -1)
|
if (c == -1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (device == NULL) {
|
if (device == NULL) {
|
||||||
printf("mkdos error: you must specify a device or partition\n");
|
printf("mkdos error: you must specify a device or partition or image\n");
|
||||||
printf(" such as /dev/disk/ide/ata/1/master/0/0_0\n");
|
printf(" such as /dev/disk/ide/ata/1/master/0/0_0\n");
|
||||||
PrintUsage();
|
PrintUsage();
|
||||||
return 1;
|
return 1;
|
||||||
@@ -150,95 +150,95 @@ status_t Initialize(int fatbits, const char *device, const char *label, bool nop
|
|||||||
|
|
||||||
printf("device = %s\n",device);
|
printf("device = %s\n",device);
|
||||||
|
|
||||||
BFile file(device,B_READ_WRITE);
|
int fd = open(device, O_RDWR);
|
||||||
status_t result = file.InitCheck();
|
|
||||||
if (result != B_OK) {
|
|
||||||
fprintf(stderr,"Error: couldn't open device %s\n",device);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fd = file.Dup();
|
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
fprintf(stderr,"Error: couldn't open file descriptor for device %s\n",device);
|
fprintf(stderr,"Error: couldn't open file for device %s %s\n",device, strerror(fd));
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsRawDevice;
|
bool isRawDevice;
|
||||||
bool HasBiosGeometry;
|
bool hasBiosGeometry;
|
||||||
bool HasDeviceGeometry;
|
bool hasDeviceGeometry;
|
||||||
bool HasPartitionInfo;
|
bool hasPartitionInfo;
|
||||||
device_geometry BiosGeometry;
|
device_geometry biosGeometry;
|
||||||
device_geometry DeviceGeometry;
|
device_geometry deviceGeometry;
|
||||||
partition_info PartitionInfo;
|
partition_info partitionInfo;
|
||||||
|
|
||||||
IsRawDevice = 0 != strstr(device,"/raw");
|
isRawDevice = 0 != strstr(device, "/raw");
|
||||||
HasBiosGeometry = B_OK == ioctl(fd,B_GET_BIOS_GEOMETRY,&BiosGeometry);
|
hasBiosGeometry = B_OK == ioctl(fd, B_GET_BIOS_GEOMETRY, &biosGeometry);
|
||||||
HasDeviceGeometry = B_OK == ioctl(fd,B_GET_GEOMETRY,&DeviceGeometry);
|
hasDeviceGeometry = B_OK == ioctl(fd, B_GET_GEOMETRY, &deviceGeometry);
|
||||||
HasPartitionInfo = B_OK == ioctl(fd,B_GET_PARTITION_INFO,&PartitionInfo);
|
hasPartitionInfo = B_OK == ioctl(fd, B_GET_PARTITION_INFO, &partitionInfo);
|
||||||
|
|
||||||
if (HasBiosGeometry) {
|
if (!isRawDevice && !hasBiosGeometry && !hasDeviceGeometry && !hasPartitionInfo)
|
||||||
|
isRawDevice = true;
|
||||||
|
|
||||||
|
if (hasBiosGeometry) {
|
||||||
printf("bios geometry: %ld heads, %ld cylinders, %ld sectors/track, %ld bytes/sector\n",
|
printf("bios geometry: %ld heads, %ld cylinders, %ld sectors/track, %ld bytes/sector\n",
|
||||||
BiosGeometry.head_count,BiosGeometry.cylinder_count,BiosGeometry.sectors_per_track,BiosGeometry.bytes_per_sector);
|
biosGeometry.head_count,biosGeometry.cylinder_count,biosGeometry.sectors_per_track,biosGeometry.bytes_per_sector);
|
||||||
}
|
}
|
||||||
if (HasBiosGeometry) {
|
if (hasBiosGeometry) {
|
||||||
printf("device geometry: %ld heads, %ld cylinders, %ld sectors/track, %ld bytes/sector\n",
|
printf("device geometry: %ld heads, %ld cylinders, %ld sectors/track, %ld bytes/sector\n",
|
||||||
DeviceGeometry.head_count,DeviceGeometry.cylinder_count,DeviceGeometry.sectors_per_track,DeviceGeometry.bytes_per_sector);
|
deviceGeometry.head_count,deviceGeometry.cylinder_count,deviceGeometry.sectors_per_track,deviceGeometry.bytes_per_sector);
|
||||||
}
|
}
|
||||||
if (HasPartitionInfo) {
|
if (hasPartitionInfo) {
|
||||||
printf("partition info: start at %Ld bytes (%Ld sectors), %Ld KB, %Ld MB, %Ld GB\n",
|
printf("partition info: start at %Ld bytes (%Ld sectors), %Ld KB, %Ld MB, %Ld GB\n",
|
||||||
PartitionInfo.offset,
|
partitionInfo.offset,
|
||||||
PartitionInfo.offset / 512,
|
partitionInfo.offset / 512,
|
||||||
PartitionInfo.offset / 1024,
|
partitionInfo.offset / 1024,
|
||||||
PartitionInfo.offset / (1024 * 1024),
|
partitionInfo.offset / (1024 * 1024),
|
||||||
PartitionInfo.offset / (1024 * 1024 * 1024));
|
partitionInfo.offset / (1024 * 1024 * 1024));
|
||||||
printf("partition info: size %Ld bytes, %Ld KB, %Ld MB, %Ld GB\n",
|
printf("partition info: size %Ld bytes, %Ld KB, %Ld MB, %Ld GB\n",
|
||||||
PartitionInfo.size,
|
partitionInfo.size,
|
||||||
PartitionInfo.size / 1024,
|
partitionInfo.size / 1024,
|
||||||
PartitionInfo.size / (1024 * 1024),
|
partitionInfo.size / (1024 * 1024),
|
||||||
PartitionInfo.size / (1024 * 1024 * 1024));
|
partitionInfo.size / (1024 * 1024 * 1024));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!HasBiosGeometry && !HasDeviceGeometry && !HasPartitionInfo) {
|
if (!isRawDevice && !hasPartitionInfo) {
|
||||||
fprintf(stderr,"Error: couldn't get device partition or geometry information\n");
|
|
||||||
close(fd);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IsRawDevice && !HasPartitionInfo) {
|
|
||||||
fprintf(stderr,"Warning: couldn't get partition information\n");
|
fprintf(stderr,"Warning: couldn't get partition information\n");
|
||||||
}
|
}
|
||||||
if ( (HasPartitionInfo && PartitionInfo.logical_block_size != 512)
|
if ( (hasPartitionInfo && partitionInfo.logical_block_size != 512)
|
||||||
|| (HasBiosGeometry && BiosGeometry.bytes_per_sector != 512)
|
|| (hasBiosGeometry && biosGeometry.bytes_per_sector != 512)
|
||||||
|| (HasDeviceGeometry && DeviceGeometry.bytes_per_sector != 512)) {
|
|| (hasDeviceGeometry && deviceGeometry.bytes_per_sector != 512)) {
|
||||||
fprintf(stderr,"Error: block size not 512 bytes\n");
|
fprintf(stderr,"Error: block size not 512 bytes\n");
|
||||||
close(fd);
|
close(fd);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
if (HasDeviceGeometry && DeviceGeometry.read_only) {
|
if (hasDeviceGeometry && deviceGeometry.read_only) {
|
||||||
fprintf(stderr,"Error: this is a read-only device\n");
|
fprintf(stderr,"Error: this is a read-only device\n");
|
||||||
close(fd);
|
close(fd);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
if (HasDeviceGeometry && DeviceGeometry.write_once) {
|
if (hasDeviceGeometry && deviceGeometry.write_once) {
|
||||||
fprintf(stderr,"Error: this is a write-once device\n");
|
fprintf(stderr,"Error: this is a write-once device\n");
|
||||||
close(fd);
|
close(fd);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
uint64 size = 0;
|
uint64 size = 0;
|
||||||
|
|
||||||
if (HasPartitionInfo) {
|
if (hasPartitionInfo) {
|
||||||
size = PartitionInfo.size;
|
size = partitionInfo.size;
|
||||||
} else if (HasDeviceGeometry) {
|
} else if (hasDeviceGeometry) {
|
||||||
size = uint64(DeviceGeometry.bytes_per_sector) * DeviceGeometry.sectors_per_track * DeviceGeometry.cylinder_count * DeviceGeometry.head_count;
|
size = uint64(deviceGeometry.bytes_per_sector) * deviceGeometry.sectors_per_track * deviceGeometry.cylinder_count * deviceGeometry.head_count;
|
||||||
} else if (HasBiosGeometry) {
|
} else if (hasBiosGeometry) {
|
||||||
size = uint64(BiosGeometry.bytes_per_sector) * BiosGeometry.sectors_per_track * BiosGeometry.cylinder_count * BiosGeometry.head_count;
|
size = uint64(biosGeometry.bytes_per_sector) * biosGeometry.sectors_per_track * biosGeometry.cylinder_count * biosGeometry.head_count;
|
||||||
|
} else {
|
||||||
|
// maybe it's just a file
|
||||||
|
struct stat stat;
|
||||||
|
if (fstat(fd, &stat) < 0) {
|
||||||
|
fprintf(stderr, "Error: couldn't get device partition or geometry information, nor size\n");
|
||||||
|
close(fd);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
size = stat.st_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsRawDevice && size > FLOPPY_MAX_SIZE) {
|
// TODO still valid on Haiku ?
|
||||||
|
/*if (isRawDevice && size > FLOPPY_MAX_SIZE) {
|
||||||
fprintf(stderr,"Error: device too large for floppy, or raw devices not supported\n");
|
fprintf(stderr,"Error: device too large for floppy, or raw devices not supported\n");
|
||||||
close(fd);
|
close(fd);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
printf("size = %Ld bytes (%Ld sectors), %Ld KB, %Ld MB, %Ld GB\n",
|
printf("size = %Ld bytes (%Ld sectors), %Ld KB, %Ld MB, %Ld GB\n",
|
||||||
size,
|
size,
|
||||||
@@ -249,7 +249,7 @@ status_t Initialize(int fatbits, const char *device, const char *label, bool nop
|
|||||||
|
|
||||||
if (fatbits == 0) {
|
if (fatbits == 0) {
|
||||||
//auto determine fat type
|
//auto determine fat type
|
||||||
if (IsRawDevice && size <= FLOPPY_MAX_SIZE && (size / FAT12_CLUSTER_MAX_SIZE) < FAT12_MAX_CLUSTER_COUNT) {
|
if (isRawDevice && size <= FLOPPY_MAX_SIZE && (size / FAT12_CLUSTER_MAX_SIZE) < FAT12_MAX_CLUSTER_COUNT) {
|
||||||
fatbits = 12;
|
fatbits = 12;
|
||||||
} else if ((size / CLUSTER_MAX_SIZE) < FAT16_MAX_CLUSTER_COUNT) {
|
} else if ((size / CLUSTER_MAX_SIZE) < FAT16_MAX_CLUSTER_COUNT) {
|
||||||
fatbits = 16;
|
fatbits = 16;
|
||||||
@@ -264,121 +264,121 @@ status_t Initialize(int fatbits, const char *device, const char *label, bool nop
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SectorPerCluster;
|
int sectorPerCluster;
|
||||||
|
|
||||||
SectorPerCluster = 0;
|
sectorPerCluster = 0;
|
||||||
if (fatbits == 12) {
|
if (fatbits == 12) {
|
||||||
SectorPerCluster = 0;
|
sectorPerCluster = 0;
|
||||||
if (size <= 4182016LL)
|
if (size <= 4182016LL)
|
||||||
SectorPerCluster = 2; // XXX don't know the correct value
|
sectorPerCluster = 2; // XXX don't know the correct value
|
||||||
if (size <= 2091008LL)
|
if (size <= 2091008LL)
|
||||||
SectorPerCluster = 1; // XXX don't know the correct value
|
sectorPerCluster = 1; // XXX don't know the correct value
|
||||||
} else if (fatbits == 16) {
|
} else if (fatbits == 16) {
|
||||||
// special BAD_CLUSTER value is 0xFFF7,
|
// special BAD_CLUSTER value is 0xFFF7,
|
||||||
// but this should work anyway, since space required by
|
// but this should work anyway, since space required by
|
||||||
// two FATs will make maximum cluster count smaller.
|
// two FATs will make maximum cluster count smaller.
|
||||||
// at least, this is what I think *should* happen
|
// at least, this is what I think *should* happen
|
||||||
SectorPerCluster = 0; //larger than 2 GB must fail
|
sectorPerCluster = 0; //larger than 2 GB must fail
|
||||||
if (size <= (2048 * 1024 * 1024LL)) // up to 2GB, use 32k clusters
|
if (size <= (2048 * 1024 * 1024LL)) // up to 2GB, use 32k clusters
|
||||||
SectorPerCluster = 64;
|
sectorPerCluster = 64;
|
||||||
if (size <= (1024 * 1024 * 1024LL)) // up to 1GB, use 16k clusters
|
if (size <= (1024 * 1024 * 1024LL)) // up to 1GB, use 16k clusters
|
||||||
SectorPerCluster = 32;
|
sectorPerCluster = 32;
|
||||||
if (size <= (512 * 1024 * 1024LL)) // up to 512MB, use 8k clusters
|
if (size <= (512 * 1024 * 1024LL)) // up to 512MB, use 8k clusters
|
||||||
SectorPerCluster = 16;
|
sectorPerCluster = 16;
|
||||||
if (size <= (256 * 1024 * 1024LL)) // up to 256MB, use 4k clusters
|
if (size <= (256 * 1024 * 1024LL)) // up to 256MB, use 4k clusters
|
||||||
SectorPerCluster = 8;
|
sectorPerCluster = 8;
|
||||||
if (size <= (128 * 1024 * 1024LL)) // up to 128MB, use 2k clusters
|
if (size <= (128 * 1024 * 1024LL)) // up to 128MB, use 2k clusters
|
||||||
SectorPerCluster = 4;
|
sectorPerCluster = 4;
|
||||||
if (size <= (16 * 1024 * 1024LL)) // up to 16MB, use 2k clusters
|
if (size <= (16 * 1024 * 1024LL)) // up to 16MB, use 2k clusters
|
||||||
SectorPerCluster = 2;
|
sectorPerCluster = 2;
|
||||||
if (size <= 4182016LL) // smaller than fat32 must fail
|
if (size <= 4182016LL) // smaller than fat32 must fail
|
||||||
SectorPerCluster = 0;
|
sectorPerCluster = 0;
|
||||||
} if (fatbits == 32) {
|
} if (fatbits == 32) {
|
||||||
SectorPerCluster = 64; // default is 32k clusters
|
sectorPerCluster = 64; // default is 32k clusters
|
||||||
if (size <= (32 * 1024 * 1024 * 1024LL)) // up to 32GB, use 16k clusters
|
if (size <= (32 * 1024 * 1024 * 1024LL)) // up to 32GB, use 16k clusters
|
||||||
SectorPerCluster = 32;
|
sectorPerCluster = 32;
|
||||||
if (size <= (16 * 1024 * 1024 * 1024LL)) // up to 16GB, use 8k clusters
|
if (size <= (16 * 1024 * 1024 * 1024LL)) // up to 16GB, use 8k clusters
|
||||||
SectorPerCluster = 16;
|
sectorPerCluster = 16;
|
||||||
if (size <= (8 * 1024 * 1024 * 1024LL)) // up to 8B, use 4k clusters
|
if (size <= (8 * 1024 * 1024 * 1024LL)) // up to 8B, use 4k clusters
|
||||||
SectorPerCluster = 8;
|
sectorPerCluster = 8;
|
||||||
if (size <= (532480 * 512LL)) // up to 260 MB, use 0.5k clusters
|
if (size <= (532480 * 512LL)) // up to 260 MB, use 0.5k clusters
|
||||||
SectorPerCluster = 1;
|
sectorPerCluster = 1;
|
||||||
if (size <= (66600 * 512LL)) // smaller than 32.5 MB must fail
|
if (size <= (66600 * 512LL)) // smaller than 32.5 MB must fail
|
||||||
SectorPerCluster = 0;
|
sectorPerCluster = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SectorPerCluster == 0) {
|
if (sectorPerCluster == 0) {
|
||||||
fprintf(stderr,"Error: failed to determine sector per cluster value, partition too large for %d bit fat\n",fatbits);
|
fprintf(stderr,"Error: failed to determine sector per cluster value, partition too large for %d bit fat\n",fatbits);
|
||||||
close(fd);
|
close(fd);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ReservedSectorCount = 0; // avoid compiler warning
|
int reservedSectorCount = 0; // avoid compiler warning
|
||||||
int RootEntryCount = 0; // avoid compiler warning
|
int rootEntryCount = 0; // avoid compiler warning
|
||||||
int NumFATs;
|
int numFATs;
|
||||||
int SectorSize;
|
int sectorSize;
|
||||||
uint8 BiosDriveId;
|
uint8 biosDriveId;
|
||||||
|
|
||||||
// get bios drive-id, or use 0x80
|
// get bios drive-id, or use 0x80
|
||||||
if (B_OK != ioctl(fd,B_GET_BIOS_DRIVE_ID,&BiosDriveId)) {
|
if (B_OK != ioctl(fd, B_GET_BIOS_DRIVE_ID, &biosDriveId)) {
|
||||||
BiosDriveId = 0x80;
|
biosDriveId = 0x80;
|
||||||
} else {
|
} else {
|
||||||
printf("bios drive id: 0x%02x\n",(int)BiosDriveId);
|
printf("bios drive id: 0x%02x\n", (int)biosDriveId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// default parameters for the bootsector
|
// default parameters for the bootsector
|
||||||
NumFATs = 2;
|
numFATs = 2;
|
||||||
SectorSize = 512;
|
sectorSize = 512;
|
||||||
if (fatbits == 12 || fatbits == 16)
|
if (fatbits == 12 || fatbits == 16)
|
||||||
ReservedSectorCount = 1;
|
reservedSectorCount = 1;
|
||||||
if (fatbits == 32)
|
if (fatbits == 32)
|
||||||
ReservedSectorCount = 32;
|
reservedSectorCount = 32;
|
||||||
if (fatbits == 12)
|
if (fatbits == 12)
|
||||||
RootEntryCount = 128; // XXX don't know the correct value
|
rootEntryCount = 128; // XXX don't know the correct value
|
||||||
if (fatbits == 16)
|
if (fatbits == 16)
|
||||||
RootEntryCount = 512;
|
rootEntryCount = 512;
|
||||||
if (fatbits == 32)
|
if (fatbits == 32)
|
||||||
RootEntryCount = 0;
|
rootEntryCount = 0;
|
||||||
|
|
||||||
// Determine FATSize
|
// Determine FATSize
|
||||||
// calculation done as MS recommends
|
// calculation done as MS recommends
|
||||||
uint64 DskSize = size / SectorSize;
|
uint64 dskSize = size / sectorSize;
|
||||||
uint32 RootDirSectors = ((RootEntryCount * 32) + (SectorSize - 1)) / SectorSize;
|
uint32 rootDirSectors = ((rootEntryCount * 32) + (sectorSize - 1)) / sectorSize;
|
||||||
uint64 TmpVal1 = DskSize - (ReservedSectorCount + RootDirSectors);
|
uint64 tmpVal1 = dskSize - (reservedSectorCount + rootDirSectors);
|
||||||
uint64 TmpVal2 = (256 * SectorPerCluster) + NumFATs;
|
uint64 tmpVal2 = (256 * sectorPerCluster) + numFATs;
|
||||||
if (fatbits == 32)
|
if (fatbits == 32)
|
||||||
TmpVal2 = TmpVal2 / 2;
|
tmpVal2 = tmpVal2 / 2;
|
||||||
uint32 FATSize = (TmpVal1 + (TmpVal2 - 1)) / TmpVal2;
|
uint32 FATSize = (tmpVal1 + (tmpVal2 - 1)) / tmpVal2;
|
||||||
// FATSize should now contain the size of *one* FAT, measured in sectors
|
// FATSize should now contain the size of *one* FAT, measured in sectors
|
||||||
// RootDirSectors should now contain the size of the fat12/16 root directory, measured in sectors
|
// RootDirSectors should now contain the size of the fat12/16 root directory, measured in sectors
|
||||||
|
|
||||||
printf("fatbits = %d, clustersize = %d\n",fatbits,SectorPerCluster * 512);
|
printf("fatbits = %d, clustersize = %d\n", fatbits, sectorPerCluster * 512);
|
||||||
printf("FAT size is %ld sectors\n",FATSize);
|
printf("FAT size is %ld sectors\n", FATSize);
|
||||||
printf("disk label: %s\n",label);
|
printf("disk label: %s\n", label);
|
||||||
|
|
||||||
char bootsector[512];
|
char bootsector[512];
|
||||||
memset(bootsector,0x00,512);
|
memset(bootsector,0x00,512);
|
||||||
memcpy(bootsector + BOOTJMP_START_OFFSET,bootjmp,sizeof(bootjmp));
|
memcpy(bootsector + BOOTJMP_START_OFFSET, bootjmp, sizeof(bootjmp));
|
||||||
memcpy(bootsector + BOOTCODE_START_OFFSET,bootcode,sizeof(bootcode));
|
memcpy(bootsector + BOOTCODE_START_OFFSET, bootcode, sizeof(bootcode));
|
||||||
|
|
||||||
if (fatbits == 32) {
|
if (fatbits == 32) {
|
||||||
bootsector32 *bs = (bootsector32 *)bootsector;
|
bootsector32 *bs = (bootsector32 *)bootsector;
|
||||||
uint16 temp16;
|
uint16 temp16;
|
||||||
uint32 temp32;
|
uint32 temp32;
|
||||||
memcpy(bs->BS_OEMName,"OpenBeOS",8);
|
memcpy(bs->BS_OEMName,"OpenBeOS",8);
|
||||||
bs->BPB_BytsPerSec = B_HOST_TO_LENDIAN_INT16(SectorSize);
|
bs->BPB_BytsPerSec = B_HOST_TO_LENDIAN_INT16(sectorSize);
|
||||||
bs->BPB_SecPerClus = SectorPerCluster;
|
bs->BPB_SecPerClus = sectorPerCluster;
|
||||||
bs->BPB_RsvdSecCnt = B_HOST_TO_LENDIAN_INT16(ReservedSectorCount);
|
bs->BPB_RsvdSecCnt = B_HOST_TO_LENDIAN_INT16(reservedSectorCount);
|
||||||
bs->BPB_NumFATs = NumFATs;
|
bs->BPB_NumFATs = numFATs;
|
||||||
bs->BPB_RootEntCnt = B_HOST_TO_LENDIAN_INT16(RootEntryCount);
|
bs->BPB_RootEntCnt = B_HOST_TO_LENDIAN_INT16(rootEntryCount);
|
||||||
bs->BPB_TotSec16 = B_HOST_TO_LENDIAN_INT16(0);
|
bs->BPB_TotSec16 = B_HOST_TO_LENDIAN_INT16(0);
|
||||||
bs->BPB_Media = 0xF8;
|
bs->BPB_Media = 0xF8;
|
||||||
bs->BPB_FATSz16 = B_HOST_TO_LENDIAN_INT16(0);
|
bs->BPB_FATSz16 = B_HOST_TO_LENDIAN_INT16(0);
|
||||||
temp16 = HasBiosGeometry ? BiosGeometry.sectors_per_track : 63;
|
temp16 = hasBiosGeometry ? biosGeometry.sectors_per_track : 63;
|
||||||
bs->BPB_SecPerTrk = B_HOST_TO_LENDIAN_INT16(temp16);
|
bs->BPB_SecPerTrk = B_HOST_TO_LENDIAN_INT16(temp16);
|
||||||
temp16 = HasBiosGeometry ? BiosGeometry.head_count : 255;
|
temp16 = hasBiosGeometry ? biosGeometry.head_count : 255;
|
||||||
bs->BPB_NumHeads = B_HOST_TO_LENDIAN_INT16(temp16);
|
bs->BPB_NumHeads = B_HOST_TO_LENDIAN_INT16(temp16);
|
||||||
temp32 = HasPartitionInfo ? (PartitionInfo.size / 512) : 0;
|
temp32 = hasPartitionInfo ? (partitionInfo.size / 512) : 0;
|
||||||
bs->BPB_HiddSec = B_HOST_TO_LENDIAN_INT32(temp32);
|
bs->BPB_HiddSec = B_HOST_TO_LENDIAN_INT32(temp32);
|
||||||
temp32 = size / 512;
|
temp32 = size / 512;
|
||||||
bs->BPB_TotSec32 = B_HOST_TO_LENDIAN_INT32(temp32);
|
bs->BPB_TotSec32 = B_HOST_TO_LENDIAN_INT32(temp32);
|
||||||
@@ -389,7 +389,7 @@ status_t Initialize(int fatbits, const char *device, const char *label, bool nop
|
|||||||
bs->BPB_FSInfo = B_HOST_TO_LENDIAN_INT16(FSINFO_SECTOR_NUM);
|
bs->BPB_FSInfo = B_HOST_TO_LENDIAN_INT16(FSINFO_SECTOR_NUM);
|
||||||
bs->BPB_BkBootSec = B_HOST_TO_LENDIAN_INT16(BACKUP_SECTOR_NUM);
|
bs->BPB_BkBootSec = B_HOST_TO_LENDIAN_INT16(BACKUP_SECTOR_NUM);
|
||||||
memset(bs->BPB_Reserved,0,12);
|
memset(bs->BPB_Reserved,0,12);
|
||||||
bs->BS_DrvNum = BiosDriveId;
|
bs->BS_DrvNum = biosDriveId;
|
||||||
bs->BS_Reserved1 = 0x00;
|
bs->BS_Reserved1 = 0x00;
|
||||||
bs->BS_BootSig = 0x29;
|
bs->BS_BootSig = 0x29;
|
||||||
*(uint32*)bs->BS_VolID = (uint32)system_time();
|
*(uint32*)bs->BS_VolID = (uint32)system_time();
|
||||||
@@ -401,25 +401,25 @@ status_t Initialize(int fatbits, const char *device, const char *label, bool nop
|
|||||||
uint16 temp16;
|
uint16 temp16;
|
||||||
uint32 temp32;
|
uint32 temp32;
|
||||||
uint32 sectorcount = size / 512;
|
uint32 sectorcount = size / 512;
|
||||||
memcpy(bs->BS_OEMName,"OpenBeOS",8);
|
memcpy(bs->BS_OEMName, "Haiku", 5);
|
||||||
bs->BPB_BytsPerSec = B_HOST_TO_LENDIAN_INT16(SectorSize);
|
bs->BPB_BytsPerSec = B_HOST_TO_LENDIAN_INT16(sectorSize);
|
||||||
bs->BPB_SecPerClus = SectorPerCluster;
|
bs->BPB_SecPerClus = sectorPerCluster;
|
||||||
bs->BPB_RsvdSecCnt = B_HOST_TO_LENDIAN_INT16(ReservedSectorCount);
|
bs->BPB_RsvdSecCnt = B_HOST_TO_LENDIAN_INT16(reservedSectorCount);
|
||||||
bs->BPB_NumFATs = NumFATs;
|
bs->BPB_NumFATs = numFATs;
|
||||||
bs->BPB_RootEntCnt = B_HOST_TO_LENDIAN_INT16(RootEntryCount);
|
bs->BPB_RootEntCnt = B_HOST_TO_LENDIAN_INT16(rootEntryCount);
|
||||||
temp16 = (sectorcount <= 65535) ? sectorcount : 0;
|
temp16 = (sectorcount <= 65535) ? sectorcount : 0;
|
||||||
bs->BPB_TotSec16 = B_HOST_TO_LENDIAN_INT16(temp16);
|
bs->BPB_TotSec16 = B_HOST_TO_LENDIAN_INT16(temp16);
|
||||||
bs->BPB_Media = 0xF8;
|
bs->BPB_Media = 0xF8;
|
||||||
bs->BPB_FATSz16 = B_HOST_TO_LENDIAN_INT16(FATSize);
|
bs->BPB_FATSz16 = B_HOST_TO_LENDIAN_INT16(FATSize);
|
||||||
temp16 = HasBiosGeometry ? BiosGeometry.sectors_per_track : 63;
|
temp16 = hasBiosGeometry ? biosGeometry.sectors_per_track : 63;
|
||||||
bs->BPB_SecPerTrk = B_HOST_TO_LENDIAN_INT16(temp16);
|
bs->BPB_SecPerTrk = B_HOST_TO_LENDIAN_INT16(temp16);
|
||||||
temp16 = HasBiosGeometry ? BiosGeometry.head_count : 255;
|
temp16 = hasBiosGeometry ? biosGeometry.head_count : 255;
|
||||||
bs->BPB_NumHeads = B_HOST_TO_LENDIAN_INT16(temp16);
|
bs->BPB_NumHeads = B_HOST_TO_LENDIAN_INT16(temp16);
|
||||||
temp32 = HasPartitionInfo ? (PartitionInfo.size / 512) : 0;
|
temp32 = hasPartitionInfo ? (partitionInfo.size / 512) : 0;
|
||||||
bs->BPB_HiddSec = B_HOST_TO_LENDIAN_INT32(temp32);
|
bs->BPB_HiddSec = B_HOST_TO_LENDIAN_INT32(temp32);
|
||||||
temp32 = (sectorcount <= 65535) ? 0 : sectorcount;
|
temp32 = (sectorcount <= 65535) ? 0 : sectorcount;
|
||||||
bs->BPB_TotSec32 = B_HOST_TO_LENDIAN_INT32(temp32);
|
bs->BPB_TotSec32 = B_HOST_TO_LENDIAN_INT32(temp32);
|
||||||
bs->BS_DrvNum = BiosDriveId;
|
bs->BS_DrvNum = biosDriveId;
|
||||||
bs->BS_Reserved1 = 0x00;
|
bs->BS_Reserved1 = 0x00;
|
||||||
bs->BS_BootSig = 0x29;
|
bs->BS_BootSig = 0x29;
|
||||||
*(uint32*)bs->BS_VolID = (uint32)system_time();
|
*(uint32*)bs->BS_VolID = (uint32)system_time();
|
||||||
@@ -463,11 +463,11 @@ status_t Initialize(int fatbits, const char *device, const char *label, bool nop
|
|||||||
printf("Writing FAT\n");
|
printf("Writing FAT\n");
|
||||||
char * zerobuffer = (char *)malloc(65536);
|
char * zerobuffer = (char *)malloc(65536);
|
||||||
memset(zerobuffer,0,65536);
|
memset(zerobuffer,0,65536);
|
||||||
int64 bytes_to_write = 512LL * (ReservedSectorCount + (NumFATs * FATSize) + RootDirSectors);
|
int64 bytes_to_write = 512LL * (reservedSectorCount + (numFATs * FATSize) + rootDirSectors);
|
||||||
int64 pos = 0;
|
int64 pos = 0;
|
||||||
while (bytes_to_write > 0) {
|
while (bytes_to_write > 0) {
|
||||||
ssize_t writesize = min_c(bytes_to_write,65536);
|
ssize_t writesize = min_c(bytes_to_write, 65536);
|
||||||
written = file.WriteAt(pos,zerobuffer,writesize);
|
written = write_pos(fd, pos, zerobuffer, writesize);
|
||||||
if (written != writesize) {
|
if (written != writesize) {
|
||||||
fprintf(stderr,"Error: write error near sector %Ld\n",pos / 512);
|
fprintf(stderr,"Error: write error near sector %Ld\n",pos / 512);
|
||||||
close(fd);
|
close(fd);
|
||||||
@@ -480,17 +480,17 @@ status_t Initialize(int fatbits, const char *device, const char *label, bool nop
|
|||||||
|
|
||||||
//write boot sector
|
//write boot sector
|
||||||
printf("Writing boot block\n");
|
printf("Writing boot block\n");
|
||||||
written = file.WriteAt(BOOT_SECTOR_NUM * 512,bootsector,512);
|
written = write_pos(fd, BOOT_SECTOR_NUM * 512, bootsector, 512);
|
||||||
if (written != 512) {
|
if (written != 512) {
|
||||||
fprintf(stderr,"Error: write error at sector %d\n",BOOT_SECTOR_NUM);
|
fprintf(stderr,"Error: write error at sector %d\n", BOOT_SECTOR_NUM);
|
||||||
close(fd);
|
close(fd);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fatbits == 32) {
|
if (fatbits == 32) {
|
||||||
written = file.WriteAt(BACKUP_SECTOR_NUM * 512,bootsector,512);
|
written = write_pos(fd, BACKUP_SECTOR_NUM * 512, bootsector, 512);
|
||||||
if (written != 512) {
|
if (written != 512) {
|
||||||
fprintf(stderr,"Error: write error at sector %d\n",BACKUP_SECTOR_NUM);
|
fprintf(stderr,"Error: write error at sector %d\n", BACKUP_SECTOR_NUM);
|
||||||
close(fd);
|
close(fd);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
@@ -530,16 +530,16 @@ status_t Initialize(int fatbits, const char *device, const char *label, bool nop
|
|||||||
sec[10] = 0xFF;
|
sec[10] = 0xFF;
|
||||||
sec[11] = 0x0F;
|
sec[11] = 0x0F;
|
||||||
}
|
}
|
||||||
written = file.WriteAt(ReservedSectorCount * 512,sec,512);
|
written = write_pos(fd, reservedSectorCount * 512, sec, 512);
|
||||||
if (written != 512) {
|
if (written != 512) {
|
||||||
fprintf(stderr,"Error: write error at sector %d\n",ReservedSectorCount);
|
fprintf(stderr,"Error: write error at sector %d\n", reservedSectorCount);
|
||||||
close(fd);
|
close(fd);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
if (NumFATs > 1) {
|
if (numFATs > 1) {
|
||||||
written = file.WriteAt((ReservedSectorCount + FATSize) * 512,sec,512);
|
written = write_pos(fd, (reservedSectorCount + FATSize) * 512,sec,512);
|
||||||
if (written != 512) {
|
if (written != 512) {
|
||||||
fprintf(stderr,"Error: write error at sector %ld\n",ReservedSectorCount + FATSize);
|
fprintf(stderr,"Error: write error at sector %ld\n", reservedSectorCount + FATSize);
|
||||||
close(fd);
|
close(fd);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
@@ -551,9 +551,9 @@ status_t Initialize(int fatbits, const char *device, const char *label, bool nop
|
|||||||
//calculate total sector count first
|
//calculate total sector count first
|
||||||
uint64 free_count = size / 512;
|
uint64 free_count = size / 512;
|
||||||
//now account for already by metadata used sectors
|
//now account for already by metadata used sectors
|
||||||
free_count -= ReservedSectorCount + (NumFATs * FATSize) + RootDirSectors;
|
free_count -= reservedSectorCount + (numFATs * FATSize) + rootDirSectors;
|
||||||
//convert from sector to clustercount
|
//convert from sector to clustercount
|
||||||
free_count /= SectorPerCluster;
|
free_count /= sectorPerCluster;
|
||||||
//and account for 1 already used cluster of root directory
|
//and account for 1 already used cluster of root directory
|
||||||
free_count -= 1;
|
free_count -= 1;
|
||||||
fsinfosector32 fsinfosector;
|
fsinfosector32 fsinfosector;
|
||||||
@@ -563,9 +563,9 @@ status_t Initialize(int fatbits, const char *device, const char *label, bool nop
|
|||||||
fsinfosector.FSI_Free_Count = B_HOST_TO_LENDIAN_INT32((uint32)free_count);
|
fsinfosector.FSI_Free_Count = B_HOST_TO_LENDIAN_INT32((uint32)free_count);
|
||||||
fsinfosector.FSI_Nxt_Free = B_HOST_TO_LENDIAN_INT32(3);
|
fsinfosector.FSI_Nxt_Free = B_HOST_TO_LENDIAN_INT32(3);
|
||||||
fsinfosector.FSI_TrailSig = B_HOST_TO_LENDIAN_INT32(0xAA550000);
|
fsinfosector.FSI_TrailSig = B_HOST_TO_LENDIAN_INT32(0xAA550000);
|
||||||
written = file.WriteAt(FSINFO_SECTOR_NUM * 512,&fsinfosector,512);
|
written = write_pos(fd, FSINFO_SECTOR_NUM * 512, &fsinfosector, 512);
|
||||||
if (written != 512) {
|
if (written != 512) {
|
||||||
fprintf(stderr,"Error: write error at sector %d\n",FSINFO_SECTOR_NUM);
|
fprintf(stderr,"Error: write error at sector %d\n", FSINFO_SECTOR_NUM);
|
||||||
close(fd);
|
close(fd);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
@@ -575,31 +575,31 @@ status_t Initialize(int fatbits, const char *device, const char *label, bool nop
|
|||||||
printf("Writing root directory\n");
|
printf("Writing root directory\n");
|
||||||
if (fatbits == 12 || fatbits == 16) {
|
if (fatbits == 12 || fatbits == 16) {
|
||||||
uint8 data[512];
|
uint8 data[512];
|
||||||
memset(data,0,512);
|
memset(data, 0, 512);
|
||||||
CreateVolumeLabel(data,label);
|
CreateVolumeLabel(data, label);
|
||||||
uint32 RootDirSector = ReservedSectorCount + (NumFATs * FATSize);
|
uint32 rootDirSector = reservedSectorCount + (numFATs * FATSize);
|
||||||
written = file.WriteAt(RootDirSector * 512,data,512);
|
written = write_pos(fd, rootDirSector * 512, data, 512);
|
||||||
if (written != 512) {
|
if (written != 512) {
|
||||||
fprintf(stderr,"Error: write error at sector %ld\n",RootDirSector);
|
fprintf(stderr,"Error: write error at sector %ld\n", rootDirSector);
|
||||||
close(fd);
|
close(fd);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
} else if (fatbits == 32) {
|
} else if (fatbits == 32) {
|
||||||
int size = 512 * SectorPerCluster;
|
int size = 512 * sectorPerCluster;
|
||||||
uint8 *cluster = (uint8*)malloc(size);
|
uint8 *cluster = (uint8*)malloc(size);
|
||||||
memset(cluster,0,size);
|
memset(cluster, 0, size);
|
||||||
CreateVolumeLabel(cluster,label);
|
CreateVolumeLabel(cluster, label);
|
||||||
uint32 RootDirSector = ReservedSectorCount + (NumFATs * FATSize) + RootDirSectors;
|
uint32 rootDirSector = reservedSectorCount + (numFATs * FATSize) + rootDirSectors;
|
||||||
written = file.WriteAt(RootDirSector * 512,cluster,size);
|
written = write_pos(fd, rootDirSector * 512, cluster, size);
|
||||||
free(cluster);
|
free(cluster);
|
||||||
if (written != size) {
|
if (written != size) {
|
||||||
fprintf(stderr,"Error: write error at sector %ld\n",RootDirSector);
|
fprintf(stderr,"Error: write error at sector %ld\n", rootDirSector);
|
||||||
close(fd);
|
close(fd);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ioctl(fd,B_FLUSH_DRIVE_CACHE);
|
ioctl(fd, B_FLUSH_DRIVE_CACHE);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -613,9 +613,9 @@ void CreateVolumeLabel(void *sector, const char *label)
|
|||||||
// XXX but the dosfs would have to be updated, too
|
// XXX but the dosfs would have to be updated, too
|
||||||
|
|
||||||
dirent *d = (dirent *)sector;
|
dirent *d = (dirent *)sector;
|
||||||
memset(d,0,sizeof(*d));
|
memset(d, 0, sizeof(*d));
|
||||||
memset(d->Name,0x20,11);
|
memset(d->Name, 0x20, 11);
|
||||||
memcpy(d->Name,label,min_c(11,strlen(label)));
|
memcpy(d->Name, label, min_c(11, strlen(label)));
|
||||||
d->Attr = 0x08;
|
d->Attr = 0x08;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user