// Create a packet buffer PACKET_BUFFER *NeoNewPacketBuffer() { PACKET_BUFFER *p; NET_BUFFER_LIST_POOL_PARAMETERS p1; // Memory allocation p = NeoZeroMalloc(sizeof(PACKET_BUFFER)); // Create a NET_BUFFER_LIST pool NeoZero(&p1, sizeof(p1)); p1.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; p1.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; p1.Header.Size = NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; p1.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT; p1.fAllocateNetBuffer = TRUE; p1.DataSize = NEO_MAX_PACKET_SIZE; p->NetBufferListPool = NdisAllocateNetBufferListPool(NULL, &p1); // Create a NET_BUFFER_LIST p->NetBufferList = NdisAllocateNetBufferList(p->NetBufferListPool, 0, 0); return p; }
// Returns with reference count initialized to one. PTAP_ADAPTER_CONTEXT tapAdapterContextAllocate(__in NDIS_HANDLE MiniportAdapterHandle) { PTAP_ADAPTER_CONTEXT adapter = NULL; adapter = (PTAP_ADAPTER_CONTEXT)NdisAllocateMemoryWithTagPriority( GlobalData.NdisDriverHandle, sizeof(TAP_ADAPTER_CONTEXT), TAP_ADAPTER_TAG, NormalPoolPriority); if (adapter) { NET_BUFFER_LIST_POOL_PARAMETERS nblPoolParameters = {0}; NdisZeroMemory(adapter, sizeof(TAP_ADAPTER_CONTEXT)); adapter->MiniportAdapterHandle = MiniportAdapterHandle; // Initialize cancel-safe IRP queue tapIrpCsqInitialize(&adapter->PendingReadIrpQueue); // Initialize TAP send packet queue. tapPacketQueueInitialize(&adapter->SendPacketQueue); // Allocate the adapter lock. NdisAllocateSpinLock(&adapter->AdapterLock); // NBL pool for making TAP receive indications. NdisZeroMemory(&nblPoolParameters, sizeof(NET_BUFFER_LIST_POOL_PARAMETERS)); // Initialize event used to determine when all receive NBLs have been returned. NdisInitializeEvent(&adapter->ReceiveNblInFlightCountZeroEvent); nblPoolParameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; nblPoolParameters.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; nblPoolParameters.Header.Size = NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; nblPoolParameters.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT; nblPoolParameters.ContextSize = 0; // nblPoolParameters.ContextSize = sizeof(RX_NETBUFLIST_RSVD); nblPoolParameters.fAllocateNetBuffer = TRUE; nblPoolParameters.PoolTag = TAP_RX_NBL_TAG; #pragma warning(suppress : 28197) adapter->ReceiveNblPool = NdisAllocateNetBufferListPool(adapter->MiniportAdapterHandle, &nblPoolParameters); if (adapter->ReceiveNblPool == NULL) { DEBUGP(("[TAP] Couldn't allocate adapter receive NBL pool\n")); NdisFreeMemory(adapter, 0, 0); } // Add initial reference. Normally removed in AdapterHalt. adapter->RefCount = 1; // Safe for multiple removes. NdisInitializeListHead(&adapter->AdapterListLink); // // The miniport adapter is initially powered up // adapter->CurrentPowerState = NdisDeviceStateD0; } return adapter; }
/********************************************************** NDIS6-related final initialization: Installing interrupt handler Allocate buffer list pool Parameters: Return value: ***********************************************************/ NDIS_STATUS ParaNdis_FinishSpecificInitialization(PARANDIS_ADAPTER *pContext) { NDIS_STATUS status = NDIS_STATUS_SUCCESS; NET_BUFFER_LIST_POOL_PARAMETERS PoolParams; NDIS_MINIPORT_INTERRUPT_CHARACTERISTICS mic; DEBUG_ENTRY(0); NdisZeroMemory(&mic, sizeof(mic)); mic.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_INTERRUPT; mic.Header.Revision = NDIS_MINIPORT_INTERRUPT_REVISION_1; mic.Header.Size = NDIS_SIZEOF_MINIPORT_INTERRUPT_CHARACTERISTICS_REVISION_1; mic.DisableInterruptHandler = MiniportDisableInterruptEx; mic.EnableInterruptHandler = MiniportEnableInterruptEx; mic.InterruptDpcHandler = MiniportInterruptDPC; mic.InterruptHandler = MiniportInterrupt; if (pContext->bUsingMSIX) { mic.MsiSupported = TRUE; mic.MsiSyncWithAllMessages = TRUE; mic.EnableMessageInterruptHandler = MiniportEnableMSIInterrupt; mic.DisableMessageInterruptHandler = MiniportDisableMSIInterrupt; mic.MessageInterruptHandler = MiniportMSIInterrupt; mic.MessageInterruptDpcHandler = MiniportMSIInterruptDpc; } PoolParams.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; PoolParams.Header.Size = sizeof(PoolParams); PoolParams.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; PoolParams.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT; PoolParams.fAllocateNetBuffer = TRUE; PoolParams.ContextSize = 0; PoolParams.PoolTag = PARANDIS_MEMORY_TAG; PoolParams.DataSize = 0; pContext->BufferListsPool = NdisAllocateNetBufferListPool(pContext->MiniportHandle, &PoolParams); if (!pContext->BufferListsPool) { status = NDIS_STATUS_RESOURCES; } if (status == NDIS_STATUS_SUCCESS) { status = NdisMRegisterInterruptEx(pContext->MiniportHandle, pContext, &mic, &pContext->InterruptHandle); } if (pContext->bUsingMSIX) { DPrintf(0, ("[%s] MSIX message table %savailable, count = %u\n", __FUNCTION__, (mic.MessageInfoTable == nullptr ? "not " : ""), (mic.MessageInfoTable == nullptr ? 0 : mic.MessageInfoTable->MessageCount))); } else { DPrintf(0, ("[%s] Not using MSIX\n", __FUNCTION__)); } if (status == NDIS_STATUS_SUCCESS) { NDIS_SG_DMA_DESCRIPTION sgDesc; sgDesc.Header.Type = NDIS_OBJECT_TYPE_SG_DMA_DESCRIPTION; sgDesc.Header.Revision = NDIS_SG_DMA_DESCRIPTION_REVISION_1; sgDesc.Header.Size = sizeof(sgDesc); sgDesc.Flags = NDIS_SG_DMA_64_BIT_ADDRESS; sgDesc.MaximumPhysicalMapping = 0x10000; // 64K sgDesc.ProcessSGListHandler = ProcessSGListHandler; sgDesc.SharedMemAllocateCompleteHandler = SharedMemAllocateCompleteHandler; sgDesc.ScatterGatherListSize = 0; // OUT value status = NdisMRegisterScatterGatherDma(pContext->MiniportHandle, &sgDesc, &pContext->DmaHandle); if (status != NDIS_STATUS_SUCCESS) { DPrintf(0, ("[%s] ERROR: NdisMRegisterScatterGatherDma failed (%X)!\n", __FUNCTION__, status)); } else { DPrintf(0, ("[%s] SG recommended size %d\n", __FUNCTION__, sgDesc.ScatterGatherListSize)); } } if (status == NDIS_STATUS_SUCCESS) { if (NDIS_CONNECT_MESSAGE_BASED == mic.InterruptType) { pContext->pMSIXInfoTable = mic.MessageInfoTable; } else if (pContext->bUsingMSIX) { DPrintf(0, ("[%s] ERROR: Interrupt type %d, message table %p\n", __FUNCTION__, mic.InterruptType, mic.MessageInfoTable)); status = NDIS_STATUS_RESOURCE_CONFLICT; } ParaNdis6_ApplyOffloadPersistentConfiguration(pContext); DebugParseOffloadBits(); } DEBUG_EXIT_STATUS(0, status); return status; }
NTSTATUS KrnlHlprNDISPoolDataPopulate(_Inout_ NDIS_POOL_DATA* pNDISPoolData, _In_opt_ UINT32 memoryTag) /* WFPSAMPLER_NDIS_POOL_TAG */ { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprNDISPoolDataPopulate()\n"); #endif /// DBG NT_ASSERT(pNDISPoolData); NTSTATUS status = STATUS_SUCCESS; NET_BUFFER_LIST_POOL_PARAMETERS nblPoolParameters = {0}; NET_BUFFER_POOL_PARAMETERS nbPoolParameters = {0}; pNDISPoolData->ndisHandle = NdisAllocateGenericObject(0, memoryTag, 0); if(pNDISPoolData->ndisHandle == 0) { status = STATUS_INVALID_HANDLE; DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, " !!!! KrnlHlprNDISPoolDataPopulate : NdisAllocateGenericObject() [status: %#x]\n", status); HLPR_BAIL; } nblPoolParameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; nblPoolParameters.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; nblPoolParameters.Header.Size = NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; nblPoolParameters.fAllocateNetBuffer = TRUE; nblPoolParameters.DataSize = 0; nblPoolParameters.PoolTag = memoryTag; pNDISPoolData->nblPoolHandle = NdisAllocateNetBufferListPool(pNDISPoolData->ndisHandle, &nblPoolParameters); if(pNDISPoolData->nblPoolHandle == 0) { status = STATUS_INVALID_HANDLE; DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, " !!!! KrnlHlprNDISPoolDataPopulate : NdisAllocateNetBufferListPool() [status: %#x]\n", status); HLPR_BAIL; } nbPoolParameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; nbPoolParameters.Header.Revision = NET_BUFFER_POOL_PARAMETERS_REVISION_1; nbPoolParameters.Header.Size = NDIS_SIZEOF_NET_BUFFER_POOL_PARAMETERS_REVISION_1; nbPoolParameters.PoolTag = memoryTag; nbPoolParameters.DataSize = 0; pNDISPoolData->nbPoolHandle = NdisAllocateNetBufferPool(pNDISPoolData->ndisHandle, &nbPoolParameters); if(pNDISPoolData->nbPoolHandle == 0) { status = STATUS_INVALID_HANDLE; DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, " !!!! KrnlHlprNDISPoolDataPopulate : NdisAllocateNetBufferPool() [status: %#x]\n", status); HLPR_BAIL; } HLPR_BAIL_LABEL: if(status != STATUS_SUCCESS) KrnlHlprNDISPoolDataPurge(pNDISPoolData); #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprNDISPoolDataPopulate()\n"); #endif /// DBG return status; }
/* * -------------------------------------------------------------------------- * OvsInitBufferPool -- * * Allocate NBL and NB pool * * XXX: more optimization may be done for buffer management include local cache * of NBL, NB, data, context, MDL. * -------------------------------------------------------------------------- */ NDIS_STATUS OvsInitBufferPool(PVOID ovsContext) { POVS_NBL_POOL ovsPool; POVS_SWITCH_CONTEXT context = (POVS_SWITCH_CONTEXT)ovsContext; NET_BUFFER_LIST_POOL_PARAMETERS nblParam; NET_BUFFER_POOL_PARAMETERS nbParam; C_ASSERT(MEMORY_ALLOCATION_ALIGNMENT >= 8); OVS_LOG_TRACE("Enter: context: %p", context); ovsPool = &context->ovsPool; RtlZeroMemory(ovsPool, sizeof (OVS_NBL_POOL)); ovsPool->ndisHandle = context->NdisFilterHandle; ovsPool->ndisContext = context->NdisSwitchContext; /* * fix size NBL pool includes * NBL + NB + MDL + DATA + Context * This is mainly used for Packet execute or slow path when copy is * required and size is less than OVS_DEFAULT_DATA_SIZE. We expect * Most of packet from user space will use this Pool. (This is * true for all bfd and cfm packet. */ RtlZeroMemory(&nblParam, sizeof (nblParam)); OVS_INIT_OBJECT_HEADER(&nblParam.Header, NDIS_OBJECT_TYPE_DEFAULT, NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1, NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1); nblParam.ContextSize = OVS_DEFAULT_NBL_CONTEXT_SIZE; nblParam.PoolTag = OVS_FIX_SIZE_NBL_POOL_TAG; nblParam.fAllocateNetBuffer = TRUE; nblParam.DataSize = OVS_DEFAULT_DATA_SIZE + OVS_DEFAULT_HEADROOM_SIZE; ovsPool->fixSizePool = NdisAllocateNetBufferListPool(context->NdisSwitchContext, &nblParam); if (ovsPool->fixSizePool == NULL) { goto pool_cleanup; } /* * Zero Size NBL Pool includes * NBL + NB + Context * This is mainly for packet with large data Size, in this case MDL and * Data will be allocate separately. */ RtlZeroMemory(&nblParam, sizeof (nblParam)); OVS_INIT_OBJECT_HEADER(&nblParam.Header, NDIS_OBJECT_TYPE_DEFAULT, NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1, NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1); nblParam.ContextSize = OVS_DEFAULT_NBL_CONTEXT_SIZE; nblParam.PoolTag = OVS_VARIABLE_SIZE_NBL_POOL_TAG; nblParam.fAllocateNetBuffer = TRUE; nblParam.DataSize = 0; ovsPool->zeroSizePool = NdisAllocateNetBufferListPool(context->NdisSwitchContext, &nblParam); if (ovsPool->zeroSizePool == NULL) { goto pool_cleanup; } /* * NBL only pool just includes * NBL (+ context) * This is mainly used for clone and partial copy */ RtlZeroMemory(&nblParam, sizeof (nblParam)); OVS_INIT_OBJECT_HEADER(&nblParam.Header, NDIS_OBJECT_TYPE_DEFAULT, NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1, NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1); nblParam.ContextSize = OVS_DEFAULT_NBL_CONTEXT_SIZE; nblParam.PoolTag = OVS_NBL_ONLY_POOL_TAG; nblParam.fAllocateNetBuffer = FALSE; nblParam.DataSize = 0; ovsPool->nblOnlyPool = NdisAllocateNetBufferListPool(context->NdisSwitchContext, &nblParam); if (ovsPool->nblOnlyPool == NULL) { goto pool_cleanup; } /* nb Pool * NB only pool, used for copy */ OVS_INIT_OBJECT_HEADER(&nbParam.Header, NDIS_OBJECT_TYPE_DEFAULT, NET_BUFFER_POOL_PARAMETERS_REVISION_1, NDIS_SIZEOF_NET_BUFFER_POOL_PARAMETERS_REVISION_1); nbParam.PoolTag = OVS_NET_BUFFER_POOL_TAG; nbParam.DataSize = 0; ovsPool->nbPool = NdisAllocateNetBufferPool(context->NdisSwitchContext, &nbParam); if (ovsPool->nbPool == NULL) { goto pool_cleanup; } OVS_LOG_TRACE("Exit: fixSizePool: %p zeroSizePool: %p nblOnlyPool: %p" "nbPool: %p", ovsPool->fixSizePool, ovsPool->zeroSizePool, ovsPool->nblOnlyPool, ovsPool->nbPool); return NDIS_STATUS_SUCCESS; pool_cleanup: OvsCleanupBufferPool(context); OVS_LOG_TRACE("Exit: Fail to initialize ovs buffer pool"); return NDIS_STATUS_RESOURCES; }
// Device is opened NTSTATUS SlDeviceOpenProc(DEVICE_OBJECT *device_object, IRP *irp) { SL_DEVICE *dev = *((SL_DEVICE **)device_object->DeviceExtension); NTSTATUS ret = STATUS_UNSUCCESSFUL; IO_STACK_LOCATION *irp_stack = IoGetCurrentIrpStackLocation(irp); if (dev->IsBasicDevice) { // Basic device ret = STATUS_SUCCESS; } else { bool set_promisc = false; volatile UINT *num_pending_oid_requests = NULL; UINT64 v; char event_name[SL_EVENT_NAME_SIZE]; char event_name_win32[SL_EVENT_NAME_SIZE]; SL_EVENT *event_object = NULL; LARGE_INTEGER count; LARGE_INTEGER freq; count = KeQueryPerformanceCounter(&freq); InterlockedIncrement(&sl->IntCounter1); // Create a new event object v = (UINT64)device_object + (UINT64)(++sl->IntCounter1) + *((UINT64 *)(&count)); sprintf(event_name, SL_EVENT_NAME, (UINT)v, (UINT)(v >> 32) + sl->IntCounter1); sprintf(event_name_win32, SL_EVENT_NAME_WIN32, (UINT)v, (UINT)(v >> 32) + sl->IntCounter1); event_object = SlNewEvent(event_name); SlLock(dev->OpenCloseLock); { // Add to the opened file list SlLockList(dev->FileList); { if (dev->Halting == false && dev->Adapter != NULL && dev->Adapter->Ready && dev->Adapter->Halt == false) { // Adapter device SL_FILE *f = SlZeroMalloc(sizeof(SL_FILE)); NET_BUFFER_LIST_POOL_PARAMETERS p; f->Device = dev; f->Adapter = dev->Adapter; f->FileObject = irp_stack->FileObject; irp_stack->FileObject->FsContext = f; SlAdd(dev->FileList, f); ret = STATUS_SUCCESS; set_promisc = true; // Event f->Event = event_object; event_object = NULL; strcpy(f->EventNameWin32, event_name_win32); // Create a lock f->RecvLock = SlNewLock(); // Create a NET_BUFFER_LIST pool SlZero(&p, sizeof(p)); p.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; p.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; p.Header.Size = NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; p.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT; p.fAllocateNetBuffer = true; p.ContextSize = 32; p.DataSize = SL_MAX_PACKET_SIZE; f->NetBufferListPool = NdisAllocateNetBufferListPool(NULL, &p); num_pending_oid_requests = &dev->Adapter->NumPendingOidRequests; } } SlUnlockList(dev->FileList); } SlUnlock(dev->OpenCloseLock); if (event_object != NULL) { SlFreeEvent(event_object); } if (set_promisc) { // Enable promiscuous mode UINT filter = NDIS_PACKET_TYPE_PROMISCUOUS; SlSendOidRequest(dev->Adapter, true, OID_GEN_CURRENT_PACKET_FILTER, &filter, sizeof(filter)); // Wait until the number of OID requests being processed becomes 0 while ((*num_pending_oid_requests) != 0) { SlSleep(50); } } } irp->IoStatus.Status = ret; IoCompleteRequest(irp, IO_NO_INCREMENT); return ret; }
NTSTATUS DriverEntry( DRIVER_OBJECT* driverObject, UNICODE_STRING* registryPath ) { NTSTATUS status; WDFDEVICE device; WDFDRIVER driver; WDFKEY configKey; NET_BUFFER_LIST_POOL_PARAMETERS nblPoolParams = {0}; // Request NX Non-Paged Pool when available ExInitializeDriverRuntime(DrvRtPoolNxOptIn); status = StreamEditInitDriverObjects( driverObject, registryPath, &driver, &device ); if (!NT_SUCCESS(status)) { goto Exit; } status = WdfDriverOpenParametersRegistryKey( driver, KEY_READ, WDF_NO_OBJECT_ATTRIBUTES, &configKey ); if (!NT_SUCCESS(status)) { goto Exit; } status = StreamEditLoadConfig(configKey); if (!NT_SUCCESS(status)) { goto Exit; } gStringToReplaceMdl = IoAllocateMdl( configStringToReplace, (ULONG) strlen(configStringToReplace), FALSE, FALSE, NULL ); if (gStringToReplaceMdl == NULL) { status = STATUS_NO_MEMORY; goto Exit; } MmBuildMdlForNonPagedPool(gStringToReplaceMdl); gNdisGenericObj = NdisAllocateGenericObject( driverObject, STREAM_EDITOR_NDIS_OBJ_TAG, 0 ); if (gNdisGenericObj == NULL) { status = STATUS_NO_MEMORY; goto Exit; } nblPoolParams.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; nblPoolParams.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; nblPoolParams.Header.Size = sizeof(nblPoolParams); nblPoolParams.fAllocateNetBuffer = TRUE; nblPoolParams.DataSize = 0; nblPoolParams.PoolTag = STREAM_EDITOR_NBL_POOL_TAG; gNetBufferListPool = NdisAllocateNetBufferListPool( gNdisGenericObj, &nblPoolParams ); if (gNetBufferListPool == NULL) { status = STATUS_NO_MEMORY; goto Exit; } status = FwpsInjectionHandleCreate( AF_UNSPEC, FWPS_INJECTION_TYPE_STREAM, &gInjectionHandle ); if (!NT_SUCCESS(status)) { goto Exit; } gWdmDevice = WdfDeviceWdmGetDeviceObject(device); status = StreamEditRegisterCallout( &gStreamEditor, gWdmDevice ); if (!NT_SUCCESS(status)) { goto Exit; } if (configEditInline) { InlineEditInit(&gStreamEditor); } else { status = OobEditInit(&gStreamEditor); if (!NT_SUCCESS(status)) { goto Exit; } } Exit: if (!NT_SUCCESS(status)) { if (gEngineHandle != NULL) { StreamEditUnregisterCallout(); } if (gInjectionHandle != NULL) { FwpsInjectionHandleDestroy(gInjectionHandle); } if (gNetBufferListPool != NULL) { NdisFreeNetBufferListPool(gNetBufferListPool); } if (gNdisGenericObj != NULL) { NdisFreeGenericObject(gNdisGenericObj); } if (gStringToReplaceMdl != NULL) { IoFreeMdl(gStringToReplaceMdl); } } return status; }
NTSTATUS DriverEntry( IN PDRIVER_OBJECT driverObject, IN PUNICODE_STRING registryPath) { NTSTATUS status = STATUS_SUCCESS; NTSTATUS symbolicLinkCreationStatus = STATUS_SUCCESS; UNICODE_STRING deviceName; UNICODE_STRING dosDeviceName; HANDLE threadHandle; NET_BUFFER_LIST_POOL_PARAMETERS nblPoolParams = {0}; UNICODE_STRING defaultSDDLString; #ifdef DEBUG DbgBreakPoint(); #endif status = drvCtlInit(driverObject); if (!NT_SUCCESS(status)) { goto Exit; } gDriverUnloading = FALSE; RtlInitUnicodeString(&defaultSDDLString, L"D:P(A;;GA;;;BU)"); RtlInitUnicodeString(&deviceName, DEVICE_NAME); status = IoCreateDeviceSecure( driverObject, 0, &deviceName, FILE_DEVICE_NETWORK, 0, FALSE, &defaultSDDLString, NULL, &gDeviceObject); if (!NT_SUCCESS(status)) { goto Exit; } RtlInitUnicodeString(&dosDeviceName, SYMBOLIC_LINK_NAME); status = IoCreateSymbolicLink(&dosDeviceName, &deviceName); symbolicLinkCreationStatus = status; if (!NT_SUCCESS(status)) { goto Exit; } status = FwpsInjectionHandleCreate0( AF_UNSPEC, FWPS_INJECTION_TYPE_STREAM, &gInjectionHandle); if (!NT_SUCCESS(status)) { goto Exit; } gNdisGenericObj = NdisAllocateGenericObject( driverObject, TAG_NDIS_OBJ, 0); if (gNdisGenericObj == NULL) { status = STATUS_NO_MEMORY; goto Exit; } nblPoolParams.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; nblPoolParams.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; nblPoolParams.Header.Size = NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; nblPoolParams.fAllocateNetBuffer = TRUE; nblPoolParams.DataSize = 0; nblPoolParams.PoolTag = TAG_NBL_POOL; gNetBufferListPool = NdisAllocateNetBufferListPool( gNdisGenericObj, &nblPoolParams); if(gNetBufferListPool == NULL) { status = STATUS_NO_MEMORY; goto Exit; } InitializeListHead(&gPacketQueue); KeInitializeSpinLock(&gPacketQueueLock); InitializeListHead(&flowContextList); KeInitializeSpinLock(&flowContextListLock); KeInitializeEvent( &gWorkerEvent, NotificationEvent, FALSE ); status = RegisterCallouts(gDeviceObject); if (!NT_SUCCESS(status)) { goto Exit; } status = PsCreateSystemThread( &threadHandle, THREAD_ALL_ACCESS, NULL, NULL, NULL, thAnalyzer, NULL); if (!NT_SUCCESS(status)) { goto Exit; } status = ObReferenceObjectByHandle( threadHandle, 0, NULL, KernelMode, (PVOID*) &gThreadObj, NULL); ASSERT(NT_SUCCESS(status)); KeSetBasePriorityThread( (PKTHREAD) gThreadObj, -2); ZwClose(threadHandle); driverObject->DriverUnload = DriverUnload; Exit: if (!NT_SUCCESS(status)) { if (gFwpmEngineHandle != NULL) { UnregisterCallouts(); } if (gInjectionHandle != NULL) { FwpsInjectionHandleDestroy0(gInjectionHandle); } if (gDeviceObject) { IoDeleteDevice(gDeviceObject); } if(NT_SUCCESS(symbolicLinkCreationStatus)) { IoDeleteSymbolicLink(&dosDeviceName); } if (gNetBufferListPool != NULL) { NdisFreeNetBufferListPool(gNetBufferListPool); } if (gNdisGenericObj != NULL) { NdisFreeGenericObject(gNdisGenericObj); } } return status; }