summaryrefslogtreecommitdiff
path: root/src/ntfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ntfs.c')
-rw-r--r--src/ntfs.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/src/ntfs.c b/src/ntfs.c
new file mode 100644
index 0000000..28b4cca
--- /dev/null
+++ b/src/ntfs.c
@@ -0,0 +1,122 @@
+//
+// AUTHOR
+// N. Nielsen
+//
+// VERSION
+// 0.7
+//
+// LICENSE
+// This software is in the public domain.
+//
+// The software is provided "as is", without warranty of any kind,
+// express or implied, including but not limited to the warranties
+// of merchantability, fitness for a particular purpose, and
+// noninfringement. In no event shall the author(s) be liable for any
+// claim, damages, or other liability, whether in an action of
+// contract, tort, or otherwise, arising from, out of, or in connection
+// with the software or the use or other dealings in the software.
+//
+// SUPPORT
+// Send bug reports to: <nielsen@memberwebs.com>
+//
+
+
+#include "usuals.h"
+#include "ntfs.h"
+
+#include "malloc.h"
+#include "string.h"
+
+
+NTFS_AttribHeader* NTFS_SearchAttribute(byte* pLocation, uint32 attrType, void* pEnd, bool bSkip)
+{
+ // Now we should be at attributes
+ while((!pEnd || (pLocation + sizeof(NTFS_AttribHeader) < pEnd)) &&
+ *((uint32*)pLocation) != kNTFS_RecEnd)
+ {
+ NTFS_AttribHeader* pAttrib = (NTFS_AttribHeader*)pLocation;
+
+ if(!bSkip)
+ {
+ if(pAttrib->type == attrType)
+ return pAttrib;
+ }
+ else
+ bSkip = false;
+
+ pLocation += pAttrib->cbAttribute;
+ }
+
+ return NULL;
+}
+
+
+NTFS_AttribHeader* NTFS_FindAttribute(NTFS_RecordHeader* pRecord, uint32 attrType, void* pEnd)
+{
+ byte* pLocation = (byte*)pRecord;
+ pLocation += kNTFS_RecHeaderLen;
+
+ return NTFS_SearchAttribute(pLocation, attrType, pEnd, false);
+}
+
+NTFS_AttribHeader* NTFS_NextAttribute(NTFS_AttribHeader* pAttrib, uint32 attrType, void* pEnd)
+{
+ return NTFS_SearchAttribute((byte*)pAttrib, attrType, pEnd, true);
+}
+
+void* NTFS_GetAttributeData(NTFS_AttribResident* pAttrib, void* pEnd)
+{
+ void* pData = ((byte*)pAttrib) + pAttrib->offAttribData;
+ if(!pEnd && pData > pEnd)
+ return NULL;
+
+ return pData;
+}
+
+bool NTFS_IsBetterNameSpace(byte n1, byte n2)
+{
+ // We like our namespaces in this order
+ // 1. WIN32
+ // 2. WIN32/DOS
+ // 3. DOS
+ // 4. POSIX
+
+ if(n1 == kNTFS_NameSpacePOSIX)
+ return true;
+ if(n1 == kNTFS_NameSpaceDOS &&
+ (n2 == kNTFS_NameSpaceWIN32 || n2 == kNTFS_NameSpaceWINDOS))
+ return true;
+ if(n1 == kNTFS_NameSpaceWINDOS &&
+ n2 == kNTFS_NameSpaceWIN32)
+ return true;
+
+ return false;
+}
+
+bool NTFS_DoFixups(byte* pCluster, uint32 cbCluster)
+{
+ ASSERT(cbCluster % kSectorSize == 0);
+ NTFS_RecordHeader* pRecord = (NTFS_RecordHeader*)pCluster;
+
+ byte numSectors = (byte)(cbCluster / kSectorSize);
+
+ // Check the number of sectors against array
+ if(pRecord->cwUpdSeq - 1 < numSectors)
+ numSectors = pRecord->cwUpdSeq - 1;
+
+ uint16* pUpdSeq = (uint16*)(pCluster + pRecord->offUpdSeq);
+
+ for(byte i = 0; i < numSectors; i++)
+ {
+ // Check last 2 bytes in each sector against
+ // first double byte value in update sequence
+ uint16* pSectorFooter = (uint16*)((pCluster + (kSectorSize - 2)) + (i * kSectorSize));
+ if(*pSectorFooter == pUpdSeq[0])
+ *pSectorFooter = pUpdSeq[i + 1];
+ else
+ return false;
+ }
+
+ return true;
+}
+