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
+79 -8
View File
@@ -9,7 +9,6 @@
#include "Volume.h" #include "Volume.h"
#include "Block.h" #include "Block.h"
#include "DiskStructures.h"
using namespace UDF; using namespace UDF;
@@ -41,7 +40,8 @@ status_t
Volume::Mount(const char *deviceName, off_t volumeStart, off_t volumeLength, Volume::Mount(const char *deviceName, off_t volumeStart, off_t volumeLength,
uint32 flags, uint32 blockSize) 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) if (!deviceName)
RETURN_ERROR(B_BAD_VALUE); RETURN_ERROR(B_BAD_VALUE);
if (_InitStatus() == B_INITIALIZED) if (_InitStatus() == B_INITIALIZED)
@@ -95,7 +95,7 @@ Volume::Mount(const char *deviceName, off_t volumeStart, off_t volumeLength,
status_t status_t
Volume::_Identify() 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; status_t err = _InitStatus() == B_DEVICE_INITIALIZED ? B_OK : B_BAD_VALUE;
@@ -112,21 +112,66 @@ Volume::_Identify()
Length(), Length(),
512, 512,
}; };
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 // Found an avds, so try the main sequence first, then
// the reserve sequence if the main one fails. // the reserve sequence if the main one fails.
anchorErr = _WalkVolumeDescriptorSequence(anchor.Data()->main_vds());
if (anchorErr)
anchorErr = _WalkVolumeDescriptorSequence(anchor.Data()->reserve_vds());
// Both failed, so try another avds
} }
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); 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 status_t
Volume::_WalkVolumeRecognitionSequence() 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) // vrs starts at block 16. Each volume structure descriptor (vsd)
// should be one block long. We're expecting to find 0 or more iso9660 // should be one block long. We're expecting to find 0 or more iso9660
// vsd's followed by some ECMA-167 vsd's. // vsd's followed by some ECMA-167 vsd's.
@@ -140,7 +185,7 @@ Volume::_WalkVolumeRecognitionSequence()
bool foundBoot = false; bool foundBoot = false;
for (uint32 block = 16; true; block++) { for (uint32 block = 16; true; block++) {
PRINT(("block %ld: ", 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()); ssize_t bytesRead = read_pos(fDevice, address, descriptor.Data(), BlockSize());
if (bytesRead == (ssize_t)BlockSize()) if (bytesRead == (ssize_t)BlockSize())
{ {
@@ -187,9 +232,35 @@ Volume::_WalkVolumeRecognitionSequence()
} }
status_t 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); RETURN(B_ERROR);
} }
+4 -2
View File
@@ -24,6 +24,8 @@ extern "C" {
#include "cpp.h" #include "cpp.h"
#include "UdfDebug.h" #include "UdfDebug.h"
#include "DiskStructures.h"
namespace UDF { namespace UDF {
class Volume { class Volume {
@@ -44,7 +46,7 @@ public:
off_t Length() const { return fLength; } off_t Length() const { return fLength; }
uint32 BlockSize() const { return fBlockSize; } 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; } off_t RelativeAddress(off_t address) { return StartAddress() + address; }
@@ -64,7 +66,7 @@ private:
// Called by Mount(), either directly or indirectly // Called by Mount(), either directly or indirectly
status_t _Identify(); status_t _Identify();
status_t _WalkVolumeRecognitionSequence(); status_t _WalkVolumeRecognitionSequence();
status_t _WalkVolumeDescriptorSequence(off_t start); status_t _WalkVolumeDescriptorSequence(extent_address extent);
private: private:
nspace_id fID; nspace_id fID;