Don't like ads? PRO users don't see any ads ;-)
Guest

partition.cpp

By: a guest on Jun 17th, 2010  |  syntax: C++  |  size: 10.01 KB  |  hits: 123  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #include "stdafx.h"
  2. #include "partition.h"
  3.  
  4. void part_sort(XboxPartitionTable *PartTbl, ULONG *starts, ULONG *ends)
  5. {
  6.         int i;
  7.         ULONG temp;
  8.  
  9.         for (i = 0; i < 14; i++)
  10.         {
  11.                 starts[i] = PartTbl->TableEntries[i].LBAStart;
  12.                 ends[i] = PartTbl->TableEntries[i].LBASize + PartTbl->TableEntries[i].LBAStart;
  13.         }
  14.         //sort
  15.         for (i = 0; i < 13; i++)
  16.         {
  17.                 if (starts[i] > starts[i+1])
  18.                 {
  19.                         temp = starts[i];
  20.                         starts[i] = starts[i+1];
  21.                         starts[i+1] = temp;
  22.                         temp = ends[i];
  23.                         ends[i] = ends[i+1];
  24.                         ends[i+1] = temp;
  25.                         i = -1;
  26.                 }
  27.         }
  28. }
  29.  
  30. int part_get_active_count(XboxPartitionTable *PartTbl)
  31. {
  32.         int i, count = 0;
  33.  
  34.         for (i = 0; i < 14; i++)
  35.         {
  36.                 if (PartTbl->TableEntries[i].Flags & PE_PARTFLAGS_IN_USE)
  37.                         count++;
  38.         }
  39.  
  40.         return count;
  41. }
  42.  
  43. ULONG part_get_first_free_start(XboxPartitionTable *PartTbl)
  44. {
  45.         int i;
  46.         ULONG starts[14], ends[14];
  47.  
  48.         if (!part_get_active_count(PartTbl))
  49.                 return XBOX_SWAPPART1_LBA_START;
  50.  
  51.         part_sort(PartTbl, starts, ends);
  52.  
  53.         for (i = 0; i < 13; i++)
  54.         {
  55.                 if (!starts[i])
  56.                         continue;
  57.  
  58.                 if (ends[i] < starts[i+1])
  59.                         return ends[i];
  60.         }
  61.  
  62.         return ends[13];
  63.  
  64. }
  65.  
  66. ULONG part_get_current_free(XboxPartitionTable *PartTbl, int PartNumber, ULONG TotalSectors)
  67. {
  68.         int i;
  69.         ULONG starts[14], ends[14];
  70.  
  71.         if (!part_get_active_count(PartTbl))
  72.                 return (TotalSectors - 1) - XBOX_SWAPPART1_LBA_START;
  73.  
  74.         part_sort(PartTbl, starts, ends);
  75.  
  76.         for (i = 0; i < 13; i++)
  77.         {
  78.                 if (!starts[i])
  79.                         continue;
  80.  
  81.                 if (starts[i] == PartTbl->TableEntries[PartNumber].LBAStart)
  82.                         return starts[i+1] - ends[i];
  83.         }
  84.  
  85.         return TotalSectors - ends[13];
  86.  
  87. }
  88.  
  89. ULONG part_get_ceil(XboxPartitionTable *PartTbl, int PartNumber, ULONG TotalSectors)
  90. {
  91.         int i, ceil = -1;
  92.  
  93.         for (i = 0; i < 14; i++)
  94.         {
  95.                 if (i == PartNumber)
  96.                         continue;
  97.  
  98.                 if (PartTbl->TableEntries[i].LBAStart > PartTbl->TableEntries[PartNumber].LBAStart)
  99.                 {
  100.                         if (ceil < 0 || PartTbl->TableEntries[i].LBAStart < PartTbl->TableEntries[ceil].LBAStart)
  101.                         {
  102.                                 ceil = i;
  103.                         }
  104.                 }
  105.         }
  106.         if (ceil < 0)
  107.                 return TotalSectors - (PartTbl->TableEntries[PartNumber].LBAStart + PartTbl->TableEntries[PartNumber].LBASize);
  108.         else
  109.                 return PartTbl->TableEntries[ceil].LBAStart - (PartTbl->TableEntries[PartNumber].LBAStart + PartTbl->TableEntries[PartNumber].LBASize);
  110. }
  111.  
  112. void part_add_size(XboxPartitionTable *PartTbl, int PartNumber, ULONG TotalSectors, ULONG addition)
  113. {
  114.         ULONG max = part_get_current_free(PartTbl, PartNumber, TotalSectors);
  115.  
  116.         if (addition > max)
  117.                 addition = max;
  118.         if (PartTbl->TableEntries[PartNumber].LBASize + addition >= LBASIZE_MAX)
  119.                 PartTbl->TableEntries[PartNumber].LBASize = LBASIZE_MAX-1;
  120.         else
  121.                 PartTbl->TableEntries[PartNumber].LBASize += addition;
  122. }
  123.  
  124. void part_sub_size(XboxPartitionTable *PartTbl, int PartNumber, ULONG TotalSectors, ULONG subtraction)
  125. {
  126.         if (PartTbl->TableEntries[PartNumber].LBASize <= subtraction)
  127.                 PartTbl->TableEntries[PartNumber].LBASize = 0;
  128.         else
  129.                 PartTbl->TableEntries[PartNumber].LBASize -= subtraction;
  130. }
  131.  
  132. void part_change_size(XboxPartitionTable *PartTbl, int PartitionNum, int TotalSectors, int TrigValue, int change_start, int Direction, bool fine)
  133. {
  134.         int num_sectors;
  135.  
  136.         void (*change_ops[])(XboxPartitionTable *PartTbl, int PartNumber, ULONG TotalSectors, ULONG addition) =
  137.         { part_add_size, part_sub_size, part_down, part_up };
  138.  
  139.         if (fine)
  140.         {
  141.                 num_sectors = 1;
  142.                 Sleep(250);
  143.         }
  144.         else if (TrigValue < 0x60)
  145.         {
  146.                 num_sectors = 16;
  147.                 Sleep(250);
  148.         }
  149.         else if (TrigValue > 0xf0)
  150.         {
  151.                 num_sectors = SECTORS_PER_CLUSTER * 0x20000;
  152.         }
  153.         else
  154.         {
  155.                 TrigValue >>= 4;
  156.                 num_sectors = SECTORS_PER_CLUSTER * 2 << (TrigValue - 4);
  157.         }
  158.  
  159.         change_ops[change_start * 2 + (Direction < 0)](PartTbl, PartitionNum, TotalSectors, num_sectors);
  160. }
  161.  
  162. bool part_enable(XboxPartitionTable *PartTbl, ULONG TotalSectors, int PartNumber)
  163. {
  164.         ULONG free = part_get_free_sectors(PartTbl, TotalSectors);
  165.  
  166.         if (free < 32)
  167.                 return false;
  168.  
  169.         PartTbl->TableEntries[PartNumber].LBAStart = part_get_first_free_start(PartTbl);
  170.         PartTbl->TableEntries[PartNumber].LBASize = 32;
  171.         PartTbl->TableEntries[PartNumber].Flags |= PE_PARTFLAGS_IN_USE;
  172.  
  173.         return true;
  174. }
  175.  
  176. void part_disable(XboxPartitionTable *PartTbl, int PartNumber)
  177. {
  178.         PartTbl->TableEntries[PartNumber].Flags &= ~PE_PARTFLAGS_IN_USE;
  179.         PartTbl->TableEntries[PartNumber].LBAStart = 0;
  180.         PartTbl->TableEntries[PartNumber].LBASize = 0;
  181. }
  182.  
  183. int part_get_last_available(XboxPartitionTable *PartTbl)
  184. {
  185.         int i, n;
  186.  
  187.         for (i = 0, n = 13; i <= n; i++)
  188.         {
  189.                 if (PartTbl->TableEntries[i].Flags ^ PE_PARTFLAGS_IN_USE)
  190.                 {
  191.                         n = i;
  192.                         break;
  193.                 }
  194.         }
  195.  
  196.         return n;
  197. }
  198.  
  199. void part_up(XboxPartitionTable *PartTbl, int PartNumber, ULONG TotalSectors, ULONG subtraction)
  200. {
  201.         if (PartTbl->TableEntries[PartNumber].LBASize <= subtraction)
  202.                 PartTbl->TableEntries[PartNumber].LBASize = 0;
  203.         else
  204.                 PartTbl->TableEntries[PartNumber].LBASize -= subtraction;
  205.  
  206.         part_sub_size(PartTbl, PartNumber, TotalSectors, subtraction);
  207.  
  208.         PartTbl->TableEntries[PartNumber].LBAStart += subtraction;
  209. }
  210.  
  211. DWORD part_get_current_free_below(XboxPartitionTable *PartTbl, int PartNumber)
  212. {
  213.         int i;
  214.         ULONG starts[14], ends[14];
  215.  
  216.         if (PartTbl->TableEntries[PartNumber].LBAStart == XBOX_SWAPPART1_LBA_START)
  217.                 return 0;
  218.  
  219.         part_sort(PartTbl, starts, ends);
  220.  
  221.         for (i = 14; i >= 1; i--)
  222.         {
  223.                 if (!ends[i])
  224.                         continue;
  225.  
  226.                 if (ends[i] <= PartTbl->TableEntries[PartNumber].LBAStart)
  227.                         return PartTbl->TableEntries[PartNumber].LBAStart - ends[i];
  228.         }
  229.  
  230.         return starts[0] - XBOX_SWAPPART1_LBA_START;
  231. }
  232.  
  233. void part_down(XboxPartitionTable *PartTbl, int PartNumber, ULONG TotalSectors, ULONG addition)
  234. {
  235.         ULONG max = part_get_current_free_below(PartTbl, PartNumber);
  236.  
  237.         if (addition > max)
  238.                 addition = max;
  239.  
  240.         PartTbl->TableEntries[PartNumber].LBAStart -= addition;
  241.         if (PartTbl->TableEntries[PartNumber].LBASize + addition >= LBASIZE_MAX)
  242.                 PartTbl->TableEntries[PartNumber].LBASize = LBASIZE_MAX-1;
  243.         else
  244.                 PartTbl->TableEntries[PartNumber].LBASize += addition;
  245.  
  246. }
  247.  
  248. void part_even(XboxPartitionTable *PartTbl, ULONG TotalSectors)
  249. {
  250.         int i, num_active = 0;
  251.         ULONG free_sectors = part_get_free_sectors(PartTbl, TotalSectors);
  252.  
  253.         for (i = 5; i < 14; i++)
  254.         {
  255.                 if (PartTbl->TableEntries[i].Flags & PE_PARTFLAGS_IN_USE)
  256.                 {
  257.                         num_active++;
  258.                         free_sectors += PartTbl->TableEntries[i].LBASize;
  259.                         PartTbl->TableEntries[i].LBAStart = 0;
  260.                         PartTbl->TableEntries[i].LBASize = 0;
  261.                 }
  262.         }
  263.  
  264.         if (!num_active)
  265.                 return;
  266.  
  267.         free_sectors /= num_active;
  268.  
  269.         for (i = 5; i < 14; i++)
  270.         {
  271.                 if (PartTbl->TableEntries[i].Flags & PE_PARTFLAGS_IN_USE)
  272.                 {
  273.                         PartTbl->TableEntries[i].LBAStart = part_get_first_free_start(PartTbl);
  274.                         PartTbl->TableEntries[i].LBASize = free_sectors - (free_sectors % 16);
  275.                 }
  276.         }
  277. }
  278.  
  279. void part_init_unused(XboxPartitionTable *PartTbl)
  280. {
  281.         int i;
  282.  
  283.         for (i = 5; i < 14; i++)
  284.         {
  285.                 if (PartTbl->TableEntries[i].Flags ^ PE_PARTFLAGS_IN_USE)
  286.                 {
  287.                         PartTbl->TableEntries[i].LBAStart = 0;
  288.                         PartTbl->TableEntries[i].LBASize = 0;
  289.                 }
  290.         }
  291. }
  292.  
  293. ULONG part_get_free_sectors(XboxPartitionTable *PartTbl, ULONG TotalSectors)
  294. {
  295.         int i;
  296.         ULONG Used = 0;
  297.  
  298.         for (i = 0; i < 14; i++)
  299.         {
  300.                 if (PartTbl->TableEntries[i].Flags | PE_PARTFLAGS_IN_USE)
  301.                         Used += PartTbl->TableEntries[i].LBASize;
  302.         }
  303.         if (TotalSectors < Used + XBOX_SWAPPART1_LBA_START)
  304.                 return 0;
  305.         else
  306.                 return TotalSectors - Used - XBOX_SWAPPART1_LBA_START;
  307. }
  308.  
  309. ULONG part_get_used_sectors(XboxPartitionTable *PartTbl)
  310. {
  311.         int i;
  312.         ULONG Used = 0;
  313.  
  314.         for (i = 0; i < 14; i++)
  315.         {
  316.                 if (PartTbl->TableEntries[i].Flags | PE_PARTFLAGS_IN_USE)
  317.                         Used += PartTbl->TableEntries[i].LBASize;
  318.         }
  319.         return Used;
  320. }
  321.  
  322. void part_setup_standard_partitions(XboxPartitionTable *PartTbl, XboxPartitionTable *BackupPartTbl, int TotalSectors, int Type)
  323. {
  324.         memcpy(PartTbl, BackupPartTbl, sizeof(XboxPartitionTable));
  325.  
  326.         PartTbl->TableEntries[5].Flags |= PE_PARTFLAGS_IN_USE;
  327.         PartTbl->TableEntries[5].LBAStart = XBOX_PART6_LBA_START;
  328.         switch (Type)
  329.         {
  330.         case 0:
  331.                 if (TotalSectors & 0xf0000000)
  332.                         PartTbl->TableEntries[5].LBASize = 0xfffffffUL - PartTbl->TableEntries[5].LBAStart;
  333.                 else
  334.                         if (TotalSectors - PartTbl->TableEntries[5].LBAStart >= LBASIZE_MAX)
  335.                                 PartTbl->TableEntries[5].LBASize = LBASIZE_MAX-1;
  336.                         else
  337.                                 PartTbl->TableEntries[5].LBASize=TotalSectors - PartTbl->TableEntries[5].LBAStart;
  338.  
  339.                         PartTbl->TableEntries[6].Flags &= ~PE_PARTFLAGS_IN_USE;
  340.                 break;
  341.         case 1:
  342.                 if (TotalSectors - PartTbl->TableEntries[5].LBAStart >= LBASIZE_MAX)
  343.                                 PartTbl->TableEntries[5].LBASize = LBASIZE_MAX-1;
  344.                         else
  345.                                 PartTbl->TableEntries[5].LBASize=TotalSectors - PartTbl->TableEntries[5].LBAStart;
  346.                 PartTbl->TableEntries[6].Flags &= ~PE_PARTFLAGS_IN_USE;
  347.                 break;
  348.         case 2:
  349.                 if (TotalSectors & 0xf0000000)
  350.                 {
  351.                         PartTbl->TableEntries[5].LBASize = 0xfffffffUL - PartTbl->TableEntries[5].LBAStart;
  352.                         PartTbl->TableEntries[6].LBAStart = 0xfffffffUL;
  353.         //              PartTbl->TableEntries[6].LBASize = TotalSectors - 0xfffffffUL;
  354.                         if (TotalSectors - PartTbl->TableEntries[6].LBAStart >= LBASIZE_MAX)
  355.                                 PartTbl->TableEntries[6].LBASize = LBASIZE_MAX-1;
  356.                         else
  357.                                 PartTbl->TableEntries[6].LBASize=TotalSectors - 0xfffffffUL;
  358.  
  359.                         PartTbl->TableEntries[6].Flags |= PE_PARTFLAGS_IN_USE;
  360.                 }
  361.                 else
  362.                 {
  363. //                      PartTbl->TableEntries[5].LBASize = TotalSectors - PartTbl->TableEntries[5].LBAStart;
  364.                         if (TotalSectors - PartTbl->TableEntries[5].LBAStart >= LBASIZE_MAX)
  365.                                 PartTbl->TableEntries[5].LBASize = LBASIZE_MAX-1;
  366.                         else
  367.                                 PartTbl->TableEntries[5].LBASize=TotalSectors - PartTbl->TableEntries[5].LBAStart;
  368.                         PartTbl->TableEntries[6].Flags &= ~PE_PARTFLAGS_IN_USE;
  369.                 }
  370.                 break;
  371.         case 3:
  372.                 PartTbl->TableEntries[5].LBASize = (ULONG) (TotalSectors - PartTbl->TableEntries[5].LBAStart) / 2;
  373.                 PartTbl->TableEntries[6].LBAStart = PartTbl->TableEntries[5].LBAStart + PartTbl->TableEntries[5].LBASize;
  374.                 PartTbl->TableEntries[6].LBASize = TotalSectors - PartTbl->TableEntries[6].LBAStart;
  375.                 PartTbl->TableEntries[6].Flags |= PE_PARTFLAGS_IN_USE;
  376.                 break;
  377.         default:
  378.                 break;
  379.         }
  380.         for (int i = 7; i < 14; i++)
  381.                 PartTbl->TableEntries[i].Flags &= ~PE_PARTFLAGS_IN_USE;
  382.  
  383.         part_init_unused(PartTbl);
  384.  
  385. }