#include "stdafx.h" #include "TDbDwgLicense.h" #include "migrtion.h" #include "dbproxy.h" #include #include #include #include "dbapserv.h" #include "wincrypt.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #ifndef MAX_STRING #define MAX_STRING 255 #endif #define VERSION_TDBINTERFACEMSGOBJ 1 //{{AFX_ARX_MACRO ACRX_DXF_DEFINE_MEMBERS(CDbDwgLicense, AcDbXrecord, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, AcDbProxyObject::kNoOperation, ATSDWGLICENSE, "ATSDWGLICENSE图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com"); //}}AFX_ARX_MACRO CDbDwgLicense::CDbDwgLicense() { } CDbDwgLicense::~CDbDwgLicense() { } static std::map g_mapDwgLicensePass; static int g_nLock = 0; BOOL GetDocLicenser() { //1.没有授权对象,直接返回通过 if(g_mapDwgLicensePass.empty()) { return TRUE; } //2.有授权加密对象,判断时效 typedef std::map::iterator It; const TCHAR* pszFileName = NULL; acdbCurDwg()->getFilename(pszFileName); if (pszFileName != NULL) { It it = g_mapDwgLicensePass.find(pszFileName); if (it != g_mapDwgLicensePass.end()) { return (*it).second; } else { return TRUE; } } return FALSE; } void SetDwgInFieldsLock(BOOL bLock) { g_nLock = bLock ? 1 : 0; } Acad::ErrorStatus CDbDwgLicense::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es; // Call dwgOutFields from AcDbXrecord if ((es = AcDbXrecord::dwgOutFields(pFiler)) != Acad::eOk) { return es; } return pFiler->filerStatus(); } Acad::ErrorStatus CDbDwgLicense::dwgInFields(AcDbDwgFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es; //Call dwgInFields from AcDbXrecord if ((es = AcDbXrecord::dwgInFields(pFiler)) != Acad::eOk) { return es; } //校对检查 if (!g_nLock) { //只对owner包含的有效的license验证 if (OwnerHasThisLicense(objectId())) { VerifyLicense(); } } return pFiler->filerStatus(); } void CDbDwgLicense::copied(const AcDbObject* dbObj,const AcDbObject* newObj) { assertNotifyEnabled(); AcDbBlockTableRecord* pObjRec = AcDbBlockTableRecord::cast(newObj); if (pObjRec != NULL && pObjRec->database() != database()) { AcDbDatabase* pDb = pObjRec->database(); ASSERT(pDb != NULL); const TCHAR* pszName; pObjRec->getName(pszName); if (_tcsicmp(pszName,ACDB_MODEL_SPACE) == 0) { g_nLock = 1; //创建注册应用程序 AcDbRegAppTable* pTbl = NULL; pDb->getRegAppTable(pTbl,AcDb::kForWrite); if (pTbl != NULL) { if (!pTbl->has(_T("TPMLCNS"))) { AcDbRegAppTableRecord* pRegTblRec = new AcDbRegAppTableRecord; pRegTblRec->setName(_T("TPMLCNS")); pTbl->add(pRegTblRec); pRegTblRec->close(); } pTbl->close(); } //创建一个授权载体对象 AcDbObjectId id; CDbLicenseCarrier* pLnsCarrier = new CDbLicenseCarrier; pObjRec->appendAcDbEntity(id,pLnsCarrier); //附加授权扩展数据 struct resbuf* pRb = NULL; rbChain(&pRb); struct resbuf* pHead = acutNewRb(AcDb::kDxfRegAppName); acutNewString(_T("TPMLCNS"), pHead->resval.rstring); pHead->rbnext = pRb; Acad::ErrorStatus es = pLnsCarrier->setXData(pHead); if (pHead != NULL) acutRelRb(pHead); pLnsCarrier->close(); g_nLock = 0; } } } BOOL CDbDwgLicense::OwnerHasThisLicense(const AcDbObjectId& id) { BOOL bHas = FALSE; AcDbObjectId idOwner = ownerId(); if (idOwner.isValid()) { AcDbDictionary* pDic = NULL; if (Acad::eOk == acdbOpenAcDbObject((AcDbObject*&)pDic,idOwner,AcDb::kForRead)) { if (pDic->has(objectId())) { bHas = TRUE; } pDic->close(); } } return bHas; } /* ------------------------------------------------------------------------------------------------ 返回: TRUE : 通过 FALSE : 不通过 ---------------------------------------------------------------------------------------------------*/ BOOL CDbDwgLicense::VerifyLicense() { assertWriteEnabled(); /* //授权信息 2008-03-02|2008-09-09|lfy|lh|2009-04-01:09|192.168.0.8|tpm|sa|21|md5 //校验码对 2008-03-02|2008-09-09|lfy|lh|***|192.168.0.8 校对 //预留默认 授权码,GUID,作为图纸打开的键值 //预留默认 2009 */ int nSuccess = 0; //1.检查该图纸是否校验过了 char szLicense[MAX_STRING]; memset(szLicense,0,MAX_STRING); char szVerify[MAX_STRING]; memset(szVerify,0,MAX_STRING); char szReserv[MAX_STRING]; memset(szReserv,0,MAX_STRING); long lReserv = 0; int nResv = GetLicenseInfo(szLicense,szVerify,szReserv,lReserv); if (nResv == 0) //没有授权信息 { return FALSE; } //有授权信息,但授权信息不完整,可能被破坏,图纸不能正常显示 if (nResv > 0 && nResv < 4) { WritePassword("0987654321"); return FALSE; } AcDbObjectId idNewLns; if (nResv == 4) //有授权信息,但授权信息完整,开始解析 { nSuccess = ImpVerifyLicense(szLicense,szVerify,szReserv,lReserv,idNewLns); if (!nSuccess) { char szPassword[33]; memset(szPassword,0,33); int nRes = ParserTPMmd5(szLicense,szPassword); if (nRes) { WritePassword(szPassword); } else { WritePassword("0987654321"); } } else { WritePassword(NULL); } } AcDbDatabase* pDb = database(); if (pDb != NULL) { const TCHAR* pszFileName = NULL; pDb->getFilename(pszFileName); if (pszFileName != NULL) { std::pair pa(pszFileName,nSuccess); if (g_mapDwgLicensePass.find(pszFileName) == g_mapDwgLicensePass.end()) { g_mapDwgLicensePass.insert(pa); } else { g_mapDwgLicensePass[pszFileName] = nSuccess; } } } //确保授权信息对象监控模型空间 if (idNewLns.isNull()) { AcDbBlockTable* pBTbl = NULL; database()->getBlockTable(pBTbl,AcDb::kForRead); if (pBTbl != NULL) { AcDbBlockTableRecord* pRec = NULL; pBTbl->getAt(ACDB_MODEL_SPACE,pRec,AcDb::kForWrite); if (pRec != NULL) { pRec->removePersistentReactor(objectId()); pRec->addPersistentReactor(objectId()); pRec->close(); } pBTbl->close(); } } return nSuccess; } void CDbDwgLicense::WritePassword(const char* pszPassword) { #if ADS>15 const SecurityParams* pParams = acdbCurDwg()->cloneSecurityParams(); if (pszPassword == NULL) //取消密码 { if (pParams != NULL) { AcDbDatabase::disposeSecurityParams(pParams); acdbCurDwg()->setSecurityParams(pParams); } } else // 设pszPassword 的 md5 密码 { AcDbDatabase::disposeSecurityParams(pParams); SecurityParams* pParams2 = new SecurityParams; memset((void*)pParams2,0,sizeof(SecurityParams)); pParams2->cbSize = sizeof(SecurityParams); int nLen = sizeof(char); int nLen2 = sizeof(wchar_t); pParams2->wszPassword = new wchar_t[33];//2664D1A4F50466DDA0F2C650DE10D692 memset(pParams2->wszPassword,0,33 * sizeof(wchar_t)); mbstowcs(pParams2->wszPassword,pszPassword,33); pParams2->ulAlgId = SECURITYPARAMS_ALGID_RC4; // Must always be this value. pParams2->ulFlags = SECURITYPARAMS_ENCRYPT_DATA; pParams2->ulKeyLength = 40; pParams2->ulProvType = PROV_RSA_FULL;// Defined in wincrypt.h pParams2->wszProvName = (LPTSTR)(L"Microsoft Base Cryptographic Provider v1.0"); acdbCurDwg()->setSecurityParams(pParams2); delete pParams2; } #endif } #define S11 7 #define S12 12 #define S13 17 #define S14 22 #define S21 5 #define S22 9 #define S23 14 #define S24 20 #define S31 4 #define S32 11 #define S33 16 #define S34 23 #define S41 6 #define S42 10 #define S43 15 #define S44 21 /* F, G, H and I are basic MD5 functions. */ #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | (~z))) /* ROTATE_LEFT rotates x left n bits. */ #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. Rotation is separate from addition to prevent recomputation. */ #define FF(a, b, c, d, x, s, ac) { \ (a) += F ((b), (c), (d)) + (x) + ac; \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define GG(a, b, c, d, x, s, ac) { \ (a) += G ((b), (c), (d)) + (x) + ac; \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define HH(a, b, c, d, x, s, ac) { \ (a) += H ((b), (c), (d)) + (x) + ac; \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define II(a, b, c, d, x, s, ac) { \ (a) += I ((b), (c), (d)) + (x) + ac; \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } const byte CDbDwgLicense::ImpMD5::PADDING[64] = { 0x80 }; const char CDbDwgLicense::ImpMD5::HEX[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; /* Default construct. */ CDbDwgLicense::ImpMD5::ImpMD5() { reset(); } /* Construct a MD5 object with a input buffer. */ CDbDwgLicense::ImpMD5::ImpMD5(const void* input, size_t length) { reset(); update(input, length); } /* Construct a MD5 object with a string. */ CDbDwgLicense::ImpMD5::ImpMD5(const std::string& str) { reset(); update(str); } /* Construct a MD5 object with a file. */ CDbDwgLicense::ImpMD5::ImpMD5(std::ifstream& in) { reset(); update(in); } /* Return the message-digest */ const byte* CDbDwgLicense::ImpMD5::digest() { if (!m_finished) { m_finished = true; final(); } return m_digest; } /* Reset the calculate state */ void CDbDwgLicense::ImpMD5::reset() { m_finished = false; /* reset number of bits. */ m_count[0] = m_count[1] = 0; /* Load magic initialization constants. */ m_state[0] = 0x67452301; m_state[1] = 0xefcdab89; m_state[2] = 0x98badcfe; m_state[3] = 0x10325476; } /* Updating the context with a input buffer. */ void CDbDwgLicense::ImpMD5::update(const void* input, size_t length) { update((const byte*)input, length); } /* Updating the context with a string. */ void CDbDwgLicense::ImpMD5::update(const std::string& str) { update((const byte*)str.c_str(), str.length()); } void CDbDwgLicense::ImpMD5::update(const std::wstring& str) { update((const byte*)str.c_str(), str.length()); } /* Updating the context with a file. */ void CDbDwgLicense::ImpMD5::update(std::ifstream& in) { if (!in) { return; } std::streamsize length; char buffer[BUFFER_SIZE]; while (!in.eof()) { in.read(buffer, BUFFER_SIZE); length = in.gcount(); if (length > 0) { update(buffer, length); } } in.close(); } /* MD5 block update operation. Continues an MD5 message-digest operation, processing another message block, and updating the context. */ void CDbDwgLicense::ImpMD5::update(const byte* input, size_t length) { uint32 i, index, partLen; m_finished = false; /* Compute number of bytes mod 64 */ index = (uint32)((m_count[0] >> 3) & 0x3f); /* update number of bits */ if ((m_count[0] += ((uint32)length << 3)) < ((uint32)length << 3)) { ++m_count[1]; } m_count[1] += ((uint32)length >> 29); partLen = 64 - index; /* transform as many times as possible. */ if (length >= partLen) { memcpy(&m_buffer[index], input, partLen); transform(m_buffer); for (i = partLen; i + 63 < length; i += 64) { transform(&input[i]); } index = 0; } else { i = 0; } /* Buffer remaining input */ memcpy(&m_buffer[index], &input[i], length - i); } /* MD5 finalization. Ends an MD5 message-m_digest operation, writing the the message m_digest and zeroizing the context. */ void CDbDwgLicense::ImpMD5::final() { byte bits[8]; uint32 oldState[4]; uint32 oldCount[2]; uint32 index, padLen; /* Save current state and count. */ memcpy(oldState, m_state, 16); memcpy(oldCount, m_count, 8); /* Save number of bits */ encode(m_count, bits, 8); /* Pad out to 56 mod 64. */ index = (uint32)((m_count[0] >> 3) & 0x3f); padLen = (index < 56) ? (56 - index) : (120 - index); update(PADDING, padLen); /* Append length (before padding) */ update(bits, 8); /* Store state in digest */ encode(m_state, m_digest, 16); /* Restore current state and count. */ memcpy(m_state, oldState, 16); memcpy(m_count, oldCount, 8); } /* MD5 basic transformation. Transforms m_state based on block. */ void CDbDwgLicense::ImpMD5::transform(const byte block[64]) { uint32 a = m_state[0], b = m_state[1], c = m_state[2], d = m_state[3], x[16]; decode(block, x, 64); /* Round 1 */ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ /* Round 2 */ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ /* Round 3 */ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ /* Round 4 */ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ m_state[0] += a; m_state[1] += b; m_state[2] += c; m_state[3] += d; } /* Encodes input (ulong) into output (byte). Assumes length is a multiple of 4. */ void CDbDwgLicense::ImpMD5::encode(const uint32* input, byte* output, size_t length) { for (size_t i = 0, j = 0; j < length; ++i, j += 4) { output[j]= (byte)(input[i] & 0xff); output[j + 1] = (byte)((input[i] >> 8) & 0xff); output[j + 2] = (byte)((input[i] >> 16) & 0xff); output[j + 3] = (byte)((input[i] >> 24) & 0xff); } } /* Decodes input (byte) into output (ulong). Assumes length is a multiple of 4. */ void CDbDwgLicense::ImpMD5::decode(const byte* input, uint32* output, size_t length) { for (size_t i = 0, j = 0; j < length; ++i, j += 4) { output[i] = ((uint32)input[j]) | (((uint32)input[j + 1]) << 8) | (((uint32)input[j + 2]) << 16) | (((uint32)input[j + 3]) << 24); } } /* Convert byte array to hex string. */ std::string CDbDwgLicense::ImpMD5::bytesToHexString(const byte* input, size_t length) { std::string str; str.reserve(length << 1); for (size_t i = 0; i < length; ++i) { int t = input[i]; int a = t / 16; int b = t % 16; str.append(1, HEX[a]); str.append(1, HEX[b]); } return str; } /* Convert digest to string value */ std::string CDbDwgLicense::ImpMD5::toString() { return bytesToHexString(digest(), 16); } int CDbDwgLicense::ImpVerifyLicense(char* pszLicense,char* pszVerify,char* pszReserv,long& lReserv,AcDbObjectId& idLnsNew) { assertWriteEnabled(); ASSERT(pszLicense != NULL && pszVerify != NULL); /* 0 1 2 3 4 5 6 7 8 9 //授权信息 2008-03-02|2008-09-09|lfy|lh|2009-04-01:09|192.168.0.8|tpm|sa|21|md5 //校验码对 2008-03-02|2008-09-09|lfy|lh|***|192.168.0.8|tpm|sa|21| md5校验 //预留默认 授权码,GUID,作为图纸打开的键值 //预留默认 8 */ std::vector sSegments; int nCount = ParserContext(pszLicense,sSegments); std::string sSeed; if (nCount >= 10) { char chSpace = '|'; sSeed.append(sSegments.at(0)); sSeed += chSpace; sSeed.append(sSegments.at(1)); sSeed += chSpace; sSeed.append(sSegments.at(2)); sSeed += chSpace; sSeed.append(sSegments.at(3)); sSeed += chSpace; sSeed.append(sSegments.at(5)); sSeed += chSpace; sSeed.append(sSegments.at(6)); sSeed += chSpace; sSeed.append(sSegments.at(7)); sSeed += chSpace; sSeed.append(sSegments.at(8)); CDbDwgLicense::ImpMD5 md5; md5.update(sSeed); std::string sVerify2 = md5.toString(); //1. 验证码是否通过 BOOL bMD5Passed = FALSE; if (sVerify2.compare(pszVerify) == 0) { bMD5Passed = TRUE; } //1.1 验证码不通过,dwg文件授权信息修改过 if (!bMD5Passed) return FALSE; //2. TPM 服务器校验,重回到TPM环境 static const GUID IID_TPMApp = { 0x284f6e8b, 0x2d11, 0x4636, { 0xb4, 0x9d, 0xea, 0xf, 0x85, 0x4, 0x87, 0xa1 } }; ::CoInitialize(NULL); IUnknown* pUnk = NULL; ::GetActiveObject(IID_TPMApp, NULL, &pUnk); if (pUnk != NULL) { //获取主框架的disp接口 IDispatch FAR* pdisp = NULL; pUnk->QueryInterface(IID_IDispatch,(LPVOID*) &pdisp); HRESULT hr = 0; if (pdisp != NULL) { OLECHAR FAR *szMember = (LPTSTR)(L"DispTPMCommand"); DISPID dispid; hr = pdisp->GetIDsOfNames(IID_NULL, &szMember, 1,LOCALE_USER_DEFAULT, &dispid); if (SUCCEEDED(hr)) { VARIANTARG vararg[2]; VariantInit(&vararg[0]); VariantInit(&vararg[1]); DISPPARAMS dispparams; dispparams.rgvarg = vararg; dispparams.rgvarg[1].vt = VT_I4; // 32-bit integer dispparams.rgvarg[1].lVal = 65536; // here's our 100! BSTR bstr = 0; dispparams.rgvarg[0].vt = VT_BSTR | VT_BYREF; // dispparams.rgvarg[0].pbstrVal = &bstr; // VARIANT varRes; VariantInit(&varRes); varRes.vt = VT_I4; varRes.lVal = 0; dispparams.rgdispidNamedArgs = NULL; // name array dispparams.cArgs = 2; // total args dispparams.cNamedArgs = 0; // named args hr = pdisp->Invoke( dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, &varRes, NULL, NULL); if (SUCCEEDED(hr)) { _bstr_t bstTemp(bstr,true); std::string sComm; sComm.append(bstTemp); //成功,重新回到原来的TPM 环境 if (sComm.compare(sSegments.at(9)) == 0) { pdisp->Release(); pUnk->Release(); return TRUE; } } } pdisp->Release(); } pUnk->Release(); } //3. 时间校验 CTime tCur = CTime::GetCurrentTime(); int nYearFr,nMonFr,nDayFr,nHourFr; int nYearTo,nMonTo,nDayTo,nHourTo; FormatTime(sSegments.at(0),nYearFr,nMonFr,nDayFr,nHourFr); FormatTime(sSegments.at(1),nYearTo,nMonTo,nDayTo,nHourTo); CTime tFr(nYearFr,nMonFr,nDayFr,nHourFr,0,0); CTime tTo(nYearTo,nMonTo,nDayTo,nHourTo,0,0); int nYearLt,nMonLt,nDayLt,nHourLt; CTimeSpan tSpan1(0,23,59,59); tTo += tSpan1; if (tCur >= tFr && tCur <= tTo)//在授权的时间内 { //上次访问时间记录,小于上次访问时间说明用户更改了系统时间 FormatTime(sSegments.at(4),nYearLt,nMonLt,nDayLt,nHourLt); CTime tLt(nYearLt,nMonLt,nDayLt,nHourLt,0,0); if (tCur < tLt) //小于上次访问时间 { if (tLt < tTo)//如果最后一次时间没有记录,记录最后一次时间点 { //写新的时间记录点 //int nYear, int nMonth, int nDay, int nHour; CTime tNewPos(tCur.GetYear(),tCur.GetMonth(),tCur.GetDay(),tCur.GetHour(),0,0); idLnsNew = WriteXRecord(sSegments,tNewPos,4,pszVerify,pszReserv,lReserv); } return FALSE; } //上次记录的时间已经超出授权的时间范围 if (tLt > tTo || tLt < tFr) { return FALSE; } //时间验证通过,考虑记录新的时间 CTimeSpan tSpan = tCur - tLt; if (tSpan.GetDays() > 0) { //根据时间锁定码,判断是否时间有作弊现象 md5.update(sSegments.at(4)); std::string sLockVery = md5.toString(); if (sLockVery.compare(pszReserv) == 0) { //时间锁定,时间有作弊现象 return FALSE; } //写新的时间记录点 //int nYear, int nMonth, int nDay, int nHour; CTime tNewPos(tCur.GetYear(),tCur.GetMonth(),tCur.GetDay(),tCur.GetHour(),0,0); idLnsNew = WriteXRecord(sSegments,tNewPos,4,pszVerify,pszReserv,lReserv); } else // 用户改回了时间,验证锁定 { //根据时间锁定码,判断是否时间有作弊现象 md5.update(sSegments.at(4)); std::string sLockVery = md5.toString(); if (sLockVery.compare(pszReserv) == 0) { //时间锁定,时间有作弊现象 return FALSE; } } return TRUE; } else//不在授权的时间内 { std::vector sSegments2; //同时锁定时间记录点,创建锁定时间记录点md5,放在reserv中 //int nYear, int nMonth, int nDay, int nHour; CTime tNewPos(tCur.GetYear(),tCur.GetMonth(),tCur.GetDay(),tCur.GetHour(),0,0); CString sNewTime = tNewPos.Format(_T("%Y-%m-%d:%H")); char szBuffer[MAX_STRING]; memset(szBuffer,0,MAX_STRING); #if ADS>16 WideCharToMultiByte( CP_ACP, 0, sNewTime, -1,szBuffer, MAX_STRING, NULL, NULL ); #else _tcscpy(szBuffer,sNewTime); #endif for (UINT i = 0;i < sSegments.size();i++) { if (i == 4) { sSegments2.push_back(szBuffer); } else { sSegments2.push_back(sSegments.at(i)); } } /* 0 1 2 3 4 5 6 7 8 9 //授权信息 2008-03-02|2008-09-09|lfy|lh|2009-04-01:09|192.168.0.8|tpm|sa|21|md5 //校验码对 2008-03-02|2008-09-09|lfy|lh|***|192.168.0.8|tpm|sa|21| md5校验 //预留默认 创建锁定时间记录点md5,放在reserv中 //预留默认 8 */ //对 2008-03-02|2008-09-09|lfy|lh|2009-04-01:09|192.168.0.8|tpm|sa|21|md5进行锁定 std::string sSrc; sSrc.append(sSegments2.at(4)); md5.update(sSrc); sVerify2 = md5.toString(); if (sVerify2.compare(pszReserv) != 0) { //写入reserve 码 idLnsNew = WriteXRecord(sSegments2,pszVerify,sVerify2,lReserv); } return FALSE; } } return 0; } int CDbDwgLicense::FormatTime(std::string& sTime,int& nYear,int& nMont,int& nDay,int& nHour) { //2009-04-01:09 int nPos = sTime.find('-',0); if (nPos != -1) { std::string sYear,sMonth,sDay,sHour,sNext; //2009 sYear = sTime.substr(0,nPos); if (sTime.size() - nPos - 1 > 0) { //04-01:09 sNext = sTime.substr(nPos + 1,sTime.size() - nPos - 1); nPos = sNext.find('-',0); if (nPos != -1) { int nPos2 = sNext.find(':',0); sDay = sNext.substr(nPos + 1,nPos2 - nPos - 1); sMonth = sNext.substr(0,nPos); if (nPos2 != -1) { sHour = sNext.substr(nPos2 + 1,sNext.size() - nPos2 - 1); } else { sHour.append("0"); } } #if ADS<17 nYear = atoi(sYear.c_str()); nMont = atoi(sMonth.c_str()); nDay = atoi(sDay.c_str()); nHour = atoi(sHour.c_str()); #else TCHAR szTemp[32]; memset(szTemp,0,32); ::MultiByteToWideChar(CP_ACP, 0, sYear.c_str(), -1, szTemp, 32); nYear = _ttoi(szTemp); memset(szTemp,0,32); ::MultiByteToWideChar(CP_ACP, 0, sMonth.c_str(), -1, szTemp, 32); nMont = _ttoi(szTemp); memset(szTemp,0,32); ::MultiByteToWideChar(CP_ACP, 0, sDay.c_str(), -1, szTemp, 32); nDay = _ttoi(szTemp); memset(szTemp,0,32); ::MultiByteToWideChar(CP_ACP, 0, sHour.c_str(), -1, szTemp, 32); nHour = _ttoi(szTemp); #endif return 1; } } return 0; } AcDbObjectId CDbDwgLicense::WriteXRecord(std::vector& sSegments,char* pszVerify, std::string& sLockTime,long lReserv) { assertWriteEnabled(); struct resbuf* pRb = NULL,*pHead = NULL; std::string sText,sScript; CString sNewTime; char szBuffer[MAX_STRING]; memset(szBuffer,0,MAX_STRING); for (UINT i = 0;i < sSegments.size();i++) { sText = sSegments.at(i); sScript.append(sText); if (i < sSegments.size() - 1) sScript.append("|"); } /* 0 1 2 3 4 5 6 7 8 9 //授权信息 2008-03-02|2008-09-09|lfy|lh|2009-04-01:09|192.168.0.8|tpm|sa|21|md5 //校验码对 2008-03-02|2008-09-09|lfy|lh|***|192.168.0.8|tpm|sa|21| md5校验 //预留默认 时间锁定码 //预留默认 8 */ #if ADS>16 TCHAR szTemp[MAX_STRING]; //授权信息 2008-03-02|2008-09-09|lfy|lh|2009-04-01:09|192.168.0.8|tpm|sa|21|md5 struct resbuf* pTempNext = NULL; pTempNext = acutNewRb(AcDb::kDxfXdAsciiString); ::MultiByteToWideChar(CP_ACP, 0, sScript.c_str(), -1, szTemp, MAX_STRING); acutNewString(szTemp, pTempNext->resval.rstring); pRb = pTempNext; pHead = pRb; //校验码对 对 2008-03-02|2008-09-09|lfy|lh|***|192.168.0.8|tpm|sa|21| 的 md5 pTempNext = acutNewRb(AcDb::kDxfXdAsciiString); ::MultiByteToWideChar(CP_ACP, 0, pszVerify, -1, szTemp, MAX_STRING); acutNewString(szTemp, pTempNext->resval.rstring); pRb->rbnext = pTempNext; pRb = pRb->rbnext; //预留默认 **** pTempNext = acutNewRb(AcDb::kDxfXdAsciiString); ::MultiByteToWideChar(CP_ACP, 0, sLockTime.c_str(), -1, szTemp, MAX_STRING); acutNewString(szTemp, pTempNext->resval.rstring); pRb->rbnext = pTempNext; pRb = pRb->rbnext; //预留默认 8 pTempNext = acutNewRb(AcDb::kDxfXdInteger32); pTempNext->resval.rlong = lReserv; pRb->rbnext = pTempNext; pRb = pRb->rbnext; #else //授权信息 2008-03-02|2008-09-09|lfy|lh|2009-04-01:09|192.168.0.8|tpm|sa|21|md5 struct resbuf* pTempNext = NULL; pTempNext = acutNewRb(AcDb::kDxfXdAsciiString); acutNewString(sScript.c_str(), pTempNext->resval.rstring); pRb = pTempNext; pHead = pRb; //校验码对 对 2008-03-02|2008-09-09|lfy|lh|***|192.168.0.8|tpm|sa|21| 的 md5 pTempNext = acutNewRb(AcDb::kDxfXdAsciiString); acutNewString(pszVerify, pTempNext->resval.rstring); pRb->rbnext = pTempNext; pRb = pRb->rbnext; //预留默认 授权码,GUID,作为图纸打开的键值 pTempNext = acutNewRb(AcDb::kDxfXdAsciiString); acutNewString(sLockTime.c_str(), pTempNext->resval.rstring); pRb->rbnext = pTempNext; pRb = pRb->rbnext; //预留默认 8 pTempNext = acutNewRb(AcDb::kDxfXdInteger32); pTempNext->resval.rlong = lReserv; pRb->rbnext = pTempNext; #endif AcDbObjectId idLns; Acad::ErrorStatus es = Acad::eOk; if (pHead != NULL) { //es = setFromRbChain(*pHead); CreateNewLicenseRecord(pHead); if (!idLns.isNull()) //添加新的反应器到blockRec中 { AcDbBlockTable* pBTbl = NULL; database()->getBlockTable(pBTbl,AcDb::kForRead); if (pBTbl != NULL) { AcDbBlockTableRecord* pRec = NULL; pBTbl->getAt(ACDB_MODEL_SPACE,pRec,AcDb::kForWrite); if (pRec != NULL) { pRec->removePersistentReactor(objectId()); pRec->addPersistentReactor(idLns); pRec->close(); } pBTbl->close(); } } acutRelRb(pHead); } return idLns; } AcDbObjectId CDbDwgLicense::WriteXRecord(std::vector& sSegments,CTime& tNewPos,int nIndex, char* pszVerify,char* pszReserv,long lReserv) { assertWriteEnabled(); struct resbuf* pRb = NULL,*pHead = NULL; std::string sText,sScript; CString sNewTime; char szBuffer[MAX_STRING]; memset(szBuffer,0,MAX_STRING); for (UINT i = 0;i < sSegments.size();i++) { sText = sSegments.at(i); if (i == nIndex) { //2009-04-01:09 sNewTime = tNewPos.Format(_T("%Y-%m-%d:%H")); #if ADS>16 WideCharToMultiByte( CP_ACP, 0, sNewTime, -1,szBuffer, MAX_STRING, NULL, NULL ); sScript.append(szBuffer); if (i < sSegments.size() - 1) sScript.append("|"); #else sScript.append(sNewTime); if (i < sSegments.size() - 1) sScript.append("|"); #endif } else { sScript.append(sText); if (i < sSegments.size() - 1) sScript.append("|"); } } /* 0 1 2 3 4 5 6 7 8 9 //授权信息 2008-03-02|2008-09-09|lfy|lh|2009-04-01:09|192.168.0.8|tpm|sa|21|md5 //校验码对 2008-03-02|2008-09-09|lfy|lh|***|192.168.0.8|tpm|sa|21| md5校验 //预留默认 授权码,GUID,作为图纸打开的键值 //预留默认 8 */ #if ADS>16 TCHAR szTemp[MAX_STRING]; //授权信息 2008-03-02|2008-09-09|lfy|lh|2009-04-01:09|192.168.0.8|tpm|sa|21|md5 struct resbuf* pTempNext = NULL; pTempNext = acutNewRb(AcDb::kDxfXdAsciiString); ::MultiByteToWideChar(CP_ACP, 0, sScript.c_str(), -1, szTemp, MAX_STRING); acutNewString(szTemp, pTempNext->resval.rstring); pRb = pTempNext; pHead = pRb; //校验码对 对 2008-03-02|2008-09-09|lfy|lh|***|192.168.0.8|tpm|sa|21| 的 md5 pTempNext = acutNewRb(AcDb::kDxfXdAsciiString); ::MultiByteToWideChar(CP_ACP, 0, pszVerify, -1, szTemp, MAX_STRING); acutNewString(szTemp, pTempNext->resval.rstring); pRb->rbnext = pTempNext; pRb = pRb->rbnext; //预留默认 **** pTempNext = acutNewRb(AcDb::kDxfXdAsciiString); ::MultiByteToWideChar(CP_ACP, 0, pszReserv, -1, szTemp, MAX_STRING); acutNewString(szTemp, pTempNext->resval.rstring); pRb->rbnext = pTempNext; pRb = pRb->rbnext; //预留默认 8 pTempNext = acutNewRb(AcDb::kDxfXdInteger32); pTempNext->resval.rlong = lReserv; pRb->rbnext = pTempNext; pRb = pRb->rbnext; #else //授权信息 2008-03-02|2008-09-09|lfy|lh|2009-04-01:09|192.168.0.8|tpm|sa|21|md5 struct resbuf* pTempNext = NULL; pTempNext = acutNewRb(AcDb::kDxfXdAsciiString); acutNewString(sScript.c_str(), pTempNext->resval.rstring); pRb = pTempNext; pHead = pRb; //校验码对 对 2008-03-02|2008-09-09|lfy|lh|***|192.168.0.8|tpm|sa|21| 的 md5 pTempNext = acutNewRb(AcDb::kDxfXdAsciiString); acutNewString(pszVerify, pTempNext->resval.rstring); pRb->rbnext = pTempNext; pRb = pRb->rbnext; //预留默认 授权码,GUID,作为图纸打开的键值 pTempNext = acutNewRb(AcDb::kDxfXdAsciiString); acutNewString(pszReserv, pTempNext->resval.rstring); pRb->rbnext = pTempNext; pRb = pRb->rbnext; //预留默认 8 pTempNext = acutNewRb(AcDb::kDxfXdInteger32); pTempNext->resval.rlong = lReserv; pRb->rbnext = pTempNext; #endif AcDbObjectId idLns; Acad::ErrorStatus es = Acad::eOk; if (pHead != NULL) { //es = setFromRbChain(*pHead); idLns = CreateNewLicenseRecord(pHead); if (!idLns.isNull()) //添加新的反应器到blockRec中 { AcDbBlockTable* pBTbl = NULL; database()->getBlockTable(pBTbl,AcDb::kForRead); if (pBTbl != NULL) { AcDbBlockTableRecord* pRec = NULL; pBTbl->getAt(ACDB_MODEL_SPACE,pRec,AcDb::kForWrite); if (pRec != NULL) { pRec->removePersistentReactor(objectId()); pRec->addPersistentReactor(idLns); pRec->close(); } pBTbl->close(); } } acutRelRb(pHead); } return idLns; } AcDbObjectId CDbDwgLicense::CreateNewLicenseRecord(struct resbuf* pHead,AcDbDatabase* pDb) { AcDbObjectId idLnc = AcDbObjectId::kNull; Acad::ErrorStatus es; if (pDb == NULL) pDb = database(); AcDbLinetypeTable* pTbl = NULL; pDb->getLinetypeTable(pTbl,AcDb::kForRead); if (pTbl != NULL) { AcDbLinetypeTableRecord* pRec = NULL; pTbl->getAt(_T("Continuous"),pRec,AcDb::kForWrite); if (pRec != NULL) { pRec->createExtensionDictionary(); AcDbObjectId idDic = pRec->extensionDictionary(); AcDbDictionary* pDic = NULL; if (Acad::eOk == acdbOpenAcDbObject((AcDbObject*&)pDic,idDic,AcDb::kForWrite)) { CString sKey; for (int nIndex = 0;nIndex < 2;nIndex++) { sKey.Format(_T("TPMLICN%d"),nIndex); if (!pDic->has(sKey)) { g_nLock = 1; CDbDwgLicense* pLicense = new CDbDwgLicense; pLicense->setFromRbChain(*pHead); pDic->setAt(sKey,pLicense,idLnc); pLicense->close(); } else { AcDbObjectId idObj; pDic->getAt(sKey,idObj); pDic->remove(sKey); AcDbObject* pObj = NULL; if (Acad::eOk == acdbOpenAcDbObject(pObj,idObj,AcDb::kForWrite)) { pObj->erase(); pObj->close(); } else { if (idObj == objectId()) { close(); if (Acad::eOk == acdbOpenAcDbObject(pObj,idObj,AcDb::kForWrite)) { es = pObj->erase(); pObj->close(); } } } } } pDic->close(); } pRec->close(); } pTbl->close(); } g_nLock = 0; return idLnc; } AcDbObjectId CDbDwgLicense::CopyNewLicenseRecord(struct resbuf* pHead,AcDbObject* pEnt) { AcDbObjectId idLicense = AcDbObjectId::kNull; if (pEnt != NULL) { AcDbObjectId idDic,idDic2; AcDbDatabase* pDb = pEnt->database(); AcDbLinetypeTable* pTbl = NULL; pDb->getLinetypeTable(pTbl,AcDb::kForRead); if (pTbl != NULL) { AcDbLinetypeTableRecord* pRec = NULL; pTbl->getAt(_T("Continuous"),pRec,AcDb::kForWrite); if (pRec != NULL) { pRec->createExtensionDictionary(); idDic = pRec->extensionDictionary(); AcDbDictionary* pDic = NULL; if (Acad::eOk == acdbOpenAcDbObject((AcDbObject*&)pDic,idDic,AcDb::kForWrite)) { BOOL bHas = FALSE; CString sKey; for (int nIndex = 0;nIndex < 2;nIndex++) { sKey.Format(_T("TPMLICN%d"),nIndex); if (pDic->has(sKey)) { bHas = TRUE; pDic->getAt(sKey,idLicense); } } if (!bHas) { sKey.Format(_T("TPMLICN%d"),0); g_nLock = 1; CDbDwgLicense* pLicense = new CDbDwgLicense; pLicense->setFromRbChain(*pHead); pDic->setAt(sKey,pLicense,idLicense); pLicense->close(); g_nLock = 0; } pDic->close(); } pRec->close(); } pTbl->close(); } } return idLicense; } int CDbDwgLicense::ParserTPMmd5(char* pszLicense,char* pszPassword) { int nFrom = -1,nTo = -1,nIndex = 0,i = 0; char szChar = '\0'; for (i = 0;i < MAX_STRING;i++) { szChar = pszLicense[i]; if (szChar == '|') { nFrom = i; } if (szChar == '\0') { nTo = i; break; } } if (nFrom != -1) { for(i = nFrom + 1;i < nTo;i++) { pszPassword[i - nFrom - 1] = toupper(pszLicense[i]); } } return (nFrom != -1 && nTo != -1); } int CDbDwgLicense::ParserContext(char* pszLicense,std::vector& sSegments) { //授权信息 2008-03-02|2008-09-09|lfy|lh|2009-04-01:09|192.168.0.8|tpm|sa|211 std::string stTemp,sReset; char szChar = '\0'; char szText[MAX_STRING]; memset(szText,0,MAX_STRING); int nIndex = 0; for (int i = 0;i < MAX_STRING;i++) { szChar = pszLicense[i]; if (szChar == '|') { szText[nIndex] = '\0'; nIndex = 0; stTemp.append(szText); sSegments.push_back(stTemp); stTemp = sReset; } else { szText[nIndex] = szChar; nIndex += 1; if (szChar == '\0') { stTemp.append(szText); sSegments.push_back(stTemp); break; } } } return sSegments.size(); } int CDbDwgLicense::GetLicenseInfo(char* pszLicense,char* pszVerify,char* pszReserv,long& lReserv) { int nSuccess = 0; struct resbuf* pRbList = NULL; rbChain(&pRbList); if (pRbList != NULL) { nSuccess = FormatLicenseInfo(pRbList,pszLicense,pszVerify,pszReserv,lReserv); acutRelRb(pRbList); } return nSuccess; } /*---------------------------------------------------------------------------------------------------------------------- 返回值 0 : 错误的授权信息 1~3 : 部分完整的授权信息 4 : 完全合法的授权信息 pRbList : 授权信息链表 pszLicense : 授权信息 pszVerify : 校验信息 pszReserv : 锁定码 lReserv : 预留 -----------------------------------------------------------------------------------------------------------------------*/ int CDbDwgLicense::FormatLicenseInfo(struct resbuf* pRbList,char* pszLicense,char* pszVerify,char* pszReserv,long& lReserv) { //1. license int nHasLicesse = 0; char szBuffer[MAX_STRING]; memset(szBuffer,0,MAX_STRING); if (pRbList != NULL && pRbList->restype == AcDb::kDxfXdAsciiString) { #if ADS < 17 _tcscpy(pszLicense,pRbList->resval.rstring); #else WideCharToMultiByte( CP_ACP, 0, pRbList->resval.rstring, -1,pszLicense, MAX_STRING, NULL, NULL ); #endif nHasLicesse = 1; //2. verify pRbList = pRbList->rbnext; if (pRbList != NULL && pRbList->restype == AcDb::kDxfXdAsciiString) { #if ADS < 17 _tcscpy(pszVerify,pRbList->resval.rstring); #else WideCharToMultiByte( CP_ACP, 0, pRbList->resval.rstring, -1,pszVerify, MAX_STRING, NULL, NULL ); #endif nHasLicesse = 2; //3. reserv pRbList = pRbList->rbnext; if (pRbList != NULL && pRbList->restype == AcDb::kDxfXdAsciiString) { #if ADS < 17 _tcscpy(pszReserv,pRbList->resval.rstring); #else WideCharToMultiByte( CP_ACP, 0, pRbList->resval.rstring, -1,pszReserv, MAX_STRING, NULL, NULL ); #endif nHasLicesse = 3; //4. lreserv pRbList = pRbList->rbnext; if (pRbList != NULL && pRbList->restype == AcDb::kDxfXdInteger32) { lReserv = pRbList->resval.rlong; nHasLicesse = 4; //完全信息读取 return nHasLicesse; } } } } return nHasLicesse; } //{{AFX_ARX_MACRO ACRX_DXF_DEFINE_MEMBERS(CDbLicenseCarrier, AcDbEntity, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, AcDbProxyEntity::kAllAllowedBits, ATSLicenseCarrier, "ATSLicenseCarrier图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com"); //}}AFX_ARX_MACRO CDbLicenseCarrier::CDbLicenseCarrier() { } CDbLicenseCarrier::~CDbLicenseCarrier() { } Acad::ErrorStatus CDbLicenseCarrier::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es; // Call dwgOutFields from TDbInterfacesObj if ((es = AcDbEntity::dwgOutFields(pFiler)) != Acad::eOk) { return es; } // Write version number. pFiler->writeItem((Adesk::UInt16)1); return pFiler->filerStatus(); } Acad::ErrorStatus CDbLicenseCarrier::dwgInFields(AcDbDwgFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es; // Call dwgInFields from TDbInterfacesObj if ((es = AcDbEntity::dwgInFields(pFiler)) != Acad::eOk) { return es; } // Read version number. Adesk::UInt16 version; pFiler->readItem(&version); if (!g_nLock) { VerifyLicense(); } return pFiler->filerStatus(); } Acad::ErrorStatus CDbLicenseCarrier::subErase(Adesk::Boolean erasing) { assertWriteEnabled(); if (erasing && !g_nLock) //[CAD命令默认: 没有锁定,并且是正删除, 不可以删除] { //禁止删除 return Acad::eNotApplicable; } return Acad::eOk; } void CDbLicenseCarrier::VerifyLicense() { //校验Continuous线型是否有授权对象 AcDbDatabase* pDb = acdbCurDwg(); struct resbuf* pHead = NULL; pHead = xData(_T("TPMLCNS")); if (pHead != NULL) { struct resbuf* pRb = pHead->rbnext; CreateNewLicenseRecord(pRb,pDb); acutRelRb(pHead); } } AcDbObjectId CDbLicenseCarrier::CreateNewLicenseRecord(struct resbuf* pHead,AcDbDatabase* pDb) { //1. 创建新的授权信息对象到continuous 线型上 AcDbObjectId idLicense = AcDbObjectId::kNull; if (pDb == NULL) pDb = acdbCurDwg(); AcDbLinetypeTable* pTbl = NULL; pDb->getLinetypeTable(pTbl,AcDb::kForRead); if (pTbl != NULL) { AcDbLinetypeTableRecord* pRec = NULL; pTbl->getAt(_T("Continuous"),pRec,AcDb::kForWrite); if (pRec != NULL) { pRec->createExtensionDictionary(); AcDbObjectId idDic = pRec->extensionDictionary(); AcDbDictionary* pDic = NULL; if (Acad::eOk == acdbOpenAcDbObject((AcDbObject*&)pDic,idDic,AcDb::kForWrite)) { BOOL bHas = FALSE; CString sKey; for (int nIndex = 0;nIndex < 2;nIndex++) { sKey.Format(_T("TPMLICN%d"),nIndex); if (pDic->has(sKey)) { bHas = TRUE; break; } } //没有授权对象时,创建新的授权对象 if (!bHas) { sKey.Format(_T("TPMLICN%d"),0); g_nLock = 1; CDbDwgLicense* pLicense = new CDbDwgLicense; pLicense->setFromRbChain(*pHead); pDic->setAt(sKey,pLicense,idLicense); pLicense->close(); g_nLock = 0; } pDic->close(); } pRec->close(); } pTbl->close(); } g_nLock = 0; return idLicense; } void InitDwgLicense(BOOL bTrue) { if(bTrue) { CDbDwgLicense::rxInit(); CDbLicenseCarrier::rxInit(); acrxBuildClassHierarchy(); } else { deleteAcRxClass(CDbDwgLicense::desc()); deleteAcRxClass(CDbLicenseCarrier::desc()); } }