NTSTATUS NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PDEVICE_EXTENSION DeviceExtension; POPEN_INSTANCE Open; PIO_STACK_LOCATION IrpSp; NDIS_STATUS Status; NDIS_STATUS ErrorStatus; UINT i; PUCHAR tpointer; PLIST_ENTRY PacketListEntry; NTSTATUS returnStatus; // // Old registry based WinPcap names // // WCHAR EventPrefix[MAX_WINPCAP_KEY_CHARS]; // UINT RegStrLen; TRACE_ENTER(); DeviceExtension = DeviceObject->DeviceExtension; IrpSp = IoGetCurrentIrpStackLocation(Irp); // allocate some memory for the open structure Open=ExAllocatePoolWithTag(NonPagedPool, sizeof(OPEN_INSTANCE), '0OWA'); if (Open==NULL) { // no memory Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory( Open, sizeof(OPEN_INSTANCE) ); // // Old registry based WinPcap names // // // // // Get the Event names base from the registry // // // RegStrLen = sizeof(EventPrefix)/sizeof(EventPrefix[0]); // // NPF_QueryWinpcapRegistryString(NPF_EVENTS_NAMES_REG_KEY_WC, // EventPrefix, // RegStrLen, // NPF_EVENTS_NAMES_WIDECHAR); // Open->DeviceExtension=DeviceExtension; // Allocate a packet pool for our xmit and receive packets NdisAllocatePacketPool( &Status, &Open->PacketPool, TRANSMIT_PACKETS, sizeof(PACKET_RESERVED)); if (Status != NDIS_STATUS_SUCCESS) { TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Failed to allocate packet pool"); ExFreePool(Open); Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_INSUFFICIENT_RESOURCES; } NdisInitializeEvent(&Open->WriteEvent); NdisInitializeEvent(&Open->NdisRequestEvent); NdisInitializeEvent(&Open->NdisWriteCompleteEvent); NdisInitializeEvent(&Open->DumpEvent); NdisAllocateSpinLock(&Open->MachineLock); NdisAllocateSpinLock(&Open->WriteLock); Open->WriteInProgress = FALSE; for (i = 0; i < g_NCpu; i++) { NdisAllocateSpinLock(&Open->CpuData[i].BufferLock); } NdisInitializeEvent(&Open->NdisOpenCloseCompleteEvent); // list to hold irp's want to reset the adapter InitializeListHead(&Open->ResetIrpList); // Initialize the request list KeInitializeSpinLock(&Open->RequestSpinLock); InitializeListHead(&Open->RequestList); #ifdef HAVE_BUGGY_TME_SUPPORT // Initializes the extended memory of the NPF machine Open->mem_ex.buffer = ExAllocatePoolWithTag(NonPagedPool, DEFAULT_MEM_EX_SIZE, '2OWA'); if((Open->mem_ex.buffer) == NULL) { // // no memory // ExFreePool(Open); Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_INSUFFICIENT_RESOURCES; } Open->mem_ex.size = DEFAULT_MEM_EX_SIZE; RtlZeroMemory(Open->mem_ex.buffer, DEFAULT_MEM_EX_SIZE); #endif //HAVE_BUGGY_TME_SUPPORT // // Initialize the open instance // Open->bpfprogram = NULL; //reset the filter Open->mode = MODE_CAPT; Open->Nbytes.QuadPart = 0; Open->Npackets.QuadPart = 0; Open->Nwrites = 1; Open->Multiple_Write_Counter = 0; Open->MinToCopy = 0; Open->TimeOut.QuadPart = (LONGLONG)1; Open->DumpFileName.Buffer = NULL; Open->DumpFileHandle = NULL; #ifdef HAVE_BUGGY_TME_SUPPORT Open->tme.active = TME_NONE_ACTIVE; #endif // HAVE_BUGGY_TME_SUPPORT Open->DumpLimitReached = FALSE; Open->MaxFrameSize = 0; Open->WriterSN=0; Open->ReaderSN=0; Open->Size=0; Open->SkipSentPackets = FALSE; Open->ReadEvent = NULL; // // we need to keep a counter of the pending IRPs // so that when the IRP_MJ_CLEANUP dispatcher gets called, // we can wait for those IRPs to be completed // Open->NumPendingIrps = 0; Open->ClosePending = FALSE; NdisAllocateSpinLock(&Open->OpenInUseLock); // //allocate the spinlock for the statistic counters // NdisAllocateSpinLock(&Open->CountersLock); // // link up the request stored in our open block // for (i = 0 ; i < MAX_REQUESTS ; i++ ) { NdisInitializeEvent(&Open->Requests[i].InternalRequestCompletedEvent); ExInterlockedInsertTailList( &Open->RequestList, &Open->Requests[i].ListElement, &Open->RequestSpinLock); } NdisResetEvent(&Open->NdisOpenCloseCompleteEvent); // // set the proper binding flags before trying to open the MAC // Open->AdapterBindingStatus = ADAPTER_BOUND; Open->AdapterHandleUsageCounter = 0; NdisAllocateSpinLock(&Open->AdapterHandleLock); // // Try to open the MAC // TRACE_MESSAGE2(PACKET_DEBUG_LOUD,"Opening the device %ws, BindingContext=%p",DeviceExtension->AdapterName.Buffer, Open); returnStatus = STATUS_SUCCESS; NdisOpenAdapter( &Status, &ErrorStatus, &Open->AdapterHandle, &Open->Medium, MediumArray, NUM_NDIS_MEDIA, g_NdisProtocolHandle, Open, &DeviceExtension->AdapterName, 0, NULL); TRACE_MESSAGE1(PACKET_DEBUG_LOUD,"Opened the device, Status=%x",Status); if (Status == NDIS_STATUS_PENDING) { NdisWaitEvent(&Open->NdisOpenCloseCompleteEvent, 0); if (!NT_SUCCESS(Open->OpenCloseStatus)) { returnStatus = Open->OpenCloseStatus; } else { returnStatus = STATUS_SUCCESS; } } else { // // request not pending, we know the result, and OpenComplete has not been called. // if (Status == NDIS_STATUS_SUCCESS) { returnStatus = STATUS_SUCCESS; } else { // // this is not completely correct, as we are converting an NDIS_STATUS to a NTSTATUS // returnStatus = Status; } } if (returnStatus == STATUS_SUCCESS) { ULONG localNumOpenedInstances; // // complete the open // localNumOpenedInstances = InterlockedIncrement(&g_NumOpenedInstances); TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Opened Instances: %u", localNumOpenedInstances); // Get the absolute value of the system boot time. // This is used for timestamp conversion. TIME_SYNCHRONIZE(&G_Start_Time); returnStatus = NPF_GetDeviceMTU(Open, Irp, &Open->MaxFrameSize); if (!NT_SUCCESS(returnStatus)) { // // Close the binding // NPF_CloseBinding(Open); } } if (!NT_SUCCESS(returnStatus)) { NPF_ReleaseOpenInstanceResources(Open); // // Free the open instance itself // ExFreePool(Open); } else { // Save or open here IrpSp->FileObject->FsContext=Open; } Irp->IoStatus.Status = returnStatus; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); TRACE_EXIT(); return returnStatus; }
VOID natpBindAdapter( OUT PNDIS_STATUS Status, IN NDIS_HANDLE BindContext, IN PNDIS_STRING DeviceName, IN PVOID SystemSpecific1, IN PVOID SystemSpecific2 ) { NDIS_HANDLE ConfigHandle = NULL; PNDIS_CONFIGURATION_PARAMETER Param; NDIS_STRING DeviceStr = UPPER_BINDINGS; PFILTER_ADAPTER pAdapt = NULL; NDIS_STATUS Sts; UINT MediumIndex, i; ULONG TotalSize; WCHAR DevicePrefix[] = L"\\Device\\"; UNREFERENCED_PARAMETER(BindContext); UNREFERENCED_PARAMETER(SystemSpecific2); __try{ NdisOpenProtocolConfiguration( Status, &ConfigHandle, SystemSpecific1 ); if (*Status != NDIS_STATUS_SUCCESS) __leave; NdisReadConfiguration( Status, &Param, ConfigHandle, &DeviceStr, NdisParameterString ); if (*Status != NDIS_STATUS_SUCCESS) __leave; TotalSize = sizeof(FILTER_ADAPTER) + Param->ParameterData.StringData.MaximumLength + DeviceName->MaximumLength; NdisAllocateMemoryWithTag(&pAdapt, TotalSize, NAT_TAG); if (NULL == pAdapt){ *Status = NDIS_STATUS_RESOURCES; __leave; } NdisZeroMemory(pAdapt, TotalSize); pAdapt->DeviceName.MaximumLength = Param->ParameterData.StringData.MaximumLength; pAdapt->DeviceName.Length = Param->ParameterData.StringData.Length; pAdapt->DeviceName.Buffer = (PWCHAR)((ULONG_PTR)pAdapt + sizeof(FILTER_ADAPTER)); NdisMoveMemory( pAdapt->DeviceName.Buffer, Param->ParameterData.StringData.Buffer, Param->ParameterData.StringData.MaximumLength ); if(sizeof(DevicePrefix) >= DeviceName->Length){ }else{ pAdapt->RootDeviceName.MaximumLength = DeviceName->MaximumLength; pAdapt->RootDeviceName.Length = DeviceName->Length - sizeof(DevicePrefix) + sizeof(WCHAR); pAdapt->RootDeviceName.Buffer = (PWCHAR)((ULONG_PTR)pAdapt + sizeof(FILTER_ADAPTER) + Param->ParameterData.StringData.MaximumLength); NdisMoveMemory( pAdapt->RootDeviceName.Buffer, DeviceName->Buffer + sizeof(DevicePrefix)/sizeof(WCHAR) - 1, DeviceName->MaximumLength - sizeof(DevicePrefix)/sizeof(WCHAR) + 1 ); } NdisInitializeEvent(&pAdapt->Event); NdisAllocateSpinLock(&pAdapt->Lock); natInitControlBlock(&pAdapt->ctrl); NdisAllocatePacketPoolEx( Status, &pAdapt->SndPP1, MIN_PACKET_POOL_SIZE, MAX_PACKET_POOL_SIZE, PROTOCOL_RESERVED_SIZE_IN_PACKET ); if (*Status != NDIS_STATUS_SUCCESS) __leave; NdisAllocatePacketPoolEx( Status, &pAdapt->SndPP2, MIN_PACKET_POOL_SIZE, MAX_PACKET_POOL_SIZE, PROTOCOL_RESERVED_SIZE_IN_PACKET ); if (*Status != NDIS_STATUS_SUCCESS) __leave; NdisAllocateBufferPool( Status, &pAdapt->SndBP, MIN_PACKET_POOL_SIZE ); if ( *Status != NDIS_STATUS_SUCCESS ) __leave; NdisAllocatePacketPoolEx( Status, &pAdapt->RcvPP1, MIN_PACKET_POOL_SIZE, MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE, PROTOCOL_RESERVED_SIZE_IN_PACKET ); if (*Status != NDIS_STATUS_SUCCESS) __leave; NdisAllocatePacketPoolEx( Status, &pAdapt->RcvPP2, MIN_PACKET_POOL_SIZE, MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE, PROTOCOL_RESERVED_SIZE_IN_PACKET ); if (*Status != NDIS_STATUS_SUCCESS) __leave; NdisAllocateBufferPool( Status, &pAdapt->RcvBP, MIN_PACKET_POOL_SIZE ); if ( *Status != NDIS_STATUS_SUCCESS ) __leave; NdisOpenAdapter( Status, &Sts, &pAdapt->BindingHandle, &MediumIndex, MediumArray, sizeof(MediumArray)/sizeof(NDIS_MEDIUM), ProtHandle, pAdapt, DeviceName, 0,NULL ); if (*Status == NDIS_STATUS_PENDING){ NdisWaitEvent(&pAdapt->Event, 0); *Status = pAdapt->Status; } if (*Status != NDIS_STATUS_SUCCESS) __leave; pAdapt->Medium = MediumArray[MediumIndex]; pAdapt->MiniportInitPending = TRUE; NdisInitializeEvent(&pAdapt->MiniportInitEvent); *Status = NdisIMInitializeDeviceInstanceEx( DriverHandle, &pAdapt->DeviceName, pAdapt ); if (*Status != NDIS_STATUS_SUCCESS) __leave; StartQueryInfo( pAdapt ); } __finally{ } if (ConfigHandle != NULL) NdisCloseConfiguration(ConfigHandle); if(NDIS_STATUS_SUCCESS != *Status){ if (pAdapt != NULL){ if (pAdapt->BindingHandle != NULL){ NDIS_STATUS LocalStatus; NdisResetEvent(&pAdapt->Event); NdisCloseAdapter(&LocalStatus, pAdapt->BindingHandle); pAdapt->BindingHandle = NULL; if (LocalStatus == NDIS_STATUS_PENDING){ NdisWaitEvent(&pAdapt->Event, 0); LocalStatus = pAdapt->Status; } } natFreeAllItems(&pAdapt->ctrl); natFreeAllFwSessionsAndRules(&pAdapt->ctrl); for(i = 0;i<FLT_FW_SESSION_HASH_TBL_SZ;i++) NdisFreeSpinLock(pAdapt->ctrl.FwSessionLocks + i); NdisFreeSpinLock(&pAdapt->ctrl.IcmpRuleLock); NdisFreeSpinLock(&pAdapt->ctrl.UdpRuleLock); NdisFreeSpinLock(&pAdapt->ctrl.TcpRuleLock); natmFreeAllPacketPools(pAdapt); NdisFreeSpinLock(&pAdapt->Lock); NdisFreeMemory(pAdapt, 0, 0); pAdapt = NULL; } } }
static NDIS_STATUS BindAdapterByName(PNDIS_STRING DeviceName) { NDIS_STATUS OpenErrorStatus; PNDISUIO_ADAPTER_CONTEXT AdapterContext; NDIS_MEDIUM SupportedMedia[1] = {NdisMedium802_3}; UINT SelectedMedium; NDIS_STATUS Status; NDIS_REQUEST Request; /* Allocate the adapter context */ AdapterContext = ExAllocatePool(NonPagedPool, sizeof(*AdapterContext)); if (!AdapterContext) { return NDIS_STATUS_RESOURCES; } /* Set up the adapter context */ RtlZeroMemory(AdapterContext, sizeof(*AdapterContext)); KeInitializeEvent(&AdapterContext->AsyncEvent, SynchronizationEvent, FALSE); KeInitializeEvent(&AdapterContext->PacketReadEvent, SynchronizationEvent, FALSE); KeInitializeSpinLock(&AdapterContext->Spinlock); InitializeListHead(&AdapterContext->PacketList); InitializeListHead(&AdapterContext->OpenEntryList); AdapterContext->OpenCount = 0; AdapterContext->DeviceName.Length = AdapterContext->DeviceName.MaximumLength = DeviceName->Length; AdapterContext->DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceName->Length); if (!AdapterContext->DeviceName.Buffer) { ExFreePool(AdapterContext); return NDIS_STATUS_RESOURCES; } /* Copy the device name into the adapter context */ RtlCopyMemory(AdapterContext->DeviceName.Buffer, DeviceName->Buffer, DeviceName->Length); DPRINT("Binding adapter %wZ\n", &AdapterContext->DeviceName); /* Create the buffer pool */ NdisAllocateBufferPool(&Status, &AdapterContext->BufferPoolHandle, 50); if (Status != NDIS_STATUS_SUCCESS) { DPRINT1("Failed to allocate buffer pool with status 0x%x\n", Status); RtlFreeUnicodeString(&AdapterContext->DeviceName); ExFreePool(AdapterContext); return Status; } /* Create the packet pool */ NdisAllocatePacketPool(&Status, &AdapterContext->PacketPoolHandle, 25, PROTOCOL_RESERVED_SIZE_IN_PACKET); if (Status != NDIS_STATUS_SUCCESS) { DPRINT1("Failed to allocate packet pool with status 0x%x\n", Status); NdisFreeBufferPool(AdapterContext->BufferPoolHandle); RtlFreeUnicodeString(&AdapterContext->DeviceName); ExFreePool(AdapterContext); return Status; } /* Send the open request */ NdisOpenAdapter(&Status, &OpenErrorStatus, &AdapterContext->BindingHandle, &SelectedMedium, SupportedMedia, 1, GlobalProtocolHandle, AdapterContext, DeviceName, 0, NULL); /* Wait for a pending open */ if (Status == NDIS_STATUS_PENDING) { KeWaitForSingleObject(&AdapterContext->AsyncEvent, Executive, KernelMode, FALSE, NULL); Status = AdapterContext->AsyncStatus; } /* Check the final status */ if (Status != NDIS_STATUS_SUCCESS) { DPRINT1("Failed to open adapter for bind with status 0x%x\n", Status); NdisFreePacketPool(AdapterContext->PacketPoolHandle); NdisFreeBufferPool(AdapterContext->BufferPoolHandle); RtlFreeUnicodeString(&AdapterContext->DeviceName); ExFreePool(AdapterContext); return Status; } /* Get the MAC options */ Request.RequestType = NdisRequestQueryInformation; Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAC_OPTIONS; Request.DATA.QUERY_INFORMATION.InformationBuffer = &AdapterContext->MacOptions; Request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(ULONG); NdisRequest(&Status, AdapterContext->BindingHandle, &Request); /* Wait for a pending request */ if (Status == NDIS_STATUS_PENDING) { KeWaitForSingleObject(&AdapterContext->AsyncEvent, Executive, KernelMode, FALSE, NULL); Status = AdapterContext->AsyncStatus; } /* Check the final status */ if (Status != NDIS_STATUS_SUCCESS) { NDIS_STATUS CloseStatus; DPRINT1("Failed to get MAC options with status 0x%x\n", Status); NdisCloseAdapter(&CloseStatus, AdapterContext->BindingHandle); if (CloseStatus == NDIS_STATUS_PENDING) { KeWaitForSingleObject(&AdapterContext->AsyncEvent, Executive, KernelMode, FALSE, NULL); } NdisFreePacketPool(AdapterContext->PacketPoolHandle); NdisFreeBufferPool(AdapterContext->BufferPoolHandle); RtlFreeUnicodeString(&AdapterContext->DeviceName); ExFreePool(AdapterContext); return Status; } /* Add the adapter context to the global list */ ExInterlockedInsertTailList(&GlobalAdapterList, &AdapterContext->ListEntry, &GlobalAdapterListLock); return STATUS_SUCCESS; }
VOID PtBindAdapter( OUT PNDIS_STATUS Status, IN NDIS_HANDLE BindContext, IN PNDIS_STRING DeviceName, IN PVOID SystemSpecific1, IN PVOID SystemSpecific2 ) /*++ Routine Description: Called by NDIS to bind to a miniport below. Arguments: Status - Return status of bind here. BindContext - Can be passed to NdisCompleteBindAdapter if this call is pended. DeviceName - Device name to bind to. This is passed to NdisOpenAdapter. SystemSpecific1 - Can be passed to NdisOpenProtocolConfiguration to read per-binding information SystemSpecific2 - Unused Return Value: NDIS_STATUS_PENDING if this call is pended. In this case call NdisCompleteBindAdapter to complete. Anything else Completes this call synchronously --*/ { NDIS_HANDLE ConfigHandle = NULL; PNDIS_CONFIGURATION_PARAMETER Param; NDIS_STRING DeviceStr = NDIS_STRING_CONST("UpperBindings"); PADAPT pAdapt = NULL; NDIS_STATUS Sts; UINT MediumIndex; ULONG TotalSize; PNDIS_CONFIGURATION_PARAMETER BundleParam; NDIS_STRING BundleStr = NDIS_STRING_CONST("BundleId"); NDIS_STATUS BundleStatus; DBGPRINT(("==> Protocol BindAdapter\n")); do { // // Access the configuration section for our binding-specific // parameters. // NdisOpenProtocolConfiguration(Status, &ConfigHandle, SystemSpecific1); if (*Status != NDIS_STATUS_SUCCESS) { break; } // // Read the "UpperBindings" reserved key that contains a list // of device names representing our miniport instances corresponding // to this lower binding. Since this is a 1:1 IM driver, this key // contains exactly one name. // // If we want to implement a N:1 mux driver (N adapter instances // over a single lower binding), then UpperBindings will be a // MULTI_SZ containing a list of device names - we would loop through // this list, calling NdisIMInitializeDeviceInstanceEx once for // each name in it. // NdisReadConfiguration(Status, &Param, ConfigHandle, &DeviceStr, NdisParameterString); if (*Status != NDIS_STATUS_SUCCESS) { break; } // // Allocate memory for the Adapter structure. This represents both the // protocol context as well as the adapter structure when the miniport // is initialized. // // In addition to the base structure, allocate space for the device // instance string. // TotalSize = sizeof(ADAPT) + Param->ParameterData.StringData.MaximumLength; NdisAllocateMemoryWithTag(&pAdapt, TotalSize, TAG); if (pAdapt == NULL) { *Status = NDIS_STATUS_RESOURCES; break; } // // Initialize the adapter structure. We copy in the IM device // name as well, because we may need to use it in a call to // NdisIMCancelInitializeDeviceInstance. The string returned // by NdisReadConfiguration is active (i.e. available) only // for the duration of this call to our BindAdapter handler. // NdisZeroMemory(pAdapt, TotalSize); pAdapt->DeviceName.MaximumLength = Param->ParameterData.StringData.MaximumLength; pAdapt->DeviceName.Length = Param->ParameterData.StringData.Length; pAdapt->DeviceName.Buffer = (PWCHAR)((ULONG_PTR)pAdapt + sizeof(ADAPT)); NdisMoveMemory(pAdapt->DeviceName.Buffer, Param->ParameterData.StringData.Buffer, Param->ParameterData.StringData.MaximumLength); NdisInitializeEvent(&pAdapt->Event); // // Allocate a packet pool for sends. We need this to pass sends down. // We cannot use the same packet descriptor that came down to our send // handler (see also NDIS 5.1 packet stacking). // NdisAllocatePacketPoolEx(Status, &pAdapt->SendPacketPoolHandle, MIN_PACKET_POOL_SIZE, MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE, sizeof(SEND_RSVD)); if (*Status != NDIS_STATUS_SUCCESS) { break; } // // Allocate a packet pool for receives. We need this to indicate receives. // Same consideration as sends (see also NDIS 5.1 packet stacking). // NdisAllocatePacketPoolEx(Status, &pAdapt->RecvPacketPoolHandle, MIN_PACKET_POOL_SIZE, MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE, PROTOCOL_RESERVED_SIZE_IN_PACKET); if (*Status != NDIS_STATUS_SUCCESS) { break; } // // Now open the adapter below and complete the initialization // NdisOpenAdapter(Status, &Sts, &pAdapt->BindingHandle, &MediumIndex, MediumArray, sizeof(MediumArray)/sizeof(NDIS_MEDIUM), ProtHandle, pAdapt, DeviceName, 0, NULL); if (*Status == NDIS_STATUS_PENDING) { NdisWaitEvent(&pAdapt->Event, 0); *Status = pAdapt->Status; } if (*Status != NDIS_STATUS_SUCCESS) { break; } pAdapt->Medium = MediumArray[MediumIndex]; // // Now ask NDIS to initialize our miniport (upper) edge. // Set the flag below to synchronize with a possible call // to our protocol Unbind handler that may come in before // our miniport initialization happens. // pAdapt->MiniportInitPending = TRUE; NdisInitializeEvent(&pAdapt->MiniportInitEvent); *Status = NdisIMInitializeDeviceInstanceEx(DriverHandle, &pAdapt->DeviceName, pAdapt); if (*Status != NDIS_STATUS_SUCCESS) { DBGPRINT(("BindAdapter: Adapt %p, IMInitializeDeviceInstance error %x\n", pAdapt, *Status)); break; } } while(FALSE); // // Close the configuration handle now - see comments above with // the call to NdisIMInitializeDeviceInstanceEx. // if (ConfigHandle != NULL) { NdisCloseConfiguration(ConfigHandle); } if (*Status != NDIS_STATUS_SUCCESS) { if (pAdapt != NULL) { if (pAdapt->BindingHandle != NULL) { NDIS_STATUS LocalStatus; // // Close the binding we opened above. // NdisCloseAdapter(&LocalStatus, pAdapt->BindingHandle); pAdapt->BindingHandle = NULL; if (LocalStatus == NDIS_STATUS_PENDING) { NdisWaitEvent(&pAdapt->Event, 0); LocalStatus = pAdapt->Status; } } if (pAdapt->SendPacketPoolHandle != NULL) { NdisFreePacketPool(pAdapt->SendPacketPoolHandle); } if (pAdapt->RecvPacketPoolHandle != NULL) { NdisFreePacketPool(pAdapt->RecvPacketPoolHandle); } NdisFreeMemory(pAdapt, sizeof(ADAPT), 0); pAdapt = NULL; } } DBGPRINT(("<== Protocol BindAdapter: pAdapt %p, Status %x\n", pAdapt, *Status)); }
VOID NDIS_API PacketBindAdapter(OUT PNDIS_STATUS pStatus, IN NDIS_HANDLE BindAdapterContext, IN PNDIS_STRING pAdapterName, IN PVOID SystemSpecific1, IN PVOID SystemSpecific2) { // bind this driver to a NIC POPEN_INSTANCE oiNew; NDIS_STATUS ErrorStatus, AllocStatus; UINT Medium; NDIS_MEDIUM MediumArray = NdisMedium802_3; UINT i; // allocate some memory for the open structure NdisAllocateMemory((PVOID *)&oiNew, sizeof(OPEN_INSTANCE), 0, -1); if (oiNew == NULL) { // not enough memory *pStatus = NDIS_STATUS_RESOURCES; return; } NdisZeroMemory((PVOID)oiNew, sizeof(OPEN_INSTANCE)); // Save Binding Context oiNew->BindAdapterContext = BindAdapterContext; // Save the device handle oiNew->hDevice = (DWORD)SystemSpecific1; // Allocate a packet pool for our xmit and receive packets NdisAllocatePacketPool(&AllocStatus, &(oiNew->PacketPool), TRANSMIT_PACKETS, sizeof(PACKET_RESERVED)); if (AllocStatus != NDIS_STATUS_SUCCESS) { // not enough memory NdisFreeMemory(oiNew, sizeof(OPEN_INSTANCE), 0); *pStatus = NDIS_STATUS_RESOURCES; return; } // Allocate a buffer pool for our xmit and receive buffers NdisAllocateBufferPool(&AllocStatus, &(oiNew->BufferPool), TRANSMIT_PACKETS); if (AllocStatus != NDIS_STATUS_SUCCESS) { // not enough memory NdisFreeMemory(oiNew, sizeof(OPEN_INSTANCE), 0); *pStatus = NDIS_STATUS_RESOURCES; return; } // list to hold irp's that want to reset the adapter NdisAllocateSpinLock(&oiNew->ResetSpinLock); InitializeListHead(&oiNew->ResetIrpList); // Initialize list for holding pending read requests NdisAllocateSpinLock(&oiNew->RcvQSpinLock); InitializeListHead(&oiNew->RcvList); // Initialize the request list NdisAllocateSpinLock(&oiNew->RequestSpinLock); InitializeListHead(&oiNew->RequestList); // link up the request stored in our open block for (i = 0; i < MAX_REQUESTS; i++) { // Braces are required as InsertTailList macro has multiple statements in it InsertTailList(&oiNew->RequestList, &oiNew->Requests[i].Reserved.ListElement); } // Try to open the MAC NdisOpenAdapter(pStatus, &ErrorStatus, &oiNew->AdapterHandle, &Medium, &MediumArray, 1, GlobalDeviceExtension->NdisProtocolHandle, oiNew, pAdapterName, 0, NULL); // Save the status returned by NdisOpenAdapter for completion routine oiNew->Status = *pStatus; switch (*pStatus) { case NDIS_STATUS_PENDING: break; case NDIS_STATUS_SUCCESS: ErrorStatus = NDIS_STATUS_SUCCESS; // fall through to completion routine with oiNew->Status // set to !NDIS_STATUS_PENDING default: PacketBindAdapterComplete(oiNew, *pStatus, ErrorStatus); break; } }
DWORD PacketOpen(PNDIS_STRING AdapterName,DWORD dwDDB,DWORD hDevice,PDIOCPARAMETERS pDiocParms) { LARGE_INTEGER SystemTime; __int64 ltime1; PDEVICE_EXTENSION pde; POPEN_INSTANCE oiNew; NDIS_STATUS nsErrorStatus, nsOpenStatus; UINT i; UINT uiMedium; NDIS_STRING NameStr; NDIS_STATUS Status; pde = GlobalDeviceExtension; /*Allocate an element that describe an adapter*/ NdisAllocateMemory( (PVOID *)&oiNew, sizeof( OPEN_INSTANCE ), 0, -1 ); if ( oiNew == NULL ) { return NDIS_STATUS_FAILURE; } NdisZeroMemory( (PVOID)oiNew, sizeof( OPEN_INSTANCE ) ); /*allocate a pool for the packet headers*/ NdisAllocatePacketPool( &nsErrorStatus, &(oiNew->PacketPool), TRANSMIT_PACKETS, sizeof(PACKET_RESERVED) ); IF_TRACE_MSG( "PACKET_RESERVED_a :%lx",sizeof(PACKET_RESERVED)); if ( nsErrorStatus != NDIS_STATUS_SUCCESS ) { IF_TRACE_MSG( "Failed to allocate packet pool AllocStatus=%x", nsErrorStatus ); NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) , 0 ); TRACE_LEAVE( "BindAdapter" ); return NDIS_STATUS_FAILURE; } /*allocate a buffer pool for the packet data*/ NdisAllocateBufferPool( &nsErrorStatus, &(oiNew->BufferPool), TRANSMIT_PACKETS ); if ( nsErrorStatus != NDIS_STATUS_SUCCESS ) { IF_TRACE_MSG( "Failed to allocate packet pool AllocStatus=%x", nsErrorStatus ); NdisFreePacketPool( oiNew->PacketPool ); NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) , 0 ); TRACE_LEAVE( "BindAdapter" ); return NDIS_STATUS_FAILURE; } NdisAllocateSpinLock( &(oiNew->ResetSpinLock) ); InitializeListHead( &(oiNew->ResetIrpList) ); NdisAllocateSpinLock( &(oiNew->RcvQSpinLock) ); InitializeListHead( &(oiNew->RcvList) ); NdisAllocateSpinLock( &(oiNew->RequestSpinLock) ); InitializeListHead( &(oiNew->RequestList) ); for ( i=0; i<MAX_REQUESTS; i++ ) { InsertTailList( &(oiNew->RequestList), &(oiNew->Requests[i].Reserved.ListElement) ); } oiNew->Status = NDIS_STATUS_PENDING; /*initialize the timer variables for this session*/ SystemTime=GetDate(); ltime1=((__int64)SystemTime.HighPart*86400); ltime1+=(__int64)(SystemTime.LowPart/1000); //current time from 1980 in seconds ltime1+=(__int64)315532800; //current time from 1970 (Unix format) in seconds ltime1*=1193182; ltime1+=(SystemTime.LowPart%1000)*1193182/1000; //current time from 1970 in ticks ltime1-=QuerySystemTime(); //boot time from 1970 in ticks oiNew->StartTime=ltime1; oiNew->Dropped=0; //reset the dropped packets counter oiNew->Received=0; //reset the received packets counter oiNew->bpfprogram=NULL; //set an accept-all filter oiNew->bpfprogramlen=0; oiNew->BufSize=0; //set an empty buffer oiNew->Buffer=NULL; //reset the buffer oiNew->Bhead=0; oiNew->Btail=0; oiNew->BLastByte=0; oiNew->TimeOut=0; //reset the timeouts oiNew->ReadTimeoutTimer=0; oiNew->mode=0; //set capture mode oiNew->Nbytes=0; //reset the counters oiNew->Npackets=0; oiNew->hDevice=hDevice; oiNew->tagProcess=pDiocParms->tagProcess; oiNew->ReadEvent=0; //reset the read event NdisAllocateSpinLock( &(oiNew->CountersLock) ); /*open the MAC driver calling NDIS*/ NdisOpenAdapter( &nsOpenStatus, &nsErrorStatus, &oiNew->AdapterHandle, &uiMedium, MediumArray, NUM_NDIS_MEDIA, pde->NdisProtocolHandle, oiNew, AdapterName, 0, NULL ); IF_TRACE_MSG( "Open Status : %lx", nsOpenStatus ); IF_TRACE_MSG( "Error Status : %lx", nsErrorStatus ); IF_TRACE_MSG( "Completion Status : %lx", oiNew->Status ); if ( nsOpenStatus == NDIS_STATUS_PENDING ) { while ( oiNew->Status == NDIS_STATUS_PENDING ) YieldExecution(); } else { PacketOpenAdapterComplete( oiNew, nsOpenStatus, nsErrorStatus ); } Status = oiNew->Status; if ( Status != NDIS_STATUS_SUCCESS ) { NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) , 0 ); return NDIS_STATUS_FAILURE; } else { } TRACE_LEAVE( "BindAdapter" ); /*return succesfully*/ return STATUS_SUCCESS; }
/************************************************************ Function used by NDIS to update the VXD when a new MAC driver is added ************************************************************/ VOID NDIS_API PacketBindAdapter( OUT PNDIS_STATUS Status, IN NDIS_HANDLE BindAdapterContext, IN PNDIS_STRING AdapterName, IN PVOID SystemSpecific1, IN PVOID SystemSpecific2 ) { PDEVICE_EXTENSION pde; POPEN_INSTANCE oiNew; NDIS_STATUS nsErrorStatus, nsOpenStatus; UINT uiMedium; UINT i; PWRAPPER_PROTOCOL_BLOCK pWPBlock; PNDIS_PROTOCOL_CHARACTERISTICS pNPChar; PADAPTER_NAME AName; PWRAPPER_MAC_BLOCK pWMBlock; PNDIS_MAC_CHARACTERISTICS pNMChar; BYTE *lpzName; TRACE_ENTER( "BindAdapter" ); pde = GlobalDeviceExtension; /*Allocate an element that describe an adapter*/ NdisAllocateMemory( (PVOID *)&AName, sizeof(ADAPTER_NAME), 0, -1 ); if ( AName == NULL ) { *Status = NDIS_STATUS_RESOURCES; return; } NdisAllocateMemory( (PVOID *)&oiNew, sizeof( OPEN_INSTANCE ), 0, -1 ); if ( oiNew == NULL ) { *Status = NDIS_STATUS_RESOURCES; return; } NdisZeroMemory( (PVOID)oiNew, sizeof( OPEN_INSTANCE ) ); /*Save Binding Context*/ oiNew->BindAdapterContext = BindAdapterContext; /*Save the device handle*/ oiNew->hDevice = (DWORD) SystemSpecific1; /*allocate a pool for the packet headers*/ NdisAllocatePacketPool( &nsErrorStatus, &(oiNew->PacketPool), TRANSMIT_PACKETS, sizeof(PACKET_RESERVED) ); IF_TRACE_MSG( "PACKET_RESERVED_b :%lx",sizeof(PACKET_RESERVED)); if ( nsErrorStatus != NDIS_STATUS_SUCCESS ) { IF_TRACE_MSG( "Failed to allocate packet pool AllocStatus=%x", nsErrorStatus ); NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) , 0 ); *Status = NDIS_STATUS_RESOURCES; TRACE_LEAVE( "BindAdapter" ); return; } /*allocate a pool for the packet data*/ NdisAllocateBufferPool( &nsErrorStatus, &(oiNew->BufferPool), TRANSMIT_PACKETS ); if ( nsErrorStatus != NDIS_STATUS_SUCCESS ) { IF_TRACE_MSG( "Failed to allocate packet pool AllocStatus=%x", nsErrorStatus ); NdisFreePacketPool( oiNew->PacketPool ); NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) , 0 ); *Status = NDIS_STATUS_RESOURCES; TRACE_LEAVE( "BindAdapter" ); return; } NdisAllocateSpinLock( &(oiNew->ResetSpinLock) ); InitializeListHead( &(oiNew->ResetIrpList) ); NdisAllocateSpinLock( &(oiNew->RcvQSpinLock) ); InitializeListHead( &(oiNew->RcvList) ); NdisAllocateSpinLock( &(oiNew->RequestSpinLock) ); InitializeListHead( &(oiNew->RequestList) ); for ( i=0; i<MAX_REQUESTS; i++ ) { InsertTailList( &(oiNew->RequestList), &(oiNew->Requests[i].Reserved.ListElement) ); } oiNew->Status = NDIS_STATUS_PENDING; oiNew->BindAdapterContext = BindAdapterContext; /*open the MAC driver calling NDIS*/ oiNew->hDevice=0; oiNew->tagProcess=0; NdisOpenAdapter( &nsOpenStatus, &nsErrorStatus, &oiNew->AdapterHandle, &uiMedium, MediumArray, NUM_NDIS_MEDIA, pde->NdisProtocolHandle, oiNew, AdapterName, 0, NULL ); IF_TRACE_MSG( "Open Status : %lx", nsOpenStatus ); IF_TRACE_MSG( "Error Status : %lx", nsErrorStatus ); IF_TRACE_MSG( "Completion Status : %lx", oiNew->Status ); if ( nsOpenStatus == NDIS_STATUS_PENDING ) { while ( oiNew->Status == NDIS_STATUS_PENDING ) YieldExecution(); } else { PacketOpenAdapterComplete( oiNew, nsOpenStatus, nsErrorStatus ); } pWPBlock = ((PWRAPPER_OPEN_BLOCK)(oiNew->AdapterHandle))->ProtocolHandle; pNPChar = &pWPBlock->ProtocolCharacteristics; IF_TRACE_MSG( "Protocol : %s", pNPChar->Name.Buffer ); IF_TRACE_MSG( "Protocol Handle : %lx", pde->NdisProtocolHandle ); IF_TRACE_MSG( "PWRAPPER_OPEN_BLOCK : %lx", oiNew->AdapterHandle ); IF_TRACE_MSG( "PWRAPPER_PROTOCOL_BLOCK : %lx", pWPBlock ); IF_TRACE_MSG( "NDIS_PROTOCOL_CHARACTERISTICS : %lx", pNPChar ); IF_TRACE_MSG( "Name : %lx", &pNPChar->Name ); IF_TRACE_MSG( "Adapter Name : %s", AdapterName->Buffer ); *Status = oiNew->Status; if ( *Status != NDIS_STATUS_SUCCESS ) { NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) , 0 ); IF_TRACE( "Bind Operation FAILED!" ); } else { AName->realnamestr.Length=AdapterName->Length; AName->realnamestr.MaximumLength=AdapterName->MaximumLength; AName->realnamestr.Buffer=AName->realname; for(i=0; i<32; i++)AName->realname[i]=AdapterName->Buffer[i]; pWMBlock = ((PWRAPPER_OPEN_BLOCK)(oiNew->AdapterHandle))->MacHandle; pNMChar = &pWMBlock->MacCharacteristics; lpzName = pNMChar->Name.Buffer; for(i=0; i<32; i++)AName->devicename[i]=lpzName[i]; InsertTailList( &GlobalDeviceExtension->AdapterNames, &AName->ListElement); //close the adapter NdisCloseAdapter(&nsErrorStatus,oiNew->AdapterHandle); if ( nsErrorStatus == NDIS_STATUS_PENDING ) { while ( oiNew->Status == NDIS_STATUS_PENDING ) YieldExecution(); } else { PacketUnbindAdapterComplete( oiNew, nsErrorStatus ); } *Status = oiNew->Status; if ( *Status == NDIS_STATUS_SUCCESS ) { //remove this adapter from the list of open adapters RemoveEntryList(&(oiNew->ListElement)); //free the memory NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) , 0 ); } else { IF_TRACE( "Close Operation FAILED!" ); } } TRACE_LEAVE( "BindAdapter" ); return; }
/* * Opens the specified adapter and binds the protocol to it * * Arguments * AdapterName - The name of the adapter with which binding should happen * * Return Value * Return TRUE if successfully bound otherwise returns FALSE * */ BOOL PKTOpenAdapter (PNDIS_STRING pAdapterName) { POPEN_INSTANCE pOI; NDIS_STATUS nsOpen; NDIS_STATUS nsError; SYSTEMTIME SystemTime; FILETIME FileTime; LARGE_INTEGER liSysTime; LARGE_INTEGER TimeFreq; LARGE_INTEGER PTime; UINT uiMedium; // Check if an instance is already opened if (g_pDeviceExtension->pOpenInstance) { SetLastError (ERROR_ALREADY_INITIALIZED); return FALSE; } // Time initialization GetSystemTime (&SystemTime); if (! (SystemTimeToFileTime (&SystemTime, &FileTime) && QueryPerformanceCounter (&PTime) && QueryPerformanceFrequency (&TimeFreq))) { return FALSE; } NdisMoveMemory (&liSysTime, &FileTime, sizeof (LARGE_INTEGER)); // allocate an instance that describes the adapter NdisAllocateMemory (&pOI, sizeof (OPEN_INSTANCE), 0, NDIS_ADDR_M1); if (pOI == NULL) { return FALSE; } NdisZeroMemory (pOI, sizeof (OPEN_INSTANCE)); // init struct variables pOI->bpfprogram = NULL; //set an accept-all filter pOI->bpfprogramlen = 0; pOI->BufSize = 0; //set an empty buffer pOI->Buffer = NULL; //reset the buffer pOI->Bhead = 0; pOI->Btail = 0; pOI->BLastByte = 0; pOI->TimeOut = 0; //reset the timeouts // create the shared name read event pOI->ReadEvent = CreateEvent (NULL, FALSE, FALSE, SH_EVENT_NAME); if (pOI->ReadEvent == NULL) { NdisFreeMemory (pOI, sizeof (OPEN_INSTANCE), 0); return FALSE; } // set time values pOI->StartTime.QuadPart = (((liSysTime.QuadPart) % 10000000) * TimeFreq.QuadPart)/10000000; liSysTime.QuadPart = liSysTime.QuadPart / 10000000 - 11644473600; pOI->StartTime.QuadPart += (liSysTime.QuadPart) * TimeFreq.QuadPart - PTime.QuadPart; // allocate pool for the packet headers NdisAllocatePacketPool (&nsError, &(pOI->PacketPool), TRANSMIT_PACKETS, sizeof (PACKET_RESERVED)); if (nsError != NDIS_STATUS_SUCCESS) { CloseHandle (pOI->ReadEvent); NdisFreeMemory (pOI, sizeof (OPEN_INSTANCE), 0); return FALSE; } // allocate buffer pool for the packet data NdisAllocateBufferPool (&nsError, &(pOI->BufferPool), TRANSMIT_PACKETS); if (nsError != NDIS_STATUS_SUCCESS) { CloseHandle (pOI->ReadEvent); NdisFreePacketPool (pOI->PacketPool); NdisFreeMemory (pOI, sizeof (OPEN_INSTANCE), 0); return FALSE; } // set status pending pOI->Status = NDIS_STATUS_PENDING; // open the MAC driver NdisOpenAdapter (&nsOpen, &nsError, &pOI->AdapterHandle, &uiMedium, MediumArray, NUM_NDIS_MEDIA, g_pDeviceExtension->NdisProtocolHandle, pOI, pAdapterName, 0, NULL); if (nsOpen == NDIS_STATUS_PENDING) { SuspendExecution (pOI); } else { PacketOpenAdapterComplete (pOI, nsOpen, nsError); } // free the packet instance if not successful if (pOI->Status != NDIS_STATUS_SUCCESS) { CloseHandle (pOI->ReadEvent); NdisFreeMemory (pOI, sizeof (OPEN_INSTANCE), 0); return FALSE; } return TRUE; }