VOID NDIS_API PacketUnbindAdapter(OUT PNDIS_STATUS Status, IN POPEN_INSTANCE Open, IN POPEN_INSTANCE junk) { // detach protocol from the NIC clean up any pending I/O requests PLIST_ENTRY PacketListEntry; PNDIS_PACKET pPacket; // The open instance of the device is about to close // We need to complete all pending I/O requests // First we complete any pending read requests NdisAcquireSpinLock(&Open->RcvQSpinLock); while (!IsListEmpty(&Open->RcvList)) { PacketListEntry = RemoveHeadList(&Open->RcvList); pPacket = CONTAINING_RECORD(PacketListEntry, NDIS_PACKET, ProtocolReserved); // complete normally PacketTransferDataComplete(Open, pPacket, NDIS_STATUS_SUCCESS, 0); } NdisReleaseSpinLock(&Open->RcvQSpinLock); // close the adapter NdisCloseAdapter(Status, Open->AdapterHandle); // Save status returned from NdisCloseAdapter for completion routine Open->Status = *Status; if (*Status != NDIS_STATUS_PENDING) PacketUnbindAdapterComplete(Open, *Status); }
/************************************************************ Start the unbind of a network driver from the protocol driver ************************************************************/ VOID NDIS_API PacketUnbindAdapter( OUT PNDIS_STATUS Status, IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE UnbindContext ) { POPEN_INSTANCE Open; NDIS_STATUS nsCloseStatus; TRACE_ENTER( "UnbindAdapter" ); Open = (POPEN_INSTANCE)ProtocolBindingContext; Open->BindAdapterContext = UnbindContext; /*clean the pending requests*/ PacketCleanUp( Status, Open ); Open->Status = NDIS_STATUS_PENDING; /*Calls NDIS to close the selected adapter*/ NdisCloseAdapter( &nsCloseStatus, Open->AdapterHandle ); if ( nsCloseStatus == NDIS_STATUS_PENDING ) { while ( Open->Status == NDIS_STATUS_PENDING ) YieldExecution(); } else { PacketUnbindAdapterComplete( Open, nsCloseStatus ); } *Status = Open->Status; if ( *Status == NDIS_STATUS_SUCCESS ) { NdisFreeMemory( Open, sizeof( OPEN_INSTANCE ) , 0 ); } else { IF_TRACE( "Unbind Operation FAILED!" ); } TRACE_LEAVE( "CloseAdapter" ); return; }
/************************************************************ 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; }
DWORD PacketClose(POPEN_INSTANCE Open,DWORD dwDDB,DWORD hDevice,PDIOCPARAMETERS pDiocParms) { NDIS_STATUS Status; NDIS_STATUS nsErrorStatus; UINT to; DWORD TEvent; TRACE_ENTER( "PacketClose" ); Open->BufSize=0; to=Open->ReadTimeoutTimer; Open->ReadTimeoutTimer=0; if(to!=0) { _asm push esi; _asm mov esi,to; CancelReadTimeOut(); _asm pop esi; } // Free the read event TEvent=Open->ReadEvent; _asm mov eax,TEvent; VxDCall(_VWIN32_CloseVxDHandle); //close the adapter NdisCloseAdapter(&nsErrorStatus,Open->AdapterHandle); if ( nsErrorStatus == NDIS_STATUS_PENDING ) { while ( Open->Status == NDIS_STATUS_PENDING ) YieldExecution(); if(Open->Status!=NDIS_STATUS_SUCCESS) { TRACE_LEAVE( "PacketClose" ); return NDIS_STATUS_FAILURE; } } else { PacketUnbindAdapterComplete( Open, nsErrorStatus ); if(nsErrorStatus!=NDIS_STATUS_SUCCESS) { TRACE_LEAVE( "PacketClose" ); return NDIS_STATUS_FAILURE; } } Status = Open->Status; if(Open->Buffer!=NULL)NdisFreeMemory(Open->Buffer,Open->BufSize,0); Open->Buffer=NULL; if(Open->bpfprogram!=NULL)NdisFreeMemory(Open->bpfprogram,Open->bpfprogramlen,0); //remove this adapter from the list of open adapters NdisAcquireSpinLock( &GlobalDeviceExtension->OpenSpinLock ); RemoveEntryList(&(Open->ListElement)); NdisReleaseSpinLock( &GlobalDeviceExtension->OpenSpinLock ); NdisFreeMemory( Open, sizeof( OPEN_INSTANCE ) , 0 ); if(pDiocParms!=NULL) *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0; TRACE_LEAVE( "PacketClose" ); return Status; }