2,643
社区成员




// DeviceEnumeratorDlg.cpp : implementation file
//
#include "stdafx.h"
#include "DeviceEnumerator.h"
#include "DeviceEnumeratorDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define MEDIA_INFO_SIZE sizeof(GET_MEDIA_TYPES)+15*sizeof(DEVICE_MEDIA_INFO)
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
/////////////////////////////////////////////////////////////////////////////
// CDeviceEnumeratorDlg dialog
CDeviceEnumeratorDlg::CDeviceEnumeratorDlg(CWnd* pParent /*=NULL*/)
: CDialog(CDeviceEnumeratorDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CDeviceEnumeratorDlg)
// 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 CDeviceEnumeratorDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDeviceEnumeratorDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDeviceEnumeratorDlg, CDialog)
//{{AFX_MSG_MAP(CDeviceEnumeratorDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDeviceEnumeratorDlg message handlers
BOOL CDeviceEnumeratorDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 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 CDeviceEnumeratorDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
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 CDeviceEnumeratorDlg::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 CDeviceEnumeratorDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CDeviceEnumeratorDlg::OnOK()
{
const char *szDevName[]=
{
"\\\\.\\A:",
"\\\\.\\B:",
"\\\\.\\PhysicalDrive0",
"\\\\.\\PhysicalDrive1",
"\\\\.\\PhysicalDrive2",
"\\\\.\\PhysicalDrive3",
"\\\\.\\PhysicalDrive4",
"\\\\.\\PhysicalDrive5",
"\\\\.\\PhysicalDrive6",
"\\\\.\\Cdrom0",
"\\\\.\\Cdrom1",
};
DISK_GEOMETRY dg;
ULONGLONG DiskSize;
BOOL bResult;
CString strMsg;
CString strTmp;
for (int i = 0; i < sizeof(szDevName)/sizeof(char*); i++)
{
bResult = GetDriveGeometry(szDevName[i], &dg);
strTmp.Format("\r\n%s result = %s\r\n", szDevName[i], bResult ? "success" : "failure");
strMsg+=strTmp;
if (!bResult) continue;
strTmp.Format(" Media Type = %d\r\n", dg.MediaType);
strMsg+=strTmp;
strTmp.Format(" Cylinders = %I64d\r\n", dg.Cylinders);
strMsg+=strTmp;
strTmp.Format(" Tracks per cylinder = %ld\r\n", (ULONG) dg.TracksPerCylinder);
strMsg+=strTmp;
strTmp.Format(" Sectors per track = %ld\r\n", (ULONG) dg.SectorsPerTrack);
strMsg+=strTmp;
strTmp.Format(" Bytes per sector = %ld\r\n", (ULONG) dg.BytesPerSector);
strMsg+=strTmp;
DiskSize = dg.Cylinders.QuadPart * (ULONG)dg.TracksPerCylinder *
(ULONG)dg.SectorsPerTrack * (ULONG)dg.BytesPerSector;
strTmp.Format(" Disk size = %I64d (Bytes) = %I64d (Mb)\r\n", DiskSize, DiskSize / (1024 * 1024));
strMsg+=strTmp;
}
AfxMessageBox(strMsg);
}
BOOL CDeviceEnumeratorDlg::GetDriveGeometry(const char* 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);
}
// DeviceEnumeratorDlg.h : header file
//
#if !defined(AFX_DEVICEENUMERATORDLG_H__6A28E8D3_F1D4_44F2_9040_103D484ABD57__INCLUDED_)
#define AFX_DEVICEENUMERATORDLG_H__6A28E8D3_F1D4_44F2_9040_103D484ABD57__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <winioctl.h>
/////////////////////////////////////////////////////////////////////////////
// CDeviceEnumeratorDlg dialog
class CDeviceEnumeratorDlg : public CDialog
{
// Construction
public:
CDeviceEnumeratorDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CDeviceEnumeratorDlg)
enum { IDD = IDD_DEVICEENUMERATOR_DIALOG };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDeviceEnumeratorDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CDeviceEnumeratorDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
virtual void OnOK();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
BOOL GetDriveGeometry(const char* filename, DISK_GEOMETRY *pdg);
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_DEVICEENUMERATORDLG_H__6A28E8D3_F1D4_44F2_9040_103D484ABD57__INCLUDED_)