TNB Library
TnbSmartAccessor.h
[詳解]
1#pragma once
11#include "TnbStr.h"
12#include "TnbSimpleVector.h"
13#include <WinIoCtl.h>
14
15
16
17//TNB Library
18namespace TNB
19{
20
21
22
52{
53public:
54
58 struct TVersion
59 {
60 BYTE bVersion;
61 BYTE bRevision;
62 BYTE bReserved;
65 DWORD dwReserved[4];
66 };
67
73 {
74 #pragma pack(push,1)
75 BYTE bAttrID;
79 WORD bRawValue[3];
80 BYTE bReserved;
81 #pragma pack(pop)
87 ULONGLONG GetValue(void) const
88 {
89 ULONGLONG ll = bRawValue[2];
90 ll <<= 16; ll += bRawValue[1];
91 ll <<= 16; ll += bRawValue[0];
92 return ll;
93 }
99 CStr ToString(void) const
100 {
101 CStr s;
102 s.Format(_T("%03d %03d %012I64X"), bAttrValue, bWorstValue, GetValue());
103 return s;
104 }
110 CStr GetAttributeIdString(bool isEnglish = true) const
111 {
112 return GetAttributeIdString(bAttrID, isEnglish);
113 }
120 static CStr GetAttributeIdString(BYTE attributeId, bool isEnglish = true)
121 {
122 CStr r;
123 switch ( attributeId )
124 {
125 case 0x01: r = isEnglish ? _T("Raw read error rate") : _T("読み込みエラー率");
126 break;
127 case 0x02: r = isEnglish ? _T("Throughput performance") : _T("スループット");
128 break;
129 case 0x03: r = isEnglish ? _T("Spinup time") : _T("スピンアップ時間");
130 break;
131 case 0x04: r = isEnglish ? _T("Start/Stop count") : _T("回転/停止数");
132 break;
133 case 0x05: r = isEnglish ? _T("Reallocated sector count") : _T("再割り当てセクター数");
134 break;
135 case 0x06: r = isEnglish ? _T("Read channel margin") : _T("リード・チャンネル・マージン");
136 break;
137 case 0x07: r = isEnglish ? _T("Seek error rate") : _T("シークエラー率");
138 break;
139 case 0x08: r = isEnglish ? _T("Seek timer performance") : _T("シークタイム性能");
140 break;
141 case 0x09: r = isEnglish ? _T("Power-on hours count") : _T("合計利用時間");
142 break;
143 case 0x0A: r = isEnglish ? _T("Spinup retry count") : _T("スピンアップ再試行回数");
144 break;
145 case 0x0B: r = isEnglish ? _T("Calibration retry count") : _T("キャリブレーション再試行回数");
146 break;
147 case 0x0C: r = isEnglish ? _T("Power cycle count") : _T("電源投入回数");
148 break;
149 case 0x0D:
150 case 0xC9: r = isEnglish ? _T("Soft read error rate") : _T("論理読み込みエラー率");
151 break;
152 case 0xBB:
153 case 0xBD:
154 case 0xBE: r = isEnglish ? _T("vendor-specific") : _T("ベンダー独自情報");
155 break;
156 case 0xBF: r = isEnglish ? _T("G-sense error rate") : _T("加速度センサー検出エラー率");
157 break;
158 case 0xC0: r = isEnglish ? _T("Power-off retract count") : _T("電源切断回避数");
159 break;
160 case 0xC1: r = isEnglish ? _T("Load/Unload cycle count") : _T("ロード/アンロード・サイクル数");
161 break;
162 case 0xC2: r = isEnglish ? _T("HDA temperature") : _T("温度");
163 break;
164 case 0xC3: r = isEnglish ? _T("Hardware ECC recovered") : _T("ハードウエアECC復旧");
165 break;
166 case 0xC4: r = isEnglish ? _T("Reallocation count") : _T("再割り当て数");
167 break;
168 case 0xC5: r = isEnglish ? _T("Current pending sector count") : _T("不安定セクター数");
169 break;
170 case 0xC6: r = isEnglish ? _T("Offline scan uncorrectable count") : _T("未訂正エラー数");
171 break;
172 case 0xC7: r = isEnglish ? _T("UDMA CRC error rate") : _T("UltraDMA CRCエラー");
173 break;
174 case 0xC8: r = isEnglish ? _T("Write error rate") : _T("書き込みエラー率");
175 break;
176 //case 0xC9:
177 case 0xCA: r = isEnglish ? _T("Data Address Mark errors") : _T("DAM(Data Address Mark)エラー");
178 break;
179 case 0xCB: r = isEnglish ? _T("Run out cancel") : _T("ECCエラー");
180 break;
181 case 0xCC: r = isEnglish ? _T("Soft ECC correction") : _T("論理ECC訂正");
182 break;
183 case 0xCD: r = isEnglish ? _T("Thermal asperity rate(TAR)") : _T("熱エラー率(TAR)");
184 break;
185 case 0xCE: r = isEnglish ? _T("Flying height") : _T("ヘッド高");
186 break;
187 case 0xCF: r = isEnglish ? _T("Spin high current") : _T("最大回転電流");
188 break;
189 case 0xD0: r = isEnglish ? _T("Spin buzz") : _T("ヘッド制御");
190 break;
191 case 0xD1: r = isEnglish ? _T("Offline seek performance") : _T("オフライン・シーク性能");
192 break;
193 case 0xDC: r = isEnglish ? _T("Disk shift") : _T("ディスク交換");
194 break;
195 case 0xDD: r = isEnglish ? _T("G-sense error rate") : _T("加速度センサー検出エラー率");
196 break;
197 case 0xDE: r = isEnglish ? _T("Loaded hours") : _T("利用時間");
198 break;
199 case 0xDF: r = isEnglish ? _T("Load/unload retry count") : _T("ロード/アンロード再試行回数");
200 break;
201 case 0xE0: r = isEnglish ? _T("Load friction") : _T("ロード抵抗");
202 break;
203 case 0xE1: r = isEnglish ? _T("Load/Unload cycle count") : _T("ロード/アンロード・サイクル数");
204 break;
205 case 0xE2: r = isEnglish ? _T("Load-in time") : _T("ロードイン時間");
206 break;
207 case 0xE3: r = isEnglish ? _T("Torque amplification count") : _T("トルク増幅数");
208 break;
209 case 0xE4: r = isEnglish ? _T("Power-off retract count") : _T("電源切断退避数");
210 break;
211 case 0xE6: r = isEnglish ? _T("GMR head amplitude") : _T("GMRヘッド振幅");
212 break;
213 case 0xE7: r = isEnglish ? _T("Temperature") : _T("温度");
214 break;
215 case 0xF0: r = isEnglish ? _T("Head flying hours") : _T("シーク移動時間");
216 break;
217 case 0xFA: r = isEnglish ? _T("Read error retry rate") : _T("読み込みエラー再試行数");
218 break;
219 default:
220 r = isEnglish ? _T("Unknown") : _T("不明");
221 break;
222 }
223 return r;
224 }
225 };
226
227
228 //---------------------------------------------------------
229
230
232 CSmartAccessor(void) : m_isValidVersion(false)
233 {
234 }
235
243 bool Collect(int deviceNo)
244 {
245 m_isValidVersion = false;
246 return m_Collect(deviceNo);
247 }
248
254 const TVersion* GetVersion(void) const
255 {
256 return m_isValidVersion ? &m_version : NULL;
257 }
258
264 size_t GetAttributeCount(void) const
265 {
266 return m_infos.GetSize();
267 }
268
275 const TAttribute* GetAttribute(INDEX index) const
276 {
277 if ( m_infos.IsInRange(index) )
278 {
279 return m_infos[index];
280 }
281 return NULL;
282 }
283
290 const TAttribute* FindAttributeId(BYTE id) const
291 {
292 loop ( i, m_infos.GetSize() )
293 {
294 if ( m_infos[i]->bAttrID == id )
295 {
296 return m_infos[i];
297 }
298 }
299 return NULL;
300 }
301
307 int GetTemperature(void) const
308 {
309 const TAttribute* p = FindAttributeId(0xC2/*温度*/);
310 if ( p != NULL )
311 {
312 return p->bRawValue[0];
313 }
314 return -1;
315 }
316
322 int GetPowerOnHoursCount(void) const
323 {
324 const TAttribute* p = FindAttributeId(0x09/*合計利用時間*/);
325 if ( p != NULL )
326 {
327 return ToInt(p->GetValue());
328 }
329 return -1;
330 }
331
337 int GetPowerCycleCount(void) const
338 {
339 const TAttribute* p = FindAttributeId(0x0C/*電源投入回数*/);
340 if ( p != NULL )
341 {
342 return ToInt(p->GetValue());
343 }
344 return -1;
345 }
346
347private:
348 enum
349 {
350 DFP_GET_VERSION = 0x00074080,
351 DFP_RECEIVE_DRIVE_DATA = 0x0007c088,
352 };
353 #pragma pack(push,1)
354 struct TReadAttrData : SENDCMDOUTPARAMS
355 {
356 BYTE bb[READ_ATTRIBUTE_BUFFER_SIZE - 1];
357 };
358 #pragma pack(pop)
359 // 収集
360 bool m_Collect(int deviceNo)
361 {
362 CStr dev;
363 dev.Format(_T("\\\\.\\PhysicalDrive%d"), deviceNo);
364 HANDLE h = ::CreateFile(dev, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
365 if ( h == INVALID_HANDLE_VALUE )
366 {
367 return false;
368 }
369 DWORD dwReturned;
370 //== Version
371 bool r1 = !! ::DeviceIoControl(h, DFP_GET_VERSION, NULL, 0, &m_version, sizeof(m_version), &dwReturned, NULL);
372 if ( ! r1 )
373 {
374 ::CloseHandle(h);
375 return false;
376 }
377 m_isValidVersion = true;
378 //== 属性取得
379 SENDCMDINPARAMS sc; //sSendCmd;
380 TReadAttrData ra; //sSendCmdOutParam;
381 Zero(sc);
382 Zero(ra);
383 sc.irDriveRegs.bFeaturesReg = READ_ATTRIBUTES;
384 sc.irDriveRegs.bCylLowReg = SMART_CYL_LOW;
385 sc.irDriveRegs.bCylHighReg = SMART_CYL_HI;
386 sc.irDriveRegs.bDriveHeadReg = static_cast<BYTE>(0xA0 | ((deviceNo & 1) << 4)); //ドライブ番号
387 sc.irDriveRegs.bCommandReg = SMART_CMD; //SMART READ DATAコマンド番号
388 sc.cBufferSize = READ_ATTRIBUTE_BUFFER_SIZE;
389 sc.bDriveNumber = static_cast<BYTE>(deviceNo); //ドライブ番号
390 bool r2 = !! ::DeviceIoControl(h, DFP_RECEIVE_DRIVE_DATA, &sc, sizeof(sc), &ra, sizeof(ra), &dwReturned, NULL);
391 ::CloseHandle(h);
392 if ( r2 && dwReturned == sizeof(TReadAttrData) )
393 {
394 return m_SetRowData(READ_ATTRIBUTE_BUFFER_SIZE, ra.bBuffer);
395 }
396 return false;
397 }
399 bool m_SetRowData(size_t size, const void* pData)
400 {
401 m_infos.RemoveAll();
402 if ( size != READ_ATTRIBUTE_BUFFER_SIZE)
403 {
404 return false;
405 }
406 m_rowData.Reset(size, static_cast<const BYTE*>(pData));
407 TAttribute* pAttribute = reinterpret_cast<TAttribute*>(&m_rowData[2]);
408 loop ( i, 30 )
409 {
410 if ( pAttribute->bAttrID != 0 )
411 {
412 m_infos.Add(pAttribute);
413 }
414 pAttribute++;
415 }
416 return true;
417 }
418
419 CWorkMem m_rowData;
421 TVersion m_version;
422 bool m_isValidVersion;
423};
424
425
426
427}; // TNB
428
429
430
#define loop(VAR, CNT)
loop構文.
Definition: TnbDef.h:343
簡易配列型情報管理関係のヘッダ
文字列管理関係のヘッダ
[ETC] コピー不可能スーパークラス.
Definition: TnbDef.h:599
簡易配列型情報管理テンプレート
SMART (Self Monitoring, Analysis and Reporting Technology)アクセスクラス.
const TAttribute * FindAttributeId(BYTE id) const
[取得] 属性情報取得.
const TAttribute * GetAttribute(INDEX index) const
[取得] 属性情報取得.
size_t GetAttributeCount(void) const
[取得] 属性数取得.
int GetTemperature(void) const
[取得] 温度情報取得.
CSmartAccessor(void)
コンストラクタ
const TVersion * GetVersion(void) const
[取得] バージョン情報取得.
int GetPowerCycleCount(void) const
[取得] 電源投入回数取得.
bool Collect(int deviceNo)
[取得] 収集.
int GetPowerOnHoursCount(void) const
[取得] 合計利用時間取得.
void Format(const TYP *lpszFormat,...)
[代入] 書式付き文字列代入.
Definition: TnbStr.h:359
void Reset(size_t l, const TYP *P)
[設定] 再設定
Definition: TnbDef.h:690
int ToInt(LPCSTR lpsz, int iBase=10)
[変換] INT変換(ASCII/SJIS用).
Definition: TnbStrLib.h:367
void Zero(V &value)
[設定] ゼロクリア.
Definition: TnbDef.h:399
TNB Library
Definition: TnbDoxyTitle.txt:2
WORD bRawValue[3]
Un-normalized value
static CStr GetAttributeIdString(BYTE attributeId, bool isEnglish=true)
[取得] 属性ID文字列取得
BYTE bAttrValue
Current normalized value
BYTE bWorstValue
How bad has it ever been?
CStr GetAttributeIdString(bool isEnglish=true) const
[取得] 属性ID文字列取得
BYTE bAttrID
Identifies which attribute
ULONGLONG GetValue(void) const
[取得] Un-normalized value取得 bRawValue[3] を 48bit 値として返します。
WORD wStatusFlags
see bit definitions below
CStr ToString(void) const
[取得] 文字列化 現在の値 ワーストの値 生データx6 の文字列を生成します。
SMART バージョン情報
DWORD fCapabilities
Bit mask of driver capabilities.
DWORD dwReserved[4]
For future use.
BYTE bIDEDeviceMap
Bit map of IDE devices.
BYTE bRevision
Binary driver revision.
BYTE bVersion
Binary driver version.