Wii U support

This commit is contained in:
Maschell 2020-12-06 23:06:22 +01:00
parent 968dee4aef
commit f8705b2c39
29 changed files with 830 additions and 519 deletions

26
.github/workflows/push_image.yml vendored Normal file
View File

@ -0,0 +1,26 @@
name: Publish Docker Image
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Get release version
id: get_release_tag
run: |
echo RELEASE_VERSION=$(echo $(date '+%Y%m%d')) >> $GITHUB_ENV
echo REPOSITORY_NAME=$(echo "$GITHUB_REPOSITORY" | awk -F / '{print $2}' | sed -e "s/:refs//" | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV
echo REPOSITORY_OWNER=$(echo "$GITHUB_REPOSITORY" | awk -F / '{print $1}' | sed 's/[^a-zA-Z0-9]//g' | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV
- name: Publish to Registry
uses: elgohr/Publish-Docker-Github-Action@master
with:
name: ${{ env.REPOSITORY_OWNER }}/${{ env.REPOSITORY_NAME }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
snapshot: true
cache: true
tags: "latest, ${{ env.RELEASE_VERSION }}"
dockerfile: Dockerfile.wiiu

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
source/wiiu_release/*
source/wii_release/*
source/cube_release/*
lib/*
.idea/*

11
Dockerfile.wiiu Normal file
View File

@ -0,0 +1,11 @@
FROM wiiuenv/devkitppc:20200810
COPY --from=wiiuenv/libiosuhax:20200812 /artifacts $DEVKITPRO
WORKDIR tmp_build
COPY . .
RUN make clean && make wiiu-release && mkdir -p /artifacts/wut/usr && cp -r lib /artifacts/wut/usr && cp -r include //artifacts/wut/usr
WORKDIR /artifacts
FROM scratch
COPY --from=0 /artifacts /artifacts

View File

@ -1,11 +1,11 @@
default: cube-release wii-release
default: cube-release wii-release wiiu-release
all: debug release
debug: cube-debug wii-debug
debug: cube-debug wii-debug wiiu-debug
release: cube-release wii-release
release: cube-release wii-release wiiu-release
cube-debug:
$(MAKE) -C source PLATFORM=cube BUILD=cube_debug
@ -13,12 +13,18 @@ cube-debug:
wii-debug:
$(MAKE) -C source PLATFORM=wii BUILD=wii_debug
wiiu-debug:
$(MAKE) -C source PLATFORM=wiiu BUILD=wiiu_debug
cube-release:
$(MAKE) -C source PLATFORM=cube BUILD=cube_release
wii-release:
$(MAKE) -C source PLATFORM=wii BUILD=wii_release
wiiu-release:
$(MAKE) -C source PLATFORM=wiiu BUILD=wiiu_release
clean:
$(MAKE) -C source clean
@ -28,7 +34,10 @@ cube-install: cube-release
wii-install: wii-release
$(MAKE) -C source wii-install PLATFORM=wii
install: wii-install
wiiu-install: wiiu-release
$(MAKE) -C source wiiu-install PLATFORM=wiiu
install: wiiu-install
run: install
$(MAKE) -C example

20
README.md Normal file
View File

@ -0,0 +1,20 @@
# libntfs for the Wii U [![Build Status](https://travis-ci.org/Maschell/libntfs-wiiu.svg)](https://travis-ci.org/Maschell/libntfs-wiiu)
## Usage
Link the application with:
```
-lntfs -liosuhax
```
## Dependencies
To be able to use libntfs for the Wii u, you need to install the following dependencies:
- [libiosuhax](https://github.com/dimok789/libiosuhax)
# Use the prebuilt files from a Docker image.
The image `wiiulegacy/libntfs` on [Docker Hub](https://hub.docker.com/r/wiiulegacy/libntfs/) provides a prebuilt library in the `/artifacts` directory. Copy it into your DevkitPPC portlibs folder.
Example:
```
COPY --from=wiiulegacy/libntfs:2013.1.13 /artifacts $DEVKITPRO/portlibs
```

View File

@ -27,9 +27,18 @@
extern "C" {
#endif
#include <gctypes.h>
#include <gccore.h>
#include <ogc/disc_io.h>
#if defined(__gamecube__) || defined (__wii__)
#include <gctypes.h>
#include <ogc/disc_io.h>
#include <gccore.h>
#elif defined (__WIIU__)
#include <iosuhax_disc_interface.h>
typedef uint8_t u8;
typedef uint16_t u16;
typedef int32_t s32;
typedef uint32_t u32;
typedef int mutex_t;
#endif
/* NTFS errno values */
#define ENOPART 3000 /* No partition was found */

View File

@ -7,12 +7,17 @@ ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC")
endif
ifeq ($(PLATFORM),wiiu)
include $(DEVKITPRO)/wut/share/wut_rules
MACHDEP += -D__WIIU__
endif
ifeq ($(PLATFORM),wii)
include $(DEVKITPPC)/wii_rules
include $(DEVKITPPC)/wii_rules
endif
ifeq ($(PLATFORM),cube)
include $(DEVKITPPC)/gamecube_rules
include $(DEVKITPPC)/gamecube_rules
endif
#---------------------------------------------------------------------------------
@ -20,7 +25,7 @@ endif
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
#---------------------------------------------------------------------------------
BUILD ?= wii_release
BUILD ?= wiiu_release
SOURCES := .
INCLUDES := ../include
LIBDIR := ../lib
@ -28,7 +33,7 @@ LIBDIR := ../lib
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
CFLAGS = -Os -Wall -ffast-math -pipe $(MACHDEP) $(INCLUDE) -DHAVE_CONFIG_H
CFLAGS = -Wall -ffast-math -pipe $(MACHDEP) $(INCLUDE) -ffunction-sections -DHAVE_CONFIG_H
CXXFLAGS = $(CFLAGS)
ASFLAGS := -g
export NTFSBIN := $(LIBDIR)/$(PLATFORM)/libntfs.a
@ -37,21 +42,29 @@ ifeq ($(BUILD),cube_debug)
CFLAGS += -DDEBUG
CXXFLAGS += -DDEBUG
endif
ifeq ($(BUILD),wii_debug)
CFLAGS += -DDEBUG
CXXFLAGS += -DDEBUG
endif
ifeq ($(BUILD),wiiu_debug)
CFLAGS += -DDEBUG
CXXFLAGS += -DDEBUG
endif
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS :=
LIBS :=
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS :=
ifeq ($(PLATFORM),wiiu)
LIBDIRS := $(WUT_ROOT)/usr
endif
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
@ -77,11 +90,9 @@ export OFILES := $(addsuffix .o,$(BINFILES)) \
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD) \
-I$(LIBOGC_INC)
-I$(CURDIR)/$(BUILD) -I$(PORTLIBS)/include
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
-L$(LIBOGC_LIB)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) $(PORTLIBS)/lib
.PHONY: $(BUILD) clean
@ -93,7 +104,7 @@ $(BUILD):
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr wii_debug wii_release cube_debug cube_release $(LIBDIR)
@rm -fr wii_debug wii_release wiiu_release cube_debug cube_release $(LIBDIR)
all: $(NTFSBIN)
@ -105,6 +116,10 @@ wii-install:
cp ../include/ntfs.h $(PORTLIBS)/include
cp ../lib/wii/libntfs.a $(PORTLIBS)/lib
wiiu-install:
cp ../include/ntfs.h $(WUT_ROOT)/usr/include
cp ../lib/wiiu/libntfs.a $(WUT_ROOT)/usr/lib
#---------------------------------------------------------------------------------
else

View File

@ -73,7 +73,7 @@ BOOL ntfs_boot_sector_is_ntfs(NTFS_BOOT_SECTOR *b)
ntfs_log_debug("Checking bytes per sector.\n");
if (le16_to_cpu(b->bpb.bytes_per_sector) < 256 ||
le16_to_cpu(b->bpb.bytes_per_sector) > 4096) {
ntfs_log_error("Unexpected bytes per sector value (%d).\n",
ntfs_log_error("Unexpected bytes per sector value (%d).\n",
le16_to_cpu(b->bpb.bytes_per_sector));
goto not_ntfs;
}
@ -89,10 +89,10 @@ BOOL ntfs_boot_sector_is_ntfs(NTFS_BOOT_SECTOR *b)
}
ntfs_log_debug("Checking cluster size.\n");
i = (u32)le16_to_cpu(b->bpb.bytes_per_sector) *
i = (u32)le16_to_cpu(b->bpb.bytes_per_sector) *
b->bpb.sectors_per_cluster;
if (i > 65536) {
ntfs_log_error("Unexpected cluster size (%d).\n", i);
ntfs_log_error("Unexpected cluster size (%d).\n", (int)i);
goto not_ntfs;
}
@ -109,7 +109,7 @@ BOOL ntfs_boot_sector_is_ntfs(NTFS_BOOT_SECTOR *b)
le16_to_cpu(b->bpb.root_entries),
le16_to_cpu(b->bpb.sectors),
le16_to_cpu(b->bpb.sectors_per_fat),
le32_to_cpu(b->bpb.large_sectors),
(int)le32_to_cpu(b->bpb.large_sectors),
b->bpb.fats);
goto not_ntfs;
}
@ -193,14 +193,14 @@ int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs)
"\n", sectors_per_cluster);
return -1;
}
sectors = sle64_to_cpu(bs->number_of_sectors);
ntfs_log_debug("NumberOfSectors = %lld\n", (long long)sectors);
if (!sectors) {
ntfs_log_error("Volume size is set to zero.\n");
return -1;
}
if (vol->dev->d_ops->seek(vol->dev,
if (vol->dev->d_ops->seek(vol->dev,
(sectors - 1) << vol->sector_size_bits,
SEEK_SET) == -1) {
ntfs_log_perror("Failed to read last sector (%lld)",
@ -208,7 +208,7 @@ int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs)
ntfs_log_error("%s", last_sector_error);
return -1;
}
vol->nr_clusters = sectors >> (ffs(sectors_per_cluster) - 1);
vol->mft_lcn = sle64_to_cpu(bs->mft_lcn);
@ -223,11 +223,11 @@ int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs)
(long long)vol->nr_clusters);
return -1;
}
vol->cluster_size = sectors_per_cluster * vol->sector_size;
if (vol->cluster_size & (vol->cluster_size - 1)) {
ntfs_log_error("cluster_size (%d) is not a power of 2.\n",
vol->cluster_size);
(int)vol->cluster_size);
return -1;
}
vol->cluster_size_bits = ffs(vol->cluster_size) - 1;
@ -252,7 +252,7 @@ int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs)
vol->mft_record_size = c << vol->cluster_size_bits;
if (vol->mft_record_size & (vol->mft_record_size - 1)) {
ntfs_log_error("mft_record_size (%d) is not a power of 2.\n",
vol->mft_record_size);
(int)vol->mft_record_size);
return -1;
}
vol->mft_record_size_bits = ffs(vol->mft_record_size) - 1;

View File

@ -35,7 +35,11 @@
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <ogc/lwp_watchdog.h>
#if defined (__WIIU__)
#elif defined(__gamecube__) || defined (__wii__)
#include <ogc/lwp_watchdog.h>
#endif
#include <string.h>
#include <limits.h>

View File

@ -42,9 +42,21 @@
#include <stddef.h>
#include <stdint.h>
#include <gctypes.h>
#include <ogc/disc_io.h>
#include <gccore.h>
#if defined (__WIIU__)
#include <iosuhax_disc_interface.h>
typedef uint8_t u8;
typedef uint16_t u16;
typedef int32_t s32;
typedef uint32_t u32;
typedef uint64_t u64;
typedef uint32_t sec_t;
typedef int mutex_t;
#elif defined(__gamecube__) || defined (__wii__)
#include <gctypes.h>
#include <ogc/disc_io.h>
#include <gccore.h>
#endif
typedef struct {
sec_t sector;
@ -54,7 +66,7 @@ typedef struct {
u8* cache;
} NTFS_CACHE_ENTRY;
typedef struct {
typedef struct NTFS_CACHE_{
const DISC_INTERFACE* disc;
sec_t endOfPartition;
unsigned int numberOfPages;

View File

@ -69,11 +69,11 @@ extern char *strsep(char **stringp, const char *delim);
#define O_BINARY 0 /* unix is binary by default */
#endif
#ifdef GEKKO
#if defined(GEKKO) || defined (__WIIU__)
#include "mem_allocate.h"
#define XATTR_CREATE 1
#define XATTR_CREATE 1
#define XATTR_REPLACE 2
#define MINORBITS 20
@ -81,7 +81,7 @@ extern char *strsep(char **stringp, const char *delim);
#define major(dev) ((unsigned int) ((dev) >> MINORBITS))
#define minor(dev) ((unsigned int) ((dev) & MINORMASK))
#define mkdev(ma,mi) (((ma) << MINORBITS) | (mi))
#define mkdev(ma,mi) (((ma) << MINORBITS) | (mi))
#define random rand
#endif /* defined GEKKO */

View File

@ -27,7 +27,7 @@
#ifndef __CYGWIN32__
/* Not on Cygwin; use standard Unix style low level device operations. */
#include "unix_io.c"
//#include "unix_io.c"
#else /* __CYGWIN32__ */

View File

@ -30,12 +30,12 @@
#ifndef __CYGWIN32__
#ifndef GEKKO
/* Not on Cygwin; use standard Unix style low level device operations. */
#define ntfs_device_default_io_ops ntfs_device_unix_io_ops
#if defined(GEKKO) || defined (__WIIU__)
/* Wii i/o device. */
#define ntfs_device_default_io_ops ntfs_device_gekko_io_ops
#else
/* Wii i/o device. */
#define ntfs_device_default_io_ops ntfs_device_gekko_io_ops
/* Not on Cygwin; use standard Unix style low level device operations. */
#define ntfs_device_default_io_ops ntfs_device_unix_io_ops
#endif
#else /* __CYGWIN32__ */

View File

@ -66,6 +66,11 @@
#include <sys/xattr.h>
#endif
#if defined(__WIIU__)
#define major(dev) ((int)(((unsigned int) (dev) >> 8) & 0xff))
#define minor(dev) ((int)((dev) & 0xff))
#endif // defined
/*
* The little endian Unicode strings "$I30", "$SII", "$SDH", "$O"
* and "$Q" as global constants.
@ -313,7 +318,7 @@ u64 ntfs_inode_lookup_by_name(ntfs_inode *dir_ni,
*/
if (ie->ie_flags & INDEX_ENTRY_END)
break;
if (!le16_to_cpu(ie->length)) {
ntfs_log_error("Zero length index entry in inode %lld"
"\n", (unsigned long long)dir_ni->mft_no);
@ -441,7 +446,7 @@ descend_into_child_node:
(u8*)ie + le16_to_cpu(ie->key_length) >
index_end) {
ntfs_log_error("Index entry out of bounds in directory "
"inode %lld.\n",
"inode %lld.\n",
(unsigned long long)dir_ni->mft_no);
errno = EIO;
goto close_err_out;
@ -452,7 +457,7 @@ descend_into_child_node:
*/
if (ie->ie_flags & INDEX_ENTRY_END)
break;
if (!le16_to_cpu(ie->length)) {
errno = EIO;
ntfs_log_error("Zero length index entry in inode %lld"
@ -681,9 +686,9 @@ ntfs_inode *ntfs_pathname_to_inode(ntfs_volume *vol, ntfs_inode *parent,
errno = EINVAL;
return NULL;
}
ntfs_log_trace("path: '%s'\n", pathname);
ascii = strdup(pathname);
if (!ascii) {
ntfs_log_error("Out of memory.\n");
@ -818,7 +823,7 @@ ntfs_inode *ntfs_pathname_to_inode(ntfs_volume *vol, ntfs_inode *parent,
err = EIO;
goto close;
}
free(unicode);
unicode = NULL;
@ -974,7 +979,7 @@ static int ntfs_filldir(ntfs_inode *dir_ni, s64 *pos, u8 ivcn_bits,
MFT_REF mref;
ntfs_log_trace("Entering.\n");
/* Advance the position even if going to skip the entry. */
if (index_type == INDEX_TYPE_ALLOCATION)
*pos = (u8*)ie - (u8*)iu.ia + (sle64_to_cpu(
@ -1055,7 +1060,7 @@ static MFT_REF ntfs_mft_get_parent_ref(ntfs_inode *ni)
int eo;
ntfs_log_trace("Entering.\n");
if (!ni) {
errno = EINVAL;
return ERR_MREF(-1);
@ -1065,7 +1070,7 @@ static MFT_REF ntfs_mft_get_parent_ref(ntfs_inode *ni)
if (!ctx)
return ERR_MREF(-1);
if (ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, 0, 0, NULL, 0, ctx)) {
ntfs_log_error("No file name found in inode %lld\n",
ntfs_log_error("No file name found in inode %lld\n",
(unsigned long long)ni->mft_no);
goto err_out;
}
@ -1126,7 +1131,7 @@ int ntfs_readdir(ntfs_inode *dir_ni, s64 *pos,
u8 index_block_size_bits, index_vcn_size_bits;
ntfs_log_trace("Entering.\n");
if (!dir_ni || !pos || !filldir) {
errno = EINVAL;
return -1;
@ -1246,10 +1251,10 @@ int ntfs_readdir(ntfs_inode *dir_ni, s64 *pos,
/* The last entry cannot contain a name. */
if (ie->ie_flags & INDEX_ENTRY_END)
break;
if (!le16_to_cpu(ie->length))
goto dir_err_out;
/* Skip index root entry if continuing previous readdir. */
if (ir_pos > (u8*)ie - (u8*)ir)
continue;
@ -1402,10 +1407,10 @@ find_next_index_buffer:
/* The last entry cannot contain a name. */
if (ie->ie_flags & INDEX_ENTRY_END)
break;
if (!le16_to_cpu(ie->length))
goto dir_err_out;
/* Skip index entry if continuing previous readdir. */
if (ia_pos - ia_start > (u8*)ie - (u8*)ia)
continue;
@ -1492,19 +1497,19 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, le32 securid,
int err, fn_len, si_len;
ntfs_log_trace("Entering.\n");
/* Sanity checks. */
if (!dir_ni || !name || !name_len) {
ntfs_log_error("Invalid arguments.\n");
errno = EINVAL;
return NULL;
}
if (dir_ni->flags & FILE_ATTR_REPARSE_POINT) {
errno = EOPNOTSUPP;
return NULL;
}
ni = ntfs_mft_record_alloc(dir_ni->vol, NULL);
if (!ni)
return NULL;
@ -1596,7 +1601,7 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, le32 securid,
ni->vol->indx_record_size >>
ni->vol->cluster_size_bits;
else
ir->clusters_per_index_block =
ir->clusters_per_index_block =
ni->vol->indx_record_size >>
NTFS_BLOCK_SIZE_BITS;
ir->index.entries_offset = cpu_to_le32(sizeof(INDEX_HEADER));
@ -1725,7 +1730,7 @@ err_out:
if (rollback_sd)
ntfs_attr_remove(ni, AT_SECURITY_DESCRIPTOR, AT_UNNAMED, 0);
if (rollback_data)
ntfs_attr_remove(ni, AT_DATA, AT_UNNAMED, 0);
/*
@ -1790,7 +1795,7 @@ int ntfs_check_empty_dir(ntfs_inode *ni)
{
ntfs_attr *na;
int ret = 0;
if (!(ni->mrec->flags & MFT_RECORD_IS_DIRECTORY))
return 0;
@ -1800,7 +1805,7 @@ int ntfs_check_empty_dir(ntfs_inode *ni)
ntfs_log_perror("Failed to open directory");
return -1;
}
/* Non-empty directory? */
if ((na->data_size != sizeof(INDEX_ROOT) + sizeof(INDEX_ENTRY_HEADER))){
/* Both ENOTEMPTY and EEXIST are ok. We use the more common. */
@ -1808,7 +1813,7 @@ int ntfs_check_empty_dir(ntfs_inode *ni)
ntfs_log_debug("Directory is not empty\n");
ret = -1;
}
ntfs_attr_close(na);
return ret;
}
@ -1817,23 +1822,23 @@ static int ntfs_check_unlinkable_dir(ntfs_inode *ni, FILE_NAME_ATTR *fn)
{
int link_count = le16_to_cpu(ni->mrec->link_count);
int ret;
ret = ntfs_check_empty_dir(ni);
if (!ret || errno != ENOTEMPTY)
return ret;
/*
/*
* Directory is non-empty, so we can unlink only if there is more than
* one "real" hard link, i.e. links aren't different DOS and WIN32 names
*/
if ((link_count == 1) ||
if ((link_count == 1) ||
(link_count == 2 && fn->file_name_type == FILE_NAME_DOS)) {
errno = ENOTEMPTY;
ntfs_log_debug("Non-empty directory without hard links\n");
goto no_hardlink;
}
ret = 0;
no_hardlink:
no_hardlink:
return ret;
}
@ -1872,7 +1877,7 @@ int ntfs_delete(ntfs_volume *vol, const char *pathname,
#endif
ntfs_log_trace("Entering.\n");
if (!ni || !dir_ni || !name || !name_len) {
ntfs_log_error("Invalid arguments.\n");
errno = EINVAL;
@ -1918,12 +1923,12 @@ search:
else
continue;
}
/* Ignore hard links from other directories */
if (dir_ni->mft_no != MREF_LE(fn->parent_directory)) {
ntfs_log_debug("MFT record numbers don't match "
"(%llu != %llu)\n",
(long long unsigned)dir_ni->mft_no,
"(%llu != %llu)\n",
(long long unsigned)dir_ni->mft_no,
(long long unsigned)MREF_LE(fn->parent_directory));
continue;
}
@ -1931,11 +1936,11 @@ search:
|| ((fn->file_name_type == FILE_NAME_POSIX)
&& NVolCaseSensitive(ni->vol)))
case_sensitive = CASE_SENSITIVE;
if (ntfs_names_are_equal(fn->file_name, fn->file_name_length,
name, name_len, case_sensitive,
name, name_len, case_sensitive,
ni->vol->upcase, ni->vol->upcase_len)){
if (fn->file_name_type == FILE_NAME_WIN32) {
looking_for_dos_name = TRUE;
ntfs_attr_reinit_search_ctx(actx);
@ -1958,13 +1963,13 @@ search:
}
goto err_out;
}
if (ntfs_check_unlinkable_dir(ni, fn) < 0)
goto err_out;
if (ntfs_index_remove(dir_ni, ni, fn, le32_to_cpu(actx->attr->value_length)))
goto err_out;
/*
* Keep the last name in place, this is useful for undeletion
* (Windows also does so), however delete the name if it were
@ -1977,10 +1982,10 @@ search:
if (ntfs_attr_record_rm(actx))
goto err_out;
}
ni->mrec->link_count = cpu_to_le16(le16_to_cpu(
ni->mrec->link_count) - 1);
ntfs_inode_mark_dirty(ni);
if (looking_for_dos_name) {
looking_for_dos_name = FALSE;
@ -2106,7 +2111,7 @@ search:
"Leaving inconsistent metadata.\n");
}
ni = NULL;
ok:
ok:
ntfs_inode_update_times(dir_ni, NTFS_UPDATE_MCTIME);
out:
if (actx)
@ -2149,14 +2154,14 @@ static int ntfs_link_i(ntfs_inode *ni, ntfs_inode *dir_ni, const ntfschar *name,
int fn_len, err;
ntfs_log_trace("Entering.\n");
if (!ni || !dir_ni || !name || !name_len ||
if (!ni || !dir_ni || !name || !name_len ||
ni->mft_no == dir_ni->mft_no) {
err = EINVAL;
ntfs_log_perror("ntfs_link wrong arguments");
goto err_out;
}
if ((ni->flags & FILE_ATTR_REPARSE_POINT)
&& !ntfs_possible_symlink(ni)) {
err = EOPNOTSUPP;
@ -2171,7 +2176,7 @@ static int ntfs_link_i(ntfs_inode *ni, ntfs_inode *dir_ni, const ntfschar *name,
else
ni->flags &= ~FILE_ATTR_HIDDEN;
}
/* Create FILE_NAME attribute. */
fn_len = sizeof(FILE_NAME_ATTR) + name_len * sizeof(ntfschar);
fn = ntfs_calloc(fn_len);
@ -2559,7 +2564,7 @@ static int set_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni,
if (set_namespace(ni, dir_ni, longname, longlen,
FILE_NAME_WIN32_AND_DOS) >= 0) {
if (!ntfs_delete(vol,
(const char*)NULL, ni, dir_ni,
(const char*)NULL, ni, dir_ni,
deletename, deletelen))
res = 0;
deleted = TRUE;
@ -2580,7 +2585,7 @@ static int set_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni,
res = -1;
}
} else {
if (!ntfs_link_i(ni, dir_ni, shortname, shortlen,
if (!ntfs_link_i(ni, dir_ni, shortname, shortlen,
FILE_NAME_DOS)
/* make sure a new link was recorded */
&& (le16_to_cpu(ni->mrec->link_count) > linkcount)) {
@ -2756,7 +2761,7 @@ int ntfs_remove_ntfs_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni)
} else {
/*
* DOS name has been found, but cannot
* migrate to Posix : something bad
* migrate to Posix : something bad
* has happened
*/
errno = EIO;

View File

@ -54,6 +54,8 @@
#include <locale.h>
#endif
typedef double f64;
#include "ntfs.h"
#include "types.h"
#include "logging.h"
@ -62,6 +64,7 @@
#include "cache.h"
#include "device.h"
#include "bootsect.h"
#include "mem_allocate.h"
#define DEV_FD(dev) ((gekko_fd *)dev->d_private)
@ -119,7 +122,7 @@ static int ntfs_device_gekko_io_open(struct ntfs_device *dev, int flags)
}
if (!interface->readSectors(fd->startSector, 1, boot)) {
ntfs_log_perror("read failure @ sector %d\n", fd->startSector);
ntfs_log_perror("read failure @ sector %d\n", (int)fd->startSector);
errno = EIO;
ntfs_free(boot);
return -1;
@ -318,7 +321,7 @@ static s64 ntfs_device_gekko_io_readbytes(struct ntfs_device *dev, s64 offset, s
// Read from the device
ntfs_log_trace("direct read from sector %d (%d sector(s) long)\n", sec_start, sec_count);
if (!ntfs_device_gekko_io_readsectors(dev, sec_start, sec_count, buf)) {
ntfs_log_perror("direct read failure @ sector %d (%d sector(s) long)\n", sec_start, sec_count);
ntfs_log_perror("direct read failure @ sector %d (%d sector(s) long)\n", (int)sec_start, (int)sec_count);
errno = EIO;
return -1;
}
@ -336,10 +339,10 @@ static s64 ntfs_device_gekko_io_readbytes(struct ntfs_device *dev, s64 offset, s
}
// Read from the device
ntfs_log_trace("buffered read from sector %d (%d sector(s) long)\n", sec_start, sec_count);
ntfs_log_trace("buffered read from sector %d (%d sector(s) long)\n", (int)sec_start, (int)sec_count);
ntfs_log_trace("count: %d sec_count:%d fd->sectorSize: %d )\n", (u32)count, (u32)sec_count,(u32)fd->sectorSize);
if (!ntfs_device_gekko_io_readsectors(dev, sec_start, sec_count, buffer)) {
ntfs_log_perror("buffered read failure @ sector %d (%d sector(s) long)\n", sec_start, sec_count);
ntfs_log_perror("buffered read failure @ sector %d (%d sector(s) long)\n", (int)sec_start, (int)sec_count);
ntfs_free(buffer);
errno = EIO;
return -1;
@ -406,9 +409,9 @@ static s64 ntfs_device_gekko_io_writebytes(struct ntfs_device *dev, s64 offset,
if((buffer_offset == 0) && (count % fd->sectorSize == 0))
{
// Write to the device
ntfs_log_trace("direct write to sector %d (%d sector(s) long)\n", sec_start, sec_count);
ntfs_log_trace("direct write to sector %d (%d sector(s) long)\n", (int)sec_start, (int)sec_count);
if (!ntfs_device_gekko_io_writesectors(dev, sec_start, sec_count, buf)) {
ntfs_log_perror("direct write failure @ sector %d (%d sector(s) long)\n", sec_start, sec_count);
ntfs_log_perror("direct write failure @ sector %d (%d sector(s) long)\n", (int)sec_start, (int)sec_count);
errno = EIO;
return -1;
}
@ -428,7 +431,7 @@ static s64 ntfs_device_gekko_io_writebytes(struct ntfs_device *dev, s64 offset,
if(buffer_offset != 0)
{
if (!ntfs_device_gekko_io_readsectors(dev, sec_start, 1, buffer)) {
ntfs_log_perror("read failure @ sector %d\n", sec_start);
ntfs_log_perror("read failure @ sector %d\n", (int)sec_start);
ntfs_free(buffer);
errno = EIO;
return -1;
@ -437,7 +440,7 @@ static s64 ntfs_device_gekko_io_writebytes(struct ntfs_device *dev, s64 offset,
if((buffer_offset+count) % fd->sectorSize != 0)
{
if (!ntfs_device_gekko_io_readsectors(dev, sec_start + sec_count - 1, 1, buffer + ((sec_count-1) * fd->sectorSize))) {
ntfs_log_perror("read failure @ sector %d\n", sec_start + sec_count - 1);
ntfs_log_perror("read failure @ sector %d\n", (int)sec_start + (int)sec_count - 1);
ntfs_free(buffer);
errno = EIO;
return -1;
@ -450,7 +453,7 @@ static s64 ntfs_device_gekko_io_writebytes(struct ntfs_device *dev, s64 offset,
// Write to the device
ntfs_log_trace("buffered write to sector %d (%d sector(s) long)\n", sec_start, sec_count);
if (!ntfs_device_gekko_io_writesectors(dev, sec_start, sec_count, buffer)) {
ntfs_log_perror("buffered write failure @ sector %d\n", sec_start);
ntfs_log_perror("buffered write failure @ sector %d\n", (int)sec_start);
ntfs_free(buffer);
errno = EIO;
return -1;

View File

@ -27,8 +27,18 @@
#include "types.h"
#include "cache2.h"
#include <gccore.h>
#include <ogc/disc_io.h>
#if defined (__WIIU__)
#include <iosuhax_disc_interface.h>
typedef uint8_t u8;
typedef uint16_t u16;
typedef int32_t s32;
typedef uint32_t u32;
typedef int mutex_t;
#elif defined(__gamecube__) || defined (__wii__)
#include <ogc/disc_io.h>
#include <gccore.h>
#endif
#define MAX_SECTOR_SIZE 4096
@ -49,6 +59,7 @@ typedef struct _gekko_fd {
u32 cachePageSize; /* The number of sectors per cache page */
} gekko_fd;
/* Forward declarations */
struct ntfs_device_operations;

File diff suppressed because it is too large Load Diff

View File

@ -124,7 +124,7 @@ ntfs_inode *ntfs_inode_allocate(ntfs_volume *vol)
static void __ntfs_inode_release(ntfs_inode *ni)
{
if (NInoDirty(ni))
ntfs_log_error("Releasing dirty inode %lld!\n",
ntfs_log_error("Releasing dirty inode %lld!\n",
(long long)ni->mft_no);
if (NInoAttrList(ni) && ni->attr_list)
free(ni->attr_list);
@ -243,7 +243,7 @@ static ntfs_inode *ntfs_inode_real_open(ntfs_volume *vol, const MFT_REF mref)
if (l != ni->attr_list_size) {
errno = EIO;
ntfs_log_perror("Unexpected attrlist size (%lld <> %u), inode "
"%lld", (long long)l, ni->attr_list_size,
"%lld", (long long)l, (unsigned int) ni->attr_list_size,
(long long)MREF(mref));
goto put_err_out;
}
@ -273,7 +273,7 @@ get_size:
set_nino_flag(ni,KnownSize);
}
ntfs_attr_put_search_ctx(ctx);
out:
out:
ntfs_log_leave("\n");
return ni;
@ -313,7 +313,7 @@ err_out:
int ntfs_inode_real_close(ntfs_inode *ni)
{
int ret = -1;
if (!ni)
return 0;
@ -378,8 +378,8 @@ int ntfs_inode_real_close(ntfs_inode *ni)
i = -1;
break;
}
/*
/*
* We could successfully sync, so only log this error
* and try to sync other inode extents too.
*/
@ -387,7 +387,7 @@ int ntfs_inode_real_close(ntfs_inode *ni)
ntfs_log_error("Extent inode %lld was not found\n",
(long long)ni->mft_no);
}
__ntfs_inode_release(ni);
ret = 0;
err:
@ -585,11 +585,11 @@ ntfs_inode *ntfs_extent_inode_open(ntfs_inode *base_ni, const MFT_REF mref)
ntfs_log_perror("%s", __FUNCTION__);
return NULL;
}
ntfs_log_enter("Opening extent inode %lld (base mft record %lld).\n",
(unsigned long long)mft_no,
(unsigned long long)base_ni->mft_no);
if (!base_ni->mft_no) {
/*
* When getting extents of MFT, we must be sure
@ -833,7 +833,7 @@ static int ntfs_inode_sync_file_name(ntfs_inode *ni, ntfs_inode *dir_ni)
if (dir_ni)
index_ni = dir_ni;
else
index_ni = ntfs_inode_open(ni->vol,
index_ni = ntfs_inode_open(ni->vol,
le64_to_cpu(fn->parent_directory));
if (!index_ni) {
if (!err)
@ -996,8 +996,8 @@ static int ntfs_inode_sync_in_dir(ntfs_inode *ni, ntfs_inode *dir_ni)
}
NInoAttrListSetDirty(ni);
goto sync_inode;
}
}
if (na->data_size == ni->attr_list_size) {
if (ntfs_attr_pwrite(na, 0, ni->attr_list_size,
ni->attr_list) != ni->attr_list_size) {
@ -1019,7 +1019,7 @@ static int ntfs_inode_sync_in_dir(ntfs_inode *ni, ntfs_inode *dir_ni)
}
ntfs_attr_close(na);
}
sync_inode:
/* Write this inode out to the $MFT (and $MFTMirr if applicable). */
if (NInoTestAndClearDirty(ni)) {
@ -1045,8 +1045,8 @@ sync_inode:
eni = ni->extent_nis[i];
if (!NInoTestAndClearDirty(eni))
continue;
if (ntfs_mft_record_write(eni->vol, eni->mft_no,
if (ntfs_mft_record_write(eni->vol, eni->mft_no,
eni->mrec)) {
if (!err || errno == EIO) {
err = errno;
@ -1066,7 +1066,7 @@ sync_inode:
errno = err;
ret = -1;
}
ntfs_log_leave("\n");
return ret;
}
@ -1135,19 +1135,19 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
}
/* Walk through all attributes. */
while (!ntfs_attr_lookup(AT_UNUSED, NULL, 0, 0, 0, NULL, 0, ctx)) {
int ale_size;
if (ctx->attr->type == AT_ATTRIBUTE_LIST) {
err = EIO;
ntfs_log_perror("Attribute list already present");
goto put_err_out;
}
ale_size = (sizeof(ATTR_LIST_ENTRY) + sizeof(ntfschar) *
ctx->attr->name_length + 7) & ~7;
al_len += ale_size;
aln = realloc(al, al_len);
if (!aln) {
err = errno;
@ -1156,9 +1156,9 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
}
ale = (ATTR_LIST_ENTRY *)(aln + ((u8 *)ale - al));
al = aln;
memset(ale, 0, ale_size);
/* Add attribute to attribute list. */
ale->type = ctx->attr->type;
ale->length = cpu_to_le16((sizeof(ATTR_LIST_ENTRY) +
@ -1225,7 +1225,7 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
ntfs_attr_close(na);
goto remove_attrlist_record;;
}
ntfs_attr_put_search_ctx(ctx);
ntfs_attr_close(na);
return 0;
@ -1326,12 +1326,12 @@ int ntfs_inode_free_space(ntfs_inode *ni, int size)
* find next, because we don't need such.
*/
while (ctx->ntfs_ino->mft_no != ni->mft_no) {
retry:
retry:
if (ntfs_attr_position(AT_UNUSED, ctx))
goto put_err_out;
}
if (ntfs_inode_base(ctx->ntfs_ino)->mft_no == FILE_MFT &&
if (ntfs_inode_base(ctx->ntfs_ino)->mft_no == FILE_MFT &&
ctx->attr->type == AT_DATA)
goto retry;
@ -1352,10 +1352,10 @@ retry:
return 0;
}
/*
* Reposition to first attribute after $STANDARD_INFORMATION
* and $ATTRIBUTE_LIST instead of simply skipping this attribute
* because in the case when we have got only in-memory attribute
* list then ntfs_attr_lookup will fail when it tries to find
* Reposition to first attribute after $STANDARD_INFORMATION
* and $ATTRIBUTE_LIST instead of simply skipping this attribute
* because in the case when we have got only in-memory attribute
* list then ntfs_attr_lookup will fail when it tries to find
* $ATTRIBUTE_LIST.
*/
ntfs_attr_reinit_search_ctx(ctx);
@ -1397,7 +1397,7 @@ void ntfs_inode_update_times(ntfs_inode *ni, ntfs_time_update_flags mask)
ni->last_data_change_time = now;
if (mask & NTFS_UPDATE_CTIME)
ni->last_mft_change_time = now;
NInoFileNameSetDirty(ni);
NInoSetDirty(ni);
}
@ -1410,7 +1410,7 @@ void ntfs_inode_update_times(ntfs_inode *ni, ntfs_time_update_flags mask)
* Check if the mft record given by @mft_no and @attr contains the bad sector
* list. Please note that mft record numbers describing $Badclus extent inodes
* will not match the current $Badclus:$Bad check.
*
*
* On success return 1 if the file is $Badclus:$Bad, otherwise return 0.
* On error return -1 with errno set to the error code.
*/
@ -1424,7 +1424,7 @@ int ntfs_inode_badclus_bad(u64 mft_no, ATTR_RECORD *attr)
errno = EINVAL;
return -1;
}
if (mft_no != FILE_BadClus)
return 0;
@ -1498,7 +1498,7 @@ int ntfs_inode_get_times(ntfs_inode *ni, char *value, size_t size)
ret = -ERANGE;
}
ntfs_attr_put_search_ctx(ctx);
}
}
return (ret ? ret : -errno);
}

28
source/lock.c Normal file
View File

@ -0,0 +1,28 @@
#ifndef USE_LWP_LOCK
#ifndef mutex_t
typedef int mutex_t;
#endif
void __attribute__ ((weak)) _NTFS_lock_init(mutex_t *mutex, int unkwn)
{
return;
}
void __attribute__ ((weak)) _NTFS_lock_deinit(mutex_t *mutex)
{
return;
}
void __attribute__ ((weak)) _NTFS_lock(mutex_t *mutex)
{
return;
}
void __attribute__ ((weak)) _NTFS_unlock(mutex_t *mutex)
{
return;
}
#endif // USE_LWP_LOCK

108
source/lock.h Normal file
View File

@ -0,0 +1,108 @@
/*
lock.h
Copyright (c) 2008 Sven Peter <svpe@gmx.net>
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. 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.
3. The name of the author may not be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _LOCK_H
#define _LOCK_H
#ifdef USE_LWP_LOCK
static inline void _NTFS_lock_init(mutex_t *mutex, int unkwn)
{
LWP_MutexInit(mutex, false);
}
static inline void _NTFS_lock_deinit(mutex_t *mutex)
{
LWP_MutexDestroy(*mutex);
}
static inline void _NTFS_lock(mutex_t *mutex)
{
LWP_MutexLock(*mutex);
}
static inline void _NTFS_unlock(mutex_t *mutex)
{
LWP_MutexUnlock(*mutex);
}
/* //not working.
#elif defined(__WIIU__)
#ifndef mutex_t
typedef int mutex_t;
#endif
#define OS_MUTEX_SIZE 44
extern void (* OSInitMutex)(void* mutex);
extern void (* OSLockMutex)(void* mutex);
extern void (* OSUnlockMutex)(void* mutex);
extern void (* OSFatal)(const char *msg);
static inline void _NTFS_lock_init(mutex_t *mutex,int unkwn){
void* new_mutex = malloc(OS_MUTEX_SIZE);
if(new_mutex == NULL){
OSFatal("_NTFS_lock_init malloc fail");
}
*mutex = (mutex_t) new_mutex;
OSInitMutex(new_mutex);
}
static inline void _NTFS_lock_deinit(mutex_t *mutex){
free((void*)(*mutex));
*mutex = 0;
}
static inline void _NTFS_lock(mutex_t *mutex)
{
OSLockMutex((void*)*mutex);
}
static inline void _NTFS_unlock(mutex_t *mutex)
{
OSUnlockMutex((void*)*mutex);
}*/
#else
// We still need a blank lock type
#ifndef mutex_t
typedef int mutex_t;
#endif
void _NTFS_lock_init(mutex_t *mutex,int unkwn);
void _NTFS_lock_deinit(mutex_t *mutex);
void _NTFS_lock(mutex_t *mutex);
void _NTFS_unlock(mutex_t *mutex);
#endif // USE_LWP_LOCK
#endif // _LOCK_H

View File

@ -85,7 +85,7 @@ int ntfs_mft_records_read(const ntfs_volume *vol, const MFT_REF mref,
VCN m;
ntfs_log_trace("inode %llu\n", (unsigned long long)MREF(mref));
if (!vol || !vol->mft_na || !b || count < 0) {
errno = EINVAL;
ntfs_log_perror("%s: b=%p count=%lld mft=%llu", __FUNCTION__,
@ -209,12 +209,12 @@ int ntfs_mft_records_write(const ntfs_volume *vol, const MFT_REF mref,
return -1;
}
int ntfs_mft_record_check(const ntfs_volume *vol, const MFT_REF mref,
int ntfs_mft_record_check(const ntfs_volume *vol, const MFT_REF mref,
MFT_RECORD *m)
{
{
ATTR_RECORD *a;
int ret = -1;
if (!ntfs_is_file_record(m->magic)) {
if (!NVolNoFixupWarn(vol))
ntfs_log_error("Record %llu has no FILE magic (0x%x)\n",
@ -222,22 +222,22 @@ int ntfs_mft_record_check(const ntfs_volume *vol, const MFT_REF mref,
(int)le32_to_cpu(*(le32*)m));
goto err_out;
}
if (le32_to_cpu(m->bytes_allocated) != vol->mft_record_size) {
ntfs_log_error("Record %llu has corrupt allocation size "
"(%u <> %u)\n", (unsigned long long)MREF(mref),
vol->mft_record_size,
le32_to_cpu(m->bytes_allocated));
(unsigned int) vol->mft_record_size,
(unsigned int) le32_to_cpu(m->bytes_allocated));
goto err_out;
}
a = (ATTR_RECORD *)((char *)m + le16_to_cpu(m->attrs_offset));
if (p2n(a) < p2n(m) || (char *)a > (char *)m + vol->mft_record_size) {
ntfs_log_error("Record %llu is corrupt\n",
(unsigned long long)MREF(mref));
goto err_out;
}
ret = 0;
err_out:
if (ret)
@ -286,7 +286,7 @@ int ntfs_file_record_read(const ntfs_volume *vol, const MFT_REF mref,
ntfs_log_perror("%s: mrec=%p", __FUNCTION__, mrec);
return -1;
}
m = *mrec;
if (!m) {
m = ntfs_malloc(vol->mft_record_size);
@ -298,7 +298,7 @@ int ntfs_file_record_read(const ntfs_volume *vol, const MFT_REF mref,
if (ntfs_mft_record_check(vol, mref, m))
goto err_out;
if (MSEQNO(mref) && MSEQNO(mref) != le16_to_cpu(m->sequence_number)) {
ntfs_log_error("Record %llu has wrong SeqNo (%d <> %d)\n",
(unsigned long long)MREF(mref), MSEQNO(mref),
@ -412,21 +412,21 @@ int ntfs_mft_record_format(const ntfs_volume *vol, const MFT_REF mref)
int ret = -1;
ntfs_log_enter("Entering\n");
m = ntfs_calloc(vol->mft_record_size);
if (!m)
goto out;
if (ntfs_mft_record_layout(vol, mref, m))
goto free_m;
if (ntfs_mft_record_write(vol, mref, m))
goto free_m;
ret = 0;
free_m:
free(m);
out:
out:
ntfs_log_leave("\n");
return ret;
}
@ -486,7 +486,7 @@ static int ntfs_mft_bitmap_find_free_rec(ntfs_volume *vol, ntfs_inode *base_ni)
int ret = -1;
ntfs_log_enter("Entering\n");
mftbmp_na = vol->mftbmp_na;
/*
* Set the end of the pass making sure we do not overflow the mft
@ -521,7 +521,7 @@ static int ntfs_mft_bitmap_find_free_rec(ntfs_volume *vol, ntfs_inode *base_ni)
buf = ntfs_malloc(PAGE_SIZE);
if (!buf)
goto leave;
ntfs_log_debug("Starting bitmap search: pass %u, pass_start 0x%llx, "
"pass_end 0x%llx, data_pos 0x%llx.\n", pass,
(long long)pass_start, (long long)pass_end,
@ -556,18 +556,18 @@ static int ntfs_mft_bitmap_find_free_rec(ntfs_volume *vol, ntfs_inode *base_ni)
byte ? *byte : -1, b);
for (; bit < size && data_pos + bit < pass_end;
bit &= ~7ull, bit += 8) {
/*
/*
* If we're extending $MFT and running out of the first
* mft record (base record) then give up searching since
* no guarantee that the found record will be accessible.
*/
if (ntfs_is_mft(base_ni) && bit > 400)
goto out;
byte = buf + (bit >> 3);
if (*byte == 0xff)
continue;
/* Note: ffz() result must be zero based. */
b = ntfs_ffz((unsigned long)*byte);
if (b < 8 && b >= (bit & 7)) {
@ -606,7 +606,7 @@ static int ntfs_mft_bitmap_find_free_rec(ntfs_volume *vol, ntfs_inode *base_ni)
}
}
/* No free mft records in currently initialized mft bitmap. */
out:
out:
free(buf);
errno = ENOSPC;
leave:
@ -633,9 +633,9 @@ static int ntfs_mft_attr_extend(ntfs_attr *na)
ntfs_log_perror("%s: MP update failed", __FUNCTION__);
goto out;
}
ret = STATUS_OK;
out:
out:
ntfs_log_leave("\n");
return ret;
}
@ -673,7 +673,7 @@ static int ntfs_mft_bitmap_extend_allocation_i(ntfs_volume *vol)
return STATUS_ERROR;
}
lcn = rl->lcn + rl->length;
rl2 = ntfs_cluster_alloc(vol, rl[1].vcn, 1, lcn, DATA_ZONE);
if (!rl2) {
ntfs_log_error("Failed to allocate a cluster for "
@ -809,7 +809,7 @@ undo_alloc:
lcn = rl->lcn;
rl->lcn = rl[1].lcn;
rl->length = 0;
/* FIXME: use an ntfs_cluster_free_* function */
if (ntfs_bitmap_clear_bit(vol->lcnbmp_na, lcn))
ntfs_log_error("Failed to free cluster.%s\n", es);
@ -851,7 +851,7 @@ undo_alloc:
static int ntfs_mft_bitmap_extend_allocation(ntfs_volume *vol)
{
int ret;
ntfs_log_enter("Entering\n");
ret = ntfs_mft_bitmap_extend_allocation_i(vol);
ntfs_log_leave("\n");
@ -879,7 +879,7 @@ static int ntfs_mft_bitmap_extend_initialized(ntfs_volume *vol)
int ret = -1;
ntfs_log_enter("Entering\n");
mftbmp_na = vol->mftbmp_na;
ctx = ntfs_attr_get_search_ctx(mftbmp_na->ni, NULL);
if (!ctx)
@ -909,7 +909,7 @@ static int ntfs_mft_bitmap_extend_initialized(ntfs_volume *vol)
ll = ntfs_attr_pwrite(mftbmp_na, old_initialized_size, 8, &ll);
if (ll == 8) {
ntfs_log_debug("Wrote eight initialized bytes to mft bitmap.\n");
vol->free_mft_records += (8 * 8);
vol->free_mft_records += (8 * 8);
ret = 0;
goto out;
}
@ -981,7 +981,7 @@ static int ntfs_mft_data_extend_allocation(ntfs_volume *vol)
BOOL update_mp = FALSE;
ntfs_log_enter("Extending mft data allocation.\n");
mft_na = vol->mft_na;
/*
* Determine the preferred allocation location, i.e. the last lcn of
@ -990,7 +990,7 @@ static int ntfs_mft_data_extend_allocation(ntfs_volume *vol)
*/
rl = ntfs_attr_find_vcn(mft_na,
(mft_na->allocated_size - 1) >> vol->cluster_size_bits);
if (!rl || !rl->length || rl->lcn < 0) {
ntfs_log_error("Failed to determine last allocated "
"cluster of mft data attribute.\n");
@ -998,7 +998,7 @@ static int ntfs_mft_data_extend_allocation(ntfs_volume *vol)
errno = EIO;
goto out;
}
lcn = rl->lcn + rl->length;
ntfs_log_debug("Last lcn of mft data attribute is 0x%llx.\n", (long long)lcn);
/* Minimum allocation is one mft record worth of clusters. */
@ -1009,7 +1009,7 @@ static int ntfs_mft_data_extend_allocation(ntfs_volume *vol)
nr = vol->mft_record_size << 4 >> vol->cluster_size_bits;
if (!nr)
nr = min_nr;
old_last_vcn = rl[1].vcn;
do {
rl2 = ntfs_cluster_alloc(vol, old_last_vcn, nr, lcn, MFT_ZONE);
@ -1029,9 +1029,9 @@ static int ntfs_mft_data_extend_allocation(ntfs_volume *vol)
ntfs_log_debug("Retrying mft data allocation with minimal cluster "
"count %lli.\n", (long long)nr);
} while (1);
ntfs_log_debug("Allocated %lld clusters.\n", (long long)nr);
rl = ntfs_runlists_merge(mft_na->rl, rl2);
if (!rl) {
err = errno;
@ -1045,7 +1045,7 @@ static int ntfs_mft_data_extend_allocation(ntfs_volume *vol)
goto out;
}
mft_na->rl = rl;
/* Find the last run in the new runlist. */
for (; rl[1].length; rl++)
;
@ -1195,13 +1195,13 @@ static int ntfs_mft_record_init(ntfs_volume *vol, s64 size)
ntfs_attr *mft_na;
s64 old_data_initialized, old_data_size;
ntfs_attr_search_ctx *ctx;
ntfs_log_enter("Entering\n");
/* NOTE: Caller must sanity check vol, vol->mft_na and vol->mftbmp_na */
mft_na = vol->mft_na;
/*
* The mft record is outside the initialized data. Extend the mft data
* attribute until it covers the allocated record. The loop is only
@ -1224,10 +1224,10 @@ static int ntfs_mft_record_init(ntfs_volume *vol, s64 size)
(long long)mft_na->data_size,
(long long)mft_na->initialized_size);
}
old_data_initialized = mft_na->initialized_size;
old_data_size = mft_na->data_size;
/*
* Extend mft data initialized size (and data size of course) to reach
* the allocated mft record, formatting the mft records along the way.
@ -1246,7 +1246,7 @@ static int ntfs_mft_record_init(ntfs_volume *vol, s64 size)
goto undo_data_init;
}
}
/* Update the mft data attribute record to reflect the new sizes. */
ctx = ntfs_attr_get_search_ctx(mft_na->ni, NULL);
if (!ctx)
@ -1262,7 +1262,7 @@ static int ntfs_mft_record_init(ntfs_volume *vol, s64 size)
ctx->attr->initialized_size = cpu_to_sle64(mft_na->initialized_size);
ctx->attr->data_size = cpu_to_sle64(mft_na->data_size);
ctx->attr->allocated_size = cpu_to_sle64(mft_na->allocated_size);
/* Ensure the changes make it to disk. */
ntfs_inode_mark_dirty(ctx->ntfs_ino);
ntfs_attr_put_search_ctx(ctx);
@ -1272,21 +1272,21 @@ static int ntfs_mft_record_init(ntfs_volume *vol, s64 size)
(long long)mft_na->allocated_size,
(long long)mft_na->data_size,
(long long)mft_na->initialized_size);
/* Sanity checks. */
if (mft_na->data_size > mft_na->allocated_size ||
mft_na->initialized_size > mft_na->data_size)
NTFS_BUG("mft_na sanity checks failed");
/* Sync MFT to minimize data loss if there won't be clean unmount. */
if (ntfs_inode_sync(mft_na->ni))
goto undo_data_init;
ret = 0;
out:
out:
ntfs_log_leave("\n");
return ret;
undo_data_init:
mft_na->initialized_size = old_data_initialized;
mft_na->data_size = old_data_size;
@ -1299,11 +1299,11 @@ static int ntfs_mft_rec_init(ntfs_volume *vol, s64 size)
ntfs_attr *mft_na;
s64 old_data_initialized, old_data_size;
ntfs_attr_search_ctx *ctx;
ntfs_log_enter("Entering\n");
mft_na = vol->mft_na;
if (size > mft_na->allocated_size || size > mft_na->initialized_size) {
errno = EIO;
ntfs_log_perror("%s: unexpected $MFT sizes, see below", __FUNCTION__);
@ -1315,10 +1315,10 @@ static int ntfs_mft_rec_init(ntfs_volume *vol, s64 size)
(long long)mft_na->initialized_size);
goto out;
}
old_data_initialized = mft_na->initialized_size;
old_data_size = mft_na->data_size;
/* Update the mft data attribute record to reflect the new sizes. */
ctx = ntfs_attr_get_search_ctx(mft_na->ni, NULL);
if (!ctx)
@ -1335,19 +1335,19 @@ static int ntfs_mft_rec_init(ntfs_volume *vol, s64 size)
ctx->attr->data_size = cpu_to_sle64(mft_na->data_size);
/* CHECKME: ctx->attr->allocation_size is already ok? */
/* Ensure the changes make it to disk. */
ntfs_inode_mark_dirty(ctx->ntfs_ino);
ntfs_attr_put_search_ctx(ctx);
/* Sanity checks. */
if (mft_na->data_size > mft_na->allocated_size ||
mft_na->initialized_size > mft_na->data_size)
NTFS_BUG("mft_na sanity checks failed");
out:
out:
ntfs_log_leave("\n");
return ret;
undo_data_init:
mft_na->initialized_size = old_data_initialized;
mft_na->data_size = old_data_size;
@ -1377,7 +1377,7 @@ static ntfs_inode *ntfs_mft_rec_alloc(ntfs_volume *vol)
if (errno != ENOSPC)
goto out;
errno = ENOSPC;
/* strerror() is intentionally used below, we want to log this error. */
ntfs_log_error("No free mft record for $MFT: %s\n", strerror(errno));
@ -1388,7 +1388,7 @@ found_free_rec:
ntfs_log_error("Failed to allocate bit in mft bitmap #2\n");
goto err_out;
}
ll = (bit + 1) << vol->mft_record_size_bits;
if (ll > mft_na->initialized_size)
if (ntfs_mft_rec_init(vol, ll) < 0)
@ -1402,7 +1402,7 @@ found_free_rec:
m = ntfs_malloc(vol->mft_record_size);
if (!m)
goto undo_mftbmp_alloc;
if (ntfs_mft_record_read(vol, bit, m)) {
free(m);
goto undo_mftbmp_alloc;
@ -1470,7 +1470,7 @@ found_free_rec:
base_ni->extent_nis = extent_nis;
}
base_ni->extent_nis[base_ni->nr_extents++] = ni;
/* Make sure the allocated inode is written out to disk later. */
ntfs_inode_mark_dirty(ni);
/* Initialize time, allocated and data size in ntfs_inode struct. */
@ -1486,7 +1486,7 @@ found_free_rec:
ntfs_log_error("allocated %sinode %lld\n",
base_ni ? "extent " : "", (long long)bit);
out:
ntfs_log_leave("\n");
ntfs_log_leave("\n");
return ni;
undo_mftbmp_alloc:
@ -1498,7 +1498,7 @@ err_out:
if (!errno)
errno = EIO;
ni = NULL;
goto out;
goto out;
}
/**
@ -1595,7 +1595,7 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, ntfs_inode *base_ni)
if (base_ni)
ntfs_log_enter("Entering (allocating an extent mft record for "
"base mft record %lld).\n",
"base mft record %lld).\n",
(long long)base_ni->mft_no);
else
ntfs_log_enter("Entering (allocating a base mft record)\n");
@ -1603,7 +1603,7 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, ntfs_inode *base_ni)
errno = EINVAL;
goto out;
}
if (ntfs_is_mft(base_ni)) {
ni = ntfs_mft_rec_alloc(vol);
goto out;
@ -1611,7 +1611,7 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, ntfs_inode *base_ni)
mft_na = vol->mft_na;
mftbmp_na = vol->mftbmp_na;
retry:
retry:
bit = ntfs_mft_bitmap_find_free_rec(vol, base_ni);
if (bit >= 0) {
ntfs_log_debug("found free record (#1) at %lld\n",
@ -1688,7 +1688,7 @@ found_free_rec:
ntfs_log_error("Failed to allocate bit in mft bitmap.\n");
goto err_out;
}
/* The mft bitmap is now uptodate. Deal with mft data attribute now. */
ll = (bit + 1) << vol->mft_record_size_bits;
if (ll > mft_na->initialized_size)
@ -1704,7 +1704,7 @@ found_free_rec:
m = ntfs_malloc(vol->mft_record_size);
if (!m)
goto undo_mftbmp_alloc;
if (ntfs_mft_record_read(vol, bit, m)) {
free(m);
goto undo_mftbmp_alloc;
@ -1787,9 +1787,9 @@ found_free_rec:
/* Return the opened, allocated inode of the allocated mft record. */
ntfs_log_debug("allocated %sinode 0x%llx.\n",
base_ni ? "extent " : "", (long long)bit);
vol->free_mft_records--;
vol->free_mft_records--;
out:
ntfs_log_leave("\n");
ntfs_log_leave("\n");
return ni;
undo_mftbmp_alloc:
@ -1801,7 +1801,7 @@ err_out:
if (!errno)
errno = EIO;
ni = NULL;
goto out;
goto out;
}
/**
@ -1865,7 +1865,7 @@ int ntfs_mft_record_free(ntfs_volume *vol, ntfs_inode *ni)
#else
if (!ntfs_inode_close(ni)) {
#endif
vol->free_mft_records++;
vol->free_mft_records++;
return 0;
}
err = errno;

View File

@ -101,7 +101,7 @@ int ntfs_mst_post_read_fixup_warn(NTFS_RECORD *b, const u32 size,
errno = EIO;
ntfs_log_perror("Incomplete multi-sector transfer: "
"magic: 0x%08x size: %d usa_ofs: %d usa_count:"
" %d data: %d usn: %d", *(le32 *)b, size,
" %d data: %d usn: %d", (unsigned int)*(le32 *)b, (int)size,
usa_ofs, usa_count, *data_pos, usn);
b->magic = magic_BAAD;
return -1;

View File

@ -37,9 +37,12 @@
#include "ntfsinternal.h"
#include "ntfsfile.h"
#include "ntfsdir.h"
#include "gekko_io.h"
#include "cache.h"
// NTFS device driver devoptab
static const devoptab_t devops_ntfs = {
NULL, /* Device name */
@ -197,7 +200,7 @@ int ntfsFindPartitions (const DISC_INTERFACE *interface, sec_t **partitions)
if (sector.boot.oem_id == NTFS_OEM_ID) {
ntfs_log_debug("Logical Partition @ %d: Valid NTFS boot sector found\n", part_lba);
if(sector.ebr.partition.type != PARTITION_TYPE_NTFS) {
ntfs_log_warning("Logical Partition @ %d: Is NTFS but type is 0x%x; 0x%x was expected\n", part_lba, sector.ebr.partition.type, PARTITION_TYPE_NTFS);
ntfs_log_warning("Logical Partition @ %d: Is NTFS but type is 0x%x; 0x%x was expected\n", (int) part_lba, sector.ebr.partition.type, PARTITION_TYPE_NTFS);
}
if (partition_count < NTFS_MAX_PARTITIONS) {
partition_starts[partition_count] = part_lba;
@ -317,6 +320,27 @@ int ntfsMountAll (ntfs_md **mounts, u32 flags)
}
ntfs_free(partitions);
}else if(partition_count == 0){
int k = 0;
// Find the next unused mount name
do {
sprintf(name, "%s%i", NTFS_MOUNT_PREFIX, k++);
if (k >= NTFS_MAX_MOUNTS) {
ntfs_free(partitions);
errno = EADDRNOTAVAIL;
return -1;
}
} while (ntfsGetDevice(name, false));
// Mount the partition
if (mount_count < NTFS_MAX_MOUNTS) {
if (ntfsMount(name, disc->interface, 0, CACHE_DEFAULT_PAGE_SIZE, CACHE_DEFAULT_PAGE_COUNT, flags)) {
strcpy(mount_points[mount_count].name, name);
mount_points[mount_count].interface = disc->interface;
mount_points[mount_count].startSector = 0;
mount_count++;
}
}
}
}

View File

@ -220,7 +220,7 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
return (int)fileStruct;
}
int ntfs_close_r (struct _reent *r, int fd)
int ntfs_close_r (struct _reent *r, void * fd)
{
ntfs_log_trace("fd %p\n", (void *) fd);
@ -253,7 +253,7 @@ int ntfs_close_r (struct _reent *r, int fd)
return 0;
}
ssize_t ntfs_write_r (struct _reent *r, int fd, const char *ptr, size_t len)
ssize_t ntfs_write_r (struct _reent *r, void * fd, const char *ptr, size_t len)
{
ntfs_log_trace("fd %p, ptr %p, len %u\n", (void *) fd, ptr, len);
@ -319,7 +319,7 @@ ssize_t ntfs_write_r (struct _reent *r, int fd, const char *ptr, size_t len)
return written;
}
ssize_t ntfs_read_r (struct _reent *r, int fd, char *ptr, size_t len)
ssize_t ntfs_read_r (struct _reent *r, void * fd, char *ptr, size_t len)
{
ntfs_log_trace("fd %p, ptr %p, len %u\n", (void *) fd, ptr, len);
@ -378,7 +378,7 @@ ssize_t ntfs_read_r (struct _reent *r, int fd, char *ptr, size_t len)
return read;
}
off_t ntfs_seek_r (struct _reent *r, int fd, off_t pos, int dir)
off_t ntfs_seek_r (struct _reent *r, void * fd, off_t pos, int dir)
{
ntfs_log_trace("fd %p, pos %llu, dir %i\n", (void *) fd, pos, dir);
@ -406,7 +406,7 @@ off_t ntfs_seek_r (struct _reent *r, int fd, off_t pos, int dir)
return position;
}
int ntfs_fstat_r (struct _reent *r, int fd, struct stat *st)
int ntfs_fstat_r (struct _reent *r, void * fd, struct stat *st)
{
ntfs_log_trace("fd %p\n", (void *) fd);
@ -431,7 +431,7 @@ int ntfs_fstat_r (struct _reent *r, int fd, struct stat *st)
return ret;
}
int ntfs_ftruncate_r (struct _reent *r, int fd, off_t len)
int ntfs_ftruncate_r (struct _reent *r, void * fd, off_t len)
{
ntfs_log_trace("fd %p, len %llu\n", (void *) fd, (u64) len);
@ -498,7 +498,7 @@ int ntfs_ftruncate_r (struct _reent *r, int fd, off_t len)
return 0;
}
int ntfs_fsync_r (struct _reent *r, int fd)
int ntfs_fsync_r (struct _reent *r, void * fd)
{
ntfs_log_trace("fd %p\n", (void *) fd);

View File

@ -53,13 +53,13 @@ void ntfsCloseFile (ntfs_file_state *file);
/* Gekko devoptab file routines for NTFS-based devices */
extern int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags, int mode);
extern int ntfs_close_r (struct _reent *r, int fd);
extern ssize_t ntfs_write_r (struct _reent *r, int fd, const char *ptr, size_t len);
extern ssize_t ntfs_read_r (struct _reent *r, int fd, char *ptr, size_t len);
extern off_t ntfs_seek_r (struct _reent *r, int fd, off_t pos, int dir);
extern int ntfs_fstat_r (struct _reent *r, int fd, struct stat *st);
extern int ntfs_ftruncate_r (struct _reent *r, int fd, off_t len);
extern int ntfs_fsync_r (struct _reent *r, int fd);
extern int ntfs_close_r (struct _reent *r, void *fd);
extern ssize_t ntfs_write_r (struct _reent *r, void * fd, const char *ptr, size_t len);
extern ssize_t ntfs_read_r (struct _reent *r, void * fd, char *ptr, size_t len);
extern off_t ntfs_seek_r (struct _reent *r, void * fd, off_t pos, int dir);
extern int ntfs_fstat_r (struct _reent *r, void * fd, struct stat *st);
extern int ntfs_ftruncate_r (struct _reent *r, void * fd, off_t len);
extern int ntfs_fsync_r (struct _reent *r, void * fd);
#endif /* _NTFSFILE_H */

View File

@ -37,6 +37,7 @@
#include "ntfsinternal.h"
#include "ntfsdir.h"
#include "ntfsfile.h"
#include "lock.h"
#if defined(__wii__)
#include <sdcard/wiisd_io.h>
@ -51,6 +52,15 @@ const INTERFACE_ID ntfs_disc_interfaces[] = {
{ NULL, NULL }
};
#elif defined (__WIIU__)
#include <iosuhax_disc_interface.h>
const INTERFACE_ID ntfs_disc_interfaces[] = {
{"sd", &IOSUHAX_sdio_disc_interface},
{"usb", &IOSUHAX_usb_disc_interface},
{NULL, NULL}
};
#elif defined(__gamecube__)
#include <sdcard/gcsd.h>
@ -190,7 +200,7 @@ int ntfsInitVolume (ntfs_vd *vd)
}
// Initialise the volume lock
LWP_MutexInit(&vd->lock, false);
_NTFS_lock_init(&vd->lock, false);
// Reset the volumes name cache
vd->name[0] = '\0';
@ -253,7 +263,7 @@ void ntfsDeinitVolume (ntfs_vd *vd)
ntfsUnlock(vd);
// Deinitialise the volume lock
LWP_MutexDestroy(vd->lock);
_NTFS_lock_deinit((mutex_t *)vd->lock);
return;
}

View File

@ -38,10 +38,21 @@
#include "reparse.h"
#include "security.h"
#include "efs.h"
#include "lock.h"
#include "unistr.h"
#include <gccore.h>
#include <ogc/disc_io.h>
#if defined (__WIIU__)
#include <iosuhax_disc_interface.h>
typedef uint8_t u8;
typedef uint16_t u16;
typedef int32_t s32;
typedef uint32_t u32;
typedef int mutex_t;
#elif defined(__gamecube__) || defined (__wii__)
#include <ogc/disc_io.h>
#include <gccore.h>
#endif
#include <sys/iosupport.h>
#define NTFS_MOUNT_PREFIX "ntfs" /* Device name prefix to use when auto-mounting */
@ -141,13 +152,13 @@ typedef struct _ntfs_vd {
/* Lock volume */
static inline void ntfsLock (ntfs_vd *vd)
{
LWP_MutexLock(vd->lock);
_NTFS_lock((mutex_t *)&vd->lock);
}
/* Unlock volume */
static inline void ntfsUnlock (ntfs_vd *vd)
{
LWP_MutexUnlock(vd->lock);
_NTFS_unlock((mutex_t *)&vd->lock);
}
/* Gekko device related routines */

View File

@ -40,7 +40,7 @@
/*
* assume "struct timespec" is not defined if st_mtime is not defined
*/
#if !defined(st_mtime) & !defined(__timespec_defined)
#if !defined(st_mtime) & !defined(__timespec_defined) & !defined(__WIIU__)
struct timespec {
time_t tv_sec;
long tv_nsec;

View File

@ -75,7 +75,7 @@
#include "realpath.h"
#include "misc.h"
const char *ntfs_home =
const char *ntfs_home =
"News, support and information: http://tuxera.com\n";
static const char *invalid_ntfs_msg =
@ -108,7 +108,7 @@ static const char *opened_volume_msg =
static const char *fakeraid_msg =
"Either the device is missing or it's powered down, or you have\n"
"SoftRAID hardware and must use an activated, different device under\n"
"SoftRAID hardware and must use an activated, different device under\n"
"/dev/mapper/, (e.g. /dev/mapper/nvidia_eahaabcc1) to mount NTFS.\n"
"Please see the 'dmraid' documentation for help.\n";
@ -144,8 +144,8 @@ static int ntfs_inode_free(ntfs_inode **ni)
if (ni && *ni) {
ret = ntfs_inode_close(*ni);
*ni = NULL;
}
}
return ret;
}
@ -169,7 +169,7 @@ static int __ntfs_volume_release(ntfs_volume *v)
if (ntfs_inode_free(&v->vol_ni))
ntfs_error_set(&err);
/*
/*
* FIXME: Inodes must be synced before closing
* attributes, otherwise unmount could fail.
*/
@ -178,20 +178,20 @@ static int __ntfs_volume_release(ntfs_volume *v)
ntfs_attr_free(&v->lcnbmp_na);
if (ntfs_inode_free(&v->lcnbmp_ni))
ntfs_error_set(&err);
if (v->mft_ni && NInoDirty(v->mft_ni))
ntfs_inode_sync(v->mft_ni);
ntfs_attr_free(&v->mftbmp_na);
ntfs_attr_free(&v->mft_na);
if (ntfs_inode_free(&v->mft_ni))
ntfs_error_set(&err);
if (v->mftmirr_ni && NInoDirty(v->mftmirr_ni))
ntfs_inode_sync(v->mftmirr_ni);
ntfs_attr_free(&v->mftmirr_na);
if (ntfs_inode_free(&v->mftmirr_ni))
ntfs_error_set(&err);
if (v->dev) {
struct ntfs_device *dev = v->dev;
@ -260,10 +260,10 @@ static int ntfs_mft_load(ntfs_volume *vol)
ntfs_log_perror("Error reading $MFT");
goto error_exit;
}
if (ntfs_mft_record_check(vol, 0, mb))
goto error_exit;
ctx = ntfs_attr_get_search_ctx(vol->mft_ni, NULL);
if (!ctx)
goto error_exit;
@ -288,7 +288,7 @@ static int ntfs_mft_load(ntfs_volume *vol)
vol->mft_ni->attr_list = ntfs_malloc(l);
if (!vol->mft_ni->attr_list)
goto error_exit;
l = ntfs_get_attribute_value(vol, ctx->attr, vol->mft_ni->attr_list);
if (!l) {
ntfs_log_error("Failed to get value of $MFT/$ATTR_LIST.\n");
@ -297,16 +297,16 @@ static int ntfs_mft_load(ntfs_volume *vol)
if (l != vol->mft_ni->attr_list_size) {
ntfs_log_error("Partial read of $MFT/$ATTR_LIST (%lld != "
"%u).\n", (long long)l,
vol->mft_ni->attr_list_size);
(unsigned int) vol->mft_ni->attr_list_size);
goto io_error_exit;
}
mft_has_no_attr_list:
ntfs_attr_setup_flag(vol->mft_ni);
/* We now have a fully setup ntfs inode for $MFT in vol->mft_ni. */
/* Get an ntfs attribute for $MFT/$DATA and set it up, too. */
vol->mft_na = ntfs_attr_open(vol->mft_ni, AT_DATA, AT_UNNAMED, 0);
if (!vol->mft_na) {
@ -428,18 +428,18 @@ static int ntfs_mftmirr_load(ntfs_volume *vol)
ntfs_log_perror("Failed to open inode $MFTMirr");
return -1;
}
vol->mftmirr_na = ntfs_attr_open(vol->mftmirr_ni, AT_DATA, AT_UNNAMED, 0);
if (!vol->mftmirr_na) {
ntfs_log_perror("Failed to open $MFTMirr/$DATA");
goto error_exit;
}
if (ntfs_attr_map_runlist(vol->mftmirr_na, 0) < 0) {
ntfs_log_perror("Failed to map runlist of $MFTMirr/$DATA");
goto error_exit;
}
return 0;
error_exit:
@ -484,12 +484,12 @@ ntfs_volume *ntfs_volume_startup(struct ntfs_device *dev,
bs = ntfs_malloc(sizeof(NTFS_BOOT_SECTOR));
if (!bs)
return NULL;
/* Allocate the volume structure. */
vol = ntfs_volume_alloc();
if (!vol)
goto error_exit;
/* Create the default upcase table. */
vol->upcase_len = ntfs_upcase_build_default(&vol->upcase);
if (!vol->upcase_len || !vol->upcase)
@ -498,7 +498,7 @@ ntfs_volume *ntfs_volume_startup(struct ntfs_device *dev,
/* Default with no locase table and case sensitive file names */
vol->locase = (ntfschar*)NULL;
NVolSetCaseSensitive(vol);
/* by default, all files are shown and not marked hidden */
NVolSetShowSysFiles(vol);
NVolSetShowHidFiles(vol);
@ -511,7 +511,7 @@ ntfs_volume *ntfs_volume_startup(struct ntfs_device *dev,
#endif
if (flags & NTFS_MNT_RDONLY)
NVolSetReadOnly(vol);
/* ...->open needs bracketing to compile with glibc 2.7 */
if ((dev->d_ops->open)(dev, NVolReadOnly(vol) ? O_RDONLY: O_RDWR)) {
if (!NVolReadOnly(vol) && (errno == EROFS)) {
@ -531,7 +531,7 @@ ntfs_volume *ntfs_volume_startup(struct ntfs_device *dev,
}
/* Attach the device to the volume. */
vol->dev = dev;
/* Now read the bootsector. */
br = ntfs_pread(dev, 0, sizeof(NTFS_BOOT_SECTOR), bs);
if (br != sizeof(NTFS_BOOT_SECTOR)) {
@ -549,7 +549,7 @@ ntfs_volume *ntfs_volume_startup(struct ntfs_device *dev,
}
if (ntfs_boot_sector_parse(vol, bs) < 0)
goto error_exit;
free(bs);
bs = NULL;
/* Now set the device block size to the sector size. */
@ -558,7 +558,7 @@ ntfs_volume *ntfs_volume_startup(struct ntfs_device *dev,
"sector size. This may affect performance "
"but should be harmless otherwise. Error: "
"%s\n", strerror(errno));
/* We now initialize the cluster allocator. */
vol->full_zones = 0;
mft_zone_size = vol->nr_clusters >> 3; /* 12.5% */
@ -652,14 +652,14 @@ static int ntfs_volume_check_logfile(ntfs_volume *vol)
errno = EIO;
return -1;
}
na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
if (!na) {
ntfs_log_perror("Failed to open $FILE_LogFile/$DATA");
err = EIO;
goto out;
}
if (!ntfs_check_logfile(na, &rp) || !ntfs_is_logfile_clean(na, rp))
err = EOPNOTSUPP;
/*
@ -682,7 +682,7 @@ static int ntfs_volume_check_logfile(ntfs_volume *vol)
}
free(rp);
ntfs_attr_close(na);
out:
out:
if (ntfs_inode_close(ni))
ntfs_error_set(&err);
if (err) {
@ -1007,16 +1007,16 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, ntfs_mount_flags flags)
ntfs_log_perror("Failed to open inode FILE_Bitmap");
goto error_exit;
}
vol->lcnbmp_na = ntfs_attr_open(vol->lcnbmp_ni, AT_DATA, AT_UNNAMED, 0);
if (!vol->lcnbmp_na) {
ntfs_log_perror("Failed to open ntfs attribute");
goto error_exit;
}
if (vol->lcnbmp_na->data_size > vol->lcnbmp_na->allocated_size) {
ntfs_log_error("Corrupt cluster map size (%lld > %lld)\n",
(long long)vol->lcnbmp_na->data_size,
(long long)vol->lcnbmp_na->data_size,
(long long)vol->lcnbmp_na->allocated_size);
goto io_error_exit;
}
@ -1172,7 +1172,7 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, ntfs_mount_flags flags)
vol->vol_name = ntfs_malloc(u + 1);
if (!vol->vol_name)
goto error_exit;
for (j = 0; j < (s32)u; j++) {
u16 uc = le16_to_cpu(vname[j]);
if (uc > 0xff)
@ -1639,7 +1639,7 @@ int ntfs_logfile_reset(ntfs_volume *vol)
ntfs_attr_close(na);
goto error_exit;
}
ntfs_attr_close(na);
return ntfs_inode_close(ni);