📄 hostmini.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Module Name:
miniport.c
Abstract:
This module implements the miniport functionality for the RNDIS host.
Functions:
--*/
#include <windows.h>
#include <halether.h>
#ifdef ZONE_INIT
#undef ZONE_INIT
#endif
#ifdef ZONE_WARNING
#undef ZONE_WARNING
#endif
#include <ndis.h>
#include <linklist.h>
#include <rndismini.h>
#include "rndis.h"
#include "mddpriv.h"
#include <celog.h>
////////////////////////////////////////////////////////////////////////////////
// Global variables used by mdd module.
//
static UCHAR DefaultVendorDescription[] = "Microsoft Virtual Rndis Miniport\0";
static UCHAR DefaultVendorID[] = "MSFT";
//
// Where we alloc and queue RNdis message list..
//
//NPAGED_LOOKASIDE_LIST DataWrapperLookAsideList;
//
// Global Structure used by MDD module.
// Initialized in wince.c
//
RNDIS_MDD RndisMdd;
UINT RNdisMddSupportedOids[] =
{
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_DESCRIPTION,
OID_GEN_VENDOR_ID,
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_CRC_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,
OID_GEN_MAXIMUM_SEND_PACKETS,
OID_GEN_VENDOR_DRIVER_VERSION,
OID_GEN_MEDIA_CONNECT_STATUS,
#ifdef NDIS50_MINIPORT
//
// Power Management..
//
OID_PNP_CAPABILITIES,
OID_PNP_SET_POWER,
OID_PNP_QUERY_POWER,
OID_PNP_ADD_WAKE_UP_PATTERN,
OID_PNP_REMOVE_WAKE_UP_PATTERN,
OID_PNP_ENABLE_WAKE_UP
#endif
};
////////////////////////////////////////////////////////////////////////////////
// HostMiniExtractOneDataWrapper()
//
// Routine Description:
//
// This function will extract one DATA_WRAPPER from listInRndisPacket.
//
// Arguments:
//
// None.
//
// Return Value:
//
// PDATA_WRAPPER or NULL if both queue is empty.
//
/*
PDATA_WRAPPER
HostMiniExtractOneDataWrapper(void)
{
PLIST_ENTRY pLink = NULL;
PDATA_WRAPPER pDataWrapper = NULL;
EnterCriticalSection(&(RndisMdd.lockInRndisPackets));
if (!IsListEmpty(&(RndisMdd.listInRndisPackets)))
{
pLink = RemoveHeadList(
&(RndisMdd.listInRndisPackets));
}
LeaveCriticalSection(&(RndisMdd.lockInRndisPackets));
if (pLink)
{
//
// Getting here means we have a message to process.
//
pDataWrapper = CONTAINING_RECORD(
pLink,
DATA_WRAPPER,
Link);
}
return pDataWrapper;
} // HostMiniExtractOneDataWrapper()
*/
////////////////////////////////////////////////////////////////////////////////
// HostMiniThread()
//
// Routine Description:
//
// This is the main thread listening and servicing all RNDIS and
// Virtual Ethernet transactions..
//
// Arguments:
//
// None.
//
// Return Value:
//
// TRUE if successful, FALSE otherwise.
//
/*
void
HostMiniThread(void)
{
PDATA_WRAPPER pDataWrapper;
CELOGMSG (ZONE_HOSTMINI | ZONE_RNDIS,
(TEXT("HostMiniThread() starts..\r\n")));
RndisMdd.dwMddFlag |= MDD_FLAG_WAITING;
////////////////////////////////////////////////////////////////////////////
// This loop runs forever..
//
while (1)
{
WaitForSingleObject(
RndisMdd.hRndisMddEvent,
INFINITE);
if (RndisMdd.bQuitNow)
{
CloseHandle(RndisMdd.hRndisMddEvent);
return;
}
//
// Get here when there is NDIS message to look at..
// Make sure everyone knows that we are no longer waiting..
//
EnterCriticalSection(&(RndisMdd.lockMdd));
RndisMdd.dwMddFlag &= ~MDD_FLAG_WAITING;
LeaveCriticalSection(&(RndisMdd.lockMdd));
//
// Immediately RESET the event, to make sure that event between the
// flag set to WAITING and WaitForSingleObject(), will trigger.
//
ResetEvent (RndisMdd.hRndisMddEvent);
//
// Start popping messages and service them..
//
while(1)
{
//
// Get one RNDIS packet.
//
pDataWrapper = HostMiniExtractOneDataWrapper();
if (pDataWrapper == NULL)
{
//
// The only way outta the loop..
//
break;
}
CELOGMSG (0, (TEXT(">> Buf[0x%x]-l[%d]\r\n"),
pDataWrapper->pucData,
pDataWrapper->dwDataSize));
//
// Call the RNDIS packet handler routine to process
// the packet then free the resources associated with the msg.
//
RndisProcessPacket(pDataWrapper);
} // while(1) consuming RNDIS packets.
//
// All done.
// Back to hybernating mode..
//
EnterCriticalSection(&(RndisMdd.lockMdd));
RndisMdd.dwMddFlag |= MDD_FLAG_WAITING;
LeaveCriticalSection(&(RndisMdd.lockMdd));
} // while(1) waiting for event..
} // HostMiniThread()
*/
////////////////////////////////////////////////////////////////////////////////
// HostMiniQueryInformation()
//
// Routine Description:
//
// Process NDIS query request.
//
// Arguments:
//
// NDIS_OID NDIS OID
// PVOID pvInformationBuffer
// ULONG ulInformationBufferLength
// PULONG pulBytesWritten
// PULONG pulBytesNeeded
//
// Return Value:
//
// NDIS_STATUS
//
NDIS_STATUS
HostMiniQueryInformation(
IN NDIS_OID Oid,
IN PVOID pvInformationBuffer,
IN ULONG ulInformationBufferLength,
OUT PULONG pulBytesWritten,
OUT PULONG pulBytesNeeded
)
{
ULONG GenericUlong;
USHORT GenericUshort;
PUCHAR pucBuffer = (PUCHAR)&GenericUlong;
ULONG ulTotalBytes = sizeof(ULONG);
NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
UCHAR pucScrapBuffer[512];
// CELOGMSG (0, (TEXT("HostMini:: QueryInfo() InBuff=[%d] :: "),
// ulInformationBufferLength));
*pulBytesNeeded = *pulBytesWritten = 0;
switch (Oid)
{
////////////////////////////////////////////////////////////////
case OID_GEN_MAC_OPTIONS:
// CELOGMSG (0, (TEXT("OID_GEN_MAC_OPTIONS.\r\n")));
GenericUlong = (ULONG)(NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
NDIS_MAC_OPTION_NO_LOOPBACK);
break;
////////////////////////////////////////////////////////////////////////
case OID_GEN_SUPPORTED_LIST:
// CELOGMSG (0, (TEXT("OID_GEN_SUPPORTED_LIST.\r\n")));
pucBuffer = (PUCHAR)RNdisMddSupportedOids;
ulTotalBytes = sizeof(RNdisMddSupportedOids);
break;
////////////////////////////////////////////////////////////////////////
case OID_GEN_HARDWARE_STATUS:
// CELOGMSG (0, (TEXT("OID_GEN_HARDWARE_STATUS.\r\n")));
GenericUlong = NdisHardwareStatusReady;
break;
////////////////////////////////////////////////////////////////////////
case OID_GEN_MEDIA_SUPPORTED:
case OID_GEN_MEDIA_IN_USE:
// CELOGMSG (0,
// (TEXT("OID_GEN_MEDIA_SUPPORTED/IN_USE.\r\n")));
GenericUlong = NdisMedium802_3;
break;
////////////////////////////////////////////////////////////////////////
case OID_GEN_MAXIMUM_FRAME_SIZE:
// CELOGMSG (0, (TEXT("OID_GEN_MAXIMUM_FRAME_SIZE.\r\n")));
GenericUlong = 1500;
break;
////////////////////////////////////////////////////////////////////////
case OID_GEN_LINK_SPEED:
// CELOGMSG (0, (TEXT("OID_GEN_LINK_SPEED.\r\n")));
GenericUlong = (ULONG)(100000);
break;
////////////////////////////////////////////////////////////////////////
case OID_GEN_TRANSMIT_BLOCK_SIZE:
// CELOGMSG (0,
// (TEXT("OID_GEN_TRANSMIT_BLOCK_SIZE.\r\n")));
GenericUlong = 1518;
break;
////////////////////////////////////////////////////////////////////////
case OID_GEN_RECEIVE_BLOCK_SIZE:
// CELOGMSG (0, (TEXT("OID_GEN_RECEIVE_BLOCK_SIZE.\r\n")));
GenericUlong = 1518;
break;
////////////////////////////////////////////////////////////////////////
case OID_GEN_MAXIMUM_LOOKAHEAD:
// CELOGMSG (0,
// (TEXT("OID_GEN_MAXIMUM_LOOKAHEAD.\r\n")));
GenericUlong = 1500;
break;
////////////////////////////////////////////////////////////////////////
case OID_GEN_VENDOR_ID:
{
ULONG ulRequiredLength;
// CELOGMSG (0, (TEXT("OID_GEN_VENDOR_ID.\r\n")));
//
// Call into PDD to get the Vendor ID.
//
// if (!PDD_Get(
if (!RndisMdd.PddCharacteristics.GetHandler(
REQ_ID_VENDOR_ID,
pucScrapBuffer,
512,
&ulRequiredLength))
{
pucBuffer = DefaultVendorID;
ulTotalBytes = strlen(DefaultVendorID);
}
else
{
pucBuffer = pucScrapBuffer;
ulTotalBytes = ulRequiredLength;
}
break;
}
////////////////////////////////////////////////////////////////////////
case OID_GEN_VENDOR_DESCRIPTION:
{
ULONG ulRequiredLength;
// CELOGMSG (0, (TEXT("OID_GEN_VENDOR_DESCRIPTION.\r\n")));
//
// Call into PDD to get the Vendor ID.
//
// if (!PDD_Get(
if (!RndisMdd.PddCharacteristics.GetHandler(
REQ_ID_VENDOR_DESCRIPTION,
pucScrapBuffer,
512,
&ulRequiredLength))
{
pucBuffer = DefaultVendorDescription;
ulTotalBytes = strlen(DefaultVendorDescription);
}
else
{
pucBuffer = pucScrapBuffer;
ulTotalBytes = ulRequiredLength;
}
break;
}
////////////////////////////////////////////////////////////////////////
case OID_GEN_VENDOR_DRIVER_VERSION:
// CELOGMSG (0,
// (TEXT("OID_GEN_VENDOR_DRIVER_VERSION.\r\n")));
GenericUshort = (MDD_DRIVER_MAJOR_VERSION << 8) +
(MDD_DRIVER_MINOR_VERSION);
pucBuffer = (PUCHAR)&GenericUshort;
ulTotalBytes = sizeof(USHORT);
break;
////////////////////////////////////////////////////////////////////////
case OID_GEN_CURRENT_PACKET_FILTER:
// CELOGMSG (0, (
// TEXT("OID_GEN_CURRENT_PACKET_FILTER.\r\n")));
// CELOGMSG (ZONE_HOSTMINI,
// (TEXT("HostMini:: GET Current Filter = [0x%x]\r\n"),
// RndisMdd.dwCurrentPacketFilter));
GenericUlong = RndisMdd.dwCurrentPacketFilter;
break;
////////////////////////////////////////////////////////////////////////
case OID_GEN_MAXIMUM_TOTAL_SIZE:
// CELOGMSG (0, (TEXT("OID_GEN_MAXIMUM_TOTAL_SIZE.\r\n")));
GenericUlong = (ULONG)(1514);
break;
////////////////////////////////////////////////////////////////////////
case OID_GEN_MEDIA_CONNECT_STATUS:
// CELOGMSG (0,
// (TEXT("OID_GEN_MEDIA_CONNECT_STATUS.\r\n")));
GenericUlong = NdisMediaStateConnected;
break;
////////////////////////////////////////////////////////////////////////
case OID_802_3_PERMANENT_ADDRESS:
// CELOGMSG (0,
// (TEXT("OID_802_3_PERMANENT_ADDRESS.\r\n")));
pucBuffer = RndisMdd.PermanentNwAddr;
ulTotalBytes = 6;
// CELOGMSG (0,
// (TEXT("RndisMdd:: PermanentNetworkAddress = %x%x%x%x%x%x\r\n"),
// pucBuffer[0],
// pucBuffer[1],
// pucBuffer[2],
// pucBuffer[3],
// pucBuffer[4],
// pucBuffer[5]));
break;
////////////////////////////////////////////////////////////////////////
case OID_802_3_CURRENT_ADDRESS:
// CELOGMSG (0,
// (TEXT("OID_802_3_PERMANENT_ADDRESS.\r\n")));
pucBuffer = RndisMdd.PermanentNwAddr;
ulTotalBytes = 6;
// CELOGMSG (0,
// (TEXT("RndisMdd:: CurrentNetworkAddress = %x%x%x%x%x%x\r\n"),
// pucBuffer[0],
// pucBuffer[1],
// pucBuffer[2],
// pucBuffer[3],
// pucBuffer[4],
// pucBuffer[5]));
break;
////////////////////////////////////////////////////////////////
case OID_GEN_MAXIMUM_SEND_PACKETS:
// CELOGMSG (0,
// (TEXT("OID_GEN_MAXIMUM_SEND_PACKETS.\r\n")));
//
// Arbitrarily chosen number..
//
GenericUlong = 16;
break;
////////////////////////////////////////////////////////////////
case OID_802_3_MAXIMUM_LIST_SIZE:
// CELOGMSG (0,
// (TEXT("OID_802_3_MAXIMUM_LIST_SIZE returning [%d]\r\n"),
// RNDIS_MAX_PACKETS_PER_MESSAGE));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -