|
|
/////////////////////////////////////////////////////////////////////////////
//
//
// Copyright (c) 1996, 1997 Microsoft Corporation
//
//
// Module Name:
// test.c
//
// Abstract:
//
// This file is a test to find out if dual binding to NDIS and KS works
//
// Author:
//
// P Porzuczek
//
// Environment:
//
// Revision History:
//
//
//////////////////////////////////////////////////////////////////////////////
#include <forward.h>
#include <memory.h>
#include <ndis.h>
#include <link.h>
#include <ipsink.h>
#include "device.h"
#include "NdisApi.h"
#include "frame.h"
#include "mem.h"
#include "adapter.h"
#include "main.h"
//////////////////////////////////////////////////////////
//
//
//
PADAPTER global_pAdapter; UCHAR achGlobalVendorDescription [] = "Microsoft TV/Video Connection"; ULONG ulGlobalInstance = 1;
//////////////////////////////////////////////////////////
//
//
const ADAPTER_VTABLE AdapterVTable = { Adapter_QueryInterface, Adapter_AddRef, Adapter_Release, Adapter_IndicateData, Adapter_IndicateReset, Adapter_GetDescription, Adapter_CloseLink };
//////////////////////////////////////////////////////////
//
//
#pragma pack (push, 1)
typedef ULONG CHECKSUM;
typedef struct _MAC_ADDRESS_ { UCHAR Address [6];
} MAC_ADDRESS, *PMAC_ADDRESS;
typedef struct _HEADER_802_3 { MAC_ADDRESS DestAddress; MAC_ADDRESS SourceAddress; UCHAR Type[2];
} HEADER_802_3, *PHEADER_802_3;
typedef struct _HEADER_IP_ { UCHAR ucVersion_Length; UCHAR ucTOS; USHORT usLength; USHORT usId; USHORT usFlags_Offset; UCHAR ucTTL; UCHAR ucProtocol; USHORT usHdrChecksum; UCHAR ucSrcAddress [4]; UCHAR ucDestAddress [4];
} HEADER_IP, *PHEADER_IP;
#pragma pack (pop)
//////////////////////////////////////////////////////////
//
//
const HEADER_802_3 h802_3Template = { {0x01, 0x00, 0x5e, 0, 0, 0} , {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} , {0x08, 0x00} };
#if DBG
//////////////////////////////////////////////////////////////////////////////
VOID DumpData ( PUCHAR pData, ULONG ulSize ) //////////////////////////////////////////////////////////////////////////////
{ ULONG ulCount; ULONG ul; UCHAR uc;
while (ulSize) { ulCount = 16 < ulSize ? 16 : ulSize;
for (ul = 0; ul < ulCount; ul++) { uc = *pData;
TEST_DEBUG (TEST_DBG_TRACE, ("%02X ", uc)); ulSize -= 1; pData += 1; }
TEST_DEBUG (TEST_DBG_TRACE, ("\n")); }
}
#endif
//////////////////////////////////////////////////////////////////////////////
NTSTATUS CreateAdapter ( PADAPTER *ppAdapter, NDIS_HANDLE ndishWrapper, NDIS_HANDLE ndishAdapterContext ) //////////////////////////////////////////////////////////////////////////////
{ NTSTATUS nsResult; PADAPTER pAdapter; UCHAR tmp_buffer [32] = {0};
//
// Init the output paramter
//
*ppAdapter = NULL;
//
// Allocate memory for the adapter block now.
//
nsResult = AllocateMemory (&pAdapter, sizeof(ADAPTER)); if (nsResult != NDIS_STATUS_SUCCESS) { return nsResult; } NdisZeroMemory (pAdapter, sizeof (ADAPTER));
//
// Init the reference count
//
pAdapter->ulRefCount = 1;
//
// Save the pAdapter into global storage
//
global_pAdapter = pAdapter;
//
// Initialize the adapter structure fields
//
pAdapter->ndishMiniport = ndishAdapterContext;
//
// Initialize the adapter vtable
//
pAdapter->lpVTable = (PADAPTER_VTABLE) &AdapterVTable;
//
// Save off the instance for this adapter
//
pAdapter->ulInstance = ulGlobalInstance++;
//
// init the spinlock for this adapter
//
NdisAllocateSpinLock(&(pAdapter->ndisSpinLock));
//Enable adapter
pAdapter->BDAAdapterEnable =1 ; //
// Setup the vendor description string for this instance
//
nsResult = AllocateMemory (&pAdapter->pVendorDescription, sizeof(achGlobalVendorDescription) + 8); if (nsResult != NDIS_STATUS_SUCCESS) { return nsResult; } NdisZeroMemory (pAdapter->pVendorDescription, sizeof (achGlobalVendorDescription) + 8);
NdisMoveMemory (pAdapter->pVendorDescription, (PVOID) achGlobalVendorDescription, sizeof (achGlobalVendorDescription)); /*
#if DBG
MyStrCat (pAdapter->pVendorDescription, "("); MyStrCat (pAdapter->pVendorDescription, MyUlToA (pAdapter->ulInstance, tmp_buffer, 10)); MyStrCat (pAdapter->pVendorDescription, ")");
DbgPrint ("Vendor description: %s\n", pAdapter->pVendorDescription); #endif // DEBUG
*/ //
// Set default completion timeout to IGNORE
//
// WARNING! The interface type is not optional!
//
NdisMSetAttributesEx ( ndishAdapterContext, pAdapter, 4, NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT | NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT | NDIS_ATTRIBUTE_DESERIALIZE , NdisInterfaceInternal);
#ifndef WIN9X
//
// Create a device so other drivers (ie Streaming minidriver) can
// link up with us
//
nsResult = (NTSTATUS) ntInitializeDeviceObject ( ndishWrapper, pAdapter, &pAdapter->pDeviceObject, &pAdapter->ndisDeviceHandle);
if (nsResult != NDIS_STATUS_SUCCESS) { return nsResult; }
#endif
///////////////////////////////////////////////////
//
// Allocate a buffer pool. This pool will be used
// to indicate the streaming data frames.
//
CreateFramePool (pAdapter, &pAdapter->pFramePool, IPSINK_NDIS_MAX_BUFFERS, IPSINK_NDIS_BUFFER_SIZE, sizeof (IPSINK_MEDIA_SPECIFIC_INFORMATION) );
return nsResult;
}
///////////////////////////////////////////////////////////////////////////////////
NTSTATUS Adapter_QueryInterface ( PADAPTER pAdapter ) ///////////////////////////////////////////////////////////////////////////////////
{ return STATUS_NOT_IMPLEMENTED; }
///////////////////////////////////////////////////////////////////////////////////
ULONG Adapter_AddRef ( PADAPTER pAdapter ) ///////////////////////////////////////////////////////////////////////////////////
{ if (pAdapter) { pAdapter->ulRefCount += 1; return pAdapter->ulRefCount; }
return 0; }
///////////////////////////////////////////////////////////////////////////////////
ULONG Adapter_Release ( PADAPTER pAdapter ) ///////////////////////////////////////////////////////////////////////////////////
{ ULONG ulRefCount = 0L;
if (pAdapter) { pAdapter->ulRefCount -= 1;
ulRefCount = pAdapter->ulRefCount;
if (pAdapter->ulRefCount == 0) { FreeMemory (pAdapter, sizeof (ADAPTER)); } }
return ulRefCount; }
//////////////////////////////////////////////////////////////////////////////
VOID Adapter_IndicateReset ( PADAPTER pAdapter ) //////////////////////////////////////////////////////////////////////////////
{ if (pAdapter) { if (pAdapter->pCurrentFrame != NULL) { if (pAdapter->pCurrentFrame->pFramePool) { TEST_DEBUG (TEST_DBG_TRACE, ("Putting Current Frame %08X back on Available Queue\n", pAdapter->pCurrentFrame)); PutFrame (pAdapter->pCurrentFrame->pFramePool, &pAdapter->pCurrentFrame->pFramePool->leAvailableQueue, pAdapter->pCurrentFrame); }
pAdapter->pCurrentFrame = NULL; pAdapter->pIn = NULL; pAdapter->ulPR = 0; } }
}
//////////////////////////////////////////////////////////////////////////////
ULONG Adapter_GetDescription ( PADAPTER pAdapter, PUCHAR pDescription ) //////////////////////////////////////////////////////////////////////////////
{ ULONG ulLength;
ulLength = MyStrLen (pAdapter->pVendorDescription) + 1; // add 1 to include terminator
//
// If the description pointer is NULL, then pass back the length only
//
if (pDescription != NULL) { NdisMoveMemory (pDescription, pAdapter->pVendorDescription, ulLength); }
return ulLength; }
//////////////////////////////////////////////////////////////////////////////
VOID Adapter_CloseLink ( PADAPTER pAdapter ) //////////////////////////////////////////////////////////////////////////////
{ if (pAdapter) { if (pAdapter->pFilter != NULL) { pAdapter->pFilter->lpVTable->Release (pAdapter->pFilter); pAdapter->pFilter = NULL; } }
}
//////////////////////////////////////////////////////////////////////////////
NTSTATUS GetNdisFrame ( PADAPTER pAdapter, PFRAME *ppFrame ) //////////////////////////////////////////////////////////////////////////////
{ PFRAME pFrame = NULL; NTSTATUS ntStatus = STATUS_UNSUCCESSFUL; PHEADER_802_3 pEthHeader = NULL; PHEADER_IP pIPHeader = NULL;
*ppFrame = NULL;
pFrame = GetFrame (pAdapter->pFramePool, &pAdapter->pFramePool->leAvailableQueue); TEST_DEBUG (TEST_DBG_TRACE, ("Getting Frame %08X from the Available Queue\n", pFrame));
if (pFrame) { ntStatus = STATUS_SUCCESS;
*ppFrame = pFrame; }
return ntStatus; }
#define SWAP_WORD(A) ((A >> 8) & 0x00FF) + ((A << 8) & 0xFF00)
//////////////////////////////////////////////////////////////////////////////
USHORT sizeof_packet ( PHEADER_IP pIpHdr ) //////////////////////////////////////////////////////////////////////////////
{ USHORT usLength;
usLength = pIpHdr->usLength;
usLength = SWAP_WORD (usLength);
return usLength; }
//////////////////////////////////////////////////////////////////////////////
NTSTATUS TranslateAndIndicate ( PADAPTER pAdapter, PUCHAR pOut, ULONG ulSR ) //////////////////////////////////////////////////////////////////////////////
{ NTSTATUS nsResult = STATUS_SUCCESS; ULONG ulAmtToCopy; ULONG uliNextByte;
ASSERT (pAdapter); ASSERT (pOut); for ( uliNextByte = 0; uliNextByte < ulSR; ) { HEADER_802_3 * pHeader802_3; HEADER_IP * pHeaderIP=NULL;
ulAmtToCopy = 0;
// If there is no current frame then sync up to a new
// 802.3 (RFC 894) ethernet frame.
//
if (pAdapter->pCurrentFrame == NULL) { // Sync to a valid looking 802.3 frame
//
while ((ulSR - uliNextByte) >= (sizeof (HEADER_802_3) + sizeof (HEADER_IP))) { pHeader802_3 = (HEADER_802_3 *) &(pOut[uliNextByte]); pHeaderIP = (HEADER_IP *) &(pOut[uliNextByte + sizeof(HEADER_802_3)]);
if ( (pHeader802_3->Type[0] == 0x08) && (pHeader802_3->Type[1] == 0x00) && (pHeaderIP->ucVersion_Length == 0x45) && (sizeof_packet( pHeaderIP) <= MAX_IP_PACKET_SIZE) ) { break; } uliNextByte++; }
if ((ulSR - uliNextByte) < (sizeof (HEADER_802_3) + sizeof (HEADER_IP))) { TEST_DEBUG (TEST_DBG_INFO, ("Stream buffer consumed while searching for valid IP packet\n")); nsResult = STATUS_SUCCESS; goto ret; }
//
// Everything looks good...get a new frame and start data transfer
//
nsResult = GetNdisFrame( pAdapter, &pAdapter->pCurrentFrame ); if (nsResult != STATUS_SUCCESS) { TEST_DEBUG (TEST_DBG_ERROR, ("Get NDIS frame failed. No more NDIS frames available. No Frame built\n")); nsResult = STATUS_SUCCESS; pAdapter->stats.ulOID_GEN_RCV_NO_BUFFER += 1; pAdapter->pIn = NULL; pAdapter->pCurrentFrame = NULL; pAdapter->ulPR = 0; goto ret; }
//Assert((pHeaderIP)!=NULL) can be used for nonretail builds here
//check if any valid null pHeaderIP case ever exists
if(!pHeaderIP) { nsResult = !(STATUS_SUCCESS); goto ret;
}
//
// Update the reference count for this frame
//
pAdapter->pCurrentFrame->lpVTable->AddRef( pAdapter->pCurrentFrame);
//
// define pointers to the data in and out buffers, and init the packet size field
//
pAdapter->pIn = (PUCHAR) (pAdapter->pCurrentFrame->pvMemory); pAdapter->ulPR = sizeof_packet( pHeaderIP) + sizeof (HEADER_802_3); pAdapter->pCurrentFrame->ulcbData = pAdapter->ulPR;
TEST_DEBUG (TEST_DBG_TRACE, ("CREATING NEW NDIS FRAME %08X, packet size %d\n", pAdapter->pCurrentFrame, pAdapter->ulPR)); }
if (pAdapter->ulPR <= (ulSR - uliNextByte)) { ulAmtToCopy = pAdapter->ulPR; } else { ulAmtToCopy = ulSR - uliNextByte; }
NdisMoveMemory( pAdapter->pIn, &(pOut[uliNextByte]), ulAmtToCopy ); pAdapter->pIn += ulAmtToCopy; pAdapter->ulPR -= ulAmtToCopy; uliNextByte += ulAmtToCopy;
if (pAdapter->ulPR == 0) { BOOLEAN bResult; PINDICATE_CONTEXT pIndicateContext = NULL; NDIS_HANDLE SwitchHandle = NULL;
AllocateMemory (&pIndicateContext, sizeof (INDICATE_CONTEXT)); if(!pIndicateContext) { nsResult = STATUS_NO_MEMORY; goto ret; }
pIndicateContext->pAdapter = pAdapter;
//
// Place the frame on the indicateQueue
//
TEST_DEBUG (TEST_DBG_TRACE, ("Putting Frame %08X on Indicate Queue\n", pAdapter->pCurrentFrame)); PutFrame (pAdapter->pFramePool, &pAdapter->pFramePool->leIndicateQueue, pAdapter->pCurrentFrame);
pAdapter->pCurrentFrame = NULL;
//Check status of SourceRouting flag
SourceRoutingStatusPoll(); //
//
// Switch to a state which allows us to call NDIS functions
//
NdisAcquireSpinLock(&(pAdapter->ndisSpinLock)); IndicateCallbackHandler (pAdapter->ndishMiniport, (PVOID) pIndicateContext); NdisReleaseSpinLock(&(pAdapter->ndisSpinLock)); } }
ret:
return nsResult; }
//////////////////////////////////////////////////////////////////////////////
NTSTATUS Adapter_IndicateData ( IN PADAPTER pAdapter, IN PVOID pvData, IN ULONG ulcbData ) //////////////////////////////////////////////////////////////////////////////
{ NTSTATUS ntStatus = STATUS_SUCCESS;
ntStatus = TranslateAndIndicate (pAdapter, pvData, ulcbData);
return ntStatus; }
|