pmt: revert 7f8090b
This commit is contained in:
@@ -1,92 +0,0 @@
|
||||
WARNING : Both HFS and HFS+ implementations of Linux 2.4 are buggy, at
|
||||
least when used before or after this implementation. Some workarounds
|
||||
are used in this implementation, but there can still be incompatibilities.
|
||||
Try Linux 2.6 if you want to play with HFS(+) resizing (though some bugs
|
||||
might also be there in 2.6, there is of course no warranty)
|
||||
|
||||
---
|
||||
|
||||
Technical doc about Apple HFS and HFS+ file systems is available at :
|
||||
* For HFS, section "Data Organization on Volumes",
|
||||
"Chapter 2 - File Manager"
|
||||
of the book "Inside Macintosh: Files"
|
||||
http://developer.apple.com/documentation/mac/Files/Files-99.html
|
||||
* For HFS+, "Technical Note TN1150", "HFS Plus Volume Format"
|
||||
http://developer.apple.com/technotes/tn/tn1150.html
|
||||
|
||||
Some useful HFS precisions concerning alignement, bit ordering, and
|
||||
order of fields for extent key comparaisons are only in the HFS+ TN
|
||||
|
||||
These Apple Creator Codes are reserved for us :
|
||||
Shnk traP GP16 GnuP PH+x Xpnd Resz GP17 GP18 GP19 GP20
|
||||
|
||||
---
|
||||
|
||||
* Cache design *
|
||||
|
||||
Versions before HFS Patch 15 were very slow when data relocation was needed,
|
||||
because every extent to relocate involved scanning the whole file system,
|
||||
looking for a reference to its physical position on the volume (this was a
|
||||
dummy algorithm, I know :)
|
||||
|
||||
HFS Patch 16 introduced a cache that allows to efficiently retrieve the place
|
||||
of the reference in the file system given the physical position of an extent.
|
||||
The cache is designed for : - efficiency
|
||||
- scaling
|
||||
- simplicity
|
||||
- avoiding memory allocation while resizing
|
||||
|
||||
This cache involves quite big worst case memory consumption, but without it
|
||||
the time needed to complete the operation in the worst case would be huge
|
||||
anyway (maybe several years...) so this isn't really an issue. The cache size
|
||||
is nearly proportional to the number of files you have, or if you have very few
|
||||
files, to the size of your volume, so worst cases situations occure when you
|
||||
fill a drive with millions of < 4 ko files :p For this very special usage you
|
||||
will just need a very special amount of RAM (on typical systems about
|
||||
(FS size) / 256 )... On a more "normal" volume it's about
|
||||
(# of files) * 20 bytes. With very few files it's about (FS Size) / 1024 / 256.
|
||||
|
||||
At the beginning of the resize process, the cache is filed by scanning the FS.
|
||||
The position of each extent is cut into 2 parts : high order is used as
|
||||
an index into a table of pointer to a linked list which contains :
|
||||
- the next ptr (sizeof struct *)
|
||||
- the extent start (4 bytes)
|
||||
- the extent size (4 bytes)
|
||||
- number of BTree block or 0 if in prim (4 bytes)
|
||||
- offset of the extent start reference
|
||||
from the block beginning (2 bytes)
|
||||
- sectors by BTree block, or
|
||||
1 for VH/MDB (1 byte)
|
||||
- FS special file / primary structure
|
||||
where the extent reference is stored (1 byte)
|
||||
(3 bits for the extent index, 5 for
|
||||
the actual ref)
|
||||
|
||||
0 : dont exists --- reserved
|
||||
1 : mdb / vh : catalog ---
|
||||
2 : mdb / vh : extent ---
|
||||
3 : vh : attributes X+-
|
||||
4 : vh : allocation X+-
|
||||
5 : vh : startup X+-
|
||||
6 : catalog ---
|
||||
7 : attributes X+-
|
||||
8 : extent (nothing to update) ---
|
||||
9 : extent (update catalog) ---
|
||||
10 : extent (update extent !?!) --- should not exist
|
||||
11 : extent (update attributes) X+-
|
||||
12 : extent (update allocation) X+-
|
||||
13 : extent (update startup) X+- reserved
|
||||
14 : vh : journal info block X+J
|
||||
15 : jib: journal X+J
|
||||
16 - 31 : ---
|
||||
|
||||
mdb : Master Directory Block
|
||||
vh : Volume Header
|
||||
X+ : HFSX or HFS+ only
|
||||
J : Journaled only
|
||||
|
||||
Large amount of memory is allocated at once (first enough memory to fit
|
||||
every files if there isn't any fragmentation +6.25%, then this value / 4,
|
||||
if this wasn't enough). On a typical FS, the first allocation should be enough.
|
||||
|
||||
---
|
||||
@@ -1,115 +0,0 @@
|
||||
## modifications dd-mm-yyyy
|
||||
---------------------- PATCH FOR PARTED 1.6.5 ----------------------------
|
||||
1 initial revision 07-04-2003
|
||||
2 one pass resizing, removal of debug info 08-04-2003
|
||||
3 safe abort if resize failed, code cleanups, timer, 10-04-2003
|
||||
source file split, won't resize if not unmounted,
|
||||
only relocate data if needed, minimize disk operations
|
||||
4 memory leaks removal, code cleanups, resize hfs+ code, 17-04-2003
|
||||
more checks, minor hfs resize bugfix, probe code
|
||||
returns real geometry
|
||||
5 hfs+ resize bugfixes : 19-04-2003
|
||||
* fragmented fs could be corrupted
|
||||
* VH wasn't written on error during alloc map writing
|
||||
* attributes file could be corrupted
|
||||
6 Use PedSector to be able to use 2To+ HD 23-04-2003
|
||||
Minor probe bugfix, Cleanups, HFS+ Timer tuning,
|
||||
7 80 columns indentation 23-04-2003
|
||||
8 Bugfix free blocks calculation in wrapper
|
||||
(makes Mac OS boot !) 28-04-2003
|
||||
---------------------- PATCH FOR PARTED 1.6.6 ----------------------------
|
||||
9 Don't destroy the file being worked on in case of
|
||||
interruption of Parted 28-10-2003
|
||||
---------------------- PATCH FOR PARTED 1.6.10 ---------------------------
|
||||
10 Regression tests, URL correction, In effect_move_extent :
|
||||
corrected memory leak & corrected a bug in precondition checks
|
||||
Added error messages, Check ped_alloc results
|
||||
Use macro for test / set / clear in the allocation bitmap
|
||||
Light probe correction, Check return value of get_empty_end
|
||||
Moved dynamic memory allocation out of effect_move_extent
|
||||
Check HFS+ version, Set implementation creator code
|
||||
Check journal absence, Corrected a bug in HFS+ block number
|
||||
calculation 24-04-2004
|
||||
--------------------- PATCH FOR PARTED 1.6.11 ----------------------------
|
||||
11-Some pointer dereference moved after non nul assertion
|
||||
-Error messages for HFS(+) file IO
|
||||
-Memory leak correction in hfs(plus)_read_bad_blocks
|
||||
-Mark out of volume blocks as used
|
||||
(improve compatibility with broken HFS+ Linux
|
||||
implementation)
|
||||
WARNING : this fix is not 100% tn1150 compatible :
|
||||
"The allocation file may be larger than the minimum
|
||||
number of bits required for the given volume size.
|
||||
Any unused bits in the bitmap must be set to _zero_."
|
||||
Anyway neither is the Linux implementation, nor was my
|
||||
previous implementations
|
||||
Maybe I should ask Apple to change the specifications
|
||||
-HISTORY, DOC and TODO files 29-04-2004
|
||||
12 Corrected a bug in hfsplus_volume_resize : size of alloc
|
||||
bitmap could be miscalculated 29-04-2004
|
||||
--------------------- PATCH FOR PARTED 1.6.12 ----------------------------
|
||||
13-Finally partial rewrite of *_search_move_*
|
||||
Easier to maintain and prepare for extent search and
|
||||
relocation algorithm changes for better ones.
|
||||
-"An extent has not been relocated!" message now only when
|
||||
relocation requested
|
||||
-Slightly better and simpler relocation algorithm
|
||||
-Update of Makefile.in and Makefile.am in fs_hfs
|
||||
-Sign correction for some 8bits HFS integers
|
||||
-Added the option --enable-hfs-extract-fs in 'configure'
|
||||
-Added every ped_geometry_sync where needed
|
||||
-Bugfix : "A root node does not need to exist
|
||||
(if the tree is empty)."
|
||||
- now handled correctly in btree_search
|
||||
-Bugfix : failure wasn't detected in some cases
|
||||
during 2 pass relocation (*_search_move_*)
|
||||
-Bugfix : The extent key comparaison was done in a wrong order
|
||||
and a pad field was used during the comparaison
|
||||
-Bugfix : in hfs_file_find_sector and hfsplus_file_find_sector
|
||||
the absolute position of a file sector could be
|
||||
miscalculated in case of fragmentation, resulting
|
||||
in potential data corruption, or various errors
|
||||
-Bugfix : The end of the HFS bitmap compatibility block was
|
||||
miscalculated ( (1<<16)/8 instead of (1<<16) )
|
||||
in hfs_resize
|
||||
07-09-2004
|
||||
--------------------- PATCH FOR PARTED 1.6.14 ----------------------------
|
||||
14 Port of Patch 13 for Parted 1.6.14 (update timestamps)
|
||||
08-09-2004
|
||||
--------------------- PATCH FOR PARTED 1.6.15 ----------------------------
|
||||
15-hfsplus_open : added a warning message if the "attributes"
|
||||
special file exists
|
||||
-hfsplus_open : added a test to check if the "allocation"
|
||||
special file has been correctly opened
|
||||
-optimisation of hfs+ block access : don't recalculate
|
||||
the address of each sector, and avoid checking the cache if
|
||||
obviously not useful
|
||||
( hfsplus_file_read && hfsplus_file_write
|
||||
&& hfsplus_file_find_extent && hfs_file_find_sector)
|
||||
-cut the "hfs.c" file in several parts
|
||||
-Bugfix: in hfsplus_do_move_primary, hfs_effect_move_extent
|
||||
was called instead of hfsplus_effect_move_extent !!!
|
||||
This could not produce data corruption, because of a welcome
|
||||
ASSERT in *_effect_move_extent that would detect the bug :)
|
||||
-Bugfix: in hfs_effect_move_extent, do
|
||||
PED_ASSERT(*ptr_to_fblock <= *ptr_fblock, return -1);
|
||||
instead of
|
||||
PED_ASSERT(*ptr_to_fblock < *ptr_fblock, return -1);
|
||||
and added that assertion to hfsplus_effect_move_extent
|
||||
-Bugfix: bugs introduced in rewrite of hfsplus_file_read
|
||||
&& hfsplus_file_write : last sector was incorrectly detected
|
||||
as out of file.
|
||||
-Cache the extent references (speed improvement ?)
|
||||
23-09-2004
|
||||
16-Bugfix: in hfsplus_do_move (reloc_plus.c), case CR_BTREE_EXT_ATTR
|
||||
incorrectly updated the cached part of priv_data->catalog_file
|
||||
instead of priv_data->attributes_file
|
||||
-Bugfix: in hfs_read_bad_blocks && hfsplus_read_bad_blocks,
|
||||
now generate an error if file_ID or type mismatch after the
|
||||
first pass
|
||||
Also check return value of ped_malloc
|
||||
-Bugfix: in hfsplus_btree_search, check return value of ped_malloc
|
||||
29-09-2004
|
||||
---------------- INTEGRATION IN PARTED 1.6.22 (cvs) ----------------------
|
||||
Futur changes will be described in ../../ChangeLog
|
||||
02-02-2005
|
||||
@@ -1,27 +0,0 @@
|
||||
--- TODO ---
|
||||
|
||||
* Continue to write regressions tests and try on 2.6 kernel -- (high)
|
||||
* Fix timer progression calculation, according to the new
|
||||
caching code -- (high)
|
||||
* write doc, website, ... -- (high)
|
||||
* Check block allocation in linux 2.4 and remove
|
||||
compatibility code if possible -- (high)
|
||||
|
||||
* In hfs(plus)_btree_search , use a static variable to detect
|
||||
illegal recursion and abort in that case. (find the right
|
||||
number of recursion before reporting bug) -- easy -- (medium)
|
||||
* Finish the HFS Extractor -- (medium)
|
||||
(add mdb & vh extraction, and maybe journal)
|
||||
|
||||
* Write code to allow enlarging and moving HFS[+x] -- (low)
|
||||
* Use a bitmap to internaly store the bad blocks -- (low)
|
||||
* Less bitmap saves ? -- (low)
|
||||
* Continue to change the relocation algorithm
|
||||
for a better one :) -- (low)
|
||||
|
||||
--- NOT todo ---
|
||||
|
||||
* debug HFS(+) Linux implementation (block allocation for HFS+,
|
||||
hard and sym links for HFS+, filename length for HFS, ...) -- (dont)
|
||||
/// Linux 2.6 contains HFS(+) implementations with less bugs
|
||||
/// Linux 2.4 should not be used anymore to access HFS(+)
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
libparted - a library for manipulating disk partitions
|
||||
Copyright (C) 2000, 2003-2005, 2007, 2009-2014, 2019-2023 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
Author : Guillaume Knispel <k_guillaume@libertysurf.fr>
|
||||
Report bug to <bug-parted@gnu.org>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <parted/parted.h>
|
||||
#include <parted/endian.h>
|
||||
#include <parted/debug.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(String) dgettext (PACKAGE, String)
|
||||
#else
|
||||
# define _(String) (String)
|
||||
#endif /* ENABLE_NLS */
|
||||
|
||||
#include "hfs.h"
|
||||
#include "probe.h"
|
||||
|
||||
uint8_t* hfs_block = NULL;
|
||||
uint8_t* hfsp_block = NULL;
|
||||
unsigned hfs_block_count;
|
||||
unsigned hfsp_block_count;
|
||||
|
||||
static PedFileSystemOps hfs_ops = {
|
||||
probe: hfs_probe,
|
||||
};
|
||||
|
||||
static PedFileSystemOps hfsplus_ops = {
|
||||
probe: hfsplus_probe,
|
||||
};
|
||||
|
||||
static PedFileSystemOps hfsx_ops = {
|
||||
probe: hfsx_probe,
|
||||
};
|
||||
|
||||
|
||||
static PedFileSystemType hfs_type = {
|
||||
next: NULL,
|
||||
ops: &hfs_ops,
|
||||
name: "hfs",
|
||||
};
|
||||
|
||||
static PedFileSystemType hfsplus_type = {
|
||||
next: NULL,
|
||||
ops: &hfsplus_ops,
|
||||
name: "hfs+",
|
||||
};
|
||||
|
||||
static PedFileSystemType hfsx_type = {
|
||||
next: NULL,
|
||||
ops: &hfsx_ops,
|
||||
name: "hfsx",
|
||||
};
|
||||
|
||||
void
|
||||
ped_file_system_hfs_init ()
|
||||
{
|
||||
ped_file_system_type_register (&hfs_type);
|
||||
ped_file_system_type_register (&hfsplus_type);
|
||||
ped_file_system_type_register (&hfsx_type);
|
||||
}
|
||||
|
||||
void
|
||||
ped_file_system_hfs_done ()
|
||||
{
|
||||
ped_file_system_type_unregister (&hfs_type);
|
||||
ped_file_system_type_unregister (&hfsplus_type);
|
||||
ped_file_system_type_unregister (&hfsx_type);
|
||||
}
|
||||
@@ -1,648 +0,0 @@
|
||||
/*
|
||||
libparted - a library for manipulating disk partitions
|
||||
Copyright (C) 2003-2005, 2007, 2009-2014, 2019-2023 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _HFS_H
|
||||
#define _HFS_H
|
||||
|
||||
/* WARNING : bn is used 2 times in theses macro */
|
||||
/* so _never_ use side effect operators when using them */
|
||||
#define TST_BLOC_OCCUPATION(tab,bn) \
|
||||
(((tab)[(bn)/8]) & (1<<(7-((bn)&7))))
|
||||
#define SET_BLOC_OCCUPATION(tab,bn) \
|
||||
(((tab)[(bn)/8]) |= (1<<(7-((bn)&7))))
|
||||
#define CLR_BLOC_OCCUPATION(tab,bn) \
|
||||
(((tab)[(bn)/8]) &= ~(1<<(7-((bn)&7))))
|
||||
|
||||
/* Maximum number of blocks for the copy buffers */
|
||||
#define BLOCK_MAX_BUFF 256
|
||||
/* Maximum size of the copy buffers, in bytes */
|
||||
#define BYTES_MAX_BUFF 8388608
|
||||
|
||||
/* Apple Creator Codes follow */
|
||||
#define HFSP_IMPL_Shnk 0x53686e6b /* in use */
|
||||
#define HFSP_IMPL_Xpnd 0x58706e64 /* reserved */
|
||||
#define HFSP_IMPL_Resz 0x5265737a /* reserved */
|
||||
#define HFSP_IMPL_PHpx 0x50482b78 /* reserved */
|
||||
#define HFSP_IMPL_traP 0x74726150 /* reserved */
|
||||
#define HFSP_IMPL_GnuP 0x476e7550 /* reserved */
|
||||
|
||||
#define HFS_SIGNATURE 0x4244 /* 'BD' */
|
||||
#define HFSP_SIGNATURE 0x482B /* 'H+' */
|
||||
#define HFSX_SIGNATURE 0x4858 /* 'HX' */
|
||||
|
||||
#define HFSP_VERSION 4
|
||||
#define HFSX_VERSION 5
|
||||
|
||||
#define HFS_HARD_LOCK 7
|
||||
#define HFS_UNMOUNTED 8
|
||||
#define HFS_BAD_SPARED 9
|
||||
#define HFS_SOFT_LOCK 15
|
||||
#define HFSP_NO_CACHE 10
|
||||
#define HFSP_INCONSISTENT 11
|
||||
#define HFSP_REUSE_CNID 12
|
||||
#define HFSP_JOURNALED 13
|
||||
|
||||
#define HFS_IDX_NODE 0x00
|
||||
#define HFS_HDR_NODE 0x01
|
||||
#define HFS_MAP_NODE 0x02
|
||||
#define HFS_LEAF_NODE 0xFF
|
||||
|
||||
#define HFS_FIRST_REC 0x0E
|
||||
#define HFS_NSD_HD_REC 0x78
|
||||
#define HFS_MAP_REC 0xF8
|
||||
|
||||
#define HFS_DATA_FORK 0x00
|
||||
#define HFS_RES_FORK 0xFF
|
||||
|
||||
#define HFS_CAT_DIR 0x01
|
||||
#define HFS_CAT_FILE 0x02
|
||||
#define HFS_CAT_DIR_TH 0x03
|
||||
#define HFS_CAT_FILE_TH 0x04
|
||||
|
||||
#define HFSP_ATTR_INLINE 0x10
|
||||
#define HFSP_ATTR_FORK 0x20
|
||||
#define HFSP_ATTR_EXTENTS 0x30
|
||||
|
||||
#define HFS_ROOT_PAR_ID 0x01
|
||||
#define HFS_ROOT_DIR_ID 0x02
|
||||
#define HFS_XTENT_ID 0x03
|
||||
#define HFS_CATALOG_ID 0x04
|
||||
#define HFS_BAD_BLOCK_ID 0x05
|
||||
#define HFSP_ALLOC_ID 0x06
|
||||
#define HFSP_STARTUP_ID 0x07
|
||||
#define HFSP_ATTRIB_ID 0x08
|
||||
#define HFSP_BOGUS_ID 0x0F
|
||||
#define HFSP_FIRST_AV_ID 0x10
|
||||
|
||||
#define HFSJ_JOURN_IN_FS 0x00
|
||||
#define HFSJ_JOURN_OTHER_DEV 0x01
|
||||
#define HFSJ_JOURN_NEED_INIT 0x02
|
||||
|
||||
#define HFSJ_HEADER_MAGIC 0x4a4e4c78
|
||||
#define HFSJ_ENDIAN_MAGIC 0x12345678
|
||||
|
||||
#define HFSX_CASE_FOLDING 0xCF /* case insensitive HFSX */
|
||||
#define HFSX_BINARY_COMPARE 0xBC /* case sensitive HFSX */
|
||||
|
||||
#define HFS_EXT_NB 3
|
||||
#define HFSP_EXT_NB 8
|
||||
|
||||
/* Define the filenames used by the FS extractor */
|
||||
#ifdef HFS_EXTRACT_FS
|
||||
|
||||
#define HFS_MDB_FILENAME "mdb.hfs"
|
||||
#define HFS_CATALOG_FILENAME "catalog.hfs"
|
||||
#define HFS_EXTENTS_FILENAME "extents.hfs"
|
||||
#define HFS_BITMAP_FILENAME "bitmap.hfs"
|
||||
|
||||
#define HFSP_VH_FILENAME "vh.hfsplus"
|
||||
#define HFSP_CATALOG_FILENAME "catalog.hfsplus"
|
||||
#define HFSP_EXTENTS_FILENAME "extents.hfsplus"
|
||||
#define HFSP_BITMAP_FILENAME "bitmap.hfsplus"
|
||||
#define HFSP_ATTRIB_FILENAME "attributes.hfsplus"
|
||||
#define HFSP_STARTUP_FILENAME "startup.hfsplus"
|
||||
|
||||
#endif /* HFS_EXTRACT_FS */
|
||||
|
||||
|
||||
|
||||
/* ----------------------------------- */
|
||||
/* -- HFS DATA STRUCTURES -- */
|
||||
/* ----------------------------------- */
|
||||
|
||||
/* Extent descriptor */
|
||||
struct __attribute__ ((packed)) _HfsExtDescriptor {
|
||||
uint16_t start_block;
|
||||
uint16_t block_count;
|
||||
};
|
||||
typedef struct _HfsExtDescriptor HfsExtDescriptor;
|
||||
typedef HfsExtDescriptor HfsExtDataRec[HFS_EXT_NB];
|
||||
|
||||
/* Volume header */
|
||||
struct __attribute__ ((packed)) _HfsMasterDirectoryBlock {
|
||||
uint16_t signature;
|
||||
uint32_t create_date;
|
||||
uint32_t modify_date;
|
||||
uint16_t volume_attributes;
|
||||
uint16_t files_in_root;
|
||||
uint16_t volume_bitmap_block; /* in sectors */
|
||||
uint16_t next_allocation;
|
||||
uint16_t total_blocks;
|
||||
uint32_t block_size; /* in bytes */
|
||||
uint32_t def_clump_size; /* in bytes */
|
||||
uint16_t start_block; /* in sectors */
|
||||
uint32_t next_free_node;
|
||||
uint16_t free_blocks;
|
||||
uint8_t name_length;
|
||||
char name[27];
|
||||
uint32_t backup_date;
|
||||
uint16_t backup_number;
|
||||
uint32_t write_count;
|
||||
uint32_t extents_clump;
|
||||
uint32_t catalog_clump;
|
||||
uint16_t dirs_in_root;
|
||||
uint32_t file_count;
|
||||
uint32_t dir_count;
|
||||
uint32_t finder_info[8];
|
||||
union __attribute__ ((packed)) {
|
||||
struct __attribute__ ((packed)) {
|
||||
uint16_t volume_cache_size; /* in blocks */
|
||||
uint16_t bitmap_cache_size; /* in blocks */
|
||||
uint16_t common_cache_size; /* in blocks */
|
||||
} legacy;
|
||||
struct __attribute__ ((packed)) {
|
||||
uint16_t signature;
|
||||
HfsExtDescriptor location;
|
||||
} embedded;
|
||||
} old_new;
|
||||
uint32_t extents_file_size; /* in bytes, block size multiple */
|
||||
HfsExtDataRec extents_file_rec;
|
||||
uint32_t catalog_file_size; /* in bytes, block size multiple */
|
||||
HfsExtDataRec catalog_file_rec;
|
||||
};
|
||||
typedef struct _HfsMasterDirectoryBlock HfsMasterDirectoryBlock;
|
||||
|
||||
/* B*-Tree Node Descriptor */
|
||||
struct __attribute__ ((packed)) _HfsNodeDescriptor {
|
||||
uint32_t next;
|
||||
uint32_t previous;
|
||||
int8_t type;
|
||||
uint8_t height;
|
||||
uint16_t rec_nb;
|
||||
uint16_t reserved;
|
||||
};
|
||||
typedef struct _HfsNodeDescriptor HfsNodeDescriptor;
|
||||
|
||||
/* Header record of a whole B*-Tree */
|
||||
struct __attribute__ ((packed)) _HfsHeaderRecord {
|
||||
uint16_t depth;
|
||||
uint32_t root_node;
|
||||
uint32_t leaf_records;
|
||||
uint32_t first_leaf_node;
|
||||
uint32_t last_leaf_node;
|
||||
uint16_t node_size;
|
||||
uint16_t max_key_len;
|
||||
uint32_t total_nodes;
|
||||
uint32_t free_nodes;
|
||||
int8_t reserved[76];
|
||||
};
|
||||
typedef struct _HfsHeaderRecord HfsHeaderRecord;
|
||||
|
||||
/* Catalog key for B*-Tree lookup in the catalog file */
|
||||
struct __attribute__ ((packed)) _HfsCatalogKey {
|
||||
uint8_t key_length; /* length of the key without key_length */
|
||||
uint8_t reserved;
|
||||
uint32_t parent_ID;
|
||||
uint8_t name_length;
|
||||
char name[31]; /* in fact physicaly 1 upto 31 */
|
||||
};
|
||||
typedef struct _HfsCatalogKey HfsCatalogKey;
|
||||
|
||||
/* Extents overflow key for B*-Tree lookup */
|
||||
struct __attribute__ ((packed)) _HfsExtentKey {
|
||||
uint8_t key_length; /* length of the key without key_length */
|
||||
uint8_t type; /* data or ressource fork */
|
||||
uint32_t file_ID;
|
||||
uint16_t start;
|
||||
};
|
||||
typedef struct _HfsExtentKey HfsExtentKey;
|
||||
|
||||
/* Catalog subdata case directory */
|
||||
struct __attribute__ ((packed)) _HfsDir {
|
||||
uint16_t flags;
|
||||
uint16_t valence; /* number of files in this directory */
|
||||
uint32_t dir_ID;
|
||||
uint32_t create_date;
|
||||
uint32_t modify_date;
|
||||
uint32_t backup_date;
|
||||
int8_t DInfo[16]; /* used by Finder, handle as reserved */
|
||||
int8_t DXInfo[16]; /* used by Finder, handle as reserved */
|
||||
uint32_t reserved[4];
|
||||
};
|
||||
typedef struct _HfsDir HfsDir;
|
||||
|
||||
/* Catalog subdata case file */
|
||||
struct __attribute__ ((packed)) _HfsFile {
|
||||
int8_t flags;
|
||||
int8_t type; /* should be 0 */
|
||||
int8_t FInfo[16]; /* used by Finder, handle as reserved */
|
||||
uint32_t file_ID;
|
||||
uint16_t data_start_block;
|
||||
uint32_t data_sz_byte;
|
||||
uint32_t data_sz_block;
|
||||
uint16_t res_start_block;
|
||||
uint32_t res_sz_byte;
|
||||
uint32_t res_sz_block;
|
||||
uint32_t create_date;
|
||||
uint32_t modify_date;
|
||||
uint32_t backup_date;
|
||||
int8_t FXInfo[16]; /* used by Finder, handle as reserved */
|
||||
uint16_t clump_size;
|
||||
HfsExtDataRec extents_data;
|
||||
HfsExtDataRec extents_res;
|
||||
uint32_t reserved;
|
||||
};
|
||||
typedef struct _HfsFile HfsFile;
|
||||
|
||||
/* Catalog subdata case directory thread */
|
||||
struct __attribute__ ((packed)) _HfsDirTh {
|
||||
uint32_t reserved[2];
|
||||
uint32_t parent_ID;
|
||||
int8_t name_length;
|
||||
char name[31];
|
||||
};
|
||||
typedef struct _HfsDirTh HfsDirTh;
|
||||
|
||||
/* Catalog subdata case file thread */
|
||||
typedef struct _HfsDirTh HfsFileTh; /* same as directory thread */
|
||||
|
||||
/* Catalog data */
|
||||
struct __attribute__ ((packed)) _HfsCatalog {
|
||||
int8_t type;
|
||||
int8_t reserved;
|
||||
union {
|
||||
HfsDir dir;
|
||||
HfsFile file;
|
||||
HfsDirTh dir_th;
|
||||
HfsFileTh file_th;
|
||||
} sel;
|
||||
};
|
||||
typedef struct _HfsCatalog HfsCatalog;
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------ */
|
||||
/* -- HFS+ DATA STRUCTURES -- */
|
||||
/* ------------------------------------ */
|
||||
|
||||
/* documented since 2004 in tn1150 */
|
||||
struct __attribute__ ((packed)) _HfsPPerms {
|
||||
uint32_t owner_ID;
|
||||
uint32_t group_ID;
|
||||
uint32_t permissions;
|
||||
uint32_t special_devices;
|
||||
};
|
||||
typedef struct _HfsPPerms HfsPPerms;
|
||||
|
||||
/* HFS+ extent descriptor*/
|
||||
struct __attribute__ ((packed)) _HfsPExtDescriptor {
|
||||
uint32_t start_block;
|
||||
uint32_t block_count;
|
||||
};
|
||||
typedef struct _HfsPExtDescriptor HfsPExtDescriptor;
|
||||
typedef HfsPExtDescriptor HfsPExtDataRec[HFSP_EXT_NB];
|
||||
|
||||
/* HFS+ fork data structure */
|
||||
struct __attribute__ ((packed)) _HfsPForkData {
|
||||
uint64_t logical_size;
|
||||
uint32_t clump_size;
|
||||
uint32_t total_blocks;
|
||||
HfsPExtDataRec extents;
|
||||
};
|
||||
typedef struct _HfsPForkData HfsPForkData;
|
||||
|
||||
/* HFS+ catalog node ID */
|
||||
typedef uint32_t HfsPNodeID;
|
||||
|
||||
/* HFS+ file names */
|
||||
typedef uint16_t unichar;
|
||||
struct __attribute__ ((packed)) _HfsPUniStr255 {
|
||||
uint16_t length;
|
||||
unichar unicode[255]; /* 1 upto 255 */
|
||||
};
|
||||
typedef struct _HfsPUniStr255 HfsPUniStr255;
|
||||
|
||||
/* HFS+ volume header */
|
||||
struct __attribute__ ((packed)) _HfsPVolumeHeader {
|
||||
uint16_t signature;
|
||||
uint16_t version;
|
||||
uint32_t attributes;
|
||||
uint32_t last_mounted_version;
|
||||
uint32_t journal_info_block;
|
||||
|
||||
uint32_t create_date;
|
||||
uint32_t modify_date;
|
||||
uint32_t backup_date;
|
||||
uint32_t checked_date;
|
||||
|
||||
uint32_t file_count;
|
||||
uint32_t dir_count;
|
||||
|
||||
uint32_t block_size;
|
||||
uint32_t total_blocks;
|
||||
uint32_t free_blocks;
|
||||
|
||||
uint32_t next_allocation;
|
||||
uint32_t res_clump_size;
|
||||
uint32_t data_clump_size;
|
||||
HfsPNodeID next_catalog_ID;
|
||||
|
||||
uint32_t write_count;
|
||||
uint64_t encodings_bitmap;
|
||||
|
||||
uint8_t finder_info[32];
|
||||
|
||||
HfsPForkData allocation_file;
|
||||
HfsPForkData extents_file;
|
||||
HfsPForkData catalog_file;
|
||||
HfsPForkData attributes_file;
|
||||
HfsPForkData startup_file;
|
||||
};
|
||||
typedef struct _HfsPVolumeHeader HfsPVolumeHeader;
|
||||
|
||||
/* HFS+ B-Tree Node Descriptor. Same as HFS btree. */
|
||||
struct __attribute__ ((packed)) _HfsPNodeDescriptor {
|
||||
uint32_t next;
|
||||
uint32_t previous;
|
||||
int8_t type;
|
||||
uint8_t height;
|
||||
uint16_t rec_nb;
|
||||
uint16_t reserved;
|
||||
};
|
||||
typedef struct _HfsPNodeDescriptor HfsPNodeDescriptor;
|
||||
|
||||
/* Header record of a whole HFS+ B-Tree. */
|
||||
struct __attribute__ ((packed)) _HfsPHeaderRecord {
|
||||
uint16_t depth;
|
||||
uint32_t root_node;
|
||||
uint32_t leaf_records;
|
||||
uint32_t first_leaf_node;
|
||||
uint32_t last_leaf_node;
|
||||
uint16_t node_size;
|
||||
uint16_t max_key_len;
|
||||
uint32_t total_nodes;
|
||||
uint32_t free_nodes; /* same as hfs btree until here */
|
||||
uint16_t reserved1;
|
||||
|
||||
uint32_t clump_size;
|
||||
uint8_t btree_type; /* must be 0 for HFS+ B-Tree */
|
||||
uint8_t key_compare_type; /* hfsx => 0xCF = case folding */
|
||||
/* 0xBC = binary compare */
|
||||
/* otherwise, reserved */
|
||||
uint32_t attributes;
|
||||
uint32_t reserved3[16];
|
||||
};
|
||||
typedef struct _HfsPHeaderRecord HfsPHeaderRecord;
|
||||
|
||||
/* Catalog key for B-Tree lookup in the HFS+ catalog file */
|
||||
struct __attribute__ ((packed)) _HfsPCatalogKey {
|
||||
uint16_t key_length;
|
||||
HfsPNodeID parent_ID;
|
||||
HfsPUniStr255 node_name;
|
||||
};
|
||||
typedef struct _HfsPCatalogKey HfsPCatalogKey;
|
||||
|
||||
/* HFS+ catalog subdata case dir */
|
||||
struct __attribute__ ((packed)) _HfsPDir {
|
||||
uint16_t flags;
|
||||
uint32_t valence;
|
||||
HfsPNodeID dir_ID;
|
||||
uint32_t create_date;
|
||||
uint32_t modify_date;
|
||||
uint32_t attrib_mod_date;
|
||||
uint32_t access_date;
|
||||
uint32_t backup_date;
|
||||
HfsPPerms permissions;
|
||||
int8_t DInfo[16]; /* used by Finder, handle as reserved */
|
||||
int8_t DXInfo[16]; /* used by Finder, handle as reserved */
|
||||
uint32_t text_encoding;
|
||||
uint32_t reserved;
|
||||
};
|
||||
typedef struct _HfsPDir HfsPDir;
|
||||
|
||||
/* HFS+ catalog subdata case file */
|
||||
struct __attribute__ ((packed)) _HfsPFile {
|
||||
uint16_t flags;
|
||||
uint32_t reserved1;
|
||||
HfsPNodeID file_ID;
|
||||
uint32_t create_date;
|
||||
uint32_t modify_date;
|
||||
uint32_t attrib_mod_date;
|
||||
uint32_t access_date;
|
||||
uint32_t backup_date;
|
||||
HfsPPerms permissions;
|
||||
int8_t FInfo[16]; /* used by Finder, handle as reserved */
|
||||
int8_t FXInfo[16]; /* used by Finder, handle as reserved */
|
||||
uint32_t text_encoding;
|
||||
uint32_t reserved2;
|
||||
|
||||
HfsPForkData data_fork;
|
||||
HfsPForkData res_fork;
|
||||
};
|
||||
typedef struct _HfsPFile HfsPFile;
|
||||
|
||||
/* HFS+ catalog subdata case thread */
|
||||
struct __attribute__ ((packed)) _HfsPThread {
|
||||
int16_t reserved;
|
||||
HfsPNodeID parent_ID;
|
||||
HfsPUniStr255 node_name;
|
||||
};
|
||||
typedef struct _HfsPThread HfsPDirTh;
|
||||
typedef struct _HfsPThread HfsPFileTh;
|
||||
|
||||
/* HFS+ Catalog leaf data */
|
||||
struct __attribute__ ((packed)) _HfsPCatalog {
|
||||
int16_t type;
|
||||
union {
|
||||
HfsPDir dir;
|
||||
HfsPFile file;
|
||||
HfsPDirTh dir_th;
|
||||
HfsPFileTh file_th;
|
||||
} sel;
|
||||
};
|
||||
typedef struct _HfsPCatalog HfsPCatalog;
|
||||
|
||||
/* HFS+ extents file key */
|
||||
struct __attribute__ ((packed)) _HfsPExtentKey {
|
||||
uint16_t key_length;
|
||||
uint8_t type;
|
||||
uint8_t pad;
|
||||
HfsPNodeID file_ID;
|
||||
uint32_t start;
|
||||
};
|
||||
typedef struct _HfsPExtentKey HfsPExtentKey;
|
||||
|
||||
/* extent file data is HfsPExtDataRec */
|
||||
|
||||
/* Fork data attribute file */
|
||||
struct __attribute__ ((packed)) _HfsPForkDataAttr {
|
||||
uint32_t record_type;
|
||||
uint32_t reserved;
|
||||
union __attribute__ ((packed)) {
|
||||
HfsPForkData fork;
|
||||
HfsPExtDataRec extents;
|
||||
} fork_res;
|
||||
};
|
||||
typedef struct _HfsPForkDataAttr HfsPForkDataAttr;
|
||||
|
||||
|
||||
/* ----------- Journal data structures ----------- */
|
||||
|
||||
/* Info block : stored in a block # defined in the VH */
|
||||
struct __attribute__ ((packed)) _HfsJJournalInfoBlock {
|
||||
uint32_t flags;
|
||||
uint32_t device_signature[8];
|
||||
uint64_t offset;
|
||||
uint64_t size;
|
||||
uint32_t reserved[32];
|
||||
};
|
||||
typedef struct _HfsJJournalInfoBlock HfsJJournalInfoBlock;
|
||||
|
||||
struct __attribute__ ((packed)) _HfsJJournalHeader {
|
||||
uint32_t magic;
|
||||
uint32_t endian;
|
||||
uint64_t start;
|
||||
uint64_t end;
|
||||
uint64_t size;
|
||||
uint32_t blhdr_size;
|
||||
uint32_t checksum;
|
||||
uint32_t jhdr_size;
|
||||
};
|
||||
typedef struct _HfsJJournalHeader HfsJJournalHeader;
|
||||
|
||||
struct __attribute__ ((packed)) _HfsJBlockInfo {
|
||||
uint64_t bnum; /* sector number */
|
||||
uint32_t bsize; /* size in bytes */
|
||||
uint32_t next;
|
||||
};
|
||||
typedef struct _HfsJBlockInfo HfsJBlockInfo;
|
||||
|
||||
struct __attribute__ ((packed)) _HfsJBlockListHeader {
|
||||
uint16_t max_blocks; /* reserved */
|
||||
uint16_t num_blocks;
|
||||
uint32_t bytes_used;
|
||||
uint32_t checksum;
|
||||
uint32_t pad;
|
||||
HfsJBlockInfo binfo[];
|
||||
};
|
||||
typedef struct _HfsJBlockListHeader HfsJBlockListHeader;
|
||||
|
||||
|
||||
|
||||
/* ---------------------------------------- */
|
||||
/* -- INTERNAL DATA STRUCTURES -- */
|
||||
/* ---------------------------------------- */
|
||||
|
||||
/* Data of an opened HFS file */
|
||||
struct _HfsPrivateFile {
|
||||
PedSector sect_nb;
|
||||
PedFileSystem* fs;
|
||||
uint32_t CNID; /* disk order (BE) */
|
||||
HfsExtDataRec first; /* disk order (BE) */
|
||||
HfsExtDataRec cache; /* disk order (BE) */
|
||||
uint16_t start_cache; /* CPU order */
|
||||
};
|
||||
typedef struct _HfsPrivateFile HfsPrivateFile;
|
||||
|
||||
/* To store bad block list */
|
||||
struct _HfsPrivateLinkExtent {
|
||||
HfsExtDescriptor extent;
|
||||
struct _HfsPrivateLinkExtent* next;
|
||||
};
|
||||
typedef struct _HfsPrivateLinkExtent HfsPrivateLinkExtent;
|
||||
|
||||
/* HFS Filesystem specific data */
|
||||
struct _HfsPrivateFSData {
|
||||
uint8_t alloc_map[(1<<16) / 8];
|
||||
HfsMasterDirectoryBlock* mdb;
|
||||
HfsPrivateFile* extent_file;
|
||||
HfsPrivateFile* catalog_file;
|
||||
HfsPrivateLinkExtent* bad_blocks_xtent_list;
|
||||
unsigned int bad_blocks_xtent_nb;
|
||||
char bad_blocks_loaded;
|
||||
};
|
||||
typedef struct _HfsPrivateFSData HfsPrivateFSData;
|
||||
|
||||
/* Generic btree key */
|
||||
struct __attribute__ ((packed)) _HfsPrivateGenericKey {
|
||||
uint8_t key_length;
|
||||
uint8_t key_content[1]; /* we use 1 as a minimum size */
|
||||
};
|
||||
typedef struct _HfsPrivateGenericKey HfsPrivateGenericKey;
|
||||
|
||||
/* ----- HFS+ ----- */
|
||||
|
||||
/* Data of an opened HFS file */
|
||||
struct _HfsPPrivateFile {
|
||||
PedSector sect_nb;
|
||||
PedFileSystem* fs;
|
||||
HfsPNodeID CNID; /* disk order (BE) */
|
||||
HfsPExtDataRec first; /* disk order (BE) */
|
||||
HfsPExtDataRec cache; /* disk order (BE) */
|
||||
uint32_t start_cache; /* CPU order */
|
||||
};
|
||||
typedef struct _HfsPPrivateFile HfsPPrivateFile;
|
||||
|
||||
struct _HfsPPrivateExtent {
|
||||
PedSector start_sector;
|
||||
PedSector sector_count;
|
||||
};
|
||||
typedef struct _HfsPPrivateExtent HfsPPrivateExtent;
|
||||
|
||||
/* To store bad block list */
|
||||
struct _HfsPPrivateLinkExtent {
|
||||
HfsPExtDescriptor extent;
|
||||
struct _HfsPPrivateLinkExtent* next;
|
||||
};
|
||||
typedef struct _HfsPPrivateLinkExtent HfsPPrivateLinkExtent;
|
||||
|
||||
/* HFS+ file system specific data */
|
||||
struct _HfsPPrivateFSData {
|
||||
PedFileSystem* wrapper; /* NULL if hfs+ is not embedded */
|
||||
PedGeometry* plus_geom; /* Geometry of HFS+ _volume_ */
|
||||
uint8_t* alloc_map;
|
||||
uint8_t* dirty_alloc_map;
|
||||
HfsPVolumeHeader* vh;
|
||||
HfsPPrivateFile* extents_file;
|
||||
HfsPPrivateFile* catalog_file;
|
||||
HfsPPrivateFile* attributes_file;
|
||||
HfsPPrivateFile* allocation_file;
|
||||
HfsPPrivateLinkExtent* bad_blocks_xtent_list;
|
||||
uint32_t jib_start_block;
|
||||
uint32_t jl_start_block;
|
||||
unsigned int bad_blocks_xtent_nb;
|
||||
char bad_blocks_loaded;
|
||||
char free_geom; /* 1 = plus_geom must be freed */
|
||||
};
|
||||
typedef struct _HfsPPrivateFSData HfsPPrivateFSData;
|
||||
|
||||
/* Generic + btree key */
|
||||
struct __attribute__ ((packed)) _HfsPPrivateGenericKey {
|
||||
uint16_t key_length;
|
||||
uint8_t key_content[1]; /* we use 1 as a minimum size */
|
||||
};
|
||||
typedef struct _HfsPPrivateGenericKey HfsPPrivateGenericKey;
|
||||
|
||||
/* ---- common ---- */
|
||||
|
||||
/* node and lead record reference for a BTree search */
|
||||
struct _HfsCPrivateLeafRec {
|
||||
unsigned int node_size; /* in sectors */
|
||||
unsigned int node_number;
|
||||
unsigned int record_pos;
|
||||
unsigned int record_number;
|
||||
};
|
||||
typedef struct _HfsCPrivateLeafRec HfsCPrivateLeafRec;
|
||||
|
||||
extern uint8_t* hfs_block;
|
||||
extern uint8_t* hfsp_block;
|
||||
extern unsigned hfs_block_count;
|
||||
extern unsigned hfsp_block_count;
|
||||
|
||||
#endif /* _HFS_H */
|
||||
@@ -1,238 +0,0 @@
|
||||
/*
|
||||
libparted - a library for manipulating disk partitions
|
||||
Copyright (C) 2004-2005, 2007, 2009-2014, 2019-2023 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <parted/parted.h>
|
||||
#include <parted/endian.h>
|
||||
#include <parted/debug.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(String) dgettext (PACKAGE, String)
|
||||
#else
|
||||
# define _(String) (String)
|
||||
#endif /* ENABLE_NLS */
|
||||
|
||||
#include "hfs.h"
|
||||
|
||||
#include "probe.h"
|
||||
|
||||
int
|
||||
hfsc_can_use_geom (PedGeometry* geom)
|
||||
{
|
||||
PedDevice* dev;
|
||||
|
||||
dev = geom->dev;
|
||||
PED_ASSERT (geom != NULL);
|
||||
PED_ASSERT (dev != NULL);
|
||||
|
||||
if (dev->sector_size != PED_SECTOR_SIZE_DEFAULT) {
|
||||
ped_exception_throw (
|
||||
PED_EXCEPTION_ERROR,
|
||||
PED_EXCEPTION_CANCEL,
|
||||
_("Parted can't use HFS file systems on disks "
|
||||
"with a sector size not equal to %d bytes."),
|
||||
(int)PED_SECTOR_SIZE_DEFAULT );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Probe an HFS volume, detecting it even if
|
||||
it is in fact a wrapper to an HFS+ volume */
|
||||
/* Used by hfsplus_probe and hfs_probe */
|
||||
PedGeometry*
|
||||
hfs_and_wrapper_probe (PedGeometry* geom)
|
||||
{
|
||||
HfsMasterDirectoryBlock *mdb;
|
||||
PedGeometry* geom_ret;
|
||||
PedSector search, max;
|
||||
|
||||
PED_ASSERT (geom != NULL);
|
||||
PED_ASSERT (hfsc_can_use_geom (geom));
|
||||
|
||||
const int sectors = ((3 * 512) + geom->dev->sector_size - 1) /
|
||||
geom->dev->sector_size;
|
||||
char * buf = alloca (sectors * geom->dev->sector_size);
|
||||
|
||||
mdb = (HfsMasterDirectoryBlock *)(buf+1024);
|
||||
|
||||
/* is 5 an intelligent value ? */
|
||||
if ((geom->length < 5)
|
||||
|| (!ped_geometry_read (geom, buf, 0, sectors))
|
||||
|| (mdb->signature != PED_CPU_TO_BE16 (HFS_SIGNATURE)) )
|
||||
return NULL;
|
||||
|
||||
search = ((PedSector) PED_BE16_TO_CPU (mdb->start_block)
|
||||
+ ((PedSector) PED_BE16_TO_CPU (mdb->total_blocks)
|
||||
* (PED_BE32_TO_CPU (mdb->block_size) / geom->dev->sector_size)));
|
||||
max = search + (PED_BE32_TO_CPU (mdb->block_size) / geom->dev->sector_size);
|
||||
if ((search < 0)
|
||||
|| !(geom_ret = ped_geometry_new (geom->dev, geom->start, search + 2)))
|
||||
return NULL;
|
||||
|
||||
for (; search < max; search++) {
|
||||
if (!ped_geometry_set (geom_ret, geom_ret->start, search + 2)
|
||||
|| !ped_geometry_read (geom_ret, buf, search, 1))
|
||||
break;
|
||||
if (mdb->signature == PED_CPU_TO_BE16 (HFS_SIGNATURE))
|
||||
return geom_ret;
|
||||
}
|
||||
|
||||
ped_geometry_destroy (geom_ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PedGeometry*
|
||||
hfsplus_probe (PedGeometry* geom)
|
||||
{
|
||||
PedGeometry* geom_ret;
|
||||
uint8_t buf[PED_SECTOR_SIZE_DEFAULT];
|
||||
|
||||
PED_ASSERT (geom != NULL);
|
||||
|
||||
if (!hfsc_can_use_geom (geom))
|
||||
return NULL;
|
||||
|
||||
if ((geom_ret = hfs_and_wrapper_probe(geom))) {
|
||||
/* HFS+ is embedded in an HFS volume ? */
|
||||
HfsMasterDirectoryBlock *mdb;
|
||||
mdb = (HfsMasterDirectoryBlock *) buf;
|
||||
|
||||
if (!ped_geometry_read (geom, buf, 2, 1)
|
||||
|| (mdb->old_new.embedded.signature
|
||||
!= PED_CPU_TO_BE16 (HFSP_SIGNATURE))) {
|
||||
ped_geometry_destroy (geom_ret);
|
||||
return NULL;
|
||||
} else
|
||||
return geom_ret;
|
||||
} else {
|
||||
/* This is a standalone HFS+ volume ? */
|
||||
PedSector search, max;
|
||||
HfsPVolumeHeader *vh;
|
||||
vh = (HfsPVolumeHeader *) buf;
|
||||
|
||||
if ((geom->length < 5)
|
||||
|| !ped_geometry_read (geom, buf, 2, 1)
|
||||
|| (vh->signature != PED_CPU_TO_BE16 (HFSP_SIGNATURE)))
|
||||
return NULL;
|
||||
|
||||
/* Correct range is indeed [ blocks*sz-2;(blocs+1)*sz-2 ( */
|
||||
/* But previous versions of my implementation used to */
|
||||
/* assume range is [(blocks-1)*sz-1;(blocks*sz) ( */
|
||||
/* (blocks-1)*sz-1 has to be scanned last, because */
|
||||
/* it can belong to a regular file */
|
||||
max = ((PedSector) PED_BE32_TO_CPU (vh->total_blocks) + 1)
|
||||
* ( PED_BE32_TO_CPU (vh->block_size) / PED_SECTOR_SIZE_DEFAULT )
|
||||
- 2;
|
||||
search = max - 2 * ( PED_BE32_TO_CPU (vh->block_size)
|
||||
/ PED_SECTOR_SIZE_DEFAULT ) + 2;
|
||||
if ((search < 0)
|
||||
|| !(geom_ret = ped_geometry_new (geom->dev, geom->start,
|
||||
search + 2)))
|
||||
return NULL;
|
||||
|
||||
for (; search < max; search++) {
|
||||
if (!ped_geometry_set (geom_ret, geom_ret->start,
|
||||
search + 2)
|
||||
|| !ped_geometry_read (geom_ret, buf, search, 1))
|
||||
break;
|
||||
if (vh->signature == PED_CPU_TO_BE16 (HFSP_SIGNATURE))
|
||||
return geom_ret;
|
||||
}
|
||||
search = ((PedSector) PED_BE32_TO_CPU (vh->total_blocks) - 1)
|
||||
* ( PED_BE32_TO_CPU (vh->block_size) / PED_SECTOR_SIZE_DEFAULT )
|
||||
- 1;
|
||||
if ((search < 0)
|
||||
|| !ped_geometry_set (geom_ret, geom_ret->start,
|
||||
search + 2)
|
||||
|| !ped_geometry_read (geom_ret, buf, search, 1)
|
||||
|| vh->signature != PED_CPU_TO_BE16 (HFSP_SIGNATURE)) {
|
||||
ped_geometry_destroy (geom_ret);
|
||||
return NULL;
|
||||
} else
|
||||
return geom_ret;
|
||||
}
|
||||
}
|
||||
|
||||
PedGeometry*
|
||||
hfs_probe (PedGeometry* geom)
|
||||
{
|
||||
PedGeometry* geom_base;
|
||||
PedGeometry* geom_plus = NULL;
|
||||
|
||||
PED_ASSERT (geom != NULL);
|
||||
|
||||
if (!hfsc_can_use_geom (geom))
|
||||
return NULL;
|
||||
|
||||
if ((geom_base = hfs_and_wrapper_probe(geom))
|
||||
&& (!(geom_plus = hfsplus_probe(geom_base))))
|
||||
return geom_base;
|
||||
else {
|
||||
if (geom_base) ped_geometry_destroy (geom_base);
|
||||
if (geom_plus) ped_geometry_destroy (geom_plus);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
PedGeometry*
|
||||
hfsx_probe (PedGeometry* geom)
|
||||
{
|
||||
PedGeometry* geom_ret;
|
||||
uint8_t buf[PED_SECTOR_SIZE_DEFAULT];
|
||||
PedSector search, max;
|
||||
HfsPVolumeHeader *vh = (HfsPVolumeHeader *) buf;
|
||||
|
||||
PED_ASSERT (geom != NULL);
|
||||
|
||||
if (!hfsc_can_use_geom (geom))
|
||||
return NULL;
|
||||
|
||||
if ((geom->length < 5)
|
||||
|| !ped_geometry_read (geom, buf, 2, 1)
|
||||
|| (vh->signature != PED_CPU_TO_BE16 (HFSX_SIGNATURE)))
|
||||
return NULL;
|
||||
|
||||
/* unlike the hfs+ code, which should be kept compatible
|
||||
with my old previous implementations, we only care here
|
||||
about legal alternate VH positions, like TN1150 describes them */
|
||||
max = ((PedSector) PED_BE32_TO_CPU (vh->total_blocks) + 1)
|
||||
* ( PED_BE32_TO_CPU (vh->block_size) / PED_SECTOR_SIZE_DEFAULT )
|
||||
- 2;
|
||||
search = max - ( PED_BE32_TO_CPU (vh->block_size) / PED_SECTOR_SIZE_DEFAULT );
|
||||
if ((search < 0)
|
||||
|| !(geom_ret = ped_geometry_new (geom->dev, geom->start,
|
||||
search + 2)))
|
||||
return NULL;
|
||||
for (; search < max; search++) {
|
||||
if (!ped_geometry_set (geom_ret, geom_ret->start,
|
||||
search + 2)
|
||||
|| !ped_geometry_read (geom_ret, buf, search, 1))
|
||||
break;
|
||||
if (vh->signature == PED_CPU_TO_BE16 (HFSX_SIGNATURE))
|
||||
return geom_ret;
|
||||
}
|
||||
|
||||
ped_geometry_destroy (geom_ret);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
libparted - a library for manipulating disk partitions
|
||||
Copyright (C) 2004-2005, 2007, 2009-2014, 2019-2023 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _PROBE_H
|
||||
#define _PROBE_H
|
||||
|
||||
#include <parted/parted.h>
|
||||
#include <parted/endian.h>
|
||||
#include <parted/debug.h>
|
||||
|
||||
#include "hfs.h"
|
||||
|
||||
int
|
||||
hfsc_can_use_geom (PedGeometry* geom);
|
||||
|
||||
PedGeometry*
|
||||
hfs_and_wrapper_probe (PedGeometry* geom);
|
||||
|
||||
PedGeometry*
|
||||
hfsplus_probe (PedGeometry* geom);
|
||||
|
||||
PedGeometry*
|
||||
hfs_probe (PedGeometry* geom);
|
||||
|
||||
PedGeometry*
|
||||
hfsx_probe (PedGeometry* geom);
|
||||
|
||||
#endif /* _PROBE_H */
|
||||
Reference in New Issue
Block a user