Make EnvironmentModification struct and pass around array directly

* The old 'store in opaque void*' is kept as entry point wrappers only
  for the C# UI.
This commit is contained in:
baldurk
2017-04-07 12:36:14 +01:00
parent 43eb5072b4
commit bc79e2296f
17 changed files with 208 additions and 265 deletions
+22 -45
View File
@@ -4,69 +4,46 @@
#include <QStandardPaths>
#include "Code/QRDUtils.h"
QString EnvironmentModification::GetTypeString() const
{
QString ret;
if(type == EnvMod::Append)
ret = QString("Append, %1").arg(ToQStr(separator));
else if(type == EnvMod::Prepend)
ret = QString("Prepend, %1").arg(ToQStr(separator));
else
ret = "Set";
return ret;
}
QString EnvironmentModification::GetDescription() const
{
QString ret;
if(type == EnvMod::Append)
ret = QString("Append %1 with %2 using %3").arg(variable).arg(value).arg(ToQStr(separator));
else if(type == EnvMod::Prepend)
ret = QString("Prepend %1 with %2 using %3").arg(variable).arg(value).arg(ToQStr(separator));
else
ret = QString("Set %1 to %2").arg(variable).arg(value);
return ret;
}
EnvironmentModification::operator QVariant() const
QVariant EnvModToVariant(const EnvironmentModification &env)
{
QVariantMap ret;
ret["variable"] = variable;
ret["value"] = value;
ret["type"] = ToQStr(type);
ret["separator"] = ToQStr(separator);
ret["variable"] = ToQStr(env.name);
ret["value"] = ToQStr(env.value);
ret["type"] = ToQStr(env.mod);
ret["separator"] = ToQStr(env.sep);
return ret;
}
EnvironmentModification::EnvironmentModification(const QVariant &v)
EnvironmentModification EnvModFromVariant(const QVariant &v)
{
QVariantMap data = v.toMap();
variable = data["variable"].toString();
value = data["value"].toString();
EnvironmentModification ret;
ret.name = data["variable"].toString().toUtf8().data();
ret.value = data["value"].toString().toUtf8().data();
QString t = data["type"].toString();
if(t == ToQStr(EnvMod::Append))
type = EnvMod::Append;
ret.mod = EnvMod::Append;
else if(t == ToQStr(EnvMod::Prepend))
type = EnvMod::Prepend;
ret.mod = EnvMod::Prepend;
else
type = EnvMod::Set;
ret.mod = EnvMod::Set;
QString s = data["separator"].toString();
if(s == ToQStr(EnvSep::SemiColon))
separator = EnvSep::SemiColon;
ret.sep = EnvSep::SemiColon;
else if(s == ToQStr(EnvSep::Colon))
separator = EnvSep::Colon;
ret.sep = EnvSep::Colon;
else if(s == ToQStr(EnvSep::Platform))
separator = EnvSep::Platform;
ret.sep = EnvSep::Platform;
else
separator = EnvSep::NoSep;
ret.sep = EnvSep::NoSep;
return ret;
}
CaptureSettings::CaptureSettings()
@@ -88,7 +65,7 @@ CaptureSettings::operator QVariant() const
QVariantList env;
for(int i = 0; i < Environment.size(); i++)
env.push_back((QVariant)Environment[i]);
env.push_back(EnvModToVariant(Environment[i]));
ret["Environment"] = env;
QVariantMap opts;
@@ -122,7 +99,7 @@ CaptureSettings::CaptureSettings(const QVariant &v)
QVariantList env = data["Environment"].toList();
for(int i = 0; i < env.size(); i++)
{
EnvironmentModification e(env[i]);
EnvironmentModification e = EnvModFromVariant(env[i]);
Environment.push_back(e);
}
-22
View File
@@ -43,28 +43,6 @@ class QWidget;
struct ICaptureContext;
struct EnvironmentModification
{
EnvironmentModification()
{
type = EnvMod::Set;
separator = EnvSep::NoSep;
}
QString variable;
QString value;
EnvMod type;
EnvSep separator;
QString GetTypeString() const;
QString GetDescription() const;
VARIANT_CAST(EnvironmentModification);
};
DECLARE_REFLECTION_STRUCT(EnvironmentModification);
struct CaptureSettings
{
CaptureSettings();
+1 -7
View File
@@ -355,11 +355,7 @@ uint32_t RenderManager::ExecuteAndInject(const QString &exe, const QString &work
const QList<EnvironmentModification> &env,
const QString &logfile, CaptureOptions opts)
{
void *envList = RENDERDOC_MakeEnvironmentModificationList(env.size());
for(int i = 0; i < env.size(); i++)
RENDERDOC_SetEnvironmentModification(envList, i, env[i].variable.toUtf8().data(),
env[i].value.toUtf8().data(), env[i].type, env[i].separator);
rdctype::array<EnvironmentModification> envList = env.toVector().toStdVector();
uint32_t ret = 0;
@@ -376,8 +372,6 @@ uint32_t RenderManager::ExecuteAndInject(const QString &exe, const QString &work
opts, false);
}
RENDERDOC_FreeEnvironmentModificationList(envList);
return ret;
}
+21 -1
View File
@@ -37,6 +37,26 @@
#define JSON_ID "rdocCaptureSettings"
#define JSON_VER 1
static QString GetDescription(const EnvironmentModification &env)
{
QString ret;
if(env.mod == EnvMod::Append)
ret = QString("Append %1 with %2 using %3")
.arg(ToQStr(env.name))
.arg(ToQStr(env.value))
.arg(ToQStr(env.sep));
else if(env.mod == EnvMod::Prepend)
ret = QString("Prepend %1 with %2 using %3")
.arg(ToQStr(env.name))
.arg(ToQStr(env.value))
.arg(ToQStr(env.sep));
else
ret = QString("Set %1 to %2").arg(ToQStr(env.name)).arg(ToQStr(env.value));
return ret;
}
Q_DECLARE_METATYPE(CaptureSettings);
CaptureDialog::CaptureDialog(ICaptureContext &ctx, OnCaptureMethod captureCallback,
@@ -662,7 +682,7 @@ void CaptureDialog::SetEnvironmentModifications(const QList<EnvironmentModificat
if(envModText != "")
envModText += ", ";
envModText += mod.GetDescription();
envModText += GetDescription(mod);
}
ui->envVar->setText(envModText);
@@ -29,6 +29,20 @@
#include "Code/QRDUtils.h"
#include "ui_EnvironmentEditor.h"
static QString GetTypeString(const EnvironmentModification &env)
{
QString ret;
if(env.mod == EnvMod::Append)
ret = QString("Append, %1").arg(ToQStr(env.sep));
else if(env.mod == EnvMod::Prepend)
ret = QString("Prepend, %1").arg(ToQStr(env.sep));
else
ret = "Set";
return ret;
}
Q_DECLARE_METATYPE(EnvironmentModification);
EnvironmentEditor::EnvironmentEditor(QWidget *parent)
@@ -115,17 +129,17 @@ void EnvironmentEditor::on_variables_currentItemChanged(QTreeWidgetItem *current
EnvironmentModification mod = sel[0]->data(0, Qt::UserRole).value<EnvironmentModification>();
if(!mod.variable.isEmpty())
if(!mod.value.empty())
{
ui->name->setText(mod.variable);
ui->value->setText(mod.value);
ui->separator->setCurrentIndex((int)mod.separator);
ui->name->setText(ToQStr(mod.name));
ui->value->setText(ToQStr(mod.value));
ui->separator->setCurrentIndex((int)mod.sep);
if(mod.type == EnvMod::Set)
if(mod.mod == EnvMod::Set)
ui->setValue->setChecked(true);
else if(mod.type == EnvMod::Append)
else if(mod.mod == EnvMod::Append)
ui->appendValue->setChecked(true);
else if(mod.type == EnvMod::Prepend)
else if(mod.mod == EnvMod::Prepend)
ui->prependValue->setChecked(true);
}
}
@@ -133,16 +147,16 @@ void EnvironmentEditor::on_variables_currentItemChanged(QTreeWidgetItem *current
void EnvironmentEditor::on_addUpdate_clicked()
{
EnvironmentModification mod;
mod.variable = ui->name->text();
mod.value = ui->value->text();
mod.separator = (EnvSep)ui->separator->currentIndex();
mod.name = ui->name->text().toUtf8().data();
mod.value = ui->value->text().toUtf8().data();
mod.sep = (EnvSep)ui->separator->currentIndex();
if(ui->appendValue->isChecked())
mod.type = EnvMod::Append;
mod.mod = EnvMod::Append;
else if(ui->prependValue->isChecked())
mod.type = EnvMod::Prepend;
mod.mod = EnvMod::Prepend;
else
mod.type = EnvMod::Set;
mod.mod = EnvMod::Set;
addModification(mod, false);
@@ -174,7 +188,7 @@ int EnvironmentEditor::existingIndex()
void EnvironmentEditor::addModification(EnvironmentModification mod, bool silent)
{
if(mod.variable.trimmed() == "")
if(mod.name.empty())
{
if(!silent)
RDDialog::critical(this, tr("Invalid variable"),
@@ -189,15 +203,15 @@ void EnvironmentEditor::addModification(EnvironmentModification mod, bool silent
if(idx < 0)
{
node = makeTreeNode({mod.variable, mod.GetTypeString(), mod.value});
node = makeTreeNode({ToQStr(mod.name), GetTypeString(mod), ToQStr(mod.value)});
ui->variables->addTopLevelItem(node);
}
else
{
node = ui->variables->topLevelItem(idx);
node->setText(0, mod.variable);
node->setText(1, mod.GetTypeString());
node->setText(2, mod.value);
node->setText(0, ToQStr(mod.name));
node->setText(1, GetTypeString(mod));
node->setText(2, ToQStr(mod.value));
}
node->setData(0, Qt::UserRole, QVariant::fromValue(mod));
@@ -225,7 +239,7 @@ QList<EnvironmentModification> EnvironmentEditor::modifications()
EnvironmentModification mod =
ui->variables->topLevelItem(i)->data(0, Qt::UserRole).value<EnvironmentModification>();
if(!mod.variable.isEmpty())
if(!mod.name.empty())
ret.push_back(mod);
}
+3 -10
View File
@@ -371,20 +371,13 @@ void MainWindow::OnInjectTrigger(uint32_t PID, const QList<EnvironmentModificati
if(!PromptCloseLog())
return;
LambdaThread *th = new LambdaThread([this, PID, env, name, opts, callback]() {
rdctype::array<EnvironmentModification> envList = env.toVector().toStdVector();
LambdaThread *th = new LambdaThread([this, PID, envList, name, opts, callback]() {
QString logfile = m_Ctx.TempLogFilename(name);
void *envList = RENDERDOC_MakeEnvironmentModificationList(env.size());
for(int i = 0; i < env.size(); i++)
RENDERDOC_SetEnvironmentModification(envList, i, env[i].variable.toUtf8().data(),
env[i].value.toUtf8().data(), env[i].type,
env[i].separator);
uint32_t ret = RENDERDOC_InjectIntoProcess(PID, envList, logfile.toUtf8().data(), opts, false);
RENDERDOC_FreeEnvironmentModificationList(envList);
GUIInvoke::call([this, PID, ret, callback]() {
if(ret == 0)
{
+20
View File
@@ -487,3 +487,23 @@ struct TargetControlMessage
};
DECLARE_REFLECTION_STRUCT(TargetControlMessage);
DOCUMENT("A modification to a single environment variable.");
struct EnvironmentModification
{
EnvironmentModification() : mod(EnvMod::Set), sep(EnvSep::NoSep), name(""), value("") {}
EnvironmentModification(EnvMod m, EnvSep s, const char *n, const char *v)
: mod(m), sep(s), name(n), value(v)
{
}
DOCUMENT("The :class:`modification <EnvMod>` to use.");
EnvMod mod;
DOCUMENT("The :class:`separator <EnvSep>` to use if needed.");
EnvSep sep;
DOCUMENT("The name of the environment variable.");
rdctype::str name;
DOCUMENT("The value to use with the modification specified in :data:`mod`.");
rdctype::str value;
};
DECLARE_REFLECTION_STRUCT(EnvironmentModification);
+11 -18
View File
@@ -931,14 +931,15 @@ This happens on the remote system, so all paths are relative to the remote files
directory containing the application is used.
:param str cmdLine: The command line to use when running the application, it will be processed in a
platform specific way to generate arguments.
:param env: Any environment variable modifications that should be made when running the program.
:param list env: Any :class:`EnvironmentModification` that should be made when running the program.
:param CaptureOptions opts: The capture options to use when injecting into the program.
:return: The ident where the new application is listening for target control, or 0 if something went
wrong.
:rtype: ``int``
)");
virtual uint32_t ExecuteAndInject(const char *app, const char *workingDir, const char *cmdLine,
void *env, const CaptureOptions &opts) = 0;
const rdctype::array<EnvironmentModification> &env,
const CaptureOptions &opts) = 0;
DOCUMENT(R"(Take ownership over a capture file.
@@ -1231,7 +1232,7 @@ DOCUMENT(R"(Launch an application and inject into it to allow capturing.
directory containing the application is used.
:param str cmdLine: The command line to use when running the application, it will be processed in a
platform specific way to generate arguments.
:param env: Any environment variable modifications that should be made when running the program.
:param list env: Any :class:`EnvironmentModification` that should be made when running the program.
:param CaptureOptions opts: The capture options to use when injecting into the program.
:param bool waitForExit: If ``True`` this function will block until the process exits.
:return: The ident where the new application is listening for target control, or 0 if something went
@@ -1239,21 +1240,23 @@ DOCUMENT(R"(Launch an application and inject into it to allow capturing.
:rtype: ``int``
)");
extern "C" RENDERDOC_API uint32_t RENDERDOC_CC
RENDERDOC_ExecuteAndInject(const char *app, const char *workingDir, const char *cmdLine, void *env,
const char *logfile, const CaptureOptions &opts, bool32 waitForExit);
RENDERDOC_ExecuteAndInject(const char *app, const char *workingDir, const char *cmdLine,
const rdctype::array<EnvironmentModification> &env, const char *logfile,
const CaptureOptions &opts, bool32 waitForExit);
DOCUMENT(R"(Where supported by operating system and permissions, inject into a running process.
:param int pid: The Process ID (PID) to inject into.
:param env: Any environment variable modifications that should be made when running the program.
:param list env: Any :class:`EnvironmentModification` that should be made when running the program.
:param CaptureOptions opts: The capture options to use when injecting into the program.
:param bool waitForExit: If ``True`` this function will block until the process exits.
:return: The ident where the new application is listening for target control, or 0 if something went
wrong.
:rtype: ``int``
)");
extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_InjectIntoProcess(
uint32_t pid, void *env, const char *logfile, const CaptureOptions &opts, bool32 waitForExit);
extern "C" RENDERDOC_API uint32_t RENDERDOC_CC
RENDERDOC_InjectIntoProcess(uint32_t pid, const rdctype::array<EnvironmentModification> &env,
const char *logfile, const CaptureOptions &opts, bool32 waitForExit);
DOCUMENT(R"(When debugging RenderDoc it can be useful to capture itself by doing a side-build with a
temporary name. This function wraps up the use of the in-application API to start a capture.
@@ -1350,16 +1353,6 @@ DOCUMENT("Internal function for setting a config setting.");
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_SetConfigSetting(const char *name,
const char *value);
DOCUMENT("Internal function for making an environment modification list.");
extern "C" RENDERDOC_API void *RENDERDOC_CC RENDERDOC_MakeEnvironmentModificationList(int numElems);
DOCUMENT("Internal function for setting an element in an environment modification list.");
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_SetEnvironmentModification(
void *mem, int idx, const char *variable, const char *value, EnvMod type, EnvSep separator);
DOCUMENT("Internal function for freeing an environment modification list.");
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_FreeEnvironmentModificationList(void *mem);
DOCUMENT("Internal function for enumerating android devices.");
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_EnumerateAndroidDevices(rdctype::str *deviceList);
+10 -37
View File
@@ -72,9 +72,9 @@ string ToStrHelper<false, EnvSep>::Get(const EnvSep &el)
}
template <>
void Serialiser::Serialise(const char *name, Process::EnvironmentModification &el)
void Serialiser::Serialise(const char *name, EnvironmentModification &el)
{
ScopedContext scope(this, name, "Process::EnvironmentModification", 0, true);
ScopedContext scope(this, name, "EnvironmentModification", 0, true);
Serialise("mod", el.mod);
Serialise("sep", el.sep);
@@ -438,12 +438,8 @@ static void ActiveRemoteClientThread(void *data)
recvser->Serialise("cmdLine", cmdLine);
recvser->Serialise("opts", opts);
uint64_t envListSize = 0;
Process::EnvironmentModification *env = NULL;
recvser->Serialise("envListSize", envListSize);
if(envListSize > 0)
recvser->SerialiseComplexArray("env", env, envListSize);
rdctype::array<EnvironmentModification> env;
recvser->Serialise("env", env);
uint32_t ident = uint32_t(ReplayStatus::NetworkIOFailed);
@@ -457,8 +453,6 @@ static void ActiveRemoteClientThread(void *data)
RDCWARN("Requested to execute program - disallowing based on configuration");
}
SAFE_DELETE_ARRAY(env);
sendType = eRemoteServer_ExecuteAndInject;
sendSer.Serialise("ident", ident);
}
@@ -894,7 +888,8 @@ public:
return ret;
}
uint32_t ExecuteAndInject(const char *app, const char *workingDir, const char *cmdLine, void *env,
uint32_t ExecuteAndInject(const char *app, const char *workingDir, const char *cmdLine,
const rdctype::array<EnvironmentModification> &env,
const CaptureOptions &opts)
{
const char *host = hostname().c_str();
@@ -905,34 +900,12 @@ public:
string workstr = workingDir && workingDir[0] ? workingDir : "";
string cmdstr = cmdLine && cmdLine[0] ? cmdLine : "";
Process::EnvironmentModification *envList = (Process::EnvironmentModification *)env;
Serialiser sendData("", Serialiser::WRITING, false);
sendData.Serialise("app", appstr);
sendData.Serialise("workingDir", workstr);
sendData.Serialise("cmdLine", cmdstr);
sendData.Serialise("opts", (CaptureOptions &)opts);
uint64_t envListSize = 0;
if(envList)
{
Process::EnvironmentModification *it = envList;
for(;;)
{
if(it->name == "")
break;
envListSize++;
it++;
}
// include terminator
envListSize++;
}
sendData.Serialise("envListSize", envListSize);
if(envListSize > 0)
sendData.SerialiseComplexArray("env", envList, envListSize);
sendData.Serialise("env", (rdctype::array<EnvironmentModification> &)env);
Send(eRemoteServer_ExecuteAndInject, sendData);
@@ -1185,9 +1158,9 @@ RemoteServer_RemoteSupportedReplays(IRemoteServer *remote, rdctype::array<rdctyp
*out = remote->RemoteSupportedReplays();
}
extern "C" RENDERDOC_API uint32_t RENDERDOC_CC
RemoteServer_ExecuteAndInject(IRemoteServer *remote, const char *app, const char *workingDir,
const char *cmdLine, void *env, const CaptureOptions &opts)
extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RemoteServer_ExecuteAndInject(
IRemoteServer *remote, const char *app, const char *workingDir, const char *cmdLine,
const rdctype::array<EnvironmentModification> &env, const CaptureOptions &opts)
{
return remote->ExecuteAndInject(app, workingDir, cmdLine, env, opts);
}
+6 -6
View File
@@ -51,7 +51,7 @@ class VulkanHook : LibraryHook
bool CreateHooks(const char *libName)
{
// we assume the implicit layer is registered - the UI will prompt the user about installing it.
Process::RegisterEnvironmentModification(Process::EnvironmentModification(
Process::RegisterEnvironmentModification(EnvironmentModification(
EnvMod::Set, EnvSep::NoSep, "ENABLE_VULKAN_RENDERDOC_CAPTURE", "1"));
// check options to set further variables, and apply
@@ -63,7 +63,7 @@ class VulkanHook : LibraryHook
void EnableHooks(const char *libName, bool enable)
{
// set the env var to 0 to disable the implicit layer
Process::RegisterEnvironmentModification(Process::EnvironmentModification(
Process::RegisterEnvironmentModification(EnvironmentModification(
EnvMod::Set, EnvSep::NoSep, "ENABLE_VULKAN_RENDERDOC_CAPTURE", enable ? "1" : "0"));
Process::ApplyEnvironmentModification();
@@ -74,11 +74,11 @@ class VulkanHook : LibraryHook
if(RenderDoc::Inst().GetCaptureOptions().APIValidation)
{
Process::RegisterEnvironmentModification(
Process::EnvironmentModification(EnvMod::Append, EnvSep::Platform, "VK_INSTANCE_LAYERS",
"VK_LAYER_LUNARG_standard_validation"));
EnvironmentModification(EnvMod::Append, EnvSep::Platform, "VK_INSTANCE_LAYERS",
"VK_LAYER_LUNARG_standard_validation"));
Process::RegisterEnvironmentModification(
Process::EnvironmentModification(EnvMod::Append, EnvSep::Platform, "VK_DEVICE_LAYERS",
"VK_LAYER_LUNARG_standard_validation"));
EnvironmentModification(EnvMod::Append, EnvSep::Platform, "VK_DEVICE_LAYERS",
"VK_LAYER_LUNARG_standard_validation"));
}
else
{
+2 -2
View File
@@ -5579,8 +5579,8 @@ ReplayStatus Vulkan_CreateReplayDevice(const char *logfile, IReplayDriver **driv
RDCDEBUG("Creating a VulkanReplay replay device");
// disable the layer env var, just in case the user left it set from a previous capture run
Process::RegisterEnvironmentModification(Process::EnvironmentModification(
EnvMod::Set, EnvSep::NoSep, "ENABLE_VULKAN_RENDERDOC_CAPTURE", "0"));
Process::RegisterEnvironmentModification(
EnvironmentModification(EnvMod::Set, EnvSep::NoSep, "ENABLE_VULKAN_RENDERDOC_CAPTURE", "0"));
Process::ApplyEnvironmentModification();
void *module = Process::LoadModule(VulkanLibraryName);
+5 -16
View File
@@ -48,25 +48,13 @@ struct CaptureOptions;
namespace Process
{
struct EnvironmentModification
{
EnvironmentModification() : mod(EnvMod::Set), sep(EnvSep::NoSep), name(""), value("") {}
EnvironmentModification(EnvMod m, EnvSep s, const char *n, const char *v)
: mod(m), sep(s), name(n), value(v)
{
}
EnvMod mod;
EnvSep sep;
string name;
string value;
};
void RegisterEnvironmentModification(EnvironmentModification modif);
void ApplyEnvironmentModification();
void StartGlobalHook(const char *pathmatch, const char *logfile, const CaptureOptions &opts);
uint32_t InjectIntoProcess(uint32_t pid, EnvironmentModification *env, const char *logfile,
const CaptureOptions &opts, bool waitForExit);
uint32_t InjectIntoProcess(uint32_t pid, const rdctype::array<EnvironmentModification> &env,
const char *logfile, const CaptureOptions &opts, bool waitForExit);
struct ProcessResult
{
string strStdout, strStderror;
@@ -75,8 +63,9 @@ struct ProcessResult
uint32_t LaunchProcess(const char *app, const char *workingDir, const char *cmdLine,
ProcessResult *result = NULL);
uint32_t LaunchAndInjectIntoProcess(const char *app, const char *workingDir, const char *cmdLine,
EnvironmentModification *env, const char *logfile,
const CaptureOptions &opts, bool waitForExit);
const rdctype::array<EnvironmentModification> &env,
const char *logfile, const CaptureOptions &opts,
bool waitForExit);
void *LoadModule(const char *module);
void *GetFunctionAddress(void *module, const char *function);
uint32_t GetCurrentPID();
+17 -29
View File
@@ -72,9 +72,9 @@ static const string GetAbsoluteAppPathFromName(const string &appName)
return string();
}
static vector<Process::EnvironmentModification> &GetEnvModifications()
static vector<EnvironmentModification> &GetEnvModifications()
{
static vector<Process::EnvironmentModification> envCallbacks;
static vector<EnvironmentModification> envCallbacks;
return envCallbacks;
}
@@ -155,7 +155,7 @@ static string shellExpand(const string &in)
return path;
}
void Process::RegisterEnvironmentModification(Process::EnvironmentModification modif)
void Process::RegisterEnvironmentModification(EnvironmentModification modif)
{
GetEnvModifications().push_back(modif);
}
@@ -178,11 +178,11 @@ void Process::ApplyEnvironmentModification()
{
EnvironmentModification &m = modifications[i];
string value = currentEnv[m.name];
string value = currentEnv[m.name.c_str()];
switch(m.mod)
{
case EnvMod::Set: value = m.value; break;
case EnvMod::Set: value = m.value.c_str(); break;
case EnvMod::Append:
{
if(!value.empty())
@@ -192,7 +192,7 @@ void Process::ApplyEnvironmentModification()
else if(m.sep == EnvSep::SemiColon)
value += ";";
}
value += m.value;
value += m.value.c_str();
break;
}
case EnvMod::Prepend:
@@ -206,7 +206,7 @@ void Process::ApplyEnvironmentModification()
}
else
{
value = m.value;
value = m.value.c_str();
}
break;
}
@@ -403,8 +403,8 @@ static pid_t RunProcess(const char *app, const char *workingDir, const char *cmd
return childPid;
}
uint32_t Process::InjectIntoProcess(uint32_t pid, EnvironmentModification *env, const char *logfile,
const CaptureOptions &opts, bool waitForExit)
uint32_t Process::InjectIntoProcess(uint32_t pid, const rdctype::array<EnvironmentModification> &env,
const char *logfile, const CaptureOptions &opts, bool waitForExit)
{
RDCUNIMPLEMENTED("Injecting into already running processes on linux");
return 0;
@@ -460,7 +460,8 @@ uint32_t Process::LaunchProcess(const char *app, const char *workingDir, const c
}
uint32_t Process::LaunchAndInjectIntoProcess(const char *app, const char *workingDir,
const char *cmdLine, EnvironmentModification *envList,
const char *cmdLine,
const rdctype::array<EnvironmentModification> &envList,
const char *logfile, const CaptureOptions &opts,
bool waitForExit)
{
@@ -475,21 +476,8 @@ uint32_t Process::LaunchAndInjectIntoProcess(const char *app, const char *workin
map<string, string> env = EnvStringToEnvMap((const char **)currentEnvironment);
vector<EnvironmentModification> &modifications = GetEnvModifications();
if(envList)
{
for(;;)
{
EnvironmentModification e = *envList;
e.name = trim(e.name);
if(e.name == "")
break;
modifications.push_back(e);
envList++;
}
}
for(const EnvironmentModification &e : envList)
modifications.push_back(e);
if(logfile == NULL)
logfile = "";
@@ -529,11 +517,11 @@ uint32_t Process::LaunchAndInjectIntoProcess(const char *app, const char *workin
{
EnvironmentModification &m = modifications[i];
string &value = env[m.name];
string &value = env[m.name.c_str()];
switch(m.mod)
{
case EnvMod::Set: value = m.value; break;
case EnvMod::Set: value = m.value.c_str(); break;
case EnvMod::Append:
{
if(!value.empty())
@@ -543,7 +531,7 @@ uint32_t Process::LaunchAndInjectIntoProcess(const char *app, const char *workin
else if(m.sep == EnvSep::SemiColon)
value += ";";
}
value += m.value;
value += m.value.c_str();
break;
}
case EnvMod::Prepend:
@@ -557,7 +545,7 @@ uint32_t Process::LaunchAndInjectIntoProcess(const char *app, const char *workin
}
else
{
value = m.value;
value = m.value.c_str();
}
break;
}
+6 -2
View File
@@ -317,8 +317,10 @@ private:
if(inject)
{
rdctype::array<EnvironmentModification> env;
// inherit logfile and capture options
uint32_t ident = RENDERDOC_InjectIntoProcess(lpProcessInformation->dwProcessId, NULL,
uint32_t ident = RENDERDOC_InjectIntoProcess(lpProcessInformation->dwProcessId, env,
RenderDoc::Inst().GetLogFile(),
RenderDoc::Inst().GetCaptureOptions(), false);
@@ -401,8 +403,10 @@ private:
if(inject)
{
rdctype::array<EnvironmentModification> env;
// inherit logfile and capture options
uint32_t ident = RENDERDOC_InjectIntoProcess(lpProcessInformation->dwProcessId, NULL,
uint32_t ident = RENDERDOC_InjectIntoProcess(lpProcessInformation->dwProcessId, env,
RenderDoc::Inst().GetLogFile(),
RenderDoc::Inst().GetCaptureOptions(), false);
+27 -30
View File
@@ -44,9 +44,9 @@ static wstring lowercase(wstring in)
return ret;
}
static vector<Process::EnvironmentModification> &GetEnvModifications()
static vector<EnvironmentModification> &GetEnvModifications()
{
static vector<Process::EnvironmentModification> envCallbacks;
static vector<EnvironmentModification> envCallbacks;
return envCallbacks;
}
@@ -78,7 +78,7 @@ static map<wstring, string> EnvStringToEnvMap(const wchar_t *envstring)
return ret;
}
void Process::RegisterEnvironmentModification(Process::EnvironmentModification modif)
void Process::RegisterEnvironmentModification(EnvironmentModification modif)
{
GetEnvModifications().push_back(modif);
}
@@ -102,7 +102,7 @@ void Process::ApplyEnvironmentModification()
// set all names to lower case so we can do case-insensitive lookups, but
// preserve the original name so that added variables maintain the same case
wstring name = StringFormat::UTF82Wide(m.name);
wstring name = StringFormat::UTF82Wide(m.name.c_str());
wstring lowername = lowercase(name);
string value;
@@ -116,7 +116,7 @@ void Process::ApplyEnvironmentModification()
switch(m.mod)
{
case EnvMod::Set: value = m.value; break;
case EnvMod::Set: value = m.value.c_str(); break;
case EnvMod::Append:
{
if(!value.empty())
@@ -126,7 +126,7 @@ void Process::ApplyEnvironmentModification()
else if(m.sep == EnvSep::Colon)
value += ":";
}
value += m.value;
value += m.value.c_str();
break;
}
case EnvMod::Prepend:
@@ -140,7 +140,7 @@ void Process::ApplyEnvironmentModification()
}
else
{
value = m.value;
value = m.value.c_str();
}
break;
}
@@ -172,7 +172,7 @@ extern "C" __declspec(dllexport) void __cdecl INTERNAL_SetLogFile(const char *lo
RenderDoc::Inst().SetLogFile(log);
}
static Process::EnvironmentModification tempEnvMod;
static EnvironmentModification tempEnvMod;
extern "C" __declspec(dllexport) void __cdecl INTERNAL_EnvModName(const char *name)
{
@@ -480,8 +480,8 @@ static PROCESS_INFORMATION RunProcess(const char *app, const char *workingDir, c
return pi;
}
uint32_t Process::InjectIntoProcess(uint32_t pid, EnvironmentModification *env, const char *logfile,
const CaptureOptions &opts, bool waitForExit)
uint32_t Process::InjectIntoProcess(uint32_t pid, const rdctype::array<EnvironmentModification> &env,
const char *logfile, const CaptureOptions &opts, bool waitForExit)
{
wstring wlogfile = logfile == NULL ? L"" : StringFormat::UTF82Wide(logfile);
@@ -753,29 +753,29 @@ uint32_t Process::InjectIntoProcess(uint32_t pid, EnvironmentModification *env,
wstring cmdWithEnv;
if(env)
if(!env.empty())
{
cmdWithEnv = paramsAlloc;
for(;;)
for(const EnvironmentModification &e : env)
{
string name = trim(env->name);
string value = env->value;
string name = trim(e.name.c_str());
string value = e.value.c_str();
if(name == "")
break;
cmdWithEnv += L" +env-";
switch(env->mod)
switch(e.mod)
{
case EnvMod::Set: cmdWithEnv += L"replace"; break;
case EnvMod::Append: cmdWithEnv += L"append"; break;
case EnvMod::Prepend: cmdWithEnv += L"prepend"; break;
}
if(env->mod != EnvMod::Set)
if(e.mod != EnvMod::Set)
{
switch(env->sep)
switch(e.sep)
{
case EnvSep::Platform: cmdWithEnv += L"-platform"; break;
case EnvSep::SemiColon: cmdWithEnv += L"-semicolon"; break;
@@ -806,8 +806,6 @@ uint32_t Process::InjectIntoProcess(uint32_t pid, EnvironmentModification *env,
cmdWithEnv += L"\"" + StringFormat::UTF82Wide(name) + L"\" ";
cmdWithEnv += L"\"" + StringFormat::UTF82Wide(value) + L"\" ";
env++;
}
commandLine = (wchar_t *)cmdWithEnv.c_str();
@@ -870,14 +868,14 @@ uint32_t Process::InjectIntoProcess(uint32_t pid, EnvironmentModification *env,
InjectFunctionCall(hProcess, loc, "INTERNAL_GetTargetControlIdent", &controlident,
sizeof(controlident));
if(env)
if(!env.empty())
{
for(;;)
for(const EnvironmentModification &e : env)
{
string name = trim(env->name);
string value = env->value;
EnvMod mod = env->mod;
EnvSep sep = env->sep;
string name = trim(e.name.c_str());
string value = e.value.c_str();
EnvMod mod = e.mod;
EnvSep sep = e.sep;
if(name == "")
break;
@@ -888,13 +886,11 @@ uint32_t Process::InjectIntoProcess(uint32_t pid, EnvironmentModification *env,
value.size() + 1);
InjectFunctionCall(hProcess, loc, "INTERNAL_EnvSep", &sep, sizeof(sep));
InjectFunctionCall(hProcess, loc, "INTERNAL_EnvMod", &mod, sizeof(mod));
env++;
}
// parameter is unused
InjectFunctionCall(hProcess, loc, "INTERNAL_ApplyEnvMods", env,
sizeof(EnvironmentModification));
void *dummy = NULL;
InjectFunctionCall(hProcess, loc, "INTERNAL_ApplyEnvMods", &dummy, sizeof(dummy));
}
}
@@ -959,7 +955,8 @@ uint32_t Process::LaunchProcess(const char *app, const char *workingDir, const c
}
uint32_t Process::LaunchAndInjectIntoProcess(const char *app, const char *workingDir,
const char *cmdLine, EnvironmentModification *env,
const char *cmdLine,
const rdctype::array<EnvironmentModification> &env,
const char *logfile, const CaptureOptions &opts,
bool waitForExit)
{
+15 -13
View File
@@ -260,21 +260,23 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_SetConfigSetting(const char
extern "C" RENDERDOC_API void *RENDERDOC_CC RENDERDOC_MakeEnvironmentModificationList(int numElems)
{
return new Process::EnvironmentModification[numElems + 1]; // last one is a terminator
rdctype::array<EnvironmentModification> *ret = new rdctype::array<EnvironmentModification>();
create_array_uninit(*ret, (size_t)numElems);
return ret;
}
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_SetEnvironmentModification(
void *mem, int idx, const char *variable, const char *value, EnvMod type, EnvSep separator)
{
Process::EnvironmentModification *mods = (Process::EnvironmentModification *)mem;
rdctype::array<EnvironmentModification> *mods = (rdctype::array<EnvironmentModification> *)mem;
mods[idx] = Process::EnvironmentModification(type, separator, variable, value);
mods->elems[idx] = EnvironmentModification(type, separator, variable, value);
}
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_FreeEnvironmentModificationList(void *mem)
{
Process::EnvironmentModification *mods = (Process::EnvironmentModification *)mem;
delete[] mods;
rdctype::array<EnvironmentModification> *mods = (rdctype::array<EnvironmentModification> *)mem;
delete mods;
}
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_SetDebugLogFile(const char *log)
@@ -400,11 +402,11 @@ RENDERDOC_CreateReplayRenderer(const char *logfile, float *progress, IReplayRend
}
extern "C" RENDERDOC_API uint32_t RENDERDOC_CC
RENDERDOC_ExecuteAndInject(const char *app, const char *workingDir, const char *cmdLine, void *env,
const char *logfile, const CaptureOptions &opts, bool32 waitForExit)
RENDERDOC_ExecuteAndInject(const char *app, const char *workingDir, const char *cmdLine,
const rdctype::array<EnvironmentModification> &env, const char *logfile,
const CaptureOptions &opts, bool32 waitForExit)
{
return Process::LaunchAndInjectIntoProcess(app, workingDir, cmdLine,
(Process::EnvironmentModification *)env, logfile, opts,
return Process::LaunchAndInjectIntoProcess(app, workingDir, cmdLine, env, logfile, opts,
waitForExit != 0);
}
@@ -420,11 +422,11 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_StartGlobalHook(const char
Process::StartGlobalHook(pathmatch, logfile, opts);
}
extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_InjectIntoProcess(
uint32_t pid, void *env, const char *logfile, const CaptureOptions &opts, bool32 waitForExit)
extern "C" RENDERDOC_API uint32_t RENDERDOC_CC
RENDERDOC_InjectIntoProcess(uint32_t pid, const rdctype::array<EnvironmentModification> &env,
const char *logfile, const CaptureOptions &opts, bool32 waitForExit)
{
return Process::InjectIntoProcess(pid, (Process::EnvironmentModification *)env, logfile, opts,
waitForExit != 0);
return Process::InjectIntoProcess(pid, env, logfile, opts, waitForExit != 0);
}
static void writeToByteVector(void *context, void *data, int size)
+9 -8
View File
@@ -320,9 +320,11 @@ struct CaptureCommand : public Command
std::cout << std::endl;
rdctype::array<EnvironmentModification> env;
uint32_t ident = RENDERDOC_ExecuteAndInject(
executable.c_str(), workingDir.empty() ? "" : workingDir.c_str(),
cmdLine.empty() ? "" : cmdLine.c_str(), NULL, logFile.empty() ? "" : logFile.c_str(), opts,
cmdLine.empty() ? "" : cmdLine.c_str(), env, logFile.empty() ? "" : logFile.c_str(), opts,
parser.exist("wait-for-exit"));
if(ident == 0)
@@ -382,7 +384,9 @@ struct InjectCommand : public Command
std::cout << "Injecting into PID " << PID << std::endl;
uint32_t ident = RENDERDOC_InjectIntoProcess(PID, NULL, logFile.empty() ? "" : logFile.c_str(),
rdctype::array<EnvironmentModification> env;
uint32_t ident = RENDERDOC_InjectIntoProcess(PID, env, logFile.empty() ? "" : logFile.c_str(),
opts, parser.exist("wait-for-exit"));
if(ident == 0)
@@ -566,7 +570,8 @@ struct CapAltBitCommand : public Command
int numEnvs = int(rest.size() / 3);
void *env = RENDERDOC_MakeEnvironmentModificationList(numEnvs);
rdctype::array<EnvironmentModification> env;
env.create(numEnvs);
for(int i = 0; i < numEnvs; i++)
{
@@ -623,12 +628,10 @@ struct CapAltBitCommand : public Command
else
{
std::cerr << "Invalid generated capaltbit env '" << rest[i * 3 + 0] << std::endl;
RENDERDOC_FreeEnvironmentModificationList(env);
return 0;
}
RENDERDOC_SetEnvironmentModification(env, i, rest[i * 3 + 1].c_str(), rest[i * 3 + 2].c_str(),
type, sep);
env[i] = EnvironmentModification(type, sep, rest[i * 3 + 1].c_str(), rest[i * 3 + 2].c_str());
}
string debuglog = parser.get<string>("debuglog");
@@ -638,8 +641,6 @@ struct CapAltBitCommand : public Command
int ret = RENDERDOC_InjectIntoProcess(parser.get<uint32_t>("pid"), env,
parser.get<string>("log").c_str(), cmdopts, false);
RENDERDOC_FreeEnvironmentModificationList(env);
return ret;
}
};