void RemoveUnseenProcesses(void) { KIRQL irql; int i; TIME liCurrentTime; if (g_proc_hash) { KeAcquireSpinLock(&g_proc_hash_guard, &irql); KeQuerySystemTime(&liCurrentTime); for (i = 0; i < HASH_SIZE; i++) { proc_entry_t *ote = g_proc_hash[i]; while (ote) { proc_entry_t *ote2 = ote->next; if(RtlLargeIntegerLessThan(liCurrentTime, ote->lastseen)) { FreeProcessData((ProcessData *)ote->pProcInfo); free((ProcessData *)ote->pProcInfo); free(ote); ote = ote2; } else ote = ote->next; } } KeReleaseSpinLock(&g_proc_hash_guard, irql); } }
NTSTATUS SoundMixerDispatch( IN OUT PLOCAL_DEVICE_INFO pLDI, IN PIRP pIrp, IN PIO_STACK_LOCATION IrpStack ) /*++ Routine Description: Mixer Irp call dispatcher Arguments: pLDI - Pointer to local device data pIrp - Pointer to IO request packet IrpStack - Pointer to current stack location Return Value: Return status from dispatched routine --*/ { NTSTATUS Status; Status = STATUS_SUCCESS; switch (IrpStack->MajorFunction) { // // Anybody can open // case IRP_MJ_CREATE: break; case IRP_MJ_CLOSE: break; case IRP_MJ_WRITE: Status = (*((PMIXER_INFO)pLDI->DeviceSpecificData)->HwSetControlData)( (PMIXER_INFO)pLDI->DeviceSpecificData, IrpStack->Parameters.Write.ByteOffset.LowPart, // ControlID IrpStack->Parameters.Write.Length, // Data length pIrp->AssociatedIrp.SystemBuffer); // Data break; case IRP_MJ_DEVICE_CONTROL: // // Dispatch the IOCTL function // Note that APIs which are possibly asynchronous do not // go through the Irp cleanup at the end here because they // may get completed before returning here or they are made // accessible to other requests by being queued. // switch (IrpStack->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_MIX_GET_CONFIGURATION: // // say how much we're sending back // Status = (*pLDI->DeviceInit->DevCapsRoutine)(pLDI, pIrp, IrpStack); break; case IOCTL_MIX_GET_CONTROL_DATA: case IOCTL_MIX_GET_LINE_DATA: { PMIXER_INFO MixerInfo; /* ** Find out what's being read */ if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MIXER_DD_READ_DATA)) { Status = STATUS_BUFFER_TOO_SMALL; break; } MixerInfo = ((PMIXER_INFO)pLDI->DeviceSpecificData); ASSERT(MixerInfo->Key == MIX_INFO_KEY); Status = (IrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_MIX_GET_CONTROL_DATA ? *MixerInfo->HwGetControlData : *MixerInfo->HwGetLineData) ( MixerInfo, ((PMIXER_DD_READ_DATA) pIrp->AssociatedIrp.SystemBuffer)->Id, // Control Id IrpStack->Parameters.DeviceIoControl. OutputBufferLength, // Data length pIrp->AssociatedIrp.SystemBuffer); // Data if (NT_SUCCESS(Status)) { pIrp->IoStatus.Information = IrpStack->Parameters.DeviceIoControl.OutputBufferLength; } break; } case IOCTL_MIX_REQUEST_NOTIFY: /* ** Check the parameters */ if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MIXER_DD_REQUEST_NOTIFY) || IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MIXER_DD_REQUEST_NOTIFY)) { Status = STATUS_BUFFER_TOO_SMALL; break; } { PMIXER_DD_REQUEST_NOTIFY MixerNotifyData; PMIXER_INFO MixerInfo; MixerInfo = ((PMIXER_INFO)pLDI->DeviceSpecificData); MixerNotifyData = (PMIXER_DD_REQUEST_NOTIFY) pIrp->AssociatedIrp.SystemBuffer; /* ** Check if the 'timer' has been initialized */ if (!MixerNotifyData->Initialized) { MixerNotifyData->CurrentLogicalTime = MixerInfo->CurrentLogicalTime; MixerNotifyData->Initialized = (BOOLEAN)TRUE; } else { /* ** See if there's more data for this IOCTL ** right now. ** ** We complete these Ioctls in 3 places : ** ** 1. Here - when they come in and there's data for them ** ** -- just this one completes ** ** 2. When data changes ** ** -- everything completes ** ** 3. When a close (cleanup) comes in ** ** -- All irps for the handle being closed complete */ if (RtlLargeIntegerLessThan( MixerNotifyData->CurrentLogicalTime, MixerInfo->CurrentLogicalTime)) { /* ** Generate notification and complete Irp ** immediately */ SoundMixerNotify(pIrp, MixerInfo); Status = STATUS_PENDING; break; } if (!RtlLargeIntegerEqualTo( MixerNotifyData->CurrentLogicalTime, MixerInfo->CurrentLogicalTime)) { /* ** Don't accept Irps with invalid 'new' times ** This should catch some rogue users. */ Status = STATUS_INVALID_PARAMETER; break; } } /* ** Add to our notification list */ SoundAddIrpToCancellableQ(&MixerInfo->NotifyQueue, pIrp, FALSE); Status = STATUS_PENDING; } break; default: dprintf2(("Unimplemented IOCTL (%08lXH) requested", IrpStack->Parameters.DeviceIoControl.IoControlCode)); Status = STATUS_INVALID_DEVICE_REQUEST; break; } break; case IRP_MJ_CLEANUP: /****************************************************************** * * Dispatch anyone waiting for notification from this device now. * ******************************************************************/ SoundFreePendingIrps( &((PMIXER_INFO)pLDI->DeviceSpecificData)->NotifyQueue, IrpStack->FileObject); break; default: dprintf1(("Unimplemented major function requested: %08lXH", IrpStack->MajorFunction)); Status = STATUS_INVALID_DEVICE_REQUEST; break; } return Status; }
VOID HalpReportResourceUsage ( IN PUNICODE_STRING HalName, IN INTERFACE_TYPE DeviceInterfaceToUse ) /*++ Routine Description: Arguments: Return Value: --*/ { PCM_RESOURCE_LIST RawResourceList, TranslatedResourceList; PCM_FULL_RESOURCE_DESCRIPTOR pRFullDesc, pTFullDesc; PCM_PARTIAL_RESOURCE_LIST pRPartList, pTPartList; PCM_PARTIAL_RESOURCE_DESCRIPTOR pRCurLoc, pTCurLoc; PCM_PARTIAL_RESOURCE_DESCRIPTOR pRSortLoc, pTSortLoc; CM_PARTIAL_RESOURCE_DESCRIPTOR RPartialDesc, TPartialDesc; ULONG i, j, k, ListSize, Count; ULONG curscale, sortscale; UCHAR pass, reporton; INTERFACE_TYPE interfacetype; ULONG CurrentIDT, CurrentElement; ADDRESS_USAGE *CurrentAddress; LARGE_INTEGER curvalue, sortvalue; // // Allocate some space to build the resource structure // RawResourceList = (PCM_RESOURCE_LIST) ExAllocatePool (NonPagedPool, PAGE_SIZE*2); TranslatedResourceList = (PCM_RESOURCE_LIST) ExAllocatePool (NonPagedPool, PAGE_SIZE*2); // This functions assumes unset fields are zero RtlZeroMemory (RawResourceList, PAGE_SIZE*2); RtlZeroMemory (TranslatedResourceList, PAGE_SIZE*2); // // Initialize the lists // RawResourceList->List[0].InterfaceType = (INTERFACE_TYPE) -1; pRFullDesc = RawResourceList->List; pRCurLoc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) RawResourceList->List; pTCurLoc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) TranslatedResourceList->List; // // Make sure all vectors 00-2f are reserved // 00-1E reserved by Intel // 1F reserved by Intel for APIC (apc priority level) // 20-2e reserved by Microsoft // 2f reserved by Microsoft for APIC (dpc priority level) // #if defined(_R98_) // CHG001 for(i=0; i < DEVICE_VECTORS; i++) { // ADD001 HalpIDTUsage[i].Flags = InternalUsage | InterruptLatched; HalpIDTUsage[i].BusReleativeVector = (UCHAR) i; } #else for(i=0; i < PRIMARY_VECTOR_BASE; i++) { if (!(HalpIDTUsage[i].Flags & IDTOwned)) { HalpIDTUsage[i].Flags = InternalUsage; HalpIDTUsage[i].BusReleativeVector = (UCHAR) i; } } #endif for(pass=0; pass < 2; pass++) { if (pass == 0) { // // First pass - build resource lists for resources reported // reported against device usage. // reporton = DeviceUsage & ~IDTOwned; interfacetype = DeviceInterfaceToUse; } else { // // Second pass = build reousce lists for resources reported // as internal usage. // reporton = InternalUsage & ~IDTOwned; interfacetype = Internal; } CurrentIDT = 0; CurrentElement = 0; CurrentAddress = HalpAddressUsageList; for (; ;) { if (CurrentIDT <= MAXIMUM_VECTOR) { // CHG001 // // Check to see if CurrentIDT needs to be reported // if (!(HalpIDTUsage[CurrentIDT].Flags & reporton)) { // Don't report on this one CurrentIDT++; continue; } // // Report CurrentIDT resource // RPartialDesc.Type = CmResourceTypeInterrupt; RPartialDesc.ShareDisposition = CmResourceShareDriverExclusive; RPartialDesc.Flags = HalpIDTUsage[CurrentIDT].Flags & InterruptLatched ? CM_RESOURCE_INTERRUPT_LATCHED : CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE; RPartialDesc.u.Interrupt.Vector = HalpIDTUsage[CurrentIDT].BusReleativeVector; RPartialDesc.u.Interrupt.Level = HalpIDTUsage[CurrentIDT].BusReleativeVector; RPartialDesc.u.Interrupt.Affinity = HalpActiveProcessors; RtlCopyMemory (&TPartialDesc, &RPartialDesc, sizeof TPartialDesc); TPartialDesc.u.Interrupt.Vector = CurrentIDT; TPartialDesc.u.Interrupt.Level = HalpIDTUsage[CurrentIDT].Irql; CurrentIDT++; } else { // // Check to see if CurrentAddress needs to be reported // if (!CurrentAddress) { break; // No addresses left } if (!(CurrentAddress->Flags & reporton)) { // Don't report on this list CurrentElement = 0; CurrentAddress = CurrentAddress->Next; continue; } if (!CurrentAddress->Element[CurrentElement].Length) { // End of current list, go to next list CurrentElement = 0; CurrentAddress = CurrentAddress->Next; continue; } // // Report CurrentAddress // RPartialDesc.Type = (UCHAR) CurrentAddress->Type; RPartialDesc.ShareDisposition = CmResourceShareDriverExclusive; if (RPartialDesc.Type == CmResourceTypePort) { i = 1; // address space port RPartialDesc.Flags = CM_RESOURCE_PORT_IO; } else { i = 0; // address space memory RPartialDesc.Flags = CM_RESOURCE_MEMORY_READ_WRITE; } // Notice: assuming u.Memory and u.Port have the same layout RPartialDesc.u.Memory.Start.HighPart = 0; RPartialDesc.u.Memory.Start.LowPart = CurrentAddress->Element[CurrentElement].Start; RPartialDesc.u.Memory.Length = CurrentAddress->Element[CurrentElement].Length; // translated address = Raw address RtlCopyMemory (&TPartialDesc, &RPartialDesc, sizeof TPartialDesc); HalTranslateBusAddress ( interfacetype, // device bus or internal 0, // bus number RPartialDesc.u.Memory.Start, // source address &i, // address space &TPartialDesc.u.Memory.Start ); // translated address if (RPartialDesc.Type == CmResourceTypePort && i == 0) { TPartialDesc.Flags = CM_RESOURCE_PORT_MEMORY; } CurrentElement++; } // // Include the current resource in the HALs list // if (pRFullDesc->InterfaceType != interfacetype) { // // Interface type changed, add another full section // RawResourceList->Count++; TranslatedResourceList->Count++; pRFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) pRCurLoc; pTFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) pTCurLoc; pRFullDesc->InterfaceType = interfacetype; pTFullDesc->InterfaceType = interfacetype; pRPartList = &pRFullDesc->PartialResourceList; pTPartList = &pTFullDesc->PartialResourceList; // // Bump current location pointers up // pRCurLoc = pRFullDesc->PartialResourceList.PartialDescriptors; pTCurLoc = pTFullDesc->PartialResourceList.PartialDescriptors; } pRPartList->Count++; pTPartList->Count++; RtlCopyMemory (pRCurLoc, &RPartialDesc, sizeof RPartialDesc); RtlCopyMemory (pTCurLoc, &TPartialDesc, sizeof TPartialDesc); pRCurLoc++; pTCurLoc++; } } ListSize = (ULONG) ( ((PUCHAR) pRCurLoc) - ((PUCHAR) RawResourceList) ); // // The HAL's resource usage structures have been built // Sort the partial lists based on the Raw resource values // pRFullDesc = RawResourceList->List; pTFullDesc = TranslatedResourceList->List; for (i=0; i < RawResourceList->Count; i++) { pRCurLoc = pRFullDesc->PartialResourceList.PartialDescriptors; pTCurLoc = pTFullDesc->PartialResourceList.PartialDescriptors; Count = pRFullDesc->PartialResourceList.Count; for (j=0; j < Count; j++) { HalpGetResourceSortValue (pRCurLoc, &curscale, &curvalue); pRSortLoc = pRCurLoc; pTSortLoc = pTCurLoc; for (k=j; k < Count; k++) { HalpGetResourceSortValue (pRSortLoc, &sortscale, &sortvalue); if (sortscale < curscale || (sortscale == curscale && RtlLargeIntegerLessThan (sortvalue, curvalue)) ) { // // Swap the elements.. // RtlCopyMemory (&RPartialDesc, pRCurLoc, sizeof RPartialDesc); RtlCopyMemory (pRCurLoc, pRSortLoc, sizeof RPartialDesc); RtlCopyMemory (pRSortLoc, &RPartialDesc, sizeof RPartialDesc); // swap translated descriptor as well RtlCopyMemory (&TPartialDesc, pTCurLoc, sizeof TPartialDesc); RtlCopyMemory (pTCurLoc, pTSortLoc, sizeof TPartialDesc); RtlCopyMemory (pTSortLoc, &TPartialDesc, sizeof TPartialDesc); // get new curscale & curvalue HalpGetResourceSortValue (pRCurLoc, &curscale, &curvalue); } pRSortLoc++; pTSortLoc++; } pRCurLoc++; pTCurLoc++; } pRFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) pRCurLoc; pTFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) pTCurLoc; } // // Inform the IO system of our resources.. // IoReportHalResourceUsage ( HalName, RawResourceList, TranslatedResourceList, ListSize ); ExFreePool (RawResourceList); ExFreePool (TranslatedResourceList); }