1
0
mirror of https://github.com/bobranten/Ext4Fsd.git synced 2025-10-30 13:28:31 -05:00
Files
Ext4Fsd/Ext2Mgr/MountPoints.cpp
2020-01-19 19:08:53 +01:00

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);
}