/************************************************************ Function that allows to perform a query on a network driver or to set the parameters of an adapter. ************************************************************/ DWORD PacketRequest( POPEN_INSTANCE Open, DWORD FunctionCode, DWORD dwDDB, DWORD hDevice, PDIOCPARAMETERS pDiocParms ) { PLIST_ENTRY RequestListEntry; PINTERNAL_REQUEST pRequest; PPACKET_RESERVED pReserved; PPACKET_OID_DATA OidData; NDIS_STATUS Status; TRACE_ENTER( "Request Packet" ); /*extract a request from the list*/ NdisAcquireSpinLock( &Open->RequestSpinLock ); RequestListEntry = PacketRemoveHeadList(&Open->RequestList); NdisReleaseSpinLock( &Open->RequestSpinLock ); if ( RequestListEntry == NULL ) { IF_TRACE( "Request List Error" ); *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0; TRACE_LEAVE( "Request Packet" ); return NDIS_STATUS_FAILURE/*NDIS_STATUS_SUCCESS*/; } pReserved = CONTAINING_RECORD( RequestListEntry, PACKET_RESERVED, ListElement ); pRequest = CONTAINING_RECORD( pReserved, INTERNAL_REQUEST, Reserved ); OidData = (PPACKET_OID_DATA)(pDiocParms->lpvInBuffer); if ( ( pDiocParms->cbInBuffer == pDiocParms->cbOutBuffer ) && ( pDiocParms->cbInBuffer >= sizeof(PACKET_OID_DATA) - 1 + OidData->Length) ) { pReserved->lpBuffer = (PVOID)PacketPageLock( pDiocParms->lpvInBuffer, pDiocParms->cbInBuffer ); pReserved->lpcbBytesReturned= (PVOID)PacketPageLock( (PVOID)pDiocParms->lpcbBytesReturned, sizeof(DWORD) ); pReserved->lpoOverlapped = (PVOID)PacketPageLock( (PVOID)pDiocParms->lpoOverlapped, sizeof(OVERLAPPED) ); pReserved->cbBuffer = pDiocParms->cbInBuffer; if ( FunctionCode == BIOCSETOID ) { pRequest->Request.RequestType = NdisRequestSetInformation; pRequest->Request.DATA.SET_INFORMATION.Oid = OidData->Oid; pRequest->Request.DATA.SET_INFORMATION.InformationBufferLength = OidData->Length; pRequest->Request.DATA.SET_INFORMATION.InformationBuffer = OidData->Data; IF_PACKETDEBUG( PACKET_DEBUG_VERY_LOUD ) { IF_TRACE_MSG2( "Request Set: Oid=%08lx, Length=%08lx", OidData->Oid, OidData->Length ); } }
/************************************************************ 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; }