From 7e6ce12a17add531695d0435e85a9e5564209e41 Mon Sep 17 00:00:00 2001
From: callum <none@none>
Date: Tue, 8 Feb 2011 15:37:12 -0800
Subject: VWR-21275 FIX // *SOME* Windows systems fail to load the Qt plugins
 if the current working Reviewed by Richard -
 http://codereview.lindenlab.com/6011001/

---
 indra/llplugin/llpluginclassmedia.cpp    |  5 +++--
 indra/llplugin/llpluginclassmedia.h      |  1 +
 indra/llplugin/llplugininstance.cpp      | 20 +++++++++++++++++++-
 indra/llplugin/llplugininstance.h        |  2 +-
 indra/llplugin/llpluginprocesschild.cpp  |  3 ++-
 indra/llplugin/llpluginprocesschild.h    |  1 +
 indra/llplugin/llpluginprocessparent.cpp |  4 +++-
 indra/llplugin/llpluginprocessparent.h   |  2 ++
 8 files changed, 32 insertions(+), 6 deletions(-)

(limited to 'indra/llplugin')

diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 595c470a19..26a20cede8 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 c826e13c40..618e928a08 100644
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -45,6 +45,7 @@ public:
 
 	// 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 c326961db4..7cde82a20e 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 50531ca77f..e6926c3e37 100644
--- a/indra/llplugin/llplugininstance.h
+++ b/indra/llplugin/llplugininstance.h
@@ -56,7 +56,7 @@ public:
 	
 	// 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 45a86476ac..0beb46d0e5 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 22ff403ad6..a9d6794e40 100644
--- a/indra/llplugin/llpluginprocesschild.h
+++ b/indra/llplugin/llpluginprocesschild.h
@@ -92,6 +92,7 @@ private:
 	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 c002de0462..db4b8b1316 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 32394809ef..c66723f175 100644
--- a/indra/llplugin/llpluginprocessparent.h
+++ b/indra/llplugin/llpluginprocessparent.h
@@ -57,6 +57,7 @@ public:
 	~LLPluginProcessParent();
 		
 	void init(const std::string &launcher_filename, 
+			  const std::string &plugin_dir,
 			  const std::string &plugin_filename, 
 			  bool debug);
 
@@ -151,6 +152,7 @@ private:
 	LLProcessLauncher mProcess;
 	
 	std::string mPluginFile;
+	std::string mPluginDir;
 
 	LLPluginProcessParentOwner *mOwner;
 	
-- 
cgit v1.2.3