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:
@@ -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;
|
||||||
|
|
||||||
// Found an avds, so try the main sequence first, then
|
for (int32 i = 0; i < avds_location_count; i++) {
|
||||||
// the reserve sequence if the main one fails.
|
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());
|
||||||
|
|
||||||
// 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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user