/* ***************************************************************** *
 * Copyright 1998 International Business Machines Corporation. All   *
 * Rights Reserved.                                                  *
 *                                                                   *
 * Please read this carefully.  Your use of this reference           *
 * implementation of certain of the IETF public-key infrastructure   *
 * specifications ("Software") indicates your acceptance of the      *
 * following.  If you do not agree to the following, do not install  *
 * or use any of the Software.                                       *
 *                                                                   *
 * Permission to use, reproduce, distribute and create derivative    *
 * works from the Software ("Software Derivative Works"), and to     *
 * distribute such Software Derivative Works is hereby granted to    *
 * you by International Business Machines Corporation ("IBM").  This *
 * permission includes a license under the patents of IBM that are   *
 * necessarily infringed by your use of the Software as provided by  *
 * IBM.                                                              *
 *                                                                   *
 * IBM licenses the Software to you on an "AS IS" basis, without     *
 * warranty of any kind.  IBM HEREBY EXPRESSLY DISCLAIMS ALL         *
 * WARRANTIES OR CONDITIONS, EITHER EXPRESS OR IMPLIED, INCLUDING,   *
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OR CONDITIONS OF       *
 * MERCHANTABILITY, NON INFRINGEMENT AND FITNESS FOR A PARTICULAR    *
 * PURPOSE.  You are solely responsible for determining the          *
 * appropriateness of using this Software and assume all risks       *
 * associated with the use of this Software, including but not       *
 * limited to the risks of program errors, damage to or loss of      *
 * data, programs or equipment, and unavailability or interruption   *
 * of operations.                                                    *
 *                                                                   *
 * IBM WILL NOT BE LIABLE FOR ANY DIRECT DAMAGES OR FOR ANY SPECIAL, *
 * INCIDENTAL, OR  INDIRECT DAMAGES OR FOR ANY ECONOMIC              *
 * CONSEQUENTIAL DAMAGES (INCLUDING LOST PROFITS OR SAVINGS), EVEN   *
 * IF IBM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.  IBM  *
 * will not be liable for the loss of, or damage to, your records or *
 * data, or any damages claimed by you based on a third party claim. *
 *                                                                   *
 * IBM wishes to obtain your feedback to assist in improving the     *
 * Software.  You grant IBM a world-wide, royalty-free right to use, *
 * copy, distribute, sublicense and prepare derivative works based   *
 * upon any feedback, including materials, error corrections,        *
 * Software Derivatives, enhancements, suggestions and the like that *
 * you provide to IBM relating to the Software (this does not        *
 * include products for which you charge a royalty and distribute to *
 * IBM under other terms and conditions).                            *
 *                                                                   *
 * You agree to distribute the Software and any Software Derivatives *
 * under a license agreement that: 1) is sufficient to notify all    *
 * licensees of the Software and Software Derivatives that IBM       *
 * assumes no liability for any claim that may arise regarding the   *
 * Software or Software Derivatives, and 2) that disclaims all       *
 * warranties, both express and implied, from IBM regarding the      *
 * Software and Software Derivatives.  (If you include this          *
 * Agreement with any distribution of the Software or Software       *
 * Derivatives you will have met this requirement.)  You agree that  *
 * you will not delete any copyright notices in the Software.        *
 *                                                                   *
 * This Agreement is the exclusive statement of your rights in the   *
 * Software as provided by IBM.   Except for the rights granted to   *
 * you in the second paragraph above, You are not granted any other  *
 * patent rights, including but not limited to the right to make     *
 * combinations of the Software with products that infringe IBM      *
 * patents. You agree to comply with all applicable laws and         *
 * regulations, including all export and import laws and regulation. *
 * This Agreement is governed by the laws of the State of New York.  *
 * This Agreement supersedes all other communications,               *
 * understandings or agreements we may have had prior to this        *
 * Agreement.                                                        *
 * ***************************************************************** */

#include <pkcsprivate.h>

#ifndef STATIC_LINK
#ifdef PKCS11_V20
CK_FUNCTION_LIST        FuncList;
HINSTANCE                       hPkcsModule;

CSSM_RETURN     SetupFuncList(LPCTSTR lpLibFileName)
{
	CK_FUNCTION_LIST_PTR     pFunctionList;
	CK_RV                                    rv;


	if ((hPkcsModule = LoadLibrary(lpLibFileName)) != NULL)
	{
		FuncList.version.major                  = 2;
		FuncList.version.minor                  = 0;
		FuncList.C_Initialize                   = (CK_C_Initialize) GetProcAddress(hPkcsModule, "C_Initialize");        
		FuncList.C_Finalize                             = (CK_C_Finalize) GetProcAddress(hPkcsModule, "C_Finalize");    
		FuncList.C_GetInfo                              = (CK_C_GetInfo) GetProcAddress(hPkcsModule, "C_GetInfo");
		FuncList.C_GetFunctionList              = (CK_C_GetFunctionList) GetProcAddress(hPkcsModule, "C_GetFunctionList");
		FuncList.C_GetSlotList                  = (CK_C_GetSlotList) GetProcAddress(hPkcsModule, "C_GetSlotList");
		FuncList.C_GetSlotInfo                  = (CK_C_GetSlotInfo) GetProcAddress(hPkcsModule, "C_GetSlotInfo");
		FuncList.C_GetTokenInfo                 = (CK_C_GetTokenInfo) GetProcAddress(hPkcsModule, "C_GetTokenInfo");
		FuncList.C_GetMechanismList             = (CK_C_GetMechanismList) GetProcAddress(hPkcsModule, "C_GetMechanismList");
		FuncList.C_GetMechanismInfo             = (CK_C_GetMechanismInfo) GetProcAddress(hPkcsModule, "C_GetMechanismInfo");
		FuncList.C_InitToken                    = (CK_C_InitToken) GetProcAddress(hPkcsModule, "C_InitToken");
		FuncList.C_InitPIN                              = (CK_C_InitPIN) GetProcAddress(hPkcsModule, "C_InitPIN");
		FuncList.C_SetPIN                               = (CK_C_SetPIN) GetProcAddress(hPkcsModule, "C_SetPIN");
		FuncList.C_OpenSession                  = (CK_C_OpenSession) GetProcAddress(hPkcsModule, "C_OpenSession");
		FuncList.C_CloseSession                 = (CK_C_CloseSession) GetProcAddress(hPkcsModule, "C_CloseSession");
		FuncList.C_CloseAllSessions             = (CK_C_CloseAllSessions) GetProcAddress(hPkcsModule, "C_CloseAllSessions");
		FuncList.C_GetSessionInfo               = (CK_C_GetSessionInfo) GetProcAddress(hPkcsModule, "C_GetSessionInfo");
		FuncList.C_GetOperationState    = (CK_C_GetOperationState) GetProcAddress(hPkcsModule, "C_GetOperationState");
		FuncList.C_SetOperationState    = (CK_C_SetOperationState) GetProcAddress(hPkcsModule, "C_SetOperationState");
		FuncList.C_Login                                = (CK_C_Login) GetProcAddress(hPkcsModule, "C_Login");
		FuncList.C_Logout                               = (CK_C_Logout) GetProcAddress(hPkcsModule, "C_Logout");
		FuncList.C_CreateObject                 = (CK_C_CreateObject) GetProcAddress(hPkcsModule, "C_CreateObject");
		FuncList.C_CopyObject                   = (CK_C_CopyObject) GetProcAddress(hPkcsModule, "C_CopyObject");
		FuncList.C_DestroyObject                = (CK_C_DestroyObject) GetProcAddress(hPkcsModule, "C_DestroyObject");  
		FuncList.C_GetObjectSize                = (CK_C_GetObjectSize) GetProcAddress(hPkcsModule, "C_GetObjectSize");
		FuncList.C_GetAttributeValue    = (CK_C_GetAttributeValue) GetProcAddress(hPkcsModule, "C_GetAttributeValue");
		FuncList.C_SetAttributeValue    = (CK_C_SetAttributeValue) GetProcAddress(hPkcsModule, "C_SetAttributeValue");
		FuncList.C_FindObjectsInit              = (CK_C_FindObjectsInit) GetProcAddress(hPkcsModule, "C_FindObjectsInit");
		FuncList.C_FindObjects                  = (CK_C_FindObjects) GetProcAddress(hPkcsModule, "C_FindObjects");
		FuncList.C_FindObjectsFinal             = (CK_C_FindObjectsFinal) GetProcAddress(hPkcsModule, "C_FindObjectsFinal");
		FuncList.C_EncryptInit                  = (CK_C_EncryptInit) GetProcAddress(hPkcsModule, "C_EncryptInit");
		FuncList.C_Encrypt                              = (CK_C_Encrypt) GetProcAddress(hPkcsModule, "C_Encrypt");
		FuncList.C_EncryptUpdate                = (CK_C_EncryptUpdate) GetProcAddress(hPkcsModule, "C_EncryptUpdate");
		FuncList.C_EncryptFinal                 = (CK_C_EncryptFinal) GetProcAddress(hPkcsModule, "C_EncryptFinal");
		FuncList.C_DecryptInit                  = (CK_C_DecryptInit) GetProcAddress(hPkcsModule, "C_DecryptInit");
		FuncList.C_Decrypt                              = (CK_C_Decrypt) GetProcAddress(hPkcsModule, "C_Decrypt");
		FuncList.C_DecryptUpdate                = (CK_C_DecryptUpdate) GetProcAddress(hPkcsModule, "C_DecryptUpdate");
		FuncList.C_DecryptFinal                 = (CK_C_DecryptFinal) GetProcAddress(hPkcsModule, "C_DecryptFinal");
		FuncList.C_DigestInit                   = (CK_C_DigestInit) GetProcAddress(hPkcsModule, "C_DigestInit");
		FuncList.C_Digest                               = (CK_C_Digest) GetProcAddress(hPkcsModule, "C_Digest");
		FuncList.C_DigestUpdate                 = (CK_C_DigestUpdate) GetProcAddress(hPkcsModule, "C_DigestUpdate");
		FuncList.C_DigestKey                    = (CK_C_DigestKey) GetProcAddress(hPkcsModule, "C_DigestKey");
		FuncList.C_DigestFinal                  = (CK_C_DigestFinal) GetProcAddress(hPkcsModule, "C_DigestFinal");
		FuncList.C_SignInit                             = (CK_C_SignInit) GetProcAddress(hPkcsModule, "C_SignInit");
		FuncList.C_Sign                                 = (CK_C_Sign) GetProcAddress(hPkcsModule, "C_Sign");
		FuncList.C_SignUpdate                   = (CK_C_SignUpdate) GetProcAddress(hPkcsModule, "C_SignUpdate");
		FuncList.C_SignFinal                    = (CK_C_SignFinal) GetProcAddress(hPkcsModule, "C_SignFinal");
		FuncList.C_SignRecoverInit              = (CK_C_SignRecoverInit) GetProcAddress(hPkcsModule, "C_SignRecoverInit");
		FuncList.C_SignRecover                  = (CK_C_SignRecover) GetProcAddress(hPkcsModule, "C_SignRecover");
		FuncList.C_VerifyInit                   = (CK_C_VerifyInit) GetProcAddress(hPkcsModule, "C_VerifyInit");
		FuncList.C_Verify                               = (CK_C_Verify) GetProcAddress(hPkcsModule, "C_Verify");
		FuncList.C_VerifyUpdate                 = (CK_C_VerifyUpdate) GetProcAddress(hPkcsModule, "C_VerifyUpdate");
		FuncList.C_VerifyFinal                  = (CK_C_VerifyFinal) GetProcAddress(hPkcsModule, "C_VerifyFinal");
		FuncList.C_VerifyRecoverInit    = (CK_C_VerifyRecoverInit) GetProcAddress(hPkcsModule, "C_VerifyRecoverInit");
		FuncList.C_VerifyRecover                = (CK_C_VerifyRecover) GetProcAddress(hPkcsModule, "C_VerifyRecover");
		FuncList.C_DigestEncryptUpdate  = (CK_C_DigestEncryptUpdate) GetProcAddress(hPkcsModule, "C_DigestEncryptUpdate");
		FuncList.C_DecryptDigestUpdate  = (CK_C_DecryptDigestUpdate) GetProcAddress(hPkcsModule, "C_DecryptDigestUpdate");
		FuncList.C_SignEncryptUpdate    = (CK_C_SignEncryptUpdate) GetProcAddress(hPkcsModule, "C_SignEncryptUpdate");
		FuncList.C_DecryptVerifyUpdate  = (CK_C_DecryptVerifyUpdate) GetProcAddress(hPkcsModule, "C_DecryptVerifyUpdate");
		FuncList.C_GenerateKey                  = (CK_C_GenerateKey) GetProcAddress(hPkcsModule, "C_GenerateKey");
		FuncList.C_GenerateKeyPair              = (CK_C_GenerateKeyPair) GetProcAddress(hPkcsModule, "C_GenerateKeyPair");
		FuncList.C_WrapKey                              = (CK_C_WrapKey) GetProcAddress(hPkcsModule, "C_WrapKey");
		FuncList.C_UnwrapKey                    = (CK_C_UnwrapKey) GetProcAddress(hPkcsModule, "C_UnwrapKey");
		FuncList.C_DeriveKey                    = (CK_C_DeriveKey) GetProcAddress(hPkcsModule, "C_DeriveKey");
		FuncList.C_SeedRandom                   = (CK_C_SeedRandom) GetProcAddress(hPkcsModule, "C_SeedRandom");
		FuncList.C_GenerateRandom               = (CK_C_GenerateRandom) GetProcAddress(hPkcsModule, "C_GenerateRandom");
		FuncList.C_GetFunctionStatus    = (CK_C_GetFunctionStatus) GetProcAddress(hPkcsModule, "C_GetFunctionStatus");
		FuncList.C_CancelFunction               = (CK_C_CancelFunction) GetProcAddress(hPkcsModule, "C_CancelFunction");

		return CSSM_OK;
	}
	else
	{
		return SetErr(GetLastError());
	}
}

CK_RV CK_ENTRY C_Initialize(
	CK_VOID_PTR pReserved)
{
	if (FuncList.C_Initialize == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_Initialize(pReserved);
}

CK_RV CK_ENTRY C_Finalize(
	CK_VOID_PTR pReserved)
{
	if (FuncList.C_Finalize == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_Finalize(pReserved);
}


CK_RV CK_ENTRY C_GetInfo(
	CK_INFO_PTR pInfo)
{
	if (FuncList.C_GetInfo == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GetInfo(pInfo);
}



CK_RV CK_ENTRY C_GetSlotList(
	CK_BBOOL tokenPresent,
	CK_SLOT_ID_PTR pSlotList,
	CK_ULONG_PTR pulCount)
{
	if (FuncList.C_GetSlotList == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GetSlotList(tokenPresent, pSlotList, pulCount);
}



CK_RV CK_ENTRY C_GetSlotInfo(
	CK_SLOT_ID slotID,
	CK_SLOT_INFO_PTR pInfo)
{
	if (FuncList.C_GetSlotInfo == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GetSlotInfo(slotID, pInfo);
}



CK_RV CK_ENTRY C_GetTokenInfo(
	CK_SLOT_ID slotID,
	CK_TOKEN_INFO_PTR pInfo)
{
	if (FuncList.C_GetTokenInfo == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GetTokenInfo(slotID, pInfo);
}



CK_RV CK_ENTRY C_GetMechanismList(
	CK_SLOT_ID slotID,
	CK_MECHANISM_TYPE_PTR pMechanismList,
	CK_ULONG_PTR pulCount)
{
	if (FuncList.C_GetMechanismList == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GetMechanismList(slotID, pMechanismList, pulCount);
}



CK_RV CK_ENTRY C_GetMechanismInfo(
	CK_SLOT_ID slotID,
	CK_MECHANISM_TYPE type,
	CK_MECHANISM_INFO_PTR pInfo)
{
	if (FuncList.C_GetMechanismInfo == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GetMechanismInfo(slotID, type, pInfo);
}



CK_RV CK_ENTRY C_InitToken(
	CK_SLOT_ID slotID,
	CK_CHAR_PTR pPin,
	CK_ULONG ulPinLen,
	CK_CHAR_PTR pLabel)
{
	if (FuncList.C_InitToken == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_InitToken(slotID, pPin, ulPinLen, pLabel);
}



CK_RV CK_ENTRY C_InitPIN(
	CK_SESSION_HANDLE hSession,
	CK_CHAR_PTR pPin,
	CK_ULONG ulPinLen)
{
	if (FuncList.C_InitPIN == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_InitPIN(hSession, pPin, ulPinLen);
}



CK_RV CK_ENTRY C_SetPIN(
	CK_SESSION_HANDLE hSession,
	CK_CHAR_PTR pOldPin,
	CK_ULONG ulOldLen,
	CK_CHAR_PTR pNewPin,
	CK_ULONG ulNewLen)
{
	if (FuncList.C_SetPIN == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_SetPIN(hSession, pOldPin, ulOldLen, pNewPin, ulNewLen);
}



CK_RV CK_ENTRY C_OpenSession(
	CK_SLOT_ID slotID,
	CK_FLAGS flags,
	CK_VOID_PTR pApplication,
	CK_NOTIFY   Notify,
	CK_SESSION_HANDLE_PTR phSession)
{
	if (FuncList.C_OpenSession == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_OpenSession(slotID, flags, pApplication, Notify, phSession);
}



CK_RV CK_ENTRY C_CloseSession(
	CK_SESSION_HANDLE hSession)
{
	if (FuncList.C_CloseSession == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_CloseSession(hSession);
}



CK_RV CK_ENTRY C_CloseAllSessions(
	CK_SLOT_ID slotID)
{
	if (FuncList.C_CloseAllSessions == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_CloseAllSessions(slotID);
}



CK_RV CK_ENTRY C_GetSessionInfo(
	CK_SESSION_HANDLE hSession,
	CK_SESSION_INFO_PTR pInfo)
{
	if (FuncList.C_GetSessionInfo == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GetSessionInfo(hSession, pInfo);
}


CK_RV CK_ENTRY C_GetOperationState(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pOperationState,
	CK_ULONG_PTR pulOperationStateLen)
{
	if (FuncList.C_GetOperationState == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GetOperationState(hSession, pOperationState, pulOperationStateLen);
}


CK_RV CK_ENTRY C_SetOperationState(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pOperationState,
	CK_ULONG ulOperationStateLen,
	CK_OBJECT_HANDLE hEncryptionKey,
	CK_OBJECT_HANDLE hAuthenticationKey)
{
	if (FuncList.C_SetOperationState == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_SetOperationState(hSession, pOperationState, ulOperationStateLen, hEncryptionKey, hAuthenticationKey);
}

CK_RV CK_ENTRY C_Login(
	CK_SESSION_HANDLE hSession,
	CK_USER_TYPE userType,
	CK_CHAR_PTR pPin,
	CK_ULONG ulPinLen)
{
	if (FuncList.C_Login == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_Login(hSession, userType, pPin, ulPinLen);
}



CK_RV CK_ENTRY C_Logout(
	CK_SESSION_HANDLE hSession)
{
	if (FuncList.C_Logout == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_Logout(hSession);
}



CK_RV CK_ENTRY C_CreateObject(
	CK_SESSION_HANDLE hSession,
	CK_ATTRIBUTE_PTR pTemplate,
	CK_ULONG ulCount,
	CK_OBJECT_HANDLE_PTR phObject)
{
	if (FuncList.C_CreateObject == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_CreateObject(hSession, pTemplate, ulCount, phObject);
}



CK_RV CK_ENTRY C_CopyObject(
	CK_SESSION_HANDLE hSession,
	CK_OBJECT_HANDLE hObject,
	CK_ATTRIBUTE_PTR pTemplate,
	CK_ULONG ulCount,
	CK_OBJECT_HANDLE_PTR phNewObject)
{
	if (FuncList.C_CopyObject == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_CopyObject(hSession, hObject, pTemplate, ulCount, phNewObject);
}



CK_RV CK_ENTRY C_DestroyObject(
	CK_SESSION_HANDLE hSession,
	CK_OBJECT_HANDLE hObject)
{
	if (FuncList.C_DestroyObject == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_DestroyObject(hSession, hObject);
}



CK_RV CK_ENTRY C_GetObjectSize(
	CK_SESSION_HANDLE hSession,
	CK_OBJECT_HANDLE hObject,
	CK_ULONG_PTR pulSize)
{
	if (FuncList.C_GetObjectSize == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GetObjectSize(hSession, hObject, pulSize);
}



CK_RV CK_ENTRY C_GetAttributeValue(
	CK_SESSION_HANDLE hSession,
	CK_OBJECT_HANDLE hObject,
	CK_ATTRIBUTE_PTR pTemplate,
	CK_ULONG ulCount)
{
	if (FuncList.C_GetAttributeValue == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GetAttributeValue(hSession, hObject, pTemplate, ulCount);
}



CK_RV CK_ENTRY C_SetAttributeValue(
	CK_SESSION_HANDLE hSession,
	CK_OBJECT_HANDLE hObject,
	CK_ATTRIBUTE_PTR pTemplate,
	CK_ULONG ulCount)
{
	if (FuncList.C_SetAttributeValue == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_SetAttributeValue(hSession, hObject, pTemplate, ulCount);
}



CK_RV CK_ENTRY C_FindObjectsInit(
	CK_SESSION_HANDLE hSession,
	CK_ATTRIBUTE_PTR pTemplate,
	CK_ULONG ulCount)
{
	if (FuncList.C_FindObjectsInit == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_FindObjectsInit(hSession, pTemplate, ulCount);
}



CK_RV CK_ENTRY C_FindObjects(
	CK_SESSION_HANDLE hSession,
	CK_OBJECT_HANDLE_PTR phObject,
	CK_ULONG ulMaxObjectCount,
	CK_ULONG_PTR pulObjectCount)
{
	if (FuncList.C_FindObjects == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_FindObjects(hSession, phObject, ulMaxObjectCount, pulObjectCount);
}



CK_RV CK_ENTRY C_FindObjectsFinal(
	CK_SESSION_HANDLE hSession)
{
	if (FuncList.C_FindObjectsFinal == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_FindObjectsFinal(hSession);
}



CK_RV CK_ENTRY C_EncryptInit(
	CK_SESSION_HANDLE hSession,
	CK_MECHANISM_PTR pMechanism,
	CK_OBJECT_HANDLE hKey)
{
	if (FuncList.C_EncryptInit == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_EncryptInit(hSession, pMechanism, hKey);
}



CK_RV CK_ENTRY C_Encrypt(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pData,
	CK_ULONG ulDataLen,
	CK_BYTE_PTR pEncryptedData,
	CK_ULONG_PTR pulEncryptedDataLen)
{
	if (FuncList.C_Encrypt == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_Encrypt(hSession, pData, ulDataLen, pEncryptedData, pulEncryptedDataLen);
}



CK_RV CK_ENTRY C_EncryptUpdate(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pPart,
	CK_ULONG ulPartLen,
	CK_BYTE_PTR pEncryptedPart,
	CK_ULONG_PTR pulEncryptedPartLen)
{
	if (FuncList.C_EncryptUpdate == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_EncryptUpdate(hSession, pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen);
}



CK_RV CK_ENTRY C_EncryptFinal(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pLastEncryptedPart,
	CK_ULONG_PTR pulEncryptedPartLen)
{
	if (FuncList.C_EncryptFinal == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_EncryptFinal(hSession, pLastEncryptedPart, pulEncryptedPartLen);
}



CK_RV CK_ENTRY C_DecryptInit(
	CK_SESSION_HANDLE hSession,
	CK_MECHANISM_PTR pMechanism,
	CK_OBJECT_HANDLE hKey)
{
	if (FuncList.C_DecryptInit == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_DecryptInit(hSession, pMechanism, hKey);
}



CK_RV CK_ENTRY C_Decrypt(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pEncryptedData,
	CK_ULONG ulEncryptedDataLen,
	CK_BYTE_PTR pData,
	CK_ULONG_PTR pulDataLen)
{
	if (FuncList.C_Decrypt == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_Decrypt(hSession, pEncryptedData, ulEncryptedDataLen, pData, pulDataLen);
}



CK_RV CK_ENTRY C_DecryptUpdate(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pEncryptedPart,
	CK_ULONG ulEncryptedPartLen,
	CK_BYTE_PTR pPart,
	CK_ULONG_PTR pulPartLen)
{
	if (FuncList.C_DecryptUpdate == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_DecryptUpdate(hSession, pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen);
}



CK_RV CK_ENTRY C_DecryptFinal(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pLastPart,
	CK_ULONG_PTR ulLastPartLen)
{
	if (FuncList.C_DecryptFinal == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_DecryptFinal(hSession, pLastPart, ulLastPartLen);
}



CK_RV CK_ENTRY C_DigestInit(
	CK_SESSION_HANDLE hSession,
	CK_MECHANISM_PTR pMechanism)
{
	if (FuncList.C_DigestInit == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_DigestInit(hSession, pMechanism);
}



CK_RV CK_ENTRY C_Digest(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pData,
	CK_ULONG ulDataLen,
	CK_BYTE_PTR pDigest,
	CK_ULONG_PTR pulDigestLen)
{
	if (FuncList.C_Digest == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_Digest(hSession, pData, ulDataLen, pDigest, pulDigestLen);
}



CK_RV CK_ENTRY C_DigestUpdate(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pPart,
	CK_ULONG ulPartLen)
{
	if (FuncList.C_DigestUpdate == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_DigestUpdate(hSession, pPart, ulPartLen);
}


CK_RV CK_ENTRY C_DigestKey(
	CK_SESSION_HANDLE hSession,
	CK_OBJECT_HANDLE hKey)
{
	if (FuncList.C_DigestKey == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_DigestKey(hSession, hKey);
}



CK_RV CK_ENTRY C_DigestFinal(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pDigest,
	CK_ULONG_PTR pulDigestLen)
{
	if (FuncList.C_DigestFinal == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_DigestFinal(hSession, pDigest, pulDigestLen);
}



CK_RV CK_ENTRY C_SignInit(
	CK_SESSION_HANDLE hSession,
	CK_MECHANISM_PTR pMechanism,
	CK_OBJECT_HANDLE hKey)
{
	if (FuncList.C_SignInit == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_SignInit(hSession, pMechanism, hKey);
}



CK_RV CK_ENTRY C_Sign(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pData,
	CK_ULONG ulDataLen,
	CK_BYTE_PTR pSignature,
	CK_ULONG_PTR pulSignatureLen)
{
	if (FuncList.C_Sign == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_Sign(hSession, pData, ulDataLen, pSignature, pulSignatureLen);
}



CK_RV CK_ENTRY C_SignUpdate(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pPart,
	CK_ULONG ulPartLen)
{
	if (FuncList.C_SignUpdate == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_SignUpdate(hSession, pPart, ulPartLen);
}



CK_RV CK_ENTRY C_SignFinal(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pSignature,
	CK_ULONG_PTR pulSignatureLen)
{
	if (FuncList.C_SignFinal == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_SignFinal(hSession, pSignature, pulSignatureLen);
}



CK_RV CK_ENTRY C_SignRecoverInit(
	CK_SESSION_HANDLE hSession,
	CK_MECHANISM_PTR pMechanism,
	CK_OBJECT_HANDLE hKey)
{
	if (FuncList.C_SignRecoverInit == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_SignRecoverInit(hSession, pMechanism, hKey);
}



CK_RV CK_ENTRY C_SignRecover(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pData,
	CK_ULONG ulDataLen,
	CK_BYTE_PTR pSignature,
	CK_ULONG_PTR pulSignatureLen)
{
	if (FuncList.C_SignRecover == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_SignRecover(hSession, pData, ulDataLen, pSignature, pulSignatureLen);
}



CK_RV CK_ENTRY C_VerifyInit(
	CK_SESSION_HANDLE hSession,
	CK_MECHANISM_PTR pMechanism,
	CK_OBJECT_HANDLE hKey)
{
	if (FuncList.C_VerifyInit == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_VerifyInit(hSession, pMechanism, hKey);
}



CK_RV CK_ENTRY C_Verify(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pData,
	CK_ULONG ulDataLen,
	CK_BYTE_PTR pSignature,
	CK_ULONG ulSignatureLen)
{
	if (FuncList.C_Verify == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_Verify(hSession, pData, ulDataLen, pSignature, ulSignatureLen);
}



CK_RV CK_ENTRY C_VerifyUpdate(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pPart,
	CK_ULONG ulPartLen)
{
	if (FuncList.C_VerifyUpdate == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_VerifyUpdate(hSession, pPart, ulPartLen);
}



CK_RV CK_ENTRY C_VerifyFinal(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pSignature,
	CK_ULONG ulSignatureLen)
{
	if (FuncList.C_VerifyFinal == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_VerifyFinal(hSession, pSignature, ulSignatureLen);
}



CK_RV CK_ENTRY C_VerifyRecoverInit(
	CK_SESSION_HANDLE hSession,
	CK_MECHANISM_PTR pMechanism,
	CK_OBJECT_HANDLE hKey)
{
	if (FuncList.C_VerifyRecoverInit == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_VerifyRecoverInit(hSession, pMechanism, hKey);
}



CK_RV CK_ENTRY C_VerifyRecover(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pSignature,
	CK_ULONG ulSignatureLen,
	CK_BYTE_PTR pData,
	CK_ULONG_PTR pulDataLen)
{
	if (FuncList.C_VerifyRecover == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_VerifyRecover(hSession, pSignature, ulSignatureLen, pData, pulDataLen);
}

CK_RV CK_ENTRY C_DigestEncryptUpdate(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pPart,
	CK_ULONG ulPartLen,
	CK_BYTE_PTR pEncryptedPart,
	CK_ULONG_PTR pulEncryptedPartLen)
{
	if (FuncList.C_DigestEncryptUpdate == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_DigestEncryptUpdate(hSession, pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen);
}

CK_RV CK_ENTRY C_DecryptDigestUpdate(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pEncryptedPart,
	CK_ULONG ulEncryptedPartLen,
	CK_BYTE_PTR pPart,
	CK_ULONG_PTR pulPartLen)
{
	if (FuncList.C_DecryptDigestUpdate == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_DecryptDigestUpdate(hSession, pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen);
}

CK_RV CK_ENTRY C_SignEncryptUpdate(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pPart,
	CK_ULONG ulPartLen,
	CK_BYTE_PTR pEncryptedPart,
	CK_ULONG_PTR pulEncryptedPartLen)
{
	if (FuncList.C_SignEncryptUpdate == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_SignEncryptUpdate(hSession, pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen);
}


CK_RV CK_ENTRY C_DecryptVerifyUpdate(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pEncryptedPart,
	CK_ULONG ulEncryptedPartLen,
	CK_BYTE_PTR pPart,
	CK_ULONG_PTR pulPartLen)
{
	if (FuncList.C_DecryptVerifyUpdate == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_DecryptVerifyUpdate(hSession, pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen);
}


CK_RV CK_ENTRY C_GenerateKey(
	CK_SESSION_HANDLE hSession,
	CK_MECHANISM_PTR pMechanism,
	CK_ATTRIBUTE_PTR pTemplate,
	CK_ULONG ulCount,
	CK_OBJECT_HANDLE_PTR phKey)
{
	if (FuncList.C_GenerateKey == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GenerateKey(hSession, pMechanism, pTemplate, ulCount, phKey);
}



CK_RV CK_ENTRY C_GenerateKeyPair(
	CK_SESSION_HANDLE hSession,
	CK_MECHANISM_PTR pMechanism,
	CK_ATTRIBUTE_PTR pPublicKeyTemplate,
	CK_ULONG ulPublicKeyAttributeCount,
	CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
	CK_ULONG ulPrivateKeyAttributeCount,
	CK_OBJECT_HANDLE_PTR phPrivateKey,
	CK_OBJECT_HANDLE_PTR phPublicKey)
{
	if (FuncList.C_GenerateKeyPair == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GenerateKeyPair(hSession, pMechanism, 
										  pPublicKeyTemplate, ulPublicKeyAttributeCount,
										  pPrivateKeyTemplate, ulPrivateKeyAttributeCount, 
										  phPrivateKey, phPublicKey);
}



CK_RV CK_ENTRY C_WrapKey(
	CK_SESSION_HANDLE hSession,
	CK_MECHANISM_PTR pMechanism,
	CK_OBJECT_HANDLE hWrappingKey,
	CK_OBJECT_HANDLE hKey,
	CK_BYTE_PTR pWrappedKey,
	CK_ULONG_PTR pulWrappedKeyLen)
{
	if (FuncList.C_WrapKey == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_WrapKey(hSession, pMechanism, hWrappingKey, hKey, pWrappedKey, pulWrappedKeyLen);
}



CK_RV CK_ENTRY C_UnwrapKey(
	CK_SESSION_HANDLE hSession,
	CK_MECHANISM_PTR pMechanism,
	CK_OBJECT_HANDLE hUnwrappingKey,
	CK_BYTE_PTR pWrappedKey,
	CK_ULONG ulWrappedKeyLen,
	CK_ATTRIBUTE_PTR pTemplate,
	CK_ULONG ulAttributeCount,
	CK_OBJECT_HANDLE_PTR phKey)
{
	if (FuncList.C_UnwrapKey == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_UnwrapKey(hSession, pMechanism, hUnwrappingKey, pWrappedKey,
									ulWrappedKeyLen, pTemplate, ulAttributeCount, phKey);
}



CK_RV CK_ENTRY C_DeriveKey(
	CK_SESSION_HANDLE hSession,
	CK_MECHANISM_PTR pMechanism,
	CK_OBJECT_HANDLE hBaseKey,
	CK_ATTRIBUTE_PTR pTemplate,
	CK_ULONG ulAttributeCount,
	CK_OBJECT_HANDLE_PTR phKey)
{
	if (FuncList.C_DeriveKey == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_DeriveKey(hSession, pMechanism, hBaseKey, pTemplate, ulAttributeCount, phKey);
}



CK_RV CK_ENTRY C_SeedRandom(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pSeed,
	CK_ULONG ulSeedLen)
{
	if (FuncList.C_SeedRandom == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_SeedRandom(hSession, pSeed, ulSeedLen);
}



			     CK_RV CK_ENTRY C_GenerateRandom(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pRandomData,
	CK_ULONG ulRandomLen)
{
	if (FuncList.C_GenerateRandom == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GenerateRandom(hSession, pRandomData, ulRandomLen);
}



CK_RV CK_ENTRY C_GetFunctionStatus(
	CK_SESSION_HANDLE hSession)
{
	if (FuncList.C_GetFunctionStatus == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GetFunctionStatus(hSession);
}



CK_RV CK_ENTRY C_CancelFunction(
	CK_SESSION_HANDLE hSession)
{
	if (FuncList.C_CancelFunction == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_CancelFunction(hSession);
}


#else

/*
	Pkcs11 Version 1.0 Function Mapper
*/

CK_FUNCTION_LIST        FuncList;
HINSTANCE                       hPkcsModule;

CSSM_RETURN     SetupFuncList(LPCTSTR lpLibFileName)
{
	if ((hPkcsModule = LoadLibrary(lpLibFileName)) != NULL)
	{
		FuncList.C_Initialize                   = (CK_C_Initialize) GetProcAddress(hPkcsModule, "C_Initialize");        
		FuncList.C_GetInfo                              = (CK_C_GetInfo) GetProcAddress(hPkcsModule, "C_GetInfo");
		FuncList.C_GetSlotList                  = (CK_C_GetSlotList) GetProcAddress(hPkcsModule, "C_GetSlotList");
		FuncList.C_GetSlotInfo                  = (CK_C_GetSlotInfo) GetProcAddress(hPkcsModule, "C_GetSlotInfo");
		FuncList.C_GetTokenInfo                 = (CK_C_GetTokenInfo) GetProcAddress(hPkcsModule, "C_GetTokenInfo");
		FuncList.C_GetMechanismList             = (CK_C_GetMechanismList) GetProcAddress(hPkcsModule, "C_GetMechanismList");
		FuncList.C_GetMechanismInfo             = (CK_C_GetMechanismInfo) GetProcAddress(hPkcsModule, "C_GetMechanismInfo");
		FuncList.C_InitToken                    = (CK_C_InitToken) GetProcAddress(hPkcsModule, "C_InitToken");
		FuncList.C_InitPIN                              = (CK_C_InitPIN) GetProcAddress(hPkcsModule, "C_InitPIN");
		FuncList.C_SetPIN                               = (CK_C_SetPIN) GetProcAddress(hPkcsModule, "C_SetPIN");
		FuncList.C_OpenSession                  = (CK_C_OpenSession) GetProcAddress(hPkcsModule, "C_OpenSession");
		FuncList.C_CloseSession                 = (CK_C_CloseSession) GetProcAddress(hPkcsModule, "C_CloseSession");
		FuncList.C_CloseAllSessions             = (CK_C_CloseAllSessions) GetProcAddress(hPkcsModule, "C_CloseAllSessions");
		FuncList.C_GetSessionInfo               = (CK_C_GetSessionInfo) GetProcAddress(hPkcsModule, "C_GetSessionInfo");
		FuncList.C_Login                                = (CK_C_Login) GetProcAddress(hPkcsModule, "C_Login");
		FuncList.C_Logout                               = (CK_C_Logout) GetProcAddress(hPkcsModule, "C_Logout");
		FuncList.C_CreateObject                 = (CK_C_CreateObject) GetProcAddress(hPkcsModule, "C_CreateObject");
		FuncList.C_CopyObject                   = (CK_C_CopyObject) GetProcAddress(hPkcsModule, "C_CopyObject");
		FuncList.C_DestroyObject                = (CK_C_DestroyObject) GetProcAddress(hPkcsModule, "C_DestroyObject");  
		FuncList.C_GetObjectSize                = (CK_C_GetObjectSize) GetProcAddress(hPkcsModule, "C_GetObjectSize");
		FuncList.C_GetAttributeValue    = (CK_C_GetAttributeValue) GetProcAddress(hPkcsModule, "C_GetAttributeValue");
		FuncList.C_SetAttributeValue    = (CK_C_SetAttributeValue) GetProcAddress(hPkcsModule, "C_SetAttributeValue");
		FuncList.C_FindObjectsInit              = (CK_C_FindObjectsInit) GetProcAddress(hPkcsModule, "C_FindObjectsInit");
		FuncList.C_FindObjects                  = (CK_C_FindObjects) GetProcAddress(hPkcsModule, "C_FindObjects");
		FuncList.C_FindObjectsFinal             = (CK_C_FindObjectsFinal) GetProcAddress(hPkcsModule, "C_FindObjectsFinal");
		FuncList.C_EncryptInit                  = (CK_C_EncryptInit) GetProcAddress(hPkcsModule, "C_EncryptInit");
		FuncList.C_Encrypt                              = (CK_C_Encrypt) GetProcAddress(hPkcsModule, "C_Encrypt");
		FuncList.C_EncryptUpdate                = (CK_C_EncryptUpdate) GetProcAddress(hPkcsModule, "C_EncryptUpdate");
		FuncList.C_EncryptFinal                 = (CK_C_EncryptFinal) GetProcAddress(hPkcsModule, "C_EncryptFinal");
		FuncList.C_DecryptInit                  = (CK_C_DecryptInit) GetProcAddress(hPkcsModule, "C_DecryptInit");
		FuncList.C_Decrypt                              = (CK_C_Decrypt) GetProcAddress(hPkcsModule, "C_Decrypt");
		FuncList.C_DecryptUpdate                = (CK_C_DecryptUpdate) GetProcAddress(hPkcsModule, "C_DecryptUpdate");
		FuncList.C_DecryptFinal                 = (CK_C_DecryptFinal) GetProcAddress(hPkcsModule, "C_DecryptFinal");
		FuncList.C_DigestInit                   = (CK_C_DigestInit) GetProcAddress(hPkcsModule, "C_DigestInit");
		FuncList.C_Digest                               = (CK_C_Digest) GetProcAddress(hPkcsModule, "C_Digest");
		FuncList.C_DigestUpdate                 = (CK_C_DigestUpdate) GetProcAddress(hPkcsModule, "C_DigestUpdate");
		FuncList.C_DigestFinal                  = (CK_C_DigestFinal) GetProcAddress(hPkcsModule, "C_DigestFinal");
		FuncList.C_SignInit                             = (CK_C_SignInit) GetProcAddress(hPkcsModule, "C_SignInit");
		FuncList.C_Sign                                 = (CK_C_Sign) GetProcAddress(hPkcsModule, "C_Sign");
		FuncList.C_SignUpdate                   = (CK_C_SignUpdate) GetProcAddress(hPkcsModule, "C_SignUpdate");
		FuncList.C_SignFinal                    = (CK_C_SignFinal) GetProcAddress(hPkcsModule, "C_SignFinal");
		FuncList.C_SignRecoverInit              = (CK_C_SignRecoverInit) GetProcAddress(hPkcsModule, "C_SignRecoverInit");
		FuncList.C_SignRecover                  = (CK_C_SignRecover) GetProcAddress(hPkcsModule, "C_SignRecover");
		FuncList.C_VerifyInit                   = (CK_C_VerifyInit) GetProcAddress(hPkcsModule, "C_VerifyInit");
		FuncList.C_Verify                               = (CK_C_Verify) GetProcAddress(hPkcsModule, "C_Verify");
		FuncList.C_VerifyUpdate                 = (CK_C_VerifyUpdate) GetProcAddress(hPkcsModule, "C_VerifyUpdate");
		FuncList.C_VerifyFinal                  = (CK_C_VerifyFinal) GetProcAddress(hPkcsModule, "C_VerifyFinal");
		FuncList.C_VerifyRecoverInit    = (CK_C_VerifyRecoverInit) GetProcAddress(hPkcsModule, "C_VerifyRecoverInit");
		FuncList.C_VerifyRecover                = (CK_C_VerifyRecover) GetProcAddress(hPkcsModule, "C_VerifyRecover");
		FuncList.C_GenerateKey                  = (CK_C_GenerateKey) GetProcAddress(hPkcsModule, "C_GenerateKey");
		FuncList.C_GenerateKeyPair              = (CK_C_GenerateKeyPair) GetProcAddress(hPkcsModule, "C_GenerateKeyPair");
		FuncList.C_WrapKey                              = (CK_C_WrapKey) GetProcAddress(hPkcsModule, "C_WrapKey");
		FuncList.C_UnwrapKey                    = (CK_C_UnwrapKey) GetProcAddress(hPkcsModule, "C_UnwrapKey");
		FuncList.C_DeriveKey                    = (CK_C_DeriveKey) GetProcAddress(hPkcsModule, "C_DeriveKey");
		FuncList.C_SeedRandom                   = (CK_C_SeedRandom) GetProcAddress(hPkcsModule, "C_SeedRandom");
		FuncList.C_GenerateRandom               = (CK_C_GenerateRandom) GetProcAddress(hPkcsModule, "C_GenerateRandom");
		FuncList.C_GetFunctionStatus    = (CK_C_GetFunctionStatus) GetProcAddress(hPkcsModule, "C_GetFunctionStatus");
		FuncList.C_CancelFunction               = (CK_C_CancelFunction) GetProcAddress(hPkcsModule, "C_CancelFunction");
	
		return CSSM_OK;
	}
	else
	{
		return SetErr(GetLastError());
	}
}


CK_RV CK_ENTRY C_Initialize(
	CK_VOID_PTR pReserved)
{
	if (FuncList.C_Initialize == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_Initialize(pReserved);
}



CK_RV CK_ENTRY C_GetInfo(
	CK_INFO_PTR pInfo)
{
	if (FuncList.C_GetInfo == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GetInfo(pInfo);
}



CK_RV CK_ENTRY C_GetSlotList(CK_BBOOL tokenPresent,
	CK_SLOT_ID_PTR pSlotList,
	CK_USHORT_PTR pusCount)
{
	if (FuncList.C_GetSlotList == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GetSlotList(tokenPresent, pSlotList, pusCount);
}



CK_RV CK_ENTRY C_GetSlotInfo(
	CK_SLOT_ID slotID,
	CK_SLOT_INFO_PTR pInfo)
{
	if (FuncList.C_GetSlotInfo == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GetSlotInfo(slotID, pInfo);
}



CK_RV CK_ENTRY C_GetTokenInfo(
	CK_SLOT_ID slotID,
	CK_TOKEN_INFO_PTR pInfo)
{
	if (FuncList.C_GetTokenInfo == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GetTokenInfo(slotID, pInfo);
}



CK_RV CK_ENTRY C_GetMechanismList(
	CK_SLOT_ID slotID,
	CK_MECHANISM_TYPE_PTR pMechanismList,
	CK_USHORT_PTR pusCount)
{
	if (FuncList.C_GetMechanismList == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GetMechanismList(slotID, pMechanismList, pusCount);
}



CK_RV CK_ENTRY C_GetMechanismInfo(
	CK_SLOT_ID slotID,
	CK_MECHANISM_TYPE type,
	CK_MECHANISM_INFO_PTR pInfo)
{
	if (FuncList.C_GetMechanismInfo == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GetMechanismInfo(slotID, type, pInfo);
}



CK_RV CK_ENTRY C_InitToken(
	CK_SLOT_ID slotID,
	CK_CHAR_PTR pPin,
	CK_USHORT usPinLen,
	CK_CHAR_PTR pLabel)
{
	if (FuncList.C_InitToken == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_InitToken(slotID, pPin, usPinLen, pLabel);
}



CK_RV CK_ENTRY C_InitPIN(
	CK_SESSION_HANDLE hSession,
	CK_CHAR_PTR pPin,
	CK_USHORT usPinLen)
{
	if (FuncList.C_InitPIN == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_InitPIN(hSession, pPin, usPinLen);
}



CK_RV CK_ENTRY C_SetPIN(
	CK_SESSION_HANDLE hSession,
	CK_CHAR_PTR pOldPin,
	CK_USHORT usOldLen,
	CK_CHAR_PTR pNewPin,
	CK_USHORT usNewLen)
{
	if (FuncList.C_SetPIN == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_SetPIN(hSession, pOldPin, usOldLen, pNewPin, usNewLen);
}



CK_RV CK_ENTRY C_OpenSession(
	CK_SLOT_ID slotID,
	CK_FLAGS flags,
	CK_VOID_PTR pApplication,
	CK_RV (*Notify)(CK_SESSION_HANDLE hSession,
	   CK_NOTIFICATION event, CK_VOID_PTR pApplication),
	CK_SESSION_HANDLE_PTR phSession)
{
	if (FuncList.C_OpenSession == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_OpenSession(slotID, flags, pApplication, Notify, phSession);
}



CK_RV CK_ENTRY C_CloseSession(
	CK_SESSION_HANDLE hSession)
{
	if (FuncList.C_CloseSession == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_CloseSession(hSession);
}



CK_RV CK_ENTRY C_CloseAllSessions(
	CK_SLOT_ID slotID)
{
	if (FuncList.C_CloseAllSessions == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_CloseAllSessions(slotID);
}



CK_RV CK_ENTRY C_GetSessionInfo(
	CK_SESSION_HANDLE hSession,
	CK_SESSION_INFO_PTR pInfo)
{
	if (FuncList.C_GetSessionInfo == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GetSessionInfo(hSession, pInfo);
}



CK_RV CK_ENTRY C_Login(
	CK_SESSION_HANDLE hSession,
	CK_USER_TYPE userType,
	CK_CHAR_PTR pPin,
	CK_USHORT usPinLen)
{
	if (FuncList.C_Login == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_Login(hSession, userType, pPin, usPinLen);
}



CK_RV CK_ENTRY C_Logout(
	CK_SESSION_HANDLE hSession)
{
	if (FuncList.C_Logout == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_Logout(hSession);
}



CK_RV CK_ENTRY C_CreateObject(
	CK_SESSION_HANDLE hSession,
	CK_ATTRIBUTE_PTR pTemplate,
	CK_USHORT usCount,
	CK_OBJECT_HANDLE_PTR phObject)
{
	if (FuncList.C_CreateObject == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_CreateObject(hSession, pTemplate, usCount, phObject);
}



CK_RV CK_ENTRY C_CopyObject(
	CK_SESSION_HANDLE hSession,
	CK_OBJECT_HANDLE hObject,
	CK_ATTRIBUTE_PTR pTemplate,
	CK_USHORT usCount,
	CK_OBJECT_HANDLE_PTR phNewObject)
{
	if (FuncList.C_CopyObject == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_CopyObject(hSession, hObject, pTemplate, usCount, phNewObject);
}



CK_RV CK_ENTRY C_DestroyObject(
	CK_SESSION_HANDLE hSession,
	CK_OBJECT_HANDLE hObject)
{
	if (FuncList.C_DestroyObject == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_DestroyObject(hSession, hObject);
}



CK_RV CK_ENTRY C_GetObjectSize(
	CK_SESSION_HANDLE hSession,
	CK_OBJECT_HANDLE hObject,
	CK_USHORT_PTR pusSize)
{
	if (FuncList.C_GetObjectSize == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GetObjectSize(hSession, hObject, pusSize);
}



CK_RV CK_ENTRY C_GetAttributeValue(
	CK_SESSION_HANDLE hSession,
	CK_OBJECT_HANDLE hObject,
	CK_ATTRIBUTE_PTR pTemplate,
	CK_USHORT usCount)
{
	if (FuncList.C_GetAttributeValue == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GetAttributeValue(hSession, hObject, pTemplate, usCount);
}



CK_RV CK_ENTRY C_SetAttributeValue(
	CK_SESSION_HANDLE hSession,
	CK_OBJECT_HANDLE hObject,
	CK_ATTRIBUTE_PTR pTemplate,
	CK_USHORT usCount)
{
	if (FuncList.C_SetAttributeValue == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_SetAttributeValue(hSession, hObject, pTemplate, usCount);
}



CK_RV CK_ENTRY C_FindObjectsInit(
	CK_SESSION_HANDLE hSession,
	CK_ATTRIBUTE_PTR pTemplate,
	CK_USHORT usCount)
{
	if (FuncList.C_FindObjectsInit == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_FindObjectsInit(hSession, pTemplate, usCount);
}



CK_RV CK_ENTRY C_FindObjects(
	CK_SESSION_HANDLE hSession,
	CK_OBJECT_HANDLE_PTR phObject,
	CK_USHORT usMaxObjectCount,
	CK_USHORT_PTR pusObjectCount)
{
	if (FuncList.C_FindObjects == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_FindObjects(hSession, phObject, usMaxObjectCount, pusObjectCount);
}



CK_RV CK_ENTRY C_FindObjectsFinal(
	CK_SESSION_HANDLE hSession)
{
	if (FuncList.C_FindObjectsFinal == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_FindObjectsFinal(hSession);
}



CK_RV CK_ENTRY C_EncryptInit(
	CK_SESSION_HANDLE hSession,
	CK_MECHANISM_PTR pMechanism,
	CK_OBJECT_HANDLE hKey)
{
	if (FuncList.C_EncryptInit == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_EncryptInit(hSession, pMechanism, hKey);
}



CK_RV CK_ENTRY C_Encrypt(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pData,
	CK_USHORT usDataLen,
	CK_BYTE_PTR pEncryptedData,
	CK_USHORT_PTR pusEncryptedDataLen)
{
	if (FuncList.C_Encrypt == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_Encrypt(hSession, pData, usDataLen, pEncryptedData, pusEncryptedDataLen);
}



CK_RV CK_ENTRY C_EncryptUpdate(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pPart,
	CK_USHORT usPartLen,
	CK_BYTE_PTR pEncryptedPart,
	CK_USHORT_PTR pusEncryptedPartLen)
{
	if (FuncList.C_EncryptUpdate == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_EncryptUpdate(hSession, pPart, usPartLen, pEncryptedPart, pusEncryptedPartLen);
}



CK_RV CK_ENTRY C_EncryptFinal(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pLastEncryptedPart,
	CK_USHORT_PTR pusEncryptedPartLen)
{
	if (FuncList.C_EncryptFinal == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_EncryptFinal(hSession, pLastEncryptedPart, pusEncryptedPartLen);
}



CK_RV CK_ENTRY C_DecryptInit(
	CK_SESSION_HANDLE hSession,
	CK_MECHANISM_PTR pMechanism,
	CK_OBJECT_HANDLE hKey)
{
	if (FuncList.C_DecryptInit == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_DecryptInit(hSession, pMechanism, hKey);
}



CK_RV CK_ENTRY C_Decrypt(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pEncryptedData,
	CK_USHORT usEncryptedDataLen,
	CK_BYTE_PTR pData,
	CK_USHORT_PTR pusDataLen)
{
	if (FuncList.C_Decrypt == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_Decrypt(hSession, pEncryptedData, usEncryptedDataLen, pData, pusDataLen);
}



CK_RV CK_ENTRY C_DecryptUpdate(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pEncryptedPart,
	CK_USHORT usEncryptedPartLen,
	CK_BYTE_PTR pPart,
	CK_USHORT_PTR pusPartLen)
{
	if (FuncList.C_DecryptUpdate == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_DecryptUpdate(hSession, pEncryptedPart, usEncryptedPartLen, pPart, pusPartLen);
}



CK_RV CK_ENTRY C_DecryptFinal(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pLastPart,
	CK_USHORT_PTR usLastPartLen)
{
	if (FuncList.C_DecryptFinal == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_DecryptFinal(hSession, pLastPart, usLastPartLen);
}



CK_RV CK_ENTRY C_DigestInit(
	CK_SESSION_HANDLE hSession,
	CK_MECHANISM_PTR pMechanism)
{
	if (FuncList.C_DigestInit == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_DigestInit(hSession, pMechanism);
}



CK_RV CK_ENTRY C_Digest(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pData,
	CK_USHORT usDataLen,
	CK_BYTE_PTR pDigest,
	CK_USHORT_PTR pusDigestLen)
{
	if (FuncList.C_Digest == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_Digest(hSession, pData, usDataLen, pDigest, pusDigestLen);
}



CK_RV CK_ENTRY C_DigestUpdate(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pPart,
	CK_USHORT usPartLen)
{
	if (FuncList.C_DigestUpdate == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_DigestUpdate(hSession, pPart, usPartLen);
}



CK_RV CK_ENTRY C_DigestFinal(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pDigest,
	CK_USHORT_PTR pusDigestLen)
{
	if (FuncList.C_DigestFinal == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_DigestFinal(hSession, pDigest, pusDigestLen);
}



CK_RV CK_ENTRY C_SignInit(
	CK_SESSION_HANDLE hSession,
	CK_MECHANISM_PTR pMechanism,
	CK_OBJECT_HANDLE hKey)
{
	if (FuncList.C_SignInit == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_SignInit(hSession, pMechanism, hKey);
}



CK_RV CK_ENTRY C_Sign(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pData,
	CK_USHORT usDataLen,
	CK_BYTE_PTR pSignature,
	CK_USHORT_PTR pusSignatureLen)
{
	if (FuncList.C_Sign == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_Sign(hSession, pData, usDataLen, pSignature, pusSignatureLen);
}



CK_RV CK_ENTRY C_SignUpdate(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pPart,
	CK_USHORT usPartLen)
{
	if (FuncList.C_SignUpdate == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_SignUpdate(hSession, pPart, usPartLen);
}



CK_RV CK_ENTRY C_SignFinal(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pSignature,
	CK_USHORT_PTR pusSignatureLen)
{
	if (FuncList.C_SignFinal == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_SignFinal(hSession, pSignature, pusSignatureLen);
}



CK_RV CK_ENTRY C_SignRecoverInit(
	CK_SESSION_HANDLE hSession,
	CK_MECHANISM_PTR pMechanism,
	CK_OBJECT_HANDLE hKey)
{
	if (FuncList.C_SignRecoverInit == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_SignRecoverInit(hSession, pMechanism, hKey);
}



CK_RV CK_ENTRY C_SignRecover(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pData,
	CK_USHORT usDataLen,
	CK_BYTE_PTR pSignature,
	CK_USHORT_PTR pusSignatureLen)
{
	if (FuncList.C_SignRecover == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_SignRecover(hSession, pData, usDataLen, pSignature, pusSignatureLen);
}



CK_RV CK_ENTRY C_VerifyInit(
	CK_SESSION_HANDLE hSession,
	CK_MECHANISM_PTR pMechanism,
	CK_OBJECT_HANDLE hKey)
{
	if (FuncList.C_VerifyInit == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_VerifyInit(hSession, pMechanism, hKey);
}



CK_RV CK_ENTRY C_Verify(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pData,
	CK_USHORT usDataLen,
	CK_BYTE_PTR pSignature,
	CK_USHORT usSignatureLen)
{
	if (FuncList.C_Verify == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_Verify(hSession, pData, usDataLen, pSignature, usSignatureLen);
}



CK_RV CK_ENTRY C_VerifyUpdate(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pPart,
	CK_USHORT usPartLen)
{
	if (FuncList.C_VerifyUpdate == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_VerifyUpdate(hSession, pPart, usPartLen);
}



CK_RV CK_ENTRY C_VerifyFinal(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pSignature,
	CK_USHORT usSignatureLen)
{
	if (FuncList.C_VerifyFinal == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_VerifyFinal(hSession, pSignature, usSignatureLen);
}



CK_RV CK_ENTRY C_VerifyRecoverInit(
	CK_SESSION_HANDLE hSession,
	CK_MECHANISM_PTR pMechanism,
	CK_OBJECT_HANDLE hKey)
{
	if (FuncList.C_VerifyRecoverInit == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_VerifyRecoverInit(hSession, pMechanism, hKey);
}



CK_RV CK_ENTRY C_VerifyRecover(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pSignature,
	CK_USHORT usSignatureLen,
	CK_BYTE_PTR pData,
	CK_USHORT_PTR pusDataLen)
{
	if (FuncList.C_VerifyRecover == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_VerifyRecover(hSession, pSignature, usSignatureLen, pData, pusDataLen);
}



CK_RV CK_ENTRY C_GenerateKey(
	CK_SESSION_HANDLE hSession,
	CK_MECHANISM_PTR pMechanism,
	CK_ATTRIBUTE_PTR pTemplate,
	CK_USHORT usCount,
	CK_OBJECT_HANDLE_PTR phKey)
{
	if (FuncList.C_GenerateKey == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GenerateKey(hSession, pMechanism, pTemplate, usCount, phKey);
}



CK_RV CK_ENTRY C_GenerateKeyPair(
	CK_SESSION_HANDLE hSession,
	CK_MECHANISM_PTR pMechanism,
	CK_ATTRIBUTE_PTR pPublicKeyTemplate,
	CK_USHORT usPublicKeyAttributeCount,
	CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
	CK_USHORT usPrivateKeyAttributeCount,
	CK_OBJECT_HANDLE_PTR phPrivateKey,
	CK_OBJECT_HANDLE_PTR phPublicKey)
{
	if (FuncList.C_GenerateKeyPair == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GenerateKeyPair(hSession, pMechanism, 
										  pPublicKeyTemplate, usPublicKeyAttributeCount,
										  pPrivateKeyTemplate, usPrivateKeyAttributeCount, 
										  phPrivateKey, phPublicKey);
}



CK_RV CK_ENTRY C_WrapKey(
	CK_SESSION_HANDLE hSession,
	CK_MECHANISM_PTR pMechanism,
	CK_OBJECT_HANDLE hWrappingKey,
	CK_OBJECT_HANDLE hKey,
	CK_BYTE_PTR pWrappedKey,
	CK_USHORT_PTR pusWrappedKeyLen)
{
	if (FuncList.C_WrapKey == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_WrapKey(hSession, pMechanism, hWrappingKey, hKey, pWrappedKey, pusWrappedKeyLen);
}



CK_RV CK_ENTRY C_UnwrapKey(
	CK_SESSION_HANDLE hSession,
	CK_MECHANISM_PTR pMechanism,
	CK_OBJECT_HANDLE hUnwrappingKey,
	CK_BYTE_PTR pWrappedKey,
	CK_USHORT usWrappedKeyLen,
	CK_ATTRIBUTE_PTR pTemplate,
	CK_USHORT usAttributeCount,
	CK_OBJECT_HANDLE_PTR phKey)
{
	if (FuncList.C_UnwrapKey == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_UnwrapKey(hSession, pMechanism, hUnwrappingKey, pWrappedKey,
									usWrappedKeyLen, pTemplate, usAttributeCount, phKey);
}



CK_RV CK_ENTRY C_DeriveKey(
	CK_SESSION_HANDLE hSession,
	CK_MECHANISM_PTR pMechanism,
	CK_OBJECT_HANDLE hBaseKey,
	CK_ATTRIBUTE_PTR pTemplate,
	CK_USHORT usAttributeCount,
	CK_OBJECT_HANDLE_PTR phKey)
{
	if (FuncList.C_DeriveKey == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_DeriveKey(hSession, pMechanism, hBaseKey, pTemplate, usAttributeCount, phKey);
}



CK_RV CK_ENTRY C_SeedRandom(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pSeed,
	CK_USHORT usSeedLen)
{
	if (FuncList.C_SeedRandom == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_SeedRandom(hSession, pSeed, usSeedLen);
}



CK_RV CK_ENTRY C_GenerateRandom(
	CK_SESSION_HANDLE hSession,
	CK_BYTE_PTR pRandomData,
	CK_USHORT usRandomLen)
{
	if (FuncList.C_GenerateRandom == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GenerateRandom(hSession, pRandomData, usRandomLen);
}



CK_RV CK_ENTRY C_GetFunctionStatus(
	CK_SESSION_HANDLE hSession)
{
	if (FuncList.C_GetFunctionStatus == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_GetFunctionStatus(hSession);
}



CK_RV CK_ENTRY C_CancelFunction(
	CK_SESSION_HANDLE hSession)
{
	if (FuncList.C_CancelFunction == NULL)
		return CKR_FUNCTION_NOT_SUPPORTED;
	else
		return FuncList.C_CancelFunction(hSession);
}



#endif
#endif
