mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-29 18:48:44 +00:00
pluginloader-win32: Prepend gstreamer-1.0-0.dll directory to PATH env for child process
Usually gst-plugin-scanner.exe will be located under libexec/gstreamer-1.0 or even somewhere user specified location via GST_PLUGIN_SCANNER environment. So, in order for child process to be able to load GStreamer DLLs, parent process will need to update PATH env Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3886>
This commit is contained in:
parent
bc0708eafb
commit
c0a4f41525
1 changed files with 89 additions and 2 deletions
|
@ -32,6 +32,8 @@
|
|||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
||||
extern HMODULE _priv_gst_dll_handle;
|
||||
|
||||
/* IMPORTANT: Bump the version number if the plugin loader packet protocol
|
||||
* changes. Changes in the binary registry format itself are handled by
|
||||
* bumping the GST_MAGIC_BINARY_VERSION_STR
|
||||
|
@ -163,6 +165,8 @@ struct _GstPluginLoader
|
|||
GstRegistry *registry;
|
||||
gchar *pipe_prefix;
|
||||
|
||||
wchar_t *env_string;
|
||||
|
||||
PROCESS_INFORMATION child_info;
|
||||
|
||||
gboolean got_plugin_detail;
|
||||
|
@ -336,8 +340,9 @@ gst_plugin_loader_try_helper (GstPluginLoader * self, gchar * location)
|
|||
|
||||
GST_LOG ("Trying to spawn gst-plugin-scanner helper at %s, command %s",
|
||||
location, cmd);
|
||||
ret = CreateProcessW (NULL, (WCHAR *) wcmd, NULL, NULL, FALSE, 0,
|
||||
NULL, NULL, &si, &self->child_info);
|
||||
ret = CreateProcessW (NULL, (WCHAR *) wcmd, NULL, NULL, FALSE,
|
||||
CREATE_UNICODE_ENVIRONMENT, (LPVOID) self->env_string, NULL, &si,
|
||||
&self->child_info);
|
||||
|
||||
if (!ret) {
|
||||
last_err = GetLastError ();
|
||||
|
@ -982,11 +987,35 @@ gst_plugin_loader_server_load (GstPluginLoader * self,
|
|||
return win32_plugin_loader_run (loader, 10000);
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
static gboolean
|
||||
is_path_env_string (wchar_t *str)
|
||||
{
|
||||
if (wcslen (str) <= wcslen (L"PATH="))
|
||||
return FALSE;
|
||||
|
||||
/* Env variable is case-insensitive */
|
||||
if ((str[0] == L'P' || str[0] == L'p') &&
|
||||
(str[1] == L'A' || str[1] == L'a') &&
|
||||
(str[2] == L'T' || str[2] == L't') &&
|
||||
(str[3] == L'H' || str[3] == L'h') && str[4] == L'=') {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
/* *INDENT-ON* */
|
||||
|
||||
static GstPluginLoader *
|
||||
gst_plugin_loader_new (GstRegistry * registry)
|
||||
{
|
||||
GstPluginLoader *self;
|
||||
Win32PluginLoader *loader;
|
||||
wchar_t *env_str;
|
||||
size_t origin_len;
|
||||
guint i;
|
||||
wchar_t lib_dir[MAX_PATH];
|
||||
wchar_t *origin_path = NULL;
|
||||
|
||||
if (!registry)
|
||||
return NULL;
|
||||
|
@ -1003,6 +1032,62 @@ gst_plugin_loader_new (GstRegistry * registry)
|
|||
g_queue_init (&self->pending_plugins);
|
||||
self->registry = gst_object_ref (registry);
|
||||
|
||||
env_str = GetEnvironmentStringsW ();
|
||||
/* Count original env string length */
|
||||
for (i = 0, origin_len = 0; env_str[origin_len]; i++) {
|
||||
if (!origin_path) {
|
||||
if (is_path_env_string (&env_str[origin_len]))
|
||||
origin_path = _wcsdup (&env_str[origin_len]);
|
||||
}
|
||||
|
||||
origin_len += wcslen (&env_str[origin_len]) + 1;
|
||||
}
|
||||
|
||||
/* Environment string is terminated with additional L'\0' */
|
||||
origin_len++;
|
||||
|
||||
if (GetModuleFileNameW (_priv_gst_dll_handle, lib_dir, MAX_PATH)) {
|
||||
wchar_t *new_env_string, *pos;
|
||||
size_t new_len;
|
||||
size_t lib_dir_len;
|
||||
wchar_t *sep = wcsrchr (lib_dir, L'\\');
|
||||
if (sep)
|
||||
*sep = L'\0';
|
||||
|
||||
lib_dir_len = wcslen (lib_dir);
|
||||
|
||||
/* +1 for L';' seperator */
|
||||
new_len = origin_len + lib_dir_len + 1;
|
||||
|
||||
new_env_string = calloc (1, sizeof (wchar_t) * new_len);
|
||||
|
||||
pos = new_env_string;
|
||||
/* Copy every env except for PATH */
|
||||
for (i = 0, origin_len = 0; env_str[origin_len]; i++) {
|
||||
size_t len = wcslen (&env_str[origin_len]);
|
||||
if (!is_path_env_string (&env_str[origin_len])) {
|
||||
wcscpy (pos, &env_str[origin_len]);
|
||||
pos += len + 1;
|
||||
}
|
||||
|
||||
origin_len += len + 1;
|
||||
}
|
||||
|
||||
/* Then copy PATH env */
|
||||
wcscpy (pos, L"PATH=");
|
||||
pos += wcslen (L"PATH=");
|
||||
wcscpy (pos, lib_dir);
|
||||
pos += lib_dir_len;
|
||||
*pos = L';';
|
||||
if (origin_path)
|
||||
wcscpy (pos + 1, origin_path + wcslen (L"PATH="));
|
||||
|
||||
self->env_string = new_env_string;
|
||||
}
|
||||
|
||||
free (origin_path);
|
||||
FreeEnvironmentStringsW (env_str);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -1132,6 +1217,8 @@ gst_plugin_loader_free (GstPluginLoader * self)
|
|||
gst_clear_object (&self->registry);
|
||||
g_queue_clear_full (&self->pending_plugins,
|
||||
(GDestroyNotify) pending_plugin_entry_free);
|
||||
|
||||
free (self->env_string);
|
||||
g_free (self);
|
||||
|
||||
return got_plugin_detail;
|
||||
|
|
Loading…
Reference in a new issue