FswHfsPlus: Add HFS+ driver with compatible opensource license (#177)

This commit is contained in:
Vladislav Yaroshchuk 2021-01-12 22:20:24 +03:00 committed by GitHub
parent c2642a9cf8
commit bdb296fcd6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 5765 additions and 2 deletions

View File

@ -237,7 +237,7 @@
OpenCorePkg/Platform/OpenRuntime/OpenRuntime.inf
OpenCorePkg/Platform/OpenUsbKbDxe/UsbKbDxe.inf
OpenCorePkg/Staging/AudioDxe/AudioDxe.inf
OpenCorePkg/Staging/VBoxHfs/VBoxHfs.inf
OpenCorePkg/Staging/FswHfsPlus/FswHfsPlus.inf
OpenCorePkg/Tests/AcpiTest/AcpiTest.inf
OpenCorePkg/Tests/AcpiTest/AcpiTestApp.inf
OpenCorePkg/Tests/CryptoTest/CryptoTest.inf

View File

@ -0,0 +1,64 @@
## @file
# File System Wrapper (FSW) based HFS+ driver.
#
# Copyright (C) 2020, Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
# Copyright (C) 2017, Gabriel L. Somlo <gsomlo@gmail.com>
#
# This program and the accompanying materials are licensed and made
# available under the terms and conditions of the BSD License which
# accompanies this distribution. The full text of the license may
# be found at http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
# BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
# EXPRESS OR IMPLIED.
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = FswHfsPlus
FILE_GUID = F474802F-26BB-4E4F-A923-2FC568E94125
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = fsw_efi_main
[Sources]
fsw_base.h
fsw_efi_base.h
fsw_efi_edk2_base.h
fsw_strfunc.h
fsw_core.h
fsw_core.c
fsw_efi.h
fsw_efi.c
fsw_lib.c
fsw_efi_lib.c
fsw_hfsplus.h
fsw_hfsplus.c
[BuildOptions]
GCC:*_*_*_CC_FLAGS = -DHOST_EFI -DFSTYPE=hfsplus
INTEL:*_*_*_CC_FLAGS = -DHOST_EFI -DFSTYPE=hfsplus
MSFT:*_*_*_CC_FLAGS = -DHOST_EFI -DFSTYPE=hfsplus
XCODE:*_*_*_CC_FLAGS = -DHOST_EFI -DFSTYPE=hfsplus
[Packages]
MdePkg/MdePkg.dec
OpenCorePkg/OpenCorePkg.dec
[LibraryClasses]
UefiLib
UefiDriverEntryPoint
[Guids]
gEfiFileSystemInfoGuid
gEfiFileSystemVolumeLabelInfoIdGuid
gEfiFileInfoGuid
gAppleBlessedOsxFolderInfoGuid ## SOMETIMES_CONSUMES
gAppleBlessedSystemFileInfoGuid ## SOMETIMES_CONSUMES
gAppleBlessedSystemFolderInfoGuid ## SOMETIMES_CONSUMES
[Protocols]
gEfiBlockIoProtocolGuid
gEfiDiskIoProtocolGuid
gEfiSimpleFileSystemProtocolGuid

View File

@ -0,0 +1,158 @@
/**
* \file fsw_base.h
* Base definitions switch.
*/
/*-
* Copyright (c) 2006 Christoph Pfisterer
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Christoph Pfisterer nor the names of the
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSW_BASE_H_
#define _FSW_BASE_H_
#ifndef FSW_DEBUG_LEVEL
/**
* Global debugging level. Can be set locally for the scope of a single
* file by defining the macro before fsw_base.h is included.
*/
#define FSW_DEBUG_LEVEL 1
#endif
#ifdef HOST_EFI
#include "fsw_efi_base.h"
#endif
#ifdef HOST_POSIX
#include "fsw_posix_base.h"
#endif
// message printing
#if FSW_DEBUG_LEVEL >= 1
#define FSW_MSG_ASSERT(params) FSW_MSGFUNC(params)
#else
#define FSW_MSG_ASSERT(params)
#endif
#if FSW_DEBUG_LEVEL >= 2
#define FSW_MSG_DEBUG(params) FSW_MSGFUNC(params)
#else
#define FSW_MSG_DEBUG(params)
#endif
#if FSW_DEBUG_LEVEL >= 3
#define FSW_MSG_DEBUGV(params) FSW_MSGFUNC(params)
#else
#define FSW_MSG_DEBUGV(params)
#endif
// Documentation for system-dependent defines
/**
* \typedef fsw_s8
* Signed 8-bit integer.
*/
/**
* \typedef fsw_u8
* Unsigned 8-bit integer.
*/
/**
* \typedef fsw_s16
* Signed 16-bit integer.
*/
/**
* \typedef fsw_u16
* Unsigned 16-bit integer.
*/
/**
* \typedef fsw_s32
* Signed 32-bit integer.
*/
/**
* \typedef fsw_u32
* Unsigned 32-bit integer.
*/
/**
* \typedef fsw_s64
* Signed 64-bit integer.
*/
/**
* \typedef fsw_u64
* Unsigned 64-bit integer.
*/
/**
* \def fsw_alloc(size,ptrptr)
* Allocate memory on the heap. This function or macro allocates \a size
* bytes of memory using host-specific methods. The address of the
* allocated memory block is stored into the pointer variable pointed
* to by \a ptrptr. A status code is returned; FSW_SUCCESS if the block
* was allocated or FSW_OUT_OF_MEMORY if there is not enough memory
* to allocated the requested block.
*/
/**
* \def fsw_free(ptr)
* Release allocated memory. This function or macro returns an allocated
* memory block to the heap for reuse. Does not return a status.
*/
/**
* \def fsw_memcpy(dest,src,size)
* Copies a block of memory from \a src to \a dest. The two memory blocks
* must not overlap, or the result of the operation will be undefined.
* Does not return a status.
*/
/**
* \def fsw_memeq(dest,src,size)
* Compares two blocks of memory for equality. Returns boolean true if the
* memory blocks are equal, boolean false if they are different.
*/
/**
* \def fsw_memzero(dest,size)
* Initializes a block of memory with zeros. Does not return a status.
*/
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,533 @@
/**
* \file fsw_core.h
* Core file system wrapper abstraction layer header.
*/
/*-
* Copyright (c) 2020 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
* Copyright (c) 2006 Christoph Pfisterer
* Portions Copyright (c) The Regents of the University of California.
* Portions Copyright (c) UNIX System Laboratories, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Christoph Pfisterer nor the names of the
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSW_CORE_H_
#define _FSW_CORE_H_
#include "fsw_base.h"
/** Maximum size for a path, specifically symlink target paths. */
#define FSW_PATH_MAX (4096)
/** Helper macro for token concatenation. */
#define FSW_CONCAT3(a,b,c) a##b##c
/** Expands to the name of a fstype dispatch table (fsw_fstype_table) for a named file system type. */
#define FSW_FSTYPE_TABLE_NAME(t) FSW_CONCAT3(fsw_,t,_table)
/** Indicates that the block cache entry is empty. */
#define FSW_INVALID_BNO (~0U)
//
// Byte-swapping macros
//
/**
* \name Byte Order Macros
* Implements big endian vs. little endian awareness and conversion.
*/
/*@{*/
typedef fsw_u16 fsw_u16_le;
typedef fsw_u16 fsw_u16_be;
typedef fsw_u32 fsw_u32_le;
typedef fsw_u32 fsw_u32_be;
typedef fsw_u64 fsw_u64_le;
typedef fsw_u64 fsw_u64_be;
#define FSW_SWAPVALUE_U16(v) ((((fsw_u16)(v) & 0xff00) >> 8) | \
(((fsw_u16)(v) & 0x00ff) << 8))
#define FSW_SWAPVALUE_U32(v) ((((fsw_u32)(v) & 0xff000000UL) >> 24) | \
(((fsw_u32)(v) & 0x00ff0000UL) >> 8) | \
(((fsw_u32)(v) & 0x0000ff00UL) << 8) | \
(((fsw_u32)(v) & 0x000000ffUL) << 24))
#define FSW_SWAPVALUE_U64(v) ((((fsw_u64)(v) & 0xff00000000000000ULL) >> 56) | \
(((fsw_u64)(v) & 0x00ff000000000000ULL) >> 40) | \
(((fsw_u64)(v) & 0x0000ff0000000000ULL) >> 24) | \
(((fsw_u64)(v) & 0x000000ff00000000ULL) >> 8) | \
(((fsw_u64)(v) & 0x00000000ff000000ULL) << 8) | \
(((fsw_u64)(v) & 0x0000000000ff0000ULL) << 24) | \
(((fsw_u64)(v) & 0x000000000000ff00ULL) << 40) | \
(((fsw_u64)(v) & 0x00000000000000ffULL) << 56))
#ifdef FSW_LITTLE_ENDIAN
#define fsw_u16_le_swap(v) (v)
#define fsw_u16_be_swap(v) FSW_SWAPVALUE_U16(v)
#define fsw_u32_le_swap(v) (v)
#define fsw_u32_be_swap(v) FSW_SWAPVALUE_U32(v)
#define fsw_u64_le_swap(v) (v)
#define fsw_u64_be_swap(v) FSW_SWAPVALUE_U64(v)
#define fsw_u16_le_sip(var)
#define fsw_u16_be_sip(var) (var = FSW_SWAPVALUE_U16(var))
#define fsw_u32_le_sip(var)
#define fsw_u32_be_sip(var) (var = FSW_SWAPVALUE_U32(var))
#define fsw_u64_le_sip(var)
#define fsw_u64_be_sip(var) (var = FSW_SWAPVALUE_U64(var))
#else
#ifdef FSW_BIG_ENDIAN
#define fsw_u16_le_swap(v) FSW_SWAPVALUE_U16(v)
#define fsw_u16_be_swap(v) (v)
#define fsw_u32_le_swap(v) FSW_SWAPVALUE_U32(v)
#define fsw_u32_be_swap(v) (v)
#define fsw_u64_le_swap(v) FSW_SWAPVALUE_U64(v)
#define fsw_u64_be_swap(v) (v)
#define fsw_u16_le_sip(var) (var = FSW_SWAPVALUE_U16(var))
#define fsw_u16_be_sip(var)
#define fsw_u32_le_sip(var) (var = FSW_SWAPVALUE_U32(var))
#define fsw_u32_be_sip(var)
#define fsw_u64_le_sip(var) (var = FSW_SWAPVALUE_U64(var))
#define fsw_u64_be_sip(var)
#else
#fail Neither FSW_BIG_ENDIAN nor FSW_LITTLE_ENDIAN are defined
#endif
#endif
/*@}*/
//
// The following evil hack avoids a lot of casts between generic and fstype-specific
// structures.
//
#ifndef VOLSTRUCTNAME
#define VOLSTRUCTNAME fsw_volume
#else
struct VOLSTRUCTNAME;
#endif
#ifndef DNODESTRUCTNAME
#define DNODESTRUCTNAME fsw_dnode
#else
struct DNODESTRUCTNAME;
#endif
/**
* Status code type, returned from all functions that can fail.
*/
typedef int fsw_status_t;
/**
* Possible status codes.
*/
enum {
FSW_SUCCESS,
FSW_OUT_OF_MEMORY,
FSW_IO_ERROR,
FSW_UNSUPPORTED,
FSW_NOT_FOUND,
FSW_VOLUME_CORRUPTED,
FSW_UNKNOWN_ERROR
};
/**
* Core: A string with explicit length and encoding information.
*/
struct fsw_string {
int type; //!< Encoding of the string - empty, ISO-8859-1, UTF8, UTF16
int len; //!< Length in characters
int size; //!< Total data size in bytes
void *data; //!< Data pointer (may be NULL if type is EMPTY or len is zero)
};
/**
* Possible string types / encodings. In the case of FSW_STRING_TYPE_EMPTY,
* all other members of the fsw_string structure may be invalid.
*/
enum {
FSW_STRING_TYPE_EMPTY,
FSW_STRING_TYPE_ISO88591,
FSW_STRING_TYPE_UTF8,
FSW_STRING_TYPE_UTF16,
FSW_STRING_TYPE_UTF16_SWAPPED
};
#ifdef FSW_LITTLE_ENDIAN
#define FSW_STRING_TYPE_UTF16_LE FSW_STRING_TYPE_UTF16
#define FSW_STRING_TYPE_UTF16_BE FSW_STRING_TYPE_UTF16_SWAPPED
#else
#define FSW_STRING_TYPE_UTF16_LE FSW_STRING_TYPE_UTF16_SWAPPED
#define FSW_STRING_TYPE_UTF16_BE FSW_STRING_TYPE_UTF16
#endif
/** Static initializer for an empty string. */
#define FSW_STRING_INIT { FSW_STRING_TYPE_EMPTY, 0, 0, NULL }
/* forward declarations */
struct fsw_dnode;
struct fsw_host_table;
struct fsw_fstype_table;
struct fsw_blockcache {
fsw_u32 refcount; //!< Reference count
fsw_u32 cache_level; //!< Level of importance of this block
fsw_u32 phys_bno; //!< Physical block number
void *data; //!< Block data buffer
};
/**
* Core: Represents a mounted volume.
*/
struct fsw_volume {
fsw_u32 phys_blocksize; //!< Block size for disk access / file system structures
fsw_u32 log_blocksize; //!< Block size for logical file data
struct DNODESTRUCTNAME *root; //!< Root directory dnode
struct fsw_string label; //!< Volume label
struct fsw_dnode *dnode_head; //!< List of all dnodes allocated for this volume
struct fsw_blockcache *bcache; //!< Array of block cache entries
fsw_u32 bcache_size; //!< Number of entries in the block cache array
void *host_data; //!< Hook for a host-specific data structure
struct fsw_host_table *host_table; //!< Dispatch table for host-specific functions
struct fsw_fstype_table *fstype_table; //!< Dispatch table for file system specific functions
int host_string_type; //!< String type used by the host environment
};
/**
* Core: Represents a "directory node" - a file, directory, symlink, whatever.
*/
struct fsw_dnode {
fsw_u32 refcount; //!< Reference count
fsw_u32 complete; //!< Flag to be set on all dnode info was filled
struct VOLSTRUCTNAME *vol; //!< The volume this dnode belongs to
struct DNODESTRUCTNAME *parent; //!< Parent directory dnode
struct fsw_string name; //!< Name of this item in the parent directory
fsw_u32 dnode_id; //!< Unique id number (usually the inode number)
int type; //!< Type of the dnode - file, dir, symlink, special
fsw_u64 size; //!< Data size in bytes
struct fsw_dnode *next; //!< Doubly-linked list of all dnodes: previous dnode
struct fsw_dnode *prev; //!< Doubly-linked list of all dnodes: next dnode
};
/**
* Possible dnode types. FSW_DNODE_TYPE_UNKNOWN may only be used before
* fsw_dnode_fill has been called on the dnode.
*/
enum {
FSW_DNODE_TYPE_UNKNOWN,
FSW_DNODE_TYPE_FILE,
FSW_DNODE_TYPE_DIR,
FSW_DNODE_TYPE_SYMLINK,
FSW_DNODE_TYPE_SPECIAL
};
enum {
BLESSED_TYPE_SYSTEM_FILE,
BLESSED_TYPE_SYSTEM_FOLDER,
BLESSED_TYPE_OSX_FOLDER
};
/**
* Core: Stores the mapping of a region of a file to the data on disk.
*/
struct fsw_extent {
int type; //!< Type of extent specification
fsw_u32 log_start; //!< Starting logical block number
fsw_u32 log_count; //!< Logical block count
fsw_u32 phys_start; //!< Starting physical block number (for FSW_EXTENT_TYPE_PHYSBLOCK only)
void *buffer; //!< Allocated buffer pointer (for FSW_EXTENT_TYPE_BUFFER only)
};
/**
* Possible extent representation types. FSW_EXTENT_TYPE_INVALID is for shandle's
* internal use only, it must not be returned from a get_extent function.
*/
enum {
FSW_EXTENT_TYPE_INVALID,
FSW_EXTENT_TYPE_SPARSE,
FSW_EXTENT_TYPE_PHYSBLOCK,
FSW_EXTENT_TYPE_BUFFER
};
/**
* Core: An access structure to a dnode's raw data. There can be multiple
* shandles per dnode, each of them has its own position pointer.
*/
struct fsw_shandle {
struct fsw_dnode *dnode; //!< The dnode this handle reads data from
fsw_u64 pos; //!< Current file pointer in bytes
struct fsw_extent extent; //!< Current extent
};
/**
* Core: Used in gathering detailed information on a volume.
*/
struct fsw_volume_stat {
fsw_u64 total_bytes; //!< Total size of data area size in bytes
fsw_u64 free_bytes; //!< Bytes still available for storing file data
};
/**
* Core: Used in gathering detailed information on a dnode.
*/
struct fsw_dnode_stat {
fsw_u64 used_bytes; //!< Bytes actually used by the file on disk
void (*store_time_posix)(struct fsw_dnode_stat *sb, int which, fsw_u32 posix_time); //!< Callback for storing a Posix-style timestamp
void (*store_attr_posix)(struct fsw_dnode_stat *sb, fsw_u16 posix_mode); //!< Callbock for storing a Posix-style file mode
void *host_data; //!< Hook for a host-specific data structure
};
/**
* Type of the timestamp passed into store_time_posix.
*/
enum {
FSW_DNODE_STAT_CTIME,
FSW_DNODE_STAT_MTIME,
FSW_DNODE_STAT_ATIME
};
/**
* Core: Function table for a host environment.
*/
struct fsw_host_table
{
int native_string_type; //!< String type used by the host environment
void (*change_blocksize)(struct fsw_volume *vol,
fsw_u32 old_phys_blocksize, fsw_u32 old_log_blocksize,
fsw_u32 new_phys_blocksize, fsw_u32 new_log_blocksize);
fsw_status_t (*read_block)(struct fsw_volume *vol, fsw_u32 phys_bno, void *buffer);
};
/**
* Core: Function table for a file system driver.
*/
struct fsw_fstype_table
{
struct fsw_string name; //!< String giving the name of the file system
fsw_u32 volume_struct_size; //!< Size for allocating the fsw_volume structure
fsw_u32 dnode_struct_size; //!< Size for allocating the fsw_dnode structure
fsw_status_t (*volume_mount)(struct VOLSTRUCTNAME *vol);
void (*volume_free)(struct VOLSTRUCTNAME *vol);
fsw_status_t (*volume_stat)(struct VOLSTRUCTNAME *vol, struct fsw_volume_stat *sb);
fsw_status_t (*dnode_fill)(struct VOLSTRUCTNAME *vol, struct DNODESTRUCTNAME *dno);
void (*dnode_free)(struct VOLSTRUCTNAME *vol, struct DNODESTRUCTNAME *dno);
fsw_status_t (*dnode_stat)(struct VOLSTRUCTNAME *vol, struct DNODESTRUCTNAME *dno,
struct fsw_dnode_stat *sb);
fsw_status_t (*get_extent)(struct VOLSTRUCTNAME *vol, struct DNODESTRUCTNAME *dno,
struct fsw_extent *extent);
fsw_status_t (*dir_lookup)(struct VOLSTRUCTNAME *vol, struct DNODESTRUCTNAME *dno,
struct fsw_string *lookup_name, struct DNODESTRUCTNAME **child_dno);
fsw_status_t (*dir_read)(struct VOLSTRUCTNAME *vol, struct DNODESTRUCTNAME *dno,
struct fsw_shandle *shand, struct DNODESTRUCTNAME **child_dno);
fsw_status_t (*readlink)(struct VOLSTRUCTNAME *vol, struct DNODESTRUCTNAME *dno,
struct fsw_string *link_target);
fsw_status_t (*get_bless_info)(struct VOLSTRUCTNAME *vol, fsw_u32 type, struct DNODESTRUCTNAME **dno_out);
};
/**
* \name Volume Functions
*/
/*@{*/
fsw_status_t fsw_mount(void *host_data,
struct fsw_host_table *host_table,
struct fsw_fstype_table *fstype_table,
struct fsw_volume **vol_out);
void fsw_unmount(struct fsw_volume *vol);
fsw_status_t fsw_volume_stat(struct fsw_volume *vol, struct fsw_volume_stat *sb);
void fsw_set_blocksize(struct VOLSTRUCTNAME *vol, fsw_u32 phys_blocksize, fsw_u32 log_blocksize);
fsw_status_t fsw_block_get(struct VOLSTRUCTNAME *vol, fsw_u32 phys_bno, fsw_u32 cache_level, void **buffer_out);
void fsw_block_release(struct VOLSTRUCTNAME *vol, fsw_u32 phys_bno, void *buffer);
/*@}*/
/**
* \name dnode Functions
*/
/*@{*/
fsw_status_t fsw_dnode_create_root(struct VOLSTRUCTNAME *vol, fsw_u32 dnode_id, struct DNODESTRUCTNAME **dno_out);
fsw_status_t fsw_dnode_create(struct VOLSTRUCTNAME *vol, struct DNODESTRUCTNAME *parent_dno, fsw_u32 dnode_id, int type,
struct fsw_string *name, struct DNODESTRUCTNAME **dno_out);
void fsw_dnode_mkcomplete(struct DNODESTRUCTNAME *dno);
int fsw_dnode_is_root(struct fsw_dnode *dno);
void fsw_dnode_retain(struct fsw_dnode *dno);
void fsw_dnode_release(struct fsw_dnode *dno);
fsw_status_t fsw_dnode_fill(struct fsw_dnode *dno);
fsw_status_t fsw_dnode_stat(struct fsw_dnode *dno, struct fsw_dnode_stat *sb);
fsw_status_t fsw_dnode_lookup(struct fsw_dnode *dno,
struct fsw_string *lookup_name, struct fsw_dnode **child_dno_out);
fsw_status_t fsw_dnode_lookup_path(struct fsw_dnode *dno,
struct fsw_string *lookup_path, char separator,
struct fsw_dnode **child_dno_out);
fsw_status_t fsw_dnode_dir_read(struct fsw_shandle *shand, struct fsw_dnode **child_dno_out);
fsw_status_t fsw_dnode_readlink(struct fsw_dnode *dno, struct fsw_string *link_target);
fsw_status_t fsw_dnode_readlink_data(struct DNODESTRUCTNAME *dno, struct fsw_string *link_target);
fsw_status_t fsw_dnode_resolve(struct fsw_dnode *dno, struct fsw_dnode **target_dno_out);
fsw_status_t fsw_dnode_get_path(struct VOLSTRUCTNAME *vol, struct DNODESTRUCTNAME *dno, struct fsw_string *out_path);
fsw_status_t fsw_get_bless_info(struct VOLSTRUCTNAME *vol, int type, struct fsw_string *out_path);
/*@}*/
/**
* \name shandle Functions
*/
/*@{*/
fsw_status_t fsw_shandle_open(struct DNODESTRUCTNAME *dno, struct fsw_shandle *shand);
void fsw_shandle_close(struct fsw_shandle *shand);
fsw_status_t fsw_shandle_read(struct fsw_shandle *shand, fsw_u32 *buffer_size_inout, void *buffer);
/*@}*/
/**
* \name Memory Functions
*/
/*@{*/
fsw_status_t fsw_alloc_zero(int len, void **ptr_out);
fsw_status_t fsw_memdup(void **dest_out, void *src, int len);
/*@}*/
/**
* \name String Functions
*/
/*@{*/
int fsw_strlen(struct fsw_string *s);
int fsw_strsize(struct fsw_string *s);
void *fsw_strdata(struct fsw_string *s);
int fsw_streq(struct fsw_string *s1, struct fsw_string *s2);
int fsw_streq_cstr(struct fsw_string *s1, const char *s2);
fsw_status_t fsw_strdup_coerce(struct fsw_string *dest, int type, struct fsw_string *src);
void fsw_strsplit(struct fsw_string *lookup_name, struct fsw_string *buffer, char separator);
void fsw_strfree(struct fsw_string *s);
/*@}*/
/**
* \name Posix Mode Macros
* These macros can be used globally to test fields and bits in
* Posix-style modes.
*
* Taken from FreeBSD sys/stat.h.
*/
/*@{*/
#ifndef S_IRWXU
#define S_ISUID 0004000 /* set user id on execution */
#define S_ISGID 0002000 /* set group id on execution */
#define S_ISTXT 0001000 /* sticky bit */
#define S_IRWXU 0000700 /* RWX mask for owner */
#define S_IRUSR 0000400 /* R for owner */
#define S_IWUSR 0000200 /* W for owner */
#define S_IXUSR 0000100 /* X for owner */
#define S_IRWXG 0000070 /* RWX mask for group */
#define S_IRGRP 0000040 /* R for group */
#define S_IWGRP 0000020 /* W for group */
#define S_IXGRP 0000010 /* X for group */
#define S_IRWXO 0000007 /* RWX mask for other */
#define S_IROTH 0000004 /* R for other */
#define S_IWOTH 0000002 /* W for other */
#define S_IXOTH 0000001 /* X for other */
#define S_IFMT 0170000 /* type of file mask */
#define S_IFIFO 0010000 /* named pipe (fifo) */
#define S_IFCHR 0020000 /* character special */
#define S_IFDIR 0040000 /* directory */
#define S_IFBLK 0060000 /* block special */
#define S_IFREG 0100000 /* regular */
#define S_IFLNK 0120000 /* symbolic link */
#define S_IFSOCK 0140000 /* socket */
#define S_ISVTX 0001000 /* save swapped text even after use */
#define S_IFWHT 0160000 /* whiteout */
#define S_ISDIR(m) (((m) & 0170000) == 0040000) /* directory */
#define S_ISCHR(m) (((m) & 0170000) == 0020000) /* char special */
#define S_ISBLK(m) (((m) & 0170000) == 0060000) /* block special */
#define S_ISREG(m) (((m) & 0170000) == 0100000) /* regular file */
#define S_ISFIFO(m) (((m) & 0170000) == 0010000) /* fifo or socket */
#define S_ISLNK(m) (((m) & 0170000) == 0120000) /* symbolic link */
#define S_ISSOCK(m) (((m) & 0170000) == 0140000) /* socket */
#define S_ISWHT(m) (((m) & 0170000) == 0160000) /* whiteout */
#define S_BLKSIZE 512 /* block size used in the stat struct */
#endif
/*@}*/
#endif

1120
Staging/FswHfsPlus/fsw_efi.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,103 @@
/**
* \file fsw_efi.h
* EFI host environment header.
*/
/*-
* Copyright (c) 2006 Christoph Pfisterer
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Christoph Pfisterer nor the names of the
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSW_EFI_H_
#define _FSW_EFI_H_
#include <Guid/AppleBless.h>
#include "fsw_core.h"
/**
* EFI Host: Private per-volume structure.
*/
typedef struct {
UINT64 Signature; //!< Used to identify this structure
EFI_FILE_IO_INTERFACE FileSystem; //!< Published EFI protocol interface structure
EFI_HANDLE Handle; //!< The device handle the protocol is attached to
EFI_DISK_IO *DiskIo; //!< The Disk I/O protocol we use for disk access
UINT32 MediaId; //!< The media ID from the Block I/O protocol
EFI_STATUS LastIOStatus; //!< Last status from Disk I/O
struct fsw_volume *vol; //!< FSW volume structure
} FSW_VOLUME_DATA;
/** Signature for the volume structure. */
#define FSW_VOLUME_DATA_SIGNATURE EFI_SIGNATURE_32 ('f', 's', 'w', 'V')
/** Access macro for the volume structure. */
#define FSW_VOLUME_FROM_FILE_SYSTEM(a) CR (a, FSW_VOLUME_DATA, FileSystem, FSW_VOLUME_DATA_SIGNATURE)
/**
* EFI Host: Private structure for a EFI_FILE interface.
*/
typedef struct {
UINT64 Signature; //!< Used to identify this structure
EFI_FILE FileHandle; //!< Published EFI protocol interface structure
UINTN Type; //!< File type used for dispatchinng
struct fsw_shandle shand; //!< FSW handle for this file
} FSW_FILE_DATA;
/** File type: regular file. */
#define FSW_EFI_FILE_TYPE_FILE (0)
/** File type: directory. */
#define FSW_EFI_FILE_TYPE_DIR (1)
/** Signature for the file handle structure. */
#define FSW_FILE_DATA_SIGNATURE EFI_SIGNATURE_32 ('f', 's', 'w', 'F')
/** Access macro for the file handle structure. */
#define FSW_FILE_FROM_FILE_HANDLE(a) CR (a, FSW_FILE_DATA, FileHandle, FSW_FILE_DATA_SIGNATURE)
//
// Library functions
//
VOID fsw_efi_decode_time(OUT EFI_TIME *EfiTime, IN UINT32 UnixTime);
UINTN fsw_efi_strsize(struct fsw_string *s);
VOID fsw_efi_strcpy(CHAR16 *Dest, struct fsw_string *src);
#endif

View File

@ -0,0 +1,81 @@
/**
* \file fsw_efi_base.h
* Base definitions for the EFI host environment.
*/
/*-
* Copyright (c) 2006 Christoph Pfisterer
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Christoph Pfisterer nor the names of the
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSW_EFI_BASE_H_
#define _FSW_EFI_BASE_H_
#include "fsw_efi_edk2_base.h"
#define FSW_LITTLE_ENDIAN (1)
// types, reuse EFI types
typedef INT8 fsw_s8;
typedef UINT8 fsw_u8;
typedef INT16 fsw_s16;
typedef UINT16 fsw_u16;
typedef INT32 fsw_s32;
typedef UINT32 fsw_u32;
typedef INT64 fsw_s64;
typedef UINT64 fsw_u64;
// allocation functions
#define fsw_alloc(size, ptrptr) (((*(ptrptr) = AllocatePool(size)) == NULL) ? FSW_OUT_OF_MEMORY : FSW_SUCCESS)
#define fsw_free(ptr) FreePool(ptr)
// memory functions
#define fsw_memzero(dest,size) ZeroMem(dest,size)
#define fsw_memcpy(dest,src,size) CopyMem(dest,src,size)
#define fsw_memeq(p1,p2,size) (CompareMem(p1,p2,size) == 0)
// message printing
#define FSW_MSGSTR(s) DEBUG_INFO, s
#define FSW_MSGFUNC(params) DEBUG(params)
// 64-bit hooks
#define FSW_U64_SHR(val,shiftbits) RShiftU64((val), (shiftbits))
#define FSW_U64_DIV(val,divisor) DivU64x32((val), (divisor), NULL)
#endif

View File

@ -0,0 +1,76 @@
/**
* \file fsw_efi_edk2_base.h
* Base definitions for the EDK EFI Toolkit environment.
*/
/*
* Copyright (c) 2012 Stefan Agner
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Christoph Pfisterer nor the names of the
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FSW_EFI_EDK2_BASE_H_
#define _FSW_EFI_EDK2_BASE_H_
/*
* Here is common declarations for EDK<->EDK2 compatibility
*/
# include <Base.h>
# include <Uefi.h>
# include <Library/DebugLib.h>
# include <Library/BaseLib.h>
# include <Protocol/DriverBinding.h>
# include <Library/BaseMemoryLib.h>
# include <Library/UefiRuntimeServicesTableLib.h>
# include <Library/UefiDriverEntryPoint.h>
# include <Library/UefiBootServicesTableLib.h>
# include <Library/MemoryAllocationLib.h>
# include <Library/DevicePathLib.h>
# include <Protocol/DevicePathFromText.h>
# include <Protocol/DevicePathToText.h>
# include <Protocol/DebugPort.h>
# include <Protocol/DebugSupport.h>
# include <Library/PrintLib.h>
# include <Library/UefiLib.h>
# include <Protocol/SimpleFileSystem.h>
# include <Protocol/BlockIo.h>
# include <Protocol/DiskIo.h>
# include <Guid/FileSystemInfo.h>
# include <Guid/FileInfo.h>
# include <Guid/FileSystemVolumeLabelInfo.h>
# include <Protocol/ComponentName.h>
# define BS gBS
# define EFI_FILE_HANDLE_REVISION EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION
# define SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL_INFO SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL
# define EFI_FILE_SYSTEM_VOLUME_LABEL_INFO EFI_FILE_SYSTEM_VOLUME_LABEL
# define EFI_SIGNATURE_32(a, b, c, d) SIGNATURE_32(a, b, c, d)
# define DivU64x32(x,y,z) DivU64x32((x),(y))
#endif

View File

@ -0,0 +1,129 @@
/**
* \file fsw_efi_lib.c
* EFI host environment library functions.
*/
/*-
* Copyright (c) 2006 Christoph Pfisterer
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Christoph Pfisterer nor the names of the
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fsw_efi.h"
//
// time conversion
//
// Adopted from public domain code in FreeBSD libc.
//
#define SECSPERMIN 60
#define MINSPERHOUR 60
#define HOURSPERDAY 24
#define DAYSPERWEEK 7
#define DAYSPERNYEAR 365
#define DAYSPERLYEAR 366
#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
#define MONSPERYEAR 12
#define EPOCH_YEAR 1970
#define EPOCH_WDAY TM_THURSDAY
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
static const int mon_lengths[2][MONSPERYEAR] = {
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
static const int year_lengths[2] = {
DAYSPERNYEAR, DAYSPERLYEAR
};
VOID fsw_efi_decode_time(OUT EFI_TIME *EfiTime, IN UINT32 UnixTime)
{
long days, rem;
int y, newy, yleap;
const int *ip;
ZeroMem(EfiTime, sizeof(EFI_TIME));
days = UnixTime / SECSPERDAY;
rem = UnixTime % SECSPERDAY;
EfiTime->Hour = (UINT8) (rem / SECSPERHOUR);
rem = rem % SECSPERHOUR;
EfiTime->Minute = (UINT8) (rem / SECSPERMIN);
EfiTime->Second = (UINT8) (rem % SECSPERMIN);
y = EPOCH_YEAR;
while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) {
newy = y + days / DAYSPERNYEAR;
if (days < 0)
--newy;
days -= (newy - y) * DAYSPERNYEAR +
LEAPS_THRU_END_OF(newy - 1) -
LEAPS_THRU_END_OF(y - 1);
y = newy;
}
EfiTime->Year = (UINT16) y;
ip = mon_lengths[yleap];
for (EfiTime->Month = 0; days >= (long) ip[EfiTime->Month]; ++(EfiTime->Month))
days = days - (long) ip[EfiTime->Month];
EfiTime->Month++; // adjust range to EFI conventions
EfiTime->Day = (UINT8) (days + 1);
}
//
// String functions, used for file and volume info
//
UINTN fsw_efi_strsize(struct fsw_string *s)
{
if (s->type == FSW_STRING_TYPE_EMPTY)
return sizeof(CHAR16);
return (s->len + 1) * sizeof(CHAR16);
}
VOID fsw_efi_strcpy(CHAR16 *Dest, struct fsw_string *src)
{
if (src->type == FSW_STRING_TYPE_EMPTY) {
Dest[0] = 0;
} else if (src->type == FSW_STRING_TYPE_UTF16) {
CopyMem(Dest, src->data, src->size);
Dest[src->len] = 0;
} else {
// TODO: coerce, recurse
Dest[0] = 0;
}
}
// EOF

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,314 @@
/** @file
HFS+ file system driver header.
Copyright (c) 2020, Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
Copyright (C) 2017, Gabriel L. Somlo <gsomlo@gmail.com>
This program and the accompanying materials are licensed and made
available under the terms and conditions of the BSD License which
accompanies this distribution. The full text of the license may
be found at http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
EXPRESS OR IMPLIED.
**/
#ifndef _FSW_HFSPLUS_H_
#define _FSW_HFSPLUS_H_
#define VOLSTRUCTNAME fsw_hfsplus_volume
#define DNODESTRUCTNAME fsw_hfsplus_dnode
/* Let debug messages be printed */
//#define FSW_DEBUG_LEVEL 2
#include "fsw_core.h"
/*============= HFS+ constants and data types from Apple TN1150 =============*/
#pragma pack(1)
#define kHFSBlockSize 512 // Minimum block size to transfer Vol.Hdr.
#define kMasterDirectoryBlock 2 // Vol.Hdr. disk offset (x kHFSBlockSize)
#define kHFSPlusSigWord 0x482B // HFS+ volume signature (ASCII for 'H+')
#define kHFSPlusMaxFileNameChars 255 // Max. length of HFS+ folder or filename
#define kHFSPlusExtentDensity 8 // Number of extent descriptors per record
#define kHFSPlusDataFork 0x00 // data fork type
#define kHFSPlusResourceFork 0xFF // resource fork type
#define kHFSRootParentID 1 // Parent ID of the root folder
#define kHFSRootFolderID 2 // ID of the root folder
#define kHFSExtentsFileID 3 // ID of the extent overflow file
#define kHFSCatalogFileID 4 // ID of the catalog file
#define kHFSBadBlockFileID 5 // ID of the bad block file
#define kHFSAllocationFileID 6 // ID of the allocation file
#define kHFSStartupFileID 7 // ID of the startup file
#define kHFSAttributesFileID 8 // ID of the attributes file
#define kHFSRepairCatalogFileID 14 // Used temporarily when rebuilding Catalog B-tree
#define kHFSBogusExtentFileID 15 // Used temporarily during ExchangeFiles operations
#define kHFSFirstUserCatalogNodeID 16 // First CNID available for use by user files and folders
#define kHFSPlusFolderRecord 1 // catalog folder record type
#define kHFSPlusFileRecord 2 // catalog file record type
#define kHFSPlusFolderThreadRecord 3 // catalog folder thread record type
#define kHFSPlusFileThreadRecord 4 // catalog file thread record type
#define kHFSPlusHFSPlusCreator 0x6866732B // 'hfs+'
#define kHFSPlusSymlinkCreator 0x72686170 //'rhap'
#define kHFSPlusHardlinkType 0x686C6E6B // 'hlnk'
#define kHFSPlusSymlinkType 0x736C6E6B // 'slnk'
#define kBTLeafNode -1 // B-Tree leaf node type
#define kBTIndexNode 0 // B-Tree index node type
#define kBTHeaderNode 1 // B-Tree header node type
// file/folder name unicode string type
typedef struct {
fsw_u16 length; // character count
fsw_u16 unicode[kHFSPlusMaxFileNameChars]; // character string
} HFSUniStr255;
// extent descriptor type
typedef struct {
fsw_u32 startBlock; // first allocation block in the extent
fsw_u32 blockCount; // extent length, in allocation blocks
} HFSPlusExtentDescriptor;
// extent record type
typedef HFSPlusExtentDescriptor HFSPlusExtentRecord[kHFSPlusExtentDensity];
// fork-data information type
typedef struct {
fsw_u64 logicalSize; // size of valid fork data, in bytes
fsw_u32 clumpSize; // fork-specific clump size
fsw_u32 totalBlocks; // total blocks across all extents in fork
HFSPlusExtentRecord extents; // initial extents for the fork data
} HFSPlusForkData;
// volume header type
typedef struct {
fsw_u16 signature; // should be kHFSPlusSigWord
fsw_u16 version; // should be kHFSPlusVersion
fsw_u32 attributes; // volume attributes
fsw_u32 lastMountedVersion; // unique ID of software that last wrote volume
fsw_u32 journalInfoBlock; // block no. of journal info
fsw_u32 createDate; // volume creation timestamp (date and time)
fsw_u32 modifyDate; // volume last modification timestamp
fsw_u32 backupDate; // timestamp of last backup
fsw_u32 checkedDate; // timestamp of last consistency check
fsw_u32 fileCount; // total number of files on volume
fsw_u32 folderCount; // total number of folders on volume
fsw_u32 blockSize; // allocation block size, in bytes
fsw_u32 totalBlocks; // total number of allocation blocks
fsw_u32 freeBlocks; // total number of unused allocation blocks
fsw_u32 nextAllocation; // block number to start next allocation search
fsw_u32 rsrcClumpSize; // dflt. resource fork clump size (in bytes)
fsw_u32 dataClumpSize; // dflt. data fork clump size (in bytes)
fsw_u32 nextCatalogID; // next unused catalog ID
fsw_u32 writeCount; // incr. each time volume is write-mounted
fsw_u64 encodingsBitmap; // keep track of text encodings used in names
fsw_u8 finderInfo[32]; // information used by the OS X Finder
HFSPlusForkData allocationFile; // info re. size & location of alloc. file
HFSPlusForkData extentsFile; // info re. size & location of extents file
HFSPlusForkData catalogFile; // info re. size & location of catalog file
HFSPlusForkData attributesFile; // info re. size & location of attr. file
HFSPlusForkData startupFile; // info re. size & location of startup file
} HFSPlusVolumeHeader;
// file permissions type
typedef struct {
fsw_u32 ownerID; // owner UID (or hard-link previous-link)
fsw_u32 groupID; // owner GID (or hard-link next-link)
fsw_u8 adminFlags; // flags changeable by root only
fsw_u8 ownerFlags; // flags changeable by owner
fsw_u16 fileMode; // BSD file type and mode bits
union {
fsw_u32 iNodeNum; // link reference number, if hard-link
fsw_u32 linkCount; // ref-count of hard-links, if indirect node file
fsw_u32 rawDevice; // device number, if block/char special dev. file
} special; // reserved for directories and most files
} HFSPlusBSDInfo;
// finder info types
typedef struct {
fsw_u32 fdType; // file type
fsw_u32 fdCreator; // file creator
fsw_u16 fdFlags; // Finder flags
struct {
fsw_u16 v; // file's location
fsw_u16 h;
} fdLocation;
fsw_u16 opaque;
} FndrFileInfo;
typedef struct {
struct { // folder's window rectangle
fsw_u16 top;
fsw_u16 left;
fsw_u16 bottom;
fsw_u16 right;
} frRect;
unsigned short frFlags; // Finder flags
struct {
fsw_u16 v; // folder's location
fsw_u16 h;
} frLocation;
fsw_u16 opaque;
} FndrDirInfo;
typedef struct {
fsw_u8 opaque[16];
} FndrOpaqueInfo;
// catalog folder record type
typedef struct {
fsw_s16 recordType; // should be kHFSPlusFolderRecord
fsw_u16 flags; // bit flags about the folder (reserved)
fsw_u32 valence; // items directly contained by this folder
fsw_u32 folderID; // CNID of this folder
fsw_u32 createDate; // folder creation timestamp (date and time)
fsw_u32 contentModDate; // folder content last modification timestamp
fsw_u32 attributeModDate; // ctime (last change to a catalog record field)
fsw_u32 accessDate; // atime (last access timestamp)
fsw_u32 backupDate; // timestamp of last backup
HFSPlusBSDInfo permissions; // folder permissions
FndrDirInfo userInfo; // information used by the OS X Finder
FndrOpaqueInfo finderInfo; // additional information for the OS X Finder
fsw_u32 textEncoding; // hint re. folder name text encoding
fsw_u32 reserved; // reserved field
} HFSPlusCatalogFolder;
// catalog file record type
typedef struct {
fsw_s16 recordType; // should be kHFSPlusFileRecord
fsw_u16 flags; // bit flags about the file (reserved)
fsw_u32 reserved1; // reserved field
fsw_u32 fileID; // CNID of this file
fsw_u32 createDate; // file creation timestamp (date and time)
fsw_u32 contentModDate; // file content last modification timestamp
fsw_u32 attributeModDate; // ctime (last change to a catalog record field)
fsw_u32 accessDate; // atime (last access timestamp)
fsw_u32 backupDate; // timestamp of last backup
HFSPlusBSDInfo permissions; // file permissions
FndrFileInfo userInfo; // information used by the OS X Finder
FndrOpaqueInfo finderInfo; // additional information for the OS X Finder
fsw_u32 textEncoding; // hint re. file name text encoding
fsw_u32 reserved2; // reserved field
HFSPlusForkData dataFork; // info re. size & location of data fork
HFSPlusForkData resourceFork; // info re. size & location of resource fork
} HFSPlusCatalogFile;
// catalog thread record type
typedef struct {
fsw_s16 recordType; // should be kHFSPlus[Folder|File]ThreadRecord
fsw_u16 reserved; // reserved field
fsw_u32 parentID; // CNID of this record's parent
HFSUniStr255 nodeName; // basename of file or folder
} HFSPlusCatalogThread;
// generic (union) catalog record type
typedef union {
fsw_s16 recordType; // kHFSPlus[Folder|File][Thread]Record
HFSPlusCatalogFolder folderRecord; // catalog folder record fields
HFSPlusCatalogFile fileRecord; // catalog file record fields
HFSPlusCatalogThread threadRecord; // catalog thread record fields
} HFSPlusCatalogRecord;
// B-Tree node descriptor found at the start of each node
typedef struct {
fsw_u32 fLink; // number of next node of this type (0 if we're last)
fsw_u32 bLink; // number of prev. node of this type (0 if we're first)
fsw_s8 kind; // node type (leaf, index, header, map)
fsw_u8 height; // node depth in B-Tree hierarchy (0 for header)
fsw_u16 numRecords; // number of records contained in this node
fsw_u16 reserved; // reserved field
} BTNodeDescriptor;
// B-Tree header record type (first record of a B-Tree header node)
typedef struct {
fsw_u16 treeDepth; // current B-Tree depth (always == rootNode.height)
fsw_u32 rootNode; // node number of B-Tree root node
fsw_u32 leafRecords; // total number of records across all leaf nodes
fsw_u32 firstLeafNode; // node number of first leaf node
fsw_u32 lastLeafNode; // node number of last leaf node
fsw_u16 nodeSize; // node size (in bytes)
fsw_u16 maxKeyLength; // max. length of a key in index/leaf node
fsw_u32 totalNodes; // total number of nodes in the B-Tree
fsw_u32 freeNodes; // number of unused nodes in the B-Tree
fsw_u16 reserved1; // reserved field
fsw_u32 clumpSize; // reserved field (deprecated)
fsw_u8 btreeType; // reserved (0 for catalog, extents, attrib. file)
fsw_u8 keyCompareType; // case-sensitive string comparison (HFSX only)
fsw_u32 attributes; // B-Tree attributes
fsw_u32 reserved3[16]; // reserved field
} BTHeaderRec;
// extent overflow file key type
typedef struct {
fsw_u16 keyLength; // key length (excluding this field)
fsw_u8 forkType; // data or resource fork
fsw_u8 pad; // ensure 32-bit alignment for subsequent fields
fsw_u32 fileID; // CNID of file to which this extent record applies
fsw_u32 startBlock; // start block of first extent described by this record
} HFSPlusExtentKey;
// catalog file key type
typedef struct {
fsw_u16 keyLength; // key length (excluding this field)
fsw_u32 parentID; // ID of parent folder (or CNID if thread record)
HFSUniStr255 nodeName; // basename of file or folder
} HFSPlusCatalogKey;
// generic (union) B-Tree record key type
typedef union {
fsw_u16 keyLength; // key length (excluding this field)
HFSPlusExtentKey extKey; // extent key fields
HFSPlusCatalogKey catKey; // catalog key fields
} HFSPlusBTKey;
typedef struct {
fsw_u32 blessedSystemFolderID; // for OpenFirmware systems
fsw_u32 blessedSystemFileID; // for EFI systems
fsw_u32 openWindowFolderID; // deprecated, first link in linked list of folders to open at mount
fsw_u32 blessedAlternateOSID; // currently used for FV2 recovery, inaccessible from UEFI
fsw_u32 unused; // formerly PowerTalk Inbox
fsw_u32 blessedOSXFolderID; // currently used for normal recovery
fsw_u64 volumeID;
} HFSPlusVolumeFinderInfo;
#pragma pack()
/*========= end HFS+ constants and data types from Apple TN1150 =============*/
/* FSW: key comparison procedure type */
typedef int (*k_cmp_t)(HFSPlusBTKey*, HFSPlusBTKey*);
// FSW: HFS+ specific dnode
struct fsw_hfsplus_dnode {
struct fsw_dnode g; // Generic (parent) dnode structure
fsw_u32 ct, mt, at; // HFS+ create/modify/access timestamps
HFSPlusExtentRecord extents; // HFS+ initial extent record
fsw_u32 bt_root; // root node index (if B-Tree file)
fsw_u16 bt_ndsz; // node size (if B-Tree file)
// Links stuff
fsw_u32 fd_creator;
fsw_u32 fd_type;
fsw_u32 inode_num;
fsw_u32 parent_id; // parent id used by dnode_fill()
};
// FSW: HFS+ specific volume
struct fsw_hfsplus_volume {
struct fsw_volume g; // Generic (parent) volume structure
HFSPlusVolumeHeader *vh; // Raw HFS+ Volume Header
struct fsw_hfsplus_dnode *catf; // Catalog file dnode
};
#endif // _FSW_HFSPLUS_H_

View File

@ -0,0 +1,317 @@
/**
* \file fsw_lib.c
* Core file system wrapper library functions.
*/
/*-
* Copyright (c) 2020 Vladislav Yaroshchuk <yaroshchuk2000@gmail.com>
* Copyright (c) 2006 Christoph Pfisterer
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Christoph Pfisterer nor the names of the
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fsw_core.h"
/* Include generated string encoding specific functions */
#include "fsw_strfunc.h"
/**
* Allocate memory and clear it.
*/
fsw_status_t fsw_alloc_zero(int len, void **ptr_out)
{
fsw_status_t status;
status = fsw_alloc(len, ptr_out);
if (status)
return status;
fsw_memzero(*ptr_out, len);
return FSW_SUCCESS;
}
/**
* Duplicate a piece of data.
*/
fsw_status_t fsw_memdup(void **dest_out, void *src, int len)
{
fsw_status_t status;
status = fsw_alloc(len, dest_out);
if (status)
return status;
fsw_memcpy(*dest_out, src, len);
return FSW_SUCCESS;
}
/**
* Get the length of a string. Returns the number of characters in the string.
*/
int fsw_strlen(struct fsw_string *s)
{
if (s == NULL || s->type == FSW_STRING_TYPE_EMPTY)
return 0;
return s->len;
}
/**
* Get the size of a string in bytes.
*/
int fsw_strsize(struct fsw_string *s)
{
if (s == NULL || s->type == FSW_STRING_TYPE_EMPTY)
return 0;
return s->size;
}
/**
* Get the data of a string.
*/
void *fsw_strdata(struct fsw_string *s)
{
if (s == NULL || s->type == FSW_STRING_TYPE_EMPTY)
return NULL;
return (void *) s->data;
}
/**
* Compare two strings for equality. The two strings are compared, taking their
* encoding into account. If they are considered equal, boolean true is returned.
* Otherwise, boolean false is returned.
*/
int fsw_streq(struct fsw_string *s1, struct fsw_string *s2)
{
struct fsw_string temp_s;
// handle empty strings
if (s1->type == FSW_STRING_TYPE_EMPTY) {
temp_s.type = FSW_STRING_TYPE_ISO88591;
temp_s.size = temp_s.len = 0;
temp_s.data = NULL;
return fsw_streq(&temp_s, s2);
}
if (s2->type == FSW_STRING_TYPE_EMPTY) {
temp_s.type = FSW_STRING_TYPE_ISO88591;
temp_s.size = temp_s.len = 0;
temp_s.data = NULL;
return fsw_streq(s1, &temp_s);
}
// check length (count of chars)
if (s1->len != s2->len)
return 0;
if (s1->len == 0) // both strings are empty
return 1;
if (s1->type == s2->type) {
// same type, do a dumb memory compare
if (s1->size != s2->size)
return 0;
return fsw_memeq(s1->data, s2->data, s1->size);
}
// dispatch to type-specific functions
#define STREQ_DISPATCH(type1, type2) \
if (s1->type == FSW_STRING_TYPE_##type1 && s2->type == FSW_STRING_TYPE_##type2) \
return fsw_streq_##type1##_##type2(s1->data, s2->data, s1->len); \
if (s2->type == FSW_STRING_TYPE_##type1 && s1->type == FSW_STRING_TYPE_##type2) \
return fsw_streq_##type1##_##type2(s2->data, s1->data, s1->len);
STREQ_DISPATCH(ISO88591, UTF8);
STREQ_DISPATCH(ISO88591, UTF16);
STREQ_DISPATCH(ISO88591, UTF16_SWAPPED);
STREQ_DISPATCH(UTF8, UTF16);
STREQ_DISPATCH(UTF8, UTF16_SWAPPED);
STREQ_DISPATCH(UTF16, UTF16_SWAPPED);
// final fallback
return 0;
}
/**
* Compare a string with a C string constant. This sets up a string descriptor
* for the string constant (second argument) and runs fsw_streq on the two
* strings. Currently the C string is interpreted as ISO 8859-1.
* Returns boolean true if the strings are considered equal, boolean false otherwise.
*/
int fsw_streq_cstr(struct fsw_string *s1, const char *s2)
{
struct fsw_string temp_s;
int i;
for (i = 0; s2[i]; i++)
;
temp_s.type = FSW_STRING_TYPE_ISO88591;
temp_s.size = temp_s.len = i;
temp_s.data = (char *)s2;
return fsw_streq(s1, &temp_s);
}
/**
* Creates a duplicate of a string, converting it to the given encoding during the copy.
* If the function returns FSW_SUCCESS, the caller must free the string later with
* fsw_strfree.
*/
fsw_status_t fsw_strdup_coerce(struct fsw_string *dest, int type, struct fsw_string *src)
{
fsw_status_t status;
if (src->type == FSW_STRING_TYPE_EMPTY || src->len == 0) {
dest->type = type;
dest->size = dest->len = 0;
dest->data = NULL;
return FSW_SUCCESS;
}
if (src->type == type) {
dest->type = type;
dest->len = src->len;
dest->size = src->size;
status = fsw_alloc(dest->size, &dest->data);
if (status)
return status;
fsw_memcpy(dest->data, src->data, dest->size);
return FSW_SUCCESS;
}
// dispatch to type-specific functions
#define STRCOERCE_DISPATCH(type1, type2) \
if (src->type == FSW_STRING_TYPE_##type1 && type == FSW_STRING_TYPE_##type2) \
return fsw_strcoerce_##type1##_##type2(src->data, src->len, dest);
STRCOERCE_DISPATCH(UTF8, ISO88591);
STRCOERCE_DISPATCH(UTF16, ISO88591);
STRCOERCE_DISPATCH(UTF16_SWAPPED, ISO88591);
STRCOERCE_DISPATCH(ISO88591, UTF8);
STRCOERCE_DISPATCH(UTF16, UTF8);
STRCOERCE_DISPATCH(UTF16_SWAPPED, UTF8);
STRCOERCE_DISPATCH(ISO88591, UTF16);
STRCOERCE_DISPATCH(UTF8, UTF16);
STRCOERCE_DISPATCH(UTF16_SWAPPED, UTF16);
return FSW_UNSUPPORTED;
}
/**
* Splits a string at the first occurence of the separator character.
* The buffer string is searched for the separator character. If it is found, the
* element string descriptor is filled to point at the part of the buffer string
* before the separator. The buffer string itself is adjusted to point at the
* remaining part of the string (without the separator).
*
* If the separator is not found in the buffer string, then element is changed to
* point at the whole buffer string, and the buffer string itself is changed into
* an empty string.
*
* This function only manipulates the pointers and lengths in the two string descriptors,
* it does not change the actual string. If the buffer string is dynamically allocated,
* you must make a copy of it so that you can release it later.
*/
void fsw_strsplit(struct fsw_string *element, struct fsw_string *buffer, char separator)
{
int i, maxlen;
if (buffer->type == FSW_STRING_TYPE_EMPTY || buffer->len == 0) {
element->type = FSW_STRING_TYPE_EMPTY;
return;
}
maxlen = buffer->len;
*element = *buffer;
if (buffer->type == FSW_STRING_TYPE_ISO88591) {
fsw_u8 *p;
p = (fsw_u8 *)element->data;
for (i = 0; i < maxlen; i++, p++) {
if (*p == separator) {
buffer->data = p + 1;
buffer->len -= i + 1;
break;
}
}
element->len = i;
if (i == maxlen) {
buffer->data = p;
buffer->len -= i;
}
element->size = element->len;
buffer->size = buffer->len;
} else if (buffer->type == FSW_STRING_TYPE_UTF16) {
fsw_u16 *p;
p = (fsw_u16 *)element->data;
for (i = 0; i < maxlen; i++, p++) {
if (*p == separator) {
buffer->data = p + 1;
buffer->len -= i + 1;
break;
}
}
element->len = i;
if (i == maxlen) {
buffer->data = p;
buffer->len -= i;
}
element->size = element->len * sizeof(fsw_u16);
buffer->size = buffer->len * sizeof(fsw_u16);
} else {
// fallback
buffer->type = FSW_STRING_TYPE_EMPTY;
}
// TODO: support UTF8 and UTF16_SWAPPED
}
/**
* Frees the memory used by a string returned from fsw_strdup_coerce.
*/
void fsw_strfree(struct fsw_string *s)
{
if (s->type != FSW_STRING_TYPE_EMPTY && s->data)
fsw_free(s->data);
s->type = FSW_STRING_TYPE_EMPTY;
}
// EOF

View File

@ -0,0 +1,453 @@
/* fsw_strfunc.h generated by mk_fsw_strfunc.py */
static int fsw_streq_ISO88591_UTF8(void *s1data, void *s2data, int len)
{
int i;
fsw_u8 *p1 = (fsw_u8 *)s1data;
fsw_u8 *p2 = (fsw_u8 *)s2data;
fsw_u32 c1, c2;
for (i = 0; i < len; i++) {
c1 = *p1++;
c2 = *p2++;
if ((c2 & 0xe0) == 0xc0) {
c2 = ((c2 & 0x1f) << 6) | (*p2++ & 0x3f);
} else if ((c2 & 0xf0) == 0xe0) {
c2 = ((c2 & 0x0f) << 12) | ((*p2++ & 0x3f) << 6);
c2 |= (*p2++ & 0x3f);
} else if ((c2 & 0xf8) == 0xf0) {
c2 = ((c2 & 0x07) << 18) | ((*p2++ & 0x3f) << 12);
c2 |= ((*p2++ & 0x3f) << 6);
c2 |= (*p2++ & 0x3f);
}
if (c1 != c2)
return 0;
}
return 1;
}
static int fsw_streq_ISO88591_UTF16(void *s1data, void *s2data, int len)
{
int i;
fsw_u8 *p1 = (fsw_u8 *)s1data;
fsw_u16 *p2 = (fsw_u16 *)s2data;
fsw_u32 c1, c2;
for (i = 0; i < len; i++) {
c1 = *p1++;
c2 = *p2++;
if (c1 != c2)
return 0;
}
return 1;
}
static int fsw_streq_ISO88591_UTF16_SWAPPED(void *s1data, void *s2data, int len)
{
int i;
fsw_u8 *p1 = (fsw_u8 *)s1data;
fsw_u16 *p2 = (fsw_u16 *)s2data;
fsw_u32 c1, c2;
for (i = 0; i < len; i++) {
c1 = *p1++;
c2 = *p2++; c2 = FSW_SWAPVALUE_U16(c2);
if (c1 != c2)
return 0;
}
return 1;
}
static int fsw_streq_UTF8_UTF16(void *s1data, void *s2data, int len)
{
int i;
fsw_u8 *p1 = (fsw_u8 *)s1data;
fsw_u16 *p2 = (fsw_u16 *)s2data;
fsw_u32 c1, c2;
for (i = 0; i < len; i++) {
c1 = *p1++;
if ((c1 & 0xe0) == 0xc0) {
c1 = ((c1 & 0x1f) << 6) | (*p1++ & 0x3f);
} else if ((c1 & 0xf0) == 0xe0) {
c1 = ((c1 & 0x0f) << 12) | ((*p1++ & 0x3f) << 6);
c1 |= (*p1++ & 0x3f);
} else if ((c1 & 0xf8) == 0xf0) {
c1 = ((c1 & 0x07) << 18) | ((*p1++ & 0x3f) << 12);
c1 |= ((*p1++ & 0x3f) << 6);
c1 |= (*p1++ & 0x3f);
}
c2 = *p2++;
if (c1 != c2)
return 0;
}
return 1;
}
static int fsw_streq_UTF8_UTF16_SWAPPED(void *s1data, void *s2data, int len)
{
int i;
fsw_u8 *p1 = (fsw_u8 *)s1data;
fsw_u16 *p2 = (fsw_u16 *)s2data;
fsw_u32 c1, c2;
for (i = 0; i < len; i++) {
c1 = *p1++;
if ((c1 & 0xe0) == 0xc0) {
c1 = ((c1 & 0x1f) << 6) | (*p1++ & 0x3f);
} else if ((c1 & 0xf0) == 0xe0) {
c1 = ((c1 & 0x0f) << 12) | ((*p1++ & 0x3f) << 6);
c1 |= (*p1++ & 0x3f);
} else if ((c1 & 0xf8) == 0xf0) {
c1 = ((c1 & 0x07) << 18) | ((*p1++ & 0x3f) << 12);
c1 |= ((*p1++ & 0x3f) << 6);
c1 |= (*p1++ & 0x3f);
}
c2 = *p2++; c2 = FSW_SWAPVALUE_U16(c2);
if (c1 != c2)
return 0;
}
return 1;
}
static int fsw_streq_UTF16_UTF16_SWAPPED(void *s1data, void *s2data, int len)
{
int i;
fsw_u16 *p1 = (fsw_u16 *)s1data;
fsw_u16 *p2 = (fsw_u16 *)s2data;
fsw_u32 c1, c2;
for (i = 0; i < len; i++) {
c1 = *p1++;
c2 = *p2++; c2 = FSW_SWAPVALUE_U16(c2);
if (c1 != c2)
return 0;
}
return 1;
}
static fsw_status_t fsw_strcoerce_UTF8_ISO88591(void *srcdata, int srclen, struct fsw_string *dest)
{
fsw_status_t status;
int i;
fsw_u8 *sp;
fsw_u8 *dp;
fsw_u32 c;
dest->type = FSW_STRING_TYPE_ISO88591;
dest->len = srclen;
dest->size = srclen * sizeof(fsw_u8);
status = fsw_alloc(dest->size, &dest->data);
if (status)
return status;
sp = (fsw_u8 *)srcdata;
dp = (fsw_u8 *)dest->data;
for (i = 0; i < srclen; i++) {
c = *sp++;
if ((c & 0xe0) == 0xc0) {
c = ((c & 0x1f) << 6) | (*sp++ & 0x3f);
} else if ((c & 0xf0) == 0xe0) {
c = ((c & 0x0f) << 12) | ((*sp++ & 0x3f) << 6);
c |= (*sp++ & 0x3f);
} else if ((c & 0xf8) == 0xf0) {
c = ((c & 0x07) << 18) | ((*sp++ & 0x3f) << 12);
c |= ((*sp++ & 0x3f) << 6);
c |= (*sp++ & 0x3f);
}
*dp++ = (fsw_u8) c;
}
return FSW_SUCCESS;
}
static fsw_status_t fsw_strcoerce_UTF16_ISO88591(void *srcdata, int srclen, struct fsw_string *dest)
{
fsw_status_t status;
int i;
fsw_u16 *sp;
fsw_u8 *dp;
fsw_u32 c;
dest->type = FSW_STRING_TYPE_ISO88591;
dest->len = srclen;
dest->size = srclen * sizeof(fsw_u8);
status = fsw_alloc(dest->size, &dest->data);
if (status)
return status;
sp = (fsw_u16 *)srcdata;
dp = (fsw_u8 *)dest->data;
for (i = 0; i < srclen; i++) {
c = *sp++;
*dp++ = (fsw_u8) c;
}
return FSW_SUCCESS;
}
static fsw_status_t fsw_strcoerce_UTF16_SWAPPED_ISO88591(void *srcdata, int srclen, struct fsw_string *dest)
{
fsw_status_t status;
int i;
fsw_u16 *sp;
fsw_u8 *dp;
fsw_u32 c;
dest->type = FSW_STRING_TYPE_ISO88591;
dest->len = srclen;
dest->size = srclen * sizeof(fsw_u8);
status = fsw_alloc(dest->size, &dest->data);
if (status)
return status;
sp = (fsw_u16 *)srcdata;
dp = (fsw_u8 *)dest->data;
for (i = 0; i < srclen; i++) {
c = *sp++; c = FSW_SWAPVALUE_U16(c);
*dp++ = (fsw_u8) c;
}
return FSW_SUCCESS;
}
static fsw_status_t fsw_strcoerce_ISO88591_UTF16(void *srcdata, int srclen, struct fsw_string *dest)
{
fsw_status_t status;
int i;
fsw_u8 *sp;
fsw_u16 *dp;
fsw_u32 c;
dest->type = FSW_STRING_TYPE_UTF16;
dest->len = srclen;
dest->size = srclen * sizeof(fsw_u16);
status = fsw_alloc(dest->size, &dest->data);
if (status)
return status;
sp = (fsw_u8 *)srcdata;
dp = (fsw_u16 *)dest->data;
for (i = 0; i < srclen; i++) {
c = *sp++;
*dp++ = (fsw_u16) c;
}
return FSW_SUCCESS;
}
static fsw_status_t fsw_strcoerce_UTF8_UTF16(void *srcdata, int srclen, struct fsw_string *dest)
{
fsw_status_t status;
int i;
fsw_u8 *sp;
fsw_u16 *dp;
fsw_u32 c;
dest->type = FSW_STRING_TYPE_UTF16;
dest->len = srclen;
dest->size = srclen * sizeof(fsw_u16);
status = fsw_alloc(dest->size, &dest->data);
if (status)
return status;
sp = (fsw_u8 *)srcdata;
dp = (fsw_u16 *)dest->data;
for (i = 0; i < srclen; i++) {
c = *sp++;
if ((c & 0xe0) == 0xc0) {
c = ((c & 0x1f) << 6) | (*sp++ & 0x3f);
} else if ((c & 0xf0) == 0xe0) {
c = ((c & 0x0f) << 12) | ((*sp++ & 0x3f) << 6);
c |= (*sp++ & 0x3f);
} else if ((c & 0xf8) == 0xf0) {
c = ((c & 0x07) << 18) | ((*sp++ & 0x3f) << 12);
c |= ((*sp++ & 0x3f) << 6);
c |= (*sp++ & 0x3f);
}
*dp++ = (fsw_u16) c;
}
return FSW_SUCCESS;
}
static fsw_status_t fsw_strcoerce_UTF16_SWAPPED_UTF16(void *srcdata, int srclen, struct fsw_string *dest)
{
fsw_status_t status;
int i;
fsw_u16 *sp;
fsw_u16 *dp;
fsw_u32 c;
dest->type = FSW_STRING_TYPE_UTF16;
dest->len = srclen;
dest->size = srclen * sizeof(fsw_u16);
status = fsw_alloc(dest->size, &dest->data);
if (status)
return status;
sp = (fsw_u16 *)srcdata;
dp = (fsw_u16 *)dest->data;
for (i = 0; i < srclen; i++) {
c = *sp++; c = FSW_SWAPVALUE_U16(c);
*dp++ = (fsw_u16) c;
}
return FSW_SUCCESS;
}
static fsw_status_t fsw_strcoerce_ISO88591_UTF8(void *srcdata, int srclen, struct fsw_string *dest)
{
fsw_status_t status;
int i, destsize;
fsw_u8 *sp;
fsw_u8 *dp;
fsw_u32 c;
sp = (fsw_u8 *)srcdata;
destsize = 0;
for (i = 0; i < srclen; i++) {
c = *sp++;
if (c < 0x000080)
destsize++;
else if (c < 0x000800)
destsize += 2;
else if (c < 0x010000)
destsize += 3;
else
destsize += 4;
}
dest->type = FSW_STRING_TYPE_UTF8;
dest->len = srclen;
dest->size = destsize;
status = fsw_alloc(dest->size, &dest->data);
if (status)
return status;
sp = (fsw_u8 *)srcdata;
dp = (fsw_u8 *)dest->data;
for (i = 0; i < srclen; i++) {
c = *sp++;
if (c < 0x000080) {
*dp++ = (fsw_u8) c;
} else if (c < 0x000800) {
*dp++ = 0xc0 | ((c >> 6) & 0x1f);
*dp++ = 0x80 | (c & 0x3f);
} else if (c < 0x010000) {
*dp++ = 0xe0 | ((c >> 12) & 0x0f);
*dp++ = 0x80 | ((c >> 6) & 0x3f);
*dp++ = 0x80 | (c & 0x3f);
} else {
*dp++ = 0xf0 | ((c >> 18) & 0x07);
*dp++ = 0x80 | ((c >> 12) & 0x3f);
*dp++ = 0x80 | ((c >> 6) & 0x3f);
*dp++ = 0x80 | (c & 0x3f);
}
}
return FSW_SUCCESS;
}
static fsw_status_t fsw_strcoerce_UTF16_UTF8(void *srcdata, int srclen, struct fsw_string *dest)
{
fsw_status_t status;
int i, destsize;
fsw_u16 *sp;
fsw_u8 *dp;
fsw_u32 c;
sp = (fsw_u16 *)srcdata;
destsize = 0;
for (i = 0; i < srclen; i++) {
c = *sp++;
if (c < 0x000080)
destsize++;
else if (c < 0x000800)
destsize += 2;
else if (c < 0x010000)
destsize += 3;
else
destsize += 4;
}
dest->type = FSW_STRING_TYPE_UTF8;
dest->len = srclen;
dest->size = destsize;
status = fsw_alloc(dest->size, &dest->data);
if (status)
return status;
sp = (fsw_u16 *)srcdata;
dp = (fsw_u8 *)dest->data;
for (i = 0; i < srclen; i++) {
c = *sp++;
if (c < 0x000080) {
*dp++ = (fsw_u8) c;
} else if (c < 0x000800) {
*dp++ = 0xc0 | ((c >> 6) & 0x1f);
*dp++ = 0x80 | (c & 0x3f);
} else if (c < 0x010000) {
*dp++ = 0xe0 | ((c >> 12) & 0x0f);
*dp++ = 0x80 | ((c >> 6) & 0x3f);
*dp++ = 0x80 | (c & 0x3f);
} else {
*dp++ = 0xf0 | ((c >> 18) & 0x07);
*dp++ = 0x80 | ((c >> 12) & 0x3f);
*dp++ = 0x80 | ((c >> 6) & 0x3f);
*dp++ = 0x80 | (c & 0x3f);
}
}
return FSW_SUCCESS;
}
static fsw_status_t fsw_strcoerce_UTF16_SWAPPED_UTF8(void *srcdata, int srclen, struct fsw_string *dest)
{
fsw_status_t status;
int i, destsize;
fsw_u16 *sp;
fsw_u8 *dp;
fsw_u32 c;
sp = (fsw_u16 *)srcdata;
destsize = 0;
for (i = 0; i < srclen; i++) {
c = *sp++; c = FSW_SWAPVALUE_U16(c);
if (c < 0x000080)
destsize++;
else if (c < 0x000800)
destsize += 2;
else if (c < 0x010000)
destsize += 3;
else
destsize += 4;
}
dest->type = FSW_STRING_TYPE_UTF8;
dest->len = srclen;
dest->size = destsize;
status = fsw_alloc(dest->size, &dest->data);
if (status)
return status;
sp = (fsw_u16 *)srcdata;
dp = (fsw_u8 *)dest->data;
for (i = 0; i < srclen; i++) {
c = *sp++; c = FSW_SWAPVALUE_U16(c);
if (c < 0x000080) {
*dp++ = (fsw_u8) c;
} else if (c < 0x000800) {
*dp++ = 0xc0 | ((c >> 6) & 0x1f);
*dp++ = 0x80 | (c & 0x3f);
} else if (c < 0x010000) {
*dp++ = 0xe0 | ((c >> 12) & 0x0f);
*dp++ = 0x80 | ((c >> 6) & 0x3f);
*dp++ = 0x80 | (c & 0x3f);
} else {
*dp++ = 0xf0 | ((c >> 18) & 0x07);
*dp++ = 0x80 | ((c >> 12) & 0x3f);
*dp++ = 0x80 | ((c >> 6) & 0x3f);
*dp++ = 0x80 | (c & 0x3f);
}
}
return FSW_SUCCESS;
}

View File

@ -151,7 +151,7 @@ package() {
"Ps2MouseDxe.efi"
"Ps2KeyboardDxe.efi"
"UsbMouseDxe.efi"
"VBoxHfs.efi"
"FswHfsPlus.efi"
"XhciDxe.efi"
)
for efiDriver in "${efiDrivers[@]}"; do