📄 util-win32.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 + -