Source code of Windows XP (NT5)
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.

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