mirror of
https://github.com/wiiu-env/libntfs.git
synced 2024-11-13 05:35:07 +01:00
Wii U support
This commit is contained in:
parent
968dee4aef
commit
f8705b2c39
26
.github/workflows/push_image.yml
vendored
Normal file
26
.github/workflows/push_image.yml
vendored
Normal 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
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
source/wiiu_release/*
|
||||
source/wii_release/*
|
||||
source/cube_release/*
|
||||
lib/*
|
||||
.idea/*
|
11
Dockerfile.wiiu
Normal file
11
Dockerfile.wiiu
Normal 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
|
17
Makefile
17
Makefile
@ -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
20
README.md
Normal 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
|
||||
```
|
@ -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 */
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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__ */
|
||||
|
||||
|
@ -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__ */
|
||||
|
99
source/dir.c
99
source/dir.c
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
516
source/index.c
516
source/index.c
File diff suppressed because it is too large
Load Diff
@ -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
28
source/lock.c
Normal 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
108
source/lock.h
Normal 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
|
||||
|
146
source/mft.c
146
source/mft.c
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user