MacDiskExtractor/disk.cpp

173 lines
5.1 KiB
C++
Raw Normal View History

2016-02-10 11:58:01 +00:00
#include <iostream>
#include <fstream>
#include <string>
2016-03-04 11:40:04 +00:00
#include <vector>
2016-02-10 11:58:01 +00:00
#include <iomanip>
2016-03-04 11:40:04 +00:00
#define FDIR_OFFSET 128 * 16
2016-02-10 11:58:01 +00:00
using namespace std;
class Disk {
2016-02-19 10:02:09 +00:00
fstream disk;
2016-02-10 11:58:01 +00:00
2016-02-19 10:02:09 +00:00
Disk() {
disk.open("copy.dsk", ios_base::binary | ios_base::in);
}
2016-02-10 11:58:01 +00:00
2016-02-19 10:02:09 +00:00
~Disk() {
disk.close();
}
Disk(const Disk&) = delete;
Disk& operator=(const Disk&) = delete;
2016-02-10 11:58:01 +00:00
public:
2016-02-19 10:02:09 +00:00
static int read(int size) {
int res = 0;
for (int i = 0; i < size; ++i) {
res = res << 8;
res |= getDisk().get();
}
return res;
}
static fstream& getDisk() {
static Disk _this;
return _this.disk;
}
2016-03-04 11:40:04 +00:00
static int findFile(int offset) {
Disk::getDisk().seekg(offset);
while (!(Disk::read(1) && 0x80)) {
++offset;
}
return offset;
}
static void volumeInfo() {
Disk::getDisk().seekg(64 * 16);
cout << hex;
cout << "--------------------" << endl;
cout << "always $D2D7 " << Disk::read(2) << endl;
cout << "date and time of initialization " << Disk::read(4) << endl;
cout << "date and time of last backup " << Disk::read(4) << endl;
cout << "volume attributes " << Disk::read(2) << endl;
cout << "number of files in directory " << Disk::read(2) << endl;
cout << "first block of directory " << Disk::read(2) << endl;
cout << "length of directory in blocks " << Disk::read(2) << endl;
cout << "number of allocation blocks on volume " << Disk::read(2) << endl;
cout << "size of allocation blocks " << Disk::read(4) << endl;
cout << "number of bytes to allocate " << Disk::read(4) << endl;
cout << "first allocation block in block map " << Disk::read(2) << endl;
cout << "next unused file number " << Disk::read(4) << endl;
cout << "number of unused allocation blocks " << Disk::read(2) << endl;
cout << "length of volume name " << Disk::read(1) << endl;
cout << "characters of volume namealways $D2D7 " << Disk::read(4) << endl;
cout << "--------------------" << endl;
}
2016-02-19 10:02:09 +00:00
};
class File {
public:
2016-03-04 11:40:04 +00:00
2016-02-19 10:02:09 +00:00
int flFIags;
int flTyp;
int flUsrWds;
int flFINum;
int flStBlk;
int flLgLen;
int flPyLen;
int flRStBlk;
int flRLgLen;
int flRPyLen;
int flCrDat;
int flMdDat;
int flNam;
string flNamS;
int fBegin;
int fEnd;
File(int offset) {
Disk::getDisk().seekg(offset);
flFIags = Disk::read(1);
2016-03-04 11:40:04 +00:00
if (flFIags & 0x80) {
2016-02-19 10:02:09 +00:00
flTyp = Disk::read(1);
flUsrWds = Disk::read(16);
flFINum = Disk::read(4);
flStBlk = Disk::read(2);
flLgLen = Disk::read(4);
flPyLen = Disk::read(4);
flRStBlk = Disk::read(2);
flRLgLen = Disk::read(4);
flRPyLen = Disk::read(4);
flCrDat = Disk::read(4);
flMdDat = Disk::read(4);
flNam = Disk::read(1);
char *temp = new char[flNam + 1];
Disk::getDisk().get(temp, flNam + 1);
flNamS = string(temp);
delete temp;
fBegin = offset;
fEnd = fBegin + 51 + flNam;
if (fEnd % 2) {
++fEnd;
}
}
}
void printAll() {
cout << hex;
2016-03-04 11:40:04 +00:00
cout << "--------------------" << endl;
cout << "flags " << flFIags << endl;
cout << "version number " << flTyp << endl;
cout << "information used by the Finder " << flUsrWds << endl;
cout << "file number " << flFINum << endl;
cout << "first allocation block of data fork " << flStBlk << endl;
cout << "logical end-of-file of data fork " << flLgLen << endl;
cout << "physical end-of-file of data fork " << flPyLen << endl;
cout << "first allocation block of resource fork " << flRStBlk << endl;
cout << "logical end-of-file of resource fork " << flRLgLen << endl;
cout << "physical end-of-file of resource fork " << flRPyLen << endl;
cout << "date and time of creation " << flCrDat << endl;
cout << "date and time of last modification " << flMdDat << endl;
cout << "length of file name " << flNam << endl;
2016-02-19 10:02:09 +00:00
cout << "--------------------" << endl;
}
void printFileName() {
2016-03-04 11:40:04 +00:00
cout << "File name: " << flNamS << endl;
2016-02-19 10:02:09 +00:00
}
2016-02-10 11:58:01 +00:00
};
2016-03-04 11:40:04 +00:00
int main() {
Disk::getDisk().seekg(64 * 16 + 12);
int fileCount = Disk::read(2);
vector< File > files;
2016-02-19 10:02:09 +00:00
2016-03-04 11:40:04 +00:00
int fBegin = FDIR_OFFSET;
for(int i = 0; i < fileCount; ++i) {
fBegin = Disk::findFile(fBegin);
files.emplace_back(fBegin);
fBegin = files.back().fEnd;
cout << "counter: " << i << endl;
files.back().printFileName();
files.back().printAll();
cout << endl << endl;
2016-02-19 10:02:09 +00:00
}
2016-03-04 11:40:04 +00:00
Disk::volumeInfo();
2016-02-19 10:02:09 +00:00
return 1;
2016-02-10 11:58:01 +00:00
}