:: commit c74c36440a4522439ef1b2afd7fb4e916209fd41

Itay Almog <itay2828@gmail.com> — 2022-01-21 15:01

parents: 35d522d388

added support for resident files, this should pretty much complete a basic support for NTFS

diff --git a/stage23/fs/ntfs.h b/stage23/fs/ntfs.h
index 46ab9d48..6d03db69 100644
--- a/stage23/fs/ntfs.h
+++ b/stage23/fs/ntfs.h
@@ -42,12 +42,18 @@ struct ntfs_file_handle {
     uint64_t mft_offset;
     uint8_t mft_run_list[256];
 
-    // the runlist, resident index and attribute list of the 
-    // current open file/directory
+    // the runlist of the open file/directory
     uint8_t run_list[128];
+
+    // The resident index, only for directories,
+    // could be at the same time as a runlist
     uint8_t resident_index_size;
     uint8_t resident_index[256];
 
+    // the resident data 
+    uint8_t resident_data_size;
+    uint8_t resident_data[256];
+
     // info about the current file
     uint32_t size_bytes;
 };
diff --git a/stage23/fs/ntfs.s2.c b/stage23/fs/ntfs.s2.c
index 31fcefeb..c4c9b51f 100644
--- a/stage23/fs/ntfs.s2.c
+++ b/stage23/fs/ntfs.s2.c
@@ -571,16 +571,33 @@ bool ntfs_open(struct ntfs_file_handle *ret, struct volume *part, const char *pa
             uint8_t *attr_ptr = NULL;
             if (!ntfs_get_file_record_attr(file_record_buffer, FR_ATTRIBUTE_DATA, &attr_ptr))
                 panic(false, "NTFS: File record missing DATA attribute");
-            struct file_record_attr_header_non_res *attr = (struct file_record_attr_header_non_res *)attr_ptr;
+            struct file_record_attr_header *attr_hdr = (struct file_record_attr_header *)attr_ptr;
+            
+            if (attr_hdr->non_res_flag) {
+                // this is non-resident data
+                struct file_record_attr_header_non_res *attr = (struct file_record_attr_header_non_res *)attr_ptr;
+
+                // mark that this has no resident data
+                ret->resident_index_size = 0;
+
+                // verify the attr and run list are in the buffer
+                if ((uint8_t *)attr + sizeof(*attr) > file_record_buffer + sizeof(file_record_buffer))
+                    panic(false, "NTFS: File record attribute is outside of file record");
+                if ((uint8_t *)attr + attr->run_offset + 256 > file_record_buffer + sizeof(file_record_buffer))
+                    panic(false, "NTFS: Run list is outside of file record");
+
+                // save the run list
+                memcpy(ret->run_list, (uint8_t *)attr + attr->run_offset, sizeof(ret->run_list));
+            } else {
+                // this is resident data
+                struct file_record_attr_header_res *attr = (struct file_record_attr_header_res *)attr_ptr;
 
-            // verify the attr and run list are in the buffer
-            if ((uint8_t *)attr + sizeof(*attr) > file_record_buffer + sizeof(file_record_buffer))
-                panic(false, "NTFS: File record attribute is outside of file record");
-            if ((uint8_t *)attr + attr->run_offset + 256 > file_record_buffer + sizeof(file_record_buffer))
-                panic(false, "NTFS: Run list is outside of file record");
+                if (attr->info_length > sizeof(ret->resident_data))
+                    panic(false, "NTFS: Resident data too big");
 
-            // save the run list
-            memcpy(ret->run_list, (uint8_t *)attr + attr->run_offset, sizeof(ret->run_list));
+                ret->resident_data_size = attr->info_length;
+                memcpy(ret->resident_data, attr + 1, attr->info_length);
+            }
 
             return true;
 
@@ -602,6 +619,23 @@ int ntfs_read(struct ntfs_file_handle *file, void *buf, uint64_t loc, uint64_t c
     // get the runlist
     uint8_t *runlist = file->run_list;
 
+    // first try and handle resident data
+    if (file->resident_data_size != 0) {
+        // check bounds
+        if (loc > file->resident_data_size)
+            return 0;
+        
+        // truncate the size 
+        if (file->resident_data_size - loc < count) {
+            count = file->resident_data_size - loc;
+        }
+
+        // copy it 
+        memcpy(buf, &file->resident_data[loc], count);
+        
+        return count;
+    }
+
     // TODO: remember the last read location so we can have faster sequential reads...
 
     // we are going to go over the runlist until we get to the offset
tab: 248 wrap: offon