windows-nt/Source/XPSP1/NT/drivers/input/hidport/mouhid/creatcls.c
2020-09-26 16:20:57 +08:00

269 lines
7 KiB
C

/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
creatcls.c
Abstract:
This module contains the code for IRP_MJ_CREATE and IRP_MJ_CLOSE dispatch
functions for the HID Mouse Filter Driver.
Environment:
Kernel mode only.
Revision History:
Jan-1997 : Initial writing, Dan Markarian
May-97 : Kenneth D. Ray converted to PnP filter
--*/
#include "mouhid.h"
NTSTATUS
MouHid_CreateComplete (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
/*++
Routine Description:
The pnp IRP is in the process of completing.
signal
Arguments:
Context set to the device object in question.
--*/
{
PIO_STACK_LOCATION stack;
UNREFERENCED_PARAMETER (DeviceObject);
stack = IoGetCurrentIrpStackLocation (Irp);
if (Irp->PendingReturned) {
IoMarkIrpPending( Irp );
}
KeSetEvent ((PKEVENT) Context, 0, FALSE);
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS
MouHid_Create (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This is the dispatch routine for create/open requests. This request
completes successfully, unless the filename's length is non-zero.
Arguments:
DeviceObject - Pointer to the device object.
Irp - Pointer to the request packet.
Return Value:
NT status code.
--*/
{
PIO_STACK_LOCATION irpSp = NULL;
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_EXTENSION data = NULL;
KEVENT event;
Print (DBG_CC_TRACE, ("DispatchCreate: Enter.\n"));
data = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
//
// Get a pointer to the current parameters for this request. The
// information is contained in the current stack location.
//
irpSp = IoGetCurrentIrpStackLocation (Irp);
//
// Determine if request is trying to open a subdirectory of the
// given device object. This is not allowed.
//
if (0 != irpSp->FileObject->FileName.Length) {
Print(DBG_CC_ERROR, ("ERROR: Create Access Denied.\n"));
status = STATUS_ACCESS_DENIED;
goto MouHid_CreateReject;
}
status = IoAcquireRemoveLock (&data->RemoveLock, Irp);
if (!NT_SUCCESS (status)) {
goto MouHid_CreateReject;
}
ExAcquireFastMutex (&data->CreateCloseMutex);
if (NULL == data->ConnectData.ClassService) {
//
// No Connection yet. How can we be enabled?
//
Print (DBG_IOCTL_ERROR, ("ERROR: enable before connect!\n"));
status = STATUS_UNSUCCESSFUL;
} else {
IoCopyCurrentIrpStackLocationToNext (Irp);
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoSetCompletionRoutine (Irp,
MouHid_CreateComplete,
&event,
TRUE,
TRUE,
TRUE);
status = IoCallDriver (data->TopOfStack, Irp);
if (STATUS_PENDING == status) {
KeWaitForSingleObject(&event,
Executive, // Waiting for reason of a driver
KernelMode, // Waiting in kernel mode
FALSE, // No allert
NULL); // No timeout
}
if (NT_SUCCESS (status)) {
status = Irp->IoStatus.Status;
}
if (NT_SUCCESS (status)) {
InterlockedIncrement(&data->EnableCount);
if (NULL == data->ReadFile &&
(irpSp->Parameters.Create.SecurityContext->DesiredAccess & FILE_READ_DATA)) {
//
// We want to start the read pump.
//
Print (DBG_IOCTL_INFO, ("Enabling Mouse \n"));
data->ReadFile = irpSp->FileObject;
KeResetEvent (&data->ReadCompleteEvent);
data->ReadInterlock = MOUHID_END_READ;
// Acquire another time for the read irp.
IoAcquireRemoveLock (&data->RemoveLock, data->ReadIrp);
data->ReadIrp->IoStatus.Status = STATUS_SUCCESS;
status = MouHid_StartRead (data);
if (STATUS_PENDING == status) {
status = STATUS_SUCCESS;
} else if (!NT_SUCCESS(status)) {
//
// Set it back to NULL so that a future open tries again
// Read should not fail if open passed. ASSERT!
//
ASSERT(NT_SUCCESS(status));
data->ReadFile = NULL;
}
}
ASSERT (data->EnableCount < 100);
ASSERT (0 < data->EnableCount);
}
}
ExReleaseFastMutex (&data->CreateCloseMutex);
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
IoReleaseRemoveLock (&data->RemoveLock, Irp);
Print(DBG_CC_TRACE, ("DispatchCreate: Exit (%x).\n", status));
return status;
MouHid_CreateReject:
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
Print(DBG_CC_TRACE, ("DispatchCreate: Exit (%x).\n", status));
return status;
}
NTSTATUS
MouHid_Close (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This is the dispatch routine for close requests. This request
completes successfully, unless the file name length is zero.
Arguments:
DeviceObject - Pointer to the device object.
Irp - Pointer to the request packet.
Return Value:
NT status code.
--*/
{
PDEVICE_EXTENSION data;
PIO_STACK_LOCATION stack;
Print(DBG_CC_TRACE, ("DispatchClose: Enter\n"));
data = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
stack = IoGetCurrentIrpStackLocation (Irp);
ExAcquireFastMutex (&data->CreateCloseMutex);
ASSERT (data->EnableCount < 100);
ASSERT (0 < data->EnableCount);
if (0 == InterlockedDecrement(&data->EnableCount)) {
Print (DBG_IOCTL_INFO, ("Disabling Mouse \n"));
KeWaitForSingleObject (&data->ReadSentEvent,
Executive,
KernelMode,
FALSE,
NULL
);
if (IoCancelIrp (data->ReadIrp)) {
KeWaitForSingleObject (&data->ReadCompleteEvent,
Executive,
KernelMode,
FALSE,
NULL
);
}
ASSERT (NULL != data->ReadFile);
// ASSERT (data->ReadFile == stack->FileObject);
data->ReadFile = NULL;
}
ExReleaseFastMutex (&data->CreateCloseMutex);
IoSkipCurrentIrpStackLocation (Irp);
Print(DBG_CC_TRACE, ("DispatchClose: Exit \n"));
return IoCallDriver (data->TopOfStack, Irp);
}