SerialNumberの取得(2)
Vistaのレジストリ情報とXPでは違っていたみたいで、このロジックでは取得できなくなってしまった。
WmiToolsを眺めていると、
Win32_PhysicalMediaに"SerialNumber"情報が入っていて、欲しい情報が取得できるみたいです。
WmiResult disk_drive = wmi.access(_T("SELECT * FROM Win32_DiskDrive")); if (disk_drive.items() == 0) { String msg = wmi.getErrorMessage(); return; } COUT << disk_drive.print(); for (size_t i = 0; i < disk_drive.size(); i++) { String drive = WmiCall::escape(disk_drive.getString(String(_T("DeviceID")), i)); String sub_select = WmiCall::createSelect(_T("ASSOCIATORS OF {Win32_DiskDrive.DeviceID=\"%s\"} WHERE AssocClass = Win32_DiskDrivePhysicalMedia ResultClass = Win32_PhysicalMedia"), drive.c_str(), NULL); WmiResult media = wmi.access(sub_select); if (media.items() > 0) { COUT << _T("SerialNumber = ") << media.getString(_T("SerialNumber")) << endl; } }
こんな感じでVistaでも取れるようになりました。
ついでにWimCallクラスの中に、escapeと言う名前のメソッドを作成しました。
/* * 文字列中の'\'をエスケープするために'\\'になるように変換した文字列を返す * param : 処理の対象となる文字列(String) * * return : String */ String WmiCall::escape(String original) { size_t spos = 0, epos = String::npos; String token = String(_T("")); do { epos = original.find_first_of(_T("\\"), spos); if (epos != String::npos) { size_t count = epos - spos + 1; token.append(original.substr(spos, count)); token.append(_T("\\")); } else { token.append(original.substr(spos)); } spos = epos + 1; } while (epos != String::npos); return token; }
これは、disk_drive.getString(String(_T("DeviceID")), i)の処理の結果として
\\.\PHYSICALDRIVE1
と言う値が帰ってくるので、これを次のWQL文に変換する時には、
\\\\.\\PHYSICALDRIVE1
のように、"\"を"\\"にエスケープするために作成しました。