Пример #1
0
/************************************************************
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 );
			}
		} 
Пример #2
0
VOID PacketAllocatePacketBuffer(PNDIS_STATUS    pStatus,
                                POPEN_INSTANCE  pOpen,
                                PNDIS_PACKET    *ppPacket,
                                PDIOCPARAMETERS pDiocParms,
                                DWORD           FunctionCode )
{
  // allocate a buffer for reading/writing

  PNDIS_BUFFER pNdisBuffer;
  PNDIS_PACKET pPacket;
  

  //  Try to get a packet from our list of free ones
  NdisAllocatePacket(pStatus, ppPacket, pOpen->PacketPool);
  
  if (*pStatus != NDIS_STATUS_SUCCESS) {
    *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
    return;
  }
  
  pPacket = *ppPacket;
  
  // Buffers used asynchronously must be page locked
  switch (FunctionCode) {
    case IOCTL_EPACKET_READ:
      RESERVED(pPacket)->lpBuffer = (PVOID)PacketPageLock(pDiocParms->lpvOutBuffer, pDiocParms->cbOutBuffer);
      RESERVED(pPacket)->cbBuffer = pDiocParms->cbOutBuffer;
      break;
    
    case IOCTL_EPACKET_WRITE:
      RESERVED(pPacket)->lpBuffer = (PVOID)PacketPageLock(pDiocParms->lpvInBuffer, pDiocParms->cbInBuffer);
      RESERVED(pPacket)->cbBuffer = pDiocParms->cbInBuffer;
      break;
    
    default:
      // recycle the packet
      NdisReinitializePacket(pPacket);
    
      // Put the packet on the free queue
      NdisFreePacket(pPacket);
    
      *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
      *pStatus = NDIS_STATUS_NOT_ACCEPTED;
      return;
  }
  
  RESERVED(pPacket)->lpcbBytesReturned = (PVOID)PacketPageLock(pDiocParms->lpcbBytesReturned, sizeof(DWORD));
  RESERVED(pPacket)->lpoOverlapped     = (PVOID)PacketPageLock(pDiocParms->lpoOverlapped, sizeof(OVERLAPPED));
  RESERVED(pPacket)->hDevice           = pDiocParms->hDevice;
  RESERVED(pPacket)->tagProcess        = pDiocParms->tagProcess;
  
  switch (FunctionCode) {
    case IOCTL_EPACKET_READ:
      NdisAllocateBuffer(pStatus,
                         &pNdisBuffer,
                         pOpen->BufferPool,
                         (PVOID)(RESERVED(pPacket)->lpBuffer + ETHERNET_HEADER_LENGTH),
                         pDiocParms->cbOutBuffer);
      break;
    
    case IOCTL_EPACKET_WRITE:
      NdisAllocateBuffer(pStatus,
                         &pNdisBuffer,
                         pOpen->BufferPool,
                         (PVOID)RESERVED(pPacket)->lpBuffer,
                         pDiocParms->cbInBuffer);
      break;
  }
  
  if (*pStatus == NDIS_STATUS_SUCCESS)
    NdisChainBufferAtFront(pPacket, pNdisBuffer); // Attach buffer to Packet
  else {
    NdisReinitializePacket(pPacket);  // recycle the packet
    NdisFreePacket(pPacket);          // Put the packet on the free queue
    *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
  }
}
Пример #3
0
DWORD NDIS_API PacketRequest(POPEN_INSTANCE  Open,
                             DWORD           FunctionCode,
                             DWORD           dwDDB,
                             DWORD           hDevice,
                             PDIOCPARAMETERS pDiocParms)
{
  // perform a packet request

  PLIST_ENTRY       RequestListEntry;
  PINTERNAL_REQUEST pRequest;
  PPACKET_RESERVED  pReserved;
  EPACKET_OID *  OidData;
  NDIS_STATUS       Status;
  

  // Acquire request element from list
  NdisAcquireSpinLock(&Open->RequestSpinLock);
  
  if (IsListEmpty(&Open->RequestList)) { 
    *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
    NdisReleaseSpinLock(&Open->RequestSpinLock);
    return NDIS_STATUS_SUCCESS;
  }

  RequestListEntry = RemoveHeadList(&Open->RequestList);
  NdisReleaseSpinLock(&Open->RequestSpinLock);
  
  pReserved = CONTAINING_RECORD(RequestListEntry, PACKET_RESERVED, ListElement);
  pRequest  = CONTAINING_RECORD(pReserved, INTERNAL_REQUEST, Reserved);
  OidData   = (EPACKET_OID*)(pDiocParms->lpvInBuffer);

  if ((pDiocParms->cbInBuffer != pDiocParms->cbOutBuffer) ||
      (pDiocParms->cbInBuffer < sizeof(*OidData) - sizeof(OidData->Data) + OidData->Length)) {
    *(DWORD *)pDiocParms->lpcbBytesReturned = 1;
    return NDIS_STATUS_BUFFER_TOO_SHORT;
  }

  // The buffer is valid
  pReserved->lpBuffer          = (PVOID)PacketPageLock(pDiocParms->lpvInBuffer, pDiocParms->cbInBuffer);
  pReserved->lpcbBytesReturned = (PVOID)PacketPageLock(pDiocParms->lpcbBytesReturned, sizeof(DWORD));
  pReserved->lpoOverlapped     = (PVOID)PacketPageLock(pDiocParms->lpoOverlapped, sizeof(OVERLAPPED));
  pReserved->cbBuffer          = pDiocParms->cbInBuffer;
  pReserved->hDevice           = pDiocParms->hDevice;
  pReserved->tagProcess        = pDiocParms->tagProcess;
  
  if (FunctionCode == IOCTL_EPACKET_SET_OID) {                      
    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;
  } 
  else {
    if (OidData->Oid >= 0x01000000)
      pRequest->Request.RequestType = NdisRequestQueryInformation;
    else
      pRequest->Request.RequestType = NdisRequestGeneric1;
    pRequest->Request.DATA.QUERY_INFORMATION.Oid                     = OidData->Oid;
    pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength = OidData->Length;
    pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer       = OidData->Data;
  }

  // submit the request
  NdisRequest(&Status, Open->AdapterHandle, &pRequest->Request);

  if (Status == NDIS_STATUS_PENDING)
    return(-1);      // This will make DeviceIOControl return ERROR_IO_PENDING

  PacketRequestComplete(Open, &pRequest->Request, Status);
  return Status;
}