#include "StdAfx.h"
#include "MyRAS.h"
#include "Log.h"
HRASCONN CMyRAS::m_hRasConn = NULL;
CWnd* CMyRAS::m_pEventWnd = NULL;
BOOL CMyRAS::m_bConnected = FALSE;
BOOL CMyRAS::m_bDialing = FALSE;
VOID WINAPI CMyRAS::RasDialEventNotifier (UINT unMsg, RASCONNSTATE rasconnstate, DWORD dwError)
{
switch(rasconnstate)
{
case RASCS_Connected:
#if defined(_LOG) && defined(_DEBUG)
CLog::Instance()->LogToFile(L"Info : RASCS_Connected\n");
#endif
m_bConnected = TRUE;
m_bDialing = FALSE;
break;
case RASCS_Disconnected:
#if defined(_LOG) && defined(_DEBUG)
CLog::Instance()->LogToFile(L"Info : RASCS_Disconnected\n");
#endif
m_bConnected = FALSE;
m_bDialing = FALSE;
m_hRasConn = NULL;
break;
}
if (dwError)
{
m_bDialing = FALSE;
}
//Forward the message to UI
m_pEventWnd->PostMessage(WM_DIAL_EVNT, rasconnstate, dwError);
/*
Error Messages
-------------------------------
600 An operation is pending.
601 The port handle is invalid.
602 The port is already open.
603 Caller's buffer is too small.
604 Wrong information specified.
605 Cannot set port information.
606 The port is not connected.
607 The event is invalid.
608 The device does not exist.
609 The device type does not exist.
610 The buffer is invalid.
611 The route is not available.
612 The route is not allocated.
613 Invalid compression specified.
614 Out of buffers.
615 The port was not found.
616 An asynchronous request is pending.
617 The port or device is already disconnecting.
618 The port is not open.
619 The port is disconnected.
620 There are no endpoints.
621 Cannot open the phone book file.
622 Cannot load the phone book file.
623 Cannot find the phone book entry.
624 Cannot write the phone book file.
625 Invalid information found in the phone book.
626 Cannot load a string.
627 Cannot find key.
628 The port was disconnected.
629 The port was disconnected by the remote machine.
630 The port was disconnected due to hardware failure.
631 The port was disconnected by the user.
632 The structure size is incorrect.
633 The port is already in use or is not configured for Remote Access dialout.
634 Cannot register your computer on the remote network.
635 Unknown error.
636 The wrong device is attached to the port.
637 The string could not be converted.
638 The request has timed out.
639 No asynchronous net available.
640 A NetBIOS error has occurred.
641 The server cannot allocate NetBIOS resources needed to support the client.
642 One of your NetBIOS names is already registered on the remote network.
643 A network adapter at the server failed.
644 You will not receive network message popups.
645 Internal authentication error.
646 The account is not permitted to log on at this time of day.
647 The account is disabled.
648 The password has expired.
649 The account does not have Remote Access permission.
650 The Remote Access server is not responding.
651 Your modem (or other connecting device) has reported an error.
652 Unrecognized response from the device.
653 A macro required by the device was not found in the device .INF file section.
654 A command or response in the device .INF file section refers to an undefined macro
655 The <message> macro was not found in the device .INF file section.
656 The <defaultoff> macro in the device .INF file section contains an undefined macro
657 The device .INF file could not be opened.
658 The device name in the device .INF or media .INI file is too long.
659 The media .INI file refers to an unknown device name.
660 The device .INF file contains no responses for the command.
661 The device .INF file is missing a command.
662 Attempted to set a macro not listed in device .INF file section.
663 The media .INI file refers to an unknown device type.
664 Cannot allocate memory.
665 The port is not configured for Remote Access.
666 Your modem (or other connecting device) is not functioning.
667 Cannot read the media .INI file.
668 The connection dropped.
669 The usage parameter in the media .INI file is invalid.
670 Cannot read the section name from the media .INI file.
671 Cannot read the device type from the media .INI file.
672 Cannot read the device name from the media .INI file.
673 Cannot read the usage from the media .INI file.
674 Cannot read the maximum connection BPS rate from the media .INI file.
675 Cannot read the maximum carrier BPS rate from the media .INI file.
676 The line is busy.
677 A person answered instead of a modem.
678 There is no answer.
679 Cannot detect carrier.
680 There is no dial tone.
681 General error reported by device.
682 ERROR WRITING SECTIONNAME
683 ERROR WRITING DEVICETYPE
684 ERROR WRITING DEVICENAME
685 ERROR WRITING MAXCONNECTBPS
686 ERROR WRITING MAXCARRIERBPS
687 ERROR WRITING USAGE
688 ERROR WRITING DEFAULTOFF
689 ERROR READING DEFAULTOFF
690 ERROR EMPTY INI FILE
691 Access denied because username and/or password is invalid on the domain.
692 Hardware failure in port or attached device.
693 ERROR NOT BINARY MACRO
694 ERROR DCB NOT FOUND
695 ERROR STATE MACHINES NOT STARTED
696 ERROR STATE MACHINES ALREADY STARTED
697 ERROR PARTIAL RESPONSE LOOPING
698 A response keyname in the device .INF file is not in the expected format.
699 The device response caused buffer overflow.
700 The expanded command in the device .INF file is too long.
701 The device moved to a BPS rate not supported by the COM driver.
702 Device response received when none expected.
703 ERROR INTERACTIVE MODE
704 ERROR BAD CALLBACK NUMBER
705 ERROR INVALID AUTH STATE
706 ERROR WRITING INITBPS
707 X.25 diagnostic indication.
708 The account has expired.
709 Error changing password on domain.
710 Serial overrun errors were detected while communicating with your modem.
711 RasMan initialization failure. Check the event log.
712 Biplex port is initializing. Wait a few seconds and redial.
713 No active ISDN lines are available.
714 Not enough ISDN channels are available to make the call.
715 Too many errors occurred because of poor phone line quality.
716 The Remote Access IP configuration is unusable.
717 No IP addresses are available in the static pool of Remote Access IP addresses.
718 PPP timeout.
719 PPP terminated by remote machine.
720 No PPP control protocols configured.
721 Remote PPP peer is not responding.
722 The PPP packet is invalid.
723 The phone number, including prefix and suffix, is too long.
724 The IPX protocol cannot dial-out on the port because the computer is an IPX router.
725 The IPX protocol cannot dial-in on the port because the IPX router is not installed..
726 The IPX protocol cannot be used for dial-out on more than one port at a time.
727 Cannot access TCPCFG.DLL.
728 Cannot find an IP adapter bound to Remote Access.
729 SLIP cannot be used unless the IP protocol is installed.
730 Computer registration is not complete.
731 The protocol is not configured.
732 The PPP negotiation is not converging.
733 The PPP control protocol for this network protocol is not available on the server.
734 The PPP link control protocol terminated..
735 The requested address was rejected by the server..
736 The remote computer terminated the control protocol.
737 Loopback detected..
738 The server did not assign an address.
739 The remote server cannot use the Windows NT encrypted password.
740 The TAPI devices configured for Remote Access failed to initialize or were not installed correctly.
741 The local computer does not support encryption.
742 The remote server does not support encryption.
743 The remote server requires encryption.
744 Cannot use the IPX net number assigned by the remote server. Check the event log.
752 A syntax error was encountered while processing a script.
*/
}
CMyRAS::CMyRAS(void)
{
m_iEntriesCount = 0;
m_psEntriesNames = NULL;
}
CMyRAS::~CMyRAS(void)
{
if(m_psEntriesNames)
{
delete [] m_psEntriesNames;
}
}
int CMyRAS::CheckIfAnyExistingConnection()
{
DWORD dwCb = sizeof(RASCONN);
DWORD dwErr = ERROR_SUCCESS;
DWORD dwConnections = 0;
RASCONN* lpRasConn = NULL;
lpRasConn = (RASCONN*)HeapAlloc(GetProcessHeap(), 0, dwCb);
if (lpRasConn == NULL)
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
return -1;
}
lpRasConn->dwSize = sizeof(RASCONN);
dwErr = RasEnumConnections(lpRasConn, &dwCb, &dwConnections);
if (ERROR_BUFFER_TOO_SMALL != dwErr)
{
return -1;
}
if (ERROR_SUCCESS == dwErr)
{
DWORD i;
#if defined(_LOG) && defined(_DEBUG)
CLog::Instance()->LogToFile(L"Info : The following RAS connections are currently active\n");
#endif
for (i = 0; i < dwConnections; i++)
{
#if defined(_LOG) && defined(_DEBUG)
CString sLog(lpRasConn[i].szEntryName);
CLog::Instance()->LogToFile(L"Info : Entry : ");
CLog::Instance()->LogToFile(sLog);
CLog::Instance()->LogToFile(L"\n");
#endif
}
}
else
{
#if defined(_LOG) && defined(_DEBUG)
CString sLog;
sLog.Format(L"%d", dwErr);
CLog::Instance()->LogToFile(L"Error : RasEnumConnections failed with error code: ");
CLog::Instance()->LogToFile(sLog);
CLog::Instance()->LogToFile(L"\n");
#endif
}
if (NULL != lpRasConn)
{
HeapFree(GetProcessHeap(), 0, lpRasConn);
lpRasConn = NULL;
}
return dwConnections;
}
BOOL CMyRAS::Initialize(CWnd* pEventWnd)
{
m_pEventWnd = pEventWnd;
// I Need to find what OS version is running
OSVERSIONINFO osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osvi);
DWORD dwCb = 0;
DWORD dwRet = ERROR_SUCCESS;
DWORD dwEntries = 0;
LPRASENTRYNAME lpRasEntryName = NULL;
if(osvi.dwMajorVersion > 5) //check OS version
{
//This code way under Windows Vist and Windows 7
// Call RasEnumEntries with lpRasEntryName = NULL. dwCb is returned with the required buffer size and
// a return code of ERROR_BUFFER_TOO_SMALL
dwRet = RasEnumEntries(NULL, NULL, lpRasEntryName, &dwCb, &dwEntries);
//Save all Needed data
m_iEntriesCount = dwEntries;
m_psEntriesNames = new CString [m_iEntriesCount];
if (dwRet == ERROR_BUFFER_TOO_SMALL)
{
// Allocate the memory needed for the array of RAS entry names.
lpRasEntryName = (LPRASENTRYNAME) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwCb);
if (lpRasEntryName == NULL)
{
//CLog::Instance()->Log("Error : HeapAlloc failed!");
return FALSE;
}
// The first RASENTRYNAME structure in the array must contain the structure size
lpRasEntryName[0].dwSize = sizeof(RASENTRYNAME);
// Call RasEnumEntries to enumerate all RAS entry names
dwRet = RasEnumEntries(NULL, NULL, lpRasEntryName, &dwCb, &dwEntries);
// If successful, print the RAS entry names
if (ERROR_SUCCESS == dwRet)
{
//CLog::Instance()->Log("Info : Address book entries were found " );
for (DWORD i = 0; i < dwEntries; i++)
{
m_psEntriesNames[i] = lpRasEntryName[i].szEntryName;
}
}
//Deallocate memory for the connection buffer
HeapFree(GetProcessHeap(), 0, lpRasEntryName);
lpRasEntryName = NULL;
return TRUE;
}
// There was either a problem with RAS or there are RAS entry names to enumerate
if(dwEntries >= 1)
{
//CLog::Instance()->Log("Error : The operation failed to acquire the buffer size.");
}
else
{
#ifdef _LOG
CLog::Instance()->LogToFile(L"Warning : There were no Address book entries found\n");
#endif
}
return FALSE;
}
else
{
//Windows XP
dwCb = sizeof(RASENTRYNAME);
//lpRasEntryName should be allocated and intialized with some size
LPRASENTRYNAME lpRasEntryName = (LPRASENTRYNAME) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwCb);
lpRasEntryName[0].dwSize = sizeof(RASENTRYNAME);
// Call RasEnumEntries with lpRasEntryName = NULL. dwCb is returned with the required buffer size and
// a return code of ERROR_BUFFER_TOO_SMALL
dwRet = RasEnumEntries(NULL, NULL, lpRasEntryName, &dwCb, &dwEntries);
//Save all Needed data
m_iEntriesCount = dwEntries;
m_psEntriesNames = new CString [m_iEntriesCount];
if (dwRet == ERROR_BUFFER_TOO_SMALL || dwRet == 0)
{
//Now we know the right size free what is already allocated
HeapFree(GetProcessHeap(), 0, lpRasEntryName);
lpRasEntryName = NULL;
//Now allocate the correct size
lpRasEntryName = (LPRASENTRYNAME) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwCb);
if (lpRasEntryName == NULL)
{
//CLog::Instance()->Log("Error : HeapAlloc failed!");
return FALSE;
}
// The first RASENTRYNAME structure in the array must contain the structure size
lpRasEntryName[0].dwSize = sizeof(RASENTRYNAME);
// Call RasEnumEntries to enumerate all RAS entry names
dwRet = RasEnumEntries(NULL, NULL, lpRasEntryName, &dwCb, &dwEntries);
// If successful, print the RAS entry names
if (ERROR_SUCCESS == dwRet)
{
//CLog::Instance()->Log("Info : Address book entries were found " );
for (int i = 0; i < dwEntries; i++)
{
m_psEntriesNames[i] = lpRasEntryName[i].szEntryName;
}
}
//Deallocate memory for the connection buffer
HeapFree(GetProcessHeap(), 0, lpRasEntryName);
lpRasEntryName = NULL;
return TRUE;
}
// There was either a problem with RAS or there are RAS entry names to enumerate
if(dwEntries >= 1)
{
//CLog::Instance()->Log("Error : The operation failed to acquire the buffer size.");
}
else
{
//CLog::Instance()->Log("Warning : There were no Address book entries found");
}
return FALSE;
}
}
CString CMyRAS::GetEntry(int iIndex) const
{
if (iIndex < 0 || m_iEntriesCount <= iIndex )
{
return NULL;
}
return m_psEntriesNames[iIndex];
}
BOOL CMyRAS::Dial(CString sEntry, CString sUser, CString sPassword)
{
m_bDialing = TRUE;
DWORD dwRet = ERROR_SUCCESS;
RASDIALPARAMS rasdialparams;
ZeroMemory(&rasdialparams, sizeof(RASDIALPARAMS));
rasdialparams.dwSize = sizeof(RASDIALPARAMS);
rasdialparams.szPhoneNumber[0] = TEXT('\0');
rasdialparams.szCallbackNumber[0] = TEXT('\0');
wcscpy_s(rasdialparams.szEntryName, sEntry);
wcscpy_s (rasdialparams.szUserName, sUser);
wcscpy_s (rasdialparams.szPassword, sPassword);
wcscpy_s (rasdialparams.szDomain, L"");
//dwRet = RasDial (NULL, NULL, &rasdialparams, 0xFFFFFFFF, (LPVOID)m_pEventWnd->GetSafeHwnd(), &m_hRasConn);
dwRet = RasDial (NULL, NULL, &rasdialparams, 0L, (LPVOID)CMyRAS::RasDialEventNotifier, &m_hRasConn);
if (dwRet)
{
//TODO: error try using RasGetErrorString
//TODO: Code needs cleaning
int ERROR_VAL = dwRet;
int BUFFER_SIZE = 256;
DWORD dwRetVal = ERROR_SUCCESS;
UINT uErrorValue = ERROR_VAL;
DWORD cBufSize = BUFFER_SIZE;
WCHAR lpszErrorString[256];
dwRetVal = RasGetErrorString(uErrorValue, lpszErrorString, cBufSize);
if(dwRetVal == ERROR_SUCCESS)
{
MessageBox(NULL, lpszErrorString, L"Error", MB_OK);
}
else
{
//wprintf(L"RasGetErrorString failed, Return Value: %d", dwRetVal);
}
m_bDialing = FALSE;
return FALSE;
}
return TRUE;
}
BOOL CMyRAS::HangUp(void)
{
//if hangup and exit you neet to Sleep(3000) after hangup; MSDN
DWORD dwRet = RasHangUp(m_hRasConn);
if(dwRet == ERROR_SUCCESS)
{
m_bConnected = FALSE;
m_hRasConn = NULL;
m_pEventWnd->PostMessage(WM_DIAL_EVNT, RASCS_Disconnected, 0);
}
return TRUE;
}
BOOL CMyRAS::GetDialErrorMsg(DWORD dwError, CString &sMsg)
{
DWORD dwRetVal = ERROR_SUCCESS;
if (dwError)
{
WCHAR lpszErrorString[256];
RasGetErrorString(dwError, lpszErrorString, 256);
sMsg = lpszErrorString;
}
if(dwRetVal == ERROR_SUCCESS)
{
return TRUE;
}
else
{
return FALSE;
}
}
RASCONNSTATE CMyRAS::GetConnectionStatus(void)
{
RASCONNSTATUS rasconnstatus;
DWORD dwRet;
ZeroMemory(&rasconnstatus, sizeof(RASCONNSTATUS));
rasconnstatus.dwSize = sizeof(RASCONNSTATUS);
dwRet = RasGetConnectStatus(m_hRasConn, &rasconnstatus);
RASCONNSTATE rasconnstate = rasconnstatus.rasconnstate;
return rasconnstate;
}
BOOL CMyRAS::GetConnectionStatistics(DWORD &dwBytesXmited, DWORD &dwBytesRcved, DWORD &dwConnectDuration)
{
RAS_STATS rasstats;
DWORD dwRet;
ZeroMemory(&rasstats, sizeof(RAS_STATS));
rasstats.dwSize = sizeof(RAS_STATS);
dwRet = RasGetConnectionStatistics(m_hRasConn, &rasstats);
if (dwRet == ERROR_SUCCESS)
{
dwBytesXmited = rasstats.dwBytesXmited;
dwBytesRcved = rasstats.dwBytesRcved;
dwConnectDuration = rasstats.dwConnectDuration;
return TRUE;
}
else
{
return FALSE;
}
}
BOOL CMyRAS::isConnected(void)
{
return m_bConnected;
}
BOOL CMyRAS::isDialing(void)
{
return m_bDialing;
}