VirtualBox

Changeset 3789 in vbox for trunk


Ignore:
Timestamp:
Jul 23, 2007 2:52:38 PM (17 years ago)
Author:
vboxsync
Message:

Changes for seamless mode switching

Location:
trunk/src/VBox/Additions/WINNT/VBoxService
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/VBoxService/VBoxSeamless.cpp

    r3739 r3789  
    2525#include <VBoxHook.h>
    2626#include <VBox/VBoxDev.h>
     27#include <iprt/assert.h>
    2728#include "helpers.h"
    2829
    29 static HMODULE hModule = 0;
    30 
    31 BOOL (* pfnVBoxInstallHook)(HMODULE hDll) = NULL;
    32 BOOL (* pfnVBoxRemoveHook)() = NULL;
    33 
     30typedef struct _VBOXSEAMLESSCONTEXT
     31{
     32    const VBOXSERVICEENV *pEnv;
     33
     34    HMODULE hModule;
     35
     36    BOOL (* pfnVBoxInstallHook)(HMODULE hDll);
     37    BOOL (* pfnVBoxRemoveHook)();
     38
     39} VBOXSEAMLESSCONTEXT;
     40
     41static VBOXSEAMLESSCONTEXT gCtx = {0};
    3442
    3543void VBoxLogString(HANDLE hDriver, char *pszStr);
     
    3745int VBoxSeamlessInit(const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread)
    3846{
     47    dprintf(("VBoxSeamlessInit\n"));
     48
    3949    *pfStartThread = false;
    40 
    41     dprintf(("VBoxSeamlessInit\n"));
     50    gCtx.pEnv = pEnv;
    4251
    4352    /* Will fail if SetWinEventHook is not present (version < NT4 SP6 apparently) */
    44     hModule = LoadLibrary(VBOXHOOK_DLL_NAME);
    45     if (hModule)
    46     {
    47         *(uintptr_t *)&pfnVBoxInstallHook = (uintptr_t)GetProcAddress(hModule, "VBoxInstallHook");
    48         *(uintptr_t *)&pfnVBoxRemoveHook  = (uintptr_t)GetProcAddress(hModule, "VBoxRemoveHook");
    49     }
    50     else
    51         dprintf(("VBoxSeamlessInit LoadLibrary failed with %d\n", GetLastError()));
    52 
    53     if (pfnVBoxInstallHook)
    54     {
     53    gCtx.hModule = LoadLibrary(VBOXHOOK_DLL_NAME);
     54    if (gCtx.hModule)
     55    {
     56        *(uintptr_t *)&gCtx.pfnVBoxInstallHook = (uintptr_t)GetProcAddress(gCtx.hModule, "VBoxInstallHook");
     57        *(uintptr_t *)&gCtx.pfnVBoxRemoveHook  = (uintptr_t)GetProcAddress(gCtx.hModule, "VBoxRemoveHook");
     58
    5559        /* inform the host that we support the seamless window mode */
    5660        VMMDevReqGuestCapabilities vmmreqGuestCaps = {0};
     
    6670        }
    6771
    68         pfnVBoxInstallHook(hModule);
    69     }
     72        *pfStartThread = true;
     73        *ppInstance = &gCtx;
     74        return VINF_SUCCESS;
     75    }
     76    else
     77    {
     78        dprintf(("VBoxSeamlessInit LoadLibrary failed with %d\n", GetLastError()));
     79        return VERR_INVALID_PARAMETER;
     80    }
     81
    7082    return VINF_SUCCESS;
    7183}
     
    8698        dprintf(("VMMDevReq_ReportGuestCapabilities: error doing IOCTL, last error: %d\n", GetLastError()));
    8799    }
    88     if (pfnVBoxRemoveHook)
    89         pfnVBoxRemoveHook();
    90 
    91     FreeLibrary(hModule);
     100
     101    if (gCtx.pfnVBoxRemoveHook)
     102        gCtx.pfnVBoxRemoveHook();
     103    if (gCtx.hModule)
     104        FreeLibrary(gCtx.hModule);
     105    gCtx.hModule = 0;
    92106    return;
    93107}
     108
     109/**
     110 * Thread function to wait for and process seamless mode change
     111 * requests
     112 */
     113unsigned __stdcall VBoxSeamlessThread(void *pInstance)
     114{
     115    VBOXSEAMLESSCONTEXT *pCtx = (VBOXSEAMLESSCONTEXT *)pInstance;
     116    HANDLE gVBoxDriver = pCtx->pEnv->hDriver;
     117    bool fTerminate = false;
     118    VBoxGuestFilterMaskInfo maskInfo;
     119    DWORD cbReturned;
     120
     121    maskInfo.u32OrMask = VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST;
     122    maskInfo.u32NotMask = 0;
     123    if (DeviceIoControl (gVBoxDriver, IOCTL_VBOXGUEST_CTL_FILTER_MASK, &maskInfo, sizeof (maskInfo), NULL, 0, &cbReturned, NULL))
     124    {
     125        dprintf(("VBoxService: DeviceIOControl(CtlMask - or) succeeded\n"));
     126    }
     127    else
     128    {
     129        dprintf(("VBoxService: DeviceIOControl(CtlMask) failed, SeamlessChangeThread exited\n"));
     130        return 0;
     131    }
     132
     133    do
     134    {
     135        /* wait for a seamless change event */
     136        VBoxGuestWaitEventInfo waitEvent;
     137        waitEvent.u32TimeoutIn = 1000;
     138        waitEvent.u32EventMaskIn = VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST;
     139        if (DeviceIoControl(gVBoxDriver, IOCTL_VBOXGUEST_WAITEVENT, &waitEvent, sizeof(waitEvent), &waitEvent, sizeof(waitEvent), &cbReturned, NULL))
     140        {
     141            dprintf(("VBoxService: DeviceIOControl succeded\n"));
     142
     143            /* are we supposed to stop? */
     144            if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 0) == WAIT_OBJECT_0)
     145                break;
     146
     147            dprintf(("VBoxService: checking event\n"));
     148
     149            /* did we get the right event? */
     150            if (waitEvent.u32EventFlagsOut & VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST)
     151            {
     152                dprintf(("VBoxService: going to get seamless change information.\n"));
     153
     154                /* We got at least one event. Read the requested resolution
     155                 * and try to set it until success. New events will not be seen
     156                 * but a new resolution will be read in this poll loop.
     157                 */
     158                for (;;)
     159                {
     160                    /* get the seamless change request */
     161                    VMMDevSeamlessChangeRequest seamlessChangeRequest = {0};
     162                    vmmdevInitRequest((VMMDevRequestHeader*)&seamlessChangeRequest, VMMDevReq_GetSeamlessChangeRequest);
     163                    seamlessChangeRequest.eventAck = VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST;
     164
     165                    BOOL fSeamlessChangeQueried = DeviceIoControl(gVBoxDriver, IOCTL_VBOXGUEST_VMMREQUEST, &seamlessChangeRequest, sizeof(seamlessChangeRequest),
     166                                                                 &seamlessChangeRequest, sizeof(seamlessChangeRequest), &cbReturned, NULL);
     167                    if (fSeamlessChangeQueried)
     168                    {
     169                        dprintf(("VBoxSeamlessThread: mode change to %d\n", seamlessChangeRequest.mode));
     170
     171                        switch(seamlessChangeRequest.mode)
     172                        {
     173                        case VMMDev_Seamless_Disabled:
     174                            if (pCtx->pfnVBoxInstallHook)
     175                                pCtx->pfnVBoxInstallHook(pCtx->hModule);
     176                            break;
     177
     178                        case VMMDev_Seamless_Visible_Region:
     179                            if (pCtx->pfnVBoxRemoveHook)
     180                                pCtx->pfnVBoxRemoveHook();
     181                            break;
     182
     183                        case VMMDev_Seamless_Host_Window:
     184                            break;
     185
     186                        default:
     187                            AssertFailed();
     188                            break;
     189                        }
     190
     191                        /* Retry the change a bit later. */
     192                        /* are we supposed to stop? */
     193                        if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 1000) == WAIT_OBJECT_0)
     194                        {
     195                            fTerminate = true;
     196                            break;
     197                        }
     198                    }
     199                    else
     200                    {
     201                        dprintf(("VBoxSeamlessThread: error from DeviceIoControl IOCTL_VBOXGUEST_VMMREQUEST\n"));
     202                        /* sleep a bit to not eat too much CPU while retrying */
     203                        /* are we supposed to stop? */
     204                        if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 50) == WAIT_OBJECT_0)
     205                        {
     206                            fTerminate = true;
     207                            break;
     208                        }
     209                    }
     210                }
     211            }
     212        }
     213        else
     214        {
     215            dprintf(("VBoxService: error 0 from DeviceIoControl IOCTL_VBOXGUEST_WAITEVENT\n"));
     216            /* sleep a bit to not eat too much CPU in case the above call always fails */
     217            if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 10) == WAIT_OBJECT_0)
     218            {
     219                fTerminate = true;
     220                break;
     221            }
     222        }
     223    }
     224    while (!fTerminate);
     225
     226    maskInfo.u32OrMask = 0;
     227    maskInfo.u32NotMask = VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST;
     228    if (DeviceIoControl (gVBoxDriver, IOCTL_VBOXGUEST_CTL_FILTER_MASK, &maskInfo, sizeof (maskInfo), NULL, 0, &cbReturned, NULL))
     229    {
     230        dprintf(("VBoxSeamlessThread: DeviceIOControl(CtlMask - not) succeeded\n"));
     231    }
     232    else
     233    {
     234        dprintf(("VBoxSeamlessThread: DeviceIOControl(CtlMask) failed\n"));
     235    }
     236
     237    dprintf(("VBoxSeamlessThread: finished seamless change request thread\n"));
     238    return 0;
     239}
  • trunk/src/VBox/Additions/WINNT/VBoxService/VBoxService.cpp

    r3739 r3789  
    7777/* The seamless windows service prototypes */
    7878int                VBoxSeamlessInit     (const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread);
     79unsigned __stdcall VBoxSeamlessThread   (void *pInstance);
    7980void               VBoxSeamlessDestroy  (const VBOXSERVICEENV *pEnv, void *pInstance);
    8081
     
    9192        "Seamless Windows",
    9293        VBoxSeamlessInit,
    93         NULL,
     94        VBoxSeamlessThread,
    9495        VBoxSeamlessDestroy
    9596    },
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette