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.

3265 lines
89 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996-1996
  5. //
  6. // File: init.cpp
  7. //
  8. // Contents:
  9. // All hydra license server initialization code.
  10. //
  11. // History:
  12. // Feb. 4, 98 HueiWang Created
  13. // Note:
  14. //---------------------------------------------------------------------------
  15. #include "pch.cpp"
  16. #include "globals.h"
  17. #include "init.h"
  18. #include "misc.h"
  19. #include "tlscert.h"
  20. #include "pid.h"
  21. #include "upgdb.h"
  22. #include "lkplite.h"
  23. #include "gencert.h"
  24. #define WHISTLER_CAL L"SYSTEM\\CurrentControlSet\\Services\\TermService\\Parameters\\WhistlerCAL"
  25. //
  26. // file scope define
  27. //
  28. #define DEFAULT_CSP MS_DEF_PROV
  29. #define PROVIDER_TYPE PROV_RSA_FULL
  30. DWORD
  31. TLSStartupLSDB(
  32. IN BOOL bCheckDBStatus,
  33. IN DWORD dwMaxDbHandles,
  34. IN BOOL bStartEmptyIfError,
  35. IN LPTSTR pszChkPointDirPath,
  36. IN LPTSTR pszTempDirPath,
  37. IN LPTSTR pszLogDirPath,
  38. IN LPTSTR pszDbFile,
  39. IN LPTSTR pszUserName,
  40. IN LPTSTR pszPassword
  41. );
  42. DWORD
  43. TLSLoadRuntimeParameters();
  44. DWORD
  45. TLSStartLSDbWorkspaceEngine(
  46. BOOL,
  47. BOOL,
  48. BOOL,
  49. BOOL
  50. );
  51. ////////////////////////////////////////////////////////////////////////////
  52. //
  53. //
  54. // Global Variables
  55. //
  56. //
  57. ////////////////////////////////////////////////////////////////////////////
  58. static BOOL g_ValidDatabase=FALSE;
  59. #if DBG
  60. void
  61. EnsureExclusiveAccessToDbFile(
  62. LPTSTR szDatabaseFile
  63. )
  64. /*++
  65. --*/
  66. {
  67. HANDLE hFile = NULL;
  68. DWORD dwErrCode;
  69. hFile = CreateFile(
  70. szDatabaseFile,
  71. GENERIC_WRITE | GENERIC_READ,
  72. 0,
  73. NULL,
  74. OPEN_EXISTING,
  75. FILE_ATTRIBUTE_NORMAL,
  76. NULL
  77. );
  78. if( INVALID_HANDLE_VALUE == hFile )
  79. {
  80. dwErrCode = GetLastError();
  81. if( ERROR_FILE_NOT_FOUND != dwErrCode )
  82. {
  83. DBGPrintf(
  84. DBG_INFORMATION,
  85. DBG_FACILITY_INIT,
  86. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  87. _TEXT("EnsureExclusiveAccessToDbFile() failed with %d\n"),
  88. dwErrCode
  89. );
  90. }
  91. else if( ERROR_SHARING_VIOLATION == dwErrCode )
  92. {
  93. // special attention...
  94. TLSASSERT( FALSE );
  95. }
  96. else
  97. {
  98. TLSASSERT( FALSE );
  99. }
  100. }
  101. else
  102. {
  103. CloseHandle( hFile );
  104. }
  105. return;
  106. }
  107. #endif
  108. ////////////////////////////////////////////////////////////////////////////
  109. BOOL
  110. TLSGenerateLSDBBackupFileName(
  111. IN LPCTSTR pszPath,
  112. IN OUT LPTSTR pszTempFile
  113. )
  114. /*++
  115. --*/
  116. {
  117. DWORD dwTempRandom;
  118. if (lstrlen(pszPath)+13 > MAX_PATH)
  119. {
  120. // path too long
  121. return FALSE;
  122. }
  123. //
  124. // Generate a temporary file name.
  125. //
  126. dwTempRandom = GetTempFileName(
  127. pszPath,
  128. _TEXT("TLS"),
  129. 0,
  130. pszTempFile
  131. );
  132. if(dwTempRandom == 0)
  133. {
  134. //
  135. // GetTempFileName failed
  136. // Generate a backup file name based on current time,
  137. // possibility of collision is high
  138. //
  139. SYSTEMTIME LocalTime;
  140. if (lstrlen(pszPath)+25 > MAX_PATH)
  141. {
  142. // path too long
  143. return FALSE;
  144. }
  145. GetLocalTime(&LocalTime);
  146. wsprintf(
  147. pszTempFile,
  148. _TEXT("%s\\LSDBBackup.%02d%02d%02d%02d%02d%02d"),
  149. pszPath,
  150. LocalTime.wYear,
  151. LocalTime.wMonth,
  152. LocalTime.wDay,
  153. LocalTime.wHour,
  154. LocalTime.wMinute,
  155. LocalTime.wSecond
  156. );
  157. }
  158. return TRUE;
  159. }
  160. /////////////////////////////////////////////////////////////////////////////
  161. BOOL
  162. CanIssuePermLicense()
  163. {
  164. #ifndef ENFORCE_LICENSING
  165. return TRUE;
  166. #else
  167. if(g_bHasHydraCert == TRUE || (g_pbServerSPK != NULL && g_cbServerSPK != 0))
  168. {
  169. return TRUE;
  170. }
  171. return FALSE;
  172. #endif
  173. }
  174. /////////////////////////////////////////////////////////////////////////////
  175. void
  176. GetServiceLastShutdownTime(
  177. OUT FILETIME* ft
  178. )
  179. /*++
  180. --*/
  181. {
  182. *ft = g_ftLastShutdownTime;
  183. return;
  184. }
  185. //---------------------------------------------------------------------
  186. void
  187. SetServiceLastShutdownTime()
  188. {
  189. GetSystemTimeAsFileTime(&g_ftLastShutdownTime);
  190. }
  191. //---------------------------------------------------------------------
  192. void
  193. GetJobObjectDefaults(
  194. PDWORD pdwInterval,
  195. PDWORD pdwRetries,
  196. PDWORD pdwRestartTime
  197. )
  198. /*++
  199. --*/
  200. {
  201. *pdwInterval = g_dwTlsJobInterval;
  202. *pdwRetries = g_dwTlsJobRetryTimes;
  203. *pdwRestartTime = g_dwTlsJobRestartTime;
  204. }
  205. /////////////////////////////////////////////////////////////////////////////
  206. DWORD
  207. GetLicenseServerRole()
  208. {
  209. return g_SrvRole;
  210. }
  211. /////////////////////////////////////////////////////////////////////////////
  212. void
  213. ServerShutdown()
  214. {
  215. #if ENFORCE_LICENSING
  216. if(g_hCaStore)
  217. {
  218. CertCloseStore(
  219. g_hCaStore,
  220. CERT_CLOSE_STORE_FORCE_FLAG
  221. );
  222. }
  223. if(g_hCaRegKey)
  224. {
  225. RegCloseKey(g_hCaRegKey);
  226. }
  227. #endif
  228. if(g_SignKey)
  229. {
  230. CryptDestroyKey(g_SignKey);
  231. }
  232. if(g_ExchKey)
  233. {
  234. CryptDestroyKey(g_ExchKey);
  235. }
  236. TLServerLastRun lastRun;
  237. memset(&lastRun, 0, sizeof(TLServerLastRun));
  238. lastRun.dwVersion = LSERVER_LSA_LASTRUN_VER_CURRENT;
  239. lastRun.ftLastShutdownTime = g_ftLastShutdownTime;
  240. // if unclean shutdown or can't get next ID, set to 0
  241. if( g_ValidDatabase == FALSE ||
  242. TLSDBGetMaxKeyPackId(g_DbWorkSpace, (DWORD *)&g_NextKeyPackId) == FALSE ||
  243. TLSDBGetMaxLicenseId(g_DbWorkSpace, (DWORD *)&g_NextLicenseId) == FALSE )
  244. {
  245. g_NextKeyPackId = 0;
  246. g_NextLicenseId = 0;
  247. }
  248. lastRun.dwMaxKeyPackId = g_NextKeyPackId;
  249. lastRun.dwMaxLicenseId = g_NextLicenseId;
  250. StoreKey(
  251. LSERVER_LSA_LASTRUN,
  252. (PBYTE)&lastRun,
  253. sizeof(TLServerLastRun)
  254. );
  255. LSShutdownCertutilLib();
  256. if( g_SelfSignCertContext != NULL )
  257. {
  258. CertFreeCertificateContext(g_SelfSignCertContext);
  259. }
  260. if(g_LicenseCertContext)
  261. {
  262. CertFreeCertificateContext(g_LicenseCertContext);
  263. }
  264. TLSDestroyCryptContext(g_hCryptProv);
  265. g_hCryptProv=NULL;
  266. //
  267. // shutdown Work manager
  268. //
  269. TLSWorkManagerShutdown();
  270. #ifndef _NO_ODBC_JET
  271. if(g_DbWorkSpace != NULL)
  272. {
  273. ReleaseWorkSpace(&g_DbWorkSpace);
  274. }
  275. #endif
  276. CloseWorkSpacePool();
  277. FreeMemory(g_pbSecretKey);
  278. FreeMemory(g_pbSignatureEncodedCert);
  279. FreeMemory(g_pbExchangeEncodedCert);
  280. //FreeMemory(g_pbDomainSid);
  281. FreeMemory(g_pCertExtensions);
  282. FreeMemory(g_pszServerUniqueId);
  283. FreeMemory(g_pszServerPid);
  284. FreeMemory(g_pbServerSPK);
  285. if(g_szDomainGuid != NULL)
  286. {
  287. RpcStringFree(&g_szDomainGuid);
  288. }
  289. return;
  290. }
  291. /////////////////////////////////////////////////////////////////////////////
  292. DWORD
  293. StartServerInitThread(
  294. void* p
  295. )
  296. /*
  297. */
  298. {
  299. DWORD dwStatus = ERROR_SUCCESS;
  300. BOOL bDebug = (p) ? TRUE : FALSE;
  301. HKEY hKey = NULL;
  302. PTLSLSASERVERID pTlsLsaServerIds=NULL;
  303. DWORD cbTlsLsaServerIds=0;
  304. do {
  305. TLSInit();
  306. //
  307. // Load various run time parameters
  308. //
  309. dwStatus = TLSLoadRuntimeParameters();
  310. if(dwStatus != ERROR_SUCCESS)
  311. {
  312. break;
  313. }
  314. //
  315. // Retrive License Server's IDs
  316. //
  317. dwStatus = RetrieveKey(
  318. LSERVER_LSA_LSERVERID,
  319. (PBYTE *)&pTlsLsaServerIds,
  320. &cbTlsLsaServerIds
  321. );
  322. if(dwStatus != ERROR_SUCCESS)
  323. {
  324. //
  325. // First time, generate various license server ID
  326. //
  327. dwStatus = TLSGeneratePid(
  328. &g_pszServerPid,
  329. &g_cbServerPid,
  330. &g_pszServerUniqueId,
  331. &g_cbServerUniqueId
  332. );
  333. if(dwStatus != ERROR_SUCCESS)
  334. {
  335. TLSLogEvent(
  336. EVENTLOG_ERROR_TYPE,
  337. TLS_E_SERVICEINIT,
  338. TLS_E_GENERATE_IDS
  339. );
  340. break;
  341. }
  342. //
  343. // Store this into LSA
  344. //
  345. dwStatus = ServerIdsToLsaServerId(
  346. (PBYTE)g_pszServerUniqueId,
  347. g_cbServerUniqueId,
  348. (PBYTE)g_pszServerPid,
  349. g_cbServerPid,
  350. g_pbServerSPK,
  351. g_cbServerSPK,
  352. NULL,
  353. 0,
  354. &pTlsLsaServerIds,
  355. &cbTlsLsaServerIds
  356. );
  357. if(dwStatus != ERROR_SUCCESS)
  358. {
  359. TLSLogEvent(
  360. EVENTLOG_ERROR_TYPE,
  361. TLS_E_SERVICEINIT,
  362. dwStatus = TLS_E_STORE_IDS
  363. );
  364. break;
  365. }
  366. dwStatus = StoreKey(
  367. LSERVER_LSA_LSERVERID,
  368. (PBYTE)pTlsLsaServerIds,
  369. cbTlsLsaServerIds
  370. );
  371. if(dwStatus != ERROR_SUCCESS)
  372. {
  373. TLSLogEvent(
  374. EVENTLOG_ERROR_TYPE,
  375. TLS_E_SERVICEINIT,
  376. dwStatus = TLS_E_STORE_IDS
  377. );
  378. break;
  379. }
  380. }
  381. else
  382. {
  383. dwStatus = LsaServerIdToServerIds(
  384. pTlsLsaServerIds,
  385. cbTlsLsaServerIds,
  386. (PBYTE *)&g_pszServerUniqueId,
  387. &g_cbServerUniqueId,
  388. (PBYTE *)&g_pszServerPid,
  389. &g_cbServerPid,
  390. &g_pbServerSPK,
  391. &g_cbServerSPK,
  392. &g_pCertExtensions,
  393. &g_cbCertExtensions
  394. );
  395. if(dwStatus != ERROR_SUCCESS)
  396. {
  397. TLSLogEvent(
  398. EVENTLOG_ERROR_TYPE,
  399. TLS_E_SERVICEINIT,
  400. dwStatus = TLS_E_RETRIEVE_IDS
  401. );
  402. break;
  403. }
  404. if( g_pszServerUniqueId == NULL ||
  405. g_cbServerUniqueId == 0 ||
  406. g_pszServerPid == NULL ||
  407. g_cbServerPid == 0 )
  408. {
  409. TLSLogEvent(
  410. EVENTLOG_ERROR_TYPE,
  411. TLS_E_SERVICEINIT,
  412. dwStatus = TLS_E_INTERNAL
  413. );
  414. break;
  415. }
  416. }
  417. //
  418. // License Server common secret key for encoding/decoding
  419. // client HWID
  420. //
  421. LicenseGetSecretKey(&g_cbSecretKey, NULL);
  422. if((g_pbSecretKey = (PBYTE)AllocateMemory(g_cbSecretKey)) == NULL)
  423. {
  424. TLSLogEvent(
  425. EVENTLOG_ERROR_TYPE,
  426. TLS_E_SERVICEINIT,
  427. dwStatus = TLS_E_ALLOCATE_MEMORY
  428. );
  429. break;
  430. }
  431. if(LicenseGetSecretKey( &g_cbSecretKey, g_pbSecretKey ) != LICENSE_STATUS_OK)
  432. {
  433. TLSLogEvent(
  434. EVENTLOG_ERROR_TYPE,
  435. TLS_E_SERVICEINIT,
  436. dwStatus = TLS_E_RETRIEVE_KEY
  437. );
  438. break;
  439. }
  440. //--------------------------------------------------------------
  441. //
  442. // Check if our database file is in import directory
  443. //
  444. //--------------------------------------------------------------
  445. dwStatus = TLSStartLSDbWorkspaceEngine(
  446. bDebug == FALSE,
  447. FALSE, // check DB file on export directory
  448. FALSE, // check file time on DB file
  449. TRUE // log low license count warning.
  450. );
  451. if(dwStatus != ERROR_SUCCESS)
  452. {
  453. break;
  454. }
  455. dwStatus = ERROR_SUCCESS;
  456. g_ValidDatabase = TRUE;
  457. //
  458. // load all policy module, ignore error
  459. //
  460. ServiceLoadAllPolicyModule(
  461. HKEY_LOCAL_MACHINE,
  462. LSERVER_POLICY_REGBASE
  463. );
  464. //
  465. // Upgrade - make two copies of certificate
  466. //
  467. dwStatus = RegOpenKeyEx(
  468. HKEY_LOCAL_MACHINE,
  469. LSERVER_SERVER_CERTIFICATE_REGKEY,
  470. 0,
  471. KEY_ALL_ACCESS,
  472. &hKey
  473. );
  474. if(hKey != NULL)
  475. {
  476. RegCloseKey(hKey);
  477. }
  478. if(dwStatus != ERROR_SUCCESS)
  479. {
  480. dwStatus = ERROR_SUCCESS;
  481. // we are not register yet...
  482. break;
  483. }
  484. //
  485. // Verify first backup copy of certificate exists
  486. //
  487. hKey = NULL;
  488. dwStatus = RegOpenKeyEx(
  489. HKEY_LOCAL_MACHINE,
  490. LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP1,
  491. 0,
  492. KEY_ALL_ACCESS,
  493. &hKey
  494. );
  495. if(hKey != NULL)
  496. {
  497. RegCloseKey(hKey);
  498. }
  499. if(dwStatus == ERROR_FILE_NOT_FOUND)
  500. {
  501. dwStatus = TLSRestoreLicenseServerCertificate(
  502. LSERVER_SERVER_CERTIFICATE_REGKEY,
  503. LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP1
  504. );
  505. if(dwStatus != ERROR_SUCCESS)
  506. {
  507. TLSLogWarningEvent(TLS_W_BACKUPCERTIFICATE);
  508. TLSRegDeleteKey(
  509. HKEY_LOCAL_MACHINE,
  510. LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP1
  511. );
  512. }
  513. }
  514. //
  515. // Verify second backup copy of certificate exists
  516. //
  517. hKey = NULL;
  518. dwStatus = RegOpenKeyEx(
  519. HKEY_LOCAL_MACHINE,
  520. LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP2,
  521. 0,
  522. KEY_ALL_ACCESS,
  523. &hKey
  524. );
  525. if(hKey != NULL)
  526. {
  527. RegCloseKey(hKey);
  528. }
  529. if(dwStatus == ERROR_FILE_NOT_FOUND)
  530. {
  531. dwStatus = TLSRestoreLicenseServerCertificate(
  532. LSERVER_SERVER_CERTIFICATE_REGKEY,
  533. LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP2
  534. );
  535. if(dwStatus != ERROR_SUCCESS)
  536. {
  537. TLSLogWarningEvent(TLS_W_BACKUPCERTIFICATE);
  538. TLSRegDeleteKey(
  539. HKEY_LOCAL_MACHINE,
  540. LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP2
  541. );
  542. }
  543. }
  544. dwStatus = ERROR_SUCCESS;
  545. } while(FALSE);
  546. if(pTlsLsaServerIds != NULL)
  547. {
  548. LocalFree(pTlsLsaServerIds);
  549. }
  550. ExitThread(dwStatus);
  551. return dwStatus;
  552. }
  553. /////////////////////////////////////////////////////////////////////////////
  554. HANDLE
  555. ServerInit(
  556. BOOL bDebug
  557. )
  558. {
  559. HANDLE hThread;
  560. DWORD dump;
  561. hThread=(HANDLE)CreateThread(
  562. NULL,
  563. 0,
  564. StartServerInitThread,
  565. LongToPtr(bDebug),
  566. 0,
  567. &dump
  568. );
  569. return hThread;
  570. }
  571. /////////////////////////////////////////////////////////////////////////////
  572. DWORD
  573. TLSRestoreLicenseServerCertificate(
  574. LPCTSTR pszSourceRegKey,
  575. LPCTSTR pszTargetRegKey
  576. )
  577. /*++
  578. --*/
  579. {
  580. DWORD dwStatus = ERROR_SUCCESS;
  581. // first delete the certificate key, ignore error
  582. TLSRegDeleteKey(
  583. HKEY_LOCAL_MACHINE,
  584. pszTargetRegKey
  585. );
  586. // copy from backup
  587. dwStatus = TLSTreeCopyRegKey(
  588. HKEY_LOCAL_MACHINE,
  589. pszSourceRegKey,
  590. HKEY_LOCAL_MACHINE,
  591. pszTargetRegKey
  592. );
  593. if(dwStatus == ERROR_FILE_NOT_FOUND)
  594. {
  595. // source registry key does not exist
  596. dwStatus = TLS_E_NO_CERTIFICATE;
  597. }
  598. return dwStatus;
  599. }
  600. ////////////////////////////////////////////////////////////////////////////////
  601. DWORD
  602. TLSLoadVerifyLicenseServerCertificates()
  603. /*++
  604. --*/
  605. {
  606. DWORD dwStatus;
  607. #if ENFORCE_LICENSING
  608. // load certificate from normal place
  609. dwStatus = TLSLoadCHEndosedCertificate(
  610. &g_cbSignatureEncodedCert,
  611. &g_pbSignatureEncodedCert,
  612. &g_cbExchangeEncodedCert,
  613. &g_pbExchangeEncodedCert
  614. );
  615. if(dwStatus == ERROR_SUCCESS)
  616. {
  617. if(g_hCaStore != NULL)
  618. {
  619. CertCloseStore(
  620. g_hCaStore,
  621. CERT_CLOSE_STORE_FORCE_FLAG
  622. );
  623. }
  624. if(g_hCaRegKey != NULL)
  625. {
  626. RegCloseKey(g_hCaRegKey);
  627. }
  628. //
  629. // license server is registered, verify certificate
  630. //
  631. g_hCaStore = CertOpenRegistryStore(
  632. HKEY_LOCAL_MACHINE,
  633. LSERVER_CERTIFICATE_REG_CA_SIGNATURE,
  634. g_hCryptProv,
  635. &g_hCaRegKey
  636. );
  637. if(g_hCaStore != NULL)
  638. {
  639. //
  640. // Go thru license server's certficiate to validate
  641. //
  642. dwStatus = TLSValidateServerCertficates(
  643. g_hCryptProv,
  644. g_hCaStore,
  645. g_pbSignatureEncodedCert,
  646. g_cbSignatureEncodedCert,
  647. g_pbExchangeEncodedCert,
  648. g_cbExchangeEncodedCert,
  649. &g_ftCertExpiredTime
  650. );
  651. if(dwStatus != ERROR_SUCCESS)
  652. {
  653. //
  654. // Invalid certificate in registry
  655. //
  656. dwStatus = TLS_E_INVALID_CERTIFICATE;
  657. }
  658. }
  659. else
  660. {
  661. //
  662. // Can't open registry key, startup as non-register
  663. // server.
  664. //
  665. //TLSLogEvent(
  666. // EVENTLOG_ERROR_TYPE,
  667. // TLS_E_SERVICEINIT,
  668. // TLS_E_OPEN_CERTSTORE,
  669. // dwStatus = GetLastError()
  670. // );
  671. dwStatus = TLS_E_NO_CERTIFICATE;
  672. }
  673. }
  674. if(dwStatus == ERROR_SUCCESS)
  675. {
  676. if(g_LicenseCertContext != NULL)
  677. {
  678. CertFreeCertificateContext(g_LicenseCertContext);
  679. }
  680. g_LicenseCertContext = CertCreateCertificateContext(
  681. X509_ASN_ENCODING,
  682. g_pbSignatureEncodedCert,
  683. g_cbSignatureEncodedCert
  684. );
  685. //if(!g_LicenseCertContext)
  686. //{
  687. // TLSLogEvent(
  688. // EVENTLOG_ERROR_TYPE,
  689. // TLS_E_SERVICEINIT,
  690. // TLS_E_CREATE_CERTCONTEXT,
  691. // GetLastError()
  692. // );
  693. //}
  694. }
  695. if(dwStatus != ERROR_SUCCESS)
  696. {
  697. g_bHasHydraCert = FALSE;
  698. }
  699. else
  700. {
  701. g_bHasHydraCert = TRUE;
  702. }
  703. #else
  704. dwStatus = TLS_E_NO_CERTIFICATE;
  705. #endif
  706. return dwStatus;
  707. }
  708. ///////////////////////////////////////////////////////////////////////
  709. BOOL
  710. TLSLoadServerCertificate()
  711. /*++
  712. Abstract:
  713. Load license server certificate
  714. --*/
  715. {
  716. BOOL bSuccess = FALSE;
  717. DWORD dwStatus;
  718. PBYTE pbSelfSignedCert = NULL;
  719. DWORD cbSelfSignedCert = 0;
  720. BOOL bSelfSignedCreated = FALSE;
  721. g_ftCertExpiredTime.dwLowDateTime = 0xFFFFFFFF;
  722. g_ftCertExpiredTime.dwHighDateTime = 0xFFFFFFFF;
  723. #if ENFORCE_LICENSING
  724. dwStatus = TLSLoadVerifyLicenseServerCertificates();
  725. //
  726. // failed to load server certificate, try backup copy,
  727. // if either one success, make sure we have all three copy up
  728. // to date.
  729. //
  730. if(dwStatus == TLS_E_INVALID_CERTIFICATE || dwStatus == TLS_E_NO_CERTIFICATE)
  731. {
  732. dwStatus = TLSRestoreLicenseServerCertificate(
  733. LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP1,
  734. LSERVER_SERVER_CERTIFICATE_REGKEY
  735. );
  736. if(dwStatus == ERROR_SUCCESS)
  737. {
  738. dwStatus = TLSLoadVerifyLicenseServerCertificates();
  739. if(dwStatus == ERROR_SUCCESS)
  740. {
  741. //
  742. // Log event indicate we are using backup certificate
  743. //
  744. LPCTSTR pString[1];
  745. pString[0]= g_szComputerName;
  746. TLSLogEventString(
  747. EVENTLOG_WARNING_TYPE,
  748. TLS_W_CORRUPTTRYBACKUPCERTIFICATE,
  749. 1,
  750. pString
  751. );
  752. //
  753. // make sure second copy is same as first copy.
  754. //
  755. TLSRestoreLicenseServerCertificate(
  756. LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP1,
  757. LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP2
  758. );
  759. }
  760. }
  761. }
  762. if(dwStatus == TLS_E_INVALID_CERTIFICATE || dwStatus == TLS_E_NO_CERTIFICATE)
  763. {
  764. dwStatus = TLSRestoreLicenseServerCertificate(
  765. LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP2,
  766. LSERVER_SERVER_CERTIFICATE_REGKEY
  767. );
  768. if(dwStatus == ERROR_SUCCESS)
  769. {
  770. dwStatus = TLSLoadVerifyLicenseServerCertificates();
  771. if(dwStatus == ERROR_SUCCESS)
  772. {
  773. //
  774. // Log event indicate we are using backup certificate
  775. //
  776. LPCTSTR pString[1];
  777. pString[0]= g_szComputerName;
  778. TLSLogEventString(
  779. EVENTLOG_WARNING_TYPE,
  780. TLS_W_CORRUPTTRYBACKUPCERTIFICATE,
  781. 1,
  782. pString
  783. );
  784. //
  785. // make sure our first copy is up to date
  786. //
  787. TLSRestoreLicenseServerCertificate(
  788. LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP2,
  789. LSERVER_SERVER_CERTIFICATE_REGKEY_BACKUP1
  790. );
  791. }
  792. }
  793. }
  794. //
  795. // Everything failed, log an event state that license server
  796. // will startup in un-registered mode
  797. //
  798. if(dwStatus == TLS_E_INVALID_CERTIFICATE)
  799. {
  800. LPCTSTR pString[1];
  801. pString[0] = g_szComputerName;
  802. TLSLogEventString(
  803. EVENTLOG_WARNING_TYPE,
  804. TLS_W_STARTUPCORRUPTEDCERT,
  805. 1,
  806. pString
  807. );
  808. }
  809. else if(CanIssuePermLicense() == FALSE)
  810. {
  811. // we are not registered yet
  812. LPCTSTR pString[1];
  813. pString[0] = g_szComputerName;
  814. TLSLogEventString(
  815. EVENTLOG_WARNING_TYPE,
  816. TLS_W_STARTUPNOCERT,
  817. 1,
  818. pString
  819. );
  820. }
  821. if( dwStatus != ERROR_SUCCESS )
  822. {
  823. //
  824. // if all failed, re-generate and start up as un-register
  825. // license server
  826. //
  827. bSuccess = FALSE;
  828. //
  829. // wipe out all certificates and re-generate everything,
  830. // don't re-generate key if we are not registered yet.
  831. //
  832. if(g_pbServerSPK == NULL || g_cbServerSPK == 0)
  833. {
  834. TLSReGenerateKeys(FALSE);
  835. }
  836. }
  837. else
  838. {
  839. bSuccess = TRUE;
  840. }
  841. #endif
  842. if(bSuccess == FALSE)
  843. {
  844. bSuccess = (TLSLoadSelfSignCertificates(
  845. g_hCryptProv,
  846. #if ENFORCE_LICENSING
  847. g_pbServerSPK,
  848. g_cbServerSPK,
  849. #else
  850. NULL,
  851. 0,
  852. #endif
  853. &g_cbSignatureEncodedCert,
  854. &g_pbSignatureEncodedCert,
  855. &g_cbExchangeEncodedCert,
  856. &g_pbExchangeEncodedCert
  857. ) == ERROR_SUCCESS);
  858. #ifndef ENFORCE_LICENSING
  859. //
  860. // non enforce license version
  861. g_bHasHydraCert = TRUE;
  862. #endif
  863. if(bSuccess == TRUE)
  864. {
  865. if(g_LicenseCertContext != NULL)
  866. {
  867. CertFreeCertificateContext(g_LicenseCertContext);
  868. }
  869. g_LicenseCertContext = CertCreateCertificateContext(
  870. X509_ASN_ENCODING,
  871. g_pbSignatureEncodedCert,
  872. g_cbSignatureEncodedCert
  873. );
  874. if(!g_LicenseCertContext)
  875. {
  876. bSuccess = FALSE;
  877. //
  878. // For self-signed cert, this is critical error, for
  879. // cert. in registry store, it must have been thru validation
  880. // so still critical error.
  881. //
  882. TLSLogEvent(
  883. EVENTLOG_ERROR_TYPE,
  884. TLS_E_SERVICEINIT,
  885. TLS_E_CREATE_CERTCONTEXT,
  886. GetLastError()
  887. );
  888. }
  889. else
  890. {
  891. // we have created a self-signed certificate.
  892. bSelfSignedCreated = TRUE;
  893. }
  894. }
  895. }
  896. //
  897. // Create a self-signed certificate for old client,
  898. //
  899. if( bSuccess == TRUE )
  900. {
  901. if( g_SelfSignCertContext != NULL )
  902. {
  903. CertFreeCertificateContext( g_SelfSignCertContext );
  904. g_SelfSignCertContext = NULL;
  905. }
  906. if( bSelfSignedCreated == FALSE )
  907. {
  908. //
  909. // Create a self-signed certificate just for old client
  910. //
  911. dwStatus = TLSCreateSelfSignCertificate(
  912. g_hCryptProv,
  913. AT_SIGNATURE,
  914. #if ENFORCE_LICENSING
  915. g_pbServerSPK,
  916. g_cbServerSPK,
  917. #else
  918. NULL,
  919. 0,
  920. #endif
  921. 0,
  922. NULL,
  923. &cbSelfSignedCert,
  924. &pbSelfSignedCert
  925. );
  926. if( dwStatus == ERROR_SUCCESS )
  927. {
  928. g_SelfSignCertContext = CertCreateCertificateContext(
  929. X509_ASN_ENCODING,
  930. pbSelfSignedCert,
  931. cbSelfSignedCert
  932. );
  933. if( g_SelfSignCertContext == NULL )
  934. {
  935. bSuccess = FALSE;
  936. TLSLogEvent(
  937. EVENTLOG_ERROR_TYPE,
  938. TLS_E_SERVICEINIT,
  939. TLS_E_CREATE_CERTCONTEXT,
  940. GetLastError()
  941. );
  942. }
  943. }
  944. }
  945. else
  946. {
  947. // we already have self-signed certificate created.
  948. g_SelfSignCertContext = CertDuplicateCertificateContext( g_LicenseCertContext );
  949. if( g_SelfSignCertContext == NULL )
  950. {
  951. TLSASSERT(FALSE);
  952. //
  953. // impossible, CertDuplicateCertificateContext() simply increase
  954. // reference count
  955. //
  956. bSuccess = FALSE;
  957. TLSLogEvent(
  958. EVENTLOG_ERROR_TYPE,
  959. TLS_E_SERVICEINIT,
  960. TLS_E_CREATE_CERTCONTEXT,
  961. GetLastError()
  962. );
  963. }
  964. }
  965. }
  966. FreeMemory(pbSelfSignedCert);
  967. return bSuccess;
  968. }
  969. //---------------------------------------------------------------------
  970. DWORD
  971. ServiceInitCrypto(
  972. IN BOOL bCreateNewKeys,
  973. IN LPCTSTR pszKeyContainer,
  974. OUT HCRYPTPROV* phCryptProv,
  975. OUT HCRYPTKEY* phSignKey,
  976. OUT HCRYPTKEY* phExchKey
  977. )
  978. /*
  979. */
  980. {
  981. DWORD dwStatus=ERROR_SUCCESS;
  982. PBYTE pbSignKey=NULL;
  983. DWORD cbSignKey=0;
  984. PBYTE pbExchKey=NULL;
  985. DWORD cbExchKey=0;
  986. if(bCreateNewKeys == FALSE)
  987. {
  988. //
  989. // Load key from LSA
  990. //
  991. dwStatus = TLSLoadSavedCryptKeyFromLsa(
  992. &pbSignKey,
  993. &cbSignKey,
  994. &pbExchKey,
  995. &cbExchKey
  996. );
  997. }
  998. if(bCreateNewKeys == TRUE || dwStatus == ERROR_FILE_NOT_FOUND)
  999. {
  1000. dwStatus = TLSCryptGenerateNewKeys(
  1001. &pbSignKey,
  1002. &cbSignKey,
  1003. &pbExchKey,
  1004. &cbExchKey
  1005. );
  1006. if(dwStatus == ERROR_SUCCESS)
  1007. {
  1008. // Save Key to LSA
  1009. dwStatus = TLSSaveCryptKeyToLsa(
  1010. pbSignKey,
  1011. cbSignKey,
  1012. pbExchKey,
  1013. cbExchKey
  1014. );
  1015. }
  1016. }
  1017. if(dwStatus == ERROR_SUCCESS)
  1018. {
  1019. //
  1020. // Initialize a clean crypto.
  1021. //
  1022. dwStatus = TLSInitCryptoProv(
  1023. pszKeyContainer,
  1024. pbSignKey,
  1025. cbSignKey,
  1026. pbExchKey,
  1027. cbExchKey,
  1028. phCryptProv,
  1029. phSignKey,
  1030. phExchKey
  1031. );
  1032. }
  1033. if(pbSignKey)
  1034. {
  1035. LocalFree(pbSignKey);
  1036. }
  1037. if(pbExchKey)
  1038. {
  1039. LocalFree(pbExchKey);
  1040. }
  1041. return dwStatus;
  1042. }
  1043. /////////////////////////////////////////////////////////////////////////////
  1044. DWORD
  1045. InitCryptoAndCertificate()
  1046. {
  1047. DWORD status=ERROR_SUCCESS;
  1048. DWORD dwServiceState;
  1049. DWORD dwCryptoState;
  1050. //
  1051. // Initialize single global Cryptographic Provider
  1052. //
  1053. status = ServiceInitCrypto(
  1054. FALSE,
  1055. NULL,
  1056. &g_hCryptProv,
  1057. &g_SignKey,
  1058. &g_ExchKey
  1059. );
  1060. if(status != ERROR_SUCCESS)
  1061. {
  1062. TLSLogEvent(
  1063. EVENTLOG_ERROR_TYPE,
  1064. TLS_E_SERVICEINIT,
  1065. TLS_E_INIT_CRYPTO,
  1066. status
  1067. );
  1068. status = TLS_E_SERVICE_STARTUP;
  1069. goto cleanup;
  1070. }
  1071. LSInitCertutilLib( NULL );
  1072. if(!TLSLoadServerCertificate())
  1073. {
  1074. status = TLS_E_SERVICE_STARTUP;
  1075. TLSLogErrorEvent(TLS_E_LOAD_CERTIFICATE);
  1076. goto cleanup;
  1077. }
  1078. //
  1079. if(!g_pbExchangeEncodedCert || !g_pbSignatureEncodedCert)
  1080. {
  1081. TLSLogErrorEvent(status = TLS_E_INTERNAL);
  1082. }
  1083. cleanup:
  1084. return status;
  1085. }
  1086. //////////////////////////////////////////////////////////////////
  1087. DWORD
  1088. TLSReGenKeysAndReloadServerCert(
  1089. BOOL bReGenKey
  1090. )
  1091. /*++
  1092. --*/
  1093. {
  1094. DWORD dwStatus;
  1095. dwStatus = TLSReGenerateKeys(bReGenKey);
  1096. //
  1097. // always try reload certificate since TLSReGenerateKeys()
  1098. // will wipe out our keys.
  1099. //
  1100. if(TLSLoadServerCertificate() == TRUE)
  1101. {
  1102. if(!g_pbExchangeEncodedCert || !g_pbSignatureEncodedCert)
  1103. {
  1104. TLSLogErrorEvent(dwStatus = TLS_E_INTERNAL);
  1105. }
  1106. }
  1107. else
  1108. {
  1109. TLSLogErrorEvent(dwStatus = TLS_E_LOAD_CERTIFICATE);
  1110. }
  1111. return dwStatus;
  1112. }
  1113. ////////////////////////////////////////////////////////////////////
  1114. DWORD
  1115. TLSReGenerateKeys(
  1116. BOOL bReGenKey
  1117. )
  1118. /*++
  1119. Always restore state back to clean install, bReGenKeyOnly
  1120. not supported.
  1121. --*/
  1122. {
  1123. HCRYPTPROV hCryptProv = NULL;
  1124. HCRYPTKEY hSignKey = NULL;
  1125. HCRYPTKEY hExchKey = NULL;
  1126. DWORD dwStatus = ERROR_SUCCESS;
  1127. PTLSLSASERVERID pTlsLsaServerIds=NULL;
  1128. DWORD cbTlsLsaServerIds=0;
  1129. //
  1130. // Create a new clean crypto.
  1131. //
  1132. dwStatus = ServiceInitCrypto(
  1133. bReGenKey,
  1134. NULL,
  1135. &hCryptProv,
  1136. &hSignKey,
  1137. &hExchKey
  1138. );
  1139. if(dwStatus != ERROR_SUCCESS)
  1140. {
  1141. return dwStatus;
  1142. }
  1143. //
  1144. // Cleanup our certificate registry.
  1145. //
  1146. TLSUninstallLsCertificate();
  1147. //
  1148. // Cleanup in-memory certificates, keys...
  1149. //
  1150. if(g_SignKey)
  1151. {
  1152. CryptDestroyKey(g_SignKey);
  1153. g_SignKey = NULL;
  1154. }
  1155. if(g_ExchKey)
  1156. {
  1157. CryptDestroyKey(g_ExchKey);
  1158. g_ExchKey = NULL;
  1159. }
  1160. if( g_SelfSignCertContext != NULL )
  1161. {
  1162. CertFreeCertificateContext( g_SelfSignCertContext );
  1163. g_SelfSignCertContext = NULL;
  1164. }
  1165. if( g_LicenseCertContext != NULL )
  1166. {
  1167. CertFreeCertificateContext(g_LicenseCertContext);
  1168. g_LicenseCertContext = NULL;
  1169. }
  1170. if(g_hCryptProv != NULL)
  1171. {
  1172. TLSDestroyCryptContext(g_hCryptProv);
  1173. }
  1174. g_hCryptProv=NULL;
  1175. FreeMemory(g_pbSignatureEncodedCert);
  1176. g_pbSignatureEncodedCert = NULL;
  1177. g_cbSignatureEncodedCert = 0;
  1178. FreeMemory(g_pbExchangeEncodedCert);
  1179. g_pbExchangeEncodedCert = NULL;
  1180. g_cbExchangeEncodedCert = 0;
  1181. //
  1182. // Always back to clean state.
  1183. //
  1184. FreeMemory(g_pCertExtensions);
  1185. g_pCertExtensions = NULL;
  1186. g_cbCertExtensions = 0;
  1187. FreeMemory(g_pbServerSPK);
  1188. g_pbServerSPK = NULL;
  1189. g_cbServerSPK = 0;
  1190. //
  1191. // Store this into LSA
  1192. //
  1193. dwStatus = ServerIdsToLsaServerId(
  1194. (PBYTE)g_pszServerUniqueId,
  1195. g_cbServerUniqueId,
  1196. (PBYTE)g_pszServerPid,
  1197. g_cbServerPid,
  1198. NULL,
  1199. 0,
  1200. NULL,
  1201. 0,
  1202. &pTlsLsaServerIds,
  1203. &cbTlsLsaServerIds
  1204. );
  1205. if(dwStatus != ERROR_SUCCESS)
  1206. {
  1207. assert(FALSE);
  1208. goto cleanup;
  1209. }
  1210. dwStatus = StoreKey(
  1211. LSERVER_LSA_LSERVERID,
  1212. (PBYTE)pTlsLsaServerIds,
  1213. cbTlsLsaServerIds
  1214. );
  1215. if(dwStatus != ERROR_SUCCESS)
  1216. {
  1217. assert(FALSE);
  1218. goto cleanup;
  1219. }
  1220. //
  1221. // Re-generate in-memory certificates...
  1222. //
  1223. g_hCryptProv = hCryptProv;
  1224. g_SignKey = hSignKey;
  1225. g_ExchKey = hExchKey;
  1226. cleanup:
  1227. FreeMemory(pTlsLsaServerIds);
  1228. return dwStatus;
  1229. }
  1230. //////////////////////////////////////////////////////////////////
  1231. DWORD
  1232. TLSReGenSelfSignCert(
  1233. IN HCRYPTPROV hCryptProv,
  1234. IN PBYTE pbSPK,
  1235. IN DWORD cbSPK,
  1236. IN DWORD dwNumExtensions,
  1237. IN PCERT_EXTENSION pCertExtensions
  1238. )
  1239. /*++
  1240. --*/
  1241. {
  1242. DWORD dwStatus;
  1243. PTLSLSASERVERID pbLsaServerId = NULL;
  1244. DWORD cbLsaServerId = 0;
  1245. PBYTE pbSignCert = NULL;
  1246. DWORD cbSignCert = 0;
  1247. PBYTE pbExchCert = NULL;
  1248. DWORD cbExchCert = 0;
  1249. DWORD dwVerifyResult;
  1250. PCCERT_CONTEXT hLicenseCertContext = NULL;
  1251. LPTSTR pszSPK = NULL;
  1252. if(hCryptProv == NULL || pbSPK == NULL || cbSPK == 0)
  1253. {
  1254. dwStatus = ERROR_INVALID_PARAMETER;
  1255. goto cleanup;
  1256. }
  1257. //
  1258. // Verify SPK, current SPK is base 24 encoded string
  1259. //
  1260. pszSPK = (LPTSTR)AllocateMemory(cbSPK + sizeof(TCHAR));
  1261. if(pszSPK == NULL)
  1262. {
  1263. dwStatus = TLS_E_ALLOCATE_MEMORY;
  1264. goto cleanup;
  1265. }
  1266. memcpy(
  1267. pszSPK,
  1268. pbSPK,
  1269. cbSPK
  1270. );
  1271. //
  1272. // Verify SPK
  1273. //
  1274. dwVerifyResult = LKPLITE_SPK_VALID;
  1275. dwStatus = LKPLiteVerifySPK(
  1276. g_pszServerPid,
  1277. pszSPK,
  1278. &dwVerifyResult
  1279. );
  1280. if(dwStatus != ERROR_SUCCESS || dwVerifyResult != LKPLITE_SPK_VALID)
  1281. {
  1282. if(dwVerifyResult == LKPLITE_SPK_INVALID)
  1283. {
  1284. dwStatus = TLS_E_INVALID_SPK;
  1285. }
  1286. else if(dwVerifyResult == LKPLITE_SPK_INVALID_SIGN)
  1287. {
  1288. dwStatus = TLS_E_SPK_INVALID_SIGN;
  1289. }
  1290. goto cleanup;
  1291. }
  1292. //
  1293. // Write SPK to LSA
  1294. //
  1295. dwStatus = ServerIdsToLsaServerId(
  1296. (PBYTE)g_pszServerUniqueId,
  1297. g_cbServerUniqueId,
  1298. (PBYTE)g_pszServerPid,
  1299. g_cbServerPid,
  1300. pbSPK,
  1301. cbSPK,
  1302. pCertExtensions,
  1303. dwNumExtensions,
  1304. &pbLsaServerId,
  1305. &cbLsaServerId
  1306. );
  1307. if(dwStatus != ERROR_SUCCESS)
  1308. {
  1309. goto cleanup;
  1310. }
  1311. //
  1312. // Save data to LSA
  1313. //
  1314. dwStatus = StoreKey(
  1315. LSERVER_LSA_LSERVERID,
  1316. (PBYTE) pbLsaServerId,
  1317. cbLsaServerId
  1318. );
  1319. if(dwStatus != ERROR_SUCCESS)
  1320. {
  1321. goto cleanup;
  1322. }
  1323. //
  1324. // Re-generate our certificatge
  1325. //
  1326. dwStatus = TLSCreateSelfSignCertificate(
  1327. hCryptProv,
  1328. AT_SIGNATURE,
  1329. pbSPK,
  1330. cbSPK,
  1331. dwNumExtensions,
  1332. pCertExtensions,
  1333. &cbSignCert,
  1334. &pbSignCert
  1335. );
  1336. if(dwStatus != ERROR_SUCCESS)
  1337. {
  1338. goto cleanup;
  1339. }
  1340. hLicenseCertContext = CertCreateCertificateContext(
  1341. X509_ASN_ENCODING,
  1342. pbSignCert,
  1343. cbSignCert
  1344. );
  1345. if( hLicenseCertContext == NULL )
  1346. {
  1347. dwStatus = GetLastError();
  1348. goto cleanup;
  1349. }
  1350. dwStatus = TLSCreateSelfSignCertificate(
  1351. hCryptProv,
  1352. AT_KEYEXCHANGE,
  1353. pbSPK,
  1354. cbSPK,
  1355. dwNumExtensions,
  1356. pCertExtensions,
  1357. &cbExchCert,
  1358. &pbExchCert
  1359. );
  1360. if(dwStatus != ERROR_SUCCESS)
  1361. {
  1362. goto cleanup;
  1363. }
  1364. //
  1365. // Certificate generated is Perm. self-signed certificate,
  1366. // don't store in registry.
  1367. //
  1368. //
  1369. // Make a copy of SPK
  1370. //
  1371. g_pbServerSPK = (PBYTE)AllocateMemory(cbSPK);
  1372. if(g_pbServerSPK == NULL)
  1373. {
  1374. dwStatus = GetLastError();
  1375. goto cleanup;
  1376. }
  1377. memcpy(
  1378. g_pbServerSPK,
  1379. pbSPK,
  1380. cbSPK
  1381. );
  1382. g_cbServerSPK = cbSPK;
  1383. if( g_SelfSignCertContext != NULL )
  1384. {
  1385. CertFreeCertificateContext(g_SelfSignCertContext);
  1386. }
  1387. g_SelfSignCertContext = CertDuplicateCertificateContext(hLicenseCertContext);
  1388. if( g_SelfSignCertContext == NULL )
  1389. {
  1390. TLSASSERT( g_SelfSignCertContext != NULL );
  1391. dwStatus = GetLastError();
  1392. goto cleanup;
  1393. }
  1394. //
  1395. // Everything is OK, switch to new certificate
  1396. //
  1397. FreeMemory(g_pbSignatureEncodedCert);
  1398. g_pbSignatureEncodedCert = pbSignCert;
  1399. g_cbSignatureEncodedCert = cbSignCert;
  1400. if(g_LicenseCertContext != NULL)
  1401. {
  1402. CertFreeCertificateContext(g_LicenseCertContext);
  1403. }
  1404. //
  1405. // use duplicate instead of direct assign
  1406. //
  1407. g_LicenseCertContext = CertDuplicateCertificateContext(hLicenseCertContext);
  1408. TLSASSERT(g_LicenseCertContext != NULL);
  1409. FreeMemory(g_pbExchangeEncodedCert);
  1410. g_pbExchangeEncodedCert = pbExchCert;
  1411. g_cbExchangeEncodedCert = cbExchCert;
  1412. pbSignCert = NULL;
  1413. pbExchCert = NULL;
  1414. //
  1415. // Mark we have Perm. self-signed cert.
  1416. //
  1417. g_bHasHydraCert = FALSE;
  1418. cleanup:
  1419. if( hLicenseCertContext != NULL )
  1420. {
  1421. CertFreeCertificateContext( hLicenseCertContext );
  1422. }
  1423. FreeMemory(pszSPK);
  1424. FreeMemory(pbLsaServerId);
  1425. FreeMemory(pbSignCert);
  1426. FreeMemory(pbExchCert);
  1427. return dwStatus;
  1428. }
  1429. //------------------------------------------------
  1430. void
  1431. CleanSetupLicenseServer()
  1432. /*++
  1433. --*/
  1434. {
  1435. DWORD dwStatus;
  1436. //
  1437. // Wipe out SPK in LSA
  1438. //
  1439. dwStatus = StoreKey(
  1440. LSERVER_LSA_LSERVERID,
  1441. (PBYTE) NULL,
  1442. 0
  1443. );
  1444. dwStatus = StoreKey(
  1445. LSERVER_LSA_LASTRUN,
  1446. (PBYTE) NULL,
  1447. 0
  1448. );
  1449. dwStatus = StoreKey(
  1450. LSERVER_LSA_PRIVATEKEY_EXCHANGE,
  1451. (PBYTE) NULL,
  1452. 0
  1453. );
  1454. dwStatus = StoreKey(
  1455. LSERVER_LSA_PRIVATEKEY_SIGNATURE,
  1456. (PBYTE) NULL,
  1457. 0
  1458. );
  1459. dwStatus = TLSUninstallLsCertificate();
  1460. return;
  1461. }
  1462. //-----------------------------------------------
  1463. //
  1464. //
  1465. DWORD
  1466. TLSStartupLSDB(
  1467. IN BOOL bCheckDBStatus,
  1468. IN DWORD dwMaxDbHandles,
  1469. IN BOOL bStartEmptyIfError,
  1470. IN BOOL bLogWarning,
  1471. IN LPTSTR pszChkPointDirPath,
  1472. IN LPTSTR pszTempDirPath,
  1473. IN LPTSTR pszLogDirPath,
  1474. IN LPTSTR pszDbFile,
  1475. IN LPTSTR pszUserName,
  1476. IN LPTSTR pszPassword
  1477. )
  1478. /*++
  1479. Abstract:
  1480. Initialize License Server's DB workspace handle list.
  1481. Parameters:
  1482. pszChkPointDirPath : ESE check point directory.
  1483. pszTempDirPath : ESE temp. directory.
  1484. pszLogDirPath : ESE log file directory.
  1485. pszDbPath : License Server database file path.
  1486. pszDbFile : License Server database file name (no path).
  1487. pszUserName : Database file user name.
  1488. pszPassword : Database file password.
  1489. Returns:
  1490. ERROR_SUCCESS or error code.
  1491. --*/
  1492. {
  1493. BOOL bSuccess = TRUE;
  1494. DWORD status = ERROR_SUCCESS;
  1495. BOOL bEmptyDatabase = FALSE;
  1496. BOOL bRemoveAvailableLicense = FALSE;
  1497. if( __TlsDbWorkSpace::g_JbInstance.IsValid() == FALSE )
  1498. {
  1499. //
  1500. // Initialize Jet Instance
  1501. //
  1502. bSuccess = TLSJbInstanceInit(
  1503. __TlsDbWorkSpace::g_JbInstance,
  1504. pszChkPointDirPath,
  1505. pszTempDirPath,
  1506. pszLogDirPath
  1507. );
  1508. if(bSuccess == FALSE)
  1509. {
  1510. status = GetLastError();
  1511. TLSASSERT(FALSE);
  1512. goto cleanup;
  1513. }
  1514. }
  1515. //
  1516. // Upgrade the database
  1517. //
  1518. status = TLSUpgradeDatabase(
  1519. __TlsDbWorkSpace::g_JbInstance,
  1520. pszDbFile,
  1521. pszUserName,
  1522. pszPassword
  1523. );
  1524. if( status == TLS_E_BETADATABSE ||
  1525. status == TLS_E_INCOMPATIBLEDATABSE ||
  1526. (TLS_ERROR(status) == TRUE && bStartEmptyIfError == TRUE) )
  1527. {
  1528. if(status == TLS_E_BETADATABSE)
  1529. {
  1530. CleanSetupLicenseServer();
  1531. }
  1532. //
  1533. // bad database, try to save a copy of it and
  1534. // restart from scratch
  1535. //
  1536. TLSLogInfoEvent(status);
  1537. TCHAR szTmpFileName[2*MAX_PATH+1];
  1538. bSuccess = TLSGenerateLSDBBackupFileName(
  1539. pszTempDirPath,
  1540. szTmpFileName
  1541. );
  1542. if (bSuccess)
  1543. {
  1544. bSuccess = MoveFileEx(
  1545. pszDbFile,
  1546. szTmpFileName,
  1547. MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED
  1548. );
  1549. }
  1550. if(bSuccess == TRUE)
  1551. {
  1552. LPCTSTR pString[1];
  1553. pString[0] = szTmpFileName;
  1554. TLSLogEventString(
  1555. EVENTLOG_INFORMATION_TYPE,
  1556. TLS_I_RENAME_DBFILE,
  1557. sizeof(pString)/sizeof(pString[0]),
  1558. pString
  1559. );
  1560. status = TLSUpgradeDatabase(
  1561. __TlsDbWorkSpace::g_JbInstance,
  1562. pszDbFile,
  1563. pszUserName,
  1564. pszPassword
  1565. );
  1566. }
  1567. else
  1568. {
  1569. //
  1570. // Can't rename this file, log an error and exit.
  1571. //
  1572. LPCTSTR pString[1];
  1573. pString[0] = pszDbFile;
  1574. TLSLogEventString(
  1575. EVENTLOG_ERROR_TYPE,
  1576. TLS_E_RENAME_DBFILE,
  1577. sizeof(pString)/sizeof(pString[0]),
  1578. pString
  1579. );
  1580. status = TLS_E_RENAME_DBFILE;
  1581. }
  1582. }
  1583. if(TLS_ERROR(status) == TRUE)
  1584. {
  1585. goto cleanup;
  1586. }
  1587. if(status == TLS_I_CREATE_EMPTYDATABASE)
  1588. {
  1589. // we startup from scratch, ignore ID checking
  1590. bEmptyDatabase = TRUE;
  1591. }
  1592. else if(status == TLS_W_NOTOWNER_DATABASE)
  1593. {
  1594. #if ENFORCE_LICENSING
  1595. // not owner of database or database version mismatch, we need to kill all the
  1596. // available licenses
  1597. bRemoveAvailableLicense = TRUE;
  1598. #endif
  1599. }
  1600. status = ERROR_SUCCESS;
  1601. //
  1602. // Allocate one handle to verify database
  1603. //
  1604. bSuccess = InitializeWorkSpacePool(
  1605. 1,
  1606. pszDbFile,
  1607. pszUserName,
  1608. pszPassword,
  1609. pszChkPointDirPath,
  1610. pszTempDirPath,
  1611. pszLogDirPath,
  1612. TRUE
  1613. );
  1614. if(bSuccess == FALSE)
  1615. {
  1616. status = GetLastError();
  1617. TLSASSERT(FALSE);
  1618. goto cleanup;
  1619. }
  1620. if((g_DbWorkSpace = AllocateWorkSpace(g_GeneralDbTimeout)) == NULL)
  1621. {
  1622. TLSLogEvent(
  1623. EVENTLOG_ERROR_TYPE,
  1624. TLS_E_SERVICEINIT,
  1625. status = TLS_E_ALLOCATE_HANDLE
  1626. );
  1627. goto cleanup;
  1628. }
  1629. //
  1630. // Initialize next keypack id and license id
  1631. //
  1632. if(TLSDBGetMaxKeyPackId(g_DbWorkSpace, (DWORD *)&g_NextKeyPackId) == FALSE)
  1633. {
  1634. status=GetLastError();
  1635. if(IS_JB_ERROR(status))
  1636. {
  1637. LPTSTR pString = NULL;
  1638. TLSGetESEError(
  1639. GET_JB_ERROR_CODE(status),
  1640. &pString
  1641. );
  1642. TLSLogEvent(
  1643. EVENTLOG_ERROR_TYPE,
  1644. TLS_E_SERVICEINIT,
  1645. TLS_E_JB_BASE,
  1646. GET_JB_ERROR_CODE(status),
  1647. (pString != NULL) ? pString : _TEXT("")
  1648. );
  1649. if(pString != NULL)
  1650. {
  1651. LocalFree(pString);
  1652. }
  1653. }
  1654. else
  1655. {
  1656. TLSLogEvent(
  1657. EVENTLOG_ERROR_TYPE,
  1658. TLS_E_SERVICEINIT,
  1659. status
  1660. );
  1661. }
  1662. goto cleanup;
  1663. }
  1664. if(!TLSDBGetMaxLicenseId(g_DbWorkSpace, (DWORD *)&g_NextLicenseId))
  1665. {
  1666. status=GetLastError();
  1667. if(IS_JB_ERROR(status))
  1668. {
  1669. LPTSTR pString = NULL;
  1670. TLSGetESEError(
  1671. GET_JB_ERROR_CODE(status),
  1672. &pString
  1673. );
  1674. TLSLogEvent(
  1675. EVENTLOG_ERROR_TYPE,
  1676. TLS_E_SERVICEINIT,
  1677. TLS_E_JB_BASE,
  1678. GET_JB_ERROR_CODE(status),
  1679. (pString != NULL) ? pString : _TEXT("")
  1680. );
  1681. if(pString != NULL)
  1682. {
  1683. LocalFree(pString);
  1684. }
  1685. }
  1686. else
  1687. {
  1688. TLSLogEvent(
  1689. EVENTLOG_ERROR_TYPE,
  1690. TLS_E_SERVICEINIT,
  1691. status
  1692. );
  1693. }
  1694. goto cleanup;
  1695. }
  1696. DBGPrintf(
  1697. DBG_INFORMATION,
  1698. DBG_FACILITY_INIT,
  1699. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  1700. _TEXT("Next KeyPack ID - %d, Next License ID - %d\n"),
  1701. g_NextKeyPackId,
  1702. g_NextLicenseId
  1703. );
  1704. //
  1705. // Verify database status with last run status
  1706. //
  1707. {
  1708. LPTLServerLastRun lpLastRun = NULL;
  1709. DWORD cbByte=0;
  1710. PBYTE pbByte=NULL;
  1711. status = RetrieveKey(
  1712. LSERVER_LSA_LASTRUN,
  1713. &pbByte,
  1714. &cbByte
  1715. );
  1716. lpLastRun = (LPTLServerLastRun)pbByte;
  1717. if( status == ERROR_SUCCESS && lpLastRun != NULL )
  1718. {
  1719. DBGPrintf(
  1720. DBG_INFORMATION,
  1721. DBG_FACILITY_INIT,
  1722. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  1723. _TEXT("Last run status : Next KeyPack ID - %d, Next License ID - %d\n"),
  1724. lpLastRun->dwMaxKeyPackId,
  1725. lpLastRun->dwMaxLicenseId
  1726. );
  1727. //
  1728. // Verify no 'copy' database
  1729. //
  1730. if( bCheckDBStatus == TRUE &&
  1731. bEmptyDatabase == FALSE &&
  1732. bRemoveAvailableLicense == FALSE &&
  1733. lpLastRun->dwMaxKeyPackId != 0 &&
  1734. lpLastRun->dwMaxLicenseId != 0 )
  1735. {
  1736. // enforce version will remove all available licenses
  1737. #if ENFORCE_LICENSING
  1738. if( lpLastRun->dwMaxKeyPackId != g_NextKeyPackId ||
  1739. lpLastRun->dwMaxLicenseId != g_NextLicenseId)
  1740. {
  1741. TLSLogWarningEvent(TLS_W_INCONSISTENT_STATUS);
  1742. bRemoveAvailableLicense = TRUE;
  1743. }
  1744. #endif
  1745. }
  1746. else
  1747. {
  1748. g_ftLastShutdownTime = lpLastRun->ftLastShutdownTime;
  1749. }
  1750. }
  1751. if(pbByte)
  1752. {
  1753. LocalFree(pbByte);
  1754. }
  1755. //
  1756. // overwrite last run status to 0 so if we crash,
  1757. // check won't get kick it
  1758. //
  1759. TLServerLastRun LastRun;
  1760. memset(&LastRun, 0, sizeof(LastRun));
  1761. LastRun.ftLastShutdownTime = g_ftLastShutdownTime;
  1762. StoreKey(
  1763. LSERVER_LSA_LASTRUN,
  1764. (PBYTE)&LastRun,
  1765. sizeof(TLServerLastRun)
  1766. );
  1767. }
  1768. g_NextKeyPackId++;
  1769. g_NextLicenseId++;
  1770. //
  1771. // remove available licenses
  1772. if(bRemoveAvailableLicense == TRUE)
  1773. {
  1774. status = TLSRemoveLicensesFromInvalidDatabase(
  1775. g_DbWorkSpace
  1776. );
  1777. if(status != ERROR_SUCCESS)
  1778. {
  1779. goto cleanup;
  1780. }
  1781. }
  1782. //
  1783. // Insert a keypack for Terminal Service Certificate.
  1784. //
  1785. status = TLSAddTermServCertificatePack(g_DbWorkSpace, bLogWarning);
  1786. if(status != ERROR_SUCCESS && status != TLS_E_DUPLICATE_RECORD)
  1787. {
  1788. TLSLogEvent(
  1789. EVENTLOG_ERROR_TYPE,
  1790. TLS_E_SERVICEINIT,
  1791. status = TLS_E_UPGRADE_DATABASE
  1792. );
  1793. goto cleanup;
  1794. }
  1795. //
  1796. // Allocate rest of the workspace handle
  1797. //
  1798. bSuccess = InitializeWorkSpacePool(
  1799. dwMaxDbHandles,
  1800. pszDbFile,
  1801. pszUserName,
  1802. pszPassword,
  1803. NULL,
  1804. NULL,
  1805. NULL,
  1806. FALSE
  1807. );
  1808. //
  1809. if(bSuccess == FALSE && GetNumberOfWorkSpaceHandle() < DB_MIN_HANDLE_NEEDED)
  1810. {
  1811. status = GetLastError();
  1812. }
  1813. // This is a temporary workaround to change keypack version in the database from 5.1 to 5.2 to accomodate for
  1814. // Beta 3 and interim builds of LS. Only in the absence of Registry key we will convert the 5.1 keypacks to 5.2
  1815. HKEY hKey = NULL;
  1816. status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WHISTLER_CAL, 0,
  1817. KEY_ALL_ACCESS, &hKey);
  1818. if (status == ERROR_SUCCESS)
  1819. {
  1820. RegCloseKey(hKey);
  1821. }
  1822. else
  1823. {
  1824. status = UpgradeKeyPackVersion(g_DbWorkSpace);
  1825. }
  1826. cleanup:
  1827. return status;
  1828. }
  1829. ///////////////////////////////////////////////////////////////
  1830. DWORD
  1831. TLSStartLSDbWorkspaceEngine(
  1832. BOOL bChkDbStatus,
  1833. BOOL bIgnoreRestoreFile,
  1834. BOOL bIgnoreFileTimeChk,
  1835. BOOL bLogWarning
  1836. )
  1837. /*++
  1838. bChkDbStatus : Match next LKP ID and License ID with LSA
  1839. bIgnoreRestoreFile : FALSE if try to open DB file under EXPORT, TRUE otherwise
  1840. bLogWarning : TRUE if log low license count warning, FALSE otherwise.
  1841. note, this parameter is ignore in enforce build.
  1842. --*/
  1843. {
  1844. TCHAR szDbRestoreFile[MAX_PATH+1];
  1845. WIN32_FIND_DATA RestoreFileAttr;
  1846. WIN32_FIND_DATA LsDbFileAttr;
  1847. BOOL bSuccess = TRUE;
  1848. DWORD dwStatus = ERROR_SUCCESS;
  1849. TCHAR szDbBackupFile[MAX_PATH+1];
  1850. TCHAR szDbRestoreTmpFile[MAX_PATH+1];
  1851. if(bIgnoreRestoreFile == TRUE)
  1852. {
  1853. DBGPrintf(
  1854. DBG_INFORMATION,
  1855. DBG_FACILITY_INIT,
  1856. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  1857. _TEXT("Ignore restore file\n")
  1858. );
  1859. goto open_existing;
  1860. }
  1861. //----------------------------------------------------------
  1862. //
  1863. // Check database file in the export directory.
  1864. //
  1865. //----------------------------------------------------------
  1866. if(MAX_PATH < (_tcslen(g_szDatabaseDir)+_tcslen(TLSBACKUP_EXPORT_DIR)+ _tcslen(g_szDatabaseFname) + 1))
  1867. {
  1868. dwStatus = E_OUTOFMEMORY;
  1869. goto open_existing;
  1870. }
  1871. _tcscpy(szDbRestoreFile, g_szDatabaseDir);
  1872. _tcscat(szDbRestoreFile, TLSBACKUP_EXPORT_DIR);
  1873. _tcscat(szDbRestoreFile, _TEXT("\\"));
  1874. _tcscat(szDbRestoreFile, g_szDatabaseFname);
  1875. bSuccess = FileExists(
  1876. szDbRestoreFile,
  1877. &RestoreFileAttr
  1878. );
  1879. if(bSuccess == FALSE)
  1880. {
  1881. goto open_existing;
  1882. }
  1883. bSuccess = FileExists(
  1884. g_szDatabaseFile,
  1885. &LsDbFileAttr
  1886. );
  1887. if(bSuccess == FALSE)
  1888. {
  1889. DBGPrintf(
  1890. DBG_INFORMATION,
  1891. DBG_FACILITY_INIT,
  1892. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  1893. _TEXT("No existing database file, use restored file...\n")
  1894. );
  1895. //
  1896. // Database file does not exist, move the restored file over and open it.
  1897. //
  1898. bSuccess = MoveFileEx(
  1899. szDbRestoreFile,
  1900. g_szDatabaseFile,
  1901. MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH
  1902. );
  1903. if(bSuccess == FALSE)
  1904. {
  1905. DBGPrintf(
  1906. DBG_INFORMATION,
  1907. DBG_FACILITY_INIT,
  1908. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  1909. _TEXT("Failed to move restore to existing db file - %d\n"),
  1910. GetLastError()
  1911. );
  1912. // can't move restore file, don't use the restore file,
  1913. // startup with empty database
  1914. dwStatus = GetLastError();
  1915. LPCTSTR pString[1];
  1916. pString[0] = szDbRestoreFile;
  1917. TLSLogEventString(
  1918. EVENTLOG_WARNING_TYPE,
  1919. TLS_E_DBRESTORE_MOVEFILE,
  1920. 1,
  1921. pString
  1922. );
  1923. }
  1924. else
  1925. {
  1926. TLSLogInfoEvent(TLS_I_USE_DBRESTOREFILE);
  1927. }
  1928. #if DBG
  1929. EnsureExclusiveAccessToDbFile( g_szDatabaseFile );
  1930. #endif
  1931. goto open_existing;
  1932. }
  1933. //
  1934. // Compare file's last modification time, if existing database file is newer
  1935. // than restore one, log event and continue opening existing file
  1936. //
  1937. if( bIgnoreFileTimeChk == FALSE )
  1938. {
  1939. if(CompareFileTime(&(RestoreFileAttr.ftLastWriteTime), &(LsDbFileAttr.ftLastWriteTime)) <= 0 )
  1940. {
  1941. DBGPrintf(
  1942. DBG_INFORMATION,
  1943. DBG_FACILITY_INIT,
  1944. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  1945. _TEXT("Restore file is too old...\n"),
  1946. GetLastError()
  1947. );
  1948. //TLSLogInfoEvent(TLS_I_DBRESTORE_OLD);
  1949. goto open_existing;
  1950. }
  1951. }
  1952. //
  1953. // make a backup copy of existing database file.
  1954. //
  1955. bSuccess = TLSGenerateLSDBBackupFileName(
  1956. g_szDatabaseDir,
  1957. szDbBackupFile
  1958. );
  1959. if (bSuccess)
  1960. {
  1961. DBGPrintf(
  1962. DBG_INFORMATION,
  1963. DBG_FACILITY_INIT,
  1964. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  1965. _TEXT("Existing database file has been backup to %s\n"),
  1966. szDbBackupFile
  1967. );
  1968. bSuccess = MoveFileEx(
  1969. g_szDatabaseFile,
  1970. szDbBackupFile,
  1971. MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH
  1972. );
  1973. }
  1974. if(bSuccess == FALSE)
  1975. {
  1976. DBGPrintf(
  1977. DBG_INFORMATION,
  1978. DBG_FACILITY_INIT,
  1979. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  1980. _TEXT("Failed to backup existing database file - %d\n"),
  1981. GetLastError()
  1982. );
  1983. //
  1984. // Can't save a copy of existing database file
  1985. // Log an error and continue to open using existing database
  1986. //
  1987. LPCTSTR pString[1];
  1988. pString[0] = g_szDatabaseFile;
  1989. TLSLogEventString(
  1990. EVENTLOG_WARNING_TYPE,
  1991. TLS_W_DBRESTORE_SAVEEXISTING,
  1992. 1,
  1993. pString
  1994. );
  1995. goto open_existing;
  1996. }
  1997. //
  1998. // Rename restore file and then try to open the restore file.
  1999. //
  2000. bSuccess = MoveFileEx(
  2001. szDbRestoreFile,
  2002. g_szDatabaseFile,
  2003. MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH
  2004. );
  2005. if(bSuccess == TRUE)
  2006. {
  2007. #if DBG
  2008. EnsureExclusiveAccessToDbFile( g_szDatabaseFile );
  2009. #endif
  2010. //
  2011. // Open the restore database file
  2012. //
  2013. dwStatus = TLSStartupLSDB(
  2014. bChkDbStatus,
  2015. g_dwMaxDbHandles,
  2016. FALSE,
  2017. bLogWarning,
  2018. g_szDatabaseDir,
  2019. g_szDatabaseDir,
  2020. g_szDatabaseDir,
  2021. g_szDatabaseFile,
  2022. g_szDbUser,
  2023. g_szDbPwd
  2024. );
  2025. if(dwStatus == ERROR_SUCCESS)
  2026. {
  2027. //
  2028. // Log event indicating we open the restore file, existing
  2029. // database file has been saved as ...
  2030. //
  2031. LPCTSTR pString[1];
  2032. pString[0] = szDbBackupFile;
  2033. TLSLogEventString(
  2034. EVENTLOG_INFORMATION_TYPE,
  2035. TLS_I_OPENRESTOREDBFILE,
  2036. 1,
  2037. pString
  2038. );
  2039. return dwStatus;
  2040. }
  2041. }
  2042. //
  2043. // Can't open the restore db file or MoveFileEx() failed
  2044. //
  2045. bSuccess = TLSGenerateLSDBBackupFileName(
  2046. g_szDatabaseDir,
  2047. szDbRestoreTmpFile
  2048. );
  2049. if (bSuccess)
  2050. {
  2051. DBGPrintf(
  2052. DBG_INFORMATION,
  2053. DBG_FACILITY_INIT,
  2054. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  2055. _TEXT("Backup restore file to %s\n"),
  2056. szDbRestoreTmpFile
  2057. );
  2058. bSuccess = MoveFileEx(
  2059. g_szDatabaseFile,
  2060. szDbRestoreTmpFile,
  2061. MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH
  2062. );
  2063. }
  2064. if(bSuccess == FALSE)
  2065. {
  2066. // failed to backup restore db file, delete it
  2067. bSuccess = DeleteFile(g_szDatabaseFile);
  2068. TLSLogErrorEvent(TLS_E_RESTOREDBFILE_OPENFAIL);
  2069. }
  2070. else
  2071. {
  2072. LPCTSTR pString[1];
  2073. pString[0] = szDbRestoreTmpFile;
  2074. TLSLogEventString(
  2075. EVENTLOG_ERROR_TYPE,
  2076. TLS_E_RESTOREDBFILE_OPENFAIL_SAVED,
  2077. 1,
  2078. pString
  2079. );
  2080. }
  2081. DBGPrintf(
  2082. DBG_INFORMATION,
  2083. DBG_FACILITY_INIT,
  2084. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  2085. _TEXT("Restore original database file %s to %s\n"),
  2086. szDbBackupFile,
  2087. g_szDatabaseFile
  2088. );
  2089. //
  2090. // Restore the existing database file
  2091. //
  2092. bSuccess = MoveFileEx(
  2093. szDbBackupFile,
  2094. g_szDatabaseFile,
  2095. MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH
  2096. );
  2097. if(bSuccess == FALSE)
  2098. {
  2099. DBGPrintf(
  2100. DBG_INFORMATION,
  2101. DBG_FACILITY_INIT,
  2102. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  2103. _TEXT("failed to restore original DB file - %d\n"),
  2104. GetLastError()
  2105. );
  2106. TLSASSERT(FALSE);
  2107. // this is really bad, continue with empty database file.
  2108. }
  2109. #if DBG
  2110. EnsureExclusiveAccessToDbFile( g_szDatabaseFile );
  2111. #endif
  2112. open_existing:
  2113. return TLSStartupLSDB(
  2114. bChkDbStatus,
  2115. g_dwMaxDbHandles,
  2116. TRUE,
  2117. bLogWarning,
  2118. g_szDatabaseDir,
  2119. g_szDatabaseDir,
  2120. g_szDatabaseDir,
  2121. g_szDatabaseFile,
  2122. g_szDbUser,
  2123. g_szDbPwd
  2124. );
  2125. }
  2126. ///////////////////////////////////////////////////////////////
  2127. DWORD
  2128. TLSLoadRuntimeParameters()
  2129. /*++
  2130. --*/
  2131. {
  2132. HKEY hKey = NULL;
  2133. DWORD dwStatus = ERROR_SUCCESS;
  2134. DWORD dwKeyType;
  2135. TCHAR szDbPath[MAX_PATH+1];;
  2136. TCHAR szDbFileName[MAX_PATH+1];
  2137. DWORD dwBuffer;
  2138. DWORD cbByte = 0;
  2139. PBYTE pbByte = NULL;
  2140. //-------------------------------------------------------------------
  2141. //
  2142. // Open HKLM\system\currentcontrolset\sevices\termservlicensing\parameters
  2143. //
  2144. //-------------------------------------------------------------------
  2145. dwStatus =RegCreateKeyEx(
  2146. HKEY_LOCAL_MACHINE,
  2147. LSERVER_REGISTRY_BASE _TEXT(SZSERVICENAME) _TEXT("\\") LSERVER_PARAMETERS,
  2148. 0,
  2149. NULL,
  2150. REG_OPTION_NON_VOLATILE,
  2151. KEY_ALL_ACCESS,
  2152. NULL,
  2153. &hKey,
  2154. NULL
  2155. );
  2156. if(dwStatus != ERROR_SUCCESS)
  2157. {
  2158. TLSLogEvent(
  2159. EVENTLOG_ERROR_TYPE,
  2160. TLS_E_SERVICEINIT,
  2161. TLS_E_ACCESS_REGISTRY,
  2162. dwStatus
  2163. );
  2164. dwStatus = TLS_E_INIT_GENERAL;
  2165. goto cleanup;
  2166. }
  2167. //-------------------------------------------------------------------
  2168. //
  2169. // Get database file location and file name
  2170. //
  2171. //-------------------------------------------------------------------
  2172. dwBuffer = sizeof(szDbPath) / sizeof(szDbPath[0]);
  2173. dwStatus = RegQueryValueEx(
  2174. hKey,
  2175. LSERVER_PARAMETERS_DBPATH,
  2176. NULL,
  2177. NULL,
  2178. (LPBYTE)szDbPath,
  2179. &dwBuffer
  2180. );
  2181. if(dwStatus != ERROR_SUCCESS)
  2182. {
  2183. //
  2184. // need to startup so use default value,
  2185. //
  2186. _tcscpy(
  2187. szDbPath,
  2188. LSERVER_DEFAULT_DBPATH
  2189. );
  2190. }
  2191. //
  2192. // Get database file name
  2193. //
  2194. dwBuffer = sizeof(szDbFileName) / sizeof(szDbFileName[0]);
  2195. dwStatus = RegQueryValueEx(
  2196. hKey,
  2197. LSERVER_PARAMETERS_DBFILE,
  2198. NULL,
  2199. NULL,
  2200. (LPBYTE)szDbFileName,
  2201. &dwBuffer
  2202. );
  2203. if(dwStatus != ERROR_SUCCESS)
  2204. {
  2205. //
  2206. // Use default value.
  2207. //
  2208. _tcscpy(
  2209. szDbFileName,
  2210. LSERVER_DEFAULT_EDB
  2211. );
  2212. }
  2213. _tcscpy(g_szDatabaseFname, szDbFileName);
  2214. //
  2215. // Always expand DB Path.
  2216. //
  2217. dwStatus = ExpandEnvironmentStrings(
  2218. szDbPath,
  2219. g_szDatabaseDir,
  2220. sizeof(g_szDatabaseDir) / sizeof(g_szDatabaseDir[0])
  2221. );
  2222. if(dwStatus == 0)
  2223. {
  2224. // can't expand environment variable, error out.
  2225. TLSLogEvent(
  2226. EVENTLOG_ERROR_TYPE,
  2227. TLS_E_SERVICEINIT,
  2228. TLS_E_LOCALDATABASEFILE,
  2229. dwStatus = GetLastError()
  2230. );
  2231. goto cleanup;
  2232. }
  2233. if(g_szDatabaseDir[_tcslen(g_szDatabaseDir) - 1] != _TEXT('\\'))
  2234. {
  2235. // JetBlue needs this.
  2236. _tcscat(g_szDatabaseDir, _TEXT("\\"));
  2237. }
  2238. //
  2239. // Full path to database file
  2240. //
  2241. _tcscpy(g_szDatabaseFile, g_szDatabaseDir);
  2242. _tcscat(g_szDatabaseFile, szDbFileName);
  2243. //
  2244. // Database file user and password
  2245. //
  2246. dwBuffer = sizeof(g_szDbUser) / sizeof(g_szDbUser[0]);
  2247. dwStatus = RegQueryValueEx(
  2248. hKey,
  2249. LSERVER_PARAMETERS_USER,
  2250. NULL,
  2251. NULL,
  2252. (LPBYTE)g_szDbUser,
  2253. &dwBuffer
  2254. );
  2255. // password is rendomly generated
  2256. dwStatus = RetrieveKey(
  2257. LSERVER_LSA_PASSWORD_KEYNAME,
  2258. &pbByte,
  2259. &cbByte
  2260. );
  2261. // backward compatibilty
  2262. if(dwStatus != ERROR_SUCCESS)
  2263. {
  2264. //
  2265. // Load password from registry or default to 'default' password
  2266. //
  2267. dwBuffer = sizeof(g_szDbPwd) / sizeof(g_szDbPwd[0]);
  2268. dwStatus = RegQueryValueEx(
  2269. hKey,
  2270. LSERVER_PARAMETERS_PWD,
  2271. NULL,
  2272. NULL,
  2273. (LPBYTE)g_szDbPwd,
  2274. &dwBuffer
  2275. );
  2276. }
  2277. else
  2278. {
  2279. //
  2280. // save info into global variable
  2281. //
  2282. memset(g_szDbPwd, 0, sizeof(g_szDbPwd));
  2283. memcpy((PBYTE)g_szDbPwd, pbByte, min(cbByte, sizeof(g_szDbPwd)));
  2284. }
  2285. if(pbByte != NULL)
  2286. {
  2287. LocalFree(pbByte);
  2288. }
  2289. //--------------------------------------------------------------------
  2290. //
  2291. // Work Object Parameters
  2292. //
  2293. //--------------------------------------------------------------------
  2294. dwBuffer = sizeof(g_dwTlsJobInterval);
  2295. dwStatus = RegQueryValueEx(
  2296. hKey,
  2297. LSERVER_PARAMETERS_WORKINTERVAL,
  2298. NULL,
  2299. NULL,
  2300. (LPBYTE)&g_dwTlsJobInterval,
  2301. &dwBuffer
  2302. );
  2303. if(dwStatus != ERROR_SUCCESS)
  2304. {
  2305. g_dwTlsJobInterval = DEFAULT_JOB_INTERVAL;
  2306. }
  2307. dwBuffer = sizeof(g_dwTlsJobRetryTimes);
  2308. dwStatus = RegQueryValueEx(
  2309. hKey,
  2310. LSERVER_PARAMETERS_RETRYTIMES,
  2311. NULL,
  2312. NULL,
  2313. (LPBYTE)&g_dwTlsJobRetryTimes,
  2314. &dwBuffer
  2315. );
  2316. if(dwStatus != ERROR_SUCCESS)
  2317. {
  2318. g_dwTlsJobRetryTimes = DEFAULT_JOB_RETRYTIMES;
  2319. }
  2320. dwBuffer=sizeof(g_dwTlsJobRestartTime);
  2321. dwStatus = RegQueryValueEx(
  2322. hKey,
  2323. LSERVER_PARAMETERS_WORKRESTART,
  2324. NULL,
  2325. NULL,
  2326. (LPBYTE)&g_dwTlsJobRestartTime,
  2327. &dwBuffer
  2328. );
  2329. if(dwStatus != ERROR_SUCCESS)
  2330. {
  2331. g_dwTlsJobRestartTime = DEFAULT_JOB_INTERVAL;
  2332. }
  2333. //---------------------------------------------------
  2334. //
  2335. // load low license warning count
  2336. //
  2337. //---------------------------------------------------
  2338. dwBuffer = sizeof(g_LowLicenseCountWarning);
  2339. dwStatus = RegQueryValueEx(
  2340. hKey,
  2341. LSERVER_PARAMETERS_LOWLICENSEWARNING,
  2342. NULL,
  2343. &dwKeyType,
  2344. NULL,
  2345. &dwBuffer
  2346. );
  2347. if(dwStatus == ERROR_SUCCESS && dwKeyType == REG_DWORD)
  2348. {
  2349. dwStatus = RegQueryValueEx(
  2350. hKey,
  2351. LSERVER_PARAMETERS_LOWLICENSEWARNING,
  2352. NULL,
  2353. &dwKeyType,
  2354. (LPBYTE)&g_LowLicenseCountWarning,
  2355. &dwBuffer
  2356. );
  2357. }
  2358. //---------------------------------------------------
  2359. //
  2360. // Temp. license grace period
  2361. //
  2362. //---------------------------------------------------
  2363. dwBuffer = sizeof(g_GracePeriod);
  2364. dwStatus = RegQueryValueEx(
  2365. hKey,
  2366. LSERVER_PARAMETERS_GRACEPERIOD,
  2367. NULL,
  2368. &dwKeyType,
  2369. NULL,
  2370. &dwBuffer
  2371. );
  2372. if(dwStatus == ERROR_SUCCESS && dwKeyType == REG_DWORD)
  2373. {
  2374. dwStatus = RegQueryValueEx(
  2375. hKey,
  2376. LSERVER_PARAMETERS_GRACEPERIOD,
  2377. NULL,
  2378. &dwKeyType,
  2379. (LPBYTE)&g_GracePeriod,
  2380. &dwBuffer
  2381. );
  2382. }
  2383. if(g_GracePeriod > GRACE_PERIOD)
  2384. {
  2385. // grace period can be greated than this.
  2386. g_GracePeriod = GRACE_PERIOD;
  2387. }
  2388. //
  2389. // Are we allow to issue temp. license
  2390. //
  2391. dwBuffer = sizeof(g_IssueTemporayLicense);
  2392. dwStatus = RegQueryValueEx(
  2393. hKey,
  2394. LSERVER_PARAMETERS_ISSUETEMPLICENSE,
  2395. NULL,
  2396. &dwKeyType,
  2397. NULL,
  2398. &dwBuffer
  2399. );
  2400. if(dwStatus == ERROR_SUCCESS && dwKeyType == REG_DWORD)
  2401. {
  2402. dwStatus = RegQueryValueEx(
  2403. hKey,
  2404. LSERVER_PARAMETERS_ISSUETEMPLICENSE,
  2405. NULL,
  2406. &dwKeyType,
  2407. (LPBYTE)&g_IssueTemporayLicense,
  2408. &dwBuffer
  2409. );
  2410. }
  2411. //------------------------------------------------------
  2412. //
  2413. // Timeout value if can't allocate a DB handle
  2414. //
  2415. //------------------------------------------------------
  2416. //
  2417. // Timeout for allocating a write handle
  2418. //
  2419. dwBuffer = sizeof(g_GeneralDbTimeout);
  2420. dwStatus = RegQueryValueEx(
  2421. hKey,
  2422. LSERVER_PARAMETERS_DBTIMEOUT,
  2423. NULL,
  2424. &dwKeyType,
  2425. NULL,
  2426. &dwBuffer
  2427. );
  2428. if(dwStatus == ERROR_SUCCESS && dwKeyType == REG_DWORD)
  2429. {
  2430. dwStatus = RegQueryValueEx(
  2431. hKey,
  2432. LSERVER_PARAMETERS_DBTIMEOUT,
  2433. NULL,
  2434. &dwKeyType,
  2435. (LPBYTE)&g_GeneralDbTimeout,
  2436. &dwBuffer
  2437. );
  2438. }
  2439. //
  2440. // Timeout for read handle
  2441. //
  2442. dwBuffer = sizeof(g_EnumDbTimeout);
  2443. dwStatus = RegQueryValueEx(
  2444. hKey,
  2445. LSERVER_PARAMETERS_EDBTIMEOUT,
  2446. NULL,
  2447. &dwKeyType,
  2448. NULL,
  2449. &dwBuffer
  2450. );
  2451. if(dwStatus == ERROR_SUCCESS && dwKeyType == REG_DWORD)
  2452. {
  2453. dwStatus = RegQueryValueEx(
  2454. hKey,
  2455. LSERVER_PARAMETERS_EDBTIMEOUT,
  2456. NULL,
  2457. &dwKeyType,
  2458. (LPBYTE)&g_EnumDbTimeout,
  2459. &dwBuffer
  2460. );
  2461. }
  2462. //------------------------------------------------------
  2463. //
  2464. // Number of database handles
  2465. //
  2466. //------------------------------------------------------
  2467. dwBuffer = sizeof(g_dwMaxDbHandles);
  2468. dwStatus = RegQueryValueEx(
  2469. hKey,
  2470. LSERVER_PARAMETERS_MAXDBHANDLES,
  2471. NULL,
  2472. &dwKeyType,
  2473. NULL,
  2474. &dwBuffer
  2475. );
  2476. if(dwStatus == ERROR_SUCCESS && dwKeyType == REG_DWORD)
  2477. {
  2478. dwStatus = RegQueryValueEx(
  2479. hKey,
  2480. LSERVER_PARAMETERS_MAXDBHANDLES,
  2481. NULL,
  2482. &dwKeyType,
  2483. (LPBYTE)&g_dwMaxDbHandles,
  2484. &dwBuffer
  2485. );
  2486. if(g_dwMaxDbHandles > DB_MAX_CONNECTIONS-1)
  2487. {
  2488. g_dwMaxDbHandles = DEFAULT_DB_CONNECTIONS;
  2489. }
  2490. }
  2491. //------------------------------------------------------
  2492. //
  2493. // Load parameters for ESENT, all parameter must be set
  2494. // and confirm to ESENT document, any error, we just
  2495. // revert back to some value we know it works.
  2496. //
  2497. //------------------------------------------------------
  2498. dwBuffer = sizeof(g_EsentMaxCacheSize);
  2499. dwStatus = RegQueryValueEx(
  2500. hKey,
  2501. LSERVER_PARAMETERS_ESENTMAXCACHESIZE,
  2502. NULL,
  2503. NULL,
  2504. (LPBYTE)&g_EsentMaxCacheSize,
  2505. &dwBuffer
  2506. );
  2507. if(dwStatus == ERROR_SUCCESS)
  2508. {
  2509. dwBuffer = sizeof(g_EsentStartFlushThreshold);
  2510. dwStatus = RegQueryValueEx(
  2511. hKey,
  2512. LSERVER_PARAMETERS_ESENTSTARTFLUSH,
  2513. NULL,
  2514. NULL,
  2515. (LPBYTE)&g_EsentStartFlushThreshold,
  2516. &dwBuffer
  2517. );
  2518. if(dwStatus == ERROR_SUCCESS)
  2519. {
  2520. dwBuffer = sizeof(g_EsentStopFlushThreadhold);
  2521. dwStatus = RegQueryValueEx(
  2522. hKey,
  2523. LSERVER_PARAMETERS_ESENTSTOPFLUSH,
  2524. NULL,
  2525. NULL,
  2526. (LPBYTE)&g_EsentStopFlushThreadhold,
  2527. &dwBuffer
  2528. );
  2529. }
  2530. }
  2531. if( dwStatus != ERROR_SUCCESS ||
  2532. g_EsentStartFlushThreshold > g_EsentStopFlushThreadhold ||
  2533. g_EsentStopFlushThreadhold > g_EsentMaxCacheSize ||
  2534. g_EsentMaxCacheSize < LSERVER_PARAMETERS_ESENTMAXCACHESIZE_MIN ||
  2535. g_EsentStartFlushThreshold < LSERVER_PARAMETERS_ESENTSTARTFLUSH_MIN ||
  2536. g_EsentStopFlushThreadhold < LSERVER_PARAMETERS_ESENTSTOPFLUSH_MIN ||
  2537. g_EsentMaxCacheSize > LSERVER_PARAMETERS_ESENTMAXCACHESIZE_MAX ||
  2538. g_EsentStartFlushThreshold > LSERVER_PARAMETERS_ESENTSTARTFLUSH_MAX ||
  2539. g_EsentStopFlushThreadhold > LSERVER_PARAMETERS_ESENTSTOPFLUSH_MAX )
  2540. {
  2541. // pre-define number to let ESENT picks its number
  2542. if( g_EsentMaxCacheSize != LSERVER_PARAMETERS_USE_ESENTDEFAULT )
  2543. {
  2544. g_EsentMaxCacheSize = LSERVER_PARAMETERS_ESENTMAXCACHESIZE_DEFAULT;
  2545. g_EsentStartFlushThreshold = LSERVER_PARAMETERS_ESENTSTARTFLUSH_DEFAULT;
  2546. g_EsentStopFlushThreadhold = LSERVER_PARAMETERS_ESENTSTOPFLUSH_DEFAULT;
  2547. }
  2548. }
  2549. dwBuffer = sizeof(g_EsentMaxVerPages);
  2550. dwStatus = RegQueryValueEx(
  2551. hKey,
  2552. LSERVER_PARAMETERS_ESENTMAXVERPAGES,
  2553. NULL,
  2554. NULL,
  2555. (LPBYTE)&g_EsentMaxVerPages,
  2556. &dwBuffer
  2557. );
  2558. if ((dwStatus != ERROR_SUCCESS)
  2559. || (g_EsentMaxVerPages > LSERVER_PARAMETERS_ESENTMAXVERPAGES_MAX)
  2560. || (g_EsentMaxVerPages < LSERVER_PARAMETERS_ESENTMAXVERPAGES_MIN))
  2561. {
  2562. g_EsentMaxVerPages = LSERVER_PARAMETERS_USE_ESENTDEFAULT;
  2563. }
  2564. //------------------------------------------------------
  2565. //
  2566. // Determine role of server in enterprise
  2567. //
  2568. //------------------------------------------------------
  2569. dwBuffer = sizeof(g_SrvRole);
  2570. dwStatus = RegQueryValueEx(
  2571. hKey,
  2572. LSERVER_PARAMETERS_ROLE,
  2573. NULL,
  2574. NULL,
  2575. (LPBYTE)&g_SrvRole,
  2576. &dwBuffer
  2577. );
  2578. if(g_SrvRole & TLSERVER_ENTERPRISE_SERVER)
  2579. {
  2580. dwBuffer = sizeof(g_szScope)/sizeof(g_szScope[0]);
  2581. memset(g_szScope, 0, sizeof(g_szScope));
  2582. dwStatus = RegQueryValueEx(
  2583. hKey,
  2584. LSERVER_PARAMETERS_SCOPE,
  2585. NULL,
  2586. &dwKeyType,
  2587. (LPBYTE)g_szScope,
  2588. &dwBuffer
  2589. );
  2590. if(dwStatus != ERROR_SUCCESS)
  2591. {
  2592. // no scope is set, default to local machine name
  2593. // consider using domain name ???
  2594. LoadResourceString(
  2595. IDS_SCOPE_ENTERPRISE,
  2596. g_szScope,
  2597. sizeof(g_szScope)/sizeof(g_szScope[0])
  2598. );
  2599. }
  2600. g_pszScope = g_szScope;
  2601. }
  2602. else
  2603. {
  2604. //
  2605. // Use the workgroup or domain name as scope
  2606. //
  2607. LPWSTR pszScope;
  2608. if(GetMachineGroup(NULL, &pszScope) == FALSE)
  2609. {
  2610. TLSLogEvent(
  2611. EVENTLOG_ERROR_TYPE,
  2612. TLS_E_SERVICEINIT,
  2613. TLS_E_RETRIEVEGROUPNAME
  2614. );
  2615. goto cleanup;
  2616. }
  2617. g_pszScope = pszScope;
  2618. }
  2619. //------------------------------------------------------
  2620. //
  2621. // Reissuance Parameters
  2622. //
  2623. //------------------------------------------------------
  2624. dwBuffer = sizeof(g_dwReissueLeaseMinimum);
  2625. dwStatus = RegQueryValueEx(
  2626. hKey,
  2627. LSERVER_PARAMETERS_LEASE_MIN,
  2628. NULL,
  2629. NULL,
  2630. (LPBYTE)&g_dwReissueLeaseMinimum,
  2631. &dwBuffer
  2632. );
  2633. if (dwStatus == ERROR_SUCCESS)
  2634. {
  2635. g_dwReissueLeaseMinimum = min(g_dwReissueLeaseMinimum,
  2636. PERMANENT_LICENSE_LEASE_EXPIRE_MIN);
  2637. }
  2638. else
  2639. {
  2640. g_dwReissueLeaseMinimum = PERMANENT_LICENSE_LEASE_EXPIRE_MIN;
  2641. }
  2642. dwBuffer = sizeof(g_dwReissueLeaseRange);
  2643. dwStatus = RegQueryValueEx(
  2644. hKey,
  2645. LSERVER_PARAMETERS_LEASE_RANGE,
  2646. NULL,
  2647. NULL,
  2648. (LPBYTE)&g_dwReissueLeaseRange,
  2649. &dwBuffer
  2650. );
  2651. if (dwStatus == ERROR_SUCCESS)
  2652. {
  2653. g_dwReissueLeaseRange = min(g_dwReissueLeaseRange,
  2654. PERMANENT_LICENSE_LEASE_EXPIRE_RANGE);
  2655. g_dwReissueLeaseRange = max(g_dwReissueLeaseRange, 1);
  2656. }
  2657. else
  2658. {
  2659. g_dwReissueLeaseRange = PERMANENT_LICENSE_LEASE_EXPIRE_RANGE;
  2660. }
  2661. dwBuffer = sizeof(g_dwReissueLeaseLeeway);
  2662. dwStatus = RegQueryValueEx(
  2663. hKey,
  2664. LSERVER_PARAMETERS_LEASE_LEEWAY,
  2665. NULL,
  2666. NULL,
  2667. (LPBYTE)&g_dwReissueLeaseLeeway,
  2668. &dwBuffer
  2669. );
  2670. if (dwStatus == ERROR_SUCCESS)
  2671. {
  2672. g_dwReissueLeaseLeeway = min(g_dwReissueLeaseLeeway,
  2673. PERMANENT_LICENSE_LEASE_EXPIRE_LEEWAY);
  2674. }
  2675. else
  2676. {
  2677. g_dwReissueLeaseLeeway = PERMANENT_LICENSE_LEASE_EXPIRE_LEEWAY;
  2678. }
  2679. dwBuffer = sizeof(g_dwReissueExpireThreadSleep);
  2680. dwStatus = RegQueryValueEx(
  2681. hKey,
  2682. LSERVER_PARAMETERS_EXPIRE_THREAD_SLEEP,
  2683. NULL,
  2684. NULL,
  2685. (LPBYTE)&g_dwReissueExpireThreadSleep,
  2686. &dwBuffer
  2687. );
  2688. if (dwStatus == ERROR_SUCCESS)
  2689. {
  2690. g_dwReissueExpireThreadSleep = min(g_dwReissueExpireThreadSleep,
  2691. EXPIRE_THREAD_SLEEP_TIME);
  2692. }
  2693. else
  2694. {
  2695. g_dwReissueExpireThreadSleep = EXPIRE_THREAD_SLEEP_TIME;
  2696. }
  2697. dwStatus = ERROR_SUCCESS;
  2698. cleanup:
  2699. if(hKey != NULL)
  2700. {
  2701. RegCloseKey(hKey);
  2702. }
  2703. return dwStatus;
  2704. }
  2705. ///////////////////////////////////////////////////////////////
  2706. DWORD
  2707. TLSPrepareForBackupRestore()
  2708. {
  2709. DBGPrintf(
  2710. DBG_INFORMATION,
  2711. DBG_FACILITY_INIT,
  2712. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  2713. _TEXT("TLSPrepareForBackupRestore...\n")
  2714. );
  2715. //
  2716. // Pretend we are shutting down.
  2717. //
  2718. // ServiceSignalShutdown();
  2719. //
  2720. // first stop workmanager thread
  2721. //
  2722. TLSWorkManagerShutdown();
  2723. //
  2724. // Close all workspace and DB handle
  2725. //
  2726. #ifndef _NO_ODBC_JET
  2727. if(g_DbWorkSpace != NULL)
  2728. {
  2729. ReleaseWorkSpace(&g_DbWorkSpace);
  2730. }
  2731. #endif
  2732. CloseWorkSpacePool();
  2733. return ERROR_SUCCESS;
  2734. }
  2735. ///////////////////////////////////////////////////////////////
  2736. DWORD
  2737. TLSRestartAfterBackupRestore(
  2738. BOOL bRestartAfterbackup
  2739. )
  2740. /*++
  2741. bRestartAfterbackup : TRUE if restart after backup, FALSE if restart after restore.
  2742. --*/
  2743. {
  2744. DWORD dwStatus;
  2745. BOOL bIgnoreRestoreFile;
  2746. BOOL bIgnoreFileTimeChecking;
  2747. BOOL bLogWarning;
  2748. DBGPrintf(
  2749. DBG_INFORMATION,
  2750. DBG_FACILITY_INIT,
  2751. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  2752. _TEXT("TLSRestartAfterBackupRestore...\n")
  2753. );
  2754. //
  2755. // Reset shutdown event
  2756. //
  2757. // ServiceResetShutdownEvent();
  2758. //
  2759. // Startup DB engine.
  2760. //
  2761. bIgnoreRestoreFile = bRestartAfterbackup;
  2762. bIgnoreFileTimeChecking = (bRestartAfterbackup == FALSE); // on restore, we need to ignore file time checking
  2763. bLogWarning = bIgnoreFileTimeChecking; // log warning after restart from restore
  2764. dwStatus = TLSStartLSDbWorkspaceEngine(
  2765. TRUE,
  2766. bIgnoreRestoreFile,
  2767. bIgnoreFileTimeChecking,
  2768. bLogWarning
  2769. );
  2770. if(dwStatus == ERROR_SUCCESS)
  2771. {
  2772. dwStatus = TLSWorkManagerInit();
  2773. }
  2774. // backup/restore always shutdown namedpipe thread
  2775. InitNamedPipeThread();
  2776. TLSASSERT(dwStatus == ERROR_SUCCESS);
  2777. DBGPrintf(
  2778. DBG_INFORMATION,
  2779. DBG_FACILITY_INIT,
  2780. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  2781. _TEXT("\tTLSRestartAfterBackupRestore() returns %d\n"),
  2782. dwStatus
  2783. );
  2784. return dwStatus;
  2785. }