/*++
*******************************************************************************
* Copyright (c) 1990-97 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				*
*																										*
*******************************************************************************

Module Name:

   prime.cpp

Abstract:

   Datafire PRIme adapter class implementation.

Author:

   Michael Zarns

--*/

#include "stdafx.h"
#include "sxbmem.h"
#include "RegNames.h"

#include "DigiKme.h"

#include "Dlg.h"
#include "prime.h"

extern CSxbmemApp theApp;

const DWORD FOURMEG = 4 * 1024 * 1024;

IMPLEMENT_DYNCREATE(CDatafirePrime, CAdapter);

BOOL CDatafirePrime::LoadConfig(const CString& keyName)
{
	int anum;
	sscanf(keyName, CString(c_pszKeyServiceName) + "%d", &anum);
	m_Name.Format("[%d] Digi DatafirePrime", anum);

	CString DeviceName = "\\\\.\\" + keyName, error;
	if (!TestAdapter(DeviceName, error)) {
		AfxMessageBox(error);
		return FALSE;
		}

	return TRUE;
}

void CDatafirePrime::LoadSummaryInfo(CStringArray& PortType, const CString& frmvsn)
{
	sDriverInfo DriverInfo;

	GetDriverInfo(DriverInfo, c_pszKeyServiceName);
	m_Drivers.Add(DriverInfo);

	for (short i = 0; i < PortType.GetSize(); i++) {
		CString protocol;

		if (PortType[i] == c_pszValueX25Protocol) {
			GetDriverInfo(DriverInfo, c_pszKeyFR_PVC_ServiceName);
			m_Drivers.Add(DriverInfo);
			protocol = c_pszKeyX25_SVC_ServiceName;
			}
		else if (PortType[i] == c_pszValueFRProtocol)
			protocol = c_pszKeyFR_PVC_ServiceName;
		else if (PortType[i] == "ISDN - PRI")
			protocol = "DigiPRI";
		else
			continue;

		GetDriverInfo(DriverInfo, protocol);
		m_Drivers.Add(DriverInfo);
		}

	m_FirmwareVersion = frmvsn;
}

///////////////////////////////////////
//
//	MemAddress : 0-2meg - size
//	Buffer 		 : pointer to buffer where data is copied to
//	Size			 : size of buffer, on return set to number of 
//							 bytes actually copied, zero on error
//							 Size must not be greater than 16k
//
//	Return value : 0 if error otherwise non zero
//
///////////////////////////////////////
BOOL CDatafirePrime::GetMemory(DWORD MemAddress, LPBYTE Buffer, DWORD *Size) const
{
	DWORD &size = *Size;
	KME_READ Read;

	if ( MemAddress + size > FOURMEG )
		return FALSE;

	if ( *Size == 0 )
		return TRUE;

	ZeroMemory( &Read, sizeof( Read ) );
	Read.Address = MemAddress;
	Read.Length = size;
	Read.pBuffer = Buffer;
 
	CEvent event(FALSE, TRUE);
	OVERLAPPED thisOl = { 0, 0, 0, 0, event };

	DWORD BytesRead = 0;
	::DeviceIoControl(m_hFile, (DWORD)IOCTL_KME_READ, 
	                  &Read, sizeof(KME_READ), 
	                  &Read, sizeof(KME_READ), 
	                  &BytesRead, &thisOl); 

	CSingleLock devIOComplete(&event);
	BOOL bSuccess = devIOComplete.Lock(100);
	size = Read.BytesRead;
	return( bSuccess );
}

BOOL CDatafirePrime::SetMemory(DWORD MemAddress, LPBYTE Buffer, DWORD *Size)
{
	DWORD &size = *Size;
	KME_WRITE Write;

	if ( MemAddress + size > FOURMEG )
		return( FALSE );

	ZeroMemory( &Write, sizeof( Write ) );
	Write.Address = MemAddress;
	Write.Length = size;
	Write.pBuffer = Buffer;

	CEvent event(FALSE, TRUE);
	OVERLAPPED thisOl = { 0, 0, 0, 0, event };

	DWORD BytesWritten = 0;
	::DeviceIoControl(m_hFile, (DWORD)IOCTL_KME_WRITE, 
	                  &Write, sizeof(KME_WRITE), 
	                  &Write, sizeof(KME_WRITE), 
	                  &BytesWritten, &thisOl); 

	CSingleLock devIOComplete(&event);
	BOOL bSuccess = devIOComplete.Lock(1000);
	size = Write.BytesWritten;
	return( bSuccess );
}
