3 * By John Hodge (thePowersGang)
15 extern char *NTFS_ReadDir(tVFS_Node *Node, int Pos);
16 extern tVFS_Node *NTFS_FindDir(tVFS_Node *Node, const char *Name);
19 int NTFS_Install(char **Arguments);
20 tVFS_Node *NTFS_InitDevice(const char *Devices, const char **Options);
21 void NTFS_Unmount(tVFS_Node *Node);
22 void NTFS_DumpEntry(tNTFS_Disk *Disk, Uint32 Entry);
25 MODULE_DEFINE(0, 0x0A /*v0.1*/, FS_NTFS, NTFS_Install, NULL);
26 tVFS_Driver gNTFS_FSInfo = {
28 .InitDevice = NTFS_InitDevice,
29 .Unmount = NTFS_Unmount,
30 .GetNodeFromINode = NULL
32 tVFS_NodeType gNTFS_DirType = {
33 .TypeName = "NTFS-File",
34 .ReadDir = NTFS_ReadDir,
35 .FindDir = NTFS_FindDir,
39 tNTFS_Disk gNTFS_Disks;
43 * \brief Installs the NTFS driver
45 int NTFS_Install(char **Arguments)
47 VFS_AddDriver( &gNTFS_FSInfo );
52 * \brief Mount a NTFS volume
54 tVFS_Node *NTFS_InitDevice(const char *Device, const char **Options)
59 disk = malloc( sizeof(tNTFS_Disk) );
61 disk->FD = VFS_Open(Device, VFS_OPENFLAG_READ);
67 Log_Debug("FS_NTFS", "&bs = %p", &bs);
68 VFS_ReadAt(disk->FD, 0, 512, &bs);
70 Log_Debug("FS_NTFS", "Jump = %02x%02x%02x",
74 Log_Debug("FS_NTFS", "SystemID = %02x%02x%02x%02x%02x%02x%02x%02x (%8C)",
75 bs.SystemID[0], bs.SystemID[1], bs.SystemID[2], bs.SystemID[3],
76 bs.SystemID[4], bs.SystemID[5], bs.SystemID[6], bs.SystemID[7],
79 Log_Debug("FS_NTFS", "BytesPerSector = %i", bs.BytesPerSector);
80 Log_Debug("FS_NTFS", "SectorsPerCluster = %i", bs.SectorsPerCluster);
81 Log_Debug("FS_NTFS", "MediaDescriptor = 0x%x", bs.MediaDescriptor);
82 Log_Debug("FS_NTFS", "SectorsPerTrack = %i", bs.SectorsPerTrack);
83 Log_Debug("FS_NTFS", "Heads = %i", bs.Heads);
84 Log_Debug("FS_NTFS", "TotalSectorCount = 0x%llx", bs.TotalSectorCount);
85 Log_Debug("FS_NTFS", "MFTStart = 0x%llx", bs.MFTStart);
86 Log_Debug("FS_NTFS", "MFTMirrorStart = 0x%llx", bs.MFTMirrorStart);
87 Log_Debug("FS_NTFS", "ClustersPerMFTRecord = %i", bs.ClustersPerMFTRecord);
88 Log_Debug("FS_NTFS", "ClustersPerIndexRecord = %i", bs.ClustersPerIndexRecord);
89 Log_Debug("FS_NTFS", "SerialNumber = 0x%llx", bs.SerialNumber);
91 disk->ClusterSize = bs.BytesPerSector * bs.SectorsPerCluster;
92 Log_Debug("NTFS", "Cluster Size = %i KiB", disk->ClusterSize/1024);
93 disk->MFTBase = bs.MFTStart;
94 Log_Debug("NTFS", "MFT Base = %i", disk->MFTBase);
95 Log_Debug("NTFS", "TotalSectorCount = 0x%x", bs.TotalSectorCount);
97 if( bs.ClustersPerMFTRecord < 0 ) {
98 disk->MFTRecSize = 1 << (-bs.ClustersPerMFTRecord);
101 disk->MFTRecSize = bs.ClustersPerMFTRecord * disk->ClusterSize;
104 disk->RootNode.Inode = 5; // MFT Ent #5 is filesystem root
105 disk->RootNode.ImplPtr = disk;
107 disk->RootNode.UID = 0;
108 disk->RootNode.GID = 0;
110 disk->RootNode.NumACLs = 1;
111 disk->RootNode.ACLs = &gVFS_ACL_EveryoneRX;
113 disk->RootNode.Type = &gNTFS_DirType;
116 NTFS_DumpEntry(disk, 5);
118 return &disk->RootNode;
122 * \brief Unmount an NTFS Disk
124 void NTFS_Unmount(tVFS_Node *Node)
130 * \brief Dumps a MFT Entry
132 void NTFS_DumpEntry(tNTFS_Disk *Disk, Uint32 Entry)
134 void *buf = malloc( Disk->MFTRecSize );
135 tNTFS_FILE_Header *hdr = buf;
136 tNTFS_FILE_Attrib *attr;
140 Log_Warning("FS_NTFS", "malloc() fail!");
144 VFS_ReadAt( Disk->FD,
145 Disk->MFTBase * Disk->ClusterSize + Entry * Disk->MFTRecSize,
149 Log_Debug("FS_NTFS", "MFT Entry #%i", Entry);
150 Log_Debug("FS_NTFS", "- Magic = 0x%08x (%4C)", hdr->Magic, &hdr->Magic);
151 Log_Debug("FS_NTFS", "- UpdateSequenceOfs = 0x%x", hdr->UpdateSequenceOfs);
152 Log_Debug("FS_NTFS", "- UpdateSequenceSize = 0x%x", hdr->UpdateSequenceSize);
153 Log_Debug("FS_NTFS", "- LSN = 0x%x", hdr->LSN);
154 Log_Debug("FS_NTFS", "- SequenceNumber = %i", hdr->SequenceNumber);
155 Log_Debug("FS_NTFS", "- HardLinkCount = %i", hdr->HardLinkCount);
156 Log_Debug("FS_NTFS", "- FirstAttribOfs = 0x%x", hdr->FirstAttribOfs);
157 Log_Debug("FS_NTFS", "- Flags = 0x%x", hdr->Flags);
158 Log_Debug("FS_NTFS", "- RecordSize = 0x%x", hdr->RecordSize);
159 Log_Debug("FS_NTFS", "- RecordSpace = 0x%x", hdr->RecordSpace);
160 Log_Debug("FS_NTFS", "- Reference = 0x%llx", hdr->Reference);
161 Log_Debug("FS_NTFS", "- NextAttribID = 0x%04x", hdr->NextAttribID);
163 attr = (void*)( (char*)hdr + hdr->FirstAttribOfs );
165 while( (tVAddr)attr < (tVAddr)hdr + hdr->RecordSize )
167 if(attr->Type == 0xFFFFFFFF) break;
168 Log_Debug("FS_NTFS", "- Attribute %i", i ++);
169 Log_Debug("FS_NTFS", " > Type = 0x%x", attr->Type);
170 Log_Debug("FS_NTFS", " > Size = 0x%x", attr->Size);
171 Log_Debug("FS_NTFS", " > ResidentFlag = 0x%x", attr->ResidentFlag);
172 Log_Debug("FS_NTFS", " > NameLength = %i", attr->NameLength);
173 Log_Debug("FS_NTFS", " > NameOffset = 0x%x", attr->NameOffset);
174 Log_Debug("FS_NTFS", " > Flags = 0x%x", attr->Flags);
175 Log_Debug("FS_NTFS", " > AttributeID = 0x%x", attr->AttributeID);
176 if( !attr->ResidentFlag ) {
177 Log_Debug("FS_NTFS", " > AttribLen = 0x%x", attr->Resident.AttribLen);
178 Log_Debug("FS_NTFS", " > AttribOfs = 0x%x", attr->Resident.AttribOfs);
179 Log_Debug("FS_NTFS", " > IndexedFlag = 0x%x", attr->Resident.IndexedFlag);
180 Log_Debug("FS_NTFS", " > Name = '%*C'", attr->NameLength, attr->Resident.Name);
181 Debug_HexDump("FS_NTFS",
182 (void*)( (tVAddr)attr + attr->Resident.AttribOfs ),
183 attr->Resident.AttribLen
187 Log_Debug("FS_NTFS", " > StartingVCN = 0x%llx", attr->NonResident.StartingVCN);
188 Log_Debug("FS_NTFS", " > LastVCN = 0x%llx", attr->NonResident.LastVCN);
189 Log_Debug("FS_NTFS", " > DataRunOfs = 0x%x", attr->NonResident.DataRunOfs);
190 Log_Debug("FS_NTFS", " > CompressionUnitSize = 0x%x", attr->NonResident.CompressionUnitSize);
191 Log_Debug("FS_NTFS", " > AllocatedSize = 0x%llx", attr->NonResident.AllocatedSize);
192 Log_Debug("FS_NTFS", " > RealSize = 0x%llx", attr->NonResident.RealSize);
193 Log_Debug("FS_NTFS", " > InitiatedSize = 0x%llx", attr->NonResident.InitiatedSize);
194 Log_Debug("FS_NTFS", " > Name = '%*C'", attr->NameLength, attr->NonResident.Name);
197 attr = (void*)( (tVAddr)attr + attr->Size );