Modules/FAT - Implemented GetNodeFromINode
[tpg/acess2.git] / Modules / Filesystems / FAT / fat.c
index 5502b5a..97044eb 100644 (file)
@@ -56,7 +56,7 @@ typedef struct sFAT_LFNCache
 // === PROTOTYPES ===\r
 // --- Driver Core\r
  int   FAT_Install(char **Arguments);\r
-tVFS_Node      *FAT_InitDevice(char *device, char **options);\r
+tVFS_Node      *FAT_InitDevice(const char *device, const char **options);\r
 void   FAT_Unmount(tVFS_Node *Node);\r
 // --- Helpers\r
  int   FAT_int_GetAddress(tVFS_Node *Node, Uint64 Offset, Uint64 *Addr, Uint32 *Cluster);\r
@@ -75,6 +75,7 @@ Uint64        FAT_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
 // --- Directory IO\r
 char   *FAT_ReadDir(tVFS_Node *Node, int ID);\r
 tVFS_Node      *FAT_FindDir(tVFS_Node *Node, const char *Name);\r
+tVFS_Node      *FAT_GetNodeFromINode(tVFS_Node *Root, Uint64 Inode);\r
 #if SUPPORT_WRITE\r
  int   FAT_Mknod(tVFS_Node *Node, const char *Name, Uint Flags);\r
  int   FAT_Relink(tVFS_Node *node, const char *OldName, const char *NewName);\r
@@ -88,7 +89,7 @@ void  FAT_CloseFile(tVFS_Node *node);
 MODULE_DEFINE(0, (0<<8)|50 /*v0.50*/, VFAT, FAT_Install, NULL, NULL);\r
 tFAT_VolInfo   gFAT_Disks[8];\r
  int   giFAT_PartCount = 0;\r
-tVFS_Driver    gFAT_FSInfo = {"fat", 0, FAT_InitDevice, FAT_Unmount, NULL};\r
+tVFS_Driver    gFAT_FSInfo = {"fat", 0, FAT_InitDevice, FAT_Unmount, FAT_GetNodeFromINode, NULL};\r
 \r
 // === CODE ===\r
 /**\r
@@ -102,10 +103,9 @@ int FAT_Install(char **Arguments)
 }\r
 \r
 /**\r
- * \fn tVFS_Node *FAT_InitDevice(char *Device, char **Options)\r
  * \brief Reads the boot sector of a disk and prepares the structures for it\r
  */\r
-tVFS_Node *FAT_InitDevice(char *Device, char **Options)\r
+tVFS_Node *FAT_InitDevice(const char *Device, const char **Options)\r
 {\r
        fat_bootsect *bs;\r
         int    i;\r
@@ -134,11 +134,15 @@ tVFS_Node *FAT_InitDevice(char *Device, char **Options)
        // - From Microsoft FAT Specifcation\r
        RootDirSectors = ((bs->files_in_root*32) + (bs->bps - 1)) / bs->bps;\r
        \r
-       if(bs->fatSz16 != 0)            FATSz = bs->fatSz16;\r
-       else                                    FATSz = bs->spec.fat32.fatSz32;\r
+       if(bs->fatSz16 != 0)\r
+               FATSz = bs->fatSz16;\r
+       else\r
+               FATSz = bs->spec.fat32.fatSz32;\r
        \r
-       if(bs->totalSect16 != 0)                TotSec = bs->totalSect16;\r
-       else                                            TotSec = bs->totalSect32;\r
+       if(bs->totalSect16 != 0)\r
+               TotSec = bs->totalSect16;\r
+       else\r
+               TotSec = bs->totalSect32;\r
        \r
        diskInfo->ClusterCount = (TotSec - (bs->resvSectCount + (bs->fatCount * FATSz) + RootDirSectors)) / bs->spc;\r
        \r
@@ -326,8 +330,8 @@ int FAT_int_GetAddress(tVFS_Node *Node, Uint64 Offset, Uint64 *Addr, Uint32 *Clu
        \r
        ENTER("pNode XOffset", Node, Offset);\r
        \r
-       cluster = Node->Inode & 0xFFFFFFFF;     // Cluster ID\r
-       LOG("cluster = %08x", cluster);\r
+       cluster = Node->Inode & 0xFFFFFFF     // Cluster ID\r
+       LOG("cluster = 0x%07x", cluster);\r
        \r
        // Do Cluster Skip\r
        // - Pre FAT32 had a reserved area for the root.\r
@@ -611,9 +615,9 @@ Uint64 FAT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
 {\r
         int    preSkip, count;\r
         int    i, cluster, pos;\r
-        int    bpc;\r
-       void    *tmpBuf;\r
        tFAT_VolInfo    *disk = Node->ImplPtr;\r
+       char    tmpBuf[disk->BytesPerCluster];\r
+        int    bpc = disk->BytesPerCluster;\r
        \r
        ENTER("pNode Xoffset Xlength pbuffer", Node, Offset, Length, Buffer);\r
        \r
@@ -624,11 +628,6 @@ Uint64 FAT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
                return 0;\r
        }\r
        \r
-       // Calculate and Allocate Bytes Per Cluster\r
-       bpc = disk->BytesPerCluster;\r
-       tmpBuf = (void*) malloc(bpc);\r
-       if( !tmpBuf )   return 0;\r
-       \r
        // Cluster is stored in the low 32-bits of the Inode field\r
        cluster = Node->Inode & 0xFFFFFFFF;\r
        \r
@@ -645,7 +644,6 @@ Uint64 FAT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
                LOG("First cluster only");\r
                FAT_int_ReadCluster(disk, cluster, bpc, tmpBuf);\r
                memcpy( Buffer, (void*)( tmpBuf + Offset%bpc ), Length );\r
-               free(tmpBuf);\r
                #if DEBUG\r
                //Debug_HexDump("FAT_Read", Buffer, Length);\r
                #endif\r
@@ -659,7 +657,6 @@ Uint64 FAT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
                cluster = FAT_int_GetFatValue(disk, cluster);\r
                if(cluster == -1) {\r
                        Log_Warning("FAT", "Offset is past end of cluster chain mark");\r
-                       free(tmpBuf);\r
                        LEAVE('i', 0);\r
                        return 0;\r
                }\r
@@ -689,7 +686,6 @@ Uint64 FAT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
                #if DEBUG\r
                //Debug_HexDump("FAT_Read", Buffer, Length);\r
                #endif\r
-               free(tmpBuf);\r
                LEAVE('i', 1);\r
                return Length;\r
        }\r
@@ -705,8 +701,7 @@ Uint64 FAT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
                // Get next cluster in the chain\r
                cluster = FAT_int_GetFatValue(disk, cluster);\r
                if(cluster == -1) {\r
-                       Warning("FAT_Read - Read past End of Cluster Chain");\r
-                       free(tmpBuf);\r
+                       Log_Warning("FAT", "FAT_Read: Read past End of Cluster Chain");\r
                        LEAVE('i', 0);\r
                        return 0;\r
                }\r
@@ -718,8 +713,7 @@ Uint64 FAT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
        // Get next cluster in the chain\r
        cluster = FAT_int_GetFatValue(disk, cluster);\r
        if(cluster == -1) {\r
-               Warning("FAT_Read - Read past End of Cluster Chain");\r
-               free(tmpBuf);\r
+               Log_Warning("FAT", "FAT_Read: Read past End of Cluster Chain");\r
                LEAVE('i', 0);\r
                return 0;\r
        }\r
@@ -739,7 +733,6 @@ Uint64 FAT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
        //Debug_HexDump("FAT_Read", Buffer, Length);\r
        #endif\r
        \r
-       free(tmpBuf);\r
        LEAVE('X', Length);\r
        return Length;\r
 }\r
@@ -771,7 +764,7 @@ void FAT_int_WriteCluster(tFAT_VolInfo *Disk, Uint32 Cluster, void *Buffer)
 Uint64 FAT_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)\r
 {\r
        tFAT_VolInfo    *disk = Node->ImplPtr;\r
-       void    *tmpBuf;\r
+       char    tmpBuf[disk->BytesPerCluster];\r
         int    remLength = Length;\r
        Uint32  cluster, tmpCluster;\r
         int    bNewCluster = 0;\r
@@ -799,29 +792,24 @@ Uint64 FAT_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
        \r
        if( Offset + Length < disk->BytesPerCluster )\r
        {\r
-               tmpBuf = malloc( disk->BytesPerCluster );\r
+               char    tmpBuf[disk->BytesPerCluster];\r
                \r
                // Read-Modify-Write\r
                FAT_int_ReadCluster( disk, cluster, disk->BytesPerCluster, tmpBuf );\r
                memcpy( tmpBuf + Offset, Buffer, Length );\r
                FAT_int_WriteCluster( disk, cluster, tmpBuf );\r
                \r
-               free(tmpBuf);\r
                return Length;\r
        }\r
        \r
        // Clean up changes within a cluster\r
        if( Offset )\r
-       {\r
-               tmpBuf = malloc( disk->BytesPerCluster );\r
-               \r
+       {       \r
                // Read-Modify-Write\r
                FAT_int_ReadCluster( disk, cluster, disk->BytesPerCluster, tmpBuf );\r
                memcpy( tmpBuf + Offset, Buffer, disk->BytesPerCluster - Offset );\r
                FAT_int_WriteCluster( disk, cluster, tmpBuf );\r
                \r
-               free(tmpBuf);\r
-               \r
                remLength -= disk->BytesPerCluster - Offset;\r
                Buffer += disk->BytesPerCluster - Offset;\r
                \r
@@ -952,7 +940,7 @@ tVFS_Node *FAT_int_CreateNode(tVFS_Node *Parent, fat_filetable *Entry, int Pos)
        memset(&node, 0, sizeof(tVFS_Node));\r
        \r
        // Set Other Data\r
-       // 0-31: Cluster, 32-63: Parent Cluster\r
+       // 0-27: Cluster, 32-59: Parent Cluster\r
        node.Inode = Entry->cluster | (Entry->clusterHi<<16) | (Parent->Inode << 32);\r
        LOG("node.Inode = %llx", node.Inode);\r
        // Position in parent directory\r
@@ -1415,6 +1403,60 @@ tVFS_Node *FAT_FindDir(tVFS_Node *Node, const char *Name)
        return NULL;\r
 }\r
 \r
+tVFS_Node *FAT_GetNodeFromINode(tVFS_Node *Root, Uint64 Inode)\r
+{\r
+       tFAT_VolInfo    *disk = Root->ImplPtr;\r
+        int    ents_per_sector = 512 / sizeof(fat_filetable); \r
+       fat_filetable   fileinfo[ents_per_sector];\r
+        int    sector = 0, i;\r
+       tVFS_Node       stub_node;\r
+\r
+       ENTER("pRoot XInode", Root, Inode);\r
+\r
+       stub_node.ImplPtr = disk;\r
+       stub_node.Size = -1;\r
+       stub_node.Inode = Inode >> 32;\r
+\r
+       for( i = 0; ; i ++ )\r
+       {\r
+               if( i == 0 || i == ents_per_sector )\r
+               {\r
+                       if(FAT_int_ReadDirSector(&stub_node, sector, fileinfo))\r
+                       {\r
+                               LOG("ReadDirSector failed");\r
+                               LEAVE('n');\r
+                               return NULL;\r
+                       }\r
+                       i = 0;\r
+                       sector ++;\r
+               }\r
+       \r
+               // Check for free/end of list\r
+               if(fileinfo[i].name[0] == '\0') break;  // End of List marker\r
+               if(fileinfo[i].name[0] == '\xE5')       continue;       // Free entry\r
+               \r
+               if(fileinfo[i].attrib == ATTR_LFN)      continue;\r
+\r
+               LOG("fileinfo[i].cluster = %x %04x", fileinfo[i].clusterHi, fileinfo[i].cluster);\r
+               #if DEBUG\r
+               {\r
+                       char    tmpName[13];\r
+                       FAT_int_ProperFilename(tmpName, fileinfo[i].name);\r
+                       LOG("tmpName = '%s'", tmpName);\r
+               }\r
+               #endif\r
+               \r
+       \r
+               if(fileinfo[i].cluster != (Inode & 0xFFFF))     continue;\r
+               if(fileinfo[i].clusterHi != ((Inode >> 16) & 0xFFFF))   continue;\r
+\r
+               LEAVE_RET('p', FAT_int_CreateNode(&stub_node, &fileinfo[i], sector*ents_per_sector+i));\r
+       }\r
+       LOG("sector = %i, i = %i", sector, i);\r
+       LEAVE('n');\r
+       return NULL;\r
+}\r
+\r
 #if SUPPORT_WRITE\r
 /**\r
  * \fn int FAT_Mknod(tVFS_Node *Node, char *Name, Uint Flags)\r

UCC git Repository :: git.ucc.asn.au