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.

227 lines
5.0 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. filter.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. #ifdef ALLOC_PRAGMA
  19. #pragma alloc_text(INIT, DriverEntry)
  20. #pragma alloc_text(PAGE, AddDevice)
  21. #pragma alloc_text(PAGE, DriverUnload)
  22. #endif
  23. BOOLEAN isWin9x = FALSE;
  24. NTSTATUS DriverEntry(
  25. IN PDRIVER_OBJECT DriverObject,
  26. IN PUNICODE_STRING RegistryPath
  27. )
  28. /*++
  29. Routine Description:
  30. Installable driver initialization entry point.
  31. This entry point is called directly by the I/O system.
  32. Arguments:
  33. DriverObject - pointer to the driver object
  34. RegistryPath - pointer to a unicode string representing the path,
  35. to driver-specific key in the registry.
  36. Return Value:
  37. STATUS_SUCCESS if successful,
  38. STATUS_UNSUCCESSFUL otherwise
  39. --*/
  40. {
  41. ULONG i;
  42. PAGED_CODE();
  43. UNREFERENCED_PARAMETER(RegistryPath);
  44. DBGVERBOSE(("DriverEntry"));
  45. isWin9x = IsWin9x();
  46. /*
  47. * Route all IRPs on device objects created by this driver
  48. * to our IRP dispatch routine.
  49. */
  50. for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++){
  51. DriverObject->MajorFunction[i] = Dispatch;
  52. }
  53. DriverObject->DriverExtension->AddDevice = AddDevice;
  54. DriverObject->DriverUnload = DriverUnload;
  55. return STATUS_SUCCESS;
  56. }
  57. NTSTATUS AddDevice(
  58. IN PDRIVER_OBJECT driverObj,
  59. IN PDEVICE_OBJECT physicalDevObj
  60. )
  61. /*++
  62. Routine Description:
  63. The PlugPlay subsystem is handing us a brand new
  64. PDO (Physical Device Object), for which we
  65. (by means of INF registration) have been asked to filter.
  66. We need to determine if we should attach or not.
  67. Create a filter device object to attach to the stack
  68. Initialize that device object
  69. Return status success.
  70. Remember: we can NOT actually send ANY non pnp IRPS to the given driver
  71. stack, UNTIL we have received an IRP_MN_START_DEVICE.
  72. Arguments:
  73. driverObj - pointer to a device object.
  74. physicalDevObj - pointer to a physical device object pointer
  75. created by the underlying bus driver.
  76. Return Value:
  77. NT status code.
  78. --*/
  79. {
  80. NTSTATUS status;
  81. PDEVICE_OBJECT functionDevObj = NULL;
  82. PAGED_CODE();
  83. DBGVERBOSE(("AddDevice: drvObj=%ph, pdo=%ph", driverObj, physicalDevObj));
  84. status = IoCreateDevice( driverObj,
  85. sizeof(DEVEXT),
  86. NULL, // name for this device
  87. FILE_DEVICE_SERIAL_PORT,
  88. 0, // device characteristics
  89. TRUE, // exclusive
  90. &functionDevObj); // our device object
  91. if (NT_SUCCESS(status)){
  92. DEVEXT *devExt;
  93. PARENTFDOEXT *parentFdoExt;
  94. ASSERT(functionDevObj);
  95. /*
  96. * Initialize device extension for new device object
  97. */
  98. devExt = (DEVEXT *)functionDevObj->DeviceExtension;
  99. RtlZeroMemory(devExt, sizeof(DEVEXT));
  100. devExt->signature = DEVICE_EXTENSION_SIGNATURE;
  101. devExt->isPdo = FALSE;
  102. parentFdoExt = &devExt->parentFdoExt;
  103. parentFdoExt->state = STATE_INITIALIZED;
  104. parentFdoExt->functionDevObj = functionDevObj;
  105. parentFdoExt->physicalDevObj = physicalDevObj;
  106. parentFdoExt->driverObj = driverObj;
  107. parentFdoExt->pendingActionCount = 0;
  108. KeInitializeEvent(&parentFdoExt->removeEvent, NotificationEvent, FALSE);
  109. KeInitializeSpinLock(&parentFdoExt->devExtSpinLock);
  110. /*
  111. * Clear the initializing bit from the new device object's flags.
  112. */
  113. functionDevObj->Flags &= ~DO_DEVICE_INITIALIZING;
  114. /*
  115. * The DO_POWER_PAGABLE bit of a device object
  116. * indicates to the kernel that the power-handling
  117. * code of the corresponding driver is pageable, and
  118. * so must be called at IRQL 0.
  119. * As a filter driver, we do not want to change the power
  120. * behavior of the driver stack in any way; therefore,
  121. * we copy this bit from the lower device object.
  122. */
  123. ASSERT(!(functionDevObj->Flags & DO_POWER_PAGABLE));
  124. functionDevObj->Flags |= (physicalDevObj->Flags & DO_POWER_PAGABLE);
  125. /*
  126. * Attach the new device object to the top of the device stack.
  127. */
  128. parentFdoExt->topDevObj = IoAttachDeviceToDeviceStack(functionDevObj, physicalDevObj);
  129. ASSERT(parentFdoExt->topDevObj);
  130. DBGVERBOSE(("created fdo %ph attached to %ph.", functionDevObj, parentFdoExt->topDevObj));
  131. }
  132. ASSERT(NT_SUCCESS(status));
  133. return status;
  134. }
  135. VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
  136. /*++
  137. Routine Description:
  138. Free all the allocated resources, etc.
  139. Note: Although the DriverUnload function often does nothing,
  140. the driver must set a DriverUnload function in
  141. DriverEntry; otherwise, the kernel will never unload
  142. the driver.
  143. Arguments:
  144. DriverObject - pointer to a driver object.
  145. Return Value:
  146. VOID.
  147. --*/
  148. {
  149. PAGED_CODE();
  150. DBGVERBOSE(("DriverUnload"));
  151. }