nsresult nsPluginFile::LoadPlugin(PRLibrary **outLibrary) { PRLibSpec libSpec; libSpec.type = PR_LibSpec_Pathname; bool exists = false; mPlugin->Exists(&exists); if (!exists) return NS_ERROR_FILE_NOT_FOUND; nsresult rv; nsAutoCString path; rv = mPlugin->GetNativePath(path); if (NS_FAILED(rv)) return rv; libSpec.value.pathname = path.get(); *outLibrary = PR_LoadLibraryWithFlags(libSpec, 0); pLibrary = *outLibrary; #ifdef DEBUG printf("LoadPlugin() %s returned %lx\n", libSpec.value.pathname, (unsigned long)pLibrary); #endif if (!pLibrary) { return NS_ERROR_FAILURE; } return NS_OK; }
/* * Load the library with the file name 'name' residing in the same * directory as the reference library, whose pathname is 'referencePath'. */ static PRLibrary* loader_LoadLibInReferenceDir(const char* referencePath, const char* name) { PRLibrary* dlh = NULL; char* fullName = NULL; char* c; PRLibSpec libSpec; /* Remove the trailing filename from referencePath and add the new one */ c = strrchr(referencePath, PR_GetDirectorySeparator()); if (c) { size_t referencePathSize = 1 + c - referencePath; fullName = (char*)PORT_Alloc(strlen(name) + referencePathSize + 1); if (fullName) { memcpy(fullName, referencePath, referencePathSize); strcpy(fullName + referencePathSize, name); #ifdef DEBUG_LOADER PR_fprintf(PR_STDOUT, "\nAttempting to load fully-qualified %s\n", fullName); #endif libSpec.type = PR_LibSpec_Pathname; libSpec.value.pathname = fullName; dlh = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL); PORT_Free(fullName); } } return dlh; }
/* static */ bool FFmpegRuntimeLinker::Init() { if (sLinkStatus) { return sLinkStatus == LinkStatus_SUCCEEDED; } for (size_t i = 0; i < ArrayLength(sLibs); i++) { const char* lib = sLibs[i]; PRLibSpec lspec; lspec.type = PR_LibSpec_Pathname; lspec.value.pathname = lib; sLibAV.mAVCodecLib = PR_LoadLibraryWithFlags(lspec, PR_LD_NOW | PR_LD_LOCAL); if (sLibAV.mAVCodecLib) { sLibAV.mAVUtilLib = sLibAV.mAVCodecLib; if (sLibAV.Link()) { sLinkStatus = LinkStatus_SUCCEEDED; return true; } } } FFMPEG_LOG("H264/AAC codecs unsupported without ["); for (size_t i = 0; i < ArrayLength(sLibs); i++) { FFMPEG_LOG("%s %s", i ? "," : " ", sLibs[i]); } FFMPEG_LOG(" ]\n"); sLinkStatus = LinkStatus_FAILED; return false; }
static PRLibrary * sftkdb_LoadFromPath(const char *path, const char *libname) { char *c; int pathLen, nameLen, fullPathLen; char *fullPathName = NULL; PRLibSpec libSpec; PRLibrary *lib = NULL; /* strip of our parent's library name */ c = strrchr(path, PR_GetDirectorySeparator()); if (!c) { return NULL; /* invalid path */ } pathLen = (c-path)+1; nameLen = strlen(libname); fullPathLen = pathLen + nameLen +1; fullPathName = (char *)PORT_Alloc(fullPathLen); if (fullPathName == NULL) { return NULL; /* memory allocation error */ } PORT_Memcpy(fullPathName, path, pathLen); PORT_Memcpy(fullPathName+pathLen, libname, nameLen); fullPathName[fullPathLen-1] = 0; libSpec.type = PR_LibSpec_Pathname; libSpec.value.pathname = fullPathName; lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL); PORT_Free(fullPathName); return lib; }
static PRLibrary* MozAVLink(const char* aName) { PRLibSpec lspec; lspec.type = PR_LibSpec_Pathname; lspec.value.pathname = aName; return PR_LoadLibraryWithFlags(lspec, PR_LD_NOW | PR_LD_LOCAL); }
PR_LoadLibrary(const char *name) { PRLibSpec libSpec; libSpec.type = PR_LibSpec_Pathname; libSpec.value.pathname = name; return PR_LoadLibraryWithFlags(libSpec, 0); }
PRLibrary* PORT_LoadLibraryFromOrigin(const char* existingShLibName, PRFuncPtr staticShLibFunc, const char* newShLibName) { PRLibrary* lib = NULL; char* fullPath = NULL; PRLibSpec libSpec; /* Get the pathname for existingShLibName, e.g. /usr/lib/libnss3.so * PR_GetLibraryFilePathname works with either the base library name or a * function pointer, depending on the platform. * We require the address of a function in the "reference library", * provided by the caller. To avoid getting the address of the stub/thunk * of an exported function by accident, use the address of a static * function rather than an exported function. */ fullPath = PR_GetLibraryFilePathname(existingShLibName, staticShLibFunc); if (fullPath) { lib = loader_LoadLibInReferenceDir(fullPath, newShLibName); #ifdef XP_UNIX if (!lib) { /* * If fullPath is a symbolic link, resolve the symbolic * link and try again. */ char* originalfullPath = loader_GetOriginalPathname(fullPath); if (originalfullPath) { PR_Free(fullPath); fullPath = originalfullPath; lib = loader_LoadLibInReferenceDir(fullPath, newShLibName); } } #endif PR_Free(fullPath); } if (!lib) { #ifdef DEBUG_LOADER PR_fprintf(PR_STDOUT, "\nAttempting to load %s\n", newShLibName); #endif libSpec.type = PR_LibSpec_Pathname; libSpec.value.pathname = newShLibName; lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL); } if (NULL == lib) { #ifdef DEBUG_LOADER PR_fprintf(PR_STDOUT, "\nLoading failed : %s.\n", newShLibName); #endif } return lib; }
bool GLLibraryLoader::OpenLibrary(const char *library) { PRLibSpec lspec; lspec.type = PR_LibSpec_Pathname; lspec.value.pathname = library; mLibrary = PR_LoadLibraryWithFlags(lspec, PR_LD_LAZY | PR_LD_LOCAL); if (!mLibrary) return false; return true; }
static PRLibrary* MozAVLink(nsIFile* aFile) { PRLibSpec lspec; PathString path = aFile->NativePath(); #ifdef XP_WIN lspec.type = PR_LibSpec_PathnameU; lspec.value.pathname_u = path.get(); #else lspec.type = PR_LibSpec_Pathname; lspec.value.pathname = path.get(); #endif #ifdef MOZ_WIDGET_ANDROID PRLibrary* lib = PR_LoadLibraryWithFlags(lspec, PR_LD_NOW | PR_LD_GLOBAL); #else PRLibrary* lib = PR_LoadLibraryWithFlags(lspec, PR_LD_NOW | PR_LD_LOCAL); #endif if (!lib) { FFMPEG_LOG("unable to load library %s", aFile->HumanReadablePath().get()); } return lib; }
static PRLibrary* loader_LoadLibrary(const char* nameToLoad) { PRLibrary* lib = NULL; char* fullPath = NULL; PRLibSpec libSpec; /* Get the pathname for nameOfAlreadyLoadedLib, i.e. /usr/lib/libnss3.so * PR_GetLibraryFilePathname works with either the base library name or a * function pointer, depending on the platform. We can't query an exported * symbol such as NSC_GetFunctionList, because on some platforms we can't * find symbols in loaded implicit dependencies. * But we can just get the address of this function ! */ fullPath = PR_GetLibraryFilePathname(NameOfThisSharedLib, (PRFuncPtr)&loader_LoadLibrary); if (fullPath) { lib = loader_LoadLibInReferenceDir(fullPath, nameToLoad); #ifdef XP_UNIX if (!lib) { /* * If fullPath is a symbolic link, resolve the symbolic * link and try again. */ char* originalfullPath = loader_GetOriginalPathname(fullPath); if (originalfullPath) { PR_Free(fullPath); fullPath = originalfullPath; lib = loader_LoadLibInReferenceDir(fullPath, nameToLoad); } } #endif PR_Free(fullPath); } if (!lib) { #ifdef DEBUG_LOADER PR_fprintf(PR_STDOUT, "\nAttempting to load %s\n", nameToLoad); #endif libSpec.type = PR_LibSpec_Pathname; libSpec.value.pathname = nameToLoad; lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL); } if (NULL == lib) { #ifdef DEBUG_LOADER PR_fprintf(PR_STDOUT, "\nLoading failed : %s.\n", nameToLoad); #endif } return lib; }
static PRLibrary * sftkdb_LoadLibrary(const char *libname) { PRLibrary *lib = NULL; PRFuncPtr fn_addr; char *parentLibPath = NULL; fn_addr = (PRFuncPtr) &sftkdb_LoadLibrary; parentLibPath = PR_GetLibraryFilePathname(SOFTOKEN_LIB_NAME, fn_addr); if (!parentLibPath) { goto done; } lib = sftkdb_LoadFromPath(parentLibPath, libname); #ifdef XP_UNIX /* handle symbolic link case */ if (!lib) { char *trueParentLibPath = sftkdb_resolvePath(parentLibPath); if (!trueParentLibPath) { goto done; } lib = sftkdb_LoadFromPath(trueParentLibPath, libname); PORT_Free(trueParentLibPath); } #endif done: if (parentLibPath) { PORT_Free(parentLibPath); } /* still couldn't load it, try the generic path */ if (!lib) { PRLibSpec libSpec; libSpec.type = PR_LibSpec_Pathname; libSpec.value.pathname = libname; lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL); } return lib; }
static PRBool LoadExtraSharedLib(const char *name, char **soname, PRBool tryToGetSoname) { PRBool ret = PR_TRUE; PRLibSpec tempSpec; PRLibrary *handle; tempSpec.type = PR_LibSpec_Pathname; tempSpec.value.pathname = name; handle = PR_LoadLibraryWithFlags(tempSpec, PR_LD_NOW|PR_LD_GLOBAL); if (!handle) { ret = PR_FALSE; DisplayPR_LoadLibraryErrorMessage(name); if (tryToGetSoname) { SearchForSoname(name, soname); if (*soname) { ret = LoadExtraSharedLib((const char *) *soname, NULL, PR_FALSE); } } } return ret; }
JSObject* Library::Create(JSContext* cx, HandleValue path, const JSCTypesCallbacks* callbacks) { RootedObject libraryObj(cx, JS_NewObject(cx, &sLibraryClass)); if (!libraryObj) return nullptr; // initialize the library JS_SetReservedSlot(libraryObj, SLOT_LIBRARY, PrivateValue(nullptr)); // attach API functions if (!JS_DefineFunctions(cx, libraryObj, sLibraryFunctions)) return nullptr; if (!path.isString()) { JS_ReportErrorASCII(cx, "open takes a string argument"); return nullptr; } PRLibSpec libSpec; RootedFlatString pathStr(cx, JS_FlattenString(cx, path.toString())); if (!pathStr) return nullptr; AutoStableStringChars pathStrChars(cx); if (!pathStrChars.initTwoByte(cx, pathStr)) return nullptr; #ifdef XP_WIN // On Windows, converting to native charset may corrupt path string. // So, we have to use Unicode path directly. char16ptr_t pathChars = pathStrChars.twoByteChars(); libSpec.value.pathname_u = pathChars; libSpec.type = PR_LibSpec_PathnameU; #else // Convert to platform native charset if the appropriate callback has been // provided. char* pathBytes; if (callbacks && callbacks->unicodeToNative) { pathBytes = callbacks->unicodeToNative(cx, pathStrChars.twoByteChars(), pathStr->length()); if (!pathBytes) return nullptr; } else { // Fallback: assume the platform native charset is UTF-8. This is true // for Mac OS X, Android, and probably Linux. size_t nbytes = GetDeflatedUTF8StringLength(cx, pathStrChars.twoByteChars(), pathStr->length()); if (nbytes == (size_t) -1) return nullptr; pathBytes = static_cast<char*>(JS_malloc(cx, nbytes + 1)); if (!pathBytes) return nullptr; ASSERT_OK(DeflateStringToUTF8Buffer(cx, pathStrChars.twoByteChars(), pathStr->length(), pathBytes, &nbytes)); pathBytes[nbytes] = 0; } libSpec.value.pathname = pathBytes; libSpec.type = PR_LibSpec_Pathname; #endif PRLibrary* library = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW); #ifndef XP_WIN JS_free(cx, pathBytes); #endif if (!library) { #define MAX_ERROR_LEN 1024 char error[MAX_ERROR_LEN] = "Cannot get error from NSPR."; uint32_t errorLen = PR_GetErrorTextLength(); if (errorLen && errorLen < MAX_ERROR_LEN) PR_GetErrorText(error); #undef MAX_ERROR_LEN if (JS::StringIsASCII(error)) { JSAutoByteString pathCharsUTF8; if (pathCharsUTF8.encodeUtf8(cx, pathStr)) JS_ReportErrorUTF8(cx, "couldn't open library %s: %s", pathCharsUTF8.ptr(), error); } else { JSAutoByteString pathCharsLatin1; if (pathCharsLatin1.encodeLatin1(cx, pathStr)) JS_ReportErrorLatin1(cx, "couldn't open library %s: %s", pathCharsLatin1.ptr(), error); } return nullptr; } // stash the library JS_SetReservedSlot(libraryObj, SLOT_LIBRARY, PrivateValue(library)); return libraryObj; }
JSObject* Library::Create(JSContext* cx, jsval path, JSCTypesCallbacks* callbacks) { JSObject* libraryObj = JS_NewObject(cx, &sLibraryClass, NULL, NULL); if (!libraryObj) return NULL; js::AutoObjectRooter root(cx, libraryObj); // initialize the library if (!JS_SetReservedSlot(cx, libraryObj, SLOT_LIBRARY, PRIVATE_TO_JSVAL(NULL))) return NULL; // attach API functions if (!JS_DefineFunctions(cx, libraryObj, sLibraryFunctions)) return NULL; if (!JSVAL_IS_STRING(path)) { JS_ReportError(cx, "open takes a string argument"); return NULL; } PRLibSpec libSpec; JSFlatString* pathStr = JS_FlattenString(cx, JSVAL_TO_STRING(path)); if (!pathStr) return NULL; #ifdef XP_WIN // On Windows, converting to native charset may corrupt path string. // So, we have to use Unicode path directly. const PRUnichar* pathChars = JS_GetFlatStringChars(pathStr); if (!pathChars) return NULL; libSpec.value.pathname_u = pathChars; libSpec.type = PR_LibSpec_PathnameU; #else // Convert to platform native charset if the appropriate callback has been // provided. char* pathBytes; if (callbacks && callbacks->unicodeToNative) { pathBytes = callbacks->unicodeToNative(cx, pathStr->chars(), pathStr->length()); if (!pathBytes) return NULL; } else { // Fallback: assume the platform native charset is UTF-8. This is true // for Mac OS X, Android, and probably Linux. size_t nbytes = js_GetDeflatedUTF8StringLength(cx, pathStr->chars(), pathStr->length()); if (nbytes == (size_t) -1) return NULL; pathBytes = static_cast<char*>(JS_malloc(cx, nbytes + 1)); if (!pathBytes) return NULL; ASSERT_OK(js_DeflateStringToUTF8Buffer(cx, pathStr->chars(), pathStr->length(), pathBytes, &nbytes)); pathBytes[nbytes] = 0; } libSpec.value.pathname = pathBytes; libSpec.type = PR_LibSpec_Pathname; #endif PRLibrary* library = PR_LoadLibraryWithFlags(libSpec, 0); #ifndef XP_WIN JS_free(cx, pathBytes); #endif if (!library) { JS_ReportError(cx, "couldn't open library"); return NULL; } // stash the library if (!JS_SetReservedSlot(cx, libraryObj, SLOT_LIBRARY, PRIVATE_TO_JSVAL(library))) return NULL; return libraryObj; }
nsresult nsPluginFile::LoadPlugin(PRLibrary **outLibrary) { PRLibSpec libSpec; libSpec.type = PR_LibSpec_Pathname; bool exists = false; mPlugin->Exists(&exists); if (!exists) return NS_ERROR_FILE_NOT_FOUND; nsresult rv; nsAutoCString path; rv = mPlugin->GetNativePath(path); if (NS_FAILED(rv)) return rv; libSpec.value.pathname = path.get(); #if defined(MOZ_WIDGET_GTK2) // Normally, Mozilla isn't linked against libXt and libXext // since it's a Gtk/Gdk application. On the other hand, // legacy plug-ins expect the libXt and libXext symbols // to already exist in the global name space. This plug-in // wrapper is linked against libXt and libXext, but since // we never call on any of these libraries, plug-ins still // fail to resolve Xt symbols when trying to do a dlopen // at runtime. Explicitly opening Xt/Xext into the global // namespace before attempting to load the plug-in seems to // work fine. #if defined(SOLARIS) || defined(HPUX) // Acrobat/libXm: Lazy resolving might cause crash later (bug 211587) *outLibrary = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW); pLibrary = *outLibrary; #else // Some dlopen() doesn't recover from a failed PR_LD_NOW (bug 223744) *outLibrary = PR_LoadLibraryWithFlags(libSpec, 0); pLibrary = *outLibrary; #endif if (!pLibrary) { LoadExtraSharedLibs(); // try reload plugin once more *outLibrary = PR_LoadLibraryWithFlags(libSpec, 0); pLibrary = *outLibrary; if (!pLibrary) { DisplayPR_LoadLibraryErrorMessage(libSpec.value.pathname); return NS_ERROR_FAILURE; } } #else *outLibrary = PR_LoadLibraryWithFlags(libSpec, 0); pLibrary = *outLibrary; #endif // MOZ_WIDGET_GTK2 #ifdef DEBUG printf("LoadPlugin() %s returned %lx\n", libSpec.value.pathname, (unsigned long)pLibrary); #endif if (!pLibrary) { return NS_ERROR_FAILURE; } return NS_OK; }
bool GMPLoaderImpl::Load(const char* aLibPath, uint32_t aLibPathLen, char* aOriginSalt, uint32_t aOriginSaltLen, const GMPPlatformAPI* aPlatformAPI) { std::string nodeId; #ifdef HASH_NODE_ID_WITH_DEVICE_ID if (aOriginSaltLen > 0) { string16 deviceId; int volumeId; if (!rlz_lib::GetRawMachineId(&deviceId, &volumeId)) { return false; } SHA256Context ctx; SHA256_Begin(&ctx); SHA256_Update(&ctx, (const uint8_t*)aOriginSalt, aOriginSaltLen); SHA256_Update(&ctx, (const uint8_t*)deviceId.c_str(), deviceId.size() * sizeof(string16::value_type)); SHA256_Update(&ctx, (const uint8_t*)&volumeId, sizeof(int)); uint8_t digest[SHA256_LENGTH] = {0}; unsigned int digestLen = 0; SHA256_End(&ctx, digest, &digestLen, SHA256_LENGTH); // Overwrite all data involved in calculation as it could potentially // identify the user, so there's no chance a GMP can read it and use // it for identity tracking. memset(&ctx, 0, sizeof(ctx)); memset(aOriginSalt, 0, aOriginSaltLen); volumeId = 0; memset(&deviceId[0], '*', sizeof(string16::value_type) * deviceId.size()); deviceId = L""; if (!rlz_lib::BytesToString(digest, SHA256_LENGTH, &nodeId)) { return false; } // We've successfully bound the origin salt to node id. // rlz_lib::GetRawMachineId and/or the system functions it // called could have left user identifiable data on the stack, // so carefully zero the stack down to the guard page. uint8_t* top; uint8_t* bottom; if (!GetStackAfterCurrentFrame(&top, &bottom)) { return false; } assert(top >= bottom); // Inline instructions equivalent to RtlSecureZeroMemory(). // We can't just use RtlSecureZeroMemory here directly, as in debug // builds, RtlSecureZeroMemory() can't be inlined, and the stack // memory it uses would get wiped by itself running, causing crashes. for (volatile uint8_t* p = (volatile uint8_t*)bottom; p < top; p++) { *p = 0; } } else #endif { nodeId = std::string(aOriginSalt, aOriginSalt + aOriginSaltLen); } // 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(aLibPath); } // Load the GMP. PRLibSpec libSpec; libSpec.value.pathname = aLibPath; libSpec.type = PR_LibSpec_Pathname; mLib = PR_LoadLibraryWithFlags(libSpec, 0); if (!mLib) { return false; } GMPInitFunc initFunc = reinterpret_cast<GMPInitFunc>(PR_FindFunctionSymbol(mLib, "GMPInit")); if (!initFunc) { return false; } if (initFunc(aPlatformAPI) != GMPNoErr) { return false; } GMPSetNodeIdFunc setNodeIdFunc = reinterpret_cast<GMPSetNodeIdFunc>(PR_FindFunctionSymbol(mLib, "GMPSetNodeId")); if (setNodeIdFunc) { setNodeIdFunc(nodeId.c_str(), nodeId.size()); } mGetAPIFunc = reinterpret_cast<GMPGetAPIFunc>(PR_FindFunctionSymbol(mLib, "GMPGetAPI")); if (!mGetAPIFunc) { return false; } return true; }
bool GMPLoaderImpl::Load(const char* aLibPath, uint32_t aLibPathLen, char* aOriginSalt, uint32_t aOriginSaltLen, const GMPPlatformAPI* aPlatformAPI) { std::string nodeId; #ifdef HASH_NODE_ID_WITH_DEVICE_ID if (aOriginSaltLen > 0) { string16 deviceId; int volumeId; if (!rlz_lib::GetRawMachineId(&deviceId, &volumeId)) { return false; } SHA256Context ctx; SHA256_Begin(&ctx); SHA256_Update(&ctx, (const uint8_t*)aOriginSalt, aOriginSaltLen); SHA256_Update(&ctx, (const uint8_t*)deviceId.c_str(), deviceId.size() * sizeof(string16::value_type)); SHA256_Update(&ctx, (const uint8_t*)&volumeId, sizeof(int)); uint8_t digest[SHA256_LENGTH] = {0}; unsigned int digestLen = 0; SHA256_End(&ctx, digest, &digestLen, SHA256_LENGTH); // Overwrite all data involved in calculation as it could potentially // identify the user, so there's no chance a GMP can read it and use // it for identity tracking. memset(&ctx, 0, sizeof(ctx)); memset(aOriginSalt, 0, aOriginSaltLen); volumeId = 0; memset(&deviceId[0], '*', sizeof(string16::value_type) * deviceId.size()); deviceId = L""; if (!rlz_lib::BytesToString(digest, SHA256_LENGTH, &nodeId)) { return false; } // We've successfully bound the origin salt to node id. // rlz_lib::GetRawMachineId and/or the system functions it // called could have left user identifiable data on the stack, // so carefully zero the stack down to the guard page. uint8_t* top; uint8_t* bottom; if (!GetStackAfterCurrentFrame(&top, &bottom)) { return false; } assert(top >= bottom); // Inline instructions equivalent to RtlSecureZeroMemory(). // We can't just use RtlSecureZeroMemory here directly, as in debug // builds, RtlSecureZeroMemory() can't be inlined, and the stack // memory it uses would get wiped by itself running, causing crashes. for (volatile uint8_t* p = (volatile uint8_t*)bottom; p < top; p++) { *p = 0; } } else #endif { nodeId = std::string(aOriginSalt, aOriginSalt + aOriginSaltLen); } #if defined(XP_WIN) && defined(MOZ_SANDBOX) // If the GMP DLL is a side-by-side assembly with static imports then the DLL // loader will attempt to create an activation context which will fail because // of the sandbox. If we create an activation context before we start the // sandbox then this one will get picked up by the DLL loader. int pathLen = MultiByteToWideChar(CP_ACP, 0, aLibPath, -1, nullptr, 0); if (pathLen == 0) { return false; } wchar_t* widePath = new wchar_t[pathLen]; if (MultiByteToWideChar(CP_ACP, 0, aLibPath, -1, widePath, pathLen) == 0) { delete[] widePath; return false; } ACTCTX actCtx = { sizeof(actCtx) }; actCtx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID; actCtx.lpSource = widePath; actCtx.lpResourceName = ISOLATIONAWARE_MANIFEST_RESOURCE_ID; ScopedActCtxHandle actCtxHandle(CreateActCtx(&actCtx)); delete[] widePath; #endif // 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(aLibPath); } // Load the GMP. PRLibSpec libSpec; libSpec.value.pathname = aLibPath; libSpec.type = PR_LibSpec_Pathname; mLib = PR_LoadLibraryWithFlags(libSpec, 0); if (!mLib) { return false; } GMPInitFunc initFunc = reinterpret_cast<GMPInitFunc>(PR_FindFunctionSymbol(mLib, "GMPInit")); if (!initFunc) { return false; } if (initFunc(aPlatformAPI) != GMPNoErr) { return false; } GMPSetNodeIdFunc setNodeIdFunc = reinterpret_cast<GMPSetNodeIdFunc>(PR_FindFunctionSymbol(mLib, "GMPSetNodeId")); if (setNodeIdFunc) { setNodeIdFunc(nodeId.c_str(), nodeId.size()); } mGetAPIFunc = reinterpret_cast<GMPGetAPIFunc>(PR_FindFunctionSymbol(mLib, "GMPGetAPI")); if (!mGetAPIFunc) { return false; } return true; }
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; }