Skip to content

Commit

Permalink
Finish implementing the UFS/UFS2 file system image readonly support f…
Browse files Browse the repository at this point in the history
…or NanaZip.Codecs.
  • Loading branch information
MouriNaruto committed Jan 31, 2025
1 parent 88792be commit 6bd854e
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 32 deletions.
61 changes: 29 additions & 32 deletions NanaZip.Codecs/NanaZip.Codecs.Archive.Ufs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,13 @@ namespace
std::string EmbeddedSymbolLink;
std::vector<std::uint64_t> BlockOffsets;
};

struct UfsFilePathInformation
{
std::string Path;
std::uint32_t Inode;
UfsInodeInformation Information;
};
}

namespace NanaZip::Codecs::Archive
Expand All @@ -128,7 +135,7 @@ namespace NanaZip::Codecs::Archive
bool m_IsBigEndian = false;
fs m_SuperBlock = { 0 };
std::map<std::string, std::uint32_t> m_TemporaryFilePaths;
std::vector<std::pair<std::string, std::uint32_t>> m_FilePaths;
std::vector<UfsFilePathInformation> m_FilePaths;
bool m_IsInitialized = false;

private:
Expand Down Expand Up @@ -660,7 +667,7 @@ namespace NanaZip::Codecs::Archive
return E_INVALIDARG;
}

HRESULT hr = S_OK;
HRESULT hr = S_FALSE;

do
{
Expand All @@ -671,11 +678,10 @@ namespace NanaZip::Codecs::Archive

for (size_t i = 0; -1 != g_SuperBlockSearchList[i]; ++i)
{
hr = this->ReadFileStream(
if (FAILED(this->ReadFileStream(
g_SuperBlockSearchList[i],
&this->m_SuperBlock,
sizeof(this->m_SuperBlock));
if (FAILED(hr))
sizeof(this->m_SuperBlock))))
{
break;
}
Expand Down Expand Up @@ -706,7 +712,6 @@ namespace NanaZip::Codecs::Archive
}
else
{
hr = S_FALSE;
continue;
}
}
Expand All @@ -717,7 +722,6 @@ namespace NanaZip::Codecs::Archive
{
if (SBLOCK_UFS2 != SuperBlockLocation)
{
hr = S_FALSE;
continue;
}
}
Expand All @@ -726,7 +730,6 @@ namespace NanaZip::Codecs::Archive
if (SuperBlockLocation < 0 ||
SuperBlockLocation > SBLOCK_UFS1)
{
hr = S_FALSE;
continue;
}
}
Expand All @@ -735,23 +738,20 @@ namespace NanaZip::Codecs::Archive
&this->m_SuperBlock.fs_frag);
if (FragmentsCount < 1)
{
hr = S_FALSE;
continue;
}

std::uint32_t CylinderGroupsCount = this->ReadUInt32(
&this->m_SuperBlock.fs_ncg);
if (CylinderGroupsCount < 1)
{
hr = S_FALSE;
continue;
}

std::int32_t BlockSize = this->ReadInt32(
&this->m_SuperBlock.fs_bsize);
if (BlockSize < MINBSIZE)
{
hr = S_FALSE;
continue;
}

Expand All @@ -760,14 +760,13 @@ namespace NanaZip::Codecs::Archive
if (SuperBlockSize > SBLOCKSIZE ||
SuperBlockSize < sizeof(fs))
{
hr = S_FALSE;
continue;
}

hr = S_OK;
break;
}
if (FAILED(hr))
if (S_OK != hr)
{
break;
}
Expand All @@ -792,7 +791,16 @@ namespace NanaZip::Codecs::Archive
this->m_FilePaths.clear();
for (auto const& Item : this->m_TemporaryFilePaths)
{
this->m_FilePaths.emplace_back(Item.first, Item.second);
UfsFilePathInformation Current;
Current.Path = Item.first;
Current.Inode = Item.second;
if (!this->GetInodeInformation(
Current.Inode,
Current.Information))
{
continue;
}
this->m_FilePaths.emplace_back(Current);
}
this->m_TemporaryFilePaths.clear();

Expand Down Expand Up @@ -857,21 +865,16 @@ namespace NanaZip::Codecs::Archive
return E_INVALIDARG;
}

UfsInodeInformation Information;
if (!this->GetInodeInformation(
this->m_FilePaths[Index].second,
Information))
{
return S_FALSE;
}
UfsInodeInformation& Information =
this->m_FilePaths[Index].Information;

switch (PropId)
{
case SevenZipArchivePath:
{
Value->bstrVal = ::SysAllocString(Mile::ToWideString(
CP_UTF8,
this->m_FilePaths[Index].first).c_str());
this->m_FilePaths[Index].Path).c_str());
if (Value->bstrVal)
{
Value->vt = VT_BSTR;
Expand Down Expand Up @@ -992,7 +995,7 @@ namespace NanaZip::Codecs::Archive
}
case SevenZipArchiveInode:
{
Value->uhVal.QuadPart = this->m_FilePaths[Index].second;
Value->uhVal.QuadPart = this->m_FilePaths[Index].Inode;
Value->vt = VT_UI8;
break;
}
Expand Down Expand Up @@ -1047,15 +1050,9 @@ namespace NanaZip::Codecs::Archive

for (UINT32 i = 0; i < NumItems; ++i)
{
UfsInodeInformation Information;
if (!this->GetInodeInformation(
this->m_FilePaths[AllFilesMode ? i : Indices[i]].second,
Information))
{
ExtractCallback->SetOperationResult(
SevenZipExtractOperationResultUnavailable);
continue;
}
UINT32 ActualFileIndex = AllFilesMode ? i : Indices[i];
UfsInodeInformation& Information =
this->m_FilePaths[ActualFileIndex].Information;

Completed += Information.FileSize;
ExtractCallback->SetCompleted(&Completed);
Expand Down
1 change: 1 addition & 0 deletions ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ Kenji Mouri
- Zstandard (Decoder inherited from 7-Zip, Encoder & Archiver inherited from
7-Zip ZS)
- NSIS (Decoder's NSIS script decompiling support, inherited from 7-Zip NSIS)
- UFS/UFS2 file system image (Archiver, read-only, both big and little endian)
- Provide additional security mitigations.
- Enable Control Flow Guard (CFG) to all target binaries for mitigating ROP
attacks.
Expand Down

0 comments on commit 6bd854e

Please sign in to comment.