diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index 595c470a195cfb12ee9425db6910548be5e99882..26a20cede85f078874e306e2dda957b4ec8a8a78 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -64,9 +64,10 @@ LLPluginClassMedia::~LLPluginClassMedia() reset(); } -bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug) +bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::string &plugin_dir, const std::string &plugin_filename, bool debug) { LL_DEBUGS("Plugin") << "launcher: " << launcher_filename << LL_ENDL; + LL_DEBUGS("Plugin") << "dir: " << plugin_dir << LL_ENDL; LL_DEBUGS("Plugin") << "plugin: " << plugin_filename << LL_ENDL; mPlugin = new LLPluginProcessParent(this); @@ -77,7 +78,7 @@ bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::s message.setValue("target", mTarget); sendMessage(message); - mPlugin->init(launcher_filename, plugin_filename, debug); + mPlugin->init(launcher_filename, plugin_dir, plugin_filename, debug); return true; } diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h index c826e13c4078abca91df7eb338a5155415c32c97..618e928a086efcec7f5bdfc52c336af94198030f 100644 --- a/indra/llplugin/llpluginclassmedia.h +++ b/indra/llplugin/llpluginclassmedia.h @@ -45,6 +45,7 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner // local initialization, called by the media manager when creating a source virtual bool init(const std::string &launcher_filename, + const std::string &plugin_dir, const std::string &plugin_filename, bool debug); diff --git a/indra/llplugin/llplugininstance.cpp b/indra/llplugin/llplugininstance.cpp index c326961db4ab2bc2439204e503a09e072cf028bc..7cde82a20e6d58aedafe33fe776a165fc8129b97 100644 --- a/indra/llplugin/llplugininstance.cpp +++ b/indra/llplugin/llplugininstance.cpp @@ -32,6 +32,10 @@ #include "llapr.h" +#if LL_WINDOWS +#include "direct.h" // needed for _chdir() +#endif + /** Virtual destructor. */ LLPluginInstanceMessageListener::~LLPluginInstanceMessageListener() { @@ -73,10 +77,24 @@ LLPluginInstance::~LLPluginInstance() * @param[in] plugin_file Name of plugin dll/dylib/so. TODO:DOC is this correct? see .h * @return 0 if successful, APR error code or error code from the plugin's init function on failure. */ -int LLPluginInstance::load(std::string &plugin_file) +int LLPluginInstance::load(const std::string& plugin_dir, std::string &plugin_file) { pluginInitFunction init_function = NULL; + if ( plugin_dir.length() ) + { +#if LL_WINDOWS + // VWR-21275: + // *SOME* Windows systems fail to load the Qt plugins if the current working + // directory is not the same as the directory with the Qt DLLs in. + // This should not cause any run time issues since we are changing the cwd for the + // plugin shell process and not the viewer. + // Changing back to the previous directory is not necessary since the plugin shell + // quits once the plugin exits. + _chdir( plugin_dir.c_str() ); +#endif + }; + int result = apr_dso_load(&mDSOHandle, plugin_file.c_str(), gAPRPoolp); diff --git a/indra/llplugin/llplugininstance.h b/indra/llplugin/llplugininstance.h index 50531ca77f2c9cf32277c1f7ce4e0eae898623c1..e6926c3e3779157e38f8f2ac457621db8fc1a30f 100644 --- a/indra/llplugin/llplugininstance.h +++ b/indra/llplugin/llplugininstance.h @@ -56,7 +56,7 @@ class LLPluginInstance // Load a plugin dll/dylib/so // Returns 0 if successful, APR error code or error code returned from the plugin's init function on failure. - int load(std::string &plugin_file); + int load(const std::string& plugin_dir, std::string &plugin_file); // Sends a message to the plugin. void sendMessage(const std::string &message); diff --git a/indra/llplugin/llpluginprocesschild.cpp b/indra/llplugin/llpluginprocesschild.cpp index 45a86476ac30b59473c9d9cfb8d3cff2b0cd2de6..0beb46d0e554120f1d8b7edecea3e5f739e28cb9 100644 --- a/indra/llplugin/llpluginprocesschild.cpp +++ b/indra/llplugin/llpluginprocesschild.cpp @@ -139,7 +139,7 @@ void LLPluginProcessChild::idle(void) if(!mPluginFile.empty()) { mInstance = new LLPluginInstance(this); - if(mInstance->load(mPluginFile) == 0) + if(mInstance->load(mPluginDir, mPluginFile) == 0) { mHeartbeat.start(); mHeartbeat.setTimerExpirySec(HEARTBEAT_SECONDS); @@ -348,6 +348,7 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message) if(message_name == "load_plugin") { mPluginFile = parsed.getValue("file"); + mPluginDir = parsed.getValue("dir"); } else if(message_name == "shm_add") { diff --git a/indra/llplugin/llpluginprocesschild.h b/indra/llplugin/llpluginprocesschild.h index 22ff403ad65484cb785cc5d119324925582410ed..a9d6794e4037393701250a04cb36185d3d3ca46a 100644 --- a/indra/llplugin/llpluginprocesschild.h +++ b/indra/llplugin/llpluginprocesschild.h @@ -92,6 +92,7 @@ class LLPluginProcessChild: public LLPluginMessagePipeOwner, public LLPluginInst LLSocket::ptr_t mSocket; std::string mPluginFile; + std::string mPluginDir; LLPluginInstance *mInstance; diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index c002de04627c312fc39704f875db817eddade6cb..db4b8b131611c149c0f2358f75aac1dd7586a7cb 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -157,10 +157,11 @@ void LLPluginProcessParent::errorState(void) setState(STATE_ERROR); } -void LLPluginProcessParent::init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug) +void LLPluginProcessParent::init(const std::string &launcher_filename, const std::string &plugin_dir, const std::string &plugin_filename, bool debug) { mProcess.setExecutable(launcher_filename); mPluginFile = plugin_filename; + mPluginDir = plugin_dir; mCPUUsage = 0.0f; mDebug = debug; setState(STATE_INITIALIZED); @@ -445,6 +446,7 @@ void LLPluginProcessParent::idle(void) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "load_plugin"); message.setValue("file", mPluginFile); + message.setValue("dir", mPluginDir); sendMessage(message); } diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h index 32394809ef25317bcb20753a04f71f82d5f0628d..c66723f1753c7a7046e21b57a3a8c2789f7ccaa1 100644 --- a/indra/llplugin/llpluginprocessparent.h +++ b/indra/llplugin/llpluginprocessparent.h @@ -57,6 +57,7 @@ class LLPluginProcessParent : public LLPluginMessagePipeOwner ~LLPluginProcessParent(); void init(const std::string &launcher_filename, + const std::string &plugin_dir, const std::string &plugin_filename, bool debug); @@ -151,6 +152,7 @@ class LLPluginProcessParent : public LLPluginMessagePipeOwner LLProcessLauncher mProcess; std::string mPluginFile; + std::string mPluginDir; LLPluginProcessParentOwner *mOwner; diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index f16d8814dd0e2cc1f9e1199a8a3e259842f927e9..9b02bdbe33881b4d76e9cdc2fbd262b8e8c42da2 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -53,7 +53,7 @@ #include "llwebsharing.h" // For LLWebSharing::setOpenIDCookie(), *TODO: find a better way to do this! #include "llfilepicker.h" #include "llnotifications.h" - +#include "lldir_win32.h" #include "llevent.h" // LLSimpleListener #include "llnotificationsutil.h" #include "lluuid.h" @@ -1766,7 +1766,8 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ media_source->setTarget(target); - if (media_source->init(launcher_name, plugin_name, gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins"))) + const std::string plugin_dir = gDirUtilp->getLLPluginDir(); + if (media_source->init(launcher_name, plugin_dir, plugin_name, gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins"))) { return media_source; }