summaryrefslogtreecommitdiff
path: root/src/VBox/Additions/WINNT/VBoxMMR/tsmfhook.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2014-03-26 19:21:20 +0000
committer <>2014-05-08 15:03:54 +0000
commitfb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch)
treec2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/Additions/WINNT/VBoxMMR/tsmfhook.cpp
parent58ed4748338f9466599adfc8a9171280ed99e23f (diff)
downloadVirtualBox-master.tar.gz
Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2.HEADVirtualBox-4.3.10master
Diffstat (limited to 'src/VBox/Additions/WINNT/VBoxMMR/tsmfhook.cpp')
-rw-r--r--src/VBox/Additions/WINNT/VBoxMMR/tsmfhook.cpp392
1 files changed, 218 insertions, 174 deletions
diff --git a/src/VBox/Additions/WINNT/VBoxMMR/tsmfhook.cpp b/src/VBox/Additions/WINNT/VBoxMMR/tsmfhook.cpp
index 6fe890de..f5f875d2 100644
--- a/src/VBox/Additions/WINNT/VBoxMMR/tsmfhook.cpp
+++ b/src/VBox/Additions/WINNT/VBoxMMR/tsmfhook.cpp
@@ -48,6 +48,8 @@ const WCHAR *g_pwszMMRFlags = L"VBoxMMR";
const WCHAR *g_pwszMMRAdditions =
L"SOFTWARE\\Oracle\\VirtualBox Guest Additions";
+const char *g_pszVRDETSMF = "/vrde/tsmf";
+
const DWORD g_dwMMRCodeCavingEnabled = 0x00000002;
BOOL g_bMMRCodeCavingIsEnabled = TRUE;
@@ -94,8 +96,6 @@ uint32_t nUserData = 1;
HANDLE ghVBoxDriver = NULL;
-typedef HRESULT (*g_pMFShutdown)(void);
-
using std::map;
using std::list;
using std::queue;
@@ -299,6 +299,11 @@ public:
return false;
}
+ static uint32_t ChannelCount()
+ {
+ return ChannelList.size();
+ }
+
DWORD GetId() { return m_Id; }
static VBOX_RDP_CHANNEL * GetFromId(DWORD Id)
@@ -521,6 +526,131 @@ void InstallHooks(const IMAGE_IMPORT_DESCRIPTOR *pDescriptor, const PBYTE pBaseA
}
}
+int StartMonitor(RTTHREAD *hMonitor, PFNRTTHREAD pMonitorFn,
+ void *pData, size_t cbStack, RTTHREADTYPE enmType,
+ uint32_t flags, const char *pszName)
+{
+ int rc;
+
+ rc = RTThreadCreate(hMonitor, pMonitorFn, pData,
+ cbStack, enmType, flags, pszName);
+
+ if (RT_FAILURE(rc))
+ {
+ VBoxMMRHookLog("VBoxMMR: Error starting monitor %s: %d\n", pszName, rc);
+ }
+
+ return rc;
+}
+
+int StopMonitor(RTTHREAD *hMonitor, const char* pszName)
+{
+ int rc;
+
+ if (*hMonitor != NIL_RTTHREAD)
+ {
+ rc = RTThreadUserSignal(*hMonitor);
+
+ if (RT_SUCCESS(rc))
+ {
+ // rc = RTThreadWait(*hMonitor, RT_INDEFINITE_WAIT, NULL);
+
+ if (RT_FAILURE(rc))
+ {
+ VBoxMMRHookLog("VBoxMMR: Error waiting for monitor %s to stop: %d\n", pszName, rc);
+ }
+ }
+ else
+ {
+ VBoxMMRHookLog("VBoxMMR: Error sending stop signal to monitor %s: %d\n", pszName, rc);
+ }
+
+ *hMonitor = NIL_RTTHREAD;
+ }
+
+
+ return rc;
+}
+
+DECLCALLBACK(int)
+MonitorDetach(RTTHREAD hThreadSelf, void *pvUser)
+{
+ VBoxGuestFilterMaskInfo maskInfo;
+ DWORD cbReturned;
+ bool bPrevious = FALSE;
+ bool bCurrent = bPrevious;
+
+ maskInfo.u32OrMask = VMMDEV_EVENT_VRDP;
+ maskInfo.u32NotMask = 0;
+
+ VBoxMMRHookLog("VBoxMMR: MonitorDetach starting\n");
+
+ if (DeviceIoControl (ghVBoxDriver, VBOXGUEST_IOCTL_CTL_FILTER_MASK, &maskInfo, sizeof (maskInfo), NULL, 0, &cbReturned, NULL))
+ {
+ VBoxMMRHookLog("VBoxTray: VBoxVRDPThread: DeviceIOControl(CtlMask - or) succeeded\n");
+ }
+ else
+ {
+ VBoxMMRHookLog("VBoxTray: VBoxVRDPThread: DeviceIOControl(CtlMask) failed\n");
+ return 0;
+ }
+
+ for(;;)
+ {
+ /* Call the host to get VRDP status and the experience level. */
+ VMMDevVRDPChangeRequest vrdpChangeRequest = {0};
+
+ vrdpChangeRequest.header.size = sizeof(VMMDevVRDPChangeRequest);
+ vrdpChangeRequest.header.version = VMMDEV_REQUEST_HEADER_VERSION;
+ vrdpChangeRequest.header.requestType = VMMDevReq_GetVRDPChangeRequest;
+ vrdpChangeRequest.u8VRDPActive = 0;
+ vrdpChangeRequest.u32VRDPExperienceLevel = 0;
+
+ if (DeviceIoControl (ghVBoxDriver,
+ VBOXGUEST_IOCTL_VMMREQUEST(sizeof(VMMDevVRDPChangeRequest)),
+ &vrdpChangeRequest,
+ sizeof(VMMDevVRDPChangeRequest),
+ &vrdpChangeRequest,
+ sizeof(VMMDevVRDPChangeRequest),
+ &cbReturned, NULL))
+ {
+ bCurrent = ( vrdpChangeRequest.u8VRDPActive == 1) ? TRUE : FALSE;
+
+ if (bCurrent != bPrevious)
+ {
+ VBoxMMRHookLog(
+ "VBoxMMR: VRDP active status changed: %d\n",
+ vrdpChangeRequest.u8VRDPActive);
+
+ if (bCurrent == FALSE &&
+ VBOX_RDP_CHANNEL::ChannelCount() > 0)
+ {
+ VBoxMMRHookLog("VBoxMMR: exiting ...\n");
+ ExitProcess(0);
+ break;
+ }
+ }
+
+ bPrevious = bCurrent;
+ }
+ else
+ {
+ VBoxMMRHookLog("VBoxMMR: VBoxVRDPThread: Error from DeviceIoControl VBOXGUEST_IOCTL_VMMREQUEST\n");
+
+ }
+
+ if (RTThreadUserWait(hThreadSelf, 1000) == VINF_SUCCESS)
+ {
+ VBoxMMRHookLog("VBoxMMR: detach monitor received stop signal\n");
+ break;
+ }
+ }
+
+ VBoxMMRHookLog("VBoxMMR: MonitorDetach stopping\n");
+
+ return VINF_SUCCESS;
+}
+
/*
* WTSQuerySessionInformationW
*/
@@ -782,11 +912,22 @@ HANDLE WINAPI MMRWinStationVirtualOpenEx(HANDLE hServer, DWORD hSession, LPSTR p
if (RT_SUCCESS(rc))
{
- WaitForSingleObject(hCreateEvent, INFINITE);
+ WaitForSingleObject(hCreateEvent, 5000);
if (g_nCreateResult == VBOX_TSMF_HCH_CREATE_ACCEPTED)
{
h = new VBOX_RDP_CHANNEL(u32ChannelHandle);
+
+ if (hDetachMonitor == NIL_RTTHREAD)
+ {
+ StartMonitor(&hDetachMonitor, MonitorDetach,
+ &nUserData, 0, RTTHREADTYPE_INFREQUENT_POLLER,
+ RTTHREADFLAGS_WAITABLE, "mmrpoll");
+ }
+ }
+ else
+ {
+ VBoxMMRHookLog("VBoxMMR: Unable to open channel: %d\n", g_nCreateResult);
}
}
else
@@ -979,21 +1120,22 @@ FARPROC WINAPI MMRGetProcAddress(HMODULE hModule, LPCSTR lpProcName)
CHAR szDllName[512];
if (FALSE == GetModuleFileNameA(hModule, szDllName, sizeof(szDllName)))
+ {
szDllName[0] = '\0';
-
+ }
}
- else
- if (0 == strcmp(lpProcName, "WTSQuerySessionInformationW"))
- {
- g_pfnWTSQuerySessionInformation = (BOOL (__stdcall *)(HANDLE,DWORD,WTS_INFO_CLASS,LPWSTR *,DWORD *)) ret;
- ret = (FARPROC) LocalWTSQuerySessionInformation;
+ else if (0 == strcmp(lpProcName, "WTSQuerySessionInformationW"))
+ {
+ g_pfnWTSQuerySessionInformation = (BOOL (__stdcall *)(HANDLE,DWORD,WTS_INFO_CLASS,LPWSTR *,DWORD *)) ret;
+ ret = (FARPROC) LocalWTSQuerySessionInformation;
CHAR szDllName[512];
if (FALSE == GetModuleFileNameA(hModule, szDllName, sizeof(szDllName)))
+ {
szDllName[0] = '\0';
-
}
+ }
}
return ret;
@@ -1077,131 +1219,6 @@ static void VBoxMMRCloseBaseDriver(void)
}
}
-DECLCALLBACK(int)
-MonitorDetach(RTTHREAD hThreadSelf, void *pvUser)
-{
- VBoxGuestFilterMaskInfo maskInfo;
- DWORD cbReturned;
- bool bPrevious = TRUE;
- bool bCurrent = TRUE;
-
- maskInfo.u32OrMask = VMMDEV_EVENT_VRDP;
- maskInfo.u32NotMask = 0;
-
- VBoxMMRHookLog("VBoxMMR: MonitorDetach starting\n");
-
- if (DeviceIoControl (ghVBoxDriver, VBOXGUEST_IOCTL_CTL_FILTER_MASK, &maskInfo, sizeof (maskInfo), NULL, 0, &cbReturned, NULL))
- {
- VBoxMMRHookLog("VBoxTray: VBoxVRDPThread: DeviceIOControl(CtlMask - or) succeeded\n");
- }
- else
- {
- VBoxMMRHookLog("VBoxTray: VBoxVRDPThread: DeviceIOControl(CtlMask) failed\n");
- return 0;
- }
-
- g_pMFShutdown ret = (g_pMFShutdown)GetProcAddress(GetModuleHandle(TEXT("Mfplat.dll")),"MFShutdown");
-
-
- for(;;)
- {
- /* Call the host to get VRDP status and the experience level. */
- VMMDevVRDPChangeRequest vrdpChangeRequest = {0};
-
- vrdpChangeRequest.header.size = sizeof(VMMDevVRDPChangeRequest);
- vrdpChangeRequest.header.version = VMMDEV_REQUEST_HEADER_VERSION;
- vrdpChangeRequest.header.requestType = VMMDevReq_GetVRDPChangeRequest;
- vrdpChangeRequest.u8VRDPActive = 0;
- vrdpChangeRequest.u32VRDPExperienceLevel = 0;
-
- if (DeviceIoControl (ghVBoxDriver,
- VBOXGUEST_IOCTL_VMMREQUEST(sizeof(VMMDevVRDPChangeRequest)),
- &vrdpChangeRequest,
- sizeof(VMMDevVRDPChangeRequest),
- &vrdpChangeRequest,
- sizeof(VMMDevVRDPChangeRequest),
- &cbReturned, NULL))
- {
- VBoxMMRHookLog("VBoxMMR: VBoxVRDPThread: u8VRDPActive = %d, level %d\n", vrdpChangeRequest.u8VRDPActive, vrdpChangeRequest.u32VRDPExperienceLevel);
- bCurrent = ( vrdpChangeRequest.u8VRDPActive == 1) ? TRUE : FALSE;
- if (bCurrent != bPrevious && bCurrent == FALSE)
- {
- HWND hWnd = FindWindow(L"WMPlayerApp", NULL);
- if (hWnd != NULL)
- {
- VBoxMMRHookLog("VBoxMMR: PostMessage close\n");
- PostMessage(hWnd, WM_COMMAND, (WPARAM) 84345 , NULL);
- //g_pMFShutdown();
-
- }
- }
- bPrevious = bCurrent;
-
- }
- else
- {
- VBoxMMRHookLog("VBoxMMR: VBoxVRDPThread: Error from DeviceIoControl VBOXGUEST_IOCTL_VMMREQUEST\n");
-
- }
-
- if (RTThreadUserWait(hThreadSelf, 1000) == VINF_SUCCESS)
- {
- VBoxMMRHookLog("VBoxMMR: detach monitor received stop signal\n");
- break;
- }
- }
-
- VBoxMMRHookLog("VBoxMMR: MonitorDetach stopping\n");
-
- return VINF_SUCCESS;
-}
-
-int StartMonitor(RTTHREAD hMonitor, PFNRTTHREAD pMonitorFn,
- void *pData, size_t cbStack, RTTHREADTYPE enmType,
- uint32_t flags, const char *pszName)
-{
- int rc;
-
- rc = RTThreadCreate(&hMonitor, pMonitorFn, pData,
- cbStack, enmType, flags, pszName);
-
- if (RT_FAILURE(rc))
- {
- VBoxMMRHookLog("VBoxMMR: Error starting monitor %s: %d\n", pszName, rc);
- }
-
- return rc;
-}
-
-int StopMonitor(RTTHREAD hMonitor, const char* pszName)
-{
- int rc;
-
- if (hMonitor != NIL_RTTHREAD)
- {
- rc = RTThreadUserSignal(hMonitor);
-
- if (RT_SUCCESS(rc))
- {
- // rc = RTThreadWait(hMonitor, RT_INDEFINITE_WAIT, NULL);
-
- if (RT_FAILURE(rc))
- {
- VBoxMMRHookLog("VBoxMMR: Error waiting for monitor %s to stop: %d\n", pszName, rc);
- }
- }
- else
- {
- VBoxMMRHookLog("VBoxMMR: Error sending stop signal to monitor %s: %d\n", pszName, rc);
- }
-
- hMonitor = NIL_RTTHREAD;
- }
-
-
- return rc;
-}
-
void
ReadTSMF(uint32_t u32ChannelHandle, uint32_t u32HGCMClientId, uint32_t u32SizeAvailable)
{
@@ -1325,19 +1342,29 @@ MonitorTSMFChannel(RTTHREAD hThreadSelf, void *pvUser)
return VINF_SUCCESS;
}
-void InstallHooksForModule(const char *pszName, HookEntry hooks[])
+void InstallHooksForSystemModule(const char *pszName, HookEntry hooks[])
{
- HMODULE hMod = LoadLibraryA(pszName);
- if (hMod != NULL)
+ /* Construct the full path to the given module and load it. */
+ char szPath[MAX_PATH];
+ UINT cchPath = GetSystemDirectoryA(szPath, MAX_PATH);
+ size_t cbName = strlen(pszName) + 1;
+ if (cchPath + 1 + cbName <= sizeof(szPath))
{
- VBoxMMRHookLog("VBoxMMR: Hooking %s -> %x \n", pszName, hMod);
- const IMAGE_IMPORT_DESCRIPTOR *pDescriptor = GetImportDescriptor(hMod);
- InstallHooks(pDescriptor, (PBYTE) hMod, hooks);
+ szPath[cchPath] = '\\';
+ memcpy(&szPath[cchPath + 1], pszName, cbName);
+
+ HMODULE hMod = LoadLibraryA(szPath);
+ if (hMod != NULL)
+ {
+ VBoxMMRHookLog("VBoxMMR: Hooking %s -> %x \n", pszName, hMod);
+ const IMAGE_IMPORT_DESCRIPTOR *pDescriptor = GetImportDescriptor(hMod);
+ InstallHooks(pDescriptor, (PBYTE) hMod, hooks);
+ }
+ else
+ VBoxMMRHookLog("VBoxMMR: Error hooking %s -> not found (last error %u)\n", pszName, GetLastError());
}
else
- {
VBoxMMRHookLog("VBoxMMR: Error hooking %s -> not found\n", pszName);
- }
}
TSMFHOOK_API LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
@@ -1352,17 +1379,24 @@ TSMFHOOK_API LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
VBoxMMRHookLog("VBoxMMR: WMP APIs Hooking started ...\n");
- InstallHooksForModule("winmm.dll", g_WinMMHooks);
- InstallHooksForModule("tsmf.dll", g_TSMFHooks);
- InstallHooksForModule("DSHOWRDPFILTER.dll", g_TSMFHooks);
- InstallHooksForModule("MSMPEG2VDEC.dll", g_DShowHooks);
- InstallHooksForModule("MFDS.dll", g_DShowHooks);
- InstallHooksForModule("mf.dll", g_MFHooks);
-
HMODULE hMod = GetModuleHandleA("wmp");
- VBoxMMRHookLog("VBoxMMR: Hooking wmp -> %x \n",hMod);
- const IMAGE_IMPORT_DESCRIPTOR *pDescriptor = GetImportDescriptor(hMod);
- InstallHooks(pDescriptor, (PBYTE) hMod, g_WMPHooks);
+ if (hMod != NULL)
+ {
+ VBoxMMRHookLog("VBoxMMR: Hooking wmp -> %x \n",hMod);
+ const IMAGE_IMPORT_DESCRIPTOR *pDescriptor = GetImportDescriptor(hMod);
+ InstallHooks(pDescriptor, (PBYTE) hMod, g_WMPHooks);
+ }
+ else
+ {
+ VBoxMMRHookLog("VBoxMMR: Error hooking wmp -> not found\n");
+ }
+
+ InstallHooksForSystemModule("winmm.dll", g_WinMMHooks);
+ InstallHooksForSystemModule("tsmf.dll", g_TSMFHooks);
+ InstallHooksForSystemModule("DSHOWRDPFILTER.dll", g_TSMFHooks);
+ InstallHooksForSystemModule("MSMPEG2VDEC.dll", g_DShowHooks);
+ InstallHooksForSystemModule("MFDS.dll", g_DShowHooks);
+ InstallHooksForSystemModule("mf.dll", g_MFHooks);
ULONG ret = RegisterTraceGuids(
ControlCallback, NULL, &ProviderId, 0,
@@ -1373,36 +1407,45 @@ TSMFHOOK_API LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
VBoxMMRHookLog("VBoxMMR: RegisterTraceGuids failed with error code: %u\n", GetLastError());
}
- int rc = VBoxMMROpenBaseDriver();
-
- if (RT_SUCCESS(rc))
- {
- StartMonitor(hDetachMonitor, MonitorDetach,
- &nUserData, 0, RTTHREADTYPE_INFREQUENT_POLLER,
- RTTHREADFLAGS_WAITABLE, "mmrpoll");
- }
-
bool bInRDPSession = (1 == GetSystemMetrics(0x1000));
if (!bInRDPSession)
{
uint32_t u32HGCMClientId = 0;
- rc = VbglR3HostChannelInit(&u32HGCMClientId);
+ int rc = VbglR3HostChannelInit(&u32HGCMClientId);
if (RT_SUCCESS(rc))
{
- hCreateEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- InitializeCriticalSection(&CreateLock);
+ uint32_t u32Size = 0;
- g_HostChannelCtx.thread = NIL_RTTHREAD;
- g_HostChannelCtx.u32HGCMClientId = u32HGCMClientId;
+ rc = VbglR3HostChannelQuery(g_pszVRDETSMF, u32HGCMClientId,
+ VBOX_HOST_CHANNEL_CTRL_EXISTS, NULL, 0, NULL, 0, &u32Size);
- StartMonitor(
- g_HostChannelCtx.thread, MonitorTSMFChannel,
- &g_HostChannelCtx, 64*_1K,
- RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE,
- "tsmfio");
+ if (RT_SUCCESS(rc))
+ {
+ hCreateEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ InitializeCriticalSection(&CreateLock);
+
+ g_HostChannelCtx.thread = NIL_RTTHREAD;
+ g_HostChannelCtx.u32HGCMClientId = u32HGCMClientId;
+
+ StartMonitor(
+ &g_HostChannelCtx.thread, MonitorTSMFChannel,
+ &g_HostChannelCtx, 64*_1K,
+ RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE,
+ "tsmfio");
+
+ VBoxMMROpenBaseDriver();
+ }
+ else
+ {
+ VBoxMMRHookLog(
+ "VBoxMMR: TSMF HGCM unavailable: hgcmid: %d, rc: %d\n",
+ u32HGCMClientId, rc);
+
+ VbglR3HostChannelTerm(u32HGCMClientId);
+ }
}
else
{
@@ -1420,13 +1463,14 @@ void Shutdown()
{
VBoxMMRHookLog("VBoxMMR: Shutdown\n");
- StopMonitor(hDetachMonitor, "mmrpoll");
+ StopMonitor(&hDetachMonitor, "mmrpoll");
VBoxMMRCloseBaseDriver();
if (g_HostChannelCtx.u32HGCMClientId != 0)
{
g_HostChannelCtx.fShutdown = true;
- StopMonitor(g_HostChannelCtx.thread, "tsmfio");
+ VbglR3HostChannelEventCancel(0, g_HostChannelCtx.u32HGCMClientId);
+ StopMonitor(&g_HostChannelCtx.thread, "tsmfio");
VbglR3HostChannelTerm(g_HostChannelCtx.u32HGCMClientId);
}