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.

626 lines
18 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996-1998
  5. //
  6. // File: conlic.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 "conlic.h"
  16. #include "db.h"
  17. #include "misc.h"
  18. #include "keypack.h"
  19. #include "clilic.h"
  20. #include "globals.h"
  21. //--------------------------------------------------------------------------
  22. // Function:
  23. // DBQueryConcurrentLicenses()
  24. //
  25. // Description:
  26. // Query number concurrent license issued to server
  27. //
  28. // Arguments:
  29. // See LSDBAllocateConcurrentLicense()
  30. //
  31. // Returns:
  32. // See LSDBAllocateConcurrentLicense()
  33. //
  34. //-------------------------------------------------------------------------
  35. DWORD
  36. TLSDBQueryConcurrentLicenses(
  37. IN PTLSDbWorkSpace pDbWkSpace,
  38. IN LPTSTR szHydra,
  39. IN PTLSDBLICENSEREQUEST pRequest,
  40. IN OUT long* dwQuantity
  41. )
  42. /*
  43. */
  44. {
  45. DWORD dwStatus = ERROR_SUCCESS;
  46. if( pDbWkSpace == NULL ||
  47. pRequest == NULL ||
  48. pRequest == NULL ||
  49. dwQuantity == NULL )
  50. {
  51. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  52. return dwStatus;
  53. }
  54. TLSLICENSEPACK keypack_search;
  55. TLSLICENSEPACK keypack_found;
  56. //keypack_search.ucAgreementType = LSKEYPACKTYPE_CONCURRENT;
  57. lstrcpyn(
  58. keypack_search.szCompanyName,
  59. (LPCTSTR)pRequest->pszCompanyName,
  60. sizeof(keypack_search.szCompanyName) / sizeof(keypack_search.szCompanyName[0])
  61. );
  62. lstrcpyn(
  63. keypack_search.szProductId,
  64. (LPTSTR)pRequest->pszProductId,
  65. sizeof(keypack_search.szProductId)/sizeof(keypack_search.szProductId[0])
  66. );
  67. keypack_search.wMajorVersion = HIWORD(pRequest->dwProductVersion);
  68. keypack_search.wMinorVersion = LOWORD(pRequest->dwProductVersion);
  69. keypack_search.dwPlatformType = pRequest->dwPlatformID;
  70. LICENSEDCLIENT license_search;
  71. LICENSEDCLIENT license_found;
  72. *dwQuantity = 0;
  73. //
  74. // Only allow one thread to enter - Jet not fast enough in updating entry
  75. //
  76. TLSDBLockKeyPackTable();
  77. dwStatus = TLSDBKeyPackEnumBegin(
  78. pDbWkSpace,
  79. TRUE,
  80. LSKEYPACK_SEARCH_PRODUCTID, //LICENSEDPACK_FIND_LICENSEPACK,
  81. &keypack_search
  82. );
  83. while(dwStatus == ERROR_SUCCESS)
  84. {
  85. dwStatus = TLSDBKeyPackEnumNext(
  86. pDbWkSpace,
  87. &keypack_found
  88. );
  89. if(dwStatus != ERROR_SUCCESS)
  90. break;
  91. //
  92. // should be a big internal error since keypack type
  93. // is on our wish list.
  94. //
  95. //if(keypack_found.ucAgreementType != keypack_search.ucAgreementType)
  96. // continue;
  97. if( keypack_found.wMajorVersion != keypack_search.wMajorVersion ||
  98. keypack_found.wMinorVersion != keypack_search.wMinorVersion )
  99. {
  100. continue;
  101. }
  102. if( _tcsicmp(keypack_found.szCompanyName, keypack_search.szCompanyName) != 0 )
  103. {
  104. continue;
  105. }
  106. if( _tcsicmp(keypack_found.szProductId, keypack_search.szProductId) != 0 )
  107. {
  108. continue;
  109. }
  110. //
  111. // Enumerate thru licensed table to sum up all license issued.
  112. //
  113. license_search.dwKeyPackId = keypack_found.dwKeyPackId;
  114. dwStatus = TLSDBLicenseEnumBegin(
  115. pDbWkSpace,
  116. TRUE,
  117. LSLICENSE_SEARCH_KEYPACKID,
  118. &license_search
  119. );
  120. while(dwStatus == ERROR_SUCCESS)
  121. {
  122. dwStatus = TLSDBLicenseEnumNext(
  123. pDbWkSpace,
  124. &license_found
  125. );
  126. if(dwStatus != ERROR_SUCCESS)
  127. break;
  128. if(szHydra && _tcsicmp(license_found.szMachineName, szHydra) == 0)
  129. {
  130. (*dwQuantity) += license_found.dwNumLicenses;
  131. }
  132. }
  133. TLSDBLicenseEnumEnd(pDbWkSpace);
  134. //
  135. // error in looping thru license table
  136. //
  137. if(dwStatus != TLS_I_NO_MORE_DATA)
  138. break;
  139. dwStatus = ERROR_SUCCESS;
  140. }
  141. TLSDBKeyPackEnumEnd(pDbWkSpace);
  142. TLSDBUnlockKeyPackTable();
  143. if(dwStatus == TLS_I_NO_MORE_DATA)
  144. dwStatus = ERROR_SUCCESS;
  145. return dwStatus;
  146. }
  147. //--------------------------------------------------------------------------
  148. // Function:
  149. // DBReturnConcurrentLicenses()
  150. //
  151. // Description:
  152. // return concurrent license from concurrent key pack
  153. //
  154. // Arguments:
  155. // See LSDBAllocateConcurrentLicense()
  156. //
  157. // Returns:
  158. // See LSDBAllocateConcurrentLicense()
  159. //
  160. //-------------------------------------------------------------------------
  161. DWORD
  162. TLSDBReturnConcurrentLicenses(
  163. IN PTLSDbWorkSpace pDbWkSpace,
  164. IN LPTSTR szHydraServer,
  165. IN PTLSDBLICENSEREQUEST pRequest,
  166. IN OUT long* dwQuantity
  167. )
  168. {
  169. //
  170. // return concurrent license works differently from normal return
  171. // need to find the concurrent keypack then find the license issued
  172. // to particular hydra server
  173. //
  174. DWORD dwStatus=ERROR_SUCCESS;
  175. if( pDbWkSpace == NULL ||
  176. pRequest == NULL ||
  177. pRequest == NULL ||
  178. dwQuantity == NULL ||
  179. szHydraServer == NULL )
  180. {
  181. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  182. return dwStatus;
  183. }
  184. LICENSEDCLIENT license_search;
  185. LICENSEDCLIENT license_found;
  186. TLSLICENSEPACK keypack_search;
  187. TLSLICENSEPACK keypack_found;
  188. keypack_search.pbDomainSid = NULL;
  189. keypack_found.pbDomainSid = NULL;
  190. DWORD dwNumLicenseToBeReturned = abs(*dwQuantity);
  191. SAFESTRCPY(
  192. license_search.szMachineName,
  193. szHydraServer
  194. );
  195. TLSDBLockKeyPackTable();
  196. dwStatus = TLSDBLicenseEnumBegin(
  197. pDbWkSpace,
  198. TRUE,
  199. LSLICENSE_SEARCH_MACHINENAME,
  200. &license_search
  201. );
  202. while(dwStatus == ERROR_SUCCESS && dwNumLicenseToBeReturned > 0)
  203. {
  204. // FreeTlsLicensePack(&keypack_found);
  205. dwStatus = TLSDBLicenseEnumNext(
  206. pDbWkSpace,
  207. &license_found
  208. );
  209. if(dwStatus != ERROR_SUCCESS)
  210. {
  211. break;
  212. }
  213. //
  214. if(license_found.ucLicenseStatus != LSLICENSE_STATUS_CONCURRENT)
  215. {
  216. continue;
  217. }
  218. //
  219. // Look into keypack table to see if this keypack has same product info
  220. //
  221. keypack_search.dwKeyPackId = license_found.dwKeyPackId;
  222. dwStatus = TLSDBKeyPackFind(
  223. pDbWkSpace,
  224. TRUE,
  225. LSKEYPACK_EXSEARCH_DWINTERNAL,
  226. &keypack_search,
  227. &keypack_found
  228. );
  229. if(dwStatus != ERROR_SUCCESS)
  230. {
  231. // TODO - log an error
  232. continue;
  233. }
  234. //if(keypack_found.ucAgreementType != LSKEYPACKTYPE_CONCURRENT)
  235. //{
  236. // TODO - log an error
  237. // continue;
  238. //}
  239. if( keypack_found.wMajorVersion != HIWORD(pRequest->dwProductVersion) ||
  240. keypack_found.wMinorVersion != LOWORD(pRequest->dwProductVersion) )
  241. {
  242. continue;
  243. }
  244. if( _tcsicmp(
  245. keypack_found.szCompanyName,
  246. (LPTSTR)pRequest->pszCompanyName) != 0)
  247. {
  248. continue;
  249. }
  250. if(_tcsicmp(
  251. keypack_found.szProductId,
  252. (LPTSTR)pRequest->pszProductId) != 0)
  253. {
  254. continue;
  255. }
  256. //
  257. // Return number of license back to keypack
  258. //
  259. //
  260. // NOTE - KeyPackFind() position the cursor on the record we need
  261. // to update
  262. keypack_found.dwNumberOfLicenses += license_found.dwNumLicenses;
  263. BOOL bSuccess;
  264. GetSystemTimeAsFileTime(&(keypack_found.ftLastModifyTime));
  265. bSuccess = pDbWkSpace->m_LicPackTable.UpdateRecord(
  266. keypack_found,
  267. LICENSEDPACK_ALLOCATE_LICENSE_UPDATE_FIELD
  268. );
  269. if(bSuccess == FALSE)
  270. {
  271. SetLastError(
  272. dwStatus = SET_JB_ERROR(pDbWkSpace->m_LicPackTable.GetLastJetError())
  273. );
  274. }
  275. else
  276. {
  277. // license table cursor is on the record we want to delete
  278. // need to delete this record
  279. bSuccess = pDbWkSpace->m_LicensedTable.DeleteRecord();
  280. if(bSuccess == FALSE)
  281. {
  282. SetLastError(
  283. dwStatus = SET_JB_ERROR(pDbWkSpace->m_LicensedTable.GetLastJetError())
  284. );
  285. }
  286. else
  287. {
  288. dwNumLicenseToBeReturned -= license_found.dwNumLicenses;
  289. }
  290. }
  291. }
  292. TLSDBLicenseEnumEnd(pDbWkSpace);
  293. *dwQuantity = abs(*dwQuantity) - dwNumLicenseToBeReturned;
  294. TLSDBUnlockKeyPackTable();
  295. return dwStatus;
  296. }
  297. //--------------------------------------------------------------------------
  298. // Function:
  299. // DBAllocateConcurrentLicense()
  300. //
  301. // Description:
  302. // Allocate concurrent license from concurrent key pack
  303. //
  304. // Arguments:
  305. // See LSDBAllocateConcurrentLicense()
  306. //
  307. // Returns:
  308. // See LSDBAllocateConcurrentLicense()
  309. //
  310. //-------------------------------------------------------------------------
  311. DWORD
  312. TLSDBGetConcurrentLicense(
  313. IN PTLSDbWorkSpace pDbWkSpace,
  314. IN LPTSTR szHydraServer,
  315. IN PTLSDBLICENSEREQUEST pRequest,
  316. IN OUT long* plQuantity
  317. )
  318. /*
  319. */
  320. {
  321. DWORD dwStatus = ERROR_SUCCESS;
  322. DWORD dwSearchedType = 0;
  323. DWORD dwSuggestType;
  324. DWORD dwPMAdjustedType = LSKEYPACKTYPE_UNKNOWN;
  325. DWORD dwLocakType = LSKEYPACKTYPE_UNKNOWN;
  326. if( pDbWkSpace == NULL ||
  327. pRequest == NULL ||
  328. pRequest == NULL ||
  329. plQuantity == NULL ||
  330. szHydraServer == NULL )
  331. {
  332. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  333. return dwStatus;
  334. }
  335. LONG lNumLicenseWanted = *plQuantity;
  336. TLSDBLicenseAllocation allocated;
  337. TLSDBAllocateRequest AllocateRequest;
  338. TLSLICENSEPACK LicenseKeyPack[10];
  339. memset(LicenseKeyPack, 0, sizeof(LicenseKeyPack));
  340. DWORD allocation_vector[10];
  341. //AllocateRequest.ucAgreementType = LSKEYPACKTYPE_CONCURRENT;
  342. AllocateRequest.szCompanyName = (LPTSTR)pRequest->pszCompanyName;
  343. AllocateRequest.szProductId = (LPTSTR)pRequest->pszProductId;
  344. AllocateRequest.dwVersion = pRequest->dwProductVersion;
  345. AllocateRequest.dwPlatformId = pRequest->dwPlatformID;
  346. AllocateRequest.dwLangId = pRequest->dwLanguageID;
  347. AllocateRequest.dwScheme = ALLOCATE_EXACT_VERSION;
  348. memset(&allocated, 0, sizeof(allocated));
  349. TLSDBLockKeyPackTable();
  350. TLSDBLockLicenseTable();
  351. do {
  352. dwSuggestType = dwLocakType;
  353. dwStatus = pRequest->pPolicy->PMLicenseRequest(
  354. pRequest->hClient,
  355. REQUEST_KEYPACKTYPE,
  356. UlongToPtr (dwSuggestType),
  357. (PVOID *)&dwPMAdjustedType
  358. );
  359. if(dwStatus != ERROR_SUCCESS)
  360. {
  361. break;
  362. }
  363. dwLocakType = (dwPMAdjustedType & ~LSKEYPACK_RESERVED_TYPE);
  364. if(dwLocakType > LSKEYPACKTYPE_LAST)
  365. {
  366. TLSLogEvent(
  367. EVENTLOG_ERROR_TYPE,
  368. TLS_E_POLICYERROR,
  369. dwStatus = TLS_E_POLICYMODULEERROR,
  370. pRequest->pPolicy->GetCompanyName(),
  371. pRequest->pPolicy->GetProductId()
  372. );
  373. break;
  374. }
  375. if(dwSearchedType & (0x1 << dwLocakType))
  376. {
  377. //
  378. // we already went thru this license pack, policy module error
  379. //
  380. TLSLogEvent(
  381. EVENTLOG_ERROR_TYPE,
  382. TLS_E_POLICYERROR,
  383. dwStatus = TLS_E_POLICYMODULERECURSIVE,
  384. pRequest->pPolicy->GetCompanyName(),
  385. pRequest->pPolicy->GetProductId()
  386. );
  387. break;
  388. }
  389. dwSearchedType |= (0x1 << dwLocakType);
  390. AllocateRequest.ucAgreementType = dwPMAdjustedType;
  391. while(lNumLicenseWanted > 0 && dwStatus == ERROR_SUCCESS)
  392. {
  393. AllocateRequest.dwNumLicenses = lNumLicenseWanted;
  394. for(int index=0; index < sizeof(LicenseKeyPack) / sizeof(LicenseKeyPack[0]); index++)
  395. {
  396. if(LicenseKeyPack[index].pbDomainSid != NULL)
  397. {
  398. // memory leak
  399. LicenseKeyPack[index].Cleanup();
  400. }
  401. }
  402. memset(allocation_vector, 0, sizeof(allocation_vector));
  403. memset(LicenseKeyPack, 0, sizeof(LicenseKeyPack));
  404. allocated.dwBufSize = sizeof(allocation_vector)/sizeof(allocation_vector[0]);
  405. allocated.pdwAllocationVector = allocation_vector;
  406. allocated.lpAllocateKeyPack = LicenseKeyPack;
  407. dwStatus = AllocateLicensesFromDB(
  408. pDbWkSpace,
  409. &AllocateRequest,
  410. TRUE, // fCheckAgreementType
  411. &allocated
  412. );
  413. if(dwStatus != ERROR_SUCCESS)
  414. {
  415. continue;
  416. }
  417. LICENSEDCLIENT issuedLicense;
  418. for(int i=0; i < allocated.dwBufSize; i++)
  419. {
  420. memset(&issuedLicense, 0, sizeof(issuedLicense));
  421. //
  422. // Update Licensed Table
  423. //
  424. issuedLicense.dwLicenseId = TLSDBGetNextLicenseId();
  425. issuedLicense.dwKeyPackId = LicenseKeyPack[i].dwKeyPackId;
  426. issuedLicense.dwNumLicenses = allocation_vector[i];
  427. issuedLicense.ftIssueDate = time(NULL);
  428. issuedLicense.ftExpireDate = INT_MAX;
  429. issuedLicense.ucLicenseStatus = LSLICENSE_STATUS_CONCURRENT;
  430. _tcscpy(issuedLicense.szMachineName, szHydraServer);
  431. _tcscpy(issuedLicense.szUserName, szHydraServer);
  432. // put license into license table
  433. dwStatus = TLSDBLicenseAdd(
  434. pDbWkSpace,
  435. &issuedLicense,
  436. 0,
  437. NULL
  438. );
  439. if(dwStatus != ERROR_SUCCESS)
  440. break;
  441. lNumLicenseWanted -= allocation_vector[i];
  442. }
  443. }
  444. } while(dwLocakType != LSKEYPACKTYPE_UNKNOWN && lNumLicenseWanted > 0);
  445. *plQuantity -= lNumLicenseWanted;
  446. TLSDBUnlockLicenseTable();
  447. TLSDBUnlockKeyPackTable();
  448. if(dwStatus != ERROR_SUCCESS)
  449. {
  450. if(lNumLicenseWanted == 0)
  451. {
  452. dwStatus = ERROR_SUCCESS;
  453. }
  454. else if(*plQuantity != 0)
  455. {
  456. dwStatus = TLS_I_NO_MORE_DATA;
  457. }
  458. }
  459. return dwStatus;
  460. }
  461. //+------------------------------------------------------------------------
  462. // Function:
  463. // LSDBAllocateConcurrentLicense()
  464. //
  465. // Description:
  466. // Allocate/Query/Return concurrent license from concurrent key pack
  467. //
  468. // Arguments:
  469. // IN sqlStmt - SQL statement to be used.
  470. // IN szHydraServer - server that request concurrent license
  471. // IN pRequest - requested product.
  472. // IN OUT dwQuantity - see Notes
  473. //
  474. // Return:
  475. // ERROR_SUCCESS
  476. // TLS_E_ODBC_ERROR
  477. //
  478. // Note:
  479. // dwQuantity INPUT RETURN
  480. // ------------------------------------- --------------------------------------
  481. // > 0 number of license requested Number of licenses successfully allocated
  482. // = 0 query number of license issued Number of licenses Issued to server
  483. // to server
  484. // < 0 number of license to be returned Number of licenses successfully returned
  485. //
  486. // Calling routine must check for return from dwQuantity.
  487. //------------------------------------------------------------------------------
  488. DWORD
  489. TLSDBAllocateConcurrentLicense(
  490. IN PTLSDbWorkSpace pDbWkSpace,
  491. IN LPTSTR szHydraServer,
  492. IN PTLSDBLICENSEREQUEST pRequest,
  493. IN OUT long* dwQuantity
  494. )
  495. /*
  496. */
  497. {
  498. DWORD status=ERROR_SUCCESS;
  499. if(*dwQuantity < 0)
  500. {
  501. // return licenses, on return, (positive number), number of license actually
  502. // returned.
  503. status = TLSDBReturnConcurrentLicenses(
  504. pDbWkSpace,
  505. szHydraServer,
  506. pRequest,
  507. dwQuantity
  508. );
  509. }
  510. else if(*dwQuantity == 0)
  511. {
  512. status = TLSDBQueryConcurrentLicenses(
  513. pDbWkSpace,
  514. szHydraServer,
  515. pRequest,
  516. dwQuantity
  517. );
  518. }
  519. else
  520. {
  521. status = TLSDBGetConcurrentLicense(
  522. pDbWkSpace,
  523. szHydraServer,
  524. pRequest,
  525. dwQuantity
  526. );
  527. }
  528. return status;
  529. }