union uINT16Data
{
int16_t val;
BYTE buf[2];
};
union uINT32Data
{
int32_t val;
BYTE buf[4];
};
union uINT64Data
{
int64_t val;
BYTE buf[8];
};
union uDOUBLEData
{
double_t val;
BYTE buf[8];
};
//(ads_md5 '(39 50 50 5 33 36 37 37 25 29 31 32 32 1 19 24 24 25 28 29 13 14 14 17 18 21 21 23 12))
static int ads_ads_md5(void)
{
constexpr size_t MD5LEN = 16;
constexpr CHAR rgbDigits[] = "0123456789abcdef";
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
BYTE rgbHash[MD5LEN];
DWORD cbHash = 0, dwStatus = 0;
std::vector<BYTE> bytes;
unique_resbuf_ptr pArgs(acedGetArgs());
for (resbuf* pTail = pArgs.get(); pTail != nullptr; pTail = pTail->rbnext)
{
switch (pTail->restype)
{
case RTSHORT:
{
uINT16Data dbl{ pTail->resval.rint };
for (size_t idx = 0; idx < 2; idx++)
bytes.push_back(dbl.buf[idx]);
}
break;
case RTLONG:
{
uINT32Data dbl{ pTail->resval.rlong };
for (size_t idx = 0; idx < 4; idx++)
bytes.push_back(dbl.buf[idx]);
}
break;
case RTREAL:
{
uDOUBLEData dbl{ pTail->resval.rreal };
for (size_t idx = 0; idx < 8; idx++)
bytes.push_back(dbl.buf[idx]);
}
break;
case RTPOINT:
{
{
uDOUBLEData dbl{ pTail->resval.rpoint[0] };
for (size_t idx = 0; idx < 8; idx++)
bytes.push_back(dbl.buf[idx]);
}
{
uDOUBLEData dbl{ pTail->resval.rpoint[1] };
for (size_t idx = 0; idx < 8; idx++)
bytes.push_back(dbl.buf[idx]);
}
}
break;
case RT3DPOINT:
{
{
uDOUBLEData dbl{ pTail->resval.rpoint[0] };
for (size_t idx = 0; idx < 8; idx++)
bytes.push_back(dbl.buf[idx]);
}
{
uDOUBLEData dbl{ pTail->resval.rpoint[1] };
for (size_t idx = 0; idx < 8; idx++)
bytes.push_back(dbl.buf[idx]);
}
{
uDOUBLEData dbl{ pTail->resval.rpoint[2] };
for (size_t idx = 0; idx < 8; idx++)
bytes.push_back(dbl.buf[idx]);
}
}
break;
case RTSTR:
{
std::string str = wstr_to_utf8(pTail->resval.rstring);
for (auto ch : str)
bytes.push_back(ch);
}
break;
default:
break;
}
}
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
dwStatus = GetLastError();
acutPrintf(L"CryptAcquireContext failed: %d\n", dwStatus);
acedRetNil();
return (RSRSLT);
}
if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
{
dwStatus = GetLastError();
acutPrintf(L"CryptAcquireContext failed: %d\n", dwStatus);
acedRetNil();
return (RSRSLT);
}
if (!CryptHashData(hHash, bytes.data(), bytes.size(), 0))
{
dwStatus = GetLastError();
acutPrintf(L"CryptHashData failed: %d\n", dwStatus);
CryptReleaseContext(hProv, 0);
CryptDestroyHash(hHash);
acedRetNil();
return dwStatus;
}
CString hash;
cbHash = MD5LEN;
if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0))
{
for (DWORD i = 0; i < cbHash; i++)
{
hash += (wchar_t(rgbDigits[rgbHash[i] >> 4]));
hash += (wchar_t(rgbDigits[rgbHash[i] & 0xf]));
}
acedRetStr(hash);
}
else
{
dwStatus = GetLastError();
acutPrintf(L"CryptGetHashParam failed: %d\n", dwStatus);
}
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
return (RSRSLT);
}