Guest User

Untitled

a guest
May 25th, 2018
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.42 KB | None | 0 0
  1. /*Programm By Daniel Galper 1539 */
  2. #include <iostream>
  3. #include <cstdio>
  4. #include <cstdlib>
  5. #include <algorithm>
  6. #include <vector>
  7. #if (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(_CRAYC)
  8. #define LINUX
  9. #elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
  10. #define WINDOWS
  11. #endif
  12. using namespace std;
  13. typedef unsigned int uint;
  14. typedef unsigned long long ull;
  15.  
  16.  
  17. int fseek64(FILE *f, ull offset, int origin)
  18. {
  19.     //#if defined(LINUX)
  20.       return fseeko64(f, offset, origin);
  21.     /*#elif defined(WINDOWS)
  22.       return _fseeki64(f, offset, origin);*/
  23.     //#endif
  24. }
  25.  
  26. FILE *file;
  27. uint BS_jmpBoot;
  28. char BS_OEMName[8];
  29. uint BPB_BytsPerSec;
  30. uint BPB_SecPerClus;
  31. uint BPB_RsvdSecCnt;
  32. uint BPB_NumFATs;
  33. uint BPB_RootEntCnt;
  34. uint BPB_TotSec16;
  35. uint BPB_Media;
  36. uint BPB_FATSz16;
  37. uint BPB_SecPerTrk;
  38. uint BPB_NumHeads;
  39. uint BPB_HiddSec;
  40. uint BPB_TotSec32;
  41. uint BPB_FATSz32;
  42. uint BPB_ExtFlags;
  43. uint BPB_FSver;
  44. uint BPB_RootClus;
  45. uint BPB_FSinfo;
  46. uint BPB_BkBootSec;
  47. uint BPB_Reserved;
  48. uint BS_DrvNum;
  49. uint BS_Reserved1;
  50. uint BS_BootSig;
  51. uint BS_VolID;
  52. char BS_VolLab[11];
  53. char BS_FilSysType[8];
  54. uint RootDirSectors;
  55. uint FirstDataSector;
  56. uint FATSz;
  57. uint FirstSectorofCluster;
  58. uint TotSec;
  59. uint DataSec;
  60. uint CountofClusters;
  61. uint FATType;
  62. uint BytsPerClus;
  63. uint DirCountPerClus;
  64. uint CurrentFile;
  65. uint firstRootDirSecNum;
  66. uint currentROOT;
  67. string string_for_writing;
  68. uint masOfByte[32];
  69. struct directory
  70. {
  71.     string Name;
  72.     uint FileSize;
  73.     uint cl_numer;
  74.     bool TypeOfObject;
  75.      directory() {
  76.         Name = string_for_writing;
  77.         //Atribute = masOfByte[11];
  78.         if(masOfByte[11] == 0x10)
  79.             TypeOfObject = false;
  80.         else
  81.             TypeOfObject = true;
  82.         if(masOfByte[11] != 0x10)
  83.         FileSize = uint(masOfByte[28] + masOfByte[29] * 256 + masOfByte[30] * 65536 + masOfByte[31] * 16777216);
  84.         cl_numer = masOfByte[26] + masOfByte[27] * 256 + masOfByte[20] * 65536 + masOfByte[21] * 16777216;
  85.     }
  86.  
  87.  
  88. };
  89. bool operator < (directory A, directory B)
  90. {
  91.     if(A.TypeOfObject != B.TypeOfObject)
  92.         return !A.TypeOfObject;
  93.     return A.Name < B.Name;
  94. }
  95. vector <directory> vector_of_dir;
  96. void scan_file() {
  97.     fseek64(file, 0, SEEK_SET);
  98.  
  99.     //по сути не нужно
  100.     //fread(&BS_jmpBoot, 3, 1, file);
  101.     //определяет форматированный ли диск
  102.     //fread(BS_OEMName, 1, 8, file);
  103.     //Количество байтов в секторе
  104.     fseek(file, 11, SEEK_SET);
  105.     fread(&BPB_BytsPerSec, 2, 1, file);
  106.  
  107.     //Количество секторов в кластере. Значение должно быть числом в степени 2, и больше 0.
  108.     fread(&BPB_SecPerClus, 1, 1, file);
  109.  
  110.     //Количество секторов в Reserved region (начинается с первого сектора диска). Должно быть больше 0. Для FAT12 и FAT16 дисков, это значение должно быть только 1.
  111.     //Для FAT32 дисков, обычное значение 32.
  112.     fread(&BPB_RsvdSecCnt, 2, 1, file);
  113.  
  114.     //Количество таблиц FAT на диске
  115.     fread(&BPB_NumFATs, 1, 1, file);
  116.  
  117.     //Для FAT12 и FAT16 дисков, это поле содержит число 32-байтных элементов корневой директории
  118.     fread(&BPB_RootEntCnt, 2, 1, file);
  119.  
  120.     //Старое 16-битное поле: общее количество секторов на диске.
  121.     //Это количество включает в себя все четыре региона диска.
  122.     fread(&BPB_TotSec16, 2, 1, file);
  123.  
  124.     //0xF8 стандартное значение для “жёстких” (не сменных) дисков
  125.     fread(&BPB_Media, 1, 1, file);
  126.  
  127.     //Для FAT12/FAT16 это количество секторов одной FAT.
  128.     //Для FAT32 это значение равно 0, а количество секторов одной FAT содержится в BPB_FATSz32.
  129.     fread(&BPB_FATSz16, 2, 1, file);
  130.  
  131.     fread(&BPB_SecPerTrk, 2, 1, file);
  132.     fread(&BPB_NumHeads, 2, 1, file);
  133.  
  134.     //Количество скрытых секторов, перед началом данного раздела диска.
  135.     fread(&BPB_HiddSec, 4, 1, file);
  136.  
  137.     //Новое 32-битное поле: общее количество секторов на диске.
  138.     //Это количество включает в себя все четыре региона диска.
  139.     fread(&BPB_TotSec32, 4, 1, file);
  140.  
  141.     if (BPB_FATSz16 == 0) {
  142.         //Это поле только для операционной системы.
  143.         fread(&BPB_FATSz32, 4, 1, file);
  144.  
  145.         //
  146.         fread(&BPB_ExtFlags, 2, 1, file);
  147.  
  148.         //В старшем байте: номер версии. Младший байт: номер промежуточной версии.
  149.         fread(&BPB_FSver, 2, 1, file);
  150.  
  151.         //Номер первого кластера корневой директории. Обычно 2, но может быть и другим
  152.         fread(&BPB_RootClus, 4, 1, file);
  153.  
  154.         //Номер сектора со структурой FSINFO в зарезервированной части FAT32. Обычно 1.
  155.         fread(&BPB_FSinfo, 2, 1, file);
  156.  
  157.         //Если не ноль, то это номер сектора в резервной области диска,
  158.         //где хранится копия boot сектора. Обычно 6. Другие значения не рекомендуются.
  159.         fread(&BPB_BkBootSec, 2, 1, file);
  160.  
  161.         //Reserved for future expstring_for_writingion.
  162.         //Code that formats FAT32 volumes should always set all of the bytes of this field to
  163.         fread(&BPB_Reserved, 12, 1, file);
  164.  
  165.     }
  166.     fseek64(file,26,SEEK_SET);
  167.     //Можно было стока всего не считывать :(
  168. }
  169. ull FirstByteOfCluster(uint NumberOfCluster) {
  170.     return ((ull(NumberOfCluster - 2)) *  ull(BPB_SecPerClus) + ull(FirstDataSector)) * ull(BPB_BytsPerSec);
  171. }
  172.  
  173. void PrintContentOfDirectory() {
  174.     for (int i = 0 ; i < vector_of_dir.size(); i++) {
  175.         if (!vector_of_dir[i].TypeOfObject) {
  176.             printf("%d  ",i);
  177.             cout << "directory" << "  ";
  178.             cout << vector_of_dir[i].Name <<  endl;
  179.         }
  180.         else {
  181.             printf("%d  ",i);
  182.             cout << "file" << "  ";
  183.             cout << vector_of_dir[i].Name << endl;
  184.         }
  185.     }
  186.  
  187. }
  188. void LongName() {
  189.     string Lg = "";
  190.     for (int i = 1; i < 11; i += 2) {
  191.         if (masOfByte[i] == 0x00) {
  192.             break;
  193.         }
  194.         Lg += masOfByte[i];
  195.     }
  196.     for (int i = 14; i < 26; i += 2) {
  197.         if (masOfByte[i] == 0x00 || masOfByte[i] == 0xFF) {
  198.             break;
  199.         }
  200.         Lg += masOfByte[i];
  201.     }
  202.     for (int i = 28; i < 32; i += 2) {
  203.         if (masOfByte[i] == 0x00 || masOfByte[i] == 0xFF) {
  204.             break;
  205.         }
  206.         Lg += masOfByte[i];
  207.     }
  208.     string_for_writing = Lg + string_for_writing;
  209. }
  210. long long NextClus() {
  211.     //переменные которая помогает в случаи если это последний кластер
  212.     uint backup;
  213.     if (FATType == 32) {
  214.         fseek64(file, BPB_BytsPerSec * BPB_RsvdSecCnt + 4 * CurrentFile, SEEK_SET);
  215.         fread(&backup, 4, 1, file);
  216.         if(backup >= 0x0ffffff8 )
  217.             return -1;
  218.  
  219.     }
  220.     else {
  221.         fseek64(file, BPB_BytsPerSec * BPB_RsvdSecCnt + 2 * CurrentFile, SEEK_SET);
  222.         fread(&backup, 2, 1, file);
  223.         if(backup >= 0xfff8)
  224.             return -1;
  225.     }
  226.     return  backup;
  227. }
  228.  
  229.  
  230. void BuildStructureOfFolder() {
  231.     bool flag = true;
  232.     uint kol = 0;
  233.     vector_of_dir.clear();
  234.     while(flag) {
  235.         if (kol == DirCountPerClus) {
  236.             int t;
  237.             t = NextClus();
  238.             if(t == -1)
  239.                 return;
  240.             CurrentFile = t;
  241.             fseek64(file,FirstByteOfCluster(CurrentFile), SEEK_SET);
  242.             kol = 0;
  243.         }
  244.         kol++;
  245.         for (int i = 0; i < 32; i++)
  246.             fread(&masOfByte[i], 1, 1, file);
  247.  
  248.  
  249.         if(masOfByte[0] == 0x00 ) {
  250.             flag = false;
  251.              continue;
  252.         }
  253.         if(masOfByte[11] == 0x08 )
  254.             continue;
  255.         if(masOfByte[0] == 0xE5)
  256.             continue;
  257.         if(masOfByte[11] == 0x0F) {
  258.             LongName();
  259.             continue;
  260.         }
  261.         if(string_for_writing == ""){
  262.             for (int i = 0; i < 8; i++)
  263.                 string_for_writing += masOfByte[i];
  264.             string_for_writing +=".";
  265.             for (int i = 8; i < 11; i++)
  266.                 string_for_writing += masOfByte[i];
  267.         }
  268.         if (string_for_writing == "..      .   ") string_for_writing = "<-";
  269.         if(string_for_writing != ".       .   " )   {
  270.             directory obj = directory();
  271.             vector_of_dir.push_back(obj);
  272.         }
  273.         string_for_writing = "";
  274.     }
  275.     sort(vector_of_dir.begin(), vector_of_dir.end());
  276. }
  277. void copy_file() {
  278.     int number;
  279.     if(!scanf("%d",&number)) {
  280.           cout << "Poprobuite ehe raz.Vi vveli ne chislo!"<< endl;
  281.           return;
  282.     }
  283.     if (number >= vector_of_dir.size() || number < 0) {
  284.             cout << "Pobrobuite ehe raz.Takogo chisla ne suchestvuet!" << endl;
  285.             return;
  286.     }
  287.     if (!vector_of_dir[number].TypeOfObject) {
  288.         cout << "Pobrobuite ehe raz.Eto ne file!" << endl;
  289.         return;
  290.     }
  291.     FILE* fpw = fopen(vector_of_dir[number].Name.c_str(), "w+b");
  292.     int NumClus = vector_of_dir[number].cl_numer;
  293.     fseek64(file,FirstByteOfCluster(NumClus),SEEK_SET);
  294.     uint byt = vector_of_dir[number].FileSize;
  295.     uint kol = 0;
  296.     while (byt > 0) {
  297.         if (kol == DirCountPerClus) {
  298.             int t;
  299.             t = NextClus();
  300.             if(t == -1)
  301.                 return;
  302.             CurrentFile = t;
  303.             fseek64(file,FirstByteOfCluster(CurrentFile), SEEK_SET);
  304.             kol = 0;
  305.         }
  306.         kol++;
  307.         uint temp;
  308.         fread(&temp,1,1,file);
  309.         fwrite(&temp,1,1,fpw);
  310.         byt--;
  311.     }
  312.     fclose(fpw);
  313.     cout << "Zapis Proshla Uspeshna" << endl;
  314. }
  315. void ChangeTheFolder() {
  316.     int number;
  317.  
  318.        if(!scanf("%d",&number)) {
  319.           cout << "Poprobuite ehe raz.Vi vveli ne chislo!"<< endl;
  320.           return;
  321.        }
  322.  
  323.         if (number >= vector_of_dir.size() || number < 0) {
  324.             cout << "Poprobuite ehe raz.Tako nomera net!" << endl;
  325.             return;
  326.         }
  327.         if (vector_of_dir[number].TypeOfObject) {
  328.             cout << "Poprobuite ehe raz.Eto ne directoria!" << endl;
  329.             return;
  330.         }
  331.         CurrentFile = vector_of_dir[number].cl_numer;
  332.         if (CurrentFile == 0) {
  333.             if (FATType == 32) {
  334.                 CurrentFile = BPB_RootClus;
  335.             }
  336.             else
  337.                fseek64(file, (BPB_RsvdSecCnt + (BPB_NumFATs * BPB_FATSz16))* BPB_BytsPerSec, SEEK_SET);
  338.  
  339.  
  340.         }
  341.         fseek64(file, FirstByteOfCluster(CurrentFile), SEEK_SET);
  342. }
  343. void vvod() {
  344.     cout << "Vvedite Commandu:" << endl;
  345.     string st;
  346.     cin >> st;
  347.     while(st != "exit") {
  348.         if( st != "cd" && st != "cf" && st != "exit") {
  349.             cout << "Poprobuite ehe raz. Takoi komandi ne sushestvuet!";
  350.         }
  351.  
  352.         if(st == "cd") {
  353.             ChangeTheFolder();
  354.             BuildStructureOfFolder();
  355.             PrintContentOfDirectory();
  356.             cout << "Vvedite Commandu:" << endl;
  357.         }
  358.         if(st == "exit")
  359.             exit(0);
  360.         if(st == "cf") {
  361.             copy_file();
  362.             PrintContentOfDirectory();
  363.             cout << "Vvedite Commandu:" << endl;
  364.         }
  365.  
  366.         cin >> st;
  367.     }
  368.  
  369. }
  370. int main()
  371. {
  372.     string s;
  373.     cin >> s;
  374.  
  375.     if((file = fopen(s.c_str() ,"r+b")) == NULL) {
  376.         printf("Error.FIle nevozmoshno otkrit.");
  377.         return 0;
  378.     }
  379.     else
  380.         printf("YES");
  381.     scan_file();
  382.     BytsPerClus = BPB_BytsPerSec * BPB_SecPerClus;
  383.     DirCountPerClus = BytsPerClus / 32;
  384.  
  385.     RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec - 1)) / BPB_BytsPerSec;
  386.  
  387.     //Начало региона данных, первый сектор кластера 2, вычисляется так:
  388.     if (BPB_FATSz16 != 0)
  389.         FATSz = BPB_FATSz16;
  390.     else
  391.         FATSz = BPB_FATSz32;
  392.  
  393.     FirstDataSector = BPB_RsvdSecCnt + (BPB_NumFATs * FATSz) + RootDirSectors;
  394.  
  395.     //Имея номер кластера N, номер первого сектора этого кластера
  396.     //(опять же относительно сектора 0 диска) вычисляется так:
  397.     FirstSectorofCluster = ((BPB_RootClus - 2) * BPB_SecPerClus) + FirstDataSector;
  398.  
  399.  
  400.     //определяем количество секторов в регионе данных диска
  401.     if (BPB_TotSec16 != 0)
  402.         TotSec = BPB_TotSec16;
  403.     else
  404.         TotSec = BPB_TotSec32;
  405.  
  406.     DataSec = TotSec - (BPB_RsvdSecCnt + (BPB_NumFATs * FATSz) + RootDirSectors);
  407.  
  408.     //определяем количество кластеров
  409.     CountofClusters = DataSec / BPB_SecPerClus;
  410.  
  411.     if (CountofClusters < 65525) {
  412.         FATType = 16;
  413.     }
  414.     else {
  415.         FATType = 32;
  416.     }
  417.     //по формулкам  из спецификации считаем где находится корневая директория
  418.     //для каждой из них считаем смещениие
  419.     if (FATType == 32) {
  420.         fseek64(file, FirstByteOfCluster(BPB_RootClus), SEEK_SET);
  421.         CurrentFile = BPB_RootClus;
  422.     }
  423.     else
  424.         fseek64(file, (BPB_RsvdSecCnt + (BPB_NumFATs * BPB_FATSz16))* BPB_BytsPerSec, SEEK_SET);
  425.  
  426.     BuildStructureOfFolder();
  427.     PrintContentOfDirectory();
  428.     vvod();
  429.     return 0;
  430. }
Add Comment
Please, Sign In to add comment