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

1708 lines
41 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. // FILE : cryptapi.c //
  3. // DESCRIPTION : Crypto API interface //
  4. // AUTHOR : //
  5. // HISTORY : //
  6. // Dec 6 1994 larrys New //
  7. // Nov 13 1995 philh Lean & mean version for the STB //
  8. // Aug 18 1996 mattt sadvapi chgs from ecm tree //
  9. // Oct 23 1997 jeffspel Checkin for SChannel use //
  10. // Feb 08 1999 sfield avoid critical section, add exception handling //
  11. // //
  12. // Copyright (C) 1993 Microsoft Corporation All Rights Reserved //
  13. /////////////////////////////////////////////////////////////////////////////
  14. #include <nt.h>
  15. #include <ntrtl.h>
  16. #include <nturtl.h>
  17. #include <windows.h>
  18. #include <wincrypt.h>
  19. #include "swincryp.h"
  20. #include "scp.h"
  21. typedef struct _VTableStruc {
  22. HCRYPTPROV hProv; // Handle to provider
  23. LONG Inuse;
  24. } VTableStruc, *PVTableStruc;
  25. typedef struct _VKeyStruc {
  26. PVTableStruc pVTable; // pointer to provider
  27. HCRYPTKEY hKey; // Handle to key
  28. } VKeyStruc, *PVKeyStruc;
  29. typedef struct _VHashStruc {
  30. PVTableStruc pVTable; // pointer to provider
  31. HCRYPTHASH hHash; // Handle to hash
  32. } VHashStruc, *PVHashStruc;
  33. void __inline EnterProviderCritSec(IN PVTableStruc pVTable);
  34. LONG __inline LeaveProviderCritSec(IN PVTableStruc pVTable);
  35. PVKeyStruc BuildVKey(IN PVTableStruc pVTable);
  36. PVHashStruc BuildVHash(IN PVTableStruc pVTable);
  37. /*
  38. - CryptAcquireContextW
  39. -
  40. * Purpose:
  41. * The CryptAcquireContext function is used to acquire a context
  42. * handle to a cryptograghic service provider (CSP).
  43. *
  44. *
  45. * Parameters:
  46. * OUT phProv - Handle to a CSP
  47. * IN OUT pszIdentity - Pointer to the name of the context's
  48. * keyset.
  49. * IN OUT pszProvider - Pointer to the name of the provider.
  50. * IN dwProvType - Requested CSP type
  51. * IN dwFlags - Flags values
  52. *
  53. * Returns:
  54. */
  55. BOOL
  56. WINAPI SCryptAcquireContextW(OUT HCRYPTPROV *phProv,
  57. IN OUT LPCWSTR pwszIdentity,
  58. IN OUT LPCWSTR pwszProvider,
  59. IN DWORD dwProvType,
  60. IN DWORD dwFlags)
  61. {
  62. CHAR *pszIdentity = NULL;
  63. CHAR *pszProvider = NULL;
  64. long c = 0;
  65. long i;
  66. BOOL fRet = FALSE;
  67. if (pwszIdentity)
  68. {
  69. c = wcslen(pwszIdentity);
  70. if (NULL == (pszIdentity = (CHAR*)LocalAlloc(LMEM_ZEROINIT,
  71. (c+1) * sizeof(CHAR))))
  72. goto Ret;
  73. for (i=0;i<c;i++)
  74. pszIdentity[i] = (CHAR)pwszIdentity[i];
  75. pszIdentity[i] = 0;
  76. }
  77. if (pwszProvider)
  78. {
  79. c = wcslen(pwszProvider);
  80. if (NULL == (pszProvider = (CHAR*)LocalAlloc(LMEM_ZEROINIT,
  81. (c+1) * sizeof(CHAR))))
  82. goto Ret;
  83. for (i=0;i<c;i++)
  84. pszProvider[i] = (CHAR)pwszProvider[i];
  85. pszProvider[i] = 0;
  86. }
  87. fRet = SCryptAcquireContextA(
  88. phProv,
  89. pszIdentity,
  90. pszProvider,
  91. dwProvType,
  92. dwFlags
  93. );
  94. Ret:
  95. if (pszIdentity)
  96. LocalFree(pszIdentity);
  97. if (pszProvider)
  98. LocalFree(pszProvider);
  99. return fRet;
  100. }
  101. BOOL
  102. WINAPI SCryptAcquireContextA(OUT HCRYPTPROV *phProv,
  103. IN OUT LPCSTR pszIdentity,
  104. IN OUT LPCSTR pszProvider, // ignored
  105. IN DWORD dwProvType, // ignored
  106. IN DWORD dwFlags)
  107. {
  108. PVTableStruc pVTable = NULL;
  109. VTableProvStruc TableForProvider;
  110. BOOL fRet = FALSE;
  111. pVTable = (PVTableStruc)LocalAlloc(
  112. LMEM_ZEROINIT,
  113. sizeof(VTableStruc)
  114. );
  115. if( pVTable == NULL ) {
  116. *phProv = 0;
  117. return FALSE;
  118. }
  119. memset(&TableForProvider, 0, sizeof(TableForProvider));
  120. TableForProvider.Version = 2;
  121. TableForProvider.FuncVerifyImage = NULL;
  122. TableForProvider.FuncReturnhWnd = 0;
  123. TableForProvider.dwProvType = dwProvType;
  124. TableForProvider.pbContextInfo = NULL;
  125. TableForProvider.cbContextInfo = 0;
  126. __try {
  127. fRet = CPAcquireContext(
  128. &pVTable->hProv,
  129. (LPSTR)pszIdentity,
  130. dwFlags,
  131. &TableForProvider
  132. );
  133. } __except (EXCEPTION_EXECUTE_HANDLER) {
  134. fRet = FALSE;
  135. ASSERT( fRet );
  136. }
  137. if(!fRet)
  138. {
  139. LocalFree(pVTable);
  140. pVTable = NULL;
  141. }
  142. else
  143. {
  144. if (dwFlags & CRYPT_DELETEKEYSET)
  145. {
  146. LocalFree(pVTable);
  147. pVTable = NULL;
  148. } else {
  149. pVTable->Inuse = 1;
  150. }
  151. }
  152. *phProv = (HCRYPTPROV)pVTable;
  153. return fRet;
  154. }
  155. /*
  156. - CryptReleaseContext
  157. -
  158. * Purpose:
  159. * The CryptReleaseContext function is used to release a
  160. * context created by CryptAcquireContext.
  161. *
  162. * Parameters:
  163. * IN phProv - Handle to a CSP
  164. * IN dwFlags - Flags values
  165. *
  166. * Returns:
  167. */
  168. BOOL
  169. WINAPI SCryptReleaseContext(IN HCRYPTPROV hProv,
  170. IN DWORD dwFlags)
  171. {
  172. PVTableStruc pVTable = (PVTableStruc) hProv;
  173. LONG ContextRefCount;
  174. BOOL fRet = FALSE;
  175. ContextRefCount = LeaveProviderCritSec( pVTable );
  176. __try {
  177. //
  178. // for debug builds, catch fools leaking state.
  179. //
  180. ASSERT( ContextRefCount == 0 );
  181. if( ContextRefCount != 0 ) {
  182. SetLastError(ERROR_BUSY);
  183. return FALSE;
  184. }
  185. fRet = CPReleaseContext(pVTable->hProv, dwFlags);
  186. } __except ( EXCEPTION_EXECUTE_HANDLER ) {
  187. fRet = FALSE;
  188. ASSERT( fRet );
  189. }
  190. LocalFree(pVTable);
  191. return fRet;
  192. }
  193. /*
  194. - CryptGenKey
  195. -
  196. * Purpose:
  197. * Generate cryptographic keys
  198. *
  199. *
  200. * Parameters:
  201. * IN hProv - Handle to a CSP
  202. * IN Algid - Algorithm identifier
  203. * IN dwFlags - Flags values
  204. * OUT phKey - Handle to a generated key
  205. *
  206. * Returns:
  207. */
  208. BOOL
  209. WINAPI SCryptGenKey(IN HCRYPTPROV hProv,
  210. IN ALG_ID Algid,
  211. IN DWORD dwFlags,
  212. OUT HCRYPTKEY * phKey)
  213. {
  214. PVTableStruc pVTable = (PVTableStruc) hProv;
  215. PVKeyStruc pVKey;
  216. BOOL fCritSec = FALSE;
  217. BOOL fRet = FALSE;
  218. __try {
  219. *phKey = 0;
  220. pVKey = BuildVKey(pVTable);
  221. if( pVKey == NULL )
  222. return FALSE;
  223. EnterProviderCritSec(pVTable);
  224. fCritSec = TRUE;
  225. fRet = CPGenKey(pVTable->hProv, Algid, dwFlags, &pVKey->hKey);
  226. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  227. fRet = FALSE;
  228. ASSERT( fRet );
  229. }
  230. if( fCritSec ) {
  231. LeaveProviderCritSec(pVTable);
  232. }
  233. if( fRet ) {
  234. *phKey = (HCRYPTKEY) pVKey;
  235. return TRUE;
  236. }
  237. if (pVKey)
  238. LocalFree(pVKey);
  239. __try {
  240. *phKey = 0;
  241. } __except (EXCEPTION_EXECUTE_HANDLER) {
  242. ; // gulp
  243. }
  244. return FALSE;
  245. }
  246. /*
  247. - CryptDuplicateKey
  248. -
  249. * Purpose:
  250. * Duplicate a cryptographic key
  251. *
  252. *
  253. * Parameters:
  254. * IN hKey - Handle to the key to be duplicated
  255. * IN pdwReserved - Reserved for later use
  256. * IN dwFlags - Flags values
  257. * OUT phKey - Handle to the new duplicate key
  258. *
  259. * Returns:
  260. */
  261. BOOL
  262. WINAPI SCryptDuplicateKey(
  263. IN HCRYPTKEY hKey,
  264. IN DWORD *pdwReserved,
  265. IN DWORD dwFlags,
  266. OUT HCRYPTKEY * phKey
  267. )
  268. {
  269. PVKeyStruc pVKey = (PVKeyStruc) hKey;
  270. PVTableStruc pVTable;
  271. PVKeyStruc pVNewKey;
  272. BOOL fCritSec = FALSE;
  273. BOOL fRet = FALSE;
  274. __try {
  275. *phKey = 0;
  276. pVTable = pVKey->pVTable;
  277. pVNewKey = BuildVKey(pVTable);
  278. if( pVNewKey == NULL ) {
  279. return FALSE;
  280. }
  281. EnterProviderCritSec(pVTable);
  282. fCritSec = TRUE;
  283. fRet = CPDuplicateKey(
  284. pVTable->hProv,
  285. pVKey->hKey,
  286. pdwReserved,
  287. dwFlags,
  288. &pVNewKey->hKey
  289. );
  290. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  291. fRet = FALSE;
  292. ASSERT( fRet );
  293. }
  294. if( fCritSec ) {
  295. LeaveProviderCritSec(pVTable);
  296. }
  297. if( fRet ) {
  298. *phKey = (HCRYPTKEY) pVNewKey;
  299. return TRUE;
  300. }
  301. if (pVNewKey)
  302. LocalFree(pVNewKey);
  303. __try {
  304. *phKey = 0;
  305. } __except (EXCEPTION_EXECUTE_HANDLER) {
  306. ; // gulp
  307. }
  308. return FALSE;
  309. }
  310. /*
  311. - CryptDeriveKey
  312. -
  313. * Purpose:
  314. * Derive cryptographic keys from base data
  315. *
  316. *
  317. * Parameters:
  318. * IN hProv - Handle to a CSP
  319. * IN Algid - Algorithm identifier
  320. * IN hHash - Handle to hash of base data
  321. * IN dwFlags - Flags values
  322. * OUT phKey - Handle to a generated key
  323. *
  324. * Returns:
  325. */
  326. BOOL
  327. WINAPI SCryptDeriveKey(IN HCRYPTPROV hProv,
  328. IN ALG_ID Algid,
  329. IN HCRYPTHASH hHash,
  330. IN DWORD dwFlags,
  331. OUT HCRYPTKEY * phKey)
  332. {
  333. PVTableStruc pVTable = (PVTableStruc) hProv;
  334. PVHashStruc pVHash = (PVHashStruc) hHash;
  335. PVKeyStruc pVKey;
  336. BOOL fCritSec = FALSE;
  337. BOOL fRet = FALSE;
  338. __try {
  339. *phKey = 0;
  340. if (pVHash->pVTable != pVTable)
  341. {
  342. SetLastError(ERROR_INVALID_PARAMETER);
  343. return FALSE;
  344. }
  345. pVKey = BuildVKey(pVTable);
  346. if( pVKey == NULL )
  347. return FALSE;
  348. EnterProviderCritSec(pVTable);
  349. fCritSec = TRUE;
  350. fRet = CPDeriveKey(
  351. pVTable->hProv,
  352. Algid,
  353. pVHash->hHash,
  354. dwFlags,
  355. &pVKey->hKey
  356. );
  357. } __except (EXCEPTION_EXECUTE_HANDLER) {
  358. fRet = FALSE;
  359. ASSERT( fRet );
  360. }
  361. if( fCritSec ) {
  362. LeaveProviderCritSec(pVTable);
  363. }
  364. if( fRet ) {
  365. *phKey = (HCRYPTKEY) pVKey;
  366. return TRUE;
  367. }
  368. if (pVKey)
  369. LocalFree(pVKey);
  370. __try {
  371. *phKey = 0;
  372. } __except (EXCEPTION_EXECUTE_HANDLER) {
  373. ; // gulp
  374. }
  375. return FALSE;
  376. }
  377. /*
  378. - CryptDestroyKey
  379. -
  380. * Purpose:
  381. * Destroys the cryptographic key that is being referenced
  382. * with the hKey parameter
  383. *
  384. *
  385. * Parameters:
  386. * IN hKey - Handle to a key
  387. *
  388. * Returns:
  389. */
  390. BOOL
  391. WINAPI SCryptDestroyKey(IN HCRYPTKEY hKey)
  392. {
  393. PVKeyStruc pVKey = (PVKeyStruc) hKey;
  394. PVTableStruc pVTable;
  395. BOOL fCritSec = FALSE;
  396. BOOL fRet = FALSE;
  397. __try {
  398. pVTable = pVKey->pVTable;
  399. EnterProviderCritSec(pVTable);
  400. fCritSec = TRUE;
  401. fRet = CPDestroyKey(pVTable->hProv, pVKey->hKey);
  402. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  403. fRet = FALSE;
  404. ASSERT( fRet );
  405. }
  406. if( fCritSec ) {
  407. LeaveProviderCritSec(pVTable);
  408. }
  409. LocalFree(pVKey);
  410. return fRet;
  411. }
  412. /*
  413. - CryptSetKeyParam
  414. -
  415. * Purpose:
  416. * Allows applications to customize various aspects of the
  417. * operations of a key
  418. *
  419. * Parameters:
  420. * IN hKey - Handle to a key
  421. * IN dwParam - Parameter number
  422. * IN pbData - Pointer to data
  423. * IN dwFlags - Flags values
  424. *
  425. * Returns:
  426. */
  427. BOOL
  428. WINAPI SCryptSetKeyParam(IN HCRYPTKEY hKey,
  429. IN DWORD dwParam,
  430. IN BYTE *pbData,
  431. IN DWORD dwFlags)
  432. {
  433. PVKeyStruc pVKey = (PVKeyStruc) hKey;
  434. PVTableStruc pVTable;
  435. BOOL fCritSec = FALSE;
  436. BOOL fRet = FALSE;
  437. __try {
  438. pVTable = pVKey->pVTable;
  439. EnterProviderCritSec(pVTable);
  440. fCritSec = TRUE;
  441. fRet = CPSetKeyParam(
  442. pVTable->hProv,
  443. pVKey->hKey,
  444. dwParam,
  445. pbData,
  446. dwFlags
  447. );
  448. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  449. fRet = FALSE;
  450. ASSERT( fRet );
  451. }
  452. if( fCritSec )
  453. LeaveProviderCritSec(pVTable);
  454. return fRet;
  455. }
  456. /*
  457. - CryptGetKeyParam
  458. -
  459. * Purpose:
  460. * Allows applications to get various aspects of the
  461. * operations of a key
  462. *
  463. * Parameters:
  464. * IN hKey - Handle to a key
  465. * IN dwParam - Parameter number
  466. * IN pbData - Pointer to data
  467. * IN pdwDataLen - Length of parameter data
  468. * IN dwFlags - Flags values
  469. *
  470. * Returns:
  471. */
  472. BOOL
  473. WINAPI SCryptGetKeyParam(IN HCRYPTKEY hKey,
  474. IN DWORD dwParam,
  475. IN BYTE *pbData,
  476. IN DWORD *pdwDataLen,
  477. IN DWORD dwFlags)
  478. {
  479. PVKeyStruc pVKey = (PVKeyStruc) hKey;
  480. PVTableStruc pVTable;
  481. BOOL fCritSec = FALSE;
  482. BOOL fRet = FALSE;
  483. __try {
  484. pVTable = pVKey->pVTable;
  485. EnterProviderCritSec(pVTable);
  486. fCritSec = TRUE;
  487. fRet = CPGetKeyParam(
  488. pVTable->hProv,
  489. pVKey->hKey,
  490. dwParam,
  491. pbData,
  492. pdwDataLen,
  493. dwFlags
  494. );
  495. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  496. fRet = FALSE;
  497. ASSERT( fRet );
  498. }
  499. if( fCritSec ) {
  500. LeaveProviderCritSec(pVTable);
  501. }
  502. return fRet;
  503. }
  504. /*
  505. - CryptGenRandom
  506. -
  507. * Purpose:
  508. * Used to fill a buffer with random bytes
  509. *
  510. *
  511. * Parameters:
  512. * IN hProv - Handle to the user identifcation
  513. * IN dwLen - Number of bytes of random data requested
  514. * OUT pbBuffer - Pointer to the buffer where the random
  515. * bytes are to be placed
  516. *
  517. * Returns:
  518. */
  519. BOOL
  520. WINAPI SCryptGenRandom(IN HCRYPTPROV hProv,
  521. IN DWORD dwLen,
  522. OUT BYTE *pbBuffer)
  523. {
  524. PVTableStruc pVTable = (PVTableStruc) hProv;
  525. BOOL fCritSec = FALSE;
  526. BOOL fRet = FALSE;
  527. __try {
  528. EnterProviderCritSec(pVTable);
  529. fCritSec = TRUE;
  530. fRet = CPGenRandom(pVTable->hProv, dwLen, pbBuffer);
  531. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  532. fRet = FALSE;
  533. ASSERT( fRet );
  534. }
  535. if( fCritSec ) {
  536. LeaveProviderCritSec(pVTable);
  537. }
  538. return fRet;
  539. }
  540. /*
  541. - CryptGetUserKey
  542. -
  543. * Purpose:
  544. * Gets a handle to a permanent user key
  545. *
  546. *
  547. * Parameters:
  548. * IN hProv - Handle to the user identifcation
  549. * IN dwKeySpec - Specification of the key to retrieve
  550. * OUT phUserKey - Pointer to key handle of retrieved key
  551. *
  552. * Returns:
  553. */
  554. BOOL
  555. WINAPI SCryptGetUserKey(IN HCRYPTPROV hProv,
  556. IN DWORD dwKeySpec,
  557. OUT HCRYPTKEY *phUserKey)
  558. {
  559. PVTableStruc pVTable = (PVTableStruc) hProv;
  560. PVKeyStruc pVKey;
  561. BOOL fCritSec = FALSE;
  562. BOOL fRet = FALSE;
  563. __try {
  564. *phUserKey = 0;
  565. pVKey = BuildVKey(pVTable);
  566. if( pVKey == NULL ) {
  567. return FALSE;
  568. }
  569. EnterProviderCritSec(pVTable);
  570. fCritSec = TRUE;
  571. fRet = CPGetUserKey(pVTable->hProv, dwKeySpec, &pVKey->hKey);
  572. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  573. fRet = FALSE;
  574. ASSERT( fRet );
  575. }
  576. if( fCritSec ) {
  577. LeaveProviderCritSec(pVTable);
  578. }
  579. if( fRet ) {
  580. *phUserKey = (HCRYPTKEY) pVKey;
  581. return TRUE;
  582. }
  583. if (pVKey)
  584. LocalFree(pVKey);
  585. __try {
  586. *phUserKey = 0;
  587. } __except(EXCEPTION_EXECUTE_HANDLER) {
  588. ; // gulp
  589. }
  590. return FALSE;
  591. }
  592. /*
  593. - CryptExportKey
  594. -
  595. * Purpose:
  596. * Export cryptographic keys out of a CSP in a secure manner
  597. *
  598. *
  599. * Parameters:
  600. * IN hKey - Handle to the key to export
  601. * IN hPubKey - Handle to the exchange public key value of
  602. * the destination user
  603. * IN dwBlobType - Type of key blob to be exported
  604. * IN dwFlags - Flags values
  605. * OUT pbData - Key blob data
  606. * OUT pdwDataLen - Length of key blob in bytes
  607. *
  608. * Returns:
  609. */
  610. BOOL
  611. WINAPI SCryptExportKey(IN HCRYPTKEY hKey,
  612. IN HCRYPTKEY hPubKey,
  613. IN DWORD dwBlobType,
  614. IN DWORD dwFlags,
  615. OUT BYTE *pbData,
  616. OUT DWORD *pdwDataLen)
  617. {
  618. PVKeyStruc pVKey = (PVKeyStruc) hKey;
  619. PVTableStruc pVTable;
  620. PVKeyStruc pVPublicKey = (PVKeyStruc) hPubKey;
  621. BOOL fCritSec = FALSE;
  622. BOOL fRet = FALSE;
  623. __try {
  624. // Note: the SCP requires that the hPubKey has the same hProv as
  625. // the hKey. This is a problem for the MITV implementation where the
  626. // signature and exchange keys always have a different provider.
  627. pVTable = pVKey->pVTable;
  628. if (pVPublicKey && pVPublicKey->pVTable != pVTable)
  629. {
  630. *pdwDataLen = 0;
  631. SetLastError(ERROR_INVALID_PARAMETER);
  632. return FALSE;
  633. }
  634. EnterProviderCritSec(pVTable);
  635. fCritSec = TRUE;
  636. fRet = CPExportKey(
  637. pVTable->hProv,
  638. pVKey->hKey,
  639. (pVPublicKey == NULL ? 0 : pVPublicKey->hKey),
  640. dwBlobType,
  641. dwFlags,
  642. pbData,
  643. pdwDataLen
  644. );
  645. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  646. fRet = FALSE;
  647. ASSERT( fRet );
  648. }
  649. if( fCritSec ) {
  650. LeaveProviderCritSec(pVTable);
  651. }
  652. return fRet;
  653. }
  654. /*
  655. - CryptImportKey
  656. -
  657. * Purpose:
  658. * Import cryptographic keys
  659. *
  660. *
  661. * Parameters:
  662. * IN hProv - Handle to the CSP user
  663. * IN pbData - Key blob data
  664. * IN dwDataLen - Length of the key blob data
  665. * IN hPubKey - Handle to the exchange public key value of
  666. * the destination user
  667. * IN dwFlags - Flags values
  668. * OUT phKey - Pointer to the handle to the key which was
  669. * Imported
  670. *
  671. * Returns:
  672. */
  673. BOOL
  674. WINAPI SCryptImportKey(IN HCRYPTPROV hProv,
  675. IN CONST BYTE *pbData,
  676. IN DWORD dwDataLen,
  677. IN HCRYPTKEY hPubKey,
  678. IN DWORD dwFlags,
  679. OUT HCRYPTKEY *phKey)
  680. {
  681. PVTableStruc pVTable = (PVTableStruc) hProv;
  682. PVKeyStruc pVKey;
  683. PVKeyStruc pVPublicKey = (PVKeyStruc) hPubKey;
  684. BOOL fCritSec = FALSE;
  685. BOOL fRet = FALSE;
  686. __try {
  687. *phKey = 0;
  688. if (pVPublicKey && pVPublicKey->pVTable != pVTable)
  689. {
  690. SetLastError(ERROR_INVALID_PARAMETER);
  691. return FALSE;
  692. }
  693. pVKey = BuildVKey(pVTable);
  694. if( pVKey == NULL )
  695. return FALSE;
  696. EnterProviderCritSec(pVTable);
  697. fCritSec = TRUE;
  698. fRet = CPImportKey(
  699. pVTable->hProv,
  700. pbData,
  701. dwDataLen,
  702. (pVPublicKey == NULL ? 0 : pVPublicKey->hKey),
  703. dwFlags,
  704. &pVKey->hKey
  705. );
  706. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  707. fRet = FALSE;
  708. ASSERT( fRet );
  709. }
  710. if( fCritSec ) {
  711. LeaveProviderCritSec(pVTable);
  712. }
  713. if( fRet ) {
  714. *phKey = (HCRYPTKEY) pVKey;
  715. return TRUE;
  716. }
  717. if (pVKey)
  718. LocalFree(pVKey);
  719. __try {
  720. *phKey = 0;
  721. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  722. ; // gulp
  723. }
  724. return FALSE;
  725. }
  726. /*
  727. - CryptEncrypt
  728. -
  729. * Purpose:
  730. * Encrypt data
  731. *
  732. *
  733. * Parameters:
  734. * IN hKey - Handle to the key
  735. * IN hHash - Optional handle to a hash
  736. * IN Final - Boolean indicating if this is the final
  737. * block of plaintext
  738. * IN dwFlags - Flags values
  739. * IN OUT pbData - Data to be encrypted
  740. * IN OUT pdwDataLen - Pointer to the length of the data to be
  741. * encrypted
  742. * IN dwBufLen - Size of Data buffer
  743. *
  744. * Returns:
  745. */
  746. BOOL
  747. WINAPI SCryptEncrypt(IN HCRYPTKEY hKey,
  748. IN HCRYPTHASH hHash,
  749. IN BOOL Final,
  750. IN DWORD dwFlags,
  751. IN OUT BYTE *pbData,
  752. IN OUT DWORD *pdwDataLen,
  753. IN DWORD dwBufLen)
  754. {
  755. PVKeyStruc pVKey = (PVKeyStruc) hKey;
  756. PVTableStruc pVTable;
  757. PVHashStruc pVHash = (PVHashStruc) hHash;
  758. BOOL fCritSec = FALSE;
  759. BOOL fRet = FALSE;
  760. __try {
  761. pVTable = pVKey->pVTable;
  762. if (pVHash && pVHash->pVTable != pVTable)
  763. {
  764. *pdwDataLen = 0;
  765. SetLastError(ERROR_INVALID_PARAMETER);
  766. return FALSE;
  767. }
  768. EnterProviderCritSec(pVTable);
  769. fCritSec = TRUE;
  770. fRet = CPEncrypt(
  771. pVTable->hProv,
  772. pVKey->hKey,
  773. (pVHash == NULL ? 0 : pVHash->hHash),
  774. Final,
  775. dwFlags,
  776. pbData,
  777. pdwDataLen,
  778. dwBufLen
  779. );
  780. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  781. fRet = FALSE;
  782. ASSERT( fRet );
  783. }
  784. if( fCritSec ) {
  785. LeaveProviderCritSec(pVTable);
  786. }
  787. return fRet;
  788. }
  789. /*
  790. - CryptDecrypt
  791. -
  792. * Purpose:
  793. * Decrypt data
  794. *
  795. *
  796. * Parameters:
  797. * IN hKey - Handle to the key
  798. * IN hHash - Optional handle to a hash
  799. * IN Final - Boolean indicating if this is the final
  800. * block of ciphertext
  801. * IN dwFlags - Flags values
  802. * IN OUT pbData - Data to be decrypted
  803. * IN OUT pdwDataLen - Pointer to the length of the data to be
  804. * decrypted
  805. *
  806. * Returns:
  807. */
  808. BOOL
  809. WINAPI SCryptDecrypt(IN HCRYPTKEY hKey,
  810. IN HCRYPTHASH hHash,
  811. IN BOOL Final,
  812. IN DWORD dwFlags,
  813. IN OUT BYTE *pbData,
  814. IN OUT DWORD *pdwDataLen)
  815. {
  816. PVKeyStruc pVKey = (PVKeyStruc) hKey;
  817. PVTableStruc pVTable;
  818. PVHashStruc pVHash = (PVHashStruc) hHash;
  819. BOOL fCritSec = FALSE;
  820. BOOL fRet = FALSE;
  821. __try {
  822. pVTable = pVKey->pVTable;
  823. if (pVHash && pVHash->pVTable != pVTable)
  824. {
  825. *pdwDataLen = 0;
  826. SetLastError(ERROR_INVALID_PARAMETER);
  827. return FALSE;
  828. }
  829. EnterProviderCritSec(pVTable);
  830. fCritSec = TRUE;
  831. fRet = CPDecrypt(
  832. pVTable->hProv,
  833. pVKey->hKey,
  834. (pVHash == NULL ? 0 : pVHash->hHash),
  835. Final,
  836. dwFlags,
  837. pbData,
  838. pdwDataLen
  839. );
  840. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  841. fRet = FALSE;
  842. ASSERT( fRet );
  843. }
  844. if( fCritSec ) {
  845. LeaveProviderCritSec(pVTable);
  846. }
  847. return fRet;
  848. }
  849. /*
  850. - CryptCreateHash
  851. -
  852. * Purpose:
  853. * initate the hashing of a stream of data
  854. *
  855. *
  856. * Parameters:
  857. * IN hProv - Handle to the user identifcation
  858. * IN Algid - Algorithm identifier of the hash algorithm
  859. * to be used
  860. * IN hKey - Optional key for MAC algorithms
  861. * IN dwFlags - Flags values
  862. * OUT pHash - Handle to hash object
  863. *
  864. * Returns:
  865. */
  866. BOOL
  867. WINAPI SCryptCreateHash(IN HCRYPTPROV hProv,
  868. IN ALG_ID Algid,
  869. IN HCRYPTKEY hKey,
  870. IN DWORD dwFlags,
  871. OUT HCRYPTHASH *phHash)
  872. {
  873. PVTableStruc pVTable = (PVTableStruc) hProv;
  874. PVKeyStruc pVKey = (PVKeyStruc) hKey;
  875. PVHashStruc pVHash;
  876. BOOL fCritSec = FALSE;
  877. BOOL fRet = FALSE;
  878. __try {
  879. *phHash = 0;
  880. if (pVKey && pVKey->pVTable != pVTable)
  881. {
  882. SetLastError(ERROR_INVALID_PARAMETER);
  883. return FALSE;
  884. }
  885. pVHash = BuildVHash(pVTable);
  886. if( pVHash == NULL )
  887. return FALSE;
  888. EnterProviderCritSec(pVTable);
  889. fCritSec = TRUE;
  890. fRet = CPCreateHash(
  891. pVTable->hProv,
  892. Algid,
  893. (pVKey == NULL ? 0 : pVKey->hKey),
  894. dwFlags,
  895. &pVHash->hHash
  896. );
  897. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  898. fRet = FALSE;
  899. ASSERT( fRet );
  900. }
  901. if( fCritSec ) {
  902. LeaveProviderCritSec(pVTable);
  903. }
  904. if( fRet ) {
  905. *phHash = (HCRYPTHASH) pVHash;
  906. return TRUE;
  907. }
  908. if (pVHash)
  909. LocalFree(pVHash);
  910. __try {
  911. *phHash = 0;
  912. } __except(EXCEPTION_EXECUTE_HANDLER) {
  913. ; // gulp
  914. }
  915. return FALSE;
  916. }
  917. /*
  918. - CryptDuplicateHash
  919. -
  920. * Purpose:
  921. * Duplicate a cryptographic hash
  922. *
  923. *
  924. * Parameters:
  925. * IN hHash - Handle to the hash to be duplicated
  926. * IN pdwReserved - Reserved for later use
  927. * IN dwFlags - Flags values
  928. * OUT phHash - Handle to the new duplicate hash
  929. *
  930. * Returns:
  931. */
  932. BOOL
  933. WINAPI SCryptDuplicateHash(
  934. IN HCRYPTHASH hHash,
  935. IN DWORD *pdwReserved,
  936. IN DWORD dwFlags,
  937. OUT HCRYPTHASH * phHash
  938. )
  939. {
  940. PVHashStruc pVHash = (PVHashStruc) hHash;
  941. PVTableStruc pVTable;
  942. PVHashStruc pVNewHash;
  943. BOOL fCritSec = FALSE;
  944. BOOL fRet = FALSE;
  945. __try {
  946. *phHash = 0;
  947. pVTable = pVHash->pVTable;
  948. pVNewHash = BuildVHash(pVTable);
  949. if( pVNewHash == NULL ) {
  950. return FALSE;
  951. }
  952. EnterProviderCritSec(pVTable);
  953. fCritSec = TRUE;
  954. fRet = CPDuplicateHash(
  955. pVTable->hProv,
  956. pVHash->hHash,
  957. pdwReserved,
  958. dwFlags,
  959. &pVNewHash->hHash
  960. );
  961. } __except (EXCEPTION_EXECUTE_HANDLER) {
  962. fRet = FALSE;
  963. ASSERT( fRet );
  964. }
  965. if( fCritSec ) {
  966. LeaveProviderCritSec(pVTable);
  967. }
  968. if( fRet ) {
  969. *phHash = (HCRYPTHASH) pVNewHash;
  970. return TRUE;
  971. }
  972. if (pVNewHash)
  973. LocalFree(pVNewHash);
  974. __try {
  975. *phHash = 0;
  976. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  977. ; // gulp
  978. }
  979. return FALSE;
  980. }
  981. /*
  982. - CryptHashData
  983. -
  984. * Purpose:
  985. * Compute the cryptograghic hash on a stream of data
  986. *
  987. *
  988. * Parameters:
  989. * IN hHash - Handle to hash object
  990. * IN pbData - Pointer to data to be hashed
  991. * IN dwDataLen - Length of the data to be hashed
  992. * IN dwFlags - Flags values
  993. *
  994. *
  995. * Returns:
  996. */
  997. BOOL
  998. WINAPI SCryptHashData(IN HCRYPTHASH hHash,
  999. IN CONST BYTE *pbData,
  1000. IN DWORD dwDataLen,
  1001. IN DWORD dwFlags)
  1002. {
  1003. PVHashStruc pVHash = (PVHashStruc) hHash;
  1004. PVTableStruc pVTable;
  1005. BOOL fCritSec = FALSE;
  1006. BOOL fRet = FALSE;
  1007. __try {
  1008. pVTable = pVHash->pVTable;
  1009. EnterProviderCritSec(pVTable);
  1010. fCritSec = TRUE;
  1011. fRet = CPHashData(
  1012. pVTable->hProv,
  1013. pVHash->hHash,
  1014. pbData,
  1015. dwDataLen,
  1016. dwFlags
  1017. );
  1018. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  1019. fRet = FALSE;
  1020. ASSERT( fRet );
  1021. }
  1022. if( fCritSec ) {
  1023. LeaveProviderCritSec(pVTable);
  1024. }
  1025. return fRet;
  1026. }
  1027. /*
  1028. - CryptHashSessionKey
  1029. -
  1030. * Purpose:
  1031. * Compute the cryptograghic hash on a key object
  1032. *
  1033. *
  1034. * Parameters:
  1035. * IN hHash - Handle to hash object
  1036. * IN hKey - Handle to a key object
  1037. * IN dwFlags - Flags values
  1038. *
  1039. * Returns:
  1040. * CRYPT_FAILED
  1041. * CRYPT_SUCCEED
  1042. */
  1043. BOOL
  1044. WINAPI SCryptHashSessionKey(IN HCRYPTHASH hHash,
  1045. IN HCRYPTKEY hKey,
  1046. IN DWORD dwFlags)
  1047. {
  1048. PVHashStruc pVHash = (PVHashStruc) hHash;
  1049. PVTableStruc pVTable;
  1050. PVKeyStruc pVKey = (PVKeyStruc) hKey;
  1051. BOOL fCritSec = FALSE;
  1052. BOOL fRet = FALSE;
  1053. __try {
  1054. pVTable = pVHash->pVTable;
  1055. if (pVKey->pVTable != pVTable)
  1056. {
  1057. SetLastError(ERROR_INVALID_PARAMETER);
  1058. return FALSE;
  1059. }
  1060. EnterProviderCritSec(pVTable);
  1061. fCritSec = TRUE;
  1062. fRet = CPHashSessionKey(
  1063. pVTable->hProv,
  1064. pVHash->hHash,
  1065. pVKey->hKey,
  1066. dwFlags
  1067. );
  1068. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  1069. fRet = FALSE;
  1070. ASSERT( fRet );
  1071. }
  1072. if( fCritSec ) {
  1073. LeaveProviderCritSec(pVTable);
  1074. }
  1075. return fRet;
  1076. }
  1077. /*
  1078. - CryptDestoyHash
  1079. -
  1080. * Purpose:
  1081. * Destory the hash object
  1082. *
  1083. *
  1084. * Parameters:
  1085. * IN hHash - Handle to hash object
  1086. *
  1087. * Returns:
  1088. */
  1089. BOOL
  1090. WINAPI SCryptDestroyHash(IN HCRYPTHASH hHash)
  1091. {
  1092. PVHashStruc pVHash = (PVHashStruc) hHash;
  1093. PVTableStruc pVTable;
  1094. BOOL fCritSec = FALSE;
  1095. BOOL fRet = FALSE;
  1096. __try {
  1097. pVTable = pVHash->pVTable;
  1098. EnterProviderCritSec(pVTable);
  1099. fCritSec = TRUE;
  1100. fRet = CPDestroyHash(pVTable->hProv, pVHash->hHash);
  1101. } __except(EXCEPTION_EXECUTE_HANDLER) {
  1102. fRet = FALSE;
  1103. ASSERT( fRet );
  1104. }
  1105. if( fCritSec ) {
  1106. LeaveProviderCritSec(pVTable);
  1107. }
  1108. LocalFree(pVHash);
  1109. return fRet;
  1110. }
  1111. /*
  1112. - CryptSignHashW
  1113. -
  1114. * Purpose:
  1115. * Create a digital signature from a hash
  1116. *
  1117. *
  1118. * Parameters:
  1119. * IN hHash - Handle to hash object
  1120. * IN dwKeySpec - Key pair that is used to sign with
  1121. * algorithm to be used
  1122. * IN sDescription - Description of data to be signed
  1123. * IN dwFlags - Flags values
  1124. * OUT pbSignture - Pointer to signature data
  1125. * OUT pdwSigLen - Pointer to the len of the signature data
  1126. *
  1127. * Returns:
  1128. */
  1129. BOOL
  1130. WINAPI SCryptSignHashW(IN HCRYPTHASH hHash,
  1131. IN DWORD dwKeySpec,
  1132. IN LPCWSTR sDescription,
  1133. IN DWORD dwFlags,
  1134. OUT BYTE *pbSignature,
  1135. OUT DWORD *pdwSigLen)
  1136. {
  1137. SetLastError(ERROR_NOT_SUPPORTED);
  1138. return FALSE;
  1139. }
  1140. BOOL
  1141. WINAPI SCryptSignHashA(IN HCRYPTHASH hHash,
  1142. IN DWORD dwKeySpec,
  1143. IN LPCSTR sDescription,
  1144. IN DWORD dwFlags,
  1145. OUT BYTE *pbSignature,
  1146. OUT DWORD *pdwSigLen)
  1147. {
  1148. PVHashStruc pVHash = (PVHashStruc) hHash;
  1149. PVTableStruc pVTable;
  1150. BOOL fCritSec = FALSE;
  1151. BOOL fRet = FALSE;
  1152. __try {
  1153. pVTable = pVHash->pVTable;
  1154. EnterProviderCritSec(pVTable);
  1155. fCritSec = TRUE;
  1156. fRet = CPSignHash(
  1157. pVTable->hProv,
  1158. pVHash->hHash,
  1159. dwKeySpec,
  1160. NULL,
  1161. dwFlags,
  1162. pbSignature,
  1163. pdwSigLen
  1164. );
  1165. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  1166. fRet = FALSE;
  1167. ASSERT( fRet );
  1168. }
  1169. if( fCritSec ) {
  1170. LeaveProviderCritSec(pVTable);
  1171. }
  1172. return fRet;
  1173. }
  1174. /*
  1175. - CryptVerifySignatureW
  1176. -
  1177. * Purpose:
  1178. * Used to verify a signature against a hash object
  1179. *
  1180. *
  1181. * Parameters:
  1182. * IN hHash - Handle to hash object
  1183. * IN pbSignture - Pointer to signature data
  1184. * IN dwSigLen - Length of the signature data
  1185. * IN hPubKey - Handle to the public key for verifying
  1186. * the signature
  1187. * IN sDescription - String describing the signed data
  1188. * IN dwFlags - Flags values
  1189. *
  1190. * Returns:
  1191. */
  1192. BOOL
  1193. WINAPI SCryptVerifySignatureW(IN HCRYPTHASH hHash,
  1194. IN CONST BYTE *pbSignature,
  1195. IN DWORD dwSigLen,
  1196. IN HCRYPTKEY hPubKey,
  1197. IN LPCWSTR sDescription,
  1198. IN DWORD dwFlags)
  1199. {
  1200. SetLastError(ERROR_NOT_SUPPORTED);
  1201. return FALSE;
  1202. }
  1203. BOOL
  1204. WINAPI SCryptVerifySignatureA(IN HCRYPTHASH hHash,
  1205. IN CONST BYTE *pbSignature,
  1206. IN DWORD dwSigLen,
  1207. IN HCRYPTKEY hPubKey,
  1208. IN LPCSTR sDescription,
  1209. IN DWORD dwFlags)
  1210. {
  1211. PVHashStruc pVHash = (PVHashStruc) hHash;
  1212. PVTableStruc pVTable;
  1213. PVKeyStruc pVPubKey = (PVKeyStruc) hPubKey;
  1214. BOOL fCritSec = FALSE;
  1215. BOOL fRet = FALSE;
  1216. __try {
  1217. pVTable = pVHash->pVTable;
  1218. if (pVPubKey && pVPubKey->pVTable != pVTable)
  1219. {
  1220. SetLastError(ERROR_INVALID_PARAMETER);
  1221. return FALSE;
  1222. }
  1223. EnterProviderCritSec(pVTable);
  1224. fCritSec = TRUE;
  1225. fRet = CPVerifySignature(
  1226. pVTable->hProv,
  1227. pVHash->hHash,
  1228. pbSignature,
  1229. dwSigLen,
  1230. (pVPubKey == NULL ? 0 : pVPubKey->hKey),
  1231. NULL,
  1232. dwFlags
  1233. );
  1234. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  1235. fRet = FALSE;
  1236. ASSERT( fRet );
  1237. }
  1238. if( fCritSec ) {
  1239. LeaveProviderCritSec(pVTable);
  1240. }
  1241. return fRet;
  1242. }
  1243. /*
  1244. - CryptSetProvParam
  1245. -
  1246. * Purpose:
  1247. * Allows applications to customize various aspects of the
  1248. * operations of a provider
  1249. *
  1250. * Parameters:
  1251. * IN hProv - Handle to a provider
  1252. * IN dwParam - Parameter number
  1253. * IN pbData - Pointer to data
  1254. * IN dwFlags - Flags values
  1255. *
  1256. * Returns:
  1257. */
  1258. BOOL
  1259. WINAPI SCryptSetProvParam(IN HCRYPTPROV hProv,
  1260. IN DWORD dwParam,
  1261. IN BYTE *pbData,
  1262. IN DWORD dwFlags)
  1263. {
  1264. PVTableStruc pVTable = (PVTableStruc) hProv;
  1265. BOOL fCritSec = FALSE;
  1266. BOOL fRet = FALSE;
  1267. __try {
  1268. EnterProviderCritSec(pVTable);
  1269. fCritSec = TRUE;
  1270. fRet = CPSetProvParam(pVTable->hProv, dwParam, pbData, dwFlags);
  1271. } __except(EXCEPTION_EXECUTE_HANDLER) {
  1272. fRet = FALSE;
  1273. ASSERT( fRet );
  1274. }
  1275. if( fCritSec ) {
  1276. LeaveProviderCritSec(pVTable);
  1277. }
  1278. return fRet;
  1279. }
  1280. /*
  1281. - CryptGetProvParam
  1282. -
  1283. * Purpose:
  1284. * Allows applications to get various aspects of the
  1285. * operations of a provider
  1286. *
  1287. * Parameters:
  1288. * IN hProv - Handle to a proivder
  1289. * IN dwParam - Parameter number
  1290. * IN pbData - Pointer to data
  1291. * IN pdwDataLen - Length of parameter data
  1292. * IN dwFlags - Flags values
  1293. *
  1294. * Returns:
  1295. */
  1296. BOOL
  1297. WINAPI SCryptGetProvParam(IN HCRYPTPROV hProv,
  1298. IN DWORD dwParam,
  1299. IN BYTE *pbData,
  1300. IN DWORD *pdwDataLen,
  1301. IN DWORD dwFlags)
  1302. {
  1303. PVTableStruc pVTable = (PVTableStruc) hProv;
  1304. BOOL fCritSec = FALSE;
  1305. BOOL fRet = FALSE;
  1306. __try {
  1307. EnterProviderCritSec(pVTable);
  1308. fCritSec = TRUE;
  1309. fRet = CPGetProvParam(
  1310. pVTable->hProv,
  1311. dwParam,
  1312. pbData,
  1313. pdwDataLen,
  1314. dwFlags
  1315. );
  1316. } __except(EXCEPTION_EXECUTE_HANDLER) {
  1317. fRet = FALSE;
  1318. ASSERT( fRet );
  1319. }
  1320. if( fCritSec ) {
  1321. LeaveProviderCritSec(pVTable);
  1322. }
  1323. return fRet;
  1324. }
  1325. /*
  1326. - CryptSetHashParam
  1327. -
  1328. * Purpose:
  1329. * Allows applications to customize various aspects of the
  1330. * operations of a hash
  1331. *
  1332. * Parameters:
  1333. * IN hHash - Handle to a hash
  1334. * IN dwParam - Parameter number
  1335. * IN pbData - Pointer to data
  1336. * IN dwFlags - Flags values
  1337. *
  1338. * Returns:
  1339. */
  1340. BOOL
  1341. WINAPI SCryptSetHashParam(IN HCRYPTHASH hHash,
  1342. IN DWORD dwParam,
  1343. IN BYTE *pbData,
  1344. IN DWORD dwFlags)
  1345. {
  1346. PVHashStruc pVHash = (PVHashStruc) hHash;
  1347. PVTableStruc pVTable;
  1348. BOOL fCritSec = FALSE;
  1349. BOOL fRet = FALSE;
  1350. __try {
  1351. pVTable = pVHash->pVTable;
  1352. EnterProviderCritSec(pVTable);
  1353. fCritSec = TRUE;
  1354. fRet = CPSetHashParam(
  1355. pVTable->hProv,
  1356. pVHash->hHash,
  1357. dwParam,
  1358. pbData,
  1359. dwFlags
  1360. );
  1361. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1362. fRet = FALSE;
  1363. ASSERT( fRet );
  1364. }
  1365. if( fCritSec ) {
  1366. LeaveProviderCritSec(pVTable);
  1367. }
  1368. return fRet;
  1369. }
  1370. /*
  1371. - CryptGetHashParam
  1372. -
  1373. * Purpose:
  1374. * Allows applications to get various aspects of the
  1375. * operations of a hash
  1376. *
  1377. * Parameters:
  1378. * IN hHash - Handle to a hash
  1379. * IN dwParam - Parameter number
  1380. * IN pbData - Pointer to data
  1381. * IN pdwDataLen - Length of parameter data
  1382. * IN dwFlags - Flags values
  1383. *
  1384. * Returns:
  1385. */
  1386. BOOL
  1387. WINAPI SCryptGetHashParam(IN HCRYPTKEY hHash,
  1388. IN DWORD dwParam,
  1389. IN BYTE *pbData,
  1390. IN DWORD *pdwDataLen,
  1391. IN DWORD dwFlags)
  1392. {
  1393. PVHashStruc pVHash = (PVHashStruc) hHash;
  1394. PVTableStruc pVTable;
  1395. BOOL fCritSec = FALSE;
  1396. BOOL fRet = FALSE;
  1397. __try {
  1398. pVTable = pVHash->pVTable;
  1399. EnterProviderCritSec(pVTable);
  1400. fCritSec = TRUE;
  1401. fRet = CPGetHashParam(
  1402. pVTable->hProv,
  1403. pVHash->hHash,
  1404. dwParam,
  1405. pbData,
  1406. pdwDataLen,
  1407. dwFlags
  1408. );
  1409. } __except(EXCEPTION_EXECUTE_HANDLER) {
  1410. fRet = FALSE;
  1411. ASSERT( fRet );
  1412. }
  1413. if( fCritSec ) {
  1414. LeaveProviderCritSec(pVTable);
  1415. }
  1416. return fRet;
  1417. }
  1418. void __inline EnterProviderCritSec(IN PVTableStruc pVTable)
  1419. {
  1420. InterlockedIncrement(&pVTable->Inuse);
  1421. }
  1422. LONG __inline LeaveProviderCritSec(IN PVTableStruc pVTable)
  1423. {
  1424. __try {
  1425. return InterlockedDecrement(&pVTable->Inuse);
  1426. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1427. return -1;
  1428. }
  1429. }
  1430. PVKeyStruc BuildVKey(IN PVTableStruc pVTable)
  1431. {
  1432. PVKeyStruc pVKey;
  1433. pVKey = (PVKeyStruc)LocalAlloc(LMEM_ZEROINIT, sizeof(VKeyStruc));
  1434. if( pVKey == NULL )
  1435. return NULL;
  1436. pVKey->pVTable = pVTable;
  1437. return pVKey;
  1438. }
  1439. PVHashStruc BuildVHash(IN PVTableStruc pVTable)
  1440. {
  1441. PVHashStruc pVHash;
  1442. pVHash = (PVHashStruc)LocalAlloc(LMEM_ZEROINIT, sizeof(VHashStruc));
  1443. if( pVHash == NULL )
  1444. return NULL;
  1445. pVHash->pVTable = pVTable;
  1446. return pVHash;
  1447. }