mirror of
https://github.com/fadden/ciderpress.git
synced 2024-11-05 16:05:02 +00:00
442 lines
13 KiB
C++
442 lines
13 KiB
C++
/*
|
|
* CiderPress
|
|
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
|
|
* See the file LICENSE for distribution terms.
|
|
*/
|
|
/*
|
|
* Implementation of the various ArchiveInfo dialog classes.
|
|
*/
|
|
#include "StdAfx.h"
|
|
#include "HelpTopics.h"
|
|
#include "ArchiveInfoDialog.h"
|
|
#include "../nufxlib/NufxLib.h"
|
|
|
|
/*
|
|
* ===========================================================================
|
|
* ArchiveInfoDialog
|
|
* ===========================================================================
|
|
*/
|
|
|
|
BEGIN_MESSAGE_MAP(ArchiveInfoDialog, CDialog)
|
|
ON_COMMAND(IDHELP, OnHelp)
|
|
END_MESSAGE_MAP()
|
|
|
|
/*
|
|
* Show general help for the archive info dialogs.
|
|
*/
|
|
void
|
|
ArchiveInfoDialog::OnHelp(void)
|
|
{
|
|
WinHelp(HELP_TOPIC_ARCHIVE_INFO, HELP_CONTEXT);
|
|
}
|
|
|
|
|
|
/*
|
|
* ===========================================================================
|
|
* NufxArchiveInfoDialog
|
|
* ===========================================================================
|
|
*/
|
|
|
|
/*
|
|
* Set up fields with NuFX archive info.
|
|
*/
|
|
BOOL
|
|
NufxArchiveInfoDialog::OnInitDialog(void)
|
|
{
|
|
CString notAvailable = "(not available)";
|
|
NuArchive* pNuArchive;
|
|
const NuMasterHeader* pMasterHeader;
|
|
CWnd* pWnd;
|
|
CString tmpStr;
|
|
NuAttr attr;
|
|
NuError nerr;
|
|
time_t when;
|
|
|
|
ASSERT(fpArchive != NULL);
|
|
|
|
pNuArchive = fpArchive->GetNuArchivePointer();
|
|
ASSERT(pNuArchive != NULL);
|
|
(void) NuGetMasterHeader(pNuArchive, &pMasterHeader);
|
|
ASSERT(pMasterHeader != NULL);
|
|
|
|
pWnd = GetDlgItem(IDC_AI_FILENAME);
|
|
CString pathName(fpArchive->GetPathName());
|
|
pWnd->SetWindowText(pathName);
|
|
|
|
pWnd = GetDlgItem(IDC_AINUFX_RECORDS);
|
|
nerr = NuGetAttr(pNuArchive, kNuAttrNumRecords, &attr);
|
|
if (nerr == kNuErrNone)
|
|
tmpStr.Format(L"%ld", attr);
|
|
else
|
|
tmpStr = notAvailable;
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
pWnd = GetDlgItem(IDC_AINUFX_FORMAT);
|
|
nerr = NuGetAttr(pNuArchive, kNuAttrArchiveType, &attr);
|
|
switch (attr) {
|
|
case kNuArchiveNuFX: tmpStr = L"NuFX"; break;
|
|
case kNuArchiveNuFXInBNY: tmpStr = L"NuFX in Binary II"; break;
|
|
case kNuArchiveNuFXSelfEx: tmpStr = L"Self-extracting NuFX"; break;
|
|
case kNuArchiveNuFXSelfExInBNY: tmpStr = L"Self-extracting NuFX in Binary II";
|
|
break;
|
|
case kNuArchiveBNY: tmpStr = L"Binary II"; break;
|
|
default:
|
|
tmpStr = L"(unknown)";
|
|
break;
|
|
};
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
pWnd = GetDlgItem(IDC_AINUFX_MASTERVERSION);
|
|
tmpStr.Format(L"%ld", pMasterHeader->mhMasterVersion);
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
pWnd = GetDlgItem(IDC_AINUFX_CREATEWHEN);
|
|
when = NufxArchive::DateTimeToSeconds(&pMasterHeader->mhArchiveCreateWhen);
|
|
tmpStr.Format(L"%.24hs", ctime(&when));
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
pWnd = GetDlgItem(IDC_AINUFX_MODIFYWHEN);
|
|
when = NufxArchive::DateTimeToSeconds(&pMasterHeader->mhArchiveModWhen);
|
|
tmpStr.Format(L"%.24hs", ctime(&when));
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
pWnd = GetDlgItem(IDC_AINUFX_JUNKSKIPPED);
|
|
nerr = NuGetAttr(pNuArchive, kNuAttrJunkOffset, &attr);
|
|
if (nerr == kNuErrNone)
|
|
tmpStr.Format(L"%ld bytes", attr);
|
|
else
|
|
tmpStr = notAvailable;
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
return ArchiveInfoDialog::OnInitDialog();
|
|
}
|
|
|
|
|
|
/*
|
|
* ===========================================================================
|
|
* DiskArchiveInfoDialog
|
|
* ===========================================================================
|
|
*/
|
|
|
|
BEGIN_MESSAGE_MAP(DiskArchiveInfoDialog, ArchiveInfoDialog)
|
|
ON_CBN_SELCHANGE(IDC_AIDISK_SUBVOLSEL, OnSubVolSelChange)
|
|
END_MESSAGE_MAP()
|
|
|
|
/*
|
|
* Set up fields with disk archive info.
|
|
*/
|
|
BOOL
|
|
DiskArchiveInfoDialog::OnInitDialog(void)
|
|
{
|
|
CWnd* pWnd;
|
|
CString tmpStr;
|
|
const DiskImg* pDiskImg;
|
|
const DiskFS* pDiskFS;
|
|
|
|
ASSERT(fpArchive != NULL);
|
|
|
|
pDiskImg = fpArchive->GetDiskImg();
|
|
ASSERT(pDiskImg != NULL);
|
|
pDiskFS = fpArchive->GetDiskFS();
|
|
ASSERT(pDiskFS != NULL);
|
|
|
|
/*
|
|
* Volume characteristics.
|
|
*/
|
|
pWnd = GetDlgItem(IDC_AI_FILENAME);
|
|
pWnd->SetWindowText(fpArchive->GetPathName());
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_OUTERFORMAT);
|
|
CStringW outerFormat(DiskImg::ToString(pDiskImg->GetOuterFormat()));
|
|
pWnd->SetWindowText(outerFormat);
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_FILEFORMAT);
|
|
CStringW fileFormat(DiskImg::ToString(pDiskImg->GetFileFormat()));
|
|
pWnd->SetWindowText(fileFormat);
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_PHYSICALFORMAT);
|
|
DiskImg::PhysicalFormat physicalFormat = pDiskImg->GetPhysicalFormat();
|
|
if (physicalFormat == DiskImg::kPhysicalFormatNib525_6656 ||
|
|
physicalFormat == DiskImg::kPhysicalFormatNib525_6384 ||
|
|
physicalFormat == DiskImg::kPhysicalFormatNib525_Var)
|
|
{
|
|
CString tmpStr;
|
|
const DiskImg::NibbleDescr* pNibbleDescr = pDiskImg->GetNibbleDescr();
|
|
if (pNibbleDescr != NULL)
|
|
tmpStr.Format(L"%hs, layout is \"%hs\"",
|
|
DiskImg::ToString(physicalFormat), pNibbleDescr->description);
|
|
else
|
|
tmpStr = DiskImg::ToString(physicalFormat); // unexpected
|
|
pWnd->SetWindowText(tmpStr);
|
|
} else {
|
|
CString physicalFormat(DiskImg::ToString(physicalFormat));
|
|
pWnd->SetWindowText(physicalFormat);
|
|
}
|
|
|
|
FillInVolumeInfo(pDiskFS);
|
|
|
|
/*
|
|
* Configure the sub-volume drop down menu. If there's only one item,
|
|
* we disable it.
|
|
*/
|
|
CComboBox* pCombo = (CComboBox*) GetDlgItem(IDC_AIDISK_SUBVOLSEL);
|
|
int idx = 0;
|
|
|
|
AddSubVolumes(pDiskFS, L"", &idx);
|
|
ASSERT(idx > 0); // must have at least the top-level DiskFS
|
|
|
|
pCombo->SetCurSel(0);
|
|
if (idx == 1)
|
|
pCombo->EnableWindow(FALSE);
|
|
|
|
return ArchiveInfoDialog::OnInitDialog();
|
|
}
|
|
|
|
/*
|
|
* Recursively add sub-volumes to the list.
|
|
*/
|
|
void
|
|
DiskArchiveInfoDialog::AddSubVolumes(const DiskFS* pDiskFS, const WCHAR* prefix,
|
|
int* pIdx)
|
|
{
|
|
CComboBox* pCombo = (CComboBox*) GetDlgItem(IDC_AIDISK_SUBVOLSEL);
|
|
CString tmpStr;
|
|
|
|
/*
|
|
* Add the current DiskFS.
|
|
*/
|
|
tmpStr = prefix;
|
|
tmpStr += pDiskFS->GetVolumeID();
|
|
pCombo->AddString(tmpStr);
|
|
pCombo->SetItemData(*pIdx, (unsigned long) pDiskFS);
|
|
(*pIdx)++;
|
|
|
|
/*
|
|
* Add everything beneath the current level.
|
|
*/
|
|
DiskFS::SubVolume* pSubVol;
|
|
pSubVol = pDiskFS->GetNextSubVolume(NULL);
|
|
tmpStr = prefix;
|
|
tmpStr += L" ";
|
|
while (pSubVol != NULL) {
|
|
AddSubVolumes(pSubVol->GetDiskFS(), tmpStr, pIdx);
|
|
|
|
pSubVol = pDiskFS->GetNextSubVolume(pSubVol);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* The user has changed their selection in the sub-volume pulldown menu.
|
|
*/
|
|
void
|
|
DiskArchiveInfoDialog::OnSubVolSelChange(void)
|
|
{
|
|
CComboBox* pCombo = (CComboBox*) GetDlgItem(IDC_AIDISK_SUBVOLSEL);
|
|
ASSERT(pCombo != NULL);
|
|
//WMSG1("+++ SELECTION IS NOW %d\n", pCombo->GetCurSel());
|
|
|
|
const DiskFS* pDiskFS;
|
|
pDiskFS = (DiskFS*) pCombo->GetItemData(pCombo->GetCurSel());
|
|
ASSERT(pDiskFS != NULL);
|
|
FillInVolumeInfo(pDiskFS);
|
|
}
|
|
|
|
/*
|
|
* Fill in the volume-specific info fields.
|
|
*/
|
|
void
|
|
DiskArchiveInfoDialog::FillInVolumeInfo(const DiskFS* pDiskFS)
|
|
{
|
|
const DiskImg* pDiskImg = pDiskFS->GetDiskImg();
|
|
CString unknown = L"(unknown)";
|
|
CString tmpStr;
|
|
DIError dierr;
|
|
CWnd* pWnd;
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_SECTORORDER);
|
|
CStringW sectorOrderW(DiskImg::ToString(pDiskImg->GetSectorOrder()));
|
|
pWnd->SetWindowText(sectorOrderW);
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_FSFORMAT);
|
|
CStringW fsFormat(DiskImg::ToString(pDiskImg->GetFSFormat()));
|
|
pWnd->SetWindowText(fsFormat);
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_FILECOUNT);
|
|
tmpStr.Format(L"%ld", pDiskFS->GetFileCount());
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
long totalUnits, freeUnits;
|
|
int unitSize;
|
|
CString reducedSize;
|
|
|
|
dierr = pDiskFS->GetFreeSpaceCount(&totalUnits, &freeUnits, &unitSize);
|
|
if (dierr == kDIErrNone) {
|
|
|
|
/* got the space; break it down by disk type */
|
|
if (unitSize == DiskImgLib::kBlockSize) {
|
|
pWnd = GetDlgItem(IDC_AIDISK_CAPACITY);
|
|
GetReducedSize(totalUnits, unitSize, &reducedSize);
|
|
tmpStr.Format(L"%ld blocks (%ls)",
|
|
totalUnits, reducedSize);
|
|
if (totalUnits != pDiskImg->GetNumBlocks()) {
|
|
CString tmpStr2;
|
|
tmpStr2.Format(L", image has room for %ld blocks",
|
|
pDiskImg->GetNumBlocks());
|
|
tmpStr += tmpStr2;
|
|
}
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_FREESPACE);
|
|
GetReducedSize(freeUnits, unitSize, &reducedSize);
|
|
tmpStr.Format(L"%ld blocks (%ls)",
|
|
freeUnits, reducedSize);
|
|
pWnd->SetWindowText(tmpStr);
|
|
} else {
|
|
ASSERT(unitSize == DiskImgLib::kSectorSize);
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_CAPACITY);
|
|
GetReducedSize(totalUnits, unitSize, &reducedSize);
|
|
tmpStr.Format(L"%ld sectors (%ls)",
|
|
totalUnits, reducedSize);
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_FREESPACE);
|
|
GetReducedSize(freeUnits, unitSize, &reducedSize);
|
|
tmpStr.Format(L"%ld sectors (%ls)",
|
|
freeUnits, reducedSize);
|
|
pWnd->SetWindowText(tmpStr);
|
|
}
|
|
} else {
|
|
/* "free space" not supported; fill in what we do know */
|
|
pWnd = GetDlgItem(IDC_AIDISK_CAPACITY);
|
|
if (pDiskImg->GetHasBlocks()) {
|
|
totalUnits = pDiskImg->GetNumBlocks();
|
|
GetReducedSize(totalUnits, DiskImgLib::kBlockSize, &reducedSize);
|
|
tmpStr.Format(L"%ld blocks (%ls)",
|
|
totalUnits, reducedSize);
|
|
} else if (pDiskImg->GetHasSectors()) {
|
|
tmpStr.Format(L"%ld tracks, %d sectors per track",
|
|
pDiskImg->GetNumTracks(), pDiskImg->GetNumSectPerTrack());
|
|
} else {
|
|
tmpStr = unknown;
|
|
}
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_FREESPACE);
|
|
pWnd->SetWindowText(unknown);
|
|
}
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_WRITEABLE);
|
|
tmpStr = pDiskFS->GetReadWriteSupported() ? L"Yes" : L"No";
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_DAMAGED);
|
|
tmpStr = pDiskFS->GetFSDamaged() ? L"Yes" : L"No";
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
const char* cp;
|
|
WCHAR* outp;
|
|
|
|
pWnd = GetDlgItem(IDC_AIDISK_NOTES);
|
|
cp = pDiskImg->GetNotes();
|
|
// GetBuffer wants length in code units, which will be 2x since it's
|
|
// wide chars. The 2x mult below is for worst-case linefeed conversion.
|
|
outp = tmpStr.GetBuffer(strlen(cp) * 2 +1);
|
|
/* convert '\n' to '\r\n' */
|
|
while (*cp != '\0') {
|
|
if (*cp == '\n')
|
|
*outp++ = '\r';
|
|
*outp++ = *cp++;
|
|
}
|
|
*outp = '\0';
|
|
tmpStr.ReleaseBuffer();
|
|
/* drop the trailing linefeed */
|
|
if (!tmpStr.IsEmpty() && tmpStr.GetAt(tmpStr.GetLength()-1) == '\n')
|
|
tmpStr.TrimRight(); // trim the whitespace chars off
|
|
pWnd->SetWindowText(tmpStr);
|
|
}
|
|
|
|
/*
|
|
* Reduce a size to something meaningful (KB, MB, GB).
|
|
*/
|
|
void
|
|
DiskArchiveInfoDialog::GetReducedSize(long numUnits, int unitSize,
|
|
CString* pOut) const
|
|
{
|
|
LONGLONG sizeInBytes = numUnits;
|
|
sizeInBytes *= unitSize;
|
|
long reducedSize;
|
|
|
|
if (sizeInBytes < 0) {
|
|
ASSERT(false);
|
|
pOut->Format(L"<bogus>");
|
|
return;
|
|
}
|
|
|
|
if (sizeInBytes >= 1024*1024*1024) {
|
|
reducedSize = (long) (sizeInBytes / (1024*1024));
|
|
pOut->Format(L"%.2fGB", reducedSize / 1024.0);
|
|
} else if (sizeInBytes >= 1024*1024) {
|
|
reducedSize = (long) (sizeInBytes / 1024);
|
|
pOut->Format(L"%.2fMB", reducedSize / 1024.0);
|
|
} else {
|
|
pOut->Format(L"%.2fKB", ((long) sizeInBytes) / 1024.0);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* ===========================================================================
|
|
* BnyArchiveInfoDialog
|
|
* ===========================================================================
|
|
*/
|
|
|
|
/*
|
|
* Set up fields with Binary II info.
|
|
*
|
|
* Binary II files are pretty dull.
|
|
*/
|
|
BOOL
|
|
BnyArchiveInfoDialog::OnInitDialog(void)
|
|
{
|
|
CWnd* pWnd;
|
|
CString tmpStr;
|
|
|
|
ASSERT(fpArchive != NULL);
|
|
|
|
pWnd = GetDlgItem(IDC_AI_FILENAME);
|
|
pWnd->SetWindowText(fpArchive->GetPathName());
|
|
tmpStr.Format(L"%ld", fpArchive->GetNumEntries());
|
|
pWnd = GetDlgItem(IDC_AIBNY_RECORDS);
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
return ArchiveInfoDialog::OnInitDialog();
|
|
}
|
|
|
|
|
|
/*
|
|
* ===========================================================================
|
|
* AcuArchiveInfoDialog
|
|
* ===========================================================================
|
|
*/
|
|
|
|
/*
|
|
* Set up fields with ACU info.
|
|
*/
|
|
BOOL
|
|
AcuArchiveInfoDialog::OnInitDialog(void)
|
|
{
|
|
CWnd* pWnd;
|
|
CString tmpStr;
|
|
|
|
ASSERT(fpArchive != NULL);
|
|
|
|
pWnd = GetDlgItem(IDC_AI_FILENAME);
|
|
pWnd->SetWindowText(fpArchive->GetPathName());
|
|
tmpStr.Format(L"%ld", fpArchive->GetNumEntries());
|
|
pWnd = GetDlgItem(IDC_AIBNY_RECORDS);
|
|
pWnd->SetWindowText(tmpStr);
|
|
|
|
return ArchiveInfoDialog::OnInitDialog();
|
|
}
|