269 lines
7 KiB
C
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);
|
||
|
}
|
||
|
|