Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2346 lines
59 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Copyright (c) 1997-1999 Microsoft Corporation
  4. //
  5. // File: tlsjob.cpp
  6. //
  7. // Contents: Various license server job.
  8. //
  9. // History:
  10. //
  11. //---------------------------------------------------------------------------
  12. #include "pch.cpp"
  13. #include "tlsjob.h"
  14. #include "jobmgr.h"
  15. #include "wkstore.h"
  16. #include "srvlist.h"
  17. #include "kp.h"
  18. #include "clilic.h"
  19. #include "keypack.h"
  20. #include "init.h"
  21. /////////////////////////////////////////////////////////////
  22. //
  23. //
  24. //
  25. //
  26. /////////////////////////////////////////////////////////////
  27. //////////////////////////////////////////////////////////////
  28. // Various interface into global work manager
  29. //////////////////////////////////////////////////////////////
  30. CWorkManager g_WorkManager;
  31. CPersistentWorkStorage g_WorkStorage;
  32. #define MAX_ERROR_MSG_SIZE 1024
  33. DWORD
  34. TLSWorkManagerInit()
  35. /*++
  36. Abstract:
  37. Initialize work manager.
  38. Parameter:
  39. None.
  40. returns:
  41. ERROR_SUCCESS or error code.
  42. --*/
  43. {
  44. DWORD dwStatus;
  45. WorkItemTable* pWkStorageTable = NULL;
  46. //
  47. // Initialize Work Storage table
  48. //
  49. pWkStorageTable = GetWorkItemStorageTable();
  50. if(pWkStorageTable == NULL)
  51. {
  52. dwStatus = GetLastError();
  53. goto cleanup;
  54. }
  55. //
  56. // Init Persistent work storage table
  57. //
  58. if(g_WorkStorage.AttachTable(pWkStorageTable) == FALSE)
  59. {
  60. dwStatus = GetLastError();
  61. goto cleanup;
  62. }
  63. //
  64. // Initialize Work Manager
  65. //
  66. dwStatus = g_WorkManager.Startup(&g_WorkStorage);
  67. cleanup:
  68. return dwStatus;
  69. }
  70. //-----------------------------------------------------------
  71. void
  72. TLSWorkManagerShutdown()
  73. /*++
  74. Abstract:
  75. Shutdown work manager.
  76. Parameter:
  77. None:
  78. Return:
  79. None.
  80. --*/
  81. {
  82. g_WorkManager.Shutdown();
  83. }
  84. //-----------------------------------------------------------
  85. DWORD
  86. TLSWorkManagerSchedule(
  87. IN DWORD dwTime,
  88. IN CWorkObject* pJob
  89. )
  90. /*++
  91. Abstract:
  92. Schedule a job to work manager.
  93. Parameter:
  94. dwTime : Suggested time for work manager to process this job.
  95. pJob : Job to be processed/scheduled.
  96. Returns:
  97. ERROR_SUCCESS or error code.
  98. --*/
  99. {
  100. return g_WorkManager.ScheduleJob(dwTime, pJob);
  101. }
  102. //-----------------------------------------------------------
  103. BOOL
  104. TLSWorkManagerSetJobDefaults(
  105. CWorkObject* pJob
  106. )
  107. /*++
  108. Abstract:
  109. Set job's interval and retry time.
  110. Parameter:
  111. pJob : Job to be set.
  112. Returns:
  113. TRUE/FALSE.
  114. --*/
  115. {
  116. DWORD dwInterval, dwRetries, dwRestart;
  117. DWORD dwStatus = ERROR_SUCCESS;
  118. if(pJob != NULL)
  119. {
  120. GetJobObjectDefaults(&dwInterval, &dwRetries, &dwRestart);
  121. pJob->SetJobInterval(dwInterval);
  122. pJob->SetJobRetryTimes(dwRetries);
  123. pJob->SetJobRestartTime(dwRestart);
  124. }
  125. else
  126. {
  127. SetLastError(ERROR_INVALID_PARAMETER);
  128. }
  129. return dwStatus == ERROR_SUCCESS;
  130. }
  131. //-----------------------------------------------------------
  132. BOOL
  133. CopyBinaryData(
  134. IN OUT PBYTE* ppbDestData,
  135. IN OUT DWORD* pcbDestData,
  136. IN PBYTE pbSrcData,
  137. IN DWORD cbSrcData
  138. )
  139. /*++
  140. Abstract:
  141. Internal routine to copy a binary data from one buffer
  142. to another.
  143. Parameters:
  144. ppbDestData: Pointer to pointer...
  145. pcbDestData:
  146. pbSrcData:
  147. cbSrcData:
  148. Return:
  149. TRUE if successful, FALSE otherwise.
  150. ++*/
  151. {
  152. PBYTE pbTarget = NULL;
  153. if( ppbDestData == NULL || pcbDestData == NULL ||
  154. pbSrcData == NULL || cbSrcData == 0 )
  155. {
  156. SetLastError(ERROR_INVALID_PARAMETER);
  157. return FALSE;
  158. }
  159. pbTarget = *ppbDestData;
  160. //
  161. // would be nice to get the actual size of memory allocated
  162. //
  163. if( *ppbDestData == NULL || LocalSize(*ppbDestData) < cbSrcData )
  164. {
  165. if(*ppbDestData == NULL)
  166. {
  167. pbTarget = (PBYTE)AllocateMemory(cbSrcData);
  168. }
  169. else
  170. {
  171. pbTarget = (PBYTE)ReallocateMemory(*ppbDestData, cbSrcData);
  172. }
  173. }
  174. if(pbTarget != NULL)
  175. {
  176. memcpy(
  177. pbTarget,
  178. pbSrcData,
  179. cbSrcData
  180. );
  181. *pcbDestData = cbSrcData;
  182. *ppbDestData = pbTarget;
  183. }
  184. return pbTarget != NULL;
  185. }
  186. //////////////////////////////////////////////////////////////////////////
  187. //
  188. // CAnnounceLsServer
  189. //
  190. //////////////////////////////////////////////////////////////////////////
  191. BOOL
  192. CAnnounceLserver::VerifyWorkObjectData(
  193. IN BOOL bCallByIsValid, // invoke by IsValid() function.
  194. IN PANNOUNCESERVERWO pbData,
  195. IN DWORD cbData
  196. )
  197. /*++
  198. Verify Announce License Server work object Data.
  199. --*/
  200. {
  201. BOOL bSuccess = FALSE;
  202. DWORD dwLen;
  203. if(pbData == NULL || cbData == 0 || cbData != pbData->dwStructSize)
  204. {
  205. TLSASSERT(FALSE);
  206. SetLastError(ERROR_INVALID_DATA);
  207. return FALSE;
  208. }
  209. //
  210. // NULL terminate string...
  211. //
  212. pbData->m_szServerId[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
  213. pbData->m_szServerName[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
  214. dwLen = _tcslen(pbData->m_szServerId);
  215. if(dwLen != 0 && dwLen < LSERVER_MAX_STRING_SIZE + 1)
  216. {
  217. dwLen = _tcslen(pbData->m_szServerName);
  218. if(dwLen != 0 && dwLen < LSERVER_MAX_STRING_SIZE + 1)
  219. {
  220. bSuccess = TRUE;
  221. }
  222. }
  223. if(bSuccess == FALSE)
  224. {
  225. SetLastError(ERROR_INVALID_DATA);
  226. }
  227. return bSuccess;
  228. }
  229. //------------------------------------------------------------------------
  230. BOOL
  231. CAnnounceLserver::CopyWorkObjectData(
  232. OUT PANNOUNCESERVERWO* ppbDest,
  233. OUT PDWORD pcbDest,
  234. IN PANNOUNCESERVERWO pbSrc,
  235. IN DWORD cbSrc
  236. )
  237. /*++
  238. Copy Announce license server work object's data
  239. --*/
  240. {
  241. DWORD dwStatus = ERROR_SUCCESS;
  242. if(ppbDest == NULL || pcbDest == NULL)
  243. {
  244. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  245. TLSASSERT(FALSE);
  246. goto cleanup;
  247. }
  248. if(CopyBinaryData(
  249. (PBYTE *)ppbDest,
  250. pcbDest,
  251. (PBYTE) pbSrc,
  252. cbSrc
  253. ) == FALSE)
  254. {
  255. dwStatus = GetLastError();
  256. }
  257. cleanup:
  258. return dwStatus == ERROR_SUCCESS;
  259. }
  260. //---------------------------------------------------------------------------
  261. BOOL
  262. CAnnounceLserver::CleanupWorkObjectData(
  263. IN OUT PANNOUNCESERVERWO* ppbData,
  264. IN OUT PDWORD pcbData
  265. )
  266. /*++
  267. Cleanup Announce license server's work object data.
  268. --*/
  269. {
  270. if(ppbData != NULL && pcbData != NULL)
  271. {
  272. FreeMemory(*ppbData);
  273. *ppbData = NULL;
  274. *pcbData = 0;
  275. }
  276. return TRUE;
  277. }
  278. //---------------------------------------------------------------------------
  279. BOOL
  280. CAnnounceLserver::IsJobCompleted(
  281. IN PANNOUNCESERVERWO pbData,
  282. IN DWORD cbData
  283. )
  284. /*++
  285. Determine if Announce License Server Job has completed.
  286. --*/
  287. {
  288. return (pbData == NULL) ? TRUE : (pbData->dwRetryTimes > GetJobRetryTimes());
  289. }
  290. //---------------------------------------------------------------------------
  291. BOOL
  292. ServerEnumCallBack(
  293. TLS_HANDLE hHandle,
  294. LPCTSTR pszServerName,
  295. HANDLE dwUserData
  296. )
  297. /*++
  298. See TLSAPI on license server enumeration.
  299. ++*/
  300. {
  301. CAnnounceLserver* pWkObject = (CAnnounceLserver *)dwUserData;
  302. DWORD dwStatus = ERROR_SUCCESS;
  303. DWORD dwErrCode;
  304. TCHAR szRemoteServerId[LSERVER_MAX_STRING_SIZE+2];
  305. TCHAR szRemoteServerName[LSERVER_MAX_STRING_SIZE+2];
  306. if(pWkObject == NULL)
  307. {
  308. SetLastError(ERROR_INVALID_DATA);
  309. TLSASSERT(dwUserData != NULL);
  310. return FALSE;
  311. }
  312. BOOL bCancel;
  313. if(pWkObject->IsWorkManagerShuttingDown() == TRUE)
  314. {
  315. return TRUE;
  316. }
  317. try {
  318. //
  319. // Enumeration call ServerEnumCallBack() twice, once before actual connection
  320. // and once after it successfully connect to remote server
  321. //
  322. if( lstrcmpi(pszServerName, pWkObject->GetWorkData()->m_szServerName) != 0 && hHandle != NULL)
  323. {
  324. //
  325. // throw exception if fail to allocate memory
  326. //
  327. TLServerInfo ServerInfo;
  328. TLServerInfo ExistingServerInfo;
  329. TLS_HANDLE hTrustHandle;
  330. hTrustHandle = TLSConnectAndEstablishTrust(
  331. NULL,
  332. hHandle
  333. );
  334. if(hTrustHandle != NULL)
  335. {
  336. dwStatus = TLSRetrieveServerInfo(
  337. hTrustHandle,
  338. &ServerInfo
  339. );
  340. if( dwStatus == ERROR_SUCCESS &&
  341. lstrcmpi(ServerInfo.GetServerId(), pWkObject->GetWorkData()->m_szServerId) != 0 )
  342. // lstrcmpi(ServerInfo.GetServerName(), pWkObject->GetWorkData()->m_szServerName) != 0
  343. {
  344. // check to see if this server is already exists
  345. dwStatus = TLSLookupRegisteredServer(
  346. ServerInfo.GetServerId(),
  347. ServerInfo.GetServerDomain(),
  348. ServerInfo.GetServerName(),
  349. &ExistingServerInfo
  350. );
  351. if(dwStatus == ERROR_SUCCESS)
  352. {
  353. ServerInfo = ExistingServerInfo;
  354. }
  355. else
  356. {
  357. // register every server.
  358. dwStatus = TLSRegisterServerWithServerInfo(&ServerInfo);
  359. if(dwStatus == TLS_E_DUPLICATE_RECORD)
  360. {
  361. dwStatus = ERROR_SUCCESS;
  362. }
  363. }
  364. // let enforce talk to non-enforce, replication will be block later
  365. if( ServerInfo.IsAnnounced() == FALSE && dwStatus == ERROR_SUCCESS )
  366. {
  367. DBGPrintf(
  368. DBG_INFORMATION,
  369. DBG_FACILITY_JOB,
  370. DBGLEVEL_FUNCTION_TRACE,
  371. _TEXT("%s - Announce to %s\n"),
  372. pWkObject->GetJobDescription(),
  373. ServerInfo.GetServerName()
  374. );
  375. dwStatus = TLSAnnounceServerToRemoteServer(
  376. TLSANNOUNCE_TYPE_STARTUP,
  377. ServerInfo.GetServerId(),
  378. ServerInfo.GetServerDomain(),
  379. ServerInfo.GetServerName(),
  380. pWkObject->GetWorkData()->m_szServerId,
  381. pWkObject->GetWorkData()->m_szScope,
  382. pWkObject->GetWorkData()->m_szServerName,
  383. &(pWkObject->GetWorkData()->m_ftLastShutdownTime)
  384. );
  385. }
  386. }
  387. }
  388. }
  389. }
  390. catch( SE_Exception e ) {
  391. dwStatus = e.getSeNumber();
  392. }
  393. catch( ... ) {
  394. dwStatus = TLS_E_INTERNAL;
  395. TLSASSERT(FALSE);
  396. }
  397. return (dwStatus == ERROR_SUCCESS) ? pWkObject->IsWorkManagerShuttingDown() : TRUE;
  398. }
  399. //---------------------------------------------------------------------------
  400. DWORD
  401. CAnnounceLserver::ExecuteJob(
  402. IN PANNOUNCESERVERWO pbData,
  403. IN DWORD cbData
  404. )
  405. /*++
  406. Execute a announce license server job.
  407. --*/
  408. {
  409. DWORD dwStatus = ERROR_SUCCESS;
  410. DBGPrintf(
  411. DBG_INFORMATION,
  412. DBG_FACILITY_JOB,
  413. DBGLEVEL_FUNCTION_TRACE,
  414. _TEXT("%s ...\n"),
  415. GetJobDescription()
  416. );
  417. if(IsWorkManagerShuttingDown() == TRUE)
  418. {
  419. return TLS_I_WORKMANAGER_SHUTDOWN;
  420. }
  421. //
  422. // Enumerate all license server
  423. //
  424. dwStatus = EnumerateTlsServer(
  425. ServerEnumCallBack,
  426. this,
  427. TLSERVER_ENUM_TIMEOUT,
  428. FALSE
  429. );
  430. //
  431. // Discovery run twice so that if more than one server
  432. // start up at the same time, second loop will catch it.
  433. //
  434. pbData->dwRetryTimes++;
  435. DBGPrintf(
  436. DBG_INFORMATION,
  437. DBG_FACILITY_JOB,
  438. DBGLEVEL_FUNCTION_TRACE,
  439. _TEXT("%s ended...\n"),
  440. GetJobDescription()
  441. );
  442. return dwStatus;
  443. }
  444. //----------------------------------------------------------------------------------------------
  445. LPCTSTR
  446. CAnnounceLserver::GetJobDescription()
  447. /*++
  448. Get announce license server job description, this is used
  449. only at debug tracing.
  450. --*/
  451. {
  452. memset(m_szJobDescription, 0, sizeof(m_szJobDescription));
  453. _tcsncpy(
  454. m_szJobDescription,
  455. ANNOUNCESERVER_DESCRIPTION,
  456. sizeof(m_szJobDescription)/sizeof(m_szJobDescription[0]) - 1
  457. );
  458. return m_szJobDescription;
  459. }
  460. ////////////////////////////////////////////////////////////
  461. //////////////////////////////////////////////////////////////////////////
  462. //
  463. // CAnnounceTOEServer
  464. //
  465. //////////////////////////////////////////////////////////////////////////
  466. BOOL
  467. CAnnounceToEServer::VerifyWorkObjectData(
  468. IN BOOL bCallByIsValid, // invoke by IsValid() function.
  469. IN PANNOUNCETOESERVERWO pbData,
  470. IN DWORD cbData
  471. )
  472. /*++
  473. Verify Announce license server to enterprise server work object
  474. data.
  475. --*/
  476. {
  477. BOOL bSuccess = FALSE;
  478. DWORD dwLen;
  479. if(pbData == NULL || cbData != pbData->dwStructSize)
  480. {
  481. TLSASSERT(FALSE);
  482. SetLastError(ERROR_INVALID_PARAMETER);
  483. return FALSE;
  484. }
  485. //
  486. // NULL terminate string...
  487. //
  488. pbData->m_szServerId[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
  489. pbData->m_szServerName[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
  490. dwLen = _tcslen(pbData->m_szServerId);
  491. if(dwLen != 0 && dwLen < LSERVER_MAX_STRING_SIZE + 1)
  492. {
  493. dwLen = _tcslen(pbData->m_szServerName);
  494. if(dwLen != 0 && dwLen < LSERVER_MAX_STRING_SIZE + 1)
  495. {
  496. bSuccess = TRUE;
  497. }
  498. }
  499. if(bSuccess == FALSE)
  500. {
  501. SetLastError(ERROR_INVALID_DATA);
  502. }
  503. return bSuccess;
  504. }
  505. //------------------------------------------------------------------------
  506. BOOL
  507. CAnnounceToEServer::CopyWorkObjectData(
  508. OUT PANNOUNCETOESERVERWO* ppbDest,
  509. OUT PDWORD pcbDest,
  510. IN PANNOUNCETOESERVERWO pbSrc,
  511. IN DWORD cbSrc
  512. )
  513. /*++
  514. Copy announce license server to enterprise server work
  515. object data.
  516. --*/
  517. {
  518. DWORD dwStatus = ERROR_SUCCESS;
  519. if(ppbDest == NULL || pcbDest == NULL)
  520. {
  521. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  522. TLSASSERT(FALSE);
  523. goto cleanup;
  524. }
  525. if(CopyBinaryData(
  526. (PBYTE *)ppbDest,
  527. pcbDest,
  528. (PBYTE) pbSrc,
  529. cbSrc
  530. ) == FALSE)
  531. {
  532. dwStatus = GetLastError();
  533. }
  534. cleanup:
  535. return dwStatus == ERROR_SUCCESS;
  536. }
  537. //---------------------------------------------------------------------------
  538. BOOL
  539. CAnnounceToEServer::CleanupWorkObjectData(
  540. IN OUT PANNOUNCETOESERVERWO* ppbData,
  541. IN OUT PDWORD pcbData
  542. )
  543. /*++
  544. Cleanup announce license server to enterprise server work
  545. object data.
  546. --*/
  547. {
  548. if(ppbData != NULL && pcbData != NULL)
  549. {
  550. FreeMemory(*ppbData);
  551. *ppbData = NULL;
  552. *pcbData = 0;
  553. }
  554. return TRUE;
  555. }
  556. //---------------------------------------------------------------------------
  557. BOOL
  558. CAnnounceToEServer::IsJobCompleted(
  559. IN PANNOUNCETOESERVERWO pbData,
  560. IN DWORD cbData
  561. )
  562. /*++
  563. Detemine if announce license server to enterprise server
  564. is completed.
  565. --*/
  566. {
  567. return (pbData == NULL) ? TRUE : GetWorkData()->bCompleted;
  568. }
  569. //---------------------------------------------------------------------------
  570. DWORD
  571. CAnnounceToEServer::ExecuteJob(
  572. IN PANNOUNCETOESERVERWO pbData,
  573. IN DWORD cbData
  574. )
  575. /*++
  576. Execute an announce license server to enterprise server work object.
  577. --*/
  578. {
  579. DWORD dwStatus = ERROR_SUCCESS;
  580. LPWSTR* pszEServerList = NULL;
  581. DWORD dwCount = 0;
  582. DWORD dwErrCode;
  583. BOOL bSkipServer;
  584. TCHAR szRemoteServerId[LSERVER_MAX_STRING_SIZE+2];
  585. TCHAR szRemoteServerName[LSERVER_MAX_STRING_SIZE+2];
  586. DBGPrintf(
  587. DBG_INFORMATION,
  588. DBG_FACILITY_JOB,
  589. DBGLEVEL_FUNCTION_TRACE,
  590. _TEXT("%s ...\n"),
  591. GetJobDescription()
  592. );
  593. TLSASSERT(pbData != NULL && cbData != 0);
  594. try {
  595. dwStatus = GetAllEnterpriseServers(
  596. &pszEServerList,
  597. &dwCount
  598. );
  599. if(dwStatus == ERROR_SUCCESS && dwCount > 0 && pszEServerList != NULL)
  600. {
  601. for(DWORD index = 0;
  602. index < dwCount && IsWorkManagerShuttingDown() == FALSE;
  603. index++)
  604. {
  605. bSkipServer = TRUE;
  606. if(pszEServerList[index] == NULL)
  607. {
  608. continue;
  609. }
  610. //
  611. // check if we already have this server in our list
  612. //
  613. TLServerInfo ServerInfo;
  614. dwStatus = TLSLookupRegisteredServer(
  615. NULL,
  616. NULL,
  617. pszEServerList[index],
  618. &ServerInfo
  619. );
  620. if(dwStatus != ERROR_SUCCESS)
  621. {
  622. //
  623. // Get the actual server name.
  624. //
  625. TLS_HANDLE hTrustHandle = NULL;
  626. hTrustHandle = TLSConnectAndEstablishTrust(
  627. pszEServerList[index],
  628. NULL
  629. );
  630. if(hTrustHandle != NULL)
  631. {
  632. if(IsWorkManagerShuttingDown() == TRUE)
  633. {
  634. // handle leak but we are shutting down
  635. break;
  636. }
  637. dwStatus = TLSRetrieveServerInfo(
  638. hTrustHandle,
  639. &ServerInfo
  640. );
  641. if(dwStatus == ERROR_SUCCESS)
  642. {
  643. if( lstrcmpi(ServerInfo.GetServerName(), pbData->m_szServerName) != 0 )
  644. {
  645. if(IsWorkManagerShuttingDown() == TRUE)
  646. {
  647. // handle leak but we are shutting down
  648. break;
  649. }
  650. dwStatus = TLSRegisterServerWithServerInfo(&ServerInfo);
  651. if(dwStatus == ERROR_SUCCESS)
  652. {
  653. // at this point, if we gets duplicate record, that mean
  654. // server is registered via announce and we already
  655. // sync. local license pack so skip it.
  656. bSkipServer = FALSE;
  657. }
  658. }
  659. }
  660. }
  661. if( hTrustHandle != NULL)
  662. {
  663. TLSDisconnectFromServer(hTrustHandle);
  664. }
  665. dwStatus = ERROR_SUCCESS;
  666. if(bSkipServer == TRUE)
  667. {
  668. continue;
  669. }
  670. }
  671. else if(GetLicenseServerRole() & TLSERVER_ENTERPRISE_SERVER)
  672. {
  673. // for enterprise server, other server will announce itself,
  674. // for domain server, we need to announce once a while
  675. // so that after enterprise restart, it still have our
  676. // server
  677. if(dwStatus == ERROR_SUCCESS && ServerInfo.GetServerVersion() != 0)
  678. {
  679. //
  680. // we already 'push' sync. with this server
  681. //
  682. continue;
  683. }
  684. }
  685. DBGPrintf(
  686. DBG_INFORMATION,
  687. DBG_FACILITY_JOB,
  688. DBGLEVEL_FUNCTION_TRACE,
  689. _TEXT("%s - Announce to %s\n"),
  690. GetJobDescription(),
  691. pszEServerList[index]
  692. );
  693. if(IsWorkManagerShuttingDown() == TRUE)
  694. {
  695. // handle leak but we are shutting down
  696. break;
  697. }
  698. dwStatus = TLSAnnounceServerToRemoteServer(
  699. TLSANNOUNCE_TYPE_STARTUP,
  700. ServerInfo.GetServerId(),
  701. ServerInfo.GetServerDomain(),
  702. ServerInfo.GetServerName(),
  703. GetWorkData()->m_szServerId,
  704. GetWorkData()->m_szScope,
  705. GetWorkData()->m_szServerName,
  706. &(GetWorkData()->m_ftLastShutdownTime)
  707. );
  708. }
  709. //
  710. // Free memory
  711. //
  712. if(pszEServerList != NULL)
  713. {
  714. for( index = 0; index < dwCount; index ++)
  715. {
  716. if(pszEServerList[index] != NULL)
  717. {
  718. LocalFree(pszEServerList[index]);
  719. }
  720. }
  721. LocalFree(pszEServerList);
  722. }
  723. }
  724. }
  725. catch( SE_Exception e )
  726. {
  727. DBGPrintf(
  728. DBG_ERROR,
  729. DBG_FACILITY_WORKMGR,
  730. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  731. _TEXT("CAnnounceToEServer::ExecuteJob() : Job has cause exception %d\n"),
  732. e.getSeNumber()
  733. );
  734. dwStatus = e.getSeNumber();
  735. TLSASSERT(FALSE);
  736. }
  737. catch(...)
  738. {
  739. DBGPrintf(
  740. DBG_ERROR,
  741. DBG_FACILITY_WORKMGR,
  742. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  743. _TEXT("CAnnounceToEServer::ExecuteJob() : Job has cause unknown exception\n")
  744. );
  745. TLSASSERT(FALSE);
  746. }
  747. //
  748. // Continue running in case user install a NT5 PDC
  749. //
  750. if(IsWorkManagerShuttingDown() == TRUE)
  751. {
  752. GetWorkData()->bCompleted = TRUE;
  753. }
  754. return dwStatus;
  755. }
  756. //--------------------------------------------------------------------
  757. LPCTSTR
  758. CAnnounceToEServer::GetJobDescription()
  759. /*++
  760. Get announce license server to enterprise server
  761. job description, used only at debug tracing.
  762. --*/
  763. {
  764. memset(m_szJobDescription, 0, sizeof(m_szJobDescription));
  765. _tcsncpy(
  766. m_szJobDescription,
  767. ANNOUNCETOESERVER_DESCRIPTION,
  768. sizeof(m_szJobDescription)/sizeof(m_szJobDescription[0]) - 1
  769. );
  770. return m_szJobDescription;
  771. }
  772. ////////////////////////////////////////////////////////////
  773. //////////////////////////////////////////////////////////////////////////
  774. //
  775. // CReturnLicense
  776. //
  777. //////////////////////////////////////////////////////////////////////////
  778. CWorkObject* WINAPI
  779. InitializeCReturnWorkObject(
  780. IN CWorkManager* pWkMgr,
  781. IN PBYTE pbWorkData,
  782. IN DWORD cbWorkData
  783. )
  784. /*++
  785. Abstract:
  786. Create/initialize a Return License work object.
  787. Parameters:
  788. pWkMgr : Pointer work manager.
  789. pbWorkData : Object's work data used to initialize return license.
  790. cbWorkData : size of work data.
  791. Return:
  792. A pointer to CWorkObject or NULL if error.
  793. --*/
  794. {
  795. CReturnLicense* pRetLicense = NULL;
  796. DWORD dwStatus;
  797. DBGPrintf(
  798. DBG_INFORMATION,
  799. DBG_FACILITY_WORKMGR,
  800. DBGLEVEL_FUNCTION_TRACE,
  801. _TEXT("InitializeCReturnWorkObject() - initializing return license...\n")
  802. );
  803. try {
  804. pRetLicense = new CReturnLicense(
  805. TRUE,
  806. (PRETURNLICENSEWO)pbWorkData,
  807. cbWorkData
  808. );
  809. //
  810. // TODO - fix this, bad design
  811. //
  812. pRetLicense->SetProcessingWorkManager(pWkMgr);
  813. TLSASSERT(pRetLicense->IsValid() == TRUE);
  814. }
  815. catch( SE_Exception e ) {
  816. pRetLicense = NULL;
  817. SetLastError(dwStatus = e.getSeNumber());
  818. TLSLogEvent(
  819. EVENTLOG_ERROR_TYPE,
  820. TLS_E_WORKMANAGERGENERAL,
  821. TLS_E_INITJOB,
  822. dwStatus
  823. );
  824. }
  825. catch(...) {
  826. pRetLicense = NULL;
  827. SetLastError(dwStatus = TLS_E_INITJOB_UNKNOWN);
  828. TLSLogEvent(
  829. EVENTLOG_ERROR_TYPE,
  830. TLS_E_WORKMANAGERGENERAL,
  831. TLS_E_INITJOB_UNKNOWN
  832. );
  833. }
  834. return pRetLicense;
  835. }
  836. //--------------------------------------------------------
  837. BOOL
  838. CReturnLicense::VerifyWorkObjectData(
  839. IN BOOL bCallByIsValid,
  840. IN PRETURNLICENSEWO pbData,
  841. IN DWORD cbData
  842. )
  843. /*++
  844. Verify a return license work object data.
  845. --*/
  846. {
  847. DWORD dwStatus = ERROR_SUCCESS;
  848. DWORD dwLen;
  849. DWORD dwNumLicensedProduct;
  850. if(pbData == NULL || cbData == 0 || pbData->cbEncryptedHwid == 0)
  851. {
  852. TLSASSERT(FALSE);
  853. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  854. }
  855. if(dwStatus == ERROR_SUCCESS)
  856. {
  857. if( pbData->dwStructVersion < CURRENT_RETURNLICENSEWO_STRUCT_VER ||
  858. pbData->dwStructSize != cbData )
  859. {
  860. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  861. TLSASSERT(FALSE);
  862. }
  863. }
  864. if(dwStatus == ERROR_SUCCESS)
  865. {
  866. //
  867. // NULL Terminate Target Server ID
  868. //
  869. pbData->szTargetServerId[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
  870. dwLen = _tcslen(pbData->szTargetServerId);
  871. if(dwLen == 0 || dwLen >= LSERVER_MAX_STRING_SIZE+1)
  872. {
  873. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  874. }
  875. }
  876. if(dwStatus == ERROR_SUCCESS)
  877. {
  878. pbData->szTargetServerName[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
  879. dwLen = _tcslen(pbData->szTargetServerName);
  880. if(dwLen == 0 || dwLen >= LSERVER_MAX_STRING_SIZE+1)
  881. {
  882. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  883. }
  884. }
  885. if(dwStatus == ERROR_SUCCESS)
  886. {
  887. pbData->szOrgProductID[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
  888. dwLen = _tcslen(pbData->szOrgProductID);
  889. if(dwLen == 0 || dwLen >= LSERVER_MAX_STRING_SIZE+1)
  890. {
  891. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  892. }
  893. }
  894. if(dwStatus == ERROR_SUCCESS)
  895. {
  896. pbData->szCompanyName[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
  897. dwLen = _tcslen(pbData->szCompanyName);
  898. if(dwLen == 0 || dwLen >= LSERVER_MAX_STRING_SIZE+1)
  899. {
  900. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  901. }
  902. }
  903. if(dwStatus == ERROR_SUCCESS)
  904. {
  905. pbData->szProductId[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
  906. dwLen = _tcslen(pbData->szProductId);
  907. if(dwLen == 0 || dwLen >= LSERVER_MAX_STRING_SIZE+1)
  908. {
  909. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  910. }
  911. }
  912. if(dwStatus == ERROR_SUCCESS)
  913. {
  914. pbData->szUserName[MAXCOMPUTERNAMELENGTH+1] = _TEXT('\0');
  915. dwLen = _tcslen(pbData->szUserName);
  916. if(dwLen == 0 || dwLen >= MAXCOMPUTERNAMELENGTH+1)
  917. {
  918. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  919. }
  920. }
  921. if(dwStatus == ERROR_SUCCESS)
  922. {
  923. pbData->szMachineName[MAXUSERNAMELENGTH+1] = _TEXT('\0');
  924. dwLen = _tcslen(pbData->szMachineName);
  925. if(dwLen == 0 || dwLen >= MAXUSERNAMELENGTH+1)
  926. {
  927. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  928. }
  929. }
  930. return dwStatus == ERROR_SUCCESS;
  931. }
  932. //----------------------------------------------------------------------------------------------
  933. BOOL
  934. CReturnLicense::CopyWorkObjectData(
  935. IN OUT PRETURNLICENSEWO* ppbDest,
  936. IN OUT PDWORD pcbDest,
  937. IN PRETURNLICENSEWO pbSrc,
  938. IN DWORD cbSrc
  939. )
  940. /*++
  941. Copy return license work object data.
  942. --*/
  943. {
  944. DWORD dwStatus = ERROR_SUCCESS;
  945. if(ppbDest == NULL || pcbDest == NULL)
  946. {
  947. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  948. TLSASSERT(FALSE);
  949. goto cleanup;
  950. }
  951. if(CopyBinaryData(
  952. (PBYTE *)ppbDest,
  953. pcbDest,
  954. (PBYTE) pbSrc,
  955. cbSrc
  956. ) == FALSE)
  957. {
  958. dwStatus = GetLastError();
  959. }
  960. cleanup:
  961. return dwStatus == ERROR_SUCCESS;
  962. }
  963. //-------------------------------------------------------------------------
  964. BOOL
  965. CReturnLicense::CleanupWorkObjectData(
  966. IN OUT PRETURNLICENSEWO* ppbData,
  967. IN OUT PDWORD pcbData
  968. )
  969. /*++
  970. Cleanup return license work object data.
  971. --*/
  972. {
  973. if(ppbData != NULL && pcbData != NULL)
  974. {
  975. FreeMemory(*ppbData);
  976. *ppbData = NULL;
  977. *pcbData = 0;
  978. }
  979. return TRUE;
  980. }
  981. //---------------------------------------------------------------------------
  982. BOOL
  983. CReturnLicense::IsJobCompleted(
  984. IN PRETURNLICENSEWO pbData,
  985. IN DWORD cbData
  986. )
  987. /*++
  988. Determine if return license job is completed.
  989. --*/
  990. {
  991. return (pbData != NULL) ? (pbData->dwNumRetry >= m_dwRetryTimes) : TRUE;
  992. }
  993. //-----------------------------------------------------------------------------
  994. #if 0
  995. DWORD
  996. _ResolveServerIdToServer(
  997. LPTSTR pszServerId,
  998. LPTSTR pszServerName
  999. )
  1000. /*++
  1001. --*/
  1002. {
  1003. DWORD dwStatus = ERROR_SUCCESS;
  1004. TLS_HANDLE hEServer = NULL;
  1005. TLServerInfo EServerInfo;
  1006. DWORD dwErrCode;
  1007. TCHAR pbSetupId[LSERVER_MAX_STRING_SIZE+2];
  1008. DWORD cbSetupId = LSERVER_MAX_STRING_SIZE+1;
  1009. TCHAR pbDomainName[LSERVER_MAX_STRING_SIZE+2];
  1010. DWORD cbDomainName = LSERVER_MAX_STRING_SIZE+1;
  1011. TCHAR pbServerName[MAX_COMPUTERNAME_LENGTH+2];
  1012. DWORD cbServerName = MAX_COMPUTERNAME_LENGTH+1;
  1013. dwStatus = TLSLookupServerById(
  1014. pszServerId,
  1015. pszServerName
  1016. );
  1017. if(dwStatus != ERROR_SUCCESS)
  1018. {
  1019. // try to resolve server name with enterprise server
  1020. dwStatus = TLSLookupAnyEnterpriseServer(&EServerInfo);
  1021. if(dwStatus == ERROR_SUCCESS)
  1022. {
  1023. hEServer = TLSConnectAndEstablishTrust(
  1024. EServerInfo.GetServerName(),
  1025. NULL
  1026. );
  1027. if(hEServer != NULL)
  1028. {
  1029. dwStatus = TLSLookupServer(
  1030. hEServer,
  1031. pszServerId,
  1032. pbSetupId,
  1033. &cbSetupId,
  1034. pbDomainName,
  1035. &cbDomainName,
  1036. pbServerName,
  1037. &cbServerName,
  1038. &dwErrCode
  1039. );
  1040. if(dwStatus == ERROR_SUCCESS && dwErrCode == ERROR_SUCCESS)
  1041. {
  1042. lstrcpy(pszServerName, pbServerName);
  1043. }
  1044. }
  1045. }
  1046. }
  1047. if(hEServer != NULL)
  1048. {
  1049. TLSDisconnectFromServer(hEServer);
  1050. }
  1051. return dwStatus;
  1052. }
  1053. #endif
  1054. //--------------------------------------------------------------------------------
  1055. DWORD
  1056. CReturnLicense::ExecuteJob(
  1057. IN PRETURNLICENSEWO pbData,
  1058. IN DWORD cbData
  1059. )
  1060. /*++
  1061. Execute a return license work object.
  1062. --*/
  1063. {
  1064. DWORD dwStatus = ERROR_SUCCESS;
  1065. TLServerInfo ServerInfo;
  1066. TCHAR szServer[LSERVER_MAX_STRING_SIZE+2];
  1067. TLSLicenseToBeReturn ToBeReturn;
  1068. TLS_HANDLE hHandle = NULL;
  1069. DWORD dwErrCode = ERROR_SUCCESS;
  1070. // log an error
  1071. TCHAR szErrMsg[MAX_ERROR_MSG_SIZE];
  1072. DWORD dwSize = sizeof(szErrMsg) / sizeof(szErrMsg[0]);
  1073. DBGPrintf(
  1074. DBG_INFORMATION,
  1075. DBG_FACILITY_JOB,
  1076. DBGLEVEL_FUNCTION_TRACE,
  1077. _TEXT("%s ...\n"),
  1078. GetJobDescription()
  1079. );
  1080. //-------------------------------------------------------
  1081. if(VerifyWorkObjectData(TRUE, pbData, cbData) == FALSE)
  1082. {
  1083. TLSASSERT(FALSE);
  1084. //
  1085. // this is invalid data, quitely abort operation
  1086. //
  1087. pbData->dwNumRetry = m_dwRetryTimes;
  1088. SetLastError(dwStatus = ERROR_INVALID_DATA);
  1089. goto cleanup;
  1090. }
  1091. if(IsWorkManagerShuttingDown() == TRUE)
  1092. {
  1093. SetLastError(dwStatus = TLS_I_WORKMANAGER_SHUTDOWN);
  1094. goto cleanup;
  1095. }
  1096. dwStatus = TLSResolveServerIdToServer(
  1097. pbData->szTargetServerId,
  1098. szServer
  1099. );
  1100. if(dwStatus != ERROR_SUCCESS)
  1101. {
  1102. // Server not register with this server, try using
  1103. // whatever name we have
  1104. lstrcpy(szServer, pbData->szTargetServerName);
  1105. dwStatus = ERROR_SUCCESS;
  1106. }
  1107. ToBeReturn.dwQuantity = pbData->dwQuantity;
  1108. ToBeReturn.dwKeyPackId = pbData->dwKeyPackId;
  1109. ToBeReturn.dwLicenseId = pbData->dwLicenseId;
  1110. ToBeReturn.cbEncryptedHwid = pbData->cbEncryptedHwid;
  1111. ToBeReturn.pbEncryptedHwid = pbData->pbEncryptedHwid;
  1112. ToBeReturn.dwProductVersion = pbData->dwProductVersion;
  1113. ToBeReturn.pszOrgProductId = pbData->szOrgProductID;
  1114. ToBeReturn.pszCompanyName = pbData->szCompanyName;
  1115. ToBeReturn.pszProductId = pbData->szProductId;
  1116. ToBeReturn.pszUserName = pbData->szUserName;
  1117. ToBeReturn.pszMachineName = pbData->szMachineName;
  1118. ToBeReturn.dwPlatformID = pbData->dwPlatformId;
  1119. if(IsWorkManagerShuttingDown() == TRUE)
  1120. {
  1121. SetLastError(dwStatus = TLS_I_WORKMANAGER_SHUTDOWN);
  1122. goto cleanup;
  1123. }
  1124. hHandle = TLSConnectAndEstablishTrust(szServer, NULL);
  1125. if(hHandle == NULL)
  1126. {
  1127. dwStatus = GetLastError();
  1128. // TLSLogEvent(
  1129. // EVENTLOG_WARNING_TYPE,
  1130. // TLS_W_RETURNLICENSE,
  1131. // TLS_I_CONTACTSERVER,
  1132. // szServer
  1133. // );
  1134. }
  1135. else
  1136. {
  1137. if(IsWorkManagerShuttingDown() == TRUE)
  1138. {
  1139. SetLastError(dwStatus = TLS_I_WORKMANAGER_SHUTDOWN);
  1140. goto cleanup;
  1141. }
  1142. // make a RPC call to return client license
  1143. dwStatus = TLSReturnLicensedProduct(
  1144. hHandle,
  1145. &ToBeReturn,
  1146. &dwErrCode
  1147. );
  1148. if(dwStatus != ERROR_SUCCESS)
  1149. {
  1150. // retry again
  1151. // TLSLogEvent(
  1152. // EVENTLOG_WARNING_TYPE,
  1153. // TLS_W_RETURNLICENSE,
  1154. // TLS_I_CONTACTSERVER,
  1155. // szServer
  1156. // );
  1157. }
  1158. else if(dwErrCode >= LSERVER_ERROR_BASE)
  1159. {
  1160. if(dwErrCode != LSERVER_E_DATANOTFOUND && dwErrCode != LSERVER_E_INVALID_DATA)
  1161. {
  1162. DWORD status;
  1163. DWORD errCode;
  1164. memset(szErrMsg, 0, sizeof(szErrMsg));
  1165. status = TLSGetLastError(
  1166. hHandle,
  1167. dwSize,
  1168. szErrMsg,
  1169. &errCode
  1170. );
  1171. if(status == ERROR_SUCCESS)
  1172. {
  1173. TLSLogEvent(
  1174. EVENTLOG_WARNING_TYPE,
  1175. TLS_W_RETURNLICENSE,
  1176. TLS_E_RETURNLICENSE,
  1177. ToBeReturn.pszMachineName,
  1178. ToBeReturn.pszUserName,
  1179. szErrMsg,
  1180. szServer
  1181. );
  1182. }
  1183. else
  1184. {
  1185. // server might be done at this instance,
  1186. // log an error with error code
  1187. TLSLogEvent(
  1188. EVENTLOG_WARNING_TYPE,
  1189. TLS_W_RETURNLICENSE,
  1190. TLS_E_RETURNLICENSECODE,
  1191. ToBeReturn.pszMachineName,
  1192. ToBeReturn.pszUserName,
  1193. dwErrCode,
  1194. szServer
  1195. );
  1196. }
  1197. }
  1198. }
  1199. }
  1200. if(dwStatus == ERROR_SUCCESS && dwErrCode == ERROR_SUCCESS)
  1201. {
  1202. // successfully return license.
  1203. pbData->dwNumRetry = m_dwRetryTimes;
  1204. }
  1205. else if(dwErrCode == LSERVER_E_INVALID_DATA || dwErrCode == LSERVER_E_DATANOTFOUND)
  1206. {
  1207. // server might be re-installed so all database entry is gone
  1208. // delete this return license job
  1209. pbData->dwNumRetry = m_dwRetryTimes;
  1210. }
  1211. else
  1212. {
  1213. pbData->dwNumRetry++;
  1214. if(pbData->dwNumRetry >= m_dwRetryTimes)
  1215. {
  1216. TLSLogEvent(
  1217. EVENTLOG_WARNING_TYPE,
  1218. TLS_W_RETURNLICENSE,
  1219. TLS_E_RETURNLICENSETOOMANY,
  1220. ToBeReturn.pszMachineName,
  1221. ToBeReturn.pszUserName,
  1222. pbData->dwNumRetry
  1223. );
  1224. }
  1225. }
  1226. cleanup:
  1227. if(hHandle != NULL)
  1228. {
  1229. TLSDisconnectFromServer(hHandle);
  1230. hHandle = NULL;
  1231. }
  1232. return dwStatus;
  1233. }
  1234. //----------------------------------------------------------------------------------------------
  1235. LPCTSTR
  1236. CReturnLicense::GetJobDescription()
  1237. /*++
  1238. Get job description, use only at debug tracing.
  1239. --*/
  1240. {
  1241. PRETURNLICENSEWO pbData = GetWorkData();
  1242. memset(m_szJobDescription, 0, sizeof(m_szJobDescription));
  1243. if(pbData)
  1244. {
  1245. _sntprintf(
  1246. m_szJobDescription,
  1247. sizeof(m_szJobDescription)/sizeof(m_szJobDescription[0]) - 1,
  1248. RETURNLICENSE_DESCRIPTION,
  1249. pbData->dwNumRetry,
  1250. pbData->dwKeyPackId,
  1251. pbData->dwLicenseId,
  1252. pbData->szTargetServerName
  1253. );
  1254. }
  1255. return m_szJobDescription;
  1256. }
  1257. //////////////////////////////////////////////////////////////////////////
  1258. //
  1259. // CSsyncLicensePack
  1260. //
  1261. //////////////////////////////////////////////////////////////////////////
  1262. BOOL
  1263. CSsyncLicensePack::VerifyWorkObjectData(
  1264. IN BOOL bCallByIsValid, // invoke by IsValid() function.
  1265. IN PSSYNCLICENSEPACK pbData,
  1266. IN DWORD cbData
  1267. )
  1268. /*++
  1269. Verify a sync. license pack work object data.
  1270. --*/
  1271. {
  1272. BOOL bSuccess = TRUE;
  1273. DWORD dwLen;
  1274. if( pbData == NULL || cbData == 0 || cbData != pbData->dwStructSize ||
  1275. (pbData->dwSyncType != SSYNC_ALL_LKP && pbData->dwSyncType != SSYNC_ONE_LKP) )
  1276. {
  1277. TLSASSERT(FALSE);
  1278. SetLastError(ERROR_INVALID_DATA);
  1279. bSuccess = FALSE;
  1280. }
  1281. else if(bCallByIsValid == FALSE)
  1282. {
  1283. for(DWORD index =0;
  1284. index < pbData->dwNumServer && bSuccess == TRUE;
  1285. index++)
  1286. {
  1287. //
  1288. // NULL terminate string...
  1289. //
  1290. pbData->m_szTargetServer[index][MAX_COMPUTERNAME_LENGTH+1] = _TEXT('\0');
  1291. dwLen = _tcslen(pbData->m_szTargetServer[index]);
  1292. if(dwLen == 0 || dwLen >= MAX_COMPUTERNAME_LENGTH + 1)
  1293. {
  1294. SetLastError(ERROR_INVALID_DATA);
  1295. bSuccess = FALSE;
  1296. }
  1297. }
  1298. }
  1299. return bSuccess;
  1300. }
  1301. //------------------------------------------------------------------------
  1302. BOOL
  1303. CSsyncLicensePack::CopyWorkObjectData(
  1304. OUT PSSYNCLICENSEPACK* ppbDest,
  1305. OUT PDWORD pcbDest,
  1306. IN PSSYNCLICENSEPACK pbSrc,
  1307. IN DWORD cbSrc
  1308. )
  1309. /*++
  1310. Copy a sync. license pack work object data.
  1311. --*/
  1312. {
  1313. DWORD dwStatus = ERROR_SUCCESS;
  1314. if(ppbDest == NULL || pcbDest == NULL)
  1315. {
  1316. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  1317. TLSASSERT(FALSE);
  1318. goto cleanup;
  1319. }
  1320. if(CopyBinaryData(
  1321. (PBYTE *)ppbDest,
  1322. pcbDest,
  1323. (PBYTE) pbSrc,
  1324. cbSrc
  1325. ) == FALSE)
  1326. {
  1327. dwStatus = GetLastError();
  1328. }
  1329. cleanup:
  1330. return dwStatus == ERROR_SUCCESS;
  1331. }
  1332. //---------------------------------------------------------------------------
  1333. BOOL
  1334. CSsyncLicensePack::CleanupWorkObjectData(
  1335. IN OUT PSSYNCLICENSEPACK* ppbData,
  1336. IN OUT PDWORD pcbData
  1337. )
  1338. /*++
  1339. Cleanup a sync. license pack work object data.
  1340. --*/
  1341. {
  1342. if(ppbData != NULL && pcbData != NULL)
  1343. {
  1344. FreeMemory(*ppbData);
  1345. *ppbData = NULL;
  1346. *pcbData = 0;
  1347. }
  1348. return TRUE;
  1349. }
  1350. //---------------------------------------------------------------------------
  1351. BOOL
  1352. CSsyncLicensePack::IsJobCompleted(
  1353. IN PSSYNCLICENSEPACK pbData,
  1354. IN DWORD cbData
  1355. )
  1356. /*++
  1357. Detemine if Job is completed.
  1358. --*/
  1359. {
  1360. return (pbData == NULL) ? TRUE : pbData->bCompleted;
  1361. }
  1362. //---------------------------------------------------------------------------
  1363. void
  1364. _AnnounceLicensePackToServers(
  1365. IN CWorkObject* ptr,
  1366. IN PTLSLICENSEPACK pLicensePack,
  1367. IN PDWORD pdwCount,
  1368. IN TCHAR pszServerList[][MAX_COMPUTERNAME_LENGTH+2],
  1369. IN BOOL* pbSsyncStatus
  1370. )
  1371. /*++
  1372. Abstract:
  1373. Sync. a license pack to list of remote server.
  1374. Parameter:
  1375. ptr : pointer to work object that started this call.
  1376. pLicensePack : Pointer to license keypack to sync. with
  1377. list of remote server.
  1378. pdwCount : On input, number of license server to push sync,
  1379. on output, number of license server successfully sync.
  1380. pszServerList : Pointer to list of remote server.
  1381. pbSsyncStatus : Pointer to an array to receive push sync status.
  1382. Returns:
  1383. None, all error are ignored.
  1384. --*/
  1385. {
  1386. DWORD dwStatus = ERROR_SUCCESS;
  1387. TLSReplRecord record;
  1388. DWORD dwNumServer = *pdwCount;
  1389. DWORD dwIndex;
  1390. TLS_HANDLE hHandle;
  1391. RPC_STATUS rpcStatus;
  1392. *pdwCount = 0;
  1393. //
  1394. // Setup replication record
  1395. //
  1396. record.dwReplCode = REPLICATIONCODE_SYNC;
  1397. record.dwUnionType = UNION_TYPE_LICENSEPACK;
  1398. record.w.ReplLicPack = *pLicensePack;
  1399. //
  1400. // Announce to all server in the list
  1401. //
  1402. for( dwIndex = 0;
  1403. dwIndex < dwNumServer && ptr->IsWorkManagerShuttingDown() == FALSE;
  1404. dwIndex++ )
  1405. {
  1406. if(pbSsyncStatus[dwIndex] == FALSE)
  1407. {
  1408. hHandle = TLSConnectAndEstablishTrust(
  1409. pszServerList[dwIndex],
  1410. NULL
  1411. );
  1412. if(hHandle != NULL)
  1413. {
  1414. DWORD dwSupportFlags = 0;
  1415. dwStatus = TLSGetSupportFlags(
  1416. hHandle,
  1417. &dwSupportFlags
  1418. );
  1419. // License Keypack is not replicated if License server version < license Keypack version
  1420. if ((dwStatus == RPC_S_OK) && !(dwSupportFlags & SUPPORT_WHISTLER_CAL))
  1421. {
  1422. continue;
  1423. }
  1424. // If the call fails => Windows 2000 LS
  1425. else if(dwStatus != RPC_S_OK)
  1426. {
  1427. continue;
  1428. }
  1429. rpcStatus = TLSAnnounceLicensePack(
  1430. hHandle,
  1431. &record,
  1432. &dwStatus
  1433. );
  1434. if(rpcStatus != RPC_S_OK)
  1435. {
  1436. // this server might be down, mark it so that
  1437. // we don't retry again
  1438. pbSsyncStatus[dwIndex] = TRUE;
  1439. }
  1440. else if(dwStatus == LSERVER_E_SERVER_BUSY)
  1441. {
  1442. // retry only when server return busy status
  1443. pbSsyncStatus[dwIndex] = FALSE;
  1444. }
  1445. else
  1446. {
  1447. // any error, just don't bother trying again
  1448. pbSsyncStatus[dwIndex] = TRUE;
  1449. }
  1450. }
  1451. else
  1452. {
  1453. // server is not available, don't ssync again
  1454. pbSsyncStatus[dwIndex] = TRUE;
  1455. }
  1456. if(hHandle != NULL)
  1457. {
  1458. TLSDisconnectFromServer(hHandle);
  1459. hHandle = NULL;
  1460. }
  1461. }
  1462. if(pbSsyncStatus[dwIndex] == TRUE)
  1463. {
  1464. (*pdwCount)++;
  1465. }
  1466. }
  1467. return;
  1468. }
  1469. //---------------------------------------------------------------------------
  1470. DWORD
  1471. _SsyncOneLocalLicensePack(
  1472. IN CSsyncLicensePack* ptr,
  1473. IN PSSYNCLICENSEPACK pSsyncLkp
  1474. )
  1475. /*++
  1476. Abstract:
  1477. Sync. one license pack to one remote server.
  1478. Parameter:
  1479. Ptr : Pointer to CSsyncLicensePack work object.
  1480. pSsyncLkp : Pinter to PSSYNCLICENSEPACK.
  1481. Returns:
  1482. ERROR_SUCCESS or error code.
  1483. --*/
  1484. {
  1485. DWORD dwStatus = ERROR_SUCCESS;
  1486. PTLSDbWorkSpace pDbWkSpace = NULL;
  1487. TLSLICENSEPACK LicensePackSearch;
  1488. TLSLICENSEPACK LicensePack;
  1489. DWORD dwSuccessCount = 0;
  1490. //
  1491. // Allocate DB Work Space.
  1492. //
  1493. pDbWkSpace = AllocateWorkSpace(SSYNC_DBWORKSPACE_TIMEOUT);
  1494. if(pDbWkSpace == NULL)
  1495. {
  1496. SetLastError(dwStatus = TLS_I_SSYNCLKP_SERVER_BUSY);
  1497. TLSLogInfoEvent(TLS_I_SSYNCLKP_SERVER_BUSY);
  1498. goto cleanup;
  1499. }
  1500. try {
  1501. LicensePackSearch.dwKeyPackId = pSsyncLkp->dwKeyPackId;
  1502. //
  1503. // retrieve license pack
  1504. //
  1505. dwStatus = TLSDBKeyPackFind(
  1506. pDbWkSpace,
  1507. TRUE,
  1508. LICENSEDPACK_PROCESS_DWINTERNAL,
  1509. &LicensePackSearch,
  1510. &LicensePack
  1511. );
  1512. if(dwStatus != ERROR_SUCCESS)
  1513. {
  1514. if(dwStatus != TLS_E_RECORD_NOTFOUND)
  1515. {
  1516. TLSLogEvent(
  1517. EVENTLOG_INFORMATION_TYPE,
  1518. TLS_W_SSYNCLKP,
  1519. dwStatus
  1520. );
  1521. }
  1522. goto cleanup;
  1523. }
  1524. if(IsLicensePackRepl(&LicensePack) == FALSE)
  1525. {
  1526. goto cleanup;
  1527. }
  1528. if(ptr->IsWorkManagerShuttingDown() == TRUE)
  1529. {
  1530. SetLastError(dwStatus = TLS_I_SERVICE_STOP);
  1531. goto cleanup;
  1532. }
  1533. //
  1534. // Make sure local Server ID and Server Name is correct
  1535. //
  1536. SAFESTRCPY(LicensePack.szInstallId, pSsyncLkp->m_szServerId);
  1537. SAFESTRCPY(LicensePack.szTlsServerName, pSsyncLkp->m_szServerName);
  1538. dwSuccessCount = pSsyncLkp->dwNumServer;
  1539. _AnnounceLicensePackToServers(
  1540. ptr,
  1541. &LicensePack,
  1542. &dwSuccessCount,
  1543. pSsyncLkp->m_szTargetServer,
  1544. pSsyncLkp->m_bSsync
  1545. );
  1546. if(dwSuccessCount != pSsyncLkp->dwNumServer)
  1547. {
  1548. TLSLogInfoEvent(TLS_I_SSYNCLKP_FAILED);
  1549. }
  1550. }
  1551. catch( SE_Exception e ) {
  1552. SetLastError(dwStatus = e.getSeNumber());
  1553. }
  1554. catch(...) {
  1555. SetLastError(dwStatus = TLS_E_INTERNAL);
  1556. TLSASSERT(FALSE);
  1557. }
  1558. cleanup:
  1559. if(pDbWkSpace != NULL)
  1560. {
  1561. ReleaseWorkSpace(&pDbWkSpace);
  1562. }
  1563. return dwStatus;
  1564. }
  1565. //----------------------------------------------------------------------------
  1566. DWORD
  1567. _SsyncAllLocalLicensePack(
  1568. IN CSsyncLicensePack* ptr,
  1569. IN PSSYNCLICENSEPACK pSsyncLkp
  1570. )
  1571. /*++
  1572. Sync. all local license pack to a remote server.
  1573. --*/
  1574. {
  1575. DWORD dwStatus = ERROR_SUCCESS;
  1576. PTLSDbWorkSpace pDbWkSpace = NULL;
  1577. TLSLICENSEPACK LicensePackSearch;
  1578. TLSLICENSEPACK LicensePack;
  1579. DWORD dwSuccessCount = 0;
  1580. BOOL SyncStatus[SSYNCLKP_MAX_TARGET];
  1581. //
  1582. // Allocate DB Work Space.
  1583. //
  1584. pDbWkSpace = AllocateWorkSpace(SSYNC_DBWORKSPACE_TIMEOUT);
  1585. if(pDbWkSpace == NULL)
  1586. {
  1587. SetLastError(dwStatus = TLS_I_SSYNCLKP_SERVER_BUSY);
  1588. TLSLogInfoEvent(TLS_I_SSYNCLKP_SERVER_BUSY);
  1589. goto cleanup;
  1590. }
  1591. try {
  1592. dwStatus = TLSDBKeyPackEnumBegin(
  1593. pDbWkSpace,
  1594. FALSE,
  1595. 0,
  1596. NULL
  1597. );
  1598. if(dwStatus == ERROR_SUCCESS)
  1599. {
  1600. while((dwStatus = TLSDBKeyPackEnumNext(pDbWkSpace, &LicensePack)) == ERROR_SUCCESS)
  1601. {
  1602. // unreliable, system time between two machine might not work,
  1603. // force sync and let remote server update its data.
  1604. if(CompareFileTime(
  1605. &LicensePack.ftLastModifyTime,
  1606. &ptr->GetWorkData()->m_ftStartSyncTime
  1607. ) < 0)
  1608. {
  1609. continue;
  1610. }
  1611. if(ptr->IsWorkManagerShuttingDown() == TRUE)
  1612. {
  1613. break;
  1614. }
  1615. if(IsLicensePackRepl(&LicensePack) == FALSE)
  1616. {
  1617. continue;
  1618. }
  1619. //
  1620. // Make sure local Server ID and Server Name is correct
  1621. //
  1622. SAFESTRCPY(LicensePack.szInstallId, pSsyncLkp->m_szServerId);
  1623. SAFESTRCPY(LicensePack.szTlsServerName, pSsyncLkp->m_szServerName);
  1624. memset(SyncStatus, 0, sizeof(SyncStatus));
  1625. dwSuccessCount = pSsyncLkp->dwNumServer;
  1626. _AnnounceLicensePackToServers(
  1627. ptr,
  1628. &LicensePack,
  1629. &dwSuccessCount,
  1630. pSsyncLkp->m_szTargetServer,
  1631. SyncStatus
  1632. );
  1633. }
  1634. TLSDBKeyPackEnumEnd(pDbWkSpace);
  1635. }
  1636. //
  1637. // ignore all error
  1638. //
  1639. dwStatus = ERROR_SUCCESS;
  1640. }
  1641. catch( SE_Exception e ) {
  1642. SetLastError(dwStatus = e.getSeNumber());
  1643. }
  1644. catch(...) {
  1645. SetLastError(dwStatus = TLS_E_WORKMANAGER_INTERNAL);
  1646. }
  1647. cleanup:
  1648. if(pDbWkSpace != NULL)
  1649. {
  1650. ReleaseWorkSpace(&pDbWkSpace);
  1651. }
  1652. return dwStatus;
  1653. }
  1654. //----------------------------------------------------------------------------
  1655. DWORD
  1656. CSsyncLicensePack::ExecuteJob(
  1657. IN PSSYNCLICENSEPACK pSsyncLkp,
  1658. IN DWORD cbSsyncLkp
  1659. )
  1660. /*++
  1661. Execute a CSsyncLicensePack work object.
  1662. --*/
  1663. {
  1664. DWORD dwStatus = ERROR_SUCCESS;
  1665. DBGPrintf(
  1666. DBG_INFORMATION,
  1667. DBG_FACILITY_JOB,
  1668. DBGLEVEL_FUNCTION_TRACE,
  1669. _TEXT("%s ...\n"),
  1670. GetJobDescription()
  1671. );
  1672. TLSASSERT(pSsyncLkp != NULL && cbSsyncLkp != 0);
  1673. if(VerifyWorkObjectData(FALSE, pSsyncLkp, cbSsyncLkp) == FALSE)
  1674. {
  1675. TLSASSERT(FALSE);
  1676. SetLastError(ERROR_INVALID_DATA);
  1677. pSsyncLkp->bCompleted = TRUE;
  1678. return ERROR_INVALID_DATA;
  1679. }
  1680. try {
  1681. if(pSsyncLkp->dwSyncType == SSYNC_ONE_LKP)
  1682. {
  1683. dwStatus = _SsyncOneLocalLicensePack(this, pSsyncLkp);
  1684. }
  1685. else
  1686. {
  1687. dwStatus = _SsyncAllLocalLicensePack(this, pSsyncLkp);
  1688. }
  1689. }
  1690. catch( SE_Exception e )
  1691. {
  1692. DBGPrintf(
  1693. DBG_ERROR,
  1694. DBG_FACILITY_WORKMGR,
  1695. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  1696. _TEXT("CSsyncLicensePack::ExecuteJob() : Job has cause exception %d\n"),
  1697. e.getSeNumber()
  1698. );
  1699. dwStatus = e.getSeNumber();
  1700. TLSASSERT(FALSE);
  1701. }
  1702. catch(...)
  1703. {
  1704. DBGPrintf(
  1705. DBG_ERROR,
  1706. DBG_FACILITY_WORKMGR,
  1707. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  1708. _TEXT("CSsyncLicensePack::ExecuteJob() : Job has cause unknown exception\n")
  1709. );
  1710. TLSASSERT(FALSE);
  1711. }
  1712. if(dwStatus == TLS_I_SSYNCLKP_SERVER_BUSY || dwStatus == TLS_I_SSYNCLKP_FAILED)
  1713. {
  1714. // retry operation
  1715. pSsyncLkp->bCompleted = FALSE;
  1716. }
  1717. else
  1718. {
  1719. pSsyncLkp->bCompleted = TRUE;
  1720. }
  1721. DBGPrintf(
  1722. DBG_INFORMATION,
  1723. DBG_FACILITY_JOB,
  1724. DBGLEVEL_FUNCTION_TRACE,
  1725. _TEXT("%s ended...\n"),
  1726. GetJobDescription()
  1727. );
  1728. return dwStatus;
  1729. }
  1730. //--------------------------------------------------------------------------------------
  1731. LPCTSTR
  1732. CSsyncLicensePack::GetJobDescription()
  1733. /*++
  1734. Get CSsyncLicensePack job description, use only
  1735. by debug tracing.
  1736. --*/
  1737. {
  1738. PSSYNCLICENSEPACK pbData = GetWorkData();
  1739. memset(m_szJobDescription, 0, sizeof(m_szJobDescription));
  1740. if(pbData != NULL)
  1741. {
  1742. _sntprintf(
  1743. m_szJobDescription,
  1744. sizeof(m_szJobDescription)/sizeof(m_szJobDescription[0]) - 1,
  1745. SSYNCLICENSEKEYPACK_DESCRIPTION,
  1746. (pbData->dwSyncType == SSYNC_ALL_LKP) ? _TEXT("ALL") : _TEXT("One"),
  1747. pbData->m_szTargetServer
  1748. );
  1749. }
  1750. return m_szJobDescription;
  1751. }
  1752. //////////////////////////////////////////////////////////////////////////
  1753. //
  1754. // CAnnounceResponse
  1755. //
  1756. //////////////////////////////////////////////////////////////////////////
  1757. BOOL
  1758. CAnnounceResponse::VerifyWorkObjectData(
  1759. IN BOOL bCallByIsValid, // invoke by IsValid() function.
  1760. IN PANNOUNCERESPONSEWO pbData,
  1761. IN DWORD cbData
  1762. )
  1763. /*++
  1764. Verify CAnnounceResponse work object data.
  1765. --*/
  1766. {
  1767. BOOL bSuccess = TRUE;
  1768. DWORD dwLen;
  1769. if(pbData == NULL || cbData == 0 || cbData != pbData->dwStructSize)
  1770. {
  1771. bSuccess = FALSE;
  1772. }
  1773. if(bSuccess == TRUE)
  1774. {
  1775. pbData->m_szTargetServerId[LSERVER_MAX_STRING_SIZE+1] = _TEXT('\0');
  1776. dwLen = _tcslen(pbData->m_szTargetServerId);
  1777. if(dwLen == 0 || dwLen >= LSERVER_MAX_STRING_SIZE + 1)
  1778. {
  1779. bSuccess = FALSE;
  1780. }
  1781. }
  1782. if(bSuccess == FALSE)
  1783. {
  1784. TLSASSERT(FALSE);
  1785. SetLastError(ERROR_INVALID_DATA);
  1786. }
  1787. return bSuccess;
  1788. }
  1789. //------------------------------------------------------------------------
  1790. BOOL
  1791. CAnnounceResponse::CopyWorkObjectData(
  1792. OUT PANNOUNCERESPONSEWO* ppbDest,
  1793. OUT PDWORD pcbDest,
  1794. IN PANNOUNCERESPONSEWO pbSrc,
  1795. IN DWORD cbSrc
  1796. )
  1797. /*++
  1798. Copy CAnnounceResponse work object data.
  1799. --*/
  1800. {
  1801. DWORD dwStatus = ERROR_SUCCESS;
  1802. if(ppbDest == NULL || pcbDest == NULL)
  1803. {
  1804. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  1805. TLSASSERT(FALSE);
  1806. goto cleanup;
  1807. }
  1808. if(CopyBinaryData(
  1809. (PBYTE *)ppbDest,
  1810. pcbDest,
  1811. (PBYTE) pbSrc,
  1812. cbSrc
  1813. ) == FALSE)
  1814. {
  1815. dwStatus = GetLastError();
  1816. }
  1817. cleanup:
  1818. return dwStatus == ERROR_SUCCESS;
  1819. }
  1820. //---------------------------------------------------------------------------
  1821. BOOL
  1822. CAnnounceResponse::CleanupWorkObjectData(
  1823. IN OUT PANNOUNCERESPONSEWO* ppbData,
  1824. IN OUT PDWORD pcbData
  1825. )
  1826. /*++
  1827. cleanup CAnnounceResponse work object data.
  1828. --*/
  1829. {
  1830. if(ppbData != NULL && pcbData != NULL)
  1831. {
  1832. FreeMemory(*ppbData);
  1833. *ppbData = NULL;
  1834. *pcbData = 0;
  1835. }
  1836. return TRUE;
  1837. }
  1838. //---------------------------------------------------------------------------
  1839. BOOL
  1840. CAnnounceResponse::IsJobCompleted(
  1841. IN PANNOUNCERESPONSEWO pbData,
  1842. IN DWORD cbData
  1843. )
  1844. /*++
  1845. Detemine if job completed.
  1846. --*/
  1847. {
  1848. return (pbData == NULL) ? TRUE : pbData->bCompleted;
  1849. }
  1850. //---------------------------------------------------------------------------
  1851. DWORD
  1852. CAnnounceResponse::ExecuteJob(
  1853. IN PANNOUNCERESPONSEWO pbData,
  1854. IN DWORD cbData
  1855. )
  1856. /*++
  1857. Execute a CAnnounceResponse work object.
  1858. --*/
  1859. {
  1860. DWORD dwStatus = ERROR_SUCCESS;
  1861. TLS_HANDLE hHandle = NULL;
  1862. DBGPrintf(
  1863. DBG_INFORMATION,
  1864. DBG_FACILITY_JOB,
  1865. DBGLEVEL_FUNCTION_TRACE,
  1866. _TEXT("%s ...\n"),
  1867. GetJobDescription()
  1868. );
  1869. TLServerInfo ServerInfo;
  1870. dwStatus = TLSLookupRegisteredServer(
  1871. pbData->m_szTargetServerId,
  1872. NULL,
  1873. NULL,
  1874. &ServerInfo
  1875. );
  1876. if(dwStatus == ERROR_SUCCESS)
  1877. {
  1878. DBGPrintf(
  1879. DBG_INFORMATION,
  1880. DBG_FACILITY_JOB,
  1881. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  1882. _TEXT("Announcing server to %s...\n"),
  1883. ServerInfo.GetServerName()
  1884. );
  1885. if(IsWorkManagerShuttingDown() == FALSE)
  1886. {
  1887. dwStatus = TLSAnnounceServerToRemoteServer(
  1888. TLSANNOUNCE_TYPE_RESPONSE,
  1889. ServerInfo.GetServerId(),
  1890. ServerInfo.GetServerDomain(),
  1891. ServerInfo.GetServerName(),
  1892. pbData->m_szLocalServerId,
  1893. pbData->m_szLocalScope,
  1894. pbData->m_szLocalServerName,
  1895. &(pbData->m_ftLastShutdownTime)
  1896. );
  1897. }
  1898. }
  1899. else
  1900. {
  1901. TLSASSERT(FALSE);
  1902. }
  1903. //
  1904. // Discovery run once
  1905. //
  1906. pbData->bCompleted = TRUE;
  1907. DBGPrintf(
  1908. DBG_INFORMATION,
  1909. DBG_FACILITY_JOB,
  1910. DBGLEVEL_FUNCTION_TRACE,
  1911. _TEXT("%s ended...\n"),
  1912. GetJobDescription()
  1913. );
  1914. return dwStatus;
  1915. }
  1916. //----------------------------------------------------------------------------------------------
  1917. LPCTSTR
  1918. CAnnounceResponse::GetJobDescription()
  1919. /*++
  1920. Retrieve CAnnounceResponse job description.
  1921. --*/
  1922. {
  1923. memset(m_szJobDescription, 0, sizeof(m_szJobDescription));
  1924. PANNOUNCERESPONSEWO pbData = GetWorkData();
  1925. if(pbData != NULL)
  1926. {
  1927. _sntprintf(
  1928. m_szJobDescription,
  1929. sizeof(m_szJobDescription)/sizeof(m_szJobDescription[0]) - 1,
  1930. ANNOUNCERESPONSE_DESCRIPTION,
  1931. pbData->m_szTargetServerId
  1932. );
  1933. }
  1934. return m_szJobDescription;
  1935. }