|
|
/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
escpos.h
Abstract: ESC/POS (serial) interface for USB Point-of-Sale devices
Author:
ervinp
Environment:
Kernel mode
Revision History:
--*/
#include "ntddser.h"
/*
* Serial Status Emulation has been disabled for the time being. */ #define STATUS_ENDPOINT 0
/*
* Bit mask for the posFlag. */ #define SERIAL_EMULATION 0x0001
#define ODD_ENDPOINT 0x0002
/*
* Bit mask for the STATUS Endpoint on the USB. */ #define EMULSER_OE 0x0001
#define EMULSER_PE 0x0002
#define EMULSER_FE 0x0004
#define EMULSER_BI 0x0008
#define EMULSER_CTS 0x0010
#define EMULSER_DSR 0x0020
#define EMULSER_RI 0x0040
#define EMULSER_DCD 0x0080
#define EMULSER_DTR 0x0100
#define EMULSER_RTS 0x0200
/*
* Emulation of the bit mask on the MODEM STATUS REGISTER. */ #define SERIAL_MSR_DCTS 0x0001
#define SERIAL_MSR_DDSR 0x0002
#define SERIAL_MSR_TERI 0x0004
#define SERIAL_MSR_DDCD 0x0008
#define SERIAL_MSR_CTS 0x0010
#define SERIAL_MSR_DSR 0x0020
#define SERIAL_MSR_RI 0x0040
#define SERIAL_MSR_DCD 0x0080
/*
* These masks are used for smooth transition of the STATUS bits * from the Endpoint to the Emulated Variables. */ #define MSR_DELTA_MASK 0x000F
#define MSR_GLOBAL_MSK 0x00F0
#define MSR_DELTA_SHFT 4
/*
* Emulation of the bit mask on the LINE STATUS REGISTER. */ #define SERIAL_LSR_DR 0x0001
#define SERIAL_LSR_OE 0x0002
#define SERIAL_LSR_PE 0x0004
#define SERIAL_LSR_FE 0x0008
#define SERIAL_LSR_BI 0x0010
#define SERIAL_LSR_THRE 0x0020
#define SERIAL_LSR_TEMT 0x0040
#define SERIAL_LSR_FIFOERR 0x0080
/*
* IOCTL CODE for applications to be able to get the device's pretty name. */ #define IOCTL_INDEX 0x0800
#define IOCTL_SERIAL_QUERY_DEVICE_NAME CTL_CODE(FILE_DEVICE_SERIAL_PORT, IOCTL_INDEX + 0, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_SERIAL_QUERY_DEVICE_ATTR CTL_CODE(FILE_DEVICE_SERIAL_PORT, IOCTL_INDEX + 1, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define MAX_BUFFER 256
/*
* Run on prototype Epson printer ? // BUGBUG REMOVE
*/ #define EPSON_PRINTER 0
/*
* BUGBUG * * Is it ok to return a partial read buffer, or should we wait * until the caller's buffer is completely full ? */ #define PARTIAL_READ_BUFFERS_OK 1
/*
* This is the default interface class value for interfaces of no defined class. */ #define USB_INTERFACE_CLASS_VENDOR 0x0ff
enum deviceState { STATE_INITIALIZED, STATE_STARTING, STATE_STARTED, STATE_START_FAILED, STATE_STOPPED, // implies device was previously started successfully
STATE_SUSPENDED, STATE_REMOVING, STATE_REMOVED };
#define DEVICE_EXTENSION_SIGNATURE 'PcsE'
typedef struct endpointInfo { USBD_PIPE_HANDLE pipeHandle; ULONG pipeLen; BOOLEAN endpointIsBusy; } ENDPOINTINFO;
typedef struct PARENT_FDO_EXTENSION {
/*
* Plug-and-play state of this device object. */ enum deviceState state;
PDRIVER_OBJECT driverObj;
/*
* Flag to notify that some special feature needs to be implemented. */ ULONG posFlag;
/*
* The device object that this driver created. */ PDEVICE_OBJECT functionDevObj;
/*
* The device object created by the next lower driver. */ PDEVICE_OBJECT physicalDevObj;
/*
* The device object at the top of the stack that we attached to. * This is often (but not always) the same as physicalDevObj. */ PDEVICE_OBJECT topDevObj;
/*
* deviceCapabilities includes a * table mapping system power states to device power states. */ DEVICE_CAPABILITIES deviceCapabilities;
/*
* pendingActionCount is used to keep track of outstanding actions. * removeEvent is used to wait until all pending actions are * completed before complete the REMOVE_DEVICE IRP and let the * driver get unloaded. */ LONG pendingActionCount; KEVENT removeEvent;
USB_DEVICE_DESCRIPTOR deviceDesc; PUSB_CONFIGURATION_DESCRIPTOR configDesc;
USBD_CONFIGURATION_HANDLE configHandle; PUSBD_INTERFACE_INFORMATION interfaceInfo;
KSPIN_LOCK devExtSpinLock;
PDEVICE_RELATIONS deviceRelations;
} PARENTFDOEXT;
/*
* Device extension for a PDO created by this driver. * A POS PDO represents a single COM (serial) port interface * which consists of a single input/output endpoint pair on the USB device. */ typedef struct POS_PDO_EXTENSION { enum deviceState state; PDEVICE_OBJECT pdo; PARENTFDOEXT *parentFdoExt; LONG comPortNumber; UNICODE_STRING pdoName; UNICODE_STRING symbolicLinkName; LIST_ENTRY fileExtensionList;
ENDPOINTINFO inputEndpointInfo; ENDPOINTINFO outputEndpointInfo;
LIST_ENTRY pendingReadIrpsList; LIST_ENTRY pendingWriteIrpsList; LIST_ENTRY completedReadPacketsList;
ULONG totalQueuedReadDataLength;
WORK_QUEUE_ITEM writeWorkItem; WORK_QUEUE_ITEM readWorkItem;
FILE_BASIC_INFORMATION fileBasicInfo;
KSPIN_LOCK devExtSpinLock;
ULONG supportedBauds; // emulation of baud rates for the device
ULONG baudRate; // emulation of current baud rate
ULONG fakeDTRRTS; // emulation of DTR and RTS lines
ULONG fakeRxSize; // emulation of read buffer size
SERIAL_TIMEOUTS fakeTimeouts; // emulation of timeout controls
SERIAL_CHARS specialChars; // emulation of special characters
SERIALPERF_STATS fakePerfStats; // emulation of performance stats
SERIAL_LINE_CONTROL fakeLineControl; // emulation of the line control register
USHORT fakeLineStatus; // emulation of line status register
USHORT fakeModemStatus; // emulation of modem status register
LIST_ENTRY pendingWaitIrpsList; // queue of WAIT_ON_MASK irps
ULONG waitMask; // mask of events to be waited upon
ULONG currentMask; // mask of events that have occured
#if !STATUS_ENDPOINT
USB_DEVICE_DESCRIPTOR dummyPacket; // we simply get the desciptor for now
#endif
USHORT statusPacket; // buffer to read the status endpoint
URB statusUrb; // urb to read the status endpoint
ENDPOINTINFO statusEndpointInfo; // stores info about the status endpoint
} POSPDOEXT;
typedef struct DEVICE_EXTENSION {
/*
* Memory signature of a device extension, for debugging. */ ULONG signature;
BOOLEAN isPdo;
union { PARENTFDOEXT parentFdoExt; POSPDOEXT pdoExt; };
} DEVEXT;
typedef struct fileExtension { ULONG signature; PFILE_OBJECT fileObject; LIST_ENTRY listEntry; } FILEEXT;
typedef struct readPacket { #define READPACKET_SIG 'tPdR'
ULONG signature;
PUCHAR data; ULONG length; ULONG offset; // offset of first byte not yet returned to client
PVOID context; PURB urb;
LIST_ENTRY listEntry;
} READPACKET;
#define NO_STATUS 0x80000000
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
/*
* Memory tag for memory blocks allocated by this driver * (used in ExAllocatePoolWithTag() call). * This DWORD appears as "Filt" in a little-endian memory byte dump. */ #define ESCPOS_TAG (ULONG)'UsoP'
#define ALLOCPOOL(pooltype, size) ExAllocatePoolWithTag(pooltype, size, ESCPOS_TAG)
#define FREEPOOL(ptr) ExFreePool(ptr)
/*
* Function prototypes */ NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath); NTSTATUS AddDevice(IN PDRIVER_OBJECT driverObj, IN PDEVICE_OBJECT pdo); VOID DriverUnload(IN PDRIVER_OBJECT DriverObject); NTSTATUS Dispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); NTSTATUS FDO_PnP(PARENTFDOEXT *parentFdoExt, PIRP irp); NTSTATUS FDO_Power(PARENTFDOEXT *parentFdoExt, PIRP irp); NTSTATUS FDO_PowerComplete(IN PDEVICE_OBJECT devObj, IN PIRP irp, IN PVOID context); NTSTATUS GetDeviceCapabilities(PARENTFDOEXT *parentFdoExt); NTSTATUS CallNextDriverSync(PARENTFDOEXT *parentFdoExt, PIRP irp); NTSTATUS CallDriverSync(PDEVICE_OBJECT devObj, PIRP irp); NTSTATUS CallDriverSyncCompletion(IN PDEVICE_OBJECT devObj, IN PIRP irp, IN PVOID Context); VOID IncrementPendingActionCount(PARENTFDOEXT *parentFdoExt); VOID DecrementPendingActionCount(PARENTFDOEXT *parentFdoExt); NTSTATUS InitUSB(PARENTFDOEXT *parentFdoExt); NTSTATUS GetConfigDescriptor(PARENTFDOEXT *parentFdoExt); NTSTATUS GetDeviceDescriptor(PARENTFDOEXT *parentFdoExt); NTSTATUS SubmitUrb(PDEVICE_OBJECT pdo, PURB urb, BOOLEAN synchronous, PVOID completionRoutine, PVOID completionContext); NTSTATUS OpenComPort(POSPDOEXT *pdoExt, PIRP irp); NTSTATUS CloseComPort(POSPDOEXT *pdoExt, PIRP irp); NTSTATUS WriteComPort(POSPDOEXT *pdoExt, PIRP irp); NTSTATUS ReadComPort(POSPDOEXT *pdoExt, PIRP irp); NTSTATUS CreateSymbolicLink(POSPDOEXT *pdoExt); NTSTATUS DestroySymbolicLink(POSPDOEXT *pdoExt); PWCHAR CreateChildPdoName(PARENTFDOEXT *parentFdoExt, ULONG portNumber); NTSTATUS CreateCOMPdo(PARENTFDOEXT *parentFdoExt, ULONG comInterfaceIndex, ENDPOINTINFO *inputEndpointInfo, ENDPOINTINFO *outputEndpointInfo, ENDPOINTINFO *statusEndpointInfo); PDEVICE_RELATIONS CopyDeviceRelations(PDEVICE_RELATIONS deviceRelations); NTSTATUS QueryDeviceRelations(PARENTFDOEXT *parentFdoExt, PIRP irp); PVOID MemDup(PVOID dataPtr, ULONG length); NTSTATUS PDO_PnP(POSPDOEXT *pdoExt, PIRP irp); NTSTATUS QueryPdoID(POSPDOEXT *pdoExt, PIRP irp); NTSTATUS ReadPipe(PARENTFDOEXT *parentFdoExt, USBD_PIPE_HANDLE pipeHandle, READPACKET *readPacket, BOOLEAN synchronous); NTSTATUS ReadPipeCompletion(IN PDEVICE_OBJECT devObj, IN PIRP irp, IN PVOID context); NTSTATUS WritePipe(PARENTFDOEXT *parentFdoExt, USBD_PIPE_HANDLE pipeHandle, PUCHAR data, ULONG dataLen); NTSTATUS SelectConfiguration(PARENTFDOEXT *parentFdoExt); NTSTATUS CleanupIO(POSPDOEXT *pdoExt, PIRP irp); NTSTATUS QueryInfo(POSPDOEXT *pdoExt, PIRP irp); NTSTATUS SetInfo(POSPDOEXT *pdoExt, PIRP irp); NTSTATUS FlushBuffers(POSPDOEXT *pdoExt); NTSTATUS Ioctl(POSPDOEXT *pdoExt, PIRP irp); NTSTATUS InternalIoctl(POSPDOEXT *pdoExt, PIRP irp); NTSTATUS SubstituteOneBusName(PWCHAR hwId); NTSTATUS SubstituteBusNames(PWCHAR busNames); ULONG WStrLen(PWCHAR str); LONG WStrNCmpI(PWCHAR s1, PWCHAR s2, ULONG n); VOID WorkItemCallback_Write(PVOID context); VOID WorkItemCallback_Read(PVOID context); VOID WriteCancelRoutine(PDEVICE_OBJECT devObj, PIRP irp); NTSTATUS EnqueueReadIrp(POSPDOEXT *pdoExt, PIRP irp, BOOLEAN enqueueAtFront, BOOLEAN lockHeld); PIRP DequeueReadIrp(POSPDOEXT *pdoExt, BOOLEAN lockHeld); VOID ReadCancelRoutine(PDEVICE_OBJECT devObj, PIRP irp); VOID IssueReadForClient(POSPDOEXT *pdoExt); VOID SatisfyPendingReads(POSPDOEXT *pdoExt); READPACKET* AllocReadPacket(PVOID data, ULONG dataLen, PVOID context); VOID FreeReadPacket(READPACKET *readPacket); LONG GetComPort(PARENTFDOEXT *parentFdoExt, ULONG comInterfaceIndex); LONG GetFreeComPortNumber(); VOID ReleaseCOMPort(LONG comPortNumber); void NumToHexString(PWCHAR String, USHORT Number, USHORT stringLen); void NumToDecString(PWCHAR String, USHORT Number, USHORT stringLen); ULONG LAtoX(PWCHAR wHexString); ULONG LAtoD(PWCHAR string); LONG MyLog(ULONG base, ULONG num); NTSTATUS CreatePdoForEachEndpointPair(PARENTFDOEXT *parentFdoExt); NTSTATUS TryWrite(POSPDOEXT *pdoExt, PIRP irp); BOOLEAN IsWin9x(); PVOID PosMmGetSystemAddressForMdlSafe(PMDL MdlAddress); VOID DeleteChildPdo(POSPDOEXT *pdoExt);
/*
* Function prototypes for Serial Emulation. */ NTSTATUS QuerySpecialFeature(PARENTFDOEXT *parentFdoExt); VOID InitializeSerEmulVariables(POSPDOEXT *pdoExt); NTSTATUS EnqueueWaitIrp(POSPDOEXT *pdoExt, PIRP irp); VOID WaitMaskCancelRoutine(PDEVICE_OBJECT devObj, PIRP irp); PIRP DequeueWaitIrp(POSPDOEXT *pdoExt); VOID UpdateMask(POSPDOEXT *pdoExt); VOID CompletePendingWaitIrps(POSPDOEXT *pdoExt, ULONG mask); NTSTATUS StatusPipe(POSPDOEXT *pdoExt, USBD_PIPE_HANDLE pipeHandle); NTSTATUS StatusPipeCompletion(IN PDEVICE_OBJECT devObj, IN PIRP irp, IN PVOID context); NTSTATUS QueryDeviceName(POSPDOEXT *pdoExt, PIRP irp);
/*
* Externs */ extern BOOLEAN isWin9x;
|