bool GMPLoaderImpl::Load(const char* aUTF8LibPath, uint32_t aUTF8LibPathLen, char* aOriginSalt, uint32_t aOriginSaltLen, const GMPPlatformAPI* aPlatformAPI, GMPAdapter* aAdapter) { std::string nodeId; if (!CalculateGMPDeviceId(aOriginSalt, aOriginSaltLen, nodeId)) { return false; } // Start the sandbox now that we've generated the device bound node id. // This must happen after the node id is bound to the device id, as // generating the device id requires privileges. if (mSandboxStarter && !mSandboxStarter->Start(aUTF8LibPath)) { return false; } // Load the GMP. PRLibSpec libSpec; #ifdef XP_WIN int pathLen = MultiByteToWideChar(CP_UTF8, 0, aUTF8LibPath, -1, nullptr, 0); if (pathLen == 0) { return false; } auto widePath = MakeUnique<wchar_t[]>(pathLen); if (MultiByteToWideChar(CP_UTF8, 0, aUTF8LibPath, -1, widePath.get(), pathLen) == 0) { return false; } libSpec.value.pathname_u = widePath.get(); libSpec.type = PR_LibSpec_PathnameU; #else libSpec.value.pathname = aUTF8LibPath; libSpec.type = PR_LibSpec_Pathname; #endif PRLibrary* lib = PR_LoadLibraryWithFlags(libSpec, 0); if (!lib) { return false; } GMPInitFunc initFunc = reinterpret_cast<GMPInitFunc>(PR_FindFunctionSymbol(lib, "GMPInit")); if ((initFunc && aAdapter) || (!initFunc && !aAdapter)) { // Ensure that if we're dealing with a GMP we do *not* use an adapter // provided from the outside world. This is important as it means we // don't call code not covered by Adobe's plugin-container voucher // before we pass the node Id to Adobe's GMP. return false; } // Note: PassThroughGMPAdapter's code must remain in this file so that it's // covered by Adobe's plugin-container voucher. mAdapter.reset((!aAdapter) ? new PassThroughGMPAdapter() : aAdapter); mAdapter->SetAdaptee(lib); if (mAdapter->GMPInit(aPlatformAPI) != GMPNoErr) { return false; } mAdapter->GMPSetNodeId(nodeId.c_str(), nodeId.size()); return true; }