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.

888 lines
21 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996-1998
  5. //
  6. // File: tlsapip.cpp
  7. //
  8. // Contents: Private API
  9. //
  10. // History: 09-09-97 HueiWang Created
  11. //
  12. //---------------------------------------------------------------------------
  13. #include <nt.h>
  14. #include <ntrtl.h>
  15. #include <nturtl.h>
  16. #include <windows.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <tchar.h>
  20. #include <rpc.h>
  21. #include "lscommon.h"
  22. #include <wincrypt.h>
  23. #include "tlsrpc.h"
  24. #include "tlsapi.h"
  25. #include "tlsapip.h"
  26. //----------------------------------------------------------------------------
  27. BOOL
  28. TLSIsLicenseEnforceEnable()
  29. /*++
  30. --*/
  31. {
  32. #if ENFORCE_LICENSING
  33. return TRUE;
  34. #else
  35. return FALSE;
  36. #endif
  37. }
  38. //----------------------------------------------------------------------------
  39. BOOL
  40. TLSIsBetaNTServer()
  41. /*++
  42. Abstract:
  43. Detemine if base NT is a beta or RTM version.
  44. Parameter:
  45. None.
  46. Return:
  47. TRUE/FALSE
  48. --*/
  49. {
  50. BOOL bBetaNt = FALSE;
  51. DWORD dwStatus;
  52. DWORD cbData;
  53. DWORD cbType;
  54. HKEY hKey = NULL;
  55. __try {
  56. LARGE_INTEGER Time = USER_SHARED_DATA->SystemExpirationDate;
  57. if(Time.QuadPart)
  58. {
  59. bBetaNt = TRUE;
  60. // check our special registry key - force
  61. // issuing a RTM license.
  62. dwStatus = RegOpenKeyEx(
  63. HKEY_LOCAL_MACHINE,
  64. L"SOFTWARE\\Microsoft\\TermServLicensing",
  65. 0,
  66. KEY_ALL_ACCESS,
  67. &hKey
  68. );
  69. if(dwStatus == ERROR_SUCCESS)
  70. {
  71. dwStatus = RegQueryValueEx(
  72. hKey,
  73. _TEXT("RunAsRTM"),
  74. NULL,
  75. &cbType,
  76. NULL,
  77. &cbData
  78. );
  79. // for testing, force it to run as RTM version.
  80. // key must exist and must be DWORD type
  81. if(dwStatus == ERROR_SUCCESS && cbType == REG_DWORD)
  82. {
  83. bBetaNt = FALSE;
  84. }
  85. }
  86. }
  87. }
  88. __except(EXCEPTION_EXECUTE_HANDLER) {
  89. ASSERT(FALSE);
  90. }
  91. if(hKey != NULL)
  92. {
  93. RegCloseKey(hKey);
  94. }
  95. return bBetaNt;
  96. }
  97. //----------------------------------------------------------------------------
  98. DWORD WINAPI
  99. TLSAllocateInternetLicenseEx(
  100. IN TLS_HANDLE hHandle,
  101. IN const CHALLENGE_CONTEXT ChallengeContext,
  102. IN const LICENSEREQUEST* pRequest,
  103. IN LPTSTR pszMachineName,
  104. IN LPTSTR pszUserName,
  105. IN const DWORD cbChallengeResponse,
  106. IN const PBYTE pbChallengeResponse,
  107. OUT PTLSInternetLicense pInternetLicense,
  108. OUT PDWORD pdwErrCode
  109. )
  110. /*++
  111. --*/
  112. {
  113. TLSLICENSEREQUEST rpcRequest;
  114. RequestToTlsRequest( pRequest, &rpcRequest );
  115. return TLSRpcAllocateInternetLicenseEx(
  116. hHandle,
  117. ChallengeContext,
  118. &rpcRequest,
  119. pszMachineName,
  120. pszUserName,
  121. cbChallengeResponse,
  122. pbChallengeResponse,
  123. pInternetLicense,
  124. pdwErrCode
  125. );
  126. }
  127. //----------------------------------------------------------------------------
  128. DWORD WINAPI
  129. TLSReturnInternetLicenseEx(
  130. IN TLS_HANDLE hHandle,
  131. IN const LICENSEREQUEST* pRequest,
  132. IN const ULARGE_INTEGER* pulSerialNumber,
  133. IN const DWORD dwQuantity,
  134. OUT PDWORD pdwErrCode
  135. )
  136. /*++
  137. --*/
  138. {
  139. TLSLICENSEREQUEST rpcRequest;
  140. RequestToTlsRequest( pRequest, &rpcRequest );
  141. return TLSRpcReturnInternetLicenseEx(
  142. hHandle,
  143. &rpcRequest,
  144. pulSerialNumber,
  145. dwQuantity,
  146. pdwErrCode
  147. );
  148. }
  149. //----------------------------------------------------------------------------
  150. DWORD WINAPI
  151. TLSRegisterLicenseKeyPack(
  152. TLS_HANDLE hHandle,
  153. LPBYTE pbCHCertBlob,
  154. DWORD cbCHCertBlobSize,
  155. LPBYTE pbRootCertBlob,
  156. DWORD cbRootCertBlob,
  157. LPBYTE lpKeyPackBlob,
  158. DWORD dwKeyPackBlobLen,
  159. PDWORD pdwErrCode
  160. )
  161. /*++
  162. ++*/
  163. {
  164. return TLSRpcRegisterLicenseKeyPack(
  165. hHandle,
  166. pbCHCertBlob,
  167. cbCHCertBlobSize,
  168. pbRootCertBlob,
  169. cbRootCertBlob,
  170. lpKeyPackBlob,
  171. dwKeyPackBlobLen,
  172. pdwErrCode
  173. );
  174. }
  175. //----------------------------------------------------------------------------
  176. DWORD WINAPI
  177. TLSTelephoneRegisterLKP(
  178. IN TLS_HANDLE hHandle,
  179. IN DWORD cbData,
  180. IN PBYTE pbData,
  181. OUT PDWORD pdwErrCode
  182. )
  183. /*++
  184. --*/
  185. {
  186. return TLSRpcTelephoneRegisterLKP(
  187. hHandle,
  188. cbData,
  189. pbData,
  190. pdwErrCode
  191. );
  192. }
  193. //----------------------------------------------------------------------------
  194. DWORD WINAPI
  195. RequestToTlsRequest(
  196. const LICENSEREQUEST* lpRequest,
  197. TLSLICENSEREQUEST* lpRpcRequest
  198. )
  199. /*++
  200. ++*/
  201. {
  202. if(lpRequest == NULL || lpRpcRequest == NULL || lpRequest->pProductInfo == NULL)
  203. return ERROR_INVALID_PARAMETER;
  204. //
  205. // NOTE : No memory allocation, DO NOT FREE ...
  206. //
  207. lpRpcRequest->cbEncryptedHwid = lpRequest->cbEncryptedHwid;
  208. lpRpcRequest->pbEncryptedHwid = lpRequest->pbEncryptedHwid;
  209. lpRpcRequest->dwLanguageID = lpRequest->dwLanguageID;
  210. lpRpcRequest->dwPlatformID = lpRequest->dwPlatformID;
  211. lpRpcRequest->ProductInfo.dwVersion = lpRequest->pProductInfo->dwVersion;
  212. lpRpcRequest->ProductInfo.cbCompanyName = lpRequest->pProductInfo->cbCompanyName;
  213. lpRpcRequest->ProductInfo.pbCompanyName = lpRequest->pProductInfo->pbCompanyName;
  214. lpRpcRequest->ProductInfo.cbProductID = lpRequest->pProductInfo->cbProductID;
  215. lpRpcRequest->ProductInfo.pbProductID = lpRequest->pProductInfo->pbProductID;
  216. return ERROR_SUCCESS;
  217. }
  218. //----------------------------------------------------------------------------
  219. DWORD WINAPI
  220. TLSReturnLicense(
  221. TLS_HANDLE hHandle,
  222. DWORD dwKeyPackId,
  223. DWORD dwLicenseId,
  224. DWORD dwRetrunReason,
  225. PDWORD pdwErrCode
  226. )
  227. /*++
  228. ++*/
  229. {
  230. return TLSRpcReturnLicense(
  231. hHandle,
  232. dwKeyPackId,
  233. dwLicenseId,
  234. dwRetrunReason,
  235. pdwErrCode
  236. );
  237. }
  238. //----------------------------------------------------------------------------
  239. DWORD WINAPI
  240. TLSGetLSPKCS10CertRequest(
  241. TLS_HANDLE hHandle,
  242. DWORD dwCertType,
  243. PDWORD pcbData,
  244. PBYTE* ppbData,
  245. PDWORD pdwErrCode
  246. )
  247. /*++
  248. ++*/
  249. {
  250. return TLSRpcGetLSPKCS10CertRequest(
  251. hHandle,
  252. dwCertType,
  253. pcbData,
  254. ppbData,
  255. pdwErrCode
  256. );
  257. }
  258. //----------------------------------------------------------------------------
  259. DWORD WINAPI
  260. TLSRequestTermServCert(
  261. TLS_HANDLE hHandle,
  262. LPLSHydraCertRequest pRequest,
  263. PDWORD cbChallengeData,
  264. PBYTE* pbChallengeData,
  265. PDWORD pdwErrCode
  266. )
  267. /*++
  268. ++*/
  269. {
  270. TLSHYDRACERTREQUEST CertRequest;
  271. CertRequest.dwHydraVersion = pRequest->dwHydraVersion;
  272. CertRequest.pbEncryptedHwid = pRequest->pbEncryptedHwid;
  273. CertRequest.cbEncryptedHwid = pRequest->cbEncryptedHwid;
  274. CertRequest.szSubjectRdn = pRequest->szSubjectRdn;
  275. CertRequest.pSubjectPublicKeyInfo = (TLSCERT_PUBLIC_KEY_INFO *)pRequest->SubjectPublicKeyInfo;
  276. CertRequest.dwNumCertExtension = pRequest->dwNumCertExtension;
  277. CertRequest.pCertExtensions = (TLSCERT_EXTENSION *)pRequest->pCertExtensions;
  278. return TLSRpcRequestTermServCert(
  279. hHandle,
  280. &CertRequest,
  281. cbChallengeData,
  282. pbChallengeData,
  283. pdwErrCode
  284. );
  285. }
  286. //----------------------------------------------------------------------------
  287. DWORD WINAPI
  288. TLSRetrieveTermServCert(
  289. TLS_HANDLE hHandle,
  290. DWORD cbResponseData,
  291. PBYTE pbResponseData,
  292. PDWORD pcbCert,
  293. PBYTE* ppbCert,
  294. PDWORD pdwErrCode
  295. )
  296. /*++
  297. ++*/
  298. {
  299. return TLSRpcRetrieveTermServCert(
  300. hHandle,
  301. cbResponseData,
  302. pbResponseData,
  303. pcbCert,
  304. ppbCert,
  305. pdwErrCode
  306. );
  307. }
  308. //----------------------------------------------------------------------------
  309. DWORD WINAPI
  310. TLSInstallCertificate(
  311. TLS_HANDLE hHandle,
  312. DWORD dwCertType,
  313. DWORD dwCertLevel,
  314. DWORD cbSingnatureCert,
  315. PBYTE pbSingnatureCert,
  316. DWORD cbExchangeCert,
  317. PBYTE pbExchangeCert,
  318. PDWORD pdwErrCode
  319. )
  320. /*++
  321. ++*/
  322. {
  323. return TLSRpcInstallCertificate(
  324. hHandle,
  325. dwCertType,
  326. dwCertLevel,
  327. cbSingnatureCert,
  328. pbSingnatureCert,
  329. cbExchangeCert,
  330. pbExchangeCert,
  331. pdwErrCode
  332. );
  333. }
  334. //----------------------------------------------------------------------------
  335. DWORD WINAPI
  336. TLSGetServerCertificate(
  337. TLS_HANDLE hHandle,
  338. BOOL bSignCert,
  339. LPBYTE *ppbCertBlob,
  340. LPDWORD lpdwCertBlobLen,
  341. PDWORD pdwErrCode
  342. )
  343. /*++
  344. ++*/
  345. {
  346. return TLSRpcGetServerCertificate(
  347. hHandle,
  348. bSignCert,
  349. ppbCertBlob,
  350. lpdwCertBlobLen,
  351. pdwErrCode
  352. );
  353. }
  354. //----------------------------------------------------------------------------
  355. DWORD WINAPI
  356. TLSKeyPackAdd(
  357. TLS_HANDLE hHandle,
  358. LPLSKeyPack lpKeypack,
  359. PDWORD pdwErrCode
  360. )
  361. /*++
  362. ++*/
  363. {
  364. return TLSRpcKeyPackAdd(
  365. hHandle,
  366. lpKeypack,
  367. pdwErrCode
  368. );
  369. }
  370. //----------------------------------------------------------------------------
  371. DWORD WINAPI
  372. TLSKeyPackSetStatus(
  373. TLS_HANDLE hHandle,
  374. DWORD dwSetParm,
  375. LPLSKeyPack lpKeyPack,
  376. PDWORD pdwErrCode
  377. )
  378. /*++
  379. ++*/
  380. {
  381. return TLSRpcKeyPackSetStatus(
  382. hHandle,
  383. dwSetParm,
  384. lpKeyPack,
  385. pdwErrCode
  386. );
  387. }
  388. //-----------------------------------------------------------------
  389. DWORD WINAPI
  390. TLSAnnounceServer(
  391. IN TLS_HANDLE hHandle,
  392. IN DWORD dwType,
  393. IN FILETIME* pftTime,
  394. IN LPTSTR pszSetupId,
  395. IN LPTSTR pszDomainName,
  396. IN LPTSTR pszMachineName,
  397. OUT PDWORD pdwErrCode
  398. )
  399. /*++
  400. ++*/
  401. {
  402. return TLSRpcAnnounceServer(
  403. hHandle,
  404. dwType,
  405. pftTime,
  406. pszSetupId,
  407. pszDomainName,
  408. pszMachineName,
  409. pdwErrCode
  410. );
  411. }
  412. //-----------------------------------------------------------------
  413. DWORD WINAPI
  414. TLSLookupServer(
  415. IN TLS_HANDLE hHandle,
  416. IN LPTSTR pszLookupSetupId,
  417. OUT LPTSTR pszLsSetupId,
  418. IN OUT PDWORD pcbSetupId,
  419. OUT LPTSTR pszDomainName,
  420. IN OUT PDWORD pcbDomainName,
  421. IN LPTSTR pszLsName,
  422. IN OUT PDWORD pcbMachineName,
  423. OUT PDWORD pdwErrCode
  424. )
  425. /*++
  426. ++*/
  427. {
  428. return TLSRpcLookupServer(
  429. hHandle,
  430. pszLookupSetupId,
  431. pszLsSetupId,
  432. pcbSetupId,
  433. pszDomainName,
  434. pcbDomainName,
  435. pszLsName,
  436. pcbMachineName,
  437. pdwErrCode
  438. );
  439. }
  440. //-----------------------------------------------------------------
  441. DWORD WINAPI
  442. TLSLookupServerFixed(
  443. IN TLS_HANDLE hHandle,
  444. IN LPTSTR pszLookupSetupId,
  445. OUT LPTSTR *pszLsSetupId,
  446. OUT LPTSTR *pszDomainName,
  447. OUT LPTSTR *pszLsName,
  448. IN OUT PDWORD pdwErrCode
  449. )
  450. /*++
  451. ++*/
  452. {
  453. return TLSRpcLookupServerFixed(
  454. hHandle,
  455. pszLookupSetupId,
  456. pszLsSetupId,
  457. pszDomainName,
  458. pszLsName,
  459. pdwErrCode
  460. );
  461. }
  462. //-------------------------------------------------------
  463. DWORD WINAPI
  464. TLSAnnounceLicensePack(
  465. IN TLS_HANDLE hHandle,
  466. IN PTLSReplRecord pReplRecord,
  467. OUT PDWORD pdwErrCode
  468. )
  469. /*++
  470. ++*/
  471. {
  472. return TLSRpcAnnounceLicensePack(
  473. hHandle,
  474. pReplRecord,
  475. pdwErrCode
  476. );
  477. }
  478. //-------------------------------------------------------
  479. DWORD WINAPI
  480. TLSReturnLicensedProduct(
  481. IN TLS_HANDLE hHandle,
  482. IN PTLSLicenseToBeReturn pClientLicense,
  483. OUT PDWORD pdwErrCode
  484. )
  485. /*++
  486. ++*/
  487. {
  488. return TLSRpcReturnLicensedProduct(
  489. hHandle,
  490. pClientLicense,
  491. pdwErrCode
  492. );
  493. }
  494. //-------------------------------------------------------
  495. DWORD WINAPI
  496. TLSChallengeServer(
  497. IN TLS_HANDLE hHandle,
  498. IN DWORD dwClientType,
  499. IN PTLSCHALLENGEDATA pClientChallenge,
  500. OUT PTLSCHALLENGERESPONSEDATA* ppServerResponse,
  501. OUT PTLSCHALLENGEDATA* ppServerChallenge,
  502. OUT PDWORD pdwErrCode
  503. )
  504. /*++
  505. --*/
  506. {
  507. return TLSRpcChallengeServer(
  508. hHandle,
  509. dwClientType,
  510. pClientChallenge,
  511. ppServerResponse,
  512. ppServerChallenge,
  513. pdwErrCode
  514. );
  515. }
  516. //-------------------------------------------------------
  517. DWORD WINAPI
  518. TLSResponseServerChallenge(
  519. IN TLS_HANDLE hHandle,
  520. IN PTLSCHALLENGERESPONSEDATA pClientResponse,
  521. OUT PDWORD pdwErrCode
  522. )
  523. /*++
  524. --*/
  525. {
  526. return TLSRpcResponseServerChallenge(
  527. hHandle,
  528. pClientResponse,
  529. pdwErrCode
  530. );
  531. }
  532. //------------------------------------------------------
  533. DWORD WINAPI
  534. TLSGetTlsPrivateData(
  535. IN TLS_HANDLE hHandle,
  536. IN DWORD dwGetDataType,
  537. IN PTLSPrivateDataUnion pGetParm,
  538. OUT PDWORD pdwRetDataType,
  539. OUT PTLSPrivateDataUnion* ppRetData,
  540. OUT PDWORD pdwErrCode
  541. )
  542. /*++
  543. --*/
  544. {
  545. return TLSRpcGetTlsPrivateData(
  546. hHandle,
  547. dwGetDataType,
  548. pGetParm,
  549. pdwRetDataType,
  550. ppRetData,
  551. pdwErrCode
  552. );
  553. }
  554. //------------------------------------------------------
  555. DWORD WINAPI
  556. TLSTriggerReGenKey(
  557. IN TLS_HANDLE hHandle,
  558. IN BOOL bKeepSPK,
  559. OUT PDWORD pdwErrCode
  560. )
  561. /*++
  562. --*/
  563. {
  564. return TLSRpcTriggerReGenKey(
  565. hHandle,
  566. bKeepSPK,
  567. pdwErrCode
  568. );
  569. }
  570. //------------------------------------------------------
  571. DWORD
  572. GetPrivateBinaryDataFromServer(
  573. TLS_HANDLE hHandle,
  574. DWORD dwType,
  575. PDWORD pcbData,
  576. PBYTE* ppbData,
  577. PDWORD pdwErrCode
  578. )
  579. /*++
  580. --*/
  581. {
  582. TLSPrivateDataUnion SearchParm;
  583. PTLSPrivateDataUnion pPrivateData = NULL;
  584. DWORD dwRetType;
  585. DWORD dwStatus;
  586. memset(
  587. &SearchParm,
  588. 0,
  589. sizeof(TLSPrivateDataUnion)
  590. );
  591. dwStatus = TLSRpcGetTlsPrivateData(
  592. hHandle,
  593. dwType,
  594. &SearchParm,
  595. &dwRetType,
  596. &pPrivateData,
  597. pdwErrCode
  598. );
  599. if(dwStatus != RPC_S_OK || *pdwErrCode != ERROR_SUCCESS)
  600. {
  601. goto cleanup;
  602. }
  603. if(dwRetType != dwType)
  604. {
  605. //
  606. // License Server error
  607. //
  608. *pdwErrCode = LSERVER_E_INVALID_RETURN;
  609. goto cleanup;
  610. }
  611. //
  612. // Copy over unique ID
  613. //
  614. *ppbData = (PBYTE)MIDL_user_allocate(pPrivateData->BinaryData.cbData);
  615. if(*ppbData != NULL)
  616. {
  617. memset(
  618. *ppbData,
  619. 0,
  620. pPrivateData->BinaryData.cbData
  621. );
  622. *pcbData = pPrivateData->BinaryData.cbData;
  623. memcpy(
  624. *ppbData,
  625. pPrivateData->BinaryData.pbData,
  626. pPrivateData->BinaryData.cbData
  627. );
  628. }
  629. else
  630. {
  631. *pdwErrCode = LSERVER_E_OUTOFMEMORY;
  632. }
  633. cleanup:
  634. if(pPrivateData != NULL)
  635. {
  636. midl_user_free(pPrivateData);
  637. }
  638. return dwStatus;
  639. }
  640. //------------------------------------------------------
  641. DWORD WINAPI
  642. TLSGetServerPID(
  643. TLS_HANDLE hHandle,
  644. PDWORD pcbData,
  645. PBYTE* ppbData,
  646. PDWORD pdwErrCode
  647. )
  648. /*++
  649. --*/
  650. {
  651. return GetPrivateBinaryDataFromServer(
  652. hHandle,
  653. TLS_PRIVATEDATA_PID,
  654. pcbData,
  655. ppbData,
  656. pdwErrCode
  657. );
  658. }
  659. //------------------------------------------------------
  660. DWORD WINAPI
  661. TLSGetServerSPK(
  662. TLS_HANDLE hHandle,
  663. PDWORD pcbData,
  664. PBYTE* ppbData,
  665. PDWORD pdwErrCode
  666. )
  667. /*++
  668. --*/
  669. {
  670. TLSPrivateDataUnion SearchParm;
  671. PTLSPrivateDataUnion pPrivateData = NULL;
  672. DWORD dwRetType;
  673. DWORD dwStatus;
  674. memset(
  675. &SearchParm,
  676. 0,
  677. sizeof(TLSPrivateDataUnion)
  678. );
  679. dwStatus = TLSRpcGetTlsPrivateData(
  680. hHandle,
  681. TLS_PRIVATEDATA_SPK,
  682. &SearchParm,
  683. &dwRetType,
  684. &pPrivateData,
  685. pdwErrCode
  686. );
  687. if(dwStatus != RPC_S_OK || *pdwErrCode != ERROR_SUCCESS)
  688. {
  689. goto cleanup;
  690. }
  691. if(dwRetType != TLS_PRIVATEDATA_SPK)
  692. {
  693. //
  694. // License Server error
  695. //
  696. *pdwErrCode = LSERVER_E_INVALID_RETURN;
  697. goto cleanup;
  698. }
  699. //
  700. // Copy over Server's SPK.
  701. // Server never return CH's cert extension.
  702. //
  703. *ppbData = (PBYTE)MIDL_user_allocate(pPrivateData->SPK.cbSPK);
  704. if(*ppbData != NULL)
  705. {
  706. memset(
  707. *ppbData,
  708. 0,
  709. pPrivateData->SPK.cbSPK
  710. );
  711. *pcbData = pPrivateData->SPK.cbSPK;
  712. memcpy(
  713. *ppbData,
  714. pPrivateData->SPK.pbSPK,
  715. pPrivateData->SPK.cbSPK
  716. );
  717. }
  718. else
  719. {
  720. *pdwErrCode = LSERVER_E_OUTOFMEMORY;
  721. }
  722. cleanup:
  723. if(pPrivateData != NULL)
  724. {
  725. midl_user_free(pPrivateData);
  726. }
  727. return dwStatus;
  728. }
  729. //-----------------------------------------------------------
  730. DWORD WINAPI
  731. TLSDepositeServerSPK(
  732. IN TLS_HANDLE hHandle,
  733. IN DWORD cbSPK,
  734. IN PBYTE pbSPK,
  735. IN PCERT_EXTENSIONS pCertExtensions,
  736. OUT PDWORD pdwErrCode
  737. )
  738. /*++
  739. --*/
  740. {
  741. TLSPrivateDataUnion SetData;
  742. DWORD dwStatus;
  743. SetData.SPK.cbSPK = cbSPK;
  744. SetData.SPK.pbSPK = pbSPK;
  745. SetData.SPK.pCertExtensions = pCertExtensions;
  746. return TLSRpcSetTlsPrivateData(
  747. hHandle,
  748. TLS_PRIVATEDATA_SPK,
  749. &SetData,
  750. pdwErrCode
  751. );
  752. }