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.

1230 lines
44 KiB

  1. /*++ BUILD Version: 0001 // Increment this if a change has global effects
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. lsapi.c
  5. Created:
  6. 20-Apr-1994
  7. Revision History:
  8. 01-Nov-1994 arth Changed from LS API set to simpler request only
  9. API.
  10. --*/
  11. #include <nt.h>
  12. #include <ntrtl.h>
  13. #include <nturtl.h>
  14. #include <windows.h>
  15. #include <ntlsapi.h>
  16. #include <llsconst.h>
  17. #include <debug.h>
  18. #include <stdlib.h>
  19. #include <lpcstub.h>
  20. // #define API_TRACE 1
  21. // #define TIME_TRACE 1
  22. // #define LOG_LICENSE_TRAFFIC
  23. #ifdef TIME_TRACE
  24. DWORD TimeDelta;
  25. #endif
  26. //
  27. // SID is linear in memory (check if this is safe assumption). Can use
  28. // RtlCopySID then pass linear buffer - use RtlLengthSid for size.
  29. //
  30. /*++
  31. NtLicenseRequest()
  32. Request licensing resources needed to allow software to be
  33. used.
  34. Format
  35. Status = NtLicenseRequest(
  36. [in] LS_STR *ProductName,
  37. [in] LS_STR *Version,
  38. [in] NT_LS_DATA *NtData)
  39. );
  40. Arguments
  41. ProductName The name of the product requesting licensing
  42. resources. This string may not be null and must
  43. be unique (in the first 32 characters) within the
  44. PublisherName domain.
  45. Version The version number of this product. This string
  46. must be unique (in the first 12 characters) within
  47. the ProductName domain, and cannot be NULL
  48. NtData The username and/or SID identifying the person using the
  49. license.
  50. NOTE: The arguments ProductName, and Version may not be
  51. NULL.
  52. Description
  53. This function is used by the application to request licensing
  54. resources to allow the identified product to execute. If a
  55. valid license is found, the challenge response is computed and
  56. LS_SUCCESS is returned.
  57. --*/
  58. LS_STATUS_CODE LS_API_ENTRY NtLicenseRequestA(
  59. LPSTR ProductName,
  60. LPSTR Version,
  61. LS_HANDLE FAR *LicenseHandle,
  62. NT_LS_DATA *NtData)
  63. {
  64. WCHAR uProductName[MAX_PRODUCT_NAME_LENGTH + 1];
  65. WCHAR uVersion[MAX_VERSION_LENGTH + 1];
  66. WCHAR uUserName[MAX_USER_NAME_LENGTH + 1];
  67. void *tmpData = NULL;
  68. LS_STATUS_CODE ret = LS_SUCCESS;
  69. #ifdef API_TRACE
  70. dprintf(TEXT("NtLicenseRequestA!!!\r\n"));
  71. #endif
  72. // Convert parms to Unicode and call Unicode function
  73. // First make sure we have correct data
  74. if ( (ProductName != NULL) && (Version != NULL) && (NtData != NULL) && (NtData->Data != NULL)) {
  75. if (lstrlenA(ProductName) > MAX_PRODUCT_NAME_LENGTH) {
  76. #ifdef API_TRACE
  77. dprintf(TEXT(" Error: ProductName too long\r\n"));
  78. #endif
  79. lstrcpy(uProductName, TEXT(""));
  80. } else
  81. MultiByteToWideChar(CP_ACP, 0, ProductName, -1, uProductName, MAX_PRODUCT_NAME_LENGTH + 1);
  82. if (lstrlenA(Version) > MAX_VERSION_LENGTH) {
  83. #ifdef API_TRACE
  84. dprintf(TEXT(" Error: Version too long\r\n"));
  85. #endif
  86. lstrcpy(uVersion, TEXT(""));
  87. } else
  88. MultiByteToWideChar(CP_ACP, 0, Version, -1, uVersion, MAX_VERSION_LENGTH + 1);
  89. if (NtData->DataType == NT_LS_USER_NAME) {
  90. if (lstrlenA((LPSTR) NtData->Data) > MAX_USER_NAME_LENGTH) {
  91. #ifdef API_TRACE
  92. dprintf(TEXT(" Error: UserName too long\r\n"));
  93. #endif
  94. lstrcpy(uUserName, TEXT(""));
  95. } else
  96. MultiByteToWideChar(CP_ACP, 0, NtData->Data, -1, uUserName, MAX_USER_NAME_LENGTH + 1);
  97. // Have UserName convert to wide char format, but need to point
  98. // Data structure to it...
  99. tmpData = (void *) NtData->Data;
  100. NtData->Data = (void *) uUserName;
  101. ret = NtLicenseRequestW(uProductName, uVersion, LicenseHandle, NtData);
  102. // Nothing needs to be converted back to ANSI on return, just return
  103. // data structure to the way it was
  104. NtData->Data = tmpData;
  105. return ret;
  106. } else {
  107. // Gave SID so no Unicode conversion needed on name
  108. ret = NtLicenseRequestW(uProductName, uVersion, LicenseHandle, NtData);
  109. return ret;
  110. }
  111. }
  112. #ifdef API_TRACE
  113. else
  114. dprintf(TEXT(" LLS Error: <NULL> Parms passed in!\r\n"));
  115. #endif
  116. // If NULL parms or such then just return a dummy handle for right now
  117. if ( LicenseHandle != NULL )
  118. *LicenseHandle = -1;
  119. return(LS_SUCCESS);
  120. } // NtLicenseRequestA
  121. LS_STATUS_CODE LS_API_ENTRY NtLicenseRequestW(
  122. LPWSTR ProductName,
  123. LPWSTR Version,
  124. LS_HANDLE FAR *LicenseHandle,
  125. NT_LS_DATA *NtData)
  126. {
  127. LPWSTR dVersion = Version;
  128. LS_STATUS_CODE Status;
  129. #ifdef API_TRACE
  130. UNICODE_STRING UString;
  131. NTSTATUS NtStatus;
  132. #endif
  133. //
  134. // Check parms before calling down
  135. //
  136. if ((ProductName == NULL) || (NtData == NULL) || (NtData->DataType > NT_LS_USER_SID)) {
  137. #ifdef API_TRACE
  138. dprintf(TEXT("NtLicenseRequestW: <Bad Parms>\r\n"));
  139. #endif
  140. if (LicenseHandle != NULL)
  141. *LicenseHandle = 0xFFFFFFFFL;
  142. return(LS_SUCCESS);
  143. }
  144. //
  145. // LsaLogonUser passes in NULL version because it doesn't know what version
  146. // the calling app is. So just use a blank field for this. There must
  147. // be something in the version field or it messes up the lower level
  148. // algorithms, so just enter a blank.
  149. //
  150. if ((Version == NULL) || (*Version == TEXT('\0')))
  151. dVersion = TEXT("");
  152. #ifdef API_TRACE
  153. if (NtData->DataType == NT_LS_USER_SID) {
  154. NtStatus = RtlConvertSidToUnicodeString(&UString, (PSID) NtData->Data, TRUE);
  155. if (NtStatus != STATUS_SUCCESS)
  156. dprintf(TEXT("NtLicenseRequestW RtlConvertSidToUnicodeString: 0x%lx\n"), NtStatus);
  157. else {
  158. if (NtData->IsAdmin)
  159. dprintf(TEXT("NtLicenseRequestW: %s, %s, <ADMIN>, SID: %s\n"), ProductName, dVersion, UString.Buffer);
  160. else
  161. dprintf(TEXT("NtLicenseRequestW: %s, %s, SID: %s\n"), ProductName, dVersion, UString.Buffer);
  162. RtlFreeUnicodeString(&UString);
  163. }
  164. } else {
  165. if (NtData->IsAdmin)
  166. dprintf(TEXT("NtLicenseRequestW: %s, %s, <ADMIN>, %s\n"), ProductName, dVersion, NtData->Data);
  167. else
  168. dprintf(TEXT("NtLicenseRequestW: %s, %s, %s\n"), ProductName, dVersion, NtData->Data);
  169. }
  170. #endif
  171. #ifdef TIME_TRACE
  172. TimeDelta = GetTickCount();
  173. #endif
  174. // make the LPC call and marshal the parms.
  175. Status = (LS_STATUS_CODE) LLSLicenseRequest2( ProductName,
  176. dVersion,
  177. NtData->DataType,
  178. (BOOLEAN) NtData->IsAdmin,
  179. NtData->Data,
  180. LicenseHandle
  181. );
  182. #ifdef TIME_TRACE
  183. TimeDelta = GetTickCount() - TimeDelta;
  184. dprintf(TEXT("NtLicenseRequest LPC Call Time: %ldms\n"), TimeDelta);
  185. #endif
  186. #ifdef LOG_LICENSE_TRAFFIC
  187. {
  188. HANDLE LogHandle;
  189. LPTSTR Strings[ 5 ];
  190. TCHAR szLicenseHandle[ 20 ];
  191. TCHAR szModuleName[ 1 + MAX_PATH ] = TEXT("<Unknown>");
  192. LogHandle = RegisterEventSourceW( NULL, TEXT("LicenseService") );
  193. if ( NULL != LogHandle )
  194. {
  195. wsprintf( szLicenseHandle, TEXT( "0x%08X" ), LicenseHandle );
  196. GetModuleFileName( NULL, szModuleName, sizeof( szModuleName ) / sizeof( *szModuleName ) );
  197. if ( NT_SUCCESS( Status ) )
  198. {
  199. Strings[ 0 ] = TEXT( "<License Request -- Accepted>" );
  200. }
  201. else
  202. {
  203. Strings[ 0 ] = TEXT( "<License Request -- * DENIED *>" );
  204. }
  205. Strings[ 1 ] = szModuleName;
  206. Strings[ 2 ] = ProductName;
  207. Strings[ 3 ] = dVersion;
  208. Strings[ 4 ] = ( NtData->DataType == NT_LS_USER_SID ) ? TEXT( "(SID)" ) : (LPTSTR) NtData->Data;
  209. Strings[ 5 ] = szLicenseHandle;
  210. ReportEvent( LogHandle,
  211. NT_SUCCESS( Status ) ? EVENTLOG_INFORMATION_TYPE : EVENTLOG_WARNING_TYPE,
  212. 0,
  213. NT_SUCCESS( Status ) ? 9999 : 9000,
  214. ( NtData->DataType == NT_LS_USER_SID ) ? (PSID) NtData->Data : NULL,
  215. 6,
  216. sizeof(DWORD),
  217. Strings,
  218. (PVOID) &Status );
  219. DeregisterEventSource(LogHandle);
  220. }
  221. }
  222. #endif // LOG_LICENSE_TRAFFIC
  223. return(Status);
  224. } // NtLicenseRequestW
  225. /*
  226. NtLSFreeHandle ( )
  227. Frees all licensing handle context.
  228. Format
  229. void NtLSFreeHandle ( [in] LS_HANDLE LicenseHandle);
  230. Arguments
  231. LicenseHandle Handle identifying the license context. This
  232. argument must be a handle that was created with
  233. NtLSRequest() or NtLicenseRequest().
  234. Description
  235. (NOTE: The handle is no longer valid.)
  236. */
  237. LS_STATUS_CODE LS_API_ENTRY NtLSFreeHandle(
  238. LS_HANDLE LicenseHandle )
  239. {
  240. #ifdef API_TRACE
  241. dprintf(TEXT("NtLSFreeHandle: %ld\r\n"), LicenseHandle);
  242. #endif
  243. #ifdef LOG_LICENSE_TRAFFIC
  244. {
  245. HANDLE LogHandle;
  246. LPTSTR Strings[ 5 ];
  247. TCHAR szLicenseHandle[ 20 ];
  248. TCHAR szModuleName[ 1 + MAX_PATH ] = TEXT("<Unknown>");
  249. LogHandle = RegisterEventSourceW( NULL, TEXT("LicenseService") );
  250. if ( NULL != LogHandle )
  251. {
  252. wsprintf( szLicenseHandle, TEXT( "0x%08X" ), LicenseHandle );
  253. GetModuleFileName( NULL, szModuleName, sizeof( szModuleName ) / sizeof( *szModuleName ) );
  254. Strings[ 0 ] = TEXT( "<License Free>" );
  255. Strings[ 1 ] = szModuleName;
  256. Strings[ 2 ] = szLicenseHandle;
  257. ReportEvent( LogHandle,
  258. EVENTLOG_INFORMATION_TYPE,
  259. 0,
  260. 10000,
  261. NULL,
  262. 3,
  263. 0,
  264. Strings,
  265. NULL );
  266. DeregisterEventSource(LogHandle);
  267. }
  268. }
  269. #endif // LOG_LICENSE_TRAFFIC
  270. //
  271. // If we get an invalid License Handle (or a dummy 0xFFFFFFFF one)
  272. // then don't even bother calling through LPC as it is a waste
  273. // of time.
  274. //
  275. if (LicenseHandle == 0xFFFFFFFFL)
  276. return( LS_SUCCESS );
  277. //
  278. // Make the LPC call
  279. //
  280. LLSLicenseFree2( LicenseHandle );
  281. return( LS_SUCCESS );
  282. } // NtLSFreeHandle
  283. #ifdef OBSOLETE
  284. // **************************************************************************
  285. // OLD API's Don't Use
  286. // **************************************************************************
  287. /*
  288. LSRequest()
  289. Request licensing resources needed to allow software to be
  290. used.
  291. Format
  292. Status = LSRequest( [in] LicenseSystem, [in] PublisherName,
  293. [in] ProductName,
  294. [in] Version, [in] TotUnitsReserved, [in]
  295. LogComment,
  296. [in/out] Challenge, [out] TotUnitsGranted, [out]
  297. hLicenseHandle );
  298. LS_STR * LicenseSystem;
  299. LS_STR * PublisherName;
  300. LS_STR * ProductName;
  301. LS_STR * Version;
  302. LS_ULONG TotUnitsReserved;
  303. LS_STR * LogComment;
  304. LS_CHALLENGE *Challenge;
  305. LS_ULONG * TotUnitsGranted;
  306. LS_HANDLE * hLicenseHandle;
  307. LS_STATUS_CODEStatus;
  308. Arguments
  309. LicenseSystem Pointer to a string which uniquely identifies
  310. the particular license system. This may be
  311. obtained through the LSEnumProviders() API.
  312. Normally, the constant LS_ANY is specified to
  313. indicate a match against all installed license
  314. systems (indicates that all license providers
  315. should be searched for a license match).
  316. PublisherName The name of the publisher (manufacturer) of
  317. this product. This string may not be null and
  318. must be unique in the first 32 characters. It is
  319. recommended that a company name and trademark be
  320. used.
  321. ProductName The name of the product requesting licensing
  322. resources. This string may not be null and must
  323. be unique (in the first 32 characters) within the
  324. PublisherName domain.
  325. Version The version number of this product. This string
  326. must be unique (in the first 12 characters) within
  327. the ProductName domain, and cannot be NULL
  328. NOTE: The arguments PublisherName, ProductName,
  329. and Version may not be NULL, or may not be
  330. LS_ANY.
  331. TotUnitsReserved Specifies the number of units required to run
  332. the application. The software publisher may
  333. choose to specify this policy attribute within the
  334. application. The recommended value of
  335. LS_DEFAULT_UNITS allows the licensing system to
  336. determine the proper value using information
  337. provided by the license system or license itself.
  338. The license system verifies that the requested
  339. number of units exist and may reserve those units,
  340. but no units are actually consumed at this time.
  341. The number of units available is returned in
  342. TotUnitsGranted.
  343. LogComment An optional string indicating a comment to be
  344. associated with the request and logged (if logging
  345. is enabled and supported) by the underlying
  346. licensing system. The underlying license system
  347. may choose to log the comment even if an error is
  348. returned (i.e., logged with the error), but this
  349. is not guaranteed. If a string is not specified,
  350. the value must be LS_NULL.
  351. Challenge Pointer to a challenge structure. The challenge
  352. response will also be returned in this structure.
  353. Refer to Challenge Mechanism on page 25 for more
  354. information.
  355. TotUnitsGrantedA pointer to an LS_ULONG in which the total
  356. number of units granted is returned. The following
  357. table describes the TotUnitsGranted return value,
  358. given the TotUnitsReserved input value, and the
  359. Status returned:
  360. LS_INSUFFICIENT_U
  361. TotUnitsReserv LS_SUCCES NITS Other
  362. ed S errors
  363. LS_DEFAULT_UNI (A) (B) (E)
  364. TS
  365. Other (C) (D) (E)
  366. (specific
  367. count)
  368. (A) The default umber of units commensurate
  369. with the license granted.(B) The maximum
  370. number of units available to the requesting
  371. software. This may be less than the normal
  372. default.
  373. (C) The number of units used to grant the
  374. request. Note that this value may be greater
  375. than or equal to the actual units requested
  376. (i.e., the policy may allow only in increments
  377. of 5 units, thus a request of 7 units would
  378. result in 10 units being granted).
  379. (D) The maximum number of units available to
  380. the requesting software. This may be more or
  381. less than the units requested.
  382. (E) Zero is returned.
  383. LicenseHandle Pointer to a LS_HANDLE in which a handle to the
  384. license context is to be returned.
  385. Status Detailed error code that can be directly processed
  386. by the caller, or that can be converted into a
  387. localized message string by the LSGetMessage()
  388. function.
  389. Description
  390. This function is used by the application to request licensing
  391. resources to allow the identified product to execute. If a
  392. valid license is found, the challenge response is computed and
  393. LS_SUCCESS is returned. At minimum, the PublisherName,
  394. ProductName, and Version strings are used to identify matching
  395. license(s). Note that an underlying license system service
  396. provider may ascertain additional information for the license
  397. request (e.g., the current username, machine name, etc.).
  398. A valid license handle is always returned by this function
  399. whether valid license resources are granted or not. This
  400. handle must always be released with LSFreeHandle() when the
  401. application has completed execution.
  402. If license resources were granted, it must call LSRelease() to
  403. free the license resource, prior to calling LSFreeHandle().
  404. A challenge response is NOT returned unless the license
  405. request completed successfully (i.e., a status code of
  406. LS_SUCCESS is returned).
  407. If the number of units requested is greater than the number of
  408. units available, then the license request is not granted. Upon
  409. successful completion, the value returned in TotUnitsReserved
  410. indicates the number of units granted. This is greater than or
  411. equal to the number of units requested unless LS_DEFAULT_UNITS
  412. was specified. In the case of failure, the value returned in
  413. TotUnitsGranted is zero.
  414. */
  415. LS_STATUS_CODE LS_API_ENTRY NtLSRequest(
  416. LS_STR FAR *LicenseSystem,
  417. LS_STR FAR *PublisherName,
  418. LS_STR FAR *ProductName,
  419. LS_STR FAR *Version,
  420. LS_ULONG TotUnitsReserved,
  421. LS_STR FAR *LogComment,
  422. LS_CHALLENGE FAR *Challenge,
  423. LS_ULONG FAR *TotUnitsGranted,
  424. LS_HANDLE FAR *LicenseHandle,
  425. NT_LS_DATA FAR *NtData)
  426. {
  427. NT_LS_DATA tmpNtData;
  428. WCHAR uProductName[MAX_PRODUCT_NAME_LENGTH + 1];
  429. WCHAR uVersion[MAX_VERSION_LENGTH + 1];
  430. WCHAR uUserName[MAX_USER_NAME_LENGTH + 1];
  431. LS_STATUS_CODE ret = LS_SUCCESS;
  432. #ifdef API_TRACE
  433. dprintf(TEXT("NtLSRequest:\r\n"));
  434. if (ProductName == NULL)
  435. dprintf(TEXT(" Product Name: <NULL>\r\n"));
  436. if (Version == NULL)
  437. dprintf(TEXT(" Version: <NULL>\r\n"));
  438. if (LicenseHandle == NULL)
  439. dprintf(TEXT(" LicenseHandle: <NULL>\r\n"));
  440. if (NtData != NULL) {
  441. if (NtData->Data == NULL)
  442. dprintf(TEXT(" NtData->Data: <NULL>\r\n"));
  443. } else
  444. dprintf(TEXT("NtData: <NULL>\r\n"));
  445. dprintf(TEXT("\r\n"));
  446. #endif
  447. // Do some fudging to follow old API spec...
  448. if ( TotUnitsGranted != NULL )
  449. *TotUnitsGranted = TotUnitsReserved;
  450. // Need to do a couple things:
  451. // 1. Convert used parms to Unicode
  452. // 2. Set up new NtData structure (extra IsAdmin field)
  453. // 3. Make call to new NtLicenseRequest API and use it's return code.
  454. //
  455. // Note: No conversion back to ANSI needed upon return from API
  456. //
  457. // First make sure we have correct data
  458. if ( (ProductName != NULL) && (Version != NULL) && (NtData != NULL) && (NtData->Data != NULL)) {
  459. // 1. Convert parms to Unicode
  460. if (lstrlenA(ProductName) > MAX_PRODUCT_NAME_LENGTH) {
  461. #ifdef API_TRACE
  462. dprintf(TEXT(" Error: ProductName too long\r\n"));
  463. #endif
  464. MultiByteToWideChar(CP_ACP, 0, ProductName, MAX_PRODUCT_NAME_LENGTH, uProductName, MAX_PRODUCT_NAME_LENGTH + 1);
  465. uProductName[MAX_PRODUCT_NAME_LENGTH] = TEXT('\0');
  466. } else
  467. MultiByteToWideChar(CP_ACP, 0, ProductName, -1, uProductName, MAX_PRODUCT_NAME_LENGTH + 1);
  468. if (lstrlenA(Version) > MAX_VERSION_LENGTH) {
  469. #ifdef API_TRACE
  470. dprintf(TEXT(" Error: Version too long\r\n"));
  471. #endif
  472. MultiByteToWideChar(CP_ACP, 0, Version, MAX_VERSION_LENGTH, uVersion, MAX_VERSION_LENGTH + 1);
  473. uVersion[MAX_VERSION_LENGTH] = TEXT('\0');
  474. } else
  475. MultiByteToWideChar(CP_ACP, 0, Version, -1, uVersion, MAX_VERSION_LENGTH + 1);
  476. // 2. Set up new NtData structure
  477. tmpNtData.DataType = NtData->DataType;
  478. // just use FALSE for IsAdmin as none of the old Apps need it.
  479. tmpNtData.IsAdmin = FALSE;
  480. if (NtData->DataType == NT_LS_USER_NAME) {
  481. if (lstrlenA((LPSTR) NtData->Data) > MAX_USER_NAME_LENGTH) {
  482. #ifdef API_TRACE
  483. dprintf(TEXT(" Error: UserName too long\r\n"));
  484. #endif
  485. MultiByteToWideChar(CP_ACP, 0, NtData->Data, MAX_USER_NAME_LENGTH, uUserName, MAX_USER_NAME_LENGTH + 1);
  486. uUserName[MAX_USER_NAME_LENGTH] = TEXT('\0');
  487. } else {
  488. MultiByteToWideChar(CP_ACP, 0, NtData->Data, -1, uUserName, MAX_USER_NAME_LENGTH + 1);
  489. }
  490. tmpNtData.Data = (void *) uUserName;
  491. // Have UserName convert to wide char format, but need to point
  492. // Data structure to it...
  493. ret = NtLicenseRequestW(uProductName, uVersion, LicenseHandle, &tmpNtData);
  494. // Nothing needs to be converted back to ANSI on return, just return
  495. return ret;
  496. } else {
  497. // Gave SID so no Unicode convesion needed on name
  498. tmpNtData.Data = NtData->Data;
  499. ret = NtLicenseRequestW(uProductName, uVersion, LicenseHandle, &tmpNtData);
  500. return ret;
  501. }
  502. }
  503. // If NULL parms or such then just return a dummy handle for right now
  504. if ( LicenseHandle != NULL )
  505. *LicenseHandle = 0xffffffffL;
  506. return(LS_SUCCESS);
  507. } // NtLSRequest
  508. /*
  509. LSRelease()
  510. Release licensing resources associated with the specified
  511. context.
  512. Format
  513. Status = LSRelease( [in] LicenseHandle, [in] TotUnitsConsumed,
  514. [in] LogComment );
  515. LS_HANDLE LicenseHandle;
  516. LS_ULONG TotUnitsConsumed;
  517. LS_STR * LogComment;
  518. LS_STATUS_CODEStatus;
  519. Arguments
  520. LicenseHandle Handle identifying the license context. This
  521. argument must be a handle that was created with
  522. LSRequest().
  523. TotUnitsConsumedThe TOTAL number of units consumed in this
  524. handle context since the initial LSRequest() call.
  525. The software publisher may choose to specify this
  526. policy attribute within the application. A value
  527. of LS_DEFAULT_UNITS indicates that the licensing
  528. system should determine the appropriate value
  529. using its own licensing policy mechanisms.
  530. LogComment An optional string indicating a comment to be
  531. associated with the request and logged (if logging
  532. is enabled and supported) by the underlying
  533. licensing system. The underlying license system
  534. may choose to log the comment even if an error is
  535. returned (i.e., logged with the error), but this
  536. is not guaranteed. If a string is not specified,
  537. the value must be LS_NULL.
  538. Status Detailed error code that can be directly processed
  539. by the caller, or that can be converted into a
  540. localized message string by the LSGetMessage()
  541. function.
  542. Description
  543. This function is used to release licensing resources
  544. associated with the license context identified by
  545. LicenseHandle. If a consumptive style licensing policy is in
  546. effect, and if the software publisher chooses to implement
  547. such license policy in the application, then the license units
  548. to be consumed may be passed as part of this call.
  549. NOTE: The license handle context is NOT freed. See
  550. LSFreeHandle().
  551. */
  552. LS_STATUS_CODE LS_API_ENTRY NtLSRelease(
  553. LS_HANDLE LicenseHandle,
  554. LS_ULONG TotUnitsConsumed,
  555. LS_STR FAR *LogComment)
  556. {
  557. return(LS_SUCCESS);
  558. }
  559. /*
  560. LSUpdate()
  561. Update the synchronization between licensed software and the
  562. licensing system.
  563. Format
  564. Status = LSUpdate( [in] LicenseHandle, [in] TotUnitsConsumed,
  565. [in] TotUnitsReserved,
  566. [in] LogComment, [in/out] Challenge, [out]
  567. TotUnitsGranted );
  568. LS_HANDLE LicenseHandle;
  569. LS_ULONG TotUnitsConsumed;
  570. LS_ULONG TotUnitsReserved;
  571. LS_STR * LogComment;
  572. LS_CHALLENGE *Challenge;
  573. LS_ULONG * TotUnitsGranted;
  574. LS_STATUS_CODEStatus;
  575. Arguments
  576. LicenseHandle Handle identifying the license context. This
  577. argument must be a handle that was created with
  578. LSRequest().
  579. TotUnitsConsumedThe TOTAL number of units consumed so far in
  580. this handle context. The software publisher may
  581. choose to specify this policy attribute within the
  582. application. A value of LS_DEFAULT_UNITS
  583. indicates that the licensing system should
  584. determine the appropriate value using its own
  585. licensing policy mechanisms. If an error is
  586. returned, then no units are consumed.
  587. TotUnitsReserved Specifies the total number of units to be
  588. reserved. If no additional units are required
  589. since the initial LSRequest() or last LSUpdate(),
  590. then this parameter should be the current total
  591. (as returned in TotUnitsGranted). The total
  592. reserved is inclusive of units consumed. That is,
  593. if an application requests 100 units be reserved,
  594. then consumes 20 units, there are still 100 units
  595. reserved (but only 80 available for consumption).
  596. If additional units are required, the application
  597. must calculate a new total for TotUnitsReserved.
  598. LS_DEFAULT_UNITS may be specified, but this will
  599. not allocate any additional units.
  600. The license system verifies that the requested
  601. number of units exist and may reserve those units,
  602. but these units are not consumed at this time.
  603. This value may be smaller than the original
  604. request to indicate that fewer units are needed
  605. than originally anticipated.
  606. LogComment An optional string indicating a comment to be
  607. associated with the request and logged (if logging
  608. is enabled and supported) by the underlying
  609. licensing system. The underlying license system
  610. may choose to log the comment even if an error is
  611. returned (i.e., logged with the error), but this
  612. is not guaranteed. If a string is not specified,
  613. the value must be LS_NULL.
  614. Challenge Pointer to a challenge structure. The challenge
  615. response will also be returned in this structure.
  616. Refer to Challenge Mechanism on page 25 for more
  617. information.
  618. TotUnitsGrantedA pointer to an LS_ULONG in which the total
  619. number of units granted since the initial license
  620. request is returned. The following table describes
  621. the TotUnitsGranted return value, given the
  622. TotUnitsReserved input value, and the Status
  623. returned:
  624. LS_INSUFFICIENT_U
  625. TotUnitsReserv LS_SUCCES NITS Other
  626. ed S errors
  627. LS_DEFAULT_UNI (A) (B) (E)
  628. TS
  629. Other (C) (D) (E)
  630. (specific
  631. count)
  632. (A) The default umber of units commensurate
  633. with the license granted. (B) The maximum
  634. number of units available to the requesting
  635. software. This may be less than the normal
  636. default.
  637. (C) The number of units used to grant the
  638. request. Note that this value may differ from
  639. the actual units requested (i.e., the policy
  640. may allow only in increments of 5 units, thus a
  641. request of 7 units would result in 10 units
  642. being granted).
  643. (D) The maximum number of units available to
  644. the requesting software. This may be more or
  645. less than the units requested.
  646. (E) Zero is returned.
  647. Status Detailed error code that can be directly processed
  648. by the caller, or that can be converted into a
  649. localized message string by the LSGetMessage()
  650. function.
  651. Description
  652. The client application periodically issues this call to re-
  653. verify that the current license is still valid. The LSQuery()
  654. API may be used to determine the proper interval for the
  655. current licensing context. A guideline of once an hour may be
  656. appropriate, with a minimum interval of 15 minutes. Consult
  657. your licensing system vendor for more information.
  658. If the number of new units requested (in TotUnitsReserved) is
  659. greater than the number available, then the update request
  660. fails with an LS_INSUFFICIENT_UNITS error. Upon successful
  661. completion, the value returned in TotUnitsGranted indicates
  662. the current total of units granted.
  663. If the TotUnitsConsumed exceeds the number of units reserved,
  664. then the error LS_INSUFFICIENT_UNITS is returned. The
  665. remaining units are consumed.
  666. A challenge response is NOT returned if an error is returned.
  667. The LSUpdate() call verifies that the licensing system context
  668. has not changed from that expected by the licensed software.
  669. In this way the LSUpdate() call can:
  670. 1.Determine if the licensing system can verify that the
  671. licensing resources granted to the specified handle are
  672. still reserved for this application by the licensing system.
  673. Note that in distributed license system, an error here might
  674. indicate a temporary network interruption, among other
  675. things.
  676. 2.Determine when the licensing system has released the
  677. licensing resources that had been granted to the specified
  678. handle, indicating the software requiring that grant no
  679. longer has authorization to execute normally.
  680. Application Software should be prepared to handle vendor
  681. specific error conditions, should they arise. However, a best
  682. effort will be used by license systems to map error conditions
  683. to the common error set.
  684. The LSUpdate() call may indicate if that the current licensing
  685. context has expired (for example, in the case of a time-
  686. restricted license policy). In such a case, the warning status
  687. LS_LICENSE_EXPIRED is returned. If any error is returned, a
  688. call to LSRelease() is still required.
  689. */
  690. LS_STATUS_CODE LS_API_ENTRY NtLSUpdate(
  691. LS_HANDLE LicenseHandle,
  692. LS_ULONG TotUnitsConsumed,
  693. LS_ULONG TotUnitsReserved,
  694. LS_STR FAR *LogComment,
  695. LS_CHALLENGE FAR *Challenge,
  696. LS_ULONG FAR *TotUnitsGranted)
  697. {
  698. // set the return buffer to NULL
  699. if ( TotUnitsGranted != NULL )
  700. *TotUnitsGranted = TotUnitsReserved;
  701. return(LS_SUCCESS);
  702. }
  703. /*
  704. LSGetMessage()
  705. Return the message associated with a License Service API
  706. status code.
  707. Format
  708. Status = LSGetMessage( [in] LicenseHandle, [in] Value, [out]
  709. Buffer, [in] BufferSize );
  710. LS_HANDLE LicenseHandle;
  711. LS_STATUS_CODEValue;
  712. LS_STR * Buffer;
  713. LS_ULONG BufferSize;
  714. LS_STATUS_CODEStatus;
  715. Arguments
  716. LicenseHandle Handle identifying the license context. This
  717. argument must be a handle that was created with
  718. LSRequest().
  719. Value Any status code returned by a License Service API
  720. function.
  721. Buffer Pointer to a buffer in which a localized error
  722. message string is to be placed.
  723. BufferSize Maximum size of the string that may be returned in
  724. Buffer.
  725. Status Resulting status of LSGetMessage() call.
  726. Description
  727. For a given error, this function returns an error code and a string
  728. describing the error, and a suggested action to be taken in
  729. response to the specific error. If the value of Value is
  730. LS_USE_LAST, then the last error associated with the supplied
  731. licensing handle, and its associated data, is returned. Otherwise,
  732. the supplied error code is used.
  733. Possible status codes returned by LSGetMessage() include:
  734. LS_SUCCESS, LS_NO_MSG_TEXT, LS_UNKNOWN_STATUS, and
  735. LS_BUFFER_TOO_SMALL.
  736. */
  737. LS_STATUS_CODE LS_API_ENTRY NtLSGetMessage(
  738. LS_HANDLE LicenseHandle,
  739. LS_STATUS_CODE Value,
  740. LS_STR FAR *Buffer,
  741. LS_ULONG BufferSize)
  742. {
  743. return(LS_TEXT_UNAVAILABLE);
  744. }
  745. /*
  746. LSQuery()
  747. Return information about the license system context associated
  748. with the specified handle.
  749. Format
  750. Status = LSQuery( [in] LicenseHandle, [in] Information, [out]
  751. InfoBuffer, [in] BufferSize,
  752. [out] ActualBufferSize);
  753. LS_HANDLE LicenseHandle;
  754. LS_ULONG Information;
  755. LS_VOID * InfoBuffer;
  756. LS_ULONG BufferSize;
  757. LS_ULONG * ActualBufferSize;
  758. LS_STATUS_CODEStatus;
  759. Arguments
  760. LicenseHandle Handle identifying the license context. This
  761. argument must be a handle that was created with
  762. LSRequest().
  763. Information Index which identifies the information to be
  764. returned.
  765. InfoBuffer Points to a buffer in which the resulting
  766. information is to be placed.
  767. BufferSize Maximum size of the buffer pointed to by
  768. InfoBuffer.
  769. ActualBufferSize On entry, points to a LS_ULONG whose value on
  770. exit indicates the actual count of characters
  771. returned in the buffer (not including the trailing
  772. NULL byte).
  773. Status Detailed error code that can be directly processed
  774. by the caller, or which can be converted into a
  775. localized message string by the LSGetMessage
  776. function.
  777. Description
  778. This function is used to obtain information about the license
  779. obtained from the LSRequest() call. For example, an application may
  780. determine the license type (demo, concurrent, personal, etc.); time
  781. restrictions; etc.
  782. The buffer should be large enough to accommodate the expected data.
  783. If the buffer is too small, then the status code
  784. LS_BUFFER_TOO_SMALL is returned and only BufferSize bytes of data
  785. are returned.
  786. The following Information constants are defined:
  787. Information Valu Meaning
  788. Constant e
  789. LS_INFO_NONE 0 Reserved.
  790. LS_INFO_SYSTEM 1 Return the unique identification
  791. of the license system supplying
  792. the current license context.
  793. This is returned as a null-
  794. terminated string.
  795. This value is the same as an
  796. appropriate call to
  797. LSEnumProviders() provides.
  798. LS_INFO_DATA 2 Return the block of
  799. miscellaneous application data
  800. contained on the license. This
  801. data is completely vendor-
  802. defined. The amount of space
  803. allocated for such data will
  804. vary from license system to
  805. license system, or may not be
  806. available at all.
  807. The first ULONG in the data
  808. buffer indicates the size (in
  809. bytes) of the actual data which
  810. follows:
  811. +------------------------------
  812. --+
  813. | ULONG
  814. |
  815. | (count of bytes that follow)
  816. |
  817. +------------------------------
  818. --+
  819. | Vendor data bytes from license
  820. |
  821. |
  822. |
  823. +------------------------------
  824. --+
  825. LS_UPDATE_PERIO 3 Return the recommended interval
  826. D (in minutes) at which LSUpdate()
  827. should be called.
  828. +------------------------------
  829. --+
  830. | ULONG
  831. |
  832. | Recommended Interval
  833. |
  834. | (in minutes)
  835. |
  836. +------------------------------
  837. --+
  838. | ULONG
  839. |
  840. | Recommended Minutes until
  841. |
  842. | next LSUpdate()call
  843. |
  844. +------------------------------
  845. --+
  846. If a value of 0xFFFFFFFF is
  847. returned for the recommended
  848. interval, then no recommendation
  849. is being made.
  850. LS_LICENSE_CONT 4 Return a value which uniquely
  851. EXT identifies the licensing context
  852. within the specific license
  853. service provider identified by
  854. the LicenseHandle.
  855. +------------------------------
  856. --+
  857. | ULONG
  858. |
  859. | Count of Bytes that follow
  860. |
  861. +------------------------------
  862. --+
  863. | BYTES
  864. |
  865. ...
  866. |
  867. |
  868. +------------------------------
  869. --+
  870. The contents of the bytes
  871. returned is license system
  872. specific. In circumstances where
  873. license system specific
  874. functionality is being used,
  875. this sequence of bytes may be
  876. used to identify the current
  877. license context.
  878. */
  879. LS_STATUS_CODE LS_API_ENTRY NtLSQuery(
  880. LS_HANDLE LicenseHandle,
  881. LS_ULONG Information,
  882. LS_VOID FAR *InfoBuffer,
  883. LS_ULONG BufferSize,
  884. LS_ULONG FAR *ActualBufferSize)
  885. {
  886. switch ( Information )
  887. {
  888. case LS_INFO_DATA:
  889. case LS_LICENSE_CONTEXT:
  890. // set the return buffer to NULL
  891. if ( InfoBuffer != NULL )
  892. *((LS_ULONG *)InfoBuffer) = 0;
  893. if ( ActualBufferSize != NULL )
  894. *ActualBufferSize = sizeof( LS_ULONG );
  895. break;
  896. case LS_UPDATE_PERIOD:
  897. if (( InfoBuffer != NULL ) && ( BufferSize >= sizeof(LS_ULONG)*2 ))
  898. {
  899. // set the return balue to no recommendation
  900. LS_ULONG * uLong = (LS_ULONG*)InfoBuffer;
  901. *uLong = 0xffffffff;
  902. uLong++;
  903. *uLong = 0xffffffff;
  904. *ActualBufferSize = sizeof(LS_ULONG) * 2;
  905. }
  906. break;
  907. case LS_INFO_NONE:
  908. case LS_INFO_SYSTEM:
  909. default:
  910. // set return buffer to NULL
  911. if ( InfoBuffer != NULL )
  912. strcpy( InfoBuffer, (LS_STR*)"");
  913. if ( ActualBufferSize != NULL )
  914. *ActualBufferSize = 0;
  915. break;
  916. }
  917. return(LS_SUCCESS);
  918. }
  919. /*
  920. LSEnumProviders()
  921. This call is used to enumerate the installed license system
  922. service providers.
  923. Format
  924. Status = LSEnumProviders( [in] Index, [out] Buffer);
  925. LS_ULONG Index
  926. LS_STR * Buffer
  927. LS_STATUS_CODEStatus;
  928. Arguments
  929. Index Index of the service provider. The first provider
  930. has an index of zero, the second has an index of
  931. one, etc. This index should be incremented by the
  932. caller for each successive call to
  933. LSEnumProviders() until the status LS_BAD_INDEX is
  934. returned.
  935. Buffer Points to a buffer in which the unique null-
  936. terminated string identifying the license system
  937. service provider is to be placed. The buffer
  938. pointed to by Buffer must be at least 255 bytes
  939. long. The value of LS_ANY indicates that the
  940. current index is not in use, but is not the last
  941. index to obtain.
  942. Status Detailed error code that can be directly processed
  943. by the caller, or which can be converted into a
  944. localized message string by the LSGetMessage()
  945. function.
  946. Description
  947. For each installed provider, a unique string is returned. The
  948. unique null-terminated string typically identifies the vendor,
  949. product, and version of the license system. This value is the same
  950. as an appropriate call to LSQuery(). An Error of LS_BAD_INDEX is
  951. returned when the value of Index is higher than the number of
  952. providers currently installed. In a networked environment, the
  953. version returned is that of the client, not the server.
  954. An application may enumerate the installed license system service
  955. providers by calling LSEnumProviders() successively. The Index is
  956. passed in and should be incremented by the caller for each call
  957. until the status LS_BAD_INDEX is returned.
  958. */
  959. LS_STATUS_CODE LS_API_ENTRY NtLSEnumProviders(
  960. LS_ULONG Index,
  961. LS_STR FAR *Buffer)
  962. {
  963. // set return buffer to NULL
  964. if ( Buffer != NULL )
  965. strcpy( Buffer, (LS_STR*)"" );
  966. return(LS_SUCCESS);
  967. }
  968. #endif // OBSOLETE