📄 ndisprot.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
// Include Files
#include "windows.h"
#include "ndis.h"
#include "ras.h"
#include "raserror.h"
#include "cxport.h"
#include "protocol.h"
#include "ppp.h"
#include "lcp.h"
#include "macp.h"
#include "ndistapi.h"
#include "cclib.h"
typedef DWORD IPAddr;
typedef DWORD IPMask;
#include "ip_intf.h"
// ----------------------------------------------------------------
//
// Global Data
//
// ----------------------------------------------------------------
#define PPP_NDIS_PROTOCOL_NAME TEXT("PPP")
static WCHAR NDISPROTName[] = PPP_NDIS_PROTOCOL_NAME;
#ifndef NDIS_API
#define NDIS_API
#endif
// Some forward declarations
void NDIS_API PROTOAComplete(NDIS_HANDLE Handle, NDIS_STATUS Status,
NDIS_STATUS ErrorStatus);
void NDIS_API PROTCAComplete(NDIS_HANDLE Handle, NDIS_STATUS Status);
void NDIS_API PROTSendComplete(NDIS_HANDLE Handle, PNDIS_WAN_PACKET Packet,
NDIS_STATUS Status);
void NDIS_API PROTTDComplete(NDIS_HANDLE Handle, PNDIS_PACKET Packet,
NDIS_STATUS Status, uint BytesCopied);
void NDIS_API PROTResetComplete(NDIS_HANDLE Handle, NDIS_STATUS Status);
void NDIS_API PROTRequestComplete(NDIS_HANDLE Handle, PNDIS_REQUEST Request,
NDIS_STATUS Status);
NDIS_STATUS NDIS_API PROTWanRcv(NDIS_HANDLE Handle, PUCHAR Packet, ULONG PacketSize);
void NDIS_API PROTWanRcvComplete(NDIS_HANDLE Handle);
void NDIS_API PROTStatus(NDIS_HANDLE Handle, NDIS_STATUS GStatus, void *Status,
uint StatusSize);
void NDIS_API PROTStatusComplete(NDIS_HANDLE Handle);
void NDIS_API PROTBindAdapter(PNDIS_STATUS RetStatus, NDIS_HANDLE BindContext,
PNDIS_STRING AdapterName, PVOID SS1, PVOID SS2);
void NDIS_API PROTUnbindAdapter(PNDIS_STATUS RetStatus,
NDIS_HANDLE ProtBindContext,
NDIS_HANDLE UnbindContext);
NDIS_PROTOCOL_CHARACTERISTICS PROTCharacteristics = {
4, // MAJOR Version
0, // MINOR Version
0,
PROTOAComplete,
PROTCAComplete,
(SEND_COMPLETE_HANDLER)PROTSendComplete,
PROTTDComplete,
PROTResetComplete,
PROTRequestComplete,
(RECEIVE_HANDLER)PROTWanRcv,
PROTWanRcvComplete,
PROTStatus,
PROTStatusComplete,
{
sizeof(PPP_NDIS_PROTOCOL_NAME) - sizeof(WCHAR), // Length in bytes not including terminating NULL
sizeof(PPP_NDIS_PROTOCOL_NAME) - sizeof(WCHAR), // MaximumLength in bytes
PPP_NDIS_PROTOCOL_NAME // PWSTR Buffer
},
NULL, // Receive Packet Handler
PROTBindAdapter, // BindAdapterHandler
PROTUnbindAdapter, // UnbindAdapterHandler
NULL, // TranslateHandler
NULL // UnloadHandler
};
#if DEBUG
PCHAR
GetOidString(
NDIS_OID Oid
)
{
PCHAR OidName;
#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
DWORD
DoNDISRegisterProtocol()
{
NDIS_STATUS Status; // Status for NDIS calls.
DEBUGMSG (ZONE_TRACE, (TEXT("+DoNDISRegisterProtocol\r\n")));
NdisRegisterProtocol(&Status, &v_PROTHandle,
(NDIS_PROTOCOL_CHARACTERISTICS *)
&PROTCharacteristics, sizeof(PROTCharacteristics));
if (Status != NDIS_STATUS_SUCCESS)
{
DEBUGMSG (ZONE_TRACE,
(TEXT(" pppMac_Initialize: Error %d from NdisRegisterProtocol\r\n"),
Status));
return ERROR_EVENT_INVALID;
}
return SUCCESS;
}
//** PROTOAComplete - PROT Open adapter complete handler.
//
// This routine is called by the NDIS driver when an open adapter
// call completes. Presumably somebody is blocked waiting for this, so
// we'll wake him up now.
//
// Entry:
// Handle - The binding handle we specified (really a pointer to an AI).
// Status - Final status of command.
// ErrorStatus - Final error status.
//
// Exit: Nothing.
//
void NDIS_API
PROTOAComplete(NDIS_HANDLE Handle, NDIS_STATUS Status, NDIS_STATUS ErrorStatus)
{
// PROTInterface *ai = (PROTInterface *)Handle; // For compiler.
DEBUGMSG (ZONE_FUNCTION, (TEXT("+PROTOAComplete(0x%X, 0x%X, 0x%X)\r\n"),
Handle, Status, ErrorStatus));
// CTESignal(&ai->ai_block, (uint)Status); // Wake him up, and return status.
DEBUGMSG (ZONE_FUNCTION, (TEXT("-PROTOAComplete:\r\n"), Handle, Status, ErrorStatus));
}
//** PROTCAComplete - PROT close adapter complete handler.
//
// This routine is called by the NDIS driver when a close adapter
// request completes.
//
// Entry:
// Handle - The binding handle we specified (really a pointer to an AI).
// Status - Final status of command.
//
// Exit: Nothing.
//
void NDIS_API
PROTCAComplete(
IN NDIS_HANDLE Handle,
IN NDIS_STATUS Status)
{
DWORD i;
PNDISWAN_ADAPTER pAdapter = (PNDISWAN_ADAPTER)Handle;
DEBUGMSG (ZONE_FUNCTION, (TEXT("PPP: +PROTCAComplete(0x%X, 0x%X)\r\n"),Handle, Status));
DEBUGMSG(ZONE_MAC || (ZONE_ERROR && Status), (TEXT("PPP: NdisCloseAdapter %s Complete Status=%x\n"), pAdapter->szAdapterName, Status));
if (pAdapter->hUnbindContext)
{
//
// The CloseAdapter was initiated by a call to our UnbindAdapter Handler, from
// which we returned NDIS_STATUS_PENDING. We now invoke the completion handler.
//
DEBUGMSG(ZONE_MAC, (TEXT("PPP: Completing Unbind for adapter %s Complete Status=%x\n"), pAdapter->szAdapterName, Status));
NdisCompleteUnbindAdapter(pAdapter->hUnbindContext, Status);
}
for (i = 0; i < pAdapter->dwNumDevices; i++)
{
LocalFree(pAdapter->pDeviceInfo[i].pwszDeviceName);
}
pppFreeMemory (pAdapter->pDeviceInfo, pAdapter->dwNumDevices * sizeof(*pAdapter->pDeviceInfo));
pppFreeMemory (pAdapter->szAdapterName, (wcslen(pAdapter->szAdapterName)+1)*sizeof(WCHAR));
pppFreeMemory (pAdapter, sizeof (NDISWAN_ADAPTER));
DEBUGMSG (ZONE_FUNCTION, (TEXT("-PROTCAComplete:\r\n")));
}
//** PROTSendComplete - PROT send complete handler.
//
// This routine is called by the NDIS driver when a send completes.
// This is a pretty time critical operation, we need to get through here
// quickly. We'll strip our buffer off and put it back, and call the upper
// later send complete handler.
//
// Entry:
// Handle - The binding handle we specified (really a pointer to an AI).
// Packet - A pointer to the packet that was sent.
// Status - Final status of command.
//
// Exit: Nothing.
//
void NDIS_API
PROTSendComplete(
NDIS_HANDLE Handle,
PNDIS_WAN_PACKET pPacket,
NDIS_STATUS Status)
{
//
// The Handle is pretty useless since it refers to the miniport
// adapter binding and not to the particular active session. So,
// we need to get our pMac via the packet. In pppMac_GetPacket
// we saved our pMac in the packet's ProtocolReserved1 field.
//
macCntxt_t *pMac = (macCntxt_t *)pPacket->ProtocolReserved1;
pppSession_t *pSession;
DEBUGMSG(ZONE_MAC || (ZONE_ERROR && Status), (L"PPP: ProtSendComplete: pPacket=%x Status=%x\n", pPacket, Status));
pSession = PPPADDREFMAC(pMac, REF_SEND_COMPLETE);
if (pSession)
{
NdisWanFreePacket(pMac, pPacket);
PPPDELREF(pSession, REF_SEND_COMPLETE);
}
}
//** PROTTDComplete - PROT transfer data complete handler.
//
// This routine is called by the NDIS driver when a transfer data
// call completes. Since we never transfer data ourselves, this must be
// from the upper layer. We'll just call his routine and let him deal
// with it.
//
// Entry:
// Handle - The binding handle we specified (really a pointer to an AI).
// Packet - A pointer to the packet used for the TD.
// Status - Final status of command.
// BytesCopied - Count of bytes copied.
//
// Exit: Nothing.
//
void NDIS_API
PROTTDComplete(NDIS_HANDLE Handle, PNDIS_PACKET Packet, NDIS_STATUS Status,
uint BytesCopied)
{
// PROTInterface *ai = (PROTInterface *)Handle;
DEBUGMSG (ZONE_FUNCTION, (TEXT("+PROTTDComplete(0x%X, 0x%X, 0x%X, %d)\r\n"),
Handle, Packet, Status, BytesCopied));
// IPTDComplete(ai->ai_context, Packet, Status, BytesCopied);
}
//** PROTResetComplete - PROT reset complete handler.
//
// This routine is called by the NDIS driver when a reset completes.
//
// Entry:
// Handle - The binding handle we specified (really a pointer to an AI).
// Status - Final status of command.
//
// Exit: Nothing.
//
void NDIS_API
PROTResetComplete(NDIS_HANDLE Handle, NDIS_STATUS Status)
{
DEBUGMSG (ZONE_FUNCTION, (TEXT("+PROTResetComplete(0x%X, 0x%X)\r\n"),
Handle, Status));
}
VOID
PppNdisFreeRequest(
PNDIS_REQUEST_BETTER pRequest)
{
// This is to be used during calls using an event, not a callback func
ASSERT (pRequest->pCompletionFunc == NULL);
// Free the event
NdisFreeEvent(&pRequest->Event);
// Free the request
DEBUGMSG(ZONE_ALLOC, (TEXT("PPP: PppNdisFreeRequest Free pRequest=%x\n"), pRequest));
pppFreeMemory(pRequest, sizeof(*pRequest));
}
VOID
PppNdisRequestCompleteCb(
PNDIS_REQUEST_BETTER pRequest,
NDIS_STATUS Status
)
//
// This function is called when an NDIS request has completed.
// A request is completed when:
// Synchronously: NdisRequest returns a status other than PENDING
// Asynchronously: NdisRequest returns PENDING and the Protocol Request Complete Handler is called
//
{
//
// Call the completion function if there is one.
// Having a completion function and blocking against the
// event are mutually exclusive,
//
if( pRequest->pCompletionFunc != NULL )
{
if (pRequest->pSession)
pppLock(pRequest->pSession);
(*pRequest->pCompletionFunc)(pRequest, pRequest->FuncArg, Status);
if (pRequest->pSession)
{
pppUnLock(pRequest->pSession);
// Delete the session reference taken in PppNdisIssueRequest to
// prevent it from going away while request was in progress
PPPDELREF(pRequest->pSession, REF_ISSUEREQUEST);
}
// Free the request
DEBUGMSG(ZONE_ALLOC, (TEXT("PPP: PppNdisRequestCompleteCb Free pRequest=%x\n"), pRequest));
pppFreeMemory(pRequest, sizeof(*pRequest));
}
else // Requesting thread is blocked on event
{
// Communicate final status to blocked caller
pRequest->Status = Status;
NdisSetEvent( &pRequest->Event );
// We can't free the request since we're using it to
// return the Status to the thread blocked on the event.
// The waiting thread must free
// the event and the request by calling PppNdisFreeRequest.
}
}
VOID
PROTRequestComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_REQUEST NdisRequest,
IN NDIS_STATUS Status
)
/*++
Routine Description:
Completion handler for the previously posted request.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -