Back to index

lightning-sunbird  0.9+nobinonly
slot.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 #ifdef DEBUG
00038 static const char CVS_ID[] = "@(#) $RCSfile: slot.c,v $ $Revision: 1.6 $ $Date: 2005/01/20 02:25:45 $";
00039 #endif /* DEBUG */
00040 
00041 /*
00042  * slot.c
00043  *
00044  * This file implements the NSSCKFWSlot type and methods.
00045  */
00046 
00047 #ifndef CK_T
00048 #include "ck.h"
00049 #endif /* CK_T */
00050 
00051 /*
00052  * NSSCKFWSlot
00053  *
00054  *  -- create/destroy --
00055  *  nssCKFWSlot_Create
00056  *  nssCKFWSlot_Destroy
00057  *
00058  *  -- public accessors --
00059  *  NSSCKFWSlot_GetMDSlot
00060  *  NSSCKFWSlot_GetFWInstance
00061  *  NSSCKFWSlot_GetMDInstance
00062  *
00063  *  -- implement public accessors --
00064  *  nssCKFWSlot_GetMDSlot
00065  *  nssCKFWSlot_GetFWInstance
00066  *  nssCKFWSlot_GetMDInstance
00067  *
00068  *  -- private accessors --
00069  *  nssCKFWSlot_GetSlotID
00070  *  nssCKFWSlot_ClearToken
00071  *
00072  *  -- module fronts --
00073  *  nssCKFWSlot_GetSlotDescription
00074  *  nssCKFWSlot_GetManufacturerID
00075  *  nssCKFWSlot_GetTokenPresent
00076  *  nssCKFWSlot_GetRemovableDevice
00077  *  nssCKFWSlot_GetHardwareSlot
00078  *  nssCKFWSlot_GetHardwareVersion
00079  *  nssCKFWSlot_GetFirmwareVersion
00080  *  nssCKFWSlot_InitToken
00081  *  nssCKFWSlot_GetToken
00082  */
00083 
00084 struct NSSCKFWSlotStr {
00085   NSSCKFWMutex *mutex;
00086   NSSCKMDSlot *mdSlot;
00087   NSSCKFWInstance *fwInstance;
00088   NSSCKMDInstance *mdInstance;
00089   CK_SLOT_ID slotID;
00090 
00091   /*
00092    * Everything above is set at creation time, and then not modified.
00093    * The invariants the mutex protects are:
00094    *
00095    * 1) Each of the cached descriptions (versions, etc.) are in an
00096    *    internally consistant state.
00097    *
00098    * 2) The fwToken points to the token currently in the slot, and
00099    *    it is in a consistant state.
00100    *
00101    * Note that the calls accessing the cached descriptions will
00102    * call the NSSCKMDSlot methods with the mutex locked.  Those
00103    * methods may then call the public NSSCKFWSlot routines.  Those
00104    * public routines only access the constant data above, so there's
00105    * no problem.  But be careful if you add to this object; mutexes
00106    * are in general not reentrant, so don't create deadlock situations.
00107    */
00108 
00109   NSSUTF8 *slotDescription;
00110   NSSUTF8 *manufacturerID;
00111   CK_VERSION hardwareVersion;
00112   CK_VERSION firmwareVersion;
00113   NSSCKFWToken *fwToken;
00114 };
00115 
00116 #ifdef DEBUG
00117 /*
00118  * But first, the pointer-tracking stuff.
00119  *
00120  * NOTE: the pointer-tracking support in NSS/base currently relies
00121  * upon NSPR's CallOnce support.  That, however, relies upon NSPR's
00122  * locking, which is tied into the runtime.  We need a pointer-tracker
00123  * implementation that uses the locks supplied through C_Initialize.
00124  * That support, however, can be filled in later.  So for now, I'll
00125  * just do this routines as no-ops.
00126  */
00127 
00128 static CK_RV
00129 slot_add_pointer
00130 (
00131   const NSSCKFWSlot *fwSlot
00132 )
00133 {
00134   return CKR_OK;
00135 }
00136 
00137 static CK_RV
00138 slot_remove_pointer
00139 (
00140   const NSSCKFWSlot *fwSlot
00141 )
00142 {
00143   return CKR_OK;
00144 }
00145 
00146 NSS_IMPLEMENT CK_RV
00147 nssCKFWSlot_verifyPointer
00148 (
00149   const NSSCKFWSlot *fwSlot
00150 )
00151 {
00152   return CKR_OK;
00153 }
00154 
00155 #endif /* DEBUG */
00156 
00157 /*
00158  * nssCKFWSlot_Create
00159  *
00160  */
00161 NSS_IMPLEMENT NSSCKFWSlot *
00162 nssCKFWSlot_Create
00163 (
00164   NSSCKFWInstance *fwInstance,
00165   NSSCKMDSlot *mdSlot,
00166   CK_SLOT_ID slotID,
00167   CK_RV *pError
00168 )
00169 {
00170   NSSCKFWSlot *fwSlot;
00171   NSSCKMDInstance *mdInstance;
00172   NSSArena *arena;
00173 
00174 #ifdef NSSDEBUG
00175   if( (CK_RV *)NULL == pError ) {
00176     return (NSSCKFWSlot *)NULL;
00177   }
00178 
00179   *pError = nssCKFWInstance_verifyPointer(fwInstance);
00180   if( CKR_OK != *pError ) {
00181     return (NSSCKFWSlot *)NULL;
00182   }
00183 #endif /* NSSDEBUG */
00184 
00185   mdInstance = nssCKFWInstance_GetMDInstance(fwInstance);
00186   if( (NSSCKMDInstance *)NULL == mdInstance ) {
00187     *pError = CKR_GENERAL_ERROR;
00188     return (NSSCKFWSlot *)NULL;
00189   }
00190 
00191   arena = nssCKFWInstance_GetArena(fwInstance, pError);
00192   if( (NSSArena *)NULL == arena ) {
00193     if( CKR_OK == *pError ) {
00194       *pError = CKR_GENERAL_ERROR;
00195     }
00196   }
00197 
00198   fwSlot = nss_ZNEW(arena, NSSCKFWSlot);
00199   if( (NSSCKFWSlot *)NULL == fwSlot ) {
00200     *pError = CKR_HOST_MEMORY;
00201     return (NSSCKFWSlot *)NULL;
00202   }
00203 
00204   fwSlot->mdSlot = mdSlot;
00205   fwSlot->fwInstance = fwInstance;
00206   fwSlot->mdInstance = mdInstance;
00207   fwSlot->slotID = slotID;
00208 
00209   fwSlot->mutex = nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
00210   if( (NSSCKFWMutex *)NULL == fwSlot->mutex ) {
00211     if( CKR_OK == *pError ) {
00212       *pError = CKR_GENERAL_ERROR;
00213     }
00214     (void)nss_ZFreeIf(fwSlot);
00215     return (NSSCKFWSlot *)NULL;
00216   }
00217 
00218   if( (void *)NULL != (void *)mdSlot->Initialize ) {
00219     *pError = CKR_OK;
00220     *pError = mdSlot->Initialize(mdSlot, fwSlot, mdInstance, fwInstance);
00221     if( CKR_OK != *pError ) {
00222       (void)nssCKFWMutex_Destroy(fwSlot->mutex);
00223       (void)nss_ZFreeIf(fwSlot);
00224       return (NSSCKFWSlot *)NULL;
00225     }
00226   }
00227 
00228 #ifdef DEBUG
00229   *pError = slot_add_pointer(fwSlot);
00230   if( CKR_OK != *pError ) {
00231     if( (void *)NULL != (void *)mdSlot->Destroy ) {
00232       mdSlot->Destroy(mdSlot, fwSlot, mdInstance, fwInstance);
00233     }
00234 
00235     (void)nssCKFWMutex_Destroy(fwSlot->mutex);
00236     (void)nss_ZFreeIf(fwSlot);
00237     return (NSSCKFWSlot *)NULL;
00238   }
00239 #endif /* DEBUG */
00240 
00241   return fwSlot;
00242 }
00243 
00244 /*
00245  * nssCKFWSlot_Destroy
00246  *
00247  */
00248 NSS_IMPLEMENT CK_RV
00249 nssCKFWSlot_Destroy
00250 (
00251   NSSCKFWSlot *fwSlot
00252 )
00253 {
00254   CK_RV error = CKR_OK;
00255 
00256 #ifdef NSSDEBUG
00257   error = nssCKFWSlot_verifyPointer(fwSlot);
00258   if( CKR_OK != error ) {
00259     return error;
00260   }
00261 #endif /* NSSDEBUG */
00262   if (fwSlot->fwToken) {
00263     nssCKFWToken_Destroy(fwSlot->fwToken);
00264   }
00265 
00266   (void)nssCKFWMutex_Destroy(fwSlot->mutex);
00267 
00268   if( (void *)NULL != (void *)fwSlot->mdSlot->Destroy ) {
00269     fwSlot->mdSlot->Destroy(fwSlot->mdSlot, fwSlot, 
00270       fwSlot->mdInstance, fwSlot->fwInstance);
00271   }
00272 
00273 #ifdef DEBUG
00274   error = slot_remove_pointer(fwSlot);
00275 #endif /* DEBUG */
00276   (void)nss_ZFreeIf(fwSlot);
00277   return error;
00278 }
00279 
00280 /*
00281  * nssCKFWSlot_GetMDSlot
00282  *
00283  */
00284 NSS_IMPLEMENT NSSCKMDSlot *
00285 nssCKFWSlot_GetMDSlot
00286 (
00287   NSSCKFWSlot *fwSlot
00288 )
00289 {
00290 #ifdef NSSDEBUG
00291   if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
00292     return (NSSCKMDSlot *)NULL;
00293   }
00294 #endif /* NSSDEBUG */
00295 
00296   return fwSlot->mdSlot;
00297 }
00298 
00299 /*
00300  * nssCKFWSlot_GetFWInstance
00301  *
00302  */
00303 
00304 NSS_IMPLEMENT NSSCKFWInstance *
00305 nssCKFWSlot_GetFWInstance
00306 (
00307   NSSCKFWSlot *fwSlot
00308 )
00309 {
00310 #ifdef NSSDEBUG
00311   if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
00312     return (NSSCKFWInstance *)NULL;
00313   }
00314 #endif /* NSSDEBUG */
00315 
00316   return fwSlot->fwInstance;
00317 }
00318 
00319 /*
00320  * nssCKFWSlot_GetMDInstance
00321  *
00322  */
00323 
00324 NSS_IMPLEMENT NSSCKMDInstance *
00325 nssCKFWSlot_GetMDInstance
00326 (
00327   NSSCKFWSlot *fwSlot
00328 )
00329 {
00330 #ifdef NSSDEBUG
00331   if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
00332     return (NSSCKMDInstance *)NULL;
00333   }
00334 #endif /* NSSDEBUG */
00335 
00336   return fwSlot->mdInstance;
00337 }
00338 
00339 /*
00340  * nssCKFWSlot_GetSlotID
00341  *
00342  */
00343 NSS_IMPLEMENT CK_SLOT_ID
00344 nssCKFWSlot_GetSlotID
00345 (
00346   NSSCKFWSlot *fwSlot
00347 )
00348 {
00349 #ifdef NSSDEBUG
00350   if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
00351     return (CK_SLOT_ID)0;
00352   }
00353 #endif /* NSSDEBUG */
00354 
00355   return fwSlot->slotID;
00356 }
00357 
00358 /*
00359  * nssCKFWSlot_GetSlotDescription
00360  *
00361  */
00362 NSS_IMPLEMENT CK_RV
00363 nssCKFWSlot_GetSlotDescription
00364 (
00365   NSSCKFWSlot *fwSlot,
00366   CK_CHAR slotDescription[64]
00367 )
00368 {
00369   CK_RV error = CKR_OK;
00370 
00371 #ifdef NSSDEBUG
00372   if( (CK_CHAR_PTR)NULL == slotDescription ) {
00373     return CKR_ARGUMENTS_BAD;
00374   }
00375 
00376   error = nssCKFWSlot_verifyPointer(fwSlot);
00377   if( CKR_OK != error ) {
00378     return error;
00379   }
00380 #endif /* NSSDEBUG */
00381 
00382   error = nssCKFWMutex_Lock(fwSlot->mutex);
00383   if( CKR_OK != error ) {
00384     return error;
00385   }
00386 
00387   if( (NSSUTF8 *)NULL == fwSlot->slotDescription ) {
00388     if( (void *)NULL != (void *)fwSlot->mdSlot->GetSlotDescription ) {
00389       fwSlot->slotDescription = fwSlot->mdSlot->GetSlotDescription(
00390         fwSlot->mdSlot, fwSlot, fwSlot->mdInstance, 
00391         fwSlot->fwInstance, &error);
00392       if( ((NSSUTF8 *)NULL == fwSlot->slotDescription) && (CKR_OK != error) ) {
00393         goto done;
00394       }
00395     } else {
00396       fwSlot->slotDescription = (NSSUTF8 *) "";
00397     }
00398   }
00399 
00400   (void)nssUTF8_CopyIntoFixedBuffer(fwSlot->slotDescription, (char *)slotDescription, 64, ' ');
00401   error = CKR_OK;
00402 
00403  done:
00404   (void)nssCKFWMutex_Unlock(fwSlot->mutex);
00405   return error;
00406 }
00407 
00408 /*
00409  * nssCKFWSlot_GetManufacturerID
00410  *
00411  */
00412 NSS_IMPLEMENT CK_RV
00413 nssCKFWSlot_GetManufacturerID
00414 (
00415   NSSCKFWSlot *fwSlot,
00416   CK_CHAR manufacturerID[32]
00417 )
00418 {
00419   CK_RV error = CKR_OK;
00420 
00421 #ifdef NSSDEBUG
00422   if( (CK_CHAR_PTR)NULL == manufacturerID ) {
00423     return CKR_ARGUMENTS_BAD;
00424   }
00425 
00426   error = nssCKFWSlot_verifyPointer(fwSlot);
00427   if( CKR_OK != error ) {
00428     return error;
00429   }
00430 #endif /* NSSDEBUG */
00431 
00432   error = nssCKFWMutex_Lock(fwSlot->mutex);
00433   if( CKR_OK != error ) {
00434     return error;
00435   }
00436 
00437   if( (NSSUTF8 *)NULL == fwSlot->manufacturerID ) {
00438     if( (void *)NULL != (void *)fwSlot->mdSlot->GetManufacturerID ) {
00439       fwSlot->manufacturerID = fwSlot->mdSlot->GetManufacturerID(
00440         fwSlot->mdSlot, fwSlot, fwSlot->mdInstance, 
00441         fwSlot->fwInstance, &error);
00442       if( ((NSSUTF8 *)NULL == fwSlot->manufacturerID) && (CKR_OK != error) ) {
00443         goto done;
00444       }
00445     } else {
00446       fwSlot->manufacturerID = (NSSUTF8 *) "";
00447     }
00448   }
00449 
00450   (void)nssUTF8_CopyIntoFixedBuffer(fwSlot->manufacturerID, (char *)manufacturerID, 32, ' ');
00451   error = CKR_OK;
00452 
00453  done:
00454   (void)nssCKFWMutex_Unlock(fwSlot->mutex);
00455   return error;
00456 }
00457 
00458 /*
00459  * nssCKFWSlot_GetTokenPresent
00460  *
00461  */
00462 NSS_IMPLEMENT CK_BBOOL
00463 nssCKFWSlot_GetTokenPresent
00464 (
00465   NSSCKFWSlot *fwSlot
00466 )
00467 {
00468 #ifdef NSSDEBUG
00469   if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
00470     return CK_FALSE;
00471   }
00472 #endif /* NSSDEBUG */
00473 
00474   if( (void *)NULL == (void *)fwSlot->mdSlot->GetTokenPresent ) {
00475     return CK_TRUE;
00476   }
00477 
00478   return fwSlot->mdSlot->GetTokenPresent(fwSlot->mdSlot, fwSlot,
00479     fwSlot->mdInstance, fwSlot->fwInstance);
00480 }
00481 
00482 /*
00483  * nssCKFWSlot_GetRemovableDevice
00484  *
00485  */
00486 NSS_IMPLEMENT CK_BBOOL
00487 nssCKFWSlot_GetRemovableDevice
00488 (
00489   NSSCKFWSlot *fwSlot
00490 )
00491 {
00492 #ifdef NSSDEBUG
00493   if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
00494     return CK_FALSE;
00495   }
00496 #endif /* NSSDEBUG */
00497 
00498   if( (void *)NULL == (void *)fwSlot->mdSlot->GetRemovableDevice ) {
00499     return CK_FALSE;
00500   }
00501 
00502   return fwSlot->mdSlot->GetRemovableDevice(fwSlot->mdSlot, fwSlot,
00503     fwSlot->mdInstance, fwSlot->fwInstance);
00504 }
00505 
00506 /*
00507  * nssCKFWSlot_GetHardwareSlot
00508  *
00509  */
00510 NSS_IMPLEMENT CK_BBOOL
00511 nssCKFWSlot_GetHardwareSlot
00512 (
00513   NSSCKFWSlot *fwSlot
00514 )
00515 {
00516 #ifdef NSSDEBUG
00517   if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
00518     return CK_FALSE;
00519   }
00520 #endif /* NSSDEBUG */
00521 
00522   if( (void *)NULL == (void *)fwSlot->mdSlot->GetHardwareSlot ) {
00523     return CK_FALSE;
00524   }
00525 
00526   return fwSlot->mdSlot->GetHardwareSlot(fwSlot->mdSlot, fwSlot,
00527     fwSlot->mdInstance, fwSlot->fwInstance);
00528 }
00529 
00530 /*
00531  * nssCKFWSlot_GetHardwareVersion
00532  *
00533  */
00534 NSS_IMPLEMENT CK_VERSION
00535 nssCKFWSlot_GetHardwareVersion
00536 (
00537   NSSCKFWSlot *fwSlot
00538 )
00539 {
00540   CK_VERSION rv;
00541 
00542 #ifdef NSSDEBUG
00543   if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
00544     rv.major = rv.minor = 0;
00545     return rv;
00546   }
00547 #endif /* NSSDEBUG */
00548 
00549   if( CKR_OK != nssCKFWMutex_Lock(fwSlot->mutex) ) {
00550     rv.major = rv.minor = 0;
00551     return rv;
00552   }
00553 
00554   if( (0 != fwSlot->hardwareVersion.major) ||
00555       (0 != fwSlot->hardwareVersion.minor) ) {
00556     rv = fwSlot->hardwareVersion;
00557     goto done;
00558   }
00559 
00560   if( (void *)NULL != (void *)fwSlot->mdSlot->GetHardwareVersion ) {
00561     fwSlot->hardwareVersion = fwSlot->mdSlot->GetHardwareVersion(
00562       fwSlot->mdSlot, fwSlot, fwSlot->mdInstance, fwSlot->fwInstance);
00563   } else {
00564     fwSlot->hardwareVersion.major = 0;
00565     fwSlot->hardwareVersion.minor = 1;
00566   }
00567 
00568   rv = fwSlot->hardwareVersion;
00569  done:
00570   (void)nssCKFWMutex_Unlock(fwSlot->mutex);
00571   return rv;
00572 }
00573 
00574 /*
00575  * nssCKFWSlot_GetFirmwareVersion
00576  *
00577  */
00578 NSS_IMPLEMENT CK_VERSION
00579 nssCKFWSlot_GetFirmwareVersion
00580 (
00581   NSSCKFWSlot *fwSlot
00582 )
00583 {
00584   CK_VERSION rv;
00585 
00586 #ifdef NSSDEBUG
00587   if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
00588     rv.major = rv.minor = 0;
00589     return rv;
00590   }
00591 #endif /* NSSDEBUG */
00592 
00593   if( CKR_OK != nssCKFWMutex_Lock(fwSlot->mutex) ) {
00594     rv.major = rv.minor = 0;
00595     return rv;
00596   }
00597 
00598   if( (0 != fwSlot->firmwareVersion.major) ||
00599       (0 != fwSlot->firmwareVersion.minor) ) {
00600     rv = fwSlot->firmwareVersion;
00601     goto done;
00602   }
00603 
00604   if( (void *)NULL != (void *)fwSlot->mdSlot->GetFirmwareVersion ) {
00605     fwSlot->firmwareVersion = fwSlot->mdSlot->GetFirmwareVersion(
00606       fwSlot->mdSlot, fwSlot, fwSlot->mdInstance, fwSlot->fwInstance);
00607   } else {
00608     fwSlot->firmwareVersion.major = 0;
00609     fwSlot->firmwareVersion.minor = 1;
00610   }
00611 
00612   rv = fwSlot->firmwareVersion;
00613  done:
00614   (void)nssCKFWMutex_Unlock(fwSlot->mutex);
00615   return rv;
00616 }
00617 
00618 /*
00619  * nssCKFWSlot_GetToken
00620  * 
00621  */
00622 NSS_IMPLEMENT NSSCKFWToken *
00623 nssCKFWSlot_GetToken
00624 (
00625   NSSCKFWSlot *fwSlot,
00626   CK_RV *pError
00627 )
00628 {
00629   NSSCKMDToken *mdToken;
00630   NSSCKFWToken *fwToken;
00631 
00632 #ifdef NSSDEBUG
00633   if( (CK_RV *)NULL == pError ) {
00634     return (NSSCKFWToken *)NULL;
00635   }
00636 
00637   *pError = nssCKFWSlot_verifyPointer(fwSlot);
00638   if( CKR_OK != *pError ) {
00639     return (NSSCKFWToken *)NULL;
00640   }
00641 #endif /* NSSDEBUG */
00642 
00643   *pError = nssCKFWMutex_Lock(fwSlot->mutex);
00644   if( CKR_OK != *pError ) {
00645     return (NSSCKFWToken *)NULL;
00646   }
00647 
00648   if( (NSSCKFWToken *)NULL == fwSlot->fwToken ) {
00649     if( (void *)NULL == (void *)fwSlot->mdSlot->GetToken ) {
00650       *pError = CKR_GENERAL_ERROR;
00651       fwToken = (NSSCKFWToken *)NULL;
00652       goto done;
00653     }
00654 
00655     mdToken = fwSlot->mdSlot->GetToken(fwSlot->mdSlot, fwSlot,
00656       fwSlot->mdInstance, fwSlot->fwInstance, pError);
00657     if( (NSSCKMDToken *)NULL == mdToken ) {
00658       if( CKR_OK == *pError ) {
00659         *pError = CKR_GENERAL_ERROR;
00660       }
00661       return (NSSCKFWToken *)NULL;
00662     }
00663 
00664     fwToken = nssCKFWToken_Create(fwSlot, mdToken, pError);
00665     fwSlot->fwToken = fwToken;
00666   } else {
00667     fwToken = fwSlot->fwToken;
00668   }
00669 
00670  done:
00671   (void)nssCKFWMutex_Unlock(fwSlot->mutex);
00672   return fwToken;
00673 }
00674 
00675 /*
00676  * nssCKFWSlot_ClearToken
00677  *
00678  */
00679 NSS_IMPLEMENT void
00680 nssCKFWSlot_ClearToken
00681 (
00682   NSSCKFWSlot *fwSlot
00683 )
00684 {
00685 #ifdef NSSDEBUG
00686   if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
00687     return;
00688   }
00689 #endif /* NSSDEBUG */
00690 
00691   if( CKR_OK != nssCKFWMutex_Lock(fwSlot->mutex) ) {
00692     /* Now what? */
00693     return;
00694   }
00695 
00696   fwSlot->fwToken = (NSSCKFWToken *)NULL;
00697   (void)nssCKFWMutex_Unlock(fwSlot->mutex);
00698   return;
00699 }
00700 
00701 /*
00702  * NSSCKFWSlot_GetMDSlot
00703  *
00704  */
00705 
00706 NSS_IMPLEMENT NSSCKMDSlot *
00707 NSSCKFWSlot_GetMDSlot
00708 (
00709   NSSCKFWSlot *fwSlot
00710 )
00711 {
00712 #ifdef DEBUG
00713   if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
00714     return (NSSCKMDSlot *)NULL;
00715   }
00716 #endif /* DEBUG */
00717 
00718   return nssCKFWSlot_GetMDSlot(fwSlot);
00719 }
00720 
00721 /*
00722  * NSSCKFWSlot_GetFWInstance
00723  *
00724  */
00725 
00726 NSS_IMPLEMENT NSSCKFWInstance *
00727 NSSCKFWSlot_GetFWInstance
00728 (
00729   NSSCKFWSlot *fwSlot
00730 )
00731 {
00732 #ifdef DEBUG
00733   if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
00734     return (NSSCKFWInstance *)NULL;
00735   }
00736 #endif /* DEBUG */
00737 
00738   return nssCKFWSlot_GetFWInstance(fwSlot);
00739 }
00740 
00741 /*
00742  * NSSCKFWSlot_GetMDInstance
00743  *
00744  */
00745 
00746 NSS_IMPLEMENT NSSCKMDInstance *
00747 NSSCKFWSlot_GetMDInstance
00748 (
00749   NSSCKFWSlot *fwSlot
00750 )
00751 {
00752 #ifdef DEBUG
00753   if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
00754     return (NSSCKMDInstance *)NULL;
00755   }
00756 #endif /* DEBUG */
00757 
00758   return nssCKFWSlot_GetMDInstance(fwSlot);
00759 }