From 9f0b5f100415204676c78011bcd87795fba0f1a8 Mon Sep 17 00:00:00 2001 From: ksherlock Date: Mon, 23 Nov 2009 22:36:05 +0000 Subject: [PATCH] git-svn-id: https://profuse.googlecode.com/svn/branches/v2@98 aa027e90-d47c-11dd-86d7-074df07e0730 --- Directory.cpp | 20 +++++++++++++++++--- Directory.h | 27 ++++++++++++++++++++++++--- MappedFile.cpp | 17 +++++++++++++++-- UniversalDiskImage.cpp | 23 ++++++++++++++++++----- UniversalDiskImage.h | 4 ++++ auto.h | 25 ++++++++++++++++++++++--- 6 files changed, 100 insertions(+), 16 deletions(-) diff --git a/Directory.cpp b/Directory.cpp index da017fa..48c2af5 100644 --- a/Directory.cpp +++ b/Directory.cpp @@ -60,6 +60,7 @@ Entry::Entry(unsigned type, const char *name) { _storageType = type; _address = 0; + _index = 0; _volume = NULL; // everything else initialized in setName. @@ -74,6 +75,7 @@ Entry::Entry(const void *bp) uint8_t x; uint16_t xcase = 0; _address = 0; + _index = 0; _volume = NULL; _caseFlag = 0; std::memset(_name, 0, 16); @@ -318,12 +320,24 @@ void VolumeDirectory::write(Buffer *out) #pragma mark SubDirectory -SubDirectory::SubDirectory(unsigned type, const char *name) : - Directory(type, name) +SubDirectory::SubDirectory(FileEntry *e) : + Directory(DirectoryHeader, e->iname()) +{ + _creation = e->creation(); + setAccess(e->access()); + + _parentEntryPointer = e->block(); + _parentEntryNumber = e->index(); + _parentEntryLength = 0x27; + +} + +SubDirectory::SubDirectory(const char *name) : + Directory(DirectoryHeader, name) { _parentPointer = 0; _parentEntryNumber = 0; - _parentEntryLength = 0x27; + _parentEntryLength = 0x27; } SubDirectory::SubDirectory(const void *bp) : diff --git a/Directory.h b/Directory.h index c546d68..bf70cfe 100644 --- a/Directory.h +++ b/Directory.h @@ -61,6 +61,14 @@ public: // returns strlen() on success, 0 on failure. static unsigned ValidName(const char *); + + unsigned block() const { return _address / 512; } + unsigned offset() const { return _address % 512; } + + unsigned address() const { return _address; } + + unsigned index() const { return _index; } + protected: Entry(int storageType, const char *name); Entry(const void *bp); @@ -71,16 +79,26 @@ protected: _storageType = type; } + setAddress(unsigned address) { _address = address; } + + setIndex(unsigned index) + { + _index = index; + } + + Volume *volume() { return _volume; } private: - unsigned _address; // absolute address on disk. + unsigned _address; + unsigned _index; + Volume *_volume; unsigned _storageType; @@ -123,7 +141,7 @@ private: unsigned _version unsigned _minVersion unsigned _access; - usnigned _entryLength; // always 0x27 + unsigned _entryLength; // always 0x27 unsigned _entriesPerBlock; //always 0x0d unsigned _fileCount; @@ -156,7 +174,7 @@ private: class SubDirectory : public Directory { public: - + SubDirectory(FileEntry *); private: unsigned _parentPointer; unsigned _parentEntryNumber; @@ -172,6 +190,9 @@ public: unsigned blocksUsed() const { return _blocksUsed; } unsigned eof() const { return _eof; } + unsigned access() const { return _access; } + + DateTime creation() const { return _creation; } DateTime modification() const { return _modification; } diff --git a/MappedFile.cpp b/MappedFile.cpp index fa3b198..bbc6bd7 100644 --- a/MappedFile.cpp +++ b/MappedFile.cpp @@ -21,8 +21,21 @@ MappedFile::MappedFile(const char *name, bool readOnly) : #undef __METHOD__ #define __METHOD__ "MappedFile::MappedFile" - auto_fd fd(::open(name, readOnly ? O_RDONLY : O_RDWR)); + // if unable to open as read/write, open as read-only. + + auto_fd fd; + + if (!readOnly) + { + fd.reset(::open(name, O_RDWR)); + } + if (fd < 0) + { + fd.reset(::open(name, O_RDONLY)); + readOnly = true; + } + if (fd < 0) { throw Exception(__METHOD__ ": Unable to open file.", errno); @@ -38,7 +51,6 @@ MappedFile::MappedFile(int fd, bool readOnly) : init(fd, readOnly); } -// todo -- verify throw calls destructor. MappedFile::MappedFile(const char *name, size_t size) : _fd(-1), _map(MAP_FAILED) @@ -48,6 +60,7 @@ MappedFile::MappedFile(const char *name, size_t size) : _size = size; _readOnly = false; + auto_fd fd(::open(name, O_CREAT | O_TRUNC | O_RDWR, 0644)); if (fd < 0) diff --git a/UniversalDiskImage.cpp b/UniversalDiskImage.cpp index 688b93f..8b08773 100644 --- a/UniversalDiskImage.cpp +++ b/UniversalDiskImage.cpp @@ -1,18 +1,25 @@ #include "UniversalDiskImage.h" #include "MappedFile.h" #include "Buffer.h" +#inluce "Endian.h" using namespace ProFUSE; +using namespace LittleEndian; UniversalDiskImage::UniversalDiskImage(const char *name, bool readOnly) : DiskImage(name, readOnly) { Validate(file()); + const void *data = file()->fileData(); + + // flags. bit 31 = locked. + _flags = Read32(data, 0x10; } UniversalDiskImage::UniversalDiskImage(MappedFile *file) : DiskImage(file) { + _flags = 0; } UniversalDiskImage *UniversalDiskImage::Create(const char *name, size_t blocks) @@ -75,7 +82,7 @@ void UniversalDiskImage::Validate(MappedFile *file) #undef __METHOD__ #define __METHOD__ "DavexDiskImage::Validate" - uint8_t *data = (uint8_t *)file->fileData(); + const void *data = file->fileData(); size_t size = file->fileSize(); bool ok = false; unsigned blocks = 0; @@ -88,13 +95,13 @@ void UniversalDiskImage::Validate(MappedFile *file) if (std::memcmp(data, "2IMG", 4)) break; // only prodos supported, for now... - if (file->read32(0x0c, LittleEndian) != 1) break; + if (Read32(data, 0x0c) != 1) break; - offset = file->read32(0x20, LittleEndian); - blocks = file->read32(0x14, LittleEndian); + offset = Read32(data, 0x20); + blocks = Read32(data, 0x14); // file size == blocks * 512 - if (file->read32(0x1c, LittleEndian) != blocks * 512) break; + if (Read32(data, 0x1c) != blocks * 512) break; if (offset + blocks * 512 > size) break; @@ -107,4 +114,10 @@ void UniversalDiskImage::Validate(MappedFile *file) file->reset(); file->setOffset(offset); file->setBlocks(blocks); +} + + +bool UniversalDiskImage::readOnly() +{ + return (_flags & 0x8000000) || DiskImage::readOnly(); } \ No newline at end of file diff --git a/UniversalDiskImage.h b/UniversalDiskImage.h index cfcd887..e26e18e 100644 --- a/UniversalDiskImage.h +++ b/UniversalDiskImage.h @@ -13,9 +13,13 @@ public: static UniversalDiskImage *Create(const char *name, size_t blocks); static UniversalDiskImage *Open(MappedFile *); + virtual bool readOnly(); + private: UniversalDiskImage(MappedFile *); static void Validate(MappedFile *); + + uint32_t flags; }; } diff --git a/auto.h b/auto.h index 73f6768..3e3d16c 100644 --- a/auto.h +++ b/auto.h @@ -26,18 +26,37 @@ private: class auto_fd { public: - auto_fd(int fd) : _fd(fd) { } + auto_fd(int fd = -1) : _fd(fd) { } - ~auto_fd() - { if (_fd != -1) ::close(_fd); } + ~auto_fd() { close(); } int release() { int tmp = _fd; _fd = -1; return tmp; } int get() const { return _fd; } operator int() const { return _fd; } + + void reset(int fd) + { + if (fd != _fd) + { + close(); + _fd = fd; + } + } private: + auto_fd& operator=(const auto_fd&); + + void close() + { + if (_fd >= 0) + { + ::close(_fd); + fd = -1; + } + } + int _fd; }; #endif