• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

E:/PROJECTS/cvsed/mixed/VIRTUA~1/kdvm/vboxrpc.h

Go to the documentation of this file.
00001 
00006 #pragma once
00007 
00008 namespace VBoxRPC
00009 {
00010 #ifndef _AMD64_
00011         static void __declspec(naked) __fastcall ExchangeData(ULONG pPhysicalAddr, int) //First dword specifies in size, second - max out size. On exit
00012         {
00013                 __asm
00014                 {
00015                         xchg eax, ecx
00016                         mov edx, 0x5659
00017                         out dx, eax
00018                         ret
00019                 }
00020         }
00021 #else
00022         extern "C" void VBoxExchangeData(ULONG pPhysicalAddr, int);
00023 
00024         static inline void ExchangeData(ULONG pPhysicalAddr, int a)
00025         {
00026                 VBoxExchangeData(pPhysicalAddr, a);
00027         }
00028 
00029 #endif
00030 }
00031 
00033 template <char *t_pBuffer, unsigned t_BufferSize> class BufferedVBoxChannel
00034 {
00035 private:
00036         unsigned m_BufferPos;
00037         unsigned m_TotalTransferSize;
00038         PHYSICAL_ADDRESS m_BufPhysical;
00039 
00040         enum {SendHdrSize = 2 * sizeof(unsigned), RecvHdrSize = sizeof(unsigned)};
00041 
00042         enum
00043         {
00044                 Idle,
00045                 Sending,
00046                 Receiving,
00047                 Received,
00048         } m_Phase;
00049 
00050 private:
00051         bool PerformDataExchange()
00052         {
00053 #ifdef VMWRPC_PARAMETER_CHECKING
00054                 if (m_Phase != Sending)
00055                         return false;
00056                 if (m_BufferPos != m_TotalTransferSize)
00057                         return false;
00058 #endif
00059                 VBoxRPC::ExchangeData(m_BufPhysical.LowPart, 0);
00060                 m_TotalTransferSize = ((unsigned *)t_pBuffer)[0] + RecvHdrSize;
00061                 m_BufferPos = RecvHdrSize;
00062                 m_Phase = Receiving;
00063                 return true;
00064         }
00065 
00066 public:
00067         BufferedVBoxChannel()
00068                 : m_BufferPos(0)
00069                 , m_TotalTransferSize(0)
00070                 , m_Phase(Idle)
00071         {
00072                 m_BufPhysical = MmGetPhysicalAddress(t_pBuffer);
00073         }
00074 
00075         ~BufferedVBoxChannel()
00076         {
00077         }
00078 
00079         bool PrepareSend(unsigned SendSize)
00080         {
00081 #ifdef VMWRPC_PARAMETER_CHECKING
00082                 if ((m_Phase != Idle) || (SendSize > (t_BufferSize - SendHdrSize)))
00083                         return false;
00084 #endif
00085                 m_TotalTransferSize = SendSize + SendHdrSize;
00086                 m_Phase = Sending;
00087                 ((unsigned *)t_pBuffer)[0] = SendSize;
00088                 ((unsigned *)t_pBuffer)[1] = t_BufferSize;
00089                 m_BufferPos = SendHdrSize;
00090                 return true;
00091         }
00092 
00093         bool SendPartial(const void *pData, unsigned Size)
00094         {
00095                 if (!Size)
00096                         return true;
00097 #ifdef VMWRPC_PARAMETER_CHECKING
00098                 if (m_Phase != Sending)
00099                         return false;
00100                 if (Size > (m_TotalTransferSize - m_BufferPos))
00101                         return false;
00102 #endif
00103                 memcpy(t_pBuffer + m_BufferPos, pData, Size);
00104                 m_BufferPos += Size;
00105                 return true;
00106         }
00107 
00108         unsigned GetReplySize()
00109         {
00110                 if (m_Phase == Receiving)
00111                         return m_TotalTransferSize - RecvHdrSize;
00112                 if (!PerformDataExchange())
00113                         return -1;
00114                 if (m_Phase != Receiving)
00115                         return -1;
00116                 return m_TotalTransferSize - RecvHdrSize;
00117         }
00118 
00119         bool Receive(void *pData, unsigned Size)
00120         {
00121                 if (!Size)
00122                         return true;
00123 #ifdef VMWRPC_PARAMETER_CHECKING
00124                 if (m_Phase != Receiving)
00125                         return false;
00126                 if (Size > (m_TotalTransferSize - m_BufferPos))
00127                         return false;
00128 #endif
00129                 memcpy(pData, t_pBuffer + m_BufferPos, Size);
00130                 m_BufferPos += Size;
00131                 if (m_BufferPos == m_TotalTransferSize)
00132                         m_Phase = Received;
00133                 return true;
00134         }
00135 
00136         bool Valid()
00137         {
00138                 return true;
00139         }
00140 
00141         bool EndReceive()
00142         {
00143                 if (m_Phase != Received)
00144                         return false;
00145                 m_Phase = Idle;
00146                 return true;
00147         }
00148 
00149         bool NeedRestartInVBoxMode()
00150         {
00151                 return false;
00152         }
00153 };