mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-27 06:26:15 +01:00
Merge branch 'gdbus-win32-no-shortname' into 'master'
gdbusaddress, win32: don't rely on short names Closes #1566 See merge request GNOME/glib!631
This commit is contained in:
commit
cf34d59bed
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
#include "glib/glib-private.h"
|
#include "glib/glib-private.h"
|
||||||
|
#include "gdbusprivate.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
@ -2421,6 +2422,14 @@ main (gint argc, gchar *argv[])
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
else if (g_strcmp0 (command, _GDBUS_ARG_WIN32_RUN_SESSION_BUS) == 0)
|
||||||
|
{
|
||||||
|
g_win32_run_session_bus (NULL, NULL, NULL, 0);
|
||||||
|
ret = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else if (g_strcmp0 (command, "complete") == 0 && argc == 4 && !request_completion)
|
else if (g_strcmp0 (command, "complete") == 0 && argc == 4 && !request_completion)
|
||||||
{
|
{
|
||||||
const gchar *completion_line;
|
const gchar *completion_line;
|
||||||
|
@ -37,8 +37,6 @@
|
|||||||
#include "gtask.h"
|
#include "gtask.h"
|
||||||
#include "glib-private.h"
|
#include "glib-private.h"
|
||||||
#include "gdbusprivate.h"
|
#include "gdbusprivate.h"
|
||||||
#include "giomodule-priv.h"
|
|
||||||
#include "gdbusdaemon.h"
|
|
||||||
#include "gstdio.h"
|
#include "gstdio.h"
|
||||||
|
|
||||||
#ifdef G_OS_UNIX
|
#ifdef G_OS_UNIX
|
||||||
@ -50,8 +48,6 @@
|
|||||||
|
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <io.h>
|
|
||||||
#include <conio.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "glibintl.h"
|
#include "glibintl.h"
|
||||||
@ -1195,325 +1191,12 @@ get_session_address_dbus_launch (GError **error)
|
|||||||
/* end of G_OS_UNIX case */
|
/* end of G_OS_UNIX case */
|
||||||
#elif defined(G_OS_WIN32)
|
#elif defined(G_OS_WIN32)
|
||||||
|
|
||||||
#define DBUS_DAEMON_ADDRESS_INFO "DBusDaemonAddressInfo"
|
|
||||||
#define DBUS_DAEMON_MUTEX "DBusDaemonMutex"
|
|
||||||
#define UNIQUE_DBUS_INIT_MUTEX "UniqueDBusInitMutex"
|
|
||||||
#define DBUS_AUTOLAUNCH_MUTEX "DBusAutolaunchMutex"
|
|
||||||
|
|
||||||
static void
|
|
||||||
release_mutex (HANDLE mutex)
|
|
||||||
{
|
|
||||||
ReleaseMutex (mutex);
|
|
||||||
CloseHandle (mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
static HANDLE
|
|
||||||
acquire_mutex (const char *mutexname)
|
|
||||||
{
|
|
||||||
HANDLE mutex;
|
|
||||||
DWORD res;
|
|
||||||
|
|
||||||
mutex = CreateMutexA (NULL, FALSE, mutexname);
|
|
||||||
if (!mutex)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
res = WaitForSingleObject (mutex, INFINITE);
|
|
||||||
switch (res)
|
|
||||||
{
|
|
||||||
case WAIT_ABANDONED:
|
|
||||||
release_mutex (mutex);
|
|
||||||
return 0;
|
|
||||||
case WAIT_FAILED:
|
|
||||||
case WAIT_TIMEOUT:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mutex;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
is_mutex_owned (const char *mutexname)
|
|
||||||
{
|
|
||||||
HANDLE mutex;
|
|
||||||
gboolean res = FALSE;
|
|
||||||
|
|
||||||
mutex = CreateMutexA (NULL, FALSE, mutexname);
|
|
||||||
if (WaitForSingleObject (mutex, 10) == WAIT_TIMEOUT)
|
|
||||||
res = TRUE;
|
|
||||||
else
|
|
||||||
ReleaseMutex (mutex);
|
|
||||||
CloseHandle (mutex);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
|
||||||
read_shm (const char *shm_name)
|
|
||||||
{
|
|
||||||
HANDLE shared_mem;
|
|
||||||
char *shared_data;
|
|
||||||
char *res;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
res = NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < 20; i++)
|
|
||||||
{
|
|
||||||
shared_mem = OpenFileMappingA (FILE_MAP_READ, FALSE, shm_name);
|
|
||||||
if (shared_mem != 0)
|
|
||||||
break;
|
|
||||||
Sleep (100);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shared_mem != 0)
|
|
||||||
{
|
|
||||||
shared_data = MapViewOfFile (shared_mem, FILE_MAP_READ, 0, 0, 0);
|
|
||||||
if (shared_data != NULL)
|
|
||||||
{
|
|
||||||
res = g_strdup (shared_data);
|
|
||||||
UnmapViewOfFile (shared_data);
|
|
||||||
}
|
|
||||||
CloseHandle (shared_mem);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HANDLE
|
|
||||||
set_shm (const char *shm_name, const char *value)
|
|
||||||
{
|
|
||||||
HANDLE shared_mem;
|
|
||||||
char *shared_data;
|
|
||||||
|
|
||||||
shared_mem = CreateFileMappingA (INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
|
|
||||||
0, strlen (value) + 1, shm_name);
|
|
||||||
if (shared_mem == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
shared_data = MapViewOfFile (shared_mem, FILE_MAP_WRITE, 0, 0, 0 );
|
|
||||||
if (shared_data == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
strcpy (shared_data, value);
|
|
||||||
|
|
||||||
UnmapViewOfFile (shared_data);
|
|
||||||
|
|
||||||
return shared_mem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* These keep state between publish_session_bus and unpublish_session_bus */
|
|
||||||
static HANDLE published_daemon_mutex;
|
|
||||||
static HANDLE published_shared_mem;
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
publish_session_bus (const char *address)
|
|
||||||
{
|
|
||||||
HANDLE init_mutex;
|
|
||||||
|
|
||||||
init_mutex = acquire_mutex (UNIQUE_DBUS_INIT_MUTEX);
|
|
||||||
|
|
||||||
published_daemon_mutex = CreateMutexA (NULL, FALSE, DBUS_DAEMON_MUTEX);
|
|
||||||
if (WaitForSingleObject (published_daemon_mutex, 10 ) != WAIT_OBJECT_0)
|
|
||||||
{
|
|
||||||
release_mutex (init_mutex);
|
|
||||||
CloseHandle (published_daemon_mutex);
|
|
||||||
published_daemon_mutex = NULL;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
published_shared_mem = set_shm (DBUS_DAEMON_ADDRESS_INFO, address);
|
|
||||||
if (!published_shared_mem)
|
|
||||||
{
|
|
||||||
release_mutex (init_mutex);
|
|
||||||
CloseHandle (published_daemon_mutex);
|
|
||||||
published_daemon_mutex = NULL;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
release_mutex (init_mutex);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
unpublish_session_bus (void)
|
|
||||||
{
|
|
||||||
HANDLE init_mutex;
|
|
||||||
|
|
||||||
init_mutex = acquire_mutex (UNIQUE_DBUS_INIT_MUTEX);
|
|
||||||
|
|
||||||
CloseHandle (published_shared_mem);
|
|
||||||
published_shared_mem = NULL;
|
|
||||||
|
|
||||||
release_mutex (published_daemon_mutex);
|
|
||||||
published_daemon_mutex = NULL;
|
|
||||||
|
|
||||||
release_mutex (init_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
wait_console_window (void)
|
|
||||||
{
|
|
||||||
FILE *console = fopen ("CONOUT$", "w");
|
|
||||||
|
|
||||||
SetConsoleTitleW (L"gdbus-daemon output. Type any character to close this window.");
|
|
||||||
fprintf (console, _("(Type any character to close this window)\n"));
|
|
||||||
fflush (console);
|
|
||||||
_getch ();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
open_console_window (void)
|
|
||||||
{
|
|
||||||
if (((HANDLE) _get_osfhandle (fileno (stdout)) == INVALID_HANDLE_VALUE ||
|
|
||||||
(HANDLE) _get_osfhandle (fileno (stderr)) == INVALID_HANDLE_VALUE) && AllocConsole ())
|
|
||||||
{
|
|
||||||
if ((HANDLE) _get_osfhandle (fileno (stdout)) == INVALID_HANDLE_VALUE)
|
|
||||||
freopen ("CONOUT$", "w", stdout);
|
|
||||||
|
|
||||||
if ((HANDLE) _get_osfhandle (fileno (stderr)) == INVALID_HANDLE_VALUE)
|
|
||||||
freopen ("CONOUT$", "w", stderr);
|
|
||||||
|
|
||||||
SetConsoleTitleW (L"gdbus-daemon debug output.");
|
|
||||||
|
|
||||||
atexit (wait_console_window);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
idle_timeout_cb (GDBusDaemon *daemon, gpointer user_data)
|
|
||||||
{
|
|
||||||
GMainLoop *loop = user_data;
|
|
||||||
g_main_loop_quit (loop);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Satisfies STARTF_FORCEONFEEDBACK */
|
|
||||||
static void
|
|
||||||
turn_off_the_starting_cursor (void)
|
|
||||||
{
|
|
||||||
MSG msg;
|
|
||||||
BOOL bRet;
|
|
||||||
|
|
||||||
PostQuitMessage (0);
|
|
||||||
|
|
||||||
while ((bRet = GetMessage (&msg, 0, 0, 0)) != 0)
|
|
||||||
{
|
|
||||||
if (bRet == -1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
TranslateMessage (&msg);
|
|
||||||
DispatchMessage (&msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__declspec(dllexport) void CALLBACK g_win32_run_session_bus (HWND hwnd, HINSTANCE hinst, char *cmdline, int nCmdShow);
|
|
||||||
|
|
||||||
__declspec(dllexport) void CALLBACK
|
|
||||||
g_win32_run_session_bus (HWND hwnd, HINSTANCE hinst, char *cmdline, int nCmdShow)
|
|
||||||
{
|
|
||||||
GDBusDaemon *daemon;
|
|
||||||
GMainLoop *loop;
|
|
||||||
const char *address;
|
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
turn_off_the_starting_cursor ();
|
|
||||||
|
|
||||||
if (g_getenv ("GDBUS_DAEMON_DEBUG") != NULL)
|
|
||||||
open_console_window ();
|
|
||||||
|
|
||||||
loop = g_main_loop_new (NULL, FALSE);
|
|
||||||
|
|
||||||
address = "nonce-tcp:";
|
|
||||||
daemon = _g_dbus_daemon_new (address, NULL, &error);
|
|
||||||
if (daemon == NULL)
|
|
||||||
{
|
|
||||||
g_printerr ("Can't init bus: %s\n", error->message);
|
|
||||||
g_error_free (error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_signal_connect (daemon, "idle-timeout", G_CALLBACK (idle_timeout_cb), loop);
|
|
||||||
|
|
||||||
if (publish_session_bus (_g_dbus_daemon_get_address (daemon)))
|
|
||||||
{
|
|
||||||
g_main_loop_run (loop);
|
|
||||||
|
|
||||||
unpublish_session_bus ();
|
|
||||||
}
|
|
||||||
|
|
||||||
g_main_loop_unref (loop);
|
|
||||||
g_object_unref (daemon);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gchar *
|
static gchar *
|
||||||
get_session_address_dbus_launch (GError **error)
|
get_session_address_dbus_launch (GError **error)
|
||||||
{
|
{
|
||||||
HANDLE autolaunch_mutex, init_mutex;
|
return _g_dbus_win32_get_session_address_dbus_launch (error);
|
||||||
char *address = NULL;
|
|
||||||
wchar_t gio_path[MAX_PATH+1+200];
|
|
||||||
|
|
||||||
autolaunch_mutex = acquire_mutex (DBUS_AUTOLAUNCH_MUTEX);
|
|
||||||
|
|
||||||
init_mutex = acquire_mutex (UNIQUE_DBUS_INIT_MUTEX);
|
|
||||||
|
|
||||||
if (is_mutex_owned (DBUS_DAEMON_MUTEX))
|
|
||||||
address = read_shm (DBUS_DAEMON_ADDRESS_INFO);
|
|
||||||
|
|
||||||
release_mutex (init_mutex);
|
|
||||||
|
|
||||||
if (address == NULL)
|
|
||||||
{
|
|
||||||
gio_path[MAX_PATH] = 0;
|
|
||||||
if (GetModuleFileNameW (_g_io_win32_get_module (), gio_path, MAX_PATH))
|
|
||||||
{
|
|
||||||
PROCESS_INFORMATION pi = { 0 };
|
|
||||||
STARTUPINFOW si = { 0 };
|
|
||||||
BOOL res;
|
|
||||||
wchar_t gio_path_short[MAX_PATH];
|
|
||||||
wchar_t rundll_path[MAX_PATH*2];
|
|
||||||
wchar_t args[MAX_PATH*4];
|
|
||||||
|
|
||||||
GetShortPathNameW (gio_path, gio_path_short, MAX_PATH);
|
|
||||||
|
|
||||||
GetWindowsDirectoryW (rundll_path, MAX_PATH);
|
|
||||||
wcscat (rundll_path, L"\\rundll32.exe");
|
|
||||||
if (GetFileAttributesW (rundll_path) == INVALID_FILE_ATTRIBUTES)
|
|
||||||
{
|
|
||||||
GetSystemDirectoryW (rundll_path, MAX_PATH);
|
|
||||||
wcscat (rundll_path, L"\\rundll32.exe");
|
|
||||||
}
|
|
||||||
|
|
||||||
wcscpy (args, L"\"");
|
|
||||||
wcscat (args, rundll_path);
|
|
||||||
wcscat (args, L"\" ");
|
|
||||||
wcscat (args, gio_path_short);
|
|
||||||
#if defined(_WIN64) || defined(_M_X64) || defined(_M_AMD64)
|
|
||||||
wcscat (args, L",g_win32_run_session_bus");
|
|
||||||
#elif defined (_MSC_VER)
|
|
||||||
wcscat (args, L",_g_win32_run_session_bus@16");
|
|
||||||
#else
|
|
||||||
wcscat (args, L",g_win32_run_session_bus@16");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
res = CreateProcessW (rundll_path, args,
|
|
||||||
0, 0, FALSE,
|
|
||||||
NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW | DETACHED_PROCESS,
|
|
||||||
0, NULL /* TODO: Should be root */,
|
|
||||||
&si, &pi);
|
|
||||||
if (res)
|
|
||||||
address = read_shm (DBUS_DAEMON_ADDRESS_INFO);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
release_mutex (autolaunch_mutex);
|
|
||||||
|
|
||||||
if (address == NULL)
|
|
||||||
g_set_error (error,
|
|
||||||
G_IO_ERROR,
|
|
||||||
G_IO_ERROR_FAILED,
|
|
||||||
_("Session dbus not running, and autolaunch failed"));
|
|
||||||
|
|
||||||
return address;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* neither G_OS_UNIX nor G_OS_WIN32 */
|
#else /* neither G_OS_UNIX nor G_OS_WIN32 */
|
||||||
static gchar *
|
static gchar *
|
||||||
get_session_address_dbus_launch (GError **error)
|
get_session_address_dbus_launch (GError **error)
|
||||||
|
@ -33,6 +33,8 @@
|
|||||||
#include "gdbusproxy.h"
|
#include "gdbusproxy.h"
|
||||||
#include "gdbuserror.h"
|
#include "gdbuserror.h"
|
||||||
#include "gdbusintrospection.h"
|
#include "gdbusintrospection.h"
|
||||||
|
#include "gdbusdaemon.h"
|
||||||
|
#include "giomodule-priv.h"
|
||||||
#include "gtask.h"
|
#include "gtask.h"
|
||||||
#include "ginputstream.h"
|
#include "ginputstream.h"
|
||||||
#include "gmemoryinputstream.h"
|
#include "gmemoryinputstream.h"
|
||||||
@ -51,6 +53,8 @@
|
|||||||
|
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <conio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "glibintl.h"
|
#include "glibintl.h"
|
||||||
@ -2054,6 +2058,357 @@ out:
|
|||||||
CloseHandle (h);
|
CloseHandle (h);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define DBUS_DAEMON_ADDRESS_INFO "DBusDaemonAddressInfo"
|
||||||
|
#define DBUS_DAEMON_MUTEX "DBusDaemonMutex"
|
||||||
|
#define UNIQUE_DBUS_INIT_MUTEX "UniqueDBusInitMutex"
|
||||||
|
#define DBUS_AUTOLAUNCH_MUTEX "DBusAutolaunchMutex"
|
||||||
|
|
||||||
|
static void
|
||||||
|
release_mutex (HANDLE mutex)
|
||||||
|
{
|
||||||
|
ReleaseMutex (mutex);
|
||||||
|
CloseHandle (mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HANDLE
|
||||||
|
acquire_mutex (const char *mutexname)
|
||||||
|
{
|
||||||
|
HANDLE mutex;
|
||||||
|
DWORD res;
|
||||||
|
|
||||||
|
mutex = CreateMutexA (NULL, FALSE, mutexname);
|
||||||
|
if (!mutex)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
res = WaitForSingleObject (mutex, INFINITE);
|
||||||
|
switch (res)
|
||||||
|
{
|
||||||
|
case WAIT_ABANDONED:
|
||||||
|
release_mutex (mutex);
|
||||||
|
return 0;
|
||||||
|
case WAIT_FAILED:
|
||||||
|
case WAIT_TIMEOUT:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_mutex_owned (const char *mutexname)
|
||||||
|
{
|
||||||
|
HANDLE mutex;
|
||||||
|
gboolean res = FALSE;
|
||||||
|
|
||||||
|
mutex = CreateMutexA (NULL, FALSE, mutexname);
|
||||||
|
if (WaitForSingleObject (mutex, 10) == WAIT_TIMEOUT)
|
||||||
|
res = TRUE;
|
||||||
|
else
|
||||||
|
ReleaseMutex (mutex);
|
||||||
|
CloseHandle (mutex);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
read_shm (const char *shm_name)
|
||||||
|
{
|
||||||
|
HANDLE shared_mem;
|
||||||
|
char *shared_data;
|
||||||
|
char *res;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
res = NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < 20; i++)
|
||||||
|
{
|
||||||
|
shared_mem = OpenFileMappingA (FILE_MAP_READ, FALSE, shm_name);
|
||||||
|
if (shared_mem != 0)
|
||||||
|
break;
|
||||||
|
Sleep (100);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shared_mem != 0)
|
||||||
|
{
|
||||||
|
shared_data = MapViewOfFile (shared_mem, FILE_MAP_READ, 0, 0, 0);
|
||||||
|
/* It looks that a race is possible here:
|
||||||
|
* if the dbus process already created mapping but didn't fill it
|
||||||
|
* the code below may read incorrect address.
|
||||||
|
* Also this is a bit complicated by the fact that
|
||||||
|
* any change in the "synchronization contract" between processes
|
||||||
|
* should be accompanied with renaming all of used win32 named objects:
|
||||||
|
* otherwise libgio-2.0-0.dll of different versions shipped with
|
||||||
|
* different apps may break each other due to protocol difference.
|
||||||
|
*/
|
||||||
|
if (shared_data != NULL)
|
||||||
|
{
|
||||||
|
res = g_strdup (shared_data);
|
||||||
|
UnmapViewOfFile (shared_data);
|
||||||
|
}
|
||||||
|
CloseHandle (shared_mem);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HANDLE
|
||||||
|
set_shm (const char *shm_name, const char *value)
|
||||||
|
{
|
||||||
|
HANDLE shared_mem;
|
||||||
|
char *shared_data;
|
||||||
|
|
||||||
|
shared_mem = CreateFileMappingA (INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
|
||||||
|
0, strlen (value) + 1, shm_name);
|
||||||
|
if (shared_mem == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
shared_data = MapViewOfFile (shared_mem, FILE_MAP_WRITE, 0, 0, 0 );
|
||||||
|
if (shared_data == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
strcpy (shared_data, value);
|
||||||
|
|
||||||
|
UnmapViewOfFile (shared_data);
|
||||||
|
|
||||||
|
return shared_mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* These keep state between publish_session_bus and unpublish_session_bus */
|
||||||
|
static HANDLE published_daemon_mutex;
|
||||||
|
static HANDLE published_shared_mem;
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
publish_session_bus (const char *address)
|
||||||
|
{
|
||||||
|
HANDLE init_mutex;
|
||||||
|
|
||||||
|
init_mutex = acquire_mutex (UNIQUE_DBUS_INIT_MUTEX);
|
||||||
|
|
||||||
|
published_daemon_mutex = CreateMutexA (NULL, FALSE, DBUS_DAEMON_MUTEX);
|
||||||
|
if (WaitForSingleObject (published_daemon_mutex, 10 ) != WAIT_OBJECT_0)
|
||||||
|
{
|
||||||
|
release_mutex (init_mutex);
|
||||||
|
CloseHandle (published_daemon_mutex);
|
||||||
|
published_daemon_mutex = NULL;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
published_shared_mem = set_shm (DBUS_DAEMON_ADDRESS_INFO, address);
|
||||||
|
if (!published_shared_mem)
|
||||||
|
{
|
||||||
|
release_mutex (init_mutex);
|
||||||
|
CloseHandle (published_daemon_mutex);
|
||||||
|
published_daemon_mutex = NULL;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
release_mutex (init_mutex);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
unpublish_session_bus (void)
|
||||||
|
{
|
||||||
|
HANDLE init_mutex;
|
||||||
|
|
||||||
|
init_mutex = acquire_mutex (UNIQUE_DBUS_INIT_MUTEX);
|
||||||
|
|
||||||
|
CloseHandle (published_shared_mem);
|
||||||
|
published_shared_mem = NULL;
|
||||||
|
|
||||||
|
release_mutex (published_daemon_mutex);
|
||||||
|
published_daemon_mutex = NULL;
|
||||||
|
|
||||||
|
release_mutex (init_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
wait_console_window (void)
|
||||||
|
{
|
||||||
|
FILE *console = fopen ("CONOUT$", "w");
|
||||||
|
|
||||||
|
SetConsoleTitleW (L"gdbus-daemon output. Type any character to close this window.");
|
||||||
|
fprintf (console, _("(Type any character to close this window)\n"));
|
||||||
|
fflush (console);
|
||||||
|
_getch ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
open_console_window (void)
|
||||||
|
{
|
||||||
|
if (((HANDLE) _get_osfhandle (fileno (stdout)) == INVALID_HANDLE_VALUE ||
|
||||||
|
(HANDLE) _get_osfhandle (fileno (stderr)) == INVALID_HANDLE_VALUE) && AllocConsole ())
|
||||||
|
{
|
||||||
|
if ((HANDLE) _get_osfhandle (fileno (stdout)) == INVALID_HANDLE_VALUE)
|
||||||
|
freopen ("CONOUT$", "w", stdout);
|
||||||
|
|
||||||
|
if ((HANDLE) _get_osfhandle (fileno (stderr)) == INVALID_HANDLE_VALUE)
|
||||||
|
freopen ("CONOUT$", "w", stderr);
|
||||||
|
|
||||||
|
SetConsoleTitleW (L"gdbus-daemon debug output.");
|
||||||
|
|
||||||
|
atexit (wait_console_window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
idle_timeout_cb (GDBusDaemon *daemon, gpointer user_data)
|
||||||
|
{
|
||||||
|
GMainLoop *loop = user_data;
|
||||||
|
g_main_loop_quit (loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Satisfies STARTF_FORCEONFEEDBACK */
|
||||||
|
static void
|
||||||
|
turn_off_the_starting_cursor (void)
|
||||||
|
{
|
||||||
|
MSG msg;
|
||||||
|
BOOL bRet;
|
||||||
|
|
||||||
|
PostQuitMessage (0);
|
||||||
|
|
||||||
|
while ((bRet = GetMessage (&msg, 0, 0, 0)) != 0)
|
||||||
|
{
|
||||||
|
if (bRet == -1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
TranslateMessage (&msg);
|
||||||
|
DispatchMessage (&msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(dllexport) void __stdcall
|
||||||
|
g_win32_run_session_bus (void* hwnd, void* hinst, const char* cmdline, int cmdshow)
|
||||||
|
{
|
||||||
|
GDBusDaemon *daemon;
|
||||||
|
GMainLoop *loop;
|
||||||
|
const char *address;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
turn_off_the_starting_cursor ();
|
||||||
|
|
||||||
|
if (g_getenv ("GDBUS_DAEMON_DEBUG") != NULL)
|
||||||
|
open_console_window ();
|
||||||
|
|
||||||
|
address = "nonce-tcp:";
|
||||||
|
daemon = _g_dbus_daemon_new (address, NULL, &error);
|
||||||
|
if (daemon == NULL)
|
||||||
|
{
|
||||||
|
g_printerr ("Can't init bus: %s\n", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
|
||||||
|
/* There is a subtle detail with "idle-timeout" signal of dbus daemon:
|
||||||
|
* It is fired on idle after last client disconnection,
|
||||||
|
* but (at least with glib 2.59.1) it is NEVER fired
|
||||||
|
* if no clients connect to daemon at all.
|
||||||
|
* This may lead to infinite run of this daemon process.
|
||||||
|
*/
|
||||||
|
g_signal_connect (daemon, "idle-timeout", G_CALLBACK (idle_timeout_cb), loop);
|
||||||
|
|
||||||
|
if (publish_session_bus (_g_dbus_daemon_get_address (daemon)))
|
||||||
|
{
|
||||||
|
g_main_loop_run (loop);
|
||||||
|
|
||||||
|
unpublish_session_bus ();
|
||||||
|
}
|
||||||
|
|
||||||
|
g_main_loop_unref (loop);
|
||||||
|
g_object_unref (daemon);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean autolaunch_binary_absent = FALSE;
|
||||||
|
|
||||||
|
gchar *
|
||||||
|
_g_dbus_win32_get_session_address_dbus_launch (GError **error)
|
||||||
|
{
|
||||||
|
HANDLE autolaunch_mutex, init_mutex;
|
||||||
|
char *address = NULL;
|
||||||
|
|
||||||
|
autolaunch_mutex = acquire_mutex (DBUS_AUTOLAUNCH_MUTEX);
|
||||||
|
|
||||||
|
init_mutex = acquire_mutex (UNIQUE_DBUS_INIT_MUTEX);
|
||||||
|
|
||||||
|
if (is_mutex_owned (DBUS_DAEMON_MUTEX))
|
||||||
|
address = read_shm (DBUS_DAEMON_ADDRESS_INFO);
|
||||||
|
|
||||||
|
release_mutex (init_mutex);
|
||||||
|
|
||||||
|
if (address == NULL && !autolaunch_binary_absent)
|
||||||
|
{
|
||||||
|
wchar_t gio_path[MAX_PATH + 2] = { 0 };
|
||||||
|
int gio_path_len = GetModuleFileNameW (_g_io_win32_get_module (), gio_path, MAX_PATH + 1);
|
||||||
|
|
||||||
|
/* The <= MAX_PATH check prevents truncated path usage */
|
||||||
|
if (gio_path_len > 0 && gio_path_len <= MAX_PATH)
|
||||||
|
{
|
||||||
|
PROCESS_INFORMATION pi = { 0 };
|
||||||
|
STARTUPINFOW si = { 0 };
|
||||||
|
BOOL res = FALSE;
|
||||||
|
wchar_t exe_path[MAX_PATH + 100] = { 0 };
|
||||||
|
/* calculate index of first char of dll file name inside full path */
|
||||||
|
int gio_name_index = gio_path_len;
|
||||||
|
for (; gio_name_index > 0; --gio_name_index)
|
||||||
|
{
|
||||||
|
wchar_t prev_char = gio_path[gio_name_index - 1];
|
||||||
|
if (prev_char == L'\\' || prev_char == L'/')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
gio_path[gio_name_index] = L'\0';
|
||||||
|
wcscpy (exe_path, gio_path);
|
||||||
|
wcscat (exe_path, L"\\gdbus.exe");
|
||||||
|
|
||||||
|
if (GetFileAttributesW (exe_path) == INVALID_FILE_ATTRIBUTES)
|
||||||
|
{
|
||||||
|
/* warning won't be raised another time
|
||||||
|
* since autolaunch_binary_absent would be already set.
|
||||||
|
*/
|
||||||
|
autolaunch_binary_absent = TRUE;
|
||||||
|
g_warning ("win32 session dbus binary not found: %S", exe_path );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wchar_t args[MAX_PATH*2 + 100] = { 0 };
|
||||||
|
wcscpy (args, L"\"");
|
||||||
|
wcscat (args, exe_path);
|
||||||
|
wcscat (args, L"\" ");
|
||||||
|
#define _L_PREFIX_FOR_EXPANDED(arg) L##arg
|
||||||
|
#define _L_PREFIX(arg) _L_PREFIX_FOR_EXPANDED (arg)
|
||||||
|
wcscat (args, _L_PREFIX (_GDBUS_ARG_WIN32_RUN_SESSION_BUS));
|
||||||
|
#undef _L_PREFIX
|
||||||
|
#undef _L_PREFIX_FOR_EXPANDED
|
||||||
|
|
||||||
|
res = CreateProcessW (exe_path, args,
|
||||||
|
0, 0, FALSE,
|
||||||
|
NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW | DETACHED_PROCESS,
|
||||||
|
0, gio_path,
|
||||||
|
&si, &pi);
|
||||||
|
}
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
address = read_shm (DBUS_DAEMON_ADDRESS_INFO);
|
||||||
|
if (address == NULL)
|
||||||
|
g_warning ("%S dbus binary failed to launch bus, maybe incompatible version", exe_path );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
release_mutex (autolaunch_mutex);
|
||||||
|
|
||||||
|
if (address == NULL)
|
||||||
|
g_set_error (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_FAILED,
|
||||||
|
_("Session dbus not running, and autolaunch failed"));
|
||||||
|
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
@ -109,6 +109,17 @@ gchar *_g_dbus_hexdump (const gchar *data, gsize len, guint indent);
|
|||||||
|
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
gchar *_g_dbus_win32_get_user_sid (void);
|
gchar *_g_dbus_win32_get_user_sid (void);
|
||||||
|
|
||||||
|
#define _GDBUS_ARG_WIN32_RUN_SESSION_BUS "_win32_run_session_bus"
|
||||||
|
/* The g_win32_run_session_bus is exported from libgio dll on win32,
|
||||||
|
* but still is NOT part of API/ABI since it is declared in private header
|
||||||
|
* and used only by tool built from same sources.
|
||||||
|
* Initially this function was introduces for usage with rundll,
|
||||||
|
* so the signature is kept rundll-compatible, though parameters aren't used.
|
||||||
|
*/
|
||||||
|
__declspec(dllexport) void __stdcall
|
||||||
|
g_win32_run_session_bus (void* hwnd, void* hinst, const char* cmdline, int cmdshow);
|
||||||
|
gchar *_g_dbus_win32_get_session_address_dbus_launch (GError **error);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gchar *_g_dbus_get_machine_id (GError **error);
|
gchar *_g_dbus_get_machine_id (GError **error);
|
||||||
|
2
gio/tests/.gitignore
vendored
2
gio/tests/.gitignore
vendored
@ -76,7 +76,7 @@ gdbus-test-codegen-old
|
|||||||
gdbus-test-fixture
|
gdbus-test-fixture
|
||||||
gdbus-testserver
|
gdbus-testserver
|
||||||
gdbus-threading
|
gdbus-threading
|
||||||
gdbus-unix-addresses
|
gdbus-address-get-session
|
||||||
glistmodel
|
glistmodel
|
||||||
gio-du
|
gio-du
|
||||||
giomodule
|
giomodule
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Mock version of dbus-launch, for gdbus-unix-addresses test
|
* Mock version of dbus-launch, for gdbus-address-get-session test
|
||||||
*
|
*
|
||||||
* Copyright © 2015 Collabora Ltd.
|
* Copyright © 2015 Collabora Ltd.
|
||||||
*
|
*
|
||||||
|
@ -18,9 +18,12 @@
|
|||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
#ifndef G_OS_UNIX
|
/* This test does NOT depend on any dbus binaries preinstalled on test host.
|
||||||
#error This is a Unix-specific test
|
* On Unix it uses mock environment (test_xdg_runtime)
|
||||||
#endif
|
* or mock dbus-launch binary (test_x11_autolaunch).
|
||||||
|
* On Windows it relies on the fact that libgio provides
|
||||||
|
* internal session dbus-server on win32.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
@ -43,6 +46,8 @@ print_address (void)
|
|||||||
g_free (addr);
|
g_free (addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
|
||||||
static GSocket *mock_bus = NULL;
|
static GSocket *mock_bus = NULL;
|
||||||
static gchar *mock_bus_path = NULL;
|
static gchar *mock_bus_path = NULL;
|
||||||
/* this is deliberately something that needs escaping */
|
/* this is deliberately something that needs escaping */
|
||||||
@ -166,14 +171,57 @@ test_xdg_runtime (void)
|
|||||||
g_test_trap_assert_passed ();
|
g_test_trap_assert_passed ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
static void
|
||||||
|
check_and_cleanup_autolaunched_win32_bus (void)
|
||||||
|
{
|
||||||
|
/* win32 autostarted bus runs infinitely if no client ever connected.
|
||||||
|
* However it exits in several seconds if the last client disconnects.
|
||||||
|
* _This_ test only checks successful launching and connectivity,
|
||||||
|
* and don't bother on bus termination behavior (being it a bug or not).
|
||||||
|
* So connect+disconnect here is not only connectivity test,
|
||||||
|
* but also the workaround the bus process infinite run.
|
||||||
|
*/
|
||||||
|
GError *err = NULL;
|
||||||
|
GDBusConnection *bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &err);
|
||||||
|
g_assert_no_error (err);
|
||||||
|
g_object_unref (bus);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_win32_autolaunch (void)
|
||||||
|
{
|
||||||
|
if (g_test_subprocess ())
|
||||||
|
{
|
||||||
|
print_address ();
|
||||||
|
|
||||||
|
check_and_cleanup_autolaunched_win32_bus ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_test_trap_subprocess (NULL, 0, 0);
|
||||||
|
/* stderr is not checked: coverage prints warnings there */
|
||||||
|
g_test_trap_assert_stdout ("nonce-tcp:host=localhost,port=*,noncefile=*\\gdbus-nonce-file-*\n");
|
||||||
|
g_test_trap_assert_passed ();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc,
|
main (int argc,
|
||||||
char *argv[])
|
char *argv[])
|
||||||
{
|
{
|
||||||
g_test_init (&argc, &argv, NULL);
|
g_test_init (&argc, &argv, NULL);
|
||||||
|
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
g_test_add_func ("/gdbus/x11-autolaunch", test_x11_autolaunch);
|
g_test_add_func ("/gdbus/x11-autolaunch", test_x11_autolaunch);
|
||||||
g_test_add_func ("/gdbus/xdg-runtime", test_xdg_runtime);
|
g_test_add_func ("/gdbus/xdg-runtime", test_xdg_runtime);
|
||||||
|
#endif
|
||||||
|
|
||||||
return g_test_run();
|
#ifdef G_OS_WIN32
|
||||||
|
g_test_add_func ("/gdbus/win32-autolaunch", test_win32_autolaunch);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return g_test_run ();
|
||||||
}
|
}
|
@ -79,6 +79,7 @@ gio_tests = {
|
|||||||
'tls-certificate' : {'extra_sources' : ['gtesttlsbackend.c']},
|
'tls-certificate' : {'extra_sources' : ['gtesttlsbackend.c']},
|
||||||
'tls-interaction' : {'extra_sources' : ['gtesttlsbackend.c']},
|
'tls-interaction' : {'extra_sources' : ['gtesttlsbackend.c']},
|
||||||
'tls-database' : {'extra_sources' : ['gtesttlsbackend.c']},
|
'tls-database' : {'extra_sources' : ['gtesttlsbackend.c']},
|
||||||
|
'gdbus-address-get-session' : {},
|
||||||
}
|
}
|
||||||
|
|
||||||
test_extra_programs = {
|
test_extra_programs = {
|
||||||
@ -284,7 +285,6 @@ if host_machine.system() != 'windows'
|
|||||||
'-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_36'],
|
'-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_36'],
|
||||||
},
|
},
|
||||||
'gapplication' : {'extra_sources' : extra_sources},
|
'gapplication' : {'extra_sources' : extra_sources},
|
||||||
'gdbus-unix-addresses' : {},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if not glib_have_cocoa
|
if not glib_have_cocoa
|
||||||
|
@ -3630,7 +3630,7 @@ g_test_trap_assertions (const char *domain,
|
|||||||
|
|
||||||
logged_child_output = logged_child_output || log_child_output (process_id);
|
logged_child_output = logged_child_output || log_child_output (process_id);
|
||||||
|
|
||||||
msg = g_strdup_printf ("stdout of child process (%s) %s: %s\nstderr was:\n%s",
|
msg = g_strdup_printf ("stdout of child process (%s) %s: %s\nstdout was:\n%s",
|
||||||
process_id, match_error, stdout_pattern, test_trap_last_stdout);
|
process_id, match_error, stdout_pattern, test_trap_last_stdout);
|
||||||
g_assertion_message (domain, file, line, func, msg);
|
g_assertion_message (domain, file, line, func, msg);
|
||||||
g_free (msg);
|
g_free (msg);
|
||||||
|
Loading…
Reference in New Issue
Block a user