获取传感器温度-硬盘温度篇

news/2024/12/22 18:21:01/

    最近在研究硬盘温度的获取。看来ata spec,疯狂的在网上查找资料,还有就是分析hwmonitor.exe(这个帮助最大)。刚开始的时候什么都不会,到什么地方获取数据呢。在之前获取dmi中,有在spec中看到有温度。但是这个一般的主板商是不会写温度数据到里面的。而wmi很多就是读取dmi数据的。所以在获取cpu温度等上面,都是读不出数据的。因此,首先打消这个念头。

    在疯狂的在网上搜寻资料之后,得到了一些有用的东西,那就是温度是在硬盘的SMART属性中有保存的。到这里我们知道了,硬盘温度保存的地方。如何获取到这部分数据呢。是怎样的一个数据结构呢?真正的问题来了。用smart获取硬盘温度,你可以再codeproject中会找一个工程。实例就是如何获取smart信息。很详细。建议看看这部分代码。他是通过读取//./PhysicalDrive0(第一块硬盘,之后一次类推)。但是有时候根本获取不到详细的属性信息。特别是在多硬盘的机器上,很可能会出现获取数据不正确的问题,主要的原因就是sata硬盘的问题。在使用codeproject中的样例就获取不到了,到这里这能另寻它路了。没有别的办法只有看spec了。看这书,我是有点看晕了。只能求救于网络了。很幸运,找到新大陆了,可以通过wmi方式得到属性值。既然这样那就用wmitools看看吧。下面把网上找到的内容粘上给大家参考一下:

   检测硬盘温度的工具或软件,都是通过 S.M.A.R.T来读取,对硬盘直接 DeviceIoControl 或者 WMI 都可以得到SMART值.SMART 数据存储于 WMI 中 ROOT/WMI/MSStorageDriver_ATAPISmartData 命名空间中,其中属性 'VendorSpecific' 包含有硬盘温度的数据,这是ATA标准定义的。可能你读出这些数据来会有些困惑,其实这是一个结构,第一个和第二个字节代表 SMART 版本信息,从第三个字节起定义 SMART 的属性,每个属性为12字节长,每个属性的第一字节为当前属性定义,0x09 定义已经使用的小时数, 0xc2 为温度属性,第五字节表示当前温度。结构如下

        struct SmartAttriubtes
        {
            char attrib;
            char flags;
            char worst;
            char normal;
            char current;
            char current1;
            char current2;
            char current3;
            char current4;
            char current5;
            char current6;
            char current7;
        }

 struct VendorSpecific
        {
            unsigned short version;
            SmartAttriubtes smartattrib [1];
        }

       如笔者硬盘读取如下数值,有些就省略了 {0xa, 0x00, 0x09, 0x32, 0, 0x63, 0x63, 0xc2, 0x03, 0, 0, 0, 0, 0, 0xc2, 0x22, 0, 0x2e, 0x3b, 0x2e, 0, 0, 0, 0x05, 0, 0, ...};
      

  排列如下
       {
          0xa, 0x00 版本信息
          0x09, 0x32, 0, 0x63, 0x63, [0xc2, 0x03], 0, 0, 0, 0, 0 硬盘使用小时数 这里是 0x3c2 = 962 小时
          0xc2, 0x22, 0, 0x2e, 0x3b, [0x2e], 0, 0, 0, 0x05, 0, 0 这是当前温度 数值为 0x2e = 46 度
       }

       win2000 不支持此 WMI 属性,只能通过 DeviceIoControl 得到,如何实现请看考附录 SMART 的OpenSource 连接

    

     确实如上面说的,2000下面没有这个东西。但是用wmi方式同样和用codeproject中的样例一样会有相同的问题。这下真的让人很郁闷。

    只有最后一招了,调试分析hwmonitor了(逆向,还好一点点还是会的)。下面是主要分析:

//获取当前系统上的存储设备信息
InBuffer:
0012EDC4  00 00 00 00 00 00 00 00 E0 ED 12 00              ....?


00414272  |> /57            push    edi                              ; /pOverlapped
00414273  |. |8D5424 38     lea     edx, dword ptr [esp+38]          ; |
00414277  |. |52            push    edx                              ; |pBytesReturned
00414278  |. |8B5424 1C     mov     edx, dword ptr [esp+1C]          ; |
0041427C  |. |68 00020000   push    200                              ; |OutBufferSize = 200 (512.)
00414281  |. |8D4424 50     lea     eax, dword ptr [esp+50]          ; |
00414285  |. |50            push    eax                              ; |OutBuffer
00414286  |. |6A 0C         push    0C                               ; |InBufferSize = C (12.)
00414288  |. |8D4C24 4C     lea     ecx, dword ptr [esp+4C]          ; |
0041428C  |. |51            push    ecx                              ; |InBuffer
0041428D  |. |68 00142D00   push    2D1400                           ; |IoControlCode = 2D1400(IOCTL_STORAGE_QUERY_PROPERTY)
00414292  |. |52            push    edx                              ; |hDevice
00414293  |. |897C24 58     mov     dword ptr [esp+58], edi          ; |
00414297  |. |897C24 5C     mov     dword ptr [esp+5C], edi          ; |
0041429B  |. |FF15 BC034A00 call    dword ptr [<&KERNEL32.DeviceIoCo>; /DeviceIoControl

 

 


//获取smart版本


00414365  |> /57            push    edi                              ; /pOverlapped
00414366  |.  8D4C24 34     lea     ecx, dword ptr [esp+34]          ; |
0041436A  |.  51            push    ecx                              ; |pBytesReturned
0041436B  |.  6A 18         push    18                               ; |OutBufferSize = 18 (24.)
0041436D  |.  33C0          xor     eax, eax                         ; |
0041436F  |.  8D5424 24     lea     edx, dword ptr [esp+24]          ; |
00414373  |.  52            push    edx                              ; |OutBuffer
00414374  |.  57            push    edi                              ; |InBufferSize
00414375  |.  57            push    edi                              ; |InBuffer
00414376  |.  894424 30     mov     dword ptr [esp+30], eax          ; |
0041437A  |.  894424 34     mov     dword ptr [esp+34], eax          ; |
0041437E  |.  894424 38     mov     dword ptr [esp+38], eax          ; |
00414382  |.  894424 3C     mov     dword ptr [esp+3C], eax          ; |
00414386  |.  894424 40     mov     dword ptr [esp+40], eax          ; |
0041438A  |.  894424 44     mov     dword ptr [esp+44], eax          ; |
0041438E  |.  8B4424 2C     mov     eax, dword ptr [esp+2C]          ; |
00414392  |.  68 80400700   push    74080                            ; |IoControlCode = SMART_GET_VERSION
00414397  |.  50            push    eax                              ; |hDevice
00414398  |.  897C24 50     mov     dword ptr [esp+50], edi          ; |
0041439C  |.  FF15 BC034A00 call    dword ptr [<&KERNEL32.DeviceIoCo>; /DeviceIoControl

0012ED6C   00000148  |hDevice = 00000148
0012ED70   00074080  |IoControlCode = SMART_GET_VERSION
0012ED74   00000000  |InBuffer = NULL
0012ED78   00000000  |InBufferSize = 0
0012ED7C   0012EDA4  |OutBuffer = 0012EDA4
0012ED80   00000018  |OutBufferSize = 18 (24.)
0012ED84   0012EDBC  |pBytesReturned = 0012EDBC
0012ED88   00000000  /pOverlapped = NULL


.text:004143AC                 mov     ecx, [esp+254h+var_238] ; GETVERSIONINPARAMS.fCapabilities
.text:004143B0                 shr     ecx, 2   
.text:004143B3                 and     ecx, 1
.text:004143B6                 mov     [ebx+718h], ecx
.text:004143BC                 jmp     short loc_4143C0

if(GETVERSIONINPARAMS.fCapabilities & CAP_SMART_CMD ) == CAP_SMART_CMD)
{

}

 

 

//发送smart命令

0012EDF0  00 00 00 00 D8 01 01 4F C2 A0 B0 00 00 00 00 00  ..ǘ企?°..
0012EE00  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ........

 


.text:00414195                 mov     [eax+6], dl
.text:00414198                 mov     edx, [esp+1Ch+lpOutBuffer]
.text:0041419C                 push    edx             ; lpOutBuffer
.text:0041419D                 push    20h             ; nInBufferSize
.text:0041419F                 push    eax             ; lpInBuffer
.text:004141A0                 mov     [eax], esi
.text:004141A2                 mov     esi, [esp+28h+hObject]
.text:004141A6                 or      bl, 0FAh
.text:004141A9                 push    7C084h          ; dwIoControlCode  SMART_SEND_DRIVE_COMMAND
.text:004141AE                 shl     bl, 4
.text:004141B1                 push    esi             ; hDevice
.text:004141B2                 mov     byte ptr [eax+4], 0D8h
.text:004141B6                 mov     byte ptr [eax+7], 4Fh
.text:004141BA                 mov     byte ptr [eax+8], 0C2h
.text:004141BE                 mov     [eax+9], bl
.text:004141C1                 mov     byte ptr [eax+0Ah], 0B0h
.text:004141C5                 call    ds:DeviceIoControl ; Sends a control code directly to a specified device driver,
.text:004141C5                                         ; causing the corre


//接受smart数据

0012EDF0  00 02 00 00 D0 01 01 4F C2 A0 B0 00 00 00 00 00  ?.ǐ企?°..
0012EE00  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ........

.text:004145B5                 call    _memset
.text:004145BA                 add     esp, 0Ch
.text:004145BD                 push    0               ; lpOverlapped
.text:004145BF                 lea     edx, [esp+288h+BytesReturned]
.text:004145C3                 push    edx             ; lpBytesReturned
.text:004145C4                 push    210h            ; nOutBufferSize
.text:004145C9                 lea     eax, [esp+290h+Dst]
.text:004145CD                 push    eax             ; lpOutBuffer
.text:004145CE                 push    20h             ; nInBufferSize
.text:004145D0                 lea     ecx, [esp+298h+InBuffer]
.text:004145D4                 push    ecx             ; lpInBuffer
.text:004145D5                 push    7C088h          ; dwIoControlCode  SMART_REV_DRIVE_DATA
.text:004145DA                 push    ebp             ; hDevice
.text:004145DB                 call    ds:DeviceIoControl ; Sends a control code directly to a specified device driver,
.text:004145DB                                         ; causing the corresponding dev

 


while(SetupDiEnumDeviceInterfaces())
{
 //获取所需的缓存大小
 if(SetupDiGetDeviceInterfaceDetail())
 {
  //获取所需的数据
  if(SetupDiGetDeviceInterfaceDetail())
  {
   //打开设备,设备名为获取buffer+4
    hFile = CreateFile();
    if(hFile != INVAILD_VALUE_HANDLE)
    {
     CloseHanle(hFile);
    } 
   
  }
 }
}

 

上面的inbuffer内容,具体的要看ata spec了。

 

可以尝试的调试分析一下,你会知道,在获取smart之前是打开设备。分析中你会知道它不是打开//./PhysicalDrive0之类的设备,而是首先通过存储设备类,知道有哪些可用的存储设备,使用SetDixxxxxxx函数可以得到具体设备名。然后GetPowerState得到设备是否正在运行,以及通过smart版本是否支持smart命令。如果这些都成立的话,那么就可以通过send smart命令进行下面的操作了。这个存储设备类的guid是{0x53f56307,0xb6bf,0x11do,0x94,0xf2,0x00,0xa0,0xc9,0x1e,0xfb,0x8b}.

 

    在得到了smart属性之后就是解析的问题的。每个smart属性都是0xc字节大小,这个上面有说的。属性type为0xC2就是温度属性了。在偏移为5的地方就是当前温度值。在到每个属性之前有0x12字节的数据(这个是什么我就不管了)。上面还有一点没有说到的就是设备属性的获取。可以得到vendorid,和products,这个我是用来表示硬盘名称的。

 

  说的还不是很详细。就说到这里吧。大致东西都说到了。

  

 

 


http://www.ppmy.cn/news/877571.html

相关文章

win11使用移动硬盘(固态非固态)卡顿问题解决

以前win10使用移动硬盘没用出现过卡顿的问题&#xff0c;后来更新win11后&#xff0c;硬盘在处理文件和文件新建以及编辑的时候&#xff0c;都会莫名其妙卡1-3秒左右。以为是盘坏了&#xff0c;各种检测和修复。发现没有问题 后来还找移动硬盘的商家沟通&#xff0c;也无果打算…

智头条|第25届中国建博会(广州)成功举行,马斯克组建xAI公司

行业动态&#xff1a; 第25届中国建博会&#xff08;广州&#xff09;成功举行 7月8日至11日期间&#xff0c;2023中国建博会(广州)暨首届广州卫博会在广州如火如荼地进行。本届展会以“冠军企业首秀平台”为定位&#xff0c;以“建装理想家&#xff0c;服务新格局”为主题&a…

IPUU的小工具拍了拍你(上)

IPUU是埃文科技旗下的综合性IP查询网站&#xff0c;提供多维度的IP数据信息。通过在线查询&#xff0c;用户可以获取目标IP地址的详尽信息&#xff0c;包括位置属性、网络属性、风险属性以及业务属性等&#xff0c;同时还可以查询域名信息。无论您是需要查看某个IP地址归属地&a…

数字音频总线A2B开发详解九(A2B一主四从系统配置详解-D主B1、B2和B3、B4从)

未完待续 我的Slave板目前就做了3块&#xff0c;后面还没有焊接好&#xff0c;所以目前就写了挂3个喇叭的配置说明。等我后面20块Slave板都焊接好之后&#xff0c;做更多不一样的Slave板&#xff0c;我再把这篇补上。 兄弟们可以提前想象一下&#xff0c;汽车音响&#xff0c…

数字音频总线A2B开发详解十(A2B一主五从系统配置详解-D主B1、B2、B3、B4和B5从)

未完待续。 我的Slave板目前就做了3块&#xff0c;后面还没有焊接好&#xff0c;所以目前就写了挂3个喇叭的配置说明。等我后面20块Slave板都焊接好之后&#xff0c;做更多不一样的Slave板&#xff0c;我再把这篇补上。 兄弟们可以提前想象一下&#xff0c;汽车音响&#xff…

多媒体会议音响扩声系统

小型会议室系统设计工程项目 多媒体会议音响扩声系统&#xff0c;系统设计、音响设备选择、安装、调试、以及设计原理、详细接线图 一、会议系统方案设计 1 会议系统功能需求 该工程项目为多媒体会议音响扩声系统&#xff0c;工程主要有1间小会议厅&#xff0c;面积40平方米&a…

soundbar未来发展_智能电视时代 Soundbar未来发展之路

智能电视时代 Soundbar未来发展之路 2014年05月22日 09:57作者&#xff1a;厂商投稿编辑&#xff1a;梁志一文章出处&#xff1a;泡泡网原创 分享 泡泡网音箱频道5月22日 前几年由于平板电视的出现&#xff0c;人们似乎一下子将所有注意力都放在视觉上了&#xff1a;大屏、超薄…

又一个即将从后装消失的生意,谁才有资格瓜分这块更大的蛋糕?

过去几年时间&#xff0c;高端车载品牌音响一直是豪华品牌的专属&#xff0c;而普通车型则大多采用不知名的音响。 如今&#xff0c;随着整车智能化尤其是座舱体验的升级&#xff0c;用户对于个性化的需求日益明确&#xff0c;更多车型品牌开始重新考虑汽车音响系统的选型&…