// KeyDecoder.cpp
#include "StdAfx.h"
#include "keydecoder.h"
int KeyDecoder::DecodeProductKey(KeyDecoder::Key key, char* pKey)
{
byte* pEncodedPID = GetRegistryDigitalProductId(key);
int keyLen = 0;
if(pEncodedPID)
{
char* pDecodedPID = DecodeProductKey(pEncodedPID);
if(pDecodedPID)
{
keyLen = (int)::strlen(pDecodedPID);
if(pKey)
{
::strcpy(pKey, pDecodedPID);
}
delete[] pDecodedPID;
}
}
return keyLen + 1;
}
char* KeyDecoder::DecodeProductKey(byte* digitalProductId)
{
// Offset of first byte of encoded product key in
// 'DigitalProductIdxxx" REG_BINARY value. Offset = 34H.
const int keyStartIndex = 52;
// Offset of last byte of encoded product key in
// 'DigitalProductIdxxx" REG_BINARY value. Offset = 43H.
const int keyEndIndex = keyStartIndex + 15;
// Possible alpha-numeric characters in product key.
char digits[] =
{
'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'M', 'P', 'Q', 'R',
'T', 'V', 'W', 'X', 'Y', '2', '3', '4', '6', '7', '8', '9',
};
// Length of decoded product key
const int decodeLength = 29;
// Length of decoded product key in byte-form.
// Each byte represents 2 chars.
const int decodeStringLength = 15;
// Array of containing the decoded product key.
char* pDecodedChars = new char[decodeLength + 1];
::memset(pDecodedChars, 0, decodeLength + 1);
// Extract byte 52 to 67 inclusive.
byte hexPid[keyEndIndex - keyStartIndex + 1];
for (int i = keyStartIndex; i <= keyEndIndex; i++)
{
hexPid[i - keyStartIndex] = digitalProductId[i];
}
for (int i = decodeLength - 1; i >= 0; i--)
{
// Every sixth char is a separator.
if ((i + 1) % 6 == 0)
{
*(pDecodedChars + i) = '-';
}
else
{
// Do the actual decoding.
int digitMapIndex = 0;
for (int j = decodeStringLength - 1; j >= 0; j--)
{
int byteValue = (digitMapIndex << 8) | hexPid[j];
hexPid[j] = (byte)(byteValue / 24);
digitMapIndex = byteValue % 24;
*(pDecodedChars + i) = digits[digitMapIndex];
}
}
}
return pDecodedChars;
}
byte* KeyDecoder::GetRegistryDigitalProductId(KeyDecoder::Key key)
{
HKEY hKey = 0;
LONG lResult = 0L;
const char* pPIDName = "DigitalProductId";
byte* pPID = 0;
switch(key)
{
case KeyDecoder::Key::XP:
lResult = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
0, KEY_QUERY_VALUE, &hKey);
break;
case KeyDecoder::Key::Office10:
break;
case KeyDecoder::Key::Office11:
break;
}
if(lResult == ERROR_SUCCESS)
{
DWORD cbData = 0;
DWORD dwType = 0;
lResult = ::RegQueryValueEx(hKey, pPIDName, 0, &dwType, 0, &cbData);
if(lResult == ERROR_SUCCESS)
{
pPID = new byte[cbData];
lResult = ::RegQueryValueEx(hKey, pPIDName, 0, &dwType, pPID, &cbData);
if(lResult != ERROR_SUCCESS)
{
delete[] pPID;
pPID = 0;
}
}
}
if(hKey)
{
::RegCloseKey(hKey);
}
return pPID;
}
|