PageRenderTime 28ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/USB_Drivers/MFUSB_PortingKitSample/sys/DriverEntry.cpp

https://github.com/gezidan/MicroFrameworkSDK-Mono
C++ | 362 lines | 247 code | 88 blank | 27 comment | 24 complexity | aeec4f95b2bce5882de07a292ae4e899 MD5 | raw file
  1. #include "stddcls.h"
  2. #include "driver.h"
  3. NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT pdo);
  4. VOID DriverUnload(IN PDRIVER_OBJECT fdo);
  5. static PCWSTR OperationInterface = L"Operations";
  6. static PCWSTR InquiryInterface = L"Inquiries";
  7. ///////////////////////////////////////////////////////////////////////////////
  8. #pragma PAGEDCODE
  9. extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
  10. IN PUNICODE_STRING RegistryPath)
  11. {
  12. KdPrint((DRIVERNAME " - Entering DriverEntry: DriverObject %8.8lX\n", DriverObject));
  13. // Insist that OS support at least the WDM level of the DDK we use
  14. if(!IoIsWdmVersionAvailable(1, 0))
  15. {
  16. KdPrint((DRIVERNAME " - Expected version of WDM (%d.%2.2d) not available\n", 1, 0));
  17. return STATUS_UNSUCCESSFUL;
  18. }
  19. // See if we're running under Win98 or NT:
  20. win98 = IsWin98();
  21. if(win98)
  22. KdPrint((DRIVERNAME " - Running under Windows 98\n"));
  23. else
  24. KdPrint((DRIVERNAME " - Running under NT\n"));
  25. // Initialize function pointers
  26. DriverObject->DriverUnload = DriverUnload;
  27. DriverObject->DriverExtension->AddDevice = AddDevice;
  28. DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
  29. DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
  30. DriverObject->MajorFunction[IRP_MJ_READ] = DispatchReadWriteFlush;
  31. DriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchReadWriteFlush;
  32. DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = DispatchReadWriteFlush;
  33. DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DispatchCleanup;
  34. DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
  35. DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = DispatchInternalControl;
  36. DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
  37. DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = DispatchWmi;
  38. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceIoControl;
  39. return STATUS_SUCCESS;
  40. }
  41. ///////////////////////////////////////////////////////////////////////////////
  42. #pragma PAGEDCODE
  43. VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
  44. {
  45. PAGED_CODE();
  46. KdPrint((DRIVERNAME " - Entering DriverUnload: DriverObject %8.8lX\n", DriverObject));
  47. }
  48. ///////////////////////////////////////////////////////////////////////////////
  49. NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT pdo)
  50. {
  51. PAGED_CODE();
  52. UNICODE_STRING interfaceName;
  53. KdPrint((DRIVERNAME " - Entering AddDevice: DriverObject %8.8lX, pdo %8.8lX\n", DriverObject, pdo));
  54. NTSTATUS status;
  55. // Create a function device object to represent the hardware we're managing.
  56. PDEVICE_OBJECT fdo;
  57. ULONG dxsize = (sizeof(DEVICE_EXTENSION) + 7) & ~7;
  58. ULONG xsize = dxsize + GetSizeofGenericExtension();
  59. status = IoCreateDevice(DriverObject,
  60. xsize,
  61. NULL,
  62. FILE_DEVICE_UNKNOWN,
  63. FILE_DEVICE_SECURE_OPEN,
  64. FALSE,
  65. &fdo);
  66. if(!NT_SUCCESS(status)){
  67. KdPrint((DRIVERNAME " - IoCreateDevice failed - %X\n", status));
  68. return status;
  69. }
  70. PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
  71. pdx->operationsInterfaceName.Buffer = NULL;
  72. pdx->inquiriesInterfaceName .Buffer = NULL;
  73. RtlInitUnicodeString( &interfaceName, OperationInterface );
  74. status = IoRegisterDeviceInterface(pdo,
  75. &MfUsbGuidOperations,
  76. &interfaceName,
  77. &pdx->operationsInterfaceName);
  78. if(!NT_SUCCESS(status)){
  79. KdPrint((DRIVERNAME " - IoRegisterDeviceInterface failed for operations interface - %X\n", status));
  80. return status;
  81. }
  82. RtlInitUnicodeString( &interfaceName, InquiryInterface );
  83. status = IoRegisterDeviceInterface(pdo,
  84. &MfUsbGuidInquiries,
  85. &interfaceName,
  86. &pdx->inquiriesInterfaceName);
  87. if(!NT_SUCCESS(status)){
  88. KdPrint((DRIVERNAME " - IoRegisterDeviceInterface failed for inquiry interface - %X\n", status));
  89. return status;
  90. }
  91. // From this point forward, any error will have side effects that need to
  92. // be cleaned up. Using a do-once allows us to modify the program
  93. // easily without losing track of the side effects.
  94. do {
  95. pdx->DeviceObject = fdo;
  96. pdx->Pdo = pdo;
  97. pdx->handles = 0;
  98. pdx->devHash = NULL;
  99. pdx->RecoveryThread = NULL;
  100. pdx->PollingIrp = NULL;
  101. pdx->LowerDeviceObject = NULL;
  102. pdx->manufacturer.Buffer = NULL;
  103. pdx->product .Buffer = NULL;
  104. pdx->serialNumber.Buffer = NULL;
  105. pdx->displayName .Buffer = NULL;
  106. // Declare the buffering method we'll use for read/write requests
  107. fdo->Flags |= DO_BUFFERED_IO;
  108. // Initialize irp related locks
  109. KeInitializeSpinLock(&pdx->ReadIrpLock);
  110. KeInitializeSpinLock(&pdx->PollLock);
  111. // Initialize queued read list
  112. InitializeListHead(&pdx->ReadIrpList);
  113. // Initialize fifo
  114. KeInitializeSpinLock(&pdx->FifoLock);
  115. pdx->FifoReadPointer = pdx->FifoWritePointer = 0;
  116. // Link our device object into the stack leading to the PDO
  117. pdx->LowerDeviceObject = IoAttachDeviceToDeviceStack(fdo, pdo);
  118. if(!pdx->LowerDeviceObject) {
  119. KdPrint((DRIVERNAME " - IoAttachDeviceToDeviceStack failed\n"));
  120. status = STATUS_DEVICE_REMOVED;
  121. break;
  122. }
  123. // allocate IRP for polling
  124. pdx->PollingIrp = IoAllocateIrp(pdx->LowerDeviceObject->StackSize, FALSE);
  125. if(!pdx->PollingIrp) {
  126. KdPrint((DRIVERNAME " - IoAllocateIrp failed\n"));
  127. status = STATUS_INSUFFICIENT_RESOURCES;
  128. break;
  129. }
  130. // Set power management flags in the device object
  131. fdo->Flags |= DO_POWER_PAGABLE;
  132. // Initialize to use the GENERIC.SYS library
  133. pdx->pgx = (PGENERIC_EXTENSION) ((PUCHAR) pdx + dxsize);
  134. GENERIC_INIT_STRUCT gis = {sizeof(GENERIC_INIT_STRUCT)};
  135. gis.DeviceObject = fdo;
  136. gis.Pdo = pdo;
  137. gis.Ldo = pdx->LowerDeviceObject;
  138. gis.RemoveLock = &pdx->RemoveLock;
  139. gis.StartDevice = StartDevice;
  140. gis.StopDevice = StopDevice;
  141. gis.RemoveDevice = RemoveDevice;
  142. gis.StartIo = StartIo;
  143. gis.DeviceQueue = &pdx->dqWrite;
  144. RtlInitUnicodeString(&gis.DebugName, LDRIVERNAME);
  145. gis.Flags = GENERIC_SURPRISE_REMOVAL_OK;
  146. status = InitializeGenericExtension(pdx->pgx, &gis);
  147. if(!NT_SUCCESS(status)) {
  148. KdPrint((DRIVERNAME " - InitializeGenericExtension failed - %X\n", status));
  149. break;
  150. }
  151. // Clear the "initializing" flag so that we can get IRPs
  152. fdo->Flags &= ~DO_DEVICE_INITIALIZING;
  153. // Set up recovery thread
  154. pdx->RecoveryExit = FALSE;
  155. KeInitializeEvent(&pdx->RecoveryEvent, SynchronizationEvent, FALSE);
  156. } while (FALSE);
  157. if(!NT_SUCCESS(status))
  158. {
  159. if(pdx->PollingIrp)
  160. {
  161. IoFreeIrp(pdx->PollingIrp);
  162. pdx->PollingIrp = NULL;
  163. }
  164. if(pdx->operationsInterfaceName.Buffer)
  165. {
  166. RtlFreeUnicodeString(&pdx->operationsInterfaceName);
  167. pdx->operationsInterfaceName.Buffer = NULL;
  168. }
  169. if(pdx->inquiriesInterfaceName.Buffer)
  170. {
  171. RtlFreeUnicodeString(&pdx->inquiriesInterfaceName);
  172. pdx->inquiriesInterfaceName.Buffer = NULL;
  173. }
  174. if(pdx->LowerDeviceObject)
  175. {
  176. IoDetachDevice(pdx->LowerDeviceObject);
  177. pdx->LowerDeviceObject = NULL;
  178. }
  179. IoDeleteDevice(fdo);
  180. }
  181. return status;
  182. }
  183. ///////////////////////////////////////////////////////////////////////////////
  184. // Pass-through dispatch routine for IRP_MJ_INTERNAL_DEVICE_CONTROL. This allows
  185. // an upper filter to talk to the device, should it want to.
  186. #pragma LOCKEDCODE
  187. NTSTATUS DispatchInternalControl(PDEVICE_OBJECT fdo, PIRP Irp)
  188. {
  189. PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
  190. NTSTATUS status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
  191. if(!NT_SUCCESS(status))
  192. return CompleteRequest(Irp, status, 0);
  193. IoSkipCurrentIrpStackLocation(Irp);
  194. status = IoCallDriver(pdx->LowerDeviceObject, Irp);
  195. IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
  196. return status;
  197. }
  198. ///////////////////////////////////////////////////////////////////////////////
  199. #pragma PAGEDCODE
  200. NTSTATUS DispatchPnp(PDEVICE_OBJECT fdo, PIRP Irp)
  201. {
  202. PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
  203. return GenericDispatchPnp(pdx->pgx, Irp);
  204. }
  205. ///////////////////////////////////////////////////////////////////////////////
  206. #pragma PAGEDCODE
  207. NTSTATUS DispatchPower(PDEVICE_OBJECT fdo, PIRP Irp)
  208. {
  209. PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
  210. return GenericDispatchPower(pdx->pgx, Irp);
  211. }
  212. ///////////////////////////////////////////////////////////////////////////////
  213. #pragma PAGEDCODE
  214. NTSTATUS DispatchWmi(PDEVICE_OBJECT fdo, PIRP Irp)
  215. {
  216. PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
  217. IoSkipCurrentIrpStackLocation(Irp);
  218. return IoCallDriver(pdx->LowerDeviceObject, Irp);
  219. }
  220. ///////////////////////////////////////////////////////////////////////////////
  221. #pragma PAGEDCODE
  222. VOID RemoveDevice(IN PDEVICE_OBJECT fdo)
  223. {
  224. PAGED_CODE();
  225. PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
  226. NTSTATUS status;
  227. KdPrint((DRIVERNAME " - Remove device...\n"));
  228. if(pdx->LowerDeviceObject)
  229. {
  230. IoDetachDevice(pdx->LowerDeviceObject);
  231. pdx->LowerDeviceObject = NULL;
  232. }
  233. if(pdx->devHash)
  234. {
  235. ExFreePool(pdx->devHash);
  236. pdx->devHash = NULL;
  237. }
  238. if(pdx->manufacturer.Buffer)
  239. {
  240. ExFreePool(pdx->manufacturer.Buffer);
  241. pdx->manufacturer.Buffer = NULL;
  242. }
  243. if(pdx->product.Buffer)
  244. {
  245. ExFreePool(pdx->product.Buffer);
  246. pdx->product.Buffer = NULL;
  247. }
  248. if(pdx->serialNumber.Buffer)
  249. {
  250. ExFreePool(pdx->serialNumber.Buffer);
  251. pdx->serialNumber.Buffer = NULL;
  252. }
  253. if(pdx->displayName.Buffer)
  254. {
  255. ExFreePool(pdx->displayName.Buffer);
  256. pdx->displayName.Buffer = NULL;
  257. }
  258. if(pdx->operationsInterfaceName.Buffer)
  259. {
  260. RtlFreeUnicodeString(&pdx->operationsInterfaceName);
  261. pdx->operationsInterfaceName.Buffer = NULL;
  262. }
  263. if(pdx->inquiriesInterfaceName.Buffer)
  264. {
  265. RtlFreeUnicodeString(&pdx->inquiriesInterfaceName);
  266. pdx->inquiriesInterfaceName.Buffer = NULL;
  267. }
  268. if(pdx->PollingIrp)
  269. {
  270. IoFreeIrp(pdx->PollingIrp);
  271. pdx->PollingIrp = NULL;
  272. }
  273. IoDeleteDevice(fdo);
  274. }