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

📄 os_win32.cpp

📁 硬盘各项性能的测试,如温度容量版本健康度型号
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/* * os_win32.cpp * * Home page of code is: http://smartmontools.sourceforge.net * * Copyright (C) 2004-8 Christian Franke <smartmontools-support@lists.sourceforge.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * You should have received a copy of the GNU General Public License * (for example COPYING); if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */#include "config.h"#include "int64.h"#include "atacmds.h"#include "extern.h"extern smartmonctrl * con; // con->permissive,reportataioctl#include "scsicmds.h"#include "utility.h"extern int64_t bytes; // malloc() byte count#include <errno.h>#ifdef _DEBUG#include <assert.h>#else#define assert(x) /**/#endif#define WIN32_LEAN_AND_MEAN#include <windows.h>#include <stddef.h> // offsetof()#include <io.h> // access()// Macro to check constants at compile time using a dummy typedef#define ASSERT_CONST(c, n) \  typedef char assert_const_##c[((c) == (n)) ? 1 : -1]#define ASSERT_SIZEOF(t, n) \  typedef char assert_sizeof_##t[(sizeof(t) == (n)) ? 1 : -1]// Needed by '-V' option (CVS versioning) of smartd/smartctlconst char *os_XXXX_c_cvsid="$Id: os_win32.cpp,v 1.61 2008/03/04 22:09:47 ballen4705 Exp $"ATACMDS_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;// Running on Win9x/ME ?static inline bool is_win9x(){	return !!(GetVersion() & 0x80000000);}// Running on 64-bit Windows as 32-bit app ?static bool is_wow64(){	HMODULE hk = GetModuleHandleA("kernel32");	if (!hk)		return false;	BOOL (WINAPI * IsWow64Process_p)(HANDLE, PBOOL) =		(BOOL (WINAPI *)(HANDLE, PBOOL))GetProcAddress(hk, "IsWow64Process");	if (!IsWow64Process_p)		return false;	BOOL w64 = FALSE;	if (!IsWow64Process_p(GetCurrentProcess(), &w64))		return false;	return !!w64;}#ifndef HAVE_GET_OS_VERSION_STR#error define of HAVE_GET_OS_VERSION_STR missing in config.h#endif// Return build host and OS version as static stringconst char * get_os_version_str(){	static char vstr[sizeof(SMARTMONTOOLS_BUILD_HOST)-3-1+sizeof("-2003r2(64)-sp2.1")+13];	char * const vptr = vstr+sizeof(SMARTMONTOOLS_BUILD_HOST)-3-1;	const int vlen = sizeof(vstr)-(sizeof(SMARTMONTOOLS_BUILD_HOST)-3);	// remove "-pc" to avoid long lines	assert(!strncmp(SMARTMONTOOLS_BUILD_HOST+5, "pc-", 3));	strcpy(vstr, "i686-"); strcpy(vstr+5, SMARTMONTOOLS_BUILD_HOST+5+3);	assert(vptr == vstr+strlen(vstr) && vptr+vlen+1 == vstr+sizeof(vstr));	OSVERSIONINFOEXA vi; memset(&vi, 0, sizeof(vi));	vi.dwOSVersionInfoSize = sizeof(vi);	if (!GetVersionExA((OSVERSIONINFOA *)&vi)) {		memset(&vi, 0, sizeof(vi));		vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);		if (!GetVersionExA((OSVERSIONINFOA *)&vi))			return vstr;	}	if (vi.dwPlatformId > 0xff || vi.dwMajorVersion > 0xff || vi.dwMinorVersion > 0xff)		return vstr;	const char * w;	switch (vi.dwPlatformId << 16 | vi.dwMajorVersion << 8 | vi.dwMinorVersion) {	  case VER_PLATFORM_WIN32_WINDOWS<<16|0x0400| 0:		w = (vi.szCSDVersion[1] == 'B' ||		     vi.szCSDVersion[1] == 'C'     ? "95-osr2" : "95");    break;	  case VER_PLATFORM_WIN32_WINDOWS<<16|0x0400|10:		w = (vi.szCSDVersion[1] == 'A'     ? "98se"    : "98");    break;	  case VER_PLATFORM_WIN32_WINDOWS<<16|0x0400|90: w = "me";     break;	//case VER_PLATFORM_WIN32_NT     <<16|0x0300|51: w = "nt3.51"; break;	  case VER_PLATFORM_WIN32_NT     <<16|0x0400| 0: w = "nt4";    break;	  case VER_PLATFORM_WIN32_NT     <<16|0x0500| 0: w = "2000";   break;	  case VER_PLATFORM_WIN32_NT     <<16|0x0500| 1:		w = (!GetSystemMetrics(87/*SM_MEDIACENTER*/) ?   "xp"		                                             :   "xp-mc"); break;	  case VER_PLATFORM_WIN32_NT     <<16|0x0500| 2:		w = (!GetSystemMetrics(89/*SM_SERVERR2*/) ?      "2003"		                                             :   "2003r2"); break;	  case VER_PLATFORM_WIN32_NT     <<16|0x0600| 0: w = "vista";  break;	  default: w = 0; break;	}	const char * w64 = (is_wow64() ? "(64)" : "");	if (!w)		snprintf(vptr, vlen, "-%s%lu.%lu%s",			(vi.dwPlatformId==VER_PLATFORM_WIN32_NT ? "nt" : "9x"),			vi.dwMajorVersion, vi.dwMinorVersion, w64);	else if (vi.wServicePackMinor)		snprintf(vptr, vlen, "-%s%s-sp%u.%u", w, w64, vi.wServicePackMajor, vi.wServicePackMinor);	else if (vi.wServicePackMajor)		snprintf(vptr, vlen, "-%s%s-sp%u", w, w64, vi.wServicePackMajor);	else		snprintf(vptr, vlen, "-%s%s", w, w64);	return vstr;}static int get_phy_drive_type(int drive);static int get_log_drive_type(int drive);#define ATARAID_FDOFFSET 0x0200static int ata_open(int phydrive, int logdrive, const char * options, int port);static void ata_close(int fd);static int ata_scan_win9x(unsigned long * drives);static int ata_scan(unsigned long * drives, int * rdriveno, unsigned long * rdrives);static const char * ata_get_def_options(void);#define TW_CLI_FDOFFSET 0x0300static int tw_cli_open(const char * name);static void tw_cli_close();#define ASPI_FDOFFSET 0x0100static int aspi_open(unsigned adapter, unsigned id);static void aspi_close(int fd);static int aspi_scan(unsigned long * drives);#define SPT_FDOFFSET 0x0400static int spt_open(int pd_num, int ld_num, int tape_num, int sub_addr);static void spt_close(int fd);static int spt_scan(unsigned long * drives);static int is_permissive(){	if (!con->permissive) {		pout("To continue, add one or more '-T permissive' options.\n");		return 0;	}	con->permissive--;	return 1;}// return number for drive letter, -1 on error// "[A-Za-z]:([/\\][.]?)?" => 0-25// Accepts trailing '"' to fix broken "X:\" parameter passing from .bat filesstatic int drive_letter(const char * s){	return (   (('A' <= s[0] && s[0] <= 'Z') || ('a' <= s[0] && s[0] <= 'z'))	        && s[1] == ':'	        && (!s[2] || (   strchr("/\\\"", s[2])	                      && (!s[3] || (s[3] == '.' && !s[4])))              ) ?	        (s[0] & 0x1f) - 1 : -1);}// Skip trailing "/dev/", do not allow "/dev/X:"static const char * skipdev(const char * s){	return (!strncmp(s, "/dev/", 5) && drive_letter(s+5) < 0 ? s+5 : s);}// tries to guess device type given the name (a path).  See utility.h// for return values.int guess_device_type (const char * dev_name){	dev_name = skipdev(dev_name);	if (!strncmp(dev_name, "scsi", 4))		return CONTROLLER_SCSI;	if (is_win9x())		return CONTROLLER_ATA;	if (!strncmp(dev_name, "hd", 2))		return CONTROLLER_ATA;	if (!strncmp(dev_name, "tw_cli", 6))		return CONTROLLER_ATA;	if (!strncmp(dev_name, "st", 2))		return CONTROLLER_SCSI;	if (!strncmp(dev_name, "nst", 3))		return CONTROLLER_SCSI;	if (!strncmp(dev_name, "tape", 4))		return CONTROLLER_SCSI;	int logdrive = drive_letter(dev_name);	if (logdrive >= 0) {		int type = get_log_drive_type(logdrive);		return (type != CONTROLLER_UNKNOWN ? type : CONTROLLER_SCSI);	}	char drive[1+1] = "";	if (sscanf(dev_name, "sd%1[a-z]", drive) == 1)		return get_phy_drive_type(drive[0]-'a');	int phydrive = -1;	if (sscanf(dev_name, "pd%d", &phydrive) == 1 && phydrive >= 0)		return get_phy_drive_type(phydrive);	return CONTROLLER_UNKNOWN;}// makes a list of ATA or SCSI devices for the DEVICESCAN directive of// smartd.  Returns number N of devices, or -1 if out of// memory. Allocates N+1 arrays: one of N pointers (devlist), the// others each contain null-terminated character strings.int make_device_names (char*** devlist, const char* type){	unsigned long drives[3];	int rdriveno[2];	unsigned long rdrives[2];	int i, j, n, nmax, sz;	const char * path;	drives[0] = drives[1] = drives[2] = 0;	rdriveno[0] = rdriveno[1] = -1;	rdrives[0] = rdrives[1] = 0;		bool win9x = is_win9x();	if (!strcmp(type, "ATA")) {		// bit i set => drive i present		if (win9x) {			n = ata_scan_win9x(drives);			path = "/dev/hda";		}		else {			n = ata_scan(drives, rdriveno, rdrives);			path = "/dev/sda";		}		nmax = 10;	}	else if (!strcmp(type, "SCSI")) {		if (win9x) {			// bit i set => drive with ID (i & 0x7) on adapter (i >> 3) present			n = aspi_scan(drives);			path = "/dev/scsi00";			nmax = 10*8;		}		else {			// bit i set => drive i present			n = spt_scan(drives);			path = "/dev/sda";			nmax = 10;		}	}	else		return -1;	if (n <= 0)		return 0;	// Alloc devlist	sz = n * sizeof(char **);	*devlist = (char **)malloc(sz); bytes += sz;	// Add devices	for (i = j = 0; i < n; ) {		while (j < nmax && !(drives[j >> 5] & (1L << (j & 0x1f))))			j++;		assert(j < nmax);		if (j == rdriveno[0] || j == rdriveno[1]) {			// Add physical drives behind this logical drive			int ci = (j == rdriveno[0] ? 0 : 1);			for (int pi = 0; pi < 32 && i < n; pi++) {				if (!(rdrives[ci] & (1L << pi)))					continue;				char rpath[20];				sprintf(rpath, "/dev/sd%c,%u", 'a'+j, pi);				sz = strlen(rpath)+1;				char * s = (char *)malloc(sz); bytes += sz;				strcpy(s, rpath);				(*devlist)[i++] = s;			}		}		else {			sz = strlen(path)+1;			char * s = (char *)malloc(sz); bytes += sz;			strcpy(s, path);			if (nmax <= 10) {				assert(j <= 9);				s[sz-2] += j; // /dev/hd[a-j]			}			else {				assert((j >> 3) <= 9);				s[sz-3] += (j >> 3);  // /dev/scsi[0-9].....				s[sz-2] += (j & 0x7); //          .....[0-7]			}			(*devlist)[i++] = s;		}		j++;	}	return n;}// Like open().  Return positive integer handle, only used by// functions below.  type="ATA" or "SCSI".  If you need to store extra// information about your devices, create a private internal array// within this file (see os_freebsd.cpp for an example).int deviceopen(const char * pathname, char *type){	pathname = skipdev(pathname);	int len = strlen(pathname);	if (!strcmp(type, "ATA")) {		// [sh]d[a-z](:[saicmfp]+)? => Physical drive 0-25, with options		char drive[1+1] = "", options[8+1] = ""; int n1 = -1, n2 = -1;		if (   sscanf(pathname, "%*[sh]d%1[a-z]%n:%7[saicmfp]%n", drive, &n1, options, &n2) >= 1		    && ((n1 == len && !options[0]) || n2 == len)                                       ) {			return ata_open(drive[0] - 'a', -1, options, -1);		}		// [sh]d[a-z],N(:[saicmfp3]+)? => Physical drive 0-25, RAID port N, with options		drive[0] = 0; options[0] = 0; n1 = -1; n2 = -1;		unsigned port = ~0;		if (   sscanf(pathname, "%*[sh]d%1[a-z],%u%n:%8[saicmfp3]%n", drive, &port, &n1, options, &n2) >= 2		    && port < 32 && ((n1 == len && !options[0]) || n2 == len)                                     ) {			return ata_open(drive[0] - 'a', -1, options, port);		}		// pd<m>,N => Physical drive <m>, RAID port N		int phydrive = -1; port = ~0; n1 = -1; n2 = -1;		if (   sscanf(pathname, "pd%d%n,%u%n", &phydrive, &n1, &port, &n2) >= 1		    && phydrive >= 0 && ((n1 == len && (int)port < 0) || (n2 == len && port < 32))) {			return ata_open(phydrive, -1, "", (int)port);		}		// [a-zA-Z]: => Physical drive behind logical drive 0-25		int logdrive = drive_letter(pathname);		if (logdrive >= 0) {			return ata_open(-1, logdrive, "", -1);		}		// tw_cli/... => Parse tw_cli output		if (!strncmp(pathname, "tw_cli/", 7)) {			return tw_cli_open(pathname+7);		}	} else if (!strcmp(type, "SCSI")) {		// scsi[0-9][0-f] => ASPI Adapter 0-9, ID 0-15, LUN 0		unsigned adapter = ~0, id = ~0; int n1 = -1;		if (sscanf(pathname,"scsi%1u%1x%n", &adapter, &id, &n1) == 2 && n1 == len) {			return aspi_open(adapter, id);		}		// sd[a-z],N => Physical drive 0-25, RAID port N		char drive[1+1] = ""; int sub_addr = -1; n1 = -1; int n2 = -1;		if (   sscanf(pathname, "sd%1[a-z]%n,%d%n", drive, &n1, &sub_addr, &n2) >= 1		    && ((n1 == len && sub_addr == -1) || (n2 == len && sub_addr >= 0))      ) {			return spt_open(drive[0] - 'a', -1, -1, sub_addr);		}		// pd<m>,N => Physical drive <m>, RAID port N		int pd_num = -1; sub_addr = -1; n1 = -1; n2 = -1;		if (   sscanf(pathname, "pd%d%n,%d%n", &pd_num, &n1, &sub_addr, &n2) >= 1		    && pd_num >= 0 && ((n1 == len && sub_addr == -1) || (n2 == len && sub_addr >= 0))) {			return spt_open(pd_num, -1, -1, sub_addr);		}		// [a-zA-Z]: => Physical drive behind logical drive 0-25		int logdrive = drive_letter(pathname);		if (logdrive >= 0) {			return spt_open(-1, logdrive, -1, -1);		}		// n?st<m> => tape drive <m> (same names used in Cygwin's /dev emulation)		int tape_num = -1; n1 = -1;		if (sscanf(pathname, "st%d%n", &tape_num, &n1) == 1 && tape_num >= 0 && n1 == len) {			return spt_open(-1, -1, tape_num, -1);		}		tape_num = -1; n1 = -1;		if (sscanf(pathname, "nst%d%n", &tape_num, &n1) == 1 && tape_num >= 0 && n1 == len) {			return spt_open(-1, -1, tape_num, -1);		}		// tape<m> => tape drive <m>		tape_num = -1; n1 = -1;		if (sscanf(pathname, "tape%d%n", &tape_num, &n1) == 1 && tape_num >= 0 && n1 == len) {			return spt_open(-1, -1, tape_num, -1);		}	}	errno = EINVAL;	return -1;}// Like close().  Acts only on handles returned by above function.int deviceclose(int fd){	if ((fd & 0xff00) == ASPI_FDOFFSET)		aspi_close(fd);	else if (fd >= SPT_FDOFFSET) 		spt_close(fd);	else if (fd == TW_CLI_FDOFFSET)		tw_cli_close();	else		ata_close(fd);	return 0;}// print examples for smartctlvoid print_smartctl_examples(){  printf("=================================================== SMARTCTL EXAMPLES =====\n\n"

⌨️ 快捷键说明

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