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

📄 os_win32.cpp

📁 硬盘各项性能的测试,如温度容量版本健康度型号
💻 CPP
📖 第 1 页 / 共 5 页
字号:
         "  smartctl -a /dev/hda                       (Prints all SMART information)\n\n"#ifdef HAVE_GETOPT_LONG         "  smartctl --smart=on --offlineauto=on --saveauto=on /dev/hda\n"         "                                              (Enables SMART on first disk)\n\n"         "  smartctl -t long /dev/hda              (Executes extended disk self-test)\n\n"         "  smartctl --attributes --log=selftest --quietmode=errorsonly /dev/hda\n"         "                                      (Prints Self-Test & Attribute errors)\n"#else         "  smartctl -s on -o on -S on /dev/hda         (Enables SMART on first disk)\n"         "  smartctl -t long /dev/hda              (Executes extended disk self-test)\n"         "  smartctl -A -l selftest -q errorsonly /dev/hda\n"         "                                      (Prints Self-Test & Attribute errors)\n"#endif         "  smartctl -a /dev/scsi21\n"         "             (Prints all information for SCSI disk on ASPI adapter 2, ID 1)\n"         "  smartctl -a /dev/sda\n"         "             (Prints all information for SCSI disk on PhysicalDrive 0)\n"         "  smartctl -a /dev/pd3\n"         "             (Prints all information for SCSI disk on PhysicalDrive 3)\n"         "  smartctl -a /dev/tape1\n"         "             (Prints all information for SCSI tape on Tape 1)\n"         "  smartctl -A /dev/hdb,3\n"         "                (Prints Attributes for physical drive 3 on 3ware 9000 RAID)\n"         "  smartctl -A /dev/tw_cli/c0/p1\n"         "            (Prints Attributes for 3ware controller 0, port 1 using tw_cli)\n"         "\n"         "  ATA SMART access methods and ordering may be specified by modifiers\n"         "  following the device name: /dev/hdX:[saicm], where\n"         "  's': SMART_* IOCTLs,         'a': IOCTL_ATA_PASS_THROUGH,\n"         "  'i': IOCTL_IDE_PASS_THROUGH, 'c': ATA via IOCTL_SCSI_PASS_THROUGH,\n"         "  'f': IOCTL_STORAGE_*,        'm': IOCTL_SCSI_MINIPORT_*.\n"         "  The default on this system is /dev/sdX:%s\n", ata_get_def_options()  );}/////////////////////////////////////////////////////////////////////////////// ATA Interface/////////////////////////////////////////////////////////////////////////////// SMART_* IOCTLs, also known as DFP_* (Disk Fault Protection)#define FILE_READ_ACCESS       0x0001#define FILE_WRITE_ACCESS      0x0002#define METHOD_BUFFERED             0#define CTL_CODE(DeviceType, Function, Method, Access) (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))#define FILE_DEVICE_DISK	   7#define IOCTL_DISK_BASE        FILE_DEVICE_DISK#define SMART_GET_VERSION \  CTL_CODE(IOCTL_DISK_BASE, 0x0020, METHOD_BUFFERED, FILE_READ_ACCESS)#define SMART_SEND_DRIVE_COMMAND \  CTL_CODE(IOCTL_DISK_BASE, 0x0021, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)#define SMART_RCV_DRIVE_DATA \  CTL_CODE(IOCTL_DISK_BASE, 0x0022, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)ASSERT_CONST(SMART_GET_VERSION       , 0x074080);ASSERT_CONST(SMART_SEND_DRIVE_COMMAND, 0x07c084);ASSERT_CONST(SMART_RCV_DRIVE_DATA    , 0x07c088);#define SMART_CYL_LOW  0x4F#define SMART_CYL_HI   0xC2#pragma pack(1)typedef struct _GETVERSIONOUTPARAMS {	UCHAR  bVersion;	UCHAR  bRevision;	UCHAR  bReserved;	UCHAR  bIDEDeviceMap;	ULONG  fCapabilities;	ULONG  dwReserved[4];} GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS;ASSERT_SIZEOF(GETVERSIONOUTPARAMS, 24);#define SMART_VENDOR_3WARE      0x13C1  // identifies 3ware specific parameterstypedef struct _GETVERSIONINPARAMS_EX {	BYTE    bVersion;	BYTE    bRevision;	BYTE    bReserved;	BYTE    bIDEDeviceMap;	DWORD   fCapabilities;	DWORD   dwDeviceMapEx;  // 3ware specific: RAID drive bit map	WORD    wIdentifier;    // Vendor specific identifier	WORD    wControllerId;  // 3ware specific: Controller ID (0,1,...)	ULONG   dwReserved[2];} GETVERSIONINPARAMS_EX, *PGETVERSIONINPARAMS_EX, *LPGETVERSIONINPARAMS_EX;ASSERT_SIZEOF(GETVERSIONINPARAMS_EX, sizeof(GETVERSIONOUTPARAMS));typedef struct _IDEREGS {	UCHAR  bFeaturesReg;	UCHAR  bSectorCountReg;	UCHAR  bSectorNumberReg;	UCHAR  bCylLowReg;	UCHAR  bCylHighReg;	UCHAR  bDriveHeadReg;	UCHAR  bCommandReg;	UCHAR  bReserved;} IDEREGS, *PIDEREGS, *LPIDEREGS;typedef struct _SENDCMDINPARAMS {	ULONG  cBufferSize;	IDEREGS  irDriveRegs;	UCHAR  bDriveNumber;	UCHAR  bReserved[3];	ULONG  dwReserved[4];	UCHAR  bBuffer[1];} SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;ASSERT_SIZEOF(SENDCMDINPARAMS, 32+1);typedef struct _SENDCMDINPARAMS_EX {	DWORD   cBufferSize;	IDEREGS irDriveRegs;	BYTE    bDriveNumber;	BYTE    bPortNumber;   // 3ware specific: port number	WORD    wIdentifier;   // Vendor specific identifier	DWORD   dwReserved[4];	BYTE    bBuffer[1];} SENDCMDINPARAMS_EX, *PSENDCMDINPARAMS_EX, *LPSENDCMDINPARAMS_EX;ASSERT_SIZEOF(SENDCMDINPARAMS_EX, sizeof(SENDCMDINPARAMS));/* DRIVERSTATUS.bDriverError constants (just for info, not used)#define SMART_NO_ERROR                    0#define SMART_IDE_ERROR                   1#define SMART_INVALID_FLAG                2#define SMART_INVALID_COMMAND             3#define SMART_INVALID_BUFFER              4#define SMART_INVALID_DRIVE               5#define SMART_INVALID_IOCTL               6#define SMART_ERROR_NO_MEM                7#define SMART_INVALID_REGISTER            8#define SMART_NOT_SUPPORTED               9#define SMART_NO_IDE_DEVICE               10*/typedef struct _DRIVERSTATUS {	UCHAR  bDriverError;	UCHAR  bIDEError;	UCHAR  bReserved[2];	ULONG  dwReserved[2];} DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS;typedef struct _SENDCMDOUTPARAMS {	ULONG  cBufferSize;	DRIVERSTATUS  DriverStatus;	UCHAR  bBuffer[1];} SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS;ASSERT_SIZEOF(SENDCMDOUTPARAMS, 16+1);#pragma pack()/////////////////////////////////////////////////////////////////////////////static void print_ide_regs(const IDEREGS * r, int out){	pout("%s=0x%02x,%s=0x%02x, SC=0x%02x, SN=0x%02x, CL=0x%02x, CH=0x%02x, SEL=0x%02x\n",	(out?"STS":"CMD"), r->bCommandReg, (out?"ERR":" FR"), r->bFeaturesReg,	r->bSectorCountReg, r->bSectorNumberReg, r->bCylLowReg, r->bCylHighReg, r->bDriveHeadReg);}static void print_ide_regs_io(const IDEREGS * ri, const IDEREGS * ro){	pout("    Input : "); print_ide_regs(ri, 0);	if (ro) {		pout("    Output: "); print_ide_regs(ro, 1);	}}/////////////////////////////////////////////////////////////////////////////// call SMART_GET_VERSION, return device map or -1 on errorstatic int smart_get_version(HANDLE hdevice, GETVERSIONINPARAMS_EX * ata_version_ex = 0){	GETVERSIONOUTPARAMS vers; memset(&vers, 0, sizeof(vers));	const GETVERSIONINPARAMS_EX & vers_ex = (const GETVERSIONINPARAMS_EX &)vers;	DWORD num_out;	if (!DeviceIoControl(hdevice, SMART_GET_VERSION,		NULL, 0, &vers, sizeof(vers), &num_out, NULL)) {		if (con->reportataioctl)			pout("  SMART_GET_VERSION failed, Error=%ld\n", GetLastError());		errno = ENOSYS;		return -1;	}	assert(num_out == sizeof(GETVERSIONOUTPARAMS));	if (con->reportataioctl > 1) {		pout("  SMART_GET_VERSION suceeded, bytes returned: %lu\n"		     "    Vers = %d.%d, Caps = 0x%lx, DeviceMap = 0x%02x\n",			num_out, vers.bVersion, vers.bRevision,			vers.fCapabilities, vers.bIDEDeviceMap);		if (vers_ex.wIdentifier == SMART_VENDOR_3WARE)			pout("    Identifier = %04x(3WARE), ControllerId=%u, DeviceMapEx = 0x%08lx\n",			vers_ex.wIdentifier, vers_ex.wControllerId, vers_ex.dwDeviceMapEx);	}	if (ata_version_ex)		*ata_version_ex = vers_ex;	// TODO: Check vers.fCapabilities here?	return vers.bIDEDeviceMap;}// call SMART_* ioctlstatic int smart_ioctl(HANDLE hdevice, int drive, IDEREGS * regs, char * data, unsigned datasize, int port){	SENDCMDINPARAMS inpar;	SENDCMDINPARAMS_EX & inpar_ex = (SENDCMDINPARAMS_EX &)inpar;	unsigned char outbuf[sizeof(SENDCMDOUTPARAMS)-1 + 512];	const SENDCMDOUTPARAMS * outpar;	DWORD code, num_out;	unsigned int size_out;	const char * name;	memset(&inpar, 0, sizeof(inpar));	inpar.irDriveRegs = *regs;	// drive is set to 0-3 on Win9x only	inpar.irDriveRegs.bDriveHeadReg = 0xA0 | ((drive & 1) << 4);	inpar.bDriveNumber = drive;	if (port >= 0) {		// Set RAID port		inpar_ex.wIdentifier = SMART_VENDOR_3WARE;		inpar_ex.bPortNumber = port;	}	assert(datasize == 0 || datasize == 512);	if (datasize) {		code = SMART_RCV_DRIVE_DATA; name = "SMART_RCV_DRIVE_DATA";		inpar.cBufferSize = size_out = 512;	}	else {		code = SMART_SEND_DRIVE_COMMAND; name = "SMART_SEND_DRIVE_COMMAND";		if (regs->bFeaturesReg == ATA_SMART_STATUS)			size_out = sizeof(IDEREGS); // ioctl returns new IDEREGS as data			// Note: cBufferSize must be 0 on Win9x		else			size_out = 0;	}	memset(&outbuf, 0, sizeof(outbuf));	if (!DeviceIoControl(hdevice, code, &inpar, sizeof(SENDCMDINPARAMS)-1,		outbuf, sizeof(SENDCMDOUTPARAMS)-1 + size_out, &num_out, NULL)) {		// CAUTION: DO NOT change "regs" Parameter in this case, see ata_command_interface()		long err = GetLastError();		if (con->reportataioctl && (err != ERROR_INVALID_PARAMETER || con->reportataioctl > 1)) {			pout("  %s failed, Error=%ld\n", name, err);			print_ide_regs_io(regs, NULL);		}		errno = (   err == ERROR_INVALID_FUNCTION/*9x*/		         || err == ERROR_INVALID_PARAMETER/*NT/2K/XP*/		         || err == ERROR_NOT_SUPPORTED ? ENOSYS : EIO);		return -1;	}	// NOTE: On Win9x, inpar.irDriveRegs now contains the returned regs	outpar = (const SENDCMDOUTPARAMS *)outbuf;	if (outpar->DriverStatus.bDriverError) {		if (con->reportataioctl) {			pout("  %s failed, DriverError=0x%02x, IDEError=0x%02x\n", name,				outpar->DriverStatus.bDriverError, outpar->DriverStatus.bIDEError);			print_ide_regs_io(regs, NULL);		}		errno = (!outpar->DriverStatus.bIDEError ? ENOSYS : EIO);		return -1;	}	if (con->reportataioctl > 1) {		pout("  %s suceeded, bytes returned: %lu (buffer %lu)\n", name,			num_out, outpar->cBufferSize);		print_ide_regs_io(regs, (regs->bFeaturesReg == ATA_SMART_STATUS ?			(const IDEREGS *)(outpar->bBuffer) : NULL));	}	if (datasize)		memcpy(data, outpar->bBuffer, 512);	else if (regs->bFeaturesReg == ATA_SMART_STATUS) {		if (nonempty(const_cast<unsigned char *>(outpar->bBuffer), sizeof(IDEREGS)))			*regs = *(const IDEREGS *)(outpar->bBuffer);		else {  // Workaround for driver not returning regs			if (con->reportataioctl)				pout("  WARNING: driver does not return ATA registers in output buffer!\n");			*regs = inpar.irDriveRegs;		}	}	return 0;}/////////////////////////////////////////////////////////////////////////////// IDE PASS THROUGH (2000, XP, undocumented)//// Based on WinATA.cpp, 2002 c't/Matthias Withopf// ftp://ftp.heise.de/pub/ct/listings/0207-218.zip#define FILE_DEVICE_CONTROLLER  4#define IOCTL_SCSI_BASE         FILE_DEVICE_CONTROLLER#define IOCTL_IDE_PASS_THROUGH \  CTL_CODE(IOCTL_SCSI_BASE, 0x040A, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)ASSERT_CONST(IOCTL_IDE_PASS_THROUGH, 0x04d028);#pragma pack(1)typedef struct {	IDEREGS IdeReg;	ULONG   DataBufferSize;	UCHAR   DataBuffer[1];} ATA_PASS_THROUGH;ASSERT_SIZEOF(ATA_PASS_THROUGH, 12+1);#pragma pack()/////////////////////////////////////////////////////////////////////////////static int ide_pass_through_ioctl(HANDLE hdevice, IDEREGS * regs, char * data, unsigned datasize){ 	if (datasize > 512) {		errno = EINVAL;		return -1;	}	unsigned int size = sizeof(ATA_PASS_THROUGH)-1 + datasize;	ATA_PASS_THROUGH * buf = (ATA_PASS_THROUGH *)VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);	DWORD num_out;	const unsigned char magic = 0xcf;	if (!buf) {		errno = ENOMEM;		return -1;	}	buf->IdeReg = *regs;	buf->DataBufferSize = datasize;	if (datasize)		buf->DataBuffer[0] = magic;	if (!DeviceIoControl(hdevice, IOCTL_IDE_PASS_THROUGH,		buf, size, buf, size, &num_out, NULL)) {		long err = GetLastError();		if (con->reportataioctl) {			pout("  IOCTL_IDE_PASS_THROUGH failed, Error=%ld\n", err);			print_ide_regs_io(regs, NULL);		}		VirtualFree(buf, 0, MEM_RELEASE);		errno = (err == ERROR_INVALID_FUNCTION || err == ERROR_NOT_SUPPORTED ? ENOSYS : EIO);		return -1;	}	// Check ATA status	if (buf->IdeReg.bCommandReg/*Status*/ & 0x01) {		if (con->reportataioctl) {			pout("  IOCTL_IDE_PASS_THROUGH command failed:\n");			print_ide_regs_io(regs, &buf->IdeReg);		}		VirtualFree(buf, 0, MEM_RELEASE);		errno = EIO;		return -1;	}	// Check and copy data	if (datasize) {		if (   num_out != size		    || (buf->DataBuffer[0] == magic && !nonempty(buf->DataBuffer+1, datasize-1))) {			if (con->reportataioctl) {				pout("  IOCTL_IDE_PASS_THROUGH output data missing (%lu, %lu)\n",					num_out, buf->DataBufferSize);				print_ide_regs_io(regs, &buf->IdeReg);			}			VirtualFree(buf, 0, MEM_RELEASE);			errno = EIO;			return -1;		}		memcpy(data, buf->DataBuffer, datasize);	}	if (con->reportataioctl > 1) {		pout("  IOCTL_IDE_PASS_THROUGH suceeded, bytes returned: %lu (buffer %lu)\n",			num_out, buf->DataBufferSize);		print_ide_regs_io(regs, &buf->IdeReg);	}	*regs = buf->IdeReg;	// Caution: VirtualFree() fails if parameter "dwSize" is nonzero	VirtualFree(buf, 0, MEM_RELEASE);	return 0;}/////////////////////////////////////////////////////////////////////////////// ATA PASS THROUGH (Win2003, XP SP2)#define IOCTL_ATA_PASS_THROUGH \	CTL_CODE(IOCTL_SCSI_BASE, 0x040B, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)ASSERT_CONST(IOCTL_ATA_PASS_THROUGH, 0x04d02c);typedef struct _ATA_PASS_THROUGH_EX {	USHORT  Length;	USHORT  AtaFlags;

⌨️ 快捷键说明

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