|
|
//////////////////////////////////////////////////////////
//
// Copyright (c) 2001 Microsoft Corporation
//
// Module Name:
// receive.cpp
//
// Abstract:
// This module contains code which implements receive
// commands from the dll
//
//////////////////////////////////////////////////////////
#include "stdafx.h"
///////////////////////////////////////////////////////////////////////
// Public functions
///////////////////////////////////////////////////////////////////////
// --------------------------------------------------------------------
//
// Function: DoReceiveDatagram
//
// Arguments: TdiHandle -- handle of address object
// pInTransportAddress -- TA for receiving on
// pOutTransportAddress -- full TA data was received on
// ppucBuffer -- buffer to stuff with received data
//
// Returns: length of data in buffer (0 if none or error)
//
// Descript: This function causes the driver to receive a datagram
//
//---------------------------------------------------------------------
ULONG DoReceiveDatagram(ULONG ulTdiHandle, PTRANSPORT_ADDRESS pInTransportAddress, PTRANSPORT_ADDRESS pOutTransportAddress, PUCHAR *ppucBuffer) { PUCHAR pucBuffer = (PUCHAR)LocalAllocateMemory(ulMAX_BUFFER_LENGTH);
if (!pucBuffer) { return 0; }
SEND_BUFFER SendBuffer; // arguments for command
//
// set up arguments
//
SendBuffer.TdiHandle = ulTdiHandle; SendBuffer.COMMAND_ARGS.SendArgs.ulBufferLength = ulMAX_BUFFER_LENGTH; SendBuffer.COMMAND_ARGS.SendArgs.pucUserModeBuffer = pucBuffer; //
// if passed in a transport address to receive on
//
if (pInTransportAddress) { memcpy(&SendBuffer.COMMAND_ARGS.SendArgs.TransAddr, pInTransportAddress, (FIELD_OFFSET(TRANSPORT_ADDRESS, Address) + FIELD_OFFSET(TA_ADDRESS, Address) + pInTransportAddress->Address[0].AddressLength));
} //
// else, set the number of addresses field to 0
//
else { SendBuffer.COMMAND_ARGS.SendArgs.TransAddr.TAAddressCount = 0; }
//
// call the driver
//
RECEIVE_BUFFER ReceiveBuffer; // return info from command
NTSTATUS lStatus = TdiLibDeviceIO(ulRECEIVEDATAGRAM, &SendBuffer, &ReceiveBuffer);
//
// deal with results -- assume no packet received or error occurred
//
ULONG ulBufferLength = 0; *ppucBuffer = NULL;
//
// will return with success but ulBufferLength = 0 if there is no
// packet available
//
if (lStatus == STATUS_SUCCESS) { ulBufferLength = ReceiveBuffer.RESULTS.RecvDgramRet.ulBufferLength; } if (ulBufferLength) { if (pOutTransportAddress) { memcpy(pOutTransportAddress, &ReceiveBuffer.RESULTS.RecvDgramRet.TransAddr, (FIELD_OFFSET(TRANSPORT_ADDRESS, Address) + FIELD_OFFSET(TA_ADDRESS, Address) + ReceiveBuffer.RESULTS.RecvDgramRet.TransAddr.TaAddress.AddressLength)); } *ppucBuffer = pucBuffer; } else { LocalFreeMemory(pucBuffer); } return ulBufferLength; }
// --------------------------------------------------------------------
//
// Function: DoReceive
//
// Arguments: TdiHandle -- handle of endpoint object
// ppucBuffer -- buffer to stuff with received data
//
// Returns: length of data in buffer (0 if error)
//
// Descript: This function causes the driver to receive data sent
// over a connection
//
//---------------------------------------------------------------------
ULONG DoReceive(ULONG ulTdiHandle, PUCHAR *ppucBuffer) { PUCHAR pucBuffer = (PUCHAR)LocalAllocateMemory(ulMAX_BUFFER_LENGTH);
if (!pucBuffer) { return 0; }
SEND_BUFFER SendBuffer; // arguments for command
//
// set up arguments
//
SendBuffer.TdiHandle = ulTdiHandle; SendBuffer.COMMAND_ARGS.SendArgs.ulBufferLength = ulMAX_BUFFER_LENGTH; SendBuffer.COMMAND_ARGS.SendArgs.pucUserModeBuffer = pucBuffer;
//
// call the driver
//
RECEIVE_BUFFER ReceiveBuffer; // return info from command
NTSTATUS lStatus = TdiLibDeviceIO(ulRECEIVE, &SendBuffer, &ReceiveBuffer);
//
// deal with results -- assume no data or error
//
*ppucBuffer = NULL; ULONG ulBufferLength = 0; // data length to return
//
// will return success with 0 bufferlength if no packet available
//
if (lStatus == STATUS_SUCCESS) { ulBufferLength = ReceiveBuffer.RESULTS.RecvDgramRet.ulBufferLength; }
if (ulBufferLength) { *ppucBuffer = pucBuffer; } else { LocalFreeMemory(pucBuffer); } return ulBufferLength; }
// ---------------------------------------
//
// Function: DoPostReceiveBuffer
//
// Arguments: TdiHandle -- handle for address object or endpoint
// ulBufferLength -- length of buffer to post for receive
//
// Returns: status of command
//
// Descript: This function allocates a buffer, which it then passed to
// the driver. The driver locks the buffer down, and posts it
// for a receive or receivedatagram.
//
// ----------------------------------------
VOID DoPostReceiveBuffer(ULONG ulTdiHandle, ULONG ulBufferLength) { NTSTATUS lStatus; // status of command
RECEIVE_BUFFER ReceiveBuffer; // return info from command
SEND_BUFFER SendBuffer; // arguments for command
//
// set up arguments
//
SendBuffer.TdiHandle = ulTdiHandle; SendBuffer.COMMAND_ARGS.SendArgs.ulBufferLength = ulBufferLength;
PUCHAR pucBuffer = (PUCHAR)LocalAllocateMemory(ulBufferLength); if (pucBuffer) { SendBuffer.COMMAND_ARGS.SendArgs.pucUserModeBuffer = pucBuffer;
//
// call the driver
//
lStatus = TdiLibDeviceIO(ulPOSTRECEIVEBUFFER, &SendBuffer, &ReceiveBuffer); if (lStatus != STATUS_SUCCESS) { _tprintf(TEXT("DoPostReceiveBuffer: failure, status = %s\n"), TdiLibStatusMessage(lStatus)); LocalFreeMemory(pucBuffer); } } else { _putts(TEXT("DoPostReceiveBuffer: failed to allocate buffer\n")); } }
// ------------------------------------------
//
// Function: DoFetchReceiveBuffer
//
// Arguments: TdiHandle -- handle of address object or endpoint
// pulBufferLength -- length of data returned
// ppDataBuffer -- allocated buffer with data
//
// Returns: status of operation
//
// Descript: This function retrieves the oldest posted buffer. If no
// data is available, it will cancel the appropriate irp
// It then returns the data to the caller as appropriate
//
// -------------------------------------------
ULONG DoFetchReceiveBuffer(ULONG ulTdiHandle, PUCHAR *ppDataBuffer) { NTSTATUS lStatus; // status of command
RECEIVE_BUFFER ReceiveBuffer; // return info from command
SEND_BUFFER SendBuffer; // arguments for command
ULONG ulBufferLength = 0; //
// set up arguments
//
SendBuffer.TdiHandle = ulTdiHandle; *ppDataBuffer = NULL;
//
// call the driver
//
lStatus = TdiLibDeviceIO(ulFETCHRECEIVEBUFFER, &SendBuffer, &ReceiveBuffer); if (lStatus == STATUS_SUCCESS) { PUCHAR pucTempBuffer = ReceiveBuffer.RESULTS.RecvDgramRet.pucUserModeBuffer; ulBufferLength = ReceiveBuffer.RESULTS.RecvDgramRet.ulBufferLength; if (ulBufferLength) { *ppDataBuffer = pucTempBuffer; } else if (pucTempBuffer) { LocalFreeMemory(pucTempBuffer); } }
return ulBufferLength; }
////////////////////////////////////////////////////////////////////
// end of file receive.cpp
////////////////////////////////////////////////////////////////////
|