Ejemplo n.º 1
0
// Unloads a plugin DLL.  "pluginType" is a handle to a plugin management data
// structure created during FE_RegisterPlugins().  There is no return val.
void FE_UnloadPlugin(void* pluginType, struct _np_handle* handle)
{
    NPPMgtBlk* pNPMgtBlk = (NPPMgtBlk*)pluginType;
    if (pNPMgtBlk == NULL)
        return;

    // XXX Note that we're double refcounting here. If we were rewriting this 
    // from scratch, we could eliminate this pNPMgtBlk and its refcount and just
    // rely on the one in the userPlugin.

    pNPMgtBlk->uRefCount--;   // another one bites the dust

    // if this DLL is the last one, call its shutdown entry point
    if (pNPMgtBlk->uRefCount == 0) {
        if (handle->userPlugin) {
            handle->userPlugin->Release();
        }
        else {
            // the NP_Shutdown entry point was misnamed as NP_PluginShutdown, early
            // in plugin project development.  Its correct name is documented
            // now, and new developers expect it to work.  However, I don't want
            // to  break the plugins already in the field, so I'll accept either
            // name
            NP_PLUGINSHUTDOWN npshutdown =
#ifndef NSPR20
                (NP_PLUGINSHUTDOWN)PR_FindSymbol("NP_Shutdown", pNPMgtBlk->pLibrary);
#else
                (NP_PLUGINSHUTDOWN)PR_FindSymbol(pNPMgtBlk->pLibrary, "NP_Shutdown");
#endif
            if (!npshutdown) {
                npshutdown =
#ifndef NSPR20
                    (NP_PLUGINSHUTDOWN)PR_FindSymbol("NP_PluginShutdown", pNPMgtBlk->pLibrary);
#else
                    (NP_PLUGINSHUTDOWN)PR_FindSymbol(pNPMgtBlk->pLibrary, "NP_PluginShutdown");
#endif
            }

            if (npshutdown != NULL) {
                NPError result = npshutdown();
            }
        }
    }

    // XXX Shouldn't the rest of this be inside the if statement, above?...

    PR_UnloadLibrary(pNPMgtBlk->pLibrary);
    pNPMgtBlk->pLibrary = NULL;
    
    if (handle->userPlugin) {
        PR_ASSERT(pNPMgtBlk->pPluginFuncs == (NPPluginFuncs*)-1);     // set in FE_LoadPlugin
        handle->userPlugin = NULL;
    }
    else {
        delete pNPMgtBlk->pPluginFuncs;
    }
    pNPMgtBlk->pPluginFuncs = NULL;
}
Ejemplo n.º 2
0
bool
nsCUPSShim::Init()
{
    mCupsLib = PR_LoadLibrary("libcups.so.2");
    if (!mCupsLib)
        return false;

    // List of symbol pointers. Must match gSymName[] defined above.
    void **symAddr[] = {
        (void **)&mCupsAddOption,
        (void **)&mCupsFreeDests,
        (void **)&mCupsGetDest,
        (void **)&mCupsGetDests,
        (void **)&mCupsPrintFile,
        (void **)&mCupsTempFd,
    };

    for (int i = gSymNameCt; i--; ) {
        *(symAddr[i]) = PR_FindSymbol(mCupsLib, gSymName[i]);
        if (! *(symAddr[i])) {
#ifdef DEBUG
            nsAutoCString msg(gSymName[i]);
            msg.Append(" not found in CUPS library");
            NS_WARNING(msg.get());
#endif
            PR_UnloadLibrary(mCupsLib);
            mCupsLib = nullptr;
            return false;
        }
    }
    return true;
}
Ejemplo n.º 3
0
NS_IMETHODIMP
nsSound::Init()
{
    /* we don't need to do esd_open_sound if we are only going to play files
       but we will if we want to do things like streams, etc
    */
    if (mInited) 
        return NS_OK;
    if (elib) 
        return NS_OK;

    EsdOpenSoundType EsdOpenSound;

    elib = PR_LoadLibrary("libesd.so.0");
    if (!elib) return NS_ERROR_FAILURE;

    EsdOpenSound = (EsdOpenSoundType) PR_FindSymbol(elib, "esd_open_sound");

    if (!EsdOpenSound)
        return NS_ERROR_FAILURE;

    esdref = (*EsdOpenSound)("localhost");

    if (!esdref)
        return NS_ERROR_FAILURE;

    mInited = PR_TRUE;

    return NS_OK;
}
Ejemplo n.º 4
0
nsresult
nsPluggableJVM::loadPluginDLL(const char* plugin_home)
{
  char* plugin_dll = PR_GetLibraryName(plugin_home, LIBJVMP);
  JVMP_GetPlugin_t fJVMP_GetPlugin;
  char errorMsg[1024] = "<unknown; can't get error from NSPR>";

  OJI_LOG2("Loading JVMP from %s", plugin_dll);
  m_dll = PR_LoadLibrary(plugin_dll);
  PR_Free(plugin_dll);
  if (!m_dll) 
    {
      if (PR_GetErrorTextLength() < (int) sizeof(errorMsg))
	PR_GetErrorText(errorMsg);
      OJI_LOG2("Cannot load plugin DLL: %s", errorMsg);
      return NS_ERROR_FAILURE;
    }
  fJVMP_GetPlugin = 
    (JVMP_GetPlugin_t) PR_FindSymbol(m_dll, "JVMP_GetPlugin");
  if (!fJVMP_GetPlugin)
    {
      if (PR_GetErrorTextLength() < (int) sizeof(errorMsg))
	PR_GetErrorText(errorMsg);
      OJI_LOG2("Cannot resolve JVMP_GetPlugin: %s", errorMsg);
      return NS_ERROR_FAILURE;
    }
  (*fJVMP_GetPlugin)(&m_jvmp_context);
  return NS_OK;
}
MediaPluginHost::MediaPluginHost() {
  MOZ_COUNT_CTOR(MediaPluginHost);

  const char* name = GetOmxLibraryName();
  ALOG("Loading OMX Plugin: %s", name ? name : "nullptr");
  if (name) {
    char *path = PR_GetLibraryFilePathname("libxul.so", (PRFuncPtr) GetOmxLibraryName);
    PRLibrary *lib = NULL;
    if (path) {
      nsAutoCString libpath(path);
      PR_Free(path);
      int32_t slash = libpath.RFindChar('/');
      if (slash != kNotFound) {
        libpath.Truncate(slash + 1);
        libpath.Append(name);
        lib = PR_LoadLibrary(libpath.get());
      }
    }
    if (!lib)
      lib = PR_LoadLibrary(name);

    if (lib) {
      Manifest *manifest = static_cast<Manifest *>(PR_FindSymbol(lib, "MPAPI_MANIFEST"));
      if (manifest) {
        mPlugins.AppendElement(manifest);
        ALOG("OMX plugin successfully loaded");
     }
    }
  }
}
Ejemplo n.º 6
0
nsSound::~nsSound()
{
    /* see above comment */
    if (esdref != -1) {
        EsdCloseType EsdClose = (EsdCloseType) PR_FindSymbol(elib, "esd_close");
        (*EsdClose)(esdref);
        esdref = -1;
    }
}
Ejemplo n.º 7
0
DB *
rdbopen(const char *appName, const char *prefix,
        const char *type, int flags, int *status)
{
    PRLibrary *lib;
    DB *db;
    char *disableUnload = NULL;

    if (lg_rdbfunc) {
        db = (*lg_rdbfunc)(appName, prefix, type, rdbmapflags(flags));
        if (!db && status && lg_rdbstatusfunc) {
            *status = (*lg_rdbstatusfunc)();
        }
        return db;
    }

    /*
     * try to open the library.
     */
    lib = PR_LoadLibrary(RDBLIB);

    if (!lib) {
        return NULL;
    }

    /* get the entry points */
    lg_rdbstatusfunc = (rdbstatusfunc)PR_FindSymbol(lib, "rdbstatus");
    lg_rdbfunc = (rdbfunc)PR_FindSymbol(lib, "rdbopen");
    if (lg_rdbfunc) {
        db = (*lg_rdbfunc)(appName, prefix, type, rdbmapflags(flags));
        if (!db && status && lg_rdbstatusfunc) {
            *status = (*lg_rdbstatusfunc)();
        }
        return db;
    }

    /* couldn't find the entry point, unload the library and fail */
    disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
    if (!disableUnload) {
        PR_UnloadLibrary(lib);
    }
    return NULL;
}
Ejemplo n.º 8
0
void* LibraryNSPR::findSymbol(const std::string& symbolName)
{
   // If the library has not been loaded yet, throw an exception.
   if ( NULL == mLibrary )
   {
      std::ostringstream msg_stream;
      msg_stream << "Library not loaded: '" << mName << "'";
      throw vpr::LibraryException(msg_stream.str(), VPR_LOCATION);
   }

   return PR_FindSymbol(mLibrary, symbolName.c_str());
}
Ejemplo n.º 9
0
MediaPluginHost::MediaPluginHost() {
  MOZ_COUNT_CTOR(MediaPluginHost);

  const char* name = GetOmxLibraryName();
  ALOG("Loading OMX Plugin: %s", name ? name : "nullptr");
  if (name) {
    PRLibrary *lib = PR_LoadLibrary(name);
    if (lib) {
      Manifest *manifest = static_cast<Manifest *>(PR_FindSymbol(lib, "MPAPI_MANIFEST"));
      if (manifest) {
        mPlugins.AppendElement(manifest);
        ALOG("OMX plugin successfully loaded");
     }
    }
  }
}
void MediaPluginHost::TryLoad(const char *name)
{
  bool forceEnabled =
      Preferences::GetBool("stagefright.force-enabled", false);
  bool disabled =
      Preferences::GetBool("stagefright.disabled", false);

  if (disabled) {
    NS_WARNING("XXX stagefright disabled\n");
    return;
  }

  ScopedGfxFeatureReporter reporter("Stagefright", forceEnabled);

  if (!forceEnabled) {
    nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
    if (gfxInfo) {
      int32_t status;
      if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_STAGEFRIGHT, &status))) {
        if (status != nsIGfxInfo::FEATURE_NO_INFO) {
          NS_WARNING("XXX stagefright blacklisted\n");
          return;
        }
      }
    }
  }

  reporter.SetSuccessful();

  PRLibrary *lib = PR_LoadLibrary(name);
  if (lib) {
    Manifest *manifest = static_cast<Manifest *>(PR_FindSymbol(lib, "MPAPI_MANIFEST"));
    if (manifest)
      mPlugins.AppendElement(manifest);
  }
}
Ejemplo n.º 11
0
bool
Library::Declare(JSContext* cx, unsigned argc, Value* vp)
{
  CallArgs args = CallArgsFromVp(argc, vp);
  RootedObject obj(cx, JS_THIS_OBJECT(cx, vp));
  if (!obj)
    return false;
  if (!IsLibrary(obj)) {
    JS_ReportErrorASCII(cx, "not a library");
    return false;
  }

  PRLibrary* library = GetLibrary(obj);
  if (!library) {
    JS_ReportErrorASCII(cx, "library not open");
    return false;
  }

  // We allow two API variants:
  // 1) library.declare(name, abi, returnType, argType1, ...)
  //    declares a function with the given properties, and resolves the symbol
  //    address in the library.
  // 2) library.declare(name, type)
  //    declares a symbol of 'type', and resolves it. The object that comes
  //    back will be of type 'type', and will point into the symbol data.
  //    This data will be both readable and writable via the usual CData
  //    accessors. If 'type' is a PointerType to a FunctionType, the result will
  //    be a function pointer, as with 1).
  if (args.length() < 2) {
    JS_ReportErrorASCII(cx, "declare requires at least two arguments");
    return false;
  }

  if (!args[0].isString()) {
    JS_ReportErrorASCII(cx, "first argument must be a string");
    return false;
  }

  RootedObject fnObj(cx, nullptr);
  RootedObject typeObj(cx);
  bool isFunction = args.length() > 2;
  if (isFunction) {
    // Case 1).
    // Create a FunctionType representing the function.
    fnObj = FunctionType::CreateInternal(cx, args[1], args[2],
                                         HandleValueArray::subarray(args, 3, args.length() - 3));
    if (!fnObj)
      return false;

    // Make a function pointer type.
    typeObj = PointerType::CreateInternal(cx, fnObj);
    if (!typeObj)
      return false;
  } else {
    // Case 2).
    if (args[1].isPrimitive() ||
        !CType::IsCType(args[1].toObjectOrNull()) ||
        !CType::IsSizeDefined(args[1].toObjectOrNull())) {
      JS_ReportErrorASCII(cx, "second argument must be a type of defined size");
      return false;
    }

    typeObj = args[1].toObjectOrNull();
    if (CType::GetTypeCode(typeObj) == TYPE_pointer) {
      fnObj = PointerType::GetBaseType(typeObj);
      isFunction = fnObj && CType::GetTypeCode(fnObj) == TYPE_function;
    }
  }

  void* data;
  PRFuncPtr fnptr;
  RootedString nameStr(cx, args[0].toString());
  AutoCString symbol;
  if (isFunction) {
    // Build the symbol, with mangling if necessary.
    FunctionType::BuildSymbolName(nameStr, fnObj, symbol);
    AppendString(symbol, "\0");

    // Look up the function symbol.
    fnptr = PR_FindFunctionSymbol(library, symbol.begin());
    if (!fnptr) {
      JS_ReportErrorASCII(cx, "couldn't find function symbol in library");
      return false;
    }
    data = &fnptr;

  } else {
    // 'typeObj' is another data type. Look up the data symbol.
    AppendString(symbol, nameStr);
    AppendString(symbol, "\0");

    data = PR_FindSymbol(library, symbol.begin());
    if (!data) {
      JS_ReportErrorASCII(cx, "couldn't find symbol in library");
      return false;
    }
  }

  RootedObject result(cx, CData::Create(cx, typeObj, obj, data, isFunction));
  if (!result)
    return false;

  if (isFunction)
    JS_SetReservedSlot(result, SLOT_FUNNAME, StringValue(nameStr));

  args.rval().setObject(*result);

  // Seal the CData object, to prevent modification of the function pointer.
  // This permanently associates this object with the library, and avoids
  // having to do things like reset SLOT_REFERENT when someone tries to
  // change the pointer value.
  // XXX This will need to change when bug 541212 is fixed -- CData::ValueSetter
  // could be called on a sealed object.
  if (isFunction && !JS_FreezeObject(cx, result))
    return false;

  return true;
}
Ejemplo n.º 12
0
JSBool
Library::Declare(JSContext* cx, uintN argc, jsval* vp)
{
  JSObject* obj = JS_THIS_OBJECT(cx, vp);
  if (!obj || !IsLibrary(cx, obj)) {
    JS_ReportError(cx, "not a library");
    return JS_FALSE;
  }

  PRLibrary* library = GetLibrary(cx, obj);
  if (!library) {
    JS_ReportError(cx, "library not open");
    return JS_FALSE;
  }

  // We allow two API variants:
  // 1) library.declare(name, abi, returnType, argType1, ...)
  //    declares a function with the given properties, and resolves the symbol
  //    address in the library.
  // 2) library.declare(name, type)
  //    declares a symbol of 'type', and resolves it. The object that comes
  //    back will be of type 'type', and will point into the symbol data.
  //    This data will be both readable and writable via the usual CData
  //    accessors. If 'type' is a PointerType to a FunctionType, the result will
  //    be a function pointer, as with 1). 
  if (argc < 2) {
    JS_ReportError(cx, "declare requires at least two arguments");
    return JS_FALSE;
  }

  jsval* argv = JS_ARGV(cx, vp);
  if (!JSVAL_IS_STRING(argv[0])) {
    JS_ReportError(cx, "first argument must be a string");
    return JS_FALSE;
  }

  JSObject* fnObj = NULL;
  JSObject* typeObj;
  js::AutoObjectRooter root(cx);
  bool isFunction = argc > 2;
  if (isFunction) {
    // Case 1).
    // Create a FunctionType representing the function.
    fnObj = FunctionType::CreateInternal(cx,
              argv[1], argv[2], &argv[3], argc - 3);
    if (!fnObj)
      return JS_FALSE;
    root.setObject(fnObj);

    // Make a function pointer type.
    typeObj = PointerType::CreateInternal(cx, fnObj);
    if (!typeObj)
      return JS_FALSE;
    root.setObject(typeObj);

  } else {
    // Case 2).
    if (JSVAL_IS_PRIMITIVE(argv[1]) ||
        !CType::IsCType(cx, JSVAL_TO_OBJECT(argv[1])) ||
        !CType::IsSizeDefined(cx, JSVAL_TO_OBJECT(argv[1]))) {
      JS_ReportError(cx, "second argument must be a type of defined size");
      return JS_FALSE;
    }

    typeObj = JSVAL_TO_OBJECT(argv[1]);
    if (CType::GetTypeCode(cx, typeObj) == TYPE_pointer) {
      fnObj = PointerType::GetBaseType(cx, typeObj);
      isFunction = fnObj && CType::GetTypeCode(cx, fnObj) == TYPE_function;
    }
  }

  void* data;
  PRFuncPtr fnptr;
  JSString* nameStr = JSVAL_TO_STRING(argv[0]);
  AutoCString symbol;
  if (isFunction) {
    // Build the symbol, with mangling if necessary.
    FunctionType::BuildSymbolName(cx, nameStr, fnObj, symbol);
    AppendString(symbol, "\0");

    // Look up the function symbol.
    fnptr = PR_FindFunctionSymbol(library, symbol.begin());
    if (!fnptr) {
      JS_ReportError(cx, "couldn't find function symbol in library");
      return JS_FALSE;
    }
    data = &fnptr;

  } else {
    // 'typeObj' is another data type. Look up the data symbol.
    AppendString(symbol, nameStr);
    AppendString(symbol, "\0");

    data = PR_FindSymbol(library, symbol.begin());
    if (!data) {
      JS_ReportError(cx, "couldn't find symbol in library");
      return JS_FALSE;
    }
  }

  JSObject* result = CData::Create(cx, typeObj, obj, data, isFunction);
  if (!result)
    return JS_FALSE;

  JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(result));

  // Seal the CData object, to prevent modification of the function pointer.
  // This permanently associates this object with the library, and avoids
  // having to do things like reset SLOT_REFERENT when someone tries to
  // change the pointer value.
  // XXX This will need to change when bug 541212 is fixed -- CData::ValueSetter
  // could be called on a sealed object.
  if (isFunction && !JS_FreezeObject(cx, result))
    return JS_FALSE;

  return JS_TRUE;
}
const mozilla::Module*
nsNativeModuleLoader::LoadModule(nsILocalFile* aFile)
{
    nsresult rv;

    if (!NS_IsMainThread()) {
        // If this call is off the main thread, synchronously proxy it
        // to the main thread.
        nsRefPtr<LoadModuleMainThreadRunnable> r = new LoadModuleMainThreadRunnable(this, aFile);
        NS_DispatchToMainThread(r, NS_DISPATCH_SYNC);
        return r->mResult;
    }

    nsCOMPtr<nsIHashable> hashedFile(do_QueryInterface(aFile));
    if (!hashedFile) {
        NS_ERROR("nsIFile is not nsIHashable");
        return NULL;
    }

    nsCAutoString filePath;
    aFile->GetNativePath(filePath);

    NativeLoadData data;

    if (mLibraries.Get(hashedFile, &data)) {
        NS_ASSERTION(data.module, "Corrupt mLibraries hash");
        LOG(PR_LOG_DEBUG,
            ("nsNativeModuleLoader::LoadModule(\"%s\") - found in cache",
             filePath.get()));
        return data.module;
    }

    // We haven't loaded this module before

    rv = aFile->Load(&data.library);

    if (NS_FAILED(rv)) {
        char errorMsg[1024] = "<unknown; can't get error from NSPR>";

        if (PR_GetErrorTextLength() < (int) sizeof(errorMsg))
            PR_GetErrorText(errorMsg);

        LOG(PR_LOG_ERROR,
            ("nsNativeModuleLoader::LoadModule(\"%s\") - load FAILED, "
             "rv: %lx, error:\n\t%s\n",
             filePath.get(), rv, errorMsg));

#ifdef DEBUG
        fprintf(stderr,
                "nsNativeModuleLoader::LoadModule(\"%s\") - load FAILED, "
                "rv: %lx, error:\n\t%s\n",
                filePath.get(), (unsigned long)rv, errorMsg);
#endif

        return NULL;
    }

#ifdef IMPLEMENT_BREAK_AFTER_LOAD
    nsCAutoString leafName;
    aFile->GetNativeLeafName(leafName);

    char *env = getenv("XPCOM_BREAK_ON_LOAD");
    char *blist;
    if (env && *env && (blist = strdup(env))) {
        char *nextTok = blist;
        while (char *token = NS_strtok(":", &nextTok)) {
            if (leafName.Find(token, PR_TRUE) != kNotFound) {
                NS_BREAK();
            }
        }

        free(blist);
    }
#endif

    void *module = PR_FindSymbol(data.library, "NSModule");
    if (module) {
        data.module = *(mozilla::Module const *const *) module;
        if (mLibraries.Put(hashedFile, data))
            return data.module;
    }
    else {
        LOG(PR_LOG_ERROR,
            ("nsNativeModuleLoader::LoadModule(\"%s\") - "
             "Symbol NSModule not found", filePath.get()));
    }

    // at some point we failed, clean up
    data.module = nsnull;
    PR_UnloadLibrary(data.library);

    return NULL;
}
Ejemplo n.º 14
0
/*
 * load a new module into our address space and initialize it.
 */
SECStatus
secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
{
    PRLibrary *library = NULL;
    CK_C_GetFunctionList entry = NULL;
    CK_INFO info;
    CK_ULONG slotCount = 0;
    SECStatus rv;
    PRBool alreadyLoaded = PR_FALSE;
    char *disableUnload = NULL;

    if (mod->loaded)
        return SECSuccess;

    /* internal modules get loaded from their internal list */
    if (mod->internal && (mod->dllName == NULL)) {
#ifdef NSS_TEST_BUILD
        entry = (CK_C_GetFunctionList)NSC_GetFunctionList;
#else
        /*
         * Loads softoken as a dynamic library,
         * even though the rest of NSS assumes this as the "internal" module.
         */
        if (!softokenLib &&
            PR_SUCCESS != PR_CallOnce(&loadSoftokenOnce, &softoken_LoadDSO))
            return SECFailure;

        PR_ATOMIC_INCREMENT(&softokenLoadCount);

        if (mod->isFIPS) {
            entry = (CK_C_GetFunctionList)
                PR_FindSymbol(softokenLib, "FC_GetFunctionList");
        } else {
            entry = (CK_C_GetFunctionList)
                PR_FindSymbol(softokenLib, "NSC_GetFunctionList");
        }

        if (!entry)
            return SECFailure;
#endif

        if (mod->isModuleDB) {
            mod->moduleDBFunc = (CK_C_GetFunctionList)
#ifdef NSS_TEST_BUILD
                NSC_ModuleDBFunc;
#else
                PR_FindSymbol(softokenLib, "NSC_ModuleDBFunc");
#endif
        }

        if (mod->moduleDBOnly) {
            mod->loaded = PR_TRUE;
            return SECSuccess;
        }
    } else {
        /* Not internal, load the DLL and look up C_GetFunctionList */
        if (mod->dllName == NULL) {
            return SECFailure;
        }

        /* load the library. If this succeeds, then we have to remember to
         * unload the library if anything goes wrong from here on out...
         */
        library = PR_LoadLibrary(mod->dllName);
        mod->library = (void *)library;

        if (library == NULL) {
            return SECFailure;
        }

        /*
         * now we need to get the entry point to find the function pointers
         */
        if (!mod->moduleDBOnly) {
            entry = (CK_C_GetFunctionList)
                PR_FindSymbol(library, "C_GetFunctionList");
        }
        if (mod->isModuleDB) {
            mod->moduleDBFunc = (void *)
                PR_FindSymbol(library, "NSS_ReturnModuleSpecData");
        }
        if (mod->moduleDBFunc == NULL)
            mod->isModuleDB = PR_FALSE;
        if (entry == NULL) {
            if (mod->isModuleDB) {
                mod->loaded = PR_TRUE;
                mod->moduleDBOnly = PR_TRUE;
                return SECSuccess;
            }
            PR_UnloadLibrary(library);
            return SECFailure;
        }
    }

    /*
     * We need to get the function list
     */
    if ((*entry)((CK_FUNCTION_LIST_PTR *)&mod->functionList) != CKR_OK)
        goto fail;

#ifdef DEBUG_MODULE
    if (PR_TRUE) {
        modToDBG = PR_GetEnvSecure("NSS_DEBUG_PKCS11_MODULE");
        if (modToDBG && strcmp(mod->commonName, modToDBG) == 0) {
            mod->functionList = (void *)nss_InsertDeviceLog(
                (CK_FUNCTION_LIST_PTR)mod->functionList);
        }
    }
#endif

    mod->isThreadSafe = PR_TRUE;

    /* Now we initialize the module */
    rv = secmod_ModuleInit(mod, oldModule, &alreadyLoaded);
    if (rv != SECSuccess) {
        goto fail;
    }

    /* module has been reloaded, this module itself is done,
     * return to the caller */
    if (mod->functionList == NULL) {
        mod->loaded = PR_TRUE; /* technically the module is loaded.. */
        return SECSuccess;
    }

    /* check the version number */
    if (PK11_GETTAB(mod)->C_GetInfo(&info) != CKR_OK)
        goto fail2;
    if (info.cryptokiVersion.major != 2)
        goto fail2;
    /* all 2.0 are a priori *not* thread safe */
    if (info.cryptokiVersion.minor < 1) {
        if (!loadSingleThreadedModules) {
            PORT_SetError(SEC_ERROR_INCOMPATIBLE_PKCS11);
            goto fail2;
        } else {
            mod->isThreadSafe = PR_FALSE;
        }
    }
    mod->cryptokiVersion = info.cryptokiVersion;

    /* If we don't have a common name, get it from the PKCS 11 module */
    if ((mod->commonName == NULL) || (mod->commonName[0] == 0)) {
        mod->commonName = PK11_MakeString(mod->arena, NULL,
                                          (char *)info.libraryDescription, sizeof(info.libraryDescription));
        if (mod->commonName == NULL)
            goto fail2;
    }

    /* initialize the Slots */
    if (PK11_GETTAB(mod)->C_GetSlotList(CK_FALSE, NULL, &slotCount) == CKR_OK) {
        CK_SLOT_ID *slotIDs;
        int i;
        CK_RV crv;

        mod->slots = (PK11SlotInfo **)PORT_ArenaAlloc(mod->arena,
                                                      sizeof(PK11SlotInfo *) * slotCount);
        if (mod->slots == NULL)
            goto fail2;

        slotIDs = (CK_SLOT_ID *)PORT_Alloc(sizeof(CK_SLOT_ID) * slotCount);
        if (slotIDs == NULL) {
            goto fail2;
        }
        crv = PK11_GETTAB(mod)->C_GetSlotList(CK_FALSE, slotIDs, &slotCount);
        if (crv != CKR_OK) {
            PORT_Free(slotIDs);
            goto fail2;
        }

        /* Initialize each slot */
        for (i = 0; i < (int)slotCount; i++) {
            mod->slots[i] = PK11_NewSlotInfo(mod);
            PK11_InitSlot(mod, slotIDs[i], mod->slots[i]);
            /* look down the slot info table */
            PK11_LoadSlotList(mod->slots[i], mod->slotInfo, mod->slotInfoCount);
            SECMOD_SetRootCerts(mod->slots[i], mod);
            /* explicitly mark the internal slot as such if IsInternalKeySlot()
             * is set */
            if (secmod_IsInternalKeySlot(mod) && (i == (mod->isFIPS ? 0 : 1))) {
                pk11_SetInternalKeySlotIfFirst(mod->slots[i]);
            }
        }
        mod->slotCount = slotCount;
        mod->slotInfoCount = 0;
        PORT_Free(slotIDs);
    }

    mod->loaded = PR_TRUE;
    mod->moduleID = nextModuleID++;
    return SECSuccess;
fail2:
    if (enforceAlreadyInitializedError || (!alreadyLoaded)) {
        PK11_GETTAB(mod)->C_Finalize(NULL);
    }
fail:
    mod->functionList = NULL;
    disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
    if (library && !disableUnload) {
        PR_UnloadLibrary(library);
    }
    return SECFailure;
}
Ejemplo n.º 15
0
int
rmain
(
  int argc,
  char *argv[]
)
{
  char *argv0 = argv[0];
  PRLibrary *lib;
  CK_C_GetFunctionList gfl;
  CK_FUNCTION_LIST_PTR epv = (CK_FUNCTION_LIST_PTR)NULL;
  CK_RV ck_rv;
  CK_INFO info;
  CK_ULONG nSlots;
  CK_SLOT_ID *pSlots;
  CK_ULONG i;
  CK_C_INITIALIZE_ARGS ia, *iap;

  (void)memset(&ia, 0, sizeof(CK_C_INITIALIZE_ARGS));
  iap = (CK_C_INITIALIZE_ARGS *)NULL;
  while( argv++, --argc ) {
    if( '-' == argv[0][0] ) {
      switch( argv[0][1] ) {
      case 'i':
        iap = &ia;
        if( ((char *)NULL != argv[1]) && ('-' != argv[1][0]) ) {
#ifdef WITH_NSS
          ia.pConfig = argv[1];
          ia.ulConfigLen = strlen(argv[1]);
          argv++, --argc;
#else
          return usage(argv0);
#endif /* WITH_NSS */
        }
        break;
      case '-':
        argv++, --argc;
        goto endargs;
      default:
        return usage(argv0);
      }
    } else {
      break;
    }
  }
 endargs:;

  if( 1 != argc ) {
    return usage(argv0);
  }

  lib = PR_LoadLibrary(argv[0]);
  if( (PRLibrary *)NULL == lib ) {
    PR_fprintf(PR_STDERR, "Can't load %s: %ld, %ld\n", argv[1], PR_GetError(), PR_GetOSError());
    return 1;
  }

  gfl = (CK_C_GetFunctionList)PR_FindSymbol(lib, "C_GetFunctionList");
  if( (CK_C_GetFunctionList)NULL == gfl ) {
    PR_fprintf(PR_STDERR, "Can't find C_GetFunctionList in %s: %ld, %ld\n", argv[1], 
               PR_GetError(), PR_GetOSError());
    return 1;
  }

  ck_rv = (*gfl)(&epv);
  if( CKR_OK != ck_rv ) {
    PR_fprintf(PR_STDERR, "CK_GetFunctionList returned 0x%08x\n", ck_rv);
    return 1;
  }

  PR_fprintf(PR_STDOUT, "Module %s loaded, epv = 0x%08x.\n\n", argv[1], (CK_ULONG)epv);

  /* C_Initialize */
  ck_rv = epv->C_Initialize(iap);
  if( CKR_OK != ck_rv ) {
    PR_fprintf(PR_STDERR, "C_Initialize returned 0x%08x\n", ck_rv);
    return 1;
  }

  /* C_GetInfo */
  (void)memset(&info, 0, sizeof(CK_INFO));
  ck_rv = epv->C_GetInfo(&info);
  if( CKR_OK != ck_rv ) {
    PR_fprintf(PR_STDERR, "C_GetInfo returned 0x%08x\n", ck_rv);
    return 1;
  }

  PR_fprintf(PR_STDOUT, "Module Info:\n");
  PR_fprintf(PR_STDOUT, "    cryptokiVersion = %lu.%02lu\n", 
             (PRUint32)info.cryptokiVersion.major, (PRUint32)info.cryptokiVersion.minor);
  PR_fprintf(PR_STDOUT, "    manufacturerID = \"%.32s\"\n", info.manufacturerID);
  PR_fprintf(PR_STDOUT, "    flags = 0x%08lx\n", info.flags);
  PR_fprintf(PR_STDOUT, "    libraryDescription = \"%.32s\"\n", info.libraryDescription);
  PR_fprintf(PR_STDOUT, "    libraryVersion = %lu.%02lu\n", 
             (PRUint32)info.libraryVersion.major, (PRUint32)info.libraryVersion.minor);
  PR_fprintf(PR_STDOUT, "\n");

  /* C_GetSlotList */
  nSlots = 0;
  ck_rv = epv->C_GetSlotList(CK_FALSE, (CK_SLOT_ID_PTR)CK_NULL_PTR, &nSlots);
  switch( ck_rv ) {
  case CKR_BUFFER_TOO_SMALL:
  case CKR_OK:
    break;
  default:
    PR_fprintf(PR_STDERR, "C_GetSlotList(FALSE, NULL, ) returned 0x%08x\n", ck_rv);
    return 1;
  }

  PR_fprintf(PR_STDOUT, "There are %lu slots.\n", nSlots);

  pSlots = (CK_SLOT_ID_PTR)PR_Calloc(nSlots, sizeof(CK_SLOT_ID));
  if( (CK_SLOT_ID_PTR)NULL == pSlots ) {
    PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]\n", nSlots * sizeof(CK_SLOT_ID));
    return 1;
  }

  ck_rv = epv->C_GetSlotList(CK_FALSE, pSlots, &nSlots);
  if( CKR_OK != ck_rv ) {
    PR_fprintf(PR_STDERR, "C_GetSlotList(FALSE, , ) returned 0x%08x\n", ck_rv);
    return 1;
  }

  for( i = 0; i < nSlots; i++ ) {
    PR_fprintf(PR_STDOUT, "    [%lu]: CK_SLOT_ID = %lu\n", (i+1), pSlots[i]);
  }

  PR_fprintf(PR_STDOUT, "\n");

  /* C_GetSlotInfo */
  for( i = 0; i < nSlots; i++ ) {
    CK_SLOT_INFO sinfo;

    PR_fprintf(PR_STDOUT, "[%lu]: CK_SLOT_ID = %lu\n", (i+1), pSlots[i]);

    (void)memset(&sinfo, 0, sizeof(CK_SLOT_INFO));
    ck_rv = epv->C_GetSlotInfo(pSlots[i], &sinfo);
    if( CKR_OK != ck_rv ) {
      PR_fprintf(PR_STDERR, "C_GetSlotInfo(%lu, ) returned 0x%08x\n", pSlots[i], ck_rv);
      return 1;
    }

    PR_fprintf(PR_STDOUT, "    Slot Info:\n");
    PR_fprintf(PR_STDOUT, "        slotDescription = \"%.64s\"\n", sinfo.slotDescription);
    PR_fprintf(PR_STDOUT, "        manufacturerID = \"%.32s\"\n", sinfo.manufacturerID);
    PR_fprintf(PR_STDOUT, "        flags = 0x%08lx\n", sinfo.flags);
    PR_fprintf(PR_STDOUT, "            -> TOKEN PRESENT = %s\n", 
               sinfo.flags & CKF_TOKEN_PRESENT ? "TRUE" : "FALSE");
    PR_fprintf(PR_STDOUT, "            -> REMOVABLE DEVICE = %s\n",
               sinfo.flags & CKF_REMOVABLE_DEVICE ? "TRUE" : "FALSE");
    PR_fprintf(PR_STDOUT, "            -> HW SLOT = %s\n", 
               sinfo.flags & CKF_HW_SLOT ? "TRUE" : "FALSE");
    PR_fprintf(PR_STDOUT, "        hardwareVersion = %lu.%02lu\n", 
               (PRUint32)sinfo.hardwareVersion.major, (PRUint32)sinfo.hardwareVersion.minor);
    PR_fprintf(PR_STDOUT, "        firmwareVersion = %lu.%02lu\n",
               (PRUint32)sinfo.firmwareVersion.major, (PRUint32)sinfo.firmwareVersion.minor);

    if( sinfo.flags & CKF_TOKEN_PRESENT ) {
      CK_TOKEN_INFO tinfo;
      CK_MECHANISM_TYPE *pMechanismList;
      CK_ULONG nMechanisms = 0;
      CK_ULONG j;

      (void)memset(&tinfo, 0, sizeof(CK_TOKEN_INFO));
      ck_rv = epv->C_GetTokenInfo(pSlots[i], &tinfo);
      if( CKR_OK != ck_rv ) {
        PR_fprintf(PR_STDERR, "C_GetTokenInfo(%lu, ) returned 0x%08x\n", pSlots[i], ck_rv);
        return 1;
      }

      PR_fprintf(PR_STDOUT, "    Token Info:\n");
      PR_fprintf(PR_STDOUT, "        label = \"%.32s\"\n", tinfo.label);
      PR_fprintf(PR_STDOUT, "        manufacturerID = \"%.32s\"\n", tinfo.manufacturerID);
      PR_fprintf(PR_STDOUT, "        model = \"%.16s\"\n", tinfo.model);
      PR_fprintf(PR_STDOUT, "        serialNumber = \"%.16s\"\n", tinfo.serialNumber);
      PR_fprintf(PR_STDOUT, "        flags = 0x%08lx\n", tinfo.flags);
      PR_fprintf(PR_STDOUT, "            -> RNG = %s\n",
                 tinfo.flags & CKF_RNG ? "TRUE" : "FALSE");
      PR_fprintf(PR_STDOUT, "            -> WRITE PROTECTED = %s\n",
                 tinfo.flags & CKF_WRITE_PROTECTED ? "TRUE" : "FALSE");
      PR_fprintf(PR_STDOUT, "            -> LOGIN REQUIRED = %s\n",
                 tinfo.flags & CKF_LOGIN_REQUIRED ? "TRUE" : "FALSE");
      PR_fprintf(PR_STDOUT, "            -> USER PIN INITIALIZED = %s\n",
                 tinfo.flags & CKF_USER_PIN_INITIALIZED ? "TRUE" : "FALSE");
      PR_fprintf(PR_STDOUT, "            -> RESTORE KEY NOT NEEDED = %s\n",
                 tinfo.flags & CKF_RESTORE_KEY_NOT_NEEDED ? "TRUE" : "FALSE");
      PR_fprintf(PR_STDOUT, "            -> CLOCK ON TOKEN = %s\n",
                 tinfo.flags & CKF_CLOCK_ON_TOKEN ? "TRUE" : "FALSE");
#ifdef CKF_SUPPORTS_PARALLEL
      PR_fprintf(PR_STDOUT, "            -> SUPPORTS PARALLEL = %s\n",
                 tinfo.flags & CKF_SUPPORTS_PARALLEL ? "TRUE" : "FALSE");
#endif /* CKF_SUPPORTS_PARALLEL */
      PR_fprintf(PR_STDOUT, "            -> PROTECTED AUTHENTICATION PATH = %s\n",
                 tinfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH ? "TRUE" : "FALSE");
      PR_fprintf(PR_STDOUT, "            -> DUAL_CRYPTO_OPERATIONS = %s\n", 
                 tinfo.flags & CKF_DUAL_CRYPTO_OPERATIONS ? "TRUE" : "FALSE");
      PR_fprintf(PR_STDOUT, "        ulMaxSessionCount = %lu\n", tinfo.ulMaxSessionCount);
      PR_fprintf(PR_STDOUT, "        ulSessionCount = %lu\n", tinfo.ulSessionCount);
      PR_fprintf(PR_STDOUT, "        ulMaxRwSessionCount = %lu\n", tinfo.ulMaxRwSessionCount);
      PR_fprintf(PR_STDOUT, "        ulRwSessionCount = %lu\n", tinfo.ulRwSessionCount);
      PR_fprintf(PR_STDOUT, "        ulMaxPinLen = %lu\n", tinfo.ulMaxPinLen);
      PR_fprintf(PR_STDOUT, "        ulMinPinLen = %lu\n", tinfo.ulMinPinLen);
      PR_fprintf(PR_STDOUT, "        ulTotalPublicMemory = %lu\n", tinfo.ulTotalPublicMemory);
      PR_fprintf(PR_STDOUT, "        ulFreePublicMemory = %lu\n", tinfo.ulFreePublicMemory);
      PR_fprintf(PR_STDOUT, "        ulTotalPrivateMemory = %lu\n", tinfo.ulTotalPrivateMemory);
      PR_fprintf(PR_STDOUT, "        ulFreePrivateMemory = %lu\n", tinfo.ulFreePrivateMemory);
      PR_fprintf(PR_STDOUT, "        hardwareVersion = %lu.%02lu\n", 
                 (PRUint32)tinfo.hardwareVersion.major, (PRUint32)tinfo.hardwareVersion.minor);
      PR_fprintf(PR_STDOUT, "        firmwareVersion = %lu.%02lu\n",
                 (PRUint32)tinfo.firmwareVersion.major, (PRUint32)tinfo.firmwareVersion.minor);
      PR_fprintf(PR_STDOUT, "        utcTime = \"%.16s\"\n", tinfo.utcTime);


      ck_rv = epv->C_GetMechanismList(pSlots[i], (CK_MECHANISM_TYPE_PTR)CK_NULL_PTR, &nMechanisms);
      switch( ck_rv ) {
      case CKR_BUFFER_TOO_SMALL:
      case CKR_OK:
        break;
      default:
        PR_fprintf(PR_STDERR, "C_GetMechanismList(%lu, NULL, ) returned 0x%08x\n", pSlots[i], ck_rv);
        return 1;
      }

      PR_fprintf(PR_STDOUT, "    %lu mechanisms:\n", nMechanisms);

      pMechanismList = (CK_MECHANISM_TYPE_PTR)PR_Calloc(nMechanisms, sizeof(CK_MECHANISM_TYPE));
      if( (CK_MECHANISM_TYPE_PTR)NULL == pMechanismList ) {
        PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]\n", 
                   nMechanisms * sizeof(CK_MECHANISM_TYPE));
        return 1;
      }

      ck_rv = epv->C_GetMechanismList(pSlots[i], pMechanismList, &nMechanisms);
      if( CKR_OK != ck_rv ) {
        PR_fprintf(PR_STDERR, "C_GetMechanismList(%lu, , ) returned 0x%08x\n", pSlots[i], ck_rv);
        return 1;
      }

      for( j = 0; j < nMechanisms; j++ ) {
        PR_fprintf(PR_STDOUT, "        {%lu}: CK_MECHANISM_TYPE = %lu\n", (j+1), pMechanismList[j]);
      }

      PR_fprintf(PR_STDOUT, "\n");

      for( j = 0; j < nMechanisms; j++ ) {
        CK_MECHANISM_INFO minfo;

        (void)memset(&minfo, 0, sizeof(CK_MECHANISM_INFO));
        ck_rv = epv->C_GetMechanismInfo(pSlots[i], pMechanismList[j], &minfo);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_GetMechanismInfo(%lu, %lu, ) returned 0x%08x\n", pSlots[i], 
                     pMechanismList[j]);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    [%lu]: CK_MECHANISM_TYPE = %lu\n", (j+1), pMechanismList[j]);
        PR_fprintf(PR_STDOUT, "    ulMinKeySize = %lu\n", minfo.ulMinKeySize);
        PR_fprintf(PR_STDOUT, "    ulMaxKeySize = %lu\n", minfo.ulMaxKeySize);
        PR_fprintf(PR_STDOUT, "    flags = 0x%08x\n", minfo.flags);
        PR_fprintf(PR_STDOUT, "        -> HW = %s\n", minfo.flags & CKF_HW ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> ENCRYPT = %s\n", minfo.flags & CKF_ENCRYPT ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> DECRYPT = %s\n", minfo.flags & CKF_DECRYPT ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> DIGEST = %s\n", minfo.flags & CKF_DIGEST ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> SIGN = %s\n", minfo.flags & CKF_SIGN ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> SIGN_RECOVER = %s\n", minfo.flags & CKF_SIGN_RECOVER ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> VERIFY = %s\n", minfo.flags & CKF_VERIFY ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> VERIFY_RECOVER = %s\n", minfo.flags & CKF_VERIFY_RECOVER ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> GENERATE = %s\n", minfo.flags & CKF_GENERATE ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> GENERATE_KEY_PAIR = %s\n", minfo.flags & CKF_GENERATE_KEY_PAIR ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> WRAP = %s\n", minfo.flags & CKF_WRAP ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> UNWRAP = %s\n", minfo.flags & CKF_UNWRAP ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> DERIVE = %s\n", minfo.flags & CKF_DERIVE ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> EXTENSION = %s\n", minfo.flags & CKF_EXTENSION ? "TRUE" : "FALSE");

        PR_fprintf(PR_STDOUT, "\n");
      }

      if( tinfo.flags & CKF_LOGIN_REQUIRED ) {
        PR_fprintf(PR_STDERR, "*** LOGIN REQUIRED but not yet implemented ***\n");
        /* all the stuff about logging in as SO and setting the user pin if needed, etc. */
        return 2;
      }

      /* session to find objects */
      {
        CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0;
        CK_SESSION_INFO sinfo;
        CK_ATTRIBUTE_PTR pTemplate;
        CK_ULONG tnObjects = 0;

        ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08x\n", pSlots[i], ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Opened a session: handle = 0x%08x\n", h);

        (void)memset(&sinfo, 0, sizeof(CK_SESSION_INFO));
        ck_rv = epv->C_GetSessionInfo(h, &sinfo);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDOUT, "C_GetSessionInfo(%lu, ) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    SESSION INFO:\n");
        PR_fprintf(PR_STDOUT, "        slotID = %lu\n", sinfo.slotID);
        PR_fprintf(PR_STDOUT, "        state = %lu\n", sinfo.state);
        PR_fprintf(PR_STDOUT, "        flags = 0x%08x\n", sinfo.flags);
#ifdef CKF_EXCLUSIVE_SESSION
        PR_fprintf(PR_STDOUT, "            -> EXCLUSIVE SESSION = %s\n", sinfo.flags & CKF_EXCLUSIVE_SESSION ? "TRUE" : "FALSE");
#endif /* CKF_EXCLUSIVE_SESSION */
        PR_fprintf(PR_STDOUT, "            -> RW SESSION = %s\n", sinfo.flags & CKF_RW_SESSION ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "            -> SERIAL SESSION = %s\n", sinfo.flags & CKF_SERIAL_SESSION ? "TRUE" : "FALSE");
#ifdef CKF_INSERTION_CALLBACK
        PR_fprintf(PR_STDOUT, "            -> INSERTION CALLBACK = %s\n", sinfo.flags & CKF_INSERTION_CALLBACK ? "TRUE" : "FALSE");
#endif /* CKF_INSERTION_CALLBACK */
        PR_fprintf(PR_STDOUT, "        ulDeviceError = %lu\n", sinfo.ulDeviceError);
        PR_fprintf(PR_STDOUT, "\n");

        ck_rv = epv->C_FindObjectsInit(h, (CK_ATTRIBUTE_PTR)CK_NULL_PTR, 0);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDOUT, "C_FindObjectsInit(%lu, NULL_PTR, 0) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        pTemplate = (CK_ATTRIBUTE_PTR)PR_Calloc(number_of_all_known_attribute_types, sizeof(CK_ATTRIBUTE));
        if( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) {
          PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]\n", 
                     number_of_all_known_attribute_types * sizeof(CK_ATTRIBUTE));
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    All objects:\n");

        while(1) {
          CK_OBJECT_HANDLE o = (CK_OBJECT_HANDLE)0;
          CK_ULONG nObjects = 0;
          CK_ULONG k;
          CK_ULONG nAttributes = 0;
          CK_ATTRIBUTE_PTR pT2;
          CK_ULONG l;

          ck_rv = epv->C_FindObjects(h, &o, 1, &nObjects);
          if( CKR_OK != ck_rv ) {
            PR_fprintf(PR_STDERR, "C_FindObjects(%lu, , 1, ) returned 0x%08x\n", h, ck_rv);
            return 1;
          }

          if( 0 == nObjects ) {
            PR_fprintf(PR_STDOUT, "\n");
            break;
          }

          tnObjects++;

          PR_fprintf(PR_STDOUT, "        OBJECT HANDLE %lu:\n", o);

          for( k = 0; k < number_of_all_known_attribute_types; k++ ) {
            pTemplate[k].type = all_known_attribute_types[k];
            pTemplate[k].pValue = (CK_VOID_PTR)CK_NULL_PTR;
            pTemplate[k].ulValueLen = 0;
          }

          ck_rv = epv->C_GetAttributeValue(h, o, pTemplate, number_of_all_known_attribute_types);
          switch( ck_rv ) {
          case CKR_OK:
          case CKR_ATTRIBUTE_SENSITIVE:
          case CKR_ATTRIBUTE_TYPE_INVALID:
          case CKR_BUFFER_TOO_SMALL:
            break;
          default:
            PR_fprintf(PR_STDERR, "C_GetAtributeValue(%lu, %lu, {all attribute types}, %lu) returned 0x%08x\n",
                       h, o, number_of_all_known_attribute_types, ck_rv);
            return 1;
          }

          for( k = 0; k < number_of_all_known_attribute_types; k++ ) {
            if( -1 != (CK_LONG)pTemplate[k].ulValueLen ) {
              nAttributes++;
            }
          }

          if( 1 ) {
            PR_fprintf(PR_STDOUT, "            %lu attributes:\n", nAttributes);
            for( k = 0; k < number_of_all_known_attribute_types; k++ ) {
              if( -1 != (CK_LONG)pTemplate[k].ulValueLen ) {
                PR_fprintf(PR_STDOUT, "                0x%08x (len = %lu)\n", pTemplate[k].type, 
                           pTemplate[k].ulValueLen);
              }
            }
            PR_fprintf(PR_STDOUT, "\n");
          }

          pT2 = (CK_ATTRIBUTE_PTR)PR_Calloc(nAttributes, sizeof(CK_ATTRIBUTE));
          if( (CK_ATTRIBUTE_PTR)NULL == pT2 ) {
            PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]\n", 
                       nAttributes * sizeof(CK_ATTRIBUTE));
            return 1;
          }

          for( l = 0, k = 0; k < number_of_all_known_attribute_types; k++ ) {
            if( -1 != (CK_LONG)pTemplate[k].ulValueLen ) {
              pT2[l].type = pTemplate[k].type;
              pT2[l].ulValueLen = pTemplate[k].ulValueLen;
              pT2[l].pValue = (CK_VOID_PTR)PR_Malloc(pT2[l].ulValueLen);
              if( (CK_VOID_PTR)NULL == pT2[l].pValue ) {
                PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]\n", pT2[l].ulValueLen);
                return 1;
              }
              l++;
            }
          }

          PR_ASSERT( l == nAttributes );

          ck_rv = epv->C_GetAttributeValue(h, o, pT2, nAttributes);
          switch( ck_rv ) {
          case CKR_OK:
          case CKR_ATTRIBUTE_SENSITIVE:
          case CKR_ATTRIBUTE_TYPE_INVALID:
          case CKR_BUFFER_TOO_SMALL:
            break;
          default:
            PR_fprintf(PR_STDERR, "C_GetAtributeValue(%lu, %lu, {existent attribute types}, %lu) returned 0x%08x\n",
                       h, o, nAttributes, ck_rv);
            return 1;
          }

          for( l = 0; l < nAttributes; l++ ) {
            PR_fprintf(PR_STDOUT, "            type = 0x%08x, len = %ld", pT2[l].type, (CK_LONG)pT2[l].ulValueLen);
            if( -1 == (CK_LONG)pT2[l].ulValueLen ) {
              ;
            } else {
              CK_ULONG m;

              if( pT2[l].ulValueLen <= 8 ) {
                PR_fprintf(PR_STDOUT, ", value = ");
              } else {
                PR_fprintf(PR_STDOUT, ", value = \n                ");
              }

              for( m = 0; (m < pT2[l].ulValueLen) && (m < 20); m++ ) {
                PR_fprintf(PR_STDOUT, "%02x", (CK_ULONG)(0xff & ((CK_CHAR_PTR)pT2[l].pValue)[m]));
              }

              PR_fprintf(PR_STDOUT, " ");

              for( m = 0; (m < pT2[l].ulValueLen) && (m < 20); m++ ) {
                CK_CHAR c = ((CK_CHAR_PTR)pT2[l].pValue)[m];
                if( (c < 0x20) || (c >= 0x7f) ) {
                  c = '.';
                }
                PR_fprintf(PR_STDOUT, "%c", c);
              }
            }

            PR_fprintf(PR_STDOUT, "\n");
          }
          
          PR_fprintf(PR_STDOUT, "\n");

          for( l = 0; l < nAttributes; l++ ) {
            PR_Free(pT2[l].pValue);
          }
          PR_Free(pT2);
        } /* while(1) */

        ck_rv = epv->C_FindObjectsFinal(h);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    (%lu objects total)\n", tnObjects);

        ck_rv = epv->C_CloseSession(h);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_CloseSession(%lu) returned 0x%08x\n", h, ck_rv);
          return 1;
        }
      } /* session to find objects */

      /* session to create, find, and delete a couple session objects */
      {
        CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0;
        CK_ATTRIBUTE one[7], two[7], three[7], delta[1], mask[1];
        CK_OBJECT_CLASS cko_data = CKO_DATA;
        CK_BBOOL false = CK_FALSE, true = CK_TRUE;
        char *key = "TEST PROGRAM";
        CK_ULONG key_len = strlen(key);
        CK_OBJECT_HANDLE hOneIn = (CK_OBJECT_HANDLE)0, hTwoIn = (CK_OBJECT_HANDLE)0, 
          hThreeIn = (CK_OBJECT_HANDLE)0, hDeltaIn = (CK_OBJECT_HANDLE)0;
        CK_OBJECT_HANDLE found[10];
        CK_ULONG nFound;

        ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08x\n", pSlots[i], ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Opened a session: handle = 0x%08x\n", h);

        one[0].type = CKA_CLASS;
        one[0].pValue = &cko_data;
        one[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
        one[1].type = CKA_TOKEN;
        one[1].pValue = &false;
        one[1].ulValueLen = sizeof(CK_BBOOL);
        one[2].type = CKA_PRIVATE;
        one[2].pValue = &false;
        one[2].ulValueLen = sizeof(CK_BBOOL);
        one[3].type = CKA_MODIFIABLE;
        one[3].pValue = &true;
        one[3].ulValueLen = sizeof(CK_BBOOL);
        one[4].type = CKA_LABEL;
        one[4].pValue = "Test data object one";
        one[4].ulValueLen = strlen(one[4].pValue);
        one[5].type = CKA_APPLICATION;
        one[5].pValue = key;
        one[5].ulValueLen = key_len;
        one[6].type = CKA_VALUE;
        one[6].pValue = "Object one";
        one[6].ulValueLen = strlen(one[6].pValue);

        two[0].type = CKA_CLASS;
        two[0].pValue = &cko_data;
        two[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
        two[1].type = CKA_TOKEN;
        two[1].pValue = &false;
        two[1].ulValueLen = sizeof(CK_BBOOL);
        two[2].type = CKA_PRIVATE;
        two[2].pValue = &false;
        two[2].ulValueLen = sizeof(CK_BBOOL);
        two[3].type = CKA_MODIFIABLE;
        two[3].pValue = &true;
        two[3].ulValueLen = sizeof(CK_BBOOL);
        two[4].type = CKA_LABEL;
        two[4].pValue = "Test data object two";
        two[4].ulValueLen = strlen(two[4].pValue);
        two[5].type = CKA_APPLICATION;
        two[5].pValue = key;
        two[5].ulValueLen = key_len;
        two[6].type = CKA_VALUE;
        two[6].pValue = "Object two";
        two[6].ulValueLen = strlen(two[6].pValue);

        three[0].type = CKA_CLASS;
        three[0].pValue = &cko_data;
        three[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
        three[1].type = CKA_TOKEN;
        three[1].pValue = &false;
        three[1].ulValueLen = sizeof(CK_BBOOL);
        three[2].type = CKA_PRIVATE;
        three[2].pValue = &false;
        three[2].ulValueLen = sizeof(CK_BBOOL);
        three[3].type = CKA_MODIFIABLE;
        three[3].pValue = &true;
        three[3].ulValueLen = sizeof(CK_BBOOL);
        three[4].type = CKA_LABEL;
        three[4].pValue = "Test data object three";
        three[4].ulValueLen = strlen(three[4].pValue);
        three[5].type = CKA_APPLICATION;
        three[5].pValue = key;
        three[5].ulValueLen = key_len;
        three[6].type = CKA_VALUE;
        three[6].pValue = "Object three";
        three[6].ulValueLen = strlen(three[6].pValue);

        ck_rv = epv->C_CreateObject(h, one, 7, &hOneIn);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_CreateObject(%lu, one, 7, ) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Created object one: handle = %lu\n", hOneIn);

        ck_rv = epv->C_CreateObject(h, two, 7, &hTwoIn);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_CreateObject(%lu, two, 7, ) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Created object two: handle = %lu\n", hTwoIn);

        ck_rv = epv->C_CreateObject(h, three, 7, &hThreeIn);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_CreateObject(%lu, three, 7, ) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Created object three: handle = %lu\n", hThreeIn);

        delta[0].type = CKA_VALUE;
        delta[0].pValue = "Copied object";
        delta[0].ulValueLen = strlen(delta[0].pValue);

        ck_rv = epv->C_CopyObject(h, hThreeIn, delta, 1, &hDeltaIn);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_CopyObject(%lu, %lu, delta, 1, ) returned 0x%08x\n", 
                     h, hThreeIn, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Copied object three: new handle = %lu\n", hDeltaIn);

        mask[0].type = CKA_APPLICATION;
        mask[0].pValue = key;
        mask[0].ulValueLen = key_len;

        ck_rv = epv->C_FindObjectsInit(h, mask, 1);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 1) returned 0x%08x\n", 
                     h, ck_rv);
          return 1;
        }

        (void)memset(&found, 0, sizeof(found));
        nFound = 0;
        ck_rv = epv->C_FindObjects(h, found, 10, &nFound);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08x\n", 
                     h, ck_rv);
          return 1;
        }

        if( 4 != nFound ) {
          PR_fprintf(PR_STDERR, "Found %lu objects, not 4.\n", nFound);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Found 4 objects: %lu, %lu, %lu, %lu\n", 
                   found[0], found[1], found[2], found[3]);

        ck_rv = epv->C_FindObjectsFinal(h);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        ck_rv = epv->C_DestroyObject(h, hThreeIn);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_DestroyObject(%lu, %lu) returned 0x%08x\n", h, hThreeIn, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Destroyed object three (handle = %lu)\n", hThreeIn);

        delta[0].type = CKA_APPLICATION;
        delta[0].pValue = "Changed application";
        delta[0].ulValueLen = strlen(delta[0].pValue);

        ck_rv = epv->C_SetAttributeValue(h, hTwoIn, delta, 1);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_SetAttributeValue(%lu, %lu, delta, 1) returned 0x%08x\n", 
                     h, hTwoIn, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Changed object two (handle = %lu).\n", hTwoIn);

        /* Can another session find these session objects? */
        {
          CK_SESSION_HANDLE h2 = (CK_SESSION_HANDLE)0;

          ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h2);
          if( CKR_OK != ck_rv ) {
            PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08x\n", pSlots[i], ck_rv);
            return 1;
          }

          PR_fprintf(PR_STDOUT, "    Opened a second session: handle = 0x%08x\n", h2);

          /* mask is still the same */

          ck_rv = epv->C_FindObjectsInit(h2, mask, 1);
          if( CKR_OK != ck_rv ) {
            PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 1) returned 0x%08x\n", 
                       h2, ck_rv);
            return 1;
          }

          (void)memset(&found, 0, sizeof(found));
          nFound = 0;
          ck_rv = epv->C_FindObjects(h2, found, 10, &nFound);
          if( CKR_OK != ck_rv ) {
            PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08x\n", 
                       h2, ck_rv);
            return 1;
          }

          if( 2 != nFound ) {
            PR_fprintf(PR_STDERR, "Found %lu objects, not 2.\n", nFound);
            return 1;
          }

          PR_fprintf(PR_STDOUT, "    Found 2 objects: %lu, %lu\n", 
                     found[0], found[1]);

          ck_rv = epv->C_FindObjectsFinal(h2);
          if( CKR_OK != ck_rv ) {
            PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h2, ck_rv);
            return 1;
          }

          /* Leave the session hanging open, we'll CloseAllSessions later */
        } /* Can another session find these session objects? */

        ck_rv = epv->C_CloseAllSessions(pSlots[i]);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_CloseAllSessions(%lu) returned 0x%08x\n", pSlots[i], ck_rv);
          return 1;
        }
      } /* session to create, find, and delete a couple session objects */

      /* Might be interesting to do a find here to verify that all session objects are gone. */

      if( tinfo.flags & CKF_WRITE_PROTECTED ) {
        PR_fprintf(PR_STDOUT, "Token is write protected, skipping token-object tests.\n");
      } else {
        CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0;
        CK_ATTRIBUTE tobj[7], tsobj[7], stobj[7], delta[1], mask[2];
        CK_OBJECT_CLASS cko_data = CKO_DATA;
        CK_BBOOL false = CK_FALSE, true = CK_TRUE;
        char *key = "TEST PROGRAM";
        CK_ULONG key_len = strlen(key);
        CK_OBJECT_HANDLE hTIn = (CK_OBJECT_HANDLE)0, hTSIn = (CK_OBJECT_HANDLE)0, 
          hSTIn = (CK_OBJECT_HANDLE)0, hDeltaIn = (CK_OBJECT_HANDLE)0;
        CK_OBJECT_HANDLE found[10];
        CK_ULONG nFound;

        ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08x\n", pSlots[i], ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Opened a session: handle = 0x%08x\n", h);

        tobj[0].type = CKA_CLASS;
        tobj[0].pValue = &cko_data;
        tobj[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
        tobj[1].type = CKA_TOKEN;
        tobj[1].pValue = &true;
        tobj[1].ulValueLen = sizeof(CK_BBOOL);
        tobj[2].type = CKA_PRIVATE;
        tobj[2].pValue = &false;
        tobj[2].ulValueLen = sizeof(CK_BBOOL);
        tobj[3].type = CKA_MODIFIABLE;
        tobj[3].pValue = &true;
        tobj[3].ulValueLen = sizeof(CK_BBOOL);
        tobj[4].type = CKA_LABEL;
        tobj[4].pValue = "Test data object token";
        tobj[4].ulValueLen = strlen(tobj[4].pValue);
        tobj[5].type = CKA_APPLICATION;
        tobj[5].pValue = key;
        tobj[5].ulValueLen = key_len;
        tobj[6].type = CKA_VALUE;
        tobj[6].pValue = "Object token";
        tobj[6].ulValueLen = strlen(tobj[6].pValue);

        tsobj[0].type = CKA_CLASS;
        tsobj[0].pValue = &cko_data;
        tsobj[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
        tsobj[1].type = CKA_TOKEN;
        tsobj[1].pValue = &true;
        tsobj[1].ulValueLen = sizeof(CK_BBOOL);
        tsobj[2].type = CKA_PRIVATE;
        tsobj[2].pValue = &false;
        tsobj[2].ulValueLen = sizeof(CK_BBOOL);
        tsobj[3].type = CKA_MODIFIABLE;
        tsobj[3].pValue = &true;
        tsobj[3].ulValueLen = sizeof(CK_BBOOL);
        tsobj[4].type = CKA_LABEL;
        tsobj[4].pValue = "Test data object token->session";
        tsobj[4].ulValueLen = strlen(tsobj[4].pValue);
        tsobj[5].type = CKA_APPLICATION;
        tsobj[5].pValue = key;
        tsobj[5].ulValueLen = key_len;
        tsobj[6].type = CKA_VALUE;
        tsobj[6].pValue = "Object token->session";
        tsobj[6].ulValueLen = strlen(tsobj[6].pValue);

        stobj[0].type = CKA_CLASS;
        stobj[0].pValue = &cko_data;
        stobj[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
        stobj[1].type = CKA_TOKEN;
        stobj[1].pValue = &false;
        stobj[1].ulValueLen = sizeof(CK_BBOOL);
        stobj[2].type = CKA_PRIVATE;
        stobj[2].pValue = &false;
        stobj[2].ulValueLen = sizeof(CK_BBOOL);
        stobj[3].type = CKA_MODIFIABLE;
        stobj[3].pValue = &true;
        stobj[3].ulValueLen = sizeof(CK_BBOOL);
        stobj[4].type = CKA_LABEL;
        stobj[4].pValue = "Test data object session->token";
        stobj[4].ulValueLen = strlen(stobj[4].pValue);
        stobj[5].type = CKA_APPLICATION;
        stobj[5].pValue = key;
        stobj[5].ulValueLen = key_len;
        stobj[6].type = CKA_VALUE;
        stobj[6].pValue = "Object session->token";
        stobj[6].ulValueLen = strlen(stobj[6].pValue);

        ck_rv = epv->C_CreateObject(h, tobj, 7, &hTIn);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_CreateObject(%lu, tobj, 7, ) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Created object token: handle = %lu\n", hTIn);

        ck_rv = epv->C_CreateObject(h, tsobj, 7, &hTSIn);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_CreateObject(%lu, tobj, 7, ) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Created object token->session: handle = %lu\n", hTSIn);
        ck_rv = epv->C_CreateObject(h, stobj, 7, &hSTIn);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_CreateObject(%lu, tobj, 7, ) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Created object session->token: handle = %lu\n", hSTIn);

        /* I've created two token objects and one session object; find the two */

        mask[0].type = CKA_APPLICATION;
        mask[0].pValue = key;
        mask[0].ulValueLen = key_len;
        mask[1].type = CKA_TOKEN;
        mask[1].pValue = &true;
        mask[1].ulValueLen = sizeof(CK_BBOOL);

        ck_rv = epv->C_FindObjectsInit(h, mask, 2);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 2) returned 0x%08x\n", 
                     h, ck_rv);
          return 1;
        }

        (void)memset(&found, 0, sizeof(found));
        nFound = 0;
        ck_rv = epv->C_FindObjects(h, found, 10, &nFound);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08x\n", 
                     h, ck_rv);
          return 1;
        }

        if( 2 != nFound ) {
          PR_fprintf(PR_STDERR, "Found %lu objects, not 2.\n", nFound);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Found 2 objects: %lu, %lu\n", 
                   found[0], found[1]);

        ck_rv = epv->C_FindObjectsFinal(h);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        /* Convert a token to session object */

        delta[0].type = CKA_TOKEN;
        delta[0].pValue = &false;
        delta[0].ulValueLen = sizeof(CK_BBOOL);

        ck_rv = epv->C_SetAttributeValue(h, hTSIn, delta, 1);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_SetAttributeValue(%lu, %lu, delta, 1) returned 0x%08x\n", 
                     h, hTSIn, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Changed object from token to session (handle = %lu).\n", hTSIn);

        /* Now find again; there should be one */

        mask[0].type = CKA_APPLICATION;
        mask[0].pValue = key;
        mask[0].ulValueLen = key_len;
        mask[1].type = CKA_TOKEN;
        mask[1].pValue = &true;
        mask[1].ulValueLen = sizeof(CK_BBOOL);

        ck_rv = epv->C_FindObjectsInit(h, mask, 2);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 2) returned 0x%08x\n", 
                     h, ck_rv);
          return 1;
        }

        (void)memset(&found, 0, sizeof(found));
        nFound = 0;
        ck_rv = epv->C_FindObjects(h, found, 10, &nFound);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08x\n", 
                     h, ck_rv);
          return 1;
        }

        if( 1 != nFound ) {
          PR_fprintf(PR_STDERR, "Found %lu objects, not 1.\n", nFound);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Found 1 objects: %lu\n", 
                   found[0]);

        ck_rv = epv->C_FindObjectsFinal(h);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        /* Convert a session to a token object */

        delta[0].type = CKA_TOKEN;
        delta[0].pValue = &true;
        delta[0].ulValueLen = sizeof(CK_BBOOL);

        ck_rv = epv->C_SetAttributeValue(h, hSTIn, delta, 1);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_SetAttributeValue(%lu, %lu, delta, 1) returned 0x%08x\n", 
                     h, hSTIn, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Changed object from session to token (handle = %lu).\n", hSTIn);

        /* Now find again; there should be two again */

        mask[0].type = CKA_APPLICATION;
        mask[0].pValue = key;
        mask[0].ulValueLen = key_len;
        mask[1].type = CKA_TOKEN;
        mask[1].pValue = &true;
        mask[1].ulValueLen = sizeof(CK_BBOOL);

        ck_rv = epv->C_FindObjectsInit(h, mask, 2);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 2) returned 0x%08x\n", 
                     h, ck_rv);
          return 1;
        }

        (void)memset(&found, 0, sizeof(found));
        nFound = 0;
        ck_rv = epv->C_FindObjects(h, found, 10, &nFound);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08x\n", 
                     h, ck_rv);
          return 1;
        }

        if( 2 != nFound ) {
          PR_fprintf(PR_STDERR, "Found %lu objects, not 2.\n", nFound);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Found 2 objects: %lu, %lu\n", 
                   found[0], found[1]);

        ck_rv = epv->C_FindObjectsFinal(h);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        /* Delete the two (found) token objects to clean up */

        ck_rv = epv->C_DestroyObject(h, found[0]);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_DestroyObject(%lu, %lu) returned 0x%08x\n", h, found[0], ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Destroyed token object (handle = %lu)\n", found[0]);

        ck_rv = epv->C_DestroyObject(h, found[1]);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_DestroyObject(%lu, %lu) returned 0x%08x\n", h, found[1], ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Destroyed token object (handle = %lu)\n", found[1]);
        
        /* Close the session and all objects should be gone */

        ck_rv = epv->C_CloseSession(h);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_CloseSession(%lu) returned 0x%08x\n", h, ck_rv);
          return 1;
        }
      } /* if( tinfo.flags & CKF_WRITE_PROTECTED ) */

      if( tinfo.flags & CKF_WRITE_PROTECTED ) {
        PR_fprintf(PR_STDOUT, "Token is write protected, skipping leaving a record.\n");
      } else {
        CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0;
        CK_ATTRIBUTE record[7], mask[2];
        CK_OBJECT_CLASS cko_data = CKO_DATA;
        CK_BBOOL false = CK_FALSE, true = CK_TRUE;
        char *key = "TEST RECORD";
        CK_ULONG key_len = strlen(key);
        CK_OBJECT_HANDLE hin = (CK_OBJECT_HANDLE)0;
        char timebuffer[256];

        ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08x\n", pSlots[i], ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Opened a session: handle = 0x%08x\n", h);

        /* I can't believe how hard NSPR makes this operation */
        {
          time_t now = 0;
          struct tm *tm;
          time(&now);
          tm = localtime(&now);
          strftime(timebuffer, sizeof(timebuffer), "%Y-%m-%d %T %Z", tm);
        }

        record[0].type = CKA_CLASS;
        record[0].pValue = &cko_data;
        record[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
        record[1].type = CKA_TOKEN;
        record[1].pValue = &true;
        record[1].ulValueLen = sizeof(CK_BBOOL);
        record[2].type = CKA_PRIVATE;
        record[2].pValue = &false;
        record[2].ulValueLen = sizeof(CK_BBOOL);
        record[3].type = CKA_MODIFIABLE;
        record[3].pValue = &true;
        record[3].ulValueLen = sizeof(CK_BBOOL);
        record[4].type = CKA_LABEL;
        record[4].pValue = "Test record";
        record[4].ulValueLen = strlen(record[4].pValue);
        record[5].type = CKA_APPLICATION;
        record[5].pValue = key;
        record[5].ulValueLen = key_len;
        record[6].type = CKA_VALUE;
        record[6].pValue = timebuffer;
        record[6].ulValueLen = strlen(timebuffer)+1;

        PR_fprintf(PR_STDOUT, "    Timestamping with \"%s\"\n", timebuffer);

        ck_rv = epv->C_CreateObject(h, record, 7, &hin);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_CreateObject(%lu, tobj, 7, ) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Created record object: handle = %lu\n", hin);
        
        PR_fprintf(PR_STDOUT, "   == All test timestamps ==\n");

        mask[0].type = CKA_CLASS;
        mask[0].pValue = &cko_data;
        mask[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
        mask[1].type = CKA_APPLICATION;
        mask[1].pValue = key;
        mask[1].ulValueLen = key_len;

        ck_rv = epv->C_FindObjectsInit(h, mask, 2);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 1) returned 0x%08x\n", 
                     h, ck_rv);
          return 1;
        }

        while( 1 ) {
          CK_OBJECT_HANDLE o = (CK_OBJECT_HANDLE)0;
          CK_ULONG nObjects = 0;
          CK_ATTRIBUTE value[1];
          char buffer[1024];

          ck_rv = epv->C_FindObjects(h, &o, 1, &nObjects);
          if( CKR_OK != ck_rv ) {
            PR_fprintf(PR_STDERR, "C_FindObjects(%lu, , 1, ) returned 0x%08x\n", h, ck_rv);
            return 1;
          }

          if( 0 == nObjects ) {
            PR_fprintf(PR_STDOUT, "\n");
            break;
          }

          value[0].type = CKA_VALUE;
          value[0].pValue = buffer;
          value[0].ulValueLen = sizeof(buffer);

          ck_rv = epv->C_GetAttributeValue(h, o, value, 1);
          switch( ck_rv ) {
          case CKR_OK:
            PR_fprintf(PR_STDOUT, "    %s\n", value[0].pValue);
            break;
          case CKR_ATTRIBUTE_SENSITIVE:
            PR_fprintf(PR_STDOUT, "    [Sensitive???]\n");
            break;
          case CKR_ATTRIBUTE_TYPE_INVALID:
            PR_fprintf(PR_STDOUT, "    [Invalid attribute???]\n");
            break;
          case CKR_BUFFER_TOO_SMALL:
            PR_fprintf(PR_STDOUT, "    (result > 1k (%lu))\n", value[0].ulValueLen);
            break;
          default:
            PR_fprintf(PR_STDERR, "C_GetAtributeValue(%lu, %lu, CKA_VALUE, 1) returned 0x%08x\n",
                       h, o);
            return 1;
          }
        } /* while */

        ck_rv = epv->C_FindObjectsFinal(h);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h, ck_rv);
          return 1;
        }
      } /* "leaving a record" else clause */

    }

    PR_fprintf(PR_STDOUT, "\n");
  }

  return 0;
}
Ejemplo n.º 16
0
/**
* This can't be implemented directly with QT.
* (We can use QSound to play local files but that was not enough.
* Also support of media formats is limited)
*
* Current implementation is copied from GTK side and implementation uses ESD interface.
*
* If we have Qtopia then we can drop ESD implementation and use Qtopia "Multimedia API"
*/
NS_IMETHODIMP nsSound::OnStreamComplete(nsIStreamLoader *aLoader,
                                        nsISupports *context,
                                        nsresult aStatus,
                                        PRUint32 dataLen,
                                        const PRUint8 *data)
{

#define GET_WORD(s, i) (s[i+1] << 8) | s[i]
#define GET_DWORD(s, i) (s[i+3] << 24) | (s[i+2] << 16) | (s[i+1] << 8) | s[i]

    // print a load error on bad status, and return
    if (NS_FAILED(aStatus)) {
#ifdef DEBUG
        if (aLoader) {
            nsCOMPtr<nsIRequest> request;
            aLoader->GetRequest(getter_AddRefs(request));
            if (request) {
                nsCOMPtr<nsIURI> uri;
                nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
                if (channel) {
                      channel->GetURI(getter_AddRefs(uri));
                      if (uri) {
                            nsCAutoString uriSpec;
                            uri->GetSpec(uriSpec);
                            printf("Failed to load %s\n", uriSpec.get());
                      }
                }
            }
        }
#endif
        return aStatus;
    }

    int fd, mask = 0;
    PRUint32 samples_per_sec = 0, avg_bytes_per_sec = 0, chunk_len = 0;
    PRUint16 format, channels = 1, bits_per_sample = 0;
    const PRUint8 *audio = nsnull;
    size_t audio_len = 0;

    if (dataLen < 4) {
        NS_WARNING("Sound stream too short to determine its type");
        return NS_ERROR_FAILURE;
    }

    if (memcmp(data, "RIFF", 4)) {
#ifdef DEBUG
        printf("We only support WAV files currently.\n");
#endif
        return NS_ERROR_FAILURE;
    }

    if (dataLen <= WAV_MIN_LENGTH) {
        NS_WARNING("WAV files should be longer than 44 bytes.");
        return NS_ERROR_FAILURE;
    }

    PRUint32 i = 12;
    while (i + 7 < dataLen) {
        if (!memcmp(data + i, "fmt ", 4) && !chunk_len) {
            i += 4;

            /* length of the rest of this subblock (should be 16 for PCM data */
            chunk_len = GET_DWORD(data, i);
            i += 4;

            if (chunk_len < 16 || i + chunk_len >= dataLen) {
                NS_WARNING("Invalid WAV file: bad fmt chunk.");
                return NS_ERROR_FAILURE;
            }

            format = GET_WORD(data, i);
            i += 2;

            channels = GET_WORD(data, i);
            i += 2;

            samples_per_sec = GET_DWORD(data, i);
            i += 4;

            avg_bytes_per_sec = GET_DWORD(data, i);
            i += 4;

            // block align
            i += 2;

            bits_per_sample = GET_WORD(data, i);
            i += 2;

            /* we don't support WAVs with odd compression codes */
            if (chunk_len != 16)
                NS_WARNING("Extra format bits found in WAV. Ignoring");

            i += chunk_len - 16;
        } else if (!memcmp(data + i, "data", 4)) {
            i += 4;
            if (!chunk_len) {
                NS_WARNING("Invalid WAV file: no fmt chunk found");
                return NS_ERROR_FAILURE;
            }

            audio_len = GET_DWORD(data, i);
            i += 4;

            /* try to play truncated WAVs */
            if (i + audio_len > dataLen)
                audio_len = dataLen - i;

            audio = data + i;
            break;
        } else {
            i += 4;
            i += GET_DWORD(data, i);
            i += 4;
        }
    }

    if (!audio) {
        NS_WARNING("Invalid WAV file: no data chunk found");
        return NS_ERROR_FAILURE;
    }

    /* No audio data? well, at least the WAV was valid. */
    if (!audio_len)
        return NS_OK;

#if 0
    printf("f: %d | c: %d | sps: %li | abps: %li | ba: %d | bps: %d | rate: %li\n",
         format, channels, samples_per_sec, avg_bytes_per_sec, block_align, bits_per_sample, rate);
#endif

    /* open up connection to esd */  
    EsdPlayStreamType EsdPlayStream = 
        (EsdPlayStreamType) PR_FindFunctionSymbol(elib, 
                                                  "esd_play_stream");
    if (!EsdPlayStream)
        return NS_ERROR_FAILURE;

    mask = ESD_PLAY | ESD_STREAM;

    if (bits_per_sample == 8)
        mask |= ESD_BITS8;
    else 
        mask |= ESD_BITS16;

    if (channels == 1)
        mask |= ESD_MONO;
    else 
        mask |= ESD_STEREO;

    nsAutoArrayPtr<PRUint8> buf;

    // ESD only handle little-endian data. 
    // Swap the byte order if we're on a big-endian architecture.
#ifdef IS_BIG_ENDIAN
    if (bits_per_sample != 8) {
        buf = new PRUint8[audio_len];
        if (!buf)
            return NS_ERROR_OUT_OF_MEMORY;
        for (PRUint32 j = 0; j + 2 < audio_len; j += 2) {
            buf[j]     = audio[j + 1];
            buf[j + 1] = audio[j];
        }

    audio = buf;
    }
#endif

    fd = (*EsdPlayStream)(mask, samples_per_sec, NULL, "mozillaSound"); 
  
    if (fd < 0) {
      int *esd_audio_format = (int *) PR_FindSymbol(elib, "esd_audio_format");
      int *esd_audio_rate = (int *) PR_FindSymbol(elib, "esd_audio_rate");
      EsdAudioOpenType EsdAudioOpen = (EsdAudioOpenType) PR_FindFunctionSymbol(elib, "esd_audio_open");
      EsdAudioWriteType EsdAudioWrite = (EsdAudioWriteType) PR_FindFunctionSymbol(elib, "esd_audio_write");
      EsdAudioCloseType EsdAudioClose = (EsdAudioCloseType) PR_FindFunctionSymbol(elib, "esd_audio_close");

      if (!esd_audio_format || !esd_audio_rate ||
          !EsdAudioOpen || !EsdAudioWrite || !EsdAudioClose)
          return NS_ERROR_FAILURE;

      *esd_audio_format = mask;
      *esd_audio_rate = samples_per_sec;
      fd = (*EsdAudioOpen)();

      if (fd < 0)
        return NS_ERROR_FAILURE;

      (*EsdAudioWrite)(audio, audio_len);
      (*EsdAudioClose)();
    } else {
      while (audio_len > 0) {
        size_t written = write(fd, audio, audio_len);
        if (written <= 0)
          break;
        audio += written;
        audio_len -= written;
      }
      close(fd);
    }

    return NS_OK;
}
const mozilla::Module*
nsNativeModuleLoader::LoadModule(nsILocalFile* aFile)
{
    nsresult rv;

    if (!NS_IsMainThread()) {
        // If this call is off the main thread, synchronously proxy it
        // to the main thread.
        nsRefPtr<LoadModuleMainThreadRunnable> r = new LoadModuleMainThreadRunnable(this, aFile);
        NS_DispatchToMainThread(r, NS_DISPATCH_SYNC);
        return r->mResult;
    }

    nsCOMPtr<nsIHashable> hashedFile(do_QueryInterface(aFile));
    if (!hashedFile) {
        NS_ERROR("nsIFile is not nsIHashable");
        return NULL;
    }

    nsCAutoString filePath;
    aFile->GetNativePath(filePath);

    NativeLoadData data;

    if (mLibraries.Get(hashedFile, &data)) {
        NS_ASSERTION(data.module, "Corrupt mLibraries hash");
        LOG(PR_LOG_DEBUG,
            ("nsNativeModuleLoader::LoadModule(\"%s\") - found in cache",
             filePath.get()));
        return data.module;
    }

    // We haven't loaded this module before

    rv = aFile->Load(&data.library);

    if (NS_FAILED(rv)) {
        char errorMsg[1024] = "<unknown; can't get error from NSPR>";

        if (PR_GetErrorTextLength() < (int) sizeof(errorMsg))
            PR_GetErrorText(errorMsg);

        LogMessage("Failed to load native module at path '%s': (%lx) %s",
                   filePath.get(), rv, errorMsg);

        return NULL;
    }

#ifdef IMPLEMENT_BREAK_AFTER_LOAD
    nsCAutoString leafName;
    aFile->GetNativeLeafName(leafName);

    char *env = getenv("XPCOM_BREAK_ON_LOAD");
    char *blist;
    if (env && *env && (blist = strdup(env))) {
        char *nextTok = blist;
        while (char *token = NS_strtok(":", &nextTok)) {
            if (leafName.Find(token, true) != kNotFound) {
                NS_BREAK();
            }
        }

        free(blist);
    }
#endif

    void *module = PR_FindSymbol(data.library, "NSModule");
    if (!module) {
        LogMessage("Native module at path '%s' doesn't export symbol `NSModule`.",
                   filePath.get());
        PR_UnloadLibrary(data.library);
        return NULL;
    }

    data.module = *(mozilla::Module const *const *) module;
    if (mozilla::Module::kVersion != data.module->mVersion) {
        LogMessage("Native module at path '%s' is incompatible with this version of Firefox, has version %i, expected %i.",
                   filePath.get(), data.module->mVersion,
                   mozilla::Module::kVersion);
        PR_UnloadLibrary(data.library);
        return NULL;
    }
        
    mLibraries.Put(hashedFile, data); // infallible
    return data.module;
}
int main(int argc, char **argv)
{
    PRIntn rv = 1;
    PLOptStatus os;
    PRIntn verbosity = 0;
    PRLibrary *runtime = NULL;
    const char *library_name = NULL;
    const PRVersionDescription *version_info;
	char buffer[100];
	PRExplodedTime exploded;
    PLOptState *opt = PL_CreateOptState(argc, argv, "d");

    PRFileDesc *err = PR_GetSpecialFD(PR_StandardError);

    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
    {
        if (PL_OPT_BAD == os) continue;
        switch (opt->option)
        {
        case 0:  /* fully qualified library name */
            library_name = opt->value;
            break;
        case 'd':  /* verbodity */
            verbosity += 1;
            break;
         default:
            PR_fprintf(err, "Usage: version [-d] {fully qualified library name}\n");
            return 2;  /* but not a lot else */
        }
    }
    PL_DestroyOptState(opt);

    if (NULL != library_name)
    {
        runtime = PR_LoadLibrary(library_name);
        if (NULL == runtime) {
			PL_FPrintError(err, "PR_LoadLibrary");
			return 3;
		} else {
            versionEntryPointType versionPoint = (versionEntryPointType)
                PR_FindSymbol(runtime, "libVersionPoint");
            if (NULL == versionPoint) {
				PL_FPrintError(err, "PR_FindSymbol");
				return 4;
			}	
			version_info = versionPoint();
		}
	} else
		version_info = libVersionPoint();	/* NSPR's version info */

	(void)PR_fprintf(err, "Runtime library version information\n");
	PR_ExplodeTime(
		version_info->buildTime, PR_GMTParameters, &exploded);
	(void)PR_FormatTime(
		buffer, sizeof(buffer), "%d %b %Y %H:%M:%S", &exploded);
	(void)PR_fprintf(err, "  Build time: %s GMT\n", buffer);
	(void)PR_fprintf(
		err, "  Build time: %s\n", version_info->buildTimeString);
	(void)PR_fprintf(
		err, "  %s V%u.%u.%u (%s%s%s)\n",
		version_info->description,
		version_info->vMajor,
		version_info->vMinor,
		version_info->vPatch,
		(version_info->beta ? " beta " : ""),
		(version_info->debug ? " debug " : ""),
		(version_info->special ? " special" : ""));
	(void)PR_fprintf(err, "  filename: %s\n", version_info->filename);
	(void)PR_fprintf(err, "  security: %s\n", version_info->security);
	(void)PR_fprintf(err, "  copyright: %s\n", version_info->copyright);
	(void)PR_fprintf(err, "  comment: %s\n", version_info->comment);
	rv = 0;
    return rv;
}
Ejemplo n.º 19
0
void*
Module::symbol (std::string name)
{
    return PR_FindSymbol(_library, name.c_str());
}
Ejemplo n.º 20
0
// Load a plugin dll.  "pluginType" is a handle to a plugin management data
// structure created during FE_RegisterPlugins().  "pNavigatorFuncs" is
// a table of entry points into Navigator, which are the services provided
// by Navigator to plugins, such as requestread() and GetUrl().  These entry
// points are stored and called by the plugin when services are needed.
// The return val is a table of functions which are entry points to the
// newly loaded plugin, such as NewStream() and Write().
NPPluginFuncs* FE_LoadPlugin(void* pluginType, NPNetscapeFuncs* pNavigatorFuncs, np_handle* handle)
{
    if(pluginType == NULL)
        return NULL;

    NPPMgtBlk* pNPMgtBlock = (NPPMgtBlk*)pluginType;

    CString csPluginDir;
    wfe_GetPluginsDirectory(csPluginDir);

    LPSTR pPathSave = NULL;   // storage for one dir spec

    wfe_PushPath(&pPathSave);  // save the current drive and dir

    // change the default dir so that implib'd plugins won't fail
    if(_chdir(csPluginDir) != 0) {
        wfe_PopPath(pPathSave);  // restore the path
        return NULL;
    }

    // must change the drive as well as the dir path
    if(isalpha(csPluginDir[0]) && csPluginDir[1] == ':') {
        if(_chdrive(wfe_MapAsciiToDriveNum(csPluginDir[0])) != 0) {
            wfe_PopPath(pPathSave);  // restore the path
            return NULL;
        }
    }

    pNPMgtBlock->pLibrary = PR_LoadLibrary(pNPMgtBlock->pPluginFilename);

    // the cross platform code should take care of the 16/32 bit issues
    if(pNPMgtBlock->pLibrary == NULL)
        return NULL;
    
    NP_CREATEPLUGIN npCreatePlugin =
#ifndef NSPR20
        (NP_CREATEPLUGIN)PR_FindSymbol("NP_CreatePlugin", pNPMgtBlock->pLibrary);
#else
        (NP_CREATEPLUGIN)PR_FindSymbol(pNPMgtBlock->pLibrary, "NP_CreatePlugin");
#endif
    if (npCreatePlugin != NULL) {
        if (thePluginManager == NULL) {
            static NS_DEFINE_IID(kIPluginManagerIID, NP_IPLUGINMANAGER_IID);
            if (nsPluginManager::Create(NULL, kIPluginManagerIID, (void**)&thePluginManager) != NS_OK)
                return NULL;
        }
        NPIPlugin* plugin = NULL;
        NPPluginError err = npCreatePlugin(thePluginManager, &plugin);
        handle->userPlugin = plugin;
        if (err == NPPluginError_NoError && plugin != NULL) {
            pNPMgtBlock->pPluginFuncs = (NPPluginFuncs*)-1;   // something to say it's loaded, but != 0
        }
    }
    else {

        NP_GETENTRYPOINTS getentrypoints =
#ifndef NSPR20
            (NP_GETENTRYPOINTS)PR_FindSymbol("NP_GetEntryPoints", pNPMgtBlock->pLibrary);
#else
            (NP_GETENTRYPOINTS)PR_FindSymbol(pNPMgtBlock->pLibrary, "NP_GetEntryPoints");
#endif
        if(getentrypoints == NULL)
        {
            PR_UnloadLibrary(pNPMgtBlock->pLibrary);
            wfe_PopPath(pPathSave);  // restore the path
            return NULL;
        }
    
        if(pNPMgtBlock->pPluginFuncs == NULL)
        {
            pNPMgtBlock->pPluginFuncs = new NPPluginFuncs;
            pNPMgtBlock->pPluginFuncs->size = sizeof NPPluginFuncs;
            pNPMgtBlock->pPluginFuncs->javaClass = NULL;
            if(pNPMgtBlock->pPluginFuncs == NULL)   // fatal, can't continue
            {
                PR_UnloadLibrary(pNPMgtBlock->pLibrary);
                wfe_PopPath(pPathSave);  // restore the path
                return NULL;
            }
        }

        if(getentrypoints(pNPMgtBlock->pPluginFuncs) != NPERR_NO_ERROR)
        {
            PR_UnloadLibrary(pNPMgtBlock->pLibrary);
            delete pNPMgtBlock->pPluginFuncs;
            pNPMgtBlock->pPluginFuncs = NULL;
            wfe_PopPath(pPathSave);  // restore the path
            return NULL;
        }

        // if the plugin's major ver level is lower than the Navigator's,
        // then they are incompatible, and should return an error
        if(HIBYTE(pNPMgtBlock->pPluginFuncs->version) < NP_VERSION_MAJOR)
        {
            PR_UnloadLibrary(pNPMgtBlock->pLibrary);
            delete pNPMgtBlock->pPluginFuncs;
            pNPMgtBlock->pPluginFuncs = NULL;
            wfe_PopPath(pPathSave);  // restore the path
            return NULL;
        }

        NP_PLUGININIT npinit = NULL;

        // if this DLL is not already loaded, call its initialization entry point
        if(pNPMgtBlock->uRefCount == 0) {
            // the NP_Initialize entry point was misnamed as NP_PluginInit, early
            // in plugin project development.  Its correct name is documented
            // now, and new developers expect it to work.  However, I don't want
            // to  break the plugins already in the field, so I'll accept either
            // name
            npinit =
#ifndef NSPR20
                (NP_PLUGININIT)PR_FindSymbol("NP_Initialize", pNPMgtBlock->pLibrary);
#else
                (NP_PLUGININIT)PR_FindSymbol(pNPMgtBlock->pLibrary, "NP_Initialize");
#endif
            if(!npinit) {
                npinit =
#ifndef NSPR20
                    (NP_PLUGININIT)PR_FindSymbol("NP_PluginInit", pNPMgtBlock->pLibrary);
#else
                    (NP_PLUGININIT)PR_FindSymbol(pNPMgtBlock->pLibrary, "NP_PluginInit");
#endif
            }
        }

        if(npinit == NULL) {
            PR_UnloadLibrary(pNPMgtBlock->pLibrary);
            delete pNPMgtBlock->pPluginFuncs;
            pNPMgtBlock->pPluginFuncs = NULL;
            wfe_PopPath(pPathSave);  // restore the path
            return NULL;
        }

        if (npinit(pNavigatorFuncs) != NPERR_NO_ERROR) {
            PR_UnloadLibrary(pNPMgtBlock->pLibrary);
            delete pNPMgtBlock->pPluginFuncs;
            pNPMgtBlock->pPluginFuncs = NULL;
            wfe_PopPath(pPathSave);  // restore the path
            return NULL;
        }
    }
    
    pNPMgtBlock->uRefCount++;   // all is well, remember it was loaded
    
    // can't pop the path until plugins have been completely loaded/init'd
    wfe_PopPath(pPathSave);  // restore the path
    return pNPMgtBlock->pPluginFuncs;
}
Ejemplo n.º 21
0
/**
 * Obtains all of the information currently available for this plugin.
 */
nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info)
{
    // clear out the info, except for the first field.
    memset(&info.fName, 0, sizeof(info) - sizeof(PRUint32));

    // need to open the plugin's resource file and read some resources.
    short refNum = OpenPluginResource();

    if (refNum >= 0) {
        if (info.fPluginInfoSize >= sizeof(nsPluginInfo)) {
            // 'STR#', 126, 2 => plugin name.
            info.fName = GetPluginString(126, 2);
      
            // 'STR#', 126, 1 => plugin description.
            info.fDescription = GetPluginString(126, 1);

            nsCString path;
            mPlugin->GetNativePath(path);
      
            FSSpec spec;
            toFSSpec(mPlugin, spec);
            info.fFileName = p2cstrdup(spec.name);

            info.fFullPath = PL_strdup(path.get());
            CFBundleRef bundle = getPluginBundle(path.get());
            if (bundle) {
                info.fBundle = PR_TRUE;
                CFRelease(bundle);
            } else
                info.fBundle = PR_FALSE;

      // It's possible that our plugin has 2 special extra entry points that'll give us more
      // mime type info. Quicktime does this to get around the need of having admin rights
      // to change mime info in the resource fork. We need to use this info instead of the
      // resource. See bug 113464.
      BPSupportedMIMETypes mi = {kBPSupportedMIMETypesStructVers_1, NULL, NULL};
      if (pLibrary) {

        // First, check for NP_GetMIMEDescription
        NP_GETMIMEDESCRIPTION pfnGetMimeDesc = 
          (NP_GETMIMEDESCRIPTION)PR_FindSymbol(pLibrary, NP_GETMIMEDESCRIPTION_NAME); 
        if (pfnGetMimeDesc) {
          nsresult rv = ParsePluginMimeDescription(pfnGetMimeDesc(), info);
          if (NS_SUCCEEDED(rv)) {    // if we could parse the mime types from NP_GetMIMEDescription,
            ::CloseResFile(refNum);  // we've got what we need, close the resource, we're done
            return rv;
          }
        }

        // Next check for mime info from BP_GetSupportedMIMETypes
        BP_GETSUPPORTEDMIMETYPES pfnMime = 
          (BP_GETSUPPORTEDMIMETYPES)PR_FindSymbol(pLibrary, "BP_GetSupportedMIMETypes");
        if (pfnMime && noErr == pfnMime(&mi, 0) && mi.typeStrings) {        
          info.fVariantCount = (**(short**)mi.typeStrings) / 2;
          ::HLock(mi.typeStrings);
          if (mi.infoStrings)  // it's possible some plugins have infoStrings missing
            ::HLock(mi.infoStrings);
        }
      }
      
      // Last, we couldn't get info from an extra entry point for some reason, 
      // Lets get info from normal resources
      if (!info.fVariantCount) {
        mi.typeStrings = ::Get1Resource('STR#', 128);
        if (mi.typeStrings) {
          info.fVariantCount = (**(short**)mi.typeStrings) / 2;
          ::DetachResource(mi.typeStrings);
          ::HLock(mi.typeStrings);
        } else {
          // Don't add this plugin because no mime types could be found
          ::CloseResFile(refNum);
          return NS_ERROR_FAILURE;
        }

        mi.infoStrings = ::Get1Resource('STR#', 127);
        if (mi.infoStrings) {
          ::DetachResource(mi.infoStrings);
          ::HLock(mi.infoStrings);
        }
      }

      // fill-in rest of info struct
      int variantCount = info.fVariantCount;
      info.fMimeTypeArray      = new char*[variantCount];
      info.fExtensionArray     = new char*[variantCount];
      if (mi.infoStrings)
        info.fMimeDescriptionArray = new char*[variantCount];

      short mimeIndex = 2, descriptionIndex = 2;
            for (int i = 0; i < variantCount; i++) {
        info.fMimeTypeArray[i]          = GetNextPluginStringFromHandle(mi.typeStrings, &mimeIndex);
        info.fExtensionArray[i]         = GetNextPluginStringFromHandle(mi.typeStrings, &mimeIndex);
        if (mi.infoStrings)
          info.fMimeDescriptionArray[i] = GetNextPluginStringFromHandle(mi.infoStrings, &descriptionIndex);
      }

      ::HUnlock(mi.typeStrings);
      ::DisposeHandle(mi.typeStrings);
      if (mi.infoStrings) {
        ::HUnlock(mi.infoStrings);      
        ::DisposeHandle(mi.infoStrings);
            }
        }
    
        ::CloseResFile(refNum);
    }
    return NS_OK;
}
Ejemplo n.º 22
0
JSBool
__Core_include (JSContext* cx, std::string path)
{
    if (__Core_isIncluded(path)) {
        #ifdef DEBUG
        std::cerr << "(already included) " << path << "." << std::endl;
        #endif

        return JS_TRUE;
    }

    if (path.substr(path.length()-3) == ".js") {
        struct stat pathStat;

        if (stat(path.c_str(), &pathStat) == -1) {
            #ifdef DEBUG
            std::cerr << "(javascript) ";
            #endif
 
            std::cerr << path << " not found." << std::endl;
            return JS_FALSE;
        }
        
        std::string cachePath = path + "c";
        struct stat cacheStat;
        if (!stat(cachePath.c_str(), &cacheStat)) {
            if (cacheStat.st_mtime >= pathStat.st_mtime) {
                try {
                    lulzJS::Script script(cx, cachePath, lulzJS::Script::Bytecode);
                    script.execute();
                }
                catch (std::exception e) { }

                if (JS_IsExceptionPending(cx)) {
                    JS_ReportPendingException(cx);
                    return JS_FALSE;
                }
            }
        }

        #ifdef DEBUG
        std::cerr << "(javascript) path: " << path << std::endl;
        #endif

        try {
            lulzJS::Script script(cx, path, lulzJS::Script::Text);
            script.execute();

            if (JS_IsExceptionPending(cx)) {
                JS_ReportPendingException(cx);
                return JS_FALSE;
            }

            script.save(cachePath, lulzJS::Script::Bytecode);
        }
        catch (std::runtime_error e) {
            JS_ReportPendingException(cx);
            return JS_FALSE;
        }
    }
    else if (path.substr(path.length()-3) == ".so") {
        #ifdef DEBUG
        std::cerr << "(object) path: " << path << std::endl;
        #endif

        struct stat test;
        if (stat(path.c_str(), &test)) {
            #ifdef DEBUG
            std::cerr << "(object) ";
            #endif

            std::cerr << path << " not found." << std::endl;
            return JS_FALSE;
        }

        PRLibrary* lib = PR_LoadLibrary(path.c_str());

        if (!lib) {
            char* error = new char[PR_GetErrorTextLength()];
            PR_GetErrorText(error);
            std::cerr << error << std::endl;
            delete [] error;
            return JS_FALSE;
        }

        JSBool (*exec)(JSContext*) = (JSBool (*)(JSContext*)) PR_FindSymbol(lib, "exec");

        if (exec == NULL || !(*exec)(cx)) {
            #ifdef DEBUG
            std::cerr << "Couldn't retrieve the symbol." << std::endl;
            #endif

            std::cerr << "The initialization of the module failed." << std::endl;
            return JS_FALSE;
        }
    }
    else {
        #ifdef DEBUG
        std::cerr << "(module) path: " << path << std::endl;
        #endif

        struct stat test;
        if (stat(path.c_str(), &test)) {
            #ifdef DEBUG
            std::cerr << "(module) ";
            #endif

            std::cerr << path << " not found." << std::endl;
            return JS_FALSE;
        }

        if (!__Core_include(cx, path + "/init.js")) {
            return JS_FALSE;
        }
    }

    included.push_back(path);

    return JS_TRUE;
}