⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ul_wdpnp.c

📁 一个linux下rs485驱动程序的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*******************************************************************  uLan Communication - uL_DRV - multiplatform uLan driver  ul_wdpnp.c	- Windows WDM PnP events processing code  (C) Copyright 1996-2004 by Pavel Pisa - project originator        http://cmp.felk.cvut.cz/~pisa  (C) Copyright 1996-2004 PiKRON Ltd.        http://www.pikron.com  (C) Copyright 2002-2004 Petr Smolik    The uLan driver project can be used and distributed   in compliance with any of next licenses   - GPL - GNU Public License     See file COPYING for details.   - LGPL - Lesser GNU Public License   - MPL - Mozilla Public License   - and other licenses added by project originator  Code can be modified and re-distributed under any combination  of the above listed licenses. If contributor does not agree with  some of the licenses, he/she can delete appropriate line.  WARNING: if you delete all lines, you are not allowed to  distribute code or sources in any form. *******************************************************************///#include <initguid.h>////{3EF4F782-AF00-11d5-87B2-00D0595444D7}//DEFINE_GUID(GUID_ULAN_WDM_DRIVER1, // 0x3ef4f782, 0xaf00, 0x11d5, 0x87, 0xb2, 0x0, 0xd0, 0x59, 0x54, 0x44, 0xd7);VOID PrintState(PULAN_DEVICE_EXTENSION devExt);VOID PrintCapabilityInfo(PDEVICE_CAPABILITIES Capabilities);VOID RequestIncrement(PULAN_DEVICE_EXTENSION devExt);VOID RequestDecrement(PULAN_DEVICE_EXTENSION devExt);VOID WaitForStop(PULAN_DEVICE_EXTENSION devExt);VOID WaitForRemove(PULAN_DEVICE_EXTENSION devExt);VOID ClearQueues(PULAN_DEVICE_EXTENSION devExt){/*stub*/};VOID ProcessQueuedRequests(PULAN_DEVICE_EXTENSION devExt){/*stub*/};NTSTATUS StartDevice (IN PULAN_DEVICE_EXTENSION devExt,IN PIO_STACK_LOCATION IrpSp);NTSTATUS StartUSBDevice (IN PULAN_DEVICE_EXTENSION devExt,IN PIO_STACK_LOCATION IrpSp);NTSTATUS CanStopDevice(PULAN_DEVICE_EXTENSION devExt, PIRP Irp);NTSTATUS CanRemoveDevice(PULAN_DEVICE_EXTENSION devExt, PIRP Irp);static NTSTATUS PnpComplete (IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PVOID Context);static PSTR pnpMinorCodes[] = {    "IRP_MN_START_DEVICE",    "IRP_MN_QUERY_REMOVE_DEVICE",    "IRP_MN_REMOVE_DEVICE",    "IRP_MN_CANCEL_REMOVE_DEVICE",    "IRP_MN_STOP_DEVICE",    "IRP_MN_QUERY_STOP_DEVICE",    "IRP_MN_CANCEL_STOP_DEVICE",    "IRP_MN_QUERY_DEVICE_RELATIONS",    "IRP_MN_QUERY_INTERFACE",    "IRP_MN_QUERY_CAPABILITIES",    "IRP_MN_QUERY_RESOURCES",    "IRP_MN_QUERY_RESOURCE_REQUIREMENTS",    "IRP_MN_QUERY_DEVICE_TEXT",    "IRP_MN_FILTER_RESOURCE_REQUIREMENTS",    "***** FUNCTION 0x0e",    "IRP_MN_READ_CONFIG",    "IRP_MN_WRITE_CONFIG",    "IRP_MN_EJECT",    "IRP_MN_SET_LOCK",    "IRP_MN_QUERY_ID",    "IRP_MN_QUERY_PNP_DEVICE_STATE",    "IRP_MN_QUERY_BUS_INFORMATION",    "IRP_MN_DEVICE_USAGE_NOTIFICATION",    "IRP_MN_SURPRISE_REMOVAL",    "IRP_MN_QUERY_LEGACY_BUS_INFORMATION"};static PSTR SystemPowerStateString[] = {"PowerSystemUnspecified","PowerSystemWorking","PowerSystemSleeping1","PowerSystemSleeping2","PowerSystemSleeping3","PowerSystemHibernate","PowerSystemShutdown","PowerSystemMaximum"};static PSTR DevicePowerStateString[] = {"PowerDeviceUnspecified","PowerDeviceD0","PowerDeviceD1","PowerDeviceD2","PowerDeviceD3","PowerDeviceMaximum"};#if DBGVOID PrintResourceList(PCM_RESOURCE_LIST);VOID PrintConfig(PPCI_COMMON_CONFIG  configInfo);#endifint uLanInstanceCounter=0;///////////////////////////////////////////////////////////////////////////////////  AddDevice////      We are called at this entry point by the Plug and Play Manager//      to add a Functional Device Object for a Physical Device Object.//      Note that we may NOT access the device in this routine, as the//      Plug and Play Manager has not yet given us any hardware resoruces.//      We get these hardware resources via the IRP_MJ_PNP IRP with//      a minor function IRP_MN_START_DEVICE.//////  INPUTS:////      DriverObj - Address of our DRIVER_OBJECT.////  OUTPUTS:////      None.////  RETURNS:////      None.////  IRQL:////    This routine is called at IRQL_PASSIVE_LEVEL.////  NOTES://///////////////////////////////////////////////////////////////////////////////NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject,                      IN PDEVICE_OBJECT PhysicalDeviceObject){    PULAN_DEVICE_EXTENSION devExt;    PDEVICE_OBJECT  functionalDeviceObject;    UNICODE_STRING  devName;    UNICODE_STRING  linkName;    UNICODE_STRING  tempName;    NTSTATUS code = STATUS_SUCCESS;    LOG_FILEIO("uLan: AddDevice: entered for instance %d\n",uLanInstanceCounter);    LOG_FILEIO("uLan: AddDevice: PDO = 0x%0x\n", PhysicalDeviceObject);    // Only up to 10 instances are handled     if(uLanInstanceCounter>=10){      uLan_DbgPrint("uLan: Too many instances, no more added\n");      return(STATUS_UNSUCCESSFUL);    }    //    // Initialize the UNICODE device name.  This will be the "native NT" name    // for our device.    //    RtlInitUnicodeString(&tempName,NT_DEVICE_NAME);    code=MyAllocUnicodeString(&devName, &tempName, tempName.Length+4);    if(uLanInstanceCounter){      devName.Buffer[devName.Length/2]='0'+uLanInstanceCounter;      devName.Length+=2;    }    uLan_DbgPrint("uLan: Ready to Call IoCreateDevice for DevName=\"%ws\" Len=%d\n",                   devName.Buffer,devName.Length);    //    // Ask the I/O Manager to create the device object and    // device extension.  In PnP terms, this is the FUNCTIONAL    // Device Object (FDO) for the device.    //    code = IoCreateDevice(DriverObject,                          sizeof(ULAN_DEVICE_EXTENSION),                          &devName,                          FILE_DEVICE_UNKNOWN,                          0,                                 FALSE,                          &functionalDeviceObject);            if(!NT_SUCCESS(code))  {      if(devName.Buffer) ExFreePool(devName.Buffer);;      uLan_DbgPrint("uLan: IoCreateDevice failed. Dev=%ws Status = 0x%0x\n",		    devName.Buffer,code);      return(STATUS_UNSUCCESSFUL);    }        //    // Get a pointer to our device extension    //    devExt = (PULAN_DEVICE_EXTENSION)functionalDeviceObject->DeviceExtension;        LOG_FILEIO("uLan: AddDevice: FDO = 0x%0x\n", functionalDeviceObject);    //    // Zero out the device extension.  While not strictly necessary    // (the documentation says the device extension is zeroed) it's    // better to be safe.    //    RtlZeroMemory(devExt, sizeof(ULAN_DEVICE_EXTENSION));    //    // Save the device object pointer away for future reference    //    devExt->DeviceObject = functionalDeviceObject;    //    // Save the address of the physical device object away for future reference    //    devExt->PhysicalDeviceObject = PhysicalDeviceObject;    //    //  Clear the Device Initializing bit since the Device Object was created    //  outside of DriverEntry.    //    functionalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;    //    // Create a familiar name for this device, so that non-kernel mode    // programs can open the device.    //    // NOTE: WDM Drivers on Win98 MUST create this link in the     // \DosDevices directory.  \?? will NOT work.    //    RtlInitUnicodeString(&tempName,DOS_DEVICE_NAME);    code=MyAllocUnicodeString(&linkName, &tempName, tempName.Length+4);    if(uLanInstanceCounter){      linkName.Buffer[linkName.Length/2]='0'+uLanInstanceCounter;      linkName.Length+=2;    }        LOG_FILEIO("uLan: AddDevice: Dev=%ws Link=%ws\n",devName.Buffer,linkName.Buffer);    //    // IoCreateSymbolicLink IS a WDM function...    //    code = IoCreateSymbolicLink(&linkName, &devName);        if (!NT_SUCCESS(code))    {        uLan_DbgPrint("uLan: IoCreateSymbolicLink failed.  Status = 0x%x\n", code);        code = STATUS_UNSUCCESSFUL;        //        // Clean up the mess        //        IoDeleteDevice(functionalDeviceObject);        if(linkName.Buffer) ExFreePool(linkName.Buffer);        if(devName.Buffer) ExFreePool(devName.Buffer);;        //        // Indicate load failure to the I/O manager; driver image is deleted...        //        return(code);    }    devExt->link_name=linkName;    devExt->ntdev_name=devName;    //    // Ask the I/O Manager to use buffered I/O    //    functionalDeviceObject->Flags |= DO_BUFFERED_IO;    //    // Set up the "Remove Event" and "Stop Event".    //    // Note that we can't use an official "Remove Lock" here, because    // the Remove Lock related calls are not in WDM.    //    KeInitializeEvent(&devExt->RemoveEvent, NotificationEvent, FALSE);    // KeInitializeEvent(&devExt->StopEvent, NotificationEvent, TRUE);    //    // Init the count of in-progress I/O requests to zero.  We use this    // to keep track of when we can remove the device.    //    // devExt->OutstandingIO = 0;    //    // Internal device state flags, used for managing PnP state of device    //    // devExt->Started = FALSE;    // devExt->HoldNewRequests = TRUE;    // devExt->Removed = FALSE;    //    // Set initial state    //    devExt->State = STATE_NEVER_STARTED;    // Initial uLan state    ul_drv_new_init_state(devExt,2);    //    // Attach our FDO to the underlying PDO    //    devExt->DeviceToSendIrpsTo =                      IoAttachDeviceToDeviceStack(functionalDeviceObject,                                                 PhysicalDeviceObject);    //    // If that didn't work...    //    if (!devExt->DeviceToSendIrpsTo)    {        uLan_DbgPrint("uLan: IoAttachDeviceToDeviceStack failed to attach to Target Device");        //        // Clean up the mess        //        IoDeleteDevice(functionalDeviceObject);        //        // Indicate load failure to the I/O manager; driver image is deleted...        //        return(STATUS_UNSUCCESSFUL);    }        #ifdef UL_WITH_WIN_PWR    // this event is triggered when self-requested power irps complete    KeInitializeEvent(&devExt->SelfRequestedPowerIrpEvent, NotificationEvent, FALSE);    #endif /* UL_WITH_WIN_PWR */    // Successfully added device, prepare number for next instance    uLanInstanceCounter++;    uLan_DbgPrint("uLan: AddDevice: done\n");    return code;}///////////////////////////////////////////////////////////////////////////////////  DispatchPnp////    This is the dispatch entry point for IRP_MJ_PNP requests.  The//    driver processes these requets, based on the current state of//    the device.//////  INPUTS:////      DeviceObject - Address of the Functional DEVICE_OBJECT for our device.//  //      Irp - Address of the IRP representing the IRP_MJ_PNP request.////  OUTPUTS:////      None.////  RETURNS://////  IRQL:////    This routine is called at IRQL_PASSIVE_LEVEL.////  NOTES:////      There are several difficulties implementing Plug and Play.//      Perhaps the greatest difficulty is deciding precisely how you//      want your device to work, given the various requests the driver//      can receive and the states the device can be in.  In our driver,//      we've decided to implement the following policies:////      1) When a removal of the device is requested, we will reject//         any new IRPs we receive (completing them with an error//         status in the dispatch routine).  We will wait until all IRPs//         that are already present on the device's queue are complete//         and then allow the remove.////      2) When a stop of the device is requested, we'll queue any//         newly received IRPs, but not initiate them.  We will wait//         until any IRPs that are presently ACTIVE in progress on the//         device complete, and then allow the stop.////      3) When a SUPRISE removal of the device is indicated, we//         immediately cancel any requests that are queued, reject any//         newly arriving requests.////      Of course, the second complexity in implementing plug and play//      is getting the logic in your driver correct, so that it works//      as you intend. According to our experience, this is easier said//      than done./////////////////////////////////////////////////////////////////////////////////NTSTATUS DispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp){    PIO_STACK_LOCATION ioStackLocation;    NTSTATUS code = STATUS_SUCCESS;    PULAN_DEVICE_EXTENSION devExt;    KEVENT eventWaitLowerDrivers;    PDEVICE_OBJECT targetDevice;    uLan_DbgPrint("uLan: DispatchPnp: called\n");    //    // Get a pointer to our (FUNCTIONAL) device object's device    // extension.    //    devExt = (PULAN_DEVICE_EXTENSION)DeviceObject->DeviceExtension;    //    // Up the count of in-progress requests    //    RequestIncrement(devExt);    ioStackLocation = IoGetCurrentIrpStackLocation(Irp);    KeInitializeEvent(&eventWaitLowerDrivers, NotificationEvent, FALSE);    uLan_DbgPrint("uLan: DispatchPnp: Current state: ");    PrintState(devExt);    uLan_DbgPrint("uLan: DispatchPnp: MINOR 0x%0X\n",ioStackLocation->MinorFunction);    if(ioStackLocation->MinorFunction<=IRP_MN_SURPRISE_REMOVAL+1)      uLan_DbgPrint("uLan: DispatchPnp: *** PNP Minor Function is %s\n",                         pnpMinorCodes[ioStackLocation->MinorFunction]);    switch( devExt->State + ioStackLocation->MinorFunction ) {        //        // STATE:   STOPPED or NEVER_STARTED        // IRP_MN:  _START_DEVICE        //        // We're here if we've received an AddDevice() call, but we

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -