diff --git a/mozilla/cck/muc/dialshr.cpp b/mozilla/cck/muc/dialshr.cpp new file mode 100644 index 00000000000..4cc0c906567 --- /dev/null +++ b/mozilla/cck/muc/dialshr.cpp @@ -0,0 +1,3939 @@ +/* -*- 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 // MFC core and standard components +#include // MFC extensions + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +} + + diff --git a/mozilla/cck/muc/dialshr.h b/mozilla/cck/muc/dialshr.h new file mode 100644 index 00000000000..7c23e200566 --- /dev/null +++ b/mozilla/cck/muc/dialshr.h @@ -0,0 +1,154 @@ +/* -*- 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. + */ + +/* dialshr.h + common header file for integrated dialer + + ** WINVER values in this file: + ** WINVER < 0x400 = Windows NT 3.5, Windows NT 3.51 + ** WINVER = 0x400 = Windows 95, Windows NT SUR (default) + ** WINVER > 0x400 = Windows NT SUR enhancements + + NB: Certain usages of WINVER would imply WIN32, our header + file assumes that WINVER >= 0x400 implies WIN32 +*/ + +#include +#include "shlobj.h" +#include "winerror.h" + +extern HINSTANCE gDLL; // dll instance +extern int gPlatformOS; // platform OS (95 or NT40) + +// account parameter block +typedef struct ACCOUNTPARAMS +{ + char ISPName[ 32 ]; + char FileName[ 16 ]; + char DNS[ 16 ]; + char DNS2[ 16 ]; + char DomainName[ 255 ]; + char LoginName[ 64 ]; + char Password[ 64 ]; + char ScriptFileName[ 255 ]; + BOOL ScriptEnabled; + BOOL NeedsTTYWindow; + char ISPPhoneNum[ 64 ]; + char ISDNPhoneNum[ 64 ]; + BOOL VJCompressionEnabled; + BOOL IntlMode; + BOOL DialOnDemand; +} ACCOUNTPARAMS; + + +// location parameter block +typedef struct LOCATIONPARAMS +{ + char ModemName[ 255 ]; + char ModemType[ 80 ]; + BOOL DialType; + char OutsideLineAccess[ 6 ]; + BOOL DisableCallWaiting; + char DisableCallWaitingCode[ 6 ]; + char UserAreaCode[ 6 ]; + short UserCountryCode; + BOOL DialAsLongDistance; + char LongDistanceAccess[ 6 ]; + BOOL DialAreaCode; + char DialPrefix[ 32 ]; + char DialSuffix[ 32 ]; + BOOL UseBothISDNLines; + BOOL b56kISDN; + DWORD DisconnectTime; +} LOCATIONPARAMS; + +// connection parameter block +typedef struct CONNECTIONPARAMS +{ + char szEntryName[ MAX_PATH ]; + LPITEMIDLIST pidl; +} CONNECTIONPARAMS; + +// following API entry-points are included for all builds +typedef DWORD (WINAPI* RASDIAL)(LPRASDIALEXTENSIONS,LPTSTR,LPRASDIALPARAMS,DWORD,LPVOID,LPHRASCONN); +typedef DWORD (WINAPI* RASHANGUP)(HRASCONN); +typedef DWORD (WINAPI* RASGETERRORSTRING)(UINT, LPSTR, DWORD); +typedef DWORD (WINAPI* RASSETENTRYPROPERTIES)(LPSTR, LPSTR, LPBYTE, DWORD, LPBYTE, DWORD); +typedef DWORD (WINAPI* RASSETENTRYDIALPARAMS)(LPTSTR,LPRASDIALPARAMS,BOOL); +typedef DWORD (WINAPI* RASGETCOUNTRYINFO)(LPRASCTRYINFO, LPDWORD); +typedef DWORD (WINAPI* RASENUMCONNECTIONS)(LPRASCONN,LPDWORD,LPDWORD); +typedef DWORD (WINAPI* RASENUMENTRIES)(LPTSTR,LPTSTR,LPRASENTRYNAME,LPDWORD,LPDWORD); +typedef DWORD (WINAPI* RASENUMDEVICES)(LPRASDEVINFO, LPDWORD, LPDWORD); +typedef DWORD (WINAPI* RASGETENTRYPROPERTIES)(LPSTR, LPSTR, LPRASENTRY, LPDWORD, LPBYTE, LPDWORD); +typedef DWORD (WINAPI* RASVALIDATEENTRYNAME)(LPSTR, LPSTR); +typedef DWORD (WINAPI* RASDELETEENTRY)(LPSTR, LPSTR); + +extern RASDIAL m_lpfnRasDial; +extern RASHANGUP m_lpfnRasHangUp; +extern RASGETERRORSTRING m_lpfnRasGetErrorString; +extern RASSETENTRYPROPERTIES m_lpfnRasSetEntryProperties; +extern RASSETENTRYDIALPARAMS m_lpfnRasSetEntryDialParams; +extern RASGETCOUNTRYINFO m_lpfnRasGetCountryInfo; +extern RASENUMCONNECTIONS m_lpfnRasEnumConnections; +extern RASENUMENTRIES m_lpfnRasEnumEntries; +extern RASENUMDEVICES m_lpfnRasEnumDevices; +extern RASGETENTRYPROPERTIES m_lpfnRasGetEntryProperties; +extern RASVALIDATEENTRYNAME m_lpfnRasValidateEntryName; +extern RASDELETEENTRY m_lpfnRasDeleteEntry; + +extern HINSTANCE m_hRasInst; + + +// for NT40 only +#if ( WINVER >= 0x401 ) +typedef DWORD (WINAPI* RASSETAUTODIALADDRESS)(LPSTR, DWORD, LPRASAUTODIALENTRYA, DWORD, DWORD); +typedef DWORD (WINAPI* RASGETAUTODIALADDRESS)(LPSTR, DWORD, LPRASAUTODIALENTRYA, LPDWORD, LPDWORD); +typedef DWORD (WINAPI* RASSETAUTODIALENABLE)(DWORD, BOOL); +typedef DWORD (WINAPI* RASSETAUTODIALPARAM)(DWORD, LPVOID, DWORD); +typedef DWORD (WINAPI* RASENUMAUTODIALADDRESSES)(LPTSTR *,LPDWORD,LPDWORD); +typedef DWORD (WINAPI* RASSETCREDENTIALS)(LPTSTR, LPTSTR, LPRASCREDENTIALS, BOOL); + +extern RASSETAUTODIALENABLE m_lpfnRasSetAutodialEnable; +extern RASSETAUTODIALADDRESS m_lpfnRasSetAutodialAddress; +extern RASGETAUTODIALADDRESS m_lpfnRasGetAutodialAddress; +extern RASSETAUTODIALPARAM m_lpfnRasSetAutodialParam; +extern RASENUMAUTODIALADDRESSES m_lpfnRasEnumAutodialAddresses; +extern RASSETCREDENTIALS m_lpfnRasSetCredentials; +#endif + +void SizeofRAS95(); +void SizeofRASNT40(); + +BOOL LoadRasFunctionsNT( LPCSTR lpszLibrary ); +BOOL GetDialUpConnection95( CONNECTIONPARAMS** connectionNames, int* numNames ); +BOOL GetDialUpConnectionNT( CONNECTIONPARAMS** connectionNames, int* numNames ); + +void EnableDialOnDemandNT(LPSTR lpProfileName, BOOL flag); +void EnableDialOnDemand95(LPSTR lpProfileName, BOOL flag); + + +BOOL LoadRasFunctions( LPCSTR lpszLibrary ); +void FreeRasFunctions(); + +BOOL GetModemList( char ***, int* ); +BOOL GetModemType( char* strModemName, char* strModemType ); + +BOOL IsDialerConnected(); +int DialerConfig( char** dialParams ); +BOOL DialerConnect(); +void DialerHangup(); diff --git a/mozilla/cck/muc/makefile.win b/mozilla/cck/muc/makefile.win new file mode 100644 index 00000000000..d15eb95e86b --- /dev/null +++ b/mozilla/cck/muc/makefile.win @@ -0,0 +1,89 @@ +# 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. + +IGNORE_MANIFEST = 1 +DEPTH = ..\ + +# Get CFLAGS, OBJDIR and such defined before using them in this makefile... +!include "$(DEPTH)\config\config.mak" + +################################################################# + +INCS = \ + -I. \ + -I$(DEPTH)\dist\public\nspr \ + -I$(DEPTH)\dist\public\pref \ + -I$(DEPTH)\dist\public\js \ + $(INCS) + +CPP_OBJS = \ + .\$(OBJDIR)\dialshr.obj \ + .\$(OBJDIR)\muc.obj \ + .\$(OBJDIR)\rasnt40.obj \ + .\$(OBJDIR)\ras95.obj \ + $(NULL) + +OBJS = \ + .\$(OBJDIR)\muc.res + +################################################################# + +MAKE_OBJ_TYPE = DLL +LIBNAME = muc +PDBFILE = $(LIBNAME).pdb +MAPFILE = $(LIBNAME).map +RESFILE = $(LIBNAME).res + +# not sure what of all this crap is really necessary +CFLAGS = \ + $(CFLAGS) \ + -MD \ + -D_USRDLL \ + -D_AFXDLL \ + -DWINVER=0x401 + +RCFLAGS = \ + $(RCFLAGS) \ + -D_AFXDLL + +# again, not sure what is necessary here, NODEFAULTLIB seems +# to be, and probably the export +LFLAGS = \ + $(LFLAGS) \ + -export:PEPluginFunc=_PEPluginFunc@12 \ + -nodefaultlib:MSVCRT \ + -machine:Ix86 + +DEFFILE = \ + muc.def + +DLL_LIBS = \ + rasapi32.lib \ + tapi32.lib \ + ole32.lib \ + $(DEPTH)\dist\$(OBJDIR)\lib\xppref32.lib \ + $(DLL_LIBS) + +DLL= \ + $(OBJDIR)\$(LIBNAME).dll + +################################################################# + +libs:: $(DLL) + +!include "$(DEPTH)\config\rules.mak" + +install:: + $(MAKE_INSTALL) .\$(OBJDIR)\$(LIBNAME).dll $(DIST)\lib diff --git a/mozilla/cck/muc/muc.aps b/mozilla/cck/muc/muc.aps new file mode 100644 index 00000000000..3f5cf2005a1 Binary files /dev/null and b/mozilla/cck/muc/muc.aps differ diff --git a/mozilla/cck/muc/muc.cpp b/mozilla/cck/muc/muc.cpp new file mode 100644 index 00000000000..0465e3f18d1 --- /dev/null +++ b/mozilla/cck/muc/muc.cpp @@ -0,0 +1,296 @@ +/* -*- 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. + */ +// muc.cpp : Defines the initialization routines for the DLL. +// + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions + +#include "muc.h" +#include "dialshr.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +enum +{ + kGetPluginVersion, + kSelectAcctConfig, + kSelectModemConfig, + kSelectDialOnDemand, + kConfigureDialer, + kConnect, + kHangup, + kEditEntry, + kDeleteEntry, + kRenameEntry, + kMonitor, +}; + +typedef long ( STDAPICALLTYPE* FARPEFUNC )( long selectorCode, void* paramBlock, void* returnData ); + + +// Keeps track of OS version, either win95 or winNT +int gPlatformOS; +HINSTANCE gDLL; + +int GetAcctConfig( char* returnData ); +int GetModemConfig( char* returnData ); + +///////////////////////////////////////////////////////////////////////////// +// CMucApp + +BEGIN_MESSAGE_MAP(CMucApp, CWinApp) + //{{AFX_MSG_MAP(CMucApp) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +///////////////////////////////////////////////////////////////////////////// +// CMucApp construction + +CMucApp::CMucApp() +{ +} + +///////////////////////////////////////////////////////////////////////////// +// CMucApp deconstruction +CMucApp::~CMucApp() +{ +} + +///////////////////////////////////////////////////////////////////////////// +// CMucApp InitInstance + +CMucApp::InitInstance() +{ + CWinApp::InitInstance(); + + SetDialogBkColor(); // Set dialog background color to gray + LoadStdProfileSettings(); // Load standard INI file options (including MRU) + + gPlatformOS = 0; + + OSVERSIONINFO* lpOsVersionInfo = new OSVERSIONINFO; + lpOsVersionInfo->dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); + + if ( GetVersionEx( lpOsVersionInfo ) ) + gPlatformOS = (int)lpOsVersionInfo->dwPlatformId; + + switch ( gPlatformOS ) + { + case VER_PLATFORM_WIN32_WINDOWS: //win95 + if( !LoadRasFunctions( "rasapi32.dll" ) ) + return FALSE; + break; + + case VER_PLATFORM_WIN32_NT: // win nt + if( !LoadRasFunctionsNT( "rasapi32.dll" ) ) + return FALSE; + break; + + default: + break; + } + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CMucApp ExitInstance + +BOOL CMucApp::ExitInstance() +{ + if ( lpOsVersionInfo != NULL ) + { + delete lpOsVersionInfo; + lpOsVersionInfo = NULL; + } + + return CWinApp::ExitInstance(); +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CMucApp object + +CMucApp gMUCDLL; + +STDAPI_( long ) +PEPluginFunc( long selectorCode, void* paramBlock, void* returnData ) +{ + long returnCode = 0; + BOOL flag = TRUE; + char acctStr[ MAX_PATH ]; + + gDLL = gMUCDLL.m_hInstance; + + switch ( selectorCode ) + { + // fill in the version in paramBlock + case kGetPluginVersion: + *(long*)returnData = 0x00010001; + break; + + // get account list + case kSelectAcctConfig: + *(int*)paramBlock = GetAcctConfig( (char*)returnData ); + break; + + // get modem list + case kSelectModemConfig: + *(int*)paramBlock = GetModemConfig( (char*)returnData ); + break; + + case kSelectDialOnDemand: + // kludge: dealing with dogbert PR3 bug + if ( *(int*)paramBlock == 1 ) + strcpy( acctStr, (char*)returnData ); + else if( *(int*)returnData == 1 ) + { + strcpy( acctStr, (char *)paramBlock ); + if( strcmp( acctStr, "None" ) == 0 ) + flag = FALSE; + } + else + { + strcpy( acctStr, "" ); + flag = FALSE; + } + switch ( gPlatformOS ) + { + case VER_PLATFORM_WIN32_WINDOWS: //win95 + EnableDialOnDemand95( acctStr, flag ); + break; + + case VER_PLATFORM_WIN32_NT: // win nt + EnableDialOnDemandNT( acctStr, flag ); + break; + + default: + break; + } + + case kConfigureDialer: + returnCode = DialerConfig( (char**)paramBlock ); + break; + + case kConnect: + returnCode = ( DialerConnect() == TRUE ? 0 : -1 ); + break; + + case kHangup: + DialerHangup(); + returnCode = 0; + break; + + default: + returnCode = 0; + break; + } + + return returnCode; +} + +///////////////////////////////////////////////////////////////////////////// +int GetAcctConfig( char* returnData ) +{ + CONNECTIONPARAMS* connectionNames; + int numNames = 0; + int i = 0, rtn; + CString str, tmp; + + switch ( gPlatformOS ) + { + case VER_PLATFORM_WIN32_WINDOWS: //win95 + rtn = GetDialUpConnection95( &connectionNames, &numNames ); + break; + + case VER_PLATFORM_WIN32_NT: // win nt + rtn = GetDialUpConnectionNT( &connectionNames, &numNames ); + break; + + default: + return FALSE; + } + + if ( rtn ) + { + returnData[ 0 ] = 0x00; + if ( connectionNames != NULL ) + { + // pile up account names in a single array, separated by a () + for ( i = 0; i < numNames; i++ ) + { + tmp = connectionNames[ i ].szEntryName; + str += tmp; + str += "()"; + } + strcpy( returnData, (const char*)str ); + + delete []connectionNames; + } + } + return numNames; +} + +///////////////////////////////////////////////////////////////////////////// +int GetModemConfig( char* returnData ) +{ + char** modemResults; + int numDevices; + int i; + CString str, tmp; + + if ( !::GetModemList( &modemResults, &numDevices ) ) + { + if ( modemResults != NULL ) + { + for ( i = 0; i < numDevices; i++ ) + { + if ( modemResults[ i ] != NULL ) + delete []modemResults[ i ]; + } + delete []modemResults; + } + return numDevices; + } + + // copy all entries to the array + returnData[ 0 ] = 0x00; + + // pile up account names in a single array, separated by a () + for ( i = 0; i < numDevices; i++ ) + { + tmp = modemResults[ i ]; + str += tmp; + str += "()"; + delete []modemResults[ i ]; + } + strcpy( returnData, (const char*)str ); + + delete []modemResults; + + return numDevices; +} diff --git a/mozilla/cck/muc/muc.def b/mozilla/cck/muc/muc.def new file mode 100644 index 00000000000..3a0554d409a --- /dev/null +++ b/mozilla/cck/muc/muc.def @@ -0,0 +1,33 @@ +; -*- Mode: Fundamental -*- +; 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. +; +LIBRARY MUC +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE SINGLE +HEAPSIZE 8192 +EXPORTS + PEPluginFunc @1 + + WEP PRIVATE +; To implement your own Windows Exit Procedure add the following +; function to your application (referring to it in the .def file is +; not required.) The extern "C" is only required if module is C++. +; extern "C" int FAR PASCAL _WEP(int) +; { +; /* Your WEP functionality goes here */ +; return 1; +; } + diff --git a/mozilla/cck/muc/muc.h b/mozilla/cck/muc/muc.h new file mode 100644 index 00000000000..041b70e2010 --- /dev/null +++ b/mozilla/cck/muc/muc.h @@ -0,0 +1,54 @@ +/* -*- 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. + */ +// muc.h : main header file for the MUC DLL + +#ifndef __AFXWIN_H__ +#error include 'stdafx.h' before including this file for PCH +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMucApp +// See muc.cpp for the implementation of this class +// + +class CMucApp : public CWinApp +{ +public: + CMucApp(); + ~CMucApp(); +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMucApp) + //}}AFX_VIRTUAL + + //{{AFX_MSG(CMucApp) + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + virtual BOOL InitInstance(); + virtual BOOL ExitInstance(); + + DECLARE_MESSAGE_MAP() + +private: +#ifdef WIN32 + OSVERSIONINFO *lpOsVersionInfo; +#endif +}; + +///////////////////////////////////////////////////////////////////////////// diff --git a/mozilla/cck/muc/muc.rc b/mozilla/cck/muc/muc.rc new file mode 100644 index 00000000000..1779cf8d9ca --- /dev/null +++ b/mozilla/cck/muc/muc.rc @@ -0,0 +1,180 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "Netscape Communication Corporation\0" + VALUE "FileDescription", "Account Setup Plugin\0" + VALUE "FileExtents", "*|*\0" + VALUE "FileOpenName", "Setup Plugin (*.*)|Setup Plugin (*.*)\0" + VALUE "FileVersion", "1, 0, 0, 1\0" + VALUE "InternalName", "aswplugin\0" + VALUE "LegalCopyright", "Copyright © 1997\0" + VALUE "MIMEType", "application/x-netscape-autoconfigure-dialer|application/x-netscape-autoconfigure-dialer-v2\0" + VALUE "OriginalFilename", "np32asw.dll\0" + VALUE "ProductName", "NNPE Account Setup Plugin\0" + VALUE "ProductVersion", "1, 0, 0, 1\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + +#endif // !_MAC + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_STATUS DIALOGEX 0, 0, 170, 55 +STYLE DS_SYSMODAL | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_NOPARENTNOTIFY +CAPTION "Account Setup" +FONT 8, "MS Sans Serif" +BEGIN + PUSHBUTTON "Cancel",IDCANCEL,60,34,50,14 + LTEXT "Status:",IDC_STATIC,13,11,23,10 + LTEXT "",IDC_DIAL_STATUS,41,11,111,18 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + IDS_APP_NAME "Account Setup" + IDS_NO_RAS_FUNCTIONS "Unable to dynamically load extended RAS functions!" + IDS_NO_DUN "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?" + IDS_DNS_ALREADY "Your system is configured for another Domain Name System (DNS) server. You may need to change your Dial-Up Networking settings to connect to the Internet.\n\nPlease see the troubleshooting section of the Installation and Setup Guide for more information." + IDS_BAD_PASSWORD "Invalid pasword in Netscape registration file." + IDS_NO_RNA_REGSERVER "Unable to create RNA phone book entry!" + IDS_MISSING_AREA_CODE "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." + IDS_NO_RNA "Unable to create shortcut to RNA phone book entry!" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_OUT_OF_MEMORY "The system is out of memory or resources." + IDS_INVALID_EXE "Unable to start the specified External Editor. It is not a valid executible program." + IDS_INVALID_FILE "The specified External Editor file was not found." + IDS_INVALID_PATH "The specified path for the External Editor is not valid." + IDS_NO_EDITOR "Unable to start the External Editor. Please check and make sure the file exists." + IDS_OPENING_PORT "Opening serial port..." + IDS_INIT_MODEM "Initializing modem..." + IDS_DIALING "Dialing..." + IDS_DIALING_OF "Dialing...\n%i of %i" + IDS_VERIFYING "Verifying user name and password..." + IDS_LOGGING_ON "Logging onto network..." + IDS_DISCONNECTING "Disconnecting..." + IDS_CONNECTED "Connection established." + IDS_NO_DIALTONE "No dial tone.\nMake sure your modem is connected to a phone line.." + IDS_LINE_BUSY "The phone number is busy. Please try\nagain later." + IDS_NO_ADMIN_PREMISSION "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." +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_REGGIE_PROGITEM_NAME "Registration Server" + IDS_SECURITY_RISK_WARNING + "SECURITY WARNING!\n\nAccount Setup has the ability to read and write files on your computer,\nconfigure dialing, networking and modem information.\n\nClick OK to allow Account Setup to operate in this manner.\nOtherwise, click CANCEL to exit this application." + IDS_CONNECTION_FAILED "Failed to connect due to following error:\n" + IDS_DIAL_ERR "ERROR! Connection failed." + IDS_CANCELDIAL "Cancel modem connection..." + IDS_NO_DUN_INSTALLED "Account Setup will not work without Dial-Up Networking installed. Please install Dial-Up Networking first before running Account Setup." + IDS_NO_DUN_NT "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." + IDS_NO_TAPI "Unable to initialize TAPI." + IDS_ERR_EDITOR "Can't open external editor:\n%s with file\n%s" + IDS_ERR_EDITOR2 "external editor:\n%s\nerr code=%d\nlength=%d\nlength(editor)=%d last char=%d\nlength(file)=%d first char=%d" + IDS_PROTOCOL_NOT_CONFIGURED + "The protocol is not configured.\nPlease reset your modem or restart your machine and try again later." +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/mozilla/cck/muc/ras95.cpp b/mozilla/cck/muc/ras95.cpp new file mode 100644 index 00000000000..dc763a5d42a --- /dev/null +++ b/mozilla/cck/muc/ras95.cpp @@ -0,0 +1,44 @@ +/* -*- 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 // MFC core and standard components +#include // MFC extensions + +extern size_t stRASENTRY; +extern size_t stRASCONN; +extern size_t stRASCTRYINFO; +extern size_t stRASDIALPARAMS; +extern size_t stRASDEVINFO; + +#ifdef WINVER +#undef WINVER +#endif +#define WINVER 0x0400 + +#include +#include + +void SizeofRAS95() +{ + stRASENTRY = sizeof( RASENTRY ); + stRASCONN = sizeof( RASCONN ); + stRASCTRYINFO = sizeof( RASCTRYINFO ); + stRASDIALPARAMS = sizeof( RASDIALPARAMS ); + stRASDEVINFO = sizeof( RASDEVINFO ); +} diff --git a/mozilla/cck/muc/rasnt40.cpp b/mozilla/cck/muc/rasnt40.cpp new file mode 100644 index 00000000000..b2389207fe2 --- /dev/null +++ b/mozilla/cck/muc/rasnt40.cpp @@ -0,0 +1,44 @@ +/* -*- 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 // MFC core and standard components +#include // MFC extensions + +extern size_t stRASENTRY; +extern size_t stRASCONN; +extern size_t stRASCTRYINFO; +extern size_t stRASDIALPARAMS; +extern size_t stRASDEVINFO; + +#ifdef WINVER +#undef WINVER +#endif +#define WINVER 0x0401 + +#include +#include + +void SizeofRASNT40() +{ + stRASENTRY = sizeof( RASENTRY ); + stRASCONN = sizeof( RASCONN ); + stRASCTRYINFO = sizeof( RASCTRYINFO ); + stRASDIALPARAMS = sizeof( RASDIALPARAMS ); + stRASDEVINFO = sizeof( RASDEVINFO ); +} diff --git a/mozilla/cck/muc/resource.h b/mozilla/cck/muc/resource.h new file mode 100644 index 00000000000..910e2361ab5 --- /dev/null +++ b/mozilla/cck/muc/resource.h @@ -0,0 +1,53 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by muc.rc +// +#define IDD_STATUS 101 +#define IDC_DIAL_STATUS 1001 +#define IDS_APP_NAME 63000 +#define IDS_NO_RAS_FUNCTIONS 63001 +#define IDS_NO_DUN 63002 +#define IDS_DNS_ALREADY 63003 +#define IDS_BAD_PASSWORD 63004 +#define IDS_NO_RNA_REGSERVER 63005 +#define IDS_MISSING_AREA_CODE 63006 +#define IDS_NO_RNA 63007 +#define IDS_TEST 63008 +#define IDS_OUT_OF_MEMORY 63008 +#define IDS_INVALID_EXE 63009 +#define IDS_INVALID_FILE 63010 +#define IDS_INVALID_PATH 63011 +#define IDS_NO_EDITOR 63012 +#define IDS_OPENING_PORT 63013 +#define IDS_INIT_MODEM 63014 +#define IDS_DIALING 63015 +#define IDS_DIALING_OF 63016 +#define IDS_VERIFYING 63017 +#define IDS_LOGGING_ON 63018 +#define IDS_DISCONNECTING 63019 +#define IDS_CONNECTED 63020 +#define IDS_NO_DIALTONE 63021 +#define IDS_LINE_BUSY 63022 +#define IDS_NO_ADMIN_PREMISSION 63023 +#define IDS_REGGIE_PROGITEM_NAME 63024 +#define IDS_SECURITY_RISK_WARNING 63025 +#define IDS_CONNECTION_FAILED 63026 +#define IDS_DIAL_ERR 63027 +#define IDS_CANCELDIAL 63028 +#define IDS_NO_DUN_INSTALLED 63029 +#define IDS_NO_DUN_NT 63030 +#define IDS_NO_TAPI 63031 +#define IDS_ERR_EDITOR 63032 +#define IDS_ERR_EDITOR2 63033 +#define IDS_PROTOCOL_NOT_CONFIGURED 63034 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 104 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1003 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/mozilla/cck/muc/test/sample_dial.c b/mozilla/cck/muc/test/sample_dial.c new file mode 100644 index 00000000000..12c499a086a --- /dev/null +++ b/mozilla/cck/muc/test/sample_dial.c @@ -0,0 +1,505 @@ +/* -*- 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. + */ + +/* JS reflection of the dialer stack + 8/24/98 +*/ + +#include "lm.h" +#include "prmem.h" + +typedef struct JSDialer +{ + JSObject* obj; + void* pstub; +} JSDialer; + +/* The following definitions need to be kept synchronized with the +values the MUC DLL accepts, currently, there's no universal header +containing them, but you can look in ns/cmd/dialup/win/muc for +the code that implements MUC, and you can reference also +ns/cmd/winfe/mucproc.h for front-end code that references MUC + +There should probably be an xp muc(pub).h or somesuch that contains +a universal MUC API. + +*/ +enum +{ + kGetPluginVersion, + kSelectAcctConfig, + kSelectModemConfig, + kSelectDialOnDemand, + kConfigureDialer, + kConnect, + kHangup, + kEditEntry, + kDeleteEntry, + kRenameEntry, + kMonitor, +}; + +#ifdef XP_WIN +typedef long (STDAPICALLTYPE *FARPEFUNC)( + long selectorCode, + void* paramBlock, + void* returnData ); + +jsint CallMuc( JSDialer* dialer, long selector, void* configData, void* returnData ) +{ + FARPEFUNC mucFunc; + jsint error = 0; + + mucFunc = (FARPEFUNC)dialer->pstub; + if ( !mucFunc ) + return -1; + + error = (jsint)( *mucFunc )( selector, configData, NULL ); + return error; +} +#else +/* provide an empty prototype until we have Unix/Mac support */ +jsint CallMuc( JSDialer*, long, void*, void* ) { } +#endif + + + + +enum dialer_slot +{ + PRIVATE_STUB = -1, +}; + +static JSPropertySpec dialer_props[] = +{ + { "privateStub", PRIVATE_STUB, JSPROP_READONLY }, + {0} +}; + +extern JSClass lm_dialer_class; + +JSBool PR_CALLBACK +dialer_getProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp) +{ + JSDialer* dialer; + enum dialer_slot dialer_slot; + JSString* str = NULL; + jsint slot; + + *vp = JS_GetEmptyStringValue( cx ); + + if ( !JSVAL_IS_INT(id) ) + return JS_TRUE; + + slot = JSVAL_TO_INT( id ); + dialer = JS_GetInstancePrivate( cx, obj, &lm_dialer_class, NULL); + + if ( !dialer ) + return JS_TRUE; + + dialer_slot = slot; + switch ( dialer_slot ) + { + default: + return JS_TRUE; + } + + if ( str ) + *vp = STRING_TO_JSVAL( str ); + return JS_TRUE; +} + +JSBool PR_CALLBACK +dialer_enumerate( JSContext* cx, JSObject* obj ) +{ + return JS_TRUE; +} + +void PR_CALLBACK +dialer_finalize( JSContext* cx, JSObject* obj ) +{ + JSDialer* dialer; + + dialer = JS_GetPrivate( cx, obj ); + if ( !dialer ) + return; + + XP_DELETE( dialer ); +} + +JSBool PR_CALLBACK +dialer_toString( JSContext* cx, JSObject* obj, uint argc, jsval* argv, jsval* rval ) +{ + JSString* str; + + str = JS_NewStringCopyZ( cx, "[object Dialer]" ); + if ( !str ) + return JS_FALSE; + + *rval = STRING_TO_JSVAL( str ); + return JS_TRUE; +} + + +JSClass lm_dialer_class = +{ + "Dialer", + JSCLASS_HAS_PRIVATE, + JS_PropertyStub, + JS_PropertyStub, + dialer_getProperty, + dialer_getProperty, + dialer_enumerate, + JS_ResolveStub, + JS_ConvertStub, + dialer_finalize +}; + +PR_STATIC_CALLBACK(PRBool) +dialer_config( JSContext* cx, JSObject* obj, uint argc, + jsval* argv, jsval* rval ) +{ + JSObject* stringArray; + jsuint count = 0; + jsval temp; + JSString* stringObject; + jsuint stringArrayLength; + PRBool result; + JSDialer* dialer; + jsint error; + + char** configData; + char* buffer; + + if ( !lm_CanAccessTarget( cx, JSTARGET_UNIVERSAL_DIALER_ACCESS ) ) + return JS_FALSE; + + if ( argc != 1 ) + return JS_FALSE; + + if ( !JSVAL_IS_OBJECT( argv[ 0 ] ) ) + return JS_FALSE; + + JS_ValueToObject( cx, argv[ 0 ], &stringArray ); + if ( !JS_IsArrayObject( cx, stringArray ) ) + return JS_FALSE; + + JS_GetArrayLength( cx, stringArray, &stringArrayLength ); + + configData = JS_malloc( cx, ( ( stringArrayLength + 1 ) * sizeof( char* ) ) ); + if ( !configData ) + return JS_FALSE; + + configData[ 0 ] = NULL; + + while ( count < stringArrayLength ) + { + if ( JS_GetElement( cx, stringArray, count, &temp ) != JS_TRUE ) + continue; + + if ( !JSVAL_IS_STRING( temp ) ) + continue; + + stringObject = JS_ValueToString( cx, temp ); + buffer = JS_strdup( cx, JS_GetStringBytes( stringObject ) ); + if ( !buffer ) + { + configData[ count ] = 0; + result = JS_FALSE; + goto fail; + } + + configData[ count ] = buffer; + buffer = NULL; + configData[ ++count ] = NULL; + } + + dialer = JS_GetPrivate( cx, obj ); + if ( !dialer ) + { + result = JS_FALSE; + goto fail; + } + + error = CallMuc( dialer, kConfigureDialer, (void*)configData, (void*)NULL ); + if ( error ) + { + result = JS_FALSE; + goto fail; + } + + result = JS_TRUE; + +fail: + if ( buffer ) + JS_free( cx, buffer ); + count = 0; + while ( configData[ count ] ) + JS_free( cx, configData[ count++ ] ); + return result; +} + +PR_STATIC_CALLBACK(PRBool) +dialer_connect( JSContext* cx, JSObject* obj, uint argc, + jsval* argv, jsval* rval ) +{ + JSDialer* dialer; + jsint error; + + if ( !lm_CanAccessTarget( cx, JSTARGET_UNIVERSAL_DIALER_ACCESS ) ) + return JS_FALSE; + + dialer = JS_GetPrivate( cx, obj ); + if ( !dialer ) + return JS_FALSE; + + error = CallMuc( dialer, kConnect, (void*)NULL, (void*)NULL ); + + if ( error ) + return JS_FALSE; + + return JS_TRUE; +} + +PR_STATIC_CALLBACK(PRBool) +dialer_hangup( JSContext* cx, JSObject* obj, uint argc, + jsval* argv, jsval* rval ) +{ + JSDialer* dialer; + jsint error; + + if ( !lm_CanAccessTarget( cx, JSTARGET_UNIVERSAL_DIALER_ACCESS ) ) + return JS_FALSE; + + dialer = JS_GetPrivate( cx, obj ); + if ( !dialer ) + return JS_FALSE; + + error = CallMuc( dialer, kHangup, (void*)NULL, (void*)NULL ); + if ( error ) + return JS_FALSE; + + return JS_TRUE; +} + +PR_STATIC_CALLBACK(PRBool) +dialer_rename( JSContext* cx, JSObject* obj, uint argc, + jsval* argv, jsval* rval ) +{ + JSDialer* dialer; + JSString* string = NULL; + jsint error; + + struct + { + char* from; + char* to; + } b; + + if ( !lm_CanAccessTarget( cx, JSTARGET_UNIVERSAL_DIALER_ACCESS ) ) + return JS_FALSE; + + dialer = JS_GetPrivate( cx, obj ); + if ( !dialer ) + return JS_FALSE; + + if ( argc != 2 ) + return JS_FALSE; + + if ( !JSVAL_IS_STRING( argv[ 0 ] ) || + !JSVAL_IS_STRING( argv[ 1 ] ) ) + return JS_FALSE; + + string = JS_ValueToString( cx, argv[ 0 ] ); + b.from = JS_strdup( cx, JS_GetStringBytes( string ) ); + string = JS_ValueToString( cx, argv[ 1 ] ); + b.to = JS_strdup( cx, JS_GetStringBytes( string ) ); + + error = CallMuc( dialer, kRenameEntry, (void*)&b, (void*)NULL ); + + if ( error ) + return JS_FALSE; + + return JS_TRUE; +} + +PR_STATIC_CALLBACK(PRBool) +dialer_delete( JSContext* cx, JSObject* obj, uint argc, + jsval* argv, jsval* rval ) +{ + JSDialer* dialer; + JSString* string = NULL; + char* name = NULL; + jsint error; + + if ( !lm_CanAccessTarget( cx, JSTARGET_UNIVERSAL_DIALER_ACCESS ) ) + return JS_FALSE; + + dialer = JS_GetPrivate( cx, obj ); + if ( !dialer ) + return JS_FALSE; + + if ( argc != 1 ) + return JS_FALSE; + + if ( !JSVAL_IS_STRING( argv[ 0 ] ) ) + return JS_FALSE; + + string = JS_ValueToString( cx, argv[ 0 ] ); + name = JS_strdup( cx, JS_GetStringBytes( string ) ); + + error = CallMuc( dialer, kDeleteEntry, (void*)name, (void*)NULL ); + + if ( error ) + return JS_FALSE; + + return JS_TRUE; +} + +PR_STATIC_CALLBACK(PRBool) +dialer_monitor( JSContext* cx, JSObject* obj, uint argc, + jsval* argv, jsval* rval ) +{ + JSDialer* dialer; + JSString* string = NULL; + char* name = NULL; + jsint error; + + if ( !lm_CanAccessTarget( cx, JSTARGET_UNIVERSAL_DIALER_ACCESS ) ) + return JS_FALSE; + + dialer = JS_GetPrivate( cx, obj ); + if ( !dialer ) + return JS_FALSE; + + error = CallMuc( dialer, kMonitor, (void*)NULL, (void*)NULL ); + + if ( error ) + return JS_FALSE; + + return JS_TRUE; +} + +PR_STATIC_CALLBACK(PRBool) +dialer_edit( JSContext* cx, JSObject* obj, uint argc, + jsval* argv, jsval* rval ) +{ + JSDialer* dialer; + JSString* string = NULL; + char* name = NULL; + jsint error; + + if ( !lm_CanAccessTarget( cx, JSTARGET_UNIVERSAL_DIALER_ACCESS ) ) + return JS_FALSE; + + dialer = JS_GetPrivate( cx, obj ); + if ( !dialer ) + return JS_FALSE; + + if ( argc != 1 ) + return JS_FALSE; + + if ( !JSVAL_IS_STRING( argv[ 0 ] ) ) + return JS_FALSE; + + string = JS_ValueToString( cx, argv[ 0 ] ); + name = JS_strdup( cx, JS_GetStringBytes( string ) ); + + error = CallMuc( dialer, kEditEntry, (void*)name, (void*)NULL ); + + if ( error ) + return JS_FALSE; + + return JS_TRUE; +} + +static JSFunctionSpec dialer_methods[] = { + {"configure", dialer_config, 1}, + {"connect", dialer_connect, 1}, + {"hangup", dialer_hangup, 0}, + {"rename", dialer_rename, 2}, + {"delete", dialer_delete, 1}, + {"monitor", dialer_monitor, 0}, + {"edit", dialer_edit, 1}, + {"toString", dialer_toString, 0}, + {0} +}; + +JSBool PR_CALLBACK +Dialer( JSContext* cx, JSObject* obj, uint argc, jsval* argv, jsval* rval ) +{ + return JS_TRUE; +} + +JSDialer* create_dialer( JSContext* cx, JSObject* parent_obj ) +{ + MochaDecoder* decoder; + JSObject* obj; + JSDialer* dialer = NULL; + +#ifdef XP_WIN + HINSTANCE mucDll = NULL; + FARPEFUNC stub = NULL; + long version; +#endif + + decoder = JS_GetPrivate( cx, JS_GetGlobalObject( cx ) ); + dialer = JS_malloc( cx, sizeof *dialer ); + if ( !dialer ) + return NULL; + XP_BZERO( dialer, sizeof *dialer ); + + obj = JS_InitClass( cx, parent_obj, NULL, &lm_dialer_class, + Dialer, 0, dialer_props, dialer_methods, NULL, NULL); + if ( !obj || !JS_SetPrivate( cx, obj, dialer ) ) + { + JS_free( cx, dialer ); + return NULL; + } + + dialer->obj = obj; + + dialer->pstub = NULL; + +#ifdef XP_WIN + mucDll = LoadLibrary( "muc.dll" ); + + /* apparently LoadLibrary can return failure codes instead of a null ptr. */ + if ( !mucDll || mucDll < 0x00000030 ) + goto done; + + stub = (FARPEFUNC)GetProcAddress( mucDll, "PEPluginFunc" ); + if ( !stub ) + goto done; + + ( *stub )( kGetPluginVersion, NULL, &version ); + if ( version >= 0x00010001 ) + dialer->pstub = (void*)stub; +#endif +done: + return dialer; +} + +JSObject* lm_NewDialer( JSContext* cx, JSObject* parent_obj ) +{ + JSDialer* dialer; + + dialer = create_dialer( cx, parent_obj ); + return ( dialer ? dialer->obj : NULL); +} + diff --git a/mozilla/cck/muc/test/test.htm b/mozilla/cck/muc/test/test.htm new file mode 100644 index 00000000000..697cabf6312 --- /dev/null +++ b/mozilla/cck/muc/test/test.htm @@ -0,0 +1,94 @@ + + + +Account Setup + + + +test of the emergency dialing system + +