/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * WinIoEx - WinIoEx_CPP.cpp
 *
 * WinIoEx Copyright (C) 2009-2010 Doug Chen.
 * 
 *
 * You can use the binary files or source code, I DO NOT restrict you anything on anywhere even 
 * commercial purpose, but please send a mail or leave a message on MSN to me before releasing your 
 * project for encourage me keep going on the project, thank you.
 *
 *
 *                                                           Doug Chen, 2009/11/10 20:23 Taiwan Taipei
 *	
 *	Name		: Doug Chen  (³―Αδ·½)
 * 	Email		: dougchen850208@gmail.com
 * 	MSN			: dougchen850208@gmail.com
 *  Location	: Taiwan Taipei
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */



#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>


#include "WinIoEx_CPP.h"
#include "..\..\All\Common\WinIoEx_Define.h"


#include "IoCtrlCode.h"
#include "..\NtDriverInstaller\NtDriverInstaller.h"




//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
WinIoEx::WinIoEx()
{
	g_ShowErrorDetailMsg = false;
}





//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
WinIoEx::~WinIoEx()
{
	UnInit();
}




//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
bool WinIoEx::IsWinIoExReady()
{
	ERR_INFO		m_ErrInfo;

	if(g_DriverHandle==NULL)
	{	
		//===================================================================
		//Set Error Info.
		m_ErrInfo.ErrorLine = __LINE__;
		m_ErrInfo.FunctionName.assign(__FUNCTION__);
		m_ErrInfo.FileName.assign(__FILE__);
		m_ErrInfo.TimeStamp.assign(__TIMESTAMP__);	
		m_ErrInfo.ClasName.assign(typeid(*this).name());
		m_ErrInfo.WinNtFunctioName.assign("");
		m_ErrInfo.WinNtLastError = ERROR_INVALID_HANDLE;
		GetLastErrorInfo(m_ErrInfo);
		return false;
	}

	return true;	
}




//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
bool WinIoEx::IsFixedDrive(wchar_t *_drive)
{
	wchar_t		m_Buff[1024] = {0};	
	wcsncpy(m_Buff,_drive,3);
	ERR_INFO	m_ErrInfo;


	switch(	GetDriveType(m_Buff))
	{
	case 	DRIVE_UNKNOWN:		// The drive type cannot be determined. 
	case	DRIVE_NO_ROOT_DIR:	// The root path is invalid; for example, there is no volume is mounted at the path.
  //case	DRIVE_REMOVABLE:	// The drive has removable media; for example, a floppy drive, thumb drive, or flash card reader.
	case	DRIVE_REMOTE:		// The drive is a remote (network) drive.
	case	DRIVE_CDROM:		// The drive is a CD-ROM drive.
	case	DRIVE_RAMDISK:		// The drive is a RAM disk.

		//===================================================================
		//Set Error Info.
		m_ErrInfo.ErrorLine = __LINE__;
		m_ErrInfo.FunctionName.assign(__FUNCTION__);
		m_ErrInfo.FileName.assign(__FILE__);
		m_ErrInfo.TimeStamp.assign(__TIMESTAMP__);	
		m_ErrInfo.ClasName.assign(typeid(*this).name());
		m_ErrInfo.WinNtFunctioName.assign("GetDriveType(...)");
		m_ErrInfo.CustomizeMsg.assign("NOT_CORRECT_DRIVE");		
		m_ErrInfo.WinNtLastError = ERROR_SUCCESS;
		GetLastErrorInfo(m_ErrInfo);
		return false;

		
	case	DRIVE_REMOVABLE:
	case	DRIVE_FIXED:

		return true;


	default:		
		//===================================================================
		//Set Error Info.
		m_ErrInfo.ErrorLine = __LINE__;
		m_ErrInfo.FunctionName.assign(__FUNCTION__);
		m_ErrInfo.FileName.assign(__FILE__);
		m_ErrInfo.TimeStamp.assign(__TIMESTAMP__);	
		m_ErrInfo.ClasName.assign(typeid(*this).name());
		m_ErrInfo.WinNtFunctioName.assign("GetDriveType(...)");
		m_ErrInfo.CustomizeMsg.assign("SWITCH_CASE_LOSS");		
		m_ErrInfo.WinNtLastError = ERROR_SUCCESS;
		GetLastErrorInfo(m_ErrInfo);
		return false;

	}
}

//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/09/04
//******************************************************************************************************
void WinIoEx::GetLastErrorInfo()
{
	char	m_MsgBuff[2048]	 = {0};
	char	m_MsgQueue[2048]	 = {0};
	vector<string>	m_InfoList;

	m_InfoList.push_back("Error Line \t =    ");
	m_InfoList.push_back("WIN32 Last Error \t =    ");
	m_InfoList.push_back("Time Stamp \t =    ");
	m_InfoList.push_back("File Name \t =    ");
	m_InfoList.push_back("Class Name \t =    ");
	m_InfoList.push_back("CustomizeMsg \t =    ");	
	m_InfoList.push_back("WIN32 API Name \t =    ");
	m_InfoList.push_back("Function Name \t =    ");	

	

	strcat(m_MsgQueue,m_InfoList[0].c_str());		sprintf(m_MsgBuff,"%d \r\n",g_ErrInfo.ErrorLine);					strcat(m_MsgQueue,m_MsgBuff);
	strcat(m_MsgQueue,m_InfoList[1].c_str());		sprintf(m_MsgBuff,"%d \r\n",g_ErrInfo.WinNtLastError);				strcat(m_MsgQueue,m_MsgBuff);
	strcat(m_MsgQueue,m_InfoList[2].c_str());		sprintf(m_MsgBuff,"%s \r\n",g_ErrInfo.TimeStamp.c_str());			strcat(m_MsgQueue,m_MsgBuff);
	strcat(m_MsgQueue,m_InfoList[3].c_str());		sprintf(m_MsgBuff,"%s \r\n",g_ErrInfo.FileName.c_str());			strcat(m_MsgQueue,m_MsgBuff);
	strcat(m_MsgQueue,m_InfoList[4].c_str());		sprintf(m_MsgBuff,"%s \r\n",g_ErrInfo.ClasName.c_str());			strcat(m_MsgQueue,m_MsgBuff);
	strcat(m_MsgQueue,m_InfoList[5].c_str());		sprintf(m_MsgBuff,"%s \r\n",g_ErrInfo.WinNtFunctioName.c_str());	strcat(m_MsgQueue,m_MsgBuff);
	strcat(m_MsgQueue,m_InfoList[6].c_str());		sprintf(m_MsgBuff,"%s \r\n",g_ErrInfo.FunctionName.c_str());		strcat(m_MsgQueue,m_MsgBuff);
	strcat(m_MsgQueue,m_InfoList[7].c_str());		sprintf(m_MsgBuff,"%s \r\n",g_ErrInfo.CustomizeMsg.c_str());		strcat(m_MsgQueue,m_MsgBuff);
	
	


	MessageBoxA(NULL,m_MsgQueue,"INFO",MB_OK);


}





//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/09/04
//******************************************************************************************************
void WinIoEx::GetLastErrorInfo(ERR_INFO  &m_ErrInfo)
{
	if(m_ErrInfo.ClasName.length()==0)				{m_ErrInfo.ClasName.assign("NULL");}
	if(m_ErrInfo.FileName.length()==0)				{m_ErrInfo.FileName.assign("NULL");}
	if(m_ErrInfo.TimeStamp.length()==0)			{m_ErrInfo.TimeStamp.assign("NULL");}
	if(m_ErrInfo.FunctionName.length()==0)			{m_ErrInfo.FunctionName.assign("NULL");}
	if(m_ErrInfo.WinNtFunctioName.length()==0)		{m_ErrInfo.WinNtFunctioName.assign("NULL");}


	memcpy(&g_ErrInfo,&m_ErrInfo,sizeof(ERR_INFO));
	GetLastErrorInfo();
}






//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
bool WinIoEx::EnableLastErrorInfoMsg()
{
	g_ShowErrorDetailMsg = true;
	g_NtDrvInstall.EnableLastErrorInfoMsg();
	return true;
}








//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
bool WinIoEx::Init()
{
	wchar_t			m_BinaryAbsPath[1024]	= {0};
	ERR_INFO		m_ErrInfo;

	wcscpy(WINIOEX_DRIVER_NAME,L"WINIOEX");
	wcscpy(WINIOEX_BINARY_NAME,L"WINIOEX.SYS");


	GetFullPathName(WINIOEX_BINARY_NAME, 256, m_BinaryAbsPath, NULL);
	if(GetLastError()!=0)
	{
		//===================================================================
		//Set Error Info.
		m_ErrInfo.ErrorLine = __LINE__;
		m_ErrInfo.FunctionName.assign(__FUNCTION__);
		m_ErrInfo.FileName.assign(__FILE__);
		m_ErrInfo.TimeStamp.assign(__TIMESTAMP__);	
		m_ErrInfo.ClasName.assign(typeid(*this).name());
		m_ErrInfo.WinNtFunctioName.assign("GetFullPathName(...)");
		m_ErrInfo.CustomizeMsg.assign("");		
		m_ErrInfo.WinNtLastError = GetLastError();
		GetLastErrorInfo(m_ErrInfo);
		return false;
	}



	if(!IsFixedDrive(m_BinaryAbsPath))
	{
		return false;
	}



	if( wcscmp(m_BinaryAbsPath,	L"")==0)		
	{
		//===================================================================
		//Set Error Info.
		m_ErrInfo.ErrorLine = __LINE__;
		m_ErrInfo.FunctionName.assign(__FUNCTION__);
		m_ErrInfo.FileName.assign(__FILE__);
		m_ErrInfo.TimeStamp.assign(__TIMESTAMP__);	
		m_ErrInfo.ClasName.assign(typeid(*this).name());
		m_ErrInfo.WinNtFunctioName.assign("");
		m_ErrInfo.CustomizeMsg.assign("WRONG_DLL_PATH");		
		m_ErrInfo.WinNtLastError = ERROR_SUCCESS;
		GetLastErrorInfo(m_ErrInfo);
		return false;	
	}

	
	if(!g_NtDrvInstall.InstallDriver(WINIOEX_DRIVER_NAME,WINIOEX_BINARY_NAME))
	{		
		return false;
	}


	
	if(!g_NtDrvInstall.StartDriver(WINIOEX_DRIVER_NAME))
	{
		return false;
	}

	
	if(!g_NtDrvInstall.CreateHandle(WINIOEX_DRIVER_NAME))
	{
		return false;
	}

	if(g_DriverHandle!=NULL)
	{
		CloseHandle(g_DriverHandle);
		g_DriverHandle = NULL;
	}
	g_NtDrvInstall.GetHandle(&g_DriverHandle);


	if(g_DriverHandle==NULL)
	{
		return false;
	}



	return true;
}




//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
bool WinIoEx::UnInit()
{
	ERR_INFO		m_ErrInfo;


	g_DriverHandle = NULL;
	// --------------------------------------
	// Don't close the handle here.
	// --------------------------------------
	//if(	g_DriverHandle != NULL)
	//{
	//	CloseHandle(g_DriverHandle);
	//	g_DriverHandle = NULL;		
	//}
	//
	//if(GetLastError()!=0)
	//{
	//	//===================================================================
	//	//Set Error Info.
	//	m_ErrInfo.ErrorLine = __LINE__;
	//	m_ErrInfo.FunctionName.assign(__FUNCTION__);
	//	m_ErrInfo.FileName.assign(__FILE__);
	//	m_ErrInfo.TimeStamp.assign(__TIMESTAMP__);	
	//	m_ErrInfo.ClasName.assign(typeid(*this).name());
	//	m_ErrInfo.WinNtFunctioName.assign("CloseHandle");
	//	m_ErrInfo.CustomizeMsg.assign("");		
	//	m_ErrInfo.WinNtLastError = GetLastError();
	//	GetLastErrorInfo(m_ErrInfo);
	//	return false;
	//}




	if(!g_NtDrvInstall.TerminalHandle())
	{	
		return false;
	}

	if(!g_NtDrvInstall.RemoveDriver(WINIOEX_DRIVER_NAME))
	{
		return false;
	}

	return true;
}







//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
bool WinIoEx::IoControlExecute(unsigned long _io_ctrl_code,unsigned long _buff_size, unsigned char _cmd_count)
{
	unsigned char		m_RetDevIoCtrl	= 0;	
	unsigned long		m_RetBuffLen	= 0;
	unsigned char		*m_pBuff		= NULL;

	ERR_INFO			m_ErrInfo;

	if(g_DriverHandle==NULL)
	{
		//===================================================================
		//Set Error Info.
		m_ErrInfo.ErrorLine = __LINE__;
		m_ErrInfo.FunctionName.assign(__FUNCTION__);
		m_ErrInfo.FileName.assign(__FILE__);
		m_ErrInfo.TimeStamp.assign(__TIMESTAMP__);	
		m_ErrInfo.ClasName.assign(typeid(*this).name());
		m_ErrInfo.WinNtFunctioName.assign("");
		m_ErrInfo.CustomizeMsg.assign("ACCESS_HANDLE_NOT_READY");		
		m_ErrInfo.WinNtLastError = ERROR_SUCCESS;
		GetLastErrorInfo(m_ErrInfo);
		return false;
	}



	if(!IsWinIoExReady())
	{
		return false;	
	}


	//if(_CmdElementCount<=0)
	//{
	//	return GErrorCode(WINIOEX_DLL_WINIOEX,	WINIOEX_IOCONTROL_EXECUTE_FAILED,	ERR_IOCONTROL_CMDLESS_THAN_ZERO);
	//}


	switch(_io_ctrl_code)
	{
		//-------------------------------------------------
	case IOCTL_IOPORT_AVAILABLE:
		m_pBuff = (unsigned char*)&g_DevExt.Pkg16;
		break;

		//-------------------------------------------------
	case IOCTL_IOPORT_GET_UCHAR:
	case IOCTL_IOPORT_SET_UCHAR:
	case IOCTL_IOPORT_GET_USHORT:
	case IOCTL_IOPORT_SET_USHORT:
	case IOCTL_IOPORT_GET_ULONG:
	case IOCTL_IOPORT_SET_ULONG:
		m_pBuff = (unsigned char*)&g_DevExt.Pkg16.Element;
		break;
		//-------------------------------------------------
	case IOCTL_CPU_GET_MSR:
	case IOCTL_CPU_SET_MSR:
		m_pBuff = (unsigned char*)&g_DevExt.CpuRegs;
		break;

		//-------------------------------------------------
	case IOCTL_MEM_GET_BLOCK:
	case IOCTL_MEM_SET_BLOCK:
		m_pBuff = (unsigned char*)&g_DevExt.Pkg1K;
		break;
	default:
		//===================================================================
		//Set Error Info.
		m_ErrInfo.ErrorLine = __LINE__;
		m_ErrInfo.FunctionName.assign(__FUNCTION__);
		m_ErrInfo.FileName.assign(__FILE__);
		m_ErrInfo.TimeStamp.assign(__TIMESTAMP__);	
		m_ErrInfo.ClasName.assign(typeid(*this).name());
		m_ErrInfo.WinNtFunctioName.assign("");
		m_ErrInfo.CustomizeMsg.assign("SWITCH_LOSS_IOCONTROLCODE");		
		m_ErrInfo.WinNtLastError = ERROR_SUCCESS;
		GetLastErrorInfo(m_ErrInfo);
		return false;
	}





	m_RetDevIoCtrl = DeviceIoControl(
		g_DriverHandle,		// Handle to device
		_io_ctrl_code,		// IO Control code for Read
		m_pBuff,			// Buffer to driver.
		_buff_size,			// Length of buffer in bytes.
		m_pBuff,			// Buffer from driver.
		_buff_size,			// Length of buffer in bytes.
		&m_RetBuffLen,		// Bytes placed in DataBuffer.
		NULL				// NULL means wait till op. completes.
		);

	if (m_RetDevIoCtrl == FALSE)
	{
		//===================================================================
		//Set Error Info.
		m_ErrInfo.ErrorLine = __LINE__;
		m_ErrInfo.FunctionName.assign(__FUNCTION__);
		m_ErrInfo.FileName.assign(__FILE__);
		m_ErrInfo.TimeStamp.assign(__TIMESTAMP__);	
		m_ErrInfo.ClasName.assign(typeid(*this).name());
		m_ErrInfo.WinNtFunctioName.assign("DeviceIoControl()");
		m_ErrInfo.CustomizeMsg.assign("");
		m_ErrInfo.WinNtLastError = ERROR_SUCCESS;
		GetLastErrorInfo(m_ErrInfo);		
		return false;
	}

	return true;
}









//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
bool WinIoEx::Available()
{	
	
	if(!IsWinIoExReady())
	{
		return false;	
	}


	if(!IoControlExecute(IOCTL_IOPORT_AVAILABLE,sizeof(PKG16),0)  )
	{
		return false;
	}

	return true;
}




//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
bool WinIoEx::GetIoPortUchar(unsigned char	_addr,	unsigned char &_value)
{	
	
	if(!IsWinIoExReady())
	{
		return false;	
	}


	g_DevExt.Pkg16.Count = 1;
	g_DevExt.Pkg16.Element[0].Index = _addr;
		
	
	_value = 0;

	if(!IoControlExecute(IOCTL_IOPORT_GET_UCHAR,sizeof(PKG16),g_DevExt.Pkg16.Count)  )
	{
		return false;
	}
	
	_value = (unsigned char)g_DevExt.Pkg16.Element[0].Data;

	return true;
}

//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
bool WinIoEx::GetIoPortUshort(unsigned short	_addr,	unsigned short &_value)
{

	if(!IsWinIoExReady())
	{
		return false;
	}


	g_DevExt.Pkg16.Count = 1;
	g_DevExt.Pkg16.Element[0].Index = _addr;
		
	_value = 0;

	if(!IoControlExecute(IOCTL_IOPORT_GET_USHORT,sizeof(PKG16),g_DevExt.Pkg16.Count)  )
	{
		return false;
	}

	_value = (unsigned char)g_DevExt.Pkg16.Element[0].Data;

	return true;
}



//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
bool WinIoEx::GetIoPortUlong(unsigned long	_addr,	unsigned long &_value)
{
	if(!IsWinIoExReady())
	{
		return false;
	}


	g_DevExt.Pkg16.Count = 1;
	g_DevExt.Pkg16.Element[0].Index = _addr;
		

	_value = 0;

	if(!IoControlExecute(IOCTL_IOPORT_GET_ULONG,sizeof(PKG16),g_DevExt.Pkg16.Count)  )
	{
		return false;
	}

	_value = g_DevExt.Pkg16.Element[0].Data;

	return true;
}




//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
bool WinIoEx::SetIoPortUchar(unsigned char	_addr,	unsigned char _value)
{
	if(!IsWinIoExReady())
	{
		return false;	
	}


	g_DevExt.Pkg16.Count = 1;
	g_DevExt.Pkg16.Element[0].Index = _addr;
	g_DevExt.Pkg16.Element[0].Data	= _value;
		
	if(!IoControlExecute(IOCTL_IOPORT_SET_UCHAR,sizeof(PKG16),g_DevExt.Pkg16.Count)  )
	{
		return false;
	}


	return true;
}






//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
bool WinIoEx::SetIoPortUshort(unsigned short	_addr,	unsigned short _value)
{
	if(!IsWinIoExReady())
	{
		return false;	
	}


	g_DevExt.Pkg16.Count = 1;
	g_DevExt.Pkg16.Element[0].Index = _addr;
	g_DevExt.Pkg16.Element[0].Data	= _value;
		
	if(!IoControlExecute(IOCTL_IOPORT_SET_USHORT,sizeof(PKG16),g_DevExt.Pkg16.Count)  )
	{
		return false;
	}


	return true;
}



//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
bool WinIoEx::SetIoPortUlong(unsigned long	_addr,	unsigned long _value)
{
	if(!IsWinIoExReady())
	{
		return false;	
	}


	g_DevExt.Pkg16.Count = 1;
	g_DevExt.Pkg16.Element[0].Index = _addr;
	g_DevExt.Pkg16.Element[0].Data	= _value;
		
	if(!IoControlExecute(IOCTL_IOPORT_SET_ULONG,sizeof(PKG16),g_DevExt.Pkg16.Count)  )
	{
		return false;
	}


	return true;
}









//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
bool WinIoEx::GetPciBusUchar(PCI_DEVICE &_pci_device)
{	
	unsigned long	m_Buffer		= 0;
	unsigned char	m_ShiftNumber = 0;


	if(!IsWinIoExReady())
	{
		return false;	
	}


	_pci_device.Data = 0;



	m_ShiftNumber = (_pci_device.Index%4)*8;




	if(!GetPciBusUlong(_pci_device) )
	{
		return false;
	}


	m_Buffer = _pci_device.Data&(0x000000FF<<m_ShiftNumber);
	_pci_device.Data = 0xFF&(m_Buffer>>m_ShiftNumber);

	return true;
}




//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
bool WinIoEx::SetPciBusUchar(PCI_DEVICE _pci_device)
{	
	PCI_DEVICE		m_PciDevice		= _pci_device;

	unsigned long	m_Buffer		= 0;
	unsigned char	m_ShiftNumber	= 0;
	
	
	if(!IsWinIoExReady())
	{
		return false;	
	}



	m_ShiftNumber = (_pci_device.Index%4)*8;
	if(!GetPciBusUlong(m_PciDevice) )
	{
		return false;
	}


	m_PciDevice.Data = (_pci_device.Data&0x000000FF)|(m_PciDevice.Data&0xFFFFFF00);


	if(!SetPciBusUlong(m_PciDevice) )
	{
		return false;
	}

	return true;
}




//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
bool WinIoEx::GetPciBusUlong(PCI_DEVICE &_pci_device)
{	
	unsigned long	m_Buffer	= 0;
	unsigned long	m_PciConfig	= 0;

	wchar_t			m_TextBuff[512]	= {0};


	if(!IsWinIoExReady())
	{
		return false;	
	}


	// Bit 31 to 24
	m_PciConfig |= (((unsigned long)_pci_device.Bus)		<< 16);
	m_PciConfig |= (((unsigned long)_pci_device.Device)		<< 11);
	m_PciConfig |= (((unsigned long)_pci_device.Function)	<< 8);
	m_PciConfig |= (((unsigned long)_pci_device.Index)		<< 0);
    m_PciConfig |= 0x80000000;// For read/write PCI bus, the BIT31 must be set 1




	if(!SetIoPortUlong((unsigned long)0xCF8, m_PciConfig) )
	{
		return false;
	}


	if(!GetIoPortUlong((unsigned long)0xCFC,m_Buffer) )
	{
		return false;
	}

    _pci_device.Data = m_Buffer;					


	return true;
}




//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
bool WinIoEx::SetPciBusUlong(PCI_DEVICE _pci_device)
{	
	unsigned long m_Buffer		= 0;
	unsigned long m_PciConfig	= 0;


	if(!IsWinIoExReady())
	{
		return false;	
	}



	m_PciConfig = ((1 << 31) | (_pci_device.Bus << 16) | (_pci_device.Device << 11) | (_pci_device.Function << 8) | (_pci_device.Index << 2)) & 0xFFFFFFFC ;// mask last 2 bits

	if(!SetIoPortUlong((unsigned long)0xCF8,m_PciConfig))	{	return false;	}
	if(!SetIoPortUlong((unsigned long)0xCFC,m_Buffer))		{	return false;	}

	_pci_device.Data = m_Buffer;
	return true;
}













//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
bool WinIoEx::GetCpuMsr(HANDLE _hproc,	unsigned char _core, unsigned long _msr, CPU_REGS &_cpu_regs)
{	
	ERR_INFO			m_ErrInfo;

	if(!IsWinIoExReady())
	{
		return false;	
	}


	_cpu_regs.EAX = 0;
	_cpu_regs.EBX = 0;
	_cpu_regs.ECX = 0;
	_cpu_regs.EDX = 0;

	g_DevExt.CpuRegs.ECX = _msr;

	

	if(!IoControlExecute(IOCTL_IOPORT_SET_UCHAR,sizeof(PKG16),g_DevExt.Pkg16.Count)  )
	{
		return false;
	}



	if(!SetProcessAffinityMask(_hproc,(1<<_core)))
	{
		//===================================================================
		//Set Error Info.
		m_ErrInfo.ErrorLine = __LINE__;
		m_ErrInfo.FunctionName.assign(__FUNCTION__);
		m_ErrInfo.FileName.assign(__FILE__);
		m_ErrInfo.TimeStamp.assign(__TIMESTAMP__);	
		m_ErrInfo.ClasName.assign(typeid(*this).name());
		m_ErrInfo.WinNtFunctioName.assign("SetProcessAffinityMask(...)");
		m_ErrInfo.CustomizeMsg.assign("");		
		m_ErrInfo.WinNtLastError = GetLastError();
		GetLastErrorInfo(m_ErrInfo);
		return false;
	}


	if(!IoControlExecute(IOCTL_CPU_GET_MSR,sizeof(CPU_REGS),0)  )
	{
		return false;
	}



	_cpu_regs.EAX = (unsigned long)g_DevExt.CpuRegs.EAX;
	_cpu_regs.EBX = (unsigned long)g_DevExt.CpuRegs.EBX;
	_cpu_regs.ECX = (unsigned long)g_DevExt.CpuRegs.ECX;
	_cpu_regs.EDX = (unsigned long)g_DevExt.CpuRegs.EDX;



	return true;

}




//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
bool WinIoEx::SetCpuMsr(HANDLE _hproc,	unsigned char _core, unsigned long _msr, CPU_REGS _cpu_regs)
{	
	ERR_INFO			m_ErrInfo;

	if(!IsWinIoExReady())
	{
		return false;	
	}


	g_DevExt.CpuRegs.EAX	= _cpu_regs.EAX;
	g_DevExt.CpuRegs.EBX	= _cpu_regs.EBX;
	g_DevExt.CpuRegs.ECX	= _msr;	
	g_DevExt.CpuRegs.EDX	= _cpu_regs.EDX;
		


	if(!SetProcessAffinityMask(_hproc,(1<<_core))==0)
	{
		//===================================================================
		//Set Error Info.
		m_ErrInfo.ErrorLine = __LINE__;
		m_ErrInfo.FunctionName.assign(__FUNCTION__);
		m_ErrInfo.FileName.assign(__FILE__);
		m_ErrInfo.TimeStamp.assign(__TIMESTAMP__);	
		m_ErrInfo.ClasName.assign(typeid(*this).name());
		m_ErrInfo.WinNtFunctioName.assign("SetProcessAffinityMask(...)");
		m_ErrInfo.CustomizeMsg.assign("");		
		m_ErrInfo.WinNtLastError = GetLastError();
		GetLastErrorInfo(m_ErrInfo);
		return false;
	}




	if(!IoControlExecute(IOCTL_CPU_SET_MSR,sizeof(CPU_REGS),0)  )
	{
		return false;
	}

	return true;
}





//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
bool WinIoEx::GetMemBlock(MEM_BLOCK &_memblock)
{
	ERR_INFO			m_ErrInfo;

	char sz[128] = {0};

	if(!IsWinIoExReady())
	{
		return false;	
	}


	memset(_memblock.Buffer,0,1024);

	if(_memblock.Buffer==NULL)
	{
		//===================================================================
		//Set Error Info.
		m_ErrInfo.ErrorLine = __LINE__;
		m_ErrInfo.FunctionName.assign(__FUNCTION__);
		m_ErrInfo.FileName.assign(__FILE__);
		m_ErrInfo.TimeStamp.assign(__TIMESTAMP__);	
		m_ErrInfo.ClasName.assign(typeid(*this).name());
		m_ErrInfo.WinNtFunctioName.assign("");
		m_ErrInfo.CustomizeMsg.assign("NULL_MEMORY_BUFFER");		
		m_ErrInfo.WinNtLastError = ERROR_SUCCESS;
		GetLastErrorInfo(m_ErrInfo);
		return false;
	}


	if(_memblock.Length<=0)
	{
		//===================================================================
		//Set Error Info.
		m_ErrInfo.ErrorLine = __LINE__;
		m_ErrInfo.FunctionName.assign(__FUNCTION__);
		m_ErrInfo.FileName.assign(__FILE__);
		m_ErrInfo.TimeStamp.assign(__TIMESTAMP__);	
		m_ErrInfo.ClasName.assign(typeid(*this).name());
		m_ErrInfo.WinNtFunctioName.assign("");
		m_ErrInfo.CustomizeMsg.assign("WRONG_INPUT_BUFFER_LENGTH");		
		m_ErrInfo.WinNtLastError = ERROR_SUCCESS;
		GetLastErrorInfo(m_ErrInfo);
		return false;
	}



	g_DevExt.Pkg1K.Index		= _memblock.Index;
	g_DevExt.Pkg1K.Length		= _memblock.Length;

	if(!IoControlExecute(IOCTL_MEM_GET_BLOCK,sizeof(PKG1K),1)  )
	{
		return false;
	}

	memcpy_s(_memblock.Buffer,_memblock.Length,g_DevExt.Pkg1K.Buffer,_memblock.Length);

	return true;
}




//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
bool WinIoEx::SetMemBlock(MEM_BLOCK _memblock)
{
	ERR_INFO			m_ErrInfo;

	if(!IsWinIoExReady())
	{
		return false;	
	}


	if(_memblock.Buffer==NULL)
	{
		//===================================================================
		//Set Error Info.
		m_ErrInfo.ErrorLine = __LINE__;
		m_ErrInfo.FunctionName.assign(__FUNCTION__);
		m_ErrInfo.FileName.assign(__FILE__);
		m_ErrInfo.TimeStamp.assign(__TIMESTAMP__);	
		m_ErrInfo.ClasName.assign(typeid(*this).name());
		m_ErrInfo.WinNtFunctioName.assign("");
		m_ErrInfo.CustomizeMsg.assign("NULL_MEMORY_BUFFER");		
		m_ErrInfo.WinNtLastError = ERROR_SUCCESS;
		GetLastErrorInfo(m_ErrInfo);
		return false;
	}


	if(_memblock.Length<=0)
	{
		//===================================================================
		//Set Error Info.
		m_ErrInfo.ErrorLine = __LINE__;
		m_ErrInfo.FunctionName.assign(__FUNCTION__);
		m_ErrInfo.FileName.assign(__FILE__);
		m_ErrInfo.TimeStamp.assign(__TIMESTAMP__);	
		m_ErrInfo.ClasName.assign(typeid(*this).name());
		m_ErrInfo.WinNtFunctioName.assign("");
		m_ErrInfo.CustomizeMsg.assign("WRONG_INPUT_BUFFER_LENGTH");		
		m_ErrInfo.WinNtLastError = ERROR_SUCCESS;
		GetLastErrorInfo(m_ErrInfo);
		return false;
	}


	g_DevExt.Pkg1K.Index		= _memblock.Index;
	g_DevExt.Pkg1K.Length		= _memblock.Length;
	memcpy(g_DevExt.Pkg1K.Buffer,_memblock.Buffer,_memblock.Length);

	if(!IoControlExecute(IOCTL_MEM_SET_BLOCK,sizeof(PKG1K),1)  )
	{
		return false;
	}

	return true;
}




