18746cb53Smrg/*
28746cb53Smrg * Copyright 2014 by VMware, Inc.
38746cb53Smrg *
48746cb53Smrg * Permission is hereby granted, free of charge, to any person obtaining a
58746cb53Smrg * copy of this software and associated documentation files (the "Software"),
68746cb53Smrg * to deal in the Software without restriction, including without limitation
78746cb53Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
88746cb53Smrg * and/or sell copies of the Software, and to permit persons to whom the
98746cb53Smrg * Software is furnished to do so, subject to the following conditions:
108746cb53Smrg *
118746cb53Smrg * The above copyright notice and this permission notice shall be included in
128746cb53Smrg * all copies or substantial portions of the Software.
138746cb53Smrg *
148746cb53Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
158746cb53Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
168746cb53Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
178746cb53Smrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
188746cb53Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
198746cb53Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
208746cb53Smrg * OTHER DEALINGS IN THE SOFTWARE.
218746cb53Smrg *
228746cb53Smrg * Except as contained in this notice, the name of the copyright holder(s)
238746cb53Smrg * and author(s) shall not be used in advertising or otherwise to promote
248746cb53Smrg * the sale, use or other dealings in this Software without prior written
258746cb53Smrg * authorization from the copyright holder(s) and author(s).
268746cb53Smrg */
278746cb53Smrg
288746cb53Smrg#ifdef HAVE_CONFIG_H
298746cb53Smrg#include "config.h"
308746cb53Smrg#endif
318746cb53Smrg
328746cb53Smrg#ifdef HAVE_LIBUDEV
338746cb53Smrg#include <libudev.h>
348746cb53Smrg#include <stdlib.h>
358746cb53Smrg#include <string.h>
368746cb53Smrg
378746cb53Smrg#define KERNEL_DEVNAME "VirtualPS/2 VMware VMMouse"
388746cb53Smrg
398746cb53Smrg/**
408746cb53Smrg * vmmouse_uses_kernel_driver - Check whether there's an active
418746cb53Smrg *    vmmouse driver in the kernel.
428746cb53Smrg *
438746cb53Smrg * Returns 0 if there was no kernel driver found.
448746cb53Smrg * Returns non-zero on error or if there was an active driver found.
458746cb53Smrg *
468746cb53Smrg * Scans the input subsystem for devices matching KERNEL_DEVNAME. These
478746cb53Smrg * devices are assumed to be active vmmouse drivers.
488746cb53Smrg */
498746cb53Smrgint vmmouse_uses_kernel_driver(void)
508746cb53Smrg{
518746cb53Smrg    struct udev *udev;
528746cb53Smrg    struct udev_enumerate *enumerate;
538746cb53Smrg    struct udev_list_entry *devices, *dev_list_entry;
548746cb53Smrg    struct udev_device *dev;
558746cb53Smrg
568746cb53Smrg    udev = udev_new();
578746cb53Smrg    if (!udev)
588746cb53Smrg	return 1;
598746cb53Smrg
608746cb53Smrg    /*
618746cb53Smrg     * Udev error return codes that are not caught immediately are
628746cb53Smrg     * typically caught in the input argument check in the udev
638746cb53Smrg     * function calls following the failing call!
648746cb53Smrg     */
658746cb53Smrg    enumerate = udev_enumerate_new(udev);
668746cb53Smrg    if (udev_enumerate_add_match_subsystem(enumerate, "input"))
678746cb53Smrg	goto out_err;
688746cb53Smrg    if (udev_enumerate_scan_devices(enumerate))
698746cb53Smrg	goto out_err;
708746cb53Smrg
718746cb53Smrg    devices = udev_enumerate_get_list_entry(enumerate);
728746cb53Smrg    udev_list_entry_foreach(dev_list_entry, devices) {
738746cb53Smrg	const char *path, *name;
748746cb53Smrg
758746cb53Smrg	path = udev_list_entry_get_name(dev_list_entry);
768746cb53Smrg	dev = udev_device_new_from_syspath(udev, path);
778746cb53Smrg	if (!dev)
788746cb53Smrg	    goto out_err;
798746cb53Smrg	name = udev_device_get_sysattr_value(dev, "name");
808746cb53Smrg	if (name && !strcasecmp(name, KERNEL_DEVNAME))
818746cb53Smrg	    goto out_found;
828746cb53Smrg
838746cb53Smrg	udev_device_unref(dev);
848746cb53Smrg    }
858746cb53Smrg
868746cb53Smrg    udev_enumerate_unref(enumerate);
878746cb53Smrg    udev_unref(udev);
888746cb53Smrg
898746cb53Smrg    return 0;
908746cb53Smrg
918746cb53Smrg  out_found:
928746cb53Smrg    udev_device_unref(dev);
938746cb53Smrg  out_err:
948746cb53Smrg    udev_enumerate_unref(enumerate);
958746cb53Smrg    udev_unref(udev);
968746cb53Smrg
978746cb53Smrg    return 1;
988746cb53Smrg}
998746cb53Smrg#else
1008746cb53Smrgint vmmouse_uses_kernel_driver(void)
1018746cb53Smrg{
1028746cb53Smrg   return 0;
1038746cb53Smrg}
1048746cb53Smrg#endif
105