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.

936 lines
22 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996-1998
  5. //
  6. // File: timebomb.cpp
  7. //
  8. // Contents: Implement licensing timebomb-related APIs
  9. //
  10. // History: 08-12-98 FredCh Created
  11. //
  12. //-----------------------------------------------------------------------------
  13. #include "precomp.h"
  14. #include "tlsapip.h"
  15. #include "time.h"
  16. extern "C" {
  17. //-----------------------------------------------------------------------------
  18. //
  19. // The LSA secret name used to store the licensing timebomb expiration
  20. //
  21. //-----------------------------------------------------------------------------
  22. #define LICENSING_TIME_BOMB_5_0 L"TIMEBOMB_832cc540-3244-11d2-b416-00c04fa30cc4"
  23. #define RTMLICENSING_TIME_BOMB_5_0 L"RTMTSTB_832cc540-3244-11d2-b416-00c04fa30cc4"
  24. #define BETA2_LICENSING_TIME_BOMB_5_1 L"BETA2TIMEBOMB_1320153D-8DA3-4e8e-B27B-0D888223A588"
  25. // L$ means only readable from the local machine
  26. #define BETA_LICENSING_TIME_BOMB_5_1 L"L$BETA3TIMEBOMB_1320153D-8DA3-4e8e-B27B-0D888223A588"
  27. #define RTM_LICENSING_TIME_BOMB_5_1 L"L$RTMTIMEBOMB_1320153D-8DA3-4e8e-B27B-0D888223A588"
  28. #define BETA_LICENSING_TIME_BOMB_LATEST_VERSION BETA_LICENSING_TIME_BOMB_5_1
  29. #define RTM_LICENSING_TIME_BOMB_LATEST_VERSION RTM_LICENSING_TIME_BOMB_5_1
  30. #define HS_PARAM_GRACE_PERIOD_ENDED L"LicensingGracePeriodEnded"
  31. //-----------------------------------------------------------------------------
  32. //
  33. // The global licensing time bomb value.
  34. //
  35. //-----------------------------------------------------------------------------
  36. FILETIME g_LicenseTimeBomb;
  37. //-----------------------------------------------------------------------------
  38. //
  39. // The number of licensing grace period is 90 days. By default, we start
  40. // logging events when there are less than 15 days from expiration and the
  41. // terminal server has not registered itself with a license server.
  42. //
  43. //-----------------------------------------------------------------------------
  44. #define GRACE_PERIOD 120
  45. #define GRACE_PERIOD_EXPIRATION_WARNING_DAYS 15
  46. //-----------------------------------------------------------------------------
  47. //
  48. // Only log the grace period warning or error once a day.
  49. //
  50. //-----------------------------------------------------------------------------
  51. #define GRACE_PERIOD_EVENT_LOG_INTERVAL (1000*60*60*24)
  52. //-----------------------------------------------------------------------------
  53. //
  54. // Thread used to warn administrator when grace period is about to expire
  55. //
  56. //-----------------------------------------------------------------------------
  57. HANDLE g_GracePeriodThreadExitEvent = NULL;
  58. CRITICAL_SECTION g_EventCritSec;
  59. //-----------------------------------------------------------------------------
  60. //
  61. // Internal functions
  62. //
  63. //-----------------------------------------------------------------------------
  64. BOOL
  65. CalculateTimeBombExpiration(
  66. FILETIME * pExpiration );
  67. DWORD
  68. GetExpirationWarningDays();
  69. BOOL
  70. IsLicensingTimeBombExpired();
  71. /*++
  72. Function:
  73. InitializeLicensingTimeBomb
  74. Description:
  75. Initialize the licensing time bomb value.
  76. Argument:
  77. None.
  78. Return:
  79. A LICENSE_STATUS return code.
  80. --*/
  81. LICENSE_STATUS
  82. InitializeLicensingTimeBomb()
  83. {
  84. LICENSE_STATUS
  85. Status;
  86. DWORD
  87. cbTimeBomb = sizeof( FILETIME );
  88. NTSTATUS
  89. NtStatus;
  90. NtStatus = RtlInitializeCriticalSection(&g_EventCritSec);
  91. if (STATUS_SUCCESS != NtStatus)
  92. {
  93. return LICENSE_STATUS_INITIALIZATION_FAILED;
  94. }
  95. Status = LsCsp_RetrieveSecret(
  96. (TLSIsBetaNTServer()) ? BETA_LICENSING_TIME_BOMB_LATEST_VERSION : RTM_LICENSING_TIME_BOMB_LATEST_VERSION,
  97. ( LPBYTE )&g_LicenseTimeBomb,
  98. &cbTimeBomb );
  99. if( LICENSE_STATUS_OK == Status && cbTimeBomb == sizeof(g_LicenseTimeBomb) )
  100. {
  101. return( LICENSE_STATUS_OK );
  102. }
  103. //
  104. // Calculate and set the timebomb
  105. //
  106. if( FALSE == CalculateTimeBombExpiration( &g_LicenseTimeBomb ) )
  107. {
  108. #if DBG
  109. DbgPrint( "CalculateTimeBombExpiration: cannot calculate licensing time bomb expiration.\n" );
  110. #endif
  111. return( LICENSE_STATUS_INITIALIZATION_FAILED );
  112. }
  113. Status = LsCsp_StoreSecret(
  114. (TLSIsBetaNTServer()) ? BETA_LICENSING_TIME_BOMB_LATEST_VERSION : RTM_LICENSING_TIME_BOMB_LATEST_VERSION,
  115. ( LPBYTE )&g_LicenseTimeBomb,
  116. sizeof( g_LicenseTimeBomb ) );
  117. return( Status );
  118. }
  119. /*++
  120. Function:
  121. IsLicensingTimeBombExpired
  122. Description:
  123. Check if the licensing time bomb has expired.
  124. Argument:
  125. None.
  126. Return:
  127. TRUE if the timebomb has expired or FALSE otherwise.
  128. --*/
  129. BOOL
  130. IsLicensingTimeBombExpired()
  131. {
  132. SYSTEMTIME
  133. SysTimeNow;
  134. FILETIME
  135. FileTimeNow,
  136. FileTimeExpiration;
  137. GetSystemTime( &SysTimeNow );
  138. SystemTimeToFileTime( &SysTimeNow, &FileTimeNow );
  139. RtlEnterCriticalSection(&g_EventCritSec);
  140. FileTimeExpiration.dwLowDateTime = g_LicenseTimeBomb.dwLowDateTime;
  141. FileTimeExpiration.dwHighDateTime = g_LicenseTimeBomb.dwHighDateTime;
  142. RtlLeaveCriticalSection(&g_EventCritSec);
  143. if( 0 > CompareFileTime( &FileTimeExpiration, &FileTimeNow ) )
  144. {
  145. return( TRUE );
  146. }
  147. return( FALSE );
  148. }
  149. /*++
  150. Function:
  151. CalculateTimeBombExpiration
  152. Description:
  153. Calculate the licensing time bomb expiration.
  154. Argument:
  155. pExpiration - The timebomb expiration date and time
  156. Return:
  157. TRUE if the expiration is calculated successfully or FALSE otherwise.
  158. --*/
  159. BOOL
  160. CalculateTimeBombExpiration(
  161. FILETIME * pExpiration )
  162. {
  163. time_t
  164. now = time( NULL );
  165. struct tm *
  166. GmTime = gmtime( &now );
  167. SYSTEMTIME
  168. SysTime;
  169. if(( NULL == pExpiration ) || ( NULL == GmTime ))
  170. {
  171. return( FALSE );
  172. }
  173. //
  174. // Add the days of licensing grace period to get the time bomb
  175. // expiration.
  176. //
  177. GmTime->tm_mday += GRACE_PERIOD;
  178. if( ( ( time_t ) -1 ) == mktime( GmTime ) )
  179. {
  180. return( FALSE );
  181. }
  182. memset( &SysTime, 0, sizeof( SYSTEMTIME ) );
  183. SysTime.wYear = (WORD) GmTime->tm_year + 1900;
  184. SysTime.wMonth = (WORD) GmTime->tm_mon + 1;
  185. SysTime.wDay = (WORD) GmTime->tm_mday;
  186. SysTime.wDayOfWeek = (WORD) GmTime->tm_wday;
  187. SysTime.wHour = (WORD) GmTime->tm_hour;
  188. SysTime.wMinute = (WORD) GmTime->tm_min;
  189. SysTime.wSecond = (WORD) GmTime->tm_sec;
  190. return( SystemTimeToFileTime( &SysTime, pExpiration ) );
  191. }
  192. /*++
  193. Function:
  194. ReceivedPermanentLicense();
  195. Description:
  196. Store the fact that we've received a permanent license
  197. Argument:
  198. None.
  199. --*/
  200. VOID
  201. ReceivedPermanentLicense()
  202. {
  203. static fReceivedPermanent = FALSE;
  204. if (!fReceivedPermanent)
  205. {
  206. RtlEnterCriticalSection(&g_EventCritSec);
  207. if (IsLicensingTimeBombExpired())
  208. {
  209. // We expired at some time in the past (before the last reboot)
  210. fReceivedPermanent = TRUE;
  211. HKEY hKey = NULL;
  212. DWORD dwDisp;
  213. LONG lReturn;
  214. lReturn = RegCreateKeyEx(
  215. HKEY_LOCAL_MACHINE,
  216. HYDRA_SERVER_PARAM,
  217. 0,
  218. NULL,
  219. REG_OPTION_NON_VOLATILE,
  220. KEY_ALL_ACCESS,
  221. NULL,
  222. &hKey,
  223. &dwDisp );
  224. if( ERROR_SUCCESS == lReturn )
  225. {
  226. //
  227. // setting the LicensingGracePeriodEnded DWORD value, the data of the value is not used
  228. //
  229. DWORD dwDays = 0;
  230. lReturn = RegSetValueEx(
  231. hKey,
  232. HS_PARAM_GRACE_PERIOD_ENDED,
  233. 0,
  234. REG_DWORD,
  235. ( PBYTE )&dwDays,
  236. sizeof( DWORD ) );
  237. }
  238. if(hKey)
  239. {
  240. RegCloseKey(hKey);
  241. }
  242. }
  243. else if (!fReceivedPermanent)
  244. {
  245. FILETIME ftNow;
  246. SYSTEMTIME stNow;
  247. fReceivedPermanent = TRUE;
  248. GetSystemTime( &stNow );
  249. SystemTimeToFileTime( &stNow , &ftNow );
  250. LsCsp_StoreSecret(
  251. (TLSIsBetaNTServer()) ? BETA_LICENSING_TIME_BOMB_LATEST_VERSION : RTM_LICENSING_TIME_BOMB_LATEST_VERSION,
  252. ( LPBYTE ) &ftNow,
  253. sizeof( ftNow ) );
  254. g_LicenseTimeBomb.dwLowDateTime = ftNow.dwLowDateTime;
  255. g_LicenseTimeBomb.dwHighDateTime = ftNow.dwHighDateTime;
  256. }
  257. RtlLeaveCriticalSection(&g_EventCritSec);
  258. }
  259. }
  260. /*++
  261. Function:
  262. CheckLicensingTimeBombExpiration();
  263. Description:
  264. The following events are logged when the terminal server
  265. has not registered itself with a license server:
  266. (1) The grace period for registration has expired
  267. (2) The grace period for registration is about to expire. By default,
  268. the system starts logging this event 15 days prior to the grace period
  269. expiration.
  270. Argument:
  271. None.
  272. Return:
  273. Nothing.
  274. --*/
  275. VOID
  276. CheckLicensingTimeBombExpiration()
  277. {
  278. SYSTEMTIME
  279. SysWarning,
  280. SysExpiration;
  281. FILETIME
  282. FileWarning,
  283. FileExpiration,
  284. CurrentTime;
  285. struct tm
  286. tmWarning,
  287. tmExpiration;
  288. DWORD
  289. dwWarningDays;
  290. //
  291. // if the licensing timebomb has expired, go ahead and log the event now
  292. //
  293. if( IsLicensingTimeBombExpired() )
  294. {
  295. if( FALSE == RegisteredWithLicenseServer())
  296. {
  297. LicenseLogEvent(
  298. EVENTLOG_ERROR_TYPE,
  299. EVENT_LICENSING_GRACE_PERIOD_EXPIRED,
  300. 0,
  301. NULL );
  302. }
  303. return;
  304. }
  305. //
  306. // get the timebomb expiration in system time format
  307. //
  308. RtlEnterCriticalSection(&g_EventCritSec);
  309. FileExpiration.dwLowDateTime = g_LicenseTimeBomb.dwLowDateTime;
  310. FileExpiration.dwHighDateTime = g_LicenseTimeBomb.dwHighDateTime;
  311. RtlLeaveCriticalSection(&g_EventCritSec);
  312. if( !FileTimeToSystemTime( &FileExpiration, &SysExpiration ) )
  313. {
  314. #if DBG
  315. DbgPrint( "LICPROT: LogLicensingTimeBombExpirationEvent: FileTimeToSystemTime failed: 0x%x\n", GetLastError() );
  316. #endif
  317. return;
  318. }
  319. //
  320. // convert the timebomb expiration to tm format
  321. //
  322. tmExpiration.tm_year = SysExpiration.wYear - 1900;
  323. tmExpiration.tm_mon = SysExpiration.wMonth - 1;
  324. tmExpiration.tm_mday = SysExpiration.wDay;
  325. tmExpiration.tm_wday = SysExpiration.wDayOfWeek;
  326. tmExpiration.tm_hour = SysExpiration.wHour;
  327. tmExpiration.tm_min = SysExpiration.wMinute;
  328. tmExpiration.tm_sec = SysExpiration.wSecond;
  329. tmExpiration.tm_isdst = -1;
  330. memcpy( &tmWarning, &tmExpiration, sizeof( tm ) );
  331. //
  332. // Get the number of days prior to expiration to start logging event
  333. //
  334. dwWarningDays = GetExpirationWarningDays();
  335. //
  336. // subtract these number of days from the expiration date
  337. //
  338. tmWarning.tm_mday -= dwWarningDays;
  339. //
  340. // get the accurate date
  341. //
  342. if( ( ( time_t ) -1 ) == mktime( &tmWarning ) )
  343. {
  344. #if DBG
  345. DbgPrint( "LICPROT: LogLicensingTimeBombExpirationEvent: mktime failed\n" );
  346. #endif
  347. return;
  348. }
  349. //
  350. // convert the date to systemtime format
  351. //
  352. memset( &SysWarning, 0, sizeof( SYSTEMTIME ) );
  353. SysWarning.wYear = (WORD) tmWarning.tm_year + 1900;
  354. SysWarning.wMonth = (WORD) tmWarning.tm_mon + 1;
  355. SysWarning.wDay = (WORD) tmWarning.tm_mday;
  356. SysWarning.wDayOfWeek = (WORD) tmWarning.tm_wday;
  357. SysWarning.wHour = (WORD) tmWarning.tm_hour;
  358. SysWarning.wMinute = (WORD) tmWarning.tm_min;
  359. SysWarning.wSecond = (WORD) tmWarning.tm_sec;
  360. //
  361. // convert from systemtime to filetime
  362. //
  363. if( !SystemTimeToFileTime( &SysWarning, &FileWarning ) )
  364. {
  365. #if DBG
  366. DbgPrint( "LICPROT: LogLicensingTimeBombExpirationEvent: SystemTimeToFileTime failed: 0x%x\n", GetLastError() );
  367. #endif
  368. return;
  369. }
  370. //
  371. // get the current time
  372. //
  373. GetSystemTimeAsFileTime( &CurrentTime );
  374. //
  375. // Log an event if we are within the warning period
  376. //
  377. if( 0 > CompareFileTime( &FileWarning, &CurrentTime ) )
  378. {
  379. LPTSTR szDate = TEXT("err");
  380. LPTSTR
  381. ptszLogString[1];
  382. int cchDate;
  383. BOOL fAllocated = FALSE;
  384. //
  385. // get the expiration date in string format.
  386. //
  387. cchDate = GetDateFormat(LOCALE_SYSTEM_DEFAULT,
  388. LOCALE_NOUSEROVERRIDE,
  389. &SysWarning,
  390. NULL,
  391. NULL,
  392. 0);
  393. if (0 != cchDate)
  394. {
  395. szDate = (LPTSTR) LocalAlloc(LMEM_FIXED,cchDate * sizeof(TCHAR));
  396. if (NULL != szDate)
  397. {
  398. fAllocated = TRUE;
  399. if (0 == GetDateFormat(LOCALE_SYSTEM_DEFAULT,
  400. LOCALE_NOUSEROVERRIDE,
  401. &SysWarning,
  402. NULL,
  403. szDate,
  404. cchDate))
  405. {
  406. LocalFree(szDate);
  407. fAllocated = FALSE;
  408. szDate = TEXT("err");
  409. }
  410. }
  411. else
  412. {
  413. szDate = TEXT("err");
  414. }
  415. }
  416. //
  417. // log the event
  418. //
  419. ptszLogString[0] = szDate;
  420. LicenseLogEvent(
  421. EVENTLOG_WARNING_TYPE,
  422. EVENT_LICENSING_GRACE_PERIOD_ABOUT_TO_EXPIRE,
  423. 1,
  424. ptszLogString );
  425. if (fAllocated)
  426. {
  427. LocalFree(szDate);
  428. }
  429. }
  430. return;
  431. }
  432. /*++
  433. Function:
  434. GetExpirationWarningDays
  435. Descriptions:
  436. Get the number of days prior to grace period expiration to log warning.
  437. Arguments:
  438. none.
  439. Returns:
  440. Nothing.
  441. --*/
  442. DWORD
  443. GetExpirationWarningDays()
  444. {
  445. HKEY
  446. hKey = NULL;
  447. DWORD
  448. dwDays = GRACE_PERIOD_EXPIRATION_WARNING_DAYS,
  449. dwValueType,
  450. dwDisp,
  451. cbValue = sizeof( DWORD );
  452. LONG
  453. lReturn;
  454. lReturn = RegCreateKeyEx(
  455. HKEY_LOCAL_MACHINE,
  456. HYDRA_SERVER_PARAM,
  457. 0,
  458. NULL,
  459. REG_OPTION_NON_VOLATILE,
  460. KEY_ALL_ACCESS,
  461. NULL,
  462. &hKey,
  463. &dwDisp );
  464. if( ERROR_SUCCESS == lReturn )
  465. {
  466. //
  467. // query the number of days prior to expiration to log warnings
  468. //
  469. lReturn = RegQueryValueEx(
  470. hKey,
  471. HS_PARAM_GRACE_PERIOD_EXPIRATION_WARNING_DAYS,
  472. NULL,
  473. &dwValueType,
  474. ( LPBYTE )&dwDays,
  475. &cbValue );
  476. if( ERROR_SUCCESS == lReturn )
  477. {
  478. //
  479. // check if the warning days value is within bound
  480. //
  481. if( dwDays > GRACE_PERIOD )
  482. {
  483. dwDays = GRACE_PERIOD_EXPIRATION_WARNING_DAYS;
  484. }
  485. }
  486. else
  487. {
  488. //
  489. // can't query the value, set the default
  490. //
  491. dwDays = GRACE_PERIOD_EXPIRATION_WARNING_DAYS;
  492. lReturn = RegSetValueEx(
  493. hKey,
  494. HS_PARAM_GRACE_PERIOD_EXPIRATION_WARNING_DAYS,
  495. 0,
  496. REG_DWORD,
  497. ( PBYTE )&dwDays,
  498. sizeof( DWORD ) );
  499. }
  500. }
  501. if( hKey )
  502. {
  503. RegCloseKey( hKey );
  504. }
  505. return( dwDays );
  506. }
  507. /****************************************************************************
  508. *
  509. * _AllowLicensingGracePeriodConnection
  510. *
  511. * Check if the licensing grace period has expired.
  512. *
  513. * ENTRY:
  514. * Nothing.
  515. *
  516. * EXIT:
  517. * TRUE - Allow connection
  518. * FALSE - Disallow connection
  519. *
  520. ****************************************************************************/
  521. BOOL
  522. AllowLicensingGracePeriodConnection()
  523. {
  524. return !IsLicensingTimeBombExpired();
  525. }
  526. DWORD WINAPI
  527. GracePeriodCheckingThread(
  528. LPVOID lpParam)
  529. {
  530. HANDLE hExit = (HANDLE) lpParam;
  531. DWORD dwWaitStatus;
  532. DWORD dwWaitInterval = GRACE_PERIOD_EVENT_LOG_INTERVAL;
  533. HKEY hKey = NULL;
  534. // Yield our first time slice
  535. Sleep(0);
  536. while (1)
  537. {
  538. LONG lReturn;
  539. DWORD dwDisp,
  540. dwValueType,
  541. dwDays,
  542. cbValue = sizeof( DWORD );
  543. lReturn = RegCreateKeyEx(
  544. HKEY_LOCAL_MACHINE,
  545. HYDRA_SERVER_PARAM,
  546. 0,
  547. NULL,
  548. REG_OPTION_NON_VOLATILE,
  549. KEY_ALL_ACCESS,
  550. NULL,
  551. &hKey,
  552. &dwDisp );
  553. if( ERROR_SUCCESS == lReturn )
  554. {
  555. //
  556. // query the presence of LicensingGracePeriodEnded value.
  557. //
  558. lReturn = RegQueryValueEx(
  559. hKey,
  560. HS_PARAM_GRACE_PERIOD_ENDED,
  561. NULL,
  562. &dwValueType,
  563. ( LPBYTE )&dwDays,
  564. &cbValue );
  565. }
  566. if(ERROR_SUCCESS != lReturn)
  567. {
  568. CheckLicensingTimeBombExpiration();
  569. dwWaitStatus = WaitForSingleObject(hExit, dwWaitInterval);
  570. if (WAIT_OBJECT_0 == dwWaitStatus)
  571. {
  572. g_GracePeriodThreadExitEvent = NULL;
  573. // hExit was signalled
  574. CloseHandle(hExit);
  575. goto done;
  576. }
  577. }
  578. else
  579. {
  580. g_GracePeriodThreadExitEvent = NULL;
  581. CloseHandle(hExit);
  582. goto done;
  583. }
  584. if(hKey != NULL)
  585. {
  586. RegCloseKey(hKey);
  587. hKey = NULL;
  588. }
  589. }
  590. done:
  591. if(hKey != NULL)
  592. {
  593. RegCloseKey(hKey);
  594. }
  595. return 1;
  596. }
  597. DWORD
  598. StartCheckingGracePeriod()
  599. {
  600. HANDLE hThread = NULL;
  601. DWORD Status = ERROR_SUCCESS;
  602. if (NULL != g_GracePeriodThreadExitEvent)
  603. {
  604. // already started
  605. return ERROR_SUCCESS;
  606. }
  607. RtlEnterCriticalSection(&g_EventCritSec);
  608. // Check one more time
  609. if (NULL != g_GracePeriodThreadExitEvent)
  610. {
  611. // already started
  612. goto done;
  613. }
  614. //
  615. // Create the event to signal thread exit
  616. //
  617. g_GracePeriodThreadExitEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
  618. if( NULL == g_GracePeriodThreadExitEvent )
  619. {
  620. Status = GetLastError();
  621. goto done;
  622. }
  623. //
  624. // Create the caching thread
  625. //
  626. hThread = CreateThread(
  627. NULL,
  628. 0,
  629. GracePeriodCheckingThread,
  630. ( LPVOID )g_GracePeriodThreadExitEvent,
  631. 0,
  632. NULL );
  633. if (hThread == NULL)
  634. {
  635. HANDLE hLocal = g_GracePeriodThreadExitEvent;
  636. g_GracePeriodThreadExitEvent = NULL;
  637. CloseHandle(hLocal);
  638. Status = GetLastError();
  639. goto done;
  640. }
  641. CloseHandle(hThread);
  642. done:
  643. RtlLeaveCriticalSection(&g_EventCritSec);
  644. return ERROR_SUCCESS;
  645. }
  646. DWORD
  647. StopCheckingGracePeriod()
  648. {
  649. //
  650. // Signal the thread to exit
  651. //
  652. if (NULL == g_GracePeriodThreadExitEvent)
  653. {
  654. // already stopped
  655. return ERROR_SUCCESS;
  656. }
  657. RtlEnterCriticalSection(&g_EventCritSec);
  658. // Check one more time
  659. if (NULL == g_GracePeriodThreadExitEvent)
  660. {
  661. // already stopped
  662. goto done;
  663. }
  664. HANDLE hLocal = g_GracePeriodThreadExitEvent;
  665. g_GracePeriodThreadExitEvent = NULL;
  666. SetEvent( hLocal );
  667. done:
  668. RtlLeaveCriticalSection(&g_EventCritSec);
  669. return ERROR_SUCCESS;
  670. }
  671. /*++
  672. Function:
  673. RegisteredWithLicenseServer
  674. Description:
  675. Check if this system has been registered with a license server.
  676. Currently, we determine if the system has been registered by checking if
  677. it has an X509 certificate. We may use different checks
  678. in the future.
  679. Arguments:
  680. none.
  681. Return:
  682. TRUE if the system has beem registered or FALSE otherwise.
  683. --*/
  684. BOOL
  685. RegisteredWithLicenseServer()
  686. {
  687. LICENSE_STATUS
  688. Status;
  689. DWORD
  690. dwSize = 0;
  691. //
  692. // check if we have an X509 certificate issued by a license server.
  693. //
  694. Status = LsCsp_GetServerData( LsCspInfo_X509Certificate, NULL, &dwSize );
  695. if( LICENSE_STATUS_OK == Status )
  696. {
  697. return( TRUE );
  698. }
  699. return( FALSE );
  700. }
  701. } // extern "C"