VBoxTray.cpp revision e0791f3e14768aaf0020eb06cbb0ada32c52f3ce
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync/* $Id$ */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync/** @file
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * VBoxTray - Guest Additions Tray Application
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync */
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync/*
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync * Copyright (C) 2006-2011 Oracle Corporation
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync *
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync * available from http://www.virtualbox.org. This file is free software;
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync * you can redistribute it and/or modify it under the terms of the GNU
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync * General Public License (GPL) as published by the Free Software
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync */
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync/*******************************************************************************
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync* Header Files *
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync*******************************************************************************/
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync#include "VBoxTray.h"
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync#include "VBoxTrayMsg.h"
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync#include "VBoxHelpers.h"
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync#include "VBoxSeamless.h"
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync#include "VBoxClipboard.h"
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync#include "VBoxDisplay.h"
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync#include "VBoxRestore.h"
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync#include "VBoxVRDP.h"
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync#include "VBoxHostVersion.h"
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync#include "VBoxSharedFolders.h"
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync#include "VBoxIPC.h"
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync#include "VBoxLA.h"
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync#include <VBoxHook.h>
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync#include "resource.h"
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync#include <malloc.h>
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync#include <VBoxGuestInternal.h>
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync#include <sddl.h>
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync#include <iprt/buildconfig.h>
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync/*******************************************************************************
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync* Internal Functions *
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync*******************************************************************************/
6728a36898fd2be125a28e84d2115d19aa4923edvboxsyncstatic int vboxTrayCreateTrayIcon(void);
9562e2d410460d8fae06fa24297f172fee1d1995vboxsyncstatic LRESULT CALLBACK vboxToolWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync/* Global message handler prototypes. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsyncstatic int vboxTrayGlMsgTaskbarCreated(WPARAM lParam, LPARAM wParam);
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync/*static int vboxTrayGlMsgShowBalloonMsg(WPARAM lParam, LPARAM wParam);*/
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync/*******************************************************************************
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync* Global Variables *
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync*******************************************************************************/
6728a36898fd2be125a28e84d2115d19aa4923edvboxsyncHANDLE ghVBoxDriver;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsyncHANDLE ghStopSem;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsyncHANDLE ghSeamlessNotifyEvent = 0;
9562e2d410460d8fae06fa24297f172fee1d1995vboxsyncSERVICE_STATUS gVBoxServiceStatus;
9562e2d410460d8fae06fa24297f172fee1d1995vboxsyncSERVICE_STATUS_HANDLE gVBoxServiceStatusHandle;
9562e2d410460d8fae06fa24297f172fee1d1995vboxsyncHINSTANCE ghInstance;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsyncHWND ghwndToolWindow;
9562e2d410460d8fae06fa24297f172fee1d1995vboxsyncNOTIFYICONDATA gNotifyIconData;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsyncDWORD gMajorVersion;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync/* The service table. */
9562e2d410460d8fae06fa24297f172fee1d1995vboxsyncstatic VBOXSERVICEINFO vboxServiceTable[] =
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync{
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync {
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync "Display",
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VBoxDisplayInit,
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VBoxDisplayThread,
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VBoxDisplayDestroy
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync },
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync {
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync "Shared Clipboard",
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync VBoxClipboardInit,
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VBoxClipboardThread,
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync VBoxClipboardDestroy
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync },
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync "Seamless Windows",
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync VBoxSeamlessInit,
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync VBoxSeamlessThread,
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync VBoxSeamlessDestroy
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync },
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync#ifdef VBOX_WITH_VRDP_SESSION_HANDLING
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync "Restore",
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VBoxRestoreInit,
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync VBoxRestoreThread,
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VBoxRestoreDestroy
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync },
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync#endif
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync "VRDP",
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VBoxVRDPInit,
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VBoxVRDPThread,
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VBoxVRDPDestroy
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync },
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync "IPC",
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VBoxIPCInit,
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VBoxIPCThread,
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VBoxIPCDestroy
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync },
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync "Location Awareness",
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VBoxLAInit,
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VBoxLAThread,
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VBoxLADestroy
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync },
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync NULL
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync};
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync/* The global message table. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsyncstatic VBOXGLOBALMESSAGE s_vboxGlobalMessageTable[] =
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync{
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Windows specific stuff. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync "TaskbarCreated",
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync vboxTrayGlMsgTaskbarCreated
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync },
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync /* VBoxTray specific stuff. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /** @todo Add new messages here! */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync NULL
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync};
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync/**
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * Gets called whenever the Windows main taskbar
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync * get (re-)created. Nice to install our tray icon.
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync *
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * @return IPRT status code.
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * @param wParam
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * @param lParam
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsyncstatic int vboxTrayGlMsgTaskbarCreated(WPARAM wParam, LPARAM lParam)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync{
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return vboxTrayCreateTrayIcon();
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync}
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsyncstatic int vboxTrayCreateTrayIcon(void)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync{
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync HICON hIcon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_VIRTUALBOX));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (hIcon == NULL)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync DWORD dwErr = GetLastError();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: Could not load tray icon, error %08X\n", dwErr));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return RTErrConvertFromWin32(dwErr);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Prepare the system tray icon. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync RT_ZERO(gNotifyIconData);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync gNotifyIconData.cbSize = NOTIFYICONDATA_V1_SIZE; // sizeof(NOTIFYICONDATA);
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync gNotifyIconData.hWnd = ghwndToolWindow;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync gNotifyIconData.uID = ID_TRAYICON;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync gNotifyIconData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync gNotifyIconData.uCallbackMessage = WM_VBOXTRAY_TRAY_ICON;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync gNotifyIconData.hIcon = hIcon;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync sprintf(gNotifyIconData.szTip, "%s Guest Additions %d.%d.%dr%d",
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VBOX_PRODUCT, VBOX_VERSION_MAJOR, VBOX_VERSION_MINOR, VBOX_VERSION_BUILD, VBOX_SVN_REV);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync int rc = VINF_SUCCESS;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (!Shell_NotifyIcon(NIM_ADD, &gNotifyIconData))
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync DWORD dwErr = GetLastError();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: Could not create tray icon, error = %08X\n", dwErr));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync rc = RTErrConvertFromWin32(dwErr);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync RT_ZERO(gNotifyIconData);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync if (hIcon)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync DestroyIcon(hIcon);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return rc;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync}
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsyncstatic void vboxTrayRemoveTrayIcon()
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync{
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (gNotifyIconData.cbSize > 0)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync /* Remove the system tray icon and refresh system tray. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Shell_NotifyIcon(NIM_DELETE, &gNotifyIconData);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync HWND hTrayWnd = FindWindow("Shell_TrayWnd", NULL); /* We assume we only have one tray atm. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (hTrayWnd)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync HWND hTrayNotifyWnd = FindWindowEx(hTrayWnd, 0, "TrayNotifyWnd", NULL);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (hTrayNotifyWnd)
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync SendMessage(hTrayNotifyWnd, WM_PAINT, 0, NULL);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync RT_ZERO(gNotifyIconData);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync}
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsyncstatic int vboxTrayStartServices(VBOXSERVICEENV *pEnv, VBOXSERVICEINFO *pTable)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync{
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: Starting services ...\n"));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync pEnv->hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (!pEnv->hStopEvent)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync /* Could not create event. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return VERR_NOT_SUPPORTED;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync while (pTable->pszName)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: Starting %s ...\n", pTable->pszName));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync int rc = VINF_SUCCESS;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync bool fStartThread = false;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync pTable->hThread = (HANDLE)0;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync pTable->pInstance = NULL;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync pTable->fStarted = false;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync if (pTable->pfnInit)
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync rc = pTable->pfnInit (pEnv, &pTable->pInstance, &fStartThread);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (RT_FAILURE(rc))
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: Failed to initialize rc = %Rrc\n", rc));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync else
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (pTable->pfnThread && fStartThread)
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync unsigned threadid;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync pTable->hThread = (HANDLE)_beginthreadex(NULL, /* security */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync 0, /* stacksize */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync pTable->pfnThread,
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync pTable->pInstance,
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync 0, /* initflag */
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync &threadid);
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync if (pTable->hThread == (HANDLE)(0))
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync rc = VERR_NOT_SUPPORTED;
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync }
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync if (RT_SUCCESS(rc))
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync pTable->fStarted = true;
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync else
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync {
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync Log(("VBoxTray: Failed to start the thread\n"));
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync if (pTable->pfnDestroy)
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync pTable->pfnDestroy(pEnv, pTable->pInstance);
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync }
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Advance to next table element. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync pTable++;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
9562e2d410460d8fae06fa24297f172fee1d1995vboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return VINF_SUCCESS;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync}
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsyncstatic void vboxTrayStopServices(VBOXSERVICEENV *pEnv, VBOXSERVICEINFO *pTable)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync{
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (!pEnv->hStopEvent)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Signal to all threads. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync SetEvent(pEnv->hStopEvent);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync while (pTable->pszName)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (pTable->fStarted)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (pTable->pfnThread)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* There is a thread, wait for termination. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync WaitForSingleObject(pTable->hThread, INFINITE);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync CloseHandle(pTable->hThread);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync pTable->hThread = 0;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (pTable->pfnDestroy)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync pTable->pfnDestroy (pEnv, pTable->pInstance);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync pTable->fStarted = false;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Advance to next table element. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync pTable++;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync CloseHandle(pEnv->hStopEvent);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync}
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsyncstatic int vboxTrayRegisterGlobalMessages(PVBOXGLOBALMESSAGE pTable)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync{
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync int rc = VINF_SUCCESS;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (pTable == NULL) /* No table to register? Skip. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return rc;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync while ( pTable->pszName
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync && RT_SUCCESS(rc))
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Register global accessible window messages. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync pTable->uMsgID = RegisterWindowMessage(TEXT(pTable->pszName));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (!pTable->uMsgID)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync DWORD dwErr = GetLastError();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: Registering global message \"%s\" failed, error = %08X\n", dwErr));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync rc = RTErrConvertFromWin32(dwErr);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Advance to next table element. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync pTable++;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return rc;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync}
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsyncstatic bool vboxTrayHandleGlobalMessages(PVBOXGLOBALMESSAGE pTable, UINT uMsg,
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync WPARAM wParam, LPARAM lParam)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync{
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (pTable == NULL)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return false;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync while (pTable && pTable->pszName)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (pTable->uMsgID == uMsg)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (pTable->pfnHandler)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync pTable->pfnHandler(wParam, lParam);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return true;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Advance to next table element. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync pTable++;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return false;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync}
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsyncstatic int vboxTrayOpenBaseDriver(void)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync{
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Open VBox guest driver. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync DWORD dwErr = ERROR_SUCCESS;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync ghVBoxDriver = CreateFile(VBOXGUEST_DEVICE_NAME,
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync GENERIC_READ | GENERIC_WRITE,
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync FILE_SHARE_READ | FILE_SHARE_WRITE,
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync NULL,
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync OPEN_EXISTING,
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync NULL);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (ghVBoxDriver == INVALID_HANDLE_VALUE)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync dwErr = GetLastError();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync LogRel(("VBoxTray: Could not open VirtualBox Guest Additions driver! Please install / start it first! Error = %08X\n", dwErr));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return RTErrConvertFromWin32(dwErr);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync}
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsyncstatic void vboxTrayCloseBaseDriver(void)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync{
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (ghVBoxDriver)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync CloseHandle(ghVBoxDriver);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync ghVBoxDriver = NULL;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync}
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsyncstatic void vboxTrayDestroyToolWindow(void)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync{
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (ghwndToolWindow)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: Destroying tool window ...\n"));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Destroy the tool window. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync DestroyWindow(ghwndToolWindow);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync ghwndToolWindow = NULL;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync UnregisterClass("VBoxTrayToolWndClass", ghInstance);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync}
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsyncstatic int vboxTrayCreateToolWindow(void)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync{
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync DWORD dwErr = ERROR_SUCCESS;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Create a custom window class. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync WNDCLASS windowClass = {0};
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync windowClass.style = CS_NOCLOSE;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync windowClass.lpfnWndProc = (WNDPROC)vboxToolWndProc;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync windowClass.hInstance = ghInstance;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync windowClass.lpszClassName = "VBoxTrayToolWndClass";
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (!RegisterClass(&windowClass))
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync dwErr = GetLastError();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: Registering invisible tool window failed, error = %08X\n", dwErr));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync else
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /*
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * Create our (invisible) tool window.
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * Note: The window name ("VBoxTrayToolWnd") and class ("VBoxTrayToolWndClass") is
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * needed for posting globally registered messages to VBoxTray and must not be
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * changed! Otherwise things get broken!
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync *
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync ghwndToolWindow = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync "VBoxTrayToolWndClass", "VBoxTrayToolWnd",
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync WS_POPUPWINDOW,
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync -200, -200, 100, 100, NULL, NULL, ghInstance, NULL);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (!ghwndToolWindow)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync dwErr = GetLastError();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: Creating invisible tool window failed, error = %08X\n", dwErr));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync else
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Reload the cursor(s). */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync hlpReloadCursor();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: Invisible tool window handle = %p\n", ghwndToolWindow));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (dwErr != ERROR_SUCCESS)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync vboxTrayDestroyToolWindow();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return RTErrConvertFromWin32(dwErr);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync}
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsyncstatic int vboxTraySetupSeamless(void)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync{
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync OSVERSIONINFO info;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync gMajorVersion = 5; /* Default to Windows XP. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync info.dwOSVersionInfoSize = sizeof(info);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (GetVersionEx(&info))
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: Windows version %ld.%ld\n", info.dwMajorVersion, info.dwMinorVersion));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync gMajorVersion = info.dwMajorVersion;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* We need to setup a security descriptor to allow other processes modify access to the seamless notification event semaphore. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync SECURITY_ATTRIBUTES SecAttr;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync DWORD dwErr = ERROR_SUCCESS;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync char secDesc[SECURITY_DESCRIPTOR_MIN_LENGTH];
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync BOOL fRC;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync SecAttr.nLength = sizeof(SecAttr);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync SecAttr.bInheritHandle = FALSE;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync SecAttr.lpSecurityDescriptor = &secDesc;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync InitializeSecurityDescriptor(SecAttr.lpSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync fRC = SetSecurityDescriptorDacl(SecAttr.lpSecurityDescriptor, TRUE, 0, FALSE);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (!fRC)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync dwErr = GetLastError();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: SetSecurityDescriptorDacl failed with last error = %08X\n", dwErr));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync else
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* For Vista and up we need to change the integrity of the security descriptor, too. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (gMajorVersion >= 6)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync BOOL (WINAPI * pfnConvertStringSecurityDescriptorToSecurityDescriptorA)(LPCSTR StringSecurityDescriptor, DWORD StringSDRevision, PSECURITY_DESCRIPTOR *SecurityDescriptor, PULONG SecurityDescriptorSize);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync HMODULE hModule = LoadLibrary("ADVAPI32.DLL");
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (!hModule)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync dwErr = GetLastError();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: Loading module ADVAPI32.DLL failed with last error = %08X\n", dwErr));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync else
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync PSECURITY_DESCRIPTOR pSD;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync PACL pSacl = NULL;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync BOOL fSaclPresent = FALSE;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync BOOL fSaclDefaulted = FALSE;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync *(uintptr_t *)&pfnConvertStringSecurityDescriptorToSecurityDescriptorA = (uintptr_t)GetProcAddress(hModule, "ConvertStringSecurityDescriptorToSecurityDescriptorA");
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: pfnConvertStringSecurityDescriptorToSecurityDescriptorA = %x\n", pfnConvertStringSecurityDescriptorToSecurityDescriptorA));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (pfnConvertStringSecurityDescriptorToSecurityDescriptorA)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync fRC = pfnConvertStringSecurityDescriptorToSecurityDescriptorA("S:(ML;;NW;;;LW)", /* this means "low integrity" */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync SDDL_REVISION_1, &pSD, NULL);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (!fRC)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync dwErr = GetLastError();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: ConvertStringSecurityDescriptorToSecurityDescriptorA failed with last error = %08X\n", dwErr));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync else
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync fRC = GetSecurityDescriptorSacl(pSD, &fSaclPresent, &pSacl, &fSaclDefaulted);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (!fRC)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync dwErr = GetLastError();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: GetSecurityDescriptorSacl failed with last error = %08X\n", dwErr));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync else
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync fRC = SetSecurityDescriptorSacl(SecAttr.lpSecurityDescriptor, TRUE, pSacl, FALSE);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (!fRC)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync dwErr = GetLastError();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: SetSecurityDescriptorSacl failed with last error = %08X\n", dwErr));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if ( dwErr == ERROR_SUCCESS
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync && gMajorVersion >= 5) /* Only for W2K and up ... */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync ghSeamlessNotifyEvent = CreateEvent(&SecAttr, FALSE, FALSE, VBOXHOOK_GLOBAL_EVENT_NAME);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (ghSeamlessNotifyEvent == NULL)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync dwErr = GetLastError();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: CreateEvent for Seamless failed, last error = %08X\n", dwErr));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return RTErrConvertFromWin32(dwErr);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync}
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsyncstatic void vboxTrayShutdownSeamless(void)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync{
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (ghSeamlessNotifyEvent)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync CloseHandle(ghSeamlessNotifyEvent);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync ghSeamlessNotifyEvent = NULL;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync}
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsyncstatic int vboxTrayServiceMain(void)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync{
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync int rc = VINF_SUCCESS;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: Entering vboxTrayServiceMain\n"));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync ghStopSem = CreateEvent(NULL, TRUE, FALSE, NULL);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (ghStopSem == NULL)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync rc = RTErrConvertFromWin32(GetLastError());
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: CreateEvent for stopping VBoxTray failed, rc=%Rrc\n", rc));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync else
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /*
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * Start services listed in the vboxServiceTable.
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VBOXSERVICEENV svcEnv;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync svcEnv.hInstance = ghInstance;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync svcEnv.hDriver = ghVBoxDriver;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Initializes disp-if to default (XPDM) mode. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VBoxDispIfInit(&svcEnv.dispIf); /* Cannot fail atm. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync #ifdef VBOX_WITH_WDDM
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /*
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * For now the display mode will be adjusted to WDDM mode if needed
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * on display service initialization when it detects the display driver type.
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync #endif
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Finally start all the built-in services! */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync rc = vboxTrayStartServices(&svcEnv, vboxServiceTable);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (RT_FAILURE(rc))
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Terminate service if something went wrong. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync vboxTrayStopServices(&svcEnv, vboxServiceTable);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync else
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync rc = vboxTrayCreateTrayIcon();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if ( RT_SUCCESS(rc)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync && gMajorVersion >= 5) /* Only for W2K and up ... */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* We're ready to create the tooltip balloon.
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Check in 10 seconds (@todo make seconds configurable) ... */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync SetTimer(ghwndToolWindow,
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync TIMERID_VBOXTRAY_CHECK_HOSTVERSION,
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync 10 * 1000, /* 10 seconds */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync NULL /* No timerproc */);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (RT_SUCCESS(rc))
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Do the Shared Folders auto-mounting stuff. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync rc = VBoxSharedFoldersAutoMount();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (RT_SUCCESS(rc))
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Report the host that we're up and running! */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync hlpReportStatus(VBoxGuestFacilityStatus_Active);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (RT_SUCCESS(rc))
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Boost thread priority to make sure we wake up early for seamless window notifications
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * (not sure if it actually makes any difference though). */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /*
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * Main execution loop
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * Wait for the stop semaphore to be posted or a window event to arrive
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync DWORD dwEventCount = 2;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync HANDLE hWaitEvent[2] = { ghStopSem, ghSeamlessNotifyEvent };
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (0 == ghSeamlessNotifyEvent) /* If seamless mode is not active / supported, reduce event array count. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync dwEventCount = 1;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: Number of events to wait in main loop: %ld\n", dwEventCount));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync while (true)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync DWORD waitResult = MsgWaitForMultipleObjectsEx(dwEventCount, hWaitEvent, 500, QS_ALLINPUT, 0);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync waitResult = waitResult - WAIT_OBJECT_0;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Only enable for message debugging, lots of traffic! */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync //Log(("VBoxTray: Wait result = %ld\n", waitResult));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (waitResult == 0)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: Event 'Exit' triggered\n"));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* exit */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync break;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync else if ( waitResult == 1
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync && ghSeamlessNotifyEvent != 0) /* Only jump in, if seamless is active! */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: Event 'Seamless' triggered\n"));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* seamless window notification */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VBoxSeamlessCheckWindows();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync else
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* timeout or a window message, handle it */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync MSG msg;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: msg %p\n", msg.message));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (msg.message == WM_QUIT)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: WM_QUIT!\n"));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync SetEvent(ghStopSem);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync continue;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync TranslateMessage(&msg);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync DispatchMessage(&msg);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: Returned from main loop, exiting ...\n"));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: Waiting for services to stop ...\n"));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync vboxTrayStopServices(&svcEnv, vboxServiceTable);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync } /* Services started */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync CloseHandle(ghStopSem);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync } /* Stop event created */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync vboxTrayRemoveTrayIcon();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: Leaving vboxTrayServiceMain with rc=%Rrc\n", rc));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return rc;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync}
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync/**
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * Main function
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsyncint APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync{
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Do not use a global namespace ("Global\\") for mutex name here, will blow up NT4 compatibility! */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync HANDLE hMutexAppRunning = CreateMutex(NULL, FALSE, "VBoxTray");
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if ( hMutexAppRunning != NULL
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync && GetLastError() == ERROR_ALREADY_EXISTS)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Close the mutex for this application instance. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync CloseHandle (hMutexAppRunning);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync hMutexAppRunning = NULL;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return 0;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync LogRel(("VBoxTray: %s r%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr()));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync int rc = RTR3InitExeNoArguments(0);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (RT_SUCCESS(rc))
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync rc = VbglR3Init();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (RT_SUCCESS(rc))
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync rc = vboxTrayOpenBaseDriver();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (RT_SUCCESS(rc))
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Save instance handle. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync ghInstance = hInstance;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync hlpReportStatus(VBoxGuestFacilityStatus_Init);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync rc = vboxTrayCreateToolWindow();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (RT_SUCCESS(rc))
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync rc = vboxTraySetupSeamless();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (RT_SUCCESS(rc))
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: Init successful\n"));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync rc = vboxTrayServiceMain();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (RT_SUCCESS(rc))
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync hlpReportStatus(VBoxGuestFacilityStatus_Terminating);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync vboxTrayShutdownSeamless();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync vboxTrayDestroyToolWindow();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (RT_SUCCESS(rc))
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync hlpReportStatus(VBoxGuestFacilityStatus_Terminated);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (RT_FAILURE(rc))
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync LogRel(("VBoxTray: Error while starting, rc=%Rrc\n", rc));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync hlpReportStatus(VBoxGuestFacilityStatus_Failed);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync LogRel(("VBoxTray: Ended\n"));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync vboxTrayCloseBaseDriver();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Release instance mutex. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (hMutexAppRunning != NULL)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync CloseHandle(hMutexAppRunning);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync hMutexAppRunning = NULL;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VbglR3Term();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return RT_SUCCESS(rc) ? 0 : 1;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync}
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync/**
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * Window procedure for our tool window
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsyncstatic LRESULT CALLBACK vboxToolWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync{
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync switch (uMsg)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync case WM_CREATE:
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: Tool window created\n"));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync int rc = vboxTrayRegisterGlobalMessages(&s_vboxGlobalMessageTable[0]);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (RT_FAILURE(rc))
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: Error registering global window messages, rc=%Rrc\n", rc));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return 0;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync case WM_CLOSE:
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return 0;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync case WM_DESTROY:
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync Log(("VBoxTray: Tool window destroyed\n"));
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync KillTimer(ghwndToolWindow, TIMERID_VBOXTRAY_CHECK_HOSTVERSION);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return 0;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync case WM_TIMER:
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync switch (wParam)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync case TIMERID_VBOXTRAY_CHECK_HOSTVERSION:
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (RT_SUCCESS(VBoxCheckHostVersion()))
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* After successful run we don't need to check again. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync KillTimer(ghwndToolWindow, TIMERID_VBOXTRAY_CHECK_HOSTVERSION);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return 0;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync default:
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync break;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync break; /* Make sure other timers get processed the usual way! */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync case WM_VBOXTRAY_TRAY_ICON:
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync switch (lParam)
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync case WM_LBUTTONDBLCLK:
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync break;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync case WM_RBUTTONDOWN:
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync break;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return 0;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync case WM_VBOX_INSTALL_SEAMLESS_HOOK:
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VBoxSeamlessInstallHook();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return 0;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync case WM_VBOX_REMOVE_SEAMLESS_HOOK:
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VBoxSeamlessRemoveHook();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return 0;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync case WM_VBOX_SEAMLESS_UPDATE:
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VBoxSeamlessCheckWindows();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return 0;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync case WM_VBOXTRAY_VM_RESTORED:
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VBoxRestoreSession();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return 0;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync case WM_VBOXTRAY_VRDP_CHECK:
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync VBoxRestoreCheckVRDP();
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return 0;
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync default:
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Handle all globally registered window messages. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync if (vboxTrayHandleGlobalMessages(&s_vboxGlobalMessageTable[0], uMsg,
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync wParam, lParam))
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync {
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return 0; /* We handled the message. @todo Add return value!*/
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync break; /* We did not handle the message, dispatch to DefWndProc. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync }
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync /* Only if message was *not* handled by our switch above, dispatch
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync * to DefWindowProc. */
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync return DefWindowProc(hWnd, uMsg, wParam, lParam);
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync}
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync
6728a36898fd2be125a28e84d2115d19aa4923edvboxsync