/*
 * CiderPress
 * Copyright (C) 2007 by faddenSoft, LLC.  All Rights Reserved.
 * See the file LICENSE for distribution terms.
 */
/*
 * Allow the user to select a disk volume.
 */
#include "stdafx.h"
#include "OpenVolumeDialog.h"
#include "Main.h"
#include "../diskimg/Win32Extra.h"  // need disk geometry calls
#include "../diskimg/ASPI.h"


BEGIN_MESSAGE_MAP(OpenVolumeDialog, CDialog)
    ON_COMMAND(IDHELP, OnHelp)
    //ON_NOTIFY(NM_CLICK, IDC_VOLUME_LIST, OnListClick)
    ON_NOTIFY(LVN_ITEMCHANGED, IDC_VOLUME_LIST, OnListChange)
    ON_NOTIFY(NM_DBLCLK, IDC_VOLUME_LIST, OnListDblClick)
    ON_CBN_SELCHANGE(IDC_VOLUME_FILTER, OnVolumeFilterSelChange)
END_MESSAGE_MAP()


BOOL OpenVolumeDialog::OnInitDialog(void)
{
    /*
     * Sets up the list of drives.
     */

    CDialog::OnInitDialog();        // do any DDX init stuff
    const Preferences* pPreferences = GET_PREFERENCES();
    long defaultFilter;

    /* highlight/select entire line, not just filename */
    CListCtrl* pListView = (CListCtrl*) GetDlgItem(IDC_VOLUME_LIST);
    ASSERT(pListView != NULL);

    ListView_SetExtendedListViewStyleEx(pListView->m_hWnd,
        LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);

    /* disable the OK button until they click on something */
    CButton* pButton = (CButton*) GetDlgItem(IDOK);
    ASSERT(pButton != NULL);

    pButton->EnableWindow(FALSE);

    /* if the read-only state is fixed, don't let them change it */
    if (!fAllowROChange) {
        CButton* pButton;
        pButton = (CButton*) GetDlgItem(IDC_OPENVOL_READONLY);
        ASSERT(pButton != NULL);
        pButton->EnableWindow(FALSE);
    }

    /* prep the combo box */
    CComboBox* pCombo = (CComboBox*) GetDlgItem(IDC_VOLUME_FILTER);
    ASSERT(pCombo != NULL);
    defaultFilter = pPreferences->GetPrefLong(kPrVolumeFilter);
    if (defaultFilter >= kBoth && defaultFilter <= kPhysical)
        pCombo->SetCurSel(defaultFilter);
    else {
        LOGI("GLITCH: invalid defaultFilter in prefs (%d)", defaultFilter);
        pCombo->SetCurSel(kLogical);
    }

    /* two columns */
    CRect rect;
    pListView->GetClientRect(&rect);
    int width;

    width = pListView->GetStringWidth(L"XXVolume or Device NameXXmmmmmm");
    pListView->InsertColumn(0, L"Volume or Device Name", LVCFMT_LEFT, width);
    pListView->InsertColumn(1, L"Remarks", LVCFMT_LEFT,
        rect.Width() - width - ::GetSystemMetrics(SM_CXVSCROLL));

    // Load the drive list.
    LoadDriveList();

    // Kluge the physical drive 0 stuff.
    DiskImg::SetAllowWritePhys0(GET_PREFERENCES()->GetPrefBool(kPrOpenVolumePhys0));

    return TRUE;
}

void OpenVolumeDialog::DoDataExchange(CDataExchange* pDX)
{
    DDX_Check(pDX, IDC_OPENVOL_READONLY, fReadOnly);
    LOGI("DoDataExchange: fReadOnly==%d", fReadOnly);
}

void OpenVolumeDialog::LoadDriveList(void)
{
    CWaitCursor waitc;
    CComboBox* pCombo;
    CListCtrl* pListView;
    int itemIndex = 0;
    int filterSelection;

    pListView = (CListCtrl*) GetDlgItem(IDC_VOLUME_LIST);
    ASSERT(pListView != NULL);
    pCombo = (CComboBox*) GetDlgItem(IDC_VOLUME_FILTER);
    ASSERT(pCombo != NULL);

    pListView->DeleteAllItems();

    /*
     * Load the logical and physical drive sets as needed.  Do the "physical"
     * set first because it's usually what we want.
     */
    filterSelection = pCombo->GetCurSel();
    if (filterSelection == kPhysical || filterSelection == kBoth)
        LoadPhysicalDriveList(pListView, &itemIndex);
    if (filterSelection == kLogical || filterSelection == kBoth)
        LoadLogicalDriveList(pListView, &itemIndex);
}

bool OpenVolumeDialog::LoadLogicalDriveList(CListCtrl* pListView, int* pItemIndex)
{
    DWORD drivesAvailable;
    bool isWin9x = IsWin9x();
    int itemIndex = *pItemIndex;

    ASSERT(pListView != NULL);

    drivesAvailable = GetLogicalDrives();
    if (drivesAvailable == 0) {
        LOGI("GetLogicalDrives failed, err=0x%08lx", drivesAvailable);
        return false;
    }
    LOGI("GetLogicalDrives returned 0x%08lx", drivesAvailable);

    // SetErrorMode(SEM_FAILCRITICALERRORS)

    /* run through the list, from A-Z */
    int i;
    for (i = 0; i < kMaxLogicalDrives; i++) {
        fVolumeInfo[i].driveType = DRIVE_UNKNOWN;

        if ((drivesAvailable >> i) & 0x01) {
            WCHAR driveName[] = L"_:\\";
            driveName[0] = 'A' + i;

            unsigned int driveType;
            const WCHAR* driveTypeComment = NULL;
            BOOL result;

            driveType = fVolumeInfo[i].driveType = GetDriveType(driveName);
            switch (driveType) {
            case DRIVE_UNKNOWN:
                // The drive type cannot be determined.
                break;
            case DRIVE_NO_ROOT_DIR:
                // The root path is invalid. For example, no volume is mounted at the path.
                break;
            case DRIVE_REMOVABLE:
                // The disk can be removed from the drive.
                driveTypeComment = L"Removable";
                break;
            case DRIVE_FIXED:
                // The disk cannot be removed from the drive.
                driveTypeComment = L"Local Disk";
                break;
            case DRIVE_REMOTE:
                // The drive is a remote (network) drive.
                driveTypeComment = L"Network";
                break;
            case DRIVE_CDROM:
                // The drive is a CD-ROM drive.
                driveTypeComment = L"CD-ROM";
                break;
            case DRIVE_RAMDISK:
                // The drive is a RAM disk.
                break;
            default:
                LOGI("UNKNOWN DRIVE TYPE %d", driveType);
                break;
            }

            if (driveType == DRIVE_CDROM && !DiskImgLib::Global::GetHasSPTI()) {
                /* use "physical" device via ASPI instead */
                LOGI("Not including CD-ROM '%ls' in logical drive list",
                    driveName);
                continue;
            }

            WCHAR volNameBuf[256];
            WCHAR fsNameBuf[64];
            const WCHAR* errorComment = NULL;
            //DWORD fsFlags;
            CString entryName, entryRemarks;

            result = ::GetVolumeInformation(driveName, volNameBuf,
                NELEM(volNameBuf), NULL, NULL, NULL /*&fsFlags*/, fsNameBuf,
                NELEM(fsNameBuf));
            if (result == FALSE) {
                DWORD err = GetLastError();
                if (err == ERROR_UNRECOGNIZED_VOLUME) {
                    // Win2K: media exists but format not recognized
                    errorComment = L"Non-Windows format";
                } else if (err == ERROR_NOT_READY) {
                    // Win2K: device exists but no media loaded
                    if (isWin9x) {
                        LOGI("Not showing drive '%ls': not ready",
                            driveName);
                        continue;   // safer not to show it
                    } else
                        errorComment = L"Not ready";
                } else if (err == ERROR_PATH_NOT_FOUND /*Win2K*/ ||
                           err == ERROR_INVALID_DATA /*Win98*/)
                {
                    // Win2K/Win98: device letter not in use
                    LOGI("GetVolumeInformation '%ls': nothing there",
                        driveName);
                    continue;
                } else if (err == ERROR_INVALID_PARAMETER) {
                    // Win2K: device is already open
                    //LOGI("GetVolumeInformation '%ls': currently open??",
                    //  driveName);
                    errorComment = L"(currently open?)";
                    //continue;
                } else if (err == ERROR_ACCESS_DENIED) {
                    // Win2K: disk is open no-read-sharing elsewhere
                    errorComment = L"(already open read-write)";
                } else if (err == ERROR_GEN_FAILURE) {
                    // Win98: floppy format not recognzied
                    // --> we don't want to access ProDOS floppies via A: in
                    //     Win98, so we skip it here
                    LOGI("GetVolumeInformation '%ls': general failure",
                        driveName);
                    continue;
                } else if (err == ERROR_INVALID_FUNCTION) {
                    // Win2K: CD-ROM with HFS
                    if (driveType == DRIVE_CDROM)
                        errorComment = L"Non-Windows format";
                    else
                        errorComment = L"(invalid disc?)";
                } else {
                    LOGI("GetVolumeInformation '%ls' failed: %ld",
                        driveName, GetLastError());
                    continue;
                }
                ASSERT(errorComment != NULL);

                entryName.Format(L"(%c:)", 'A' + i);
                if (driveTypeComment != NULL)
                    entryRemarks.Format(L"%ls - %ls", driveTypeComment,
                        errorComment);
                else
                    entryRemarks.Format(L"%ls", errorComment);
            } else {
                entryName.Format(L"%ls (%c:)", volNameBuf, 'A' + i);
                if (driveTypeComment != NULL)
                    entryRemarks.Format(L"%ls", driveTypeComment);
                else
                    entryRemarks = "";
            }

            pListView->InsertItem(itemIndex, entryName);
            pListView->SetItemText(itemIndex, 1, entryRemarks);
            pListView->SetItemData(itemIndex, (DWORD) i + 'A');
//LOGI("%%%% added logical %d", itemIndex);
            itemIndex++;
        } else {
            LOGI(" (drive %c not available)", i + 'A');
        }
    }

    *pItemIndex = itemIndex;

    return true;
}

bool OpenVolumeDialog::LoadPhysicalDriveList(CListCtrl* pListView, int* pItemIndex)
{
    /*
     * I don't see a clever way to do this in Win2K except to open the first 8
     * or so devices and see what happens.
     *
     * Win9x isn't much better, though you can be reasonably confident that there
     * are at most 4 floppy drives and 4 hard drives.
     *
     * TODO: check again for a better way
     */

    bool isWin9x = IsWin9x();
    int itemIndex = *pItemIndex;
    int i;

    if (isWin9x) {
        // fairly arbitrary choices
        const int kMaxFloppies = 4;
        const int kMaxHardDrives = 8;

        for (i = 0; i < kMaxFloppies; i++) {
            CString driveName, remark;
            bool result;

            result = HasPhysicalDriveWin9x(i, &remark);
            if (result) {
                driveName.Format(L"Floppy disk %d", i);
                pListView->InsertItem(itemIndex, driveName);
                pListView->SetItemText(itemIndex, 1, remark);
                pListView->SetItemData(itemIndex, (DWORD) i);
//LOGI("%%%% added floppy %d", itemIndex);
                itemIndex++;
            }
        }
        for (i = 0; i < kMaxHardDrives; i++) {
            CString driveName, remark;
            bool result;

            result = HasPhysicalDriveWin9x(i + 128, &remark);
            if (result) {
                driveName.Format(L"Hard drive %d", i);
                pListView->InsertItem(itemIndex, driveName);
                pListView->SetItemText(itemIndex, 1, remark);
                pListView->SetItemData(itemIndex, (DWORD) i + 128);
//LOGI("%%%% added HD %d", itemIndex);
                itemIndex++;
            }
        }
    } else {
        for (i = 0; i < kMaxPhysicalDrives; i++) {
            CString driveName, remark;
            bool result;

            result = HasPhysicalDriveWin2K(i + 128, &remark);
            if (result) {
                driveName.Format(L"Physical disk %d", i);
                pListView->InsertItem(itemIndex, driveName);
                pListView->SetItemText(itemIndex, 1, remark);
                pListView->SetItemData(itemIndex, (DWORD) i + 128); // HD volume
                itemIndex++;
            }
        }
    }

    if (DiskImgLib::Global::GetHasASPI()) {
        LOGI("IGNORING ASPI");
#if 0   // can we remove this?
        DIError dierr;
        DiskImgLib::ASPI* pASPI = DiskImgLib::Global::GetASPI();
        ASPIDevice* deviceArray = NULL;
        int numDevices;

        dierr = pASPI->GetAccessibleDevices(
                    ASPI::kDevMaskCDROM | ASPI::kDevMaskHardDrive,
                    &deviceArray, &numDevices);
        if (dierr == kDIErrNone) {
            LOGI("Adding %d ASPI CD-ROM devices", numDevices);
            for (i = 0; i < numDevices; i++) {
                CString driveName, remark;
                CString addr, vendor, product;
                DWORD aspiAddr;

                addr.Format("ASPI %d:%d:%d",
                    deviceArray[i].GetAdapter(),
                    deviceArray[i].GetTarget(),
                    deviceArray[i].GetLun());
                vendor = deviceArray[i].GetVendorID();
                vendor.TrimRight();
                product = deviceArray[i].GetProductID();
                product.TrimRight();

                driveName.Format("%s %s", vendor, product);
                if (deviceArray[i].GetDeviceType() == ASPIDevice::kTypeCDROM)
                    remark = "CD-ROM";
                else if (deviceArray[i].GetDeviceType() == ASPIDevice::kTypeDASD)
                    remark = "Direct-access device";
                if (!deviceArray[i].GetDeviceReady())
                    remark += " - Not ready";

                aspiAddr =  (DWORD) 0xaa << 24 |
                            (DWORD) deviceArray[i].GetAdapter() << 16 |
                            (DWORD) deviceArray[i].GetTarget() << 8 |
                            (DWORD) deviceArray[i].GetLun();
                //LOGI("ADDR for '%s' is 0x%08lx",
                //  (const char*) driveName, aspiAddr);

                pListView->InsertItem(itemIndex, driveName);
                pListView->SetItemText(itemIndex, 1, remark);
                pListView->SetItemData(itemIndex, aspiAddr);
                itemIndex++;
            }
        }

        delete[] deviceArray;
#endif
    }

    *pItemIndex = itemIndex;
    return true;
}

bool OpenVolumeDialog::HasPhysicalDriveWin9x(int unit, CString* pRemark)
{
    HANDLE handle = NULL;
    const int VWIN32_DIOC_DOS_INT13 = 4;
    const int CARRY_FLAG = 1;
    BOOL result;
    typedef struct _DIOC_REGISTERS {
        DWORD reg_EBX;
        DWORD reg_EDX;
        DWORD reg_ECX;
        DWORD reg_EAX;
        DWORD reg_EDI;
        DWORD reg_ESI;
        DWORD reg_Flags;
    } DIOC_REGISTERS, *PDIOC_REGISTERS;
    DIOC_REGISTERS reg = {0};
    DWORD lastError, cb;
    unsigned char buf[512];

    if (unit > 4)
        return false;   // floppy drives only

    handle = CreateFile(L"\\\\.\\vwin32", 0, 0, NULL,
                OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL);
    if (handle == INVALID_HANDLE_VALUE) {
        LOGI(" Unable to open vwin32: %ld", ::GetLastError());
        return false;
    }

#if 0   // didn't do what I wanted
    reg.reg_EAX = MAKEWORD(0, 0x00);    // func 0x00 == reset controller
    reg.reg_EDX = MAKEWORD(unit, 0);    // specify driver
    result = DeviceIoControl(handle, VWIN32_DIOC_DOS_INT13, &reg,
                sizeof(reg), &reg, sizeof(reg), &cb, 0);
    LOGI("  DriveReset(drive=0x%02x) result=%d carry=%d",
        unit, result, reg.reg_Flags & CARRY_FLAG);
#endif

    reg.reg_EAX = MAKEWORD(1, 0x02);    // read 1 sector
    reg.reg_EBX = (DWORD) buf;
    reg.reg_ECX = MAKEWORD(1, 0);       // sector 0 (+1), cylinder 0
    reg.reg_EDX = MAKEWORD(unit, 0);    // head

    result = DeviceIoControl(handle, VWIN32_DIOC_DOS_INT13, &reg,
                sizeof(reg) /*bytes*/, &reg, sizeof(reg) /*bytes*/, &cb, 0);
    lastError = GetLastError();
    ::CloseHandle(handle);

    if (result == 0 || (reg.reg_Flags & CARRY_FLAG)) {
        int ah = HIBYTE(reg.reg_EAX);
        LOGI(" DevIoCtrl(unit=%02xh) failed: result=%d lastErr=%d Flags=0x%08lx",
            unit, result, lastError, reg.reg_Flags);
        LOGI("   AH=%d (EAX=0x%08lx) byte=0x%02x", ah, reg.reg_EAX, buf[0]);
        if (ah != 1) {
            // failure code 1 means "invalid parameter", drive doesn't exist
            // mine returns 128, "timeout", when no disk is in the drive
            *pRemark = "Not ready";
            return true;
        } else
            return false;
    }

    *pRemark = "Removable";

    return true;
}

bool OpenVolumeDialog::HasPhysicalDriveWin2K(int unit, CString* pRemark)
{
    HANDLE hDevice;         // handle to the drive to be examined 
    DISK_GEOMETRY dg;       // disk drive geometry structure
    DISK_GEOMETRY_EX dge;   // extended geometry request buffer
    BOOL result;            // results flag
    DWORD junk;             // discard results
    LONGLONG diskSize;      // size of the drive, in bytes
    CString fileName;
    DWORD err;

    /*
     * See if the drive is there.
     */
    ASSERT(unit >= 128 && unit < 160);      // arbitrary max
    fileName.Format(L"\\\\.\\PhysicalDrive%d", unit - 128);

    hDevice = ::CreateFile(fileName,  // drive to open
                0,                  // no access to the drive
                FILE_SHARE_READ | FILE_SHARE_WRITE, // share mode
                NULL,               // default security attributes
                OPEN_EXISTING,      // disposition
                0,                  // file attributes
                NULL);              // do not copy file attributes

    if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
        return false;

    /*
     * Try to get the drive geometry.  First try with the fancy WinXP call,
     * then fall back to the Win2K call if it doesn't exist.
     */
    result = ::DeviceIoControl(hDevice,
                IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
                NULL, 0,                // input buffer
                &dge, sizeof(dge),      // output buffer + size in bytes
                &junk,                  // # bytes returned
                (LPOVERLAPPED) NULL);   // synchronous I/O
    if (result) {
        diskSize = dge.DiskSize.QuadPart;
        LOGI(" EX results for device %02xh", unit);
        LOGI("  Disk size = %I64d (bytes) = %I64d (MB)",
            diskSize, diskSize / (1024*1024));
        if (diskSize > 1024*1024*1024)
            pRemark->Format(L"Size is %.2fGB",
                (double) diskSize / (1024.0 * 1024.0 * 1024.0));
        else
            pRemark->Format(L"Size is %.2fMB",
                (double) diskSize / (1024.0 * 1024.0));
    } else {
        // Win2K shows ERROR_INVALID_FUNCTION or ERROR_NOT_SUPPORTED
        LOGI("IOCTL_DISK_GET_DRIVE_GEOMETRY_EX failed, error was %ld",
            GetLastError());
        result = ::DeviceIoControl(hDevice, // device to be queried
                    IOCTL_DISK_GET_DRIVE_GEOMETRY,  // operation to perform
                    NULL, 0,                // no input buffer
                    &dg, sizeof(dg),        // output buffer + size in bytes
                    &junk,                  // # bytes returned
                    (LPOVERLAPPED) NULL);   // synchronous I/O

        if (result) {
            LOGI(" Results for device %02xh", unit);
            LOGI("  Cylinders = %I64d", dg.Cylinders.QuadPart);
            LOGI("  Tracks per cylinder = %ld", (ULONG) dg.TracksPerCylinder);
            LOGI("  Sectors per track = %ld", (ULONG) dg.SectorsPerTrack);
            LOGI("  Bytes per sector = %ld", (ULONG) dg.BytesPerSector);

            diskSize = dg.Cylinders.QuadPart * (ULONG)dg.TracksPerCylinder *
                        (ULONG)dg.SectorsPerTrack * (ULONG)dg.BytesPerSector;
            LOGI("Disk size = %I64d (bytes) = %I64d (MB)", diskSize,
                    diskSize / (1024 * 1024));
            if (diskSize > 1024*1024*1024)
                pRemark->Format(L"Size is %.2fGB",
                    (double) diskSize / (1024.0 * 1024.0 * 1024.0));
            else
                pRemark->Format(L"Size is %.2fMB",
                    (double) diskSize / (1024.0 * 1024.0));
        } else {
            err = GetLastError();
        }
    }

    ::CloseHandle(hDevice);

    if (!result) {
        LOGI("DeviceIoControl(IOCTL_DISK_GET_DRIVE_GEOMETRY) failed (err=%ld)",
            err);
        *pRemark = "Not ready";
    }

    return true;
}

void OpenVolumeDialog::OnListChange(NMHDR*, LRESULT* pResult)
{
    CListCtrl* pListView = (CListCtrl*) GetDlgItem(IDC_VOLUME_LIST);
    CButton* pButton = (CButton*) GetDlgItem(IDOK);
    pButton->EnableWindow(pListView->GetSelectedCount() != 0);
    //LOGI("ENABLE %d", pListView->GetSelectedCount() != 0);

    *pResult = 0;
}

void OpenVolumeDialog::OnListDblClick(NMHDR* pNotifyStruct, LRESULT* pResult)
{
    CListCtrl* pListView = (CListCtrl*) GetDlgItem(IDC_VOLUME_LIST);
    CButton* pButton = (CButton*) GetDlgItem(IDOK);

    if (pListView->GetSelectedCount() != 0) {
        pButton->EnableWindow();
        OnOK();
    }

    *pResult = 0;
}

void OpenVolumeDialog::OnVolumeFilterSelChange(void)
{
    CComboBox* pCombo = (CComboBox*) GetDlgItem(IDC_VOLUME_FILTER);
    ASSERT(pCombo != NULL);
    LOGI("+++ SELECTION IS NOW %d", pCombo->GetCurSel());
    LoadDriveList();
}

void OpenVolumeDialog::OnOK(void)
{
    /*
     * Figure out the (zero-based) drive letter.
     */
    CListCtrl* pListView = (CListCtrl*) GetDlgItem(IDC_VOLUME_LIST);
    ASSERT(pListView != NULL);

    if (pListView->GetSelectedCount() != 1) {
        CString msg, failed;
        CheckedLoadString(&failed, IDS_FAILED);
        CheckedLoadString(&msg, IDS_VOLUME_SELECT_ONE);
        MessageBox(msg, failed, MB_OK);
        return;
    }

    POSITION posn;
    posn = pListView->GetFirstSelectedItemPosition();
    if (posn == NULL) {
        ASSERT(false);
        return;
    }
    int num = pListView->GetNextSelectedItem(posn);
    DWORD driveID = pListView->GetItemData(num);
    UINT formatID = 0;

    if (HIBYTE(HIWORD(driveID)) == 0xaa) {
        // TODO: remove this?
        fChosenDrive.Format(L"%hs%d:%d:%d\\",
            DiskImgLib::kASPIDev,
            LOBYTE(HIWORD(driveID)),
            HIBYTE(LOWORD(driveID)),
            LOBYTE(LOWORD(driveID)));
        //ForceReadOnly(true);
    } else if (driveID >= 'A' && driveID <= 'Z') {
        /*
         * Do we want to let them do this?  We show some logical drives
         * that we don't want them to actually use.
         */
        switch (fVolumeInfo[driveID-'A'].driveType) {
        case DRIVE_REMOVABLE:
        case DRIVE_FIXED:
            break;              // allow
        case DRIVE_CDROM:       //formatID = IDS_VOLUME_NO_CDROM;
            ForceReadOnly(true);
            break;
        case DRIVE_REMOTE:      formatID = IDS_VOLUME_NO_REMOTE;
            break;
        case DRIVE_RAMDISK:     formatID = IDS_VOLUME_NO_RAMDISK;
            break;
        case DRIVE_UNKNOWN:
        case DRIVE_NO_ROOT_DIR:
        default:                formatID = IDS_VOLUME_NO_GENERIC;
            break;
        }

        fChosenDrive.Format(L"%c:\\", driveID);
    } else if ((driveID >= 0 && driveID < 4) ||
               (driveID >= 0x80 && driveID < 0x88))
    {
        fChosenDrive.Format(L"%02x:\\", driveID);
    } else {
        ASSERT(false);
        return;
    }

    if (formatID != 0) {
        CString msg, notAllowed;

        CheckedLoadString(&notAllowed, IDS_NOT_ALLOWED);
        CheckedLoadString(&msg, formatID);
        MessageBox(msg, notAllowed, MB_OK);
    } else {
        Preferences* pPreferences = GET_PREFERENCES_WR();
        CComboBox* pCombo = (CComboBox*) GetDlgItem(IDC_VOLUME_FILTER);
        pPreferences->SetPrefLong(kPrVolumeFilter, pCombo->GetCurSel());
        LOGI("SETTING PREF TO %ld", pCombo->GetCurSel());

        CDialog::OnOK();
    }
}

void OpenVolumeDialog::ForceReadOnly(bool readOnly) const
{
    CButton* pButton = (CButton*) GetDlgItem(IDC_OPENVOL_READONLY);
    ASSERT(pButton != NULL);

    if (readOnly)
        pButton->SetCheck(BST_CHECKED);
    else
        pButton->SetCheck(BST_UNCHECKED);
    LOGW("FORCED READ ONLY %d", readOnly);
}
