HEXA BLOG

プログラム

HEXA BLOGプログラム2011.6.23

ドングル

すっかり梅雨ですが雨雨にも負けず、
休日はバイクで駆け抜けるgood sun晴れこと山口です。
お久しぶりで御座います。
さて少し前に自宅での3DCGのアニメーション用に
messiah studio(http://www.projectmessiah.com/)というソフトを超キャンペーン価格で購入したのですが、
このソフトのライセンス認証が少し面白い仕組みになっていました。
市販のUSBメモリをハードウェアキーとして動作させるのです。
昔はライセンス認証の為だけに専用のドングルと呼ばれるハードウェアを使っていたのですが、
果たして市販のUSBメモリがその役目を果たせるのか気になったので少し調べてみました。
するとWindowsではWMIという機能でディスクドライブのユニークなIDを取得できるようです。
ソースコードも沢山見つける事が出来たのですが、
C#やVBのコードばかりでしたので、C++ではどう書いたら良いのか試しに書いてみました。
今回はUSBのディスクドライブを列挙してその固有IDを表示するものです。
(ソースコードはVisualStudio2010のコンソールアプリケーションで動作確認しています。)

#define _WIN32_DCOM
#include <iostream>
#include <windows.h>
#include <chstring.h>
#include <comdef.h>
#include <Wbemidl.h>
using namespace std;
#pragma comment(lib, "wbemuuid.lib")
int main(int argc, char **argv){
IWbemLocator *wbem_locator = NULL;
IWbemServices *wbem_services = NULL;
IEnumWbemClassObject *wbem_enumerator = NULL;
// まずはCOMの初期化とか
CoInitializeEx(0, COINIT_MULTITHREADED);
CoInitializeSecurity(NULL, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL, EOAC_NONE, NULL);
// WMIにアクセスするためのインスタンス作成
CoCreateInstance(CLSID_WbemLocator, 0,
CLSCTX_INPROC_SERVER, IID_IWbemLocator, reinterpret_cast<LPVOID*>&wbem_locator));
// root\cimv2名前空間に接続
wbem_locator->ConnectServer(_bstr_t(L"\\\\.\\ROOT\\CIMV2"),
NULL, NULL, 0, NULL,
0, 0, &wbem_services);
CoSetProxyBlanket(wbem_services,
RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
// USBインターフェースのディスクドライブを取得するクエリを発行
wbem_services->ExecQuery(bstr_t(L"WQL"),
bstr_t(L"SELECT * FROM Win32_DiskDrive WHERE InterfaceType='USB'"),
WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
NULL, &wbem_enumerator);
IWbemClassObject *wbem_object = NULL;
ULONG returned = 0;
while(wbem_enumerator){
wbem_enumerator->Next(WBEM_INFINITE, 1, &wbem_object, &returned);
if(returned == 0){
break;
}
VARIANT value;
VariantInit(&value);
// ここで取得できる文字列がUSBの固有ID
wbem_object->Get(L"PNPDeviceID", 0, &value, 0, 0);
cout << static_cast<char*>(bstr_t(value)) << endl;
VariantClear(&value);
}
wbem_services->Release();
wbem_locator->Release();
wbem_enumerator->Release();
if(wbem_object){
wbem_object->Release();
}
CoUninitialize();
return 0;
}

COMの初期化関係で行数が多いですが、
実質はインスタンス作成部分から固有ID取得までが目的の処理になります。
この固有IDを基にしたライセンスファイルを作成して、
アプリケーション起動時に二つの整合性を確認出来れば確かにハードウェアキーとして使えそうです。
面白くなってきたのでもしかしたら次回に続くかもしれないです。

RECRUIT

大阪・東京共にスタッフを募集しています。
特にキャリア採用のプログラマー・アーティストに興味がある方は下のボタンをクリックしてください

RECRUIT SITE