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

📄 os_win32.cpp

📁 硬盘各项性能的测试,如温度容量版本健康度型号
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		&query, sizeof(query), data, sizeof(*data), &num_out, NULL)) {		if (con->reportataioctl > 1 || con->reportscsiioctl > 1)			pout("  IOCTL_STORAGE_QUERY_PROPERTY failed, Error=%ld\n", GetLastError());		errno = ENOSYS;		return -1;	}	if (con->reportataioctl > 1 || con->reportscsiioctl > 1) {		pout("  IOCTL_STORAGE_QUERY_PROPERTY returns:\n"		     "    Vendor:   \"%s\"\n"		     "    Product:  \"%s\"\n"		     "    Revision: \"%s\"\n"		     "    Removable: %s\n"		     "    BusType:   0x%02x\n",		     (data->desc.VendorIdOffset        ? data->raw+data->desc.VendorIdOffset : ""),		     (data->desc.ProductIdOffset       ? data->raw+data->desc.ProductIdOffset : ""),		     (data->desc.ProductRevisionOffset ? data->raw+data->desc.ProductRevisionOffset : ""),		     (data->desc.RemovableMedia? "Yes":"No"), data->desc.BusType		);	}	return 0;}/////////////////////////////////////////////////////////////////////////////// IOCTL_STORAGE_PREDICT_FAILURE#define IOCTL_STORAGE_PREDICT_FAILURE \  CTL_CODE(IOCTL_STORAGE_BASE, 0x0440, METHOD_BUFFERED, FILE_ANY_ACCESS)typedef struct _STORAGE_PREDICT_FAILURE {	ULONG  PredictFailure;	UCHAR  VendorSpecific[512];} STORAGE_PREDICT_FAILURE, *PSTORAGE_PREDICT_FAILURE;ASSERT_SIZEOF(STORAGE_PREDICT_FAILURE, 4+512);/////////////////////////////////////////////////////////////////////////////// Call IOCTL_STORAGE_PREDICT_FAILURE, return PredictFailure value// or -1 on error, opionally return VendorSpecific data.// (This works without admin rights)static int storage_predict_failure_ioctl(HANDLE hdevice, char * data = 0){	STORAGE_PREDICT_FAILURE pred;	memset(&pred, 0, sizeof(pred));	DWORD num_out;	if (!DeviceIoControl(hdevice, IOCTL_STORAGE_PREDICT_FAILURE,		0, 0, &pred, sizeof(pred), &num_out, NULL)) {		if (con->reportataioctl > 1)			pout("  IOCTL_STORAGE_PREDICT_FAILURE failed, Error=%ld\n", GetLastError());		errno = ENOSYS;		return -1;	}	if (con->reportataioctl > 1) {		pout("  IOCTL_STORAGE_PREDICT_FAILURE returns:\n"		     "    PredictFailure: 0x%08lx\n"		     "    VendorSpecific: 0x%02x,0x%02x,0x%02x,...,0x%02x\n",		     pred.PredictFailure,		     pred.VendorSpecific[0], pred.VendorSpecific[1], pred.VendorSpecific[2],		     pred.VendorSpecific[sizeof(pred.VendorSpecific)-1]		);	}	if (data)		memcpy(data, pred.VendorSpecific, sizeof(pred.VendorSpecific));	return (!pred.PredictFailure ? 0 : 1);}/////////////////////////////////////////////////////////////////////////////// get CONTROLLER_* for open handlestatic int get_controller_type(HANDLE hdevice, bool admin, GETVERSIONINPARAMS_EX * ata_version_ex){	// Try SMART_GET_VERSION first to detect ATA SMART support	// for drivers reporting BusTypeScsi (3ware)	if (admin && smart_get_version(hdevice, ata_version_ex) >= 0)		return CONTROLLER_ATA;	// Get BusType from device descriptor	STORAGE_DEVICE_DESCRIPTOR_DATA data;	if (storage_query_property_ioctl(hdevice, &data))		return CONTROLLER_UNKNOWN;	switch (data.desc.BusType) {		case BusTypeAta:		case BusTypeSata:			if (ata_version_ex)				memset(ata_version_ex, 0, sizeof(*ata_version_ex));			return CONTROLLER_ATA;		case BusTypeScsi:		case BusTypeiScsi:		case BusTypeSas:			return CONTROLLER_SCSI;		default:			return CONTROLLER_UNKNOWN;	}	/*NOTREACHED*/}// get CONTROLLER_* for device pathstatic int get_controller_type(const char * path, GETVERSIONINPARAMS_EX * ata_version_ex = 0){	bool admin = true;	HANDLE h = CreateFileA(path, GENERIC_READ|GENERIC_WRITE,		FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);	if (h == INVALID_HANDLE_VALUE) {		admin = false;		h = CreateFileA(path, 0,			FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);		if (h == INVALID_HANDLE_VALUE)			return CONTROLLER_UNKNOWN;	}	if (con->reportataioctl > 1 || con->reportscsiioctl > 1)		pout(" %s: successfully opened%s\n", path, (!admin ? " (without admin rights)" :""));	int type = get_controller_type(h, admin, ata_version_ex);	CloseHandle(h);	return type;}// get CONTROLLER_* for physical drive numberstatic int get_phy_drive_type(int drive, GETVERSIONINPARAMS_EX * ata_version_ex){	char path[30];	snprintf(path, sizeof(path)-1, "\\\\.\\PhysicalDrive%d", drive);	return get_controller_type(path, ata_version_ex);}static int get_phy_drive_type(int drive){	return get_phy_drive_type(drive, 0);}// get CONTROLLER_* for logical drive numberstatic int get_log_drive_type(int drive){	char path[30];	snprintf(path, sizeof(path)-1, "\\\\.\\%c:", 'A'+drive);	return get_controller_type(path);}// Build IDENTIFY information from STORAGE_DEVICE_DESCRIPTORstatic int get_identify_from_device_property(HANDLE hdevice, ata_identify_device * id){	STORAGE_DEVICE_DESCRIPTOR_DATA data;	if (storage_query_property_ioctl(hdevice, &data))		return -1;	memset(id, 0, sizeof(*id));	if (data.desc.ProductIdOffset)		copy_swapped(id->model, data.raw+data.desc.ProductIdOffset, sizeof(id->model));	if (data.desc.ProductRevisionOffset)		copy_swapped(id->fw_rev, data.raw+data.desc.ProductRevisionOffset, sizeof(id->fw_rev));	id->major_rev_num = 0x1<<3; // ATA-3	id->command_set_1 = 0x0001; id->command_set_2 = 0x4000; // SMART supported, words 82,83 valid	id->cfs_enable_1  = 0x0001; id->csf_default   = 0x4000; // SMART enabled, words 85,87 valid	return 0;}/////////////////////////////////////////////////////////////////////////////// Call GetDevicePowerState() if available (Win98/ME/2000/XP/2003)// returns: 1=active, 0=standby, -1=error// (This would also work for SCSI drives)static int get_device_power_state(HANDLE hdevice){	static HINSTANCE h_kernel_dll = 0;#ifdef __CYGWIN__	static DWORD kernel_dll_pid = 0;#endif	static BOOL (WINAPI * GetDevicePowerState_p)(HANDLE, BOOL *) = 0;	BOOL state = TRUE;	if (!GetDevicePowerState_p#ifdef __CYGWIN__	    || kernel_dll_pid != GetCurrentProcessId() // detect fork()#endif	   ) {		if (h_kernel_dll == INVALID_HANDLE_VALUE) {			errno = ENOSYS;			return -1;		}		if (!(h_kernel_dll = LoadLibraryA("KERNEL32.DLL"))) {			pout("Cannot load KERNEL32.DLL, Error=%ld\n", GetLastError());			h_kernel_dll = (HINSTANCE)INVALID_HANDLE_VALUE;			errno = ENOSYS;			return -1;		}		if (!(GetDevicePowerState_p = (BOOL (WINAPI *)(HANDLE, BOOL *))		                              GetProcAddress(h_kernel_dll, "GetDevicePowerState"))) {			if (con->reportataioctl)				pout("  GetDevicePowerState() not found, Error=%ld\n", GetLastError());			FreeLibrary(h_kernel_dll);			h_kernel_dll = (HINSTANCE)INVALID_HANDLE_VALUE;			errno = ENOSYS;			return -1;		}#ifdef __CYGWIN__		kernel_dll_pid = GetCurrentProcessId();#endif	}	if (!GetDevicePowerState_p(hdevice, &state)) {		long err = GetLastError();		if (con->reportataioctl)			pout("  GetDevicePowerState() failed, Error=%ld\n", err);		errno = (err == ERROR_INVALID_FUNCTION ? ENOSYS : EIO);		// TODO: This may not work as expected on transient errors,		// because smartd interprets -1 as SLEEP mode regardless of errno.		return -1;	}	if (con->reportataioctl > 1)		pout("  GetDevicePowerState() succeeded, state=%d\n", state);	return state;}/////////////////////////////////////////////////////////////////////////////// TODO: Put in a struct indexed by fd (or better a C++ object of course ;-)static HANDLE h_ata_ioctl = 0;static bool ata_admin; // true if opened with admin rightsstatic const char * ata_def_options;static char * ata_usr_options;const int max_ata_driveno = 25;static int ata_driveno; // Drive numberstatic int ata_driveno_is_log = -1; // 0=physical drivenumber, 1=logical drive number, -1=unknownstatic char ata_smartver_state[max_ata_driveno+1]; // SMART_GET_VERSION: 0=unknown, 1=OK, 2=failed// Print SMARTVSD error message, return errnostatic int smartvsd_error(){	char path[MAX_PATH];	unsigned len;	if (!(5 <= (len = GetSystemDirectoryA(path, MAX_PATH)) && len < MAX_PATH/2))		return ENOENT;	// SMARTVSD.VXD present?	strcpy(path+len, "\\IOSUBSYS\\SMARTVSD.VXD");	if (!access(path, 0)) {		// Yes, standard IDE driver used?		HANDLE h;		if (   (h = CreateFileA("\\\\.\\ESDI_506",		             GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,		             NULL, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE		    && GetLastError() == ERROR_FILE_NOT_FOUND                             ) {			pout("Standard IDE driver ESDI_506.PDR not used, or no IDE/ATA drives present.\n");			return ENOENT;		}		else {			if (h != INVALID_HANDLE_VALUE) // should not happen				CloseHandle(h);			pout("SMART driver SMARTVSD.VXD is installed, but not loaded.\n");			return ENOSYS;		}	}	else {		strcpy(path+len, "\\SMARTVSD.VXD");		if (!access(path, 0)) {			// Some Windows versions install SMARTVSD.VXD in SYSTEM directory			// (http://support.microsoft.com/kb/265854/en-us).			path[len] = 0;			pout("SMART driver is not properly installed,\n"				 " move SMARTVSD.VXD from \"%s\" to \"%s\\IOSUBSYS\"\n"				 " and reboot Windows.\n", path, path);		}		else {			// Some Windows versions do not provide SMARTVSD.VXD			// (http://support.microsoft.com/kb/199886/en-us).			path[len] = 0;			pout("SMARTVSD.VXD is missing in folder \"%s\\IOSUBSYS\".\n", path);		}		return ENOSYS;	}}// Get default ATA device optionsstatic const char * ata_get_def_options(){	DWORD ver = GetVersion();	if ((ver & 0x80000000) || (ver & 0xff) < 4) // Win9x/ME		return "s"; // SMART_* only	else if ((ver & 0xff) == 4) // WinNT4		return "sc"; // SMART_*, SCSI_PASS_THROUGH	else // WinXP, 2003, Vista		return "pasifm"; // GetDevicePowerState(), ATA_, SMART_*, IDE_PASS_THROUGH,		                 // STORAGE_*, SCSI_MINIPORT_*}// Open ATA devicestatic int ata_open(int phydrive, int logdrive, const char * options, int port){	// TODO: This version does not allow to open more than 1 ATA devices	if (h_ata_ioctl) {		errno = ENFILE;		return -1;	}	// Using both physical and logical drive names (in smartd.conf) not supported yet	if (!(   ata_driveno_is_log < 0	      || (phydrive >= 0 && !ata_driveno_is_log)	      || (logdrive >= 0 &&  ata_driveno_is_log))) {		pout("Using both /dev/hdX and X: is not supported\n");		errno = EINVAL;		return -1;	}	// path depends on Windows Version	bool win9x = is_win9x();	char devpath[30];	if (win9x && 0 <= phydrive && phydrive <= 7)		// Use patched "smartvse.vxd" for drives 4-7, see INSTALL file for details		strcpy(devpath, (phydrive <= 3 ? "\\\\.\\SMARTVSD" : "\\\\.\\SMARTVSE"));	else if (!win9x && 0 <= phydrive && phydrive <= max_ata_driveno)		snprintf(devpath, sizeof(devpath)-1, "\\\\.\\PhysicalDrive%d", phydrive);	else if (!win9x && 0 <= logdrive && logdrive <= max_ata_driveno) {		snprintf(devpath, sizeof(devpath)-1, "\\\\.\\%c:", 'A'+logdrive);	}	else {		errno = ENOENT;		return -1;	}	// Open device	h_ata_ioctl = INVALID_HANDLE_VALUE;	if (win9x || !(*options && !options[strspn(options, "fp")])) {		// Open with admin rights		ata_admin = true;		h_ata_ioctl = CreateFileA(devpath, GENERIC_READ|GENERIC_WRITE,			FILE_SHARE_READ|FILE_SHARE_WRITE,			NULL, OPEN_EXISTING, 0, 0);	}	if (!win9x && h_ata_ioctl == INVALID_HANDLE_VALUE) {		// Open without admin rights		ata_admin = false;		h_ata_ioctl = CreateFileA(devpath, 0,			FILE_SHARE_READ|FILE_SHARE_WRITE,			NULL, OPEN_EXISTING, 0, 0);	}	if (h_ata_ioctl == INVALID_HANDLE_VALUE) {		long err = GetLastError();		pout("Cannot open device %s, Error=%ld\n", devpath, err);		if (err == ERROR_FILE_NOT_FOUND)			errno = (win9x && phydrive <= 3 ? smartvsd_error() : ENOENT);		else if (err == ERROR_ACCESS_DENIED)			errno = EACCES;		else			errno = EIO;		h_ata_ioctl = 0;		return -1;	}	if (con->reportataioctl > 1)		pout("%s: successfully opened%s\n", devpath, (!ata_admin ? " (without admin rights)" :""));	// Set default options according to Windows version	if (!ata_def_options)		ata_def_options = ata_get_def_options();	// Save user options	if (port >= 0 && !*options)		options = "s3"; // RAID: SMART_* and SCSI_MINIPORT	assert(!ata_usr_options);	if (*options)		ata_usr_options = strdup(options);	// NT4/2000/XP: SMART_GET_VERSION may spin up disk, so delay until first real SMART_* call	if (phydrive >= 0) {		ata_driveno = phydrive; ata_driveno_is_log = 0;	}	else {		assert(logdrive >= 0);		ata_driveno = logdrive; ata_driveno_is_log = 1;	}	if (!win9x && port < 0)		return 0;	// Win9X/ME: Get drive map	// RAID: Get port map	GETVERSIONINPARAMS_EX vers_ex;	int devmap = smart_get_version(h_ata_ioctl, (port >= 0 ? &vers_ex : 0));	unsigned long portmap = 0;	if (port >= 0 && devmap >= 0) {		// 3ware RAID: check vendor id		if (vers_ex.wIdentifier != SMART_VENDOR_3WARE) {			pout("SMART_GET_VERSION returns unknown Identifier = %04x\n"			     "This is no 3ware 9000 controller or driver has no SMART support.\n",			     vers_ex.wIdentifier);			devmap = -1;		}		else			portmap = vers_ex.dwDeviceMapEx;	}	if (devmap < 0) {		pout("%s: ATA driver has no SMART support\n", devpath);		if (!is_permissive()) {			ata_close(0);			errno = ENOSYS;			return -1;		}		devmap = 0x0f;	}	ata_smartver_state[ata_driveno] = 1;	if (port >= 0) {		// 3ware RAID: update devicemap first		if (!update_

⌨️ 快捷键说明

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