Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*Programm By Daniel Galper 1539 */
- #include <iostream>
- #include <cstdio>
- #include <cstdlib>
- #include <algorithm>
- #include <vector>
- #if (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(_CRAYC)
- #define LINUX
- #elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
- #define WINDOWS
- #endif
- using namespace std;
- typedef unsigned int uint;
- typedef unsigned long long ull;
- int fseek64(FILE *f, ull offset, int origin)
- {
- //#if defined(LINUX)
- return fseeko64(f, offset, origin);
- /*#elif defined(WINDOWS)
- return _fseeki64(f, offset, origin);*/
- //#endif
- }
- FILE *file;
- uint BS_jmpBoot;
- char BS_OEMName[8];
- uint BPB_BytsPerSec;
- uint BPB_SecPerClus;
- uint BPB_RsvdSecCnt;
- uint BPB_NumFATs;
- uint BPB_RootEntCnt;
- uint BPB_TotSec16;
- uint BPB_Media;
- uint BPB_FATSz16;
- uint BPB_SecPerTrk;
- uint BPB_NumHeads;
- uint BPB_HiddSec;
- uint BPB_TotSec32;
- uint BPB_FATSz32;
- uint BPB_ExtFlags;
- uint BPB_FSver;
- uint BPB_RootClus;
- uint BPB_FSinfo;
- uint BPB_BkBootSec;
- uint BPB_Reserved;
- uint BS_DrvNum;
- uint BS_Reserved1;
- uint BS_BootSig;
- uint BS_VolID;
- char BS_VolLab[11];
- char BS_FilSysType[8];
- uint RootDirSectors;
- uint FirstDataSector;
- uint FATSz;
- uint FirstSectorofCluster;
- uint TotSec;
- uint DataSec;
- uint CountofClusters;
- uint FATType;
- uint BytsPerClus;
- uint DirCountPerClus;
- uint CurrentFile;
- uint firstRootDirSecNum;
- uint currentROOT;
- string string_for_writing;
- uint masOfByte[32];
- struct directory
- {
- string Name;
- uint FileSize;
- uint cl_numer;
- bool TypeOfObject;
- directory() {
- Name = string_for_writing;
- //Atribute = masOfByte[11];
- if(masOfByte[11] == 0x10)
- TypeOfObject = false;
- else
- TypeOfObject = true;
- if(masOfByte[11] != 0x10)
- FileSize = uint(masOfByte[28] + masOfByte[29] * 256 + masOfByte[30] * 65536 + masOfByte[31] * 16777216);
- cl_numer = masOfByte[26] + masOfByte[27] * 256 + masOfByte[20] * 65536 + masOfByte[21] * 16777216;
- }
- };
- bool operator < (directory A, directory B)
- {
- if(A.TypeOfObject != B.TypeOfObject)
- return !A.TypeOfObject;
- return A.Name < B.Name;
- }
- vector <directory> vector_of_dir;
- void scan_file() {
- fseek64(file, 0, SEEK_SET);
- //по сути не нужно
- //fread(&BS_jmpBoot, 3, 1, file);
- //определяет форматированный ли диск
- //fread(BS_OEMName, 1, 8, file);
- //Количество байтов в секторе
- fseek(file, 11, SEEK_SET);
- fread(&BPB_BytsPerSec, 2, 1, file);
- //Количество секторов в кластере. Значение должно быть числом в степени 2, и больше 0.
- fread(&BPB_SecPerClus, 1, 1, file);
- //Количество секторов в Reserved region (начинается с первого сектора диска). Должно быть больше 0. Для FAT12 и FAT16 дисков, это значение должно быть только 1.
- //Для FAT32 дисков, обычное значение 32.
- fread(&BPB_RsvdSecCnt, 2, 1, file);
- //Количество таблиц FAT на диске
- fread(&BPB_NumFATs, 1, 1, file);
- //Для FAT12 и FAT16 дисков, это поле содержит число 32-байтных элементов корневой директории
- fread(&BPB_RootEntCnt, 2, 1, file);
- //Старое 16-битное поле: общее количество секторов на диске.
- //Это количество включает в себя все четыре региона диска.
- fread(&BPB_TotSec16, 2, 1, file);
- //0xF8 стандартное значение для “жёстких” (не сменных) дисков
- fread(&BPB_Media, 1, 1, file);
- //Для FAT12/FAT16 это количество секторов одной FAT.
- //Для FAT32 это значение равно 0, а количество секторов одной FAT содержится в BPB_FATSz32.
- fread(&BPB_FATSz16, 2, 1, file);
- fread(&BPB_SecPerTrk, 2, 1, file);
- fread(&BPB_NumHeads, 2, 1, file);
- //Количество скрытых секторов, перед началом данного раздела диска.
- fread(&BPB_HiddSec, 4, 1, file);
- //Новое 32-битное поле: общее количество секторов на диске.
- //Это количество включает в себя все четыре региона диска.
- fread(&BPB_TotSec32, 4, 1, file);
- if (BPB_FATSz16 == 0) {
- //Это поле только для операционной системы.
- fread(&BPB_FATSz32, 4, 1, file);
- //
- fread(&BPB_ExtFlags, 2, 1, file);
- //В старшем байте: номер версии. Младший байт: номер промежуточной версии.
- fread(&BPB_FSver, 2, 1, file);
- //Номер первого кластера корневой директории. Обычно 2, но может быть и другим
- fread(&BPB_RootClus, 4, 1, file);
- //Номер сектора со структурой FSINFO в зарезервированной части FAT32. Обычно 1.
- fread(&BPB_FSinfo, 2, 1, file);
- //Если не ноль, то это номер сектора в резервной области диска,
- //где хранится копия boot сектора. Обычно 6. Другие значения не рекомендуются.
- fread(&BPB_BkBootSec, 2, 1, file);
- //Reserved for future expstring_for_writingion.
- //Code that formats FAT32 volumes should always set all of the bytes of this field to
- fread(&BPB_Reserved, 12, 1, file);
- }
- fseek64(file,26,SEEK_SET);
- //Можно было стока всего не считывать :(
- }
- ull FirstByteOfCluster(uint NumberOfCluster) {
- return ((ull(NumberOfCluster - 2)) * ull(BPB_SecPerClus) + ull(FirstDataSector)) * ull(BPB_BytsPerSec);
- }
- void PrintContentOfDirectory() {
- for (int i = 0 ; i < vector_of_dir.size(); i++) {
- if (!vector_of_dir[i].TypeOfObject) {
- printf("%d ",i);
- cout << "directory" << " ";
- cout << vector_of_dir[i].Name << endl;
- }
- else {
- printf("%d ",i);
- cout << "file" << " ";
- cout << vector_of_dir[i].Name << endl;
- }
- }
- }
- void LongName() {
- string Lg = "";
- for (int i = 1; i < 11; i += 2) {
- if (masOfByte[i] == 0x00) {
- break;
- }
- Lg += masOfByte[i];
- }
- for (int i = 14; i < 26; i += 2) {
- if (masOfByte[i] == 0x00 || masOfByte[i] == 0xFF) {
- break;
- }
- Lg += masOfByte[i];
- }
- for (int i = 28; i < 32; i += 2) {
- if (masOfByte[i] == 0x00 || masOfByte[i] == 0xFF) {
- break;
- }
- Lg += masOfByte[i];
- }
- string_for_writing = Lg + string_for_writing;
- }
- long long NextClus() {
- //переменные которая помогает в случаи если это последний кластер
- uint backup;
- if (FATType == 32) {
- fseek64(file, BPB_BytsPerSec * BPB_RsvdSecCnt + 4 * CurrentFile, SEEK_SET);
- fread(&backup, 4, 1, file);
- if(backup >= 0x0ffffff8 )
- return -1;
- }
- else {
- fseek64(file, BPB_BytsPerSec * BPB_RsvdSecCnt + 2 * CurrentFile, SEEK_SET);
- fread(&backup, 2, 1, file);
- if(backup >= 0xfff8)
- return -1;
- }
- return backup;
- }
- void BuildStructureOfFolder() {
- bool flag = true;
- uint kol = 0;
- vector_of_dir.clear();
- while(flag) {
- if (kol == DirCountPerClus) {
- int t;
- t = NextClus();
- if(t == -1)
- return;
- CurrentFile = t;
- fseek64(file,FirstByteOfCluster(CurrentFile), SEEK_SET);
- kol = 0;
- }
- kol++;
- for (int i = 0; i < 32; i++)
- fread(&masOfByte[i], 1, 1, file);
- if(masOfByte[0] == 0x00 ) {
- flag = false;
- continue;
- }
- if(masOfByte[11] == 0x08 )
- continue;
- if(masOfByte[0] == 0xE5)
- continue;
- if(masOfByte[11] == 0x0F) {
- LongName();
- continue;
- }
- if(string_for_writing == ""){
- for (int i = 0; i < 8; i++)
- string_for_writing += masOfByte[i];
- string_for_writing +=".";
- for (int i = 8; i < 11; i++)
- string_for_writing += masOfByte[i];
- }
- if (string_for_writing == ".. . ") string_for_writing = "<-";
- if(string_for_writing != ". . " ) {
- directory obj = directory();
- vector_of_dir.push_back(obj);
- }
- string_for_writing = "";
- }
- sort(vector_of_dir.begin(), vector_of_dir.end());
- }
- void copy_file() {
- int number;
- if(!scanf("%d",&number)) {
- cout << "Poprobuite ehe raz.Vi vveli ne chislo!"<< endl;
- return;
- }
- if (number >= vector_of_dir.size() || number < 0) {
- cout << "Pobrobuite ehe raz.Takogo chisla ne suchestvuet!" << endl;
- return;
- }
- if (!vector_of_dir[number].TypeOfObject) {
- cout << "Pobrobuite ehe raz.Eto ne file!" << endl;
- return;
- }
- FILE* fpw = fopen(vector_of_dir[number].Name.c_str(), "w+b");
- int NumClus = vector_of_dir[number].cl_numer;
- fseek64(file,FirstByteOfCluster(NumClus),SEEK_SET);
- uint byt = vector_of_dir[number].FileSize;
- uint kol = 0;
- while (byt > 0) {
- if (kol == DirCountPerClus) {
- int t;
- t = NextClus();
- if(t == -1)
- return;
- CurrentFile = t;
- fseek64(file,FirstByteOfCluster(CurrentFile), SEEK_SET);
- kol = 0;
- }
- kol++;
- uint temp;
- fread(&temp,1,1,file);
- fwrite(&temp,1,1,fpw);
- byt--;
- }
- fclose(fpw);
- cout << "Zapis Proshla Uspeshna" << endl;
- }
- void ChangeTheFolder() {
- int number;
- if(!scanf("%d",&number)) {
- cout << "Poprobuite ehe raz.Vi vveli ne chislo!"<< endl;
- return;
- }
- if (number >= vector_of_dir.size() || number < 0) {
- cout << "Poprobuite ehe raz.Tako nomera net!" << endl;
- return;
- }
- if (vector_of_dir[number].TypeOfObject) {
- cout << "Poprobuite ehe raz.Eto ne directoria!" << endl;
- return;
- }
- CurrentFile = vector_of_dir[number].cl_numer;
- if (CurrentFile == 0) {
- if (FATType == 32) {
- CurrentFile = BPB_RootClus;
- }
- else
- fseek64(file, (BPB_RsvdSecCnt + (BPB_NumFATs * BPB_FATSz16))* BPB_BytsPerSec, SEEK_SET);
- }
- fseek64(file, FirstByteOfCluster(CurrentFile), SEEK_SET);
- }
- void vvod() {
- cout << "Vvedite Commandu:" << endl;
- string st;
- cin >> st;
- while(st != "exit") {
- if( st != "cd" && st != "cf" && st != "exit") {
- cout << "Poprobuite ehe raz. Takoi komandi ne sushestvuet!";
- }
- if(st == "cd") {
- ChangeTheFolder();
- BuildStructureOfFolder();
- PrintContentOfDirectory();
- cout << "Vvedite Commandu:" << endl;
- }
- if(st == "exit")
- exit(0);
- if(st == "cf") {
- copy_file();
- PrintContentOfDirectory();
- cout << "Vvedite Commandu:" << endl;
- }
- cin >> st;
- }
- }
- int main()
- {
- string s;
- cin >> s;
- if((file = fopen(s.c_str() ,"r+b")) == NULL) {
- printf("Error.FIle nevozmoshno otkrit.");
- return 0;
- }
- else
- printf("YES");
- scan_file();
- BytsPerClus = BPB_BytsPerSec * BPB_SecPerClus;
- DirCountPerClus = BytsPerClus / 32;
- RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec - 1)) / BPB_BytsPerSec;
- //Начало региона данных, первый сектор кластера 2, вычисляется так:
- if (BPB_FATSz16 != 0)
- FATSz = BPB_FATSz16;
- else
- FATSz = BPB_FATSz32;
- FirstDataSector = BPB_RsvdSecCnt + (BPB_NumFATs * FATSz) + RootDirSectors;
- //Имея номер кластера N, номер первого сектора этого кластера
- //(опять же относительно сектора 0 диска) вычисляется так:
- FirstSectorofCluster = ((BPB_RootClus - 2) * BPB_SecPerClus) + FirstDataSector;
- //определяем количество секторов в регионе данных диска
- if (BPB_TotSec16 != 0)
- TotSec = BPB_TotSec16;
- else
- TotSec = BPB_TotSec32;
- DataSec = TotSec - (BPB_RsvdSecCnt + (BPB_NumFATs * FATSz) + RootDirSectors);
- //определяем количество кластеров
- CountofClusters = DataSec / BPB_SecPerClus;
- if (CountofClusters < 65525) {
- FATType = 16;
- }
- else {
- FATType = 32;
- }
- //по формулкам из спецификации считаем где находится корневая директория
- //для каждой из них считаем смещениие
- if (FATType == 32) {
- fseek64(file, FirstByteOfCluster(BPB_RootClus), SEEK_SET);
- CurrentFile = BPB_RootClus;
- }
- else
- fseek64(file, (BPB_RsvdSecCnt + (BPB_NumFATs * BPB_FATSz16))* BPB_BytsPerSec, SEEK_SET);
- BuildStructureOfFolder();
- PrintContentOfDirectory();
- vvod();
- return 0;
- }
Add Comment
Please, Sign In to add comment