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

📄 rtfiles.c

📁 MTK平台绝密核心代码之文件驱动,希望对大家有用
💻 C
📖 第 1 页 / 共 5 页
字号:
#define SUBMARK_MASK       (0x0000FFFF)
#define SUBMARK_LASTNUM    (119)

/* Directory Associated Cache Value, store run-time cache
 * Design to get faster respone for browsing application, especially on Large Directory case
 */
typedef struct MTDirAssociatedCache {
   RTFDrive * Drive;
   RTFCluster Cluster;
   UINT       Value;
} DirAssocatedCacheStruct;

#define DIRCACHE_NUM       (8)
#define DIRCACHE_MASK      (0x00000007)

#ifndef _LOW_COST_SINGLE_BANK_FLASH_
DirAssocatedCacheStruct    g_DirCacheArray[DIRCACHE_NUM];
#endif /* _LOW_COST_SINGLE_BANK_FLASH_ */

//---------------------- MT Global Static Func --------------------------

#ifdef __FS_QM_SUPPORT__
   static void  GetQuotaEntry(int * Index, RTFile * f);
   static int   QMPermitAllocate(UINT DriveFree, int Index, UINT NeedCluster);
#endif

#if (defined(__FS_SHADOW_NAND__) || defined(__FS_SHADOW_CARD__))
static void InitShadowFAT(RTFDrive *Drive);
static void FlushShadowFAT(void);
#endif

static void INTERN SetupFMapF_FileHandle(RTFile *f);
static int INTERN MTChkMapedFH(RTFHANDLE File);
static RTFCluster INTERN FATSearchZeroInBuffer(RTFDrive *Drive, RTFCluster Cluster);
static void INTERN FATHoistSubMark(RTFDrive *Drive, RTFCluster Begin, RTFCluster End);
static void INTERN FATLowerSubMark(RTFDrive *Drive, RTFCluster Begin, RTFCluster End);
static void INTERN FATInitInfoSectorSubMark(RTFDrive *Drive);
static RTFCluster INTERN FATHintSearchBySubMark(RTFDrive * Drive, RTFCluster Cluster, int MarkFlag);

//---------------------- MT Global Extern Func --------------------------
#ifdef __FS_TRACE_SUPPORT__
   #include <stdio.h>
   extern void tst_sys_trace(kal_uint8 *);
#endif
extern kal_bool INT_QueryExceptionStatus(void);

/***********************************************************************/
/* MTK Enhancement, Karen Hsu, ADD END */

static RTFCriticalErrorHandler CriticalError = RTFDefaultCriticalErrorHandler;
static UINT       Unique = 0;

//static fs_block_type_enum fs_block_type = FS_BLOCK_ENUM; /* Fix multi-access bug, Karen Hsu, 2004/07/08, REM */
static int        TLSBlockIndex = -1;

extern void WDT_Restart2(void); /* Add for avoiding compile warning, Karen Hsu, 2004/01/14 */

BYTE          RTFAPI _rtfLock(BYTE * Lock); // Temp = *Lock;  *Lock = 1; return Temp;
static void   INTERN LockDevice   (RTFDevice * Dev);
static void   INTERN DiscardOtherBuffer(RTFBuffer * B);
static void * INTERN SearchBuffer (RTFDevice * Dev, RTFSector Sector);
static void * INTERN GetBuffer    (RTFDevice * Dev, RTFSector Sector, UINT Flags);
static void   INTERN ScanDevices(void);
static void   INTERN UnmountDevice(RTFDevice * Dev, int CloseFiles);
static char   INTERN ScanPartitionTable(char volatile DriveLetter, RTFDevice * Dev, int PartitionKind);
static int    INTERN GenerateShortName(const char * LongName, char * ShortName);
static void   INTERN IncShortName(char * ShortName);

#define RTFRoundUp(N, Multiple)  (((N)+(Multiple)-1) & ~((Multiple)-1))
#define RTFRoundDown(N, Multiple) ((N) & ~((Multiple)-1))

#define CLUSTER_TO_SECTOR(Drive, Cluster)     ((Drive)->FirstDataSector + (((Cluster)-2L) << (Drive)->SPerCShift))
#define CLUSTER_TO_SECTOR_DIR(Drive, Cluster) (((Cluster) == RTF_ROOT_DIR) ? (Drive)->FirstDirSector : CLUSTER_TO_SECTOR(Drive, Cluster))
#define CLUSTER_TO_SECTOR_OFS(Drive, Cluster, Ofs)     ((Drive)->FirstDataSector + (((Cluster)-2L) << (Drive)->SPerCShift) + ((Ofs) >> (Drive)->Dev->DevData.SectorShift))
#define CLUSTER_TO_SECTOR_DIR_OFS(Drive, Cluster, Ofs) ((((Cluster) == RTF_ROOT_DIR) ? (Drive)->FirstDirSector : CLUSTER_TO_SECTOR(Drive, Cluster)) + ((Ofs) >> (Drive)->Dev->DevData.SectorShift))
#define SECTOR_OFS(Drive, Ofs)                ((Ofs) & ((Drive)->Dev->DevData.SectorSize-1))
#define SAME_DIR_ENTRY(D1, D2)                (((D1).Cluster == (D2).Cluster) && ((D1).Index == (D2).Index))
#define DIRS_PER_SECTOR(Drive)                (Drive->Dev->DevData.SectorSize/sizeof(RTFDOSDirEntry))

// Buffer flags
#define B_VALID   0x01   // buffer has valid data
#define B_DIRTY   0x02   // buffer has valid data and must be written to disk
#define B_INUSE   0x04   // buffer is being accessed by RTFiles
#define B_BUSY    0x08   // buffer is being accessed by a device driver
#define B_SINGLE  0x10   // single buffer for emergent use only /* Guarantee fixed disk access, Karen Hsu, 2005/05/19 */

/*----------------------------------*/
static int INTERN PowerTwo(unsigned int i)
{
   if (i == 0)
      return 0; // it's a power of two, put we need > 0
   while (i != 0)
   {
      if ((i & 1) && (i != 1))
         return 0;
      i >>= 1;
   }
   return 1;
}

/*-----------------------------------*/
static void INTERN ToHexString(char * Name, DWORD TimeStamp)
// write 8 hex digits, no zero termination
{
   UINT i;
   char HexDigits[] = "0123456789ABCDEF";

   for (i=0; i<8; i++)
   {
      Name[7-i] = HexDigits[TimeStamp & 0xF];
      TimeStamp >>= 4;
   }
}

/*-----------------------------------*/
static int INTERN IsValidShortNameChar(char c)
// ".", "\\", and ":" is invalid
{
   if ( strchr(ShortNameChars, c) )
      return 1;
   else
      return 0;
}

/*-----------------------------------*/
/* Check the validity of filename with ascii code only */
int RTFAPI IsValidLongNameChar(WCHAR c)
//static int INTERN IsValidLongNameChar(WCHAR c)
// "\\" and ":" is invalid
{
   char LongNameChars[]  = ".+,;=[]";

   if ( c<0x80 )
      return ( strchr(ShortNameChars, (char)c) || strchr(LongNameChars, (char)c) );

   return 1;
}

/*-----------------------------------*/
/* check only the last filename component */
static void INTERN CheckValidFileName(const WCHAR * FileName)
{
   const WCHAR *p = kal_wstrrchr(FileName, 0x005c);

   if (p == NULL)
      p = FileName;
   else
      p++;

   /* Fix Dot-begin issue, Karen Hsu, 2004/04/29, ADD START */
   if((*p == 0x2E) || (*p == 0x20))
   {
#ifdef __FS_TRACE_SUPPORT__
      if(g_TraceFlag & MT_TRACE_ERROR)
         MTTraceFS((DWORD)kal_get_current_thread_ID(), 1, __LINE__, RTF_INVALID_FILENAME, NULL, (BYTE *)FileName);
#endif
      XRAISE(RTF_INVALID_FILENAME);
   }
   /* Fix Dot-begin issue, Karen Hsu, 2004/04/29, ADD END */

   for ( ;*p != 0x0; p++)
   {  if (!IsValidLongNameChar(*p) || *p == 0xFFFF /* UCS2 convert failure mark, WCP_SW, 2005/11/17*/)
      {
#ifdef __FS_TRACE_SUPPORT__
         if(g_TraceFlag & MT_TRACE_ERROR)
            MTTraceFS((DWORD)kal_get_current_thread_ID(), 1, __LINE__, RTF_INVALID_FILENAME, NULL, (BYTE *)FileName);
#endif
         XRAISE(RTF_INVALID_FILENAME);
      }
   }

   /* Fix Dot-end issue, Karen Hsu, 2004/04/29, ADD START */
   p--;
   if(*p == 0x2E)
   {
#ifdef __FS_TRACE_SUPPORT__
      if(g_TraceFlag & MT_TRACE_ERROR)
         MTTraceFS((DWORD)kal_get_current_thread_ID(), 1, __LINE__, RTF_INVALID_FILENAME, NULL, (BYTE *)FileName);
#endif
      XRAISE(RTF_INVALID_FILENAME);
   }
   /* Fix Dot-end issue, Karen Hsu, 2004/04/29, ADD END */
}

/*-----------------------------------*/
/* COMPare Unicode and Ascii STRING */
int compUAstring(const char * FileName, const char* str, int len)
{
   int i;

   for (i=0; i<len; i++)
   {
      if (!compASCII(FileName, i, str[i]))
         return 0;
   }
   return 1;
}

/*-----------------------------------*/
WCHAR UnicodetoNative(WCHAR unicode)
{
        if ( unicode<0x80 )
           return unicode;
        else
/* Support SFN in active encoding, Karen Hsu, 2004/05/28, MOD START */
   {
      WCHAR encode;
      encode = UCS2_TO_WCHAR(unicode);
      ASSERT(encode != 0x0000);
      return encode;
   }
/* Support SFN in active encoding, Karen Hsu, 2004/05/28, MOD END */
}

/*-----------------------------------*/
WCHAR NativetoUnicode(WCHAR native)
{
   return native;
}

/*-----------------------------------*/
static char INTERN _rtftoupper(signed char c)
{
   if ( (c >= 'a') && (c <= 'z') )
      return c - ('a' - 'A');
   return c;
}

/*-----------------------------------*/
WCHAR RTFAPI wchartoupper(WCHAR c)
{
   // check if ascii code
   if ( (c>=0x61) && (c<=0x7a) )
      return c - (0x61 - 0x41);
   return c;
}

/*-----------------------------------*/
static RTFErrorAction INTERN HandleCriticalError(RTFDevice * Dev, int ErrorCode);
static int INTERN GetDiskGeometry(RTFDevice * Dev, RTFPartitionRecord * DiskGeometry, BYTE * MediaDescriptor);

/*-----------------------------------*/
static void INTERN CheckMedia(RTFDevice * Dev)
{
   if ((Dev->DevData.MediaRemovedReported == 0) ||
       (Dev->DevData.MediaPresent == 0))
   {
      Dev->DevData.MediaRemovedReported = 1;
#ifdef __FS_TRACE_SUPPORT__
      if(g_TraceFlag & MT_TRACE_ERROR)
      {
         if(Dev->DeviceFlags & MT_DEVICE_NOR_FLASH)
            kal_sprintf(TraceTmpBuf, "Dev:NOR");
         else if(Dev->DeviceFlags & MT_DEVICE_NAND_FLASH)
            kal_sprintf(TraceTmpBuf, "Dev:NAND");
         else
            kal_sprintf(TraceTmpBuf, "Dev:Card");
         memset(TraceTmpBuf+strlen((char *)TraceTmpBuf)+1, 0, 2);
         MTTraceFS((DWORD)kal_get_current_thread_ID(), 1, __LINE__, RTF_MEDIA_CHANGED, NULL, (BYTE *)TraceTmpBuf);
      }
#endif
      XRAISE(RTF_MEDIA_CHANGED);
   }
}

/*-----------------------------------*/
static int INTERN MountDevice(RTFDevice * Dev, DWORD Flags)
{
   int volatile Result;
   RTFSYSFreeMutex((RTFMutex *)RTFLock);
   XTRY
      case XCODE:
         Dev->DevData.MediaRemovedReported = 1;
         CheckMedia(Dev);
         Dev->DevData.ErrorCondition = RTF_NO_ERROR;
         Dev->DevData.MediaDescriptor = 0;
         memset((void *)&Dev->DevData.Geometry, 0, sizeof(Dev->DevData.Geometry));
         Dev->DevData.MountState = Initialized;

         Result = Dev->Driver->MountDevice(Dev->DriverData, Dev->DeviceNumber, Dev->DeviceType, Dev->DeviceFlags);
         if (Result < RTF_NO_ERROR)
         {
#ifdef __FS_TRACE_SUPPORT__
            if(g_TraceFlag & MT_TRACE_ERROR)
            {
               if(Dev->DeviceFlags & MT_DEVICE_NOR_FLASH)
                  kal_sprintf(TraceTmpBuf, "Dev:NOR");
               else if(Dev->DeviceFlags & MT_DEVICE_NAND_FLASH)
                  kal_sprintf(TraceTmpBuf, "Dev:NAND");
               else
                  kal_sprintf(TraceTmpBuf, "Dev:Card");
               memset(TraceTmpBuf+strlen((char *)TraceTmpBuf)+1, 0, 2);
               MTTraceFS((DWORD)kal_get_current_thread_ID(), 1, __LINE__, Result, NULL, (BYTE *)TraceTmpBuf);
            }
#endif
            XRAISE(Result);
         }

         if (Result > RTF_MIN_BUFFER_SIZE)
         {
#ifdef __FS_TRACE_SUPPORT__
            if(g_TraceFlag & MT_TRACE_ERROR)
            {
               if(Dev->DeviceFlags & MT_DEVICE_NOR_FLASH)
                  kal_sprintf(TraceTmpBuf, "Dev:NOR");
               else if(Dev->DeviceFlags & MT_DEVICE_NAND_FLASH)
                  kal_sprintf(TraceTmpBuf, "Dev:NAND");
               else
                  kal_sprintf(TraceTmpBuf, "Dev:Card");
               memset(TraceTmpBuf+strlen((char *)TraceTmpBuf)+1, 0, 2);
               MTTraceFS((DWORD)kal_get_current_thread_ID(), 1, __LINE__, RTF_INVALID_SECTOR_SIZE, NULL, (BYTE *)TraceTmpBuf);
            }
#endif
            XRAISE(RTF_INVALID_SECTOR_SIZE);
         }
         if (!PowerTwo(Result))
         {
#ifdef __FS_TRACE_SUPPORT__
            if(g_TraceFlag & MT_TRACE_ERROR)
            {
               if(Dev->DeviceFlags & MT_DEVICE_NOR_FLASH)
                  kal_sprintf(TraceTmpBuf, "Dev:NOR");
               else if(Dev->DeviceFlags & MT_DEVICE_NAND_FLASH)
                  kal_sprintf(TraceTmpBuf, "Dev:NAND");
               else
                  kal_sprintf(TraceTmpBuf, "Dev:Card");
               memset(TraceTmpBuf+strlen((char *)TraceTmpBuf)+1, 0, 2);
               MTTraceFS((DWORD)kal_get_current_thread_ID(), 1, __LINE__, RTF_INVALID_SECTOR_SIZE, NULL, (BYTE *)TraceTmpBuf);
            }
#endif
            XRAISE(RTF_INVALID_SECTOR_SIZE);
         }

         Dev->DevData.SectorSize = Result;
         Dev->DevData.SectorShift = 0;
         while ((1 << Dev->DevData.SectorShift) < Dev->DevData.SectorSize)
            Dev->DevData.SectorShift++;

         break;
      default:
         if (Flags & NO_RAISE)
         {
            Result = XVALUE;
            XHANDLED;
         }
         break;
      case XFINALLY:
         RTFSYSLockMutex(RTFLock, RTF_INFINITE);
         break;
   XEND
   if (Result >= RTF_NO_ERROR)
   {
      /* Modify for write protect issue, Karen Hsu, 2004/04/07, MOD START */
      if(GetDiskGeometry(Dev, &Dev->DevData.Geometry, &Dev->DevData.MediaDescriptor) == RTF_WRITE_PROTECTION)
         Dev->DeviceFlags |= MT_DEVICE_WRITE_PROTECT;
      else
         Dev->DeviceFlags &= ~MT_DEVICE_WRITE_PROTECT;
      //GetDiskGeometry(Dev, &Dev->DevData.Geometry, &Dev->DevData.MediaDescriptor);
      /* Modify for write protect issue, Karen Hsu, 2004/04/07, MOD END */

      /* Add for usb normal mode access, , 2005/12/01, ADD START */
      if (Dev->DeviceNumber == gFS_DeviceNumOfSYSDRV)
      {
         Dev->DeviceFlags |= MT_DEVICE_NO_EXPORT;
      }
      /* Add for usb normal mode access, , 2005/12/01, ADD END */
      Dev->DevData.MountState = Mounted;
   }
   /* Reserve drive name for mount error device, Karen Hsu, 2004/03/04, ADD START */
   else
   {
      if(GetDiskGeometry(Dev, &Dev->DevData.Geometry, &Dev->DevData.MediaDescriptor))
      {
         if(Dev->DeviceFlags & MT_DEVICE_NOR_FLASH)
            NorPartition = KAL_TRUE;
         else if(Dev->DeviceFlags & MT_DEVICE_NAND_FLASH)
            NandPartition = KAL_TRUE;
      }
   }
   /* Reserve drive name for mount error device, Karen Hsu, 2004/03/04, ADD END */
   return Result;
}

/*-----------------------------------*/
static int INTERN ShutDown(RTFDevice * Dev)
{
   int volatile Result;
   RTFSYSFreeMutex(RTFLock);
   XTRY
      case XCODE:
         CheckMedia(Dev);
         Result = Dev->Driver->ShutDown(Dev->DriverData);
         break;
      default:
         Result = XVALUE;
         XHANDLED;
         break;
      case XFINALLY:
         RTFSYSLockMutex(RTFLock, RTF_INFINITE);
         break;
   XEND
   return Result;
}

/*-----------------------------------*/
static int INTERN ReadSectors(RTFDevice * Dev, void * Data, RTFSector Sector, UINT Sectors, DWORD Flags)
{
   int volatile Result;
   RTFSYSFreeMutex(RTFLock);
   XTRY
      case XCODE:
         CheckMedia(Dev);
         if (Dev->DevData.ErrorCondition < RTF_NO_ERROR)
         {
#ifdef __FS_TRACE_SUPPORT__
            if(g_TraceFlag & MT_TRACE_ERROR)
            {
               if(Dev->DeviceFlags & MT_DEVICE_NOR_FLASH)
                  kal_sprintf(TraceTmpBuf, "Dev:NOR, Sector: %d, Sectors: %d", Sector, Sectors);
               else if(Dev->DeviceFlags & MT_DEVICE_NAND_FLASH)
                  kal_sprintf(TraceTmpBuf, "Dev:NAND, Sector: %d, Sectors: %d", Sector, Sectors);
               else
                  kal_sprintf(TraceTmpBuf, "Dev:Card, Sector: %d, Sectors: %d", Sector, Sectors);
               memset(TraceTmpBuf+strlen((char *)TraceTmpBuf)+1, 0, 2);
               MTTraceFS((DWORD)kal_get_current_thread_ID(), 1, __LINE__, Dev->DevData.ErrorCondition, NULL, (BYTE *)TraceTmpBuf);
            }
#endif
            XRAISE(Dev->DevData.ErrorCondition);
         }
         if (Dev->DevData.MountState < Mounted)
         {
#ifdef __FS_TRACE_SUPPORT__
            if(g_TraceFlag & MT_TRACE_ERROR)
            {
               if(Dev->DeviceFlags & MT_DEVICE_NOR_FLASH)
                  kal_sprintf(TraceTmpBuf, "Dev:NOR, Sector: %d, Sectors: %d", Sector, Sectors);
               else if(Dev->DeviceFlags & MT_DEVICE_NAND_FLASH)
                  kal_sprintf(TraceTmpBuf, "Dev:NAND, Sector: %d, Sectors: %d", Sector, Sectors);
               else
                  kal_sprintf(TraceTmpBuf, "Dev:Card, Sector: %d, Sectors: %d", Sector, Sectors);
               memset(TraceTmpBuf+strlen((char *)TraceTmpBuf)+1, 0, 2);
               MTTraceFS((DWORD)kal_get_current_thread_ID(), 1, __LINE__, RTF_DRIVE_NOT_READY, NULL, (BYTE *)TraceTmpBuf);
            }
#endif
            XRAISE(RTF_DRIVE_NOT_READY);
         }
         Result = Dev->Driver->ReadSectors(Dev->DriverData, Sector, Sectors, Data);
         if (Result < RTF_NO_ERROR)
         {
#ifdef __FS_TRACE_SUPPORT__
            if(g_TraceFlag & MT_TRACE_ERROR)
            {
               if(Dev->DeviceFlags & MT_DEVICE_NOR_FLASH)
                  kal_sprintf(TraceTmpBuf, "Dev:NOR, Sector: %d, Sectors: %d", Sector, Sectors);
               else if(Dev->DeviceFlags & MT_DEVICE_NAND_FLASH)
                  kal_sprintf(TraceTmpBuf, "Dev:NAND, Sector: %d, Sectors: %d", Sector, Sectors);
               else
                  kal_sprintf(TraceTmpBuf, "Dev:Card, Sector: %d, Sectors: %d", Sector, Sectors);
               memset(TraceTmpBuf+strlen((char *)TraceTmpBuf)+1, 0, 2);
               MTTraceFS((DWORD)kal_get_current_thread_ID(), 1, __LINE__, Result, NULL, (BYTE *)TraceTmpBuf);
            }
#endif
            XRAISE(Result);
         }
         break;
      default:
         if (((Flags & NO_CRITICAL) == 0) &&
             (HandleCriticalError(Dev, XVALUE) == RTFRetry))
         {
            XHANDLED;

⌨️ 快捷键说明

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