if( CK_TRUE != nssCKFWToken_GetIsWriteProtected(fwToken) ) {
if( CK_TRUE == nssCKFWToken_GetIsWriteProtected(fwToken) ) {
nssCKFWToken_OpenSession(  NSSCKFWToken *fwToken,  CK_BBOOL rw,  CK_VOID_PTR pApplication,  CK_NOTIFY Notify,  CK_RV *pError){  NSSCKFWSession *fwSession = (NSSCKFWSession *)NULL;  NSSCKMDSession *mdSession;#ifdef NSSDEBUG  if( (CK_RV *)NULL == pError ) {    return (NSSCKFWSession *)NULL;  }  *pError = nssCKFWToken_verifyPointer(fwToken);  if( CKR_OK != *pError ) {    return (NSSCKFWSession *)NULL;  }  switch( rw ) {  case CK_TRUE:  case CK_FALSE:    break;  default:    *pError = CKR_ARGUMENTS_BAD;    return (NSSCKFWSession *)NULL;  }#endif /* NSSDEBUG */  *pError = nssCKFWMutex_Lock(fwToken->mutex);  if( CKR_OK != *pError ) {    return (NSSCKFWSession *)NULL;  }  if( CK_TRUE == rw ) {    /* Read-write session desired */    if( CK_TRUE != nssCKFWToken_GetIsWriteProtected(fwToken) ) {      *pError = CKR_TOKEN_WRITE_PROTECTED;      goto done;    }  } else {    /* Read-only session desired */    if( CKS_RW_SO_FUNCTIONS == nssCKFWToken_GetSessionState(fwToken) ) {      *pError = CKR_SESSION_READ_WRITE_SO_EXISTS;      goto done;    }  }  /* We could compare sesion counts to any limits we know of, I guess.. */  if( (void *)NULL == (void *)fwToken->mdToken->OpenSession ) {    /*     * I'm not sure that the Module actually needs to implement     * mdSessions -- the Framework can keep track of everything      * needed, really.  But I'll sort out that detail later..     */    *pError = CKR_GENERAL_ERROR;    goto done;  }  fwSession = nssCKFWSession_Create(fwToken, rw, pApplication, Notify, pError);  if( (NSSCKFWSession *)NULL == fwSession ) {    if( CKR_OK == *pError ) {      *pError = CKR_GENERAL_ERROR;    }    goto done;  }  mdSession = fwToken->mdToken->OpenSession(fwToken->mdToken, fwToken,                fwToken->mdInstance, fwToken->fwInstance, fwSession,                rw, pError);  if( (NSSCKMDSession *)NULL == mdSession ) {    (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);    if( CKR_OK == *pError ) {      *pError = CKR_GENERAL_ERROR;    }    goto done;  }  *pError = nssCKFWSession_SetMDSession(fwSession, mdSession);  if( CKR_OK != *pError ) {    if( (void *)NULL != (void *)mdSession->Close ) {      mdSession->Close(mdSession, fwSession, fwToken->mdToken, fwToken,      fwToken->mdInstance, fwToken->fwInstance);    }    (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);    goto done;  }  *pError = nssCKFWHash_Add(fwToken->sessions, fwSession, fwSession);  if( CKR_OK != *pError ) {    (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);    fwSession = (NSSCKFWSession *)NULL;    goto done;  } done:  (void)nssCKFWMutex_Unlock(fwToken->mutex);  return fwSession;}