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

E:/PROJECTS/cvsed/mixed/VIRTUA~1/VBoxDD/IOHandlers.cpp

Go to the documentation of this file.
00001 #include "stdafx.h"
00002 #include "../rpcdispatch/rpcdisp.h"
00003 #include "../rpcdispatch/kdcomdisp.h"
00004 #include "../rpcdispatch/reporter.h"
00005 #include "VBoxCmdLine.h"
00006 
00007 #include <VBox/mm.h>
00008 
00009 static bool s_bVMWareOpenChannelDetected = false;
00010 static bool s_bChannelDetectSuccessful = false;
00011 
00012 static unsigned KDRPCDirectHandler(char *pCommandBody, unsigned CommandBodyLength, char **ppReply);
00013 static unsigned KDRPCProxyHandler(char *pCommandBody, unsigned CommandBodyLength, char **ppReply);
00014 
00015 int VirtualKDPortOutHandler( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb )
00016 {
00017         struct  
00018         {
00019                 unsigned RequestSize;
00020                 unsigned MaxReplySize;
00021         } RequestHeader = {0, };
00022         static char CmdBody[262144];
00023         if (Port == 0x5659)
00024         {
00025                 int rc = PDMDevHlpPhysRead(pDevIns, (RTGCPHYS)u32, &RequestHeader, sizeof(RequestHeader));
00026                 if (!RT_SUCCESS(rc) || !RequestHeader.RequestSize)
00027                         return VINF_SUCCESS;
00028                 rc = PDMDevHlpPhysRead(pDevIns, (RTGCPHYS)(u32 + sizeof(RequestHeader)), CmdBody, RequestHeader.RequestSize);
00029                 if (!RT_SUCCESS(rc))
00030                         return VINF_SUCCESS;
00031                 ASSERT(!memcmp(CmdBody, g_szRPCCommandHeader, sizeof(g_szRPCCommandHeader) - 1));
00032                 
00033                 char *pReply = NULL;
00034 #ifdef KDVMWARE_USE_PROXY
00035                 unsigned done = KDRPCProxyHandler(CmdBody + sizeof(g_szRPCCommandHeader) - 1, RequestHeader.RequestSize - (sizeof(g_szRPCCommandHeader) - 1), &pReply);
00036 #else
00037                 unsigned done = KDRPCDirectHandler(CmdBody + sizeof(g_szRPCCommandHeader) - 1, RequestHeader.RequestSize - (sizeof(g_szRPCCommandHeader) - 1), &pReply);
00038 #endif
00039 
00040                 if (!pReply)
00041                         done = 0;
00042 
00043                 char Prefix[sizeof(done) + 2];
00044                 ((unsigned *)Prefix)[0] = done + 2;
00045                 Prefix[sizeof(unsigned)] = '1';
00046                 Prefix[sizeof(unsigned) + 1] = ' ';
00047 
00048                 rc = PDMDevHlpPhysWrite(pDevIns, (RTGCPHYS)u32, Prefix, sizeof(Prefix));
00049                 if (!RT_SUCCESS(rc))
00050                         return VINF_SUCCESS;
00051                 if (done)
00052                 {
00053                         rc = PDMDevHlpPhysWrite(pDevIns, (RTGCPHYS)(u32 + sizeof(Prefix)), pReply, done);
00054                         if (!RT_SUCCESS(rc))
00055                                 return VINF_SUCCESS;
00056                 }
00057                 return VINF_SUCCESS;
00058         }
00059         else
00060         {
00061                 if ((Port == 0x5658) && (u32 == 0x564D5868))
00062                         s_bVMWareOpenChannelDetected = true;
00063                 else
00064                         s_bVMWareOpenChannelDetected = false;
00065                 return VINF_SUCCESS;
00066         }
00067 }
00068 
00069 int VirtualKDPortInHandler( PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb )
00070 {
00071         if (s_bVMWareOpenChannelDetected)
00072         {
00073                 *pu32 = 'XOBV'; //Checked in VMWRPC.H
00074                 s_bVMWareOpenChannelDetected = false;
00075                 s_bChannelDetectSuccessful = true;
00076         }
00077         else
00078                 *pu32 = -1;
00079         return VINF_SUCCESS;
00080 }
00081 
00082 //-------------------------------------------------------------------------------------------------------------------------------------
00083 
00084 
00085 #ifdef KDVMWARE_USE_PROXY
00086 
00087 int MaxDelay = 0;
00088 static char ReplyBuffer[262144];
00089 
00090 static unsigned KDRPCProxyHandler(char *pCommandBody, unsigned CommandBodyLength, char **ppReply)
00091 {
00092         DWORD done = 0;
00093         DWORD tick = GetTickCount();
00094         for (;;)
00095         {
00096                 BOOL b = CallNamedPipe(_T("\\\\.\\pipe\\kdvmware_proxypipe"), pCommandBody, CommandBodyLength, ReplyBuffer, sizeof(ReplyBuffer), &done, INFINITE);
00097                 if (b)
00098                 {
00099                         int delay = (int)(GetTickCount() - tick);
00100                         if (delay > MaxDelay)
00101                                 MaxDelay = delay;
00102                         break;
00103                 }
00104                 int er = GetLastError();
00105                 if ((GetTickCount() - tick) > 1000)
00106                         return 0;
00107         }
00108         *ppReply = ReplyBuffer;
00109         return done;
00110 }
00111 
00112 #else
00113 
00114 static KdRpcDispatcher *s_pClient = NULL;
00115 
00116 static unsigned KDRPCDirectHandler(char *pCommandBody, unsigned CommandBodyLength, char **ppReply)
00117 {
00118         if (!s_pClient)
00119                 return false;
00120         return s_pClient->OnRequest(pCommandBody, CommandBodyLength, ppReply);
00121 }
00122 
00123 #endif
00124 
00125 void InitializeRpcDispatcher()
00126 {
00127 #ifndef KDVMWARE_USE_PROXY
00128         LPWSTR lpCmdLine = GetCommandLineW();
00129         wchar_t wszPipeName[MAX_PATH] = {0,};
00130         if (!VBoxCmdLineToPipeNameW(lpCmdLine, wszPipeName, __countof(wszPipeName)))
00131                 return;
00132         ASSERT(g_pReporter);
00133         wcsncpy(g_pReporter->GetStatusPointer()->PipeName, wszPipeName, __countof(g_pReporter->GetStatusPointer()->PipeName));
00134         s_pClient = new KdRpcDispatcher(new KdComDispatcher(wszPipeName));
00135 #else
00136         wcsncpy(g_pReporter->GetStatusPointer()->PipeName, L"\\\\.\\pipe\\kdvmware_proxypipe", __countof(g_pReporter->GetStatusPointer()->PipeName));
00137 #endif
00138         g_pReporter->GetStatusPointer()->PatchErrorPlus1 = 1;
00139 }