📄 ndistapi.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.
//
/*****************************************************************************
*
*
* @doc EX_RAS
* ndistapi.c Ndis TAPI utilities
*
*/
// Include Files
#include "windows.h"
#include "ndis.h"
#include "ras.h"
#include "raserror.h"
#include "cxport.h"
#include "protocol.h"
#include "ppp.h"
#include "macp.h"
#include "unimodem.h"
void
ndisTapiProcessDevCaps(
PNDISWAN_ADAPTER pAdapter,
PNDIS_TAPI_GET_DEV_CAPS pGetDevCaps)
//
// This function is called after the adapter has successfully returned
// DevCaps information. We process the returned info and add it to the
// pDeviceInfo array for the adapter.
//
{
DWORD dwDeviceID;
LPTSTR szDeviceName,
szDeviceType,
szMediaName,
szProviderName;
USHORT wDeviceType;
PNDISTAPI_DEVICE_INFO pInfo;
UNIMODEM_INFO *pUnimodemInfo;
BOOL bIsNullModem = FALSE;
dwDeviceID = pGetDevCaps->ulDeviceID;
// We should never have issued a request for a deviceID that is too big
if (dwDeviceID >= pAdapter->dwNumDevices)
{
RETAILMSG(1, (L"PPP: ndisTapiProcessDevCaps ERROR invalid dwDeviceID %u >= %u\n", dwDeviceID, pAdapter->dwNumDevices));
ASSERT(FALSE);
}
else
{
pInfo = &pAdapter->pDeviceInfo[dwDeviceID];
// Clear existing device info, if any
LocalFree(pInfo->pwszDeviceName);
memset(pInfo, 0, sizeof(pInfo));
szDeviceName = (LPTSTR)((LPBYTE)&(pGetDevCaps->LineDevCaps) + pGetDevCaps->LineDevCaps.ulLineNameOffset);
//
// If we are unable to otherwise determine a device type,
// assume it is a "modem" device.
//
szDeviceType = RASDT_Modem;
wDeviceType = 0xFFFF;
// UNIMODEM and PPTP put TSP name in the ProviderInfo area
if (pGetDevCaps->LineDevCaps.ulProviderInfoOffset)
{
//
// ProviderInfo is of the format:
// MediaName\0ProviderName\0
//
szMediaName = (PTSTR)((PBYTE)&(pGetDevCaps->LineDevCaps)+ pGetDevCaps->LineDevCaps.ulProviderInfoOffset);
szProviderName = szMediaName + _tcslen(szMediaName) + 1;
if (szProviderName > (PTSTR)((PBYTE)szMediaName + pGetDevCaps->LineDevCaps.ulProviderInfoSize))
szProviderName = NULL;
if (_tcscmp(TEXT("UNIMODEM"), szMediaName) == 0)
{
// UNIMODEM device
if (pGetDevCaps->LineDevCaps.ulDevSpecificOffset)
{
pUnimodemInfo = (UNIMODEM_INFO *)((LPBYTE)&(pGetDevCaps->LineDevCaps) + pGetDevCaps->LineDevCaps.ulDevSpecificOffset);
wDeviceType = pUnimodemInfo->wDeviceType;
switch (pUnimodemInfo->wDeviceType)
{
case DT_NULL_MODEM :
bIsNullModem = TRUE;
// FALLTHROUGH
case DT_IRCOMM_MODEM :
case DT_DYNAMIC_PORT :
szDeviceType = RASDT_Direct;
break;
case DT_EXTERNAL_MODEM:
case DT_INTERNAL_MODEM:
case DT_PCMCIA_MODEM:
case DT_PARALLEL_PORT:
case DT_PARALLEL_MODEM:
case DT_DYNAMIC_MODEM :
default :
szDeviceType = RASDT_Modem;
break;
}
}
}
else if (_tcsicmp(RASDT_Direct, szMediaName) == 0)
{
szDeviceType = RASDT_Direct;
}
else if (_tcsicmp(RASDT_Modem, szMediaName) == 0)
{
szDeviceType = RASDT_Modem;
}
else if (_tcsicmp(RASDT_Vpn, szMediaName) == 0)
{
szDeviceType = RASDT_Vpn;
if (szProviderName && _tcsicmp(szProviderName, RASDT_PPPoE) == 0)
{
szDeviceType = RASDT_PPPoE;
}
}
}
pInfo->bIsNullModem = bIsNullModem;
pInfo->pwszDeviceName = LocalAlloc(LPTR, (wcslen(szDeviceName) + 1) * sizeof(WCHAR));
if (pInfo->pwszDeviceName)
{
wcscpy(pInfo->pwszDeviceName, szDeviceName);
pInfo->pwszDeviceType = szDeviceType;
}
}
}
void
ndisTapiLineGetDevCapsCompleteCallback(
PNDIS_REQUEST_BETTER pRequest,
PNDISWAN_ADAPTER pAdapter,
NDIS_STATUS Status)
//
// This function is called when the miniport driver completes
// an OID_TAPI_GET_DEV_CAPS request.
//
{
PNDIS_TAPI_GET_DEV_CAPS pGetDevCaps;
DWORD dwDeviceID;
DWORD dwNeededSize,
dwExtraSize;
DEBUGMSG(ZONE_FUNCTION, (L"PPP: +ndisTapiLineGetDevCapsCompleteCallback Status=%x\n", Status));
pAdapter->bEnumeratingDevices = FALSE;
if (Status != NDIS_STATUS_SUCCESS)
{
DEBUGMSG(ZONE_ERROR, (L"PPP: ndisTapiLineGetDevCapsCompleteCallback got Status = %x for adapter %s\n", Status, pAdapter->szAdapterName));
}
else
{
if (pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength < sizeof(NDIS_TAPI_GET_DEV_CAPS))
{
DEBUGMSG(ZONE_ERROR, (L"PPP: ndisTapiGetLinkInfoCompleteCallback BufferLength too small (%u < %u)\n",
pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength, sizeof(NDIS_TAPI_GET_DEV_CAPS)));
}
else
{
pGetDevCaps = pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer;
dwDeviceID = pGetDevCaps->ulDeviceID;
dwNeededSize = pGetDevCaps->LineDevCaps.ulNeededSize;
// Check to see if we need a bigger buffer
if (dwNeededSize <= pGetDevCaps->LineDevCaps.ulTotalSize)
{
// Buffer was big enough to receive the required info
// Extract the returned device information and add it to the adapter
ndisTapiProcessDevCaps(pAdapter, pGetDevCaps);
// Advance deviceID to the next device to be enumerated for the adapter
dwDeviceID++;
dwExtraSize = 0;
}
else
{
dwExtraSize = dwNeededSize - sizeof(LINE_DEV_CAPS);
}
// Issue a new request if more devices remain to be enumerated, or to retry
// a request with bigger buffer.
if (dwDeviceID < pAdapter->dwNumDevices)
{
NdisTapiIssueLineGetDevCaps(pAdapter, dwDeviceID, dwExtraSize);
}
else
{
// No more devices remain to be enumerated
DEBUGMSG(ZONE_MAC, (L"PPP: Completed device enumeration for adapter %s\n", pAdapter->szAdapterName));
}
}
}
// Free the memory allocated for the request.
LocalFree(pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer);
DEBUGMSG(ZONE_FUNCTION, (TEXT("PPP: -ndisTapiLineGetDevCapsCompleteCallback\n")));
}
void
NdisTapiIssueLineGetDevCaps(
PNDISWAN_ADAPTER pAdapter,
DWORD dwDeviceID,
DWORD dwExtraSize)
//
// Send an asynchronous OID_TAPI_GET_DEV_CAPS request to the miniport adapter
// to retrieve device information for the specified dwDeviceID.
//
{
NDIS_STATUS Status;
PNDIS_TAPI_GET_DEV_CAPS pGetDevCaps;
DWORD dwGetDevCapsSize;
//
// If we already have an OID_TAPI_GET_DEV_CAPS pending, we don't
// need to issue a new one. When the current one completes it will
// continue to enumerate all the devices for the adapter.
//
if (!pAdapter->bEnumeratingDevices)
{
dwGetDevCapsSize = sizeof(NDIS_TAPI_GET_DEV_CAPS) + dwExtraSize;
pGetDevCaps = LocalAlloc(LPTR, dwGetDevCapsSize);
if (NULL != pGetDevCaps)
{
pAdapter->bEnumeratingDevices = TRUE;
pGetDevCaps->LineDevCaps.ulTotalSize = dwGetDevCapsSize - offsetof(NDIS_TAPI_GET_DEV_CAPS, LineDevCaps);
pGetDevCaps->ulRequestID = 0;
pGetDevCaps->ulDeviceID = dwDeviceID;
pGetDevCaps->ulExtVersion = 0;
PppNdisIssueRequest(&Status,
pAdapter,
NdisRequestQueryInformation,
OID_TAPI_GET_DEV_CAPS,
pGetDevCaps,
dwGetDevCapsSize,
NULL,
ndisTapiLineGetDevCapsCompleteCallback,
pAdapter,
NULL);
}
}
}
//
// To reduce the necessity of having to send 2 OID_TAPI_GET_DEV_CAPS because
// the first one doesn't have enough room for extra info, we send this many
// bytes of extra space in the initial request.
//
#define DEFAULT_GETDEVCAPS_EXTRA_BYTES 256
NDIS_STATUS
NdisTapiSetNumLineDevs(
PNDISWAN_ADAPTER pAdapter,
DWORD dwNumLineDevs)
//
// This function is called to set the number of line devices owned by the adapter.
// It is called when the OID_TAPI_PROVIDER_INITIALIZE completes to set the initial
// number of devices, and later when a LINE_CREATE indication is received from the
// miniport adapter to indicate that new devices have been added (e.g. inserting
// a PCMCIA modem card).
//
{
PNDISTAPI_DEVICE_INFO pDevInfoNew;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
DWORD dwFirstNewDevice;
DEBUGMSG(ZONE_MAC, (TEXT("PPP: NdisTapiSetNumLineDevs for adapter %s to %u\n"), pAdapter->szAdapterName, pAdapter->dwNumDevices));
dwFirstNewDevice = pAdapter->dwNumDevices;
if (dwNumLineDevs <= dwFirstNewDevice)
{
DEBUGMSG(dwNumLineDevs && ZONE_WARN, (TEXT("PPP: WARNING New numLineDevs %u <= current %u for adapter %s\n"), dwNumLineDevs, dwFirstNewDevice, pAdapter->szAdapterName));
}
else
{
// Allocate memory for larger device info array.
pDevInfoNew = pppAllocateMemory(dwNumLineDevs * sizeof(*pAdapter->pDeviceInfo));
if (pDevInfoNew == NULL)
{
DEBUGMSG(ZONE_ERROR, (TEXT("PPP: ERROR Unable to allocate memory for %u LineDevs for adapter %s\n"), dwNumLineDevs, pAdapter->szAdapterName));
Status = NDIS_STATUS_RESOURCES;
}
else
{
// Copy old array to new
memcpy(pDevInfoNew, pAdapter->pDeviceInfo, dwFirstNewDevice * sizeof(*pAdapter->pDeviceInfo));
// Free the old array, switch adapter to the new
pppFreeMemory(pAdapter->pDeviceInfo, dwFirstNewDevice * sizeof(*pAdapter->pDeviceInfo));
pAdapter->pDeviceInfo = pDevInfoNew;
pAdapter->dwNumDevices = dwNumLineDevs;
// Send requests to enumerate the new line devices to get name and type information
NdisTapiIssueLineGetDevCaps(pAdapter, dwFirstNewDevice, DEFAULT_GETDEVCAPS_EXTRA_BYTES);
}
}
return Status;
}
void
ndisTapiProviderInitializeCompleteCallback(
PNDIS_REQUEST_BETTER pRequest,
PNDISWAN_ADAPTER pAdapter,
NDIS_STATUS Status)
//
// This function is called when the miniport driver completes
// an OID_TAPI_PROVIDER_INITIALIZE request.
//
{
PNDIS_TAPI_PROVIDER_INITIALIZE pProvInit;
DEBUGMSG(ZONE_FUNCTION, (L"PPP: +ndisTapiProviderInitializeCompleteCallback Status=%x\n", Status));
if (Status != NDIS_STATUS_SUCCESS)
{
DEBUGMSG(ZONE_ERROR, (L"PPP: ndisTapiProviderInitializeCompleteCallback got Status = %x for adapter %s\n", Status, pAdapter->szAdapterName));
}
else
{
if (pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength < sizeof(*pProvInit))
{
DEBUGMSG(ZONE_ERROR, (L"PPP: ndisTapiGetLinkInfoCompleteCallback BufferLength too small (%u < %u)\n",
pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength, sizeof(*pProvInit)));
}
else
{
pProvInit = pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer;
// Extract the returned device information and add it to the adapter
DEBUGMSG (ZONE_MAC, (TEXT("PPP: AddAdapter: '%s' returned ProvID=%d NumDev=%d\n"),
pAdapter->szAdapterName, pAdapter->dwProviderID, pAdapter->dwNumDevices));
pAdapter->dwProviderID = pProvInit->ulProviderID;
NdisTapiSetNumLineDevs(pAdapter, pProvInit->ulNumLineDevs);
}
}
if (Status != NDIS_STATUS_SUCCESS)
AdapterDelRef(pAdapter);
// Free the memory allocated for the request.
LocalFree(pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer);
DEBUGMSG(ZONE_FUNCTION, (TEXT("PPP: -ndisTapiProviderInitializeCompleteCallback\n")));
}
void
NdisTapiAdapterInitialize(
PNDISWAN_ADAPTER pAdapter)
//
// This function is called after we have successfully bound to a new
// WAN miniport adapter. It gathers information from the adapter to
// complete initialization.
//
{
NDIS_STATUS Status;
PNDIS_TAPI_PROVIDER_INITIALIZE pProvInit;
pProvInit = LocalAlloc (LPTR, sizeof(*pProvInit));
if (NULL != pProvInit)
{
// pProvInit->ulDeviceIDBase = 0;
PppNdisIssueRequest(&Status,
pAdapter,
NdisRequestQueryInformation,
OID_TAPI_PROVIDER_INITIALIZE,
pProvInit,
sizeof(*pProvInit),
NULL,
ndisTapiProviderInitializeCompleteCallback,
pAdapter,
NULL);
}
}
/*****************************************************************************
*
*
* @func LPTSTR | TapiLineTranslateAddress |
* Get the Dialable or Displayable format of a number
*
* @rdesc Returns a LPTSTR or NULL. The caller must free this string.
*
* @parm DWORD | dwDeviceID |
* The Device ID to use
* @parm DWORD | dwCountryCode |
* The country code
* @parm LPCTSTR | szAreaCode |
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -