#include #include #include void xpc_msg_header_init( xpc_msg_header_t *msg, unsigned long interface, unsigned short func) { memset(msg, 0x0, sizeof *msg); msg->hdr_magic = XPC_MSG_MAGIC; msg->hdr_interface = interface; msg->hdr_func = func; msg->hdr_status = 0; } bool xpc_msg_header_validate(const xpc_msg_header_t *msg) { return msg->hdr_magic == XPC_MSG_MAGIC; } kern_status_t xpc_msg_recv(kern_handle_t channel, xpc_msg_t *out) { kern_iovec_t iov = IOVEC(&out->msg_header, sizeof out->msg_header); kern_msg_t msg = { .msg_data = &iov, .msg_data_count = 1, .msg_handles = out->msg_handles, .msg_handles_count = KERN_MSG_MAX_HANDLES, }; kern_status_t status = msg_recv(channel, &msg); if (status != KERN_OK) { return status; } if (!xpc_msg_header_validate(&out->msg_header)) { return KERN_INVALID_ARGUMENT; } out->msg_sender.e_channel = channel; out->msg_sender.e_task = msg.msg_sender; out->msg_sender.e_port = msg.msg_endpoint; out->msg_sender.e_msg = msg.msg_id; return KERN_OK; } kern_status_t xpc_msg_read( const xpc_msg_t *msg, size_t offset, void *p, size_t count) { kern_iovec_t iov = IOVEC(p, count); size_t r = 0; return msg_read( msg->msg_sender.e_channel, msg->msg_sender.e_msg, offset, &iov, 1, &r); } kern_status_t xpc_msg_write( const xpc_msg_t *msg, size_t offset, const void *p, size_t count) { kern_iovec_t iov = IOVEC(p, count); size_t w = 0; return msg_write( msg->msg_sender.e_channel, msg->msg_sender.e_msg, offset, &iov, 1, &w); } kern_status_t xpc_msg_reply( const xpc_msg_t *msg, kern_iovec_t *iov, size_t iov_count, kern_msg_handle_t *handles, size_t handle_count) { kern_msg_t reply = MSG(iov, iov_count, handles, handle_count); return msg_reply( msg->msg_sender.e_channel, msg->msg_sender.e_msg, &reply); } kern_status_t xpc_msg_reply_error(const xpc_msg_t *msg, unsigned short code) { xpc_msg_header_t reply_data = { .hdr_magic = XPC_MSG_MAGIC, .hdr_interface = msg->msg_header.hdr_interface, .hdr_func = msg->msg_header.hdr_func, .hdr_status = code, }; kern_iovec_t iov = IOVEC(&reply_data, sizeof reply_data); kern_msg_t reply = MSG(&iov, 1, NULL, 0); return msg_reply( msg->msg_sender.e_channel, msg->msg_sender.e_msg, &reply); }