Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1481 lines
42 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996-1998
  5. //
  6. // File: kp.cpp
  7. //
  8. // Contents:
  9. // Contains wrapper call to deal with concepture
  10. // license key pack table, this includes LicPack, LicPackStatus,
  11. // and LicPackDesc table.
  12. //
  13. // History:
  14. // 04/16/98 HueiWang Created.
  15. //---------------------------------------------------------------------------
  16. #include "pch.cpp"
  17. #include "kp.h"
  18. #include "globals.h"
  19. #include "server.h"
  20. #include "lkplite.h"
  21. #include "keypack.h"
  22. #include "lkpdesc.h"
  23. #include "misc.h"
  24. #include "permlic.h"
  25. #define STRSAFE_NO_DEPRECATE
  26. #include <strsafe.h>
  27. //++-------------------------------------------------------------------------------
  28. BOOL
  29. ValidLicenseKeyPackParameter(
  30. IN LPLSKeyPack lpKeyPack,
  31. IN BOOL bAdd
  32. )
  33. /*++
  34. Abtract:
  35. Validate a LSKeyPack value.
  36. Parameter:
  37. lpKeyPack - keypack value to be validated,
  38. bAdd - TRUE if this value is to be inserted into table, FALSE otherwise, note
  39. if value is to be inserted into table, it require more parameters.
  40. Return:
  41. TRUE if valid LSKeyPack value, FALSE otherwise.
  42. ++*/
  43. {
  44. BOOL bValid=FALSE;
  45. do {
  46. // verify input parameter
  47. if((lpKeyPack->ucKeyPackType & ~LSKEYPACK_RESERVED_TYPE) < LSKEYPACKTYPE_FIRST ||
  48. (lpKeyPack->ucKeyPackType & ~LSKEYPACK_RESERVED_TYPE) > LSKEYPACKTYPE_LAST)
  49. {
  50. DBGPrintf(
  51. DBG_ERROR,
  52. DBG_FACILITY_RPC,
  53. DBG_FACILITY_KEYPACK,
  54. _TEXT("ValidLicenseKeyPackParameter : invalid key pack type - %d\n"),
  55. lpKeyPack->ucKeyPackType
  56. );
  57. break;
  58. }
  59. UCHAR ucKeyPackStatus = lpKeyPack->ucKeyPackStatus & ~LSKEYPACKSTATUS_RESERVED;
  60. if((ucKeyPackStatus < LSKEYPACKSTATUS_FIRST ||
  61. ucKeyPackStatus > LSKEYPACKSTATUS_LAST) &&
  62. ucKeyPackStatus != LSKEYPACKSTATUS_DELETE)
  63. {
  64. DBGPrintf(
  65. DBG_ERROR,
  66. DBG_FACILITY_RPC,
  67. DBG_FACILITY_KEYPACK,
  68. _TEXT("ValidLicenseKeyPackParameter : invalid key pack status - %d\n"),
  69. lpKeyPack->ucKeyPackStatus
  70. );
  71. break;
  72. }
  73. if(lpKeyPack->ucLicenseType < LSKEYPACKLICENSETYPE_FIRST ||
  74. lpKeyPack->ucLicenseType > LSKEYPACKLICENSETYPE_LAST)
  75. {
  76. DBGPrintf(
  77. DBG_ERROR,
  78. DBG_FACILITY_RPC,
  79. DBG_FACILITY_KEYPACK,
  80. _TEXT("ValidLicenseKeyPackParameter : invalid license type - %d\n"),
  81. lpKeyPack->ucLicenseType
  82. );
  83. break;
  84. }
  85. if(!bAdd)
  86. {
  87. bValid = TRUE;
  88. break;
  89. }
  90. if(lpKeyPack->ucChannelOfPurchase < LSKEYPACKCHANNELOFPURCHASE_FIRST ||
  91. lpKeyPack->ucChannelOfPurchase > LSKEYPACKCHANNELOFPURCHASE_LAST)
  92. {
  93. DBGPrintf(
  94. DBG_ERROR,
  95. DBG_FACILITY_RPC,
  96. DBG_FACILITY_KEYPACK,
  97. _TEXT("ValidLicenseKeyPackParameter : invalid channel of purchase - %d\n"),
  98. lpKeyPack->ucChannelOfPurchase
  99. );
  100. break;
  101. }
  102. if(!_tcslen(lpKeyPack->szCompanyName))
  103. {
  104. DBGPrintf(
  105. DBG_ERROR,
  106. DBG_FACILITY_RPC,
  107. DBG_FACILITY_KEYPACK,
  108. _TEXT("ValidLicenseKeyPackParameter : invalid company name\n")
  109. );
  110. break;
  111. }
  112. if(!_tcslen(lpKeyPack->szKeyPackId))
  113. {
  114. DBGPrintf(
  115. DBG_ERROR,
  116. DBG_FACILITY_RPC,
  117. DBG_FACILITY_KEYPACK,
  118. _TEXT("ValidLicenseKeyPackParameter : invalid key pack id\n")
  119. );
  120. break;
  121. }
  122. if(!_tcslen(lpKeyPack->szProductName))
  123. {
  124. DBGPrintf(
  125. DBG_ERROR,
  126. DBG_FACILITY_RPC,
  127. DBG_FACILITY_KEYPACK,
  128. _TEXT("ValidLicenseKeyPackParameter : invalid product name\n")
  129. );
  130. break;
  131. }
  132. if(!_tcslen(lpKeyPack->szProductId))
  133. {
  134. DBGPrintf(
  135. DBG_ERROR,
  136. DBG_FACILITY_RPC,
  137. DBG_FACILITY_KEYPACK,
  138. _TEXT("ValidLicenseKeyPackParameter : invalid product id\n")
  139. );
  140. break;
  141. }
  142. if(!_tcslen(lpKeyPack->szProductDesc))
  143. {
  144. // set product desc = product name
  145. _tcscpy(lpKeyPack->szProductDesc, lpKeyPack->szProductName);
  146. }
  147. if(!_tcslen(lpKeyPack->szBeginSerialNumber))
  148. {
  149. DBGPrintf(
  150. DBG_ERROR,
  151. DBG_FACILITY_RPC,
  152. DBG_FACILITY_KEYPACK,
  153. _TEXT("ValidLicenseKeyPackParameter : invalid serial number\n")
  154. );
  155. break;
  156. }
  157. bValid=TRUE;
  158. } while(FALSE);
  159. return bValid;
  160. }
  161. //++----------------------------------------------------------------------
  162. DWORD
  163. TLSDBLicenseKeyPackAdd(
  164. IN PTLSDbWorkSpace pDbWkSpace,
  165. IN LPLSKeyPack lpLsKeyPack
  166. )
  167. /*++
  168. Abstract:
  169. Add an entry into concepture keypack table, this includes LicPack,
  170. LicPackStatus, and LicPackDesc table.
  171. Parameter:
  172. pDbWkSpace : workspace handle.
  173. lpLsKeyPack : license key pack to be added into table.
  174. Returns:
  175. ++*/
  176. {
  177. DWORD dwStatus;
  178. PTLSLICENSEPACK pLicPack = NULL;
  179. LICPACKDESC LicPackDesc;
  180. if(!ValidLicenseKeyPackParameter(lpLsKeyPack, TRUE))
  181. return TLS_E_INVALID_DATA;
  182. TLSDBLockKeyPackTable();
  183. TLSDBLockKeyPackDescTable();
  184. do {
  185. pLicPack = new TLSLICENSEPACK;
  186. if(pLicPack == NULL)
  187. {
  188. SetLastError(dwStatus = TLS_E_ALLOCATE_MEMORY);
  189. break;
  190. }
  191. if(ConvertLsKeyPackToKeyPack(
  192. lpLsKeyPack,
  193. pLicPack,
  194. &LicPackDesc
  195. ) == FALSE)
  196. {
  197. dwStatus = GetLastError();
  198. break;
  199. }
  200. //
  201. // Add license server info into TLSLICENSEPACK
  202. //
  203. //LicPack.pbDomainSid = g_pbDomainSid;
  204. //LicPack.cbDomainSid = g_cbDomainSid;
  205. _tcscpy(pLicPack->szInstallId, (LPTSTR)g_pszServerPid);
  206. _tcscpy(pLicPack->szTlsServerName, g_szComputerName);
  207. //
  208. // No domain name at this time
  209. //
  210. memset(pLicPack->szDomainName, 0, sizeof(pLicPack->szDomainName));
  211. if(lpLsKeyPack->ucKeyPackStatus != LSKEYPACKSTATUS_ADD_DESC)
  212. {
  213. dwStatus = TLSDBKeyPackAdd(pDbWkSpace, pLicPack);
  214. if(dwStatus != ERROR_SUCCESS)
  215. {
  216. // this is global memory, destructor will try to free it.
  217. pLicPack->pbDomainSid = NULL;
  218. pLicPack->cbDomainSid = 0;
  219. break;
  220. }
  221. }
  222. pLicPack->pbDomainSid = NULL;
  223. pLicPack->cbDomainSid = 0;
  224. //
  225. // Make sure keypack got inserted
  226. //
  227. dwStatus = TLSDBKeyPackEnumBegin(
  228. pDbWkSpace,
  229. TRUE,
  230. LSKEYPACK_EXSEARCH_DWINTERNAL,
  231. pLicPack
  232. );
  233. if(dwStatus != ERROR_SUCCESS)
  234. break;
  235. dwStatus = TLSDBKeyPackEnumNext(
  236. pDbWkSpace,
  237. pLicPack
  238. );
  239. TLSDBKeyPackEnumEnd(pDbWkSpace);
  240. if(dwStatus != ERROR_SUCCESS)
  241. break;
  242. LicPackDesc.dwKeyPackId = pLicPack->dwKeyPackId;
  243. //
  244. // Add keypack description into keypack desc
  245. //
  246. dwStatus = TLSDBKeyPackDescAddEntry(
  247. pDbWkSpace,
  248. &LicPackDesc
  249. );
  250. ConvertKeyPackToLsKeyPack(
  251. pLicPack,
  252. &LicPackDesc,
  253. lpLsKeyPack
  254. );
  255. if(pLicPack != NULL)
  256. {
  257. delete pLicPack;
  258. }
  259. } while(FALSE);
  260. TLSDBUnlockKeyPackDescTable();
  261. TLSDBUnlockKeyPackTable();
  262. return dwStatus;
  263. }
  264. //++-----------------------------------------------------------------------
  265. DWORD
  266. TLSDBLicenseKeyPackSetStatus(
  267. IN PTLSDbWorkSpace pDbWkSpace,
  268. IN DWORD dwSetStatus,
  269. IN LPLSKeyPack lpLsKeyPack
  270. )
  271. /*++
  272. Abstract:
  273. Set the status of Licensed KeyPack.
  274. Parameter:
  275. pDbWkSpace - workspace handle.
  276. dwSetStatus - type of status to be set.
  277. lpLsKeyPack - record/value to be set.
  278. Returns:
  279. ++*/
  280. {
  281. TLSLICENSEPACK LicPack;
  282. //
  283. // Status of keypack is in KeyPack table
  284. //
  285. if(ConvertLsKeyPackToKeyPack(
  286. lpLsKeyPack,
  287. &LicPack,
  288. NULL
  289. ) == FALSE)
  290. {
  291. return GetLastError();
  292. }
  293. return TLSDBKeyPackSetValues(pDbWkSpace, FALSE, dwSetStatus, &LicPack);
  294. }
  295. //++---------------------------------------------------------------------
  296. DWORD
  297. TLSDBLicenseKeyPackUpdateLicenses(
  298. PTLSDbWorkSpace pDbWkSpace,
  299. BOOL bAdd,
  300. IN LPLSKeyPack lpLsKeyPack
  301. )
  302. /*++
  303. Abstract:
  304. Add/Remove license from a keypack.
  305. Parameter:
  306. pDbWkSpace - workspace handle.
  307. bAdd - TRUE if add entry into table, FALSE otherwise.
  308. lpLsKeyPack -
  309. Returns:
  310. ++*/
  311. {
  312. DWORD dwStatus;
  313. TLSLICENSEPACK LicPack;
  314. //
  315. // Redirect call to KeyPack Table, not thing in KeyPackDesc can be updated.
  316. //
  317. if(ConvertLsKeyPackToKeyPack(
  318. lpLsKeyPack,
  319. &LicPack,
  320. NULL
  321. ) == FALSE)
  322. {
  323. dwStatus = GetLastError();
  324. goto cleanup;
  325. }
  326. dwStatus=TLSDBKeyPackUpdateNumOfAvailableLicense(
  327. pDbWkSpace,
  328. bAdd,
  329. &LicPack
  330. );
  331. //
  332. // return new value back to caller
  333. //
  334. ConvertKeyPackToLsKeyPack(
  335. &LicPack,
  336. NULL,
  337. lpLsKeyPack
  338. );
  339. cleanup:
  340. return dwStatus;
  341. }
  342. //++---------------------------------------------------------------------
  343. LPENUMHANDLE
  344. TLSDBLicenseKeyPackEnumBegin(
  345. BOOL bMatchAll,
  346. DWORD dwSearchParm,
  347. LPLSKeyPack lpLsKeyPack
  348. )
  349. /*++
  350. Abstract:
  351. Begin enumeration of concepture License Key Pack table.
  352. Parameter:
  353. bMatchAll - TRUE if match all search value, FALSE otherwise.
  354. dwSearchParm - Field to be included in search.
  355. lpLsKeyPack - KeyPack value to search.
  356. Returns:
  357. ++*/
  358. {
  359. DWORD dwStatus;
  360. LPENUMHANDLE hEnum=NULL;
  361. TLSLICENSEPACK licpack;
  362. licpack.pbDomainSid = NULL;
  363. hEnum = new ENUMHANDLE;
  364. if(hEnum == NULL)
  365. return NULL;
  366. hEnum->pbWorkSpace=AllocateWorkSpace(g_EnumDbTimeout);
  367. if(hEnum->pbWorkSpace == NULL)
  368. {
  369. SetLastError(TLS_E_ALLOCATE_HANDLE);
  370. TLSDBLicenseKeyPackEnumEnd(hEnum);
  371. return NULL;
  372. }
  373. memset(&hEnum->CurrentKeyPack, 0, sizeof(hEnum->CurrentKeyPack));
  374. memset(&hEnum->KPDescSearchValue, 0, sizeof(hEnum->KPDescSearchValue));
  375. hEnum->dwKPDescSearchParm = 0;
  376. if(ConvertLsKeyPackToKeyPack(
  377. lpLsKeyPack,
  378. &licpack,
  379. &hEnum->KPDescSearchValue
  380. ) == FALSE)
  381. {
  382. TLSDBLicenseKeyPackEnumEnd(hEnum);
  383. return NULL;
  384. }
  385. //
  386. // establish KeyPack enumeration
  387. dwStatus = TLSDBKeyPackEnumBegin(
  388. hEnum->pbWorkSpace,
  389. bMatchAll,
  390. dwSearchParm,
  391. &licpack
  392. );
  393. if(dwStatus != ERROR_SUCCESS)
  394. {
  395. SetLastError(dwStatus);
  396. TLSDBLicenseKeyPackEnumEnd(hEnum);
  397. return NULL;
  398. }
  399. //
  400. // Store keypack desc search value
  401. //
  402. if(dwSearchParm & LSKEYPACK_SEARCH_LANGID)
  403. hEnum->dwKPDescSearchParm |= LICPACKDESCRECORD_TABLE_SEARCH_LANGID;
  404. if(dwSearchParm & LSKEYPACK_SEARCH_COMPANYNAME)
  405. hEnum->dwKPDescSearchParm |= LICPACKDESCRECORD_TABLE_SEARCH_COMPANYNAME;
  406. if(dwSearchParm & LSKEYPACK_SEARCH_PRODUCTNAME)
  407. hEnum->dwKPDescSearchParm |= LICPACKDESCRECORD_TABLE_SEARCH_PRODUCTNAME;
  408. if(dwSearchParm & LSKEYPACK_SEARCH_PRODUCTDESC)
  409. hEnum->dwKPDescSearchParm |= LICPACKDESCRECORD_TABLE_SEARCH_PRODUCTDESC;
  410. hEnum->bKPDescMatchAll=bMatchAll;
  411. hEnum->chFetchState=ENUMHANDLE::FETCH_NEXT_KEYPACK;
  412. return hEnum;
  413. }
  414. //++----------------------------------------------------------------------
  415. DWORD
  416. TLSDBLicenseKeyPackEnumNext(
  417. LPENUMHANDLE lpEnumHandle,
  418. LPLSKeyPack lpLsKeyPack,
  419. BOOL bShowAll
  420. )
  421. /*++
  422. Abstract:
  423. Fetch next combined LicPack, LicPackStatus, and LicPackDesc record that
  424. match search condiftion.
  425. Parameter:
  426. lpEnumHandle - enumeration handle return by TLSDBLicenseKeyPackEnumBegin().
  427. lpLsKeyPack - return value found.
  428. bShowAll - return all keypack
  429. Returns:
  430. Note:
  431. Caller need to discard return value and call TLSDBLicenseKeyPackEnumNext()
  432. again when this function return TLS_I_MORE_DATA, this is to prevent
  433. stack overflow in recursive call.
  434. ++*/
  435. {
  436. //
  437. // No recursive call to prevent stack overflow
  438. //
  439. DWORD dwStatus;
  440. switch(lpEnumHandle->chFetchState)
  441. {
  442. case ENUMHANDLE::FETCH_NEXT_KEYPACK:
  443. //
  444. // Retrieve next row in keypack
  445. dwStatus=TLSDBKeyPackEnumNext(
  446. lpEnumHandle->pbWorkSpace,
  447. &lpEnumHandle->CurrentKeyPack
  448. );
  449. if(dwStatus != ERROR_SUCCESS)
  450. break;
  451. if(bShowAll == FALSE)
  452. {
  453. //
  454. // Never return keypack that is solely for issuing certificate to
  455. // Hydra Server
  456. if(_tcsicmp(lpEnumHandle->CurrentKeyPack.szKeyPackId,
  457. HYDRAPRODUCT_HS_CERTIFICATE_KEYPACKID) == 0 &&
  458. _tcsicmp(lpEnumHandle->CurrentKeyPack.szProductId,
  459. HYDRAPRODUCT_HS_CERTIFICATE_SKU) == 0)
  460. {
  461. //
  462. // Prevent infinite recursive call, let calling routine handle this
  463. return TLS_I_MORE_DATA;
  464. }
  465. //
  466. // Do not show remote key pack
  467. //
  468. if( lpEnumHandle->CurrentKeyPack.ucAgreementType & LSKEYPACK_REMOTE_TYPE)
  469. {
  470. return TLS_I_MORE_DATA;
  471. }
  472. if( lpEnumHandle->CurrentKeyPack.ucKeyPackStatus & LSKEYPACKSTATUS_REMOTE)
  473. {
  474. return TLS_I_MORE_DATA;
  475. }
  476. lpEnumHandle->CurrentKeyPack.ucAgreementType &= ~LSKEYPACK_RESERVED_TYPE;
  477. lpEnumHandle->CurrentKeyPack.ucKeyPackStatus &= ~LSKEYPACKSTATUS_RESERVED;
  478. }
  479. //
  480. // Fetch KeyPackDesc table
  481. //
  482. lpEnumHandle->chFetchState=ENUMHANDLE::FETCH_NEW_KEYPACKDESC;
  483. //
  484. // FALL THRU.
  485. //
  486. case ENUMHANDLE::FETCH_NEW_KEYPACKDESC:
  487. //
  488. // retrieve new keypackdesc that match up with keypack
  489. lpEnumHandle->KPDescSearchValue.dwKeyPackId = lpEnumHandle->CurrentKeyPack.dwKeyPackId;
  490. lpEnumHandle->dwKPDescSearchParm |= LICPACKDESCRECORD_TABLE_SEARCH_KEYPACKID;
  491. // lpEnumHandle->pbWorkSpace->Cleanup();
  492. //
  493. // First issue a query to see if product has matching language ID
  494. LICPACKDESC kpDesc;
  495. memset(&kpDesc, 0, sizeof(LICPACKDESC));
  496. kpDesc = lpEnumHandle->KPDescSearchValue;
  497. dwStatus = TLSDBKeyPackDescFind(
  498. lpEnumHandle->pbWorkSpace,
  499. TRUE,
  500. lpEnumHandle->dwKPDescSearchParm,
  501. &kpDesc,
  502. NULL
  503. );
  504. if(dwStatus == TLS_E_RECORD_NOTFOUND)
  505. {
  506. //
  507. // Show description in English
  508. kpDesc.dwLanguageId = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
  509. dwStatus = TLSDBKeyPackDescFind(
  510. lpEnumHandle->pbWorkSpace,
  511. TRUE,
  512. lpEnumHandle->dwKPDescSearchParm,
  513. &kpDesc,
  514. NULL
  515. );
  516. if(dwStatus == TLS_E_RECORD_NOTFOUND)
  517. {
  518. //
  519. // No product description for this lanuage ID and english
  520. //
  521. _tcscpy(kpDesc.szCompanyName, lpEnumHandle->CurrentKeyPack.szCompanyName);
  522. _tcscpy(kpDesc.szProductName, lpEnumHandle->CurrentKeyPack.szProductId);
  523. _tcscpy(kpDesc.szProductDesc, lpEnumHandle->CurrentKeyPack.szProductId);
  524. ConvertKeyPackToLsKeyPack(
  525. &lpEnumHandle->CurrentKeyPack,
  526. &kpDesc,
  527. lpLsKeyPack
  528. );
  529. dwStatus = ERROR_SUCCESS;
  530. lpEnumHandle->chFetchState=ENUMHANDLE::FETCH_NEXT_KEYPACK;
  531. break;
  532. }
  533. }
  534. dwStatus = TLSDBKeyPackDescEnumBegin(
  535. lpEnumHandle->pbWorkSpace,
  536. lpEnumHandle->bKPDescMatchAll,
  537. lpEnumHandle->dwKPDescSearchParm,
  538. &kpDesc
  539. );
  540. if(dwStatus != ERROR_SUCCESS)
  541. break;
  542. lpEnumHandle->chFetchState=ENUMHANDLE::FETCH_NEXT_KEYPACKDESC;
  543. //
  544. // FALL THRU
  545. //
  546. case ENUMHANDLE::FETCH_NEXT_KEYPACKDESC:
  547. {
  548. LICPACKDESC licpackdesc;
  549. dwStatus = TLSDBKeyPackDescEnumNext(
  550. lpEnumHandle->pbWorkSpace,
  551. &licpackdesc
  552. );
  553. if(dwStatus == ERROR_SUCCESS)
  554. {
  555. ConvertKeyPackToLsKeyPack(
  556. &lpEnumHandle->CurrentKeyPack,
  557. &licpackdesc,
  558. lpLsKeyPack
  559. );
  560. }
  561. else if(dwStatus == TLS_I_NO_MORE_DATA)
  562. {
  563. lpEnumHandle->chFetchState=ENUMHANDLE::FETCH_NEXT_KEYPACK;
  564. //
  565. // Set the status to MORE DATA
  566. //
  567. dwStatus = TLS_I_MORE_DATA;
  568. // terminate enumeration for keypack description table
  569. TLSDBKeyPackDescEnumEnd(lpEnumHandle->pbWorkSpace);
  570. }
  571. }
  572. break;
  573. }
  574. return dwStatus;
  575. }
  576. //++------------------------------------------------------------------
  577. DWORD
  578. TLSDBLicenseKeyPackEnumEnd(
  579. LPENUMHANDLE lpEnumHandle
  580. )
  581. /*++
  582. Abstract:
  583. End enumeration of concepture license key pack table.
  584. Parameter;
  585. lpEnumHandle - enumeration handle return by TLSDBLicenseKeyPackEnumBegin().
  586. Returns:
  587. ++*/
  588. {
  589. if(lpEnumHandle)
  590. {
  591. if(lpEnumHandle->pbWorkSpace)
  592. {
  593. TLSDBKeyPackDescEnumEnd(lpEnumHandle->pbWorkSpace);
  594. TLSDBKeyPackEnumEnd(lpEnumHandle->pbWorkSpace);
  595. //FreeTlsLicensePack(&(lpEnumHandle->CurrentKeyPack));
  596. ReleaseWorkSpace(&(lpEnumHandle->pbWorkSpace));
  597. }
  598. delete lpEnumHandle;
  599. }
  600. return ERROR_SUCCESS;
  601. }
  602. //+--------------------------------------------------------------------
  603. #define CH_PLATFORMID_OTHERS 3
  604. #define CH_PLATFORMID_UPGRADE 2
  605. BOOL
  606. VerifyInternetLicensePack(
  607. License_KeyPack* pLicensePack
  608. )
  609. /*++
  610. --*/
  611. {
  612. BOOL bSuccess = TRUE;
  613. switch(pLicensePack->dwKeypackType)
  614. {
  615. case LICENSE_KEYPACK_TYPE_SELECT:
  616. case LICENSE_KEYPACK_TYPE_MOLP:
  617. case LICENSE_KEYPACK_TYPE_RETAIL:
  618. break;
  619. default:
  620. DBGPrintf(
  621. DBG_ERROR,
  622. DBG_FACILITY_RPC,
  623. DBG_FACILITY_KEYPACK,
  624. _TEXT("LSDBRegisterLicenseKeyPack : invalid keypack type - %d\n"),
  625. pLicensePack->dwKeypackType
  626. );
  627. bSuccess = FALSE;
  628. }
  629. if(bSuccess == FALSE)
  630. {
  631. goto cleanup;
  632. }
  633. if(bSuccess == FALSE)
  634. {
  635. goto cleanup;
  636. }
  637. if(CompareFileTime(&pLicensePack->ActiveDate, &pLicensePack->ExpireDate) > 0)
  638. {
  639. DBGPrintf(
  640. DBG_ERROR,
  641. DBG_FACILITY_RPC,
  642. DBG_FACILITY_KEYPACK,
  643. _TEXT("LSDBRegisterLicenseKeyPack : invalid activate date and expiration date\n")
  644. );
  645. bSuccess = FALSE;
  646. goto cleanup;
  647. }
  648. if(pLicensePack->pbProductId == NULL || pLicensePack->cbProductId == NULL)
  649. {
  650. DBGPrintf(
  651. DBG_ERROR,
  652. DBG_FACILITY_RPC,
  653. DBG_FACILITY_KEYPACK,
  654. _TEXT("LSDBRegisterLicenseKeyPack : No product ID\n")
  655. );
  656. bSuccess = FALSE;
  657. goto cleanup;
  658. }
  659. if(pLicensePack->dwDescriptionCount == 0 || pLicensePack->pDescription == NULL)
  660. {
  661. DBGPrintf(
  662. DBG_ERROR,
  663. DBG_FACILITY_RPC,
  664. DBG_FACILITY_KEYPACK,
  665. _TEXT("LSDBRegisterLicenseKeyPack : No product description\n")
  666. );
  667. bSuccess = FALSE;
  668. goto cleanup;
  669. }
  670. if(pLicensePack->cbManufacturer == 0 || pLicensePack->pbManufacturer == NULL)
  671. {
  672. DBGPrintf(
  673. DBG_ERROR,
  674. DBG_FACILITY_RPC,
  675. DBG_FACILITY_KEYPACK,
  676. _TEXT("LSDBRegisterLicenseKeyPack : No product manufacturer\n")
  677. );
  678. bSuccess = FALSE;
  679. }
  680. cleanup:
  681. return bSuccess;
  682. }
  683. //----------------------------------------------------------------------
  684. DWORD
  685. ConvertInternetLicensePackToPMLicensePack(
  686. License_KeyPack* pLicensePack,
  687. PPMREGISTERLICENSEPACK ppmLicensePack
  688. )
  689. /*++
  690. --*/
  691. {
  692. DWORD dwStatus = ERROR_SUCCESS;
  693. memset(ppmLicensePack, 0, sizeof(PMREGISTERLICENSEPACK));
  694. if(VerifyInternetLicensePack(pLicensePack) == FALSE)
  695. {
  696. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  697. goto cleanup;
  698. }
  699. ppmLicensePack->SourceType = REGISTER_SOURCE_INTERNET;
  700. ppmLicensePack->dwKeyPackType = pLicensePack->dwKeypackType;
  701. ppmLicensePack->dwDistChannel = pLicensePack->dwDistChannel;
  702. ppmLicensePack->KeypackSerialNum = pLicensePack->KeypackSerialNum;
  703. ppmLicensePack->IssueDate = pLicensePack->IssueDate;
  704. ppmLicensePack->ActiveDate = pLicensePack->ActiveDate;
  705. ppmLicensePack->ExpireDate = pLicensePack->ExpireDate;
  706. ppmLicensePack->dwBeginSerialNum = pLicensePack->dwBeginSerialNum;
  707. ppmLicensePack->dwQuantity = pLicensePack->dwQuantity;
  708. memcpy(
  709. ppmLicensePack->szProductId,
  710. pLicensePack->pbProductId,
  711. min(sizeof(ppmLicensePack->szProductId) - sizeof(TCHAR), pLicensePack->cbProductId)
  712. );
  713. memcpy(
  714. ppmLicensePack->szCompanyName,
  715. pLicensePack->pbManufacturer,
  716. min(sizeof(ppmLicensePack->szCompanyName) - sizeof(TCHAR), pLicensePack->cbManufacturer)
  717. );
  718. ppmLicensePack->dwProductVersion = pLicensePack->dwProductVersion;
  719. ppmLicensePack->dwPlatformId = pLicensePack->dwPlatformId;
  720. ppmLicensePack->dwLicenseType = pLicensePack->dwLicenseType;
  721. ppmLicensePack->dwDescriptionCount = pLicensePack->dwDescriptionCount;
  722. if( pLicensePack->dwDescriptionCount != 0 )
  723. {
  724. ppmLicensePack->pDescription = (PPMREGISTERLKPDESC)AllocateMemory(sizeof(PMREGISTERLKPDESC) * ppmLicensePack->dwDescriptionCount);
  725. if(ppmLicensePack->pDescription != NULL)
  726. {
  727. for(DWORD dwIndex = 0; dwIndex < ppmLicensePack->dwDescriptionCount; dwIndex++)
  728. {
  729. ppmLicensePack->pDescription[dwIndex].Locale = pLicensePack->pDescription[dwIndex].Locale;
  730. memcpy(
  731. ppmLicensePack->pDescription[dwIndex].szProductName,
  732. pLicensePack->pDescription[dwIndex].pbProductName,
  733. min(
  734. sizeof(ppmLicensePack->pDescription[dwIndex].szProductName) - sizeof(TCHAR),
  735. pLicensePack->pDescription[dwIndex].cbProductName
  736. )
  737. );
  738. memcpy(
  739. ppmLicensePack->pDescription[dwIndex].szProductDesc,
  740. pLicensePack->pDescription[dwIndex].pDescription,
  741. min(
  742. sizeof(ppmLicensePack->pDescription[dwIndex].szProductDesc) - sizeof(TCHAR),
  743. pLicensePack->pDescription[dwIndex].cbDescription
  744. )
  745. );
  746. }
  747. }
  748. else
  749. {
  750. SetLastError(dwStatus = ERROR_OUTOFMEMORY);
  751. }
  752. }
  753. cleanup:
  754. return dwStatus;
  755. }
  756. //----------------------------------------------------------------------------
  757. DWORD
  758. TLSDBInstallKeyPack(
  759. IN PTLSDbWorkSpace pDbWkSpace,
  760. IN PPMLSKEYPACK ppmLsKeyPack,
  761. OUT LPLSKeyPack lpInstalledKeyPack
  762. )
  763. /*++
  764. --*/
  765. {
  766. DWORD dwStatus = ERROR_SUCCESS;
  767. LSKeyPack KeyPack;
  768. DWORD i;
  769. //
  770. // Policy module should leave product name/description in PPMREGISTERLKPDESC
  771. //
  772. memset(&KeyPack, 0, sizeof(LSKeyPack));
  773. KeyPack = ppmLsKeyPack->keypack;
  774. if (!FileTimeToLicenseDate(
  775. &ppmLsKeyPack->ActiveDate,
  776. &KeyPack.dwActivateDate
  777. ))
  778. {
  779. dwStatus = GetLastError();
  780. goto cleanup;
  781. }
  782. if (!FileTimeToLicenseDate(
  783. &ppmLsKeyPack->ExpireDate,
  784. &KeyPack.dwExpirationDate
  785. ))
  786. {
  787. dwStatus = GetLastError();
  788. goto cleanup;
  789. }
  790. //
  791. // Add to KeyPack and KeyPackDesc Table.
  792. for(i=0; i < ppmLsKeyPack->dwDescriptionCount && dwStatus == ERROR_SUCCESS; i++)
  793. {
  794. KeyPack.ucKeyPackStatus = (i) ? LSKEYPACKSTATUS_ADD_DESC : LSKEYPACKSTATUS_ACTIVE;
  795. KeyPack.dwLanguageId = ppmLsKeyPack->pDescription[i].Locale;
  796. _tcscpy(
  797. KeyPack.szProductName,
  798. ppmLsKeyPack->pDescription[i].szProductName
  799. );
  800. _tcscpy(
  801. KeyPack.szProductDesc,
  802. ppmLsKeyPack->pDescription[i].szProductDesc
  803. );
  804. //
  805. // This is a temporary workaround to Install Whistler CALs: If registry key is not set,
  806. // Keypack's minor version number is set to 2.
  807. //
  808. HKEY hKey = NULL;
  809. dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WHISTLER_CAL, 0,
  810. KEY_ALL_ACCESS, &hKey);
  811. if (dwStatus == ERROR_SUCCESS)
  812. {
  813. RegCloseKey(hKey);
  814. }
  815. else
  816. {
  817. if(KeyPack.wMajorVersion == 5 && KeyPack.wMinorVersion == 1)
  818. {
  819. KeyPack.wMinorVersion = 2;
  820. KeyPack.szProductId[7] = _T('2');
  821. }
  822. }
  823. dwStatus = TLSDBLicenseKeyPackAdd(pDbWkSpace, &KeyPack);
  824. }
  825. if(dwStatus == ERROR_SUCCESS)
  826. {
  827. KeyPack.dwNumberOfLicenses = KeyPack.dwTotalLicenseInKeyPack;
  828. KeyPack.ucKeyPackStatus = LSKEYPACKSTATUS_ACTIVE;
  829. if (!FileTimeToLicenseDate(
  830. &ppmLsKeyPack->ActiveDate,
  831. &KeyPack.dwActivateDate
  832. ))
  833. {
  834. dwStatus = GetLastError();
  835. goto cleanup;
  836. }
  837. if (!FileTimeToLicenseDate(
  838. &ppmLsKeyPack->ExpireDate,
  839. &KeyPack.dwExpirationDate
  840. ))
  841. {
  842. dwStatus = GetLastError();
  843. goto cleanup;
  844. }
  845. dwStatus=TLSDBLicenseKeyPackSetStatus(
  846. pDbWkSpace,
  847. LSKEYPACK_SET_ACTIVATEDATE | LSKEYPACK_SET_KEYPACKSTATUS | LSKEYPACK_SET_EXPIREDATE | LSKEYPACK_EXSEARCH_AVAILABLE,
  848. &KeyPack
  849. );
  850. }
  851. //
  852. // Post a ssync work object to all known server.
  853. //
  854. if(dwStatus == ERROR_SUCCESS)
  855. {
  856. *lpInstalledKeyPack = KeyPack;
  857. }
  858. cleanup:
  859. return dwStatus;
  860. }
  861. DWORD
  862. TLSDBRegisterLicenseKeyPack(
  863. IN PTLSDbWorkSpace pDbWkSpace,
  864. IN License_KeyPack* pLicenseKeyPack,
  865. OUT LPLSKeyPack lpInstalledKeyPack
  866. )
  867. /*++
  868. Abstract:
  869. Add a license keypack into database.
  870. Parameter:
  871. pDbWkSpace : workspace handle.
  872. pLicenseKeyPack : Licensed key pack to be added.
  873. Returns:
  874. */
  875. {
  876. LSKeyPack KeyPack;
  877. long activeDate;
  878. long expireDate;
  879. DWORD dwStatus=ERROR_SUCCESS;
  880. PMREGISTERLICENSEPACK pmLicensePack;
  881. PMLSKEYPACK pmLsKeyPack;
  882. CTLSPolicy* pPolicy = NULL;
  883. PMHANDLE hClient = NULL;
  884. TCHAR szTlsProductCode[LSERVER_MAX_STRING_SIZE+1];
  885. TCHAR szCHProductCode[LSERVER_MAX_STRING_SIZE+1];
  886. DWORD dwBufSize = LSERVER_MAX_STRING_SIZE + 1;
  887. DWORD i;
  888. dwStatus = ConvertInternetLicensePackToPMLicensePack(
  889. pLicenseKeyPack,
  890. &pmLicensePack
  891. );
  892. if(dwStatus != ERROR_SUCCESS)
  893. {
  894. goto cleanup;
  895. }
  896. StringCbCopyN(szCHProductCode,
  897. sizeof(szCHProductCode),
  898. pmLicensePack.szProductId,
  899. LSERVER_MAX_STRING_SIZE+1);
  900. if(TranslateCHCodeToTlsCode(
  901. pmLicensePack.szCompanyName,
  902. szCHProductCode,
  903. szTlsProductCode,
  904. &dwBufSize) == TRUE )
  905. {
  906. // if can't find a policy module to handle, use default.
  907. StringCbCopyN(pmLicensePack.szProductId,
  908. sizeof(pmLicensePack.szProductId),
  909. szTlsProductCode,
  910. sizeof(pmLicensePack.szProductId));
  911. }
  912. // use default if necessary
  913. pPolicy = AcquirePolicyModule(
  914. pmLicensePack.szCompanyName,
  915. pmLicensePack.szProductId,
  916. TRUE
  917. );
  918. if(pPolicy == NULL)
  919. {
  920. dwStatus = GetLastError();
  921. goto cleanup;
  922. }
  923. hClient = GenerateClientId();
  924. dwStatus = pPolicy->PMRegisterLicensePack(
  925. hClient,
  926. REGISTER_PROGRESS_NEW,
  927. (PVOID)&pmLicensePack,
  928. (PVOID)&pmLsKeyPack
  929. );
  930. if(dwStatus != ERROR_SUCCESS)
  931. {
  932. goto cleanup;
  933. }
  934. dwStatus = TLSDBInstallKeyPack(
  935. pDbWkSpace,
  936. &pmLsKeyPack,
  937. lpInstalledKeyPack
  938. );
  939. if(dwStatus == ERROR_SUCCESS)
  940. {
  941. TLSResetLogLowLicenseWarning(
  942. pmLicensePack.szCompanyName,
  943. pmLicensePack.szProductId,
  944. pmLicensePack.dwProductVersion,
  945. FALSE
  946. );
  947. }
  948. cleanup:
  949. if(pPolicy != NULL && hClient != NULL)
  950. {
  951. pPolicy->PMRegisterLicensePack(
  952. hClient,
  953. REGISTER_PROGRESS_END,
  954. UlongToPtr(dwStatus),
  955. NULL
  956. );
  957. ReleasePolicyModule(pPolicy);
  958. }
  959. if(pmLicensePack.pDescription != NULL)
  960. {
  961. FreeMemory(pmLicensePack.pDescription);
  962. }
  963. return dwStatus;
  964. }
  965. //+--------------------------------------------------------------------
  966. //
  967. // TermSrv specific code...
  968. //
  969. // PRODUCT_INFO_COMPANY_NAME is defined in license.h
  970. //
  971. #define LKP_VERSION_BASE 1
  972. #define WINDOWS_VERSION_NT5 5
  973. #define WINDOWS_VERSION_BASE 2000
  974. DWORD
  975. TLSDBTelephoneRegisterLicenseKeyPack(
  976. IN PTLSDbWorkSpace pDbWkSpace,
  977. IN LPTSTR pszPID,
  978. IN PBYTE pbLKP,
  979. IN DWORD cbLKP,
  980. OUT LPLSKeyPack lpInstalledKeyPack
  981. )
  982. /*++
  983. Abstract:
  984. Add a license keypack into database.
  985. Parameter:
  986. pDbWkSpace : workspace handle.
  987. pLicenseKeyPack : Licensed key pack to be added.
  988. Returns:
  989. */
  990. {
  991. DWORD dwStatus;
  992. DWORD dwVerifyResult;
  993. DWORD dwQuantity;
  994. DWORD dwSerialNumber;
  995. DWORD dwExpirationMos;
  996. DWORD dwVersion;
  997. DWORD dwUpgrade;
  998. LSKeyPack keypack;
  999. DWORD dwProductVersion;
  1000. PMKEYPACKDESCREQ kpDescReq;
  1001. PPMKEYPACKDESC pKpDesc = NULL;
  1002. CTLSPolicy* pPolicy=NULL;
  1003. PMHANDLE hClient = NULL;
  1004. DWORD dwProgramType;
  1005. struct tm expire;
  1006. time_t currentDate;
  1007. time_t ExpirationDate;
  1008. PMREGISTERLICENSEPACK pmLicensePack;
  1009. PMLSKEYPACK pmLsKeyPack;
  1010. LPTSTR pszLKP = NULL;
  1011. TCHAR szTlsProductCode[LSERVER_MAX_STRING_SIZE+1];
  1012. TCHAR szCHProductCode[LSERVER_MAX_STRING_SIZE+1];
  1013. DWORD dwBufSize = LSERVER_MAX_STRING_SIZE + 1;
  1014. if(pDbWkSpace == NULL || pszPID == NULL || pbLKP == NULL || cbLKP == 0)
  1015. {
  1016. dwStatus = ERROR_INVALID_PARAMETER;
  1017. goto cleanup;
  1018. }
  1019. //
  1020. // Make sure data passed in is NULL terminated, current LKP
  1021. // is base 24 encoded string.
  1022. //
  1023. pszLKP = (LPTSTR)AllocateMemory( cbLKP + sizeof(TCHAR) );
  1024. if(pszLKP == NULL)
  1025. {
  1026. dwStatus = TLS_E_ALLOCATE_MEMORY;
  1027. goto cleanup;
  1028. }
  1029. StringCbCopyN(pszLKP,
  1030. cbLKP+sizeof(TCHAR),
  1031. (LPTSTR)pbLKP,
  1032. cbLKP);
  1033. //
  1034. // Verify LKP
  1035. //
  1036. dwVerifyResult = LKPLITE_LKP_VALID;
  1037. dwStatus = LKPLiteVerifyLKP(
  1038. pszPID,
  1039. pszLKP,
  1040. &dwVerifyResult
  1041. );
  1042. if(dwStatus != ERROR_SUCCESS || dwVerifyResult != LKPLITE_LKP_VALID)
  1043. {
  1044. if(dwVerifyResult == LKPLITE_LKP_INVALID)
  1045. {
  1046. dwStatus = TLS_E_INVALID_LKP;
  1047. }
  1048. else if(dwVerifyResult == LKPLITE_LKP_INVALID_SIGN)
  1049. {
  1050. dwStatus = TLS_E_LKP_INVALID_SIGN;
  1051. }
  1052. goto cleanup;
  1053. }
  1054. //
  1055. // Decode LKP
  1056. //
  1057. dwStatus = LKPLiteCrackLKP(
  1058. pszPID,
  1059. pszLKP,
  1060. szCHProductCode,
  1061. &dwQuantity,
  1062. &dwSerialNumber,
  1063. &dwExpirationMos,
  1064. &dwVersion,
  1065. &dwUpgrade,
  1066. &dwProgramType
  1067. );
  1068. if(dwStatus != ERROR_SUCCESS)
  1069. {
  1070. dwStatus = TLS_E_DECODE_LKP;
  1071. goto cleanup;
  1072. }
  1073. if(TranslateCHCodeToTlsCode(
  1074. PRODUCT_INFO_COMPANY_NAME,
  1075. szCHProductCode,
  1076. szTlsProductCode,
  1077. &dwBufSize) == FALSE )
  1078. {
  1079. // if can't find a policy module to handle, use default.
  1080. StringCbCopyN(szTlsProductCode,
  1081. sizeof(szTlsProductCode),
  1082. szCHProductCode,
  1083. sizeof(szTlsProductCode));
  1084. }
  1085. //
  1086. // Current LKP does not support 1) other company, 2)
  1087. // only register with NT5 or later
  1088. //
  1089. pPolicy = AcquirePolicyModule(
  1090. PRODUCT_INFO_COMPANY_NAME,
  1091. szTlsProductCode,
  1092. TRUE
  1093. );
  1094. if(pPolicy == NULL)
  1095. {
  1096. dwStatus = GetLastError();
  1097. goto cleanup;
  1098. }
  1099. memset(&keypack, 0, sizeof(keypack));
  1100. memset(&pmLicensePack, 0, sizeof(pmLicensePack));
  1101. pmLicensePack.SourceType = REGISTER_SOURCE_PHONE;
  1102. switch(dwProgramType)
  1103. {
  1104. case LKPLITE_PROGRAM_SELECT:
  1105. pmLicensePack.dwKeyPackType = LICENSE_KEYPACK_TYPE_SELECT;
  1106. break;
  1107. case LKPLITE_PROGRAM_MOLP:
  1108. pmLicensePack.dwKeyPackType = LICENSE_KEYPACK_TYPE_MOLP;
  1109. break;
  1110. case LKPLITE_PROGRAM_RETAIL:
  1111. pmLicensePack.dwKeyPackType = LICENSE_KEYPACK_TYPE_RETAIL;
  1112. break;
  1113. default:
  1114. SetLastError(dwStatus = TLS_E_INVALID_DATA);
  1115. goto cleanup;
  1116. }
  1117. pmLicensePack.dwDistChannel = LSKEYPACKCHANNELOFPURCHASE_RETAIL;
  1118. GetSystemTimeAsFileTime(&pmLicensePack.IssueDate);
  1119. pmLicensePack.ActiveDate = pmLicensePack.IssueDate;
  1120. currentDate = time(NULL);
  1121. expire = *gmtime( (time_t *)&currentDate );
  1122. expire.tm_mon += dwExpirationMos;
  1123. ExpirationDate = mktime(&expire);
  1124. if(ExpirationDate == (time_t) -1)
  1125. {
  1126. //
  1127. // expiration month is too big,
  1128. // set it to 2038/1/1
  1129. //
  1130. memset(&expire, 0, sizeof(expire));
  1131. expire.tm_year = 2038 - 1900;
  1132. expire.tm_mon = 0;
  1133. expire.tm_mday = 1;
  1134. ExpirationDate = mktime(&expire);
  1135. }
  1136. if(ExpirationDate == (time_t) -1)
  1137. {
  1138. //
  1139. // invalid time
  1140. //
  1141. dwStatus = ERROR_INVALID_PARAMETER;
  1142. goto cleanup;
  1143. }
  1144. UnixTimeToFileTime(ExpirationDate, &pmLicensePack.ExpireDate);
  1145. //
  1146. // dwSerialNumber is license pack serial number not begin
  1147. // serial number in license pack.
  1148. //
  1149. pmLicensePack.KeypackSerialNum.Data1 = dwSerialNumber;
  1150. //
  1151. // Tel. registration does not have any info regarding
  1152. // begin serial number in license pack.
  1153. //
  1154. pmLicensePack.dwBeginSerialNum = 0;
  1155. pmLicensePack.dwQuantity = dwQuantity;
  1156. _tcscpy(pmLicensePack.szProductId, szTlsProductCode);
  1157. _tcscpy(pmLicensePack.szCompanyName, PRODUCT_INFO_COMPANY_NAME);
  1158. if(dwVersion == 1)
  1159. {
  1160. pmLicensePack.dwProductVersion = MAKELONG(0, WINDOWS_VERSION_NT5);
  1161. }
  1162. else
  1163. {
  1164. DWORD dwMajorVer = (dwVersion >> 3);
  1165. // Right most 3 bits represent Minor version and stored in LOBYTE(LOWORD)
  1166. pmLicensePack.dwProductVersion = (DWORD)(dwVersion & 07);
  1167. // 4 bits starting at 6th position represent Major version and stored in LOBYTE(HIWORD)
  1168. pmLicensePack.dwProductVersion |= (DWORD)(dwMajorVer << 16);
  1169. }
  1170. pmLicensePack.dwPlatformId = dwUpgrade;
  1171. pmLicensePack.dwLicenseType = LSKEYPACKLICENSETYPE_UNKNOWN;
  1172. pmLicensePack.pbLKP = pbLKP;
  1173. pmLicensePack.cbLKP = cbLKP;
  1174. hClient = GenerateClientId();
  1175. dwStatus = pPolicy->PMRegisterLicensePack(
  1176. hClient,
  1177. REGISTER_PROGRESS_NEW,
  1178. (PVOID)&pmLicensePack,
  1179. (PVOID)&pmLsKeyPack
  1180. );
  1181. if(dwStatus != ERROR_SUCCESS)
  1182. {
  1183. goto cleanup;
  1184. }
  1185. dwStatus = TLSDBInstallKeyPack(
  1186. pDbWkSpace,
  1187. &pmLsKeyPack,
  1188. lpInstalledKeyPack
  1189. );
  1190. if(dwStatus == ERROR_SUCCESS)
  1191. {
  1192. TLSResetLogLowLicenseWarning(
  1193. pmLicensePack.szCompanyName,
  1194. pmLicensePack.szProductId,
  1195. pmLicensePack.dwProductVersion,
  1196. FALSE
  1197. );
  1198. }
  1199. cleanup:
  1200. FreeMemory(pszLKP);
  1201. //
  1202. // Close policy module
  1203. //
  1204. if(pPolicy != NULL && hClient != NULL)
  1205. {
  1206. pPolicy->PMRegisterLicensePack(
  1207. hClient,
  1208. REGISTER_PROGRESS_END,
  1209. UlongToPtr(dwStatus),
  1210. NULL
  1211. );
  1212. ReleasePolicyModule(pPolicy);
  1213. }
  1214. return dwStatus;
  1215. }