mirror of
https://github.com/bobranten/Ext4Fsd.git
synced 2025-10-29 21:18:30 -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);
|
|
}
|