/*****************************************************************************
* 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
*
*****************************************************************************/


// ConfigDigiPamAPort.cpp : implementation file
//

#include "stdafx.h"
#include "resource.h"
#include "ConfigDigiPamAPort.h"
#include "digiinf.h"
#include <winsvc.h>

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

/////////////////////////////////////////////////////////////////////////////
// CConfigDigiPamAPort dialog


CConfigDigiPamAPort::CConfigDigiPamAPort(CWnd* pParent /*=NULL*/)
	: CDialog(CConfigDigiPamAPort::IDD, pParent)
{
	//{{AFX_DATA_INIT(CConfigDigiPamAPort)
	m_PortNumber = WANLINKS_PAM_PORT;
	//}}AFX_DATA_INIT

   RegKey = NULL;
}


CConfigDigiPamAPort::~CConfigDigiPamAPort()
{
	if (RegKey != NULL) RegCloseKey(RegKey);
}

void CConfigDigiPamAPort::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CConfigDigiPamAPort)
	DDX_Text(pDX, IDC_PortNumber, m_PortNumber);
	DDV_MinMaxInt(pDX, m_PortNumber, 1024, 65535);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CConfigDigiPamAPort, CDialog)
	//{{AFX_MSG_MAP(CConfigDigiPamAPort)
	ON_WM_CREATE()
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CConfigDigiPamAPort message handlers

// Please note that these next two functions should really be made common
// and put in DigiFwrk.  But, considering the time, and the fact that the
// DigiFwrk.dsp file has been drastically modified for NT5 stuff, I don't
// think it would be a wise decision to do that right now.  I'm adding
// them here for release F, and then when that ships, I'll come back and
// change it to the right way.

#pragma message("NOTE: NOTE: StartService() should be made a generic/common routine in DigiFwrk\\DriverServices.cpp")
static bool StartService(CString const & ServiceName)
{
	bool Success = false;

	SC_HANDLE SCMHandle = NULL;
	SC_HANDLE ServiceHandle = NULL;

	try
	{
		SCMHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
		AffirmThrow(SCMHandle != NULL);

		ServiceHandle = OpenService(SCMHandle, ServiceName, SERVICE_ALL_ACCESS);
		AffirmThrow(ServiceHandle != NULL);

		BOOL ServiceStarted = ::StartService(ServiceHandle, 0, NULL);
		DWORD LastError = (!ServiceStarted) ? GetLastError() : ERROR_SUCCESS;

		if (ServiceStarted || (LastError == ERROR_SERVICE_ALREADY_RUNNING))
		{
			TRACE("%s has been succeedfully started\n", ServiceName);
			Success = true;
		}
		else
		{
			TRACE("%s StartService() failed!  System error: %d\n", ServiceName, LastError);
		}
   }
   catch(CAffirmException ae)
   {
   }

	if (ServiceHandle != NULL)
		CloseServiceHandle(ServiceHandle);

	if (SCMHandle != NULL)
		CloseServiceHandle(SCMHandle);

	return Success;
}

#pragma message("NOTE: NOTE: StopService() should be made a generic/common routine in DigiFwrk\\DriverServices.cpp")
static bool StopService(CString const & ServiceName)
{
	bool Success = false;

	SC_HANDLE SCMHandle = NULL;
	SC_HANDLE ServiceHandle = NULL;

	try
	{
		SCMHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
		AffirmThrow(SCMHandle != NULL);

		ServiceHandle = OpenService(SCMHandle, ServiceName, SERVICE_ALL_ACCESS);
		AffirmThrow(ServiceHandle != NULL);

		SERVICE_STATUS Status = {0};
		if (ControlService(ServiceHandle, SERVICE_CONTROL_STOP, &Status))
		{
			// The ControlService() returned TRUE, so the service must have been
			// running, and the stop if pending.
			TRACE("Waiting for service to stop.");
			for (int Try = 0;
					Try < 30 &&
					QueryServiceStatus(ServiceHandle, &Status) &&
					Status.dwCurrentState != SERVICE_STOPPED;
					Try++)
			{
				TRACE(".");
				Sleep(1000);
			}
			TRACE("\n");
		}

		TRACE("%s has been succeedfully stopped\n", ServiceName);
		Success = true;
	}
   catch(CAffirmException ae)
   {
   }

	if (ServiceHandle != NULL)
		CloseServiceHandle(ServiceHandle);

	if (SCMHandle != NULL)
		CloseServiceHandle(SCMHandle);

	return Success;
}

void CConfigDigiPamAPort::OnOK() 
{
   try
   {
		if (UpdateData(TRUE))
		{
			AffirmThrow(RegKey != NULL);

			CString PortNumber;
			PortNumber.Format(TEXT(" %d"), m_PortNumber);
			ImagePath += PortNumber;

			Affirm(StopService(WANLINKS_PAMA_SERVICE_NAME_TEXT));
			AffirmThrow(RegWriteExpandStrValue(RegKey, TEXT("ImagePath"), ImagePath));
			Affirm(StartService(WANLINKS_PAMA_SERVICE_NAME_TEXT));

			CDialog::OnOK();
		}
   }
   catch(CAffirmException ae)
   {
   }
}

BOOL CConfigDigiPamAPort::OnInitDialog() 
{
	CDialog::OnInitDialog();

   try
   {
		// when installed, ImagePath looks something like "%SystemRoot%\system32\DigiPamA.exe"
		// if the port has been configured, there may be an optional number at the end, which
		// gets passed to DigiPamA like a command line argument
		TRACE("ImagePath = %s\n", ImagePath);
		int Space = ImagePath.Find(TEXT(' '));
		if (Space > 0)
		{
			TRACE("Found a space at index %d\n", Space);

			CString PortNumber = ImagePath.Right(ImagePath.GetLength() - Space);
			TRACE("Looks like the port number is %s\n", PortNumber);

			m_PortNumber = atoi(PortNumber);

			ImagePath = ImagePath.Left(Space);	// truncate our copy of ImagePath
		}

		UpdateData(FALSE);
   }
   catch(CAffirmException ae)
   {
   }

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

int CConfigDigiPamAPort::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	int Return = -1;	// don't create me

   try
   {
		if (CDialog::OnCreate(lpCreateStruct) != -1)
		{
			AffirmThrow(
				RegOpenKey(
					HKEY_LOCAL_MACHINE, 
					TEXT("SYSTEM\\CurrentControlSet\\Services\\" WANLINKS_PAMA_SERVICE_NAME_QUOT), 
					&RegKey));
			AffirmThrow(RegKey != NULL);

			AffirmThrow(RegReadExpandStrValue(RegKey, TEXT("ImagePath"), ImagePath));

			Return = 0;		// everything is ok, keep going
		}
   }
   catch(CAffirmException ae)
   {
		// if we get here, that's because the registry isn't setup the way we expected
		// we should probably put up an error messagebox or something
   }

	return Return;
}

void CConfigDigiPamAPort::OnDestroy() 
{
#ifdef NT5
	HtmlHelp(NULL, NULL, HH_CLOSE_ALL, 0) ;
#else
	AfxGetApp()->WinHelp(0, HELP_QUIT);
#endif
	CDialog::OnDestroy();
}
