// 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; } } BOOL CMountPoints::AddMountPoint( CHAR drvChar, BOOL bRegistry, BOOL bMountMgr ) { CHAR devPath[MAX_PATH]; PEXT2_LETTER drvLetter = NULL; ULONGLONG letterMask = 0; BOOL rc = TRUE; BOOL bMount = FALSE; PEXT2_VOLUME_PROPERTY3 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); return FALSE; } } if (drvLetter->bUsed) return FALSE; if ((m_Volume != NULL) && (m_Volume->DrvLetters == 0) && (m_Volume->EVP.bExt2 || m_Volume->EVP.bExt3) ) { bMount = 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; bMount = TRUE; } if (EVP) { if (Ext2IsNullUuid(&EVP->UUID[0])) { AfxMessageBox("UUID is 0."); } if (!Ext2CheckVolumeRegistryProperty(EVP)) { Ext2SetDefaultVolumeRegistryProperty(EVP); } } /* create an entry in regisgtry */ { 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; EVP->Flags2 |= EXT2_VPROP3_AUTOMOUNT; Ext2StorePropertyinRegistry(EVP); rc = Ext2SetExt2Property(Handle, EVP); errorout: Ext2Close(&Handle); } if (bMount) { 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; } } else { rc = FALSE; } if (0 && bMountMgr) { Ext2UpdateDrvLetter(drvLetter, devPath); if (!bMount) { Ext2RefreshVolumePoint(devPath, drvLetter->Letter); } Sleep(500); 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 TRUE drvSel.m_bDosDev = TRUE; drvSel.m_bMountMgr = FALSE; drvSel.m_bRegistry = FALSE; #else if (m_Cdrom || busType == BusType1394 || busType == BusTypeUsb ) { drvSel.m_bMountMgr = TRUE; drvSel.m_bRegistry = FALSE; drvSel.m_bDosDev = FALSE; } #endif if (drvSel.DoModal() != IDOK) { return; } AddMountPoint(drvSel.m_DrvLetter.GetAt(0), drvSel.m_bRegistry, drvSel.m_bMountMgr ); OnOK(); } 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 TRUE drvSel.m_bMountMgr = FALSE; drvSel.m_bRegistry = FALSE; drvSel.m_bDosDev = TRUE; #else if (m_Cdrom || busType == BusType1394 || busType == BusTypeUsb ) { drvSel.m_bMountMgr = TRUE; drvSel.m_bRegistry = FALSE; drvSel.m_bDosDev = FALSE; } #endif 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 ); } OnOK(); } BOOL 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); if (m_drvList.GetItemCount() == 0) OnOK(); } } 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); } m_drvList.SetSelectionMark(0); m_drvList.SetFocus(); m_Letter = m_drvList.GetItemText(0, 0); if (m_Letter.IsEmpty()) { SET_WIN(ID_CHANGE_MOUNTPOINT, FALSE); SET_WIN(ID_REMOVE_MOUNTPOINT, FALSE); } else { SET_WIN(ID_CHANGE_MOUNTPOINT, TRUE); SET_WIN(ID_REMOVE_MOUNTPOINT, TRUE); } 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); }