diff --git a/src/LibHac/Boot/Package2StorageReader.cs b/src/LibHac/Boot/Package2StorageReader.cs
index c23a02e1..125a0cde 100644
--- a/src/LibHac/Boot/Package2StorageReader.cs
+++ b/src/LibHac/Boot/Package2StorageReader.cs
@@ -13,33 +13,38 @@ namespace LibHac.Boot
///
/// Parses a package2 file and opens the payloads within.
///
- public class Package2StorageReader
+ public class Package2StorageReader : IDisposable
{
private const int KernelPayloadIndex = 0;
private const int IniPayloadIndex = 1;
- private IStorage _storage;
+ private SharedRef _storage;
private Package2Header _header;
private KeySet _keySet;
private Crypto.AesKey _key;
public ref readonly Package2Header Header => ref _header;
+ public void Dispose()
+ {
+ _storage.Destroy();
+ }
+
///
/// Initializes the .
///
/// The keyset to use for decrypting the package.
/// An of the encrypted package2.
/// The of the operation.
- public Result Initialize(KeySet keySet, IStorage storage)
+ public Result Initialize(KeySet keySet, in SharedRef storage)
{
- Result rc = storage.Read(0, SpanHelpers.AsByteSpan(ref _header));
+ Result rc = storage.Get.Read(0, SpanHelpers.AsByteSpan(ref _header));
if (rc.IsFailure()) return rc;
_key = keySet.Package2Keys[_header.Meta.KeyGeneration];
DecryptHeader(_key, ref _header.Meta, ref _header.Meta);
- _storage = storage;
+ _storage.SetByCopy(in storage);
_keySet = keySet;
return Result.Success;
}
@@ -47,14 +52,12 @@ namespace LibHac.Boot
///
/// Opens a decrypted of one of the payloads in the package.
///
- /// If the method returns successfully, contains an
+ /// If the method returns successfully, contains an
/// of the specified payload.
/// The index of the payload to get. Must me less than
/// The of the operation.
- public Result OpenPayload(out IStorage payloadStorage, int index)
+ public Result OpenPayload(ref UniqueRef outPayloadStorage, int index)
{
- UnsafeHelpers.SkipParamInit(out payloadStorage);
-
if ((uint)index >= Package2Header.PayloadCount)
return ResultLibHac.ArgumentOutOfRange.Log();
@@ -65,53 +68,52 @@ namespace LibHac.Boot
if (size == 0)
{
- payloadStorage = payloadSubStorage;
+ outPayloadStorage.Reset(payloadSubStorage);
return Result.Success;
}
byte[] iv = _header.Meta.PayloadIvs[index].Bytes.ToArray();
- payloadStorage = new CachedStorage(new Aes128CtrStorage(payloadSubStorage, _key.DataRo.ToArray(), iv, true), 0x4000, 1, true);
+ outPayloadStorage.Reset(new CachedStorage(new Aes128CtrStorage(payloadSubStorage, _key.DataRo.ToArray(), iv, true), 0x4000, 1, true));
return Result.Success;
}
///
/// Opens an of the kernel payload.
///
- /// If the method returns successfully, contains an
+ /// If the method returns successfully, contains an
/// of the kernel payload.
/// The of the operation.
- public Result OpenKernel(out IStorage kernelStorage)
+ public Result OpenKernel(ref UniqueRef outKernelStorage)
{
- return OpenPayload(out kernelStorage, KernelPayloadIndex);
+ return OpenPayload(ref outKernelStorage, KernelPayloadIndex);
}
///
/// Opens an of the initial process binary. If the binary is embedded in
/// the kernel, this method will attempt to locate and return the embedded binary.
///
- /// If the method returns successfully, contains an
+ /// If the method returns successfully, contains an
/// of the initial process binary.
/// The of the operation.
- public Result OpenIni(out IStorage iniStorage)
+ public Result OpenIni(ref UniqueRef outIniStorage)
{
if (HasIniPayload())
{
- return OpenPayload(out iniStorage, IniPayloadIndex);
+ return OpenPayload(ref outIniStorage, IniPayloadIndex);
}
// Ini is embedded in the kernel
- UnsafeHelpers.SkipParamInit(out iniStorage);
-
- Result rc = OpenKernel(out IStorage kernelStorage);
+ using var kernelStorage = new UniqueRef();
+ Result rc = OpenKernel(ref kernelStorage.Ref());
if (rc.IsFailure()) return rc;
- if (!IniExtract.TryGetIni1Offset(out int offset, out int size, kernelStorage))
+ if (!IniExtract.TryGetIni1Offset(out int offset, out int size, kernelStorage.Get))
{
// Unable to find the ini. Could be a new, unsupported layout.
return ResultLibHac.NotImplemented.Log();
}
- iniStorage = new SubStorage(kernelStorage, offset, size);
+ outIniStorage.Reset(new SubStorage(kernelStorage.Release(), offset, size));
return Result.Success;
}
@@ -140,7 +142,7 @@ namespace LibHac.Boot
Unsafe.SkipInit(out Package2Meta meta);
Span metaBytes = SpanHelpers.AsByteSpan(ref meta);
- Result rc = _storage.Read(Package2Header.SignatureSize, metaBytes);
+ Result rc = _storage.Get.Read(Package2Header.SignatureSize, metaBytes);
if (rc.IsFailure()) return rc;
return _header.VerifySignature(_keySet.Package2SigningKeyParams.Modulus, metaBytes);
@@ -209,10 +211,10 @@ namespace LibHac.Boot
///
/// Opens a decrypted of the entire package.
///
- /// If the method returns successfully, contains a decrypted
+ /// If the method returns successfully, contains a decrypted
/// of the package.
/// The of the operation.
- public Result OpenDecryptedPackage(out IStorage packageStorage)
+ public Result OpenDecryptedPackage(ref UniqueRef outPackageStorage)
{
var storages = new List(4);
@@ -239,17 +241,14 @@ namespace LibHac.Boot
if (_header.Meta.PayloadSizes[i] == 0)
continue;
- Result rc = OpenPayload(out IStorage payloadStorage, i);
- if (rc.IsFailure())
- {
- UnsafeHelpers.SkipParamInit(out packageStorage);
- return rc;
- }
+ using var payloadStorage = new UniqueRef();
+ Result rc = OpenPayload(ref payloadStorage.Ref(), i);
+ if (rc.IsFailure()) return rc.Miss();
- storages.Add(payloadStorage);
+ storages.Add(payloadStorage.Release());
}
- packageStorage = new ConcatenationStorage(storages, true);
+ outPackageStorage.Reset(new ConcatenationStorage(storages, true));
return Result.Success;
}
diff --git a/src/LibHac/Kernel/InitialProcessBinaryReader.cs b/src/LibHac/Kernel/InitialProcessBinaryReader.cs
index 041ee2e9..4f8f81eb 100644
--- a/src/LibHac/Kernel/InitialProcessBinaryReader.cs
+++ b/src/LibHac/Kernel/InitialProcessBinaryReader.cs
@@ -1,4 +1,5 @@
-using System.Runtime.CompilerServices;
+using System;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using LibHac.Common;
using LibHac.Diag;
@@ -6,32 +7,37 @@ using LibHac.Fs;
namespace LibHac.Kernel
{
- public class InitialProcessBinaryReader
+ public class InitialProcessBinaryReader : IDisposable
{
internal const uint ExpectedMagic = 0x31494E49; // INI1
private const int MaxProcessCount = 80;
- private IStorage _storage;
+ private SharedRef _storage;
private IniHeader _header;
private (int offset, int size)[] _offsets;
public ref readonly IniHeader Header => ref _header;
public int ProcessCount => _header.ProcessCount;
- public Result Initialize(IStorage binaryStorage)
+ public void Dispose()
{
- if (binaryStorage is null)
+ _storage.Destroy();
+ }
+
+ public Result Initialize(in SharedRef binaryStorage)
+ {
+ if (!binaryStorage.HasValue)
return ResultLibHac.NullArgument.Log();
// Verify there's enough data to read the header
- Result rc = binaryStorage.GetSize(out long iniSize);
+ Result rc = binaryStorage.Get.GetSize(out long iniSize);
if (rc.IsFailure()) return rc;
if (iniSize < Unsafe.SizeOf())
return ResultLibHac.InvalidIniFileSize.Log();
// Read the INI file header and validate some of its values.
- rc = binaryStorage.Read(0, SpanHelpers.AsByteSpan(ref _header));
+ rc = binaryStorage.Get.Read(0, SpanHelpers.AsByteSpan(ref _header));
if (rc.IsFailure()) return rc;
if (_header.Magic != ExpectedMagic)
@@ -45,36 +51,40 @@ namespace LibHac.Kernel
rc = GetKipOffsets(out _offsets, binaryStorage, _header.ProcessCount);
if (rc.IsFailure()) return rc;
- _storage = binaryStorage;
+ _storage.SetByCopy(in binaryStorage);
return Result.Success;
}
- public Result OpenKipStorage(out IStorage storage, int index)
+ public Result OpenKipStorage(ref UniqueRef outStorage, int index)
{
- UnsafeHelpers.SkipParamInit(out storage);
-
if ((uint)index >= _header.ProcessCount)
return ResultLibHac.ArgumentOutOfRange.Log();
(int offset, int size) range = _offsets[index];
- storage = new SubStorage(_storage, range.offset, range.size);
+ outStorage.Reset(new SubStorage(in _storage, range.offset, range.size));
return Result.Success;
}
- private static Result GetKipOffsets(out (int offset, int size)[] kipOffsets, IStorage iniStorage,
+ private static Result GetKipOffsets(out (int offset, int size)[] kipOffsets, in SharedRef iniStorage,
int processCount)
{
Assert.SdkRequiresLessEqual(processCount, MaxProcessCount);
UnsafeHelpers.SkipParamInit(out kipOffsets);
+ Result rc = iniStorage.Get.GetSize(out long iniStorageSize);
+ if (rc.IsFailure()) return rc.Miss();
+
var offsets = new (int offset, int size)[processCount];
int offset = Unsafe.SizeOf();
- var kipReader = new KipReader();
+ using var kipReader = new KipReader();
for (int i = 0; i < processCount; i++)
{
- Result rc = kipReader.Initialize(new SubStorage(iniStorage, offset, int.MaxValue));
+ using var kipStorage =
+ new SharedRef(new SubStorage(in iniStorage, offset, iniStorageSize - offset));
+
+ rc = kipReader.Initialize(in kipStorage);
if (rc.IsFailure()) return rc;
int kipSize = kipReader.GetFileSize();
diff --git a/src/LibHac/Kernel/KipReader.cs b/src/LibHac/Kernel/KipReader.cs
index a7d2b693..78df5080 100644
--- a/src/LibHac/Kernel/KipReader.cs
+++ b/src/LibHac/Kernel/KipReader.cs
@@ -8,9 +8,9 @@ using LibHac.Fs;
namespace LibHac.Kernel
{
- public class KipReader
+ public class KipReader : IDisposable
{
- private IStorage KipStorage { get; set; }
+ private SharedRef _kipStorage;
private KipHeader _header;
@@ -34,48 +34,51 @@ namespace LibHac.Kernel
public int AffinityMask => _header.AffinityMask;
public int StackSize => _header.StackSize;
- public Result Initialize(IStorage kipData)
+ public void Dispose()
{
- if (kipData is null)
+ _kipStorage.Destroy();
+ }
+
+ public Result Initialize(in SharedRef kipData)
+ {
+ if (!kipData.HasValue)
return ResultLibHac.NullArgument.Log();
// Verify there's enough data to read the header
- Result rc = kipData.GetSize(out long kipSize);
+ Result rc = kipData.Get.GetSize(out long kipSize);
if (rc.IsFailure()) return rc;
if (kipSize < Unsafe.SizeOf())
return ResultLibHac.InvalidKipFileSize.Log();
- rc = kipData.Read(0, SpanHelpers.AsByteSpan(ref _header));
+ rc = kipData.Get.Read(0, SpanHelpers.AsByteSpan(ref _header));
if (rc.IsFailure()) return rc;
if (!_header.IsValid)
return ResultLibHac.InvalidKipMagic.Log();
- KipStorage = kipData;
+ _kipStorage.SetByCopy(in kipData);
return Result.Success;
}
///
/// Gets the raw input KIP file.
///
- /// If the operation returns successfully, an
+ /// If the operation returns successfully, an
/// containing the KIP data.
/// The of the operation.
- public Result GetRawData(out IStorage kipData)
+ public Result GetRawData(ref UniqueRef outKipData)
{
- UnsafeHelpers.SkipParamInit(out kipData);
-
int kipFileSize = GetFileSize();
- Result rc = KipStorage.GetSize(out long inputFileSize);
+ Result rc = _kipStorage.Get.GetSize(out long inputFileSize);
if (rc.IsFailure()) return rc;
// Verify the input KIP file isn't truncated
if (inputFileSize < kipFileSize)
return ResultLibHac.InvalidKipFileSize.Log();
- kipData = new SubStorage(KipStorage, 0, kipFileSize);
+ outKipData.Reset(new SubStorage(in _kipStorage, 0, kipFileSize));
return Result.Success;
}
@@ -149,14 +152,14 @@ namespace LibHac.Kernel
int offset = CalculateSegmentOffset((int)segment);
// Verify the segment offset is in-range
- rc = KipStorage.GetSize(out long kipSize);
+ rc = _kipStorage.Get.GetSize(out long kipSize);
if (rc.IsFailure()) return rc;
if (kipSize < offset + segmentHeader.FileSize)
return ResultLibHac.InvalidKipFileSize.Log();
// Read the segment data.
- rc = KipStorage.Read(offset, buffer.Slice(0, segmentHeader.FileSize));
+ rc = _kipStorage.Get.Read(offset, buffer.Slice(0, segmentHeader.FileSize));
if (rc.IsFailure()) return rc;
// Decompress if necessary.
diff --git a/src/LibHac/Kip.cs b/src/LibHac/Kip.cs
index c021679a..5d06fe72 100644
--- a/src/LibHac/Kip.cs
+++ b/src/LibHac/Kip.cs
@@ -1,5 +1,6 @@
using System;
using System.IO;
+using LibHac.Common;
using LibHac.Fs;
using LibHac.FsSystem;
using LibHac.Kernel;
@@ -200,8 +201,10 @@ namespace LibHac
for (int i = 0; i < KipCount; i++)
{
+ using var sharedStorage = new SharedRef(Storage.Slice(offset));
+
Kips[i] = new KipReader();
- Kips[i].Initialize(Storage.Slice(offset)).ThrowIfFailure();
+ Kips[i].Initialize(in sharedStorage).ThrowIfFailure();
offset += Kips[i].GetFileSize();
}
diff --git a/src/hactoolnet/ProcessKip.cs b/src/hactoolnet/ProcessKip.cs
index 3cc9aa5b..b7ba88fe 100644
--- a/src/hactoolnet/ProcessKip.cs
+++ b/src/hactoolnet/ProcessKip.cs
@@ -1,4 +1,5 @@
using System.IO;
+using LibHac.Common;
using LibHac.Fs;
using LibHac.FsSystem;
using LibHac.Kernel;
@@ -9,50 +10,50 @@ namespace hactoolnet
{
public static void ProcessKip1(Context ctx)
{
- using (var file = new LocalStorage(ctx.Options.InFile, FileAccess.Read))
+ using var file = new SharedRef(new LocalStorage(ctx.Options.InFile, FileAccess.Read));
+
+ using var kip = new KipReader();
+ kip.Initialize(in file).ThrowIfFailure();
+
+ if (!string.IsNullOrWhiteSpace(ctx.Options.UncompressedOut))
{
- var kip = new KipReader();
- kip.Initialize(file).ThrowIfFailure();
+ byte[] uncompressed = new byte[kip.GetUncompressedSize()];
- if (!string.IsNullOrWhiteSpace(ctx.Options.UncompressedOut))
- {
- byte[] uncompressed = new byte[kip.GetUncompressedSize()];
+ kip.ReadUncompressedKip(uncompressed).ThrowIfFailure();
- kip.ReadUncompressedKip(uncompressed).ThrowIfFailure();
-
- File.WriteAllBytes(ctx.Options.UncompressedOut, uncompressed);
- }
+ File.WriteAllBytes(ctx.Options.UncompressedOut, uncompressed);
}
}
public static void ProcessIni1(Context ctx)
{
- using (var file = new LocalStorage(ctx.Options.InFile, FileAccess.Read))
- {
- string outDir = ctx.Options.OutDir;
+ using var file = new SharedRef(new LocalStorage(ctx.Options.InFile, FileAccess.Read));
- if (outDir != null)
- {
- ExtractIni1(file, outDir);
- }
+ string outDir = ctx.Options.OutDir;
+
+ if (outDir != null)
+ {
+ ExtractIni1(in file, outDir);
}
}
- public static void ExtractIni1(IStorage iniStorage, string outDir)
+ public static void ExtractIni1(in SharedRef iniStorage, string outDir)
{
- var ini1 = new InitialProcessBinaryReader();
+ using var ini1 = new InitialProcessBinaryReader();
ini1.Initialize(iniStorage).ThrowIfFailure();
Directory.CreateDirectory(outDir);
- var kipReader = new KipReader();
+ using var kipReader = new KipReader();
for (int i = 0; i < ini1.ProcessCount; i++)
{
- ini1.OpenKipStorage(out IStorage kipStorage, i).ThrowIfFailure();
+ using var kipStorage = new UniqueRef();
+ ini1.OpenKipStorage(ref kipStorage.Ref(), i).ThrowIfFailure();
- kipReader.Initialize(kipStorage).ThrowIfFailure();
+ using SharedRef sharedKipStorage = SharedRef.Create(ref kipStorage.Ref());
+ kipReader.Initialize(in sharedKipStorage).ThrowIfFailure();
- kipStorage.WriteAllBytes(System.IO.Path.Combine(outDir, $"{kipReader.Name.ToString()}.kip1"));
+ sharedKipStorage.Get.WriteAllBytes(System.IO.Path.Combine(outDir, $"{kipReader.Name.ToString()}.kip1"));
}
}
}
diff --git a/src/hactoolnet/ProcessPackage.cs b/src/hactoolnet/ProcessPackage.cs
index ceefaff4..b1cb7515 100644
--- a/src/hactoolnet/ProcessPackage.cs
+++ b/src/hactoolnet/ProcessPackage.cs
@@ -15,43 +15,42 @@ namespace hactoolnet
{
public static void ProcessPk11(Context ctx)
{
- using (var file = new SharedRef(new LocalStorage(ctx.Options.InFile, FileAccess.Read)))
+ using var file = new SharedRef(new LocalStorage(ctx.Options.InFile, FileAccess.Read));
+
+ var package1 = new LibHac.Boot.Package1();
+ package1.Initialize(ctx.KeySet, in file).ThrowIfFailure();
+
+ ctx.Logger.LogMessage(package1.Print());
+
+ string outDir = ctx.Options.OutDir;
+
+ if (package1.IsDecrypted && outDir != null)
{
- var package1 = new LibHac.Boot.Package1();
- package1.Initialize(ctx.KeySet, in file).ThrowIfFailure();
+ Directory.CreateDirectory(outDir);
- ctx.Logger.LogMessage(package1.Print());
+ IStorage decryptedStorage = package1.OpenDecryptedPackage1Storage();
- string outDir = ctx.Options.OutDir;
+ WriteFile(decryptedStorage, "Decrypted.bin");
+ WriteFile(package1.OpenWarmBootStorage(), "Warmboot.bin");
+ WriteFile(package1.OpenNxBootloaderStorage(), "NX_Bootloader.bin");
+ WriteFile(package1.OpenSecureMonitorStorage(), "Secure_Monitor.bin");
- if (package1.IsDecrypted && outDir != null)
+ if (package1.IsMariko)
{
- Directory.CreateDirectory(outDir);
+ WriteFile(package1.OpenDecryptedWarmBootStorage(), "Warmboot_Decrypted.bin");
- IStorage decryptedStorage = package1.OpenDecryptedPackage1Storage();
+ var marikoOemLoader = new SubStorage(decryptedStorage, Unsafe.SizeOf(),
+ package1.MarikoOemHeader.Size);
- WriteFile(decryptedStorage, "Decrypted.bin");
- WriteFile(package1.OpenWarmBootStorage(), "Warmboot.bin");
- WriteFile(package1.OpenNxBootloaderStorage(), "NX_Bootloader.bin");
- WriteFile(package1.OpenSecureMonitorStorage(), "Secure_Monitor.bin");
-
- if (package1.IsMariko)
- {
- WriteFile(package1.OpenDecryptedWarmBootStorage(), "Warmboot_Decrypted.bin");
-
- var marikoOemLoader = new SubStorage(decryptedStorage, Unsafe.SizeOf(),
- package1.MarikoOemHeader.Size);
-
- WriteFile(marikoOemLoader, "Mariko_OEM_Bootloader.bin");
- }
+ WriteFile(marikoOemLoader, "Mariko_OEM_Bootloader.bin");
}
+ }
- void WriteFile(IStorage storage, string filename)
- {
- string path = Path.Combine(outDir, filename);
- ctx.Logger.LogMessage($"Writing {path}...");
- storage.WriteAllBytes(path, ctx.Logger);
- }
+ void WriteFile(IStorage storage, string filename)
+ {
+ string path = Path.Combine(outDir, filename);
+ ctx.Logger.LogMessage($"Writing {path}...");
+ storage.WriteAllBytes(path, ctx.Logger);
}
}
@@ -105,43 +104,47 @@ namespace hactoolnet
public static void ProcessPk21(Context ctx)
{
- using (var file = new CachedStorage(new LocalStorage(ctx.Options.InFile, FileAccess.Read), 0x4000, 4, false))
+ using var file = new SharedRef(new CachedStorage(new LocalStorage(ctx.Options.InFile, FileAccess.Read), 0x4000, 4, false));
+
+ using var package2 = new Package2StorageReader();
+ package2.Initialize(ctx.KeySet, in file).ThrowIfFailure();
+
+ ctx.Logger.LogMessage(package2.Print());
+
+ string outDir = ctx.Options.OutDir;
+ string iniDir = ctx.Options.Ini1OutDir;
+
+ if (iniDir == null && ctx.Options.ExtractIni1)
{
- var package2 = new Package2StorageReader();
- package2.Initialize(ctx.KeySet, file).ThrowIfFailure();
+ iniDir = Path.Combine(outDir, "INI1");
+ }
- ctx.Logger.LogMessage(package2.Print());
+ if (outDir != null)
+ {
+ Directory.CreateDirectory(outDir);
- string outDir = ctx.Options.OutDir;
- string iniDir = ctx.Options.Ini1OutDir;
+ using var kernelStorage = new UniqueRef();
+ package2.OpenPayload(ref kernelStorage.Ref(), 0).ThrowIfFailure();
+ kernelStorage.Get.WriteAllBytes(Path.Combine(outDir, "Kernel.bin"), ctx.Logger);
- if (iniDir == null && ctx.Options.ExtractIni1)
- {
- iniDir = Path.Combine(outDir, "INI1");
- }
+ using var ini1Storage = new UniqueRef();
+ package2.OpenIni(ref ini1Storage.Ref()).ThrowIfFailure();
+ ini1Storage.Get.WriteAllBytes(Path.Combine(outDir, "INI1.bin"), ctx.Logger);
- if (outDir != null)
- {
- Directory.CreateDirectory(outDir);
+ using var decPackageStorage = new UniqueRef();
+ package2.OpenDecryptedPackage(ref decPackageStorage.Ref()).ThrowIfFailure();
+ decPackageStorage.Get.WriteAllBytes(Path.Combine(outDir, "Decrypted.bin"), ctx.Logger);
+ }
- package2.OpenPayload(out IStorage kernelStorage, 0).ThrowIfFailure();
- kernelStorage.WriteAllBytes(Path.Combine(outDir, "Kernel.bin"), ctx.Logger);
+ if (iniDir != null)
+ {
+ Directory.CreateDirectory(iniDir);
- package2.OpenIni(out IStorage ini1Storage).ThrowIfFailure();
- ini1Storage.WriteAllBytes(Path.Combine(outDir, "INI1.bin"), ctx.Logger);
+ using var ini1Storage = new UniqueRef();
+ package2.OpenIni(ref ini1Storage.Ref()).ThrowIfFailure();
- package2.OpenDecryptedPackage(out IStorage decPackageStorage).ThrowIfFailure();
- decPackageStorage.WriteAllBytes(Path.Combine(outDir, "Decrypted.bin"), ctx.Logger);
- }
-
- if (iniDir != null)
- {
- Directory.CreateDirectory(iniDir);
-
- package2.OpenIni(out IStorage ini1Storage).ThrowIfFailure();
-
- ProcessKip.ExtractIni1(ini1Storage, iniDir);
- }
+ using SharedRef sharedIni1Storage = SharedRef.Create(ref ini1Storage.Ref());
+ ProcessKip.ExtractIni1(in sharedIni1Storage, iniDir);
}
}