mirror of
				https://github.com/bobranten/Ext4Fsd.git
				synced 2025-10-30 21:38:31 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			500 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			500 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // 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);
 | |
| }
 |