diff options
author | Matt Wu <matt@ext2fsd.com> | 2011-01-30 15:27:46 +0300 |
---|---|---|
committer | Matt Wu <matt@ext2fsd.com> | 2011-01-30 15:27:46 +0300 |
commit | abd6c07223688f426f95bdc39104b42ee3b7740f (patch) | |
tree | 31a81f325411309392b61f0c27572ac9848ba640 /Ext2Mgr/MountPoints.cpp | |
parent | 0bab5d4b813fde9600a1570b288c8bbacc1aec3e (diff) |
Ext2Mgr 2.50
Diffstat (limited to 'Ext2Mgr/MountPoints.cpp')
-rw-r--r-- | Ext2Mgr/MountPoints.cpp | 469 |
1 files changed, 469 insertions, 0 deletions
diff --git a/Ext2Mgr/MountPoints.cpp b/Ext2Mgr/MountPoints.cpp new file mode 100644 index 0000000..2a2d09e --- /dev/null +++ b/Ext2Mgr/MountPoints.cpp @@ -0,0 +1,469 @@ +// MountPoints.cpp : implementation file +// + +#include "stdafx.h" +#include "ext2mgr.h" +#include "MountPoints.h" +#include "Ext2MgrDlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMountPoints dialog + + +CMountPoints::CMountPoints(CWnd* pParent /*=NULL*/) + : CDialog(CMountPoints::IDD, pParent) +{ + //{{AFX_DATA_INIT(CMountPoints) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT + m_Cdrom = NULL; + m_Volume = NULL; + m_Part = NULL; + m_Letter = ""; + m_bUpdated = TRUE; + m_bMgrNoted = FALSE; + m_MainDlg = NULL; +} + +void CMountPoints::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CMountPoints) + DDX_Control(pDX, IDC_DRV_LETTER_LIST, m_drvList); + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CMountPoints, CDialog) + //{{AFX_MSG_MAP(CMountPoints) + ON_NOTIFY(NM_CLICK, IDC_DRV_LETTER_LIST, OnClickDrvLetterList) + ON_BN_CLICKED(ID_ADD_MOUNTPOINT, OnAddMountpoint) + ON_BN_CLICKED(ID_CHANGE_MOUNTPOINT, OnChangeMountpoint) + ON_BN_CLICKED(ID_REMOVE_MOUNTPOINT, OnRemoveMountpoint) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CMountPoints message handlers + +void CMountPoints::OnClickDrvLetterList(NMHDR* pNMHDR, LRESULT* pResult) +{ + // TODO: Add your control notification handler code here + int item = m_drvList.GetSelectionMark(); + if (item != -1) { + m_Letter = m_drvList.GetItemText(item, 0); + + if (!m_Letter.IsEmpty()) { + SET_WIN(ID_CHANGE_MOUNTPOINT, TRUE); + SET_WIN(ID_REMOVE_MOUNTPOINT, TRUE); + } + } + + if (pResult) { + *pResult = 0; + } +} + +BOOLEAN +CMountPoints::AddMountPoint( + CHAR drvChar, + BOOLEAN bRegistry, + BOOLEAN bMountMgr +) +{ + CHAR devPath[MAX_PATH]; + PEXT2_LETTER drvLetter = NULL; + ULONGLONG letterMask = 0; + BOOLEAN rc = TRUE; + BOOLEAN bFirstMount = FALSE; + + PEXT2_VOLUME_PROPERTY2 EVP = NULL; + + memset(devPath, 0, MAX_PATH); + + if (drvChar >= '0' && drvChar <= '9') { + drvLetter = &drvDigits[drvChar - '0']; + letterMask = ((ULONGLONG) 1) << (drvChar - '0' + 32); + } else if (drvChar >= 'A' && drvChar <= 'Z') { + drvLetter = &drvLetters[drvChar - 'A']; + letterMask = ((ULONGLONG) 1) << (drvChar - 'A'); + } + + if (!drvLetter) { + return FALSE; + } + + if (m_Part) { + if (m_Part->Volume) { + strcpy(devPath, m_Part->Volume->Name); + } else { + sprintf(devPath, "\\Device\\Harddisk%u\\Partition%u", + m_Part->Disk->OrderNo, m_Part->Number); + } + } + + if (m_Volume) { + strcpy(devPath, m_Volume->Name); + EVP = &m_Volume->EVP; + } + + if (m_Cdrom) { + strcpy(devPath, m_Cdrom->Name); + EVP = &m_Cdrom->EVP; + } + + if (bRegistry) { + CString str; + + if (Ext2SetRegistryMountPoint(&drvChar, devPath, bRegistry)) { + Ext2AssignDrvLetter(drvLetter, devPath, FALSE); + EndDialog(0); + } else { + str.Format("Failed to modify registry: SYSTEM\\CurrentControlSet\\Control\\Session Manager\\DOS Devices\n"); + AfxMessageBox(str, MB_OK|MB_ICONWARNING); + } + } + + if (bMountMgr) { + + if ((m_Volume != NULL) && (m_Volume->DrvLetters == 0) && + (m_Volume->EVP.bExt2 || m_Volume->EVP.bExt3) ) { + bFirstMount = TRUE; + } else if (m_Part != NULL && m_Part->Volume && + (m_Part->Volume->DrvLetters == 0) && + (m_Part->Volume->EVP.bExt2 || m_Part->Volume->EVP.bExt3) ) { + EVP = &m_Part->Volume->EVP; + bFirstMount = TRUE; + } + } + + if (EVP) { + if (Ext2IsNullUuid(&EVP->UUID[0])) { + AfxMessageBox("UUID is 0."); + } + if (!Ext2CheckVolumeRegistryProperty(EVP)) { + Ext2SetDefaultVolumeRegistryProperty(EVP); + } + } + + if (bFirstMount) { + + NT::NTSTATUS status; + HANDLE Handle = NULL; + CString str; + + status = Ext2Open(devPath, &Handle, EXT2_DESIRED_ACCESS); + if (!NT_SUCCESS(status)) { + str.Format("Ext2Fsd service is not started.\n"); + AfxMessageBox(str, MB_OK | MB_ICONSTOP); + return FALSE; + } + + rc = Ext2QueryExt2Property(Handle, EVP); + if (!rc) { + goto errorout; + } + + EVP->DrvLetter = drvLetter->Letter | 0x80; + Ext2StorePropertyinRegistry(EVP); + + if (Ext2RefreshVolumePoint(devPath, EVP->DrvLetter)) { + EVP->DrvLetter = 0xFF; + } + + rc = Ext2SetExt2Property(Handle, EVP); + +errorout: + + Ext2Close(&Handle); + + } else { + + rc = Ext2AssignDrvLetter(drvLetter, devPath, bMountMgr); + if (!rc && !bMountMgr) { + CString str; + str.Format("Failed to assign new drive letter %c:\n", drvChar); + AfxMessageBox(str, MB_OK|MB_ICONWARNING); + return FALSE; + } + } + + if (bMountMgr) { + + Ext2UpdateDrvLetter(drvLetter, devPath); + + if (!bFirstMount) { + Ext2RefreshVolumePoint(devPath, drvLetter->Letter); + } + + Sleep(2000); + drvChar = Ext2QueryMountPoint(devPath); + + if (drvChar >= '0' && drvChar <= '9') { + drvLetter = &drvDigits[drvChar - '0']; + letterMask = ((ULONGLONG) 1) << (drvChar - '0' + 32); + } else if (drvChar >= 'A' && drvChar <= 'Z') { + drvLetter = &drvLetters[drvChar - 'A']; + letterMask = ((ULONGLONG) 1) << (drvChar - 'A'); + } else { + drvLetter = NULL; + letterMask = 0; + } + + rc = drvLetter ? TRUE : FALSE; + } + + if (rc) { + + m_bUpdated = TRUE; + if (m_Part) { + m_Part->DrvLetters |= letterMask; + if (m_Part->Volume) { + m_Part->Volume->DrvLetters |= letterMask; + } + InitializeList(m_Part->DrvLetters); + } + if (m_Volume) { + m_Volume->DrvLetters |= letterMask; + InitializeList(m_Volume->DrvLetters); + } + if (m_Cdrom) { + m_Cdrom->DrvLetters |= letterMask; + InitializeList(m_Cdrom->DrvLetters); + } + + /* + ((CExt2MgrDlg *)m_MainDlg)->DriverLetterChangeNotify(drvLetter->Letter, TRUE); + */ + + m_MainDlg->SendMessage( + WM_MOUNTPOINT_NOTIFY, + 'DA', (LPARAM)drvLetter->Letter); + } + + return TRUE; +} + +void CMountPoints::OnAddMountpoint() +{ + CSelectDrvLetter drvSel; + STORAGE_BUS_TYPE busType = BusTypeAta; + + if (m_Part) { + busType = m_Part->Disk->SDD.BusType; + } + + if (m_Volume && m_Volume->Part) { + busType = m_Volume->Part->Disk->SDD.BusType; + } + + if (m_Cdrom || + busType == BusType1394 || + busType == BusTypeUsb ) { + + drvSel.m_bMountMgr = TRUE; + drvSel.m_bRegistry = FALSE; + drvSel.m_bDosDev = FALSE; + } + + if (drvSel.DoModal() != IDOK) { + return; + } + + AddMountPoint(drvSel.m_DrvLetter.GetAt(0), + drvSel.m_bRegistry, + drvSel.m_bMountMgr + ); +} + +void CMountPoints::OnChangeMountpoint() +{ + CHAR odrvChar = 0; + CHAR ndrvChar = 0; + + CSelectDrvLetter drvSel; + STORAGE_BUS_TYPE busType = BusTypeAta; + + if (m_Part) { + busType = m_Part->Disk->SDD.BusType; + } + + if (m_Volume && m_Volume->Part) { + busType = m_Volume->Part->Disk->SDD.BusType; + } + + if (m_Cdrom || + busType == BusType1394 || + busType == BusTypeUsb ) { + + drvSel.m_bMountMgr = TRUE; + drvSel.m_bRegistry = FALSE; + drvSel.m_bDosDev = FALSE; + } + + if (drvSel.DoModal() != IDOK) { + return; + } + + ndrvChar = drvSel.m_DrvLetter.GetAt(0); + odrvChar = m_Letter.GetAt(0); + + if (RemoveMountPoint(odrvChar)) { + AddMountPoint( + ndrvChar, + drvSel.m_bRegistry, + drvSel.m_bMountMgr + ); + } +} + +BOOLEAN +CMountPoints::RemoveMountPoint(CHAR drvChar) +{ + PEXT2_LETTER drvLetter = NULL; + ULONGLONG letterMask = 0; + + if (drvChar >= '0' && drvChar <= '9') { + drvLetter = &drvDigits[drvChar - '0']; + letterMask = ((ULONGLONG) 1) << (drvChar - '0' + 32); + } else if (drvChar >= 'A' && drvChar <= 'Z') { + drvLetter = &drvLetters[drvChar - 'A']; + letterMask = ((ULONGLONG) 1) << (drvChar - 'A'); + } + + if (!drvLetter) { + return FALSE; + } + + Ext2SetRegistryMountPoint(&drvChar, NULL, FALSE); + if (Ext2RemoveDrvLetter(drvLetter)) { + + m_MainDlg->SendMessage(WM_MOUNTPOINT_NOTIFY, + 'DR', (LPARAM)drvLetter->Letter); + + } else { + + CString str; + str.Format("Failed to remove drive letter %c:\n", drvChar); + AfxMessageBox(str, MB_OK|MB_ICONWARNING); + return FALSE; + } + + if (m_Part) { + m_Part->DrvLetters &= (~letterMask); + if (m_Part->Volume) { + m_Part->Volume->DrvLetters &= ~letterMask; + } + InitializeList(m_Part->DrvLetters); + } + + if (m_Volume) { + PEXT2_PARTITION part = Ext2QueryVolumePartition(m_Volume); + m_Volume->DrvLetters &= ~letterMask; + if (part) { + part->DrvLetters &= ~letterMask; + } + InitializeList(m_Volume->DrvLetters); + } + + if (m_Cdrom) { + m_Cdrom->DrvLetters &= ~letterMask; + InitializeList(m_Cdrom->DrvLetters); + } + + return TRUE; +} + +void CMountPoints::OnRemoveMountpoint() +{ + CHAR drvChar = m_Letter.GetAt(0); + + if (RemoveMountPoint(drvChar)) { + SET_WIN(ID_CHANGE_MOUNTPOINT, FALSE); + SET_WIN(ID_REMOVE_MOUNTPOINT, FALSE); + } +} + +void CMountPoints::OnOK() +{ + // TODO: Add extra validation here + + CDialog::OnOK(); +} + +void CMountPoints::OnCancel() +{ + CDialog::OnCancel(); +} + + +void CMountPoints::InitializeList(ULONGLONG letters) +{ + CHAR drvName[] = "C:\0"; + int i = 0; + ULONGLONG drive = 0; + + m_drvList.DeleteAllItems(); + + for (i=0; i < 10; i++) { + drive = ((ULONGLONG) 1) << (i + 32); + if (letters & drive) { + drvName[0] = '0' + i; + m_drvList.InsertItem( + m_drvList.GetItemCount(), + drvName); + } + } + + for (i=2; i < 26; i++) { + drive = ((ULONGLONG) 1) << (i); + if (letters & drive) { + drvName[0] = 'A' + i; + m_drvList.InsertItem( + m_drvList.GetItemCount(), + drvName); + } + } +} + +BOOL CMountPoints::OnInitDialog() +{ + CDialog::OnInitDialog(); + + // TODO: Add extra initialization here + ASSERT(m_Volume || m_Part); + + if (m_Part) { + InitializeList(m_Part->DrvLetters); + } else if (m_Volume) { + InitializeList(m_Volume->DrvLetters); + } else { + InitializeList(m_Cdrom->DrvLetters); + } + + SET_WIN(ID_CHANGE_MOUNTPOINT, FALSE); + SET_WIN(ID_REMOVE_MOUNTPOINT, FALSE); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +BOOL CMountPoints::PreTranslateMessage(MSG* pMsg) +{ + // TODO: Add your specialized code here and/or call the base class + +#if 0 + if (pMsg->message==WM_KEYDOWN) { + if (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE) { + pMsg->wParam = NULL; + } + } +#endif + + return CDialog::PreTranslateMessage(pMsg); +} |