diff --git a/.gitignore b/.gitignore
index fd6060e..8120e9f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,4 +5,4 @@
/*.dll
/bin
/test
-/test/*
\ No newline at end of file
+/test/*
diff --git a/filepath.c b/filepath.c
index 98c106c..d96789c 100644
--- a/filepath.c
+++ b/filepath.c
@@ -20,7 +20,7 @@ void os_strcpy(oschar_t *dst, const char *src) {
const UTF8 *sourceStart = (const UTF8 *)src;
UTF16 *targetStart = (UTF16 *)dst;
uint32_t src_len, dst_len;
- src_len = strlen(src);
+ src_len = (uint32_t)strlen(src);
dst_len = src_len + 1;
const UTF8 *sourceEnd = (const UTF8 *)(src + src_len);
UTF16 *targetEnd = (UTF16 *)(dst + dst_len);
diff --git a/hactool-vs2019/.gitignore b/hactool-vs2019/.gitignore
new file mode 100644
index 0000000..a645fe0
--- /dev/null
+++ b/hactool-vs2019/.gitignore
@@ -0,0 +1,5 @@
+.vs
+out
+Win32
+x64
+*.user
diff --git a/hactool-vs2019/getopt.c b/hactool-vs2019/getopt.c
new file mode 100644
index 0000000..8036bee
--- /dev/null
+++ b/hactool-vs2019/getopt.c
@@ -0,0 +1,1223 @@
+/* Getopt for Microsoft C
+This code is a modification of the Free Software Foundation, Inc.
+Getopt library for parsing command line argument the purpose was
+to provide a Microsoft Visual C friendly derivative. This code
+provides functionality for both Unicode and Multibyte builds.
+
+Date: 02/03/2011 - Ludvik Jerabek - Initial Release
+Version: 1.0
+Comment: Supports getopt, getopt_long, and getopt_long_only
+and POSIXLY_CORRECT environment flag
+License: LGPL
+
+Revisions:
+
+09/04/2014 - bowen han get the latest getopt source
+
+**DISCLAIMER**
+Getopt for GNU.
+ NOTE: getopt is part of the C library, so if you don't know what
+ "Keep this file name-space clean" means, talk to drepper@gnu.org
+ before changing it!
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ . */
+//#define _CRT_SECURE_NO_WARNINGS
+
+#include
+
+# include
+#include
+#include
+#include
+#ifndef ELIDE_CODE
+
+#ifndef attribute_hidden
+# define attribute_hidden
+#endif
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+ but it behaves differently for the user, since it allows the user
+ to intersperse the options with the other arguments.
+
+ As `getopt' works, it permutes the elements of ARGV so that,
+ when it is done, all the options precede everything else. Thus
+ all application programs are extended to handle flexible argument order.
+
+ Setting the environment variable POSIXLY_CORRECT disables permutation.
+ Then the behavior is completely standard.
+
+ GNU application programs can use a third alternative mode in which
+ they can distinguish the relative order of options and other arguments. */
+
+#include "getopt.h"
+#include "getopt_int.h"
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+TCHAR *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+/* 1003.2 says this must be 1 before any call. */
+int optind = 1;
+
+/* Callers store zero here to inhibit the error message
+ for unrecognized options. */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+ This must be initialized on some systems to avoid linking in the
+ system's own getopt implementation. */
+
+int optopt = _T('?');
+
+/* Keep a global copy of all internal members of getopt_data. */
+
+static struct _getopt_data getopt_data;
+
+
+#ifndef __GNU_LIBRARY__
+
+
+
+#endif /* not __GNU_LIBRARY__ */
+
+#ifdef _LIBC
+/* Stored original parameters.
+ XXX This is no good solution. We should rather copy the args so
+ that we can compare them later. But we must not use malloc(3). */
+extern int __libc_argc;
+extern TCHAR **__libc_argv;
+
+/* Bash 2.0 gives us an environment variable containing flags
+ indicating ARGV elements that should not be considered arguments. */
+
+# ifdef USE_NONOPTION_FLAGS
+/* Defined in getopt_init.c */
+extern TCHAR *__getopt_nonoption_flags;
+# endif
+
+# ifdef USE_NONOPTION_FLAGS
+# define SWAP_FLAGS(ch1, ch2) \
+ if (d->__nonoption_flags_len > 0) \
+ { \
+ char __tmp = __getopt_nonoption_flags[ch1]; \
+ __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
+ __getopt_nonoption_flags[ch2] = __tmp; \
+ }
+# else
+# define SWAP_FLAGS(ch1, ch2)
+# endif
+#else /* !_LIBC */
+# define SWAP_FLAGS(ch1, ch2)
+#endif /* _LIBC */
+
+/* Exchange two adjacent subsequences of ARGV.
+ One subsequence is elements [first_nonopt,last_nonopt)
+ which contains all the non-options that have been skipped so far.
+ The other is elements [last_nonopt,optind), which contains all
+ the options processed since those non-options were skipped.
+
+ `first_nonopt' and `last_nonopt' are relocated so that they describe
+ the new indices of the non-options in ARGV after they are moved. */
+
+static void
+exchange (TCHAR **argv, struct _getopt_data *d)
+{
+ int bottom = d->__first_nonopt;
+ int middle = d->__last_nonopt;
+ int top = d->optind;
+ TCHAR *tem;
+
+ /* Exchange the shorter segment with the far end of the longer segment.
+ That puts the shorter segment into the right place.
+ It leaves the longer segment in the right place overall,
+ but it consists of two parts that need to be swapped next. */
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+ /* First make sure the handling of the `__getopt_nonoption_flags'
+ string can work normally. Our top argument must be in the range
+ of the string. */
+ if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len)
+ {
+ /* We must extend the array. The user plays games with us and
+ presents new arguments. */
+ TCHAR *new_str = malloc ((top + 1)*sizeof(TCHAR));
+ if (new_str == NULL)
+ d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0;
+ else
+ {
+ memset (__mempcpy (new_str, __getopt_nonoption_flags,
+ d->__nonoption_flags_max_len),
+ '\0', top + 1 - d->__nonoption_flags_max_len);
+ d->__nonoption_flags_max_len = top + 1;
+ __getopt_nonoption_flags = new_str;
+ }
+ }
+#endif
+
+ while (top > middle && middle > bottom)
+ {
+ if (top - middle > middle - bottom)
+ {
+ /* Bottom segment is the short one. */
+ int len = middle - bottom;
+ int i;
+
+ /* Swap it with the top part of the top segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[top - (middle - bottom) + i];
+ argv[top - (middle - bottom) + i] = tem;
+ SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
+ }
+ /* Exclude the moved bottom segment from further swapping. */
+ top -= len;
+ }
+ else
+ {
+ /* Top segment is the short one. */
+ int len = top - middle;
+ int i;
+
+ /* Swap it with the bottom part of the bottom segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[middle + i];
+ argv[middle + i] = tem;
+ SWAP_FLAGS (bottom + i, middle + i);
+ }
+ /* Exclude the moved top segment from further swapping. */
+ bottom += len;
+ }
+ }
+
+ /* Update records for the slots the non-options now occupy. */
+
+ d->__first_nonopt += (d->optind - d->__last_nonopt);
+ d->__last_nonopt = d->optind;
+}
+
+/* Initialize the internal data when the first call is made. */
+
+static const TCHAR *
+_getopt_initialize (int argc, TCHAR *const *argv, const TCHAR *optstring,
+ struct _getopt_data *d, int posixly_correct)
+{
+ /* Start processing options with ARGV-element 1 (since ARGV-element 0
+ is the program name); the sequence of previously skipped
+ non-option ARGV-elements is empty. */
+
+ d->__first_nonopt = d->__last_nonopt = d->optind;
+
+ d->__nextchar = NULL;
+
+ d->__posixly_correct = posixly_correct | !!getenv ("POSIXLY_CORRECT");
+
+ /* Determine how to handle the ordering of options and nonoptions. */
+
+ if (optstring[0] == _T('-'))
+ {
+ d->__ordering = RETURN_IN_ORDER;
+ ++optstring;
+ }
+ else if (optstring[0] == _T('+'))
+ {
+ d->__ordering = REQUIRE_ORDER;
+ ++optstring;
+ }
+ else if (d->__posixly_correct)
+ d->__ordering = REQUIRE_ORDER;
+ else
+ d->__ordering = PERMUTE;
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+ if (!d->__posixly_correct
+ && argc == __libc_argc && argv == __libc_argv)
+ {
+ if (d->__nonoption_flags_max_len == 0)
+ {
+ if (__getopt_nonoption_flags == NULL
+ || __getopt_nonoption_flags[0] == '\0')
+ d->__nonoption_flags_max_len = -1;
+ else
+ {
+ const TCHAR *orig_str = __getopt_nonoption_flags;
+ int len = d->__nonoption_flags_max_len = lstrlen (orig_str);
+ if (d->__nonoption_flags_max_len < argc)
+ d->__nonoption_flags_max_len = argc;
+ __getopt_nonoption_flags =
+ (TCHAR *) malloc ((d->__nonoption_flags_max_len)*sizeof(TCHAR));
+ if (__getopt_nonoption_flags == NULL)
+ d->__nonoption_flags_max_len = -1;
+ else
+ memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
+ '\0', d->__nonoption_flags_max_len - len);
+ }
+ }
+ d->__nonoption_flags_len = d->__nonoption_flags_max_len;
+ }
+ else
+ d->__nonoption_flags_len = 0;
+#endif
+
+ return optstring;
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+ given in OPTSTRING.
+
+ If an element of ARGV starts with '-', and is not exactly "-" or "--",
+ then it is an option element. The characters of this element
+ (aside from the initial '-') are option characters. If `getopt'
+ is called repeatedly, it returns successively each of the option characters
+ from each of the option elements.
+
+ If `getopt' finds another option character, it returns that character,
+ updating `optind' and `nextchar' so that the next call to `getopt' can
+ resume the scan with the following option character or ARGV-element.
+
+ If there are no more option characters, `getopt' returns -1.
+ Then `optind' is the index in ARGV of the first ARGV-element
+ that is not an option. (The ARGV-elements have been permuted
+ so that those that are not options now come last.)
+
+ OPTSTRING is a string containing the legitimate option characters.
+ If an option character is seen that is not listed in OPTSTRING,
+ return '?' after printing an error message. If you set `opterr' to
+ zero, the error message is suppressed but we still return '?'.
+
+ If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+ so the following text in the same ARGV-element, or the text of the following
+ ARGV-element, is returned in `optarg'. Two colons mean an option that
+ wants an optional arg; if there is text in the current ARGV-element,
+ it is returned in `optarg', otherwise `optarg' is set to zero.
+
+ If OPTSTRING starts with `-' or `+', it requests different methods of
+ handling the non-option ARGV-elements.
+ See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+ Long-named options begin with `--' instead of `-'.
+ Their names may be abbreviated as long as the abbreviation is unique
+ or is an exact match for some defined option. If they have an
+ argument, it follows the option name in the same ARGV-element, separated
+ from the option name by a `=', or else the in next ARGV-element.
+ When `getopt' finds a long-named option, it returns 0 if that option's
+ `flag' field is nonzero, the value of the option's `val' field
+ if the `flag' field is zero.
+
+ The elements of ARGV aren't really const, because we permute them.
+ But we pretend they're const in the prototype to be compatible
+ with other systems.
+
+ LONGOPTS is a vector of `struct option' terminated by an
+ element containing a name which is zero.
+
+ LONGIND returns the index in LONGOPT of the long-named option found.
+ It is only valid when a long-named option has been found by the most
+ recent call.
+
+ If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+ long-named options. */
+
+int
+_getopt_internal_r (int argc, TCHAR *const *argv, const TCHAR *optstring,
+ const struct option *longopts, int *longind,
+ int long_only, struct _getopt_data *d, int posixly_correct)
+{
+ int print_errors = d->opterr;
+
+ if (argc < 1)
+ return -1;
+
+ d->optarg = NULL;
+
+ if (d->optind == 0 || !d->__initialized)
+ {
+ if (d->optind == 0)
+ d->optind = 1; /* Don't scan ARGV[0], the program name. */
+ optstring = _getopt_initialize (argc, argv, optstring, d,
+ posixly_correct);
+ d->__initialized = 1;
+ }
+ else if (optstring[0] == _T('-') || optstring[0] == _T('+'))
+ optstring++;
+ if (optstring[0] == _T(':'))
+ print_errors = 0;
+
+ /* Test whether ARGV[optind] points to a non-option argument.
+ Either it does not have option syntax, or there is an environment flag
+ from the shell indicating it is not an option. The later information
+ is only used when the used in the GNU libc. */
+
+# define NONOPTION_P (argv[d->optind][0] != _T('-') || argv[d->optind][1] == _T('\0'))
+
+
+ if (d->__nextchar == NULL || *d->__nextchar == _T('\0'))
+ {
+ /* Advance to the next ARGV-element. */
+
+ /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
+ moved back by the user (who may also have changed the arguments). */
+ if (d->__last_nonopt > d->optind)
+ d->__last_nonopt = d->optind;
+ if (d->__first_nonopt > d->optind)
+ d->__first_nonopt = d->optind;
+
+ if (d->__ordering == PERMUTE)
+ {
+ /* If we have just processed some options following some non-options,
+ exchange them so that the options come first. */
+
+ if (d->__first_nonopt != d->__last_nonopt
+ && d->__last_nonopt != d->optind)
+ exchange ((TCHAR **) argv, d);
+ else if (d->__last_nonopt != d->optind)
+ d->__first_nonopt = d->optind;
+
+ /* Skip any additional non-options
+ and extend the range of non-options previously skipped. */
+
+ while (d->optind < argc && NONOPTION_P)
+ d->optind++;
+ d->__last_nonopt = d->optind;
+ }
+
+ /* The special ARGV-element `--' means premature end of options.
+ Skip it like a null option,
+ then exchange with previous non-options as if it were an option,
+ then skip everything else like a non-option. */
+
+ if (d->optind != argc && !lstrcmp (argv[d->optind], _T("--")))
+ {
+ d->optind++;
+
+ if (d->__first_nonopt != d->__last_nonopt
+ && d->__last_nonopt != d->optind)
+ exchange ((TCHAR **) argv, d);
+ else if (d->__first_nonopt == d->__last_nonopt)
+ d->__first_nonopt = d->optind;
+ d->__last_nonopt = argc;
+
+ d->optind = argc;
+ }
+
+ /* If we have done all the ARGV-elements, stop the scan
+ and back over any non-options that we skipped and permuted. */
+
+ if (d->optind == argc)
+ {
+ /* Set the next-arg-index to point at the non-options
+ that we previously skipped, so the caller will digest them. */
+ if (d->__first_nonopt != d->__last_nonopt)
+ d->optind = d->__first_nonopt;
+ return -1;
+ }
+
+ /* If we have come to a non-option and did not permute it,
+ either stop the scan or describe it to the caller and pass it by. */
+
+ if (NONOPTION_P)
+ {
+ if (d->__ordering == REQUIRE_ORDER)
+ return -1;
+ d->optarg = argv[d->optind++];
+ return 1;
+ }
+
+ /* We have found another option-ARGV-element.
+ Skip the initial punctuation. */
+
+ d->__nextchar = (argv[d->optind] + 1
+ + (longopts != NULL && argv[d->optind][1] == _T('-')));
+ }
+
+ /* Decode the current option-ARGV-element. */
+
+ /* Check whether the ARGV-element is a long option.
+
+ If long_only and the ARGV-element has the form "-f", where f is
+ a valid short option, don't consider it an abbreviated form of
+ a long option that starts with f. Otherwise there would be no
+ way to give the -f short option.
+
+ On the other hand, if there's a long option "fubar" and
+ the ARGV-element is "-fu", do consider that an abbreviation of
+ the long option, just like "--fu", and not "-f" with arg "u".
+
+ This distinction seems to be the most useful approach. */
+
+ if (longopts != NULL
+ && (argv[d->optind][1] == _T('-')
+ || (long_only && (argv[d->optind][2]
+ || !_tcschr (optstring, argv[d->optind][1])))))
+ {
+ TCHAR *nameend;
+ unsigned int namelen;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ struct option_list
+ {
+ const struct option *p;
+ struct option_list *next;
+ } *ambig_list = NULL;
+ int exact = 0;
+ int indfound = -1;
+ int option_index;
+
+ for (nameend = d->__nextchar; *nameend && *nameend != _T('='); nameend++)
+ /* Do nothing. */ ;
+ namelen = (unsigned int)(nameend - d->__nextchar);
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!_tcsnccmp (p->name, d->__nextchar, namelen))
+ {
+ if (namelen == (unsigned int) lstrlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else if (long_only
+ || pfound->has_arg != p->has_arg
+ || pfound->flag != p->flag
+ || pfound->val != p->val)
+ {
+ /* Second or later nonexact match found. */
+ struct option_list *newp = _alloca (sizeof (*newp));
+ newp->p = p;
+ newp->next = ambig_list;
+ ambig_list = newp;
+ }
+ }
+
+ if (ambig_list != NULL && !exact)
+ {
+ if (print_errors)
+ {
+ struct option_list first;
+ first.p = pfound;
+ first.next = ambig_list;
+ ambig_list = &first;
+
+#if defined _LIBC
+ TCHAR *buf = NULL;
+ size_t buflen = 0;
+
+ FILE *fp = open_memstream (&buf, &buflen);
+ if (fp != NULL)
+ {
+ _ftprintf (fp,
+ _T("%s: option '%s' is ambiguous; possibilities:"),
+ argv[0], argv[d->optind]);
+
+ do
+ {
+ _ftprintf (fp, " '--%s'", ambig_list->p->name);
+ ambig_list = ambig_list->next;
+ }
+ while (ambig_list != NULL);
+
+ fputc_unlocked ('\n', fp);
+
+ if (__builtin_expect (fclose (fp) != EOF, 1))
+ {
+ _IO_flockfile (stderr);
+
+ int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+ ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
+
+ __fxprintf (NULL, "%s", buf);
+
+ ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+ _IO_funlockfile (stderr);
+
+ free (buf);
+ }
+ }
+#else
+ _ftprintf (stderr,
+ _T("%s: option '%s' is ambiguous; possibilities:"),
+ argv[0], argv[d->optind]);
+ do
+ {
+ _ftprintf (stderr, _T(" '--%s'"), ambig_list->p->name);
+ ambig_list = ambig_list->next;
+ }
+ while (ambig_list != NULL);
+
+ fputc(_T('\n'), stderr);
+#endif
+ }
+ d->__nextchar += lstrlen (d->__nextchar);
+ d->optind++;
+ d->optopt = 0;
+ return _T('?');
+ }
+
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ d->optind++;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ d->optarg = nameend + 1;
+ else
+ {
+ if (print_errors)
+ {
+#if defined _LIBC
+ TCHAR *buf;
+ int n;
+#endif
+
+ if (argv[d->optind - 1][1] == _T('-'))
+ {
+ /* --option */
+#if defined _LIBC
+ n = __asprintf (&buf, _T("\
+%s: option '--%s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+#else
+ _ftprintf (stderr, _T("\
+%s: option '--%s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+#endif
+ }
+ else
+ {
+ /* +option or -option */
+#if defined _LIBC
+ n = __asprintf (&buf, _T("\
+%s: option '%c%s' doesn't allow an argument\n"),
+ argv[0], argv[d->optind - 1][0],
+ pfound->name);
+#else
+ _ftprintf (stderr, _T("\
+%s: option '%c%s' doesn't allow an argument\n"),
+ argv[0], argv[d->optind - 1][0],
+ pfound->name);
+#endif
+ }
+
+#if defined _LIBC
+ if (n >= 0)
+ {
+ _IO_flockfile (stderr);
+
+ int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+ ((_IO_FILE *) stderr)->_flags2
+ |= _IO_FLAGS2_NOTCANCEL;
+
+ __fxprintf (NULL, "%s", buf);
+
+ ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+ _IO_funlockfile (stderr);
+
+ free (buf);
+ }
+#endif
+ }
+
+ d->__nextchar += lstrlen (d->__nextchar);
+
+ d->optopt = pfound->val;
+ return _T('?');
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (d->optind < argc)
+ d->optarg = argv[d->optind++];
+ else
+ {
+ if (print_errors)
+ {
+#if defined _LIBC
+ TCHAR *buf;
+
+ if (__asprintf (&buf, _T("\
+%s: option '--%s' requires an argument\n"),
+ argv[0], pfound->name) >= 0)
+ {
+ _IO_flockfile (stderr);
+
+ int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+ ((_IO_FILE *) stderr)->_flags2
+ |= _IO_FLAGS2_NOTCANCEL;
+
+ __fxprintf (NULL, "%s", buf);
+
+ ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+ _IO_funlockfile (stderr);
+
+ free (buf);
+ }
+#else
+ _ftprintf (stderr,
+ _T("%s: option '--%s' requires an argument\n"),
+ argv[0], pfound->name);
+#endif
+ }
+ d->__nextchar += lstrlen (d->__nextchar);
+ d->optopt = pfound->val;
+ return optstring[0] == _T(':') ? _T(':') : _T('?');
+ }
+ }
+ d->__nextchar += lstrlen (d->__nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+
+ /* Can't find it as a long option. If this is not getopt_long_only,
+ or the option starts with '--' or is not a valid short
+ option, then it's an error.
+ Otherwise interpret it as a short option. */
+ if (!long_only || argv[d->optind][1] == _T('-')
+ || _tcschr (optstring, *d->__nextchar) == NULL)
+ {
+ if (print_errors)
+ {
+#if defined _LIBC
+ TCHAR *buf;
+ int n;
+#endif
+
+ if (argv[d->optind][1] == _T('-'))
+ {
+ /* --option */
+#if defined _LIBC
+ n = __asprintf (&buf, _T("%s: unrecognized option '--%s'\n"),
+ argv[0], d->__nextchar);
+#else
+ _ftprintf (stderr, _T("%s: unrecognized option '--%s'\n"),
+ argv[0], d->__nextchar);
+#endif
+ }
+ else
+ {
+ /* +option or -option */
+#if defined _LIBC
+ n = __asprintf (&buf, _T("%s: unrecognized option '%c%s'\n"),
+ argv[0], argv[d->optind][0], d->__nextchar);
+#else
+ _ftprintf (stderr, _T("%s: unrecognized option '%c%s'\n"),
+ argv[0], argv[d->optind][0], d->__nextchar);
+#endif
+ }
+
+#if defined _LIBC
+ if (n >= 0)
+ {
+ _IO_flockfile (stderr);
+
+ int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+ ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
+
+ __fxprintf (NULL, "%s", buf);
+
+ ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+ _IO_funlockfile (stderr);
+
+ free (buf);
+ }
+#endif
+ }
+ d->__nextchar = (TCHAR *) _T("");
+ d->optind++;
+ d->optopt = 0;
+ return _T('?');
+ }
+ }
+
+ /* Look at and handle the next short option-character. */
+
+ {
+ TCHAR c = *d->__nextchar++;
+ TCHAR *temp = _tcschr (optstring, c);
+
+ /* Increment `optind' when we start to process its last character. */
+ if (*d->__nextchar == _T('\0'))
+ ++d->optind;
+
+ if (temp == NULL || c == _T(':') || c == _T(';'))
+ {
+ if (print_errors)
+ {
+#if defined _LIBC
+ TCHAR *buf;
+ int n;
+#endif
+
+#if defined _LIBC
+ n = __asprintf (&buf, _T("%s: invalid option -- '%c'\n"),
+ argv[0], c);
+#else
+ _ftprintf (stderr, _T("%s: invalid option -- '%c'\n"), argv[0], c);
+#endif
+
+#if defined _LIBC
+ if (n >= 0)
+ {
+ _IO_flockfile (stderr);
+
+ int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+ ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
+
+ __fxprintf (NULL, "%s", buf);
+
+ ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+ _IO_funlockfile (stderr);
+
+ free (buf);
+ }
+#endif
+ }
+ d->optopt = c;
+ return _T('?');
+ }
+ /* Convenience. Treat POSIX -W foo same as long option --foo */
+ if (temp[0] == _T('W') && temp[1] == _T(';'))
+ {
+ if (longopts == NULL)
+ goto no_longs;
+
+ TCHAR *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = 0;
+ int option_index;
+
+ /* This is an option that requires an argument. */
+ if (*d->__nextchar != _T('\0'))
+ {
+ d->optarg = d->__nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ d->optind++;
+ }
+ else if (d->optind == argc)
+ {
+ if (print_errors)
+ {
+#if defined _LIBC
+ TCHAR *buf;
+
+ if (__asprintf (&buf,
+ _T("%s: option requires an argument -- '%c'\n"),
+ argv[0], c) >= 0)
+ {
+ _IO_flockfile (stderr);
+
+ int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+ ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
+
+ __fxprintf (NULL, "%s", buf);
+
+ ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+ _IO_funlockfile (stderr);
+
+ free (buf);
+ }
+#else
+ _ftprintf (stderr,
+ _T("%s: option requires an argument -- '%c'\n"),
+ argv[0], c);
+#endif
+ }
+ d->optopt = c;
+ if (optstring[0] == _T(':'))
+ c = _T(':');
+ else
+ c = _T('?');
+ return c;
+ }
+ else
+ /* We already incremented `d->optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ d->optarg = argv[d->optind++];
+
+ /* optarg is now the argument, see if it's in the
+ table of longopts. */
+
+ for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != _T('=');
+ nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!_tcsnccmp (p->name, d->__nextchar, nameend - d->__nextchar))
+ {
+ if ((unsigned int) (nameend - d->__nextchar) == lstrlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else if (long_only
+ || pfound->has_arg != p->has_arg
+ || pfound->flag != p->flag
+ || pfound->val != p->val)
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+ if (ambig && !exact)
+ {
+ if (print_errors)
+ {
+#if defined _LIBC
+ TCHAR *buf;
+
+ if (__asprintf (&buf, _T("%s: option '-W %s' is ambiguous\n"),
+ argv[0], d->optarg) >= 0)
+ {
+ _IO_flockfile (stderr);
+
+ int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+ ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
+
+ __fxprintf (NULL, "%s", buf);
+
+ ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+ _IO_funlockfile (stderr);
+
+ free (buf);
+ }
+#else
+ _ftprintf (stderr, _T("%s: option '-W %s' is ambiguous\n"),
+ argv[0], d->optarg);
+#endif
+ }
+ d->__nextchar += lstrlen (d->__nextchar);
+ d->optind++;
+ return _T('?');
+ }
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ d->optarg = nameend + 1;
+ else
+ {
+ if (print_errors)
+ {
+#if defined _LIBC
+ TCHAR *buf;
+
+ if (__asprintf (&buf, _T("\
+%s: option '-W %s' doesn't allow an argument\n"),
+ argv[0], pfound->name) >= 0)
+ {
+ _IO_flockfile (stderr);
+
+ int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+ ((_IO_FILE *) stderr)->_flags2
+ |= _IO_FLAGS2_NOTCANCEL;
+
+ __fxprintf (NULL, "%s", buf);
+
+ ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+ _IO_funlockfile (stderr);
+
+ free (buf);
+ }
+#else
+ _ftprintf (stderr, _T("\
+%s: option '-W %s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+#endif
+ }
+
+ d->__nextchar += lstrlen (d->__nextchar);
+ return _T('?');
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (d->optind < argc)
+ d->optarg = argv[d->optind++];
+ else
+ {
+ if (print_errors)
+ {
+#if defined _LIBC
+ TCHAR *buf;
+
+ if (__asprintf (&buf, _T("\
+%s: option '-W %s' requires an argument\n"),
+ argv[0], pfound->name) >= 0)
+ {
+ _IO_flockfile (stderr);
+
+ int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+ ((_IO_FILE *) stderr)->_flags2
+ |= _IO_FLAGS2_NOTCANCEL;
+
+ __fxprintf (NULL, "%s", buf);
+
+ ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+ _IO_funlockfile (stderr);
+
+ free (buf);
+ }
+#else
+ _ftprintf (stderr, _T("\
+%s: option '-W %s' requires an argument\n"),
+ argv[0], pfound->name);
+#endif
+ }
+ d->__nextchar += lstrlen (d->__nextchar);
+ return optstring[0] == _T(':') ? _T(':') : _T('?');
+ }
+ }
+ else
+ d->optarg = NULL;
+ d->__nextchar += lstrlen (d->__nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+
+ no_longs:
+ d->__nextchar = NULL;
+ return _T('W'); /* Let the application handle it. */
+ }
+ if (temp[1] == _T(':'))
+ {
+ if (temp[2] == _T(':'))
+ {
+ /* This is an option that accepts an argument optionally. */
+ if (*d->__nextchar != _T('\0'))
+ {
+ d->optarg = d->__nextchar;
+ d->optind++;
+ }
+ else
+ d->optarg = NULL;
+ d->__nextchar = NULL;
+ }
+ else
+ {
+ /* This is an option that requires an argument. */
+ if (*d->__nextchar != _T('\0'))
+ {
+ d->optarg = d->__nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ d->optind++;
+ }
+ else if (d->optind == argc)
+ {
+ if (print_errors)
+ {
+#if defined _LIBC
+ TCHAR *buf;
+
+ if (__asprintf (&buf, _T("\
+%s: option requires an argument -- '%c'\n"),
+ argv[0], c) >= 0)
+ {
+ _IO_flockfile (stderr);
+
+ int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
+ ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
+
+ __fxprintf (NULL, "%s", buf);
+
+ ((_IO_FILE *) stderr)->_flags2 = old_flags2;
+ _IO_funlockfile (stderr);
+
+ free (buf);
+ }
+#else
+ _ftprintf (stderr,
+ _T("%s: option requires an argument -- '%c'\n"),
+ argv[0], c);
+#endif
+ }
+ d->optopt = c;
+ if (optstring[0] == _T(':'))
+ c = _T(':');
+ else
+ c = _T('?');
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ d->optarg = argv[d->optind++];
+ d->__nextchar = NULL;
+ }
+ }
+ return c;
+ }
+}
+
+int
+_getopt_internal (int argc, TCHAR *const *argv, const TCHAR *optstring,
+ const struct option *longopts, int *longind, int long_only,
+ int posixly_correct)
+{
+ int result;
+
+ getopt_data.optind = optind;
+ getopt_data.opterr = opterr;
+
+ result = _getopt_internal_r (argc, argv, optstring, longopts,
+ longind, long_only, &getopt_data,
+ posixly_correct);
+
+ optind = getopt_data.optind;
+ optarg = getopt_data.optarg;
+ optopt = getopt_data.optopt;
+
+ return result;
+}
+
+int
+getopt (int argc, TCHAR *const *argv, const TCHAR *optstring)
+{
+ return _getopt_internal (argc, argv, optstring,
+ (const struct option *) 0,
+ (int *) 0,
+ 0, 0);
+}
+
+
+
+
+
+int
+getopt_long (int argc, TCHAR *const *argv, const TCHAR *options,
+ const struct option *long_options, int *opt_index)
+{
+ return _getopt_internal (argc, (TCHAR **) argv, options, long_options,
+ opt_index, 0, 0);
+}
+
+
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+ If an option that starts with '-' (not '--') doesn't match a long option,
+ but does match a short option, it is parsed as a short option
+ instead. */
+
+int
+getopt_long_only (int argc, TCHAR *const *argv,
+ const TCHAR *options,
+ const struct option *long_options, int *opt_index)
+{
+ return _getopt_internal (argc, (TCHAR **) argv, options, long_options,
+ opt_index, 1, 0);
+}
+
+int
+_getopt_long_r(int argc, TCHAR* const* argv, const TCHAR* options,
+ const struct option* long_options, int* opt_index,
+ struct _getopt_data* d)
+{
+ return _getopt_internal_r(argc, argv, options, long_options, opt_index,
+ 0, d, 0);
+}
+
+int
+_getopt_long_only_r (int argc, TCHAR* const* argv, const TCHAR *options,
+ const struct option *long_options, int *opt_index,
+ struct _getopt_data *d)
+{
+ return _getopt_internal_r (argc, argv, options, long_options, opt_index,
+ 1, d, 0);
+}
+
+
+
+
+
+
+
+
+
+
+#ifdef _LIBC
+int
+__posix_getopt (int argc, TCHAR *const *argv, const TCHAR *optstring)
+{
+ return _getopt_internal (argc, argv, optstring,
+ (const struct option *) 0,
+ (int *) 0,
+ 0, 1);
+}
+#endif
+
+#endif /* Not ELIDE_CODE. */
+
+
diff --git a/hactool-vs2019/getopt.h b/hactool-vs2019/getopt.h
new file mode 100644
index 0000000..55c7828
--- /dev/null
+++ b/hactool-vs2019/getopt.h
@@ -0,0 +1,168 @@
+/* Declarations for getopt.
+ Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ . */
+
+#pragma once
+//#define _CRT_SECURE_NO_WARNINGS
+#include
+#ifndef __need_getopt
+# define _GETOPT_H 1
+#endif
+
+/* If __GNU_LIBRARY__ is not already defined, either we are being used
+ standalone, or this is the first header included in the source file.
+ If we are being used with glibc, we need to include , but
+ that does not exist if we are standalone. So: if __GNU_LIBRARY__ is
+ not defined, include , which will pull in for us
+ if it's from glibc. (Why ctype.h? It's guaranteed to exist and it
+ doesn't flood the namespace with stuff the way some other headers do.) */
+#if !defined __GNU_LIBRARY__
+# include
+#endif
+
+#ifndef __THROW
+# ifndef __GNUC_PREREQ
+# define __GNUC_PREREQ(maj, min) (0)
+# endif
+# if defined __cplusplus && __GNUC_PREREQ (2,8)
+# define __THROW throw ()
+# else
+# define __THROW
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+extern TCHAR *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+ for unrecognized options. */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized. */
+
+extern int optopt;
+
+
+/* Describe the long-named options requested by the application.
+ The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+ of `struct option' terminated by an element containing a name which is
+ zero.
+
+ The field `has_arg' is:
+ no_argument (or 0) if the option does not take an argument,
+ required_argument (or 1) if the option requires an argument,
+ optional_argument (or 2) if the option takes an optional argument.
+
+ If the field `flag' is not NULL, it points to a variable that is set
+ to the value given in the field `val' when the option is found, but
+ left unchanged if the option is not found.
+
+ To have a long-named option do something other than set an `int' to
+ a compiled-in constant, such as set a value from `optarg', set the
+ option's `flag' field to zero and its `val' field to a nonzero
+ value (the equivalent single-letter option character, if there is
+ one). For long options that have a zero `flag' field, `getopt'
+ returns the contents of the `val' field. */
+
+struct option
+{
+ const TCHAR *name;
+ /* has_arg can't be an enum because some compilers complain about
+ type mismatches in all the code that assumes it is an int. */
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'. */
+
+# define no_argument 0
+# define required_argument 1
+# define optional_argument 2
+
+
+
+/* Get definitions and prototypes for functions to process the
+ arguments in ARGV (ARGC of them, minus the program name) for
+ options given in OPTS.
+
+ Return the option character from OPTS just read. Return -1 when
+ there are no more options. For unrecognized options, or options
+ missing arguments, `optopt' is set to the option letter, and '?' is
+ returned.
+
+ The OPTS string is a list of characters which are recognized option
+ letters, optionally followed by colons, specifying that that letter
+ takes an argument, to be placed in `optarg'.
+
+ If a letter in OPTS is followed by two colons, its argument is
+ optional. This behavior is specific to the GNU `getopt'.
+
+ The argument `--' causes premature termination of argument
+ scanning, explicitly telling `getopt' that there are no more
+ options.
+
+ If OPTS begins with `--', then non-option arguments are treated as
+ arguments to the option '\0'. This behavior is specific to the GNU
+ `getopt'. */
+
+extern int getopt (int ___argc, TCHAR *const *___argv, const TCHAR *__shortopts)
+ __THROW;
+
+extern int getopt_long (int ___argc, TCHAR *const *___argv,
+ const TCHAR *__shortopts,
+ const struct option *__longopts, int *__longind)
+ __THROW;
+extern int getopt_long_only (int ___argc, TCHAR *const *___argv,
+ const TCHAR *__shortopts,
+ const struct option *__longopts, int *__longind)
+ __THROW;
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Make sure we later can get all the definitions and declarations. */
+#undef __need_getopt
+
+
diff --git a/hactool-vs2019/getopt_int.h b/hactool-vs2019/getopt_int.h
new file mode 100644
index 0000000..11e866f
--- /dev/null
+++ b/hactool-vs2019/getopt_int.h
@@ -0,0 +1,131 @@
+// This came from: https://github.com/bugparty/getopt_vc
+
+/* Internal declarations for getopt.
+ Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ . */
+
+#ifndef _GETOPT_INT_H
+#define _GETOPT_INT_H 1
+
+extern int _getopt_internal (int ___argc, TCHAR *const *___argv,
+ const TCHAR *__shortopts,
+ const struct option *__longopts, int *__longind,
+ int __long_only, int posixly_correct);
+
+
+/* Reentrant versions which can handle parsing multiple argument
+ vectors at the same time. */
+
+/* Data type for reentrant functions. */
+struct _getopt_data
+{
+ /* These have exactly the same meaning as the corresponding global
+ variables, except that they are used for the reentrant
+ versions of getopt. */
+ int optind;
+ int opterr;
+ int optopt;
+ TCHAR *optarg;
+
+ /* Internal members. */
+
+ /* True if the internal members have been initialized. */
+ int __initialized;
+
+ /* The next char to be scanned in the option-element
+ in which the last option character we returned was found.
+ This allows us to pick up the scan where we left off.
+
+ If this is zero, or a null string, it means resume the scan
+ by advancing to the next ARGV-element. */
+ TCHAR *__nextchar;
+
+ /* Describe how to deal with options that follow non-option ARGV-elements.
+
+ If the caller did not specify anything,
+ the default is REQUIRE_ORDER if the environment variable
+ POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+ REQUIRE_ORDER means don't recognize them as options;
+ stop option processing when the first non-option is seen.
+ This is what Unix does.
+ This mode of operation is selected by either setting the environment
+ variable POSIXLY_CORRECT, or using `+' as the first character
+ of the list of option characters.
+
+ PERMUTE is the default. We permute the contents of ARGV as we
+ scan, so that eventually all the non-options are at the end.
+ This allows options to be given in any order, even with programs
+ that were not written to expect this.
+
+ RETURN_IN_ORDER is an option available to programs that were
+ written to expect options and other ARGV-elements in any order
+ and that care about the ordering of the two. We describe each
+ non-option ARGV-element as if it were the argument of an option
+ with character code 1. Using `-' as the first character of the
+ list of option characters selects this mode of operation.
+
+ The special argument `--' forces an end of option-scanning regardless
+ of the value of `ordering'. In the case of RETURN_IN_ORDER, only
+ `--' can cause `getopt' to return -1 with `optind' != ARGC. */
+
+ enum
+ {
+ REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+ } __ordering;
+
+ /* If the POSIXLY_CORRECT environment variable is set. */
+ int __posixly_correct;
+
+
+ /* Handle permutation of arguments. */
+
+ /* Describe the part of ARGV that contains non-options that have
+ been skipped. `first_nonopt' is the index in ARGV of the first
+ of them; `last_nonopt' is the index after the last of them. */
+
+ int __first_nonopt;
+ int __last_nonopt;
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+ int __nonoption_flags_max_len;
+ int __nonoption_flags_len;
+# endif
+};
+
+/* The initializer is necessary to set OPTIND and OPTERR to their
+ default values and to clear the initialization flag. */
+#define _GETOPT_DATA_INITIALIZER { 1, 1 }
+
+extern int _getopt_internal_r (int ___argc, TCHAR *const *___argv,
+ const TCHAR *__shortopts,
+ const struct option *__longopts, int *__longind,
+ int __long_only, struct _getopt_data *__data,
+ int posixly_correct);
+
+extern int _getopt_long_r (int ___argc, TCHAR *const *___argv,
+ const TCHAR *__shortopts,
+ const struct option *__longopts, int *__longind,
+ struct _getopt_data *__data);
+
+extern int _getopt_long_only_r (int ___argc, TCHAR *const *___argv,
+ const TCHAR *__shortopts,
+ const struct option *__longopts,
+ int *__longind,
+ struct _getopt_data *__data);
+
+#endif /* getopt_int.h */
diff --git a/hactool-vs2019/hactool-vs2019.sln b/hactool-vs2019/hactool-vs2019.sln
new file mode 100644
index 0000000..ada2e14
--- /dev/null
+++ b/hactool-vs2019/hactool-vs2019.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30011.22
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hactool-vs2019", "hactool-vs2019.vcxproj", "{387FDC50-8D38-4BEA-9B75-C76950C8AB6C}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {387FDC50-8D38-4BEA-9B75-C76950C8AB6C}.Debug|x64.ActiveCfg = Debug|x64
+ {387FDC50-8D38-4BEA-9B75-C76950C8AB6C}.Debug|x64.Build.0 = Debug|x64
+ {387FDC50-8D38-4BEA-9B75-C76950C8AB6C}.Debug|x86.ActiveCfg = Debug|Win32
+ {387FDC50-8D38-4BEA-9B75-C76950C8AB6C}.Debug|x86.Build.0 = Debug|Win32
+ {387FDC50-8D38-4BEA-9B75-C76950C8AB6C}.Release|x64.ActiveCfg = Release|x64
+ {387FDC50-8D38-4BEA-9B75-C76950C8AB6C}.Release|x64.Build.0 = Release|x64
+ {387FDC50-8D38-4BEA-9B75-C76950C8AB6C}.Release|x86.ActiveCfg = Release|Win32
+ {387FDC50-8D38-4BEA-9B75-C76950C8AB6C}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {598145D1-DBA7-418F-8FFA-D746AEA4E0E3}
+ EndGlobalSection
+EndGlobal
diff --git a/hactool-vs2019/hactool-vs2019.vcxproj b/hactool-vs2019/hactool-vs2019.vcxproj
new file mode 100644
index 0000000..dded912
--- /dev/null
+++ b/hactool-vs2019/hactool-vs2019.vcxproj
@@ -0,0 +1,309 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 16.0
+ {387FDC50-8D38-4BEA-9B75-C76950C8AB6C}
+ Win32Proj
+ hactoolvs2019
+ 10.0
+
+
+
+ Application
+ true
+ v142
+ MultiByte
+
+
+ Application
+ false
+ v142
+ true
+ MultiByte
+
+
+ Application
+ true
+ v142
+ MultiByte
+
+
+ Application
+ false
+ v142
+ true
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ hactool
+ $(SolutionDir)out\$(Platform)\$(Configuration)\
+ $(SolutionDir)$(Platform)\$(Configuration)\
+
+
+ true
+ hactool
+ $(SolutionDir)out\$(Platform)\$(Configuration)\
+ $(SolutionDir)$(Platform)\$(Configuration)\
+
+
+ false
+ hactool
+ $(SolutionDir)out\$(Platform)\$(Configuration)\
+ $(SolutionDir)$(Platform)\$(Configuration)\
+
+
+ false
+ hactool
+ $(SolutionDir)out\$(Platform)\$(Configuration)\
+ $(SolutionDir)$(Platform)\$(Configuration)\
+
+
+
+ NotUsing
+ Level3
+ true
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS
+ true
+ MultiThreadedDebug
+ ..\mbedtls\include;..;.
+
+
+ Console
+ true
+
+
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+ NotUsing
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS
+ true
+ MultiThreadedDebug
+ ..\mbedtls\include;..;.
+
+
+ Console
+ true
+
+
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+ NotUsing
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS
+ true
+ MultiThreaded
+ ..\mbedtls\include;..;.
+
+
+ Console
+ true
+ true
+ true
+
+
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+ NotUsing
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS
+ true
+ MultiThreaded
+ ..\mbedtls\include;..;.
+
+
+ Console
+ true
+ true
+ true
+
+
+ kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hactool-vs2019/hactool-vs2019.vcxproj.filters b/hactool-vs2019/hactool-vs2019.vcxproj.filters
new file mode 100644
index 0000000..eed4053
--- /dev/null
+++ b/hactool-vs2019/hactool-vs2019.vcxproj.filters
@@ -0,0 +1,395 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {dc7c8410-6307-4c8a-8882-ecc443936c2a}
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+ mbedtls
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/hfs0.c b/hfs0.c
index f9548b2..e2fb28d 100644
--- a/hfs0.c
+++ b/hfs0.c
@@ -17,14 +17,14 @@ void hfs0_process(hfs0_ctx_t *ctx) {
}
uint64_t header_size = hfs0_get_header_size(&raw_header);
- ctx->header = malloc(header_size);
+ ctx->header = malloc((size_t)header_size);
if (ctx->header == NULL) {
fprintf(stderr, "Failed to allocate HFS0 header!\n");
exit(EXIT_FAILURE);
}
fseeko64(ctx->file, ctx->offset, SEEK_SET);
- if (fread(ctx->header, 1, header_size, ctx->file) != header_size) {
+ if (fread(ctx->header, 1, (size_t)header_size, ctx->file) != header_size) {
fprintf(stderr, "Failed to read HFS0 header!\n");
exit(EXIT_FAILURE);
}
diff --git a/kip.c b/kip.c
index 01ccd35..d7796e0 100644
--- a/kip.c
+++ b/kip.c
@@ -184,7 +184,7 @@ static void *kip1_uncompress(kip1_ctx_t *ctx, uint64_t *size) {
new_header.flags &= 0xF8;
*size = kip1_get_size_from_header(&new_header);
- unsigned char *new_kip = calloc(1, *size);
+ unsigned char *new_kip = calloc(1, (size_t)*size);
if (new_kip == NULL) {
fprintf(stderr, "Failed to allocate uncompressed KIP1!\n");
exit(EXIT_FAILURE);
@@ -219,14 +219,14 @@ void kip1_process(kip1_ctx_t *ctx) {
}
uint64_t size = kip1_get_size_from_header(&raw_header);
- ctx->header = malloc(size);
+ ctx->header = malloc((size_t)size);
if (ctx->header == NULL) {
fprintf(stderr, "Failed to allocate KIP1!\n");
exit(EXIT_FAILURE);
}
fseeko64(ctx->file, 0, SEEK_SET);
- if (fread(ctx->header, 1, size, ctx->file) != size) {
+ if (fread(ctx->header, 1, (size_t)size, ctx->file) != size) {
fprintf(stderr, "Failed to read KIP1!\n");
exit(EXIT_FAILURE);
}
@@ -293,7 +293,7 @@ void kip1_save(kip1_ctx_t *ctx) {
}
uint64_t sz = 0;
void *uncmp = kip1_uncompress(ctx, &sz);
- if (fwrite(uncmp, 1, sz, f_uncmp) != sz) {
+ if (fwrite(uncmp, 1, (size_t)sz, f_uncmp) != sz) {
fprintf(stderr, "Failed to write uncompressed kip!\n");
exit(EXIT_FAILURE);
}
diff --git a/main.c b/main.c
index 07f53cb..6e04d8c 100644
--- a/main.c
+++ b/main.c
@@ -3,7 +3,6 @@
#include
#include
#include
-#include
#include "types.h"
#include "utils.h"
#include "settings.h"
@@ -607,12 +606,12 @@ int main(int argc, char **argv) {
npdm_size = raw_hdr.acid_offset + raw_hdr.acid_size;
}
fseeko64(tool_ctx.file, 0, SEEK_SET);
- npdm_t *npdm = malloc(npdm_size);
+ npdm_t *npdm = malloc((size_t)npdm_size);
if (npdm == NULL) {
fprintf(stderr, "Failed to allocate NPDM!\n");
exit(EXIT_FAILURE);
}
- if (fread(npdm, 1, npdm_size, tool_ctx.file) != npdm_size) {
+ if (fread(npdm, 1, (size_t)npdm_size, tool_ctx.file) != npdm_size) {
fprintf(stderr, "Failed to read NPDM!\n");
exit(EXIT_FAILURE);
}
diff --git a/mbedtls/library/Makefile b/mbedtls/library/Makefile
index eb2f2f3..fe0865f 100644
--- a/mbedtls/library/Makefile
+++ b/mbedtls/library/Makefile
@@ -45,7 +45,7 @@ ifdef WINDOWS_BUILD
DLEXT=dll
endif
-OBJS_CRYPTO= aes.o aesni.o arc4.o \
+OBJS_CRYPTO= aes_mbedtls.o aesni.o arc4.o \
asn1parse.o asn1write.o base64.o \
bignum.o blowfish.o camellia.o \
ccm.o cipher.o cipher_wrap.o \
@@ -61,7 +61,7 @@ OBJS_CRYPTO= aes.o aesni.o arc4.o \
padlock.o pem.o pk.o \
pk_wrap.o pkcs12.o pkcs5.o \
pkparse.o pkwrite.o platform.o \
- ripemd160.o rsa.o sha1.o \
+ ripemd160.o rsa_mbedtls.o sha1.o \
sha256.o sha512.o threading.o \
timing.o version.o \
version_features.o xtea.o
diff --git a/mbedtls/library/aes.c b/mbedtls/library/aes_mbedtls.c
similarity index 100%
rename from mbedtls/library/aes.c
rename to mbedtls/library/aes_mbedtls.c
diff --git a/mbedtls/library/rsa.c b/mbedtls/library/rsa_mbedtls.c
similarity index 100%
rename from mbedtls/library/rsa.c
rename to mbedtls/library/rsa_mbedtls.c
diff --git a/nax0.c b/nax0.c
index 3693c96..65d2a6c 100644
--- a/nax0.c
+++ b/nax0.c
@@ -14,7 +14,7 @@ static size_t nax0_read(nax0_ctx_t *ctx, uint64_t offset, void *dst, size_t size
fseeko64(which, offset_in_file, SEEK_SET);
uint64_t left_in_file = 0xFFFF0000ULL - offset_in_file;
if (size > left_in_file) {
- return fread(dst, 1, left_in_file, which) + nax0_read(ctx, offset + left_in_file, (unsigned char *)dst + left_in_file, size - left_in_file);
+ return fread(dst, 1, (size_t)left_in_file, which) + nax0_read(ctx, offset + left_in_file, (unsigned char *)dst + left_in_file, (size_t)(size - left_in_file));
} else {
return fread(dst, 1, size, which);
}
@@ -129,18 +129,18 @@ void nax0_save(nax0_ctx_t *ctx) {
}
uint64_t read_size = 0x400000; /* 4 MB buffer. */
- memset(buf, 0xCC, read_size); /* Debug in case I fuck this up somehow... */
+ memset(buf, 0xCC, (size_t)read_size); /* Debug in case I fuck this up somehow... */
while (ofs < end_ofs) {
if (ofs + read_size >= end_ofs) read_size = end_ofs - ofs;
- if (nax0_read(ctx, ofs, buf, read_size) != read_size) {
+ if (nax0_read(ctx, ofs, buf, (size_t)read_size) != read_size) {
fprintf(stderr, "Failed to read file!\n");
exit(EXIT_FAILURE);
}
uint64_t dec_size = (read_size + 0x3FFF) & ~0x3FFF;
- aes_xts_decrypt(ctx->aes_ctx, buf, buf, dec_size, (ofs - 0x4000) >> 14, 0x4000);
+ aes_xts_decrypt(ctx->aes_ctx, buf, buf, (size_t)dec_size, (size_t)((ofs - 0x4000) >> 14), 0x4000);
- if (fwrite(buf, 1, read_size, f_dec) != read_size) {
+ if (fwrite(buf, 1, (size_t)read_size, f_dec) != read_size) {
fprintf(stderr, "Failed to write file!\n");
exit(EXIT_FAILURE);
}
diff --git a/nca.c b/nca.c
index 8a84366..e4bc7ec 100644
--- a/nca.c
+++ b/nca.c
@@ -43,13 +43,13 @@ void nca_section_fseek(nca_section_ctx_t *ctx, uint64_t offset) {
} else if (ctx->crypt_type == CRYPT_XTS) {
fseeko64(ctx->file, (ctx->offset + offset) & ~ctx->sector_mask, SEEK_SET);
ctx->cur_seek = (ctx->offset + offset) & ~ctx->sector_mask;
- ctx->sector_num = offset / ctx->sector_size;
- ctx->sector_ofs = offset & ctx->sector_mask;
+ ctx->sector_num = (size_t)(offset / ctx->sector_size);
+ ctx->sector_ofs = (uint32_t)(offset & ctx->sector_mask);
} else if (ctx->crypt_type == CRYPT_NCA0) {
fseeko64(ctx->file, (ctx->offset + offset) & ~ctx->sector_mask, SEEK_SET);
ctx->cur_seek = ((ctx->offset + offset - 0x400ULL) & ~ctx->sector_mask) + 0x400ULL;
- ctx->sector_num = (ctx->offset + offset - 0x400ULL) / ctx->sector_size;
- ctx->sector_ofs = (ctx->offset + offset - 0x400ULL) & ctx->sector_mask;
+ ctx->sector_num = (size_t)((ctx->offset + offset - 0x400ULL) / ctx->sector_size);
+ ctx->sector_ofs = (uint32_t)((ctx->offset + offset - 0x400ULL) & ctx->sector_mask);
} else if (ctx->type == BKTR && ctx->bktr_ctx.subsection_block != NULL) {
/* No better way to do this than to make all BKTR seeking virtual. */
ctx->bktr_ctx.virtual_seek = offset;
@@ -118,10 +118,10 @@ static size_t nca_bktr_section_physical_fread(nca_section_ctx_t *ctx, void *buff
} else {
/* Sad path. */
uint64_t within_subsection = next_subsec->offset - ctx->bktr_ctx.bktr_seek;
- if ((read = nca_section_fread(ctx, buffer, within_subsection)) != within_subsection) {
+ if ((read = nca_section_fread(ctx, buffer, (size_t)within_subsection)) != within_subsection) {
return 0;
}
- read += nca_section_fread(ctx, (char *)buffer + within_subsection, count - within_subsection);
+ read += nca_section_fread(ctx, (char *)buffer + within_subsection, (size_t)(count - within_subsection));
if (read != count) {
return 0;
}
@@ -141,16 +141,16 @@ size_t nca_section_fread(nca_section_ctx_t *ctx, void *buffer, size_t count) {
}
if (ctx->crypt_type == CRYPT_XTS || ctx->crypt_type == CRYPT_NCA0) { /* AES-XTS requires special handling... */
- unsigned char *sector_buf = malloc(ctx->sector_size);
- if ((read = fread(sector_buf, size, ctx->sector_size, ctx->file)) != ctx->sector_size) {
+ unsigned char *sector_buf = malloc((size_t)ctx->sector_size);
+ if ((read = fread(sector_buf, size, (size_t)ctx->sector_size, ctx->file)) != ctx->sector_size) {
free(sector_buf);
return 0;
}
- aes_xts_decrypt(ctx->aes, sector_buf, sector_buf, ctx->sector_size, ctx->sector_num, ctx->sector_size);
+ aes_xts_decrypt(ctx->aes, sector_buf, sector_buf, (size_t)ctx->sector_size, ctx->sector_num, (size_t)ctx->sector_size);
if (count > ctx->sector_size - ctx->sector_ofs) { /* We're leaving the sector... */
- memcpy(buffer, sector_buf + ctx->sector_ofs, ctx->sector_size - ctx->sector_ofs);
- size_t remaining = count - (ctx->sector_size - ctx->sector_ofs);
- size_t ofs = (ctx->sector_size - ctx->sector_ofs);
+ memcpy(buffer, sector_buf + ctx->sector_ofs, (size_t)(ctx->sector_size - ctx->sector_ofs));
+ size_t remaining = (size_t)(count - (ctx->sector_size - ctx->sector_ofs));
+ size_t ofs = (size_t)(ctx->sector_size - ctx->sector_ofs);
ctx->sector_num++;
ctx->sector_ofs = 0;
if (remaining & ~ctx->sector_mask) { /* Read intermediate sectors. */
@@ -160,26 +160,26 @@ size_t nca_section_fread(nca_section_ctx_t *ctx, void *buffer, size_t count) {
return ofs;
}
- aes_xts_decrypt(ctx->aes, (char *)buffer + ofs, (char *)buffer + ofs, remaining & ~ctx->sector_mask, ctx->sector_num, ctx->sector_size);
- ctx->sector_num += remaining / ctx->sector_size;
+ aes_xts_decrypt(ctx->aes, (char *)buffer + ofs, (char *)buffer + ofs, remaining & ~ctx->sector_mask, ctx->sector_num, (size_t)ctx->sector_size);
+ ctx->sector_num += (size_t)(remaining / ctx->sector_size);
ofs += remaining & ~ctx->sector_mask;
remaining &= ctx->sector_mask;
- read += addl;
+ read += (size_t)addl;
}
if (remaining) { /* Read last sector. */
- if ((read = fread(sector_buf, size, ctx->sector_size, ctx->file)) != ctx->sector_size) {
+ if ((read = fread(sector_buf, size, (size_t)ctx->sector_size, ctx->file)) != ctx->sector_size) {
free(sector_buf);
return ofs;
}
- aes_xts_decrypt(ctx->aes, sector_buf, sector_buf, ctx->sector_size, ctx->sector_num, ctx->sector_size);
+ aes_xts_decrypt(ctx->aes, sector_buf, sector_buf, (size_t)ctx->sector_size, ctx->sector_num, (size_t)ctx->sector_size);
memcpy((char *)buffer + ofs, sector_buf, remaining);
- ctx->sector_ofs = remaining;
+ ctx->sector_ofs = (uint32_t)remaining;
read = count;
}
} else {
memcpy(buffer, sector_buf + ctx->sector_ofs, count);
- ctx->sector_num += (ctx->sector_ofs + count) / ctx->sector_size;
- ctx->sector_ofs += count;
+ ctx->sector_num += (size_t)((ctx->sector_ofs + count) / ctx->sector_size);
+ ctx->sector_ofs += (uint32_t)count;
ctx->sector_ofs &= ctx->sector_mask;
read = count;
}
@@ -253,11 +253,11 @@ size_t nca_section_fread(nca_section_ctx_t *ctx, void *buffer, size_t count) {
}
} else {
uint64_t within_relocation = next_reloc->virt_offset - ctx->bktr_ctx.virtual_seek;
- if ((read = nca_section_fread(ctx, buffer, within_relocation)) != within_relocation) {
+ if ((read = nca_section_fread(ctx, buffer, (size_t)within_relocation)) != within_relocation) {
return 0;
}
nca_section_fseek(ctx, virt_seek + within_relocation);
- read += nca_section_fread(ctx, (char *)buffer + within_relocation, count - within_relocation);
+ read += nca_section_fread(ctx, (char *)buffer + within_relocation, (size_t)(count - within_relocation));
if (read != count) {
return 0;
}
@@ -373,17 +373,17 @@ static void nca_save(nca_ctx_t *ctx) {
ctx->section_contexts[i].physical_reads = 1;
uint64_t read_size = 0x400000; /* 4 MB buffer. */
- memset(buf, 0xCC, read_size); /* Debug in case I fuck this up somehow... */
+ memset(buf, 0xCC, (size_t)read_size); /* Debug in case I fuck this up somehow... */
uint64_t ofs = 0;
uint64_t end_ofs = ofs + ctx->section_contexts[i].size;
nca_section_fseek(&ctx->section_contexts[i], ofs);
while (ofs < end_ofs) {
if (ofs + read_size >= end_ofs) read_size = end_ofs - ofs;
- if (nca_section_fread(&ctx->section_contexts[i], buf, read_size) != read_size) {
+ if (nca_section_fread(&ctx->section_contexts[i], buf, (size_t)read_size) != read_size) {
fprintf(stderr, "Failed to read file!\n");
exit(EXIT_FAILURE);
}
- if (fwrite(buf, 1, read_size, f_dec) != read_size) {
+ if (fwrite(buf, 1, (size_t)read_size, f_dec) != read_size) {
fprintf(stderr, "Failed to write file!\n");
exit(EXIT_FAILURE);
}
@@ -667,7 +667,7 @@ int nca_decrypt_header(nca_ctx_t *ctx) {
fprintf(stderr, "Failed to read NCA0 FS header at %" PRIx64"!\n", offset);
exit(EXIT_FAILURE);
}
- aes_xts_decrypt(aes_ctx, &dec_header.fs_headers[i], &dec_header.fs_headers[i], sizeof(dec_header.fs_headers[i]), (offset - 0x400ULL) >> 9ULL, 0x200);
+ aes_xts_decrypt(aes_ctx, &dec_header.fs_headers[i], &dec_header.fs_headers[i], sizeof(dec_header.fs_headers[i]), (size_t)((offset - 0x400ULL) >> 9ULL), 0x200);
}
}
free_aes_ctx(aes_ctx);
@@ -899,7 +899,7 @@ static validity_t nca_section_check_external_hash_table(nca_section_ctx_t *ctx,
}
unsigned char cur_hash[0x20];
uint64_t read_size = block_size;
- unsigned char *block = malloc(block_size);
+ unsigned char *block = malloc((size_t)block_size);
if (block == NULL) {
fprintf(stderr, "Failed to allocate hash block!\n");
exit(EXIT_FAILURE);
@@ -911,15 +911,15 @@ static validity_t nca_section_check_external_hash_table(nca_section_ctx_t *ctx,
nca_section_fseek(ctx, ofs + data_ofs);
if (ofs + read_size > data_len) {
/* Last block... */
- memset(block, 0, read_size);
+ memset(block, 0, (size_t)read_size);
read_size = data_len - ofs;
}
- if (nca_section_fread(ctx, block, read_size) != read_size) {
+ if (nca_section_fread(ctx, block, (size_t)read_size) != read_size) {
fprintf(stderr, "Failed to read section!\n");
exit(EXIT_FAILURE);
}
- sha256_hash_buffer(cur_hash, block, full_block ? block_size : read_size);
+ sha256_hash_buffer(cur_hash, block, (size_t)(full_block ? block_size : read_size));
if (memcmp(cur_hash, cur_hash_table_entry, 0x20) != 0) {
result = VALIDITY_INVALID;
break;
@@ -940,14 +940,14 @@ static validity_t nca_section_check_hash_table(nca_section_ctx_t *ctx, uint64_t
uint64_t hash_table_size = data_len / block_size;
if (data_len % block_size) hash_table_size++;
hash_table_size *= 0x20;
- unsigned char *hash_table = malloc(hash_table_size);
+ unsigned char *hash_table = malloc((size_t)hash_table_size);
if (hash_table == NULL) {
fprintf(stderr, "Failed to allocate hash table!\n");
exit(EXIT_FAILURE);
}
nca_section_fseek(ctx, hash_ofs);
- if (nca_section_fread(ctx, hash_table, hash_table_size) != hash_table_size) {
+ if (nca_section_fread(ctx, hash_table, (size_t)hash_table_size) != hash_table_size) {
fprintf(stderr, "Failed to read section!\n");
exit(EXIT_FAILURE);
}
@@ -1004,13 +1004,13 @@ void nca_process_pfs0_section(nca_section_ctx_t *ctx) {
}
uint64_t header_size = pfs0_get_header_size(&raw_header);
- ctx->pfs0_ctx.header = malloc(header_size);
+ ctx->pfs0_ctx.header = malloc((size_t)header_size);
if (ctx->pfs0_ctx.header == NULL) {
fprintf(stderr, "Failed to get PFS0 header size!\n");
exit(EXIT_FAILURE);
}
nca_section_fseek(ctx, sb->pfs0_offset);
- if (nca_section_fread(ctx, ctx->pfs0_ctx.header, header_size) != header_size) {
+ if (nca_section_fread(ctx, ctx->pfs0_ctx.header, (size_t)header_size) != header_size) {
fprintf(stderr, "Failed to read PFS0 header!\n");
exit(EXIT_FAILURE);
}
@@ -1024,13 +1024,13 @@ void nca_process_pfs0_section(nca_section_ctx_t *ctx) {
exit(EXIT_FAILURE);
}
- ctx->pfs0_ctx.npdm = malloc(cur_file->size);
+ ctx->pfs0_ctx.npdm = malloc((size_t)cur_file->size);
if (ctx->pfs0_ctx.npdm == NULL) {
fprintf(stderr, "Failed to allocate NPDM!\n");
exit(EXIT_FAILURE);
}
nca_section_fseek(ctx, sb->pfs0_offset + pfs0_get_header_size(ctx->pfs0_ctx.header) + cur_file->offset);
- if (nca_section_fread(ctx, ctx->pfs0_ctx.npdm, cur_file->size) != cur_file->size) {
+ if (nca_section_fread(ctx, ctx->pfs0_ctx.npdm, (size_t)cur_file->size) != cur_file->size) {
fprintf(stderr, "Failed to read NPDM!\n");
exit(EXIT_FAILURE);
}
@@ -1075,25 +1075,25 @@ void nca_process_ivfc_section(nca_section_ctx_t *ctx) {
if ((ctx->tool_ctx->action & (ACTION_EXTRACT | ACTION_LISTROMFS)) && ctx->romfs_ctx.header.header_size == ROMFS_HEADER_SIZE) {
/* Pre-load the file/data entry caches. */
- ctx->romfs_ctx.directories = calloc(1, ctx->romfs_ctx.header.dir_meta_table_size);
+ ctx->romfs_ctx.directories = calloc(1, (size_t)ctx->romfs_ctx.header.dir_meta_table_size);
if (ctx->romfs_ctx.directories == NULL) {
fprintf(stderr, "Failed to allocate RomFS directory cache!\n");
exit(EXIT_FAILURE);
}
nca_section_fseek(ctx, ctx->romfs_ctx.romfs_offset + ctx->romfs_ctx.header.dir_meta_table_offset);
- if (nca_section_fread(ctx, ctx->romfs_ctx.directories, ctx->romfs_ctx.header.dir_meta_table_size) != ctx->romfs_ctx.header.dir_meta_table_size) {
+ if (nca_section_fread(ctx, ctx->romfs_ctx.directories, (size_t)ctx->romfs_ctx.header.dir_meta_table_size) != ctx->romfs_ctx.header.dir_meta_table_size) {
fprintf(stderr, "Failed to read RomFS directory cache!\n");
exit(EXIT_FAILURE);
}
- ctx->romfs_ctx.files = calloc(1, ctx->romfs_ctx.header.file_meta_table_size);
+ ctx->romfs_ctx.files = calloc(1, (size_t)ctx->romfs_ctx.header.file_meta_table_size);
if (ctx->romfs_ctx.files == NULL) {
fprintf(stderr, "Failed to allocate RomFS file cache!\n");
exit(EXIT_FAILURE);
}
nca_section_fseek(ctx, ctx->romfs_ctx.romfs_offset + ctx->romfs_ctx.header.file_meta_table_offset);
- if (nca_section_fread(ctx, ctx->romfs_ctx.files, ctx->romfs_ctx.header.file_meta_table_size) != ctx->romfs_ctx.header.file_meta_table_size) {
+ if (nca_section_fread(ctx, ctx->romfs_ctx.files, (size_t)ctx->romfs_ctx.header.file_meta_table_size) != ctx->romfs_ctx.header.file_meta_table_size) {
fprintf(stderr, "Failed to read RomFS file cache!\n");
exit(EXIT_FAILURE);
}
@@ -1154,24 +1154,24 @@ void nca_process_bktr_section(nca_section_ctx_t *ctx) {
exit(EXIT_FAILURE);
}
/* Allocate space for an extra (fake) relocation entry, to simplify our logic. */
- void *relocs = calloc(1, sb->relocation_header.size + (0x3FF0 / sizeof(uint64_t)) * sizeof(bktr_relocation_entry_t));
+ void *relocs = calloc(1, (size_t)(sb->relocation_header.size + (0x3FF0 / sizeof(uint64_t)) * sizeof(bktr_relocation_entry_t)));
if (relocs == NULL) {
fprintf(stderr, "Failed to allocate relocation header!\n");
exit(EXIT_FAILURE);
}
/* Allocate space for an extra (fake) subsection entry, to simplify our logic. */
- void *subs = calloc(1, sb->subsection_header.size + (0x3FF0 / sizeof(uint64_t)) * sizeof(bktr_subsection_entry_t) + sizeof(bktr_subsection_entry_t));
+ void *subs = calloc(1, (size_t)(sb->subsection_header.size + (0x3FF0 / sizeof(uint64_t)) * sizeof(bktr_subsection_entry_t) + sizeof(bktr_subsection_entry_t)));
if (subs == NULL) {
fprintf(stderr, "Failed to allocate subsection header!\n");
exit(EXIT_FAILURE);
}
nca_section_fseek(ctx, sb->relocation_header.offset);
- if (nca_section_fread(ctx, relocs, sb->relocation_header.size) != sb->relocation_header.size) {
+ if (nca_section_fread(ctx, relocs, (size_t)sb->relocation_header.size) != sb->relocation_header.size) {
fprintf(stderr, "Failed to read relocation header!\n");
exit(EXIT_FAILURE);
}
nca_section_fseek(ctx, sb->subsection_header.offset);
- if (nca_section_fread(ctx, subs, sb->subsection_header.size) != sb->subsection_header.size) {
+ if (nca_section_fread(ctx, subs, (size_t)sb->subsection_header.size) != sb->subsection_header.size) {
fprintf(stderr, "Failed to read subsection header!\n");
exit(EXIT_FAILURE);
}
@@ -1246,24 +1246,24 @@ void nca_process_bktr_section(nca_section_ctx_t *ctx) {
if ((ctx->tool_ctx->action & (ACTION_EXTRACT | ACTION_LISTROMFS)) && ctx->bktr_ctx.header.header_size == ROMFS_HEADER_SIZE) {
/* Pre-load the file/data entry caches. */
- ctx->bktr_ctx.directories = calloc(1, ctx->bktr_ctx.header.dir_meta_table_size);
+ ctx->bktr_ctx.directories = calloc(1, (size_t)ctx->bktr_ctx.header.dir_meta_table_size);
if (ctx->bktr_ctx.directories == NULL) {
fprintf(stderr, "Failed to allocate RomFS directory cache!\n");
exit(EXIT_FAILURE);
}
nca_section_fseek(ctx, ctx->bktr_ctx.romfs_offset + ctx->bktr_ctx.header.dir_meta_table_offset);
- if (nca_section_fread(ctx, ctx->bktr_ctx.directories, ctx->bktr_ctx.header.dir_meta_table_size) != ctx->bktr_ctx.header.dir_meta_table_size) {
+ if (nca_section_fread(ctx, ctx->bktr_ctx.directories, (size_t)ctx->bktr_ctx.header.dir_meta_table_size) != ctx->bktr_ctx.header.dir_meta_table_size) {
fprintf(stderr, "Failed to read RomFS directory cache!\n");
exit(EXIT_FAILURE);
}
- ctx->bktr_ctx.files = calloc(1, ctx->bktr_ctx.header.file_meta_table_size);
+ ctx->bktr_ctx.files = calloc(1, (size_t)ctx->bktr_ctx.header.file_meta_table_size);
if (ctx->bktr_ctx.files == NULL) {
fprintf(stderr, "Failed to allocate RomFS file cache!\n");
exit(EXIT_FAILURE);
}
nca_section_fseek(ctx, ctx->bktr_ctx.romfs_offset + ctx->bktr_ctx.header.file_meta_table_offset);
- if (nca_section_fread(ctx, ctx->bktr_ctx.files, ctx->bktr_ctx.header.file_meta_table_size) != ctx->bktr_ctx.header.file_meta_table_size) {
+ if (nca_section_fread(ctx, ctx->bktr_ctx.files, (size_t)ctx->bktr_ctx.header.file_meta_table_size) != ctx->bktr_ctx.header.file_meta_table_size) {
fprintf(stderr, "Failed to read RomFS file cache!\n");
exit(EXIT_FAILURE);
}
@@ -1374,21 +1374,21 @@ void nca_save_section_file(nca_section_ctx_t *ctx, uint64_t ofs, uint64_t total_
}
uint64_t read_size = 0x400000; /* 4 MB buffer. */
- unsigned char *buf = malloc(read_size);
+ unsigned char *buf = malloc((size_t)read_size);
if (buf == NULL) {
fprintf(stderr, "Failed to allocate file-save buffer!\n");
exit(EXIT_FAILURE);
}
- memset(buf, 0xCC, read_size); /* Debug in case I fuck this up somehow... */
+ memset(buf, 0xCC, (size_t)read_size); /* Debug in case I fuck this up somehow... */
uint64_t end_ofs = ofs + total_size;
while (ofs < end_ofs) {
nca_section_fseek(ctx, ofs);
if (ofs + read_size >= end_ofs) read_size = end_ofs - ofs;
- if (nca_section_fread(ctx, buf, read_size) != read_size) {
+ if (nca_section_fread(ctx, buf, (size_t)read_size) != read_size) {
fprintf(stderr, "Failed to read file!\n");
exit(EXIT_FAILURE);
}
- if (fwrite(buf, 1, read_size, f_out) != read_size) {
+ if (fwrite(buf, 1, (size_t)read_size, f_out) != read_size) {
fprintf(stderr, "Failed to write file!\n");
exit(EXIT_FAILURE);
}
diff --git a/nso.c b/nso.c
index df39404..0f1af96 100644
--- a/nso.c
+++ b/nso.c
@@ -17,7 +17,7 @@ static void *nso_uncompress(nso0_ctx_t *ctx) {
new_header.flags &= 0xF8;
uint64_t size = nso_get_size(&new_header);
- nso0_header_t *new_nso = calloc(1, size);
+ nso0_header_t *new_nso = calloc(1, (size_t)size);
if (new_nso == NULL) {
fprintf(stderr, "Failed to allocate uncompressed NSO0!\n");
exit(EXIT_FAILURE);
@@ -64,14 +64,14 @@ void nso0_process(nso0_ctx_t *ctx) {
}
uint64_t size = nso_get_size(&raw_header);
- ctx->header = malloc(size);
+ ctx->header = malloc((size_t)size);
if (ctx->header == NULL) {
fprintf(stderr, "Failed to allocate NSO0!\n");
exit(EXIT_FAILURE);
}
fseeko64(ctx->file, 0, SEEK_SET);
- if (fread(ctx->header, 1, size, ctx->file) != size) {
+ if (fread(ctx->header, 1, (size_t)size, ctx->file) != size) {
fprintf(stderr, "Failed to read NSO0!\n");
exit(EXIT_FAILURE);
}
@@ -117,7 +117,7 @@ void nso0_save(nso0_ctx_t *ctx) {
fprintf(stderr, "Failed to open %s!\n", uncmp_path->char_path);
return;
}
- if (fwrite(ctx->uncompressed_header, 1, nso_get_size(ctx->uncompressed_header), f_uncmp) != nso_get_size(ctx->uncompressed_header)) {
+ if (fwrite(ctx->uncompressed_header, 1, (size_t)nso_get_size(ctx->uncompressed_header), f_uncmp) != nso_get_size(ctx->uncompressed_header)) {
fprintf(stderr, "Failed to write uncompressed nso!\n");
exit(EXIT_FAILURE);
}
diff --git a/pfs0.c b/pfs0.c
index 3cc11fb..9442c7a 100644
--- a/pfs0.c
+++ b/pfs0.c
@@ -16,14 +16,14 @@ void pfs0_process(pfs0_ctx_t *ctx) {
}
uint64_t header_size = pfs0_get_header_size(&raw_header);
- ctx->header = malloc(header_size);
+ ctx->header = malloc((size_t)header_size);
if (ctx->header == NULL) {
fprintf(stderr, "Failed to allocate PFS0 header!\n");
exit(EXIT_FAILURE);
}
fseeko64(ctx->file, 0, SEEK_SET);
- if (fread(ctx->header, 1, header_size, ctx->file) != header_size) {
+ if (fread(ctx->header, 1, (size_t)header_size, ctx->file) != header_size) {
fprintf(stderr, "Failed to read PFS0 header!\n");
exit(EXIT_FAILURE);
}
@@ -42,13 +42,13 @@ void pfs0_process(pfs0_ctx_t *ctx) {
if (strcmp(pfs0_get_file_name(ctx->header, i), "main.npdm") == 0) {
/* We might have found the exefs... */
- ctx->npdm = malloc(cur_file->size);
+ ctx->npdm = malloc((size_t)cur_file->size);
if (ctx->npdm == NULL) {
fprintf(stderr, "Failed to allocate NPDM!\n");
exit(EXIT_FAILURE);
}
fseeko64(ctx->file, pfs0_get_header_size(ctx->header) + cur_file->offset, SEEK_SET);
- if (fread(ctx->npdm, 1, cur_file->size, ctx->file) != cur_file->size) {
+ if (fread(ctx->npdm, 1, (size_t)cur_file->size, ctx->file) != cur_file->size) {
fprintf(stderr, "Failed to read NPDM!\n");
exit(EXIT_FAILURE);
}
diff --git a/romfs.c b/romfs.c
index 7bce70b..7500b7b 100644
--- a/romfs.c
+++ b/romfs.c
@@ -74,25 +74,25 @@ void romfs_process(romfs_ctx_t *ctx) {
if ((ctx->tool_ctx->action & (ACTION_EXTRACT | ACTION_LISTROMFS)) && ctx->header.header_size == ROMFS_HEADER_SIZE) {
/* Pre-load the file/data entry caches. */
- ctx->directories = calloc(1, ctx->header.dir_meta_table_size);
+ ctx->directories = calloc(1, (size_t)ctx->header.dir_meta_table_size);
if (ctx->directories == NULL) {
fprintf(stderr, "Failed to allocate RomFS directory cache!\n");
exit(EXIT_FAILURE);
}
- fseeko64(ctx->file, ctx->romfs_offset + ctx->header.dir_meta_table_offset, SEEK_SET);
- if (fread(ctx->directories, 1, ctx->header.dir_meta_table_size, ctx->file) != ctx->header.dir_meta_table_size) {
+ fseeko64(ctx->file, (size_t)(ctx->romfs_offset + ctx->header.dir_meta_table_offset), SEEK_SET);
+ if (fread(ctx->directories, 1, (size_t)ctx->header.dir_meta_table_size, ctx->file) != ctx->header.dir_meta_table_size) {
fprintf(stderr, "Failed to read RomFS directory cache!\n");
exit(EXIT_FAILURE);
}
- ctx->files = calloc(1, ctx->header.file_meta_table_size);
+ ctx->files = calloc(1, (size_t)ctx->header.file_meta_table_size);
if (ctx->files == NULL) {
fprintf(stderr, "Failed to allocate RomFS file cache!\n");
exit(EXIT_FAILURE);
}
fseeko64(ctx->file, ctx->romfs_offset + ctx->header.file_meta_table_offset, SEEK_SET);
- if (fread(ctx->files, 1, ctx->header.file_meta_table_size, ctx->file) != ctx->header.file_meta_table_size) {
+ if (fread(ctx->files, 1, (size_t)ctx->header.file_meta_table_size, ctx->file) != ctx->header.file_meta_table_size) {
fprintf(stderr, "Failed to read RomFS file cache!\n");
exit(EXIT_FAILURE);
}
diff --git a/rsa.c b/rsa.c
index 7fd0310..94e2b81 100644
--- a/rsa.c
+++ b/rsa.c
@@ -20,7 +20,7 @@ static void calculate_mgf1_and_xor(unsigned char *data, size_t data_size, const
h_buf[h_src_size + 3 - i] = (seed >> (8 * i)) & 0xFF;
}
sha256_hash_buffer(mgf1_buf, h_buf, h_src_size + 4);
- for (unsigned int i = ofs; i < data_size && i < ofs + 0x20; i++) {
+ for (size_t i = ofs; i < data_size && i < ofs + 0x20; i++) {
data[i] ^= mgf1_buf[i - ofs];
}
seed++;
diff --git a/save.c b/save.c
index e216a21..4576e07 100644
--- a/save.c
+++ b/save.c
@@ -27,9 +27,9 @@ void save_duplex_storage_init(duplex_storage_ctx_t *ctx, duplex_fs_layer_info_t
ctx->block_size = 1 << layer->info.block_size_power;
ctx->bitmap.data = ctx->bitmap_storage;
- ctx->bitmap.bitmap = malloc(bitmap_size >> 3);
+ ctx->bitmap.bitmap = malloc((size_t)(bitmap_size >> 3));
- uint32_t bits_remaining = bitmap_size;
+ uint32_t bits_remaining = (uint32_t)bitmap_size;
uint32_t bitmap_pos = 0;
uint32_t *buffer_pos = (uint32_t *)bitmap;
while (bits_remaining) {
@@ -51,7 +51,7 @@ void save_duplex_storage_init(duplex_storage_ctx_t *ctx, duplex_fs_layer_info_t
uint32_t save_duplex_storage_read(duplex_storage_ctx_t *ctx, void *buffer, uint64_t offset, size_t count) {
uint64_t in_pos = offset;
uint32_t out_pos = 0;
- uint32_t remaining = count;
+ uint32_t remaining = (uint32_t)count;
while (remaining) {
uint32_t block_num = (uint32_t)(in_pos / ctx->block_size);
@@ -75,7 +75,7 @@ remap_segment_ctx_t *save_remap_init_segments(remap_header_t *header, remap_entr
for (unsigned int i = 0; i < header->map_segment_count; i++) {
remap_segment_ctx_t *seg = &segments[i];
seg->entry_count = 0;
- remap_entry_ctx_t **ptr = malloc(sizeof(remap_entry_ctx_t *) * (seg->entry_count + 1));
+ remap_entry_ctx_t **ptr = malloc((size_t)(sizeof(remap_entry_ctx_t *) * (seg->entry_count + 1)));
if (!ptr) {
fprintf(stderr, "Failed to allocate entries in remap storage!\n");
exit(EXIT_FAILURE);
@@ -88,7 +88,7 @@ remap_segment_ctx_t *save_remap_init_segments(remap_header_t *header, remap_entr
while (entry_idx < num_map_entries && map_entries[entry_idx - 1].virtual_offset_end == map_entries[entry_idx].virtual_offset) {
map_entries[entry_idx].segment = seg;
map_entries[entry_idx - 1].next = &map_entries[entry_idx];
- ptr = realloc(seg->entries, sizeof(remap_entry_ctx_t *) * (seg->entry_count + 1));
+ ptr = realloc(seg->entries, (size_t)(sizeof(remap_entry_ctx_t *) * (seg->entry_count + 1)));
if (!ptr) {
fprintf(stderr, "Failed to reallocate entries in remap storage!\n");
exit(EXIT_FAILURE);
@@ -116,7 +116,7 @@ uint32_t save_remap_read(remap_storage_ctx_t *ctx, void *buffer, uint64_t offset
remap_entry_ctx_t *entry = save_remap_get_map_entry(ctx, offset);
uint64_t in_pos = offset;
uint32_t out_pos = 0;
- uint32_t remaining = count;
+ uint32_t remaining = (uint32_t)count;
while (remaining) {
uint64_t entry_pos = in_pos - entry->virtual_offset;
@@ -147,7 +147,7 @@ uint32_t save_remap_read(remap_storage_ctx_t *ctx, void *buffer, uint64_t offset
uint32_t save_journal_storage_read(journal_storage_ctx_t *ctx, remap_storage_ctx_t *remap, void *buffer, uint64_t offset, size_t count) {
uint64_t in_pos = offset;
uint32_t out_pos = 0;
- uint32_t remaining = count;
+ uint32_t remaining = (uint32_t)count;
while (remaining) {
uint32_t block_num = (uint32_t)(in_pos / ctx->block_size);
@@ -194,7 +194,8 @@ void save_ivfc_storage_init(hierarchical_integrity_verification_storage_ctx_t *c
{"HierarchicalIntegrityVerificationStorage::L4", 44},
{"HierarchicalIntegrityVerificationStorage::L5", 44}
};
- integrity_verification_info_ctx_t init_info[ivfc->num_levels];
+ // integrity_verification_info_ctx_t init_info[ivfc->num_levels];
+ integrity_verification_info_ctx_t init_info[SAVE_MAX_IVFC_LEVELS];
init_info[0].data = &levels[0];
init_info[0].block_size = 0;
@@ -212,7 +213,7 @@ void save_ivfc_storage_init(hierarchical_integrity_verification_storage_ctx_t *c
level_data->base_storage = &levels[i];
level_data->sector_size = init_info[i].block_size;
level_data->_length = init_info[i].data->data_size;
- level_data->sector_count = (level_data->_length + level_data->sector_size - 1) / level_data->sector_size;
+ level_data->sector_count = (uint32_t)((level_data->_length + level_data->sector_size - 1) / level_data->sector_size);
memcpy(level_data->salt, init_info[i].salt, 0x20);
level_data->block_validities = calloc(1, sizeof(validity_t) * level_data->sector_count);
ctx->level_validities[i - 1] = level_data->block_validities;
@@ -419,7 +420,7 @@ uint32_t save_allocation_table_storage_read(allocation_table_storage_ctx_t *ctx,
save_allocation_table_iterator_begin(&iterator, ctx->fat, ctx->initial_block);
uint64_t in_pos = offset;
uint32_t out_pos = 0;
- uint32_t remaining = count;
+ uint32_t remaining = (uint32_t)count;
while (remaining) {
uint32_t block_num = (uint32_t)(in_pos / ctx->block_size);
@@ -559,11 +560,11 @@ validity_t save_ivfc_validate(hierarchical_integrity_verification_storage_ctx_t
uint64_t block_size = storage->sector_size;
uint32_t block_count = (uint32_t)((storage->_length + block_size - 1) / block_size);
- uint8_t *buffer = malloc(block_size);
+ uint8_t *buffer = malloc((size_t)block_size);
for (unsigned int j = 0; j < block_count; j++) {
if (ctx->level_validities[ivfc->num_levels - 2][j] == VALIDITY_UNCHECKED) {
- uint32_t to_read = storage->_length - block_size * j < block_size ? storage->_length - block_size * j : block_size;
+ uint32_t to_read = (uint32_t)(storage->_length - block_size * j < block_size ? storage->_length - block_size * j : block_size);
save_ivfc_storage_read(storage, buffer, block_size * j, to_read, 1);
}
if (ctx->level_validities[ivfc->num_levels - 2][j] == VALIDITY_INVALID) {
@@ -664,16 +665,16 @@ void save_process(save_ctx_t *ctx) {
ctx->duplex_layers[0].data_b = (uint8_t *)&ctx->header + ctx->header.layout.duplex_master_offset_b;
memcpy(&ctx->duplex_layers[0].info, &ctx->header.duplex_header.layers[0], sizeof(duplex_info_t));
- ctx->duplex_layers[1].data_a = malloc(ctx->header.layout.duplex_l1_size);
- save_remap_read(&ctx->data_remap_storage, ctx->duplex_layers[1].data_a, ctx->header.layout.duplex_l1_offset_a, ctx->header.layout.duplex_l1_size);
- ctx->duplex_layers[1].data_b = malloc(ctx->header.layout.duplex_l1_size);
- save_remap_read(&ctx->data_remap_storage, ctx->duplex_layers[1].data_b, ctx->header.layout.duplex_l1_offset_b, ctx->header.layout.duplex_l1_size);
+ ctx->duplex_layers[1].data_a = malloc((size_t)ctx->header.layout.duplex_l1_size);
+ save_remap_read(&ctx->data_remap_storage, ctx->duplex_layers[1].data_a, ctx->header.layout.duplex_l1_offset_a, (size_t)ctx->header.layout.duplex_l1_size);
+ ctx->duplex_layers[1].data_b = malloc((size_t)ctx->header.layout.duplex_l1_size);
+ save_remap_read(&ctx->data_remap_storage, ctx->duplex_layers[1].data_b, ctx->header.layout.duplex_l1_offset_b, (size_t)ctx->header.layout.duplex_l1_size);
memcpy(&ctx->duplex_layers[1].info, &ctx->header.duplex_header.layers[1], sizeof(duplex_info_t));
- ctx->duplex_layers[2].data_a = malloc(ctx->header.layout.duplex_data_size);
- save_remap_read(&ctx->data_remap_storage, ctx->duplex_layers[2].data_a, ctx->header.layout.duplex_data_offset_a, ctx->header.layout.duplex_data_size);
- ctx->duplex_layers[2].data_b = malloc(ctx->header.layout.duplex_data_size);
- save_remap_read(&ctx->data_remap_storage, ctx->duplex_layers[2].data_b, ctx->header.layout.duplex_data_offset_b, ctx->header.layout.duplex_data_size);
+ ctx->duplex_layers[2].data_a = malloc((size_t)ctx->header.layout.duplex_data_size);
+ save_remap_read(&ctx->data_remap_storage, ctx->duplex_layers[2].data_a, ctx->header.layout.duplex_data_offset_a, (size_t)ctx->header.layout.duplex_data_size);
+ ctx->duplex_layers[2].data_b = malloc((size_t)ctx->header.layout.duplex_data_size);
+ save_remap_read(&ctx->data_remap_storage, ctx->duplex_layers[2].data_b, ctx->header.layout.duplex_data_offset_b, (size_t)ctx->header.layout.duplex_data_size);
memcpy(&ctx->duplex_layers[2].info, &ctx->header.duplex_header.layers[2], sizeof(duplex_info_t));
/* Initialize hierarchical duplex storage. */
@@ -681,8 +682,8 @@ void save_process(save_ctx_t *ctx) {
save_duplex_storage_init(&ctx->duplex_storage.layers[0], &ctx->duplex_layers[1], bitmap, ctx->header.layout.duplex_master_size);
ctx->duplex_storage.layers[0]._length = ctx->header.layout.duplex_l1_size;
- bitmap = malloc(ctx->duplex_storage.layers[0]._length);
- save_duplex_storage_read(&ctx->duplex_storage.layers[0], bitmap, 0, ctx->duplex_storage.layers[0]._length);
+ bitmap = malloc((size_t)ctx->duplex_storage.layers[0]._length);
+ save_duplex_storage_read(&ctx->duplex_storage.layers[0], bitmap, 0, (size_t)ctx->duplex_storage.layers[0]._length);
save_duplex_storage_init(&ctx->duplex_storage.layers[1], &ctx->duplex_layers[2], bitmap, ctx->duplex_storage.layers[0]._length);
ctx->duplex_storage.layers[1]._length = ctx->header.layout.duplex_data_size;
@@ -692,7 +693,7 @@ void save_process(save_ctx_t *ctx) {
ctx->meta_remap_storage.type = STORAGE_DUPLEX;
ctx->meta_remap_storage.duplex = &ctx->duplex_storage.data_layer;
ctx->meta_remap_storage.header = &ctx->header.meta_remap_header;
- ctx->meta_remap_storage.map_entries = malloc(sizeof(remap_entry_ctx_t) * ctx->meta_remap_storage.header->map_entry_count);
+ ctx->meta_remap_storage.map_entries = malloc((size_t)(sizeof(remap_entry_ctx_t) * ctx->meta_remap_storage.header->map_entry_count));
ctx->meta_remap_storage.file = ctx->file;
fseeko64(ctx->file, ctx->header.layout.meta_map_entry_offset, SEEK_SET);
for (unsigned int i = 0; i < ctx->meta_remap_storage.header->map_entry_count; i++) {
@@ -704,8 +705,8 @@ void save_process(save_ctx_t *ctx) {
ctx->meta_remap_storage.segments = save_remap_init_segments(ctx->meta_remap_storage.header, ctx->meta_remap_storage.map_entries, ctx->meta_remap_storage.header->map_entry_count);
/* Initialize journal map. */
- ctx->journal_map_info.map_storage = malloc(ctx->header.layout.journal_map_table_size);
- save_remap_read(&ctx->meta_remap_storage, ctx->journal_map_info.map_storage, ctx->header.layout.journal_map_table_offset, ctx->header.layout.journal_map_table_size);
+ ctx->journal_map_info.map_storage = malloc((size_t)ctx->header.layout.journal_map_table_size);
+ save_remap_read(&ctx->meta_remap_storage, ctx->journal_map_info.map_storage, ctx->header.layout.journal_map_table_offset, (size_t)ctx->header.layout.journal_map_table_size);
/* Initialize journal storage. */
ctx->journal_storage.header = &ctx->header.journal_header;
@@ -721,7 +722,7 @@ void save_process(save_ctx_t *ctx) {
ctx->journal_storage.map.entries[i].physical_index = *pos & 0x7FFFFFFF;
pos += 2;
}
- ctx->journal_storage.block_size = ctx->journal_storage.header->block_size;
+ ctx->journal_storage.block_size = (uint32_t)ctx->journal_storage.header->block_size;
ctx->journal_storage._length = ctx->journal_storage.header->total_size - ctx->journal_storage.header->journal_size;
/* Initialize core IVFC storage. */
@@ -732,15 +733,15 @@ void save_process(save_ctx_t *ctx) {
/* Initialize FAT storage. */
if (ctx->header.layout.version < 0x50000) {
- ctx->fat_storage = malloc(ctx->header.layout.fat_size);
- save_remap_read(&ctx->meta_remap_storage, ctx->fat_storage, ctx->header.layout.fat_offset, ctx->header.layout.fat_size);
+ ctx->fat_storage = malloc((size_t)ctx->header.layout.fat_size);
+ save_remap_read(&ctx->meta_remap_storage, ctx->fat_storage, ctx->header.layout.fat_offset, (size_t)ctx->header.layout.fat_size);
} else {
for (unsigned int i = 0; i < 5; i++) {
ctx->fat_ivfc_storage.levels[i].save_ctx = ctx;
}
save_ivfc_storage_init(&ctx->fat_ivfc_storage, ctx->header.layout.fat_ivfc_master_hash_a, &ctx->header.fat_ivfc_header);
- ctx->fat_storage = malloc(ctx->fat_ivfc_storage._length);
- save_remap_read(&ctx->meta_remap_storage, ctx->fat_storage, ctx->header.fat_ivfc_header.level_headers[ctx->header.fat_ivfc_header.num_levels - 2].logical_offset, ctx->fat_ivfc_storage._length);
+ ctx->fat_storage = malloc((size_t)ctx->fat_ivfc_storage._length);
+ save_remap_read(&ctx->meta_remap_storage, ctx->fat_storage, ctx->header.fat_ivfc_header.level_headers[ctx->header.fat_ivfc_header.num_levels - 2].logical_offset, (size_t)ctx->fat_ivfc_storage._length);
}
if (ctx->tool_ctx->action & ACTION_VERIFY) {
@@ -823,7 +824,7 @@ void save_save_file(save_ctx_t *ctx, uint64_t ofs, uint64_t total_size, uint32_t
}
uint64_t read_size = 0x400000; /* 4 MB buffer. */
- unsigned char *buf = malloc(read_size);
+ unsigned char *buf = malloc((size_t)read_size);
if (buf == NULL) {
fprintf(stderr, "Failed to allocate file-save buffer!\n");
exit(EXIT_FAILURE);
@@ -834,8 +835,8 @@ void save_save_file(save_ctx_t *ctx, uint64_t ofs, uint64_t total_size, uint32_t
save_open_fat_storage(&ctx->save_filesystem_core, &storage, start_block);
while (ofs < end_ofs) {
if (ofs + read_size >= end_ofs) read_size = end_ofs - ofs;
- save_allocation_table_storage_read(&storage, buf, ofs, read_size);
- if (fwrite(buf, 1, read_size, f_out) != read_size) {
+ save_allocation_table_storage_read(&storage, buf, ofs, (size_t)read_size);
+ if (fwrite(buf, 1, (size_t)read_size, f_out) != read_size) {
fprintf(stderr, "Failed to write file!\n");
exit(EXIT_FAILURE);
}
@@ -852,7 +853,7 @@ static int save_visit_save_file(save_ctx_t *ctx, uint32_t file_index, filepath_t
if (!save_fs_list_get_value(&ctx->save_filesystem_core.file_table.file_table, file_index, &entry)) {
return 0;
}
- uint32_t name_size = strlen(entry.name);
+ uint32_t name_size = (uint32_t)strlen(entry.name);
filepath_t *cur_path = calloc(1, sizeof(filepath_t));
if (cur_path == NULL) {
@@ -888,7 +889,7 @@ static int save_visit_save_dir(save_ctx_t *ctx, uint32_t dir_index, filepath_t *
if (!save_fs_list_get_value(&ctx->save_filesystem_core.file_table.directory_table, dir_index, &entry)) {
return 0;
}
- uint32_t name_size = strlen(entry.name);
+ uint32_t name_size = (uint32_t)strlen(entry.name);
filepath_t *cur_path = calloc(1, sizeof(filepath_t));
if (cur_path == NULL) {
diff --git a/save.h b/save.h
index 4340011..bfa2018 100644
--- a/save.h
+++ b/save.h
@@ -9,6 +9,8 @@
#define SAVE_FS_LIST_MAX_NAME_LENGTH 0x40
#define SAVE_FS_LIST_ENTRY_SIZE 0x60
+#define SAVE_MAX_IVFC_LEVELS 6
+
#define MAGIC_DISF 0x46534944
#define MAGIC_DPFS 0x53465044
#define MAGIC_JNGL 0x4C474E4A
diff --git a/types.h b/types.h
index 3738338..122af7e 100644
--- a/types.h
+++ b/types.h
@@ -16,4 +16,12 @@ typedef enum {
#define GET_VALIDITY_STR(validity) ((validity == VALIDITY_VALID) ? "GOOD" : "FAIL")
+// visual studio compatibility
+#ifdef _WIN32
+#define strcasecmp _stricmp
+#define strdup _strdup
+#else
+#include
+#endif
+
#endif
diff --git a/utils.c b/utils.c
index 3d40bbb..4b05612 100644
--- a/utils.c
+++ b/utils.c
@@ -30,12 +30,12 @@ void print_magic(const char *prefix, uint32_t magic) {
void memdump(FILE *f, const char *prefix, const void *data, size_t size) {
const uint8_t *p = (const uint8_t *)data;
- unsigned int prefix_len = strlen(prefix);
+ size_t prefix_len = strlen(prefix);
size_t offset = 0;
int first = 1;
while (size) {
- unsigned int max = 32;
+ size_t max = 32;
if (max > size) {
max = size;
@@ -45,10 +45,10 @@ void memdump(FILE *f, const char *prefix, const void *data, size_t size) {
fprintf(f, "%s", prefix);
first = 0;
} else {
- fprintf(f, "%*s", prefix_len, "");
+ fprintf(f, "%*s", (int)prefix_len, "");
}
- for (unsigned int i = 0; i < max; i++) {
+ for (size_t i = 0; i < max; i++) {
fprintf(f, "%02X", p[offset++]);
}
@@ -66,7 +66,7 @@ void save_buffer_to_file(void *buf, uint64_t size, struct filepath *filepath) {
return;
}
- fwrite(buf, 1, size, f_out);
+ fwrite(buf, 1, (size_t)size, f_out);
fclose(f_out);
}
@@ -92,21 +92,21 @@ void save_file_section(FILE *f_in, uint64_t ofs, uint64_t total_size, filepath_t
}
uint64_t read_size = 0x400000; /* 4 MB buffer. */
- unsigned char *buf = malloc(read_size);
+ unsigned char *buf = malloc((size_t)read_size);
if (buf == NULL) {
fprintf(stderr, "Failed to allocate file-save buffer!\n");
exit(EXIT_FAILURE);
}
- memset(buf, 0xCC, read_size); /* Debug in case I fuck this up somehow... */
+ memset(buf, 0xCC, (size_t)read_size); /* Debug in case I fuck this up somehow... */
uint64_t end_ofs = ofs + total_size;
fseeko64(f_in, ofs, SEEK_SET);
while (ofs < end_ofs) {
if (ofs + read_size >= end_ofs) read_size = end_ofs - ofs;
- if (fread(buf, 1, read_size, f_in) != read_size) {
+ if (fread(buf, 1, (size_t)read_size, f_in) != read_size) {
fprintf(stderr, "Failed to read file!\n");
exit(EXIT_FAILURE);
}
- fwrite(buf, 1, read_size, f_out);
+ fwrite(buf, 1, (size_t)read_size, f_out);
ofs += read_size;
}
@@ -123,7 +123,7 @@ validity_t check_memory_hash_table(FILE *f_in, unsigned char *hash_table, uint64
}
unsigned char cur_hash[0x20];
uint64_t read_size = block_size;
- unsigned char *block = malloc(block_size);
+ unsigned char *block = malloc((size_t)block_size);
if (block == NULL) {
fprintf(stderr, "Failed to allocate hash block!\n");
exit(EXIT_FAILURE);
@@ -135,15 +135,15 @@ validity_t check_memory_hash_table(FILE *f_in, unsigned char *hash_table, uint64
fseeko64(f_in, ofs + data_ofs, SEEK_SET);
if (ofs + read_size > data_len) {
/* Last block... */
- memset(block, 0, read_size);
+ memset(block, 0, (size_t)read_size);
read_size = data_len - ofs;
}
- if (fread(block, 1, read_size, f_in) != read_size) {
+ if (fread(block, 1, (size_t)read_size, f_in) != read_size) {
fprintf(stderr, "Failed to read file!\n");
exit(EXIT_FAILURE);
}
- sha256_hash_buffer(cur_hash, block, full_block ? block_size : read_size);
+ sha256_hash_buffer(cur_hash, block, (size_t)(full_block ? block_size : read_size));
if (memcmp(cur_hash, cur_hash_table_entry, 0x20) != 0) {
result = VALIDITY_INVALID;
break;
@@ -163,7 +163,7 @@ validity_t check_memory_hash_table_with_suffix(FILE *f_in, unsigned char *hash_t
unsigned char cur_hash[0x20];
uint64_t read_size = block_size;
- unsigned char *block = malloc(block_size);
+ unsigned char *block = malloc((size_t)block_size);
if (block == NULL) {
fprintf(stderr, "Failed to allocate hash block!\n");
exit(EXIT_FAILURE);
@@ -175,17 +175,17 @@ validity_t check_memory_hash_table_with_suffix(FILE *f_in, unsigned char *hash_t
fseeko64(f_in, ofs + data_ofs, SEEK_SET);
if (ofs + read_size > data_len) {
/* Last block... */
- memset(block, 0, read_size);
+ memset(block, 0, (size_t)read_size);
read_size = data_len - ofs;
}
- if (fread(block, 1, read_size, f_in) != read_size) {
+ if (fread(block, 1, (size_t)read_size, f_in) != read_size) {
fprintf(stderr, "Failed to read file!\n");
exit(EXIT_FAILURE);
}
{
sha_ctx_t *sha_ctx = new_sha_ctx(HASH_TYPE_SHA256, 0);
- sha_update(sha_ctx, block, full_block ? block_size : read_size);
+ sha_update(sha_ctx, block, (size_t)(full_block ? block_size : read_size));
if (suffix) {
sha_update(sha_ctx, suffix, sizeof(*suffix));
}
@@ -211,14 +211,14 @@ validity_t check_file_hash_table(FILE *f_in, uint64_t hash_ofs, uint64_t data_of
uint64_t hash_table_size = data_len / block_size;
if (data_len % block_size) hash_table_size++;
hash_table_size *= 0x20;
- unsigned char *hash_table = malloc(hash_table_size);
+ unsigned char *hash_table = malloc((size_t)hash_table_size);
if (hash_table == NULL) {
fprintf(stderr, "Failed to allocate hash table!\n");
exit(EXIT_FAILURE);
}
fseeko64(f_in, hash_ofs, SEEK_SET);
- if (fread(hash_table, 1, hash_table_size, f_in) != hash_table_size) {
+ if (fread(hash_table, 1, (size_t)hash_table_size, f_in) != hash_table_size) {
fprintf(stderr, "Failed to read file!\n");
exit(EXIT_FAILURE);
}