⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtfbs.c

📁 MTK平台绝密核心代码之文件驱动,希望对大家有用
💻 C
📖 第 1 页 / 共 2 页
字号:
   Sectors          = NewStartSector - P->RelativeSector;

   if (Sectors > P->Sectors)
      return RTF_INVALID_FILE_SYSTEM;

   if ((Sectors + SectorsPerCylinder) > P->Sectors)
      return RTF_INVALID_FILE_SYSTEM;

   if (NewStartCylinder >= 1024) // we can't put such values in the partition table
      NewStartCylinder = 0;

   // setup new partition

   P[1].StartHead   = 0;
   P[1].StartSector = 1 | ((NewStartCylinder & 0x300) >> 2);
   P[1].StartTrack  = NewStartCylinder;

   // move EndHead/Sector/Track from P to P+1

   P[1].EndHead     = P[0].EndHead;
   P[1].EndSector   = P[0].EndSector;
   P[1].EndTrack    = P[0].EndTrack;

   P[1].RelativeSector = NewStartSector;
   P[1].Sectors     = P[0].RelativeSector + P[0].Sectors - NewStartSector;

   // adjust P[0]'s EndHead/Sector/Track, Sectors

   OldEndCylinder   = (NewStartSector-2) / SectorsPerCylinder;
   if (OldEndCylinder >= 1024)
      OldEndCylinder = 0;

   P[0].EndSector   = (P[0].EndSector & 63) | ((OldEndCylinder & 0x300) >> 2);
   P[0].EndTrack    = OldEndCylinder;
 
   P[0].Sectors     = Sectors;

   // Set OSTypes

   P[0].OSType = DefaultOSType(P[0].Sectors, (P[0].RelativeSector + P[0].Sectors - 1) / SectorsPerCylinder);
   P[1].OSType = DefaultOSType(P[1].Sectors, (P[1].RelativeSector + P[1].Sectors - 1) / SectorsPerCylinder);
   
   return P - MBR->PTable + 1; // index of new partition
}

/* 
  Partition Size    ClusterS  ClusterC
  ------------------------------------
  FAT-12   0-  1M    0.5k      0-  2k
          1M-  4M      1k     1k-  4k
          4M- 16M      2k     2k-
          8M- 16M      4k     2k-  4k

  FAT-16  2M-  8M    0.5k     4k- 16k
          8M- 32M      1k     8k- 32k
         32M-128M      2k    16k- 64k
        128M-512M      4k    32k-
        256M-512M      8k    32k- 64k

  FAT-32
        128M-256M      2k    64k-128k
        256M-  1G      4k    64k-256k
          1G-  4G      8k   128k-512k
          4G- 16G     16k   256k-  1M
         16G- 64G     32k   512k-  2M
         64G-256G     32k     2M-  8M
        256G-  1T     32k     8M- 32M
          1T-  2T     32k    32M- 64M

Default configurations do not allow cluster sizes beyond 4k for FAT-12
and 8k for FAT-16
*/

/*-----------------------------------*/
static DWORD GetDefaultClusterSize(DWORD Sectors, int FatType)
{
   DWORD Result = 1;
   DWORD Size;

   switch (FatType)
   {
      case 12:
         Size  = 1 M;
         break;
      case 16:
         Size  = 8 M;
         break;
      case 32:
         Result = 4;
         Size  = 256 M;
         break;
      /* Remove RVCT warning, Karen Hsu, 2004/11/02, ADD START */
      default:
         Size = 1 M;
         break;
      /* Remove RVCT warning, Karen Hsu, 2004/11/02, ADD END */
   }

   while (Size < Sectors)
   {
      Result <<= 1;
      Size <<= 2;
   }

   // the default must be Microsoft compatible, even though RTFiles supports more

   return (Result > 64) ? 64 : Result;
}

/*-----------------------------------*/
int RTFAPI RTFCreateBootSector(void * BootSector,
                               const RTFPartitionRecord * Partition,
                               BYTE MediaDescriptor,
                               UINT MinSectorsPerCluster,
                               DWORD Flags)
{
   RTFBootRecord * BR = BootSector;
   int FatType;
   DWORD SectorsPerCluster;
   DWORD RootDirSectors, DataSectors, Clusters, NetSectors;

   if (!QPowerTwo(MinSectorsPerCluster))
      return RTF_PARAM_ERROR;

   #define FMT_FAT_ALL_FLAGS  (RTF_FMT_FAT_12 | RTF_FMT_FAT_16 | RTF_FMT_FAT_32)
   switch (Flags & FMT_FAT_ALL_FLAGS)
   {
      case RTF_FMT_FAT_12:
      case (RTF_FMT_FAT_12 | RTF_FMT_FAT_16):
         FatType = 12;
         break;
      case RTF_FMT_FAT_16:
      case (RTF_FMT_FAT_16 | RTF_FMT_FAT_32):
         FatType = 16;
         break;
      case RTF_FMT_FAT_32:
         if (Flags & RTF_FMT_NO_FAT_32)
            return RTF_PARAM_ERROR;
         FatType = 32;
         break;
      default:
         if (Partition->Sectors < (16 M))
            FatType = 12;
         else if (Partition->Sectors < (512 M))
            FatType = 16;
         else
            if (Flags & RTF_FMT_NO_FAT_32)
               FatType = 16;
            else
               FatType = 32;
   }

NewFATType:

   if ((Flags & RTF_FMT_NO_FAT_32) && (FatType == 32))
       return RTF_INVALID_FILE_SYSTEM; // this can only happen due to a retry

   memset((void*)BR, 0, SECTOR_SIZE);
   BR->NearJump[0] = 0xEB;
   BR->NearJump[1] = 0x58;
   BR->NearJump[2] = 0x90;
   memcpy((void*)&BR->BootCode, (void*)BootCode, sizeof(BootCode));
   memcpy((void*)BR->BP.OEMName, "FileSys ", 8);
   BR->Signature          = 0xAA55;
   BR->BP.BytesPerSector  = SECTOR_SIZE;
   BR->BP.ReservedSectors = (FatType == 32) ? 32 : 1;
   BR->BP.TotalSectors    = Partition->Sectors;
   BR->BP.SectorsOnDisk   = (Partition->Sectors >= 0x10000l) ? 0 : Partition->Sectors;
   BR->BP.NumberOfHiddenSectors = Partition->RelativeSector;
   BR->BP.NumberOfFATs    = (Flags & RTF_FMT_SINGLE_FAT) ? 1 : 2;
   switch (FatType)
   {
      case 12: BR->BP.DirEntries = 128; break;
      case 16: BR->BP.DirEntries = 512; break;
      case 32: BR->BP.DirEntries =   0; break;
   }
   BR->BP.MediaDescriptor = MediaDescriptor;
   BR->BP.SectorsPerTrack = Partition->EndSector & 63;
   BR->BP.NumberOfHeads   = Partition->EndHead + 1;

   {
      RTFExtendedBIOSParameter * EBPB = (FatType == 32) ? &BR->BP.E._32.BPB : &BR->BP.E._16.BPB;

      EBPB->PhysicalDiskNumber = (BR->BP.MediaDescriptor == 0xF8) ? 0x80 : 0;
      EBPB->Signature       = 0x29; // keep NT happy
      RTFSYSGetDateTime((RTFDOSDateTime*) &EBPB->SerialNumber);
      memcpy((void*)EBPB->Label, "NO NAME    ", sizeof(EBPB->Label));
      switch (FatType)
      {
         case 12: memcpy((void*)EBPB->SystemID, "FAT12   ", 8); break;
         case 16: memcpy((void*)EBPB->SystemID, "FAT16   ", 8); break;
         case 32: memcpy((void*)EBPB->SystemID, "FAT32   ", 8); break;
      }
   }

   if (FatType == 32)
   {
      BR->BP.E._32.RootDirCluster = 2;
      BR->BP.E._32.FSInfoSector = 1;
      BR->BP.E._32.BackupBootSector = 6;
   }

   RootDirSectors    = (BR->BP.DirEntries * 32 + (BR->BP.BytesPerSector - 1)) / SECTOR_SIZE;
   NetSectors        = BR->BP.TotalSectors - BR->BP.ReservedSectors - RootDirSectors;
   SectorsPerCluster = MinSectorsPerCluster ? MinSectorsPerCluster : GetDefaultClusterSize(BR->BP.TotalSectors, FatType);

NewClusterSize:

   switch (FatType)
   {
      case 12:
      case 16:
         // calculate the maximum FAT size assuming that the FAT itself needs just one sector.
         // Then, reduce the FAT one sector at a time until it no longer fits.
         // increase the FAT by one sector to a valid configuration (this
         // is done after the enclosing switch statement)

         #define FAT_12_SECTORS(Clusters) ((((Clusters)+2) * 3 / 2 - 1) / SECTOR_SIZE + 1)
         #define FAT_16_SECTORS(Clusters) ((((Clusters)+2) * 2     - 1) / SECTOR_SIZE + 1)
         #define FAT_SECTORS(Clusters)    ((FatType == 12) ? FAT_12_SECTORS(Clusters) : FAT_16_SECTORS(Clusters))

         BR->BP.SectorsPerFAT = FAT_SECTORS((FatType == 12) ? MAX_CLUSTERS_12 : MAX_CLUSTERS_16); // too large

         while (1)
         {
            DataSectors = NetSectors - BR->BP.NumberOfFATs * BR->BP.SectorsPerFAT; // too small
            Clusters    = DataSectors / SectorsPerCluster;

            // Do we have too many clusters?
            // If so, increase cluster size. This loop will increase the
            // number of data sectors, so this problem will not get fixed
            // and is detected in the first iteration
            if (Clusters > ((FatType == 12) ? MAX_CLUSTERS_12 : MAX_CLUSTERS_16))
            {
               if (SectorsPerCluster < (32l*1024))
               {
                  if ((Flags & RTF_FMT_FAT_32) == 0) // we are allowd to pick FAT type
                  {
                     switch (FatType)
                     {
                        case 12:
                           if (SectorsPerCluster >= 16)
                           {
                              FatType = 16;
                              goto NewFATType;
                           }
                           break;
                        case 16:
                           if ((SectorsPerCluster >= 64) && ((Flags & RTF_FMT_NO_FAT_32) == 0))
                           {
                              FatType = 32;
                              goto NewFATType;
                           }
                     } // switch (FatType)
                  }
                  // increase cluster size if feasible or necessary
                  SectorsPerCluster *= 2;
                  goto NewClusterSize;
               }
               else
                  return RTF_INVALID_FILE_SYSTEM;
            }   
            // Is our FAT big enough to hold all clusters?
            // If it's too small, increment (success).
            // This can't be true in the first interation as the maximum
            // FAT size must accomodate for MAX_CLUSTERS
            // If we have too many clusters, the previous check threw us
            // out already
            if (BR->BP.SectorsPerFAT < FAT_SECTORS(Clusters))
               break;

            BR->BP.SectorsPerFAT--;
         }
         BR->BP.SectorsPerFAT++;
         DataSectors = NetSectors - BR->BP.NumberOfFATs * BR->BP.SectorsPerFAT;
         Clusters    = DataSectors / SectorsPerCluster;
         // check that we do not have too few clusters
         if ((FatType == 16) && (Clusters <= MAX_CLUSTERS_12))
            return RTF_INVALID_FILE_SYSTEM;
         break;

      case 32:
         // we do not have to worry about too many clusters
         // start with 512 cluster per fat (minimum for FAT-32) and increase until it fits.

         #define FAT_32_SECTORS(Clusters) ((((Clusters)+2) * 4 - 1) / SECTOR_SIZE + 1)

         for (BR->BP.E._32.SectorsPerFAT=512; ;BR->BP.E._32.SectorsPerFAT++)
         {
            DataSectors = NetSectors - BR->BP.NumberOfFATs * BR->BP.E._32.SectorsPerFAT;
            Clusters    = DataSectors / SectorsPerCluster;

            // Is our FAT big enough to hold all clusters?
            if (BR->BP.E._32.SectorsPerFAT >= FAT_32_SECTORS(Clusters))
               break; 
         }
         // check that we do not have too few clusters
         if (Clusters <= MAX_CLUSTERS_16)
            return RTF_INVALID_FILE_SYSTEM;
         break;
   }

   // record SectorsPerCluster

   if (SectorsPerCluster <= 128)
      BR->BP.SectorsPerCluster = SectorsPerCluster;
   else
   {
      BR->BP.SectorsPerCluster = 0;
      while ((1 << BR->BP.SectorsPerCluster) < SectorsPerCluster)
         BR->BP.SectorsPerCluster++;
      BR->BP.SectorsPerCluster |= 0x80;
   }

   /* Add to support Renasas NAND, Karen Hsu, 2005/05/19, ADD START */
   if (Flags & RTF_FMT_GET_DATA_SECTOR)
   {
      if (FatType == 12)
         return (BR->BP.ReservedSectors + BR->BP.NumberOfFATs * BR->BP.SectorsPerFAT + RootDirSectors);
      else if (FatType == 16)
         return (BR->BP.ReservedSectors + BR->BP.NumberOfFATs * BR->BP.SectorsPerFAT + RootDirSectors);
      else
         return (BR->BP.ReservedSectors + BR->BP.NumberOfFATs * BR->BP.E._32.SectorsPerFAT);
   }
   else
   /* Add to support Renasas NAND, Karen Hsu, 2005/05/19, ADD END */
      return FatType;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -