isousb.c
上传用户:leituo004
上传日期:2014-11-03
资源大小:159k
文件大小:12k
源码类别:

驱动编程

开发平台:

Visual C++

  1. /*++
  2. Copyright (c) 2000  Microsoft Corporation
  3. Module Name:
  4.     isousb.c
  5. Abstract:
  6.     Isoch USB device driver for Intel 82930 USB test board
  7. Main module
  8. Author:
  9. Environment:
  10.     kernel mode only
  11. Notes:
  12.     Copyright (c) 2000 Microsoft Corporation.  
  13.     All Rights Reserved.
  14. --*/
  15. #include "isousb.h"
  16. #include "isopnp.h"
  17. #include "isopwr.h"
  18. #include "isodev.h"
  19. #include "isowmi.h"
  20. #include "isousr.h"
  21. #include "isorwr.h"
  22. #include "isostrm.h"
  23. //
  24. // Globals
  25. //
  26. ULONG   DebugLevel = 1;
  27. GLOBALS Globals;
  28. NTSTATUS
  29. DriverEntry(
  30.     IN PDRIVER_OBJECT  DriverObject,
  31.     IN PUNICODE_STRING UniRegistryPath
  32.     );
  33. VOID
  34. IsoUsb_DriverUnload(
  35.     IN PDRIVER_OBJECT DriverObject
  36.     );
  37. NTSTATUS
  38. IsoUsb_AddDevice(
  39.     IN PDRIVER_OBJECT DriverObject,
  40.     IN PDEVICE_OBJECT PhysicalDeviceObject
  41.     );
  42. #ifdef PAGE_CODE
  43. #ifdef ALLOC_PRAGMA
  44. #pragma alloc_text(INIT, DriverEntry)
  45. #pragma alloc_text(PAGE, IsoUsb_DriverUnload)
  46. #pragma alloc_text(PAGE, IsoUsb_DispatchCreate)
  47. #pragma alloc_text(PAGE, IsoUsb_DispatchClose)
  48. #endif
  49. #endif
  50. NTSTATUS
  51. DriverEntry(
  52.     IN PDRIVER_OBJECT  DriverObject,
  53.     IN PUNICODE_STRING UniRegistryPath
  54.     )
  55. /*++ 
  56. Routine Description:
  57.     Installable driver initialization entry point.
  58.     This entry point is called directly by the I/O system.    
  59. Arguments:
  60.     
  61.     DriverObject - pointer to driver object 
  62.     RegistryPath - pointer to a unicode string representing the path to driver 
  63.                    specific key in the registry.
  64. Return Values:
  65.     NT status value
  66.     
  67. --*/
  68. {
  69.     NTSTATUS        ntStatus;
  70.     PUNICODE_STRING registryPath;
  71.     
  72.     //
  73.     // initialization of variables
  74.     //
  75.     registryPath = &Globals.IsoUsb_RegistryPath;
  76.     //
  77.     // Allocate pool to hold a null-terminated copy of the path.
  78.     // Safe in paged pool since all registry routines execute at
  79.     // PASSIVE_LEVEL.
  80.     //
  81.     registryPath->MaximumLength = UniRegistryPath->Length + sizeof(UNICODE_NULL);
  82.     registryPath->Length        = UniRegistryPath->Length;
  83.     registryPath->Buffer        = ExAllocatePool(PagedPool,
  84.                                                  registryPath->MaximumLength);
  85.     if (!registryPath->Buffer) {
  86.         IsoUsb_DbgPrint(1, ("Failed to allocate memory for registryPathn"));
  87.         ntStatus = STATUS_INSUFFICIENT_RESOURCES;
  88.         goto DriverEntry_Exit;
  89.     } 
  90.     RtlZeroMemory (registryPath->Buffer, 
  91.                    registryPath->MaximumLength);
  92.     RtlMoveMemory (registryPath->Buffer, 
  93.                    UniRegistryPath->Buffer, 
  94.                    UniRegistryPath->Length);
  95.     ntStatus = STATUS_SUCCESS;
  96.     //
  97.     // Initialize the driver object with this driver's entry points.
  98.     //
  99.     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IsoUsb_DispatchDevCtrl;
  100.     DriverObject->MajorFunction[IRP_MJ_POWER]          = IsoUsb_DispatchPower;
  101.     DriverObject->MajorFunction[IRP_MJ_PNP]            = IsoUsb_DispatchPnP;
  102.     DriverObject->MajorFunction[IRP_MJ_CREATE]         = IsoUsb_DispatchCreate;
  103.     DriverObject->MajorFunction[IRP_MJ_CLOSE]          = IsoUsb_DispatchClose;
  104.     DriverObject->MajorFunction[IRP_MJ_CLEANUP]        = IsoUsb_DispatchClean;
  105.     DriverObject->MajorFunction[IRP_MJ_READ]           =
  106.     DriverObject->MajorFunction[IRP_MJ_WRITE]          = IsoUsb_DispatchReadWrite;
  107.     DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = IsoUsb_DispatchSysCtrl;
  108.     DriverObject->DriverUnload                         = IsoUsb_DriverUnload;
  109.     DriverObject->DriverExtension->AddDevice           = (PDRIVER_ADD_DEVICE)
  110.                                                          IsoUsb_AddDevice;
  111. DriverEntry_Exit:
  112.     return ntStatus;
  113. }
  114. VOID
  115. IsoUsb_DriverUnload(
  116.     IN PDRIVER_OBJECT DriverObject
  117.     )
  118. /*++
  119. Description:
  120.     This function will free the memory allocations in DriverEntry.
  121. Arguments:
  122.     DriverObject - pointer to driver object 
  123. Return:
  124.     None
  125. --*/
  126. {
  127.     PUNICODE_STRING registryPath;
  128.     IsoUsb_DbgPrint(3, ("IsoUsb_DriverUnload - beginsn"));
  129.     registryPath = &Globals.IsoUsb_RegistryPath;
  130.     if(registryPath->Buffer) {
  131.         ExFreePool(registryPath->Buffer);
  132.         registryPath->Buffer = NULL;
  133.     }
  134.     IsoUsb_DbgPrint(3, ("IsoUsb_DriverUnload - endsn"));
  135.     return;
  136. }
  137. NTSTATUS
  138. IsoUsb_AddDevice(
  139.     IN PDRIVER_OBJECT DriverObject,
  140.     IN PDEVICE_OBJECT PhysicalDeviceObject
  141.     )
  142. /*++
  143. Description:
  144. Arguments:
  145.     DriverObject - Store the pointer to the object representing us.
  146.     PhysicalDeviceObject - Pointer to the device object created by the
  147.                            undelying bus driver.
  148. Return:
  149.     STATUS_SUCCESS - if successful STATUS_UNSUCCESSFUL - otherwise
  150. --*/
  151. {
  152.     NTSTATUS          ntStatus;
  153.     PDEVICE_OBJECT    deviceObject;
  154.     PDEVICE_EXTENSION deviceExtension;
  155.     POWER_STATE       state;
  156.     KIRQL             oldIrql;
  157.     IsoUsb_DbgPrint(3, ("IsoUsb_AddDevice - beginsn"));
  158.     deviceObject = NULL;
  159.     ntStatus = IoCreateDevice(
  160.                     DriverObject,                   // our driver object
  161.                     sizeof(DEVICE_EXTENSION),       // extension size for us
  162.                     NULL,                           // name for this device
  163.                     FILE_DEVICE_UNKNOWN,
  164.                     FILE_AUTOGENERATED_DEVICE_NAME, // device characteristics
  165.                     FALSE,                          // Not exclusive
  166.                     &deviceObject);                 // Our device object
  167.     if(!NT_SUCCESS(ntStatus)) {
  168.         //
  169.         // returning failure here prevents the entire stack from functioning,
  170.         // but most likely the rest of the stack will not be able to create
  171.         // device objects either, so it is still OK.
  172.         //                
  173.         IsoUsb_DbgPrint(1, ("Failed to create device objectn"));
  174.         return ntStatus;
  175.     }
  176.     //
  177.     // Initialize the device extension
  178.     //
  179.     deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension;
  180.     deviceExtension->FunctionalDeviceObject = deviceObject;
  181.     deviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
  182.     deviceObject->Flags |= DO_DIRECT_IO;
  183.     //
  184.     // initialize the device state lock and set the device state
  185.     //
  186.     KeInitializeSpinLock(&deviceExtension->DevStateLock);
  187.     INITIALIZE_PNP_STATE(deviceExtension);
  188.     //
  189.     //initialize OpenHandleCount
  190.     //
  191.     deviceExtension->OpenHandleCount = 0;
  192.     //
  193.     // Initialize the selective suspend variables
  194.     //
  195.     KeInitializeSpinLock(&deviceExtension->IdleReqStateLock);
  196.     deviceExtension->IdleReqPend = 0;
  197.     deviceExtension->PendingIdleIrp = NULL;
  198.     //
  199.     // Hold requests until the device is started
  200.     //
  201.     deviceExtension->QueueState = HoldRequests;
  202.     //
  203.     // Initialize the queue and the queue spin lock
  204.     //
  205.     InitializeListHead(&deviceExtension->NewRequestsQueue);
  206.     KeInitializeSpinLock(&deviceExtension->QueueLock);
  207.     //
  208.     // Initialize the remove event to not-signaled.
  209.     //
  210.     KeInitializeEvent(&deviceExtension->RemoveEvent, 
  211.                       SynchronizationEvent, 
  212.                       FALSE);
  213.     //
  214.     // Initialize the stop event to signaled.
  215.     // This event is signaled when the OutstandingIO becomes 1
  216.     //
  217.     KeInitializeEvent(&deviceExtension->StopEvent, 
  218.                       SynchronizationEvent, 
  219.                       TRUE);
  220.     //
  221.     // OutstandingIo count biased to 1.
  222.     // Transition to 0 during remove device means IO is finished.
  223.     // Transition to 1 means the device can be stopped
  224.     //
  225.     deviceExtension->OutStandingIO = 1;
  226.     KeInitializeSpinLock(&deviceExtension->IOCountLock);
  227.     //
  228.     // Delegating to WMILIB
  229.     //
  230.     ntStatus = IsoUsb_WmiRegistration(deviceExtension);
  231.     if(!NT_SUCCESS(ntStatus)) {
  232.         IsoUsb_DbgPrint(1, ("IsoUsb_WmiRegistration failed with %Xn", ntStatus));
  233.         IoDeleteDevice(deviceObject);
  234.         return ntStatus;
  235.     }
  236.     //
  237.     // set the flags as underlying PDO
  238.     //
  239.     if(PhysicalDeviceObject->Flags & DO_POWER_PAGABLE) {
  240.         deviceObject->Flags |= DO_POWER_PAGABLE;
  241.     }
  242.     //
  243.     // Typically, the function driver for a device is its 
  244.     // power policy owner, although for some devices another 
  245.     // driver or system component may assume this role. 
  246.     // Set the initial power state of the device, if known, by calling 
  247.     // PoSetPowerState.
  248.     // 
  249.     deviceExtension->DevPower = PowerDeviceD0;
  250.     deviceExtension->SysPower = PowerSystemWorking;
  251.     state.DeviceState = PowerDeviceD0;
  252.     PoSetPowerState(deviceObject, DevicePowerState, state);
  253.     //
  254.     // attach our driver to device stack
  255.     // The return value of IoAttachDeviceToDeviceStack is the top of the
  256.     // attachment chain.  This is where all the IRPs should be routed.
  257.     //
  258.     deviceExtension->TopOfStackDeviceObject = 
  259.                 IoAttachDeviceToDeviceStack(deviceObject,
  260.                                             PhysicalDeviceObject);
  261.     if(NULL == deviceExtension->TopOfStackDeviceObject) {
  262.         IsoUsb_WmiDeRegistration(deviceExtension);
  263.         IoDeleteDevice(deviceObject);
  264.         return STATUS_NO_SUCH_DEVICE;
  265.     }
  266.         
  267.     //
  268.     // Register device interfaces
  269.     //
  270.     ntStatus = IoRegisterDeviceInterface(deviceExtension->PhysicalDeviceObject, 
  271.                                          &GUID_CLASS_I82930_ISO, 
  272.                                          NULL, 
  273.                                          &deviceExtension->InterfaceName);
  274.     if(!NT_SUCCESS(ntStatus)) {
  275.         IsoUsb_WmiDeRegistration(deviceExtension);
  276.         IoDetachDevice(deviceExtension->TopOfStackDeviceObject);
  277.         IoDeleteDevice(deviceObject);
  278.         return ntStatus;
  279.     }
  280.     if(IoIsWdmVersionAvailable(1, 0x20)) {
  281.         deviceExtension->WdmVersion = WinXpOrBetter;
  282.     }
  283.     else if(IoIsWdmVersionAvailable(1, 0x10)) {
  284.         deviceExtension->WdmVersion = Win2kOrBetter;
  285.     }
  286.     else if(IoIsWdmVersionAvailable(1, 0x5)) {
  287.         deviceExtension->WdmVersion = WinMeOrBetter;
  288.     }
  289.     else if(IoIsWdmVersionAvailable(1, 0x0)) {
  290.         deviceExtension->WdmVersion = Win98OrBetter;
  291.     }
  292.     deviceExtension->SSRegistryEnable = 0;
  293.     deviceExtension->SSEnable = 0;
  294.     //
  295.     // Win XP only
  296.     // check the registry flag -
  297.     // whether the device should selectively
  298.     // suspend when idle
  299.     //
  300.     if(WinXpOrBetter == deviceExtension->WdmVersion) {
  301.         IsoUsb_GetRegistryDword(ISOUSB_REGISTRY_PARAMETERS_PATH,
  302.                                  L"IsoUsbEnable",
  303.                                  &deviceExtension->SSRegistryEnable);
  304.         if(deviceExtension->SSRegistryEnable) {
  305.             //
  306.             // initialize DPC
  307.             //
  308.             KeInitializeDpc(&deviceExtension->DeferredProcCall, 
  309.                             DpcRoutine, 
  310.                             deviceObject);
  311.             //
  312.             // initialize timer
  313.             // the DPC and the timer in conjunction, 
  314.             // monitor the state of the device to 
  315.             // selectively suspend the device.
  316.             //
  317.             KeInitializeTimerEx(&deviceExtension->Timer,
  318.                                 NotificationTimer);
  319.             //
  320.             // Initialize the NoDpcWorkItemPendingEvent to signaled state.
  321.             // This event is cleared when a Dpc is fired and signaled
  322.             // on completion of the work-item.
  323.             //
  324.             KeInitializeEvent(&deviceExtension->NoDpcWorkItemPendingEvent, 
  325.                               NotificationEvent, 
  326.                               TRUE);
  327.             //
  328.             // Initialize the NoIdleReqPendEvent to ensure that the idle request
  329.             // is indeed complete before we unload the drivers.
  330.             //
  331.             KeInitializeEvent(&deviceExtension->NoIdleReqPendEvent,
  332.                               NotificationEvent,
  333.                               TRUE);
  334.         }
  335.     }
  336.     //
  337.     // Clear the DO_DEVICE_INITIALIZING flag.
  338.     // Note: Do not clear this flag until the driver has set the
  339.     // device power state and the power DO flags. 
  340.     //
  341.     deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
  342.     IsoUsb_DbgPrint(3, ("IsoUsb_AddDevice - endsn"));
  343.     return ntStatus;
  344. }