mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-31 10:41:12 +00:00
a82f4dd9b7
When using native compiler exceptions, it isn't valid to use GetExceptionCode and GetExceptionInformation anywhere other than in the filter or handler blocks since it would be very hard for the compiler to work out where to retrieve the exception information from on the stack. Therefore, remove the WINE_EXCEPTION_FILTER and WINE_FINALLY_FUNC macros which enabled GetExceptionCode, GetExceptionInformation and AbnormalTermination to be used inside of the functions they declared and fix up all callers to access the information directly.
249 lines
7.1 KiB
C
249 lines
7.1 KiB
C
/*
|
|
* HAL devices support
|
|
*
|
|
* Copyright 2006 Alexandre Julliard
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
#include "config.h"
|
|
#include "wine/port.h"
|
|
|
|
#include <assert.h>
|
|
#include <errno.h>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <sys/time.h>
|
|
|
|
#include "windef.h"
|
|
#include "winbase.h"
|
|
#include "winreg.h"
|
|
#include "winuser.h"
|
|
#include "excpt.h"
|
|
|
|
#include "wine/library.h"
|
|
#include "wine/exception.h"
|
|
#include "wine/debug.h"
|
|
#include "explorer_private.h"
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(explorer);
|
|
|
|
#ifdef SONAME_LIBHAL
|
|
|
|
#include <dbus/dbus.h>
|
|
#include <hal/libhal.h>
|
|
|
|
#define DBUS_FUNCS \
|
|
DO_FUNC(dbus_bus_get); \
|
|
DO_FUNC(dbus_connection_close); \
|
|
DO_FUNC(dbus_connection_read_write_dispatch); \
|
|
DO_FUNC(dbus_error_init); \
|
|
DO_FUNC(dbus_error_free); \
|
|
DO_FUNC(dbus_error_is_set)
|
|
|
|
#define HAL_FUNCS \
|
|
DO_FUNC(libhal_ctx_free); \
|
|
DO_FUNC(libhal_ctx_init); \
|
|
DO_FUNC(libhal_ctx_new); \
|
|
DO_FUNC(libhal_ctx_set_dbus_connection); \
|
|
DO_FUNC(libhal_ctx_set_device_added); \
|
|
DO_FUNC(libhal_ctx_set_device_property_modified); \
|
|
DO_FUNC(libhal_ctx_set_device_removed); \
|
|
DO_FUNC(libhal_ctx_shutdown); \
|
|
DO_FUNC(libhal_device_get_property_bool); \
|
|
DO_FUNC(libhal_device_get_property_string); \
|
|
DO_FUNC(libhal_device_add_property_watch); \
|
|
DO_FUNC(libhal_device_remove_property_watch); \
|
|
DO_FUNC(libhal_free_string); \
|
|
DO_FUNC(libhal_free_string_array); \
|
|
DO_FUNC(libhal_get_all_devices)
|
|
|
|
#define DO_FUNC(f) static typeof(f) * p_##f
|
|
DBUS_FUNCS;
|
|
HAL_FUNCS;
|
|
#undef DO_FUNC
|
|
|
|
static BOOL load_functions(void)
|
|
{
|
|
void *hal_handle;
|
|
char error[128];
|
|
|
|
/* Load libhal with RTLD_GLOBAL so that the dbus symbols are available.
|
|
* We can't load libdbus directly since libhal may have been built against a
|
|
* different version but with the same soname. Binary compatibility is for wimps. */
|
|
|
|
if (!(hal_handle = wine_dlopen(SONAME_LIBHAL, RTLD_NOW|RTLD_GLOBAL, error, sizeof(error))))
|
|
goto failed;
|
|
|
|
#define DO_FUNC(f) if (!(p_##f = wine_dlsym( RTLD_DEFAULT, #f, error, sizeof(error) ))) goto failed
|
|
DBUS_FUNCS;
|
|
#undef DO_FUNC
|
|
|
|
#define DO_FUNC(f) if (!(p_##f = wine_dlsym( hal_handle, #f, error, sizeof(error) ))) goto failed
|
|
HAL_FUNCS;
|
|
#undef DO_FUNC
|
|
|
|
return TRUE;
|
|
|
|
failed:
|
|
WINE_WARN( "failed to load HAL support: %s\n", error );
|
|
return FALSE;
|
|
}
|
|
|
|
static LONG WINAPI assert_fault(EXCEPTION_POINTERS *eptr)
|
|
{
|
|
if (eptr->ExceptionRecord->ExceptionCode == EXCEPTION_WINE_ASSERTION)
|
|
return EXCEPTION_EXECUTE_HANDLER;
|
|
return EXCEPTION_CONTINUE_SEARCH;
|
|
}
|
|
|
|
/* HAL callback for new device */
|
|
static void new_device( LibHalContext *ctx, const char *udi )
|
|
{
|
|
DBusError error;
|
|
char *parent = NULL;
|
|
char *mount_point = NULL;
|
|
char *device = NULL;
|
|
char *type = NULL;
|
|
|
|
p_dbus_error_init( &error );
|
|
|
|
if (!(device = p_libhal_device_get_property_string( ctx, udi, "block.device", &error )))
|
|
goto done;
|
|
|
|
if (!(mount_point = p_libhal_device_get_property_string( ctx, udi, "volume.mount_point", &error )))
|
|
goto done;
|
|
|
|
if (!(parent = p_libhal_device_get_property_string( ctx, udi, "info.parent", &error )))
|
|
goto done;
|
|
|
|
if (!p_libhal_device_get_property_bool( ctx, parent, "storage.removable", &error ))
|
|
goto done;
|
|
|
|
if (!(type = p_libhal_device_get_property_string( ctx, parent, "storage.drive_type", &error )))
|
|
p_dbus_error_free( &error ); /* ignore error */
|
|
|
|
add_dos_device( udi, device, mount_point, type );
|
|
|
|
/* add property watch for mount point */
|
|
p_libhal_device_add_property_watch( ctx, udi, &error );
|
|
|
|
done:
|
|
if (type) p_libhal_free_string( type );
|
|
if (parent) p_libhal_free_string( parent );
|
|
if (device) p_libhal_free_string( device );
|
|
if (mount_point) p_libhal_free_string( mount_point );
|
|
p_dbus_error_free( &error );
|
|
}
|
|
|
|
/* HAL callback for removed device */
|
|
static void removed_device( LibHalContext *ctx, const char *udi )
|
|
{
|
|
DBusError error;
|
|
|
|
WINE_TRACE( "removed %s\n", wine_dbgstr_a(udi) );
|
|
|
|
if (remove_dos_device( udi ))
|
|
{
|
|
p_dbus_error_init( &error );
|
|
p_libhal_device_remove_property_watch( ctx, udi, &error );
|
|
p_dbus_error_free( &error );
|
|
}
|
|
}
|
|
|
|
/* HAL callback for property changes */
|
|
static void property_modified (LibHalContext *ctx, const char *udi,
|
|
const char *key, dbus_bool_t is_removed, dbus_bool_t is_added)
|
|
{
|
|
WINE_TRACE( "udi %s key %s %s\n", wine_dbgstr_a(udi), wine_dbgstr_a(key),
|
|
is_added ? "added" : is_removed ? "removed" : "modified" );
|
|
|
|
if (!strcmp( key, "volume.mount_point" )) new_device( ctx, udi );
|
|
}
|
|
|
|
|
|
static DWORD WINAPI hal_thread( void *arg )
|
|
{
|
|
DBusError error;
|
|
DBusConnection *dbc;
|
|
LibHalContext *ctx;
|
|
int i, num;
|
|
char **list;
|
|
|
|
if (!(ctx = p_libhal_ctx_new())) return 1;
|
|
|
|
p_dbus_error_init( &error );
|
|
if (!(dbc = p_dbus_bus_get( DBUS_BUS_SYSTEM, &error )))
|
|
{
|
|
WINE_WARN( "failed to get system dbus connection: %s\n", error.message );
|
|
p_dbus_error_free( &error );
|
|
return 1;
|
|
}
|
|
|
|
p_libhal_ctx_set_dbus_connection( ctx, dbc );
|
|
p_libhal_ctx_set_device_added( ctx, new_device );
|
|
p_libhal_ctx_set_device_removed( ctx, removed_device );
|
|
p_libhal_ctx_set_device_property_modified( ctx, property_modified );
|
|
|
|
if (!p_libhal_ctx_init( ctx, &error ))
|
|
{
|
|
WINE_WARN( "HAL context init failed: %s\n", error.message );
|
|
p_dbus_error_free( &error );
|
|
return 1;
|
|
}
|
|
|
|
/* retrieve all existing devices */
|
|
if (!(list = p_libhal_get_all_devices( ctx, &num, &error ))) p_dbus_error_free( &error );
|
|
else
|
|
{
|
|
for (i = 0; i < num; i++) new_device( ctx, list[i] );
|
|
p_libhal_free_string_array( list );
|
|
}
|
|
|
|
__TRY
|
|
{
|
|
while (p_dbus_connection_read_write_dispatch( dbc, -1 )) /* nothing */ ;
|
|
}
|
|
__EXCEPT( assert_fault )
|
|
{
|
|
WINE_WARN( "dbus assertion failure, disabling HAL support\n" );
|
|
return 1;
|
|
}
|
|
__ENDTRY;
|
|
|
|
p_libhal_ctx_shutdown( ctx, &error );
|
|
p_dbus_error_free( &error ); /* just in case */
|
|
p_dbus_connection_close( dbc );
|
|
p_libhal_ctx_free( ctx );
|
|
return 0;
|
|
}
|
|
|
|
void initialize_hal(void)
|
|
{
|
|
HANDLE handle;
|
|
|
|
if (!load_functions()) return;
|
|
if (!(handle = CreateThread( NULL, 0, hal_thread, NULL, 0, NULL ))) return;
|
|
CloseHandle( handle );
|
|
}
|
|
|
|
#else /* SONAME_LIBHAL */
|
|
|
|
void initialize_hal(void)
|
|
{
|
|
WINE_TRACE( "Skipping, HAL support not compiled in\n" );
|
|
}
|
|
|
|
#endif /* SONAME_LIBHAL */
|