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.

218 lines
5.0 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. dispatch.c
  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 <WDM.H>
  13. #include <usbdi.h>
  14. #include <usbdlib.h>
  15. #include <usbioctl.h>
  16. #include "escpos.h"
  17. #include "debug.h"
  18. NTSTATUS Dispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP irp)
  19. /*++
  20. Routine Description:
  21. Common entrypoint for all Io Request Packets
  22. Arguments:
  23. DeviceObject - pointer to a device object.
  24. irp - Io Request Packet
  25. Return Value:
  26. NT status code.
  27. --*/
  28. {
  29. DEVEXT *devExt;
  30. PIO_STACK_LOCATION irpSp;
  31. ULONG majorFunc, minorFunc;
  32. BOOLEAN isPdo;
  33. NTSTATUS status;
  34. PARENTFDOEXT *parentFdoExt;
  35. devExt = DeviceObject->DeviceExtension;
  36. ASSERT(devExt->signature == DEVICE_EXTENSION_SIGNATURE);
  37. irpSp = IoGetCurrentIrpStackLocation(irp);
  38. /*
  39. * Get major/minor function codes in private variables
  40. * so we can access them after the IRP is completed.
  41. */
  42. majorFunc = irpSp->MajorFunction;
  43. minorFunc = irpSp->MinorFunction;
  44. isPdo = devExt->isPdo;
  45. if (isPdo){
  46. parentFdoExt = devExt->pdoExt.parentFdoExt;
  47. }
  48. else {
  49. parentFdoExt = &devExt->parentFdoExt;
  50. }
  51. DBG_LOG_IRP_MAJOR(irp, majorFunc, isPdo, FALSE, -1);
  52. /*
  53. * For all IRPs except REMOVE, we increment the PendingActionCount
  54. * across the dispatch routine in order to prevent a race condition with
  55. * the REMOVE_DEVICE IRP (without this increment, if REMOVE_DEVICE
  56. * preempted another IRP, device object and extension might get
  57. * freed while the second thread was still using it).
  58. */
  59. if (!((majorFunc == IRP_MJ_PNP) && (minorFunc == IRP_MN_REMOVE_DEVICE))){
  60. IncrementPendingActionCount(parentFdoExt);
  61. }
  62. if (isPdo){
  63. POSPDOEXT *pdoExt = &devExt->pdoExt;
  64. switch (majorFunc){
  65. case IRP_MJ_PNP:
  66. status = PDO_PnP(pdoExt, irp);
  67. break;
  68. case IRP_MJ_CREATE:
  69. status = OpenComPort(pdoExt, irp);
  70. break;
  71. case IRP_MJ_CLOSE:
  72. status = CloseComPort(pdoExt, irp);
  73. break;
  74. case IRP_MJ_READ:
  75. status = ReadComPort(pdoExt, irp);
  76. break;
  77. case IRP_MJ_WRITE:
  78. status = WriteComPort(pdoExt, irp);
  79. break;
  80. case IRP_MJ_CLEANUP:
  81. status = CleanupIO(pdoExt, irp);
  82. break;
  83. case IRP_MJ_QUERY_INFORMATION:
  84. status = QueryInfo(pdoExt, irp);
  85. break;
  86. case IRP_MJ_SET_INFORMATION:
  87. status = SetInfo(pdoExt, irp);
  88. break;
  89. case IRP_MJ_FLUSH_BUFFERS:
  90. status = FlushBuffers(pdoExt);
  91. break;
  92. case IRP_MJ_DEVICE_CONTROL:
  93. status = Ioctl(pdoExt, irp);
  94. break;
  95. case IRP_MJ_INTERNAL_DEVICE_CONTROL:
  96. status = InternalIoctl(pdoExt, irp);
  97. break;
  98. case IRP_MJ_POWER:
  99. PoStartNextPowerIrp(irp);
  100. status = STATUS_SUCCESS;
  101. break;
  102. default:
  103. /*
  104. * For unsupported IRPs, we fail them with the default status.
  105. */
  106. status = irp->IoStatus.Status;
  107. break;
  108. }
  109. if (status != STATUS_PENDING){
  110. irp->IoStatus.Status = status;
  111. IoCompleteRequest(irp, IO_NO_INCREMENT);
  112. }
  113. }
  114. else {
  115. if ((majorFunc != IRP_MJ_PNP) &&
  116. (majorFunc != IRP_MJ_CLOSE) &&
  117. ((parentFdoExt->state == STATE_REMOVING) ||
  118. (parentFdoExt->state == STATE_REMOVED))){
  119. /*
  120. * While the device is being removed,
  121. * we only pass down the PNP and CLOSE IRPs.
  122. * We fail all other IRPs.
  123. */
  124. status = irp->IoStatus.Status = STATUS_DELETE_PENDING;
  125. IoCompleteRequest(irp, IO_NO_INCREMENT);
  126. }
  127. else {
  128. BOOLEAN passIrpDown = FALSE;
  129. switch (majorFunc){
  130. case IRP_MJ_PNP:
  131. status = FDO_PnP(parentFdoExt, irp);
  132. break;
  133. case IRP_MJ_POWER:
  134. status = FDO_Power(parentFdoExt, irp);
  135. break;
  136. default:
  137. /*
  138. * For unsupported IRPs, we simply send the IRP
  139. * down the driver stack.
  140. */
  141. passIrpDown = TRUE;
  142. break;
  143. }
  144. if (passIrpDown){
  145. IoCopyCurrentIrpStackLocationToNext(irp);
  146. status = IoCallDriver(parentFdoExt->physicalDevObj, irp);
  147. }
  148. }
  149. }
  150. /*
  151. * Balance the increment to PendingActionCount above.
  152. */
  153. if (!((majorFunc == IRP_MJ_PNP) && (minorFunc == IRP_MN_REMOVE_DEVICE))){
  154. DecrementPendingActionCount(parentFdoExt);
  155. }
  156. DBG_LOG_IRP_MAJOR(irp, majorFunc, isPdo, TRUE, status);
  157. return status;
  158. }