| /* |
| asfs.c -- parted asfs filesystem support |
| Copyright (C) 1998-2000, 2007 Free Software Foundation, Inc. |
| |
| This program is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 2 of the License, or |
| (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program; if not, write to the Free Software |
| Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. |
| */ |
| |
| #include <config.h> |
| |
| #include <parted/parted.h> |
| #include <parted/debug.h> |
| #include <parted/endian.h> |
| |
| #include "amiga.h" |
| #include "asfs.h" |
| |
| #if ENABLE_NLS |
| # include <libintl.h> |
| # define _(String) dgettext (PACKAGE, String) |
| #else |
| # define _(String) (String) |
| #endif /* ENABLE_NLS */ |
| |
| static int |
| _asfs_probe_root (PedGeometry *geom, uint32_t *block, int blocksize, PedSector root) { |
| int i, sum; |
| PedSector start, end; |
| |
| if (PED_BE32_TO_CPU (block[0]) != 0x53465300) return 0; |
| for (i = 0, sum = 1; i < 128*blocksize; i++) sum += PED_BE32_TO_CPU (block[i]); |
| if (sum != 0) return 0; |
| if (PED_BE32_TO_CPU (block[2]) * blocksize + geom->start != root) { |
| return 0; |
| } |
| start = ((((PedSector) PED_BE32_TO_CPU (block[8])) << 32) |
| + (PedSector) PED_BE32_TO_CPU (block[9])) / 512; |
| end = (((((PedSector) PED_BE32_TO_CPU (block[10])) << 32) |
| + (PedSector) PED_BE32_TO_CPU (block[11])) / 512) - 1; |
| if (start != geom->start || end != geom->end) return 0; |
| return 1; |
| } |
| |
| static PedGeometry* |
| _asfs_probe (PedGeometry* geom) |
| { |
| uint32_t *block; |
| struct PartitionBlock * part; |
| int blocksize = 1, reserved = 1, prealloc = 1; |
| PedSector root; |
| int found = 0; |
| |
| PED_ASSERT (geom != NULL, return NULL); |
| PED_ASSERT (geom->dev != NULL, return NULL); |
| |
| /* Finds the blocksize, prealloc and reserved values of the partition block */ |
| if (!(part = ped_malloc (PED_SECTOR_SIZE_DEFAULT*blocksize))) { |
| ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, |
| _("%s : Failed to allocate partition block\n"), __func__); |
| goto error_part; |
| } |
| if (amiga_find_part(geom, part) != NULL) { |
| prealloc = PED_BE32_TO_CPU (part->de_PreAlloc) == 0 ? |
| 1 : PED_BE32_TO_CPU (part->de_PreAlloc); |
| reserved = PED_BE32_TO_CPU (part->de_Reserved) == 0 ? |
| 1 : PED_BE32_TO_CPU (part->de_Reserved); |
| blocksize = PED_BE32_TO_CPU (part->de_SizeBlock) |
| * PED_BE32_TO_CPU (part->de_SectorPerBlock) / 128; |
| } |
| ped_free (part); |
| |
| /* Test boot block */ |
| if (!(block = ped_malloc (PED_SECTOR_SIZE_DEFAULT*blocksize))) { |
| ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, |
| _("%s : Failed to allocate block\n"), __func__); |
| goto error_block; |
| } |
| root = geom->start; |
| if (!ped_device_read (geom->dev, block, root, blocksize)) { |
| ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, |
| _("%s : Couldn't read root block %llu\n"), __func__, root); |
| goto error; |
| } |
| if (PED_BE32_TO_CPU (block[0]) != 0x53465300) { |
| goto error; |
| } |
| |
| /* Find and test the root blocks */ |
| if (_asfs_probe_root(geom, block, blocksize, root)) { |
| found++; |
| } |
| root = geom->end - blocksize - (geom->length % blocksize) + 1; |
| if (!ped_device_read (geom->dev, block, root, 1)) { |
| ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL, |
| _("%s : Couldn't read root block %llu\n"), __func__, root); |
| goto error; |
| } |
| if (_asfs_probe_root(geom, block, blocksize, root)) { |
| found++; |
| } |
| if (found != 0) { |
| ped_free (block); |
| return ped_geometry_duplicate (geom); |
| } |
| |
| error: |
| ped_free (block); |
| error_block: |
| error_part: |
| return NULL; |
| } |
| |
| static PedFileSystemOps _asfs_ops = { |
| probe: _asfs_probe, |
| clobber: NULL, |
| open: NULL, |
| create: NULL, |
| close: NULL, |
| check: NULL, |
| resize: NULL, |
| copy: NULL, |
| get_create_constraint: NULL, |
| get_copy_constraint: NULL, |
| get_resize_constraint: NULL |
| }; |
| |
| PedFileSystemType _asfs_type = { |
| next: NULL, |
| ops: &_asfs_ops, |
| name: "asfs", |
| block_sizes: ((int[2]){512, 0}) |
| }; |