/*****************************************************************************
* Copyright (c) 1990-99 Digi International Inc., All Rights Reserved
* 
* This software contains proprietary and confidential information of Digi
* International Inc.  By accepting transfer of this copy, Recipient agrees
* to retain this software in confidence, to prevent disclosure to others,
* and to make no use of this software other than that for which it was
* delivered.  This is an unpublished copyrighted work of Digi International
* Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
* prohibited.
* 
* Restricted Rights Legend
*
* Use, duplication, or disclosure by the Government is subject to
* restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
* Technical Data and Computer Software clause at DFARS 252.227-7031 or
* subparagraphs (c)(1) and (2) of the Commercial Computer Software -
* Restricted Rights at 48 CFR 52.227-19, as applicable.
*
* Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
*
*****************************************************************************/

#include "stdafx.h"

static BOOL ValidateThisIsNT351(void)
{
   BOOL fIsNT351 = FALSE;

   try
   {
		OSVERSIONINFO osvi = { 0 };
		osvi.dwOSVersionInfoSize = sizeof(osvi);
		AffirmThrow(GetVersionEx(&osvi));

		TRACE("OS Version is %d.%d\n", osvi.dwMajorVersion, osvi.dwMinorVersion);

      fIsNT351 = ((osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
		            (osvi.dwMajorVersion == 3) && (osvi.dwMinorVersion == 51));
   }
   catch(CAffirmException ae)
   {
   }

   return fIsNT351;
}

#define RAS_MODEM_INF_FILE TEXT("\\ras\\modem.inf")

static BOOL OpenRASModemInfFile(CStdioFile & ModemInf)
{
   BOOL fSuccess = FALSE;

   try
   {
		CString RASModemInfPath;
		GetSystemDirectory(RASModemInfPath.GetBufferSetLength(MAX_PATH), MAX_PATH);
		RASModemInfPath.ReleaseBuffer();
		RASModemInfPath += RAS_MODEM_INF_FILE;

		TRACE("Opening %s\n", RASModemInfPath);

		fSuccess = ModemInf.Open(RASModemInfPath, CFile::modeNoTruncate | CFile::modeReadWrite);
   }
   catch(CAffirmException ae)
   {
   }

   return fSuccess;
}

#define DIGIRAS56KMODEM_SECTION_START		TEXT("[Digi RAS 56K Modem]")
#define DIGIRAS56KMODEM_SECTION_END			TEXT(";-- END ") DIGIRAS56KMODEM_SECTION_START

static BOOL ModemSectionAlreadyExists(void)
{
   BOOL fExists = FALSE;

   try
   {
		CStdioFile ModemInf;
		AffirmThrow(OpenRASModemInfFile(ModemInf));

		CString Line;
		while (ModemInf.ReadString(Line) && !fExists)
			fExists = (Line == DIGIRAS56KMODEM_SECTION_START);

		TRACE("%s does%s already exist\n", DIGIRAS56KMODEM_SECTION_START, fExists ? "" : " NOT");

		ModemInf.Close();
   }
   catch(CAffirmException ae)
   {
   }

   return fExists;
}

static TCHAR const * const DIGIRAS56KMODEM_SECTION = TEXT("\n"

DIGIRAS56KMODEM_SECTION_START "\n"

"CALLBACKTIME=10\n"
"DEFAULTOFF=compression\n"
"MAXCARRIERBPS=57600\n"
"MAXCONNECTBPS=115200\n"

"<Blind_Off>=X4\n"
"<Blind_On>=X3\n"
"<CallSetupFailTimer>=S7=<#>\n"
"<Compression_Off>=%C0\n"
"<Compression_On>=%C3\n"
"<DialPrefix>=D\n"
"<DialSuffix>=;\n"
"<ErrorControl_Forced>=\\N2\n"
"<ErrorControl_Off>=\\N0\n"
"<ErrorControl_On>=\\N3\n"
"<FlowControl_Off>=&K0\n"
"<FlowControl_Hard>=&K3\n"
"<FlowControl_Soft>=&K4\n"
"<InactivityTimeout>=S30=<#>\n"
"<Modulation_Bell>=B1\n"
"<Modulation_CCITT>=B0\n"
"<Modulation_CCITT_V23>=+MS=3\n"
"<Prefix>=AT\n"
"<Pulse>=P\n"
"<speakermode_setup>=M3\n"
"<speakermode_on>=M2\n"
"<speakermode_off>=M0\n"
"<speakermode_dial>=M1\n"
"<speakervolume_low>=L0\n"
"<speakervolume_med>=L2\n"
"<speakervolume_high>=L3\n"
"<SpeedNegotiation_Off>=N0\n"
"<SpeedNegotiation_On>=N1\n"
"<Terminator>=<cr>\n"
"<Tone>=T\n"
"<autodial_on>=ATDT\n"
"<autodial_off>=ATX3D\n"

"DETECT_STRING=ATI0<cr>\n"
"DETECT_RESPONSE=Digi RAS modem 56000\n"

"COMMAND_INIT=AT<cr>\n"
"COMMAND_INIT=AT &F E0 V1 &D2 &C1 W1 S0=0 S95=47<cr>\n"
"COMMAND_LISTEN=ATS0=0<cr>\n"
"COMMAND_DIAL=<autodial><phonenumber><cr>\n"

"<autodial_on>=ATDT\n"
"<autodial_off>=ATD\n"

"COMMAND_INIT=ATF1<cr>\n"
"COMMAND_INIT=AT E1<cr>\n"
"COMMAND_INIT=AT &F &C1 V1 &D2 &Q0 X4 &S0 S0=1 S64=15 S2=43 S7=55<cr>\n"

"COMMAND_DIAL=<autodial><phonenumber><cr>\n"

"CONNECT=<cr><lf>CONNECT <carrierbps><cr><lf>\n"
"CONNECT_EC=<cr><lf>CONNECT <carrierbps> RELIABLE<cr><lf>\n"
"CONNECT_EC=<cr><lf>CONNECT <carrierbps> LAPM<cr><lf>\n"
"CONNECT_EC=<cr><lf>CONNECT <carrierbps> RELIABLE COMPRESSED<cr><lf>\n"
"CONNECT_EC=<cr><lf>CONNECT <carrierbps> LAPM COMPRESSED<cr><lf>\n"

"COMMAND_LISTEN=ATS0=1<cr>\n"
"CONNECT=<cr><lf>CONNECT <carrierbps><cr><lf>\n"
"CONNECT_EC=<cr><lf>CONNECT <carrierbps> RELIABLE<cr><lf>\n"
"CONNECT_EC=<cr><lf>CONNECT <carrierbps> LAPM<cr><lf>\n"
"CONNECT_EC=<cr><lf>CONNECT <carrierbps> RELIABLE COMPRESSED<cr><lf>\n"
"CONNECT_EC=<cr><lf>CONNECT <carrierbps> LAPM COMPRESSED<cr><lf>\n"

DIGIRAS56KMODEM_SECTION_END

"\n");

static BOOL AddModemSection(void)
{
   BOOL fSuccess = FALSE;

   try
   {
		CStdioFile ModemInf;
		AffirmThrow(OpenRASModemInfFile(ModemInf));

		TRACE("Appending %s section to modem.inf\n", DIGIRAS56KMODEM_SECTION_START);

		ModemInf.SeekToEnd();
		ModemInf.WriteString(DIGIRAS56KMODEM_SECTION);

		ModemInf.Close();

      fSuccess = TRUE;
   }
   catch(CAffirmException ae)
   {
   }

   return fSuccess;
}

static BOOL OpenTempModemInfFile(CStdioFile & ModemInf)
{
   BOOL fSuccess = FALSE;

   try
   {
		CString TempModemInfDir;
		GetTempPath(MAX_PATH, TempModemInfDir.GetBufferSetLength(MAX_PATH));

		CString TempModemInfPath;
		GetTempFileName(TempModemInfDir, TEXT("dig"), 0, TempModemInfPath.GetBufferSetLength(MAX_PATH));

		TRACE("Opening %s\n", TempModemInfPath);

		fSuccess = ModemInf.Open(TempModemInfPath, CFile::modeCreate | CFile::modeReadWrite);
   }
   catch(CAffirmException ae)
   {
   }

   return fSuccess;
}

static BOOL RemoveModemSection(void)
{
   BOOL fSuccess = FALSE;

   try
   {
		CStdioFile ModemInf;
		AffirmThrow(OpenRASModemInfFile(ModemInf));

		CStdioFile TempInf;
		AffirmThrow(OpenTempModemInfFile(TempInf));

		BOOL fSkipLine = FALSE;
		CString Line;
		while (ModemInf.ReadString(Line))
		{
			if (Line == DIGIRAS56KMODEM_SECTION_START)
				fSkipLine = TRUE;

			if (!fSkipLine)
				TempInf.WriteString(Line);

			if (fSkipLine && (Line == DIGIRAS56KMODEM_SECTION_END))
				fSkipLine = FALSE;
		}

		ModemInf.Close();
		TempInf.Close();

		TRACE("Moving %s to %s\n", TempInf.GetFilePath(), ModemInf.GetFilePath());
		AffirmThrow(MoveFileEx(TempInf.GetFilePath(), ModemInf.GetFilePath(), MOVEFILE_REPLACE_EXISTING));

      fSuccess = TRUE;
   }
   catch(CAffirmException ae)
   {
   }

   return fSuccess;
}

BOOL AddModemToRAS(CString const & AdapterType)
{
   BOOL fSuccess = FALSE;

   try
   {
		AffirmThrow((AdapterType == DXB_REGVAL_OPTION_ENUM_HOUSTON) ||
						(AdapterType == DXB_REGVAL_OPTION_ENUM_LONDON)  ||
						(AdapterType == DXB_REGVAL_OPTION_ENUM_CHASKA));

		AffirmThrow(ValidateThisIsNT351());

		if (!ModemSectionAlreadyExists())
			AffirmThrow(AddModemSection());

      fSuccess = TRUE;
   }
   catch(CAffirmException ae)
   {
   }

   return fSuccess;
}

BOOL RemoveModemFromRAS(CString const & AdapterType)
{
   BOOL fSuccess = FALSE;

   try
   {
		AffirmThrow((AdapterType == DXB_REGVAL_OPTION_ENUM_HOUSTON) ||
						(AdapterType == DXB_REGVAL_OPTION_ENUM_LONDON)  ||
						(AdapterType == DXB_REGVAL_OPTION_ENUM_CHASKA));

		AffirmThrow(ValidateThisIsNT351());
		AffirmThrow(RemoveModemSection());

      fSuccess = TRUE;
   }
   catch(CAffirmException ae)
   {
   }

   return fSuccess;
}
