ULONG ParaNdis_GetSystemCPUCount() { ULONG nProcessors; #if NDIS_SUPPORT_NDIS620 nProcessors = NdisGroupActiveProcessorCount(ALL_PROCESSOR_GROUPS); #elif NDIS_SUPPORT_NDIS6 nProcessors = NdisSystemProcessorCount(); #else #error not supported #endif return nProcessors; }
// // Packet Driver's entry routine. // NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { NDIS_PROTOCOL_CHARACTERISTICS ProtocolChar; PDEVICE_OBJECT DeviceObject = NULL; PDEVICE_EXTENSION DeviceExtension = NULL; NTSTATUS Status = STATUS_SUCCESS; NTSTATUS ErrorCode = STATUS_SUCCESS; NDIS_STRING ProtoName = NDIS_STRING_CONST("PacketDriver"); ULONG DevicesCreated=0; NDIS_HANDLE NdisProtocolHandle; WCHAR* bindT; PKEY_VALUE_PARTIAL_INFORMATION tcpBindingsP; UNICODE_STRING macName; ULONG OsMajorVersion, OsMinorVersion; PsGetVersion(&OsMajorVersion, &OsMinorVersion, NULL, NULL); // // Define the correct flag to skip the loopback packets, according to the OS // if((OsMajorVersion == 5) && (OsMinorVersion == 0)) { // Windows 2000 wants both NDIS_FLAGS_DONT_LOOPBACK and NDIS_FLAGS_SKIP_LOOPBACK g_SendPacketFlags = NDIS_FLAGS_DONT_LOOPBACK | NDIS_FLAGS_SKIP_LOOPBACK_W2K; } else { // Windows XP, 2003 and following want only NDIS_FLAGS_DONT_LOOPBACK g_SendPacketFlags = NDIS_FLAGS_DONT_LOOPBACK; } if (((OsMajorVersion == 6) && (OsMinorVersion >= 1)) || (OsMajorVersion >= 7)) { // Use KeQueryActiveProcessors to get the number of CPUs in Windows 7 or later KAFFINITY cpus = KeQueryActiveProcessors(); NCpu = 0; while (cpus) { if (cpus % 2) { NCpu++; } cpus = cpus / 2; } } else { // Use NdisSystemProcessorCount in Windows Vista or earlier NCpu = NdisSystemProcessorCount(); } ReadTimeStampModeFromRegistry(RegistryPath); IF_LOUD(DbgPrint("%ws",RegistryPath->Buffer);)
/****************************************************************** Replacement of resource requirement list, when needed: The procedure traverses over all the resource lists in existing resource requirement list (we receive it in IRP information field). When the driver is not built to work with MSI resources, we must remove them from the resource requirement list, otherwise the driver will fail to initialize Typically MSI interrupts are labeled as preferred ones, when line interrupts are labeled as alternative resources. Removing message interrupts, remove also "alternative" label from line interrupts. *******************************************************************/ static PIO_RESOURCE_REQUIREMENTS_LIST ParseFilterResourceIrp( IN NDIS_HANDLE MiniportAddDeviceContext, PIO_RESOURCE_REQUIREMENTS_LIST prrl, BOOLEAN bRemoveMSIResources) { tRRLData newRRLData; ULONG nRemoved = 0; UINT nInterrupts = 0; PIO_RESOURCE_REQUIREMENTS_LIST newPrrl = NULL; ULONG QueueNumber; #if NDIS_SUPPORT_NDIS620 QueueNumber = NdisGroupActiveProcessorCount(ALL_PROCESSOR_GROUPS) + 1; #elif NDIS_SUPPORT_NDIS6 QueueNumber = NdisSystemProcessorCount(); #else QueueNumber = 0; /* Don't create MSI resource descriptors*/ #endif if (QueueNumber > 2048) QueueNumber = 2048; DPrintf(resourceFilterLevel, ("[%s]%s\n", __FUNCTION__, bRemoveMSIResources ? "(Remove MSI resources...)" : "")); newPrrl = (PIO_RESOURCE_REQUIREMENTS_LIST)NdisAllocateMemoryWithTagPriority( MiniportAddDeviceContext, prrl->ListSize + (bRemoveMSIResources ? 0 : QueueNumber * sizeof(IO_RESOURCE_DESCRIPTOR)), PARANDIS_MEMORY_TAG, NormalPoolPriority); InitializeNewResourceRequirementsList(&newRRLData, newPrrl, prrl); if (prrl) { ULONG n, offset; PVOID p = &prrl->List[0]; DPrintf(resourceFilterLevel, ("[%s] %d bytes, %d lists\n", __FUNCTION__, prrl->ListSize, prrl->AlternativeLists)); offset = RtlPointerToOffset(prrl, p); for (n = 0; n < prrl->AlternativeLists && offset < prrl->ListSize; ++n) { ULONG nDesc; IO_RESOURCE_LIST *pior = (IO_RESOURCE_LIST *)p; if ((offset + sizeof(*pior)) < prrl->ListSize) { IO_RESOURCE_DESCRIPTOR *pd = &pior->Descriptors[0]; DPrintf(resourceFilterLevel, ("[%s]+%d %d:%d descriptors follow\n", __FUNCTION__, offset, n, pior->Count)); offset += RtlPointerToOffset(p, pd); AddNewResourceList(&newRRLData, pior); for (nDesc = 0; nDesc < pior->Count; ++nDesc) { BOOLEAN bRemove = FALSE; if ((offset + sizeof(*pd)) <= prrl->ListSize) { #ifdef DBG DPrintf(resourceFilterLevel, ("[%s]+%d %d: type %d/%s, flags %X, option %X\n", __FUNCTION__, offset, nDesc, pd->Type, CM_RESOURCE_TYPE2String(pd->Type), pd->Flags, pd->Option)); #else DPrintf(resourceFilterLevel, ("[%s]+%d %d: type %d, flags %X, option %X\n", __FUNCTION__, offset, nDesc, pd->Type, pd->Flags, pd->Option)); #endif if (pd->Type == CmResourceTypeInterrupt) { nInterrupts++; DPrintf(0, ("[%s] min/max = %lx/%lx Option = 0x%lx, ShareDisposition = %u \n", __FUNCTION__, pd->u.Interrupt.MinimumVector, pd->u.Interrupt.MaximumVector, pd->Option, pd->ShareDisposition)); if (pd->Flags & CM_RESOURCE_INTERRUPT_MESSAGE) { bRemove = bRemoveMSIResources; } else { // reset IO_RESOURCE_ALTERNATIVE attribute on Line Interrupt, // if we remove MSI vectors, otherwise Windows will not allocate it for the device if (bRemoveMSIResources && (pd->Option & IO_RESOURCE_ALTERNATIVE)) { pd->Option &= ~IO_RESOURCE_ALTERNATIVE; } } } if (!bRemove) AddNewResourceDescriptor(&newRRLData, pd); else nRemoved++; } offset += sizeof(*pd); pd = (IO_RESOURCE_DESCRIPTOR *)RtlOffsetToPointer(prrl, offset); } if (!bRemoveMSIResources) { while (nInterrupts < QueueNumber) { IO_RESOURCE_DESCRIPTOR ior; ior.Type = CmResourceTypeInterrupt; ior.Flags = CM_RESOURCE_INTERRUPT_LATCHED | CM_RESOURCE_INTERRUPT_MESSAGE | CM_RESOURCE_INTERRUPT_POLICY_INCLUDED; ior.Option = 0; ior.ShareDisposition = CmResourceShareDeviceExclusive; ior.u.Interrupt.MinimumVector = ior.u.Interrupt.MaximumVector = CM_RESOURCE_INTERRUPT_MESSAGE_TOKEN; ior.u.Interrupt.AffinityPolicy = IrqPolicyMachineDefault; ior.u.Interrupt.PriorityPolicy = IrqPriorityNormal; AddNewResourceDescriptor(&newRRLData, &ior); nInterrupts++; } } FinalizeResourceList(&newRRLData); p = pd; } } } if (!bRemoveMSIResources) { SetupInterrruptAffinity(newPrrl); } if (bRemoveMSIResources && nRemoved) { DPrintf(0, ("[%s] %d resources removed\n", __FUNCTION__, nRemoved)); } return newPrrl; }