windows-nt/Source/XPSP1/NT/drivers/wdm/input/opos/posusb/escpos.c
2020-09-26 16:20:57 +08:00

228 lines
5 KiB
C

/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
filter.c
Abstract: ESC/POS (serial) interface for USB Point-of-Sale devices
Author:
ervinp
Environment:
Kernel mode
Revision History:
--*/
#include <WDM.H>
#include <usbdi.h>
#include <usbdlib.h>
#include <usbioctl.h>
#include "escpos.h"
#include "debug.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, AddDevice)
#pragma alloc_text(PAGE, DriverUnload)
#endif
BOOLEAN isWin9x = FALSE;
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
/*++
Routine Description:
Installable driver initialization entry point.
This entry point is called directly by the I/O system.
Arguments:
DriverObject - pointer to the driver object
RegistryPath - pointer to a unicode string representing the path,
to driver-specific key in the registry.
Return Value:
STATUS_SUCCESS if successful,
STATUS_UNSUCCESSFUL otherwise
--*/
{
ULONG i;
PAGED_CODE();
UNREFERENCED_PARAMETER(RegistryPath);
DBGVERBOSE(("DriverEntry"));
isWin9x = IsWin9x();
/*
* Route all IRPs on device objects created by this driver
* to our IRP dispatch routine.
*/
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++){
DriverObject->MajorFunction[i] = Dispatch;
}
DriverObject->DriverExtension->AddDevice = AddDevice;
DriverObject->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
NTSTATUS AddDevice(
IN PDRIVER_OBJECT driverObj,
IN PDEVICE_OBJECT physicalDevObj
)
/*++
Routine Description:
The PlugPlay subsystem is handing us a brand new
PDO (Physical Device Object), for which we
(by means of INF registration) have been asked to filter.
We need to determine if we should attach or not.
Create a filter device object to attach to the stack
Initialize that device object
Return status success.
Remember: we can NOT actually send ANY non pnp IRPS to the given driver
stack, UNTIL we have received an IRP_MN_START_DEVICE.
Arguments:
driverObj - pointer to a device object.
physicalDevObj - pointer to a physical device object pointer
created by the underlying bus driver.
Return Value:
NT status code.
--*/
{
NTSTATUS status;
PDEVICE_OBJECT functionDevObj = NULL;
PAGED_CODE();
DBGVERBOSE(("AddDevice: drvObj=%ph, pdo=%ph", driverObj, physicalDevObj));
status = IoCreateDevice( driverObj,
sizeof(DEVEXT),
NULL, // name for this device
FILE_DEVICE_SERIAL_PORT,
0, // device characteristics
TRUE, // exclusive
&functionDevObj); // our device object
if (NT_SUCCESS(status)){
DEVEXT *devExt;
PARENTFDOEXT *parentFdoExt;
ASSERT(functionDevObj);
/*
* Initialize device extension for new device object
*/
devExt = (DEVEXT *)functionDevObj->DeviceExtension;
RtlZeroMemory(devExt, sizeof(DEVEXT));
devExt->signature = DEVICE_EXTENSION_SIGNATURE;
devExt->isPdo = FALSE;
parentFdoExt = &devExt->parentFdoExt;
parentFdoExt->state = STATE_INITIALIZED;
parentFdoExt->functionDevObj = functionDevObj;
parentFdoExt->physicalDevObj = physicalDevObj;
parentFdoExt->driverObj = driverObj;
parentFdoExt->pendingActionCount = 0;
KeInitializeEvent(&parentFdoExt->removeEvent, NotificationEvent, FALSE);
KeInitializeSpinLock(&parentFdoExt->devExtSpinLock);
/*
* Clear the initializing bit from the new device object's flags.
*/
functionDevObj->Flags &= ~DO_DEVICE_INITIALIZING;
/*
* The DO_POWER_PAGABLE bit of a device object
* indicates to the kernel that the power-handling
* code of the corresponding driver is pageable, and
* so must be called at IRQL 0.
* As a filter driver, we do not want to change the power
* behavior of the driver stack in any way; therefore,
* we copy this bit from the lower device object.
*/
ASSERT(!(functionDevObj->Flags & DO_POWER_PAGABLE));
functionDevObj->Flags |= (physicalDevObj->Flags & DO_POWER_PAGABLE);
/*
* Attach the new device object to the top of the device stack.
*/
parentFdoExt->topDevObj = IoAttachDeviceToDeviceStack(functionDevObj, physicalDevObj);
ASSERT(parentFdoExt->topDevObj);
DBGVERBOSE(("created fdo %ph attached to %ph.", functionDevObj, parentFdoExt->topDevObj));
}
ASSERT(NT_SUCCESS(status));
return status;
}
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
/*++
Routine Description:
Free all the allocated resources, etc.
Note: Although the DriverUnload function often does nothing,
the driver must set a DriverUnload function in
DriverEntry; otherwise, the kernel will never unload
the driver.
Arguments:
DriverObject - pointer to a driver object.
Return Value:
VOID.
--*/
{
PAGED_CODE();
DBGVERBOSE(("DriverUnload"));
}