X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FModules%2FFilesystems%2FNTFS%2Fmain.c;h=18caf46245a783d7530b6833f14a1f373d915174;hb=384befc18f81f42d2dd6e324a35904ad037b3af7;hp=8d6a724d21935784ce09d028c9ec44eeef7a92ed;hpb=2c6ec285c9fd7a3034942e724708e2e65d904e4c;p=tpg%2Facess2.git diff --git a/KernelLand/Modules/Filesystems/NTFS/main.c b/KernelLand/Modules/Filesystems/NTFS/main.c index 8d6a724d..18caf462 100644 --- a/KernelLand/Modules/Filesystems/NTFS/main.c +++ b/KernelLand/Modules/Filesystems/NTFS/main.c @@ -40,11 +40,12 @@ tVFS_NodeType gNTFS_DirType = { .TypeName = "NTFS-Dir", .ReadDir = NTFS_ReadDir, .FindDir = NTFS_FindDir, - .Close = NULL + .Close = NTFS_Close }; tVFS_NodeType gNTFS_FileType = { .TypeName = "NTFS-File", - .Close = NULL + .Read = NTFS_ReadFile, + .Close = NTFS_Close }; tNTFS_Disk gNTFS_Disks; @@ -69,7 +70,11 @@ int NTFS_Detect(int FD) if( bs.BytesPerSector == 0 || (bs.BytesPerSector & 511) ) return 0; - + if( bs.SectorsPerCluster == 0 ) + return 0; + if( bs.ClustersPerMFTRecord == 0 ) + return 0; + Uint64 ncluster = bs.TotalSectorCount / bs.SectorsPerCluster; if( bs.MFTStart >= ncluster || bs.MFTMirrorStart >= ncluster ) return 0; @@ -122,6 +127,7 @@ tVFS_Node *NTFS_InitDevice(const char *Device, const char **Options) #endif disk->ClusterSize = bs.BytesPerSector * bs.SectorsPerCluster; + ASSERTR(disk->ClusterSize > 0, NULL); disk->MFTBase = bs.MFTStart; Log_Debug("NTFS", "Cluster Size = %i KiB", disk->ClusterSize/1024); Log_Debug("NTFS", "MFT Base = %i", disk->MFTBase); @@ -133,10 +139,11 @@ tVFS_Node *NTFS_InitDevice(const char *Device, const char **Options) else { disk->MFTRecSize = bs.ClustersPerMFTRecord * disk->ClusterSize; } + ASSERTR(disk->MFTRecSize > 0, NULL); //NTFS_DumpEntry(disk, 0); // $MFT //NTFS_DumpEntry(disk, 3); // $VOLUME - disk->InodeCache = Inode_GetHandle(); + disk->InodeCache = Inode_GetHandle(NTFS_FreeNode); disk->MFTDataAttr = NULL; disk->MFTDataAttr = NTFS_GetAttrib(disk, 0, NTFS_FileAttrib_Data, "", 0); @@ -177,6 +184,25 @@ void NTFS_Unmount(tVFS_Node *Node) free(Disk); } +void NTFS_Close(tVFS_Node *Node) +{ + tNTFS_Disk *Disk = Node->ImplPtr; + Inode_UncacheNode(Disk->InodeCache, Node->Inode); +} + +void NTFS_FreeNode(tVFS_Node *Node) +{ + if( Node->Type == &gNTFS_DirType ) { + tNTFS_Directory *Dir = (void*)Node; + NTFS_FreeAttrib(Dir->I30Root); + NTFS_FreeAttrib(Dir->I30Allocation); + } + else { + tNTFS_File *File = (void*)Node; + NTFS_FreeAttrib(File->Data); + } +} + int NTFS_int_ApplyUpdateSequence(void *Buffer, size_t BufLen, const Uint16 *Sequence, size_t NumEntries) { Uint16 cksum = Sequence[0]; @@ -203,6 +229,9 @@ int NTFS_int_ApplyUpdateSequence(void *Buffer, size_t BufLen, const Uint16 *Sequ tNTFS_FILE_Header *NTFS_GetMFT(tNTFS_Disk *Disk, Uint32 MFTEntry) { + // TODO: Cache MFT allocation for short-term + + // tNTFS_FILE_Header *ret = malloc( Disk->MFTRecSize ); if(!ret) { Log_Warning("FS_NTFS", "malloc() fail!"); @@ -312,8 +341,12 @@ tNTFS_Attrib *NTFS_GetAttrib(tNTFS_Disk *Disk, Uint32 MFTEntry, int Type, const if( attr->Type != Type ) continue; if( Name ) { - LOG("Name check = '%s'", Name); + if( attr->NameOffset + attr->NameLength*2 > attr->Size ) { + break; + } const void *name16 = (char*)attr + attr->NameOffset; + LOG("Name check: '%s' == '%.*ls'", + Name, attr->NameLength, name16); if( UTF16_CompareWithUTF8(attr->NameLength, name16, Name) != 0 ) continue ; } @@ -325,11 +358,10 @@ tNTFS_Attrib *NTFS_GetAttrib(tNTFS_Disk *Disk, Uint32 MFTEntry, int Type, const ASSERT(attr->NameOffset % 1 == 0); Uint16 *name16 = (Uint16*)attr + attr->NameOffset/2; size_t namelen = UTF16_ConvertToUTF8(0, NULL, attr->NameLength, name16); - size_t edatalen = (attr->NonresidentFlag ? 0 : attr->Resident.AttribLen*4); + size_t edatalen = (attr->NonresidentFlag ? 0 : attr->Resident.AttribLen); tNTFS_Attrib *ret = malloc( sizeof(tNTFS_Attrib) + namelen + 1 + edatalen ); if(!ret) { - LEAVE('n'); - return NULL; + goto _error; } if( attr->NonresidentFlag ) ret->Name = (void*)(ret + 1); @@ -376,17 +408,26 @@ tNTFS_Attrib *NTFS_GetAttrib(tNTFS_Disk *Disk, Uint32 MFTEntry, int Type, const { ret->DataSize = edatalen; memcpy(ret->ResidentData, (char*)attr + attr->Resident.AttribOfs, edatalen); + Debug_HexDump("GetAttrib Resident", ret->ResidentData, edatalen); } + NTFS_ReleaseMFT(Disk, MFTEntry, hdr); LEAVE('p', ret); return ret; } +_error: NTFS_ReleaseMFT(Disk, MFTEntry, hdr); LEAVE('n'); return NULL; } +void NTFS_FreeAttrib(tNTFS_Attrib *Attrib) +{ + if( Attrib ) + free(Attrib); +} + size_t NTFS_ReadAttribData(tNTFS_Attrib *Attrib, Uint64 Offset, size_t Length, void *Buffer) { if( !Attrib ) @@ -465,17 +506,13 @@ void NTFS_DumpEntry(tNTFS_Disk *Disk, Uint32 Entry) tNTFS_FILE_Attrib *attr; int i; - tNTFS_FILE_Header *hdr = malloc( Disk->MFTRecSize ); + + tNTFS_FILE_Header *hdr = NTFS_GetMFT(Disk, Entry); if(!hdr) { Log_Warning("FS_NTFS", "malloc() fail!"); return ; } - VFS_ReadAt( Disk->FD, - Disk->MFTBase * Disk->ClusterSize + Entry * Disk->MFTRecSize, - Disk->MFTRecSize, - hdr); - Log_Debug("FS_NTFS", "MFT Entry #%i", Entry); Log_Debug("FS_NTFS", "- Magic = 0x%08x (%4C)", hdr->Magic, &hdr->Magic); Log_Debug("FS_NTFS", "- UpdateSequenceOfs = 0x%x", hdr->UpdateSequenceOfs); @@ -536,5 +573,5 @@ void NTFS_DumpEntry(tNTFS_Disk *Disk, Uint32 Entry) attr = (void*)( (tVAddr)attr + attr->Size ); } - free(hdr); + NTFS_ReleaseMFT(Disk, Entry, hdr); }