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.

3505 lines
87 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996-1998
  5. //
  6. // File: tlsapi.cpp
  7. //
  8. // Contents:
  9. //
  10. // History: 12-09-97 HueiWang Created
  11. //
  12. //---------------------------------------------------------------------------
  13. #include <windows.h>
  14. #include <wincrypt.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <tchar.h>
  18. #include <rpc.h>
  19. #include <ntsecapi.h>
  20. #include <lmcons.h>
  21. #include <lmserver.h>
  22. #include <lmerr.h>
  23. #include <lmapibuf.h>
  24. #include <ntdsapi.h>
  25. #include <dsrole.h>
  26. #include <lmjoin.h>
  27. #include <winldap.h>
  28. #include <winsock2.h>
  29. #include <dsgetdc.h>
  30. //
  31. // Only include RNG functions from tssec
  32. //
  33. #define NO_INCLUDE_LICENSING 1
  34. #include <tssec.h>
  35. #include "lscommon.h"
  36. #include "tlsrpc.h"
  37. #include "tlsapi.h"
  38. #include "tlsapip.h"
  39. #include "lscsp.h"
  40. #include "license.h"
  41. static BOOL g_bLog = 1;
  42. extern "C" {
  43. VOID LogMsg(
  44. PWCHAR msgFormat,
  45. ...
  46. );
  47. }
  48. extern "C" DWORD WINAPI
  49. TLSConnect(
  50. handle_t binding,
  51. TLS_HANDLE *pphContext
  52. );
  53. extern "C" DWORD WINAPI
  54. TLSDisconnect(
  55. TLS_HANDLE* pphContext
  56. );
  57. extern "C" BOOL
  58. IsSystemService();
  59. #include <lmcons.h> // Netxxx API includes
  60. #include <lmserver.h>
  61. #include <lmerr.h>
  62. #include <lmapibuf.h>
  63. #define DISCOVERY_INTERVAL (60 * 60 * 1000)
  64. static HANDLE g_hCachingThreadExit = NULL;
  65. static HANDLE g_hImmediateDiscovery = NULL;
  66. static HANDLE g_hDiscoverySoon = NULL;
  67. static BOOL g_fOffSiteLicenseServer = FALSE;
  68. static PSEC_WINNT_AUTH_IDENTITY g_pRpcIdentity = NULL;
  69. #define REG_DOMAIN_SERVER_MULTI L"DomainLicenseServerMulti"
  70. #define TERMINAL_SERVICE_PARAM_DISCOVERY "SYSTEM\\CurrentControlSet\\Services\\TermService\\Parameters\\LicenseServers"
  71. // 2 second timeout
  72. #define SERVER_NP_TIMEOUT (2 * 1000)
  73. #define INSTALL_CERT_DELAY (5 * 1000)
  74. BOOL g_fInDomain = -1;
  75. LONG lLibUsage = 0;
  76. typedef struct {
  77. TLS_HANDLE *hBinding;
  78. DWORD dwTimeout; // In milliseconds - INFINITE for none
  79. LARGE_INTEGER timeInitial; // As returned by QueryPerformanceCounter
  80. } LS_ENUM_PARAM, *PLS_ENUM_PARAM;
  81. void * MIDL_user_allocate(size_t size)
  82. {
  83. return(HeapAlloc(GetProcessHeap(), 0, size));
  84. }
  85. void MIDL_user_free( void *pointer)
  86. {
  87. HeapFree(GetProcessHeap(), 0, pointer);
  88. }
  89. //
  90. // FUNCTIONS: StartTime()
  91. // EndTime()
  92. //
  93. // USAGE:
  94. // StartTime();
  95. // // Do some work.
  96. // mseconds = EndTime();
  97. //
  98. // RETURN VALUE:
  99. // Milliseconds between StartTime() and EndTime() calls.
  100. LARGE_INTEGER TimeT;
  101. void StartTimeT(void)
  102. {
  103. QueryPerformanceCounter(&TimeT);
  104. }
  105. ULONG EndTimeT()
  106. {
  107. LARGE_INTEGER liDiff;
  108. LARGE_INTEGER liFreq;
  109. QueryPerformanceCounter(&liDiff);
  110. liDiff.QuadPart -= TimeT.QuadPart;
  111. liDiff.QuadPart *= 1000; // Adjust to milliseconds, shouldn't overflow...
  112. (void)QueryPerformanceFrequency(&liFreq);
  113. return ((ULONG)(liDiff.QuadPart / liFreq.QuadPart));
  114. }
  115. //+------------------------------------------------------------------------
  116. // Function: ConnectToLsServer()
  117. //
  118. // Description:
  119. //
  120. // Binding to sepecific hydra license server
  121. //
  122. // Arguments:
  123. //
  124. // szLsServer - Hydra License Server name
  125. //
  126. // Return Value:
  127. //
  128. // RPC binding handle or NULL if error, use GetLastError() to retrieve
  129. // error.
  130. //-------------------------------------------------------------------------
  131. static TLS_HANDLE WINAPI
  132. ConnectLsServer(
  133. LPTSTR szLsServer,
  134. LPTSTR szProtocol,
  135. LPTSTR szEndPoint,
  136. DWORD dwAuthLevel )
  137. {
  138. LPTSTR szBindingString;
  139. RPC_BINDING_HANDLE hBinding=NULL;
  140. RPC_STATUS status;
  141. TLS_HANDLE pContext=NULL;
  142. BOOL fSuccess;
  143. HKEY hKey = NULL;
  144. DWORD dwType;
  145. DWORD cbData;
  146. DWORD dwErr;
  147. DWORD dwNumRetries = 1; // default to one retry
  148. LPWSTR pszServerPrincipalName = NULL;
  149. if(g_bLog)
  150. {
  151. if (NULL != szLsServer)
  152. LogMsg(L"\nSERVER=%s\n",szLsServer);
  153. }
  154. //
  155. // If this isn't local
  156. //
  157. if ((NULL != szLsServer) && (NULL != szEndPoint))
  158. {
  159. TCHAR szPipeName[MAX_PATH+1];
  160. if (lstrlen(szLsServer) > ((sizeof(szPipeName) / sizeof(TCHAR)) - 26))
  161. {
  162. if(g_bLog)
  163. LogMsg(L"Server name too long\n");
  164. return NULL;
  165. }
  166. //
  167. // First check if license server named pipe exists
  168. //
  169. wsprintf(szPipeName,TEXT("\\\\%s\\pipe\\%s"),szLsServer,TEXT(SZSERVICENAME));
  170. if(g_bLog)
  171. StartTimeT();
  172. fSuccess = WaitNamedPipe(szPipeName,SERVER_NP_TIMEOUT);
  173. dwErr = GetLastError();
  174. if(g_bLog)
  175. {
  176. ULONG ulTime = EndTimeT();
  177. LogMsg(L"WaitNamedPipe time == %lu\n",ulTime);
  178. }
  179. if (!fSuccess)
  180. {
  181. if(g_bLog)
  182. LogMsg(L"WaitNamedPipe (%s) failed 0x%x\n",szPipeName,dwErr);
  183. return NULL;
  184. }
  185. }
  186. else if(g_bLog)
  187. LogMsg(L"Not trying WaitNamedPipe on local machine\n");
  188. dwErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  189. TEXT(LSERVER_DISCOVERY_PARAMETER_KEY),
  190. 0,
  191. KEY_READ,
  192. &hKey);
  193. if (dwErr == ERROR_SUCCESS)
  194. {
  195. cbData = sizeof(dwNumRetries);
  196. dwErr = RegQueryValueEx(hKey,
  197. L"NumRetries",
  198. NULL,
  199. &dwType,
  200. (PBYTE)&dwNumRetries,
  201. &cbData);
  202. RegCloseKey(hKey);
  203. }
  204. status = RpcStringBindingCompose(0,
  205. szProtocol,
  206. szLsServer,
  207. szEndPoint,
  208. 0,
  209. &szBindingString);
  210. if(status!=RPC_S_OK)
  211. {
  212. if(g_bLog)
  213. LogMsg(L"RpcStringBindingCompose failed 0x%x\n",status);
  214. return NULL;
  215. }
  216. status=RpcBindingFromStringBinding( szBindingString, &hBinding);
  217. RpcStringFree( &szBindingString );
  218. if(status != RPC_S_OK)
  219. {
  220. if(g_bLog)
  221. LogMsg(L"RpcBindingFromStringBinding failed 0x%x\n",status);
  222. return NULL;
  223. }
  224. status = RpcMgmtSetComTimeout(hBinding,RPC_C_BINDING_MIN_TIMEOUT);
  225. if (status != RPC_S_OK)
  226. {
  227. if(g_bLog)
  228. LogMsg(L"RpcMgmtSetComTimeout failed 0x%x\n",status);
  229. return NULL;
  230. }
  231. BOOL fRetry = TRUE;
  232. //
  233. // Find the principle name
  234. //
  235. status = RpcMgmtInqServerPrincName(hBinding,
  236. RPC_C_AUTHN_GSS_NEGOTIATE,
  237. &pszServerPrincipalName);
  238. if(status == RPC_S_OK)
  239. {
  240. status=RpcBindingSetAuthInfo(hBinding,
  241. pszServerPrincipalName,
  242. dwAuthLevel,
  243. RPC_C_AUTHN_GSS_NEGOTIATE,
  244. g_pRpcIdentity,
  245. 0);
  246. RpcStringFree(&pszServerPrincipalName);
  247. }
  248. else
  249. goto Label;
  250. if(status == RPC_S_OK)
  251. {
  252. retry:
  253. // Obtain context handle from server
  254. status = TLSConnect( hBinding, &pContext );
  255. if(status != ERROR_SUCCESS)
  256. {
  257. pContext = NULL;
  258. if( status == RPC_S_UNKNOWN_AUTHN_SERVICE || status == ERROR_ACCESS_DENIED && fRetry)
  259. {
  260. Label:
  261. fRetry = FALSE;
  262. //Try again with no security set
  263. status = RpcBindingSetAuthInfo(hBinding,
  264. 0,
  265. dwAuthLevel,
  266. RPC_C_AUTHN_WINNT,
  267. g_pRpcIdentity,
  268. 0);
  269. if(status == RPC_S_OK)
  270. {
  271. // Obtain context handle from server
  272. status = TLSConnect( hBinding, &pContext );
  273. }
  274. }
  275. if((status == RPC_S_CALL_FAILED) || (status == RPC_S_CALL_FAILED_DNE))
  276. {
  277. //
  278. // Workaround for an RPC problem where the first RPC after
  279. // the LS starts, fails
  280. //
  281. if (dwNumRetries > 0)
  282. {
  283. dwNumRetries--;
  284. goto retry;
  285. }
  286. }
  287. }
  288. }
  289. //
  290. // Memory leak
  291. //
  292. if(hBinding != NULL)
  293. {
  294. RpcBindingFree(&hBinding);
  295. }
  296. SetLastError((status == RPC_S_OK) ? ERROR_SUCCESS : status);
  297. return pContext;
  298. }
  299. //+------------------------------------------------------------------------
  300. // Function: BindAnyServer()
  301. //
  302. // Description:
  303. //
  304. // Call back routine for TLSConnectToAnyLsServer()
  305. //
  306. // Arguments:
  307. //
  308. // See EnumerateTlsServer()
  309. //
  310. // Return Value:
  311. //
  312. // Always TRUE to terminate server enumeration
  313. //-------------------------------------------------------------------------
  314. static BOOL
  315. BindAnyServer(
  316. TLS_HANDLE hRpcBinding,
  317. LPCTSTR pszServerName,
  318. HANDLE dwUserData
  319. )
  320. /*++
  321. ++*/
  322. {
  323. PLS_ENUM_PARAM pParam = (PLS_ENUM_PARAM) dwUserData;
  324. TLS_HANDLE* hBinding = pParam->hBinding;
  325. RPC_STATUS rpcStatus;
  326. HKEY hKey = NULL;
  327. DWORD dwBuffer = 0;
  328. DWORD cbBuffer = sizeof (DWORD);
  329. DWORD dwErrCode = 0;
  330. // Skip Windows 2000 License servers
  331. if (hRpcBinding != NULL)
  332. {
  333. DWORD dwSupportFlags = 0;
  334. dwErrCode = TLSGetSupportFlags(
  335. hRpcBinding,
  336. &dwSupportFlags
  337. );
  338. if ((dwErrCode == RPC_S_OK) && !(dwSupportFlags & SUPPORT_WHISTLER_CAL))
  339. {
  340. return FALSE;
  341. }
  342. // If the call fails => Windows 2000 LS
  343. else if(dwErrCode != RPC_S_OK)
  344. {
  345. return FALSE;
  346. }
  347. *hBinding=hRpcBinding;
  348. return TRUE;
  349. }
  350. if (pParam->dwTimeout != INFINITE)
  351. {
  352. LARGE_INTEGER timeDiff;
  353. LARGE_INTEGER timeFreq;
  354. *hBinding=hRpcBinding;
  355. QueryPerformanceCounter(&timeDiff);
  356. timeDiff.QuadPart -= pParam->timeInitial.QuadPart;
  357. timeDiff.QuadPart *= 1000; // Adjust to milliseconds, shouldn't overflow
  358. (void)QueryPerformanceFrequency(&timeFreq);
  359. if (((ULONG)(timeDiff.QuadPart / timeFreq.QuadPart)) > pParam->dwTimeout)
  360. {
  361. if(g_bLog)
  362. LogMsg(L"BindAnyServer timed out\n");
  363. return TRUE;
  364. }
  365. }
  366. return FALSE;
  367. }
  368. void
  369. RandomizeArray(LPWSTR *rgwszServers, DWORD cServers)
  370. {
  371. DWORD i;
  372. LPWSTR wszServerTmp;
  373. int val;
  374. if (cServers < 2)
  375. return;
  376. srand(GetTickCount());
  377. for (i = 0; i < cServers; i++)
  378. {
  379. val = rand() % (cServers - i);
  380. if (val == 0)
  381. continue;
  382. //
  383. // Swap # i with # (val+i)
  384. //
  385. wszServerTmp = rgwszServers[i];
  386. rgwszServers[i] = rgwszServers[val+i];
  387. rgwszServers[val+i] = wszServerTmp;
  388. }
  389. }
  390. HRESULT
  391. GetLicenseServersFromReg(LPWSTR wszRegKey, LPWSTR *ppwszServerNames,DWORD *pcServers, LPWSTR **prgwszServers)
  392. {
  393. HRESULT hr = S_OK;
  394. HKEY hKey = NULL;
  395. DWORD dwType;
  396. DWORD cbData = 0;
  397. LPWSTR szServers=NULL, pchServer;
  398. DWORD dwErr;
  399. DWORD i,val;
  400. DWORD iLocalComputer = (DWORD)(-1);
  401. WCHAR szLocalComputerName[MAXCOMPUTERNAMELENGTH+1] = L"";
  402. DWORD cbLocalComputerName=MAXCOMPUTERNAMELENGTH+1;
  403. *ppwszServerNames = NULL;
  404. *prgwszServers = NULL;
  405. dwErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  406. TEXT(LSERVER_DISCOVERY_PARAMETER_KEY),
  407. 0,
  408. KEY_READ,
  409. &hKey);
  410. if (dwErr != ERROR_SUCCESS)
  411. {
  412. hr = HRESULT_FROM_WIN32(dwErr);
  413. goto CleanErr;
  414. }
  415. dwErr = RegQueryValueEx(hKey,
  416. wszRegKey,
  417. NULL,
  418. &dwType,
  419. NULL,
  420. &cbData);
  421. if (dwErr != ERROR_SUCCESS)
  422. {
  423. hr = HRESULT_FROM_WIN32(dwErr);
  424. goto CleanErr;
  425. }
  426. if ((dwType != REG_MULTI_SZ) || (cbData < (2 * sizeof(WCHAR))))
  427. {
  428. hr = E_FAIL;
  429. goto CleanErr;
  430. }
  431. szServers = (LPWSTR) LocalAlloc(LPTR,cbData);
  432. if (NULL == szServers)
  433. {
  434. hr = E_OUTOFMEMORY;
  435. goto CleanErr;
  436. }
  437. dwErr = RegQueryValueEx(hKey,
  438. wszRegKey,
  439. NULL,
  440. &dwType,
  441. (PBYTE)szServers,
  442. &cbData);
  443. if (dwErr != ERROR_SUCCESS)
  444. {
  445. hr = HRESULT_FROM_WIN32(dwErr);
  446. goto CleanErr;
  447. }
  448. for (i = 0, pchServer = szServers; (pchServer != NULL) && (*pchServer != L'\0'); pchServer = wcschr(pchServer,L'\0')+1, i++)
  449. ;
  450. if (i == 0)
  451. {
  452. hr = E_FAIL;
  453. goto CleanErr;
  454. }
  455. *pcServers = i;
  456. *prgwszServers = (LPWSTR *)LocalAlloc(LPTR,sizeof(LPWSTR) * (*pcServers));
  457. if (*prgwszServers == NULL)
  458. {
  459. hr = E_OUTOFMEMORY;
  460. goto CleanErr;
  461. }
  462. // Don't treat error from this function as fatal
  463. GetComputerName(szLocalComputerName, &cbLocalComputerName);
  464. for (i = 0, pchServer = szServers; (i < (*pcServers)) && (pchServer != NULL) && (*pchServer != L'\0'); pchServer = wcschr(pchServer,L'\0')+1, i++) {
  465. (*prgwszServers)[i] = pchServer;
  466. if ((iLocalComputer == (DWORD)(-1)) && (wcscmp(pchServer,szLocalComputerName) == 0))
  467. {
  468. iLocalComputer = i;
  469. }
  470. }
  471. //
  472. // Put local computer at head of list
  473. //
  474. if (iLocalComputer != (DWORD)(-1))
  475. {
  476. if (iLocalComputer != 0)
  477. {
  478. //
  479. // Swap # iLocalComputer with # 0
  480. //
  481. pchServer = (*prgwszServers)[iLocalComputer];
  482. (*prgwszServers)[iLocalComputer] = (*prgwszServers)[0];
  483. (*prgwszServers)[0] = pchServer;
  484. }
  485. RandomizeArray((*prgwszServers)+1,(*pcServers) - 1);
  486. }
  487. else
  488. {
  489. RandomizeArray((*prgwszServers),*pcServers);
  490. }
  491. *ppwszServerNames = szServers;
  492. CleanErr:
  493. if (FAILED(hr))
  494. {
  495. if (NULL != szServers)
  496. {
  497. LocalFree(szServers);
  498. }
  499. if (NULL != *prgwszServers)
  500. {
  501. LocalFree(*prgwszServers);
  502. }
  503. }
  504. if (hKey != NULL)
  505. {
  506. RegCloseKey(hKey);
  507. }
  508. return hr;
  509. }
  510. HRESULT
  511. WriteLicenseServersToReg(LPWSTR wszRegKey, LPWSTR pwszServerNames,DWORD cchServers)
  512. {
  513. HRESULT hr = S_OK;
  514. HKEY hKey = NULL;
  515. DWORD dwType = REG_MULTI_SZ;
  516. DWORD dwErr;
  517. DWORD dwDisp;
  518. //
  519. // Delete the value
  520. //
  521. dwErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  522. TEXT(LSERVER_DISCOVERY_PARAMETER_KEY),
  523. 0,
  524. KEY_WRITE,
  525. &hKey);
  526. if (dwErr == ERROR_SUCCESS)
  527. {
  528. RegDeleteValue(hKey,wszRegKey);
  529. }
  530. if ((pwszServerNames == NULL) || (cchServers < 2))
  531. {
  532. hr = S_OK;
  533. goto CleanErr;
  534. }
  535. if(hKey != NULL)
  536. {
  537. RegCloseKey(hKey);
  538. hKey = NULL;
  539. }
  540. dwErr = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  541. TEXT(LSERVER_DISCOVERY_PARAMETER_KEY),
  542. 0,
  543. TEXT(""),
  544. REG_OPTION_NON_VOLATILE,
  545. KEY_WRITE,
  546. NULL,
  547. &hKey,
  548. &dwDisp);
  549. if (dwErr != ERROR_SUCCESS)
  550. {
  551. hr = HRESULT_FROM_WIN32(dwErr);
  552. goto CleanErr;
  553. }
  554. dwErr = RegSetValueEx(hKey,
  555. wszRegKey,
  556. 0,
  557. dwType,
  558. (CONST BYTE *)pwszServerNames,
  559. cchServers*sizeof(WCHAR));
  560. if (dwErr != ERROR_SUCCESS)
  561. {
  562. hr = HRESULT_FROM_WIN32(dwErr);
  563. goto CleanErr;
  564. }
  565. CleanErr:
  566. if (hKey != NULL)
  567. {
  568. RegCloseKey(hKey);
  569. }
  570. return hr;
  571. }
  572. //
  573. // Free pszDomain using NetApiBufferFree
  574. //
  575. DWORD WINAPI
  576. TLSInDomain(BOOL *pfInDomain, LPWSTR *pszDomain)
  577. {
  578. NET_API_STATUS dwErr;
  579. DSROLE_PRIMARY_DOMAIN_INFO_BASIC *pDomainInfo = NULL;
  580. PDOMAIN_CONTROLLER_INFO pdcInfo = NULL;
  581. if (pfInDomain == NULL)
  582. {
  583. return ERROR_INVALID_PARAMETER;
  584. }
  585. *pfInDomain = FALSE;
  586. //
  587. // Check if we're in a workgroup
  588. //
  589. dwErr = DsRoleGetPrimaryDomainInformation(NULL,
  590. DsRolePrimaryDomainInfoBasic,
  591. (PBYTE *) &pDomainInfo);
  592. if ((dwErr != NO_ERROR) || (pDomainInfo == NULL))
  593. {
  594. return dwErr;
  595. }
  596. switch (pDomainInfo->MachineRole)
  597. {
  598. case DsRole_RoleStandaloneWorkstation:
  599. case DsRole_RoleStandaloneServer:
  600. DsRoleFreeMemory(pDomainInfo);
  601. if (NULL != pszDomain)
  602. {
  603. NETSETUP_JOIN_STATUS BufferType;
  604. dwErr = NetGetJoinInformation(NULL,pszDomain,&BufferType);
  605. }
  606. return dwErr;
  607. break; // just in case
  608. }
  609. DsRoleFreeMemory(pDomainInfo);
  610. dwErr = DsGetDcName(NULL, // Computer Name
  611. NULL, // Domain Name
  612. NULL, // Domain GUID
  613. NULL, // Site Name
  614. DS_DIRECTORY_SERVICE_PREFERRED,
  615. &pdcInfo);
  616. if ((dwErr != NO_ERROR) || (pdcInfo == NULL))
  617. {
  618. if (dwErr == ERROR_NO_SUCH_DOMAIN)
  619. {
  620. *pfInDomain = FALSE;
  621. return NO_ERROR;
  622. }
  623. else
  624. {
  625. if (pdcInfo == NULL)
  626. dwErr = ERROR_INTERNAL_ERROR;
  627. return dwErr;
  628. }
  629. }
  630. if (pdcInfo->Flags & DS_DS_FLAG)
  631. {
  632. *pfInDomain = TRUE;
  633. }
  634. if (pszDomain != NULL)
  635. {
  636. dwErr = NetApiBufferAllocate((wcslen(pdcInfo->DomainName)+1) * sizeof(WCHAR),
  637. (LPVOID *)pszDomain);
  638. if ((NERR_Success == dwErr) && (NULL != *pszDomain))
  639. {
  640. wcscpy(*pszDomain,pdcInfo->DomainName);
  641. }
  642. }
  643. if (pdcInfo != NULL)
  644. NetApiBufferFree(pdcInfo);
  645. return dwErr;
  646. }
  647. /*++
  648. Function:
  649. LicenseServerCachingThread
  650. Description:
  651. This is the thread that does the license server caching.
  652. Arguments:
  653. lpParam - contains the exit event handle
  654. Returns:
  655. Always 1
  656. --*/
  657. DWORD WINAPI
  658. LicenseServerCachingThread(
  659. LPVOID lpParam )
  660. {
  661. DWORD
  662. dwWaitStatus;
  663. HANDLE
  664. hExit = (HANDLE)lpParam;
  665. DWORD
  666. dwDiscoveryInterval = DISCOVERY_INTERVAL;
  667. HANDLE
  668. rgWaitHandles[] = {hExit,g_hImmediateDiscovery,g_hDiscoverySoon};
  669. BOOL
  670. bFoundServer;
  671. BOOL
  672. bSkipOne = FALSE;
  673. HANDLE
  674. hEvent;
  675. //
  676. // Yield our time slice to other threads now, so that the terminal server
  677. // service can start up quickly. Refresh the license server cache when we
  678. // resume our time slice.
  679. //
  680. Sleep( 0 );
  681. while (1)
  682. {
  683. if (!bSkipOne)
  684. {
  685. bFoundServer = TLSRefreshLicenseServerCache(INFINITE);
  686. if ((!g_fOffSiteLicenseServer) && bFoundServer)
  687. {
  688. dwDiscoveryInterval = INFINITE;
  689. }
  690. }
  691. else
  692. {
  693. bSkipOne = FALSE;
  694. }
  695. dwWaitStatus = WaitForMultipleObjects(
  696. sizeof(rgWaitHandles) / sizeof(HANDLE),
  697. rgWaitHandles,
  698. FALSE, // wait for any one event
  699. dwDiscoveryInterval);
  700. if (WAIT_OBJECT_0 == dwWaitStatus)
  701. {
  702. // hExit was signalled
  703. goto done;
  704. }
  705. if ((WAIT_OBJECT_0+1) == dwWaitStatus)
  706. {
  707. // g_hImmediateDiscovery was signalled
  708. // reduce dwDiscoveryInterval
  709. dwDiscoveryInterval = DISCOVERY_INTERVAL;
  710. }
  711. if ((WAIT_OBJECT_0+2) == dwWaitStatus)
  712. {
  713. // g_hDiscoverySoon was signalled
  714. // reduce dwDiscoveryInterval, but wait one round
  715. dwDiscoveryInterval = DISCOVERY_INTERVAL;
  716. bSkipOne = TRUE;
  717. }
  718. // we timed out, or hImmediateDiscovery was signalled. Re-start
  719. // discovery
  720. }
  721. done:
  722. hEvent = g_hCachingThreadExit;
  723. g_hCachingThreadExit = NULL;
  724. CloseHandle(hEvent);
  725. hEvent = g_hImmediateDiscovery;
  726. g_hImmediateDiscovery = NULL;
  727. CloseHandle(hEvent);
  728. hEvent = g_hDiscoverySoon;
  729. g_hDiscoverySoon = NULL;
  730. CloseHandle(hEvent);
  731. return 1;
  732. }
  733. extern "C" void
  734. TLSShutdown()
  735. {
  736. if (0 < InterlockedDecrement(&lLibUsage))
  737. {
  738. //
  739. // Someone else is using it
  740. //
  741. return;
  742. }
  743. TLSStopDiscovery();
  744. if (NULL != g_pRpcIdentity)
  745. {
  746. PSEC_WINNT_AUTH_IDENTITY pRpcIdentity = g_pRpcIdentity;
  747. g_pRpcIdentity = NULL;
  748. if (NULL != pRpcIdentity->User)
  749. {
  750. LocalFree(pRpcIdentity->User);
  751. }
  752. LocalFree(pRpcIdentity);
  753. }
  754. //
  755. // Cleanup random number generator
  756. //
  757. TSRNG_Shutdown();
  758. LsCsp_Exit();
  759. }
  760. extern "C" DWORD WINAPI
  761. TLSInit()
  762. {
  763. LICENSE_STATUS status;
  764. BOOL fInDomain = FALSE;
  765. if (0 != InterlockedExchangeAdd(&lLibUsage,1))
  766. {
  767. //
  768. // Already been initialized
  769. //
  770. return ERROR_SUCCESS;
  771. }
  772. status = LsCsp_Initialize();
  773. if (LICENSE_STATUS_OK != status)
  774. {
  775. InterlockedDecrement(&lLibUsage);
  776. switch (status)
  777. {
  778. case LICENSE_STATUS_OUT_OF_MEMORY:
  779. return ERROR_NOT_ENOUGH_MEMORY;
  780. case LICENSE_STATUS_NO_CERTIFICATE:
  781. return SCARD_E_CERTIFICATE_UNAVAILABLE;
  782. case LICENSE_STATUS_INVALID_CERTIFICATE:
  783. return CERT_E_MALFORMED;
  784. default:
  785. return E_FAIL;
  786. }
  787. }
  788. if ((NO_ERROR == TLSInDomain(&fInDomain, NULL))
  789. && (fInDomain)
  790. && (IsSystemService()))
  791. {
  792. //
  793. // We're running as SYSTEM
  794. // Create an RPC identity for use as an RPC client
  795. //
  796. g_pRpcIdentity = (PSEC_WINNT_AUTH_IDENTITY) LocalAlloc(LPTR, sizeof(SEC_WINNT_AUTH_IDENTITY));
  797. if (NULL != g_pRpcIdentity)
  798. {
  799. g_pRpcIdentity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
  800. g_pRpcIdentity->UserLength = MAX_COMPUTERNAME_LENGTH + 2;
  801. g_pRpcIdentity->User = (WCHAR *) LocalAlloc(LPTR, g_pRpcIdentity->UserLength * sizeof(WCHAR));
  802. if (NULL != g_pRpcIdentity->User)
  803. {
  804. if (GetComputerNameEx(ComputerNamePhysicalNetBIOS,g_pRpcIdentity->User,&(g_pRpcIdentity->UserLength)))
  805. {
  806. if (g_pRpcIdentity->UserLength < MAX_COMPUTERNAME_LENGTH + 1)
  807. {
  808. g_pRpcIdentity->User[g_pRpcIdentity->UserLength++] = L'$';
  809. g_pRpcIdentity->User[g_pRpcIdentity->UserLength] = 0;
  810. }
  811. else
  812. {
  813. LocalFree(g_pRpcIdentity->User);
  814. LocalFree(g_pRpcIdentity);
  815. g_pRpcIdentity = NULL;
  816. InterlockedDecrement(&lLibUsage);
  817. return E_FAIL;
  818. }
  819. }
  820. else
  821. {
  822. LocalFree(g_pRpcIdentity->User);
  823. LocalFree(g_pRpcIdentity);
  824. g_pRpcIdentity = NULL;
  825. InterlockedDecrement(&lLibUsage);
  826. return GetLastError();
  827. }
  828. }
  829. else
  830. {
  831. LocalFree(g_pRpcIdentity);
  832. g_pRpcIdentity = NULL;
  833. InterlockedDecrement(&lLibUsage);
  834. return ERROR_NOT_ENOUGH_MEMORY;
  835. }
  836. }
  837. else
  838. {
  839. InterlockedDecrement(&lLibUsage);
  840. return ERROR_NOT_ENOUGH_MEMORY;
  841. }
  842. }
  843. //
  844. // Init random number generator
  845. //
  846. TSRNG_Initialize();
  847. return ERROR_SUCCESS;
  848. }
  849. extern "C" DWORD WINAPI
  850. TLSStartDiscovery()
  851. {
  852. HANDLE hCachingThread = NULL;
  853. HANDLE hEvent;
  854. if (NULL != g_hCachingThreadExit)
  855. {
  856. // already started
  857. return ERROR_SUCCESS;
  858. }
  859. //
  860. // Create the event to signal thread exit
  861. //
  862. g_hCachingThreadExit = CreateEvent( NULL, FALSE, FALSE, NULL );
  863. if( NULL == g_hCachingThreadExit )
  864. {
  865. return GetLastError();
  866. }
  867. g_hImmediateDiscovery = CreateEvent(NULL,FALSE,FALSE,NULL);
  868. if (NULL == g_hImmediateDiscovery)
  869. {
  870. hEvent = g_hCachingThreadExit;
  871. g_hCachingThreadExit = NULL;
  872. CloseHandle(hEvent);
  873. return GetLastError();
  874. }
  875. g_hDiscoverySoon = CreateEvent(NULL,FALSE,FALSE,NULL);
  876. if (NULL == g_hDiscoverySoon)
  877. {
  878. hEvent = g_hCachingThreadExit;
  879. g_hCachingThreadExit = NULL;
  880. CloseHandle(hEvent);
  881. hEvent = g_hImmediateDiscovery;
  882. g_hImmediateDiscovery = NULL;
  883. CloseHandle(hEvent);
  884. return GetLastError();
  885. }
  886. //
  887. // Create the caching thread
  888. //
  889. hCachingThread = CreateThread(
  890. NULL,
  891. 0,
  892. LicenseServerCachingThread,
  893. ( LPVOID )g_hCachingThreadExit,
  894. 0,
  895. NULL );
  896. if (hCachingThread == NULL)
  897. {
  898. hEvent = g_hCachingThreadExit;
  899. g_hCachingThreadExit = NULL;
  900. CloseHandle(hEvent);
  901. hEvent = g_hImmediateDiscovery;
  902. g_hImmediateDiscovery = NULL;
  903. CloseHandle(hEvent);
  904. hEvent = g_hDiscoverySoon;
  905. g_hDiscoverySoon = NULL;
  906. CloseHandle(hEvent);
  907. return GetLastError();
  908. }
  909. CloseHandle(hCachingThread);
  910. return ERROR_SUCCESS;
  911. }
  912. extern "C" DWORD WINAPI
  913. TLSStopDiscovery()
  914. {
  915. //
  916. // Signal the thread to exit
  917. //
  918. if (NULL != g_hCachingThreadExit)
  919. {
  920. SetEvent( g_hCachingThreadExit );
  921. }
  922. return ERROR_SUCCESS;
  923. }
  924. //
  925. // Number of DCs to allocate space for at a time
  926. //
  927. #define DC_LIST_CHUNK 10
  928. //+------------------------------------------------------------------------
  929. // Function:
  930. //
  931. // EnumerateLsServer()
  932. //
  933. // Description:
  934. //
  935. // Routine to enumerate all hydra license server in network
  936. //
  937. // Arguments:
  938. //
  939. // szScope - Scope limit, NULL if doen't care.
  940. // dwPlatformType - verify if license server have licenses for this platform,
  941. // LSKEYPACKPLATFORMTYPE_UNKNOWN if doesn't care.
  942. // fCallBack - call back routine when EnumerateServer() founds any server,
  943. // dwUserData - data to be pass to call back routine
  944. //
  945. // Return Value:
  946. //
  947. // RPC_S_OK or any RPC specific error code.
  948. //
  949. // NOTE:
  950. //
  951. // Enumeration terminate when either there is no more server or call back
  952. // routine return TRUE.
  953. //
  954. //-------------------------------------------------------------------------
  955. DWORD WINAPI
  956. EnumerateTlsServerInDomain(
  957. IN LPCTSTR szDomain,
  958. IN TLSENUMERATECALLBACK fCallBack,
  959. IN HANDLE dwUserData,
  960. IN DWORD dwTimeOut,
  961. IN BOOL fRegOnly,
  962. IN OUT BOOL *pfOffSite
  963. )
  964. /*++
  965. ++*/
  966. {
  967. DWORD entriesread = 0;
  968. BOOL bCancel=FALSE;
  969. DWORD dwErrCode;
  970. LPWSTR pwszServerTmp = NULL;
  971. LPWSTR pwszServer = NULL;
  972. HRESULT hr;
  973. LPWSTR pwszServers = NULL;
  974. LPWSTR pwszServersTmp = NULL;
  975. DWORD cchServers = 0;
  976. DWORD cchServer;
  977. LPWSTR *rgwszServers = NULL;
  978. LPWSTR *rgwszServersTmp;
  979. LPWSTR pwszServerNames = NULL;
  980. DWORD dwErr = ERROR_SUCCESS, i;
  981. HANDLE hDcOpen = NULL;
  982. LPWSTR szSiteName = NULL;
  983. BOOL fOffSiteIn;
  984. BOOL fFoundOne = FALSE;
  985. BOOL fFoundOneOffSite = FALSE;
  986. DWORD cChunks = 0;
  987. DWORD cServersOnSite = 0;
  988. if (fRegOnly)
  989. {
  990. //
  991. // check for a license server in the registry
  992. //
  993. if(g_bLog)
  994. LogMsg(L"\n----------Trying Domain License Server Discovery Cache----------\n");
  995. hr = GetLicenseServersFromReg(REG_DOMAIN_SERVER_MULTI,&pwszServerNames,&entriesread,&rgwszServers);
  996. if (FAILED(hr))
  997. {
  998. dwErr = hr;
  999. goto Cleanup;
  1000. }
  1001. }
  1002. else
  1003. {
  1004. if(g_bLog)
  1005. LogMsg(L"\n----------Trying Domain License Server Discovery----------\n");
  1006. if (NULL == pfOffSite)
  1007. {
  1008. return ERROR_INVALID_PARAMETER;
  1009. }
  1010. fOffSiteIn = *pfOffSite;
  1011. *pfOffSite = FALSE;
  1012. dwErr = DsGetSiteName(NULL,&szSiteName);
  1013. if(dwErr != ERROR_SUCCESS)
  1014. {
  1015. if(g_bLog)
  1016. LogMsg(L"DsGetSiteName failed %x\n",dwErr);
  1017. goto Cleanup;
  1018. }
  1019. dwErr = DsGetDcOpenW(szDomain,
  1020. fOffSiteIn ? DS_NOTIFY_AFTER_SITE_RECORDS: DS_ONLY_DO_SITE_NAME,
  1021. szSiteName,
  1022. NULL, // DomainGuid
  1023. NULL, // DnsForestName
  1024. 0, // Flags
  1025. &hDcOpen
  1026. );
  1027. if(dwErr != ERROR_SUCCESS)
  1028. {
  1029. if(g_bLog)
  1030. LogMsg(L"DsGetDcOpen failed %x\n",dwErr);
  1031. goto Cleanup;
  1032. }
  1033. rgwszServers = (LPWSTR *) LocalAlloc(LPTR,
  1034. DC_LIST_CHUNK * sizeof(LPWSTR));
  1035. if (NULL == rgwszServers)
  1036. {
  1037. if(g_bLog)
  1038. LogMsg(L"Out of memory\n");
  1039. dwErr = E_OUTOFMEMORY;
  1040. goto Cleanup;
  1041. }
  1042. cChunks = 1;
  1043. //
  1044. // Read the whole DC list
  1045. //
  1046. do
  1047. {
  1048. if (entriesread >= (cChunks * DC_LIST_CHUNK))
  1049. {
  1050. cChunks++;
  1051. rgwszServersTmp = (LPWSTR *)
  1052. LocalReAlloc(rgwszServers,
  1053. DC_LIST_CHUNK * sizeof(LPWSTR) * cChunks,
  1054. LHND);
  1055. if (NULL == rgwszServersTmp)
  1056. {
  1057. dwErr = E_OUTOFMEMORY;
  1058. goto Cleanup;
  1059. }
  1060. else
  1061. {
  1062. rgwszServers = rgwszServersTmp;
  1063. }
  1064. }
  1065. dwErr = DsGetDcNextW(hDcOpen,
  1066. NULL,
  1067. NULL,
  1068. rgwszServers+entriesread);
  1069. if (ERROR_FILEMARK_DETECTED == dwErr)
  1070. {
  1071. // Now going off-site; use NULL ptr marker
  1072. rgwszServers[entriesread] = NULL;
  1073. cServersOnSite = entriesread;
  1074. dwErr = ERROR_SUCCESS;
  1075. fFoundOneOffSite = TRUE;
  1076. }
  1077. entriesread++;
  1078. } while (ERROR_SUCCESS == dwErr);
  1079. // don't count the final error
  1080. entriesread--;
  1081. if (!fFoundOneOffSite)
  1082. cServersOnSite = entriesread;
  1083. // Now randomize the two portions of the array
  1084. RandomizeArray(rgwszServers,cServersOnSite);
  1085. if (fFoundOneOffSite)
  1086. {
  1087. RandomizeArray(rgwszServers+cServersOnSite+1,
  1088. entriesread - cServersOnSite - 1);
  1089. }
  1090. // Now allocate memory for registry entry
  1091. pwszServers = (LPWSTR) LocalAlloc(LPTR,2*sizeof(WCHAR));
  1092. if (NULL == pwszServers)
  1093. {
  1094. if(g_bLog)
  1095. LogMsg(L"Out of memory\n");
  1096. dwErr = E_OUTOFMEMORY;
  1097. goto Cleanup;
  1098. }
  1099. cchServers = 2;
  1100. pwszServers[0] = pwszServers[1] = L'\0';
  1101. }
  1102. for(i=0; bCancel == FALSE; i++)
  1103. {
  1104. PCONTEXT_HANDLE pContext=NULL;
  1105. RPC_STATUS rpcStatus;
  1106. if (!fRegOnly)
  1107. {
  1108. if (fFoundOneOffSite && i == cServersOnSite)
  1109. {
  1110. if (fFoundOne)
  1111. break;
  1112. // Now going off-site
  1113. i++;
  1114. *pfOffSite = TRUE;
  1115. }
  1116. }
  1117. if (i >= entriesread)
  1118. break;
  1119. pwszServerTmp = rgwszServers[i];
  1120. bCancel=fCallBack(pContext, pwszServerTmp, dwUserData);
  1121. if(bCancel == TRUE)
  1122. continue;
  1123. if(!(pContext = TLSConnectToLsServer(pwszServerTmp)))
  1124. {
  1125. //
  1126. // could be access denied.
  1127. //
  1128. if(g_bLog)
  1129. LogMsg(L"Can't connect to %s. Maybe it has no License Service running on it.\n",pwszServerTmp);
  1130. continue;
  1131. }
  1132. do {
  1133. //
  1134. // Skip enterprise server
  1135. //
  1136. DWORD dwVersion;
  1137. rpcStatus = TLSGetVersion( pContext, &dwVersion );
  1138. if(rpcStatus != RPC_S_OK)
  1139. {
  1140. break;
  1141. }
  1142. #if ENFORCE_LICENSING
  1143. //
  1144. // W2K Beta 3 to RC1 upgrade, don't connect to any non-enforce
  1145. // server 5.2 or older
  1146. //
  1147. if(IS_ENFORCE_LSSERVER(dwVersion) == FALSE)
  1148. {
  1149. if( GET_LSSERVER_MAJOR_VERSION(dwVersion) <= 5 &&
  1150. GET_LSSERVER_MINOR_VERSION(dwVersion) <= 2 )
  1151. {
  1152. continue;
  1153. }
  1154. }
  1155. if( GET_LSSERVER_MAJOR_VERSION(dwVersion) < 6 )
  1156. {
  1157. continue;
  1158. }
  1159. //
  1160. // Prevent beta <-> RTM server talking to each other
  1161. //
  1162. //
  1163. // TLSIsBetaNTServer() returns TRUE if eval NT
  1164. // IS_LSSERVER_RTM() returns TRUE if LS is an RTM.
  1165. //
  1166. if( TLSIsBetaNTServer() == IS_LSSERVER_RTM(dwVersion) )
  1167. {
  1168. continue;
  1169. }
  1170. #endif
  1171. if(dwVersion & TLS_VERSION_ENTERPRISE_BIT)
  1172. {
  1173. continue;
  1174. }
  1175. if(g_bLog)
  1176. LogMsg(L"!!!Connected to License Service on %s\n",pwszServerTmp);
  1177. bCancel=fCallBack(pContext, pwszServerTmp, dwUserData);
  1178. if (!fRegOnly)
  1179. {
  1180. //
  1181. // Add to list of servers
  1182. //
  1183. cchServer = wcslen(pwszServerTmp);
  1184. pwszServersTmp = (LPWSTR) LocalReAlloc(pwszServers,(cchServers+cchServer+1)*sizeof(TCHAR),LHND);
  1185. if (NULL == pwszServersTmp)
  1186. {
  1187. break;
  1188. }
  1189. pwszServers = pwszServersTmp;
  1190. if (cchServers == 2)
  1191. {
  1192. wcscpy(pwszServers,pwszServerTmp);
  1193. cchServers += cchServer;
  1194. } else
  1195. {
  1196. wcscpy(pwszServers+cchServers-1,pwszServerTmp);
  1197. cchServers += cchServer + 1;
  1198. }
  1199. pwszServers[cchServers-1] = L'\0';
  1200. }
  1201. fFoundOne = TRUE;
  1202. } while (FALSE);
  1203. if(bCancel == FALSE && pContext != NULL)
  1204. {
  1205. TLSDisconnect(&pContext);
  1206. }
  1207. } // for loop
  1208. if (!fRegOnly)
  1209. {
  1210. WriteLicenseServersToReg(REG_DOMAIN_SERVER_MULTI,pwszServers,cchServers);
  1211. }
  1212. Cleanup:
  1213. if (NULL != hDcOpen)
  1214. DsGetDcCloseW(hDcOpen);
  1215. if (NULL != rgwszServers)
  1216. {
  1217. if (!fRegOnly)
  1218. {
  1219. for (i = 0; i < entriesread; i++)
  1220. {
  1221. if (NULL != rgwszServers[i])
  1222. {
  1223. NetApiBufferFree(rgwszServers[i]);
  1224. }
  1225. }
  1226. }
  1227. LocalFree(rgwszServers);
  1228. }
  1229. if (szSiteName)
  1230. NetApiBufferFree(szSiteName);
  1231. if (pwszServerNames)
  1232. LocalFree(pwszServerNames);
  1233. if (pwszServers)
  1234. LocalFree(pwszServers);
  1235. if (pwszServer)
  1236. LocalFree(pwszServer);
  1237. return dwErr;
  1238. }
  1239. DWORD WINAPI
  1240. EnumerateTlsServerInWorkGroup(
  1241. IN TLSENUMERATECALLBACK pfCallBack,
  1242. IN HANDLE dwUserData,
  1243. IN DWORD dwTimeOut,
  1244. IN BOOL fRegOnly
  1245. )
  1246. /*++
  1247. ++*/
  1248. {
  1249. DWORD dwStatus=ERROR_SUCCESS;
  1250. TCHAR szServerMailSlotName[MAX_PATH+1];
  1251. TCHAR szLocalMailSlotName[MAX_PATH+1];
  1252. HANDLE hClientSlot = INVALID_HANDLE_VALUE;
  1253. HANDLE hServerSlot = INVALID_HANDLE_VALUE;
  1254. TCHAR szDiscMsg[MAX_MAILSLOT_MSG_SIZE+1];
  1255. TCHAR szComputerName[MAXCOMPUTERNAMELENGTH+1];
  1256. TCHAR szRandomMailSlotName[MAXCOMPUTERNAMELENGTH+1];
  1257. DWORD cbComputerName=MAXCOMPUTERNAMELENGTH+1;
  1258. DWORD cbWritten=0;
  1259. DWORD cbRead=0;
  1260. BOOL bCancel = FALSE;
  1261. DWORD dwErrCode;
  1262. HRESULT hr;
  1263. LPWSTR pwszServers = NULL;
  1264. LPWSTR pwszServersTmp = NULL;
  1265. DWORD cchServers = 0;
  1266. DWORD cchServer;
  1267. LPWSTR *rgwszServers = NULL;
  1268. LPWSTR pwszServerNames = NULL;
  1269. DWORD cServers = 0;
  1270. DWORD i = 0;
  1271. LPWSTR pwszServerTmp = szComputerName;
  1272. if (!fRegOnly)
  1273. {
  1274. if(g_bLog)
  1275. LogMsg(L"\n----------Trying Workgroup License Server Discovery----------\n");
  1276. if(!GetComputerName(szComputerName, &cbComputerName))
  1277. {
  1278. dwStatus = GetLastError();
  1279. goto cleanup;
  1280. }
  1281. if (0 == (1 & GetSystemMetrics(SM_NETWORK)))
  1282. {
  1283. // No network; try local machine
  1284. if(g_bLog)
  1285. LogMsg(L"No network, trying local computer=%s\n",szComputerName);
  1286. dwStatus = ERROR_SUCCESS;
  1287. goto TryServer;
  1288. }
  1289. wsprintf(
  1290. szRandomMailSlotName,
  1291. _TEXT("%08x"),
  1292. GetCurrentThreadId()
  1293. );
  1294. _stprintf(
  1295. szLocalMailSlotName,
  1296. _TEXT("\\\\.\\mailslot\\%s"),
  1297. szRandomMailSlotName
  1298. );
  1299. //
  1300. // Create local mail slot for server's response
  1301. //
  1302. hClientSlot=CreateMailslot(
  1303. szLocalMailSlotName,
  1304. 0,
  1305. (dwTimeOut == MAILSLOT_WAIT_FOREVER) ? 5 * 1000: dwTimeOut,
  1306. NULL
  1307. );
  1308. if(hClientSlot == INVALID_HANDLE_VALUE)
  1309. {
  1310. dwStatus = GetLastError();
  1311. goto cleanup;
  1312. }
  1313. //
  1314. // Open server's mail slot
  1315. //
  1316. _stprintf(
  1317. szServerMailSlotName,
  1318. _TEXT("\\\\%s\\mailslot\\%s"),
  1319. _TEXT("*"),
  1320. _TEXT(SERVERMAILSLOTNAME)
  1321. );
  1322. hServerSlot=CreateFile(
  1323. szServerMailSlotName,
  1324. GENERIC_WRITE, // only need write
  1325. FILE_SHARE_READ,
  1326. NULL,
  1327. OPEN_EXISTING,
  1328. FILE_ATTRIBUTE_NORMAL,
  1329. NULL
  1330. );
  1331. if(hServerSlot == INVALID_HANDLE_VALUE)
  1332. {
  1333. dwStatus = GetLastError();
  1334. goto cleanup;
  1335. }
  1336. //
  1337. // Formulate discovery message
  1338. //
  1339. _stprintf(
  1340. szDiscMsg,
  1341. _TEXT("%s %c%s%c %c%s%c"),
  1342. _TEXT(LSERVER_DISCOVERY),
  1343. _TEXT(LSERVER_OPEN_BLK),
  1344. szComputerName,
  1345. _TEXT(LSERVER_CLOSE_BLK),
  1346. _TEXT(LSERVER_OPEN_BLK),
  1347. szRandomMailSlotName,
  1348. _TEXT(LSERVER_CLOSE_BLK)
  1349. );
  1350. if (!WriteFile(hServerSlot, szDiscMsg, (_tcslen(szDiscMsg) + 1) * sizeof(TCHAR), &cbWritten, NULL) ||
  1351. (cbWritten != (_tcslen(szDiscMsg) + 1 ) * sizeof(TCHAR)))
  1352. {
  1353. dwStatus = GetLastError();
  1354. if (dwStatus == ERROR_NETWORK_UNREACHABLE)
  1355. {
  1356. // No network; try local machine
  1357. if(g_bLog)
  1358. LogMsg(L"No network, trying local computer=%s\n",szComputerName);
  1359. dwStatus = ERROR_SUCCESS;
  1360. goto TryServer;
  1361. }
  1362. else
  1363. {
  1364. goto cleanup;
  1365. }
  1366. }
  1367. // Allocate for registry entry
  1368. pwszServers = (LPWSTR) LocalAlloc(LPTR,2*sizeof(WCHAR));
  1369. if (NULL == pwszServers)
  1370. {
  1371. if(g_bLog)
  1372. LogMsg(L"Out of memory\n");
  1373. dwStatus = E_OUTOFMEMORY;
  1374. goto cleanup;
  1375. }
  1376. cchServers = 2;
  1377. pwszServers[0] = pwszServers[1] = L'\0';
  1378. } else
  1379. {
  1380. //
  1381. // check for a license server in the registry
  1382. //
  1383. if(g_bLog)
  1384. LogMsg(L"\n----------Trying Workgroup License Server Discovery Cache----------");
  1385. hr = GetLicenseServersFromReg(REG_DOMAIN_SERVER_MULTI,&pwszServerNames,&cServers,&rgwszServers);
  1386. if (FAILED(hr))
  1387. {
  1388. dwStatus = hr;
  1389. goto cleanup;
  1390. }
  1391. }
  1392. do {
  1393. if(fRegOnly)
  1394. {
  1395. if (i >= cServers)
  1396. {
  1397. break;
  1398. }
  1399. pwszServerTmp = rgwszServers[i++];
  1400. } else
  1401. {
  1402. memset(szComputerName, 0, sizeof(szComputerName));
  1403. if(!ReadFile(hClientSlot, szComputerName, sizeof(szComputerName) - sizeof(TCHAR), &cbRead, NULL))
  1404. {
  1405. dwStatus=GetLastError();
  1406. break;
  1407. }
  1408. if(g_bLog)
  1409. LogMsg(L"Trying server=%s\n",szComputerName);
  1410. }
  1411. TryServer:
  1412. bCancel=pfCallBack(NULL, pwszServerTmp, dwUserData);
  1413. if(bCancel == TRUE)
  1414. {
  1415. continue;
  1416. }
  1417. PCONTEXT_HANDLE pContext=NULL;
  1418. RPC_STATUS rpcStatus;
  1419. if(!(pContext = TLSConnectToLsServer(pwszServerTmp)))
  1420. {
  1421. //
  1422. // could be access denied.
  1423. //
  1424. continue;
  1425. if(g_bLog)
  1426. LogMsg(L"Can't connect to %s. Maybe it has no License Service running on it.\n",pwszServerTmp);
  1427. }
  1428. do {
  1429. //
  1430. // Skip enterprise server
  1431. //
  1432. DWORD dwVersion;
  1433. rpcStatus = TLSGetVersion( pContext, &dwVersion );
  1434. if(rpcStatus != RPC_S_OK)
  1435. {
  1436. continue;
  1437. }
  1438. #if ENFORCE_LICENSING
  1439. //
  1440. // W2K Beta 3 to RC1 upgrade, don't connect to any non-enforce
  1441. // server 5.2 or older
  1442. //
  1443. if(IS_ENFORCE_LSSERVER(dwVersion) == FALSE)
  1444. {
  1445. if( GET_LSSERVER_MAJOR_VERSION(dwVersion) <= 5 &&
  1446. GET_LSSERVER_MINOR_VERSION(dwVersion) <= 2 )
  1447. {
  1448. continue;
  1449. }
  1450. }
  1451. if( GET_LSSERVER_MAJOR_VERSION(dwVersion) < 6 )
  1452. {
  1453. continue;
  1454. }
  1455. //
  1456. // No Beta <--> RTM server.
  1457. //
  1458. //
  1459. // TLSIsBetaNTServer() returns TRUE if eval NT
  1460. // IS_LSSERVER_RTM() returns TRUE if LS is an RTM.
  1461. //
  1462. if( TLSIsBetaNTServer() == IS_LSSERVER_RTM(dwVersion) )
  1463. {
  1464. continue;
  1465. }
  1466. #endif
  1467. if(dwVersion & TLS_VERSION_ENTERPRISE_BIT)
  1468. {
  1469. continue;
  1470. }
  1471. if(g_bLog)
  1472. LogMsg(L"!!!Connected to License Service on %s\n",pwszServerTmp);
  1473. bCancel=pfCallBack(pContext, pwszServerTmp, dwUserData);
  1474. if (!fRegOnly)
  1475. {
  1476. //
  1477. // Add to list of servers
  1478. //
  1479. cchServer = wcslen(pwszServerTmp);
  1480. pwszServersTmp = (LPWSTR) LocalReAlloc(pwszServers,(cchServers+cchServer+1)*sizeof(TCHAR),LHND);
  1481. if (NULL == pwszServersTmp)
  1482. {
  1483. continue;
  1484. }
  1485. pwszServers = pwszServersTmp;
  1486. if (cchServers == 2)
  1487. {
  1488. wcscpy(pwszServers,pwszServerTmp);
  1489. cchServers += cchServer;
  1490. } else
  1491. {
  1492. wcscpy(pwszServers+cchServers-1,pwszServerTmp);
  1493. cchServers += cchServer + 1;
  1494. }
  1495. pwszServers[cchServers-1] = L'\0';
  1496. }
  1497. } while (FALSE);
  1498. if(bCancel == FALSE && pContext != NULL)
  1499. {
  1500. TLSDisconnectFromServer(pContext);
  1501. }
  1502. } while(bCancel == FALSE);
  1503. if (!fRegOnly)
  1504. {
  1505. WriteLicenseServersToReg(REG_DOMAIN_SERVER_MULTI,pwszServers,cchServers);
  1506. }
  1507. cleanup:
  1508. if(hClientSlot != INVALID_HANDLE_VALUE)
  1509. {
  1510. CloseHandle(hClientSlot);
  1511. }
  1512. if(hServerSlot != INVALID_HANDLE_VALUE)
  1513. {
  1514. CloseHandle(hServerSlot);
  1515. }
  1516. if (pwszServerNames)
  1517. LocalFree(pwszServerNames);
  1518. if (pwszServers)
  1519. LocalFree(pwszServers);
  1520. if (rgwszServers)
  1521. LocalFree(rgwszServers);
  1522. return dwStatus;
  1523. }
  1524. DWORD
  1525. GetServersFromRegistry(
  1526. LPWSTR wszRegKey,
  1527. LPWSTR **prgszServers,
  1528. DWORD *pcCount
  1529. )
  1530. {
  1531. HKEY hParamKey = NULL;
  1532. DWORD dwValueType;
  1533. DWORD cbValue = 0, dwDisp;
  1534. LONG lReturn;
  1535. DWORD cbServer;
  1536. DWORD cServers;
  1537. DWORD cchServerMax;
  1538. LPWSTR *rgszServers;
  1539. DWORD i, j;
  1540. *prgszServers = NULL;
  1541. *pcCount = 0;
  1542. lReturn = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  1543. wszRegKey,
  1544. 0,
  1545. KEY_READ,
  1546. &hParamKey );
  1547. if (ERROR_SUCCESS != lReturn)
  1548. return lReturn;
  1549. lReturn = RegQueryInfoKey(hParamKey,
  1550. NULL,
  1551. NULL,
  1552. NULL,
  1553. &cServers,
  1554. &cchServerMax,
  1555. NULL,
  1556. NULL,
  1557. NULL,
  1558. NULL,
  1559. NULL,
  1560. NULL);
  1561. if (ERROR_SUCCESS != lReturn)
  1562. {
  1563. RegCloseKey( hParamKey );
  1564. return lReturn;
  1565. }
  1566. if (0 == cServers)
  1567. {
  1568. RegCloseKey( hParamKey );
  1569. return ERROR_NO_MORE_ITEMS;
  1570. }
  1571. rgszServers = (LPWSTR *) LocalAlloc(LPTR,cServers*sizeof(LPWSTR));
  1572. if (NULL == rgszServers)
  1573. {
  1574. RegCloseKey( hParamKey );
  1575. return ERROR_NOT_ENOUGH_MEMORY;
  1576. }
  1577. // Add one for null terminator
  1578. cchServerMax++;
  1579. for (i = 0; i < cServers; i++)
  1580. {
  1581. rgszServers[i] = (LPWSTR) LocalAlloc(LPTR,cchServerMax * sizeof(WCHAR));
  1582. if (NULL == rgszServers[i])
  1583. {
  1584. for (j = 0; j < i; j++)
  1585. {
  1586. LocalFree(rgszServers[j]);
  1587. }
  1588. LocalFree(rgszServers);
  1589. RegCloseKey( hParamKey );
  1590. return ERROR_NOT_ENOUGH_MEMORY;
  1591. }
  1592. cbServer = cchServerMax * sizeof(WCHAR);
  1593. lReturn = RegEnumKeyEx(hParamKey,
  1594. i,
  1595. rgszServers[i],
  1596. &cbServer,
  1597. NULL,
  1598. NULL,
  1599. NULL,
  1600. NULL);
  1601. if (ERROR_SUCCESS != lReturn)
  1602. {
  1603. for (j = 0; j <= i; j++)
  1604. {
  1605. LocalFree(rgszServers[j]);
  1606. }
  1607. LocalFree(rgszServers);
  1608. RegCloseKey( hParamKey );
  1609. return lReturn;
  1610. }
  1611. }
  1612. *prgszServers = rgszServers;
  1613. *pcCount = cServers;
  1614. return ERROR_SUCCESS;
  1615. }
  1616. DWORD WINAPI
  1617. EnumerateTlsServerInRegistry(
  1618. IN TLSENUMERATECALLBACK pfCallBack,
  1619. IN HANDLE dwUserData,
  1620. IN DWORD dwTimeOut,
  1621. LPWSTR wszRegKey
  1622. )
  1623. /*++
  1624. ++*/
  1625. {
  1626. BOOL bCancel=FALSE;
  1627. DWORD dwIndex = 0;
  1628. DWORD cServers = 0;
  1629. LPWSTR *rgszServers = NULL;
  1630. DWORD lReturn;
  1631. lReturn = GetServersFromRegistry(wszRegKey,
  1632. &rgszServers,
  1633. &cServers
  1634. );
  1635. if (ERROR_SUCCESS != lReturn)
  1636. {
  1637. return lReturn;
  1638. }
  1639. if(g_bLog)
  1640. LogMsg(L"\n----------Trying Registry Bypass Discovery----------\n");
  1641. RandomizeArray(rgszServers,cServers);
  1642. for (;dwIndex < cServers; dwIndex++)
  1643. {
  1644. PCONTEXT_HANDLE pContext=NULL;
  1645. RPC_STATUS rpcStatus;
  1646. bCancel=pfCallBack(pContext, rgszServers[dwIndex], dwUserData);
  1647. if(bCancel == TRUE)
  1648. continue;
  1649. if(!(pContext = TLSConnectToLsServer(rgszServers[dwIndex])))
  1650. {
  1651. //
  1652. // could be access denied, or the machine is gone
  1653. //
  1654. if(g_bLog)
  1655. LogMsg(L"Can't connect to %s. Maybe it has no License Service running on it.\n",rgszServers[dwIndex]);
  1656. continue;
  1657. }
  1658. do {
  1659. //
  1660. // Skip enterprise server
  1661. //
  1662. DWORD dwVersion;
  1663. rpcStatus = TLSGetVersion( pContext, &dwVersion );
  1664. if(rpcStatus != RPC_S_OK)
  1665. {
  1666. break;
  1667. }
  1668. #if ENFORCE_LICENSING
  1669. //
  1670. // W2K Beta 3 to RC1 upgrade, don't connect to any non-enforce
  1671. // server 5.2 or older
  1672. //
  1673. if(IS_ENFORCE_LSSERVER(dwVersion) == FALSE)
  1674. {
  1675. if( GET_LSSERVER_MAJOR_VERSION(dwVersion) <= 5 &&
  1676. GET_LSSERVER_MINOR_VERSION(dwVersion) <= 2 )
  1677. {
  1678. // old License Server
  1679. continue;
  1680. }
  1681. }
  1682. if( GET_LSSERVER_MAJOR_VERSION(dwVersion) < 6 )
  1683. {
  1684. continue;
  1685. }
  1686. //
  1687. // Prevent beta <-> RTM server talking to each other
  1688. //
  1689. //
  1690. // TLSIsBetaNTServer() returns TRUE if eval NT
  1691. // IS_LSSERVER_RTM() returns TRUE if LS is an RTM.
  1692. //
  1693. if( TLSIsBetaNTServer() == IS_LSSERVER_RTM(dwVersion) )
  1694. {
  1695. continue;
  1696. }
  1697. #endif
  1698. if(g_bLog)
  1699. LogMsg(L"!!!Connected to License Service on %s\n",rgszServers[dwIndex]);
  1700. bCancel=pfCallBack(pContext, rgszServers[dwIndex], dwUserData);
  1701. } while (FALSE);
  1702. if(bCancel == FALSE && pContext != NULL)
  1703. {
  1704. TLSDisconnect(&pContext);
  1705. }
  1706. } // for loop
  1707. for (dwIndex = 0; dwIndex < cServers; dwIndex++)
  1708. {
  1709. LocalFree(rgszServers[dwIndex]);
  1710. }
  1711. LocalFree(rgszServers);
  1712. return ERROR_SUCCESS;
  1713. }
  1714. DWORD WINAPI
  1715. EnumerateTlsServer(
  1716. IN TLSENUMERATECALLBACK pfCallBack,
  1717. IN HANDLE dwUserData,
  1718. IN DWORD dwTimeOut,
  1719. IN BOOL fRegOnly
  1720. )
  1721. /*++
  1722. ++*/
  1723. {
  1724. DWORD dwErr;
  1725. LPWSTR szDomain = NULL;
  1726. BOOL fOffSite = FALSE; // don't try to go off-site
  1727. //
  1728. // First check for a registry bypass of discovery
  1729. //
  1730. dwErr = EnumerateTlsServerInRegistry(
  1731. pfCallBack,
  1732. dwUserData,
  1733. dwTimeOut,
  1734. TEXT(TERMINAL_SERVICE_PARAM_DISCOVERY)
  1735. );
  1736. if ((!fRegOnly) || (g_fInDomain == -1))
  1737. {
  1738. //
  1739. // Check even if set (for !fRegOnly), to get domain name
  1740. //
  1741. dwErr = TLSInDomain(&g_fInDomain, fRegOnly ? NULL : &szDomain);
  1742. if (dwErr != NO_ERROR)
  1743. return dwErr;
  1744. }
  1745. //
  1746. // Reading registry failed, use full discovery
  1747. //
  1748. if(g_fInDomain)
  1749. {
  1750. dwErr = EnumerateTlsServerInDomain(
  1751. szDomain,
  1752. pfCallBack,
  1753. dwUserData,
  1754. dwTimeOut,
  1755. fRegOnly,
  1756. &fOffSite
  1757. );
  1758. if ((dwErr == NO_ERROR) && !fRegOnly)
  1759. {
  1760. g_fOffSiteLicenseServer = fOffSite;
  1761. }
  1762. }
  1763. else
  1764. {
  1765. dwErr = EnumerateTlsServerInWorkGroup(
  1766. pfCallBack,
  1767. dwUserData,
  1768. dwTimeOut,
  1769. fRegOnly
  1770. );
  1771. }
  1772. if (NULL != szDomain)
  1773. {
  1774. NetApiBufferFree(szDomain);
  1775. }
  1776. if ((NULL != g_hImmediateDiscovery)
  1777. && (dwErr != NO_ERROR) && fRegOnly)
  1778. {
  1779. SetEvent(g_hImmediateDiscovery);
  1780. }
  1781. if ((NULL != g_hDiscoverySoon)
  1782. && (dwErr == NO_ERROR) && fOffSite && !fRegOnly)
  1783. {
  1784. SetEvent(g_hDiscoverySoon);
  1785. }
  1786. return dwErr;
  1787. }
  1788. TLS_HANDLE
  1789. ConnectAndCheckServer(LPWSTR szServer)
  1790. {
  1791. TLS_HANDLE hBinding;
  1792. DWORD dwVersion;
  1793. RPC_STATUS rpcStatus;
  1794. hBinding = TLSConnectToLsServer(szServer);
  1795. if(hBinding == NULL)
  1796. {
  1797. goto done;
  1798. }
  1799. // Skip Windows 2000 License servers
  1800. DWORD dwSupportFlags = 0;
  1801. DWORD dwErrCode = 0;
  1802. dwErrCode = TLSGetSupportFlags(
  1803. hBinding,
  1804. &dwSupportFlags
  1805. );
  1806. if ((dwErrCode == RPC_S_OK) && !(dwSupportFlags & SUPPORT_WHISTLER_CAL))
  1807. {
  1808. TLSDisconnect(&hBinding);
  1809. goto done;
  1810. }
  1811. // If the call fails => Windows 2000 LS
  1812. else if(dwErrCode != RPC_S_OK)
  1813. {
  1814. TLSDisconnect(&hBinding);
  1815. goto done;
  1816. }
  1817. rpcStatus = TLSGetVersion(
  1818. hBinding,
  1819. &dwVersion
  1820. );
  1821. if( GET_LSSERVER_MAJOR_VERSION(dwVersion) < 6 )
  1822. {
  1823. TLSDisconnect(&hBinding);
  1824. goto done;
  1825. }
  1826. if(rpcStatus != RPC_S_OK)
  1827. {
  1828. TLSDisconnect(&hBinding);
  1829. goto done;
  1830. }
  1831. if( TLSIsBetaNTServer() == IS_LSSERVER_RTM(dwVersion) )
  1832. {
  1833. TLSDisconnect(&hBinding);
  1834. goto done;
  1835. }
  1836. done:
  1837. return hBinding;
  1838. }
  1839. //+------------------------------------------------------------------------
  1840. // Function: TLSConnectToAnyLsServer()
  1841. //
  1842. // Description:
  1843. //
  1844. // Routine to bind to any license server
  1845. //
  1846. // Arguments:
  1847. // dwTimeout - INFINITE for going off-site
  1848. //
  1849. // Return Value:
  1850. //
  1851. // RPC binding handle or NULL if error, use GetLastError() to retrieve
  1852. // detail error.
  1853. //-------------------------------------------------------------------------
  1854. TLS_HANDLE WINAPI
  1855. TLSConnectToAnyLsServer(
  1856. DWORD dwTimeout
  1857. )
  1858. /*++
  1859. ++*/
  1860. {
  1861. TLS_HANDLE hBinding=NULL;
  1862. HRESULT hr = S_OK;
  1863. LPWSTR *rgszServers = NULL;
  1864. DWORD cServers = 0;
  1865. DWORD i;
  1866. DWORD dwErr;
  1867. BOOL fInDomain;
  1868. LPWSTR szDomain = NULL;
  1869. LPWSTR szServerFound = NULL;
  1870. BOOL fRegOnly = (dwTimeout != INFINITE);
  1871. LPWSTR pwszServerNames = NULL;
  1872. BOOL fFreeServerNames = TRUE;
  1873. // TODO: add error codes/handling to all of this
  1874. //
  1875. // First check for a registry bypass of discovery
  1876. //
  1877. dwErr = GetServersFromRegistry(
  1878. TEXT(TERMINAL_SERVICE_PARAM_DISCOVERY),
  1879. &rgszServers,
  1880. &cServers
  1881. );
  1882. if (ERROR_SUCCESS == dwErr)
  1883. {
  1884. RandomizeArray(rgszServers,cServers);
  1885. for (i = 0; i < cServers; i++)
  1886. {
  1887. hBinding = ConnectAndCheckServer(rgszServers[i]);
  1888. if (NULL != hBinding)
  1889. {
  1890. szServerFound = rgszServers[i];
  1891. goto found_one;
  1892. }
  1893. }
  1894. if(NULL != rgszServers)
  1895. {
  1896. for (i = 0; i < cServers; i++)
  1897. {
  1898. LocalFree(rgszServers[i]);
  1899. }
  1900. LocalFree(rgszServers);
  1901. rgszServers = NULL;
  1902. }
  1903. }
  1904. //
  1905. // Next try Site (Enterprise) license servers
  1906. //
  1907. if (!fRegOnly)
  1908. {
  1909. hr = GetAllEnterpriseServers(&rgszServers,&cServers);
  1910. if (SUCCEEDED(hr))
  1911. {
  1912. RandomizeArray(rgszServers,cServers);
  1913. }
  1914. }
  1915. else
  1916. {
  1917. // rgszServers[i] is an index into pwszServerNames; don't free
  1918. fFreeServerNames = FALSE;
  1919. hr = GetLicenseServersFromReg(ENTERPRISE_SERVER_MULTI,
  1920. &pwszServerNames,
  1921. &cServers,
  1922. &rgszServers);
  1923. }
  1924. if (SUCCEEDED(hr))
  1925. {
  1926. for (i = 0; i < cServers; i++)
  1927. {
  1928. hBinding = ConnectAndCheckServer(rgszServers[i]);
  1929. if (NULL != hBinding)
  1930. {
  1931. szServerFound = rgszServers[i];
  1932. goto found_one;
  1933. }
  1934. }
  1935. if(NULL != rgszServers)
  1936. {
  1937. if (fFreeServerNames)
  1938. {
  1939. for (i = 0; i < cServers; i++)
  1940. {
  1941. LocalFree(rgszServers[i]);
  1942. }
  1943. LocalFree(rgszServers);
  1944. }
  1945. rgszServers = NULL;
  1946. }
  1947. }
  1948. //
  1949. // No Site LS found, try Domain/Workgroup servers
  1950. //
  1951. dwErr = TLSInDomain(&fInDomain, &szDomain);
  1952. if (dwErr != NO_ERROR)
  1953. {
  1954. return NULL;
  1955. }
  1956. LS_ENUM_PARAM param;
  1957. param.hBinding = &hBinding;
  1958. param.dwTimeout = INFINITE;
  1959. QueryPerformanceCounter(&(param.timeInitial));
  1960. fFreeServerNames = TRUE;
  1961. if (fInDomain)
  1962. {
  1963. BOOL fOffSite = TRUE;
  1964. dwErr = EnumerateTlsServerInDomain(
  1965. szDomain,
  1966. BindAnyServer,
  1967. &param,
  1968. INFINITE,
  1969. fRegOnly,
  1970. &fOffSite
  1971. );
  1972. if (dwErr == NO_ERROR)
  1973. {
  1974. g_fOffSiteLicenseServer = fOffSite;
  1975. }
  1976. }
  1977. else
  1978. {
  1979. dwErr = EnumerateTlsServerInWorkGroup(
  1980. BindAnyServer,
  1981. &param,
  1982. MAILSLOT_WAIT_FOREVER,
  1983. fRegOnly
  1984. );
  1985. }
  1986. if (NULL != szDomain)
  1987. {
  1988. NetApiBufferFree(szDomain);
  1989. }
  1990. if (hBinding != NULL)
  1991. goto found_one;
  1992. if (NULL != pwszServerNames)
  1993. {
  1994. LocalFree(pwszServerNames);
  1995. }
  1996. if ((NULL != g_hImmediateDiscovery)
  1997. && fRegOnly)
  1998. {
  1999. SetEvent(g_hImmediateDiscovery);
  2000. }
  2001. else if ((NULL != g_hDiscoverySoon)
  2002. && !fRegOnly && g_fOffSiteLicenseServer)
  2003. {
  2004. SetEvent(g_hDiscoverySoon);
  2005. }
  2006. return NULL;
  2007. found_one:
  2008. if (NULL != pwszServerNames)
  2009. {
  2010. LocalFree(pwszServerNames);
  2011. }
  2012. if(NULL != rgszServers)
  2013. {
  2014. if (fFreeServerNames)
  2015. {
  2016. for (i = 0; i < cServers; i++)
  2017. {
  2018. LocalFree(rgszServers[i]);
  2019. }
  2020. }
  2021. LocalFree(rgszServers);
  2022. }
  2023. return hBinding;
  2024. }
  2025. BOOL
  2026. TLSRefreshLicenseServerCache(
  2027. IN DWORD dwTimeOut
  2028. )
  2029. /*++
  2030. Abstract:
  2031. Refresh license server cache in registry.
  2032. Parameter:
  2033. dwTimeOut : Reserverd, should pass in INIFINITE for now
  2034. Returns:
  2035. TRUE/FALSE
  2036. --*/
  2037. {
  2038. BOOL bFoundServer = FALSE;
  2039. TLS_HANDLE hBinding = NULL;
  2040. hBinding = TLSConnectToAnyLsServer(dwTimeOut);
  2041. if (NULL != hBinding)
  2042. {
  2043. bFoundServer = TRUE;
  2044. TLSDisconnect(&hBinding);
  2045. }
  2046. return bFoundServer;
  2047. }
  2048. LICENSE_STATUS
  2049. InstallCertificate(LPVOID lpParam)
  2050. {
  2051. Sleep(INSTALL_CERT_DELAY);
  2052. return LsCsp_InstallX509Certificate(NULL);
  2053. }
  2054. //-------------------------------------------------------------------------
  2055. TLS_HANDLE WINAPI
  2056. TLSConnectToLsServer(
  2057. LPTSTR pszLsServer
  2058. )
  2059. /*++
  2060. ++*/
  2061. {
  2062. TCHAR szMachineName[MAX_COMPUTERNAME_LENGTH + 1] ;
  2063. PCONTEXT_HANDLE pContext=NULL;
  2064. DWORD cbMachineName=MAX_COMPUTERNAME_LENGTH;
  2065. HANDLE hThread = NULL;
  2066. static BOOL fLSFound = FALSE;
  2067. memset(szMachineName, 0, sizeof(szMachineName));
  2068. GetComputerName(szMachineName, &cbMachineName);
  2069. if(pszLsServer == NULL || _tcsicmp(szMachineName, pszLsServer) == 0)
  2070. {
  2071. pContext=ConnectLsServer(
  2072. szMachineName,
  2073. _TEXT(RPC_PROTOSEQLPC),
  2074. NULL,
  2075. RPC_C_AUTHN_LEVEL_DEFAULT
  2076. );
  2077. if(GetLastError() >= LSERVER_ERROR_BASE)
  2078. {
  2079. return NULL;
  2080. }
  2081. // try to connect with TCP protocol, if local procedure failed
  2082. }
  2083. if(pContext == NULL)
  2084. {
  2085. pContext=ConnectLsServer(
  2086. pszLsServer,
  2087. _TEXT(RPC_PROTOSEQNP),
  2088. _TEXT(LSNAMEPIPE),
  2089. RPC_C_AUTHN_LEVEL_PKT_PRIVACY
  2090. );
  2091. }
  2092. if (!fLSFound && (NULL != pContext))
  2093. {
  2094. fLSFound = TRUE;
  2095. // Now that someone's connected, we can install a license
  2096. hThread = CreateThread(NULL,
  2097. 0,
  2098. InstallCertificate,
  2099. NULL,
  2100. 0,
  2101. NULL);
  2102. if (hThread != NULL)
  2103. {
  2104. CloseHandle(hThread);
  2105. }
  2106. else
  2107. {
  2108. // Can't create the thread; try again later
  2109. fLSFound = FALSE;
  2110. }
  2111. }
  2112. return (TLS_HANDLE) pContext;
  2113. }
  2114. //-------------------------------------------------------------------------
  2115. void WINAPI
  2116. TLSDisconnectFromServer(
  2117. TLS_HANDLE pHandle
  2118. )
  2119. /*++
  2120. ++*/
  2121. {
  2122. if(pHandle != NULL)
  2123. {
  2124. TLSDisconnect( &pHandle );
  2125. }
  2126. }
  2127. //----------------------------------------------------------------------------
  2128. DWORD WINAPI
  2129. TLSConnect(
  2130. handle_t binding,
  2131. TLS_HANDLE *ppHandle
  2132. )
  2133. /*++
  2134. ++*/
  2135. {
  2136. RPC_STATUS rpc_status;
  2137. rpc_status = TLSRpcConnect(binding, ppHandle);
  2138. if(g_bLog)
  2139. LogMsg(L"\tRPC call TLSRpcConnect returned %d\n", rpc_status);
  2140. return rpc_status;
  2141. }
  2142. //----------------------------------------------------------------------------
  2143. DWORD WINAPI
  2144. TLSDisconnect(
  2145. TLS_HANDLE* pphHandle
  2146. )
  2147. /*++
  2148. ++*/
  2149. {
  2150. RPC_STATUS rpc_status;
  2151. rpc_status = TLSRpcDisconnect( pphHandle );
  2152. if(g_bLog)
  2153. LogMsg(L"\tRPC call TLSRpcDisconnect returned %d\n", rpc_status);
  2154. if(rpc_status != RPC_S_OK)
  2155. {
  2156. RpcSmDestroyClientContext(pphHandle);
  2157. }
  2158. *pphHandle = NULL;
  2159. return ERROR_SUCCESS;
  2160. }
  2161. //-------------------------------------------------------------------------
  2162. DWORD WINAPI
  2163. TLSGetVersion (
  2164. IN TLS_HANDLE hHandle,
  2165. OUT PDWORD pdwVersion
  2166. )
  2167. /*++
  2168. ++*/
  2169. {
  2170. RPC_STATUS rpc_status;
  2171. rpc_status = TLSRpcGetVersion( hHandle, pdwVersion );
  2172. if(g_bLog)
  2173. LogMsg(L"\tRPC call TLSRpcGetVersion returned %d and version 0x%x\n", rpc_status, *pdwVersion);
  2174. return rpc_status;
  2175. }
  2176. //----------------------------------------------------------------------------
  2177. DWORD WINAPI
  2178. TLSSendServerCertificate(
  2179. TLS_HANDLE hHandle,
  2180. DWORD cbCert,
  2181. PBYTE pbCert,
  2182. PDWORD pdwErrCode
  2183. )
  2184. /*++
  2185. ++*/
  2186. {
  2187. RPC_STATUS rpc_status;
  2188. rpc_status = TLSRpcSendServerCertificate(
  2189. hHandle,
  2190. cbCert,
  2191. pbCert,
  2192. pdwErrCode
  2193. );
  2194. if(g_bLog)
  2195. LogMsg(L"\tRPC call TLSRpcSendServerCertificate returned %d and errorcode %d\n", rpc_status, *pdwErrCode);
  2196. return rpc_status;
  2197. }
  2198. //----------------------------------------------------------------------------
  2199. DWORD WINAPI
  2200. TLSGetServerName(
  2201. TLS_HANDLE hHandle,
  2202. LPTSTR szMachineName,
  2203. PDWORD pcbSize,
  2204. PDWORD pdwErrCode
  2205. )
  2206. /*++
  2207. ++*/
  2208. {
  2209. RPC_STATUS rpc_status;
  2210. rpc_status = TLSRpcGetServerName(
  2211. hHandle,
  2212. szMachineName,
  2213. pcbSize,
  2214. pdwErrCode
  2215. );
  2216. if(g_bLog)
  2217. LogMsg(L"\tRPC call TLSRpcGetServerName returned %d and errorcode %d\n", rpc_status, *pdwErrCode);
  2218. return rpc_status;
  2219. }
  2220. //----------------------------------------------------------------------------
  2221. DWORD WINAPI
  2222. TLSGetServerNameEx(
  2223. TLS_HANDLE hHandle,
  2224. LPTSTR szMachineName,
  2225. PDWORD pcbSize,
  2226. PDWORD pdwErrCode
  2227. )
  2228. /*++
  2229. ++*/
  2230. {
  2231. RPC_STATUS rpc_status;
  2232. rpc_status = TLSRpcGetServerNameEx(
  2233. hHandle,
  2234. szMachineName,
  2235. pcbSize,
  2236. pdwErrCode
  2237. );
  2238. if(g_bLog)
  2239. LogMsg(L"\tRPC call TLSRpcGetServerNameEx returned %d and errorcode %d\n", rpc_status, *pdwErrCode);
  2240. if (rpc_status == RPC_S_PROCNUM_OUT_OF_RANGE)
  2241. {
  2242. rpc_status = TLSRpcGetServerName(
  2243. hHandle,
  2244. szMachineName,
  2245. pcbSize,
  2246. pdwErrCode
  2247. );
  2248. if(g_bLog)
  2249. LogMsg(L"\tRPC call TLSRpcGetServerName returned %d and errorcode %d\n", rpc_status, *pdwErrCode);
  2250. }
  2251. return rpc_status;
  2252. }
  2253. //----------------------------------------------------------------------------
  2254. DWORD WINAPI
  2255. TLSGetServerNameFixed(
  2256. TLS_HANDLE hHandle,
  2257. LPTSTR *pszMachineName,
  2258. PDWORD pdwErrCode
  2259. )
  2260. /*++
  2261. ++*/
  2262. {
  2263. RPC_STATUS rpc_status;
  2264. rpc_status = TLSRpcGetServerNameFixed(
  2265. hHandle,
  2266. pszMachineName,
  2267. pdwErrCode
  2268. );
  2269. if(g_bLog)
  2270. LogMsg(L"\tRPC call TLSRpcGetServerNameFixed returned %d and errorcode %d\n", rpc_status, *pdwErrCode);
  2271. return rpc_status;
  2272. }
  2273. //----------------------------------------------------------------------------
  2274. DWORD WINAPI
  2275. TLSGetServerScope(
  2276. TLS_HANDLE hHandle,
  2277. LPTSTR szScopeName,
  2278. PDWORD pcbSize,
  2279. PDWORD pdwErrCode)
  2280. /*++
  2281. ++*/
  2282. {
  2283. RPC_STATUS rpc_status;
  2284. rpc_status = TLSRpcGetServerScope(
  2285. hHandle,
  2286. szScopeName,
  2287. pcbSize,
  2288. pdwErrCode
  2289. );
  2290. if(g_bLog)
  2291. LogMsg(L"\tRPC call TLSRpcGetServerScope returned %d and errorcode %d\n", rpc_status, *pdwErrCode);
  2292. return rpc_status;
  2293. }
  2294. //----------------------------------------------------------------------------
  2295. DWORD WINAPI
  2296. TLSGetServerScopeFixed(
  2297. TLS_HANDLE hHandle,
  2298. LPTSTR *pszScopeName,
  2299. PDWORD pdwErrCode)
  2300. /*++
  2301. ++*/
  2302. {
  2303. RPC_STATUS rpc_status;
  2304. rpc_status = TLSRpcGetServerScopeFixed(
  2305. hHandle,
  2306. pszScopeName,
  2307. pdwErrCode
  2308. );
  2309. if(g_bLog)
  2310. LogMsg(L"\tRPC call TLSRpcGetServerScopeFixed returned %d and errorcode %d\n", rpc_status, *pdwErrCode);
  2311. return rpc_status;
  2312. }
  2313. //----------------------------------------------------------------------------
  2314. DWORD WINAPI
  2315. TLSIssuePlatformChallenge(
  2316. TLS_HANDLE hHandle,
  2317. DWORD dwClientInfo,
  2318. PCHALLENGE_CONTEXT pChallengeContext,
  2319. PDWORD pcbChallengeData,
  2320. PBYTE* pChallengeData,
  2321. PDWORD pdwErrCode
  2322. )
  2323. /*++
  2324. ++*/
  2325. {
  2326. return TLSRpcIssuePlatformChallenge(
  2327. hHandle,
  2328. dwClientInfo,
  2329. pChallengeContext,
  2330. pcbChallengeData,
  2331. pChallengeData,
  2332. pdwErrCode
  2333. );
  2334. }
  2335. //----------------------------------------------------------------------------
  2336. DWORD WINAPI
  2337. TLSIssueNewLicense(
  2338. TLS_HANDLE hHandle,
  2339. CHALLENGE_CONTEXT ChallengeContext,
  2340. LICENSEREQUEST *pRequest,
  2341. LPTSTR pMachineName,
  2342. LPTSTR pUserName,
  2343. DWORD cbChallengeResponse,
  2344. PBYTE pbChallengeResponse,
  2345. BOOL bAcceptTemporaryLicense,
  2346. PDWORD pcbLicense,
  2347. PBYTE* ppbLicense,
  2348. PDWORD pdwErrCode
  2349. )
  2350. /*++
  2351. ++*/
  2352. {
  2353. TLSLICENSEREQUEST rpcRequest;
  2354. RequestToTlsRequest( pRequest, &rpcRequest );
  2355. return TLSRpcRequestNewLicense(
  2356. hHandle,
  2357. ChallengeContext,
  2358. &rpcRequest,
  2359. pMachineName,
  2360. pUserName,
  2361. cbChallengeResponse,
  2362. pbChallengeResponse,
  2363. bAcceptTemporaryLicense,
  2364. pcbLicense,
  2365. ppbLicense,
  2366. pdwErrCode
  2367. );
  2368. }
  2369. //----------------------------------------------------------------------------
  2370. DWORD WINAPI
  2371. TLSIssueNewLicenseEx(
  2372. TLS_HANDLE hHandle,
  2373. PDWORD pSupportFlags,
  2374. CHALLENGE_CONTEXT ChallengeContext,
  2375. LICENSEREQUEST *pRequest,
  2376. LPTSTR pMachineName,
  2377. LPTSTR pUserName,
  2378. DWORD cbChallengeResponse,
  2379. PBYTE pbChallengeResponse,
  2380. BOOL bAcceptTemporaryLicense,
  2381. DWORD dwQuantity,
  2382. PDWORD pcbLicense,
  2383. PBYTE* ppbLicense,
  2384. PDWORD pdwErrCode
  2385. )
  2386. /*++
  2387. ++*/
  2388. {
  2389. DWORD dwStatus;
  2390. TLSLICENSEREQUEST rpcRequest;
  2391. RequestToTlsRequest( pRequest, &rpcRequest );
  2392. dwStatus = TLSRpcRequestNewLicenseEx(
  2393. hHandle,
  2394. pSupportFlags,
  2395. ChallengeContext,
  2396. &rpcRequest,
  2397. pMachineName,
  2398. pUserName,
  2399. cbChallengeResponse,
  2400. pbChallengeResponse,
  2401. bAcceptTemporaryLicense,
  2402. dwQuantity,
  2403. pcbLicense,
  2404. ppbLicense,
  2405. pdwErrCode
  2406. );
  2407. if (dwStatus == RPC_S_PROCNUM_OUT_OF_RANGE)
  2408. {
  2409. *pSupportFlags = 0;
  2410. dwStatus = TLSRpcRequestNewLicense(
  2411. hHandle,
  2412. ChallengeContext,
  2413. &rpcRequest,
  2414. pMachineName,
  2415. pUserName,
  2416. cbChallengeResponse,
  2417. pbChallengeResponse,
  2418. bAcceptTemporaryLicense,
  2419. pcbLicense,
  2420. ppbLicense,
  2421. pdwErrCode
  2422. );
  2423. }
  2424. return(dwStatus);
  2425. }
  2426. //----------------------------------------------------------------------------
  2427. DWORD WINAPI
  2428. TLSIssueNewLicenseExEx(
  2429. TLS_HANDLE hHandle,
  2430. PDWORD pSupportFlags,
  2431. CHALLENGE_CONTEXT ChallengeContext,
  2432. LICENSEREQUEST *pRequest,
  2433. LPTSTR pMachineName,
  2434. LPTSTR pUserName,
  2435. DWORD cbChallengeResponse,
  2436. PBYTE pbChallengeResponse,
  2437. BOOL bAcceptTemporaryLicense,
  2438. BOOL bAcceptFewerLicenses,
  2439. DWORD *pdwQuantity,
  2440. PDWORD pcbLicense,
  2441. PBYTE* ppbLicense,
  2442. PDWORD pdwErrCode
  2443. )
  2444. /*++
  2445. ++*/
  2446. {
  2447. DWORD dwStatus;
  2448. TLSLICENSEREQUEST rpcRequest;
  2449. RequestToTlsRequest( pRequest, &rpcRequest );
  2450. dwStatus = TLSRpcRequestNewLicenseExEx(
  2451. hHandle,
  2452. pSupportFlags,
  2453. ChallengeContext,
  2454. &rpcRequest,
  2455. pMachineName,
  2456. pUserName,
  2457. cbChallengeResponse,
  2458. pbChallengeResponse,
  2459. bAcceptTemporaryLicense,
  2460. bAcceptFewerLicenses,
  2461. pdwQuantity,
  2462. pcbLicense,
  2463. ppbLicense,
  2464. pdwErrCode
  2465. );
  2466. if (dwStatus == RPC_S_PROCNUM_OUT_OF_RANGE)
  2467. {
  2468. dwStatus = TLSRpcRequestNewLicenseEx(
  2469. hHandle,
  2470. pSupportFlags,
  2471. ChallengeContext,
  2472. &rpcRequest,
  2473. pMachineName,
  2474. pUserName,
  2475. cbChallengeResponse,
  2476. pbChallengeResponse,
  2477. bAcceptTemporaryLicense,
  2478. *pdwQuantity,
  2479. pcbLicense,
  2480. ppbLicense,
  2481. pdwErrCode
  2482. );
  2483. if (dwStatus == RPC_S_PROCNUM_OUT_OF_RANGE)
  2484. {
  2485. *pSupportFlags = 0;
  2486. dwStatus = TLSRpcRequestNewLicense(
  2487. hHandle,
  2488. ChallengeContext,
  2489. &rpcRequest,
  2490. pMachineName,
  2491. pUserName,
  2492. cbChallengeResponse,
  2493. pbChallengeResponse,
  2494. bAcceptTemporaryLicense,
  2495. pcbLicense,
  2496. ppbLicense,
  2497. pdwErrCode
  2498. );
  2499. }
  2500. }
  2501. return(dwStatus);
  2502. }
  2503. //----------------------------------------------------------------------------
  2504. DWORD WINAPI
  2505. TLSUpgradeLicense(
  2506. TLS_HANDLE hHandle,
  2507. LICENSEREQUEST *pRequest,
  2508. CHALLENGE_CONTEXT ChallengeContext,
  2509. DWORD cbChallengeResponse,
  2510. PBYTE pbChallengeResponse,
  2511. DWORD cbOldLicense,
  2512. PBYTE pbOldLicense,
  2513. PDWORD pcbNewLicense,
  2514. PBYTE* ppbNewLicense,
  2515. PDWORD pdwErrCode
  2516. )
  2517. /*++
  2518. ++*/
  2519. {
  2520. TLSLICENSEREQUEST rpcRequest;
  2521. RequestToTlsRequest( pRequest, &rpcRequest );
  2522. return TLSRpcUpgradeLicense(
  2523. hHandle,
  2524. &rpcRequest,
  2525. ChallengeContext,
  2526. cbChallengeResponse,
  2527. pbChallengeResponse,
  2528. cbOldLicense,
  2529. pbOldLicense,
  2530. pcbNewLicense,
  2531. ppbNewLicense,
  2532. pdwErrCode
  2533. );
  2534. }
  2535. //----------------------------------------------------------------------------
  2536. DWORD WINAPI
  2537. TLSUpgradeLicenseEx(
  2538. TLS_HANDLE hHandle,
  2539. PDWORD pSupportFlags,
  2540. LICENSEREQUEST *pRequest,
  2541. CHALLENGE_CONTEXT ChallengeContext,
  2542. DWORD cbChallengeResponse,
  2543. PBYTE pbChallengeResponse,
  2544. DWORD cbOldLicense,
  2545. PBYTE pbOldLicense,
  2546. DWORD dwQuantity,
  2547. PDWORD pcbNewLicense,
  2548. PBYTE* ppbNewLicense,
  2549. PDWORD pdwErrCode
  2550. )
  2551. /*++
  2552. ++*/
  2553. {
  2554. DWORD dwStatus;
  2555. TLSLICENSEREQUEST rpcRequest;
  2556. RequestToTlsRequest( pRequest, &rpcRequest );
  2557. dwStatus = TLSRpcUpgradeLicenseEx(
  2558. hHandle,
  2559. pSupportFlags,
  2560. &rpcRequest,
  2561. ChallengeContext,
  2562. cbChallengeResponse,
  2563. pbChallengeResponse,
  2564. cbOldLicense,
  2565. pbOldLicense,
  2566. dwQuantity,
  2567. pcbNewLicense,
  2568. ppbNewLicense,
  2569. pdwErrCode
  2570. );
  2571. if (dwStatus == RPC_S_PROCNUM_OUT_OF_RANGE)
  2572. {
  2573. *pSupportFlags = 0;
  2574. dwStatus = TLSRpcUpgradeLicense(
  2575. hHandle,
  2576. &rpcRequest,
  2577. ChallengeContext,
  2578. cbChallengeResponse,
  2579. pbChallengeResponse,
  2580. cbOldLicense,
  2581. pbOldLicense,
  2582. pcbNewLicense,
  2583. ppbNewLicense,
  2584. pdwErrCode
  2585. );
  2586. }
  2587. return(dwStatus);
  2588. }
  2589. //----------------------------------------------------------------------------
  2590. DWORD WINAPI
  2591. TLSAllocateConcurrentLicense(
  2592. TLS_HANDLE hHandle,
  2593. LPTSTR szHydraServer,
  2594. LICENSEREQUEST *pRequest,
  2595. LONG *dwQuantity,
  2596. PDWORD pdwErrCode
  2597. )
  2598. /*++
  2599. ++*/
  2600. {
  2601. TLSLICENSEREQUEST rpcRequest;
  2602. RequestToTlsRequest( pRequest, &rpcRequest );
  2603. return TLSRpcAllocateConcurrentLicense(
  2604. hHandle,
  2605. szHydraServer,
  2606. &rpcRequest,
  2607. dwQuantity,
  2608. pdwErrCode
  2609. );
  2610. }
  2611. //----------------------------------------------------------------------------
  2612. DWORD WINAPI
  2613. TLSGetLastError(
  2614. TLS_HANDLE hHandle,
  2615. DWORD cbBufferSize,
  2616. LPTSTR pszBuffer,
  2617. PDWORD pdwErrCode
  2618. )
  2619. /*++
  2620. ++*/
  2621. {
  2622. RPC_STATUS rpc_status;
  2623. rpc_status = TLSRpcGetLastError(
  2624. hHandle,
  2625. &cbBufferSize,
  2626. pszBuffer,
  2627. pdwErrCode
  2628. );
  2629. if(g_bLog)
  2630. LogMsg(L"\tRPC call TLSRpcGetLastError returned %d\n", rpc_status);
  2631. return rpc_status;
  2632. }
  2633. //----------------------------------------------------------------------------
  2634. DWORD WINAPI
  2635. TLSGetLastErrorFixed(
  2636. TLS_HANDLE hHandle,
  2637. LPTSTR *pszBuffer,
  2638. PDWORD pdwErrCode
  2639. )
  2640. /*++
  2641. ++*/
  2642. {
  2643. RPC_STATUS rpc_status;
  2644. rpc_status = TLSRpcGetLastErrorFixed(
  2645. hHandle,
  2646. pszBuffer,
  2647. pdwErrCode
  2648. );
  2649. if(g_bLog)
  2650. LogMsg(L"\tRPC call TLSRpcGetLastErrorFixed returned %d\n", rpc_status);
  2651. return rpc_status;
  2652. }
  2653. //----------------------------------------------------------------------------
  2654. DWORD WINAPI
  2655. TLSKeyPackEnumBegin(
  2656. TLS_HANDLE hHandle,
  2657. DWORD dwSearchParm,
  2658. BOOL bMatchAll,
  2659. LPLSKeyPackSearchParm lpSearchParm,
  2660. PDWORD pdwErrCode
  2661. )
  2662. /*++
  2663. ++*/
  2664. {
  2665. return TLSRpcKeyPackEnumBegin(
  2666. hHandle,
  2667. dwSearchParm,
  2668. bMatchAll,
  2669. lpSearchParm,
  2670. pdwErrCode
  2671. );
  2672. }
  2673. //----------------------------------------------------------------------------
  2674. DWORD WINAPI
  2675. TLSKeyPackEnumNext(
  2676. TLS_HANDLE hHandle,
  2677. LPLSKeyPack lpKeyPack,
  2678. PDWORD pdwErrCode
  2679. )
  2680. /*++
  2681. ++*/
  2682. {
  2683. return TLSRpcKeyPackEnumNext(
  2684. hHandle,
  2685. lpKeyPack,
  2686. pdwErrCode
  2687. );
  2688. }
  2689. //----------------------------------------------------------------------------
  2690. DWORD WINAPI
  2691. TLSKeyPackEnumEnd(
  2692. TLS_HANDLE hHandle,
  2693. PDWORD pdwErrCode
  2694. )
  2695. /*++
  2696. ++*/
  2697. {
  2698. return TLSRpcKeyPackEnumEnd(hHandle, pdwErrCode);
  2699. }
  2700. //----------------------------------------------------------------------------
  2701. DWORD WINAPI
  2702. TLSLicenseEnumBegin(
  2703. TLS_HANDLE hHandle,
  2704. DWORD dwSearchParm,
  2705. BOOL bMatchAll,
  2706. LPLSLicenseSearchParm lpSearchParm,
  2707. PDWORD pdwErrCode
  2708. )
  2709. /*++
  2710. ++*/
  2711. {
  2712. return TLSRpcLicenseEnumBegin(
  2713. hHandle,
  2714. dwSearchParm,
  2715. bMatchAll,
  2716. lpSearchParm,
  2717. pdwErrCode
  2718. );
  2719. }
  2720. //----------------------------------------------------------------------------
  2721. DWORD WINAPI
  2722. TLSLicenseEnumNext(
  2723. TLS_HANDLE hHandle,
  2724. LPLSLicense lpLicense,
  2725. PDWORD pdwErrCode
  2726. )
  2727. /*++
  2728. ++*/
  2729. {
  2730. return TLSRpcLicenseEnumNext(
  2731. hHandle,
  2732. lpLicense,
  2733. pdwErrCode
  2734. );
  2735. }
  2736. //----------------------------------------------------------------------------
  2737. DWORD WINAPI
  2738. TLSLicenseEnumNextEx(
  2739. TLS_HANDLE hHandle,
  2740. LPLSLicenseEx lpLicenseEx,
  2741. PDWORD pdwErrCode
  2742. )
  2743. /*++
  2744. ++*/
  2745. {
  2746. DWORD dwRet;
  2747. if (NULL == lpLicenseEx)
  2748. {
  2749. return ERROR_INVALID_PARAMETER;
  2750. }
  2751. dwRet = TLSRpcLicenseEnumNextEx(
  2752. hHandle,
  2753. lpLicenseEx,
  2754. pdwErrCode
  2755. );
  2756. if (RPC_S_PROCNUM_OUT_OF_RANGE == dwRet)
  2757. {
  2758. LSLicense License;
  2759. dwRet = TLSRpcLicenseEnumNext(
  2760. hHandle,
  2761. &License,
  2762. pdwErrCode
  2763. );
  2764. if ((dwRet == RPC_S_OK)
  2765. && (NULL != pdwErrCode)
  2766. && (*pdwErrCode == ERROR_SUCCESS))
  2767. {
  2768. // older versions only support quantity == 1
  2769. memcpy(lpLicenseEx,&License,sizeof(License));
  2770. lpLicenseEx->dwQuantity = 1;
  2771. }
  2772. }
  2773. return dwRet;
  2774. }
  2775. //----------------------------------------------------------------------------
  2776. DWORD WINAPI
  2777. TLSLicenseEnumEnd(
  2778. TLS_HANDLE hHandle,
  2779. PDWORD pdwErrCode
  2780. )
  2781. /*++
  2782. ++*/
  2783. {
  2784. return TLSRpcLicenseEnumEnd(hHandle, pdwErrCode);
  2785. }
  2786. //----------------------------------------------------------------------------
  2787. DWORD WINAPI
  2788. TLSGetAvailableLicenses(
  2789. TLS_HANDLE hHandle,
  2790. DWORD dwSearchParm,
  2791. LPLSKeyPack lplsKeyPack,
  2792. LPDWORD lpdwAvail,
  2793. PDWORD pdwErrCode
  2794. )
  2795. /*++
  2796. ++*/
  2797. {
  2798. return TLSRpcGetAvailableLicenses(
  2799. hHandle,
  2800. dwSearchParm,
  2801. lplsKeyPack,
  2802. lpdwAvail,
  2803. pdwErrCode
  2804. );
  2805. }
  2806. //----------------------------------------------------------------------------
  2807. DWORD WINAPI
  2808. TLSGetRevokeKeyPackList(
  2809. TLS_HANDLE hHandle,
  2810. PDWORD pcbNumberOfRange,
  2811. LPLSRange *ppRevokeRange,
  2812. PDWORD pdwErrCode
  2813. )
  2814. /*++
  2815. ++*/
  2816. {
  2817. return TLSRpcGetRevokeKeyPackList(
  2818. hHandle,
  2819. pcbNumberOfRange,
  2820. ppRevokeRange,
  2821. pdwErrCode
  2822. );
  2823. }
  2824. //----------------------------------------------------------------------------
  2825. DWORD WINAPI
  2826. TLSGetRevokeLicenseList(
  2827. TLS_HANDLE hHandle,
  2828. PDWORD pcbNumberOfRange,
  2829. LPLSRange *ppRevokeRange,
  2830. PDWORD pdwErrCode
  2831. )
  2832. /*++
  2833. ++*/
  2834. {
  2835. return TLSRpcGetRevokeLicenseList(
  2836. hHandle,
  2837. pcbNumberOfRange,
  2838. ppRevokeRange,
  2839. pdwErrCode
  2840. );
  2841. }
  2842. //----------------------------------------------------------------------------
  2843. DWORD WINAPI
  2844. TLSMarkLicense(
  2845. TLS_HANDLE hHandle,
  2846. UCHAR ucFlags,
  2847. DWORD cbLicense,
  2848. PBYTE pLicense,
  2849. PDWORD pdwErrCode
  2850. )
  2851. /*++
  2852. ++*/
  2853. {
  2854. return TLSRpcMarkLicense(
  2855. hHandle,
  2856. ucFlags,
  2857. cbLicense,
  2858. pLicense,
  2859. pdwErrCode
  2860. );
  2861. }
  2862. //----------------------------------------------------------------------------
  2863. DWORD WINAPI
  2864. TLSCheckLicenseMark(
  2865. TLS_HANDLE hHandle,
  2866. DWORD cbLicense,
  2867. PBYTE pLicense,
  2868. PUCHAR pucFlags,
  2869. PDWORD pdwErrCode
  2870. )
  2871. /*++
  2872. ++*/
  2873. {
  2874. return TLSRpcCheckLicenseMark(
  2875. hHandle,
  2876. cbLicense,
  2877. pLicense,
  2878. pucFlags,
  2879. pdwErrCode
  2880. );
  2881. }
  2882. //----------------------------------------------------------------------------
  2883. DWORD WINAPI
  2884. TLSGetSupportFlags(
  2885. TLS_HANDLE hHandle,
  2886. DWORD *pdwSupportFlags
  2887. )
  2888. /*++
  2889. ++*/
  2890. {
  2891. return TLSRpcGetSupportFlags(
  2892. hHandle,
  2893. pdwSupportFlags
  2894. );
  2895. }