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

📄 driverpn.c

📁 profibus-dp主站源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
//-----------------------------------------------------------------------------
// $Id: driverpnp.c,v 1.0.0                                         2004/01/13
//-----------------------------------------------------------------------------
//
//      ProfiM - PROFIBUS MASTER DRIVER FOR WINDOWS NT/2000
//
// Author:  
//      Pavel Trnka, CTU FEE
//      trnkap@seznam.cz
// With help and advices from:
//      Ing. Petr Smolik, CTU FEE
//      Ing. Pavel Pisa, CTU FEE
//      Ing. Pavel Burget, CTU FEE
//
//-----------------------------------------------------------------------------
//
// Popis:
// ------
//   Cast ovladace pro preklad s podporou PnP. Do projektu je vkladana pokud
// je nadefinovano falesne makro PnP (vardef.h).
//   Zajistuje start ovladace (DriverEntry), ziskani hardwarovych prostredku
// (AddDevice), zpracovavani PnP zprav (DispatchPnP) a vsechny potrebne funkce
// pro zajisteni PnP kompatibilitu ovladace.
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

#include "DriverPnP.h"



///////////////////////////////////////////////////////////////////////////////
//
// Unicode String Manipulation routine
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS MyAllocUnicodeString( PUNICODE_STRING UStr,
                               PUNICODE_STRING InUStr,
                               USHORT Len )
{
  NTSTATUS  Status;
  ULONG     Size;
  if ( !Len && InUStr )
  {
    Len = InUStr->Length;
  }
  RtlInitUnicodeString( UStr, NULL );
  if ( Len )
  {
    Size = Len + 2;
    UStr->Buffer = ExAllocatePool( PagedPool, Size );
    if ( !UStr->Buffer )
      return STATUS_UNSUCCESSFUL;
    RtlZeroMemory( UStr->Buffer, Size );
    UStr->MaximumLength = Len;
    if ( InUStr )
      RtlCopyUnicodeString( UStr, InUStr );
  }
  return STATUS_SUCCESS;
}



///////////////////////////////////////////////////////////////////////////////
//
//  GetRegistryDWord
//
//    Reads a registry key value from an already opened registry key
//
//  INPUTS:
//  Handle    - handle to the opened registry key
//  KeyNameString - WCHAR string to the desired key
//  OUTPUTS:
//  Data    - buffer for the data

//
//  RETURNS:
//  NT Status code
//
//  IRQL:
//  IRQL PASSIVE_LEVEL
//
///////////////////////////////////////////////////////////////////////////////
BOOLEAN
GetRegistryDWord (
    IN HANDLE Handle,
    IN PWCHAR KeyNameString,
    IN PULONG Data
    )
{
  UNICODE_STRING   keyName;
  ULONG            length;
  PKEY_VALUE_FULL_INFORMATION fullInfo;
  NTSTATUS         status = STATUS_INSUFFICIENT_RESOURCES;
  ULONG            DataLength=4;

  RtlInitUnicodeString (&keyName, KeyNameString);

  length = sizeof(KEY_VALUE_FULL_INFORMATION)+keyName.Length+4+DataLength;
  fullInfo = ExAllocatePool(PagedPool, length); 

  if (fullInfo) 
  {
    status = ZwQueryValueKey (Handle,&keyName,KeyValueFullInformation,
        fullInfo,length,&length);
  
    if (NT_SUCCESS(status)) 
    {
      // If there is enough room in the data buffer, copy the output
      if ( DataLength >= fullInfo->DataLength ) 
      {
        RtlCopyMemory (Data,((PUCHAR) fullInfo) + fullInfo->DataOffset, 
           fullInfo->DataLength);
        ExFreePool(fullInfo);           
        return TRUE;
      }
    }
    
    ExFreePool(fullInfo);
  }

  return FALSE;
}



///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//
//                             PCI routines
//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////                                

                               

#define PCI_ANY_ID 0xffff
typedef struct pci_device_id {
  USHORT vendor;
  USHORT device;
  USHORT subvendor;
  USHORT subdevice;
  USHORT class_val,clask_mask;
  ULONG  driver_data;
} pci_device_id_t;

//-----------------------------------------------------------------------------


static struct pci_device_id pb_pci_tbl[] /*__devinitdata*/ = {
  /* Advantech PCI-1602A, negated DTR */
  { /* PCI_VENDOR_ID */ 0x13fe, /* PCI_DEVICE_ID */ 0x1600,
    /* PCI_VENDOR_ID */ PCI_ANY_ID, /* PCI_SUBDEVICE_ID */ PCI_ANY_ID,
    0, 0, 0x16954000|U950PCI_CHOPT_TXDTRNEG|U950PCI_CHOPT_HSPDOSC},
  /* Tedia PCI-1482 */
  { /* PCI_VENDOR_ID */ 0x1415, /* PCI_DEVICE_ID */ 0x950A,
    /* PCI_VENDOR_ID */ PCI_ANY_ID, /* PCI_SUBDEVICE_ID */ PCI_ANY_ID,
    0, 0, 0x16954000|U950PCI_CHOPT_RXDONRI|U950PCI_CHOPT_HSPDOSC},
  /* Tedia PCI-1482 with PiKRON signature */
  { /* PCI_VENDOR_ID */ 0x1760, /* PCI_DEVICE_ID */ 0x8004,
    /* PCI_VENDOR_ID */ PCI_ANY_ID, /* PCI_SUBDEVICE_ID */ PCI_ANY_ID,
    0, 0, 0x16954000|U950PCI_CHOPT_RXDONRI},
  { 0, } /* terminate list */
};

//-----------------------------------------------------------------------------

BOOLEAN FindPciHWID(PWCHAR HWID,
        OUT pci_device_id_t **Ppci_device_id
             )
{
  PWCHAR pwcH, pwcM;
  WCHAR  fldName;
  USHORT vendorID=0;
  USHORT deviceID=0;
  USHORT subvendorID=0;
  USHORT subdeviceID=0;
  ULONG  val, i, c;
  static WCHAR PciHWIDMask[]=L"PCI\\VEN_vvvv&DEV_xxxx&SUBSYS_sssswwww";
  pci_device_id_t *device_id;

  *Ppci_device_id=NULL;
  if(HWID==NULL) return FALSE;

  pwcH=HWID;
  pwcM=PciHWIDMask;
  while(*pwcH&&*pwcM) {
    if(*pwcH==*pwcM){
      pwcH++; pwcM++;
      continue;
    }
    fldName=*pwcM;
    if((fldName!='v')&&(fldName!='x')&&
       (fldName!='s')&&(fldName!='w')) break;
    val=0;
    for(i=4;i--;){
      c=*(pwcH++); pwcM++;
      if(c<='9') c-='0';
      else if(c<='F') c=c-'A'+10;
      else if(c<='f') c=c-'a'+10;
      if(c>15) {val=0;break;}
      val<<=4;
      val+=c;
    }
    switch (fldName) {
      case 'v':
        vendorID=(USHORT)val;
  break;
      case 'x':
        deviceID=(USHORT)val;
  break;
      case 'w':
        subvendorID=(USHORT)val;
  break;
      case 's':
        subdeviceID=(USHORT)val;
  break;
    }
  }
#if DBG
  DbgPrint("PB: Ven %04X Dev %04X SubVen %04X SubDev %04X\n", 
                 vendorID,deviceID,subvendorID,subdeviceID);
#endif

  for(device_id=pb_pci_tbl;device_id->vendor;device_id++){
    if((device_id->vendor!=PCI_ANY_ID)&&(device_id->vendor!=vendorID)) continue;
    if((device_id->device!=PCI_ANY_ID)&&(device_id->device!=deviceID)) continue;
    if((device_id->subvendor!=PCI_ANY_ID)&&(device_id->vendor!=subvendorID)) continue;
    if((device_id->subdevice!=PCI_ANY_ID)&&(device_id->device!=subdeviceID)) continue;
    *Ppci_device_id=device_id;
    return TRUE;
  }

  return FALSE;
}


///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////



///////////////////////////////////////////////////////////////////////////////
//
//  DriverEntry
//
//      This routine is called when the driver is first loaded.  
//
//  INPUTS:
//
//      DriverObj - Address of the DRIVER_OBJECT created by NT for this driver.
//
//      RegistryPath - UNICODE_STRING which represents this drivers KEY in the
//                   Registry.  
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//      STATUS_SUCCESS. Otherwise an error indicating why the driver could not
//                    Load.
//
//  IRQL:
//
//    This routine is called at IRQL_PASSIVE_LEVEL.
//
//  NOTES:
//
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS DriverEntry( PDRIVER_OBJECT DriverObj, PUNICODE_STRING RegistryPath )
{
  DbgPrint( "ProfiM PnP: Enter the driver!\n" );
  DbgPrint( "ProfiM PnP: Version 0.025 with PnP support (%s  %s)\n", 
            __TIME__, 
            __DATE__ );
  DbgPrint( "ProfiM PnP: Umisteni v registrech: \"%ws\" ",
            RegistryPath->Buffer );


  //
  // Establish dispatch entry points for the functions we support
  //
  DriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchRoutine;
  DriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchRoutine;
  DriverObj->MajorFunction[IRP_MJ_READ] = DispatchRoutine;
  DriverObj->MajorFunction[IRP_MJ_WRITE] = DispatchRoutine;
  DriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchRoutine;
  DriverObj->MajorFunction[IRP_MJ_CLEANUP] = DispatchRoutine;

  //
  // PnP and Power entry points
  //
  DriverObj->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
  /// DriverObj->MajorFunction[IRP_MJ_POWER]          =  DispatchPower;

  //
  // WMI entry point
  //
  DriverObj->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = DispatchSystemControl;

  //
  // AddDevice Function
  //
  DriverObj->DriverExtension->AddDevice = AddDevice;

  //
  // Unload function
  //
  DriverObj->DriverUnload = UnloadDriver;

  //
  // Save the registry path for later use.
  //
  MyAllocUnicodeString( &PB_RegistryPath, RegistryPath, 0 );



  //
  // Initial reasonable value for driver spinlock
  //
  //**    uL_SpinLock_Irql=DISPATCH_LEVEL+1;


  DbgPrint( "ProfiM PnP: All initialized!\n" );

  return( STATUS_SUCCESS );
}

///////////////////////////////////////////////////////////////////////////////
//
//  DriverUnload
//
//      This routine is our dynamic unload entry point.  We are called here when
//    the OS wants to unload our driver.  It is our responsibility to release any
//    resources we allocated.
//
//  INPUTS:
//
//      DriverObj - Address of our DRIVER_OBJECT.
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//      None.
//
//  IRQL:
//
//    This routine is called at IRQL_PASSIVE_LEVEL.
//
//  NOTES:
//
//    No doubt we pool leak at this entry point by not properly returning everything.
//
///////////////////////////////////////////////////////////////////////////////
VOID UnloadDriver( PDRIVER_OBJECT DriverObject )
{
  PPROFIM_DEVICE_EXTENSION      devExt;
  PDEVICE_OBJECT                devObj, nextDevObj;
  IO_RESOURCE_REQUIREMENTS_LIST reqList;
  NTSTATUS                      code;
  UNICODE_STRING                linkName;
  CM_RESOURCE_LIST              returnResources;
  BOOLEAN                       conflictDetected;

  DbgPrint( "ProfiM PnP: DriverUnload\n" );

  //
  // For THIS driver, there will only ever be a single device object.
  // Because of this, we just get it from the DriverObj.  If this were
  // a multiple device driver, we would do this in a while loop...
  //
  nextDevObj = DriverObject->DeviceObject;
  while ( nextDevObj )
  {
    devObj = nextDevObj;
    nextDevObj = devObj->NextDevice;

    // Find ProfiM Device Extension
    devExt = ( PPROFIM_DEVICE_EXTENSION ) devObj->DeviceExtension;

    if ( !devExt )
    {
      DbgPrint( "PnP: UnloadDriver Error - DeviceExtension is NULL!" );
      return;
    }        
    if ( devExt->magic != PROFIM_MAGIC )
    {
      DbgPrint( "PnP: UnloadDriver Error - Device Extension MAGIC is invalid!" );
      return;
    }      

    // Set State
    devExt->State = STATE_REMOVED;

    // Return ProfiM system resources
    ReturnResources( devExt );

    // Destroy DeviceObject
    RemoveDevice( devObj );
  }

  if ( PB_RegistryPath.Buffer )
    ExFreePool( PB_RegistryPath.Buffer );
}









VOID  PrintState( PPROFIM_DEVICE_EXTENSION devExt );
VOID  RequestIncrement( PPROFIM_DEVICE_EXTENSION devExt );
VOID  RequestDecrement( PPROFIM_DEVICE_EXTENSION devExt );
VOID  WaitForStop( PPROFIM_DEVICE_EXTENSION devExt );
VOID  WaitForRemove( PPROFIM_DEVICE_EXTENSION devExt );
VOID ClearQueues( PPROFIM_DEVICE_EXTENSION devExt )
{
  /*stub*/
};
VOID ProcessQueuedRequests( PPROFIM_DEVICE_EXTENSION devExt )

⌨️ 快捷键说明

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