|
|
// =====================================================================================
// R A S A P I . C P P
// =====================================================================================
#include "pch.hxx"
#include "rasapi.h"
#include "connect.h"
#include "resource.h"
#include "error.h"
#include "strconst.h"
#include "xpcomm.h"
#include "rasdlgsp.h"
#include "goptions.h"
// =====================================================================================
// Ras Dial Function Pointers
// =====================================================================================
static CRITICAL_SECTION g_rCritSec; static HINSTANCE g_hInstRas=NULL; static HINSTANCE g_hInstRasDlg=NULL; static RASDIALPROC g_pRasDial=NULL; static RASENUMCONNECTIONSPROC g_pRasEnumConnections=NULL; static RASENUMENTRIESPROC g_pRasEnumEntries=NULL; static RASGETCONNECTSTATUSPROC g_pRasGetConnectStatus=NULL; static RASGETERRORSTRINGPROC g_pRasGetErrorString=NULL; static RASHANGUPPROC g_pRasHangup=NULL; static RASSETENTRYDIALPARAMSPROC g_pRasSetEntryDialParams=NULL; static RASGETENTRYDIALPARAMSPROC g_pRasGetEntryDialParams=NULL; static RASCREATEPHONEBOOKENTRYPROC g_pRasCreatePhonebookEntry=NULL; static RASEDITPHONEBOOKENTRYPROC g_pRasEditPhonebookEntry=NULL; static RASDIALDLGPROC g_pRasDialDlg=NULL;
// =====================================================================================
// Make our code look prettier
// =====================================================================================
#undef RasDial
#undef RasEnumConnections
#undef RasEnumEntries
#undef RasGetConnectStatus
#undef RasGetErrorString
#undef RasHangup
#undef RasSetEntryDialParams
#undef RasGetEntryDialParams
#undef RasCreatePhonebookEntry
#undef RasEditPhonebookEntry
#undef RasDialDlg
#define RasDial (*g_pRasDial)
#define RasEnumConnections (*g_pRasEnumConnections)
#define RasEnumEntries (*g_pRasEnumEntries)
#define RasGetConnectStatus (*g_pRasGetConnectStatus)
#define RasGetErrorString (*g_pRasGetErrorString)
#define RasHangup (*g_pRasHangup)
#define RasSetEntryDialParams (*g_pRasSetEntryDialParams)
#define RasGetEntryDialParams (*g_pRasGetEntryDialParams)
#define RasCreatePhonebookEntry (*g_pRasCreatePhonebookEntry)
#define RasEditPhonebookEntry (*g_pRasEditPhonebookEntry)
#define RasDialDlg (*g_pRasDialDlg)
#define DEF_HANGUP_WAIT 10 // Seconds
static const TCHAR s_szRasDlgDll[] = "RASDLG.DLL"; #ifdef UNICODE
static const TCHAR s_szRasDialDlg[] = "RasDialDlgW"; #else
static const TCHAR s_szRasDialDlg[] = "RasDialDlgA"; #endif
// =====================================================================================
// Cool little RAS Utilities
// =====================================================================================
HRESULT HrVerifyRasLoaded(VOID); BOOL FEnumerateConnections(LPRASCONN *ppRasConn, ULONG *pcConnections); BOOL FFindConnection(LPTSTR lpszEntry, LPHRASCONN phRasConn); BOOL FRasHangupAndWait(HRASCONN hRasConn, DWORD dwMaxWaitSeconds); HRESULT HrRasError(HWND hwnd, HRESULT hrRasError, DWORD dwRasDial); VOID CombinedRasError(HWND hwnd, UINT unids, LPTSTR pszRasError, DWORD dwRasError);
extern BOOL FIsPlatformWinNT();
// =====================================================================================
// LpCreateRasObject
// =====================================================================================
CRas *LpCreateRasObject(VOID) { CRas *pRas = new CRas; return pRas; }
// =====================================================================================
// RasInit
// =====================================================================================
VOID RasInit(VOID) { InitializeCriticalSection(&g_rCritSec); }
// =====================================================================================
// RasDeinit
// =====================================================================================
VOID RasDeinit(VOID) { if(g_hInstRas) { EnterCriticalSection(&g_rCritSec); g_pRasEnumConnections=NULL; g_pRasEnumEntries=NULL; g_pRasGetConnectStatus=NULL; g_pRasGetErrorString=NULL; g_pRasHangup=NULL; g_pRasSetEntryDialParams=NULL; g_pRasGetEntryDialParams=NULL; g_pRasCreatePhonebookEntry=NULL; g_pRasEditPhonebookEntry=NULL; FreeLibrary(g_hInstRas); g_hInstRas=NULL; LeaveCriticalSection(&g_rCritSec); } if(g_hInstRasDlg) { EnterCriticalSection(&g_rCritSec); g_pRasDialDlg=NULL; FreeLibrary(g_hInstRasDlg); g_hInstRasDlg=NULL; LeaveCriticalSection(&g_rCritSec); } DeleteCriticalSection(&g_rCritSec); }
// =====================================================================================
// CRas::CRas
// =====================================================================================
CRas::CRas() { DOUT("CRas::CRas"); m_cRef = 1; m_fIStartedRas = FALSE; m_iConnectType = 0; *m_szConnectName = _T('\0'); *m_szCurrentConnectName = _T('\0'); m_hRasConn = NULL; m_fForceHangup = FALSE; ZeroMemory(&m_rdp, sizeof(RASDIALPARAMS)); m_fSavePassword = FALSE; m_fShutdown = FALSE; }
// =====================================================================================
// CRas::~CRas
// =====================================================================================
CRas::~CRas() { DOUT("CRas::~CRas"); }
// =====================================================================================
// CRas::AddRef
// =====================================================================================
ULONG CRas::AddRef(VOID) { DOUT("CRas::AddRef %lx ==> %d", this, m_cRef+1); return ++m_cRef; }
// =====================================================================================
// CRas::Release
// =====================================================================================
ULONG CRas::Release(VOID) { DOUT("CRas::Release %lx ==> %d", this, m_cRef-1); if (--m_cRef == 0) { delete this; return 0; } return m_cRef; }
// =====================================================================================
// CRas::FUsingRAS
// =====================================================================================
BOOL CRas::FUsingRAS(VOID) { return m_iConnectType == iConnectRAS ? TRUE : FALSE; }
// =====================================================================================
// CRas::SetConnectInfo
// =====================================================================================
VOID CRas::SetConnectInfo(DWORD iConnectType, LPTSTR pszConnectName) { // Changing connection, drop current ?
if (m_iConnectType == iConnectRAS && iConnectType != iConnectRAS) Disconnect(NULL, FALSE); // Save Connection Data
StrCpyN (m_szConnectName, pszConnectName, RAS_MaxEntryName+1); m_iConnectType = iConnectType;
// Not using RAS
if (m_iConnectType != iConnectRAS) return; }
// =====================================================================================
// CRas::HrConnect
// =====================================================================================
HRESULT CRas::HrConnect(HWND hwnd) { // Locals
HRESULT hr=S_OK; LPRASCONN pRasConn=NULL; ULONG cConnections;
// Not using RAS
if (m_iConnectType != iConnectRAS) goto exit;
// Not inited
hr = HrVerifyRasLoaded(); if (FAILED(hr)) { HrRasError(hwnd, hr, 0); TRAPHR(hr); goto exit; }
// Get Current RAS Connection
FEnumerateConnections(&pRasConn, &cConnections);
// Connections ?
if (cConnections) { m_hRasConn = pRasConn[0].hrasconn; StrCpyN(m_szCurrentConnectName, pRasConn[0].szEntryName, ARRAYSIZE(m_szCurrentConnectName)); } else { m_fIStartedRas = FALSE; m_hRasConn = NULL; *m_szCurrentConnectName = _T('\0'); }
// If RAS Connection present, is it equal to suggested
if (m_hRasConn) { // Current connection is what I want ?
if (lstrcmpi(m_szCurrentConnectName, m_szConnectName) == 0) goto exit;
// Otherwise, if we didn't start the RAS connection...
else if (m_fIStartedRas == FALSE) { // Get option fo handling current connection
UINT unAnswer = UnPromptCloseConn(hwnd);
// Cancel ?
if (IDCANCEL == unAnswer) { hr = TRAPHR(hrUserCancel); goto exit; }
// Close Current ?
else if (idrgDialNew == unAnswer) { m_fForceHangup = TRUE; Disconnect(NULL, FALSE); m_fForceHangup = FALSE; }
// Otherwise, use current ?
else if (idrgUseCurrent == unAnswer) goto exit;
// Problems
else Assert(FALSE); }
// Otherwise, I started the connection, so close it
else if (m_fIStartedRas == TRUE) Disconnect(NULL, FALSE); }
// We probably shouldn't have a connection handle at this point
Assert(m_hRasConn == NULL);
// Dial the connection
CHECKHR(hr = HrStartRasDial(hwnd));
// If Synchronous -- Woo - hoo were connected and we started the connection
m_fIStartedRas = TRUE; StrCpyN(m_szCurrentConnectName, m_szConnectName, ARRAYSIZE(m_szCurrentConnectName));
exit: // Cleanup
SafeMemFree(pRasConn);
// Done
return hr; }
// =====================================================================================
// CRas::UnPromptCloseConn
// =====================================================================================
UINT CRas::UnPromptCloseConn(HWND hwnd) { return DialogBoxParam(g_hLocRes, MAKEINTRESOURCE (iddRasCloseConn), hwnd, RasCloseConnDlgProc, (LPARAM)this); }
// =====================================================================================
// CRas::RasCloseConnDlgProc
// =====================================================================================
INT_PTR CALLBACK CRas::RasCloseConnDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { // Locals
CRas *pRas=NULL; TCHAR szRes[255], szMsg[255+RAS_MaxEntryName+1];
switch(uMsg) { case WM_INITDIALOG: // Get lparam
pRas = (CRas *)lParam; if (!pRas) { Assert (FALSE); EndDialog(hwnd, E_FAIL); return 1; }
// Center
CenterDialog(hwnd);
// Set Text
GetWindowText(GetDlgItem(hwnd, idcCurrentMsg), szRes, sizeof(szRes)/sizeof(TCHAR)); wnsprintf(szMsg, ARRAYSIZE(szMsg),szRes, pRas->m_szCurrentConnectName); SetWindowText(GetDlgItem(hwnd, idcCurrentMsg), szMsg);
// Set control
GetWindowText(GetDlgItem(hwnd, idrgDialNew), szRes, sizeof(szRes)/sizeof(TCHAR)); wnsprintf(szMsg, ARRAYSIZE(szMsg),szRes, pRas->m_szConnectName); SetWindowText(GetDlgItem(hwnd, idrgDialNew), szMsg);
// Set Default
CheckDlgButton(hwnd, idrgDialNew, TRUE); return 1;
case WM_COMMAND: switch(GET_WM_COMMAND_ID(wParam,lParam)) { case IDOK: EndDialog(hwnd, IsDlgButtonChecked(hwnd, idrgDialNew) ? idrgDialNew : idrgUseCurrent); return 1;
case IDCANCEL: EndDialog(hwnd, IDCANCEL); return 1; } } return 0; }
// =====================================================================================
// CRas::HrRasLogon
// =====================================================================================
HRESULT CRas::HrRasLogon(HWND hwnd, BOOL fForcePrompt) { // Locals
HRESULT hr=S_OK; DWORD dwRasError;
// Do we need to prompt for logon information first ?
ZeroMemory(&m_rdp, sizeof(RASDIALPARAMS)); m_rdp.dwSize = sizeof(RASDIALPARAMS); StrCpyN(m_rdp.szEntryName, m_szConnectName, ARRAYSIZE(m_rdp.szEntryName));
// Get params
dwRasError = RasGetEntryDialParams(NULL, &m_rdp, &m_fSavePassword); if (dwRasError) { HrRasError(hwnd, hrGetDialParamsFailed, dwRasError); hr = TRAPHR(hrGetDialParamsFailed); goto exit; }
if (g_pRasDialDlg) { // RasDialDlg will take it from here
goto exit; }
// Do we need to get password / account information
if (fForcePrompt || m_fSavePassword == FALSE || FIsStringEmpty(m_rdp.szUserName) || FIsStringEmpty(m_rdp.szPassword)) { // RAS Logon
hr = DialogBoxParam (g_hLocRes, MAKEINTRESOURCE (iddRasLogon), hwnd, RasLogonDlgProc, (LPARAM)this); if (hr == hrUserCancel) { HrRasError(hwnd, hrUserCancel, 0); hr = hrUserCancel; goto exit; } }
exit: // Done
return hr; }
// =====================================================================================
// CRas::RasLogonDlgProc
// =====================================================================================
INT_PTR CALLBACK CRas::RasLogonDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { // Locals
TCHAR sz[255], szText[255+RAS_MaxEntryName+1]; CRas *pRas = (CRas *)GetWndThisPtr(hwnd); DWORD dwRasError;
switch (uMsg) { case WM_INITDIALOG: // Get lparam
pRas = (CRas *)lParam; if (!pRas) { Assert (FALSE); EndDialog(hwnd, E_FAIL); return 1; }
// Center the window
CenterDialog (hwnd);
// Get Window Title
GetWindowText(hwnd, sz, sizeof(sz)); wnsprintf(szText, ARRAYSIZE(szText),sz, pRas->m_szConnectName); SetWindowText(hwnd, szText);
// Word Default
AthLoadString(idsDefault, sz, sizeof(sz)); // Set Fields
Edit_LimitText(GetDlgItem(hwnd, ideUserName), UNLEN); Edit_LimitText(GetDlgItem(hwnd, idePassword), PWLEN); //Edit_LimitText(GetDlgItem(hwnd, ideDomain), DNLEN);
Edit_LimitText(GetDlgItem(hwnd, idePhone), RAS_MaxPhoneNumber); SetDlgItemText(hwnd, ideUserName, pRas->m_rdp.szUserName); SetDlgItemText(hwnd, idePassword, pRas->m_rdp.szPassword);
/*
if (FIsStringEmpty(pRas->m_rdp.szDomain)) SetDlgItemText(hwnd, ideDomain, sz); else SetDlgItemText(hwnd, ideDomain, pRas->m_rdp.szDomain); */
if (FIsStringEmpty(pRas->m_rdp.szPhoneNumber)) SetDlgItemText(hwnd, idePhone, sz); else SetDlgItemText(hwnd, idePhone, pRas->m_rdp.szPhoneNumber);
CheckDlgButton(hwnd, idchSavePassword, pRas->m_fSavePassword);
// Save pRas
SetWndThisPtr (hwnd, pRas); return 1;
case WM_COMMAND: switch(GET_WM_COMMAND_ID(wParam,lParam)) { case idbEditConnection: EditPhonebookEntry(hwnd, pRas->m_szConnectName); return 1;
case IDCANCEL: EndDialog(hwnd, hrUserCancel); return 1;
case IDOK: AthLoadString(idsDefault, sz, sizeof(sz));
// Set Fields
GetDlgItemText(hwnd, ideUserName, pRas->m_rdp.szUserName, UNLEN+1); GetDlgItemText(hwnd, idePassword, pRas->m_rdp.szPassword, PWLEN+1);
/*
GetDlgItemText(hwnd, ideDomain, pRas->m_rdp.szDomain, DNLEN+1); if (lstrcmp(pRas->m_rdp.szDomain, sz) == 0) *pRas->m_rdp.szDomain = _T('\0'); */ GetDlgItemText(hwnd, idePhone, pRas->m_rdp.szPhoneNumber, RAS_MaxPhoneNumber+1); if (lstrcmp(pRas->m_rdp.szPhoneNumber, sz) == 0) *pRas->m_rdp.szPhoneNumber = _T('\0'); pRas->m_fSavePassword = IsDlgButtonChecked(hwnd, idchSavePassword);
// Save Dial Parameters
dwRasError = RasSetEntryDialParams(NULL, &pRas->m_rdp, !pRas->m_fSavePassword); if (dwRasError) { HrRasError(hwnd, hrSetDialParamsFailed, dwRasError); return 1; } EndDialog(hwnd, S_OK); return 1; } break;
case WM_DESTROY: SetWndThisPtr (hwnd, NULL); break; } return 0; }
// =====================================================================================
// CRas::HrShowRasDialError
// =====================================================================================
HRESULT CRas::HrStartRasDial(HWND hwndParent) { // Locals
HRESULT hr=S_OK;
// Logon first ?
CHECKHR (hr = HrRasLogon(hwndParent, FALSE));
if (g_pRasDialDlg) { RASDIALDLG rdd = {0}; BOOL fRet;
rdd.dwSize = sizeof(rdd); rdd.hwndOwner = hwndParent;
#if (WINVER >= 0x401)
rdd.dwSubEntry = m_rdp.dwSubEntry; #else
rdd.dwSubEntry = 0; #endif
fRet = RasDialDlg(NULL, m_rdp.szEntryName, lstrlen(m_rdp.szPhoneNumber) ? m_rdp.szPhoneNumber : NULL, &rdd); if (!fRet) { hr = E_FAIL; } } else { // Done
hr = DialogBoxParam (g_hLocRes, MAKEINTRESOURCE (iddRasProgress), hwndParent, RasProgressDlgProc, (LPARAM)this); }
exit: // Done
return hr; }
// =====================================================================================
// CRas::RasProgressDlgProc
// =====================================================================================
INT_PTR CALLBACK CRas::RasProgressDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { // Locals
TCHAR szText[255+RAS_MaxEntryName+1], sz[255]; CRas *pRas = (CRas *)GetWndThisPtr(hwnd); static TCHAR s_szCancel[40]; static UINT s_unRasEventMsg=0; static BOOL s_fDetails=FALSE; static RECT s_rcDialog; static BOOL s_fAuthStarted=FALSE; DWORD dwRasError, cyDetails; RASCONNSTATUS rcs; RECT rcDetails, rcDlg; switch (uMsg) { case WM_INITDIALOG: // Get lparam
pRas = (CRas *)lParam; if (!pRas) { Assert (FALSE); EndDialog(hwnd, E_FAIL); return 1; }
// Save this pointer
SetWndThisPtr (hwnd, pRas);
// Save Original Size of the dialog
GetWindowRect (hwnd, &s_rcDialog);
// Details enabled
s_fDetails = DwGetOption(OPT_RASCONNDETAILS);
// Hide details drop down
if (s_fDetails == FALSE) { // Hid
GetWindowRect (GetDlgItem (hwnd, idcSplitter), &rcDetails);
// Height of details
cyDetails = s_rcDialog.bottom - rcDetails.top; // Re-size
MoveWindow (hwnd, s_rcDialog.left, s_rcDialog.top, s_rcDialog.right - s_rcDialog.left, s_rcDialog.bottom - s_rcDialog.top - cyDetails - 1, FALSE); } else { AthLoadString (idsHideDetails, sz, sizeof (sz)); SetWindowText (GetDlgItem (hwnd, idbDet), sz); }
// Get registered RAS event message id
s_unRasEventMsg = RegisterWindowMessageA(RASDIALEVENT); if (s_unRasEventMsg == 0) s_unRasEventMsg = WM_RASDIALEVENT;
// Center the window
CenterDialog (hwnd);
// Get Window Title
GetWindowText(hwnd, sz, sizeof(sz)); wnsprintf(szText, ARRAYSIZE(szText),sz, pRas->m_szConnectName); SetWindowText(hwnd, szText);
// Dialog Xxxxxxx.....
AthLoadString(idsRas_Dialing, sz, sizeof(sz)/sizeof(TCHAR)); wnsprintf(szText, ARRAYSIZE(szText),sz, pRas->m_rdp.szPhoneNumber); SetWindowText(GetDlgItem(hwnd, ideProgress), szText);
// Get Cancel Text
GetWindowText(GetDlgItem(hwnd, IDCANCEL), s_szCancel, sizeof(s_szCancel));
// Give the list box and hscroll
SendMessage(GetDlgItem(hwnd, idlbDetails), LB_SETHORIZONTALEXTENT, 600, 0);
// Dial the connection
pRas->m_hRasConn = NULL; dwRasError = RasDial(NULL, NULL, &pRas->m_rdp, 0xFFFFFFFF, hwnd, &pRas->m_hRasConn); if (dwRasError) { pRas->FailedRasDial(hwnd, hrRasDialFailure, dwRasError); if (!pRas->FLogonRetry(hwnd, s_szCancel)) { SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDCANCEL,IDCANCEL), NULL); return 1; } } return 1;
case WM_COMMAND: switch(GET_WM_COMMAND_ID(wParam,lParam)) { case IDCANCEL: SetDwOption(OPT_RASCONNDETAILS, s_fDetails); EnableWindow(GetDlgItem(hwnd, IDCANCEL), FALSE); if (pRas) pRas->FailedRasDial(hwnd, hrUserCancel, 0); EndDialog(hwnd, hrUserCancel); return 1;
case idbDet: // Get current location of the dialog
GetWindowRect (hwnd, &rcDlg);
// If currently hidden
if (s_fDetails == FALSE) { // Re-size
MoveWindow (hwnd, rcDlg.left, rcDlg.top, s_rcDialog.right - s_rcDialog.left, s_rcDialog.bottom - s_rcDialog.top, TRUE);
AthLoadString (idsHideDetails, sz, sizeof (sz)); SetWindowText (GetDlgItem (hwnd, idbDet), sz); s_fDetails = TRUE; }
else { // Size of details
GetWindowRect (GetDlgItem (hwnd, idcSplitter), &rcDetails); cyDetails = rcDlg.bottom - rcDetails.top; MoveWindow (hwnd, rcDlg.left, rcDlg.top, s_rcDialog.right - s_rcDialog.left, s_rcDialog.bottom - s_rcDialog.top - cyDetails - 1, TRUE);
AthLoadString (idsShowDetails, sz, sizeof (sz)); SetWindowText (GetDlgItem (hwnd, idbDet), sz); s_fDetails = FALSE; } break; } break;
case WM_DESTROY: SetWndThisPtr (hwnd, NULL); break;
default: if (!pRas) break;
if (uMsg == s_unRasEventMsg) { HWND hwndLB = GetDlgItem(hwnd, idlbDetails);
// Error ?
if (lParam) { // Disconnected
AthLoadString(idsRASCS_Disconnected, sz, sizeof(sz)/sizeof(TCHAR)); ListBox_AddString(hwndLB, sz);
// Log Error
TCHAR szRasError[512]; if (RasGetErrorString(lParam, szRasError, sizeof(szRasError)) == 0) { TCHAR szError[512 + 255]; AthLoadString(idsErrorText, sz, sizeof(sz)); wnsprintf(szError, ARRAYSIZE(szError),"%s %d: %s", sz, lParam, szRasError); ListBox_AddString(hwndLB, szError); }
// Select last item
SendMessage(hwndLB, LB_SETCURSEL, ListBox_GetCount(hwndLB)-1, 0);
// Show Error
pRas->FailedRasDial(hwnd, hrRasDialFailure, lParam);
// Re logon
if (!pRas->FLogonRetry(hwnd, s_szCancel)) { SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDCANCEL,IDCANCEL), NULL); return 1; } }
// Otherwise, process RAS event
else { switch(wParam) { case RASCS_OpenPort: AthLoadString(idsRASCS_OpenPort, sz, sizeof(sz)/sizeof(TCHAR)); ListBox_AddString(hwndLB, sz); break;
case RASCS_PortOpened: AthLoadString(idsRASCS_PortOpened, sz, sizeof(sz)/sizeof(TCHAR)); ListBox_AddString(hwndLB, sz); break;
case RASCS_ConnectDevice: rcs.dwSize = sizeof(RASCONNSTATUS); if (pRas->m_hRasConn && RasGetConnectStatus(pRas->m_hRasConn, &rcs) == 0) { AthLoadString(idsRASCS_ConnectDevice, sz, sizeof(sz)/sizeof(TCHAR)); wnsprintf(szText, ARRAYSIZE(szText),sz, rcs.szDeviceName, rcs.szDeviceType); ListBox_AddString(hwndLB, szText); } break;
case RASCS_DeviceConnected: rcs.dwSize = sizeof(RASCONNSTATUS); if (pRas->m_hRasConn && RasGetConnectStatus(pRas->m_hRasConn, &rcs) == 0) { AthLoadString(idsRASCS_DeviceConnected, sz, sizeof(sz)/sizeof(TCHAR)); wnsprintf(szText, ARRAYSIZE(szText),sz, rcs.szDeviceName, rcs.szDeviceType); ListBox_AddString(hwndLB, szText); } break;
case RASCS_AllDevicesConnected: AthLoadString(idsRASCS_AllDevicesConnected, sz, sizeof(sz)/sizeof(TCHAR)); ListBox_AddString(hwndLB, sz); break;
case RASCS_Authenticate: if (s_fAuthStarted == FALSE) { AthLoadString(idsRas_Authentication, sz, sizeof(sz)/sizeof(TCHAR)); SetWindowText(GetDlgItem(hwnd, ideProgress), sz); ListBox_AddString(hwndLB, sz); s_fAuthStarted = TRUE; } break;
case RASCS_AuthNotify: rcs.dwSize = sizeof(RASCONNSTATUS); if (pRas->m_hRasConn && RasGetConnectStatus(pRas->m_hRasConn, &rcs) == 0) { AthLoadString(idsRASCS_AuthNotify, sz, sizeof(sz)/sizeof(TCHAR)); wnsprintf(szText, ARRAYSIZE(szText),sz, rcs.dwError); ListBox_AddString(hwndLB, szText); if (rcs.dwError) { pRas->FailedRasDial(hwnd, hrRasDialFailure, rcs.dwError); if (!pRas->FLogonRetry(hwnd, s_szCancel)) { SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDCANCEL,IDCANCEL), NULL); return 1; } } } break;
case RASCS_AuthRetry: AthLoadString(idsRASCS_AuthRetry, sz, sizeof(sz)/sizeof(TCHAR)); ListBox_AddString(hwndLB, sz); break;
case RASCS_AuthCallback: AthLoadString(idsRASCS_AuthCallback, sz, sizeof(sz)/sizeof(TCHAR)); ListBox_AddString(hwndLB, sz); break;
case RASCS_AuthChangePassword: AthLoadString(idsRASCS_AuthChangePassword, sz, sizeof(sz)/sizeof(TCHAR)); ListBox_AddString(hwndLB, sz); break;
case RASCS_AuthProject: AthLoadString(idsRASCS_AuthProject, sz, sizeof(sz)/sizeof(TCHAR)); ListBox_AddString(hwndLB, sz); break;
case RASCS_AuthLinkSpeed: AthLoadString(idsRASCS_AuthLinkSpeed, sz, sizeof(sz)/sizeof(TCHAR)); ListBox_AddString(hwndLB, sz); break;
case RASCS_AuthAck: AthLoadString(idsRASCS_AuthAck, sz, sizeof(sz)/sizeof(TCHAR)); ListBox_AddString(hwndLB, sz); break;
case RASCS_ReAuthenticate: AthLoadString(idsRas_Authenticated, sz, sizeof(sz)/sizeof(TCHAR)); SetWindowText(GetDlgItem(hwnd, ideProgress), sz); AthLoadString(idsRASCS_Authenticated, sz, sizeof(sz)/sizeof(TCHAR)); ListBox_AddString(hwndLB, sz); break;
case RASCS_PrepareForCallback: AthLoadString(idsRASCS_PrepareForCallback, sz, sizeof(sz)/sizeof(TCHAR)); ListBox_AddString(hwndLB, sz); break;
case RASCS_WaitForModemReset: AthLoadString(idsRASCS_WaitForModemReset, sz, sizeof(sz)/sizeof(TCHAR)); ListBox_AddString(hwndLB, sz); break;
case RASCS_WaitForCallback: AthLoadString(idsRASCS_WaitForCallback, sz, sizeof(sz)/sizeof(TCHAR)); ListBox_AddString(hwndLB, sz); break;
case RASCS_Projected: AthLoadString(idsRASCS_Projected, sz, sizeof(sz)/sizeof(TCHAR)); ListBox_AddString(hwndLB, sz); break;
case RASCS_Disconnected: AthLoadString(idsRASCS_Disconnected, sz, sizeof(sz)/sizeof(TCHAR)); SetWindowText(GetDlgItem(hwnd, ideProgress), sz); ListBox_AddString(hwndLB, sz); pRas->FailedRasDial(hwnd, hrRasDialFailure, 0); if (!pRas->FLogonRetry(hwnd, s_szCancel)) { SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDCANCEL,IDCANCEL), NULL); return 1; } break;
case RASCS_Connected: SetDwOption(OPT_RASCONNDETAILS, s_fDetails); AthLoadString(idsRASCS_Connected, sz, sizeof(sz)/sizeof(TCHAR)); SetWindowText(GetDlgItem(hwnd, ideProgress), sz); ListBox_AddString(hwndLB, sz); EndDialog(hwnd, S_OK); break; }
// Select last lb item
SendMessage(hwndLB, LB_SETCURSEL, ListBox_GetCount(hwndLB)-1, 0); } return 1; } break; }
// Done
return 0; }
// =====================================================================================
// CRas::FLogonRetry
// =====================================================================================
BOOL CRas::FLogonRetry(HWND hwnd, LPTSTR pszCancel) { // Locals
DWORD dwRasError;
// Reset Cancel button
SetWindowText(GetDlgItem(hwnd, IDCANCEL), pszCancel);
// Empty the listbox
ListBox_ResetContent(GetDlgItem(hwnd, idlbDetails));
while(1) { // If failed...
if (FAILED(HrRasLogon(hwnd, TRUE))) return FALSE;
// Dial the connection
m_hRasConn = NULL; dwRasError = RasDial(NULL, NULL, &m_rdp, 0xFFFFFFFF, hwnd, &m_hRasConn); if (dwRasError) { FailedRasDial(hwnd, hrRasDialFailure, dwRasError); continue; }
// Success
break; }
// Done
return TRUE; }
// =====================================================================================
// CRas::FailedRasDial
// =====================================================================================
VOID CRas::FailedRasDial(HWND hwnd, HRESULT hrRasError, DWORD dwRasError) { // Locals
TCHAR sz[255];
// Hangup the connection
if (m_hRasConn) FRasHangupAndWait(m_hRasConn, DEF_HANGUP_WAIT);
// Disconnected
AthLoadString(idsRASCS_Disconnected, sz, sizeof(sz)/sizeof(TCHAR)); SetWindowText(GetDlgItem(hwnd, ideProgress), sz);
// Save dwRasError
HrRasError(hwnd, hrRasError, dwRasError);
// NULL it
m_hRasConn = NULL;
// Change dialog button to OK
AthLoadString(idsOK, sz, sizeof(sz)/sizeof(TCHAR)); SetWindowText(GetDlgItem(hwnd, IDCANCEL), sz); }
// =====================================================================================
// CRas::Disconnect
// =====================================================================================
VOID CRas::Disconnect(HWND hwnd, BOOL fShutdown) { // If not using RAS, who give a crap
if (m_iConnectType != iConnectRAS) { Assert(m_hRasConn == NULL); Assert(m_fIStartedRas == FALSE); goto exit; }
// Do we have a RAS connection
if (m_hRasConn && (m_fIStartedRas || m_fForceHangup)) { // Locals
TCHAR szRes[255]; TCHAR szMsg[255]; INT nAnswer=IDYES;
// If Shutdown, lets prompt the user
if (fShutdown) { // Remember were shuting down
m_fShutdown = TRUE;
// Prompt
AthLoadString(idsRasPromptDisconnect, szRes, sizeof(szRes)/sizeof(TCHAR)); wnsprintf(szMsg, ARRAYSIZE(szMsg),szRes, m_szCurrentConnectName);
// Prompt shutdown ?
nAnswer = AthMessageBox(hwnd, MAKEINTRESOURCE(idsAthena), szMsg, 0, MB_YESNO | MB_ICONEXCLAMATION ); } else AssertSz(m_fShutdown == FALSE, "Disconnect better not have been called with fShutdown = TRUE, and then FALSE");
// Hangup
if (nAnswer == IDYES) { FRasHangupAndWait(m_hRasConn, DEF_HANGUP_WAIT); m_hRasConn = NULL; m_fIStartedRas = FALSE; *m_szCurrentConnectName = _T('\0'); } }
// Otherwise, reset state
else { // Leave current connection informtaion
m_hRasConn = NULL; m_fIStartedRas = FALSE; }
exit: // Done
return; }
// ****************************************************************************************
// Simple RAS Utility Functions
// ****************************************************************************************
// =====================================================================================
// HrVerifyRasLoaded
// =====================================================================================
HRESULT HrVerifyRasLoaded(VOID) { // Locals
UINT uOldErrorMode;
// Protected
EnterCriticalSection(&g_rCritSec);
// If dll is loaded, lets verify all of my function pointers
if (!g_hInstRas) { // Try loading Ras.
uOldErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX); g_hInstRas = LoadLibrary(szRasDll); SetErrorMode(uOldErrorMode);
// Failure ?
if (!g_hInstRas) goto failure;
// Did we load it
g_pRasDial = (RASDIALPROC)GetProcAddress(g_hInstRas, szRasDial); g_pRasEnumConnections = (RASENUMCONNECTIONSPROC)GetProcAddress(g_hInstRas, szRasEnumConnections); g_pRasEnumEntries = (RASENUMENTRIESPROC)GetProcAddress(g_hInstRas, szRasEnumEntries); g_pRasGetConnectStatus = (RASGETCONNECTSTATUSPROC)GetProcAddress(g_hInstRas, szRasGetConnectStatus); g_pRasGetErrorString = (RASGETERRORSTRINGPROC)GetProcAddress(g_hInstRas, szRasGetErrorString); g_pRasHangup = (RASHANGUPPROC)GetProcAddress(g_hInstRas, szRasHangup); g_pRasSetEntryDialParams = (RASSETENTRYDIALPARAMSPROC)GetProcAddress(g_hInstRas, szRasSetEntryDialParams); g_pRasGetEntryDialParams = (RASGETENTRYDIALPARAMSPROC)GetProcAddress(g_hInstRas, szRasGetEntryDialParams); g_pRasCreatePhonebookEntry = (RASCREATEPHONEBOOKENTRYPROC)GetProcAddress(g_hInstRas, szRasCreatePhonebookEntry); g_pRasEditPhonebookEntry = (RASEDITPHONEBOOKENTRYPROC)GetProcAddress(g_hInstRas, szRasEditPhonebookEntry); }
if (!g_hInstRasDlg && FIsPlatformWinNT()) { // Try loading Ras.
uOldErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX); g_hInstRasDlg = LoadLibrary(s_szRasDlgDll); SetErrorMode(uOldErrorMode);
// Failure ?
if (!g_hInstRasDlg) goto failure;
g_pRasDialDlg = (RASDIALDLGPROC)GetProcAddress(g_hInstRasDlg, s_szRasDialDlg);
if (!g_pRasDialDlg) goto failure; }
// Make sure all functions have been loaded
if (g_pRasDial && g_pRasEnumConnections && g_pRasEnumEntries && g_pRasGetConnectStatus && g_pRasGetErrorString && g_pRasHangup && g_pRasSetEntryDialParams && g_pRasGetEntryDialParams && g_pRasCreatePhonebookEntry && g_pRasEditPhonebookEntry) { // Protected
LeaveCriticalSection(&g_rCritSec);
// Success
return S_OK; }
failure: // Protected
LeaveCriticalSection(&g_rCritSec);
// Otherwise, were hosed
return TRAPHR(hrRasInitFailure); }
// =====================================================================================
// CombinedRasError
// =====================================================================================
VOID CombinedRasError(HWND hwnd, UINT unids, LPTSTR pszRasError, DWORD dwRasError) { // Locals
TCHAR szRes[255], sz[30]; LPTSTR pszError=NULL;
// Load string
AthLoadString(unids, szRes, sizeof(szRes));
// Allocate memory for errors
DWORD cchSize = lstrlen(szRes) + lstrlen(pszRasError) + 100; pszError = SzStrAlloc(cchSize);
// Out of Memory ?
if (!pszError) AthMessageBox(hwnd, MAKEINTRESOURCE(idsRasError), szRes, 0, MB_OK | MB_ICONSTOP);
// Build Error message
else { AthLoadString(idsErrorText, sz, sizeof(sz)); wnsprintf(pszError, cchSize, "%s\n\n%s %d: %s", szRes, sz, dwRasError, pszRasError); AthMessageBox(hwnd, MAKEINTRESOURCE(idsRasError), pszError, 0, MB_OK | MB_ICONSTOP); MemFree(pszError); } }
// =====================================================================================
// HrRasError
// =====================================================================================
HRESULT HrRasError(HWND hwnd, HRESULT hrRasError, DWORD dwRasError) { // Locals
TCHAR szRasError[256]; BOOL fRasError=FALSE;
// No Error
if (SUCCEEDED(hrRasError)) return hrRasError;
// Look up RAS error
if (dwRasError) { if (RasGetErrorString(dwRasError, szRasError, sizeof(szRasError)) == 0) fRasError = TRUE; else *szRasError = _T('\0'); }
// General Error
switch(hrRasError) { case hrUserCancel: break;
case hrMemory: AthMessageBoxW(hwnd, MAKEINTRESOURCEW(idsRasError), MAKEINTRESOURCEW(idsMemory), 0, MB_OK | MB_ICONSTOP); break;
case hrRasInitFailure: AthMessageBoxW(hwnd, MAKEINTRESOURCEW(idsRasError), MAKEINTRESOURCEW(hrRasInitFailure), 0, MB_OK | MB_ICONSTOP); break;
case hrRasDialFailure: if (fRasError) CombinedRasError(hwnd, HR_CODE(hrRasDialFailure), szRasError, dwRasError); else AthMessageBoxW(hwnd, MAKEINTRESOURCEW(idsRasError), MAKEINTRESOURCEW(hrRasDialFailure), 0, MB_OK | MB_ICONSTOP); break;
case hrRasServerNotFound: AthMessageBoxW(hwnd, MAKEINTRESOURCEW(idsRasError), MAKEINTRESOURCEW(hrRasServerNotFound), 0, MB_OK | MB_ICONSTOP); break;
case hrGetDialParamsFailed: AthMessageBoxW(hwnd, MAKEINTRESOURCEW(idsRasError), MAKEINTRESOURCEW(hrGetDialParamsFailed), 0, MB_OK | MB_ICONSTOP); break;
case E_FAIL: default: AthMessageBoxW(hwnd, MAKEINTRESOURCEW(idsRasError), MAKEINTRESOURCEW(idsRasErrorGeneral), 0, MB_OK | MB_ICONSTOP); break; }
// Done
return hrRasError; }
// =====================================================================================
// FEnumerateConnections
// =====================================================================================
BOOL FEnumerateConnections(LPRASCONN *ppRasConn, ULONG *pcConnections) { // Locals
DWORD dw, dwSize; BOOL fResult=FALSE;
// Check Params
Assert(ppRasConn && pcConnections);
// Make sure RAS is loaded
if (FAILED(HrVerifyRasLoaded())) goto exit;
// Init
*ppRasConn = NULL; *pcConnections = 0;
// Sizeof my buffer
dwSize = sizeof(RASCONN);
// Allocate enough for 1 ras connection info object
if (!MemAlloc((LPVOID *)ppRasConn, dwSize)) { TRAPHR(hrMemory); goto exit; }
// Buffer size
(*ppRasConn)->dwSize = dwSize;
// Enumerate ras connections
dw = RasEnumConnections(*ppRasConn, &dwSize, pcConnections);
// Not enough memory ?
if (dw == ERROR_BUFFER_TOO_SMALL) { // Reallocate
if (!MemRealloc((LPVOID *)ppRasConn, dwSize)) { TRAPHR(hrMemory); goto exit; }
// Call enumerate again
*pcConnections = 0; (*ppRasConn)->dwSize = sizeof(RASCONN); dw = RasEnumConnections(*ppRasConn, &dwSize, pcConnections); }
// If still failed
if (dw) { AssertSz(FALSE, "RasEnumConnections failed"); goto exit; }
// Success
fResult = TRUE;
exit: // Done
return fResult; }
// =====================================================================================
// FFindConnection
// =====================================================================================
BOOL FFindConnection(LPTSTR lpszEntry, LPHRASCONN phRasConn) { // Locals
ULONG cConnections, i; LPRASCONN pRasConn=NULL; BOOL fResult=FALSE;
// Check Params
Assert(lpszEntry && phRasConn);
// Make sure RAS is loaded
if (FAILED(HrVerifyRasLoaded())) goto exit;
// Init
*phRasConn = NULL;
// Enumerate Connections
if (!FEnumerateConnections(&pRasConn, &cConnections)) goto exit;
// If still failed
for (i=0; i<cConnections; i++) { if (lstrcmpi(pRasConn[i].szEntryName, lpszEntry) == 0) { *phRasConn = pRasConn[i].hrasconn; fResult = TRUE; goto exit; } }
exit: // Cleanup
SafeMemFree(pRasConn);
// Done
return fResult; }
// ==================================================================================================================
// FRasHangupAndWait
// ==================================================================================================================
BOOL FRasHangupAndWait(HRASCONN hRasConn, DWORD dwMaxWaitSeconds) { // Locals
RASCONNSTATUS rcs; DWORD dwTicks=GetTickCount();
// Check Params
if (!hRasConn) return 0;
// Make sure RAS is loaded
if (FAILED (HrVerifyRasLoaded())) return FALSE;
// Call Ras hangup
if (RasHangup(hRasConn)) return FALSE;
// Wait for connection to really close
while (RasGetConnectStatus(hRasConn, &rcs) == 0) { // Wait timeout
if (GetTickCount() - dwTicks >= dwMaxWaitSeconds * 1000) break;
// Sleep and yields
Sleep(0); }
// Wait 1/2 seconds for modem to reset
Sleep(500);
// Done
return TRUE; }
// ==================================================================================================================
// FillRasCombo
// ==================================================================================================================
VOID FillRasCombo(HWND hwndCtl, BOOL fUpdateOnly) { LPRASENTRYNAME lprasentry=NULL; DWORD dwSize; DWORD cEntries; DWORD dwError;
// Make sure RAS is loaded
if (FAILED (HrVerifyRasLoaded())) return;
if (!fUpdateOnly) SendMessage(hwndCtl, CB_RESETCONTENT,0,0); dwSize = sizeof(RASENTRYNAME); if (!MemAlloc((LPVOID*) &lprasentry, dwSize)) return; lprasentry->dwSize = sizeof(RASENTRYNAME); cEntries = 0; dwError = RasEnumEntries(NULL, NULL, lprasentry, &dwSize, &cEntries); if (dwError == ERROR_BUFFER_TOO_SMALL) { MemFree(lprasentry); MemAlloc((LPVOID*) &lprasentry, dwSize); lprasentry->dwSize = sizeof(RASENTRYNAME); cEntries = 0; dwError = RasEnumEntries(NULL, NULL, lprasentry, &dwSize, &cEntries); }
if (dwError) goto error; while(cEntries) { if (!fUpdateOnly) SendMessage(hwndCtl, CB_ADDSTRING, 0, (LPARAM)(lprasentry[cEntries-1].szEntryName)); else { if (ComboBox_FindStringExact(hwndCtl, 0, lprasentry[cEntries - 1].szEntryName) < 0) { int iSel = ComboBox_AddString(hwndCtl, lprasentry[cEntries - 1].szEntryName); Assert(iSel >= 0); ComboBox_SetCurSel(hwndCtl, iSel); } } cEntries--; }
error: MemFree(lprasentry); }
// ==================================================================================================================
// EditPhoneBookEntry
// ==================================================================================================================
DWORD EditPhonebookEntry(HWND hwnd, LPTSTR pszEntryName) { if (FAILED(HrVerifyRasLoaded())) return (DWORD)E_FAIL;
return RasEditPhonebookEntry(hwnd, NULL, pszEntryName); }
// ==================================================================================================================
// CreatePhonebookEntry
// ==================================================================================================================
DWORD CreatePhonebookEntry(HWND hwnd) { if (FAILED(HrVerifyRasLoaded())) return (DWORD)E_FAIL;
return RasCreatePhonebookEntry(hwnd, NULL); }
|