遇到这个问题的时候首先就将windows的几个直接获取磁盘相关信息的API函数给否决掉了,比如GetDiskType,返回类型只有几个,并且固态硬盘作为新生事物,这个多年前就存在的API应该是不可能有相关信息的。

下面就想到了WMI来获取磁盘的相关信息来判断,WMI获取的磁盘相关信息明显是多了很多,但是仔细到MSDN上查看相关的返回值,发现并没有可以作为判断依据的属性或者。本人也亲自实现了一下,发现果然是没有什么返回值可以给我们作为判断的依据。

下面我们到网上查了下相关的解决办法,里面有人提到,通过判断磁盘的转速来判断磁盘是不是固态硬盘BOOL

下面我通过DeviceIoControl函数获取了文章中所说的转速信息的word217所在的结构体的信息

// 向驱动发“IDENTIFY DEVICE”命令,获得设备信息 // hDevice: 设备句柄 // pIdInfo: 设备信息结构指针
BOOL IdentifyDevice(HANDLE hDevice, PIDINFO pIdInfo)
{
	PSENDCMDINPARAMS pSCIP; // 输入数据结构指针
	PSENDCMDOUTPARAMS pSCOP; // 输出数据结构指针
	DWORD dwOutBytes; // IOCTL输出数据长度
	BOOL bResult; // IOCTL返回值 // 申请输入/输出数据结构空间
	pSCIP = (PSENDCMDINPARAMS)::GlobalAlloc(LMEM_ZEROINIT, sizeof(SENDCMDINPARAMS) - 1);
	pSCOP = (PSENDCMDOUTPARAMS)::GlobalAlloc(LMEM_ZEROINIT, sizeof(SENDCMDOUTPARAMS) + sizeof(IDINFO) - 1); // 指定ATA/ATAPI命令的寄存器值 //
	pSCIP->irDriveRegs.bFeaturesReg = 0; //
	pSCIP->irDriveRegs.bSectorCountReg = 0; //
	pSCIP->irDriveRegs.bSectorNumberReg = 0; //
	pSCIP->irDriveRegs.bCylLowReg = 0; //
	pSCIP->irDriveRegs.bCylHighReg = 0; //
	pSCIP->irDriveRegs.bDriveHeadReg = 0; 
	pSCIP->irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY; // 指定输入/输出数据缓冲区大小 IDENTIFY DEVICE
	pSCIP->cBufferSize = 0; 
	pSCOP->cBufferSize = sizeof(IDINFO); //
	bResult = ::DeviceIoControl(hDevice, // 设备句柄
		DFP_RECEIVE_DRIVE_DATA, // 指定IOCTL
		pSCIP, sizeof(SENDCMDINPARAMS) - 1, // 输入数据缓冲区
		pSCOP, sizeof(SENDCMDOUTPARAMS) + sizeof(IDINFO) - 1, // 输出数据缓冲区
		&dwOutBytes, // 输出数据长度
		(LPOVERLAPPED)NULL); // 用同步I/O // 复制设备参数结构
	::memcpy(pIdInfo, pSCOP->bBuffer, sizeof(IDINFO)); // 释放输入/输出数据空间
	::GlobalFree(pSCOP); 
	::GlobalFree(pSCIP); 
	return bResult;
}


但是,我发现无论是机械硬盘还是固态硬盘word217都是0,也就是无返回

数据的结构体为IDENTIFY_DEVICE_DATA,该结构体本身很长,有兴趣的可以去查查看。

调查工作到这里就陷入僵局了,但是我发现在上文中,其中提过可以通过TRIM属性来判断是否是SSD属性。但是有可能出现偏差。因为早期的SSD和组成RAID的SSD没有TRIM属性。但是觉得总比什么都没有强吧,我就尝试着获取TRIM属性。获取属性其实和上面获取硬件信息是一样的都是通过函数DeviceIoControl.。只不过输入输出的结构体和IOCTL指令不同罢了,输入的结构体为STORAGE_PROPERTY_QUERY,输出的结构体为DEVICE_TRIM_DESCRIPTOR,IOCTL的指令为IOCTL_STORAGE_QUERY_PROPERTY。完成以后测试,在不同类型的固态和机械硬盘上测试后发现都可以正常识别。看来偏差情况还是很少发生的。至此调查结束。

测试结果: