Windows NT Device Driver Toolkits by Patrick Tennberg Listing One // Getting, claiming, and using resources with WinDK. // Get the resources from the registry CRegistry *pRegistry = new CRegistry(m_DriverRegPath); pRegistry->SetRelativePath(Concatenate(pDeviceName,L"\\Parameters")); pRegistry->GetKey(L"PortBase",&m_PortBase); pRegistry->GetKey(L"PortRange",&m_PortRange); pRegistry->GetKey(L"Irq",&m_Irq); delete pRegistry; BOOLEAN fConflict; CResource *pResources = new CResource(ISA,0,this,2); pResources->AddPortResource(m_MappedAddress); pResources->AddInterruptResource(m_Interrupt); pResources->AssignCardsResources(m_DriverRegPath,&conflict); delete pResources; // Accessing the I/O ports using WinDK WINDK_MAPPED_ADDRESS m_MappedAddress // map the device ports m_MappedAddress.Length = m_PortRange; m_MappedAddress.PortType = PORT_MAPPED; m_MappedAddress.UnmappedAddress.LowPart = m_PortBase; m_MappedAddress.UnmappedAddress.HighPart = 0; m_MappedAddress.Flags = CmResourceShareDeviceExclusive; // map I/O address status = MapIoAddress(Isa, busNumber, m_MappedAddress); // Write to port WRITE_PORT_UCHAR((PUCHAR)(m_MappedAddress.pAddress+RESET_ALL),0); // Map an interrupt WINDK_INTERRUPT_RESOURCE m_Interrupt; // Setup an interrupt with WinDK m_Interrupt.Level = m_Irq; m_Interrupt.Vector = m_Irq; m_Interrupt.Affinity = 0; m_Interrupt.Flags = CmResourceShareDeviceExclusive; m_Interrupt.Mode = Latched; // DpcForIsr and Isr is static functions they can however use member functions InitializeInterrupt( ISA, 0, reinterpret_cast(DpcForIsr), reinterpret_cast(Isr), this, m_Interrupt );// Claming resources with WinDK // The resources are automatically released in the destructor // Unmap the I/O address UnmapIoAddress(m_MappedAddress); Listing Two // Getting, claiming, and using resources with DriverWorks. Using the registry // with Driver::Works. Driver::Works has it's own way of defining devices in // the registry. The advantage of using there model is that // you can use the KConfigurationQuery class and CreateRegistryPath m_RegPath = KDevice::CreateRegistryPath(L"MyDevice",m_Unit); KRegistryKey unitKey(*m_RegPath); if (NT_SUCCESS(unitKey.LastError())) { unitKey.QueryValue(L"PortBase", &m_PortBase); unitKey.QueryValue(L"PortRange", &m_PortRange); unitKey.QueryValue(L"Irq", &m_Irq); } // Claming resources with Driver::Works KResourceRequest resReq(Isa,0,0); resReq.AddPort(m_PortBase, m_PortBase, m_PortRange, 2, 0, CmResourceShareDeviceExclusive); resReq.AddIrq(m_Irq,m_Irq); resReq.Submit(this,m_DriverRegPath); // Accessing the I/O ports using Driver::Works KIoRange m_Ports; // BusType, Offset, I/O port base, I/O port range fStatus = m_Ports.Initialize(Isa,0,m_PortBase,m_PortRange); // Write to the port m_Ports.outb(RESET_ALL,0); // Map an interrupt with Driver::Works KInterrupt m_Interrupt; // Setup the interrupt m_Interrupt.Initialize(Isa,0,m_Irq,m_Irq,Latched,FALSE,FALSE); // The Isr can be a member of the device class, it can also be an static // member function to avoid the overhead of an extra function call. m_Interrupt.Connect(LinkTo(Isr),this); // Initialize a DPC object which may be queued by interrupt service routine InitializeDpcForIsr(LinkTo(DpcForIsr)); // Release claimed resources KResourceRequest resReq(Isa,0,0); resReq.Release(this,m_DriverRegPath); // The destructor unmaps the memory automatically 2