|
|
// --------------------------------------------------------------------------------
// Ixpras.cpp
// Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
// Steven J. Bailey
// --------------------------------------------------------------------------------
#include "pch.hxx"
#include "dllmain.h"
#include "ixpras.h"
#include "strconst.h"
#include "resource.h"
#include "demand.h"
#include "shlwapi.h"
// --------------------------------------------------------------------------------
// RAS API Typedefs
// --------------------------------------------------------------------------------
typedef DWORD (APIENTRY *RASDIALPROC)(LPRASDIALEXTENSIONS, LPTSTR, LPRASDIALPARAMS, DWORD, LPVOID, LPHRASCONN); typedef DWORD (APIENTRY *RASENUMCONNECTIONSPROC)(LPRASCONN, LPDWORD, LPDWORD); typedef DWORD (APIENTRY *RASENUMENTRIESPROC)(LPTSTR, LPTSTR, LPRASENTRYNAME, LPDWORD, LPDWORD); typedef DWORD (APIENTRY *RASGETCONNECTSTATUSPROC)(HRASCONN, LPRASCONNSTATUS); typedef DWORD (APIENTRY *RASGETERRORSTRINGPROC)(UINT, LPTSTR, DWORD); typedef DWORD (APIENTRY *RASHANGUPPROC)(HRASCONN); typedef DWORD (APIENTRY *RASSETENTRYDIALPARAMSPROC)(LPTSTR, LPRASDIALPARAMS, BOOL); typedef DWORD (APIENTRY *RASGETENTRYDIALPARAMSPROC)(LPTSTR, LPRASDIALPARAMS, BOOL*); typedef DWORD (APIENTRY *RASCREATEPHONEBOOKENTRYPROC)(HWND, LPTSTR); typedef DWORD (APIENTRY *RASEDITPHONEBOOKENTRYPROC)(HWND, LPTSTR, LPTSTR);
// --------------------------------------------------------------------------------
// RAS Function Pointers
// --------------------------------------------------------------------------------
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;
#define DEF_HANGUP_WAIT 10 // Seconds
// --------------------------------------------------------------------------------
// 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
#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)
// --------------------------------------------------------------------------------
// HrLoadRAS
// --------------------------------------------------------------------------------
HRESULT HrLoadRAS(void) { // Locals
HRESULT hr=S_OK; UINT uOldErrorMode;
// Thread Safety
EnterCriticalSection(&g_csRAS);
// If dll is loaded, lets verify all of my function pointers
if (g_hinstRAS) goto exit;
// Bug #20573 - Let's do a little voodoo here. On NT, it appears that they
// have a key in the registry to show which protocols are
// supported by RAS service. AKA - if this key doesn't exist,
// then RAS isn't installed. This may enable us to avoid some
// special bugs when RAS get's uninstalled on NT.
OSVERSIONINFO os; os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&os);
if (os.dwPlatformId == VER_PLATFORM_WIN32_NT) { HKEY hKey; const TCHAR c_szRegKeyRAS[] = TEXT("SOFTWARE\\Microsoft\\RAS");
if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyRAS, 0, KEY_READ, &hKey)) { hr = TrapError(IXP_E_RAS_NOT_INSTALLED); goto exit; }
RegCloseKey(hKey); }
// Try loading RAS
uOldErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX); g_hinstRAS = LoadLibraryA("RASAPI32.DLL"); SetErrorMode(uOldErrorMode);
// Failure ?
if (NULL == g_hinstRAS) { hr = TrapError(IXP_E_RAS_NOT_INSTALLED); goto exit; }
// Did we load it
g_pRasDial = (RASDIALPROC)GetProcAddress(g_hinstRAS, c_szRasDial); g_pRasEnumConnections = (RASENUMCONNECTIONSPROC)GetProcAddress(g_hinstRAS, c_szRasEnumConnections); g_pRasEnumEntries = (RASENUMENTRIESPROC)GetProcAddress(g_hinstRAS, c_szRasEnumEntries); g_pRasGetConnectStatus = (RASGETCONNECTSTATUSPROC)GetProcAddress(g_hinstRAS, c_szRasGetConnectStatus); g_pRasGetErrorString = (RASGETERRORSTRINGPROC)GetProcAddress(g_hinstRAS, c_szRasGetErrorString); g_pRasHangup = (RASHANGUPPROC)GetProcAddress(g_hinstRAS, c_szRasHangup); g_pRasSetEntryDialParams = (RASSETENTRYDIALPARAMSPROC)GetProcAddress(g_hinstRAS, c_szRasSetEntryDialParams); g_pRasGetEntryDialParams = (RASGETENTRYDIALPARAMSPROC)GetProcAddress(g_hinstRAS, c_szRasGetEntryDialParams); g_pRasCreatePhonebookEntry = (RASCREATEPHONEBOOKENTRYPROC)GetProcAddress(g_hinstRAS, c_szRasCreatePhonebookEntry); g_pRasEditPhonebookEntry = (RASEDITPHONEBOOKENTRYPROC)GetProcAddress(g_hinstRAS, c_szRasEditPhonebookEntry);
// 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) goto exit;
// Failure...
hr = TrapError(IXP_E_RAS_PROCS_NOT_FOUND);
exit: // Thread Safety
LeaveCriticalSection(&g_csRAS);
// Done
return hr; }
// --------------------------------------------------------------------------------
// CRASTransport::CRASTransport
// --------------------------------------------------------------------------------
CRASTransport::CRASTransport(void) { DllAddRef(); m_cRef = 1; m_pCallback = NULL; *m_szConnectoid = '\0'; m_hConn = NULL; m_fConnOwner = FALSE; m_hwndRAS = NULL; m_uRASMsg = 0; ZeroMemory(&m_rServer, sizeof(INETSERVER)); ZeroMemory(&m_rDialParams, sizeof(RASDIALPARAMS)); InitializeCriticalSection(&m_cs); }
// --------------------------------------------------------------------------------
// CRASTransport::~CRASTransport
// --------------------------------------------------------------------------------
CRASTransport::~CRASTransport(void) { EnterCriticalSection(&m_cs); ZeroMemory(&m_rServer, sizeof(INETSERVER)); SafeRelease(m_pCallback); *m_szConnectoid = '\0'; m_hConn = NULL; if (m_hwndRAS) DestroyWindow(m_hwndRAS); LeaveCriticalSection(&m_cs); DeleteCriticalSection(&m_cs); DllRelease(); }
// --------------------------------------------------------------------------------
// CRASTransport::QueryInterface
// --------------------------------------------------------------------------------
STDMETHODIMP CRASTransport::QueryInterface(REFIID riid, LPVOID *ppv) { // Locals
HRESULT hr=S_OK;
// Bad param
if (ppv == NULL) { hr = TrapError(E_INVALIDARG); goto exit; }
// Init
*ppv=NULL;
// IID_IUnknown
if (IID_IUnknown == riid) *ppv = ((IUnknown *)this);
// IID_IInternetTransport
else if (IID_IInternetTransport == riid) *ppv = ((IInternetTransport *)this);
// IID_IRASTransport
else if (IID_IRASTransport == riid) *ppv = (IRASTransport *)this;
// If not null, addref it and return
if (NULL != *ppv) { ((LPUNKNOWN)*ppv)->AddRef(); goto exit; }
// No Interface
hr = TrapError(E_NOINTERFACE);
exit: // Done
return hr; }
// --------------------------------------------------------------------------------
// CRASTransport::QueryInterface
// --------------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CRASTransport::AddRef(void) { return ++m_cRef; }
// --------------------------------------------------------------------------------
// CRASTransport::QueryInterface
// --------------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CRASTransport::Release(void) { if (0 != --m_cRef) return m_cRef; delete this; return 0; }
// --------------------------------------------------------------------------------
// CRASTransport::HandsOffCallback
// --------------------------------------------------------------------------------
STDMETHODIMP CRASTransport::HandsOffCallback(void) { // Locals
HRESULT hr=S_OK;
// Thread Safety
EnterCriticalSection(&m_cs);
// No current callback
if (NULL == m_pCallback) { hr = TrapError(S_FALSE); goto exit; }
// Release it
SafeRelease(m_pCallback);
exit: // Thread Safety
LeaveCriticalSection(&m_cs);
// Done
return hr; }
// --------------------------------------------------------------------------------
// CRASTransport::InitNew
// --------------------------------------------------------------------------------
STDMETHODIMP CRASTransport::InitNew(IRASCallback *pCallback) { // Locals
HRESULT hr=S_OK;
// check params
if (NULL == pCallback) return TrapError(E_INVALIDARG);
// Thread Safety
EnterCriticalSection(&m_cs);
// Release current callback
SafeRelease(m_pCallback);
// Assume new callback
m_pCallback = pCallback; m_pCallback->AddRef();
// Have I Create my modeless window for RAS connections yet?
if (NULL == m_hwndRAS) { // Create Modeless Window
m_hwndRAS = CreateDialogParam(g_hLocRes, MAKEINTRESOURCE(IDD_RASCONNECT), NULL, RASConnectDlgProc, (LPARAM)this); if (NULL == m_hwndRAS) { hr = TrapError(E_FAIL); goto exit; }
// Get registered RAS event message id
m_uRASMsg = RegisterWindowMessageA(RASDIALEVENT); if (m_uRASMsg == 0) m_uRASMsg = WM_RASDIALEVENT; }
exit: // Thread Safety
LeaveCriticalSection(&m_cs);
// Done
return hr; }
// --------------------------------------------------------------------------------
// CRASTransport::GetCurrentConnectoid
// --------------------------------------------------------------------------------
STDMETHODIMP CRASTransport::GetCurrentConnectoid(LPSTR pszConnectoid, ULONG cchMax) { // Locals
HRESULT hr=S_OK; LPRASCONN prgConnection=NULL; DWORD cConnection;
// Invalid Arg
if (NULL == pszConnectoid || cchMax < CCHMAX_CONNECTOID) return TrapError(E_INVALIDARG);
// Thread Safety
EnterCriticalSection(&m_cs);
// Get Current RAS Connection
if (FEnumerateConnections(&prgConnection, &cConnection) == 0 || 0 == cConnection) { hr = IXP_E_NOT_CONNECTED; goto exit; }
// Is there at l
StrCpyN(pszConnectoid, prgConnection[0].szEntryName, cchMax);
exit: // Cleanup
SafeMemFree(prgConnection);
// Thread Safety
LeaveCriticalSection(&m_cs);
// Done
return hr; }
// --------------------------------------------------------------------------------
// CRASTransport::Connect
// --------------------------------------------------------------------------------
STDMETHODIMP CRASTransport::Connect(LPINETSERVER pInetServer, boolean fAuthenticate, boolean fCommandLogging) { // Locals
HRESULT hr=S_OK; LPRASCONN prgConn=NULL; DWORD cConn, dwError;
// check params
if (NULL == pInetServer) return TrapError(E_INVALIDARG);
// RAS_CONNECT_RAS ?
if (RAS_CONNECT_RAS != pInetServer->rasconntype) return IXP_S_RAS_NOT_NEEDED;
// Empty Connectoid
if (FIsEmptyA(pInetServer->szConnectoid)) return TrapError(IXP_E_RAS_INVALID_CONNECTOID);
// Thread Safety
EnterCriticalSection(&m_cs);
// Initialized
if (NULL == m_pCallback) { hr = TrapError(IXP_E_NOT_INIT); goto exit; }
// LoadRAS
CHECKHR(hr = HrLoadRAS());
// Save pInetServer
CopyMemory(&m_rServer, pInetServer, sizeof(INETSERVER));
// No Current Known Connection
if (NULL == m_hConn) { // Get Current RAS Connection
if (FEnumerateConnections(&prgConn, &cConn) && cConn > 0) { m_fConnOwner = FALSE; m_hConn = prgConn[0].hrasconn; StrCpyN(m_szConnectoid, prgConn[0].szEntryName, ARRAYSIZE(m_szConnectoid)); } }
// Otherwise, verify the connection status
else { // Locals
RASCONNSTATUS rcs;
// Get Connection Status
rcs.dwSize = sizeof(RASCONNSTATUS); dwError = RasGetConnectStatus(m_hConn, &rcs); if (dwError || rcs.dwError || RASCS_Disconnected == rcs.rasconnstate) { m_fConnOwner = FALSE; m_hConn = NULL; *m_szConnectoid = '\0'; } }
// If RAS Connection present, is it equal to suggested
if (m_hConn) { // Better have a connectoid
Assert(*m_szConnectoid);
// Current connection is what I want ?
if (lstrcmpi(m_szConnectoid, m_rServer.szConnectoid) == 0) { m_pCallback->OnRasDialStatus(RASCS_Connected, 0, this); hr = IXP_S_RAS_USING_CURRENT; goto exit; }
// Otherwise, if we didn't start the RAS connection...
else if (FALSE == m_fConnOwner) { // Prompt to Close un-owner current connection...
hr = m_pCallback->OnReconnect(m_szConnectoid, m_rServer.szConnectoid, this);
// Cancel ?
if (IXP_E_USER_CANCEL == hr) goto exit;
// Use Current Connection...
else if (S_FALSE == hr) { hr = IXP_S_RAS_USING_CURRENT; goto exit; }
// Close Current ?
else { FRasHangupAndWait(DEF_HANGUP_WAIT); } }
// Otherwise, I started the connection, so close it
else if (m_fConnOwner == TRUE) { FRasHangupAndWait(DEF_HANGUP_WAIT); } }
// We probably shouldn't have a connection handle at this point
Assert(m_hConn == NULL);
// Dial the connection
CHECKHR(hr = HrStartRasDial());
// If Synchronous -- Woo - hoo were connected and we started the connection
m_fConnOwner = TRUE; StrCpyN(m_szConnectoid, m_rServer.szConnectoid, ARRAYSIZE(m_szConnectoid));
exit: // Cleanup
SafeMemFree(prgConn);
// Thread Safety
LeaveCriticalSection(&m_cs);
// Done
return hr; }
// --------------------------------------------------------------------------------
// CRASTransport::HrStartRasDial
// --------------------------------------------------------------------------------
HRESULT CRASTransport::HrStartRasDial(void) { // Locals
HRESULT hr=S_OK; BOOL fRetry=FALSE; DWORD dwError;
// Prompt for while
while(1) { // Logon first ?
hr = HrLogon(fRetry); if (FAILED(hr)) goto exit;
// If Succeeded
#ifndef WIN16
dwError = RasDial(NULL, NULL, &m_rDialParams, 0xFFFFFFFF, m_hwndRAS, &m_hConn); #else
dwError = RasDial(NULL, NULL, &m_rDialParams, 0xFFFFFFFF, (LPVOID)m_hwndRAS, &m_hConn); #endif
if (dwError == 0) break;
// Lets feed the user the error
m_pCallback->OnRasDialStatus(RASCS_Disconnected, dwError, this);
// Retry Logon
fRetry = TRUE; }
exit: // Done
return hr; }
// --------------------------------------------------------------------------------
// CRASTransport::RASConnectDlgProc
// --------------------------------------------------------------------------------
INT_PTR CALLBACK CRASTransport::RASConnectDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { // Locals
CRASTransport *pTransport=(CRASTransport *)GetWndThisPtr(hwnd); switch (uMsg) { case WM_INITDIALOG: pTransport = (CRASTransport *)lParam; Assert(pTransport); SetWndThisPtr(hwnd, pTransport); return 0;
case WM_DESTROY: SetWndThisPtr(hwnd, NULL); break;
default: if (NULL != pTransport) { // Thread Safety
EnterCriticalSection(&pTransport->m_cs);
// Our Message
if (NULL != pTransport->m_pCallback && uMsg == pTransport->m_uRASMsg) { // Handle Error
if (lParam) { // Hangup
if (pTransport->m_hConn) pTransport->FRasHangupAndWait(DEF_HANGUP_WAIT); }
// Give to callback
pTransport->m_pCallback->OnRasDialStatus((RASCONNSTATE)wParam, (DWORD) lParam, pTransport); }
// thread Safety
LeaveCriticalSection(&pTransport->m_cs); } }
// Done
return 0; }
// --------------------------------------------------------------------------------
// CRASTransport::HrLogon
// --------------------------------------------------------------------------------
HRESULT CRASTransport::HrLogon(BOOL fForcePrompt) { // Locals
HRESULT hr=S_OK; DWORD dwRasError; BOOL fSavePassword;
// Do we need to prompt for logon information first ?
ZeroMemory(&m_rDialParams, sizeof(RASDIALPARAMS)); m_rDialParams.dwSize = sizeof(RASDIALPARAMS); Assert(sizeof(m_rDialParams.szEntryName) >= sizeof(m_rServer.szConnectoid)); StrCpyN(m_rDialParams.szEntryName, m_rServer.szConnectoid, sizeof(m_rDialParams.szEntryName));
// Get params
dwRasError = RasGetEntryDialParams(NULL, &m_rDialParams, &fSavePassword); if (dwRasError) { hr = TrapError(IXP_E_RAS_GET_DIAL_PARAMS); goto exit; }
// Do we need to get password / account information
if (fForcePrompt || !fSavePassword || FIsEmpty(m_rDialParams.szUserName) || FIsEmpty(m_rDialParams.szPassword)) { // Locals
IXPRASLOGON rLogon;
// Init
ZeroMemory(&rLogon, sizeof(IXPRASLOGON));
// Fill Logon Data...
StrCpyN(rLogon.szConnectoid, m_rDialParams.szEntryName, ARRAYSIZE(rLogon.szConnectoid)); StrCpyN(rLogon.szUserName, m_rDialParams.szUserName, ARRAYSIZE(rLogon.szUserName)); StrCpyN(rLogon.szPassword, m_rDialParams.szPassword, ARRAYSIZE(rLogon.szPassword)); StrCpyN(rLogon.szDomain, m_rDialParams.szDomain, ARRAYSIZE(rLogon.szDomain)); StrCpyN(rLogon.szPhoneNumber, m_rDialParams.szPhoneNumber, ARRAYSIZE(rLogon.szPhoneNumber)); rLogon.fSavePassword = fSavePassword;
// Prompt
hr = m_pCallback->OnLogonPrompt(&rLogon, this);
// If OK, lets save the settings
if (S_OK == hr) { // Copy parameters back
StrCpyN(m_rDialParams.szUserName, rLogon.szUserName, ARRAYSIZE(m_rDialParams.szUserName)); StrCpyN(m_rDialParams.szPassword, rLogon.szPassword, ARRAYSIZE(m_rDialParams.szPassword)); StrCpyN(m_rDialParams.szDomain, rLogon.szDomain, ARRAYSIZE(m_rDialParams.szDomain)); StrCpyN(m_rDialParams.szPhoneNumber, rLogon.szPhoneNumber, ARRAYSIZE(m_rDialParams.szPhoneNumber));
// Save the dial params
if (RasSetEntryDialParams(NULL, &m_rDialParams, !rLogon.fSavePassword)) { Assert(FALSE); TrapError(E_FAIL); } }
// RAID-26845 - RAS Transport: Canceling RAS Logon doesn't cancel
else { hr = TrapError(IXP_E_USER_CANCEL); goto exit; } }
exit: // Done
return hr; }
// --------------------------------------------------------------------------------
// CRASTransport::DropConnection
// --------------------------------------------------------------------------------
STDMETHODIMP CRASTransport::DropConnection(void) { // Thread Safety
EnterCriticalSection(&m_cs);
// Hangup
if (m_hConn) FRasHangupAndWait(DEF_HANGUP_WAIT);
// Thread Safety
LeaveCriticalSection(&m_cs);
// Done
return S_OK; }
// --------------------------------------------------------------------------------
// CRASTransport::Disconnect
// --------------------------------------------------------------------------------
STDMETHODIMP CRASTransport::Disconnect(void) { // Locals
HRESULT hr=S_OK;
// Thread Safety
EnterCriticalSection(&m_cs);
// If not using RAS, who give a crap
if (RAS_CONNECT_RAS != m_rServer.rasconntype) { Assert(m_hConn == NULL); Assert(m_fConnOwner == FALSE); goto exit; }
// Do we have a RAS connection
if (m_hConn) { if (m_pCallback->OnDisconnect(m_szConnectoid, (boolean) !!m_fConnOwner, this) == S_OK) FRasHangupAndWait(DEF_HANGUP_WAIT); }
// Pretend the connection is owned by the user
m_hConn = NULL; m_fConnOwner = FALSE;
exit: // Thread Safety
LeaveCriticalSection(&m_cs);
// Done
return hr; }
// --------------------------------------------------------------------------------
// CRASTransport::IsState
// --------------------------------------------------------------------------------
STDMETHODIMP CRASTransport::IsState(IXPISSTATE isstate) { // Locals
HRESULT hr=S_FALSE;
// Thread Safety
EnterCriticalSection(&m_cs);
// Initialized
if (NULL == m_pCallback) { hr = TrapError(IXP_E_NOT_INIT); goto exit; }
// Lets validate m_hConn first
if (NULL != m_hConn) { // Get Connection Status
RASCONNSTATUS rcs; DWORD dwError;
// Setup Structure Size
rcs.dwSize = sizeof(RASCONNSTATUS);
// Get Ras Connection Status
dwError = RasGetConnectStatus(m_hConn, &rcs); // Failure or not connected
if (dwError || rcs.dwError || RASCS_Disconnected == rcs.rasconnstate) { m_fConnOwner = FALSE; m_hConn = NULL; *m_szConnectoid = '\0'; } }
// Handle IsType
switch(isstate) { // Are we connected
case IXP_IS_CONNECTED: hr = (m_hConn) ? S_OK : S_FALSE; break;
// Are we busy
case IXP_IS_BUSY: if (NULL == m_hConn) hr = IXP_E_NOT_CONNECTED; else hr = S_FALSE; break;
// Are we busy
case IXP_IS_READY: if (NULL == m_hConn) hr = IXP_E_NOT_CONNECTED; else hr = S_OK; break;
// Have we been authenticated yet
case IXP_IS_AUTHENTICATED: if (NULL == m_hConn) hr = IXP_E_NOT_CONNECTED; else hr = S_OK; break;
// Unhandled ixpistype
default: IxpAssert(FALSE); break; }
exit: // Thread Safety
LeaveCriticalSection(&m_cs);
// Done
return hr; }
// --------------------------------------------------------------------------------
// CRASTransport::GetServerInfo
// --------------------------------------------------------------------------------
STDMETHODIMP CRASTransport::GetServerInfo(LPINETSERVER pInetServer) { // check params
if (NULL == pInetServer) return TrapError(E_INVALIDARG);
// Thread Safety
EnterCriticalSection(&m_cs);
// Copy Server information
CopyMemory(pInetServer, &m_rServer, sizeof(INETSERVER));
// Thread Safety
LeaveCriticalSection(&m_cs);
// Done
return S_OK; }
// --------------------------------------------------------------------------------
// CRASTransport::GetIXPType
// --------------------------------------------------------------------------------
STDMETHODIMP_(IXPTYPE) CRASTransport::GetIXPType(void) { return IXP_RAS; }
// --------------------------------------------------------------------------------
// CRASTransport::InetServerFromAccount
// --------------------------------------------------------------------------------
STDMETHODIMP CRASTransport::InetServerFromAccount(IImnAccount *pAccount, LPINETSERVER pInetServer) { return E_NOTIMPL; }
// --------------------------------------------------------------------------------
// CRASTransport::FEnumerateConnections
// --------------------------------------------------------------------------------
BOOL CRASTransport::FEnumerateConnections(LPRASCONN *pprgConn, ULONG *pcConn) { // Locals
HRESULT hr=S_OK; DWORD dw, dwSize; BOOL fResult=FALSE;
// Check Params
Assert(pprgConn && pcConn);
// Init
*pprgConn = NULL; *pcConn = 0;
// Sizeof my buffer
dwSize = sizeof(RASCONN);
// Allocate enough for 1 ras connection info object
CHECKHR(hr = HrAlloc((LPVOID *)pprgConn, dwSize));
// Buffer size
(*pprgConn)->dwSize = dwSize;
// Enumerate ras connections
dw = RasEnumConnections(*pprgConn, &dwSize, pcConn);
// Not enough memory ?
if (dw == ERROR_BUFFER_TOO_SMALL) { // Reallocate
CHECKHR(hr = HrRealloc((LPVOID *)pprgConn, dwSize)); *pcConn = 0; (*pprgConn)->dwSize = sizeof(RASCONN); dw = RasEnumConnections(*pprgConn, &dwSize, pcConn); }
// If still failed
if (dw) { AssertSz(FALSE, "RasEnumConnections failed"); goto exit; }
// Success
fResult = TRUE;
exit: // Done
return fResult; }
// --------------------------------------------------------------------------------
// CRASTransport::FFindConnection
// --------------------------------------------------------------------------------
BOOL CRASTransport::FFindConnection(LPSTR pszConnectoid, LPHRASCONN phConn) { // Locals
ULONG cConn, i; LPRASCONN prgConn=NULL; BOOL fResult=FALSE;
// Check Params
Assert(pszConnectoid && phConn);
// Init
*phConn = NULL;
// Enumerate Connections
if (!FEnumerateConnections(&prgConn, &cConn)) goto exit;
// If still failed
for (i=0; i<cConn; i++) { if (lstrcmpi(prgConn[i].szEntryName, pszConnectoid) == 0) { *phConn = prgConn[i].hrasconn; fResult = TRUE; goto exit; } }
exit: // Cleanup
SafeMemFree(prgConn);
// Done
return fResult; }
// --------------------------------------------------------------------------------
// CRASTransport::FRasHangupAndWait
// --------------------------------------------------------------------------------
BOOL CRASTransport::FRasHangupAndWait(DWORD dwMaxWaitSeconds) { // Locals
RASCONNSTATUS rcs; DWORD dwTicks=GetTickCount();
// Check Params
Assert(m_hConn); if (NULL == m_hConn || RasHangup(m_hConn)) { m_hConn = NULL; m_fConnOwner = FALSE; *m_szConnectoid = '\0'; return FALSE; }
// Wait for connection to really close
ZeroMemory(&rcs, sizeof(RASCONNSTATUS)); rcs.dwSize = sizeof(RASCONNSTATUS); while (RasGetConnectStatus(m_hConn, &rcs) == 0 && rcs.rasconnstate != RASCS_Disconnected) { // Wait timeout
if (GetTickCount() - dwTicks >= dwMaxWaitSeconds * 1000) break;
// Sleep and yields
Sleep(0); }
// Wait 2 seconds for modem to reset
Sleep(2000);
// Reset
m_hConn = NULL; m_fConnOwner = FALSE; *m_szConnectoid = '\0';
// Done
return TRUE; }
// --------------------------------------------------------------------------------
// CRASTransport::FillConnectoidCombo
// --------------------------------------------------------------------------------
STDMETHODIMP CRASTransport::FillConnectoidCombo(HWND hwndComboBox, boolean fUpdateOnly, DWORD *pdwRASResult) { // Locals
HRESULT hr=S_OK;
// check params
if (NULL == hwndComboBox || FALSE == IsWindow(hwndComboBox)) return TrapError(E_INVALIDARG);
// Thread Safety
EnterCriticalSection(&m_cs);
// Call global function
CHECKHR(hr = HrFillRasCombo(hwndComboBox, fUpdateOnly, pdwRASResult));
exit: // Thread Safety
LeaveCriticalSection(&m_cs);
// Done
return hr; }
// --------------------------------------------------------------------------------
// CRASTransport::EditConnectoid
// --------------------------------------------------------------------------------
STDMETHODIMP CRASTransport::EditConnectoid(HWND hwndParent, LPSTR pszConnectoid, DWORD *pdwRASResult) { // Locals
HRESULT hr=S_OK;
// check params
if (NULL == pszConnectoid) return TrapError(E_INVALIDARG);
// Thread Safety
EnterCriticalSection(&m_cs);
// Call general function
CHECKHR(hr = HrEditPhonebookEntry(hwndParent, pszConnectoid, pdwRASResult));
exit: // Thread Safety
LeaveCriticalSection(&m_cs);
// Done
return hr; }
// --------------------------------------------------------------------------------
// CRASTransport::GetRasErrorString
// --------------------------------------------------------------------------------
STDMETHODIMP CRASTransport::GetRasErrorString(UINT uRasErrorValue, LPSTR pszErrorString, ULONG cchMax, DWORD *pdwRASResult) { // Locals
HRESULT hr=S_OK;
// check params
if (NULL == pdwRASResult || 0 == uRasErrorValue || NULL == pszErrorString || cchMax <= 1) return TrapError(E_INVALIDARG);
// Thread Safety
EnterCriticalSection(&m_cs);
// Make Sure RAS is Loaded
CHECKHR(hr = HrLoadRAS());
// Call RAS Function
*pdwRASResult = RasGetErrorString(uRasErrorValue, pszErrorString, cchMax); if (*pdwRASResult) { hr = TrapError(IXP_E_RAS_ERROR); goto exit; }
exit: // Thread Safety
LeaveCriticalSection(&m_cs);
// Done
return hr; }
// --------------------------------------------------------------------------------
// CRASTransport::CreateConnectoid
// --------------------------------------------------------------------------------
STDMETHODIMP CRASTransport::CreateConnectoid(HWND hwndParent, DWORD *pdwRASResult) { // Locals
HRESULT hr=S_OK;
// Thread Safety
EnterCriticalSection(&m_cs);
// Call General Function
CHECKHR(hr = HrCreatePhonebookEntry(hwndParent, pdwRASResult));
exit: // Thread Safety
LeaveCriticalSection(&m_cs);
// Done
return hr; }
|