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.

1025 lines
30 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996-1998
  5. //
  6. // File: db.cpp
  7. //
  8. // Contents:
  9. // all routine deal with cross table query
  10. //
  11. // History:
  12. // Feb 4, 98 HueiWang Created
  13. //---------------------------------------------------------------------------
  14. #include "pch.cpp"
  15. #include "globals.h"
  16. #include "db.h"
  17. #include "clilic.h"
  18. #include "keypack.h"
  19. #include "kp.h"
  20. #include "lkpdesc.h"
  21. #include "postjob.h"
  22. #define STRSAFE_NO_DEPRECATE
  23. #include <strsafe.h>
  24. /****************************************************************************
  25. Function:
  26. LSDBValidateLicense()
  27. Description:
  28. Routine to validate license agaist database, must call LSDecodeLicense()
  29. to convert hydra license to LICENSEREQUEST structure.
  30. Arguments:
  31. IN CSQLStmt* - SQL Statement handle to use
  32. IN PLICENSEREQUEST - License in the form of LICENSEREQUEST structure
  33. IN dwKeyPackId - KeyPack table's ID that is license is issued from
  34. IN dwLicenseId - License tables's License ID
  35. OUT LPKEYPACK - KeyPack record this license is issued from, NULL if not
  36. interested in this value.
  37. OUT LPLICENSE - Corresponding license record for this license, NULL if
  38. not interest in this value.
  39. Returns:
  40. ERROR_SUCCESS
  41. TLS_E_INVALID_LICENSE
  42. TLS_E_INTERNAL
  43. ODBC error.
  44. ****************************************************************************/
  45. DWORD
  46. TLSDBValidateLicense(
  47. PTLSDbWorkSpace pDbWkSpace,
  48. //IN PBYTE pbLicense,
  49. //IN DWORD cbLicense,
  50. IN PHWID phWid,
  51. IN PLICENSEREQUEST pLicensedProduct,
  52. IN DWORD dwKeyPackId,
  53. IN DWORD dwLicenseId,
  54. OUT PTLSLICENSEPACK lpKeyPack,
  55. OUT LPLICENSEDCLIENT lpLicense
  56. )
  57. /*
  58. */
  59. {
  60. DWORD dwStatus=ERROR_SUCCESS;
  61. DWORD dwMatchCount=0;
  62. if(pDbWkSpace == NULL)
  63. {
  64. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  65. TLSASSERT(FALSE);
  66. return dwStatus;
  67. }
  68. TLSLICENSEPACK keypack_search;
  69. TLSLICENSEPACK keypack_found;
  70. LICENSEDCLIENT license_search;
  71. LICENSEDCLIENT license_found;
  72. int count=0;
  73. BOOL bValid=TRUE;
  74. memset(&license_search, 0, sizeof(LICENSEDCLIENT));
  75. memset(&license_found, 0, sizeof(LICENSEDCLIENT));
  76. keypack_found.pbDomainSid = NULL;
  77. license_search.dwLicenseId = dwLicenseId;
  78. dwStatus = TLSDBLicenseEnumBegin(
  79. pDbWkSpace,
  80. TRUE,
  81. LSLICENSE_SEARCH_LICENSEID,
  82. &license_search
  83. );
  84. if(dwStatus != ERROR_SUCCESS)
  85. {
  86. if(IS_JB_ERROR(dwStatus) != TRUE)
  87. {
  88. SetLastError(dwStatus = TLS_E_INVALID_LICENSE);
  89. }
  90. goto cleanup;
  91. }
  92. do
  93. {
  94. dwStatus=TLSDBLicenseEnumNext(
  95. pDbWkSpace,
  96. &license_found
  97. );
  98. if(dwStatus != ERROR_SUCCESS)
  99. break;
  100. count++;
  101. } while(count < 1);
  102. TLSDBLicenseEnumEnd(pDbWkSpace);
  103. if(count != 1)
  104. {
  105. // can't find the license
  106. SetLastError(dwStatus = TLS_E_INVALID_LICENSE);
  107. goto cleanup;
  108. }
  109. if(count > 1)
  110. {
  111. // more than one entry in database has identical
  112. // license id
  113. SetLastError(dwStatus = TLS_E_INTERNAL);
  114. goto cleanup;
  115. }
  116. //
  117. // Not issue by this license server???
  118. //
  119. if(license_found.dwKeyPackId != dwKeyPackId)
  120. {
  121. SetLastError(dwStatus = TLS_E_INVALID_LICENSE);
  122. goto cleanup;
  123. }
  124. //
  125. // new license request might pass different HWID
  126. //
  127. dwMatchCount += (int)(license_found.dwSystemBiosChkSum == phWid->dwPlatformID);
  128. dwMatchCount += (int)(license_found.dwVideoBiosChkSum == phWid->Data1);
  129. dwMatchCount += (int)(license_found.dwFloppyBiosChkSum == phWid->Data2);
  130. dwMatchCount += (int)(license_found.dwHardDiskSize == phWid->Data3);
  131. dwMatchCount += (int)(license_found.dwRamSize == phWid->Data4);
  132. if(dwMatchCount < LICENSE_MIN_MATCH)
  133. {
  134. SetLastError(dwStatus = TLS_E_INVALID_LICENSE);
  135. }
  136. //
  137. // Verify against KeyPack Table
  138. //
  139. memset(&keypack_search, 0, sizeof(keypack_search));
  140. keypack_search.dwKeyPackId = dwKeyPackId;
  141. dwStatus = TLSDBKeyPackFind(
  142. pDbWkSpace,
  143. TRUE,
  144. LSKEYPACK_EXSEARCH_DWINTERNAL,
  145. &keypack_search,
  146. &keypack_found
  147. );
  148. if(dwStatus != ERROR_SUCCESS)
  149. {
  150. if(IS_JB_ERROR(dwStatus) != TRUE)
  151. {
  152. SetLastError(dwStatus = TLS_E_INVALID_LICENSE);
  153. }
  154. goto cleanup;
  155. }
  156. // match KeyPack's Product ID, Version, Language ID, PlatformID
  157. // structure change, no more product version.
  158. if(pLicensedProduct->dwPlatformID != keypack_found.dwPlatformType ||
  159. _tcsicmp((LPTSTR)pLicensedProduct->pProductInfo->pbCompanyName, keypack_found.szCompanyName) ||
  160. _tcsicmp((LPTSTR)pLicensedProduct->pProductInfo->pbProductID, keypack_found.szProductId) )
  161. {
  162. SetLastError(dwStatus = TLS_E_INVALID_LICENSE);
  163. }
  164. cleanup:
  165. //FreeTlsLicensePack(&keypack_found);
  166. if(dwStatus == ERROR_SUCCESS)
  167. {
  168. if(lpKeyPack)
  169. {
  170. *lpKeyPack = keypack_found;
  171. }
  172. if(lpLicense)
  173. {
  174. *lpLicense = license_found;
  175. }
  176. }
  177. return dwStatus;
  178. }
  179. /*************************************************************************
  180. Function:
  181. LSDBDeleteLicense()
  182. *************************************************************************/
  183. DWORD
  184. TLSDBDeleteLicense(
  185. PTLSDbWorkSpace pDbWkSpace,
  186. IN DWORD dwKeyPackId,
  187. DWORD dwLicenseId
  188. )
  189. /*
  190. */
  191. {
  192. // TODO - license entry base on license id
  193. // 1) Return license back to key pack
  194. // 2) 'Physically' delete the license.
  195. return ERROR_SUCCESS;
  196. }
  197. /*************************************************************************
  198. Function:
  199. LSDBRevokeLicense()
  200. *************************************************************************/
  201. DWORD
  202. TLSDBRevokeLicense(
  203. PTLSDbWorkSpace pDbWkSpace,
  204. IN DWORD dwKeyPacKId,
  205. IN DWORD dwLicenseId
  206. )
  207. {
  208. // Set License Status to revoked
  209. // Return License to KeyPack
  210. // call LSDBDeleteKeyPack() and if not successful, insert into RevokeLicenseTable
  211. return ERROR_SUCCESS;
  212. }
  213. /*************************************************************************
  214. Function:
  215. LSDBReturnLicense()
  216. *************************************************************************/
  217. DWORD
  218. TLSDBReturnLicense(
  219. PTLSDbWorkSpace pDbWkSpace,
  220. IN DWORD dwKeyPackId,
  221. IN DWORD dwLicenseId,
  222. IN DWORD dwNewLicenseStatus
  223. )
  224. /*
  225. */
  226. {
  227. DWORD dwStatus=ERROR_SUCCESS;
  228. DWORD dwQuantity = 1;
  229. TLSDBLockKeyPackTable();
  230. TLSDBLockLicenseTable();
  231. //
  232. // no verification on record got updated.
  233. //
  234. LICENSEDCLIENT license;
  235. license.dwLicenseId = dwLicenseId;
  236. license.ucLicenseStatus = dwNewLicenseStatus;
  237. //
  238. // use undocumented feature to delete license
  239. //
  240. DBGPrintf(
  241. DBG_INFORMATION,
  242. DBG_FACILITY_RETURN,
  243. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  244. _TEXT("Deleting license ID %d issued by keypack %d\n"),
  245. license.dwLicenseId,
  246. dwKeyPackId
  247. );
  248. if (dwNewLicenseStatus == LSLICENSESTATUS_DELETE)
  249. {
  250. // get number of CALs in this license
  251. LICENSEDCLIENT licenseFound;
  252. dwStatus = TLSDBLicenseFind(
  253. pDbWkSpace,
  254. TRUE,
  255. LSLICENSE_SEARCH_LICENSEID,
  256. &license,
  257. &licenseFound
  258. );
  259. if(dwStatus == ERROR_SUCCESS)
  260. {
  261. dwQuantity = licenseFound.dwNumLicenses;
  262. }
  263. }
  264. dwStatus = TLSDBLicenseSetValue(
  265. pDbWkSpace,
  266. LSLICENSE_EXSEARCH_LICENSESTATUS,
  267. &license,
  268. FALSE
  269. );
  270. if(dwStatus == ERROR_SUCCESS && dwNewLicenseStatus == LSLICENSESTATUS_DELETE)
  271. {
  272. dwStatus = TLSDBReturnLicenseToKeyPack(
  273. pDbWkSpace,
  274. dwKeyPackId,
  275. dwQuantity
  276. );
  277. }
  278. TLSDBUnlockLicenseTable();
  279. TLSDBUnlockKeyPackTable();
  280. return dwStatus;
  281. }
  282. /*************************************************************************
  283. Function:
  284. LSDBReturnLicenseToKeyPack()
  285. *************************************************************************/
  286. DWORD
  287. TLSDBReturnLicenseToKeyPack(
  288. IN PTLSDbWorkSpace pDbWkSpace,
  289. IN DWORD dwKeyPackId,
  290. IN int dwNumLicense
  291. )
  292. {
  293. DWORD dwStatus = ERROR_SUCCESS;
  294. TLSDBLockKeyPackTable();
  295. #ifdef DBG
  296. DWORD dwPrevNumLicense=0;
  297. #endif
  298. TLSLICENSEPACK found;
  299. TLSLICENSEPACK search;
  300. found.pbDomainSid = NULL;
  301. do {
  302. // retrieve number of licenses
  303. search.dwKeyPackId = dwKeyPackId;
  304. dwStatus = TLSDBKeyPackFind(
  305. pDbWkSpace,
  306. TRUE,
  307. LSKEYPACK_EXSEARCH_DWINTERNAL,
  308. &search,
  309. &found
  310. );
  311. if(dwStatus != ERROR_SUCCESS)
  312. {
  313. if(IS_JB_ERROR(dwStatus) == FALSE)
  314. {
  315. SetLastError(dwStatus = TLS_E_RECORD_NOTFOUND);
  316. }
  317. break;
  318. }
  319. if(search.dwKeyPackId != found.dwKeyPackId)
  320. {
  321. TLSASSERT(FALSE);
  322. }
  323. #ifdef DBG
  324. dwPrevNumLicense = found.dwNumberOfLicenses;
  325. #endif
  326. // set the number of licenses issued by 1
  327. switch( (found.ucAgreementType & ~LSKEYPACK_RESERVED_TYPE) )
  328. {
  329. case LSKEYPACKTYPE_RETAIL:
  330. case LSKEYPACKTYPE_OPEN:
  331. case LSKEYPACKTYPE_SELECT:
  332. // number of licenses available
  333. if (found.dwNumberOfLicenses + dwNumLicense <= found.dwTotalLicenseInKeyPack)
  334. {
  335. found.dwNumberOfLicenses += dwNumLicense;
  336. dwNumLicense = 0;
  337. }
  338. else
  339. {
  340. DWORD dwRet = found.dwTotalLicenseInKeyPack - found.dwNumberOfLicenses;
  341. found.dwNumberOfLicenses = found.dwTotalLicenseInKeyPack;
  342. dwNumLicense -= dwRet;
  343. }
  344. break;
  345. case LSKEYPACKTYPE_FREE:
  346. case LSKEYPACKTYPE_TEMPORARY:
  347. // number of license issued
  348. if(found.dwNumberOfLicenses > 0)
  349. {
  350. found.dwNumberOfLicenses -= dwNumLicense;
  351. dwNumLicense = 0;
  352. }
  353. break;
  354. default:
  355. SetLastError(dwStatus = TLS_E_CORRUPT_DATABASE);
  356. break;
  357. }
  358. #ifdef DBG
  359. DBGPrintf(
  360. DBG_INFORMATION,
  361. DBG_FACILITY_RETURN,
  362. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  363. _TEXT("Returning license to keypack %d - from %d to %d\n"),
  364. found.dwKeyPackId,
  365. dwPrevNumLicense,
  366. found.dwNumberOfLicenses
  367. );
  368. #endif
  369. //
  370. // use undocumented feature to delete temp. keypack
  371. if( (found.ucAgreementType & ~LSKEYPACK_RESERVED_TYPE) == LSKEYPACKTYPE_TEMPORARY &&
  372. found.dwNumberOfLicenses == 0)
  373. {
  374. found.ucKeyPackStatus = LSKEYPACKSTATUS_DELETE;
  375. // delete keypack desc table
  376. LICPACKDESC keyPackDesc;
  377. memset(&keyPackDesc, 0, sizeof(LICPACKDESC));
  378. keyPackDesc.dwKeyPackId = found.dwKeyPackId;
  379. TLSDBKeyPackDescSetValue(
  380. pDbWkSpace,
  381. KEYPACKDESC_SET_DELETE_ENTRY,
  382. &keyPackDesc
  383. );
  384. }
  385. dwStatus=TLSDBKeyPackSetValues(
  386. pDbWkSpace,
  387. TRUE,
  388. LSKEYPACK_EXSEARCH_AVAILABLE,
  389. &found
  390. );
  391. } while(FALSE);
  392. if ((dwStatus == ERROR_SUCCESS) && (dwNumLicense > 0))
  393. {
  394. // next, find more keypacks of the same type to return licenses to
  395. // ignore any error
  396. TLSDBReturnLicenseToAnyKeyPack(
  397. pDbWkSpace,
  398. found.szProductId,
  399. found.wMajorVersion,
  400. found.wMinorVersion,
  401. dwKeyPackId,
  402. dwNumLicense);
  403. }
  404. TLSDBUnlockKeyPackTable();
  405. return dwStatus;
  406. }
  407. /*************************************************************************
  408. Function:
  409. TLSDBReturnLicenseToAnyKeyPack()
  410. *************************************************************************/
  411. DWORD
  412. TLSDBReturnLicenseToAnyKeyPack(
  413. IN PTLSDbWorkSpace pDbWkSpace,
  414. IN TCHAR *szProductId,
  415. IN WORD wMajorVersion,
  416. IN WORD wMinorVersion,
  417. IN DWORD dwKeyPackIdSkip,
  418. IN int dwNumLicense
  419. )
  420. {
  421. DWORD dwStatus = ERROR_SUCCESS;
  422. TLSLICENSEPACK found;
  423. TLSLICENSEPACK search;
  424. SAFESTRCPY(search.szProductId,szProductId);
  425. dwStatus = TLSDBKeyPackEnumBegin(pDbWkSpace,
  426. TRUE, // bMatchAll
  427. LSKEYPACK_SEARCH_PRODUCTID,
  428. &search
  429. );
  430. if(dwStatus != ERROR_SUCCESS)
  431. {
  432. goto cleanup;
  433. }
  434. while ((dwNumLicense > 0)
  435. && ((dwStatus = TLSDBKeyPackEnumNext(pDbWkSpace, &found))
  436. == ERROR_SUCCESS))
  437. {
  438. if (found.dwKeyPackId == dwKeyPackIdSkip)
  439. continue;
  440. if (found.wMajorVersion != wMajorVersion)
  441. continue;
  442. if (found.wMinorVersion != wMinorVersion)
  443. continue;
  444. if (found.ucAgreementType & LSKEYPACK_REMOTE_TYPE)
  445. continue;
  446. if (found.ucKeyPackStatus & LSKEYPACKSTATUS_REMOTE)
  447. continue;
  448. UCHAR ucKeyPackStatus = found.ucKeyPackStatus & ~LSKEYPACKSTATUS_RESERVED;
  449. if(ucKeyPackStatus == LSKEYPACKSTATUS_UNKNOWN
  450. || ucKeyPackStatus == LSKEYPACKSTATUS_RETURNED
  451. || ucKeyPackStatus == LSKEYPACKSTATUS_REVOKED
  452. || ucKeyPackStatus == LSKEYPACKSTATUS_OTHERS)
  453. continue;
  454. if (found.dwNumberOfLicenses == found.dwTotalLicenseInKeyPack)
  455. continue;
  456. UCHAR ucAgreementType = found.ucAgreementType & ~LSKEYPACK_RESERVED_TYPE;
  457. if (ucAgreementType != LSKEYPACKTYPE_RETAIL
  458. && ucAgreementType != LSKEYPACKTYPE_OPEN
  459. && ucAgreementType != LSKEYPACKTYPE_SELECT)
  460. continue;
  461. if (_tcsicmp(found.szProductId, szProductId) != 0)
  462. continue;
  463. // number of licenses available
  464. if (found.dwNumberOfLicenses + dwNumLicense <= found.dwTotalLicenseInKeyPack)
  465. {
  466. found.dwNumberOfLicenses += dwNumLicense;
  467. dwStatus=TLSDBKeyPackSetValues(
  468. pDbWkSpace,
  469. TRUE,
  470. LSKEYPACK_EXSEARCH_AVAILABLE,
  471. &found
  472. );
  473. if (ERROR_SUCCESS == dwStatus)
  474. {
  475. dwNumLicense = 0;
  476. }
  477. }
  478. else
  479. {
  480. DWORD dwRet = found.dwTotalLicenseInKeyPack - found.dwNumberOfLicenses;
  481. found.dwNumberOfLicenses = found.dwTotalLicenseInKeyPack;
  482. dwStatus=TLSDBKeyPackSetValues(
  483. pDbWkSpace,
  484. TRUE,
  485. LSKEYPACK_EXSEARCH_AVAILABLE,
  486. &found
  487. );
  488. if (ERROR_SUCCESS == dwStatus)
  489. {
  490. dwNumLicense -= dwRet;
  491. }
  492. }
  493. }
  494. TLSDBKeyPackEnumEnd(pDbWkSpace);
  495. cleanup:
  496. return dwStatus;
  497. }
  498. /*************************************************************************
  499. Function:
  500. LSDBRevokeKeyPack()
  501. *************************************************************************/
  502. DWORD
  503. TLSDBRevokeKeyPack(
  504. IN PTLSDbWorkSpace pDbWkSpace,
  505. IN DWORD dwKeyPackId
  506. )
  507. {
  508. // Set Key Pack Status to Revoke
  509. // Insert this key pack into RevokeKeyPackTable ???
  510. return ERROR_SUCCESS;
  511. }
  512. /*************************************************************************
  513. Function:
  514. LSDBReturnKeyPack()
  515. *************************************************************************/
  516. DWORD
  517. TLSDBReturnKeyPack(
  518. IN PTLSDbWorkSpace pDbWkSpace,
  519. IN DWORD dwKeyPackId
  520. )
  521. {
  522. // Same as RevokeKeyPack except status is return
  523. // Delete Key pack only when all license has been returned.
  524. return ERROR_SUCCESS;
  525. }
  526. /*************************************************************************
  527. Function:
  528. LSDBDeleteKeyPack()
  529. *************************************************************************/
  530. DWORD
  531. TLSDBDeleteKeyPack(
  532. PTLSDbWorkSpace pDbWkSpace,
  533. IN DWORD dwKeyPackId
  534. )
  535. {
  536. // Delete Only when all license has been returned.
  537. return ERROR_SUCCESS;
  538. }
  539. //+------------------------------------------------------------------------
  540. // Function:
  541. // AllocateLicenses()
  542. //
  543. // Description:
  544. // Allocate license from key Pack
  545. //
  546. // Arguments:
  547. // IN lpSqlStmt - sql statement handle
  548. // IN ucKeyPackType - key pack type to allocate license from
  549. // IN szCompanyName - Product Company
  550. // IN szProductId - Product Name
  551. // IN dwVersion - Product Version
  552. // IN dwPlatformId - Product PlatformId
  553. // IN dwLangId - Product Lanugage Id
  554. // IN OUT lpdwNumLicense - number of license to be allocated and on
  555. // return, number of licenses actually allocated
  556. // IN bufSize - number of interested keypack that has requested license
  557. // IN OUT lpAllocationVector - number of license allocated from list of
  558. // key pack that has requested licenses.
  559. // IN OUT LPKEYPACK - key Pack that license was allocated from
  560. //
  561. // Returns:
  562. // TLS_E_INVALID_DATA Invalid parameter
  563. // TLS_I_NO_MORE_DATA No key pack has the requested license
  564. //
  565. // Notes:
  566. // To keep code clean/simple, call ReturnLicenses() for returning
  567. // licenses
  568. //-------------------------------------------------------------------------
  569. DWORD
  570. VerifyTLSDBAllocateRequest(
  571. IN PTLSDBAllocateRequest pRequest
  572. )
  573. /*
  574. */
  575. {
  576. DWORD dwStatus = ERROR_SUCCESS;
  577. UCHAR ucAgreementType;
  578. if(pRequest == NULL)
  579. {
  580. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  581. goto cleanup;
  582. }
  583. ucAgreementType = (pRequest->ucAgreementType & ~LSKEYPACK_RESERVED_TYPE);
  584. if(ucAgreementType < LSKEYPACKTYPE_FIRST || ucAgreementType > LSKEYPACKTYPE_LAST)
  585. {
  586. DBGPrintf(
  587. DBG_ERROR,
  588. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  589. DBG_ALL_LEVEL,
  590. _TEXT("AllocateLicenses() invalid keypack type - %d\n"),
  591. pRequest->ucAgreementType
  592. );
  593. SetLastError(dwStatus = TLS_E_INVALID_DATA);
  594. goto cleanup;
  595. }
  596. if(pRequest->szCompanyName == NULL || _tcslen(pRequest->szCompanyName) == 0)
  597. {
  598. DBGPrintf(
  599. DBG_ERROR,
  600. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  601. DBG_ALL_LEVEL,
  602. _TEXT("AllocateLicenses() invalid company name\n")
  603. );
  604. SetLastError(dwStatus = TLS_E_INVALID_DATA);
  605. goto cleanup;
  606. }
  607. if(pRequest->szProductId == NULL || _tcslen(pRequest->szProductId) == 0)
  608. {
  609. DBGPrintf(
  610. DBG_ERROR,
  611. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  612. DBG_ALL_LEVEL,
  613. _TEXT("AllocateLicenses() invalid product id\n")
  614. );
  615. SetLastError(dwStatus = TLS_E_INVALID_DATA);
  616. }
  617. cleanup:
  618. return dwStatus;
  619. }
  620. //----------------------------------------------------------------------
  621. DWORD
  622. AllocateLicensesFromDB(
  623. IN PTLSDbWorkSpace pDbWkSpace,
  624. IN PTLSDBAllocateRequest pRequest,
  625. IN BOOL fCheckAgreementType,
  626. IN OUT PTLSDBLicenseAllocation pAllocated
  627. )
  628. /*
  629. */
  630. {
  631. DWORD status=ERROR_SUCCESS;
  632. if(pDbWkSpace == NULL || pRequest == NULL || pAllocated == NULL)
  633. {
  634. DBGPrintf(
  635. DBG_ERROR,
  636. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  637. DBG_ALL_LEVEL,
  638. _TEXT("pDbWkSpace is NULL...\n")
  639. );
  640. SetLastError(status = ERROR_INVALID_PARAMETER);
  641. TLSASSERT(FALSE);
  642. return status;
  643. }
  644. status = VerifyTLSDBAllocateRequest(pRequest);
  645. if(status != ERROR_SUCCESS)
  646. return status;
  647. if(pAllocated->dwBufSize <= 0)
  648. {
  649. DBGPrintf(
  650. DBG_ERROR,
  651. DBG_FACILITY_ALLOCATELICENSE,
  652. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  653. _TEXT("AllocateLicenses() invalid return buffer size\n")
  654. );
  655. SetLastError(status = TLS_E_INVALID_DATA);
  656. return status;
  657. }
  658. #ifdef DBG
  659. DWORD dwPrevNumLicense;
  660. #endif
  661. BOOL bProductInstalled=FALSE;
  662. DWORD bufIndex=0;
  663. TLSLICENSEPACK keypack_search;
  664. TLSLICENSEPACK keypack_found;
  665. DWORD dwNumLicenses = pRequest->dwNumLicenses; // number of license wanted/returned
  666. DWORD dwTotalAllocated=0;
  667. memset(&keypack_search, 0, sizeof(keypack_search));
  668. memset(&keypack_found, 0, sizeof(keypack_found));
  669. keypack_search.ucAgreementType = pRequest->ucAgreementType;
  670. StringCbCopy(keypack_search.szCompanyName, sizeof(keypack_search.szCompanyName), pRequest->szCompanyName);
  671. StringCbCopy(keypack_search.szProductId, sizeof(keypack_search.szProductId), pRequest->szProductId);
  672. keypack_search.wMajorVersion = HIWORD(pRequest->dwVersion);
  673. keypack_search.wMinorVersion = LOWORD(pRequest->dwVersion);
  674. keypack_search.dwPlatformType = pRequest->dwPlatformId;
  675. LicPackTable& licpack_table=pDbWkSpace->m_LicPackTable;
  676. time_t current_time=time(NULL);
  677. //
  678. // Lock Key Pack table
  679. // Only update requires locking, read might get in-correct value.
  680. //
  681. //
  682. // Only allow one thread to enter - Jet not fast enough in updating entry
  683. //
  684. TLSDBLockKeyPackTable();
  685. status = TLSDBKeyPackEnumBegin(
  686. pDbWkSpace,
  687. TRUE,
  688. LSKEYPACK_SEARCH_PRODUCTID | (fCheckAgreementType ? LICENSEDPACK_FIND_LICENSEPACK : 0),
  689. &keypack_search
  690. );
  691. if(status != ERROR_SUCCESS)
  692. goto cleanup;
  693. while(status == ERROR_SUCCESS && dwNumLicenses != 0 && bufIndex < pAllocated->dwBufSize)
  694. {
  695. status = TLSDBKeyPackEnumNext(
  696. pDbWkSpace,
  697. &keypack_found
  698. );
  699. if(status != ERROR_SUCCESS)
  700. break;
  701. //
  702. // Skip remote keypack
  703. //
  704. if(keypack_found.ucAgreementType & LSKEYPACK_REMOTE_TYPE)
  705. {
  706. continue;
  707. }
  708. if(keypack_found.ucKeyPackStatus & LSKEYPACKSTATUS_REMOTE)
  709. {
  710. continue;
  711. }
  712. if(fCheckAgreementType
  713. && (keypack_found.ucAgreementType != pRequest->ucAgreementType))
  714. {
  715. continue;
  716. }
  717. UCHAR ucKeyPackStatus = keypack_found.ucKeyPackStatus & ~LSKEYPACKSTATUS_RESERVED;
  718. // Allocating licenses
  719. //
  720. // Throw away any key pack that has bad status
  721. // one of the reason why can't returning license in this routine
  722. // for returning license, we should not care about key pack
  723. // status.
  724. if(ucKeyPackStatus == LSKEYPACKSTATUS_UNKNOWN ||
  725. ucKeyPackStatus == LSKEYPACKSTATUS_RETURNED ||
  726. ucKeyPackStatus == LSKEYPACKSTATUS_REVOKED ||
  727. ucKeyPackStatus == LSKEYPACKSTATUS_OTHERS)
  728. {
  729. continue;
  730. }
  731. //
  732. // we find the product, make sure the version is what we want.
  733. //
  734. bProductInstalled=TRUE;
  735. // Expired keypack
  736. // TODO - update table here.
  737. if((DWORD)keypack_found.dwExpirationDate < current_time)
  738. continue;
  739. //
  740. // never allocate from older version
  741. //
  742. if( keypack_found.wMajorVersion < HIWORD(pRequest->dwVersion) )
  743. {
  744. continue;
  745. }
  746. //
  747. // Same major version but older minor
  748. //
  749. if( keypack_found.wMajorVersion == HIWORD(pRequest->dwVersion) &&
  750. keypack_found.wMinorVersion < LOWORD(pRequest->dwVersion) )
  751. {
  752. continue;
  753. }
  754. if(pRequest->dwScheme == ALLOCATE_EXACT_VERSION)
  755. {
  756. if(keypack_found.wMajorVersion != HIWORD(pRequest->dwVersion) ||
  757. keypack_found.wMinorVersion < LOWORD(pRequest->dwVersion) )
  758. {
  759. continue;
  760. }
  761. }
  762. UCHAR ucAgreementType = (keypack_found.ucAgreementType & ~LSKEYPACK_RESERVED_TYPE);
  763. //
  764. // Verify number of licenses left
  765. //
  766. if((ucAgreementType == LSKEYPACKTYPE_SELECT ||
  767. ucAgreementType == LSKEYPACKTYPE_RETAIL ||
  768. ucAgreementType == LSKEYPACKTYPE_OPEN) &&
  769. keypack_found.dwNumberOfLicenses == 0)
  770. {
  771. continue;
  772. }
  773. pAllocated->lpAllocateKeyPack[bufIndex] = keypack_found;
  774. #ifdef DBG
  775. dwPrevNumLicense = pAllocated->lpAllocateKeyPack[bufIndex].dwNumberOfLicenses;
  776. #endif
  777. if( ucAgreementType != LSKEYPACKTYPE_RETAIL &&
  778. ucAgreementType != LSKEYPACKTYPE_OPEN &&
  779. ucAgreementType != LSKEYPACKTYPE_SELECT )
  780. {
  781. // For Free/temporary license, number of available license is
  782. // how many license has been issued
  783. pAllocated->lpAllocateKeyPack[bufIndex].dwNumberOfLicenses += dwNumLicenses;
  784. pAllocated->pdwAllocationVector[bufIndex] = dwNumLicenses;
  785. dwTotalAllocated += dwNumLicenses;
  786. pAllocated->lpAllocateKeyPack[bufIndex].dwNextSerialNumber += dwNumLicenses;
  787. dwNumLicenses=0;
  788. }
  789. else
  790. {
  791. int allocated=min(dwNumLicenses, keypack_found.dwNumberOfLicenses);
  792. pAllocated->lpAllocateKeyPack[bufIndex].dwNumberOfLicenses -= allocated;
  793. dwNumLicenses -= allocated;
  794. pAllocated->pdwAllocationVector[bufIndex] = allocated;
  795. dwTotalAllocated += allocated;
  796. pAllocated->lpAllocateKeyPack[bufIndex].dwNextSerialNumber += allocated;
  797. }
  798. #if DBG
  799. DBGPrintf(
  800. DBG_INFORMATION,
  801. DBG_FACILITY_ALLOCATELICENSE,
  802. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  803. _TEXT("Updating keypack %d number of license from %d to %d\n"),
  804. pAllocated->lpAllocateKeyPack[bufIndex].dwKeyPackId,
  805. dwPrevNumLicense,
  806. pAllocated->lpAllocateKeyPack[bufIndex].dwNumberOfLicenses
  807. );
  808. #endif
  809. //
  810. // Update number of licenses available for this keypack and license id in keypack
  811. //
  812. GetSystemTimeAsFileTime(&(pAllocated->lpAllocateKeyPack[bufIndex].ftLastModifyTime));
  813. if(licpack_table.UpdateRecord(
  814. pAllocated->lpAllocateKeyPack[bufIndex],
  815. LICENSEDPACK_ALLOCATE_LICENSE_UPDATE_FIELD
  816. ) == FALSE)
  817. {
  818. SetLastError(status = SET_JB_ERROR(licpack_table.GetLastJetError()));
  819. TLSASSERT(FALSE);
  820. break;
  821. }
  822. #ifdef DBG
  823. TLSLICENSEPACK test;
  824. if(licpack_table.FetchRecord(test) == FALSE)
  825. {
  826. SetLastError(status = SET_JB_ERROR(licpack_table.GetLastJetError()));
  827. TLSASSERT(FALSE);
  828. }
  829. if(test.dwKeyPackId != pAllocated->lpAllocateKeyPack[bufIndex].dwKeyPackId ||
  830. test.dwNumberOfLicenses != pAllocated->lpAllocateKeyPack[bufIndex].dwNumberOfLicenses)
  831. {
  832. TLSASSERT(FALSE);
  833. }
  834. //FreeTlsLicensePack(&test);
  835. #endif
  836. bufIndex++;
  837. }
  838. //
  839. // terminate enumeration.
  840. //
  841. TLSDBKeyPackEnumEnd(pDbWkSpace);
  842. if(status == TLS_I_NO_MORE_DATA)
  843. {
  844. if(bufIndex != 0)
  845. {
  846. status = ERROR_SUCCESS;
  847. }
  848. else if(!bProductInstalled)
  849. {
  850. SetLastError(status = TLS_E_PRODUCT_NOTINSTALL);
  851. }
  852. }
  853. if(keypack_found.dwNumberOfLicenses == 0)
  854. {
  855. TLSAnnounceLKPToAllRemoteServer(keypack_found.dwKeyPackId,0);
  856. }
  857. pAllocated->dwBufSize = bufIndex;
  858. pAllocated->dwTotalAllocated = dwTotalAllocated;
  859. pAllocated->dwBufSize = bufIndex;
  860. cleanup:
  861. TLSDBUnlockKeyPackTable();
  862. return status;
  863. }