?? asyncmac.c
字號:
/* Copyright (c) 1999-2000 Microsoft Corporation. All rights reserved. */
#include "windows.h"
#include "tapi.h"
#include "ndis.h"
#include "ndiswan.h"
#include "ndistapi.h"
#include "asyncmac.h"
#include "frame.h"
#include "cclib.h"
#define DEV_CLASS_COMM_DATAMODEM TEXT("comm/datamodem")
#ifdef DEBUG
DBGPARAM dpCurSettings = {
TEXT("AsyncMac"), {
TEXT("Init"), TEXT("Undefined"),TEXT("Undefined"),TEXT("Undefined"),
TEXT("Undefined"),TEXT("Send"), TEXT("Undefined"),TEXT("Undefined"),
TEXT("Tapi"), TEXT("Recv"), TEXT("Interface"),TEXT("Misc"),
TEXT("Alloc"), TEXT("Function"), TEXT("Warning"), TEXT("Error") },
0x0000C000
};
#endif // DEBUG
HINSTANCE v_hInstance;
NDIS_HANDLE v_hNdisWrapper;
PDRIVER_OBJECT v_AsyncDriverObject;
DWORD v_GlobalAdapterCount;
// Because this driver only supports a single adapter, it is unnecessary to have
// a list of active adapters. Instead, a single pointer to the active adapter (NULL
// if none active) is sufficient.
PASYNCMAC_ADAPTER v_pAdapter;
CRITICAL_SECTION v_AdapterCS;
NDIS_OID SupportedOids[] = {
OID_GEN_MAC_OPTIONS,
OID_GEN_SUPPORTED_LIST,
OID_GEN_MEDIA_SUPPORTED,
OID_GEN_MEDIA_IN_USE,
OID_GEN_VENDOR_DESCRIPTION,
OID_GEN_VENDOR_ID,
OID_GEN_DRIVER_VERSION,
OID_GEN_HARDWARE_STATUS,
OID_GEN_LINK_SPEED,
OID_GEN_MAXIMUM_LOOKAHEAD,
OID_GEN_CURRENT_LOOKAHEAD,
OID_GEN_MAXIMUM_FRAME_SIZE,
OID_GEN_TRANSMIT_BLOCK_SIZE,
OID_GEN_RECEIVE_BLOCK_SIZE,
OID_GEN_MAXIMUM_TOTAL_SIZE,
OID_GEN_RECEIVE_BUFFER_SPACE,
OID_GEN_TRANSMIT_BUFFER_SPACE,
OID_WAN_CURRENT_ADDRESS,
OID_WAN_PERMANENT_ADDRESS,
OID_WAN_GET_INFO,
OID_WAN_GET_LINK_INFO,
OID_WAN_SET_LINK_INFO,
OID_WAN_MEDIUM_SUBTYPE,
OID_WAN_HEADER_FORMAT,
/* NOT Supported yet
OID_TAPI_GET_ADDRESS_CAPS,
OID_TAPI_GET_EXTENSION_ID,
OID_TAPI_NEGOTIATE_EXT_VERSION,
*/
OID_TAPI_GET_DEV_CAPS,
OID_TAPI_PROVIDER_INITIALIZE,
OID_TAPI_TRANSLATE_ADDRESS,
OID_TAPI_OPEN,
OID_TAPI_MAKE_CALL,
OID_TAPI_DROP,
OID_TAPI_CLOSE_CALL,
OID_TAPI_CLOSE,
/*
OID_WAN_GET_BRIDGE_INFO,
OID_WAN_GET_COMP_INFO,
OID_WAN_GET_STATS_INFO,
OID_WAN_LINE_COUNT,
OID_WAN_PROTOCOL_TYPE,
OID_WAN_QUALITY_OF_SERVICE,
OID_WAN_SET_BRIDGE_INFO,
OID_WAN_SET_COMP_INFO,
*/
};
#if DEBUG
PUCHAR
GetOidString(
NDIS_OID Oid
)
{
PUCHAR OidName = NULL;
#define OID_CASE(oid) case (oid): OidName = #oid; break
switch (Oid)
{
OID_CASE(OID_GEN_CURRENT_LOOKAHEAD);
OID_CASE(OID_GEN_DRIVER_VERSION);
OID_CASE(OID_GEN_HARDWARE_STATUS);
OID_CASE(OID_GEN_LINK_SPEED);
OID_CASE(OID_GEN_MAC_OPTIONS);
OID_CASE(OID_GEN_MAXIMUM_LOOKAHEAD);
OID_CASE(OID_GEN_MAXIMUM_FRAME_SIZE);
OID_CASE(OID_GEN_MAXIMUM_TOTAL_SIZE);
OID_CASE(OID_GEN_MEDIA_SUPPORTED);
OID_CASE(OID_GEN_MEDIA_IN_USE);
OID_CASE(OID_GEN_RECEIVE_BLOCK_SIZE);
OID_CASE(OID_GEN_RECEIVE_BUFFER_SPACE);
OID_CASE(OID_GEN_SUPPORTED_LIST);
OID_CASE(OID_GEN_TRANSMIT_BLOCK_SIZE);
OID_CASE(OID_GEN_TRANSMIT_BUFFER_SPACE);
OID_CASE(OID_GEN_VENDOR_DESCRIPTION);
OID_CASE(OID_GEN_VENDOR_ID);
OID_CASE(OID_802_3_CURRENT_ADDRESS);
OID_CASE(OID_TAPI_ACCEPT);
OID_CASE(OID_TAPI_ANSWER);
OID_CASE(OID_TAPI_CLOSE);
OID_CASE(OID_TAPI_CLOSE_CALL);
OID_CASE(OID_TAPI_CONDITIONAL_MEDIA_DETECTION);
OID_CASE(OID_TAPI_CONFIG_DIALOG);
OID_CASE(OID_TAPI_DEV_SPECIFIC);
OID_CASE(OID_TAPI_DIAL);
OID_CASE(OID_TAPI_DROP);
OID_CASE(OID_TAPI_GET_ADDRESS_CAPS);
OID_CASE(OID_TAPI_GET_ADDRESS_ID);
OID_CASE(OID_TAPI_GET_ADDRESS_STATUS);
OID_CASE(OID_TAPI_GET_CALL_ADDRESS_ID);
OID_CASE(OID_TAPI_GET_CALL_INFO);
OID_CASE(OID_TAPI_GET_CALL_STATUS);
OID_CASE(OID_TAPI_GET_DEV_CAPS);
OID_CASE(OID_TAPI_GET_DEV_CONFIG);
OID_CASE(OID_TAPI_GET_EXTENSION_ID);
OID_CASE(OID_TAPI_GET_ID);
OID_CASE(OID_TAPI_GET_LINE_DEV_STATUS);
OID_CASE(OID_TAPI_MAKE_CALL);
OID_CASE(OID_TAPI_NEGOTIATE_EXT_VERSION);
OID_CASE(OID_TAPI_OPEN);
OID_CASE(OID_TAPI_PROVIDER_INITIALIZE);
OID_CASE(OID_TAPI_PROVIDER_SHUTDOWN);
OID_CASE(OID_TAPI_SECURE_CALL);
OID_CASE(OID_TAPI_SELECT_EXT_VERSION);
OID_CASE(OID_TAPI_SEND_USER_USER_INFO);
OID_CASE(OID_TAPI_SET_APP_SPECIFIC);
OID_CASE(OID_TAPI_SET_CALL_PARAMS);
OID_CASE(OID_TAPI_SET_DEFAULT_MEDIA_DETECTION);
OID_CASE(OID_TAPI_SET_DEV_CONFIG);
OID_CASE(OID_TAPI_SET_MEDIA_MODE);
OID_CASE(OID_TAPI_SET_STATUS_MESSAGES);
OID_CASE(OID_TAPI_TRANSLATE_ADDRESS);
OID_CASE(OID_WAN_CURRENT_ADDRESS);
OID_CASE(OID_WAN_GET_BRIDGE_INFO);
OID_CASE(OID_WAN_GET_COMP_INFO);
OID_CASE(OID_WAN_GET_INFO);
OID_CASE(OID_WAN_GET_LINK_INFO);
OID_CASE(OID_WAN_GET_STATS_INFO);
OID_CASE(OID_WAN_HEADER_FORMAT);
OID_CASE(OID_WAN_LINE_COUNT);
OID_CASE(OID_WAN_MEDIUM_SUBTYPE);
OID_CASE(OID_WAN_PERMANENT_ADDRESS);
OID_CASE(OID_WAN_PROTOCOL_TYPE);
OID_CASE(OID_WAN_QUALITY_OF_SERVICE);
OID_CASE(OID_WAN_SET_BRIDGE_INFO);
OID_CASE(OID_WAN_SET_COMP_INFO);
OID_CASE(OID_WAN_SET_LINK_INFO);
default:
OidName = "Unknown OID";
break;
}
return OidName;
}
#endif
//
// This constant is used for places where NdisAllocateMemory
// needs to be called and the HighestAcceptableAddress does
// not matter.
//
NDIS_PHYSICAL_ADDRESS HighestAcceptableMax = NDIS_PHYSICAL_ADDRESS_CONST(-1,-1);
// Number of bytes to allocate before and after each block to look for corruption
#define GUARD_REGION_SIZE 32
#define GUARD_BYTE_VALUE (BYTE)'a'
#ifdef DEBUG
BOOL
memchk(
BYTE *pMem,
BYTE bValue,
UINT nBytes)
//
// Return true if the bytes at pMem are all set to bValue.
//
{
BYTE *pStartMem = pMem;
UINT nOrigBytes = nBytes;
//DEBUGMSG (1, (TEXT("Check %x bytes at %x\n"), nBytes, pMem));
while (nBytes--)
if (*pMem++ != bValue)
{
DumpMem(pStartMem, nOrigBytes);
DebugBreak();
return FALSE;
}
return TRUE;
}
BOOL
AsyncMacGuardRegionOk(
IN void *pMem,
IN UINT nBytes)
//
// Validate the guard regions at the start and end of a block of allocated memory.
//
{
BOOL bResult;
pMem = (BYTE *)pMem - GUARD_REGION_SIZE;
bResult = memchk(pMem, GUARD_BYTE_VALUE, GUARD_REGION_SIZE)
&& memchk((BYTE *)pMem + nBytes + GUARD_REGION_SIZE, GUARD_BYTE_VALUE, GUARD_REGION_SIZE);
if (bResult == FALSE)
DEBUGMSG(1, (TEXT("MemCorrupted: pMem=%x size=%x\n"), pMem, nBytes));
return bResult;
}
#endif
void *
AsyncMacAllocateMemory(
IN UINT nBytes)
//
// Call NdisAllocateMemory to allocate a block of the requested size.
// In DEBUG mode, allocate leading and trailing guard regions to look for memory corruption.
//
{
void *pMem;
NDIS_STATUS Status;
#ifdef DEBUG
nBytes += 2 * GUARD_REGION_SIZE;
#endif
Status = NdisAllocateMemory( (PVOID *)&pMem, nBytes, 0, HighestAcceptableMax);
if (Status != NDIS_STATUS_SUCCESS)
{
DEBUGMSG (ZONE_ERROR, (TEXT("+ASYNCMAC: AllocMem %d bytes failed\n")));
pMem = NULL;
}
#ifdef DEBUG
else
{
memset(pMem, GUARD_BYTE_VALUE, GUARD_REGION_SIZE);
memset((BYTE *)pMem + nBytes - GUARD_REGION_SIZE, GUARD_BYTE_VALUE, GUARD_REGION_SIZE);
pMem = (BYTE *)pMem + GUARD_REGION_SIZE;
ASSERT(AsyncMacGuardRegionOk(pMem, nBytes - 2 * GUARD_REGION_SIZE));
}
#endif
return pMem;
}
void
AsyncMacFreeMemory(
IN void *pMem,
IN UINT nBytes)
{
#ifdef DEBUG
ASSERT(AsyncMacGuardRegionOk(pMem, nBytes));
pMem = (BYTE *)pMem - GUARD_REGION_SIZE;
nBytes += 2 * GUARD_REGION_SIZE;
#endif
NdisFreeMemory(pMem, nBytes, 0);
}
//
// ZZZ Portable interface.
//
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
/*++
Routine Description:
This is the primary initialization routine for the async driver.
It is simply responsible for the intializing the wrapper and registering
the MAC. It then calls a system and architecture specific routine that
will initialize and register each adapter.
Arguments:
DriverObject - Pointer to driver object created by the system.
Return Value:
The status of the operation.
--*/
{
NDIS_STATUS InitStatus;
NDIS_MINIPORT_CHARACTERISTICS AsyncChar;
DEBUGMSG (ZONE_INIT|ZONE_INTERFACE,
(TEXT("+ASYNCMAC:DriverEntry(0x%X, 0x%X)\r\n"),
DriverObject, RegistryPath));
v_AsyncDriverObject = DriverObject;
v_pAdapter = NULL;
//
// Initialize the wrapper.
//
NdisMInitializeWrapper(&v_hNdisWrapper, DriverObject,
RegistryPath, NULL);
//
// Initialize the MAC characteristics for the call to NdisRegisterMac.
//
NdisZeroMemory(&AsyncChar, sizeof(AsyncChar));
AsyncChar.MajorNdisVersion = ASYNC_NDIS_MAJOR_VERSION;
AsyncChar.MinorNdisVersion = ASYNC_NDIS_MINOR_VERSION;
AsyncChar.Reserved = NDIS_USE_WAN_WRAPPER;
//
// We do not need the following handlers:
// CheckForHang
// DisableInterrupt
// EnableInterrupt
// HandleInterrupt
// ISR
// Send
// TransferData
//
AsyncChar.HaltHandler = MpHalt;
AsyncChar.InitializeHandler = MpInit;
AsyncChar.QueryInformationHandler = MpQueryInfo;
AsyncChar.ReconfigureHandler = MpReconfigure;
AsyncChar.ResetHandler = MpReset;
AsyncChar.WanSendHandler = MpSend;
AsyncChar.SetInformationHandler = MpSetInfo;
InitStatus = NdisMRegisterMiniport(v_hNdisWrapper,
&AsyncChar,
sizeof(AsyncChar));
if ( InitStatus == NDIS_STATUS_SUCCESS ) {
DEBUGMSG (ZONE_INIT|ZONE_INTERFACE,
(TEXT("-ASYNCMAC:DriverEntry: Returning STATUS_SUCCESS\r\n"),
DriverObject, RegistryPath));
return NDIS_STATUS_SUCCESS;
}
NdisTerminateWrapper(v_hNdisWrapper, DriverObject);
DEBUGMSG (ZONE_INIT|ZONE_INTERFACE|ZONE_ERROR,
(TEXT("-ASYNCMAC:DriverEntry: Returning STATUS_FAILURE\r\n"),
DriverObject, RegistryPath));
return NDIS_STATUS_FAILURE;
}
//
// Standard Windows DLL entrypoint.
// Since Windows CE NDIS miniports are implemented as DLLs, a DLL entrypoint is
// needed.
//
BOOL __stdcall
DllEntry(
HANDLE hDLL,
DWORD dwReason,
LPVOID lpReserved
)
{
switch (dwReason) {
case DLL_PROCESS_ATTACH:
v_hInstance = (HINSTANCE) hDLL;
DEBUGREGISTER(hDLL);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -