static void WaitHaltEvent(PARANDIS_ADAPTER *pContext, const char *Reason) { UINT ms = 5000; if (!NdisWaitEvent(&pContext->HaltEvent, 1)) { while (!NdisWaitEvent(&pContext->HaltEvent, ms)) { DPrintf(0, ("[%s]", __FUNCTION__)); } } }
NTSTATUS DispatchCleanup( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { POPEN_INSTANCE pOpen = (POPEN_INSTANCE)DeviceObject->DeviceExtension; NTSTATUS status = STATUS_SUCCESS; if(DeviceObject == g_data.pControlDevice) { Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } IoIncrement(pOpen); CancelReadIrp(DeviceObject); IoDecrement(pOpen); NdisWaitEvent(&pOpen->CleanupEvent, 0); Irp->IoStatus.Information = 0; Irp->IoStatus.Status = status; IoCompleteRequest (Irp, IO_NO_INCREMENT); return status; }
DWORD hifIRQThread(void *Context) { A_STATUS status = A_OK; HIF_DEVICE *device; device = (HIF_DEVICE *)Context; NDIS_DEBUG_PRINTF(DBG_LEVEL_HIF, " %s() is Running... \r\n",__FUNCTION__); while (TRUE) { NdisWaitEvent(&hifIRQEvent, 0); NdisResetEvent(&hifIRQEvent); NDIS_DEBUG_PRINTF(DBG_TRACE, "%s() - Running & ",__FUNCTION__); status = device->htcCallbacks.dsrHandler(device->htcCallbacks.context); AR_DEBUG_ASSERT(status == A_OK); NDIS_DEBUG_PRINTF(DBG_TRACE, " Exit \r\n"); SDIOConnectInterrupt(device->handle,hifIRQHandler); } // while return SD_API_STATUS_SUCCESS; }
/*----------------------------------------------------------------------------- * Function: MPT_DeInitAdapter() * * Overview: Extra DeInitialization for Mass Production Test. * * Input: PADAPTER pAdapter * * Output: NONE * * Return: NONE * * Revised History: * When Who Remark * 05/08/2007 MHC Create Version 0. * 05/18/2007 MHC Add normal driver MPHalt code. * *---------------------------------------------------------------------------*/ VOID MPT_DeInitAdapter( IN PADAPTER pAdapter ) { PMPT_CONTEXT pMptCtx = &pAdapter->mppriv.MptCtx; pMptCtx->bMptDrvUnload = _TRUE; #ifdef CONFIG_RTL8723A _rtw_free_sema(&(pMptCtx->MPh2c_Sema)); _cancel_timer_ex( &pMptCtx->MPh2c_timeout_timer); #endif #if 0 // for Windows PlatformFreeWorkItem( &(pMptCtx->MptWorkItem) ); while(pMptCtx->bMptWorkItemInProgress) { if(NdisWaitEvent(&(pMptCtx->MptWorkItemEvent), 50)) { break; } } NdisFreeSpinLock( &(pMptCtx->MptWorkItemSpinLock) ); #endif }
VOID NPF_CloseOpenInstance( IN POPEN_INSTANCE pOpen ) { ULONG i = 0; NDIS_EVENT Event; ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); NdisInitializeEvent(&Event); NdisResetEvent(&Event); NdisAcquireSpinLock(&pOpen->OpenInUseLock); pOpen->ClosePending = TRUE; while(pOpen->NumPendingIrps > 0) { NdisReleaseSpinLock(&pOpen->OpenInUseLock); NdisWaitEvent(&Event,1); NdisAcquireSpinLock(&pOpen->OpenInUseLock); } NdisReleaseSpinLock(&pOpen->OpenInUseLock); }
VOID MiniportHalt5( IN NDIS_HANDLE MiniportAdapterContext ) { PADAPTER pAdapt = (PADAPTER)MiniportAdapterContext; NDIS_STATUS Status; // // Delete the ioctl interface that was created when the miniport // was created. // (VOID)ProtocolDeregisterDevice(); #ifdef _DEBUG // 关闭直接包发送接口 if(pAdapt->FileObject) { // // Make sure any threads trying to send have finished. // pAdapt->FileObject->FsContext = NULL; pAdapt->FileObject = NULL; } #endif // // If we have a valid bind, close the miniport below the protocol // if (pAdapt->BindingHandle != NULL) { // // Close the binding below. and wait for it to complete // NdisResetEvent(&pAdapt->Event); NdisCloseAdapter(&Status, pAdapt->BindingHandle); if (Status == NDIS_STATUS_PENDING) { NdisWaitEvent(&pAdapt->Event, 0); Status = pAdapt->Status; } ASSERT (Status == NDIS_STATUS_SUCCESS); pAdapt->BindingHandle = NULL; } // // Free all resources on this adapter structure. // MiniportFreeAllPacketPools5(pAdapt); NdisFreeSpinLock(&pAdapt->Lock); NdisFreeMemory(pAdapt, 0, 0); }
VOID ParaNdis_Suspend(PARANDIS_ADAPTER *pContext) { DEBUG_ENTRY(0); NdisResetEvent(&pContext->ResetEvent); if (NDIS_STATUS_PENDING != ParaNdis5_StopSend(pContext, TRUE, OnSendStoppedOnReset)) { NdisSetEvent(&pContext->ResetEvent); } NdisWaitEvent(&pContext->ResetEvent, 0); NdisResetEvent(&pContext->ResetEvent); if (NDIS_STATUS_PENDING != ParaNdis5_StopReceive(pContext, TRUE, OnReceiveStoppedOnReset)) { NdisSetEvent(&pContext->ResetEvent); } NdisWaitEvent(&pContext->ResetEvent, 0); NdisResetEvent(&pContext->ResetEvent); DEBUG_EXIT_STATUS(0, 0); }
static VOID VenetQuiesce(PADAPTER a) { /* we are shutting down, deal with remaining packets. */ UNREFERENCED_PARAMETER(a); /* Wait for any outstanding TX to complete. */ NdisWaitEvent(&a->sendEvent, 0); }
void CAR6KMini::IndicateReceivePackets() // // This function is called on the worker thread to indicate received // packets. // { NDIS_PACKET *pPacket; NDIS_PACKET *PacketArray[MAX_PACKETS_PER_INDICATE]; ULONG NumPacketsToIndicate; LIST_ENTRY *pNode; boolean bEventSignalled; NdisResetEvent(&m_RxWorkItemExitedEvent); while (false == m_Halting) { // Wait for packets to be placed on the list bEventSignalled = NdisWaitEvent(&m_RxPendingEvent, 0); if (m_Halting || !bEventSignalled) break; NumPacketsToIndicate = 0; // // Get up to MAX_PACKET_PER_INDICATE packets from the RxPending list. // Put the packet pointers into an array. // Lock(); while (!IsListEmpty(&m_RxPendingPacketList)) { pNode = RemoveHeadList(&m_RxPendingPacketList); pPacket = (PNDIS_PACKET)((PBYTE)pNode - offsetof(NDIS_PACKET, MiniportReserved)); PacketArray[NumPacketsToIndicate++] = pPacket; if (NumPacketsToIndicate == MAX_PACKETS_PER_INDICATE) { Unlock(); NdisMIndicateReceivePacket(m_MiniportAdapterHandle, PacketArray, NumPacketsToIndicate); Lock(); NumPacketsToIndicate = 0; } } NdisResetEvent(&m_RxPendingEvent); Unlock(); // // Indicate the received packets up to protocol drivers bound to us. // if (NumPacketsToIndicate) NdisMIndicateReceivePacket(m_MiniportAdapterHandle, PacketArray, NumPacketsToIndicate); } NdisSetEvent(&m_RxWorkItemExitedEvent); }
VOID ParaNdis_Suspend(PARANDIS_ADAPTER *pContext) { DPrintf(0, ("[%s]%s\n", __FUNCTION__, pContext->bFastSuspendInProcess ? "(Fast)" : "")); NdisResetEvent(&pContext->ResetEvent); if (NDIS_STATUS_PENDING != ParaNdis6_SendPauseRestart(pContext, TRUE, OnSendPauseCompleteOnReset)) { NdisSetEvent(&pContext->ResetEvent); } NdisWaitEvent(&pContext->ResetEvent, 0); if (!pContext->bFastSuspendInProcess) { NdisResetEvent(&pContext->ResetEvent); if (NDIS_STATUS_PENDING != ParaNdis6_ReceivePauseRestart(pContext, TRUE, OnReceivePauseCompleteOnReset)) { NdisSetEvent(&pContext->ResetEvent); } NdisWaitEvent(&pContext->ResetEvent, 0); } else { ParaNdis6_ReceivePauseRestart(pContext, TRUE, NULL); } DEBUG_EXIT_STATUS(0, 0); }
//------------------------------------------------------------------------------ void eventkcal_getEventForUser(void* pEvent_p, size_t* pSize_p) { tOplkError error; BOOL fRet; UINT32 timeout = 500; // Check parameter validity ASSERT(pEvent_p != NULL); ASSERT(pSize_p != NULL); if (!instance_l.fInitialized) return; fRet = NdisWaitEvent(&instance_l.userWaitEvent, timeout); if (fRet && (instance_l.userEventCount == 0)) { NdisResetEvent(&instance_l.userWaitEvent); return; } NdisResetEvent(&instance_l.userWaitEvent); // Kernel-to-user queue is processed with higher priority. if (eventkcal_getEventCountCircbuf(kEventQueueK2U) > 0) { NdisInterlockedDecrement(&instance_l.userEventCount); error = eventkcal_getEventCircbuf(kEventQueueK2U, pEvent_p, pSize_p); if ((error != kErrorOk) || (pEvent_p == NULL)) { DEBUG_LVL_ERROR_TRACE("%s() Error reading K2U events %d!\n", __func__, error); } return; } else if (eventkcal_getEventCountCircbuf(kEventQueueUInt) > 0) { NdisInterlockedDecrement(&instance_l.userEventCount); error = eventkcal_getEventCircbuf(kEventQueueUInt, pEvent_p, pSize_p); if (error != kErrorOk) { DEBUG_LVL_ERROR_TRACE("%s() Error reading UINT events %d!\n", __func__, error); return; } } }
static void shared_dpc_thread(void *h) { shared_info_t *sh = (shared_info_t *)h; /* Read the priority from registry */ CeSetThreadPriority(GetCurrentThread(), sh->DPCPriority); while (TRUE) { NdisWaitEvent(&sh->dpc_event, 0); /* wait forever */ NdisResetEvent(&sh->dpc_event); /* reset the event */ (sh->dpc_cb)(sh->dpc_arg); } }
VOID tapWaitForReceiveNblInFlightCountZeroEvent(__in PTAP_ADAPTER_CONTEXT Adapter) { LONG nblCount; // // Wait until higher-level protocol has returned all NBLs // to the driver. // // Add one NBL "bias" to insure allow event to be reset safely. nblCount = NdisInterlockedIncrement(&Adapter->ReceiveNblInFlightCount); ASSERT(nblCount > 0); NdisResetEvent(&Adapter->ReceiveNblInFlightCountZeroEvent); // // Now remove the bias and wait for the ReceiveNblInFlightCountZeroEvent // if the count returned is not zero. // nblCount = NdisInterlockedDecrement(&Adapter->ReceiveNblInFlightCount); ASSERT(nblCount >= 0); if (nblCount) { LARGE_INTEGER startTime, currentTime; NdisGetSystemUpTimeEx(&startTime); for (;;) { BOOLEAN waitResult = NdisWaitEvent(&Adapter->ReceiveNblInFlightCountZeroEvent, TAP_WAIT_POLL_LOOP_TIMEOUT); NdisGetSystemUpTimeEx(¤tTime); if (waitResult) { break; } DEBUGP(("[%s] Waiting for %d in-flight receive NBLs to be returned.\n", MINIPORT_INSTANCE_ID(Adapter), Adapter->ReceiveNblInFlightCount)); } DEBUGP(("[%s] Waited %d ms for all in-flight NBLs to be returned.\n", MINIPORT_INSTANCE_ID(Adapter), (currentTime.LowPart - startTime.LowPart))); } }
DWORD hifIRQThread(LPVOID Context) { SD_DEVICE_HANDLE hDevice = Context; A_STATUS status; HIF_DEVICE *device; if (hDevice == NULL) { return SD_API_STATUS_UNSUCCESSFUL; } while (1) { NdisWaitEvent(&hifIRQEvent, 0); NdisResetEvent(&hifIRQEvent); device = getHifDevice(hDevice); status = htcCallbacks.dsrHandler(device); AR_DEBUG_ASSERT(status == A_OK); } // while return SD_API_STATUS_SUCCESS; }
//------------------------------------------------------------------------------ static void eventThread(void* pArg) { INT timeout = 50; PKTHREAD thread; BOOL fRet = FALSE; UNUSED_PARAMETER(pArg); // increase the priority of the thread thread = KeGetCurrentThread(); KeSetPriorityThread(thread, HIGH_PRIORITY); instance_l.fThreadIsRunning = TRUE; while (!instance_l.fStopThread) { fRet = NdisWaitEvent(&instance_l.kernelWaitEvent, timeout); if (fRet && (instance_l.kernelEventCount == 0)) { // Timeout occurred, continue to wait. NdisResetEvent(&instance_l.kernelWaitEvent); continue; } NdisResetEvent(&instance_l.kernelWaitEvent); /* first handle all kernel internal events --> higher priority! */ while (eventkcal_getEventCountCircbuf(kEventQueueKInt) > 0) { eventkcal_processEventCircbuf(kEventQueueKInt); NdisInterlockedDecrement(&instance_l.kernelEventCount); } if (eventkcal_getEventCountCircbuf(kEventQueueU2K) > 0) { eventkcal_processEventCircbuf(kEventQueueU2K); NdisInterlockedDecrement(&instance_l.kernelEventCount); } } instance_l.fThreadIsRunning = FALSE; }
/*----------------------------------------------------------------------------- * Function: MPT_DeInitAdapter() * * Overview: Extra DeInitialization for Mass Production Test. * * Input: PADAPTER pAdapter * * Output: NONE * * Return: NONE * * Revised History: * When Who Remark * 05/08/2007 MHC Create Version 0. * 05/18/2007 MHC Add normal driver MPHalt code. * *---------------------------------------------------------------------------*/ VOID MPT_DeInitAdapter( IN PADAPTER pAdapter ) { PMPT_CONTEXT pMptCtx = &pAdapter->mppriv.MptCtx; pMptCtx->bMptDrvUnload = _TRUE; #if 0 // for Windows PlatformFreeWorkItem( &(pMptCtx->MptWorkItem) ); while(pMptCtx->bMptWorkItemInProgress) { if(NdisWaitEvent(&(pMptCtx->MptWorkItemEvent), 50)) { break; } } NdisFreeSpinLock( &(pMptCtx->MptWorkItemSpinLock) ); #endif }
VOID VenetHalt(NDIS_HANDLE handle, NDIS_HALT_ACTION action) { PADAPTER a = (PADAPTER) handle; UNREFERENCED_PARAMETER(action); vlog("halt called"); VENET_SET_SYNC_FLAG(a, VNET_ADAPTER_HALT_IN_PROGRESS); VenetDetach(a); VenetFreeQueuedSend(a, NDIS_STATUS_FAILURE); /* Now dec and wait for the remove event */ VENET_ADAPTER_PUT(a); NdisWaitEvent(&a->removeEvent, 5000); /* Free resources */ NdisFreeSpinLock(&a->Lock); if (a->resetTimer) NdisFreeTimerObject(a->resetTimer); if (a->recvTimer) NdisFreeTimerObject(a->recvTimer); if (a->dmaHandle) NdisMDeregisterScatterGatherDma(a->dmaHandle); VenetFreeRx(a); VenetFreeTx(a); if (a->vif.close) a->vif.close(a->bus_handle); NdisFreeSpinLock(&a->sendLock); NdisFreeSpinLock(&a->recvLock); VenetFree(a, sizeof(ADAPTER)); }
NTSTATUS PacketCleanup(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { // This is the dispatch routine for cleanup requests. // This routine is called whenever a handle to the device is closed. POPEN_INSTANCE open; NTSTATUS status = STATUS_SUCCESS; DebugPrint(("Packet: Cleanup\n")); if (DeviceObject == Globals.ControlDeviceObject) { Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } open = DeviceObject->DeviceExtension; IoIncrement(open); // Cancel all the pending reads. PacketCancelReadIrps(DeviceObject); // Since the current implementation of NDIS doesn't // allow us to cancel requests pending at the // miniport, we must wait here until they complete. IoDecrement(open); NdisWaitEvent(&open->CleanupEvent, 0); Irp->IoStatus.Information = 0; Irp->IoStatus.Status = status; IoCompleteRequest (Irp, IO_NO_INCREMENT); return status; }
/*----------------------------------------------------------------------------- * Function: MPT_DeInitAdapter() * * Overview: Extra DeInitialization for Mass Production Test. * * Input: PADAPTER pAdapter * * Output: NONE * * Return: NONE * * Revised History: * When Who Remark * 05/08/2007 MHC Create Version 0. * 05/18/2007 MHC Add normal driver MPHalt code. * *---------------------------------------------------------------------------*/ VOID MPT_DeInitAdapter( IN PADAPTER pAdapter ) { PMPT_CONTEXT pMptCtx = &pAdapter->mppriv.MptCtx; pMptCtx->bMptDrvUnload = _TRUE; #ifdef CONFIG_RTL8723A _rtw_free_sema(&(pMptCtx->MPh2c_Sema)); _cancel_timer_ex( &pMptCtx->MPh2c_timeout_timer); rtw_write32(pAdapter, 0xcc, (rtw_read32(pAdapter, 0xcc)& 0xFFFFFFFD)| 0x00000002); rtw_write32(pAdapter, 0x6b, (rtw_read32(pAdapter, 0x6b)& 0xFFFFFFFB)); rtw_msleep_os(500); rtw_write32(pAdapter, 0x6b, (rtw_read32(pAdapter, 0x6b)& 0xFFFFFFFB)| 0x00000004); rtw_write32(pAdapter, 0xcc, (rtw_read32(pAdapter, 0xcc)& 0xFFFFFFFD)); rtw_msleep_os(1000); DBG_871X("_rtw_mp_xmit_priv reinit for normal mode\n"); _rtw_mp_xmit_priv(&pAdapter->xmitpriv); #endif #if 0 // for Windows PlatformFreeWorkItem( &(pMptCtx->MptWorkItem) ); while(pMptCtx->bMptWorkItemInProgress) { if(NdisWaitEvent(&(pMptCtx->MptWorkItemEvent), 50)) { break; } } NdisFreeSpinLock( &(pMptCtx->MptWorkItemSpinLock) ); #endif }
/* * -------------------------------------------------------------------------- * Utility function to issue the specified OID to the NDIS stack. The OID is * directed towards the miniport edge of the extensible switch. * An OID that gets issued may not complete immediately, and in such cases, the * function waits for the OID to complete. Thus, this function must not be * called at the PASSIVE_LEVEL. * -------------------------------------------------------------------------- */ static NDIS_STATUS OvsIssueOidRequest(POVS_SWITCH_CONTEXT switchContext, NDIS_REQUEST_TYPE oidType, UINT32 oidRequestEnum, PVOID oidInputBuffer, UINT32 inputSize, PVOID oidOutputBuffer, UINT32 outputSize, UINT32 *outputSizeNeeded) { NDIS_STATUS status; PNDIS_OID_REQUEST oidRequest; POVS_OID_CONTEXT oidContext; ULONG OvsExtOidRequestId = 'ISVO'; DBG_UNREFERENCED_PARAMETER(inputSize); DBG_UNREFERENCED_PARAMETER(oidInputBuffer); OVS_LOG_TRACE("Enter: switchContext: %p, oidType: %d", switchContext, oidType); ASSERT(oidInputBuffer == NULL || inputSize != 0); ASSERT(oidOutputBuffer == NULL || outputSize != 0); ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); oidRequest = OvsAllocateMemoryWithTag(sizeof *oidRequest, OVS_OID_POOL_TAG); if (!oidRequest) { status = NDIS_STATUS_RESOURCES; goto done; } oidContext = OvsAllocateMemoryWithTag(sizeof *oidContext, OVS_OID_POOL_TAG); if (!oidContext) { OvsFreeMemoryWithTag(oidRequest, OVS_OID_POOL_TAG); status = NDIS_STATUS_RESOURCES; goto done; } RtlZeroMemory(oidRequest, sizeof *oidRequest); RtlZeroMemory(oidContext, sizeof *oidContext); oidRequest->Header.Type = NDIS_OBJECT_TYPE_OID_REQUEST; oidRequest->Header.Revision = NDIS_OID_REQUEST_REVISION_1; oidRequest->Header.Size = NDIS_SIZEOF_OID_REQUEST_REVISION_1; oidRequest->RequestType = oidType; oidRequest->PortNumber = 0; oidRequest->Timeout = 0; oidRequest->RequestId = (PVOID)OvsExtOidRequestId; switch(oidType) { case NdisRequestQueryInformation: oidRequest->DATA.QUERY_INFORMATION.Oid = oidRequestEnum; oidRequest->DATA.QUERY_INFORMATION.InformationBuffer = oidOutputBuffer; oidRequest->DATA.QUERY_INFORMATION.InformationBufferLength = outputSize; break; default: ASSERT(FALSE); status = NDIS_STATUS_INVALID_PARAMETER; break; } /* * We make use of the SourceReserved field in the OID request to store * pointers to the original OID (if any), and also context for completion * (if any). */ oidContext->status = NDIS_STATUS_SUCCESS; NdisInitializeEvent(&oidContext->oidComplete); OvsOidSetOrigRequest(oidRequest, NULL); OvsOidSetContext(oidRequest, oidContext); NdisInterlockedIncrement(&(switchContext->pendingOidCount)); status = NdisFOidRequest(switchContext->NdisFilterHandle, oidRequest); if (status == NDIS_STATUS_PENDING) { NdisWaitEvent(&oidContext->oidComplete, 0); } else { NdisInterlockedDecrement(&(switchContext->pendingOidCount)); } if (status == NDIS_STATUS_INVALID_LENGTH || oidContext->status == NDIS_STATUS_INVALID_LENGTH) { switch(oidType) { case NdisRequestQueryInformation: *outputSizeNeeded = oidRequest->DATA.QUERY_INFORMATION.BytesNeeded; } } status = oidContext->status; ASSERT(status != NDIS_STATUS_PENDING); OvsFreeMemoryWithTag(oidRequest, OVS_OID_POOL_TAG); OvsFreeMemoryWithTag(oidContext, OVS_OID_POOL_TAG); done: OVS_LOG_TRACE("Exit: status %8x.", status); return status; }
VOID MPHalt( IN NDIS_HANDLE MiniportAdapterContext ) /*++ Routine Description: Halt handler. All the hard-work for clean-up is done here. Arguments: MiniportAdapterContext Pointer to the Adapter Return Value: None. --*/ { PADAPT pAdapt = (PADAPT)MiniportAdapterContext; NDIS_STATUS Status; PADAPT *ppCursor; DBGPRINT(("==>MiniportHalt: Adapt %p\n", pAdapt)); // // Remove this adapter from the global list // NdisAcquireSpinLock(&GlobalLock); for (ppCursor = &pAdaptList; *ppCursor != NULL; ppCursor = &(*ppCursor)->Next) { if (*ppCursor == pAdapt) { *ppCursor = pAdapt->Next; break; } } NdisReleaseSpinLock(&GlobalLock); // // Make Suprise Unbind Notification // netgOnUnbindAdapter( pAdapt->pOpenContext ); // // Delete the ioctl interface that was created when the miniport // was created. // (VOID)PtDeregisterDevice(); if (pAdapt->BindingHandle != NULL) { NDIS_STATUS LocalStatus; // // Close the binding to the adapter // NdisResetEvent(&pAdapt->Event); NdisCloseAdapter(&LocalStatus, pAdapt->BindingHandle); pAdapt->BindingHandle = NULL; if (LocalStatus == NDIS_STATUS_PENDING) { NdisWaitEvent(&pAdapt->Event, 0); LocalStatus = pAdapt->Status; } ASSERT (LocalStatus == NDIS_STATUS_SUCCESS); } // // Remove Reference To The Adapter // PtDerefAdapter( pAdapt ); DBGPRINT(("<== MiniportHalt: pAdapt %p\n", pAdapt)); }
NTSTATUS NPF_GetDeviceMTU( IN POPEN_INSTANCE pOpen, IN PIRP pIrp, OUT PUINT pMtu) { PLIST_ENTRY RequestListEntry; PINTERNAL_REQUEST MaxSizeReq; NDIS_STATUS ReqStatus; TRACE_ENTER(); ASSERT(pOpen != NULL); ASSERT(pIrp != NULL); ASSERT(pMtu != NULL); // Extract a request from the list of free ones RequestListEntry = ExInterlockedRemoveHeadList(&pOpen->RequestList, &pOpen->RequestSpinLock); if (RequestListEntry == NULL) { // // THIS IS WRONG // // // Assume Ethernet // *pMtu = 1514; TRACE_EXIT(); return STATUS_SUCCESS; } MaxSizeReq = CONTAINING_RECORD(RequestListEntry, INTERNAL_REQUEST, ListElement); MaxSizeReq->Request.RequestType = NdisRequestQueryInformation; MaxSizeReq->Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAXIMUM_TOTAL_SIZE; MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBuffer = pMtu; MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(*pMtu); NdisResetEvent(&MaxSizeReq->InternalRequestCompletedEvent); // submit the request NdisRequest( &ReqStatus, pOpen->AdapterHandle, &MaxSizeReq->Request); if (ReqStatus == NDIS_STATUS_PENDING) { NdisWaitEvent(&MaxSizeReq->InternalRequestCompletedEvent, 0); ReqStatus = MaxSizeReq->RequestStatus; } // // Put the request in the list of the free ones // ExInterlockedInsertTailList(&pOpen->RequestList, &MaxSizeReq->ListElement, &pOpen->RequestSpinLock); if (ReqStatus == NDIS_STATUS_SUCCESS) { TRACE_EXIT(); return STATUS_SUCCESS; } else { // // THIS IS WRONG // // // Assume Ethernet // *pMtu = 1514; TRACE_EXIT(); return STATUS_SUCCESS; // return ReqStatus; } }
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 NPF_CloseBinding( IN POPEN_INSTANCE pOpen) { NDIS_EVENT Event; NDIS_STATUS Status; ASSERT(pOpen != NULL); ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); NdisInitializeEvent(&Event); NdisResetEvent(&Event); NdisAcquireSpinLock(&pOpen->AdapterHandleLock); while(pOpen->AdapterHandleUsageCounter > 0) { NdisReleaseSpinLock(&pOpen->AdapterHandleLock); NdisWaitEvent(&Event,1); NdisAcquireSpinLock(&pOpen->AdapterHandleLock); } // // now the UsageCounter is 0 // while(pOpen->AdapterBindingStatus == ADAPTER_UNBINDING) { NdisReleaseSpinLock(&pOpen->AdapterHandleLock); NdisWaitEvent(&Event,1); NdisAcquireSpinLock(&pOpen->AdapterHandleLock); } // // now the binding status is either bound or unbound // if (pOpen->AdapterBindingStatus == ADAPTER_UNBOUND) { NdisReleaseSpinLock(&pOpen->AdapterHandleLock); return; } ASSERT(pOpen->AdapterBindingStatus == ADAPTER_BOUND); pOpen->AdapterBindingStatus = ADAPTER_UNBINDING; NdisReleaseSpinLock(&pOpen->AdapterHandleLock); // // do the release procedure // NdisResetEvent(&pOpen->NdisOpenCloseCompleteEvent); // Close the adapter NdisCloseAdapter( &Status, pOpen->AdapterHandle ); if (Status == NDIS_STATUS_PENDING) { TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Pending NdisCloseAdapter"); NdisWaitEvent(&pOpen->NdisOpenCloseCompleteEvent, 0); } else { TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Not Pending NdisCloseAdapter"); } NdisAcquireSpinLock(&pOpen->AdapterHandleLock); pOpen->AdapterBindingStatus = ADAPTER_UNBOUND; NdisReleaseSpinLock(&pOpen->AdapterHandleLock); }
A_STATUS HIFReadWrite(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 length, A_UINT32 request, void *context) { A_STATUS status = A_OK; //unsigned long flags; BUS_REQUEST *busrequest; BUS_REQUEST *async; BUS_REQUEST *active; AR_DEBUG_ASSERT(device != NULL); do { if ((request & HIF_ASYNCHRONOUS) || (request & HIF_SYNCHRONOUS)) { /* serialize all requests through the async thread */ NDIS_DEBUG_PRINTF(DBG_TRACE, "AR6000: Execution mode: %s\n", (request & HIF_ASYNCHRONOUS) ?"Async":"Synch"); busrequest = hifAllocateBusRequest(device); if (busrequest == NULL) { NDIS_DEBUG_PRINTF(DBG_ERR, "AR6000: no async bus requests available\n"); return A_ERROR; } Hif_Lock(); busrequest->address = address; busrequest->buffer = buffer; busrequest->length = length; busrequest->request = request; busrequest->context = context; //NDIS_DEBUG_PRINTF(1, " add = %x, length = %x, request = %d \r\n", address, length, request); /* add to async list */ active = device->asyncreq; if (active == NULL) { device->asyncreq = busrequest; device->asyncreq->inusenext = NULL; } else { for (async = device->asyncreq; async != NULL; async = async->inusenext) { active = async; } active->inusenext = busrequest; busrequest->inusenext = NULL; } Hif_Unlock(); if (request & HIF_SYNCHRONOUS) { NdisSetEvent(&device->sem_async); /* Wait Read/Write Complete from the async_task */ if( ! NdisWaitEvent(&busrequest->sem_req, HIF_SYNCHRONOUS_WAIT_TIME)) { NDIS_DEBUG_PRINTF(DBG_ERR, " HIF Synchronous Read/Write Time Out !! \r\n"); NdisResetEvent(&busrequest->sem_req); return A_ERROR; } NdisResetEvent(&busrequest->sem_req); hifFreeBusRequest(device, busrequest); if(busrequest->status != A_OK) NDIS_DEBUG_PRINTF(DBG_ERR, "%s() Read/Write Err \r\n", __FUNCTION__); return busrequest->status; } else { NdisSetEvent(&device->sem_async); return A_PENDING; } } else { NDIS_DEBUG_PRINTF(DBG_ERR, "AR6000: Invalid execution mode: 0x%08x\n", (unsigned int)request); status = A_EINVAL; break; } }while(0); NDIS_DEBUG_PRINTF(0, "%s() : - Exit \r\n",__FUNCTION__); return status; }
static int async_task(void *param) { HIF_DEVICE *device; BUS_REQUEST *request; A_STATUS status; static int rw_cnt = 0; device = (HIF_DEVICE *)param; while(!device->async_shutdown) { /* wait for work */ NdisWaitEvent(&device->sem_async, 0); NdisResetEvent(&device->sem_async); if (device->async_shutdown) { NDIS_DEBUG_PRINTF(DBG_TRACE, "AR6000: async task stopping\n"); break; } /* pull the request to work on */ while (device->asyncreq != NULL) { request = device->asyncreq; if (request->inusenext != NULL) device->asyncreq = request->inusenext; else device->asyncreq = NULL; /* call HIFReadWrite in sync mode to do the work */ NDIS_DEBUG_PRINTF(DBG_TRACE, "AR6000: async_task processing req: 0x%X \r\n", (unsigned int)request); rw_cnt++; if(rw_cnt > 1) NDIS_DEBUG_PRINTF(DBG_ERR, "%s() : two time call !!!!! \r\n", __FUNCTION__); status = __HIFReadWrite(device, request->address, request->buffer, request->length, request->request & ~HIF_SYNCHRONOUS, NULL); rw_cnt --; if (request->request & HIF_ASYNCHRONOUS) { NDIS_DEBUG_PRINTF(DBG_TRACE, "AR6000: async_task completion routine req: 0x%X\n", (unsigned int)request); device->htcCallbacks.rwCompletionHandler(request->context, status); NDIS_DEBUG_PRINTF(DBG_TRACE, "AR6000: async_task freeing req: 0x%X\n", (unsigned int)request); hifFreeBusRequest(device, request); } else { NDIS_DEBUG_PRINTF(DBG_TRACE, "AR6000: async_task upping req: 0x%X\n", (unsigned int)request); request->status = status; NdisSetEvent(&request->sem_req); } } } return 0; }
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 PtUnbindAdapter( OUT PNDIS_STATUS Status, IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE UnbindContext ) /*++ Routine Description: Called by NDIS when we are required to unbind to the adapter below. This functions shares functionality with the miniport's HaltHandler. The code should ensure that NdisCloseAdapter and NdisFreeMemory is called only once between the two functions Arguments: Status Placeholder for return status ProtocolBindingContext Pointer to the adapter structure UnbindContext Context for NdisUnbindComplete() if this pends Return Value: Status for NdisIMDeinitializeDeviceContext --*/ { PADAPT pAdapt =(PADAPT)ProtocolBindingContext; NDIS_HANDLE BindingHandle = pAdapt->BindingHandle; NDIS_STATUS LocalStatus; DBGPRINT(("==> PtUnbindAdapter: Adapt %p\n", pAdapt)); if (pAdapt->QueuedRequest == TRUE) { pAdapt->QueuedRequest = FALSE; PtRequestComplete (pAdapt, &pAdapt->Request, NDIS_STATUS_FAILURE ); } #ifndef WIN9X // // Check if we had called NdisIMInitializeDeviceInstanceEx and // we are awaiting a call to MiniportInitialize. // if (pAdapt->MiniportInitPending == TRUE) { // // Try to cancel the pending IMInit process. // LocalStatus = NdisIMCancelInitializeDeviceInstance( DriverHandle, &pAdapt->DeviceName); if (LocalStatus == NDIS_STATUS_SUCCESS) { // // Successfully cancelled IM Initialization; our // Miniport Initialize routine will not be called // for this device. // pAdapt->MiniportInitPending = FALSE; ASSERT(pAdapt->MiniportHandle == NULL); } else { // // Our Miniport Initialize routine will be called // (may be running on another thread at this time). // Wait for it to finish. // NdisWaitEvent(&pAdapt->MiniportInitEvent, 0); ASSERT(pAdapt->MiniportInitPending == FALSE); } } #endif // !WIN9X // // Call NDIS to remove our device-instance. We do most of the work // inside the HaltHandler. // // The Handle will be NULL if our miniport Halt Handler has been called or // if the IM device was never initialized // if (pAdapt->MiniportHandle != NULL) { *Status = NdisIMDeInitializeDeviceInstance(pAdapt->MiniportHandle); if (*Status != NDIS_STATUS_SUCCESS) { *Status = NDIS_STATUS_FAILURE; } } else { // // We need to do some work here. // Close the binding below us // and release the memory allocated. // if(pAdapt->BindingHandle != NULL) { NdisResetEvent(&pAdapt->Event); NdisCloseAdapter(Status, pAdapt->BindingHandle); // // Wait for it to complete // if(*Status == NDIS_STATUS_PENDING) { NdisWaitEvent(&pAdapt->Event, 0); *Status = pAdapt->Status; } } else { // // Both Our MiniportHandle and Binding Handle should not be NULL. // *Status = NDIS_STATUS_FAILURE; ASSERT(0); } // // Free the memory here, if was not released earlier(by calling the HaltHandler) // NdisFreeMemory(pAdapt, sizeof(ADAPT), 0); } DBGPRINT(("<== PtUnbindAdapter: Adapt %p\n", pAdapt)); }
VOID natpUnbindAdapter( OUT PNDIS_STATUS Status, IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE UnbindContext ) { PFILTER_ADAPTER pAdapt; NDIS_STATUS LocalStatus; pAdapt = (PFILTER_ADAPTER)ProtocolBindingContext; UNREFERENCED_PARAMETER(UnbindContext); NdisAcquireSpinLock(&pAdapt->Lock); pAdapt->UnbindingInProcess = TRUE; if (pAdapt->QueuedRequest == TRUE){ pAdapt->QueuedRequest = FALSE; NdisReleaseSpinLock(&pAdapt->Lock); natpRequestComplete(pAdapt, &pAdapt->IntReq.NdisRequest, NDIS_STATUS_FAILURE ); }else{ NdisReleaseSpinLock(&pAdapt->Lock); } if (pAdapt->MiniportInitPending == TRUE){ LocalStatus = NdisIMCancelInitializeDeviceInstance( DriverHandle, &pAdapt->DeviceName ); if (LocalStatus == NDIS_STATUS_SUCCESS){ pAdapt->MiniportInitPending = FALSE; ASSERT(pAdapt->MiniportHandle == NULL); }else{ NdisWaitEvent(&pAdapt->MiniportInitEvent, 0); ASSERT(pAdapt->MiniportInitPending == FALSE); } } if (pAdapt->MiniportHandle != NULL){ *Status = NdisIMDeInitializeDeviceInstance( pAdapt->MiniportHandle ); if (*Status != NDIS_STATUS_SUCCESS) *Status = NDIS_STATUS_FAILURE; }else{ if(NULL != pAdapt->BindingHandle){ NdisResetEvent(&pAdapt->Event); NdisCloseAdapter(Status, pAdapt->BindingHandle); if(*Status == NDIS_STATUS_PENDING){ NdisWaitEvent(&pAdapt->Event, 0); *Status = pAdapt->Status; } pAdapt->BindingHandle = NULL; }else{ *Status = NDIS_STATUS_FAILURE; } natFreeAllItems(&pAdapt->ctrl); natFreeAllFwSessionsAndRules(&pAdapt->ctrl); natmFreeAllPacketPools(pAdapt); if (pAdapt) NdisFreeSpinLock(&pAdapt->Lock); NdisFreeMemory(pAdapt, 0, 0); } }
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; } } }