Add allocation Block Map
This commit is contained in:
parent
94eba936f3
commit
584be84d23
235
disk.cpp
235
disk.cpp
|
@ -4,16 +4,35 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
#define FDIR_OFFSET 128 * 16
|
#define LOGBLOCK_LENGTH 512
|
||||||
|
#define ALLOCBLOCK_LENGTH LOGBLOCK_LENGTH * 2
|
||||||
|
#define VINF_OFFSET LOGBLOCK_LENGTH * 2
|
||||||
|
#define ABMAP_OFFSET VINF_OFFSET + 64
|
||||||
|
#define FDIR_OFFSET LOGBLOCK_LENGTH * 4
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class Disk {
|
class Disk {
|
||||||
|
|
||||||
fstream disk;
|
fstream disk;
|
||||||
|
|
||||||
Disk() {
|
Disk() {
|
||||||
disk.open("copy.dsk", ios_base::binary | ios_base::in);
|
disk.open("copy.dsk", ios_base::binary | ios_base::in);
|
||||||
|
|
||||||
|
disk.seekg(VINF_OFFSET + 16);
|
||||||
|
drBILen = readByte(2);
|
||||||
|
drNmAIBIks = readByte(2);
|
||||||
|
|
||||||
|
allocBlockMap.resize(drNmAIBIks);
|
||||||
|
disk.seekg(ABMAP_OFFSET);
|
||||||
|
int temp, val1, val2;
|
||||||
|
for (int i = 0; i < drNmAIBIks;) {
|
||||||
|
temp = readByte(3);
|
||||||
|
val1 = (temp & 0x00FFF000) >> 12;
|
||||||
|
val2 = (temp & 0x00000FFF);
|
||||||
|
allocBlockMap[i++] = val1;
|
||||||
|
allocBlockMap[i++] = val2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~Disk() {
|
~Disk() {
|
||||||
|
@ -26,51 +45,90 @@ class Disk {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static int read(int size) {
|
int drBILen;
|
||||||
|
int drNmAIBIks;
|
||||||
|
vector<int> allocBlockMap;
|
||||||
|
|
||||||
|
int readByte(int size) {
|
||||||
int res = 0;
|
int res = 0;
|
||||||
for (int i = 0; i < size; ++i) {
|
for (int i = 0; i < size; ++i) {
|
||||||
res = res << 8;
|
res = res << 8;
|
||||||
res |= getDisk().get();
|
res |= disk.get();
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fstream& getDisk() {
|
string readString(int size) {
|
||||||
|
char *temp = new char[size + 1];
|
||||||
|
disk.get(temp, size + 1);
|
||||||
|
string stemp(temp);
|
||||||
|
delete temp;
|
||||||
|
return stemp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static fstream& getDiskStream() {
|
||||||
|
return getDisk().disk;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Disk& getDisk() {
|
||||||
static Disk _this;
|
static Disk _this;
|
||||||
return _this.disk;
|
return _this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int getFContOffset() {
|
||||||
|
return FDIR_OFFSET + LOGBLOCK_LENGTH * getDisk().drBILen;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int findFile(int offset) {
|
static int findFile(int offset) {
|
||||||
Disk::getDisk().seekg(offset);
|
Disk::getDiskStream().seekg(offset);
|
||||||
while (!(Disk::read(1) && 0x80)) {
|
while (!(Disk::getDisk().readByte(1) && 0x80)) {
|
||||||
++offset;
|
++offset;
|
||||||
}
|
}
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void volumeInfo() {
|
static void volumeInfo() {
|
||||||
Disk::getDisk().seekg(64 * 16);
|
int temp;
|
||||||
|
|
||||||
|
Disk::getDiskStream().seekg(64 * 16);
|
||||||
cout << hex;
|
cout << hex;
|
||||||
cout << "--------------------" << endl;
|
cout << "--------------------" << endl;
|
||||||
cout << "always $D2D7 " << Disk::read(2) << endl;
|
cout << "Volume Information" << 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;
|
cout << "--------------------" << endl;
|
||||||
|
cout << "always $D2D7 " << Disk::getDisk().readByte(2) << endl;
|
||||||
|
cout << "date and time of initialization " << Disk::getDisk().readByte(4) << endl;
|
||||||
|
cout << "date and time of last backup " << Disk::getDisk().readByte(4) << endl;
|
||||||
|
cout << "volume attributes " << Disk::getDisk().readByte(2) << endl;
|
||||||
|
cout << "number of files in directory " << Disk::getDisk().readByte(2) << endl;
|
||||||
|
cout << "first block of directory " << Disk::getDisk().readByte(2) << endl;
|
||||||
|
cout << "length of directory in blocks " << Disk::getDisk().readByte(2) << endl;
|
||||||
|
cout << "number of allocation blocks on volume " << Disk::getDisk().readByte(2) << endl;
|
||||||
|
cout << "size of allocation blocks " << Disk::getDisk().readByte(4) << endl;
|
||||||
|
cout << "number of bytes to allocate " << Disk::getDisk().readByte(4) << endl;
|
||||||
|
cout << "first allocation block in block map " << Disk::getDisk().readByte(2) << endl;
|
||||||
|
cout << "next unused file number " << Disk::getDisk().readByte(4) << endl;
|
||||||
|
cout << "number of unused allocation blocks " << Disk::getDisk().readByte(2) << endl;
|
||||||
|
temp = Disk::getDisk().readByte(1);
|
||||||
|
cout << "length of volume name " << temp << endl;
|
||||||
|
cout << "characters of volume name " << Disk::getDisk().readString(temp) << endl;
|
||||||
|
cout << "--------------------" << endl;
|
||||||
|
|
||||||
|
cout << "Allocation Block Map" << endl;
|
||||||
|
cout << "--------------------" << endl;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for (auto &it : getDisk().allocBlockMap) {
|
||||||
|
cout << 2 + i++ << "->" << it << " ";
|
||||||
|
if (it == 1) {
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cout << endl << "--------------------" << endl;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
class File {
|
class File {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -94,26 +152,22 @@ public:
|
||||||
int fEnd;
|
int fEnd;
|
||||||
|
|
||||||
File(int offset) {
|
File(int offset) {
|
||||||
Disk::getDisk().seekg(offset);
|
Disk::getDiskStream().seekg(offset);
|
||||||
flFIags = Disk::read(1);
|
flFIags = Disk::getDisk().readByte(1);
|
||||||
if (flFIags & 0x80) {
|
if (flFIags & 0x80) {
|
||||||
flTyp = Disk::read(1);
|
flTyp = Disk::getDisk().readByte(1);
|
||||||
flUsrWds = Disk::read(16);
|
flUsrWds = Disk::getDisk().readByte(16);
|
||||||
flFINum = Disk::read(4);
|
flFINum = Disk::getDisk().readByte(4);
|
||||||
flStBlk = Disk::read(2);
|
flStBlk = Disk::getDisk().readByte(2);
|
||||||
flLgLen = Disk::read(4);
|
flLgLen = Disk::getDisk().readByte(4);
|
||||||
flPyLen = Disk::read(4);
|
flPyLen = Disk::getDisk().readByte(4);
|
||||||
flRStBlk = Disk::read(2);
|
flRStBlk = Disk::getDisk().readByte(2);
|
||||||
flRLgLen = Disk::read(4);
|
flRLgLen = Disk::getDisk().readByte(4);
|
||||||
flRPyLen = Disk::read(4);
|
flRPyLen = Disk::getDisk().readByte(4);
|
||||||
flCrDat = Disk::read(4);
|
flCrDat = Disk::getDisk().readByte(4);
|
||||||
flMdDat = Disk::read(4);
|
flMdDat = Disk::getDisk().readByte(4);
|
||||||
flNam = Disk::read(1);
|
flNam = Disk::getDisk().readByte(1);
|
||||||
|
flNamS = Disk::getDisk().readString(flNam);
|
||||||
char *temp = new char[flNam + 1];
|
|
||||||
Disk::getDisk().get(temp, flNam + 1);
|
|
||||||
flNamS = string(temp);
|
|
||||||
delete temp;
|
|
||||||
|
|
||||||
fBegin = offset;
|
fBegin = offset;
|
||||||
fEnd = fBegin + 51 + flNam;
|
fEnd = fBegin + 51 + flNam;
|
||||||
|
@ -123,35 +177,54 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void printAll() {
|
string printAll() {
|
||||||
cout << hex;
|
return string("--------------------") +
|
||||||
cout << "--------------------" << endl;
|
"\nflags " + to_string(flFIags) +
|
||||||
cout << "flags " << flFIags << endl;
|
"\nversion number " + to_string(flTyp) +
|
||||||
cout << "version number " << flTyp << endl;
|
"\ninformation used by the Finder " + to_string(flUsrWds) +
|
||||||
cout << "information used by the Finder " << flUsrWds << endl;
|
"\nfile number " + to_string(flFINum) +
|
||||||
cout << "file number " << flFINum << endl;
|
"\nfirst allocation block of data fork " + to_string(flStBlk) +
|
||||||
cout << "first allocation block of data fork " << flStBlk << endl;
|
"\nlogical end-of-file of data fork " + to_string(flLgLen) +
|
||||||
cout << "logical end-of-file of data fork " << flLgLen << endl;
|
"\nphysical end-of-file of data fork " + to_string(flPyLen) +
|
||||||
cout << "physical end-of-file of data fork " << flPyLen << endl;
|
"\nfirst allocation block of resource fork " + to_string(flRStBlk) +
|
||||||
cout << "first allocation block of resource fork " << flRStBlk << endl;
|
"\nlogical end-of-file of resource fork " + to_string(flRLgLen) +
|
||||||
cout << "logical end-of-file of resource fork " << flRLgLen << endl;
|
"\nphysical end-of-file of resource fork " + to_string(flRPyLen) +
|
||||||
cout << "physical end-of-file of resource fork " << flRPyLen << endl;
|
"\ndate and time of creation " + to_string(flCrDat) +
|
||||||
cout << "date and time of creation " << flCrDat << endl;
|
"\ndate and time of last modification " + to_string(flMdDat) +
|
||||||
cout << "date and time of last modification " << flMdDat << endl;
|
"\nlength of file name " + to_string(flNam) +
|
||||||
cout << "length of file name " << flNam << endl;
|
"\n--------------------\n";
|
||||||
cout << "--------------------" << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void printFileName() {
|
string printFileName() {
|
||||||
cout << "File name: " << flNamS << endl;
|
return string("File name: ") + flNamS + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
string getValidFileName() {
|
||||||
|
string temp = flNamS;
|
||||||
|
auto it = temp.find("/");
|
||||||
|
while (it < temp.size()) {
|
||||||
|
temp.replace(it, 1, "_");
|
||||||
|
it = temp.find("/");
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
string saveFile() {
|
||||||
|
string temp = "save file: \n";
|
||||||
|
|
||||||
|
Disk::getDiskStream().seekg(Disk::getFContOffset() + (flRStBlk - 2) * ALLOCBLOCK_LENGTH);
|
||||||
|
for (int i = 0; i < flRLgLen; ++i) {
|
||||||
|
temp += (char)Disk::getDiskStream().get();
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|
||||||
Disk::getDisk().seekg(64 * 16 + 12);
|
Disk::getDiskStream().seekg(VINF_OFFSET + 12);
|
||||||
int fileCount = Disk::read(2);
|
int fileCount = Disk::getDisk().readByte(2);
|
||||||
vector< File > files;
|
vector< File > files;
|
||||||
|
|
||||||
|
|
||||||
|
@ -160,14 +233,38 @@ int main() {
|
||||||
fBegin = Disk::findFile(fBegin);
|
fBegin = Disk::findFile(fBegin);
|
||||||
files.emplace_back(fBegin);
|
files.emplace_back(fBegin);
|
||||||
fBegin = files.back().fEnd;
|
fBegin = files.back().fEnd;
|
||||||
|
|
||||||
cout << "counter: " << i << endl;
|
|
||||||
files.back().printFileName();
|
|
||||||
files.back().printAll();
|
|
||||||
cout << endl << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Disk::volumeInfo();
|
Disk::volumeInfo();
|
||||||
|
|
||||||
|
system("rm -r Files");
|
||||||
|
system("mkdir Files");
|
||||||
|
vector< fstream > fileStreams(fileCount);
|
||||||
|
for (int i = 0; i < fileCount; ++i) {
|
||||||
|
fileStreams[i].open(string("Files/") + to_string(i) + ":" + files[i].getValidFileName() + ".txt", std::fstream::out);
|
||||||
|
if (!fileStreams[i].is_open()) {
|
||||||
|
cout << "error: file not created: " << files[i].flNamS + ".txt" << endl;
|
||||||
|
}
|
||||||
|
fileStreams[i] << files[i].printAll() << endl;
|
||||||
|
fileStreams[i] << files[i].saveFile() << endl;
|
||||||
|
fileStreams[i].close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int q1 = Disk::getFContOffset();
|
||||||
|
int q2 = q1 + (files.back().flRStBlk - 2) * ALLOCBLOCK_LENGTH;
|
||||||
|
int q3 = q2 + files.back().flRPyLen;
|
||||||
|
|
||||||
|
cout << dec;
|
||||||
|
cout << "our first file " << q1/ 16 << endl;
|
||||||
|
cout << "our end file " << q2 / 16 << endl;
|
||||||
|
cout << "our end file end " << q3 / 16 << endl;
|
||||||
|
cout << "MB end file " << (q3 + LOGBLOCK_LENGTH * 3) / 16 << endl;
|
||||||
|
|
||||||
|
Disk::getDiskStream().seekg(0, ios::end);
|
||||||
|
cout << "Disk size " << Disk::getDiskStream().tellg() / 16 << endl;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
Loading…
Reference in New Issue