1/* 2 * Copyright 2003-2013, Axel D��rfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7#include "Volume.h" 8#include "Directory.h" 9 10#include <boot/partitions.h> 11#include <boot/platform.h> 12 13#include <string.h> 14#include <unistd.h> 15#include <fcntl.h> 16#include <stdio.h> 17#include <stdlib.h> 18 19 20using namespace FFS; 21using std::nothrow; 22 23 24Volume::Volume(boot::Partition *partition) 25 : 26 fRoot(NULL) 27{ 28 if ((fDevice = open_node(partition, O_RDONLY)) < B_OK) 29 return; 30 31 if (read_pos(fDevice, 0, &fType, sizeof(int32)) < B_OK) 32 return; 33 34 fType = B_BENDIAN_TO_HOST_INT32(fType); 35 36 switch (fType) { 37 case DT_AMIGA_FFS: 38 case DT_AMIGA_FFS_INTL: 39 case DT_AMIGA_FFS_DCACHE: 40 break; 41 42 case DT_AMIGA_OFS: 43 printf("The Amiga OFS is not yet supported.\n"); 44 return; 45 default: 46 // unsupported file system 47 //printf("amiga_ffs: unsupported: %08lx\n", fType); 48 return; 49 } 50 51 char *buffer = (char *)malloc(4096); 52 if (buffer == NULL) 53 return; 54 55 int32 blockSize = partition->block_size; 56 if (get_root_block(fDevice, buffer, blockSize, partition->size) != B_OK) { 57 // try to get the root block at different sizes, if the 58 // block size was incorrectly passed from the partitioning 59 // system 60 for (int32 size = 512; size <= 4096; size <<= 1) { 61 if (get_root_block(fDevice, buffer, size, partition->size) == B_OK) { 62 blockSize = size; 63 break; 64 } else if (size >= 4096) { 65 puts("Could not find root block\n"); 66 free(buffer); 67 return; 68 } 69 } 70 } 71 72 char *newBuffer = (char *)realloc(buffer, blockSize); 73 // if reallocation fails, we keep the old buffer 74 if (newBuffer != NULL) 75 buffer = newBuffer; 76 77 fRootNode.SetTo(buffer, blockSize); 78 fRoot = new(nothrow) Directory(*this, fRootNode); 79 // fRoot will free the buffer for us upon destruction 80} 81 82 83Volume::~Volume() 84{ 85 delete fRoot; 86 close(fDevice); 87} 88 89 90status_t 91Volume::InitCheck() 92{ 93 if (fRoot != NULL) 94 return fRootNode.ValidateCheckSum(); 95 96 return B_ERROR; 97} 98 99 100// #pragma mark - 101 102 103float 104amiga_ffs_identify_file_system(boot::Partition *partition) 105{ 106 Volume volume(partition); 107 108 return volume.InitCheck() < B_OK ? 0 : 0.8; 109} 110 111 112static status_t 113amiga_ffs_get_file_system(boot::Partition *partition, ::Directory **_root) 114{ 115 Volume *volume = new(nothrow) Volume(partition); 116 if (volume == NULL) 117 return B_NO_MEMORY; 118 119 if (volume->InitCheck() < B_OK) { 120 delete volume; 121 return B_ERROR; 122 } 123 124 *_root = volume->Root(); 125 return B_OK; 126} 127 128 129file_system_module_info gAmigaFFSFileSystemModule = { 130 "file_systems/amiga_ffs/v1", 131 kPartitionTypeAmigaFFS, 132 amiga_ffs_identify_file_system, 133 amiga_ffs_get_file_system 134}; 135 136