/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * WinIoEx - DeviceControl.c
 *
 * 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 "Driver.h"



//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
NTSTATUS DispatchDeviceIoControl(PDEVICE_OBJECT fdo, PIRP Irp)
{
    PDEVICE_EXTENSION pdx       = (PDEVICE_EXTENSION)fdo->DeviceExtension;    
    PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
    NTSTATUS ntStatus           = STATUS_SUCCESS;
    
    ULONG ControlCode   = IrpStack->Parameters.DeviceIoControl.IoControlCode;
    ULONG InputLength   = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
    ULONG OutputLength  = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
    PUCHAR IOSysBuffer  = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
	

    
    unsigned long ByteTxd = 0;
    
    unsigned long m_Addr = 0;
    unsigned long m_Data = 0;
    unsigned long m_LoopIndex = 0;

  
  
  
  
    
    KdPrint(("IO CONTROL CODE = 0x%X\r\n ",ControlCode));
     
     KdPrint(("InputLength=0x%X  OutputLength=0x%X \r\n",InputLength,OutputLength));
	//-------------------------------------------------------------------------------------------------------------
	//Checking buffer size. It's common buffer so input buffer and output buffer have the same size.
	if( InputLength != OutputLength )
	{
        KdPrint(("STATUS_INVALID_PARAMETER,  InputLength=0x%X  OutputLength=0x%X \r\n",InputLength,OutputLength));
		ntStatus = STATUS_INVALID_PARAMETER;
	}
    

	
	//-------------------------------------------------------------------------------------------------------------
	//Copy input buffer data to IOSysBuffer.
	switch(ControlCode)
	{
		//-------------------------------------------------
		case IOCTL_IOPORT_AVAILABLE:
	        KdPrint(("Copy system memory to buffer!!!\r\n"));
	        InputLength = OutputLength= OutputLength/sizeof(MEM_BLOCK_1K);    	    
	        RtlCopyMemory(&pdx->Buff_Mem_1K, IOSysBuffer, sizeof(MEM_BLOCK_1K));
			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:
	        InputLength = OutputLength= OutputLength/sizeof(CMD_PACKAGE16);    	    
	        RtlCopyMemory(&pdx->Buff_Package, IOSysBuffer, sizeof(CMD_PACKAGE16));
			break;
		//-------------------------------------------------
		case IOCTL_CPU_GET_MSR:
		case IOCTL_CPU_SET_MSR:
			KdPrint(("Copy system memory to buffer!!!\r\n"));
	        InputLength = OutputLength= OutputLength/sizeof(CPU_REGS);    	    
	        RtlCopyMemory(&pdx->Cpu_Regs, IOSysBuffer, sizeof(CPU_REGS));
			break;

		//-------------------------------------------------
		case IOCTL_MEM_GET_BLOCK:
		case IOCTL_MEM_SET_BLOCK:
	        KdPrint(("Copy system memory to buffer!!!\r\n"));
	        InputLength = OutputLength= OutputLength/sizeof(MEM_BLOCK_1K);    	    
	        RtlCopyMemory(&pdx->Buff_Mem_1K, IOSysBuffer, sizeof(MEM_BLOCK_1K));
			break;
		default:
			ByteTxd = 0;
			KdPrint(("STATUS_INVALID_PARAMETER,  Loss condition.\r\n"));       
			ntStatus = STATUS_INVALID_PARAMETER;
			return CompleteIrp(Irp, ntStatus, ByteTxd);
	}
	
	
	
	KdPrint(("ControlCode  Entry - B4\r\n"));

    

	//-------------------------------------------------------------------------------------------------------------
	//Select Io Control Code.
    switch(ControlCode) {
        KdPrint(("ControlCode  Entry - Io control code switch case.\r\n"));
		//-------------------------------------------------------------------------------------------
		case IOCTL_IOPORT_AVAILABLE:
            RtlCopyMemory(pdx->Buff_Mem_1K.BufferBody,DRVVERSION, sizeof(DRVVERSION));        
            KdPrint(("IOCTL_IOPORT_AVAILABLE Entry\r\n"));
			ntStatus = STATUS_SUCCESS;
		break;
		//-------------------------------------------------------------------------------------------
		case IOCTL_IOPORT_GET_UCHAR:           
            KdPrint(("IOCTL_IOPORT_GET_UCHAR Entry\r\n"));
            
            if((InputLength<=0)||(OutputLength<=0))
            {
                KdPrint(("STATUS_INVALID_PARAMETER,  Input Buffer Length or Output Buffer Length smaller than 0.\r\n"));
                ntStatus = STATUS_INVALID_PARAMETER;
            }
            
            for(m_LoopIndex=0;m_LoopIndex<InputLength;m_LoopIndex++)
            {
                m_Addr = pdx->Buff_Package.CmdElement[m_LoopIndex].Index;                
                IOPORT_GET_UCHAR((unsigned char)m_Addr,&(unsigned char)m_Data);                               
                
                pdx->Buff_Package.CmdElement[m_LoopIndex].Data = m_Data;                                  
                KdPrint(("Get - Index = %d\tAddr = 0x%.2X\tValue = 0x%.2X\tRetSize=%d\r\n",m_LoopIndex,m_Addr,m_Data,ByteTxd));
			}
            
    
            ntStatus = STATUS_SUCCESS;			
			
		break;
        
		//-------------------------------------------------------------------------------------------
		case IOCTL_IOPORT_SET_UCHAR:
            KdPrint(("IOCTL_IOPORT_SET_UCHAR Entry\r\n"));
            
            if((InputLength<=0)||(OutputLength<=0))
            {
                KdPrint(("STATUS_INVALID_PARAMETER,  Input Buffer Length or Output Buffer Length smaller than 0.\r\n"));
                ntStatus = STATUS_INVALID_PARAMETER;
            }
            
            for(m_LoopIndex=0;m_LoopIndex<InputLength;m_LoopIndex++)
            {
                m_Addr = pdx->Buff_Package.CmdElement[m_LoopIndex].Index; 
                m_Data = pdx->Buff_Package.CmdElement[m_LoopIndex].Data; 
                
                IOPORT_SET_UCHAR((unsigned char)m_Addr,(unsigned char)m_Data);                               
                                                
                KdPrint(("Set - Index = %.2d\t\tAddr = 0x%.2X\t\tValue = 0x%.2X\t\tRetSize=%d\r\n",m_LoopIndex,pdx->Buff_Package.CmdElement[m_LoopIndex].Index,pdx->Buff_Package.CmdElement[m_LoopIndex].Data,ByteTxd));
			}
            
    
            ntStatus = STATUS_SUCCESS;	
		break;
		//-------------------------------------------------------------------------------------------
		case IOCTL_IOPORT_GET_ULONG:
            KdPrint(("IOCTL_IOPORT_GET_ULONG Entry\r\n"));
            
            if((InputLength<=0)||(OutputLength<=0))
            {
                KdPrint(("STATUS_INVALID_PARAMETER,  Input Buffer Length or Output Buffer Length smaller than 0.\r\n"));
                ntStatus = STATUS_INVALID_PARAMETER;
            }
            
            for(m_LoopIndex=0;m_LoopIndex<InputLength;m_LoopIndex++)
            {
                m_Addr = pdx->Buff_Package.CmdElement[m_LoopIndex].Index;                
                IOPORT_GET_ULONG(m_Addr,&m_Data);                               
                
                pdx->Buff_Package.CmdElement[m_LoopIndex].Data = m_Data;                                                  
                KdPrint(("IOCTL_IOPORT_GET_ULONG Index=%d \t Addr=0x%.8X \t Value = 0x%.8X \t RetSize=%d\r\n",m_LoopIndex,m_Addr,m_Data,ByteTxd));
			}                
        
			ntStatus = STATUS_SUCCESS;
		break;
		//-------------------------------------------------------------------------------------------
		case IOCTL_IOPORT_SET_ULONG:
            KdPrint(("IOCTL_IOPORT_SET_ULONG Entry\r\n"));            
            if((InputLength<=0)||(OutputLength<=0))
            {
                KdPrint(("STATUS_INVALID_PARAMETER,  Input Buffer Length or Output Buffer Length smaller than 0.\r\n"));
                ntStatus = STATUS_INVALID_PARAMETER;
            }
            
            for(m_LoopIndex=0;m_LoopIndex<InputLength;m_LoopIndex++)
            {
                m_Addr = pdx->Buff_Package.CmdElement[m_LoopIndex].Index; 
                m_Data = pdx->Buff_Package.CmdElement[m_LoopIndex].Data; 
                
                IOPORT_SET_ULONG(m_Addr,m_Data);                               
                                                
                KdPrint(("Set - Index = %.2d\t\tAddr = 0x%.8X\t\tValue = 0x%.8X\t\tRetSize=%d\r\n",m_LoopIndex,pdx->Buff_Package.CmdElement[m_LoopIndex].Index,pdx->Buff_Package.CmdElement[m_LoopIndex].Data,ByteTxd));
			}
            
            ntStatus = STATUS_SUCCESS;	
		break;	
		
		
		//-------------------------------------------------------------------------------------------
		case IOCTL_IOPORT_GET_USHORT:
            KdPrint(("IOCTL_IOPORT_GET_USHORT Entry\r\n"));            
            if((InputLength<=0)||(OutputLength<=0))
            {
                KdPrint(("STATUS_INVALID_PARAMETER,  Input Buffer Length or Output Buffer Length smaller than 0.\r\n"));
                ntStatus = STATUS_INVALID_PARAMETER;
            }
            
            for(m_LoopIndex=0;m_LoopIndex<InputLength;m_LoopIndex++)
            {
                m_Addr = pdx->Buff_Package.CmdElement[m_LoopIndex].Index;                
                IOPORT_GET_USHORT(m_Addr,&m_Data);                               
                
                pdx->Buff_Package.CmdElement[m_LoopIndex].Data = m_Data;                                                  
                KdPrint(("Get - Index = %d\tAddr = 0x%.8X\tValue = 0x%.8X\tRetSize=%d\r\n",m_LoopIndex,m_Addr,m_Data,ByteTxd));
			}                
        
            
            ntStatus = STATUS_SUCCESS;	
		break;	
		
		
		//-------------------------------------------------------------------------------------------
		case IOCTL_IOPORT_SET_USHORT:
            KdPrint(("IOCTL_IOPORT_SET_USHORT Entry\r\n"));            
            if((InputLength<=0)||(OutputLength<=0))
            {
                KdPrint(("STATUS_INVALID_PARAMETER,  Input Buffer Length or Output Buffer Length smaller than 0.\r\n"));
                ntStatus = STATUS_INVALID_PARAMETER;
            }
            
            for(m_LoopIndex=0;m_LoopIndex<InputLength;m_LoopIndex++)
            {
                m_Addr = pdx->Buff_Package.CmdElement[m_LoopIndex].Index; 
                m_Data = pdx->Buff_Package.CmdElement[m_LoopIndex].Data; 
                
                IOPORT_SET_USHORT(m_Addr,m_Data);                               
                                                
                KdPrint(("Set - Index = %.2d\t\tAddr = 0x%.8X\t\tValue = 0x%.8X\t\tRetSize=%d\r\n",m_LoopIndex,pdx->Buff_Package.CmdElement[m_LoopIndex].Index,pdx->Buff_Package.CmdElement[m_LoopIndex].Data,ByteTxd));
			}
            
            ntStatus = STATUS_SUCCESS;	
		break;	
		//-------------------------------------------------------------------------------------------
		case IOCTL_CPU_GET_MSR:
			
			if((InputLength<=0)||(OutputLength<=0))
            {
                KdPrint(("STATUS_INVALID_PARAMETER,  Input Buffer Length or Output Buffer Length smaller than 0.\r\n"));
                ntStatus = STATUS_INVALID_PARAMETER;
            }
							
			RWMSR_GET_VALUE(&pdx->Cpu_Regs);	

			
			ntStatus = STATUS_SUCCESS;
		break;
		//-------------------------------------------------------------------------------------------
		case IOCTL_CPU_SET_MSR:
			
			if((InputLength<=0)||(OutputLength<=0))
            {
                KdPrint(("STATUS_INVALID_PARAMETER,  Input Buffer Length or Output Buffer Length smaller than 0.\r\n"));
                ntStatus = STATUS_INVALID_PARAMETER;
            }
								
			RWMSR_SET_VALUE(pdx->Cpu_Regs);
			
			ntStatus = STATUS_SUCCESS;
		break;
		//-------------------------------------------------------------------------------------------
		case IOCTL_MEM_GET_BLOCK:
            KdPrint(("IOCTL_MEM_GET_BLOCK  Index=0x%X           Length=0x%X\r\n",pdx->Buff_Mem_1K.Index,pdx->Buff_Mem_1K.Length));
            if(pdx->Buff_Mem_1K.Length<=sizeof(MEM_BLOCK_1K))
            {                   
                //unsigned char m_Buffer[1024] = {0};                         
                //RWMEM_GET_BLOCK(pdx->Buff_Mem_1K.Index,pdx->Buff_Mem_1K.Length,m_Buffer);
                //KdPrint(("Buffer Data = %s",m_Buffer));
                
                
                RWMEM_GET_BLOCK(pdx->Buff_Mem_1K.Index,pdx->Buff_Mem_1K.Length,pdx->Buff_Mem_1K.BufferBody);
                

            }
            else
            {
                ntStatus = STATUS_INVALID_DEVICE_REQUEST;
                ByteTxd = 0;
            }
		break;
		//-------------------------------------------------------------------------------------------
		case IOCTL_MEM_SET_BLOCK:
            KdPrint(("IOCTL_MEM_SET_BLOCK  Index=0x%X           Length=0x%X\r\n",pdx->Buff_Mem_1K.Index,pdx->Buff_Mem_1K.Length));
            if(pdx->Buff_Mem_1K.Length<=sizeof(MEM_BLOCK_1K))
            {                
                RWMEM_SET_BLOCK(pdx->Buff_Mem_1K.Index,pdx->Buff_Mem_1K.Length,pdx->Buff_Mem_1K.BufferBody);
            }
            else
            {
                ntStatus = STATUS_INVALID_DEVICE_REQUEST;
                ByteTxd = 0;
            }
		break;
        //-------------------------------------------------------------------------------------------
        default: 
            //Dprintf(DDIC, ("Unknown DeviceIoControl Code!\r\n"));
            //ntStatus = STATUS_INVALID_DEVICE_REQUEST;
            KdPrint(("DRV STATUS_INVALID_DEVICE_REQUEST Entry \r\n"));
            ntStatus = STATUS_INVALID_DEVICE_REQUEST;
            break;
           
    }
	
    
	KdPrint(("ControlCode  Entry - A4\r\n"));
    //-------------------------------------------------------------------------------------------------------------
	//Copy input buffer data to IOSysBuffer.
	switch(ControlCode)
	{
		//-------------------------------------------------
		case IOCTL_IOPORT_AVAILABLE:
	        KdPrint(("Copy system memory to buffer!!! IOCTL_IOPORT_AVAILABLE \r\n"));
	        KdPrint(("Data=%s\r\n",pdx->Buff_Mem_1K.BufferBody));        
	        InputLength = OutputLength= OutputLength/sizeof(MEM_BLOCK_1K);    	    
	        RtlCopyMemory(IOSysBuffer, &pdx->Buff_Mem_1K,sizeof(MEM_BLOCK_1K)); 
	        ByteTxd =sizeof(MEM_BLOCK_1K);
			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:
			KdPrint(("Copy system memory to buffer!!! IOCTL_IOPORT_XXX_XXXXX \r\n"));
	        RtlCopyMemory(IOSysBuffer, &pdx->Buff_Package,sizeof(CMD_PACKAGE16));
	        ByteTxd =sizeof(CMD_PACKAGE16);
			KdPrint(("Copy system memory to buffer!!! IOCTL_IOPORT_XXX_XXXXX RetSize=%d\r\n",ByteTxd));
			break;
		//-------------------------------------------------
		case IOCTL_CPU_GET_MSR:
		case IOCTL_CPU_SET_MSR:
			KdPrint(("Copy buffer to system memory !!!\r\n"));
	        RtlCopyMemory(IOSysBuffer, &pdx->Cpu_Regs,sizeof(CPU_REGS));   
	        ByteTxd =sizeof(CPU_REGS);
			break;

		//-------------------------------------------------
		case IOCTL_MEM_GET_BLOCK:
		case IOCTL_MEM_SET_BLOCK:
	        KdPrint(("Copy buffer to system memory !!!\r\n"));
	        RtlCopyMemory(IOSysBuffer, &pdx->Buff_Mem_1K,sizeof(MEM_BLOCK_1K));   
	        ByteTxd =sizeof(MEM_BLOCK_1K);
			break;
		default:
	        KdPrint(("STATUS_INVALID_PARAMETER,  Loss condition.\r\n"));
	        ByteTxd = 0;        
	        ntStatus = STATUS_INVALID_PARAMETER;
	}
	
	
    


    return CompleteIrp(Irp, ntStatus, ByteTxd);
}
















//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
//void MemoryReadBlockEx(PDEVICE_EXTENSION pdx)
unsigned long RWMEM_GET_BLOCK(unsigned long _Index, unsigned long _Length, unsigned char *_Buffer)
{	    	
    unsigned long       AccessAddress;
    unsigned long       in_buffer_size;
    PHYSICAL_ADDRESS    PhysicalAddress;
    unsigned long i;    
    void *VirtualAddress = NULL;
    

    PhysicalAddress.LowPart = _Index;
    PhysicalAddress.HighPart = 0;
    VirtualAddress = MmMapIoSpace(PhysicalAddress,  // PhysicalAddress
                                  _Length,          // NumberOfBytes
                                  MmNonCached);     // CacheType, 0->MmNonCached
                                                    //          , 1->MmCached
                                                    //          , 2->MmWriteCombined
                                                 
    RtlCopyMemory(_Buffer, VirtualAddress,_Length);

    if(VirtualAddress!=NULL)
    {
        KdPrint(("5Index=0x%X\t\tLength=0x%X\r\n",_Index,_Length));
        MmUnmapIoSpace(VirtualAddress, _Length);  
    }

    
    KdPrint(("RWMEM_GET_BLOCK"));
    return 0;   // 0=Successful. 
}














//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
//void MemoryReadBlockEx(PDEVICE_EXTENSION pdx)
unsigned long RWMEM_SET_BLOCK(unsigned long _Index, unsigned long _Length, unsigned char *_Buffer)
{	    	
    unsigned long       AccessAddress;
    unsigned long       in_buffer_size;
    PHYSICAL_ADDRESS    PhysicalAddress;
    unsigned long i;    
    void *VirtualAddress = NULL;
    

    PhysicalAddress.LowPart = _Index;
    PhysicalAddress.HighPart = 0;
    VirtualAddress = MmMapIoSpace(PhysicalAddress,  // PhysicalAddress
                                  _Length,          // NumberOfBytes
                                  MmNonCached);     // CacheType, 0->MmNonCached
                                                    //          , 1->MmCached
                                                    //          , 2->MmWriteCombined
                                                 

	KdPrint(("    RtlCopyMemory\r\n"));
    RtlCopyMemory(VirtualAddress, _Buffer, _Length);

    if(VirtualAddress!=NULL)
    {
        KdPrint(("5Index=0x%X\t\tLength=0x%X\r\n",_Index,_Length));
        MmUnmapIoSpace(VirtualAddress, _Length);  
    }

    
    KdPrint(("RWMEM_SET_BLOCK"));
    return 0;   // 0=Successful. 
}

















//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
unsigned long IOPORT_GET_UCHAR(unsigned char _index, unsigned char  *_value)
{
    *_value = (unsigned char)READ_PORT_UCHAR((PUCHAR)_index);
    
    return 0;	//Successful.
}



/*******************************************************************************
 *	Description:	
 *	Paraments:		
 *	Return:			
 *  ----------------------------------------------------------------------------
 *	Author:		Ayr.Chen
 *	Created Date:	2009.01.12
 *******************************************************************************/
unsigned long IOPORT_SET_UCHAR(unsigned char _index, unsigned char _value)
{
    WRITE_PORT_UCHAR((PUCHAR)_index,(UCHAR)_value);     
	return 0;	//Successful.
}













//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
unsigned long IOPORT_GET_USHORT(unsigned short _index, unsigned short *_value)
{
   *_value = READ_PORT_USHORT((PUSHORT)_index);
    KdPrint(("-READ_PORT_USHORT  Index=%lX*_value=%X",_index,*_value));
    return 0;	//Successful. 
}











//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
unsigned long IOPORT_SET_USHORT(unsigned short _index, unsigned short _value)
{
    WRITE_PORT_USHORT((PSHORT)_index,(SHORT)_value);
    return 0;	//Successful.
}



















//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
unsigned long IOPORT_GET_ULONG(unsigned long _index, unsigned long *_value)
{
	//unsigned long 	m_Value = 0;
   *_value = READ_PORT_ULONG((PULONG)_index);
   //m_Value = READ_PORT_ULONG((PULONG)_index);
   
   //m_RetValue = READ_PORT_ULONG((PULONG)_index);
   //*_value = 0xABCDABCD;
    KdPrint(("-IOPORT_GET_ULONG  Index=0x%.8X     m_RetValue=0x%.8X \r\n",_index,*_value));
	//*_value = m_Value;
    return 0;	//Successful. 
}













//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
unsigned long IOPORT_SET_ULONG(unsigned long _index, unsigned long _value)
{
    WRITE_PORT_ULONG((PULONG)_index,(ULONG)_value);
    return 0;	//Successful.
}
















//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
unsigned long RWMSR_GET_VALUE(CPU_REGS *_CpuRegs)
{

	unsigned long   A = _CpuRegs->EAX;
	unsigned long   B = _CpuRegs->EBX;
	unsigned long   C = _CpuRegs->ECX;
	unsigned long   D = _CpuRegs->EDX;
	
	KdPrint(("1 READ EAX=0x%.8X\t	EBX=0x%.8X\t ECX=0x%.8X \t EDX=0x%.8X\r\n",A,B,C,D));

   _asm
   {
		push eax
		push ebx
		push ecx
		push edx

		mov		ECX,C
		rdmsr  
		mov   	A,	eax  
		mov   	B,	ebx
		mov   	C,	ecx
		mov   	D,	edx

		pop edx
		pop ecx
		pop ebx		
		pop eax
   }
   
   KdPrint(("2  READ EAX=0x%.8X\t	EBX=0x%.8X\t ECX=0x%.8X \t EDX=0x%.8X\r\n",A,B,C,D));
   
	_CpuRegs->EAX = A;
	_CpuRegs->EBX = B;
	_CpuRegs->ECX = C;
	_CpuRegs->EDX = D;
   
   
   return 0;
}














//******************************************************************************************************
//
//------------------------------------------------------------------------------------------------------
// Author	: Doug Chen
// Date		: 2009/10/05
//******************************************************************************************************
unsigned long RWMSR_SET_VALUE(CPU_REGS _CpuRegs)
{	
	KdPrint(("1 WRITE EAX=0x%.8X\t	EBX=0x%.8X\t ECX=0x%.8X \t EDX=0x%.8X\r\n",_CpuRegs.EAX,_CpuRegs.EBX,_CpuRegs.ECX,_CpuRegs.EDX));
   _asm
   {
		push eax
		push ebx
		push ecx
		push edx

		mov		eax,_CpuRegs.EAX;
		mov		ebx,_CpuRegs.EBX;
		mov		ecx,_CpuRegs.ECX;
		mov		edx,_CpuRegs.EDX;

		wrmsr
		
		pop edx
		pop ecx
		pop ebx
		pop eax
   }
   
   	KdPrint(("2 WRITE  EAX=0x%.8X\t	EBX=0x%.8X\t ECX=0x%.8X \t EDX=0x%.8X\r\n",_CpuRegs.EAX,_CpuRegs.EBX,_CpuRegs.ECX,_CpuRegs.EDX));
   return 0;
}
















