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

📄 pvrhddbenchdlg.cpp

📁 HDD benchmark tool - microsoft visual C++
💻 CPP
字号:
// PvrHDDBenchDlg.cpp : implementation file
//

#include "stdafx.h"
#include "PvrHDDBench.h"
#include "PvrHDDBenchDlg.h"

#include <winioctl.h>

#include "vcplot.h"
#include "vcaxis.h"
#include "vcaxisscale.h"
#include "vctick.h"
#include "vcvaluescale.h"

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

/////////////////////////////////////////////////////////////////////////////
// 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()

/////////////////////////////////////////////////////////////////////////////
// CPvrHDDBenchDlg dialog

CPvrHDDBenchDlg::CPvrHDDBenchDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CPvrHDDBenchDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CPvrHDDBenchDlg)
	m_StrCurDrive		= _T("NO DRIVE SELECTED");
	m_BlkSize	= 4;
	m_NrOfRW	= 16;
	//}}AFX_DATA_INIT
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

	
	m_CurHDD				= -1; // no drive selected  
	
	m_hSelectedDrive		= INVALID_HANDLE_VALUE;
}

void CPvrHDDBenchDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CPvrHDDBenchDlg)
	DDX_Control(pDX, IDC_PROGRESS, m_Progress);
	DDX_Control(pDX, IDC_HDDLIST, m_HDDList);			
	DDX_Text(pDX, IDC_DRIVEID, m_StrCurDrive);
	DDX_Control(pDX, IDC_MSCHART2, m_Chart);
	DDX_Text(pDX, IDC_BLKSIZE, m_BlkSize);
	DDV_MinMaxDWord(pDX, m_BlkSize, 4, 1024);
	DDX_Text(pDX, IDC_NROFRW, m_NrOfRW);
	DDV_MinMaxDWord(pDX, m_NrOfRW, 2, 1024);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CPvrHDDBenchDlg, CDialog)
	//{{AFX_MSG_MAP(CPvrHDDBenchDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_NOTIFY(NM_DBLCLK, IDC_HDDLIST, OnDblclkHddlist)
	ON_WM_HSCROLL()
	ON_BN_CLICKED(IDC_BUTTON1, OnBenchmark)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPvrHDDBenchDlg message handlers

BOOL CPvrHDDBenchDlg::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);
		}
	}

	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	FindSystemDrives();

	// init interface values 
	// let's take care of sliders 
	UpdateData(TRUE);
	m_StrCurDrive.Format("NO DRIVE SELECTED");
	UpdateData(FALSE);
	// init interface values 



	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CPvrHDDBenchDlg::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 CPvrHDDBenchDlg::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();
	}
}

HCURSOR CPvrHDDBenchDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}


void
CPvrHDDBenchDlg::FindSystemDrives()
{
	CString StrDriveName;
	short	DriveNumber;
	HANDLE	hDrive;

	// try to find physical drive 0 (should exist !!!)
	DriveNumber = 0;
	StrDriveName.Format("\\\\.\\PHYSICALDRIVE%d",DriveNumber);
	hDrive = CreateFile(StrDriveName,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);	

	while(hDrive != INVALID_HANDLE_VALUE)
	{
		CloseHandle(hDrive);
		m_HDDList.InsertItem(DriveNumber,StrDriveName);
		// try to find another physical drive 
		DriveNumber++;
		StrDriveName.Format("\\\\.\\PHYSICALDRIVE%d",DriveNumber);
		hDrive = CreateFile(StrDriveName,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);		
	}

	CloseHandle(hDrive);
}

void CPvrHDDBenchDlg::OnDblclkHddlist(NMHDR* pNMHDR, LRESULT* pResult) 
{	
	*pResult = 0;
	
	// make this disk the current benchmarked disk 
	CListCtrl*	pList = (CListCtrl*) GetDlgItem(pNMHDR->idFrom);
	POSITION	pos	  = pList->GetFirstSelectedItemPosition();
	if(pos)
	{
		// find the selected HDD
		int nItem	= pList->GetNextSelectedItem(pos);
		if(nItem==0) return; // do not allow to choose physical drive 0
		m_CurHDD	= (SHORT) nItem;
		
		UpdateBenchDrive();		
		UpdateBenchParams();

	}
}

void CPvrHDDBenchDlg::UpdateBenchDrive()
{
	CString			StrDriveName;
	DISK_GEOMETRY	geometry;
	DWORD			breturn;

	if(m_hSelectedDrive != INVALID_HANDLE_VALUE)
	{
		CloseHandle(m_hSelectedDrive);
		m_hSelectedDrive = INVALID_HANDLE_VALUE;
	}

	StrDriveName.Format("\\\\.\\PHYSICALDRIVE%d",m_CurHDD);
	m_hSelectedDrive = CreateFile(StrDriveName,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);	

	// get information about drive geometry :)
	DeviceIoControl(m_hSelectedDrive,IOCTL_DISK_GET_DRIVE_GEOMETRY,NULL,0,&geometry,sizeof(DISK_GEOMETRY),&breturn,NULL);
	
	// we need to have the drive size ! 
	m_DriveSize = geometry.Cylinders.QuadPart*geometry.TracksPerCylinder*geometry.SectorsPerTrack*geometry.BytesPerSector;

	UpdateData(TRUE);
	m_StrCurDrive.Format("%s IS SELECTED [ %I64u cyl | %Lu tracks/cyl | %Lu sec/track | %Lu bytes/sec | %.2f GBytes ]" , StrDriveName,
																													 geometry.Cylinders.QuadPart,
																													 geometry.TracksPerCylinder,
																													 geometry.SectorsPerTrack,
																													 geometry.BytesPerSector,
																													 (float)m_DriveSize/(1024*1024*1024));
	UpdateData(FALSE);

}

void CPvrHDDBenchDlg::UpdateBenchParams()
{
}

void CPvrHDDBenchDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
}


#define SET_XY_READ(i,xv,yv)		index[0]=i;index[1]=0;saResults.PutElement(index,COleVariant(xv));\
									index[0]=i;index[1]=1;saResults.PutElement(index,COleVariant(yv));
									
#define SET_XY_WRITE(i,xv,yv)		index[0]=i;index[1]=2;saResults.PutElement(index,COleVariant(xv));\
									index[0]=i;index[1]=3;saResults.PutElement(index,COleVariant(yv));
void CPvrHDDBenchDlg::OnBenchmark() 
{
	DWORD			CurrentCtlPoint;
	DWORD			CurrentRW;
	DWORD			BytesRead;
	DWORD			BytesWritten;
	LONG			OffsetLow;
	LONG			OffsetHigh;
	__int64			CurrentReadOffset,CurrentWriteOffset;
	__int64			CurrentReadBaseOffset,CurrentWriteBaseOffset;
	__int64			CtlPointDistance;

	UCHAR			*pReadBuffer;
	UCHAR			*pWriteBuffer;
	
	//// Update the data, so that we have the current values 
	UpdateData(TRUE);
	UpdateData(FALSE);
	////

	COleSafeArray	saResults; 
	DWORD			nElts[2];
	long			index[2];

	double			readrate,writerate;
	double			readbase,writebase;
	double			time;

	CtlPointDistance	= m_BlkSize * m_NrOfRW * 1024; 
	m_NrofControlPoints = m_DriveSize/CtlPointDistance;

	m_Progress.SetRange32(0,m_NrofControlPoints);
	m_Progress.SetPos(0);

	pReadBuffer  = new UCHAR[1024*m_BlkSize];
	pWriteBuffer = new UCHAR[1024*m_BlkSize];

	QueryPerformanceFrequency(&m_CounterFrequency);

	// create the safearray that will hold the datas 
	nElts[0] = m_NrofControlPoints;
	nElts[1] = 4;
	saResults.Create(VT_VARIANT,2,nElts);

	for(CurrentCtlPoint=0;CurrentCtlPoint<m_NrofControlPoints;CurrentCtlPoint++)
	{
		CurrentReadBaseOffset	= CurrentCtlPoint * CtlPointDistance;
		CurrentWriteBaseOffset	= (m_NrofControlPoints-CurrentCtlPoint-1)*CtlPointDistance;
		
		CurrentReadOffset	= CurrentReadBaseOffset;
		CurrentWriteOffset	= CurrentWriteBaseOffset;

		 
		for(CurrentRW=0;CurrentRW<m_NrOfRW;CurrentRW++)
		{
			// Read Operation 
			if(!CurrentRW) QueryPerformanceCounter(&m_ReadStartTime); // start the counter
			OffsetHigh = (LONG)(CurrentReadOffset >> 32);
			OffsetLow  = (LONG)(CurrentReadOffset &  0x00000000FFFFFFFF);
			SetFilePointer(m_hSelectedDrive,OffsetLow,&OffsetHigh,FILE_BEGIN);
			ReadFile(m_hSelectedDrive,pReadBuffer,1024*m_BlkSize,&BytesRead,NULL);
		
			if(CurrentRW == (m_NrOfRW-1)) 
				QueryPerformanceCounter(&m_ReadStopTime); // stop the counter 


			// Write Operation 
			if(!CurrentRW) QueryPerformanceCounter(&m_WriteStartTime); // start the counter 
			OffsetHigh = (LONG)(CurrentWriteOffset >> 32);
			OffsetLow  = (LONG)(CurrentWriteOffset &  0x00000000FFFFFFFF);
			SetFilePointer(m_hSelectedDrive,OffsetLow,&OffsetHigh,FILE_BEGIN);
			WriteFile(m_hSelectedDrive,pWriteBuffer,1024*m_BlkSize,&BytesWritten,NULL);
		
			CurrentReadOffset  += (1024*m_BlkSize);
			CurrentWriteOffset += (1024*m_BlkSize);
		}

		QueryPerformanceCounter(&m_WriteStopTime); // stop the counter

		time	  = (double)(m_WriteStopTime.QuadPart - m_WriteStartTime.QuadPart)/m_CounterFrequency.QuadPart;
		writerate = (double)(m_BlkSize*m_NrOfRW)/(1024*time);

		time	 = (double)(m_ReadStopTime.QuadPart - m_ReadStartTime.QuadPart)/m_CounterFrequency.QuadPart;
		readrate = (double)(m_BlkSize*m_NrOfRW)/(1024*time);

		readbase	= (double)(CurrentReadBaseOffset  + (double)CtlPointDistance/2)/(1024*1024*1024);
		writebase	= (double)(CurrentWriteBaseOffset + (double)CtlPointDistance/2)/(1024*1024*1024);

		SET_XY_READ(CurrentCtlPoint,readbase,(double)readrate);
		SET_XY_WRITE(CurrentCtlPoint,writebase,(double)writerate);

		m_Progress.SetPos(CurrentCtlPoint);
	}	

	delete pReadBuffer;
	delete pWriteBuffer;	

	// just make sure the graph looks 'good' !!
	VARIANT			idx;
	CVcPlot			plot	= m_Chart.GetPlot();
	plot.SetAutoLayout(FALSE);	
	idx.decVal.sign = 1;
	CVcAxis			xaxis	= plot.GetAxis(0,idx);
	CVcValueScale	xvscale = xaxis.GetValueScale();

	plot.SetUniformAxis(FALSE);
	xvscale.SetAuto(FALSE);
	xvscale.SetMinimum(0.0);
	xvscale.SetMaximum((double)m_DriveSize/(1024*1024*1024)); 
	//
		
	m_Chart.SetChartData(saResults.Detach());
	m_Chart.SetColumnCount(4);
	m_Chart.SetRowCount((short)m_NrofControlPoints);
	m_Chart.SetColumn(1);m_Chart.SetColumnLabel("READ");
	m_Chart.SetColumn(3);m_Chart.SetColumnLabel("WRITE");
	m_Chart.Refresh();

}




⌨️ 快捷键说明

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