📄 mac.c
字号:
// Configure the port timeouts to:
// 1. Make a ReadFile return after no more than dwTimeoutMilliseconds
// 2. Allow 500 ms + 2ms/byte before timing out a WriteFile
if (GetCommTimeouts( pMac->hComPort, &CommTimeouts ) == FALSE)
{
dwResult = GetLastError();
break;
}
CommTimeouts.ReadIntervalTimeout = dwTimeoutMilliseconds;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 0;
CommTimeouts.WriteTotalTimeoutMultiplier = 2;
CommTimeouts.WriteTotalTimeoutConstant = 500;
if (SetCommTimeouts( pMac->hComPort, &CommTimeouts ) == FALSE)
{
dwResult = GetLastError();
break;
}
// Return no bytes read. To read bytes "RasRetrieveBuffer" must be called
*pdwSize = 0;
// Save context information for use by the receive thread
pMac->pRxBuffer = pBuffer;
pMac->dwRxBufferSize = MAX_CUSTOM_SCRIPT_RX_BUFFER_SIZE;
pMac->dwRxBytesReceived = 0;
pMac->hRxEvent = hEvent;
if (pMac->hRxEventThread == NULL)
{
pMac->hRxEventThread = CreateThread (NULL, 0, rasReceiveEventThread, pMac, 0, &dwID);
if (pMac->hRxEventThread == NULL)
{
dwResult = GetLastError();
break;
}
}
} while (FALSE);
return dwResult;
}
DWORD
pppMacCustomScriptExecute(
IN macCntxt_t *pMac,
IN OUT LPRASDIALPARAMS pRasDialParams)
//
// Run the "script" on the line, after the connection has been established
// but before LCP starts.
//
// RAS calls the RasCustomScriptExecute function when establishing a connection for a phone-book entry that has the RASEO_CustomScript option set.
//
// The RasCustomScriptExecute function should be in the dll specified in the registry value
// \\HKEY_LOCAL_MACHINE\Comm\PPP\Parms\CustomScriptDllPath REG_SZ
//
// Optionally, if the "szScript" parameter of the RasEntry is of the format:
// <dllName>[|<parameterName>]
// then the name specified before the '|' character will be the name of the dll loaded.
// That is, it will be loaded in place of the registry setting.
//
// DWORD RasCustomScriptExecute(
// HANDLE hPort,
// LPCWSTR lpszPhonebook,
// LPCWSTR lpszEntryName,
// PFNRASGETBUFFER pfnRasGetBuffer,
// PFNRASFREEBUFFER pfnRasFreeBuffer,
// PFNRASSENDBUFFER pfnRasSendBuffer,
// PFNRASRECEIVEBUFFER pfnRasReceiveBuffer,
// PFNRASRETRIEVEBUFFER pfnRasRetrieveBuffer,
// HWND hWnd,
// RASDIALPARAMS *pRasDialParams,
// RASCUSTOMSCRIPTEXTENSIONS *pRasCustomScriptExtensions
// );
//
// hPort is the handle returned by the Miniport in an OID_TAPI_GET_ID query of
// the deviceClass "comm/datamodem". If the Miniport returns an error on that query,
// the script will not be run.
//
// If the RasCustomScriptExecute function returns SUCCESS (0), then the connection attempt
// will proceed to the LCP negotiations and so forth.
// A non-0 return value will cause the connection to be terminated.
//
{
pppSession_t *s_p = pMac->session;
DWORD dwResult,
nRead;
LPTSTR pStr;
WCHAR wszDllName[MAX_PATH+1];
HMODULE hScriptDLL;
DWORD (*pfnRasCustomScriptExecute)();
PVAR_STRING pDeviceID;
NDIS_STATUS Status;
DEBUGMSG (ZONE_FUNCTION, (TEXT("PPP: +pppMacCustomScriptExecute\n")));
do
{
//
// Get the handle to the COM port from the miniport driver
//
Status = NdisTapiGetDeviceId(pMac, LINECALLSELECT_CALL, TEXT("comm/datamodem"), &pDeviceID);
if (Status != NDIS_STATUS_SUCCESS)
{
dwResult = E_FAIL;
break;
}
pMac->hComPort = *((HANDLE *)((LPBYTE)pDeviceID + pDeviceID->ulStringOffset));
pppFreeMemory(pDeviceID, pDeviceID->ulTotalSize);
//
// Get the name of the custom script dll, from the
// szScript field of the RASENTRY, if present, otherwise
// HKLM\Comm\Ppp\Parms\CustomScriptDllPath
//
wcscpy(wszDllName, s_p->rasEntry.szScript);
pStr = _tcschr(wszDllName, TEXT('|'));
if (pStr)
{
*(pStr++) = TEXT('\0');
}
else
{
nRead = ReadRegistryValues(
HKEY_LOCAL_MACHINE, L"Comm\\PPP\\Parms",
L"CustomScriptDllPath", REG_SZ, 0, (PVOID)wszDllName, sizeof(wszDllName),
NULL);
if (nRead != 1)
{
dwResult = E_FAIL;
break;
}
}
DEBUGMSG (ZONE_PPP, (TEXT("PPP: Custom Script DLL='%s'\n"), wszDllName));
hScriptDLL = LoadLibrary (wszDllName);
if (hScriptDLL == NULL)
{
DEBUGMSG (ZONE_ERROR, (TEXT("PPP: ERROR - Unable to LoadLibrary ('%s'), GetLastError=%d\n"),
wszDllName, GetLastError()));
dwResult = E_FAIL;
break;
}
pfnRasCustomScriptExecute = GetProcAddress(hScriptDLL, L"RasCustomScriptExecute");
if (pfnRasCustomScriptExecute == NULL)
{
DEBUGMSG (ZONE_ERROR, (TEXT("PPP: ERROR - Unable to find RunScript function in DLL '%s'\n"),
s_p->rasEntry.szScript));
dwResult = E_FAIL;
}
else
{
DEBUGMSG (ZONE_FUNCTION, (TEXT("PPP: Calling %s!RasCustomScriptExecute()\n"),
wszDllName));
dwResult = pfnRasCustomScriptExecute(
pMac,
NULL, // lpszPhonebook,
s_p->rasDialParams.szEntryName,
RasGetBuffer,
RasFreeBuffer,
RasSendBuffer,
RasReceiveBuffer,
RasRetrieveBuffer,
NULL, // hWnd
pRasDialParams,
NULL // pRasCustomScriptExtensions
);
DEBUGMSG(dwResult && ZONE_ERROR,
(TEXT("PPP: ERROR - Script %s - RasCustomScriptExecute returned error %d\n"),
wszDllName, dwResult));
// Terminate the receive thread, if any
(void)SetCommMask (pMac->hComPort, 0);
if (pMac->hRxEventThread)
{
WaitForSingleObject(pMac->hRxEventThread, INFINITE);
CloseHandle(pMac->hRxEventThread);
pMac->hRxEventThread = NULL;
}
pMac->hRxEvent = NULL;
pMac->pRxBuffer = NULL;
pMac->dwRxBufferSize = 0;
pMac->dwRxBytesReceived = 0;
}
FreeLibrary (hScriptDLL);
} while (FALSE);
pMac->hComPort = NULL;
return dwResult;
}
DWORD
pppMac_Dial(
void *context,
LPRASPENTRY pRasEntry,
LPRASDIALPARAMS pRasDialParams)
{
macCntxt_t *pMac = (macCntxt_t *)context;
pppSession_t *s_p = (pppSession_t *)pMac->session;
LPTSTR szDialStr;
DWORD dwFlag;
DWORD dwRetVal = NO_ERROR;
HANDLE hHangupCompleteEvent;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
DEBUGMSG (ZONE_FUNCTION,
(TEXT("+pppMac_Dial(0x%X, 0x%X, 0x%X) (%s) %s\r\n"),
context, pRasEntry, pRasDialParams,
pRasEntry->szAreaCode,
pRasEntry->szLocalPhoneNumber));
do
{
//
// For PPPoE, set flag to suppress prepending the address and
// control bytes when sending a frame.
//
if (_tcscmp(pRasEntry->szDeviceType, RASDT_PPPoE) == 0)
{
pMac->bIsPPPoE = TRUE;
}
//
// For Vpn lines, we don't want to translate the VPN server name
// (phone number)
//
if ((_tcscmp(pRasEntry->szDeviceType, RASDT_Vpn) != 0) &&
(_tcscmp(pRasEntry->szDeviceType, RASDT_PPPoE) != 0))
{
pppUnLock(s_p);
dwFlag = 0;
if (pRasEntry->dwfOptions & RASEO_UseCountryAndAreaCodes)
dwFlag = LINETRANSLATEOPTION_FORCELD;
else if (pRasEntry->dwfOptions & RASEO_DialAsLocalCall)
dwFlag = LINETRANSLATEOPTION_FORCELOCAL;
szDialStr = NdisTapiLineTranslateAddress (pMac->pAdapter, pMac->dwDeviceID,
pRasEntry->dwCountryCode,
pRasEntry->szAreaCode,
pRasEntry->szLocalPhoneNumber,
TRUE, dwFlag);
pppLock(s_p);
if (NULL == szDialStr)
{
DEBUGMSG(ZONE_ERROR, (TEXT("PPP: ERROR from NdisTapiLineTranslateAddress\r\n")));
dwRetVal = ERROR_BAD_PHONE_NUMBER;
break;
}
}
else
{
szDialStr = &pRasEntry->szLocalPhoneNumber[0];
}
//
// Not all devices require devconfig. These will return NDIS_STATUS_NOT_SUPPORTED,
// NDIS_STATUS_NOT_RECOGNIZED, or NDIS_STATUS_INVALID_OID,
// when we try to get/set OID_TAPI_GET/SET_DEV_CONFIG. This is not an error, we
// continue to try to establish the connection in that case.
//
// If the RAS entry doesn't have a dev config, then get the default config
// for the line.
if (((pppSession_t *)(pMac->session))->lpbDevConfig == NULL)
{
pppUnLock(s_p);
Status = NdisTapiGetDevConfig (pMac->pAdapter, pMac->dwDeviceID,
&(((pppSession_t *)(pMac->session))->lpbDevConfig),
&((pppSession_t *)(pMac->session))->dwDevConfigSize);
pppLock(s_p);
if (Status != NDIS_STATUS_SUCCESS
&& Status != NDIS_STATUS_NOT_SUPPORTED
&& Status != NDIS_STATUS_NOT_RECOGNIZED
&& Status != NDIS_STATUS_INVALID_OID)
{
DEBUGMSG(ZONE_ERROR, (TEXT("PPP: ERROR from NdisTapiGetDevConfig %x\r\n"), Status));
break;
}
}
//
// Bluetooth modems need the devconfig set before lineOpen since there is Bluetooth
// connection information in the devconfig.
//
if (Status == NDIS_STATUS_SUCCESS)
{
Status = NdisTapiSetDevConfig (pMac);
if (Status != NDIS_STATUS_SUCCESS
&& Status != NDIS_STATUS_NOT_SUPPORTED
&& Status != NDIS_STATUS_NOT_RECOGNIZED
&& Status != NDIS_STATUS_INVALID_OID)
{
DEBUGMSG(ZONE_ERROR,(TEXT("PPP: ERROR from NdisTapiSetDevConfig %x\r\n"), Status));
break;
}
}
DEBUGMSG (ZONE_RAS, (TEXT("PPP: DialableString='%s'\r\n"), szDialStr));
Status = NdisTapiLineOpen (pMac);
if (Status != NDIS_STATUS_SUCCESS)
{
DEBUGMSG (ZONE_ERROR, (TEXT("PPP: ERROR from NdisTapiLineOpen %x\r\n"), Status));
break;
}
DEBUGMSG (ZONE_RAS, (TEXT("NdisTapiLineOpen successful\r\n")));
//
// Non-zero TapiEcode means that another thread called NdisTapiHangUp while
// we were doing the LineOpen, so we should proceed to abort the dialing.
//
if (pMac->TapiEcode)
{
DEBUGMSG (ZONE_RAS, (TEXT("PPP: TapiEcode=%d after NdisTapiLineOpen\n")));
dwRetVal = pMac->TapiEcode;
break;
}
Status = NdisTapiLineMakeCall (pMac, szDialStr);
if (Status != NDIS_STATUS_SUCCESS)
{
DEBUGMSG(ZONE_ERROR, (TEXT("PPP: ERROR from NdisTapiLineMakeCall %x\r\n"), Status));
break;
}
} while (FALSE); // end do
// Done with the dial string, free it if space allocated for it
if (szDialStr != &pRasEntry->szLocalPhoneNumber[0])
LocalFree (szDialStr);
// Return with error if something went wrong
if (Status != NDIS_STATUS_SUCCESS)
dwRetVal = pppMac_NdisToRasErrorCode(Status);
if (dwRetVal != NO_ERROR)
return dwRetVal;
DEBUGMSG (ZONE_RAS, (TEXT("NdisTapiLineMakeCall successful\r\n")));
DEBUGMSG (ZONE_RAS, (TEXT("PPP: NdisTapiLineMakeCall waiting for event\n")));
//
// Unlock the session while we are waiting for the NdisTapiEvent so that
// pppSessionStop can initiate an abort (e.g. user presses "Cancel").
//
pppUnLock( s_p );
//
// Wait for something to complete, either a status indication
// from the adapter (e.g. CALL_CONNECTED) or a pppSessionStop call.
//
WaitForSingleObject (pMac->hNdisTapiEvent, INFINITE);
pppLock( s_p );
DEBUGMSG (ZONE_RAS, (TEXT("PPP: NdisTapiLineMakeCall got event\n")));
DEBUGMSG (ZONE_RAS, (TEXT("pppMac_Dial: TapiEcode=%d\r\n"), pMac->TapiEcode));
if (pMac->TapiEcode == 0)
{
// Do we have a script?
if (s_p->rasEntry.dwfOptions & RASEO_CustomScript)
{
pppChangeOfState (pMac->session, RASCS_Interactive, 0);
pMac->TapiEcode = pppMacCustomScriptExecute(pMac, pRasDialParams);
}
if (pMac->TapiEcode == 0)
{
pppChangeOfState (pMac->session, RASCS_DeviceConnected, 0);
}
//
// This will trigger the miniport to begin listening for data,
// e.g. on AsyncMac it causes the RxThread to be created.
//
(void)NdisTapiGetDeviceId(pMac, LINECALLSELECT_CALL, L"ndis", NULL);
}
if (pMac->TapiEcode)
{
// Close all of our handles etc.
hHangupCompleteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
NdisTapiHangup (pMac, pppHangupComplete, hHangupCompleteEvent);
if (hHangupCompleteEvent != NULL)
{
//
// Unlock the session while we are waiting for the NdisTapiEvent so that
// pppSessionStop can initiate an abort (e.g. user presses "Cancel").
//
pppUnLock( s_p );
WaitForSingleObject(hHangupCompleteEvent, INFINITE);
pppLock( s_p );
CloseHandle(hHangupCompleteEvent);
}
}
return pMac->TapiEcode;
}
void
pppMac_Reset(void *context)
{
macCntxt_t *pMac = (macCntxt_t *)context;
NDIS_STATUS Status;
DEBUGMSG (ZONE_FUNCTION, (TEXT("PPP: +pppMac_Reset\n")));
// Ugly kludge to force L2TP to abort IKE negotiations,
// since we cannot get L2TP an OID_TAPI_CLOSE request until
// the OID_TAPI_MAKE_CALL request completes.
NdisReset (&Status, pMac->pAdapter->hAdapter);
}
void
pppMac_AbortDial(void *context)
//
// This function will abort a dialing operation if one is in progress.
//
{
macCntxt_t *pMac = (macCntxt_t *)context;
DEBUGMSG (ZONE_FUNCTION, (TEXT("PPP: +pppMac_AbortDial\n")));
pMac->TapiEcode = ERROR_USER_DISCONNECTION;
SetEvent (pMac->hNdisTapiEvent);
DEBUGMSG (ZONE_FUNCTION, (TEXT("PPP: -pppMac_AbortDial\n")));
}
void
pppMac_CallClose(
void *context,
void (*pCallCloseCompleteCallback)(PVOID),
PVOID pCallbackData)
{
macCntxt_t *pMac = (macCntxt_t *)context;
DEBUGMSG(ZONE_FUNCTION, (TEXT("+pppMac_Close\n")));
// Let's just hang up....
NdisTapiHangup (pMac, pCallCloseCompleteCallback, pCallbackData);
DEBUGMSG(ZONE_FUNCTION, (TEXT("-pppMac_Close\n")));
}
void
pppMac_LineClose (
void *context,
void (*pLineCloseCompleteCallback)(PVOID),
PVOID pCallbackData)
{
macCntxt_t *pMac = (macCntxt_t *)context;
NDIS_STATUS Status;
DEBUGMSG(ZONE_FUNCTION, (TEXT("+pppMac_LineClose\n")));
Status = NdisTapiLineClose(pMac, pLineCloseCompleteCallback, pCallbackData);
DEBUGMSG(ZONE_FUNCTION, (TEXT("-pppMac_LineClose\n")));
}
void
pppMac_InstanceDelete (void *context)
{
macCntxt_t *pMac = (macCntxt_t *)context;
DEBUGMSG(ZONE_MAC, (L"PPP: Delete MAC %x adapter=%x\n", pMac, pMac->pAdapter));
DEBUGMSG (ZONE_TRACE, (TEXT("!pppMac_InstanceDelete\r\n")));
if (pMac->pAdapter) {
AdapterDelRef (pMac->pAdapter);
pMac->pAdapter = NULL;
}
CloseHandle (pMac->hNdisTapiEvent);
CloseHandle (pMac->hEventLineOpenComplete);
NdisFreeSpinLock (&pMac->PacketLock);
pppFreeMemory(pMac->PacketMemory, pMac->PacketMemorySize);
pppFreeMemory (pMac, sizeof (macCntxt_t));
}
void
pppMac_GetCallSpeed(
void *context,
PDWORD pSpeed)
{
macCntxt_t *pMac = (macCntxt_t *)context;
DEBUGMSG (ZONE_FUNCTION, (TEXT("+pppMac_GetCallSpeed\n")));
*pSpeed = pMac->LinkSpeed * 100;
DEBUGMSG(ZONE_MAC, (TEXT("PPP: Interface Bit Rate is %u b/s\n"), *pSpeed));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -