Win8対応のプロダクトキー取得処理

VC++で作ったソフトからWindowsの
プロダクトキーを取得したいってコトがあって、色々と調べてみた。
日本語の情報自体は結構あったけど、なぜか内容がバラバラで・・・

レジストリ内の
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersionの「DigitalProductId」を使うとか、「DigitalProductId4」を使うとか、
データ位置に関しても幾つかの情報を見掛けたり・・・

ただ、どの情報を試してもWin8じゃ正常に取れない・・・!
で、延々と調べ続けて、海外のフォーラムで
ようやくそれらしい情報が!
これ とか これ がまさにそれ。

フォーラムに書いてあるコードがVBSだから、
参考にしつつVC++で書き直してみた。

bool GetWindowsProductKey(char key[30])
{
	bool ret = false;
	HKEY hKey = nullptr;

	// レジストリを開く
	if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
		_T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"),
		0, KEY_READ | KEY_WOW64_64KEY, &hKey) == ERROR_SUCCESS)
	{
		DWORD size, type;
		// 必要なバッファのサイズを取得
		if (RegQueryValueEx(hKey, _T("DigitalProductId"),
			nullptr, &type, nullptr, &size) == ERROR_SUCCESS)
		{
			BYTE *buff = new BYTE[size];
			// データを取得
			if (RegQueryValueEx(hKey, _T("DigitalProductId"),
				nullptr, &type, buff, &size) == ERROR_SUCCESS)
			{
				const int keyStartIndex = 52;
				const char digits[] = "BCDFGHJKMPQRTVWXY2346789";

				// Windows 8かどうか
				BYTE isWin8 = static_cast<BYTE>(buff[66] / 6) & 1;
				buff[66] = (buff[66] & 0xF7) | ((isWin8 & 2) * 4);
				
				int cur = 0;
				for (int i = 24; i >= 0; --i)
				{
					cur = 0;
					for (int x = keyStartIndex + 14; x >= keyStartIndex; --x)
					{
						cur = (cur << 8) | buff[x];
						buff[x] = static_cast<BYTE>(cur / 24);
						cur = cur % 24;
					}
					key[i] = digits[cur];
				}

				if (isWin8 == 1)
				{
					memmove_s(key, cur, key + 1, cur);
					key[cur] = 'N';
				}

				memmove_s(key + 24, 5, key + 20, 5);
				key[23] = '-';
				memmove_s(key + 18, 5, key + 15, 5);
				key[17] = '-';
				memmove_s(key + 12, 5, key + 10, 5);
				key[11] = '-';
				memmove_s(key + 6, 5, key + 5, 5);
				key[5] = '-';
				key[29] = '\0';

				ret = true;
			}

			delete [] buff;
		}

		// レジストリを閉じる
		RegCloseKey(hKey);
	}
	
	return ret;
}

とりあえず処理は合ってるはず・・・?
実際に文字に変換してるところの処理はサッパリ分からない・・・(汗
Win8のときの特別な処理は、元のVBSのソースを見てると、
なんだか複雑な文字列処理をしてるように見えるんだけど、
要は最後に出てきたcurの位置に’N’を入れたいだけっぽい?
何故これで取得できるのかは分からない・・・

一応自分が使ってるマシンでは正常に取得できたー
で、色々と調べたのは良いけど、結局使わなかったという・・・(苦笑)
ま、参考までにー

じゃ、ゲームして寝るー
バイニー☆

test?

コメントを残す