diff --git a/Directory.cpp b/Directory.cpp index 04ee1ed..786e16c 100644 --- a/Directory.cpp +++ b/Directory.cpp @@ -5,7 +5,7 @@ #include "Entry.h" #include "Buffer.h" #include "Endian.h" - +#include "BlockDevice.h" #include "Exception.h" @@ -69,3 +69,39 @@ void Directory::setAccess(unsigned access) // todo -- mark dirty? update block? } + + +void Directory::loadChildren(BlockDevice *device, unsigned block) +{ + uint8_t buffer[512]; + unsigned next; + bool first = true; + unsigned offset; + + // set of already-visited blocks? + + while(block) + { + device->read(block, buffer); + + next = Read16(buffer, 2); + + _entryBlocks.push_back(block); + + offset = 4; + if (!first) + { + // storage type 0 is deleted, don't load... + + } + + + + first = false; + block = next; + } + + +} + + diff --git a/Entry.h b/Entry.h index 3ff3d39..1e2ca82 100644 --- a/Entry.h +++ b/Entry.h @@ -131,6 +131,8 @@ protected: std::vector _children; std::vector _entryBlocks; + + void loadChildren(BlockDevice *, unsigned block); private: @@ -149,7 +151,10 @@ private: class VolumeDirectory: public Directory { public: - VolumeDirectory(const char *name, BlockDevice *device); + static VolumeDirectory *Create(const char *name, BlockDevice *device); + static VolumeDirectory *Create(BlockDevice *); + + virtual ~VolumeDirectory(); unsigned bitmapPointer() const { return _bitmapPointer; } @@ -162,7 +167,12 @@ public: virtual void write(Buffer *); BlockDevice *device() const { return _device; } + private: + + VolumeDirectory(const char *name, BlockDevice *device); + VolumeDirectory(BlockDevice *device, const void *bp); + Bitmap *_bitmap; BlockDevice *_device; diff --git a/VolumeDirectory.cpp b/VolumeDirectory.cpp index 1f81c14..dd67bdb 100644 --- a/VolumeDirectory.cpp +++ b/VolumeDirectory.cpp @@ -15,6 +15,25 @@ using namespace LittleEndian; #pragma mark VolumeDirectory + +VolumeDirectory *VolumeDirectory::Create(const char *name, BlockDevice *device) +{ + return new VolumeDirectory(name, device); +} + +VolumeDirectory *VolumeDirectory::Create(BlockDevice *device) +{ + uint8_t block[512]; + // always block 2. + + device->read(2, block); + + return new VolumeDirectory(device, block); +} + + + + VolumeDirectory::VolumeDirectory(const char *name, BlockDevice *device) : Directory(VolumeHeader, name) { @@ -75,6 +94,46 @@ VolumeDirectory::VolumeDirectory(const char *name, BlockDevice *device) : _bitmap = bitmap.release(); } + +VolumeDirectory::VolumeDirectory(BlockDevice *device, const void *bp) : + Directory(bp), + _modification(0,0) +{ +#undef __METHOD__ +#define __METHOD__ "VolumeDirectory::VolumeDirectory" + + // + 4 to skip over the block poitners. + std::auto_ptr bitmap; + const void *vp = 4 + (const uint8_t *)bp; + + + if (storageType() != VolumeHeader) + throw ProDOSException(__METHOD__ ": Invalid storage type.", 0x4b); + + + + _modification = DateTime(Read16(vp, 0x12), Read16(vp, 0x14)); + + _bitmapPointer = Read16(vp, 0x23); + + _totalBlocks = Read16(vp, 0x25); + + + // verify totalBlocks <= device->blocks() ? + + if (_bitmapPointer >= _totalBlocks) + throw ProDOSException(__METHOD__ ": Invalid bitmap pointer.", 0x5a); + + + // bitmap pointer... + bitmap.reset(new Bitmap(device, _bitmapPointer, _totalBlocks)); + + + // parse the directory header.... + + _bitmap = bitmap.release(); +} + VolumeDirectory::~VolumeDirectory() { if (_device) diff --git a/newfs_prodos.cpp b/newfs_prodos.cpp index a8dd84d..756f607 100644 --- a/newfs_prodos.cpp +++ b/newfs_prodos.cpp @@ -275,7 +275,7 @@ int main(int argc, char **argv) // VolumeDirectory assumes ownership of device, // but doesn't release it on exception. - volume.reset(new VolumeDirectory(volumeName.c_str(), device.get())); + volume.reset(VolumeDirectory::Create(volumeName.c_str(), device.get())); device.release(); }