Patch by Filip Navaraf: Removed the mouse class gdi callback

svn path=/trunk/; revision=10317
This commit is contained in:
Thomas Bluemel 2004-07-30 09:42:11 +00:00
parent 6a79a66086
commit 61430b7b65
4 changed files with 216 additions and 404 deletions

View file

@ -19,119 +19,77 @@
#define NDEBUG
#include <debug.h>
BOOLEAN AlreadyOpened = FALSE;
VOID MouseClassPassiveCallback(PDEVICE_OBJECT ClassDeviceObject, PVOID Context)
{
PDEVICE_EXTENSION ClassDeviceExtension = ClassDeviceObject->DeviceExtension;
MOUSE_INPUT_DATA PortData[MOUSE_BUFFER_SIZE];
ULONG InputCount;
KIRQL OldIrql;
assert(NULL != ClassDeviceExtension->GDIInformation.CallBack);
KeAcquireSpinLock(&(ClassDeviceExtension->SpinLock), &OldIrql);
DPRINT("Entering MouseClassPassiveCallback\n");
while (0 != ClassDeviceExtension->InputCount) {
ClassDeviceExtension->PortData -= ClassDeviceExtension->InputCount;
RtlMoveMemory(PortData, ClassDeviceExtension->PortData,
ClassDeviceExtension->InputCount * sizeof(MOUSE_INPUT_DATA));
InputCount = ClassDeviceExtension->InputCount;
ClassDeviceExtension->InputCount = 0;
KeReleaseSpinLock(&(ClassDeviceExtension->SpinLock), OldIrql);
DPRINT("MouseClassPassiveCallBack() Calling GDI callback at %p\n",
ClassDeviceExtension->GDIInformation.CallBack);
/* We're jumping through hoops to get to run at PASSIVE_LEVEL, let's make
sure we succeeded */
ASSERT_IRQL(PASSIVE_LEVEL);
(*(PGDI_SERVICE_CALLBACK_ROUTINE)ClassDeviceExtension->GDIInformation.CallBack)
(PortData, InputCount);
KeAcquireSpinLock(&(ClassDeviceExtension->SpinLock), &OldIrql);
}
ClassDeviceExtension->PassiveCallbackQueued = FALSE;
DPRINT("Leaving MouseClassPassiveCallback\n");
KeReleaseSpinLock(&(ClassDeviceExtension->SpinLock), OldIrql);
}
BOOLEAN MouseClassCallBack(PDEVICE_OBJECT ClassDeviceObject, PMOUSE_INPUT_DATA MouseDataStart,
PMOUSE_INPUT_DATA MouseDataEnd, PULONG InputCount)
BOOLEAN MouseClassCallBack(
PDEVICE_OBJECT ClassDeviceObject, PMOUSE_INPUT_DATA MouseDataStart,
PMOUSE_INPUT_DATA MouseDataEnd, PULONG InputCount)
{
PDEVICE_EXTENSION ClassDeviceExtension = ClassDeviceObject->DeviceExtension;
ULONG ReadSize;
PIRP Irp;
KIRQL OldIrql;
// In classical NT, you would take the input data and pipe it through the IO system, for the GDI to read.
// In ReactOS, however, we use a GDI callback for increased mouse responsiveness. The reason we don't
// simply call from the port driver is so that our mouse class driver can support NT mouse port drivers.
PIO_STACK_LOCATION Stack;
ULONG SafeInputCount = *InputCount;
ULONG ReadSize;
DPRINT("Entering MouseClassCallBack\n");
/* if(ClassDeviceExtension->ReadIsPending == TRUE)
if (ClassDeviceExtension->ReadIsPending == TRUE)
{
Irp = ClassDeviceObject->CurrentIrp;
ClassDeviceObject->CurrentIrp = NULL;
Stack = IoGetCurrentIrpStackLocation(Irp);
ReadSize = sizeof(MOUSE_INPUT_DATA) * (*InputCount);
/* A read request is waiting for input, so go straight to it */
RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer, MouseDataStart,
sizeof(MOUSE_INPUT_DATA));
// A read request is waiting for input, so go straight to it
RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer, (PCHAR)MouseDataStart, ReadSize);
// Go to next packet and complete this request with STATUS_SUCCESS
/* Go to next packet and complete this request with STATUS_SUCCESS */
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = ReadSize;
Stack->Parameters.Read.Length = ReadSize;
Irp->IoStatus.Information = sizeof(MOUSE_INPUT_DATA);
Stack->Parameters.Read.Length = sizeof(MOUSE_INPUT_DATA);
IoStartNextPacket(ClassDeviceObject, FALSE);
IoCompleteRequest(Irp, IO_MOUSE_INCREMENT);
ClassDeviceExtension->ReadIsPending = FALSE;
} */
// If we have data from the port driver and a higher service to send the data to
if((*InputCount>0) && (*(PGDI_SERVICE_CALLBACK_ROUTINE)ClassDeviceExtension->GDIInformation.CallBack != NULL))
{
KeAcquireSpinLock(&(ClassDeviceExtension->SpinLock), &OldIrql);
/* Skip the packet we just sent away */
MouseDataStart++;
SafeInputCount--;
}
if(ClassDeviceExtension->InputCount + *InputCount > MOUSE_BUFFER_SIZE)
{
ReadSize = MOUSE_BUFFER_SIZE - ClassDeviceExtension->InputCount;
} else {
ReadSize = *InputCount;
}
/* If we have data from the port driver and a higher service to send the data to */
if (SafeInputCount != 0)
{
KeAcquireSpinLock(&ClassDeviceExtension->SpinLock, &OldIrql);
// FIXME: If we exceed the buffer, mouse data gets thrown away.. better solution?
// Move the mouse input data from the port data queue to our class data queue
RtlMoveMemory(ClassDeviceExtension->PortData, (PCHAR)MouseDataStart,
sizeof(MOUSE_INPUT_DATA) * ReadSize);
// Move the pointer and counter up
ClassDeviceExtension->PortData += ReadSize;
ClassDeviceExtension->InputCount += ReadSize;
if(*(PGDI_SERVICE_CALLBACK_ROUTINE)ClassDeviceExtension->GDIInformation.CallBack != NULL) {
if (! ClassDeviceExtension->PassiveCallbackQueued) {
if (NULL == ClassDeviceExtension->WorkItem) {
ClassDeviceExtension->WorkItem = IoAllocateWorkItem(ClassDeviceObject);
}
if (NULL != ClassDeviceExtension->WorkItem) {
DPRINT("Queueing workitem\n");
IoQueueWorkItem(ClassDeviceExtension->WorkItem, MouseClassPassiveCallback, CriticalWorkQueue, NULL);
ClassDeviceExtension->PassiveCallbackQueued = TRUE;
}
if (ClassDeviceExtension->InputCount + SafeInputCount > MOUSE_BUFFER_SIZE)
{
ReadSize = MOUSE_BUFFER_SIZE - ClassDeviceExtension->InputCount;
} else {
ReadSize = SafeInputCount;
}
} else {
DPRINT("MouseClassCallBack() NO GDI callback installed\n");
}
KeReleaseSpinLock(&(ClassDeviceExtension->SpinLock), OldIrql);
} else {
DPRINT("MouseClassCallBack() entered, InputCount = %d - DOING NOTHING\n", *InputCount);
}
DPRINT("Leaving MouseClassCallBack\n");
return TRUE;
/*
* FIXME: If we exceed the buffer, mouse data gets thrown away.. better
* solution?
*/
/*
* Move the mouse input data from the port data queue to our class data
* queue.
*/
RtlMoveMemory(ClassDeviceExtension->PortData, (PCHAR)MouseDataStart,
sizeof(MOUSE_INPUT_DATA) * ReadSize);
/* Move the pointer and counter up */
ClassDeviceExtension->PortData += ReadSize;
ClassDeviceExtension->InputCount += ReadSize;
KeReleaseSpinLock(&ClassDeviceExtension->SpinLock, OldIrql);
} else {
DPRINT("MouseClassCallBack() entered, InputCount = %d - DOING NOTHING\n", *InputCount);
}
DPRINT("Leaving MouseClassCallBack\n");
return TRUE;
}
NTSTATUS ConnectMousePortDriver(PDEVICE_OBJECT ClassDeviceObject)
@ -146,8 +104,6 @@ NTSTATUS ConnectMousePortDriver(PDEVICE_OBJECT ClassDeviceObject)
CLASS_INFORMATION ClassInformation;
PDEVICE_EXTENSION DeviceExtension = ClassDeviceObject->DeviceExtension;
DeviceExtension->GDIInformation.CallBack = NULL;
// Get the port driver's DeviceObject
// FIXME: The name might change.. find a way to be more dynamic?
@ -195,147 +151,90 @@ NTSTATUS STDCALL MouseClassDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
NTSTATUS Status;
switch (Stack->MajorFunction)
{
{
case IRP_MJ_CREATE:
if (AlreadyOpened == TRUE)
{
Status = STATUS_SUCCESS;
}
else
{
Status = STATUS_SUCCESS;
AlreadyOpened = TRUE;
}
break;
Status = STATUS_SUCCESS;
break;
case IRP_MJ_CLOSE:
Status = STATUS_SUCCESS;
break;
Status = STATUS_SUCCESS;
break;
case IRP_MJ_READ:
if (Stack->Parameters.Read.Length == 0) {
Status = STATUS_SUCCESS;
} else {
Status = STATUS_PENDING;
}
break;
if (Stack->Parameters.Read.Length < sizeof(MOUSE_INPUT_DATA))
{
Status = STATUS_BUFFER_TOO_SMALL;
break;
}
IoMarkIrpPending(Irp);
IoStartPacket(DeviceObject, Irp, NULL, NULL);
return STATUS_PENDING;
default:
DPRINT1("NOT IMPLEMENTED\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
}
DPRINT1("NOT IMPLEMENTED\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
if (Status==STATUS_PENDING)
{
IoMarkIrpPending(Irp);
IoStartPacket(DeviceObject, Irp, NULL, NULL);
} else {
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
return(Status);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
VOID MouseClassStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
VOID STDCALL
MouseClassStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
ULONG ReadSize;
if(DeviceExtension->InputCount>0)
if (DeviceExtension->InputCount > 0)
{
KIRQL oldIrql;
// FIXME: We should not send too much input data.. depends on the max buffer size of the win32k
ReadSize = DeviceExtension->InputCount * sizeof(MOUSE_INPUT_DATA);
// Bring the PortData back to base so that it can be copied
DeviceExtension->PortData -= DeviceExtension->InputCount;
DeviceExtension->InputCount = 0;
KeAcquireSpinLock(&DeviceExtension->SpinLock, &oldIrql);
RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer,
DeviceExtension->PortData - DeviceExtension->InputCount,
sizeof(MOUSE_INPUT_DATA));
if (DeviceExtension->InputCount > 1)
{
RtlMoveMemory(
DeviceExtension->PortData - DeviceExtension->InputCount,
DeviceExtension->PortData - DeviceExtension->InputCount + 1,
(DeviceExtension->InputCount - 1) * sizeof(MOUSE_INPUT_DATA));
}
DeviceExtension->PortData--;
DeviceExtension->InputCount--;
DeviceExtension->ReadIsPending = FALSE;
RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer, (PCHAR)DeviceExtension->PortData, ReadSize);
// Go to next packet and complete this request with STATUS_SUCCESS
/* Go to next packet and complete this request with STATUS_SUCCESS */
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = ReadSize;
Stack->Parameters.Read.Length = ReadSize;
Irp->IoStatus.Information = sizeof(MOUSE_INPUT_DATA);
Stack->Parameters.Read.Length = sizeof(MOUSE_INPUT_DATA);
IoCompleteRequest(Irp, IO_MOUSE_INCREMENT);
oldIrql = KeGetCurrentIrql();
if (oldIrql < DISPATCH_LEVEL)
{
KeRaiseIrql (DISPATCH_LEVEL, &oldIrql);
IoStartNextPacket (DeviceObject, FALSE);
KeLowerIrql(oldIrql);
}
else
{
IoStartNextPacket (DeviceObject, FALSE);
}
IoStartNextPacket(DeviceObject, FALSE);
KeReleaseSpinLock(&DeviceExtension->SpinLock, oldIrql);
} else {
DeviceExtension->ReadIsPending = TRUE;
}
}
NTSTATUS STDCALL MouseClassInternalDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
// Retrieve GDI's callback
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status;
switch(Stack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_INTERNAL_MOUSE_CONNECT:
DeviceExtension->GDIInformation =
*((PGDI_INFORMATION)Stack->Parameters.DeviceIoControl.Type3InputBuffer);
DPRINT("MouseClassInternalDeviceControl() installed GDI callback at %p\n", DeviceExtension->GDIInformation.CallBack);
status = STATUS_SUCCESS;
break;
case IOCTL_INTERNAL_MOUSE_DISCONNECT:
DeviceExtension->GDIInformation.CallBack = NULL;
status = STATUS_SUCCESS;
break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
Irp->IoStatus.Status = status;
if (status == STATUS_PENDING) {
IoMarkIrpPending(Irp);
IoStartPacket(DeviceObject, Irp, NULL, NULL);
} else {
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
return status;
}
NTSTATUS STDCALL
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
PDEVICE_OBJECT DeviceObject;
UNICODE_STRING DeviceName = ROS_STRING_INITIALIZER(L"\\Device\\MouseClass");
UNICODE_STRING SymlinkName = ROS_STRING_INITIALIZER(L"\\??\\MouseClass"); NTSTATUS Status;
UNICODE_STRING DeviceName = ROS_STRING_INITIALIZER(L"\\Device\\Mouse");
UNICODE_STRING SymlinkName = ROS_STRING_INITIALIZER(L"\\??\\Mouse");
NTSTATUS Status;
DriverObject->MajorFunction[IRP_MJ_CREATE] = MouseClassDispatch;
// DriverObject->MajorFunction[IRP_MJ_CLOSE] = MouseClassDispatch;
// DriverObject->MajorFunction[IRP_MJ_READ] = MouseClassDispatch;
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = MouseClassInternalDeviceControl; // to get GDI callback
// DriverObject->DriverStartIo = MouseClassStartIo;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = MouseClassDispatch;
DriverObject->MajorFunction[IRP_MJ_READ] = MouseClassDispatch;
DriverObject->DriverStartIo = MouseClassStartIo;
Status = IoCreateDevice(DriverObject,
sizeof(DEVICE_EXTENSION),
@ -345,24 +244,26 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
TRUE,
&DeviceObject);
if (!NT_SUCCESS(Status))
{
return(Status);
}
{
return(Status);
}
DeviceObject->Flags = DeviceObject->Flags | DO_BUFFERED_IO;
Status = IoCreateSymbolicLink(&SymlinkName, &DeviceName);
if (!NT_SUCCESS(Status))
{
IoDeleteDevice(DeviceObject);
return(Status);
}
{
IoDeleteDevice(DeviceObject);
return Status;
}
Status = ConnectMousePortDriver(DeviceObject);
if (!NT_SUCCESS(Status))
{
IoDeleteSymbolicLink(&SymlinkName);
IoDeleteDevice(DeviceObject);
return(Status);
}
return(STATUS_SUCCESS);
{
IoDeleteSymbolicLink(&SymlinkName);
IoDeleteDevice(DeviceObject);
return Status;
}
return STATUS_SUCCESS;
}

View file

@ -6,5 +6,4 @@ typedef struct _DEVICE_EXTENSION {
ULONG InputCount;
PMOUSE_INPUT_DATA PortData;
PDEVICE_OBJECT PortDeviceObject; // FIXME: Expand this to handle multiple port drivers (make *PortDeviceObject)
GDI_INFORMATION GDIInformation;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: mouse.c,v 1.76 2004/07/14 20:48:57 navaraf Exp $
/* $Id: mouse.c,v 1.77 2004/07/30 09:42:11 weiden Exp $
*
* PROJECT: ReactOS kernel
* PURPOSE: Mouse
@ -243,103 +243,6 @@ MouseSafetyOnDrawEnd(SURFOBJ *SurfObj)
return(TRUE);
}
#define ClearMouseInput(mi) \
mi.dx = 0; \
mi.dy = 0; \
mi.mouseData = 0; \
mi.dwFlags = 0;
#define SendMouseEvent(mi) \
if(mi.dx != 0 || mi.dy != 0) \
mi.dwFlags |= MOUSEEVENTF_MOVE; \
if(mi.dwFlags) \
IntMouseInput(&mi); \
ClearMouseInput(mi);
VOID /* STDCALL */
MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount)
{
PMOUSE_INPUT_DATA mid;
MOUSEINPUT mi;
ULONG i;
ClearMouseInput(mi);
mi.time = 0;
mi.dwExtraInfo = 0;
for(i = 0; i < InputCount; i++)
{
mid = (Data + i);
mi.dx += mid->LastX;
mi.dy += mid->LastY;
if(mid->ButtonFlags)
{
if(mid->ButtonFlags & MOUSE_LEFT_BUTTON_DOWN)
{
mi.dwFlags |= MOUSEEVENTF_LEFTDOWN;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_LEFT_BUTTON_UP)
{
mi.dwFlags |= MOUSEEVENTF_LEFTUP;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_MIDDLE_BUTTON_DOWN)
{
mi.dwFlags |= MOUSEEVENTF_MIDDLEDOWN;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_MIDDLE_BUTTON_UP)
{
mi.dwFlags |= MOUSEEVENTF_MIDDLEUP;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_RIGHT_BUTTON_DOWN)
{
mi.dwFlags |= MOUSEEVENTF_RIGHTDOWN;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_RIGHT_BUTTON_UP)
{
mi.dwFlags |= MOUSEEVENTF_RIGHTUP;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_BUTTON_4_DOWN)
{
mi.mouseData |= XBUTTON1;
mi.dwFlags |= MOUSEEVENTF_XDOWN;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_BUTTON_4_UP)
{
mi.mouseData |= XBUTTON1;
mi.dwFlags |= MOUSEEVENTF_XUP;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_BUTTON_5_DOWN)
{
mi.mouseData |= XBUTTON2;
mi.dwFlags |= MOUSEEVENTF_XDOWN;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_BUTTON_5_UP)
{
mi.mouseData |= XBUTTON2;
mi.dwFlags |= MOUSEEVENTF_XUP;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_WHEEL)
{
mi.mouseData = mid->ButtonData;
mi.dwFlags |= MOUSEEVENTF_WHEEL;
SendMouseEvent(mi);
}
}
}
SendMouseEvent(mi);
}
/* SOFTWARE MOUSE POINTER IMPLEMENTATION **************************************/
VOID FASTCALL

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: input.c,v 1.36 2004/07/04 01:23:32 navaraf Exp $
/* $Id: input.c,v 1.37 2004/07/30 09:42:11 weiden Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -34,13 +34,9 @@
/* GLOBALS *******************************************************************/
#define ENABLEMOUSEGDICALLBACK 1
static HANDLE MouseDeviceHandle;
#if !ENABLEMOUSEGDICALLBACK
static HANDLE MouseThreadHandle;
static CLIENT_ID MouseThreadId;
#endif
static HANDLE KeyboardThreadHandle;
static CLIENT_ID KeyboardThreadId;
static HANDLE KeyboardDeviceHandle;
@ -50,8 +46,104 @@ PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue = 0;
/* FUNCTIONS *****************************************************************/
#if !ENABLEMOUSEGDICALLBACK
VOID STDCALL_FUNC STATIC
#define ClearMouseInput(mi) \
mi.dx = 0; \
mi.dy = 0; \
mi.mouseData = 0; \
mi.dwFlags = 0;
#define SendMouseEvent(mi) \
if(mi.dx != 0 || mi.dy != 0) \
mi.dwFlags |= MOUSEEVENTF_MOVE; \
if(mi.dwFlags) \
IntMouseInput(&mi); \
ClearMouseInput(mi);
VOID FASTCALL
ProcessMouseInputData(PMOUSE_INPUT_DATA Data, ULONG InputCount)
{
PMOUSE_INPUT_DATA mid;
MOUSEINPUT mi;
ULONG i;
ClearMouseInput(mi);
mi.time = 0;
mi.dwExtraInfo = 0;
for(i = 0; i < InputCount; i++)
{
mid = (Data + i);
mi.dx += mid->LastX;
mi.dy += mid->LastY;
if(mid->ButtonFlags)
{
if(mid->ButtonFlags & MOUSE_LEFT_BUTTON_DOWN)
{
mi.dwFlags |= MOUSEEVENTF_LEFTDOWN;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_LEFT_BUTTON_UP)
{
mi.dwFlags |= MOUSEEVENTF_LEFTUP;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_MIDDLE_BUTTON_DOWN)
{
mi.dwFlags |= MOUSEEVENTF_MIDDLEDOWN;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_MIDDLE_BUTTON_UP)
{
mi.dwFlags |= MOUSEEVENTF_MIDDLEUP;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_RIGHT_BUTTON_DOWN)
{
mi.dwFlags |= MOUSEEVENTF_RIGHTDOWN;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_RIGHT_BUTTON_UP)
{
mi.dwFlags |= MOUSEEVENTF_RIGHTUP;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_BUTTON_4_DOWN)
{
mi.mouseData |= XBUTTON1;
mi.dwFlags |= MOUSEEVENTF_XDOWN;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_BUTTON_4_UP)
{
mi.mouseData |= XBUTTON1;
mi.dwFlags |= MOUSEEVENTF_XUP;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_BUTTON_5_DOWN)
{
mi.mouseData |= XBUTTON2;
mi.dwFlags |= MOUSEEVENTF_XDOWN;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_BUTTON_5_UP)
{
mi.mouseData |= XBUTTON2;
mi.dwFlags |= MOUSEEVENTF_XUP;
SendMouseEvent(mi);
}
if(mid->ButtonFlags & MOUSE_WHEEL)
{
mi.mouseData = mid->ButtonData;
mi.dwFlags |= MOUSEEVENTF_WHEEL;
SendMouseEvent(mi);
}
}
}
SendMouseEvent(mi);
}
VOID STDCALL
MouseThreadMain(PVOID StartContext)
{
UNICODE_STRING MouseDeviceName;
@ -121,12 +213,11 @@ MouseThreadMain(PVOID StartContext)
}
DPRINT("MouseEvent\n");
MouseGDICallBack(&MouseInput, sizeof(MOUSE_INPUT_DATA));
ProcessMouseInputData(&MouseInput, Iosb.Information / sizeof(MOUSE_INPUT_DATA));
}
DPRINT("Mouse Input Thread Stopped...\n");
}
}
#endif
STATIC VOID STDCALL
KeyboardThreadMain(PVOID StartContext)
@ -323,16 +414,6 @@ NTSTATUS FASTCALL
InitInputImpl(VOID)
{
NTSTATUS Status;
#if ENABLEMOUSEGDICALLBACK
UNICODE_STRING MouseDeviceName;
OBJECT_ATTRIBUTES MouseObjectAttributes;
IO_STATUS_BLOCK Iosb;
PIRP Irp;
PFILE_OBJECT FileObject;
GDI_INFORMATION GdiInfo;
KEVENT IoEvent;
PIO_STACK_LOCATION StackPtr;
#endif
KeInitializeEvent(&InputThreadsStart, NotificationEvent, FALSE);
@ -351,78 +432,7 @@ InitInputImpl(VOID)
/* Initialize the default keyboard layout */
(VOID)W32kGetDefaultKeyLayout();
#if ENABLEMOUSEGDICALLBACK
/*
* Connect to the mouse class driver.
* Failures here don't result in a failure return, the system must be
* able to operate without mouse
*/
RtlRosInitUnicodeStringFromLiteral(&MouseDeviceName, L"\\??\\MouseClass");
InitializeObjectAttributes(&MouseObjectAttributes,
&MouseDeviceName,
0,
NULL,
NULL);
Status = ZwOpenFile(&MouseDeviceHandle,
FILE_ALL_ACCESS,
&MouseObjectAttributes,
&Iosb,
0,
FILE_SYNCHRONOUS_IO_ALERT);
if (!NT_SUCCESS(Status))
{
DPRINT1("Win32K: Failed to open mouse.\n");
return STATUS_SUCCESS;
}
Status = ObReferenceObjectByHandle(MouseDeviceHandle,
FILE_READ_DATA | FILE_WRITE_DATA,
IoFileObjectType,
KernelMode,
(PVOID *) &FileObject,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("Win32K: Failed to reference mouse file object. (0x%X)\n", Status);
ZwClose(MouseDeviceHandle);
return STATUS_SUCCESS;
}
KeInitializeEvent(&IoEvent, FALSE, NotificationEvent);
GdiInfo.CallBack = MouseGDICallBack;
Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_MOUSE_CONNECT,
FileObject->DeviceObject,
&GdiInfo,
sizeof(GdiInfo),
NULL,
0,
TRUE,
&FileObject->Event,
&Iosb);
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->FileObject = FileObject;
StackPtr->DeviceObject = FileObject->DeviceObject;
StackPtr->Parameters.DeviceIoControl.InputBufferLength = sizeof(GdiInfo);
StackPtr->Parameters.DeviceIoControl.OutputBufferLength = 0;
Status = IoCallDriver(FileObject->DeviceObject, Irp);
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, FALSE,
NULL);
Status = Iosb.Status;
}
if (!NT_SUCCESS(Status))
{
DPRINT1("Win32K: Failed to connect to mouse driver.\n");
ObDereferenceObject(&FileObject);
NtClose(MouseDeviceHandle);
return STATUS_SUCCESS;
}
#else
Status = PsCreateSystemThread(&MouseThreadHandle,
THREAD_ALL_ACCESS,
NULL,
@ -434,7 +444,6 @@ InitInputImpl(VOID)
{
DPRINT1("Win32K: Failed to create mouse thread.\n");
}
#endif
return STATUS_SUCCESS;
}