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