diff --git a/pipewire/client/interfaces.h b/pipewire/client/interfaces.h index 0462fcec0..07a4302cf 100644 --- a/pipewire/client/interfaces.h +++ b/pipewire/client/interfaces.h @@ -528,11 +528,18 @@ struct pw_client_node_events { * The transport area is used to exchange real-time commands between * the client and the server. * + * \param readfd fd for signal data can be read + * \param writefd fd for signal data can be written * \param memfd the memory fd of the area * \param offset the offset to map * \param size the size to map */ - void (*transport) (void *object, int readfd, int writefd, int memfd, uint32_t offset, uint32_t size); + void (*transport) (void *object, + int readfd, + int writefd, + int memfd, + uint32_t offset, + uint32_t size); }; #define pw_client_node_notify_set_props(r,...) ((struct pw_client_node_events*)r->iface->events)->props(r,__VA_ARGS__) diff --git a/pipewire/modules/module-flatpak.c b/pipewire/modules/module-flatpak.c index d9f8da823..52cc85bce 100644 --- a/pipewire/modules/module-flatpak.c +++ b/pipewire/modules/module-flatpak.c @@ -29,7 +29,9 @@ #include +#include "pipewire/client/interfaces.h" #include "pipewire/client/utils.h" + #include "pipewire/server/core.h" #include "pipewire/server/module.h" @@ -43,7 +45,6 @@ struct impl { struct pw_listener global_removed; struct spa_list client_list; - struct pw_access access; struct spa_source *dispatch_event; }; @@ -53,15 +54,23 @@ struct client_info { struct spa_list link; struct pw_client *client; bool is_sandboxed; + const struct pw_core_methods *old_methods; + struct pw_core_methods core_methods; struct spa_list async_pending; + struct pw_listener resource_added; + struct pw_listener resource_removed; }; struct async_pending { struct spa_list link; - bool handled; struct client_info *info; + bool handled; char *handle; - struct pw_access_data *access_data; + struct pw_resource *resource; + char *factory_name; + char *name; + struct pw_properties *properties; + uint32_t new_id; }; static struct client_info *find_client_info(struct impl *impl, struct pw_client *client) @@ -106,44 +115,28 @@ static struct async_pending *find_pending(struct client_info *cinfo, const char return NULL; } -static void free_pending(struct pw_access_data *d) +static void free_pending(struct async_pending *p) { - struct async_pending *p = d->user_data; - if (!p->handled) close_request(p); pw_log_debug("pending %p: handle %s", p, p->handle); spa_list_remove(&p->link); free(p->handle); -} - -static void -add_pending(struct client_info *cinfo, const char *handle, struct pw_access_data *access_data) -{ - struct async_pending *p; - struct pw_access_data *ad; - - ad = access_data->async_start(access_data, sizeof(struct async_pending)); - ad->free = free_pending; - - p = ad->user_data; - p->info = cinfo; - p->handle = strdup(handle); - p->access_data = ad; - p->handled = false; - pw_log_debug("pending %p: handle %s", p, handle); - - spa_list_insert(cinfo->async_pending.prev, &p->link); + free(p->factory_name); + free(p->name); + if (p->properties) + pw_properties_free(p->properties); + free(p); } static void client_info_free(struct client_info *cinfo) { struct async_pending *p, *tmp; - spa_list_for_each_safe(p, tmp, &cinfo->async_pending, link) { - p->access_data->complete(p->access_data, SPA_RESULT_NO_PERMISSION); - } + spa_list_for_each_safe(p, tmp, &cinfo->async_pending, link) + free_pending(p); + spa_list_remove(&cinfo->link); free(cinfo); } @@ -221,8 +214,8 @@ check_global_owner(struct pw_core *core, struct pw_client *client, struct pw_glo return false; } -static int -do_view_global(struct pw_access *access, struct pw_client *client, struct pw_global *global) +static bool +do_global_filter(struct pw_global *global, struct pw_client *client, void *data) { if (global->type == client->core->type.link) { struct pw_link *link = global->object; @@ -230,15 +223,15 @@ do_view_global(struct pw_access *access, struct pw_client *client, struct pw_glo /* we must be able to see both nodes */ if (link->output && !check_global_owner(client->core, client, link->output->node->global)) - return SPA_RESULT_ERROR; + return false; if (link->input && !check_global_owner(client->core, client, link->input->node->global)) - return SPA_RESULT_ERROR; + return false; } else if (!check_global_owner(client->core, client, global)) - return SPA_RESULT_ERROR; + return false; - return SPA_RESULT_OK; + return true; } static DBusHandlerResult @@ -250,7 +243,6 @@ portal_response(DBusConnection *connection, DBusMessage *msg, void *user_data) uint32_t response = 2; DBusError error; struct async_pending *p; - struct pw_access_data *d; dbus_error_init(&error); @@ -267,26 +259,39 @@ portal_response(DBusConnection *connection, DBusMessage *msg, void *user_data) return DBUS_HANDLER_RESULT_HANDLED; p->handled = true; - d = p->access_data; pw_log_debug("portal check result: %d", response); - d->complete(d, response == 0 ? SPA_RESULT_OK : SPA_RESULT_NO_PERMISSION); + if (response == 0) { + cinfo->old_methods->create_node (p->resource, + p->factory_name, + p->name, + &p->properties->dict, + p->new_id); + } else { + pw_core_notify_error(cinfo->client->core_resource, + p->resource->id, SPA_RESULT_NO_PERMISSION, "not allowed"); + + } + free_pending(p); + pw_client_set_busy(cinfo->client, false); return DBUS_HANDLER_RESULT_HANDLED; } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -static int -do_create_node(struct pw_access *access, - struct pw_access_data *data, - const char *factory_name, - const char *name, - struct pw_properties *properties) + +static void do_create_node(void *object, + const char *factory_name, + const char *name, + const struct spa_dict *props, + uint32_t new_id) { - struct impl *impl = SPA_CONTAINER_OF(access, struct impl, access); - struct client_info *cinfo = find_client_info(impl, data->resource->client); + struct pw_resource *resource = object; + struct client_info *cinfo = resource->access_private; + struct impl *impl = cinfo->impl; + struct pw_client *client = resource->client; DBusMessage *m = NULL, *r = NULL; DBusError error; pid_t pid; @@ -294,14 +299,15 @@ do_create_node(struct pw_access *access, DBusMessageIter dict_iter; const char *handle; const char *device; + struct async_pending *p; if (!cinfo->is_sandboxed) { - data->complete(data, SPA_RESULT_OK); - return SPA_RESULT_OK; + cinfo->old_methods->create_node (object, factory_name, name, props, new_id); + return; } if (strcmp(factory_name, "client-node") != 0) { - data->complete(data, SPA_RESULT_NO_PERMISSION); - return SPA_RESULT_NO_PERMISSION; + pw_log_error("can only allow client-node"); + goto not_allowed; } pw_log_info("ask portal for client %p", cinfo->client); @@ -345,61 +351,93 @@ do_create_node(struct pw_access *access, dbus_connection_add_filter(impl->bus, portal_response, cinfo, NULL); - add_pending(cinfo, handle, data); + p = calloc(1, sizeof(struct async_pending)); + p->info = cinfo; + p->handle = strdup(handle); + p->handled = false; + p->resource = resource; + p->factory_name = strdup(factory_name); + p->name = strdup(name); + p->properties = props ? pw_properties_new_dict(props) : NULL; + p->new_id = new_id; + pw_client_set_busy(client, true); - return SPA_RESULT_RETURN_ASYNC(0); + pw_log_debug("pending %p: handle %s", p, handle); + spa_list_insert(cinfo->async_pending.prev, &p->link); + + return; no_method_call: pw_log_error("Failed to create message"); - return SPA_RESULT_NO_PERMISSION; + goto not_allowed; message_failed: dbus_message_unref(m); - return SPA_RESULT_NO_PERMISSION; + goto not_allowed; send_failed: pw_log_error("Failed to call portal: %s", error.message); dbus_error_free(&error); dbus_message_unref(m); - return SPA_RESULT_NO_PERMISSION; + goto not_allowed; parse_failed: pw_log_error("Failed to parse AccessDevice result: %s", error.message); dbus_error_free(&error); dbus_message_unref(r); - return SPA_RESULT_NO_PERMISSION; + goto not_allowed; subscribe_failed: pw_log_error("Failed to subscribe to Request signal: %s", error.message); dbus_error_free(&error); - return SPA_RESULT_NO_PERMISSION; + goto not_allowed; + not_allowed: + pw_core_notify_error(client->core_resource, + resource->id, SPA_RESULT_NO_PERMISSION, "not allowed"); + return; } -static int -do_create_link(struct pw_access *access, - struct pw_access_data *data, +static void +do_create_link(void *object, uint32_t output_node_id, uint32_t output_port_id, uint32_t input_node_id, uint32_t input_port_id, const struct spa_format *filter, - const struct pw_properties *props) + const struct spa_dict *props, + uint32_t new_id) { - struct impl *impl = SPA_CONTAINER_OF(access, struct impl, access); - struct client_info *cinfo = find_client_info(impl, data->resource->client); - int res; + struct pw_resource *resource = object; + struct client_info *cinfo = resource->access_private; + struct pw_client *client = resource->client; - if (cinfo->is_sandboxed) - res = SPA_RESULT_NO_PERMISSION; - else - res = SPA_RESULT_OK; - - data->complete(data, res); - return SPA_RESULT_OK; + if (cinfo->is_sandboxed) { + pw_core_notify_error(client->core_resource, + resource->id, SPA_RESULT_NO_PERMISSION, "not allowed"); + return; + } + cinfo->old_methods->create_link (object, + output_node_id, + output_port_id, + input_node_id, + input_port_id, + filter, + props, + new_id); } +static void on_resource_added(struct pw_listener *listener, + struct pw_client *client, + struct pw_resource *resource) +{ + struct client_info *cinfo = SPA_CONTAINER_OF(listener, struct client_info, resource_added); + struct impl *impl = cinfo->impl; -static struct pw_access access_checks = { - do_view_global, - do_create_node, - do_create_link, -}; + if (resource->type == impl->core->type.core) { + cinfo->old_methods = resource->implementation; + cinfo->core_methods = *cinfo->old_methods; + resource->implementation = &cinfo->core_methods; + resource->access_private = cinfo; + cinfo->core_methods.create_node = do_create_node; + cinfo->core_methods.create_link = do_create_link; + } +} static void on_global_added(struct pw_listener *listener, struct pw_core *core, struct pw_global *global) @@ -417,6 +455,8 @@ on_global_added(struct pw_listener *listener, struct pw_core *core, struct pw_gl cinfo->is_sandboxed = true; spa_list_init(&cinfo->async_pending); + pw_signal_add(&client->resource_added, &cinfo->resource_added, on_resource_added); + spa_list_insert(impl->client_list.prev, &cinfo->link); pw_log_debug("module %p: client %p added", impl, client); @@ -624,7 +664,6 @@ static struct impl *module_new(struct pw_core *core, struct pw_properties *prope impl->core = core; impl->properties = properties; - impl->access = access_checks; impl->bus = dbus_bus_get_private(DBUS_BUS_SESSION, &error); if (impl->bus == NULL) @@ -640,12 +679,12 @@ static struct impl *module_new(struct pw_core *core, struct pw_properties *prope toggle_timeout, impl, NULL); dbus_connection_set_wakeup_main_function(impl->bus, wakeup_main, impl, NULL); - core->access = &impl->access; - spa_list_init(&impl->client_list); pw_signal_add(&core->global_added, &impl->global_added, on_global_added); pw_signal_add(&core->global_removed, &impl->global_removed, on_global_removed); + core->global_filter = do_global_filter; + core->global_filter_data = impl; return impl; diff --git a/pipewire/server/access.c b/pipewire/server/access.c deleted file mode 100644 index e60de5257..000000000 --- a/pipewire/server/access.c +++ /dev/null @@ -1,20 +0,0 @@ -/* PipeWire - * Copyright (C) 2015 Wim Taymans - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library 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 "pipewire/server/core.h" diff --git a/pipewire/server/access.h b/pipewire/server/access.h deleted file mode 100644 index 9abbaecd2..000000000 --- a/pipewire/server/access.h +++ /dev/null @@ -1,70 +0,0 @@ -/* PipeWire - * Copyright (C) 2015 Wim Taymans - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library 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. - */ - -#ifndef __PIPEWIRE_ACCESS_H__ -#define __PIPEWIRE_ACCESS_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#define PIPEWIRE_TYPE__Access "PipeWire:Object:Access" -#define PIPEWIRE_TYPE_ACCESS_BASE PIPEWIRE_TYPE__Access ":" - -#include -#include -#include - -struct pw_access_data { - struct pw_resource *resource; - - void *(*async_start) (struct pw_access_data *data, size_t size); - void (*complete) (struct pw_access_data *data, int res); - void (*free) (struct pw_access_data *data); - void *user_data; -}; - - -/** - * \struct pw_access - * - * PipeWire Access support struct. - */ -struct pw_access { - int (*view_global) (struct pw_access *access, - struct pw_client *client, struct pw_global *global); - int (*create_node) (struct pw_access *access, - struct pw_access_data *data, - const char *factory_name, - const char *name, struct pw_properties *properties); - int (*create_link) (struct pw_access *access, - struct pw_access_data *data, - uint32_t output_node_id, - uint32_t output_port_id, - uint32_t input_node_id, - uint32_t input_port_id, - const struct spa_format *filter, - const struct pw_properties *props); -}; - -#ifdef __cplusplus -} -#endif - -#endif /* __PIPEWIRE_ACCESS_H__ */ diff --git a/pipewire/server/client-node.c b/pipewire/server/client-node.c index 3406a519f..0d63e6e2e 100644 --- a/pipewire/server/client-node.c +++ b/pipewire/server/client-node.c @@ -1173,7 +1173,9 @@ struct pw_client_node *pw_client_node_new(struct pw_client *client, this->resource = pw_resource_new(client, id, client->core->type.client_node, - this, (pw_destroy_t) client_node_resource_destroy); + this, + &client_node_methods, + (pw_destroy_t) client_node_resource_destroy); if (this->resource == NULL) goto error_no_resource; @@ -1184,8 +1186,6 @@ struct pw_client_node *pw_client_node_new(struct pw_client *client, pw_signal_add(&this->node->loop_changed, &impl->loop_changed, on_loop_changed); pw_signal_add(&impl->core->global_added, &impl->global_added, on_global_added); - this->resource->implementation = &client_node_methods; - return this; error_no_resource: diff --git a/pipewire/server/client.c b/pipewire/server/client.c index 2b2f81aeb..748b92b71 100644 --- a/pipewire/server/client.c +++ b/pipewire/server/client.c @@ -43,7 +43,7 @@ client_bind_func(struct pw_global *global, struct pw_client *client, uint32_t ve struct pw_client *this = global->object; struct pw_resource *resource; - resource = pw_resource_new(client, id, global->type, global->object, client_unbind_func); + resource = pw_resource_new(client, id, global->type, global->object, NULL, client_unbind_func); if (resource == NULL) goto no_mem; diff --git a/pipewire/server/core.c b/pipewire/server/core.c index d2b9571e2..6196199db 100644 --- a/pipewire/server/core.c +++ b/pipewire/server/core.c @@ -38,19 +38,16 @@ struct impl { struct spa_support support[4]; }; -struct access_create_node { - struct pw_access_data data; - char *factory_name; - char *name; - struct pw_properties *properties; - uint32_t new_id; - bool async; -}; /** \endcond */ -#define ACCESS_VIEW_GLOBAL(client,global) (client->core->access == NULL || \ - client->core->access->view_global (client->core->access, \ - client, global) == SPA_RESULT_OK) +static bool pw_global_is_visible(struct pw_global *global, + struct pw_client *client) +{ + struct pw_core *core = client->core; + + return (core->global_filter == NULL || + core->global_filter(global, client, core->global_filter_data)); +} static void registry_bind(void *object, uint32_t id, uint32_t version, uint32_t new_id) { @@ -66,7 +63,7 @@ static void registry_bind(void *object, uint32_t id, uint32_t version, uint32_t if (&global->link == &core->global_list) goto no_id; - if (!ACCESS_VIEW_GLOBAL(client, global)) + if (!pw_global_is_visible(global, client)) goto no_id; pw_log_debug("global %p: bind object id %d to %d", global, id, new_id); @@ -118,16 +115,17 @@ static void core_get_registry(void *object, uint32_t new_id) registry_resource = pw_resource_new(client, new_id, - this->type.registry, this, destroy_registry_resource); + this->type.registry, + this, + ®istry_methods, + destroy_registry_resource); if (registry_resource == NULL) goto no_mem; - registry_resource->implementation = ®istry_methods; - spa_list_insert(this->registry_resource_list.prev, ®istry_resource->link); spa_list_for_each(global, &this->global_list, link) { - if (ACCESS_VIEW_GLOBAL(client, global)) + if (pw_global_is_visible(global, client)) pw_registry_notify_global(registry_resource, global->id, spa_type_map_get_type(this->type.map, @@ -143,73 +141,6 @@ static void core_get_registry(void *object, uint32_t new_id) resource->id, SPA_RESULT_NO_MEMORY, "no memory"); } -static void *async_create_node_start(struct pw_access_data *data, size_t size) -{ - struct access_create_node *d; - struct pw_client *client = data->resource->client; - - d = calloc(1, sizeof(struct access_create_node) + size); - memcpy(d, data, sizeof(struct access_create_node)); - d->factory_name = strdup(d->factory_name); - d->name = strdup(d->name); - d->async = true; - d->data.user_data = SPA_MEMBER(d, sizeof(struct access_create_node), void); - - pw_client_set_busy(client, true); - - return d; -} - -static void async_create_node_free(struct pw_access_data *data) -{ - struct access_create_node *d = (struct access_create_node *) data; - - if (d->properties) - pw_properties_free(d->properties); - if (d->async) { - if (d->data.free) - d->data.free(&d->data); - free(d->factory_name); - free(d->name); - free(d); - } -} - -static void async_create_node_complete(struct pw_access_data *data, int res) -{ - struct access_create_node *d = (struct access_create_node *) data; - struct pw_resource *resource = d->data.resource; - struct pw_client *client = resource->client; - struct pw_node_factory *factory; - - if (res != SPA_RESULT_OK) - goto denied; - - factory = pw_core_find_node_factory(client->core, d->factory_name); - if (factory == NULL) - goto no_factory; - - /* error will be posted */ - pw_node_factory_create_node(factory, client, d->name, d->properties, d->new_id); - d->properties = NULL; - - goto done; - - no_factory: - pw_log_error("can't find node factory"); - pw_core_notify_error(client->core_resource, - resource->id, SPA_RESULT_INVALID_ARGUMENTS, "unknown factory name"); - goto done; - denied: - pw_log_error("create node refused %d", res); - pw_core_notify_error(client->core_resource, - resource->id, SPA_RESULT_NO_PERMISSION, "operation not allowed"); - done: - async_create_node_free(&d->data); - pw_client_set_busy(client, false); - return; -} - static void core_create_node(void *object, const char *factory_name, @@ -219,47 +150,39 @@ core_create_node(void *object, { struct pw_resource *resource = object; struct pw_client *client = resource->client; - int i; + struct pw_node_factory *factory; struct pw_properties *properties; - struct access_create_node access_data; - int res; + int i; + + factory = pw_core_find_node_factory(client->core, factory_name); + if (factory == NULL) + goto no_factory; properties = pw_properties_new(NULL, NULL); if (properties == NULL) goto no_mem; - for (i = 0; i < props->n_items; i++) { + for (i = 0; i < props->n_items; i++) pw_properties_set(properties, props->items[i].key, props->items[i].value); - } - access_data.data.resource = resource; - access_data.data.async_start = async_create_node_start; - access_data.data.complete = async_create_node_complete; - access_data.data.free = NULL; - access_data.factory_name = (char *) factory_name; - access_data.name = (char *) name; - access_data.properties = properties; - access_data.new_id = new_id; - access_data.async = false; + /* error will be posted */ + pw_node_factory_create_node(factory, client, name, properties, new_id); + properties = NULL; - if (client->core->access) { - res = client->core->access->create_node(client->core->access, - &access_data.data, - factory_name, - name, - properties); - } else { - res = SPA_RESULT_OK; - } - if (!SPA_RESULT_IS_ASYNC(res)) - async_create_node_complete(&access_data.data, res); + done: return; + no_factory: + pw_log_error("can't find node factory"); + pw_core_notify_error(client->core_resource, + resource->id, SPA_RESULT_INVALID_ARGUMENTS, "unknown factory name"); + goto done; + no_mem: - pw_log_error("can't create client node"); + pw_log_error("can't create properties"); pw_core_notify_error(client->core_resource, resource->id, SPA_RESULT_NO_MEMORY, "no memory"); - return; + goto done; } static void @@ -294,7 +217,7 @@ static void core_update_types(void *object, uint32_t first_id, uint32_t n_types, } } -static struct pw_core_methods core_methods = { +static const struct pw_core_methods core_methods = { &core_update_types, &core_sync, &core_get_registry, @@ -316,12 +239,10 @@ core_bind_func(struct pw_global *global, struct pw_client *client, uint32_t vers struct pw_core *this = global->object; struct pw_resource *resource; - resource = pw_resource_new(client, id, global->type, global->object, core_unbind_func); + resource = pw_resource_new(client, id, global->type, global->object, &core_methods, core_unbind_func); if (resource == NULL) goto no_mem; - resource->implementation = &core_methods; - spa_list_insert(this->resource_list.prev, &resource->link); client->core_resource = resource; @@ -483,8 +404,8 @@ pw_core_add_global(struct pw_core *core, pw_log_debug("global %p: new %u %s, owner %p", this, this->id, type_name, owner); spa_list_for_each(registry, &core->registry_resource_list, link) - if (ACCESS_VIEW_GLOBAL(registry->client, this)) - pw_registry_notify_global(registry, this->id, type_name, this->version); + if (pw_global_is_visible(this, registry->client)) + pw_registry_notify_global(registry, this->id, type_name, this->version); return true; } @@ -533,8 +454,8 @@ void pw_global_destroy(struct pw_global *global) pw_signal_emit(&global->destroy_signal, global); spa_list_for_each(registry, &core->registry_resource_list, link) - if (ACCESS_VIEW_GLOBAL(registry->client, global)) - pw_registry_notify_global_remove(registry, global->id); + if (pw_global_is_visible(global, registry->client)) + pw_registry_notify_global_remove(registry, global->id); pw_map_remove(&core->objects, global->id); diff --git a/pipewire/server/core.h b/pipewire/server/core.h index 6a5ca2ecd..683e91dff 100644 --- a/pipewire/server/core.h +++ b/pipewire/server/core.h @@ -29,7 +29,8 @@ extern "C" { struct pw_global; #include -#include +#include + #include #include #include @@ -87,6 +88,9 @@ struct pw_global; typedef int (*pw_bind_func_t) (struct pw_global *global, struct pw_client *client, uint32_t version, uint32_t id); +typedef bool (*pw_global_filter_func_t) (struct pw_global *global, + struct pw_client *client, void *data); + /** \page page_global Global * * Global objects represent resources that are available on the server and @@ -141,7 +145,9 @@ struct pw_core { struct pw_properties *properties; /**< properties of the core */ struct pw_type type; /**< type map and common types */ - struct pw_access *access; /**< access control checks */ + + pw_global_filter_func_t global_filter; + void *global_filter_data; struct pw_map objects; /**< map of known objects */ diff --git a/pipewire/server/link.c b/pipewire/server/link.c index c3f8bddd3..91598250e 100644 --- a/pipewire/server/link.c +++ b/pipewire/server/link.c @@ -834,7 +834,7 @@ link_bind_func(struct pw_global *global, struct pw_client *client, uint32_t vers struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this); struct pw_resource *resource; - resource = pw_resource_new(client, id, global->type, global->object, link_unbind_func); + resource = pw_resource_new(client, id, global->type, global->object, NULL, link_unbind_func); if (resource == NULL) goto no_mem; diff --git a/pipewire/server/meson.build b/pipewire/server/meson.build index 6ec68938b..fd2d2bf02 100644 --- a/pipewire/server/meson.build +++ b/pipewire/server/meson.build @@ -1,5 +1,4 @@ pipewirecore_headers = [ - 'access.h', 'client.h', 'client-node.h', 'command.h', @@ -17,7 +16,6 @@ pipewirecore_headers = [ ] pipewirecore_sources = [ - 'access.c', 'client.c', 'client-node.c', 'command.c', diff --git a/pipewire/server/module.c b/pipewire/server/module.c index c8d5a9e0a..d945d3ae5 100644 --- a/pipewire/server/module.c +++ b/pipewire/server/module.c @@ -92,7 +92,7 @@ module_bind_func(struct pw_global *global, struct pw_client *client, uint32_t ve struct pw_module *this = global->object; struct pw_resource *resource; - resource = pw_resource_new(client, id, global->type, global->object, NULL); + resource = pw_resource_new(client, id, global->type, global->object, NULL, NULL); if (resource == NULL) goto no_mem; diff --git a/pipewire/server/node.c b/pipewire/server/node.c index faa1c2ecd..1229c3b13 100644 --- a/pipewire/server/node.c +++ b/pipewire/server/node.c @@ -465,7 +465,7 @@ node_bind_func(struct pw_global *global, struct pw_client *client, uint32_t vers struct pw_node *this = global->object; struct pw_resource *resource; - resource = pw_resource_new(client, id, global->type, global->object, node_unbind_func); + resource = pw_resource_new(client, id, global->type, global->object, NULL, node_unbind_func); if (resource == NULL) goto no_mem; diff --git a/pipewire/server/resource.c b/pipewire/server/resource.c index 7adc15d1f..7d88432df 100644 --- a/pipewire/server/resource.c +++ b/pipewire/server/resource.c @@ -29,7 +29,11 @@ struct impl { /** \endcond */ struct pw_resource *pw_resource_new(struct pw_client *client, - uint32_t id, uint32_t type, void *object, pw_destroy_t destroy) + uint32_t id, + uint32_t type, + void *object, + const void *implementation, + pw_destroy_t destroy) { struct impl *impl; struct pw_resource *this; @@ -43,6 +47,7 @@ struct pw_resource *pw_resource_new(struct pw_client *client, this->client = client; this->type = type; this->object = object; + this->implementation = implementation; this->destroy = destroy; pw_signal_init(&this->destroy_signal); diff --git a/pipewire/server/resource.h b/pipewire/server/resource.h index 8867a729a..0cd5aa7ff 100644 --- a/pipewire/server/resource.h +++ b/pipewire/server/resource.h @@ -70,13 +70,19 @@ struct pw_resource { const struct pw_interface *iface; /**< protocol specific interface functions */ const void *implementation; /**< implementation */ + void *access_private; /**< private data for access control */ + /** Emited when the resource is destroyed */ PW_SIGNAL(destroy_signal, (struct pw_listener *listener, struct pw_resource *resource)); }; struct pw_resource * pw_resource_new(struct pw_client *client, - uint32_t id, uint32_t type, void *object, pw_destroy_t destroy); + uint32_t id, + uint32_t type, + void *object, + const void *implementation, + pw_destroy_t destroy); void pw_resource_destroy(struct pw_resource *resource);