Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

713 lines
14 KiB

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
request.c
Abstract:
Ndis 3.0 MAC driver for the UB card
This file handles NdisRequest. The module was for the most part extracted
from the elnkii driver
Author:
Brian Lieuallen (BrianLie) 07/02/92
Environment:
Kernel Mode Operating Systems : NT and other lesser OS's
Revision History:
Brian Lieuallen BrianLie 12/15/93
Made it a mini-port
--*/
#include <ndis.h>
//#include <efilter.h>
#include "niudata.h"
#include "debug.h"
#include "ubhard.h"
#include "ubsoft.h"
#include "ubnei.h"
NDIS_STATUS
UbneiFilterChangeAction(
IN UINT NewFilterClasses,
IN NDIS_HANDLE MacBindingHandle
);
//
// If you add to this, make sure to add the
// a case in UbneiFillInGlobalData() and in
// UbneiQueryGlobalStatistics() if global
// information only or
// UbneiQueryProtocolStatistics() if it is
// protocol queriable information.
//
STATIC UINT UbneiGlobalSupportedOids[] = {
OID_GEN_SUPPORTED_LIST,
OID_GEN_HARDWARE_STATUS,
OID_GEN_MEDIA_SUPPORTED,
OID_GEN_MEDIA_IN_USE,
OID_GEN_MAXIMUM_LOOKAHEAD,
OID_GEN_MAXIMUM_FRAME_SIZE,
OID_GEN_MAXIMUM_TOTAL_SIZE,
OID_GEN_MAC_OPTIONS,
OID_GEN_PROTOCOL_OPTIONS,
OID_GEN_LINK_SPEED,
OID_GEN_TRANSMIT_BUFFER_SPACE,
OID_GEN_RECEIVE_BUFFER_SPACE,
OID_GEN_TRANSMIT_BLOCK_SIZE,
OID_GEN_RECEIVE_BLOCK_SIZE,
OID_GEN_VENDOR_ID,
OID_GEN_VENDOR_DESCRIPTION,
OID_GEN_DRIVER_VERSION,
OID_GEN_CURRENT_PACKET_FILTER,
OID_GEN_CURRENT_LOOKAHEAD,
OID_GEN_XMIT_OK,
OID_GEN_RCV_OK,
OID_GEN_XMIT_ERROR,
OID_GEN_RCV_ERROR,
OID_GEN_RCV_NO_BUFFER,
OID_802_3_PERMANENT_ADDRESS,
OID_802_3_CURRENT_ADDRESS,
OID_802_3_MULTICAST_LIST,
OID_802_3_MAXIMUM_LIST_SIZE,
OID_802_3_RCV_ERROR_ALIGNMENT,
OID_802_3_XMIT_ONE_COLLISION,
OID_802_3_XMIT_MORE_COLLISIONS
};
NDIS_STATUS
UbneiQueryInformation(
IN NDIS_HANDLE MiniportContext,
IN NDIS_OID Oid,
IN PVOID InfoBuffer,
IN ULONG BytesLeft,
OUT PULONG BytesWritten,
OUT PULONG BytesNeeded
)
/*++
Routine Description:
The UbneiQueryProtocolInformation process a Query request for
NDIS_OIDs that are specific to a binding about the MAC. Note that
some of the OIDs that are specific to bindings are also queryable
on a global basis. Rather than recreate this code to handle the
global queries, I use a flag to indicate if this is a query for the
global data or the binding specific data.
Arguments:
Adapter - a pointer to the adapter.
Oid - the NDIS_OID to process.
PlaceInInfoBuffer - a pointer into the NdisRequest->InformationBuffer
into which store the result of the query.
BytesLeft - the number of bytes left in the InformationBuffer.
BytesNeeded - If there is not enough room in the information buffer
then this will contain the number of bytes needed to complete the
request.
BytesWritten - a pointer to the number of bytes written into the
InformationBuffer.
Return Value:
The function value is the status of the operation.
--*/
{
NDIS_MEDIUM Medium = NdisMedium802_3;
ULONG GenericULong = 0;
USHORT GenericUShort = 0;
UCHAR GenericArray[6];
PUBNEI_ADAPTER pAdapter=MiniportContext;
PLOWNIUDATA pRcvDWindow = (PLOWNIUDATA) pAdapter->pCardRam;
NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
//
// Common variables for pointing to result of query
//
PVOID MoveSource;
ULONG MoveBytes;
NDIS_HARDWARE_STATUS HardwareStatus = NdisHardwareStatusReady;
//
// General Algorithm:
//
// Switch(Request)
// Get requested information
// Store results in a common variable.
// Copy result in common variable to result buffer.
//
//
// Make sure that ulong is 4 bytes. Else GenericULong must change
// to something of size 4.
//
ASSERT(sizeof(ULONG) == 4);
IF_REQ_LOUD(DbgPrint("UBNEI: QueryProtocol %08lx\n",Oid);)
MoveSource = (PVOID)(&GenericULong);
MoveBytes = sizeof(GenericULong);
//
// Switch on request type
//
switch (Oid) {
case OID_GEN_MAC_OPTIONS:
GenericULong = (
NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
NDIS_MAC_OPTION_NO_LOOPBACK |
NDIS_MAC_OPTION_RECEIVE_SERIALIZED);
break;
case OID_GEN_SUPPORTED_LIST:
MoveSource = (PVOID)(&UbneiGlobalSupportedOids);
MoveBytes = sizeof(UbneiGlobalSupportedOids);
break;
case OID_GEN_HARDWARE_STATUS:
HardwareStatus = NdisHardwareStatusReady;
MoveSource = (PVOID)(&HardwareStatus);
MoveBytes = sizeof(NDIS_HARDWARE_STATUS);
break;
case OID_GEN_MEDIA_SUPPORTED:
case OID_GEN_MEDIA_IN_USE:
MoveSource = (PVOID) (&Medium);
MoveBytes = sizeof(NDIS_MEDIUM);
break;
case OID_GEN_MAXIMUM_LOOKAHEAD:
GenericULong = pAdapter->ReceiveBufSize-14;
break;
case OID_GEN_MAXIMUM_FRAME_SIZE:
GenericULong = (ULONG)(1514 - 14);
break;
case OID_GEN_MAXIMUM_TOTAL_SIZE:
GenericULong = (ULONG)(1514);
break;
case OID_GEN_LINK_SPEED:
GenericULong = (ULONG)(100000);
break;
case OID_GEN_TRANSMIT_BUFFER_SPACE:
GenericULong = pAdapter->TransmitBufferSpace;
break;
case OID_GEN_RECEIVE_BUFFER_SPACE:
GenericULong = pAdapter->ReceiveBufferSpace;
break;
case OID_GEN_TRANSMIT_BLOCK_SIZE:
GenericULong = pAdapter->TransmitBlockSize;
break;
case OID_GEN_RECEIVE_BLOCK_SIZE:
GenericULong = pAdapter->ReceiveBlockSize;
break;
case OID_GEN_VENDOR_ID:
NdisMoveMemory(
(PVOID)&GenericULong,
pAdapter->PermanentAddress,
3
);
GenericULong &= 0xFFFFFF00;
break;
case OID_GEN_VENDOR_DESCRIPTION:
MoveSource = (PVOID)"UBNEI Ethernet Adapter.";
MoveBytes = 24;
break;
case OID_GEN_DRIVER_VERSION:
GenericUShort = ((USHORT)UBNEI_NDIS_MAJOR_VERSION << 8) |
UBNEI_NDIS_MINOR_VERSION;
MoveSource = (PVOID)(&GenericUShort);
MoveBytes = sizeof(GenericUShort);
break;
case OID_GEN_CURRENT_LOOKAHEAD:
GenericULong = (ULONG)(pAdapter->MaxLookAhead);
IF_REQ_LOUD(DbgPrint("Querying LookAhead: %d\n,GenericULong");)
break;
case OID_802_3_PERMANENT_ADDRESS:
IF_REQ_LOUD(DbgPrint("Querying Permanent address\n");)
NdisMoveMemory((PCHAR)GenericArray,
pAdapter->PermanentAddress,
ETH_LENGTH_OF_ADDRESS);
MoveSource = (PVOID)(GenericArray);
MoveBytes = sizeof(pAdapter->PermanentAddress);
break;
case OID_802_3_CURRENT_ADDRESS:
IF_REQ_LOUD(DbgPrint("Querying Current address\n");)
NdisMoveMemory(
(PCHAR)GenericArray,
pAdapter->StationAddress,
ETH_LENGTH_OF_ADDRESS
);
MoveSource = (PVOID)(GenericArray);
MoveBytes = sizeof(pAdapter->StationAddress);
break;
case OID_802_3_MAXIMUM_LIST_SIZE:
GenericULong = (ULONG) DEFAULT_MULTICAST_SIZE;
break;
case OID_GEN_XMIT_OK:
NdisReadRegisterUlong(
&pRcvDWindow->sst.SST_TotalFramesTransmitted,
&GenericULong
);
break;
case OID_GEN_RCV_OK:
NdisReadRegisterUlong(
(PUCHAR)&pRcvDWindow->sst.SST_TotalFramesReceived,
&GenericULong
);
break;
case OID_GEN_XMIT_ERROR:
GenericULong = pAdapter->FramesXmitBad;
break;
case OID_GEN_RCV_ERROR:
NdisReadRegisterUlong(
(PUCHAR)&pRcvDWindow->sst.SST_FramesReceivedWithErrors,
&GenericULong
);
break;
case OID_GEN_RCV_NO_BUFFER:
GenericULong = (UINT)(pAdapter->MissedPackets);
break;
case OID_802_3_RCV_ERROR_ALIGNMENT:
GenericULong = (UINT)pAdapter->FrameAlignmentErrors;
break;
case OID_802_3_XMIT_ONE_COLLISION:
GenericULong = (UINT)pAdapter->FramesXmitOneCollision;
break;
case OID_802_3_XMIT_MORE_COLLISIONS:
GenericULong = (UINT)pAdapter->FramesXmitManyCollisions;
break;
default:
StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
break;
}
if (StatusToReturn == NDIS_STATUS_SUCCESS) {
if (MoveBytes > BytesLeft) {
//
// Not enough room in InformationBuffer. Punt
//
*BytesNeeded = MoveBytes;
StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
} else {
//
// Store result.
//
NdisMoveMemory(InfoBuffer, MoveSource, MoveBytes);
(*BytesWritten) = MoveBytes;
}
}
#if DBG
if (StatusToReturn != NDIS_STATUS_SUCCESS) {
IF_REQ_LOUD(DbgPrint("Out QueryInfo oid=%08lx failed\n",Oid);)
}
#endif
IF_VERY_LOUD( DbgPrint("Out QueryProtocol\n");)
return StatusToReturn;
}
NDIS_STATUS
UbneiSetInformation(
IN NDIS_HANDLE MiniportContext,
IN NDIS_OID Oid,
IN PVOID InfoBuffer,
IN ULONG BytesLeft,
OUT PULONG BytesRead,
OUT PULONG BytesNeeded
)
/*++
Routine Description:
The UbneiSetInformation is used by UbneiRequest to set information
about the MAC.
Arguments:
Adapter - A pointer to the adapter.
Open - A pointer to an open instance.
NdisRequest - A structure which contains the request type (Set),
an array of operations to perform, and an array for holding
the results of the operations.
Return Value:
The function value is the status of the operation.
--*/
{
//
// General Algorithm:
//
// Verify length
// Switch(Request)
// Process Request
//
//
// Variables for a particular request
//
PUBNEI_ADAPTER pAdapter=MiniportContext;
UINT OidLength;
//
// Variables for holding the new values to be used.
//
ULONG LookAhead;
ULONG Filter;
NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
IF_REQ_LOUD( DbgPrint("Ubnei: SetInfo %08lx %0d\n",(UINT)Oid,BytesLeft);)
//
// Get Oid and Length of request
//
OidLength = BytesLeft;
switch (Oid) {
case OID_802_3_MULTICAST_LIST:
//
// Verify length
//
if ((OidLength % ETH_LENGTH_OF_ADDRESS) != 0){
StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
*BytesRead = 0;
*BytesNeeded = 0;
break;
}
#if DBG
{
UINT j;
PUCHAR Address;
Address=InfoBuffer;
for (j=0; j<(OidLength / ETH_LENGTH_OF_ADDRESS); j++) {
IF_REQ_LOUD(DbgPrint(" %02x-%02x-%02x-%02x-%02x-%02x\n",
Address[j*6],
Address[j*6+1],
Address[j*6+2],
Address[j*6+3],
Address[j*6+4],
Address[j*6+5]);)
}
}
#endif
StatusToReturn=UbneiAddressChangeAction(
OidLength,
(PUCHAR)InfoBuffer,
pAdapter
);
break;
case OID_GEN_CURRENT_PACKET_FILTER:
//
// Verify length
//
if (OidLength != 4 ) {
StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
*BytesRead = 0;
*BytesNeeded = 0;
break;
}
NdisMoveMemory(&Filter, InfoBuffer, 4);
StatusToReturn=UbneiFilterChangeAction(
Filter,
pAdapter
);
break;
case OID_GEN_CURRENT_LOOKAHEAD:
//
// Verify length
//
if (OidLength != 4) {
StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
*BytesRead = 0;
*BytesNeeded = 0;
break;
}
NdisMoveMemory(
&LookAhead,
InfoBuffer,
4
);
IF_REQ_LOUD(DbgPrint("Setting LookAhead: %d\n",LookAhead);)
if (LookAhead <= pAdapter->ReceiveBufSize-14) {
pAdapter->MaxLookAhead=LookAhead;
} else {
StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
}
break;
case OID_GEN_PROTOCOL_OPTIONS:
StatusToReturn = NDIS_STATUS_SUCCESS;
break;
default:
StatusToReturn = NDIS_STATUS_INVALID_OID;
*BytesRead = 0;
*BytesNeeded = 0;
break;
}
if (StatusToReturn == NDIS_STATUS_SUCCESS) {
*BytesRead = BytesLeft;
*BytesNeeded = 0;
}
#if DBG
if ((StatusToReturn != NDIS_STATUS_SUCCESS)
&&
(StatusToReturn != NDIS_STATUS_PENDING)) {
IF_REQ_LOUD(DbgPrint("Out SetInfo oid=%08lx failed\n",Oid);)
}
#endif
return StatusToReturn;;
}