VirtualBox

Changeset 57741 in vbox for trunk


Ignore:
Timestamp:
Sep 14, 2015 3:24:42 PM (9 years ago)
Author:
vboxsync
Message:

Additions/VBoxTray:

  • Refactored internal services to use the RTThread API.
  • First take on cleaning up VBoxTray, separating the services more and more. See @todos.
  • Updated some code areas where deprecated APIs were used.
  • A lot of log formatting fixes and renaming.
Location:
trunk/src/VBox/Additions/WINNT/VBoxTray
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp

    r55401 r57741  
    77
    88/*
    9  * Copyright (C) 2006-2014 Oracle Corporation
     9 * Copyright (C) 2006-2015 Oracle Corporation
    1010 *
    1111 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2121#include "VBoxHelpers.h"
    2222
     23#include <iprt/asm.h>
     24
    2325#include <VBox/HostServices/VBoxClipboardSvc.h>
    2426#include <strsafe.h>
     
    2729#ifdef DEBUG
    2830# define LOG_ENABLED
    29 # define LOG_GROUP LOG_GROUP_DEFAULT
     31# define LOG_GROUP LOG_GROUP_SHARED_CLIPBOARD
    3032#endif
    3133#include <VBox/log.h>
     
    3638{
    3739    const VBOXSERVICEENV *pEnv;
    38 
    39     uint32_t u32ClientID;
    40 
    41     ATOM     atomWindowClass;
    42 
    43     HWND     hwnd;
    44 
    45     HWND     hwndNextInChain;
    46 
    47     UINT     timerRefresh;
    48 
    49     bool     fCBChainPingInProcess;
    50 
    51 //    bool     fOperational;
    52 
    53 //    uint32_t u32LastSentFormat;
    54 //    uint64_t u64LastSentCRC64;
    55 
    56 } VBOXCLIPBOARDCONTEXT;
    57 
    58 static char gachWindowClassName[] = "VBoxSharedClipboardClass";
     40    uint32_t              u32ClientID;
     41    ATOM                  wndClass;
     42    HWND                  hwnd;
     43    HWND                  hwndNextInChain;
     44    UINT                  timerRefresh;
     45    bool                  fCBChainPingInProcess;
     46} VBOXCLIPBOARDCONTEXT, *PVBOXCLIPBOARDCONTEXT;
     47
     48/** Static since it is the single instance. Directly used in the windows proc. */
     49static VBOXCLIPBOARDCONTEXT g_Ctx = { NULL };
     50
     51static char s_szClipWndClassName[] = "VBoxSharedClipboardClass";
    5952
    6053enum { CBCHAIN_TIMEOUT = 5000 /* ms */ };
    6154
    62 static int vboxClipboardChanged(VBOXCLIPBOARDCONTEXT *pCtx)
     55static int vboxClipboardChanged(PVBOXCLIPBOARDCONTEXT pCtx)
    6356{
    6457    AssertPtr(pCtx);
     
    7568        UINT format = 0;
    7669
    77         while ((format = EnumClipboardFormats (format)) != 0)
     70        while ((format = EnumClipboardFormats(format)) != 0)
    7871        {
    7972            LogFlowFunc(("vboxClipboardChanged: format = 0x%08X\n", format));
     
    9184
    9285                default:
     86                {
    9387                    if (format >= 0xC000)
    9488                    {
     
    10599                    }
    106100                    break;
     101                }
    107102            }
    108103        }
    109104
    110         CloseClipboard ();
     105        CloseClipboard();
    111106        rc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, u32Formats);
    112107    }
     
    115110
    116111/* Add ourselves into the chain of cliboard listeners */
    117 static void addToCBChain (VBOXCLIPBOARDCONTEXT *pCtx)
    118 {
    119     pCtx->hwndNextInChain = SetClipboardViewer (pCtx->hwnd);
     112static void vboxClipboardAddToCBChain(PVBOXCLIPBOARDCONTEXT pCtx)
     113{
     114    AssertPtrReturnVoid(pCtx);
     115    pCtx->hwndNextInChain = SetClipboardViewer(pCtx->hwnd);
     116    /** @todo r=andy Return code?? */
    120117}
    121118
    122119/* Remove ourselves from the chain of cliboard listeners */
    123 static void removeFromCBChain (VBOXCLIPBOARDCONTEXT *pCtx)
    124 {
    125     ChangeClipboardChain (pCtx->hwnd, pCtx->hwndNextInChain);
     120static void vboxClipboardRemoveFromCBChain(PVBOXCLIPBOARDCONTEXT pCtx)
     121{
     122    AssertPtrReturnVoid(pCtx);
     123
     124    ChangeClipboardChain(pCtx->hwnd, pCtx->hwndNextInChain);
    126125    pCtx->hwndNextInChain = NULL;
     126    /** @todo r=andy Return code?? */
    127127}
    128128
     
    131131 * There is a race if a ping returns after the next one is initiated, but nothing
    132132 * very bad is likely to happen. */
    133 VOID CALLBACK CBChainPingProc(HWND hwnd, UINT uMsg, ULONG_PTR dwData, LRESULT lResult)
    134 {
    135     (void) hwnd;
    136     (void) uMsg;
    137     (void) lResult;
    138     VBOXCLIPBOARDCONTEXT *pCtx = (VBOXCLIPBOARDCONTEXT *)dwData;
     133VOID CALLBACK vboxClipboardChainPingProc(HWND hWnd, UINT uMsg, ULONG_PTR dwData, LRESULT lResult)
     134{
     135    NOREF(hWnd);
     136    NOREF(uMsg);
     137    NOREF(lResult);
     138
     139    /** @todo r=andy Why not using SetWindowLongPtr for keeping the context? */
     140    PVBOXCLIPBOARDCONTEXT pCtx = (PVBOXCLIPBOARDCONTEXT)dwData;
     141    AssertPtr(pCtx);
     142
    139143    pCtx->fCBChainPingInProcess = FALSE;
    140144}
    141145
    142 static LRESULT vboxClipboardProcessMsg(VBOXCLIPBOARDCONTEXT *pCtx, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    143 {
     146static LRESULT vboxClipboardProcessMsg(PVBOXCLIPBOARDCONTEXT pCtx, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
     147{
     148    AssertPtr(pCtx);
     149
    144150    LRESULT rc = 0;
    145151
     
    197203            if (!hViewer || pCtx->fCBChainPingInProcess)
    198204            {
    199                 removeFromCBChain(pCtx);
    200                 addToCBChain(pCtx);
     205                vboxClipboardRemoveFromCBChain(pCtx);
     206                vboxClipboardAddToCBChain(pCtx);
    201207            }
    202208            /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be
     
    205211            hViewer = GetClipboardViewer();
    206212            if (hViewer)
    207                 SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pCtx->hwndNextInChain, (LPARAM)pCtx->hwndNextInChain, CBChainPingProc, (ULONG_PTR) pCtx);
     213                SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pCtx->hwndNextInChain, (LPARAM)pCtx->hwndNextInChain, vboxClipboardChainPingProc, (ULONG_PTR) pCtx);
    208214        } break;
    209215
     
    541547}
    542548
    543 static LRESULT CALLBACK vboxClipboardWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
    544 
    545 static int vboxClipboardInit (VBOXCLIPBOARDCONTEXT *pCtx)
    546 {
     549static LRESULT CALLBACK vboxClipboardWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
     550
     551static int vboxClipboardCreateWindow(PVBOXCLIPBOARDCONTEXT pCtx)
     552{
     553    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
     554
     555    int rc = VINF_SUCCESS;
     556
     557    AssertPtr(pCtx->pEnv);
     558    HINSTANCE hInstance = pCtx->pEnv->hInstance;
     559    Assert(hInstance != 0);
     560
    547561    /* Register the Window Class. */
    548     WNDCLASS wc;
    549 
    550     wc.style         = CS_NOCLOSE;
    551     wc.lpfnWndProc   = vboxClipboardWndProc;
    552     wc.cbClsExtra    = 0;
    553     wc.cbWndExtra    = 0;
    554     wc.hInstance     = pCtx->pEnv->hInstance;
    555     wc.hIcon         = NULL;
    556     wc.hCursor       = NULL;
    557     wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
    558     wc.lpszMenuName  = NULL;
    559     wc.lpszClassName = gachWindowClassName;
    560 
    561     pCtx->atomWindowClass = RegisterClass (&wc);
    562 
    563     int rc = VINF_SUCCESS;
    564     if (pCtx->atomWindowClass == 0)
    565     {
    566         rc = VERR_NOT_SUPPORTED;
    567     }
    568     else
     562    WNDCLASSEX wc = { 0 };
     563    wc.cbSize     = sizeof(WNDCLASSEX);
     564
     565    if (!GetClassInfoEx(hInstance, s_szClipWndClassName, &wc))
     566    {
     567        wc.style         = CS_NOCLOSE;
     568        wc.lpfnWndProc   = vboxClipboardWndProc;
     569        wc.hInstance     = pCtx->pEnv->hInstance;
     570        wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
     571        wc.lpszClassName = s_szClipWndClassName;
     572
     573        pCtx->wndClass = RegisterClassEx(&wc);
     574        if (pCtx->wndClass == 0)
     575            rc = RTErrConvertFromWin32(GetLastError());
     576    }
     577
     578    if (RT_SUCCESS(rc))
    569579    {
    570580        /* Create the window. */
    571         pCtx->hwnd = CreateWindowEx (WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,
    572                                      gachWindowClassName, gachWindowClassName,
    573                                      WS_POPUPWINDOW,
    574                                      -200, -200, 100, 100, NULL, NULL, pCtx->pEnv->hInstance, NULL);
    575 
     581        pCtx->hwnd = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,
     582                                    s_szClipWndClassName, s_szClipWndClassName,
     583                                    WS_POPUPWINDOW,
     584                                    -200, -200, 100, 100, NULL, NULL, hInstance, NULL);
    576585        if (pCtx->hwnd == NULL)
    577586        {
     
    583592                         SWP_NOACTIVATE | SWP_HIDEWINDOW | SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_NOSIZE);
    584593
    585             addToCBChain(pCtx);
     594            vboxClipboardAddToCBChain(pCtx);
    586595            pCtx->timerRefresh = SetTimer(pCtx->hwnd, 0, 10 * 1000, NULL);
    587596        }
    588597    }
    589598
    590     LogFlowFunc(("vboxClipboardInit returned with rc = %Rrc\n", rc));
     599    LogFlowFuncLeaveRC(rc);
    591600    return rc;
    592601}
    593602
    594 static void vboxClipboardDestroy(VBOXCLIPBOARDCONTEXT *pCtx)
    595 {
     603static void vboxClipboardDestroy(PVBOXCLIPBOARDCONTEXT pCtx)
     604{
     605    AssertPtrReturnVoid(pCtx);
     606
    596607    if (pCtx->hwnd)
    597608    {
    598         removeFromCBChain(pCtx);
     609        vboxClipboardRemoveFromCBChain(pCtx);
    599610        if (pCtx->timerRefresh)
    600611            KillTimer(pCtx->hwnd, 0);
    601612
    602         DestroyWindow (pCtx->hwnd);
     613        DestroyWindow(pCtx->hwnd);
    603614        pCtx->hwnd = NULL;
    604615    }
    605616
    606     if (pCtx->atomWindowClass != 0)
    607     {
    608         UnregisterClass(gachWindowClassName, pCtx->pEnv->hInstance);
    609         pCtx->atomWindowClass = 0;
    610     }
    611 }
    612 
    613 /* Static since it is the single instance. Directly used in the windows proc. */
    614 static VBOXCLIPBOARDCONTEXT gCtx = { NULL };
    615 
    616 static LRESULT CALLBACK vboxClipboardWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    617 {
     617    if (pCtx->wndClass != 0)
     618    {
     619        UnregisterClass(s_szClipWndClassName, pCtx->pEnv->hInstance);
     620        pCtx->wndClass = 0;
     621    }
     622}
     623
     624static LRESULT CALLBACK vboxClipboardWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
     625{
     626    PVBOXCLIPBOARDCONTEXT pCtx = &g_Ctx; /** @todo r=andy Make pCtx available through SetWindowLongPtr() / GWL_USERDATA. */
     627    AssertPtr(pCtx);
     628
    618629    /* Forward with proper context. */
    619     return vboxClipboardProcessMsg(&gCtx, hwnd, msg, wParam, lParam);
    620 }
    621 
    622 int VBoxClipboardInit(const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread)
    623 {
    624     LogFlowFunc(("VBoxClipboardInit\n"));
    625     if (gCtx.pEnv)
     630    return vboxClipboardProcessMsg(pCtx, hWnd, uMsg, wParam, lParam);
     631}
     632
     633DECLCALLBACK(int) VBoxClipboardInit(const PVBOXSERVICEENV pEnv, void **ppInstance)
     634{
     635    LogFlowFuncEnter();
     636
     637    PVBOXCLIPBOARDCONTEXT pCtx = &g_Ctx; /* Only one instance for now. */
     638    AssertPtr(pCtx);
     639
     640    if (pCtx->pEnv)
    626641    {
    627642        /* Clipboard was already initialized. 2 or more instances are not supported. */
     
    632647    {
    633648        /* Do not use clipboard for remote sessions. */
    634         LogRel(("VBoxTray: clipboard has been disabled for a remote session.\n"));
     649        LogRel(("Clipboard: Clipboard has been disabled for a remote session\n"));
    635650        return VERR_NOT_SUPPORTED;
    636651    }
    637652
    638     RT_ZERO (gCtx);
    639     gCtx.pEnv = pEnv;
    640 
    641     int rc = VbglR3ClipboardConnect(&gCtx.u32ClientID);
    642     if (RT_SUCCESS (rc))
    643     {
    644         rc = vboxClipboardInit(&gCtx);
    645         if (RT_SUCCESS (rc))
    646         {
    647             /* Always start the thread for host messages. */
    648             *pfStartThread = true;
     653    RT_BZERO(pCtx, sizeof(VBOXCLIPBOARDCONTEXT));
     654    pCtx->pEnv = pEnv;
     655
     656    int rc = VbglR3ClipboardConnect(&pCtx->u32ClientID);
     657    if (RT_SUCCESS(rc))
     658    {
     659        rc = vboxClipboardCreateWindow(pCtx);
     660        if (RT_SUCCESS(rc))
     661        {
     662            *ppInstance = pCtx;
    649663        }
    650664        else
    651665        {
    652             VbglR3ClipboardDisconnect(gCtx.u32ClientID);
     666            VbglR3ClipboardDisconnect(pCtx->u32ClientID);
    653667        }
    654668    }
    655669
    656     if (RT_SUCCESS(rc))
    657         *ppInstance = &gCtx;
     670    LogFlowFuncLeaveRC(rc);
    658671    return rc;
    659672}
    660673
    661 unsigned __stdcall VBoxClipboardThread(void *pInstance)
    662 {
    663     LogFlowFunc(("VBoxClipboardThread\n"));
    664 
    665     VBOXCLIPBOARDCONTEXT *pCtx = (VBOXCLIPBOARDCONTEXT *)pInstance;
     674DECLCALLBACK(int) VBoxClipboardWorker(void *pInstance, bool volatile *pfShutdown)
     675{
     676    AssertPtr(pInstance);
     677    LogFlowFunc(("pInstance=%p\n", pInstance));
     678
     679    /*
     680     * Tell the control thread that it can continue
     681     * spawning services.
     682     */
     683    RTThreadUserSignal(RTThreadSelf());
     684
     685    PVBOXCLIPBOARDCONTEXT pCtx = (PVBOXCLIPBOARDCONTEXT)pInstance;
    666686    AssertPtr(pCtx);
     687
     688    int rc;
    667689
    668690    /* The thread waits for incoming messages from the host. */
     
    671693        uint32_t u32Msg;
    672694        uint32_t u32Formats;
    673         int rc = VbglR3ClipboardGetHostMsg(pCtx->u32ClientID, &u32Msg, &u32Formats);
     695        rc = VbglR3ClipboardGetHostMsg(pCtx->u32ClientID, &u32Msg, &u32Formats);
    674696        if (RT_FAILURE(rc))
    675697        {
    676             LogFlowFunc(("VBoxClipboardThread: Failed to call the driver for host message! rc = %Rrc\n", rc));
    677698            if (rc == VERR_INTERRUPTED)
    678             {
    679                 /* Wait for termination event. */
    680                 WaitForSingleObject(pCtx->pEnv->hStopEvent, INFINITE);
    681699                break;
    682             }
     700
     701            LogFlowFunc(("Error getting host message, rc=%Rrc\n", rc));
     702
     703            if (*pfShutdown)
     704                break;
     705
    683706            /* Wait a bit before retrying. */
    684             AssertPtr(pCtx->pEnv);
    685             if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 1000) == WAIT_OBJECT_0)
    686             {
    687                 break;
    688             }
     707            RTThreadSleep(1000);
    689708            continue;
    690709        }
    691710        else
    692711        {
    693             LogFlowFunc(("VBoxClipboardThread: VbglR3ClipboardGetHostMsg u32Msg = %ld, u32Formats = %ld\n", u32Msg, u32Formats));
     712            LogFlowFunc(("u32Msg=%RU32, u32Formats=0x%x\n", u32Msg, u32Formats));
    694713            switch (u32Msg)
    695714            {
     715                /** @todo r=andy Use a #define for WM_USER (+1). */
    696716                case VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS:
    697717                {
     
    699719                     * Forward the information to the window, so it can later
    700720                     * respond to WM_RENDERFORMAT message. */
    701                     ::PostMessage (pCtx->hwnd, WM_USER, 0, u32Formats);
     721                    ::PostMessage(pCtx->hwnd, WM_USER, 0, u32Formats);
    702722                } break;
    703723
     
    705725                {
    706726                    /* The host needs data in the specified format. */
    707                     ::PostMessage (pCtx->hwnd, WM_USER + 1, 0, u32Formats);
     727                    ::PostMessage(pCtx->hwnd, WM_USER + 1, 0, u32Formats);
    708728                } break;
    709729
     
    711731                {
    712732                    /* The host is terminating. */
    713                     rc = VERR_INTERRUPTED;
     733                    LogRel(("Clipboard: Terminating ...\n"));
     734                    ASMAtomicXchgBool(pfShutdown, true);
    714735                } break;
    715736
    716737                default:
    717738                {
    718                     LogFlowFunc(("VBoxClipboardThread: Unsupported message from host! Message = %ld\n", u32Msg));
    719                 }
     739                    LogFlowFunc(("Unsupported message from host, message=%RU32\n", u32Msg));
     740
     741                    /* Wait a bit before retrying. */
     742                    RTThreadSleep(1000);
     743                } break;
    720744            }
    721745        }
    722     }
    723     return 0;
    724 }
    725 
    726 void VBoxClipboardDestroy(const VBOXSERVICEENV *pEnv, void *pInstance)
    727 {
    728     VBOXCLIPBOARDCONTEXT *pCtx = (VBOXCLIPBOARDCONTEXT *)pInstance;
    729     if (pCtx != &gCtx)
    730     {
    731         LogFlowFunc(("VBoxClipboardDestroy: invalid instance %p (our = %p)!\n", pCtx, &gCtx));
    732         pCtx = &gCtx;
    733     }
    734 
    735     vboxClipboardDestroy (pCtx);
     746
     747        if (*pfShutdown)
     748            break;
     749    }
     750
     751    LogFlowFuncLeaveRC(rc);
     752    return rc;
     753}
     754
     755DECLCALLBACK(int) VBoxClipboardStop(void *pInstance)
     756{
     757    AssertPtrReturn(pInstance, VERR_INVALID_POINTER);
     758
     759    LogFunc(("Stopping pInstance=%p\n", pInstance));
     760
     761    PVBOXCLIPBOARDCONTEXT pCtx = (PVBOXCLIPBOARDCONTEXT)pInstance;
     762    AssertPtr(pCtx);
     763
    736764    VbglR3ClipboardDisconnect(pCtx->u32ClientID);
    737     memset (pCtx, 0, sizeof (*pCtx));
     765    pCtx->u32ClientID = 0;
     766
     767    LogFlowFuncLeaveRC(VINF_SUCCESS);
     768    return VINF_SUCCESS;
     769}
     770
     771DECLCALLBACK(void) VBoxClipboardDestroy(void *pInstance)
     772{
     773    AssertPtrReturnVoid(pInstance);
     774
     775    PVBOXCLIPBOARDCONTEXT pCtx = (PVBOXCLIPBOARDCONTEXT)pInstance;
     776    AssertPtr(pCtx);
     777
     778    /* Make sure that we are disconnected. */
     779    Assert(pCtx->u32ClientID == 0);
     780
     781    vboxClipboardDestroy(pCtx);
     782    RT_BZERO(pCtx, sizeof(VBOXCLIPBOARDCONTEXT));
     783
    738784    return;
    739785}
    740786
     787/**
     788 * The service description.
     789 */
     790VBOXSERVICEDESC g_SvcDescClipboard =
     791{
     792    /* pszName. */
     793    "clipboard",
     794    /* pszDescription. */
     795    "Shared Clipboard",
     796    /* methods */
     797    VBoxClipboardInit,
     798    VBoxClipboardWorker,
     799    VBoxClipboardStop,
     800    VBoxClipboardDestroy
     801};
     802
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.h

    r55401 r57741  
    55
    66/*
    7  * Copyright (C) 2006-2010 Oracle Corporation
     7 * Copyright (C) 2006-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1919#define __VBOXSERVICESHAREDCLIPLBOARD__H
    2020
    21 /* The shared clipboard service prototypes. */
    22 int                VBoxClipboardInit    (const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread);
    23 unsigned __stdcall VBoxClipboardThread  (void *pInstance);
    24 void               VBoxClipboardDestroy (const VBOXSERVICEENV *pEnv, void *pInstance);
     21#endif /* __VBOXSERVICESHAREDCLIPLBOARD__H */
    2522
    26 
    27 #endif /* __VBOXSERVICESHAREDCLIPLBOARD__H */
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDispIf.cpp

    r55401 r57741  
    5353} VBOXDISPIF_OP;
    5454
    55 DWORD EnableAndResizeDispDev(DEVMODE *paDeviceModes, DISPLAY_DEVICE *paDisplayDevices, DWORD totalDispNum, UINT Id, DWORD aWidth, DWORD aHeight,
    56                                     DWORD aBitsPerPixel, LONG aPosX, LONG aPosY, BOOL fEnabled, BOOL fExtDispSup);
    57 
    5855static DWORD vboxDispIfWddmResizeDisplay(PCVBOXDISPIF const pIf, UINT Id, BOOL fEnable, DISPLAY_DEVICE * paDisplayDevices, DEVMODE *paDeviceMode, UINT devModes);
    59 
    6056static DWORD vboxDispIfResizePerform(PCVBOXDISPIF const pIf, UINT iChangedMode, BOOL fEnable, BOOL fExtDispSup, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes);
    61 
    6257static DWORD vboxDispIfWddmEnableDisplaysTryingTopology(PCVBOXDISPIF const pIf, UINT cIds, UINT *pIds, BOOL fEnable);
    63 
    6458static DWORD vboxDispIfResizeStartedWDDMOp(VBOXDISPIF_OP *pOp);
    6559
    66 /* APIs specific to win7 and above WDDM architecture. Not available for Vista WDDM.
    67  * This is the reason they have not been put in the VBOXDISPIF struct in VBoxDispIf.h
     60/*
     61 * APIs specific to Win7 and above WDDM architecture. Not available for Vista WDDM.
     62 * This is the reason they have not been put in the VBOXDISPIF struct in VBoxDispIf.h.
    6863 */
    6964typedef struct _VBOXDISPLAYWDDMAPICONTEXT
     
    961956{
    962957    HRESULT hr = S_OK;
     958
     959    /** @todo r=andy Use VBOXSERVICEENV::hInstance. */
    963960    HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
     961
    964962    /* Register the Window Class. */
    965     WNDCLASS wc;
    966     if (!GetClassInfo(hInstance, VBOXRRWND_NAME, &wc))
    967     {
    968         wc.style = 0;//CS_OWNDC;
    969         wc.lpfnWndProc = vboxRrWndProc;
    970         wc.cbClsExtra = 0;
    971         wc.cbWndExtra = 0;
    972         wc.hInstance = hInstance;
    973         wc.hIcon = NULL;
    974         wc.hCursor = NULL;
    975         wc.hbrBackground = NULL;
    976         wc.lpszMenuName = NULL;
     963    WNDCLASSEX wc = { 0 };
     964    wc.cbSize     = sizeof(WNDCLASSEX);
     965
     966    if (!GetClassInfoEx(hInstance, VBOXRRWND_NAME, &wc))
     967    {
     968        wc.lpfnWndProc   = vboxRrWndProc;
     969        wc.hInstance     = hInstance;
    977970        wc.lpszClassName = VBOXRRWND_NAME;
    978         if (!RegisterClass(&wc))
     971
     972        if (!RegisterClassEx(&wc))
    979973        {
    980974            DWORD winErr = GetLastError();
     
    17901784static DWORD vboxDispIfResizeStartedWDDMOp(VBOXDISPIF_OP *pOp)
    17911785{
    1792     DWORD NumDevices = VBoxGetDisplayConfigCount();
     1786    DWORD NumDevices = VBoxDisplayGetCount();
    17931787    if (NumDevices == 0)
    17941788    {
     
    18021796    DWORD DevPrimaryNum = 0;
    18031797
    1804     DWORD winEr = VBoxGetDisplayConfig(NumDevices, &DevPrimaryNum, &DevNum, paDisplayDevices, paDeviceModes);
     1798    DWORD winEr = VBoxDisplayGetConfig(NumDevices, &DevPrimaryNum, &DevNum, paDisplayDevices, paDeviceModes);
    18051799    if (winEr != NO_ERROR)
    18061800    {
     
    18311825        WARN(("VBoxTray: vboxDispIfResizeStartedWDDMOp: vboxDispIfWaitDisplayDataInited failed winEr 0x%x\n", winEr));
    18321826
    1833     DWORD NewNumDevices = VBoxGetDisplayConfigCount();
     1827    DWORD NewNumDevices = VBoxDisplayGetCount();
    18341828    if (NewNumDevices == 0)
    18351829    {
     
    18461840    DWORD NewDevPrimaryNum = 0;
    18471841
    1848     winEr = VBoxGetDisplayConfig(NewNumDevices, &NewDevPrimaryNum, &NewDevNum, paNewDisplayDevices, paNewDeviceModes);
     1842    winEr = VBoxDisplayGetConfig(NewNumDevices, &NewDevPrimaryNum, &NewDevNum, paNewDisplayDevices, paNewDeviceModes);
    18491843    if (winEr != NO_ERROR)
    18501844    {
     
    19451939{
    19461940    DWORD err = NO_ERROR;
    1947     AssertBreakpoint();
     1941
    19481942    OSVERSIONINFO OSinfo;
    1949     OSinfo.dwOSVersionInfoSize = sizeof (OSinfo);
     1943    OSinfo.dwOSVersionInfoSize = sizeof(OSinfo);
    19501944    GetVersionEx (&OSinfo);
    19511945    if (OSinfo.dwMajorVersion >= 5)
     
    20592053}
    20602054
    2061 static DWORD vboxDispIfSeamlesCreateWDDM(PCVBOXDISPIF const pIf, VBOXDISPIF_SEAMLESS *pSeamless, HANDLE hEvent)
     2055static DWORD vboxDispIfSeamlessCreateWDDM(PCVBOXDISPIF const pIf, VBOXDISPIF_SEAMLESS *pSeamless, HANDLE hEvent)
    20622056{
    20632057    HRESULT hr = vboxDispKmtOpenAdapter(&pIf->modeData.wddm.KmtCallbacks, &pSeamless->modeData.wddm.Adapter);
     
    20892083}
    20902084
    2091 static DWORD vboxDispIfSeamlesTermWDDM(VBOXDISPIF_SEAMLESS *pSeamless)
     2085static DWORD vboxDispIfSeamlessTermWDDM(VBOXDISPIF_SEAMLESS *pSeamless)
    20922086{
    20932087#ifdef VBOX_DISPIF_WITH_OPCONTEXT
     
    21002094}
    21012095
    2102 static DWORD vboxDispIfSeamlesSubmitWDDM(VBOXDISPIF_SEAMLESS *pSeamless, VBOXDISPIFESCAPE *pData, int cbData)
     2096static DWORD vboxDispIfSeamlessSubmitWDDM(VBOXDISPIF_SEAMLESS *pSeamless, VBOXDISPIFESCAPE *pData, int cbData)
    21032097{
    21042098    D3DKMT_ESCAPE EscapeData = {0};
     
    21212115}
    21222116
    2123 DWORD VBoxDispIfSeamlesCreate(PCVBOXDISPIF const pIf, VBOXDISPIF_SEAMLESS *pSeamless, HANDLE hEvent)
     2117DWORD VBoxDispIfSeamlessCreate(PCVBOXDISPIF const pIf, VBOXDISPIF_SEAMLESS *pSeamless, HANDLE hEvent)
    21242118{
    21252119    memset(pSeamless, 0, sizeof (*pSeamless));
     
    21342128        case VBOXDISPIF_MODE_WDDM:
    21352129        case VBOXDISPIF_MODE_WDDM_W7:
    2136             return vboxDispIfSeamlesCreateWDDM(pIf, pSeamless, hEvent);
     2130            return vboxDispIfSeamlessCreateWDDM(pIf, pSeamless, hEvent);
    21372131#endif
    21382132        default:
    2139             WARN(("VBoxTray: VBoxDispIfSeamlesCreate: invalid mode %d\n", pIf->enmMode));
    2140             return ERROR_INVALID_PARAMETER;
    2141     }
    2142 }
    2143 
    2144 DWORD VBoxDispIfSeamlesTerm(VBOXDISPIF_SEAMLESS *pSeamless)
     2133            break;
     2134    }
     2135
     2136    WARN(("VBoxTray: VBoxDispIfSeamlessCreate: invalid mode %d\n", pIf->enmMode));
     2137    return ERROR_INVALID_PARAMETER;
     2138}
     2139
     2140DWORD VBoxDispIfSeamlessTerm(VBOXDISPIF_SEAMLESS *pSeamless)
    21452141{
    21462142    PCVBOXDISPIF const pIf = pSeamless->pIf;
     
    21552151        case VBOXDISPIF_MODE_WDDM:
    21562152        case VBOXDISPIF_MODE_WDDM_W7:
    2157             winEr = vboxDispIfSeamlesTermWDDM(pSeamless);
     2153            winEr = vboxDispIfSeamlessTermWDDM(pSeamless);
    21582154            break;
    21592155#endif
    21602156        default:
    2161             WARN(("VBoxTray: VBoxDispIfSeamlesTerm: invalid mode %d\n", pIf->enmMode));
     2157            WARN(("VBoxTray: VBoxDispIfSeamlessTerm: invalid mode %d\n", pIf->enmMode));
    21622158            winEr = ERROR_INVALID_PARAMETER;
    21632159            break;
     
    21702166}
    21712167
    2172 DWORD VBoxDispIfSeamlesSubmit(VBOXDISPIF_SEAMLESS *pSeamless, VBOXDISPIFESCAPE *pData, int cbData)
     2168DWORD VBoxDispIfSeamlessSubmit(VBOXDISPIF_SEAMLESS *pSeamless, VBOXDISPIFESCAPE *pData, int cbData)
    21732169{
    21742170    PCVBOXDISPIF const pIf = pSeamless->pIf;
     
    21882184        case VBOXDISPIF_MODE_WDDM:
    21892185        case VBOXDISPIF_MODE_WDDM_W7:
    2190             return vboxDispIfSeamlesSubmitWDDM(pSeamless, pData, cbData);
     2186            return vboxDispIfSeamlessSubmitWDDM(pSeamless, pData, cbData);
    21912187#endif
    21922188        default:
    2193             WARN(("VBoxTray: VBoxDispIfSeamlesSubmit: invalid mode %d\n", pIf->enmMode));
     2189            WARN(("VBoxTray: VBoxDispIfSeamlessSubmit: invalid mode %d\n", pIf->enmMode));
    21942190            return ERROR_INVALID_PARAMETER;
    21952191    }
    21962192}
     2193
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDispIf.h

    r55401 r57741  
    5151        struct
    5252        {
    53             LONG (WINAPI * pfnChangeDisplaySettingsEx)(LPCSTR lpszDeviceName, LPDEVMODE lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam);
     53            LONG (WINAPI *pfnChangeDisplaySettingsEx)(LPCSTR lpszDeviceName, LPDEVMODE lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam);
    5454        } xpdm;
    5555#ifdef VBOX_WITH_WDDM
     
    5757        {
    5858            /* ChangeDisplaySettingsEx does not exist in NT. ResizeDisplayDevice uses the function. */
    59             LONG (WINAPI * pfnChangeDisplaySettingsEx)(LPCTSTR lpszDeviceName, LPDEVMODE lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam);
    60 
     59            LONG (WINAPI *pfnChangeDisplaySettingsEx)(LPCTSTR lpszDeviceName, LPDEVMODE lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam);
    6160            /* EnumDisplayDevices does not exist in NT. isVBoxDisplayDriverActive et al. are using these functions. */
    62             BOOL (WINAPI * pfnEnumDisplayDevices)(IN LPCSTR lpDevice, IN DWORD iDevNum, OUT PDISPLAY_DEVICEA lpDisplayDevice, IN DWORD dwFlags);
     61            BOOL (WINAPI *pfnEnumDisplayDevices)(IN LPCSTR lpDevice, IN DWORD iDevNum, OUT PDISPLAY_DEVICEA lpDisplayDevice, IN DWORD dwFlags);
    6362
    6463            VBOXDISPKMT_CALLBACKS KmtCallbacks;
     
    8079DWORD VBoxDispIfResizeModes(PCVBOXDISPIF const pIf, UINT iChangedMode, BOOL fEnable, BOOL fExtDispSup, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes, UINT cDevModes);
    8180DWORD VBoxDispIfCancelPendingResize(PCVBOXDISPIF const pIf);
    82 
    8381DWORD VBoxDispIfResizeStarted(PCVBOXDISPIF const pIf);
    84 
    8582
    8683typedef struct VBOXDISPIF_SEAMLESS
     
    108105}
    109106
    110 DWORD VBoxDispIfSeamlesCreate(PCVBOXDISPIF const pIf, VBOXDISPIF_SEAMLESS *pSeamless, HANDLE hEvent);
    111 DWORD VBoxDispIfSeamlesTerm(VBOXDISPIF_SEAMLESS *pSeamless);
    112 DWORD VBoxDispIfSeamlesSubmit(VBOXDISPIF_SEAMLESS *pSeamless, VBOXDISPIFESCAPE *pData, int cbData);
     107DWORD VBoxDispIfSeamlessCreate(PCVBOXDISPIF const pIf, VBOXDISPIF_SEAMLESS *pSeamless, HANDLE hEvent);
     108DWORD VBoxDispIfSeamlessTerm(VBOXDISPIF_SEAMLESS *pSeamless);
     109DWORD VBoxDispIfSeamlessSubmit(VBOXDISPIF_SEAMLESS *pSeamless, VBOXDISPIFESCAPE *pData, int cbData);
     110
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDisplay.cpp

    r53313 r57741  
    55
    66/*
    7  * Copyright (C) 2006-2014 Oracle Corporation
     7 * Copyright (C) 2006-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4242{
    4343    const VBOXSERVICEENV *pEnv;
    44 
    4544    BOOL fAnyX;
    46 
    47     /* ChangeDisplaySettingsEx does not exist in NT. ResizeDisplayDevice uses the function. */
     45    /** ChangeDisplaySettingsEx does not exist in NT. ResizeDisplayDevice uses the function. */
    4846    LONG (WINAPI * pfnChangeDisplaySettingsEx)(LPCTSTR lpszDeviceName, LPDEVMODE lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam);
    49 
    50     /* EnumDisplayDevices does not exist in NT. isVBoxDisplayDriverActive et al. are using these functions. */
     47    /** EnumDisplayDevices does not exist in NT. isVBoxDisplayDriverActive et al. are using these functions. */
    5148    BOOL (WINAPI * pfnEnumDisplayDevices)(IN LPCSTR lpDevice, IN DWORD iDevNum, OUT PDISPLAY_DEVICEA lpDisplayDevice, IN DWORD dwFlags);
    52 } VBOXDISPLAYCONTEXT;
    53 
    54 static VBOXDISPLAYCONTEXT gCtx = {0};
     49    /** Display driver interface, XPDM - WDDM abstraction see VBOXDISPIF** definitions above */
     50    VBOXDISPIF dispIf;
     51} VBOXDISPLAYCONTEXT, *PVBOXDISPLAYCONTEXT;
     52
     53static VBOXDISPLAYCONTEXT g_Ctx = { 0 };
    5554
    5655#ifdef VBOX_WITH_WDDM
     
    6564#endif
    6665
    67 int VBoxDisplayInit(const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread)
     66static DECLCALLBACK(int) VBoxDisplayInit(const PVBOXSERVICEENV pEnv, void **ppInstance)
    6867{
    69     LogFlowFunc(("VBoxDisplayInit ...\n"));
    70 
    71     OSVERSIONINFO OSinfo;
    72     OSinfo.dwOSVersionInfoSize = sizeof (OSinfo);
     68    LogFlowFuncEnter();
     69
     70    PVBOXDISPLAYCONTEXT pCtx = &g_Ctx; /** @todo r=andy Use instance data via service lookup (add void *pInstance). */
     71    AssertPtr(pCtx);
     72
     73    OSVERSIONINFO OSinfo; /** @todo r=andy Use VBoxTray's g_dwMajorVersion? */
     74    OSinfo.dwOSVersionInfoSize = sizeof(OSinfo);
    7375    GetVersionEx (&OSinfo);
    7476
    75     HMODULE hUser = GetModuleHandle("user32.dll");
    76 
    77     gCtx.pEnv = pEnv;
     77    int rc;
     78    HMODULE hUser = GetModuleHandle("user32.dll"); /** @todo r=andy Use RTLdrXXX and friends. */
     79
     80    pCtx->pEnv = pEnv;
    7881
    7982    if (NULL == hUser)
    8083    {
    8184        LogFlowFunc(("Could not get module handle of USER32.DLL!\n"));
    82         return VERR_NOT_IMPLEMENTED;
    83     }
    84     else if (OSinfo.dwMajorVersion >= 5)        /* APIs available only on W2K and up! */
    85     {
    86         *(uintptr_t *)&gCtx.pfnChangeDisplaySettingsEx = (uintptr_t)GetProcAddress(hUser, "ChangeDisplaySettingsExA");
    87         LogFlowFunc(("pfnChangeDisplaySettingsEx = %p\n", gCtx.pfnChangeDisplaySettingsEx));
    88 
    89         *(uintptr_t *)&gCtx.pfnEnumDisplayDevices = (uintptr_t)GetProcAddress(hUser, "EnumDisplayDevicesA");
    90         LogFlowFunc(("pfnEnumDisplayDevices = %p\n", gCtx.pfnEnumDisplayDevices));
     85        rc = VERR_NOT_IMPLEMENTED;
     86    }
     87    else if (OSinfo.dwMajorVersion >= 5)        /* APIs available only on W2K and up. */
     88    {
     89        /** @todo r=andy Use RTLdrXXX and friends. */
     90        /** @todo r=andy No unicode version available? */
     91        *(uintptr_t *)&pCtx->pfnChangeDisplaySettingsEx = (uintptr_t)GetProcAddress(hUser, "ChangeDisplaySettingsExA");
     92        LogFlowFunc(("pfnChangeDisplaySettingsEx = %p\n", pCtx->pfnChangeDisplaySettingsEx));
     93
     94        *(uintptr_t *)&pCtx->pfnEnumDisplayDevices = (uintptr_t)GetProcAddress(hUser, "EnumDisplayDevicesA");
     95        LogFlowFunc(("pfnEnumDisplayDevices = %p\n", pCtx->pfnEnumDisplayDevices));
    9196
    9297#ifdef VBOX_WITH_WDDM
    9398        if (OSinfo.dwMajorVersion >= 6)
    9499        {
    95             /* this is vista and up, check if we need to switch the display driver if to WDDM mode */
     100            /* This is Vista and up, check if we need to switch the display driver if to WDDM mode. */
    96101            LogFlowFunc(("this is Windows Vista and up\n"));
    97             VBOXDISPLAY_DRIVER_TYPE enmType = getVBoxDisplayDriverType (&gCtx);
     102            VBOXDISPLAY_DRIVER_TYPE enmType = getVBoxDisplayDriverType(pCtx);
    98103            if (enmType == VBOXDISPLAY_DRIVER_TYPE_WDDM)
    99104            {
    100105                LogFlowFunc(("WDDM driver is installed, switching display driver if to WDDM mode\n"));
    101                 /* this is hacky, but the most easiest way */
     106                /* This is hacky, but the most easiest way. */
    102107                VBOXDISPIF_MODE enmMode = (OSinfo.dwMajorVersion > 6 || OSinfo.dwMinorVersion > 0) ? VBOXDISPIF_MODE_WDDM_W7 : VBOXDISPIF_MODE_WDDM;
    103                 DWORD err = VBoxDispIfSwitchMode(const_cast<PVBOXDISPIF>(&pEnv->dispIf), enmMode, NULL /* old mode, we don't care about it */);
    104                 if (err == NO_ERROR)
    105                     LogFlowFunc(("DispIf switched to WDDM mode successfully\n"));
     108                DWORD dwErr = VBoxDispIfSwitchMode(const_cast<PVBOXDISPIF>(&pEnv->dispIf), enmMode, NULL /* old mode, we don't care about it */);
     109                if (dwErr == NO_ERROR)
     110                {
     111                    LogFlowFunc(("DispIf successfully switched to WDDM mode\n"));
     112                    rc = VINF_SUCCESS;
     113                }
    106114                else
    107                     LogFlowFunc(("Failed to switch DispIf to WDDM mode, err (%d)\n", err));
     115                {
     116                    LogFlowFunc(("Failed to switch DispIf to WDDM mode, error (%d)\n", dwErr));
     117                    rc = RTErrConvertFromWin32(dwErr);
     118                }
    108119            }
    109         }
     120            else
     121                rc = VINF_SUCCESS;
     122        }
     123        else
     124            rc = VINF_SUCCESS;
    110125#endif
    111126    }
    112     else if (OSinfo.dwMajorVersion <= 4)            /* Windows NT 4.0 */
    113     {
    114         /* Nothing to do here yet */
    115     }
    116     else                                /* Unsupported platform */
    117     {
    118         LogFlowFunc(("Warning, display for platform not handled yet!\n"));
    119         return VERR_NOT_IMPLEMENTED;
    120     }
    121 
    122     VBOXDISPIFESCAPE_ISANYX IsAnyX = {0};
    123     IsAnyX.EscapeHdr.escapeCode = VBOXESC_ISANYX;
    124     DWORD err = VBoxDispIfEscapeInOut(&pEnv->dispIf, &IsAnyX.EscapeHdr, sizeof (uint32_t));
    125     if (err == NO_ERROR)
    126         gCtx.fAnyX = !!IsAnyX.u32IsAnyX;
    127     else
    128         gCtx.fAnyX = TRUE;
    129 
    130     LogFlowFunc(("Display init successful\n"));
    131 
    132     *pfStartThread = true;
    133     *ppInstance = (void *)&gCtx;
    134     return VINF_SUCCESS;
     127    else if (OSinfo.dwMajorVersion <= 4) /* Windows NT 4.0. */
     128    {
     129        /* Nothing to do here yet. */
     130        /** @todo r=andy Has this been tested? */
     131        rc = VINF_SUCCESS;
     132    }
     133    else                                 /* Unsupported platform. */
     134    {
     135        LogFlowFunc(("Warning: Display for platform not handled yet!\n"));
     136        rc = VERR_NOT_IMPLEMENTED;
     137    }
     138
     139    if (RT_SUCCESS(rc))
     140    {
     141        VBOXDISPIFESCAPE_ISANYX IsAnyX = { 0 };
     142        IsAnyX.EscapeHdr.escapeCode = VBOXESC_ISANYX;
     143        DWORD err = VBoxDispIfEscapeInOut(&pEnv->dispIf, &IsAnyX.EscapeHdr, sizeof(uint32_t));
     144        if (err == NO_ERROR)
     145            pCtx->fAnyX = !!IsAnyX.u32IsAnyX;
     146        else
     147            pCtx->fAnyX = TRUE;
     148
     149        *ppInstance = pCtx;
     150    }
     151
     152    LogFlowFuncLeaveRC(rc);
     153    return rc;
    135154}
    136155
    137 void VBoxDisplayDestroy (const VBOXSERVICEENV *pEnv, void *pInstance)
     156static DECLCALLBACK(void) VBoxDisplayDestroy(void *pInstance)
    138157{
    139158    return;
     
    141160
    142161#ifdef VBOX_WITH_WDDM
    143 static VBOXDISPLAY_DRIVER_TYPE getVBoxDisplayDriverType(VBOXDISPLAYCONTEXT *pCtx)
     162static VBOXDISPLAY_DRIVER_TYPE getVBoxDisplayDriverType(PVBOXDISPLAYCONTEXT pCtx)
    144163#else
    145 static bool isVBoxDisplayDriverActive(VBOXDISPLAYCONTEXT *pCtx)
     164static bool isVBoxDisplayDriverActive(PVBOXDISPLAYCONTEXT pCtx)
    146165#endif
    147166{
     
    224243}
    225244
    226 DWORD EnableAndResizeDispDev(DEVMODE *paDeviceModes, DISPLAY_DEVICE *paDisplayDevices, DWORD totalDispNum, UINT Id, DWORD aWidth, DWORD aHeight,
    227                                     DWORD aBitsPerPixel, LONG aPosX, LONG aPosY, BOOL fEnabled, BOOL fExtDispSup)
     245/** @todo r=andy The "display", "seamless" (and VBoxCaps facility in VBoxTray.cpp indirectly) is using this.
     246 *               Add a PVBOXDISPLAYCONTEXT here for properly getting the display (XPDM/WDDM) abstraction interfaces. */
     247DWORD EnableAndResizeDispDev(DEVMODE *paDeviceModes, DISPLAY_DEVICE *paDisplayDevices,
     248                             DWORD totalDispNum, UINT Id, DWORD aWidth, DWORD aHeight,
     249                             DWORD aBitsPerPixel, LONG aPosX, LONG aPosY, BOOL fEnabled, BOOL fExtDispSup)
    228250{
    229251    DISPLAY_DEVICE displayDeviceTmp;
     
    233255    DWORD iter ;
    234256
     257    PVBOXDISPLAYCONTEXT pCtx = &g_Ctx; /* See todo above. */
     258
    235259    deviceMode = paDeviceModes[Id];
    236260    displayDevice = paDisplayDevices[Id];
     
    240264        if (iter != 0 && iter != Id && !(paDisplayDevices[iter].StateFlags & DISPLAY_DEVICE_ACTIVE))
    241265        {
    242             LogRel(("VBoxTray:Initially disabling the monitor with id = %d . Total Monitor=%d\n", iter, totalDispNum));
     266            LogRel(("Display: Initially disabling monitor with ID=%ld; total monitor count is %ld\n", iter, totalDispNum));
    243267            DEVMODE deviceModeTmp;
    244268            ZeroMemory(&deviceModeTmp, sizeof(DEVMODE));
     
    247271                                     | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS ;
    248272            displayDeviceTmp = paDisplayDevices[iter];
    249             gCtx.pfnChangeDisplaySettingsEx(displayDeviceTmp.DeviceName, &deviceModeTmp, NULL,
    250                                            (CDS_UPDATEREGISTRY | CDS_NORESET), NULL);
     273            pCtx->pfnChangeDisplaySettingsEx(displayDeviceTmp.DeviceName, &deviceModeTmp, NULL,
     274                                             (CDS_UPDATEREGISTRY | CDS_NORESET), NULL);
    251275        }
    252276    }
     
    259283            if(!(displayDevice.StateFlags & DISPLAY_DEVICE_ACTIVE))
    260284            {
    261                 LogRel(("Secondary Monitor with ID=%d and name=%s Not Enabled. Enabling it.\n", Id, displayDevice.DeviceName));
     285                LogRel(("Display [ID=%ld, name='%s']: Is a secondary monitor and disabled -- enabling it\n", Id, displayDevice.DeviceName));
    262286                deviceMode.dmPosition.x = paDeviceModes[0].dmPelsWidth;
    263287                deviceMode.dmPosition.y = 0;
     
    274298                    deviceMode.dmFields =   DM_BITSPERPEL | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY  | DM_POSITION;
    275299
    276                 dwStatus = gCtx.pfnChangeDisplaySettingsEx((LPSTR)displayDevice.DeviceName,&deviceMode, NULL, (CDS_UPDATEREGISTRY | CDS_NORESET), NULL);
     300                dwStatus = pCtx->pfnChangeDisplaySettingsEx((LPSTR)displayDevice.DeviceName,&deviceMode, NULL, (CDS_UPDATEREGISTRY | CDS_NORESET), NULL);
    277301                /* A second call to ChangeDisplaySettings updates the monitor.*/
    278                 gCtx.pfnChangeDisplaySettingsEx(NULL, NULL, NULL,0, NULL);
     302                pCtx->pfnChangeDisplaySettingsEx(NULL, NULL, NULL,0, NULL);
    279303            }
    280304            else /* secondary monitor already enabled. Request to change the resolution or position. */
     
    282306                if (aWidth !=0 && aHeight != 0)
    283307                {
    284                     LogRel(("Display : %s , Change Height: %d & Width: %d\n", displayDevice.DeviceName, aWidth, aHeight));
     308                    LogRel(("Display [ID=%ld, name='%s']: Changing resolution to %ldx%ld\n", Id, displayDevice.DeviceName, aWidth, aHeight));
    285309                    deviceMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL
    286310                                          | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS;
     
    291315                if (aPosX != 0 || aPosY != 0)
    292316                {
    293                     LogRel(("Display: %s PosX: %d, PosY: %d\n", displayDevice.DeviceName, aPosX, aPosY));
     317                    LogRel(("Display [ID=%ld, name='%s']: Changing position to %ld,%ld\n", Id, displayDevice.DeviceName, aPosX, aPosY));
    294318                    deviceMode.dmFields |=  DM_POSITION;
    295319                    deviceMode.dmPosition.x = aPosX;
    296320                    deviceMode.dmPosition.y = aPosY;
    297321                }
    298                 dwStatus = gCtx.pfnChangeDisplaySettingsEx((LPSTR)displayDevice.DeviceName,
    299                                                    &deviceMode, NULL, CDS_NORESET|CDS_UPDATEREGISTRY, NULL);
     322                dwStatus = pCtx->pfnChangeDisplaySettingsEx((LPSTR)displayDevice.DeviceName,
     323                                                            &deviceMode, NULL, CDS_NORESET|CDS_UPDATEREGISTRY, NULL);
    300324                /* A second call to ChangeDisplaySettings updates the monitor. */
    301                 gCtx.pfnChangeDisplaySettingsEx(NULL, NULL, NULL,0, NULL);
     325                pCtx->pfnChangeDisplaySettingsEx(NULL, NULL, NULL,0, NULL);
    302326            }
    303327        }
    304328        else /* Request is there to disable the monitor with ID = Id*/
    305329        {
    306             LogRel(("Disable the Display: %d\n", displayDevice.DeviceName));
     330            LogRel(("Display [ID=%ld, name='%s']: Disalbing\n", Id, displayDevice.DeviceName));
    307331
    308332            DEVMODE deviceModeTmp;
     
    312336                                     | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS ;
    313337            displayDeviceTmp = paDisplayDevices[Id];
    314             dwStatus = gCtx.pfnChangeDisplaySettingsEx(displayDeviceTmp.DeviceName, &deviceModeTmp, NULL,
    315                                            (CDS_UPDATEREGISTRY | CDS_NORESET), NULL);
    316             gCtx.pfnChangeDisplaySettingsEx(NULL, NULL, NULL,0, NULL);
     338            dwStatus = pCtx->pfnChangeDisplaySettingsEx(displayDeviceTmp.DeviceName, &deviceModeTmp, NULL,
     339                                                        (CDS_UPDATEREGISTRY | CDS_NORESET), NULL);
     340            pCtx->pfnChangeDisplaySettingsEx(NULL, NULL, NULL,0, NULL);
    317341        }
    318342    }
     
    320344}
    321345
    322 DWORD VBoxGetDisplayConfigCount()
     346DWORD VBoxDisplayGetCount(void)
    323347{
    324348    DISPLAY_DEVICE DisplayDevice;
     
    354378}
    355379
    356 DWORD VBoxGetDisplayConfig(const DWORD NumDevices, DWORD *pDevPrimaryNum, DWORD *pNumDevices, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes)
     380DWORD VBoxDisplayGetConfig(const DWORD NumDevices, DWORD *pDevPrimaryNum, DWORD *pNumDevices,
     381                           DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes)
    357382{
    358383    /* Fetch information about current devices and modes. */
     
    441466
    442467/* Returns TRUE to try again. */
    443 static BOOL ResizeDisplayDevice(UINT Id, DWORD Width, DWORD Height, DWORD BitsPerPixel,
     468/** @todo r=andy Why not using the VMMDevDisplayChangeRequestEx structure for all those parameters here? */
     469static BOOL ResizeDisplayDevice(PVBOXDISPLAYCONTEXT pCtx,
     470                                UINT Id, DWORD Width, DWORD Height, DWORD BitsPerPixel,
    444471                                BOOL fEnabled, LONG dwNewPosX, LONG dwNewPosY, bool fChangeOrigin,
    445                                 VBOXDISPLAYCONTEXT *pCtx, BOOL fExtDispSup)
     472                                BOOL fExtDispSup)
    446473{
    447474    BOOL fDispAlreadyEnabled = false; /* check whether the monitor with ID is already enabled. */
     
    453480          Id, Width, Height, dwNewPosX, dwNewPosY, fChangeOrigin, fEnabled, fExtDispSup));
    454481
    455     if (!gCtx.fAnyX)
     482    if (!pCtx->fAnyX)
    456483        Width &= 0xFFF8;
    457484
    458485    VBoxDispIfCancelPendingResize(&pCtx->pEnv->dispIf);
    459486
    460     DWORD NumDevices = VBoxGetDisplayConfigCount();
     487    DWORD NumDevices = VBoxDisplayGetCount();
    461488
    462489    if (NumDevices == 0 || Id >= NumDevices)
     
    473500    DWORD DevNum = 0;
    474501    DWORD DevPrimaryNum = 0;
    475     DWORD dwStatus = VBoxGetDisplayConfig(NumDevices, &DevPrimaryNum, &DevNum, paDisplayDevices, paDeviceModes);
     502    DWORD dwStatus = VBoxDisplayGetConfig(NumDevices, &DevPrimaryNum, &DevNum, paDisplayDevices, paDeviceModes);
    476503    if (dwStatus != NO_ERROR)
    477504    {
     
    566593     * all rect conditions are true. Thus in this case nothing has to be done.
    567594     */
    568     if ( !fModeReset && (!fEnabled == !fDispAlreadyEnabled)
    569         && paRects[Id].left == dwNewPosX
    570         && paRects[Id].top == dwNewPosY
    571         && paRects[Id].right - paRects[Id].left == Width
    572         && paRects[Id].bottom - paRects[Id].top == Height
     595    if (   !fModeReset && (!fEnabled == !fDispAlreadyEnabled)
     596        && paRects[Id].left                      == dwNewPosX
     597        && paRects[Id].top                       == dwNewPosY
     598        && paRects[Id].right  - paRects[Id].left == Width
     599        && paRects[Id].bottom - paRects[Id].top  == Height
    573600        && paDeviceModes[Id].dmBitsPerPel == BitsPerPixel)
    574601    {
     
    617644
    618645            LogFlowFunc(("ResizeDisplayDevice: pfnChangeDisplaySettingsEx %x: %dx%dx%d at %d,%d fields 0x%X\n",
    619                   gCtx.pfnChangeDisplaySettingsEx,
     646                  pCtx->pfnChangeDisplaySettingsEx,
    620647                  paDeviceModes[i].dmPelsWidth,
    621648                  paDeviceModes[i].dmPelsHeight,
     
    681708              paDeviceModes[i].dmPosition.y));
    682709
    683         LONG status = gCtx.pfnChangeDisplaySettingsEx((LPSTR)paDisplayDevices[i].DeviceName,
    684                                         &paDeviceModes[i], NULL, CDS_NORESET | CDS_UPDATEREGISTRY, NULL);
     710        LONG status = pCtx->pfnChangeDisplaySettingsEx((LPSTR)paDisplayDevices[i].DeviceName,
     711                                                       &paDeviceModes[i], NULL, CDS_NORESET | CDS_UPDATEREGISTRY, NULL);
    685712        LogFlowFunc(("ResizeDisplayDevice: ChangeDisplaySettingsEx position status %d, err %d\n", status, GetLastError ()));
    686713    }
     
    706733 * requests
    707734 */
    708 unsigned __stdcall VBoxDisplayThread(void *pInstance)
     735DECLCALLBACK(int) VBoxDisplayWorker(void *pInstance, bool volatile *pfShutdown)
    709736{
    710     LogFlowFunc(("Entered\n"));
    711 
    712     VBOXDISPLAYCONTEXT *pCtx = (VBOXDISPLAYCONTEXT *)pInstance;
     737    AssertPtr(pInstance);
     738    LogFlowFunc(("pInstance=%p\n", pInstance));
     739
     740    /*
     741     * Tell the control thread that it can continue
     742     * spawning services.
     743     */
     744    RTThreadUserSignal(RTThreadSelf());
     745
     746    PVBOXDISPLAYCONTEXT pCtx = (PVBOXDISPLAYCONTEXT)pInstance;
     747
    713748    HANDLE gVBoxDriver = pCtx->pEnv->hDriver;
    714     bool fTerminate = false;
    715749    VBoxGuestFilterMaskInfo maskInfo;
    716750    DWORD cbReturned;
     
    720754    if (!DeviceIoControl(gVBoxDriver, VBOXGUEST_IOCTL_CTL_FILTER_MASK, &maskInfo, sizeof (maskInfo), NULL, 0, &cbReturned, NULL))
    721755    {
    722         LogFlowFunc(("DeviceIOControl(CtlMask - or) failed, thread exiting\n"));
    723         return 0;
    724     }
    725 
    726     PostMessage(ghwndToolWindow, WM_VBOX_GRAPHICS_SUPPORTED, 0, 0);
     756        DWORD dwErr = GetLastError();
     757        LogFlowFunc(("DeviceIOControl(CtlMask - or) failed with %ld, exiting\n", dwErr));
     758        return RTErrConvertFromWin32(dwErr);
     759    }
     760
     761    PostMessage(g_hwndToolWindow, WM_VBOX_GRAPHICS_SUPPORTED, 0, 0);
    727762
    728763    VBoxDispIfResizeStarted(&pCtx->pEnv->dispIf);
    729764
    730     do
     765    int rc = VINF_SUCCESS;
     766
     767    for (;;)
    731768    {
    732769        BOOL fExtDispSup = TRUE;
    733770        /* Wait for a display change event. */
    734771        VBoxGuestWaitEventInfo waitEvent;
    735         waitEvent.u32TimeoutIn = 1000;
     772        waitEvent.u32TimeoutIn   = 1000;
    736773        waitEvent.u32EventMaskIn = VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST | VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED;
    737774        if (DeviceIoControl(gVBoxDriver, VBOXGUEST_IOCTL_WAITEVENT, &waitEvent, sizeof(waitEvent), &waitEvent, sizeof(waitEvent), &cbReturned, NULL))
     
    750787
    751788            /* are we supposed to stop? */
    752             if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 0) == WAIT_OBJECT_0)
     789            if (*pfShutdown)
    753790                break;
    754791
     
    847884                                     displayChangeRequest.cyOrigin,
    848885                                     displayChangeRequest.fChangeOrigin));
    849                                 if (!ResizeDisplayDevice(displayChangeRequest.display,
     886                                if (!ResizeDisplayDevice(pCtx,
     887                                                         displayChangeRequest.display,
    850888                                                         displayChangeRequest.xres,
    851889                                                         displayChangeRequest.yres,
     
    855893                                                         displayChangeRequest.cyOrigin,
    856894                                                         displayChangeRequest.fChangeOrigin,
    857                                                          pCtx,
    858895                                                         fExtDispSup
    859896                                                         ))
     
    922959
    923960                                    LogFlowFunc(("setting new mode %d x %d, %d BPP\n",
    924                                          devMode.dmPelsWidth, devMode.dmPelsHeight, devMode.dmBitsPerPel));
     961                                                 devMode.dmPelsWidth, devMode.dmPelsHeight, devMode.dmBitsPerPel));
    925962
    926963                                    /* set the new mode */
     
    955992
    956993                        /* Retry the change a bit later. */
    957                         /* are we supposed to stop? */
    958                         if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 1000) == WAIT_OBJECT_0)
    959                         {
    960                             fTerminate = true;
    961                             break;
    962                         }
     994                        RTThreadSleep(1000);
    963995                    }
    964996                }
    965997                else
    966998                {
    967                     LogFlowFunc(("error from DeviceIoControl VBOXGUEST_IOCTL_VMMREQUEST\n"));
    968999                    /* sleep a bit to not eat too much CPU while retrying */
    969                     /* are we supposed to stop? */
    970                     if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 50) == WAIT_OBJECT_0)
    971                     {
    972                         fTerminate = true;
    973                         break;
    974                     }
     1000                    RTThreadSleep(50);
    9751001                }
    9761002            }
     1003
     1004            /* are we supposed to stop? */
     1005            if (*pfShutdown)
     1006                break;
     1007
    9771008            if (waitEvent.u32EventFlagsOut & VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED)
    9781009                hlpReloadCursor();
     
    9801011        else
    9811012        {
    982 #ifndef DEBUG_andy /* Too noisy for me. */
    983             LogFlowFunc(("error 0 from DeviceIoControl VBOXGUEST_IOCTL_WAITEVENT\n"));
    984 #endif
    9851013            /* sleep a bit to not eat too much CPU in case the above call always fails */
    986             if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 10) == WAIT_OBJECT_0)
    987             {
    988                 fTerminate = true;
     1014            RTThreadSleep(10);
     1015
     1016            if (*pfShutdown)
    9891017                break;
    990             }
    991         }
    992     } while (!fTerminate);
     1018        }
     1019    }
    9931020
    9941021    /*
     
    9991026    if (!DeviceIoControl(gVBoxDriver, VBOXGUEST_IOCTL_CTL_FILTER_MASK, &maskInfo, sizeof (maskInfo), NULL, 0, &cbReturned, NULL))
    10001027        LogFlowFunc(("DeviceIOControl(CtlMask - not) failed\n"));
    1001     PostMessage(ghwndToolWindow, WM_VBOX_GRAPHICS_UNSUPPORTED, 0, 0);
    1002 
    1003     LogFlowFunc(("finished display change request thread\n"));
    1004     return 0;
     1028    PostMessage(g_hwndToolWindow, WM_VBOX_GRAPHICS_UNSUPPORTED, 0, 0);
     1029
     1030    LogFlowFuncLeaveRC(rc);
     1031    return rc;
    10051032}
     1033
     1034/**
     1035 * The service description.
     1036 */
     1037VBOXSERVICEDESC g_SvcDescDisplay =
     1038{
     1039    /* pszName. */
     1040    "display",
     1041    /* pszDescription. */
     1042    "Display Notifications",
     1043    /* methods */
     1044    VBoxDisplayInit,
     1045    VBoxDisplayWorker,
     1046    NULL /* pfnStop */,
     1047    VBoxDisplayDestroy
     1048};
     1049
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDisplay.h

    r55401 r57741  
    55
    66/*
    7  * Copyright (C) 2006-2010 Oracle Corporation
     7 * Copyright (C) 2006-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1919#define __VBOXSERVICEDISPLAY__H
    2020
    21 /* The display service prototypes. */
    22 int                VBoxDisplayInit    (const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread);
    23 unsigned __stdcall VBoxDisplayThread  (void *pInstance);
    24 void               VBoxDisplayDestroy (const VBOXSERVICEENV *pEnv, void *pInstance);
     21DWORD VBoxDisplayGetCount();
     22DWORD VBoxDisplayGetConfig(const DWORD NumDevices, DWORD *pDevPrimaryNum, DWORD *pNumDevices, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes);
    2523
    26 DWORD VBoxGetDisplayConfigCount();
    27 DWORD VBoxGetDisplayConfig(const DWORD NumDevices, DWORD *pDevPrimaryNum, DWORD *pNumDevices, DISPLAY_DEVICE *paDisplayDevices, DEVMODE *paDeviceModes);
     24DWORD EnableAndResizeDispDev(DEVMODE *paDeviceModes, DISPLAY_DEVICE *paDisplayDevices, DWORD totalDispNum, UINT Id, DWORD aWidth, DWORD aHeight,
     25                             DWORD aBitsPerPixel, LONG aPosX, LONG aPosY, BOOL fEnabled, BOOL fExtDispSup);
    2826
    2927#ifndef VBOX_WITH_WDDM
    30 static bool isVBoxDisplayDriverActive (void);
     28static bool isVBoxDisplayDriverActive(void);
    3129#else
    3230/* @misha: getVBoxDisplayDriverType is used instead.
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.cpp

    r56661 r57741  
    4848#endif
    4949
     50/** The drag and drop window's window class. */
     51#define VBOX_DND_WND_CLASS            "VBoxTrayDnDWnd"
     52
    5053/** @todo Merge this with messages from VBoxTray.h. */
    5154#define WM_VBOXTRAY_DND_MESSAGE       WM_APP + 401
     
    6265static LRESULT CALLBACK vboxDnDWndProcInstance(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    6366static LRESULT CALLBACK vboxDnDWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
     67
     68static VBOXDNDCONTEXT g_Ctx = { 0 };
    6469
    6570VBoxDnDWnd::VBoxDnDWnd(void)
     
    97102 * @param   pContext                Pointer to context to use.
    98103 */
    99 int VBoxDnDWnd::Initialize(PVBOXDNDCONTEXT pContext)
    100 {
    101     AssertPtrReturn(pContext, VERR_INVALID_POINTER);
     104int VBoxDnDWnd::Initialize(PVBOXDNDCONTEXT pCtx)
     105{
     106    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
    102107
    103108    /* Save the context. */
    104     this->pContext = pContext;
     109    this->pCtx = pCtx;
    105110
    106111    int rc = RTSemEventCreate(&mEventSem);
     
    113118        rc = RTThreadCreate(&hThread, VBoxDnDWnd::Thread, this,
    114119                            0, RTTHREADTYPE_MSG_PUMP, RTTHREADFLAGS_WAITABLE,
    115                             "VBoxTrayDnDWnd");
     120                            "dndwnd"); /** @todo Include ID if there's more than one proxy window. */
    116121        if (RT_SUCCESS(rc))
    117122            rc = RTThreadUserWait(hThread, 30 * 1000 /* Timeout in ms */);
     
    128133 * Destroys the proxy window and releases all remaining
    129134 * resources again.
    130  *
    131135 */
    132136void VBoxDnDWnd::Destroy(void)
     
    144148    RTCritSectDelete(&mCritSect);
    145149    if (mEventSem != NIL_RTSEMEVENT)
     150    {
    146151        RTSemEventDestroy(mEventSem);
     152        mEventSem = NIL_RTSEMEVENT;
     153    }
     154
     155    if (pCtx->wndClass != 0)
     156    {
     157        UnregisterClass(VBOX_DND_WND_CLASS, pCtx->pEnv->hInstance);
     158        pCtx->wndClass = 0;
     159    }
    147160
    148161    LogFlowFuncLeave();
     
    162175    AssertPtrReturn(pvUser, VERR_INVALID_POINTER);
    163176
     177    LogFlowFuncEnter();
     178
    164179    VBoxDnDWnd *pThis = (VBoxDnDWnd*)pvUser;
    165180    AssertPtr(pThis);
    166181
    167     PVBOXDNDCONTEXT pContext = pThis->pContext;
    168     AssertPtr(pContext);
    169     AssertPtr(pContext->pEnv);
    170 
    171     HINSTANCE hInstance = pContext->pEnv->hInstance;
     182    PVBOXDNDCONTEXT pCtx = pThis->pCtx;
     183    AssertPtr(pCtx);
     184    AssertPtr(pCtx->pEnv);
     185
     186    int rc = VINF_SUCCESS;
     187
     188    AssertPtr(pCtx->pEnv);
     189    HINSTANCE hInstance = pCtx->pEnv->hInstance;
    172190    Assert(hInstance != 0);
    173191
    174192    /* Create our proxy window. */
    175     WNDCLASSEX wndClass;
    176     RT_ZERO(wndClass);
    177 
    178     wndClass.cbSize        = sizeof(WNDCLASSEX);
    179     wndClass.lpfnWndProc   = vboxDnDWndProc;
    180     wndClass.lpszClassName = "VBoxTrayDnDWnd";
    181     wndClass.hInstance     = hInstance;
    182     wndClass.style         = CS_NOCLOSE;
     193    WNDCLASSEX wc = { 0 };
     194    wc.cbSize     = sizeof(WNDCLASSEX);
     195
     196    if (!GetClassInfoEx(hInstance, VBOX_DND_WND_CLASS, &wc))
     197    {
     198        wc.lpfnWndProc   = vboxDnDWndProc;
     199        wc.lpszClassName = VBOX_DND_WND_CLASS;
     200        wc.hInstance     = hInstance;
     201        wc.style         = CS_NOCLOSE;
    183202#ifdef VBOX_DND_DEBUG_WND
    184     wndClass.style        |= CS_HREDRAW | CS_VREDRAW;
    185     wndClass.hbrBackground = (HBRUSH)(CreateSolidBrush(RGB(255, 0, 0)));
     203        wc.style        |= CS_HREDRAW | CS_VREDRAW;
     204        wc.hbrBackground = (HBRUSH)(CreateSolidBrush(RGB(255, 0, 0)));
    186205#else
    187     wndClass.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
    188 #endif
    189 
    190     bool fSignalled = false; /* Thread signalled? */
    191 
    192     int rc = VINF_SUCCESS;
    193     if (!RegisterClassEx(&wndClass))
    194     {
    195         DWORD dwErr = GetLastError();
    196         LogFlowFunc(("Unable to register proxy window class, error=%ld\n", dwErr));
    197         rc = RTErrConvertFromWin32(dwErr);
     206        wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
     207#endif
     208        if (!RegisterClassEx(&wc))
     209        {
     210            DWORD dwErr = GetLastError();
     211            LogFlowFunc(("Unable to register proxy window class, error=%ld\n", dwErr));
     212            rc = RTErrConvertFromWin32(dwErr);
     213        }
    198214    }
    199215
     
    208224        pThis->hWnd =
    209225            CreateWindowEx(dwExStyle,
    210                            "VBoxTrayDnDWnd", "VBoxTrayDnDWnd",
     226                           VBOX_DND_WND_CLASS, VBOX_DND_WND_CLASS,
    211227                           dwStyle,
    212228#ifdef VBOX_DND_DEBUG_WND
     
    251267#ifdef VBOX_WITH_DRAG_AND_DROP_GH
    252268        rc = pThis->RegisterAsDropTarget();
     269#else
     270        rc = VINF_SUCCESS;
    253271#endif
    254272    }
     
    259277    }
    260278
     279    bool fSignalled = false;
     280
    261281    if (RT_SUCCESS(rc))
    262282    {
     
    265285
    266286        bool fShutdown = false;
    267         while (RT_SUCCESS(rc))
     287        for (;;)
    268288        {
    269289            MSG uMsg;
     
    274294            }
    275295
    276             if (ASMAtomicReadBool(&pContext->fShutdown))
     296            if (ASMAtomicReadBool(&pCtx->fShutdown))
    277297                fShutdown = true;
    278298
    279299            if (fShutdown)
    280300            {
    281                 LogFlowFunc(("Cancelling ...\n"));
     301                LogFlowFunc(("Closing proxy window ...\n"));
    282302                break;
    283303            }
     
    356376        }
    357377
    358         case WM_CLOSE:
    359         {
    360             OnDestroy();
    361 
    362             DestroyWindow(hWnd);
     378        case WM_QUIT:
     379        {
     380            LogFlowThisFunc(("WM_QUIT\n"));
    363381            PostQuitMessage(0);
    364382            return 0;
    365383        }
    366384
     385        case WM_DESTROY:
     386        {
     387            LogFlowThisFunc(("WM_DESTROY\n"));
     388
     389            OnDestroy();
     390            return 0;
     391        }
     392
    367393        case WM_LBUTTONDOWN:
     394        {
    368395            LogFlowThisFunc(("WM_LBUTTONDOWN\n"));
    369396            mfMouseButtonDown = true;
    370397            return 0;
     398        }
    371399
    372400        case WM_LBUTTONUP:
     401        {
    373402            LogFlowThisFunc(("WM_LBUTTONUP\n"));
    374403            mfMouseButtonDown = false;
     
    381410            reset();
    382411            return 0;
     412        }
    383413
    384414        case WM_MOUSELEAVE:
     415        {
    385416            LogFlowThisFunc(("WM_MOUSELEAVE\n"));
    386417            return 0;
     418        }
    387419
    388420        /* Will only be called once; after the first mouse move, this
     
    642674    {
    643675        pDropTarget = new VBoxDnDDropTarget(this /* pParent */);
    644         AssertPtr(pDropTarget);
    645676        HRESULT hr = CoLockObjectExternal(pDropTarget, TRUE /* fLock */,
    646677                                          FALSE /* fLastUnlockReleases */);
     
    706737int VBoxDnDWnd::OnCreate(void)
    707738{
     739    LogFlowFuncEnter();
    708740    int rc = VbglR3DnDConnect(&mDnDCtx);
    709741    if (RT_FAILURE(rc))
     
    722754void VBoxDnDWnd::OnDestroy(void)
    723755{
     756    DestroyWindow(hWnd);
     757
    724758    VbglR3DnDDisconnect(&mDnDCtx);
    725759    LogFlowThisFuncLeave();
     
    812846                    }
    813847                    else /* Should never happen. */
    814                         AssertReleaseFailedBreak(("Format specification for '%s' not implemented\n", pszFormat));
     848                        AssertReleaseMsgFailedBreak(("Format specification for '%s' not implemented\n", pszFormat));
    815849                    break;
    816850                }
     
    940974    /* Post ESC to our window to officially abort the
    941975     * drag and drop operation. */
    942     PostMessage(hWnd, WM_KEYDOWN, VK_ESCAPE, 0 /* lParam */);
     976    this->PostMessage(WM_KEYDOWN, VK_ESCAPE /* wParam */, 0 /* lParam */);
    943977
    944978    LogFlowFuncLeaveRC(rc);
     
    11961230            {
    11971231                case VERR_ACCESS_DENIED:
    1198                     rc = hlpShowBalloonTip(ghInstance, ghwndToolWindow, ID_TRAYICON,
     1232                    rc = hlpShowBalloonTip(g_hInstance, g_hwndToolWindow, ID_TRAYICON,
    11991233                                           szMsg, szTitle,
    12001234                                           15 * 1000 /* Time to display in msec */, NIIF_INFO);
     
    12701304#endif /* VBOX_WITH_DRAG_AND_DROP_GH */
    12711305
     1306void VBoxDnDWnd::PostMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
     1307{
     1308    LogFlowFunc(("Posting message %u\n"));
     1309    BOOL fRc = ::PostMessage(hWnd, uMsg, wParam, lParam);
     1310    Assert(fRc);
     1311}
     1312
    12721313/**
    12731314 * Injects a DnD event in this proxy window's Windows
     
    12821323    AssertPtrReturn(pEvent, VERR_INVALID_POINTER);
    12831324
    1284     BOOL fRc = PostMessage(hWnd, WM_VBOXTRAY_DND_MESSAGE,
    1285                            0 /* wParm */, (LPARAM)pEvent /* lParm */);
     1325    BOOL fRc = ::PostMessage(hWnd, WM_VBOXTRAY_DND_MESSAGE,
     1326                             0 /* wParm */, (LPARAM)pEvent /* lParm */);
    12861327    if (!fRc)
    12871328    {
     1329        DWORD dwErr = GetLastError();
     1330
    12881331        static int s_iBitchedAboutFailedDnDMessages = 0;
    12891332        if (s_iBitchedAboutFailedDnDMessages++ < 32)
    12901333        {
    1291             DWORD dwErr = GetLastError();
    1292             LogRel(("DnD: Processing event %p failed with %ld (%Rrc), skpping\n",
     1334            LogRel(("DnD: Processing event %p failed with %ld (%Rrc), skipping\n",
    12931335                    pEvent, dwErr, RTErrConvertFromWin32(dwErr)));
    12941336        }
     
    12971339        pEvent = NULL;
    12981340
    1299         return VERR_NO_MEMORY;
     1341        return RTErrConvertFromWin32(dwErr);
    13001342    }
    13011343
     
    15611603 * @param   pfStartThread               Pointer to flag whether the DnD service can be started or not.
    15621604 */
    1563 int VBoxDnDInit(const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread)
     1605DECLCALLBACK(int) VBoxDnDInit(const PVBOXSERVICEENV pEnv, void **ppInstance)
    15641606{
    15651607    AssertPtrReturn(pEnv, VERR_INVALID_POINTER);
    1566     /** ppInstance not used here. */
    1567     AssertPtrReturn(pfStartThread, VERR_INVALID_POINTER);
     1608    AssertPtrReturn(ppInstance, VERR_INVALID_POINTER);
    15681609
    15691610    LogFlowFuncEnter();
    15701611
    1571     *pfStartThread = false;
    1572 
    1573     PVBOXDNDCONTEXT pCtx = &gCtx;
     1612    PVBOXDNDCONTEXT pCtx = &g_Ctx; /* Only one instance at the moment. */
     1613    AssertPtr(pCtx);
    15741614
    15751615    int rc;
    15761616    bool fSupportedOS = true;
    15771617
    1578     s_pfnSendInput = (PFNSENDINPUT)
    1579         RTLdrGetSystemSymbol("User32.dll", "SendInput");
    1580     fSupportedOS = !RT_BOOL(s_pfnSendInput == NULL);
    1581     s_pfnEnumDisplayMonitors = (PFNENUMDISPLAYMONITORS)
    1582         RTLdrGetSystemSymbol("User32.dll", "EnumDisplayMonitors");
    1583     /* g_pfnEnumDisplayMonitors is optional. */
    1584 
    1585     if (!fSupportedOS)
    1586     {
    1587         LogRel(("DnD: Not supported Windows version, disabling drag and drop support\n"));
     1618    if (VbglR3AutoLogonIsRemoteSession())
     1619    {
     1620        /* Do not do drag and drop for remote sessions. */
     1621        LogRel(("DnD: Drag and drop has been disabled for a remote session\n"));
    15881622        rc = VERR_NOT_SUPPORTED;
    15891623    }
    15901624    else
    15911625        rc = VINF_SUCCESS;
     1626
     1627    if (RT_SUCCESS(rc))
     1628    {
     1629        s_pfnSendInput = (PFNSENDINPUT)
     1630            RTLdrGetSystemSymbol("User32.dll", "SendInput");
     1631        fSupportedOS = !RT_BOOL(s_pfnSendInput == NULL);
     1632        s_pfnEnumDisplayMonitors = (PFNENUMDISPLAYMONITORS)
     1633            RTLdrGetSystemSymbol("User32.dll", "EnumDisplayMonitors");
     1634        /* g_pfnEnumDisplayMonitors is optional. */
     1635
     1636        if (!fSupportedOS)
     1637        {
     1638            LogRel(("DnD: Not supported Windows version, disabling drag and drop support\n"));
     1639            rc = VERR_NOT_SUPPORTED;
     1640        }
     1641    }
    15921642
    15931643    if (RT_SUCCESS(rc))
     
    16191669    {
    16201670        *ppInstance = pCtx;
    1621         *pfStartThread = true;
    16221671
    16231672        LogRel(("DnD: Drag and drop service successfully started\n"));
    1624         return VINF_SUCCESS;
    1625     }
    1626 
    1627     LogRel(("DnD: Initializing drag and drop service failed with rc=%Rrc\n", rc));
     1673    }
     1674    else
     1675        LogRel(("DnD: Initializing drag and drop service failed with rc=%Rrc\n", rc));
     1676
     1677    LogFlowFuncLeaveRC(rc);
    16281678    return rc;
    16291679}
    16301680
    1631 void VBoxDnDStop(const VBOXSERVICEENV *pEnv, void *pInstance)
    1632 {
    1633     AssertPtrReturnVoid(pEnv);
    1634     AssertPtrReturnVoid(pInstance);
     1681DECLCALLBACK(int) VBoxDnDStop(void *pInstance)
     1682{
     1683    AssertPtrReturn(pInstance, VERR_INVALID_POINTER);
    16351684
    16361685    LogFunc(("Stopping pInstance=%p\n", pInstance));
     
    16411690    /* Set shutdown indicator. */
    16421691    ASMAtomicWriteBool(&pCtx->fShutdown, true);
    1643 }
    1644 
    1645 void VBoxDnDDestroy(const VBOXSERVICEENV *pEnv, void *pInstance)
    1646 {
    1647     AssertPtr(pEnv);
    1648     AssertPtr(pInstance);
     1692
     1693    /* Disconnect. */
     1694    VbglR3DnDDisconnect(&pCtx->cmdCtx);
     1695
     1696    LogFlowFuncLeaveRC(VINF_SUCCESS);
     1697    return VINF_SUCCESS;
     1698}
     1699
     1700DECLCALLBACK(void) VBoxDnDDestroy(void *pInstance)
     1701{
     1702    AssertPtrReturnVoid(pInstance);
    16491703
    16501704    LogFunc(("Destroying pInstance=%p\n", pInstance));
     
    16591713    VBoxDnDWnd *pWnd = pCtx->lstWnd.first();
    16601714    if (pWnd)
     1715    {
    16611716        delete pWnd;
     1717        pWnd = NULL;
     1718    }
    16621719
    16631720    if (pCtx->hEvtQueueSem != NIL_RTSEMEVENT)
    16641721        RTSemEventDestroy(pCtx->hEvtQueueSem);
    16651722
    1666     LogFunc(("Destroyed pInstance=%p, rc=%Rrc\n",
    1667              pInstance, rc));
    1668 }
    1669 
    1670 unsigned __stdcall VBoxDnDThread(void *pInstance)
    1671 {
     1723    LogFunc(("Destroyed pInstance=%p, rc=%Rrc\n", pInstance, rc));
     1724}
     1725
     1726DECLCALLBACK(int) VBoxDnDWorker(void *pInstance, bool volatile *pfShutdown)
     1727{
     1728    AssertPtr(pInstance);
    16721729    LogFlowFunc(("pInstance=%p\n", pInstance));
     1730
     1731    /*
     1732     * Tell the control thread that it can continue
     1733     * spawning services.
     1734     */
     1735    RTThreadUserSignal(RTThreadSelf());
    16731736
    16741737    PVBOXDNDCONTEXT pCtx = (PVBOXDNDCONTEXT)pInstance;
    16751738    AssertPtr(pCtx);
    16761739
    1677     VBGLR3GUESTDNDCMDCTX ctxDnD; /* The thread's own DnD context. */
    1678 
    1679     int rc = VbglR3DnDConnect(&ctxDnD);
     1740    int rc = VbglR3DnDConnect(&pCtx->cmdCtx);
    16801741    if (RT_FAILURE(rc))
    16811742        return rc;
     
    16881749    /* Number of invalid messages skipped in a row. */
    16891750    int cMsgSkippedInvalid = 0;
    1690 
    1691     do
    1692     {
    1693         PVBOXDNDEVENT pEvent = (PVBOXDNDEVENT)RTMemAlloc(sizeof(VBOXDNDEVENT));
     1751    PVBOXDNDEVENT pEvent = NULL;
     1752
     1753    for (;;)
     1754    {
     1755        pEvent = (PVBOXDNDEVENT)RTMemAllocZ(sizeof(VBOXDNDEVENT));
    16941756        if (!pEvent)
    16951757        {
     
    16991761        /* Note: pEvent will be free'd by the consumer later. */
    17001762
    1701         rc = VbglR3DnDProcessNextMessage(&ctxDnD, &pEvent->Event);
     1763        rc = VbglR3DnDProcessNextMessage(&pCtx->cmdCtx, &pEvent->Event);
    17021764        LogFlowFunc(("VbglR3DnDProcessNextMessage returned uType=%RU32, rc=%Rrc\n",
    17031765                     pEvent->Event.uType, rc));
    17041766
    1705         if (ASMAtomicReadBool(&pCtx->fShutdown))
    1706             break;
    1707 
    17081767        if (   RT_SUCCESS(rc)
    1709             || rc == VERR_CANCELLED)
     1768            /* Cancelled from host. */
     1769            || rc == VERR_CANCELLED
     1770            )
    17101771        {
    17111772            cMsgSkippedInvalid = 0; /* Reset skipped messages count. */
    17121773
    1713             LogFlowFunc(("Received new event, type=%RU32\n", pEvent->Event.uType));
    1714 
    1715             int rc2 = pWnd->ProcessEvent(pEvent);
    1716             if (RT_FAILURE(rc2))
    1717                 LogFlowFunc(("Processing event failed with rc=%Rrc\n", rc2));
     1774            LogFlowFunc(("Received new event, type=%RU32, rc=%Rrc\n", pEvent->Event.uType, rc));
     1775
     1776            rc = pWnd->ProcessEvent(pEvent);
     1777            if (RT_SUCCESS(rc))
     1778            {
     1779                /* Event was consumed and the proxy window till take care of the memory -- NULL it. */
     1780                pEvent = NULL;
     1781            }
     1782            else
     1783                LogFlowFunc(("Processing event failed with rc=%Rrc\n", rc));
     1784        }
     1785        else if (rc == VERR_INTERRUPTED) /* Disconnected from service. */
     1786        {
     1787            LogFlowFunc(("Posting quit message ...\n"));
     1788            pWnd->PostMessage(WM_QUIT, 0 /* wParm */, 0 /* lParm */);
     1789            rc = VINF_SUCCESS;
    17181790        }
    17191791        else
     
    17321804            }
    17331805
    1734             int rc2 = VbglR3DnDGHSendError(&ctxDnD, rc);
     1806            int rc2 = VbglR3DnDGHSendError(&pCtx->cmdCtx, rc);
    17351807            AssertRC(rc2);
    17361808        }
     
    17411813        if (RT_FAILURE(rc)) /* Don't hog the CPU on errors. */
    17421814            RTThreadSleep(1000 /* ms */);
    1743 
    1744     } while (true);
     1815    }
     1816
     1817    if (pEvent)
     1818    {
     1819        RTMemFree(pEvent);
     1820        pEvent = NULL;
     1821    }
    17451822
    17461823    LogFlowFunc(("Shutting down ...\n"));
    17471824
    1748     VbglR3DnDDisconnect(&ctxDnD);
     1825    VbglR3DnDDisconnect(&pCtx->cmdCtx);
    17491826
    17501827    LogFlowFuncLeaveRC(rc);
     
    17521829}
    17531830
     1831/**
     1832 * The service description.
     1833 */
     1834VBOXSERVICEDESC g_SvcDescDnD =
     1835{
     1836    /* pszName. */
     1837    "draganddrop",
     1838    /* pszDescription. */
     1839    "Drag and Drop",
     1840    /* methods */
     1841    VBoxDnDInit,
     1842    VBoxDnDWorker,
     1843    VBoxDnDStop,
     1844    VBoxDnDDestroy
     1845};
     1846
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.h

    r56661 r57741  
    2323#include <iprt/cpp/mtlist.h>
    2424#include <iprt/cpp/ministring.h>
    25 
    26 int                VBoxDnDInit    (const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread);
    27 unsigned __stdcall VBoxDnDThread  (void *pInstance);
    28 void               VBoxDnDStop    (const VBOXSERVICEENV *pEnv, void *pInstance);
    29 void               VBoxDnDDestroy (const VBOXSERVICEENV *pEnv, void *pInstance);
    3025
    3126class VBoxDnDWnd;
     
    225220    /** Shutdown indicator. */
    226221    bool                       fShutdown;
     222    /** The registered window class. */
     223    ATOM                       wndClass;
    227224    /** The DnD main event queue. */
    228225    RTCMTList<VBOXDNDEVENT>    lstEvtQueue;
     
    233230     *  Note: At the moment only one window is supported. */
    234231    RTCMTList<VBoxDnDWnd*>     lstWnd;
     232    /** The DnD command context. */
     233    VBGLR3GUESTDNDCMDCTX       cmdCtx;
    235234
    236235} VBOXDNDCONTEXT, *PVBOXDNDCONTEXT;
    237 static VBOXDNDCONTEXT gCtx = {0};
    238236
    239237/**
     
    335333#endif
    336334
     335    void PostMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
    337336    int ProcessEvent(PVBOXDNDEVENT pEvent);
    338337
     
    352351
    353352    /** Pointer to DnD context. */
    354     PVBOXDNDCONTEXT            pContext;
     353    PVBOXDNDCONTEXT            pCtx;
    355354    /** The proxy window's main thread for processing
    356355     *  window messages. */
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxHostVersion.cpp

    r51469 r57741  
    66
    77/*
    8  * Copyright (C) 2010-2014 Oracle Corporation
     8 * Copyright (C) 2010-2015 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3333/** @todo Move this part in VbglR3 and just provide a callback for the platform-specific
    3434          notification stuff, since this is very similar to the VBoxClient code. */
    35 int VBoxCheckHostVersion()
     35int VBoxCheckHostVersion(void)
    3636{
    3737    int rc;
     
    5858                                                "install option from the Devices menu.", pszGuestVersion, pszHostVersion);
    5959
    60                 rc = hlpShowBalloonTip(ghInstance, ghwndToolWindow, ID_TRAYICON,
     60                rc = hlpShowBalloonTip(g_hInstance, g_hwndToolWindow, ID_TRAYICON,
    6161                                       szMsg, szTitle,
    6262                                       5000 /* Time to display in msec */, NIIF_INFO);
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxIPC.cpp

    r51469 r57741  
    77
    88/*
    9  * Copyright (C) 2010-2014 Oracle Corporation
     9 * Copyright (C) 2010-2015 Oracle Corporation
    1010 *
    1111 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    5858
    5959} VBOXIPCCONTEXT, *PVBOXIPCCONTEXT;
    60 static VBOXIPCCONTEXT gCtx = {0};
     60
     61static VBOXIPCCONTEXT g_Ctx = { 0 };
    6162
    6263/** Function pointer for GetLastInputInfo(). */
     
    108109    {
    109110        /* Showing the balloon tooltip is not critical. */
    110         int rc2 = hlpShowBalloonTip(ghInstance, ghwndToolWindow, ID_TRAYICON,
     111        int rc2 = hlpShowBalloonTip(g_hInstance, g_hwndToolWindow, ID_TRAYICON,
    111112                                    ipcMsg.szMsgContent, ipcMsg.szMsgTitle,
    112113                                    ipcMsg.uShowMS, ipcMsg.uType);
     
    163164 * @return  IPRT status code.
    164165 * @param   pEnv                        The IPC service's environment.
    165  * @param   ppInstance                  The instance pointer which refer to this object.
    166  * @param   pfStartThread               Pointer to flag whether the IPC service can be started or not.
    167  */
    168 int VBoxIPCInit(const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread)
     166 * @param   ppInstance                  The instance pointer which refers to this object.
     167 */
     168DECLCALLBACK(int) VBoxIPCInit(const PVBOXSERVICEENV pEnv, void **ppInstance)
    169169{
    170170    AssertPtrReturn(pEnv, VERR_INVALID_POINTER);
    171     /** ppInstance not used here. */
    172     AssertPtrReturn(pfStartThread, VERR_INVALID_POINTER);
     171    AssertPtrReturn(ppInstance, VERR_INVALID_POINTER);
    173172
    174173    LogFlowFuncEnter();
    175174
    176     *pfStartThread = false;
    177 
    178     int rc = RTCritSectInit(&gCtx.CritSect);
     175    PVBOXIPCCONTEXT pCtx = &g_Ctx; /* Only one instance at the moment. */
     176    AssertPtr(pCtx);
     177
     178    int rc = RTCritSectInit(&pCtx->CritSect);
    179179    if (RT_SUCCESS(rc))
    180180    {
     
    195195                                VBOXTRAY_IPC_PIPE_PREFIX, pszUserName))
    196196                {
    197                     rc = RTLocalIpcServerCreate(&gCtx.hServer, szPipeName,
     197                    rc = RTLocalIpcServerCreate(&pCtx->hServer, szPipeName,
    198198                                                RTLOCALIPC_FLAGS_MULTI_SESSION);
    199199                    if (RT_SUCCESS(rc))
     
    201201                        RTStrFree(pszUserName);
    202202
    203                         gCtx.pEnv = pEnv;
    204                         RTListInit(&gCtx.SessionList);
    205 
    206                         *ppInstance = &gCtx;
    207                         *pfStartThread = true;
    208 
    209                         /* GetLastInputInfo only is available starting at Windows 2000. */
     203                        pCtx->pEnv = pEnv;
     204                        RTListInit(&pCtx->SessionList);
     205
     206                        *ppInstance = pCtx;
     207
     208                        /* GetLastInputInfo only is available starting at Windows 2000 -- might fail. */
    210209                        s_pfnGetLastInputInfo = (PFNGETLASTINPUTINFO)
    211210                            RTLdrGetSystemSymbol("User32.dll", "GetLastInputInfo");
    212211
    213                         LogRelFunc(("Local IPC server now running at \"%s\"\n",
    214                                     szPipeName));
     212                        LogRelFunc(("Local IPC server now running at \"%s\"\n", szPipeName));
    215213                        return VINF_SUCCESS;
    216214                    }
     
    224222        }
    225223
    226         RTCritSectDelete(&gCtx.CritSect);
     224        RTCritSectDelete(&pCtx->CritSect);
    227225    }
    228226
     
    231229}
    232230
    233 void VBoxIPCStop(const VBOXSERVICEENV *pEnv, void *pInstance)
    234 {
    235     AssertPtrReturnVoid(pEnv);
     231DECLCALLBACK(void) VBoxIPCStop(void *pInstance)
     232{
    236233    AssertPtrReturnVoid(pInstance);
    237234
     
    267264}
    268265
    269 void VBoxIPCDestroy(const VBOXSERVICEENV *pEnv, void *pInstance)
    270 {
    271     AssertPtrReturnVoid(pEnv);
     266DECLCALLBACK(void) VBoxIPCDestroy(void *pInstance)
     267{
    272268    AssertPtrReturnVoid(pInstance);
    273269
     
    476472        if (pSession)
    477473        {
    478             pSession->pCtx = pCtx;
    479             pSession->hSession = hSession;
     474            pSession->pCtx      = pCtx;
     475            pSession->hSession   = hSession;
    480476            pSession->fTerminate = false;
    481             pSession->hThread = NIL_RTTHREAD;
     477            pSession->hThread    = NIL_RTTHREAD;
    482478
    483479            /* Start IPC session thread. */
     
    485481            rc = RTThreadCreate(&pSession->hThread, vboxIPCSessionThread,
    486482                                pSession /* pvUser */, 0 /* Default stack size */,
    487                                 RTTHREADTYPE_DEFAULT, 0 /* Flags */, "VBXTRYIPCSESS");
     483                                RTTHREADTYPE_DEFAULT, 0 /* Flags */, "IPCSESSION");
    488484            if (RT_SUCCESS(rc))
    489485            {
     
    529525 * requests
    530526 */
    531 unsigned __stdcall VBoxIPCThread(void *pInstance)
    532 {
     527DECLCALLBACK(int) VBoxIPCWorker(void *pInstance, bool volatile *pfShutdown)
     528{
     529    AssertPtr(pInstance);
     530    LogFlowFunc(("pInstance=%p\n", pInstance));
     531
    533532    LogFlowFuncEnter();
     533
     534    /*
     535     * Tell the control thread that it can continue
     536     * spawning services.
     537     */
     538    RTThreadUserSignal(RTThreadSelf());
    534539
    535540    PVBOXIPCCONTEXT pCtx = (PVBOXIPCCONTEXT)pInstance;
    536541    AssertPtr(pCtx);
    537542
     543    int rc;
     544
    538545    bool fShutdown = false;
    539546    for (;;)
    540547    {
    541548        RTLOCALIPCSESSION hClientSession = NIL_RTLOCALIPCSESSION;
    542         int rc = RTLocalIpcServerListen(pCtx->hServer, &hClientSession);
     549        rc = RTLocalIpcServerListen(pCtx->hServer, &hClientSession);
    543550        if (RT_FAILURE(rc))
    544551        {
     
    561568        }
    562569
    563         AssertPtr(pCtx->pEnv);
    564         if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 0 /* No waiting */) == WAIT_OBJECT_0)
     570        if (*pfShutdown)
    565571            break;
    566572    }
    567573
    568     LogFlowFuncLeave();
    569     return 0;
    570 }
    571 
     574    LogFlowFuncLeaveRC(rc);
     575    return rc;
     576}
     577
     578/**
     579 * The service description.
     580 */
     581VBOXSERVICEDESC g_SvcDescIPC =
     582{
     583    /* pszName. */
     584    "IPC",
     585    /* pszDescription. */
     586    "Inter-Process Communication",
     587    /* methods */
     588    VBoxIPCInit,
     589    VBoxIPCWorker,
     590    NULL /* pfnStop */,
     591    VBoxIPCDestroy
     592};
     593
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxIPC.h

    r47195 r57741  
    2222
    2323int                VBoxIPCInit    (const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread);
    24 unsigned __stdcall VBoxIPCThread  (void *pInstance);
     24unsigned __stdcall VBoxIPCWorker  (void *pInstance);
    2525void               VBoxIPCStop    (const VBOXSERVICEENV *pEnv, void *pInstance);
    2626void               VBoxIPCDestroy (const VBOXSERVICEENV *pEnv, void *pInstance);
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxLA.cpp

    r51469 r57741  
    55
    66/*
    7  * Copyright (C) 2014 Oracle Corporation
     7 * Copyright (C) 2014-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    5454
    5555
    56 struct VBOXLACONTEXT
     56typedef struct _VBOXLACONTEXT
    5757{
    5858    const VBOXSERVICEENV *pEnv;
     
    9292
    9393    BOOL (WINAPI * pfnProcessIdToSessionId)(DWORD dwProcessId, DWORD *pSessionId);
    94 };
    95 
    96 typedef struct ACTIONENTRY
     94} VBOXLACONTEXT, *PVBOXLACONTEXT;
     95
     96typedef struct _ACTIONENTRY
    9797{
    9898    RTLISTNODE nodeActionEntry;
    9999    uint32_t u32Index;
    100100    WCHAR wszCommandLine[1];
    101 } ACTIONENTRY;
    102 
    103 
    104 static VBOXLACONTEXT gCtx = {0};
     101} ACTIONENTRY, *PACTIONENTRY;
     102
     103
     104static VBOXLACONTEXT g_Ctx = { 0 };
    105105
    106106static const char *g_pszPropActiveClient = "/VirtualBox/HostInfo/VRDP/ActiveClient";
     
    407407}
    408408
    409 static BOOL GetVolatileEnvironmentKey(WCHAR *pwszRegKey, DWORD cbRegKey)
     409static BOOL GetVolatileEnvironmentKey(PVBOXLACONTEXT pCtx, WCHAR *pwszRegKey, DWORD cbRegKey)
    410410{
    411411    BOOL fFound = FALSE;
     
    417417
    418418    /* Attempt to open HKCU\Volatile Environment\<session ID> first. */
    419     if (   gCtx.pfnProcessIdToSessionId != NULL
    420         && gCtx.pfnProcessIdToSessionId(GetCurrentProcessId(), &nSessionID))
     419    if (   pCtx->pfnProcessIdToSessionId
     420        && pCtx->pfnProcessIdToSessionId(GetCurrentProcessId(), &nSessionID))
    421421    {
    422422        RTStrPrintf(szRegKey, sizeof(szRegKey),
     
    485485}
    486486
    487 static BOOL GetUtcInfoClientName(WCHAR *pwszClientName, DWORD cbClientName)
     487static BOOL laGetUtcInfoClientName(PVBOXLACONTEXT pCtx, WCHAR *pwszClientName, DWORD cbClientName)
    488488{
    489489    LONG lErr;
    490490
    491491    WCHAR wszRegKey[REG_KEY_LEN];
    492     if (!GetVolatileEnvironmentKey(wszRegKey, sizeof(wszRegKey)))
     492    if (!GetVolatileEnvironmentKey(pCtx, wszRegKey, sizeof(wszRegKey)))
    493493    {
    494494        return FALSE;
     
    561561}
    562562
    563 static BOOL SetClientName(const WCHAR *pwszClientName)
     563static BOOL laSetClientName(PVBOXLACONTEXT pCtx, const WCHAR *pwszClientName)
    564564{
    565565    LONG lErr;
    566566
    567567    WCHAR wszRegKey[REG_KEY_LEN];
    568     if (!GetVolatileEnvironmentKey(wszRegKey, sizeof(wszRegKey)))
     568    if (!GetVolatileEnvironmentKey(pCtx, wszRegKey, sizeof(wszRegKey)))
    569569    {
    570570        return FALSE;
     
    613613                            &dwResult) == 0)
    614614    {
    615         LogFlowFunc(("SendMessageTimeout failed, error %d\n", GetLastError()));
    616     }
    617 }
    618 
    619 static void laUpdateClientName(VBOXLACONTEXT *pCtx)
     615        LogFlowFunc(("SendMessageTimeout failed, error %ld\n", GetLastError()));
     616    }
     617}
     618
     619static void laUpdateClientName(PVBOXLACONTEXT pCtx)
    620620{
    621621    WCHAR wszUtcInfoClientName[MAX_CLIENT_NAME_CHARS];
    622622
    623     if (GetUtcInfoClientName(wszUtcInfoClientName, sizeof(wszUtcInfoClientName)))
    624     {
    625         if (SetClientName(wszUtcInfoClientName))
    626         {
     623    if (laGetUtcInfoClientName(pCtx, wszUtcInfoClientName, sizeof(wszUtcInfoClientName)))
     624    {
     625        if (laSetClientName(pCtx, wszUtcInfoClientName))
    627626            laBroadcastSettingChange();
    628         }
    629     }
    630 }
    631 
    632 static void laOnClientLocationInfo(char *pszClientInfo[][2])
     627    }
     628}
     629
     630static void laOnClientLocationInfo(PVBOXLACONTEXT pCtx, char *pszClientInfo[][2])
    633631{
    634632    /*
     
    642640    unsigned int idx;
    643641    WCHAR wszRegKey[REG_KEY_LEN];
    644     if (!GetVolatileEnvironmentKey(wszRegKey, sizeof(wszRegKey)))
     642    if (!GetVolatileEnvironmentKey(pCtx, wszRegKey, sizeof(wszRegKey)))
    645643    {
    646644        LogFlowFunc(("Failed to get 'Volatile Environment' registry key\n"));
     
    660658    if (lRet != ERROR_SUCCESS)
    661659    {
    662         LogFlowFunc(("Failed to open key [%ls], error %lu\n",
    663                wszRegKey, lRet));
     660        LogFlowFunc(("Failed to open key [%ls], error %lu\n", wszRegKey, lRet));
    664661        return;
    665662    }
     
    716713}
    717714
    718 static void laDoAttach(VBOXLACONTEXT *pCtx)
     715static void laDoAttach(PVBOXLACONTEXT pCtx)
    719716{
    720717    LogFlowFunc(("laDoAttach\n"));
     
    727724}
    728725
    729 static void laDoDetach(VBOXLACONTEXT *pCtx)
     726static void laDoDetach(PVBOXLACONTEXT pCtx)
    730727{
    731728    LogFlowFunc(("laDoDetach\n"));
     
    836833
    837834        if (rc != VERR_BUFFER_OVERFLOW)
    838         {
    839835            break;
    840         }
    841836
    842837        cbBuf += 1024;
     
    877872
    878873    if (pszValue)
    879     {
    880874        RTMemFree(pszValue);
    881     }
    882 
    883     LogFlowFunc(("laGetUint32: rc = %Rrc, [%s]\n",
    884            rc, pszName));
    885 
     875
     876    LogFlowFunc(("laGetUint32: rc = %Rrc, [%s]\n", rc, pszName));
    886877    return rc;
    887878}
     
    894885                           ppszValue);
    895886
    896     LogFlowFunc(("laGetString: rc = %Rrc, [%s]\n",
    897            rc, pszName));
    898 
     887    LogFlowFunc(("laGetString: rc = %Rrc, [%s]\n", rc, pszName));
    899888    return rc;
    900889}
    901890
    902 static int laGetActiveClient(VBOXLACONTEXT *pCtx, uint64_t *pu64Timestamp, uint32_t *pu32Value)
     891static int laGetActiveClient(PVBOXLACONTEXT pCtx, uint64_t *pu64Timestamp, uint32_t *pu32Value)
    903892{
    904893    int rc = laGetUint32(pCtx->u32GuestPropHandle,
     
    907896                         pu32Value);
    908897
    909     LogFlowFunc(("laGetActiveClient: rc %Rrc, %d, %lld\n", rc, *pu32Value, *pu64Timestamp));
    910 
     898    LogFlowFunc(("laGetActiveClient: rc %Rrc, %RU32, %RU64\n", rc, *pu32Value, *pu64Timestamp));
    911899    return rc;
    912900}
    913901
    914 static int laUpdateCurrentState(VBOXLACONTEXT *pCtx, uint32_t u32ActiveClientId, uint64_t u64ActiveClientTS)
     902static int laUpdateCurrentState(PVBOXLACONTEXT pCtx, uint32_t u32ActiveClientId, uint64_t u64ActiveClientTS)
    915903{
    916904    /* Prepare the current state for the active client.
    917905     * If u32ActiveClientId is 0, then there is no connected clients.
    918906     */
    919     LogFlowFunc(("laUpdateCurrentState: %u %lld\n",
    920             u32ActiveClientId, u64ActiveClientTS));
     907    LogFlowFunc(("laUpdateCurrentState: %RU32 %RU64\n", u32ActiveClientId, u64ActiveClientTS));
    921908
    922909    int rc = VINF_SUCCESS;
     
    10191006    }
    10201007
    1021     LogFlowFunc(("laUpdateCurrentState rc = %Rrc\n",
    1022            rc));
    1023 
     1008    LogFlowFunc(("laUpdateCurrentState rc = %Rrc\n", rc));
    10241009    return rc;
    10251010}
    10261011
    1027 static int laWait(VBOXLACONTEXT *pCtx, uint64_t *pu64Timestamp, uint32_t u32Timeout)
    1028 {
    1029     LogFlowFunc(("laWait [%s]\n",
    1030            pCtx->activeClient.pszPropWaitPattern));
     1012static int laWait(PVBOXLACONTEXT pCtx, uint64_t *pu64Timestamp, uint32_t u32Timeout)
     1013{
     1014    LogFlowFunc(("laWait [%s]\n", pCtx->activeClient.pszPropWaitPattern));
    10311015
    10321016    int rc = laWaitProperties(pCtx->u32GuestPropHandle,
     
    10361020                              u32Timeout);
    10371021
    1038     LogFlowFunc(("laWait rc %Rrc\n",
    1039            rc));
    1040 
     1022    LogFlowFunc(("laWait rc %Rrc\n", rc));
    10411023    return rc;
    10421024}
    10431025
    1044 static void laProcessClientInfo(VBOXLACONTEXT *pCtx)
     1026static void laProcessClientInfo(PVBOXLACONTEXT pCtx)
    10451027{
    10461028    /* Check if the name was changed. */
     
    10661048                         &pClientInfoMap[idx][LA_UTCINFO_PROP_VALUE]);
    10671049
    1068          LogFlowFunc(("laProcessClientInfo: read [%s], at %lld\n",
    1069                 pClientInfoMap[idx][LA_UTCINFO_PROP_VALUE], u64Timestamp));
     1050         LogFlowFunc(("laProcessClientInfo: read [%s], at %RU64\n",
     1051                      pClientInfoMap[idx][LA_UTCINFO_PROP_VALUE], u64Timestamp));
    10701052
    10711053        if (RT_FAILURE(rc))
     
    10801062        if (u64Timestamp != pCtx->activeClient.u64LastNameTimestamp)
    10811063        {
    1082             laOnClientLocationInfo(pClientInfoMap);
     1064            laOnClientLocationInfo(pCtx, pClientInfoMap);
    10831065
    10841066            pCtx->activeClient.u64LastNameTimestamp = u64Timestamp;
     
    10951077}
    10961078
    1097 static void laProcessAttach(VBOXLACONTEXT *pCtx)
     1079static void laProcessAttach(PVBOXLACONTEXT pCtx)
    10981080{
    10991081    /* Check if the attach was changed. */
     
    11101092    if (RT_SUCCESS(rc))
    11111093    {
    1112         LogFlowFunc(("laProcessAttach: read %d, at %lld\n",
    1113                u32Attach, u64Timestamp));
    1114 
     1094        LogFlowFunc(("laProcessAttach: read %RU32, at %RU64\n", u32Attach, u64Timestamp));
    11151095        if (u64Timestamp != pCtx->activeClient.u64LastAttachTimestamp)
    11161096        {
     
    11201100
    11211101                /* Just do the last action. */
    1122                 pCtx->u32Action = u32Attach?
    1123                                        LA_DO_ATTACH:
    1124                                        LA_DO_DETACH;
     1102                pCtx->u32Action = u32Attach
     1103                                ? LA_DO_ATTACH : LA_DO_DETACH;
    11251104
    11261105                pCtx->activeClient.u32LastAttach = u32Attach;
     
    11331112                 * which means that it was changed and restored.
    11341113                 */
    1135                 pCtx->u32Action = u32Attach?
    1136                                        LA_DO_DETACH_AND_ATTACH:
    1137                                        LA_DO_ATTACH_AND_DETACH;
     1114                pCtx->u32Action = u32Attach
     1115                                ? LA_DO_DETACH_AND_ATTACH : LA_DO_ATTACH_AND_DETACH;
    11381116            }
    11391117
     
    11431121    }
    11441122
    1145     LogFlowFunc(("laProcessAttach: action %d\n",
    1146            pCtx->u32Action));
    1147 }
    1148 
    1149 static void laDoActions(VBOXLACONTEXT *pCtx)
    1150 {
    1151     /* Check if the attach was changed.
     1123    LogFlowFunc(("laProcessAttach: action %RU32\n", pCtx->u32Action));
     1124}
     1125
     1126static void laDoActions(PVBOXLACONTEXT pCtx)
     1127{
     1128    /*
     1129     * Check if the attach was changed.
    11521130     *
    11531131     * Caller assumes that this function will filter double actions.
    11541132     * That is two or more LA_DO_ATTACH will do just one LA_DO_ATTACH.
    11551133     */
    1156     LogFlowFunc(("laDoActions: action %d, prev %d\n",
    1157            pCtx->u32Action, pCtx->u32PrevAction));
     1134    LogFlowFunc(("laDoActions: action %RU32, prev %RU32\n", pCtx->u32Action, pCtx->u32PrevAction));
    11581135
    11591136    switch(pCtx->u32Action)
     
    12091186}
    12101187
    1211 int VBoxLAInit(const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread)
    1212 {
    1213     gCtx.pEnv = pEnv;
     1188DECLCALLBACK(int) VBoxLAInit(const PVBOXSERVICEENV pEnv, void **ppInstance)
     1189{
     1190    AssertPtrReturn(pEnv, VERR_INVALID_POINTER);
     1191    AssertPtrReturn(ppInstance, VERR_INVALID_POINTER);
     1192
     1193    LogFlowFuncEnter();
     1194
     1195    PVBOXLACONTEXT pCtx = &g_Ctx; /* Only one instance at the moment. */
     1196    AssertPtr(pCtx);
     1197
     1198    pCtx->pEnv = pEnv;
    12141199
    12151200    DWORD dwValue = 0;
     
    12171202        && (dwValue & 0x10) != 0)
    12181203    {
    1219          gCtx.fLogEnabled = true;
     1204         pCtx->fLogEnabled = true;
    12201205    }
    12211206    else
    12221207    {
    1223          gCtx.fLogEnabled = false;
    1224     }
    1225 
    1226     LogFlowFunc(("\n"));
     1208         pCtx->fLogEnabled = false;
     1209    }
    12271210
    12281211    /* DetachOnDisconnect is enabled by default. */
     
    12311214        && (dwValue & 0x02) == 0)
    12321215    {
    1233          gCtx.fDetachOnDisconnect = false;
     1216         pCtx->fDetachOnDisconnect = false;
    12341217    }
    12351218    else
    12361219    {
    1237          gCtx.fDetachOnDisconnect = true;
    1238     }
    1239 
    1240     LogRel(("LA: DetachOnDisconnect=%RTbool\n", gCtx.fDetachOnDisconnect));
    1241 
    1242     int rc = VbglR3GuestPropConnect(&gCtx.u32GuestPropHandle);
     1220         pCtx->fDetachOnDisconnect = true;
     1221    }
     1222
     1223    LogRel(("LA: DetachOnDisconnect=%RTbool\n", pCtx->fDetachOnDisconnect));
     1224
     1225    int rc = VbglR3GuestPropConnect(&pCtx->u32GuestPropHandle);
    12431226    if (RT_FAILURE(rc))
    1244     {
    12451227        return rc;
    1246     }
    1247 
    1248     RTListInit(&gCtx.listAttachActions);
    1249     RTListInit(&gCtx.listDetachActions);
    1250 
    1251     RT_ZERO(gCtx.activeClient);
    1252 
    1253     *(void **)&gCtx.pfnProcessIdToSessionId = RTLdrGetSystemSymbol("kernel32.dll", "ProcessIdToSessionId");
    1254     *pfStartThread = true;
    1255     *ppInstance = &gCtx;
     1228
     1229    RTListInit(&pCtx->listAttachActions);
     1230    RTListInit(&pCtx->listDetachActions);
     1231
     1232    RT_ZERO(pCtx->activeClient);
     1233
     1234    *(void **)&pCtx->pfnProcessIdToSessionId = RTLdrGetSystemSymbol("kernel32.dll", "ProcessIdToSessionId");
     1235
     1236    *ppInstance = pCtx;
     1237    LogFlowFuncLeaveRC(VINF_SUCCESS);
    12561238    return VINF_SUCCESS;
    12571239}
    12581240
    1259 
    1260 void VBoxLADestroy(const VBOXSERVICEENV *pEnv, void *pInstance)
    1261 {
    1262     LogFlowFuncEnter();
    1263 
    1264     VBOXLACONTEXT *pCtx = (VBOXLACONTEXT *)pInstance;
     1241DECLCALLBACK(void) VBoxLADestroy(void *pInstance)
     1242{
     1243    AssertPtrReturnVoid(pInstance);
     1244
     1245    LogFlowFunc(("Destroying pInstance=%p\n", pInstance));
     1246
     1247    PVBOXLACONTEXT pCtx = (PVBOXLACONTEXT)pInstance;
     1248    AssertPtr(pCtx);
    12651249
    12661250    if (pCtx->u32GuestPropHandle != 0)
     
    12781262 * Thread function to wait for and process property changes
    12791263 */
    1280 unsigned __stdcall VBoxLAThread(void *pInstance)
    1281 {
    1282     VBOXLACONTEXT *pCtx = (VBOXLACONTEXT *)pInstance;
    1283 
    1284     LogFlowFunc(("Started\n"));
     1264DECLCALLBACK(int) VBoxLAWorker(void *pInstance, bool volatile *pfShutdown)
     1265{
     1266    AssertPtr(pInstance);
     1267    LogFlowFunc(("pInstance=%p\n", pInstance));
     1268
     1269    /*
     1270     * Tell the control thread that it can continue
     1271     * spawning services.
     1272     */
     1273    RTThreadUserSignal(RTThreadSelf());
     1274
     1275    PVBOXLACONTEXT pCtx = (PVBOXLACONTEXT)pInstance;
    12851276
    12861277    /*
     
    12951286     */
    12961287
    1297     if (!ActionExecutorEnumerateRegistryKey(g_pwszRegKeyReconnectActions, &gCtx.listAttachActions))
     1288    if (!ActionExecutorEnumerateRegistryKey(g_pwszRegKeyReconnectActions, &pCtx->listAttachActions))
    12981289    {
    12991290        LogFlowFunc(("Can't enumerate registry key %ls\n", g_pwszRegKeyReconnectActions));
    13001291    }
    1301     if (!ActionExecutorEnumerateRegistryKey(g_pwszRegKeyDisconnectActions, &gCtx.listDetachActions))
     1292    if (!ActionExecutorEnumerateRegistryKey(g_pwszRegKeyDisconnectActions, &pCtx->listDetachActions))
    13021293    {
    13031294        LogFlowFunc(("Can't enumerate registry key %ls\n", g_pwszRegKeyDisconnectActions));
     
    13081299    /* Start at Detached state. */
    13091300    pCtx->u32PrevAction = LA_DO_DETACH;
     1301
     1302    int rc;
    13101303
    13111304    for (;;)
     
    13231316        uint64_t u64Timestamp = 0;
    13241317        uint32_t u32ActiveClientId = 0;
    1325         int rc = laGetActiveClient(pCtx, &u64Timestamp, &u32ActiveClientId);
     1318        rc = laGetActiveClient(pCtx, &u64Timestamp, &u32ActiveClientId);
    13261319
    13271320        if (RT_SUCCESS(rc))
     
    13571350                        && fClientIdChanged)
    13581351                    {
    1359                         LogFlowFunc(("client disconnected\n"));
     1352                        LogFlowFunc(("Client disconnected\n"));
    13601353
    13611354                        /* laDoActions will prevent a repeated detach action. So if there
     
    13721365        }
    13731366
    1374         /* Check if it is time to exit.
     1367        /*
     1368         * Check if it is time to exit.
    13751369         * If the code above failed, wait a bit until repeating to avoid a loop.
    13761370         * Otherwise just check if the stop event was signalled.
    13771371         */
    1378         uint32_t u32Wait;
     1372        RTMSINTERVAL msWait;
    13791373        if (   rc == VERR_NOT_FOUND
    13801374            || pCtx->activeClient.u32ClientId == 0)
    13811375        {
    13821376            /* No connections, wait longer. */
    1383             u32Wait = 5000;
     1377            msWait = 5000;
     1378            rc = VINF_SUCCESS;
    13841379        }
    13851380        else if (RT_FAILURE(rc))
    13861381        {
    1387             u32Wait = 1000;
     1382            static int s_iBitchedAboutFailedGetActiveClient = 0;
     1383            if (s_iBitchedAboutFailedGetActiveClient++ < 32)
     1384                LogRel(("LA: Retrieving current client(s) failed with %Rrc\n", rc));
     1385
     1386            msWait = 10000;
    13881387        }
    13891388        else
    1390         {
    1391             u32Wait = 0;
    1392         }
    1393         if (WaitForSingleObject(pCtx->pEnv->hStopEvent, u32Wait) == WAIT_OBJECT_0)
    1394         {
     1389            msWait = 0;
     1390
     1391        if (*pfShutdown)
    13951392            break;
    1396         }
    1397     }
    1398 
    1399     LogFlowFunc(("Finished\n"));
    1400     return 0;
    1401 }
     1393
     1394        if (msWait)
     1395            RTThreadSleep(msWait);
     1396    }
     1397
     1398    LogFlowFuncLeaveRC(rc);
     1399    return rc;
     1400}
     1401
     1402/**
     1403 * The service description.
     1404 */
     1405VBOXSERVICEDESC g_SvcDescLA =
     1406{
     1407    /* pszName. */
     1408    "LA",
     1409    /* pszDescription. */
     1410    "Location Awareness",
     1411    /* methods */
     1412    VBoxLAInit,
     1413    VBoxLAWorker,
     1414    NULL /* pfnStop */,
     1415    VBoxLADestroy
     1416};
     1417
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxLA.h

    r40498 r57741  
    55
    66/*
    7  * Copyright (C) 2012 Oracle Corporation
     7 * Copyright (C) 2012-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1919#define __VBOXSERVICELA__H
    2020
    21 int                VBoxLAInit    (const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread);
    22 unsigned __stdcall VBoxLAThread  (void *pInstance);
    23 void               VBoxLADestroy (const VBOXSERVICEENV *pEnv, void *pInstance);
     21#endif /* __VBOXSERVICELA__H */
    2422
    25 #endif /* __VBOXSERVICELA__H */
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxSeamless.cpp

    r51469 r57741  
    55
    66/*
    7  * Copyright (C) 2006-2014 Oracle Corporation
     7 * Copyright (C) 2006-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4949
    5050    PVBOXDISPIFESCAPE lpEscapeData;
    51 } VBOXSEAMLESSCONTEXT;
     51} VBOXSEAMLESSCONTEXT, *PVBOXSEAMLESSCONTEXT;
    5252
    5353typedef struct
     
    5757} VBOX_ENUM_PARAM, *PVBOX_ENUM_PARAM;
    5858
    59 static VBOXSEAMLESSCONTEXT gCtx = {0};
     59static VBOXSEAMLESSCONTEXT g_Ctx = { 0 };
    6060
    6161void VBoxLogString(HANDLE hDriver, char *pszStr);
    6262
    63 int VBoxSeamlessInit(const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread)
    64 {
    65     Log(("VBoxTray: VBoxSeamlessInit\n"));
    66 
    67     *pfStartThread = false;
    68     gCtx.pEnv = pEnv;
    69     gCtx.hModHook = NIL_RTLDRMOD;
     63DECLCALLBACK(int) VBoxSeamlessInit(const PVBOXSERVICEENV pEnv, void **ppInstance)
     64{
     65    LogFlowFuncEnter();
     66
     67    PVBOXSEAMLESSCONTEXT pCtx = &g_Ctx; /* Only one instance at the moment. */
     68    AssertPtr(pCtx);
     69
     70    pCtx->pEnv     = pEnv;
     71    pCtx->hModHook = NIL_RTLDRMOD;
    7072
    7173    OSVERSIONINFO OSinfo;
     
    7375    GetVersionEx (&OSinfo);
    7476
    75     int rc = VINF_SUCCESS;
     77    int rc;
    7678
    7779    /* We have to jump out here when using NT4, otherwise it complains about
     
    8587    {
    8688        /* Will fail if SetWinEventHook is not present (version < NT4 SP6 apparently) */
    87         rc = RTLdrLoadAppPriv(VBOXHOOK_DLL_NAME, &gCtx.hModHook);
     89        rc = RTLdrLoadAppPriv(VBOXHOOK_DLL_NAME, &pCtx->hModHook);
    8890        if (RT_SUCCESS(rc))
    8991        {
    90             *(PFNRT *)&gCtx.pfnVBoxHookInstallWindowTracker = RTLdrGetFunction(gCtx.hModHook, "VBoxHookInstallWindowTracker");
    91             *(PFNRT *)&gCtx.pfnVBoxHookRemoveWindowTracker  = RTLdrGetFunction(gCtx.hModHook, "VBoxHookRemoveWindowTracker");
     92            *(PFNRT *)&pCtx->pfnVBoxHookInstallWindowTracker = RTLdrGetFunction(pCtx->hModHook, "VBoxHookInstallWindowTracker");
     93            *(PFNRT *)&pCtx->pfnVBoxHookRemoveWindowTracker  = RTLdrGetFunction(pCtx->hModHook, "VBoxHookRemoveWindowTracker");
    9294
    9395            /* rc should contain success status */
    94             AssertRC(rc);
     96            AssertRC(rc); /** @todo r=andy Makes no sense here!? */
    9597
    9698            VBoxSeamlessSetSupported(TRUE);
    9799
    98 //            if (RT_SUCCESS(rc))
    99             {
    100                 *pfStartThread = true;
    101                 *ppInstance = &gCtx;
    102             }
     100            *ppInstance = pCtx;
    103101        }
    104102        else
    105             Log(("VBoxTray: VBoxSeamlessInit: LoadLibrary of \"%s\" failed with rc=%Rrc\n", VBOXHOOK_DLL_NAME, rc));
    106     }
    107 
     103            LogFlowFunc(("Unable to load %s, rc=%Rrc\n", VBOXHOOK_DLL_NAME, rc));
     104    }
     105
     106    LogFlowFuncLeaveRC(rc);
    108107    return rc;
    109108}
    110109
    111 
    112 void VBoxSeamlessDestroy(const VBOXSERVICEENV *pEnv, void *pInstance)
    113 {
    114     Log(("VBoxTray: VBoxSeamlessDestroy\n"));
     110void VBoxSeamlessDestroy(void *pInstance)
     111{
     112    LogFlowFuncEnter();
     113
     114    PVBOXSEAMLESSCONTEXT pCtx = (PVBOXSEAMLESSCONTEXT)pInstance;
     115    AssertPtr(pCtx);
    115116
    116117    VBoxSeamlessSetSupported(FALSE);
    117118
    118119    /* Inform the host that we no longer support the seamless window mode. */
    119     if (gCtx.pfnVBoxHookRemoveWindowTracker)
    120         gCtx.pfnVBoxHookRemoveWindowTracker();
    121     if (gCtx.hModHook != NIL_RTLDRMOD)
    122     {
    123         RTLdrClose(gCtx.hModHook);
    124         gCtx.hModHook = NIL_RTLDRMOD;
     120    if (pCtx->pfnVBoxHookRemoveWindowTracker)
     121        pCtx->pfnVBoxHookRemoveWindowTracker();
     122    if (pCtx->hModHook != NIL_RTLDRMOD)
     123    {
     124        RTLdrClose(pCtx->hModHook);
     125        pCtx->hModHook = NIL_RTLDRMOD;
    125126    }
    126127    return;
    127128}
    128129
    129 static void VBoxSeamlessInstallHook()
    130 {
    131     if (gCtx.pfnVBoxHookInstallWindowTracker)
     130static void VBoxSeamlessInstallHook(void)
     131{
     132    PVBOXSEAMLESSCONTEXT pCtx = &g_Ctx; /** @todo r=andy Use instance data via service lookup (add void *pInstance). */
     133    AssertPtr(pCtx);
     134
     135    if (pCtx->pfnVBoxHookInstallWindowTracker)
    132136    {
    133137        /* Check current visible region state */
    134138        VBoxSeamlessCheckWindows(true);
    135139
    136         HMODULE hMod = (HMODULE)RTLdrGetNativeHandle(gCtx.hModHook);
     140        HMODULE hMod = (HMODULE)RTLdrGetNativeHandle(pCtx->hModHook);
    137141        Assert(hMod != (HMODULE)~(uintptr_t)0);
    138         gCtx.pfnVBoxHookInstallWindowTracker(hMod);
    139     }
    140 }
    141 
    142 static void VBoxSeamlessRemoveHook()
    143 {
    144     if (gCtx.pfnVBoxHookRemoveWindowTracker)
    145         gCtx.pfnVBoxHookRemoveWindowTracker();
    146 
    147     if (gCtx.lpEscapeData)
    148     {
    149         free(gCtx.lpEscapeData);
    150         gCtx.lpEscapeData = NULL;
    151     }
    152 }
    153 
    154 extern HANDLE ghSeamlessKmNotifyEvent;
    155 
    156 static VBOXDISPIF_SEAMLESS gVBoxDispIfSeamless;
    157 
    158 
    159 void VBoxSeamlessEnable()
    160 {
    161     Assert(ghSeamlessKmNotifyEvent);
    162 
    163     VBoxDispIfSeamlesCreate(&gCtx.pEnv->dispIf, &gVBoxDispIfSeamless, ghSeamlessKmNotifyEvent);
     142        pCtx->pfnVBoxHookInstallWindowTracker(hMod);
     143    }
     144}
     145
     146static void VBoxSeamlessRemoveHook(void)
     147{
     148    PVBOXSEAMLESSCONTEXT pCtx = &g_Ctx; /** @todo r=andy Use instance data via service lookup (add void *pInstance). */
     149    AssertPtr(pCtx);
     150
     151    if (pCtx->pfnVBoxHookRemoveWindowTracker)
     152        pCtx->pfnVBoxHookRemoveWindowTracker();
     153
     154    if (pCtx->lpEscapeData)
     155    {
     156        free(pCtx->lpEscapeData);
     157        pCtx->lpEscapeData = NULL;
     158    }
     159}
     160
     161extern HANDLE g_hSeamlessKmNotifyEvent;
     162
     163static VBOXDISPIF_SEAMLESS gVBoxDispIfSeamless; /** @todo r=andy Move this into VBOXSEAMLESSCONTEXT? */
     164
     165
     166void VBoxSeamlessEnable(void)
     167{
     168    PVBOXSEAMLESSCONTEXT pCtx = &g_Ctx; /** @todo r=andy Use instance data via service lookup (add void *pInstance). */
     169    AssertPtr(pCtx);
     170
     171    Assert(g_hSeamlessKmNotifyEvent);
     172
     173    VBoxDispIfSeamlessCreate(&pCtx->pEnv->dispIf, &gVBoxDispIfSeamless, g_hSeamlessKmNotifyEvent);
    164174
    165175    VBoxSeamlessInstallHook();
    166176}
    167177
    168 void VBoxSeamlessDisable()
    169 {
     178void VBoxSeamlessDisable(void)
     179{
     180    PVBOXSEAMLESSCONTEXT pCtx = &g_Ctx; /** @todo r=andy Use instance data via service lookup (add void *pInstance). */
     181    AssertPtr(pCtx);
     182    NOREF(pCtx);
     183
    170184    VBoxSeamlessRemoveHook();
    171185
    172     VBoxDispIfSeamlesTerm(&gVBoxDispIfSeamless);
     186    VBoxDispIfSeamlessTerm(&gVBoxDispIfSeamless);
    173187}
    174188
     
    279293void VBoxSeamlessCheckWindows(bool fForce)
    280294{
     295    PVBOXSEAMLESSCONTEXT pCtx = &g_Ctx; /** @todo r=andy Use instance data via service lookup (add void *pInstance). */
     296    AssertPtr(pCtx);
     297
    281298    if (!VBoxDispIfSeamlesIsValid(&gVBoxDispIfSeamless))
    282299        return;
     
    314331                    }
    315332#endif
    316                     LPRGNDATA lpCtxRgnData = VBOXDISPIFESCAPE_DATA(gCtx.lpEscapeData, RGNDATA);
     333                    LPRGNDATA lpCtxRgnData = VBOXDISPIFESCAPE_DATA(pCtx->lpEscapeData, RGNDATA);
    317334                    if (fForce
    318                         ||  !gCtx.lpEscapeData
     335                        ||  !pCtx->lpEscapeData
    319336                        ||  (lpCtxRgnData->rdh.dwSize + lpCtxRgnData->rdh.nRgnSize != cbSize)
    320337                        ||  memcmp(lpCtxRgnData, lpRgnData, cbSize))
    321338                    {
    322339                        /* send to display driver */
    323                         VBoxDispIfSeamlesSubmit(&gVBoxDispIfSeamless, lpEscapeData, cbSize);
    324 
    325                         if (gCtx.lpEscapeData)
    326                             free(gCtx.lpEscapeData);
    327                         gCtx.lpEscapeData = lpEscapeData;
     340                        VBoxDispIfSeamlessSubmit(&gVBoxDispIfSeamless, lpEscapeData, cbSize);
     341
     342                        if (pCtx->lpEscapeData)
     343                            free(pCtx->lpEscapeData);
     344                        pCtx->lpEscapeData = lpEscapeData;
    328345                    }
    329346                    else
    330347                        Log(("VBoxTray: Visible rectangles haven't changed; ignore\n"));
    331348                }
    332                 if (lpEscapeData != gCtx.lpEscapeData)
     349                if (lpEscapeData != pCtx->lpEscapeData)
    333350                    free(lpEscapeData);
    334351            }
     
    345362 * requests
    346363 */
    347 unsigned __stdcall VBoxSeamlessThread(void *pInstance)
    348 {
    349     VBOXSEAMLESSCONTEXT *pCtx = (VBOXSEAMLESSCONTEXT *)pInstance;
     364static DECLCALLBACK(int) VBoxSeamlessWorker(void *pInstance, bool volatile *pfShutdown)
     365{
     366    AssertPtrReturn(pInstance, VERR_INVALID_POINTER);
     367    LogFlowFunc(("pInstance=%p\n", pInstance));
     368
     369    /*
     370     * Tell the control thread that it can continue
     371     * spawning services.
     372     */
     373    RTThreadUserSignal(RTThreadSelf());
     374
     375    PVBOXSEAMLESSCONTEXT pCtx = (PVBOXSEAMLESSCONTEXT)pInstance;
     376
    350377    HANDLE gVBoxDriver = pCtx->pEnv->hDriver;
    351     bool fTerminate = false;
    352378    VBoxGuestFilterMaskInfo maskInfo;
    353379    DWORD cbReturned;
    354     BOOL fWasScreenSaverActive = FALSE, ret;
     380    BOOL fWasScreenSaverActive = FALSE, fRet;
    355381
    356382    maskInfo.u32OrMask = VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST;
    357383    maskInfo.u32NotMask = 0;
    358     if (DeviceIoControl (gVBoxDriver, VBOXGUEST_IOCTL_CTL_FILTER_MASK, &maskInfo, sizeof (maskInfo), NULL, 0, &cbReturned, NULL))
    359     {
    360         Log(("VBoxTray: VBoxSeamlessThread: DeviceIOControl(CtlMask - or) succeeded\n"));
    361     }
    362     else
    363     {
    364         Log(("VBoxTray: VBoxSeamlessThread: DeviceIOControl(CtlMask) failed, SeamlessChangeThread exited\n"));
    365         return 0;
    366     }
    367 
    368     do
     384    if (!DeviceIoControl(gVBoxDriver, VBOXGUEST_IOCTL_CTL_FILTER_MASK, &maskInfo, sizeof (maskInfo), NULL, 0, &cbReturned, NULL))
     385    {
     386        DWORD dwErr = GetLastError();
     387        LogRel(("Seamless: DeviceIOControl(CtlMask) failed with %ld, exiting ...\n", dwErr));
     388        return RTErrConvertFromWin32(dwErr);
     389    }
     390
     391    int rc = VINF_SUCCESS;
     392
     393    for (;;)
    369394    {
    370395        /* wait for a seamless change event */
     
    374399        if (DeviceIoControl(gVBoxDriver, VBOXGUEST_IOCTL_WAITEVENT, &waitEvent, sizeof(waitEvent), &waitEvent, sizeof(waitEvent), &cbReturned, NULL))
    375400        {
    376             Log(("VBoxTray: VBoxSeamlessThread: DeviceIOControl succeeded\n"));
    377 
    378401            /* are we supposed to stop? */
    379             if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 0) == WAIT_OBJECT_0)
     402            if (*pfShutdown)
    380403                break;
    381 
    382             Log(("VBoxTray: VBoxSeamlessThread: checking event\n"));
    383404
    384405            /* did we get the right event? */
    385406            if (waitEvent.u32EventFlagsOut & VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST)
    386407            {
    387                 Log(("VBoxTray: VBoxTray: going to get seamless change information\n"));
    388 
    389408                /* We got at least one event. Read the requested resolution
    390409                 * and try to set it until success. New events will not be seen
     
    402421                    if (fSeamlessChangeQueried)
    403422                    {
    404                         Log(("VBoxTray: VBoxSeamlessThread: mode change to %d\n", seamlessChangeRequest.mode));
     423                        LogFlowFunc(("Mode changed to %d\n", seamlessChangeRequest.mode));
    405424
    406425                        switch(seamlessChangeRequest.mode)
     
    409428                            if (fWasScreenSaverActive)
    410429                            {
    411                                 Log(("VBoxTray: Re-enabling the screensaver\n"));
    412                                 ret = SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, TRUE, NULL, 0);
    413                                 if (!ret)
    414                                     Log(("VBoxTray: SystemParametersInfo SPI_SETSCREENSAVEACTIVE failed with %d\n", GetLastError()));
     430                                LogRel(("Seamless: Re-enabling the screensaver\n"));
     431                                fRet = SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, TRUE, NULL, 0);
     432                                if (!fRet)
     433                                    LogRel(("Seamless: SystemParametersInfo SPI_SETSCREENSAVEACTIVE failed with %ld\n", GetLastError()));
    415434                            }
    416                             PostMessage(ghwndToolWindow, WM_VBOX_SEAMLESS_DISABLE, 0, 0);
     435                            PostMessage(g_hwndToolWindow, WM_VBOX_SEAMLESS_DISABLE, 0, 0);
    417436                            break;
    418437
    419438                        case VMMDev_Seamless_Visible_Region:
    420                             ret = SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, &fWasScreenSaverActive, 0);
    421                             if (!ret)
    422                                 Log(("VBoxTray: SystemParametersInfo SPI_GETSCREENSAVEACTIVE failed with %d\n", GetLastError()));
     439                            fRet = SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, &fWasScreenSaverActive, 0);
     440                            if (!fRet)
     441                                LogRel(("Seamless: SystemParametersInfo SPI_GETSCREENSAVEACTIVE failed with %ld\n", GetLastError()));
    423442
    424443                            if (fWasScreenSaverActive)
    425                                 Log(("VBoxTray: Disabling the screensaver\n"));
    426 
    427                             ret = SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0);
    428                             if (!ret)
    429                                 Log(("VBoxTray: SystemParametersInfo SPI_SETSCREENSAVEACTIVE failed with %d\n", GetLastError()));
    430                             PostMessage(ghwndToolWindow, WM_VBOX_SEAMLESS_ENABLE, 0, 0);
     444                                LogRel(("Seamless: Disabling the screensaver\n"));
     445
     446                            fRet = SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0);
     447                            if (!fRet)
     448                                LogRel(("Seamless: SystemParametersInfo SPI_SETSCREENSAVEACTIVE failed with %ld\n", GetLastError()));
     449                            PostMessage(g_hwndToolWindow, WM_VBOX_SEAMLESS_ENABLE, 0, 0);
    431450                            break;
    432451
     
    441460                    }
    442461                    else
    443                     {
    444                         Log(("VBoxTray: VBoxSeamlessThread: error from DeviceIoControl VBOXGUEST_IOCTL_VMMREQUEST\n"));
    445                     }
     462                        LogRel(("Seamless: DeviceIoControl(ChangeReq) failed with %ld\n", GetLastError()));
     463
     464                    if (*pfShutdown)
     465                        break;
     466
    446467                    /* sleep a bit to not eat too much CPU while retrying */
    447                     /* are we supposed to stop? */
    448                     if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 50) == WAIT_OBJECT_0)
    449                     {
    450                         fTerminate = true;
    451                         break;
    452                     }
     468                    RTThreadSleep(10);
    453469                }
    454470            }
     
    456472        else
    457473        {
    458             Log(("VBoxTray: VBoxTray: error 0 from DeviceIoControl VBOXGUEST_IOCTL_WAITEVENT\n"));
    459474            /* sleep a bit to not eat too much CPU in case the above call always fails */
    460             if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 10) == WAIT_OBJECT_0)
    461             {
    462                 fTerminate = true;
    463                 break;
    464             }
    465         }
    466     }
    467     while (!fTerminate);
     475            RTThreadSleep(10);
     476        }
     477
     478        if (*pfShutdown)
     479            break;
     480    }
    468481
    469482    maskInfo.u32OrMask = 0;
    470483    maskInfo.u32NotMask = VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST;
    471     if (DeviceIoControl (gVBoxDriver, VBOXGUEST_IOCTL_CTL_FILTER_MASK, &maskInfo, sizeof (maskInfo), NULL, 0, &cbReturned, NULL))
    472     {
    473         Log(("VBoxTray: VBoxSeamlessThread: DeviceIOControl(CtlMask - not) succeeded\n"));
    474     }
    475     else
    476     {
    477         Log(("VBoxTray: VBoxSeamlessThread: DeviceIOControl(CtlMask) failed\n"));
    478     }
    479 
    480     Log(("VBoxTray: VBoxSeamlessThread: finished seamless change request thread\n"));
    481     return 0;
    482 }
    483 
     484    if (!DeviceIoControl(gVBoxDriver, VBOXGUEST_IOCTL_CTL_FILTER_MASK, &maskInfo, sizeof (maskInfo), NULL, 0, &cbReturned, NULL))
     485        LogRel(("Seamless: DeviceIOControl(CtlMask) failed with %ld\n", GetLastError()));
     486
     487    LogFlowFuncLeaveRC(rc);
     488    return rc;
     489}
     490
     491/**
     492 * The service description.
     493 */
     494VBOXSERVICEDESC g_SvcDescSeamless =
     495{
     496    /* pszName. */
     497    "seamless",
     498    /* pszDescription. */
     499    "Seamless Windows",
     500    /* methods */
     501    VBoxSeamlessInit,
     502    VBoxSeamlessWorker,
     503    NULL /* pfnStop */,
     504    VBoxSeamlessDestroy
     505};
     506
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxSeamless.h

    r55401 r57741  
    55
    66/*
    7  * Copyright (C) 2006-2010 Oracle Corporation
     7 * Copyright (C) 2006-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1919#define __VBOXSERVICESEAMLESS__H
    2020
    21 /* The seamless windows service prototypes */
    22 int                VBoxSeamlessInit     (const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread);
    23 unsigned __stdcall VBoxSeamlessThread   (void *pInstance);
    24 void               VBoxSeamlessDestroy  (const VBOXSERVICEENV *pEnv, void *pInstance);
    25 
    26 
    2721void VBoxSeamlessEnable();
    2822void VBoxSeamlessDisable();
     
    3226
    3327#endif /* __VBOXSERVICESEAMLESS__H */
     28
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.cpp

    r57358 r57741  
    55
    66/*
    7  * Copyright (C) 2006-2014 Oracle Corporation
     7 * Copyright (C) 2006-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4444#include <sddl.h>
    4545
     46#include <iprt/asm.h>
    4647#include <iprt/buildconfig.h>
    4748#include <iprt/ldr.h>
     
    137138*   Global Variables                                                                                                             *
    138139*********************************************************************************************************************************/
    139 HANDLE                ghVBoxDriver;
    140 HANDLE                ghStopSem;
    141 HANDLE                ghSeamlessWtNotifyEvent = 0;
    142 HANDLE                ghSeamlessKmNotifyEvent = 0;
    143 SERVICE_STATUS        gVBoxServiceStatus;
    144 SERVICE_STATUS_HANDLE gVBoxServiceStatusHandle;
    145 HINSTANCE             ghInstance;
    146 HWND                  ghwndToolWindow;
    147 NOTIFYICONDATA        gNotifyIconData;
    148 DWORD                 gMajorVersion;
     140HANDLE                g_hVBoxDriver;
     141HANDLE                g_hStopSem;
     142HANDLE                g_hSeamlessWtNotifyEvent = 0;
     143HANDLE                g_hSeamlessKmNotifyEvent = 0;
     144HINSTANCE             g_hInstance;
     145HWND                  g_hwndToolWindow;
     146NOTIFYICONDATA        g_NotifyIconData;
     147DWORD                 g_dwMajorVersion;
    149148
    150149static PRTLOGGER      g_pLoggerRelease = NULL;
     
    153152static uint64_t       g_uHistoryFileSize = 100 * _1M;    /* Max 100MB per file. */
    154153
    155 /* The service table. */
    156 static VBOXSERVICEINFO vboxServiceTable[] =
    157 {
    158     {
    159         "Display",
    160         VBoxDisplayInit,
    161         VBoxDisplayThread,
    162         NULL /* pfnStop */,
    163         VBoxDisplayDestroy
    164     },
    165     {
    166         "Shared Clipboard",
    167         VBoxClipboardInit,
    168         VBoxClipboardThread,
    169         NULL /* pfnStop */,
    170         VBoxClipboardDestroy
    171     },
    172     {
    173         "Seamless Windows",
    174         VBoxSeamlessInit,
    175         VBoxSeamlessThread,
    176         NULL /* pfnStop */,
    177         VBoxSeamlessDestroy
    178     },
    179     {
    180         "VRDP",
    181         VBoxVRDPInit,
    182         VBoxVRDPThread,
    183         NULL /* pfnStop */,
    184         VBoxVRDPDestroy
    185     },
    186     {
    187         "IPC",
    188         VBoxIPCInit,
    189         VBoxIPCThread,
    190         VBoxIPCStop,
    191         VBoxIPCDestroy
    192     },
    193     {
    194         "Location Awareness",
    195         VBoxLAInit,
    196         VBoxLAThread,
    197         NULL /* pfnStop */,
    198         VBoxLADestroy
    199     },
     154/**
     155 * The details of the services that has been compiled in.
     156 */
     157static VBOXSERVICEINFO g_aServices[] =
     158{
     159    { &g_SvcDescDisplay,        NIL_RTTHREAD, NULL, false, false, false, false, true },
     160    { &g_SvcDescClipboard,      NIL_RTTHREAD, NULL, false, false, false, false, true },
     161    { &g_SvcDescSeamless,       NIL_RTTHREAD, NULL, false, false, false, false, true },
     162    { &g_SvcDescVRDP,           NIL_RTTHREAD, NULL, false, false, false, false, true },
     163    { &g_SvcDescIPC,            NIL_RTTHREAD, NULL, false, false, false, false, true },
     164    { &g_SvcDescLA,             NIL_RTTHREAD, NULL, false, false, false, false, true },
    200165#ifdef VBOX_WITH_DRAG_AND_DROP
    201     {
    202         "Drag and Drop",
    203         VBoxDnDInit,
    204         VBoxDnDThread,
    205         VBoxDnDStop,
    206         VBoxDnDDestroy
    207     },
     166    { &g_SvcDescDnD,            NIL_RTTHREAD, NULL, false, false, false, false, true }
    208167#endif
    209     {
    210         NULL
    211     }
    212168};
    213169
     
    244200static int vboxTrayCreateTrayIcon(void)
    245201{
    246     HICON hIcon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_VIRTUALBOX));
     202    HICON hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_VIRTUALBOX));
    247203    if (hIcon == NULL)
    248204    {
    249205        DWORD dwErr = GetLastError();
    250         Log(("Could not load tray icon, error %08X\n", dwErr));
     206        LogFunc(("Could not load tray icon, error %08X\n", dwErr));
    251207        return RTErrConvertFromWin32(dwErr);
    252208    }
    253209
    254210    /* Prepare the system tray icon. */
    255     RT_ZERO(gNotifyIconData);
    256     gNotifyIconData.cbSize           = NOTIFYICONDATA_V1_SIZE; // sizeof(NOTIFYICONDATA);
    257     gNotifyIconData.hWnd             = ghwndToolWindow;
    258     gNotifyIconData.uID              = ID_TRAYICON;
    259     gNotifyIconData.uFlags           = NIF_ICON | NIF_MESSAGE | NIF_TIP;
    260     gNotifyIconData.uCallbackMessage = WM_VBOXTRAY_TRAY_ICON;
    261     gNotifyIconData.hIcon            = hIcon;
    262 
    263     sprintf(gNotifyIconData.szTip, "%s Guest Additions %d.%d.%dr%d",
     211    RT_ZERO(g_NotifyIconData);
     212    g_NotifyIconData.cbSize           = NOTIFYICONDATA_V1_SIZE; // sizeof(NOTIFYICONDATA);
     213    g_NotifyIconData.hWnd             = g_hwndToolWindow;
     214    g_NotifyIconData.uID              = ID_TRAYICON;
     215    g_NotifyIconData.uFlags           = NIF_ICON | NIF_MESSAGE | NIF_TIP;
     216    g_NotifyIconData.uCallbackMessage = WM_VBOXTRAY_TRAY_ICON;
     217    g_NotifyIconData.hIcon            = hIcon;
     218
     219    sprintf(g_NotifyIconData.szTip, "%s Guest Additions %d.%d.%dr%d",
    264220            VBOX_PRODUCT, VBOX_VERSION_MAJOR, VBOX_VERSION_MINOR, VBOX_VERSION_BUILD, VBOX_SVN_REV);
    265221
    266222    int rc = VINF_SUCCESS;
    267     if (!Shell_NotifyIcon(NIM_ADD, &gNotifyIconData))
     223    if (!Shell_NotifyIcon(NIM_ADD, &g_NotifyIconData))
    268224    {
    269225        DWORD dwErr = GetLastError();
    270         Log(("Could not create tray icon, error = %08X\n", dwErr));
     226        LogFunc(("Could not create tray icon, error=%ld\n", dwErr));
    271227        rc = RTErrConvertFromWin32(dwErr);
    272         RT_ZERO(gNotifyIconData);
     228        RT_ZERO(g_NotifyIconData);
    273229    }
    274230
     
    278234}
    279235
    280 static void vboxTrayRemoveTrayIcon()
    281 {
    282     if (gNotifyIconData.cbSize > 0)
     236static void vboxTrayRemoveTrayIcon(void)
     237{
     238    if (g_NotifyIconData.cbSize > 0)
    283239    {
    284240        /* Remove the system tray icon and refresh system tray. */
    285         Shell_NotifyIcon(NIM_DELETE, &gNotifyIconData);
     241        Shell_NotifyIcon(NIM_DELETE, &g_NotifyIconData);
    286242        HWND hTrayWnd = FindWindow("Shell_TrayWnd", NULL); /* We assume we only have one tray atm. */
    287243        if (hTrayWnd)
     
    291247                SendMessage(hTrayNotifyWnd, WM_PAINT, 0, NULL);
    292248        }
    293         RT_ZERO(gNotifyIconData);
    294     }
    295 }
    296 
    297 static int vboxTrayStartServices(VBOXSERVICEENV *pEnv, VBOXSERVICEINFO *pTable)
     249        RT_ZERO(g_NotifyIconData);
     250    }
     251}
     252
     253/**
     254 * The service thread.
     255 *
     256 * @returns Whatever the worker function returns.
     257 * @param   ThreadSelf      My thread handle.
     258 * @param   pvUser          The service index.
     259 */
     260static DECLCALLBACK(int) vboxTrayServiceThread(RTTHREAD ThreadSelf, void *pvUser)
     261{
     262    PVBOXSERVICEINFO pSvc = (PVBOXSERVICEINFO)pvUser;
     263    AssertPtr(pSvc);
     264
     265#ifndef RT_OS_WINDOWS
     266    /*
     267     * Block all signals for this thread. Only the main thread will handle signals.
     268     */
     269    sigset_t signalMask;
     270    sigfillset(&signalMask);
     271    pthread_sigmask(SIG_BLOCK, &signalMask, NULL);
     272#endif
     273
     274    int rc = pSvc->pDesc->pfnWorker(pSvc->pInstance, &pSvc->fShutdown);
     275    ASMAtomicXchgBool(&pSvc->fShutdown, true);
     276    RTThreadUserSignal(ThreadSelf);
     277
     278    LogFunc(("Worker for '%s' ended with %Rrc\n", pSvc->pDesc->pszName, rc));
     279    return rc;
     280}
     281
     282static int vboxTrayServicesStart(PVBOXSERVICEENV pEnv)
    298283{
    299284    AssertPtrReturn(pEnv, VERR_INVALID_POINTER);
    300     AssertPtrReturn(pTable, VERR_INVALID_POINTER);
    301 
    302     Log(("Starting services ...\n"));
    303 
    304     /** @todo Use IPRT events here. */
    305     pEnv->hStopEvent = CreateEvent(NULL, TRUE /* bManualReset */,
    306                                    FALSE /* bInitialState */, NULL);
    307 
    308     if (!pEnv->hStopEvent)
    309     {
    310         /* Could not create event. */
    311         return VERR_NOT_SUPPORTED;
    312     }
    313 
    314     while (   pTable
    315            && pTable->pszName)
    316     {
    317         Log(("Starting %s ...\n", pTable->pszName));
    318 
    319         int rc = VINF_SUCCESS;
    320 
    321         bool fStartThread = false;
    322 
    323         pTable->hThread = (HANDLE)0;
    324         pTable->pInstance = NULL;
    325         pTable->fStarted = false;
    326 
    327         if (pTable->pfnInit)
    328             rc = pTable->pfnInit(pEnv, &pTable->pInstance, &fStartThread);
    329 
    330         if (RT_FAILURE(rc))
    331         {
    332             LogRel(("Failed to initialize service \"%s\", rc=%Rrc\n",
    333                     pTable->pszName, rc));
     285
     286    LogRel(("Starting services ...\n"));
     287
     288    int rc = VINF_SUCCESS;
     289
     290    for (unsigned i = 0; i < RT_ELEMENTS(g_aServices); i++)
     291    {
     292        PVBOXSERVICEINFO pSvc = &g_aServices[i];
     293        LogRel(("Starting service '%s' ...\n", pSvc->pDesc->pszName));
     294
     295        pSvc->hThread   = NIL_RTTHREAD;
     296        pSvc->pInstance = NULL;
     297        pSvc->fStarted  = false;
     298        pSvc->fShutdown = false;
     299
     300        int rc2 = VINF_SUCCESS;
     301
     302        if (pSvc->pDesc->pfnInit)
     303            rc2 = pSvc->pDesc->pfnInit(pEnv, &pSvc->pInstance);
     304
     305        if (RT_FAILURE(rc2))
     306        {
     307            LogRel(("Failed to initialize service '%s', rc=%Rrc\n", pSvc->pDesc->pszName, rc));
     308            if (rc2 == VERR_NOT_SUPPORTED)
     309            {
     310                LogRel(("Service '%s' is not supported on this system\n", pSvc->pDesc->pszName));
     311                rc2 = VINF_SUCCESS;
     312            }
     313            /* Keep going. */
    334314        }
    335315        else
    336316        {
    337             if (   pTable->pfnThread
    338                 && fStartThread)
    339             {
    340                 unsigned threadid;
    341                 /** @todo Use RTThread* here. */
    342                 pTable->hThread = (HANDLE)_beginthreadex(NULL,  /* security */
    343                                                          0,     /* stacksize */
    344                                                          pTable->pfnThread,
    345                                                          pTable->pInstance,
    346                                                          0,     /* initflag */
    347                                                          &threadid);
    348                 if (pTable->hThread == (HANDLE)(0))
    349                     rc = VERR_NOT_SUPPORTED;
    350             }
    351 
    352             if (RT_SUCCESS(rc))
    353                 pTable->fStarted = true;
    354             else
    355             {
    356                 Log(("Failed to start the thread\n"));
    357                 if (pTable->pfnDestroy)
    358                     pTable->pfnDestroy(pEnv, pTable->pInstance);
    359             }
    360         }
    361 
    362         /* Advance to next table element. */
    363         pTable++;
    364     }
    365 
    366     return VINF_SUCCESS;
    367 }
    368 
    369 static void vboxTrayStopServices(VBOXSERVICEENV *pEnv, VBOXSERVICEINFO *pTable)
    370 {
    371     if (!pEnv->hStopEvent)
    372         return;
    373 
    374     /* Signal to all threads. */
    375     SetEvent(pEnv->hStopEvent);
    376 
    377     VBOXSERVICEINFO *pCurTable = pTable;
    378     while (   pCurTable
    379            && pCurTable->pszName)
    380     {
    381         if (pCurTable->pfnStop)
    382             pCurTable->pfnStop(pEnv, pCurTable->pInstance);
    383 
    384         /* Advance to next table element. */
    385         pCurTable++;
    386     }
    387 
    388     pCurTable = pTable; /* Reset to first element. */
    389     while (   pCurTable
    390            && pCurTable->pszName)
    391     {
    392         if (pCurTable->fStarted)
    393         {
    394             if (pCurTable->pfnThread)
    395             {
    396                 /* There is a thread, wait for termination. */
    397                 /** @todo Use RTThread* here. */
    398                 /** @todo Don't wait forever here. Use a sensible default. */
    399                 WaitForSingleObject(pCurTable->hThread, INFINITE);
    400 
    401                 /** @todo Dito. */
    402                 CloseHandle(pCurTable->hThread);
    403                 pCurTable->hThread = NULL;
    404             }
    405 
    406             if (pCurTable->pfnDestroy)
    407                 pCurTable->pfnDestroy(pEnv, pCurTable->pInstance);
    408             pCurTable->fStarted = false;
    409         }
    410 
    411         /* Advance to next table element. */
    412         pCurTable++;
    413     }
    414 
    415     CloseHandle(pEnv->hStopEvent);
     317            if (pSvc->pDesc->pfnWorker)
     318            {
     319                rc2 = RTThreadCreate(&pSvc->hThread, vboxTrayServiceThread, pSvc /* pvUser */,
     320                                     0 /* Default stack size */, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, pSvc->pDesc->pszName);
     321                if (RT_SUCCESS(rc2))
     322                {
     323                    pSvc->fStarted = true;
     324
     325                    RTThreadUserWait(pSvc->hThread, 30 * 1000 /* Timeout in ms */);
     326                    if (pSvc->fShutdown)
     327                    {
     328                        LogRel(("Service '%s' failed to start!\n", pSvc->pDesc->pszName));
     329                        rc = VERR_GENERAL_FAILURE;
     330                    }
     331                    else
     332                        LogRel(("Service '%s' started\n", pSvc->pDesc->pszName));
     333                }
     334                else
     335                {
     336                    LogRel(("Failed to start thread for service '%s': %Rrc\n", rc2));
     337                    if (pSvc->pDesc->pfnDestroy)
     338                        pSvc->pDesc->pfnDestroy(pSvc->pInstance);
     339                }
     340            }
     341        }
     342
     343        if (RT_SUCCESS(rc))
     344            rc = rc2;
     345    }
     346
     347    if (RT_SUCCESS(rc))
     348        LogRel(("All services started\n"));
     349    else
     350        LogRel(("Services started, but some with errors\n"));
     351
     352    LogFlowFuncLeaveRC(rc);
     353    return rc;
     354}
     355
     356static int vboxTrayServicesStop(VBOXSERVICEENV *pEnv)
     357{
     358    AssertPtrReturn(pEnv, VERR_INVALID_POINTER);
     359
     360    LogRel2(("Stopping all services ...\n"));
     361
     362    /*
     363     * Signal all the services.
     364     */
     365    for (unsigned i = 0; i < RT_ELEMENTS(g_aServices); i++)
     366        ASMAtomicWriteBool(&g_aServices[i].fShutdown, true);
     367
     368    /*
     369     * Do the pfnStop callback on all running services.
     370     */
     371    for (unsigned i = 0; i < RT_ELEMENTS(g_aServices); i++)
     372    {
     373        PVBOXSERVICEINFO pSvc = &g_aServices[i];
     374        if (   pSvc->fStarted
     375            && pSvc->pDesc->pfnStop)
     376        {
     377            LogRel2(("Calling stop function for service '%s' ...\n", pSvc->pDesc->pszName));
     378            int rc2 = pSvc->pDesc->pfnStop(pSvc->pInstance);
     379            if (RT_FAILURE(rc2))
     380                LogRel(("Failed to stop service '%s': %Rrc\n", pSvc->pDesc->pszName, rc2));
     381        }
     382    }
     383
     384    LogRel2(("All stop functions for services called\n"));
     385
     386    int rc = VINF_SUCCESS;
     387
     388    /*
     389     * Wait for all the service threads to complete.
     390     */
     391    for (unsigned i = 0; i < RT_ELEMENTS(g_aServices); i++)
     392    {
     393        PVBOXSERVICEINFO pSvc = &g_aServices[i];
     394        if (!pSvc->fEnabled) /* Only stop services which were started before. */
     395            continue;
     396
     397        if (pSvc->hThread != NIL_RTTHREAD)
     398        {
     399            LogRel2(("Waiting for service '%s' to stop ...\n", pSvc->pDesc->pszName));
     400            int rc2 = VINF_SUCCESS;
     401            for (int j = 0; j < 30; j++) /* Wait 30 seconds in total */
     402            {
     403                rc2 = RTThreadWait(pSvc->hThread, 1000 /* Wait 1 second */, NULL);
     404                if (RT_SUCCESS(rc2))
     405                    break;
     406            }
     407            if (RT_FAILURE(rc2))
     408            {
     409                LogRel(("Service '%s' failed to stop (%Rrc)\n", pSvc->pDesc->pszName, rc2));
     410                if (RT_SUCCESS(rc))
     411                    rc = rc2;
     412            }
     413        }
     414
     415        if (pSvc->pDesc->pfnDestroy)
     416        {
     417            LogRel2(("Terminating service '%s' ...\n", pSvc->pDesc->pszName));
     418            pSvc->pDesc->pfnDestroy(pSvc->pInstance);
     419        }
     420    }
     421
     422    if (RT_SUCCESS(rc))
     423        LogRel(("All services stopped\n"));
     424
     425    LogFlowFuncLeaveRC(rc);
     426    return rc;
    416427}
    417428
     
    463474    /* Open VBox guest driver. */
    464475    DWORD dwErr = ERROR_SUCCESS;
    465     ghVBoxDriver = CreateFile(VBOXGUEST_DEVICE_NAME,
     476    g_hVBoxDriver = CreateFile(VBOXGUEST_DEVICE_NAME,
    466477                             GENERIC_READ | GENERIC_WRITE,
    467478                             FILE_SHARE_READ | FILE_SHARE_WRITE,
     
    470481                             FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
    471482                             NULL);
    472     if (ghVBoxDriver == INVALID_HANDLE_VALUE)
     483    if (g_hVBoxDriver == INVALID_HANDLE_VALUE)
    473484    {
    474485        dwErr = GetLastError();
     
    480491static void vboxTrayCloseBaseDriver(void)
    481492{
    482     if (ghVBoxDriver)
    483     {
    484         CloseHandle(ghVBoxDriver);
    485         ghVBoxDriver = NULL;
     493    if (g_hVBoxDriver)
     494    {
     495        CloseHandle(g_hVBoxDriver);
     496        g_hVBoxDriver = NULL;
    486497    }
    487498}
     
    612623static void vboxTrayDestroyToolWindow(void)
    613624{
    614     if (ghwndToolWindow)
     625    if (g_hwndToolWindow)
    615626    {
    616627        Log(("Destroying tool window ...\n"));
    617628
    618629        /* Destroy the tool window. */
    619         DestroyWindow(ghwndToolWindow);
    620         ghwndToolWindow = NULL;
    621 
    622         UnregisterClass("VBoxTrayToolWndClass", ghInstance);
     630        DestroyWindow(g_hwndToolWindow);
     631        g_hwndToolWindow = NULL;
     632
     633        UnregisterClass("VBoxTrayToolWndClass", g_hInstance);
    623634    }
    624635}
     
    629640
    630641    /* Create a custom window class. */
    631     WNDCLASS windowClass = {0};
    632     windowClass.style         = CS_NOCLOSE;
    633     windowClass.lpfnWndProc   = (WNDPROC)vboxToolWndProc;
    634     windowClass.hInstance     = ghInstance;
    635     windowClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
    636     windowClass.lpszClassName = "VBoxTrayToolWndClass";
    637     if (!RegisterClass(&windowClass))
     642    WNDCLASSEX wc = { 0 };
     643    wc.cbSize        = sizeof(WNDCLASSEX);
     644    wc.style         = CS_NOCLOSE;
     645    wc.lpfnWndProc   = (WNDPROC)vboxToolWndProc;
     646    wc.hInstance     = g_hInstance;
     647    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
     648    wc.lpszClassName = "VBoxTrayToolWndClass";
     649
     650    if (!RegisterClassEx(&wc))
    638651    {
    639652        dwErr = GetLastError();
     
    649662         *
    650663         */
    651         ghwndToolWindow = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,
     664        g_hwndToolWindow = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,
    652665                                         "VBoxTrayToolWndClass", "VBoxTrayToolWnd",
    653666                                         WS_POPUPWINDOW,
    654                                          -200, -200, 100, 100, NULL, NULL, ghInstance, NULL);
    655         if (!ghwndToolWindow)
     667                                         -200, -200, 100, 100, NULL, NULL, g_hInstance, NULL);
     668        if (!g_hwndToolWindow)
    656669        {
    657670            dwErr = GetLastError();
     
    663676            hlpReloadCursor();
    664677
    665             Log(("Invisible tool window handle = %p\n", ghwndToolWindow));
     678            Log(("Invisible tool window handle = %p\n", g_hwndToolWindow));
    666679        }
    667680    }
     
    675688{
    676689    OSVERSIONINFO info;
    677     gMajorVersion = 5; /* Default to Windows XP. */
     690    g_dwMajorVersion = 5; /* Default to Windows XP. */
    678691    info.dwOSVersionInfoSize = sizeof(info);
    679692    if (GetVersionEx(&info))
    680693    {
    681694        Log(("Windows version %ld.%ld\n", info.dwMajorVersion, info.dwMinorVersion));
    682         gMajorVersion = info.dwMajorVersion;
     695        g_dwMajorVersion = info.dwMajorVersion;
    683696    }
    684697
     
    702715    {
    703716        /* For Vista and up we need to change the integrity of the security descriptor, too. */
    704         if (gMajorVersion >= 6)
     717        if (g_dwMajorVersion >= 6)
    705718        {
    706719            BOOL (WINAPI * pfnConvertStringSecurityDescriptorToSecurityDescriptorA)(LPCSTR StringSecurityDescriptor, DWORD StringSDRevision, PSECURITY_DESCRIPTOR  *SecurityDescriptor, PULONG  SecurityDescriptorSize);
     
    744757
    745758        if (   dwErr == ERROR_SUCCESS
    746             && gMajorVersion >= 5) /* Only for W2K and up ... */
    747         {
    748             ghSeamlessWtNotifyEvent = CreateEvent(&SecAttr, FALSE, FALSE, VBOXHOOK_GLOBAL_WT_EVENT_NAME);
    749             if (ghSeamlessWtNotifyEvent == NULL)
     759            && g_dwMajorVersion >= 5) /* Only for W2K and up ... */
     760        {
     761            g_hSeamlessWtNotifyEvent = CreateEvent(&SecAttr, FALSE, FALSE, VBOXHOOK_GLOBAL_WT_EVENT_NAME);
     762            if (g_hSeamlessWtNotifyEvent == NULL)
    750763            {
    751764                dwErr = GetLastError();
     
    753766            }
    754767
    755             ghSeamlessKmNotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    756             if (ghSeamlessKmNotifyEvent == NULL)
     768            g_hSeamlessKmNotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
     769            if (g_hSeamlessKmNotifyEvent == NULL)
    757770            {
    758771                dwErr = GetLastError();
     
    766779static void vboxTrayShutdownSeamless(void)
    767780{
    768     if (ghSeamlessWtNotifyEvent)
    769     {
    770         CloseHandle(ghSeamlessWtNotifyEvent);
    771         ghSeamlessWtNotifyEvent = NULL;
    772     }
    773 
    774     if (ghSeamlessKmNotifyEvent)
    775     {
    776         CloseHandle(ghSeamlessKmNotifyEvent);
    777         ghSeamlessKmNotifyEvent = NULL;
     781    if (g_hSeamlessWtNotifyEvent)
     782    {
     783        CloseHandle(g_hSeamlessWtNotifyEvent);
     784        g_hSeamlessWtNotifyEvent = NULL;
     785    }
     786
     787    if (g_hSeamlessKmNotifyEvent)
     788    {
     789        CloseHandle(g_hSeamlessKmNotifyEvent);
     790        g_hSeamlessKmNotifyEvent = NULL;
    778791    }
    779792}
     
    792805{
    793806    int rc = VINF_SUCCESS;
    794     Log(("Entering vboxTrayServiceMain\n"));
    795 
    796     ghStopSem = CreateEvent(NULL, TRUE, FALSE, NULL);
    797     if (ghStopSem == NULL)
     807    LogFunc(("Entering vboxTrayServiceMain\n"));
     808
     809    g_hStopSem = CreateEvent(NULL, TRUE, FALSE, NULL);
     810    if (g_hStopSem == NULL)
    798811    {
    799812        rc = RTErrConvertFromWin32(GetLastError());
    800         Log(("CreateEvent for stopping VBoxTray failed, rc=%Rrc\n", rc));
     813        LogFunc(("CreateEvent for stopping VBoxTray failed, rc=%Rrc\n", rc));
    801814    }
    802815    else
     
    806819         */
    807820        VBOXSERVICEENV svcEnv;
    808         svcEnv.hInstance = ghInstance;
    809         svcEnv.hDriver   = ghVBoxDriver;
     821        svcEnv.hInstance = g_hInstance;
     822        svcEnv.hDriver   = g_hVBoxDriver;
    810823
    811824        /* Initializes disp-if to default (XPDM) mode. */
     
    819832
    820833        /* Finally start all the built-in services! */
    821         rc = vboxTrayStartServices(&svcEnv, vboxServiceTable);
     834        rc = vboxTrayServicesStart(&svcEnv);
    822835        if (RT_FAILURE(rc))
    823836        {
    824837            /* Terminate service if something went wrong. */
    825             vboxTrayStopServices(&svcEnv, vboxServiceTable);
     838            vboxTrayServicesStop(&svcEnv);
    826839        }
    827840        else
     
    829842            rc = vboxTrayCreateTrayIcon();
    830843            if (   RT_SUCCESS(rc)
    831                 && gMajorVersion >= 5) /* Only for W2K and up ... */
     844                && g_dwMajorVersion >= 5) /* Only for W2K and up ... */
    832845            {
    833846                /* We're ready to create the tooltip balloon.
    834847                   Check in 10 seconds (@todo make seconds configurable) ... */
    835                 SetTimer(ghwndToolWindow,
     848                SetTimer(g_hwndToolWindow,
    836849                         TIMERID_VBOXTRAY_CHECK_HOSTVERSION,
    837850                         10 * 1000, /* 10 seconds */
     
    864877                DWORD dwEventCount = 0;
    865878
    866                 hWaitEvent[dwEventCount++] = ghStopSem;
     879                hWaitEvent[dwEventCount++] = g_hStopSem;
    867880
    868881                /* Check if seamless mode is not active and add seamless event to the list */
    869                 if (0 != ghSeamlessWtNotifyEvent)
     882                if (0 != g_hSeamlessWtNotifyEvent)
    870883                {
    871                     hWaitEvent[dwEventCount++] = ghSeamlessWtNotifyEvent;
     884                    hWaitEvent[dwEventCount++] = g_hSeamlessWtNotifyEvent;
    872885                }
    873886
    874                 if (0 != ghSeamlessKmNotifyEvent)
     887                if (0 != g_hSeamlessKmNotifyEvent)
    875888                {
    876                     hWaitEvent[dwEventCount++] = ghSeamlessKmNotifyEvent;
     889                    hWaitEvent[dwEventCount++] = g_hSeamlessKmNotifyEvent;
    877890                }
    878891
     
    882895                }
    883896
    884                 Log(("Number of events to wait in main loop: %ld\n", dwEventCount));
     897                LogFlowFunc(("Number of events to wait in main loop: %ld\n", dwEventCount));
    885898                while (true)
    886899                {
     
    893906                    if (waitResult == 0)
    894907                    {
    895                         Log(("Event 'Exit' triggered\n"));
     908                        LogFunc(("Event 'Exit' triggered\n"));
    896909                        /* exit */
    897910                        break;
     
    904917                            if (hWaitEvent[waitResult])
    905918                            {
    906                                 if (hWaitEvent[waitResult] == ghSeamlessWtNotifyEvent)
     919                                if (hWaitEvent[waitResult] == g_hSeamlessWtNotifyEvent)
    907920                                {
    908                                     Log(("Event 'Seamless' triggered\n"));
     921                                    LogFunc(("Event 'Seamless' triggered\n"));
    909922
    910923                                    /* seamless window notification */
     
    912925                                    fHandled = TRUE;
    913926                                }
    914                                 else if (hWaitEvent[waitResult] == ghSeamlessKmNotifyEvent)
     927                                else if (hWaitEvent[waitResult] == g_hSeamlessKmNotifyEvent)
    915928                                {
    916                                     Log(("Event 'Km Seamless' triggered\n"));
     929                                    LogFunc(("Event 'Km Seamless' triggered\n"));
    917930
    918931                                    /* seamless window notification */
     
    922935                                else if (hWaitEvent[waitResult] == vboxDtGetNotifyEvent())
    923936                                {
    924                                     Log(("Event 'Dt' triggered\n"));
     937                                    LogFunc(("Event 'Dt' triggered\n"));
    925938                                    VBoxTrayCheckDt();
    926939                                    fHandled = TRUE;
     
    935948                            while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    936949                            {
    937 #ifndef DEBUG_andy
    938                                 Log(("msg %p\n", msg.message));
     950#ifdef DEBUG_andy
     951                                LogFlowFunc(("PeekMessage %u\n", msg.message));
    939952#endif
    940953                                if (msg.message == WM_QUIT)
    941954                                {
    942                                     Log(("WM_QUIT!\n"));
    943                                     SetEvent(ghStopSem);
     955                                    LogFunc(("Terminating ...\n"));
     956                                    SetEvent(g_hStopSem);
    944957                                }
    945958                                TranslateMessage(&msg);
     
    949962                    }
    950963                }
    951                 Log(("Returned from main loop, exiting ...\n"));
    952             }
    953             Log(("Waiting for services to stop ...\n"));
    954             vboxTrayStopServices(&svcEnv, vboxServiceTable);
     964                LogFunc(("Returned from main loop, exiting ...\n"));
     965            }
     966            LogFunc(("Waiting for services to stop ...\n"));
     967            vboxTrayServicesStop(&svcEnv);
    955968        } /* Services started */
    956         CloseHandle(ghStopSem);
     969        CloseHandle(g_hStopSem);
    957970    } /* Stop event created */
    958971
    959972    vboxTrayRemoveTrayIcon();
    960973
    961     Log(("Leaving vboxTrayServiceMain with rc=%Rrc\n", rc));
     974    LogFunc(("Leaving with rc=%Rrc\n", rc));
    962975    return rc;
    963976}
     
    9961009    {
    9971010        /* Save instance handle. */
    998         ghInstance = hInstance;
     1011        g_hInstance = hInstance;
    9991012
    10001013        hlpReportStatus(VBoxGuestFacilityStatus_Init);
     
    10041017            VBoxCapsInit();
    10051018
    1006             rc = vboxStInit(ghwndToolWindow);
     1019            rc = vboxStInit(g_hwndToolWindow);
    10071020            if (!RT_SUCCESS(rc))
    10081021            {
    1009                 LogFlowFunc(("vboxStInit failed, rc %d\n"));
     1022                LogFlowFunc(("vboxStInit failed, rc=%Rrc\n", rc));
    10101023                /* ignore the St Init failure. this can happen for < XP win that do not support WTS API
    10111024                 * in that case the session is treated as active connected to the physical console
     
    10171030            if (!RT_SUCCESS(rc))
    10181031            {
    1019                 LogFlowFunc(("vboxDtInit failed, rc %d\n"));
     1032                LogFlowFunc(("vboxDtInit failed, rc=%Rrc\n", rc));
    10201033                /* ignore the Dt Init failure. this can happen for < XP win that do not support WTS API
    10211034                 * in that case the session is treated as active connected to the physical console
     
    10261039            rc = VBoxAcquireGuestCaps(VMMDEV_GUEST_SUPPORTS_SEAMLESS | VMMDEV_GUEST_SUPPORTS_GRAPHICS, 0, true);
    10271040            if (!RT_SUCCESS(rc))
    1028             {
    1029                 LogFlowFunc(("VBoxAcquireGuestCaps cfg failed rc %d, ignoring..\n", rc));
    1030             }
    1031 
    1032             rc = vboxTraySetupSeamless();
     1041                LogFlowFunc(("VBoxAcquireGuestCaps failed with rc=%Rrc, ignoring ...\n", rc));
     1042
     1043            rc = vboxTraySetupSeamless(); /** @todo r=andy Do we really want to be this critical for the whole application? */
    10331044            if (RT_SUCCESS(rc))
    10341045            {
    1035                 Log(("Init successful\n"));
    10361046                rc = vboxTrayServiceMain();
    10371047                if (RT_SUCCESS(rc))
     
    10771087
    10781088/**
    1079  * Window procedure for our tool window
     1089 * Window procedure for our main tool window.
    10801090 */
    10811091static LRESULT CALLBACK vboxToolWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    10821092{
     1093    LogFlowFunc(("hWnd=%p, uMsg=%u\n", hWnd, uMsg));
     1094
    10831095    switch (uMsg)
    10841096    {
    10851097        case WM_CREATE:
    10861098        {
    1087             Log(("Tool window created\n"));
     1099            LogFunc(("Tool window created\n"));
    10881100
    10891101            int rc = vboxTrayRegisterGlobalMessages(&s_vboxGlobalMessageTable[0]);
    10901102            if (RT_FAILURE(rc))
    1091                 Log(("Error registering global window messages, rc=%Rrc\n", rc));
     1103                LogFunc(("Error registering global window messages, rc=%Rrc\n", rc));
    10921104            return 0;
    10931105        }
     
    10971109
    10981110        case WM_DESTROY:
    1099             Log(("Tool window destroyed\n"));
    1100             KillTimer(ghwndToolWindow, TIMERID_VBOXTRAY_CHECK_HOSTVERSION);
     1111        {
     1112            LogFunc(("Tool window destroyed\n"));
     1113            KillTimer(g_hwndToolWindow, TIMERID_VBOXTRAY_CHECK_HOSTVERSION);
    11011114            return 0;
     1115        }
    11021116
    11031117        case WM_TIMER:
     1118        {
    11041119            if (VBoxCapsCheckTimer(wParam))
    11051120                return 0;
     
    11151130                    {
    11161131                        /* After successful run we don't need to check again. */
    1117                         KillTimer(ghwndToolWindow, TIMERID_VBOXTRAY_CHECK_HOSTVERSION);
     1132                        KillTimer(g_hwndToolWindow, TIMERID_VBOXTRAY_CHECK_HOSTVERSION);
    11181133                    }
    11191134                    return 0;
     
    11221137                    break;
    11231138            }
     1139
    11241140            break; /* Make sure other timers get processed the usual way! */
     1141        }
    11251142
    11261143        case WM_VBOXTRAY_TRAY_ICON:
     1144        {
    11271145            switch (lParam)
    11281146            {
     
    11341152            }
    11351153            return 0;
     1154        }
    11361155
    11371156        case WM_VBOX_SEAMLESS_ENABLE:
     1157        {
    11381158            VBoxCapsEntryFuncStateSet(VBOXCAPS_ENTRY_IDX_SEAMLESS, VBOXCAPS_ENTRY_FUNCSTATE_STARTED);
    11391159            return 0;
     1160        }
    11401161
    11411162        case WM_VBOX_SEAMLESS_DISABLE:
     1163        {
    11421164            VBoxCapsEntryFuncStateSet(VBOXCAPS_ENTRY_IDX_SEAMLESS, VBOXCAPS_ENTRY_FUNCSTATE_SUPPORTED);
    11431165            return 0;
     1166        }
    11441167
    11451168        case WM_DISPLAYCHANGE:
    11461169        case WM_VBOX_SEAMLESS_UPDATE:
     1170        {
    11471171            if (VBoxCapsEntryIsEnabled(VBOXCAPS_ENTRY_IDX_SEAMLESS))
    11481172                VBoxSeamlessCheckWindows(true);
    11491173            return 0;
     1174        }
    11501175
    11511176        case WM_VBOX_GRAPHICS_SUPPORTED:
     1177        {
    11521178            VBoxGrapicsSetSupported(TRUE);
    11531179            return 0;
     1180        }
    11541181
    11551182        case WM_VBOX_GRAPHICS_UNSUPPORTED:
     1183        {
    11561184            VBoxGrapicsSetSupported(FALSE);
    11571185            return 0;
     1186        }
    11581187
    11591188        case WM_WTSSESSION_CHANGE:
     
    11671196            return 0;
    11681197        }
     1198
    11691199        default:
    1170 
     1200        {
    11711201            /* Handle all globally registered window messages. */
    11721202            if (vboxTrayHandleGlobalMessages(&s_vboxGlobalMessageTable[0], uMsg,
     
    11761206            }
    11771207            break; /* We did not handle the message, dispatch to DefWndProc. */
    1178     }
    1179 
    1180     /* Only if message was *not* handled by our switch above, dispatch
    1181      * to DefWindowProc. */
     1208        }
     1209    }
     1210
     1211    /* Only if message was *not* handled by our switch above, dispatch to DefWindowProc. */
    11821212    return DefWindowProc(hWnd, uMsg, wParam, lParam);
    11831213}
     
    14431473    int rc = VINF_SUCCESS;
    14441474    OSVERSIONINFO info;
    1445     gMajorVersion = 5; /* Default to Windows XP. */
     1475    g_dwMajorVersion = 5; /* Default to Windows XP. */
    14461476    info.dwOSVersionInfoSize = sizeof(info);
    14471477    if (GetVersionEx(&info))
    14481478    {
    14491479        LogRel(("Windows version %ld.%ld\n", info.dwMajorVersion, info.dwMinorVersion));
    1450         gMajorVersion = info.dwMajorVersion;
     1480        g_dwMajorVersion = info.dwMajorVersion;
    14511481    }
    14521482
     
    14991529                    BOOL fRc = FALSE;
    15001530                    /* For Vista and up we need to change the integrity of the security descriptor, too. */
    1501                     if (gMajorVersion >= 6)
     1531                    if (g_dwMajorVersion >= 6)
    15021532                    {
    15031533                        HMODULE hModHook = (HMODULE)RTLdrGetNativeHandle(gVBoxDt.hLdrModHook);
     
    15131543                    if (!fRc)
    15141544                    {
    1515                         gVBoxDt.idTimer = SetTimer(ghwndToolWindow, TIMERID_VBOXTRAY_DT_TIMER, 500, (TIMERPROC)NULL);
     1545                        gVBoxDt.idTimer = SetTimer(g_hwndToolWindow, TIMERID_VBOXTRAY_DT_TIMER, 500, (TIMERPROC)NULL);
    15161546                        if (!gVBoxDt.idTimer)
    15171547                        {
     
    15861616}
    15871617
    1588 
    15891618/* we need to perform Acquire/Release using the file handled we use for rewuesting events from VBoxGuest
    15901619 * otherwise Acquisition mechanism will treat us as different client and will not propagate necessary requests
     
    15991628    Info.u32OrMask = fOr;
    16001629    Info.u32NotMask = fNot;
    1601     if (!DeviceIoControl(ghVBoxDriver, VBOXGUEST_IOCTL_GUEST_CAPS_ACQUIRE, &Info, sizeof(Info), &Info, sizeof(Info), &cbReturned, NULL))
     1630    if (!DeviceIoControl(g_hVBoxDriver, VBOXGUEST_IOCTL_GUEST_CAPS_ACQUIRE, &Info, sizeof(Info), &Info, sizeof(Info), &cbReturned, NULL))
    16021631    {
    16031632        DWORD LastErr = GetLastError();
     
    16501679static VBOXCAPS gVBoxCaps;
    16511680
    1652 static DECLCALLBACK(void) vboxCapsOnEnableSeamles(struct VBOXCAPS *pConsole, struct VBOXCAPS_ENTRY *pCap, BOOL fEnabled)
     1681static DECLCALLBACK(void) vboxCapsOnEnableSeamless(struct VBOXCAPS *pConsole, struct VBOXCAPS_ENTRY *pCap, BOOL fEnabled)
    16531682{
    16541683    if (fEnabled)
    16551684    {
    1656         Log(("vboxCapsOnEnableSeamles: ENABLED\n"));
     1685        Log(("vboxCapsOnEnableSeamless: ENABLED\n"));
    16571686        Assert(pCap->enmAcState == VBOXCAPS_ENTRY_ACSTATE_ACQUIRED);
    16581687        Assert(pCap->enmFuncState == VBOXCAPS_ENTRY_FUNCSTATE_STARTED);
     
    16611690    else
    16621691    {
    1663         Log(("vboxCapsOnEnableSeamles: DISABLED\n"));
     1692        Log(("vboxCapsOnEnableSeamless: DISABLED\n"));
    16641693        Assert(pCap->enmAcState != VBOXCAPS_ENTRY_ACSTATE_ACQUIRED || pCap->enmFuncState != VBOXCAPS_ENTRY_FUNCSTATE_STARTED);
    16651694        VBoxSeamlessDisable();
     
    17381767    pConsole->aCaps[VBOXCAPS_ENTRY_IDX_SEAMLESS].fCap = VMMDEV_GUEST_SUPPORTS_SEAMLESS;
    17391768    pConsole->aCaps[VBOXCAPS_ENTRY_IDX_SEAMLESS].iCap = VBOXCAPS_ENTRY_IDX_SEAMLESS;
    1740     pConsole->aCaps[VBOXCAPS_ENTRY_IDX_SEAMLESS].pfnOnEnable = vboxCapsOnEnableSeamles;
     1769    pConsole->aCaps[VBOXCAPS_ENTRY_IDX_SEAMLESS].pfnOnEnable = vboxCapsOnEnableSeamless;
    17411770    pConsole->aCaps[VBOXCAPS_ENTRY_IDX_GRAPHICS].fCap = VMMDEV_GUEST_SUPPORTS_GRAPHICS;
    17421771    pConsole->aCaps[VBOXCAPS_ENTRY_IDX_GRAPHICS].iCap = VBOXCAPS_ENTRY_IDX_GRAPHICS;
     
    17581787    {
    17591788        Log(("killing console timer\n"));
    1760         KillTimer(ghwndToolWindow, pConsole->idTimer);
     1789        KillTimer(g_hwndToolWindow, pConsole->idTimer);
    17611790        pConsole->idTimer = 0;
    17621791    }
     
    18201849    if (!fNeedNewTimer)
    18211850    {
    1822         KillTimer(ghwndToolWindow, pConsole->idTimer);
     1851        KillTimer(g_hwndToolWindow, pConsole->idTimer);
    18231852        /* cleanup timer data */
    18241853        pConsole->idTimer = 0;
     
    18811910    if (!pConsole->idTimer)
    18821911    {
    1883         pConsole->idTimer = SetTimer(ghwndToolWindow, TIMERID_VBOXTRAY_CAPS_TIMER, 100, (TIMERPROC)NULL);
     1912        pConsole->idTimer = SetTimer(g_hwndToolWindow, TIMERID_VBOXTRAY_CAPS_TIMER, 100, (TIMERPROC)NULL);
    18841913        if (!pConsole->idTimer)
    18851914        {
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.h

    r51469 r57741  
    55
    66/*
    7  * Copyright (C) 2006-2014 Oracle Corporation
     7 * Copyright (C) 2006-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4646#include <iprt/initterm.h>
    4747#include <iprt/string.h>
     48#include <iprt/thread.h>
    4849
    4950#include <VBox/version.h>
     
    6364#define WM_VBOXTRAY_TRAY_ICON                   WM_APP + 40
    6465
    65 
    6666/* The tray icon's ID. */
    6767#define ID_TRAYICON                             2000
    68 
    6968
    7069/*
     
    7675#define TIMERID_VBOXTRAY_ST_DELAYED_INIT_TIMER  1003
    7776
    78 /* The environment information for services. */
     77/**
     78 * The environment information for services.
     79 */
    7980typedef struct _VBOXSERVICEENV
    8081{
     82    /** hInstance of VBoxTray. */
    8183    HINSTANCE hInstance;
     84    /** Handle of guest driver. */
    8285    HANDLE    hDriver;
    83     HANDLE    hStopEvent;
    84     /* display driver interface, XPDM - WDDM abstraction see VBOXDISPIF** definitions above */
     86    /* Display driver interface, XPDM - WDDM abstraction see VBOXDISPIF** definitions above */
     87    /** @todo r=andy Argh. Needed by the "display" + "seamless" services (which in turn get called
     88     *               by the VBoxCaps facility. See #8037. */
    8589    VBOXDISPIF dispIf;
    86 } VBOXSERVICEENV;
     90} VBOXSERVICEENV, *PVBOXSERVICEENV;
    8791
    88 /* The service initialization info and runtime variables. */
     92/**
     93 * A service descriptor.
     94 */
     95typedef struct _VBOXSERVICEDESC
     96{
     97    /** The service's name. RTTHREAD_NAME_LEN maximum characters. */
     98    char           *pszName;
     99    /** The service description. */
     100    char           *pszDesc;
     101
     102    /** Callbacks. */
     103
     104    /**
     105     * Initializes a service.
     106     * @returns VBox status code.
     107     * @param   pEnv
     108     * @param   ppInstance      Where to return the thread-specific instance data.
     109     */
     110    DECLCALLBACKMEMBER(int,  pfnInit)   (const PVBOXSERVICEENV pEnv, void **ppInstance);
     111
     112    /** Called from the worker thread.
     113     *
     114     * @returns VBox status code.
     115     * @retval  VINF_SUCCESS if exitting because *pfShutdown was set.
     116     * @param   pInstance       Pointer to thread-specific instance data.
     117     * @param   pfShutdown      Pointer to a per service termination flag to check
     118     *                          before and after blocking.
     119     */
     120    DECLCALLBACKMEMBER(int,  pfnWorker) (void *pInstance, bool volatile *pfShutdown);
     121
     122    /**
     123     * Stops a service.
     124     */
     125    DECLCALLBACKMEMBER(int,  pfnStop)   (void *pInstance);
     126
     127    /**
     128     * Does termination cleanups.
     129     *
     130     * @remarks This may be called even if pfnInit hasn't been called!
     131     */
     132    DECLCALLBACKMEMBER(void, pfnDestroy)(void *pInstance);
     133} VBOXSERVICEDESC, *PVBOXSERVICEDESC;
     134
     135extern VBOXSERVICEDESC g_SvcDescDisplay;
     136extern VBOXSERVICEDESC g_SvcDescClipboard;
     137extern VBOXSERVICEDESC g_SvcDescSeamless;
     138extern VBOXSERVICEDESC g_SvcDescVRDP;
     139extern VBOXSERVICEDESC g_SvcDescIPC;
     140extern VBOXSERVICEDESC g_SvcDescLA;
     141#ifdef VBOX_WITH_DRAG_AND_DROP
     142extern VBOXSERVICEDESC g_SvcDescDnD;
     143#endif
     144
     145/**
     146 * The service initialization info and runtime variables.
     147 */
    89148typedef struct _VBOXSERVICEINFO
    90149{
    91     char     *pszName;
    92     int      (* pfnInit)             (const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread);
    93     unsigned (__stdcall * pfnThread) (void *pInstance);
    94     void     (* pfnStop)             (const VBOXSERVICEENV *pEnv, void *pInstance);
    95     void     (* pfnDestroy)          (const VBOXSERVICEENV *pEnv, void *pInstance);
    96 
    97     /* Variables. */
    98     HANDLE   hThread;
    99     void    *pInstance;
    100     bool     fStarted;
    101 } VBOXSERVICEINFO;
     150    /** Pointer to the service descriptor. */
     151    PVBOXSERVICEDESC pDesc;
     152    /** Thread handle. */
     153    RTTHREAD         hThread;
     154    /** Pointer to service-specific instance data.
     155     *  Must be free'd by the service itself. */
     156    void            *pInstance;
     157    /** Whether Pre-init was called. */
     158    bool             fPreInited;
     159    /** Shutdown indicator. */
     160    bool volatile    fShutdown;
     161    /** Indicator set by the service thread exiting. */
     162    bool volatile    fStopped;
     163    /** Whether the service was started or not. */
     164    bool             fStarted;
     165    /** Whether the service is enabled or not. */
     166    bool             fEnabled;
     167} VBOXSERVICEINFO, *PVBOXSERVICEINFO;
    102168
    103169/* Globally unique (system wide) message registration. */
     
    116182} VBOXGLOBALMESSAGE, *PVBOXGLOBALMESSAGE;
    117183
    118 extern HWND         ghwndToolWindow;
    119 extern HINSTANCE    ghInstance;
     184extern HWND         g_hwndToolWindow;
     185extern HINSTANCE    g_hInstance;
    120186
    121187#endif /* !___VBOXTRAY_H */
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxVRDP.cpp

    r51469 r57741  
    55
    66/*
    7  * Copyright (C) 2006-2014 Oracle Corporation
     7 * Copyright (C) 2006-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    5959};
    6060
    61 typedef struct _VBoxExperienceParameter
     61typedef struct _VBOXVRDPEXPPARAM
    6262{
    6363    const char *name;
     
    6969    UINT  cbSavedValue;
    7070    char  achSavedValue[2 * MAX_PATH]; /* Large enough to save the bitmap path. */
    71 } VBoxExperienceParameter;
     71} VBOXVRDPEXPPARAM, *PVBOXVRDPEXPPARAM;
     72
     73typedef struct _VBOXVRDPCONTEXT
     74{
     75    const VBOXSERVICEENV *pEnv;
     76
     77    uint32_t level;
     78    BOOL fSavedThemeEnabled;
     79
     80    RTLDRMOD hModUxTheme;
     81
     82    HRESULT (* pfnEnableTheming)(BOOL fEnable);
     83    BOOL (* pfnIsThemeActive)(VOID);
     84} VBOXVRDPCONTEXT, *PVBOXVRDPCONTEXT;
     85
     86static VBOXVRDPCONTEXT g_Ctx = { 0 };
    7287
    7388#define SPI_(l, a) #a, SPI_SET##a, SPI_GET##a, VRDP_EXPERIENCE_LEVEL_##l
    7489
    75 static VBoxExperienceParameter parameters[] =
     90static VBOXVRDPEXPPARAM s_aSPIParams[] =
    7691{
    7792    { SPI_(MEDIUM, DESKWALLPAPER),           VBOX_SPI_STRING,   "" },
     
    92107#undef SPI_
    93108
    94 static void vboxExperienceSet (uint32_t level)
    95 {
    96     int i;
    97     for (i = 0; i < RT_ELEMENTS(parameters); i++)
    98     {
    99         if (parameters[i].level > level)
     109static void vboxExperienceSet(uint32_t uLevel)
     110{
     111    for (size_t i = 0; i < RT_ELEMENTS(s_aSPIParams); i++)
     112    {
     113        PVBOXVRDPEXPPARAM pParam = &s_aSPIParams[i];
     114        if (pParam->level > uLevel)
    100115        {
    101116            /*
    102117             * The parameter has to be disabled.
    103118             */
    104             LogFlowFunc(("Saving %s\n", parameters[i].name));
     119            LogFlowFunc(("Saving %s\n", pParam->name));
    105120
    106121            /* Save the current value. */
    107             switch (parameters[i].type)
     122            switch (pParam->type)
    108123            {
    109124                case VBOX_SPI_STRING:
     
    112127                     * The 3rd parameter points to the buffer.
    113128                     */
    114                     SystemParametersInfo (parameters[i].uActionGet,
     129                    SystemParametersInfo (pParam->uActionGet,
    115130                                          MAX_PATH,
    116                                           parameters[i].achSavedValue,
     131                                          pParam->achSavedValue,
    117132                                          0);
    118133                } break;
     
    122137                {
    123138                    /* The 3rd parameter points to BOOL. */
    124                     SystemParametersInfo (parameters[i].uActionGet,
    125                                           0,
    126                                           parameters[i].achSavedValue,
     139                    SystemParametersInfo (pParam->uActionGet,
     140                                          0,
     141                                          pParam->achSavedValue,
    127142                                          0);
    128143                } break;
     
    134149                     * The uiParam parameter must alos be set.
    135150                     */
    136                     if (parameters[i].cbSavedValue > sizeof (parameters[i].achSavedValue))
     151                    if (pParam->cbSavedValue > sizeof (pParam->achSavedValue))
    137152                    {
    138                         LogFlowFunc(("Not enough space %d > %d\n", parameters[i].cbSavedValue, sizeof (parameters[i].achSavedValue)));
     153                        LogFlowFunc(("Not enough space %d > %d\n", pParam->cbSavedValue, sizeof (pParam->achSavedValue)));
    139154                        break;
    140155                    }
    141156
    142                     *(UINT *)&parameters[i].achSavedValue[0] = parameters[i].cbSavedValue;
    143 
    144                     SystemParametersInfo (parameters[i].uActionGet,
    145                                           parameters[i].cbSavedValue,
    146                                           parameters[i].achSavedValue,
     157                    *(UINT *)&pParam->achSavedValue[0] = pParam->cbSavedValue;
     158
     159                    SystemParametersInfo (s_aSPIParams[i].uActionGet,
     160                                          s_aSPIParams[i].cbSavedValue,
     161                                          s_aSPIParams[i].achSavedValue,
    147162                                          0);
    148163                } break;
     
    152167            }
    153168
    154             LogFlowFunc(("Disabling %s\n", parameters[i].name));
     169            LogFlowFunc(("Disabling %s\n", pParam->name));
    155170
    156171            /* Disable the feature. */
    157             switch (parameters[i].type)
     172            switch (pParam->type)
    158173            {
    159174                case VBOX_SPI_STRING:
    160175                {
    161176                    /* The 3rd parameter points to the string. */
    162                     SystemParametersInfo (parameters[i].uActionSet,
    163                                           0,
    164                                           parameters[i].pvDisable,
     177                    SystemParametersInfo (pParam->uActionSet,
     178                                          0,
     179                                          pParam->pvDisable,
    165180                                          SPIF_SENDCHANGE);
    166181                } break;
     
    169184                {
    170185                    /* The 2nd parameter is BOOL. */
    171                     SystemParametersInfo (parameters[i].uActionSet,
     186                    SystemParametersInfo (pParam->uActionSet,
    172187                                          FALSE,
    173188                                          NULL,
     
    178193                {
    179194                    /* The 3rd parameter is NULL to disable. */
    180                     SystemParametersInfo (parameters[i].uActionSet,
     195                    SystemParametersInfo (pParam->uActionSet,
    181196                                          0,
    182197                                          NULL,
     
    187202                {
    188203                    /* The 3rd parameter points to the structure. */
    189                     SystemParametersInfo (parameters[i].uActionSet,
    190                                           0,
    191                                           parameters[i].pvDisable,
     204                    SystemParametersInfo (pParam->uActionSet,
     205                                          0,
     206                                          pParam->pvDisable,
    192207                                          SPIF_SENDCHANGE);
    193208                } break;
     
    200215}
    201216
    202 static void vboxExperienceRestore (uint32_t level)
     217static void vboxExperienceRestore(uint32_t uLevel)
    203218{
    204219    int i;
    205     for (i = 0; i < RT_ELEMENTS(parameters); i++)
    206     {
    207         if (parameters[i].level > level)
     220    for (i = 0; i < RT_ELEMENTS(s_aSPIParams); i++)
     221    {
     222        PVBOXVRDPEXPPARAM pParam = &s_aSPIParams[i];
     223        if (pParam->level > uLevel)
    208224        {
    209             LogFlowFunc(("Restoring %s\n", parameters[i].name));
     225            LogFlowFunc(("Restoring %s\n", pParam->name));
    210226
    211227            /* Restore the feature. */
    212             switch (parameters[i].type)
     228            switch (pParam->type)
    213229            {
    214230                case VBOX_SPI_STRING:
    215231                {
    216232                    /* The 3rd parameter points to the string. */
    217                     SystemParametersInfo (parameters[i].uActionSet,
    218                                           0,
    219                                           parameters[i].achSavedValue,
     233                    SystemParametersInfo (pParam->uActionSet,
     234                                          0,
     235                                          pParam->achSavedValue,
    220236                                          SPIF_SENDCHANGE);
    221237                } break;
     
    224240                {
    225241                    /* The 2nd parameter is BOOL. */
    226                     SystemParametersInfo (parameters[i].uActionSet,
    227                                           *(BOOL *)&parameters[i].achSavedValue[0],
     242                    SystemParametersInfo (pParam->uActionSet,
     243                                          *(BOOL *)&pParam->achSavedValue[0],
    228244                                          NULL,
    229245                                          SPIF_SENDCHANGE);
     
    233249                {
    234250                    /* The 3rd parameter is NULL to disable. */
    235                     BOOL fSaved = *(BOOL *)&parameters[i].achSavedValue[0];
    236 
    237                     SystemParametersInfo (parameters[i].uActionSet,
     251                    BOOL fSaved = *(BOOL *)&pParam->achSavedValue[0];
     252
     253                    SystemParametersInfo (pParam->uActionSet,
    238254                                          0,
    239255                                          fSaved? &fSaved: NULL,
     
    244260                {
    245261                    /* The 3rd parameter points to the structure. */
    246                     SystemParametersInfo (parameters[i].uActionSet,
    247                                           0,
    248                                           parameters[i].achSavedValue,
     262                    SystemParametersInfo (pParam->uActionSet,
     263                                          0,
     264                                          pParam->achSavedValue,
    249265                                          SPIF_SENDCHANGE);
    250266                } break;
     
    257273}
    258274
    259 
    260 typedef struct _VBOXVRDPCONTEXT
    261 {
    262     const VBOXSERVICEENV *pEnv;
    263 
    264     uint32_t level;
    265     BOOL fSavedThemeEnabled;
    266 
    267     RTLDRMOD hModUxTheme;
    268 
    269     HRESULT (* pfnEnableTheming)(BOOL fEnable);
    270     BOOL (* pfnIsThemeActive)(VOID);
    271 } VBOXVRDPCONTEXT;
    272 
    273 
    274 static VBOXVRDPCONTEXT gCtx = {0};
    275 
    276 
    277 int VBoxVRDPInit(const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread)
    278 {
    279     LogFlowFunc(("VBoxVRDPInit\n"));
    280 
    281     gCtx.pEnv      = pEnv;
    282     gCtx.level     = VRDP_EXPERIENCE_LEVEL_FULL;
    283     gCtx.fSavedThemeEnabled = FALSE;
    284 
    285     int rc = RTLdrLoadSystem("UxTheme.dll", false /*fNoUnload*/, &gCtx.hModUxTheme);
     275static DECLCALLBACK(int) VBoxVRDPInit(const PVBOXSERVICEENV pEnv, void **ppInstance)
     276{
     277    AssertPtrReturn(pEnv, VERR_INVALID_POINTER);
     278    AssertPtrReturn(ppInstance, VERR_INVALID_POINTER);
     279
     280    LogFlowFuncEnter();
     281
     282    PVBOXVRDPCONTEXT pCtx = &g_Ctx; /* Only one instance at the moment. */
     283    AssertPtr(pCtx);
     284
     285    pCtx->pEnv               = pEnv;
     286    pCtx->level              = VRDP_EXPERIENCE_LEVEL_FULL;
     287    pCtx->fSavedThemeEnabled = FALSE;
     288
     289    int rc = RTLdrLoadSystem("UxTheme.dll", false /*fNoUnload*/, &g_Ctx.hModUxTheme);
    286290    if (RT_SUCCESS(rc))
    287291    {
    288         *(PFNRT *)&gCtx.pfnEnableTheming = RTLdrGetFunction(gCtx.hModUxTheme, "EnableTheming");
    289         *(PFNRT *)&gCtx.pfnIsThemeActive = RTLdrGetFunction(gCtx.hModUxTheme, "IsThemeActive");
     292        *(PFNRT *)&pCtx->pfnEnableTheming = RTLdrGetFunction(g_Ctx.hModUxTheme, "EnableTheming");
     293        *(PFNRT *)&pCtx->pfnIsThemeActive = RTLdrGetFunction(g_Ctx.hModUxTheme, "IsThemeActive");
     294
     295        *ppInstance = &g_Ctx;
    290296    }
    291297    else
    292298    {
    293         gCtx.hModUxTheme = NIL_RTLDRMOD;
    294         gCtx.pfnEnableTheming = NULL;
    295         gCtx.pfnIsThemeActive = NULL;
    296     }
    297 
    298     *pfStartThread = true;
    299     *ppInstance = &gCtx;
    300     return VINF_SUCCESS;
     299        g_Ctx.hModUxTheme = NIL_RTLDRMOD;
     300        g_Ctx.pfnEnableTheming = NULL;
     301        g_Ctx.pfnIsThemeActive = NULL;
     302    }
     303
     304    LogFlowFuncLeaveRC(rc);
     305    return rc;
    301306}
    302307
    303 
    304 void VBoxVRDPDestroy(const VBOXSERVICEENV *pEnv, void *pInstance)
    305 {
    306     LogFlowFunc(("VBoxVRDPDestroy\n"));
    307     VBOXVRDPCONTEXT *pCtx = (VBOXVRDPCONTEXT *)pInstance;
     308static DECLCALLBACK(void) VBoxVRDPDestroy(void *pInstance)
     309{
     310    AssertPtrReturnVoid(pInstance);
     311
     312    LogFlowFuncEnter();
     313
     314    PVBOXVRDPCONTEXT pCtx = (PVBOXVRDPCONTEXT)pInstance;
     315
    308316    vboxExperienceRestore (pCtx->level);
    309     if (gCtx.hModUxTheme != NIL_RTLDRMOD)
    310     {
    311         RTLdrClose(gCtx.hModUxTheme);
    312         gCtx.hModUxTheme = NIL_RTLDRMOD;
    313     }
     317    if (pCtx->hModUxTheme != NIL_RTLDRMOD)
     318    {
     319        RTLdrClose(g_Ctx.hModUxTheme);
     320        pCtx->hModUxTheme = NIL_RTLDRMOD;
     321    }
     322
    314323    return;
    315324}
     
    318327 * Thread function to wait for and process mode change requests
    319328 */
    320 unsigned __stdcall VBoxVRDPThread(void *pInstance)
    321 {
    322     VBOXVRDPCONTEXT *pCtx = (VBOXVRDPCONTEXT *)pInstance;
     329static DECLCALLBACK(int) VBoxVRDPWorker(void *pInstance, bool volatile *pfShutdown)
     330{
     331    AssertPtrReturn(pInstance, VERR_INVALID_POINTER);
     332
     333    LogFlowFuncEnter();
     334
     335    /*
     336     * Tell the control thread that it can continue
     337     * spawning services.
     338     */
     339    RTThreadUserSignal(RTThreadSelf());
     340
     341    PVBOXVRDPCONTEXT pCtx = (PVBOXVRDPCONTEXT)pInstance;
     342    AssertPtr(pCtx);
     343
    323344    HANDLE gVBoxDriver = pCtx->pEnv->hDriver;
    324345    bool fTerminate = false;
     
    328349    maskInfo.u32OrMask = VMMDEV_EVENT_VRDP;
    329350    maskInfo.u32NotMask = 0;
    330     if (DeviceIoControl (gVBoxDriver, VBOXGUEST_IOCTL_CTL_FILTER_MASK, &maskInfo, sizeof (maskInfo), NULL, 0, &cbReturned, NULL))
    331     {
    332         LogFlowFunc(("DeviceIOControl(CtlMask - or) succeeded\n"));
    333     }
    334     else
    335     {
    336         LogFlowFunc(("DeviceIOControl(CtlMask) failed\n"));
    337         return 0;
    338     }
    339 
    340     do
     351    if (!DeviceIoControl(gVBoxDriver, VBOXGUEST_IOCTL_CTL_FILTER_MASK, &maskInfo, sizeof (maskInfo), NULL, 0, &cbReturned, NULL))
     352    {
     353        DWORD dwErr = GetLastError();
     354        LogFlowFunc(("DeviceIOControl(CtlMask) failed with %ld, exiting\n", dwErr));
     355        return RTErrConvertFromWin32(dwErr);
     356    }
     357
     358    int rc = VINF_SUCCESS;
     359
     360    for (;;)
    341361    {
    342362        /* wait for the event */
     
    346366        if (DeviceIoControl(gVBoxDriver, VBOXGUEST_IOCTL_WAITEVENT, &waitEvent, sizeof(waitEvent), &waitEvent, sizeof(waitEvent), &cbReturned, NULL))
    347367        {
    348             LogFlowFunc(("DeviceIOControl succeeded\n"));
    349 
    350368            /* are we supposed to stop? */
    351             if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 0) == WAIT_OBJECT_0)
     369            if (*pfShutdown)
    352370                break;
    353 
    354             LogFlowFunc(("checking event\n"));
    355371
    356372            /* did we get the right event? */
     
    417433                else
    418434                {
    419 #ifndef DEBUG_andy /* Too noisy for me. */
    420                     LogFlowFunc(("Error from DeviceIoControl VBOXGUEST_IOCTL_VMMREQUEST\n"));
    421 #endif
    422435                    /* sleep a bit to not eat too much CPU in case the above call always fails */
    423                     if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 10) == WAIT_OBJECT_0)
    424                     {
    425                         fTerminate = true;
     436                    RTThreadSleep(10);
     437
     438                    if (*pfShutdown)
    426439                        break;
    427                     }
    428440                }
    429441            }
     
    431443        else
    432444        {
    433 #ifndef DEBUG_andy
    434             LogFlowFunc(("Error from DeviceIoControl VBOXGUEST_IOCTL_WAITEVENT\n"));
    435 #endif
    436445            /* sleep a bit to not eat too much CPU in case the above call always fails */
    437             if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 10) == WAIT_OBJECT_0)
    438             {
    439                 fTerminate = true;
     446            RTThreadSleep(50);
     447
     448            if (*pfShutdown)
    440449                break;
    441             }
    442450        }
    443     } while (!fTerminate);
    444 
    445     maskInfo.u32OrMask = 0;
     451    }
     452
     453    maskInfo.u32OrMask  = 0;
    446454    maskInfo.u32NotMask = VMMDEV_EVENT_VRDP;
    447     if (DeviceIoControl (gVBoxDriver, VBOXGUEST_IOCTL_CTL_FILTER_MASK, &maskInfo, sizeof (maskInfo), NULL, 0, &cbReturned, NULL))
    448     {
    449         LogFlowFunc(("DeviceIOControl(CtlMask - not) succeeded\n"));
    450     }
    451     else
    452     {
     455    if (!DeviceIoControl(gVBoxDriver, VBOXGUEST_IOCTL_CTL_FILTER_MASK, &maskInfo, sizeof (maskInfo), NULL, 0, &cbReturned, NULL))
    453456        LogFlowFunc(("DeviceIOControl(CtlMask) failed\n"));
    454     }
    455 
    456     LogFlowFunc(("Finished VRDP change request thread\n"));
    457     return 0;
     457
     458    LogFlowFuncLeaveRC(rc);
     459    return rc;
    458460}
    459461
     462/**
     463 * The service description.
     464 */
     465VBOXSERVICEDESC g_SvcDescVRDP =
     466{
     467    /* pszName. */
     468    "VRDP",
     469    /* pszDescription. */
     470    "VRDP Connection Notification",
     471    /* methods */
     472    VBoxVRDPInit,
     473    VBoxVRDPWorker,
     474    NULL /* pfnStop */,
     475    VBoxVRDPDestroy
     476};
     477
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