예제 #1
0
파일: dbus.c 프로젝트: AmesianX/RosWine
static BOOL hal_enumerate_devices(void)
{
    LibHalContext *ctx;
    DBusError error;
    int i, num;
    char **list;

    if (!p_libhal_ctx_new) return FALSE;
    if (!(ctx = p_libhal_ctx_new())) return FALSE;

    p_libhal_ctx_set_dbus_connection( ctx, connection );
    p_libhal_ctx_set_device_added( ctx, hal_new_device );
    p_libhal_ctx_set_device_removed( ctx, hal_removed_device );
    p_libhal_ctx_set_device_property_modified( ctx, hal_property_modified );

    p_dbus_error_init( &error );
    if (!p_libhal_ctx_init( ctx, &error ))
    {
        WARN( "HAL context init failed: %s\n", error.message );
        p_dbus_error_free( &error );
        return FALSE;
    }

    /* 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++) hal_new_device( ctx, list[i] );
        p_libhal_free_string_array( list );
    }
    return TRUE;
}
예제 #2
0
파일: dbus.c 프로젝트: AmesianX/RosWine
static BOOL udisks_enumerate_devices(void)
{
    DBusMessage *request, *reply;
    DBusError error;
    char **paths;
    int i, count;

    request = p_dbus_message_new_method_call( "org.freedesktop.UDisks", "/org/freedesktop/UDisks",
                                              "org.freedesktop.UDisks", "EnumerateDevices" );
    if (!request) return FALSE;

    p_dbus_error_init( &error );
    reply = p_dbus_connection_send_with_reply_and_block( connection, request, udisks_timeout, &error );
    p_dbus_message_unref( request );
    if (!reply)
    {
        WARN( "failed: %s\n", error.message );
        p_dbus_error_free( &error );
        return FALSE;
    }
    p_dbus_error_free( &error );

    if (p_dbus_message_get_args( reply, &error, DBUS_TYPE_ARRAY,
                                 DBUS_TYPE_OBJECT_PATH, &paths, &count, DBUS_TYPE_INVALID ))
    {
        for (i = 0; i < count; i++) udisks_new_device( paths[i] );
        p_dbus_free_string_array( paths );
    }
    else WARN( "unexpected args in EnumerateDevices reply\n" );

    p_dbus_message_unref( reply );
    return TRUE;
}
예제 #3
0
파일: dbus.c 프로젝트: AmesianX/RosWine
static DBusHandlerResult udisks_filter( DBusConnection *ctx, DBusMessage *msg, void *user_data )
{
    char *path;
    DBusError error;

    p_dbus_error_init( &error );

    if (p_dbus_message_is_signal( msg, "org.freedesktop.UDisks", "DeviceAdded" ) &&
        p_dbus_message_get_args( msg, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID ))
    {
        udisks_new_device( path );
    }
    else if (p_dbus_message_is_signal( msg, "org.freedesktop.UDisks", "DeviceRemoved" ) &&
             p_dbus_message_get_args( msg, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID ))
    {
        udisks_removed_device( path );
    }
    else if (p_dbus_message_is_signal( msg, "org.freedesktop.UDisks", "DeviceChanged" ) &&
             p_dbus_message_get_args( msg, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID ))
    {
        udisks_changed_device( path );
    }
    else TRACE( "ignoring message type=%d path=%s interface=%s method=%s\n",
                p_dbus_message_get_type( msg ), p_dbus_message_get_path( msg ),
                p_dbus_message_get_interface( msg ), p_dbus_message_get_member( msg ) );

    p_dbus_error_free( &error );
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
예제 #4
0
파일: hal.c 프로젝트: howard5888/wineT
/* HAL callback for new device */
static void new_device( LibHalContext *ctx, const char *udi )
{
    DBusError error;
    char *parent, *mount_point, *device, *type;

    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 );

    if (type) p_libhal_free_string( type );
    p_libhal_free_string( parent );
    p_libhal_free_string( device );
    p_libhal_free_string( mount_point );

    /* add property watch for mount point */
    p_libhal_device_add_property_watch( ctx, udi, &error );

done:
    p_dbus_error_free( &error );
}
예제 #5
0
파일: hal.c 프로젝트: howard5888/wineT
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;
}
예제 #6
0
파일: dbus.c 프로젝트: AmesianX/RosWine
/* HAL callback for removed device */
static void hal_removed_device( LibHalContext *ctx, const char *udi )
{
    DBusError error;

    TRACE( "removed %s\n", wine_dbgstr_a(udi) );

    if (!remove_dos_device( -1, udi ))
    {
        p_dbus_error_init( &error );
        p_libhal_device_remove_property_watch( ctx, udi, &error );
        p_dbus_error_free( &error );
    }
    else remove_volume( udi );
}
예제 #7
0
파일: dbus.c 프로젝트: AmesianX/RosWine
/* HAL callback for new device */
static void hal_new_device( LibHalContext *ctx, const char *udi )
{
    DBusError error;
    char *parent = NULL;
    char *mount_point = NULL;
    char *device = NULL;
    char *type = NULL;
    char *uuid_str = NULL;
    GUID guid, *guid_ptr = NULL;
    enum device_type drive_type;

    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 (!(uuid_str = p_libhal_device_get_property_string( ctx, udi, "volume.uuid", &error )))
        p_dbus_error_free( &error );  /* ignore error */
    else
        guid_ptr = parse_uuid( &guid, uuid_str );

    if (!(type = p_libhal_device_get_property_string( ctx, parent, "storage.drive_type", &error )))
        p_dbus_error_free( &error );  /* ignore error */

    if (type && !strcmp( type, "cdrom" )) drive_type = DEVICE_CDROM;
    else if (type && !strcmp( type, "floppy" )) drive_type = DEVICE_FLOPPY;
    else drive_type = DEVICE_UNKNOWN;

    if (p_libhal_device_get_property_bool( ctx, parent, "storage.removable", &error ))
    {
        add_dos_device( -1, udi, device, mount_point, drive_type, guid_ptr );
        /* add property watch for mount point */
        p_libhal_device_add_property_watch( ctx, udi, &error );
    }
    else if (guid_ptr) add_volume( udi, device, mount_point, DEVICE_HARDDISK_VOL, guid_ptr );

done:
    if (type) p_libhal_free_string( type );
    if (parent) p_libhal_free_string( parent );
    if (device) p_libhal_free_string( device );
    if (uuid_str) p_libhal_free_string( uuid_str );
    if (mount_point) p_libhal_free_string( mount_point );
    p_dbus_error_free( &error );
}
예제 #8
0
파일: dbus.c 프로젝트: AmesianX/RosWine
static DWORD WINAPI dbus_thread( void *arg )
{
    static const char udisks_match[] = "type='signal',"
                                       "interface='org.freedesktop.UDisks',"
                                       "sender='org.freedesktop.UDisks'";

    DBusError error;

    p_dbus_error_init( &error );
    if (!(connection = p_dbus_bus_get( DBUS_BUS_SYSTEM, &error )))
    {
        WARN( "failed to get system dbus connection: %s\n", error.message );
        p_dbus_error_free( &error );
        return 1;
    }

    if (p_dbus_connection_add_filter( connection, udisks_filter, NULL, NULL ))
	p_dbus_bus_add_match( connection, udisks_match, &error );

    if (!udisks_enumerate_devices())
    {
        p_dbus_bus_remove_match( connection, udisks_match, &error );
        p_dbus_connection_remove_filter( connection, udisks_filter, NULL );

#ifdef SONAME_LIBHAL
        if (!hal_enumerate_devices())
        {
            p_dbus_connection_close( connection );
            p_dbus_error_free( &error );
            return 1;
        }
#endif
    }

    __TRY
    {
        while (p_dbus_connection_read_write_dispatch( connection, -1 )) /* nothing */ ;
    }
    __EXCEPT( assert_fault )
    {
        WARN( "dbus assertion failure, disabling support\n" );
        return 1;
    }
    __ENDTRY;

    p_dbus_connection_close( connection );
    return 0;
}
예제 #9
0
static DBusHandlerResult udisks_filter( DBusConnection *ctx, DBusMessage *msg, void *user_data )
{
    char *path;
    DBusError error;

    p_dbus_error_init( &error );

    /* udisks signals */
    if (p_dbus_message_is_signal( msg, "org.freedesktop.UDisks", "DeviceAdded" ) &&
        p_dbus_message_get_args( msg, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID ))
    {
        udisks_new_device( path );
    }
    else if (p_dbus_message_is_signal( msg, "org.freedesktop.UDisks", "DeviceRemoved" ) &&
             p_dbus_message_get_args( msg, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID ))
    {
        udisks_removed_device( path );
    }
    else if (p_dbus_message_is_signal( msg, "org.freedesktop.UDisks", "DeviceChanged" ) &&
             p_dbus_message_get_args( msg, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID ))
    {
        udisks_changed_device( path );
    }
    /* udisks2 signals */
    else if (p_dbus_message_is_signal( msg, "org.freedesktop.DBus.ObjectManager", "InterfacesAdded" ) &&
             p_dbus_message_get_args( msg, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID ))
    {
        TRACE( "added %s\n", wine_dbgstr_a(path) );
        udisks2_add_devices( path );
    }
    else if (p_dbus_message_is_signal( msg, "org.freedesktop.DBus.ObjectManager", "InterfacesRemoved" ) &&
             p_dbus_message_get_args( msg, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID ))
    {
        udisks_removed_device( path );
    }
    else if (p_dbus_message_is_signal( msg, "org.freedesktop.DBus.Properties", "PropertiesChanged" ))
    {
        const char *udi = p_dbus_message_get_path( msg );
        TRACE( "changed %s\n", wine_dbgstr_a(udi) );
        udisks2_add_devices( udi );
    }
    else TRACE( "ignoring message type=%d path=%s interface=%s method=%s\n",
                p_dbus_message_get_type( msg ), p_dbus_message_get_path( msg ),
                p_dbus_message_get_interface( msg ), p_dbus_message_get_member( msg ) );

    p_dbus_error_free( &error );
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
예제 #10
0
파일: hal.c 프로젝트: howard5888/wineT
/* HAL callback for removed device */
static void removed_device( LibHalContext *ctx, const char *udi )
{
    DBusError error;
    struct dos_drive *drive;

    WINE_TRACE( "removed %s\n", wine_dbgstr_a(udi) );

    LIST_FOR_EACH_ENTRY( drive, &drives_list, struct dos_drive, entry )
    {
        if (strcmp( udi, drive->udi )) continue;
        p_dbus_error_init( &error );
        p_libhal_device_remove_property_watch( ctx, udi, &error );
        remove_dos_device( drive );
        p_dbus_error_free( &error );
        return;
    }
}
예제 #11
0
/* UDisks2 is almost, but not quite, entirely unlike UDisks.
 * It would have been easy to make it backwards compatible, but where would be the fun in that?
 */
static BOOL udisks2_add_devices( const char *changed )
{
    DBusMessage *request, *reply;
    DBusMessageIter dict, iter, block;
    DBusError error;
    const char *udi;

    request = p_dbus_message_new_method_call( "org.freedesktop.UDisks2", "/org/freedesktop/UDisks2",
                                              "org.freedesktop.DBus.ObjectManager", "GetManagedObjects" );
    if (!request) return FALSE;

    p_dbus_error_init( &error );
    reply = p_dbus_connection_send_with_reply_and_block( connection, request, udisks_timeout, &error );
    p_dbus_message_unref( request );
    if (!reply)
    {
        WARN( "failed: %s\n", error.message );
        p_dbus_error_free( &error );
        return FALSE;
    }
    p_dbus_error_free( &error );

    p_dbus_message_iter_init( reply, &dict );
    if (p_dbus_message_iter_get_arg_type( &dict ) == DBUS_TYPE_ARRAY)
    {
        p_dbus_message_iter_recurse( &dict, &iter );
        while ((udi = udisks_next_dict_entry( &iter, &block )))
        {
            if (!starts_with( udi, "/org/freedesktop/UDisks2/block_devices/" )) continue;
            if (changed && strcmp( changed, udi )) continue;
            udisks2_add_device( udi, &dict, &block );
        }
    }
    else WARN( "unexpected args in GetManagedObjects reply\n" );

    p_dbus_message_unref( reply );
    return TRUE;
}
예제 #12
0
파일: dbus.c 프로젝트: AmesianX/RosWine
/* UDisks callback for new device */
static void udisks_new_device( const char *udi )
{
    static const char *dev_name = "org.freedesktop.UDisks.Device";
    DBusMessage *request, *reply;
    DBusMessageIter iter, variant;
    DBusError error;
    const char *device = NULL;
    const char *mount_point = NULL;
    const char *type = NULL;
    GUID guid, *guid_ptr = NULL;
    int removable = FALSE;
    enum device_type drive_type = DEVICE_UNKNOWN;

    request = p_dbus_message_new_method_call( "org.freedesktop.UDisks", udi,
                                              "org.freedesktop.DBus.Properties", "GetAll" );
    if (!request) return;

    p_dbus_message_iter_init_append( request, &iter );
    p_dbus_message_iter_append_basic( &iter, DBUS_TYPE_STRING, &dev_name );

    p_dbus_error_init( &error );
    reply = p_dbus_connection_send_with_reply_and_block( connection, request, -1, &error );
    p_dbus_message_unref( request );
    if (!reply)
    {
        WARN( "failed: %s\n", error.message );
        p_dbus_error_free( &error );
        return;
    }
    p_dbus_error_free( &error );

    p_dbus_message_iter_init( reply, &iter );
    if (p_dbus_message_iter_get_arg_type( &iter ) == DBUS_TYPE_ARRAY)
    {
        const char *name;

        p_dbus_message_iter_recurse( &iter, &iter );
        while ((name = udisks_next_dict_entry( &iter, &variant )))
        {
            if (!strcmp( name, "DeviceFile" ))
                p_dbus_message_iter_get_basic( &variant, &device );
            else if (!strcmp( name, "DeviceIsRemovable" ))
                p_dbus_message_iter_get_basic( &variant, &removable );
            else if (!strcmp( name, "IdType" ))
                p_dbus_message_iter_get_basic( &variant, &type );
            else if (!strcmp( name, "DriveMediaCompatibility" ))
            {
                DBusMessageIter media;
                p_dbus_message_iter_recurse( &variant, &media );
                while (p_dbus_message_iter_get_arg_type( &media ) == DBUS_TYPE_STRING)
                {
                    const char *media_type;
                    p_dbus_message_iter_get_basic( &media, &media_type );
                    if (!strncmp( media_type, "optical_dvd", 11 ))
                        drive_type = DEVICE_DVD;
                    if (!strncmp( media_type, "floppy", 6 ))
                        drive_type = DEVICE_FLOPPY;
                    else if (!strncmp( media_type, "optical_", 8 ) && drive_type == DEVICE_UNKNOWN)
                        drive_type = DEVICE_CDROM;
                    p_dbus_message_iter_next( &media );
                }
            }
            else if (!strcmp( name, "DeviceMountPaths" ))
            {
                DBusMessageIter paths;
                p_dbus_message_iter_recurse( &variant, &paths );
                if (p_dbus_message_iter_get_arg_type( &paths ) == DBUS_TYPE_STRING)
                    p_dbus_message_iter_get_basic( &paths, &mount_point );
            }
            else if (!strcmp( name, "IdUuid" ))
            {
                char *uuid_str;
                p_dbus_message_iter_get_basic( &variant, &uuid_str );
                guid_ptr = parse_uuid( &guid, uuid_str );
            }
        }
    }

    TRACE( "udi %s device %s mount point %s uuid %s type %s removable %u\n",
           debugstr_a(udi), debugstr_a(device), debugstr_a(mount_point),
           debugstr_guid(guid_ptr), debugstr_a(type), removable );

    if (type)
    {
        if (!strcmp( type, "iso9660" ))
        {
            removable = TRUE;
            drive_type = DEVICE_CDROM;
        }
        else if (!strcmp( type, "udf" ))
        {
            removable = TRUE;
            drive_type = DEVICE_DVD;
        }
    }

    if (device)
    {
        if (removable) add_dos_device( -1, udi, device, mount_point, drive_type, guid_ptr );
        else if (guid_ptr) add_volume( udi, device, mount_point, DEVICE_HARDDISK_VOL, guid_ptr );
    }

    p_dbus_message_unref( reply );
}
예제 #13
0
static DWORD WINAPI dbus_thread( void *arg )
{
    static const char udisks_match[] = "type='signal',"
                                       "interface='org.freedesktop.UDisks',"
                                       "sender='org.freedesktop.UDisks'";
    static const char udisks2_match_interfaces[] = "type='signal',"
                                                   "interface='org.freedesktop.DBus.ObjectManager',"
                                                   "path='/org/freedesktop/UDisks2'";
    static const char udisks2_match_properties[] = "type='signal',"
                                                   "interface='org.freedesktop.DBus.Properties'";


    DBusError error;

    p_dbus_error_init( &error );
    if (!(connection = p_dbus_bus_get( DBUS_BUS_SYSTEM, &error )))
    {
        WARN( "failed to get system dbus connection: %s\n", error.message );
        p_dbus_error_free( &error );
        return 1;
    }

    /* first try UDisks2 */

    p_dbus_connection_add_filter( connection, udisks_filter, NULL, NULL );
    p_dbus_bus_add_match( connection, udisks2_match_interfaces, &error );
    p_dbus_bus_add_match( connection, udisks2_match_properties, &error );
    if (udisks2_add_devices( NULL )) goto found;
    p_dbus_bus_remove_match( connection, udisks2_match_interfaces, &error );
    p_dbus_bus_remove_match( connection, udisks2_match_properties, &error );

    /* then try UDisks */

    p_dbus_bus_add_match( connection, udisks_match, &error );
    if (udisks_enumerate_devices()) goto found;
    p_dbus_bus_remove_match( connection, udisks_match, &error );
    p_dbus_connection_remove_filter( connection, udisks_filter, NULL );

    /* then finally HAL */

#ifdef SONAME_LIBHAL
    if (!hal_enumerate_devices())
    {
        p_dbus_error_free( &error );
        return 1;
    }
#endif

found:
    __TRY
    {
        while (p_dbus_connection_read_write_dispatch( connection, -1 )) /* nothing */ ;
    }
    __EXCEPT( assert_fault )
    {
        WARN( "dbus assertion failure, disabling support\n" );
        return 1;
    }
    __ENDTRY;

    return 0;
}