⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 diskmountdlg.cpp

📁 枚举PC所有逻辑盘符,并判断其性质,可区分DRIVE_FIXED型的设备是硬盘还是移动硬盘,DRIVE_REMOVABLE类型的设备是软盘还是U盘 工作中的积累,希望对大家有帮助.感谢PUDN曾经给予
💻 CPP
字号:
// DiskMountDlg.cpp : implementation file
//

#include "stdafx.h"
#include "DiskMount.h"
#include "DiskMountDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


//mxp--begin
#define MEDIA_INFO_SIZE    sizeof(GET_MEDIA_TYPES)+15*sizeof(DEVICE_MEDIA_INFO)
//mxp--end


/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDiskMountDlg dialog

CDiskMountDlg::CDiskMountDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CDiskMountDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDiskMountDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CDiskMountDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDiskMountDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CDiskMountDlg, CDialog)
	//{{AFX_MSG_MAP(CDiskMountDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
	ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDiskMountDlg message handlers

BOOL CDiskMountDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CDiskMountDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CDiskMountDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CDiskMountDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}




BOOL GetDriveGeometry(const TCHAR * filename, DISK_GEOMETRY * pdg)
{
	HANDLE hDevice;         // 设备句柄
	BOOL bResult;           // DeviceIoControl的返回结果
	GET_MEDIA_TYPES *pmt;   // 内部用的输出缓冲区
	DWORD dwOutBytes;       // 输出数据长度
	
	// 打开设备
	hDevice = ::CreateFile(filename,           // 文件名
		GENERIC_READ,                          // 软驱需要读盘
		FILE_SHARE_READ | FILE_SHARE_WRITE,    // 共享方式
		NULL,                                  // 默认的安全描述符
		OPEN_EXISTING,                         // 创建方式
		0,                                     // 不需设置文件属性
		NULL);                                 // 不需参照模板文件
	
	if (hDevice == INVALID_HANDLE_VALUE)
	{
		// 设备无法打开...
		return FALSE;
	}
	
	// 用IOCTL_DISK_GET_DRIVE_GEOMETRY取磁盘参数
	bResult = ::DeviceIoControl(hDevice,       // 设备句柄
		IOCTL_DISK_GET_DRIVE_GEOMETRY,         // 取磁盘参数
		NULL, 0,                               // 不需要输入数据
		pdg, sizeof(DISK_GEOMETRY),            // 输出数据缓冲区
		&dwOutBytes,                           // 输出数据长度
		(LPOVERLAPPED)NULL);                   // 用同步I/O
	
	// 如果失败,再用IOCTL_STORAGE_GET_MEDIA_TYPES_EX取介质类型参数
	if (!bResult)
	{
		pmt = (GET_MEDIA_TYPES *)new BYTE[MEDIA_INFO_SIZE];
		
		bResult = ::DeviceIoControl(hDevice,    // 设备句柄
			IOCTL_STORAGE_GET_MEDIA_TYPES_EX,   // 取介质类型参数
			NULL, 0,                            // 不需要输入数据
			pmt, MEDIA_INFO_SIZE,               // 输出数据缓冲区
			&dwOutBytes,                        // 输出数据长度
			(LPOVERLAPPED)NULL);                // 用同步I/O
		
		if (bResult)
		{
			// 注意到结构DEVICE_MEDIA_INFO是在结构DISK_GEOMETRY的基础上扩充的
			// 为简化程序,用memcpy代替如下多条赋值语句:
			// pdg->MediaType = (MEDIA_TYPE)pmt->MediaInfo[0].DeviceSpecific.DiskInfo.MediaType;
			// pdg->Cylinders = pmt->MediaInfo[0].DeviceSpecific.DiskInfo.Cylinders;
			// pdg->TracksPerCylinder = pmt->MediaInfo[0].DeviceSpecific.DiskInfo.TracksPerCylinder;
			// ... ...
			::memcpy(pdg, pmt->MediaInfo, sizeof(DISK_GEOMETRY));
		}
		
		delete pmt;
	}
	
	// 关闭设备句柄
	::CloseHandle(hDevice);
	
	return (bResult);	
}

BOOL GetDisksProperty(const TCHAR * filename, PSTORAGE_DEVICE_DESCRIPTOR pDevDesc)
{
	HANDLE hDevice;         // 设备句柄
	BOOL bResult;           // DeviceIoControl的返回结果
	DWORD dwOutBytes;       // 输出数据长度
	
	// 打开设备
	hDevice = ::CreateFile(filename,           // 文件名
		GENERIC_READ,                          // 软驱需要读盘
		FILE_SHARE_READ | FILE_SHARE_WRITE,    // 共享方式
		NULL,                                  // 默认的安全描述符
		OPEN_EXISTING,                         // 创建方式
		0,                                     // 不需设置文件属性
		NULL);                                 // 不需参照模板文件
	
	if (hDevice == INVALID_HANDLE_VALUE)
	{
		// 设备无法打开...
		return FALSE;
	}
	STORAGE_PROPERTY_QUERY	Query;	
					
	
	Query.PropertyId = StorageDeviceProperty;
	Query.QueryType = PropertyStandardQuery;
	
	bResult = ::DeviceIoControl(hDevice,				
		IOCTL_STORAGE_QUERY_PROPERTY,
		&Query, sizeof(STORAGE_PROPERTY_QUERY),	
		pDevDesc, pDevDesc->Size,				
		&dwOutBytes,							
		(LPOVERLAPPED)NULL);
	
	// 关闭设备句柄
	::CloseHandle(hDevice);		
	return bResult;

}



void CDiskMountDlg::OnButton1() 
{
	// TODO: Add your control notification handler code here
	TCHAR* s;
	TCHAR szBuf[100];
	DISK_GEOMETRY dg;
	MEDIA_TYPE    mt;
	CString  szInfor,szTemp;
	
	
	memset(szBuf,0,100);
	DWORD len = GetLogicalDriveStrings(sizeof(szBuf)/sizeof(TCHAR),szBuf);	
	for (s = szBuf; *s; s += _tcslen(s)+1)
	{	
		LPCTSTR sDrivePath = s;		
		TRACE("\r\n%s \r\n",sDrivePath);
		
		TCHAR szPath[100] = _T("\\\\.\\");
		::_tcscat(szPath,sDrivePath);
		int nSize = ::_tcslen(szPath);
		szPath[nSize-1] = '\0';	
		
		szTemp.Empty();
		szTemp += szPath[nSize-3];	
		szTemp += szPath[nSize-2];

		UINT uDriveType = GetDriveType(sDrivePath);
		
		if (uDriveType == DRIVE_CDROM)//光驱类 (CDROM、DVD、虚拟光驱 )
		{
			szTemp += "  CD-ROM";
		}
		else if (uDriveType == DRIVE_REMOVABLE)//可移动删除类设备(软驱、USB设备)
		{
			szTemp += "  DRIVE_REMOVABLE--";
			BOOL bRetVal = GetDriveGeometry(szPath,&dg);
			if(bRetVal)
			{
				mt = dg.MediaType;//获取媒体类型				
				if((mt>=1 && mt<=10) ||(mt>=13 && mt<=22))//软驱
				{
					szTemp += "FLOPPY DISK(软驱)";					
				}
				else if(mt == Unknown)//未知
				{
					szTemp += "  Unknown(未知)";			
				}			
				else if(mt == RemovableMedia)//Removable media other than floppy(U盘)
				{
					szTemp += "  RemovableMedia(U盘)";
				}				
			}
			else
				szTemp += "  读取失败,请插入软盘重试!";			
			
		}
		else if(uDriveType == DRIVE_FIXED)//固定设备(硬盘或移动硬盘)
		{
			szTemp += "  DRIVE_FIXED(硬盘或移动硬盘)";
			PSTORAGE_DEVICE_DESCRIPTOR pDevDesc;
			
			pDevDesc = (PSTORAGE_DEVICE_DESCRIPTOR)new BYTE[sizeof(STORAGE_DEVICE_DESCRIPTOR) + 512 - 1];
			
			pDevDesc->Size = sizeof(STORAGE_DEVICE_DESCRIPTOR) + 512 - 1;
			if(GetDisksProperty(szPath, pDevDesc))
			{
				 UINT Type = pDevDesc->BusType;
				 switch(Type)
				 {
					 case BusTypeUnknown : //0x00
						 szTemp += "  BusTypeUnknown(未知)";	
						 break;
					 case BusTypeScsi:
						 szTemp += "  BusTypeScsi";
						 break;
					 case BusTypeAtapi:
						 szTemp += "  BusTypeAtapi";
						 break;
					 case BusTypeAta:
						 szTemp += "  BusTypeAta(硬盘)";
						 break;
					 case BusType1394:
						  szTemp += "  BusType1394";
						 break;
					 case BusTypeSsa:
						 szTemp += "  BusTypeSsa";
						 break;
					 case BusTypeFibre:
						 szTemp += "  BusTypeFibre";
						 break;
					 case BusTypeUsb:
						 szTemp += "  BusTypeUsb";
						 break;
					 case BusTypeMaxReserved: //0x7F
						 szTemp += "  BusTypeMaxReserved";
						 break;
					 default:
						 szTemp += "  读总线类型出错!";
						 break;
				 }
			}	
		}
		else
		{
			szTemp += "其它";
		}		
		szInfor += szTemp;
		szInfor += "\r\n\r\n";
		
	}
	SetDlgItemText(IDC_EDIT1,szInfor);	
}


bool   GetFloppyLetter(TCHAR szFloppyBuf[10],int &nFloppyNumber)
{
	TCHAR* s;
	TCHAR szBuf[100];
	DISK_GEOMETRY dg;
	CString  szInfor,szTemp;
	HANDLE 	hDevice;
	BOOL   bResult;
	DWORD dwOutBytes;
	
	GET_MEDIA_TYPES *pmt;	
	
	memset(szBuf,0,100);
	DWORD len = GetLogicalDriveStrings(sizeof(szBuf)/sizeof(TCHAR),szBuf);	
	for (s = szBuf; *s; s += _tcslen(s)+1)
	{	
		LPCTSTR sDrivePath = s;		
		TRACE("\r\n%s \r\n",sDrivePath);
		
		TCHAR szPath[100] = _T("\\\\.\\");
		::_tcscat(szPath,sDrivePath);
		int nSize = ::_tcslen(szPath);
		szPath[nSize-1] = '\0';	
		
		szTemp.Empty();
		szTemp += szPath[nSize-3];	
		szTemp += szPath[nSize-2];
		
		UINT uDriveType = GetDriveType(sDrivePath);
		if(uDriveType == DRIVE_REMOVABLE)//可移动删除类设备(软驱、USB设备)
		{
			szTemp += "  DRIVE_REMOVABLE--";
			// 打开设备
            hDevice = ::CreateFile(szPath,           // 文件名
				GENERIC_READ,                          // 软驱需要读盘
				FILE_SHARE_READ | FILE_SHARE_WRITE,    // 共享方式
				NULL,                                  // 默认的安全描述符
				OPEN_EXISTING,                         // 创建方式
				0,                                     // 不需设置文件属性
				NULL);                                 // 不需参照模板文件
			
			if (hDevice != INVALID_HANDLE_VALUE)//打开成功
			{
				bResult = ::DeviceIoControl(hDevice,       // 设备句柄
					IOCTL_DISK_GET_DRIVE_GEOMETRY,         // 取磁盘参数
					NULL, 0,                               // 不需要输入数据
					&dg, sizeof(DISK_GEOMETRY),            // 输出数据缓冲区
					&dwOutBytes,                           // 输出数据长度
					(LPOVERLAPPED)NULL);                   // 用同步I/O
				
				// 如果失败,再用IOCTL_STORAGE_GET_MEDIA_TYPES_EX取介质类型参数
				if (!bResult)
				{
					pmt = (GET_MEDIA_TYPES *)new BYTE[MEDIA_INFO_SIZE];
					
					bResult = ::DeviceIoControl(hDevice,    // 设备句柄
						IOCTL_STORAGE_GET_MEDIA_TYPES_EX,   // 取介质类型参数
						NULL, 0,                            // 不需要输入数据
						pmt, MEDIA_INFO_SIZE,               // 输出数据缓冲区
						&dwOutBytes,                        // 输出数据长度
						(LPOVERLAPPED)NULL);                // 用同步I/O
					
					if (bResult)
					{
						// 注意到结构DEVICE_MEDIA_INFO是在结构DISK_GEOMETRY的基础上扩充的
						// 为简化程序,用memcpy代替如下多条赋值语句:
						// pdg->MediaType = (MEDIA_TYPE)pmt->MediaInfo[0].DeviceSpecific.DiskInfo.MediaType;
						// pdg->Cylinders = pmt->MediaInfo[0].DeviceSpecific.DiskInfo.Cylinders;
						// pdg->TracksPerCylinder = pmt->MediaInfo[0].DeviceSpecific.DiskInfo.TracksPerCylinder;
						// ... ...
						::memcpy(&dg, pmt->MediaInfo, sizeof(DISK_GEOMETRY));
					}
					
					delete pmt;
				}
				if(dg.MediaType != RemovableMedia)
				{
					szFloppyBuf[nFloppyNumber] = szPath[nSize-3];
					nFloppyNumber++;
					
				}
			}			
			// 关闭设备句柄
			::CloseHandle(hDevice);			
		}	
		szInfor += szTemp;
		szInfor += "\r\n\r\n";
	}	
	return true;
}


void CDiskMountDlg::OnButton2() 
{
	// TODO: Add your control notification handler code here
	CString szInfor;
	int nFloppyNumber=0;//定义软驱数量
	TCHAR szFloppyBuf[10];//软驱盘符
	memset(szFloppyBuf,0,10);
	szFloppyBuf[0]=0;
	GetFloppyLetter(szFloppyBuf,nFloppyNumber);
	if(nFloppyNumber)
		szInfor.Format("总共有%d个软驱,盘符分别为:\r\n\r\n",nFloppyNumber);
	else
		szInfor.Format("不存在软驱!");

	for(int i=0;i<nFloppyNumber;i++)
	{		
		szInfor +=szFloppyBuf[i];
		szInfor +="\r\n";
		SetDlgItemText(IDC_EDIT1,szInfor);	
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -