mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 08:12:05 +00:00
3940 lines
112 KiB
C++
3940 lines
112 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public License
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
* http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
* for the specific language governing rights and limitations under the
|
|
* NPL.
|
|
*
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
* Reserved.
|
|
*/
|
|
//#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;\nproc 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;
|
|
}
|
|
|
|
|