From 09cc114845e38cfcf9aa78e237d959ec57b93b60 Mon Sep 17 00:00:00 2001 From: Joshua Bell Date: Mon, 22 Jul 2024 08:33:40 -0700 Subject: [PATCH] ADDFILE should never make first block sparse When checking if a file block can be sparse (i.e. not actually allocated on disk), ensure the test always fails for the first block of the file, as this would violate the ProDOS file system specification, and makes ProDOS-8 unhappy. Additionally, when loading a volume, log if files are encountered that have sparse first blocks. https://github.com/mach-kernel/cadius/issues/42 --- Src/Dc_Prodos.c | 9 +++++++++ Src/Prodos_Add.c | 16 ++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Src/Dc_Prodos.c b/Src/Dc_Prodos.c index c979036..2436167 100644 --- a/Src/Dc_Prodos.c +++ b/Src/Dc_Prodos.c @@ -1090,6 +1090,9 @@ static int GetFileDataResourceSize(struct prodos_image *current_image, struct fi if(tab_block[i] == 0) file_entry->nb_sparse++; + if(tab_block[0] == 0) + logf_error(" Warning : Block 0 is sparse in file: '%s'.\n", file_entry->file_path); + /* Table des blocs utilisés */ file_entry->tab_used_block = BuildUsedBlockTable(nb_block,tab_block,nb_index_block,tab_index_block,&file_entry->nb_used_block); if(file_entry->tab_used_block == NULL) @@ -1180,6 +1183,9 @@ static int GetFileDataResourceSize(struct prodos_image *current_image, struct fi if(tab_block[i] == 0) file_entry->nb_sparse++; + if(tab_block[0] == 0) + logf_error(" Warning : Block 0 is sparse in data fork of file: '%s'.\n", file_entry->file_path); + /* Table des blocs utilisés (Data) */ tab_used_block_data = BuildUsedBlockTable(nb_block,tab_block,nb_index_block,tab_index_block,&nb_used_block_data); if(tab_used_block_data == NULL) @@ -1250,6 +1256,9 @@ static int GetFileDataResourceSize(struct prodos_image *current_image, struct fi if(tab_block[i] == 0) file_entry->nb_sparse++; + if(tab_block[0] == 0) + logf_error(" Warning : Block 0 is sparse in resource fork of file: '%s'.\n", file_entry->file_path); + /* Table des blocs utilisés (Resource) */ tab_used_block_resource = BuildUsedBlockTable(nb_block,tab_block,nb_index_block,tab_index_block,&nb_used_block_resource); if(tab_used_block_resource == NULL) diff --git a/Src/Prodos_Add.c b/Src/Prodos_Add.c index 483669c..5028640 100644 --- a/Src/Prodos_Add.c +++ b/Src/Prodos_Add.c @@ -565,7 +565,9 @@ static void ComputeFileBlockUsage(struct prodos_file *current_file) for(i=0; idata_length; i+=BLOCK_SIZE) { /* Recherche les plages de 0 */ - if(i+BLOCK_SIZE <= current_file->data_length) + if(i == 0) + result = 1; /* Block 0 ne doit pas être Sparse */ + else if(i+BLOCK_SIZE <= current_file->data_length) result = memcmp(¤t_file->data[i],empty_block,BLOCK_SIZE); else result = memcmp(¤t_file->data[i],empty_block,current_file->data_length-i); @@ -586,7 +588,9 @@ static void ComputeFileBlockUsage(struct prodos_file *current_file) for(i=0; iresource_length; i+=BLOCK_SIZE) { /* Recherche les plages de 0 */ - if(i+BLOCK_SIZE <= current_file->resource_length) + if(i == 0) + result = 1; /* Block 0 ne doit pas être Sparse */ + else if(i+BLOCK_SIZE <= current_file->resource_length) result = memcmp(¤t_file->resource[i],empty_block,BLOCK_SIZE); else result = memcmp(¤t_file->resource[i],empty_block,current_file->resource_length-i); @@ -883,7 +887,9 @@ static WORD CreateSaplingContent(struct prodos_image *current_image, struct prod for(i=0,j=1,k=0; i