Added code to search out anchor volume pointers and dump out any

volume descriptor sequences found.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3280 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Tyler Dauwalder
2003-05-21 07:09:50 +00:00
parent 6cbf5bf379
commit 565457fd43
2 changed files with 88 additions and 15 deletions
+84 -13
View File
@@ -9,7 +9,6 @@
#include "Volume.h"
#include "Block.h"
#include "DiskStructures.h"
using namespace UDF;
@@ -41,7 +40,8 @@ status_t
Volume::Mount(const char *deviceName, off_t volumeStart, off_t volumeLength,
uint32 flags, uint32 blockSize)
{
DEBUG_INIT(CF_PUBLIC | CF_VOLUME_OPS);
DEBUG_INIT_ETC(CF_PUBLIC | CF_VOLUME_OPS, "Volume",
("devName = `%s'", deviceName));
if (!deviceName)
RETURN_ERROR(B_BAD_VALUE);
if (_InitStatus() == B_INITIALIZED)
@@ -95,7 +95,7 @@ Volume::Mount(const char *deviceName, off_t volumeStart, off_t volumeLength,
status_t
Volume::_Identify()
{
DEBUG_INIT(CF_PRIVATE | CF_VOLUME_OPS);
DEBUG_INIT(CF_PRIVATE | CF_VOLUME_OPS, "Volume");
status_t err = _InitStatus() == B_DEVICE_INITIALIZED ? B_OK : B_BAD_VALUE;
@@ -112,21 +112,66 @@ Volume::_Identify()
Length(),
512,
};
// Found an avds, so try the main sequence first, then
// the reserve sequence if the main one fails.
// Both failed, so try another avds
bool found_vds = false;
for (int32 i = 0; i < avds_location_count; i++) {
off_t block = avds_locations[i];
off_t address = AddressForRelativeBlock(block);
Block<anchor_volume_descriptor_pointer> anchor(BlockSize());
status_t anchorErr = anchor.InitCheck();
if (!anchorErr) {
ssize_t bytesRead = read_pos(fDevice, address, anchor.Data(), BlockSize());
anchorErr = bytesRead == (ssize_t)BlockSize() ? B_OK : B_IO_ERROR;
if (anchorErr) {
PRINT(("block %lld: read_pos(pos:%lld, len:%ld) failed with error 0x%lx\n",
block, address, BlockSize(), bytesRead));
}
}
if (!anchorErr) {
anchor.Data()->tag().dump();
anchorErr = anchor.Data()->tag().init_check(block);
if (anchorErr) {
PRINT(("block %lld: invalid anchor\n", block));
} else {
PRINT(("block %lld: valid anchor\n", block));
}
}
if (!anchorErr) {
// Found an avds, so try the main sequence first, then
// the reserve sequence if the main one fails.
anchorErr = _WalkVolumeDescriptorSequence(anchor.Data()->main_vds());
if (anchorErr)
anchorErr = _WalkVolumeDescriptorSequence(anchor.Data()->reserve_vds());
}
if (!anchorErr) {
PRINT(("block %lld: found valid vds\n", avds_locations[i]));
found_vds = true;
break;
} //else {
// Both failed, so loop around and try another avds
// PRINT(("block %lld: vds search failed\n", avds_locations[i]));
// }
}
err = found_vds ? B_OK : B_ERROR;
}
RETURN(err);
}
/*! \brief Walks the iso9660/ecma-167 volume recognition sequence, returning
\c B_OK if the presence of a UDF filesystem on this volume is likely.
\return \c B_OK: An ECMA-167 vsd was found, or at least one extended area
vsd was found and no ECMA-168 vsds were found.
\return "error code": Only iso9660 vsds were found, an ECMA-168 vsd was
found (but no ECMA-167 vsd), or an error occurred.
*/
status_t
Volume::_WalkVolumeRecognitionSequence()
{
DEBUG_INIT(CF_PRIVATE | CF_VOLUME_OPS);
DEBUG_INIT(CF_PRIVATE | CF_VOLUME_OPS, "Volume");
// vrs starts at block 16. Each volume structure descriptor (vsd)
// should be one block long. We're expecting to find 0 or more iso9660
// vsd's followed by some ECMA-167 vsd's.
@@ -140,7 +185,7 @@ Volume::_WalkVolumeRecognitionSequence()
bool foundBoot = false;
for (uint32 block = 16; true; block++) {
PRINT(("block %ld: ", block))
off_t address = RelativeAddressForBlock(block);
off_t address = AddressForRelativeBlock(block);
ssize_t bytesRead = read_pos(fDevice, address, descriptor.Data(), BlockSize());
if (bytesRead == (ssize_t)BlockSize())
{
@@ -187,9 +232,35 @@ Volume::_WalkVolumeRecognitionSequence()
}
status_t
Volume::_WalkVolumeDescriptorSequence(off_t start)
Volume::_WalkVolumeDescriptorSequence(extent_address extent)
{
DEBUG_INIT(CF_PRIVATE | CF_VOLUME_OPS);
DEBUG_INIT_ETC(CF_PRIVATE | CF_VOLUME_OPS, "Volume", ("loc:%ld, len:%ld",
extent.location(), extent.length()));
uint32 count = extent.length()/BlockSize();
for (uint32 i = 0; i < count; i++)
{
off_t block = extent.location()+i;
off_t address = AddressForRelativeBlock(block);
Block<descriptor_tag> tag(BlockSize());
status_t err = tag.InitCheck();
if (!err) {
ssize_t bytesRead = read_pos(fDevice, address, tag.Data(), BlockSize());
err = bytesRead == (ssize_t)BlockSize() ? B_OK : B_IO_ERROR;
if (err) {
PRINT(("block %lld: read_pos(pos:%lld, len:%ld) failed with error 0x%lx\n",
block, address, BlockSize(), bytesRead));
}
}
if (!err) {
PRINT(("descriptor #%ld (block %lld):\n", i, block));
if (tag.Data()->id() == 1) {
primary_vd *vd = (primary_vd*)tag.Data();
vd->dump();
} else {
tag.Data()->dump();
}
}
}
RETURN(B_ERROR);
}
+4 -2
View File
@@ -24,6 +24,8 @@ extern "C" {
#include "cpp.h"
#include "UdfDebug.h"
#include "DiskStructures.h"
namespace UDF {
class Volume {
@@ -44,7 +46,7 @@ public:
off_t Length() const { return fLength; }
uint32 BlockSize() const { return fBlockSize; }
off_t RelativeAddressForBlock(off_t block) { return StartAddress() + block * BlockSize(); }
off_t AddressForRelativeBlock(off_t block) { return StartAddress() + block * BlockSize(); }
off_t RelativeAddress(off_t address) { return StartAddress() + address; }
@@ -64,7 +66,7 @@ private:
// Called by Mount(), either directly or indirectly
status_t _Identify();
status_t _WalkVolumeRecognitionSequence();
status_t _WalkVolumeDescriptorSequence(off_t start);
status_t _WalkVolumeDescriptorSequence(extent_address extent);
private:
nspace_id fID;