vfs: check userland buffers before reading them.
[haiku.git] / src / system / boot / loader / file_systems / amiga_ffs / Volume.cpp
blob996d2a1173a2fedcac3d4f799ff9068b60ed1845
1 /*
2 * Copyright 2003-2013, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
4 */
7 #include "Volume.h"
8 #include "Directory.h"
10 #include <boot/partitions.h>
11 #include <boot/platform.h>
13 #include <string.h>
14 #include <unistd.h>
15 #include <fcntl.h>
16 #include <stdio.h>
17 #include <stdlib.h>
20 using namespace FFS;
21 using std::nothrow;
24 Volume::Volume(boot::Partition *partition)
26 fRoot(NULL)
28 if ((fDevice = open_node(partition, O_RDONLY)) < B_OK)
29 return;
31 if (read_pos(fDevice, 0, &fType, sizeof(int32)) < B_OK)
32 return;
34 fType = B_BENDIAN_TO_HOST_INT32(fType);
36 switch (fType) {
37 case DT_AMIGA_FFS:
38 case DT_AMIGA_FFS_INTL:
39 case DT_AMIGA_FFS_DCACHE:
40 break;
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;
51 char *buffer = (char *)malloc(4096);
52 if (buffer == NULL)
53 return;
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;
72 char *newBuffer = (char *)realloc(buffer, blockSize);
73 // if reallocation fails, we keep the old buffer
74 if (newBuffer != NULL)
75 buffer = newBuffer;
77 fRootNode.SetTo(buffer, blockSize);
78 fRoot = new(nothrow) Directory(*this, fRootNode);
79 // fRoot will free the buffer for us upon destruction
83 Volume::~Volume()
85 delete fRoot;
86 close(fDevice);
90 status_t
91 Volume::InitCheck()
93 if (fRoot != NULL)
94 return fRootNode.ValidateCheckSum();
96 return B_ERROR;
100 // #pragma mark -
103 float
104 amiga_ffs_identify_file_system(boot::Partition *partition)
106 Volume volume(partition);
108 return volume.InitCheck() < B_OK ? 0 : 0.8;
112 static status_t
113 amiga_ffs_get_file_system(boot::Partition *partition, ::Directory **_root)
115 Volume *volume = new(nothrow) Volume(partition);
116 if (volume == NULL)
117 return B_NO_MEMORY;
119 if (volume->InitCheck() < B_OK) {
120 delete volume;
121 return B_ERROR;
124 *_root = volume->Root();
125 return B_OK;
129 file_system_module_info gAmigaFFSFileSystemModule = {
130 "file_systems/amiga_ffs/v1",
131 kPartitionTypeAmigaFFS,
132 amiga_ffs_identify_file_system,
133 amiga_ffs_get_file_system