/******************************************************************************
 *                                                                         
 *               (C) COPYRIGHT Pacific MindWorks, Inc. 2001-2005
 *                          All rights reserved.
 *
 *****************************************************************************/

#ifndef __NTLIOPROVIDERNULL_INCLUDED
#define __NTLIOPROVIDERNULL_INCLUDED

#include <stdarg.h>
#include <atlrx.h>
#include "ntlutil.h"

///////////////////////////////////////////////////////////////////////////////
//	CNullIOProvider

class CNullIOProvider :
	public CDriverIOProvider
{
public:
	CNullIOProvider();
	virtual ~CNullIOProvider();

	// Initialization
	virtual HRESULT ioprvInitializeIOProvider(CObjectModelNodeBase* pObjectModelNode, CErrorManagerBase* pErrorManager, CPerfMonManager* pPerfMonManager, BSTR bstrResourceDescriptor);
	virtual HRESULT ioprvCloseIOProvider();
	virtual IOProviderType ioprvGetIOProviderType();

	// IRegister-style functions
	virtual HRESULT ioprvRegisterIn8(UINT16 space, UINT32 offset, UINT8* val);
	virtual HRESULT ioprvRegisterOut8(UINT16 space, UINT32 offset, UINT8 val);
	virtual HRESULT ioprvRegisterIn16(UINT16 space, UINT32 offset, UINT16* val);
	virtual HRESULT ioprvRegisterOut16(UINT16 space, UINT32 offset, UINT16 val);
	virtual HRESULT ioprvRegisterIn32(UINT16 space, UINT32 offset, UINT32* val);
	virtual HRESULT ioprvRegisterOut32(UINT16 space, UINT32 offset, UINT32 val);
	virtual HRESULT ioprvRegisterMoveIn8(UINT16 space, UINT32 offset, UINT32 length, UINT8 buf[]);
	virtual HRESULT ioprvRegisterMoveOut8(UINT16 space, UINT32 offset, UINT32 length, UINT8 buf[]);
	virtual HRESULT ioprvRegisterMoveIn16(UINT16 space, UINT32 offset, UINT32 length, UINT16 buf[]);
	virtual HRESULT ioprvRegisterMoveOut16(UINT16 space, UINT32 offset, UINT32 length, UINT16 buf[]);
	virtual HRESULT ioprvRegisterMoveIn32(UINT16 space, UINT32 offset, UINT32 length, UINT32 buf[]);
	virtual HRESULT ioprvRegisterMoveOut32(UINT16 space, UINT32 offset, UINT32 length, UINT32 buf[]);

protected:
	// IMessage-style functions.
	virtual HRESULT ioprvMessageIORead(BYTE* pBuf, long cbDesired, long* plActualLength);
	virtual HRESULT ioprvMessageIORead(long cbDesired, SAFEARRAY** ppsa);
	virtual HRESULT ioprvMessageIOReadString(long cchDesired, BSTR* pbstrBuf);
	virtual HRESULT ioprvMessageIOWrite(BYTE* pBuf, long cbDesired, long* pcbActual);
	virtual HRESULT ioprvMessageIOWrite(SAFEARRAY* psa, long cbDesired, long* pcbActual);
	virtual HRESULT ioprvMessageIOWriteString(BSTR bstrBuf, long* pcchActual);
	virtual HRESULT ioprvMessageIOClear();
	virtual HRESULT ioprvMessageIOReadSTB(long* plStatus);
	virtual HRESULT ioprvMessageIOSetSendEndEnabled(bool bEnable);
	virtual HRESULT ioprvMessageIOGetSendEndEnabled(bool* pbEnable);
	virtual HRESULT ioprvMessageIOSetTerminationCharacter(BYTE val);
	virtual HRESULT ioprvMessageIOGetTerminationCharacter(BYTE* pVal);
	virtual HRESULT ioprvMessageIOSetTerminationCharacterEnabled(bool bEnable);
	virtual HRESULT ioprvMessageIOGetTerminationCharacterEnabled(bool* pbEnable);
	virtual HRESULT ioprvMessageIOSetTimeout(long lTimeout);
	virtual HRESULT ioprvMessageIOGetTimeout(long* plTimeout);

	// Formatted I/O functions.
	virtual HRESULT ioprvFormattedIOSetInstrumentBigEndian(bool bBigEndian);
	virtual HRESULT ioprvFormattedIOGetInstrumentBigEndian(bool* pbBigEndian);
	virtual HRESULT ioprvFormattedIOWriteString(const CString& strData, bool bFlushAndEnd);
	virtual HRESULT ioprvFormattedIOWriteNumber(VARIANT data, NtlAsciiType type, bool bFlushAndEnd);
	virtual HRESULT ioprvFormattedIOWriteList(VARIANT data, NtlAsciiType type, const CString& strListSeparator, bool bFlushAndEnd);
	virtual HRESULT ioprvFormattedIOWriteIEEEBlock(const CString& strCommand, VARIANT data, bool bFlushAndEnd);
	virtual HRESULT ioprvFormattedIOReadString(CString& strData);
	virtual HRESULT ioprvFormattedIOReadNumber(NtlAsciiType type, VARIANT* pData, bool bFlushToEnd);
	virtual HRESULT ioprvFormattedIOReadList(NtlAsciiType type, const CString& strListSeparator, VARIANT* pData);
	virtual HRESULT ioprvFormattedIOReadIEEEBlock(NtlBinaryType type, VARIANT* pData, bool bSeekToBlock, bool bFlushToEnd);
	virtual HRESULT ioprvFormattedIOFlushWrite(bool bSendEND);
	virtual HRESULT ioprvFormattedIOFlushRead();
	virtual HRESULT ioprvFormattedIOSetBufferSize(NtlBufferMask mask, long lSize);

protected:
	HRESULT CreateVariant(NtlAsciiType type, VARIANT* pData);
	HRESULT CreateArray(NtlAsciiType type, VARIANT* pData);
	HRESULT CreateArray(NtlBinaryType type, VARIANT* pData);

protected:
	bool m_bBigEndian;
	long m_lTimeout;
	BYTE m_nTerminationChar;
	bool m_bTerminationCharEnabled;
	bool m_bSendEndEnabled;
};


inline CNullIOProvider::CNullIOProvider() 
	: m_bBigEndian(false), m_lTimeout(2), m_nTerminationChar(0), m_bTerminationCharEnabled(false), m_bSendEndEnabled(false)
{
}

inline CNullIOProvider::~CNullIOProvider()
{
}

inline HRESULT CNullIOProvider::ioprvInitializeIOProvider(CObjectModelNodeBase* pObjectModelNode, CErrorManagerBase* pErrorManager, CPerfMonManager* pPerfMonManager, BSTR bstrResourceDescriptor)
{
	if (pErrorManager == NULL)
		return E_INVALIDARG;

	if (pPerfMonManager == NULL)
		return E_INVALIDARG;

	if (bstrResourceDescriptor == NULL)
		return E_INVALIDARG;

	HRESULT hr = S_OK;

	// If it already has been initialized, then it will get closed
	ioprvCloseIOProvider();

	// Initialize base class
	hr = __super::ioprvInitializeIOProvider(pObjectModelNode, pErrorManager, pPerfMonManager, bstrResourceDescriptor);

	return hr;
}

inline HRESULT CNullIOProvider::ioprvCloseIOProvider()
{
	HRESULT hr = S_OK;

	hr = __super::ioprvCloseIOProvider();

	return hr;
}

inline IOProviderType CNullIOProvider::ioprvGetIOProviderType()
{
	return NullIOProvider;
}

inline HRESULT CNullIOProvider::ioprvMessageIORead(BYTE* pBuf, long cbDesired, long* plActualLength)
{
	IO_METHOD_START();

	if (cbDesired < 0)
		return E_INVALIDARG;

	if (pBuf == NULL)
		return E_INVALIDARG;

	if (plActualLength == NULL)
		return E_POINTER;
	*plActualLength = 0;

	HRESULT hr = S_OK;

	for (int i = 0; i < cbDesired; i++)
	{
		pBuf[i] = 0;
	}
	*plActualLength = cbDesired;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvMessageIORead(long cbDesired, SAFEARRAY** ppsa)
{
	IO_METHOD_START();

	if (cbDesired < 0)
		return E_INVALIDARG;

	if (ppsa == NULL)
		return E_POINTER;
	*ppsa = NULL;

	HRESULT hr = S_OK;

	*ppsa = ::SafeArrayCreateVector(VT_UI1, 0, 0);

	return hr;
}

inline HRESULT CNullIOProvider::ioprvMessageIOReadString(long cchDesired, BSTR* pbstrBuf)
{
	IO_METHOD_START();

	if (cchDesired < 0)
		return E_INVALIDARG;

	if (pbstrBuf == NULL)
		return E_POINTER;
	*pbstrBuf = NULL;

	HRESULT hr = S_OK;

    *pbstrBuf = CComBSTR("0").Detach();

	return hr;
}

inline HRESULT CNullIOProvider::ioprvMessageIOWrite(BYTE* pBuf, long cbDesired, long* pcbActual)
{
	IO_METHOD_START();

	if (pBuf == NULL)
		return E_INVALIDARG;

	if (cbDesired < 0)
		return E_INVALIDARG;

	if (pcbActual == NULL)
		return E_POINTER;
	*pcbActual = 0;

	HRESULT hr = S_OK;

	*pcbActual = cbDesired;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvMessageIOWrite(SAFEARRAY* psa, long cbDesired, long* pcbActual)
{
	IO_METHOD_START();

	if (psa == NULL)
		return E_INVALIDARG;

	if (cbDesired < 0)
		return E_INVALIDARG;

	if (pcbActual == NULL)
		return E_POINTER;
	*pcbActual = 0;

	HRESULT hr = S_OK;

	*pcbActual = cbDesired;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvMessageIOWriteString(BSTR bstrBuf, long* pcchActual)
{
	IO_METHOD_START();

	if (bstrBuf == NULL)
		return E_INVALIDARG;

	if (pcchActual == NULL)
		return E_POINTER;
	*pcchActual = 0;

	HRESULT hr = S_OK;

	*pcchActual = ::SysStringLen(bstrBuf);

	return hr;
}

inline HRESULT CNullIOProvider::ioprvMessageIOClear()
{
	IO_METHOD_START();

	HRESULT hr = S_OK;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvMessageIOReadSTB(long* plStatus)
{
	IO_METHOD_START();

	if (plStatus == NULL)
		return E_POINTER;
	*plStatus = 0;

	HRESULT hr = S_OK;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvMessageIOSetSendEndEnabled(bool bEnable)
{
	IO_METHOD_START();

	HRESULT hr = S_OK;

	m_bSendEndEnabled = bEnable;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvMessageIOGetSendEndEnabled(bool* pbEnable)
{
	IO_METHOD_START();

	if (pbEnable == NULL)
		return E_POINTER;

	HRESULT hr = S_OK;

	*pbEnable = m_bSendEndEnabled;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvMessageIOSetTerminationCharacter(BYTE val)
{
	IO_METHOD_START();

	HRESULT hr = S_OK;

	m_nTerminationChar = val;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvMessageIOGetTerminationCharacter(BYTE* pVal)
{
	IO_METHOD_START();

	if (pVal == NULL)
		return E_POINTER;

	HRESULT hr = S_OK;

	*pVal = m_nTerminationChar;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvMessageIOSetTerminationCharacterEnabled(bool bEnable)
{
	IO_METHOD_START();

	HRESULT hr = S_OK;

	m_bTerminationCharEnabled = bEnable;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvMessageIOGetTerminationCharacterEnabled(bool* pbEnable)
{
	IO_METHOD_START();

	if (pbEnable == NULL)
		return E_POINTER;

	HRESULT hr = S_OK;

	*pbEnable = m_bTerminationCharEnabled;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvMessageIOSetTimeout(long lTimeout)
{
	IO_METHOD_START();

	HRESULT hr = S_OK;

	m_lTimeout = lTimeout;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvMessageIOGetTimeout(long* plTimeout)
{
	IO_METHOD_START();

	if (plTimeout == NULL)
		return E_POINTER;

	HRESULT hr = S_OK;

	*plTimeout = m_lTimeout;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvFormattedIOSetInstrumentBigEndian(bool bBigEndian)
{
	IO_METHOD_START();

	HRESULT hr = S_OK;

	m_bBigEndian = bBigEndian;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvFormattedIOGetInstrumentBigEndian(bool* pbBigEndian)
{
	IO_METHOD_START();

	if (pbBigEndian == NULL)
		return E_POINTER;

	HRESULT hr = S_OK;

	*pbBigEndian = m_bBigEndian;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvFormattedIOWriteString(const CString& strData, bool bFlushAndEnd)
{
	NTL_UNUSED(strData);
	NTL_UNUSED(bFlushAndEnd);

	IO_METHOD_START();

	HRESULT hr = S_OK;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvFormattedIOWriteNumber(VARIANT data, NtlAsciiType type, bool bFlushAndEnd)
{
	NTL_UNUSED(data);
	NTL_UNUSED(type);
	NTL_UNUSED(bFlushAndEnd);

	IO_METHOD_START();

	HRESULT hr = S_OK;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvFormattedIOWriteList(VARIANT data, NtlAsciiType type, const CString& strListSeparator, bool bFlushAndEnd)
{
	NTL_UNUSED(data);
	NTL_UNUSED(type);
	NTL_UNUSED(strListSeparator);
	NTL_UNUSED(bFlushAndEnd);

	IO_METHOD_START();

	HRESULT hr = S_OK;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvFormattedIOWriteIEEEBlock(const CString& strCommand, VARIANT data, bool bFlushAndEnd)
{
	NTL_UNUSED(strCommand);
	NTL_UNUSED(data);
	NTL_UNUSED(bFlushAndEnd);

	IO_METHOD_START();

	HRESULT hr = S_OK;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvFormattedIOReadString(CString& strData)
{
	IO_METHOD_START();

	HRESULT hr = S_OK;

	strData = _T("");

	return hr;
}

inline HRESULT CNullIOProvider::ioprvFormattedIOReadNumber(NtlAsciiType type, VARIANT* pData, bool bFlushToEnd)
{
	NTL_UNUSED(bFlushToEnd);

	IO_METHOD_START();

	if (pData == NULL)
		return E_POINTER;

	HRESULT hr = S_OK;

	hr = CreateVariant(type, pData);

	return hr;
}

inline HRESULT CNullIOProvider::ioprvFormattedIOReadList(NtlAsciiType type, const CString& strListSeparator, VARIANT* pData)
{
	NTL_UNUSED(strListSeparator);

	IO_METHOD_START();

	if (pData == NULL)
		return E_POINTER;

	HRESULT hr = S_OK;

	hr = CreateArray(type, pData);

	return hr;
}

inline HRESULT CNullIOProvider::ioprvFormattedIOReadIEEEBlock(NtlBinaryType type, VARIANT* pData, bool bSeekToBlock, bool bFlushToEnd)
{
	NTL_UNUSED(bSeekToBlock);
	NTL_UNUSED(bFlushToEnd);

	IO_METHOD_START();

	if (pData == NULL)
		return E_POINTER;

	HRESULT hr = S_OK;

	hr = CreateArray(type, pData);

	return hr;
}

inline HRESULT CNullIOProvider::ioprvFormattedIOFlushWrite(bool bSendEND)
{
	NTL_UNUSED(bSendEND);

	IO_METHOD_START();

	HRESULT hr = S_OK;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvFormattedIOFlushRead()
{
	IO_METHOD_START();

	HRESULT hr = S_OK;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvFormattedIOSetBufferSize(NtlBufferMask mask, long lSize)
{
	NTL_UNUSED(mask);
	NTL_UNUSED(lSize);

	IO_METHOD_START();

	HRESULT hr = S_OK;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvRegisterIn8(UINT16 space, UINT32 offset, UINT8* val)
{
	NTL_UNUSED(space);
	NTL_UNUSED(offset);

	IO_METHOD_START();

	if (val == NULL)
		return E_POINTER;
	*val = 0;

	HRESULT hr = S_OK;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvRegisterOut8(UINT16 space, UINT32 offset, UINT8 val)
{
	NTL_UNUSED(space);
	NTL_UNUSED(offset);
	NTL_UNUSED(val);

	IO_METHOD_START();

	HRESULT hr = S_OK;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvRegisterIn16(UINT16 space, UINT32 offset, UINT16* val)
{
	NTL_UNUSED(space);
	NTL_UNUSED(offset);

	IO_METHOD_START();

	if (val == NULL)
		return E_POINTER;
	*val = 0;

	HRESULT hr = S_OK;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvRegisterOut16(UINT16 space, UINT32 offset, UINT16 val)
{
	NTL_UNUSED(space);
	NTL_UNUSED(offset);
	NTL_UNUSED(val);

	IO_METHOD_START();

	HRESULT hr = S_OK;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvRegisterIn32(UINT16 space, UINT32 offset, UINT32* val)
{
	NTL_UNUSED(space);
	NTL_UNUSED(offset);

	IO_METHOD_START();

	if (val == NULL)
		return E_POINTER;
	*val = 0;

	HRESULT hr = S_OK;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvRegisterOut32(UINT16 space, UINT32 offset, UINT32 val)
{
	NTL_UNUSED(space);
	NTL_UNUSED(offset);
	NTL_UNUSED(val);

	IO_METHOD_START();

	HRESULT hr = S_OK;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvRegisterMoveIn8(UINT16 space, UINT32 offset, UINT32 length, UINT8 buf[])
{
	NTL_UNUSED(space);
	NTL_UNUSED(offset);
	NTL_UNUSED(length);

	IO_METHOD_START();

	if (buf == NULL)
		return E_INVALIDARG;

	HRESULT hr = S_OK;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvRegisterMoveOut8(UINT16 space, UINT32 offset, UINT32 length, UINT8 buf[])
{
	NTL_UNUSED(space);
	NTL_UNUSED(offset);
	NTL_UNUSED(length);

	IO_METHOD_START();

	if (buf == NULL)
		return E_INVALIDARG;

	HRESULT hr = S_OK;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvRegisterMoveIn16(UINT16 space, UINT32 offset, UINT32 length, UINT16 buf[])
{
	NTL_UNUSED(space);
	NTL_UNUSED(offset);
	NTL_UNUSED(length);

	IO_METHOD_START();

	if (buf == NULL)
		return E_INVALIDARG;

	HRESULT hr = S_OK;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvRegisterMoveOut16(UINT16 space, UINT32 offset, UINT32 length, UINT16 buf[])
{
	NTL_UNUSED(space);
	NTL_UNUSED(offset);
	NTL_UNUSED(length);

	IO_METHOD_START();

	if (buf == NULL)
		return E_INVALIDARG;

	HRESULT hr = S_OK;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvRegisterMoveIn32(UINT16 space, UINT32 offset, UINT32 length, UINT32 buf[])
{
	NTL_UNUSED(space);
	NTL_UNUSED(offset);
	NTL_UNUSED(length);

	IO_METHOD_START();

	if (buf == NULL)
		return E_INVALIDARG;

	HRESULT hr = S_OK;

	return hr;
}

inline HRESULT CNullIOProvider::ioprvRegisterMoveOut32(UINT16 space, UINT32 offset, UINT32 length, UINT32 buf[])
{
	NTL_UNUSED(space);
	NTL_UNUSED(offset);
	NTL_UNUSED(length);

	IO_METHOD_START();

	if (buf == NULL)
		return E_INVALIDARG;

	HRESULT hr = S_OK;

	return hr;
}

inline HRESULT CNullIOProvider::CreateVariant(NtlAsciiType type, VARIANT* pData)
{
	if (pData == NULL)
		return E_POINTER;

	HRESULT hr = S_OK;

	VariantInit(pData);

	switch (type)
	{
		case NtlAsciiType_I2:
			pData->vt = VT_I2;
			pData->iVal = 0;
			break;
		case NtlAsciiType_I4:
			pData->vt = VT_I4;
			pData->lVal = 0;
			break;
		case NtlAsciiType_R4:
			pData->vt = VT_R4;
			pData->fltVal = 0;
			break;
		case NtlAsciiType_R8:
			pData->vt = VT_R8;
			pData->dblVal = 0;
			break;
		case NtlAsciiType_BSTR:
			pData->vt = VT_BSTR;
			pData->bstrVal = CComBSTR("").Detach();
			break;
		case NtlAsciiType_Any:
			pData->vt = VT_I4;
			pData->lVal = 0;
			break;
		case NtlAsciiType_UI1:
			pData->vt = VT_UI1;
			pData->bVal = 0;
			break;
		default:
			hr = E_FAIL;
			break;
	}

	return hr;
}

inline HRESULT CNullIOProvider::CreateArray(NtlAsciiType type, VARIANT* pData)
{
	if (pData == NULL)
		return E_POINTER;

	HRESULT hr = S_OK;

	VariantInit(pData);

	VARTYPE vt = VT_R4;

	switch (type)
	{
		case NtlAsciiType_I2:
			vt = VT_I2;
			break;
		case NtlAsciiType_I4:
			vt = VT_I4;
			break;
		case NtlAsciiType_R4:
			vt = VT_R4;
			break;
		case NtlAsciiType_R8:
			vt = VT_R8;
			break;
		case NtlAsciiType_BSTR:
			vt = VT_BSTR;
			break;
		case NtlAsciiType_Any:
			vt = VT_I4;
			break;
		case NtlAsciiType_UI1:
			vt = VT_UI1;
			break;
		default:
			hr = E_FAIL;
			break;
	}

	if (SUCCEEDED(hr))
	{
		SAFEARRAY* psa = ::SafeArrayCreateVector(vt, 0, 0);

		if (psa != NULL)
		{
			pData->vt = (VARTYPE)(VT_ARRAY | vt);
			pData->parray = psa;
		}
		else
		{
			hr = E_FAIL;
		}
	}

	return hr;
}

inline HRESULT CNullIOProvider::CreateArray(NtlBinaryType type, VARIANT* pData)
{
	if (pData == NULL)
		return E_POINTER;

	HRESULT hr = S_OK;

	VariantInit(pData);
	
	VARTYPE vt = VT_R4;

	switch (type)
	{
		case NtlBinaryType_I2:
			vt = VT_I2;
			break;
		case NtlBinaryType_I4:
			vt = VT_I4;
			break;
		case NtlBinaryType_R4:
			vt = VT_R4;
			break;
		case NtlBinaryType_R8:
			vt = VT_R8;
			break;
		case NtlBinaryType_UI1:
			vt = VT_UI1;
			break;
		default:
			hr = E_FAIL;
			break;
	}

	if (SUCCEEDED(hr))
	{
		SAFEARRAY* psa = ::SafeArrayCreateVector(vt, 0, 0);

		if (psa != NULL)
		{
			pData->vt = (VARTYPE)(VT_ARRAY | vt);
			pData->parray = psa;
		}
		else
		{
			hr = E_FAIL;
		}
	}

	return hr;
}

#endif // #endif __NTLIOPROVIDERNULL_INCLUDED
