Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

388 lines
13 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. escpos.h
  5. Abstract: ESC/POS (serial) interface for USB Point-of-Sale devices
  6. Author:
  7. ervinp
  8. Environment:
  9. Kernel mode
  10. Revision History:
  11. --*/
  12. #include "ntddser.h"
  13. /*
  14. * Serial Status Emulation has been disabled for the time being.
  15. */
  16. #define STATUS_ENDPOINT 0
  17. /*
  18. * Bit mask for the posFlag.
  19. */
  20. #define SERIAL_EMULATION 0x0001
  21. #define ODD_ENDPOINT 0x0002
  22. /*
  23. * Bit mask for the STATUS Endpoint on the USB.
  24. */
  25. #define EMULSER_OE 0x0001
  26. #define EMULSER_PE 0x0002
  27. #define EMULSER_FE 0x0004
  28. #define EMULSER_BI 0x0008
  29. #define EMULSER_CTS 0x0010
  30. #define EMULSER_DSR 0x0020
  31. #define EMULSER_RI 0x0040
  32. #define EMULSER_DCD 0x0080
  33. #define EMULSER_DTR 0x0100
  34. #define EMULSER_RTS 0x0200
  35. /*
  36. * Emulation of the bit mask on the MODEM STATUS REGISTER.
  37. */
  38. #define SERIAL_MSR_DCTS 0x0001
  39. #define SERIAL_MSR_DDSR 0x0002
  40. #define SERIAL_MSR_TERI 0x0004
  41. #define SERIAL_MSR_DDCD 0x0008
  42. #define SERIAL_MSR_CTS 0x0010
  43. #define SERIAL_MSR_DSR 0x0020
  44. #define SERIAL_MSR_RI 0x0040
  45. #define SERIAL_MSR_DCD 0x0080
  46. /*
  47. * These masks are used for smooth transition of the STATUS bits
  48. * from the Endpoint to the Emulated Variables.
  49. */
  50. #define MSR_DELTA_MASK 0x000F
  51. #define MSR_GLOBAL_MSK 0x00F0
  52. #define MSR_DELTA_SHFT 4
  53. /*
  54. * Emulation of the bit mask on the LINE STATUS REGISTER.
  55. */
  56. #define SERIAL_LSR_DR 0x0001
  57. #define SERIAL_LSR_OE 0x0002
  58. #define SERIAL_LSR_PE 0x0004
  59. #define SERIAL_LSR_FE 0x0008
  60. #define SERIAL_LSR_BI 0x0010
  61. #define SERIAL_LSR_THRE 0x0020
  62. #define SERIAL_LSR_TEMT 0x0040
  63. #define SERIAL_LSR_FIFOERR 0x0080
  64. /*
  65. * IOCTL CODE for applications to be able to get the device's pretty name.
  66. */
  67. #define IOCTL_INDEX 0x0800
  68. #define IOCTL_SERIAL_QUERY_DEVICE_NAME CTL_CODE(FILE_DEVICE_SERIAL_PORT, IOCTL_INDEX + 0, METHOD_BUFFERED, FILE_ANY_ACCESS)
  69. #define IOCTL_SERIAL_QUERY_DEVICE_ATTR CTL_CODE(FILE_DEVICE_SERIAL_PORT, IOCTL_INDEX + 1, METHOD_BUFFERED, FILE_ANY_ACCESS)
  70. #define MAX_BUFFER 256
  71. /*
  72. * Run on prototype Epson printer ? // BUGBUG REMOVE
  73. */
  74. #define EPSON_PRINTER 0
  75. /*
  76. * BUGBUG
  77. *
  78. * Is it ok to return a partial read buffer, or should we wait
  79. * until the caller's buffer is completely full ?
  80. */
  81. #define PARTIAL_READ_BUFFERS_OK 1
  82. /*
  83. * This is the default interface class value for interfaces of no defined class.
  84. */
  85. #define USB_INTERFACE_CLASS_VENDOR 0x0ff
  86. enum deviceState {
  87. STATE_INITIALIZED,
  88. STATE_STARTING,
  89. STATE_STARTED,
  90. STATE_START_FAILED,
  91. STATE_STOPPED, // implies device was previously started successfully
  92. STATE_SUSPENDED,
  93. STATE_REMOVING,
  94. STATE_REMOVED
  95. };
  96. #define DEVICE_EXTENSION_SIGNATURE 'PcsE'
  97. typedef struct endpointInfo {
  98. USBD_PIPE_HANDLE pipeHandle;
  99. ULONG pipeLen;
  100. BOOLEAN endpointIsBusy;
  101. } ENDPOINTINFO;
  102. typedef struct PARENT_FDO_EXTENSION {
  103. /*
  104. * Plug-and-play state of this device object.
  105. */
  106. enum deviceState state;
  107. PDRIVER_OBJECT driverObj;
  108. /*
  109. * Flag to notify that some special feature needs to be implemented.
  110. */
  111. ULONG posFlag;
  112. /*
  113. * The device object that this driver created.
  114. */
  115. PDEVICE_OBJECT functionDevObj;
  116. /*
  117. * The device object created by the next lower driver.
  118. */
  119. PDEVICE_OBJECT physicalDevObj;
  120. /*
  121. * The device object at the top of the stack that we attached to.
  122. * This is often (but not always) the same as physicalDevObj.
  123. */
  124. PDEVICE_OBJECT topDevObj;
  125. /*
  126. * deviceCapabilities includes a
  127. * table mapping system power states to device power states.
  128. */
  129. DEVICE_CAPABILITIES deviceCapabilities;
  130. /*
  131. * pendingActionCount is used to keep track of outstanding actions.
  132. * removeEvent is used to wait until all pending actions are
  133. * completed before complete the REMOVE_DEVICE IRP and let the
  134. * driver get unloaded.
  135. */
  136. LONG pendingActionCount;
  137. KEVENT removeEvent;
  138. USB_DEVICE_DESCRIPTOR deviceDesc;
  139. PUSB_CONFIGURATION_DESCRIPTOR configDesc;
  140. USBD_CONFIGURATION_HANDLE configHandle;
  141. PUSBD_INTERFACE_INFORMATION interfaceInfo;
  142. KSPIN_LOCK devExtSpinLock;
  143. PDEVICE_RELATIONS deviceRelations;
  144. } PARENTFDOEXT;
  145. /*
  146. * Device extension for a PDO created by this driver.
  147. * A POS PDO represents a single COM (serial) port interface
  148. * which consists of a single input/output endpoint pair on the USB device.
  149. */
  150. typedef struct POS_PDO_EXTENSION {
  151. enum deviceState state;
  152. PDEVICE_OBJECT pdo;
  153. PARENTFDOEXT *parentFdoExt;
  154. LONG comPortNumber;
  155. UNICODE_STRING pdoName;
  156. UNICODE_STRING symbolicLinkName;
  157. LIST_ENTRY fileExtensionList;
  158. ENDPOINTINFO inputEndpointInfo;
  159. ENDPOINTINFO outputEndpointInfo;
  160. LIST_ENTRY pendingReadIrpsList;
  161. LIST_ENTRY pendingWriteIrpsList;
  162. LIST_ENTRY completedReadPacketsList;
  163. ULONG totalQueuedReadDataLength;
  164. WORK_QUEUE_ITEM writeWorkItem;
  165. WORK_QUEUE_ITEM readWorkItem;
  166. FILE_BASIC_INFORMATION fileBasicInfo;
  167. KSPIN_LOCK devExtSpinLock;
  168. ULONG supportedBauds; // emulation of baud rates for the device
  169. ULONG baudRate; // emulation of current baud rate
  170. ULONG fakeDTRRTS; // emulation of DTR and RTS lines
  171. ULONG fakeRxSize; // emulation of read buffer size
  172. SERIAL_TIMEOUTS fakeTimeouts; // emulation of timeout controls
  173. SERIAL_CHARS specialChars; // emulation of special characters
  174. SERIALPERF_STATS fakePerfStats; // emulation of performance stats
  175. SERIAL_LINE_CONTROL fakeLineControl; // emulation of the line control register
  176. USHORT fakeLineStatus; // emulation of line status register
  177. USHORT fakeModemStatus; // emulation of modem status register
  178. LIST_ENTRY pendingWaitIrpsList; // queue of WAIT_ON_MASK irps
  179. ULONG waitMask; // mask of events to be waited upon
  180. ULONG currentMask; // mask of events that have occured
  181. #if !STATUS_ENDPOINT
  182. USB_DEVICE_DESCRIPTOR dummyPacket; // we simply get the desciptor for now
  183. #endif
  184. USHORT statusPacket; // buffer to read the status endpoint
  185. URB statusUrb; // urb to read the status endpoint
  186. ENDPOINTINFO statusEndpointInfo; // stores info about the status endpoint
  187. } POSPDOEXT;
  188. typedef struct DEVICE_EXTENSION {
  189. /*
  190. * Memory signature of a device extension, for debugging.
  191. */
  192. ULONG signature;
  193. BOOLEAN isPdo;
  194. union {
  195. PARENTFDOEXT parentFdoExt;
  196. POSPDOEXT pdoExt;
  197. };
  198. } DEVEXT;
  199. typedef struct fileExtension {
  200. ULONG signature;
  201. PFILE_OBJECT fileObject;
  202. LIST_ENTRY listEntry;
  203. } FILEEXT;
  204. typedef struct readPacket {
  205. #define READPACKET_SIG 'tPdR'
  206. ULONG signature;
  207. PUCHAR data;
  208. ULONG length;
  209. ULONG offset; // offset of first byte not yet returned to client
  210. PVOID context;
  211. PURB urb;
  212. LIST_ENTRY listEntry;
  213. } READPACKET;
  214. #define NO_STATUS 0x80000000
  215. #define MIN(a,b) (((a) < (b)) ? (a) : (b))
  216. #define MAX(a,b) (((a) > (b)) ? (a) : (b))
  217. /*
  218. * Memory tag for memory blocks allocated by this driver
  219. * (used in ExAllocatePoolWithTag() call).
  220. * This DWORD appears as "Filt" in a little-endian memory byte dump.
  221. */
  222. #define ESCPOS_TAG (ULONG)'UsoP'
  223. #define ALLOCPOOL(pooltype, size) ExAllocatePoolWithTag(pooltype, size, ESCPOS_TAG)
  224. #define FREEPOOL(ptr) ExFreePool(ptr)
  225. /*
  226. * Function prototypes
  227. */
  228. NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
  229. NTSTATUS AddDevice(IN PDRIVER_OBJECT driverObj, IN PDEVICE_OBJECT pdo);
  230. VOID DriverUnload(IN PDRIVER_OBJECT DriverObject);
  231. NTSTATUS Dispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
  232. NTSTATUS FDO_PnP(PARENTFDOEXT *parentFdoExt, PIRP irp);
  233. NTSTATUS FDO_Power(PARENTFDOEXT *parentFdoExt, PIRP irp);
  234. NTSTATUS FDO_PowerComplete(IN PDEVICE_OBJECT devObj, IN PIRP irp, IN PVOID context);
  235. NTSTATUS GetDeviceCapabilities(PARENTFDOEXT *parentFdoExt);
  236. NTSTATUS CallNextDriverSync(PARENTFDOEXT *parentFdoExt, PIRP irp);
  237. NTSTATUS CallDriverSync(PDEVICE_OBJECT devObj, PIRP irp);
  238. NTSTATUS CallDriverSyncCompletion(IN PDEVICE_OBJECT devObj, IN PIRP irp, IN PVOID Context);
  239. VOID IncrementPendingActionCount(PARENTFDOEXT *parentFdoExt);
  240. VOID DecrementPendingActionCount(PARENTFDOEXT *parentFdoExt);
  241. NTSTATUS InitUSB(PARENTFDOEXT *parentFdoExt);
  242. NTSTATUS GetConfigDescriptor(PARENTFDOEXT *parentFdoExt);
  243. NTSTATUS GetDeviceDescriptor(PARENTFDOEXT *parentFdoExt);
  244. NTSTATUS SubmitUrb(PDEVICE_OBJECT pdo, PURB urb, BOOLEAN synchronous, PVOID completionRoutine, PVOID completionContext);
  245. NTSTATUS OpenComPort(POSPDOEXT *pdoExt, PIRP irp);
  246. NTSTATUS CloseComPort(POSPDOEXT *pdoExt, PIRP irp);
  247. NTSTATUS WriteComPort(POSPDOEXT *pdoExt, PIRP irp);
  248. NTSTATUS ReadComPort(POSPDOEXT *pdoExt, PIRP irp);
  249. NTSTATUS CreateSymbolicLink(POSPDOEXT *pdoExt);
  250. NTSTATUS DestroySymbolicLink(POSPDOEXT *pdoExt);
  251. PWCHAR CreateChildPdoName(PARENTFDOEXT *parentFdoExt, ULONG portNumber);
  252. NTSTATUS CreateCOMPdo(PARENTFDOEXT *parentFdoExt, ULONG comInterfaceIndex, ENDPOINTINFO *inputEndpointInfo, ENDPOINTINFO *outputEndpointInfo, ENDPOINTINFO *statusEndpointInfo);
  253. PDEVICE_RELATIONS CopyDeviceRelations(PDEVICE_RELATIONS deviceRelations);
  254. NTSTATUS QueryDeviceRelations(PARENTFDOEXT *parentFdoExt, PIRP irp);
  255. PVOID MemDup(PVOID dataPtr, ULONG length);
  256. NTSTATUS PDO_PnP(POSPDOEXT *pdoExt, PIRP irp);
  257. NTSTATUS QueryPdoID(POSPDOEXT *pdoExt, PIRP irp);
  258. NTSTATUS ReadPipe(PARENTFDOEXT *parentFdoExt, USBD_PIPE_HANDLE pipeHandle, READPACKET *readPacket, BOOLEAN synchronous);
  259. NTSTATUS ReadPipeCompletion(IN PDEVICE_OBJECT devObj, IN PIRP irp, IN PVOID context);
  260. NTSTATUS WritePipe(PARENTFDOEXT *parentFdoExt, USBD_PIPE_HANDLE pipeHandle, PUCHAR data, ULONG dataLen);
  261. NTSTATUS SelectConfiguration(PARENTFDOEXT *parentFdoExt);
  262. NTSTATUS CleanupIO(POSPDOEXT *pdoExt, PIRP irp);
  263. NTSTATUS QueryInfo(POSPDOEXT *pdoExt, PIRP irp);
  264. NTSTATUS SetInfo(POSPDOEXT *pdoExt, PIRP irp);
  265. NTSTATUS FlushBuffers(POSPDOEXT *pdoExt);
  266. NTSTATUS Ioctl(POSPDOEXT *pdoExt, PIRP irp);
  267. NTSTATUS InternalIoctl(POSPDOEXT *pdoExt, PIRP irp);
  268. NTSTATUS SubstituteOneBusName(PWCHAR hwId);
  269. NTSTATUS SubstituteBusNames(PWCHAR busNames);
  270. ULONG WStrLen(PWCHAR str);
  271. LONG WStrNCmpI(PWCHAR s1, PWCHAR s2, ULONG n);
  272. VOID WorkItemCallback_Write(PVOID context);
  273. VOID WorkItemCallback_Read(PVOID context);
  274. VOID WriteCancelRoutine(PDEVICE_OBJECT devObj, PIRP irp);
  275. NTSTATUS EnqueueReadIrp(POSPDOEXT *pdoExt, PIRP irp, BOOLEAN enqueueAtFront, BOOLEAN lockHeld);
  276. PIRP DequeueReadIrp(POSPDOEXT *pdoExt, BOOLEAN lockHeld);
  277. VOID ReadCancelRoutine(PDEVICE_OBJECT devObj, PIRP irp);
  278. VOID IssueReadForClient(POSPDOEXT *pdoExt);
  279. VOID SatisfyPendingReads(POSPDOEXT *pdoExt);
  280. READPACKET* AllocReadPacket(PVOID data, ULONG dataLen, PVOID context);
  281. VOID FreeReadPacket(READPACKET *readPacket);
  282. LONG GetComPort(PARENTFDOEXT *parentFdoExt, ULONG comInterfaceIndex);
  283. LONG GetFreeComPortNumber();
  284. VOID ReleaseCOMPort(LONG comPortNumber);
  285. void NumToHexString(PWCHAR String, USHORT Number, USHORT stringLen);
  286. void NumToDecString(PWCHAR String, USHORT Number, USHORT stringLen);
  287. ULONG LAtoX(PWCHAR wHexString);
  288. ULONG LAtoD(PWCHAR string);
  289. LONG MyLog(ULONG base, ULONG num);
  290. NTSTATUS CreatePdoForEachEndpointPair(PARENTFDOEXT *parentFdoExt);
  291. NTSTATUS TryWrite(POSPDOEXT *pdoExt, PIRP irp);
  292. BOOLEAN IsWin9x();
  293. PVOID PosMmGetSystemAddressForMdlSafe(PMDL MdlAddress);
  294. VOID DeleteChildPdo(POSPDOEXT *pdoExt);
  295. /*
  296. * Function prototypes for Serial Emulation.
  297. */
  298. NTSTATUS QuerySpecialFeature(PARENTFDOEXT *parentFdoExt);
  299. VOID InitializeSerEmulVariables(POSPDOEXT *pdoExt);
  300. NTSTATUS EnqueueWaitIrp(POSPDOEXT *pdoExt, PIRP irp);
  301. VOID WaitMaskCancelRoutine(PDEVICE_OBJECT devObj, PIRP irp);
  302. PIRP DequeueWaitIrp(POSPDOEXT *pdoExt);
  303. VOID UpdateMask(POSPDOEXT *pdoExt);
  304. VOID CompletePendingWaitIrps(POSPDOEXT *pdoExt, ULONG mask);
  305. NTSTATUS StatusPipe(POSPDOEXT *pdoExt, USBD_PIPE_HANDLE pipeHandle);
  306. NTSTATUS StatusPipeCompletion(IN PDEVICE_OBJECT devObj, IN PIRP irp, IN PVOID context);
  307. NTSTATUS QueryDeviceName(POSPDOEXT *pdoExt, PIRP irp);
  308. /*
  309. * Externs
  310. */
  311. extern BOOLEAN isWin9x;