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.

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