Commit 0ed830ea authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

mouhid.sys: Introduce a new HID pointer device driver.

This only matches with digitizer devices for now, it could later be used for HID mice but for now we use a different path for that.
parent 8db5dec9
......@@ -169,6 +169,7 @@ P: Aric Stewart <aric@codeweavers.com>
F: dlls/hid/
F: dlls/hidclass.sys/
F: dlls/hidparse.sys/
F: dlls/mouhid.sys/
F: dlls/winehid.sys/
HTTP server
......
......@@ -1233,6 +1233,7 @@ enable_midimap
enable_mlang
enable_mmcndmgr
enable_mmdevapi
enable_mouhid_sys
enable_mountmgr_sys
enable_mp3dmod
enable_mpr
......@@ -21976,6 +21977,7 @@ wine_fn_config_makefile dlls/mmdevapi/tests enable_tests
wine_fn_config_makefile dlls/mmdevldr.vxd enable_win16
wine_fn_config_makefile dlls/mmsystem.dll16 enable_win16
wine_fn_config_makefile dlls/monodebg.vxd enable_win16
wine_fn_config_makefile dlls/mouhid.sys enable_mouhid_sys
wine_fn_config_makefile dlls/mountmgr.sys enable_mountmgr_sys
wine_fn_config_makefile dlls/mouse.drv16 enable_win16
wine_fn_config_makefile dlls/mp3dmod enable_mp3dmod
......
......@@ -2792,6 +2792,7 @@ WINE_CONFIG_MAKEFILE(dlls/mmdevapi/tests)
WINE_CONFIG_MAKEFILE(dlls/mmdevldr.vxd,enable_win16)
WINE_CONFIG_MAKEFILE(dlls/mmsystem.dll16,enable_win16)
WINE_CONFIG_MAKEFILE(dlls/monodebg.vxd,enable_win16)
WINE_CONFIG_MAKEFILE(dlls/mouhid.sys)
WINE_CONFIG_MAKEFILE(dlls/mountmgr.sys)
WINE_CONFIG_MAKEFILE(dlls/mouse.drv16,enable_win16)
WINE_CONFIG_MAKEFILE(dlls/mp3dmod)
......
MODULE = mouhid.sys
IMPORTS = ntoskrnl
EXTRADLLFLAGS = -Wl,--subsystem,native
SOURCES = \
main.c \
mouhid.rc \
mouhid.sys.spec
/*
* Copyright 2024 Rémi Bernon for CodeWeavers
*
* 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 <stdarg.h>
#include <stdlib.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "winioctl.h"
#include "ntuser.h"
#include "ddk/wdm.h"
#include "ddk/hidport.h"
#include "ddk/hidpddi.h"
#include "ddk/hidtypes.h"
#include "wine/hid.h"
#include "wine/debug.h"
#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL(hid);
struct device
{
LONG removed;
DEVICE_OBJECT *bus_device;
};
static inline struct device *impl_from_DEVICE_OBJECT( DEVICE_OBJECT *device )
{
return (struct device *)device->DeviceExtension;
}
static NTSTATUS WINAPI driver_ioctl( DEVICE_OBJECT *device, IRP *irp )
{
IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp );
ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;
struct device *impl = impl_from_DEVICE_OBJECT( device );
if (InterlockedOr( &impl->removed, FALSE ))
{
irp->IoStatus.Status = STATUS_DELETE_PENDING;
irp->IoStatus.Information = 0;
IoCompleteRequest( irp, IO_NO_INCREMENT );
return STATUS_DELETE_PENDING;
}
TRACE( "device %p, irp %p, code %#lx, bus_device %p.\n", device, irp, code, impl->bus_device );
IoSkipCurrentIrpStackLocation( irp );
return IoCallDriver( impl->bus_device, irp );
}
static NTSTATUS WINAPI set_event_completion( DEVICE_OBJECT *device, IRP *irp, void *context )
{
if (irp->PendingReturned) KeSetEvent( (KEVENT *)context, IO_NO_INCREMENT, FALSE );
return STATUS_MORE_PROCESSING_REQUIRED;
}
static NTSTATUS WINAPI driver_pnp( DEVICE_OBJECT *device, IRP *irp )
{
IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp );
struct device *impl = impl_from_DEVICE_OBJECT( device );
UCHAR code = stack->MinorFunction;
NTSTATUS status;
KEVENT event;
TRACE( "device %p, irp %p, code %#x, bus_device %p.\n", device, irp, code, impl->bus_device );
switch (stack->MinorFunction)
{
case IRP_MN_START_DEVICE:
KeInitializeEvent( &event, NotificationEvent, FALSE );
IoCopyCurrentIrpStackLocationToNext( irp );
IoSetCompletionRoutine( irp, set_event_completion, &event, TRUE, TRUE, TRUE );
status = IoCallDriver( impl->bus_device, irp );
if (status == STATUS_PENDING)
{
KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL );
status = irp->IoStatus.Status;
}
if (status) irp->IoStatus.Status = status;
IoCompleteRequest( irp, IO_NO_INCREMENT );
return status;
case IRP_MN_SURPRISE_REMOVAL:
status = STATUS_SUCCESS;
break;
case IRP_MN_REMOVE_DEVICE:
IoSkipCurrentIrpStackLocation( irp );
status = IoCallDriver( impl->bus_device, irp );
IoDetachDevice( impl->bus_device );
IoDeleteDevice( device );
return status;
default:
IoSkipCurrentIrpStackLocation( irp );
return IoCallDriver( impl->bus_device, irp );
}
return STATUS_SUCCESS;
}
static NTSTATUS WINAPI add_device( DRIVER_OBJECT *driver, DEVICE_OBJECT *bus_device )
{
struct device *impl;
DEVICE_OBJECT *device;
NTSTATUS status;
TRACE( "driver %p, bus_device %p.\n", driver, bus_device );
if ((status = IoCreateDevice( driver, sizeof(struct device), NULL, FILE_DEVICE_BUS_EXTENDER,
0, FALSE, &device )))
{
ERR( "failed to create bus FDO, status %#lx.\n", status );
return status;
}
impl = device->DeviceExtension;
impl->bus_device = bus_device;
IoAttachDeviceToDeviceStack( device, bus_device );
device->Flags &= ~DO_DEVICE_INITIALIZING;
return STATUS_SUCCESS;
}
static void WINAPI driver_unload( DRIVER_OBJECT *driver )
{
TRACE( "driver %p\n", driver );
}
NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
{
TRACE( "driver %p, path %s.\n", driver, debugstr_w(path->Buffer) );
driver->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = driver_ioctl;
driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = driver_ioctl;
driver->MajorFunction[IRP_MJ_PNP] = driver_pnp;
driver->DriverExtension->AddDevice = add_device;
driver->DriverUnload = driver_unload;
return STATUS_SUCCESS;
}
[Version]
Signature="$CHICAGO$"
ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318}
Class=System
[Manufacturer]
Wine=mfg_section
[mfg_section]
HID touch screen device=device_section,HID_DEVICE_UP:000D_U:0004
[device_section.Services]
AddService = mouhid,0x2,svc_section
[svc_section]
Description="Wine HID mouse device driver"
DisplayName="Wine HID mouse"
ServiceBinary="%12%\mouhid.sys"
LoadOrderGroup="WinePlugPlay"
ServiceType=1
StartType=3
ErrorControl=1
/*
* Copyright 2024 Rémi Bernon for CodeWeavers
*
* 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
*/
/* @makedep: mouhid.inf */
1 WINE_DATA_FILE mouhid.inf
......@@ -2608,6 +2608,7 @@ services,"@%11%\ws2_32.dll,-4"
[InfFiles]
input.inf,"@%12%\hidclass.sys,-1"
mouhid.inf,"@%12%\mouhid.sys,-1"
winebus.inf,"@%12%\winebus.sys,-1"
winehid.inf,"@%12%\winehid.sys,-1"
wineusb.inf,"@%12%\wineusb.sys,-1"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment