1998-12-31 02:03:13 +03:00
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
1999-11-02 08:38:33 +03:00
* The contents of this file are subject to the Netscape Public
* License Version 1.1 ( the " License " ) ; you may not use this file
* except in compliance with the License . You may obtain a copy of
* the License at http : //www.mozilla.org/NPL/
1998-12-31 02:03:13 +03:00
*
1999-11-02 08:38:33 +03:00
* Software distributed under the License is distributed on an " AS
* IS " basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied . See the License for the specific language governing
* rights and limitations under the License .
1998-12-31 02:03:13 +03:00
*
1999-11-02 08:38:33 +03:00
* The Original Code is mozilla . org code .
*
* The Initial Developer of the Original Code is Netscape
1998-12-31 02:03:13 +03:00
* Communications Corporation . Portions created by Netscape are
1999-11-02 08:38:33 +03:00
* Copyright ( C ) 1998 Netscape Communications Corporation . All
* Rights Reserved .
*
* Contributor ( s ) :
1998-12-31 02:03:13 +03:00
*/
//#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
# include <afxwin.h> // MFC core and standard components
# include <afxext.h> // MFC extensions
# include <windows.h>
# include <string.h>
# include <stdio.h>
# include <time.h>
# include <dos.h>
# include <winbase.h>
# include <raserror.h>
# include <shlobj.h>
# include <regstr.h>
# include <tapi.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <winsock.h>
# include "dialshr.h"
# include "resource.h"
# include "xp_mem.h"
# include "prefapi.h"
# define trace
# define MAX_ENTRIES 20
// Navigator quit message (see QuitNavigator)
# define ID_APP_SUPER_EXIT 34593
// The number of times we try to dial
# define NUM_ATTEMPTS 3
# define IDDISCONNECTED 31
enum CallState
{
StateIdle ,
StateConnecting ,
StateConnected ,
StateDisconnecting
} ;
CallState gCallState = StateIdle ;
UINT gDialAttempts = 0 ; // keeps the total number of dialing count
HRASCONN gRasConn ; // handle to the current ras connection
RASCONNSTATE gRASstate ; // current connection's ras state
RASDIALPARAMS gDialParams ; // keeps the current connection info
HWND gHwndStatus = NULL ; // handle to our connection status window
BOOL gCancelled = FALSE ; // assume connection will be there unless user cancels
BOOL gLineDrop = FALSE ;
BOOL gDeviceErr = FALSE ; // assume no hardware err
HWND gHwndNavigator = NULL ;
HANDLE gRasMon = NULL ; // process handle to RasMon on WinNT
HINSTANCE m_hRasInst = NULL ;
// NT/95 entrypoints
RASDIAL m_lpfnRasDial ;
RASHANGUP m_lpfnRasHangUp ;
RASGETERRORSTRING m_lpfnRasGetErrorString ;
RASSETENTRYPROPERTIES m_lpfnRasSetEntryProperties ;
RASSETENTRYDIALPARAMS m_lpfnRasSetEntryDialParams ;
RASGETCOUNTRYINFO m_lpfnRasGetCountryInfo ;
RASENUMCONNECTIONS m_lpfnRasEnumConnections ;
RASENUMENTRIES m_lpfnRasEnumEntries ;
RASENUMDEVICES m_lpfnRasEnumDevices ;
RASGETENTRYPROPERTIES m_lpfnRasGetEntryProperties ;
RASVALIDATEENTRYNAME m_lpfnRasValidateEntryName ;
RASDELETEENTRY m_lpfnRasDeleteEntry ;
// NT entrypoints
RASSETAUTODIALENABLE m_lpfnRasSetAutodialEnable ;
RASSETAUTODIALADDRESS m_lpfnRasSetAutodialAddress ;
RASGETAUTODIALADDRESS m_lpfnRasGetAutodialAddress ;
RASSETAUTODIALPARAM m_lpfnRasSetAutodialParam ;
RASENUMAUTODIALADDRESSES m_lpfnRasEnumAutodialAddresses ;
RASSETCREDENTIALS m_lpfnRasSetCredentials ;
size_t stRASENTRY ;
size_t stRASCONN ;
size_t stRASCTRYINFO ;
size_t stRASDIALPARAMS ;
size_t stRASDEVINFO ;
size_t stRASENTRYNAME ;
//********************************************************************************
// LoadRasFunctions()
//********************************************************************************
BOOL LoadRasFunctions ( LPCSTR lpszLibrary )
{
// ASSERT(!m_hRasInst);
m_hRasInst = : : LoadLibrary ( lpszLibrary ) ;
if ( ( UINT ) m_hRasInst > 32 )
{
m_lpfnRasSetEntryProperties = ( RASSETENTRYPROPERTIES ) : : GetProcAddress ( m_hRasInst , " RasSetEntryProperties " ) ;
m_lpfnRasGetCountryInfo = ( RASGETCOUNTRYINFO ) : : GetProcAddress ( m_hRasInst , " RasGetCountryInfo " ) ;
m_lpfnRasEnumDevices = ( RASENUMDEVICES ) : : GetProcAddress ( m_hRasInst , " RasEnumDevices " ) ;
m_lpfnRasGetEntryProperties = ( RASGETENTRYPROPERTIES ) : : GetProcAddress ( m_hRasInst , " RasGetEntryProperties " ) ;
m_lpfnRasValidateEntryName = ( RASVALIDATEENTRYNAME ) : : GetProcAddress ( m_hRasInst , " RasValidateEntryName " ) ;
m_lpfnRasDeleteEntry = ( RASDELETEENTRY ) : : GetProcAddress ( m_hRasInst , " RasDeleteEntry " ) ;
m_lpfnRasHangUp = ( RASHANGUP ) : : GetProcAddress ( m_hRasInst , " RasHangUpA " ) ;
m_lpfnRasDial = ( RASDIAL ) : : GetProcAddress ( m_hRasInst , " RasDialA " ) ;
m_lpfnRasEnumConnections = ( RASENUMCONNECTIONS ) : : GetProcAddress ( m_hRasInst , " RasEnumConnectionsA " ) ;
m_lpfnRasSetEntryDialParams = ( RASSETENTRYDIALPARAMS ) : : GetProcAddress ( m_hRasInst , " RasSetEntryDialParamsA " ) ;
m_lpfnRasEnumEntries = ( RASENUMENTRIES ) : : GetProcAddress ( m_hRasInst , " RasEnumEntriesA " ) ;
SizeofRAS95 ( ) ;
return TRUE ;
}
else
{
MessageBox ( NULL , " Please install Dial-up Networking " , " Netscape " , MB_ICONSTOP ) ;
: : FreeLibrary ( m_hRasInst ) ;
m_hRasInst = NULL ;
return FALSE ;
}
}
//********************************************************************************
// LoadRasFunctionsNT()
//********************************************************************************
BOOL LoadRasFunctionsNT ( LPCSTR lpszLibrary )
{
m_hRasInst = : : LoadLibrary ( lpszLibrary ) ;
if ( ( UINT ) m_hRasInst > 32 )
{
m_lpfnRasSetEntryProperties = ( RASSETENTRYPROPERTIES ) : : GetProcAddress ( m_hRasInst , " RasSetEntryPropertiesA " ) ;
m_lpfnRasGetCountryInfo = ( RASGETCOUNTRYINFO ) : : GetProcAddress ( m_hRasInst , " RasGetCountryInfoA " ) ;
m_lpfnRasEnumDevices = ( RASENUMDEVICES ) : : GetProcAddress ( m_hRasInst , " RasEnumDevicesA " ) ;
m_lpfnRasGetEntryProperties = ( RASGETENTRYPROPERTIES ) : : GetProcAddress ( m_hRasInst , " RasGetEntryPropertiesA " ) ;
m_lpfnRasValidateEntryName = ( RASVALIDATEENTRYNAME ) : : GetProcAddress ( m_hRasInst , " RasValidateEntryNameA " ) ;
m_lpfnRasDeleteEntry = ( RASDELETEENTRY ) : : GetProcAddress ( m_hRasInst , " RasDeleteEntryA " ) ;
m_lpfnRasEnumEntries = ( RASENUMENTRIES ) : : GetProcAddress ( m_hRasInst , " RasEnumEntriesA " ) ;
m_lpfnRasHangUp = ( RASHANGUP ) : : GetProcAddress ( m_hRasInst , " RasHangUpA " ) ;
m_lpfnRasDial = ( RASDIAL ) : : GetProcAddress ( m_hRasInst , " RasDialA " ) ;
m_lpfnRasEnumConnections = ( RASENUMCONNECTIONS ) : : GetProcAddress ( m_hRasInst , " RasEnumConnectionsA " ) ;
m_lpfnRasSetEntryDialParams = ( RASSETENTRYDIALPARAMS ) : : GetProcAddress ( m_hRasInst , " RasSetEntryDialParamsA " ) ;
// AUTODIAL
m_lpfnRasSetAutodialEnable = ( RASSETAUTODIALENABLE ) : : GetProcAddress ( m_hRasInst , " RasSetAutodialEnableA " ) ;
m_lpfnRasSetAutodialAddress = ( RASSETAUTODIALADDRESS ) : : GetProcAddress ( m_hRasInst , " RasSetAutodialAddressA " ) ;
m_lpfnRasGetAutodialAddress = ( RASGETAUTODIALADDRESS ) : : GetProcAddress ( m_hRasInst , " RasGetAutodialAddressA " ) ;
m_lpfnRasSetAutodialParam = ( RASSETAUTODIALPARAM ) : : GetProcAddress ( m_hRasInst , " RasSetAutodialParamA " ) ;
m_lpfnRasSetCredentials = ( RASSETCREDENTIALS ) : : GetProcAddress ( m_hRasInst , " RasSetCredentialsA " ) ;
m_lpfnRasEnumAutodialAddresses = ( RASENUMAUTODIALADDRESSES ) : : GetProcAddress ( m_hRasInst , " RasEnumAutodialAddressesA " ) ;
SizeofRASNT40 ( ) ;
return TRUE ;
}
else
{
MessageBox ( NULL , " Please install Dial-up Networking " , " Netscape " , MB_ICONSTOP ) ;
: : FreeLibrary ( m_hRasInst ) ;
m_hRasInst = NULL ;
return FALSE ;
}
}
//********************************************************************************
// FreeRasFunctions()
//********************************************************************************
void FreeRasFunctions ( )
{
if ( ( UINT ) m_hRasInst > 32 )
FreeLibrary ( m_hRasInst ) ;
}
//********************************************************************************
// GetModemList (s/b GetModems)
// Returns list of modems available for use ('installed' by the user). For Win95
// this list come from the OS, and each entry contains 2 strings - the first is
// the Modem Name, and the second is the device type (both are needed to select
// the device to use to make a Dial-up connection).
//********************************************************************************
BOOL GetModemList ( char * * * resultModemList , int * numDevices )
{
DWORD dwBytes = 0 , dwDevices ;
LPRASDEVINFO lpRnaDevInfo ;
// First find out how much memory to allocate
( * m_lpfnRasEnumDevices ) ( NULL , & dwBytes , & dwDevices ) ;
lpRnaDevInfo = ( LPRASDEVINFO ) malloc ( dwBytes ) ;
if ( ! lpRnaDevInfo )
return ( FALSE ) ;
lpRnaDevInfo - > dwSize = stRASDEVINFO ;
( * m_lpfnRasEnumDevices ) ( lpRnaDevInfo , & dwBytes , & dwDevices ) ;
// copy all entries to the char array
* resultModemList = new char * [ dwDevices + 1 ] ;
if ( * resultModemList = = NULL )
return FALSE ;
* numDevices = dwDevices ;
for ( unsigned short i = 0 ; i < dwDevices ; i + + )
{
( * resultModemList ) [ i ] = new char [ strlen ( lpRnaDevInfo [ i ] . szDeviceName ) + 1 ] ;
if ( ( * resultModemList ) [ i ] = = NULL )
return FALSE ;
strcpy ( ( * resultModemList ) [ i ] , lpRnaDevInfo [ i ] . szDeviceName ) ;
}
return TRUE ;
}
//********************************************************************************
// GetModemType
// Returns the type for the selected modem.
//********************************************************************************
BOOL GetModemType ( char * strModemName , char * strModemType )
{
DWORD dwBytes = 0 , dwDevices ;
LPRASDEVINFO lpRnaDevInfo ;
// First get Modem (okay - Device) info from Win95
// find out how much memory to allocate
( * m_lpfnRasEnumDevices ) ( NULL , & dwBytes , & dwDevices ) ;
lpRnaDevInfo = ( LPRASDEVINFO ) malloc ( dwBytes ) ;
if ( ! lpRnaDevInfo )
return NULL ;
lpRnaDevInfo - > dwSize = stRASDEVINFO ;
( * m_lpfnRasEnumDevices ) ( lpRnaDevInfo , & dwBytes , & dwDevices ) ;
// If match the modem given from JS then return the associated Type
for ( unsigned short i = 0 ; i < dwDevices ; i + + )
{
if ( 0 = = strcmp ( strModemName , lpRnaDevInfo [ i ] . szDeviceName ) )
{
strModemType = new char [ strlen ( lpRnaDevInfo [ i ] . szDeviceType ) + 1 ] ;
strcpy ( strModemType , lpRnaDevInfo [ i ] . szDeviceType ) ;
return TRUE ;
}
}
return FALSE ;
}
//********************************************************************************
// EnableDialOnDemand (win95)
// Set the magic keys in the registry to enable dial on demand
//********************************************************************************
void EnableDialOnDemand95 ( LPSTR lpProfileName , BOOL flag )
{
HKEY hKey ;
DWORD dwDisposition ;
long result ;
char * szData ;
// We need to tell windows about dialing on demand
result = RegCreateKeyEx ( HKEY_LOCAL_MACHINE , " System \\ CurrentControlSet \\ Services \\ Winsock \\ Autodial " ,
NULL , NULL , NULL , KEY_ALL_ACCESS , NULL , & hKey , & dwDisposition ) ;
// err, oops
if ( result ! = ERROR_SUCCESS )
return ;
szData = " url.dll " ;
result = RegSetValueEx ( hKey , " AutodialDllName32 " , NULL , REG_SZ , ( LPBYTE ) szData , strlen ( szData ) ) ;
szData = " AutodialHookCallback " ;
result = RegSetValueEx ( hKey , " AutodialFcnName32 " , NULL , REG_SZ , ( LPBYTE ) szData , strlen ( szData ) ) ;
RegCloseKey ( hKey ) ;
// set the autodial flag first
result = RegCreateKeyEx ( HKEY_CURRENT_USER , " Software \\ Microsoft \\ Windows \\ CurrentVersion \\ Internet Settings " ,
NULL , NULL , NULL , KEY_ALL_ACCESS , NULL , & hKey , & dwDisposition ) ;
// err, oops
if ( result ! = ERROR_SUCCESS )
return ;
// set the autodial and idle-time disconnect
DWORD dwValue = flag ;
result = RegSetValueEx ( hKey , " EnableAutodial " , NULL , REG_DWORD , ( LPBYTE ) & dwValue , sizeof ( DWORD ) ) ;
// try setting autodisconnect here
dwValue = 1 ;
result = RegSetValueEx ( hKey , " EnableAutoDisconnect " , NULL , REG_DWORD , ( LPBYTE ) & dwValue , sizeof ( DWORD ) ) ;
// default auto-disconnect after 5 minutes
dwValue = 5 ;
result = RegSetValueEx ( hKey , " DisconnectIdleTime " , NULL , REG_DWORD , ( LPBYTE ) & dwValue , sizeof ( DWORD ) ) ;
RegCloseKey ( hKey ) ;
// set the autodisconnect flags here too
result = RegCreateKeyEx ( HKEY_CURRENT_USER , " Software \\ Microsoft \\ Windows \\ Internet Settings " ,
NULL , NULL , NULL , KEY_ALL_ACCESS , NULL , & hKey , & dwDisposition ) ;
// err, oops
if ( result ! = ERROR_SUCCESS )
return ;
dwValue = 1 ;
result = RegSetValueEx ( hKey , " EnableAutoDisconnect " , NULL , REG_DWORD , ( LPBYTE ) & dwValue , sizeof ( DWORD ) ) ;
// default auto-disconnect after 5 minutes
dwValue = 5 ;
result = RegSetValueEx ( hKey , " DisconnectIdleTime " , NULL , REG_DWORD , ( LPBYTE ) & dwValue , sizeof ( DWORD ) ) ;
RegCloseKey ( hKey ) ;
// OK, let's tell it which profile to autodial
result = RegCreateKeyEx ( HKEY_CURRENT_USER , " RemoteAccess " , NULL , NULL , NULL ,
KEY_ALL_ACCESS , NULL , & hKey , & dwDisposition ) ;
// err, oops
if ( result ! = ERROR_SUCCESS )
return ;
if ( flag ) // enable dod
{
result = RegSetValueEx ( hKey , " InternetProfile " , NULL , REG_SZ , ( LPBYTE ) lpProfileName , strlen ( lpProfileName ) ) ;
result = RegSetValueEx ( hKey , " Default " , NULL , REG_SZ , ( LPBYTE ) lpProfileName , strlen ( lpProfileName ) ) ;
}
else // disable dod
{
result = RegSetValueEx ( hKey , " InternetProfile " , NULL , REG_SZ , NULL , strlen ( lpProfileName ) ) ;
result = RegSetValueEx ( hKey , " Default " , NULL , REG_SZ , NULL , strlen ( lpProfileName ) ) ;
}
RegCloseKey ( hKey ) ;
}
//********************************************************************************
//
// lineCallbackFuncNT (winNT40)
//
// Sets the RAS structure for Dial on Demand, NT40 doesn't use registry like win95
//********************************************************************************
void FAR PASCAL
lineCallbackFuncNT ( DWORD /* hDevice */ , DWORD /* dwMsg */ , DWORD /* dwCallbackInstance */ ,
DWORD /* dwParam1 */ , DWORD /* dwParam2 */ , DWORD /* dwParam3 */ )
{
}
void EnableDialOnDemandNT ( LPSTR lpProfileName , BOOL flag )
{
RASAUTODIALENTRY rasAutodialEntry ;
DWORD dwBytes = 0 ;
DWORD dwNumDevs ;
HLINEAPP lineApp ;
DWORD dwApiVersion ;
LINEINITIALIZEEXPARAMS lineInitExParams ;
LINETRANSLATECAPS lineTranslateCaps ;
int rtn ;
// Initialize TAPI. We need to do this in order to get the dialable
// number and to bring up the location dialog
dwApiVersion = 0x00020000 ;
lineInitExParams . dwOptions = LINEINITIALIZEEXOPTION_USEEVENT ;
lineInitExParams . dwTotalSize = sizeof ( LINEINITIALIZEEXPARAMS ) ;
lineInitExParams . dwNeededSize = sizeof ( LINEINITIALIZEEXPARAMS ) ;
rtn = lineInitializeEx ( & lineApp , gDLL , lineCallbackFuncNT ,
NULL , & dwNumDevs , & dwApiVersion , & lineInitExParams ) ;
if ( rtn = = 0 )
{
lineTranslateCaps . dwTotalSize = sizeof ( LINETRANSLATECAPS ) ;
lineTranslateCaps . dwNeededSize = sizeof ( LINETRANSLATECAPS ) ;
rtn = lineGetTranslateCaps ( lineApp , dwApiVersion , & lineTranslateCaps ) ;
}
rasAutodialEntry . dwFlags = 0 ;
rasAutodialEntry . dwDialingLocation = lineTranslateCaps . dwCurrentLocationID ;
strcpy ( rasAutodialEntry . szEntry , lpProfileName ) ;
rasAutodialEntry . dwSize = sizeof ( RASAUTODIALENTRY ) ;
// set auto dial params
int val = flag ;
rtn = ( * m_lpfnRasSetAutodialParam ) ( RASADP_DisableConnectionQuery , & val , sizeof ( int ) ) ;
if ( rtn = = ERROR_INVALID_PARAMETER )
{
trace ( " dialer.cpp : EnableDialOnDemandNT - Invalid Parameter. Can't set Autodial Parameters. (r) " ) ;
return ;
}
else if ( rtn = = ERROR_INVALID_SIZE )
{
trace ( " dialer.cpp : EnableDialOnDemandNT - Invalid size. Can't set Autodial Parameters. (r) " ) ;
return ;
}
else if ( rtn )
{
trace ( " dialer.cpp : EnableDialOnDemandNT - Can't set Autodial Parameters. Error %d. (r) " , rtn ) ;
return ;
}
if ( flag ) // set dod entry if the flag is enabled
{
rtn = ( * m_lpfnRasSetAutodialAddress ) ( " www.netscape.com " , 0 , & rasAutodialEntry , sizeof ( RASAUTODIALENTRY ) , 1 ) ;
if ( rtn = = ERROR_INVALID_PARAMETER )
{
trace ( " dialer.cpp : EnableDialOnDemandNT - Invalid Parameter. Can't set Autodial Address. (r) " ) ;
return ;
}
else if ( rtn = = ERROR_INVALID_SIZE )
{
trace ( " dialer.cpp : EnableDialOnDemandNT - Invalid size. Can't set Autodial Address. (r) " ) ;
return ;
}
else if ( rtn )
{
trace ( " dialer.cpp : EnableDialOnDemandNT - Can't set Autodial Address. Error %d. (r) " , rtn ) ;
return ;
}
}
rtn = ( * m_lpfnRasSetAutodialEnable ) ( rasAutodialEntry . dwDialingLocation , flag ) ;
if ( rtn )
{
trace ( " dialer.cpp : EnableDialOnDemandNT - Can't set Autodial Enable. Error %d. (r) " , rtn ) ;
return ;
}
return ;
}
//********************************************************************************
// utility function
// sameStrings
// checks for string equality between a STRRET and a LPCTSTR
//********************************************************************************
static BOOL sameStrings ( LPITEMIDLIST pidl , STRRET & lpStr1 , LPCTSTR lpStr2 )
{
char buf [ MAX_PATH ] ;
char * mystr ;
int cch ;
switch ( lpStr1 . uType )
{
case STRRET_WSTR :
cch = WideCharToMultiByte ( CP_ACP , WC_SEPCHARS | WC_COMPOSITECHECK ,
lpStr1 . pOleStr , - 1 , buf , MAX_PATH , NULL , NULL ) ;
cch = GetLastError ( ) ;
return strcmp ( lpStr2 , buf ) = = 0 ;
case STRRET_OFFSET :
mystr = ( ( char * ) pidl ) + lpStr1 . uOffset ;
return strcmp ( lpStr2 , ( ( char * ) pidl ) + lpStr1 . uOffset ) = = 0 ;
case STRRET_CSTR :
mystr = lpStr1 . cStr ;
return strcmp ( lpStr2 , lpStr1 . cStr ) = = 0 ;
}
return FALSE ;
}
//********************************************************************************
// utility function
// procStrings
//********************************************************************************
static BOOL procStrings ( LPITEMIDLIST pidl , STRRET & lpStr1 , char * lpStr2 )
{
char * mystr ;
int cch ;
switch ( lpStr1 . uType )
{
case STRRET_WSTR :
cch = WideCharToMultiByte ( CP_ACP , WC_SEPCHARS | WC_COMPOSITECHECK ,
lpStr1 . pOleStr , - 1 , lpStr2 , MAX_PATH , NULL , NULL ) ;
return TRUE ;
case STRRET_OFFSET :
mystr = ( ( char * ) pidl ) + lpStr1 . uOffset ;
strcpy ( lpStr2 , ( ( char * ) pidl ) + lpStr1 . uOffset ) ;
return TRUE ;
case STRRET_CSTR :
mystr = lpStr1 . cStr ;
strcpy ( lpStr2 , lpStr1 . cStr ) ;
return TRUE ;
}
return FALSE ;
}
//********************************************************************************
// utility function
// next
//********************************************************************************
static LPITEMIDLIST next ( LPCITEMIDLIST pidl )
{
LPSTR lpMem = ( LPSTR ) pidl ;
lpMem + = pidl - > mkid . cb ;
return ( LPITEMIDLIST ) lpMem ;
}
//********************************************************************************
// utility function
// getSize
//********************************************************************************
static UINT getSize ( LPCITEMIDLIST pidl )
{
UINT cbTotal = 0 ;
if ( pidl )
{
cbTotal + = sizeof ( pidl - > mkid . cb ) ;
while ( pidl - > mkid . cb )
{
cbTotal + = pidl - > mkid . cb ;
pidl = next ( pidl ) ;
}
}
return cbTotal ;
}
//********************************************************************************
// utility function
// create
//********************************************************************************
static LPITEMIDLIST create ( UINT cbSize )
{
IMalloc * pMalloc ;
LPITEMIDLIST pidl = 0 ;
if ( FAILED ( SHGetMalloc ( & pMalloc ) ) )
return 0 ;
pidl = ( LPITEMIDLIST ) pMalloc - > Alloc ( cbSize ) ;
if ( pidl )
memset ( pidl , 0 , cbSize ) ;
pMalloc - > Release ( ) ;
return pidl ;
}
//********************************************************************************
// utility function
// ConcatPidls
//********************************************************************************
static LPITEMIDLIST concatPidls ( LPCITEMIDLIST pidl1 , LPCITEMIDLIST pidl2 )
{
UINT cb1 = getSize ( pidl1 ) - sizeof ( pidl1 - > mkid . cb ) ;
UINT cb2 = getSize ( pidl2 ) ;
LPITEMIDLIST pidlNew = create ( cb1 + cb2 ) ;
if ( pidlNew )
{
memcpy ( pidlNew , pidl1 , cb1 ) ;
memcpy ( ( ( LPSTR ) pidlNew ) + cb1 , pidl2 , cb2 ) ;
}
return pidlNew ;
}
//********************************************************************************
// GetMyComputerFolder
// This routine returns the ISHellFolder for the virtual My Computer folder,
// and also returns the PIDL.
//********************************************************************************
HRESULT GetMyComputerFolder ( LPSHELLFOLDER * ppshf , LPITEMIDLIST * ppidl )
{
IMalloc * pMalloc ;
HRESULT hres ;
hres = SHGetMalloc ( & pMalloc ) ;
if ( FAILED ( hres ) )
return hres ;
// Get the PIDL for "My Computer"
hres = SHGetSpecialFolderLocation ( /*pWndOwner->m_hWnd*/ NULL , CSIDL_DRIVES , ppidl ) ;
if ( SUCCEEDED ( hres ) )
{
IShellFolder * pshf ;
hres = SHGetDesktopFolder ( & pshf ) ;
if ( SUCCEEDED ( hres ) )
{
// Get the shell folder for "My Computer"
hres = pshf - > BindToObject ( * ppidl , NULL , IID_IShellFolder , ( LPVOID * ) ppshf ) ;
pshf - > Release ( ) ;
}
}
pMalloc - > Release ( ) ;
return hres ;
}
//********************************************************************************
// GetDialupNetworkingFolder
// This routine returns the ISHellFolder for the virtual Dial-up Networking
// folder, and also returns the PIDL.
//********************************************************************************
static HRESULT getDialUpNetworkingFolder ( LPSHELLFOLDER * ppshf , LPITEMIDLIST * ppidl )
{
HRESULT hres ;
IMalloc * pMalloc = NULL ;
IShellFolder * pmcf = NULL ;
LPITEMIDLIST pidlmc ;
char szDialupName [ 256 ] ;
HKEY hKey ;
DWORD cbData ;
// Poke around in the registry to find out what the Dial-Up Networking
// folder is called on this machine
szDialupName [ 0 ] = ' \0 ' ;
if ( ERROR_SUCCESS = = RegOpenKeyEx ( HKEY_CLASSES_ROOT ,
" CLSID \\ {992CFFA0-F557-101A-88EC-00DD010CCC48} " ,
NULL ,
KEY_QUERY_VALUE ,
& hKey ) )
{
cbData = sizeof ( szDialupName ) ;
RegQueryValueEx ( hKey , " " , NULL , NULL , ( LPBYTE ) szDialupName , & cbData ) ;
}
// if we didn't get anything just use the default
if ( szDialupName [ 0 ] = = ' \0 ' )
{
char * strText ;
strText = " Dial-Up Networking " ;
//CString strText;
//strText.LoadString(IDS_DIAL_UP_NW);
strcpy ( szDialupName , ( LPCSTR ) strText ) ;
}
RegCloseKey ( hKey ) ;
// OK, now look for that folder
hres = SHGetMalloc ( & pMalloc ) ;
if ( FAILED ( hres ) )
return hres ;
// Get the virtual folder for My Computer
hres = GetMyComputerFolder ( & pmcf , & pidlmc ) ;
if ( SUCCEEDED ( hres ) )
{
IEnumIDList * pEnumIDList ;
// Now we need to find the "Dial-Up Networking" folder
hres = pmcf - > EnumObjects ( NULL , SHCONTF_FOLDERS | SHCONTF_NONFOLDERS , & pEnumIDList ) ;
if ( SUCCEEDED ( hres ) )
{
LPITEMIDLIST pidl ;
int flag = 1 ;
STRRET name ;
while ( ( NOERROR = = ( hres = pEnumIDList - > Next ( 1 , & pidl , NULL ) ) ) & & ( flag ) )
{
memset ( & name , 0 , sizeof ( STRRET ) ) ;
name . uType = STRRET_CSTR ; // preferred choice
hres = pmcf - > GetDisplayNameOf ( pidl , SHGDN_INFOLDER , & name ) ;
if ( FAILED ( hres ) )
{
pMalloc - > Free ( pidl ) ;
flag = 0 ;
//break;
}
if ( sameStrings ( pidl , name , szDialupName ) )
{
* ppidl = concatPidls ( pidlmc , pidl ) ;
hres = pmcf - > BindToObject ( pidl , NULL , IID_IShellFolder , ( LPVOID * ) ppshf ) ;
int rtn = GetLastError ( ) ;
pMalloc - > Free ( pidl ) ;
flag = 0 ;
//break;
}
if ( flag )
pMalloc - > Free ( pidl ) ;
}
pEnumIDList - > Release ( ) ;
}
pmcf - > Release ( ) ;
pMalloc - > Free ( pidlmc ) ;
}
pMalloc - > Release ( ) ;
return hres ;
}
//********************************************************************************
// GetDialUpConnection
//********************************************************************************
BOOL GetDialUpConnection95 ( CONNECTIONPARAMS * * connectionNames , int * numNames )
{
HRESULT hres ;
IMalloc * pMalloc = NULL ;
IShellFolder * pshf = NULL ;
LPITEMIDLIST pidldun ;
LPITEMIDLIST pidl ;
STRRET name ;
char temp [ MAX_PATH ] ;
int flag = 1 ;
int i = 0 ;
// Initialize out parameter
hres = SHGetMalloc ( & pMalloc ) ;
if ( FAILED ( hres ) )
return FALSE ;
// First get the Dial-Up Networking virtual folder
hres = getDialUpNetworkingFolder ( & pshf , & pidldun ) ;
if ( SUCCEEDED ( hres ) & & ( pshf ! = NULL ) )
{
IEnumIDList * pEnumIDList ;
// Enumerate the files looking for the desired connection
hres = pshf - > EnumObjects ( NULL , SHCONTF_FOLDERS | SHCONTF_NONFOLDERS , & pEnumIDList ) ;
if ( SUCCEEDED ( hres ) )
{
* numNames = 0 ;
while ( NOERROR = = ( hres = pEnumIDList - > Next ( 1 , & pidl , NULL ) ) )
( * numNames ) + + ;
pEnumIDList - > Reset ( ) ;
* connectionNames = new CONNECTIONPARAMS [ * numNames ] ;
if ( * connectionNames = = NULL )
return FALSE ;
while ( ( NOERROR = = ( hres = pEnumIDList - > Next ( 1 , & pidl , NULL ) ) ) & & ( flag ) )
{
name . uType = STRRET_CSTR ; // preferred choice
hres = pshf - > GetDisplayNameOf ( pidl , SHGDN_INFOLDER , & name ) ;
if ( FAILED ( hres ) )
{
pMalloc - > Free ( pidl ) ;
flag = 0 ;
//break;
}
procStrings ( pidl , name , temp ) ;
if ( strcmp ( temp , " Make New Connection " ) ! = 0 )
{
strcpy ( ( * connectionNames ) [ i ] . szEntryName , temp ) ;
( * connectionNames ) [ i ] . pidl = concatPidls ( pidldun , pidl ) ;
i + + ;
}
if ( flag )
pMalloc - > Free ( pidl ) ;
}
pEnumIDList - > Release ( ) ;
}
pshf - > Release ( ) ;
pMalloc - > Free ( pidldun ) ;
}
pMalloc - > Release ( ) ;
* numNames = i ;
return TRUE ;
}
//********************************************************************************
// GetDialUpConnection
//********************************************************************************
BOOL GetDialUpConnectionNT ( CONNECTIONPARAMS * * connectionNames , int * numNames )
{
RASENTRYNAME * rasEntryName ;
DWORD cb ;
DWORD cEntries ;
int i ;
char * szPhoneBook ;
szPhoneBook = NULL ;
rasEntryName = new RASENTRYNAME [ MAX_ENTRIES ] ;
if ( rasEntryName = = NULL )
return FALSE ;
memset ( rasEntryName , 0 , MAX_ENTRIES ) ;
rasEntryName [ 0 ] . dwSize = sizeof ( RASENTRYNAME ) ;
cb = sizeof ( RASENTRYNAME ) * MAX_ENTRIES ;
int rtn = ( * m_lpfnRasEnumEntries ) ( NULL , szPhoneBook , rasEntryName , & cb , & cEntries ) ;
if ( rtn ! = 0 )
return FALSE ;
* numNames = cEntries ;
* connectionNames = new CONNECTIONPARAMS [ * numNames + 1 ] ;
for ( i = 0 ; i < * numNames ; i + + )
strcpy ( ( * connectionNames ) [ i ] . szEntryName , rasEntryName [ i ] . szEntryName ) ;
delete [ ] rasEntryName ;
return TRUE ;
}
//********************************************************************************
// getDialupConnectionPIDL
//********************************************************************************
static HRESULT getDialUpConnectionPIDL ( LPCTSTR lpConnectionName , LPITEMIDLIST * ppidl )
{
HRESULT hres ;
IMalloc * pMalloc = NULL ;
IShellFolder * pshf = NULL ;
LPITEMIDLIST pidldun ;
// Initialize out parameter
* ppidl = NULL ;
hres = SHGetMalloc ( & pMalloc ) ;
if ( FAILED ( hres ) )
return hres ;
// First get the Dial-Up Networking virtual folder
hres = getDialUpNetworkingFolder ( & pshf , & pidldun ) ;
if ( SUCCEEDED ( hres ) & & ( pshf ! = NULL ) )
{
IEnumIDList * pEnumIDList ;
// Enumerate the files looking for the desired connection
hres = pshf - > EnumObjects ( /*pWndOwner->m_hWnd*/ NULL , SHCONTF_FOLDERS | SHCONTF_NONFOLDERS , & pEnumIDList ) ;
if ( SUCCEEDED ( hres ) )
{
LPITEMIDLIST pidl ;
int flag = 1 ;
while ( ( NOERROR = = ( hres = pEnumIDList - > Next ( 1 , & pidl , NULL ) ) ) & & flag )
{
STRRET name ;
name . uType = STRRET_CSTR ; // preferred choice
hres = pshf - > GetDisplayNameOf ( pidl , SHGDN_INFOLDER , & name ) ;
if ( FAILED ( hres ) )
{
pMalloc - > Free ( pidl ) ;
flag = 0 ;
//break;
}
if ( sameStrings ( pidl , name , lpConnectionName ) )
{
* ppidl = concatPidls ( pidldun , pidl ) ;
pMalloc - > Free ( pidl ) ;
flag = 0 ;
//break;
}
if ( flag )
pMalloc - > Free ( pidl ) ;
}
pEnumIDList - > Release ( ) ;
}
pshf - > Release ( ) ;
pMalloc - > Free ( pidldun ) ;
}
pMalloc - > Release ( ) ;
return hres ;
}
//********************************************************************************
// getNetscapePIDL
//********************************************************************************
static void getNetscapePidl ( LPITEMIDLIST * ppidl )
{
char szPath [ MAX_PATH ] , * p ;
OLECHAR olePath [ MAX_PATH ] ;
IShellFolder * pshf ;
GetModuleFileName ( gDLL , szPath , sizeof ( szPath ) ) ;
//GetModuleFileName(AfxGetInstanceHandle(), szPath, sizeof(szPath));
//we need to take off \plugins\npasw.dll from the path
p = strrchr ( szPath , ' \\ ' ) ;
if ( p )
* p = ' \0 ' ;
p = strrchr ( szPath , ' \\ ' ) ;
if ( p )
* p = ' \0 ' ;
strcat ( szPath , " \\ netscape.exe " ) ;
HRESULT hres = SHGetDesktopFolder ( & pshf ) ;
if ( SUCCEEDED ( hres ) )
{
MultiByteToWideChar ( CP_ACP , MB_PRECOMPOSED , ( LPCSTR ) szPath , - 1 , ( LPWSTR ) olePath , sizeof ( olePath ) ) ;
ULONG lEaten ;
pshf - > ParseDisplayName ( NULL , NULL , ( LPOLESTR ) olePath , & lEaten , ppidl , NULL ) ;
}
return ;
}
//********************************************************************************
// getMsgString
// loads a Message String from the string table
//********************************************************************************
static BOOL getMsgString ( char * buf , UINT uID )
{
if ( ! buf )
return FALSE ;
int ret = LoadString ( gDLL , uID , buf , 255 ) ;
return ret ;
}
//********************************************************************************
// getSystemDirectory_1()
// intended to be a more fail-safe version of GetSystemDirectory
// returns:
// NULL if the path cannot be obtained for any reason
// otherwise, the "GetSystemDirectory" path
//********************************************************************************
static char * getSystemDirectory_1 ( )
{
UINT startLength = MAX_PATH ;
UINT sysPathLength = MAX_PATH ;
char * sysPath ;
start :
sysPath = ( char * ) malloc ( sizeof ( char ) * startLength ) ;
if ( ! sysPath )
return NULL ;
sysPathLength = : : GetSystemDirectory ( sysPath , startLength ) ;
if ( sysPathLength = = 0 )
return NULL ;
if ( sysPathLength > startLength )
{
free ( sysPath ) ;
startLength = sysPathLength ;
goto start ;
}
return sysPath ;
}
//********************************************************************************
// getPhoneBookNT()
// returns the path to the NT Phone Book file (rasphone.pbk)
// returns:
// NULL if the path cannot be obtained for any reason
// otherwise, the phone book file path
//********************************************************************************
static char * getPhoneBookNT ( )
{
char * sysPath ;
char * pbPath ;
sysPath = getSystemDirectory_1 ( ) ;
if ( ! sysPath )
return FALSE ;
pbPath = ( char * ) malloc ( sizeof ( char ) * strlen ( sysPath ) + 30 ) ;
if ( ! pbPath )
{
free ( sysPath ) ;
return FALSE ;
}
strcpy ( pbPath , sysPath ) ;
strcat ( pbPath , " \\ ras \\ rasphone.pbk " ) ;
strcat ( pbPath , " \0 " ) ;
free ( sysPath ) ;
return pbPath ;
}
//********************************************************************************
// startRasMonNT()
// starts the "rasmon" process (rasmon.exe)
// returns:
// FALSE if the process cannot be started for any reason
// TRUE otherwise
//********************************************************************************
static BOOL startRasMonNT ( )
{
// starts up RASMON process
PROCESS_INFORMATION pi ;
BOOL ret ;
STARTUPINFO sti ;
UINT err = ERROR_SUCCESS ;
char * sysPath ;
char * rasMonPath ;
sysPath = getSystemDirectory_1 ( ) ;
if ( ! sysPath )
return FALSE ;
rasMonPath = ( char * ) malloc ( sizeof ( char ) * strlen ( sysPath ) + 30 ) ;
if ( ! rasMonPath )
{
free ( sysPath ) ;
return FALSE ;
}
strcpy ( rasMonPath , sysPath ) ;
strcat ( rasMonPath , " \\ rasmon.exe " ) ;
strcat ( rasMonPath , " \0 " ) ;
free ( sysPath ) ;
memset ( & sti , 0 , sizeof ( sti ) ) ;
sti . cb = sizeof ( STARTUPINFO ) ;
// Run the RASMON app
ret = : : CreateProcess ( rasMonPath , NULL , NULL , NULL , FALSE , 0 , NULL , NULL , & sti , & pi ) ;
if ( ret = = TRUE )
{
gRasMon = pi . hProcess ;
Sleep ( 3000 ) ;
}
free ( rasMonPath ) ;
return ret ;
}
static void setStatusDialogText ( int iField , const char * pText )
{
if ( gHwndStatus )
{
HWND hField = GetDlgItem ( gHwndStatus , iField ) ;
if ( hField )
SetWindowText ( hField , pText ) ;
}
}
static void removeStatusDialog ( )
{
if ( gHwndStatus )
{
EndDialog ( gHwndStatus , TRUE ) ;
gHwndStatus = NULL ;
}
}
static int displayErrMsgWnd ( char * text , int style , HWND hwnd )
{
char title [ 50 ] ;
getMsgString ( ( char * ) & title , IDS_APP_NAME ) ;
if ( hwnd = = NULL )
hwnd = GetActiveWindow ( ) ;
int ret = MessageBox ( hwnd , text , title , style ) ;
return ret ;
}
static void displayDialErrorMsg ( DWORD dwError )
{
char szErr [ 256 ] ;
char szErrStr [ 256 ] ;
HWND wind ;
ASSERT ( m_lpfnRasGetErrorString ) ;
( * m_lpfnRasGetErrorString ) ( ( UINT ) dwError , szErr , sizeof ( szErr ) ) ;
// some of the default error strings are pretty lame
switch ( dwError )
{
case ERROR_NO_DIALTONE :
getMsgString ( szErr , IDS_NO_DIALTONE ) ;
break ;
case ERROR_LINE_BUSY :
getMsgString ( szErr , IDS_LINE_BUSY ) ;
break ;
case ERROR_PROTOCOL_NOT_CONFIGURED :
getMsgString ( szErr , IDS_PROTOCOL_NOT_CONFIGURED ) ;
default :
break ;
}
getMsgString ( szErrStr , IDS_CONNECTION_FAILED ) ;
strcat ( szErrStr , szErr ) ;
wind = gHwndStatus ;
if ( ! wind )
wind = gHwndNavigator ;
displayErrMsgWnd ( szErrStr , MB_OK | MB_ICONEXCLAMATION , wind ) ;
}
static void connectErr ( DWORD dwError )
{
char strText [ 255 ] ;
if ( gHwndStatus )
{
getMsgString ( ( char * ) strText , IDS_DIAL_ERR ) ;
setStatusDialogText ( IDC_DIAL_STATUS , strText ) ;
Sleep ( 1000 ) ;
removeStatusDialog ( ) ;
}
gDeviceErr = TRUE ; // some sort of device err
displayDialErrorMsg ( dwError ) ;
}
BOOL CALLBACK statusDialogCallback ( HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam )
{
BOOL bRetval = FALSE ;
DWORD dwRet ;
if ( ! gHwndStatus )
gHwndStatus = hWnd ;
switch ( uMsg )
{
case WM_INITDIALOG :
return TRUE ;
break ;
case WM_COMMAND :
{
WORD wNotifyCode = HIWORD ( wParam ) ;
WORD wID = LOWORD ( wParam ) ;
HWND hControl = ( HWND ) lParam ;
switch ( wID )
{
case IDDISCONNECTED :
// if (AfxMessageBox(IDS_LOST_CONNECTION, MB_YESNO) == IDYES)
// m_pMainWnd->PostMessage(WM_COMMAND, IDC_DIAL);
break ;
case IDCANCEL :
{
// RasHangUp & destroy dialog box
bRetval = TRUE ;
gCancelled = TRUE ;
ASSERT ( m_lpfnRasHangUp ) ;
char strText [ 255 ] ;
getMsgString ( strText , IDS_CANCELDIAL ) ;
setStatusDialogText ( IDC_DIAL_STATUS , strText ) ;
dwRet = ( * m_lpfnRasHangUp ) ( gRasConn ) ;
if ( dwRet = = ERROR_INVALID_HANDLE )
trace ( " dialer.cpp : statusDialogCallback - Can't hangup. Invalid Connection Handle. (r) " ) ;
else if ( dwRet & & dwRet ! = ERROR_INVALID_HANDLE )
trace ( " dialer.cpp : statusDialogCallback - Can't hangup. Error %d. (r) " , dwRet ) ;
Sleep ( 3000 ) ;
removeStatusDialog ( ) ;
break ;
}
}
}
}
return bRetval ;
}
static void setCallState ( CallState newState )
{
gCallState = newState ;
switch ( gCallState )
{
case StateConnected :
// destroy our connection status window
removeStatusDialog ( ) ;
break ;
case StateConnecting :
// creates status dialog box
HWND hwndParent = GetActiveWindow ( ) ;
int nResult ;
nResult = DialogBox ( gDLL , MAKEINTRESOURCE ( IDD_STATUS ) , hwndParent , ( DLGPROC ) statusDialogCallback ) ;
ASSERT ( nResult ! = - 1 ) ;
break ;
}
}
//********************************************************************************
// RasDialFunc
// call back function for RasDial
//********************************************************************************
void CALLBACK
RasDialFunc ( HRASCONN hRasConn , UINT uMsg ,
RASCONNSTATE rasConnState , DWORD dwError , DWORD dwExtendedError )
{
if ( uMsg ! = WM_RASDIALEVENT )
return ;
// ignore all other messages
gRASstate = rasConnState ;
char strText [ 255 ] ;
DWORD dwRet ;
switch ( rasConnState )
{
case RASCS_OpenPort :
// wait for status dialog to show up first
while ( gHwndStatus = = NULL )
Sleep ( 1000 ) ;
getMsgString ( strText , IDS_OPENING_PORT ) ;
setStatusDialogText ( IDC_DIAL_STATUS , strText ) ;
if ( dwError )
connectErr ( dwError ) ;
else
Sleep ( 1000 ) ;
break ;
case RASCS_PortOpened :
getMsgString ( strText , IDS_INIT_MODEM ) ;
setStatusDialogText ( IDC_DIAL_STATUS , strText ) ;
if ( dwError )
connectErr ( dwError ) ;
else
Sleep ( 1000 ) ;
break ;
case RASCS_ConnectDevice :
if ( gDialAttempts = = 1 )
{
getMsgString ( strText , IDS_DIALING ) ;
setStatusDialogText ( IDC_DIAL_STATUS , strText ) ;
}
else
{
char szBuf [ 128 ] ;
getMsgString ( strText , IDS_DIALING_OF ) ;
wsprintf ( szBuf , ( LPCSTR ) strText , gDialAttempts , NUM_ATTEMPTS ) ;
setStatusDialogText ( IDC_DIAL_STATUS , strText ) ;
}
if ( dwError )
connectErr ( dwError ) ;
else
Sleep ( 1000 ) ;
break ;
case RASCS_Authenticate :
getMsgString ( strText , IDS_VERIFYING ) ;
setStatusDialogText ( IDC_DIAL_STATUS , strText ) ;
if ( dwError )
connectErr ( dwError ) ;
else
Sleep ( 1000 ) ;
break ;
case RASCS_Authenticated :
getMsgString ( strText , IDS_LOGGING_ON ) ;
setStatusDialogText ( IDC_DIAL_STATUS , strText ) ;
if ( dwError )
connectErr ( dwError ) ;
else
Sleep ( 1000 ) ;
break ;
case RASCS_Connected :
getMsgString ( strText , IDS_CONNECTED ) ;
setStatusDialogText ( IDC_DIAL_STATUS , strText ) ;
setCallState ( StateConnected ) ;
if ( dwError )
connectErr ( dwError ) ;
else
Sleep ( 1000 ) ;
break ;
case RASCS_Disconnected :
// If this is an unexpected disconnect then hangup and take
// down the status dialog box
if ( gCallState = = StateConnected | | gCallState = = StateConnecting )
{
ASSERT ( m_lpfnRasHangUp ) ;
dwRet = ( * m_lpfnRasHangUp ) ( gRasConn ) ;
if ( dwRet = = ERROR_INVALID_HANDLE )
trace ( " dialer.cpp : ProcessRasDialEvent (stateConnected) - Can't hangup. Invalid Connection Handle. " ) ;
else if ( dwRet & & dwRet ! = ERROR_INVALID_HANDLE )
trace ( " dialer.cpp : ProcessRasDialEvent (stateConnected) - Can't hangup. Error %d " , dwRet ) ;
Sleep ( 3000 ) ;
if ( gCallState = = StateConnecting )
{
if ( dwError ! = SUCCESS )
{
if ( gHwndStatus )
{
getMsgString ( strText , IDS_DISCONNECTING ) ;
setStatusDialogText ( IDC_DIAL_STATUS , strText ) ;
}
}
}
// here we pass redial msg if needed.
removeStatusDialog ( ) ;
if ( gCallState = = StateConnecting )
{
gLineDrop = TRUE ; // remove if we ask users for redial
displayDialErrorMsg ( dwError ) ;
}
}
setCallState ( StateIdle ) ;
break ;
case RASCS_WaitForModemReset :
getMsgString ( strText , IDS_DISCONNECTING ) ;
setStatusDialogText ( IDC_DIAL_STATUS , strText ) ;
if ( dwError )
{
trace ( " dialer.cpp : ProcessRasDialEvent (WaitForModemReset) - Connection Error %d " , dwError ) ;
connectErr ( dwError ) ;
}
else
Sleep ( 1000 ) ;
break ;
default :
if ( dwError )
{
trace ( " dialer.cpp : ProcessRasDialEvent (default case) - Connection Error %d " , dwError ) ;
connectErr ( dwError ) ;
}
break ;
}
}
//********************************************************************************
// DialerConnect
// initiates a dialer connection (used if Dial on Demand is disabled)
// assumes the dialer has already been configured
// returns:
// FALSE if the dialer cannot be connected
// TRUE if the dialer is already connected or if it was able to connect
// successfully
//********************************************************************************
BOOL DialerConnect ( )
{
DWORD dwError ;
DWORD dwRet ;
BOOL connectSucceed = TRUE ;
gHwndNavigator = GetActiveWindow ( ) ;
// return if dialer already connected
if ( IsDialerConnected ( ) )
return TRUE ;
gDialAttempts = 1 ;
gRasConn = NULL ; // init global connection handle
gCancelled = FALSE ; // assume connection is not canceled by the user, unless otherwise
char * pbPath = NULL ;
LPVOID notifierProc = NULL ;
DWORD notifierType = 0 ;
notifierType = 1 ;
notifierProc = ( LPVOID ) RasDialFunc ;
// WinNT40 find system phone book first then start RASDIAL
if ( gPlatformOS = = VER_PLATFORM_WIN32_NT )
{
startRasMonNT ( ) ; // should check the error here, but I don't know
// what to do if we fail (report that error?)
pbPath = getPhoneBookNT ( ) ;
}
ASSERT ( m_lpfnRasDial ) ;
// do the dialing here
dwError = ( * m_lpfnRasDial ) ( NULL , pbPath , & gDialParams , notifierType , notifierProc , & gRasConn ) ;
if ( dwError = = ERROR_NOT_ENOUGH_MEMORY )
trace ( " dialer.cpp : [native] DialerConnect - Not enough memory for dialing activity. Dialing failed. " ) ;
else if ( dwError & & dwError ! = ERROR_NOT_ENOUGH_MEMORY )
trace ( " dialer.cpp : [native] DialerConnect - Dialing failed. Error code = %d " , dwError ) ;
if ( dwError = = SUCCESS )
{
// Dialing succeeded
// display connections status dialog & dispatch window msgs...
MSG msg ;
setCallState ( StateConnecting ) ;
while ( ( ( gRASstate ! = RASCS_Connected ) & &
( gRASstate ! = RASCS_Disconnected ) ) & &
( ! gCancelled ) & &
( ! gLineDrop ) & &
( ! gDeviceErr ) )
{
if ( : : GetMessage ( & msg , NULL , 0 , 0 ) )
{
: : TranslateMessage ( & msg ) ;
: : DispatchMessage ( & msg ) ;
}
else
{
// WM_QUIT!!!
break ;
}
}
removeStatusDialog ( ) ;
if ( ( gRASstate ! = RASCS_Connected ) | | gCancelled )
connectSucceed = FALSE ;
}
else
{
// dialing failed!!!, display err msg
connectSucceed = FALSE ;
displayDialErrorMsg ( dwError ) ;
}
if ( ! connectSucceed )
{
// hangup connection
if ( gRasConn )
{
ASSERT ( m_lpfnRasHangUp ) ;
dwRet = ( * m_lpfnRasHangUp ) ( gRasConn ) ;
if ( dwRet = = ERROR_INVALID_HANDLE )
trace ( " dialer.cpp : [native] DialerConnect - Can't hangup. Invalid Connection Handle. " ) ;
else if ( dwRet & & dwRet ! = ERROR_INVALID_HANDLE )
trace ( " dialer.cpp : [native] DialerConnect - Can't hangup. Error %d " , dwRet ) ;
// give RasHangUp some time till complete hangup
removeStatusDialog ( ) ;
// wait three seconds for tear-down of notification proc.
// should figure out how to do this better (maybe set something
// in RasDialFunc which ensures us not getting called again?)
Sleep ( 3000 ) ;
}
}
SetActiveWindow ( gHwndNavigator ) ;
return connectSucceed ;
}
//********************************************************************************
// DialerHangup
// terminates a dialer connection
// if there is an active connection, it is terminated
// returns:
// nothing
//********************************************************************************
void DialerHangup ( )
{
RASCONN * info = NULL ;
RASCONN * lpTemp = NULL ;
DWORD code ;
DWORD count = 0 ;
DWORD dSize = stRASCONN ;
DWORD dwRet ;
BOOL triedOnce = FALSE ;
tryAgain :
// try to get a buffer to receive the connection data
info = ( RASCONN * ) LocalAlloc ( LPTR , ( UINT ) dSize ) ;
if ( ! info )
return ;
// set RAS struct size
info - > dwSize = dSize ;
ASSERT ( m_lpfnRasEnumConnections ) ;
// enumerate open connections
code = ( * m_lpfnRasEnumConnections ) ( info , & dSize , & count ) ;
if ( code ! = 0 & & triedOnce = = TRUE )
{
LocalFree ( info ) ;
return ;
}
if ( code = = ERROR_BUFFER_TOO_SMALL )
{
triedOnce = TRUE ;
// free the old buffer & allocate a new bigger one
LocalFree ( info ) ;
goto tryAgain ;
}
// check for no connections
if ( count = = 0 )
{
LocalFree ( info ) ;
return ;
}
ASSERT ( m_lpfnRasHangUp ) ;
// just hang up everything
for ( int i = 0 ; i < ( int ) count ; i + + )
{
dwRet = ( * m_lpfnRasHangUp ) ( info [ i ] . hrasconn ) ;
if ( dwRet = = ERROR_INVALID_HANDLE )
trace ( " dialer.cpp : DialerHangup - Can't hangup. Invalid Connection Handle. " ) ;
else if ( dwRet & & dwRet ! = ERROR_INVALID_HANDLE )
trace ( " dialer.cpp : DialerHangup - Can't hangup. Error %d. " , dwRet ) ;
Sleep ( 3000 ) ;
}
LocalFree ( info ) ;
}
//********************************************************************************
// findDialerData
// search the javascript array for specific string value
//********************************************************************************
char * findDialerData ( char * * dialerData , char * name )
{
char * * entry = dialerData ;
char * value ;
while ( * entry )
{
if ( strncmp ( * entry , name , strlen ( name ) ) = = 0 )
{
value = strchr ( * entry , ' = ' ) ;
if ( value )
value + + ;
break ;
}
entry + + ;
}
return ( char * ) value ;
}
//********************************************************************************
// fillAccountParameters
// fill in account information, given from JS array
//********************************************************************************
static void fillAccountParameters ( char * * dialerData , ACCOUNTPARAMS * account )
{
char * value ;
value = findDialerData ( dialerData , " AccountName " ) ;
strcpy ( account - > ISPName , value ? value : " My Account " ) ;
// file name
value = findDialerData ( dialerData , " FileName " ) ;
strcpy ( account - > FileName , value ? value : " My Account " ) ;
// DNS
value = findDialerData ( dialerData , " DNSAddress " ) ;
strcpy ( account - > DNS , value ? value : " 0.0.0.0 " ) ;
// DNS2
value = findDialerData ( dialerData , " DNSAddress2 " ) ;
strcpy ( account - > DNS2 , value ? value : " 0.0.0.0 " ) ;
// domain name
value = findDialerData ( dialerData , " DomainName " ) ;
strcpy ( account - > DomainName , value ? value : " " ) ;
// login name
value = findDialerData ( dialerData , " LoginName " ) ;
strcpy ( account - > LoginName , value ? value : " " ) ;
// password
value = findDialerData ( dialerData , " Password " ) ;
strcpy ( account - > Password , value ? value : " " ) ;
// script file name
value = findDialerData ( dialerData , " ScriptFileName " ) ;
strcpy ( account - > ScriptFileName , value ? value : " " ) ;
// script enabled?
value = findDialerData ( dialerData , " ScriptEnabled " ) ;
if ( value )
{
account - > ScriptEnabled = ( strcmp ( value , " TRUE " ) = = 0 ) ;
// get script content
value = findDialerData ( dialerData , " Script " ) ;
if ( value )
{
// ReggieScript = (char*) malloc(strlen(value) + 1);
// strcpy(ReggieScript, value);
}
}
else
account - > ScriptEnabled = 0 ;
// need TTY window?
value = findDialerData ( dialerData , " NeedsTTYWindow " ) ;
account - > NeedsTTYWindow = ( value & & ( strcmp ( value , " TRUE " ) = = 0 ) ) ;
// VJ compression enabled?
value = findDialerData ( dialerData , " VJCompresssionEnabled " ) ;
account - > VJCompressionEnabled = ( value & & ( strcmp ( value , " TRUE " ) = = 0 ) ) ;
// International mode?
value = findDialerData ( dialerData , " IntlMode " ) ;
account - > IntlMode = ( value & & ( strcmp ( value , " TRUE " ) = = 0 ) ) ;
// dial on demand?
value = findDialerData ( dialerData , " DialOnDemand " ) ;
account - > DialOnDemand = ( value & & ( strcmp ( value , " TRUE " ) = = 0 ) ) ;
// isp phone number
value = findDialerData ( dialerData , " ISPPhoneNum " ) ;
if ( value )
strcpy ( account - > ISPPhoneNum , value ) ;
else
strcpy ( account - > ISPPhoneNum , " " ) ;
// ISDN phone number
value = findDialerData ( dialerData , " ISDNPhoneNum " ) ;
if ( value )
strcpy ( account - > ISDNPhoneNum , value ) ;
else
strcpy ( account - > ISDNPhoneNum , " " ) ;
}
//********************************************************************************
// fillLocationParameters
// fill in location information, given from JS array
//********************************************************************************
static void fillLocationParameters ( char * * dialerData , LOCATIONPARAMS * location )
{
char * value ;
// modem name
value = findDialerData ( dialerData , " ModemName " ) ;
strcpy ( location - > ModemName , value ? value : " " ) ;
// modem type
value = findDialerData ( dialerData , " ModemType " ) ;
strcpy ( location - > ModemType , value ? value : " " ) ;
// dial type
value = findDialerData ( dialerData , " DialType " ) ;
location - > DialType = ! ( value & & ( strcmp ( value , " TONE " ) = = 0 ) ) ;
// outside line access
value = findDialerData ( dialerData , " OutsideLineAccess " ) ;
strcpy ( location - > OutsideLineAccess , value ? value : " " ) ;
// disable call waiting?
value = findDialerData ( dialerData , " DisableCallWaiting " ) ;
location - > DisableCallWaiting = ( value & & ( strcmp ( value , " TRUE " ) = = 0 ) ) ;
// disable call waiting code
value = findDialerData ( dialerData , " DisableCallWaitingCode " ) ;
strcpy ( location - > DisableCallWaitingCode , value ? value : " " ) ;
// user area code
value = findDialerData ( dialerData , " UserAreaCode " ) ;
strcpy ( location - > UserAreaCode , value ? value : " " ) ;
// user country code
value = findDialerData ( dialerData , " CountryCode " ) ;
if ( value )
{
char * stopstr = " \0 " ;
location - > UserCountryCode = ( short ) strtol ( value , & stopstr , 10 ) ;
}
else
location - > UserCountryCode = 1 ; // default to US
// dial as long distance?
value = findDialerData ( dialerData , " DialAsLongDistance " ) ;
location - > DialAsLongDistance = ( value & & ( strcmp ( value , " TRUE " ) = = 0 ) ) ;
// long distance access
value = findDialerData ( dialerData , " LongDistanceAccess " ) ;
strcpy ( location - > LongDistanceAccess , value ? value : " " ) ;
// dial area code?
value = findDialerData ( dialerData , " DialAreaCode " ) ;
location - > DialAreaCode = ( value & & ( strcmp ( value , " TRUE " ) = = 0 ) ) ;
// dial prefix code
value = findDialerData ( dialerData , " DialPrefix " ) ;
strcpy ( location - > DialPrefix , value ? value : " " ) ;
// dial suffix code
value = findDialerData ( dialerData , " DialSuffix " ) ;
strcpy ( location - > DialSuffix , value ? value : " " ) ;
// use both ISDN lines?
value = findDialerData ( dialerData , " UseBothISDNLines " ) ;
location - > UseBothISDNLines = ( value & & ( strcmp ( value , " TRUE " ) = = 0 ) ) ;
// 56k ISDN?
value = findDialerData ( dialerData , " 56kISDN " ) ;
location - > b56kISDN = ( value & & ( strcmp ( value , " TRUE " ) = = 0 ) ) ;
// disconnect time
value = findDialerData ( dialerData , " DisconnectTime " ) ;
if ( value )
location - > DisconnectTime = atoi ( value ) ;
else
location - > DisconnectTime = 5 ;
}
//********************************************************************************
// onlyOneSet
// Just an XOR of DialAsLongDistance & DialAreaCode - if only one of them is
// set then we can't use MS Locations (if neither are set then we can use
// locations, but disable use of both - they just don't allow disabling of each
// individually)
//********************************************************************************
static BOOL onlyOneSet ( const LOCATIONPARAMS & location )
{
return ( location . DialAsLongDistance ?
( location . DialAreaCode ? FALSE : TRUE ) :
( location . DialAreaCode ? TRUE : FALSE ) ) ;
}
//********************************************************************************
// prefixAvail
// returns:
// TRUE if there are prefixes that make location unusable
//********************************************************************************
static BOOL prefixAvail ( const LOCATIONPARAMS & location )
{
return ( location . DisableCallWaiting & & location . DisableCallWaitingCode [ 0 ] ! = 0 ) | |
( location . OutsideLineAccess & & location . OutsideLineAccess [ 0 ] ! = 0 ) ;
}
//********************************************************************************
// parseNumber
//
// Parses a canonical TAPI phone number into country code, area code, and
// local subscriber number
//********************************************************************************
static void parseNumber ( LPCSTR lpszCanonical , LPDWORD lpdwCountryCode ,
LPSTR lpszAreaCode , LPSTR lpszLocal )
{
//*** sscanf dependency removed for win16 compatibility
char temp [ 256 ] ;
int p1 , p2 ;
// Initialize our return values
* lpdwCountryCode = 1 ; // North America Calling Plan
* lpszAreaCode = ' \0 ' ;
* lpszLocal = ' \0 ' ;
if ( ! lpszCanonical | | ! * lpszCanonical )
return ;
// We allow three variations (two too many):
// -: +1 (415) 428-3838 (TAPI canonical number)
// -: (415) 428-3838 (TAPI canonical number minus country code)
// -: 428-3838 (subscriber number only)
//
// NOTE: this approach only works if there is a city/area code. The TAPI
// spec says the city/area code is optional for countries that have a flat
// phone numbering system
// Take my advice, always start at the beginning.
p1 = 0 ;
// Allow spaces
while ( lpszCanonical [ p1 ] = = ' ' )
p1 + + ;
// Handle the country code if '+' prefix seen
if ( lpszCanonical [ p1 ] = = ' + ' )
{
p1 + + ;
if ( ! isdigit ( lpszCanonical [ p1 ] ) )
return ;
p2 = p1 ;
while ( isdigit ( lpszCanonical [ p1 ] ) )
p1 + + ;
strncpy ( temp , & lpszCanonical [ p2 ] , p1 - p2 ) ;
* lpdwCountryCode = atoi ( temp ) ;
}
// Allow spaces
while ( lpszCanonical [ p1 ] = = ' ' )
p1 + + ;
// Handle the area code if '(' prefix seen
if ( lpszCanonical [ p1 ] = = ' ( ' )
{
p1 + + ;
if ( ! isdigit ( lpszCanonical [ p1 ] ) )
return ;
p2 = p1 ;
while ( isdigit ( lpszCanonical [ p1 ] ) )
p1 + + ;
strncpy ( lpszAreaCode , & lpszCanonical [ p2 ] , p1 - p2 ) ;
p1 + + ; // Skip over the trailing ')'
}
// Allow spaces
while ( lpszCanonical [ p1 ] = = ' ' )
p1 + + ;
// Whatever's left is the subscriber number (possibly including the whole string)
strcpy ( lpszLocal , & lpszCanonical [ p1 ] ) ;
}
//********************************************************************************
// composeNumber
// create a phone number encompassing all of the location information to hack
// around dialup networking ignoring the location information if you turn off
// the "dial area and country code" flag
//********************************************************************************
static void composeNumber ( ACCOUNTPARAMS & account , const LOCATIONPARAMS & location , char csNumber [ ] )
{
// if they need to dial something to get an outside line next
if ( location . OutsideLineAccess [ 0 ] ! = 0 )
{
strcat ( csNumber , location . OutsideLineAccess ) ;
strcat ( csNumber , " " ) ;
}
// add disable call waiting if it exists
if ( location . DisableCallWaiting & & location . DisableCallWaitingCode [ 0 ] ! = 0 )
{
strcat ( csNumber , location . DisableCallWaitingCode ) ;
strcat ( csNumber , " " ) ;
}
if ( account . IntlMode )
{
// In international mode we don't fill out the area code or
// anything, just the exchange part
strcat ( csNumber , account . ISPPhoneNum ) ;
}
else
{
// lets parse the number into pieces so we can get the area code & country code
DWORD nCntry ;
char szAreaCode [ 32 ] ;
char szPhoneNumber [ 32 ] ;
parseNumber ( account . ISPPhoneNum , & nCntry , szAreaCode , szPhoneNumber ) ;
// dial the 1 (country code) first if they want it
if ( location . DialAsLongDistance )
{
char cntry [ 10 ] ;
ultoa ( nCntry , cntry , 10 ) ;
if ( strcmp ( location . LongDistanceAccess , " " ) = = 0 )
strcat ( csNumber , cntry ) ;
else
strcat ( csNumber , location . LongDistanceAccess ) ;
strcat ( csNumber , " " ) ;
}
// dial the area code next if requested
if ( location . DialAreaCode )
{
strcat ( csNumber , szAreaCode ) ;
strcat ( csNumber , " " ) ;
}
// dial the local part of the number
strcat ( csNumber , szPhoneNumber ) ;
}
}
//********************************************************************************
// toNumericAddress
// converts from dotted address to numeric internet address
//********************************************************************************
static BOOL toNumericAddress ( LPCSTR lpszAddress , DWORD & dwAddress )
{
//*** sscanf dependency removed for win16 compatibility
char temp [ 256 ] ;
int a , b , c , d ;
int p1 , p2 ;
strcpy ( temp , lpszAddress ) ;
p2 = p1 = 0 ;
while ( temp [ p1 ] ! = ' . ' )
p1 + + ;
temp [ p1 ] = ' \0 ' ;
a = atoi ( & temp [ p2 ] ) ;
p2 = + + p1 ;
while ( temp [ p1 ] ! = ' . ' )
p1 + + ;
temp [ p1 ] = ' \0 ' ;
b = atoi ( & temp [ p2 ] ) ;
p2 = + + p1 ;
while ( temp [ p1 ] ! = ' . ' )
p1 + + ;
temp [ p1 ] = ' \0 ' ;
c = atoi ( & temp [ p2 ] ) ;
p2 = + + p1 ;
d = atoi ( & temp [ p2 ] ) ;
// Must be in network order (different than Intel byte ordering)
LPBYTE lpByte = ( LPBYTE ) & dwAddress ;
* lpByte + + = BYTE ( a ) ;
* lpByte + + = BYTE ( b ) ;
* lpByte + + = BYTE ( c ) ;
* lpByte = BYTE ( d ) ;
return TRUE ;
}
//********************************************************************************
// getCountryID
//********************************************************************************
static BOOL getCountryID ( DWORD dwCountryCode , DWORD & dwCountryID )
{
ASSERT ( m_lpfnRasGetCountryInfo ) ;
if ( ! m_lpfnRasGetCountryInfo )
{
trace ( " dialer.cpp : GetCountryID - RasGetCountryinfo func not availble. (r) " ) ;
return FALSE ;
}
RASCTRYINFO * pCI = NULL ;
BOOL bRetval = FALSE ;
DWORD dwSize = stRASCTRYINFO + 256 ;
pCI = ( RASCTRYINFO * ) malloc ( ( UINT ) dwSize ) ;
if ( pCI )
{
pCI - > dwSize = stRASCTRYINFO ;
pCI - > dwCountryID = 1 ;
while ( ( * m_lpfnRasGetCountryInfo ) ( pCI , & dwSize ) = = 0 )
{
if ( pCI - > dwCountryCode = = dwCountryCode )
{
dwCountryID = pCI - > dwCountryID ;
bRetval = TRUE ;
break ;
}
pCI - > dwCountryID = pCI - > dwNextCountryID ;
}
free ( pCI ) ;
pCI = NULL ;
}
return bRetval ;
}
//********************************************************************************
// createLink
// creates a shell shortcut to the PIDL
//********************************************************************************
static HRESULT createLink ( LPITEMIDLIST pidl , LPCTSTR lpszPathLink , LPCTSTR lpszDesc ,
char * iconPath )
{
HRESULT hres ;
IShellLink * psl = NULL ;
// Get a pointer to the IShellLink interface.
//CoInitialize(NULL); // work around for Nav thread lock bug
hres = CoCreateInstance ( CLSID_ShellLink , NULL , CLSCTX_INPROC_SERVER ,
IID_IShellLink , ( LPVOID FAR * ) & psl ) ;
if ( SUCCEEDED ( hres ) )
{
IPersistFile * ppf ;
// Set the path to the shortcut target, and add the description.
psl - > SetIDList ( pidl ) ;
psl - > SetDescription ( lpszDesc ) ;
if ( iconPath & & iconPath [ 0 ] )
psl - > SetIconLocation ( iconPath , 0 ) ;
// Query IShellLink for the IPersistFile interface for saving the
// shortcut in persistent storage.
hres = psl - > QueryInterface ( IID_IPersistFile , ( LPVOID FAR * ) & ppf ) ;
if ( SUCCEEDED ( hres ) )
{
WORD wsz [ MAX_PATH ] ;
// Ensure that the string is ANSI.
MultiByteToWideChar ( CP_ACP , 0 , lpszPathLink , - 1 , wsz , MAX_PATH ) ;
// Save the link by calling IPersistFile::Save.
hres = ppf - > Save ( ( LPCOLESTR ) wsz , STGM_READ ) ;
ppf - > Release ( ) ;
}
psl - > Release ( ) ;
}
//CoUninitialize();
return hres ;
}
//********************************************************************************
// fileExists
//********************************************************************************
static BOOL fileExists ( LPCSTR lpszFileName )
{
BOOL bResult = FALSE ;
HANDLE hFile = NULL ;
// opens the file for READ
hFile = CreateFile ( lpszFileName , GENERIC_READ , 0 , NULL , OPEN_EXISTING ,
FILE_ATTRIBUTE_NORMAL , NULL ) ;
if ( hFile ! = INVALID_HANDLE_VALUE ) { // openned file is valid
bResult = TRUE ;
CloseHandle ( hFile ) ;
}
return bResult ;
}
//********************************************************************************
// processScriptLogin
// generate a script file and return the name of the file. The
// caller is responsible for freeing the script file name
//********************************************************************************
static BOOL processScriptedLogin ( LPSTR lpszBuf , const char * lpszScriptFile )
{
// validate our args just for fun
if ( ! lpszBuf | | ( lpszBuf [ 0 ] = = ' \0 ' ) | | ! lpszScriptFile )
return ( FALSE ) ;
// open the actual script file
FILE * fp = fopen ( lpszScriptFile , " w " ) ;
if ( ! fp )
return ( FALSE ) ;
// generate a prolog
char timebuf [ 24 ] ;
char datebuf [ 24 ] ;
_strtime ( timebuf ) ;
_strdate ( datebuf ) ;
fprintf ( fp , " ; %s \n ; Created: %s at %s \n ; \n ; \n proc main \n " , lpszScriptFile , datebuf , timebuf ) ;
// Send a return to poke the server. Is this needed?
fprintf ( fp , " transmit \" ^M \" \n " ) ;
for ( int i = 0 ; lpszBuf ; i + + ) {
LPSTR lpszDelim ;
// Each event consists of two parts:
// 1. string to wait for
// 2. string to reply with
//
// The string to reply with is optional. A '|' separates the two strings
// and another '|' separates each event
lpszDelim = strchr ( lpszBuf , ' | ' ) ;
if ( lpszDelim )
* lpszDelim = ' \0 ' ;
// we are in the "wait for event"
fprintf ( fp , " waitfor \" %s \" ,matchcase until 30 \n " , lpszBuf ) ;
// skip to the next bit
lpszBuf = lpszDelim ? lpszDelim + 1 : NULL ;
if ( lpszBuf ) {
// now look for the reply event
lpszDelim = strchr ( lpszBuf , ' | ' ) ;
if ( lpszDelim )
* lpszDelim = ' \0 ' ;
// we are in the "reply with" event
// NOTE: we will want to get the ^M value from someone else
// since different ISPs will probably want different ones
if ( ! stricmp ( lpszBuf , " %name " ) )
fprintf ( fp , " transmit $USERID \n " ) ;
else if ( ! stricmp ( lpszBuf , " %password " ) )
fprintf ( fp , " transmit $PASSWORD \n " ) ;
else if ( lpszBuf [ 0 ] )
fprintf ( fp , " transmit \" %s \" \n " , lpszBuf ) ;
fprintf ( fp , " transmit \" ^M \" \n " ) ;
}
lpszBuf = lpszDelim ? lpszDelim + 1 : NULL ;
}
// writeout the ending bits and cleanup
fprintf ( fp , " endproc \n " ) ;
fclose ( fp ) ;
return ( TRUE ) ;
}
//********************************************************************************
// createPhoneBookEntry
// Create a dial-up networking profile
//********************************************************************************
static BOOL createPhoneBookEntry ( ACCOUNTPARAMS account , const LOCATIONPARAMS & location )
{
DWORD dwRet ;
BOOL ret = FALSE ;
RASENTRY rasEntry ;
// abort if RAS API ptrs are invalid & mem alloc fails
ASSERT ( m_lpfnRasSetEntryProperties ) ;
ASSERT ( m_lpfnRasSetEntryDialParams ) ;
if ( ! m_lpfnRasSetEntryProperties | |
! m_lpfnRasSetEntryDialParams )
return FALSE ;
// Initialize the RNA struct
memset ( & rasEntry , 0 , stRASENTRY ) ;
rasEntry . dwSize = stRASENTRY ;
rasEntry . dwfOptions = RASEO_ModemLights | RASEO_RemoteDefaultGateway ;
// Only allow compression if reg server says its OK
if ( account . VJCompressionEnabled )
rasEntry . dwfOptions | = RASEO_IpHeaderCompression | RASEO_SwCompression ;
if ( account . NeedsTTYWindow )
if ( gPlatformOS = = VER_PLATFORM_WIN32_WINDOWS )
rasEntry . dwfOptions | = RASEO_TerminalBeforeDial ; //win95 bug! RASEO_TerminalBeforeDial means terminal after dial
else
rasEntry . dwfOptions | = RASEO_TerminalAfterDial ;
// If Intl Number (not NorthAmerica), or Area Code w/o LDAccess (1) or
// visa-versa, then abandon using Location - NOTE: for Intl Number we
// should be able to use location, check it out!
if ( account . IntlMode | | onlyOneSet ( location ) )
{
char szNumber [ RAS_MaxPhoneNumber + 1 ] ;
szNumber [ 0 ] = ' \0 ' ;
composeNumber ( account , location , szNumber ) ;
strcpy ( rasEntry . szLocalPhoneNumber , szNumber ) ;
strcpy ( rasEntry . szAreaCode , " 415 " ) ; // hack around MS bug -- ignored
rasEntry . dwCountryCode = 1 ; // hack around MS bug -- ignored
}
else
{
// Let Win95 decide to dial the area code or not
rasEntry . dwfOptions | = RASEO_UseCountryAndAreaCodes ;
trace ( " dialer.cpp : Use country and area codes = %d " , rasEntry . dwfOptions ) ;
// Configure the phone number
parseNumber ( account . ISPPhoneNum , & rasEntry . dwCountryCode ,
rasEntry . szAreaCode , rasEntry . szLocalPhoneNumber ) ;
if ( ! account . IntlMode )
{
// if not internationalize version, check the area code and make
// sure we got a valid area code, if not throw up a err msg
if ( rasEntry . szAreaCode [ 0 ] = = ' \0 ' )
{
// Err: The service provider's phone number is missing its area code
// (or is not in TAPI cannonical form in the configuration file).
// Account creation will fail until this is fixed.
char * buf = ( char * ) malloc ( sizeof ( char ) * 255 ) ;
if ( buf )
{
if ( getMsgString ( buf , IDS_MISSING_AREA_CODE ) )
displayErrMsgWnd ( buf , MB_OK | MB_ICONEXCLAMATION , gHwndNavigator ) ;
free ( buf ) ;
}
return FALSE ;
}
}
}
// Now that we have the country code, we need to find the associated
// country ID
getCountryID ( rasEntry . dwCountryCode , rasEntry . dwCountryID ) ;
// Configure the IP data
rasEntry . dwfOptions | = RASEO_SpecificNameServers ;
if ( account . DNS [ 0 ] )
toNumericAddress ( account . DNS , * ( LPDWORD ) & rasEntry . ipaddrDns ) ;
if ( account . DNS2 [ 0 ] )
toNumericAddress ( account . DNS2 , * ( LPDWORD ) & rasEntry . ipaddrDnsAlt ) ;
// Configure the protocol and device settings here:
// Negotiate TCP/IP
rasEntry . dwfNetProtocols = RASNP_Ip ;
// Point-to-Point protocal (PPP)
rasEntry . dwFramingProtocol = RASFP_Ppp ;
// modem's information
strcpy ( rasEntry . szDeviceName , location . ModemName ) ;
strcpy ( rasEntry . szDeviceType , location . ModemType ) ;
// If we have a script, then store it too
if ( account . ScriptEnabled )
{
BOOL rtnval = TRUE ;
/* // if there is script content, 'Translate' and store in file
if ( ReggieScript )
{
// construct script filename if it does not exists
if ( strlen ( account . ScriptFileName ) = = 0 )
{
GetProfileDirectory ( account . ScriptFileName ) ;
int nIndex = strlen ( account . ScriptFileName ) ;
strncat ( account . ScriptFileName , account . ISPName , 8 ) ;
strcat ( account . ScriptFileName , " .scp " ) ;
}
rtnval = ProcessScriptedLogin ( ( LPSTR ) ReggieScript , account . ScriptFileName ) ;
free ( ReggieScript ) ;
}
// if there really is a script file (from ISP or Reggie) then use it
if ( rtnval & & FileExists ( account . ScriptFileName ) )
{
strcpy ( rasEntry . szScript , account . ScriptFileName ) ;
// convert forward slash to backward slash
int nLen = strlen ( rasEntry . szScript ) ;
for ( int i = 0 ; i < nLen ; i + + )
if ( rasEntry . szScript [ i ] = = ' / ' )
rasEntry . szScript [ i ] = ' \\ ' ;
}
*/
}
dwRet = ( * m_lpfnRasValidateEntryName ) ( NULL , ( LPSTR ) account . ISPName ) ;
if ( dwRet = = ERROR_ALREADY_EXISTS )
dwRet = 0 ;
ASSERT ( dwRet = = 0 ) ;
if ( dwRet = = ERROR_INVALID_NAME )
{
trace ( " dialer.cpp : CreateRNAEntry (RasValidateEntryName) - Invalid Name. Can't set RasEntry properties. (r) " ) ;
return FALSE ;
}
else if ( dwRet = = ERROR_ALREADY_EXISTS )
{
trace ( " dialer.cpp : CreateRNAEntry (RasValidateEntryName) - This name already exists. (r) " ) ;
return FALSE ;
}
else if ( dwRet )
{
trace ( " dialer.cpp : CreateRNAEntry (RasValidateEntryName) - Can't Validate account name. Error %d. (r) " , dwRet ) ;
return FALSE ;
}
dwRet = ( * m_lpfnRasSetEntryProperties ) ( NULL , ( LPSTR ) ( LPCSTR ) account . ISPName ,
( LPBYTE ) & rasEntry , stRASENTRY , NULL , 0 ) ;
ASSERT ( dwRet = = 0 ) ;
//if ( dwRet )
//return -1; // ??? this is going to return TRUE
if ( dwRet = = ERROR_BUFFER_INVALID )
{
trace ( " dialer.cpp : CreateRNAEntry (RasSetEntryProperties) - Invalid Buffer. Can't set RasEntry properties. (r) " ) ;
return FALSE ;
}
else if ( dwRet = = ERROR_CANNOT_OPEN_PHONEBOOK )
{
trace ( " dialer.cpp : CreateRNAEntry (RasSetEntryProperties) - Can't open phonebook. Corrupted phonebook or missing components. Can't set RasEntry properties. (r) " ) ;
return FALSE ;
}
else if ( dwRet )
{
trace ( " dialer.cpp : CreateRNAEntry (RasSetEntryProperties) - Can't set RasEntry properties. Error %d. (r) " , dwRet ) ;
return FALSE ;
}
// We need to set the login name and password with a separate call
// why doesn't this work for winNT40??
memset ( & gDialParams , 0 , sizeof ( gDialParams ) ) ;
gDialParams . dwSize = stRASDIALPARAMS ;
strcpy ( gDialParams . szEntryName , account . ISPName ) ;
strcpy ( gDialParams . szUserName , account . LoginName ) ;
strcpy ( gDialParams . szPassword , account . Password ) ;
// Creating connection entry!
char * pbPath = NULL ;
if ( gPlatformOS = VER_PLATFORM_WIN32_NT )
pbPath = getPhoneBookNT ( ) ;
else
pbPath = ( char * ) account . ISPName ;
dwRet = ( * m_lpfnRasSetEntryDialParams ) ( pbPath , & gDialParams , FALSE ) ;
if ( dwRet = = ERROR_BUFFER_INVALID )
{
trace ( " dialer.cpp : CreateRNAEntry (RasSetEntryDialParams) - Invalid Buffer. Can't set RasEntry Dial properties. (r) " ) ;
return FALSE ;
}
else if ( dwRet = = ERROR_CANNOT_OPEN_PHONEBOOK )
{
trace ( " dialer.cpp : CreateRNAEntry (RasSetEntryDialParams) - Can't open phonebook. Corrupted phonebook or missing components. Can't set RasEntry Dial properties. (r) " ) ;
return FALSE ;
}
else if ( dwRet = = ERROR_CANNOT_FIND_PHONEBOOK_ENTRY )
{
trace ( " dialer.cpp : CreateRNAEntry (RasSetEntryDialParams) - Phonebook entry does not exist. Can't set RasEntry Dial properties. (r) " ) ;
return FALSE ;
}
else if ( dwRet )
{
trace ( " dialer.cpp : CreateRNAEntry (RasSetEntryDialParams) - Can't set RasEntry Dial properties. Error %d. (r) " , dwRet ) ;
return FALSE ;
}
ret = ( dwRet = = 0 ) ;
if ( gPlatformOS = VER_PLATFORM_WIN32_NT )
{
RASCREDENTIALS credentials ;
// sets up user login info for new phonebook entry
memset ( & credentials , 0 , sizeof ( RASCREDENTIALS ) ) ;
credentials . dwSize = sizeof ( RASCREDENTIALS ) ;
credentials . dwMask = RASCM_UserName | RASCM_Password ;
strcpy ( credentials . szUserName , account . LoginName ) ;
strcpy ( credentials . szPassword , account . Password ) ;
strcpy ( credentials . szDomain , account . DomainName ) ;
dwRet = ( * m_lpfnRasSetCredentials ) ( pbPath , ( LPSTR ) account . ISPName , & credentials , FALSE ) ;
if ( dwRet = = ERROR_INVALID_PARAMETER )
{
trace ( " dialer.cpp : CreateRNAEntry (RasSetCredentials) - Invalid Parameter. Can't set user credentials. (r) " ) ;
return FALSE ;
}
else if ( dwRet = = ERROR_CANNOT_OPEN_PHONEBOOK )
{
trace ( " dialer.cpp : CreateRNAEntry (RasSetCredentials) - Can't open phonebook. Corrupted phonebook or missing components. Can't set user credentials. (r) " ) ;
return FALSE ;
}
else if ( dwRet = = ERROR_CANNOT_FIND_PHONEBOOK_ENTRY )
{
trace ( " dialer.cpp : CreateRNAEntry (RasSetCredentials) - Phonebook entry does not exist. Can't set user credentials. (r) " ) ;
return FALSE ;
}
else if ( dwRet = = ERROR_INVALID_SIZE )
{
trace ( " dialer.cpp : CreateRNAEntry (RasSetCredentials) - Invalid size value. Can't set user credentials. (r) " ) ;
return FALSE ;
}
else if ( dwRet )
{
trace ( " dialer.cpp : CreateRNAEntry (RasSetCredentials) - Can't set user credentials. Error %d. (r) " , dwRet ) ;
return FALSE ;
}
ret = ( dwRet = = 0 ) ;
if ( pbPath )
free ( pbPath ) ;
}
// dialing on demand is cool. let's do that on win95 now
if ( ret = = TRUE & & account . DialOnDemand )
if ( gPlatformOS = = VER_PLATFORM_WIN32_WINDOWS )
EnableDialOnDemand95 ( ( LPSTR ) account . ISPName , TRUE ) ;
else if ( gPlatformOS = = VER_PLATFORM_WIN32_NT )
EnableDialOnDemandNT ( ( LPSTR ) account . ISPName , TRUE ) ;
//SetAutoDisconnect( location.DisconnectTime );
return ret ;
}
//********************************************************************************
// DialerConfig
//
// setup and configures the dialer and networking stuff
// used in 3 conditions:
// 1. when calling regi for a new account
// 2. to configure new account from regi on users system
// 3. when optionally register Navigator in existing account path
//********************************************************************************
int DialerConfig ( char * * dialerDataArray )
{
gHwndNavigator = GetActiveWindow ( ) ;
ACCOUNTPARAMS account ;
LOCATIONPARAMS location ;
if ( ! dialerDataArray )
return - 1 ;
// now we try to get values from the JS array and put them into corresponding
// account and location parameters
fillAccountParameters ( dialerDataArray , & account ) ;
fillLocationParameters ( dialerDataArray , & location ) ;
// configure & creating Dial-Up Networking profile here for Win95 & WinNT40
// win16 use Shiva's RAS
if ( ! ( createPhoneBookEntry ( account , location ) ) )
{
// Err: Unable to crate RNA phone book entry!
char * buf = ( char * ) malloc ( sizeof ( char ) * 255 ) ;
if ( buf )
{
if ( getMsgString ( buf , IDS_NO_RNA_REGSERVER ) )
displayErrMsgWnd ( buf , MB_OK | MB_ICONEXCLAMATION , gHwndNavigator ) ;
free ( buf ) ;
}
}
// int ret;
// if ( gPlatformOS == VER_PLATFORM_WIN32_WINDOWS )
// {
// // sets the location stuff
// ret = SetLocationInfo( account, location );
// //ret = DisplayDialableNumber();
// }
// else
// {
// ret = SetLocationInfoNT( account, location );
// }
return 0 ;
}
//********************************************************************************
// IsDialerConnected
// checks if the dialer is still connected
//
// returns:
// TRUE if the dialer is connected
// FALSE if the dialer is not connected or there is an error trying to
// determine if the dialer is connected
//********************************************************************************
BOOL IsDialerConnected ( )
{
RASCONN * info = NULL ;
RASCONN * lpTemp = NULL ;
DWORD code = 0 ;
DWORD count = 0 ;
DWORD dSize = stRASCONN ;
// try to get a buffer to receive the connection data
if ( ! ( info = ( RASCONN * ) LocalAlloc ( LPTR , dSize ) ) )
return FALSE ;
// see if there are any open connections
info - > dwSize = stRASCONN ;
code = ( * m_lpfnRasEnumConnections ) ( info , & dSize , & count ) ;
if ( 0 ! = code ) // ERROR_BUFFER_TOO_SMALL ?
{
// free the old buffer
LocalFree ( info ) ;
// allocate a new bigger one
info = ( RASCONN * ) LocalAlloc ( LPTR , dSize ) ;
if ( ! info )
return FALSE ;
// try to enumerate again
info - > dwSize = dSize ;
if ( ( * m_lpfnRasEnumConnections ) ( info , & dSize , & count ) ! = 0 )
{
LocalFree ( info ) ;
// can't enumerate connections, assume none is active
return FALSE ;
}
}
// check for no connections
if ( 0 = = count )
{
LocalFree ( info ) ;
return FALSE ;
}
LocalFree ( info ) ;
return TRUE ;
}
//********************************************************************************
// SetAutoDisconnect
// Sets the autodisconnect time if idle
// the parameter "disconnectTime" is specified as MINUTES, convert it to SECONDS
// as necessary
//********************************************************************************
void SetAutoDisconnect ( DWORD disconnectTime )
{
HKEY hKey ;
DWORD dwDisposition ;
long result ;
DWORD dwValue ;
// if it's win95
if ( gPlatformOS = = VER_PLATFORM_WIN32_WINDOWS )
{
//
// set the autodial flag first
//
result = RegCreateKeyEx ( HKEY_CURRENT_USER , " Software \\ Microsoft \\ Windows \\ CurrentVersion \\ Internet Settings " ,
NULL , NULL , NULL , KEY_ALL_ACCESS , NULL , & hKey , & dwDisposition ) ;
// err, oops
if ( result ! = ERROR_SUCCESS )
return ;
// try setting autodisconnect here
dwValue = 1 ;
result = RegSetValueEx ( hKey , " EnableAutoDisconnect " , NULL , REG_BINARY , ( LPBYTE ) & dwValue , sizeof ( DWORD ) ) ;
// default auto-disconnect after 5 minutes or as specified (with a minimal of 3 minutes)
if ( disconnectTime < 3 )
dwValue = 3 ;
else
dwValue = disconnectTime ;
result = RegSetValueEx ( hKey , " DisconnectIdleTime " , NULL , REG_BINARY , ( LPBYTE ) & dwValue , sizeof ( DWORD ) ) ;
RegCloseKey ( hKey ) ;
//
// set the autodisconnect flags here too
//
result = RegCreateKeyEx ( HKEY_CURRENT_USER , " Software \\ Microsoft \\ Windows \\ Internet Settings " ,
NULL , NULL , NULL , KEY_ALL_ACCESS , NULL , & hKey , & dwDisposition ) ;
// err, oops
if ( result ! = ERROR_SUCCESS )
return ;
dwValue = 1 ;
result = RegSetValueEx ( hKey , " EnableAutoDisconnect " , NULL , REG_BINARY , ( LPBYTE ) & dwValue , sizeof ( DWORD ) ) ;
// default auto-disconnect after 5 minutes
if ( disconnectTime < 3 )
dwValue = 3 ;
else
dwValue = disconnectTime ;
result = RegSetValueEx ( hKey , " DisconnectIdleTime " , NULL , REG_BINARY , ( LPBYTE ) & dwValue , sizeof ( DWORD ) ) ;
RegCloseKey ( hKey ) ;
//
// also set the autodial flag here
//
result = RegCreateKeyEx ( HKEY_USERS , " .Default \\ Software \\ Microsoft \\ Windows \\ CurrentVersion \\ Internet Settings " ,
NULL , NULL , NULL , KEY_ALL_ACCESS , NULL , & hKey , & dwDisposition ) ;
// err, oops
if ( result ! = ERROR_SUCCESS )
return ;
// try setting autodisconnect here
dwValue = 1 ;
result = RegSetValueEx ( hKey , " EnableAutoDisconnect " , NULL , REG_BINARY , ( LPBYTE ) & dwValue , sizeof ( DWORD ) ) ;
// default auto-disconnect after 5 minutes or as specified (with a minimal of 3 minutes)
if ( disconnectTime < 3 )
dwValue = 3 ;
else
dwValue = disconnectTime ;
result = RegSetValueEx ( hKey , " DisconnectIdleTime " , NULL , REG_BINARY , ( LPBYTE ) & dwValue , sizeof ( DWORD ) ) ;
RegCloseKey ( hKey ) ;
//
// set the autodisconnect flags here too
//
result = RegCreateKeyEx ( HKEY_USERS , " .Default \\ Software \\ Microsoft \\ Windows \\ Internet Settings " ,
NULL , NULL , NULL , KEY_ALL_ACCESS , NULL , & hKey , & dwDisposition ) ;
// err, oops
if ( result ! = ERROR_SUCCESS )
return ;
dwValue = 1 ;
result = RegSetValueEx ( hKey , " EnableAutoDisconnect " , NULL , REG_BINARY , ( LPBYTE ) & dwValue , sizeof ( DWORD ) ) ;
// default auto-disconnect after 5 minutes
if ( disconnectTime < 3 )
dwValue = 3 ;
else
dwValue = disconnectTime ;
result = RegSetValueEx ( hKey , " DisconnectIdleTime " , NULL , REG_BINARY , ( LPBYTE ) & dwValue , sizeof ( DWORD ) ) ;
RegCloseKey ( hKey ) ;
} else { // NT40
// we need to convert disconnectTime to # of seconds for NT40
dwValue = ( disconnectTime * 60 ) ;
result = RegOpenKeyEx ( HKEY_USERS , " .DEFAULT \\ Software \\ Microsoft \\ RAS Phonebook " , NULL , KEY_ALL_ACCESS , & hKey ) ;
if ( result ! = ERROR_SUCCESS )
return ;
// now set the auto disconnect seconds
result = RegSetValueEx ( hKey , " IdleHangupSeconds " , NULL , REG_DWORD , ( LPBYTE ) & dwValue , sizeof ( DWORD ) ) ;
RegCloseKey ( hKey ) ;
}
return ;
}
//********************************************************************************
// CheckDNS
// for Win95
// If user has DNS enabled, when setting up an account, we need to warn them
// that there might be problems.
//********************************************************************************
void CheckDNS ( )
{
char buf [ 256 ] ;
HKEY hKey ;
DWORD cbData ;
LONG res ;
// open the key if registry
if ( ERROR_SUCCESS ! = RegOpenKeyEx ( HKEY_LOCAL_MACHINE ,
" System \\ CurrentControlSet \\ Services \\ VxD \\ MSTCP " ,
NULL ,
KEY_ALL_ACCESS ,
& hKey ) )
return ;
cbData = sizeof ( buf ) ;
res = RegQueryValueEx ( hKey , " EnableDNS " , NULL , NULL , ( LPBYTE ) buf , & cbData ) ;
RegCloseKey ( hKey ) ;
// if DNS is enabled we need to warn the user
if ( buf [ 0 ] = = ' 1 ' )
{
BOOL correctWinsockVersion = FALSE ;
// check for user's winsock version first, see if it's winsock2
WORD wVersionRequested ;
WSADATA wsaData ;
int err ;
wVersionRequested = MAKEWORD ( 2 , 2 ) ;
err = WSAStartup ( wVersionRequested , & wsaData ) ;
if ( err ! = 0 )
{
// user doesn't have winsock2, so check their winsock's date
char winDir [ MAX_PATH ] ;
UINT uSize = MAX_PATH ;
char winsockFile [ MAX_PATH ] ;
winDir [ 0 ] = ' \0 ' ;
winsockFile [ 0 ] = ' \0 ' ;
GetWindowsDirectory ( ( char * ) & winDir , uSize ) ;
strcpy ( winsockFile , winDir ) ;
strcat ( winsockFile , " \\ winsock.dll " ) ;
HANDLE hfile = CreateFile ( ( char * ) & winsockFile , GENERIC_READ , 0 , NULL ,
OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL ) ;
if ( hfile ! = INVALID_HANDLE_VALUE )
{
// openned file is valid
FILETIME lastWriteTime ;
BOOL rtnval = GetFileTime ( hfile , NULL , NULL , & lastWriteTime ) ;
SYSTEMTIME systemTime ;
rtnval = FileTimeToSystemTime ( & lastWriteTime , & systemTime ) ;
// perfect example of why Windows software is so awful
if ( ( systemTime . wYear > = 1996 ) & & ( systemTime . wMonth > = 8 ) & &
( systemTime . wDay > = 24 ) )
correctWinsockVersion = TRUE ;
CloseHandle ( hfile ) ;
}
}
else
correctWinsockVersion = TRUE ;
if ( ! correctWinsockVersion )
{
// Err: Your system is configured for another Domain Name System (DNS) server.
// You might need to edit your DNS configuration. Check the User's Guide
// for more information.
char buf [ 255 ] ;
if ( getMsgString ( buf , IDS_DNS_ALREADY ) )
displayErrMsgWnd ( buf , MB_OK | MB_ICONASTERISK , NULL ) ;
}
}
return ;
}
//********************************************************************************
// CheckDUN
// for Win95
// If user doesn't have Dial-Up Networking installed, they will have problem
// setting up an account.
//********************************************************************************
BOOL CheckDUN ( )
{
static const char c_szRNA [ ] = " rundll.exe setupx.dll,InstallHinfSection RNA 0 rna.inf " ;
BOOL bInstall = FALSE ;
HKEY hKey ;
LONG res ;
char szBuf [ MAX_PATH ] ;
// Let's see if its installed
if ( ERROR_SUCCESS ! = RegOpenKeyEx ( HKEY_LOCAL_MACHINE ,
" SOFTWARE \\ Microsoft \\ Windows \\ CurrentVersion \\ Setup \\ OptionalComponents \\ RNA " ,
NULL ,
KEY_QUERY_VALUE ,
& hKey ) )
bInstall = TRUE ;
// the key is there, was it actually installed though...
if ( ! bInstall )
{
DWORD cbData = sizeof ( szBuf ) ;
res = RegQueryValueEx ( hKey , " Installed " , NULL , NULL , ( LPBYTE ) szBuf , & cbData ) ;
if ( szBuf [ 0 ] ! = ' 1 ' & & szBuf [ 0 ] ! = ' Y ' & & szBuf [ 0 ] ! = ' y ' )
bInstall = TRUE ;
}
// make sure a random file from the installation exists so that we
// know the user actually installed instead of just skipping over
// the install step
if ( ! bInstall )
{
if ( GetSystemDirectory ( szBuf , sizeof ( szBuf ) ) )
{
// create a name of one of the files
strcat ( szBuf , " \\ pppmac.vxd " ) ;
// let's see if that file exists
struct _stat stat_struct ;
if ( _stat ( szBuf , & stat_struct ) ! = 0 )
bInstall = TRUE ;
}
}
// if no Dial-Up Networking installed install it now
if ( bInstall )
{
// let the user not install it or exit
//
// Err: Dial-Up Networking has not been installed on this machine;
// this product will not work until Dial-Up Networking is installed.
// Would you like to install Dial-Up Networking now?
char * buf = ( char * ) malloc ( sizeof ( char ) * 255 ) ;
if ( ! buf )
// Err: Out of Memory
return FALSE ;
if ( getMsgString ( buf , IDS_NO_DUN ) )
{
if ( IDOK ! = displayErrMsgWnd ( buf , MB_OKCANCEL | MB_ICONASTERISK , NULL ) )
{
free ( buf ) ;
return FALSE ;
}
}
free ( buf ) ;
// install Dial-Up Networking
PROCESS_INFORMATION pi ;
STARTUPINFO sti ;
UINT err = ERROR_SUCCESS ;
memset ( & sti , 0 , sizeof ( sti ) ) ;
sti . cb = sizeof ( STARTUPINFO ) ;
// Run the setup application
if ( CreateProcess ( NULL , ( LPSTR ) c_szRNA ,
NULL , NULL , FALSE , 0 , NULL , NULL , & sti , & pi ) )
{
CloseHandle ( pi . hThread ) ;
// Wait for the modem wizard process to complete
WaitForSingleObject ( pi . hProcess , INFINITE ) ;
CloseHandle ( pi . hProcess ) ;
}
}
RegCloseKey ( hKey ) ;
return TRUE ;
}
//********************************************************************************
// check if a user is an Administrator on NT40
//********************************************************************************
static BOOL isWinNTAdmin ( )
{
HANDLE hAccessToken ;
UCHAR infoBuffer [ 1024 ] ;
PTOKEN_GROUPS ptgGroups = ( PTOKEN_GROUPS ) infoBuffer ;
DWORD dwInfoBufferSize ;
PSID psidAdministrators ;
SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY ;
UINT x ;
BOOL bSuccess ;
if ( ! OpenProcessToken ( GetCurrentProcess ( ) , TOKEN_READ , & hAccessToken ) )
return FALSE ;
bSuccess = GetTokenInformation ( hAccessToken , TokenGroups , infoBuffer ,
1024 , & dwInfoBufferSize ) ;
CloseHandle ( hAccessToken ) ;
if ( ! bSuccess )
return FALSE ;
if ( ! AllocateAndInitializeSid ( & siaNtAuthority , 2 ,
SECURITY_BUILTIN_DOMAIN_RID ,
DOMAIN_ALIAS_RID_ADMINS ,
0 , 0 , 0 , 0 , 0 , 0 ,
& psidAdministrators ) )
return FALSE ;
// assume that we don't find the admin SID.
bSuccess = FALSE ;
for ( x = 0 ; x < ptgGroups - > GroupCount ; x + + )
{
if ( EqualSid ( psidAdministrators , ptgGroups - > Groups [ x ] . Sid ) )
{
bSuccess = TRUE ;
break ;
}
}
FreeSid ( & psidAdministrators ) ;
return bSuccess ;
}
//********************************************************************************
// CheckDUN_NT
// for WinNT40
// If user doesn't have Dial-Up Networking installed, they will have problem
// setting up an account.
//********************************************************************************
BOOL CheckDUN_NT ( )
{
BOOL bInstall = FALSE ;
BOOL bAdmin = FALSE ;
HKEY hKey ;
LONG res ;
char szBuf [ MAX_PATH ] ;
char * buf = NULL ;
// Let's see if its installed
// "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\RemoteAccess"
if ( ERROR_SUCCESS ! = RegOpenKeyEx ( HKEY_LOCAL_MACHINE ,
" SYSTEM \\ CurrentControlSet \\ Services \\ RemoteAccess " ,
NULL ,
KEY_QUERY_VALUE ,
& hKey ) )
bInstall = TRUE ;
// the key is there, was it actually installed though...
// look for some RAS keys
szBuf [ 0 ] = ' \0 ' ;
if ( ! bInstall )
{
DWORD cbData = sizeof ( szBuf ) ;
res = RegQueryValueEx ( hKey , " DisplayName " , NULL , NULL , ( LPBYTE ) szBuf , & cbData ) ;
if ( strlen ( szBuf ) = = 0 )
bInstall = TRUE ;
RegCloseKey ( hKey ) ;
// how about autodial manager....
// "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\RasAuto"
if ( ERROR_SUCCESS ! = RegOpenKeyEx ( HKEY_LOCAL_MACHINE ,
" SYSTEM \\ CurrentControlSet \\ Services \\ RasAuto " ,
NULL ,
KEY_QUERY_VALUE ,
& hKey ) )
bInstall = TRUE ;
RegCloseKey ( hKey ) ;
}
// if no Dial-Up Networking installed, warn the users depending on
// their premissions and return FALSE
if ( bInstall )
{
bAdmin = isWinNTAdmin ( ) ;
if ( bAdmin )
{
// Err: Dial-Up Networking has not been installed on this machine;
// this product will not work until Dial-Up Networking is installed.
// Pleas install Dial-Up Networking before running Accout Setup.
char buf [ 255 ] ;
if ( getMsgString ( buf , IDS_NO_DUN_NT ) )
displayErrMsgWnd ( buf , MB_OK | MB_ICONASTERISK , NULL ) ;
#if 0
// install Dial-Up Networking
PROCESS_INFORMATION pi ;
STARTUPINFO sti ;
UINT err = ERROR_SUCCESS ;
char RASphone [ MAX_PATH ] ;
GetSystemDirectory ( RASphone , MAX_PATH ) ;
strcat ( RASphone , " \\ rasphone.exe " ) ;
memset ( & sti , 0 , sizeof ( sti ) ) ;
sti . cb = sizeof ( STARTUPINFO ) ;
// Run the setup application
if ( CreateProcess ( ( LPCTSTR ) & RASphone , NULL ,
NULL , NULL , FALSE , 0 , NULL , NULL , & sti , & pi ) )
{
CloseHandle ( pi . hThread ) ;
// Wait for the Dial-Up Networking install process to complete
WaitForSingleObject ( pi . hProcess , INFINITE ) ;
CloseHandle ( pi . hProcess ) ;
}
# endif
}
else
{
// user need to have administrator premission to install, and ASW won't
// work if DUN is not installed
// Err: You do not have Administrator premission on this machine to intall
// Dial-Up Networking. Please make sure you have Administrator premission
// in order to install Dial-Up Networking first before running Account Setup.
char buf [ 255 ] ;
if ( getMsgString ( buf , IDS_NO_ADMIN_PREMISSION ) )
displayErrMsgWnd ( buf , MB_OK | MB_ICONASTERISK , NULL ) ;
}
return FALSE ;
}
return TRUE ;
}
//********************************************************************************
// CreateDialerShortcut
// Creates a shell shortcut to the PIDL
//********************************************************************************
static short createDialerShortcut ( char * szDesktop , // Desktop path
LPCSTR accountName , // connectoid/phonebook entry name
IMalloc * pMalloc ,
char * szPath , // path to PE folder
char * strDesc ,
char * iconPath ) // shortcut description
{
HRESULT hres ;
LPITEMIDLIST pidl ;
char desktop [ MAX_PATH ] ;
DWORD cbData ;
HKEY hKey ;
long res ;
szDesktop [ 0 ] = ' \0 ' ;
// gets Desktop folder path from registry for both win95 & winNT40
// "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"
if ( ERROR_SUCCESS ! = RegOpenKeyEx ( HKEY_CURRENT_USER ,
REGSTR_PATH_SPECIAL_FOLDERS ,
NULL ,
KEY_QUERY_VALUE ,
& hKey ) )
return - 3 ; // huh?
cbData = MAX_PATH ;
res = RegQueryValueEx ( hKey , " Desktop " , NULL , NULL , ( LPBYTE ) desktop , & cbData ) ;
RegCloseKey ( hKey ) ;
strcpy ( szDesktop , desktop ) ;
// win95 only
if ( gPlatformOS = = VER_PLATFORM_WIN32_WINDOWS )
{
// Get a PIDL that points to the dial-up connection
hres = getDialUpConnectionPIDL ( accountName , & pidl ) ;
if ( FAILED ( hres ) )
{
// Err: Unable to create shortcut to RNA phone book entry
char * buf = ( char * ) malloc ( sizeof ( char ) * 255 ) ;
if ( ! buf )
// Err: Out of Memory
return - 6 ; // huh?
if ( getMsgString ( buf , IDS_NO_RNA ) )
{
if ( IDOK ! = displayErrMsgWnd ( buf , MB_OK | MB_ICONEXCLAMATION , NULL ) )
{
free ( buf ) ;
return FALSE ;
}
}
free ( buf ) ;
return - 1 ;
}
// If the dial-up networking folder is open when we create the RNA
// entry, then we will have failed to get a PIDL above. The dial-up
// networking folder itself won't display the icon until it is closed
// and re-opened. There's nothing we can do but return
if ( ! pidl )
{
pMalloc - > Release ( ) ;
return - 2 ; // huh?
}
// Create a shortcut on the desktop
char strPath [ MAX_PATH ] ;
strcpy ( strPath , szDesktop ) ;
strcat ( strPath , " \\ " ) ;
strcat ( strPath , strDesc ) ;
strcat ( strPath , " .Lnk " ) ;
createLink ( pidl , strPath , strDesc , iconPath ) ;
// And one in our PE folder
strcpy ( strPath , szPath ) ;
strcat ( strPath , " \\ " ) ;
strcat ( strPath , strDesc ) ;
strcat ( strPath , " .Lnk " ) ;
createLink ( pidl , strPath , strDesc , iconPath ) ;
}
else if ( gPlatformOS = = VER_PLATFORM_WIN32_NT )
{
// WinNT40 here
// make sure the phonebook entry we created still exists
char * sysDir = ( char * ) malloc ( sizeof ( char ) * MAX_PATH ) ;
if ( ! sysDir )
return - 5 ; // huh?
char pbPath [ MAX_PATH ] ;
GetSystemDirectory ( sysDir , MAX_PATH ) ;
strcpy ( pbPath , sysDir ) ;
strcat ( pbPath , " \\ ras \\ rasphone.pbk " ) ;
strcat ( pbPath , " \0 " ) ;
free ( sysDir ) ;
RASENTRYNAME rasEntryName [ MAX_PATH ] ;
if ( ! rasEntryName )
return - 7 ; // huh?
rasEntryName [ 0 ] . dwSize = stRASENTRYNAME ;
DWORD size = stRASENTRYNAME * MAX_PATH ;
DWORD entries ;
if ( 0 ! = RasEnumEntries ( NULL , pbPath , rasEntryName , & size , & entries ) )
return - 4 ;
BOOL exists = FALSE ;
DWORD i = 0 ;
while ( ( i < entries ) & & ( ! exists ) )
{
if ( strcmp ( rasEntryName [ i ] . szEntryName , accountName ) = = 0 )
exists = TRUE ;
i + + ;
}
// create a shortcut file on desktop
if ( exists )
{
HANDLE hfile = NULL ;
// create phonebook entry shortcut file on desktop, overwrites if exists
SECURITY_ATTRIBUTES secAttrib ;
memset ( & secAttrib , 0 , sizeof ( SECURITY_ATTRIBUTES ) ) ;
secAttrib . nLength = sizeof ( SECURITY_ATTRIBUTES ) ;
secAttrib . lpSecurityDescriptor = NULL ;
secAttrib . bInheritHandle = FALSE ;
// construct phonebook entry shortcut file name
char file [ MAX_PATH ] ;
strcpy ( file , szDesktop ) ;
strcat ( file , " \\ " ) ;
strcat ( file , accountName ) ;
strcat ( file , " .rnk " ) ;
hfile = CreateFile ( file , GENERIC_READ | GENERIC_WRITE , FILE_SHARE_READ | FILE_SHARE_WRITE ,
& secAttrib , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL ) ;
if ( hfile = = INVALID_HANDLE_VALUE )
return - 9 ; // huh?
CloseHandle ( hfile ) ;
hfile = NULL ;
// writes shortcut file data in the following format:
// [Dial-Up Shortcut]
// Entry=stuff
// Phonebook=C:\WINNT40\System32\RAS\rasphone.pbk (default system phonebook)
WritePrivateProfileString ( " Dial-Up Shortcut " , " Entry " , accountName , file ) ;
WritePrivateProfileString ( " Dial-Up Shortcut " , " Phonebook " , pbPath , file ) ;
// create the same shortcut file in our PE folder
strcpy ( file , szPath ) ;
strcat ( file , " \\ " ) ;
strcat ( file , accountName ) ;
strcat ( file , " .rnk " ) ;
hfile = CreateFile ( file , GENERIC_READ | GENERIC_WRITE , FILE_SHARE_READ | FILE_SHARE_WRITE ,
& secAttrib , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL ) ;
if ( hfile = = INVALID_HANDLE_VALUE )
return - 10 ;
CloseHandle ( hfile ) ;
WritePrivateProfileString ( " Dial-Up Shortcut " , " Entry " , accountName , file ) ;
WritePrivateProfileString ( " Dial-Up Shortcut " , " Phonebook " , pbPath , file ) ;
}
else
return - 8 ; // huh?
}
return 0 ;
}
//********************************************************************************
// createProgramItems
// adds 2 icons:
// Dialer - to Dial-Up Networking folder, Desktop & our PE folder
// Navigator - to our PE folder
//********************************************************************************
static short createProgramItems ( LPCSTR accountName , LPCSTR iniPath , char * iconFile )
{
char szPath [ MAX_PATH ] ;
LPITEMIDLIST pidl ;
char szBuf [ MAX_PATH ] ;
IMalloc * pMalloc ;
SHGetMalloc ( & pMalloc ) ;
// gets the path to "Programs" folder
if ( gPlatformOS = = VER_PLATFORM_WIN32_WINDOWS )
{
SHGetSpecialFolderLocation ( NULL , CSIDL_PROGRAMS , & pidl ) ;
SHGetPathFromIDList ( pidl , szBuf ) ;
pMalloc - > Free ( pidl ) ;
}
else if ( gPlatformOS = = VER_PLATFORM_WIN32_NT )
{
// NT4.0: get the "Programs" folder for "All Users"
HKEY hKey ;
DWORD bufsize = sizeof ( szBuf ) ;
if ( ERROR_SUCCESS = = RegOpenKeyEx ( HKEY_LOCAL_MACHINE ,
" SOFTWARE \\ Microsoft \\ Windows NT \\ CurrentVersion " ,
NULL ,
KEY_QUERY_VALUE ,
& hKey ) )
{
RegQueryValueEx ( hKey , " PathName " , NULL , NULL , ( LPBYTE ) szBuf , & bufsize ) ;
strcat ( szBuf , " \\ Profiles \\ All Users \\ Start Menu \\ Programs " ) ;
}
else
return - 1 ;
}
// gets Netscape PE folder here
char buf [ 256 ] ;
char * csFolderName ;
csFolderName = ( char * ) malloc ( sizeof ( char ) * 256 ) ;
if ( ! csFolderName )
return - 4 ; // huh?
strcpy ( csFolderName , " Netscape Personal Edition " ) ;
// check for custom folder name
if ( : : GetPrivateProfileString (
" General " ,
" InstallFolder " ,
( const char * ) csFolderName ,
buf , sizeof ( buf ) ,
iniPath ) )
strcpy ( csFolderName , buf ) ;
strcpy ( szPath , szBuf ) ;
strcat ( szPath , " \\ " ) ;
strcat ( szPath , csFolderName ) ;
free ( csFolderName ) ;
// First do Dialer Icon
// Create a dialer icon shortcut description
char strDesc [ MAX_PATH ] ;
# ifdef UPGRADE
if ( ? ? ? entryInfo . bUpgrading )
{
char * csTmp = " Dialer " ;
strcpy ( strDesc , accountName ) ;
strcat ( strDesc , " " ) ;
strcat ( strDesc , csTmp ) ;
}
else
{
strcpy ( strDesc , " Dial " ) ;
strcat ( strDesc , " " ) ;
strcat ( strDesc , accountName ) ;
}
# else
strcpy ( strDesc , " Dial " ) ;
strDesc [ strlen ( strDesc ) + 1 ] = ' \0 ' ;
strDesc [ strlen ( strDesc ) ] = ( char ) 32 ;
strcat ( strDesc , accountName ) ;
# endif
char szDesktop [ 512 ] ;
// create dialer shortcut icon on desktop and in PE folder
int rtn = createDialerShortcut ( szDesktop , accountName , pMalloc , szPath , strDesc , iconFile ) ;
if ( rtn ! = 0 )
return rtn ;
# ifdef FOLDER_IN_START_MENU
// Cleanup
pMalloc - > Free ( pidl ) ;
pMalloc - > Release ( ) ;
# endif
: : Sleep ( 250 ) ;
return 0 ;
}
//********************************************************************************
// DesktopConfig
// Sets up user's desktop (creates icons and short cuts)
//********************************************************************************
void DesktopConfig ( char * accountName , char * iconFileName ,
char * acctsetIniPath )
{
static char lastIconFile [ _MAX_PATH ] = { ' \0 ' } ;
if ( iconFileName ! = NULL )
{
// JS may pass us different file for icon file
if ( ( iconFileName ) & & ( strcmp ( iconFileName , lastIconFile ) ! = 0 ) )
{
if ( strcmp ( lastIconFile , " " ) ! = 0 )
{
if ( fileExists ( lastIconFile ) ) // a temp icon file may already existed
_unlink ( lastIconFile ) ;
}
// check if icon file exists
if ( fileExists ( iconFileName ) )
strcpy ( lastIconFile , iconFileName ) ;
else
lastIconFile [ 0 ] = ' \0 ' ;
}
}
// remove the RegiServer RAS
char regiRAS [ 50 ] ;
getMsgString ( ( char * ) regiRAS , IDS_REGGIE_PROGITEM_NAME ) ;
( * m_lpfnRasDeleteEntry ) ( NULL , ( LPSTR ) regiRAS ) ;
// creates prgram icons in folders and desktop
int ret = createProgramItems ( accountName , acctsetIniPath , lastIconFile ) ;
}
//********************************************************************************
// QuitNavigator
// quits the navigator
//********************************************************************************
void QuitNavigator ( )
{
// Bug#112622 - don't broadcast this, java catches it and dies.
// Instead, find the hidden window and tell _it_ what to do.
// The strings in this call are hard-coded because the constants needed
// do not exist and multiple places are doing similar things. The
// values themselves come from winfe's Netscape.cpp.
HWND hWnd = FindWindowEx ( NULL , NULL , " aHiddenFrameClass " , " Netscape's Hidden Frame " ) ;
PostMessage ( /*HWND_BROADCAST*/ hWnd , WM_COMMAND , ID_APP_SUPER_EXIT , 0L ) ;
}
//********************************************************************************
// getCurrentProfileDirectory
// gets the current Navigator user profile directory
//********************************************************************************
extern char * GetCurrentProfileDirectory ( )
{
char * profilePath = NULL ;
int bufSize = 256 ;
char buf [ 256 ] ;
buf [ 0 ] = ' \0 ' ;
if ( PREF_OK = = PREF_GetCharPref ( " profile.directory " , buf , & bufSize ) )
{
// make sure we append the last '\' in the profile dir path
strcat ( buf , " \\ " ) ;
trace ( " profile.cpp : GetCurrentProfileDirectory : Got the Current User profile = %s " , buf ) ;
}
else
trace ( " profile.cpp : GetCurrentProfileDirectory : Error in obtaining Current User profile " ) ;
profilePath = strdup ( buf ) ;
return profilePath ;
}
//********************************************************************************
// GetCurrentProfileName
// gets the current Navigator user profile name
//********************************************************************************
extern char * GetCurrentProfileName ( )
{
char * profileName = NULL ;
int bufSize = 256 ;
char buf [ 256 ] ;
buf [ 0 ] = ' \0 ' ;
if ( PREF_OK = = PREF_GetCharPref ( " profile.name " , buf , & bufSize ) )
trace ( " profile.cpp : GetCurrentProfileDirectory : Got the Current profile name = %s " , buf ) ;
else
trace ( " profile.cpp : GetCurrentProfileName : Error in obtaining Current User profile " ) ;
profileName = strdup ( buf ) ;
return profileName ;
}
//********************************************************************************
// SetCurrentProfileName
// changes the current Navigator user profile name to a different name
//********************************************************************************
void SetCurrentProfileName ( char * profileName )
{
assert ( profileName ) ;
if ( NULL = = profileName ) // abort if string allocation fails
return ;
if ( PREF_ERROR = = PREF_SetDefaultCharPref ( " profile.name " , profileName ) )
trace ( " profile.cpp : SetCurrentProfileName : Error in setting Current User profile name. " ) ;
else
{
trace ( " profile.cpp : SetCurrentProfileName : Current User profile is set to = %s " , profileName ) ;
if ( PREF_ERROR = = PREF_SetDefaultBoolPref ( " profile.temporary " , FALSE ) )
trace ( " profile.cpp : SetCurrentProfileName : Error in setting Temporary flag to false. " ) ;
else
trace ( " profile.cpp : SetCurrentProfileName : Made the profile to be permanent. " ) ;
}
}
// The format of the entry is
// LocationX=Y,"name","outside-line-local","outside-line-long-D","area-code",1,0,0,1,"",tone=0,"call-waiting-string"
typedef struct tapiLineStruct
{
int nIndex ;
char csLocationName [ 60 ] ;
char csOutsideLocal [ 20 ] ;
char csOutsideLongDistance [ 20 ] ;
char csAreaCode [ 20 ] ;
int nCountryCode ;
int nCreditCard ;
int nDunnoB ;
int nDunnoC ;
char csDialAsLongDistance [ 10 ] ;
int nPulseDialing ;
char csCallWaiting [ 20 ] ;
} TAPILINE ;
//********************************************************************************
// readNextInt
// Pull an int off the front of the string and return the new string ptr
//********************************************************************************
char * readNextInt ( char * pInString , int * pInt )
{
char * pStr ;
char buf [ 32 ] ;
if ( ! pInString )
{
* pInt = 0 ;
return NULL ;
}
// copy the string over. This strchr should be smarter
pStr = strchr ( pInString , ' , ' ) ;
if ( ! pStr )
{
* pInt = 0 ;
return NULL ;
}
// convert the string
strncpy ( buf , pInString , pStr - pInString ) ;
buf [ pStr - pInString ] = ' \0 ' ;
* pInt = atoi ( buf ) ;
// return the part after the int
return ( pStr + 1 ) ;
}
//********************************************************************************
// readNextString
// Pull a string from the front of the incoming string and return
// the first character after the string
//********************************************************************************
char * readNextString ( char * pInString , char * csString )
{
csString [ 0 ] = ' \0 ' ;
int i = 0 , x = 0 ;
BOOL copy = FALSE ;
char newpInString [ MAX_PATH ] ;
if ( ! pInString )
{
csString = " " ;
return NULL ;
}
// skip over first quote
if ( pInString [ i ] = = ' \" ' )
i + + ;
// copy over stuff by hand line a moron
while ( pInString [ i ] ! = ' \" ' )
{
//strcat(csString, (char *)pInString[i]);
csString [ x ] = pInString [ i ] ;
i + + ;
x + + ;
copy = TRUE ;
}
if ( copy )
csString [ x ] = ' \0 ' ;
// skip over the closing quote
if ( pInString [ i ] = = ' \" ' )
i + + ;
// skip over the comma at the end
if ( pInString [ i ] = = ' , ' )
i + + ;
newpInString [ 0 ] = ' \0 ' ;
x = 0 ;
for ( unsigned short j = i ; j < strlen ( pInString ) ; j + + )
{
//strcat(newpInString, (char *)pInString[j]);
newpInString [ x ] = pInString [ j ] ;
x + + ;
}
newpInString [ x ] = ' \0 ' ;
strcpy ( pInString , newpInString ) ;
return pInString ;
}
//********************************************************************************
// readTapiLine
// Read a line out of the telephon.ini file and fill the stuff in
//********************************************************************************
void readTapiLine ( char * lpszFile , int nLineNumber , TAPILINE * line )
{
char buf [ 256 ] ;
char pLocation [ 128 ] ;
sprintf ( pLocation , " Location%d " , nLineNumber ) ;
: : GetPrivateProfileString ( " Locations " , pLocation , " " , buf , sizeof ( buf ) , lpszFile ) ;
char * pString = buf ;
pString = readNextInt ( pString , & line - > nIndex ) ;
pString = readNextString ( pString , ( char * ) & line - > csLocationName ) ;
pString = readNextString ( pString , ( char * ) & line - > csOutsideLocal ) ;
pString = readNextString ( pString , ( char * ) & line - > csOutsideLongDistance ) ;
pString = readNextString ( pString , ( char * ) & line - > csAreaCode ) ;
pString = readNextInt ( pString , & line - > nCountryCode ) ;
pString = readNextInt ( pString , & line - > nCreditCard ) ;
pString = readNextInt ( pString , & line - > nDunnoB ) ;
pString = readNextInt ( pString , & line - > nDunnoC ) ;
pString = readNextString ( pString , ( char * ) & line - > csDialAsLongDistance ) ;
pString = readNextInt ( pString , & line - > nPulseDialing ) ;
pString = readNextString ( pString , ( char * ) & line - > csCallWaiting ) ;
}
//********************************************************************************
// writeTapiLine
// Given a tapiLine structure write it out to telephon.ini
//********************************************************************************
void writeTapiLine ( char * lpszFile , int nLineNumber , TAPILINE * line )
{
char buffer [ 256 ] ;
sprintf ( buffer , " %d, \" %s \" , \" %s \" , \" %s \" , \" %s \" ,%d,%d,%d,%d, \" %s \" ,%d, \" %s \" " ,
line - > nIndex ,
( const char * ) line - > csLocationName ,
( const char * ) line - > csOutsideLocal ,
( const char * ) line - > csOutsideLongDistance ,
( const char * ) line - > csAreaCode ,
line - > nCountryCode ,
line - > nCreditCard ,
line - > nDunnoB ,
line - > nDunnoC ,
( const char * ) line - > csDialAsLongDistance ,
line - > nPulseDialing ,
( const char * ) line - > csCallWaiting ) ;
char pLocation [ 32 ] ;
sprintf ( pLocation , " Location%d " , nLineNumber ) ;
: : WritePrivateProfileString ( " Locations " , pLocation , buffer , lpszFile ) ;
}
//********************************************************************************
// SetLocationInfo
// sets the location info for win95 dialers
// The format of the entry is
// LocationX=Y,"name","outside-line-local","outside-line-long-D","area-code",1,0,0,1,"",tone=0,"call-waiting-string"
//********************************************************************************
BOOL SetLocationInfo ( ACCOUNTPARAMS account , LOCATIONPARAMS location )
{
// first read information from telephon.ini
char buf [ 256 ] ;
// get windows directory
char lpszDir [ MAX_PATH ] ;
if ( GetWindowsDirectory ( lpszDir , MAX_PATH ) = = 0 )
return FALSE ; // huh?
strcat ( lpszDir , " \\ telephon.ini " ) ;
// now we build new line information based on the old one and some info
// see if there were any locations to begin with
: : GetPrivateProfileString ( " Locations " , " CurrentLocation " , " " , buf , sizeof ( buf ) , lpszDir ) ;
if ( buf [ 0 ] = = ' \0 ' )
{
// build the string
TAPILINE line ;
line . nIndex = 0 ;
strcpy ( line . csLocationName , " Default Location " ) ;
strcpy ( line . csOutsideLocal , location . OutsideLineAccess ) ;
strcpy ( line . csOutsideLongDistance , location . OutsideLineAccess ) ;
strcpy ( line . csAreaCode , location . UserAreaCode ) ;
line . nCountryCode = location . UserCountryCode ;
line . nCreditCard = 0 ;
line . nDunnoB = 0 ;
line . nDunnoC = 1 ;
if ( location . DialAsLongDistance = = TRUE )
strcpy ( line . csDialAsLongDistance , " 528 " ) ;
else
strcpy ( line . csDialAsLongDistance , " " ) ;
line . nPulseDialing = ( location . DialType = = 0 ? 1 : 0 ) ;
if ( location . DisableCallWaiting )
strcpy ( line . csCallWaiting , location . DisableCallWaitingCode ) ;
else
strcpy ( line . csCallWaiting , " " ) ;
writeTapiLine ( lpszDir , 0 , & line ) ;
// need to create a whole location section
: : WritePrivateProfileString ( " Locations " , " CurrentLocation " , " 0,0 " , lpszDir ) ;
: : WritePrivateProfileString ( " Locations " , " Locations " , " 1,1 " , lpszDir ) ;
: : WritePrivateProfileString ( " Locations " , " Inited " , " 1 " , lpszDir ) ;
}
else
{
int nId , nCount ;
sscanf ( buf , " %d,%d " , & nId , & nCount ) ;
// read the line
TAPILINE line ;
readTapiLine ( lpszDir , nId , & line ) ;
strcpy ( line . csOutsideLocal , location . OutsideLineAccess ) ;
strcpy ( line . csOutsideLongDistance , location . OutsideLineAccess ) ;
if ( location . DisableCallWaiting )
strcpy ( line . csCallWaiting , location . DisableCallWaitingCode ) ;
else
strcpy ( line . csCallWaiting , " " ) ;
line . nPulseDialing = ( location . DialType = = 0 ? 1 : 0 ) ;
if ( strcmp ( location . UserAreaCode , " " ) ! = 0 )
strcpy ( line . csAreaCode , location . UserAreaCode ) ;
if ( location . DialAsLongDistance = = TRUE )
strcpy ( line . csDialAsLongDistance , " 528 " ) ;
else
strcpy ( line . csDialAsLongDistance , " " ) ;
// write the line back out
writeTapiLine ( lpszDir , nId , & line ) ;
}
return TRUE ;
}
//********************************************************************************
// SetLocationInfoNT
// sets the location info for winNT dialers
//********************************************************************************
BOOL SetLocationInfoNT ( ACCOUNTPARAMS account , LOCATIONPARAMS location )
{
LINEINITIALIZEEXPARAMS m_LineInitExParams ;
HLINEAPP m_LineApp ;
DWORD dwNumDevs ;
LINETRANSLATECAPS m_LineTranslateCaps ;
DWORD dwApiVersion = 0x00020000 ;
// Initialize TAPI. in order to get current location ID
m_LineInitExParams . dwOptions = LINEINITIALIZEEXOPTION_USEEVENT ;
m_LineInitExParams . dwTotalSize = sizeof ( LINEINITIALIZEEXPARAMS ) ;
m_LineInitExParams . dwNeededSize = sizeof ( LINEINITIALIZEEXPARAMS ) ;
if ( lineInitialize ( & m_LineApp , gDLL , lineCallbackFuncNT , NULL , & dwNumDevs ) ! = 0 )
{
char buf [ 255 ] ;
if ( getMsgString ( buf , IDS_NO_TAPI ) )
displayErrMsgWnd ( buf , MB_OK | MB_ICONEXCLAMATION , NULL ) ;
return FALSE ;
}
m_LineTranslateCaps . dwTotalSize = sizeof ( LINETRANSLATECAPS ) ;
m_LineTranslateCaps . dwNeededSize = sizeof ( LINETRANSLATECAPS ) ;
if ( lineGetTranslateCaps ( m_LineApp , dwApiVersion , & m_LineTranslateCaps ) ! = 0 )
return FALSE ;
//m_LineTranslateCaps.dwCurrentLocationID
// gets the location info from registry
HKEY hKey ;
char * keyPath = ( char * ) malloc ( sizeof ( char ) * 512 ) ;
assert ( keyPath ) ;
if ( ! keyPath )
return FALSE ;
strcpy ( keyPath , " SOFTWARE \\ Microsoft \\ Windows \\ CurrentVersion \\ Telephony \\ locations " ) ;
// finds the user profile location in registry
if ( ERROR_SUCCESS ! = RegOpenKeyEx ( HKEY_LOCAL_MACHINE , keyPath , NULL , KEY_ALL_ACCESS , & hKey ) )
return FALSE ;
DWORD subKeys ;
DWORD maxSubKeyLen ;
DWORD maxClassLen ;
DWORD values ;
DWORD maxValueNameLen ;
DWORD maxValueLen ;
DWORD securityDescriptor ;
FILETIME lastWriteTime ;
// get some information about this reg key
if ( ERROR_SUCCESS ! = RegQueryInfoKey ( hKey , NULL , NULL , NULL , & subKeys , & maxSubKeyLen , & maxClassLen , & values , & maxValueNameLen , & maxValueLen , & securityDescriptor , & lastWriteTime ) )
return FALSE ;
// now loop through the location keys to find the one that matches current location ID
if ( subKeys > 0 )
{
DWORD subkeyNameSize = maxSubKeyLen + 1 ;
char subkeyName [ 20 ] ;
for ( DWORD index = 0 ; index < subKeys ; index + + )
{
// gets a location key name
if ( ERROR_SUCCESS ! = RegEnumKey ( hKey , index , subkeyName , subkeyNameSize ) )
return FALSE ;
// try open location key
char newSubkeyPath [ 260 ] ;
HKEY hkeyNewSubkey ;
strcpy ( ( char * ) newSubkeyPath , keyPath ) ;
strcat ( ( char * ) newSubkeyPath , " \\ " ) ;
strcat ( ( char * ) newSubkeyPath , subkeyName ) ;
if ( ERROR_SUCCESS ! = RegOpenKeyEx ( HKEY_LOCAL_MACHINE , ( char * ) newSubkeyPath , NULL , KEY_ALL_ACCESS , & hkeyNewSubkey ) )
return FALSE ;
DWORD valbuf ;
DWORD type = REG_SZ ;
DWORD bufsize = 20 ;
// get location key's ID value
if ( ERROR_SUCCESS ! = RegQueryValueEx ( hkeyNewSubkey , " ID " , NULL , & type , ( LPBYTE ) & valbuf , & bufsize ) )
return FALSE ;
// if it matches the default location ID
if ( valbuf = = m_LineTranslateCaps . dwCurrentLocationID )
{
// we got the location we want, now change the pulse/tone flag
DWORD flagsVal ;
if ( location . DialType = = 0 )
if ( location . DisableCallWaiting )
flagsVal = 4 ;
else
flagsVal = 0 ;
else if ( location . DisableCallWaiting )
flagsVal = 5 ;
else
flagsVal = 1 ;
if ( ERROR_SUCCESS ! = RegSetValueEx ( hkeyNewSubkey , " Flags " , NULL , type , ( LPBYTE ) & flagsVal , bufsize ) )
return FALSE ;
// sets the OutsideAccess
if ( ERROR_SUCCESS ! = RegSetValueEx ( hkeyNewSubkey , " OutsideAccess " , NULL , REG_SZ , ( LPBYTE ) & location . OutsideLineAccess , strlen ( location . OutsideLineAccess ) + 1 ) )
return FALSE ;
if ( ERROR_SUCCESS ! = RegSetValueEx ( hkeyNewSubkey , " LongDistanceAccess " , NULL , REG_SZ , ( LPBYTE ) & location . OutsideLineAccess , strlen ( location . OutsideLineAccess ) + 1 ) )
return FALSE ;
// sets call waiting
char * callwaiting ;
if ( location . DisableCallWaiting )
callwaiting = location . DisableCallWaitingCode ;
else
callwaiting = " " ;
if ( ERROR_SUCCESS ! = RegSetValueEx ( hkeyNewSubkey , " DisableCallWaiting " , NULL , REG_SZ , ( LPBYTE ) callwaiting , strlen ( callwaiting ) + 1 ) )
return FALSE ;
// sets user's area code
if ( strcmp ( location . UserAreaCode , " " ) ! = 0 )
{
if ( ERROR_SUCCESS ! = RegSetValueEx ( hkeyNewSubkey , " AreaCode " , NULL , REG_SZ , ( LPBYTE ) location . UserAreaCode , strlen ( location . UserAreaCode ) + 1 ) )
return FALSE ;
}
else
{
// check if we're international, and force a default area code, so that we don't get an error creating a dialer
if ( account . IntlMode )
{
char * code = " 415 " ;
if ( ERROR_SUCCESS ! = RegSetValueEx ( hkeyNewSubkey , " AreaCode " , NULL , REG_SZ , ( LPBYTE ) code , strlen ( code ) + 1 ) )
return FALSE ;
}
}
RegCloseKey ( hkeyNewSubkey ) ;
break ;
}
RegCloseKey ( hkeyNewSubkey ) ;
}
}
RegCloseKey ( hKey ) ;
return TRUE ;
}
//********************************************************************************
// native method:
// CheckEnvironment
// checks for DUN, RAS function loading correctly
//********************************************************************************
BOOL CheckEnvironment ( )
{
// try loading RAS routines in RAS dlls
// if fails return FALSE
switch ( gPlatformOS )
{
case VER_PLATFORM_WIN32_NT : // NT
//check if it's WinNT40 first
if ( ! LoadRasFunctionsNT ( " RASAPI32.DLL " ) )
{
// Err: Unable to dynamically load extended RAS functions!
char * buf = ( char * ) malloc ( sizeof ( char ) * 255 ) ;
if ( buf )
{
if ( getMsgString ( buf , IDS_NO_RAS_FUNCTIONS ) )
displayErrMsgWnd ( buf , MB_OK | MB_ICONEXCLAMATION , NULL ) ;
free ( buf ) ;
}
return FALSE ;
}
break ;
case VER_PLATFORM_WIN32_WINDOWS : // defaults to win95
if ( ! LoadRasFunctions ( " RASAPI32.DLL " ) & & ! LoadRasFunctions ( " RNAPH.DLL " ) )
{
// Err: Unable to dynamically load extended RAS functions!
char * buf = ( char * ) malloc ( sizeof ( char ) * 255 ) ;
if ( buf )
{
if ( getMsgString ( buf , IDS_NO_RAS_FUNCTIONS ) )
displayErrMsgWnd ( buf , MB_OK | MB_ICONEXCLAMATION , NULL ) ;
free ( buf ) ;
}
return FALSE ;
}
break ;
}
// Check to make sure Dial-Up Networking is installed.
// It may be uninstalled by user.
// return FALSE if Dialup Networking is not installed
switch ( gPlatformOS )
{
case VER_PLATFORM_WIN32_NT :
if ( FALSE = = CheckDUN_NT ( ) )
{
char buf [ 255 ] ;
if ( getMsgString ( ( char * ) buf , IDS_NO_DUN_INSTALLED ) )
displayErrMsgWnd ( ( char * ) buf , MB_OK | MB_ICONEXCLAMATION , NULL ) ;
return FALSE ;
}
break ;
default :
if ( FALSE = = CheckDUN ( ) )
{
char buf [ 255 ] ;
if ( getMsgString ( ( char * ) buf , IDS_NO_DUN_INSTALLED ) )
displayErrMsgWnd ( ( char * ) buf , MB_OK | MB_ICONEXCLAMATION , NULL ) ;
return FALSE ;
}
break ;
}
// for win95 only:
// Check to see if DNS is already configured for a LAN connection.
// If so warn the user that this may cause conflicts, and continue.
if ( gPlatformOS = = VER_PLATFORM_WIN32_WINDOWS )
CheckDNS ( ) ;
return TRUE ;
}