static short resetProcess(PacketNode *head, PacketNode *tail) { short reset = FALSE; PacketNode *pac = head->next; while (pac != tail) { if (checkDirection(pac->addr.Direction, resetInbound, resetOutbound) && pac->packetLen > TCP_MIN_SIZE && (setNextCount || calcChance(chance))) { PWINDIVERT_TCPHDR pTcpHdr; WinDivertHelperParsePacket( pac->packet, pac->packetLen, NULL, NULL, NULL, NULL, &pTcpHdr, NULL, NULL, NULL); if (pTcpHdr != NULL) { LOG("injecting reset w/ chance %.1f%%", chance/100.0); pTcpHdr->Rst = 1; WinDivertHelperCalcChecksums(pac->packet, pac->packetLen, 0); reset = TRUE; if (setNextCount > 0) { InterlockedDecrement16(&setNextCount); } } } pac = pac->next; } return reset; }
/* * @implemented */ VOID NTAPI MmFreePagesFromMdl(IN PMDL Mdl) { PVOID Base; PPFN_NUMBER Pages; LONG NumberOfPages; PMMPFN Pfn1; KIRQL OldIrql; DPRINT("Freeing MDL: %p\n", Mdl); // // Sanity checks // ASSERT(KeGetCurrentIrql() <= APC_LEVEL); ASSERT((Mdl->MdlFlags & MDL_IO_SPACE) == 0); ASSERT(((ULONG_PTR)Mdl->StartVa & (PAGE_SIZE - 1)) == 0); // // Get address and page information // Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset); NumberOfPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount); // // Acquire PFN lock // OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); // // Loop all the MDL pages // Pages = (PPFN_NUMBER)(Mdl + 1); do { // // Reached the last page // if (*Pages == LIST_HEAD) break; // // Get the page entry // Pfn1 = MiGetPfnEntry(*Pages); ASSERT(Pfn1); ASSERT(Pfn1->u2.ShareCount == 1); ASSERT(MI_IS_PFN_DELETED(Pfn1) == TRUE); if (Pfn1->u4.PteFrame != 0x1FFEDCB) { /* Corrupted PFN entry or invalid free */ KeBugCheckEx(MEMORY_MANAGEMENT, 0x1236, (ULONG_PTR)Mdl, (ULONG_PTR)Pages, *Pages); } // // Clear it // Pfn1->u3.e1.StartOfAllocation = 0; Pfn1->u3.e1.EndOfAllocation = 0; Pfn1->u2.ShareCount = 0; // // Dereference it // ASSERT(Pfn1->u3.e2.ReferenceCount != 0); if (Pfn1->u3.e2.ReferenceCount != 1) { /* Just take off one reference */ InterlockedDecrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount); } else { /* We'll be nuking the whole page */ MiDecrementReferenceCount(Pfn1, *Pages); } // // Clear this page and move on // *Pages++ = LIST_HEAD; } while (--NumberOfPages != 0); // // Release the lock // KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); // // Remove the pages locked flag // Mdl->MdlFlags &= ~MDL_PAGES_LOCKED; }