windows-nt/Source/XPSP1/NT/drivers/wdm/input/tabletpc/mutohpen/hidpen.c
2020-09-26 16:20:57 +08:00

256 lines
7 KiB
C

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
hidpen.c
Abstract: Serial Pen Tablet HID Driver.
Environment:
Kernel mode
Author:
Michael Tsang (MikeTs) 13-Mar-2000
Revision History:
--*/
#include "pch.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, HpenCreateClose)
#pragma alloc_text(PAGE, HpenAddDevice)
#pragma alloc_text(PAGE, HpenUnload)
#endif //ifdef ALLOC_PRAGMA
/*****************************************************************************
*
* @doc EXTERNAL
*
* @func NTSTATUS | DriverEntry |
* Installable driver initialization entry point.
* <nl>This entry point is called directly by the I/O system.
*
* @parm IN PDRIVER_OBJECT | DrvObj | Points to the driver object.
* @parm IN PUNICODE_STRINT | RegPath | Points to the registry path.
*
* @rvalue SUCCESS | returns STATUS_SUCCESS
* @rvalue FAILURE | returns NT status code
*
*****************************************************************************/
NTSTATUS EXTERNAL
DriverEntry(
IN PDRIVER_OBJECT DrvObj,
IN PUNICODE_STRING RegPath
)
{
PROCNAME("DriverEntry")
NTSTATUS status = STATUS_SUCCESS;
HID_MINIDRIVER_REGISTRATION hidMinidriverRegistration;
ENTER(1, ("(DrvObj=%p,RegPath=%p)\n", DrvObj, RegPath));
DrvObj->MajorFunction[IRP_MJ_CREATE] =
DrvObj->MajorFunction[IRP_MJ_CLOSE] = HpenCreateClose;
DrvObj->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = HpenInternalIoctl;
DrvObj->MajorFunction[IRP_MJ_PNP] = HpenPnp;
DrvObj->MajorFunction[IRP_MJ_POWER] = HpenPower;
DrvObj->DriverUnload = HpenUnload;
DrvObj->DriverExtension->AddDevice = HpenAddDevice;
//
// Register with HIDCLASS.SYS module
//
RtlZeroMemory(&hidMinidriverRegistration,
sizeof(hidMinidriverRegistration));
hidMinidriverRegistration.Revision = HID_REVISION;
hidMinidriverRegistration.DriverObject = DrvObj;
hidMinidriverRegistration.RegistryPath = RegPath;
hidMinidriverRegistration.DeviceExtensionSize = sizeof(DEVICE_EXTENSION);
hidMinidriverRegistration.DevicesArePolled = FALSE;
status = HidRegisterMinidriver(&hidMinidriverRegistration);
if (NT_SUCCESS(status))
{
#ifdef DEBUG
ExInitializeFastMutex(&gmutexDevExtList);
InitializeListHead(&glistDevExtHead);
#endif
}
else
{
ERRPRINT(("failed to register mini driver (status=%x)\n", status));
}
EXIT(1, ("=%x\n", status));
return status;
} //DriverEntry
/*****************************************************************************
*
* @doc EXTERNAL
*
* @func NTSTATUS | HpenCreateClose |
* Process the create and close IRPs sent to this device.
*
* @parm IN PDEVICE_OBJECT | DevObj | Points to the device object.
* @parm IN PIRP | Irp | Points to an I/O Request Packet.
*
* @rvalue STATUS_SUCCESS | success
* @rvalue STATUS_INVALID_PARAMETER | Irp not handled
*
*****************************************************************************/
NTSTATUS EXTERNAL
HpenCreateClose(
IN PDEVICE_OBJECT DevObj,
IN PIRP Irp
)
{
PROCNAME("HpenCreateClose")
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION irpsp;
PAGED_CODE ();
UNREFERENCED_PARAMETER(DevObj);
irpsp = IoGetCurrentIrpStackLocation(Irp);
ENTER(1, ("(DevObj=%p,Irp=%p,IrpStack=%p,Major=%s)\n",
DevObj, Irp, irpsp,
LookupName(irpsp->MajorFunction, MajorFnNames)));
switch(irpsp->MajorFunction)
{
case IRP_MJ_CREATE:
case IRP_MJ_CLOSE:
Irp->IoStatus.Information = 0;
break;
default:
ERRPRINT(("invalid major function %s\n",
LookupName(irpsp->MajorFunction, MajorFnNames)));
status = STATUS_INVALID_PARAMETER;
break;
}
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
EXIT(1, ("=%x\n", status));
return status;
} //HpenCreateClose
/*****************************************************************************
*
* @doc EXTERNAL
*
* @func NTSTATUS | HpenAddDevice |
* Called by hidclass, allows us to initialize our device extensions.
*
* @parm IN PDRIVER_OBJECT | DrvObj | Points to the driver object.
* @parm IN PDEVICE_OBJECT | DevObj |
* Points to a functional device object created by hidclass.
*
* @rvalue SUCCESS | Returns STATUS_SUCCESS.
* @rvalue FAILURE | Returns NT status code.
*
*****************************************************************************/
NTSTATUS EXTERNAL
HpenAddDevice(
IN PDRIVER_OBJECT DrvObj,
IN PDEVICE_OBJECT DevObj
)
{
PROCNAME("HpenAddDevice")
NTSTATUS status;
PDEVICE_EXTENSION devext;
PAGED_CODE ();
ENTER(1, ("(DrvObj=%p,DevObj=%p)\n", DrvObj, DevObj));
ASSERT(DevObj != NULL);
UNREFERENCED_PARAMETER(DrvObj);
devext = GET_MINIDRIVER_DEVICE_EXTENSION(DevObj);
RtlZeroMemory(devext, sizeof(*devext));
devext->pdo = GET_PDO(DevObj);
devext->SerialDevObj = GET_NEXT_DEVICE_OBJECT(DevObj);
devext->ReadWorkItem[0].WorkItem = IoAllocateWorkItem(DevObj);
if (devext->ReadWorkItem[0].WorkItem != NULL)
{
devext->ReadWorkItem[1].WorkItem = IoAllocateWorkItem(DevObj);
if (devext->ReadWorkItem[1].WorkItem != NULL)
{
IoInitializeRemoveLock(&devext->RemoveLock, HPEN_POOL_TAG, 0, 10);
KeInitializeSpinLock(&devext->SpinLock);
devext->PowerState = PowerDeviceD0;
#ifdef DEBUG
ExAcquireFastMutex(&gmutexDevExtList);
InsertTailList(&glistDevExtHead, &devext->List);
ExReleaseFastMutex(&gmutexDevExtList);
#endif
OemAddDevice(devext);
DevObj->Flags &= ~DO_DEVICE_INITIALIZING;
DevObj->Flags |= DO_POWER_PAGABLE;
status = STATUS_SUCCESS;
}
else
{
ERRPRINT(("failed to allocate second read work item\n"));
IoFreeWorkItem(devext->ReadWorkItem[0].WorkItem);
status = STATUS_INSUFFICIENT_RESOURCES;
}
}
else
{
ERRPRINT(("failed to allocate first read work item\n"));
status = STATUS_INSUFFICIENT_RESOURCES;
}
EXIT(1, ("=%x\n", status));
return status;
} //HpenAddDevice
/*****************************************************************************
*
* @doc EXTERNAL
*
* @func void | HpenUnload | Free all the allocated resources, etc.
*
* @parm IN PDRIVER_OBJECT | DrvObj | Points to the driver object.
*
*****************************************************************************/
VOID EXTERNAL
HpenUnload(
IN PDRIVER_OBJECT DrvObj
)
{
PROCNAME("HpenUnload")
PAGED_CODE();
ENTER(1, ("(DrvObj=%p)\n", DrvObj));
ASSERT(DrvObj->DeviceObject == NULL);
UNREFERENCED_PARAMETER(DrvObj);
EXIT(1, ("!\n"));
return;
} //HpenUnload