From d730e8c2edc8f86d66a6dad26d8fca9bac05d220 Mon Sep 17 00:00:00 2001 From: Richard Huveneers Date: Mon, 7 Jun 2021 21:01:04 +0200 Subject: [PATCH] Implemented IOCTL_GET_APFS_INFO ioctl --- ufs/ufsd/src/apfs/apfs.cpp | 34 ++++++++++++++++++++++++++++++++++ ufs/ufsd/src/apfs/apfs.h | 6 +++--- ufs/ufsd/src/unixfs/unixfs.cpp | 23 ++++++++++++++++------- 3 files changed, 53 insertions(+), 10 deletions(-) diff --git a/ufs/ufsd/src/apfs/apfs.cpp b/ufs/ufsd/src/apfs/apfs.cpp index 9e663e9..621f6e1 100644 --- a/ufs/ufsd/src/apfs/apfs.cpp +++ b/ufs/ufsd/src/apfs/apfs.cpp @@ -220,6 +220,40 @@ int CApfsFileSystem::ReInit( return CUnixFileSystem::ReInit( Options, Flags, Params ); } +int CApfsFileSystem::OnGetApfsInfo() +{ + size_t BytesReturned = 0; + struct UFSD_VOLUME_APFS_INFO *info = (struct UFSD_VOLUME_APFS_INFO *) m_IO.OutBuffer; + for (unsigned int Idx = 0; Idx < m_pApfsSuper->GetMountedVolumesCount(); Idx++) { + if (BytesReturned + sizeof(struct UFSD_VOLUME_APFS_INFO) > m_IO.OutBufferSize) + { + if (m_IO.BytesReturned) + *m_IO.BytesReturned = BytesReturned; + return Idx ? ERR_MORE_DATA : ERR_INSUFFICIENT_BUFFER; + } + CApfsVolumeSb *vol = m_pApfsSuper->GetVolume(Idx); + apfs_vsb *volSb = vol->GetVolumeSb(); + info[Idx] = { + .BlocksUsed = volSb->vsb_blocks_used, + .BlocksReserved = volSb->vsb_blocks_reserved, + .FilesCount = volSb->vsb_files_count, + .DirsCount = volSb->vsb_dirs_count, + .SymlinksCount = volSb->vsb_symlinks_count, + .SpecFilesCount = volSb->vsb_spec_files_count, + .SnapshotsCount = volSb->vsb_snapshots_count, + .Index = Idx, + .Encrypted = vol->IsEncrypted(), + .CaseSensitive = vol->IsCaseSensitive() + }; + Memcpy2(info[Idx].SerialNumber, volSb->vsb_uuid, 0x10); + Memcpy2(info[Idx].VolumeName, volSb->vsb_volname, 0x100); + info[Idx].Creator[0] = '\0'; + BytesReturned += sizeof(struct UFSD_VOLUME_APFS_INFO); + } + if (m_IO.BytesReturned) + *m_IO.BytesReturned = BytesReturned; + return ERR_NOERROR; +} #ifdef UFSD_APFS_RO ///////////////////////////////////////////////////////////////////////////// diff --git a/ufs/ufsd/src/apfs/apfs.h b/ufs/ufsd/src/apfs/apfs.h index 211fd1c..7db95a5 100644 --- a/ufs/ufsd/src/apfs/apfs.h +++ b/ufs/ufsd/src/apfs/apfs.h @@ -126,14 +126,14 @@ class CApfsFileSystem : public CUnixFileSystem // Find cluster with the last checkpoint superblock int FindCSBBlock(const apfs_sb* pMSB, UINT64& Block) const; + // Handler for IOCTL_GET_APFS_INFO + virtual int OnGetApfsInfo(); + #ifndef UFSD_APFS_RO //================================================================= // APFS I/O handlers //================================================================= - // Handler for IOCTL_GET_APFS_INFO - virtual int OnGetApfsInfo(); - // Handler for IOCTL_GET_RETRIEVAL_POINTERS2 virtual int OnGetRetrievalPointers(); diff --git a/ufs/ufsd/src/unixfs/unixfs.cpp b/ufs/ufsd/src/unixfs/unixfs.cpp index ec66741..9325638 100644 --- a/ufs/ufsd/src/unixfs/unixfs.cpp +++ b/ufs/ufsd/src/unixfs/unixfs.cpp @@ -241,15 +241,24 @@ int CUnixFileSystem::SetVolumeInfo( } int CUnixFileSystem::IoControl( - IN size_t , - IN const void* , - IN size_t , - OUT void* , - IN size_t , - OUT size_t* + IN size_t FsIoControlCode, + IN const void* InBuffer, + IN size_t InBufferSize, + OUT void* OutBuffer, + IN size_t OutBufferSize, + OUT size_t* BytesReturned ) { - return ERR_NOTIMPLEMENTED; + m_IO.InBuffer = InBuffer; + m_IO.InBufferSize = InBufferSize; + m_IO.OutBuffer = OutBuffer; + m_IO.OutBufferSize = OutBufferSize; + m_IO.BytesReturned = BytesReturned; + switch (FsIoControlCode) { + case IOCTL_GET_APFS_INFO: + return OnGetApfsInfo(); + } + return ERR_NOTIMPLEMENTED; } int CUnixFileSystem::OnGetRetrievalPointers() { return ERR_NOTIMPLEMENTED; }