diff --git a/indra/llcommon/llprocess.cpp b/indra/llcommon/llprocess.cpp
index 8c0caca68045b54ddf1838b51d878092f8899cee..dfb2ed69e998304ea9b1c685582c96b87846c54e 100644
--- a/indra/llcommon/llprocess.cpp
+++ b/indra/llcommon/llprocess.cpp
@@ -26,7 +26,6 @@
 
 #include "linden_common.h"
 #include "llprocess.h"
-#include "llsd.h"
 #include "llsdserialize.h"
 #include "stringize.h"
 
@@ -41,7 +40,7 @@ struct LLProcessError: public std::runtime_error
 	LLProcessError(const std::string& msg): std::runtime_error(msg) {}
 };
 
-LLProcessPtr LLProcess::create(const LLSD& params)
+LLProcessPtr LLProcess::create(const LLSDParamAdapter<Params>& params)
 {
 	try
 	{
@@ -54,16 +53,13 @@ LLProcessPtr LLProcess::create(const LLSD& params)
 	}
 }
 
-LLProcess::LLProcess(const LLSD& params):
+LLProcess::LLProcess(const LLSDParamAdapter<Params>& params):
 	mProcessID(0),
-	mAutokill(params["autokill"].asBoolean())
+	mAutokill(params.autokill)
 {
-	// nonstandard default bool value
-	if (! params.has("autokill"))
-		mAutokill = true;
-	if (! params.has("executable"))
+	if (! params.validateBlock(true))
 	{
-		throw LLProcessError(STRINGIZE("not launched: missing 'executable'\n"
+		throw LLProcessError(STRINGIZE("not launched: failed parameter validation\n"
 									   << LLSDNotationStreamer(params)));
 	}
 
@@ -108,14 +104,14 @@ static std::string quote(const std::string& str)
 	return result + "\"";
 }
 
-void LLProcess::launch(const LLSD& params)
+void LLProcess::launch(const LLSDParamAdapter<Params>& params)
 {
 	PROCESS_INFORMATION pinfo;
 	STARTUPINFOA sinfo;
 	memset(&sinfo, 0, sizeof(sinfo));
 	
-	std::string args = quote(params["executable"]);
-	BOOST_FOREACH(const std::string& arg, llsd::inArray(params["args"]))
+	std::string args = quote(params.executable);
+	BOOST_FOREACH(const std::string& arg, params.args)
 	{
 		args += " ";
 		args += quote(arg);
@@ -128,7 +124,7 @@ void LLProcess::launch(const LLSD& params)
 
 	// Convert wrapper to a real std::string so we can use c_str(); but use a
 	// named variable instead of a temporary so c_str() pointer remains valid.
-	std::string cwd(params["cwd"]);
+	std::string cwd(params.cwd);
 	const char * working_directory = 0;
 	if (! cwd.empty())
 		working_directory = cwd.c_str();
@@ -212,7 +208,7 @@ static bool reap_pid(pid_t pid)
 	return false;
 }
 
-void LLProcess::launch(const LLSD& params)
+void LLProcess::launch(const LLSDParamAdapter<Params>& params)
 {
 	// flush all buffers before the child inherits them
 	::fflush(NULL);
@@ -222,7 +218,7 @@ void LLProcess::launch(const LLSD& params)
 	{
 		// child process
 
-		std::string cwd(params["cwd"]);
+		std::string cwd(params.cwd);
 		if (! cwd.empty())
 		{
 			// change to the desired child working directory
@@ -239,12 +235,11 @@ void LLProcess::launch(const LLSD& params)
 		std::vector<const char*> fake_argv;
 
 		// add the executable path
-		std::string executable(params["executable"]);
+		std::string executable(params.executable);
 		fake_argv.push_back(executable.c_str());
 
 		// and any arguments
-		const LLSD& params_args(params["args"]);
-		std::vector<std::string> args(params_args.beginArray(), params_args.endArray());
+		std::vector<std::string> args(params.args.begin(), params.args.end());
 		BOOST_FOREACH(const std::string& arg, args)
 		{
 			fake_argv.push_back(arg.c_str());
diff --git a/indra/llcommon/llprocess.h b/indra/llcommon/llprocess.h
index 9a74cfe8291afae70a547aa2f305c67ee4ab5f1e..9ea129baf28d8aabfa19bb7cdf80f9968d27f093 100644
--- a/indra/llcommon/llprocess.h
+++ b/indra/llcommon/llprocess.h
@@ -27,6 +27,8 @@
 #ifndef LL_LLPROCESS_H
 #define LL_LLPROCESS_H
 
+#include "llinitparam.h"
+#include "llsdparam.h"
 #include <boost/shared_ptr.hpp>
 #include <boost/noncopyable.hpp>
 
@@ -35,8 +37,6 @@
 #include <windows.h>
 #endif
 
-class LLSD;
-
 class LLProcess;
 /// LLProcess instances are created on the heap by static factory methods and
 /// managed by ref-counted pointers.
@@ -50,17 +50,38 @@ class LL_COMMON_API LLProcess: public boost::noncopyable
 {
 	LOG_CLASS(LLProcess);
 public:
+	/// Param block definition
+	struct Params: public LLInitParam::Block<Params>
+	{
+		Params():
+			executable("executable"),
+			args("args"),
+			cwd("cwd"),
+			autokill("autokill", true)
+		{}
+
+		/// pathname of executable
+		Mandatory<std::string> executable;
+		/// zero or more additional command-line arguments
+		Multiple<std::string> args;
+		/// current working directory, if need it changed
+		Optional<std::string> cwd;
+		/// implicitly kill process on destruction of LLProcess object
+		Optional<bool> autokill;
+	};
 
 	/**
-	 * Factory accepting LLSD::Map.
+	 * Factory accepting either plain LLSD::Map or Params block.
 	 * MAY RETURN DEFAULT-CONSTRUCTED LLProcessPtr if params invalid!
 	 *
+	 * Redundant with Params definition above?
+	 *
 	 * executable (required, string):				executable pathname
 	 * args		  (optional, string array):			extra command-line arguments
 	 * cwd		  (optional, string, dft no chdir): change to this directory before executing
 	 * autokill	  (optional, bool, dft true):		implicit kill() on ~LLProcess
 	 */
-	static LLProcessPtr create(const LLSD& params);
+	static LLProcessPtr create(const LLSDParamAdapter<Params>& params);
 	virtual ~LLProcess();
 
 	// isRunning isn't const because, if child isn't running, it clears stored
@@ -96,8 +117,8 @@ class LL_COMMON_API LLProcess: public boost::noncopyable
 	
 private:
 	/// constructor is private: use create() instead
-	LLProcess(const LLSD& params);
-	void launch(const LLSD& params);
+	LLProcess(const LLSDParamAdapter<Params>& params);
+	void launch(const LLSDParamAdapter<Params>& params);
 
 	id mProcessID;
 	bool mAutokill;