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

📄 os_win32.cpp

📁 硬盘各项性能的测试,如温度容量版本健康度型号
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	sb.regs = *regs;	sb.regs.bReserved = port;	DWORD num_out;	if (!DeviceIoControl(hdevice, IOCTL_SCSI_MINIPORT,		&sb, sizeof(sb), &sb, sizeof(sb), &num_out, NULL)) {		long err = GetLastError();		if (con->reportataioctl) {			pout("  ATA via IOCTL_SCSI_MINIPORT failed, Error=%ld\n", err);			print_ide_regs_io(regs, NULL);		}		errno = (err == ERROR_INVALID_FUNCTION ? ENOSYS : EIO);		return -1;	}	if (sb.srbc.ReturnCode) {		if (con->reportataioctl) {			pout("  ATA via IOCTL_SCSI_MINIPORT failed, ReturnCode=0x%08lx\n", sb.srbc.ReturnCode);			print_ide_regs_io(regs, NULL);		}		errno = EIO;		return -1;	}	// Copy data	if (datasize > 0)		memcpy(data, sb.buffer, datasize);	if (con->reportataioctl > 1) {		pout("  ATA via IOCTL_SCSI_MINIPORT suceeded, bytes returned: %lu\n", num_out);		print_ide_regs_io(regs, &sb.regs);	}	*regs = sb.regs;	return 0;}/////////////////////////////////////////////////////////////////////////////// 3ware specific call to update the devicemap returned by SMART_GET_VERSION.// 3DM/CLI "Rescan Controller" function does not to always update it.static int update_3ware_devicemap_ioctl(HANDLE hdevice){	SRB_IO_CONTROL srbc;	memset(&srbc, 0, sizeof(srbc));	strcpy((char *)srbc.Signature, "<3ware>");	srbc.HeaderLength = sizeof(SRB_IO_CONTROL);	srbc.Timeout = 60; // seconds	srbc.ControlCode = 0xCC010014;	srbc.ReturnCode = 0;	srbc.Length = 0;	DWORD num_out;	if (!DeviceIoControl(hdevice, IOCTL_SCSI_MINIPORT,		&srbc, sizeof(srbc), &srbc, sizeof(srbc), &num_out, NULL)) {		long err = GetLastError();		if (con->reportataioctl)			pout("  UPDATE DEVICEMAP via IOCTL_SCSI_MINIPORT failed, Error=%ld\n", err);		errno = (err == ERROR_INVALID_FUNCTION ? ENOSYS : EIO);		return -1;	}	if (srbc.ReturnCode) {		if (con->reportataioctl)			pout("  UPDATE DEVICEMAP via IOCTL_SCSI_MINIPORT failed, ReturnCode=0x%08lx\n", srbc.ReturnCode);		errno = EIO;		return -1;	}	if (con->reportataioctl > 1)		pout("  UPDATE DEVICEMAP via IOCTL_SCSI_MINIPORT suceeded\n");	return 0;}/////////////////////////////////////////////////////////////////////////////// Routines for pseudo device /dev/tw_cli/*// Parses output of 3ware "tw_cli /cx/py show all" or 3DM SMART data window// Get clipboard datastatic int get_clipboard(char * data, int datasize){	if (!OpenClipboard(NULL))		return -1;	HANDLE h = GetClipboardData(CF_TEXT);	if (!h) {		CloseClipboard();		return 0;	}	const void * p = GlobalLock(h);	int n = GlobalSize(h);	if (n > datasize)		n = datasize;	memcpy(data, p, n);	GlobalFree(h);	CloseClipboard();	return n;}// Run a command, write stdout to dataout// TODO: Combine with daemon_win32.cpp:daemon_spawn()static int run_cmd(const char * cmd, char * dataout, int outsize){	// Create stdout pipe	SECURITY_ATTRIBUTES sa = {sizeof(sa), 0, TRUE};	HANDLE pipe_out_w, h;	if (!CreatePipe(&h, &pipe_out_w, &sa/*inherit*/, outsize))		return -1;	HANDLE self = GetCurrentProcess();	HANDLE pipe_out_r;	if (!DuplicateHandle(self, h, self, &pipe_out_r,		GENERIC_READ, FALSE/*!inherit*/, DUPLICATE_CLOSE_SOURCE)) {		CloseHandle(pipe_out_w);		return -1;	}	HANDLE pipe_err_w;	if (!DuplicateHandle(self, pipe_out_w, self, &pipe_err_w,		0, TRUE/*inherit*/, DUPLICATE_SAME_ACCESS)) {		CloseHandle(pipe_out_r); CloseHandle(pipe_out_w);		return -1;	}	// Create process	STARTUPINFO si;	memset(&si, 0, sizeof(si)); si.cb = sizeof(si);	si.hStdInput  = INVALID_HANDLE_VALUE;	si.hStdOutput = pipe_out_w; si.hStdError  = pipe_err_w;	si.dwFlags = STARTF_USESTDHANDLES;	PROCESS_INFORMATION pi;	if (!CreateProcess(		NULL, const_cast<char *>(cmd),		NULL, NULL, TRUE/*inherit*/,		CREATE_NO_WINDOW/*do not create a new console window*/,		NULL, NULL, &si, &pi)) {		CloseHandle(pipe_err_w); CloseHandle(pipe_out_r); CloseHandle(pipe_out_w);		return -1;	}	CloseHandle(pi.hThread);	CloseHandle(pipe_err_w); CloseHandle(pipe_out_w);	// Copy stdout to output buffer	int i = 0;	while (i < outsize) {		DWORD num_read;		if (!ReadFile(pipe_out_r, dataout+i, outsize-i, &num_read, NULL) || num_read == 0)			break;		i += num_read;	}	CloseHandle(pipe_out_r);	// Wait for process	WaitForSingleObject(pi.hProcess, INFINITE);	CloseHandle(pi.hProcess);	return i;}static const char * findstr(const char * str, const char * sub){	const char * s = strstr(str, sub);	return (s ? s+strlen(sub) : "");}static void copy_swapped(unsigned char * dest, const char * src, int destsize){	int srclen = strcspn(src, "\r\n");	int i;	for (i = 0; i < destsize-1 && i < srclen-1; i+=2) {		dest[i] = src[i+1]; dest[i+1] = src[i];	}	if (i < destsize-1 && i < srclen)		dest[i+1] = src[i];}static ata_identify_device * tw_cli_identbuf = 0;static ata_smart_values * tw_cli_smartbuf = 0;static int tw_cli_open(const char * name){	// Read tw_cli or 3DM browser output into buffer	char buffer[4096];	int size = -1, n1 = -1;	if (!strcmp(name, "clip")) { // tw_cli/clip => read clipboard		size = get_clipboard(buffer, sizeof(buffer));	}	else if (!strcmp(name, "stdin")) {  // tw_cli/stdin => read stdin		size = fread(buffer, 1, sizeof(buffer), stdin);	}	else if (sscanf(name, "c%*u/p%*u%n", &n1) >= 0 && n1 == (int)strlen(name)) {		// tw_cli/cx/py => read output from "tw_cli /cx/py show all"		char cmd[100];		snprintf(cmd, sizeof(cmd), "tw_cli /%s show all", name);		if (con->reportataioctl > 1)			pout("tw_cli/%s: Run: \"%s\"\n", name, cmd);		size = run_cmd(cmd, buffer, sizeof(buffer));	}	else {		errno = EINVAL; return -1;	}	if (con->reportataioctl > 1)		pout("tw_cli/%s: Read %d bytes\n", name, size);	if (size <= 0) {		errno = ENOENT; return -1;	}	if (size >= (int)sizeof(buffer)) {		errno = EIO; return -1;	}	buffer[size] = 0;	if (con->reportataioctl > 1)		pout("[\n%.100s%s\n]\n", buffer, (size>100?"...":""));	// Fake identify sector	ASSERT_SIZEOF(ata_identify_device, 512);	ata_identify_device * id = (ata_identify_device *)malloc(sizeof(ata_identify_device));	memset(id, 0, sizeof(*id));	copy_swapped(id->model    , findstr(buffer, " Model = "   ), sizeof(id->model));	copy_swapped(id->fw_rev   , findstr(buffer, " Firmware Version = "), sizeof(id->fw_rev));	copy_swapped(id->serial_no, findstr(buffer, " Serial = "  ), sizeof(id->serial_no));	unsigned long nblocks = 0; // "Capacity = N.N GB (N Blocks)"	sscanf(findstr(buffer, "Capacity = "), "%*[^(\r\n](%lu", &nblocks);	if (nblocks) {		id->words047_079[49-47] = 0x0200; // size valid		id->words047_079[60-47] = (unsigned short)(nblocks    ); // secs_16		id->words047_079[61-47] = (unsigned short)(nblocks>>16); // secs_32	}	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	// Parse smart data hex dump	const char * s = findstr(buffer, "Drive Smart Data:");	if (!*s) {		s = findstr(buffer, "S.M.A.R.T. (Controller"); // from 3DM browser window		if (*s) {			const char * s1 = findstr(s, "<td class"); // html version			if (*s1)				s = s1;			s += strcspn(s, "\r\n");		}		else			s = buffer; // try raw hex dump without header	}	unsigned char * sd = (unsigned char *)malloc(512);	int i = 0;	for (;;) {		unsigned x = ~0; int n = -1;		if (!(sscanf(s, "%x %n", &x, &n) == 1 && !(x & ~0xff)))			break;		sd[i] = (unsigned char)x;		if (!(++i < 512 && n > 0))			break;		s += n;		if (*s == '<') // "<br>"			s += strcspn(s, "\r\n");	}	if (i < 512) {		free(sd);		if (!id->model[1]) {			// No useful data found			free(id);			char * err = strstr(buffer, "Error:");			if (!err)				err = strstr(buffer, "error :");			if (err) {				// Print tw_cli error message				err[strcspn(err, "\r\n")] = 0;				pout("%s\n", err);			}			errno = EIO;			return -1;		}		sd = 0;	}	tw_cli_identbuf = id;	tw_cli_smartbuf = (ata_smart_values *)sd;	return TW_CLI_FDOFFSET;}static void tw_cli_close(){	if (tw_cli_identbuf) {		free(tw_cli_identbuf); tw_cli_identbuf = 0;	}	if (tw_cli_smartbuf) {		free(tw_cli_smartbuf); tw_cli_smartbuf = 0;	}}static int tw_cli_command_interface(smart_command_set command, int /*select*/, char * data){	switch (command) {	  case IDENTIFY:		if (!tw_cli_identbuf)			break;		memcpy(data, tw_cli_identbuf, 512);		return 0;	  case READ_VALUES:		if (!tw_cli_smartbuf)			break;		memcpy(data, tw_cli_smartbuf, 512);		return 0;	  case READ_THRESHOLDS:		if (!tw_cli_smartbuf)			break;		// Fake zero thresholds		{			const ata_smart_values   * sv = tw_cli_smartbuf;			ata_smart_thresholds_pvt * tr = (ata_smart_thresholds_pvt *)data;			memset(tr, 0, 512);			// TODO: Indicate missing thresholds in ataprint.cpp:PrintSmartAttribWithThres()			// (ATA_SMART_READ_THRESHOLDS is marked obsolete since ATA-5)			for (int i = 0; i < NUMBER_ATA_SMART_ATTRIBUTES; i++)				tr->chksum -= tr->thres_entries[i].id = sv->vendor_attributes[i].id;		}		return 0;	  case ENABLE:	  case STATUS:	  case STATUS_CHECK: // Fake "good" SMART status		return 0;	  default:		break;	}	// Arrive here for all unsupported commands	errno = ENOSYS;	return -1;}/////////////////////////////////////////////////////////////////////////////// IOCTL_STORAGE_QUERY_PROPERTY#define FILE_DEVICE_MASS_STORAGE    0x0000002d#define IOCTL_STORAGE_BASE          FILE_DEVICE_MASS_STORAGE#define FILE_ANY_ACCESS             0#define IOCTL_STORAGE_QUERY_PROPERTY \	CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS)typedef enum _STORAGE_BUS_TYPE {	BusTypeUnknown      = 0x00,	BusTypeScsi         = 0x01,	BusTypeAtapi        = 0x02,	BusTypeAta          = 0x03,	BusType1394         = 0x04,	BusTypeSsa          = 0x05,	BusTypeFibre        = 0x06,	BusTypeUsb          = 0x07,	BusTypeRAID         = 0x08,	BusTypeiScsi        = 0x09,	BusTypeSas          = 0x0A,	BusTypeSata         = 0x0B,	BusTypeSd           = 0x0C,	BusTypeMmc          = 0x0D,	BusTypeMax          = 0x0E,	BusTypeMaxReserved  = 0x7F} STORAGE_BUS_TYPE, *PSTORAGE_BUS_TYPE;typedef struct _STORAGE_DEVICE_DESCRIPTOR {	ULONG Version;	ULONG Size;	UCHAR DeviceType;	UCHAR DeviceTypeModifier;	BOOLEAN RemovableMedia;	BOOLEAN CommandQueueing;	ULONG VendorIdOffset;	ULONG ProductIdOffset;	ULONG ProductRevisionOffset;	ULONG SerialNumberOffset;	STORAGE_BUS_TYPE BusType;	ULONG RawPropertiesLength;	UCHAR RawDeviceProperties[1];} STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR;typedef enum _STORAGE_QUERY_TYPE {	PropertyStandardQuery = 0,	PropertyExistsQuery,	PropertyMaskQuery,	PropertyQueryMaxDefined} STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE;typedef enum _STORAGE_PROPERTY_ID {	StorageDeviceProperty = 0,	StorageAdapterProperty,	StorageDeviceIdProperty,	StorageDeviceUniqueIdProperty,	StorageDeviceWriteCacheProperty,	StorageMiniportProperty,	StorageAccessAlignmentProperty} STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID;typedef struct _STORAGE_PROPERTY_QUERY {	STORAGE_PROPERTY_ID PropertyId;	STORAGE_QUERY_TYPE QueryType;	UCHAR AdditionalParameters[1];} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY;/////////////////////////////////////////////////////////////////////////////union STORAGE_DEVICE_DESCRIPTOR_DATA {	STORAGE_DEVICE_DESCRIPTOR desc;	char raw[256];};// Get STORAGE_DEVICE_DESCRIPTOR_DATA for device.// (This works without admin rights)static int storage_query_property_ioctl(HANDLE hdevice, STORAGE_DEVICE_DESCRIPTOR_DATA * data){	STORAGE_PROPERTY_QUERY query = {StorageDeviceProperty, PropertyStandardQuery, 0};	memset(data, 0, sizeof(*data));	DWORD num_out;	if (!DeviceIoControl(hdevice, IOCTL_STORAGE_QUERY_PROPERTY,

⌨️ 快捷键说明

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