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

📄 util-win32.c

📁 Console HDD performance test for windows or unix
💻 C
字号:
#include <windows.h>
#include <stdio.h>
#include "util.h"


#define IDLE_PROCESS_ID 4


char def_device[]="C:";

static HANDLE idle_proc;

static long_long perf_mul=0;

int hdd_prepare()
{
	SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS);
	SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_HIGHEST);
	SetThreadAffinityMask(GetCurrentThread(),1);
	if (!QueryPerformanceFrequency((LARGE_INTEGER*)&perf_mul)) return -1;
	perf_mul/=1000000L;
	idle_proc=OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,IDLE_PROCESS_ID);
	if (!idle_proc) {
		fprintf(stderr,"can't open idle process: %s\n",hdd_error_msg());
		return -2;
	}
	return 0;
}

static void show_errname(const char*name,const char*msg)
{
	fprintf(stderr,"error: %s: invalid device name format (%s)\nvalid formats are:\n\tX:\twhere X - logical drive letter;\n\tN:\twhere N - physical drive number\n\t{GUID}\twhere GUID - volume identifier\n",name,msg);
} 

int  open_hdd(const char*name)
{
	char buf[256];
	int l=strlen(name);
	if (name[0]=='{') {
		if (l<3||name[l-1]!='}') {
			show_errname(name,"invalid GUID");
			return -1;
		}
		wsprintf(buf,TEXT("\\\\?\\Volume%s"),name);
	} else {
		if (l!=2||name[1]!=':') {
			show_errname(name,"generic syntax error");
			return -1;
		}
		if (isdigit(name[0])) {
			wsprintf(buf,TEXT("\\\\.\\PHYSICALDRIVE%c"),name[0]);
		} else if (isalpha(name[0])) {
			wsprintf(buf,TEXT("\\\\.\\%c:"),name[0]);
		} else {
			show_errname(name,"invalid drive letter");
			return -1;
		}
	}
	return (int)CreateFile(buf,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING,NULL);
}


void close_hdd(int handle)
{
	CloseHandle((HANDLE)handle);
}

int  read_hdd(int handle,struct HDD_INFO*info,long_long blk,int count,void*buffer)
{
	DWORD nb;
	union {
		long_long pos;
		long x[2];
	} r;
	r.pos=(long_long)blk*info->block_size;
	SetFilePointer((HANDLE)handle,r.x[0],r.x+1,FILE_BEGIN);
	if (!ReadFile((HANDLE)handle,buffer,count*info->block_size,&nb,NULL)) return 0;
	return nb/info->block_size;
}

int  read_hdd_cur(int handle,struct HDD_INFO*info,int count,void*buffer)
{
	DWORD nb;
	if (!ReadFile((HANDLE)handle,buffer,count*info->block_size,&nb,NULL)) return 0;
	return nb/info->block_size;
}

int  seek_hdd(int handle,struct HDD_INFO*info,long_long blk)
{
	union {
		long_long pos;
		long x[2];
	} r;
	r.pos=(long_long)blk*info->block_size;
	SetFilePointer((HANDLE)handle,r.x[0],r.x+1,FILE_BEGIN);
	return 0;
}


int get_execution_times(long_long*user,long_long*kernel)
{
	long_long tc, te;
	if (!GetThreadTimes(GetCurrentThread(),(FILETIME*)&tc,(FILETIME*)&te,(FILETIME*)kernel,(FILETIME*)user)) return -1;
	(*user)/=10;
	(*kernel)/=10;
	return 0;
}


int get_idle_time(long_long*res)
{
	long_long tc, te, tu, tk;
	if (!GetProcessTimes(idle_proc,(FILETIME*)&tc,(FILETIME*)&te,(FILETIME*)&tk,(FILETIME*)&tu)) return -1;
	*res=(tu+tk)/10;
	return 0;
}

long_long get_system_time()
{
	long_long res;
	QueryPerformanceCounter((LARGE_INTEGER*)&res);
	res/=perf_mul;
	return res;
}

int get_hdd_info(int handle,struct HDD_INFO*info)
{
	DISK_GEOMETRY geom;
	PARTITION_INFORMATION pinf;
	DWORD ret;
	if (!DeviceIoControl((HANDLE)handle,IOCTL_DISK_GET_DRIVE_GEOMETRY,NULL,0,&geom,sizeof(geom),&ret,NULL)) return -1;
	info->block_size=geom.BytesPerSector;
	if (!DeviceIoControl((HANDLE)handle,IOCTL_DISK_GET_PARTITION_INFO,NULL,0,&pinf,sizeof(pinf),&ret,NULL)) {
		info->n_blocks=geom.Cylinders.QuadPart*geom.TracksPerCylinder*geom.SectorsPerTrack;
	} else {
		info->n_blocks=pinf.PartitionLength.QuadPart/info->block_size;
	}
	return 0;
}


void*alloc_hdd_buffer(struct HDD_INFO*info,int nsec)
{
	return VirtualAlloc(NULL,nsec*info->block_size,MEM_COMMIT,PAGE_READWRITE);
}


void free_hdd_buffer(void*mem,struct HDD_INFO*info,int nsec)
{
	VirtualFree(mem,nsec*info->block_size,MEM_DECOMMIT);
}


char*hdd_error_msg()
{
	static char msgbuf[MAX_PATH];
	int err=GetLastError();
	msgbuf[0]=0;
	FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
		NULL,err,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
		msgbuf,sizeof(msgbuf),NULL);
	return msgbuf;
}

⌨️ 快捷键说明

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