/*****************************************************************************
* Copyright (c) 1990-98 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
*
*****************************************************************************/
// linkcfg.cpp : Defines the initialization routines for the DLL.
// The main file that provides all entry points for LinkService management
// as well as other support routines that create services and write/read 
// from the registry
// This file is modified from the original supplied in the sample SDK.

#include "stdafx.h"
#include "x25cfg.h"
#include "x25def.h"
#include "common.h"
#include "commonres.h"
#include "HdwSettings.h"
#include "modeset.h"
#include "x25Settings.h"
#include <winreg.h>


// specific to X.25 parameters
#define	NUAADDR		_T("LNUA")
#define INCOMING	_T("ISVCRng")
#define OUTGOING	_T("OSVCRng")
#define TWOWAY		_T("2SVCRng")
#define	PVC			_T("PVCRng")
#define FILTER		_T("FilterIncoming")
#define	REVERSE		_T("AcceptRevCh")
#define	STANDBY		_T("Standby")
#define	STARTUP		_T("Restart")
#define	N2RETRY		_T("N2Retry")
#define	T1TIMEOUT	_T("T1Timeout")
#define	DATARATE	_T("DataRate")
#define	NRZI		_T("NRZI")
#define	L2WINDOW	_T("L2Window")
#define	L3WINDOW	_T("L3Window")
#define	L3PKTSIZE	_T("L3PktSz")

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


MGX25DS gMgX25_data;



// BOOL		bNewLinkService = FALSE;





/////////////////////////////////////////////////////////////////////////////
// CLinkcfgApp

BEGIN_MESSAGE_MAP(CLinkcfgApp, CWinApp)
	//{{AFX_MSG_MAP(CLinkcfgApp)
		// 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()

/////////////////////////////////////////////////////////////////////////////
// CLinkcfgApp construction

CLinkcfgApp::CLinkcfgApp()
{
	//
	// Indicate that the Property Sheet uses the Help Button.
	//
	cpsLinkService.m_psh.dwFlags |= PSH_HASHELP + PSH_NOAPPLYNOW;

	// Place all significant initialization in InitInstance
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CLinkcfgApp object

CLinkcfgApp theApp;

/*
**	Purpose:
**		Read X.25 specific parameters from the registry and
**		fill the global structure 
**	Arguments:
**		pointer to the registry location where the params are
**		should be of the form
**      System\CurrentControlSet\Services\<linkservicename>\Parameters\ExtraParameters
**	Returns:
**		none
***************************************************************************/
static void ReadX25Params(char* szKey)
{
	char sztemp[MAX_STRING];
	DWORD dSize = sizeof(sztemp);
	if (!fQueryRegistryValue(szKey, NUAADDR, sztemp, &dSize))
		strcpy(sztemp,"000000000000000");
	gMgX25_data.szNUAAddress = sztemp;
	
	dSize = sizeof(sztemp);
	if (!fQueryRegistryValue(szKey, INCOMING, sztemp,&dSize))
		strcpy(sztemp,"");
	gMgX25_data.szRangeIncoming = sztemp;
	
	dSize = sizeof(sztemp);
	if (!fQueryRegistryValue(szKey, TWOWAY, sztemp,&dSize))
		strcpy(sztemp,"0001-0004");
	gMgX25_data.szRangeTwoWay = sztemp;
	
	dSize = sizeof(sztemp);
	if (!fQueryRegistryValue(szKey, OUTGOING, sztemp,&dSize))
		strcpy(sztemp,"");
	gMgX25_data.szRangeOutgoing = sztemp;
	
	dSize = sizeof(sztemp);
	if (!fQueryRegistryValue(szKey, PVC, sztemp,&dSize))
		strcpy(sztemp,"");
	gMgX25_data.szRangePVC = sztemp;

	DWORD dTemp;
	dSize = sizeof(dTemp);

	if (!fQueryRegistryValue(szKey, FILTER, (char*)&dTemp, &dSize))
		dTemp = 1;
	gMgX25_data.bFilter = dTemp;
	if (!fQueryRegistryValue(szKey, REVERSE, (char*)&dTemp, &dSize))
		dTemp = 0;
	gMgX25_data.bReverse = dTemp;

	if (!fQueryRegistryValue(szKey, STANDBY, (char*)&dTemp, &dSize))
		dTemp = 0;
	gMgX25_data.bStandby = dTemp;

	if (!fQueryRegistryValue(szKey, STARTUP, (char*)&dTemp, &dSize))
		dTemp = 1;
	gMgX25_data.bStartup = dTemp;

	if (!fQueryRegistryValue(szKey, N2RETRY, (char*)&dTemp, &dSize))
		dTemp = 10;
	gMgX25_data.dN2RetryLimit = dTemp;

	if (!fQueryRegistryValue(szKey, T1TIMEOUT, (char*)&dTemp, &dSize))
		dTemp = 30;
	gMgX25_data.dT1Timeout = dTemp;

	if (!fQueryRegistryValue(szKey, DATARATE, (char*)&dTemp, &dSize))
		dTemp = 1;
	gMgX25_data.bDataRate = dTemp;

	if (!fQueryRegistryValue(szKey, NRZI, (char*)&dTemp, &dSize))
		dTemp = 1;
	gMgX25_data.bEncodingNRZ = dTemp;

	if (!fQueryRegistryValue(szKey, L2WINDOW, (char*)&dTemp, &dSize))
		dTemp = 7;
	gMgX25_data.dL2Window = dTemp;

	if (!fQueryRegistryValue(szKey, L3WINDOW, (char*)&dTemp, &dSize))
		dTemp = 7;
	gMgX25_data.dL3Window = dTemp;

	if (!fQueryRegistryValue(szKey, L3PKTSIZE, (char*)&dTemp, &dSize))
		dTemp = 128;
	gMgX25_data.dL3PacketSize = dTemp;

}

/*
**	Purpose:
**		Write X.25 specific parameters to the registry from the
**		global structure 
**	Arguments:
**		pointer to the registry location where the params are
**		should be of the form
**      System\CurrentControlSet\Services\<linkservicename>\Parameters\ExtraParameters
**	Returns:
**		none
***************************************************************************/
static void WriteX25Params(char *szKey)
{
	fAddRegistryEntry(szKey,NUAADDR,(char*)(LPCTSTR)gMgX25_data.szNUAAddress,REG_SZ,
		gMgX25_data.szNUAAddress.GetLength()+1);
	fAddRegistryEntry(szKey,INCOMING,(char*)(LPCTSTR)gMgX25_data.szRangeIncoming,REG_SZ,
		gMgX25_data.szRangeIncoming.GetLength()+1);
	fAddRegistryEntry(szKey,OUTGOING,(char*)(LPCTSTR)gMgX25_data.szRangeOutgoing,REG_SZ,
		gMgX25_data.szRangeOutgoing.GetLength()+1);
	fAddRegistryEntry(szKey,TWOWAY,(char*)(LPCTSTR)gMgX25_data.szRangeTwoWay,REG_SZ,
		gMgX25_data.szRangeTwoWay.GetLength()+1);
	fAddRegistryEntry(szKey,PVC,(char*)(LPCTSTR)gMgX25_data.szRangePVC,REG_SZ,
		gMgX25_data.szRangePVC.GetLength()+1);

	DWORD dTemp;
	dTemp = gMgX25_data.bFilter;
	fAddRegistryEntry(szKey,FILTER,(char*)&dTemp,REG_DWORD,sizeof(DWORD));
	dTemp = gMgX25_data.bReverse;
	fAddRegistryEntry(szKey,REVERSE,(char*)&dTemp,REG_DWORD,sizeof(DWORD));
	dTemp = gMgX25_data.bStandby;
	fAddRegistryEntry(szKey,STANDBY,(char*)&dTemp,REG_DWORD,sizeof(DWORD));
	dTemp = gMgX25_data.bStartup;
	fAddRegistryEntry(szKey,STARTUP,(char*)&dTemp,REG_DWORD,sizeof(DWORD));
	fAddRegistryEntry(szKey,N2RETRY,(char*)&gMgX25_data.dN2RetryLimit,REG_DWORD,sizeof(DWORD));
	fAddRegistryEntry(szKey,T1TIMEOUT,(char*)&gMgX25_data.dT1Timeout,REG_DWORD,sizeof(DWORD));

	dTemp = gMgX25_data.bDataRate;
	fAddRegistryEntry(szKey,NRZI,(char*)&dTemp,REG_DWORD,sizeof(DWORD));
	dTemp = gMgX25_data.bEncodingNRZ;
	fAddRegistryEntry(szKey,NRZI,(char*)&dTemp,REG_DWORD,sizeof(DWORD));
	fAddRegistryEntry(szKey,L2WINDOW,(char*)&gMgX25_data.dL2Window,REG_DWORD,sizeof(DWORD));
	fAddRegistryEntry(szKey,L3WINDOW,(char*)&gMgX25_data.dL3Window,REG_DWORD,sizeof(DWORD));
	fAddRegistryEntry(szKey,L3PKTSIZE,(char*)&gMgX25_data.dL3PacketSize,REG_DWORD,sizeof(DWORD));

	dTemp = 2;
	fAddRegistryEntry(szKey,"DiscAction",(char*)&dTemp,REG_DWORD,sizeof(DWORD));
	dTemp = 1;
	fAddRegistryEntry(szKey,"L1Init",(char*)&dTemp,REG_DWORD,sizeof(DWORD));
	fAddRegistryEntry(szKey,"L2Start",(char*)&dTemp,REG_DWORD,sizeof(DWORD));


}

/*
**      Purpose:
**              Configuration Function for an IBM SDLC Adaptor.
**
**      Arguments: 
**
**      Returns:
**              TRUE	if network bindings need to be recalculated
**              FALSE	if network bindings do not need to be recalculated.
**
**      Notes:
**              
**
***************************************************************************/
__declspec(dllexport) BOOL WINAPI ConfigureLinkService(LPSTR szComputerName, 
												LPSTR szLinkServiceTitle)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	BOOL			bReturnCode = FALSE;
	BOOL			bNewLinkService = FALSE;
	
	fConnectRegistry(szComputerName);

	HINSTANCE hInst = AfxGetResourceHandle();
	//
	// Check to see if we have administrative rights to the remote box.
	//
	if (!fCanWeAdministerRemoteBox())
	{
	CHAR		temp_string[32],temp_string2[128];

		LoadString(hInst,IDS_UNABLE_ADMIN_REMOTE_T,temp_string,sizeof(temp_string));
		LoadString(hInst,IDS_UNABLE_ADMIN_REMOTE_M,temp_string2,sizeof(temp_string2));
		::MessageBox(GetActiveWindow(),
					 temp_string2,
					 temp_string,
					 MB_ICONEXCLAMATION);

		return TRUE;
	}

	// Set the Global Global Variables
	SetOSGlobals();

	// if we are adding a new service, find out if we have an available line pre configured to 
	// run SNA
	CString szSNALinePath;
	if (!strcmp(szLinkServiceTitle, ""))
	{
		BOOL bSuccess;

		if (gdwOSMajorVersion <= 4)
			bSuccess = bAvailableSNALineNT4(szSNALinePath);
		else
			bSuccess = bAvailableSNALineNT5(szSNALinePath);

		if (!bSuccess)
		{
			return FALSE;
		}
		bNewLinkService = TRUE;
	}

	
	gMgsdlc_data.bBindingsNeeded = FALSE;

	//
	// Add all Property Pages to the Link Service Property Sheet
	//
	CHdwSettings	cppHdwSettings;
	CModeSet		cppModeSet;
	CX25Settings	cppX25Settings;
	theApp.cpsLinkService.AddPage(&cppModeSet);
	theApp.cpsLinkService.AddPage(&cppHdwSettings);
	theApp.cpsLinkService.AddPage(&cppX25Settings);
	//
	// Setup the global data structure. This will also read data from registry
	//
	fSetupGlobalValues(szLinkServiceTitle, szComputerName, (LPSTR)(LPCTSTR)szSNALinePath);

	CString szLinkServiceNumber(REGSERVICE);
	szLinkServiceNumber += gMgsdlc_data.szLinkServiceName;
	szLinkServiceNumber += REGPARAMS;
	// read our X.25 parameters
	ReadX25Params((char*)(LPCTSTR)szLinkServiceNumber);

	CString szPropSheetTitle(gMgsdlc_data.szLinkServiceTitle);
	szPropSheetTitle += _T(" ");
	szPropSheetTitle += gMgsdlc_data.szCardString;

	theApp.cpsLinkService.SetTitle( szPropSheetTitle );

	//
	// Invoke the Link Service Property Sheet.
	//
	if (IDOK == theApp.cpsLinkService.DoModal())
	{
		//
		// Create the Link Service Service
		//

		fInstallService(bNewLinkService,szComputerName,(LPSTR)(LPCTSTR)szSNALinePath);
		WriteX25Params((char*)(LPCTSTR)szLinkServiceNumber);
	}
	fDisconnectRegistry();
	fAddPerfmonCounters(szComputerName);
	bReturnCode = gMgsdlc_data.bBindingsNeeded;

	return bReturnCode;
}



/*
**      Purpose:
**              Remove Link Service.
**
**      Arguments: 
**
**      Returns:
**              TRUE	if network bindings need to be recalculated
**              FALSE	if network bindings do not need to be recalculated.
**
**      Notes:
**              
**
***************************************************************************/
__declspec(dllexport) BOOL WINAPI RemoveLinkService(LPSTR szComputerName, 
											 LPSTR szLinkServiceTitle)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	// Set the Global Global Variables
	SetOSGlobals();

	return fRemoveLinkService(szComputerName,szLinkServiceTitle);
}




/*
**      Purpose:
**              Remove All IBM SDLC Link Services.
**
**      Arguments: 
**
**      Returns:
**              TRUE	if network bindings need to be recalculated.
**              FALSE	if network bindings do not need to be recalculated.
**
**      Notes:
**              
**
***************************************************************************/
__declspec(dllexport) BOOL WINAPI RemoveAllLinkServices(LPSTR szComputerName)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	// Set the Global Global Variables
	SetOSGlobals();

	return fRemoveAllLinkServices(szComputerName);
}

