void HERMESFreeResources(PHERMEScontext pCtx) { CM_RESOURCE_LIST NullResourceList; BOOLEAN ResourceConflict; #ifdef DEBUG DEBUG1("[HERMESFreeResources]\n"); #endif if (pCtx->InterruptObject) IoDisconnectInterrupt(pCtx->InterruptObject); pCtx->InterruptObject= NULL; // // Deallocate the resources. // RtlZeroMemory((PVOID)&NullResourceList, sizeof(NullResourceList)); IoReportResourceUsage(NULL, pCtx->DriverObject, &NullResourceList, sizeof(ULONG), NULL, NULL, 0, FALSE, &ResourceConflict); }
VOID SoundFreeDevice( IN PDEVICE_OBJECT DeviceObject ) /*++ Routine Description : Free the all resources related to this device : The device object itself Any declared hardware resources (via IoReportResourceUsage) Any symbolic link related to this device Arguments : DeviceObject - the device to free Return Value : None --*/ { CM_RESOURCE_LIST NullResourceList; BOOLEAN ResourceConflict; // // Free the device if any // if (DeviceObject != NULL) { // // Undeclare any resources used by the device // (delete anything the driver has at the same time!) // NullResourceList.Count = 0; IoReportResourceUsage(NULL, DeviceObject->DriverObject, &NullResourceList, sizeof(ULONG), DeviceObject, &NullResourceList, sizeof(ULONG), FALSE, &ResourceConflict); // // Remove the device's symbolic link // { PLOCAL_DEVICE_INFO pLDI; UNICODE_STRING DeviceName; NTSTATUS Status; pLDI = DeviceObject->DeviceExtension; Status = SoundCreateDeviceName( L"\\DosDevices\\", pLDI->DeviceInit->PrototypeName + wcslen(L"\\Device\\"), pLDI->DeviceNumber, &DeviceName); if (NT_SUCCESS(Status)) { IoDeleteSymbolicLink(&DeviceName); ExFreePool(DeviceName.Buffer); } } // // Delete the device object // IoDeleteDevice(DeviceObject); } }
NTSTATUS SoundReportResourceUsage( IN PDEVICE_OBJECT DeviceObject, IN INTERFACE_TYPE BusType, IN ULONG BusNumber, IN PULONG InterruptNumber OPTIONAL, IN KINTERRUPT_MODE InterruptMode, IN BOOLEAN InterruptShareDisposition, IN PULONG DmaChannel OPTIONAL, IN PULONG FirstIoPort OPTIONAL, IN ULONG IoPortLength ) /*++ Routine Description : Calls IoReportResourceUsage for the device and resources passed in. NOTE that this supercedes previous resources declared for this device. It is assumed that all resources owned by the device cannot be shared, except for level-sensitive interrupts which can be shared. Arguments : DeviceObject - The device which 'owns' the resources This can also be a pointer to a driver object BusType - The type of bus on which the device lives BusNumber - The bus number (of type BusType) where the device is InterruptNumber - The interrupt the devices uses (if any) DmaChannel - The DMA channel the device uses FirstIoPort - The start Io port for the device IoPortLength - The number of bytes of IO space the device uses (starting at FirstIoPort) Return Value : STATUS_SUCCESS if no problems The return from IoReportResourceUsage if this fails STATUS_DEVICE_CONFIGURATION_ERROR is IoReportResourceUsage reports a conflict --*/ { NTSTATUS Status; // // Our resource list to report back to the system // /* Compiler rejects this UCHAR ResBuffer[FIELD_OFFSET( CM_RESOURCE_LIST, List[0].PartialResourceList.PartialDescriptors[3].Type)]; */ UCHAR ResBuffer[3 * sizeof(CM_RESOURCE_LIST)]; BOOLEAN ResourceConflict; PCM_RESOURCE_LIST ResourceList; PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor; ResourceList = (PCM_RESOURCE_LIST)ResBuffer; Descriptor = ResourceList->List[0].PartialResourceList.PartialDescriptors; ResourceConflict = FALSE; // // Zero out any unused data // RtlZeroMemory(ResBuffer, sizeof(ResBuffer)); // // We assume there's only 1 bus so we only need one list. // Fill in the bus description // ResourceList->Count = 1; ResourceList->List[0].InterfaceType = BusType; ResourceList->List[0].BusNumber = BusNumber; // // If the device is using IO Ports add this to the list // if (ARGUMENT_PRESENT(FirstIoPort)) { PHYSICAL_ADDRESS PortAddress; ULONG MemType; PHYSICAL_ADDRESS MappedAddress; PortAddress.LowPart = *FirstIoPort; PortAddress.HighPart = 0; MemType = 1; HalTranslateBusAddress( BusType, BusNumber, PortAddress, &MemType, &MappedAddress); ResourceList->List[0].PartialResourceList.Count++; Descriptor->Type = CmResourceTypePort; Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; Descriptor->u.Port.Start.LowPart = *FirstIoPort; Descriptor->u.Port.Length = IoPortLength; Descriptor->Flags = MemType == 0 ? CM_RESOURCE_PORT_MEMORY : CM_RESOURCE_PORT_IO; // // Move on to next resource descriptor entry // Descriptor++; } // // Add interrupt information (if any) to the list // if (ARGUMENT_PRESENT(InterruptNumber)) { KAFFINITY Affinity; KIRQL InterruptRequestLevel; ULONG InterruptVector; // // Get the processor affinity and vector // InterruptVector = HalGetInterruptVector(BusType, BusNumber, *InterruptNumber, *InterruptNumber, &InterruptRequestLevel, &Affinity); ResourceList->List[0].PartialResourceList.Count++; Descriptor->Type = CmResourceTypeInterrupt; Descriptor->ShareDisposition = (UCHAR)(InterruptShareDisposition ? CmResourceShareShared : CmResourceShareDeviceExclusive); Descriptor->Flags = InterruptMode == Latched ? CM_RESOURCE_INTERRUPT_LATCHED : CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE; Descriptor->u.Interrupt.Level = *InterruptNumber; Descriptor->u.Interrupt.Vector = InterruptVector; Descriptor->u.Interrupt.Affinity = (ULONG)Affinity; // // Move on to next resource descriptor entry // Descriptor++; } // // Add DMA description if any // if (ARGUMENT_PRESENT(DmaChannel)) { ResourceList->List[0].PartialResourceList.Count++; Descriptor->Type = CmResourceTypeDma; Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; Descriptor->u.Dma.Channel = *DmaChannel; Descriptor->u.Dma.Port = 0; // ??? // // Move on to next resource descriptor entry // Descriptor++; } // // Report our resource usage and detect conflicts // switch (DeviceObject->Type) { case IO_TYPE_DEVICE: Status = IoReportResourceUsage(NULL, DeviceObject->DriverObject, NULL, 0, DeviceObject, ResourceList, (PUCHAR)Descriptor - (PUCHAR)ResourceList, FALSE, &ResourceConflict); break; case IO_TYPE_DRIVER: Status = IoReportResourceUsage(NULL, (PDRIVER_OBJECT)DeviceObject, ResourceList, (PUCHAR)Descriptor - (PUCHAR)ResourceList, NULL, NULL, 0, FALSE, &ResourceConflict); break; default: ASSERTMSG("SoundReportResourceUsage - invalid object", FALSE); } if (ResourceConflict) { dprintf1(("Resource conflict reported")); Status = STATUS_DEVICE_CONFIGURATION_ERROR; } return Status; }