ntfs_boot_sector_is_ntfs/ntfs_boot_sector_parse: log errors

master
szaka 2006-12-08 23:55:10 +00:00
parent a65b19aa02
commit 45630fa43c
3 changed files with 78 additions and 78 deletions

View File

@ -1,8 +1,9 @@
/*
* bootsect.h - Exports for bootsector record handling. Originated from the Linux-NTFS
* project.
* bootsect.h - Exports for bootsector record handling.
* Originated from the Linux-NTFS project.
*
* Copyright (c) 2000-2002 Anton Altaparmakov
* Copyright (c) 2006 Szabolcs Szakacsits
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
@ -28,20 +29,14 @@
#include "layout.h"
/**
* is_boot_sector_ntfs - check a boot sector for describing an ntfs volume
* ntfs_boot_sector_is_ntfs - check a boot sector for describing an ntfs volume
* @b: buffer containing the boot sector
* @silent: if 1 don't display progress information
*
* This function checks the boot sector in @b for describing a valid ntfs
* volume. Return TRUE if @b is a valid NTFS boot sector or FALSE otherwise.
* If silent is FALSE, progress output will be output to stdout. If silent is
* TRUE no output to stdout will occur. Errors/warnings to stderr will occur
* disregarding the value of silent (but only if configure was run with
* --enable-debug).
*/
extern BOOL ntfs_boot_sector_is_ntfs(NTFS_BOOT_SECTOR *b, BOOL silent);
extern int ntfs_boot_sector_parse(ntfs_volume *vol,
const NTFS_BOOT_SECTOR *bs);
extern BOOL ntfs_boot_sector_is_ntfs(NTFS_BOOT_SECTOR *b);
extern int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs);
#endif /* defined _NTFS_BOOTSECT_H */

View File

@ -2,7 +2,7 @@
* bootsect.c - Boot sector handling code. Originated from the Linux-NTFS project.
*
* Copyright (c) 2000-2006 Anton Altaparmakov
* Copyright (c) 2003-2004 Szabolcs Szakacsits
* Copyright (c) 2003-2006 Szabolcs Szakacsits
* Copyright (c) 2005 Yura Pakhuchiy
*
* This program/include file is free software; you can redistribute it and/or
@ -57,11 +57,12 @@
*
* Return TRUE if @b contains a valid ntfs boot sector and FALSE if not.
*/
BOOL ntfs_boot_sector_is_ntfs(NTFS_BOOT_SECTOR *b, const BOOL silent __attribute__((unused)))
BOOL ntfs_boot_sector_is_ntfs(NTFS_BOOT_SECTOR *b)
{
u32 i;
BOOL ret = FALSE;
ntfs_log_debug("\nBeginning bootsector check...\n");
ntfs_log_debug("Beginning bootsector check.\n");
/* Calculate the checksum. Note, this is just a simple addition of
all u32 values in the bootsector starting at the beginning and
@ -71,93 +72,102 @@ BOOL ntfs_boot_sector_is_ntfs(NTFS_BOOT_SECTOR *b, const BOOL silent __attribute
u32 *u = (u32 *)b;
u32 *bi = (u32 *)(&b->checksum);
ntfs_log_debug("Calculating bootsector checksum... ");
ntfs_log_debug("Calculating bootsector checksum.\n");
for (i = 0; u < bi; ++u)
i += le32_to_cpup(u);
if (le32_to_cpu(b->checksum) && le32_to_cpu(b->checksum) != i)
if (le32_to_cpu(b->checksum) && le32_to_cpu(b->checksum) != i) {
ntfs_log_error("Bootsector checksum failed.\n");
goto not_ntfs;
ntfs_log_debug("OK\n");
}
}
/* Check OEMidentifier is "NTFS " */
ntfs_log_debug("Checking OEMid... ");
if (b->oem_id != cpu_to_le64(0x202020205346544eULL)) /* "NTFS " */
ntfs_log_debug("Checking OEMid, NTFS signature.\n");
if (b->oem_id != cpu_to_le64(0x202020205346544eULL)) { /* "NTFS " */
ntfs_log_error("NTFS signature is missing.\n");
goto not_ntfs;
ntfs_log_debug("OK\n");
}
/* Check bytes per sector value is between 256 and 4096. */
ntfs_log_debug("Checking bytes per sector... ");
if (le16_to_cpu(b->bpb.bytes_per_sector) < 0x100 ||
le16_to_cpu(b->bpb.bytes_per_sector) > 0x1000)
ntfs_log_debug("Checking bytes per sector.\n");
if (le16_to_cpu(b->bpb.bytes_per_sector) < 256 ||
le16_to_cpu(b->bpb.bytes_per_sector) > 4096) {
ntfs_log_error("Unexpected bytes per sector value (%d).\n",
le16_to_cpu(b->bpb.bytes_per_sector));
goto not_ntfs;
ntfs_log_debug("OK\n");
}
/* Check sectors per cluster value is valid. */
ntfs_log_debug("Checking sectors per cluster... ");
ntfs_log_debug("Checking sectors per cluster.\n");
switch (b->bpb.sectors_per_cluster) {
case 1: case 2: case 4: case 8: case 16: case 32: case 64: case 128:
break;
default:
ntfs_log_error("Unexpected sectors per cluster value (%d).\n",
b->bpb.sectors_per_cluster);
goto not_ntfs;
}
ntfs_log_debug("OK\n");
/* Check the cluster size is not above 65536 bytes. */
ntfs_log_debug("Checking cluster size... ");
if ((u32)le16_to_cpu(b->bpb.bytes_per_sector) *
b->bpb.sectors_per_cluster > 0x10000)
ntfs_log_debug("Checking cluster size.\n");
i = (u32)le16_to_cpu(b->bpb.bytes_per_sector) *
b->bpb.sectors_per_cluster;
if (i > 65536) {
ntfs_log_error("Unexpected cluster size (%d).\n", i);
goto not_ntfs;
ntfs_log_debug("OK\n");
}
/* Check reserved/unused fields are really zero. */
ntfs_log_debug("Checking reserved fields are zero... ");
ntfs_log_debug("Checking reserved fields are zero.\n");
if (le16_to_cpu(b->bpb.reserved_sectors) ||
le16_to_cpu(b->bpb.root_entries) ||
le16_to_cpu(b->bpb.sectors) ||
le16_to_cpu(b->bpb.sectors_per_fat) ||
le32_to_cpu(b->bpb.large_sectors) ||
b->bpb.fats)
b->bpb.fats) {
ntfs_log_error("Reserved fields aren't zero "
"(%d, %d, %d, %d, %d, %d).\n",
le16_to_cpu(b->bpb.reserved_sectors),
le16_to_cpu(b->bpb.root_entries),
le16_to_cpu(b->bpb.sectors),
le16_to_cpu(b->bpb.sectors_per_fat),
le32_to_cpu(b->bpb.large_sectors),
b->bpb.fats);
goto not_ntfs;
ntfs_log_debug("OK\n");
}
/* Check clusters per file mft record value is valid. */
ntfs_log_debug("Checking clusters per mft record... ");
ntfs_log_debug("Checking clusters per mft record.\n");
if ((u8)b->clusters_per_mft_record < 0xe1 ||
(u8)b->clusters_per_mft_record > 0xf7) {
switch (b->clusters_per_mft_record) {
case 1: case 2: case 4: case 8: case 0x10: case 0x20: case 0x40:
break;
default:
ntfs_log_error("Unexpected clusters per mft record "
"(%d).\n", b->clusters_per_mft_record);
goto not_ntfs;
}
}
ntfs_log_debug("OK\n");
/* Check clusters per index block value is valid. */
ntfs_log_debug("Checking clusters per index block... ");
ntfs_log_debug("Checking clusters per index block.\n");
if ((u8)b->clusters_per_index_record < 0xe1 ||
(u8)b->clusters_per_index_record > 0xf7) {
switch (b->clusters_per_index_record) {
case 1: case 2: case 4: case 8: case 0x10: case 0x20: case 0x40:
break;
default:
ntfs_log_error("Unexpected clusters per index record "
"(%d).\n", b->clusters_per_index_record);
goto not_ntfs;
}
}
ntfs_log_debug("OK\n");
if (b->end_of_sector_marker != cpu_to_le16(0xaa55))
ntfs_log_debug("Warning: Bootsector has invalid end of sector marker.\n");
ntfs_log_debug("Warning: Bootsector has invalid end of sector "
"marker.\n");
ntfs_log_debug("Bootsector check completed successfully.\n");
return TRUE;
ret = TRUE;
not_ntfs:
ntfs_log_debug("FAILED\n");
ntfs_log_error("Bootsector check failed.\n");
return FALSE;
return ret;
}
/**
@ -172,8 +182,9 @@ not_ntfs:
*/
int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs)
{
u8 sectors_per_cluster;
s8 c;
s64 sectors;
u8 sectors_per_cluster;
s8 c;
/* We return -1 with errno = EINVAL on error. */
errno = EINVAL;
@ -188,34 +199,34 @@ int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs)
* ntfs_boot_sector_is_ntfs but in this way we can just do this once.
*/
sectors_per_cluster = bs->bpb.sectors_per_cluster;
ntfs_log_debug("NumberOfSectors = %lli\n", sle64_to_cpu(bs->number_of_sectors));
ntfs_log_debug("SectorsPerCluster = 0x%x\n", sectors_per_cluster);
if (sectors_per_cluster & (sectors_per_cluster - 1)) {
ntfs_log_debug("Error: %s is not a valid NTFS partition! "
"sectors_per_cluster is not a power of 2.\n",
vol->dev->d_name);
ntfs_log_error("sectors_per_cluster (%d) is not a power of 2."
"\n", sectors_per_cluster);
return -1;
}
vol->nr_clusters = sle64_to_cpu(bs->number_of_sectors) >>
(ffs(sectors_per_cluster) - 1);
sectors = sle64_to_cpu(bs->number_of_sectors);
ntfs_log_debug("NumberOfSectors = %lld\n", sectors);
vol->nr_clusters = sectors >> (ffs(sectors_per_cluster) - 1);
vol->mft_lcn = sle64_to_cpu(bs->mft_lcn);
vol->mftmirr_lcn = sle64_to_cpu(bs->mftmirr_lcn);
ntfs_log_debug("MFT LCN = 0x%llx\n", vol->mft_lcn);
ntfs_log_debug("MFTMirr LCN = 0x%llx\n", vol->mftmirr_lcn);
if (vol->mft_lcn > vol->nr_clusters ||
vol->mftmirr_lcn > vol->nr_clusters) {
ntfs_log_debug("Error: %s is not a valid NTFS partition!\n",
vol->dev->d_name);
ntfs_log_debug("($Mft LCN or $MftMirr LCN is greater than the "
"number of clusters!)\n");
if (vol->mft_lcn > vol->nr_clusters ||
vol->mftmirr_lcn > vol->nr_clusters) {
ntfs_log_error("$MFT LCN (%lld) or $MFTMirr LCN (%lld) is "
"greater than the number of clusters (%lld).\n",
vol->mft_lcn, vol->mftmirr_lcn, vol->nr_clusters);
return -1;
}
vol->cluster_size = sectors_per_cluster * vol->sector_size;
if (vol->cluster_size & (vol->cluster_size - 1)) {
ntfs_log_debug("Error: %s is not a valid NTFS partition! "
"cluster_size is not a power of 2.\n",
vol->dev->d_name);
ntfs_log_error("cluster_size (%d) is not a power of 2.\n",
vol->cluster_size);
return -1;
}
vol->cluster_size_bits = ffs(vol->cluster_size) - 1;
@ -239,9 +250,8 @@ int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs)
else
vol->mft_record_size = c << vol->cluster_size_bits;
if (vol->mft_record_size & (vol->mft_record_size - 1)) {
ntfs_log_debug("Error: %s is not a valid NTFS partition! "
"mft_record_size is not a power of 2.\n",
vol->dev->d_name);
ntfs_log_error("mft_record_size (%d) is not a power of 2.\n",
vol->mft_record_size);
return -1;
}
vol->mft_record_size_bits = ffs(vol->mft_record_size) - 1;
@ -271,3 +281,4 @@ int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs)
vol->mftmirr_size = vol->cluster_size / vol->mft_record_size;
return 0;
}

View File

@ -391,9 +391,6 @@ ntfs_volume *ntfs_volume_startup(struct ntfs_device *dev, unsigned long flags)
#ifdef DEBUG
const char *OK = "OK\n";
const char *FAILED = "FAILED\n";
BOOL debug = 1;
#else
BOOL debug = 0;
#endif
if (!dev || !dev->d_ops || !dev->d_name) {
@ -443,16 +440,13 @@ ntfs_volume *ntfs_volume_startup(struct ntfs_device *dev, unsigned long flags)
goto error_exit;
}
ntfs_log_debug(OK);
if (!ntfs_boot_sector_is_ntfs(bs, !debug)) {
ntfs_log_error("Device '%s' is not a valid NTFS partition!\n",
dev->d_name);
if (!ntfs_boot_sector_is_ntfs(bs)) {
errno = EINVAL;
goto error_exit;
}
if (ntfs_boot_sector_parse(vol, bs) < 0) {
ntfs_log_perror("Failed to parse ntfs bootsector");
if (ntfs_boot_sector_parse(vol, bs) < 0)
goto error_exit;
}
free(bs);
bs = NULL;
/* Now set the device block size to the sector size. */